Automation Blueprint: Prevent condition sequence from continuously looping

I seem to be running into a continuous loop. How do I get the automation to run though it’s sequences once without the need of turning the automation off?

Desired outcome:

  • when an inpute_boolean is ON check certain conditions
  • IF condition is met, run the sequence and then stop until the next time the automation is triggered

Sequence:

  • IF the actual water run off is more than the desired water run off
  • THEN reduce water volumne by a certain percentage
  • ELSE IF the actual water run off is less than designed run off
  • THEN increase water volume by a certain percentage
  • ELSE Do nothing

All the calucations work fine but it just goes into a continuous loop. Thank you all in advance for taking the time to read and for any advice you might have.

# Set condition so that the 'Water Volume' only gets updated if the 'Update Water Volume' is turned ON
  - condition: state
    entity_id: input_boolean.update_water_volume
    state: 'on'
  - choose:
# Redude 'Water Volume' if the plant feed run off is too high
    - conditions:
        condition: template
        value_template: "{{ states('sensor.actual_plant_feed_run_off') | float(0) >= states('input_number.plant_feed_run_off_high') | float(0) }}"
      sequence:
        - action: input_number.set_value
          data_template:
            entity_id: input_number.water_volume
            value: >
              {% set reduceWaterVolumeAmount = ((states('input_number.water_volume') | float(0)) / 100) * (states('input_number.adjust_water_volume_amount') | float(0)) %}  
              {% set waterVolume = states('input_number.water_volume') | float(0) %} 
              {{ waterVolume - reduceWaterVolumeAmount }}
        - event: ''
          event_data:
            event_type: "{{ run_off_high }}"
# Increase 'Water Volume' if the plant feed run off is too low
    - conditions:
        condition: template
        value_template: "{{ states('sensor.actual_plant_feed_run_off') | float(0) <= states('input_number.plant_feed_run_off_low') | float(0) }}"
      sequence:
        - action: input_number.set_value
          data_template:
            entity_id: input_number.water_volume
            value: >
              {% set increaseWaterVolumeAmount = ((states('input_number.water_volume') | float(0)) / 100) * (states('input_number.adjust_water_volume_amount') | float(0)) %}  
              {% set waterVolume = states('input_number.water_volume') | float(0) %} 
              {{ waterVolume + increaseWaterVolumeAmount }}
        - event: ''
          event_data:
            event_type: "{{ run_off_low }}"
mode: single

Full code:

blueprint:
  name: Drain Tank Monitor
  description: ''
  domain: automation
  input:

# Input script for selecting the scales for the drain tank and setting the event_type to trigger this automation
    drain_tank_volume:
      name: Select Sensor Scale Value
      description: "Select sensor that gives you the weight-volume of the nutrient tank"
      selector:
          entity:
            filter:
              - domain: sensor
    tank_fill_complete_event:
      name: "Plant Feed Run Off Trigger"
      description: "This is the event_type that the wait trigger listens out for"
      default: "fill_tank_complete"
      selector:
        text:

variables:
  drain_tank_volume: !input drain_tank_volume
  tank_fill_complete_event: !input tank_fill_complete_event


# Trigger automation when the tank fill is completed
triggers:
  - trigger: event
    event_type: "{{ tank_fill_complete_event }}"

# Set Condition so that the plant feed run off automation only runs during the cycle start and end date
conditions:
  - condition: template
    value_template: >
      {% set startDate = states('input_datetime.cycle_start_date') | as_datetime | as_local %} 
      {% set endDate = states('sensor.cycle_end_date') | as_datetime | as_local %}
      {% set today = now() %} 
      {{ endDate >= today >= startDate}}

actions:
# Update 'Plant Feed Run Off' with the value of the drain tank scale value
  - action: input_number.set_value
    data_template:
      entity_id: input_number.plant_feed_run_off
      value: "{{ states(drain_tank_volume) }}"
  - delay:
      seconds: 2
# Update 'Total Plant Feed Run Off' with the 'Plant Feed Run Off' value to get total litres contained in drain tank
  - action: input_number.set_value
    data_template:
      entity_id: input_number.total_plant_feed_run_off
      value: >
        {% set totalRunOff = states('input_number.total_plant_feed_run_off') | float %}  
        {% set plantFeedRunOff = states('input_number.plant_feed_run_off') | float %} 
        {{ totalRunOff + plantFeedRunOff }}
# Set condition so that the 'Water Volume' only gets updated if the 'Update Water Volume' is turned ON
  - condition: state
    entity_id: input_boolean.update_water_volume
    state: 'on'
  - choose:
# Redude 'Water Volume' if the plant feed run off is too high
    - conditions:
        condition: template
        value_template: "{{ states('sensor.actual_plant_feed_run_off') | float(0) >= states('input_number.plant_feed_run_off_high') | float(0) }}"
      sequence:
        - action: input_number.set_value
          data_template:
            entity_id: input_number.water_volume
            value: >
              {% set reduceWaterVolumeAmount = ((states('input_number.water_volume') | float(0)) / 100) * (states('input_number.adjust_water_volume_amount') | float(0)) %}  
              {% set waterVolume = states('input_number.water_volume') | float(0) %} 
              {{ waterVolume - reduceWaterVolumeAmount }}
        - event: ''
          event_data:
            event_type: "{{ run_off_high }}"
# Increase 'Water Volume' if the plant feed run off is too low
    - conditions:
        condition: template
        value_template: "{{ states('sensor.actual_plant_feed_run_off') | float(0) <= states('input_number.plant_feed_run_off_low') | float(0) }}"
      sequence:
        - action: input_number.set_value
          data_template:
            entity_id: input_number.water_volume
            value: >
              {% set increaseWaterVolumeAmount = ((states('input_number.water_volume') | float(0)) / 100) * (states('input_number.adjust_water_volume_amount') | float(0)) %}  
              {% set waterVolume = states('input_number.water_volume') | float(0) %} 
              {{ waterVolume + increaseWaterVolumeAmount }}
        - event: ''
          event_data:
            event_type: "{{ run_off_low }}"
mode: single

What do the debug traces for the automation say?

Nothing jumps out to me as something that would definitely cause looping The possible issues that pop out to me are:

  1. The actions firing events don’t have event types… I don’t think that’s allowed, but I could be wrong.
  2. There are two undefined variables run_off_low and run_off_high.

Sorry @Didgeridrew for wasting your time. You were 100% correct, they are now allowed. Seems having them causes it to loop. Perhaps I am writing them wrong for an automation but coding them like below works in a script:

- event: ''
  event_data:
    event_type: !input tank_fill_complete_event

As for the traces, I’m still understanding how to diagnose them. If I understand it correctly, it would appear it’s aborting due to ‘Update Water Volume’ being off. But in fact, it loops through the choose conditions until I turn off the input_boolean.update_water_volume

On a side note regarding variables (removed the redundant variable you spotted) is there actually any need for defining a variable for such things as events? I think I need to do more reading into trigger_variables as I don’t know how they work

As the below code doesn’t work if I set the event_type with a variable

triggers:
  - trigger: event
    event_type: "{{ tank_fill_complete_event }}"

But firing an event will work with a variable:

- event: ''
  event_data:
    event_type: !input tank_fill_complete_event

Hopefully the following simplified example will help explain where the variables are needed vs. the inputs.

blueprint:
  name: Event Trigger Automation
  description: ''
  domain: automation
  input:
    trigger_custom_event:
      name: "Trigger Event Type"
      description: "This is the event_type that the trigger listens out for"
      default: "trigger_"
      selector:
        text:
    action_custom_event:
      name: "Action Event Type"
      description: "This is the event_type that the action will post"
      default: "action_"
      selector:
        text:
variables:
  trigger_event: !input trigger_custom_event 
  action_event: !input action_custom_event
triggers:
  - trigger: event
    event_type: !input trigger_custom_event
conditions: []
actions:
  - event: !input action_custom_event
    event_data:
      trigger_event: "{{ trigger_event }}"
  - action: persistent_notification.create
    data:
      title: "Automation: {{ this.attributes.friendly_name }}"
      message: |
        Automation successfully run at {{ now() }}
        Action Event: {{ action_event }}
mode: single
1 Like

Updated my response ^^

Oh I see! It certainly does help, thank you! I didn’t understand the fact that you were defining the variable i.e. trigger_event vs action_event

So perhaps a different topic but potentially related. I am having an issue with a trigger where by an automation should run if a soil moisture reading is less than a soil moisture reading target. And if I directly add the sensor.soil_moisture_sensor into the value_template it works fine but as a variable it doesn’t. Is that again due to defining the variable? (if I am using the correct terminology)

variables:
  soil_moisture_sensor: !input soil_moisture_sensor
  plant_feed_full_proces_automation: !input plant_feed_full_proces_automation

# WHY won't the sensor work with the input but it will by directly adding the sensor
triggers:
  - trigger: template
    value_template: "{{ (states(soil_moisture_sensor) | float) <= (states('input_number.soil_moisture_water_trigger') | float) }}"

Also, not all my code I reference shows the pretty colours (which makes it way easier to read). what gives?

When you use the default ``` at the start of the code block, it uses the forum default (I forget which format it is). If you use ```yaml instead of ``` at the start of the block will give the colors you see in my posts.

That is where you need trigger_variables. The basic variables block is rendered after the trigger. The trigger_variables are rendered on startup so the listeners can be properly set up. Just be aware that trigger_variables only allows limited templates, so you can’t use alot of the template functions available elsewhere.

trigger_variables:
  soil_moisture_sensor: !input soil_moisture_sensor

variables:
  plant_feed_full_proces_automation: !input plant_feed_full_proces_automation

triggers:
  - trigger: template
    value_template: "{{ (states(soil_moisture_sensor) | float) <= (states('input_number.soil_moisture_water_trigger') | float) }}"
1 Like

:rofl:
I'm not worth