Gas Water Heater pilot light out and energy monitor

Hello everyone. I would like to thank the whole community at large. There is no way I could have been successful with HA without all of you. In reality, this is the communities’ project just as much as mine. I just took bits and pieces and put it together.

I have had a long standing problem with my hot water heater in that the pilot light often goes out on windy days. The exhaust vent is in a breeze way. When the wind blows from a specific direction it builds a high-pressure area in that location. Up until now I generally found out by the shower not being hot in the morning. Not the way to start a day!

I want to add that tampering with the pilot light system was not something I took lightly. In fact, I was very concerned. I also would encourage that you do not take on this project unless you are aware of the implications. The approach I took was to monitor the load/voltage drop across the Thermopile. It only required attaching leads across the terminals of the thermopile output. This method did not interfere with the actual method used to shut off the pilot. I decided to approach the problem by using an ESP8266 nodemcu and ESPHome. In retrospect I would have used an ESP32 since it has more than one analog pin. I will explain more later.

The connection is pretty basic. I soldered two leads to the circuit board to the input location of the thermopile. A red lead to the positive and black to the negative. These were clearly labeled on the cover of the water heater controller.

On the NodeMCU I connected the red lead to the A0 pin and the black lead to the ground pin.

I then created a ESPHome Node

sensor:
  - platform: adc
    pin: A0
    name: "Voltage"
    accuracy_decimals: 3
    update_interval: 15s

Then I created several different ways to monitor the output voltage. I created an instantaneous gauge and a graph over time.

This is where I found an unexpected situation. I noticed the there was random times that the voltage reading fluctuated. After some investigation I realized that the voltage reading dropped while the main burner was on. I am not sure why. It could be because when the main burner kicks on the flame on the pilot reduces because of pressure drop. It could be that the control unit is drawing more Milliamps when holding the valve open for the main burner. It could also be a combination of both.

I use node red for most of my automation, so I created a way to track the on time by starting and stopping a timer when the voltage was between a certain range. When to voltage was above .1 V and below .14 V the timer would run outside that range it would stop. I zero out the timer at midnight and this gives me a daily time on. On any given hot water heater this might need to be adjusted.

The reason to consider a ESP32 would be that it has multiple analog pins so you could add things like moisture sensors, Outlet temp sensors and possibly control a water cutoff valve.

I hope someone finds this project inspiring as I have found others inspiring.

Below are some more pictures of the project completed and what a pilot light out event looks like.

A neat project.

Could you have used a light sensor over the status light to at least warn you that the pilot light maybe out ?

I like the breadboard the ESP32 is on - do you have a link for them ?

I tried several different approaches including that one. They all were a fail. Then I found this video that led me in this direction.

Link to breadboard
https://smile.amazon.com/gp/product/B07H9CV1H9/ref=ppx_yo_dt_b_asin_title_o02_s00?ie=UTF8&psc=1

So does the pilot light stay on all the time using a small amount of Gas ? In the UK we used to have gas boilers like that with a small window so you could see the pilot light but now there is no pilot light and when the boiler turns on it ignites the gas itself.

Thanks for the link - similar products on their UK store.

Yes here in the US the pilot stays on all the time for most water heaters. The up side is that the water heater works even when the power is out.

That’s funny in a “wow, that’s ironic” kind of way). :laughing:

I have the same style & brand gas control valve as you and I the exact same issue.

I originally thought the same as you that the wind was blowing the pilot out occasionally. But then it happened and there was no wind at all. So I figured it was a failure in the gas controller itself.

It was only a very occasional nuisance so I didn’t get around to getting a new valve for a while but those few times waking up to a cold shower was enough to get me thinking, like you, about how to let me know ahead of time if the pilot was out.

But I ended up using a different (but similar) approach as you did.

I ended up using a NodeMCU with a thermocouple attached. And then I put the thermocouple into the flue to measure the temperature of the gases/water. That way I didn’t have to modify the gas controller at all.

As of now it’s only “temporary” so it looks a little janky. But at this point I think it’s considered “permanently temporary” since it’s been like it is for months - if it works don’t mess with it. Am I right?

And besides I had every intention of replacing the valve. But ironically it has only failed a couple of times since I got the sensor set up so it’s been kind of a low priority.

here are a couple of pictures of the “temporary” set up:

and here is a graph of the temperature readings. You can definitely tell when the hot water is being used.

Since with the pilot and the thermal mass of the water in the tank the temp hangs out around 130 degrees when the main burner isn’t on I have my notifications set to tell me at 125 degrees that there is a problem.

1 Like

Yes that is pretty funny to have such a similar situation. My tank is inside my house in the laundry room. It has a air exchange vent that is closed loop. I have had this tank about a year. It even has a “Flame Knock down sensor” If it gets to windy and the main burner is on, it somehow disconnects the thermopile and you have to push this little rod back in to get the pilot to even light.

I guess we share a brain :grinning:

1 Like

Great setup. Installed my own, seems to be working great. Can you share a bit more about your node red timer? I’ve got an Event state trigger setup as if statement (if below X voltage) - but a bit lost finding the best way to start a timer that home assistant also tracks.

Thanks!

Above is the Nodered flow. It does 2 things. Turns a Boolean Helper on and off to hopefully correspond with the water heater on and off times (input_boolean.waterheateron). It also runs a timer that updates Input number helper (input_number.whontime).

PS: I cannot take credit for the code. Unfortunately I have lost track of the person that posted it. Credits to the unknown contributor!

Thanks so much! Getting this when trying to import:

[{"id":"8553d42c.9c72f8","type":"server-state-changed","z":"a533205c.6d71f","name":"Hotwater Heater","server":"f65d7dca.9fa39","version":1,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"sensor.voltage","entityidfiltertype":"exact","outputinitially":false,"state_type":"num","haltifstate":".1","halt_if_type":"num","halt_if_compare":"gt","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":100,"y":140,"wires":[["9ab76594.503838"],[]]},{"id":"a1afd68a.2386e8","type":"api-call-service","z":"a533205c.6d71f","name":"","server":"f65d7dca.9fa39","version":1,"debugenabled":false,"service_domain":"input_boolean","service":"turn_on","entityId":"input_boolean.waterheateron","data":"","dataType":"jsonata","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":1000,"y":120,"wires":[[]]},{"id":"981b2f5f.12132","type":"mytimeout","z":"a533205c.6d71f","name":"Timer","outtopic":"","outsafe":"","outwarning":"","outunsafe":"on","warning":"0","timer":"30","debug":false,"ndebug":false,"ignoreCase":false,"repeat":false,"again":false,"x":830,"y":260,"wires":[["8762a2.069e3d6"],[]]},{"id":"8762a2.069e3d6","type":"api-call-service","z":"a533205c.6d71f","name":"","server":"f65d7dca.9fa39","version":1,"debugenabled":false,"service_domain":"input_boolean","service":"turn_off","entityId":"input_boolean.waterheateron","data":"","dataType":"jsonata","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":1000,"y":320,"wires":[[]]},{"id":"e9f08f87.9a58","type":"switch","z":"a533205c.6d71f","name":"","property":"payload","propertyType":"msg","rules":[{"t":"btwn","v":".001","vt":"num","v2":".099","v2t":"num"},{"t":"btwn","v":".1","vt":"num","v2":".14","v2t":"num"},{"t":"btwn","v":".141","vt":"num","v2":"1","v2t":"num"}],"checkall":"true","repair":false,"outputs":3,"x":510,"y":140,"wires":[["4f4f3513.55eabc"],["e26013ef.b17ef","68596569.990dfc"],["4f4f3513.55eabc"]]},{"id":"e26013ef.b17ef","type":"change","z":"a533205c.6d71f","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"on","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":720,"y":140,"wires":[["981b2f5f.12132","a1afd68a.2386e8"]]},{"id":"20a66941.79cd36","type":"inject","z":"a533205c.6d71f","name":"","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"0.13","payloadType":"str","x":100,"y":60,"wires":[["9ab76594.503838"]]},{"id":"9ab76594.503838","type":"change","z":"a533205c.6d71f","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"$number(payload)","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":340,"y":140,"wires":[["e9f08f87.9a58"]]},{"id":"68596569.990dfc","type":"change","z":"a533205c.6d71f","name":"Start","rules":[{"t":"set","p":"payload","pt":"msg","to":"run","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":470,"y":340,"wires":[["130e73c2.fce6bc"]]},{"id":"4f4f3513.55eabc","type":"change","z":"a533205c.6d71f","name":"Stop","rules":[{"t":"set","p":"payload","pt":"msg","to":"stop","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":499,"y":292,"wires":[["130e73c2.fce6bc"]]},{"id":"ac33ed6a.20fa3","type":"api-call-service","z":"a533205c.6d71f","name":"Time On","server":"f65d7dca.9fa39","version":1,"debugenabled":false,"service_domain":"input_number","service":"set_value","entityId":"input_number.whontime","data":"{\"value\" : \"{{payload}}\"}","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":900,"y":480,"wires":[[]]},{"id":"12d6d8a0.cc78d7","type":"inject","z":"a533205c.6d71f","name":"Run","props":[{"p":"payload","v":"run","vt":"str"},{"p":"topic","v":"","vt":"string"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"run","payloadType":"str","x":170,"y":500,"wires":[["130e73c2.fce6bc"]]},{"id":"2300e9a9.76fec6","type":"inject","z":"a533205c.6d71f","name":"Stop","props":[{"p":"payload","v":"stop","vt":"str"},{"p":"topic","v":"","vt":"string"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"stop","payloadType":"str","x":170,"y":560,"wires":[["130e73c2.fce6bc"]]},{"id":"d10919c1.ed5708","type":"inject","z":"a533205c.6d71f","name":"Reset","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"59 23 * * *","once":false,"onceDelay":0.1,"topic":"","payload":"reset","payloadType":"str","x":180,"y":400,"wires":[["130e73c2.fce6bc"]]},{"id":"130e73c2.fce6bc","type":"function","z":"a533205c.6d71f","name":"","func":"if (msg.payload == \"reset\") {\n    flow.set(\"counter\",0);\n}\n\nflow.set(\"status\",msg.payload);","outputs":0,"noerr":0,"x":500,"y":500,"wires":[]},{"id":"a5ec0ed0.301f8","type":"inject","z":"a533205c.6d71f","name":"","props":[{"p":"payload","v":"1","vt":"num"},{"p":"topic","v":"","vt":"string"}],"repeat":"1","crontab":"","once":true,"onceDelay":"0.5","topic":"","payload":"1","payloadType":"num","x":170,"y":660,"wires":[["6ebacdb1.431cf4"]]},{"id":"6ebacdb1.431cf4","type":"function","z":"a533205c.6d71f","name":"","func":"var status = flow.get(\"status\")  || \"stop\";\nvar count  = flow.get(\"counter\") || 0;\n\nif (status == \"run\"){\n    count = count + 1;\n}\n\nflow.set(\"counter\",count);\nmsg.payload = count;\nreturn msg;\n","outputs":1,"noerr":0,"initialize":"","finalize":"","x":370,"y":660,"wires":[["b6e1a25e.eec7c"]]},{"id":"b6e1a25e.eec7c","type":"calculator","z":"a533205c.6d71f","name":"/60","inputMsgField":"payload","outputMsgField":"payload","operation":"div","constant":"60","round":true,"decimals":"6","x":610,"y":600,"wires":[["1aca852e.dc496b"]]},{"id":"1aca852e.dc496b","type":"calculator","z":"a533205c.6d71f","name":"/60","inputMsgField":"payload","outputMsgField":"payload","operation":"div","constant":"60","round":true,"decimals":"3","x":770,"y":560,"wires":[["ac33ed6a.20fa3"]]},{"id":"f65d7dca.9fa39","type":"server","name":"Home Assistant","addon":true}]

:exploding_head:

I think it’s hilarious that people go to Node-Red because they complain that YAML and Jinja are “too complicated”. And then act like the code posted above makes complete sense and is easier. :laughing:

My most complicated templates/automations aren’t anywhere near to that sheer wall of text.

You don’t really deal with that code above. That is an export file. It builds the nodes and relationships when you import it. There are just things that you cannot do with Yaml and code unless you are a coding wizard… Different strokes for different folks :slight_smile:

@Hankc64 Thanks for sharing your project! I was looking to solve a similar problem and was able to leverage a lot of what you shared here.

I ended up making a battery powered version just to monitor when my pilot light goes out. It’s trending towards 100 day battery life.

I also made a case to hold the ESP32_bat_pro board and battery. If anyone would like to use it in there design, you can download it here: https://www.printables.com/model/569576-case-for-esp32-bat-pro-board-and-battery

I also forked a GitHub repo with some very slight modifications to make it easy to integrate the battery monitoring features of the board I used into ESPHome: https://github.com/gfalgiano/lc709203f instructions are on the GitHub page.

The dashboard I setup