Legrand ZLGP15 combo and double tap

this blueprint is compatible only with legrand 4 scenes ref:
0 677 55L/68L, 0 677 56L, 0 677 69L/87L, 0 770 26L, 6 000 84L, 7 418 02L, 7 418 32L, 7 418 62L, 5 742 88, 5 742 94, 5 743 23, 5 748 37 and new version

Open your Home Assistant instance and show the blueprint import dialog with a specific blueprint pre-filled.

blueprint:
  homeassistant:
    min_version: 2024.10.0
  name: Legrand ZLGP15 (simple + double tap + combo + combo double tap)
  description: >
    Advanced blueprint for battery-free wireless control of the Legrand ZLGP15 via Zigbee2MQTT.

    Use the MQTT /action topic of Zigbee2MQTT.

    Manages:
    - simple press : 1, 2, 3, 4
    - double press : 1, 2, 3, 4
    - combo : 1+3, 2+4, 1+4, 2+3
    - double press on combo : 1+3, 2+4, 1+4, 2+3

    Logic :
    1. Combo detection in a short window
    2. If a combo is found, wait for a second identical combo for a double tap combo.
    3. If there is no second combo, execute the simple combo.
    4. If there's no combo at the start, wait for a simple double tap.
    5. Otherwise simple support
  domain: automation

  input:
    controller:
      name: Controller Name
      description: Exact device name in Zigbee2MQTT
      selector:
        text: {}

    settings_section:
      name: Settings
      icon: mdi:cog-outline
      collapsed: true
      input:
        base_topic:
          name: Base topic (MQTT)
          description: Base topic configured in Zigbee2MQTT
          default: Zigbee2mqtt
          selector:
            text: {}

        combo_window:
          name: Combo window
          description: Time window to detect a combo
          default: 20
          selector:
            number:
              min: 5
              max: 100
              step: 5
              mode: box
              unit_of_measurement: ms

        double_tap_window:
          name: Double tap window
          description: Time window to detect a double tap
          default: 300
          selector:
            number:
              min: 50
              max: 600
              step: 10
              mode: box
              unit_of_measurement: ms

    simple_actions_section:
      name: Simple Actions
      icon: mdi:gesture-tap-button
      collapsed: false
      input:
        button_1_pressed:
          name: Button 1 Pressed
          default: []
          selector:
            action: {}
        button_2_pressed:
          name: Button 2 Pressed
          default: []
          selector:
            action: {}
        button_3_pressed:
          name: Button 3 Pressed
          default: []
          selector:
            action: {}
        button_4_pressed:
          name: Button 4 Pressed
          default: []
          selector:
            action: {}

    double_tap_actions_section:
      name: Double Tap Actions
      icon: mdi:gesture-double-tap
      collapsed: true
      input:
        button_1_double_pressed:
          name: Button 1 Double Pressed
          default: []
          selector:
            action: {}
        button_2_double_pressed:
          name: Button 2 Double Pressed
          default: []
          selector:
            action: {}
        button_3_double_pressed:
          name: Button 3 Double Pressed
          default: []
          selector:
            action: {}
        button_4_double_pressed:
          name: Button 4 Double Pressed
          default: []
          selector:
            action: {}

    combo_actions_section:
      name: Combo Actions
      icon: mdi:gesture-two-tap
      collapsed: true
      input:
        button_1_and_3_pressed:
          name: Buttons 1 and 3 Pressed
          default: []
          selector:
            action: {}
        button_2_and_4_pressed:
          name: Buttons 2 and 4 Pressed
          default: []
          selector:
            action: {}
        button_1_and_4_pressed:
          name: Buttons 1 and 4 Pressed
          default: []
          selector:
            action: {}
        button_2_and_3_pressed:
          name: Buttons 2 and 3 Pressed
          default: []
          selector:
            action: {}

    combo_double_tap_actions_section:
      name: Combo Double Tap Actions
      icon: mdi:gesture-double-tap
      collapsed: true
      input:
        button_1_and_3_double_pressed:
          name: Buttons 1 and 3 Double Pressed
          default: []
          selector:
            action: {}
        button_2_and_4_double_pressed:
          name: Buttons 2 and 4 Double Pressed
          default: []
          selector:
            action: {}
        button_1_and_4_double_pressed:
          name: Buttons 1 and 4 Double Pressed
          default: []
          selector:
            action: {}
        button_2_and_3_double_pressed:
          name: Buttons 2 and 3 Double Pressed
          default: []
          selector:
            action: {}

mode: single
max_exceeded: silent

trigger_variables:
  base_topic: !input base_topic
  controller: !input controller

triggers:
  - trigger: mqtt
    topic: "{{ base_topic ~ '/' ~ controller ~ '/action' }}"

conditions:
  - condition: template
    value_template: "{{ trigger.payload in ['press_1', 'press_2', 'press_3', 'press_4'] }}"

actions:
  - variables:
      command: "{{ trigger.payload }}"
      action_topic: "{{ base_topic ~ '/' ~ controller ~ '/action' }}"

  - choose:
      # ----------------------------------------------------------------------
      # BUTTON 1
      # ----------------------------------------------------------------------
      - conditions: "{{ command == 'press_1' }}"
        sequence:
          - wait_for_trigger:
              - trigger: mqtt
                topic: "{{ action_topic }}"
                payload: "press_3"
              - trigger: mqtt
                topic: "{{ action_topic }}"
                payload: "press_4"
            timeout:
              milliseconds: !input combo_window
            continue_on_timeout: true

          - choose:
              # Combo 1+3
              - conditions: "{{ wait.trigger is not none and wait.trigger.payload == 'press_3' }}"
                sequence:
                  - wait_for_trigger:
                      - trigger: mqtt
                        topic: "{{ action_topic }}"
                        payload: "press_1"
                      - trigger: mqtt
                        topic: "{{ action_topic }}"
                        payload: "press_3"
                    timeout:
                      milliseconds: !input double_tap_window
                    continue_on_timeout: true

                  - choose:
                      - conditions: "{{ wait.trigger is not none }}"
                        sequence:
                          - variables:
                              combo13_first: "{{ wait.trigger.payload }}"
                              combo13_expected: "{{ 'press_3' if wait.trigger.payload == 'press_1' else 'press_1' }}"
                          - wait_for_trigger:
                              - trigger: mqtt
                                topic: "{{ action_topic }}"
                                payload: "{{ combo13_expected }}"
                            timeout:
                              milliseconds: !input combo_window
                            continue_on_timeout: true
                          - choose:
                              - conditions: "{{ wait.trigger is not none }}"
                                sequence: !input button_1_and_3_double_pressed
                            default: !input button_1_and_3_pressed
                    default: !input button_1_and_3_pressed

              # Combo 1+4
              - conditions: "{{ wait.trigger is not none and wait.trigger.payload == 'press_4' }}"
                sequence:
                  - wait_for_trigger:
                      - trigger: mqtt
                        topic: "{{ action_topic }}"
                        payload: "press_1"
                      - trigger: mqtt
                        topic: "{{ action_topic }}"
                        payload: "press_4"
                    timeout:
                      milliseconds: !input double_tap_window
                    continue_on_timeout: true

                  - choose:
                      - conditions: "{{ wait.trigger is not none }}"
                        sequence:
                          - variables:
                              combo14_first: "{{ wait.trigger.payload }}"
                              combo14_expected: "{{ 'press_4' if wait.trigger.payload == 'press_1' else 'press_1' }}"
                          - wait_for_trigger:
                              - trigger: mqtt
                                topic: "{{ action_topic }}"
                                payload: "{{ combo14_expected }}"
                            timeout:
                              milliseconds: !input combo_window
                            continue_on_timeout: true
                          - choose:
                              - conditions: "{{ wait.trigger is not none }}"
                                sequence: !input button_1_and_4_double_pressed
                            default: !input button_1_and_4_pressed
                    default: !input button_1_and_4_pressed

            default:
              # Pas de combo -> test double appui simple
              - wait_for_trigger:
                  - trigger: mqtt
                    topic: "{{ action_topic }}"
                    payload: "press_1"
                timeout:
                  milliseconds: !input double_tap_window
                continue_on_timeout: true
              - choose:
                  - conditions: "{{ wait.trigger is not none }}"
                    sequence: !input button_1_double_pressed
                default: !input button_1_pressed

      # ----------------------------------------------------------------------
      # BUTTON 2
      # ----------------------------------------------------------------------
      - conditions: "{{ command == 'press_2' }}"
        sequence:
          - wait_for_trigger:
              - trigger: mqtt
                topic: "{{ action_topic }}"
                payload: "press_3"
              - trigger: mqtt
                topic: "{{ action_topic }}"
                payload: "press_4"
            timeout:
              milliseconds: !input combo_window
            continue_on_timeout: true

          - choose:
              # Combo 2+3
              - conditions: "{{ wait.trigger is not none and wait.trigger.payload == 'press_3' }}"
                sequence:
                  - wait_for_trigger:
                      - trigger: mqtt
                        topic: "{{ action_topic }}"
                        payload: "press_2"
                      - trigger: mqtt
                        topic: "{{ action_topic }}"
                        payload: "press_3"
                    timeout:
                      milliseconds: !input double_tap_window
                    continue_on_timeout: true

                  - choose:
                      - conditions: "{{ wait.trigger is not none }}"
                        sequence:
                          - variables:
                              combo23_first: "{{ wait.trigger.payload }}"
                              combo23_expected: "{{ 'press_3' if wait.trigger.payload == 'press_2' else 'press_2' }}"
                          - wait_for_trigger:
                              - trigger: mqtt
                                topic: "{{ action_topic }}"
                                payload: "{{ combo23_expected }}"
                            timeout:
                              milliseconds: !input combo_window
                            continue_on_timeout: true
                          - choose:
                              - conditions: "{{ wait.trigger is not none }}"
                                sequence: !input button_2_and_3_double_pressed
                            default: !input button_2_and_3_pressed
                    default: !input button_2_and_3_pressed

              # Combo 2+4
              - conditions: "{{ wait.trigger is not none and wait.trigger.payload == 'press_4' }}"
                sequence:
                  - wait_for_trigger:
                      - trigger: mqtt
                        topic: "{{ action_topic }}"
                        payload: "press_2"
                      - trigger: mqtt
                        topic: "{{ action_topic }}"
                        payload: "press_4"
                    timeout:
                      milliseconds: !input double_tap_window
                    continue_on_timeout: true

                  - choose:
                      - conditions: "{{ wait.trigger is not none }}"
                        sequence:
                          - variables:
                              combo24_first: "{{ wait.trigger.payload }}"
                              combo24_expected: "{{ 'press_4' if wait.trigger.payload == 'press_2' else 'press_2' }}"
                          - wait_for_trigger:
                              - trigger: mqtt
                                topic: "{{ action_topic }}"
                                payload: "{{ combo24_expected }}"
                            timeout:
                              milliseconds: !input combo_window
                            continue_on_timeout: true
                          - choose:
                              - conditions: "{{ wait.trigger is not none }}"
                                sequence: !input button_2_and_4_double_pressed
                            default: !input button_2_and_4_pressed
                    default: !input button_2_and_4_pressed

            default:
              - wait_for_trigger:
                  - trigger: mqtt
                    topic: "{{ action_topic }}"
                    payload: "press_2"
                timeout:
                  milliseconds: !input double_tap_window
                continue_on_timeout: true
              - choose:
                  - conditions: "{{ wait.trigger is not none }}"
                    sequence: !input button_2_double_pressed
                default: !input button_2_pressed

      # ----------------------------------------------------------------------
      # BUTTON 3
      # ----------------------------------------------------------------------
      - conditions: "{{ command == 'press_3' }}"
        sequence:
          - wait_for_trigger:
              - trigger: mqtt
                topic: "{{ action_topic }}"
                payload: "press_1"
              - trigger: mqtt
                topic: "{{ action_topic }}"
                payload: "press_2"
            timeout:
              milliseconds: !input combo_window
            continue_on_timeout: true

          - choose:
              # Combo 1+3
              - conditions: "{{ wait.trigger is not none and wait.trigger.payload == 'press_1' }}"
                sequence:
                  - wait_for_trigger:
                      - trigger: mqtt
                        topic: "{{ action_topic }}"
                        payload: "press_1"
                      - trigger: mqtt
                        topic: "{{ action_topic }}"
                        payload: "press_3"
                    timeout:
                      milliseconds: !input double_tap_window
                    continue_on_timeout: true

                  - choose:
                      - conditions: "{{ wait.trigger is not none }}"
                        sequence:
                          - variables:
                              combo31_first: "{{ wait.trigger.payload }}"
                              combo31_expected: "{{ 'press_3' if wait.trigger.payload == 'press_1' else 'press_1' }}"
                          - wait_for_trigger:
                              - trigger: mqtt
                                topic: "{{ action_topic }}"
                                payload: "{{ combo31_expected }}"
                            timeout:
                              milliseconds: !input combo_window
                            continue_on_timeout: true
                          - choose:
                              - conditions: "{{ wait.trigger is not none }}"
                                sequence: !input button_1_and_3_double_pressed
                            default: !input button_1_and_3_pressed
                    default: !input button_1_and_3_pressed

              # Combo 2+3
              - conditions: "{{ wait.trigger is not none and wait.trigger.payload == 'press_2' }}"
                sequence:
                  - wait_for_trigger:
                      - trigger: mqtt
                        topic: "{{ action_topic }}"
                        payload: "press_2"
                      - trigger: mqtt
                        topic: "{{ action_topic }}"
                        payload: "press_3"
                    timeout:
                      milliseconds: !input double_tap_window
                    continue_on_timeout: true

                  - choose:
                      - conditions: "{{ wait.trigger is not none }}"
                        sequence:
                          - variables:
                              combo32_first: "{{ wait.trigger.payload }}"
                              combo32_expected: "{{ 'press_3' if wait.trigger.payload == 'press_2' else 'press_2' }}"
                          - wait_for_trigger:
                              - trigger: mqtt
                                topic: "{{ action_topic }}"
                                payload: "{{ combo32_expected }}"
                            timeout:
                              milliseconds: !input combo_window
                            continue_on_timeout: true
                          - choose:
                              - conditions: "{{ wait.trigger is not none }}"
                                sequence: !input button_2_and_3_double_pressed
                            default: !input button_2_and_3_pressed
                    default: !input button_2_and_3_pressed

            default:
              - wait_for_trigger:
                  - trigger: mqtt
                    topic: "{{ action_topic }}"
                    payload: "press_3"
                timeout:
                  milliseconds: !input double_tap_window
                continue_on_timeout: true
              - choose:
                  - conditions: "{{ wait.trigger is not none }}"
                    sequence: !input button_3_double_pressed
                default: !input button_3_pressed

      # ----------------------------------------------------------------------
      # BUTTON 4
      # ----------------------------------------------------------------------
      - conditions: "{{ command == 'press_4' }}"
        sequence:
          - wait_for_trigger:
              - trigger: mqtt
                topic: "{{ action_topic }}"
                payload: "press_1"
              - trigger: mqtt
                topic: "{{ action_topic }}"
                payload: "press_2"
            timeout:
              milliseconds: !input combo_window
            continue_on_timeout: true

          - choose:
              # Combo 1+4
              - conditions: "{{ wait.trigger is not none and wait.trigger.payload == 'press_1' }}"
                sequence:
                  - wait_for_trigger:
                      - trigger: mqtt
                        topic: "{{ action_topic }}"
                        payload: "press_1"
                      - trigger: mqtt
                        topic: "{{ action_topic }}"
                        payload: "press_4"
                    timeout:
                      milliseconds: !input double_tap_window
                    continue_on_timeout: true

                  - choose:
                      - conditions: "{{ wait.trigger is not none }}"
                        sequence:
                          - variables:
                              combo41_first: "{{ wait.trigger.payload }}"
                              combo41_expected: "{{ 'press_4' if wait.trigger.payload == 'press_1' else 'press_1' }}"
                          - wait_for_trigger:
                              - trigger: mqtt
                                topic: "{{ action_topic }}"
                                payload: "{{ combo41_expected }}"
                            timeout:
                              milliseconds: !input combo_window
                            continue_on_timeout: true
                          - choose:
                              - conditions: "{{ wait.trigger is not none }}"
                                sequence: !input button_1_and_4_double_pressed
                            default: !input button_1_and_4_pressed
                    default: !input button_1_and_4_pressed

              # Combo 2+4
              - conditions: "{{ wait.trigger is not none and wait.trigger.payload == 'press_2' }}"
                sequence:
                  - wait_for_trigger:
                      - trigger: mqtt
                        topic: "{{ action_topic }}"
                        payload: "press_2"
                      - trigger: mqtt
                        topic: "{{ action_topic }}"
                        payload: "press_4"
                    timeout:
                      milliseconds: !input double_tap_window
                    continue_on_timeout: true

                  - choose:
                      - conditions: "{{ wait.trigger is not none }}"
                        sequence:
                          - variables:
                              combo42_first: "{{ wait.trigger.payload }}"
                              combo42_expected: "{{ 'press_4' if wait.trigger.payload == 'press_2' else 'press_2' }}"
                          - wait_for_trigger:
                              - trigger: mqtt
                                topic: "{{ action_topic }}"
                                payload: "{{ combo42_expected }}"
                            timeout:
                              milliseconds: !input combo_window
                            continue_on_timeout: true
                          - choose:
                              - conditions: "{{ wait.trigger is not none }}"
                                sequence: !input button_2_and_4_double_pressed
                            default: !input button_2_and_4_pressed
                    default: !input button_2_and_4_pressed

            default:
              - wait_for_trigger:
                  - trigger: mqtt
                    topic: "{{ action_topic }}"
                    payload: "press_4"
                timeout:
                  milliseconds: !input double_tap_window
                continue_on_timeout: true
              - choose:
                  - conditions: "{{ wait.trigger is not none }}"
                    sequence: !input button_4_double_pressed
                default: !input button_4_pressed

Hello Pepeuch,

Thanks for contributing to the community with a new Blueprint.
I have a suggestion for you. Many people who are not familiar with directory structures will have problems installing this without the Home Assistant MY tools.
Adding a MY link for this Blueprint to your top post would help them a lot.
Here is the link to make that.
Create a link – My Home Assistant

Hello, sorry for the missing link, I’ll create one. I didn’t think of it, but this is my first post here. I’ll take care of it as soon as possible.

1 Like

Link it’s ready :wink: