Automation Loops to auto start generator help

I’m trying to create an automation to start the on-board RV generator but there are two loops that I can’t seem to get my head around writing it. I created a flow chart of the process.

Summarizing: The generator can take up to 30 seconds to start so the start relay remains on. I have an optocoupler that reads if the generator is running. When this sensor detects the generator is running, the start relay is turned off want to send a notification. However, if the generator does not start in 30 seconds, I want to repeat this process up to 3x before sending an error notification that it did not start. My confusion is getting the loops and conditions correct in the automation.

alias: Start Generator
description: Process to safely start generator unattended
trigger:
  - platform: state
    entity_id:
      - input_boolean.generator_start
    from: "off"
    to: "on"
condition: []
action:
  - repeat:
      count: 3
      sequence:
        - action: switch.turn_on
          metadata: {}
          data: {}
          target:
            entity_id: switch.generator_relay_start
  - condition: state
    entity_id: binary_sensor.generator_state
    state: "off"
  - action: timer.start
    metadata: {}
    data: {}
    target:
      entity_id: timer.generator_start
  - action: switch.turn_on
    metadata: {}
    data: {}
    target:
      entity_id: switch.generator_relay_start
  - condition: state
    entity_id: binary_sensor.generator_state
    state: "on"
  - delay:
      hours: 0
      minutes: 0
      seconds: 5
      milliseconds: 0
  - action: timer.cancel
    metadata: {}
    data: {}
    target:
      entity_id: timer.generator_start
  - if:
      - condition: state
        entity_id: binary_sensor.generator_state
        state: "off"
      - condition: state
        entity_id: timer.generator_start
        state: active
        for:
          hours: 0
          minutes: 0
          seconds: 30
    then: []
mode: single

I’m a bit sluggish in my head right now so I can’t properly take it all in.
But just an idea.
Perhaps you can not use loops but instead use several trigger with for: x seconds and choose, and then use a counter to keep track of how many times it has “looped”.

This is just a thought of a different way that it perhaps could be done.

Full Disclosure: I had difficulty understanding your requirements because it seemed to me like there were discrepancies between the written description, flowchart, and automation. So if what I created below missed the mark, I’m hoping you can point out where I misunderstood your requirements and then I’ll adjust the automation accordingly.

I created an automation that employs a repeat - until that uses a wait_template with a 30 second timeout (so no timer entity is needed).

It turns on the switch then waits, for up to 30 seconds, for the binary_sensor to turn on. It checks the wait variable to determine if the template’s condition was met within the 30 seconds timeout or not.

  • If the binary_sensor turns on within 30 seconds, the automation posts a notification indicating success.

  • If it fails to turn on within 30 seconds and the loop count is less than 3, the automation tries again. If the loop count is 3, it posts a notification indicating failure.

To be clear, I’m not 100% certain it meets all your requirements because there are steps in your automation that I haven’t duplicated in mine. Nevertheless, at the very least I think it’s a good starting point and I can help you refine it to meet your specific needs.

alias: Start Generator
description: Process to safely start generator unattended
trigger:
  - platform: state
    entity_id:
      - input_boolean.generator_start
    from: "off"
    to: "on"
condition: []
action:
  - repeat:
      sequence:
        - action: switch.turn_on
          target:
            entity_id: switch.generator_relay_start
        - wait_template: "{{ is_state('binary_sensor.generator_state', 'on') }}"
          timeout:
            seconds: 30
        - if: "{{ wait.completed }}"
          then:
            - action: notify.persistent_notification
              data:
                title: Success
                message: Generator started.
          else:
            - if: "{{ repeat.index == 3 }}"
              then:
                - action: notify.persistent_notification
                  data:
                    title: Failure
                    message: Three attempts to start generator have failed.
        - action: switch.turn_off
          target:
            entity_id: switch.generator_relay_start
        - delay:
            seconds: "{{ 5 if not wait.completed else 0 }}"
      until: "{{ is_state('binary_sensor.generator_state', 'on') or repeat.index >= 3 }}"

EDIT

Correction. Added missing terminating single-quote to 'on' in two places.

Thanks so much for your work! I created several dummy sensors and an entity card yesterday in Lovelace to test an automation just for the starting sequence without the “re-try” loop. I did that because I accidentally turned on my generator during testing and it was running for 5 hours :frowning:

My initial automation was a mess and did not accurately reflect the desired process described in the flow chart. The new “test” automation is below and does require a manual toggle of ’ input_boolean.test_generator_running_toggle’ to simulate the generator in the running state.

I will put yours in on Saturday and give it a try. I’m looking forward to doing that. Due to my mistake mentioned above, I want to add some sort of “clock” to report the generator run time.

alias: Test Generator Start
description: Using Test Sensors, not real sensors
trigger:
  - platform: state
    entity_id:
      - input_button.start_gen_button
    from: null
condition:
  - condition: state
    entity_id: input_boolean.auto_start_enabled
    state: "on"
action:
  - action: input_boolean.turn_on
    metadata: {}
    data: {}
    target:
      entity_id: input_boolean.test_start_relay
  - action: timer.start
    metadata: {}
    data: {}
    target:
      entity_id: timer.generator_start
  - wait_for_trigger:
      - platform: state
        entity_id:
          - input_boolean.test_generator_running_toggle
        from: "off"
        to: "on"
    timeout:
      hours: 0
      minutes: 0
      seconds: 10
      milliseconds: 0
  - action: timer.cancel
    metadata: {}
    data: {}
    target:
      entity_id: timer.generator_start
  - action: input_boolean.turn_off
    metadata: {}
    data: {}
    target:
      entity_id: input_boolean.test_start_relay
  - if:
      - condition: state
        entity_id: input_boolean.test_generator_running_toggle
        state: "on"
    then:
      - action: notify.mobile_app_sm_n960u
        metadata: {}
        data:
          message: Generator Started
    else:
      - action: notify.mobile_app_sm_n960u
        metadata: {}
        data:
          message: Generator Did not Start
mode: single

Lovelace Card for testing with Dummy Sensors

type: entities
entities:
  - entity: input_button.start_gen_button
  - entity: input_boolean.test_generator_running_toggle
  - entity: input_boolean.test_start_relay
  - entity: timer.generator_start
  - entity: input_boolean.test_stop_relay
  - entity: input_button.test_stop_relay
title: Generator Testing Dummy Sensors
show_header_toggle: false

Tried to use your code and received a weird error.

Message malformed: invalid template (TemplateSyntaxError: unexpected char “'” at 45) for dictionary value @ data[‘action’][0][‘repeat’][‘sequence’][1][‘wait_template’]

I’m using the UI for my automations. Once I get everything working, I’ll move them into packages. I copied and pasted the yaml into a new automation. I must be missing something. Ran out of time to debug further. I’m not giving up.

There’s missing a ' after on in the wait template

1 Like

What Hellis said; missing single-quote.

The word on is used in the wait_template and the until.

It should be delimited with single-quotes like this 'on' but the example I posted is missing the terminating single-quote so it’s 'on instead.

Please add the missing single-quote in both places (I have already corrected the example above).

The first loop is working great. I have not purposely tried pulling spark plug to prevent generator from starting to test the second loop. Temps have been in the 80’s (F) so this time of year it starts reliably. I tried adding a few more actions and for whatever reason they are not firing as expected. They are skipped over in the traces, too. I’ve posted the latest automation.

alias: Generator Start Cycle Loop
description: Process to safely start generator unattended with Retry Loop
trigger:
  - platform: state
    entity_id:
      - input_boolean.generator_start
    from: "off"
    to: "on"
condition: []
action:
  - repeat:
      sequence:
        - action: switch.turn_on
          target:
            entity_id: switch.generator_relay_start
          data: {}
        - wait_template: "{{ is_state('binary_sensor.generator_state', 'on') }}"
          timeout:
            seconds: 15
        - if:
            - condition: template
              value_template: "{{ wait.completed }}"
          then:
            - action: notify.persistent_notification
              data:
                title: Success
                message: Generator started.
            - action: mqtt.publish
              metadata: {}
              data:
                topic: victron-rv/W/b827ebc2e94d/system/5/Relay
                payload: "{\"value\":0}"
# This section is not firing
            - action: switch.turn_off
              metadata: {}
              data: {}
              target:
                entity_id: switch.generator_relay_start
            - action: input_boolean.turn_off
              metadata: {}
              data: {}
              target:
                entity_id: input_boolean.generator_start
######
          else:
            - if:
                - condition: template
                  value_template: "{{ repeat.index == 3 }}"
              then:
                - action: notify.persistent_notification
                  data:
                    title: Failure
                    message: Three attempts to start generator have failed.
            - action: mqtt.publish
              metadata: {}
              data:
                topic: victron-rv/W/b827ebc2e94d/system/5/Relay
                payload: "{\"value\":1}"
        - action: switch.turn_off
          target:
            entity_id:
              - switch.generator_relay_start
          data: {}
        - action: input_boolean.turn_off
          metadata: {}
          data: {}
          target:
            entity_id: input_boolean.generator_start
        - delay:
            seconds: "{{ 10 if not wait.completed else 0 }}"
      until:
        - condition: template
          value_template: >-
            {{ is_state('binary_sensor.generator_state', 'on') or repeat.index
            >= 3 }}

Here is the trace

repeat:
  sequence:
    - action: switch.turn_on
      target:
        entity_id: switch.generator_relay_start
      data: {}
    - wait_template: '{{ is_state(''binary_sensor.generator_state'', ''on'') }}'
      timeout:
        seconds: 15
    - if:
        - condition: template
          value_template: '{{ wait.completed }}'
      then:
        - action: notify.persistent_notification
          data:
            title: Success
            message: Generator started.
        - action: mqtt.publish
          metadata: {}
          data:
            topic: victron-rv/W/b827ebc2e94d/system/0/Relay
            payload: '{"value":0}'
      else:
        - if:
            - condition: template
              value_template: '{{ repeat.index == 3 }}'
          then:
            - action: notify.persistent_notification
              data:
                title: Failure
                message: Three attempts to start generator have failed.
    - action: switch.turn_off
      target:
        entity_id: switch.generator_relay_start
      data: {}
    - delay:
        seconds: '{{ 10 if not wait.completed else 0 }}'
  until:
    - condition: template
      value_template: >-
        {{ is_state('binary_sensor.generator_state', 'on') or repeat.index >= 3
        }}

Great work! And many thanks! This is a head scratcher.