You are indeed a far braver person than me. Personally I would always start with the clear understanding that the Home Assistant configuration file should never, ever be updated like this. Just too easy for one of your values to become “unavailable” and then your config to become “initial: unavailable”. Not sure how HA would like that. However, each to his own…
Thoughts and considerations:
Point 1. As @Mikefila has pointed out, the ‘input_number’ entities are special in two ways. First, unlike most entities in HA, we can update their state values (both via the dashboard and via service calls) and second, HA automatically restores them to the last state value at restarts. This happens automatically, it just does not happen if you set an initial value as you are doing, as that initial value is used instead. I would suggest that you only need to remove the ‘initial’ value setting from your configuration (or just use the Helper setup which does not include this feature) and HA will restore all your input_numbers on a restart for you. Job done. No need to read any further…
Point 2. As per your OP, it is not usually possible to do more than one thing in a node per message, so working through a list of entities to get, save, and write requires either a lot of nodes, or a sequence of messages passed as input to one node. Easy enough to do using an array (list) and the split and join nodes. That is how Node-RED can execute iteration.
Point 3. Yes you can use the template node to execute Jinja to get the state values, then a function node to pick them out of the string and put them into an object, then save them to context. However the standard Nodes can be used to do much of this work for you.
So, here is my suggestion. Two flows
- the first reads a given list of input_number entities, builds a JSON object of all them with their state values, and saves this to context.
- the second reads back the context variable, and then for each input_number entity / value pair it will call the input_number:set_value service call to write the value back again.
The advantage of this, apart from not having to mess with the HA configuration file, is that it can be run at any point to save the input_number entity set, and run at any point to restore this set.
You could trigger this from an Event: state node to perform the save-to-context on any change to one or all of your input_numbers.
You could write another flow to update / change the stored context value, or even just one field (for one input_number), thus maintaining your saved data set.
You could extend this to save blocks of data to context (object within an object) so that you could, for example save the current settings to ‘usual’ and another set to ‘holiday’, much as scenes do in HA.
In terms of saving over a restart, the Node-RED context store is normally to volatile memory only, however it is possible to change this or add an extra store that saves to file. This allows for context variables to be persistent over NR restarts.
(@Mikefila has given you the link above)
Note that I have set this flow up with just input_numbers, and set the Current state node for state type ‘number’, but it is easy to change this to collect states as strings and to deal with the necessary change to a number for write-back as required.
[{"id":"6c0af22021cbdcb6","type":"api-current-state","z":"92ed4c92bf112b10","name":"Read state (numbers)","server":"","version":3,"outputs":1,"halt_if":"","halt_if_type":"str","halt_if_compare":"is","entity_id":"","state_type":"num","blockInputOverrides":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"entityState"}],"for":"0","forType":"num","forUnits":"minutes","override_topic":false,"state_location":"payload","override_payload":"msg","entity_location":"data","override_data":"msg","x":740,"y":820,"wires":[["76d3e4092163bec9"]]},{"id":"da4bce88a8848620","type":"inject","z":"92ed4c92bf112b10","name":"Run to save state values to context","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"[\"input_number.help_fc_power\",\"input_number.help_in_battery_cycles\",\"input_number.help_temp_number\"]","payloadType":"json","x":220,"y":820,"wires":[["dccac1f4373dde9d"]]},{"id":"4b89f3ba2935375e","type":"debug","z":"92ed4c92bf112b10","name":"debug 13","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1260,"y":820,"wires":[]},{"id":"dccac1f4373dde9d","type":"split","z":"92ed4c92bf112b10","name":"","splt":"\\n","spltType":"str","arraySplt":1,"arraySpltType":"len","stream":false,"addname":"","x":430,"y":820,"wires":[["575c24e171f0ef4b"]]},{"id":"575c24e171f0ef4b","type":"change","z":"92ed4c92bf112b10","name":"Entity ID","rules":[{"t":"set","p":"topic","pt":"msg","to":"payload","tot":"msg"},{"t":"set","p":"payload","pt":"msg","to":"{\"entityId\": payload}","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":560,"y":820,"wires":[["6c0af22021cbdcb6"]]},{"id":"76d3e4092163bec9","type":"join","z":"92ed4c92bf112b10","name":"","mode":"custom","build":"object","property":"payload","propertyType":"msg","key":"topic","joiner":"\\n","joinerType":"str","accumulate":false,"timeout":"","count":"","reduceRight":false,"reduceExp":"","reduceInit":"","reduceInitType":"","reduceFixup":"","x":910,"y":820,"wires":[["d2361b949b499ecf"]]},{"id":"d2361b949b499ecf","type":"change","z":"92ed4c92bf112b10","name":"Save object to context","rules":[{"t":"set","p":"SaveInputs","pt":"flow","to":"payload","tot":"msg","dc":true}],"action":"","property":"","from":"","to":"","reg":false,"x":1080,"y":820,"wires":[["4b89f3ba2935375e"]]},{"id":"2788765ab6b8cf84","type":"inject","z":"92ed4c92bf112b10","name":"Run to reset state values","props":[],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":190,"y":880,"wires":[["6da32448695ba68d"]]},{"id":"6da32448695ba68d","type":"change","z":"92ed4c92bf112b10","name":"Read object from context","rules":[{"t":"set","p":"payload","pt":"msg","to":"SaveInputs","tot":"flow","dc":true},{"t":"set","p":"payload","pt":"msg","to":"$spread(payload)","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":430,"y":880,"wires":[["982750997a6f2398"]]},{"id":"982750997a6f2398","type":"split","z":"92ed4c92bf112b10","name":"","splt":"\\n","spltType":"str","arraySplt":1,"arraySpltType":"len","stream":false,"addname":"","x":610,"y":880,"wires":[["928b8cedad382b07"]]},{"id":"080860e921b7f8c4","type":"debug","z":"92ed4c92bf112b10","name":"debug 14","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1260,"y":880,"wires":[]},{"id":"5b78f62a513063d3","type":"api-call-service","z":"92ed4c92bf112b10","name":"Write state (input number)","server":"","version":5,"debugenabled":false,"domain":"input_number","service":"set_value","areaId":[],"deviceId":[],"entityId":[],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"all","x":950,"y":880,"wires":[["080860e921b7f8c4"]]},{"id":"928b8cedad382b07","type":"change","z":"92ed4c92bf112b10","name":"Set for Call","rules":[{"t":"set","p":"payload","pt":"msg","to":"(\t $id:=$keys(payload)[0];\t $value:=$lookup(payload,$id);\t {\"target\": {\"entity_id\": $id},\t \"data\": {\"value\": $value}\t }\t\t\t)","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":750,"y":880,"wires":[["5b78f62a513063d3"]]}]