Pellet stove hopper level, ultrasonic sensor and thermostat relay. ESPHOME

Thermostat controlled pellet stove relay.
Ultrasonic pellet fuel hopper level sensor.

Thought it would be nice to see if the Wood heat Pellet stove needed pellets at any time and be able to automate when low.
I already had a low volt relay connected to the stove for a thermostat control integrated with my Schedy heating schedule using input Boolean occupancy detection so I just needed to swap out the old relay with a D1 mini and a relay shield and just because I could I added a DS18B20 temperature shield. (but it is reading high because it located behind the pellet stove).
D1 mini 5$
D1 mini relay shield 2$
D1 mini DS18B20 temperature sensor shield 2.50$
Ultrasonic Module HC-SR04 Distance Sensor 2$

Temporary project box until I 3D print a new box to fit all the components.


  name: pellet_controller
  platform: ESP8266
  board: d1_mini

  ssid: "smarthome1"
  password: "wireless"
#IP Address:
  # Enable fallback hotspot (captive portal) in case wifi connection fails

    ssid: "Pellet Controller"
    password: "1QTAReJlz3j5"
#Open web port for browser access
  port: 80

# Enable logging

# Enable Home Assistant API

  - platform: ultrasonic
    trigger_pin: D4
    echo_pin: D3
    name: "pellet level in percent"
    update_interval: 30s
# Optional variables:
    icon: "mdi:sack-percent"
    accuracy_decimals: 0      
    # Calculates in %
    # Replace 0.46 by the height of hopper. From the sensor to the bottom.
    # I used this website to know how I should multiply my values : 
    - lambda: return (0.46-x)*(100/0.46);
    unit_of_measurement: "%"
  #- platform: ultrasonic
  #  trigger_pin: D4
   # echo_pin: D3

  #  update_interval: 30s
 #Optional variables:
   # icon: "mdi:sack-percent"
   # filters:
     #Replace the 0.46 by the height of hopper. From the sensor to the bottom.
     # I multiplied by 100 in order to get CM since the sensor works in meters
   # - lambda: return (0.46-x)*100;
   # unit_of_measurement: "cm"
  - platform: dallas
    name: "pellet stove Temperature"
    address: "0xB303139779A1FE28"   
  - pin: D2
    #update_interval: 30s  

  - platform: gpio
    name: "pellet_stove_relay"
    pin: D1    

Node red flow for random alexa messages when level gets low.

[{"id":"5eec722a.87ac8c","type":"tab","label":"pellets","disabled":false,"info":""},{"id":"fd5738bb.a8f118","type":"api-call-service","z":"5eec722a.87ac8c","name":"turn off lights","server":"ceea5ac5.1b1658","version":1,"debugenabled":false,"service_domain":"switch","service":"turn_off","entityId":"switch.garage_light, switch.driveway_light","data":"","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":630,"y":80,"wires":[[]]},{"id":"81055a15.3fda38","type":"delay","z":"5eec722a.87ac8c","name":"","pauseType":"delay","timeout":"15","timeoutUnits":"minutes","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":470,"y":80,"wires":[["fd5738bb.a8f118"]]},{"id":"bd26d583.2beb68","type":"server-state-changed","z":"5eec722a.87ac8c","name":"pellet level","server":"ceea5ac5.1b1658","version":1,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"sensor.pellet_level_in_percent","entityidfiltertype":"exact","outputinitially":true,"state_type":"num","haltifstate":"","halt_if_type":"str","halt_if_compare":"is","outputs":1,"output_only_on_state_change":false,"for":"","forType":"num","forUnits":"minutes","ignorePrevStateNull":false,"ignorePrevStateUnknown":false,"ignorePrevStateUnavailable":false,"ignoreCurrentStateUnknown":false,"ignoreCurrentStateUnavailable":false,"x":80,"y":100,"wires":[["195c90a5.5c30af"]]},{"id":"d0a5c7d9.3c0718","type":"api-call-service","z":"5eec722a.87ac8c","name":"alexa say ","server":"ceea5ac5.1b1658","version":1,"debugenabled":true,"service_domain":"notify","service":"alexa_media_moms_room_dot","entityId":"","data":"{\"message\":\"{{payload}}\",\"data\":{\"type\":\"tts\"}}","dataType":"json","mergecontext":"","output_location":"payload","output_location_type":"msg","mustacheAltTags":false,"x":680,"y":360,"wires":[[]]},{"id":"4354ce85.085d3","type":"api-call-service","z":"5eec722a.87ac8c","name":"alexa say ","server":"ceea5ac5.1b1658","version":1,"debugenabled":true,"service_domain":"notify","service":"alexa_media_kitchen_echo_dot","entityId":"","data":"{\"message\":\"{{payload}}\",\"data\":{\"type\":\"tts\"}}","dataType":"json","mergecontext":"","output_location":"payload","output_location_type":"msg","mustacheAltTags":false,"x":680,"y":320,"wires":[[]]},{"id":"11ae4a5a.95b376","type":"switch","z":"5eec722a.87ac8c","name":"","property":"payload","propertyType":"msg","rules":[{"t":"btwn","v":"10","vt":"num","v2":"28","v2t":"num"}],"checkall":"true","repair":false,"outputs":1,"x":370,"y":140,"wires":[["a0085c07.65023"]]},{"id":"195c90a5.5c30af","type":"range-for","z":"5eec722a.87ac8c","name":"","above":"","below":"28","for":"5","units":"min","continuous":false,"x":210,"y":160,"wires":[["11ae4a5a.95b376"],[]]},{"id":"7b2a5bfd.635a74","type":"inject","z":"5eec722a.87ac8c","name":"31","props":[{"p":"payload"},{"p":"topic","v":"","vt":"num"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"31","payloadType":"num","x":50,"y":280,"wires":[["195c90a5.5c30af"]]},{"id":"a0085c07.65023","type":"time-range-switch","z":"5eec722a.87ac8c","name":"","lat":"","lon":"","startTime":"07:00","endTime":"22:30","startOffset":0,"endOffset":0,"x":520,"y":200,"wires":[["c72d9bbc.14ee88"],[]]},{"id":"3d06733c.aa49dc","type":"api-call-service","z":"5eec722a.87ac8c","name":"turn off boolean","server":"ceea5ac5.1b1658","version":1,"debugenabled":false,"service_domain":"input_boolean","service":"turn_off","entityId":"input_boolean.pellets_low","data":"","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":420,"y":540,"wires":[[]]},{"id":"c72d9bbc.14ee88","type":"api-call-service","z":"5eec722a.87ac8c","name":"input need pellets on","server":"ceea5ac5.1b1658","version":1,"debugenabled":false,"service_domain":"input_boolean","service":"turn_on","entityId":"input_boolean.pellets_low","data":"","dataType":"jsonata","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":620,"y":140,"wires":[[]]},{"id":"51945849.e946f8","type":"switch","z":"5eec722a.87ac8c","name":"","property":"payload","propertyType":"msg","rules":[{"t":"btwn","v":"30","vt":"num","v2":"95","v2t":"num"}],"checkall":"true","repair":false,"outputs":1,"x":310,"y":480,"wires":[["3d06733c.aa49dc"]]},{"id":"c8160e0f.f0ddd","type":"range-for","z":"5eec722a.87ac8c","name":"","above":"30","below":"","for":"5","units":"min","continuous":false,"x":150,"y":520,"wires":[["51945849.e946f8"],[]]},{"id":"cf2df0ad.95a2e","type":"server-state-changed","z":"5eec722a.87ac8c","name":"pellet level full turn off","server":"ceea5ac5.1b1658","version":1,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"sensor.pellet_level_in_percent","entityidfiltertype":"exact","outputinitially":true,"state_type":"num","haltifstate":"","halt_if_type":"str","halt_if_compare":"is","outputs":1,"output_only_on_state_change":false,"for":"","forType":"num","forUnits":"minutes","ignorePrevStateNull":false,"ignorePrevStateUnknown":false,"ignorePrevStateUnavailable":false,"ignoreCurrentStateUnknown":false,"ignoreCurrentStateUnavailable":false,"x":100,"y":440,"wires":[["c8160e0f.f0ddd"]]},{"id":"82e4c7b9.879a68","type":"api-call-service","z":"5eec722a.87ac8c","name":"alexa say ","server":"ceea5ac5.1b1658","version":1,"debugenabled":true,"service_domain":"notify","service":"alexa_media_carlene_s_echo_dot","entityId":"","data":"{\"message\":\"{{payload}}\",\"data\":{\"type\":\"tts\"}}","dataType":"json","mergecontext":"","output_location":"payload","output_location_type":"msg","mustacheAltTags":false,"x":680,"y":400,"wires":[[]]},{"id":"169b3b7.23a99c5","type":"server-state-changed","z":"5eec722a.87ac8c","name":"need pellets message on","server":"ceea5ac5.1b1658","version":1,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"input_boolean.pellets_low","entityidfiltertype":"exact","outputinitially":false,"state_type":"str","haltifstate":"30","halt_if_type":"str","halt_if_compare":"is","outputs":2,"output_only_on_state_change":true,"for":"1","forType":"num","forUnits":"minutes","ignorePrevStateNull":false,"ignorePrevStateUnknown":false,"ignorePrevStateUnavailable":false,"ignoreCurrentStateUnknown":false,"ignoreCurrentStateUnavailable":false,"x":180,"y":380,"wires":[["1a08494.f4d8bb7"],[]]},{"id":"1a08494.f4d8bb7","type":"function","z":"5eec722a.87ac8c","name":"random message","func":"var line1 = [\"Heya anyone there?, \", \"Yo People of the house, \", \"Hello You yes you, \", \"howdy-do house guest, \"]\nvar line2 = [\n        \"The pellet stove \", \"the heater \", \"the thing that keep you toasty \", \"The furnace \", \"The pellet stove \"\n        ]\nvar line3 = [\n        \"wanted you to know  \",\n        \"Asked me to tell you  \",\n        \"Told me to pass along to you  \",\n        \"Ordered me to tell you  \",\n        \"Shared with me  \"\n        ]\nvar line4 = [\n        \"its hopper hungry, \", \"Its time to fill with Pellets, \", \" it needs stove chow, \", \" the hopper is low , \"\n        ]\nvar line5 = [\n        \"pellets now or cold later.\", \"time for a 40 pound workout.\", \"dont go to bed cold.\", \"I know I am annoying you \"\n        ]\nmsg.payload =\n\nline1[Math.floor(Math.random() * line1.length)]+\nline2[Math.floor(Math.random() * line2.length)]+\nline3[Math.floor(Math.random() * line3.length)]+\nline4[Math.floor(Math.random() * line4.length)]+\nline5[Math.floor(Math.random() * line4.length)]\n\nreturn msg","outputs":1,"noerr":0,"initialize":"","finalize":"","x":490,"y":400,"wires":[["4354ce85.085d3","d0a5c7d9.3c0718","82e4c7b9.879a68"]]},{"id":"ceea5ac5.1b1658","type":"server","name":"Home Assistant","legacy":false,"addon":true,"rejectUnauthorizedCerts":true,"ha_boolean":"y|yes|true|on|home|open","connectionDelay":true,"cacheJson":true}]

My background. I have been using sonoff devices and ewelink with IFTTT for about 3 years to automate my home and heating and evaporative cooler. I made the jump to HA and I have been playing with Home assistant since 2018. I’m enjoying playing with WLED I made a automatic fish feeder also.
Over 30 years I have been installing and servicing Hearth products specializing in Gas and wood pellet burning stoves.
Home automation is a hobby I needed.
my Facebook page


This is super interesting since I kind of wanted to DIY one for a Traeger. Does the ultrasonic sensor need light at all or does it work in a completely dark area(eg: lid closed on a pellet hopper).

ultrasonic means by ultra sound…
hence it also works in the dark :thinking:

No light.
it using ultrasonic waves measure the time it takes to bounce back.
HC-SR04 ultrasonic distance sensor. This economical sensor provides 2cm to 400cm of non-contact measurement functionality with a ranging accuracy that can reach up to 3mm. Each HC-SR04 module includes an ultrasonic transmitter, a receiver and a control circuit.

There are only four pins that you need to worry about on the HC-SR04: VCC (Power), Trig (Trigger), Echo (Receive), and GND (Ground).

1 Like

I tried this project, but I must say that the vibrations and/or the heat generated by the stove seem to compromise the ultrasonic sensor data. So it works only when the stove is empity, at least for me.

Hi , I have a biomass boiler and interested in trying the pellet depth reader. CAn I ask if the relay is needed for just reading depths? Do you have a wiring diagram?

The reason I ask is some research ahs shown capacitors being added and others straight wiring to D1 and yours has a relay. Just wondering why and the best way to move forward.

Again I want to have it like yours and alert me when the level is low. I am new to this HA and haven’t even ventured to Amazon Alexa and the notifications.

Sorry I just saw this.
No relay needed.
My set up is a all in one controller for a pellet stove.
The relay is for the thermostat

Hey, nice project. I would like to just measure the level of pellet in my stove, so I decided to use this projet: Salt level sensor for water softener in Home Assistant with ESPHome – ADONNO . I am just stuck at one point, what power source to use? When I try to buy the D1 mini on amazon, it says don’t use a source higher than 3,3V . Others say they are using a phone charger, equivalent to 5V 1A. Can you please tell me about the power source wiring you use? Thank you

Most d1 mini that I have used have 5v micro usb connection that takes 5v and converts down.
You can also connect to the 5v pin on the board.
The sensor you connect to the 5v pin or 3.3v pin depending on brand.

See pin out for your board.
Also here is a screenshot from the link you attached

Thank you. I meant by connecting the D1 mini to the power outlet. Anyhow, I guess I will use an iphone adapter, should work fine based on all the comments I saw online.

You can use the 5v pin and ground for power in or the USB port
The 5v in brown in this pin out mhpXmtOSe0HoCXXRchFNQ6iqgfkq5Uvbvri7g1UNgmU

I have my automation for alert set it has to be in a range for a set time before trigger.
Also changing the report time helps

The internet is an amazing place. I’m new to home automation, and it took me ~100 random searches to find this page. You’re doing almost exactly what I’m after! Pellet level monitoring and the ability to control the pellet stove from temp data.

This will be my first actually DIY project. My question: it appears that my pellet stove needs “millivolt” support from thermostats. Whereas a lot of other equipment uses 24v. Does the D1 relay you are using support that? I have a Harman p35i, which has a room temp sensor, but I believe also dry contacts for hooking up a thermostat. So… would the D1 relay be what I need for simple “on/off”?

How does it survive dust?

All ideas I had to monitor pellet in stove none survived problem of dust. I guess that ultrasound sensor would eventually suffer from dust too.

The relay is a dry contact {no power} open and closed like a mechanical thermostat it just opens and closes the loop to the thermostat circuit.
Open tells the control board do not call for heat.
Closed tells control board call for heat
The same as a gas valve. closed pulls the magnet open for gas to flow
Open the magnet closes and gas does not flow.

So far since March 2021, 6 tons of pellets no issues with dust.
Only issue is with vibration\pellet movement when feeding and or a non flat surface causes false readings but in my automation I make up.

Great! I will surely give it a try.

Can you share your automation that solves for the vibration? I just finished reflashing a Tuya pellet stove and there are unused inputs on that chip that this would be perfect for. I also happen to have that ultrasonic sensor in my parts collection.

Basically i have a condition that says it has to hold at between my set low level before it triggers my alert.
Sorry I’m a Little slammed right now with hearth appliances.

Hi guys,
I created the same sensor using a d1 mini and a Ultrasonic module HC-SR04.
I set the update time to 2s and I have some problems with heat and vibrations, I think, cause when the pellet level is above 50cm I have some trouble with the sensor.
In this case, the correct value is between 0.35 and 0.37 meters, but most of the time the sensor is freaking out.
In my automation I have set a minimum time of 4 minutes before triggering the notification, but it happens that the sensor stays with the wrong measurement for more than that.

I also tried to change the update interval to 1s, 5s, 10s and more but with no success.
Any suggestions?