Lutron RA3 / HomeWorks QSX (LEAP)
Lutron's current processors — RadioRA 3, HomeWorks QSX, and standalone QSX — are controlled over the LAN using Lutron's LEAP protocol over a secure (TLS) connection. One processor becomes one GEM device, and that single device controls every light, shade, fan, keypad, and scene on the project. Lights, shades, and fans become GEM zones; keypad buttons and LEDs are driven and read back live.
Control requires a one-time, on-site pairing in which GEM and the processor exchange a certificate. Pairing must be authorized by physically pressing the processor's front-panel button — it cannot be triggered from the Lutron app.
The Caséta Smart Bridge Pro speaks the same LEAP protocol and is handled by the separate
lutron_caseta driver, which shares this driver's pairing and sync flow. The standard (non-Pro)
Smart Bridge does not expose LEAP and cannot be used. The older telnet-based HomeWorks and QS
processors use the lutron_homeworks / lutron_qs drivers instead and are configured from
the Lutron integration page, not here.
What's controlled
- Lights — on / off, set level (dimming) with a fade time, and color/white tuning on spectrum-capable fixtures (hue, saturation, vibrancy, and color temperature).
- Shades — open / close / stop (raise / lower / stop) and set position on dimming shades.
- Fans — set speed by percentage or by named speed (off / low / medium / high).
- Keypads — press and press-and-hold any keypad button, set keypad LED state, and reflect live LED state and button activity back into GEM (used by the on-screen Lutron Keypad widget).
- Scenes — activate a Lutron scene in any area.
- Project structure — pull the processor's areas, zones, and control stations into GEM, and optionally mirror the whole Lutron area tree into GEM site spaces and UIs.
Prerequisites
- A RadioRA 3, HomeWorks QSX, or QSX processor on the same LAN as GEM, with a known IP address. Give it a static IP or a DHCP reservation so its address never moves.
- Network reachability between GEM and the processor on two TCP ports:
- 8081 — ongoing LEAP control (kept open the whole time the device is enabled).
- 8083 — used once during pairing to exchange the client certificate.
- Physical access to the processor's front panel to authorize pairing.
- The Lutron product on your GEM license. Adding any Lutron device requires it; existing devices keep running if a license later changes. See License.
If GEM can reach 8081 but not 8083, the device may appear online yet the pair command will fail.
Open both ports between GEM and the processor before you start.
Setup — add, pair, and sync
1. Add the device
- Open Devices, add a device, and choose the Lutron RA3 / QSX (LEAP) driver.
- Give it a name and set the Processor IP (
ip) to the processor's LAN address. - Save, enable the device, then reload it so the driver comes online. The device must be
running before the
paircommand will work.
Processors also advertise themselves on the network (mDNS), but you still enter the IP manually for pairing — don't rely on auto-discovery to fill it in.
2. Pair with the processor
- At the processor, press and hold the front-panel pairing button until the indicator ring/LED flashes — this puts it into pairing mode. LEAP requires proof of physical access, so this step cannot be done from the Lutron mobile app.
- While the processor is still in pairing mode, open the device's Commands tab and run
pair. GEM connects on port 8083, exchanges certificates, and stores them encrypted on the device. - Once paired, GEM connects over LEAP (port 8081) on its own and reconnects automatically after a reboot or network blip. You only pair again if you replace the processor or delete the stored credentials.
If you ever swap processors or move the device to a different unit, clear the stored LEAP Key
Pair and LEAP Certificates attributes on the device, then run pair again. Certificates are
tied to the specific processor that issued them.
3. Pull in the zones
After pairing, run one of the sync commands from the Commands tab:
sync_zones— walks the processor and creates a GEM zone for every controllable output (lights, shades, fans). This is the minimum to start controlling things.sync_areas— does everythingsync_zonesdoes and mirrors the Lutron area tree into GEM site spaces: it creates/links a site space per Lutron area, fills in the matching zones, and stamps each zone with its space. It never renames or deletes spaces you already have. Passcreate_uis=trueto also generate a UI for any space that doesn't yet have one.
GEM also resyncs on its own: when the driver connects it pulls zones if it hasn't synced in the last hour, and it keeps the connection alive with a periodic ping.
On the Setup wizard's Discover Devices step, GEM detects a newly added Lutron
processor and shows a Lutron Sync card. Turning on its "mirror rooms" option queues an area sync
(equivalent to sync_areas with UI creation) that runs automatically as soon as pairing completes —
handy when you add the processor before pressing the pairing button.
Zones
Each Lutron output becomes a GEM zone. The zone's Address is the numeric Lutron zone id, which the sync commands fill in for you. GEM picks the subsystem and zone control type from the Lutron output type:
| Lutron output type | GEM subsystem | Zone control | How you control it |
|---|---|---|---|
| Dimmed | Lights | light_dimmer | on / off / set level with fade |
| Switched | Lights | light_switch | on / off |
| Spectrum Tune | Lights | light_dimmer | on / off / level; color via spectrum_level |
| Color Tune | Lights | light_dimmer | on / off / level; color via spectrum_level |
| Shade | Shades | shade_dimmer | open / close / stop / set position |
| Fan Speed | Fans | fan_default | set speed (percent or named) |
Many fans are wired to a Lutron Switched or Dimmed output rather than a dedicated Fan Speed control, so by output type alone they would import as Lights. When a zone's Lutron name contains the word fan, sync_zones recategorizes it into the Fans subsystem and picks the control from the physical output: a Switched load becomes fan_onoff (on/off only — e.g. an exhaust or bath fan), while a Dimmed (or true Fan Speed) load becomes fan_default (variable high / medium / low / off). Name your Lutron outputs accordingly and the fan lands in the right place automatically.
What the standard zone verbs do on a Lutron zone:
- on / off — full on (100%) or off. On a dimmer this is a dim-to-100 / dim-to-0; on a switched load it's a relay on / off.
- level — set brightness 0–100 with a fade time in seconds. If you don't pass a fade, GEM uses the Lights subsystem's default fade rate (or 4 seconds if none is set).
- open / close / stop — raise / lower / stop a shade.
Color and white tuning
For spectrum- or color-tunable fixtures, set color with the spectrum_level command against the
zone's address. Its arguments are level, hue, saturation, vibrancy, and fade_rate (any you
omit keep the fixture's current value). White-tunable fixtures report their color temperature back
as the zone's kelvin attribute. Color-tunable fixtures import as dimmer zones, so on / off / level
work as plain brightness out of the box; use spectrum_level (or a macro that calls it) to drive
color.
Fan speed
A fan zone accepts either a percentage level (0 = off, 1–33 = low, 34–66 = medium, 67–100 =
high) or a named speed — off, low, medium, high. The zone's state reflects the current
named speed — pushed natively by true Fan Speed outputs, and derived from the reported level on
fans wired to a switched or dimmed leg (which only report a level), so state is usable either way.
Keypads and buttons
GEM controls and reads Lutron keypads (seeTouch, Palladiom, Sunnata, and the like):
press_button/hold_button(argumentid, the Lutron button id) — emulate a tap or a press-and-hold on a keypad button, exactly as if someone pushed it.set_led(argumentsled,state) — turn a keypad LED on or off (state=on/off).- Live keypad LED state and button activity are pushed back to GEM, so on-screen controls stay in sync with the physical keypads.
To find the button and LED ids, run get_control_stations for a flat list of every keypad on
the processor, or get_control_station (argument control_station_id) for one keypad's full
detail — model, serial, its LEDs, and its buttons grouped the way they're laid out on the device.
Each button also reports programmed and programming_model_type, read from the button's LEAP
programming model — a button with no assignment in the Lutron design (commonly an unused
raise/lower pair) has no programming model and reports programmed: false.
On-screen keypad widget
The Lutron Keypad widget renders a physical keypad on a GEM UI page —
the buttons mirror the real layout, honor press / hold, and light up to match live LED state. With
no settings at all, the widget finds the first lutron_qsx processor on the system and resolves its
keypad from the UI's lutron_control_station_id attribute — which sync_areas fills in for each
UI it links to a Lutron area — so dropping the widget on a synced room's UI just works, and one
widget follows whatever room UI it's placed on. To pin a specific keypad instead, pick the Lutron
processor Device, then pick the Keypad (the picker is fed by get_control_stations).
Turning on Use UI attribute forces the UI attribute even when a keypad is picked.
Buttons the processor reports as unprogrammed (see above) are hidden, since pressing them does nothing — turn on Show unprogrammed buttons to render the complete physical plate anyway.
Turning on Faceplate draws a shared wallplate behind the button banks, replicating the
installed hardware — multi-gang stations share one plate. The widget's chrome (plate, buttons,
LEDs, faceplate) follows the active theme via the --keypad-* design tokens — see the
Theme Contract.
Scenes
Run activate_scene with area_id (the Lutron area) and scene_id to recall a Lutron scene.
Use the inspection commands below (get_root_area, get_child_areas, get_associated_zones) to
discover area ids and the scenes available in each.
Device attributes
Most of these are written by the driver — you normally only set Processor IP.
| Attribute | Set by | Purpose |
|---|---|---|
ip (Processor IP) | You | LAN IP of the processor. |
keypair (LEAP Key Pair) | pair | Generated key pair, stored encrypted. Do not edit. |
certificates (LEAP Certificates) | pair | Client/CA certificates issued during pairing, stored encrypted. |
subscriptions | Driver | Internal map of live LEAP subscription URLs. |
button_subscriptions / led_subscriptions | Driver | Keypad button/LED ids GEM is subscribed to for live events. |
last_sync | Driver | Timestamp of the last zone sync, used to decide when to resync. |
Two optional advanced overrides are read if present on the device: ping_interval (keep-alive
interval, default 30 seconds) and sync_interval (auto-resync interval, default 1 hour). Leave them
unset unless you have a specific reason to change the cadence.
When sync_areas runs, it also writes a lutron_area_href attribute on each matched site space (and
the site) and a lutron_control_station_id on each UI it links to an area, so the keypad widget and
other room-aware features can find the right Lutron objects automatically.
Zone attributes
On lighting/shade/fan zones the driver maintains live state attributes you can read or trigger on:
| Attribute | Meaning |
|---|---|
level | Current brightness / shade position (0–100). |
state | Current named state. Lights and on/off fan legs report on / off; variable fans report off / low / medium / high. Native FanSpeed outputs push this themselves; switched/dimmed legs only report a level, so the driver derives the state from it (fan speeds use GEM's standard thresholds: above 50 = high, above 25 = medium, above 0 = low). |
color | Current color as a hex value (spectrum fixtures). |
hue / saturation / vibrancy | Current color components (spectrum fixtures). |
kelvin | Current color temperature (white-tunable fixtures). |
control_type | The zone's physical Lutron control type (FanSpeed / Dimmed / Switched / …), stamped by the sync commands. GEM uses it so a fan_default zone drives correctly no matter how it's wired: a Dimmed load is sent as a dimmed level, a Switched load as an on/off level (any non-zero speed → on, 0 → off), and a true FanSpeed load as a native fan speed. Set automatically — leave it alone. |
Command reference
| Command | Arguments | Action |
|---|---|---|
pair | — | Exchange certificates with the processor (processor must be in pairing mode). |
sync_zones | — | Create GEM zones for all lights/shades/fans on the processor. |
sync_areas | create_uis | Sync zones and mirror the Lutron area tree into site spaces (and UIs if create_uis=true). |
on / off | address | Turn a zone fully on / off. |
level | address, level, fade_rate | Set a dimmer level (0–100) over a fade time in seconds. |
spectrum_level | address, level, vibrancy, hue, saturation, fade_rate | Set color/level on a spectrum-tunable fixture. |
set_fan | address, level | Set a fan speed by percent or name. |
open / close / stop | address | Raise / lower / stop a shade. |
press_button / hold_button | id | Tap or press-and-hold a keypad button. |
set_led | led, state | Turn a keypad LED on / off. |
activate_scene | area_id, scene_id | Recall a Lutron scene in an area. |
get_root_area | — | Read the top of the Lutron area tree. |
get_child_areas | area_id, include_components | List child areas, control stations, and devices. Pass include_components=true to also enumerate buttons + LEDs (slower). |
get_associated_zones | area_id | List child areas with their zone details. |
get_control_stations | — | Flat list of all keypads/control stations on the processor. |
get_control_station | control_station_id | Full detail (model, serial, LEDs, buttons) for one control station. |
subscribe | url | Subscribe to a LEAP status URL for live events. |
read_request | url | Read any LEAP resource by URL (diagnostic). |
Troubleshooting
| Symptom | Check |
|---|---|
pair command fails | The processor isn't in pairing mode — hold the front-panel button until the ring flashes, then run pair again. Confirm TCP 8083 is open between GEM and the processor. |
| Pairs but no events / nothing controls | The stored certificates may belong to a different processor. Clear the LEAP Key Pair and LEAP Certificates attributes and re-pair. Confirm TCP 8081 is open. |
| No zones appear after pairing | Run sync_zones (or sync_areas) from the Commands tab. |
| A zone won't dim / only switches | The Lutron output is a Switched (relay) load, not a dimmer — it imports as a switched zone and only supports on / off. |
| Color commands do nothing | The fixture isn't spectrum/color-tunable, or you sent on/level instead of spectrum_level. Use spectrum_level against the zone's address. |
| Keypad LEDs/buttons out of sync on screen | Re-run sync_areas (or get_control_stations) so GEM re-subscribes to the keypad's LEDs and buttons. |
| Device drops offline periodically | Confirm the processor has a static IP/reservation and that nothing is closing the LAN path on port 8081. |
See also
- Lutron — the Integrations page: XML import for HomeWorks/QS processors and the broader LEAP pairing/sync overview.
- Zones — how zones, addresses, and control types work.
- Site Spaces — how
sync_areasmirrors the Lutron area tree. - Widgets — adding the Lutron Keypad widget to a UI page.
- Commands — running and scripting device commands.
- Devices — adding and configuring devices.
- License — enabling the Lutron product.