From 0e01321bdfa104efe1f21331e2a4b0fca5af8daf Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 10 Dec 2023 07:59:41 -1000 Subject: [PATCH 01/18] Add support for happy eyeballs --- aiohomekit/controller/ip/connection.py | 88 ++++++++++++++++++-------- aiohomekit/controller/ip/discovery.py | 1 + aiohomekit/zeroconf.py | 3 + poetry.lock | 15 ++++- pyproject.toml | 1 + 5 files changed, 80 insertions(+), 28 deletions(-) diff --git a/aiohomekit/controller/ip/connection.py b/aiohomekit/controller/ip/connection.py index 6a230952..26d3bc82 100644 --- a/aiohomekit/controller/ip/connection.py +++ b/aiohomekit/controller/ip/connection.py @@ -15,6 +15,8 @@ # from __future__ import annotations +import socket +import aiohappyeyeballs import asyncio import logging from typing import TYPE_CHECKING, Any @@ -48,6 +50,22 @@ logger = logging.getLogger(__name__) +def _convert_hosts_to_addr_infos( + hosts: list[str], port: int +) -> list[aiohappyeyeballs.AddrInfoType]: + """Converts the list of hosts to a list of addr_infos. + The list of hosts is the result of a DNS lookup. The list of + addr_infos is the result of a call to `socket.getaddrinfo()`. + """ + addr_infos: list[aiohappyeyeballs.AddrInfoType] = [] + for host in hosts: + is_ipv6 = ":" in host + family = socket.AF_INET6 if is_ipv6 else socket.AF_INET + addr = (host, port, 0, 0) if is_ipv6 else (host, port) + addr_infos.append( + (family, socket.SOCK_STREAM, socket.IPPROTO_TCP, host, addr) + ) + return addr_infos class ConnectionReady(Exception): """Raised when a connection is ready to be retried.""" @@ -58,7 +76,6 @@ class InsecureHomeKitProtocol(asyncio.Protocol): def __init__(self, connection: HomeKitConnection) -> None: self.connection = connection - self.host = ":".join((connection.host, str(connection.port))) self.result_cbs: list[asyncio.Future[HttpResponse]] = [] self.current_response = HttpResponse() self.loop = asyncio.get_running_loop() @@ -218,10 +235,10 @@ def data_received(self, data: bytes) -> None: class HomeKitConnection: def __init__( - self, owner: IpPairing, host: str, port: int, concurrency_limit: int = 1 + self, owner: IpPairing, hosts: list[str], port: int, concurrency_limit: int = 1 ) -> None: self.owner = owner - self.host = host + self.hosts = hosts self.port = port self.closing: bool = False @@ -241,13 +258,14 @@ def __init__( self._concurrency_limit = asyncio.Semaphore(concurrency_limit) self._reconnect_future: asyncio.Future[None] | None = None self._last_connector_error: Exception | None = None + self.connected_host: str | None = None @property def name(self) -> str: """Return the name of the connection.""" if self.owner: return self.owner.name - return f"{self.host}:{self.port}" + return f"{self.connected_host or self.hosts}:{self.port}" @property def is_connected(self) -> bool: @@ -477,7 +495,7 @@ async def request( # WARNING: It is vital that a Host: header is present or some devices # will reject the request. - buffer.append(f"Host: {self.host}") + buffer.append(f"Host: {self.connected_host or self.hosts}:{self.port}") if headers: for header, value in headers: @@ -502,7 +520,7 @@ async def request( async with self._concurrency_limit: if not self.protocol: raise AccessoryDisconnectedError("Tried to send while not connected") - logger.debug("%s: raw request: %r", self.host, request_bytes) + logger.debug("%s: raw request: %r", self.connected_host, request_bytes) resp = await self.protocol.send_bytes(request_bytes) if resp.code >= 400 and resp.code <= 499: @@ -512,7 +530,7 @@ async def request( response=resp, ) - logger.debug("%s: raw response: %r", self.host, resp.body) + logger.debug("%s: raw response: %r", self.connected_host, resp.body) return resp @@ -546,24 +564,42 @@ def _connection_lost(self, exception: Exception) -> None: self.transport = None self.protocol = None + + async def _connect_once(self) -> None: """_connect_once must only ever be called from _reconnect to ensure its done with a lock.""" loop = asyncio.get_event_loop() - logger.debug("Attempting connection to %s:%s", self.host, self.port) + logger.debug("Attempting connection to %s:%s", self.hosts, self.port) - try: - async with asyncio_timeout(10): - self.transport, self.protocol = await loop.create_connection( - lambda: InsecureHomeKitProtocol(self), self.host, self.port - ) - - except asyncio.TimeoutError: - raise TimeoutError("Timeout") - - except OSError as e: - raise ConnectionError(str(e)) + addr_infos = _convert_hosts_to_addr_infos(self.hosts, self.port) + last_exception: Exception | None = None + sock: socket.socket | None = None + interleave = 1 + while addr_infos: + try: + async with asyncio_timeout(10): + sock = await aiohappyeyeballs.start_connection( + addr_infos, + happy_eyeballs_delay=0.25, + interleave=interleave, + loop=self._loop, + ) + break + except (OSError, asyncio.TimeoutError) as err: + last_exception = err + aiohappyeyeballs.pop_addr_infos_interleave(addr_infos, interleave) + + if sock is None: + if isinstance(last_exception, asyncio.TimeoutError): + raise TimeoutError("Timeout") from last_exception + raise ConnectionError(str(last_exception)) from last_exception + + self.transport, self.protocol = await loop.create_connection( + lambda: InsecureHomeKitProtocol(self), sock=sock + ) + self.connected_host = sock.getpeername()[0] if self.owner: await self.owner.connection_made(False) @@ -582,7 +618,7 @@ async def _reconnect(self) -> None: async with self._connect_lock: interval = 0.5 - logger.debug("Starting reconnect loop to %s:%s", self.host, self.port) + logger.debug("Starting reconnect loop to %s:%s", self.hosts, self.port) while not self.closing: self._last_connector_error = None @@ -638,7 +674,7 @@ def event_received(self, event: HttpResponse) -> None: self.owner.event_received(parsed) def __repr__(self) -> str: - return f"HomeKitConnection(host={self.host!r}, port={self.port!r})" + return f"HomeKitConnection(host={(self.connected_host or self.hosts)!r}, port={self.port!r})" class SecureHomeKitConnection(HomeKitConnection): @@ -647,7 +683,7 @@ class SecureHomeKitConnection(HomeKitConnection): def __init__(self, owner: IpPairing, pairing_data: dict[str, Any]) -> None: super().__init__( owner, - pairing_data["AccessoryIP"], + pairing_data.get("AccessoryIPs", [pairing_data["AccessoryIP"]]), pairing_data["AccessoryPort"], ) self.pairing_data = pairing_data @@ -663,14 +699,14 @@ async def _connect_once(self): if self.owner and self.owner.description: pairing = self.owner try: - if self.host != pairing.description.address: + if set(self.hosts) != set(pairing.description.addresses): logger.debug( "%s: Host changed from %s to %s", pairing.name, - self.host, + self.hosts, pairing.description.address, ) - self.host = pairing.description.address + self.hosts = pairing.description.addresses if self.port != pairing.description.port: logger.debug( @@ -714,7 +750,7 @@ async def _connect_once(self): self.is_secure = True - logger.debug("Secure connection to %s:%s established", self.host, self.port) + logger.debug("Secure connection to %s:%s established", self.connected_host, self.port) if self.owner: await self.owner.connection_made(True) diff --git a/aiohomekit/controller/ip/discovery.py b/aiohomekit/controller/ip/discovery.py index a9872127..f548c2c1 100644 --- a/aiohomekit/controller/ip/discovery.py +++ b/aiohomekit/controller/ip/discovery.py @@ -92,6 +92,7 @@ async def finish_pairing(pin: str) -> IpPairing: break pairing["AccessoryIP"] = self.description.address + pairing["AccessoryIPs"] = self.description.addresses pairing["AccessoryPort"] = self.description.port pairing["Connection"] = "IP" diff --git a/aiohomekit/zeroconf.py b/aiohomekit/zeroconf.py index 3f07ed70..214c88e1 100644 --- a/aiohomekit/zeroconf.py +++ b/aiohomekit/zeroconf.py @@ -158,6 +158,9 @@ def _update_from_discovery(self, description: HomeKitService): class ZeroconfPairing(AbstractPairing): + + description: HomeKitService + def _async_endpoint_changed(self) -> None: """The IP and/or port of the accessory has changed.""" pass diff --git a/poetry.lock b/poetry.lock index 126366c2..0299af05 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.7.1 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.6.1 and should not be changed by hand. [[package]] name = "aiocoap" @@ -30,6 +30,17 @@ files = [ {file = "aiofiles-23.2.1.tar.gz", hash = "sha256:84ec2218d8419404abcb9f0c02df3f34c6e0a68ed41072acfb1cef5cbc29051a"}, ] +[[package]] +name = "aiohappyeyeballs" +version = "2.0.0" +description = "Happy Eyeballs" +optional = false +python-versions = ">=3.8,<4.0" +files = [ + {file = "aiohappyeyeballs-2.0.0-py3-none-any.whl", hash = "sha256:7d2ad650ecc77f7a82b63aea8460b52ecf3760c5bcd79bebfb0ba2ccc0cc0ae7"}, + {file = "aiohappyeyeballs-2.0.0.tar.gz", hash = "sha256:017d118c6c6d1ea3a91f1129a234a4f663efdd159bb05c45ca9256bb583dc960"}, +] + [[package]] name = "aiohttp" version = "3.9.0" @@ -1657,4 +1668,4 @@ ifaddr = ">=0.1.7" [metadata] lock-version = "2.0" python-versions = "^3.10" -content-hash = "7e06a0207c6b1c9c83e846879b4ee694c8e725972c0a17e2db63a422e25f2673" +content-hash = "02ca9d97e9944114e083a0bc705735ae8634699de6f6b198267c12e620ebd1a4" diff --git a/pyproject.toml b/pyproject.toml index 0c0601f9..8f48fd19 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -31,6 +31,7 @@ orjson = ">=3.7.8" async-timeout = {version = ">=4.0.2", python = "<3.11"} chacha20poly1305 = "^0.0.3" async-interrupt = ">=1.1.1" +aiohappyeyeballs = ">=2.0.0" [tool.poetry.dev-dependencies] isort = "^5.10.1" From 54c56cff7e5703456b38dffb0f1f3a2f6e792aa1 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 10 Dec 2023 07:59:50 -1000 Subject: [PATCH 02/18] Add support for happy eyeballs --- aiohomekit/controller/ip/connection.py | 16 ++++++++-------- aiohomekit/zeroconf.py | 1 - 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/aiohomekit/controller/ip/connection.py b/aiohomekit/controller/ip/connection.py index 26d3bc82..7b4bca33 100644 --- a/aiohomekit/controller/ip/connection.py +++ b/aiohomekit/controller/ip/connection.py @@ -15,12 +15,12 @@ # from __future__ import annotations -import socket -import aiohappyeyeballs import asyncio import logging +import socket from typing import TYPE_CHECKING, Any +import aiohappyeyeballs from async_interrupt import interrupt from aiohomekit.crypto.chacha20poly1305 import ( @@ -50,6 +50,7 @@ logger = logging.getLogger(__name__) + def _convert_hosts_to_addr_infos( hosts: list[str], port: int ) -> list[aiohappyeyeballs.AddrInfoType]: @@ -62,11 +63,10 @@ def _convert_hosts_to_addr_infos( is_ipv6 = ":" in host family = socket.AF_INET6 if is_ipv6 else socket.AF_INET addr = (host, port, 0, 0) if is_ipv6 else (host, port) - addr_infos.append( - (family, socket.SOCK_STREAM, socket.IPPROTO_TCP, host, addr) - ) + addr_infos.append((family, socket.SOCK_STREAM, socket.IPPROTO_TCP, host, addr)) return addr_infos + class ConnectionReady(Exception): """Raised when a connection is ready to be retried.""" @@ -564,8 +564,6 @@ def _connection_lost(self, exception: Exception) -> None: self.transport = None self.protocol = None - - async def _connect_once(self) -> None: """_connect_once must only ever be called from _reconnect to ensure its done with a lock.""" loop = asyncio.get_event_loop() @@ -750,7 +748,9 @@ async def _connect_once(self): self.is_secure = True - logger.debug("Secure connection to %s:%s established", self.connected_host, self.port) + logger.debug( + "Secure connection to %s:%s established", self.connected_host, self.port + ) if self.owner: await self.owner.connection_made(True) diff --git a/aiohomekit/zeroconf.py b/aiohomekit/zeroconf.py index 214c88e1..d74ff823 100644 --- a/aiohomekit/zeroconf.py +++ b/aiohomekit/zeroconf.py @@ -158,7 +158,6 @@ def _update_from_discovery(self, description: HomeKitService): class ZeroconfPairing(AbstractPairing): - description: HomeKitService def _async_endpoint_changed(self) -> None: From b500efe3124a1a05522977af53ea19717e79a7eb Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 10 Dec 2023 08:06:55 -1000 Subject: [PATCH 03/18] limit addresses to valid --- aiohomekit/zeroconf.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/aiohomekit/zeroconf.py b/aiohomekit/zeroconf.py index d74ff823..c1373629 100644 --- a/aiohomekit/zeroconf.py +++ b/aiohomekit/zeroconf.py @@ -88,14 +88,16 @@ def from_service_info(cls, service: AsyncServiceInfo) -> HomeKitService: # This means the first address will always be the most recently added # address of the given IP version. # - for ip_addr in addresses: - if not ip_addr.is_link_local and not ip_addr.is_unspecified: - address = str(ip_addr) - break - if not address: + valid_addresses = [ + str(ip_addr) + for ip_addr in addresses + if not ip_addr.is_link_local and not ip_addr.is_unspecified + ] + if not valid_addresses: raise ValueError( "Invalid HomeKit Zeroconf record: Missing non-link-local or unspecified address" ) + address = valid_addresses[0] props: dict[str, str] = { k.decode("utf-8").lower(): v.decode("utf-8") @@ -118,7 +120,7 @@ def from_service_info(cls, service: AsyncServiceInfo) -> HomeKitService: protocol_version=props.get("pv", "1.0"), type=service.type, address=address, - addresses=[str(ip_addr) for ip_addr in addresses], + addresses=valid_addresses, port=service.port, ) From 114df73dc1c533a57dc6d282505a08f0e21331be Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 10 Dec 2023 08:10:26 -1000 Subject: [PATCH 04/18] fix tests --- aiohomekit/controller/ip/pairing.py | 6 ++++-- tests/test_zeroconf.py | 8 ++++---- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/aiohomekit/controller/ip/pairing.py b/aiohomekit/controller/ip/pairing.py index 69dd26e6..66b94bb2 100644 --- a/aiohomekit/controller/ip/pairing.py +++ b/aiohomekit/controller/ip/pairing.py @@ -112,9 +112,11 @@ def poll_interval(self) -> timedelta: @property def name(self) -> str: """Return the name of the pairing with the address.""" + connection = self.connection + host = connection.connected_host or connection.hosts if self.description: - return f"{self.description.name} [{self.connection.host}:{self.connection.port}] (id={self.id})" - return f"[{self.connection.host}:{self.connection.port}] (id={self.id})" + return f"{self.description.name} [{host}:{connection.port}] (id={self.id})" + return f"[{host}:{connection.port}] (id={self.id})" def event_received(self, event): self._callback_listeners(format_characteristic_list(event)) diff --git a/tests/test_zeroconf.py b/tests/test_zeroconf.py index 3fceaa95..d19ee5c1 100644 --- a/tests/test_zeroconf.py +++ b/tests/test_zeroconf.py @@ -311,7 +311,7 @@ def test_ignore_link_local(): assert svc.feature_flags == FeatureFlags.SUPPORTS_APPLE_AUTHENTICATION_COPROCESSOR assert svc.category == Categories.LIGHTBULB assert svc.address == "127.0.0.1" - assert svc.addresses == ["169.254.121.37", "127.0.0.1"] + assert svc.addresses == ["127.0.0.1"] assert svc.port == 1234 @@ -349,7 +349,7 @@ def test_ignore_link_local_ipv6(): assert svc.feature_flags == FeatureFlags.SUPPORTS_APPLE_AUTHENTICATION_COPROCESSOR assert svc.category == Categories.LIGHTBULB assert svc.address == "2a00:1450:4009:820::200e" - assert svc.addresses == ["169.254.121.37", "2a00:1450:4009:820::200e"] + assert svc.addresses == ["2a00:1450:4009:820::200e"] assert svc.port == 1234 @@ -422,7 +422,7 @@ def test_ignore_unspecified(): assert svc.feature_flags == FeatureFlags.SUPPORTS_APPLE_AUTHENTICATION_COPROCESSOR assert svc.category == Categories.LIGHTBULB assert svc.address == "127.0.0.1" - assert svc.addresses == ["0.0.0.0", "127.0.0.1"] + assert svc.addresses == ["127.0.0.1"] assert svc.port == 1234 @@ -460,5 +460,5 @@ def test_ignore_unspecified_ipv6(): assert svc.feature_flags == FeatureFlags.SUPPORTS_APPLE_AUTHENTICATION_COPROCESSOR assert svc.category == Categories.LIGHTBULB assert svc.address == "2a00:1450:4009:820::200e" - assert svc.addresses == ["0.0.0.0", "2a00:1450:4009:820::200e"] + assert svc.addresses == ["2a00:1450:4009:820::200e"] assert svc.port == 1234 From 6dca6811359d46bda7cf45ef31622274a68e5c60 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 10 Dec 2023 08:17:20 -1000 Subject: [PATCH 05/18] tweaks --- aiohomekit/zeroconf.py | 6 +++--- tests/test_zeroconf.py | 28 ++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/aiohomekit/zeroconf.py b/aiohomekit/zeroconf.py index c1373629..32ca3be0 100644 --- a/aiohomekit/zeroconf.py +++ b/aiohomekit/zeroconf.py @@ -129,13 +129,13 @@ class ZeroconfServiceListener(ServiceListener): """An empty service listener.""" def add_service(self, zc: Zeroconf, type_: str, name: str) -> None: - pass + """A service has been added.""" def remove_service(self, zc: Zeroconf, type_: str, name: str) -> None: - pass + """A service has been removed.""" def update_service(self, zc: Zeroconf, type_: str, name: str) -> None: - pass + """A service has been updated.""" def find_brower_for_hap_type(azc: AsyncZeroconf, hap_type: str) -> AsyncServiceBrowser: diff --git a/tests/test_zeroconf.py b/tests/test_zeroconf.py index d19ee5c1..250474a8 100644 --- a/tests/test_zeroconf.py +++ b/tests/test_zeroconf.py @@ -462,3 +462,31 @@ def test_ignore_unspecified_ipv6(): assert svc.address == "2a00:1450:4009:820::200e" assert svc.addresses == ["2a00:1450:4009:820::200e"] assert svc.port == 1234 + + +def test_no_valid_addresses(): + desc = { + b"c#": b"1", + b"id": b"00:00:01:00:00:02", + b"md": b"unittest", + b"s#": b"11", + b"ci": b"5", + b"sf": b"0", + b"ff": b"1", + } + info = AsyncServiceInfo( + "_hap._tcp.local.", + "foo2._hap._tcp.local.", + addresses=[ + socket.inet_aton("0.0.0.0"), + ], + port=1234, + properties=desc, + weight=0, + priority=0, + ) + with pytest.raises( + ValueError, + match="Invalid HomeKit Zeroconf record: Missing non-link-local or unspecified address", + ): + HomeKitService.from_service_info(info) From 19f8611eae02e5be070a3f471cbe878af45f5837 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 10 Dec 2023 11:14:24 -1000 Subject: [PATCH 06/18] add timeout to tests --- .github/workflows/ci.yml | 2 +- poetry.lock | 16 +++++++++++++++- pyproject.toml | 3 +++ 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 857bd3db..8ec7ecb0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -130,6 +130,6 @@ jobs: - name: Run pytest shell: bash - run: poetry run python -m pytest --cov=. --cov-report=xml + run: poetry run python -m pytest --cov=. --cov-report=xml --timeout=60 - uses: codecov/codecov-action@v3 diff --git a/poetry.lock b/poetry.lock index 0299af05..d9c028ca 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1352,6 +1352,20 @@ pytest = ">=4.6" [package.extras] testing = ["fields", "hunter", "process-tests", "pytest-xdist", "six", "virtualenv"] +[[package]] +name = "pytest-timeout" +version = "2.2.0" +description = "pytest plugin to abort hanging tests" +optional = false +python-versions = ">=3.7" +files = [ + {file = "pytest-timeout-2.2.0.tar.gz", hash = "sha256:3b0b95dabf3cb50bac9ef5ca912fa0cfc286526af17afc806824df20c2f72c90"}, + {file = "pytest_timeout-2.2.0-py3-none-any.whl", hash = "sha256:bde531e096466f49398a59f2dde76fa78429a09a12411466f88a07213e220de2"}, +] + +[package.dependencies] +pytest = ">=5.0.0" + [[package]] name = "pyupgrade" version = "2.38.4" @@ -1668,4 +1682,4 @@ ifaddr = ">=0.1.7" [metadata] lock-version = "2.0" python-versions = "^3.10" -content-hash = "02ca9d97e9944114e083a0bc705735ae8634699de6f6b198267c12e620ebd1a4" +content-hash = "5776ec92d8675e3f447f331cd1af5bad937b6f2f5744bb62086d7ba8d12fb8a8" diff --git a/pyproject.toml b/pyproject.toml index 8f48fd19..c22598ac 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -47,6 +47,9 @@ pytest-cov = "^3.0.0" asynctest = "^0.13.0" aiohttp = ">=3.8.3" +[tool.poetry.group.dev.dependencies] +pytest-timeout = "^2.2.0" + [tool.black] target-version = ["py39", "py310"] From fb48a7be895c85d2cecd6c6b0a006c8f92dd6e5d Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 10 Dec 2023 11:22:43 -1000 Subject: [PATCH 07/18] debug tests --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8ec7ecb0..422f2afb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -130,6 +130,6 @@ jobs: - name: Run pytest shell: bash - run: poetry run python -m pytest --cov=. --cov-report=xml --timeout=60 + run: poetry run python -m pytest -vvvs --cov=. --cov-report=xml --timeout=60 - uses: codecov/codecov-action@v3 From 2c9f85b32fda434a58f38664fe75d319cce0e981 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 10 Dec 2023 13:23:11 -1000 Subject: [PATCH 08/18] require fixed zeroconf --- poetry.lock | 55 ++++---------------------------------------------- pyproject.toml | 2 +- 2 files changed, 5 insertions(+), 52 deletions(-) diff --git a/poetry.lock b/poetry.lock index d9c028ca..32b5c5be 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1619,60 +1619,13 @@ multidict = ">=4.0" [[package]] name = "zeroconf" -version = "0.85.0" +version = "0.128.3" description = "A pure python implementation of multicast DNS service discovery" optional = false python-versions = ">=3.7,<4.0" files = [ - {file = "zeroconf-0.85.0-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:5cf6e51f049fe70940795a06d02eb2e771e253a79b27f53a6022d22066056591"}, - {file = "zeroconf-0.85.0-cp310-cp310-manylinux_2_17_i686.manylinux_2_5_i686.manylinux1_i686.manylinux2014_i686.whl", hash = "sha256:8e14e48be926ebe1e223d97cf1b88a49964c789765341c88e2f59cc5f102862c"}, - {file = "zeroconf-0.85.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3f8912c80cb52b074472a82240431b80a1bf402befe75d356f739543ee7ccd7c"}, - {file = "zeroconf-0.85.0-cp310-cp310-manylinux_2_31_x86_64.whl", hash = "sha256:4d2537a8675be464ce4a1b1c220923e05b471525a6d775fcf07df321f0aab864"}, - {file = "zeroconf-0.85.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:c018463fd6314ebb6b365c655b2407c1f49e95f875ad7d1ecf8a0b5bde996ad2"}, - {file = "zeroconf-0.85.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:5363c60ae0aa2dd87602efbd45a7a167dc5a3e2f8eaa987be98be576d24501c2"}, - {file = "zeroconf-0.85.0-cp310-cp310-win32.whl", hash = "sha256:f8c6a3c91692571bea35d3dba0d6e8d51da98eeb1e942df095a2a29c428f2eaa"}, - {file = "zeroconf-0.85.0-cp310-cp310-win_amd64.whl", hash = "sha256:5ec00c86e12aa38d9401328e92451c7ba35b88a0420abc7d5be4973f747a17df"}, - {file = "zeroconf-0.85.0-cp311-cp311-macosx_11_0_x86_64.whl", hash = "sha256:ea5db032c94521268c0c6f20a368eac3c779ace8c19f5aa20c73de92bac8d3f8"}, - {file = "zeroconf-0.85.0-cp311-cp311-manylinux_2_17_i686.manylinux_2_5_i686.manylinux1_i686.manylinux2014_i686.whl", hash = "sha256:49c79cab71e0a5e6bc4291538d0029ac59ceab92e401789036d30f131a1713b2"}, - {file = "zeroconf-0.85.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1ed85ca11f7a5d41823b931ae01a296f1ad2357958a4ba72842c366817157125"}, - {file = "zeroconf-0.85.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:15052dcb23f7f3352e8ff692fa78f4e94b6fdd015e8c33800156039c685d566d"}, - {file = "zeroconf-0.85.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:7a598aad2013759f6f08340629bea9dbc1a407f3855166d697764342a1394082"}, - {file = "zeroconf-0.85.0-cp311-cp311-win32.whl", hash = "sha256:c552537a555a507dbaf2ff596089fff638f784a96704f12bd7938cf55d1f5b07"}, - {file = "zeroconf-0.85.0-cp311-cp311-win_amd64.whl", hash = "sha256:66e6181fc2875b19f5b31b7e2cd14e1c2a3c201ebfb8c85015434827268ec934"}, - {file = "zeroconf-0.85.0-cp37-cp37m-macosx_11_0_x86_64.whl", hash = "sha256:0f3338b0dd8e4bc52606c5db93f78b9944309d0c9c9361ecb14c05838abaff2a"}, - {file = "zeroconf-0.85.0-cp37-cp37m-manylinux_2_17_i686.manylinux_2_5_i686.manylinux1_i686.manylinux2014_i686.whl", hash = "sha256:66564ce49a664f8b05344f36467474da380266d04a5840ab1835a61c5c88758d"}, - {file = "zeroconf-0.85.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7ecfc7d5de369a4152bc47e31db1670919c45ccf0f7498fb82ed8c831343b133"}, - {file = "zeroconf-0.85.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:f67c1902075d75b7bf428b32910229100e746d5cbc2e4cce32f1c925ae1c2d7b"}, - {file = "zeroconf-0.85.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:f90881f0ba2612956ac8f40bdb4308295c6056873044072055cf33d8090306dc"}, - {file = "zeroconf-0.85.0-cp37-cp37m-win32.whl", hash = "sha256:3739f18c3fe730711605016cad60ffef2316654de42bc9daaa144b6740197ff7"}, - {file = "zeroconf-0.85.0-cp37-cp37m-win_amd64.whl", hash = "sha256:dc6243ea7f87ad84e93fdcac764394b8a290da020a45473e76ce1ce9074ef54e"}, - {file = "zeroconf-0.85.0-cp38-cp38-macosx_11_0_x86_64.whl", hash = "sha256:39e5db8d2d9420bcd6dd603481bf22e69ccf0007f84970ec400cf20ffef7cf86"}, - {file = "zeroconf-0.85.0-cp38-cp38-manylinux_2_17_i686.manylinux_2_5_i686.manylinux1_i686.manylinux2014_i686.whl", hash = "sha256:ddd5732eff099e4979464373973c5599724b7aa91c4a544a7b952841a87a1513"}, - {file = "zeroconf-0.85.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18b37facd332f5c8b8ec50272a0f4edd96f46b531893b9fada175ab1daf4f6e3"}, - {file = "zeroconf-0.85.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:ef861bd542594a2bb99b8fb0d6769ccec0c138955da058aaecc45fde1e7a4a03"}, - {file = "zeroconf-0.85.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:666e429a2d34b0a2549a54fe1ff41be29b5f8972d92bc4a32e31a4bec768ffcb"}, - {file = "zeroconf-0.85.0-cp38-cp38-win32.whl", hash = "sha256:fb9f7109802932b54f53493911be941de69e5af4f1178618cd4a929582241644"}, - {file = "zeroconf-0.85.0-cp38-cp38-win_amd64.whl", hash = "sha256:632c07e8a6d66248e4f1041c61ab015cd9a38a0c1095302e3123493b2d8353a4"}, - {file = "zeroconf-0.85.0-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:0e6d54451cc5cfc83e59d56d8f115f0d779f1a1b4d95cf2fba2865d5477b7358"}, - {file = "zeroconf-0.85.0-cp39-cp39-manylinux_2_17_i686.manylinux_2_5_i686.manylinux1_i686.manylinux2014_i686.whl", hash = "sha256:6cd514a6e98c9d661770c4015de263a5d73f37c9351e143b3e3079a15b173e8b"}, - {file = "zeroconf-0.85.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:978ced0e587e95ab08215f81691b783f965e76c1c4c4779bcd7be25dba68cfd4"}, - {file = "zeroconf-0.85.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:cfe64cf9615cc85e08cd3ca354d051ce4f0ccf850ad9e516ad1c2d932a156173"}, - {file = "zeroconf-0.85.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c4d248d0aeab26729b26743e7dfb32b6a9a859757ad7a9362fa2c2bda1560bb1"}, - {file = "zeroconf-0.85.0-cp39-cp39-win32.whl", hash = "sha256:1c0c181d8ddf47fb9deb8422eba5fdb707eccc19444dd3f0427fe0fc0d079bb1"}, - {file = "zeroconf-0.85.0-cp39-cp39-win_amd64.whl", hash = "sha256:2701a112d236cf9889d0524ccb7f0227262e9f2bb30e6c4a485d2c56b55d889b"}, - {file = "zeroconf-0.85.0-pp37-pypy37_pp73-macosx_11_0_x86_64.whl", hash = "sha256:a5590e65e518c535e7f28f718a2dc633649248ae0ee086d02c6bec1662e314fa"}, - {file = "zeroconf-0.85.0-pp37-pypy37_pp73-manylinux_2_17_i686.manylinux_2_5_i686.manylinux1_i686.manylinux2014_i686.whl", hash = "sha256:4d86352f2aba8872fc1856bd7f49776424a099d32fd709f354ef74a58c5ebe08"}, - {file = "zeroconf-0.85.0-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d1150d7df2109d4783a703f21371aad7e490ce8d6ac8f503d05a894185a602f"}, - {file = "zeroconf-0.85.0-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:ad357a85da7abcd29df3ef0eb4a4b54b7c1f634a27ec90f44b0ae9695c8af561"}, - {file = "zeroconf-0.85.0-pp38-pypy38_pp73-macosx_11_0_x86_64.whl", hash = "sha256:6b8471fec89b842def43c1dc1c378df0da71727a74153aea7f554abf5acd20d7"}, - {file = "zeroconf-0.85.0-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux_2_5_i686.manylinux1_i686.manylinux2014_i686.whl", hash = "sha256:ebef751b56ce666f0c0d1916e5f2d55e36b76cf5726e8f3255bc89b5f12b8a93"}, - {file = "zeroconf-0.85.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba67321ace5de703fd36f516e4ebc717d356c4fcf53ba55c7383caa0ba3e8e78"}, - {file = "zeroconf-0.85.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:8d27ddcf52687fe8f5a4fc2ad189f69ee88a721d8302fbe47ef77f75de17ece6"}, - {file = "zeroconf-0.85.0-pp39-pypy39_pp73-macosx_11_0_x86_64.whl", hash = "sha256:fd34f1d452e49c5f20308a7d57cd836b4bf958309ef832a73bf709835faf02f5"}, - {file = "zeroconf-0.85.0-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux_2_5_i686.manylinux1_i686.manylinux2014_i686.whl", hash = "sha256:a40890a5d8fa9c72e93d8ada45b3eaa7298de1b37310ec0e35003f4f2e99c880"}, - {file = "zeroconf-0.85.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4adc04be2b8b5ed879e04dce160f48a3f089f98582520921ee5de2c7d1450bcf"}, - {file = "zeroconf-0.85.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:21efdd22a4cf6b1d4a2d9f1e28f5396fc9c18f22c38a724cfa83ee58a5377e4a"}, - {file = "zeroconf-0.85.0.tar.gz", hash = "sha256:abd71fc8d98c11b2c8c9edf679dcf2bdb554738b9814a31eb05dd9e8c0d66afd"}, + {file = "zeroconf-0.128.3-cp310-cp310-manylinux_2_31_x86_64.whl", hash = "sha256:f29de2b169e2978e3c03aa8f41b59875c334b92a89fa8d7cdf261396bcb890cd"}, + {file = "zeroconf-0.128.3.tar.gz", hash = "sha256:0eee9f729f9a3c66e8b458b20d32635c69765586e75f05ad2e9d2c420477e718"}, ] [package.dependencies] @@ -1682,4 +1635,4 @@ ifaddr = ">=0.1.7" [metadata] lock-version = "2.0" python-versions = "^3.10" -content-hash = "5776ec92d8675e3f447f331cd1af5bad937b6f2f5744bb62086d7ba8d12fb8a8" +content-hash = "e032934ebe3f8da7339024cfe09370382249afbc763dc5b76d90f6392ac595b6" diff --git a/pyproject.toml b/pyproject.toml index c22598ac..8219a65c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,7 +21,7 @@ include = ["aiohomekit/py.typed"] [tool.poetry.dependencies] python = "^3.10" cryptography = ">=2.9.2" -zeroconf = ">=0.73.0" +zeroconf = ">=0.128.3" commentjson = "^0.9.0" aiocoap = ">=0.4.5" bleak = ">=0.19.0" From b9e769080baf376a68956bf0bb7e2d49de88b762 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 10 Dec 2023 13:47:55 -1000 Subject: [PATCH 09/18] bump zc --- poetry.lock | 8 ++++---- pyproject.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/poetry.lock b/poetry.lock index 32b5c5be..092d9363 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1619,13 +1619,13 @@ multidict = ">=4.0" [[package]] name = "zeroconf" -version = "0.128.3" +version = "0.128.4" description = "A pure python implementation of multicast DNS service discovery" optional = false python-versions = ">=3.7,<4.0" files = [ - {file = "zeroconf-0.128.3-cp310-cp310-manylinux_2_31_x86_64.whl", hash = "sha256:f29de2b169e2978e3c03aa8f41b59875c334b92a89fa8d7cdf261396bcb890cd"}, - {file = "zeroconf-0.128.3.tar.gz", hash = "sha256:0eee9f729f9a3c66e8b458b20d32635c69765586e75f05ad2e9d2c420477e718"}, + {file = "zeroconf-0.128.4-cp310-cp310-manylinux_2_31_x86_64.whl", hash = "sha256:d930fd774baeb161f9262f45f50df058ad47675a7943452fa2e45ba4e4b033fd"}, + {file = "zeroconf-0.128.4.tar.gz", hash = "sha256:57590a48e36897a04ea4b1a41ba6bbf833637b99ac6fa9530a2f70783d916c39"}, ] [package.dependencies] @@ -1635,4 +1635,4 @@ ifaddr = ">=0.1.7" [metadata] lock-version = "2.0" python-versions = "^3.10" -content-hash = "e032934ebe3f8da7339024cfe09370382249afbc763dc5b76d90f6392ac595b6" +content-hash = "5af59e5cdbe5c5e018b51c43afd5ff5c3b7c73ff082fa5187fe4b9488f921800" diff --git a/pyproject.toml b/pyproject.toml index 8219a65c..e6da0793 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,7 +21,7 @@ include = ["aiohomekit/py.typed"] [tool.poetry.dependencies] python = "^3.10" cryptography = ">=2.9.2" -zeroconf = ">=0.128.3" +zeroconf = ">=0.128.4" commentjson = "^0.9.0" aiocoap = ">=0.4.5" bleak = ">=0.19.0" From 0877870e15b3739f470d8875cafb8060db898885 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 10 Dec 2023 13:55:47 -1000 Subject: [PATCH 10/18] fix addresses --- aiohomekit/controller/ip/discovery.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aiohomekit/controller/ip/discovery.py b/aiohomekit/controller/ip/discovery.py index f548c2c1..7adeac95 100644 --- a/aiohomekit/controller/ip/discovery.py +++ b/aiohomekit/controller/ip/discovery.py @@ -36,7 +36,7 @@ class IpDiscovery(ZeroconfDiscovery): def __init__(self, controller, description: HomeKitService): super().__init__(description) self.controller = controller - self.connection = HomeKitConnection(None, description.address, description.port) + self.connection = HomeKitConnection(None, description.addresses, description.port) def __repr__(self): return f"IPDiscovery(host={self.description.address}, port={self.description.port})" From a885647e07a1f982d5ed0454a5cf951d59195d2b Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 10 Dec 2023 13:56:39 -1000 Subject: [PATCH 11/18] lint --- aiohomekit/controller/ip/discovery.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/aiohomekit/controller/ip/discovery.py b/aiohomekit/controller/ip/discovery.py index 7adeac95..32799b6a 100644 --- a/aiohomekit/controller/ip/discovery.py +++ b/aiohomekit/controller/ip/discovery.py @@ -36,7 +36,9 @@ class IpDiscovery(ZeroconfDiscovery): def __init__(self, controller, description: HomeKitService): super().__init__(description) self.controller = controller - self.connection = HomeKitConnection(None, description.addresses, description.port) + self.connection = HomeKitConnection( + None, description.addresses, description.port + ) def __repr__(self): return f"IPDiscovery(host={self.description.address}, port={self.description.port})" From 11200ce14d02159901051230b99bebbff1f45a89 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 10 Dec 2023 14:01:08 -1000 Subject: [PATCH 12/18] remove debug --- .github/workflows/ci.yml | 2 +- poetry.lock | 16 +--------------- pyproject.toml | 3 --- 3 files changed, 2 insertions(+), 19 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 422f2afb..857bd3db 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -130,6 +130,6 @@ jobs: - name: Run pytest shell: bash - run: poetry run python -m pytest -vvvs --cov=. --cov-report=xml --timeout=60 + run: poetry run python -m pytest --cov=. --cov-report=xml - uses: codecov/codecov-action@v3 diff --git a/poetry.lock b/poetry.lock index 092d9363..60694285 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1352,20 +1352,6 @@ pytest = ">=4.6" [package.extras] testing = ["fields", "hunter", "process-tests", "pytest-xdist", "six", "virtualenv"] -[[package]] -name = "pytest-timeout" -version = "2.2.0" -description = "pytest plugin to abort hanging tests" -optional = false -python-versions = ">=3.7" -files = [ - {file = "pytest-timeout-2.2.0.tar.gz", hash = "sha256:3b0b95dabf3cb50bac9ef5ca912fa0cfc286526af17afc806824df20c2f72c90"}, - {file = "pytest_timeout-2.2.0-py3-none-any.whl", hash = "sha256:bde531e096466f49398a59f2dde76fa78429a09a12411466f88a07213e220de2"}, -] - -[package.dependencies] -pytest = ">=5.0.0" - [[package]] name = "pyupgrade" version = "2.38.4" @@ -1635,4 +1621,4 @@ ifaddr = ">=0.1.7" [metadata] lock-version = "2.0" python-versions = "^3.10" -content-hash = "5af59e5cdbe5c5e018b51c43afd5ff5c3b7c73ff082fa5187fe4b9488f921800" +content-hash = "ac9d8d993418a84dccf616112ab57ea4c5b8a320e9e62ac77338b8e6cf5ee1f4" diff --git a/pyproject.toml b/pyproject.toml index e6da0793..ec6e31be 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -47,9 +47,6 @@ pytest-cov = "^3.0.0" asynctest = "^0.13.0" aiohttp = ">=3.8.3" -[tool.poetry.group.dev.dependencies] -pytest-timeout = "^2.2.0" - [tool.black] target-version = ["py39", "py310"] From 334144a006b2be883c04ff66fc626c79f67a7b5c Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 10 Dec 2023 18:25:53 -1000 Subject: [PATCH 13/18] bump --- poetry.lock | 8 ++++---- pyproject.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/poetry.lock b/poetry.lock index 60694285..073be06c 100644 --- a/poetry.lock +++ b/poetry.lock @@ -32,13 +32,13 @@ files = [ [[package]] name = "aiohappyeyeballs" -version = "2.0.0" +version = "2.1.0" description = "Happy Eyeballs" optional = false python-versions = ">=3.8,<4.0" files = [ - {file = "aiohappyeyeballs-2.0.0-py3-none-any.whl", hash = "sha256:7d2ad650ecc77f7a82b63aea8460b52ecf3760c5bcd79bebfb0ba2ccc0cc0ae7"}, - {file = "aiohappyeyeballs-2.0.0.tar.gz", hash = "sha256:017d118c6c6d1ea3a91f1129a234a4f663efdd159bb05c45ca9256bb583dc960"}, + {file = "aiohappyeyeballs-2.1.0-py3-none-any.whl", hash = "sha256:0cfb6957905f363ad97b5782d24e3b375d627d14a27c5f35144a40acc3d29c87"}, + {file = "aiohappyeyeballs-2.1.0.tar.gz", hash = "sha256:c488b0620296af00f0553b23239c28578f7139733dcce0a1771b91ed1f50c9b5"}, ] [[package]] @@ -1621,4 +1621,4 @@ ifaddr = ">=0.1.7" [metadata] lock-version = "2.0" python-versions = "^3.10" -content-hash = "ac9d8d993418a84dccf616112ab57ea4c5b8a320e9e62ac77338b8e6cf5ee1f4" +content-hash = "cf3634afe107c8964eccbd52f1338ef5254c57a3415878f6985f4f7b573e4b2b" diff --git a/pyproject.toml b/pyproject.toml index ec6e31be..a7ac2c67 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -31,7 +31,7 @@ orjson = ">=3.7.8" async-timeout = {version = ">=4.0.2", python = "<3.11"} chacha20poly1305 = "^0.0.3" async-interrupt = ">=1.1.1" -aiohappyeyeballs = ">=2.0.0" +aiohappyeyeballs = ">=2.1.0" [tool.poetry.dev-dependencies] isort = "^5.10.1" From 218dd7b70312c2bf6c1342cfc3c6e29bd03740e4 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 10 Dec 2023 20:35:20 -1000 Subject: [PATCH 14/18] bump again --- poetry.lock | 57 ++++++++++++++++++++++++++++++++++++++++++++++---- pyproject.toml | 2 +- 2 files changed, 54 insertions(+), 5 deletions(-) diff --git a/poetry.lock b/poetry.lock index 073be06c..5aff11a1 100644 --- a/poetry.lock +++ b/poetry.lock @@ -32,13 +32,13 @@ files = [ [[package]] name = "aiohappyeyeballs" -version = "2.1.0" +version = "2.2.0" description = "Happy Eyeballs" optional = false python-versions = ">=3.8,<4.0" files = [ - {file = "aiohappyeyeballs-2.1.0-py3-none-any.whl", hash = "sha256:0cfb6957905f363ad97b5782d24e3b375d627d14a27c5f35144a40acc3d29c87"}, - {file = "aiohappyeyeballs-2.1.0.tar.gz", hash = "sha256:c488b0620296af00f0553b23239c28578f7139733dcce0a1771b91ed1f50c9b5"}, + {file = "aiohappyeyeballs-2.2.0-py3-none-any.whl", hash = "sha256:13c71e0d73893aefccf72098c66b7726e30514b6e85cde0b1ddbd5e9f3b24be2"}, + {file = "aiohappyeyeballs-2.2.0.tar.gz", hash = "sha256:a24486e1d1310aa8f3cf02691d661a6164bed865365c38d482308d541273c0da"}, ] [[package]] @@ -1610,7 +1610,56 @@ description = "A pure python implementation of multicast DNS service discovery" optional = false python-versions = ">=3.7,<4.0" files = [ + {file = "zeroconf-0.128.4-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:f1fffb6b00d6831b93b579bc9f124bc39a1c4575be0bf61c49a7e997d298c2f4"}, + {file = "zeroconf-0.128.4-cp310-cp310-manylinux_2_17_i686.manylinux_2_5_i686.manylinux1_i686.manylinux2014_i686.whl", hash = "sha256:480f31fc1cd589126914e5ac33d7accfa58470846669b1f94f1450e391d0f672"}, + {file = "zeroconf-0.128.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:066031149969a81b475ed501e3ab9ff909963321dbcb7671e1801c05c70788e3"}, {file = "zeroconf-0.128.4-cp310-cp310-manylinux_2_31_x86_64.whl", hash = "sha256:d930fd774baeb161f9262f45f50df058ad47675a7943452fa2e45ba4e4b033fd"}, + {file = "zeroconf-0.128.4-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:f5fadebdbed4b829ae2606f1ce867190d0890fe2af98e26f95baecb4161256c5"}, + {file = "zeroconf-0.128.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:252a4c4fb617012c76595050de8cb25bc627f2f42f57ac487bebf22cef7ca982"}, + {file = "zeroconf-0.128.4-cp310-cp310-win32.whl", hash = "sha256:b4cadd044dad6e72362520802abc9d87cde9db28178fd5eeace0f92e23cbcb87"}, + {file = "zeroconf-0.128.4-cp310-cp310-win_amd64.whl", hash = "sha256:3beb96ec4b3f51cca6a8e1a690a7903434ad32fcae16a51ad12f48e9a171a5f7"}, + {file = "zeroconf-0.128.4-cp311-cp311-macosx_11_0_x86_64.whl", hash = "sha256:f20fdc3f9223f41f24dbb138cd53e459db3a5ebe395262cb40e09fe2491d6cc4"}, + {file = "zeroconf-0.128.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:600e49c6c7b791974c0708a5c9b38c49a2571fd94d4d7a0fcd2a4832d1344ffe"}, + {file = "zeroconf-0.128.4-cp311-cp311-manylinux_2_17_i686.manylinux_2_5_i686.manylinux1_i686.manylinux2014_i686.whl", hash = "sha256:8ac60af319c8735aecfe9f6efbe4edcfafa80756e1804746be3dea5af5ca4df8"}, + {file = "zeroconf-0.128.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bd44da66febce0bf9d19aab1f03ed2a0dc8637b3cedb59c03c71a7633e129dcd"}, + {file = "zeroconf-0.128.4-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:bffa09785dc0cbb935f67fb2c60e97c9f312a967a5408e6830694a83bdb8534c"}, + {file = "zeroconf-0.128.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3a82ff93cba9fd601a09e91ea3be176b17a166dafba576763d68f8fca4ee63cc"}, + {file = "zeroconf-0.128.4-cp311-cp311-win32.whl", hash = "sha256:368fb96014b8367a165ae24ec9f9046021362e8767a271e756b690babee83ae0"}, + {file = "zeroconf-0.128.4-cp311-cp311-win_amd64.whl", hash = "sha256:bd9b072d3fd44af07d59afc28d484764cdf5606a489f4f3a0f1b8d0ad9605ba0"}, + {file = "zeroconf-0.128.4-cp312-cp312-macosx_11_0_x86_64.whl", hash = "sha256:23e729ed1aaa061e2c2d829538fe45a3226353a9b6f770111d15c597c8f0fdd1"}, + {file = "zeroconf-0.128.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:337bd1c6fdaa625b3d000bd3971200a2cbe25e649571bbfc64122fc1fa5ccfaf"}, + {file = "zeroconf-0.128.4-cp312-cp312-manylinux_2_17_i686.manylinux_2_5_i686.manylinux1_i686.manylinux2014_i686.whl", hash = "sha256:73b7a805e4ed954f1fd230b7593bb64bf61c39df3aa5de93ce5596370321d830"}, + {file = "zeroconf-0.128.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0992038690ac29ead8cc1875e3edb19b9270a525141d34696c876f5bd5ce3d41"}, + {file = "zeroconf-0.128.4-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:f04ab023e487d60680a40b998db61828e93308256d9be0cdace55f0671933a37"}, + {file = "zeroconf-0.128.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:72e4cf3ec30d2b32663b94e99cf2b46060f8a6ebbec118fe27288c827d466b4d"}, + {file = "zeroconf-0.128.4-cp312-cp312-win32.whl", hash = "sha256:365d1c5d19e1181b0739138c7625c9fd7d249ba6c2c3090523c12d9ef95e0806"}, + {file = "zeroconf-0.128.4-cp312-cp312-win_amd64.whl", hash = "sha256:0085fecdac1a9df930d10bad87312f85d2f2dccc5b3e4d729e67eb9a37b70e5b"}, + {file = "zeroconf-0.128.4-cp38-cp38-macosx_11_0_x86_64.whl", hash = "sha256:345e25e79403f6f631fc301b273ca8ea074bacb984e927f5078c67b31701e9d1"}, + {file = "zeroconf-0.128.4-cp38-cp38-manylinux_2_17_i686.manylinux_2_5_i686.manylinux1_i686.manylinux2014_i686.whl", hash = "sha256:c1ef0839e491800c145712aebd528785ce22ce93c662e031006526bc1544758f"}, + {file = "zeroconf-0.128.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe95b6d0f75df16bcaacf367cfd9282a592abfa01a13f78f2986a059f2ee8a84"}, + {file = "zeroconf-0.128.4-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:d1c4980d661b08bcc5fa7c01db20821ab8d2752c22e3371ece99f7ac2f2e32d2"}, + {file = "zeroconf-0.128.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8a5f6e2f53c21a66bd178223173e11e81fa3f4b46971c88e42b3140810f51d87"}, + {file = "zeroconf-0.128.4-cp38-cp38-win32.whl", hash = "sha256:4416549413d3528565690103ad8e9c5f0b43f1c85acb38bb10b6dcf7b49f86fe"}, + {file = "zeroconf-0.128.4-cp38-cp38-win_amd64.whl", hash = "sha256:0db3118508165b629eee19dfddc56f339674d1b42ab478a79f1e98abd2dc9742"}, + {file = "zeroconf-0.128.4-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:8bc72a3ebfa28483e87f42f97870e9cf9f4431f1300c8edf6d94f5ef700a97a3"}, + {file = "zeroconf-0.128.4-cp39-cp39-manylinux_2_17_i686.manylinux_2_5_i686.manylinux1_i686.manylinux2014_i686.whl", hash = "sha256:07d948dea3940bea5c45e4f5c53f8ad24c94da4b76663586d263c2cd9a3fd8f4"}, + {file = "zeroconf-0.128.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a43dfb4b27eb1e582de1384c8d47c89d042c316c0a5e0b83e144ab8fed0b3809"}, + {file = "zeroconf-0.128.4-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:fccc01d2371e4a5329cd5fa63dffc525d089d37518f7c71cde2237bb897c46b8"}, + {file = "zeroconf-0.128.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:4764d890fb0c7797979965576e2d500e4ae04b1dfc2ec74a8073bd50f6283f9c"}, + {file = "zeroconf-0.128.4-cp39-cp39-win32.whl", hash = "sha256:d009905b24f359b68ab52ee36fe1b70b98aa2b894344a3b43def59e19487876e"}, + {file = "zeroconf-0.128.4-cp39-cp39-win_amd64.whl", hash = "sha256:f7ee28319c6875984288fb4a6b1ffb1d7ae438abd5fb841634a7deda67ff2ca3"}, + {file = "zeroconf-0.128.4-pp310-pypy310_pp73-macosx_11_0_x86_64.whl", hash = "sha256:dda6f1919623d7e48529bacbe3f931d5470686885d42ae7badfec399f4fb656d"}, + {file = "zeroconf-0.128.4-pp310-pypy310_pp73-manylinux_2_17_i686.manylinux_2_5_i686.manylinux1_i686.manylinux2014_i686.whl", hash = "sha256:f78b705cf0411572062a48da1f352fff20d2df63d0fefcc67e138c04425126c8"}, + {file = "zeroconf-0.128.4-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:63048a02935aa36cebf21a5b69b4544402056ac31856033e47a6e3ee823623f2"}, + {file = "zeroconf-0.128.4-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:1c2bd5e0861d4bf5aa3205258f928adb7c40bff9722fbc4af96a6e9a7aa0fe3d"}, + {file = "zeroconf-0.128.4-pp38-pypy38_pp73-macosx_11_0_x86_64.whl", hash = "sha256:da60073f3873fb1b726504c3b61f94b5692312a2c96f92129b186d7b8d67466c"}, + {file = "zeroconf-0.128.4-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux_2_5_i686.manylinux1_i686.manylinux2014_i686.whl", hash = "sha256:3d08d910981db566a1a86bf290ae9eeb482cd5666d6e535f237f1a5a46bbdbc3"}, + {file = "zeroconf-0.128.4-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c46174ee7592c5c08efce3d96d013751d913482af914200b0459dfa087cd57a3"}, + {file = "zeroconf-0.128.4-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:a04df8e47f1acbbcb1aee7e62e2229ba4b32bbd5d22fcdfabb2d26ac0d350837"}, + {file = "zeroconf-0.128.4-pp39-pypy39_pp73-macosx_11_0_x86_64.whl", hash = "sha256:d4e5f5ad78979d9ac4015188bdc56de965e71d13ac26a2e9277c14c4269e71aa"}, + {file = "zeroconf-0.128.4-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux_2_5_i686.manylinux1_i686.manylinux2014_i686.whl", hash = "sha256:abef601bae969f2b76717aa33a9895f2e70e402e464fd6ef73432d8a2b6a6966"}, + {file = "zeroconf-0.128.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:030cb93b9913ad7a66d132c8b419a13b9b73dcb78c6d6508948fbade18e2b18d"}, + {file = "zeroconf-0.128.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:b5923ba60c84f3ccefe7ec74ca08f28c46a5c26ab0010962ab293a778e181054"}, {file = "zeroconf-0.128.4.tar.gz", hash = "sha256:57590a48e36897a04ea4b1a41ba6bbf833637b99ac6fa9530a2f70783d916c39"}, ] @@ -1621,4 +1670,4 @@ ifaddr = ">=0.1.7" [metadata] lock-version = "2.0" python-versions = "^3.10" -content-hash = "cf3634afe107c8964eccbd52f1338ef5254c57a3415878f6985f4f7b573e4b2b" +content-hash = "e8c998b39d678bd1d9b25074311459015eca0790705a4d98be7be38502576006" diff --git a/pyproject.toml b/pyproject.toml index a7ac2c67..818fe13f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -31,7 +31,7 @@ orjson = ">=3.7.8" async-timeout = {version = ">=4.0.2", python = "<3.11"} chacha20poly1305 = "^0.0.3" async-interrupt = ">=1.1.1" -aiohappyeyeballs = ">=2.1.0" +aiohappyeyeballs = ">=2.2.0" [tool.poetry.dev-dependencies] isort = "^5.10.1" From 3193fdad7fc2eb99216b9d465ebc2cadee591f9b Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Mon, 11 Dec 2023 08:38:06 -1000 Subject: [PATCH 15/18] [] host header, pregen --- aiohomekit/controller/ip/connection.py | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/aiohomekit/controller/ip/connection.py b/aiohomekit/controller/ip/connection.py index 7b4bca33..82332901 100644 --- a/aiohomekit/controller/ip/connection.py +++ b/aiohomekit/controller/ip/connection.py @@ -259,6 +259,7 @@ def __init__( self._reconnect_future: asyncio.Future[None] | None = None self._last_connector_error: Exception | None = None self.connected_host: str | None = None + self.host_header: str | None = None @property def name(self) -> str: @@ -490,12 +491,13 @@ async def request( "Connection lost before request could be sent" ) - buffer = [] - buffer.append(f"{method.upper()} {target} HTTP/1.1") # WARNING: It is vital that a Host: header is present or some devices # will reject the request. - buffer.append(f"Host: {self.connected_host or self.hosts}:{self.port}") + buffer = [ + f"{method.upper()} {target} HTTP/1.1", + self.host_header + ] if headers: for header, value in headers: @@ -597,7 +599,12 @@ async def _connect_once(self) -> None: self.transport, self.protocol = await loop.create_connection( lambda: InsecureHomeKitProtocol(self), sock=sock ) - self.connected_host = sock.getpeername()[0] + connected_host = sock.getpeername()[0] + self.connected_host = connected_host + if ":" in connected_host: + self.host_header = f"Host: [{connected_host}]:{self.port}" + else: + self.host_header = f"Host: {connected_host}:{self.port}" if self.owner: await self.owner.connection_made(False) From 4cd18ba85766db68a03ebe78225ef8118c47e4f6 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Mon, 11 Dec 2023 08:38:13 -1000 Subject: [PATCH 16/18] lint --- aiohomekit/controller/ip/connection.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/aiohomekit/controller/ip/connection.py b/aiohomekit/controller/ip/connection.py index 82332901..28ab3af7 100644 --- a/aiohomekit/controller/ip/connection.py +++ b/aiohomekit/controller/ip/connection.py @@ -491,13 +491,9 @@ async def request( "Connection lost before request could be sent" ) - # WARNING: It is vital that a Host: header is present or some devices # will reject the request. - buffer = [ - f"{method.upper()} {target} HTTP/1.1", - self.host_header - ] + buffer = [f"{method.upper()} {target} HTTP/1.1", self.host_header] if headers: for header, value in headers: From 166aeb549e245079456bf2bdb847168b97d64f4c Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Mon, 11 Dec 2023 08:39:07 -1000 Subject: [PATCH 17/18] should be addresses --- aiohomekit/controller/ip/connection.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aiohomekit/controller/ip/connection.py b/aiohomekit/controller/ip/connection.py index 28ab3af7..e643c215 100644 --- a/aiohomekit/controller/ip/connection.py +++ b/aiohomekit/controller/ip/connection.py @@ -705,7 +705,7 @@ async def _connect_once(self): "%s: Host changed from %s to %s", pairing.name, self.hosts, - pairing.description.address, + pairing.description.addresses, ) self.hosts = pairing.description.addresses From c674500a04bd0603874f5770c9c8a53f3c3cd90b Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Mon, 11 Dec 2023 20:10:00 -1000 Subject: [PATCH 18/18] bump --- poetry.lock | 8 ++++---- pyproject.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/poetry.lock b/poetry.lock index 5aff11a1..9b52513c 100644 --- a/poetry.lock +++ b/poetry.lock @@ -32,13 +32,13 @@ files = [ [[package]] name = "aiohappyeyeballs" -version = "2.2.0" +version = "2.3.0" description = "Happy Eyeballs" optional = false python-versions = ">=3.8,<4.0" files = [ - {file = "aiohappyeyeballs-2.2.0-py3-none-any.whl", hash = "sha256:13c71e0d73893aefccf72098c66b7726e30514b6e85cde0b1ddbd5e9f3b24be2"}, - {file = "aiohappyeyeballs-2.2.0.tar.gz", hash = "sha256:a24486e1d1310aa8f3cf02691d661a6164bed865365c38d482308d541273c0da"}, + {file = "aiohappyeyeballs-2.3.0-py3-none-any.whl", hash = "sha256:90e8844cd69cdffbeab33a252ede73557abff3811c7db2863bd8da014b1b8e04"}, + {file = "aiohappyeyeballs-2.3.0.tar.gz", hash = "sha256:d6c05ff76c1269f6854362d252de3789cce87b53f6a7b958c87369b583a5d498"}, ] [[package]] @@ -1670,4 +1670,4 @@ ifaddr = ">=0.1.7" [metadata] lock-version = "2.0" python-versions = "^3.10" -content-hash = "e8c998b39d678bd1d9b25074311459015eca0790705a4d98be7be38502576006" +content-hash = "80b72c6c8a3961c6c5107ccdb29caeb9fedfc4afb1ca78fd9b02b4dfb10deb40" diff --git a/pyproject.toml b/pyproject.toml index 818fe13f..0079b2ba 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -31,7 +31,7 @@ orjson = ">=3.7.8" async-timeout = {version = ">=4.0.2", python = "<3.11"} chacha20poly1305 = "^0.0.3" async-interrupt = ">=1.1.1" -aiohappyeyeballs = ">=2.2.0" +aiohappyeyeballs = ">=2.3.0" [tool.poetry.dev-dependencies] isort = "^5.10.1"