Main

How to Stage a Hub Migration When Both Old and New Systems Need to Control the Same Lock

Migrating a smart lock from one hub to another is not a cutover. It is a staged handoff where two controllers temporarily share authority over a single mechanical device. The main entity here is dual-control staging: the practice of keeping an old hub and a new hub both able to lock and unlock the same deadbolt while you move automations, users, and monitoring from one to the other. Adjacent concepts include Zigbee2MQTT coordinator migration, Z-Wave JS controller shift, Home Assistant instance duplication, MQTT topic namespacing, and lock user-code synchronization. This matters because locks are not lights. A failed migration on a lamp is an inconvenience; a failed migration on a front door is a physical security event. The procedure below is the one I use when a resident or small-office operator cannot tolerate a gap in lock control.

I have run this on Schlage and Yale Z-Wave locks, on Kwikset Zigbee models, and on a few ESPHome-driven relay locks that are really just a solenoid and a reed switch. The numbers below are from those installs, not from a lab. Where I have not tested something, I say so.

Why dual control is harder than it sounds

A lock is a stateful device with a finite radio. It can usually be paired to one primary controller at a time. Some Z-Wave locks support multiple association groups, which lets them report state to more than one hub, but only one hub holds the S2 security keys and the user-code slots. Zigbee locks are similar: one coordinator owns the network, and a second coordinator cannot simply join as a peer. So “both systems control the same lock” almost never means the lock is simultaneously paired to two networks. It means one of these three arrangements:

  • Controller shift: the lock stays paired to the old network, and the new hub is added as a secondary controller or via a bridge.
  • Parallel pairing: the lock is excluded from the old network and included on the new one, while the old hub retains control through a different path (a cloud integration, a keypad code, or a manual override).
  • Physical parallel: the lock is on the new network, and the old system keeps a non-radio path such as a keypad code, a mechanical key, or a dry-contact relay wired to the lock’s remote input.

Each has a different failure mode. Controller shift is the cleanest but depends on the lock firmware supporting it. Parallel pairing is the most common but creates a window where neither hub is fully authoritative. Physical parallel is the most reliable but the least elegant, and it is often the right answer for a small office with a single door.

Pre-flight: what to inventory before you touch the lock

Before any migration, I build a one-page inventory. This is not optional. The inventory prevents the most common failure: discovering mid-migration that a lock has 14 user codes and you only know 6 of them.

Lock-side inventory

  • Model and firmware version, read from the hub’s device page, not from the sticker.
  • Radio protocol and security class: Z-Wave S0, S2 Unauthenticated, S2 Authenticated, or Zigbee with install code.
  • Number of user-code slots and which slots are occupied.
  • Whether the lock supports remote code management or only local keypad programming.
  • Battery level and last wake-up interval. A lock that wakes every 6 hours will make your migration take 6 hours if you wait for it.

Hub-side inventory

  • Old hub: network keys, controller node ID, and whether it is the primary or secondary controller.
  • New hub: coordinator firmware version, network keys, and whether it is running a fresh network or an existing one.
  • Automations that reference the lock: name, trigger, and whether they are time-based, presence-based, or manual.
  • Integrations that read lock state: dashboards, notifications, logging, and any third-party service.

If you are running Home Assistant, the Z-Wave JS integration documentation and the Zigbee2MQTT FAQ are the two references I keep open. They are not migration guides, but they define the controller and network-key behavior you are working within.

For a broader audit of the small systems around the lock, the internal piece on auditing the small systems that quietly run your week is a useful companion. The lock is rarely the only device that needs a migration plan.

The three staging patterns, with tradeoffs

Pattern A: Controller shift (Z-Wave only, and only sometimes)

Z-Wave supports a controller shift where the old primary becomes a secondary and the new hub becomes primary. In theory, the lock stays paired and both controllers can send commands. In practice, I have seen this work cleanly on Aeotec and HomeSeer controllers with older locks, and I have seen it fail on locks that require S2 Authenticated inclusion because the new controller cannot inherit the S2 keys without re-inclusion. If your lock is S2 Authenticated, assume you will need to exclude and re-include. Test the shift on a non-critical device first.

Tradeoff: least disruption if it works, highest uncertainty if it does not. I would not schedule this on a Friday afternoon.

Pattern B: Parallel pairing with a control gap

This is the most common approach. You exclude the lock from the old network, include it on the new one, and accept a window where the old hub cannot control it. The window is usually 2 to 10 minutes per lock, but it can stretch to an hour if the lock is sleepy or if the inclusion fails and you have to retry.

To reduce the gap, I stage the new hub’s automations and user codes before the exclusion. The new hub should be ready to send its first command the moment the lock appears. I also keep a physical key or a keypad code active during the window. If the lock is the only entry to a space, this pattern is not acceptable without a human standing at the door.

Tradeoff: simple, well-understood, but creates a real security gap. Use it for interior doors or when someone is on site.

Pattern C: Physical parallel

Here the old system keeps a non-radio path. That might be a keypad code that the old hub manages through the lock’s local programming, a mechanical key, or a dry-contact input on the lock that the old hub can trigger through a relay. The new hub takes the radio path. Both systems can lock and unlock, but they do not share a network.

This is the pattern I recommend for small offices with one or two doors. It is boring, it works during a network outage, and it does not depend on firmware behavior. The tradeoff is that state synchronization is manual: the old system may not know the lock was unlocked by the new system unless you wire a status contact back.

Step-by-step staging procedure

This procedure assumes Home Assistant on both sides, but the logic applies to Hubitat, SmartThings, or a vendor hub. The order matters.

1. Freeze changes on the old hub

Stop adding users, stop editing automations, and note the current state. If you have a change log, mark the freeze time. This prevents the classic failure where a new user code is added during migration and never copied to the new hub.

2. Build the new hub’s lock entry in advance

On the new hub, create the device entry, the dashboard card, and the automations, but leave them disabled. For Z-Wave JS, you can pre-create the node entry only after inclusion, so instead prepare the automation blueprints and scripts with a placeholder entity ID. For Zigbee2MQTT, you can pre-configure the friendly name and the MQTT topic in configuration.yaml before the device joins.

3. Namespace your MQTT topics

If both hubs publish lock state to MQTT, use separate topic prefixes. I use home/old/lock/front and home/new/lock/front during the migration, then collapse to one prefix after cutover. This prevents the two hubs from fighting over retained messages. A retained locked message from the old hub can make the new hub’s dashboard show the wrong state for hours.

4. Export user codes

Read every occupied user-code slot from the old hub. If the old hub cannot read codes, you will need to read them from the lock’s programming interface or accept that you will re-enter them. I have not found a reliable way to extract codes from a lock that does not expose them over the radio. Plan for manual re-entry.

5. Choose your staging pattern and announce the window

For a residence, the window is usually 15 minutes. For a small office, I schedule it outside business hours and tell the affected people. If the lock is the only entry, someone stands at the door with a key.

6. Exclude from the old network

Put the old hub in exclusion mode, then trigger exclusion on the lock. On most Z-Wave locks this is a keypad sequence; on Zigbee it is usually a button hold. Confirm the old hub shows the device as removed. Do not skip this confirmation. A half-excluded lock can leave stale routes that confuse the new network.

7. Include on the new network

Put the new hub in inclusion mode with the correct security class. For S2 Authenticated, have the DSK ready. For Zigbee, use the install code if the lock supports it. Watch the interview process. If the lock is sleepy, you may need to wake it manually several times. I have seen a Yale Z-Wave lock take 40 minutes to complete an interview because it woke only on keypad press.

8. Verify state and control

Lock and unlock from the new hub. Confirm the state changes in the new hub’s dashboard. Then check the old hub: it should show the device as unavailable or removed. If the old hub still shows a stale state, clear the retained MQTT message or remove the device entry.

9. Re-enter user codes

Add the codes to the new hub. Test each one at the keypad. This is the step people skip, and it is the step that generates support calls. If the lock supports remote code management, push the codes from the new hub and verify at the door.

10. Re-enable automations and monitor for 72 hours

Enable the new hub’s automations one at a time. Watch the lock’s battery level and wake-up behavior. A lock that was fine on the old network may behave differently on the new one if the route is longer or the coordinator is weaker. I check the Z-Wave JS network graph or the Zigbee2MQTT map after 24 hours.

Graceful degradation when things fail

The migration is not done when the new hub controls the lock. It is done when you know what happens when the new hub fails.

  • Power loss: the lock should fail to its last mechanical state. Most deadbolts stay locked or unlocked as set. Test this by pulling the hub’s power, not the lock’s batteries.
  • Network loss: the keypad code should still work. If your lock relies on the hub for code validation, a network outage locks out every user. I have not seen a residential lock that does this, but some commercial models do.
  • Cloud loss: if the old hub was cloud-dependent and the new hub is local-first, the migration is an improvement. If the new hub is also cloud-dependent, you have not gained reliability, only changed vendors.
  • Coordinator failure: keep a backup of the new hub’s network keys and configuration. For Zigbee2MQTT, that is the coordinator_backup.json and the database.db. For Z-Wave JS, it is the zwave-js cache and the network keys. Without these, a coordinator failure means re-including every device.

If the lock is the only entry and the building has no staff, a mechanical timer or a plain keyed switch is the smarter choice. I say that without irony. A smart lock adds convenience and auditability, but it also adds a failure domain. If the cost of that failure domain is higher than the convenience, do not stage the migration. Keep the mechanical path.

What I would do differently for a small office

For a small office with one door and a handful of staff, I would use Pattern C and not migrate the lock at all during business hours. I would keep the old hub controlling the lock through a keypad code, bring the new hub online for monitoring and logging only, and schedule the radio migration for a maintenance window when the office is empty. The new hub can read lock state through a separate sensor if the lock supports it, or through a door sensor and a relay.

For a residence, Pattern B is usually fine because someone is home. The gap is short and the risk is low. The exception is a rental property or a vacation home where no one is on site. There, I would use Pattern C or wait until someone can be present.

FAQ

Can a Z-Wave lock be paired to two hubs at the same time?

Not in the way most people mean. A Z-Wave lock has one primary controller that holds the security keys and manages user codes. It can report state to multiple controllers through association groups, but only one controller can include or exclude it. A controller shift can move primary authority to a new hub, but the lock is still on one network. If you need two independent control paths, use a physical parallel arrangement.

How long does a lock migration take?

For a Z-Wave lock that is awake and responsive, exclusion and inclusion take 2 to 5 minutes. For a sleepy lock, plan 30 to 60 minutes. The full procedure, including user codes and automation verification, takes 1 to 2 hours per lock. I have not seen a lock migration that took less than 45 minutes end to end, including testing.

What happens to user codes during migration?

They are stored in the lock, not the hub, in most residential models. Excluding the lock from the old network does not erase the codes. Including it on the new network also does not erase them. The new hub may not be able to read them, so you will need to re-enter them if you want the new hub to manage them. If the lock supports remote code management, the new hub can overwrite slots, but it cannot read existing codes unless the lock exposes them.

Do I need to exclude the lock before including it on the new hub?

Yes, for both Z-Wave and Zigbee. A lock that is still paired to the old network will not join a new one. Some hubs offer a “replace” or “migrate” function that handles the exclusion and inclusion in one step, but the underlying process is the same. If you skip exclusion, the inclusion will fail or the lock will appear as a ghost node.

What is the safest way to migrate a lock that is the only entry?

Use a physical parallel path. Keep a mechanical key or a keypad code active, and have someone on site during the radio migration. If no one can be on site, do not migrate the lock until someone can be. The convenience of a local-first hub is not worth a lockout.

The takeaway

Staging a hub migration for a lock is a sequencing problem, not a technology problem. Inventory first, choose a pattern that matches your tolerance for a control gap, namespace your MQTT topics, and test the failure modes before you call it done. If the lock is critical and no one can be present, the mechanical path is not a compromise. It is the correct engineering choice.

Next, I will write about how to back up and restore a Zigbee2MQTT coordinator without re-pairing every device. That is the step that turns a 2-hour migration into a 20-minute one, and it is the part most people skip until they need it.