feat(akuvox, schlage): converge legacy tag format to canonical lcm:<slot>: - #1242
Conversation
…lot>: PR C2 -- final piece of the user-tag idempotency rollout. Akuvox and Schlage have used a slot-encoding tag (``[LCM:<slot>] <friendly name>``) since they identify codes by name rather than slot. Converge on the canonical ``lcm:<slot>:<friendly name>`` format introduced for Matter (#1239) so the codebase has one convention across every provider that needs a name-side tag. Implementation is a single import swap per provider: the local ``_make_tagged_name`` alias now points at the canonical builder (``make_tagged_name``) instead of the deprecated legacy builder (``make_legacy_tagged_name``). Every existing call site that writes a tagged name now emits canonical format; no other code changes needed. Migration is implicit: ``_parse_tag`` already accepts both formats (tolerant parser added in #1238), so legacy-tagged users are still discovered by slot. On the next write that touches a code/user, the provider's ``async_set_credential`` recomputes the tagged name via ``_make_tagged_name`` (now canonical) and rewrites the lock-stored name. The friendly portion is preserved verbatim. Regression tests added: * Schlage: ``test_set_credential_migrates_legacy_format_tag_on_write`` -- seeds a ``[LCM:1] Guest`` code, asserts the post-write code is named ``lcm:1:Guest`` and that the legacy entry is cleaned up. * Akuvox: same shape; the modify_user call carries canonical name. Existing tests sweep: per-provider fixture seeds were converted from legacy to canonical format (representing the post-migration steady state). The ``parse_tag`` parametrize tests intentionally keep the legacy strings to lock in the tolerant parser's back-compat behavior; the legacy builder is no longer referenced anywhere. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Entire-Checkpoint: 2a0cca3bc821
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #1242 +/- ##
=======================================
Coverage 96.97% 96.98%
=======================================
Files 53 53
Lines 6153 6168 +15
Branches 461 461
=======================================
+ Hits 5967 5982 +15
Misses 186 186
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Pull request overview
This PR completes the Akuvox/Schlage portion of the user-tag idempotency rollout by switching those providers from emitting the legacy bracketed tag format ([LCM:<slot>] <name>) to the canonical tag format (lcm:<slot>:<name>), aligning them with other providers and the shared tolerant parser in providers/_util.py.
Changes:
- Switch Akuvox and Schlage providers to build tagged names using the canonical
make_tagged_name()helper. - Update provider and E2E tests to expect canonical tag strings by default.
- Add regression tests that confirm a legacy-tagged code/user is rewritten to canonical format on the next write.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
custom_components/lock_code_manager/providers/schlage.py |
Swap to canonical tag builder for all Schlage name writes. |
custom_components/lock_code_manager/providers/akuvox.py |
Swap to canonical tag builder for all Akuvox name writes. |
tests/providers/schlage/test_provider.py |
Update expectations to canonical tags; add legacy→canonical migration-on-write test. |
tests/providers/schlage/test_e2e.py |
Update E2E assertions to canonical tags. |
tests/providers/akuvox/test_provider.py |
Update expectations to canonical tags; add/adjust migration and set-credential tests. |
tests/providers/akuvox/test_e2e.py |
Update E2E assertions to canonical tags. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| from ._base import BaseLock | ||
| from ._util import make_legacy_tagged_name as _make_tagged_name, parse_tag as _parse_tag | ||
| from ._util import make_tagged_name as _make_tagged_name, parse_tag as _parse_tag | ||
| from .const import LOGGER |
| from ..domain.models import SlotCredential | ||
| from ._base import BaseLock | ||
| from ._util import make_legacy_tagged_name as _make_tagged_name, parse_tag as _parse_tag | ||
| from ._util import make_tagged_name as _make_tagged_name, parse_tag as _parse_tag | ||
| from .const import LOGGER |
|
|
||
| assert result is True | ||
| assert modify_calls[0]["name"] == "[LCM:1] Guest" | ||
| # Friendly portion preserved verbatim; only the format changed. |
Proposed change
Final piece of the user-tag idempotency rollout. Akuvox and Schlage have used a slot-encoding tag (
[LCM:<slot>] <friendly name>) since they identify codes by name rather than slot — same purpose, same mechanism, different format from what Matter and Z-Wave now use. This PR converges them on the canonicallcm:<slot>:<friendly name>format introduced in #1239, so every provider that needs a name-side tag uses the same convention.How it works
A single import swap per provider: the local
_make_tagged_namealias now points at the canonical builder (make_tagged_name) instead of the deprecated legacy builder (make_legacy_tagged_name). Every existing call site that writes a tagged name now emits canonical format; no other code changes needed.Migration
Migration is implicit and per-code/per-user, not a one-shot sweep:
_parse_tagalready accepts both formats (the tolerant parser landed in refactor(providers/_util): tolerant tag parser + new compact format builder #1238), so legacy-tagged codes are still discovered correctly by slot.async_set_credentialrecomputes the tagged name via_make_tagged_name(now canonical) and rewrites the lock-stored name.For a code LCM never touches after the upgrade, the legacy tag stays — and continues to work because the parser accepts it. The format converges as installs see normal LCM activity.
Regression coverage
test_set_credential_migrates_legacy_format_tag_on_write— seeds a[LCM:1] Guestcode, asserts the post-write code is namedlcm:1:Guestand the legacy entry is cleaned up.modify_usercall carries the canonical name.Existing tests were swept: per-provider fixture seeds were converted from legacy to canonical format (representing the post-migration steady state). The
parse_tagparametrize tests intentionally keep the legacy strings so the tolerant parser's back-compat behavior stays pinned; if the legacy branch is ever removed from_util.py, those tests will catch it.Type of change
Additional information
make_legacy_tagged_namehelper in_util.pyis no longer referenced by any provider. Keeping it for the upgrade window; can be removed in a future release once existing installs have rotated.Test plan
[LCM:<slot>]tagged user; verify the user's name is rewritten tolcm:<slot>:form after the write🤖 Generated with Claude Code