Offline-startup API - #9
Open
theharshl wants to merge 15 commits into
Open
Conversation
…and Lync clients, data models, constants, and tests.
- Update MCA bass/treble/balance range to -12..12 - Enforce step size of 4 for bass/treble and 6 for balance - Remove scaling logic from client and HA integration - Add unit tests for MCA audio control logic and rounding - Bump version to 0.0.26
…ance declaration SET_ECHO_COMMAND_CODE and QUERY_ID_CODE are already defined in constants.py — drop the defensive hasattr ternaries in lync_client.py. Also add the missing @AbstractMethod declaration for async_set_balance in base_client.py alongside async_set_bass and async_set_treble.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Populate _zone_names on every ZONE_NAME_RECEIVE_COMMAND regardless of whether zone_data exists yet. Expose get_zone_name(zone) -> str | None mirroring get_source_name(). Also initialize _zone_names in async_connect. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… cache tests Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
async_get_model_info() previously probed once with no retry, so a bad read (partial data, or a gateway that resets on DTR toggle when a USB serial adapter opens the port) left model_info as None, which crashed async_get_client() with a bare TypeError on model_info["kind"]. Wires the existing retry_attempts into the model probe, adds a settle delay after opening the serial port before the first write, and raises a clear ValueError instead of crashing when detection still fails. Fixes theharshl/htd-home-assistant#6
The model probe read the reply with a single StreamReader.read(), which returns as soon as any bytes are buffered — a cheap USB-serial adapter delivering a reply across several USB packets was misread as a failed probe. Reads now accumulate until the reply matches a known model, the line goes quiet, or an overall deadline expires; a silent device no longer hangs the probe forever. Probe retries also re-opened the serial port on every attempt, and each open can toggle DTR and reset the gateway — so retries kept resetting the device they were probing. The probe now opens the connection once, pays the settle delay once, and retries on the open connection. The persistent connection now waits out the same settle delay before its first refresh write, which was previously sent immediately after the port opened and could be lost to the same reset. Replaces utils.async_send_command with async_open_connection + async_read_response; renames MODEL_PROBE_SETTLE_DELAY to SERIAL_SETTLE_DELAY now that it also guards the persistent connection. Reported by @steve28 in theharshl/htd-home-assistant#19 (MCA-66 over USB-serial). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
A checksum mismatch means the parsed zone/command/length can't be trusted -- it may be a coincidental match on misaligned or corrupted bytes -- so skipping the full presumed frame length left the parser permanently desynced after a single dropped/corrupted byte from a flaky USB-serial adapter. Resync by header length only, matching the existing unknown-command recovery path, so one bad frame no longer cascades into a stream of "Bad sync buffer" / "Invalid command value" errors during normal zone control. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
… device is unreachable at setup
Give each SUPPORTED_MODELS entry a persistable "key" and add get_model_info(key) so a caller can rebuild the correct client class from storage alone, without probing the device. Add get_source_names() and get_zone_names() so only controller-confirmed names (never placeholders) are safe to persist across restarts.
…safe disconnect async_start() connects once and, on failure, hands off to a while-loop reconnect task guarded by a single handle (_ensure_reconnect_task) instead of the old self-rescheduling _async_reconnect, which left a window where connection_lost could see a stale, not-done task handle and fail to start a new attempt. disconnect() is now safe on a client that never connected and cancels any in-flight retry task. Updates test_reconnect_logic in test_base_client_coverage.py, which asserted the old self-rescheduling behavior (asyncio.create_task called from within _async_reconnect); it now asserts the loop's observable contract (two connect attempts, then return) instead.
…cted, and broadcast connection state - _send_cmd, HtdMcaClient.refresh, and HtdLyncClient.refresh now raise HtdConnectionError when the connection is None or not connected, instead of the AttributeError that came from writing to a None transport. - The heartbeat loop exits quietly on HtdConnectionError instead of dying with an unretrieved task exception. - connection_made and connection_lost each broadcast(None) so subscribed entities (should_poll = False) repaint on connect/disconnect transitions. - Fixed test fixtures/tests that set _connection but never _connected, which the new guard exposed as tests implicitly assuming a connected state: test_send_and_validate_success/timeout, htd_instance (test_client.py), lync_client (test_lync_client_coverage.py), mca_client (test_mca_client_coverage.py).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Groundwork so a consumer can construct a client and set up entities without the amplifier being reachable:
build_clientfactory, withasync_get_clientrewritten on top of it — construction is now separable from connection.async_startno longer raises when the device is unreachable; it returns and lets a single-handle reconnect loop retry with exponential backoff, logging each attempt.HtdConnectionErrorinstead ofAttributeError, and connection state is broadcast to subscribers.Existing callers are unaffected —
async_get_clientkeeps its signature and behavior.Tests: 200 passing.
Part of the fork-upstreaming stack — see hikirsch/htd-home-assistant#34. Based on L2; until that merges the diff above includes its changes too. Please merge with a plain merge commit so the rest of the stack stays intact.