Automation option that checks if entity is not unavailable and repeats action

As you can see, there are several existing Feature Requests along the same lines requesting some form of “retry”. So far, none have been fulfilled.

Here’s what I currently suggest as a means of performing an action more than once, but no more than a certain number of times before conceding failure (to avoid trying indefinitely). The example uses a simple repeat - until to turn off a switch. It gives up after 5 attempts.

Here’s a slightly more sophisticated version that is more responsive than the linked example, because it uses a wait_for_trigger, instead of a fixed delay, for each iteration of the repeat. It tries to lock the door lock but no more than twice.

- repeat:
    sequence:
      - service: lock.lock
        target:
          entity_id: lock.door_lock
      - wait_for_trigger:
          - platform: state
            entity_id: lock.door_lock
            from: unlocked
            to: locked
        timeout: "00:00:04"
   until:
     - condition: template
       value_template: >-
         {{ is_state('lock.door_lock', 'locked') or
           repeat.index >= 2 }}

FWIW, I use this method for just one device in my home. Just like in the example, it’s a door lock and when its batteries are weak it takes more than one attempt to lock the door.

The lock isn’t able to report its battery level. However, when it takes more than one try to lock it, my version of the example also notifies me that the batteries may be weak because it took two attempts to lock the door.