Esp32 WROOM thermostat with fan control

Hi all,

i am struggeling with getting my code to work.
What i want is to build a thermostat. Depending on the state of desired temperature and real temperature the state should go to heat or cool. If the state is e.g. heat or cool a relay for the valve should triggerd and depending on the temperature difference a fan should turn on (relay 1-3).

Whatever i do the fan always is in high mode ( relay 3). anyone can give me some pointers so i can understand what i am doing wrong and how i can correct it?
please bare in mind i’m not an expert. ’
Thanks in advance.
FritsOv

type or paste code here
sensor:
# DHT22- AM2302 sensor  
  - platform: dht
    pin: $dht_data
    update_interval: 30s
    temperature: 
        name: "Thermostaat_test_2p" 
        id: dht_temperature
        accuracy_decimals: 1
        filters:
          - offset: $offset 
    humidity: 
        name: "humidity"
        accuracy_decimals: 1 
        id: dht_humidity

switch:
# relay 1 fanlevel low 
  - platform: gpio
    pin: $fan_low_relay_pin
    name: "Fan low"
    id: relay_1
    interlock: &interlock_group [relay_1, relay_2, relay_3]
    interlock_wait_time: $interlock_time
    internal: true

# relay 2 fanlevel mid   
  - platform: gpio
    pin: $fan_mid_relay_pin
    name: "Fan mid"
    id: relay_2
    interlock: *interlock_group
    interlock_wait_time: $interlock_time
    internal: true

# relay 3 fanlevel high    
  - platform: gpio
    pin: $fan_high_relay_pin
    name: "Fan high"
    id: relay_3
    interlock: *interlock_group
    interlock_wait_time: $interlock_time
    internal: true

# relay 4  valve    
  - platform: gpio
    pin: $valve_pin
    name: "valve"
    id: valve
    icon: "mdi:valve"
    internal: true

# heatmode      
  - platform: gpio
    pin: $heat_pin
    name: "heating"
    id: heater
    icon: "mdi:heating-coil"
    interlock: &interlock_2 [heater, cooler]
    interlock_wait_time: $interlock_time
    internal: true

# coolmode   
  - platform: gpio
    pin: $cool_pin
    name: "cooling"
    id: cooler
    icon: "mdi:snowflake"
    interlock: *interlock_2
    interlock_wait_time: $interlock_time
    internal: true

# setting up fan with output to corresponding fanspeed
fan:
  - platform: speed
    id: ventilate
    output: custom_fan
    name: "Fan"
    speed_count: 3
    
output:
  - platform: template
    id: custom_fan
    type: float 
    write_action:
      - if:
          condition:
            lambda: return ((state ==0));
          then:
            #action for off
            - logger.log: "turn all relays to off!"
            - switch.turn_off: relay_1
            - switch.turn_off: relay_2
            - switch.turn_off: relay_3
      - if:
          condition:
 #            lambda: return (( id(dht_temperature).state  > .16) && (id(dht_temperature).state < .34));  
             lambda: return (( state > .16) && (state < .34));
          then:
            # action for low
            - logger.log: "Fan Turned to low speed!"
            - switch.turn_on: relay_1
      - if:
          condition:
#             lambda: return (( id(dht_temperature).state  > .35) && (id(dht_temperature).state < .7));
             lambda: return ((state > .35) && (state < .7));
          then:
           # action for medium
            - logger.log: "Fan Turned to medium speed!"
            - switch.turn_on: relay_2
            - switch.turn_on: valve            
      - if:
          condition:
#             lambda: return (( id(dht_temperature).state  == 1));
             lambda: return ((state ==1));
          then:
            # action for high
            - logger.log: "Fan Turned to high speed!"
            - switch.turn_on: relay_3

# setting up climate conrol
climate:
  - platform: thermostat
    name: $name_thermostat
    id: this_thermostat
    visual:
      min_temperature: 15
      max_temperature: 40
      temperature_step: 0.1 °C                ### step temperature up and down 
    sensor: dht_temperature

# defaults and on boot     
    default_preset: Home                      
    on_boot_restore_from: memory              
    # on_boot_restore_from: default_preset    

# set minimum time for cooling, heating and idle   
    min_cooling_off_time: $off_time
    min_cooling_run_time: $run_time
    min_heating_off_time: $off_time            
    min_heating_run_time: $run_time             
    min_idle_time: 5s

# set fan minimum time     
    min_fanning_run_time: $run_time
    min_fanning_off_time: $off_time
    min_fan_mode_switching_time: $fan_switch_time

# predefined settings wirth min and max temperature
    preset:
      - name: Home
        default_target_temperature_low: 19.0  
        default_target_temperature_high: 22.0    
      - name: Away
        default_target_temperature_low: 15.0  
        default_target_temperature_high: 18.0    
      - name: Sleep        
        default_target_temperature_low: 18.0  
        default_target_temperature_high: 19.0  

# deadbangs
    cool_deadband: 0.2 °C
    cool_overrun: 0.3 °C
    heat_deadband: 0.3 °C
    heat_overrun: 0.5 °C

# actions to take when stat sets to cool, heat 
    cool_action:
      - switch.turn_on: cooler
      - switch.turn_on: valve
      - fan.turn_on: ventilate

    heat_action:
      - switch.turn_on: heater
      - switch.turn_on: valve
      - fan.turn_on: ventilate

    idle_action:
      - switch.turn_off: heater
      - switch.turn_off: cooler
      - switch.turn_off: valve
      - fan.turn_off: ventilate 

    fan_mode_on_action:
      - fan.turn_on: ventilate
      
    fan_only_action:
      - switch.turn_off: heater
      - switch.turn_off: cooler
      - switch.turn_off: valve
      - fan.turn_on: ventilate
     
    fan_mode_low_action:
      lambda: !lambda |-
        auto call = id(ventilate).turn_on();
        call.set_speed(1);
        call.perform();
     
    fan_mode_medium_action:
     lambda: !lambda |-
        auto call = id(ventilate).turn_on();
        call.set_speed(2);
        call.perform();
     
    fan_mode_high_action:
     lambda: !lambda |-
       auto call = id(ventilate).turn_on();
       call.set_speed(3);
       call.perform();
     
    fan_mode_off_action:
     - fan.turn_off: ventilate

What happens if you set internal: false for all relays then trigger any of them from HA?

Do they work as expected and set the fan speed?

In short, No.

if i dont use internal i can set all of the relay’s manual to on or off. But running the code there is no difference if i put them internal of not. The fan speed is always on max.
If i remove speed: 3 then the fan does not turn on and is should.
Cant figure out what i am doing wrong or why the state isn’t picked up.
with speed: 3 and an idle state it turns off all the coded relay’s as it should do, therefore it does the routine in output: where state !=0 turns off all the relay’s.

I’ve never seen ‘state’ called like that before in shorthand. Normally you need to refer to it like in your commented out section, id(dht_temperature).state ?

Does the logger logs work as expected in that section?

Hi Mahko,

Your right but calling the lambda with id did not work.
according the esp manual find it here
this should work. The only difference is that in the example a turn_on statement is:

  • output.turn_on: button_off
    but that cant work because the relay is a gpio and has no inherrit from binary::
    at least that is the message.

Error.log

i cant find where this error is written. Loglevel is set to DEBUG but i cant find the messages.

stuck for now… till someone can give me some pointers or help.