Counter node loses count on upgrade

Hi, I've run into a problem where I lose my information from a counter node. The last 2 upgrades it's reset to it's initial value. I have context enabled in settings.js. I can see the file, the value is correct.

I feel like I am missing something, does the counter node load the data from flow.counter automatically on restart? Or do I need to set it to check the file?

Just to note I've removed all decimals from the counter node, it's converted back to decimal in the change node.

[{"id":"49a8a6f8.e3aba8","type":"inject","z":"ec78a76b.a0a4d","name":"Test decrement ","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":640,"y":40,"wires":[["381f2c71.f7670c"]]},{"id":"4f4facbf.7c9d5c","type":"ha-entity","z":"ec78a76b.a0a4d","name":"Oil usage","server":"","version":1,"debugenabled":true,"outputs":1,"entityType":"sensor","config":[{"property":"name","value":"Oil Level"},{"property":"device_class","value":""},{"property":"icon","value":"mdi:propane-tank-outline"},{"property":"unit_of_measurement","value":"gal"}],"state":"count","stateType":"msg","attributes":[{"property":"msg.count","value":"","valueType":"num"}],"resend":true,"outputLocation":"","outputLocationType":"none","inputOverride":"allow","outputOnStateChange":false,"outputPayload":"$entity().state ? \"on\": \"off\"","outputPayloadType":"jsonata","x":1320,"y":100,"wires":[[]],"info":"decimal: 2"},{"id":"244dd0d2.4bfca","type":"poll-state","z":"ec78a76b.a0a4d","name":"Is furnace on?","server":"","version":1,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"updateinterval":"10","updateIntervalUnits":"seconds","outputinitially":false,"outputonchanged":false,"entity_id":"binary_sensor.furnace","state_type":"str","halt_if":"on","halt_if_type":"str","halt_if_compare":"is","outputs":2,"x":170,"y":100,"wires":[["381f2c71.f7670c"],[]]},{"id":"c62686c3.3c9558","type":"change","z":"ec78a76b.a0a4d","name":"set flow.counter","rules":[{"t":"set","p":"counter","pt":"flow","to":"count","tot":"msg"},{"t":"set","p":"count","pt":"msg","to":"count/100000","tot":"jsonata"},{"t":"set","p":"count","pt":"msg","to":"$round(count, 2)","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":1080,"y":100,"wires":[["4f4facbf.7c9d5c"]]},{"id":"50d32aa4.cbfa3c","type":"server-state-changed","z":"ec78a76b.a0a4d","name":"Input boolean oil reset","server":"","version":1,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"input_boolean.oil_reset","entityidfiltertype":"exact","outputinitially":false,"state_type":"str","haltifstate":"on","halt_if_type":"str","halt_if_compare":"is","outputs":2,"output_only_on_state_change":true,"for":0,"forType":"num","forUnits":"minutes","ignorePrevStateNull":true,"ignorePrevStateUnknown":true,"ignorePrevStateUnavailable":true,"ignoreCurrentStateUnknown":true,"ignoreCurrentStateUnavailable":true,"x":200,"y":160,"wires":[["ab075888.bab5e","6f0843b0.c5be9c","5704c381.facbb4","3536c069.0b7b98"],[]]},{"id":"ab075888.bab5e","type":"delay","z":"ec78a76b.a0a4d","name":"","pauseType":"delay","timeout":"250","timeoutUnits":"milliseconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":210,"y":240,"wires":[["a979c77d.9d5538"]]},{"id":"a979c77d.9d5538","type":"api-call-service","z":"ec78a76b.a0a4d","name":"turn off reset switch","server":"","version":1,"debugenabled":false,"service_domain":"input_boolean","service":"toggle","entityId":"input_boolean.oil_reset","data":"","dataType":"jsonata","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":230,"y":320,"wires":[[]]},{"id":"bcf643d5.c3e278","type":"api-call-service","z":"ec78a76b.a0a4d","name":"persistant notification if reset from home assistant","server":"","version":1,"debugenabled":false,"service_domain":"persistent_notification","service":"create","entityId":"","data":"{\t   \"message\":\"Please check your history if you did not initiate this action.\",\t   \"title\":\"Oil level reset\"\t}","dataType":"jsonata","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":1190,"y":160,"wires":[[]]},{"id":"381f2c71.f7670c","type":"counter","z":"ec78a76b.a0a4d","name":"counter","init":"55000000","step":"694","lower":null,"upper":null,"mode":"decrement","outputs":"1","x":860,"y":100,"wires":[["c62686c3.3c9558"]]},{"id":"6f0843b0.c5be9c","type":"change","z":"ec78a76b.a0a4d","name":"delete flow.counter, reset count","rules":[{"t":"set","p":"reset","pt":"msg","to":"true","tot":"bool"},{"t":"delete","p":"counter","pt":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":550,"y":160,"wires":[["381f2c71.f7670c","bcf643d5.c3e278"]]},{"id":"2dfecd3b.2dd8ca","type":"server-state-changed","z":"ec78a76b.a0a4d","name":"counter reset?","server":"","version":1,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"sensor.oil_level","entityidfiltertype":"exact","outputinitially":false,"state_type":"str","haltifstate":"550","halt_if_type":"num","halt_if_compare":"gte","outputs":2,"output_only_on_state_change":true,"for":0,"forType":"num","forUnits":"minutes","ignorePrevStateNull":false,"ignorePrevStateUnknown":false,"ignorePrevStateUnavailable":false,"ignoreCurrentStateUnknown":false,"ignoreCurrentStateUnavailable":false,"x":710,"y":220,"wires":[["42e444f4.34dcbc"],[]]},{"id":"42e444f4.34dcbc","type":"traffic","z":"ec78a76b.a0a4d","name":"","property_allow":"payload","filter_allow":"go","ignore_case_allow":false,"negate_allow":false,"send_allow":false,"property_stop":"payload","filter_stop":"stop","ignore_case_stop":false,"negate_stop":false,"send_stop":false,"default_start":true,"differ":false,"x":990,"y":260,"wires":[["c790064b.a3e35"]]},{"id":"5704c381.facbb4","type":"delay","z":"ec78a76b.a0a4d","name":"","pauseType":"delay","timeout":"2","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":460,"y":320,"wires":[["ce7ed37d.fc4988"]]},{"id":"3536c069.0b7b98","type":"change","z":"ec78a76b.a0a4d","name":"stop","rules":[{"t":"set","p":"payload","pt":"msg","to":"stop","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":470,"y":260,"wires":[["42e444f4.34dcbc"]]},{"id":"c790064b.a3e35","type":"api-call-service","z":"ec78a76b.a0a4d","name":"persistant notification if level 100%","server":"","version":1,"debugenabled":false,"service_domain":"persistent_notification","service":"create","entityId":"","data":"{\t   \"message\":\"Oil level sensor at 100%\",\t   \"title\":\"Oil level\"\t}","dataType":"jsonata","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":1240,"y":260,"wires":[[]]},{"id":"ce7ed37d.fc4988","type":"ha-wait-until","z":"ec78a76b.a0a4d","name":"","server":"","outputs":2,"entityId":"sensor.oil_level","entityIdFilterType":"exact","property":"state","comparator":"lt","value":"550","valueType":"num","timeout":"7","timeoutType":"num","timeoutUnits":"days","entityLocation":"","entityLocationType":"none","checkCurrentState":true,"blockInputOverrides":true,"x":640,"y":320,"wires":[["cad48df3.7f3a68"],[]]},{"id":"cad48df3.7f3a68","type":"change","z":"ec78a76b.a0a4d","name":"go","rules":[{"t":"set","p":"payload","pt":"msg","to":"go","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":790,"y":320,"wires":[["42e444f4.34dcbc"]]},{"id":"9a6e8332.90d2b","type":"inject","z":"ec78a76b.a0a4d","name":"Reset to number set here","props":[{"p":"reset","v":"50200000","vt":"num"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payloadType":"str","x":290,"y":40,"wires":[["381f2c71.f7670c"]]}]

Home assistant add-on ver 8.2.1

Are you storing the context in memory or in the file system? Can you copy and paste that section on the settings.js file please?

Thanks for the quick reply


  contextStorage: {
    default: {
        module: "localfilesystem"
    }
  },

Do you mean upgrade of HA + node-red to a newer version?

I believe HA runs node-red in a container - that is maybe destroyed and re-created upon upgrade. I would ask over at the HA forums.

1 Like

I notice it looks like you have a node deleting the counter. Are you sure it isn’t run on a deploy? Put some debug nodes into see what is happening. Also though the node name says it resets flow.msg it is actually deleting msg.counter

1 Like

Thanks again. It does run in a container and either is possible. It may be destroyed or the reset message could be sent with the upgrade. Is the reset flow.counter needed? Would it not just rewrite the new value when reset was sent to the counter node?

edit delete flow.counter

Is it needed, well I don’t know what you are doing so I can’t answer that. Can you just write a new value - yes

I don’t quite get your last statement edit delete ‘flow.counter’

When I reset the count it also deletes msg.counter. Do I need to delete msg.counter when I reset the counter node.

Msg.counter is part of the msg going into that node. Flow.counter is something different.

Is it? I took that part of the flow from one of your posts actually. You have set to delete flow.counter.

In the documentation I understand it to be delete msg.counter and made the change as I could not find a reference to delete flow.counter on the "working with context page".

Should I change that back to delete flow.counter?

https://nodered.org/docs/user-guide/context#using-context-in-a-flow

So after testing both ways delete flow.counter is correct and the documentation does not work.

It depends on what you are trying to do. Remember a msg is being sent from node to node and can contain many things. If you use an inject node, you will see it defaults to setting msg.payload to a time stamp and msg.topic is blank. You can add other things to the msg like msg.temperature or msg.color or msg.counter. Other nodes that the msg passes thru can also add things to the msg.

Context data (node, flow or global) allows you to store some data that is not in the msg but can be used by a node when a msg arrives. You could think about this like a train. The train is the msg. The stations are the nodes. The train has different cars - the msg has different parts like topic and payload and counter. And the flow variables are like a telegraph message that is already at the station when the train arrives.

As for the documentation, nothing is perfect and it is up to all of us to help make it better. If you find something confusing or missing and can make it better, create a PR and submit your changes to help out others.

But to get back to your question, it depends on if you are using msg.counter for a reason along with flow.counter. That is something I can’t answer.

My goal is to have the data (count) persist even through upgrades. I understood that the way to do that is to enable context.

Will do for the deleting documentation PR

When I upgrade now it resets to the initial value.

When you say upgrade do you mean a deploy or an upgrade of some software?
Have you added debug Nodes in to see what path you are going thru the flow?

It only happens on an upgrade to a new version of node-red. It was happening sometimes on deploy. Since context has be enabled that has not been a problem. It's been working without a problem for about 4 weeks.

I'm new to node red and do a lot of testing, so I am constantly deploying new flows.

So is this still an issue? An upgrade of node red should not effect the context data unless you were storing it in memory, in which case every stop/start of node-red would wipe it out.

This is an add-on to home assistant. It may have something to do with how the containers are handled during an upgrade. I just wanted to make sure I had taken the correct steps before I open an issue.

Thanks again for the help I'll update the thread when I find something out.

One other question does the name of the flow have to match the node it's attached to? In my flow the counter node is named counter and flow.counter.

If the counter node was named pieces would I then use flow.pieces?

Flow variables are NOT connected to a node or a message. They are available to any node in the flow (flow in this case being all the nodes that are connected by wires - the term ‘flow’ means many things. All the nodes and wires on all tabs are called the flow as are a series of nodes connected by wires.)

If you wanted a variable only attached to one node, you would use a context(node) variable. If you want a variable available to every node in your project< you would use a global variable.

Yes - so where exactly does the HA container persist its volumes ? unless they mount the internal filesystem you are writing to as either an external volume, or to the host filesystem, then it will get replaced when HA does.

1 Like