|
## This uses 2 separate DALI channels to control warm and cold LEDs and wraps them |
|
## as a single color temp light. |
|
## Some DALi dimmers (e.g. DA4-D) can dim 4 channels and have 4 DALI addresses, yet when switching to color temp mode they have |
|
## only 1 DALI address. This trade-off allows to control 2 lights with 2 DALI addresses and 1 dimmer (rather than 1 DALI address |
|
## and 1 dimmer) |
|
|
|
# Loads default set of integrations. Do not remove. |
|
default_config: |
|
|
|
# logger: |
|
# default: info |
|
|
|
# Load frontend themes from the themes folder |
|
frontend: |
|
themes: !include_dir_merge_named themes |
|
|
|
automation: !include automations.yaml |
|
# script: !include scripts.yaml |
|
scene: !include scenes.yaml |
|
|
|
modbus: |
|
- name: dlc02 |
|
type: tcp |
|
host: 192.168.31.27 |
|
port: 502 |
|
timeout: 5 |
|
|
|
switches: |
|
- name: "DLC02 Dummy Switch" |
|
slave: 255 |
|
address: 0 |
|
write_type: coil |
|
|
|
# --- Universal DALI Control Script --- |
|
script: |
|
control_dali_light: |
|
alias: "Universal DALI Light Controller" |
|
description: "Controls a DALI light, supporting dual-channel CCT (2ch) or single-address CCT." |
|
fields: |
|
light_type: |
|
description: "The type of DALI light. Can be 'cct_2ch' or 'cct'." |
|
dali_addr: |
|
description: "The DALI short address (for single-address lights)." |
|
dali_addr_ww: |
|
description: "The DALI short address for the Warm White channel (for CCT lights)." |
|
dali_addr_cw: |
|
description: "The DALI short address for the Cool White channel (for CCT lights)." |
|
brightness: |
|
description: "Overall brightness (0-255)." |
|
color_temp_mireds: |
|
description: "Color temperature in Mireds." |
|
bus_id: |
|
description: "DALI Bus ID (1 for Bus A, 2 for Bus B)." |
|
min_mireds: |
|
description: "The minimum mired value for this light." |
|
max_mireds: |
|
description: "The maximum mired value for this light." |
|
sequence: |
|
- choose: |
|
- conditions: |
|
- condition: template |
|
value_template: "{{ light_type == 'cct_2ch' }}" |
|
sequence: |
|
- variables: |
|
brightness_val: "{{ [[brightness | int(0), 0] | max, 255] | min }}" |
|
mireds_val: "{{ [ [ color_temp_mireds | int(262), min_mireds | int(154) ] | max, max_mireds | int(370) ] | min }}" |
|
min_mireds_val: "{{ min_mireds | int(154) }}" |
|
max_mireds_val: "{{ max_mireds | int(370) }}" |
|
warmth_ratio: "{{ (mireds_val - min_mireds_val) / (max_mireds_val - min_mireds_val) }}" |
|
ww_level_dali: "{{ [((brightness_val * (warmth_ratio | sqrt)) | round(0) | int), 254] | min }}" |
|
cw_level_dali: "{{ [((brightness_val * ((1 - warmth_ratio) | sqrt)) | round(0) | int), 254] | min }}" |
|
bus_prefix: "{{ (bus_id | int(1)) * 0x0100 }}" |
|
- service: modbus.write_register |
|
data: |
|
hub: dlc02 |
|
slave: 255 |
|
address: 41001 |
|
value: |
|
- "{{ bus_prefix + (dali_addr_ww | int) }}" |
|
- "{{ 0x0200 + ww_level_dali }}" |
|
- 0x0000 |
|
- 0x0000 |
|
- service: modbus.write_register |
|
data: |
|
hub: dlc02 |
|
slave: 255 |
|
address: 41001 |
|
value: |
|
- "{{ bus_prefix + (dali_addr_cw | int) }}" |
|
- "{{ 0x0200 + cw_level_dali }}" |
|
- 0x0000 |
|
- 0x0000 |
|
- conditions: |
|
- condition: template |
|
value_template: "{{ light_type == 'cct' }}" |
|
sequence: |
|
- variables: |
|
brightness_dali: "{{ [[brightness | int(0), 0] | max, 254] | min }}" |
|
mireds_clamped: "{{ [[color_temp_mireds | int(262), 154] | max, 500] | min }}" |
|
kelvin_val: "{{ (1000000 / mireds_clamped) | int(4000) }}" |
|
bus_prefix: "{{ (bus_id | int(1)) * 0x0100 }}" |
|
- service: modbus.write_register |
|
data: |
|
hub: dlc02 |
|
slave: 255 |
|
address: 41001 |
|
value: |
|
- "{{ bus_prefix + (dali_addr | int) }}" |
|
- "{{ 0x0200 + brightness_dali }}" |
|
- 0x0000 |
|
- 0x0000 |
|
- service: modbus.write_register |
|
data: |
|
hub: dlc02 |
|
slave: 255 |
|
address: 41001 |
|
value: |
|
- "{{ bus_prefix + (dali_addr | int) }}" |
|
- 0x0501 |
|
- "{{ kelvin_val }}" |
|
- 0x0000 |
|
default: |
|
- service: system_log.write |
|
data: |
|
level: error |
|
message: "control_dali_light script called with invalid light_type: {{ light_type }}" |
|
|
|
# ------------------------------------------------------------------ |
|
# --- TEMPLATE LIGHT DEFINITIONS --- |
|
# --- This version is more compatible with standard HA controls --- |
|
# ------------------------------------------------------------------ |
|
# Input helpers to store last known light values |
|
input_number: |
|
dali_cct_office_lamp_last_brightness: |
|
name: "DALI CCT Office Lamp Last Brightness" |
|
min: 0 |
|
max: 255 |
|
step: 1 |
|
initial: 255 |
|
mode: box |
|
dali_cct_office_lamp_last_color_temp: |
|
name: "DALI CCT Office Lamp Last Color Temp" |
|
min: 154 |
|
max: 370 |
|
step: 1 |
|
initial: 262 |
|
mode: box |
|
|
|
template: |
|
- light: |
|
# --- Light Definition #1: The CCT Office Lamp (Improved with State Preservation) --- |
|
- name: "DALI CCT Office Lamp" |
|
unique_id: dali_cct_office_lamp |
|
|
|
# Color temperature range for the light |
|
min_mireds: 154 |
|
max_mireds: 370 |
|
|
|
# The turn_on action now simply ensures the light is on, relying on other |
|
# services to set the correct brightness and color temperature. |
|
turn_on: |
|
- service: system_log.write |
|
data: |
|
level: info |
|
message: "DALI CCT Office Lamp turn_on called - brightness: {{ states('input_number.dali_cct_office_lamp_last_brightness') | int(255) }}, color_temp: {{ states('input_number.dali_cct_office_lamp_last_color_temp') | int(262) }}" |
|
- service: script.control_dali_light |
|
data: |
|
<<: &dali_cct_office_lamp_common_data |
|
light_type: 'cct_2ch' |
|
bus_id: 1 |
|
dali_addr_ww: 0 |
|
dali_addr_cw: 1 |
|
min_mireds: 154 |
|
max_mireds: 370 |
|
brightness: "{{ states('input_number.dali_cct_office_lamp_last_brightness') | int(255) }}" |
|
color_temp_mireds: "{{ states('input_number.dali_cct_office_lamp_last_color_temp') | int(262) }}" |
|
|
|
# The turn_off action now only sets brightness to 0, using the last known color temp. |
|
turn_off: |
|
- service: system_log.write |
|
data: |
|
level: info |
|
message: "DALI CCT Office Lamp turn_off called - color_temp: {{ states('input_number.dali_cct_office_lamp_last_color_temp') | int(262) }}" |
|
- service: script.control_dali_light |
|
data: |
|
<<: *dali_cct_office_lamp_common_data |
|
brightness: 0 |
|
color_temp_mireds: "{{ states('input_number.dali_cct_office_lamp_last_color_temp') | int(262) }}" |
|
|
|
# This action is triggered by the brightness slider and saves the new brightness. |
|
set_level: |
|
- service: system_log.write |
|
data: |
|
level: info |
|
message: "DALI CCT Office Lamp set_level called - brightness: {{ brightness }}, color_temp: {{ states('input_number.dali_cct_office_lamp_last_color_temp') | int(262) }}" |
|
- service: input_number.set_value |
|
target: |
|
entity_id: input_number.dali_cct_office_lamp_last_brightness |
|
data: |
|
value: "{{ [[brightness | int(0), 0] | max, 255] | min }}" |
|
- service: script.control_dali_light |
|
data: |
|
<<: *dali_cct_office_lamp_common_data |
|
brightness: "{{ brightness }}" |
|
color_temp_mireds: "{{ states('input_number.dali_cct_office_lamp_last_color_temp') | int(262) }}" |
|
|
|
# This action is triggered by the color temperature slider and saves the new temperature. |
|
set_temperature: |
|
- service: system_log.write |
|
data: |
|
level: info |
|
message: >- |
|
DALI CCT Office Lamp set_temperature called - |
|
brightness: {{ brightness | default(states('input_number.dali_cct_office_lamp_last_brightness')|int) }}, |
|
color_temp: {{ color_temp }} |
|
- service: input_number.set_value |
|
target: |
|
entity_id: input_number.dali_cct_office_lamp_last_color_temp |
|
data: |
|
value: "{{ [[color_temp | int(262), 154] | max, 370] | min }}" |
|
- if: |
|
- condition: template |
|
# only store a new last‐brightness if HA actually sent one |
|
value_template: "{{ brightness is defined }}" |
|
then: |
|
- service: input_number.set_value |
|
target: |
|
entity_id: input_number.dali_cct_office_lamp_last_brightness |
|
data: |
|
value: "{{ brightness }}" |
|
- service: script.control_dali_light |
|
data: |
|
<<: *dali_cct_office_lamp_common_data |
|
brightness: "{{ brightness | default(states('input_number.dali_cct_office_lamp_last_brightness')|int) }}" |
|
color_temp_mireds: "{{ color_temp }}" |
|
|
|
# --- EXAMPLE: Single-Address Lamp (Improved) --- |
|
# - name: "DALI Single Address Lamp" |
|
# unique_id: dali_single_addr_lamp_a2 |
|
# turn_on: |
|
# - service: script.control_dali_light |
|
# data: |
|
# light_type: 'cct' |
|
# bus_id: 1 |
|
# dali_addr: 2 |
|
# brightness: "{{ state_attr(this.entity_id, 'brightness') | int(255) }}" |
|
# color_temp_mireds: "{{ state_attr(this.entity_id, 'color_temp_mireds') | int(300) }}" |
|
# turn_off: |
|
# - service: script.control_dali_light |
|
# data: |
|
# light_type: 'cct' |
|
# bus_id: 1 |
|
# dali_addr: 2 |
|
# brightness: 0 |
|
# color_temp_mireds: "{{ state_attr(this.entity_id, 'color_temp_mireds') | int(300) }}" |
|
# set_level: |
|
# - service: script.control_dali_light |
|
# data: |
|
# light_type: 'cct' |
|
# bus_id: 1 |
|
# dali_addr: 2 |
|
# brightness: "{{ brightness }}" |
|
# color_temp_mireds: "{{ state_attr(this.entity_id, 'color_temp_mireds') | int(300) }}" |
|
# set_temperature: |
|
# - service: script.control_dali_light |
|
# data: |
|
# light_type: 'cct' |
|
# bus_id: 1 |
|
# dali_addr: 2 |
|
# brightness: "{{ state_attr(this.entity_id, 'brightness') | int(0) }}" |
|
# color_temp_mireds: "{{ color_temp }}" |