Skip to content

Yale Durus / MD-04I – BLE updates time out and disconnect, despite LockInfo working #279

@philbert

Description

@philbert

Describe the bug
I have a Yale Durus lock that reports as model MD-04I over BLE. Using yalexs-ble via the Yale Access Bluetooth integration in Home Assistant, the library can successfully connect and obtain LockInfo (manufacturer/model/serial/firmware), but any further update attempts time out or disconnect.

In practice this means:

  • The lock is discovered, and BLE connection succeeds briefly.
  • LockInfo is retrieved correctly:
    LockInfo(manufacturer='yale', model='MD-04I', serial='LQHEW0007T', firmware='1.8.0')
  • Subsequent calls to PushLock._update() repeatedly end with TimeoutError and BleakConnectionError: Failed to connect after 1 attempt(s): Disconnected.
  • The integration never reaches a stable “connected and updating” state, so the lock is unusable over BLE.

So it looks like MD-04I is at least partially supported (Device Info works), but the encrypted/push/update path is not behaving as expected for this model/firmware.

To Reproduce

  1. Add the lock to the Yale Home app (works correctly).
  2. Add the lock to Home Assistant via the Yale cloud integration (works correctly).
  3. Add / enable Yale Access Bluetooth integration (yalexs_ble).
  4. Home Assistant sees the lock’s BLE MAC and attempts to connect.
  5. BLE session immediately disconnects and retries indefinitely.

This happens with ESPHome BLE proxy with a strong RSSI, so range/interference is ruled out.

Additional context

2025-11-24 23:17:54.612 DEBUG (MainThread) [yalexs_ble.push] Obtained lock info: LockInfo(manufacturer='yale', model='MD-04I', serial='LQHEW0007T', firmware='1.8.0')
2025-11-24 23:17:54.613 DEBUG (MainThread) [yalexs_ble.push] Needs battery workaround model MD-04I: False
2025-11-24 23:17:59.219 DEBUG (MainThread) [yalexs_ble.push] Garage back (B0:44:9C:05:05:2A): Disconnect timer reset due to operation lock
2025-11-24 23:17:59.219 DEBUG (MainThread) [yalexs_ble.push] Garage back (B0:44:9C:05:05:2A): Resetting disconnect timer to 5.1 seconds
2025-11-24 23:18:04.320 DEBUG (MainThread) [yalexs_ble.push] Garage back (B0:44:9C:05:05:2A): Disconnect timer reset due to operation lock
2025-11-24 23:18:04.320 DEBUG (MainThread) [yalexs_ble.push] Garage back (B0:44:9C:05:05:2A): Resetting disconnect timer to 5.1 seconds
2025-11-24 23:18:04.615 DEBUG (MainThread) [yalexs_ble.push] Garage back (B0:44:9C:05:05:2A): Disconnected due to , cleaning up
2025-11-24 23:18:04.615 DEBUG (MainThread) [yalexs_ble.push] Garage back (B0:44:9C:05:05:2A): Disconnecting
2025-11-24 23:18:04.845 DEBUG (MainThread) [yalexs_ble.push] Garage back (B0:44:9C:05:05:2A): Disconnected from lock callback
2025-11-24 23:18:04.894 DEBUG (MainThread) [yalexs_ble.push] Garage back (B0:44:9C:05:05:2A): Disconnect completed
2025-11-24 23:18:04.894 DEBUG (MainThread) [yalexs_ble.push] Garage back (B0:44:9C:05:05:2A): <class 'TimeoutError'> error calling <function PushLock._update at 0x7f2bcff77100>, retrying  (2/3)...
2025-11-24 23:18:04.899 DEBUG (MainThread) [yalexs_ble.push] Garage back (B0:44:9C:05:05:2A): Starting update (has_lock_info: True)
2025-11-24 23:18:18.379 DEBUG (MainThread) [yalexs_ble.push] Garage back (B0:44:9C:05:05:2A): Resetting disconnect timer to 5.1 seconds
2025-11-24 23:18:18.379 DEBUG (MainThread) [yalexs_ble.push] Needs battery workaround model MD-04I: False
2025-11-24 23:18:23.481 DEBUG (MainThread) [yalexs_ble.push] Garage back (B0:44:9C:05:05:2A): Disconnect timer reset due to operation lock
2025-11-24 23:18:23.481 DEBUG (MainThread) [yalexs_ble.push] Garage back (B0:44:9C:05:05:2A): Resetting disconnect timer to 5.1 seconds
2025-11-24 23:18:28.381 DEBUG (MainThread) [yalexs_ble.push] Garage back (B0:44:9C:05:05:2A): Disconnected due to , cleaning up
2025-11-24 23:18:28.382 DEBUG (MainThread) [yalexs_ble.push] Garage back (B0:44:9C:05:05:2A): Disconnecting
2025-11-24 23:18:28.526 DEBUG (MainThread) [yalexs_ble.push] Garage back (B0:44:9C:05:05:2A): Disconnected from lock callback
2025-11-24 23:18:28.531 DEBUG (MainThread) [yalexs_ble.push] Garage back (B0:44:9C:05:05:2A): Disconnect completed
2025-11-24 23:18:28.532 DEBUG (MainThread) [yalexs_ble.push] Garage back (B0:44:9C:05:05:2A): <class 'TimeoutError'> error calling <function PushLock._update at 0x7f2bcff77100>, reach max attempts (3/3)
2025-11-24 23:18:28.536 ERROR (MainThread) [yalexs_ble.push] Garage back (B0:44:9C:05:05:2A): Timed out updating
2025-11-24 23:18:28.541 DEBUG (MainThread) [yalexs_ble.push] Garage back (B0:44:9C:05:05:2A): Executing forced disconnect: stopping
2025-11-24 23:18:28.541 DEBUG (MainThread) [yalexs_ble.push] Waiting for advertisement callbacks for Garage back (B0:44:9C:05:05:2A)
2025-11-24 23:18:28.541 DEBUG (MainThread) [yalexs_ble.push] Garage back (B0:44:9C:05:05:2A): Scheduling update to happen in 0.01 seconds
2025-11-24 23:18:28.554 DEBUG (MainThread) [yalexs_ble.push] Garage back (B0:44:9C:05:05:2A): Deferred update starting
2025-11-24 23:18:28.554 DEBUG (MainThread) [yalexs_ble.push] Garage back (B0:44:9C:05:05:2A): Starting deferred update
2025-11-24 23:18:28.554 DEBUG (MainThread) [yalexs_ble.push] Garage back (B0:44:9C:05:05:2A): Acquiring lock
2025-11-24 23:18:28.554 DEBUG (MainThread) [yalexs_ble.push] Garage back (B0:44:9C:05:05:2A): Starting retry loop
2025-11-24 23:18:28.554 DEBUG (MainThread) [yalexs_ble.push] Garage back (B0:44:9C:05:05:2A): Starting update (has_lock_info: False)
2025-11-24 23:18:37.329 DEBUG (MainThread) [yalexs_ble.push] Garage back (B0:44:9C:05:05:2A): Resetting disconnect timer to 5.1 seconds
2025-11-24 23:18:38.231 DEBUG (MainThread) [yalexs_ble.push] Obtained lock info: LockInfo(manufacturer='yale', model='MD-04I', serial='LQHEW0007T', firmware='1.8.0')
2025-11-24 23:18:38.231 DEBUG (MainThread) [yalexs_ble.push] Needs battery workaround model MD-04I: False
2025-11-24 23:18:42.430 DEBUG (MainThread) [yalexs_ble.push] Garage back (B0:44:9C:05:05:2A): Disconnect timer reset due to operation lock
2025-11-24 23:18:42.430 DEBUG (MainThread) [yalexs_ble.push] Garage back (B0:44:9C:05:05:2A): Resetting disconnect timer to 5.1 seconds
2025-11-24 23:18:47.532 DEBUG (MainThread) [yalexs_ble.push] Garage back (B0:44:9C:05:05:2A): Disconnect timer reset due to operation lock
2025-11-24 23:18:47.532 DEBUG (MainThread) [yalexs_ble.push] Garage back (B0:44:9C:05:05:2A): Resetting disconnect timer to 5.1 seconds
2025-11-24 23:18:48.233 DEBUG (MainThread) [yalexs_ble.push] Garage back (B0:44:9C:05:05:2A): Disconnected due to , cleaning up
2025-11-24 23:18:48.233 DEBUG (MainThread) [yalexs_ble.push] Garage back (B0:44:9C:05:05:2A): Disconnecting
2025-11-24 23:18:48.402 DEBUG (MainThread) [yalexs_ble.push] Garage back (B0:44:9C:05:05:2A): Disconnected from lock callback
2025-11-24 23:18:48.410 DEBUG (MainThread) [yalexs_ble.push] Garage back (B0:44:9C:05:05:2A): Disconnect completed
2025-11-24 23:18:48.410 DEBUG (MainThread) [yalexs_ble.push] Garage back (B0:44:9C:05:05:2A): <class 'TimeoutError'> error calling <function PushLock._update at 0x7f2bcff77100>, retrying  (0/3)...
2025-11-24 23:18:48.415 DEBUG (MainThread) [yalexs_ble.push] Garage back (B0:44:9C:05:05:2A): Starting update (has_lock_info: True)
2025-11-24 23:18:48.416 DEBUG (MainThread) [yalexs_ble.push] Garage back (B0:44:9C:05:05:2A): Failed to connect due to Garage back (B0:44:9C:05:05:2A) - B0:44:9C:05:05:2A: Failed to connect after 1 attempt(s): Disconnected, forcing disconnect
2025-11-24 23:18:48.416 DEBUG (MainThread) [yalexs_ble.push] Garage back (B0:44:9C:05:05:2A): Disconnected due to Garage back (B0:44:9C:05:05:2A) - B0:44:9C:05:05:2A: Failed to connect after 1 attempt(s): Disconnected, cleaning up
2025-11-24 23:18:48.416 DEBUG (MainThread) [yalexs_ble.push] Garage back (B0:44:9C:05:05:2A): Disconnecting
2025-11-24 23:18:48.416 DEBUG (MainThread) [yalexs_ble.push] Garage back (B0:44:9C:05:05:2A): Disconnect completed
2025-11-24 23:18:48.416 DEBUG (MainThread) [yalexs_ble.push] Garage back (B0:44:9C:05:05:2A): <class 'bleak_retry_connector.BleakConnectionError'> error calling <function PushLock._update at 0x7f2bcff77100>, retrying  (1/3)...
2025-11-24 23:18:48.421 DEBUG (MainThread) [yalexs_ble.push] Garage back (B0:44:9C:05:05:2A): Starting update (has_lock_info: True)
2025-11-24 23:19:01.081 DEBUG (MainThread) [yalexs_ble.push] Garage back (B0:44:9C:05:05:2A): Resetting disconnect timer to 5.1 seconds
2025-11-24 23:19:01.081 DEBUG (MainThread) [yalexs_ble.push] Needs battery workaround model MD-04I: False
2025-11-24 23:19:06.182 DEBUG (MainThread) [yalexs_ble.push] Garage back (B0:44:9C:05:05:2A): Disconnect timer reset due to operation lock
2025-11-24 23:19:06.182 DEBUG (MainThread) [yalexs_ble.push] Garage back (B0:44:9C:05:05:2A): Resetting disconnect timer to 5.1 seconds
2025-11-24 23:19:11.083 DEBUG (MainThread) [yalexs_ble.push] Garage back (B0:44:9C:05:05:2A): Disconnected due to , cleaning up
2025-11-24 23:19:11.083 DEBUG (MainThread) [yalexs_ble.push] Garage back (B0:44:9C:05:05:2A): Disconnecting
2025-11-24 23:19:11.453 DEBUG (MainThread) [yalexs_ble.push] Garage back (B0:44:9C:05:05:2A): Disconnected from lock callback
2025-11-24 23:19:11.453 DEBUG (MainThread) [yalexs_ble.push] Garage back (B0:44:9C:05:05:2A): Disconnected from lock callback
2025-11-24 23:19:11.456 DEBUG (MainThread) [yalexs_ble.push] Garage back (B0:44:9C:05:05:2A): Disconnect completed
2025-11-24 23:19:11.456 DEBUG (MainThread) [yalexs_ble.push] Garage back (B0:44:9C:05:05:2A): <class 'TimeoutError'> error calling <function PushLock._update at 0x7f2bcff77100>, retrying  (2/3)...
2025-11-24 23:19:11.458 DEBUG (MainThread) [yalexs_ble.push] Garage back (B0:44:9C:05:05:2A): Starting update (has_lock_info: True)
2025-11-24 23:19:11.524 DEBUG (MainThread) [yalexs_ble.push] Garage back (B0:44:9C:05:05:2A): Failed to connect due to Garage back (B0:44:9C:05:05:2A) - B0:44:9C:05:05:2A: Failed to connect after 1 attempt(s): Disconnected, forcing disconnect
2025-11-24 23:19:11.524 DEBUG (MainThread) [yalexs_ble.push] Garage back (B0:44:9C:05:05:2A): Disconnected due to Garage back (B0:44:9C:05:05:2A) - B0:44:9C:05:05:2A: Failed to connect after 1 attempt(s): Disconnected, cleaning up
2025-11-24 23:19:11.524 DEBUG (MainThread) [yalexs_ble.push] Garage back (B0:44:9C:05:05:2A): Disconnecting
2025-11-24 23:19:11.524 DEBUG (MainThread) [yalexs_ble.push] Garage back (B0:44:9C:05:05:2A): Disconnect completed
2025-11-24 23:19:11.525 DEBUG (MainThread) [yalexs_ble.push] Garage back (B0:44:9C:05:05:2A): <class 'bleak_retry_connector.BleakConnectionError'> error calling <function PushLock._update at 0x7f2bcff77100>, reach max attempts (3/3)
2025-11-24 23:19:11.531 ERROR (MainThread) [yalexs_ble.push] Garage back (B0:44:9C:05:05:2A): Bluetooth error updating
2025-11-24 23:19:11.536 DEBUG (MainThread) [yalexs_ble.push] Garage back (B0:44:9C:05:05:2A): Executing forced disconnect: stopping

Key points:

  • Model: MD-04I
  • Firmware: 1.8.0
  • Serial: LQHEW0007T
  • Lock is a Yale Durus (EU, Yale Home ecosystem).
  • Cloud control via Yale integration works as expected.
  • BLE fails only at the update/push stage, not at initial info retrieval.

I’m happy to provide:

  • Full debug logs
  • Home Assistant diagnostics
  • BLE traces (btmon/hcidump)
  • And to test any experimental branch or wheel that adds/adjusts support for MD-04I.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions