Skip to content

fix(zwave_js): reconcile the driver value DB after User Code CC writes#1334

Merged
raman325 merged 2 commits into
mainfrom
fix/uc-post-write-reconcile
Jul 10, 2026
Merged

fix(zwave_js): reconcile the driver value DB after User Code CC writes#1334
raman325 merged 2 commits into
mainfrom
fix/uc-post-write-reconcile

Conversation

@raman325

Copy link
Copy Markdown
Owner

Proposed change

Follow-up to #1327, closing the remaining User Code CC gaps for users on the driver the Z-Wave JS add-on currently ships (15.25.0):

  • Supervised success never persists (Defect 2): on locks the driver dispatches to User Code CC, a supervised (S2) write through the unified access-control API emits the unified event but leaves the value database at its pre-write state, so every later cached read — including LCM's initial load after a restart — serves the stale slot and sync issues a redundant rewrite.
  • Supervised failure never reconciles (Defect 3): after a supervision FAIL nothing re-reads the slot, so an already-wrong cache entry stays wrong indefinitely.

Both are fixed upstream in driver 15.25.2 (zwave-js/zwave-js#8927), which the add-on has not shipped yet.

The bridge: after each write on a User-Code-CC-advertising node, _async_uc_reconcile_value_db reads the written slot back via access_control.get_credential — a fresh single-slot device read. On the User Code CC dispatch path the solicited report repairs the value database and doubles as a push through the #1327 report shim (confirming the write end-to-end); on a User Credential CC lock the driver dispatches natively and the read is merely redundant. The read is best-effort: a failure never changes the write outcome.

Precisely scoped call sites:

  • Confirmed set → read (Defect 2).
  • Definitive rejection / duplicate → read before raising (Defect 3).
  • OPTIMISTIC set → skipped: the seam's on-demand confirmation read already hard-refreshes for every optimistic write; a single-slot read would be pure duplication.
  • Transient failure (LockDisconnected) → skipped: the node is unreachable anyway.
  • Successful delete → skipped: the driver clears its cached User Code CC values on successful deletes since 15.24.3 (zwave-js/zwave-js#8866); failed deletes read back.

Self-sunsetting like the shim: get_credential is a supported API on both sides of the upstream transition — on ≥15.25.2 the read is merely redundant, and on the v16 branch (with zwave-js/zwave-js#8930) solicited reads still persist via the querying API methods. The helper lives inside the #1327 shim section and shares its removal recipe (updated in this PR), so the whole User Code CC bridge deletes as one unit once the minimum supported driver includes #8930.

Cost: one extra Z-Wave round-trip per credential write (writes are rare events), none for optimistic writes or successful deletes.

Type of change

  • Dependency upgrade
  • Bugfix (non-breaking change which fixes an issue)
  • New feature (which adds functionality)
  • Breaking change (fix/feature causing existing functionality to break)
  • Code quality improvements to existing code or addition of tests

Additional information

Checklist

  • The code change is tested and works locally.
  • Local tests pass. Your PR cannot be merged unless tests pass
  • There is no commented out code in this PR.
  • Tests have been added to verify that the new code works.

Full suite passes locally (1254 passed, 3 skipped); prek clean.

🤖 Generated with Claude Code

https://claude.ai/code/session_015tvvgVhy5F12XVyv6RQBv7

Drivers before 15.25.2 (zwave-js/zwave-js#8927) never persist a
supervised User Code CC write to the value database on success and
never re-read the slot on failure, so cached reads -- including LCM's
initial load after a restart -- serve stale slots. After each
confirmed or rejected write on a User Code CC node, read the slot
back through the unified API: the solicited report repairs the value
database and doubles as a push through the report shim.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015tvvgVhy5F12XVyv6RQBv7
Entire-Checkpoint: 50f3161621d5
Copilot AI review requested due to automatic review settings July 10, 2026 15:14
@github-actions github-actions Bot added python Pull requests that update Python code bug Something isn't working labels Jul 10, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR extends the Z-Wave JS provider to proactively reconcile the driver’s value database after User Code CC credential writes, mitigating stale cached reads on driver versions prior to the upstream fixes. It fits into the provider’s existing “User Code CC report shim” block as an additional bridge until the minimum supported driver includes the upstream corrections.

Changes:

  • Add a post-write single-slot read (get_credential) on confirmed writes and on definitive supervised rejections to force the driver cache to converge on User Code CC nodes.
  • Skip reconciliation reads for optimistic writes and transient transport failures, and for successful deletes (driver already clears cached values).
  • Add targeted provider tests + fixture support for access_control.get_credential.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

File Description
custom_components/lock_code_manager/providers/zwave_js.py Adds _async_uc_reconcile_value_db and wires it into set/delete credential paths; updates shim removal recipe.
tests/providers/zwave_js/conftest.py Extends the mocked access_control to include get_credential.
tests/providers/zwave_js/test_provider.py Adds test coverage for when reconciliation reads should/shouldn’t run and that failures are swallowed.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread custom_components/lock_code_manager/providers/zwave_js.py
@codecov

codecov Bot commented Jul 10, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 96.97%. Comparing base (ca59c22) to head (db88144).
⚠️ Report is 4 commits behind head on main.
✅ All tests successful. No failed tests found.

Additional details and impacted files

Impacted file tree graph

@@           Coverage Diff           @@
##             main    #1334   +/-   ##
=======================================
  Coverage   96.96%   96.97%           
=======================================
  Files          53       53           
  Lines        6429     6441   +12     
  Branches      473      473           
=======================================
+ Hits         6234     6246   +12     
  Misses        195      195           
Flag Coverage Δ
python 97.50% <100.00%> (+<0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
...components/lock_code_manager/providers/zwave_js.py 99.29% <100.00%> (+0.03%) ⬆️
🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

The rejection call sites run inside except clauses; an unexpected
exception from the read would replace the mapped typed error and
derail the seam's handling. Swallow broadly like the coordinator's
confirmation-read backstop: expected comms failures log at debug,
unexpected exceptions log at error with traceback since the log line
is the only remaining evidence of the bug.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015tvvgVhy5F12XVyv6RQBv7
Entire-Checkpoint: 7bc30d557a01
@raman325 raman325 merged commit 9a2408a into main Jul 10, 2026
18 checks passed
@raman325 raman325 deleted the fix/uc-post-write-reconcile branch July 10, 2026 15:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working python Pull requests that update Python code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants