mirror of
https://github.com/home-assistant/core.git
synced 2025-07-17 18:27:09 +00:00
Send ssdp requests to ipv4 broadcast as well (#52760)
* Send ssdp requests to 255.255.255.255 as well - This matches pysonos behavior and may fix reports of inability to discover some sonos devices https://github.com/amelchio/pysonos/blob/master/pysonos/discovery.py#L120 * Update homeassistant/components/ssdp/__init__.py
This commit is contained in:
parent
0f076610fd
commit
574cb03acc
@ -29,6 +29,8 @@ from .flow import FlowDispatcher, SSDPFlow
|
|||||||
DOMAIN = "ssdp"
|
DOMAIN = "ssdp"
|
||||||
SCAN_INTERVAL = timedelta(seconds=60)
|
SCAN_INTERVAL = timedelta(seconds=60)
|
||||||
|
|
||||||
|
IPV4_BROADCAST = IPv4Address("255.255.255.255")
|
||||||
|
|
||||||
# Attributes for accessing info from SSDP response
|
# Attributes for accessing info from SSDP response
|
||||||
ATTR_SSDP_LOCATION = "ssdp_location"
|
ATTR_SSDP_LOCATION = "ssdp_location"
|
||||||
ATTR_SSDP_ST = "ssdp_st"
|
ATTR_SSDP_ST = "ssdp_st"
|
||||||
@ -236,7 +238,20 @@ class Scanner:
|
|||||||
async_callback=self._async_process_entry, source_ip=source_ip
|
async_callback=self._async_process_entry, source_ip=source_ip
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
try:
|
||||||
|
IPv4Address(source_ip)
|
||||||
|
except ValueError:
|
||||||
|
continue
|
||||||
|
# Some sonos devices only seem to respond if we send to the broadcast
|
||||||
|
# address. This matches pysonos' behavior
|
||||||
|
# https://github.com/amelchio/pysonos/blob/d4329b4abb657d106394ae69357805269708c996/pysonos/discovery.py#L120
|
||||||
|
self._ssdp_listeners.append(
|
||||||
|
SSDPListener(
|
||||||
|
async_callback=self._async_process_entry,
|
||||||
|
source_ip=source_ip,
|
||||||
|
target_ip=IPV4_BROADCAST,
|
||||||
|
)
|
||||||
|
)
|
||||||
self.hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP, self.async_stop)
|
self.hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP, self.async_stop)
|
||||||
self.hass.bus.async_listen_once(
|
self.hass.bus.async_listen_once(
|
||||||
EVENT_HOMEASSISTANT_STARTED, self.flow_dispatcher.async_start
|
EVENT_HOMEASSISTANT_STARTED, self.flow_dispatcher.async_start
|
||||||
|
@ -295,15 +295,15 @@ async def test_start_stop_scanner(async_start_mock, async_search_mock, hass):
|
|||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
async_fire_time_changed(hass, dt_util.utcnow() + timedelta(seconds=200))
|
async_fire_time_changed(hass, dt_util.utcnow() + timedelta(seconds=200))
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
assert async_start_mock.call_count == 1
|
assert async_start_mock.call_count == 2
|
||||||
assert async_search_mock.call_count == 1
|
assert async_search_mock.call_count == 2
|
||||||
|
|
||||||
hass.bus.async_fire(EVENT_HOMEASSISTANT_STOP)
|
hass.bus.async_fire(EVENT_HOMEASSISTANT_STOP)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
async_fire_time_changed(hass, dt_util.utcnow() + timedelta(seconds=200))
|
async_fire_time_changed(hass, dt_util.utcnow() + timedelta(seconds=200))
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
assert async_start_mock.call_count == 1
|
assert async_start_mock.call_count == 2
|
||||||
assert async_search_mock.call_count == 1
|
assert async_search_mock.call_count == 2
|
||||||
|
|
||||||
|
|
||||||
async def test_unexpected_exception_while_fetching(hass, aioclient_mock, caplog):
|
async def test_unexpected_exception_while_fetching(hass, aioclient_mock, caplog):
|
||||||
@ -459,11 +459,11 @@ async def test_scan_with_registered_callback(hass, aioclient_mock, caplog):
|
|||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
assert hass.state == CoreState.running
|
assert hass.state == CoreState.running
|
||||||
|
|
||||||
assert len(integration_callbacks) == 3
|
assert len(integration_callbacks) == 5
|
||||||
assert len(integration_callbacks_from_cache) == 3
|
assert len(integration_callbacks_from_cache) == 5
|
||||||
assert len(integration_match_all_callbacks) == 3
|
assert len(integration_match_all_callbacks) == 5
|
||||||
assert len(integration_match_all_not_present_callbacks) == 0
|
assert len(integration_match_all_not_present_callbacks) == 0
|
||||||
assert len(match_any_callbacks) == 3
|
assert len(match_any_callbacks) == 5
|
||||||
assert len(not_matching_integration_callbacks) == 0
|
assert len(not_matching_integration_callbacks) == 0
|
||||||
assert integration_callbacks[0] == {
|
assert integration_callbacks[0] == {
|
||||||
ssdp.ATTR_UPNP_DEVICE_TYPE: "Paulus",
|
ssdp.ATTR_UPNP_DEVICE_TYPE: "Paulus",
|
||||||
@ -546,7 +546,7 @@ async def test_unsolicited_ssdp_registered_callback(hass, aioclient_mock, caplog
|
|||||||
assert hass.state == CoreState.running
|
assert hass.state == CoreState.running
|
||||||
|
|
||||||
assert (
|
assert (
|
||||||
len(integration_callbacks) == 2
|
len(integration_callbacks) == 4
|
||||||
) # unsolicited callbacks without st are not cached
|
) # unsolicited callbacks without st are not cached
|
||||||
assert integration_callbacks[0] == {
|
assert integration_callbacks[0] == {
|
||||||
"UDN": "uuid:RINCON_1111BB963FD801400",
|
"UDN": "uuid:RINCON_1111BB963FD801400",
|
||||||
@ -635,7 +635,7 @@ async def test_scan_second_hit(hass, aioclient_mock, caplog):
|
|||||||
async_fire_time_changed(hass, dt_util.utcnow() + timedelta(seconds=200))
|
async_fire_time_changed(hass, dt_util.utcnow() + timedelta(seconds=200))
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
assert len(integration_callbacks) == 2
|
assert len(integration_callbacks) == 4
|
||||||
assert integration_callbacks[0] == {
|
assert integration_callbacks[0] == {
|
||||||
ssdp.ATTR_UPNP_DEVICE_TYPE: "Paulus",
|
ssdp.ATTR_UPNP_DEVICE_TYPE: "Paulus",
|
||||||
ssdp.ATTR_SSDP_EXT: "",
|
ssdp.ATTR_SSDP_EXT: "",
|
||||||
@ -781,7 +781,12 @@ async def test_async_detect_interfaces_setting_empty_route(hass):
|
|||||||
hass.bus.async_fire(EVENT_HOMEASSISTANT_STARTED)
|
hass.bus.async_fire(EVENT_HOMEASSISTANT_STARTED)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
assert {create_args[0][1]["source_ip"], create_args[1][1]["source_ip"]} == {
|
argset = set()
|
||||||
IPv4Address("192.168.1.5"),
|
for argmap in create_args:
|
||||||
IPv6Address("2001:db8::"),
|
argset.add((argmap[1].get("source_ip"), argmap[1].get("target_ip")))
|
||||||
|
|
||||||
|
assert argset == {
|
||||||
|
(IPv6Address("2001:db8::"), None),
|
||||||
|
(IPv4Address("192.168.1.5"), IPv4Address("255.255.255.255")),
|
||||||
|
(IPv4Address("192.168.1.5"), None),
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user