Switch scenes using Hue Dimmer Switch attached directly to ZHA

Use your ZHA-attached (no Hue Hub) Hue Dimmer Switches to cycle through scenes in a given area, and optionally control specific lights and switches with double and triple taps of the on and off buttons. This replicates as much as possible the behaviour of the dimmers with the Hue bridge where a repeated press on the on button will cycle through scenes, the off will turn the current devices off and the brightness buttons will do the expected thing. This uses home assistant scenes, so can control not only lights but also tasmota smart plugs and similar, so you can control a mix of smart bulbs and dumb devices attached to smart plugs from your dimmer switches.

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

blueprint:
  domain: automation
  name: Switch scenes with Philips Hue Dimmer Switch (RWL022 or RWL021)
  description: >  
    Control custom scenes within HA in the same way the Hue dimmer switches work for
    native Philips Hue scenes. If lights are on then the power button will cycle through
    scenes, if they're off it'll try to start the most recently used scene. Off button
    will turn off all lights in the most recently used scene's entity list, as will the
    brightness up / down control.
  input:
    zha_device_21:
      name: Dimmer switch
      description: Switch to use to control scenes (RWL021), use either this or the RWL022 entry below. If both are specified this will be used in preference.
      selector:
        device:
          filter:
            integration: zha
            model: RWL021
          entity:
            - domain: sensor
              device_class: battery
          multiple: false
      default: null
    zha_device_22:
      name: Dimmer switch
      description: Switch to use to control scenes (RWL022)
      selector:
        device:
          filter:
            integration: zha
            model: RWL022
          entity:
            - domain: sensor
              device_class: battery
          multiple: false
      default: null
    area:
      name: Area to control
      description: Scenes will be discovered from this area
      selector:
        area:
          multiple: false
    prefix:
      name: Scene name prefix
      description: Only scenes in this area matching this prefix will be used
      selector:
        text:
          multiline: false
          prefix: 'scene.'
          type: text
      default: ''
    transition_time:
      name: Transition time
      description: Time to move between scenes and switch on or off in seconds
      selector:
        number:
          min: 0
          max: 10
          step: 0.1
          unit_of_measurement: "seconds"
          mode: "slider"
      default: 1.0
    double_press_devices:
      name: Double press devices
      description: Specific lights and switches to control with double presses of the on and off buttons
      selector:
        target:
          entity:
            - domain: light
            - domain: switch
              integration: tasmota
      default: []
    triple_press_devices:
      name: Triple press devices
      description: Specific lights and tasmota smart-plugs to control with triple presses of the on and off buttons
      selector:
        target:
          entity:
            - domain: light
            - domain: switch
              integration: tasmota
      default: []
  source_url: https://gist.github.com/tomoinn/8be33ad4418a85998c7fb43264538e28
mode: queued
max_exceeded: silent
variables:
  device_id_21: !input zha_device_21
  device_id_22: !input zha_device_22
  device_id: >
    {% if device_id_21 is defined and device_id_21!=None %}
    {{ device_id_21 }}
    {% else %}
    {{ device_id_22 }}
    {% endif %}
trigger:
- platform: event
  event_type: zha_event
condition: '{{ trigger.event.data.device_id == device_id }}'
action:
- variables:
    prefix: !input prefix
    area: !input area
    command_type: '{{ trigger.event.data.command }}'
    double_press_devices: !input double_press_devices
    triple_press_devices: !input triple_press_devices
    all_scenes: >
      {{ states.scene |
         selectattr('entity_id', 'in', area_entities(area)) |
         selectattr('entity_id','match','^scene.'+prefix) |
         map(attribute='entity_id') | list }}
    unknown_scenes: >
      {{ expand(all_scenes) |
         selectattr('state','eq','unknown') |
         map(attribute='entity_id') | list }}
    known_scenes: >
      {{ expand(all_scenes) |
         rejectattr('state','eq','unknown') |
         sort(attribute='state', reverse=true) |
         map(attribute='entity_id') | list }}
    ordered_scenes: '{{ known_scenes + unknown_scenes }}'
    current_scene: >
      {% if known_scenes | count == 0 %}
        {{ '' }}
      {% else %}
        {{ ordered_scenes[0] }}
      {% endif %}
    next_scene: >
      {% if known_scenes | count == 0 %}
        {% if ordered_scenes | count > 0 %}
          {{ ordered_scenes[0] }}
        {% else %}
          {{ '' }}
        {% endif %}
      {% else %}
        {{ ordered_scenes[ordered_scenes | count -1] }}
      {% endif %}
    lights: >
      {% if current_scene == '' %}
        {{ [] }}
      {% else %}
        {{ state_attr(current_scene, 'entity_id') | expand | map(attribute='entity_id') | list }}
      {% endif %}
    lights_on: >
      {{ lights | expand | selectattr('state','eq','on') | map(attribute='state') | list | count > 0 }}
    transition_time: !input transition_time
- service: logbook.log
  data:
    name: all_scenes
    message: >
      Ordered scenes : {{ ordered_scenes }}
      Current scene: {{ current_scene }}
      Next scene: {{ next_scene }}
      Lights: {{ lights }}
      Lights on: {{ lights_on }}
- choose:
  - conditions: '{{ command_type == "on_double_press" }}'
    sequence:
    - service: light.turn_on
      target: '{{ double_press_devices }}'
      data:
        transition: '{{ transition_time }}'
    - service: switch.turn_on
      target: '{{ double_press_devices }}'
  - conditions: '{{ command_type == "off_double_press" }}'
    sequence:
    - service: light.turn_off
      target: '{{ double_press_devices }}'
      data:
        transition: '{{ transition_time }}'
    - service: switch.turn_off
      target: '{{ double_press_devices }}'
  - conditions: '{{ command_type == "on_triple_press" }}'
    sequence:
    - service: light.turn_on
      target: '{{ triple_press_devices }}'
      data:
        transition: '{{ transition_time }}'
    - service: switch.turn_on
      target: '{{ triple_press_devices }}'
  - conditions: '{{ command_type == "off_triple_press" }}'
    sequence:
    - service: light.turn_off
      target: '{{ triple_press_devices }}'
      data:
        transition: '{{ transition_time }}'
    - service: switch.turn_off
      target: '{{ triple_press_devices }}'
  - conditions: '{{ command_type == "on_press" and lights_on }}'
    sequence:
    - service: scene.turn_on
      data:
        transition: '{{ transition_time }}'
      target:
        entity_id: '{{ next_scene }}'
  - conditions: '{{ command_type == "on_press" and lights_on == false and current_scene != "" }}'
    sequence:
    - service: scene.turn_on
      data:
        transition: '{{ transition_time }}'
      target:
        entity_id: '{{ current_scene }}'
  - conditions: '{{ command_type == "off_press" and lights_on }}'
    sequence:
    - service: light.turn_off
      target:
        entity_id: '{{ lights }}'
      data:
        transition: '{{ transition_time }}'
    - service: switch.turn_off
      data:
        entity_id: '{{ lights }}'
  - conditions: '{{ command_type == "down_hold" or command_type == "down_short_release" }}'
    sequence:
    - service: light.turn_on
      data:
        brightness_step_pct: -15
        transition: 0.3
      target:
        entity_id: '{{ lights }}'

  - conditions: '{{ command_type == "up_hold" or command_type == "up_short_release" }}'
    sequence:
    - service: light.turn_on
      data:
        brightness_step_pct: 15
        transition: 0.3
      target:
        entity_id: '{{ lights }}'
2 Likes

Thanks for sharing this, this is almost exactly what I was looking for. Could you perhaps assist me with the following? I would like it if the lights are off, to always start with a certain scene, not the most recently used.

Background; I’ve just started to move away from the Hue hub (privacy/account etc) but would really this specific functionality. I’ve searched a lot but I’m not able to find a solution. Yours works very well, with my only problem being it always starts the last scene (when light is off and remote pressed) and I would like it to always start with a certain specific scene.

I tried some ‘manual’ automations but they were slow, and I found no good way to create an -if- statement which checks the current brightnesslevel or active scene.

I had the same wish and have now spent some time adapting the code…ok, ChatGPT helped me a lot :smiley:
But here you have a customized version. After a few tests it works perfectly for me.

Copy the Link and add the Blueprint in HA directly.

Link to the RAW Text