Skip to content

Dispatch LEVEL_CHANGED event on set_level for QNET controllers#125

Open
GitDakky wants to merge 1 commit into
thecynic:masterfrom
GitDakky:fix/qnet-set-level-state-dispatch
Open

Dispatch LEVEL_CHANGED event on set_level for QNET controllers#125
GitDakky wants to merge 1 commit into
thecynic:masterfrom
GitDakky:fix/qnet-set-level-state-dispatch

Conversation

@GitDakky

@GitDakky GitDakky commented Apr 7, 2026

Copy link
Copy Markdown

Problem

HomeWorks QS processors (QNET protocol) do not echo back ~OUTPUT state changes on the same telnet connection that sent the #OUTPUT command. This means the LEVEL_CHANGED event was never dispatched after set_level(), causing Home Assistant to revert the UI toggle state.

Observed behaviour: Toggle a light on → light turns on → UI reverts to off. Toggle again → sends off command but light was already on, so nothing visible happens.

Root Cause

GNET controllers (original HomeWorks) echo the state change as a monitoring event (~OUTPUT,id,1,level), which triggers handle_update()_dispatch_event(). On QNET, handle_update() is never called for self-initiated changes because no echo is sent on the same connection.

Fix

Dispatch Output.Event.LEVEL_CHANGED immediately after updating self._level in set_level(). This is safe for both GNET and QNET:

  • QNET: This is the only notification that consumers receive — essential.
  • GNET: The echo will also trigger handle_update(), dispatching a second event with the same level. This is harmless as consumers (like HA) are idempotent for same-value updates.

Testing

Tested on Lutron HomeWorks QS Gulliver processors (firmware 15.10.0) — 558 entities (lights, switches, shades, occupancy sensors). Light toggles now correctly reflect state in Home Assistant.

Related: PR #122 added QNET prompt support. This PR completes QNET compatibility for state management.

HomeWorks QS processors (QNET protocol) do not echo back ~OUTPUT
state changes on the same telnet connection that sent the command.
This means the LEVEL_CHANGED event was never dispatched after
set_level(), causing Home Assistant to revert the UI state.

GNET controllers (original HomeWorks) echo the state change as a
monitoring event, so the event was dispatched via handle_update().
On QNET, handle_update() is never called for self-initiated changes.

This fix dispatches the event immediately after updating the internal
level, ensuring HA (and any other consumer) gets notified regardless
of controller protocol.

Tested on Lutron HomeWorks QS Gulliver processors (firmware 15.10.0)
at Longueville Hall, Jersey — 558 entities, lights/switches/shades.
@cdheiser

cdheiser commented Apr 7, 2026

Copy link
Copy Markdown
Collaborator

Wow... HomeWorks QS is just a pile of odd behavior and poorly documented gems.

This could result in some odd behavior. With RadioRA2, we get back that actual levels/state and update that before dispatching an event. On HomeWorks QS, we'll report a level that may not be accurate/correct. For example, if we try to set a motor to 50%, HomeWorks QS will just refuse if it's not supported by the motor, but we'd just silently report to the user that we changed the level successfully.

Querying the controller right away won't make things better either, as a device could be mid-state-transition.

There are 2 paths I could see going down:

  1. Implement QS-Quirks mode where we blindly dispatch the event if we saw QNET when logging in
  2. Implement a listener connection for the monitoring of state changes

I'm somewhat inclined to attempt number 2.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants