Turn switch on when connection to Home Assistant is lost

Hello,

I use two ESPHome-controlled relays to control my heat pump. I would like to implement automatic fallback logic that turns the heating on if Home Assistant is offline for more than 30 minutes.

I accomplished something similar on a Shelly 2PM by sending a REST command from Home Assistant to the Shelly every minute to reset a timer on the device. If the reset command is missed for more than a certain number of minutes, the device performs a specific action (in this case, retracting an awning).

How can I accomplish something similar with ESPHome?

Thank you!

Maybe just call an ESPHome action from HA?

I’m sure there are many ways to do that, which one is best, I don’t know.
One way could be status binary sensor with timer script.
Something like:

binary_sensor:
  - platform: status
    id: ha_connected
    on_release: # when HA disconnects
      then:
        - script.execute: fallback_timer
    on_press: #when HA reconnects
      then:
        - script.stop: fallback_timer
1 Like

I use a number of sensors in my heating controller that fallback to a local sensors or a fixed value if the ESP module loses connection to HA.

  - platform: template # Sets Heat schedule to ON if Homeassistant not available and connected
    name: "${friendly_name} CH Schedule"
    id: heat_schedule
    lambda: |-
      if (id(connected).state) {
        return id(ha_heat_schedule).state;
      } else {
        return "on";
      }

Hopefully you cn see how this works.

Another approach might use the api.connected condition which checks if at least one client is connected to the ESPHome native API.

Possibly check api.connected in an api.on_client_disconnected trigger, and if it was the last connection start a timer. api.on_client_connected trigger can reset the timer since there must now be some connection.

Thank you to all of you for pointing me in the right direction!

I went with @Karosm suggestion because it seemed easier to implement a delay. This is my solution with the help of Grok:

globals:
  - id: saved_heating_state
    type: bool
    initial_value: 'false'
  - id: fallback_active
    type: bool
    initial_value: 'false'

binary_sensor:
  - platform: status
    id: ha_connected
    on_release:  # HA disconnected → start fallback
      then:
        - script.execute: fallback_timer
    on_press:     # HA reconnected → stop and restore
      then:
        - script.stop: fallback_timer
        - script.execute: restore_heating_state

script:
  - id: fallback_timer
    mode: single
    then:
      - delay: 240min
      - logger.log:
          level: WARN
          format: "HA offline for 240min - activating fallback heating"
      - globals.set:
          id: saved_heating_state
          value: !lambda "return id(heizanforderung).state;"
      - logger.log:
          level: WARN
          format: "Previous state of heating request saved: %s"
          args: [ "id(heizanforderung).state ? \"ON\" : \"OFF\"" ]
      - globals.set:
          id: fallback_active
          value: 'true'
      - switch.turn_on: heizanforderung
      - logger.log:
          level: WARN
          format: "Heating request turned ON because Home Assistant is offline"

  - id: restore_heating_state
    mode: queued
    then:
      - if:
          condition:
            lambda: 'return id(fallback_active);'
          then:
            - logger.log:
                level: WARN
                format: "HA back online - restoring previous heating request state"
            - if:
                condition:
                  lambda: 'return id(saved_heating_state);'
                then:
                  - switch.turn_on: heizanforderung
                  - logger.log:
                      level: WARN
                      format: "Heating request restored: ON"
                else:
                  - switch.turn_off: heizanforderung
                  - logger.log:
                      level: WARN
                      format: "Heating request restored: OFF"
            - globals.set:
                id: fallback_active
                value: 'false'
          else:
            - logger.log:
                level: WARN
                format: "HA came back online before timeout - no fallback heating activated."