Update async_upnp_client to 0.29.0 (#70604)

pull/70703/head
J. Nick Koston 2022-04-25 06:53:35 -10:00 committed by GitHub
parent f6d9c75476
commit 5224cf5968
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 36 additions and 38 deletions

View File

@ -3,7 +3,7 @@
"name": "DLNA Digital Media Renderer",
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/dlna_dmr",
"requirements": ["async-upnp-client==0.28.0"],
"requirements": ["async-upnp-client==0.29.0"],
"dependencies": ["ssdp"],
"after_dependencies": ["media_source"],
"ssdp": [

View File

@ -3,7 +3,7 @@
"name": "DLNA Digital Media Server",
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/dlna_dms",
"requirements": ["async-upnp-client==0.28.0"],
"requirements": ["async-upnp-client==0.29.0"],
"dependencies": ["ssdp"],
"after_dependencies": ["media_source"],
"ssdp": [

View File

@ -7,7 +7,7 @@
"samsungctl[websocket]==0.7.1",
"samsungtvws[async,encrypted]==2.5.0",
"wakeonlan==2.0.1",
"async-upnp-client==0.28.0"
"async-upnp-client==0.29.0"
],
"ssdp": [
{

View File

@ -11,12 +11,7 @@ import logging
from typing import Any
from async_upnp_client.aiohttp import AiohttpSessionRequester
from async_upnp_client.const import (
AddressTupleVXType,
DeviceOrServiceType,
SsdpHeaders,
SsdpSource,
)
from async_upnp_client.const import AddressTupleVXType, DeviceOrServiceType, SsdpSource
from async_upnp_client.description_cache import DescriptionCache
from async_upnp_client.ssdp import SSDP_PORT, determine_source_target, is_ipv4_address
from async_upnp_client.ssdp_listener import SsdpDevice, SsdpDeviceTracker, SsdpListener
@ -246,13 +241,13 @@ async def _async_process_callbacks(
@core_callback
def _async_headers_match(
headers: Mapping[str, Any], match_dict: dict[str, str]
headers: CaseInsensitiveDict, lower_match_dict: dict[str, str]
) -> bool:
for header, val in match_dict.items():
for header, val in lower_match_dict.items():
if val == MATCH_ALL:
if header not in headers:
return False
elif headers.get(header) != val:
elif headers.get_lower(header) != val:
return False
return True
@ -328,7 +323,7 @@ class Scanner:
@property
def _all_headers_from_ssdp_devices(
self,
) -> dict[tuple[str, str], Mapping[str, Any]]:
) -> dict[tuple[str, str], CaseInsensitiveDict]:
return {
(ssdp_device.udn, dst): headers
for ssdp_device in self._ssdp_devices
@ -340,19 +335,21 @@ class Scanner:
) -> Callable[[], None]:
"""Register a callback."""
if match_dict is None:
match_dict = {}
lower_match_dict = {}
else:
lower_match_dict = {k.lower(): v for k, v in match_dict.items()}
# Make sure any entries that happened
# before the callback was registered are fired
for headers in self._all_headers_from_ssdp_devices.values():
if _async_headers_match(headers, match_dict):
if _async_headers_match(headers, lower_match_dict):
await _async_process_callbacks(
[callback],
await self._async_headers_to_discovery_info(headers),
SsdpChange.ALIVE,
)
callback_entry = (callback, match_dict)
callback_entry = (callback, lower_match_dict)
self._callbacks.append(callback_entry)
@core_callback
@ -461,13 +458,13 @@ class Scanner:
@core_callback
def _async_get_matching_callbacks(
self,
combined_headers: SsdpHeaders,
combined_headers: CaseInsensitiveDict,
) -> list[SsdpCallback]:
"""Return a list of callbacks that match."""
return [
callback
for callback, match_dict in self._callbacks
if _async_headers_match(combined_headers, match_dict)
for callback, lower_match_dict in self._callbacks
if _async_headers_match(combined_headers, lower_match_dict)
]
async def _ssdp_listener_callback(
@ -490,9 +487,8 @@ class Scanner:
# If there are no changes from a search, do not trigger a config flow
if source != SsdpSource.SEARCH_ALIVE:
info_desc = await self._async_get_description_dict(location) or {}
assert isinstance(combined_headers, CaseInsensitiveDict)
matching_domains = self.integration_matchers.async_matching_domains(
CaseInsensitiveDict({**combined_headers.as_dict(), **info_desc})
CaseInsensitiveDict(combined_headers.as_dict(), **info_desc)
)
if not callbacks and not matching_domains:
@ -530,7 +526,7 @@ class Scanner:
return await self._description_cache.async_get_description_dict(location) or {}
async def _async_headers_to_discovery_info(
self, headers: Mapping[str, Any]
self, headers: CaseInsensitiveDict
) -> SsdpServiceInfo:
"""Combine the headers and description into discovery_info.
@ -571,7 +567,7 @@ class Scanner:
def discovery_info_from_headers_and_description(
combined_headers: Mapping[str, Any],
combined_headers: CaseInsensitiveDict,
info_desc: Mapping[str, Any],
) -> SsdpServiceInfo:
"""Convert headers and description to discovery_info."""

View File

@ -2,7 +2,7 @@
"domain": "ssdp",
"name": "Simple Service Discovery Protocol (SSDP)",
"documentation": "https://www.home-assistant.io/integrations/ssdp",
"requirements": ["async-upnp-client==0.28.0"],
"requirements": ["async-upnp-client==0.29.0"],
"dependencies": ["network"],
"after_dependencies": ["zeroconf"],
"codeowners": [],

View File

@ -3,7 +3,7 @@
"name": "UPnP/IGD",
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/upnp",
"requirements": ["async-upnp-client==0.28.0", "getmac==0.8.2"],
"requirements": ["async-upnp-client==0.29.0", "getmac==0.8.2"],
"dependencies": ["network", "ssdp"],
"codeowners": ["@StevenLooman", "@ehendrix23"],
"ssdp": [

View File

@ -2,7 +2,7 @@
"domain": "yeelight",
"name": "Yeelight",
"documentation": "https://www.home-assistant.io/integrations/yeelight",
"requirements": ["yeelight==0.7.10", "async-upnp-client==0.28.0"],
"requirements": ["yeelight==0.7.10", "async-upnp-client==0.29.0"],
"codeowners": ["@zewelor", "@shenxn", "@starkillerOG", "@alexyao2015"],
"config_flow": true,
"dependencies": ["network"],

View File

@ -9,7 +9,8 @@ from ipaddress import IPv4Address
import logging
from urllib.parse import urlparse
from async_upnp_client.search import SsdpHeaders, SsdpSearchListener
from async_upnp_client.search import SsdpSearchListener
from async_upnp_client.utils import CaseInsensitiveDict
from homeassistant import config_entries
from homeassistant.components import network, ssdp
@ -46,8 +47,8 @@ class YeelightScanner:
"""Initialize class."""
self._hass = hass
self._host_discovered_events: dict[str, list[asyncio.Event]] = {}
self._unique_id_capabilities: dict[str, SsdpHeaders] = {}
self._host_capabilities: dict[str, SsdpHeaders] = {}
self._unique_id_capabilities: dict[str, CaseInsensitiveDict] = {}
self._host_capabilities: dict[str, CaseInsensitiveDict] = {}
self._track_interval: CALLBACK_TYPE | None = None
self._listeners: list[SsdpSearchListener] = []
self._connected_events: list[asyncio.Event] = []
@ -123,7 +124,7 @@ class YeelightScanner:
if isinstance(source_ip, IPv4Address) and not source_ip.is_loopback
}
async def async_discover(self) -> ValuesView[SsdpHeaders]:
async def async_discover(self) -> ValuesView[CaseInsensitiveDict]:
"""Discover bulbs."""
_LOGGER.debug("Yeelight discover with interval %s", DISCOVERY_SEARCH_INTERVAL)
await self.async_setup()
@ -139,7 +140,7 @@ class YeelightScanner:
for listener in self._listeners:
listener.async_search()
async def async_get_capabilities(self, host: str) -> SsdpHeaders | None:
async def async_get_capabilities(self, host: str) -> CaseInsensitiveDict | None:
"""Get capabilities via SSDP."""
if host in self._host_capabilities:
return self._host_capabilities[host]
@ -157,7 +158,7 @@ class YeelightScanner:
self._host_discovered_events[host].remove(host_event)
return self._host_capabilities.get(host)
def _async_discovered_by_ssdp(self, response: SsdpHeaders) -> None:
def _async_discovered_by_ssdp(self, response: CaseInsensitiveDict) -> None:
@callback
def _async_start_flow(*_) -> None:
asyncio.create_task(
@ -177,7 +178,7 @@ class YeelightScanner:
# of another discovery
async_call_later(self._hass, 1, _async_start_flow)
async def _async_process_entry(self, headers: SsdpHeaders) -> None:
async def _async_process_entry(self, headers: CaseInsensitiveDict) -> None:
"""Process a discovery."""
_LOGGER.debug("Discovered via SSDP: %s", headers)
unique_id = headers["id"]

View File

@ -4,7 +4,7 @@ aiodiscover==1.4.11
aiohttp==3.8.1
aiohttp_cors==0.7.0
astral==2.2
async-upnp-client==0.28.0
async-upnp-client==0.29.0
async_timeout==4.0.2
atomicwrites==1.4.0
attrs==21.2.0

View File

@ -333,7 +333,7 @@ asterisk_mbox==0.5.0
# homeassistant.components.ssdp
# homeassistant.components.upnp
# homeassistant.components.yeelight
async-upnp-client==0.28.0
async-upnp-client==0.29.0
# homeassistant.components.supla
asyncpysupla==0.0.5

View File

@ -269,7 +269,7 @@ arcam-fmj==0.12.0
# homeassistant.components.ssdp
# homeassistant.components.upnp
# homeassistant.components.yeelight
async-upnp-client==0.28.0
async-upnp-client==0.29.0
# homeassistant.components.sleepiq
asyncsleepiq==1.2.3

View File

@ -4,10 +4,11 @@ from datetime import timedelta
from unittest.mock import AsyncMock, MagicMock, patch
from async_upnp_client.search import SsdpSearchListener
from async_upnp_client.utils import CaseInsensitiveDict
from yeelight import BulbException, BulbType
from yeelight.main import _MODEL_SPECS
from homeassistant.components import ssdp, zeroconf
from homeassistant.components import zeroconf
from homeassistant.components.yeelight import (
CONF_MODE_MUSIC,
CONF_NIGHTLIGHT_SWITCH_TYPE,
@ -157,7 +158,7 @@ def _mocked_bulb(cannot_connect=False):
return bulb
def _patched_ssdp_listener(info: ssdp.SsdpHeaders, *args, **kwargs):
def _patched_ssdp_listener(info: CaseInsensitiveDict, *args, **kwargs):
listener = SsdpSearchListener(*args, **kwargs)
async def _async_callback(*_):