I have a network of ESP32 based devices which monitor the moisture levels in my Houseplants. Each device identifies itself to NodeRed via an MQTT message with the IP Address of the device as the Topic. I want to be able to know if any device has stopped working and am therefore storing the last time they polled in Context using the IP address as the id. UNfortunately this doesn't work. It can be exemplified by the following code.
[{"id":"894faba19e37b2c5","type":"function","z":"6569e3df316afd50","name":"function 18","func":"let currentTime = new Date().getTime();\nlet ip = \"192.120.1.23\";\nflow.set(ip,currentTime);\n\nreturn msg;","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":310,"y":620,"wires":[[]]}]
The reason that is happening is because we are allowed to specify a javascript object description as the id. For example, one could write flow.set("a.b", 42) and the a.b would be treated as meaning property b of object a. So by using "192.120.1.23" you are creating a multi-dimensional array named "192", where you are setting element 120 (which implies filling in empty values 0 to 119) to another array where element 1 contains the object "23" which has been set to the current time.
I am not sure if there is a solution. I will think about it.
My own workaround was to just use the last segment of the ip address and concatenate that to "IP". All my addresses are on the local network so I think that will work as well.
I'm 76 years old and started off life 52 years ago as a COBOL programmer where the semi-colon was absolutely sacrosanct. But now most of my non Javascript code is Arduino IDE where once again it rules so I do it out of habit now.
I thought that the original problem might have something to do with the Javascript object and I guess it is a problem when you have typeless variables. Its odd though to get data and data structure confused.
Incidentally you can achieve an alert when one of your ESPs goes offline by using a single trigger node, no code at all.
Each ESP is using a unique msg.topic , it's IP address.
Send all the messages to a trigger node set to send nothing, wait for a certain time and then send the last message received:
Thank you for that suggestion I will give it a try. Although often I like to use tried and tested methods that are independent of the platform I'm using. Because my moisture sensors are battery powered I'm putting them into deep sleep between samples and the sample interval is 30 minutes. When the device wakes it polls NodeRed for its calibration data and returns the latest readings from the sensor. After handling the the data returned, the function node checks the time stamp for all the other sensors and sends me an email for any that require attention. I'm still working out in my own mind how often the e-mail should be resent if the issue is not resolved.
Sometimes my elderly brain finds the specification of some inbuilt functions too hard to decipher and it is easier to write a bit of code myself. I'm totally self taught in the last 3 years on everything I have learned about IoT, including javascript, Arduino, NodeRed, HomeAssistant , MQTT and the building of the devices that the routines written using these apps monitor and control
I'm not sure whether this is relevant as I am not using the NodeRed MQTT broker but thank you for your suggestion and please correct me if I'm wrong. You might also like to read my response to @jbudd 's suggestion above
It seems that lots of folks use Node-red primarily as an environment for writing and running snippets of javascript and indeed it is very approachable for that (I have no idea how to write or run javascript outside of Node-red!)
Don't neglect all the other nodes though, it is very a capable language without having to write [much] code.
I think @Trying_to_learn's suggestion is considerably more elegant than mine.