Node-RED nodes for hubitat

Since this is a very active thread for a long time already and it is well appreciated and viewed, i added it to the “wiki” list I created as a starting point for the community. Hope you are ok with that @fblackburn.

Suggestions, links, contributions etc are welcome.

5 Likes

Any C-8 beta testers migrated their Node-RED setup? Anything to watch out for?

My Node-Red flows have been working without change - had to reauthorize the MakerAPI interface.

5 Likes

Wow, this is such an eye-opener to me! Thank you!
I wrestled with RM way too long, and not being able to make simple changes without a lot of head scratching is awesome.

Note-to-self: goodbye RM!

1 Like

Hi @fblackburn, first of all thanks for developing and sharing this amazing extension!

Would it be possible to add expressions to the Arguments field of the Command node?
Something like {{msg.payload.value}}.

I can add a Change node and set the msg.arguments there, but I'd rather have less nodes and use the original message.

Currently I find myself always having to add a Change node before a Command node.

3 Likes

FWIW, convenience aside, the computational expense of that extra change node is next to nothing.

2 Likes

It is really just for the convenience, less nodes to deal with, less maintenance, easier to copy and change flows, etc.

Nodes are the bread and butter of Node-Red. More nodes is more or less the expectation. Nodes are bite-sized steps along the way to a perfect automation.

I have a bunch of Change nodes who's only purpose is to normalize the names. The Function can certainly accept the original names but I have two Thermostat drivers and I want a common Function.

Are you sure? The Command Node doesn't require that.. but maybe it's just that I commonly use two command nodes.

Screenshot 2023-04-27 at 8.22.08 AM

I would find that convenient as well. Many of the built-in nodes support mustache referencing, so this certainly would not be unheard of.

That said, it is a nice to have not have to have for me.

3 Likes

Yes, some commands like on/off or open/close don't require arguments, then you don't need a Change node.
I have just started automating my apartment, and I have lots of shades. I'm using the setPosition command which requires the position argument. I'm sure there will be other flows without arguments, I just didn't get to them yet.

That is the beauty of programming, you have unlimited ways of solving things!
What I have proposed wouldn't change anything in your organization style, since it would be optional.

1 Like

I typically use a single change node to provide both a command and an argument (if needed). And then I recycle the same change node in other sequences that have a similar outcome .....

1 Like

Me too. Because I'm also paranoid and strip out any other arguments/ commands.

A few times I had daisy chaining logic and a few extra argument parameters made their way to places they shouldn't.

So now I sanitize the input before it goes into the hubitat nodes (when I have multiple commands in a chain anyway).

Same. And I have had a similar issue as well; for example, a command failing because an illegal argument from much earlier in the sequence was passed along.

For some time I was selecting devices via change nodes as well, but stopped doing that because of the high possibility of errors occurring due to sloppy sequence building.

1 Like

As a software developer, code duplication is the source of all evil in my opinion.
I'm just starting with Node-RED, so if you could provide more details on how you avoid node duplication, it would be great :slight_smile:
I have few automations and I'm already having bad feelings about the spreading duplications.

1 Like

You may want to look at subflows to see if they work for your use case.

https://nodered.org/docs/user-guide/editor/workspace/subflows

1 Like

And/or link calls.

2 Likes

@csteele, I've been using Node-RED for over a year, and never noticed the three arguments for setColorTemparature. Thanks for pointing this out.

How would you get the color temperature AND level from global variables to enter into one command node?

Here's what I'm currently doing:
image
I feel that I could save some network traffic by sending these as one command, especially since I've got 75 lights updating with circadian and level.

1 Like

You can do this using a template node. I’ll post a sample sequence when I get home.

1 Like

Screenshot 2023-04-27 at 5.29.30 PM

Create a msg.arguments, I happen to use a Function in this example:

Screenshot 2023-04-27 at 5.29.02 PM
And then just leave the Argument blank:

Screenshot 2023-04-27 at 5.29.48 PM

2 Likes

@JonL

With NR, there are many ways to skin a cat. @csteele provided one method, using a function node, to set hue/saturation/level or colorTemp/level.

Here are two others in the context of a set of sequences that demonstrate how to capture the state of an RGBW device to a set of flow variables, and restore that captured state using the previously saved flow variables.

I've demonstrated two ways to pass H+S+L or CT+L to msg.arguments during the restore. The first method uses a join node. The second, which is cleaner, uses a template node.

Sequence that can be imported
[
    {
        "id": "91a3133eb0da7fd1",
        "type": "tab",
        "label": "Capture/Restore",
        "disabled": false,
        "info": ""
    },
    {
        "id": "bd43a28e31299b4e",
        "type": "join",
        "z": "91a3133eb0da7fd1",
        "name": "json join",
        "mode": "custom",
        "build": "object",
        "property": "payload",
        "propertyType": "msg",
        "key": "topic",
        "joiner": ",",
        "joinerType": "str",
        "accumulate": false,
        "timeout": "",
        "count": "3",
        "reduceRight": false,
        "reduceExp": "",
        "reduceInit": "",
        "reduceInitType": "num",
        "reduceFixup": "",
        "x": 900,
        "y": 580,
        "wires": [
            [
                "1a20d06b3e2b00de"
            ]
        ]
    },
    {
        "id": "33c87a8fe098f670",
        "type": "change",
        "z": "91a3133eb0da7fd1",
        "name": "hue",
        "rules": [
            {
                "t": "set",
                "p": "topic",
                "pt": "msg",
                "to": "hue",
                "tot": "str"
            },
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "nightstand_hue",
                "tot": "flow"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 690,
        "y": 540,
        "wires": [
            [
                "bd43a28e31299b4e"
            ]
        ]
    },
    {
        "id": "9e9ff88f8850ec97",
        "type": "delay",
        "z": "91a3133eb0da7fd1",
        "name": "",
        "pauseType": "delay",
        "timeout": "1",
        "timeoutUnits": "milliseconds",
        "rate": "1",
        "nbRateUnits": "1",
        "rateUnits": "second",
        "randomFirst": "1",
        "randomLast": "5",
        "randomUnits": "seconds",
        "drop": false,
        "allowrate": false,
        "outputs": 1,
        "x": 775,
        "y": 580,
        "wires": [
            [
                "bd43a28e31299b4e"
            ]
        ],
        "l": false
    },
    {
        "id": "882f9aa4ccd461d8",
        "type": "delay",
        "z": "91a3133eb0da7fd1",
        "name": "",
        "pauseType": "delay",
        "timeout": "2",
        "timeoutUnits": "milliseconds",
        "rate": "1",
        "nbRateUnits": "1",
        "rateUnits": "second",
        "randomFirst": "1",
        "randomLast": "5",
        "randomUnits": "seconds",
        "drop": false,
        "allowrate": false,
        "outputs": 1,
        "x": 775,
        "y": 620,
        "wires": [
            [
                "bd43a28e31299b4e"
            ]
        ],
        "l": false
    },
    {
        "id": "1a20d06b3e2b00de",
        "type": "change",
        "z": "91a3133eb0da7fd1",
        "name": "setColor",
        "rules": [
            {
                "t": "set",
                "p": "command",
                "pt": "msg",
                "to": "setColor",
                "tot": "str"
            },
            {
                "t": "set",
                "p": "arguments",
                "pt": "msg",
                "to": "$string(payload)",
                "tot": "jsonata"
            },
            {
                "t": "delete",
                "p": "payload",
                "pt": "msg"
            },
            {
                "t": "delete",
                "p": "topic",
                "pt": "msg"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 1060,
        "y": 580,
        "wires": [
            [
                "752c91c1499e6c0d"
            ]
        ]
    },
    {
        "id": "ebaff8760d384dad",
        "type": "inject",
        "z": "91a3133eb0da7fd1",
        "name": "capture",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payloadType": "str",
        "x": 190,
        "y": 220,
        "wires": [
            [
                "d493e99a42f7e962"
            ]
        ]
    },
    {
        "id": "b844cd04e44b82c2",
        "type": "change",
        "z": "91a3133eb0da7fd1",
        "name": "sat",
        "rules": [
            {
                "t": "set",
                "p": "topic",
                "pt": "msg",
                "to": "saturation",
                "tot": "str"
            },
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "nightstand_sat",
                "tot": "flow"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 670,
        "y": 580,
        "wires": [
            [
                "9e9ff88f8850ec97"
            ]
        ]
    },
    {
        "id": "a068ec247987c0a3",
        "type": "change",
        "z": "91a3133eb0da7fd1",
        "name": "lvl",
        "rules": [
            {
                "t": "set",
                "p": "topic",
                "pt": "msg",
                "to": "level",
                "tot": "str"
            },
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "nightstand_level",
                "tot": "flow"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 670,
        "y": 620,
        "wires": [
            [
                "882f9aa4ccd461d8"
            ]
        ]
    },
    {
        "id": "752c91c1499e6c0d",
        "type": "hubitat command",
        "z": "91a3133eb0da7fd1",
        "deviceLabel": "Nightstand",
        "name": "",
        "server": "a22e0ea9.276dc8",
        "deviceId": "1848",
        "command": "",
        "commandArgs": "",
        "x": 1230,
        "y": 520,
        "wires": [
            []
        ]
    },
    {
        "id": "34509478991b20e0",
        "type": "change",
        "z": "91a3133eb0da7fd1",
        "name": "setCT",
        "rules": [
            {
                "t": "set",
                "p": "command",
                "pt": "msg",
                "to": "setColorTemperature",
                "tot": "str"
            },
            {
                "t": "set",
                "p": "arguments",
                "pt": "msg",
                "to": "$string(payload)",
                "tot": "jsonata"
            },
            {
                "t": "delete",
                "p": "payload",
                "pt": "msg"
            },
            {
                "t": "delete",
                "p": "topic",
                "pt": "msg"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 1070,
        "y": 460,
        "wires": [
            [
                "752c91c1499e6c0d"
            ]
        ]
    },
    {
        "id": "0b1d78c881efdaa9",
        "type": "join",
        "z": "91a3133eb0da7fd1",
        "name": "string join",
        "mode": "custom",
        "build": "string",
        "property": "payload",
        "propertyType": "msg",
        "key": "topic",
        "joiner": ",",
        "joinerType": "str",
        "accumulate": false,
        "timeout": "",
        "count": "3",
        "reduceRight": false,
        "reduceExp": "",
        "reduceInit": "",
        "reduceInitType": "num",
        "reduceFixup": "",
        "x": 900,
        "y": 460,
        "wires": [
            [
                "34509478991b20e0"
            ]
        ]
    },
    {
        "id": "3a6e9026443d9a4b",
        "type": "change",
        "z": "91a3133eb0da7fd1",
        "name": "CT",
        "rules": [
            {
                "t": "set",
                "p": "topic",
                "pt": "msg",
                "to": "CT",
                "tot": "str"
            },
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "nightstand_ct",
                "tot": "flow"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 690,
        "y": 420,
        "wires": [
            [
                "0b1d78c881efdaa9"
            ]
        ]
    },
    {
        "id": "fa09d8b57c2cae11",
        "type": "delay",
        "z": "91a3133eb0da7fd1",
        "name": "",
        "pauseType": "delay",
        "timeout": "1",
        "timeoutUnits": "milliseconds",
        "rate": "1",
        "nbRateUnits": "1",
        "rateUnits": "second",
        "randomFirst": "1",
        "randomLast": "5",
        "randomUnits": "seconds",
        "drop": false,
        "allowrate": false,
        "outputs": 1,
        "x": 775,
        "y": 460,
        "wires": [
            [
                "0b1d78c881efdaa9"
            ]
        ],
        "l": false
    },
    {
        "id": "a172a41701dca630",
        "type": "delay",
        "z": "91a3133eb0da7fd1",
        "name": "",
        "pauseType": "delay",
        "timeout": "2",
        "timeoutUnits": "milliseconds",
        "rate": "1",
        "nbRateUnits": "1",
        "rateUnits": "second",
        "randomFirst": "1",
        "randomLast": "5",
        "randomUnits": "seconds",
        "drop": false,
        "allowrate": false,
        "outputs": 1,
        "x": 775,
        "y": 500,
        "wires": [
            [
                "0b1d78c881efdaa9"
            ]
        ],
        "l": false
    },
    {
        "id": "a29e26c0b164ffaa",
        "type": "inject",
        "z": "91a3133eb0da7fd1",
        "name": "restore",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payloadType": "str",
        "x": 190,
        "y": 520,
        "wires": [
            [
                "d7d131b5316c0ae1"
            ]
        ]
    },
    {
        "id": "6c7591caf5a8ae1b",
        "type": "change",
        "z": "91a3133eb0da7fd1",
        "name": "lvl",
        "rules": [
            {
                "t": "set",
                "p": "topic",
                "pt": "msg",
                "to": "level",
                "tot": "str"
            },
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "nightstand_level",
                "tot": "flow"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 670,
        "y": 460,
        "wires": [
            [
                "fa09d8b57c2cae11"
            ]
        ]
    },
    {
        "id": "adc81e31e3a921e5",
        "type": "change",
        "z": "91a3133eb0da7fd1",
        "name": "time",
        "rules": [
            {
                "t": "set",
                "p": "topic",
                "pt": "msg",
                "to": "time",
                "tot": "str"
            },
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "0",
                "tot": "str"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 670,
        "y": 500,
        "wires": [
            [
                "a172a41701dca630"
            ]
        ]
    },
    {
        "id": "d493e99a42f7e962",
        "type": "hubitat device",
        "z": "91a3133eb0da7fd1",
        "deviceLabel": "Nightstand",
        "name": "",
        "server": "a22e0ea9.276dc8",
        "deviceId": "1848",
        "attribute": "",
        "sendEvent": false,
        "x": 350,
        "y": 220,
        "wires": [
            [
                "335faf55a5b1b2e2"
            ]
        ]
    },
    {
        "id": "335faf55a5b1b2e2",
        "type": "change",
        "z": "91a3133eb0da7fd1",
        "name": "nightstand",
        "rules": [
            {
                "t": "set",
                "p": "nightstand_switch",
                "pt": "flow",
                "to": "payload.switch.value",
                "tot": "msg"
            },
            {
                "t": "set",
                "p": "nightstand_colorMode",
                "pt": "flow",
                "to": "payload.colorMode.value",
                "tot": "msg"
            },
            {
                "t": "set",
                "p": "nightstand_ct",
                "pt": "flow",
                "to": "payload.colorTemperature.value",
                "tot": "msg"
            },
            {
                "t": "set",
                "p": "nightstand_hue",
                "pt": "flow",
                "to": "payload.hue.value",
                "tot": "msg"
            },
            {
                "t": "set",
                "p": "nightstand_sat",
                "pt": "flow",
                "to": "payload.saturation.value",
                "tot": "msg"
            },
            {
                "t": "set",
                "p": "nightstand_level",
                "pt": "flow",
                "to": "payload.level.value",
                "tot": "msg"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 530,
        "y": 220,
        "wires": [
            []
        ]
    },
    {
        "id": "d7d131b5316c0ae1",
        "type": "switch",
        "z": "91a3133eb0da7fd1",
        "name": "on/off",
        "property": "nightstand_switch",
        "propertyType": "flow",
        "rules": [
            {
                "t": "eq",
                "v": "on",
                "vt": "str"
            },
            {
                "t": "eq",
                "v": "off",
                "vt": "str"
            }
        ],
        "checkall": "true",
        "repair": false,
        "outputs": 2,
        "x": 330,
        "y": 520,
        "wires": [
            [
                "ae9b298edeef2436"
            ],
            [
                "190351b1c435ba0d"
            ]
        ]
    },
    {
        "id": "ae9b298edeef2436",
        "type": "switch",
        "z": "91a3133eb0da7fd1",
        "name": "CT or RGB",
        "property": "nightstand_colorMode",
        "propertyType": "flow",
        "rules": [
            {
                "t": "eq",
                "v": "CT",
                "vt": "str"
            },
            {
                "t": "eq",
                "v": "RGB",
                "vt": "str"
            }
        ],
        "checkall": "true",
        "repair": false,
        "outputs": 2,
        "x": 490,
        "y": 520,
        "wires": [
            [
                "3a6e9026443d9a4b",
                "6c7591caf5a8ae1b",
                "adc81e31e3a921e5"
            ],
            [
                "33c87a8fe098f670",
                "b844cd04e44b82c2",
                "a068ec247987c0a3"
            ]
        ]
    },
    {
        "id": "de897648d00e3312",
        "type": "comment",
        "z": "91a3133eb0da7fd1",
        "name": "CAPTURE",
        "info": "",
        "x": 180,
        "y": 160,
        "wires": []
    },
    {
        "id": "88864d62853db2d2",
        "type": "comment",
        "z": "91a3133eb0da7fd1",
        "name": "RESTORE",
        "info": "",
        "x": 180,
        "y": 340,
        "wires": []
    },
    {
        "id": "190351b1c435ba0d",
        "type": "hubitat command",
        "z": "91a3133eb0da7fd1",
        "deviceLabel": "Nightstand",
        "name": "",
        "server": "a22e0ea9.276dc8",
        "deviceId": "1848",
        "command": "off",
        "commandArgs": "",
        "x": 490,
        "y": 580,
        "wires": [
            []
        ]
    },
    {
        "id": "014055f77ed84f67",
        "type": "inject",
        "z": "91a3133eb0da7fd1",
        "name": "restore",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payloadType": "str",
        "x": 190,
        "y": 760,
        "wires": [
            [
                "017ab3f736444c0e"
            ]
        ]
    },
    {
        "id": "017ab3f736444c0e",
        "type": "switch",
        "z": "91a3133eb0da7fd1",
        "name": "on/off",
        "property": "nightstand_switch",
        "propertyType": "flow",
        "rules": [
            {
                "t": "eq",
                "v": "on",
                "vt": "str"
            },
            {
                "t": "eq",
                "v": "off",
                "vt": "str"
            }
        ],
        "checkall": "true",
        "repair": false,
        "outputs": 2,
        "x": 330,
        "y": 760,
        "wires": [
            [
                "2094f7829799edf6"
            ],
            [
                "d1285baa82986252"
            ]
        ]
    },
    {
        "id": "2094f7829799edf6",
        "type": "switch",
        "z": "91a3133eb0da7fd1",
        "name": "CT or RGB",
        "property": "nightstand_colorMode",
        "propertyType": "flow",
        "rules": [
            {
                "t": "eq",
                "v": "CT",
                "vt": "str"
            },
            {
                "t": "eq",
                "v": "RGB",
                "vt": "str"
            }
        ],
        "checkall": "true",
        "repair": false,
        "outputs": 2,
        "x": 490,
        "y": 760,
        "wires": [
            [
                "74f5c9f8c6c486b0"
            ],
            [
                "1ef53261633bc945"
            ]
        ]
    },
    {
        "id": "d1285baa82986252",
        "type": "hubitat command",
        "z": "91a3133eb0da7fd1",
        "deviceLabel": "Nightstand",
        "name": "",
        "server": "a22e0ea9.276dc8",
        "deviceId": "1848",
        "command": "off",
        "commandArgs": "",
        "x": 490,
        "y": 820,
        "wires": [
            []
        ]
    },
    {
        "id": "69cde6cad2b9be64",
        "type": "change",
        "z": "91a3133eb0da7fd1",
        "name": "setCT",
        "rules": [
            {
                "t": "set",
                "p": "command",
                "pt": "msg",
                "to": "setColorTemperature",
                "tot": "str"
            },
            {
                "t": "delete",
                "p": "payload",
                "pt": "msg"
            },
            {
                "t": "delete",
                "p": "topic",
                "pt": "msg"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 870,
        "y": 740,
        "wires": [
            [
                "0e98fd79fdae948f"
            ]
        ]
    },
    {
        "id": "c3cd84f69eb81d80",
        "type": "change",
        "z": "91a3133eb0da7fd1",
        "name": "setColor",
        "rules": [
            {
                "t": "set",
                "p": "command",
                "pt": "msg",
                "to": "setColor",
                "tot": "str"
            },
            {
                "t": "delete",
                "p": "payload",
                "pt": "msg"
            },
            {
                "t": "delete",
                "p": "topic",
                "pt": "msg"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 860,
        "y": 780,
        "wires": [
            [
                "0e98fd79fdae948f"
            ]
        ]
    },
    {
        "id": "0e98fd79fdae948f",
        "type": "hubitat command",
        "z": "91a3133eb0da7fd1",
        "deviceLabel": "Nightstand",
        "name": "",
        "server": "a22e0ea9.276dc8",
        "deviceId": "1848",
        "command": "",
        "commandArgs": "",
        "x": 1050,
        "y": 760,
        "wires": [
            []
        ]
    },
    {
        "id": "74f5c9f8c6c486b0",
        "type": "template",
        "z": "91a3133eb0da7fd1",
        "name": "CT arguments",
        "field": "arguments",
        "fieldType": "msg",
        "format": "handlebars",
        "syntax": "mustache",
        "template": "{{flow.nightstand_ct}},{{flow.nightstand_level}},0",
        "output": "str",
        "x": 680,
        "y": 740,
        "wires": [
            [
                "69cde6cad2b9be64"
            ]
        ]
    },
    {
        "id": "1ef53261633bc945",
        "type": "template",
        "z": "91a3133eb0da7fd1",
        "name": "color arguments",
        "field": "arguments",
        "fieldType": "msg",
        "format": "handlebars",
        "syntax": "mustache",
        "template": "{\"hue\":{{flow.nightstand_hue}},\"saturation\":{{flow.nightstand_sat}},\"level\":{{flow.nightstand_level}}}",
        "output": "str",
        "x": 680,
        "y": 780,
        "wires": [
            [
                "c3cd84f69eb81d80"
            ]
        ]
    },
    {
        "id": "a22e0ea9.276dc8",
        "type": "hubitat config",
        "name": "HubitatM",
        "usetls": false,
        "host": "192.168.1.46",
        "port": "80",
        "appId": "1522",
        "nodeRedServer": "http://192.168.1.4:1880",
        "webhookPath": "/hubitat/webhook",
        "autoRefresh": true,
        "useWebsocket": false,
        "colorEnabled": true,
        "color": "#5dd049"
    }
]
4 Likes