Skip to content

Instantly share code, notes, and snippets.

@jroehl
Last active August 23, 2025 17:24
Show Gist options
  • Select an option

  • Save jroehl/0937c589c8d878bd945ee7ebe0a70f4b to your computer and use it in GitHub Desktop.

Select an option

Save jroehl/0937c589c8d878bd945ee7ebe0a70f4b to your computer and use it in GitHub Desktop.
blueprint:
name: Remote Light Control (ZHA) — Toggle+Dim (separate targets)
description: >
ZHA remote: short "on" uses time-based brightness; short "off" turns off.
Dimming (short/long) can target a different light/area/device.
domain: automation
input:
remote_device:
name: ZHA Remote
selector:
device:
integration: zha
toggle_target:
name: Toggle target (on/off)
selector:
target:
entity:
domain: light
dim_target:
name: Dimming target (up/down)
description: Can be different from toggle target.
selector:
target:
entity:
domain: light
enable_toggle:
name: Enable ON/OFF handling
default: true
selector: { boolean: {} }
enable_dimming:
name: Enable Dimming
default: true
selector: { boolean: {} }
# Turn-on profile (dual brightness by time)
brightness_inside_pct:
name: Brightness (inside window)
default: 60
selector: { number: { min: 1, max: 100, unit_of_measurement: "%", mode: slider } }
brightness_outside_pct:
name: Brightness (outside window)
default: 30
selector: { number: { min: 1, max: 100, unit_of_measurement: "%", mode: slider } }
color_temp_kelvin:
name: Color temperature (Kelvin) on turn_on
default: 2584
selector: { number: { min: 1500, max: 6500, unit_of_measurement: K, mode: slider } }
time_window_start:
name: Time window start
selector: { time: {} }
time_window_end:
name: Time window end
selector: { time: {} }
overnight_window:
name: Window crosses midnight
default: false
selector: { boolean: {} }
transition_sec:
name: Transition (seconds)
default: 1
selector: { number: { min: 0, max: 10, step: 0.1, unit_of_measurement: s, mode: slider } }
# Dimming settings
dim_step_pct:
name: Dimming step (% per short press)
default: 10
selector: { number: { min: 1, max: 50, unit_of_measurement: "%", mode: slider } }
long_press_multiplier:
name: Long-press multiplier
default: 2
selector: { number: { min: 1, max: 5, step: 1, mode: slider } }
feedback_notifications:
name: Show persistent notification on dim changes
default: false
selector: { boolean: {} }
mode: single
variables:
overnight: !input overnight_window
enable_toggle: !input enable_toggle
enable_dimming: !input enable_dimming
step: !input dim_step_pct
long_mult: !input long_press_multiplier
transition: !input transition_sec
color_temp: !input color_temp_kelvin
inside_pct: !input brightness_inside_pct
outside_pct: !input brightness_outside_pct
triggers:
# Toggle ON/OFF
- trigger: device
id: turn_off
device_id: !input remote_device
domain: zha
type: remote_button_short_press
subtype: turn_off
- trigger: device
id: turn_on
device_id: !input remote_device
domain: zha
type: remote_button_short_press
subtype: turn_on
# Dimming up/down (short/long)
- trigger: device
id: dim_up_short
device_id: !input remote_device
domain: zha
type: remote_button_short_press
subtype: dim_up
- trigger: device
id: dim_up_long
device_id: !input remote_device
domain: zha
type: remote_button_long_press
subtype: dim_up
- trigger: device
id: dim_down_short
device_id: !input remote_device
domain: zha
type: remote_button_short_press
subtype: dim_down
- trigger: device
id: dim_down_long
device_id: !input remote_device
domain: zha
type: remote_button_long_press
subtype: dim_down
actions:
- choose:
# === TURN ON inside window (non-overnight) ===
- conditions:
- condition: template
value_template: "{{ enable_toggle }}"
- condition: trigger
id: turn_on
- condition: template
value_template: "{{ not overnight }}"
- condition: time
after: !input time_window_start
before: !input time_window_end
sequence:
- service: light.turn_on
target: !input toggle_target
data:
brightness_pct: !input brightness_inside_pct
color_temp_kelvin: !input color_temp_kelvin
transition: !input transition_sec
# === TURN ON inside window (overnight) ===
- conditions:
- condition: template
value_template: "{{ enable_toggle }}"
- condition: trigger
id: turn_on
- condition: template
value_template: "{{ overnight }}"
- condition: or
conditions:
- condition: time
after: !input time_window_start
- condition: time
before: !input time_window_end
sequence:
- service: light.turn_on
target: !input toggle_target
data:
brightness_pct: !input brightness_inside_pct
color_temp_kelvin: !input color_temp_kelvin
transition: !input transition_sec
# === TURN ON outside window ===
- conditions:
- condition: template
value_template: "{{ enable_toggle }}"
- condition: trigger
id: turn_on
sequence:
- service: light.turn_on
target: !input toggle_target
data:
brightness_pct: !input brightness_outside_pct
color_temp_kelvin: !input color_temp_kelvin
transition: !input transition_sec
# === TURN OFF ===
- conditions:
- condition: template
value_template: "{{ enable_toggle }}"
- condition: trigger
id: turn_off
sequence:
- service: light.turn_off
target: !input toggle_target
data:
transition: !input transition_sec
# === DIM UP short ===
- conditions:
- condition: template
value_template: "{{ enable_dimming }}"
- condition: trigger
id: dim_up_short
sequence:
- service: light.turn_on
target: !input dim_target
data:
brightness_step_pct: !input dim_step_pct
transition: !input transition_sec
- if:
- condition: template
value_template: "{{ feedback_notifications }}"
then:
- service: persistent_notification.create
data:
title: "Brightness"
message: "Adjusted by +{{ step }}%"
# === DIM UP long ===
- conditions:
- condition: template
value_template: "{{ enable_dimming }}"
- condition: trigger
id: dim_up_long
sequence:
- service: light.turn_on
target: !input dim_target
data:
brightness_step_pct: "{{ step * long_mult }}"
transition: !input transition_sec
- if:
- condition: template
value_template: "{{ feedback_notifications }}"
then:
- service: persistent_notification.create
data:
title: "Brightness"
message: "Adjusted by +{{ step * long_mult }}%"
# === DIM DOWN short ===
- conditions:
- condition: template
value_template: "{{ enable_dimming }}"
- condition: trigger
id: dim_down_short
sequence:
- service: light.turn_on
target: !input dim_target
data:
brightness_step_pct: "{{ -1 * step }}"
transition: !input transition_sec
- if:
- condition: template
value_template: "{{ feedback_notifications }}"
then:
- service: persistent_notification.create
data:
title: "Brightness"
message: "Adjusted by -{{ step }}%"
# === DIM DOWN long ===
- conditions:
- condition: template
value_template: "{{ enable_dimming }}"
- condition: trigger
id: dim_down_long
sequence:
- service: light.turn_on
target: !input dim_target
data:
brightness_step_pct: "{{ -1 * step * long_mult }}"
transition: !input transition_sec
- if:
- condition: template
value_template: "{{ feedback_notifications }}"
then:
- service: persistent_notification.create
data:
title: "Brightness"
message: "Adjusted by -{{ step * long_mult }}%"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment