Trigger from Node-Red if a sensor doesn't change for X hours

Hi,
Newb with both HA and Node-Red and tries to migrate from an old home automation controller and make things working better…

Background
I have simple, cheap and pretty good working 433MHz temperature sensors in my freezers and fridges (2+2). They are powered by 2xAA batteries that lasts for years. I just put the sensors in the freezers and fridges. No cables to route. Very easy solution.
One limitation is that these sensors can come start sending simultaneously and the controller can’t receive the signal. That only lasts for a few hours then the transmission starts working again.
BUT - the problem is that even if batteries lasts for years, I get no notification when they run out. I could potentially put in a calendar reminder for every 4-5 year to change them preventatively…but I will not learn anything from that solution.

I have managed to create NodeRed flows that sends me a notification and an email if temperature goes above a set limit. For that I use the Trigger State node that only triggers when current value is above setpoint and previous value is setpoint or lower. After that I have the change node that creates the payload as an object with a text for the fridge/freezer (text) and temperature as temp
{ "text": "Freezer Kitchen", "temp": msg.payload }
And another change node for converting to string variable output for the email node.

But now I want a flow that sends the corresponding notification if a sensor has not changed it’s value for X hours. Can that be made in Node-Red?
I found this thread regarding something similar:

but that’s looks to be a HA Automation. I try to keep all my “logics” in NodeRed and not spread it around…

https://zachowj.github.io/node-red-contrib-home-assistant-websocket/node/events-state.html

?
I can get “Event: state” node to trigger when a sensor state changes, but how I make it trigger if the sensor have not changed for a set time?

Fill in the “for” conditional with the amount of time.

image

Hmmm…still don’t get it…
if the entity is >0 for X minutes…it will always be…
The sensors sends a payload about every 5th minute. One way communication.

What I think I would like to do to be sure sensors are still updating is to check a few times a day (maybe 4-6 times) if the sensor value is the same as last time.
Fridges and freezers fluctuate a bit in temperature, so the risk/chance that the value is exact the same if I check twice or a few times in a row is not so likely:
image

Idealy I would like to see if the last three-four values is identically and then trigger a notification…

Not if the state goes back to zero before the time limit (for) expires. Therefore, if your temp is the same for x minutes (not fluctuating), then you have a problem?

Tried to set it up like this
image
with a test sensor that I modify the value of


And on first deply I got a message and timer started.
I left it for one minute and got a second message - so far so good
Then I continuously changed the sensor value for 3 minutes and got not messages - still good
After that I just left it for a couple of minutes and expected a message after 1 min, but nothing came through…
Edit/add: Tried to uncheck the “current state equals previous state”, but it didn’t made any difference

Unfortunately state doesn’t go to zero if sensor stops sending. It just stops sending. They are pretty stupid…

Ok, sorry I misunderstood. This is probably the solution; where you are not getting a state change for x amount of time:

should I use an “Event: state” node to capture the sensor every X hour (1 min for testing) and pass sensor payload:


and not ignore if state is not changed

into a function node with that code

var lastChange = new Date(msg.data.old_state.last_changed).getTime();
var now = new Date().getTime();
var secs = Math.floor((now / 1000)-(lastChange / 1000));
msg.sensor = {};
msg.sensor.lastChange = secs;
msg.delay = Math.floor(secs/3) * 1000;
if (msg.delay < 60000) { msg.delay = 60000; }
else if (msg.delay > 900000) { msg.delay = 900000; }
return msg;

might be a bit on they way…but I’m not just a beginner on HA and NR…I’m not that experienced in codeing either…but eager to learn :slight_smile:
There are a few different time settning and I don’t really understand…and according to the description it does not really do what I’m after…

Doing some more searching I found this:

1 Like

Maybe you could put a delay node on the start of your flow.
The delay node can be set to hold back the message output until the timer in its setting runs out, but with a reset each time a new message arrive.
This way the messages should be blocked in the delay node until no updates is received and the delay node then release its message.

How do you mean? Start with a delay node, without anything going into it?
Use “Override delay with msg.delay” in some way?
What after the delay node? A current state node? But how to feed anything in to the delay node then?
I think something in your description sounds reasonable…but I don’t understand how to do…

A lot of code…a little bit too much for me…not really know where to start to understand. Want a lot, but feels like a long way to go to learn, but I must start somewhere…but from what I understand most of this is regarding binary sensors. Can it be applied to a thermometer as well?
Late here now…trying to get some time to read it again and try again tomorrow

I agree with WallyR. all presented solutions so far are over-engineered while what you want can be achieved without anything special but built-in delay node which will measure the time for you and publish message when time exceeds

use output of Events:state node to feed a Delay node. in between of them you have to set the message properly in order to reset the delay node.(use change node to add ‘reset’ property to the message)

This way every incoming message will reset the Delay node starting measuring time from the beginning ). If message will not come within specified time, delay node will publish the last stored message. Use it to trigger notification (the message contains all you need, the last value, name of entity etc)

you may set state node to not publish message if previews and new states are equal. But tbh I think getting the same values proves your device is working. So I wouldn’t include that condition

I think the second link I provided is a simple solution that requires no code (just a polling node). I tested it with one of my temperature sensors and it works as expected.

Entities have a timeSinceChangedMs attribute measured in milliseconds. If that value is greater than 86400000 (24 hours) the state has not changed in 24 hours.

So, you can poll timeSinceChangedMs at some interval (60 seconds or whatever) and check to see if that value is greater than the time you want (not changed in 24 hours = true?).

A working example. Modify the Entity Id, Update Interval, and milliseconds (If State) for your environment. You can replace the debug 1 node with your notification.

image

[{"id":"bddbd75a.af7608","type":"poll-state","z":"8b43de8505f17be7","name":"","server":"f3f422ce.9f2a6","version":2,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"updateinterval":"10","updateIntervalType":"num","updateIntervalUnits":"seconds","outputinitially":false,"outputonchanged":false,"entity_id":"sensor.basement_flood_temperature","state_type":"str","halt_if":"$entity().timeSinceChangedMs > 86400000","halt_if_type":"jsonata","halt_if_compare":"jsonata","outputs":2,"x":700,"y":300,"wires":[["1df3de1bd2af0c7b"],["69fcee022f51c44b"]]},{"id":"1df3de1bd2af0c7b","type":"debug","z":"8b43de8505f17be7","name":"debug 1","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":1000,"y":280,"wires":[]},{"id":"69fcee022f51c44b","type":"debug","z":"8b43de8505f17be7","name":"debug 2","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":1000,"y":340,"wires":[]},{"id":"f3f422ce.9f2a6","type":"server","name":"Home Assistant","version":5,"addon":true,"rejectUnauthorizedCerts":true,"ha_boolean":"y|yes|true|on|home|open","connectionDelay":true,"cacheJson":true,"heartbeat":false,"heartbeatInterval":30,"areaSelector":"friendlyName","deviceSelector":"friendlyName","entitySelector":"friendlyName","statusSeparator":"at: ","statusYear":"hidden","statusMonth":"short","statusDay":"numeric","statusHourCycle":"h23","statusTimeFormat":"h:m","enableGlobalContextStore":true}]

I tried this and swapped entity id for one of my sensors:
image

But it looks like it’s not sending the timeSinceChangedMs message

image

Those sensors are pretty simple and stupid. It looks like poll state only reads last value from the database.
Maybe this only works for smarter sensors? What kind of sensor did you try on?

Big thanks for all effort trying to help!

maybe OT, but I saw now that after every deply I get a warning I have unconfigured nodes and it looks to be Home Assistant it warns about…

image

Something to bother about or can I do something about it

Edit:
Some googling and I think it was another Home Assistant Server node was inserted with the import of the poll state code…deleted now and back to normal

Hmmm…tried a bit
It works to have the Event:state node to send out every message that comes from the detector.

Then I configured the output it like this:


Added reset as output in the event:state node (isn’t that what a change node would do?)

But on every message where the delay node is reset, the message is discarded, so there is no message left to send if time runs out…?

You have probably imported some nodes at a time and a server config node was included.
It does not mean much here, because the number is 0, so no other nodes need it and you can then just doubleclick on it and choose delete.