Ever wondered if you could control your Christmas tree lights from a custom mobile app you built yourself? Adalo lets you build database-driven web apps and native iOS and Android apps — published to the App Store and Google Play — from a single no-code editor.
This tutorial walks you through creating a Christmas tree light control app by integrating Adalo with DreamFactory, Flask, and a healthy dose of creative problem-solving.

Having spent my career writing software and often struggling mightily with the design, since joining the Adalo team a few months ago I've been pretty much blown away by how easy it is to create and wire up user interfaces using the Adalo app builder. Adalo is a no-code app builder for database-driven web apps and native iOS and Android apps—one version across all three platforms, published to the Apple App Store and Google Play. Candidly I had always thought no-code app builders were limited to creating fairly simplistic CRUD-style (create, retrieve, update, delete) apps and dashboards.
With Christmas fast approaching, and being the type of nerd who likes to automate things for no particular reason, a few days ago I started to wonder if it would be possible to create an Adalo app that could control my family Christmas tree lights. They're already wired up with a smart plug and our kitchen Alexa device and so can be turned on and off with the command, "Alexa, turn on the Christmas tree", but you know what's better than one home automation integration? Two. What follows is a recap of my quest to create and launch of a Christmas tree light management mobile app using Adalo, duct tape, and poor judgement.
The app will be available for a few days beginning Monday, December 16, and may be periodically offline due to me not being home (afraid of fire), my wife threatening to strangle me for making this public, or the obvious technical issues that may arise. Check it out at https://xmas.wjgilmore.com.
Introducing the App
The app is creatively called the Adalo XMAS Tree App. It consists of some theming, two buttons for toggling the Christmas lights, and a YouTube livestream so you can watch the action in realtime. But those buttons, oh those buttons are practically irresistible. You just can't help but press them and see that tree either light up in response or imagine my wife groaning after seeing it go dark yet again. Last night we were catching up on the Apple series Silo (season 2, watch it, it's amazing), and I found myself in a death struggle with some unknown digital intruder. I think I know who it was (Allison don't think I don't know it was you!), but anyway the tree terrorist would click it off. And I would turn it back on. A few moments later the grinch was back and the lights were off again. And I would again valiantly fight back, illuminating the living room once again. They say heroes aren't born but forged in tinsel, and I'm living proof of it.
I'll bet your salivating at the idea of pushing those buttons. Well have at it. Go to https://xmas.wjgilmore.com and give them a press. WARNING: I have no idea how long this is going to be available before it's knocked offline by my ISP, a programming error, or frankly my wife.

Talking to the Smart Plug
Because in 2026 we can't be bothered with bending down to plug and unplug a string of lights, I used a TP-Link KP115 smart plug to control the lights via Alexa. This is a pretty straightforward process, but to my knowledge there is no official way to interact with the plug outside of Alexa and the horrible manufacturer app. GitHub to the rescue! As expected, a kind programmer reverse engineered the plug communication protocol and bundled it up into a convenient Python package called python-kasa. To install python-kasa run:
Once installed you can begin interrogating your local network of supported devices using the discover command:
So not only can you easily identify each device's assigned IP address, you can also determine whether it's turned on, how long it has been in the on or off state, and how much power it has consumed both for the current month and since the last reboot. Pretty cool!
Once you know the device IP address, it's easy to turn it on and off:
Creating an API
My ultimate goal was to control this plug via an Adalo mobile app which could be conceivably accessed from anywhere in the world including the North Pole. This means opening up an Internet connection from my home network to the outside world. Let me be clear: there are right ways to do this, and there are wrong ways. The way I'm about to show you is very, very wrong, and my home internet services provider will likely shut off our connection for doing it this way.
The simplest version of this API needs by my estimation three endpoints: status, on, and off. The status endpoint tells us whether the plug is on or off, while the on and off endpoints are self-explanatory. I used Flask to create the API, and found it to be very easy to use. To create an endpoint you just define the route URI and then the method that immediate follows is executed when that endpoint is requested. Believe it or not this is enough to create a functioning Flask API:
Save this file as status.py or whatever and then start the Flask server like this:
Because Flask routes are by default GET requests, you can just open your browser and go to http://127.0.0.1:5000/status to test it out. Presuming there are no syntax errors you should see the string hello displayed in the browser.
In the case of my project, I needed the API endpoints to execute python-kasa commands, and so I used Python's subprocess module to run shell commands. For the sake of this project I can get away with playing things a bit fast and loose, however if you ever try something similar and need to pass parameters into the shell command then it is critically important that you validate the data before doing so. Here is the complete Flask script used for this project:
Talking to the Outside World
You probably noticed that the Flask API is running on localhost, meaning it's not accessible to the outside world. To make this API accessible elsewhere I use a service called ngrok. ngrok has been around for as long as I can remember, and long story short it will expose a local development server to the internet (among many other things). Using ngrok we can expose port 5000 of my local server to an ngrok.app subdomain as easy as running this command:
Now I can go to my ngrok endpoint from any network and it will forward the requests to and from my API!
Proxying the Requests Through DreamFactory
For both security and flexibility reasons I then routed the ngrok endpoint through DreamFactory. DreamFactory is best known as a database wrapper capable of quickly exposing an enterprise-grade REST API, however it can do all sorts of other interesting things such as extending the capabilities of existing APIs. I used DreamFactory's scripted service connector because I thought it might be fun to eventually integrate other capabilities into the app such as the current temperature at the North Pole. Doing this is incredibly easy using DreamFactory because I can just add new endpoints to my scripted service.
DreamFactory's scripted services connector supports the PHP, Python, and NodeJS languages, and because I'm most familiar with the platform's PHP-based API I went with that:
Just for sake of illustration I've extended what's exposed through the Flask API by adding a /temperature endpoint which when requested will return "Freezing".
After saving these changes I added a role-based access control to the DreamFactory API and then generated an API key. The DreamFactory API endpoints are now only accessible by providing the API key which is provided via a secure HTTP header.
Integrating the API and Adalo App
One of my favorite Adalo builder features is how easy it is to tie events to user actions. For instance when clicking on the "Turn tree on" button an API call to the /on endpoint needs to happen. This is accomplished as easily as adding an "action" to the button and indicating what kind of event needs to occur in order for that action to execute. Further, you can define multiple actions as shown in this screenshot (taken from the actual app):

The API call is sent to the aforementioned DreamFactory endpoint. Again, the call is secured by passing along an API key via the HTTP header. Defining this call is accomplished via a simple web wizard, one step of which is shown in the following screenshot:

Counting Light Toggle Frequency
I thought it would be fun to keep track of the number of times users have turned lights on and off. I could do this within the local Flask API using SQLite, but thought it made sense to keep this tally closer to the app and so used Adalo's Collections feature instead. I created a single collection called counts consisting of four fields: ID (the usual auto-incrementing primary key), name (which stores the strings on and off , and the usual timestamps. Usual caveats apply here, I could have probably set this up a bit more efficiently but we're just bulldozing our way through the project. Here is an example of a few records stored in the table:

Charting the Results
My friend Nic over at DreamFactory suggested creating a chart depicting the toggling frequency. I didn't feel like writing any custom code to implement this however it's trivial to export data out of an Adalo collection and so I did that and uploaded it along with an example chart into ChatGPT:

Yes I am always polite when talking to AI these days. I for one welcome and appreciate our robot overlords. I didn't like how the chart turned out though and so after a few more attempts I asked it to create a pie chart instead:

Setting Up the YouTube Livestream
Setting up the YouTube livestream was really straightforward; I used Adalo's YouTube marketplace component, pasted in the livestream URL, and it just worked. Plus I get to watch the livestream status using this fun YouTube Studio interface:

Creating the App Icon
I have no design skill whatsoever, and so just relied on DALL-E to generate one for me. I used the prompt "Please create a 1024 x 1024 px icon for a mobile app used to Control Christmas tree lights". DALL-E ignored the dimensions and created the two options found in the screenshot:

In the interests of time, I selected the very first icon it created, downloaded it to my Mac, and then used macOS' little-known remove background feature to remove the background gradient:

Conclusion
This was a very fun project that made my kids and neighbors laugh, and aggravated my wife to no end. Sometimes the best projects are those which have no real purpose other than to have a few laughs. Hopefully by the time you read this my house hasn't burned down. Perhaps in a later post I'll document some of the other funny things which popped up during development, such as Treehouse instructor Laura Coronel writing an automated script to interact with the user interface and toggle the tree lights 100 times in one minute.
FAQ
| Question | Answer |
|---|---|
| Can I easily integrate external APIs and smart home devices with a no-code app? | Yes, with Adalo's No Code App Builder, you can easily integrate external APIs and smart home devices into your app. Adalo makes it simple to tie API calls to user actions like button clicks through a straightforward web wizard, allowing you to connect to services like DreamFactory, custom Flask APIs, or any REST endpoint with secure HTTP headers. |
| Why choose Adalo over other App Builder solutions? | Adalo is a no-code app builder for database-driven web apps and native iOS and Android apps—one version across all three platforms. AI-assisted building and streamlined publishing enable launch to the Apple App Store and Google Play in days rather than months. This ability to publish directly to app stores is crucial because marketing and distribution are often the hardest parts of launching a new app or business—having your app available in the stores where users already search for solutions gives you a major competitive advantage. |
| What's the fastest way to build and publish a smart home control app to the Apple App Store and Google Play Store? | Adalo is the fastest way to build and publish a smart home control app to the Apple App Store and Google Play. With No Code App Builder's drag-and-drop interface and AI-assisted building, you can go from idea to published app in days rather than months. Adalo handles the complex App Store submission process, so you can focus on your app's features and user experience instead of wrestling with certificates, provisioning profiles, and store guidelines. |
| How do I add button actions and user interactions in Adalo? | Adding button actions in Adalo is incredibly easy—you simply add an 'action' to any button and specify what event triggers it. You can define multiple actions per button, such as making an API call and updating a database record simultaneously. This makes creating interactive apps with real-world functionality straightforward even without coding experience. |
| Can I store and track data in my Adalo app? | Yes, Adalo includes a built-in Collections feature that lets you create database tables to store and track data. You can easily set up collections with custom fields, timestamps, and relationships, then export data whenever needed. This makes it simple to track user activity, store app state, or maintain any data your app requires. |
| How do I embed YouTube videos or livestreams in my Adalo app? | Adalo offers marketplace components including a YouTube component that makes embedding videos incredibly simple. You just add the YouTube marketplace component to your screen, paste in your video or livestream URL, and it works immediately. This allows you to add rich media content to your apps without any custom coding. |
| Do I need design skills to create a professional-looking app with Adalo? | No, you don't need design skills to create a great-looking app with Adalo. The platform includes theming capabilities and pre-built components that help you create polished interfaces. You can also use AI tools like DALL-E to generate custom app icons and graphics, making the entire app creation process accessible to everyone. |










