I resolved my Node-Red issue. Looking forward to trying your flow.
Yes 2.5 gal per hour. This is for a small apartment building, about 7000 sq. ft.
@Mikefila, I juts wanted to let you know that your approach has been working great.
I appreciate everyone’s help with this solution and I have learned a little bit more of Home Assistant with all the ideas and feedback.
Thanks again.
Last night my tank randomly reset. The switch went unavailable and upon restore to off it triggered a reset. Idk if you have experience that yet but changing the following should prevent it.
to
No, I have not experienced that issue but I have made the recommended changes.
@Mikefila, so it looks like I may still be experiencing the reset after making your suggested change. I think it may be related to a restart of HA. Is there a way to “write” the last known value of the oil used and use that as the starting point going forward until an actual reset is requested?
On the left choose history and choose the sensor for the counter. It should be sensor.oil
unless you changed it. Choose a time before the reset and it will show a chart.
When you see the time it reset it will show the previous level. If you enter that time in the logbook, on the left by history tab, it will tell you what triggered the reset.
It reset yesterday and I see a bunch of Tank reset became unavailable and then reset turned off.
I am not sure what caused that. I will need to look into my logs more.
Okay made a change using an input boolean for the reset switch. This should ignore any unavailable/unknown state changes. Go to configuration–>helpers–>add helper and choose toggle name it Oil reset. If you want to use a different name just change the name of the input boolean in the node.
[{"id":"43680138.7be8c8","type":"inject","z":"7d105d71.cc18e4","name":"Test","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"on","payloadType":"str","x":450,"y":40,"wires":[["bd2250f5.562288"]]},{"id":"bd2250f5.562288","type":"counter","z":"7d105d71.cc18e4","name":"oil counter","init":"429","step":"0.0104","lower":"","upper":"","mode":"decrement","outputs":2,"x":730,"y":80,"wires":[["43a6f30c.96e75c"],[]]},{"id":"2a4aa0d1.e11918","type":"ha-entity","z":"7d105d71.cc18e4","name":"Oil usage","server":"7c85afe1.bbea8","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":"payload","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":1200,"y":80,"wires":[[]],"info":"decimal: 2"},{"id":"7a32a30c.d5ba2c","type":"poll-state","z":"7d105d71.cc18e4","name":"Is furnace on?","server":"7c85afe1.bbea8","version":1,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"updateinterval":"15","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":210,"y":80,"wires":[["bd2250f5.562288"],[]]},{"id":"2274d86c.b1991","type":"function","z":"7d105d71.cc18e4","name":"reset message ","func":"msg.reset = \"True\";\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":500,"y":120,"wires":[["bd2250f5.562288"]]},{"id":"43a6f30c.96e75c","type":"change","z":"7d105d71.cc18e4","name":"set to 2 decimal points","rules":[{"t":"set","p":"payload","pt":"msg","to":"$round(payload, 2)","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":960,"y":80,"wires":[["2a4aa0d1.e11918"]]},{"id":"5ee37ec9.ecabb","type":"server-state-changed","z":"7d105d71.cc18e4","name":"Input boolean oil reset","server":"7c85afe1.bbea8","version":1,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"input_boolean.oil_reset","entityidfiltertype":"exact","outputinitially":true,"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":240,"y":140,"wires":[["dcfe2213.4b8aa8","2274d86c.b1991"],[]]},{"id":"dcfe2213.4b8aa8","type":"delay","z":"7d105d71.cc18e4","name":"","pauseType":"delay","timeout":"250","timeoutUnits":"milliseconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":490,"y":160,"wires":[["e731237a.3046b"]]},{"id":"e731237a.3046b","type":"api-call-service","z":"7d105d71.cc18e4","name":"Turn off reset switch","server":"7c85afe1.bbea8","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":760,"y":160,"wires":[[]]},{"id":"7c85afe1.bbea8","type":"server","name":"Home Assistant","legacy":false,"addon":true,"rejectUnauthorizedCerts":true,"ha_boolean":"y|yes|true|on|home|open","connectionDelay":true,"cacheJson":true}]
Thanks Mike, I will update accordingly.
Thank you for your help.
I just tried that. I changed the input_number and restarted. My updated value was not stored. The input_number value was reset to the initial: value after the restart.
What am I doing wrong?
If you specify an initial value, it will always be set to that value on startup or reload. The concept of storing the last known value is lost if you define an initial value.
Got it, thanks!!
Not sure why I didn’t see that. I tried again without an initial: value and it saved across restarts as expected.
For future reference, input_select
behaves differently. It cannot exist without an initial value; you can’t define an “empty” input_select
and then populate it later (via a script or automation). Because it must be initialized, any changes you make to it afterwards are lost after a restart (because it uses its initial value on startup).
I learned this when I tried to use an input_select
for general storage of data (it’s a list that can be expanded). Everything worked well until I restarted Home Assistant and all my added data was discarded and replaced by the initial value(s). I thought I could create an empty input_select
and then any data I added to it would be stored/restored. No; it must have an initial value (i.e. the input_select
must be defined with at least one option).
Glad I’m not the only one tripped up by that. Thanks for elaborating!
For anyone who might be interested, I documented my progress on my oil tank level gauge project here:
@Mikefila, Just an FYI, I noticed I had an issue where I “deployed” my Node-Red flows and the oil tracker reset my tank value back to 275. Other then that it has been running fine.
Alright this should be it. Apparently node-red by default does not save data, it needs to be enabled. Go to your file editor and navigate to the node red folder. Find the file settings.js
and select it. You need to add the following:
contextStorage: {
default: {
module: "localfilesystem"
}
},
It’s important to watch your blank spaces, each dot is 1 space.
Save the file, go to supervisor, node-red app and restart node red. Give it a minute or two and check the logs tab inside the node-red app page, see if there are any errors.
Here is the revised flow that will save the count.
[{"id":"49a8a6f8.e3aba8","type":"inject","z":"ec78a76b.a0a4d","name":"Test","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"on","payloadType":"str","x":430,"y":60,"wires":[["381f2c71.f7670c"]]},{"id":"4f4facbf.7c9d5c","type":"ha-entity","z":"ec78a76b.a0a4d","name":"Oil usage","server":"7c85afe1.bbea8","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":1380,"y":100,"wires":[[]],"info":"decimal: 2"},{"id":"244dd0d2.4bfca","type":"poll-state","z":"ec78a76b.a0a4d","name":"Is furnace on?","server":"7c85afe1.bbea8","version":1,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"updateinterval":"15","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 to 2 decimal points","rules":[{"t":"set","p":"count","pt":"msg","to":"$round(count, 2)","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":1160,"y":100,"wires":[["4f4facbf.7c9d5c"]]},{"id":"50d32aa4.cbfa3c","type":"server-state-changed","z":"ec78a76b.a0a4d","name":"Input boolean oil reset","server":"7c85afe1.bbea8","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":220,"wires":[["ab075888.bab5e","6f0843b0.c5be9c"],[]]},{"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":430,"y":220,"wires":[["a979c77d.9d5538"]]},{"id":"a979c77d.9d5538","type":"api-call-service","z":"ec78a76b.a0a4d","name":"turn off reset switch","server":"7c85afe1.bbea8","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":810,"y":220,"wires":[[]]},{"id":"bcf643d5.c3e278","type":"api-call-service","z":"ec78a76b.a0a4d","name":"persistant notification if reset","server":"7c85afe1.bbea8","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":840,"y":160,"wires":[[]]},{"id":"381f2c71.f7670c","type":"counter","z":"ec78a76b.a0a4d","name":"oil counter","init":"550","step":"0.0104","lower":"","upper":"","mode":"decrement","outputs":"1","x":790,"y":100,"wires":[["b98146ef.0ab288","c62686c3.3c9558"]]},{"id":"b98146ef.0ab288","type":"change","z":"ec78a76b.a0a4d","name":"save count to flow.counter","rules":[{"t":"set","p":"counter","pt":"flow","to":"count","tot":"msg"},{"t":"set","p":"payload","pt":"msg","to":"count/1000","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":1170,"y":160,"wires":[[]]},{"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":"flow"}],"action":"","property":"","from":"","to":"","reg":false,"x":490,"y":160,"wires":[["381f2c71.f7670c","bcf643d5.c3e278"]]},{"id":"7c85afe1.bbea8","type":"server","name":"Home Assistant","legacy":false,"addon":true,"rejectUnauthorizedCerts":true,"ha_boolean":"y|yes|true|on|home|open","connectionDelay":true,"cacheJson":true}]
E. You should also see a new folder inside the node-red folder named context
.
Thanks Mike
Don’t thank me yet lol, there is a problem with the math. The counter can encounter errors with decimals. So you have to multiply your burn rate to bring it to a whole number, then multiply the gallons.
my ex
burn rate: .0104
x 10,000
= 104
then 550gal x 10000 = 5,500,000gal.
Enter that in the counter. Now swap these 2 nodes in. Adjust the multiplier as necessary.
[{"id":"c62686c3.3c9558","type":"change","z":"ec78a76b.a0a4d","name":"set to 2 decimal points","rules":[{"t":"set","p":"count","pt":"msg","to":"count/10000","tot":"jsonata"},{"t":"set","p":"count","pt":"msg","to":"$round(count, 2)","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":1160,"y":100,"wires":[["4f4facbf.7c9d5c"]]},{"id":"b98146ef.0ab288","type":"change","z":"ec78a76b.a0a4d","name":"save count to flow.counter","rules":[{"t":"set","p":"counter","pt":"flow","to":"count","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":1170,"y":160,"wires":[[]]}]
This will bring it back to 2 decimals in HA.
So, if I understand this correctly, I would take my burn rate of .00354 (per 15 seconds) and times that by 100000 to get to 354 and then times my tank capacity by 100000, which will make it 27500000 gallons. The new gallons value would be put into the “oil counter” node along with the new burn rate of 354, I then would divide the counter number by 100000 in the “set to 2 decimal flow”.
Is that the correct logic?