Lutron Aurora controller for Zigbee2MQTT via pyscript

Trying to get the most I can out of these old switches. They don’t provide enough information in ZHA to do reasonable dimmer control, but Z2MQTT provides a little more info for control.

# Zigbee2MQTT - Lutron Aurora Control
# - Listens to MQTT messages on zigbee2mqtt/<device>
# - Maps switch device names to target light entities using SWITCH_TO_LIGHTS dictionary
# - Button press toggles lights on/off
# - Rotation adjusts brightness (only when lights are already on)
# - Uses action_level and action_transition_time from Z2M payloads

# logger.set_level(**{"custom_components.pyscript.file.zigbee2mqtt_lutron_aurora_control": "debug"})

# Configuration: Map switch device names to target light entities
# Key: Switch name (from MQTT)
# Value: List of light entity IDs that this switch controls
SWITCH_TO_LIGHTS = {
    "Office Hue Switch": [
        "light.office_nano_bulb_01",
        "light.office_nano_bulb_02",
        "light.office_hue_lightstrip",
    ],
    "Living Room Hue Switch": ["light.magic_areas_light_groups_living_room_all_lights"],
}

# Brightness settings
BRIGHTNESS_MIN = 10
BRIGHTNESS_MAX = 255
DEFAULT_TRANSITION = 0.2


# Clamp brightness to valid range
def clamp_brightness(value: int) -> int:
    return max(BRIGHTNESS_MIN, min(value, BRIGHTNESS_MAX))


# Returns brightness of first lit entity, or None if no lights are on
def get_current_brightness(target_lights: list[str]) -> int | None:
    for entity in target_lights:
        if state.get(entity) == "on":
            brightness = state.get(f"{entity}.brightness")
            if brightness is not None:
                return int(brightness)
    return None


# Check if the event is a button press (vs rotation)
def is_press_event(transition_time: float, action_level: int) -> bool:
    # Aurora sends transition_time=0.07 for button presses
    if abs(transition_time - 0.07) < 1e-3:
        return True
    return False


@mqtt_trigger("zigbee2mqtt/+")
def on_z2m_event(topic=None, payload=None, payload_obj=None, **kwargs):
    if not topic or not topic.startswith("zigbee2mqtt/"):
        return

    device_name = topic.split("/", 1)[1]

    # Look up target lights from configuration mapping
    target_lights = SWITCH_TO_LIGHTS.get(device_name)
    if target_lights is None:
        log.debug(f"No mapping found for switch '{device_name}', skipping")
        return

    log.debug(f"TARGETING: {target_lights}")

    # Check if any light entity exists
    entity_exists = False
    for entity in target_lights:
        if state.get(entity):
            entity_exists = True
            break
    if not entity_exists:
        log.debug(f"No light entities found in {target_lights}, skipping")
        return

    # Parse payload
    action_level = (payload_obj or {}).get("action_level")
    transition_time = (payload_obj or {}).get("action_transition_time", 0)

    # Ignore if no action_level reported
    if action_level is None:
        return

    # Handle button press: toggle light
    if is_press_event(transition_time, action_level):
        log.debug(f"{device_name} --> TOGGLE")
        light.toggle(entity_id=target_lights)
        return

    # Handle rotation: adjust brightness (only when lights are on)
    current_brightness = get_current_brightness(target_lights)
    if current_brightness is None:
        return

    new_brightness = clamp_brightness(action_level)

    # Skip redundant write if no change
    if current_brightness == new_brightness:
        return

    log.debug(f"{device_name} --> Rotate dim -> brightness {new_brightness}")
    light.turn_on(
        entity_id=target_lights,
        brightness=new_brightness,
        transition=DEFAULT_TRANSITION,
    )

I have been trying to look for solution like this for ages.
For the uninitiated like me, how do I use the script & where do I put / setup the script?

Hi @k8gg

  1. On your computer, create a file called zigbee2mqtt_lutron_aurora_control.py
  2. Copy and paste the code from the first post into the file.
  3. In Home Assistant, install pyscript via HACS - Use Options 1 here.
  4. Follow the configuration instructions here. During configuration there’s a sentence "Add files with a suffix of .py in the folder <config>/pyscript". Copy the zigbee2mqtt_lutron_aurora_control.py to the pyscript folder during that step.

If you need more help let me know. I’m excited to see if this works well for others.

Cheers!

1 Like