Skip to content

Add dual-connection support for HomeWorks QS status updates#130

Open
cdheiser wants to merge 1 commit into
thecynic:masterfrom
cdheiser:homeworks-dual-connection
Open

Add dual-connection support for HomeWorks QS status updates#130
cdheiser wants to merge 1 commit into
thecynic:masterfrom
cdheiser:homeworks-dual-connection

Conversation

@cdheiser

Copy link
Copy Markdown
Collaborator

Summary

HomeWorks QS (QNET) only delivers status updates to telnet sessions that did not originate the command. With a single connection, commands sent by pylutron never generate inbound handle_update callbacks for the caller's own actions -- lights/shades/motors appear to not respond even though the hardware moves.

This PR implements the standard industry workaround: when the QNET> prompt is detected after login, a second LutronConnection is opened for sending commands while the original connection is kept as a monitor-only session. On RadioRA 2 / QS Standalone (GNET>), behavior is unchanged -- single connection as before.

Changes

LutronConnection:

  • Detects the prompt type (GNET vs QNET) from the login response and exposes it via a prompt_type property and class constants PROMPT_GNET / PROMPT_QNET.
  • New enable_monitoring constructor parameter (default True). When False, the #MONITORING subscription commands are skipped during login. The command connection doesn't need monitoring -- the monitor connection handles all inbound status updates.

Lutron:

  • connect() checks prompt_type after the initial connection. If QNET, it creates a second LutronConnection with enable_monitoring=False and stores it as _cmd_conn.
  • send() routes commands through _cmd_conn when present, falling back to _conn on RadioRA 2.
  • New is_homeworks property for downstream consumers (e.g. Home Assistant) to detect the connection mode.
  • The command connection uses self._recv as its callback so that query responses (?OUTPUT,...) are still processed -- query responses return to the requesting session even on HWQS, unlike unsolicited status updates.

Wire diagram:

RadioRA 2 (GNET>):
  self._conn  ──── send + monitor + recv_cb ────  Controller

HomeWorks QS (QNET>):
  self._conn      ──── monitor + recv_cb ────┐
                                              ├──  Controller
  self._cmd_conn  ──── send + recv_cb ───────┘

Reconnection: Both connections use LutronConnection._main_loop independently, each handling their own reconnect-on-drop cycle. Since both connect to the same host, transient network issues will typically affect both simultaneously.

Test plan

  • New tests/test_homeworks.py with 11 tests:
    • Prompt type detection: GNET sets PROMPT_GNET, QNET sets PROMPT_QNET, None before login
    • Monitoring control: 7 #MONITORING commands sent when enabled, 0 when disabled
    • Lutron.connect() on GNET: no _cmd_conn created, is_homeworks is False
    • Lutron.connect() on QNET: _cmd_conn created, is_homeworks is True
    • Command routing: send() goes to _cmd_conn on HWQS, _conn on RadioRA 2
    • Status update dispatch: _recv on monitor connection fires handle_update
    • Integration test: mock QNET session receives status update lines through the full pipeline
  • Updated tests/test_connection.py: existing QNET login test now also asserts prompt_type
  • Full test suite passes (69 tests)
  • mypy --strict clean on all 16 source files
  • Manual verification on real HomeWorks QS hardware

🤖 Generated with Claude Code

HomeWorks QS (QNET) only delivers status updates to telnet sessions
that did not originate the command. With a single connection, commands
sent by pylutron never generate inbound status updates on that same
session, breaking handle_update callbacks for the caller's own actions.

When the QNET> prompt is detected after login, a second LutronConnection
is opened for sending commands while the original connection is kept as
a monitor-only session. This is the standard industry workaround for the
HWQS protocol limitation. On RadioRA 2 / QS Standalone (GNET>), behavior
is unchanged.

Changes to LutronConnection:
- Detect and expose the prompt type (GNET/QNET) via prompt_type property
- Add enable_monitoring flag to skip #MONITORING setup on the command
  connection (monitoring on the send session is unnecessary and could
  cause duplicate dispatches)

Changes to Lutron:
- After connect(), open a second connection when QNET is detected
- Route send() through the command connection when present
- Add is_homeworks property for downstream consumers

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@cdheiser

Copy link
Copy Markdown
Collaborator Author

@sergiobaiao this should make status updates in homeworks work better if you wanted to try it.

@sergiobaiao

Copy link
Copy Markdown

i'll get into it. Sorry for the lack of presence, health issues...

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