Add discovery for Tube's Zigbee coordinators to ZHA (#48420)
* add discovery for tube zigbee gateways * update discovery * add test * another test * develop translations * review commentspull/48520/head
parent
9043a1f5aa
commit
4dc885dcc3
|
@ -9,6 +9,8 @@ import voluptuous as vol
|
|||
from zigpy.config import CONF_DEVICE, CONF_DEVICE_PATH
|
||||
|
||||
from homeassistant import config_entries
|
||||
from homeassistant.const import CONF_HOST, CONF_NAME
|
||||
from homeassistant.helpers.typing import DiscoveryInfoType
|
||||
|
||||
from .core.const import (
|
||||
CONF_BAUDRATE,
|
||||
|
@ -91,6 +93,37 @@ class ZhaFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
|||
data_schema=vol.Schema(schema),
|
||||
)
|
||||
|
||||
async def async_step_zeroconf(self, discovery_info: DiscoveryInfoType):
|
||||
"""Handle zeroconf discovery."""
|
||||
# Hostname is format: livingroom.local.
|
||||
local_name = discovery_info["hostname"][:-1]
|
||||
node_name = local_name[: -len(".local")]
|
||||
host = discovery_info[CONF_HOST]
|
||||
device_path = f"socket://{host}:6638"
|
||||
|
||||
await self.async_set_unique_id(node_name)
|
||||
self._abort_if_unique_id_configured(
|
||||
updates={
|
||||
CONF_DEVICE: {CONF_DEVICE_PATH: device_path},
|
||||
}
|
||||
)
|
||||
|
||||
# Check if already configured
|
||||
if self._async_current_entries():
|
||||
return self.async_abort(reason="single_instance_allowed")
|
||||
|
||||
# pylint: disable=no-member # https://github.com/PyCQA/pylint/issues/3167
|
||||
self.context["title_placeholders"] = {
|
||||
CONF_NAME: node_name,
|
||||
}
|
||||
|
||||
self._device_path = device_path
|
||||
self._radio_type = (
|
||||
RadioType.ezsp.name if "efr32" in local_name else RadioType.znp.name
|
||||
)
|
||||
|
||||
return await self.async_step_port_config()
|
||||
|
||||
async def async_step_port_config(self, user_input=None):
|
||||
"""Enter port settings specific for this type of radio."""
|
||||
errors = {}
|
||||
|
@ -118,9 +151,13 @@ class ZhaFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
|||
if isinstance(radio_schema, vol.Schema):
|
||||
radio_schema = radio_schema.schema
|
||||
|
||||
# pylint: disable=no-member # https://github.com/PyCQA/pylint/issues/3167
|
||||
source = self.context.get("source")
|
||||
for param, value in radio_schema.items():
|
||||
if param in SUPPORTED_PORT_SETTINGS:
|
||||
schema[param] = value
|
||||
if source == config_entries.SOURCE_ZEROCONF and param == CONF_BAUDRATE:
|
||||
schema[param] = 115200
|
||||
|
||||
return self.async_show_form(
|
||||
step_id="port_config",
|
||||
|
|
|
@ -15,5 +15,7 @@
|
|||
"zigpy-zigate==0.7.3",
|
||||
"zigpy-znp==0.4.0"
|
||||
],
|
||||
"codeowners": ["@dmulcahey", "@adminiuga"]
|
||||
"codeowners": ["@dmulcahey", "@adminiuga"],
|
||||
"zeroconf": [{ "type": "_esphomelib._tcp.local.", "name": "tube*" }],
|
||||
"after_dependencies": ["zeroconf"]
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
{
|
||||
"config": {
|
||||
"flow_title": "ZHA: {name}",
|
||||
"step": {
|
||||
"user": {
|
||||
"title": "ZHA",
|
||||
|
@ -21,7 +22,9 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"error": { "cannot_connect": "[%key:common::config_flow::error::cannot_connect%]" },
|
||||
"error": {
|
||||
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]"
|
||||
},
|
||||
"abort": {
|
||||
"single_instance_allowed": "[%key:common::config_flow::abort::single_instance_allowed%]"
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
"error": {
|
||||
"cannot_connect": "Failed to connect"
|
||||
},
|
||||
"flow_title": "ZHA: {name}",
|
||||
"step": {
|
||||
"pick_radio": {
|
||||
"data": {
|
||||
|
|
|
@ -57,6 +57,10 @@ ZEROCONF = {
|
|||
"_esphomelib._tcp.local.": [
|
||||
{
|
||||
"domain": "esphome"
|
||||
},
|
||||
{
|
||||
"domain": "zha",
|
||||
"name": "tube*"
|
||||
}
|
||||
],
|
||||
"_fbx-api._tcp.local.": [
|
||||
|
|
|
@ -28,6 +28,57 @@ def com_port():
|
|||
return port
|
||||
|
||||
|
||||
@patch("homeassistant.components.zha.async_setup_entry", AsyncMock(return_value=True))
|
||||
@patch("zigpy_znp.zigbee.application.ControllerApplication.probe", return_value=True)
|
||||
async def test_discovery(detect_mock, hass):
|
||||
"""Test zeroconf flow -- radio detected."""
|
||||
service_info = {
|
||||
"host": "192.168.1.200",
|
||||
"port": 6053,
|
||||
"hostname": "_tube_zb_gw._tcp.local.",
|
||||
"properties": {"name": "tube_123456"},
|
||||
}
|
||||
flow = await hass.config_entries.flow.async_init(
|
||||
"zha", context={"source": "zeroconf"}, data=service_info
|
||||
)
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
flow["flow_id"], user_input={}
|
||||
)
|
||||
|
||||
assert result["type"] == RESULT_TYPE_CREATE_ENTRY
|
||||
assert result["title"] == "socket://192.168.1.200:6638"
|
||||
assert result["data"] == {
|
||||
"device": {
|
||||
"baudrate": 115200,
|
||||
"flow_control": None,
|
||||
"path": "socket://192.168.1.200:6638",
|
||||
},
|
||||
CONF_RADIO_TYPE: "znp",
|
||||
}
|
||||
|
||||
|
||||
@patch("homeassistant.components.zha.async_setup_entry", AsyncMock(return_value=True))
|
||||
@patch("zigpy_znp.zigbee.application.ControllerApplication.probe", return_value=True)
|
||||
async def test_discovery_already_setup(detect_mock, hass):
|
||||
"""Test zeroconf flow -- radio detected."""
|
||||
service_info = {
|
||||
"host": "192.168.1.200",
|
||||
"port": 6053,
|
||||
"hostname": "_tube_zb_gw._tcp.local.",
|
||||
"properties": {"name": "tube_123456"},
|
||||
}
|
||||
await setup.async_setup_component(hass, "persistent_notification", {})
|
||||
MockConfigEntry(domain=DOMAIN, data={"usb_path": "/dev/ttyUSB1"}).add_to_hass(hass)
|
||||
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
"zha", context={"source": "zeroconf"}, data=service_info
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert result["type"] == "abort"
|
||||
assert result["reason"] == "single_instance_allowed"
|
||||
|
||||
|
||||
@patch("serial.tools.list_ports.comports", MagicMock(return_value=[com_port()]))
|
||||
@patch(
|
||||
"homeassistant.components.zha.config_flow.detect_radios",
|
||||
|
|
Loading…
Reference in New Issue