I got the inspiration behind this project by reading internet switch tutorial posted by Talha a while ago on Hackster. It was super cool and I thought what could be more wild than controlling just an LED over the internet? Controlling a real appliance maybe! So I decided to build an ESP8266 based quick circuitry, and a web application to control the air cooler in my room over the web.
I have worked on a similar thing in my university's final year project where I made a smart socket board to control the lights and fans of my room, but it took me almost a year to figure out just the basic technology stack. For example, I built my own hardware and my app, which led me to build my own server backend through which my app sent commands to the appliances and the appliances sent acknowledgments to the app. And the working wasn't very fast either.
And so, we designed Grandeur to solve the big little problems. Building the tech stack of connecting the hardware things to internet is hard and super scary and hence always proves to be a huge limiting factor in going a step ahead of the norm and making something crazy in hardware domain – particularly when you are like me: building a startup and wanting to go custom from tip to toe. So I thought of porting my final year project with Grandeur to control my room's air cooler. So, let's create 🔧.Step 1: Getting Started
- Start by logging in to the platform and creating a new project.
- Since I want to build my own app to control the cooler, I will use Grandeur's JS SDK for sending data to my hardware and add login functionality into the app. For this, I need the API key and access credentials which I will provide to the SDK, which then makes connection with the cloud. API key acts as the identifier for my project while access credentials (Access key and token) are part of the request's source validating scheme. This is how I get them:
- Auth is the way Grandeur provides to build register/login functionalities in the app. This way multiple users can use the app, each controlling its own (paired) devices. With builtin access management, a user can only access a device paired to its own account; I'll get to that in a sec. Below is how I created a new user.
- So to program the ESP8266, I use the Arduino SDK to receive the data sent from the app. To enable this SDK to connect with the cloud, it needs my device ID (which I get while registering my air cooler device in my project) and device access token (which I get when I pair my device with the user account I created). It is important to note here that if you want to connect multiple ESP modules to cloud then each chip is required to have a different device ID and thus separate registration. This is how you can register a new device:
- Finally, I pair my newly created device with the user account that I created earlier. This gives the user the authority to send data to the device from the app through JS SDK. P.S. a user can only access devices paired to its account. This is how you can pair a device with a user account:
At this point, it is worth mentioning that you can alternatively create a new user (using the register functionality) and pair a device to a user account through the JS SDK as well. This helps in resolving production use cases – like you can allow users to register directly from the app or pair devices after buying them from you – just the way you use Philips app to use hue bulbs.
We designed Grandeur around production use cases you can encounter while building an internet connected hardware solution, e.g., you are a solar startup and want to enable your users to monitor the energy generated from their solar panels on your app.
Okay, enough theory, let's start coding now.
I extended the same code used by Talha. However, I do not hard-code the ID of my device. Instead, I get a list from cloud using the JS SDK function
and populate the grid of tiles in the App's UI. This way, the user can work with multiple devices on a single page. Each tile represents a separate device and so I attach a separate on-click event handler to each tile. This way, the respective device is signaled to change its state whenever a tile is clicked, which I do by updating the
state variable of the device using this JS SDK function:
I don't hard-code the user's account credentials either. Instead, I make a login page to later add them from the running app. Here is a state diagram of my application:
So, the app shows a loading screen on start, during which it validates if the user is authenticated to display the devices tiles or the login screen. Along with this, the app attaches a listener on connection state of SDK as well, which makes the SDK track the connection status and emit an event whenever the connection gets established. So it's like an event is fired and a callback is called as soon as the user authenticates on the login screen (because the SDK establishes a sync connection with server only after authentication).
On connection establishment, the app requests the server for the list of paired devices (since you can perform device related requests only on sync i.e. after authentication). The logic of the whole routine is shown as below:
First of all, the app requests the list of devices from the server which it then loops over and generates html to represent each device as a tile. Then it subscribes to the state update event of the devices and attaches on-click event listeners to the html tiles. The app DOM is updated after generating the html for all the devices.
The event listener on a device DOM element (a tile) toggles the
state of that device, the hardware gets the update and toggles the cooler's state. Also since the app subscribed to the device state, its listener is automatically fired once the
state is updated on clicking the device tile, and updates the app's UI to represent that the state has been changed (Grandeur is event driven, remember!).
This is also a validation. The UI gets updated only when it is certain that the server has acknowledged the update and has forward it to the device because the app and device subscribe to the same event. Therefore I could safely assume that the device would have already received an update when my app handler gets fired. You can find the code for app here. That's how the app looks like in action:
The device code is the same as what Talha did in Internet Switch tutorial. I just changed the pin number and used a separate LED to give a visual output of connecting to WiFi and to the Cloud (by blinking). The logic of the device code is pretty straight forward:
Device listens for the connection event (just as the app did) and subscribes to device data update. It then configures the GPIO pins and finally jumps into the loop routine where it syncs itself with the cloud. The SDK establishes a sync connection with the server and loop basically just allows the SDK code to run the underlying logic and fetch updates from the server.
Then on data update event, it simply update the
state of the control pin. The code is accessible here. That's how the app and device look together in action. You can run this setup locally using the Grandeur CLI, documented by Talha here.
That's my fav section because I literally love joining the software world to the hardware world; this is where the magic happens. Since we are controlling a GPIO (D5) of Nodemcu using the app, we can attach a relay to that pin and control the power supply to the cooler. The circuit design is straightforward:
I am driving an led and a relay with a classic transistor-as-switch circuit because the NodeMCU works at 3.3V while the relay and led works at 5V and the NodeMCU can't source enough current anyways (driving relay directly with NodeMCU can cause imperfect latching of the relay resulting in burning the microcontroller).
I have designed this circuit like a breakout board, so there are several connectors like for 220V source, load (cooler), relay (which basically acts like a digitally controlled switch between source and load), power supply (5V DC) and relay control terminals. Finally, there is a switch as well (which turns off/on the entire circuitry). Here's the PCB layout:
The relay that I am using here is a 25A solid state relay but you can find any off-the-shelf relay (as long as it is operated through 5V input and can endure the cooler's load). Hint: you can just use a slightly bigger relay to control the air conditioner or literally any kind of machine. You can find the Eagle project file at the end.Step 5: Box
Yeah! we are going super dope here. I have also designed an enclosure box for the circuitry with the Fusion 3D (since I used Eagle and Fusion is like perfect big bro – works like charm with Eagle). It looks like this:
I have also attached the STL file with this project so you can literally just 3D print one for yourself. I have designed it as per the specs of the PCB so it will fit, plus there is room for power supply and relay as well, but please confirm that your relay and power supply fit before printing, as I used mine for reference here.Demo
This is it. We are at the end. I developed my PCB using a local service provider but you can use this (disclaimer: I haven't used this service and I don't represent this company). I 3D-printed the box using my own printer but there are many services available out there. I soldered and wired everything and tested it on my own cooler. Watch this video 👇Conclusion
With this, it is a wrap. Grandeur makes IoT dev ten folds easier plus it is free to get started and you can go all the way custom with your own app and your own hardware and give your stuff your own look and feel. And then you can do serious stuff like you can start your own startup while not having to worry about doing the backend (because Grandeur can handle real production load with ~200ms throughput. That's 🤯). This way you can get into market in weeks.
I'll be doing more tutorials on this topic (you can expect more wild things TBH). Plus you can check out the official hub for more tutorials. Thanks for tuning in. Do let me know about your feedback and feel free to reach out. I am always here.
Till next time!