mirror of
https://github.com/home-assistant/core.git
synced 2025-07-23 21:27:38 +00:00
Add SSDP discovery to Nanoleaf (#56907)
This commit is contained in:
parent
73e58c8c62
commit
538773a14a
@ -92,25 +92,42 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
|
|||||||
) -> FlowResult:
|
) -> FlowResult:
|
||||||
"""Handle Nanoleaf Zeroconf discovery."""
|
"""Handle Nanoleaf Zeroconf discovery."""
|
||||||
_LOGGER.debug("Zeroconf discovered: %s", discovery_info)
|
_LOGGER.debug("Zeroconf discovered: %s", discovery_info)
|
||||||
return await self._async_discovery_handler(discovery_info)
|
return await self._async_homekit_zeroconf_discovery_handler(discovery_info)
|
||||||
|
|
||||||
async def async_step_homekit(self, discovery_info: DiscoveryInfoType) -> FlowResult:
|
async def async_step_homekit(self, discovery_info: DiscoveryInfoType) -> FlowResult:
|
||||||
"""Handle Nanoleaf Homekit discovery."""
|
"""Handle Nanoleaf Homekit discovery."""
|
||||||
_LOGGER.debug("Homekit discovered: %s", discovery_info)
|
_LOGGER.debug("Homekit discovered: %s", discovery_info)
|
||||||
return await self._async_discovery_handler(discovery_info)
|
return await self._async_homekit_zeroconf_discovery_handler(discovery_info)
|
||||||
|
|
||||||
async def _async_discovery_handler(
|
async def _async_homekit_zeroconf_discovery_handler(
|
||||||
self, discovery_info: DiscoveryInfoType
|
self, discovery_info: DiscoveryInfoType
|
||||||
|
) -> FlowResult:
|
||||||
|
"""Handle Nanoleaf Homekit and Zeroconf discovery."""
|
||||||
|
return await self._async_discovery_handler(
|
||||||
|
discovery_info["host"],
|
||||||
|
discovery_info["name"].replace(f".{discovery_info['type']}", ""),
|
||||||
|
discovery_info["properties"]["id"],
|
||||||
|
)
|
||||||
|
|
||||||
|
async def async_step_ssdp(self, discovery_info: DiscoveryInfoType) -> FlowResult:
|
||||||
|
"""Handle Nanoleaf SSDP discovery."""
|
||||||
|
_LOGGER.debug("SSDP discovered: %s", discovery_info)
|
||||||
|
return await self._async_discovery_handler(
|
||||||
|
discovery_info["_host"],
|
||||||
|
discovery_info["nl-devicename"],
|
||||||
|
discovery_info["nl-deviceid"],
|
||||||
|
)
|
||||||
|
|
||||||
|
async def _async_discovery_handler(
|
||||||
|
self, host: str, name: str, device_id: str
|
||||||
) -> FlowResult:
|
) -> FlowResult:
|
||||||
"""Handle Nanoleaf discovery."""
|
"""Handle Nanoleaf discovery."""
|
||||||
host = discovery_info["host"]
|
|
||||||
# The name is unique and printed on the device and cannot be changed.
|
# The name is unique and printed on the device and cannot be changed.
|
||||||
name = discovery_info["name"].replace(f".{discovery_info['type']}", "")
|
|
||||||
await self.async_set_unique_id(name)
|
await self.async_set_unique_id(name)
|
||||||
self._abort_if_unique_id_configured({CONF_HOST: host})
|
self._abort_if_unique_id_configured({CONF_HOST: host})
|
||||||
|
|
||||||
# Import from discovery integration
|
# Import from discovery integration
|
||||||
self.device_id = discovery_info["properties"]["id"]
|
self.device_id = device_id
|
||||||
self.discovery_conf = cast(
|
self.discovery_conf = cast(
|
||||||
dict,
|
dict,
|
||||||
await self.hass.async_add_executor_job(
|
await self.hass.async_add_executor_job(
|
||||||
|
@ -10,6 +10,20 @@
|
|||||||
"NL*"
|
"NL*"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"ssdp": [
|
||||||
|
{
|
||||||
|
"st": "Nanoleaf_aurora:light"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"st": "nanoleaf:nl29"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"st": "nanoleaf:nl42"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"st": "nanoleaf:nl52"
|
||||||
|
}
|
||||||
|
],
|
||||||
"codeowners": ["@milanmeu"],
|
"codeowners": ["@milanmeu"],
|
||||||
"iot_class": "local_polling"
|
"iot_class": "local_polling"
|
||||||
}
|
}
|
@ -171,6 +171,20 @@ SSDP = {
|
|||||||
"manufacturer": "konnected.io"
|
"manufacturer": "konnected.io"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"nanoleaf": [
|
||||||
|
{
|
||||||
|
"st": "Nanoleaf_aurora:light"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"st": "nanoleaf:nl29"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"st": "nanoleaf:nl42"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"st": "nanoleaf:nl52"
|
||||||
|
}
|
||||||
|
],
|
||||||
"netgear": [
|
"netgear": [
|
||||||
{
|
{
|
||||||
"deviceType": "urn:schemas-upnp-org:device:InternetGatewayDevice:1",
|
"deviceType": "urn:schemas-upnp-org:device:InternetGatewayDevice:1",
|
||||||
|
@ -74,10 +74,7 @@ async def test_user_unavailable_user_step_link_step(hass: HomeAssistant) -> None
|
|||||||
"homeassistant.components.nanoleaf.config_flow.Nanoleaf.authorize",
|
"homeassistant.components.nanoleaf.config_flow.Nanoleaf.authorize",
|
||||||
side_effect=Unavailable,
|
side_effect=Unavailable,
|
||||||
):
|
):
|
||||||
result3 = await hass.config_entries.flow.async_configure(
|
result3 = await hass.config_entries.flow.async_configure(result["flow_id"], {})
|
||||||
result["flow_id"],
|
|
||||||
{},
|
|
||||||
)
|
|
||||||
assert result3["type"] == "abort"
|
assert result3["type"] == "abort"
|
||||||
assert result3["reason"] == "cannot_connect"
|
assert result3["reason"] == "cannot_connect"
|
||||||
|
|
||||||
@ -115,10 +112,7 @@ async def test_user_error_setup_finish(
|
|||||||
"homeassistant.components.nanoleaf.config_flow.Nanoleaf.get_info",
|
"homeassistant.components.nanoleaf.config_flow.Nanoleaf.get_info",
|
||||||
side_effect=error,
|
side_effect=error,
|
||||||
):
|
):
|
||||||
result3 = await hass.config_entries.flow.async_configure(
|
result3 = await hass.config_entries.flow.async_configure(result["flow_id"], {})
|
||||||
result["flow_id"],
|
|
||||||
{},
|
|
||||||
)
|
|
||||||
assert result3["type"] == "abort"
|
assert result3["type"] == "abort"
|
||||||
assert result3["reason"] == reason
|
assert result3["reason"] == reason
|
||||||
|
|
||||||
@ -151,9 +145,7 @@ async def test_user_not_authorizing_new_tokens_user_step_link_step(
|
|||||||
assert result2["errors"] is None
|
assert result2["errors"] is None
|
||||||
assert result2["step_id"] == "link"
|
assert result2["step_id"] == "link"
|
||||||
|
|
||||||
result3 = await hass.config_entries.flow.async_configure(
|
result3 = await hass.config_entries.flow.async_configure(result["flow_id"])
|
||||||
result["flow_id"],
|
|
||||||
)
|
|
||||||
assert result3["type"] == "form"
|
assert result3["type"] == "form"
|
||||||
assert result3["errors"] is None
|
assert result3["errors"] is None
|
||||||
assert result3["step_id"] == "link"
|
assert result3["step_id"] == "link"
|
||||||
@ -165,10 +157,7 @@ async def test_user_not_authorizing_new_tokens_user_step_link_step(
|
|||||||
|
|
||||||
mock_nanoleaf.return_value.authorize.side_effect = None
|
mock_nanoleaf.return_value.authorize.side_effect = None
|
||||||
|
|
||||||
result5 = await hass.config_entries.flow.async_configure(
|
result5 = await hass.config_entries.flow.async_configure(result["flow_id"], {})
|
||||||
result["flow_id"],
|
|
||||||
{},
|
|
||||||
)
|
|
||||||
assert result5["type"] == "create_entry"
|
assert result5["type"] == "create_entry"
|
||||||
assert result5["title"] == TEST_NAME
|
assert result5["title"] == TEST_NAME
|
||||||
assert result5["data"] == {
|
assert result5["data"] == {
|
||||||
@ -213,20 +202,14 @@ async def test_user_exception_user_step(hass: HomeAssistant) -> None:
|
|||||||
|
|
||||||
mock_nanoleaf.return_value.authorize.side_effect = Exception()
|
mock_nanoleaf.return_value.authorize.side_effect = Exception()
|
||||||
|
|
||||||
result4 = await hass.config_entries.flow.async_configure(
|
result4 = await hass.config_entries.flow.async_configure(result["flow_id"], {})
|
||||||
result["flow_id"],
|
|
||||||
{},
|
|
||||||
)
|
|
||||||
assert result4["type"] == "form"
|
assert result4["type"] == "form"
|
||||||
assert result4["step_id"] == "link"
|
assert result4["step_id"] == "link"
|
||||||
assert result4["errors"] == {"base": "unknown"}
|
assert result4["errors"] == {"base": "unknown"}
|
||||||
|
|
||||||
mock_nanoleaf.return_value.authorize.side_effect = None
|
mock_nanoleaf.return_value.authorize.side_effect = None
|
||||||
mock_nanoleaf.return_value.get_info.side_effect = Exception()
|
mock_nanoleaf.return_value.get_info.side_effect = Exception()
|
||||||
result5 = await hass.config_entries.flow.async_configure(
|
result5 = await hass.config_entries.flow.async_configure(result["flow_id"], {})
|
||||||
result["flow_id"],
|
|
||||||
{},
|
|
||||||
)
|
|
||||||
assert result5["type"] == "abort"
|
assert result5["type"] == "abort"
|
||||||
assert result5["reason"] == "unknown"
|
assert result5["reason"] == "unknown"
|
||||||
|
|
||||||
@ -307,10 +290,7 @@ async def test_reauth(hass: HomeAssistant) -> None:
|
|||||||
assert result["type"] == "form"
|
assert result["type"] == "form"
|
||||||
assert result["step_id"] == "link"
|
assert result["step_id"] == "link"
|
||||||
|
|
||||||
result2 = await hass.config_entries.flow.async_configure(
|
result2 = await hass.config_entries.flow.async_configure(result["flow_id"], {})
|
||||||
result["flow_id"],
|
|
||||||
{},
|
|
||||||
)
|
|
||||||
assert result2["type"] == "abort"
|
assert result2["type"] == "abort"
|
||||||
assert result2["reason"] == "reauth_successful"
|
assert result2["reason"] == "reauth_successful"
|
||||||
|
|
||||||
@ -460,3 +440,42 @@ async def test_import_discovery_integration(
|
|||||||
|
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
assert len(mock_setup_entry.mock_calls) == 1
|
assert len(mock_setup_entry.mock_calls) == 1
|
||||||
|
|
||||||
|
|
||||||
|
async def test_ssdp_discovery(hass: HomeAssistant) -> None:
|
||||||
|
"""Test SSDP discovery."""
|
||||||
|
with patch(
|
||||||
|
"homeassistant.components.nanoleaf.config_flow.load_json",
|
||||||
|
return_value={},
|
||||||
|
), patch(
|
||||||
|
"homeassistant.components.nanoleaf.config_flow.Nanoleaf",
|
||||||
|
return_value=_mock_nanoleaf(TEST_HOST, TEST_TOKEN),
|
||||||
|
), patch(
|
||||||
|
"homeassistant.components.nanoleaf.async_setup_entry",
|
||||||
|
return_value=True,
|
||||||
|
) as mock_setup_entry:
|
||||||
|
result = await hass.config_entries.flow.async_init(
|
||||||
|
DOMAIN,
|
||||||
|
context={"source": config_entries.SOURCE_SSDP},
|
||||||
|
data={
|
||||||
|
"_host": TEST_HOST,
|
||||||
|
"nl-devicename": TEST_NAME,
|
||||||
|
"nl-deviceid": TEST_DEVICE_ID,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
assert result["type"] == "form"
|
||||||
|
assert result["errors"] is None
|
||||||
|
assert result["step_id"] == "link"
|
||||||
|
|
||||||
|
result2 = await hass.config_entries.flow.async_configure(result["flow_id"], {})
|
||||||
|
|
||||||
|
assert result2["type"] == "create_entry"
|
||||||
|
assert result2["title"] == TEST_NAME
|
||||||
|
assert result2["data"] == {
|
||||||
|
CONF_HOST: TEST_HOST,
|
||||||
|
CONF_TOKEN: TEST_TOKEN,
|
||||||
|
}
|
||||||
|
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
assert len(mock_setup_entry.mock_calls) == 1
|
||||||
|
Loading…
x
Reference in New Issue
Block a user