Variables in Automation

I am trying to create an automation around a IKEA TRADFRI Shortcut Button.
The basics are already working (i.e. reacting on the events the button sends).
I have found the following blueprint, which reacts also on virtual double clicks, for which the device does not send events itself.
Following this blueprint I want to adapt my automation, however I am having trouble with the variables section.

My automation currently looks as follows:
- alias: Light - Tradfri Shortcut Button
  id: 'Light_tradfri_shortcut_button'
  variables:
    button_short: "1002"
    button_long: "1001"
    button_release: "1003"
  trigger:
    platform: event
    event_type: deconz_event
    event_data:
      id: tradfri_shortcut_button #ikea_e1812
  mode: restart
  max_exceeded: silent
  
  condition:
  # check that the button event is not empty
  - condition: template
    value_template: '{{ trigger.event.data.event not in ["","None"] }}'

  action:
  - variables:
      # adjusted debounce delay so that the resulting double press delay is exactly as specified by the user when running the action, taking also account of debouncing
      # make sure it never goes below the minimum double press delay
      adjusted_double_press_delay: "{{ [states('input_number.tradfri_double_press_delay') | int - states('input_number.tradfri_debounce_delay') | int, 100] | max }}"

      trigger_action: "{{ trigger.event.data.event }}"
      trigger_delta: "{{ (as_timestamp(now()) - as_timestamp((states('input_text.last_shortcut_button_event') | from_json).last_triggered if 'input_text.last_shortcut_button_event' is not none and (states('input_text.last_shortcut_button_event') | regex_match("^\{(\".*\": \".*\"(, )?)*\}$")) else "1970-01-01 00:00:00")) * 1000 }}""

  # debouncing - when automation is triggered multiple times, the last automation run is the one which completes execution, due to mode restart
  # therefore previous runs must wait for the debounce delay before executing any other action
  # if the delay expires and the automation is still running it means it's the last run and execution can continue
  - delay:
      milliseconds: states('input_number.tradfri_debounce_delay') | int
  - choose:
    - conditions: '{{ trigger_action | string in button_short }}'
      # Toggle Livingroom Rear
      sequence:
        - choose: 
            # if previous event was a short press
            - conditions: "{{ trigger_action | string in states('input_text.last_shortcut_button_event') and trigger_delta | int <= states('input_number.tradfri_double_press_delay') | int }}"
              sequence:
                # store the double press event in the last controller event helper
                - service: input_text.set_value
                  data:
                    entity_id: input_text.last_shortcut_button_event
                    value: '{{ {"trigger_action":"double_press","last_triggered":now() | string} | to_json }}'
                # run the double press action
                - service: light.toggle
                  entity_id: light.livingroom_front
          # previous event was not a short press
          default:
            # wait for the double press event to occur, within the provided delay
            # if the second press is received, automation is restarted
            - delay:
                milliseconds: '{{ adjusted_double_press_delay }}'
            # if delay expires, no second press was received, therefore run the short press action
            # run the short press action
            - service: light.toggle
              entity_id: light.livingroom_rear
    - conditions: '{{ trigger_action | string in button_long }}'
      # Toggle Livingroom Floor Lamp
      sequence:
        - service: light.toggle
          entity_id: light.livingroom_floor_lamp
    - conditions: '{{ trigger_action | string in button_release }}'
      sequence: []

But I am getting the following error checking my configuration:

Error loading /config/configuration.yaml: while parsing a block mapping
in "/config/automation/light.yaml", line 44, column 7
expected <block end>, but found '<scalar>'

Am I missinterpreting how the variable section is working? Is there a typo somewhere, that I am not seeing? I do have other automations using partialy similar variable trigger_action: '{{ trigger.event.data.click_type }}' which does work correctly.
In the documentation I can only find descriptions about variables within scripts, but not within automations.

Any help is welcome. Thank you.

Looks like it may be due to incorrect use of quotations in the line defining the trigger.delta variable.

It you use double-quotes inside a template, you must use single-quotes outside the template. Alternately, if you use single-quotes inside the template, use double-quotes outside the template.

In this case, there’s an invalid mix of single and double-quotes inside the template plus there are two consecutive double-quotes at the end. You need to fix all of that by following the rule I described.

Thank you very much for spotting this detail, so there was nothing wrong with the gernal understanding.
I did have a couple of follow on errors within the automation. In case anyone is intereseted in the working result, you can find the working automation below:

- alias: Light - Tradfri Shortcut Button
  id: 'Light_tradfri_shortcut_button'
  variables:
    button_short: "1002"
    button_long: "1001"
    button_release: "1003"
  trigger:
    platform: event
    event_type: deconz_event
    event_data:
      id: tradfri_shortcut_button #ikea_e1812
  mode: restart
  max_exceeded: silent
  
  condition:
  # check that the button event is not empty
  - condition: template
    value_template: '{{ trigger.event.data.event not in ["","None"] }}'

  action:
  - variables:
      # adjusted debounce delay so that the resulting double press delay is exactly as specified by the user when running the action, taking also account of debouncing
      # make sure it never goes below the minimum double press delay
      adjusted_double_press_delay: "{{ [states('input_number.tradfri_double_press_delay') | int - states('input_number.tradfri_debounce_delay') | int, 100] | max }}"

      trigger_action: "{{ trigger.event.data.event }}"
      trigger_delta: '{{ (as_timestamp(now()) - as_timestamp((states("input_text.last_shortcut_button_event") | from_json).last_triggered if "input_text.last_shortcut_button_event" is not none and (states("input_text.last_shortcut_button_event") | regex_match("^\{(\".*\": \".*\"(, )?)*\}$")) else "1970-01-01 00:00:00")) * 1000 }}'

  # debouncing - when automation is triggered multiple times, the last automation run is the one which completes execution, due to mode restart
  # therefore previous runs must wait for the debounce delay before executing any other action
  # if the delay expires and the automation is still running it means it's the last run and execution can continue
  - delay:
      milliseconds: "{{ states('input_number.tradfri_debounce_delay') }}"
    # update helper
  - service: input_text.set_value
    data:
      entity_id: input_text.last_shortcut_button_event
      value: '{{ {"trigger_action":trigger_action,"last_triggered":now()|string} | to_json }}'
  - choose:
    - conditions: '{{ trigger_action | string in button_short }}'
      # Toggle Livingroom Rear
      sequence:
        - choose: 
            # if previous event was a short press
            - conditions: "{{ trigger_action | string in states('input_text.last_shortcut_button_event') and trigger_delta | int <= states('input_number.tradfri_double_press_delay') | int }}"
              sequence:
                # store the double press event in the last controller event helper
                - service: input_text.set_value
                  data:
                    entity_id: input_text.last_shortcut_button_event
                    value: '{{ {"trigger_action":"double_press","last_triggered":now() | string} | to_json }}'
                # run the double press action
                - service: light.toggle
                  entity_id: light.livingroom_front
          # previous event was not a short press
          default:
            # wait for the double press event to occur, within the provided delay
            # if the second press is received, automation is restarted
            - delay:
                milliseconds: '{{ adjusted_double_press_delay }}'
            # if delay expires, no second press was received, therefore run the short press action
            # run the short press action
            - service: light.toggle
              entity_id: light.livingroom_rear
    - conditions: '{{ trigger_action | string in button_long }}'
      # Toggle Livingroom Floor Lamp
      sequence:
        - service: light.toggle
          entity_id: light.livingroom_floor_lamp
    - conditions: '{{ trigger_action | string in button_release }}'
      sequence: []

Also thanks to @epmatt who generated the blueprint in a first place.

2 Likes