Add zeroconf discovery to zwave_js (#69382)

This commit is contained in:
Raman Gupta 2022-04-06 12:46:13 -04:00 committed by GitHub
parent c0e9cfedfb
commit bc194cd209
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 89 additions and 4 deletions

View File

@ -14,6 +14,7 @@ from zwave_js_server.version import VersionInfo, get_server_version
from homeassistant import config_entries, exceptions
from homeassistant.components import usb
from homeassistant.components.hassio import HassioServiceInfo, is_hassio
from homeassistant.components.zeroconf import ZeroconfServiceInfo
from homeassistant.const import CONF_NAME, CONF_URL
from homeassistant.core import HomeAssistant, callback
from homeassistant.data_entry_flow import (
@ -337,6 +338,33 @@ class ConfigFlow(BaseZwaveJSFlow, config_entries.ConfigFlow, domain=DOMAIN):
return await self.async_step_manual()
async def async_step_zeroconf(
self, discovery_info: ZeroconfServiceInfo
) -> FlowResult:
"""Handle zeroconf discovery."""
home_id = str(discovery_info.properties["homeId"])
await self.async_set_unique_id(home_id)
self._abort_if_unique_id_configured()
self.ws_address = f"ws://{discovery_info.host}:{discovery_info.port}"
self.context.update({"title_placeholders": {CONF_NAME: home_id}})
return await self.async_step_zeroconf_confirm()
async def async_step_zeroconf_confirm(
self, user_input: dict | None = None
) -> FlowResult:
"""Confirm the setup."""
if user_input is not None:
return await self.async_step_manual({CONF_URL: self.ws_address})
assert self.ws_address
return self.async_show_form(
step_id="zeroconf_confirm",
description_placeholders={
"home_id": self.unique_id,
CONF_URL: self.ws_address[5:],
},
)
async def async_step_usb(self, discovery_info: usb.UsbServiceInfo) -> FlowResult:
"""Handle USB Discovery."""
if not is_hassio(self.hass):

View File

@ -29,5 +29,6 @@
]
}
],
"zeroconf": ["_zwave-js-server._tcp.local."],
"loggers": ["zwave_js_server"]
}

View File

@ -36,6 +36,10 @@
},
"hassio_confirm": {
"title": "Set up Z-Wave JS integration with the Z-Wave JS add-on"
},
"zeroconf_confirm": {
"description": "Do you want to add the Z-Wave JS Server with home ID {home_id} found at {url} to Home Assistant?",
"title": "Discovered Z-Wave JS Server"
}
},
"error": {

View File

@ -26,7 +26,6 @@
"step": {
"configure_addon": {
"data": {
"network_key": "Network Key",
"s0_legacy_key": "S0 Key (Legacy)",
"s2_access_control_key": "S2 Access Control Key",
"s2_authenticated_key": "S2 Authenticated Key",
@ -59,6 +58,10 @@
},
"usb_confirm": {
"description": "Do you want to setup {name} with the Z-Wave JS add-on?"
},
"zeroconf_confirm": {
"description": "Do you want to add the Z-Wave JS Server with home ID {home_id} found at {url} to Home Assistant?",
"title": "Discovered Z-Wave JS Server"
}
}
},
@ -113,7 +116,6 @@
"data": {
"emulate_hardware": "Emulate Hardware",
"log_level": "Log level",
"network_key": "Network Key",
"s0_legacy_key": "S0 Key (Legacy)",
"s2_access_control_key": "S2 Access Control Key",
"s2_authenticated_key": "S2 Authenticated Key",
@ -142,6 +144,5 @@
"title": "The Z-Wave JS add-on is starting."
}
}
},
"title": "Z-Wave JS"
}
}

View File

@ -377,6 +377,11 @@ ZEROCONF = {
{
"domain": "kodi"
}
],
"_zwave-js-server._tcp.local.": [
{
"domain": "zwave_js"
}
]
}

View File

@ -10,6 +10,7 @@ from homeassistant import config_entries
from homeassistant.components import usb
from homeassistant.components.hassio import HassioServiceInfo
from homeassistant.components.hassio.handler import HassioAPIError
from homeassistant.components.zeroconf import ZeroconfServiceInfo
from homeassistant.components.zwave_js.config_flow import SERVER_VERSION_TIMEOUT, TITLE
from homeassistant.components.zwave_js.const import DOMAIN
@ -2459,3 +2460,48 @@ async def test_import_addon_installed(
}
assert len(mock_setup.mock_calls) == 1
assert len(mock_setup_entry.mock_calls) == 1
async def test_zeroconf(hass):
"""Test zeroconf discovery."""
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": config_entries.SOURCE_ZEROCONF},
data=ZeroconfServiceInfo(
host="localhost",
addresses=["127.0.0.1"],
hostname="mock_hostname",
name="mock_name",
port=3000,
type="_zwave-js-server._tcp.local.",
properties={"homeId": "1234"},
),
)
assert result["type"] == "form"
assert result["step_id"] == "zeroconf_confirm"
with patch(
"homeassistant.components.zwave_js.async_setup", return_value=True
) as mock_setup, patch(
"homeassistant.components.zwave_js.async_setup_entry",
return_value=True,
) as mock_setup_entry:
result = await hass.config_entries.flow.async_configure(result["flow_id"], {})
await hass.async_block_till_done()
assert result["type"] == "create_entry"
assert result["title"] == TITLE
assert result["data"] == {
"url": "ws://localhost:3000",
"usb_path": None,
"s0_legacy_key": None,
"s2_access_control_key": None,
"s2_authenticated_key": None,
"s2_unauthenticated_key": None,
"use_addon": False,
"integration_created_addon": False,
}
assert len(mock_setup.mock_calls) == 1
assert len(mock_setup_entry.mock_calls) == 1