-
-
Notifications
You must be signed in to change notification settings - Fork 18
Z Wave JS UI (MQTT)
Lock Code Manager supports Z-Wave locks bridged into Home Assistant through zwave-js-ui's MQTT discovery gateway — locks that show up as lock.* entities from the mqtt integration, not the zwave_js integration. This is a separate provider from Z-Wave, which covers Z-Wave JS's official websocket integration.
Consider the official Z-Wave integration instead. zwave-js-ui itself discourages MQTT discovery in favor of its websocket server, and the
zwave_jsintegration is the better-supported path in both Home Assistant and Lock Code Manager. Switching does not require re-pairing your locks or touching your Z-Wave network — enable the WS server in zwave-js-ui and add the Z-Wave JS integration in Home Assistant; only entity IDs change. This provider exists for setups already built around the MQTT entities.
zwave-js-ui can auto-discover its nodes into Home Assistant as mqtt-platform entities. Lock Code Manager identifies which of those entities are Z-Wave locks bridged by zwave-js-ui (as opposed to Zigbee2MQTT or any other MQTT bridge) from the device registry identifier zwave-js-ui publishes: zwavejs2mqtt_<home_id>_node<node_id>.
Unlike the Zigbee2MQTT provider, which reads and writes by publishing directly to value topics, this provider drives zwave-js-ui's MQTT API (<prefix>/_CLIENTS/ZWAVE_GATEWAY-<name>/api/sendCommand) to call the Z-Wave User Code command class's get, set, and clear methods — the same command class surface the Z-Wave provider reaches over the websocket integration. Each API call is tagged with a request nonce and matched against the response, so other MQTT clients calling the same gateway (the zwave-js-ui frontend, other automations) don't cross wires.
Only User Code CC locks are supported. User Credential (U3C) locks — the newer per-user model described on the Z-Wave page — are not supported by this provider; use the official Z-Wave JS integration for those locks.
- zwave-js-ui running with its MQTT gateway enabled, connected to the same broker as Home Assistant's MQTT integration
- Gateway Type Named or ValueID gives full functionality. Manual gateway type works in a reduced, polling-only mode — see Limitations
- Retain enabled in zwave-js-ui's MQTT settings is recommended. The gateway is normally identified directly from the lock's own discovery data; the fallback discovery path additionally needs the gateway's retained client-status topic
- A Z-Wave lock exposing the User Code command class (0x63)
- The lock entity must appear as
lock.*from themqttintegration in Home Assistant
| Operation | Supported | Notes |
|---|---|---|
| Set PIN | ✅ | Via zwave-js-ui's sendCommand API → User Code CC set
|
| Clear PIN | ✅ | Via zwave-js-ui's sendCommand API → User Code CC clear
|
| Read PIN | ✅ | Via zwave-js-ui's sendCommand API → User Code CC get, one slot per round trip |
| Push updates | ✅ | Via MQTT subscription to the node's value topics (Named or ValueID gateway type only) |
| Code slot events | ✅ | Via Notification CC publications (keypad lock/unlock) |
Locks discovered through zwave-js-ui's MQTT gateway require no provider-specific configuration in Lock Code Manager — they appear in the config flow's lock selector like any other lock, alongside websocket-integrated Z-Wave locks, Zigbee2MQTT locks, and everything else.
- In zwave-js-ui, confirm the MQTT gateway is enabled, Type is Named or ValueID, and Retain is on.
- Confirm the lock shows up as a
lock.*entity from Home Assistant'smqttintegration (via zwave-js-ui's discovery payloads). - Add the lock to a Lock Code Manager config entry's Locks selector, same as any other lock. See Adding and Removing Locks.
If you select an MQTT lock that Lock Code Manager can't attribute to a supported bridge (Zigbee2MQTT or zwave-js-ui), the config flow rejects the submission with an error naming the entity, rather than accepting it and leaving it permanently disconnected.
Lock Code Manager resolves which zwave-js-ui gateway serves a lock automatically. zwave-js-ui embeds its own status topic in every discovery payload it publishes, so each lock names its gateway directly — this handles any number of gateways, including several sharing one MQTT prefix. When a lock's discovery data lacks that entry, a fallback scan of the prefix's client-status topics runs instead:
- If exactly one zwave-js-ui gateway is visible under the lock's MQTT prefix, it's used directly.
- Multiple zwave-js-ui gateways are supported — for example, more than one Z-Wave network bridged under different prefixes on the same broker. When more than one gateway shares a prefix, Lock Code Manager queries each and matches the one reporting the lock's Z-Wave home ID.
- In the fallback scan only: if two gateways under the same prefix report the same home ID — typically a primary and secondary controller bridging one network — resolution is ambiguous and is refused rather than guessed.
Lock Code Manager subscribes to the lock's node topic and applies updates as they arrive:
- User Code value publications (PIN set/cleared, in either the Named or ValueID topic shape) confirm the slot's state without waiting for the next poll.
- Keypad lock/unlock events are delivered via Notification CC publications and fire the same
pin_usedcode slot events used by the Blueprints usage-limiting automations.
A hard refresh runs hourly to re-read every slot and catch anything a dropped MQTT message missed. Locks running in polling-only mode (Manual gateway type) are instead polled on a regular cadence.
- Manual gateway type runs in a reduced mode. Custom per-value topics can't be shape-parsed for the lock's node topic, so push updates and keypad events are unavailable; PIN reads, writes, and sync still work through the gateway api, with polling standing in for push. Switch to Named or ValueID for full functionality, including "unlocked by user" events.
- User Credential (U3C) locks are not supported. This provider currently speaks User Code CC only; U3C-only locks need the official Z-Wave integration.
- Duplicate gateways on one prefix are refused in the fallback discovery path only. See Gateway discovery above.
- Sequential slot reads: like the Zigbee2MQTT provider, PIN codes are read one slot at a time rather than in parallel, to avoid overwhelming the gateway and mesh.
As with the Zigbee2MQTT provider's expose_pin data, both directions of this provider's traffic — PIN reads, writes, and value publications — pass through your MQTT broker unencrypted. Secure the broker accordingly: require authentication, use TLS, and scope ACLs so only trusted clients can subscribe to or publish on the zwave-js-ui prefix. Avoid pasting raw MQTT traffic or debug logs containing PIN values into public bug reports.
Support for this provider is new. If you have tested Lock Code Manager with a Z-Wave lock bridged through zwave-js-ui's MQTT gateway, please open an issue or PR to add it to this list.
Confirm the lock's device identifier in Home Assistant's device registry ends with the <home_id>_node<node_id> pattern zwave-js-ui publishes (the prefix is zwavejs2mqtt_ by default but honors a custom UID_DISCOVERY_PREFIX).
Confirm Retain is enabled in zwave-js-ui's MQTT settings. Lock Code Manager discovers the gateway by reading its retained client-status topic (_CLIENTS/ZWAVE_GATEWAY-*/status); with Retain off, there's nothing to read on subscribe.
The selected MQTT lock's device identifier doesn't match a bridge Lock Code Manager recognizes (Zigbee2MQTT or zwave-js-ui). Confirm it's actually discovered by zwave-js-ui and not some other MQTT integration.
Check that the MQTT integration is connected in Home Assistant, that the zwave-js-ui gateway is online, and that the underlying Z-Wave node is not in a failed state in zwave-js-ui's control panel.
Getting Started
UI
Features
- Managing Guests and Rentals
- Services and Actions
- Blueprints
- Tracking lock state change events
- Using Condition Entities
- Unsupported Condition Entities
Advanced
Development
Troubleshooting
FAQ
Supported Integrations