mirror of
https://github.com/home-assistant/core.git
synced 2025-07-19 19:27:45 +00:00
Add zeroconf support for yeelight (#56758)
This commit is contained in:
parent
8e91e6e97e
commit
4513a46248
@ -60,6 +60,17 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
|
|||||||
self._discovered_ip = discovery_info[IP_ADDRESS]
|
self._discovered_ip = discovery_info[IP_ADDRESS]
|
||||||
return await self._async_handle_discovery()
|
return await self._async_handle_discovery()
|
||||||
|
|
||||||
|
async def async_step_zeroconf(self, discovery_info):
|
||||||
|
"""Handle discovery from zeroconf."""
|
||||||
|
self._discovered_ip = discovery_info["host"]
|
||||||
|
await self.async_set_unique_id(
|
||||||
|
"{0:#0{1}x}".format(int(discovery_info["name"][-26:-18]), 18)
|
||||||
|
)
|
||||||
|
self._abort_if_unique_id_configured(
|
||||||
|
updates={CONF_HOST: self._discovered_ip}, reload_on_update=False
|
||||||
|
)
|
||||||
|
return await self._async_handle_discovery()
|
||||||
|
|
||||||
async def async_step_ssdp(self, discovery_info):
|
async def async_step_ssdp(self, discovery_info):
|
||||||
"""Handle discovery from ssdp."""
|
"""Handle discovery from ssdp."""
|
||||||
self._discovered_ip = urlparse(discovery_info["location"]).hostname
|
self._discovered_ip = urlparse(discovery_info["location"]).hostname
|
||||||
|
@ -8,9 +8,12 @@
|
|||||||
"dependencies": ["network"],
|
"dependencies": ["network"],
|
||||||
"quality_scale": "platinum",
|
"quality_scale": "platinum",
|
||||||
"iot_class": "local_push",
|
"iot_class": "local_push",
|
||||||
"dhcp": [{
|
"dhcp": [
|
||||||
"hostname": "yeelink-*"
|
{
|
||||||
}],
|
"hostname": "yeelink-*"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"zeroconf": [{ "type": "_miio._udp.local.", "name": "yeelink-*" }],
|
||||||
"homekit": {
|
"homekit": {
|
||||||
"models": ["YL*"]
|
"models": ["YL*"]
|
||||||
}
|
}
|
||||||
|
@ -168,6 +168,10 @@ ZEROCONF = {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"domain": "xiaomi_miio"
|
"domain": "xiaomi_miio"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"domain": "yeelight",
|
||||||
|
"name": "yeelink-*"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"_nanoleafapi._tcp.local.": [
|
"_nanoleafapi._tcp.local.": [
|
||||||
|
@ -37,6 +37,17 @@ CAPABILITIES = {
|
|||||||
"name": "",
|
"name": "",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ID_DECIMAL = f"{int(ID, 16):08d}"
|
||||||
|
|
||||||
|
ZEROCONF_DATA = {
|
||||||
|
"host": IP_ADDRESS,
|
||||||
|
"port": 54321,
|
||||||
|
"hostname": f"yeelink-light-strip1_miio{ID_DECIMAL}.local.",
|
||||||
|
"type": "_miio._udp.local.",
|
||||||
|
"name": f"yeelink-light-strip1_miio{ID_DECIMAL}._miio._udp.local.",
|
||||||
|
"properties": {"epoch": "1", "mac": "000000000000"},
|
||||||
|
}
|
||||||
|
|
||||||
NAME = "name"
|
NAME = "name"
|
||||||
SHORT_ID = hex(int("0x000000000015243f", 16))
|
SHORT_ID = hex(int("0x000000000015243f", 16))
|
||||||
UNIQUE_NAME = f"yeelight_{MODEL}_{SHORT_ID}"
|
UNIQUE_NAME = f"yeelight_{MODEL}_{SHORT_ID}"
|
||||||
|
@ -33,6 +33,7 @@ from . import (
|
|||||||
MODULE_CONFIG_FLOW,
|
MODULE_CONFIG_FLOW,
|
||||||
NAME,
|
NAME,
|
||||||
UNIQUE_FRIENDLY_NAME,
|
UNIQUE_FRIENDLY_NAME,
|
||||||
|
ZEROCONF_DATA,
|
||||||
_mocked_bulb,
|
_mocked_bulb,
|
||||||
_patch_discovery,
|
_patch_discovery,
|
||||||
_patch_discovery_interval,
|
_patch_discovery_interval,
|
||||||
@ -576,3 +577,67 @@ async def test_discovered_ssdp(hass):
|
|||||||
|
|
||||||
assert result["type"] == RESULT_TYPE_ABORT
|
assert result["type"] == RESULT_TYPE_ABORT
|
||||||
assert result["reason"] == "already_configured"
|
assert result["reason"] == "already_configured"
|
||||||
|
|
||||||
|
|
||||||
|
async def test_discovered_zeroconf(hass):
|
||||||
|
"""Test we can setup when discovered from zeroconf."""
|
||||||
|
await setup.async_setup_component(hass, "persistent_notification", {})
|
||||||
|
|
||||||
|
mocked_bulb = _mocked_bulb()
|
||||||
|
with _patch_discovery(), _patch_discovery_interval(), patch(
|
||||||
|
f"{MODULE_CONFIG_FLOW}.AsyncBulb", return_value=mocked_bulb
|
||||||
|
):
|
||||||
|
result = await hass.config_entries.flow.async_init(
|
||||||
|
DOMAIN,
|
||||||
|
context={"source": config_entries.SOURCE_ZEROCONF},
|
||||||
|
data=ZEROCONF_DATA,
|
||||||
|
)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
assert result["type"] == RESULT_TYPE_FORM
|
||||||
|
assert result["errors"] is None
|
||||||
|
|
||||||
|
with _patch_discovery(), _patch_discovery_interval(), patch(
|
||||||
|
f"{MODULE}.async_setup", return_value=True
|
||||||
|
) as mock_async_setup, patch(
|
||||||
|
f"{MODULE}.async_setup_entry", return_value=True
|
||||||
|
) as mock_async_setup_entry:
|
||||||
|
result2 = await hass.config_entries.flow.async_configure(result["flow_id"], {})
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
assert result2["type"] == "create_entry"
|
||||||
|
assert result2["data"] == {
|
||||||
|
CONF_HOST: IP_ADDRESS,
|
||||||
|
CONF_ID: "0x000000000015243f",
|
||||||
|
CONF_MODEL: MODEL,
|
||||||
|
}
|
||||||
|
assert mock_async_setup.called
|
||||||
|
assert mock_async_setup_entry.called
|
||||||
|
|
||||||
|
mocked_bulb = _mocked_bulb()
|
||||||
|
with _patch_discovery(), _patch_discovery_interval(), patch(
|
||||||
|
f"{MODULE_CONFIG_FLOW}.AsyncBulb", return_value=mocked_bulb
|
||||||
|
):
|
||||||
|
result = await hass.config_entries.flow.async_init(
|
||||||
|
DOMAIN,
|
||||||
|
context={"source": config_entries.SOURCE_ZEROCONF},
|
||||||
|
data=ZEROCONF_DATA,
|
||||||
|
)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
assert result["type"] == RESULT_TYPE_ABORT
|
||||||
|
assert result["reason"] == "already_configured"
|
||||||
|
|
||||||
|
mocked_bulb = _mocked_bulb()
|
||||||
|
with _patch_discovery(), _patch_discovery_interval(), patch(
|
||||||
|
f"{MODULE_CONFIG_FLOW}.AsyncBulb", return_value=mocked_bulb
|
||||||
|
):
|
||||||
|
result = await hass.config_entries.flow.async_init(
|
||||||
|
DOMAIN,
|
||||||
|
context={"source": config_entries.SOURCE_SSDP},
|
||||||
|
data=CAPABILITIES,
|
||||||
|
)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
assert result["type"] == RESULT_TYPE_ABORT
|
||||||
|
assert result["reason"] == "already_configured"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user