Giter Site home page Giter Site logo

aiohomekit's People

Contributors

adrum avatar agoode avatar balloob avatar bdraco avatar beele avatar cdce8p avatar dcmeglio avatar dependabot[bot] avatar ecoen66 avatar ekos2001 avatar fabaff avatar jaredhobbs avatar jc2k avatar liebehentze avatar ntninja avatar roysjosh avatar vfreex avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

aiohomekit's Issues

Use extras to allow use of some backends and not others?

The original plan was to put something like this in pyproject.toml:

[tool.poetry.dependencies]
python = "^3.9"
cryptography = ">=2.9.2"
commentjson = "^0.9.0"
zeroconf = { version=">=0.32.0", optional=True }
aiocoap = { version=">=0.4.1", optional=True }
bleak = { version=">=0.4.1", optional=True }

[tool.poetry.extras]
ble = ["bleak"]
coap = ["aiocoap", "zeroconf"]
ip = ["zeroconf]

Then refer to aiohomekit as aiohomekit[ble,coap,ip] in HA manifests.

The SUPPORTS_ const are a bit pointless without this.

If poetry can be configured to pull in all 3 into dev env by default i'd still want to do this I think.

RuntimeError: Set changed size during iteration

2022-05-09 19:41:59 ERROR (MainThread) [aiohomekit.controller.ip.connection] Unexpected error whilst trying to connect to accessory. Will retry.
Traceback (most recent call last):
  File "/usr/local/lib/python3.9/site-packages/aiohomekit/controller/ip/connection.py", line 540, in _reconnect
    return await self._connect_once()
  File "/usr/local/lib/python3.9/site-packages/aiohomekit/controller/ip/connection.py", line 648, in _connect_once
    await self.owner.connection_made(True)
  File "/usr/local/lib/python3.9/site-packages/aiohomekit/controller/ip/pairing.py", line 103, in connection_made
    await self.subscribe(self.subscriptions)
  File "/usr/local/lib/python3.9/site-packages/aiohomekit/controller/ip/pairing.py", line 299, in subscribe
    return await self._update_subscriptions(characteristics, True)
  File "/usr/local/lib/python3.9/site-packages/aiohomekit/controller/ip/pairing.py", line 330, in _update_subscriptions
    "characteristics": [
  File "/usr/local/lib/python3.9/site-packages/aiohomekit/controller/ip/pairing.py", line 330, in <listcomp>
    "characteristics": [
RuntimeError: Set changed size during iteration

This happened while testing something else. Documenting it now so I don't forget

Simplify TLV parsing

The TLV parsing we have adopted from upstream returns a list of tuples. This means you can't do:

result[TLV.kTLVType_State]

You have to instead order the results and do:

if result[0] == TLV.kTLVType_State and....

This is working, so I have been reluctant to change it. But it has hard for new users (and me) to follow.

Upstream has now factored TLV handling out into a seperate library here. However it did introduce a few regressions. It is an improvement because you can declare the types and structure of the expected data a bit better, but the result returned is still not very ergonomic.

Ultimately i'd like to parse a TLV into a structure that can be checked with a linter, rather that returning a list or a dict.

When attempting to close a garage door with an obstruction status code 70408 is thrown

I think this is a bug in the myq homekit bridge as I believe these are supposed to be negative.

2020-10-22 22:22:21 ERROR (MainThread) [homeassistant.core] Error executing service: <ServiceCall cover.close_cover (c:da4a8e04b5257836ff910b3f366b1beb): entity_id=['cover.large_garage_door_local']>
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/core.py", line 1465, in catch_exceptions
    await coro_or_task
  File "/usr/src/homeassistant/homeassistant/core.py", line 1484, in _execute_service
    await handler.job.target(service_call)
  File "/usr/src/homeassistant/homeassistant/helpers/entity_component.py", line 204, in handle_service
    await self.hass.helpers.service.entity_service_call(
  File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 482, in entity_service_call
    future.result()  # pop exception if have
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 664, in async_request_call
    await coro
  File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 519, in _handle_entity_call
    await result
  File "/usr/src/homeassistant/homeassistant/components/homekit_controller/cover.py", line 105, in async_close_cover
    await self.set_door_state(STATE_CLOSED)
  File "/usr/src/homeassistant/homeassistant/components/homekit_controller/cover.py", line 109, in set_door_state
    await self.async_put_characteristics(
  File "/usr/src/homeassistant/homeassistant/components/homekit_controller/__init__.py", line 94, in async_put_characteristics
    return await self._accessory.put_characteristics(payload)
  File "/usr/src/homeassistant/homeassistant/components/homekit_controller/connection.py", line 403, in put_characteristics
    results = await self.pairing.put_characteristics(characteristics)
  File "/usr/local/lib/python3.8/site-packages/aiohomekit/controller/ip/pairing.py", line 265, in put_characteristics
    data = {
  File "/usr/local/lib/python3.8/site-packages/aiohomekit/controller/ip/pairing.py", line 268, in <dictcomp>
    "description": HapStatusCodes[d["status"]],
  File "/usr/local/lib/python3.8/site-packages/aiohomekit/protocol/statuscodes.py", line 58, in __getitem__
    raise KeyError(f"Item {item} not found")
KeyError: 'Item 70408 not found'

Unknown parser state with homebridge as accessory

I just upgraded to hass 0.107.5, and during startup I get the following traceback:


Traceback (most recent call last):
  File "/usr/local/lib/python3.7/asyncio/selector_events.py", line 826, in _read_ready__data_received
    self._protocol.data_received(data)
  File "/usr/local/lib/python3.7/site-packages/aiohomekit/controller/ip/connection.py", line 185, in data_received
    super().data_received(decrypted)
  File "/usr/local/lib/python3.7/site-packages/aiohomekit/controller/ip/connection.py", line 84, in data_received
    data = self.current_response.parse(data)
  File "/usr/local/lib/python3.7/site-packages/aiohomekit/http/response.py", line 95, in parse
    raise HttpException("Unknown parser state")
aiohomekit.exceptions.HttpException: Unknown parser state

I took a look at the parser and it seems like the only way this can happen is if more data arrives after STATE_DONE is set.

The only accessory I'm using is actually homebridge, to use another layer of translation that hass can't do natively yet. It's definitely possible that homebridge does something strange compared to a real accessory. I attempted re-pairing just to verify that homebridge is the culprit, and indeed the traceback appeared immediately.

Let me know what info I can provide to help debug this!

Pairing with new Belkin Wemo WDS070 Smart Dimmer fails

I bought this dimmer which touts itself as a HomeKit only Thread dimmer with Bluetooth. I picked it up just to see how Home Assistant would handle it. I hoped at least it might connect via Bluetooth. Sadly it looks like I'm getting pairing error...

Pairing attempt failed with an unhandled exception
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/components/homekit_controller/config_flow.py", line 465, in async_step_pair
    return await self._entry_from_accessory(pairing)
  File "/usr/src/homeassistant/homeassistant/components/homekit_controller/config_flow.py", line 589, in _entry_from_accessory
    name = await pairing.get_primary_name()
  File "/usr/local/lib/python3.10/site-packages/aiohomekit/controller/abstract.py", line 143, in get_primary_name
    accessories = await self.list_accessories_and_characteristics()
  File "/usr/local/lib/python3.10/site-packages/aiohomekit/controller/ble/pairing.py", line 103, in _async_wrap
    return await func(self, *args, **kwargs)
  File "/usr/local/lib/python3.10/site-packages/aiohomekit/controller/ble/client.py", line 65, in _async_wrap
    return await func(*args, **kwargs)
  File "/usr/local/lib/python3.10/site-packages/aiohomekit/controller/ble/pairing.py", line 529, in list_accessories_and_characteristics
    await self._populate_accessories_and_characteristics()
  File "/usr/local/lib/python3.10/site-packages/aiohomekit/controller/ble/pairing.py", line 621, in _populate_accessories_and_characteristics
    await self._populate_char_values(config_changed)
  File "/usr/local/lib/python3.10/site-packages/aiohomekit/controller/ble/pairing.py", line 551, in _populate_char_values
    results = await self._get_characteristics_while_connected(chars)
  File "/usr/local/lib/python3.10/site-packages/aiohomekit/controller/ble/pairing.py", line 747, in _get_characteristics_while_connected
    data = await self._async_request_under_lock(OpCode.CHAR_READ, char)
  File "/usr/local/lib/python3.10/site-packages/aiohomekit/controller/ble/pairing.py", line 295, in _async_request_under_lock
    raise_for_pdu_status(self.client, pdu_status)
  File "/usr/local/lib/python3.10/site-packages/aiohomekit/controller/ble/client.py", line 206, in raise_for_pdu_status
    raise ValueError(
ValueError: C3:28:A0:79:0E:7D: PDU status was not success: Invalid request (6)

Also apologies if I'm raising this issue in the wrong place 🙏 I'm happy to take it somewhere else and/or try to provide any more detailed logs if I can.

Hard to understand crashes if target devices sends empty/incomplete data

I just thought I'd document this: When the target device sends a supposedly incomplete or empty response (as in the first patch of #9 in my case), aiohomekit will crash with an assertion error. There are two problems with this:

  • Assertions are debug-only: When running Python in optimized mode (python -O …), the assertions will disappear and aiohomekit will happily continue operations with invalid data.
  • The statemachines in aiohomekit/protocol/__init__.py each return a list of “expected” OP codes that does NOT do what I, at least, expected: When reading this code, I assumed this would cause the caller to ensure that the provided TLV values contain any of the expected items in the order given in that list – the reality is a bit different and I'd be very interested in any explanation as to what the actual code is supposed to achieve. 🙂

Sometimes service resolution fails on the edge of bluetooth range

We need to disconnect and reconnect in this case

Logger: homeassistant.config_entries
Source: components/homekit_controller/connection.py:204
First occurred: 2:11:29 PM (1 occurrences)
Last logged: 2:11:29 PM

Error setting up entry VOCOlinc-VS1-1857C6 for homekit_controller
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/config_entries.py", line 357, in async_setup
    result = await component.async_setup_entry(hass, self)
  File "/usr/src/homeassistant/homeassistant/components/homekit_controller/__init__.py", line 42, in async_setup_entry
    await conn.async_setup()
  File "/usr/src/homeassistant/homeassistant/components/homekit_controller/connection.py", line 204, in async_setup
    await self.pairing.async_populate_accessories_state(force_update=True)
  File "/usr/local/lib/python3.10/site-packages/aiohomekit/controller/ble/pairing.py", line 596, in async_populate_accessories_state
    await self._async_populate_accessories_state(force_update)
  File "/usr/local/lib/python3.10/site-packages/aiohomekit/controller/ble/pairing.py", line 103, in _async_wrap
    return await func(self, *args, **kwargs)
  File "/usr/local/lib/python3.10/site-packages/aiohomekit/controller/ble/client.py", line 66, in _async_wrap
    return await func(*args, **kwargs)
  File "/usr/local/lib/python3.10/site-packages/aiohomekit/controller/ble/pairing.py", line 608, in _async_populate_accessories_state
    await self._populate_accessories_and_characteristics(force_update)
  File "/usr/local/lib/python3.10/site-packages/aiohomekit/controller/ble/pairing.py", line 642, in _populate_accessories_and_characteristics
    await self._async_pair_verify()
  File "/usr/local/lib/python3.10/site-packages/aiohomekit/controller/ble/pairing.py", line 410, 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 288, in drive_pairing_state_machine
    char = client.get_characteristic(ServicesTypes.PAIRING, characteristic)
  File "/usr/local/lib/python3.10/site-packages/aiohomekit/controller/ble/bleak.py", line 37, in get_characteristic
    raise ValueError(
ValueError: Service 00000055-0000-1000-8000-0026BB765291 not found, available services: []

Add more checking of result from device

The HAP client should raise if the status code is outside the 200 range. It should preserve the body in the exception - for example a 400 maybe accompanied by JSON with a status code, or a TLV with an error code. The higher level abstraction might still want to parse this and surface it to the user via a higher level error.

The secure session and pairing code in particular should not tolerate empty payloads.

Feature Request: Report light levels are integer values.

I hope I'm posting this in the correct repo. Please let me know if I should post this elsewhere.

I'm using Home Assistant's homekit_controller integration that relies on aiohomekit. For light sensors it reports float values in lux. The fractional portion is not particularly significant for illuminance and I was wondering if you would consider rounding it to the nearest whole integer value.

Alternately, perhaps this can be addressed in the homekit_controller integration?

Pairing fails with BLE device Feit LED bulb

https://www.amazon.com/dp/B07J2FP389?psc=1&ref=ppx_yo2ov_dt_b_product_details

Feit Electric OM60/SW/HK 60W Equivalent A19 Smart, Works with Apple HomeKit and Siri Voice Control, No Hub Required LED Light Bulb, 4.4" H x 2.4" D, 2700K Soft White

‎OM60/SW/HK


2022-08-07 12:23:04.157 DEBUG (MainThread) [homeassistant.components.homekit_controller.config_flow] Pairing authentication failed
Traceback (most recent call last):
  File "/Users/bdraco/home-assistant/homeassistant/components/homekit_controller/config_flow.py", line 464, in async_step_pair
    pairing = await self.finish_pairing(code)
  File "/Users/bdraco/home-assistant/venv/lib/python3.10/site-packages/aiohomekit/controller/ble/client.py", line 61, in _async_wrap
    return await func(*args, **kwargs)
  File "/Users/bdraco/home-assistant/venv/lib/python3.10/site-packages/aiohomekit/controller/ble/discovery.py", line 147, in finish_pairing
    pairing = await drive_pairing_state_machine(
  File "/Users/bdraco/home-assistant/venv/lib/python3.10/site-packages/aiohomekit/controller/ble/client.py", line 195, in drive_pairing_state_machine
    request, expected = state_machine.send(TLV.decode_bytes(response))
  File "/Users/bdraco/home-assistant/venv/lib/python3.10/site-packages/aiohomekit/protocol/__init__.py", line 222, in perform_pair_setup_part2
    handle_state_step(response_tlv, TLV.M4)
  File "/Users/bdraco/home-assistant/venv/lib/python3.10/site-packages/aiohomekit/protocol/__init__.py", line 87, in handle_state_step
    error_handler(tlv_dict[TLV.kTLVType_Error], f"step {expected_state}")
  File "/Users/bdraco/home-assistant/venv/lib/python3.10/site-packages/aiohomekit/protocol/__init__.py", line 61, in error_handler
    raise AuthenticationError(stage)
aiohomekit.exceptions.AuthenticationError: step bytearray(b'\x04')

There is a race in reconnecting when the c# changes which results in random failures

2022-07-05 09:36:35 DEBUG (MainThread) [aiohomekit.controller.ip.connection] 192.168.213.219: raw response: bytearray(b'\x06\x01\x06\x05\x87\xe5\x04\xda\x85i\xf5F>\xbc2P\x9eR\xc7\xad\xff\xad\xb0:4\x86=x\x02\x8f\xd57\xd4%d\xf4\xcf\x16c\x13\xbcRR=\xd9\xea\xf8\xb1V\xe2+\xa1\xba\x9bHIV\xebM\xe1\xce\xaa\xb2\xcb,\xa0\x02B\xcc\xbaS\xf51P\xceT\\\x8b\xd8\xf0\x96|\xb5\xed\x8b \xad\x91\xb2\x04\xf2\xaeq\x89\\G\xf6\xce\xce\x97\x10\xdd\xe0\x0f\xd7\x1c\x02\x0bBJ\xc4\xbc\x8b\x98K\x0b\xc6\x07\xab\x9f\xb28\xed\xc0h\x0c\xcc\xdf\x8f\xb0\xf5\x18k\x7f\x90\x93\\\xe3>\x90')
2022-07-05 09:36:35 DEBUG (MainThread) [aiohomekit.protocol.tlv] receiving [
  6: (1 bytes/<class 'bytearray'>) 0x06
  5: (135 bytes/<class 'bytearray'>) 0xe504da8569f5463ebc32509e52c7adffadb03a34863d78028fd537d42564f4cf166313bc52523dd9eaf8b156e22ba1ba9b484956eb4de1ceaab2cb2ca00242ccba53f53150ce545c8bd8f0967cb5ed8b20ad91b204f2ae71895c47f6cece9710dde00fd71c020b424ac4bc8b984b0bc607ab9fb238edc0680cccdf8fb0f5186b7f90935ce33e90
]

2022-07-05 09:36:35 DEBUG (MainThread) [aiohomekit.protocol.tlv] receiving [
  1: (17 bytes/<class 'bytearray'>) 0x31393a39333a32383a33383a42443a3445
  3: (32 bytes/<class 'bytearray'>) 0x6bd2cb9912a3f3a1cec94196d0c77f93b68d4145cd2c7fdd76fe8d05dcddda3a
  10: (64 bytes/<class 'bytearray'>) 0x8a2f4d354b3762dee61e477659163ce35574b8b6858bef48112a9ceebb7f4b1cd5daf0ff8ca4f6b6660eb7520f445c1f58562d818f617a8a45c79890949bf40c
]

2022-07-05 09:36:35 DEBUG (MainThread) [aiohomekit.controller.ip.connection] Connection HomeKitConnection(host='192.168.213.219', port=63928) lost.
2022-07-05 09:36:35 DEBUG (MainThread) [aiohomekit.controller.ip.connection] Starting reconnect loop to 192.168.213.219:63928
2022-07-05 09:36:35 DEBUG (MainThread) [aiohomekit.controller.ip.connection] Attempting connection to 192.168.213.219:63928
2022-07-05 09:36:35 DEBUG (MainThread) [aiohomekit.protocol.tlv] sending [
  6: (1 bytes/<class 'bytearray'>) 0x01
  3: (32 bytes/<class 'bytes'>) b'\xa1\x02\x04\x86CK\x0cyr\n@7\xe5\xcc\x95\x814\x91.\xb7\xc8"\xb4B+w\xf2\x04\x15\x93\xc9q'
]

2022-07-05 09:36:35 DEBUG (MainThread) [aiohomekit.controller.ip.connection] 192.168.213.219: raw request: b'POST /pair-verify HTTP/1.1\r\nHost: 192.168.213.219\r\nContent-Length: 37\r\nContent-Type: application/pairing+tlv8\r\n\r\n\x06\x01\x01\x03 \xa1\x02\x04\x86CK\x0cyr\n@7\xe5\xcc\x95\x814\x91.\xb7\xc8"\xb4B+w\xf2\x04\x15\x93\xc9q'
2022-07-05 09:36:35 DEBUG (MainThread) [homeassistant.components.homekit_controller.config_flow] HomeKit info 19:93:28:38:BD:4E: c# incremented, refreshing entities
2022-07-05 09:36:35 DEBUG (MainThread) [aiohomekit.controller.ip.connection] Starting reconnect loop to 192.168.213.219:63928
2022-07-05 09:36:35 DEBUG (MainThread) [aiohomekit.controller.ip.connection] Attempting connection to 192.168.213.219:63928
2022-07-05 09:36:35 DEBUG (MainThread) [aiohomekit.controller.ip.connection] 192.168.213.219: raw response: bytearray(b"\x06\x01\x02\x03 \xa3f\xf9\x1aZ\xf3\xf2\x879:\xfa\xd1A%\xa1\xed\x85\x91\x8c#\\[\x9aj\x14|\xde\xec\tbVq\x05e)\x80\x011\xb7\xa6\x8a\xef\xa6\xf8}\x9e\xe9\x14\x8d\xe6d!e\xde\x97\x00T\xea\x96\xc1+\xd8\xa2_\xf1<q\xe1&\xdc\xc2\xb7\'L\x90\xf9/\x032\x1c\xccb;\x84\xc4\x8c\x1e\xff\x97\x04C@^\x82f\xc6\xdc\x18\xd6\xc4V\xdf\x8e0\xc2\xe8\x06}a\xce\xb9\xd6mG\x91\x1da\xdd^Y>\xdc:\xde\xaf\xac\xa5&v>\x91\x12\x98\x1f\\")
2022-07-05 09:36:35 DEBUG (MainThread) [aiohomekit.protocol.tlv] receiving [
  6: (1 bytes/<class 'bytearray'>) 0x02
  3: (32 bytes/<class 'bytearray'>) 0xa366f91a5af3f287393afad14125a1ed85918c235c5b9a6a147cdeec09625671
  5: (101 bytes/<class 'bytearray'>) 0x29800131b7a68aefa6f87d9ee9148de6642165de970054ea96c12bd8a25ff13c71e126dcc2b7274c90f92f03321ccc623b84c48c1eff970443405e8266c6dc18d6c456df8e30c2e8067d61ceb9d66d47911d61dd5e593edc3adeafaca526763e9112981f5c
]

2022-07-05 09:36:35 DEBUG (MainThread) [aiohomekit.protocol.tlv] receiving [
  1: (17 bytes/<class 'bytearray'>) 0x31393a39333a32383a33383a42443a3445
  10: (64 bytes/<class 'bytearray'>) 0xd167a6864566f7e8a6a6b195e003641a5d1aecad9e5f68491a6d29eebcaff171c83f94480af5684595e1207f66c62b49f36087ff138c67aa055a436fa0b0ed0d
]

2022-07-05 09:36:35 DEBUG (MainThread) [aiohomekit.protocol.tlv] sending [
  1: (36 bytes/<class 'bytes'>) b'7eb78a6c-b75b-49fb-b6e9-e36d5865090e'
  10: (64 bytes/<class 'bytes'>) b"\xc8&\x82\x88\x1c\xdb\xcbL\xeb(\x0e\xb4\x95\x9c\xe6\xc2?\x12:\x88\x9d\x7f/\xff\x0et\x80\xcfN\xcde\xc9wU\x8d>\x85~+h\xb9\xc9K\x0e\x17\xd6\\;'\x18\x8d9\x88\xd3\xa8\xd9\xb5`\xe1\x15\x1bs\x14\x01"
]

2022-07-05 09:36:35 DEBUG (MainThread) [aiohomekit.protocol.tlv] sending [
  6: (1 bytes/<class 'bytearray'>) 0x03
  5: (120 bytes/<class 'bytes'>) b")r\xb8.\x98\xeb\xabr$\x86+\xa2+\xf6D+\x86\xebj\xf5\\\xda\x95\x8a\x7f2Sa\xda\x7f'\x18\x83)i\x91o\x0e\xec\x18\x000\x08\xf1\xfd\xf9\xee=\xe7\x0e\xb6\xb2\tZ\xa1\xb2|\x15X\xbf\xe5\xcb(\x9eNq\xfa\x06G\xa8\xcf\x12\xfc\xf0\x8f\xb6\xa8\xa5a\xfa\xe3\xf9\x12\xc7\xef\xeeq\xf9\tP[U\x98\xe2(\xec\xc7\x83\x04\x0c;o\x88\xb0\xb0C\xce\xd6\xccsv=n`@\xb6\xb0\x89*\xb8"
]

2022-07-05 09:36:35 DEBUG (MainThread) [aiohomekit.controller.ip.connection] 192.168.213.219: raw request: b"POST /pair-verify HTTP/1.1\r\nHost: 192.168.213.219\r\nContent-Length: 125\r\nContent-Type: application/pairing+tlv8\r\n\r\n\x06\x01\x03\x05x)r\xb8.\x98\xeb\xabr$\x86+\xa2+\xf6D+\x86\xebj\xf5\\\xda\x95\x8a\x7f2Sa\xda\x7f'\x18\x83)i\x91o\x0e\xec\x18\x000\x08\xf1\xfd\xf9\xee=\xe7\x0e\xb6\xb2\tZ\xa1\xb2|\x15X\xbf\xe5\xcb(\x9eNq\xfa\x06G\xa8\xcf\x12\xfc\xf0\x8f\xb6\xa8\xa5a\xfa\xe3\xf9\x12\xc7\xef\xeeq\xf9\tP[U\x98\xe2(\xec\xc7\x83\x04\x0c;o\x88\xb0\xb0C\xce\xd6\xccsv=n`@\xb6\xb0\x89*\xb8"
2022-07-05 09:36:35 DEBUG (MainThread) [aiohomekit.protocol.tlv] sending [
  6: (1 bytes/<class 'bytearray'>) 0x01
  3: (32 bytes/<class 'bytes'>) b'\xbc\x9b[V\x92\xc1\xfb\xb0\xb1av\xa8.)\xb6:-/\xb6\xb7\xa2\xb4\x97\xce\xdf\x03y\x91\x81<\x0b~'
]

2022-07-05 09:36:35 DEBUG (MainThread) [aiohomekit.controller.ip.connection] 192.168.213.219: raw request: b'POST /pair-verify HTTP/1.1\r\nHost: 192.168.213.219\r\nContent-Length: 37\r\nContent-Type: application/pairing+tlv8\r\n\r\n\x06\x01\x01\x03 \xbc\x9b[V\x92\xc1\xfb\xb0\xb1av\xa8.)\xb6:-/\xb6\xb7\xa2\xb4\x97\xce\xdf\x03y\x91\x81<\x0b~'
2022-07-05 09:36:36 DEBUG (MainThread) [aiohomekit.controller.ip.connection] 192.168.213.219: raw response: bytearray(b'\x06\x01\x04')
2022-07-05 09:36:36 DEBUG (MainThread) [aiohomekit.protocol.tlv] receiving [
  6: (1 bytes/<class 'bytearray'>) 0x04
]

2022-07-05 09:36:36 DEBUG (MainThread) [aiohomekit.controller.ip.connection] Secure connection to 192.168.213.219:63928 established
2022-07-05 09:36:36 DEBUG (MainThread) [aiohomekit.controller.ip.connection] 192.168.213.219: raw request: b'GET /accessories HTTP/1.1\r\nHost: 192.168.213.219\r\n\r\n'
2022-07-05 09:36:36 DEBUG (MainThread) [aiohomekit.controller.ip.connection] 192.168.213.219: raw response: bytearray(b"\x06\x01\x02\x03 \xe9\x9d)>\x07\x07m$B\xdc\xcc\x1d\xb3\x14D\x14!\x16#\xfc\x14\xc0\xf1\xb1\xd4\xba\xc5\xa6\xb8L\x8c\t\x05eG\xea\'\xf5\xd2G\xd2 \xc4\x19\xc21D\xdf\xf0\x0b4\x93\x9e\x15\'#\xe0\xbcN\xf0\x0e\xebf\xa54\xc5\xc3\x97\xba\x9c\xf8\xa4_\xb5\x19\xb07\xde\x06E\xfc\xf1\x0blf\xfb\xcf\x18\x84\xfb?\xf9\xa2\xc1\x94\xf92\xc8l\xe2\x16\xf2\x94\x94\xfcQ\x18k4\xb5\xec8\x8d\x06i\x1b\xe0\xbc\xa6d[*?\xc9MA\x90%\x89\xc1V\xff\x98\x1b\xc7")
2022-07-05 09:36:36 DEBUG (MainThread) [aiohomekit.protocol.tlv] receiving [
  6: (1 bytes/<class 'bytearray'>) 0x02
  3: (32 bytes/<class 'bytearray'>) 0xe99d293e07076d2442dccc1db3144414211623fc14c0f1b1d4bac5a6b84c8c09
  5: (101 bytes/<class 'bytearray'>) 0x47ea27f5d247d220c419c23144dff00b34939e152723e0bc4ef00eeb66a534c5c397ba9cf8a45fb519b037de0645fcf10b6c66fbcf1884fb3ff9a2c194f932c86ce216f29494fc51186b34b5ec388d06691be0bca6645b2a3fc94d41902589c156ff981bc7
]

2022-07-05 09:36:36 DEBUG (MainThread) [aiohomekit.protocol.tlv] receiving [
  1: (17 bytes/<class 'bytearray'>) 0x31393a39333a32383a33383a42443a3445
  10: (64 bytes/<class 'bytearray'>) 0xb88a13c72a53167cd0ac8974688fb2308edecdf6fde6bb4147cce91fd80d2d438c804152a497aa1fc6af3b98730a365cbf7f057061d5e7af05a0aac31ca65c07
]

2022-07-05 09:36:36 DEBUG (MainThread) [aiohomekit.protocol.tlv] sending [
  1: (36 bytes/<class 'bytes'>) b'a775a4f4-7538-4c43-8f95-20b257758a08'
  10: (64 bytes/<class 'bytes'>) b'\x86\xe7xz\x81\xe7\x08\xb3\r\xd1\x01\xd1\xbc\x8e*@\x14B\x92\x04\xfd\xe99\xed\xe5"M*\'\xb4\xb8B\xa6\x85\x1cuJgv\xe3o\x846\x8d5z\x9f*;\xb9 \xc6\xee\xf0Y\xa9f|\xe4\xf1\xe4g\x18\x0c'
]

2022-07-05 09:36:36 DEBUG (MainThread) [aiohomekit.protocol.tlv] sending [
  6: (1 bytes/<class 'bytearray'>) 0x03
  5: (120 bytes/<class 'bytes'>) b"\xe3p$\x1fOr\x0b2\xff\x14Je\x84\xd4\x19\xf3M:\xad}\xbb\x14\xb2W}\x8a\x13\xd80\xaa\xad\xea\x90\x83\xef\xdc\xe6\xce\xca'\xacA\x00\x17\xc9\xd3\xad\x01\xd8\xcc`\xc1\x96\r\xefI\x1d=\x1c\xccOcE\x1f\xed\r\x96\x92\xdd\x8e\xa9\x8c\xa0\xa5\xab\x9a\xb6\xde\x8c\x03&\xa9\xbfZ\x12\xdc\x10\x1fk\x90\xed9\xbb\xec\xae|z8k'K\x9fQ4\xe8k\xcd\xad\x16\xab\xaa\x1e\xb4L\xd6\xa9\x8d\xc54)"
]

2022-07-05 09:36:36 DEBUG (MainThread) [aiohomekit.controller.ip.connection] 192.168.213.219: raw request: b"POST /pair-verify HTTP/1.1\r\nHost: 192.168.213.219\r\nContent-Length: 125\r\nContent-Type: application/pairing+tlv8\r\n\r\n\x06\x01\x03\x05x\xe3p$\x1fOr\x0b2\xff\x14Je\x84\xd4\x19\xf3M:\xad}\xbb\x14\xb2W}\x8a\x13\xd80\xaa\xad\xea\x90\x83\xef\xdc\xe6\xce\xca'\xacA\x00\x17\xc9\xd3\xad\x01\xd8\xcc`\xc1\x96\r\xefI\x1d=\x1c\xccOcE\x1f\xed\r\x96\x92\xdd\x8e\xa9\x8c\xa0\xa5\xab\x9a\xb6\xde\x8c\x03&\xa9\xbfZ\x12\xdc\x10\x1fk\x90\xed9\xbb\xec\xae|z8k'K\x9fQ4\xe8k\xcd\xad\x16\xab\xaa\x1e\xb4L\xd6\xa9\x8d\xc54)"
2022-07-05 09:36:36 DEBUG (MainThread) [aiohomekit.controller.ip.connection] 192.168.213.219: raw response: bytearray(b'{"accessories":[{"aid":1,"services":[{"iid":1,"type":"3E","primary":false,"hidden":false,"linked":[],"characteristics":[{"iid":2,"type":"14","format":"bool","perms":["pw"]},{"iid":3,"type":"20","format":"string","value":"LIFX","perms":["pr"],"ev":false},{"iid":4,"type":"21","format":"string","value":"LIFX Color","perms":["pr"],"ev":false},{"iid":5,"type":"23","format":"string","value":"LIFX Color 687652","perms":["pr"],"ev":false},{"iid":6,"type":"30","format":"string","value":"D073D5687652","perms":["pr"],"ev":false},{"iid":7,"type":"52","format":"string","value":"3.70","perms":["pr"],"ev":false},{"iid":8,"type":"53","format":"string","value":"1","perms":["pr"],"ev":false},{"iid":48,"type":"34AB8811-AC7F-4340-BAC3-FD6A85F9943B","format":"string","value":"2.1;16B127","perms":["pr"],"ev":false}]},{"iid":16,"type":"A2","primary":false,"hidden":false,"linked":[],"characteristics":[{"iid":17,"type":"37","format":"string","value":"1.1.0","perms":["pr"],"ev":false}]},{"iid":9,"type":"43","primary":true,"hidden":false,"linked":[],"characteristics":[{"iid":14,"type":"23","format":"string","value":"Color Yest","perms":["pr"],"ev":false},{"iid":10,"type":"25","format":"bool","value":0,"perms":["pr","pw","ev"],"ev":false},{"iid":11,"type":"8","format":"int","value":100,"perms":["pr","pw","ev"],"ev":false,"unit":"percentage","minValue":0,"maxValue":100,"minStep":1},{"iid":12,"type":"2F","format":"float","value":0,"perms":["pr","pw","ev"],"ev":false,"unit":"percentage","minValue":0,"maxValue":100,"minStep":1},{"iid":13,"type":"13","format":"float","value":360,"perms":["pr","pw","ev"],"ev":false,"unit":"arcdegrees","minValue":0,"maxValue":360,"minStep":1}]}]}]}')
2022-07-05 09:36:36 DEBUG (MainThread) [aiohomekit.controller.ip.connection] Starting reconnect loop to 192.168.213.219:63928
2022-07-05 09:36:36 DEBUG (MainThread) [aiohomekit.controller.ip.connection] Attempting connection to 192.168.213.219:63928
2022-07-05 09:36:36 DEBUG (MainThread) [aiohomekit.protocol.tlv] sending [
  6: (1 bytes/<class 'bytearray'>) 0x01
  3: (32 bytes/<class 'bytes'>) b'm\xd0\x92\xae]\x8by\xddf"cbm\x1e\xec\xe2y\xdb\x83\xbe\xe9\x98\xd5\t,\xb2,\x9a\x8d\xeb\x82@'
]

2022-07-05 09:36:36 DEBUG (MainThread) [aiohomekit.controller.ip.connection] 192.168.213.219: raw request: b'POST /pair-verify HTTP/1.1\r\nHost: 192.168.213.219\r\nContent-Length: 37\r\nContent-Type: application/pairing+tlv8\r\n\r\n\x06\x01\x01\x03 m\xd0\x92\xae]\x8by\xddf"cbm\x1e\xec\xe2y\xdb\x83\xbe\xe9\x98\xd5\t,\xb2,\x9a\x8d\xeb\x82@'
2022-07-05 09:36:36 DEBUG (MainThread) [aiohomekit.controller.ip.connection] 192.168.213.219: raw response: bytearray(b'\x06\x01\x04\x07\x01\x02')
2022-07-05 09:36:36 DEBUG (MainThread) [aiohomekit.protocol.tlv] receiving [
  6: (1 bytes/<class 'bytearray'>) 0x04
  7: (1 bytes/<class 'bytearray'>) 0x02
]

2022-07-05 09:36:36 ERROR (MainThread) [aiohomekit.controller.ip.connection] Unhandled error from connecter.
Traceback (most recent call last):
  File "/Users/bdraco/home-assistant/venv/lib/python3.10/site-packages/aiohomekit/controller/ip/connection.py", line 247, in done_callback
    result.result()
  File "/Users/bdraco/home-assistant/venv/lib/python3.10/site-packages/aiohomekit/controller/ip/connection.py", line 541, in _reconnect
    return await self._connect_once()
  File "/Users/bdraco/home-assistant/venv/lib/python3.10/site-packages/aiohomekit/controller/ip/connection.py", line 627, in _connect_once
    request, expected = state_machine.send(response)
  File "/Users/bdraco/home-assistant/venv/lib/python3.10/site-packages/aiohomekit/protocol/__init__.py", line 493, in get_session_keys
    handle_state_step(response_tlv, TLV.M4)
  File "/Users/bdraco/home-assistant/venv/lib/python3.10/site-packages/aiohomekit/protocol/__init__.py", line 87, in handle_state_step
    error_handler(tlv_dict[TLV.kTLVType_Error], f"step {expected_state}")
  File "/Users/bdraco/home-assistant/venv/lib/python3.10/site-packages/aiohomekit/protocol/__init__.py", line 61, in error_handler
    raise AuthenticationError(stage)
aiohomekit.exceptions.AuthenticationError: step bytearray(b'\x04')
2022-07-05 09:36:36 ERROR (MainThread) [homeassistant] Error doing job: Task exception was never retrieved
Traceback (most recent call last):
  File "/Users/bdraco/home-assistant/homeassistant/components/homekit_controller/connection.py", line 401, in async_refresh_entity_map
    self.accessories = await self.pairing.list_accessories_and_characteristics()
  File "/Users/bdraco/home-assistant/venv/lib/python3.10/site-packages/aiohomekit/controller/ip/pairing.py", line 132, in list_accessories_and_characteristics
    await self._ensure_connected()
  File "/Users/bdraco/home-assistant/venv/lib/python3.10/site-packages/aiohomekit/controller/ip/pairing.py", line 107, in _ensure_connected
    await asyncio.wait_for(self.connection.ensure_connection(), 10)
  File "/opt/homebrew/Cellar/[email protected]/3.10.5/Frameworks/Python.framework/Versions/3.10/lib/python3.10/asyncio/tasks.py", line 445, in wait_for
    return fut.result()
  File "/Users/bdraco/home-assistant/venv/lib/python3.10/site-packages/aiohomekit/controller/ip/connection.py", line 291, in ensure_connection
    await asyncio.shield(self._connector)
  File "/Users/bdraco/home-assistant/venv/lib/python3.10/site-packages/aiohomekit/controller/ip/connection.py", line 247, in done_callback
    result.result()
  File "/Users/bdraco/home-assistant/venv/lib/python3.10/site-packages/aiohomekit/controller/ip/connection.py", line 541, in _reconnect
    return await self._connect_once()
  File "/Users/bdraco/home-assistant/venv/lib/python3.10/site-packages/aiohomekit/controller/ip/connection.py", line 627, in _connect_once
    request, expected = state_machine.send(response)
  File "/Users/bdraco/home-assistant/venv/lib/python3.10/site-packages/aiohomekit/protocol/__init__.py", line 493, in get_session_keys
    handle_state_step(response_tlv, TLV.M4)
  File "/Users/bdraco/home-assistant/venv/lib/python3.10/site-packages/aiohomekit/protocol/__init__.py", line 87, in handle_state_step
    error_handler(tlv_dict[TLV.kTLVType_Error], f"step {expected_state}")
  File "/Users/bdraco/home-assistant/venv/lib/python3.10/site-packages/aiohomekit/protocol/__init__.py", line 61, in error_handler
    raise AuthenticationError(stage)
aiohomekit.exceptions.AuthenticationError: step bytearray(b'\x04')
2022-07-05 09:36:36 DEBUG (MainThread) [aiohomekit.controller.ip.connection] 192.168.213.219: raw response: bytearray(b'\x06\x01\x02\x03 \xc8!\xa4\xe9\xde\xbb\x85\xc2\xaa\xcb\x92\\\x11\xcd\x88\xff\xa1\xa1\xf2\xee\xf4\x1a^\x17\xea$\xab8\xd1\xee\x1d5\x05e\x16\xc8\\2\xc5\xe3\xb3\xa5\x8b\xf7\n\xffJ\xfd\x1f\x92>\xd5(v|\xab\x1a\x9f,\x8az\xb1\x9ay*5Z\x8e\x8f\xe3Z\x83@\x7f\x04\x88\xef\xdf!\xabt[\n\x98\xc4\n\xa9\x12\xe9\x9a\xc3\xe0\xa3c\xc3\xb5=0\xc0\x1d0.F[_5\x9d\x89,\xee\xc9a\xc5Wx\xde\xc8\xb0\x88\x8c\x07\x86\x98\xebX\xcbq\x8a\xba\xebm\x9aa\xe5\xd3')
2022-07-05 09:36:36 DEBUG (MainThread) [aiohomekit.protocol.tlv] receiving [
  6: (1 bytes/<class 'bytearray'>) 0x02
  3: (32 bytes/<class 'bytearray'>) 0xc821a4e9debb85c2aacb925c11cd88ffa1a1f2eef41a5e17ea24ab38d1ee1d35
  5: (101 bytes/<class 'bytearray'>) 0x16c85c32c5e3b3a58bf70aff4afd1f923ed528767cab1a9f2c8a7ab19a792a355a8e8fe35a83407f0488efdf21ab745b0a98c40aa912e99ac3e0a363c3b53d30c01d302e465b5f359d892ceec961c55778dec8b0888c078698eb58cb718abaeb6d9a61e5d3
]

2022-07-05 09:36:36 DEBUG (MainThread) [aiohomekit.protocol.tlv] receiving [
  1: (17 bytes/<class 'bytearray'>) 0x31393a39333a32383a33383a42443a3445
  10: (64 bytes/<class 'bytearray'>) 0x84a195e227dfa92fa885c86c83fb04a41b708c7d21af7b45b49641ded0127338dd17412dcbe67486a605cbbc79a2d9a461269062e407f0e880f7b969aed4c00d
]

2022-07-05 09:36:36 DEBUG (MainThread) [aiohomekit.protocol.tlv] sending [
  1: (36 bytes/<class 'bytes'>) b'7eb78a6c-b75b-49fb-b6e9-e36d5865090e'
  10: (64 bytes/<class 'bytes'>) b'\x18\x8f\xb84\xb4-\xe2\xf6<6j\xc1\x16N\xae\xeeLi\x8b\x0e\xee\xec\xb1\xf4=\xef\xcb\x94*\x90k\x8f\x87\xbf\\\x8dw\xb3\xe6\xe7\xa5j2\xdf,j\xae\x01\x81\xa7*.bG\x1c\x9a\xfd^\xe38\xbbB\xb6\r'
]

2022-07-05 09:36:36 DEBUG (MainThread) [aiohomekit.protocol.tlv] sending [
  6: (1 bytes/<class 'bytearray'>) 0x03
  5: (120 bytes/<class 'bytes'>) b'\x16\xc6\x16\xe3]IJ0\x0b@\xe5\xf9Z\xc6\x96S\xec\x15U\xf2\xeair\xf1\xcbnV\xd5S\xf1\xac\xd9zRc6)\x80\xc5vg\x99\x0c<0\xf9iF\x10\x8b\xb3(\xf2\xd2$\xeb$A\\c*>\xdf\x1f\xaa\xbe\x16\x0b{\x85\xf1NX\x90\xc6\xd4?[z"c\x90\x86\x05c\xa2\xc8\x8a\x0b\x9dq\xe3#f:2\xcb.>k\xe9\xcd\xe5\xf4\xdc[\x0e\x81\x1b\xbf]\xc5\x06\x88,\x00_v\xfe\xb9'
]

2022-07-05 09:36:36 DEBUG (MainThread) [aiohomekit.controller.ip.connection] 192.168.213.219: raw request: b'POST /pair-verify HTTP/1.1\r\nHost: 192.168.213.219\r\nContent-Length: 125\r\nContent-Type: application/pairing+tlv8\r\n\r\n\x06\x01\x03\x05x\x16\xc6\x16\xe3]IJ0\x0b@\xe5\xf9Z\xc6\x96S\xec\x15U\xf2\xeair\xf1\xcbnV\xd5S\xf1\xac\xd9zRc6)\x80\xc5vg\x99\x0c<0\xf9iF\x10\x8b\xb3(\xf2\xd2$\xeb$A\\c*>\xdf\x1f\xaa\xbe\x16\x0b{\x85\xf1NX\x90\xc6\xd4?[z"c\x90\x86\x05c\xa2\xc8\x8a\x0b\x9dq\xe3#f:2\xcb.>k\xe9\xcd\xe5\xf4\xdc[\x0e\x81\x1b\xbf]\xc5\x06\x88,\x00_v\xfe\xb9'
2022-07-05 09:36:36 DEBUG (MainThread) [aiohomekit.controller.ip.connection] 192.168.213.219: raw response: bytearray(b'\x06\x01\x04')
2022-07-05 09:36:36 DEBUG (MainThread) [aiohomekit.protocol.tlv] receiving [
  6: (1 bytes/<class 'bytearray'>) 0x04
]

2022-07-05 09:36:36 DEBUG (MainThread) [aiohomekit.controller.ip.connection] Secure connection to 192.168.213.219:63928 established
2022-07-05 09:36:36 DEBUG (MainThread) [homeassistant.components.homekit_controller.connection] Called async_set_available_state with True for 19:93:28:38:BD:4E
2022-07-05 09:36:36 DEBUG (MainThread) [aiohomekit.controller.ip.connection] 192.168.213.219: raw request: b'GET /accessories HTTP/1.1\r\nHost: 192.168.213.219\r\n\r\n'
2022-07-05 09:36:36 DEBUG (MainThread) [aiohomekit.controller.ip.connection] 192.168.213.219: raw response: bytearray(b'{"accessories":[{"aid":1,"services":[{"iid":1,"type":"3E","primary":false,"hidden":false,"linked":[],"characteristics":[{"iid":2,"type":"14","format":"bool","perms":["pw"]},{"iid":3,"type":"20","format":"string","value":"LIFX","perms":["pr"],"ev":false},{"iid":4,"type":"21","format":"string","value":"LIFX Color","perms":["pr"],"ev":false},{"iid":5,"type":"23","format":"string","value":"LIFX Color 687652","perms":["pr"],"ev":false},{"iid":6,"type":"30","format":"string","value":"D073D5687652","perms":["pr"],"ev":false},{"iid":7,"type":"52","format":"string","value":"3.70","perms":["pr"],"ev":false},{"iid":8,"type":"53","format":"string","value":"1","perms":["pr"],"ev":false},{"iid":48,"type":"34AB8811-AC7F-4340-BAC3-FD6A85F9943B","format":"string","value":"2.1;16B127","perms":["pr"],"ev":false}]},{"iid":16,"type":"A2","primary":false,"hidden":false,"linked":[],"characteristics":[{"iid":17,"type":"37","format":"string","value":"1.1.0","perms":["pr"],"ev":false}]},{"iid":9,"type":"43","primary":true,"hidden":false,"linked":[],"characteristics":[{"iid":14,"type":"23","format":"string","value":"Color Yest","perms":["pr"],"ev":false},{"iid":10,"type":"25","format":"bool","value":0,"perms":["pr","pw","ev"],"ev":false},{"iid":11,"type":"8","format":"int","value":100,"perms":["pr","pw","ev"],"ev":false,"unit":"percentage","minValue":0,"maxValue":100,"minStep":1},{"iid":12,"type":"2F","format":"float","value":0,"perms":["pr","pw","ev"],"ev":false,"unit":"percentage","minValue":0,"maxValue":100,"minStep":1},{"iid":13,"type":"13","format":"float","value":360,"perms":["pr","pw","ev"],"ev":false,"unit":"arcdegrees","minValue":0,"maxValue":360,"minStep":1}]}]}]}')
2022-07-05 09:36:36 DEBUG (MainThread) [homeassistant.components.homekit_controller.connection] Migrating device registry entries for pairing 19:93:28:38:BD:4E

Exepected state bytearray(b'\x06') but got bytearray(b'\x06\x05') when trying to pair a HomeKit bridge

Hi!

Dont know if this is the right place to post this issue.
I'm having some trouble with pairing of a HomeKit bridge to HA. I have never touched HA before, so all this is new to me.
Is there an issue with aiohomekit or the bridge I'm trying to add?

2020-11-17 02:22:15 ERROR (MainThread) [homeassistant.components.homekit_controller.config_flow] Pairing attempt failed with an unhandled exception
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/components/homekit_controller/config_flow.py", line 297, in async_step_pair
    pairing = await self.finish_pairing(code)
  File "/usr/local/lib/python3.8/site-packages/aiohomekit/controller/ip/discovery.py", line 99, in finish_pairing
    request, expected = state_machine.send(response)
  File "/usr/local/lib/python3.8/site-packages/aiohomekit/protocol/__init__.py", line 243, in perform_pair_setup_part2
    handle_state_step(response_tlv, TLV.M6)
  File "/usr/local/lib/python3.8/site-packages/aiohomekit/protocol/__init__.py", line 81, in handle_state_step
    raise InvalidError(f"Exepected state {expected_state} but got {actual_state}")
aiohomekit.exceptions.InvalidError: Exepected state bytearray(b'\x06') but got bytearray(b'\x06\x05')

Running HassOS on a IntelNUC with Proxmox

arch x86_64
chassis vm
dev false
docker true
docker_version 19.03.12
hassio true
host_os HassOS 4.16
installation_type Home Assistant OS
os_name Linux
os_version 5.4.75
python_version 3.8.6
supervisor 2020.11.0
timezone Europe/Oslo
version 0.117.6
virtualenv false

EDIT:
I can also add that pairing this bridge directly to HomeKit works fine, but not when trying to pair it to HA.

Have also debug logs if needed, with this setup in configuration.yaml:

 logger:
  default: info
  logs:
    aiohomekit: debug
    homeassistant.components.homekit_controller: debug

Share PDU code between CoAP and BLE?

I optimistically put the BLE PDU code in aiohomekit/pdu.py. But how generic is it?

We can move the CoAP versions for OpCode and PDUStatus to aiohomekit.pdu for sure.

In terms of merging encode_pdu:

  • How does CoAP handle IP fragmentation? The spec says to assume a max payload size of 1024. An ipv6 packet has a minimum MTU of 1280. So i'm guessing we won't need do do fragmentation for CoAP? So i don't really want to inflict my version on you if thats the case.

In terms of merging decode_pdu:

  • It looks like your CoAP accessory always returns a body length, even if there is no body. That's not the case for BLE. 3 byte response PDU's are pretty common. It will be interesting to see if that is a Nanoleaf behaviour or not.
  • The request/response bit should be set of BLE PDU, so I could use your version there.
  • I can see why you'd return a ValueError, but the return type gets a bit messy. I think for mine i'll probably add a "proper" exception rather than just a ValueError. Would that work for you?

CC @roysjosh

Eliminate usage of crypt library

Because of the crypt library is not available on Windows, I'm receiving an error in HA
2020-08-03 00:45:40:0100 700 2020-08-03 00:45:39 ERROR (MainThread) [homeassistant.config_entries] Error occurred loading configuration flow for integration homekit_controller: The crypt module is not supported on Windows

As I can see, it is used in one place only to generate a salt in the aiohomekit/aiohomekit/crypto/srp.py
salt = crypt.mksalt(crypt.METHOD_SHA512)[3:]

May be it can be replaced with different implementation?

Pairing with a Cozylife 3 gang switch sometimes fails

2022-08-14 13:14:15.371 DEBUG (MainThread) [aiohomekit.protocol.tlv] receiving [
  1 (Identifier): (17 bytes/<class 'bytearray'>) 0x35423a32453a45303a38443a44373a3430
  3 (PublicKey): (32 bytes/<class 'bytearray'>) 0x0000000000000000000000000000000000000000000000000000000000000000
  10 (Signature): (64 bytes/<class 'bytearray'>) 0x74bd4c98f89b79a8a2882e4ad4deb910ad2770c9285c413ed7af8e65b7cc4fcbdf506a2990548f87aa322debc9a258dfa0fbedb9abfa8e0bb0f4f5d12f3a1f00
]

I'm going to guess the device sending a public key of 0000000 is a problem :)

2022-08-14 13:12:55.621 DEBUG (MainThread) [aiohomekit.controller.ip.connection] 192.168.106.202: raw request: b'GET /characteristics?id=1.13 HTTP/1.1\r\nHost: 192.168.106.202\r\n\r\n'
2022-08-14 13:12:56.082 DEBUG (MainThread) [aiohomekit.controller.ip.connection] 192.168.106.202: raw response: bytearray(b'{"characteristics":[{"aid":1,"iid":13,"value":false}]}')
2022-08-14 13:13:19.174 DEBUG (MainThread) [aiohomekit.controller.ip.connection] 192.168.106.25: raw request: b'GET /characteristics?id=1.51 HTTP/1.1\r\nHost: 192.168.106.25\r\n\r\n'
2022-08-14 13:13:19.247 DEBUG (MainThread) [aiohomekit.controller.ip.connection] 192.168.106.25: raw response: bytearray(b'{"characteristics":[{"aid":1,"iid":51,"value":1}]}')
2022-08-14 13:13:32.704 DEBUG (MainThread) [aiohomekit.controller.ip.connection] 192.168.107.81: raw request: b'GET /characteristics?id=1.13 HTTP/1.1\r\nHost: 192.168.107.81\r\n\r\n'
2022-08-14 13:13:32.800 DEBUG (MainThread) [aiohomekit.controller.ip.connection] 192.168.107.81: raw response: bytearray(b'{"characteristics":[{"aid":1,"iid":13,"value":false}]}')
2022-08-14 13:13:34.279 DEBUG (MainThread) [aiohomekit.controller.ip.connection] 192.168.107.127: raw request: b'GET /characteristics?id=1.37,1.34,1.49,1.52,1.18,1.76,1.21,1.24,1.27,1.33,1.39,1.36,1.51,1.54,1.75,1.20,1.17,1.23,1.35,1.38,1.41,1.50,1.53,1.19,1.25,1.22 HTTP/1.1\r\nHost: 192.168.107.127\r\n\r\n'
2022-08-14 13:13:34.398 DEBUG (MainThread) [aiohomekit.controller.ip.connection] 192.168.107.127: raw response: bytearray(b'{"characteristics":[{"aid":1,"iid":37,"value":27.8},{"aid":1,"iid":34,"value":20.6},{"aid":1,"iid":49,"value":1},{"aid":1,"iid":52,"value":100},{"aid":1,"iid":18,"value":2},{"aid":1,"iid":76,"value":0},{"aid":1,"iid":21,"value":1},{"aid":1,"iid":24,"value":53.0},{"aid":1,"iid":27,"value":"My ecobee"},{"aid":1,"iid":33,"value":0},{"aid":1,"iid":39,"value":27.8},{"aid":1,"iid":36,"value":17.8},{"aid":1,"iid":51,"value":0},{"aid":1,"iid":54,"value":"There may be a problem with the Cooling system.\\nFor the past 4 hours the thermostat has been callin"},{"aid":1,"iid":75,"value":1},{"aid":1,"iid":20,"value":25.6},{"aid":1,"iid":17,"value":0},{"aid":1,"iid":23,"value":20.6},{"aid":1,"iid":35,"value":25.6},{"aid":1,"iid":38,"value":18.3},{"aid":1,"iid":41,"value":"2014-01-03T00:00:00-10:00W"},{"aid":1,"iid":50,"value":0},{"aid":1,"iid":53,"value":0},{"aid":1,"iid":19,"value":22.4},{"aid":1,"iid":25,"value":36.0},{"aid":1,"iid":22,"value":25.6}]}')
2022-08-14 13:13:52.588 DEBUG (MainThread) [aiohomekit.controller.ble.controller] Discovery for hkid 5B:2E:E0:8D:D7:40 not found, waiting for advertisement with timeout: 30.0
2022-08-14 13:13:52.589 DEBUG (MainThread) [aiohomekit.controller.ip.connection] Starting reconnect loop to 192.168.107.146:80
2022-08-14 13:13:52.589 DEBUG (MainThread) [aiohomekit.controller.ip.connection] Attempting connection to 192.168.107.146:80
2022-08-14 13:13:52.624 DEBUG (MainThread) [aiohomekit.protocol] #1 ios -> accessory: send SRP start request
2022-08-14 13:13:52.624 DEBUG (MainThread) [aiohomekit.protocol.tlv] sending [
  6 (State): (1 bytes/<class 'bytearray'>) 0x01
  0 (Method): (1 bytes/<class 'bytearray'>) 0x00
]

2022-08-14 13:13:52.624 DEBUG (MainThread) [aiohomekit.controller.ip.connection] 192.168.107.146: raw request: b'POST /pair-setup HTTP/1.1\r\nHost: 192.168.107.146\r\nContent-Length: 6\r\nContent-Type: application/pairing+tlv8\r\n\r\n\x06\x01\x01\x00\x01\x00'
2022-08-14 13:13:52.769 DEBUG (MainThread) [aiohomekit.controller.ip.connection] 192.168.107.146: raw response: bytearray(b'\x06\x01\x02\x03\xffU5\x93\x16\x05\x8d\xb7i\xd9"`\xd7\xbaq\xcf\xe9\x16v7\xaf,\xb6/\x1d\xb8\xbcN\x19\xc3"q\xf5\xbbP:e.?\x15=t*\x95\xcf\xab\x92\x80\xee(\xf9.\xa2\xac\xa7\x89\xbc\x1b\x7f\x15\xf8\x8f\x9ek\x9b\xd5\xfe?\xb3\xcc\xc6\xfb\x03\xc4b\xe6u\xafU\xb5/\x91\xdb\xf5)\x904b\x1a\x84\x12\x9bH~\x1f\xb8)\x03g\xbb\x1f\x81\xfd\xd9\xceh\x13\xe3\xc6\xf4\xf4e\x95y;\xcb\x9b\x15g\xeb\xb4 \xd3\x8bPL\xab\x18\xd14gE\xa4\x89\x83/\xa6I\xff\xd8\x93\xb9\xe2\xd1K<#I\xdb\xcb\x8b\xd3\n\x11LP\x1a\xa9(\xdd\xcf\x96\xc3\xd1\xc0\xbd\x11\xab\xecS\x14\xae\xabhn\x98\xfb\x1a(\xf5\x94\xfc\xf7Emg\xd3\xf6\x89\xd0\x0b0NzA\xd0{\x1f\xfa_w\x1c\xca\x8cw\xfd\x0f+\xcc\xe0\x97\xd17=\x8f\xbb\xc3i\xef\xfd\x94\x02\x15Q0\x18\xc7\x8f\\\xd8.\xc14\x92\xa7C[\xe9\xac\x04\xe3X\x10.`\x9f\xca\xc6N\xb7\x8f$I\xdc\xa3e\x03\x81}\xddd\x86\xc0\xc4z\xd8[\x9b\xc5Z\x02\x88\xceJ\x92\xd5\xda\xeb\xe9\\k\xf3I \x94q\x81\xbc4\x98(\xb0\xff^\xbe\x04\x02\xef\x8a\x81\xb6\x98\xc7\xefw?y\x1d52D\x9db\xf6"\xc5\xaf\xcc`\t\xbcxA\xbfB\xc1\x08\x9d\x1a\x03\x1d\xb0\xaa\xee\n\xa7:1\x8f_\xc4\x91\x8d\xa7\x8d\x03\xb3\xcd\xa5\x96{*<\x7f\xac7\x0b*\xa7\xaap^\x97\xb4\x89\xa8\xe0\x10FA\x9eF\x8a\xc3#4\xde\xd7B\x8d\xa5\xab\xf63ds\x86\x02\x10\x18\x1a5\x00\x1e\xe2\xf7?-\\\xa5[M\x14@\x8b')
2022-08-14 13:13:52.770 DEBUG (MainThread) [aiohomekit.protocol.tlv] receiving [
  6 (State): (1 bytes/<class 'bytearray'>) 0x02
  3 (PublicKey): (384 bytes/<class 'bytearray'>) 0x55359316058db769d92260d7ba71cfe9167637af2cb62f1db8bc4e19c32271f5bb503a652e3f153d742a95cfab9280ee28f92ea2aca789bc1b7f15f88f9e6b9bd5fe3fb3ccc6fb03c462e675af55b52f91dbf5299034621a84129b487e1fb8290367bb1f81fdd9ce6813e3c6f4f46595793bcb9b1567ebb420d38b504cab18d1346745a489832fa649ffd893b9e2d14b3c2349dbcb8bd30a114c501aa928ddcf96c3d1c0bd11abec5314aeab686e98fb1a28f594fcf7456d67d3f689d00b304e7a41d07b1ffa5f771cca8c77fd0f2bcce097d1373d8fbbc369effd940215513018c78f5cd82ec13492a7435be9ac04e358102e609fcac64eb78f2449dca3657ddd6486c0c47ad85b9bc55a0288ce4a92d5daebe95c6bf34920947181bc349828b0ff5ebe0402ef8a81b698c7ef773f791d3532449d62f622c5afcc6009bc7841bf42c1089d1a031db0aaee0aa73a318f5fc4918da78d03b3cda5967b2a3c7fac370b2aa7aa705e97b489a8e01046419e468ac32334ded7428da5abf633647386
  2 (Salt): (16 bytes/<class 'bytearray'>) 0x181a35001ee2f73f2d5ca55b4d14408b
]

2022-08-14 13:13:52.770 DEBUG (MainThread) [aiohomekit.protocol] #3 ios -> accessory: send SRP verify request
2022-08-14 13:13:55.621 DEBUG (MainThread) [aiohomekit.controller.ip.connection] 192.168.106.202: raw request: b'GET /characteristics?id=1.13 HTTP/1.1\r\nHost: 192.168.106.202\r\n\r\n'
2022-08-14 13:13:55.670 DEBUG (MainThread) [aiohomekit.controller.ip.connection] 192.168.106.202: raw response: bytearray(b'{"characteristics":[{"aid":1,"iid":13,"value":false}]}')
2022-08-14 13:14:04.999 INFO (MainThread) [homeassistant.helpers.entity_registry] Registered new device_tracker.bluetooth_le_tracker entity: device_tracker.e922ebea_552d_b43d_b2c5_e232c3ced028
2022-08-14 13:14:14.615 DEBUG (MainThread) [aiohomekit.protocol.tlv] sending [
  6 (State): (1 bytes/<class 'bytearray'>) 0x03
  3 (PublicKey): (384 bytes/<class 'bytes'>) b"\xec\xf77\xe2\x95X\x96\xf7\x95\x8fK|\xa4\x84\xd8\xf2\xa5\xa7\xba\x97\x99\x0fB\xd3R\xb8\xbe\xad\x95\xe3\xd4\x08Dq\xc5\xa6\x92\x89\ru\x02'%^]\x9c\xaen\x03L\xb4q\x9bU|\xa3\xd7\xb0\xac)\xe0\x0ba\x17O \x08*+\xe7\x83\x8f\xbce&O\xa7'\x14\xc39\x9b\x80wU\tGr\x80yRXoL\xd0\xd5\xcf5_LN/\x04\x89p\xdd\xef;\xe4\x83J\x81sg\xd3\xb2\x9f\xd3\x08b \xc3\x1d]\x80\xc44\xb1H\xc5l\x04A=\x89\x8a\x98\xc0\x8at,z\xa7P\xf1i\xadA@]\x0f\x97\xc6^\x0e\x8a\t1\xda\x98\xe6F\xc7H\x80<R\xb8\x1c\x9d\xad\xc2jV\xa9\x1e\x1b$(hP\xbc\x9f\xc1\xe1H\x9a\xdf&\xaeu\x02\x15\xc6\x9fR\xcc\xc7t\xa3\xfe\xecJ\xb8\xa1\x97\x8b\x01\xd5\x95.\x97\xa4 \xcac\xe9aSQa]fl\xb3\xde\x91zOG\x87X\x14U\xd3x\x02\xfa\xb0\x01U\xf2\xb09q\x81\x83\x9a\x020\xe7\xb7\xe3\x10\xa8\x90&\x1f\xafYL\xfd\xd9X5p\xac;D6\x97\xb6\x07\xd6\xffDG\x98\xedmnr`M\x00\x04|\x07\x96\xd9\xcb\x82T\x94\xef*\x08[\xd3W\x0c\xed\xb4\x0f\xce\xfa2Z\xe2\xa5\xdd{\x84\n\xa3\x8f#\x9c\xcf\x86w-\xfdo\xfb\xad\xd8\xc4\xccW\x13\xa0YS4\xdfY\\\xf0b\x14WP\xfc\xbaA\xfc\xd5VXf\x05{\xdc|\x1ck6\xfb\xfeXR\xef\xfc\\\x9c\xcd\xe9\x8a:\x81im\xed\x12I\xdb\xc2\x16\xe5\xe1\xf5s\xba"
  4 (Proof): (64 bytes/<class 'bytes'>) b"\xcf$\xa4uu\xca\xb6\xe6\x0b)\xd6=\xee\x1d\x9dO\x91xAg|\x82F\xcd\xe9\xa9\xb0\xa3I\xd4\xd9\x0cJW\xbf\x14\x15,u\xab!8\xc6y\x17Y\x9cy\x88\x1c]\xc8h't\x97x`\xf6\xb9\x1e-O\x92"
]

2022-08-14 13:14:14.615 DEBUG (MainThread) [aiohomekit.controller.ip.connection] 192.168.107.146: raw request: b"POST /pair-setup HTTP/1.1\r\nHost: 192.168.107.146\r\nContent-Length: 457\r\nContent-Type: application/pairing+tlv8\r\n\r\n\x06\x01\x03\x03\xff\xec\xf77\xe2\x95X\x96\xf7\x95\x8fK|\xa4\x84\xd8\xf2\xa5\xa7\xba\x97\x99\x0fB\xd3R\xb8\xbe\xad\x95\xe3\xd4\x08Dq\xc5\xa6\x92\x89\ru\x02'%^]\x9c\xaen\x03L\xb4q\x9bU|\xa3\xd7\xb0\xac)\xe0\x0ba\x17O \x08*+\xe7\x83\x8f\xbce&O\xa7'\x14\xc39\x9b\x80wU\tGr\x80yRXoL\xd0\xd5\xcf5_LN/\x04\x89p\xdd\xef;\xe4\x83J\x81sg\xd3\xb2\x9f\xd3\x08b \xc3\x1d]\x80\xc44\xb1H\xc5l\x04A=\x89\x8a\x98\xc0\x8at,z\xa7P\xf1i\xadA@]\x0f\x97\xc6^\x0e\x8a\t1\xda\x98\xe6F\xc7H\x80<R\xb8\x1c\x9d\xad\xc2jV\xa9\x1e\x1b$(hP\xbc\x9f\xc1\xe1H\x9a\xdf&\xaeu\x02\x15\xc6\x9fR\xcc\xc7t\xa3\xfe\xecJ\xb8\xa1\x97\x8b\x01\xd5\x95.\x97\xa4 \xcac\xe9aSQa]fl\xb3\xde\x91zOG\x87X\x14U\xd3x\x02\xfa\xb0\x01U\xf2\xb09q\x81\x83\x9a\x020\xe7\xb7\xe3\x10\xa8\x03\x81\x90&\x1f\xafYL\xfd\xd9X5p\xac;D6\x97\xb6\x07\xd6\xffDG\x98\xedmnr`M\x00\x04|\x07\x96\xd9\xcb\x82T\x94\xef*\x08[\xd3W\x0c\xed\xb4\x0f\xce\xfa2Z\xe2\xa5\xdd{\x84\n\xa3\x8f#\x9c\xcf\x86w-\xfdo\xfb\xad\xd8\xc4\xccW\x13\xa0YS4\xdfY\\\xf0b\x14WP\xfc\xbaA\xfc\xd5VXf\x05{\xdc|\x1ck6\xfb\xfeXR\xef\xfc\\\x9c\xcd\xe9\x8a:\x81im\xed\x12I\xdb\xc2\x16\xe5\xe1\xf5s\xba\x04@\xcf$\xa4uu\xca\xb6\xe6\x0b)\xd6=\xee\x1d\x9dO\x91xAg|\x82F\xcd\xe9\xa9\xb0\xa3I\xd4\xd9\x0cJW\xbf\x14\x15,u\xab!8\xc6y\x17Y\x9cy\x88\x1c]\xc8h't\x97x`\xf6\xb9\x1e-O\x92"
2022-08-14 13:14:14.943 DEBUG (MainThread) [aiohomekit.controller.ip.connection] 192.168.107.146: raw response: bytearray(b"\x06\x01\x04\x04@\x92O\xbc\xe4\x03\xb1/\x13F\xdfpO\x10H\x9d\x9e2\xb7\xc3\xcb\xff\t\'E\x8a:L\xb6\xea\n\xbcC\xa5\x8e\x1fi=0\\\x08\xd6\xf2zr?cG\xa9;T\xaa\x81\xe9`\xad\xa8qL\xff\xa3\xe6f2\x0f\x05\x1a\xbc\x04P\x91Rp\xa6\xbf\x9f;\xe1\xbe\x8b$i\xc2\tC\x84\xc5\xc0\xaa\xbf\xf7\r\x91")
2022-08-14 13:14:14.943 DEBUG (MainThread) [aiohomekit.protocol.tlv] receiving [
  6 (State): (1 bytes/<class 'bytearray'>) 0x04
  4 (Proof): (64 bytes/<class 'bytearray'>) 0x924fbce403b12f1346df704f10489d9e32b7c3cbff0927458a3a4cb6ea0abc43a58e1f693d305c08d6f27a723f6347a93b54aa81e960ada8714cffa3e666320f
  5 (EncryptedData): (26 bytes/<class 'bytearray'>) 0xbc0450915270a6bf9f3be1be8b2469c2094384c5c0aabff70d91
]

2022-08-14 13:14:14.943 DEBUG (MainThread) [aiohomekit.protocol] #5 ios -> accessory: send SRP exchange request
2022-08-14 13:14:15.136 DEBUG (MainThread) [aiohomekit.protocol.tlv] sending [
  1 (Identifier): (36 bytes/<class 'bytes'>) b'a8445b03-0802-4894-98eb-962429cfa37a'
  3 (PublicKey): (32 bytes/<class 'bytes'>) b"^\x9c\xa9\xaf\x9a2{\xa1\x04\xe4\xbep\xbe\xed\xe3b\xc0\xc0+\x81\x0fO\xc1\xf9L\xa7'>O11\xa5"
  10 (Signature): (64 bytes/<class 'bytes'>) b'\x82j\xb6\x8f\t\xb6\xd6-\x05l|\xe87\xdb\x18\xc0\t\x02\x80\xf6\xf6spN/\xbc1\x8f\x94\xcd\x1e\\\xd0\xbbL\x063\xefd\xeb\xb5d8]\xc7ij\x95\x1f\x03f\x94D\xd3\xaf\xcdD\x1e\x99u\xdf&H\x02'
]

2022-08-14 13:14:15.136 DEBUG (MainThread) [aiohomekit.protocol.tlv] sending [
  6 (State): (1 bytes/<class 'bytearray'>) 0x05
  5 (EncryptedData): (154 bytes/<class 'bytes'>) b'\xf5\xf4{\x98\x8a^\x81l\xf7z~r\xa3\x06\xf3\x0b(\xd8\xd5l\xf5\xb4\x925\xdf\xe6S\x14\xeb\xf4\xe8\xc6xE>\x1d\x9e\xab\x1a\x05\x13\x12\x11V`\xd2\xb0\xc3\xb4\x8fwY\xeeRh|\xe3\x985\x12\xbfl/\n\xdc\x11+~\xdf\x91\x84\x16\xa7\x1e\xdd\xe1-e\xe2\xa4\xca\xc2\x1f\x94B\xa9\xa4_\x1ab\x849\xc8\x8a]\x10s\x97\x9e\xb5MrK\x89\xf7\xdd\xd0\xcby\xf9\xb0\xcf\xff\xc2\xe3\xa3]D\xdd\xf2\xafx\xc0\xc7\xa1X\xcfDB\xdd\x08\xe3X\xd9\xcc^\xcb6j\x80\x8f\x8b,dN\xc1\x85E\xf9,\xe5Z\xb3\x07'
]

2022-08-14 13:14:15.136 DEBUG (MainThread) [aiohomekit.controller.ip.connection] 192.168.107.146: raw request: b'POST /pair-setup HTTP/1.1\r\nHost: 192.168.107.146\r\nContent-Length: 159\r\nContent-Type: application/pairing+tlv8\r\n\r\n\x06\x01\x05\x05\x9a\xf5\xf4{\x98\x8a^\x81l\xf7z~r\xa3\x06\xf3\x0b(\xd8\xd5l\xf5\xb4\x925\xdf\xe6S\x14\xeb\xf4\xe8\xc6xE>\x1d\x9e\xab\x1a\x05\x13\x12\x11V`\xd2\xb0\xc3\xb4\x8fwY\xeeRh|\xe3\x985\x12\xbfl/\n\xdc\x11+~\xdf\x91\x84\x16\xa7\x1e\xdd\xe1-e\xe2\xa4\xca\xc2\x1f\x94B\xa9\xa4_\x1ab\x849\xc8\x8a]\x10s\x97\x9e\xb5MrK\x89\xf7\xdd\xd0\xcby\xf9\xb0\xcf\xff\xc2\xe3\xa3]D\xdd\xf2\xafx\xc0\xc7\xa1X\xcfDB\xdd\x08\xe3X\xd9\xcc^\xcb6j\x80\x8f\x8b,dN\xc1\x85E\xf9,\xe5Z\xb3\x07'
2022-08-14 13:14:15.370 DEBUG (MainThread) [aiohomekit.controller.ip.connection] 192.168.107.146: raw response: bytearray(b'\x06\x01\x06\x05\x87t\xa2\x0e\xa7\x14\xf4d\x8a\x7f+& \xc8\xd0YT-V1\x00\xb4>"\xb2\xbe\xd3\xb4\x86\r\xddiss\x8c\r\xa52\xb6\xcb\x86\xf4S-\xfa\xcb\xa8\x05S#\x9f\xe8\x9c,\xd4Z\x05\x99X\x9b r\x13T\xc0\xec{\xe78\x1fQ\x8d\xed\xd2v4\x91\xd3\x1cO\x84\xd6\x0e\xc36\xfb\xd9\xb8\xa5b\x0c\xff\xda\xf0\x9e\x80-\x88d\x14\xe95\x0e\xbb)":\x13\x82\xf0\xf4\x85\x89\xb1\x1e\xaa\x84J\xe2\x1a\x14\xd3\x9f\xa3"\xa1Z\x11\x1c\x187\x88=z\x8c\x83')
2022-08-14 13:14:15.370 DEBUG (MainThread) [aiohomekit.protocol.tlv] receiving [
  6 (State): (1 bytes/<class 'bytearray'>) 0x06
  5 (EncryptedData): (135 bytes/<class 'bytearray'>) 0x74a20ea714f4648a7f2b2620c8d059542d563100b43e22b2bed3b4860ddd6973738c0da532b6cb86f4532dfacba80553239fe89c2cd45a0599589b20721354c0ec7be7381f518dedd2763491d31c4f84d60ec336fbd9b8a5620cffdaf09e802d886414e9350ebb29223a1382f0f48589b11eaa844ae21a14d39fa322a15a111c1837883d7a8c83
]

2022-08-14 13:14:15.371 DEBUG (MainThread) [aiohomekit.protocol.tlv] receiving [
  1 (Identifier): (17 bytes/<class 'bytearray'>) 0x35423a32453a45303a38443a44373a3430
  3 (PublicKey): (32 bytes/<class 'bytearray'>) 0x0000000000000000000000000000000000000000000000000000000000000000
  10 (Signature): (64 bytes/<class 'bytearray'>) 0x74bd4c98f89b79a8a2882e4ad4deb910ad2770c9285c413ed7af8e65b7cc4fcbdf506a2990548f87aa322debc9a258dfa0fbedb9abfa8e0bb0f4f5d12f3a1f00
]

2022-08-14 13:14:15.458 ERROR (MainThread) [homeassistant.components.homekit_controller.config_flow] Pairing attempt failed with an unhandled exception
Traceback (most recent call last):
  File "/Users/bdraco/home-assistant/venv/lib/python3.10/site-packages/aiohomekit/protocol/__init__.py", line 337, in perform_pair_setup_part2
    e25519s.verify(bytes(accessory_sig), bytes(accessory_info))
  File "/Users/bdraco/home-assistant/venv/lib/python3.10/site-packages/cryptography/hazmat/backends/openssl/ed25519.py", line 73, in verify
    raise exceptions.InvalidSignature
cryptography.exceptions.InvalidSignature

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Users/bdraco/home-assistant/homeassistant/components/homekit_controller/config_flow.py", line 464, in async_step_pair
    pairing = await self.finish_pairing(code)
  File "/Users/bdraco/home-assistant/venv/lib/python3.10/site-packages/aiohomekit/controller/ip/discovery.py", line 88, in finish_pairing
    request, expected = state_machine.send(response)
  File "/Users/bdraco/home-assistant/venv/lib/python3.10/site-packages/aiohomekit/protocol/__init__.py", line 339, in perform_pair_setup_part2
    raise InvalidSignatureError("step #7")
aiohomekit.exceptions.InvalidSignatureError: step #7
2022-08-14 13:14:15.462 DEBUG (MainThread) [aiohomekit.controller.ble.controller] Discovery for hkid 5B:2E:E0:8D:D7:40 not found, waiting for advertisement with timeout: 30.0
2022-08-14 13:14:15.465 DEBUG (MainThread) [aiohomekit.protocol] #1 ios -> accessory: send SRP start request
2022-08-14 13:14:15.465 DEBUG (MainThread) [aiohomekit.protocol.tlv] sending [
  6 (State): (1 bytes/<class 'bytearray'>) 0x01
  0 (Method): (1 bytes/<class 'bytearray'>) 0x00
]

2022-08-14 13:14:15.465 DEBUG (MainThread) [aiohomekit.controller.ip.connection] 192.168.107.146: raw request: b'POST /pair-setup HTTP/1.1\r\nHost: 192.168.107.146\r\nContent-Length: 6\r\nContent-Type: application/pairing+tlv8\r\n\r\n\x06\x01\x01\x00\x01\x00'
2022-08-14 13:14:15.569 DEBUG (MainThread) [aiohomekit.controller.ip.connection] 192.168.107.146: raw response: bytearray(b'\x06\x01\x02\x07\x01\x06')
2022-08-14 13:14:15.569 DEBUG (MainThread) [aiohomekit.protocol.tlv] receiving [
  6 (State): (1 bytes/<class 'bytearray'>) 0x02
  7 (Error): (1 bytes/<class 'bytearray'>) 0x06 [Unavailable]
]


iDevice Switch not working

Pairing an iDevice Switch through Home Assistant (HA) causes an error:

Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/config_entries.py", line 216, in async_setup
    hass, self
  File "/usr/src/homeassistant/homeassistant/components/homekit_controller/__init__.py", line 189, in async_setup_entry
    if not await conn.async_setup():
  File "/usr/src/homeassistant/homeassistant/components/homekit_controller/connection.py", line 159, in async_setup
    self.entity_map = Accessories.from_list(self.accessories)
  File "/usr/local/lib/python3.7/site-packages/aiohomekit/model/__init__.py", line 259, in from_list
    self.add_accessory(Accessory.create_from_dict(accessory))
  File "/usr/local/lib/python3.7/site-packages/aiohomekit/model/__init__.py", line 190, in create_from_dict
    "format": char_data["format"],
KeyError: 'format'

Changing line 190 to return None if key is not found solves the problem, and allows the iDevices accessory to be added to HA.

Line 190: "format": char_data.get("format", None),

I don't know enough about Homekit to know whether a "format" key is necessary, but it appears that it is not.

Don't make our own service browser

From chat with @bdraco

zc.async_add_listener(self, None)
zc.async_remove_listener(self)

then all the changes come in via

    def async_update_records(self, zc: 'Zeroconf', now: float, records: List[RecordUpdate]) -> None:
        """Updates service information from a DNS record.

        This method will be run in the event loop.
        """

And you have to reject everything you don't want

async_add_listener will take a second argument of DNSQuestions if you want it to feed you back all the answer it already knows for the question. Otherwise you only get a live feed of what comes in over the wire

its probably fine to do that. Its how AsyncServiceInfo listeners for responses
as long as there is a single listener and you don't add a new one for every device it shouldn't have a scale problem
if its just c# updates, they will all be TXTRecords and you could ignore anything else

Bluetooth debugging

Model not set

This hits everything. But this was the only patch needed to be able to pair an Eve Motion.

It's not part of the advertisement, we have to read a characteristic.

diff --git a/homeassistant/components/homekit_controller/config_flow.py b/homeassistant/components/homekit_controller/config_flow.py
index ac840eb068..86334f14b1 100644
--- a/homeassistant/components/homekit_controller/config_flow.py
+++ b/homeassistant/components/homekit_controller/config_flow.py
@@ -111,7 +111,7 @@ class HomekitControllerFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
         if user_input is not None:
             key = user_input["device"]
             self.hkid = self.devices[key].description.id
-            self.model = self.devices[key].description.model
+            self.model = getattr(self.devices[key].description, "model", "Bluetooth device")
             self.name = self.devices[key].description.name
 
             await self.async_set_unique_id(

Failure during pairing

This was with a Nanoleaf Essentials Light strip.

Device rejects our pairing attempt by closing the connection:

2022-07-14 21:23:34.351 DEBUG (MainThread) [aiohomekit.protocol.tlv] sending [
  6: (1 bytes/<class 'bytearray'>) 0x01
  3: (32 bytes/<class 'bytes'>) b'\xf8\xe2|\xc0\x81~\xfb\xdaU.mW\x86\x12\xb3\x084\xf3?\xdd\x8e<\x92\xc3\x00\x88\xfd\x04\x97V\x81\x0b'
]

2022-07-14 21:23:34.351 DEBUG (MainThread) [aiohomekit.controller.ble.client] Using fragment size: 101
2022-07-14 21:23:34.351 DEBUG (MainThread) [aiohomekit.controller.ble.client] Writing fragment: b'\x00\x02\xf2#\x00*\x00\t\x01\x01\x01%\x06\x01\x01\x03 \xf8\xe2|\xc0\x81~\xfb\xdaU.mW\x86\x12\xb3\x084\xf3?\xdd\x8e<\x92\xc3\x00\x88\xfd\x04\x97V\x81\x0b'
2022-07-14 21:23:35.350 DEBUG (MainThread) [aiohomekit.controller.ble.pairing] Session closed
2022-07-14 21:23:35.351 ERROR (MainThread) [homeassistant.components.homekit_controller.config_flow] Pairing attempt failed with an unhandled exception
Traceback (most recent call last):
  File "/Users/john/Projects/home-assistant/homeassistant/components/homekit_controller/config_flow.py", line 371, in async_step_pair
    return await self._entry_from_accessory(pairing)
  File "/Users/john/Projects/home-assistant/homeassistant/components/homekit_controller/config_flow.py", line 484, in _entry_from_accessory
    accessories = await pairing.list_accessories_and_characteristics()
  File "/Users/john/Projects/home-assistant/venv/lib/python3.9/site-packages/aiohomekit/controller/ble/pairing.py", line 283, in list_accessories_and_characteristics
    await self._ensure_connected()
  File "/Users/john/Projects/home-assistant/venv/lib/python3.9/site-packages/aiohomekit/controller/ble/pairing.py", line 174, in _ensure_connected
    await self._async_pair_verify()
  File "/Users/john/Projects/home-assistant/venv/lib/python3.9/site-packages/aiohomekit/controller/ble/pairing.py", line 204, in _async_pair_verify
    session_id, derive = await drive_pairing_state_machine(
  File "/Users/john/Projects/home-assistant/venv/lib/python3.9/site-packages/aiohomekit/controller/ble/client.py", line 147, in drive_pairing_state_machine
    response = await char_write(
  File "/Users/john/Projects/home-assistant/venv/lib/python3.9/site-packages/aiohomekit/controller/ble/client.py", line 114, in char_write
    data = await ble_request(
  File "/Users/john/Projects/home-assistant/venv/lib/python3.9/site-packages/aiohomekit/controller/ble/client.py", line 84, in ble_request
    data = await client.read_gatt_char(handle)
  File "/Users/john/Projects/home-assistant/venv/lib/python3.9/site-packages/bleak/backends/corebluetooth/client.py", line 261, in read_gatt_char
    output = await self._delegate.read_characteristic(
  File "/Users/john/Projects/home-assistant/venv/lib/python3.9/site-packages/bleak/backends/corebluetooth/PeripheralDelegate.py", line 144, in read_characteristic
    return await asyncio.wait_for(future, timeout=5)
  File "/usr/local/Cellar/[email protected]/3.9.13_1/Frameworks/Python.framework/Versions/3.9/lib/python3.9/asyncio/tasks.py", line 479, in wait_for
    return fut.result()
bleak.exc.BleakError: disconnected

If we a device roams between bluetooth adapters we need to clear the services cache

2022-08-17 18:41:44.899 ERROR (MainThread) [homeassistant.components.websocket_api.http.connection] [281472599046320] [org.bluez.Error.Failed] Not connected
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/components/websocket_api/commands.py", line 199, in handle_call_service
    await hass.services.async_call(
  File "/usr/src/homeassistant/homeassistant/core.py", line 1717, in async_call
    task.result()
  File "/usr/src/homeassistant/homeassistant/core.py", line 1754, in _execute_service
    await cast(Callable[[ServiceCall], Awaitable[None]], handler.job.target)(
  File "/usr/src/homeassistant/homeassistant/helpers/entity_component.py", line 204, in handle_service
    await service.entity_service_call(
  File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 676, in entity_service_call
    future.result()  # pop exception if have
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 931, in async_request_call
    await coro
  File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 713, in _handle_entity_call
    await result
  File "/usr/src/homeassistant/homeassistant/components/homekit_controller/switch.py", line 81, in async_turn_off
    await self.async_put_characteristics({CharacteristicsTypes.ON: False})
  File "/usr/src/homeassistant/homeassistant/components/homekit_controller/entity.py", line 91, in async_put_characteristics
    return await self._accessory.put_characteristics(payload)
  File "/usr/src/homeassistant/homeassistant/components/homekit_controller/connection.py", line 633, in put_characteristics
    results = await self.pairing.put_characteristics(characteristics)
  File "/usr/local/lib/python3.10/site-packages/aiohomekit/controller/ble/pairing.py", line 103, in _async_wrap
    return await func(self, *args, **kwargs)
  File "/usr/local/lib/python3.10/site-packages/aiohomekit/controller/ble/client.py", line 66, in _async_wrap
    return await func(*args, **kwargs)
  File "/usr/local/lib/python3.10/site-packages/aiohomekit/controller/ble/pairing.py", line 776, in put_characteristics
    await self._populate_accessories_and_characteristics()
  File "/usr/local/lib/python3.10/site-packages/aiohomekit/controller/ble/pairing.py", line 618, in _populate_accessories_and_characteristics
    await self._async_pair_verify()
  File "/usr/local/lib/python3.10/site-packages/aiohomekit/controller/ble/pairing.py", line 393, 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 289, in drive_pairing_state_machine
    iid = await client.get_characteristic_iid(char)
  File "/usr/local/lib/python3.10/site-packages/aiohomekit/controller/ble/bleak.py", line 58, in get_characteristic_iid
    value = bytes(await self.read_gatt_descriptor(iid_handle.handle))
  File "/usr/local/lib/python3.10/site-packages/bleak/backends/bluezdbus/client.py", line 609, in read_gatt_descriptor
    assert_reply(reply)
  File "/usr/local/lib/python3.10/site-packages/bleak/backends/bluezdbus/utils.py", line 22, in assert_reply
    raise BleakDBusError(reply.error_name, reply.body)
bleak.exc.BleakDBusError: [org.bluez.Error.Failed] Not connected

Use an existing library for HTTP/1.1 header parsing

One of the issues fixed in #9 could have easily be prevented by not employing a roll-your-own HTTP header parsing library. While the custom framing requirements making using a full-blown HTTP client undesirable, at the HTTP parsing/generation could be delegated to a common library maintained by “somebody else” and h11 seems like the perfect tool for this job as it (I know at least one “serious” HTTP library that uses it).

Allow controller to spawn background tasks

  • BLE should be able to monitor advertisements for c# changes (to trigger refresh of characteristic map)
  • BLE should be able to monitor advertisements for s# changes (to trigger disconnected notifications)
  • BLE should be able to run discovery in background (for discovery to be as slick as in Home Assistant)
  • IP should be able to run discovery in background (without neccesarily relying on zeroconf integration) (TBD)
  • IP should be able to detect c# changes (to trigger refresh of characteristic map without tight coupling to config entries)

Ultimately this means that there won't be seperate discover_ip and discover_ble callables, there will be a discovered property that the background tasks populate and callbacks to add/remove discovered devices.

Not able to connect to device after successfully pairing

Was able to connect to device from CLI with the result Pairing for "air" was established.
I've might misunderstood, but shouldn't I be able to interact with the device after pairing was established? Or do I need to handle some kind of session/permanent connection?
Since python3 -m aiohomekit list-pairings -a "air" results in Timeout while waiting for connection to device, the wifi icon started blinking again (waiting for connection) and the device won't show in Apple HomeKit, it looks like it entered some kind of zombie state.

Had some problems keeping this smart device connected to HomeAssistant permanently, so I wanted to try it "manually" from the source. Any tips on how to get additional logs from the post pairing process?

Xiaomi motion sensor periodically triggers motion

I have couple Xiaomi motion sensors that are linked to the Aqara M2 hub which I exposed to HA via Homekit Controller component.

But I noticed that the Xiaomi motion sensor periodically triggers motion even though there's no motion at all:
image

Motions logs are shown correctly in the Aqara app. So I think this is some kind of periodic health checks that are being treated as motion in HK controller.

Also note that this only happens to Xiaomi motion sensors (original V1 Mi sensor), Aqara motion sensors (V2) are working fine.

I've turned on following loggers for debugging but I don't see anything useful:

  aiohomekit: debug
  homeassistant.components.homekit_controller: debug

Is there any other loggers that I can turn on to see what's going on?

Issue with pairing with Heatmiser Neohub

Hi,
I have a Heatmiser Neohub (https://www.heatmiser.com/en/neohub-smart-control/) that is supposed to be homekit compatible. I have however struggled to get it paired with Home assistant lately (I did an update of home assistant from a very old version where it used to work) and after some debugging I found what seems to be an issue with very rigid code on the Neohub side. I contacted Heatmiser telling them that this looks like a bug on their side, but they refuse to do anything since they manage to pair with iOS devices, which apparently are tolerant against these issues.

With this change I manage to pair with the Neohub (this diff is against fcfbf87 which is an old version of the library):

index 646942e..e991f9b 100644
--- a/aiohomekit/controller/ip/connection.py
+++ b/aiohomekit/controller/ip/connection.py
@@ -256,7 +256,7 @@ class HomeKitConnection:
         return await self.request(
             method="PUT",
             target=target,
-            headers=[("Content-Type", content_type), ("Content-Length", len(body))],
+            headers=[("Content-Length", len(body)),("Content-Type", content_type)],
             body=body,
         )
 
@@ -296,7 +296,7 @@ class HomeKitConnection:
         return await self.request(
             method="POST",
             target=target,
-            headers=[("Content-Type", content_type), ("Content-Length", len(body))],
+            headers=[("Content-Length", len(body)),("Content-Type", content_type)],
             body=body,
         )
 
diff --git a/aiohomekit/protocol/__init__.py b/aiohomekit/protocol/__init__.py
index 8cc2f7d..b9ae776 100644
--- a/aiohomekit/protocol/__init__.py
+++ b/aiohomekit/protocol/__init__.py
@@ -197,6 +197,9 @@ def perform_pair_setup_part2(
 
     # M4 Verification (page 43)
     response_tlv = TLV.reorder(response_tlv, step4_expectations)
+    if len(response_tlv) == 1:
+        response_tlv.insert(0, [TLV.kTLVType_State, TLV.M4])
+
     assert (
         response_tlv[0][0] == TLV.kTLVType_State and response_tlv[0][1] == TLV.M4
     ), "perform_pair_setup: State not M4"

This indicates they are depending on a specific order of the headers in a PUT request, and don't provide a proper M4 response according to the spec, but seems like iOS devices somehow don't care about this.

I am wondering if it would be possible to get these changes into the aiohomekit as arguing with support people at Heatmiser seems futile? And being the pragmatist that I am - this might be the path of least resistance.

Regards
Ronny

Does CoAP support Pair-Resume like BLE?

The BLE version of HAP supports a variant of Pair-Verify where it can resume a previous session. Pair-Resume bypasses ECC calculations so it is significantly faster at setting up a secure session for low power BLE devices.

I've implemented this for BLE in #69.

Given the cross-over between HAP BLE devices and HAP Thread devices I am wondering whether these devices support Pair-Resume over CoAP as well.

CC @roysjosh

Calls to `zeroconf.get_service_info` need to be wrapped with try/except for `zeroconf.BadTypeInNameException` or `zeroconf.Error`

I'm working on fixing this for Home Assistant's browser when I noticed aiohomekit is affected as well

2020-08-13 18:33:40 ERROR (zeroconf-ServiceBrowser__hap._tcp.local._1206) [root] Uncaught thread exception
Traceback (most recent call last):
  File "/usr/local/lib/python3.8/threading.py", line 932, in _bootstrap_inner
    self.run()
  File "/usr/local/lib/python3.8/site-packages/zeroconf/__init__.py", line 1680, in run
    self._service_state_changed.fire(
  File "/usr/local/lib/python3.8/site-packages/zeroconf/__init__.py", line 1438, in fire
    h(**kwargs)
  File "/usr/local/lib/python3.8/site-packages/zeroconf/__init__.py", line 1536, in on_change
    listener.add_service(*args)
  File "/usr/local/lib/python3.8/site-packages/aiohomekit/zeroconf/__init__.py", line 59, in add_service
    info = zeroconf.get_service_info(zeroconf_type, name)
  File "/usr/local/lib/python3.8/site-packages/zeroconf/__init__.py", line 2371, in get_service_info
    info = ServiceInfo(type_, name)
  File "/usr/local/lib/python3.8/site-packages/zeroconf/__init__.py", line 1732, in __init__
    if not type_.endswith(service_type_name(name, allow_underscores=True)):
  File "/usr/local/lib/python3.8/site-packages/zeroconf/__init__.py", line 268, in service_type_name
    raise BadTypeInNameException("Type '%s' must end with '._tcp.local.' or '._udp.local.'" % type_)
zeroconf.BadTypeInNameException: Type 'crash.local.' must end with '._tcp.local.' or '._udp.local.'

Migrate to cryptography > 3

cryptography 3.x was release a while ago. It would be nice if aiohomekit is migrated to cryptography to allow the installation along other modules in the same venv.

Fedora's development release already ships cryptography 3.x.

Make use of PEP-593 for tlv8 serializing?

https://www.python.org/dev/peps/pep-0593/

Requires python 3.9+ which is what we are currently targetting.

Example from the PEP is:

UnsignedShort = Annotated[int, struct2.ctype('H')]
SignedChar = Annotated[int, struct2.ctype('b')]

class Student(struct2.Packed):
    # mypy typechecks 'name' field as 'str'
    name: Annotated[str, struct2.ctype("<10s")]
    serialnum: UnsignedShort
    school: SignedChar

# 'unpack' only uses the metadata within the type annotations
Student.unpack(record)
# Student(name=b'raymond   ', serialnum=4658, school=264)

https://github.com/alecthomas/injector has a PEP-593 mode that adds an Inject[int]. mypy just see's int.

BLE: splat during init, subscriptions

My Elements Border Router has died so I've been playing around with BLE. I edited config/.storage/core.config_entries to swap the transport from CoAP to BLE and got this splat soon after Pair-Verify:

2022-03-30 20:53:48 ERROR (MainThread) [homeassistant] Error doing job: Task exception was never retrieved
Traceback (most recent call last):
  File ".../aiohomekit/controller/ble/pairing.py", line 376, in subscribe
    await self._ensure_connected()
  File ".../aiohomekit/controller/ble/pairing.py", line 176, in _ensure_connected
    for (aid, iid) in self.subscriptions:
RuntimeError: Set changed size during iteration

CoAP Pair-Verify timeout

What do you think about the current CoAP pair-verify timeout of 8s? During startup, HA will try to connect 3x causing a 24s delay to HA startup if any HAP/CoAP device is unreachable. I don't have any battery-powered devices but I feel like 4s should be enough for just about anything to complete pair-verify.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.