IKEA STYRBAR Remote (E2002) for Matter

Trigger actions from the four buttons on an IKEA STYRBAR remote control. Tap, long press and long release are supported on the up/down buttons, and tap is supported on the left/right buttons. Requires an IKEA DIRIGERA hub connected to Home Assistant via the Matter integration.

This remote is more than a little strange in the way it sends events to Home Assistant, which results in some unusual behaviour that I have not found a way to work around:

  1. initial_press events are sent immediately when any button is pressed, regardless of whether the button is tapped or held down. This means the only way to distinguish between a tap and a long press is to look for the short_release event. Because of this, tap events for the up and down buttons are processed when the button is released, not when it is pressed. Why just up and down? Because…

  2. …the left and right buttons only send initial_press events, so there are no long press or long release actions for these buttons. This also means that tap events for the left and right buttons are processed when the button is pressed, not when it is released as with the up and down buttons. This is great, except…

  3. …if either the left or right button is held down, the remote only sends a short_release event for the ‘up’ button. So yes, this means that holding either of these buttons will trigger the tap action for the up button instead. And no, I have no idea why it works like this. I don’t send the events, I just deal with what shows up!

One issue that could be worked around is that this remote regularly sends duplicate events for the same button press. The Lockout Time provided in this blueprint is intended to remedy this by blocking any further button actions for the specified amount of time.

Based on Lorenzo Cecchelli’s ZHA blueprint for SOMRIG shortcut buttons. Adapted for STYRBAR and the Matter integration by Edward Wright.

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

blueprint:
  name: Matter - IKEA STYRBAR Remote control (Model E2002) V1.0
  description: Trigger actions from the four buttons on an IKEA STYRBAR
    remote control. Tap, long press and long release are supported on
    the up/down buttons, and tap is supported on the left/right buttons.
    Requires an IKEA DIRIGERA hub connected to Home Assistant via the
    [Matter integration](https://www.home-assistant.io/integrations/matter).
  

    This remote is more than a little strange in the way it sends events
    to Home Assistant, which results in some unusual behaviour that I have
    not found a way to work around.


    1) 'initial_press' events are sent immediately when any button is pressed,
    regardless of whether the button is tapped or held down.  This means
    the only way to distinguish between a tap and a long press is to look
    for the 'short_release' event.  Because of this, tap events for the
    up and down buttons are processed when the button is released, not
    when it is pressed.  Why just up and down?  Because...

    
    2) ...the left and right buttons only send 'initial_press' events, so
    there are no long press or long release actions for these buttons.  This
    also means that tap events for the left and right buttons are processed
    when the button is pressed, not when it is released as with the up and
    down buttons.  This is great, except...

    
    3) ...if either the left or right button is held down, the remote only sends
    a 'short_release' event for the 'up' button.  So yes, this means that holding
    either of these buttons will trigger the tap action for the up button instead.
    And no, I have no idea why it works like this.  I don't send the events, I
    just deal with what shows up!


    One issue that could be worked around is that this remote regularly sends
    duplicate events for the same button press.  The Lockout Time provided in
    this blueprint is intended to remedy this by blocking any further button
    actions for the specified amount of time.  


    Based on [Lorenzo Cecchelli](https://community.home-assistant.io/u/cecche/summary)'s
    [ZHA blueprint](https://community.home-assistant.io/t/ikea-somrig-remote-e2213-zha/668671)
    for SOMRIG shortcut buttons.  Adapted for STYRBAR and the Matter integration by
    [Edward Wright](https://community.home-assistant.io/u/fasteddy516/summary).
  author: Edward Wright
  domain: automation
  input:
    up_button:
      name: '"Up" Button Event'
      description: The entity corresponding to the up button event.
        (Up = "big sun" icon with detent)
      selector:
        entity:
          multiple: false
          filter:
            - integration: matter
              domain: event
              device_class: button
    down_button:
      name: '"Down" Button Event'
      description: The entity corresponding to the down button event.
        (Down = "little sun" icon with no detent)
      selector:
        entity:
          multiple: false
          filter:
            - integration: matter
              domain: event
              device_class: button
    left_button:
      name: '"Left" Button Event'
      description: The entity corresponding to the left button event.
      selector:
        entity:
          multiple: false
          filter:
            - integration: matter
              domain: event
              device_class: button
    right_button:
      name: '"Right" Button Event'
      description: The entity corresponding to the right button event.
      selector:
        entity:
          multiple: false
          filter:
            - integration: matter
              domain: event
              device_class: button
    lockout_time:
      name: Lockout Time
      description: The time to wait before accepting another button press after a
        button press has been detected. Use this to prevent multiple actions from
        being triggered by a single button press.
      default: 250
      selector:
        number:
          min: 0
          max: 1000
          unit_of_measurement: milliseconds
          mode: slider
    up_tap:
      name: "Action: Up > Tap"
      description: Triggered when the 'up' button is released.
        (Also triggered by holding the left or right button.)
      default: []
      selector:
        action: {}
    up_long_press:
      name: "Action: Up > Long Press"
      default: []
      selector:
        action: {}
    up_long_release:
      name: "Action: Up > Release after Long Press"
      default: []
      selector:
        action: {}
    down_tap:
      name: "Action: Down > Tap"
      description: Triggered when the 'down' button is released.
      default: []
      selector:
        action: {}
    down_long_press:
      name: "Action: Down > Long Press"
      default: []
      selector:
        action: {}
    down_long_release:
      name: "Action: Down > Release after Long Press"
      default: []
      selector:
        action: {}
    left_tap:
      name: "Action: Left > Tap"
      default: []
      selector:
        action: {}
    right_tap:
      name: "Action: Right > Tap"
      default: []
      selector:
        action: {}
mode: single
max_exceeded: silent
trigger:
- platform: state
  entity_id:
    - !input up_button
    - !input down_button
    - !input left_button
    - !input right_button
action:
  - variables:
      up: !input up_button
      down: !input down_button
      left: !input left_button
      right: !input right_button
  - choose:
    - conditions:
        - condition: template
          value_template: >-
            {{ trigger.to_state['attributes']['event_type'] == 'initial_press'
            }}
        - condition: template
          value_template: >-
            {{ trigger.entity_id == left
            }}
      sequence:
        - choose:
          - conditions:
              - condition: template
                value_template: >-
                  {{ trigger.entity_id == left
                  }}
            sequence: !input left_tap
        - delay:
            hours: 0
            minutes: 0
            seconds: 0
            milliseconds: !input lockout_time
    - conditions:
        - condition: template
          value_template: >-
            {{ trigger.to_state['attributes']['event_type'] == 'initial_press'
            }}
        - condition: template
          value_template: >-
            {{ trigger.entity_id == right
            }}
      sequence:
        - choose:
          - conditions:
              - condition: template
                value_template: >-
                  {{ trigger.entity_id == right
                  }}
            sequence: !input right_tap
        - delay:
            hours: 0
            minutes: 0
            seconds: 0
            milliseconds: !input lockout_time
    - conditions:
        - condition: template
          value_template: >-
            {{ trigger.to_state['attributes']['event_type'] == 'short_release'
            }}
      sequence:
        - choose:
          - conditions:
              - condition: template
                value_template: >-
                  {{ trigger.entity_id == up
                  }}
            sequence: !input up_tap
          - conditions:
              - condition: template
                value_template: >-
                  {{ trigger.entity_id == down
                  }}
            sequence: !input down_tap
        - delay:
            hours: 0
            minutes: 0
            seconds: 0
            milliseconds: !input lockout_time
    - conditions:
        - condition: template
          value_template: >-
            {{ trigger.to_state['attributes']['event_type'] == 'long_press'
            }}
      sequence:
        - choose:
          - conditions:
              - condition: template
                value_template: >-
                  {{ trigger.entity_id == up
                  }}
            sequence: !input up_long_press
          - conditions:
              - condition: template
                value_template: >-
                  {{ trigger.entity_id == down
                  }}
            sequence: !input down_long_press
        - delay:
            hours: 0
            minutes: 0
            seconds: 0
            milliseconds: !input lockout_time
    - conditions:
        - condition: template
          value_template: >-
            {{ trigger.to_state['attributes']['event_type'] == 'long_release'
            }}
      sequence:
        - choose:
          - conditions:
              - condition: template
                value_template: >-
                  {{ trigger.entity_id == up
                  }}
            sequence: !input up_long_release
          - conditions:
              - condition: template
                value_template: >-
                  {{ trigger.entity_id == down
                  }}
            sequence: !input down_long_release
        - delay:
            hours: 0
            minutes: 0
            seconds: 0
            milliseconds: !input lockout_time