Node-RED as Alternative Rule Engine

Hi All

A happy new year to everyone :slight_smile:

Something has been bugging me for a while, so I have spent an hour finding a solution.

What I wanted to do was mimic the Press and Hold dimming / volume change that you might see in some hardware.

I found a way to detect a button event, get the current Item state (a number) and add or subtract a number then inject the new value back into the Volume or Dimmer Item.

This worked well, I had 2 buttons.
1 for up
1 for down

I could even use the Long_Press and Release states from these buttons to loop the trigger so that holding the button down kept on having an effect, until the button was released.

What I wanted to do was reduce this down to 1 button, that would increase the volume (or brightness) until a limit was hit, then decrease until another limit was hit.

I found the solution by using a Global Value in Node Red.

Here is what I have running now in a Function node :smile_cat:

var volume = Number(msg.payload.state);
var button = String(msg.payload_in);
var newMsg = { payload:button};
var Dir = global.get("LoungeDir");

var newVolume = 0;

//  newVolume = volume + 5;
msg.payload = volume;

if (isNaN(Dir)) {
     global.set("LoungeDir", 1);
     Dir = global.get("LoungeDir");
}

if  (volume <= 6 ) { if (Dir == -1)  {
        newVolume = volume + 5;
        msg.payload = newVolume;
        global.set("LoungeDir", 1);
        return [msg,newMsg];
	}}
	
if  (volume <= 90 ) { if (Dir == 1)  {
        newVolume = volume + 5;
        msg.payload = newVolume;
//        global.set("LoungeDir", 1);
        return [msg,newMsg];
	}}
	
if  (volume >= 90 ) { if (Dir == 1)  {
        newVolume = volume - 5;
        msg.payload = newVolume;
        global.set("LoungeDir", -1);
        return [msg,newMsg];
	}}
	
if  (volume <= 90 ) { if (Dir == -1)  {
        newVolume = volume - 5;
        msg.payload = newVolume;
//        global.set("LoungeDir", 1);
        return [msg,newMsg];
	}}	



return [msg,newMsg]; 

Here is the entire collection of Nodes

[
    {
        "id": "bfe462be.f71a5",
        "type": "function",
        "z": "f5370db.29be5f",
        "name": "Dining Room Btn 3",
        "func": "var event = msg.payload.event;\nvar channel = msg.payload.channel;\nvar newMsg = { payload: msg.payload.event };\nvar button = \"velbus:vmbgp2:c5053467:24:input#CH3\"\n\nif  (channel === button )  {\n\tif (event === \"PRESSED\") {\n\t\treturn [msg, newMsg, null, null];\n\t}\n\tif (event === \"LONG_PRESSED\") {\n\t\treturn [msg, null, newMsg, null];\n\t}\n\tif (event === \"RELEASED\") {\n\t\treturn [msg, null, null, newMsg];\n\t}\n}\nreturn null;",
        "outputs": 4,
        "noerr": 0,
        "x": 390,
        "y": 140,
        "wires": [
            [],
            [
                "6ba85279.a48a9c"
            ],
            [
                "82c396c8.6ef1d8"
            ],
            [
                "f7ff8751.3c9c78"
            ]
        ],
        "outputLabels": [
            "Whole Msg",
            "PRESSED",
            "LONG_PRESSED",
            "RELEASED"
        ]
    },
    {
        "id": "6ba85279.a48a9c",
        "type": "openhab2-get",
        "z": "f5370db.29be5f",
        "name": "",
        "controller": "deaa963.282a968",
        "itemname": "LoungeZone_Volume",
        "x": 880,
        "y": 60,
        "wires": [
            [
                "b93a65be.3a6588"
            ]
        ]
    },
    {
        "id": "4954678d.cca448",
        "type": "openhab2-out",
        "z": "f5370db.29be5f",
        "name": "Lounge Volume",
        "controller": "deaa963.282a968",
        "itemname": "LoungeZone_Volume",
        "topic": "ItemCommand",
        "payload": "",
        "x": 1220,
        "y": 140,
        "wires": [
            []
        ]
    },
    {
        "id": "82c396c8.6ef1d8",
        "type": "looptimer",
        "z": "f5370db.29be5f",
        "duration": "1",
        "units": "Second",
        "maxloops": "15",
        "maxtimeout": "1",
        "maxtimeoutunits": "Minute",
        "name": "",
        "x": 700,
        "y": 140,
        "wires": [
            [
                "6ba85279.a48a9c"
            ],
            []
        ]
    },
    {
        "id": "f7ff8751.3c9c78",
        "type": "change",
        "z": "f5370db.29be5f",
        "name": "Stop Loop",
        "rules": [
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "STOP",
                "tot": "str"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 570,
        "y": 240,
        "wires": [
            [
                "82c396c8.6ef1d8"
            ]
        ]
    },
    {
        "id": "b93a65be.3a6588",
        "type": "function",
        "z": "f5370db.29be5f",
        "name": "Change Volume value by 5",
        "func": "var volume = Number(msg.payload.state);\nvar button = String(msg.payload_in);\nvar newMsg = { payload:button};\nvar Dir = global.get(\"LoungeDir\");\n\nvar newVolume = 0;\n\n//  newVolume = volume + 5;\nmsg.payload = volume;\n\nif (isNaN(Dir)) {\n     global.set(\"LoungeDir\", 1);\n     Dir = global.get(\"LoungeDir\");\n}\n\nif  (volume <= 6 ) { if (Dir == -1)  {\n        newVolume = volume + 5;\n        msg.payload = newVolume;\n        global.set(\"LoungeDir\", 1);\n        return [msg,newMsg];\n\t}}\n\t\nif  (volume <= 90 ) { if (Dir == 1)  {\n        newVolume = volume + 5;\n        msg.payload = newVolume;\n//        global.set(\"LoungeDir\", 1);\n        return [msg,newMsg];\n\t}}\n\t\nif  (volume >= 90 ) { if (Dir == 1)  {\n        newVolume = volume - 5;\n        msg.payload = newVolume;\n        global.set(\"LoungeDir\", -1);\n        return [msg,newMsg];\n\t}}\n\t\nif  (volume <= 90 ) { if (Dir == -1)  {\n        newVolume = volume - 5;\n        msg.payload = newVolume;\n//        global.set(\"LoungeDir\", 1);\n        return [msg,newMsg];\n\t}}\t\n\n\n\nreturn [msg,newMsg];",
        "outputs": 2,
        "noerr": 0,
        "x": 900,
        "y": 200,
        "wires": [
            [
                "deb42c17.7b645",
                "4954678d.cca448"
            ],
            [
                "43fac0f6.8305b"
            ]
        ]
    },
    {
        "id": "ec5643f1.2da01",
        "type": "inject",
        "z": "f5370db.29be5f",
        "name": "",
        "topic": "",
        "payload": "PRESSED",
        "payloadType": "str",
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "x": 340,
        "y": 200,
        "wires": [
            [
                "6ba85279.a48a9c"
            ]
        ]
    },
    {
        "id": "deb42c17.7b645",
        "type": "debug",
        "z": "f5370db.29be5f",
        "name": "",
        "active": true,
        "tosidebar": false,
        "console": false,
        "tostatus": true,
        "complete": "payload",
        "targetType": "msg",
        "x": 1210,
        "y": 200,
        "wires": []
    },
    {
        "id": "43fac0f6.8305b",
        "type": "debug",
        "z": "f5370db.29be5f",
        "name": "",
        "active": true,
        "tosidebar": false,
        "console": false,
        "tostatus": true,
        "complete": "payload",
        "targetType": "msg",
        "x": 1210,
        "y": 260,
        "wires": []
    },
    {
        "id": "569a9540.f364ec",
        "type": "inject",
        "z": "f5370db.29be5f",
        "name": "",
        "topic": "",
        "payload": "LONG_PRESSED",
        "payloadType": "str",
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "x": 310,
        "y": 240,
        "wires": [
            [
                "82c396c8.6ef1d8"
            ]
        ]
    },
    {
        "id": "a2023990.27a8e8",
        "type": "inject",
        "z": "f5370db.29be5f",
        "name": "",
        "topic": "",
        "payload": "10",
        "payloadType": "str",
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "x": 1190,
        "y": 60,
        "wires": [
            [
                "4954678d.cca448"
            ]
        ]
    },
    {
        "id": "63c707ec.0969b8",
        "type": "inject",
        "z": "f5370db.29be5f",
        "name": "",
        "topic": "",
        "payload": "RELEASED",
        "payloadType": "str",
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "x": 330,
        "y": 280,
        "wires": [
            [
                "f7ff8751.3c9c78"
            ]
        ]
    },
    {
        "id": "deaa963.282a968",
        "type": "openhab2-controller",
        "z": "",
        "name": "OpenHAB2 Home",
        "protocol": "http",
        "host": "127.0.0.1",
        "port": "8080",
        "path": "",
        "username": "",
        "password": ""
    }
]

The amusing thing (or at least to my mind) is that if I hold the button in the Long_Press state, the volume (or brightness) will happily glide between 5 & 95.

Not a feature I can see using very often, but a nice side effect.

I hope this helps someone.

Best wishes,

Stuart

1 Like