Node-RED as Alternative Rule Engine

i suck at gates i guess becuse i did not undertsand a thing :slight_smile:

I can work on a better example to understand the functionality. I am on it :smiley: give me 20 minutes

Okay I hope this will help you understanding the logic gates :slight_smile:
Logic Gate Addon

Here is the code to paste this flow so you can try and error yourself :slight_smile:
The White boxes contain more information. Copy below or via pastebin https://pastebin.com/BLYGFn1Q

[
    {
        "id": "3cac3927.abaf16",
        "type": "inject",
        "z": "127fd315.6c04dd",
        "name": "",
        "topic": "",
        "payload": "OPEN",
        "payloadType": "str",
        "repeat": "",
        "crontab": "",
        "once": false,
        "x": 165.5,
        "y": 176,
        "wires": [
            [
                "4d2ba3b8.29ec84",
                "72652330.3a11ac",
                "6da9c580.db005c"
            ]
        ]
    },
    {
        "id": "25fb8c64.060d0c",
        "type": "inject",
        "z": "127fd315.6c04dd",
        "name": "",
        "topic": "",
        "payload": "CLOSED",
        "payloadType": "str",
        "repeat": "",
        "crontab": "",
        "once": false,
        "x": 158,
        "y": 208,
        "wires": [
            [
                "4d2ba3b8.29ec84",
                "72652330.3a11ac",
                "6da9c580.db005c"
            ]
        ]
    },
    {
        "id": "bda906de.dfdf78",
        "type": "comment",
        "z": "127fd315.6c04dd",
        "name": "Item Door",
        "info": "This block displays a Door item from openHAB with the status OPEN/CLOSED",
        "x": 154.5,
        "y": 145,
        "wires": []
    },
    {
        "id": "6d8cfd0d.a20944",
        "type": "inject",
        "z": "127fd315.6c04dd",
        "name": "",
        "topic": "",
        "payload": "ON",
        "payloadType": "str",
        "repeat": "",
        "crontab": "",
        "once": false,
        "x": 170,
        "y": 409,
        "wires": [
            [
                "c7d3f01.b3cba1",
                "5fd52631.fe9be8",
                "b69b8cef.4fec58"
            ]
        ]
    },
    {
        "id": "3a25038.87822fc",
        "type": "inject",
        "z": "127fd315.6c04dd",
        "name": "",
        "topic": "",
        "payload": "OFF",
        "payloadType": "str",
        "repeat": "",
        "crontab": "",
        "once": false,
        "x": 171.5,
        "y": 441,
        "wires": [
            [
                "c7d3f01.b3cba1",
                "5fd52631.fe9be8",
                "b69b8cef.4fec58"
            ]
        ]
    },
    {
        "id": "cf9b9b63.27f8e",
        "type": "comment",
        "z": "127fd315.6c04dd",
        "name": "Item Movement Detection",
        "info": "This block displays a movment detection from openHAB\nwith the states ON/OFF",
        "x": 115,
        "y": 378,
        "wires": []
    },
    {
        "id": "78014ba9.80a13c",
        "type": "comment",
        "z": "127fd315.6c04dd",
        "name": "Logic Gate Info",
        "info": "I used this \"Addon\"\nhttps://flows.nodered.org/node/node-red-contrib-bool-gate",
        "x": 667.5,
        "y": 612,
        "wires": []
    },
    {
        "id": "4a8849d1.f8a308",
        "type": "comment",
        "z": "127fd315.6c04dd",
        "name": "openHAB INFO",
        "info": "so far as I have noticed, openHAB items do not\npublish a topic so we need to \"inject a topic ourself\"\n",
        "x": 666.5,
        "y": 580,
        "wires": []
    },
    {
        "id": "a9865891.288bd",
        "type": "change",
        "z": "127fd315.6c04dd",
        "name": "topic=mov",
        "rules": [
            {
                "t": "set",
                "p": "topic",
                "pt": "msg",
                "to": "mov",
                "tot": "str"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 555,
        "y": 443,
        "wires": [
            [
                "e36cea52.be3638",
                "f21e0fc0.db63e8",
                "efbc1126.53ca4"
            ]
        ]
    },
    {
        "id": "cbc9801c.5635e8",
        "type": "change",
        "z": "127fd315.6c04dd",
        "name": "topic=door",
        "rules": [
            {
                "t": "set",
                "p": "topic",
                "pt": "msg",
                "to": "door",
                "tot": "str"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 590,
        "y": 202,
        "wires": [
            [
                "2cda8f2f.a5bb98",
                "a5c3cc89.843c78",
                "f2afec2d.eb6ca"
            ]
        ]
    },
    {
        "id": "4d2ba3b8.29ec84",
        "type": "debug",
        "z": "127fd315.6c04dd",
        "name": "",
        "active": true,
        "console": "false",
        "complete": "false",
        "x": 348.5,
        "y": 97,
        "wires": []
    },
    {
        "id": "72652330.3a11ac",
        "type": "debug",
        "z": "127fd315.6c04dd",
        "name": "",
        "active": true,
        "console": "false",
        "complete": "topic",
        "x": 338,
        "y": 130,
        "wires": []
    },
    {
        "id": "2cda8f2f.a5bb98",
        "type": "debug",
        "z": "127fd315.6c04dd",
        "name": "",
        "active": true,
        "console": "false",
        "complete": "false",
        "x": 850,
        "y": 112,
        "wires": []
    },
    {
        "id": "a5c3cc89.843c78",
        "type": "debug",
        "z": "127fd315.6c04dd",
        "name": "",
        "active": true,
        "console": "false",
        "complete": "topic",
        "x": 839.5,
        "y": 145,
        "wires": []
    },
    {
        "id": "6da9c580.db005c",
        "type": "delay",
        "z": "127fd315.6c04dd",
        "name": "",
        "pauseType": "delay",
        "timeout": "5",
        "timeoutUnits": "seconds",
        "rate": "1",
        "nbRateUnits": "1",
        "rateUnits": "second",
        "randomFirst": "1",
        "randomLast": "5",
        "randomUnits": "seconds",
        "drop": false,
        "x": 401.5,
        "y": 204,
        "wires": [
            [
                "cbc9801c.5635e8"
            ]
        ]
    },
    {
        "id": "b69b8cef.4fec58",
        "type": "delay",
        "z": "127fd315.6c04dd",
        "name": "",
        "pauseType": "delay",
        "timeout": "5",
        "timeoutUnits": "seconds",
        "rate": "1",
        "nbRateUnits": "1",
        "rateUnits": "second",
        "randomFirst": "1",
        "randomLast": "5",
        "randomUnits": "seconds",
        "drop": false,
        "x": 389,
        "y": 443,
        "wires": [
            [
                "a9865891.288bd"
            ]
        ]
    },
    {
        "id": "c7d3f01.b3cba1",
        "type": "debug",
        "z": "127fd315.6c04dd",
        "name": "",
        "active": true,
        "console": "false",
        "complete": "false",
        "x": 355,
        "y": 337,
        "wires": []
    },
    {
        "id": "5fd52631.fe9be8",
        "type": "debug",
        "z": "127fd315.6c04dd",
        "name": "",
        "active": true,
        "console": "false",
        "complete": "topic",
        "x": 344.5,
        "y": 370,
        "wires": []
    },
    {
        "id": "f2afec2d.eb6ca",
        "type": "delay",
        "z": "127fd315.6c04dd",
        "name": "",
        "pauseType": "delay",
        "timeout": "5",
        "timeoutUnits": "seconds",
        "rate": "1",
        "nbRateUnits": "1",
        "rateUnits": "second",
        "randomFirst": "1",
        "randomLast": "5",
        "randomUnits": "seconds",
        "drop": false,
        "x": 832,
        "y": 217,
        "wires": [
            [
                "f431570a.0bd32",
                "3d7e8aef.ff113e"
            ]
        ]
    },
    {
        "id": "efbc1126.53ca4",
        "type": "delay",
        "z": "127fd315.6c04dd",
        "name": "",
        "pauseType": "delay",
        "timeout": "5",
        "timeoutUnits": "seconds",
        "rate": "1",
        "nbRateUnits": "1",
        "rateUnits": "second",
        "randomFirst": "1",
        "randomLast": "5",
        "randomUnits": "seconds",
        "drop": false,
        "x": 802,
        "y": 449,
        "wires": [
            [
                "f431570a.0bd32",
                "3d7e8aef.ff113e"
            ]
        ]
    },
    {
        "id": "f431570a.0bd32",
        "type": "and-gate",
        "z": "127fd315.6c04dd",
        "name": "",
        "rules": [
            {
                "t": "eq",
                "v": "OPEN",
                "vt": "str",
                "propertyType": "msg",
                "property": "payload",
                "topic": "door"
            },
            {
                "t": "eq",
                "v": "ON",
                "vt": "str",
                "propertyType": "msg",
                "property": "payload",
                "topic": "mov"
            }
        ],
        "outputTopic": "resultTopic",
        "gateType": "and",
        "emitOnlyIfTrue": true,
        "x": 1046.5,
        "y": 322,
        "wires": [
            [
                "80597c64.31837",
                "be7ce667.592698"
            ]
        ]
    },
    {
        "id": "e36cea52.be3638",
        "type": "debug",
        "z": "127fd315.6c04dd",
        "name": "",
        "active": true,
        "console": "false",
        "complete": "false",
        "x": 724,
        "y": 351,
        "wires": []
    },
    {
        "id": "f21e0fc0.db63e8",
        "type": "debug",
        "z": "127fd315.6c04dd",
        "name": "",
        "active": true,
        "console": "false",
        "complete": "topic",
        "x": 716.5,
        "y": 384,
        "wires": []
    },
    {
        "id": "80597c64.31837",
        "type": "debug",
        "z": "127fd315.6c04dd",
        "name": "",
        "active": true,
        "console": "false",
        "complete": "false",
        "x": 1241,
        "y": 289,
        "wires": []
    },
    {
        "id": "be7ce667.592698",
        "type": "debug",
        "z": "127fd315.6c04dd",
        "name": "",
        "active": true,
        "console": "false",
        "complete": "topic",
        "x": 1231.5,
        "y": 321,
        "wires": []
    },
    {
        "id": "f1219097.361278",
        "type": "comment",
        "z": "127fd315.6c04dd",
        "name": "Information!",
        "info": "This Flow aims to ask for 2 States of 2 Items and\ncheck for both results OPEN/ON to forward to the\nnext stepp.",
        "x": 656,
        "y": 547,
        "wires": []
    },
    {
        "id": "fc18ecd4.206ed",
        "type": "comment",
        "z": "127fd315.6c04dd",
        "name": "inject topic door",
        "info": "",
        "x": 600.5,
        "y": 232,
        "wires": []
    },
    {
        "id": "127ea454.adb43c",
        "type": "comment",
        "z": "127fd315.6c04dd",
        "name": "inject topic mov",
        "info": "",
        "x": 565,
        "y": 475,
        "wires": []
    },
    {
        "id": "3d7e8aef.ff113e",
        "type": "or-gate",
        "z": "127fd315.6c04dd",
        "name": "",
        "rules": [
            {
                "t": "eq",
                "v": "OPEN",
                "vt": "str",
                "propertyType": "msg",
                "property": "payload",
                "topic": "door"
            },
            {
                "t": "eq",
                "v": "ON",
                "vt": "str",
                "propertyType": "msg",
                "property": "payload",
                "topic": "mov"
            }
        ],
        "outputTopic": "",
        "gateType": "or",
        "emitOnlyIfTrue": true,
        "x": 1040.5,
        "y": 441,
        "wires": [
            [
                "df869ae4.3bf64",
                "2ac08dd8.fb5fe2"
            ]
        ]
    },
    {
        "id": "c06f6f07.95d598",
        "type": "comment",
        "z": "127fd315.6c04dd",
        "name": "INFO",
        "info": "This gate will only forward if the \"Door\" is OPEN\nand the Movement Detection is \"ON\"\n\n\"True Restriction\" meens only forward the payload\nif the gates is **green** TRUE",
        "x": 1037.5,
        "y": 290,
        "wires": []
    },
    {
        "id": "a0bf7769.6bf8c",
        "type": "comment",
        "z": "127fd315.6c04dd",
        "name": "INFO",
        "info": "This gate will forward if the \"door\" is OPEN **OR**\nthe movment detection is ON\n\n\"True Restriction\" meens only forward the payload\nif the gates is **green** TRUE",
        "x": 1032,
        "y": 409,
        "wires": []
    },
    {
        "id": "df869ae4.3bf64",
        "type": "debug",
        "z": "127fd315.6c04dd",
        "name": "",
        "active": true,
        "console": "false",
        "complete": "false",
        "x": 1218,
        "y": 421,
        "wires": []
    },
    {
        "id": "2ac08dd8.fb5fe2",
        "type": "debug",
        "z": "127fd315.6c04dd",
        "name": "",
        "active": true,
        "console": "false",
        "complete": "topic",
        "x": 1207.5,
        "y": 454,
        "wires": []
    }
]  
3 Likes

Thank you so much i will give it try !
edit:now i got it :slight_smile:
and i think first exmaple has some issue, this is why i did not understand
the or gate was not working there i think…

I tested both gates, and both worked for me

1 Like

Just thought this might be useful to someone… working with groups between Openhab and Node-red.

In this example we want to know the general state of the group, but also the member that caused it to turn to this state and use this information as a variable towards a Pushover notification. Let’s say a group containing door sensors (ON, OFF).

In my example i want to have a Pushover notification tell me which sensor caused the gDoorWindowSensorAllOO group to change to ON.

  • The group state is part of the msg.payload
  • The status of each individual members is provided as an array in msg.payload.members

  • gDoorWindowSensorAllOO is the Openhab group
  • Splitter is the node used to split every object in the array into separate messages
  • Switch is used to filter only the messages matching ON
  • The orange template node is used to format the Pushover message using a variable for the payload
  • the pushover Openhab is the actual pushover item that Openhab uses to send the pushover notification

gDoorWindowSensorAllOO

Splitter (install the splitter node from the palette in Node-red)

Switch

Template Node

vPushover

[{"id":"c40cbb29.6ae5c8","type":"openhab2-get","z":"21a0918d.92d92e","name":"gDoorWindowSensorAllOO","controller":"be8b0821.df18b8","itemname":"gDoorWindowSensorAllOO","x":360,"y":300,"wires":[["c4e75089.d06b3"]]},{"id":"2b19c903.238346","type":"openhab2-out","z":"21a0918d.92d92e","name":"vPushover","controller":"be8b0821.df18b8","itemname":"vPushover","topic":"ItemUpdate","payload":"","x":1050,"y":300,"wires":[]},{"id":"2650a2cd.a46bbe","type":"template","z":"21a0918d.92d92e","name":"Send error info","field":"payload","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"Door/Window open: {{payload.label}} !","output":"str","x":860,"y":300,"wires":[["2b19c903.238346"]]},{"id":"c4e75089.d06b3","type":"splitter","z":"21a0918d.92d92e","name":"","property":"payload.members","x":570,"y":300,"wires":[["49d325c0.7d5fdc"]]},{"id":"49d325c0.7d5fdc","type":"switch","z":"21a0918d.92d92e","name":"","property":"payload.state","propertyType":"msg","rules":[{"t":"eq","v":"ON","vt":"str"}],"checkall":"true","repair":false,"outputs":1,"x":690,"y":300,"wires":[["2650a2cd.a46bbe"]]},{"id":"f3b75c98.93c21","type":"comment","z":"21a0918d.92d92e","name":"Split based on array","info":"Test","x":330,"y":260,"wires":[]},{"id":"be8b0821.df18b8","type":"openhab2-controller","z":"","name":"Openhab2 - Prod","protocol":"http","host":"localhost","port":"8080","path":"","username":"","password":""}]
4 Likes

Can you please confirm that the trailing ` is correct?

I am getting this error with it:

2018-11-20 11:46:31.786 [WARN ] [el.core.internal.ModelRepositoryImpl] - Configuration model ‘vNotification.items’ has errors, therefore ignoring it: [2,43]: extraneous input ‘`’ expecting EOF

The trailing ’ is incorrect and should be removed. it will make your error/WARN go away

1 Like

Everything works fine without it. Thanks.

Hi,

I am very interesting in Node Red as alternative rule engine. And the most part from my old rules, I migrate to Node Red. On point is current still unclear for me. Maybe one of you have an idea.

In my old rules a use the astro events to make my garten light on or of. My rule is:

rule "Sonnenuntergang Event"
when
    Channel 'astro:sun:home:set#event' triggered START
then   
    //Gartenbeleuchtung
    soS20_1.sendCommand(ON)
end

rule "Sonnenaufgang Event"
when
    Channel 'astro:sun:home:rise#event' triggered START
then   
    //Gartenbeleuchtung
    soS20_1.sendCommand(OFF)
end

But with Node Red I tried sunevents and a lot of other nodes to use this logic in Node Red. I also tried the examples in this thread, but I did not get it working. Any idea to migrate my logic to Node Red?

BR
Rene

U can use the “bigtimer” node in node-red to accomplish this.

2 Likes

Thanks. I will try it.

New to red node, but have been trying to get alarm function flows up and running

I found a contrib node here: https://flows.nodered.org/node/node-red-contrib-alarm and installed it as it can be used with the homekit contrib node previously mentioned in this thread.

The node guide has this warning:
WARNING: There is NO infinite loop detection right now! So MAKE SURE if you create ANY path from a “StateChanged” to a “ChangeState” node, that you MUST ensure the loop is not permanent or you will burn up cpu! A good enhancement would be perhaps to build in a “keepalive” countdown for 2 iterations or something to auto-kill a message stuck in a loop if anyone wants to take that on.

How do I add such a function between the change status node and homekit item to stop infinite loops?

Thanks in advance. Apologies if I have missed any required details needed to answer the above
John

@john0wingnut - The RBE node is a good option for this. Only sends through a message if it’s payload is different from the previous message.

The other homekit node specific option will be seen in many of your other functions (since I know you’ve copied mine) the line you’re looking for is:

if (msg.hap.context !== undefined ) { }

Any script inside of the { } on that if statement will only happen if the message is from a homekit node. In other words, msg.hap.context is only defined if the message originated in a homekit node.

For those using node red as an openhab rule engine substitute I’d really recommend installing the time range switch node


image

It gives you a lot of flexibility routing the payload one of two ways depending on a time range.

7 Likes

Yep really useful…

@BrutalBirdie

Hi

Did you ever find a solution to this issue?

I would like to be able to use Channel trigger data in NodeRed flows too.

Something like this

   Channel 'velbus:vmbgpod:d212bf44:2C:input#CH1' triggered
or Channel 'velbus:vmbgpod:d212bf44:2C:input#CH2' triggered
or Channel 'velbus:vmbgpod:d212bf44:2C:input#CH3' triggered
or Channel 'velbus:vmbgpod:d212bf44:2C:input#CH4' triggered 

Where the possible states are

RELEASED
PRESSED
LONG_PRESSED

The only thing I can think of so far is to create a blanket DSL rule that maps the state of these triggers to Virtual Items in openHAB2.

Using this thread as inspiration… - Passing receivedEvent and triggeringItem as parameters to a lambda: which type to use? - #3 by shutterfreak

I created this rule, which I might be able to use to map events to virtual items

rule "Button Event mapper"
when
	   Channel 'velbus:vmbgpod:d212bf44:2C:input#CH1' triggered
	or Channel 'velbus:vmbgpod:d212bf44:2C:input#CH2' triggered
	or Channel 'velbus:vmbgpod:d212bf44:2C:input#CH3' triggered
	or Channel 'velbus:vmbgpod:d212bf44:2C:input#CH4' triggered
then


//		receivedEvent.channel.toString // Full 'channel' that triggered the event
//		receivedEvent.channel.thingUID.toString // Thing ID portion of channel (everything before the last ':')
//		receivedEvent.channel.id.toString // ID portion of channel (everything after the last ':')

	logInfo("Button Event","This button "+receivedEvent.channel.toString.replace(":","_").replace("#","_")+" -- Had this Event "+receivedEvent.getEvent())

    sendCommand(receivedEvent.channel.toString.replace(":","_").replace("#","_"),receivedEvent.getEvent())

end

You can just use a function node to filter for the event connected to the Openhab events node. Just connect a debug node that shows the whole message object to the Openhab-events node and trigger your event. The events node passes all openhab events so be aware there will be alot happening. You will see what your event is called in the nodered debug once you find it there and you can than write a simple if function in a function node to only pass this payload and even map different outputs of the function node to different openhab events. No need for any DSL rules.

2 Likes

Okay…

I can’t pretend that I totally understand all that, but I’ll give it a try :slight_smile:

I think it will be the syntax of the Function node that will stop me :sob:

1 Like

If you have any questions just ask, I used this approach before I moved to Mqtt for connecting openhab and nodered and it worked quite good.