Trying to use a variable passed to a script as a state trigger within the script

Hey all,

I’ve got a working automation that forcibly discharges my home battery down to certain thresholds at various points in the day. Eg. at 20:30 it’ll discharge down to 50%, and at 21:30 it’ll discharge to 25% and so on. It look like this:

alias: "Libbi: Timed exports"
description: ""
trigger:
  - platform: time
    at: "20:30:00"
    id: "2030"
  - platform: time
    at: "21:30:00"
    id: "2130"
  - platform: time
    at: "22:30:00"
    id: "2230"
  - platform: time
    at: "23:00:00"
    id: "2300"
condition:
  - condition: not
    conditions:
      - condition: state
        entity_id: sensor.myenergi_zappi_22100218_status
        state: Boosting
action:
  - choose:
      - conditions:
          - condition: trigger
            id:
              - "2030"
          - condition: numeric_state
            entity_id: sensor.myenergi_libbi_24049368_soc
            above: 50
        sequence:
          - service: notify.telegram_us
            data:
              data:
                message_tag: libbi
              message: >-
                Libbi at {{ states('sensor.myenergi_libbi_24049368_soc') }}%
                charge. Exporting to 25%
          - if:
              - condition: state
                entity_id: sensor.myenergi_zappi_22100218_plug_status
                state: EV Connected
            then:
              - device_id: 29e9524df6815f8f22c8b154295dcf8d
                domain: select
                entity_id: 201e81484bc3aa7f614de6916ddc9c80
                type: select_option
                option: Stopped
          - device_id: 8c1f789db93bb94e82f47e9fda5ba4f1
            domain: select
            entity_id: efbdc28be6e6c52562e33d7d4492fa1f
            type: select_option
            option: Export
          - wait_for_trigger:
              - platform: state
                entity_id:
                  - sensor.myenergi_libbi_24049368_soc
                to: "25"
            timeout:
              hours: 0
              minutes: 59
              seconds: 30
              milliseconds: 0
            continue_on_timeout: false
          - device_id: 8c1f789db93bb94e82f47e9fda5ba4f1
            domain: select
            entity_id: efbdc28be6e6c52562e33d7d4492fa1f
            type: select_option
            option: Normal
          - service: notify.telegram_us
            data:
              data:
                message_tag: libbi
              message: Export stopped.
          - if:
              - condition: state
                entity_id: select.myenergi_zappi_22100218_charge_mode
                state: Stopped
            then:
              - device_id: 29e9524df6815f8f22c8b154295dcf8d
                domain: select
                entity_id: 201e81484bc3aa7f614de6916ddc9c80
                type: select_option
                option: Eco+

… And then there’s 3 more options that do the exact same sequence just with the different time and SoC conditions. It works but it’s obviously super clunky, so I’ve been trying to convert that sequence into a script in order to simplify it. So now, for the first block, I’m just doing this:

action:
  - choose:
      - conditions:
          - condition: trigger
            id:
              - "2030"
          - condition: numeric_state
            entity_id: sensor.myenergi_libbi_24049368_soc
            above: 50
        sequence:
          - service: script.libbi_export
            data:
              target: "50"

And then my script contains the main sequence:

alias: Libbi Export
sequence:
  - service: notify.telegram_me
    data:
      data:
        message_tag: libbi
      message: >-
        Libbi at {{ states('sensor.myenergi_libbi_24049368_soc') }}% charge.
        Exporting to {{ target }}%
  - if:
      - condition: state
        entity_id: sensor.myenergi_zappi_22100218_plug_status
        state: EV Connected
    then:
      - device_id: 29e9524df6815f8f22c8b154295dcf8d
        domain: select
        entity_id: 201e81484bc3aa7f614de6916ddc9c80
        type: select_option
        option: Stopped
  - device_id: 8c1f789db93bb94e82f47e9fda5ba4f1
    domain: select
    entity_id: efbdc28be6e6c52562e33d7d4492fa1f
    type: select_option
    option: Export
  - wait_for_trigger:
      - platform: state
        entity_id:
          - sensor.myenergi_libbi_24049368_soc
        to: "{{ target }}"
    timeout:
      hours: 0
      minutes: 59
      seconds: 30
      milliseconds: 0
    continue_on_timeout: false
  - device_id: 8c1f789db93bb94e82f47e9fda5ba4f1
    domain: select
    entity_id: efbdc28be6e6c52562e33d7d4492fa1f
    type: select_option
    option: Normal
  - service: notify.telegram_me
    data:
      data:
        message_tag: libbi
      message: Export stopped.
  - if:
      - condition: state
        entity_id: select.myenergi_zappi_22100218_charge_mode
        state: Stopped
    then:
      - device_id: 29e9524df6815f8f22c8b154295dcf8d
        domain: select
        entity_id: 201e81484bc3aa7f614de6916ddc9c80
        type: select_option
        option: Eco+
mode: single
icon: mdi:battery-arrow-down

Where I’m coming unstuck is that the {{ target }} variable works great inside the notification message, but I can’t make it work inside the wait_for_trigger action.

After a lot of Googling I’ve also tried doing it as a wait_template in various guises but none of these work either:

  - wait_template: "{{ is_state('sensor.myenergi_libbi_24049368_soc','{{ target }}') }}"
    timeout: "00:59:30"
    continue_on_timeout: false

and (with and without single quotes around target):

  - wait_template: "{{ is_state('sensor.myenergi_libbi_24049368_soc',target) }}"
    timeout: "00:59:30"
    continue_on_timeout: false

Very much clutching at straws, but as this is reporting battery level, perhaps I need to include the % sign, but I can’t make that work either.

I feel like this must be possible but I’m pulling my hair out trying to get the syntax right! After what feels like a wasted afternoon I’m very much open to any suggestions here.

Thanks everyone.

A wait_for_trigger’s inability to handle script variables appears to be a bug.

If you’re experiencing the same problem with wait_template then it may have the same bug.

FWIW, this template you tried would never work because you cannot nest templates like that.

wait_template: "{{ is_state('sensor.myenergi_libbi_24049368_soc','{{ target }}') }}"

The second thing you tried was correct as far as templating goes but if it failed to work then it implies wait_template has the same issue with script variables as wait_for_trigger.

wait_template: "{{ is_state('sensor.myenergi_libbi_24049368_soc',target) }}"

BTW, when choosing a variable name, try to avoid a name that is identical to a scripting statement (i.e. like “target”).

Ha, well that explains a lot! I tried changing the variable to a more suitable name just in case it was tripping up the wait_template (thanks for that tip), but it didn’t make any difference.

I also tried setting the value of an input_number helper at the start of the script:

  - service: input_number.set_value
    metadata: {}
    data:
      value: "{{ export_target }}"
    target:
      entity_id: input_number.libbi_export_target

And using that as the trigger either in the wait_for_trigger:

  - wait_for_trigger:
      - platform: state
        entity_id:
          - sensor.myenergi_libbi_24049368_soc
        to: "{{ states('input_number.libbi_export_target') }}"
    timeout: "00:59:30"
    continue_on_timeout: false

Or the wait_template:

  - wait_template: "{{ is_state('sensor.myenergi_libbi_24049368_soc',input_number.libbi_export_target) }}"
    timeout: "00:59:30"
    continue_on_timeout: false

But neither seems to work (though I’m not sure I’m doing the wait_template correctly as the script immediately goes to current: 0 in the States listing but it doesn’t continue with the rest of the actions).

I’ll subscribe to the thread you linked anyway. It’s interesting that it’s a 2 year old stale bug that suddenly got traction again only 6 days ago!

Thanks very much for your help.

I’m new to HA. I’m looking to do exactly what you are dsmiscussing. Did you make progress with this integration?

No, I scrapped the whole script idea and moved it back into a single automation, but with some tweaks. Now there’s 4 different choose actions that set the target level into an input_number helper based on the trigger time:

actions:
  - choose:
      - conditions:
          - condition: trigger
            id:
              - "2030"
        sequence:
          - data:
              value: 50
            target:
              entity_id: input_number.libbi_export_target
            action: input_number.set_value

Then underneath the choose block is the main sequence of actions (this is what I was trying to move into a script), with a template trigger that waits for the SoC to be equal or less than the target value helper:

wait_for_trigger:
  - value_template: >-
      {{ states('sensor.myenergi_libbi_24049368_soc') | int <=
      states('input_number.libbi_export_target') | int }}
    trigger: template

It’s tidier than what I had but doesn’t achieve the original plan of moving things to a script. In fact I’ve mostly abandoned scripts entirely, preferring to just streamline each automation as much as possible. I currently have 81 automations and only 4 scripts!

Appreciate that doesn’t really help you with your goal, but as far as I’m aware the bug described above was never fixed.

You would be better served starting your own thread with details about what your goal is, not how you think you’re going to do it.

Based on the title, this whole thread started from an impossible premise. Passed variables are accessed by templating and State triggers have never allowed templates.

Variables can be passed into scripts and used in Wait template or Wait for trigger, as long as you follow the rules for templating, variable scoping, and variable typing.

Stripped-down version of OP's automation/script combo
alias: Passing Export Target
description: ""
triggers:
  - trigger: time
    at:
      - "20:30:00"
      - "21:30:00"
      - "22:30:00"
      - "23:00:00"
conditions: []
actions:
  - variables:
      mapper:
        "20:30": 50
        "21:30": 40
        "22:30": 30
        "23:00": 25
      export: |
        {{ mapper.get((trigger.now|as_datetime).strftime('%H:%M')) }}
  - action: script.export
    data:
      export_target: "{{ export }}"
mode: single

The fields block shown in the script example below is not required, but it makes the script easier to use as an action when using the visual editors or Action tool.

sequence:
# PRE-WAIT SCRIPT ACTIONS

  - wait_for_trigger:
      - value_template: >-
          {{ states('sensor.example_soc')|float(0) <= export_target }}
        trigger: template
    timeout: "00:59:30"
    continue_on_timeout: false

# POST-WAIT SCRIPT ACTIONS

fields:
  export_target:
    selector:
      number:
        min: 0
        max: 100
        step: 1
    name: Export Target
    default: 0
    required: true
alias: Export to Target
description: ""
1 Like