Averaging Sequence for Node-Red - Hubitat

Even after all 3 inputs have reported? You’ll get NaN before the 3rd but then they are all saved and you shouldn’t see it again.

I know you’d rather have just 1 report every 3s and I can add that if you want. I preferred it the way it is because I refreshed the sensor that needed a higher reporting rate and left the other alone because it reports “responsibly”. :wink:

That’s easy enough to add to what I sent you and I can do it as well.

yeah I can slap that anywhere once resolved.

1 or 3 is not really a big deal, they get filtered buy the batch. The only reason it’s an issue is the VD will only take 1 set command per second, so it takes the first which is not the average. I use the batch/switch to filter out the other. No biggie, not like I personally sit here and it (once finish that is lol)

yep. I get 6 debug logs every time I click it and they say (can’t get them all but they all say NaN)

Ah, but it will be after 13s because the first round of reports are stored so every new message IN will generate a new message OUT with the updated average. There is NO reset.

Here’s my simple test flow. Perhaps I oversimplified?

[{"id":"765e87f9.08fe38","type":"tab","label":"Flow 2","disabled":false,"info":""},{"id":"bf5664a3.971428","type":"function","z":"765e87f9.08fe38","name":"Average","func":"if (msg.payload.deviceId == \"78\") context.set('78',msg.payload.value);\nif (msg.payload.deviceId == \"2335\") context.set('2335',msg.payload.value);\nif (msg.payload.deviceId == \"2471\") context.set('2471',msg.payload.value);\nmsg.payload.average = ((context.get('78') + context.get('2335') + context.get('2471')) / 3 );\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":490,"y":190,"wires":[["ba855fb1.9424"]]},{"id":"ba855fb1.9424","type":"debug","z":"765e87f9.08fe38","name":"messages","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":650,"y":190,"wires":[]},{"id":"5c264232.19753c","type":"inject","z":"765e87f9.08fe38","name":"2335","props":[{"p":"payload.deviceId","v":"2335","vt":"str"},{"p":"payload.value","v":"47","vt":"num"}],"repeat":"","crontab":"","once":true,"onceDelay":"2","topic":"","x":320,"y":190,"wires":[["bf5664a3.971428"]]},{"id":"4823dc81.b51b84","type":"inject","z":"765e87f9.08fe38","name":"78","props":[{"p":"payload.deviceId","v":"78","vt":"str"},{"p":"payload.value","v":"33","vt":"num"}],"repeat":"","crontab":"","once":true,"onceDelay":"1","topic":"","x":320,"y":150,"wires":[["bf5664a3.971428"]]},{"id":"2461284b.b49b78","type":"inject","z":"765e87f9.08fe38","name":"2471","props":[{"p":"payload.deviceId","v":"2471","vt":"str"},{"p":"payload.value","v":"52","vt":"num"}],"repeat":"","crontab":"","once":true,"onceDelay":"03","topic":"","payloadType":"str","x":320,"y":230,"wires":[["bf5664a3.971428"]]}]

yeah IDK what is wrong between the example that work and the actually one that gives NaN. All I can think of is it not see the deviceId correct so it is not setting the variably. Again coding is not my wheel house so this is just a guess. Your example works fine.

I used to make a living coding but that was almost 11 years ago and JavaScript is new to me so I’m far from an expert. Just one of the reasons I took the easy route with this function.

I see what’s wrong. I fat-fingered one of the deviceId numbers.

Here ya go

if (msg.payload.deviceId == "78") context.set('78',msg.payload.value);
if (msg.payload.deviceId == "2535") context.set('2535',msg.payload.value);
if (msg.payload.deviceId == "2471") context.set('2471',msg.payload.value);
msg.payload.average = ((context.get('78') + context.get('2535') + context.get('2471')) / 3 );
return msg;
2 Likes

:+1:

can’t believe I didn’t catch that. I am usualy better at proofing.
image

Awesomesauce! I like your way better for two big reasons

  1. it sets the value so every time it’s averaged it is using the correct 3 numbers (the node just keeps averaging down, which is why I needed a reset)

  2. Since values are store I can remove the inject node and let the devices update naturally (or added a refresh as need like you said).

Let me clean this up a bit, add batch/limit nodes and I’ll post an update.

THANKS!! Huge Kudos for the help and never say die spirit! knew I liked you for a reason :laughing:

2 Likes

Shhhhhhhhhh! You’re gonna ruin my reputation!
:wink:

I’ve lost a ton of skills by not doing any programming for 11 years (some would say I never had them to lose :stuck_out_tongue_winking_eye:) but I’ve always been tenacious and I love to give back to folks like you who contribute SO much.

1 Like

Ha, I tried this a few months ago and abandoned it because it felt wonky. My approach was to monitor the Hubitat Event Socket for temperature updates to the device I want to average and then pass the msg through the Hubitat nodes for those devices, forcing each to output their value. Then average them.

It worked, but i ended up sticking the the Average Apps in Hubitat.

Yeah, the Average App in Hubitat makes it much easier. I wonder if anyone can come up with a subflow that easily averages a random number of sensors.

As I mentioned previously, my function code could/should be a good starting point to do it all in a single node. It’ll take a fair amount of logic additions to git 'er done and I have more pressing things to attend to for the foreseeable future. Maybe someone faster than me with JS code will jump in.