Repeat Until with OR conditions

I am trying to create an automation that will keep firing until an RF controlled fan is off or on. I’ve tried this with both “states” and “is_state” in the conditions. But it seems like no matter what I do it only runs once and I could use some help. Thanks.

- alias: Samuel's Ceiling Fan Light
  trigger:
    - platform: state
      entity_id:
        - binary_sensor.samuel_ceiling_fan_light_input
      id: wall_switch
  action:
    - choose:
      - conditions:
          - condition: trigger
            id: wall_switch
        sequence:
          - repeat:
              until:
                condition: or
                conditions:
                  - condition: template
                    value_template: "{{ states('binary_sensor.samuel_ceiling_fan_light_input') == 'on' and states('binary_sensor.samuel_s_ceiling_fan_light_wattage') == 'on' }}"
                  - condition: template
                    value_template: "{{ states('binary_sensor.samuel_ceiling_fan_light_input') == 'off' and states('binary_sensor.samuel_s_ceiling_fan_light_wattage') == 'off' }}"
              sequence:
                - service: mqtt.publish
                  data:
                    topic: "home/OpenMQTTGateway/commands/MQTTto433"
                    payload_template: >-
                      {% if states('binary_sensor.samuel_ceiling_fan_light_input') == 'on' %}
                        {"value":16774171,"protocol":11,"length":24,"delay":385, "repeat": 10}
                      {% elif states('binary_sensor.samuel_ceiling_fan_light_input') == 'off' %}
                        {"value":16774172,"protocol":11,"length":24,"delay":385, "repeat": 5}
                      {% else %}
                        {"value":Samuel Light Switch ERROR}
                      {% endif %}
                - delay: 00:00:02
  mode: restart

Does the MQTT command change the state of the triggering binary sensor?
That would cancel and restart the automation since you are using restart mode will retrigger… which seems like it might create a loop.

You can simplify your until condition using tuple comparison:

until:
  condition: template
  value_template: >
    {{ ( states('binary_sensor.samuel_ceiling_fan_light_input'), 
    states('binary_sensor.samuel_s_ceiling_fan_light_wattage') ) 
    in [('on' ,'on'), ('off', 'off')] }}
sequence:

I just tried your code without success. The MQTT command is sending the RF signal to turn the light on or off. Which I don’t think is affecting the Until statement. Unfortunately, it is the same signal “16774171” for both. “16774172” is a dummy code which does trigger “16774171” elsewhere and I will include my full code at the bottom. This has been the challenge all along with this project. I want to double check the fan states based on the watt reading I am getting from the Shelly 2.5 I have attached to the fan switch.

THIS IS THE EXACT DUMBED DOWN CODE I JUST TRIED IN AN EFFORT TO ISOLATE

- alias: Samuel's Ceiling Fan Light
  trigger:
    - platform: state
      entity_id:
        - binary_sensor.samuel_ceiling_fan_light_input
     # state of wall switch on/off
      id: wall_switch
    - platform: state
      entity_id:
        - counter.samuel_fan_light
      id: light_state
  action:
    - choose:
      - conditions:
          - condition: trigger
            id: wall_switch
        sequence:
          - repeat:
              until:
                condition: template
                value_template: >
                  {{ ( states('binary_sensor.samuel_ceiling_fan_light_input'), states('binary_sensor.samuel_s_ceiling_fan_light_wattage') ) in [('on' ,'on'), ('off', 'off')] }}
# checking whether the wall switch is on/ff and the light is on based on watt reading
              sequence:
                - service: mqtt.publish
                  data:
                    topic: "home/OpenMQTTGateway/commands/MQTTto433"
                    payload_template: >-
                      {% if states('binary_sensor.samuel_ceiling_fan_light_input') == 'on' %}
#wall switch on
                        {"value":16774171,"protocol":11,"length":24,"delay":385, "repeat": 10}
                      {% elif states('binary_sensor.samuel_ceiling_fan_light_input') == 'off' %}
#wall switch off
                        {"value":16774172,"protocol":11,"length":24,"delay":385, "repeat": 5}
                      {% else %}
                        {"value":Samuel Light Switch ERROR}
                      {% endif %}
                - delay:
                    seconds: 4

FULL CODE

- alias: Samuel's Ceiling Fan Light
  trigger:
    - platform: state
      entity_id:
        - binary_sensor.samuel_ceiling_fan_light_input
      id: wall_switch
    - platform: mqtt
      topic: "home/OpenMQTTGateway/433toMQTT"
      value_template: '{{ value_json.value }}'
      payload: '16774171'
      id: remote
    - platform: mqtt
      topic: "home/OpenMQTTGateway/433toMQTT"
      value_template: '{{ value_json.value }}'
      payload: '16774172'
      id: app
    - platform: state
      entity_id:
        - counter.samuel_fan_light
      id: light_state
  action:
    - choose:
      - conditions:
          - condition: trigger
            id: wall_switch
        sequence:
          - repeat:
              until:
                condition: template
                value_template: >
                  {{ ( states('binary_sensor.samuel_ceiling_fan_light_input'), states('binary_sensor.samuel_s_ceiling_fan_light_wattage') ) in [('on' ,'on'), ('off', 'off')] }}
              sequence:
                topic: "home/OpenMQTTGateway/commands/MQTTto433"
                payload_template: >-
                  {% if states('binary_sensor.samuel_ceiling_fan_light_input') == 'on' and states('counter.samuel_fan_light')|int == 0 %}
                    {"value":16774171,"protocol":11,"length":24,"delay":385, "repeat": 10}
                  {% elif states('binary_sensor.samuel_ceiling_fan_light_input') == 'off' and states('counter.samuel_fan_light')|int == 1 %}
                    {"value":16774172,"protocol":11,"length":24,"delay":385, "repeat": 5}
                  {% else %}
                    {"value":Samuel Light Switch ERROR}
                  {% endif %}
                - delay:
                    seconds: 4
                  
      - conditions:
          - condition: trigger
            id: remote
        sequence:
          - service: >
              {% if states('counter.samuel_fan_light')|int > 0  %}
                counter.reset
              {% else %}
                counter.increment
              {% endif %}
            entity_id: counter.samuel_fan_light

      - conditions:
          - condition: trigger
            id: app
        sequence:
          - service: mqtt.publish
            data:
              topic: "home/OpenMQTTGateway/commands/MQTTto433"
              payload: '{"value":16774171,"protocol":11,"length":24,"delay":385, "repeat": 10}'
          - delay: 00:00:01
          - service: counter.reset
            target:
              entity_id: 
                - counter.samuel_fan_light

      - conditions:
          - condition: trigger
            id: light_state
        sequence:
          - service: mqtt.publish
            data:
              topic: "home/OpenMQTTGateway/433toMQTT/Samuel_Fan/light"
              payload_template: >-
                {% if states('counter.samuel_fan_light')|int == 1  %} on
                {% else %} off
                {% endif %}
              retain: true
  mode: restart

- alias: Samuel's Ceiling Fan Speed
  trigger:
    - platform: state
      entity_id:
        - binary_sensor.samuel_ceiling_fan_speed_input
      from: "off"
      to: "on"
      id: fan_speed
    - platform: state
      entity_id:
        - binary_sensor.samuel_ceiling_fan_speed_input
      from: "on"
      to: "off"
      for:
        seconds: 3
      id: switch_off
    - platform: numeric_state
      entity_id: counter.samuel_fan_speed
      above: 3
      id: reset
    - platform: mqtt
      topic: "home/OpenMQTTGateway/433toMQTT/Samuel_Fan/speed"
      value_template: '{{ value_json.value }}'
      id: mqtt_speed
  action:
    - choose:
        - conditions:
            - condition: trigger
              id: fan_speed
          sequence:
            - service: counter.increment
              target:
                entity_id: 
                  - counter.samuel_fan_speed
            - service: mqtt.publish
              data:
                topic: "home/OpenMQTTGateway/commands/MQTTto433"
                payload_template: >-
                  {% if states('counter.samuel_fan_speed')|int == 1  %}
                    {"value":16774147,"protocol":11,"length":24,"delay":385, "repeat": 5}
                  {% elif states('counter.samuel_fan_speed')|int == 2  %}
                    {"value":16774146,"protocol":11,"length":24,"delay":385, "repeat": 5}
                  {% elif states('counter.samuel_fan_speed')|int == 3  %}
                    {"value":16774145,"protocol":11,"length":24,"delay":385, "repeat": 5}
                  {% else %} 
                    {"value":16774144,"protocol":11,"length":24,"delay":385, "repeat": 5}
                  {% endif %}

        - conditions:
            - condition: trigger
              id: reset
          sequence:
            - service: counter.reset
              target:
                entity_id: 
                  - counter.samuel_fan_speed

        - conditions:
            - condition: trigger
              id: switch_off
          sequence:
            - service: counter.reset
              target:
                entity_id: 
                  - counter.samuel_fan_speed
            - service: mqtt.publish
              data:
                topic: "home/OpenMQTTGateway/commands/MQTTto433"
                payload: '{"value":16774144,"protocol":11,"length":24,"delay":385, "repeat": 5}'
                retain: true

        - conditions:
            - condition: trigger
              id: mqtt_speed
          sequence:
            - service: counter.configure
              data:
                value: >
                  {% if trigger.payload == 'low'  %}
                    1
                  {% elif trigger.payload == 'medium'  %}
                    2
                  {% elif trigger.payload == 'high'  %}
                    3
                  {% else %}
                    0
                  {% endif %}
              target:
                entity_id: counter.samuel_fan_speed
  mode: restart

After doing a lot of experimenting it seems the “payload_template: >-” is causing the problem. I am just not sure what the statement is not liking to only fire once.

  action:
    - choose:
      - conditions:
          - condition: trigger
            id: wall_switch
        sequence:
          - repeat:
              until:
                condition: template
                value_template: >
                  {{ ( states('binary_sensor.samuel_ceiling_fan_light_input'),states('binary_sensor.samuel_s_ceiling_fan_light_wattage') ) in [('on' ,'on'), ('off', 'off')] }}
              sequence:
                - service: mqtt.publish
                  data:
                    topic: "home/OpenMQTTGateway/commands/MQTTto433"
                    payload_template: >-
                      {% if states('binary_sensor.samuel_ceiling_fan_light_input') == 'on' %}
                        {"value":16774171,"protocol":11,"length":24,"delay":385, "repeat": 5}
                      {% elif states('binary_sensor.samuel_ceiling_fan_light_input') == 'off' %}
                        {"value":16774172,"protocol":11,"length":24,"delay":385, "repeat": 5}
                      {% else %}
                        {"value":Samuel Light Switch ERROR}
                      {% endif %}
                - delay:
                    seconds: 4

So it does look like another trigger in the automation is restarting everything like you said. If I run the repeat part of the automation in a script I assume this will alleviate the problem?

So I did indeed create a script and call it from the automation and all is well.

SCRIPT

samuel_fan_wall_switch:
    sequence:
      - repeat:
          until:
            condition: template
            value_template: >
              {{ ( states('binary_sensor.samuel_ceiling_fan_light_input'),states('binary_sensor.samuel_s_ceiling_fan_light_wattage') ) in [('on' ,'on'), ('off', 'off')] }}
          sequence:
            - service: mqtt.publish
              data:
                topic: "home/OpenMQTTGateway/commands/MQTTto433"
                payload_template: >-
                  {% if states('binary_sensor.samuel_ceiling_fan_light_input') == 'on' and states('counter.samuel_fan_light')|int == 0 %}
                    {"value":16774171,"protocol":11,"length":24,"delay":385, "repeat": 5}
                  {% elif states('binary_sensor.samuel_ceiling_fan_light_input') == 'off' and states('counter.samuel_fan_light')|int == 1 %}
                    {"value":16774172,"protocol":11,"length":24,"delay":385, "repeat": 5}
                  {% else %}
                    {"value":Samuel Light Switch ERROR}
                  {% endif %}
            - service: counter.configure
              data:
                value: >
                  {% if trigger.to_state == 'on'  %}
                    1
                  {% else %}
                    0
                  {% endif %}
              target:
                entity_id: counter.samuel_fan_light
            - delay:
                seconds: 5
mode: restart

AUTOMATION

- alias: Samuel's Ceiling Fan Light
  trigger:
    - platform: state
      entity_id:
        - binary_sensor.samuel_ceiling_fan_light_input
      id: wall_switch
    - platform: mqtt
      topic: "home/OpenMQTTGateway/433toMQTT"
      value_template: '{{ value_json.value }}'
      payload: '16774171'
      id: remote
    - platform: mqtt
      topic: "home/OpenMQTTGateway/433toMQTT"
      value_template: '{{ value_json.value }}'
      payload: '16774172'
      id: app
    - platform: state
      entity_id:
        - counter.samuel_fan_light
      id: light_state
  action:
    - choose:
        - conditions:
            - condition: trigger
              id: wall_switch
          sequence:
            - service: script.turn_on
              target:
                entity_id: 
                  - script.samuel_fan_wall_switch
                  
        - conditions:
            - condition: trigger
              id: remote
          sequence:
            - service: >
                {% if states('counter.samuel_fan_light')|int > 0  %}
                  counter.reset
                {% else %}
                  counter.increment
                {% endif %}
              entity_id: counter.samuel_fan_light

        - conditions:
            - condition: trigger
              id: app
          sequence:
            - service: mqtt.publish
              data:
                topic: "home/OpenMQTTGateway/commands/MQTTto433"
                payload: '{"value":16774171,"protocol":11,"length":24,"delay":385, "repeat": 5}'
            - delay: 00:00:01
            - service: counter.reset
              target:
                entity_id: 
                  - counter.samuel_fan_light

        - conditions:
            - condition: trigger
              id: light_state
          sequence:
            - service: mqtt.publish
              data:
                topic: "home/OpenMQTTGateway/433toMQTT/Samuel_Fan/light"
                payload_template: >-
                  {% if states('counter.samuel_fan_light')|int == 1  %} on
                  {% else %} off
                  {% endif %}
                retain: true
  mode: restart