node-red-contrib-home-assistant-websocket
Version:
Node-RED integration with Home Assistant through websocket and REST API
1 lines • 5.53 kB
JSON
[{"id":"1997b594da7d37b1","type":"group","z":"776c027950fc8c3f","name":"Process history data using JSONata in a change node","style":{"label":true,"color":"#000000"},"nodes":["bd6511844a39ca08","3d87bbb92fa35243","9a3ca494edc54a30","3a4534cdc46ae67d","891ee0da3deec2c1","27f0ecf4ea3dc24f","d5dc0b522463577a"],"x":34,"y":2499,"w":1312,"h":122},{"id":"bd6511844a39ca08","type":"api-current-state","z":"776c027950fc8c3f","g":"1997b594da7d37b1","name":"Get current state","server":"","version":3,"outputs":1,"halt_if":"","halt_if_type":"str","halt_if_compare":"is","entity_id":"person.george","state_type":"str","blockInputOverrides":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"payload ~> |$|{\"entityId\": $entity().entity_id}|","valueType":"jsonata"},{"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":350,"y":2540,"wires":[["9a3ca494edc54a30"]]},{"id":"3d87bbb92fa35243","type":"inject","z":"776c027950fc8c3f","g":"1997b594da7d37b1","name":"Set parameters","props":[{"p":"payload"},{"p":"startAt","v":"$fromMillis($millis()-(7*24*60*60000))","vt":"jsonata"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"relativeTime\": \"1 week\"\t}","payloadType":"jsonata","x":160,"y":2540,"wires":[["bd6511844a39ca08"]]},{"id":"9a3ca494edc54a30","type":"api-get-history","z":"776c027950fc8c3f","g":"1997b594da7d37b1","name":"Read history","server":"","version":1,"startDate":"","endDate":"","entityId":"","entityIdType":"equals","useRelativeTime":true,"relativeTime":"","flatten":true,"outputType":"array","outputLocationType":"msg","outputLocation":"payload","x":530,"y":2540,"wires":[["3a4534cdc46ae67d"]]},{"id":"3a4534cdc46ae67d","type":"change","z":"776c027950fc8c3f","g":"1997b594da7d37b1","name":"Get filtered state periods","rules":[{"t":"set","p":"payload","pt":"msg","to":"(\t/* FILTER parameters */\t $fMins:=50;\t\t/* get current state from entity 'data', and set the 'last_changed' to now */\t $first:= data~>|$|{\"last_changed\": $now()}|;\t\t/* add this to far end of history payload array, then sort by reverse time order */\t $x:=$append(payload, $first)^(>last_changed,>last_updated);\t\t/* copy the oldest state value, and add in as the first record at start of history */\t/* we now have a 'now' and 'start of history' record, even if payload was empty */ \t $x:=$append($x,{\"state\": $x[0].state, \"last_changed\": startAt});\t\t/* create array of state changes, with how long they have been in that state */\t/* remove any zero periods and unknown states FILTER OUT AS REQUIRED */\t $events:=$x#$i.(\t $prior:= $i>0 ? $x[$i-1] : {\"first\": $now()};\t {\"index\": $i,\t \"state\": state,\t \"from\": last_changed,\t \"upto\": $prior.last_changed,\t \"dmins\": ($toMillis($prior.last_changed)-$toMillis(last_changed))/60000~>$round(0)\t }\t )[dmins>$fMins and state!=\"unknown\"];\t\t/* merge consecutive records with the same state into one longer period */\t/* get each event position as 'start - middle - end' or 'only' */\t\t $temp:=$events#$v.(\t $back:= $v<1 ? false : state = $events[$v-1].state;\t $next:= state = $events[$v+1].state;\t $position:=( $back ? ($next ? \"middle\" : \"end\") : ($next ? \"start\" : \"only\") );\t $~>|$|{\"index\": $v, \"position\": $position}|\t );\t\t/* get start and end indexes, and zip into a sequence array of [start, end] */\t/* map this array of sequences to an array of objects, one for each sequence */\t/* where the object is the combination of a run of the same state value */\t\t $chain:=$zip($temp[position=\"start\"].index, $temp[position=\"end\"].index);\t\t $array:=$map($chain, function($item) {(\t $recA:=$events[$item[0]];\t $recB:=$events[$item[1]];\t {\"state\": $recA.state,\t \"from\": $recB.from,\t \"upto\": $recA.upto,\t \"dmins\": ($toMillis($recA.upto)-$toMillis($recB.from))/60000~>$round(0),\t \"position\": \"merged\"}\t )\t });\t\t/* combine the 'only' single events with the now-merged sequences, and sort by time */\t $append($temp[position=\"only\"], $array)^(>from);\t\t)","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":750,"y":2540,"wires":[["891ee0da3deec2c1","27f0ecf4ea3dc24f"]]},{"id":"891ee0da3deec2c1","type":"debug","z":"776c027950fc8c3f","g":"1997b594da7d37b1","name":"State History Events","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1200,"y":2540,"wires":[]},{"id":"27f0ecf4ea3dc24f","type":"change","z":"776c027950fc8c3f","g":"1997b594da7d37b1","name":"When 'not home' during the day","rules":[{"t":"set","p":"payload","pt":"msg","to":"payload[state=\"not_home\" and ($substringBefore(from,\"T\") = $substringBefore(upto,\"T\") ) ]","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":930,"y":2580,"wires":[["d5dc0b522463577a"]]},{"id":"d5dc0b522463577a","type":"debug","z":"776c027950fc8c3f","g":"1997b594da7d37b1","name":"Out during the day","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1190,"y":2580,"wires":[]}]