Node-RED nodes for hubitat

Can't answer that - I use a different version of that node that I installed from the command line.

I know I've seen that but I don't recall if it was the Lutron nodes or not. I'm also not sure how I "fixed" it but try putting an empty lowercase.html file in the top folder with the Lutron code.

@fblackburn, I'm getting this message in my NR debug sidepane ever 5 minutes and I haven't figured out why or where it comes from. I also don't know what device has an ID of 834.

Unable to cast to dataType for device ID (834) with attribute (BinaryOutput). Open an issue (Issues · fblackburn1/node-red-contrib-hubitat · GitHub) to report back the following output: BOOLEAN: true

I don't have a GitHub account and I prefer not creating one so I hope that is not an imposition on you.

Do you know which node it's coming from?

Usually when I get odd conversion errors it's because I forgot to change the "type" in a change node - like from a string to a number or boolean. Recently it happened with a JSON object . Left it as the default string instead of changing it to "JSON" and hilarity ensued, well mostly. :exploding_head:

edit: you probably know this but you can locate the node in the debug by clicking on the "node header" line above the actual debug output in the pane.

Goto http://hubipaddress/device/edit/834 and it will open up that device.

Thanks to @stephen_nutt I do now. It's one of @iharyadi's environmental sensor that I've added a relay to and "attribute (BinaryOutput)" now makes sense. Thanks to both of you for helping me find this.

Exactly, and now that I know where to look I could do that BUT that device is referenced only twice in NR, once to read "Illuminance" and once to send a "refresh". The only place the relay is referenced is in a Virtual Switch I setup in HE and the VS is only by a tile on the [RELEASE] Hubitat Dashboard - Android dashboard app which is via Maker API so now I'm at a loss to understand how the BinaryOutput attribute is even known to NR.
:thinking:

EDIT: I searched the flows_host.json file for several terms related to the device and the only thing I find in there is the ID of 834. There is no "binary" anything so I I need @fblackburn to help sort this out.

Another odd thing is that the header on the debug message I posted above cites the "websocket" config while I only use webhook in the 2 nodes that reference device 834 in NR.

But I thought that websocket responds with ALL events regardless of the maker API? If you are using WS at all that's where the issue may be.

edit:
I'll bet it's similar to @TechMedX's old issue..

1 Like

I really need to look under the hood on this but that would explain it, alright. I do use WS for my motion lighting so it's back in @fblackburn's court, which is what the error message said.

Thanks for helping me understand what's happening here!

1 Like

It won't be the last time websocket is going to bite you in the arse. :wink:

3 Likes

It's not the first time either! :laughing:

At least it's not messing anything up...except my mind. :roll_eyes:

1 Like

Since version 1.4.0, NR track all devices (and all attributes) available through Maker API. Then if you have only one device that doesn't follow the supported dataType as describe in the HE wiki, it will display this warning. Even if you don't use this device/attribute in your flows.

If you don't use this device at all, then you can uncheck it in Maker API config (but it's annoying)
In an ideal world, all drivers will respect those dataType (but we don't live in a unicorn world)

Anyways, two days ago I mitigate this warning with this PR (not released) to try to describe what is happening and display this warning only one time by device.

In your case, after a NR restart, on the first event of your device (834), you will see:

The device (834) sends an event (BinaryOutput) with non-official dataType (BOOLEAN).
The default behaviour is to leave the attribute value (true) as string.
It may result in a difference when getting attribute value with input vs event (e.g., json vs string).
You should report back this issue to the device driver maintainer.
Supported dataType: https://docs.hubitat.com/index.php?title=Attribute_Object

Then you will not receive any same warning from this device, until the next NR restart.

Will that solve your issue or there are something else I can improve?

Edit: I was planning to release this version today or tomorrow

5 Likes

Yes, thank you. But see my last post :point_up: as it's not breaking anything.

I appreciate the explanation and it's cool that you've already addressed it. :+1:

new version 1.5.1 :christmas_tree:

  • device/command: set name dynamically according the device label. It will be updated when the node will be saved.
    dynamic-name

  • config: display dataType warning only once by device instead of at each event.

Wait, you haven't seen the 1.5.0 release note :fearful: ...
Ok I made a mistake on the release and miss something, so these changes include 1.5.0 too :sweat_smile:

Dang .... My gif show another typo in the name placeholder when no device selected for the command node ... well it will be fixed in another release ... another day :laughing:

7 Likes

Thanks, @fblackburn, this has removed the unnerving messages in my debug sidebar.
:+1:

Node-Red with Hub Mesh token, Can one use the token from Hub Mesh with Node-Red instead of using Maker API? If so, any reason to do one or the other?

1 Like

Nope. Need maker API. I would love it if Hubitat open sourced/documented the message format for hub mesh, but I doubt that will happen.

3 Likes

small fix version 1.5.2 related to the dynamic name feature

  • device: set msg.topic to device label when name is empty
  • command: fix name placeholder when no device selected
6 Likes

Lets see if I can figure out how to share this so that someone else can use it. Exporting from node-red feels unpredictable to me.

This is a subflow which does zone activity aggregation. Notably it will take regular contact switches to trigger zone activity as well as the traditional motion sensors. In my case, doors are placed at 90º angles to the room so covering them with a motion sensor is difficult without adding a dedicated motion sensor. The contact event will auto-reset similar to the way a motion sensor does.

The subflow takes configuration values for contact sensor reset and zone activity reset via topic:config messages, which means that the parameters can be reconfigured depending on the time of day... or whatever you want.

The motion aggregation component is in an unsafe function node, and is mostly code from someone else on this forum/thread. I removed a couple features and implemented them as node-red sequences, and I try to use as few third-party nodes as possible.

[{"id":"4c7c8cd1.6a2a1c","type":"subflow","name":"My Zone Activity Aggregator","info":"","category":"","in":[{"x":100,"y":200,"wires":[{"id":"28720ce3.415504"}]}],"out":[{"x":700,"y":520,"wires":[{"id":"f95fc416.12cdb8","port":"0"}]},{"x":1120,"y":620,"wires":[{"id":"f9fb7202.670248","port":0}]}],"env":[{"name":"Zone Name","type":"str","value":"Motion zone"}],"color":"#DDAA99","status":{"x":1060,"y":840,"wires":[{"id":"baa794b2.a49bd","port":0},{"id":"3adf6856.200d98","port":0},{"id":"6214c0ab.73eb08","port":0}]}},{"id":"37082482.1d726c","type":"unsafe-function","z":"4c7c8cd1.6a2a1c","name":"Motion Aggregator","func":"let motionStatus = null;\nlet activeCount = 0;\n\nlet sensors = context.get(\"sensors\") || {};\nlet wasActive = context.get(\"active\") || false;\nlet deviceId\n\nif (typeof msg.payload != \"undefined\" && msg.payload !== null) {\n    deviceId = msg.payload.deviceId;\n}\n\nif (typeof deviceId != \"undefined\") {\n\n    // If we didn't receive an event, the process was triggered by something else (eg. enabling the automation)\n    motionStatus = msg.payload.value\n\n    if (typeof sensors[deviceId] == \"undefined\") {\n        sensors[deviceId] = {}\n    }\n\n    let deviceObject = sensors[deviceId]\n\n    deviceObject.state = motionStatus\n    deviceObject.displayName = msg.topic\n\n    context.set(\"sensors\", sensors)\n}\n\n\nfor (let [deviceId, values] of Object.entries(sensors)) {\n    if ( values.state == 'active' ) {\n        activeCount++\n    }\n}\n\nconst active = activeCount > 0\n\nnewMessage = {\n  topic: env.get(\"Zone Name\"),\n  payload: active ? \"active\" : \"inactive\",\n  count: activeCount\n}\n\n    context.set(\"active\", active)\n    return newMessage\n","outputs":1,"noerr":0,"x":990,"y":160,"wires":[["1135a6a5.8ffeb9"]]},{"id":"baa794b2.a49bd","type":"change","z":"4c7c8cd1.6a2a1c","name":"Active sensor count","rules":[{"t":"set","p":"payload","pt":"msg","to":"count  & \" \" & payload & \" sensors\"","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":920,"y":880,"wires":[[]]},{"id":"f9fb7202.670248","type":"trigger","z":"4c7c8cd1.6a2a1c","name":"Activity off delay","op1":"","op2":"","op1type":"nul","op2type":"payl","duration":"5","extend":true,"overrideDelay":true,"units":"min","reset":"","bytopic":"all","topic":"topic","outputs":1,"x":1000,"y":620,"wires":[[]]},{"id":"f95fc416.12cdb8","type":"switch","z":"4c7c8cd1.6a2a1c","name":"is active?","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"active","vt":"str"},{"t":"eq","v":"inactive","vt":"str"}],"checkall":"false","repair":false,"outputs":2,"x":600,"y":600,"wires":[["bf8561c.27047a"],["4c35d83e.70c12"]]},{"id":"d1fef5e9.1faa","type":"switch","z":"4c7c8cd1.6a2a1c","name":"is active?","property":"count","propertyType":"msg","rules":[{"t":"eq","v":"0","vt":"str"},{"t":"else"}],"checkall":"true","repair":false,"outputs":2,"x":720,"y":860,"wires":[["3adf6856.200d98"],["baa794b2.a49bd"]]},{"id":"3adf6856.200d98","type":"change","z":"4c7c8cd1.6a2a1c","name":"Inactive","rules":[{"t":"set","p":"payload","pt":"msg","to":"\"inactive\"","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":880,"y":840,"wires":[[]]},{"id":"28720ce3.415504","type":"switch","z":"4c7c8cd1.6a2a1c","name":"Separate config messages","property":"topic","propertyType":"msg","rules":[{"t":"else"},{"t":"eq","v":"config","vt":"str"}],"checkall":"true","repair":false,"outputs":2,"x":280,"y":200,"wires":[["5e909849.a5ede"],["ab2b2200.580fe"]]},{"id":"bf8561c.27047a","type":"change","z":"4c7c8cd1.6a2a1c","name":"Reset","rules":[{"t":"set","p":"reset","pt":"msg","to":"true","tot":"bool"}],"action":"","property":"","from":"","to":"","reg":false,"x":810,"y":580,"wires":[["f9fb7202.670248"]]},{"id":"5e909849.a5ede","type":"switch","z":"4c7c8cd1.6a2a1c","name":"Separate motion from contact","property":"payload.name","propertyType":"msg","rules":[{"t":"eq","v":"motion","vt":"str"},{"t":"eq","v":"contact","vt":"str"}],"checkall":"true","repair":false,"outputs":2,"x":690,"y":200,"wires":[["37082482.1d726c"],["ee67eca9.7c9548","83dac1a6.f49bb"]]},{"id":"ee67eca9.7c9548","type":"change","z":"4c7c8cd1.6a2a1c","name":"Active-true","rules":[{"t":"set","p":"payload","pt":"msg","to":"active","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":970,"y":220,"wires":[["de4555d9.03c9f8"]]},{"id":"9dec185d.0fa0b","type":"change","z":"4c7c8cd1.6a2a1c","name":"Active-false","rules":[{"t":"set","p":"payload","pt":"msg","to":"inactive","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":1350,"y":260,"wires":[["de4555d9.03c9f8"]]},{"id":"979d8215.69ba18","type":"link out","z":"4c7c8cd1.6a2a1c","name":"Switch Event","links":["b4f2e905.4ec488","c551054e.c3663","db637502.ed7b1"],"x":1535,"y":220,"wires":[]},{"id":"1135a6a5.8ffeb9","type":"link out","z":"4c7c8cd1.6a2a1c","name":"Motion Event","links":["b4f2e905.4ec488","c551054e.c3663"],"x":1195,"y":160,"wires":[]},{"id":"c551054e.c3663","type":"link in","z":"4c7c8cd1.6a2a1c","name":"","links":["1135a6a5.8ffeb9","979d8215.69ba18"],"x":295,"y":840,"wires":[["2d4ae563.a0394a"]]},{"id":"b4f2e905.4ec488","type":"link in","z":"4c7c8cd1.6a2a1c","name":"","links":["1135a6a5.8ffeb9","979d8215.69ba18"],"x":295,"y":600,"wires":[["a6ce7a5b.5718f8"]]},{"id":"ab2b2200.580fe","type":"link out","z":"4c7c8cd1.6a2a1c","name":"Config","links":["e1a2c208.c8ace8"],"x":575,"y":260,"wires":[]},{"id":"e1a2c208.c8ace8","type":"link in","z":"4c7c8cd1.6a2a1c","name":"","links":["ab2b2200.580fe"],"x":295,"y":1120,"wires":[["c4696ddd.05a93"]]},{"id":"7878ae9d.d67828","type":"comment","z":"4c7c8cd1.6a2a1c","name":"Config","info":"","x":650,"y":260,"wires":[]},{"id":"cb4ad9ea.ed3e38","type":"comment","z":"4c7c8cd1.6a2a1c","name":"Motion event","info":"","x":1310,"y":160,"wires":[]},{"id":"acfeb2ce.da0e98","type":"comment","z":"4c7c8cd1.6a2a1c","name":"Sensor event","info":"","x":1650,"y":220,"wires":[]},{"id":"c4696ddd.05a93","type":"switch","z":"4c7c8cd1.6a2a1c","name":"Set config parameter","property":"payload.name","propertyType":"msg","rules":[{"t":"eq","v":"sensor_reset_delay","vt":"str"},{"t":"eq","v":"active_reset_delay","vt":"str"},{"t":"eq","v":"zone_active","vt":"str"}],"checkall":"true","repair":false,"outputs":3,"x":480,"y":1120,"wires":[["3f0f1369.4b070c"],["b127ab0f.e7777"],["49b85432.3fb394"]]},{"id":"3f0f1369.4b070c","type":"change","z":"4c7c8cd1.6a2a1c","name":"","rules":[{"t":"set","p":"sensor_reset_delay","pt":"flow","to":"payload.value","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":780,"y":1060,"wires":[[]]},{"id":"b127ab0f.e7777","type":"change","z":"4c7c8cd1.6a2a1c","name":"","rules":[{"t":"set","p":"activity_reset_delay","pt":"flow","to":"payload.value","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":780,"y":1120,"wires":[[]]},{"id":"83dac1a6.f49bb","type":"change","z":"4c7c8cd1.6a2a1c","name":"Sensor reset delay","rules":[{"t":"set","p":"delay","pt":"msg","to":"sensor_reset_delay","tot":"flow"}],"action":"","property":"","from":"","to":"","reg":false,"x":990,"y":260,"wires":[["b5799027.c31f78","1f831024.572ef8"]]},{"id":"b5799027.c31f78","type":"debug","z":"4c7c8cd1.6a2a1c","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1170,"y":320,"wires":[]},{"id":"1f831024.572ef8","type":"trigger","z":"4c7c8cd1.6a2a1c","name":"","op1":"","op2":"","op1type":"nul","op2type":"payl","duration":"5","extend":true,"overrideDelay":true,"units":"s","reset":"","bytopic":"all","topic":"topic","outputs":1,"x":1180,"y":260,"wires":[["9dec185d.0fa0b"]]},{"id":"4c35d83e.70c12","type":"change","z":"4c7c8cd1.6a2a1c","name":"Activity reset delay","rules":[{"t":"set","p":"delay","pt":"msg","to":"activity_reset_delay","tot":"flow"}],"action":"","property":"","from":"","to":"","reg":false,"x":790,"y":620,"wires":[["f9fb7202.670248"]]},{"id":"7a24866e.db567","type":"comment","z":"4c7c8cd1.6a2a1c","name":"Zone Active","info":"","x":810,"y":520,"wires":[]},{"id":"268891b5.f0e4f6","type":"comment","z":"4c7c8cd1.6a2a1c","name":"Zone Inactive","info":"","x":1070,"y":560,"wires":[]},{"id":"de4555d9.03c9f8","type":"rbe","z":"4c7c8cd1.6a2a1c","name":"","func":"rbe","gap":"","start":"","inout":"out","property":"payload","x":1475,"y":220,"wires":[["979d8215.69ba18"]],"l":false},{"id":"28fb421d.2d7a2e","type":"comment","z":"4c7c8cd1.6a2a1c","name":"Status text","info":"","x":340,"y":780,"wires":[]},{"id":"3dc117c7.63b51","type":"comment","z":"4c7c8cd1.6a2a1c","name":"Config Parameters","info":"","x":370,"y":1060,"wires":[]},{"id":"2d4ae563.a0394a","type":"switch","z":"4c7c8cd1.6a2a1c","name":"Motion zone active","property":"zone_active","propertyType":"flow","rules":[{"t":"else"},{"t":"false"}],"checkall":"true","repair":false,"outputs":2,"x":470,"y":840,"wires":[["6214c0ab.73eb08"],["d1fef5e9.1faa"]]},{"id":"6214c0ab.73eb08","type":"change","z":"4c7c8cd1.6a2a1c","name":"Disabled","rules":[{"t":"set","p":"payload","pt":"msg","to":"\"Disabled\"","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":880,"y":800,"wires":[[]]},{"id":"49b85432.3fb394","type":"change","z":"4c7c8cd1.6a2a1c","name":"","rules":[{"t":"set","p":"zone_active","pt":"flow","to":"payload.value","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":760,"y":1180,"wires":[[]]},{"id":"a6ce7a5b.5718f8","type":"switch","z":"4c7c8cd1.6a2a1c","name":"Zone enabled?","property":"zone_active","propertyType":"flow","rules":[{"t":"true"}],"checkall":"false","repair":false,"outputs":1,"x":440,"y":600,"wires":[["f95fc416.12cdb8"]]},{"id":"c90679d.51c6188","type":"comment","z":"4c7c8cd1.6a2a1c","name":"Outputs","info":"","x":330,"y":540,"wires":[]}]

I'm not sure if this picture will be helpful or not, but here it is visually:

3 Likes

I suggest you post this in the Node-Red Flow Samples/Sharing topic.

2 Likes

Question for the group...

Would it be useful to anyone other than me to have an option in the command node to "only send command if different than current state"?

The thought is that there are a lot of times I check the current status of a device and don't send an on/off (for example) command if it is already in that state. Why? Processing power on the node-red side is cheap, and any reduction in hubitat hub and zwave/zigbee mesh traffic is a big plus.

Not sure how useful that would be to others, so thought I would ask before dropping it in Francois' suggestion box. :slight_smile:

Example:
Here I check if the light is off before turning on. With the proposed option you could get rid of the circled device node and switch node, and then let the command node send it (or not) depending on the current state of the device.

It isn't especially difficult to put those 2 extra nodes in there, though, so it is not a huge deal either way to me. Just an idea.

Edit: The downside, though, is commands and state values don't always match... So instead of a single check box it might be required for user to manually specify the state value on which to not send the command. Example - presence... Arrived/departed commands versus states of present/not present...

4 Likes

Download the Hubitat app