Variables in automations and mixing YAML/jinja

I am working on an automation to automatically open the correct garage door when I approach my home. I got it working for one vehicle but I want to expand it. I have three vehicles and three garage doors. The intention to use bluetooth connections to determine which vehicle I am driving. Then check whether the garage door is presently closed and if it is, open it.

I could do easily do this with a different automation for each vehicle, or perhaps with fairly lengthy “choose” actions, but there must be a more elegant way. And I want to learn more. So I have tried to define a variable called garage_door_num that will be assigned a “1” to “3” depending on which vehicle I am driving, and a “0” if none (eg I’m walking to the house) in which case no garage door should open.

This variable will end up being used twice:

  • first, in a condition to check the correct garage door is closed before trying to open it
  • second, in an action to open the correct garage door

I know I’m doing something wrong, and I think it is related to either the scope of variables or the scope of jinja vs YAML variables. Or the insertion of jinja expressions directly into YAML code, which I have done before but perhaps I’m doing it wrong this time.

According to this very useful post, YAML variables defined right after the trigger should have script-wide scope. Is this correct? So that’s what I am trying to go with.

Here’s the code so far:

description: "Open correct garage door for approaching vehicle"
mode: single
triggers:
  - trigger: zone
    entity_id: device_tracker.sm_s938b
    zone: zone.home
    event: enter
variables:  #1 is Jeep, #2 is VW, #3 is Audi, zero means no car connected
  garage_door_num: >  #according to documentation variables defined here have script-wide scope?
    {% if 'F8:6D:CC:A7:ED:2D (Uconnect-2c5266)' 
      in state_attr('sensor.sm_s938b_bluetooth_connection', 
     'connected_paired_devices') %}
      "1"
    {% elif '9C:8D:7C:32:6F:52 (VW BT 1706)' 
      in state_attr('sensor.sm_s938b_bluetooth_connection', 
     'connected_paired_devices') %}
      "2"
    {% elif '00:0E:9F:73:06:72 (Audi UHV 1671)' 
       in state_attr('sensor.sm_s938b_bluetooth_connection', 
       'connected_paired_devices') %}
      "3"
    {% else %}
      "0"
    {% endif %}
conditions:
  - condition: state  #check whether garage door is closed
    entity_id: binary_sensor.omnilink_garage_dr_{{ garage_door_num }}
    state:
      - "off"
  - condition: template
    value_template: "{{ garage_door_num != '0' }}"  #in which case no vehicle is connected
actions:
  - action: light.turn_on
    metadata: {}
    target:
      entity_id: light.omnilink_garagedr_{{ garage_door_num }}
    data: {}

The YAML parses as blue in the editor, but after I save I get “malformed” error:
malformed

I really enjoy learning all of this and the community is just incredibly helpful so far (thank you very much). In that spirit, anyone who feels like doing so please point out any areas where the code could be improved. I love learning this stuff.

(another question, is there any way to force the forum parser to show YAML coloring when I include a code block?)

  - condition: state  #check whether garage door is closed
    entity_id: binary_sensor.omnilink_garage_dr_{{ garage_door_num }}
    state:
      - "off"

The only conditions that allow templating are Template conditions… also, it’s best to avoid inline comments.

  - alias: check whether garage door is closed
    condition: template
    value_template: |
      {{ is_state('binary_sensor.omnilink_garage_dr_'~ garage_door_num, 'off') }}

I don’t know if the following was just for this post, but it would break your template:

garage_door_num: > #according to documentation variables defined here have script-wide scope?

description: "Open correct garage door for approaching vehicle"
mode: single
triggers:
  - trigger: zone
    entity_id: device_tracker.sm_s938b
    zone: zone.home
    event: enter
variables:  
  garage_door_num: >  
    {# according to documentation variables defined here have script-wide scope? #}
    {# #1 is Jeep, #2 is VW, #3 is Audi, zero means no car connected #}
    {% set connected = state_attr('sensor.sm_s938b_bluetooth_connection','connected_paired_devices')%}
    {% if 'F8:6D:CC:A7:ED:2D (Uconnect-2c5266)' in connected %}
      "1"
    {% elif '9C:8D:7C:32:6F:52 (VW BT 1706)' in connected %}
      "2"
    {% elif '00:0E:9F:73:06:72 (Audi UHV 1671)' in connected %}
      "3"
    {% else %}
      "0"
    {% endif %}
conditions:
  - alias: check whether garage door is closed
    condition: template
    value_template: |
      {{ is_state('binary_sensor.omnilink_garage_dr_'~ garage_door_num, 'off') }}
  - alias: In which case no vehicle is connected
    condition: template
    value_template: "{{ garage_door_num != '0' }}"
actions:
  - action: light.turn_on
    metadata: {}
    target:
      entity_id: light.omnilink_garagedr_{{ garage_door_num }}
    data: {}
1 Like

Thank you Didgeridrew on both counts, also the comment point.

To be clear then, is it correct to say that conditions only allow templates in template conditions, but actions allow more liberal use of inline templating?

thank you!!! I knew there should be a way to query the Bluetooth attributes more efficiently…
So much to learn. Much appreciated.

Yes, nearly all values for configuration variables in Actions can be templated.

However, there are both triggers and conditions other than the Template types that support templating for specific configuration variables… State Conditions and Triggers only support them in the for variable.

Community Guides - What the Heck is a Template…? - Where should I use templates?

1 Like