Automation Logic check please

I’m just starting to try out automations in my setup. The aim is to test when my power tariff (Intelligent Octopus Go) triggers a cheap rate during normal peak hours. The to set up my solar and battery to make best use of the cheap energy. I have a couple that are working for the normal day/night rate turning on/off but haven’t been able to get the peak rate/ad hoc scheduled off peak periods to trigger.
I think this is because one of the conditions I am testing for (zappi__status) is taking a couple of minutes to wind up the spring and change state.
So I am attempting to introduce a delay to allow for this.
I can’t test it until I plug in later and octopus creates a charge schedule (hopefully with some ad hoc periods scheduled).
I have examined the entities concerned over a couple of days and think I have the correct logic for what I’m trying to achieve.
Could I ask those more experienced in yaml them me ( believe me that’s not a high bar) to check if my logic is correct and the syntax (especially my use of quotes) of the yaml will do what I want please?
I’m pretty happy with the actions I need to take on the solar side, it’s the logic and syntax to get the actions triggered that I’m unsure of.
Both yaml files below:

alias: Peak Hours Intelligent Despatching Turns On
description: |-
  Test for Intelligent Dispatching on, Zappi is boosting and Peak Rate is on.
  Then setup Growatt to charge battery and import all from grid.
trigger:
  - platform: state
    entity_id:
      - binary_sensor.octopus_energy_a_********_intelligent_dispatching
    from: "off"
    to: "on"
action:
  - delay: "00:03:00"
  - condition: and
    conditions:
      - condition: state
        entity_id: binary_sensor.iogpeakhours
        state: "on"
      - condition: state
        entity_id: sensor.myenergi_zappi_********_status
        state: "Boosting"
  - type: turn_on
    device_id: 76747b33c758620b3a9c673b2fae7913
    entity_id: fe1df43fe54f44aee44f083003607e81
    domain: switch
  - device_id: 76747b33c758620b3a9c673b2fae7913
    domain: select
    entity_id: 0f5d6c23ccadb375b20f1d3c86236066
    type: select_option
    option: Battery first
  - device_id: 76747b33c758620b3a9c673b2fae7913
    domain: select
    entity_id: 802dec9df90526f6a03f5e4343144029
    type: select_option
    option: Enabled
  - device_id: 76747b33c758620b3a9c673b2fae7913
    domain: number
    entity_id: 0e0c82237cb16f866b35290fa49e880b
    type: set_value
    value: 0
mode: single
alias: Peak Hours Intelligent Despatching Turns Off
description: >-
  Test for Intelligent Dispatching off.

  Test myenergi Home Charger Status is NOT Boosting

  Then setup Growatt to load first. Reset values changed in Peak Hours
  Intelligent Despatching Turns ON
trigger:
  - platform: state
    entity_id:
      - binary_sensor.octopus_energy_a_********_intelligent_dispatching
    from: "on"
    to: "off"
action:
  - delay: "00:03:00"
  - condition: state
    entity_id: binary_sensor.iogpeakhours
    state: "on"
  - condition: or
    conditions:
      - condition: state
        entity_id: sensor.myenergi_zappi_********_status
        state: "Paused"
      - condition: state
        entity_id: sensor.myenergi_zappi_********_status
        state: "Completed"  
  - device_id: 76747b33c758620b3a9c673b2fae7913
    domain: number
    entity_id: 0e0c82237cb16f866b35290fa49e880b
    type: set_value
    value: 100
  - device_id: 76747b33c758620b3a9c673b2fae7913
    domain: select
    entity_id: 802dec9df90526f6a03f5e4343144029
    type: select_option
    option: Disabled
  - device_id: 76747b33c758620b3a9c673b2fae7913
    domain: select
    entity_id: 0f5d6c23ccadb375b20f1d3c86236066
    type: select_option
    option: Load first
  - type: turn_off
    device_id: 76747b33c758620b3a9c673b2fae7913
    entity_id: fe1df43fe54f44aee44f083003607e81
    domain: switch
mode: single

Home Assistant has the ability to WAIT for something to happen.

I have an automation that turns off my camera stream to a tablet when the front porch is unoccupied for 5 seconds:

  - wait_for_trigger:
    - platform: state
      entity_id:
      - binary_sensor.camera_g4_doorbell_pro_person_detected
      to: 'off'
      for:
        hours: 0
        minutes: 0
        seconds: 5
    continue_on_timeout: true
    timeout:
      hours: 0
      minutes: 3
      seconds: 0
      milliseconds: 0

The timeout part says, after 3 minutes of waiting, continue anyways. This could be set to false and the automation would stop running / waiting after 3 minutes.

1 Like

Also…

Conditions are “and” by default, so you don’t need that line.

Where you want the automation to stop if a condition is not met, the normal sequence is trigger - condition - action. So something like…

trigger:
  - platform: state
    entity_id:
      - binary_sensor.octopus_energy_a_********_intelligent_dispatching
    from: "off"
    to: "on"
    for:
      hours: 0
      minutes: 3
      seconds: 0
condition:
  - condition: state
    entity_id: binary_sensor.iogpeakhours
    state: "on"
  - condition: state
    entity_id: sensor.myenergi_zappi_********_status
     state: "Boosting"
action:
  etc, etc.

Notice then it’s condition: not conditions:

1 Like

Personally prefer the wait_for_trigger - as then you get execution of your intended action immediately when triggered. You’re also not (based on how you set it up) going to ‘miss’ the execution if it doesn’t happen to occur within your fixed waiting timeframe. It also still gives you the ability to execute or abort after a fixed timeframe. Super powerful / efficient.

1 Like

Thanks for that suggestion. It sounds like it would suit my use case.
Can I just check…

Is the logic of that:
IF intelligent_dispatching turns on AND stays on for 3 minutes,
then and only then the conditions are tested and.
If all conditions are met, the actions executed.
Else the automation exits without completing the actions?

Thanks for that suggestion. It sounds ideal.
Looking at the documentation, would this work in my case…

action:
  - wait_for_trigger:
      - condition: state
        entity_id: sensor.myenergi_zappi_********_status
        state: "Boosting"
	timeout: "00:05:00
  - condition:
      - condition: state
        entity_id: binary_sensor.iogpeakhours
        state: "on"

Personally, for multiple conditions, I use a template:

- wait_for_trigger:
  - platform: template
    value_template: "{{ is_state('sensor.myenergi_zappi_********_status','Boosting') and is_state('binary_sensor.iogpeakhours','on') }}"
  timeout: "00:05:00"
  continue_on_timeout: true

So that will wait for both sensor conditions to be met within 5 minutes and carry on with the actions if both are met. If one or the other is not met within the timeout it will continue and not execute the remaining actions?
Sorry if I’m being a bit dim :wink:

Trying this out. It doesn’t like the syntax of the wait_for_trigger block as the side bar on the yaml editor goes red and I can’t save it.
It’s somewhere between the wait_for_trigger and continue_on_timeout lines as without them it goes green and can be saved.
Where have I got it wrong?

alias: Test wait for trigger Peak Hours Intelligent Despatching Turns On
description: |-
  Test for Intelligent Dispatching on, Zappi is boosting and Peak Rate is on.
  Then setup Growatt to charge battery and import all from grid.
trigger:
  - platform: state
    entity_id:
      - binary_sensor.octopus_energy_a_********_intelligent_dispatching
    from: "off"
    to: "on"
action:
  - wait_for_trigger:
      - platform: template
        value_template: "{{ is_state('sensor.myenergi_zappi_********_status','Boosting') and is_state('binary_sensor.iogpeakhours','on') }}"
	  timeout: "00:05:00"
      continue_on_timeout: true
  - type: turn_on
    device_id: 76747b33c758620b3a9c673b2fae7913
    entity_id: fe1df43fe54f44aee44f083003607e81
    domain: switch
  - device_id: 76747b33c758620b3a9c673b2fae7913
    domain: select
    entity_id: 0f5d6c23ccadb375b20f1d3c86236066
    type: select_option
    option: Battery first
  - device_id: 76747b33c758620b3a9c673b2fae7913
    domain: select
    entity_id: 802dec9df90526f6a03f5e4343144029
    type: select_option
    option: Enabled
  - device_id: 76747b33c758620b3a9c673b2fae7913
    domain: number
    entity_id: 0e0c82237cb16f866b35290fa49e880b
    type: set_value
    value: 0
mode: single

Yup.

Although strictly speaking I suppose it should be “WHEN intelligent_dispatching…”. Triggers are single changes of state, it can be confusing to think of them like conditions.

1 Like

Thanks for that. I’m easily confused :confused: :laughing:

1 Like

@Markus99
I think I’ve sorted the syntax. Must have had an extra space in the indentation somewhere.

action:
  - wait_for_trigger:
      - platform: template
        value_template: >-
          {{ is_state('sensor.myenergi_zappi_********_status','Boosting') and
          is_state('binary_sensor.iogpeakhours','on') }}
    timeout: "00:05:00"
    continue_on_timeout: true

Seems to pass the save test anyway :slight_smile:
Am I right to assume the wait_for_trigger doesn’t need to see a change of state to that specified, i.e. if the entity is already in that state it will pass the test?
I ask because it is highly likely that iogpeakhours will already be on when we get here.

How do I change this to now test for zappi NOT Boosting AND iogpeakhours still ON?
Something like this but in a template format…

action:
  - condition: and
    conditions: 
      - condition: state
        entity_id: binary_sensor.iogpeakhours
        state: "on"
      - condition: 
          not:
          - condition: state
            entity_id: sensor.myenergi_zappi_24258124_status
            state: Boosting

No, I don’t think so. The trigger is the change of state. If the state doesn’t change, it won’t fire. You do have the timeout, however - as you have it, the action part of the automation will always run after five minutes, whether or not the test is passed.

The easiest way is to change the state of your sensors in Developer Tools | States. (It’s only a temporary change - they will revert to their real values next time they get an update.)

1 Like

A trigger fires when the condition(s) CHANGE to true. So, if they’re already true then it won’t fire. A work-around here is introducing an IF statement, similar to what this person has done: Wait_for_trigger automation never continues despite being true - #3 by gerombo

As to your question about ‘not’ boosting - believe this should work:

value_template: >-
          {{ states('sensor.myenergi_zappi_********_status') != 'Boosting' and
          is_state('binary_sensor.iogpeakhours','on') }}

With Home Assistant - there typically seem to be multiple ways to do things…

1 Like

Is that because I have continue_on_timeout: true
I don’t want the actions to run if the test fails so if I set that to false will that stop the actions if the test fails? My assumption is it will.

I’m trying to implement something along these lines but I can’t get the syntax right.
I think it’s just an indentation issue but I’m damned if I can see it.
Can anyone help and old duffer out and see what’s wrong here please?

alias: Test wait for trigger Peak Hours Intelligent Despatching Turns On
description: |-
  Test for Intelligent Dispatching on, Zappi is boosting and Peak Rate is on.
  Then setup Growatt to charge battery and import all from grid.
trigger:
  - platform: state
    entity_id:
      - binary_sensor.octopus_energy_a_********_intelligent_dispatching
    from: "off"
    to: "on"
action:
  - if:
      - condition: state
        entity_id: 'sensor.myenergi_zappi_********_status'
        state: 'Boosting'
      - condition: state
        entity-id: 'binary_sensor.iogpeakhours'
        state: 'on'
        for:
          seconds: 0
    then:
      - type: turn_on
        device_id: 76747b33c758620b3a9c673b2fae7913
        entity_id: fe1df43fe54f44aee44f083003607e81
        domain: switch
      - device_id: 76747b33c758620b3a9c673b2fae7913
        domain: select
        entity_id: 0f5d6c23ccadb375b20f1d3c86236066
        type: select_option
        option: Battery first
      - device_id: 76747b33c758620b3a9c673b2fae7913
        domain: select
        entity_id: 802dec9df90526f6a03f5e4343144029
        type: select_option
        option: Enabled
      - device_id: 76747b33c758620b3a9c673b2fae7913
        domain: number
        entity_id: 0e0c82237cb16f866b35290fa49e880b
        type: set_value
        value: 0
    else:
      - condition: state
        entity-id: 'binary_sensor.iogpeakhours'
        state: 'on'
          - wait_for_trigger:
              - platform: template
                value_template: >-
                  {{ is_state('sensor.myenergi_zappi_********_status','Boosting') }}
            timeout: "00:05:00"
            continue_on_timeout: false
        - type: turn_on
          device_id: 76747b33c758620b3a9c673b2fae7913
          entity_id: fe1df43fe54f44aee44f083003607e81
          domain: switch
        - device_id: 76747b33c758620b3a9c673b2fae7913
          domain: select
          entity_id: 0f5d6c23ccadb375b20f1d3c86236066
          type: select_option
          option: Battery first
        - device_id: 76747b33c758620b3a9c673b2fae7913
          domain: select
          entity_id: 802dec9df90526f6a03f5e4343144029
          type: select_option
          option: Enabled
        - device_id: 76747b33c758620b3a9c673b2fae7913
          domain: number
          entity_id: 0e0c82237cb16f866b35290fa49e880b
          type: set_value
          value: 0

Oddly it won’t save in HA but if I paste the code into Notepad++ it doesn’t throw any errors?
in HA the save error is

Message malformed: extra keys not allowed @ data[‘action’][0][‘if’][1][‘entity-id’]

If I take out the else section to the end it likes it.

It’s due to a typo. Look at the second condition in the if statement.

You used a hyphen in entity-id instead of an underscore as in entity_id.

1 Like

Great spot, thanks for that.
Sadly it still throws the error

Message malformed: extra keys not allowed @ data[‘action’][0][‘if’][1][‘entity-id’]

When I try to save it :frowning:

entity-id is also in the end else statement.


    else:
      - condition: state
        entity-id: 'binary_sensor.iogpeakhours'