# zLock Slots Home Assistant custom integration for managing user-code slots on Z-Wave locks, with per-lock "last action" / "last user" tracking and a Lovelace card for inline slot management. Requires Home Assistant **2026.7.0 or later** and locks connected through the built-in `zwave_js` integration. ## Installation Install via [HACS](https://hacs.xyz/) as a custom repository (`https://git.zi3.xyz/code/zlock_slots`, category *Integration*), or copy `custom_components/zlock_slots/` into your HA `config/custom_components/` directory. Restart Home Assistant, then add the integration under **Settings → Devices & services → Add integration → zLock Slots** and select the Z-Wave lock(s) to manage. The integration's options (⚙ on the integration entry) let you add/remove locks later and define **groups** — named sets of locks that publish a shared last-action / last-user sensor. ## Entities For each configured lock (`lock.`): | Entity | State | |---|---| | `sensor._last_action` | `locked` / `unlocked`, or unknown until the first event | | `sensor._last_user` | slot name (or number), `` for physical operation, `` for HA/Z-Wave commands | | `sensor._slots` | count of occupied code slots; `attributes.slots` lists `{slot_num, status, name}` | Each group gets its own `last_action` / `last_user` sensor pair, updated by events from any lock in the group, plus a `slots` sensor showing the union of occupied slots across its member locks (a slot present on any member appears; status/name come from whichever member has it first — groups don't reconcile disagreements between members). Last action/user survive HA restarts. Slot names are stored by the integration (they are not written to the lock) and are preserved when a code is cleared. ## Services Every service takes exactly one of `lock_entity_id` or `group_name`, plus: | Service | Fields | Notes | |---|---|---| | `zlock_slots.set_code` | `slot` (optional), `code`, `name` (optional) | Omit `slot` to auto-assign the lowest free slot | | `zlock_slots.clear_code` | `slot` | Slot name is preserved | | `zlock_slots.set_name` | `slot`, `name` | Set an empty name to remove it | | `zlock_slots.set_slot_enabled` | `slot`, `enabled` | Enable/disable without changing the PIN | Targeting a `group_name` fans the operation out to every lock in the group. Failures on individual locks are logged but don't block the others or roll back — a group is a convenience for acting on several locks at once, not a sync guarantee. When auto-assigning a slot for a group, the lowest slot unused by *any* member is chosen, so the same slot number lands on all of them. ### `zlock_slots.copy_slots` A hardware-migration helper for replacing one lock with another, not a routine card operation. Takes `source_lock_entity_id` and `target_lock_entity_id` (both required, must differ, both must already be managed by this integration) and fully mirrors the source's Z-Wave user-slot profile — codes, enabled/disabled status, and slot names — onto the target. This is a full mirror: any slot occupied on the target with no counterpart on the source is deleted. Slot 0 is reserved by Z-Wave and never shown or written. ## Lovelace card The card is registered automatically as a dashboard resource (`/zlock_slots/zlock-slots-card.js`). If your dashboards are YAML-managed, add it manually as a JavaScript module resource. ```yaml type: custom:zlock-slots-card entity: sensor.front_door_slots # the *_slots sensor (lock or group) lock_entity_id: lock.front_door # — or group_name: All Locks title: Front Door # optional ``` The card lists occupied slots with inline editing: click a name to rename it, use the row icons to change a PIN, enable/disable, or clear a slot, and use the form at the bottom to add a code (slot number optional — auto-assigns). ## Development ```sh uv run pytest ``` Tests run against the pinned Home Assistant version from `pytest-homeassistant-custom-component` (kept in sync with the minimum supported HA release declared in `hacs.json`).