aioesphomeapi/aioesphomeapi/util.py

87 lines
2.0 KiB
Python
Raw Normal View History

2019-04-07 19:03:26 +02:00
import asyncio
import functools
2019-04-07 19:03:26 +02:00
import socket
from typing import Any, Optional, Tuple
import zeroconf
2019-04-07 19:03:26 +02:00
2020-07-14 20:00:12 +02:00
# pylint: disable=cyclic-import
2019-04-07 19:03:26 +02:00
from aioesphomeapi.core import APIConnectionError
def _varuint_to_bytes(value: int) -> bytes:
if value <= 0x7F:
return bytes([value])
ret = bytes()
while value:
temp = value & 0x7F
value >>= 7
if value:
ret += bytes([temp | 0x80])
else:
ret += bytes([temp])
return ret
def _bytes_to_varuint(value: bytes) -> Optional[int]:
result = 0
bitpos = 0
for val in value:
result |= (val & 0x7F) << bitpos
bitpos += 7
if (val & 0x80) == 0:
return result
return None
async def resolve_ip_address_getaddrinfo(
eventloop: asyncio.events.AbstractEventLoop, host: str, port: int
) -> Tuple[Any, ...]:
Avoid a jump to the executor to unpack an ip address string (#26) Avoids executor overload on Home Assistant startup 2021-02-13 18:31:38 DEBUG (MainThread) [homeassistant.runner] Calling executor with function: <function getaddrinfo at 0x7f00184c8ca0>, args: ('10.45.211.201', 6053, <AddressFamily.AF_INET: 2>, 0, 6, 0), kwargs: {} 2021-02-13 18:31:51 DEBUG (MainThread) [homeassistant.runner] Calling executor with function: <function getaddrinfo at 0x7f00184c8ca0>, args: ('10.45.210.102', 6053, <AddressFamily.AF_INET: 2>, 0, 6, 0), kwargs: {} 2021-02-13 18:31:51 DEBUG (MainThread) [homeassistant.runner] Calling executor with function: <function getaddrinfo at 0x7f00184c8ca0>, args: ('10.45.211.180', 6053, <AddressFamily.AF_INET: 2>, 0, 6, 0), kwargs: {} 2021-02-13 18:31:51 DEBUG (MainThread) [homeassistant.runner] Calling executor with function: <function getaddrinfo at 0x7f00184c8ca0>, args: ('10.45.210.100', 6053, <AddressFamily.AF_INET: 2>, 0, 6, 0), kwargs: {} 2021-02-13 18:31:51 DEBUG (MainThread) [homeassistant.runner] Calling executor with function: <function getaddrinfo at 0x7f00184c8ca0>, args: ('10.45.214.225', 6053, <AddressFamily.AF_INET: 2>, 0, 6, 0), kwargs: {} 2021-02-13 18:31:51 DEBUG (MainThread) [homeassistant.runner] Calling executor with function: <function getaddrinfo at 0x7f00184c8ca0>, args: ('10.45.213.240', 6053, <AddressFamily.AF_INET: 2>, 0, 6, 0), kwargs: {} 2021-02-13 18:31:51 DEBUG (MainThread) [homeassistant.runner] Calling executor with function: <function getaddrinfo at 0x7f00184c8ca0>, args: ('10.45.213.168', 6053, <AddressFamily.AF_INET: 2>, 0, 6, 0), kwargs: {} 2021-02-13 18:31:51 DEBUG (MainThread) [homeassistant.runner] Calling executor with function: <function getaddrinfo at 0x7f00184c8ca0>, args: ('10.45.210.29', 6053, <AddressFamily.AF_INET: 2>, 0, 6, 0), kwargs: {} 2021-02-13 18:31:51 DEBUG (MainThread) [homeassistant.runner] Calling executor with function: <function getaddrinfo at 0x7f00184c8ca0>, args: ('10.45.209.89', 6053, <AddressFamily.AF_INET: 2>, 0, 6, 0), kwargs: {} 2021-02-13 18:31:51 DEBUG (MainThread) [homeassistant.runner] Calling executor with function: <function getaddrinfo at 0x7f00184c8ca0>, args: ('10.45.209.250', 6053, <AddressFamily.AF_INET: 2>, 0, 6, 0), kwargs: {} 2021-02-13 18:31:51 DEBUG (MainThread) [homeassistant.runner] Calling executor with function: <function getaddrinfo at 0x7f00184c8ca0>, args: ('10.45.214.56', 6053, <AddressFamily.AF_INET: 2>, 0, 6, 0), kwargs: {} 2021-02-13 18:31:51 DEBUG (MainThread) [homeassistant.runner] Calling executor with function: <function getaddrinfo at 0x7f00184c8ca0>, args: ('10.45.209.137', 6053, <AddressFamily.AF_INET: 2>, 0, 6, 0), kwargs: {} 2021-02-13 18:32:04 DEBUG (MainThread) [homeassistant.runner] Calling executor with function: <function getaddrinfo at 0x7f00184c8ca0>, args: ('10.45.209.89', 6053, <AddressFamily.AF_INET: 2>, 0, 6, 0), kwargs: {} 2021-02-13 18:32:14 DEBUG (MainThread) [homeassistant.runner] Calling executor with function: <function getaddrinfo at 0x7f00184c8ca0>, args: ('10.45.209.89', 6053, <AddressFamily.AF_INET: 2>, 0, 6, 0), kwargs: {} 2021-02-13 18:32:23 DEBUG (MainThread) [homeassistant.runner] Calling executor with function: <function getaddrinfo at 0x7f00184c8ca0>, args: ('10.45.209.89', 6053, <AddressFamily.AF_INET: 2>, 0, 6, 0), kwargs: {} 2021-02-13 18:32:58 DEBUG (MainThread) [homeassistant.runner] Calling executor with function: <function getaddrinfo at 0x7f00184c8ca0>, args: ('10.45.209.89', 6053, <AddressFamily.AF_INET: 2>, 0, 6, 0), kwargs: {} 2021-02-13 18:33:10 DEBUG (MainThread) [homeassistant.runner] Calling executor with function: <function getaddrinfo at 0x7f00184c8ca0>, args: ('10.45.209.89', 6053, <AddressFamily.AF_INET: 2>, 0, 6, 0), kwargs: {} 2021-02-13 18:33:19 DEBUG (MainThread) [homeassistant.runner] Calling executor with function: <function getaddrinfo at 0x7f00184c8ca0>, args: ('10.45.209.89', 6053, <AddressFamily.AF_INET: 2>, 0, 6, 0), kwargs: {}
2021-02-15 15:58:11 +01:00
try:
socket.inet_aton(host)
except OSError:
pass
else:
return (host, port)
2019-04-07 19:03:26 +02:00
try:
res = await eventloop.getaddrinfo(
host, port, family=socket.AF_INET, proto=socket.IPPROTO_TCP
)
2019-04-07 19:03:26 +02:00
except OSError as err:
raise APIConnectionError("Error resolving IP address: {}".format(err))
if not res:
raise APIConnectionError("Error resolving IP address: No matches!")
_, _, _, _, sockaddr = res[0]
return sockaddr
async def resolve_ip_address(
eventloop: asyncio.events.AbstractEventLoop,
host: str,
port: int,
zeroconf_instance: Optional[zeroconf.Zeroconf] = None,
) -> Tuple[Any, ...]:
if host.endswith(".local"):
from aioesphomeapi.host_resolver import resolve_host
2019-04-07 19:03:26 +02:00
try:
return (
await eventloop.run_in_executor(
None,
functools.partial(
resolve_host, host, zeroconf_instance=zeroconf_instance
),
),
port,
)
except APIConnectionError:
pass
return await resolve_ip_address_getaddrinfo(eventloop, host, port)