Use variables for automation triggers & conditions

I want to improve the efficiency of a script that manages a fan, and avoid repeating hard coded values.

So I tried to add variables:

alias: Ventilation SDB New
mode: restart
variables:
  max_dew: 14
  min_dew: '{{ max_dew - 0.2 }}'
  max_ext_dew: '10'
  ext_dew_limit: '{{ max_ext_dew - 0.2 }}'
description: Ventilation SDB
trigger:
  - platform: numeric_state
    entity_id: sensor.sdb_dewpoint
    above: '{{ max_dew }}'
    for:
      hours: 0
      minutes: 0
      seconds: 0
  - platform: numeric_state
    entity_id: sensor.sdb_dewpoint
    below: '13.8'
    for:
      hours: 0
      minutes: 0
      seconds: 0
  - platform: numeric_state
    entity_id: sensor.exterieur_dewpoint
    below: '10'
  - platform: numeric_state
    entity_id: sensor.exterieur_dewpoint
    above: '20'
  - platform: event
    event_type: homeassistant_start
action: null

In the first ā€˜aboveā€™ parameter in the sample code, I have written above: '{{ max_dew }}', but the UI complains with ā€œMessage malformed: expected float for dictionary value @ data[ā€˜aboveā€™]ā€ . I also tried above: "{% max_dew | float %}" and other variations without success.

My intent is to reuse these variables in action conditions as well.

Is this possible? If yes, what is the right way to do it?

Variables are only resolved after the trigger occurs. Secondly, you can only use templates in fields that allow templates.

1 Like

@petro Thank you for your answer.

I suggest you explain your endgoal. You can likely achieve what you want to acheive with a single automation using templates in other areas.

I manage the extraction fan in the bathroom using an automation that enables the fan if the absolute humidity is above a given level and the exterior humidity is below a certain level.

I already have the automation further below which works, but has the following side-effects:

  • While the fan is on, itā€™s filling up the log with the checks in the repeatā€¦while loop;
  • When changing a limit, I have to change it in multiple locations.

So I wanted to:

  • Use variables for the limits so that they are easier to adjust;
  • Not use a repeatā€¦until, but rather trigger on the hystereris levels and when the fan is on/off, check if it has to be turned off/on according to the hysteresis levels.
  • Continue to use a single automation.
alias: Ventilation SDB
description: Ventilation SDB
trigger:
  - platform: numeric_state
    entity_id: sensor.sdb_dewpoint
    above: '14'
    for:
      hours: 0
      minutes: 0
      seconds: 0
  - platform: numeric_state
    entity_id: sensor.exterieur_dewpoint
    below: '11.5'
  - platform: event
    event_type: homeassistant_start
condition:
  - condition: or
    conditions:
      - condition: and
        conditions:
          - condition: numeric_state
            entity_id: sensor.exterieur_dewpoint
            below: '11.5'
          - condition: numeric_state
            entity_id: sensor.sdb_dewpoint
            above: '14'
      - condition: state
        entity_id: light.sonoff_01minizb_4febc024_on_off
        state: 'on'
action:
  - type: turn_on
    device_id: 3c3d6f675c5d59e015c83cfd7d4282ed
    entity_id: light.sonoff_01minizb_4febc024_on_off
    domain: light
  - repeat:
      sequence:
        - delay:
            hours: 0
            minutes: 2
            seconds: 0
            milliseconds: 0
      while:
        - condition: and
          conditions:
            - condition: numeric_state
              entity_id: sensor.sdb_dewpoint
              above: '13.8'
            - condition: numeric_state
              entity_id: sensor.exterieur_dewpoint
              below: '10.5'
  - type: turn_off
    device_id: 3c3d6f675c5d59e015c83cfd7d4282ed
    entity_id: light.sonoff_01minizb_4febc024_on_off
    domain: light
mode: restart

The following trace shows an execution of this automation where I had the loop delay set to 15 seconds (which I now increased to 2 minutes):

You can make 2 input_numbers and use them in all those places. Secondly, is there any reason why you arenā€™t using a wait_for_trigger instead of the while loop? Use wait for trigger with 2 triggers and a timeout of 40 minutes where you continue on timeout.

example template trigger based on an input number

{{ states('sensor.exterieur_dewpoint') | float < states('input_number.exterieur_dewpoint_threshold') | float - 1.0 }}
  1. Ok, Iā€™ll try with input numbers - I thought that this would prompt the user to input numbers in the UI.
  2. I do not remember if I considered wait for trigger. I guess the main reason is that I am not intimate with this part of HA.

You can hide them from the UI.

I probably tried the ā€˜wait_for_triggerā€™ - the issue I had with it is that it only triggers when one of the values change, so not when the condition is already true when wait_for_trigger is evaluated.

Iā€™ll probably get away with it when used in a regular way, but when starting it manually, the fan is turned on (the condition is skipped) and not turning off while the humidity levels are low enough already.
I think I went with the solution that I could test.

For now, I am not using input numbers yet (as far as I understand they haved to be defined ā€œoutsideā€ the automation), but I have:

alias: Ventilation SDB
description: Ventilation SDB
trigger:
  - platform: numeric_state
    entity_id: sensor.sdb_dewpoint
    above: '14'
  - platform: numeric_state
    entity_id: sensor.exterieur_dewpoint
    below: '11.5'
  - platform: event
    event_type: homeassistant_start
    id: ha_restart
condition:
  - condition: or
    conditions:
      - condition: and
        conditions:
          - condition: numeric_state
            entity_id: sensor.exterieur_dewpoint
            below: '11.5'
          - condition: numeric_state
            entity_id: sensor.sdb_dewpoint
            above: '14'
      - condition: and
        conditions:
          - condition: state
            entity_id: light.sonoff_01minizb_4febc024_on_off
            state: 'on'
          - condition: trigger
            id: ha_restart
action:
  - type: turn_on
    device_id: 3c3d6f675c5d59e015c83cfd7d4282ed
    entity_id: light.sonoff_01minizb_4febc024_on_off
    domain: light
  - wait_for_trigger:
      - platform: template
        value_template: >-
          {{ states('sensor.sdb_dewpoint') | float < 13.8 or
          states('sensor.exterieur_dewpoint') | float > 12 }}
  - type: turn_off
    device_id: 3c3d6f675c5d59e015c83cfd7d4282ed
    entity_id: light.sonoff_01minizb_4febc024_on_off
    domain: light
mode: restart

While the wait_for_trigger did not have a timeout specified and I did not intervene on the automation (no update, no cancel), the trace shows the 'wait_for_trigger` was canceled, so the fan continued running beyond 12:45PM at which time the trigger condition was met:

.

I am going to test this one more time without changing the automation.

your automation is set to restart. Change your automation to single.

Ok, Iā€™ll change it to single which will not hurt due to the changes.

However the automation documentation about modes does not hint there is a difference between restart and single regarding the observed cancelation.

The first line in the docs you linked state what it does.

vs single

Even the image shows you what it does

image

Hereā€™s a previous post of mine how I run a bathroom fan based on humidity.

Uses average humidity inside and a binary sensor + automation.