My home automation projects built with MQTT and Node Red



I thought I’d start a topic about some of the home automation things I’m doing with Blynk.

We live in London, England, and also have a holiday home in Spain where we spend around 4 months of the year. Most of my home automation projects are based in the Spanish home and are aimed at simplifying day-to-day life while we’re there. My wife is disabled, and finds new technology a bit of a challenge, so all the projects that I’ve created are aimed at being practical, easy to use and reliable.

Lets start with a bit of an introduction to the technology platform that I’m using…

Part 1 – Background

I don’t use Blynk in the same way as most other people, so this post is aimed at explaining the technology used and hopefully demonstrating that it’s worthwhile going down this route if you’re building complex projects.

The core of my system is a Raspberry Pi 3 running Node-Red and the Mosquitto MQTT server. I use the Blynk cloud server for simplicity and reliability.

Node-Red is a graphical programming/workflow environment that is extremely powerful and it can be expanded by writing your own functions in a language which is very similar to Arduino C+. It’s also very simple to import additional ‘Nodes’ that are contributed via the Node-Red community and which add additional functionality. One of the ones I use is set of nodes developed and maintained by @gab.lau that give integration with Blynk. Other nodes I use on a regular basis allow integration with Amazon Alexa and Ikea Tradfri lighting. There’s also a very powerful and flexible timing node developed by @scargill which I use to handle all of my scheduling.

MQTT is a message transfer protocol that allows devices to transfer commands and data very easily. One way to visualise how MQTT works is to think of it as a standard folder/directory system that you might find on a Windows PC where you can drop messages for various programs to pick-up and use. Say you set-up a folder structure called:


You can then drop commands like “On” / “Off” (or “1” / “0”) in to this folder so that the devices that monitor this folder see the command, pick it up and do something with it.
In MQTT terms, putting a message in a folder is called Publishing and monitoring a folder is called Subscribing. The folders themselves are called Topics.

Obviously you don’t use a Windows file structure to achieve this, everything is handled in the background by the Mosquitto MQTT server when it comes to where and how the messages are stored. But, thinking of it in the same terms as you would when setting-up a folder structure to store data on your PC can help you to create a logical topic structure.

A Simple Example
Let’s take a look at a simple example of how you could use Blynk, Node-Red and MQTT together to control a light…

A simple system could have:

  • A mobile phone or tablet running Blynk, with a project that has a single on/off button widget connected to virtual pin 1.

  • A simple Node-Red flow that takes the output from the V1 button and writes it to our MQTT topic of Home/Lounge/Lights/Light_1/Command

  • An MCU device (in this case a Sonoff switch that will control a light), running software that connects to the local Wi-Fi and subscribes to the Home/Lounge/Lights/Light_1/Command topic. If the Sonoff receives a “1” then it will activate the relay to turn the light on, if it receives a “0” it will deactivate the relay to turn the light off.

The Node-Red flow for this would simply be:

The green node on the left is the incoming data from the Blynk button widget (a “0” or “1”), the pink node on the right outputs the same message (“0” or “1”) to the MQTT Topic.

You might ask “Why go to all this bother – why not just use a simple Blynk sketch”. The answer us that for something as basic as this then yes, a simple Blynk sketch is easier and quicker. However, it’s very easy to add-in other devices and get them talking to each other, something that isn’t as simple to do using just Blynk.

One of the things I use this system for is controlling my air conditioning, cooling fans and wall heaters. I have multiple temperature/humidity sensors, a Nextion touch screen, Infra-Red transmitters (to control the aircon and fans), Sonoff switches (to control the heaters) and a 433MHz receiver linked to door & window sensors (to warn if they are open when using the heating or air conditioning). This gives 8 devices that all talk to each other and interact in some way.
Doing this with Blynk alone would be a challenging task, so I use Blynk for what it’s great at – giving app control over settings, regardless of where you are in the world at the time.

Adding-in Alexa Voice Control
Building on my previous example, here’s how you would add-in Amazon Alexa voice control for the light that we’ve just set-up.

The Alexa “plug-in” for Node-Red allows you to name your devices however you wish. In this case I’ve gone with “Light 1” again. This is the Grey node bottom left. The output from the Alexa node takes the form of “TurnOnRequest” or “TurnOffRequest” and these strings need to be translated into “1” and “0” so we use a Change node (the yellow one at the bottom for this) for this.
As we also want the Blynk switch widget to stay synchronised, we need to write the output of the Change node back to pin V1, as well as to the MQTT node, so we use a Blynk output node (green, bottom right).

Once you’ve asked Alexa to discover your new device, saying “Alexa, Turn Light 1 On” will activate the Sonoff and turn the light on, as well as updating the app to show the switch widget on V1 as being On. I doubt that there’s an easier or quicker way to add Alexa integration to any project.

Graphical Programming versus Coding
As an example of how easy it is to achieve results using the graphical programming environment of Node-Red, this is how the Change node is configured to translate the output from the Alexa node into the format we want:

It’s extremely simple to do things like this and I’m sure some would find it easier than writing the corresponding “if” statement in code.
Having said that, it you want to do this in a user defined function then there’s a node to allow you to do that. Personally, I tend to write functions that can perform multiple tasks to reduce the node count, but it depends on the complexity of the flow and what I’m trying to achieve.

Hopefully this has helped to explain a bit about what Node-Red and MQTT are, and how this combination can be used with Blynk.
If you’re interested in creating your own Node-Red and MQTT setup on a Pi then I’d recommend taking a look at the installation script that @scargill has created on his tech blog website:

In the next posts I’ll start to get into more detail about the real world projects that I’m working on, starting with my door-entry system that I’ve created in Spain.


Using Dashboard with Blynk
Would is possible to use widget Device Selector for
No button state in Node Red if i change it on the app
Blynk Write Event and NodeRed
More than one TCP connection

Part 2 – Door Entry System

If you’ve not read Part 1 yet then I’d suggest that you do, before going any further.

Our home in Spain has gate to the street which has a conventional speech-only door entry system that allows us to talk to people at the gate and release the lock if we wish. The gate also has a lock that can be opened using a conventional key, but getting the key in the lock and opening the gate can be a bit fiddly, especially in the dark after a few beers!

Our community swimming pool has a door entry system controlled by RFID key fobs, where each house on the urbanisation has a fob with a different code. I decided that adding a similar RFID system to the gate of our house would be a nice improvement, and having just one key fob that opened both the pool and the house gate would be the most sensible approach.

After a few false starts, I eventually managed to work out that the key fob for the community pool is a Mifare 1k system. I bought a Wiegand protocol waterproof reader that can read the Mifare fobs and initially built a stand-alone reader using an Arduino Mini. This worked okay, but I realised that I really wanted more functionality, such as the ability to release the gate remotely (more about the thinking behind that later) and to know when the gate had been opened (handy to monitor when our keyholder does his property checks when we’re not there).

Copying the pool entry fob proved trickier than I thought, as a random code is embedded into most fobs when they are made, but I needed more fobs with the same User ID code as our original one. I eventually managed to source fobs with a re-writeable block zero (which is where the User ID is stored) at a sensible price so I ordered some and a writer to be able to clone my existing fob.

I recently replaced the Arduino Mini with a Wemos D1 Mini Pro (chosen because I needed an external antenna) and “Blynkified” the gate.

This worked well gave the ability to release the gate via the app and to keep a log (using a Table widget) of when the gate has been released and what method has been used to release it (Blynk app, RFID fob or 433MHz button – more on that later). It also logs the User ID code from any unidentified RFID fobs so I can see if someone has tried their fob against my reader.

Having done this, the door entry for the gate still didn’t really give all the functionality we wanted it to. The gate is at the front of the property and the door entry intercom is in a room at the rear of the property. We have a window at the front that overlooks the gate, and in practice we find that it’s easier to go to the window and look out, and often open the window and speak to the person at the gate. This works better because you can see who you’re talking to, and also because if the visitor is Spanish then the language barrier seems less problematic when you’re speaking face to face rather than over the intercom. The disadvantage to this approach is that if you then decide that you want to let the person in, you either have to walk to the intercom handset and release the gate (then usually go back to check that they entered okay) or rummage around and find your phone, open the Blynk app and then release the gate.

Obviously a video Entryphone would solve some of these issues, but installation could prove problematic and I wanted a cheaper and simpler solution. I eventually settled on a 433MHz battery powered button located near the window, and a 433MHz receiver attached to a Wemos D1 Mini to act as 433 to MQTT gateway. This allows the button to be pressed to release the gate whilst standing at the window and it’s much quicker and easier than either of the other two options.

The button transmits a preset code on the 433MHz frequency, and when the MQTT gateway receives that specific code it sends an MQTT instruction via the server to the gate to release the lock.

The final enhancement (for the time being at least) was to change the system so that it turns on the security lights at the front of the house for 2 minutes when the gate is released, provided it’s dark outside. This uses a Sonoff switch wired into the PIR lighting and the Node-Red “Big Timer” node from @scargill to calculate if it’s dark or not. The outside lighting is actually divided into four zones, each of which is controlled by a separate Sonoff and I’ll talk a bit more about that in a later installment.

So, this is a diagram showing how various devices talk to each other…

And this is what the Node-Red flow looks like:

The flow actually has a couple of features I’ve not yet mentioned: RSSI data from the Wemos Pro on the gate, via an MQTT message that’s sent every 5 seconds and pushed out to the app; an online/offline LED in the app to tell me if the Wemos Pro is connected to the network and; feedback to the “OPen Gate” button widget in the Blynk app so that it turns on momentarily when the gate is released via either the RFID tag or the 433MHz button.

Being able to release the gate via the RFID tag is my most important priority, so my code running on the Wemos Pro that’s connected to the RFID reader is written so that it continues to work in stand-alone mode if the Wemos can’t connect to either the Wi-Fi or the MQTT server. It tries briefly to re-connect every 60 seconds if it’s in stand-alone mode, so it goes back to IoT mode when the Wi-Fi etc. is back up and running - without affecting the operation of the RFID system.

I’m currently kicking around a few more enhancements:

  • I’d like to install a microswitch to tell me when the gate is closed. That’s easy from a software point of view, but not so easy from a practicality and reliability angle. I’d probably set-up a Blynk alert if the gate is left open for a certain duration.

  • I also plan to install a CCTV camera that will show me an area that includes the gate, and I might be able to integrate this into the Blynk app, and possibly add a tablet near the door entry intercom to display the CCTV image like a video Entryphone. The CCTV will primarily be to allow me to monitor activity while I’m away, but it could make the door entry system more flexible as well.

  • A system that will send a Blynk alert to tell me when the call button on the door entry system has been pressed. This should be easy to achieve with a simple opto-isolator from the door entry call button. Having this facility will be useful when we have visitors but we’re out of earshot of the door entry system.

Thanks for taking the time to read this, but please don’t ask me for code or for the Node-Red flows.
My setup is very specific to what I’m doing and if you already have the skills then you’d be better starting from scratch to create your own system that meets your specific needs. If you don’t have the skills then I don’t really want to spend my time trying to explain the details and guide you through editing the code and flows to suit your own requirements.

This series of posts are intended to show people what can be achieved quite easily with a Node-Red/MQTT/Blynk setup and to maybe give people inspiration and a few ideas for their own projects.

In future posts I’ll try to explain my outside lighting, heating controller, indoor lights, power cut monitor, blinds controller and weather station projects.


Esp8266 NFC multi door lock system

83 posts were split to a new topic: Comments about automation projects built with MQTT and Node Red


Part 3 – Outside Lighting

This doesn’t sound like a very interesting home automation subject, but actually it makes a big difference to the way that we enjoy the outside space at our home in Spain, especially when we socialise outside in the warm summer evenings and nights.

I’ve installed some external LED floodlights that are linked to PIR detectors and divided into zones. Each zone covers a different outside area and has two or three PIR detectors so that no matter which direction you enter the zone from it turns the lights on for a period of time.

I wanted to add a method of overriding the PIR detectors, which would put the lights on for a longer period – handy when you’re sitting outside eating and drinking, but not moving about enough to keep the PIR detectors constantly triggered; also handy when you’re parking the car, as the movement of the car doesn’t normally trigger the PIRs.

I started by adding a Sonoff Basic to each of the zones and using Blynk as a way of triggering a countdown timer to put the lights on for a pre-set time – 60 minutes in the eating area and 5 minutes in the area where the car is parked.
This worked well, but meant that everyone who wanted to control the lights would need the Blynk app installed on their phone and access to the shared project. Not very convenient for guests, and this approach would mean that our guests would still be able to control the lights long after they’d returned home. I think the fact that it’s not possible to revoke access for specific users is one of the main drawbacks of the Blynk shared app.

As I’d already created a 433MHz to MQTT gateway for my door entry system (see Part 2), I decided to use this as an additional way of starting the countdown timers.
I also added-in Amazon Alexa voice support (I explained this briefly in Part 1), so that it’s very easy to turn on all of the outside lights for a few minutes simply by saying “Alexa, turn the Outside Lights on”, when you’re within earshot of an Alexa device. This is handy when we’re sat indoors at night and hear a strange noise outside and want to quickly put the lights on to see what has caused it. So far all we’ve seen are the local cats disappearing into the shadows, but it’s good to have a quick and simple to use way of scarring-off potential prowlers.

These are the 433MHz fobs that I give to guests:

The red button (A) activates the lights in the seating area for 60 minutes. The other button (B) cancels the timer.
I also have a 4 button fob on my keyring. Buttons A and B work the same as the other fob, Button C puts the lights on in the parking area for 5 minutes and Button D puts all the lights on for 2 minutes. Button B cancels all of these operations.
You’ll see me demonstrating buttons A and B on this fob this in the video at the end.

To explain in more detail what the coding behind this this looks like I created an example in Node-Red that controls just one lighting zone, to demonstrate the countdown timer process and show how the various trigger devices link together. I also decided to use a Slider widget in the example to allow the user to control how long the light should stay on for, once triggered.

Let’s start by looking at the trigger processes (don’t worry about the spider’s web of connections at this stage, I’ll come to those later):

Flow 1

This part of flow shows inputs from

  • The Alexa output from an Alexa device I’ve named “Outside Lights”
  • A Blynk button widget on V1
  • Two “Inject” nodes that allow off/on (0/1) commands to be issued directly from the Node-Red flow
  • The MQTT commands that come from the 433MHz to MQTT gateway (or any MQTT software that can publish to a topic)

The part of the flow that gets the value from the Slider widget on V2 looks like this:

The value from the slider widget (in minutes) arrives into the green node. The orange Function node simply multiplies the number of minutes set using the slider by 60 to turn it into seconds, then stores the value in a global variable called Countdown_Timer.

The code for that looks like looks like this:

global.set('Countdown_Timer',(msg.payload*60)); // Take the minutes value from te slider widget and convert to seconds

Now we’ll see how these triggers and the slider link together:

The wiring looks twice as complex as it could, because of the decision to use a slider to set the countdown time period.
This slider is attached to V2, and whenever an On command is received from any of the trigger devices we need to do the equivalent of a Blynk.syncVirtual(V2); command in C++. This is done with the green Sync node that I’ve called “Sync value from V2 slider”. This simply goes and fetches the slider value from the Blynk cloud server and triggers the equivalent of a BLYNK_WRITE(V2);, so that the current value of the slider setting is pushed to the green “Slider Widget on V2 - Countdown minutes” node.

The trigger device nodes are also connected to a function “Start/Cancel Countdown Timer” Once one of the trigger devices has sent a command to this function it simply simply updates a few global variables, depending on whether it received a 1 or a 0. The code looks like this:

if (msg.payload ==="1")                         // Do this if we received an On command "1"
    global.set('Light_On_Flag',true);           // We annt the light to be on 
    global.set('MQTT_Msg_Sent_Flag',false);     // But the MQTT message to turn the light on hasnt been sent yet

else                                            // Do this if we received an Off command "0"
    global.set('Countdown_Timer',0);            // Reset the countdown timer to zero

return msg;                                     // Output the "1" or "0" as the message payload   

The command is also passed out the other side of the function to update the button widget on V1. This is so that the button in the app stays synchronised with all the other trigger devices. If Alexa turns the lights on then we also want the Blynk button widget to reflect this.

Because the Alexa node can be used to both tiurn the light on/off and to set the duration in minutes that you want the light to stay on for, it has two outputs. The code within the function directs the appropriate command to the correct output, and does a bit of sense-checking on the duration. It would be perfectly acceptable to Alexa to say “Alexa, set Outside light to minus 100”, or “… to 50,000”. In this example, I’ve set the slider widget so that it’s range is 1 to 60, so my code ensures that these are the minimum and maximum values that are outputted from the function node.
Of course, if I say “Alexa, set outside light to 50,000” Alexa will respond “Outside is set to 50,000” but the slider value and the duration of the countdown will be capped at 60 minutes.

Here’s the code for that:

var OnOff;
var Duration;

if (msg.command==='TurnOnRequest')
    return [null, {'payload': OnOff}];

if (msg.command==='TurnOffRequest')
        return [null, {'payload': OnOff}];

if (msg.command=="SetTargetTemperatureRequest")
    if (Duration <=0)
        Temp = 1
    if (Duration >60)
        Duration = 60
    return [{'payload': Temp}, null];

The real processing work is done in this part of the flow:

The blue/grey node on the left hand side called “Auto inject something once every second” does exactly what it says on the tin – it sends a pulse of data out once every second. It doesn’t matter what this data is, it’s simply needed to trigger the “Reduce remaining time by 1 sec” function. Think of it like a Blynk timer calling a function once every second.

The orange “Reduce remaining time by 1 sec” function has two outputs. One sends the remaining countdown time in MM:SS format to the Blynk button widget on V1. This is done using the green node which is a Blynk Set Property node. In this case the property that is being updated is the “On Label” property for the button, so that when the light is on, the button shows the remaining time:

The other output goes to the pink MQTT Output node. This is used to turn the Sonoff Basic that controls the lights on and off. The code running on the Sonoff subscribes to the MQTT topic called “Spain/Outside_Lighting/Seating_Area” and when it sees a “1” in this topic it activates the lights, when it sees a “0” in this topic it deactivates the lights.
I only want to send an MQTT message once at the start and once at the end of the countdown timer process, so the code in my function handles this.
This is the code in the “Reduce remaining time by 1 sec” function. You have to remember that it’s called once every second, regardless of whether the lights are on or off, and that each time it’s called the local variables are wiped clean.

// Initialise the local variables and update them with the GLOBAL variables
var Countdown_Timer = global.get('Countdown_Timer')             //Remaining time that the light stays on for
var Light_On_Flag = global.get('Light_On_Flag')                 // Flag to show if the light is/should be on
var MQTT_Msg_Sent_Flag = global.get('MQTT_Msg_Sent_Flag')       // Flag to show if we've sent the MQTT On message yet
var Completed_Flag = global.get('Completed_Flag')               // Flag to show if we've finished the countdown yet

// Initialise the local variables
var Minutes = 0 // Intermediate variable to hold remaining whole minutes as Integer
var Seconds = 0 // Intermediate variable to hold remaining seconds (0-59) as Integer
var Minutes_String = "" // Intermediate variable to hold remaining whole minutes as String
var Seconds_String = "" // Intermediate variable to hold remaining seconds (0-59) as String
var MM_SS_String = "" // Intermediate variable to hold remaining in MM:SS format String

if (Light_On_Flag && Countdown_Timer>=1)    // If the light is/should be on then we execute this loop until countdown reaches 1
    Countdown_Timer = Countdown_Timer-1;    // Decrement the countdown
    global.set('Countdown_Timer',Countdown_Timer);  // write the new countdown value back to the global variable to store it
    Completed_Flag = false;                         // We're not done yet
    global.set('Completed_Flag',false);             // write the completed flag back to the global variable to store it
    Secs_to_MM_SS();                                // Call the function to convert the remaining time in seconds to MM:SS format
    node.status({fill:"green",shape:"dot", text: MM_SS_String});    // Display the result on the node, to give feedback

   if (MQTT_Msg_Sent_Flag!==true)   // If we've not sent the MQTT message to turn the light on yet, do it now...
        node.send ([{'payload': MM_SS_String}, {'payload': "1"}]); // Write the MM:SS to output 1 and the MQTT on instruction ("1") to output 2
        global.set('MQTT_Msg_Sent_Flag', true);     // Set the flag to show that we've now sent the MQTT instruction
    else    // If we have sent the MQTT On instruction then we don't needs to send it again...
        node.send ([{'payload': MM_SS_String}, null]); // Write the MM:SS to output 1 and nothing to output 2
else    // We get here if the countdown timer is 0 - This will happen once every second when the light is off!! 
    if (Light_On_Flag && Completed_Flag!==true) // Ifr the MQTT message to turn the light off hasn't been sent yet, do this... 
        node.send ([{'payload': "--:--"}, {'payload': "0"}]); // Write "--:--" to output 1 and an MQTT Off command ("0") to output 2 
        Completed_Flag = true   // we're now done
        global.set('Completed_Flag', Completed_Flag);   // write the completed flag back to the global variable to store it
        node.status({text: " "});       // Clear the display on the node
        Light_On_Flag = false   // The light is now off
        global.set('Light_On_Flag', Light_On_Flag); //Update the flag in the global variable

function Secs_to_MM_SS()    // function to convert the remaining time in seconds to MM:SS format
    Minutes=parseInt(Countdown_Timer/60);   // Get the number of whole minutes remaining - Use and integer to round correctly
    Seconds = Countdown_Timer-(Minutes*60); // Get the number of seconds remaining (0 to 59) for the MM:SS display 
    if (Minutes<10)
        Minutes_String = "0" + Minutes.toString()   // If less than 10 minutes remaining then add a leading zero and convert to a string       
        Minutes_String = Minutes.toString() // If more than 10 minutes remaining then no need to add a leading zero - just convert to a string             

    if (Seconds<10)
        Seconds_String = "0" + Seconds.toString()    // If less than 10 seconds remaining then add a leading zero and convert to a string           
        Seconds_String = Seconds.toString()  // If more than 10 seconds remaining then no need to add a leading zero - just convert to a string                 
    MM_SS_String = Minutes_String + ":" + Seconds_String // Create the MM:SS string from the minute and second strings

I’m not going to explain the code in detail here, as I think the in-code comments do that fairly well. The only thing that may not make any sense if you’ve never seen Node-Red before is this bit of code:
node.status({fill:"green",shape:"dot", text: MM_SS_String});
Each node has the ability to display text below the code, to provide information to the user. You’ll have noticed messages like “connected to pin V1”. These are very handy when troubleshooting, and the line of code above displays a green dot with the remaining countdown time in MM:SS format when the light is on.

Flow 5

Here’s the full flow:
You’ll obviously have been paying attention, so you’ll have spotted couple of things that I haven’t mentioned yet…

There’s a connection from the “Start/Cancel Countdown Timer” function to the “Reduce remaining time by 1 sec” function. This isn’t really necessary, but it ensures that when one of the input devices pushes a message into the “Start/Cancel Countdown Timer” function it immediately passes through to the “Reduce remaining time by 1 sec” function. This triggers the function immediately, rather than having to wait until the next 1 second trigger come from the auto inject node. This just makes the lights a bit more responsive, otherwise there could be a response time of up to 1 second before the lights go on or off.

There’s also a connection from the second output of the “Reduce remaining time by 1 sec” to the “Button Widget V1 - Update Start/Cancel switch status” node. This is important, as when the countdown timer reaches the end and sends it’s “0” message to the MQTT node to turn off the light, it also needs to turn the widget button off in the app, to keep everything synchronised.

I made a short video showing it in action. In the video I’ve mirrored the Blynk screen from my phone so that you can see more clearly what’s happening with the button and slider widgets. I’ve also demonstrated that you can use any MQTT client to publish a 1 or a 0 to the “Spain/433/Outside_Light” topic to turn the light on and off, in this case using a program called MQTTfx.

Turn up the sound if you want to hear the Alexa commands and responses.

As you can see, any combination of the input devices can be used to turn the timer on and off. What I’ve not shown is the timeout timer ticking down to zero and switching the light off automatically, but trust me that this works too.

The next installment will be about my heating/air conditioning controller. This will be a very high-level overview as it’s quite a complex system, but it might provide a bit of food for thought for anyone wanting to embark on a similar project.


Alexa read VPIN