Speed Fan auto off

Hi!

I have a PWM fan controller, with an push-button to cycle through off - low - medium - high.

I have created a script with a 5h delay, that turns the fan off. It works great when using the push-button. But how can I make it work when I set the speed via Home Assistant?

# Pinning
# D1 - Button
# D2 - RPM meeter
# D3 - PWM pulse

substitutions:
  hostid: fireplace_fan
  hostname: Fireplace Fan
  comment: Fireplace fan controller
  node_platform: ESP8266
  node_board: d1_mini

packages:
  core: !include common/core.yaml
  basic_sensors: !include common/basic_sensors.yaml

sensor:
  - platform: pulse_counter
    pin: 
      number: D2
      mode: INPUT_PULLUP
    unit_of_measurement: 'RPM'
    accuracy_decimals: 0 
    id: ${hostid}_speed
    name: ${hostname} Speed
    filters:
      - multiply: 0.5

fan:
  - platform: speed
    id: ${hostid}_fan
    name: ${hostname}
    output: ${hostid}_fan_speed
    speed:
      low: 0.35
      medium: 0.6
      high: 1

output:
  - platform: esp8266_pwm
    pin: D3
    frequency: 25000 Hz
    id: ${hostid}_fan_speed

binary_sensor:
  - platform: gpio
    pin: 
      number: D1
      mode: INPUT_PULLUP
      inverted: True
    id: ${hostid}_button
    name: ${hostname} Button
    on_multi_click:
    - timing:
        - ON for at most 0.2s
        - OFF for at most 0.2s
        - ON for at most 0.2s
        - OFF for at least 0.2s
      then:
        - logger.log: "Double Clicked"
        - lambda: |-
            auto call = id(${hostid}_fan).make_call();
            if (!id(${hostid}_fan).state) {
              call.set_state(true);
              call.set_speed(FAN_SPEED_HIGH);
            } else if (id(${hostid}_fan).speed == FAN_SPEED_LOW) {
              call.set_state(false);
            } else if (id(${hostid}_fan).speed == FAN_SPEED_MEDIUM) {
              call.set_speed(FAN_SPEED_LOW);
            } else if (id(${hostid}_fan).speed == FAN_SPEED_HIGH) {
              call.set_speed(FAN_SPEED_MEDIUM);
            }
            call.perform();
        - script.execute: ${hostid}_auto_off
    - timing:
        - ON for at least 1s
      then:
        - logger.log: "Single Long Clicked"
        - lambda: |-
            auto call = id(${hostid}_fan).make_call();
            call.set_state(false);
            call.set_speed(FAN_SPEED_LOW);
            call.perform();
        - script.stop : ${hostid}_auto_off
    - timing:
        - ON for at most 0.4s
        - OFF for at least 0.4s
      then:
        - logger.log: "Single Short Clicked"
        - lambda: |-
            auto call = id(${hostid}_fan).make_call();
            if (!id(${hostid}_fan).state) {
              call.set_state(true);
              call.set_speed(FAN_SPEED_LOW);
            } else if (id(${hostid}_fan).speed == FAN_SPEED_LOW) {
              call.set_speed(FAN_SPEED_MEDIUM);
            } else if (id(${hostid}_fan).speed == FAN_SPEED_MEDIUM) {
              call.set_speed(FAN_SPEED_HIGH);
            } else if (id(${hostid}_fan).speed == FAN_SPEED_HIGH) {
              call.set_state(false);
            }
            call.perform();
        - script.execute: ${hostid}_auto_off

script:
  - id: ${hostid}_auto_off
    mode: restart
    then:
      - delay: 18000s # 5h
      - fan.turn_off: ${hostid}_fan

Is there a way to make an automation trigger on a fan-state-change?
Thanks!

Saddly the fan has no “turn_on” trigger. I think it should have (maybe open a feature request for that if it does not exist yet).

In the meantime you can use an interval automation Automations and Templates — ESPHome with for example 1 second. In the action you have a condition to check that the fan is off. In the the action you use while to wait until it is on. Then you execute your script. I think that you work. Good luck.