mysensors node red proxy flow

Quick Project: MySensors MQTT Proxy with Node-RED

This post may contain affiliate links. Please see the disclaimer for more information.

In my previous exploration of MySensors, I encountered issues with the range of the nrf24l01+ radio. One of the simplest solutions to this problem is to move the gateway closer to the intended deployment of the sensors. In my case the sensor is positioned on the back wall of our house, just outside the master bedroom. Connected to the TV inside the master bedroom is a Raspberry Pi running Libreelec. I reasoned that I should be able to use this Pi to proxy the MySensors serial data to Home Assistant via MQTT, using the MySensors Node-RED nodes. With this approach I can make a new MQTT gateway using hardware I already have deployed.

It was also suggested that adding a 10-100uF 6.3/10V capacitor across the power line to the radio would also help with the range issues. I’m definitely going to do this, but the components haven’t arrived yet!

Hardware Setup

If you followed my previous post all you need to do here is plug in the serial gateway to the Pi! Otherwise you’re going to need to build a gateway (and maybe some sensors). Go check out my original post for more details.

It’s probably worth going through how this is going to work. Basically, the idea is that the RF data will be received by our existing MySensors gateway and sent via serial to the RPi. This will be read by Node-RED, re-encoded and sent via MQTT to Home Assistant which will still act as the MySensors controller:

Serial GW ⇒ Serial Connection ⇒ Node-RED (on RPi) ⇒ MQTT ⇒ HASS (Controller)

In the return direction this dataflow operates in reverse:

HASS ⇒ MQTT ⇒ Node-RED ⇒ Serial Connection ⇒ Serial GW

Deploying Node-RED on Libreelec

Libreelec is a cut down appliance-like Linux distribution, specifically for running Kodi. At first glance it seems like installing a third party program such as Node-RED would be difficult. However, Libreelec has Docker support via an add-on, which makes things as easy as running the command:

$ docker run -d --restart=always --device=/dev/ttyUSB0:/dev/ttyUSB0 --group-add dialout -v /storage/node-red-data:/data -p 1880:1880 --name node-red nodered/node-red:latest

This starts the Node-RED Docker container with access to the serial port for our plugged in Arduino board. You’ll need to adjust the path to the TTY device depending on how the Arduino gets enumerated. We are also storing the data for Node-RED (including flows) in the Libreelec storage directory, so that we can re-create the container without losing our flows.

Once this starts up, you should be able to access a nice clean Node-RED instance on port 1880 of your Libreelec Pi. At this point it’s probably a good idea secure your instance and set up projects for backing up your flows via Git.

MySensors Proxy Flow

So here’s what you came here for. Using the MySensors nodes I’ve created a flow which receives MySensors data via the serial port decodes it to a Javascript object and then immediately encodes it and sends it via MQTT. To do this we make use of the serial decode and MQTT encode nodes. In the opposite direction we receive MQTT data on the mysensors/in/# wildcard and decode it to another JS object. This is then immediately encoded for serial and sent out the serial port. The finished flow looks like this:

mysensors node red proxy flow
The MySensors proxy flow

The full JSON for this is below. You’ll need to update the details for the MQTT broker and serial port to match your installation:

[{"id":"750924cf.e87e14","type":"tab","label":"MySensors MQTT Proxy","disabled":false,"info":""},{"id":"e7a50a55.c700d8","type":"mysdecode","z":"750924cf.e87e14","database":"","name":"Decode Serial","mqtt":false,"enrich":false,"x":244,"y":125,"wires":[["1fe04ed1.423d09"]]},{"id":"1fe04ed1.423d09","type":"mysencode","z":"750924cf.e87e14","name":"Encode MQTT","mqtt":true,"mqtttopic":"mysensors/out","x":429,"y":125,"wires":[["73eb8bcf.3be6bc"]]},{"id":"73eb8bcf.3be6bc","type":"mqtt out","z":"750924cf.e87e14","name":"","topic":"","qos":"","retain":"","broker":"61f77eeb.b75e2","x":584,"y":125,"wires":[]},{"id":"1a5ca295.7db125","type":"serial in","z":"750924cf.e87e14","name":"serial in","serial":"31aea0d6.e5a438","x":87,"y":125,"wires":[["e7a50a55.c700d8"]]},{"id":"5a8336a4.b9d398","type":"mqtt in","z":"750924cf.e87e14","name":"","topic":"mysensors/in/#","qos":"2","datatype":"auto","broker":"61f77eeb.b75e2","x":117,"y":179,"wires":[["b8c6fd6f.3ecf08"]]},{"id":"b8c6fd6f.3ecf08","type":"mysdecode","z":"750924cf.e87e14","database":"","name":"Decode MQTT","mqtt":true,"enrich":false,"x":320,"y":180,"wires":[["440bfad4.44eadc"]]},{"id":"440bfad4.44eadc","type":"mysencode","z":"750924cf.e87e14","name":"Encode Serial","mqtt":false,"mqtttopic":"","x":508,"y":179,"wires":[["e8c5f4bd.bc3d3"]]},{"id":"e8c5f4bd.bc3d3","type":"serial out","z":"750924cf.e87e14","name":"serial out","serial":"31aea0d6.e5a438","x":676,"y":179,"wires":[]},{"id":"61f77eeb.b75e2","type":"mqtt-broker","z":"","name":"Home Broker","broker":"mqtt.example.com","port":"1883","tls":"b8f1023d.4df4","clientid":"","usetls":false,"compatmode":true,"keepalive":"60","cleansession":true,"birthTopic":"nodered/status","birthQos":"2","birthRetain":"true","birthPayload":"online","closeTopic":"nodered/status","closeQos":"2","closeRetain":"true","closePayload":"offline","willTopic":"nodered/status","willQos":"2","willRetain":"true","willPayload":"offline"},{"id":"31aea0d6.e5a438","type":"serial-port","z":"","serialport":"/dev/ttyUSB0","serialbaud":"115200","databits":"8","parity":"none","stopbits":"1","waitfor":"","dtr":"none","rts":"none","cts":"none","dsr":"none","newline":"\\n","bin":"false","out":"char","addchar":"","responsetimeout":"10000"},{"id":"b8f1023d.4df4","type":"tls-config","z":"","name":"Home Broker","cert":"","key":"","ca":"","certname":"","keyname":"","caname":"","verifyservercert":true}]

That’s it for the flow. We can integrate this into HASS by changing our previous gateway configuration to use MQTT:

mysensors:
  gateways:
    - device: mqtt
      persistence_file: '/config/mysensors.json'
      topic_in_prefix: 'mysensors/out'
      topic_out_prefix: 'mysensors/in'

Conclusion

With this in place I’m now able to receive data from my sensor in the greenhouse without the reception issues I was experiencing. I like the use of Node-RED for these kinds of protocol conversion jobs. Its dataflow model is supremely suited to these operations.

Other than the range issue, the MySensors node I built in my previous post has been pretty reliable. I did make a minor hardware change to the setup I described earlier, which was to move positive battery connection from the raw power line to the VCC line of the Arduino. This is because the raw line is regulated to 3.3V. The voltage regulator will consume some power and also won’t work once the battery voltage drops below about 3.3V. Connecting to VCC powers the micro directly from the battery without the extra power loss. Since this modification the sensor has been running flawlessly for several weeks.

If you liked this post and want to see more, please consider subscribing to the mailing list (below) or the RSS feed. You can also follow me on Twitter. If you want to show your appreciation, feel free to buy me a coffee.

Loading

mysensors greenhouse sensor

Prototyping Battery Powered Sensors with MySensors and Home Assistant

This post may contain affiliate links. Please see the disclaimer for more information.

Sometimes it’s nice to be able to undertake a spur of the moment project that can be completed in a couple of hours. Of course, this rarely happens if the project is hardware related due to the need to wait for any parts you may not have to hand. This article will relate one such rare occurrence in my decision to try out the MySensors project for an outdoor, battery powered sensor prototype which would be integrated with Home Assistant.

The motivation for this project was the installation of a small greenhouse kit from the local hardware store, so that we had somewhere sheltered to raise seeds for the garden. The positioning of the greenhouse is along the back wall of our house, which gets quite a bit of sun. I realised it would be nice to log the temperature inside the greenhouse and send notifications when it was outside certain thresholds. I could then go out to open the door and otherwise check on the seedlings. As you will see below, I was able to build such a sensor very quickly and get it running using pretty much unmodified example code.

About MySensors

MySensors is an Arduino library for building low power mesh networked sensors based NRF24L01+ and RFM69 radios. It allows you to easily get the networking up and running so you can focus on building and deploying your sensors.

The sensors connect back to a gateway device which forwards traffic on to some controller software. There are several different types of gateway available, ranging from a simple serial gateway to networked options using MQTT and the ESP8266. There are also several different controllers available. However, I’ll be focussing on using Home Assistant.

Since these sensors are based on relatively low powered components, such as low bit-rate radios and 8-bit Arduinos they are much more suited to battery operation than the equivalent ESP8266 or ESP32 based sensor. The trade off for this is that the performance and capabilities are lower. For that reason I’d advise you to use an ESP based system with ESPHome if you have a decent power supply available or where you are actuating devices that already have higher power requirements. This is because MySensors actuation devices are not allowed to sleep in order to receive commands, which negates many of the power savings.

Parts and Assembly

For my initial deployment I wanted to test the power usage of a sensor in the field so as to see if this approach is viable. This sensor would use a DHT11 temperature and humidity sensor along with the radio and would be powered from 2xAA batteries. I also built a simple serial gateway which I connected directly to my main server via USB.

mysensors home assistant
The assembled gateway
mysensors home assistant
The assembled electronics for the sensor

The parts used in my build were as follows:

mysensors case
The sensor case, fresh off the printer
mysensors case
Packing the electronics in the case resulted in quite the birds nest
mysensors case
However, everything looked neat with the lid on!

These were assembled pretty much as per the instructions. First I connected up the radios to both gateway and sensor. I then connected up the DHT sensor and the battery holder on the sensor side. It’s worth noting that I used digital pin 4 rather than pin 3 for the DHT because I connected it without looking at the instructions. However, it makes little difference, just a minor change to the example code.

I didn’t make any hardware optimisations for low power usage at this stage, except for the obvious one of removing the power LED on the pro mini board (LED1 on the schematic). This will save a significant amount of power, since otherwise it would be on all the time.

Software

The software side of things was even more trivial than the hardware. For the gateway I just flashed the provided serial gateway code. For the sensor I just flashed the DHT example code with the small modification to the pin noted above. Both of these just worked without any further tweaking. The DHT example did require me to include a custom DHT sensor library which I copied from the git repo in question.

I used my preferred tool of Platformio for building and flashing. The only things to consider here are to initialise the projects with the correct board names (diecimilaatmega328 and pro8MHzatmega328 in my case) and to install the MySensors library in each project. This can be accomplished with the command:

platformio lib install --save MySensors

If you want to reproduce my exact setup or use it as a basis for your own, you can grab my code from GitLab.

Connecting MySensors to Home Assistant

With the firmware flashed to the devices, the next step is setting up the MySensors controller in Home Assistant. The first step in this process was making the serial adapter of the Arduino available through the layers of virtualisation in my setup. In order to do this I first added the serial adapter as a USB device to the KVM virtual machine via virt-manager. Secondly, I added the device to the Home Assistant container in my docker-compose.yml file with the entry:

devices:
  - /dev/ttyUSB0:/dev/ttyUSB0

Once the deployment had finished, I was able to add the MySensors integration to my Home Assistant configuration, which I did in a new package file:

mysensors:
   gateways:
     - device: /dev/ttyUSB0
       persistence_file: '/config/mysensors.json'
   debug: true
   persistence: true
   version: '2.3'
   optimistic: false

This sets up the integration with a single serial gateway on the port in question. With HASS restarted after this change, I was able to see my sensors. However, the entity IDs and resulting friendly names are based on the MySensors internal identifiers. I don’t really mind the cryptic entity IDs, but I updated the friendly names by adding the following to my customize section:

sensor.temperatureandhumidity_3_0:
friendly_name: "Greenhouse Humidity"

sensor.temperatureandhumidity_3_1:
friendly_name: "Greenhouse Temperature"

Notifications

The final step in the HASS setup for this achieves the goal of being notified when I need to check on the seedlings. This was accomplished via a couple of simple automations:

automation:
  - alias: "Greenhouse High Temperature Notification"
    trigger:
      platform: numeric_state
      entity_id: sensor.temperatureandhumidity_3_1
      above: 27
      for:
        minutes: 30
    condition:
      condition: state
      entity_id: input_boolean.greenhouse_active
      state: 'on'
    action:
      service: notify.family
      data_template:
        title: "Greenhouse Temperature High!"
        message: "The greenhouse temperature is {{ states.sensor.temperatureandhumidity_3_1.state }}{{ states.sensor.temperatureandhumidity_3_1.attributes.unit_of_measurement }}. You may wish to open the door and check if the plants need watering."
  - alias: "Greenhouse Low Temperature Notification"
    trigger:
      platform: numeric_state
      entity_id: sensor.temperatureandhumidity_3_1
      below: 11
      for:
        minutes: 30
    condition:
      condition: state
      entity_id: input_boolean.greenhouse_active
      state: 'on'
    action:
      service: notify.family
      data_template:
        title: "Greenhouse Temperature Low!"
        message: "The greenhouse temperature is {{ states.sensor.temperatureandhumidity_3_1.state }}{{ states.sensor.temperatureandhumidity_3_1.attributes.unit_of_measurement }}. You may wish to close the door."

These are pretty simple and send the notifications via my Gotify server. The only minor bit of complexity was that I added an input boolean to allow the notifications to be controlled together. I could just as easily turn off both automation rules when the greenhouse is not in use, but it’s nice to have a single switch for that purpose:

input_boolean:
  greenhouse_active:
    name: "Greenhouse In Use"
    icon: mdi:sprout

Range Issues

With all that in place, I tested the sensor overnight inside the house and then deployed it the following morning. I had placed it inside as close to the back wall where the greenhouse is located as possible and it worked fine. It even worked fine after deploying it in the greenhouse for around 12 hours.

mysensors greenhouse sensor
The sensor deployed inside the greenhouse (from inside)
mysensors home assistant
From outside the plastic of the greenhouse protects the electronics from the elements

Then it stopped sending data.

I brought the sensor in and examined it. The battery voltage was fine and after a reset it came back up, so I deployed it again. The same thing happened within a few minutes. I then brought the sensor back inside and put it in the garage, just a few meters from the gateway. It’s been operating there successfully for several days.

I can only conclude from this that the radio range is pretty poor. I have a couple of mitigations in mind for this, the first of these will be to move the gateway closer to the garden. For this I may need a networked gateway, or I may plug it into a nearby Raspberry Pi. I’ll try the Raspberry Pi idea first and see if I can get it working with the Node-RED MySensors nodes. Ideally, I’d like these just to operate as a proxy so that the MySensors controller will still be Home Assistant.

The other potential mitigation is to use a radio with a higher gain antenna and amplifier on the gateway. I may do this anyway in time in order to get better range into the garden for other sensors.

Conclusion

Overall I’m pretty pleased with the MySensors setup I’ve been able to create here. It’s very much a prototype and there are still a few issues to work out, but it’s promising. The best thing is that it only took me a couple of hours, though this was aided massively by having the parts already to hand.

MySensors itself seems quite nice and there is certainly a large community around it. As compared to other offerings such as ESPHome, it feels a bit basic to actually have to write (or copy) Arduino code and upload it to the device. I much prefer the YAML approach for describing simple sensors. That said, I still had to write no code in order to get this working! I’d love to see a similar YAML based code generator for this platform though.

I’ll definitely be building and deploying a few more MySensors nodes, primarily in the garden where ability to run off batteries for a decent length of time is a great advantage. However, I need to fix the range issue first, which I’ll be sure to post an update on.

As always please get in contact to share your own experiences!

If you liked this post and want to see more, please consider subscribing to the mailing list (below) or the RSS feed. You can also follow me on Twitter. If you want to show your appreciation, feel free to buy me a coffee.

Loading