- iot
- knowlege-backup
- home improvement
- heating
- esphome
- home assistant
- electronics
- esp32
ESPHome Controlled Fireplace Blower
Our home had a gas fireplace in our living room when we moved in. Though the radiant heat from it felt good when winter came, there was no blower installed so a lot of the heat was wasted. After one winter of wasted heat, I purchased a blower designed for gas fireplaces. It gets inserted into the base of the unit and turns on based on the temperature. The fan pulls air from under the unit, which is exposed to the room, and blows it through a vent in the back of the unit which heats the air and ejects it through the vent at the top.
This worked great for years, but this winter I was being driven insane by the noise. The fan was loud enough to require cranking up the volume when watching TV. The only way to stop it was to unplug it and we would inevitably forget to plug it back in.
I considered a few options:
- Just use a smart plug and be able to control it if needed, with automatic on overnight.
- Buy a new, more expensive fan and hope it would be quieter
- Do it myself.
I like do it myself as an option, so I dug into the possibilities. I was sure I could use ESPHome to accomplish my goals and after some research I learned that yes, ESPHome could handle this problem. I listed these as my goals.
Goals
- [ x ] - Quiet operation
- [ x ] - Able to control the fan from Home Assistant
- [ x ] - Use standard components, so I can fix it if something fails
- [ x ] - Monitor Temperature from Home Assistant
- [ x ] - Original remote must still work(spousal approval)
Stretch Goals
I done some preliminary research on how to achieve these, but have yet to spend a ton of time working on them.
- [ ] - Control Fireplace burner state from Home Assistant
- [ ] - Determine Fireplace burner state in Home Assistant
- [ ] - Climate Control
Build Details
I ended up with the following components:
- Three 120mm PWM fans
- esp32
- DHT11 Temperature and Humidity Sensor
- 12v Buck Converter

The fans are wired in series, 12v from the DC transformer, PWM signals, and ground are all wired together.
The buck converter receives 12v from the transformer, drops the voltage and sends 5v to the dht11, and the vin pin on the esp32. Ground from both the dht11 and esp32 is wired to output ground on the buck converter, along with the ground from the fans.
PWM from the fans is wired to a PWM output pin on the esp32 and the DHT11 signal pin is wired into a GPIO.
Once I validated everything worked well, I soldered things together and stuck them into a plastic case. The fans were mounted to a 3d printed case that allows air to flow from underneath and push up through the vents. I also stuck a case around the DHT11 and attached it to the top of the lower compartment with a magnet, which improves temperature pickup.
Software Notes
The important bits of my esphome configuration file are at the bottom of this post.
My primary goal was to ensure this would continue to function even if Home Assistant or the network went down. Home Assistant’s only role is as a dashboard and allowing for setting thresholds remotely. The actual decisions to turn the fan on, speed, and turning it off is fully handled by the esp32 device.
I am extremely happy with the result. The fans are significantly quieter when running at lower speeds and if I bump their speed up a bit beyond silent they move a ton more air than the purpose build blower did.

# Allows setting thresholds within Home Assistant but storing them on the device.
number:
- platform: template
name: "$friendly_name Low Temp Threshold"
id: low_temp_threshold
optimistic: true
min_value: 50
max_value: 80
step: 1
initial_value: 70
unit_of_measurement: "°F"
mode: box
restore_value: true
- platform: template
name: "$friendly_name High Temp Threshold"
id: high_temp_threshold
optimistic: true
min_value: 80
max_value: 120
step: 1
initial_value: 98
unit_of_measurement: "°F"
mode: box
restore_value: true
- platform: template
name: "$friendly_name Max Fan Speed"
id: max_fan_speed
optimistic: true
min_value: 13
max_value: 100
step: 1
initial_value: 65
unit_of_measurement: "%"
mode: slider
restore_value: true
# the lamda here does most of the work. It triggers the fans on based on the temperature thresholds above and ramps up the fan
# as the temperature increases.
sensor:
- platform: dht
pin: GPIO21
model: DHT11
temperature:
id: "fireplace_temperature"
name: "$friendly_name Temperature"
accuracy_decimals: 1
filters:
- exponential_moving_average:
alpha: 0.1
send_every: 1
- lambda: return x * (9.0/5.0) + 32.0;
unit_of_measurement: "°F"
on_value:
then:
- lambda: |-
float temp = id(fireplace_temperature).state;
float low_temp = id(low_temp_threshold).state;
float high_temp = id(high_temp_threshold).state;
float max_speed = id(max_fan_speed).state;
bool manual_mode = id(manual_control).state;
if (temp <= low_temp) {
// Below low threshold - turn off
id(fireplace_fan).turn_off().perform();
} else if (manual_mode) {
// Manual mode is on - do nothing, let user control
return;
} else if (temp >= high_temp * 0.95) {
// At or above 95% of high temp - max speed
id(fireplace_fan).turn_on().set_speed(max_speed).perform();
} else {
// Between low and 95% of high - linear ramp
float temp_range = (high_temp * 0.95) - low_temp;
float temp_position = temp - low_temp;
float speed_percent = (temp_position / temp_range) * max_speed;
speed_percent = max(1.0f, min(max_speed, speed_percent));
id(fireplace_fan).turn_on().set_speed((int)speed_percent).perform();
}
# Some fun wiring up of output and fan to allow fan monitoring in home assistant
output:
- platform: ledc
pin: GPIO25
id: fireplace_fan_pwm
frequency: 25000 Hz # Above audible range
min_power: 13%
zero_means_zero: true
fan:
- platform: speed
output: fireplace_fan_pwm
id: fireplace_fan
name: "$friendly_name Fan"
speed_count: 100 # Gives you 0-100% control
# Allows full manual control of the fan.
switch:
- platform: template
name: "$friendly_name Manual Control"
id: manual_control
optimistic: true
restore_mode: RESTORE_DEFAULT_OFF
Note:
I ran into a really frustrating issue throughout this project where Home Assistant would stop communicating with the device. I could get data from the device to HA, but not consistently send updates. I managed to track it down and wrote a post mortem.