Yale iM1 lock unreliable

I have a Yale Assure SL lock with iM1 module connected to HA with the HomeKit Controller integration. Sometimes it works fine, sometimes it’s very slow to respond (over 1 minute), and sometimes it doesn’t respond at all. Today I noticed this error in the log while it’s not responding to lock/unlock commands.

Before moving to HA, I had this lock paired to HomeKit with Apple TV and it worked perfectly there. I’m guessing maybe this is a Bluetooth (BLE) signal strength issue, but I’m not sure how to improve it. I can’t easily move the Raspberry Pi closer to the door. Is there some way to pair it with Apple TV and then “share” that to HA?

2022-12-09 23:35:07.708 ERROR (MainThread) [homeassistant.core] Error executing service: <ServiceCall lock.lock (c:01GKXFAB2G9PXH0VJDMBFXC32F): entity_id=['lock.yale_lock']>
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/core.py", line 1763, in catch_exceptions
    await coro_or_task
  File "/usr/src/homeassistant/homeassistant/core.py", line 1782, in _execute_service
    await cast(Callable[[ServiceCall], Awaitable[None]], handler.job.target)(
  File "/usr/src/homeassistant/homeassistant/helpers/entity_component.py", line 213, in handle_service
    await service.entity_service_call(
  File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 678, in entity_service_call
    future.result()  # pop exception if have
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 943, in async_request_call
    await coro
  File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 715, in _handle_entity_call
    await result
  File "/usr/src/homeassistant/homeassistant/components/homekit_controller/lock.py", line 116, in async_lock
    await self._set_lock_state(STATE_LOCKED)
  File "/usr/src/homeassistant/homeassistant/components/homekit_controller/lock.py", line 124, in _set_lock_state
    await self.async_put_characteristics(
  File "/usr/src/homeassistant/homeassistant/components/homekit_controller/entity.py", line 90, in async_put_characteristics
    return await self._accessory.put_characteristics(payload)
  File "/usr/src/homeassistant/homeassistant/components/homekit_controller/connection.py", line 732, in put_characteristics
    await self.pairing.put_characteristics(characteristics)
  File "/usr/local/lib/python3.10/site-packages/aiohomekit/controller/ble/pairing.py", line 188, in _async_operation_lock_wrap
    return await func(self, *args, **kwargs)
  File "/usr/local/lib/python3.10/site-packages/bleak_retry_connector/__init__.py", line 723, in _async_wrap_bluetooth_connection_error_retry
    return await func(*args, **kwargs)
  File "/usr/local/lib/python3.10/site-packages/aiohomekit/controller/ble/pairing.py", line 204, in _async_disconnect_on_missing_services_wrap
    return await func(self, *args, **kwargs)
  File "/usr/local/lib/python3.10/site-packages/aiohomekit/controller/ble/pairing.py", line 228, in _async_restore_and_resume
    await self._populate_accessories_and_characteristics()
  File "/usr/local/lib/python3.10/site-packages/aiohomekit/controller/ble/pairing.py", line 1132, in _populate_accessories_and_characteristics
    await self._async_pair_verify()
  File "/usr/local/lib/python3.10/site-packages/aiohomekit/controller/ble/pairing.py", line 572, in _async_pair_verify
    session_id, derive = await drive_pairing_state_machine(
  File "/usr/local/lib/python3.10/site-packages/aiohomekit/controller/ble/client.py", line 232, in drive_pairing_state_machine
    decoded = await _pairing_char_write(client, char, iid, request)
  File "/usr/local/lib/python3.10/site-packages/aiohomekit/controller/ble/client.py", line 186, in _pairing_char_write
    data = await char_write(client, None, None, handle, iid, next_write)
  File "/usr/local/lib/python3.10/site-packages/aiohomekit/controller/ble/client.py", line 169, in char_write
    pdu_status, data = await ble_request(
  File "/usr/local/lib/python3.10/site-packages/aiohomekit/controller/ble/client.py", line 72, in ble_request
    await _write_pdu(client, encryption_key, opcode, handle, iid, data, tid)
  File "/usr/local/lib/python3.10/site-packages/aiohomekit/controller/ble/client.py", line 99, in _write_pdu
    await client.write_gatt_char(
  File "/usr/local/lib/python3.10/site-packages/bleak/__init__.py", line 593, in write_gatt_char
    await self._backend.write_gatt_char(char_specifier, data, response)
  File "/usr/local/lib/python3.10/site-packages/bleak/backends/bluezdbus/client.py", line 801, in write_gatt_char
    assert_reply(reply)
  File "/usr/local/lib/python3.10/site-packages/bleak/backends/bluezdbus/utils.py", line 20, in assert_reply
    raise BleakDBusError(reply.error_name, reply.body)
bleak.exc.BleakDBusError: [org.bluez.Error.Failed] Operation failed with ATT error: 0x0e (Unlikely Error)

I cross-posted this in a very similar issue on Github but I’ll also share my workaround here in case it helps anyone.

I have found that restarting the HomeKit integration fixes this issue, so I don’t believe it’s caused by weak signal strength. It sounds like some underlying bug in the bleak code. For now, my workaround is an automation that reloads HomeKit every time this error is logged. So when I try to lock the door, it fails, sends me a notification, and then I lock again and it works. I’m still testing but so far this hack is working reliably every time.

- alias: Reload HomeKit after Yale error
  trigger:
  - platform: event
    event_type: system_log_event
    event_data:
      level: ERROR
  condition:
  - condition: template
    value_template: '{{ "yale_lock" in trigger.event.data.message[0] }}'
  action:
  - service: notify.notify
    data:
      message: Restarting HomeKit because Yale Lock logged an error
  - service: homekit.reload
  mode: single

For this to work, you have to enable system_log events in configuration.yaml:

system_log:
  max_entries: 50
  fire_event: true
1 Like