Palazzetti DHCP Discovery (#129731)
Co-authored-by: Franck Nijhof <frenck@frenck.nl> Co-authored-by: Franck Nijhof <git@frenck.dev>pull/130283/head
parent
e382f924e6
commit
7515deddab
|
@ -6,6 +6,7 @@ from pypalazzetti.client import PalazzettiClient
|
||||||
from pypalazzetti.exceptions import CommunicationError
|
from pypalazzetti.exceptions import CommunicationError
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
|
from homeassistant.components import dhcp
|
||||||
from homeassistant.config_entries import ConfigFlow, ConfigFlowResult
|
from homeassistant.config_entries import ConfigFlow, ConfigFlowResult
|
||||||
from homeassistant.const import CONF_HOST
|
from homeassistant.const import CONF_HOST
|
||||||
from homeassistant.helpers import device_registry as dr
|
from homeassistant.helpers import device_registry as dr
|
||||||
|
@ -16,6 +17,8 @@ from .const import DOMAIN, LOGGER
|
||||||
class PalazzettiConfigFlow(ConfigFlow, domain=DOMAIN):
|
class PalazzettiConfigFlow(ConfigFlow, domain=DOMAIN):
|
||||||
"""Palazzetti config flow."""
|
"""Palazzetti config flow."""
|
||||||
|
|
||||||
|
_discovered_device: PalazzettiClient
|
||||||
|
|
||||||
async def async_step_user(
|
async def async_step_user(
|
||||||
self, user_input: dict[str, Any] | None = None
|
self, user_input: dict[str, Any] | None = None
|
||||||
) -> ConfigFlowResult:
|
) -> ConfigFlowResult:
|
||||||
|
@ -48,3 +51,41 @@ class PalazzettiConfigFlow(ConfigFlow, domain=DOMAIN):
|
||||||
data_schema=vol.Schema({vol.Required(CONF_HOST): str}),
|
data_schema=vol.Schema({vol.Required(CONF_HOST): str}),
|
||||||
errors=errors,
|
errors=errors,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
async def async_step_dhcp(
|
||||||
|
self, discovery_info: dhcp.DhcpServiceInfo
|
||||||
|
) -> ConfigFlowResult:
|
||||||
|
"""Handle DHCP discovery."""
|
||||||
|
|
||||||
|
LOGGER.debug(
|
||||||
|
"DHCP discovery detected Palazzetti: %s", discovery_info.macaddress
|
||||||
|
)
|
||||||
|
|
||||||
|
await self.async_set_unique_id(dr.format_mac(discovery_info.macaddress))
|
||||||
|
self._abort_if_unique_id_configured()
|
||||||
|
self._discovered_device = PalazzettiClient(hostname=discovery_info.ip)
|
||||||
|
try:
|
||||||
|
await self._discovered_device.connect()
|
||||||
|
except CommunicationError:
|
||||||
|
return self.async_abort(reason="cannot_connect")
|
||||||
|
|
||||||
|
return await self.async_step_discovery_confirm()
|
||||||
|
|
||||||
|
async def async_step_discovery_confirm(
|
||||||
|
self, user_input: dict[str, Any] | None = None
|
||||||
|
) -> ConfigFlowResult:
|
||||||
|
"""Confirm discovery."""
|
||||||
|
if user_input is not None:
|
||||||
|
return self.async_create_entry(
|
||||||
|
title=self._discovered_device.name,
|
||||||
|
data={CONF_HOST: self._discovered_device.host},
|
||||||
|
)
|
||||||
|
|
||||||
|
self._set_confirm_only()
|
||||||
|
return self.async_show_form(
|
||||||
|
step_id="discovery_confirm",
|
||||||
|
description_placeholders={
|
||||||
|
"name": self._discovered_device.name,
|
||||||
|
"host": self._discovered_device.host,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
|
@ -3,6 +3,15 @@
|
||||||
"name": "Palazzetti",
|
"name": "Palazzetti",
|
||||||
"codeowners": ["@dotvav"],
|
"codeowners": ["@dotvav"],
|
||||||
"config_flow": true,
|
"config_flow": true,
|
||||||
|
"dhcp": [
|
||||||
|
{
|
||||||
|
"hostname": "connbox*",
|
||||||
|
"macaddress": "40F3857*"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"registered_devices": true
|
||||||
|
}
|
||||||
|
],
|
||||||
"documentation": "https://www.home-assistant.io/integrations/palazzetti",
|
"documentation": "https://www.home-assistant.io/integrations/palazzetti",
|
||||||
"integration_type": "device",
|
"integration_type": "device",
|
||||||
"iot_class": "local_polling",
|
"iot_class": "local_polling",
|
||||||
|
|
|
@ -8,6 +8,9 @@
|
||||||
"data_description": {
|
"data_description": {
|
||||||
"host": "The host name or the IP address of the Palazzetti CBox"
|
"host": "The host name or the IP address of the Palazzetti CBox"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"discovery_confirm": {
|
||||||
|
"description": "Do you want to add {name} ({host}) to Home Assistant?"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"abort": {
|
"abort": {
|
||||||
|
|
|
@ -379,6 +379,15 @@ DHCP: Final[list[dict[str, str | bool]]] = [
|
||||||
"hostname": "gateway*",
|
"hostname": "gateway*",
|
||||||
"macaddress": "F8811A*",
|
"macaddress": "F8811A*",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"domain": "palazzetti",
|
||||||
|
"hostname": "connbox*",
|
||||||
|
"macaddress": "40F3857*",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"domain": "palazzetti",
|
||||||
|
"registered_devices": True,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"domain": "powerwall",
|
"domain": "powerwall",
|
||||||
"hostname": "1118431-*",
|
"hostname": "1118431-*",
|
||||||
|
|
|
@ -4,8 +4,9 @@ from unittest.mock import AsyncMock
|
||||||
|
|
||||||
from pypalazzetti.exceptions import CommunicationError
|
from pypalazzetti.exceptions import CommunicationError
|
||||||
|
|
||||||
|
from homeassistant.components import dhcp
|
||||||
from homeassistant.components.palazzetti.const import DOMAIN
|
from homeassistant.components.palazzetti.const import DOMAIN
|
||||||
from homeassistant.config_entries import SOURCE_USER
|
from homeassistant.config_entries import SOURCE_DHCP, SOURCE_USER
|
||||||
from homeassistant.const import CONF_HOST
|
from homeassistant.const import CONF_HOST
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.data_entry_flow import FlowResultType
|
from homeassistant.data_entry_flow import FlowResultType
|
||||||
|
@ -92,3 +93,48 @@ async def test_duplicate(
|
||||||
|
|
||||||
assert result["type"] is FlowResultType.ABORT
|
assert result["type"] is FlowResultType.ABORT
|
||||||
assert result["reason"] == "already_configured"
|
assert result["reason"] == "already_configured"
|
||||||
|
|
||||||
|
|
||||||
|
async def test_dhcp_flow(
|
||||||
|
hass: HomeAssistant, mock_palazzetti_client: AsyncMock, mock_setup_entry: AsyncMock
|
||||||
|
) -> None:
|
||||||
|
"""Test the DHCP flow."""
|
||||||
|
result = await hass.config_entries.flow.async_init(
|
||||||
|
DOMAIN,
|
||||||
|
data=dhcp.DhcpServiceInfo(
|
||||||
|
hostname="connbox1234", ip="192.168.1.1", macaddress="11:22:33:44:55:66"
|
||||||
|
),
|
||||||
|
context={"source": SOURCE_DHCP},
|
||||||
|
)
|
||||||
|
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
assert result["type"] is FlowResultType.FORM
|
||||||
|
assert result["step_id"] == "discovery_confirm"
|
||||||
|
|
||||||
|
result = await hass.config_entries.flow.async_configure(
|
||||||
|
result["flow_id"],
|
||||||
|
{},
|
||||||
|
)
|
||||||
|
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
assert result["type"] is FlowResultType.CREATE_ENTRY
|
||||||
|
assert result["title"] == "Stove"
|
||||||
|
assert result["result"].unique_id == "11:22:33:44:55:66"
|
||||||
|
|
||||||
|
|
||||||
|
async def test_dhcp_flow_error(
|
||||||
|
hass: HomeAssistant, mock_palazzetti_client: AsyncMock, mock_setup_entry: AsyncMock
|
||||||
|
) -> None:
|
||||||
|
"""Test the DHCP flow."""
|
||||||
|
mock_palazzetti_client.connect.side_effect = CommunicationError()
|
||||||
|
|
||||||
|
result = await hass.config_entries.flow.async_init(
|
||||||
|
DOMAIN,
|
||||||
|
data=dhcp.DhcpServiceInfo(
|
||||||
|
hostname="connbox1234", ip="192.168.1.1", macaddress="11:22:33:44:55:66"
|
||||||
|
),
|
||||||
|
context={"source": SOURCE_DHCP},
|
||||||
|
)
|
||||||
|
|
||||||
|
assert result["type"] is FlowResultType.ABORT
|
||||||
|
assert result["reason"] == "cannot_connect"
|
||||||
|
|
Loading…
Reference in New Issue