Lutron QS
Lutron's QS-series processors — and other Lutron systems that expose Lutron's telnet
Integration Access Port, such as HomeWorks QS and RadioRA 2 main repeaters — are
controlled over the LAN using Lutron's classic integration protocol (the #OUTPUT / #DEVICE
command set). One processor becomes one GEM device, and that single device drives every dimmer,
switch, shade, fan, keypad, and thermostat on the project. Lighting, shade, fan, and HVAC outputs
become GEM zones, keyed by their Lutron Integration ID; keypad button presses are read back
live as zone attributes you can trigger automations on.
Unlike the newer LEAP processors, there is no certificate pairing here — GEM opens a telnet session to the processor, logs in with an integration user, and starts sending commands. You bring zones in either by uploading the processor's XML export or by adding them by hand with their Integration ID.
This page covers the lutron_qs telnet driver. Lutron's current RadioRA 3, HomeWorks
QSX, QSX, and Caséta Smart Bridge Pro processors instead speak the secure LEAP protocol
and pair with a certificate — use the Lutron RA3 / HomeWorks QSX or
Lutron Caséta driver for those. The older HomeWorks Interactive / Illumination
processors use the separate lutron_homeworks driver (same telnet idea, different command syntax). If
you're not sure which you have, the deciding factor is the port: this driver talks telnet on port 23;
the LEAP drivers talk TLS on 8081/8083.
What's controlled
- Lights — on / off and set level (dimming) with a fade time, on dimmer outputs; on / off on non-dim (switched) outputs.
- Shades — open / close (raise / lower to a position), set position by level, and group control for shade groups.
- Fans — set speed by level (0–100); the processor maps the percentage to the fixture's speed steps.
- Keypads — press / hold / release / double-tap any keypad button, and read live keypad button activity back into GEM as zone attributes for use in triggers and macros.
- Thermostats — on HomeWorks QS systems with HVAC: current temperature, heat/cool setpoints, operating mode, and fan mode, read live and settable from the standard climate control. See Thermostats below.
The telnet integration protocol carries dim levels only — it has no color or color-temperature control. Color- and white-tunable fixtures dim normally, but hue / saturation / color-temperature tuning is only available on the LEAP processors via the Lutron RA3 / HomeWorks QSX driver.
Prerequisites
- A QS-series (or HomeWorks QS / RadioRA 2) 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.
- Telnet integration enabled on the processor, with an integration login user created in the Lutron programming software. This is a separate login from the programming/design PC account.
- Network reachability between GEM and the processor on TCP port 23 (telnet).
- The Lutron product on your GEM license. Adding any Lutron device requires it; existing devices keep running if a license later changes. See License.
- The processor's XML configuration export (from the Lutron programming software) if you want to bulk-import zones rather than add them one at a time.
Setup — add the device, then bring in zones
1. Add the device
- Open Devices, add a device, and choose the Lutron QS driver.
- Give it a name and set the Processor IP (
ip) to the processor's LAN address. - Fill in the integration credentials under the optional attributes:
- Login (
login) — the integration user name (commonlylutron). You can use Username (username) instead; they're interchangeable. - Password (
password) — the integration password (commonlyintegration). Stored encrypted. - Credentials left blank fall back to the factory defaults for the QS integration access
port —
lutron/integration— so a stock processor connects with no credentials entered. Anything you fill in always wins over the defaults. - Telnet Port (
port) — defaults to 23; only change it if your processor uses a non-standard port. - Default Fade Rate (seconds) (
fade_rate) — fade time used for level changes when a command doesn't specify one. Defaults to 3 seconds.
- Login (
- Save, enable the device, then reload it so the driver opens the telnet session and logs in. Watch the device's connection state turn online.
After logging in, the driver waits for the processor's QNET> prompt to confirm the credentials
were accepted before it starts driving the session. If the processor answers bad login, the
driver stops rather than talk to a rejected session, and writes authentication failed (bad login)
to the device's last_error attribute so the misconfiguration is visible instead of showing up
as a silent reconnect loop. The attribute clears automatically on the next successful login.
2. Bring in the zones
Each controllable output (dimmer, switch, shade, fan) becomes a GEM zone whose Address is the Lutron Integration ID. You have two ways to create them.
Option A — XML import (recommended for whole projects). Export the project's XML from the Lutron programming software, then:
- Open the Lutron Import page (admin Integrations → Lutron).
- Pick your device from the Device dropdown (it lists only
lutron_qsandlutron_homeworksdevices). - Choose the XML File (only
.xmlis accepted), then click Import Zones. - Review the results — Created / Skipped / Errors cards and a per-output table. Outputs whose Integration ID already exists on the device are skipped, so you can safely re-run the import after adding more outputs in Lutron.
The importer reads each output's Integration ID, name, and Lutron output type, and creates a zone in the right subsystem with the matching control type:
| Lutron output type | GEM subsystem | Zone control |
|---|---|---|
INC, MLV, ELV, AUTO_DETECT | Lights | light_dimmer |
NON_DIM_INC, NON_DIM_FLUORESCENT | Lights | light_switch |
SYSTEM_SHADE | Shades | shade_dimmer |
CEILING_FAN_TYPE, EXHAUST_FAN_TYPE | Fans | fan_default |
Output types outside this list are skipped. The zone name comes from the Lutron area name plus the
output name (e.g. kitchen_island).
Option B — add zones by hand. On Zones, add a zone, set its Device to
the Lutron processor, set the Address to the output's Lutron Integration ID (a number, e.g.
18), and pick the control type (light_dimmer, light_switch, shade_dimmer, or fan_default).
If the processor reports activity for an Integration ID that has no GEM zone yet, the driver creates
a disabled light_dimmer zone named discovered_<device>_<id> (label Discovered <id>) in the
Lights subsystem so you can review it. These are always created as dimmers regardless of the real
output type, so prefer the XML import (or manual entry) to get shades, fans, and switched loads
classified correctly — then enable and rename the discovered placeholders only if needed.
Zones
Each Lutron output is one GEM zone; its Address is the numeric Integration ID. What the standard zone verbs do:
- on / off — full on (100%) or off, sent instantly (no fade). On a dimmer this is dim-to-100 / dim-to-0; on a switched load it's a relay on / off.
- level — set a dimmer 0–100 with a fade time in seconds. If you don't pass a fade, GEM uses the device's Default Fade Rate (3 seconds unless you changed it).
- open / close — for a shade zone, raise to 100% / lower to 0%. These use the same set-level command, so they move the shade to a fixed position rather than jogging it.
Fans are driven by level: send level 0–100 (or on / off), and the Lutron output translates
the percentage into the fan's speed steps.
The QS driver's open / close send a shade to a position; there is no built-in stop verb and
no momentary raise/lower. If you need true start-raising / start-lowering / stop, send the raw Lutron
integration string with the passthrough command — Lutron #OUTPUT actions 2 (start raising),
3 (start lowering), and 4 (stop), e.g. passthrough with command = #OUTPUT,18,4 to stop
output 18. For a shade group, use shade_group_level (address = the shade group Integration
ID, level = 0–100).
Live feedback and monitoring
GEM reflects physical changes by watching the events the processor echoes on the telnet session —
~OUTPUT level reports and ~DEVICE keypad events. For those to arrive, integration monitoring
must be on. If GEM isn't picking up changes made at a keypad or in the Lutron app:
- Enable monitoring in the Lutron programming, or run the
monitorcommand on the device (Commands tab) withtype=all(oroutput/device) andaction=enable.
Whenever the driver connects (and at most once an hour), it re-queries every zone's current level so GEM resynchronizes after a reboot or network blip. Commands are throttled (about two per second) to avoid flooding the processor, so a large initial sync can take a minute.
Thermostats
HomeWorks QS systems with HVAC (Lutron thermostats or third-party equipment integrated behind the processor) expose each thermostat by an HVAC integration ID. Create a zone in the climate subsystem with that ID as the Address and the driver takes it from there — no other configuration:
- On connect it enables HVAC monitoring (
#MONITORING,17,1) and reads each stat's temperature, heat/cool setpoints, operating mode, and fan mode; changes made at the wall or by schedules push live from then on. - The zone carries
temperature,heat_setpoint,cool_setpoint,system_mode, andfan_mode(all °F), plussystem_modes/fan_modescapability lists that drive the climate control's mode buttons. All of them work in attribute triggers. - The standard climate UI works as-is: setpoint up/down sends
setpoint(with the cool/heat side), the advanced panel sendssystem_mode/fan_mode. - Lutron writes setpoints as a heat/cool pair — the driver merges the side you change with the cached other side, and refuses (with an error, then a refresh query) rather than guess if the pair has never been reported.
- Unknown stats seen on the wire are auto-created as disabled climate zones for review, the same way discovered outputs become disabled dimmer zones.
Third-party HVAC behind the processor sometimes reports operating/fan mode as "not available" (protocol value 256). Those stats still hold both setpoints — the driver presents them as auto, and all setpoint control works normally.
Keypads and buttons
Keypads are addressed by their Lutron Integration ID through the device command, which maps
to Lutron's #DEVICE integration command:
device— argumentsaddress(the keypad's Integration ID),component_number(the button or LED component number from the Lutron programming), andaction_number. The action picker offers press (3), release (4), hold (5), double_tap (6), and hold_release (32) — so you can emulate a tap or a press-and-hold on a real keypad button from a macro.
When monitoring is enabled, incoming keypad activity is written back as zone attributes. If you
add a zone whose Address is the keypad's Integration ID, each button event sets a timestamp
attribute named button_<button>_<action> on that zone (and on the device) — for example
button_2_press, button_3_hold, or button_4_double_tap. Build an
attribute trigger on the relevant button_<n>_press attribute to run a
macro when someone taps that button. (The on-screen Lutron Keypad widget and the
get_control_stations discovery commands are LEAP-only features and are not available on QS — use
the device command and these button attributes instead.)
Device attributes
You normally only set the connection fields; the rest are written by the driver.
| Attribute | Set by | Purpose |
|---|---|---|
ip (Processor IP) | You | LAN IP of the processor. |
port (Telnet Port) | You (optional) | Telnet port, default 23. |
login (Login) / username (Username) | You | Integration user name. Either attribute works; blank falls back to the factory default lutron. |
password (Password) | You | Integration password, stored encrypted. Blank falls back to the factory default integration. |
fade_rate (Default Fade Rate (seconds)) | You (optional) | Fade used for level when no fade is passed. Default 3. |
last_error | Driver | Set to authentication failed (bad login) … when the processor rejects the integration credentials; cleared on the next successful login. |
last_sync | Driver | Timestamp of the last full level re-query, used to decide when to resync. |
button_<n>_<action> | Driver | Timestamp of the most recent press/hold/etc. seen on the corresponding keypad component (also mirrored to the keypad's zone). |
Zone attributes
On lighting, shade, and fan zones the driver maintains live state you can read or trigger on:
| Attribute | Meaning |
|---|---|
level | Current dimmer level / shade position / fan level (0–100), updated from the processor's ~OUTPUT reports. |
state | on / off, maintained on switched (light_switch) zones. |
button_<n>_<action> | On a keypad zone, the timestamp of the most recent button event (press / release / hold / double_tap / hold_release). |
Command reference
| Command | Arguments | Action |
|---|---|---|
on / off | address | Set the output fully on (100%) / off, instantly. |
level | address, level, fade_rate | Set a dimmer 0–100 over a fade time in seconds (defaults to the device fade rate). |
open / close | address | Raise (100%) / lower (0%) a shade. |
shade_group_level | address, level | Set a shade group to a position (0–100). |
device | address, component_number, action_number | Press / hold / release a keypad button component. |
monitor | type, action | Enable / disable integration monitoring for an event category (output, device, all, …). |
query_level | address | Ask the processor for an output's current level. |
query_output | address | Query an output's full status. |
setpoint | address, setpoint, mode | Set a thermostat setpoint (°F). mode picks the side (cool / heat); omitted = the side matching the operating mode. |
system_mode | address, mode | Set the thermostat operating mode (off / heat / cool / auto / em_heat). |
fan_mode | address, mode | Set the thermostat fan mode (auto / on / cycler / high / medium / low / top). |
query_hvac | address, action | Query thermostat state (temperature, setpoints, mode, fan_mode, call_status). |
passthrough | command | Send a raw Lutron integration string verbatim (e.g. #OUTPUT,18,4). |
Troubleshooting
| Symptom | Check |
|---|---|
| Device won't connect | Confirm the processor's telnet integration is enabled, TCP 23 is reachable, and the IP is correct. The driver auto-reconnects, so a flapping device usually means a wrong IP/port or a closed LAN path. |
Connects but goes right back offline; last_error says authentication failed (bad login) | The processor rejected the credentials. The Login / Password are the integration user, not the programming-PC user — re-enter them, then reload the device. Blank credentials use the factory defaults lutron / integration, so a processor with a custom integration user needs them filled in. |
| Changes at a keypad or in the app don't show in GEM | Integration monitoring isn't reporting events — enable it in the Lutron programming, or run the monitor command with type=all, action=enable. |
| A light won't dim / only switches | The output is a non-dim (switched) load — it imports as a light_switch zone and only supports on / off. |
Lots of Discovered <id> disabled zones appeared | The processor reported outputs that weren't imported. Import the XML (or add them by hand) so they get the correct control type, then delete the placeholders. |
| Initial sync is slow | Expected — commands are throttled to protect the processor; a large project can take up to a minute to re-query all levels. |
See also
- Lutron — the Integrations page, home of the XML import for HomeWorks/QS processors.
- Lutron RA3 / HomeWorks QSX — the LEAP driver for current processors.
- Lutron Caséta — the LEAP driver for the Caséta Smart Bridge Pro.
- Zones — how zones, addresses, and control types work.
- Subsystems — the Lights / Shades / Fans groupings outputs land in.
- Triggers — firing macros from keypad button attributes.
- Commands — running and scripting device commands.
- Devices — adding and configuring devices.
- License — enabling the Lutron product.