Sending Motion & Door open/close events to Slack using Node-RED

Sending slack alerts when doors open and close

This technique uses the following Hardware:

  • Sonoff RF Bridge ($14)
  • RaspberryPi Zero W ($10) + SD Card
  • 433MHz open/close magnetic sensor ($6)
  • 433MHz PIR sensor ($5)
  • Micro USB cables (to power Sonoff + Raspberry Pi)
  • USB to Serial adaptor (to flash Tasmota software onto the Sonoff)

And the following free and/or open source Software:

  • Tasmota (think of this like a mini operating system that will run on the Sonoff RF Bridge, it lets us easily send and receive 433MHz signals via MQTT)
  • Raspbian Buster Lite, this is the operating system we’ll put on the SD card that will run on the Raspberry Pi Zero W
  • Node-RED is the web based tool that lets us easily wire together events that come from MQTT and pipe those events to other devices or services (i.e. MQTT message to Slack message). This software will run on the Raspberry Pi.
  • Mosquitto is a MQTT broker/server that will run on the Raspberry Pi, the Sonoff will send all received 433MHz messages to the MQTT broker. Node-RED is also connected to the MQTT broker so that’s how it sees the 433MHz events.
  • esptool is a command line program used to flash the new Tasmota software onto the Sonoff RF Bridge. We’ll use this once in the initial Tasmota setup. There’s other options for flashing such as via Visual Studio code or Arduino but I find esptool easiest.

Here are the steps covered in detail below:

  1. Flashing Tasmota to the Sonoff RF Bridge (i.e. open it up, connect some wires, use esptool to flash Tasmota to the onboard ESP8266)
  2. Setting up the Raspberry Pi with Node-RED + mosquitto mqtt
  3. Configuring Tasmota to connect to Wifi and send events to our Pi MQTT server
  4. Configuring Node-RED to “do things” when it receives events via MQTT (i.e. post to slash)

Lets get started!

Hardware used in this setup

Flashing Tasmota to the Sonoff RF Bridge:

I’m assuming your running this howto from Linux. Windows and Mac users will need some adjustments around how software is installed and port names etc..

First install esptool ( pip install esptool ) on your laptop. We’ll use this tool to write the Tasmota firmware over Serial to the Sonoff.

Next, open up the Sonoff. Use a small flat screwdriver to remove the sticky feet covering the 4 screws, then undo them like this:

Remove the screws from the back.

Then make sure all power is off and open it up, you’ll see the board sitting inside:

Board inside the Sonoff RF Bridge

Now pull the board out gently, it should pop out with little force:

Inside the Sonoff RF Bridge. The big white thing in the middle is a light that glows when the unit is on, the springey looking things are the antenna.

Now we’re going to bent the light up gently so we can access the main switch, and the serial TX/RX pins easier. Bend up gently like this:

Bending the sonoff light up

Now connect the USB serial cables to the Sonoff, like so (basically just make sure it’s 3v and not 5v and make sure the TX goes to RX, and RX to TX):

USB Serial 3V      =>  Sonoff 3V
USB Serial Ground  =>  Sonoff Ground
USB Serial TX      =>  Sonoff RX
USB Serial RX      =>  Sonoff TX

Then turn the main switch OFF, it should be labelled as OFF on latest Sonoff devices (or just switch it close to the light endpoints). It looks a bit like this:

Connecting the TX/RX serial to Sonoff ready for flashing. With the main switch off.

Now download the latest tasmota.bin firmware file from https://github.com/arendst/Tasmota/releases to your laptop ready to use shortly.

First we’re going to backup the factory Sonoff firmware:

  1. Hold down the button on the side of the Sonoff
  2. Plug the USB Serial adaptor (with the 4 serial cables connected to the Sonoff) into your laptop
  3. Let go of the button after a few seconds. The Sonoff will now be in “flash ready mode”
  4. Make a backup of the firmware with esptool read_flash feature:
$ sudo chown dtbaker: /dev/ttyUSB0  # if your user doesn't have tty access, use this hack to get it quickly and avoid permission denied errors. 

$ esptool.py --port /dev/ttyUSB0 read_flash 0x00000 0x100000 fwbackup.bin

esptool.py v2.8
Serial port /dev/ttyUSB0
Connecting....
Detecting chip type... ESP8266
Chip is ESP8285
Features: WiFi, Embedded Flash
Crystal is 26MHz
MAC: 60:01:94:e4:b9:63
Uploading stub...
Running stub...
Stub running...
1048576 (100 %)
1048576 (100 %)
Read 1048576 bytes at 0x0 in 95.4 seconds (88.0 kbit/s)...
Hard resetting via RTS pin...

$ ls -lh fwbackup.bin 
-rw-rw-r-- 1 dtbaker dtbaker 1.0M Feb  5 20:19 fwbackup.bin

Now we’re going to erase the Sonoff flash, so it’s ready for writing:

$ esptool.py --port /dev/ttyUSB0 erase_flash

esptool.py v2.8
Serial port /dev/ttyUSB0
Connecting....
Detecting chip type... ESP8266
Chip is ESP8285
Features: WiFi, Embedded Flash
Crystal is 26MHz
MAC: 60:01:94:e4:b9:63
Uploading stub...
Running stub...
Stub running...
Erasing flash (this may take a while)...
Chip erase completed successfully in 3.1s
Hard resetting via RTS pin...

Now it’s finally time to write the Tasmota.bin file to the Sonoff that you downloaded before:

$ esptool.py --port /dev/ttyUSB0 write_flash -fs 1MB -fm dout 0x0 

Downloads/tasmota.bin 
esptool.py v2.8
Serial port /dev/ttyUSB0
Connecting....
Detecting chip type... ESP8266
Chip is ESP8285
Features: WiFi, Embedded Flash
Crystal is 26MHz
MAC: 60:01:94:e4:b9:63
Uploading stub...
Running stub...
Stub running...
Configuring flash size...
Compressed 580480 bytes to 399923...
Wrote 580480 bytes (399923 compressed) at 0x00000000 in 35.3 seconds (effective 131.4 kbit/s)...
Hash of data verified.

Leaving...
Hard resetting via RTS pin...

Done!

Now unplug the USB serial adaptor, switch the main board switch from OFF to ON again, and gently push the main light back down into its original place.

While the board is still out of the housing you can plug in a Micro USB power cable to make sure it’s all working before re-assembling everything, just incase you have to flash it again for some reason.

Once it powers up, grab your phone and see if a tasmota-X wifi network is available:

Tasmota has successfully started on the Sonoff

I prefer to use my phone for this initial setup so my laptop still has internet for Googling things etc.. Connect your phone to the tasmota wifi network and visit http://192.168.4.1 then go to the Configure > Wifi section like this:

The Wifi configuration area of the Tasmota interface, as viewed from a phone

Enter your wifi ssid and password into the first two boxes then scroll down to press save. Tasmota will reboot and after 30 seconds it’ll come back up connected to your main Wifi, so you can now access this interface easier from your laptop.

Disconnect / forget the network from your phone, you wont need it again now it’s on main wifi.

Now that Tasmota is on the main wifi you have to find its IP address, as assigned by DHCP. The easiest way to do this is to have a look in your router for the list of connected devices, it should be named tasmota. For me it came through as 172.16.5.93 but it’ll be different for everyone.

So open up the tasmota interface in a web browser from your laptop again:
http://PUT-YOUR-TASMOTA-IP-HERE/

You’ll see this nice interface:

Default Tasmota interface via Web configuration tool

The first thing we need to do is change the overall “mode” of the device from “Basic Module” over to “Sonoff Bridge”. To do this go to Configure Module and choose Sonoff Bridge from the list:

Press save and wait 30 seconds for it to restart. Now refresh the main web interface again and it should look like this, confirming that the device is now in “Bridge” mode:

Sonoff main UI in bridge mode

Configure the Raspberry Pi Zero W with Node-RED and Mosquitto MQTT

Install raspbian buster light onto the Raspberry Pi W SD Card. This is beyond the scope of this blog post. Have a look at here for the download link and some instructions. Using the “light” version of raspbian is fine and will work better on th e low powered Pi Zero: https://www.raspberrypi.org/downloads/raspbian/

Once you’ve installed the Raspberry Pi, configured Wifi and enabled SSH, you can now SSH into the Pi from your laptop and install some software, like so:

$ ssh pi@ip-address-of-pizero-here
Password: raspberry 

$ sudo apt-get update
  .... takes a few minutes

$ sudo apt-get install mosquitto mosquitto-clients nodejs nodered
  .... takes a few minutes

$ sudo systemctl enable nodered.service   # so nodered starts on boot

$ sudo reboot

The first Pi reboot will take a while as Node-RED does its thing and starts up. Check back in a few minutes. Once it’s fully booted and Node-RED has started you can access the UI via a web browser at: http://ip-address-of-pi-here:1880

You should see a blank canvas ready for you to wire up the MQTT to Slack flow.

Connect Tasmota to our new MQTT broker:

Now that we have an MQTT broker installed on the Raspberry Pi (above) we can jump back into our Tasmota web UI and configure it to send all 433MHz events over MQTT to the Pi.

Go to Configure > MQTT and put in the IP address of the Raspberry Pi, and choose a topic that makes sense for your application, like so:

Configure MQTT from Sonoff

Now we can confirm the MQTT broker is receiving 433MHz events by checking the raw MQTT messages using mosquitto_sub command, like this:

$ sudo apt-get install mosquitto-clients
$ mosquitto_sub -h ip-address-of-pi-here -t "#" -v


doorSensors/RESULT {"Time":"2020-02-05T12:20:35","RfReceived":{"Sync":14060,"Low":480,"High":1380,"Data":"3E780E","RfKey":"None"}}

doorSensors/RESULT {"Time":"2020-02-05T12:20:45","RfReceived":{"Sync":14060,"Low":480,"High":1380,"Data":"3E780A","RfKey":"None"}}

If you get a Error: Connection refused message from the mosquitto_sub command ti means the IP address is wrong or the mosquitto server isn’t running on the Raspberry Pi. SSH into the Pi and fix things up.

Setup Node-RED to post messages to Slack

This is the fun part:

An example flow on how to process messages from MQTT and send to Slack

You’ll want to use these Node-RED nodes in the flow;

  • MQTT in (to read messages from the doorSensors/RESULTS topic from MQTT)
  • JSON block (to convert the mqtt string into a JSON object for the next step)
  • Function Block (to split out the device ID and open/close action from MQTT)
  • Count block (to optionally limit how many “motion” alerts to send per minute, if you’re in an area with lots of motion it can be a bit annoying having a constant stream of messages come through, we just need 1 alert)
  • Switch Block (to easily rename device IDs to friendly names like “Front Door”)
  • Function Block (to build out a JSON object that Slack can consume)
  • Slack-web-out Block (to post the message to slack)
Reading MQTT messages into Node-RED
Simple string to JSON conversion
This is the function block to decide the type of motion event and split some strings up
Any messages coming down this line will be restricted to 1 per 5 minutes
Rename our 5 character IDs to friendly names for slack
Build up some JSON that can be sent to slack

And finally we post to slack using the slack-web-out node. You’ll have to install the slack package through Node-RED menu -> “Manage Pallete” -> “Install” -> slack.

And you’ll want a legacy slack API token to configure this node, from here.

Finally send the message to Slack
The messages coming through to Slack from Node-RED

3D printing a case to hold the Sonoff and Raspberry Pi Zero

I wanted a quick case for the Sonoff + Pi duo so they can stick together for this project. The easiest way to do this was using OpenSCAD/ OpenJScad.

So I went over to https://openjscad.org/ and typed out the following quick bit of code, after measuring the size of the sonoff/pi slots:

var wallWidth = 2; // width of walls
var sonoffWidth = 63; // width of the sonoff unit
var sonoffDepth = 21; // depth of the sonoff unit
var raspberryPiZeroWidth = 66;
var raspberryPiZeroDepth = 2;
var unitWidth = raspberryPiZeroWidth + (wallWidth * 2);
var unitDepth = wallWidth + sonoffDepth + wallWidth + raspberryPiZeroDepth + wallWidth;
var unitHeight = 30;

function sonoffHolder() {
  return difference(
    // This is our main hunk of plastic rectangle, we'll cut things out of this:
    cube({size: [unitWidth, unitDepth, unitHeight]}),
    // These are the bits we cut out of the block above:
    union(
      // We move our next cut over into the center of the sonoff cut area:
      translate([(unitWidth - sonoffWidth) / 2, wallWidth, wallWidth],
        // This is the area the sonoff will slot into
        cube({size: [sonoffWidth, sonoffDepth, unitHeight - wallWidth]})
      ),
      translate([(unitWidth - raspberryPiZeroWidth) / 2, wallWidth + sonoffDepth + wallWidth, wallWidth],
        // This is the area the raspberry pi will slot into
        cube({size: [raspberryPiZeroWidth, raspberryPiZeroDepth, unitHeight - wallWidth]})
      )
    )
  );
}

function main() {
  return sonoffHolder();
}

Which produced this beauty:

Next step was to download the STL file and throw it into a Slicer like so:

Slicing the STL into GCODE

Then print:

Then assemble:

Now it’s time to put the sensors up!

Use the included double sided tape, or some glue, or screw them in. Test the sensors have enough range to reach wherever your Sonoff/Tasmota is located. You may have to move the Sonoff around to get the best reception for all your sensors.

Get creative!

Now that you have the basic setup with Sonoff, Tasmota, MQTT and Node-RED you can start to get creative.

  • Maybe graph open, closed and motion events in Grafana?
  • Send push notifications to your phone if you’re not home?
  • Control other 433MHz appliances and switches?
  • Turn a light on when a gate or door is opened?
  • Send an alert if a door is left open too long?

Leave a Reply

Your email address will not be published. Required fields are marked *