Node-RED nodes for hubitat

Because why not? @tmichael - Here is a very crude example of what I was thinking... hopefully I was understanding what you were going for..

The switch "property" is a JSONATA expression that evaluates to true or false...

($flowContext("hue") = payload.hue.value)
 	and ($flowContext("saturation") = payload.saturation.value)
	and ($flowContext("level") != payload.level.value)
	and ($flowContext("colorMode") = payload.colorMode.value)

It may still be a little buggy but you get the idea. My "Office Left Table Light" is a Sengled Color+ bulb using the Zigbee Advanced drivers. Also the 2 HE device nodes have the "all" attribute set and "send events" turned off.

The idea is to test for Level changes but everything else being the same. Also had to add a test for colorMode as switching between RGB and CT leaves the HSL values the same.

edit: might also want to add colorTemperature as a test / flow var too..

Being more a Javascript than JSONATA guy, I was thinking a function node, but otherwise this lines up with my thinking. The challenge is that sometimes a color change will come in as a Level change followed by a Hue change followed by a Saturation change. Without a delay built into the process, the level change will look like a brightness change if the evaluation happens before the hue or saturation change can update the flow variables.

2 Likes

So I was not getting that behavior with my testing. Of course I was using the "Set Color" (w/color map) and "Set Temperature" commands on the device page... so maybe there is something different going on. Easy enough to stick a delay in right after the HE device "level" node..

I like Javascript as well but JSONATA is pretty powerful for what it does and allows you to use the basic system nodes like Switch, Change etc.

1 Like

One other addition, you could also use this node maybe for a max delay:

You could also add device nodes with send events for "colorTemperature", "saturation" and "hue"..

I totally agree. I found that I had a complicated and detailed need at one point and jumped into JS for that. Once you are comfortable with 1, then getting equally proficient in the other feels like learning a second language unnecessarily. I respect people that try to stick with standard nodes (NR is a visual programming environment after all), but once I mastered the function node with JS hammer, I saw a lot of nails that it could care for. :grinning:

temp edit: I think I have a good solution, and will post it once I verify that it does what I want.

Shared solution at: https://community.hubitat.com/t/node-red-flow-samples-sharing/45207/573

1 Like

Cool! You might want to post it over on this thread:

JSONATA is like XPath/XQuery for JSON... it's a worthwhile skill to develop I think especially for streamlining things.. the other thing to consider is building it into a subflow... you can use HE node deviceID's for dynamic stuff.

Hi guys,
I am no developer.
I have started using node red a couple of month ago trying to be ready for Samrtthings taking away IDE. I was (and still) using Hubconnect to try and keep my Samsung AC units in sync with virtual switch and a virtual thermostat in HE. Had to use 2 devices as HE virtual thermostst is missing the switch capability.
With the help of @mavrrick58 I am now able to fully take advantage of Samsung Automation Studio pallet.
My question regards my need to keep my virtual devices and the "real" AC units in sync for the Switch, ThermostatMode, ThermostatFanMode, and CoolingSetpoint.
In practice, I am using the AC "real" thermostst unit and the Virtual switch and Virtual Thermostat (on a dashboard) to operate the AC unit. So, I might set the Coolong Set Point in each of them and would like it to be reflected in the other right away.
I have created 2 flows - one to update the "real" thermostat with changes initiated in the virtual devices and the 2nd for the other way around.
This sometime creates a problem. Say for example virtual thermostst cooling set point is 24 and I would like to change it to 22 and I have to go through 23. When node red sees 23 it will triger a flow to update the "real" thermostat to 23 and will trigger a change to the Virtual thermostat to 23 while I manually changed it to 22. Hope my explanation is understood.
I guess that this is something a developer deals with all the sime ......but I am no developer :roll_eyes:
Any ideas?
Can a flow run in a circle to avoid this?
Attached are my flows.


I generated a solution and posted in the sharing thread at:
https://community.hubitat.com/t/node-red-flow-samples-sharing/45207/573

2 Likes

Here is my original request
I have a list of timestamps as part of an object in the msg.payload

This is a shortened list:

image

How would I go about comparing all the msg.payload.heapsOfNamesHere in 1 go, rather than manually entering each msg.payload.Mike's Computer and msg.payload.Temp Ensuite. etc.... I want to compare to a timestamp of now, for reference.

Here was erkrek's answer

JSONATA perhaps? $each?

Here's a simple example you can adapt..

$each(payload, function($v, $k) {$k & ": " & $v})

This is where I'm up to currently
Thanks, that helped. I'm now at the stage where I want to compare the output. I've got the payload as an array, but I'd like to keep it as an object, since then I can use the name as the identifier.

How would I keep it an an object, so I can use the names? Or how do I compare it (as an array) to the key/names?

This is the output.
image

This is the expression in the change node.

image

You can change the output of $each to be an array of individual objects so something like this:

$each(msg.payload, function($v,$k) {{"name": $k, "value":$v}})

Then you would have a switch node or whatever that has this JSONATA expression to filter out the ones you want:

*[value < 0]

The idea here is to transform your original JSON object to a more ordered array of objects which you can then use JSONATA to compare against all values. If you wanted to see the "name" you can do something like this:

*[value < 0].name

note: use any JSONATA comparison expression - value < 0 is just an example!

1 Like

And of course you can combine the expressions...

$each(msg.payload, function($v,$k){{"name": $k, "value":$v}})[value < 0]
1 Like

One more thing!!!

(Apologies I seem to be particularly hopped up on my morning coffee :coffee: )

You can also use an "inline if" and do a similar thing..

$each(msg.payload, function($v,$k){ $v < 0 ? {"name": $k, "value":$v} : undefined})	

This might actually be more efficient then doing the evaluation after the $each... the trick is the use of "undefined" to prevent output of the "false" condition.

2 Likes

Thanks for this @erktrek . I did what I wanted to do, and now my questions will cease until I think of something new to be done!

2 Likes

Okay cool! :+1:

edit: uh, I meant cool as in good you solved your issue not cool that you've stopped asking questions!!! :rofl:

4 Likes

I wanted to share a heads up on something that just about made me lose my mind trying to debug, but was just user error on my part.

I have had my hubitat and Node-Red connected for a long time and have been doing really useful automation this way. I also happen to have a second hubitat connected to the first via Hub mesh (also connected to Node-Red, but not relevant to the story. For reasons that don't matter to this circumstance, one of the 2 hubs has login security turned on and the other doesn't. I had a series of power outages (yes, I should have my systems on a UPS, but don't). I found that when my hubitat comes online before router comes online, it fails to get its reserved IP address via DHCP and so thinks of itself as having the default address of 168.... Interestingly enough by google wifi setup routes traffic to reserved IP address, but the mesh interface on the secured hub only accepts a mesh connection on the IP address that the hub thinks it is using. To overcome this, I assigned a static IP address to the hubitat. This fixed my mesh following a power outage problem.

Turns out, I had configured my hubitat node with a webhook set to reach my Node-Red using the device name, not the device's IP address. This worked without any problems before I changed the hub to a static IP address. After that change, I noticed flows were malfunctioning all over the place. Unfortunately, I didn't connect the change to the problems and so spent a lot of time on how I had misconfigured the webhook without realizing I had changed it. I did many changes trying to debug the self created mess. It turns out that when you configure hubitat with a static IP address, you must assign the address, the default gateway and the DNS server. The DNS server can be skipped as it has a default setting of 8.8.8.8 which is a google DSN server. This seemed easy enough.

I am sure the more savvy have already spotted the root of my problem. The Maker app was using the device name to send updates to my Node-Red, but because Google had no knowledge of my network it had no way to translate the hostname into the IP address. Once I recognized the problem, there was a very easy fix. Updated the hubitat DNS to my in home router as the DNS, Took all of 30 seconds to fix the problem after I spent a lot longer than that to figure out how I had broken it.

Bottom line. If you use the a LAN name for your Node-Red server and set up your Hubitat with a static IP address, use a DNS (typically your router) that is LAN name aware and not the default google DNS of 8.8.8.8.

This is new right for Node-RED 2.1.0-beta.1?

image

This is great for all of those obsessive/compulsives among us!

5 Likes

How is 2.0 working out for you? Haven't upgraded as yet but I'm wondering if you (or anyone else here) has upgraded the NR version with the pre-built Homebridge image. I have done v1 upgrades on my Homebridge instance but not sure how it will work from v1 to v2...

Just a quick heads up - IF you are running Node-RED v2.1.2 there seems to be some weirdness going on with the environmental variables (used as properties in subflows).. the properties show correctly when editing a specific node but when editing the subflow template only the first entry is shown... Things still work but you might end up messing up your vars if you edit and save the subflow.

V2.1.3 seems to resolve this issue.

5 Likes

My Node Red automations have slowed down and I am not sure why. If I restart, it works quickly for a while but then slows again.

Immediately after a restart:

I thought I could put a debug node after each step of my flow but the timestamp is only each second. Does anyone know if there is a way to see log timestamps to 2 or 3 decimals like the HE log?

It's all of my Node Red flows that are slow, not just this one. I don't know if getting that detailed of a timestamp will helo but I am at a loss of what could be causing the slowdown or what tools are available to debug.

The other weird thing is the the Node Red Log shows the button being pushed and the Office switch turning on 3 times and this is immediately after the restart. I have seen other cases where it gets to 4.

image

I created a Rule in HE to do the same as the flow and it was fast as expected so it is not an HE issue.

If it slows down over time, it could be a loop? Are you able to open up a logging window (on the node red device) and see if you have a loop somewhere? Or put a few debug nodes on the end of your flows, to determine if there is a loop?