Hi!
I’m trying to get the time (in minutes) since last state change for a sensor. Any easy way to do this? Thanks!
Hi!
I’m trying to get the time (in minutes) since last state change for a sensor. Any easy way to do this? Thanks!
If you’re using the websocket version each entity will have a property timeSinceChangedMs
. Which is the time in milliseconds since the state last changed.
Sorry, but I’m not using that node. Any way, I took a look and couldn’t find out how to achieve what I need. Thanks
Sorry, I’m talking about Node-RED nodes.
So are we - the Node Red node is from ‘node-red-contrib-home-assistant-websocket’ which you can find at https://flows.nodered.org/node/node-red-contrib-home-assistant-websocket.
Using the events_state node to listen for a specific sensor changing state - we have msg.data.new_state.timeSinceChangedMs . msg.data.old_state tells us about the previous state and msg.data.new_state tells us about the new state. Since the value is in milliseconds, we can divide by 1000 to get seconds and then divide by 60 to get minutes.
var lastChange = Math.floor(msg.data.new_state.timeSinceChangedMs / 1000);
if (lastChange > 300 && msg.data.new_state.state === true) {
// do something because the state last changed 5 minutes ago and is now true/on
}
(node-red newbie)
Okay, great so we can calculate the lastChange time.
But where do I put the calculation
(var lastChange = Math.floor(msg.data.new_state.timeSinceChangedMs / 1000);
in a function node, template node? How do I use it?
Probably a very dump question but its not obvious if you are a beginner like me…
That’ll be in a function node, that’s the easiest way to to calculations on the data contained in the msg object.
This is my current (working) code that I use daily for calculating a delay to wait and check if the state is still the same:
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;
This code is used to check how long ago a door contact changed, and calculate a delay for the delay node to check again to make sure the door is still closed. If the door is still closed after the delay, then the light is turned off. The delay changes based on how long the door was opened for.
I know this is a very old post, but if anyone stumbles upon this and were looking for essentially a heartbeat on a sensor (like a BLE temperature sensor) that wouldn’t report a new value if stuck, I have a very simple solution.
Using the Home Assistant ‘Poll State’ node (polled at a frequency that suits your needs) via node-red-contrib-home-assistant-websocket, you can use the data property timeSinceChangedMs
the user Kermit referenced above. I simply scaled it to seconds via range node and used a switch node to see if the value hasn’t changed in an hour.
Very simple heartbeat for sensors that are prone to occasional freezing.
Hi.
Could you share your json, please?
Thanks.
It’s done.
Some texts are in Brazilian portuguese, but it is possible to understand it.
[{“id”:“ee800cbbd7b0c9e0”,“type”:“poll-state”,“z”:“7a10674471569e9c”,“name”:“Gel 2 - Temp”,“server”:“fad61953.26ffa8”,“version”:3,“exposeAsEntityConfig”:“”,“updateInterval”:“5”,“updateIntervalType”:“num”,“updateIntervalUnits”:“minutes”,“outputInitially”:false,“outputOnChanged”:false,“entityId”:“sensor.cozinha_geladeira2_temphumi_temperature”,“stateType”:“str”,“ifState”:“”,“ifStateType”:“str”,“ifStateOperator”:“is”,“outputs”:1,“outputProperties”:[{“property”:“payload”,“propertyType”:“msg”,“value”:“”,“valueType”:“entityState”},{“property”:“data”,“propertyType”:“msg”,“value”:“”,“valueType”:“entity”},{“property”:“topic”,“propertyType”:“msg”,“value”:“”,“valueType”:“triggerId”},{“property”:“sensor”,“propertyType”:“msg”,“value”:“Geladeira 2”,“valueType”:“str”}],“x”:90,“y”:220,“wires”:[[“a57127c0a26c673d”]]},{“id”:“a57127c0a26c673d”,“type”:“range”,“z”:“7a10674471569e9c”,“minin”:“0”,“maxin”:“1000”,“minout”:“0”,“maxout”:“1”,“action”:“scale”,“round”:false,“property”:“data.timeSinceChangedMs”,“name”:“ms > s”,“x”:270,“y”:220,“wires”:[[“c7e306c821918af7”]]},{“id”:“c7e306c821918af7”,“type”:“switch”,“z”:“7a10674471569e9c”,“name”:“Validate”,“property”:“data.timeSinceChangedMs”,“propertyType”:“msg”,“rules”:[{“t”:“gt”,“v”:“600”,“vt”:“num”}],“checkall”:“true”,“repair”:false,“outputs”:1,“x”:460,“y”:220,“wires”:[[“7f385e712d936632”]]},{“id”:“7f385e712d936632”,“type”:“api-call-service”,“z”:“7a10674471569e9c”,“name”:“PushNot”,“server”:“fad61953.26ffa8”,“version”:7,“debugenabled”:false,“action”:“notify.mobile_app_motorola_edge_50_pro”,“floorId”:,“areaId”:,“deviceId”:,“entityId”:,“labelId”:,“data”:“{"message":"{{sensor}}","title":"Sensor com problemas"}”,“dataType”:“json”,“mergeContext”:“”,“mustacheAltTags”:false,“outputProperties”:,“queue”:“none”,“blockInputOverrides”:false,“domain”:“notify”,“service”:“mobile_app_motorola_edge_50_pro”,“x”:680,“y”:280,“wires”:[]},{“id”:“fad61953.26ffa8”,“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}]
You can also use jsonata and do the checking in the poll node. Time is in milliseconds so, for example, an hour would be 3600000.
$entity().timeSinceChangedMs > 3600000
Sorry to reopen this thread, but I’m trying to do something similar and struggling
I have a current state node below which checks if a drawer is open
What I want to know is if the state changed to open in the past 2 minutes… i.e. if at the time this node is checked it has been left open for longer than 2 minutes it will give one result, and if it became that state within 2 minutes it would give another result…
I feel this should be simple - i know it is if I want to know that it’s been open for 2 mins as I can do it in the properties as is - but I want to know if the timeSinceChange is <2mins
Can someone advise how I might do that in this flow??
[{"id":"3b2c035eeb7bce4c","type":"server-state-changed","z":"dfe30d90959988bc","name":"Bedroom Bottom Left Window","server":"3aa13fed.bf745","version":6,"outputs":2,"exposeAsEntityConfig":"","entities":{"entity":["binary_sensor.bedroom_window_bottom_left_contact_sensor_contact"],"substring":[],"regex":[]},"outputInitially":false,"stateType":"str","ifState":"on","ifStateType":"str","ifStateOperator":"is","outputOnlyOnStateChange":true,"for":"0","forType":"num","forUnits":"minutes","ignorePrevStateNull":true,"ignorePrevStateUnknown":true,"ignorePrevStateUnavailable":true,"ignoreCurrentStateUnknown":true,"ignoreCurrentStateUnavailable":true,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"entityState"},{"property":"data","propertyType":"msg","value":"","valueType":"eventData"},{"property":"topic","propertyType":"msg","value":"","valueType":"triggerId"}],"x":160,"y":1020,"wires":[["a738ccdc5e567ced","4fe5d44ef7163671"],["a738ccdc5e567ced","4fe5d44ef7163671"]]},{"id":"4fe5d44ef7163671","type":"api-current-state","z":"dfe30d90959988bc","name":"Bedroom Drawer is Open","server":"3aa13fed.bf745","version":3,"outputs":2,"halt_if":"on","halt_if_type":"str","halt_if_compare":"is","entity_id":"binary_sensor.bedroom_drawer_contact_sensor","state_type":"str","blockInputOverrides":true,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"entityState"},{"property":"data","propertyType":"msg","value":"","valueType":"entity"}],"for":"0","forType":"num","forUnits":"minutes","override_topic":false,"state_location":"payload","override_payload":"msg","entity_location":"data","override_data":"msg","x":550,"y":920,"wires":[["e3528021cb5f8667"],["20d9a8df8398fc8f"]]},{"id":"20d9a8df8398fc8f","type":"debug","z":"dfe30d90959988bc","name":"No Alarm: Bedroom Drawer is open","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1020,"y":920,"wires":[]},{"id":"3aa13fed.bf745","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}]
EDIT: Answering my own question - found this solution in a reddit thread and seems to be working:
[{"id":"ba0faeb3.d854f","type":"ha-get-entities","z":"dfe30d90959988bc","name":"Get Bedroom Drawer Info","server":"3aa13fed.bf745","version":1,"rules":[{"condition":"state_object","property":"entity_id","logic":"is","value":"binary_sensor.bedroom_drawer_contact_sensor","valueType":"str"}],"outputType":"array","outputEmptyResults":false,"outputLocationType":"msg","outputLocation":"payload","outputResultsCount":1,"x":450,"y":1980,"wires":[["41727ce9.15ee34"]]},{"id":"41727ce9.15ee34","type":"switch","z":"dfe30d90959988bc","name":"Drawer Open?","property":"payload[0].state","propertyType":"msg","rules":[{"t":"eq","v":"on","vt":"str"},{"t":"eq","v":"off","vt":"str"}],"checkall":"true","repair":false,"outputs":2,"x":360,"y":2040,"wires":[["c14a641f.1ac488"],["a899c1a861915553"]]},{"id":"c14a641f.1ac488","type":"switch","z":"dfe30d90959988bc","name":"<2mins since turned opened?","property":"payload[0].timeSinceChangedMs","propertyType":"msg","rules":[{"t":"lt","v":"120000","vt":"str"},{"t":"else"}],"checkall":"true","repair":false,"outputs":2,"x":630,"y":2040,"wires":[["2fc65d5d91621316"],["a899c1a861915553"]]},{"id":"8d991fad1637caf2","type":"inject","z":"dfe30d90959988bc","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":140,"y":1980,"wires":[["ba0faeb3.d854f"]]},{"id":"a899c1a861915553","type":"debug","z":"dfe30d90959988bc","name":"ALARM: Drawer Not Open or > 2mins","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":850,"y":2100,"wires":[]},{"id":"3aa13fed.bf745","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}]
@AaronAutomation can you give me the detail of your projet please ?
the detail inside MS to S, validate and sensor frozen
thanks for all Cédric