Process improvement plan: fixes, robustness, tests/CI, behavior, perf, docs (v1.18.1 → v1.22.1) - #12
Merged
Conversation
…iene cleanups v1.18.1 - services.yaml + strings.json/en.json: destination/source are Order numbers (profile CSV Order column), not Quartz Port Numbers; fix the misleading example values (#1) - diagnostics: redact router host via async_redact_data so diagnostics attached to public issues never leak the IP (#5) - helpers.device_info: drop dead first version-read block and unused pkg_version import (#16) - fix stale comments: ParseResult names are keyed by Order, dangling port-map comment in button.py, CLAUDE.md now documents the 60s keepalive probe (#17) - remove unused imports/variables: lock.py EntityCategory, binary_sensor.py router_display_name, sensor.py time, options_flow.py CONF_NAME, config_flow.py csv_was_uploaded (#18) - hacs.json: drop stale filename key left over from the card repo (#21) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NTy9wAPHGwy2FM5yyjxqPR
…nambiguous source labels v1.19.0 - config flow: set a host:port unique_id and abort when the router is already configured — the already_configured abort string is live now (#2) - hidden CSV rows: keep them in the name/port maps (MAGNUM still uses their Orders in .UV/.SV) but exclude hidden sources from the select dropdown options; persist hidden orders in entry.data and align the config/options flow wording with the actual behavior (#3) - .E storm guard: the reader now runs concurrently with the connect-time sweep; mnemonic sweeps (.RD/.RT) abort after 5 consecutive .E replies, and .E replies attributable to .I interrogation or mnemonic queries are counted in new interrogate_rejected/mnemonic_rejected stats instead of flooding recent_errors (#6) - destination select: options list and a label→Order reverse map are built once and cached (invalidated on name updates); duplicate Global Names get an ' (Order N)' suffix so every label resolves to exactly one source — also removes the per-take O(n) label scan and the per-state- write options rebuild (#11, #13, #14) - Clear CSV button now also clears namespaces and hidden-row data Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NTy9wAPHGwy2FM5yyjxqPR
- tests/: 55 pytest cases via pytest-homeassistant-custom-component — csv_parser (all 5 formats, hidden rows, Order≠Port, malformed rows), quartz_client dispatch (.UV/.A/.BA/.RAD/.RAT/.E/.X, order tracking, optimistic routing, sweep abort, end-to-end CR framing), helpers (user_can_route matrix, notify_blocked_route event/notification payloads), config flow (happy path, duplicate abort, cannot_connect), options-flow diff builders, select label dedup/hidden/namespace (#24) - .github/workflows/ci.yml: ruff + mypy + pytest + a strings.json ↔ translations/en.json equality assert (#25, #29) - .github/workflows/validate.yml: hacs/action + hassfest (#26) - pyproject.toml with pytest/ruff/mypy config; requirements_test.txt - annotate flows with ConfigFlowResult (FlowResult is deprecated) and import DeviceInfo under TYPE_CHECKING so ruff/mypy pass clean (#19) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NTy9wAPHGwy2FM5yyjxqPR
…reconnect backoff v1.21.0 - .E rollback: route() remembers (dest, prev_src); an .E within 5 s of the take restores the previous route and fires the route callback so the select snaps back. A .UV confirmation disarms the rollback; .I attribution now uses a bounded pending counter (keepalive probes excluded) so it can't swallow unrelated .E forever (#4) - entity listeners: all platforms register via helpers.subscribe_listener + async_on_remove, so partial platform reloads no longer leak dead callbacks (#7) - reconfigure flow: change host/port/name from the UI without deleting the entry — profile data, CSV names, and options are preserved; collisions with other entries abort as already_configured (#8) - reconnect backoff: configured reconnect_delay is the floor, doubling per failed cycle up to 120 s, reset on successful connect or when the option changes (#12) - tests: rollback/confirmation/stale-window, backoff sequence, reconfigure happy path + collision abort (63 tests total) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NTy9wAPHGwy2FM5yyjxqPR
…nnected property v1.22.0 - connect-time sweeps (.I routes, .BI locks, .RD/.RT names) now write 8 commands per drain with 50 ms between batches — a 512-destination matrix syncs in ~8 s instead of ~74 s; estimated_sync_seconds updated to match the batched pacing (#15) - over-provision detection runs when the sync sweep completes (driven by sync_callback + reply grace) instead of a fixed 10 s sleep per connect; the grace task is tracked and cancelled on disconnect/unload, so flapping connections no longer pile up untracked tasks (#10, #22) - Detect Destinations button awaits the interrogation drain (with stall detection for controllers that ignore .I) instead of sleeping 2 s (#10) - QuartzClient.stop() awaits the cancelled run loop; .P re-query tasks are tracked and cancelled on stop (#22) - new helpers.detection_status() is the single source of truth for the configured/detected/suggested numbers used by the Profile Mismatch sensor, the startup detection check, and the Detect button (#20) - public QuartzClient.connected property replaces all private _connected peeks (#23) - tests: batching, interrogation drain, detection status, listener unsubscribe, sync estimate (70 tests total) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NTy9wAPHGwy2FM5yyjxqPR
- README: document lock entities, connection/profile sensors, Detect Destinations, Clean Up Stale Entities, read-only destinations + allowed users, the evertz_quartz_route_blocked event contract with an example push automation, startup sync notification, batched sweeps, reconnect backoff, .E rollback, reconfigure, lock protocol commands, keepalive probe, and diagnostics redaction (#27) - CLAUDE.md: file map now lists lock/binary_sensor/sensor/tests/CI, the entity table covers all current entities, and new sections document hidden-row semantics, .E attribution, batched sync, backoff, unique_id/reconfigure, new stats, and the automated test suite (#28) - deflake the reconfigure test: patch setup/unload around the reload-triggering abort Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NTy9wAPHGwy2FM5yyjxqPR
…e state keys, hacs.json schema, MIT LICENSE v1.22.2 Caught by the new validate.yml on its first PR run: - manifest.json keys sorted (domain, name, then alphabetical) - log-level select state translation keys lowercased (hassfest requires [a-z0-9-_]+) - hacs.json: 'category' is not a valid key (it is the hacs/action input, not part of the repo manifest) - add the MIT LICENSE file the README already declares (HACS requires it) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NTy9wAPHGwy2FM5yyjxqPR
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.
Implements all 29 findings from the v1.18.0 code review & improvement plan, as six milestone commits (each with its own version bump, so the release workflow publishes v1.22.1 on merge).
Commits / milestones
v1.18.1 — pure fixes & hygiene (#1, #5, #16–18, #21)
services.yaml+strings.json/en.jsonnow describedestination/sourceas Order numbers with corrected examples — following the old docs routed the wrong source on any profile where Order ≠ Port (438 sources on the tested profile).host(safe to attach to public issues).helpers.device_info(), stale comments (ParseResult keying, button.py, CLAUDE.md keepalive), unused imports/variables, stalehacs.jsonfilenamekey.v1.19.0 — robustness (#2, #3, #6, #11, #13, #14)
{host}:{port}unique_id — adding the same router twice now aborts withalready_configured..UV/.SV) but excluded from source dropdowns; flow wording aligned with actual behavior..Estorm guard: the reader task runs concurrently with the connect-time sweep; mnemonic sweeps abort after 5 consecutive.E, and expected.Ereplies are counted in newinterrogate_rejected/mnemonic_rejectedstats instead of floodingrecent_errors.label → Orderreverse map; duplicate Global Names get an(Order N)suffix so every label resolves unambiguously (also removes the per-state-write rebuild and per-take O(n) scan).v1.20.0 — tests, CI, validation (#19, #24–26, #29)
pytest-homeassistant-custom-component: csv_parser (all 5 formats, hidden rows, Order≠Port, malformed rows), client dispatch (.UV/.A/.BA/.RAD/.RAT/.E/.X), optimistic routing, sweep abort, an end-to-end fake-router test for CR-only framing, permission matrix, blocked-route event payloads, config/options flows, select labels.ci.yml(ruff + mypy + pytest + strings.json ↔ en.json equality assert) andvalidate.yml(HACS + hassfest).ConfigFlowResult;DeviceInfoimported underTYPE_CHECKING.v1.21.0 — behavior (#4, #7, #8, #12)
.Ewithin 5 s (a.UVecho disarms the rollback).async_on_remove— no more leaked callbacks on partial platform reloads.v1.22.0 — performance & refactors (#10, #15, #20, #22, #23)
estimated_sync_seconds()matches.sync_callbackinstead ofsleep(10)per connect; grace/detection tasks tracked and cancelled on disconnect/unload.stop()awaits the cancelled run loop;.Pre-query tasks tracked.helpers.detection_status()replaces three copies of the configured/detected/suggested logic.QuartzClient.connectedproperty replaces all_connectedpeeks.v1.22.1 — docs (#27, #28)
evertz_quartz_route_blockedcontract with an example automation, startup sync notification, connection behavior, lock protocol commands.Verification
.Eattribution, sweep abort, optimistic routing + rollback all observed working.🤖 Generated with Claude Code
https://claude.ai/code/session_01NTy9wAPHGwy2FM5yyjxqPR
Generated by Claude Code