Output template write_action lambda for a speed fan set by interlocked relays

I’m hacking together this old fan to be esphome controlled but I’m stuck at the lambda actions for the output component that sets the fan speed. I can’t seem to map the output template to the correct relay states. And Im hoping some of you lambda wizards can point me in the right direction.

The fan speed is set by activating one of 3 interlocked relays. When the fan is off then all the relays need to turn off. Right now the relays are not switching correctly when I change the fan speed or oscillation.

Any thoughts on how to fix this?

This is the relevent YAML lines for the fan:

switch:
  - platform: gpio
    name: "Oscillate"
    pin: 23
    restore_mode: ALWAYS_OFF
    inverted: true
    id: oscillation_switch         
    internal: false
  - platform: gpio
    name: "Fan Speed 1"
    pin: 25
    restore_mode: ALWAYS_OFF
    inverted: true
    interlock: &interlock_group [fan_speed_1, fan_speed_2, fan_speed_3,]
    interlock_wait_time: 1s
    id: fan_speed_1         
    internal: false   
  - platform: gpio
    name: "Fan Speed 2"
    pin: 26
    restore_mode: ALWAYS_OFF
    inverted: true
    interlock: *interlock_group
    interlock_wait_time: 1s
    id: fan_speed_2         
    internal: false   
  - platform: gpio
    name: "Fan Speed 3"
    pin: 27
    restore_mode: ALWAYS_OFF
    inverted: true
    interlock: *interlock_group
    interlock_wait_time: 1s
    id: fan_speed_3         
    internal: false   

fan:
  - platform: speed
    output: fan_speed_output
    oscillation_output: oscillation_output
    speed_count: 3
    name: "Tower Fan"
    id: tower_fan

output:
  - platform: template
    type: binary    
    id: oscillation_output
    write_action:
      - if:
         condition:
           lambda: return (state = 1);
         then:
           - switch.turn_on: oscillation_switch
      - if:
          condition: 
            lambda: return (state = 0);
          then:
            - switch.turn_off: oscillation_switch  
  - platform: template
    type: float
    id: fan_speed_output   
    write_action:
      - if: 
          condition: 
            lambda: return (state = 0.33);
          then:
            - switch.turn_on: fan_speed_1
      - if:
          condition:
            lambda: return (state = 0.66);
          then: 
            - switch.turn_on: fan_speed_2
      - if:
          condition:
            lambda: return (state = 1);
          then:
            - switch.turn_on: fan_speed_3
      - if:
          condition:
            lambda: return (state = 0);
          then:
            - switch.turn_off: fan_speed_1
            - switch.turn_off: fan_speed_2
            - switch.turn_off: fan_speed_3 
           
1 Like

Bump. I am still stuck on this. It will work if replace the esphome Speed Fan with a template fan in home assistant. I want the fan control on the device and not to depend on Home assistant.

@floatev any luck ?

I Haven’t looked at this in a few months. It’s about to get hot so now’s the time to have another look at this. I’ll test it out and report back here soon.

Not sure if that’s the problem but I’ve noticed you’re using the assign operator = instead of the comparing operator == on your lambda.
state = 1 will always return true, and set the state to 1 while state == 1 will set no state and return true if the state is 1.

Thanks @duhanebe I updated the operator and it’s working.