Set switch state based on climate mode at boot time

Hi, Could I get a pointer with this please?

I have a heating controller which has a number of modes, one of the modes is where the heating is controlled by the thermostat integration in ESPHome. The thermostat state (HEAT, OFF, etc) is retained during a reboot, so I need to detect that state using a lambda and then set a template switch exposed to HA to indicate that the thermostat is in control of the heating. So if the thermostat is set to HEAT mode then the switch needs to be on; if the thermostat is set to OFF mode then the switch needs to be off. Make sense?

I have tried to automate this at boot by doing the following:

esphome:
  name: relayboard1
  on_boot:
    priority: -100
    then:
      # read the RTC time once when the system boots
      - ds1307.read_time:
      - if:    # Check if we are still in AUTO mode and then set the switch back into the correct state
          condition:
            lambda: 'return id(thermostat_ds).mode == CLIMATE_MODE_HEAT;'
          then:
            - switch.turn_on: brb_ds_auto_mode_toggle
            - logger.log: "break IS CLIMATE_MODE_HEAT - DS"
          else: 
            - logger.log: "break Checkpoint - DS"

  - platform: template # Switch exposed to HA
    # AUTO mode DOWNSTAIRS
    name: "AUTO mode - Downstairs"
    id: "brb_ds_auto_mode_toggle"
    optimistic: true
    turn_on_action:
      then:
        - script.execute: auto_mode_on_ds
    turn_off_action: 
      then:
        - script.execute: auto_mode_off_ds

  - platform: thermostat
    id: thermostat_ds
    name: "Thermostat Downstairs"
    sensor: downstairs_room_temps_average
    preset:
      - name: Normal
        default_target_temperature_low: 21 °C
      - name: Low
        default_target_temperature_low: 18 °C
    visual:
      min_temperature: 16.0 °C
      max_temperature: 24.0 °C
      temperature_step: 0.5 °C
    min_heating_off_time: 300s
    min_heating_run_time: 300s
    heat_overrun: 0.5 °C
    heat_deadband: 0.2 °C
    heat_action:
      - switch.turn_on: brb_ds_direct
    min_idle_time: 0s
    idle_action:
      - switch.turn_off: brb_ds_direct
    off_mode:
      - switch.turn_off: brb_ds_direct
      - delay: 0.2s  # Clashes with going idle

The problem is that even through I have added in obvious log entries and set the priority to -100, I cannot see these logs appearing in the API log stream when the controller boots up and the switch states don’t appear to be getting evaluated. Maybe the last part is a problem with my lambda, but I can’t troubleshoot what I can’t see.

So my question is, is “lambda: ‘return id(thermostat_ds).mode == CLIMATE_MODE_HEAT;’” the best way to check the status of the thermostat at boot, or is there a better way?

Why not just to save template switch state by using restore_mode ?
And then it will change thermostat mode on toggling.

Hi and thanks for your feedback.
I was looking at that option earlier in the day but discounted it because " RESTORE_DEFAULT_ON" would “Attempt to restore state and default to ON”, but that’s not what I want to happen. But looking again, maybe “RESTORE_DEFAULT_OFF” would suffice for my needs. I’ll test it now.

It will set to OFF on first boot of device - when no state of switch previously saved.

Theroretically can imagine situation when f.e. switch state was saved, but then device powered off and thermostat state not saved.

Ok, it’s doing just like you said - it’s restoring the switch state and also running the scripts behind it after a reboot.

Setting the write period is crucial though.

preferences:
  flash_write_interval: 1min

I think I want to write as little as possible to this ESP, I’ll probably set that to once every 3 to 5 mins.

And that behaviour is fine. :+1:

Here’s the full code: