Affordable Smart-Home DIY with JS

Dean Shub
Wix Engineering
Published in
5 min readJan 11, 2019

There’s no better feeling than going into my air conditioned home after a full wintry working day with hot water waiting for me using my own
smart-home DIY.

Photo by Stephan Bechert on Unsplash

Smart-Homes are usually really expensive, with low voltage wiring and big hardware frameworks that automate your entire house, but you can also integrate a few cheap appliances and write your own app using Node.js to create a DIY Smart-Home.

Let’s get down to business:
First, we need hardware that will trigger infrared (and maybe radio) signals, which should have an API (preferably in JS) and be very cheap. I found Broadlink RM mini\pro fits the criteria perfectly, and there are plenty of coupons you can find on Google for it. Of course, there are many other devices you can try out.

The Broadlink RM mini can control any IR (Infra Red) device; air conditioner, TV, receiver, and more. In addition, the BroadLink RM mini can also learn signals from remote controls.
Let’s start by controlling the air conditioning!

First the API for controlling the Broadlink RM mini device, I used https://github.com/lprhodes/broadlinkjs-rm but since it seems unmaintained, I decided to copy the only relevant file and maintain it myself.

Let’s go through the code of our broadlinkController.js file.
At the beginning of the file there’s an import of the API file that we copied.
We insatiate it to get the b variable, which has all the functions to talk to our devices.

At the third line, there’s an import of keys which I previously saved from the Broadlink devices (use fs.writeFile on the first time to generate these keys), in order to identify where the device is located (I have a device in each room: living room, bedroom, workroom)

Then we have a variable called devicesReady which contains a promise that returns an object with devices by their names.

Then we have 3 functions:

getDeviceByName — receives the name of the room where the Broadlink device is located, returns the device controlling object.
learnSignal — receives the name of the room where the Broadlink device is located and the name of the signal you are going to learn (for example, TV-power or AC18Deg) a file will be created with that name, returns the signal name if managed to learn the signal.
sendSignal — receives a signal name (same name that we gave to the previous function) and the name of the room where the Broadlink device is located (and sends the signal by that name from that room).

Now that we have a node app that controls IR we just need a UI to control it.
But why write your own UI if you can use an existing platform to make things easier?!

I choose to use telegram bots, a simple cross platform messaging app that allows creating bots for free and has a great API.

Let’s go over the main things here,
config module allows me to use configuration files per environment so I keep the bot token there (and out of the repo), the token and the bot should be generated using botfather.
bot is an object used to communicate with Telegram API.
The functions sendMessage, addCommand, editMessageReplyMarkup, editMessageText are wrappers around the regular telegram bot functions but they allow us to re-use bot commands through the runCommand function by saving all commands on the commands variable.
The callback_query event is an event that’s triggered when a user presses the button feature within the telegram bot.

So now let’s stick things together

That’s the index file of our app, it registers the start command and the callback event.

Now we need these commands, though it may not look so, the start command is pretty simple.

It states that when we text the command /start to the bot, it’ll respond with the text “Hi ____, what do you want to do?”, and it’ll add to that message a button for every location with a device (in my case living room, bedroom, workroom [see video below]).

Now we need to have a reply when we click these buttons.

OK, I know it’s a bit much, but here’s the gist of it:
1) The default exported function receives data from the button clicked, which allows us to identified what button clicked.
2) Then we match it with other buttons — for example, clicking the bedroom button will show buttons of turning the TV on\off or starting the AC on hot or whatever we decide, for example in point 3.
3) Then if the AC hot button pressed we should respond with both triggering broadlinkController ‘s sendSignal function and reset the buttons to the device location buttons (returning to the previous phase).

This is the finished demo:

From here on out you can make it as advanced as you want, I added logs, permissions and human recognition that lets me know when people come to my house (let me know if you have any other cool things I can add).

All can be found in my repository

https://github.com/deanshub/smarthome-js

There are many additional devices you can control like lights and the boiler.

Radio lights controller for less than 2$
Switcher, a water boiler controller

There’s no better feeling than going into my air conditioned home after a full wintry working day with hot water waiting for me using my own
smart-home DIY bot.

If you enjoyed this post, and want me to write the next chapter on how to create your own security camera that integrates with this article’s smart-home bot, clap and let me know and I’ll write the next post.

--

--