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.