*Esphome stand alone 120 volt AC blower or fan speed controller

ESPHome Standalone 120 Volt AC Blower/Fan Speed Controller Control the speed manually with a button or set it to adjust automatically based on temperature ranges. Works seamlessly with or without Home Assistant automation or a constant network connection.

Objective

Develop a Smart Wood Pellet Stove System

Goal

Override the manufacturer’s control board to independently manage the convection blower. The current control board sets the blower speed based on the heat rate setting, but the convection blower always stays at a lower fan speed because, in my case, the stove is usually set to heat levels 2 or 3 out of 5. By synchronizing the stove’s operation with the thermostat schedule, we can maintain a consistent temperature throughout our home. I already setup a smart relay and ultrasonic sensor for pellet level in the hopper.
Here:
Smart pellet stove using shedy Python based schedule and ultrasonic sensor.

Plan

Enhance control over the convection blower of the pellet stove, ensuring it adjusts speeds according to the stove’s temperature and turns off when it cools down.

Implementation

To achieve this, I removed the power connection from the stove’s control board to the convection blower and used ESPHOME to program an ESP32. Here are the components and their details:

Components:

Setup

The ESP32, in conjunction with the AC dimmer module and temperature sensor, allows for precise control of the convection blower’s speed in relation to the stove’s temperature. This ensures it adjusts accordingly and turns off when the stove cools down, helping maintain a comfortable and consistent temperature in our home.

I achieved this by connecting the 120V from the stove’s power to an AC dimmer module controlled by the ESP32 using ESPHOME for programming. A DS18B20 digital sensor is attached to the back panel of the convection chamber to monitor temperature accurately. This setup ensures that the convection blower operates efficiently, enhancing the overall performance of the pellet stove and maintaining the desired temperature.

My cleaned up Full ESPHOME Yaml
or my github repository with updates.
currently working on my Pellet stove convection fan. No button just automatically controlling fan function with Temperature .
updated 12/30/2024

esphome:
  name: pellet-controller-fan
  friendly_name: Pellet Controller Fan

esp32:
  board: esp32dev # Hiletgo esp32-DevKitc-32   esp-32d esp-32 cp2012 usbc board
  framework:
    type: arduino

api:

ota:
  platform: esphome

logger:

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  power_save_mode: none
  manual_ip:
    static_ip: 192.168.2.21
    gateway: 192.168.2.1
    subnet: 255.255.255.0

web_server:
  version: 3
  port: 80

captive_portal:

output:
  - platform: ac_dimmer
    id: pellet_fan_dimmer
    gate_pin: GPIO16
    zero_cross_pin:
      number: GPIO19
    method: LEADING
    min_power: 42%  # Minimum power level set to 42%

one_wire:
  - platform: gpio
    pin: GPIO4

sensor:
  - platform: dallas_temp # DS18b20 3 pin wire digital thermometer
    address: 0xc00000004421a328
    id: dallastemp3
    name: "stove fan temperature"
    icon: "mdi:thermometer"
    device_class: "temperature"
    unit_of_measurement: "°C"
    accuracy_decimals: 2
    update_interval: 60s  # Updated interval to 60 seconds

  - platform: template
    name: "Fan Speed"
    id: fan_speed
    unit_of_measurement: "%"
    accuracy_decimals: 0

text_sensor:
  - platform: template
    name: "Fan Speed Level"
    id: fan_speed_level

  - platform: template
    name: "Fan Status"
    id: fan_status

select:
  - platform: template
    name: "Fan Speed Level"
    id: fan_speed_select
    options:
      - "Off"
      - "Low"
      - "Medium-Low"
      - "Medium"
      - "Medium-High"
      - "High"
    optimistic: true
    initial_option: "Off"
    set_action:
      - lambda: |-
          if (x == "Off") {
            id(pellet_fan_dimmer).set_level(0.0);
            id(fan_status).publish_state("Off");
            id(fan_speed).publish_state(0);
            id(fan_speed_level).publish_state("Off");

          } else if (x == "Low") {
            id(pellet_fan_dimmer).set_level(0.35);  // Updated speed level 1 to 0.35
            id(fan_status).publish_state("On");
            id(fan_speed).publish_state(35);  // Adjusted percentage to match the level
            id(fan_speed_level).publish_state("Low");

          } else if (x == "Medium-Low") {
            id(pellet_fan_dimmer).set_level(0.4);
            id(fan_status).publish_state("On");
            id(fan_speed).publish_state(40);
            id(fan_speed_level).publish_state("Medium-Low");

          } else if (x == "Medium") {
            id(pellet_fan_dimmer).set_level(0.5);  // Updated speed level 3 to 0.5
            id(fan_status).publish_state("On");
            id(fan_speed).publish_state(50);  // Adjusted percentage to match the level
            id(fan_speed_level).publish_state("Medium");

          } else if (x == "Medium-High") {
            id(pellet_fan_dimmer).set_level(0.7);  // Updated speed level 4 to 0.7
            id(fan_status).publish_state("On");
            id(fan_speed).publish_state(70);  // Adjusted percentage to match the level
            id(fan_speed_level).publish_state("Medium-High");
            
          } else if (x == "High") {
            id(pellet_fan_dimmer).set_level(1.0);
            id(fan_status).publish_state("On");
            id(fan_speed).publish_state(100);
            id(fan_speed_level).publish_state("High");
          }

# Temperature ranges and Fan on or off controlled with Lambda below 
# Adjust fan speed with set_level(0.35) = 35% to fine-tune fan speed percentage at each 1 to 5 step. Level 1 would be 35%

# Match the fan speed set action for set level and published % state in the above lambda "Low", "Medium-Low" etc. to the settings below

interval:
  - interval: 31s
    then:
      - lambda: |-
          float temp = id(dallastemp3).state;  
          if (temp < 31.5) { // Off state for when stove is cooling down shut off at 31.5 
            id(pellet_fan_dimmer).set_level(0.0);  
            id(fan_status).publish_state("Off");
            id(fan_speed).publish_state(0);
            id(fan_speed_level).publish_state("Off");

            // When STOVE is starting up and running, fan will turn on and run on low (35%) at above 33 then increase speeds with temperature ranges
          } else if (temp >= 33 && temp <= 36)  {
            id(pellet_fan_dimmer).set_level(0.35);  // Updated speed level 1 to 0.35
            id(fan_status).publish_state("On");
            id(fan_speed).publish_state(35);  // Adjusted percentage to match the level
            id(fan_speed_level).publish_state("Low");

          } else if (temp > 36 && temp <= 45) {
            id(pellet_fan_dimmer).set_level(0.4);
            id(fan_status).publish_state("On");
            id(fan_speed).publish_state(40);
            id(fan_speed_level).publish_state("Medium-Low");

          } else if (temp > 45 && temp <= 50) {
            id(pellet_fan_dimmer).set_level(0.5);  // Updated speed level 3 to 0.5
            id(fan_status).publish_state("On");
            id(fan_speed).publish_state(50);  // Adjusted percentage to match the level
            id(fan_speed_level).publish_state("Medium");

          } else if (temp > 50 && temp <= 60) {
            id(pellet_fan_dimmer).set_level(0.7);  // Updated speed level 4 to 0.7
            id(fan_status).publish_state("On");
            id(fan_speed).publish_state(70);  // Adjusted percentage to match the level
            id(fan_speed_level).publish_state("Medium-High");
            
          } else if (temp > 60) {
            id(pellet_fan_dimmer).set_level(1.0);
            id(fan_status).publish_state("On");
            id(fan_speed).publish_state(100);
            id(fan_speed_level).publish_state("High");
          }

  - interval: 8h  # Run this every 8 hours
    then:
      - if:
          condition:
            binary_sensor.is_on: fan_off_10_min
          then:
            - logger.log: "Fan has been off for 10 minutes. Rebooting device."
            - delay: 5s  # Short delay before rebooting
            - switch.turn_on: restart_switch

# Create a binary sensor to track if the fan has been off for at least 10 minutes
binary_sensor:
  - platform: template
    name: "Fan Off for 10 Minutes"
    id: fan_off_10_min
    lambda: |-
      return id(fan_status).state == "Off";
    filters:
      - delayed_on: 600s  # 10 minutes

# Switch to trigger a reboot
switch:
  - platform: restart
    name: "Restart Switch"
    id: restart_switch

Test blower and breadboard, blower or controller not the one use in pellet stove.
Video of working module

I’m using an ESP32 with an AC dimmer to control a pellet stove’s room air blower speed, adjusting it based on different temperature ranges.


Esp web portal page.

Home assistant History of Room temp, Stove temp and fan actions.

Home assistant dashboard

Fahrenheit Sensor Entity for use in Home Assistant
Sensor template in home assistant template.yaml to convert C° to F °

- sensors:
    stove_temp_in_c:
      friendly_name: "stove temp in C°"
      unique_id: stovetemp11111
      value_template: '{{ "%.2f"|format((( states("sensor.pellet_controller_fan_stove_fan_temperature") | float ) -32) *5/9) }}'

Playing with ESPHome Methods

To achieve my goal, I experimented with various ESPHome methods at my desk. I set up an ESP32 on a breadboard with a contact button, a temperature sensor, an AC dimmer module, and connected it to a blower motor for prototyping. On my test board, I experimented with temperature percentage steps using the on_value_range: method. Additionally, I tested the fan.cycle_speed action with a button to control fan speeds. Each button press cycles through the following states: off, on, 1, 2, 3, 4, and 5.

I used Copilot in GitHub to help polish the ESPHome YAML and guide me on the different methods to control fan speeds with temperature.

Button Configuration: yaml

- platform: gpio
  pin:
    number: GPIO15
    mode:
      input: true
      pullup: true
    inverted: true
    id: fanbutton
  name: fan button
  filters:
    - delayed_off: 20ms
  on_press:
    - fan.cycle_speed: fan_speeds

This setup allows effective control of the fan speed through button presses.

My Background
I am no expert just learning and having fun.
I have been an avid user of smart home electronics, currently managing over 200 local, off-the-cloud smart devices in our home. I started off using eWeLink with IFTTT, then branched out to Home Assistant and began converting Sonoff and other devices with Tasmota in 2016. This has allowed me to automate various aspects of my home, including heating and evaporative cooling systems. My journey into the world of home automation took a significant leap with the help of creators like Digiblur DIY, Dr. ZZZs, and many other helpful people on Discord when I started experimenting with Home Assistant in 2016. The experience has been both rewarding and educational.

Some of my projects involve playing with WLED and ESPHome, which have been incredibly fun. Additionally, I’ve successfully created an automatic fish feeder, hacked lamps, and made my pellet stove smart, showcasing my penchant for blending technology with creativity.

With over 35 years of experience in installing and servicing hearth products, I specialize in gas and wood pellet-burning stoves. This extensive background has honed my skills and expertise in the industry, allowing me to provide top-notch service to my clients.

Home automation has become a much-needed hobby, offering a perfect blend of technical challenges and innovative solutions. I continue to explore new ways to enhance my living environment through automation.

Feel free to check out my Facebook page: DIY Redneck - The Stove Doc.
my Facebook page diyredneck.thestovedoc.com
and my stovedoc page

1 Like

12/31/224
Cleaned up Yaml to much more friendly automatic Fan Via Temperature setting functions.

Hi Rod,

I plan to replace the original mb of my pellet stove with an esp32. I think that working on the fan regulation first is a good idea. What do you think about using the original smoke temperature sensor (NTC 10k) ? I suppose I can use an ADC to read the temperature? But I would need a more advanced board with 2 ADC inputs and 2 pwm output or the next steps (Ambient + smoke temp, ambient and exhaust fans)

There are many brands and models of pellet stoves.
some newer stoves have K type and other temperature probes but MOST do not they just control blowers and shut down with a few fan limit switches.
so without knowledge of the stove you have I would not be able to give input.

Actually my stove has 2 NTC 10K probes (one for room temperature and one for smokes). The ambiant blower speed is regulated with constants but the TRIAC of my mb has gone so it’s working at full speed all the time. I find the idea to modulate the blower speed according the the stove temperature very good.

What brand and model?
Just for reference
Well the parts for what I did did not cost that much
I put the dallas sensor just sitting on the back of the convection housing and seems to work fine
But…
The one wire protocol seems to interfere with voltage to other pins every time it updates readings.
I may get a k type board and probe and try.
Something like this but with a probe to match max heat
Esphome MAX6675 K-Type Thermocouple Temperature Sensor¶

This one whole kit for $8 is max temp of 85C there are other thermocouple that are higher temp if you need
HiLetgo DC 3-5V MAX6675 Module + K Type Thermocouple Temperature Sensor

So far I’m very happy with how the fan adjusted to stove temp.
I had one clutch s few days ago where it was not updating or the board was being weird and kept cycling
After I power cycled it no problems since.
So I added the reboot every 8 hours if blower has been off for 10 minutes automation in code .

NTC is not K-type. We can calculate the NTC resistance using ADC, this is supported by esphome. However the sensor is already wired to the mainboard so I believe it’s not possible to read the values from an esp32 at the same time. Could be possible if ground was shared between the esp32 and the mainboard but they have distinct ac power supply.

The Stove is from CS Thermos, Italy (Fenice model)

I was just saying if you wanted to make a separate controller like I did
I dont have time to start digging into hacking my stoves board YET