Node-RED as a rule/script engine for openHAB

From an automation perspective, not too much. Mostly just some time based events for making sure lights and fans are off during the day, that the garage is closed at night, etc. From a command standpoint, MQTT is a message queue, so all the normal concerns around a distributed system and message order apply here. I could, for instance, totally setup something that turns lights on when a motion detector signals, and a timed event that turns them off at that time and they will conflict. I’m sure I could whip something up with the existing system I have to handle that, but it would basically mean adding real persistence and state comparisons that I don’t do right now.

There are persistence nodes you can integrate so you could conceivably create things like last state change tracking and such (i.e., event says trigger, logic in event says the door was opened less then 5 minutes ago, so don’t close garage door, etc.). Right NOW my system is pretty stateless, except for the MQTT persistence (i.e., a new client connects and it gets sent the last published message for every device topic, meaning the current state).

Just for info. It’s hard to resist user-friendliness of Node-Red also in bindings.
I just wanted to have an event on sunrise and sunset for my rules.
In Openhab I have to install Astro Binding, configure location on openhab.cfg, and define event items (hopefuly copy-paste). So one command and 2 file edits.

In node-red - just install suncalc library and you get nice block with all needed configurability right away. And it’s shows current status right under block for debugging! Cool!

Not tested both approaches yet, but anyway hard to resist.

1 Like

This thread proved most interesting to me. As it happens, I have been using Node-Red too along with MQTT. However, rather than try and replace OpenHab (of which I’ve been very happy), I use it to send state data via the Persistent MQTT plug-in, to a Microsoft Azure IoT Hub. Currently the only thing I do with all this data is dump it into a database. Lack of time. I find that the free IoT Hub is adequate for this.

To accomplish this I threw together a Node-Red module that would understand OpenHab MQTT state input and convert it to JSON for Azure IoT which allows one to run Stream Analytics against the input. It’s smart enough to interrogate OpenHab for the device type so that can be included with the device name and state.

Should anybody be interested in the code, the Node-Red module is on GitHub. Code is reasonable but it is not packaged as an npm. You can find it here: https://github.com/markrad/OH-AzureIoT.

This is a great topic. Thanks to OP!

I had been planning to write my own scheduling utility to work with OH, but it looks like I can leverage Node-RED for everything I need (the node-red-contrib-schedex node looks perfect for my needs).

1 Like

Artyom, thanks for great topic. I’m newbie in OH but already could feel all pain with debugging rules. Installed NR and it looks great, but there is something not clear in my mind

How will item definition look if i want to combine custom protocol with MQTT? Below use cases:

  1. Item gets event from outside and should forward it to MQTT. I described item as below
Switch  DemoSwitch    "Demo switch"    { megadevice="sec:192.168.0.10:2", mqtt=">[mosquitto:house/room/light:command:*:default]" }

As result, item state is updated correctly by event from custom binding, but OH doesn’t forward change status to MQTT. If i change item state via UI then i get messages in MQTT. Should i forward change status to MQTT by rules in this case?

  1. The same scenario in opposite direction - NR made a decision and now i should send a command to device via MQTT-OH-custom binding.

Can you shed light on details of such configuration?

Hi Dmitry,

There is no need to bind every item individually - you just use Event bus binding configuration, as described in https://github.com/openhab/openhab/wiki/MQTT-Binding
E.g in my openhab.cfg file I have following definitions for MQTT:

mqtt:mybroker.url=tcp://localhost:1883
mqtt:mybroker.retain=true
mqtt-eventbus:broker=mybroker
mqtt-eventbus:commandPublishTopic=/myhome/in/${item}
mqtt-eventbus:statePublishTopic=/myhome/state/${item}

mqtt-eventbus:stateSubscribeTopic=/myhome/out/${item}
mqtt-eventbus:commandSubscribeTopic=/myhome/command/${item}/state

Mosquitto broker in my case runs on the same machine.
As a result all events automatically appear as MQTT messages and you can send commands to /myhome/command/${item}/state topic - and these will be processed by OpenHab

3 Likes

@Artyom_Syomushkin

Thanks for that. I keep forgetting about the event bus.

Michael, any chance you can (after removing security stuff) share you Alexa flow?
Or if you copied it from somewhere can you send a link to the material you used?

I’m not sure I should just drop a JSON blob here, and I’m not sure it’d be entirely helpful to you anyway as its specific to my setup so you’d have to heavily modify it. Also I can’t guarantee its still right because I use Google Home now. But I can give you an idea of what I did.

  1. I added a POST endpoint per room (I based all commands on “turn on [room] [device]”, etc. I had ONE endpoint at first, but this worked better for some reason, and I do an Alexa skill per room.
  2. Because I did an endpoint per room, I modified the message coming in to add msg.payload.request.intent.slots.room = { “value”: “master bedroom” }; for instance, since Alexa wasn’t responsible for sending me that anymore.
  3. I checked message type and only process “IntentRequest”. There is also “SessionEndedRequest” and “LaunchRequest”, but for basic control you don’t have to deal with these.
  4. I then parse the intent type Alexa sent. For me, these are intent types I created in the skill, like “OnOffIntent”, “LevelIntent” and “OpenCloseIntent”. Each requires a slightly different message to eventually be sent to my MQTT system, so I treat each a little differently.
  5. Then the only tricky part: Alexa’s role is done here. so for every output of the switch, I go to a node that builds a response message, and then to an http return node. You can build the message with a template or function node (latter is better IMO). Just do a “return { … };” in it. The message format is documented, but here ya go:
    {
      "version": "1.0",
      "response": {
        "outputSpeech": {
          "type": "PlainText",
          "text": "OK"
        },
        "shouldEndSession": true
      }
    }
  1. Then for each of those output nodes on the switch you can also link to whatever your internal actions need to be. For me this is building MQTT messages on the slots the Alexa message sent over, but this’ll be specific to your implementation of the skill and your system. My nodes end up building an intermediate message that I then pass to a function I wrote to build an MQTT message from that format:
    var room = msg.payload.request.intent.slots.room.value;
    var device = msg.payload.request.intent.slots.device.value;
    var value = msg.payload.request.intent.slots.onOffState.value;

    var newMsg = {};
    newMsg.payload = {
        room: room,
        device: device,
        value: value
    };

    return newMsg;

One thing that I’ll point out: Alexa requires you to use SSL, so you are going to have to figure out how to enable SSL on your node-red installation. Alexa will let you self sign and upload a public key for verification in the skill. Google will not, so I actually use letsencrypt to get a real cert.

You will also need to poke a hole through your router firewall for port 443 and point it at the node-red install.

But if you really want to lock this down correctly, here’s what I did:

  1. Install nginx on the machine.
  2. Leave node-red in default mode, no SSL.
  3. Setup letsencrypt on the box and get an SSL cert onto the nginx install correctly. Good luck, this was a pain in the ass.
  4. Setup nginx to proxy the node-red install, and to allow external IPs to ONLY access the Alexa endpoints you created:
    server {
      listen 443 ssl;
      ssl on;
      ssl_certificate PATHTOPEM;
      ssl_certificate_key PATHTOPRIVATEPEM;
      ssl_verify_depth 3;
      ssl_protocols TLSv1.1 TLSv1.2;
      ssl_ciphers "ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SH"`;`

      location / {
        allow 192.168.1.0/24;
        deny all;
        try_files $uri @proxy;
      }

      location ~* ^/(ROOTOFYOUREXPOSEDENDPOINTS) {
        allow all;
        try_files $uri @proxy;
      }

      location @proxy {
        proxy_pass http://localhost:1880;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
      }
    }

Automating openHAB Items with Node-RED without MQTT hassle ? Try node-red-contrib-openhab2

1 Like

I am really loving that node-red-contrib-openhab2 plugin. Working like a charm.

Now I can replace the openHAB rules with Node-RED :slight_smile:

1 Like

Does the extra processing add much delay in rule execution? Being a non-programmer this looks like a much easier way for rule creation and I like the other integrations available.

From my perspective I didn’t see any delays doing things through node-RED. The ease of debugging the flows just makes things so much easier.

What kind of delays are you worried about?

I have a few light rules that trigger off manual switches so trying to make sure they trigger as soon as possible to when the other switch is turned on/off.

I played with it for about an hour today and it doesn’t seem to have as much flexibility as the text based rules files (for example it only triggers a new message when a value is changed, whereas in the OH2 rules I can fire off a rule when a value is updated even if it is updated with the same value)

@Peter_De_Mangelaere Thanks for putting together the OH2 node. Is it possible to expand the in bound messaging to include the same types of trigger events as OH rules (received update and received command)? Specifically I use the on update quite a bit where I want to capture a trigger event even if it doesn’t change the actual state of the item.

1 Like

Just my two cents, I played with Node-RED as a rule processor for OpenHab2. I did this because the JavaScript plugin was not available for OpenHab2 at the time. I dislike XTend(?). I find it very clunky. In the end I implemented all of my rules in standard Node JS modules. I found implementing rules in Node-RED such as “turn off this light in ten minutes unless something else happens or something wants to keep it on for longer” difficult to define in Node-RED. In Node they were still a pain but I felt I had a more granular level of control.

Thanks for the feedback.
Give me a few days to implement the expansion of inbound messages the most convenient way.

I’ll feedback when ready.

Great, thanks!!

By the way Michael, thanks.
The details such as SSL certificate stuff is a little more than I want to bite off.

@Peter_De_Mangelaere it doesn’t work here. OpenHab items list is empty. http://localhost:8080/rest/items working fine … No debug log on console.