Skip to main content

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.

Lutron Caséta uses a sibling driver

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.
Both ports must be open

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

  1. Open Devices, add a device, and choose the Lutron RA3 / QSX (LEAP) driver.
  2. Give it a name and set the Processor IP (ip) to the processor's LAN address.
  3. Save, enable the device, then reload it so the driver comes online. The device must be running before the pair command 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

  1. 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.
  2. 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.
  3. 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.
Pair from the Lutron page instead

The Lutron page's Overview tab drives this whole sequence for you: it checks the address and both ports first, tells you what to press, counts down the processor's pairing window, and reports whether the certificate actually arrived. pair returns as soon as the pairing connection opens — long before the exchange happens — so on the Commands tab it reads as an instant success whether or not anyone pressed the button. Run pair_status there for the same checks without starting a pairing.

An unreachable processor — wrong IP, port 8083 filtered, pairing service not listening — makes pair return an error describing which of those it was, rather than waiting on a connection that never completes.

Re-pairing

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 everything sync_zones does 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. Pass create_uis=true to 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.

Setup wizard shortcut

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. Sync also keeps each zone named after its Lutron area + output name — to rename a zone in GEM without the next sync reverting it, set the zone's custom_label attribute to true (see Zone attributes). GEM picks the subsystem and zone control type from the Lutron output type:

Lutron output typeGEM subsystemZone controlHow you control it
DimmedLightslight_dimmeron / off / set level with fade
SwitchedLightslight_switchon / off
Spectrum TuneLightslight_dimmeron / off / level; color via spectrum_level
Color TuneLightslight_dimmeron / off / level; color via spectrum_level
ShadeShadesshade_dimmeropen / close / stop / set position
Fan SpeedFansfan_defaultset speed (percent or named)
Fans wired to a switch or dimmer

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.
Reassigned zone controls (water features, power, fireplaces, ...)

Lutron outputs often drive loads that aren't lights — a fountain pump on a switching module, a fireplace, landscape power. If you move such a zone into another subsystem and give it a different zone control (water_onoff, power_default, fireplace_default, high_medium_low_off, ...), on / off / level commands still work: GEM routes them by the zone's physical Lutron output type (control_type attribute — switched, dimmed, or fan speed), regardless of which control the zone uses in the UI.

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 (argument id, the Lutron button id) — emulate a tap or a press-and-hold on a keypad button, exactly as if someone pushed it.
  • set_led (arguments led, 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. sync_areas only assigns device locations that actually contain a keypad-type device — a room whose only "device location" is a load module (say, a J-box relay module driving a fountain) or a sensor gets no keypad attribute, and each skipped location is listed in the sync result under stations_skipped. 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.

With no title configured, the widget titles itself after the keypad's Lutron area ("SPEAKEASY" renders as Speakeasy), falling back to the station name — a configured widget title always wins.

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.

Scrolling a page past the keypad does not send a button press: a touch that starts on a button and then drags to scroll is discarded on release, so a widget placed part-way down a long page is safe to swipe over.

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.

Keypads on a generated RTI remote

A generated RTI program mirrors the same keypad. When the remote's UI carries lutron_control_station_id, its lighting page becomes that station's engraved buttons rather than GEM's light scenes, and every press calls this driver's press_button with the LEAP button id — the keypad's own programming decides what happens. Unprogrammed buttons are left off, a UI carrying several stations gets a page per keypad behind a hub, and there is no hold form (RTI has no hold gesture on a generated button). Re-engraving or reprogramming a button in the Lutron database flags the remote for regeneration; if the processor cannot be read at generation time the page falls back to scenes with a warning saying so.

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.

AttributeSet byPurpose
ip (Processor IP)YouLAN IP of the processor.
keypair (LEAP Key Pair)pairGenerated key pair, stored encrypted. Do not edit.
certificates (LEAP Certificates)pairClient/CA certificates issued during pairing, stored encrypted.
subscriptionsDriverInternal map of live LEAP subscription URLs.
button_subscriptions / led_subscriptionsDriverKeypad button/LED ids GEM is subscribed to for live events.
last_syncDriverTimestamp of the last zone sync, used to decide when to resync.
paired_atpairTimestamp of the last successful pairing. Shown on the Lutron page's Overview tab.

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:

AttributeMeaning
levelCurrent brightness / shade position (0–100).
stateCurrent 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).
colorCurrent color as a hex value (spectrum fixtures).
hue / saturation / vibrancyCurrent color components (spectrum fixtures).
kelvinCurrent color temperature (white-tunable fixtures).
control_typeThe 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.
custom_labelSet to true to mark the zone's name and label as user-customized. By default, sync keeps every zone named after its Lutron area + output name — if you rename the zone in GEM, the next sync (which also runs on reconnect) renames it back. With custom_label set, sync leaves the name and label alone while still updating everything else.

Command reference

CommandArgumentsAction
pairExchange certificates with the processor (processor must be in pairing mode).
sync_zonesCreate GEM zones for all lights/shades/fans on the processor.
sync_areascreate_uisSync zones and mirror the Lutron area tree into site spaces (and UIs if create_uis=true).
on / offaddressTurn a zone fully on / off.
leveladdress, level, fade_rateSet a dimmer level (0–100) over a fade time in seconds.
spectrum_leveladdress, level, vibrancy, hue, saturation, fade_rateSet color/level on a spectrum-tunable fixture.
set_fanaddress, levelSet a fan speed by percent or name.
open / close / stopaddressRaise / lower / stop a shade.
press_button / hold_buttonidTap or press-and-hold a keypad button.
set_ledled, stateTurn a keypad LED on / off.
activate_scenearea_id, scene_idRecall a Lutron scene in an area.
get_root_areaRead the top of the Lutron area tree.
get_child_areasarea_id, include_componentsList child areas, control stations, and devices. Pass include_components=true to also enumerate buttons + LEDs (slower).
get_associated_zonesarea_idList child areas with their zone details.
get_control_stationsFlat list of all keypads/control stations on the processor.
get_control_stationcontrol_station_idFull detail (model, serial, LEDs, buttons) for one control station.
subscribeurlSubscribe to a LEAP status URL for live events.
read_requesturlRead any LEAP resource by URL (diagnostic).
pair_statusPairing readiness: certificate/key-pair presence, LEAP session state, whether TCP 8081 and 8083 answer, and a suggested next step. Reports presence only — never returns the key material.
get_trafficsince, limitThe last 400 LEAP frames the driver sent and received. since=<seq> returns only newer frames, for incremental polling.
clear_trafficEmpty the protocol trace buffer.

The protocol trace is memory-only and is never persisted. The LAP pairing exchange runs on a separate connection and is deliberately not traced, so the CSR and the issued certificate never enter the buffer. The Lutron page renders it as a live monitor.

Troubleshooting

SymptomCheck
pair command failsRun pair_status (or open the Lutron page's Overview tab) — it says whether the IP is set and whether 8081/8083 answer, which separates a network problem from a pairing-mode problem. Otherwise the processor isn't in pairing mode: hold the front-panel button until the ring flashes, then run pair again.
pair reports success but nothing worksPairing needs the button held on the processor at that moment. The Lutron page's pairing panel watches for the certificate and tells you whether one actually arrived; the raw pair command returns as soon as the connection opens.
Pairs but no events / nothing controlsThe 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 pairingRun sync_zones (or sync_areas) from the Commands tab.
A zone won't dim / only switchesThe Lutron output is a Switched (relay) load, not a dimmer — it imports as a switched zone and only supports on / off.
Color commands do nothingThe 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 screenRe-run sync_areas (or get_control_stations) so GEM re-subscribes to the keypad's LEDs and buttons.
Device drops offline periodicallyConfirm the processor has a static IP/reservation and that nothing is closing the LAN path on port 8081.

See also

  • Lutron — the Integrations page: the guided pairing panel, project import, the zone commissioning bench, the keypad and scene browsers and the protocol monitor.
  • Zones — how zones, addresses, and control types work.
  • Site Spaces — how sync_areas mirrors 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.