blueprint:
  name: Ikea BILRESA scroll wheel (sensors for scroll, events for press)
  description: "Ikea BILRESA blueprint met 3 kanalen.\n\n- Scroll links/rechts gebruikt
    sensor.*current_switch_position_* (pulse 0/1).\n  Alleen rising edge (0->1) triggert,
    dus per klik exact 1 stap en direct.\n- Druk op scrollwiel blijft event.* gebruiken
    zodat single/double/long/hold blijft werken.\n"
  domain: automation
  input:
    remote:
      name: Remote
      description: Ikea BILRESA remote control device
      selector:
        device:
          multiple: false
    channel1_section:
      name: Kanaal 1
      collapsed: true
      input:
        click_action_ch1:
          name: 'Kanaal 1: click actie'
          default: []
          selector:
            action: {}
        double_click_action_ch1:
          name: 'Kanaal 1: double click actie'
          default: []
          selector:
            action: {}
        long_click_action_ch1:
          name: 'Kanaal 1: long press actie'
          default: []
          selector:
            action: {}
        on_hold_action_ch1:
          name: 'Kanaal 1: on-hold actie'
          description: Herhaalt totdat losgelaten, zie on_hold_delay
          default: []
          selector:
            action: {}
        scroll_wheel_target_ch1:
          name: 'Kanaal 1: scroll target(s)'
          description: Light of media_player die je met het wiel wilt bedienen
          default: []
          selector:
            entity:
              multiple: true
              filter:
              - domain:
                - light
                - media_player
              reorder: false
        scroll_wheel_mode_ch1:
          name: 'Kanaal 1: scroll mode'
          default: 'lights: dim'
          selector:
            select:
              options:
              - 'lights: dim'
              - 'lights: color temp and color hue'
              - 'lights: color temp only'
              - 'lights: color hue only'
              - 'media: volume control'
              custom_value: false
              multiple: false
              sort: false
    channel2_section:
      name: Kanaal 2
      collapsed: true
      input:
        click_action_ch2:
          name: 'Kanaal 2: click actie'
          default: []
          selector:
            action: {}
        double_click_action_ch2:
          name: 'Kanaal 2: double click actie'
          default: []
          selector:
            action: {}
        long_click_action_ch2:
          name: 'Kanaal 2: long press actie'
          default: []
          selector:
            action: {}
        on_hold_action_ch2:
          name: 'Kanaal 2: on-hold actie'
          description: Herhaalt totdat losgelaten, zie on_hold_delay
          default: []
          selector:
            action: {}
        scroll_wheel_target_ch2:
          name: 'Kanaal 2: scroll target(s)'
          default: []
          selector:
            entity:
              multiple: true
              filter:
              - domain:
                - light
                - media_player
              reorder: false
        scroll_wheel_mode_ch2:
          name: 'Kanaal 2: scroll mode'
          default: 'lights: dim'
          selector:
            select:
              options:
              - 'lights: dim'
              - 'lights: color temp and color hue'
              - 'lights: color temp only'
              - 'lights: color hue only'
              - 'media: volume control'
              custom_value: false
              multiple: false
              sort: false
    channel3_section:
      name: Kanaal 3
      collapsed: true
      input:
        click_action_ch3:
          name: 'Kanaal 3: click actie'
          default: []
          selector:
            action: {}
        double_click_action_ch3:
          name: 'Kanaal 3: double click actie'
          default: []
          selector:
            action: {}
        long_click_action_ch3:
          name: 'Kanaal 3: long press actie'
          default: []
          selector:
            action: {}
        on_hold_action_ch3:
          name: 'Kanaal 3: on-hold actie'
          description: Herhaalt totdat losgelaten, zie on_hold_delay
          default: []
          selector:
            action: {}
        scroll_wheel_target_ch3:
          name: 'Kanaal 3: scroll target(s)'
          default: []
          selector:
            entity:
              multiple: true
              filter:
              - domain:
                - light
                - media_player
              reorder: false
        scroll_wheel_mode_ch3:
          name: 'Kanaal 3: scroll mode'
          default: 'lights: dim'
          selector:
            select:
              options:
              - 'lights: dim'
              - 'lights: color temp and color hue'
              - 'lights: color temp only'
              - 'lights: color hue only'
              - 'media: volume control'
              custom_value: false
              multiple: false
              sort: false
    global_section:
      name: Globale instellingen
      collapsed: true
      input:
        dim_step_pct:
          name: Dimmer stapgrootte (%)
          default: 5
          selector:
            number:
              mode: box
              step: 1.0
        dim_min_pct:
          name: Minimum brightness (%)
          default: 5
          selector:
            number:
              mode: box
              step: 1.0
        min_color_temp:
          name: Minimum kleurtemperatuur (K)
          default: 2200
          selector:
            number:
              mode: box
              step: 1.0
        max_color_temp:
          name: Maximum kleurtemperatuur (K)
          default: 4000
          selector:
            number:
              mode: box
              step: 1.0
        color_temp_step:
          name: Kleurtemperatuur stap (K)
          default: 100
          selector:
            number:
              mode: box
              step: 1.0
        color_hue_step:
          name: Hue stap (graden, 0..360)
          default: 4
          selector:
            number:
              mode: box
              step: 1.0
        color_saturation:
          name: Saturation (%)
          default: 100
          selector:
            number:
              mode: box
              step: 1.0
        on_hold_delay:
          name: On-hold delay (sec)
          default: 0.1
          selector:
            number:
              mode: box
              step: 0.1
        volume_step_pct:
          name: Volume stap (%)
          default: 2
          selector:
            number:
              mode: box
              step: 1.0
        volume_max_pct:
          name: Max volume (%)
          default: 50
          selector:
            number:
              mode: box
              step: 1.0
  source_url: https://raw.githubusercontent.com/BoGu5/ha-blueprints/a688916fc161affcb2577e1ed90bb4f7ecf778fb/kea%20BILRESA%20scroll%20wheel%20(sensors%20for%20scroll%2C%20events%20for%20press)
alias: Ikea_BILRESA_scroll_wheel
mode: queued
max: 50
max_exceeded: silent
trigger:
- trigger: event
  event_type: state_changed
  event_data:
    entity_id: '{{ var_press_event_ch1 }}'
  id: press_ch1
- trigger: event
  event_type: state_changed
  event_data:
    entity_id: '{{ var_press_event_ch2 }}'
  id: press_ch2
- trigger: event
  event_type: state_changed
  event_data:
    entity_id: '{{ var_press_event_ch3 }}'
  id: press_ch3
- trigger: event
  event_type: state_changed
  event_data:
    entity_id: '{{ var_scroll_right_sensor_ch1 }}'
  id: scroll_right_ch1
- trigger: event
  event_type: state_changed
  event_data:
    entity_id: '{{ var_scroll_right_sensor_ch2 }}'
  id: scroll_right_ch2
- trigger: event
  event_type: state_changed
  event_data:
    entity_id: '{{ var_scroll_right_sensor_ch3 }}'
  id: scroll_right_ch3
- trigger: event
  event_type: state_changed
  event_data:
    entity_id: '{{ var_scroll_left_sensor_ch1 }}'
  id: scroll_left_ch1
- trigger: event
  event_type: state_changed
  event_data:
    entity_id: '{{ var_scroll_left_sensor_ch2 }}'
  id: scroll_left_ch2
- trigger: event
  event_type: state_changed
  event_data:
    entity_id: '{{ var_scroll_left_sensor_ch3 }}'
  id: scroll_left_ch3
condition:
- condition: template
  value_template: "{% set o = trigger.event.data.old_state %} {% set n = trigger.event.data.new_state
    %} {{ o is not none and n is not none\n   and o.state not in ['unavailable','unknown']\n
    \  and n.state not in ['unavailable','unknown'] }}"
variables:
  targets_entities_ch1: !input scroll_wheel_target_ch1
  targets_entities_ch2: !input scroll_wheel_target_ch2
  targets_entities_ch3: !input scroll_wheel_target_ch3
  scroll_wheel_mode_ch1: !input scroll_wheel_mode_ch1
  scroll_wheel_mode_ch2: !input scroll_wheel_mode_ch2
  scroll_wheel_mode_ch3: !input scroll_wheel_mode_ch3
  var_min_pct: !input dim_min_pct
  var_dim_step_pct: !input dim_step_pct
  var_color_hue_step: !input color_hue_step
  var_color_saturation: !input color_saturation
  var_min_color_temp: !input min_color_temp
  var_max_color_temp: !input max_color_temp
  var_color_temp_step: !input color_temp_step
  var_on_hold_delay: !input on_hold_delay
  var_volume_step_pct: !input volume_step_pct
  var_volume_max_pct: !input volume_max_pct
action:
- variables:
    channel: '{% if trigger.id in [''press_ch1'',''scroll_left_ch1'',''scroll_right_ch1'']
      %}ch1 {% elif trigger.id in [''press_ch2'',''scroll_left_ch2'',''scroll_right_ch2'']
      %}ch2 {% elif trigger.id in [''press_ch3'',''scroll_left_ch3'',''scroll_right_ch3'']
      %}ch3 {% else %}unknown{% endif %}'
    is_press: '{{ trigger.id is match(''^press_'') }}'
    is_scroll: '{{ trigger.id is match(''^scroll_'') }}'
    scroll_dir: '{% if trigger.id in [''scroll_left_ch1'',''scroll_left_ch2'',''scroll_left_ch3'']
      %}left {% elif trigger.id in [''scroll_right_ch1'',''scroll_right_ch2'',''scroll_right_ch3'']
      %}right {% else %}none{% endif %}'
    pulse_rising: '{% set o = trigger.event.data.old_state.state %} {% set n = trigger.event.data.new_state.state
      %} {{ (o in [''0'',''off''] and n in [''1'',''on'']) }}'
    scroll_steps: '{{ 1 if (is_scroll and pulse_rising) else 0 }}'
    press_event_type: "{% if is_press %}\n  {{ trigger.event.data.new_state.attributes.event_type
      | default('') }}\n{% else %}\n  {{ '' }}\n{% endif %}"
- choose:
  - conditions:
    - condition: template
      value_template: '{{ is_press and press_event_type == ''multi_press_1'' }}'
    sequence:
    - choose:
      - conditions: '{{ channel == ''ch1'' }}'
        sequence: !input click_action_ch1
      - conditions: '{{ channel == ''ch2'' }}'
        sequence: !input click_action_ch2
      - conditions: '{{ channel == ''ch3'' }}'
        sequence: !input click_action_ch3
  - conditions:
    - condition: template
      value_template: '{{ is_press and press_event_type == ''multi_press_2'' }}'
    sequence:
    - choose:
      - conditions: '{{ channel == ''ch1'' }}'
        sequence: !input double_click_action_ch1
      - conditions: '{{ channel == ''ch2'' }}'
        sequence: !input double_click_action_ch2
      - conditions: '{{ channel == ''ch3'' }}'
        sequence: !input double_click_action_ch3
  - conditions:
    - condition: template
      value_template: '{{ is_press and press_event_type == ''long_press'' }}'
    sequence:
    - choose:
      - conditions: '{{ channel == ''ch1'' }}'
        sequence:
        - sequence: !input long_click_action_ch1
        - repeat:
            while: "{{ repeat.index < 500\n   and state_attr(var_press_event_ch1,
              'event_type') == 'long_press' }}"
            sequence:
            - sequence: !input on_hold_action_ch1
            - delay: '{{ var_on_hold_delay }}'
      - conditions: '{{ channel == ''ch2'' }}'
        sequence:
        - sequence: !input long_click_action_ch2
        - repeat:
            while: "{{ repeat.index < 500\n   and state_attr(var_press_event_ch2,
              'event_type') == 'long_press' }}"
            sequence:
            - sequence: !input on_hold_action_ch2
            - delay: '{{ var_on_hold_delay }}'
      - conditions: '{{ channel == ''ch3'' }}'
        sequence:
        - sequence: !input long_click_action_ch3
        - repeat:
            while: "{{ repeat.index < 500\n   and state_attr(var_press_event_ch3,
              'event_type') == 'long_press' }}"
            sequence:
            - sequence: !input on_hold_action_ch3
            - delay: '{{ var_on_hold_delay }}'
  - conditions:
    - condition: template
      value_template: '{{ is_scroll and scroll_steps > 0 and scroll_dir in [''left'',''right'']
        }}'
    sequence:
    - repeat:
        for_each: '{{ (targets_entities_ch1 if channel == ''ch1'' else (targets_entities_ch2
          if channel == ''ch2'' else targets_entities_ch3)) }}'
        sequence:
        - choose:
          - conditions:
            - condition: template
              value_template: '{{ (scroll_wheel_mode_ch1 if channel == ''ch1'' else
                (scroll_wheel_mode_ch2 if channel == ''ch2'' else scroll_wheel_mode_ch3))
                == ''lights: dim'' }}'
            sequence:
            - if:
              - condition: template
                value_template: '{{ is_state(repeat.item, ''on'') }}'
              then:
              - action: light.turn_on
                target:
                  entity_id: '{{ repeat.item }}'
                data:
                  brightness_step_pct: "{% if scroll_dir == 'right' %}\n  {{ scroll_steps
                    * var_dim_step_pct }}\n{% else %}\n  {{ -1 * ([scroll_steps *
                    var_dim_step_pct,\n            state_attr(repeat.item, 'brightness')
                    * 100 / 254 - var_min_pct] | min) }}\n{% endif %}"
                  transition: 0.1
          - conditions:
            - condition: template
              value_template: "{% set mode = (scroll_wheel_mode_ch1 if channel ==
                'ch1' else (scroll_wheel_mode_ch2 if channel == 'ch2' else scroll_wheel_mode_ch3))
                %} {{ mode == 'lights: color temp only'\n   or (mode == 'lights: color
                temp and color hue' and state_attr(repeat.item, 'color_temp_kelvin')
                is not none) }}"
            sequence:
            - action: script.light_color_temp_helper
              data:
                mode: '{{ ''down'' if scroll_dir == ''left'' else ''up'' }}'
                min_color_temp: '{{ var_min_color_temp }}'
                max_color_temp: '{{ var_max_color_temp }}'
                color_temp_step: '{{ var_color_temp_step * scroll_steps }}'
                target_light: '{{ repeat.item }}'
          - conditions:
            - condition: template
              value_template: "{% set mode = (scroll_wheel_mode_ch1 if channel ==
                'ch1' else (scroll_wheel_mode_ch2 if channel == 'ch2' else scroll_wheel_mode_ch3))
                %} {{ mode == 'lights: color hue only'\n   or (mode == 'lights: color
                temp and color hue' and state_attr(repeat.item, 'color_temp_kelvin')
                is none) }}"
            sequence:
            - action: script.light_color_hs_helper
              data:
                target_light: '{{ repeat.item }}'
                color_hue_step: '{{ var_color_hue_step * scroll_steps }}'
                color_saturation: '{{ var_color_saturation }}'
                mode: '{{ ''down'' if scroll_dir == ''left'' else ''up'' }}'
          - conditions:
            - condition: template
              value_template: '{{ (scroll_wheel_mode_ch1 if channel == ''ch1'' else
                (scroll_wheel_mode_ch2 if channel == ''ch2'' else scroll_wheel_mode_ch3))
                == ''media: volume control'' }}'
            sequence:
            - action: media_player.volume_set
              target:
                entity_id: '{{ repeat.item }}'
              data:
                volume_level: "{{ [[\n    (state_attr(repeat.item, 'volume_level')
                  | float(0)) * 100\n    + (1 if scroll_dir == 'right' else -1) *
                  scroll_steps * var_volume_step_pct,\n    var_volume_max_pct\n  ]
                  | min, 0] | max / 100 }}"
trigger_variables:
  var_remote: !input remote
  var_press_event_ch1: "{% for item in device_entities(var_remote) %}\n  {% set m
    = item | regex_findall(find='^event\\\\..+_3$') %}\n  {% if m | length > 0 %}{{
    m[0] }}{% endif %}\n{% endfor %}"
  var_press_event_ch2: "{% for item in device_entities(var_remote) %}\n  {% set m
    = item | regex_findall(find='^event\\\\..+_6$') %}\n  {% if m | length > 0 %}{{
    m[0] }}{% endif %}\n{% endfor %}"
  var_press_event_ch3: "{% for item in device_entities(var_remote) %}\n  {% set m
    = item | regex_findall(find='^event\\\\..+_9$') %}\n  {% if m | length > 0 %}{{
    m[0] }}{% endif %}\n{% endfor %}"
  var_scroll_right_sensor_ch1: "{% for item in device_entities(var_remote) %}\n  {%
    set m = item | regex_findall(find='^sensor\\\\..+current_switch_position_1$')
    %}\n  {% if m | length > 0 %}{{ m[0] }}{% endif %}\n{% endfor %}"
  var_scroll_left_sensor_ch1: "{% for item in device_entities(var_remote) %}\n  {%
    set m = item | regex_findall(find='^sensor\\\\..+current_switch_position_2$')
    %}\n  {% if m | length > 0 %}{{ m[0] }}{% endif %}\n{% endfor %}"
  var_scroll_right_sensor_ch2: "{% for item in device_entities(var_remote) %}\n  {%
    set m = item | regex_findall(find='^sensor\\\\..+current_switch_position_4$')
    %}\n  {% if m | length > 0 %}{{ m[0] }}{% endif %}\n{% endfor %}"
  var_scroll_left_sensor_ch2: "{% for item in device_entities(var_remote) %}\n  {%
    set m = item | regex_findall(find='^sensor\\\\..+current_switch_position_5$')
    %}\n  {% if m | length > 0 %}{{ m[0] }}{% endif %}\n{% endfor %}"
  var_scroll_right_sensor_ch3: "{% for item in device_entities(var_remote) %}\n  {%
    set m = item | regex_findall(find='^sensor\\\\..+current_switch_position_7$')
    %}\n  {% if m | length > 0 %}{{ m[0] }}{% endif %}\n{% endfor %}"
  var_scroll_left_sensor_ch3: "{% for item in device_entities(var_remote) %}\n  {%
    set m = item | regex_findall(find='^sensor\\\\..+current_switch_position_8$')
    %}\n  {% if m | length > 0 %}{{ m[0] }}{% endif %}\n{% endfor %}"
