locks.md: document durable sync architecture + nightly backup
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -46,7 +46,7 @@ user-invocable: true
|
|||||||
|
|
||||||
<references>
|
<references>
|
||||||
<reference file="reference/locks.md"
|
<reference file="reference/locks.md"
|
||||||
summary="Door locks: two zwave_js keypad locks, 8 code slots via input_text/input_boolean helpers, script.lock_sync_all_codes + per-slot automations, fix for 'userCode for code slot N not found'"
|
summary="Door locks: two zwave_js keypad locks, 8 code slots via helpers, lock_sync_slot single-source script + all-codes wrapper + per-slot and self-healing automations, usercode-cache fix, nightly git backup"
|
||||||
categories=["home-automation"]
|
categories=["home-automation"]
|
||||||
keywords=["lock", "locks", "door code", "door codes", "usercode", "code slot", "keypad", "lock_sync_all_codes", "set_lock_usercode", "zwave", "front door", "bunkhouse"] />
|
keywords=["lock", "locks", "door code", "door codes", "usercode", "code slot", "keypad", "lock_sync_all_codes", "set_lock_usercode", "zwave", "front door", "bunkhouse"] />
|
||||||
</references>
|
</references>
|
||||||
|
|||||||
+31
-14
@@ -10,23 +10,40 @@ Slot 1 = Fritz family, 2 = cleaner, 4 = carpenter, 5 = backup.
|
|||||||
</overview>
|
</overview>
|
||||||
|
|
||||||
<sync>
|
<sync>
|
||||||
`script.lock_sync_all_codes` (mode: queued) walks slots 1–8; for each slot it
|
All code writes go through `script.lock_sync_slot` (fields: `slot` 1–8), the
|
||||||
calls `zwave_js.set_lock_usercode` on BOTH locks — the slot's code if its
|
single source of truth. Per slot it: resolves the code (slot's own code if
|
||||||
`_enabled` boolean is on, otherwise the slot-1 family code (hardcoded in the
|
`_enabled` on, else the slot-1 family code), REFUSES non-4-10-digit codes
|
||||||
script's default branches). `automation.lock_slot_N_sync_both_locks` (per slot)
|
(persistent notification "slot N SKIPPED", nothing written), then per lock does
|
||||||
also pushes on helper change. An error on any step ABORTS the script — later
|
a UserCode CC `get` (repopulates the Z-Wave value cache so a missing cached
|
||||||
slots and the second lock do not sync.
|
slot can't error) followed by `zwave_js.set_lock_usercode` — every zwave call
|
||||||
|
`continue_on_error` so one lock/slot never blocks the rest.
|
||||||
|
|
||||||
The `input_boolean.lock_code_slot_N_*` / `input_text.lock_code_slot_N_*` /
|
- `script.lock_sync_all_codes` — warns (persistent + `notify.mobile_app_donavan_s_iphone_16_pro`)
|
||||||
`input_boolean.lock_slotN_lodge/bunkhouse_enabled` entities are unavailable
|
if a lock's `*_node_status` sensor isn't alive/asleep, then runs
|
||||||
leftovers from earlier schemes — ignore.
|
`lock_sync_slot` for slots 1–8.
|
||||||
|
- `automation.lock_slot_N_sync_both_locks` (×8) — trigger on the slot's
|
||||||
|
`_enabled` OR `_code` helper change → `lock_sync_slot` for that slot.
|
||||||
|
- `automation.lock_codes_full_sync_self_heal` — full sync daily 04:00 and
|
||||||
|
10 min after HA start, so transient failures heal within a day.
|
||||||
|
|
||||||
|
Disabled slots are overwritten with the family code (design choice), so the
|
||||||
|
family code exists in multiple lock slots.
|
||||||
</sync>
|
</sync>
|
||||||
|
|
||||||
<troubleshooting>
|
<troubleshooting>
|
||||||
Error `userCode for code slot N not found` from `zwave_js.set_lock_usercode`
|
Error `userCode for code slot N not found` from `zwave_js.set_lock_usercode`
|
||||||
= Z-Wave JS value cache has no userCode value for that slot (never
|
= Z-Wave JS value cache has no userCode value for that slot, NOT a lock or code
|
||||||
queried/interviewed), NOT a lock or code problem. Fix by forcing a UserCode CC
|
problem. The sync script's pre-`get` prevents it; manual fix:
|
||||||
read to repopulate the cache, then re-run the sync script:
|
`zwave_js.invoke_cc_api {device_id, command_class: "99", method_name: "get", parameters: [N]}`
|
||||||
`zwave_js.invoke_cc_api {device_id, command_class: "99", method_name: "get", parameters: [N]}`.
|
then re-run the sync.
|
||||||
(2026-07-05: lodge slot 3 hit this; gets were run for slots 1–8 on both locks.)
|
|
||||||
</troubleshooting>
|
</troubleshooting>
|
||||||
|
|
||||||
|
<backup>
|
||||||
|
Scripts/automations/dashboards/helper-definitions are mirrored to
|
||||||
|
`dfritz/home-assistant` repo under `lodge/` (API export — the lodge HA has no
|
||||||
|
SSH). Nightly Gitea Actions workflow `.gitea/workflows/backup-ha.yaml` IN THIS
|
||||||
|
SKILL REPO (secrets `HA_TOKEN` + `GIT_TOKEN` on skills/thelonglakelodge; ops
|
||||||
|
lacks rights to put secrets on dfritz/home-assistant) exports and pushes only
|
||||||
|
on change; failure emails via action/notify-email. Manual run: the workflow's
|
||||||
|
`workflow_dispatch`, or `HA_TOKEN=... lodge/backup.sh` in the mirror repo.
|
||||||
|
</backup>
|
||||||
|
|||||||
Reference in New Issue
Block a user