Fix SSDP/UPnP server after testing (#80815)

This commit is contained in:
Steven Looman 2022-10-24 22:19:19 +02:00 committed by GitHub
parent ac4645a37e
commit b5f70a404a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 24 additions and 14 deletions

View File

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

View File

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

View File

@ -7,7 +7,7 @@
"samsungctl[websocket]==0.7.1", "samsungctl[websocket]==0.7.1",
"samsungtvws[async,encrypted]==2.5.0", "samsungtvws[async,encrypted]==2.5.0",
"wakeonlan==2.1.0", "wakeonlan==2.1.0",
"async-upnp-client==0.32.0" "async-upnp-client==0.32.1"
], ],
"ssdp": [ "ssdp": [
{ {

View File

@ -9,6 +9,7 @@ from enum import Enum
from ipaddress import IPv4Address, IPv6Address from ipaddress import IPv4Address, IPv6Address
import logging import logging
import socket import socket
from time import time
from typing import Any from typing import Any
from urllib.parse import urljoin from urllib.parse import urljoin
import xml.etree.ElementTree as ET import xml.etree.ElementTree as ET
@ -29,7 +30,12 @@ from async_upnp_client.server import (
UpnpServerDevice, UpnpServerDevice,
UpnpServerService, UpnpServerService,
) )
from async_upnp_client.ssdp import SSDP_PORT, determine_source_target, is_ipv4_address from async_upnp_client.ssdp import (
SSDP_PORT,
determine_source_target,
fix_ipv6_address_scope_id,
is_ipv4_address,
)
from async_upnp_client.ssdp_listener import SsdpDevice, SsdpDeviceTracker, SsdpListener from async_upnp_client.ssdp_listener import SsdpDevice, SsdpDeviceTracker, SsdpListener
from async_upnp_client.utils import CaseInsensitiveDict from async_upnp_client.utils import CaseInsensitiveDict
@ -213,8 +219,8 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
UPNP_SERVER: server, UPNP_SERVER: server,
} }
hass.create_task(scanner.async_start()) await scanner.async_start()
hass.create_task(server.async_start()) await server.async_start()
return True return True
@ -415,6 +421,7 @@ class Scanner:
else: else:
source_tuple = (source_ip_str, 0) source_tuple = (source_ip_str, 0)
source, target = determine_source_target(source_tuple) source, target = determine_source_target(source_tuple)
source = fix_ipv6_address_scope_id(source) or source
self._ssdp_listeners.append( self._ssdp_listeners.append(
SsdpListener( SsdpListener(
async_callback=self._ssdp_listener_callback, async_callback=self._ssdp_listener_callback,
@ -710,6 +717,7 @@ class Server:
) )
# Start a server on all source IPs. # Start a server on all source IPs.
boot_id = int(time())
for source_ip in await async_build_source_set(self.hass): for source_ip in await async_build_source_set(self.hass):
source_ip_str = str(source_ip) source_ip_str = str(source_ip)
if source_ip.version == 6: if source_ip.version == 6:
@ -722,6 +730,7 @@ class Server:
else: else:
source_tuple = (source_ip_str, 0) source_tuple = (source_ip_str, 0)
source, target = determine_source_target(source_tuple) source, target = determine_source_target(source_tuple)
source = fix_ipv6_address_scope_id(source) or source
http_port = await _async_find_next_available_port(source) http_port = await _async_find_next_available_port(source)
_LOGGER.debug("Binding UPnP HTTP server to: %s:%s", source_ip, http_port) _LOGGER.debug("Binding UPnP HTTP server to: %s:%s", source_ip, http_port)
self._upnp_servers.append( self._upnp_servers.append(
@ -730,6 +739,7 @@ class Server:
target=target, target=target,
http_port=http_port, http_port=http_port,
server_device=HassUpnpServiceDevice, server_device=HassUpnpServiceDevice,
boot_id=boot_id,
options={ options={
SSDP_SEARCH_RESPONDER_OPTIONS: { SSDP_SEARCH_RESPONDER_OPTIONS: {
SSDP_SEARCH_RESPONDER_OPTION_ALWAYS_REPLY_WITH_ROOT_DEVICE: True SSDP_SEARCH_RESPONDER_OPTION_ALWAYS_REPLY_WITH_ROOT_DEVICE: True

View File

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

View File

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

View File

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

View File

@ -4,7 +4,7 @@ aiodiscover==1.4.13
aiohttp==3.8.1 aiohttp==3.8.1
aiohttp_cors==0.7.0 aiohttp_cors==0.7.0
astral==2.2 astral==2.2
async-upnp-client==0.32.0 async-upnp-client==0.32.1
async_timeout==4.0.2 async_timeout==4.0.2
atomicwrites-homeassistant==1.4.1 atomicwrites-homeassistant==1.4.1
attrs==21.2.0 attrs==21.2.0

View File

@ -353,7 +353,7 @@ asterisk_mbox==0.5.0
# homeassistant.components.ssdp # homeassistant.components.ssdp
# homeassistant.components.upnp # homeassistant.components.upnp
# homeassistant.components.yeelight # homeassistant.components.yeelight
async-upnp-client==0.32.0 async-upnp-client==0.32.1
# homeassistant.components.supla # homeassistant.components.supla
asyncpysupla==0.0.5 asyncpysupla==0.0.5

View File

@ -307,7 +307,7 @@ arcam-fmj==0.12.0
# homeassistant.components.ssdp # homeassistant.components.ssdp
# homeassistant.components.upnp # homeassistant.components.upnp
# homeassistant.components.yeelight # homeassistant.components.yeelight
async-upnp-client==0.32.0 async-upnp-client==0.32.1
# homeassistant.components.sleepiq # homeassistant.components.sleepiq
asyncsleepiq==1.2.3 asyncsleepiq==1.2.3

View File

@ -671,7 +671,7 @@ async def test_async_detect_interfaces_setting_empty_route(
ssdp_listeners = hass.data[ssdp.DOMAIN][ssdp.SSDP_SCANNER]._ssdp_listeners ssdp_listeners = hass.data[ssdp.DOMAIN][ssdp.SSDP_SCANNER]._ssdp_listeners
sources = {ssdp_listener.source for ssdp_listener in ssdp_listeners} sources = {ssdp_listener.source for ssdp_listener in ssdp_listeners}
assert sources == {("2001:db8::%1", 0, 0, 1), ("192.168.1.5", 0)} assert sources == {("2001:db8::", 0, 0, 1), ("192.168.1.5", 0)}
@pytest.mark.usefixtures("mock_get_source_ip") @pytest.mark.usefixtures("mock_get_source_ip")
@ -695,7 +695,7 @@ async def test_bind_failure_skips_adapter(
"""Test that an adapter with a bind failure is skipped.""" """Test that an adapter with a bind failure is skipped."""
async def _async_start(self): async def _async_start(self):
if self.source == ("2001:db8::%1", 0, 0, 1): if self.source == ("2001:db8::", 0, 0, 1):
raise OSError raise OSError
SsdpListener.async_start = _async_start SsdpListener.async_start = _async_start