Z2M - IKEA STYRBAR remote for multiple lights

So, I bought a IKEA Styrbar remote and wanted to use it to control the brightness of multiple lights with the ability to extend it to more lights (relatively) easily. As I did not find any solution for that, here is the blueprint:

blueprint:
  name: IKEA STYRBAR - multi light control
  description: Control multiple lights with IKEA Styrbar Remote over Zigebee2MQTT
  domain: automation
  input:
    remote:
      name: Styrbar-Remote Action Entity
      selector:
        entity:
          filter:
            - domain: sensor
              integration: mqtt
    light_id_entity:
      name: Input Number for selected light index
      selector:
        entity:
          multiple: false
          filter:
            - domain: input_number
    light_number_entity:
      name: Input Number for amount of lights you want to control
      selector:
        entity:
          multiple: false
          filter:
            - domain: input_number
    light_id:
      name: Index of this light in the list of lights you want to control
      selector:
        number:
          min: 0
          max: 100
          mode: box
    light:
      name: Styrbar-Remote Action Entity
      selector:
        entity:
          multiple: false
          filter:
            - domain: light
    arrow_left_hold_action:
      name: Arrow left hold action
      selector:
        action:
      default: []
    arrow_left_release_action:
      name: Arrow left release action
      selector:
        action:
      default: []
    arrow_right_hold_action:
      name: Arrow right hold action
      selector:
        action:
      default: []
    arrow_right_release_action:
      name: Arrow right release action
      selector:
        action:
      default: []
    increase_delay:
      name: Delay after increasing the light index (ms)
      selector:
        number:
          min: 0
          max: 1000
      default: 100
    force_brightness:
      name: If you want to set the brightness to Brightness (%) percent for every 'on' command
      selector:
        boolean:
      default: false
    brightness_pct:
      name: Brightness (%) if force brightness is active
      selector:
        number:
          min: 0
          max: 100
      default: 50
    millis_delay:
      name: Brightness increment delay (ms)
      selector:
        number:
          min: 0
          max: 1000
      default: 150
    repeat_count:
      name: Iteration Count for Brightness increment
      selector:
        number:
          min: 0
          max: 100
      default: 20
    brightness_step:
      name: Step of brightness for each iteration (%)
      selector:
        number:
          min: 0
          max: 100
      default: 20
variables:
  light: !input light
  force_brightness: !input force_brightness
  bri_pct: !input brightness_pct
  light_id: !input light_id
  light_id_entity: !input light_id_entity
  light_number_entity: !input light_number_entity
  brightness_step: !input brightness_step
  repeat_count: !input repeat_count
  millis_delay: !input millis_delay
description: ""
trigger:
  - platform: state
    entity_id: !input remote
    to: "on"
    id: "on"
  - platform: state
    entity_id: !input remote
    to: "off"
    id: "off"
  - platform: state
    entity_id: !input remote
    to: brightness_move_up
    id: brightness_move_up
  - platform: state
    entity_id: !input remote
    to: brightness_move_down
    id: brightness_move_down
  - platform: state
    entity_id: !input remote
    to: brightness_stop
    id: brightness_stop
  - platform: state
    entity_id: !input remote
    to: arrow_left_click
    id: arrow_left_click
  - platform: state
    entity_id: !input remote
    to: arrow_left_hold
    id: arrow_left_hold
  - platform: state
    entity_id: !input remote
    to: arrow_left_release
    id: arrow_left_release
  - platform: state
    entity_id: !input remote
    to: arrow_right_click
    id: arrow_right_click
  - platform: state
    entity_id: !input remote
    to: arrow_right_hold
    id: arrow_right_hold
  - platform: state
    entity_id: !input remote
    to: arrow_right_release
    id: arrow_right_release
condition:
  - alias: "Light ID matching"
    condition: template
    value_template: "{{ states(light_id_entity) | int == light_id }}"
action:
  - choose:
      - conditions:
          - condition: trigger
            id:
              - "on"
          - condition: template
            value_template: "{{ force_brightness }}"
        sequence:
          - service: light.turn_on
            target:
              entity_id: "{{ light }}"
            data:
              brightness_pct: "{{ bri_pct }}"
        alias: "on_force"
      - conditions:
          - condition: trigger
            id:
              - "on"
        sequence:
          - service: light.turn_on
            target:
              entity_id: "{{ light }}"
        alias: "on"
      - conditions:
          - condition: trigger
            id:
              - "off"
        sequence:
          - service: light.turn_off
            target:
              entity_id: "{{ light }}"
        alias: "off"
      - conditions:
          - condition: trigger
            id:
              - brightness_move_up
        sequence:
          - repeat:
              count: "{{ repeat_count }}"
              sequence:
                - service: light.turn_on
                  metadata: {}
                  data:
                    brightness_step_pct: "{{ brightness_step }}"
                  target:
                    entity_id: "{{ light }}"
                - delay:
                    hours: 0
                    minutes: 0
                    seconds: 0
                    milliseconds: "{{ millis_delay }}"
        alias: brightness_move_up
      - conditions:
          - condition: trigger
            id:
              - brightness_move_down
        sequence:
          - repeat:
              count: "{{ repeat_count }}"
              sequence:
                - service: light.turn_on
                  metadata: {}
                  data:
                    brightness_step_pct: "{{ -brightness_step }}"
                  target:
                    entity_id: "{{ light }}"
                - delay:
                    hours: 0
                    minutes: 0
                    seconds: 0
                    milliseconds: "{{ millis_delay }}"
        alias: brightness_move_down
      - conditions:
          - condition: trigger
            id:
              - brightness_stop
        sequence: []
        alias: brightness_stop
      - conditions:
          - condition: trigger
            id:
              - arrow_left_click
        sequence:
          - choose:
              - conditions:
                  - condition: template
                    value_template: "{{ states(light_id_entity) | int <= 0 }}"
                sequence:
                  - delay:
                      hours: 0
                      minutes: 0
                      seconds: 0
                      milliseconds: !input increase_delay
                  - service: input_number.set_value
                    data_template:
                      entity_id: !input light_id_entity
                      value: "{{ states(light_number_entity) | int - 1 }}"
            default:
              - delay:
                  hours: 0
                  minutes: 0
                  seconds: 0
                  milliseconds: !input increase_delay
              - service: input_number.decrement
                entity_id: !input light_id_entity
        alias: arrow_left_click
      - conditions:
          - condition: trigger
            id:
              - arrow_left_hold
        sequence: []
        alias: arrow_left_hold
      - conditions:
          - condition: trigger
            id:
              - arrow_left_release
        sequence: []
        alias: arrow_left_release
      - conditions:
          - condition: trigger
            id:
              - arrow_right_click
        sequence:
          - choose:
              - conditions:
                  - condition: template
                    value_template: "{{ states(light_id_entity) | int >= states(light_number_entity) | int - 1 }}"
                sequence:
                  - delay:
                      hours: 0
                      minutes: 0
                      seconds: 0
                      milliseconds: !input increase_delay
                  - service: input_number.set_value
                    entity_id: !input light_id_entity
                    data:
                      value: 0
            default:
              - delay:
                  hours: 0
                  minutes: 0
                  seconds: 0
                  milliseconds: !input increase_delay
              - service: input_number.increment
                entity_id: !input light_id_entity
        alias: arrow_right_click
      - conditions:
          - condition: trigger
            id:
              - arrow_right_hold
        sequence: []
        alias: arrow_right_hold
      - conditions:
          - condition: trigger
            id:
              - arrow_right_release
        sequence: []
        alias: arrow_right_release
mode: restart

To use the blueprint, you need to add two input number helpers:

  1. An index for the currently selected light
  2. A number for the amount of lights that you want to control with this blueprint (you need to increment this one manually each time you add another light)

The configuration is relatively simple, you just add the action sensor of your Styrbar remote, the light you want to control, the two input number helpers configured above, and specify the index of the light (starting with 0).
You need to add an automation for each light you want to include and increase the index by 1 each time.

If you want your light to always start with the same brightness, you can specify it in the blueprint and set the boolean to true, so that the light brightness is forced each time. Otherwise the light will turn on with its last brightness value.

The other configuration options are mostly for possible problems that could arise. If you discover that two automations trigger simultaniously, increase the delay after increasing the light index, for me 100ms works great, which is why that is the default.

I don’t use the hold actions, but I included them in the inputs if you want to use those.

The mode of the blueprint is restart, as that is how the brightness control works here. The long press on brightness up or down triggers a loop (default 20 iterations) that increases the brightess by the specified percentage (default 5) and waits for some amount of time (default 150ms) in each iteration. When the brightness stop command comes, it restarts the automation and therefore intercepts the loop with the light being at the correct brightness.

As you may have noticed, this is a rather substential automation and not that easy to set up, but I wanted to share it anyway. Maybe it helps someone who wanted to achieve the same as me.

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