feat: route User Code CC setValue calls through access control API, bump schema to 51#1566
feat: route User Code CC setValue calls through access control API, bump schema to 51#1566raman325 wants to merge 5 commits into
Conversation
…ump schema to 51 zwave-js removed setValue support for User Code CC user codes, making the unified access control API the only way to manage them. Route legacy setValue calls (setting userCode, or setting userIdStatus to Available) through that API so clients that still use the setValue path keep working. The routing applies to all schema versions since the legacy path no longer exists. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR preserves compatibility for legacy clients that use node.set_value to manage User Code CC credentials by routing those specific setValue calls through the unified Access Control API introduced/required by upstream zwave-js changes. It also bumps the documented API schema to reflect this behavioral change while keeping the response shape stable for callers.
Changes:
- Add a best-effort shim in the node
setValuehandler to translate legacy User Code CC writes intoaccessControl.setCredential(...)/accessControl.deleteCredential(...). - Convert
SetCredentialResultback into aSetValueResultso the outwardnode.set_valueresponse remains consistent. - Bump
maxSchemaVersionto 51 and document the behavior inAPI_SCHEMA.md.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| src/lib/node/message_handler.ts | Adds User Code CC setValue routing via Access Control API and result conversion logic |
| src/lib/const.ts | Bumps supported schema max from 50 to 51 |
| API_SCHEMA.md | Documents schema 51 behavior change for legacy User Code CC node.set_value writes |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
…rol API Audit of the legacy UserCodeCC setValue implementation against the next branch found two more removed paths that have access control equivalents: - adminCode (and the pre-rename masterCode alias) -> setAdminCode(), converted via supervisionResultToSetValueResult - userIdStatus Enabled/Disabled/Messaging -> setUser() with the matching active/userType options, mirroring the reverse mapping zwave-js uses internally userIdStatus = PassageMode has no access control equivalent and is documented as no longer supported. keypadMode keeps working through setValue upstream and needs no routing. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…o SetValueResult - Accept Uint8Array user codes in the setValue shim, matching the removed UserCodeCC SET_VALUE implementation and accessControl.setCredential - Catch the Argument_Invalid error thrown by setUser when a User Code CC slot has no cached code and convert it to an InvalidValue SetValueResult so all routed paths return a consistent result shape Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ed slot setCredential on User Credential CC devices requires an existing user, so legacy clients could never create a new user/code through the shim. Route through addUser when no cached user exists for the slot, which creates the user and credential together on both CC paths. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
AlCalzone
left a comment
There was a problem hiding this comment.
LGTM. Do you have any way to test this?
|
If I build everything locally I can try the old services in HA which will exercise this path. I can't test all the conditions but I can validate at least the set and delete get done properly. I'll look into this later today |
|
tested and successfully working (I had to send Websocket commands manually since, per my comment on Discord, HA services are going to break and there's nothing we can do about it) |
Summary
zwave-js (zwave-js/zwave-js#8930, targeting
next) made the unified Access Control API the source of truth for User Code CC: theuserCode/userIdStatus/adminCodevalues became internal and theirsetValue/pollValuesupport was removed. Clients that manage user codes via thenode.set_valuepath (e.g. existing Home Assistant installs) would silently break once the server ships a driver containing that change.This PR routes those legacy
setValuecalls through the access control API on a best-effort basis, covering every path the oldUserCodeCCSET_VALUE implementation supported:setValuecalluserCode(string)accessControl.setCredential(...)userIdStatus=AvailableaccessControl.deleteCredential(...)userIdStatus=EnabledaccessControl.setUser(userId, { active: true })userIdStatus=DisabledaccessControl.setUser(userId, { active: false })userIdStatus=MessagingaccessControl.setUser(userId, { active: true, userType: NonAccess })adminCode/masterCode(string)accessControl.setAdminCode(...)Not routed:
keypadModestill works throughsetValueupstream, anduserIdStatus=PassageModehas no access control equivalent (documented as no longer supported).Implementation notes:
getCredentialCapabilitiesCached()(PIN code, or Password for locks that allow non-PIN characters) rather than hardcodedvalueId.endpoint, and anything unroutable (other properties/values, non-numeric propertyKey, unsupported endpoint/type) falls back tonode.setValueunchangedSetValueResult(SetCredentialResult/SetUserResultvia local converters,setAdminCode's supervision result viasupervisionResultToSetValueResult) so the response shape is unchanged for callersThe routing intentionally applies to all schema versions: the clients that need it are the ones that have not adopted the access control API, and the legacy behavior it would otherwise preserve no longer exists in zwave-js. Schema 51 documents the behavior change; clients targeting schema 51+ should use the
endpoint.access_controlcommands directly.Changes
src/lib/node/message_handler.ts:trySetUserCodeValue()shim + result converterssrc/lib/const.ts:maxSchemaVersion50 → 51API_SCHEMA.md: Schema 51 entryTesting
prettier --check,tsc --noEmit, andeslintpasstsx src/test/integration.tspasses🤖 Generated with Claude Code