Insteon HUB DHCP discovery (#70685)
Co-authored-by: Paulus Schoutsen <paulus@home-assistant.io>pull/70699/head
parent
28ba572d9d
commit
6363c67398
|
@ -7,7 +7,7 @@ from pyinsteon import async_connect
|
|||
import voluptuous as vol
|
||||
|
||||
from homeassistant import config_entries
|
||||
from homeassistant.components import usb
|
||||
from homeassistant.components import dhcp, usb
|
||||
from homeassistant.const import (
|
||||
CONF_ADDRESS,
|
||||
CONF_DEVICE,
|
||||
|
@ -19,6 +19,7 @@ from homeassistant.const import (
|
|||
)
|
||||
from homeassistant.core import callback
|
||||
from homeassistant.data_entry_flow import FlowResult
|
||||
from homeassistant.helpers.device_registry import format_mac
|
||||
from homeassistant.helpers.dispatcher import async_dispatcher_send
|
||||
|
||||
from .const import (
|
||||
|
@ -114,6 +115,7 @@ class InsteonFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
|||
|
||||
_device_path: str | None = None
|
||||
_device_name: str | None = None
|
||||
discovered_conf: dict[str, str] = {}
|
||||
|
||||
@staticmethod
|
||||
@callback
|
||||
|
@ -170,7 +172,7 @@ class InsteonFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
|||
return self.async_create_entry(title="", data=user_input)
|
||||
user_input.pop(CONF_HUB_VERSION)
|
||||
errors["base"] = "cannot_connect"
|
||||
schema_defaults = user_input if user_input is not None else {}
|
||||
schema_defaults = user_input if user_input is not None else self.discovered_conf
|
||||
data_schema = build_hub_schema(hub_version=hub_version, **schema_defaults)
|
||||
step_id = STEP_HUB_V2 if hub_version == 2 else STEP_HUB_V1
|
||||
return self.async_show_form(
|
||||
|
@ -203,12 +205,14 @@ class InsteonFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
|||
discovery_info.pid,
|
||||
)
|
||||
self._set_confirm_only()
|
||||
self.context["title_placeholders"] = {CONF_NAME: self._device_name}
|
||||
self.context["title_placeholders"] = {
|
||||
CONF_NAME: f"Insteon PLM {self._device_name}"
|
||||
}
|
||||
await self.async_set_unique_id(config_entries.DEFAULT_DISCOVERY_UNIQUE_ID)
|
||||
return await self.async_step_confirm_usb()
|
||||
|
||||
async def async_step_confirm_usb(self, user_input=None):
|
||||
"""Confirm a discovery."""
|
||||
"""Confirm a USB discovery."""
|
||||
if user_input is not None:
|
||||
return await self.async_step_plm({CONF_DEVICE: self._device_path})
|
||||
|
||||
|
@ -217,6 +221,15 @@ class InsteonFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
|||
description_placeholders={CONF_NAME: self._device_name},
|
||||
)
|
||||
|
||||
async def async_step_dhcp(self, discovery_info: dhcp.DhcpServiceInfo) -> FlowResult:
|
||||
"""Handle a DHCP discovery."""
|
||||
self.discovered_conf = {CONF_HOST: discovery_info.ip}
|
||||
self.context["title_placeholders"] = {
|
||||
CONF_NAME: f"Insteon Hub {discovery_info.ip}"
|
||||
}
|
||||
await self.async_set_unique_id(format_mac(discovery_info.macaddress))
|
||||
return await self.async_step_user()
|
||||
|
||||
|
||||
class InsteonOptionsFlowHandler(config_entries.OptionsFlow):
|
||||
"""Handle an Insteon options flow."""
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
"documentation": "https://www.home-assistant.io/integrations/insteon",
|
||||
"requirements": ["pyinsteon==1.0.13"],
|
||||
"codeowners": ["@teharris1"],
|
||||
"dhcp": [{ "macaddress": "000EF3*" }, { "registered_devices": true }],
|
||||
"config_flow": true,
|
||||
"iot_class": "local_push",
|
||||
"loggers": ["pyinsteon", "pypubsub"],
|
||||
|
|
|
@ -43,7 +43,8 @@
|
|||
},
|
||||
"abort": {
|
||||
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]",
|
||||
"single_instance_allowed": "[%key:common::config_flow::abort::single_instance_allowed%]"
|
||||
"single_instance_allowed": "[%key:common::config_flow::abort::single_instance_allowed%]",
|
||||
"not_insteon_device": "Discovered device not an Insteon device"
|
||||
}
|
||||
},
|
||||
"options": {
|
||||
|
|
|
@ -49,6 +49,8 @@ DHCP: list[dict[str, str | bool]] = [
|
|||
{'domain': 'hunterdouglas_powerview',
|
||||
'hostname': 'hunter*',
|
||||
'macaddress': '002674*'},
|
||||
{'domain': 'insteon', 'macaddress': '000EF3*'},
|
||||
{'domain': 'insteon', 'registered_devices': True},
|
||||
{'domain': 'intellifire', 'hostname': 'zentrios-*'},
|
||||
{'domain': 'isy994', 'registered_devices': True},
|
||||
{'domain': 'isy994', 'hostname': 'isy*', 'macaddress': '0021B9*'},
|
||||
|
|
|
@ -2,8 +2,10 @@
|
|||
|
||||
from unittest.mock import patch
|
||||
|
||||
import voluptuous_serialize
|
||||
|
||||
from homeassistant import config_entries, data_entry_flow
|
||||
from homeassistant.components import usb
|
||||
from homeassistant.components import dhcp, usb
|
||||
from homeassistant.components.insteon.config_flow import (
|
||||
HUB1,
|
||||
HUB2,
|
||||
|
@ -37,6 +39,7 @@ from homeassistant.const import (
|
|||
CONF_USERNAME,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
|
||||
from .const import (
|
||||
MOCK_HOSTNAME,
|
||||
|
@ -648,3 +651,48 @@ async def test_discovery_via_usb_already_setup(hass):
|
|||
|
||||
assert result["type"] == data_entry_flow.RESULT_TYPE_ABORT
|
||||
assert result["reason"] == "single_instance_allowed"
|
||||
|
||||
|
||||
async def test_discovery_via_dhcp_hubv1(hass):
|
||||
"""Test usb flow."""
|
||||
await _test_dhcp(hass, HUB1)
|
||||
|
||||
|
||||
async def test_discovery_via_dhcp_hubv2(hass):
|
||||
"""Test usb flow."""
|
||||
await _test_dhcp(hass, HUB2)
|
||||
|
||||
|
||||
async def _test_dhcp(hass, modem_type):
|
||||
"""Test the dhcp discovery for a moddem type."""
|
||||
discovery_info = dhcp.DhcpServiceInfo(
|
||||
ip="11.22.33.44", hostname="", macaddress="00:0e:f3:aa:bb:cc"
|
||||
)
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
"insteon",
|
||||
context={"source": config_entries.SOURCE_DHCP},
|
||||
data=discovery_info,
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
|
||||
assert result["step_id"] == "user"
|
||||
|
||||
with patch("homeassistant.components.insteon.config_flow.async_connect"), patch(
|
||||
"homeassistant.components.insteon.async_setup_entry", return_value=True
|
||||
):
|
||||
result2 = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"], user_input={"modem_type": modem_type}
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert result2["type"] == data_entry_flow.RESULT_TYPE_FORM
|
||||
assert result["step_id"] == "user"
|
||||
|
||||
schema = voluptuous_serialize.convert(
|
||||
result2["data_schema"],
|
||||
custom_serializer=cv.custom_serializer,
|
||||
)
|
||||
for field in schema:
|
||||
if field["name"] == "host":
|
||||
assert field.get("default") == "11.22.33.44"
|
||||
break
|
||||
|
|
Loading…
Reference in New Issue