Saving and Restoring States
Using Home Assistant scene creation
Home Assistant added the ability to create scenes on the fly. This has reduced the work needed to be done in Node-RED to be able to restore entities to a previous state.
[{"id":"44c8f86e.a64488","type":"trigger-state","z":"ffbd7f06.4a014","name":"Front Door Opened","exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityid":"sensor.front_door","entityidfiltertype":"exact","debugenabled":false,"constraints":[{"id":"nqs49205fvp","targetType":"this_entity","targetValue":"","propertyType":"current_state","propertyValue":"new_state.state","comparatorType":"is","comparatorValueDatatype":"str","comparatorValue":"open"},{"id":"b6o1iwadls4","targetType":"this_entity","targetValue":"","propertyType":"previous_state","propertyValue":"old_state.state","comparatorType":"is","comparatorValueDatatype":"str","comparatorValue":"closed"}],"constraintsmustmatch":"all","outputs":2,"customoutputs":[],"outputinitially":false,"state_type":"str","x":202,"y":1056,"wires":[["af046290.fdf2b"],[]]},{"id":"af046290.fdf2b","type":"api-call-service","z":"ffbd7f06.4a014","name":"Snapshot Entities","version":1,"debugenabled":false,"service_domain":"scene","service":"create","entityId":"","data":"{\"scene_id\":\"before\",\"snapshot_entities\":[\"light.wled_master_bedroom_tv\"]}","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":410,"y":1056,"wires":[["7af76536.dfa6cc"]]},{"id":"7af76536.dfa6cc","type":"api-call-service","z":"ffbd7f06.4a014","name":"Change entities","version":1,"debugenabled":false,"service_domain":"light","service":"turn_on","entityId":"light.wled_master_bedroom_tv","data":"{\"rgb_color\":[255,0,0],\"brightness\":128}","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":608,"y":1056,"wires":[["c6f24589.9beb48"]]},{"id":"c6f24589.9beb48","type":"delay","z":"ffbd7f06.4a014","name":"","pauseType":"delay","timeout":"15","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":780,"y":1056,"wires":[["f762690.97b1198"]]},{"id":"f762690.97b1198","type":"api-call-service","z":"ffbd7f06.4a014","name":"Restore Entities State","version":1,"debugenabled":false,"service_domain":"scene","service":"turn_on","entityId":"scene.before","data":"","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":964,"y":1056,"wires":[[]]}]
Here are several examples using the get-entities node to get the states of several entities and then how to restore the entity states.
Using the get entities node
[{"id":"953f4576.faa588","type":"ha-get-entities","z":"6cb9e978.bf4588","server":"8d00ebbc.99a928","name":"Get States","rules":[{"property":"entity_id","logic":"is","value":"^(light|switch|climate)\\.+","valueType":"re"}],"output_type":"array","output_empty_results":false,"output_location_type":"msg","output_location":"payload","output_results_count":1,"x":294,"y":80,"wires":[["2dab5a86.e54686"]]},{"id":"821d957.d510168","type":"inject","z":"6cb9e978.bf4588","name":"Store states","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":118,"y":80,"wires":[["953f4576.faa588"]]},{"id":"5bc878cb.d80f08","type":"comment","z":"6cb9e978.bf4588","name":"How I would do store states","info":"","x":152,"y":32,"wires":[]},{"id":"2dab5a86.e54686","type":"function","z":"6cb9e978.bf4588","name":"transform data","func":"const entities = msg.payload.map((e) => {\n const domain = e.entity_id.split('.')[0];\n const payload = {};\n\n switch(domain) {\n case 'switch':\n case 'light':\n payload.domain = domain;\n payload.service = `turn_${e.state}`;\n payload.data = { entity_id: e.entity_id }; \n break;\n case 'climate':\n payload.domain = 'climate';\n payload.service = `set_temperature`;\n payload.data = {\n entity_id: e.entity_id,\n temperature: e.attributes.temperature,\n target_temp_low: e.attributes.min_temp,\n target_temp_high: e.attributes.max_temp,\n operation_mode: e.attributes.operation_mode\n };\n break;\n }\n return payload;\n});\n// Save the states\nflow.set('savedStates', entities);\n\n// create a blank message object with out new payload\nmsg = { payload: entities };\nreturn msg;","outputs":1,"noerr":0,"x":480,"y":80,"wires":[["ceaf42e4.e245d"]]},{"id":"ceaf42e4.e245d","type":"debug","z":"6cb9e978.bf4588","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":646,"y":80,"wires":[]}]
[{"id":"f14f56e1.4d9a28","type":"inject","z":"6cb9e978.bf4588","name":"Store states","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":118,"y":256,"wires":[["3790fc30.12b354","18d6f55.537770b","94a3c52.9fa9738"]]},{"id":"18d6f55.537770b","type":"ha-get-entities","z":"6cb9e978.bf4588","server":"8d00ebbc.99a928","name":"Get Switches","rules":[{"property":"entity_id","logic":"starts_with","value":"switch","valueType":"str"},{"property":"state","logic":"includes","value":"on,off","valueType":"str"}],"output_type":"split","output_empty_results":false,"output_location_type":"msg","output_location":"payload","output_results_count":1,"x":290,"y":256,"wires":[["19e85c0e.f4d1d4"]]},{"id":"94a3c52.9fa9738","type":"ha-get-entities","z":"6cb9e978.bf4588","server":"8d00ebbc.99a928","name":"Get Lights","rules":[{"property":"entity_id","logic":"starts_with","value":"light","valueType":"str"},{"property":"state","logic":"includes","value":"on,off","valueType":"str"}],"output_type":"split","output_empty_results":false,"output_location_type":"msg","output_location":"payload","output_results_count":1,"x":290,"y":208,"wires":[["19e85c0e.f4d1d4"]]},{"id":"297ff244.47ca4e","type":"comment","z":"6cb9e978.bf4588","name":"Easier to follow version","info":"","x":132,"y":160,"wires":[]},{"id":"3790fc30.12b354","type":"ha-get-entities","z":"6cb9e978.bf4588","server":"8d00ebbc.99a928","name":"Get Climate","rules":[{"property":"entity_id","logic":"starts_with","value":"climate","valueType":"str"}],"output_type":"split","output_empty_results":false,"output_location_type":"msg","output_location":"payload","output_results_count":1,"x":290,"y":304,"wires":[["36705576.17a42a"]]},{"id":"19e85c0e.f4d1d4","type":"function","z":"6cb9e978.bf4588","name":"transform data","func":"const payload = {};\npayload.domain = msg.payload.entity_id.split('.')[0];\npayload.service = `turn_${msg.payload.state}`;\npayload.data = { entity_id: msg.payload.entity_id };\n\n// create a blank message object with out new payload\nmsg = { payload: payload };\nreturn msg;","outputs":1,"noerr":0,"x":476,"y":256,"wires":[["2b7e0299.1ce7ae"]]},{"id":"36705576.17a42a","type":"function","z":"6cb9e978.bf4588","name":"transform data","func":"const payloads = [];\nconst payload = {};\npayload.domain = 'climate';\npayload.service = `set_temperature`;\npayload.data = {\n entity_id: msg.payload.entity_id,\n temperature: msg.payload.attributes.temperature,\n target_temp_low: msg.payload.attributes.min_temp,\n target_temp_high: msg.payload.attributes.max_temp,\n operation_mode: msg.payload.attributes.operation_mode\n};\n\n// create a blank message object with out new payload\nmsg = { payload: payload };\nreturn msg;","outputs":1,"noerr":0,"x":476,"y":304,"wires":[["2b7e0299.1ce7ae"]]},{"id":"e254a879.41d408","type":"comment","z":"6cb9e978.bf4588","name":"function nodes could be replaced with a change nodes","info":"","x":596,"y":208,"wires":[]},{"id":"2b7e0299.1ce7ae","type":"join","z":"6cb9e978.bf4588","name":"","mode":"custom","build":"array","property":"payload","propertyType":"msg","key":"topic","joiner":"\\n","joinerType":"str","accumulate":false,"timeout":"5","count":"","reduceRight":false,"reduceExp":"","reduceInit":"","reduceInitType":"","reduceFixup":"","x":654,"y":256,"wires":[["b3db19bf.61d8e8"]]},{"id":"472ff71c.c342c8","type":"debug","z":"6cb9e978.bf4588","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":1026,"y":256,"wires":[]},{"id":"b3db19bf.61d8e8","type":"change","z":"6cb9e978.bf4588","name":"","rules":[{"t":"set","p":"savedStates","pt":"flow","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":832,"y":256,"wires":[["472ff71c.c342c8"]]}]
[{"id":"ab90e938.1eff18","type":"inject","z":"3c84cc55.8f02f4","name":"Restore states","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":294,"y":656,"wires":[["a5a0930.ed3ae7"]]},{"id":"a5a0930.ed3ae7","type":"change","z":"3c84cc55.8f02f4","name":"Get Saved States","rules":[{"t":"set","p":"payload","pt":"msg","to":"savedStates","tot":"flow"}],"action":"","property":"","from":"","to":"","reg":false,"x":490,"y":656,"wires":[["6247c7cf.5cb858"]]},{"id":"8f420c5d.82373","type":"debug","z":"3c84cc55.8f02f4","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":998,"y":656,"wires":[]},{"id":"6247c7cf.5cb858","type":"split","z":"3c84cc55.8f02f4","name":"","splt":"\\n","spltType":"str","arraySplt":1,"arraySpltType":"len","stream":false,"addname":"","x":658,"y":656,"wires":[["719b7b39.cbf0e4"]]},{"id":"719b7b39.cbf0e4","type":"api-call-service","z":"3c84cc55.8f02f4","name":"Restore State","version":"1","debugenabled":false,"service_domain":"","service":"","entityId":"","data":"","dataType":"json","mergecontext":"","output_location":"payload","output_location_type":"msg","mustacheAltTags":false,"x":816,"y":656,"wires":[["8f420c5d.82373"]]}]
As you can see in the above examples the switch
and light
domains are just saving and restoring the state, on/off. But what if some users wanted to also save and restore the brightness level or not. The climate
domain is saving and restoring more than just the state.
Also see: