0.113 Choose Example

As you may have heard 0.113 included a revolutionary logic mechanism called “chooser”. It occurred to me that this could be a “better” way to handle multiple events, such that happens with scene buttons.

For example I have a Xiaomi switch which has two buttons built in. It can product the following events: left_single, left_double, right_single, right_double, both_single, both_double. Up until version 0.113 we could only accomplish this by using service_templates and data_templates and some complex template code. While I am proud of the solution I came up with, it always takes me time to wrap my head around it when I haven’t looked at the code in a while. The new “chooser” version I created may be longer, and perhaps less elegant, but I believe the purpose of the code will be clear quickly every time I revisit the code.

Pre-0.113 Template version

  - service_template: >
      {%- set clicks = trigger.event.data.command.split('_')[1]  %}

      {%- if clicks == "double" -%}
        switch.toggle
      {%- elif clicks == "single" -%}
        light.toggle
      {%- endif %}
    data_template:
      entity_id: >
        {%- set side = trigger.event.data.command.split('_')[0]  %}
        {%- set clicks = trigger.event.data.command.split('_')[1]  %}

        {%- set button_press = {
            "left": {
              "single": "light.bedroom",
              "double": "switch.sound_machine"
            },
            "right": {
              "single": "light.brian",
              "double": "switch.bedroom_fan"
            },
            "both": {
              "single": "light.bedroom_table_lamp",
              "double": "switch.sound_machine, switch.bedroom_fan"
            }
          }
        -%}
        {{ button_press[side][clicks] }}

Post 0.113 Choose version

    # Bedroom Double Switch
    - conditions:
      - condition: template
        value_template: "{{ trigger.event.data.device_ieee == '00:15:8d:00:02:83:e2:b6' }}"
      sequence:
        choose:
          # Single Click: Left
          - conditions:
            - condition: template
              value_template: "{{ trigger.event.data.command == 'left_single' }}"
            sequence:
              - service: light.toggle
                entity_id: light.bedroom
          # Single Click: Right
          - conditions:
            - condition: template
              value_template: "{{ trigger.event.data.command == 'right_single' }}"
            sequence:
              - service: light.toggle
                entity_id: light.brian
          # Single Click: Both
          - conditions:
            - condition: template
              value_template: "{{ trigger.event.data.command == 'both_single' }}"
            sequence:
              - service: light.toggle
                entity_id: light.bedroom_table_lamp
          # Double Click: Left
          - conditions:
            - condition: template
              value_template: "{{ trigger.event.data.command == 'left_double' }}"
            sequence:
              - service: switch.toggle
                entity_id: switch.sound_machine
          # Double Click: Right
          - conditions:
            - condition: template
              value_template: "{{ trigger.event.data.command == 'right_double' }}"
            sequence:
              - service: switch.toggle
                entity_id: switch.bedroom_fan
          # Double Click: Both
          - conditions:
            - condition: template
              value_template: "{{ trigger.event.data.command == 'both_double' }}"
            sequence:
              - service: switch.toggle
                entity_id:
                  - switch.sound_machine
                  - switch.bedroom_fan
4 Likes

Your pre-0.113 template version can be reduced to this:

  - service_template: homeassistant.toggle
    data_template:
      entity_id: >
        {% set entity = {'left_single': 'light.bedroom', 'right_single': 'light.brian',
                         'both_single': 'light.glowforge', 'left_double': 'switch.sound_machine',
                         'right_double': 'switch.bedroom_fan', 'both_double': 'switch.sound_machine, switch.family_room_fan'}
        {{ entity[trigger.event.data.args.value] if trigger.event.data.args.value in entity.keys() else 'none' }}

In this application, the service remains the same, the service uses no options, and only the entities change. That’s a good candidate for a traditional data_template.

Where choose becomes superior is when the service is not the same and each service uses a different set of options. For example, light.turn_on accepts many options but light_turn_off accepts none. Although a service_template can produce turn_on or turn_off, the data_template cannot add/subtract options. However, this situation is easily handled by using choose.

3 Likes

The chooser version is probably best for every day Home Assistant users, as it is easier to understand what the code is doing. Although as a programmer I love your elegant version!

P.S. Just to help any future Xiaomi Double Switch owners: due to an error in my orginal example (which has now been corrected) the correct value comes from trigger.event.data.command instead of trigger.event.data.args.value. Here @123’s improved code, with the correct value being evaluated.

  - service_template: homeassistant.toggle
    data_template:
      entity_id: >
        {% set entity = {'left_single': 'light.bedroom', 'right_single': 'light.brian', 'both_single': 'light.bedroom_table_lamp',
                         'left_double': 'switch.sound_machine', 'right_double': 'switch.bedroom_fan', 'both_double': 'switch.sound_machine, switch.bedroom_fan'}
        {{ entity[trigger.event.data.command] if trigger.event.data.command in entity.keys() else 'none' }}