Controling a PWM fan depending on temperature

Hello,
I’ve tried without success. Sorry.
With Home Assistant 2025.8.3 and ESPHome Builder on a Raspberry pi 5 (Pi OS 6.12.34), I want to control a PWM fan depending of local temperature. The DHT11 and PWM fan are well integrated in HA but when I want to manage the fan with ESPHome, i can’t activite the fan automaticaly. I tried with “on_value_range” command on sensor or automation/trigger and code, no success.
For range on sensor (for me the most simple), here is my code (I replaced Output Fan by a relay on GPIO for tests)

# Example configuration entry
switch:
  - platform: gpio
    pin: GPIO15
    id: Relay1
    name: "Relais 1"
  - platform: gpio
    pin: GPIO13
    id: Relay2
    name: "Relais 2"
  - platform: gpio
    pin: GPIO12
    id: Relay3
    name: "Relais 3"

sensor:
  - platform: dht
    pin: GPIO4
    model: DHT11
    temperature:
      name: "Temperature"
      id: temp_sensor
      on_value_range:
        - above: 25.0
          then:
            - switch.turn_on: Relay1
        - below: 25.0
          then:
            - switch.turn_off: Relay1
    update_interval: 3s`.  

And for the automation/trigger, my code too:

automation:
  - trigger:
    - platform: state
        entity_id: sensor.temperature
        # Déclencher seulement si la température change de plus de 0.5°C
        not:
          - delta: 0.5
    then:
      - lambda: |-
          float temp = id(temp_sensor).state;
          float temp_min = 20.0;
          float temp_max = 45.0;

          float normalized_temp = (temp - temp_min) / (temp_max - temp_min);
          normalized_temp = min(max(normalized_temp, 0.0), 1.0);

          float speed_percent = pow(normalized_temp, 1.5) * 100.0;

          if (speed_percent > 5.0) {
            id(pwm_fan).turn_on().set_speed(speed_percent / 100.0);
          } else {
            id(pwm_fan).turn_off();
          }
What is going wrong ?
I you have a idea, it should be great.
Thanks in advance.

Be aware that that triggers only if the range changes. If initial state is x it’s not triggering anything before it breaks the 25’c threshold.

Many thanks @Karosm.
I have followed your recommendations; and it’s fine. I have tested with a hair dryer to modify temperature on my sensor (DHT); I can manage my fan from Off to 100%.
My code (without WiFi chapter):

# Source: https://esphome.io/components/switch/gpio/
# Source: https://community.home-assistant.io/t/controlling-noctua-pwm-fan-with-esp8266/562457/7
# Source: https://newscrewdriver.com/2022/07/27/tmp36-temperature-sensor-esp8266-not-a-great-team/
# Source: https://community.home-assistant.io/t/controling-a-pwm-fan-depending-on-temperature/937684
esphome:
  name: "rack"
  friendly_name: Rack
  on_boot:
    - priority: 600
      then:
        - fan.turn_on:
            id: fan_toggle
            speed: 25
        - switch.turn_on: Relay1
        - switch.turn_off: Relay2
        - switch.turn_off: Relay3

esp8266:
  board: esp01_1m

here logger, api and WiFi

# Switch for relays
switch:
  - platform: gpio
    pin: GPIO15
    id: Relay1
    name: "Relais 1"
  - platform: gpio
    pin: GPIO13
    id: Relay2
    name: "Relais 2"
  - platform: gpio
    pin: GPIO12
    id: Relay3
    name: "Relais 3"

# Temperature Sensor DHT (nb: a TMP36 don't work, it return only a value, not a temperature or humidity)
sensor:
  - platform: dht
    pin: GPIO4
    model: DHT11
    temperature:
      name: "Temperature"
      id: temp_sensor
      on_value_range:
        - below: 22.0
          then:
          - fan.turn_off: 
              id: fan_toggle
        - above: 22.0
          below: 25.0
          then:
          - fan.turn_on: 
              id: fan_toggle
              speed: 25
        - above: 25.0
          below: 28.0
          then:
          - fan.turn_on: 
              id: fan_toggle
              speed: 50
        - above: 28.0
          below: 31.0
          then:
          - fan.turn_on: 
              id: fan_toggle
              speed: 75
        - above: 31.0
          then:
          - fan.turn_on: 
              id: fan_toggle
              speed: 100
    update_interval: 10s

  # to display fan RPM
  - platform: pulse_counter
    pin:
      number: GPIO14
      mode:
        input: true
        pullup: true
    name: Fan Speed
    id: fan_pulse
    unit_of_measurement: 'RPM'
    filters:
      - multiply: 0.27
    count_mode:
      rising_edge: INCREMENT
      falling_edge: DISABLE
    update_interval: 10s
    accuracy_decimals: 0

# the physical fan
output:                                                                                                                                                          
  - platform: esp8266_pwm
    id: fan_speed
    pin: GPIO16
    frequency: "10000 Hz"
    min_power: 13%
    max_power: 100%

# the interface fan
fan:
  - platform: speed
    output: fan_speed
    name: fan speed
    id: fan_toggle

One more time many thanks from France.

Why not use the climate component?