Update LaMetric config entry using DHCP discovery data (#78527)

* Update LaMetric config entry using DHCP discovery data

* Update translations
This commit is contained in:
Franck Nijhof 2022-09-16 08:35:12 +02:00 committed by GitHub
parent e7ca40156f
commit 564150169b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 74 additions and 4 deletions

View File

@ -20,6 +20,7 @@ from demetriek import (
import voluptuous as vol
from yarl import URL
from homeassistant.components.dhcp import DhcpServiceInfo
from homeassistant.components.ssdp import (
ATTR_UPNP_FRIENDLY_NAME,
ATTR_UPNP_SERIAL,
@ -29,6 +30,7 @@ from homeassistant.const import CONF_API_KEY, CONF_DEVICE, CONF_HOST, CONF_MAC
from homeassistant.data_entry_flow import AbortFlow, FlowResult
from homeassistant.helpers.aiohttp_client import async_get_clientsession
from homeassistant.helpers.config_entry_oauth2_flow import AbstractOAuth2FlowHandler
from homeassistant.helpers.device_registry import format_mac
from homeassistant.helpers.selector import (
SelectOptionDict,
SelectSelector,
@ -245,6 +247,22 @@ class LaMetricFlowHandler(AbstractOAuth2FlowHandler, domain=DOMAIN):
},
)
async def async_step_dhcp(self, discovery_info: DhcpServiceInfo) -> FlowResult:
"""Handle dhcp discovery to update existing entries."""
mac = format_mac(discovery_info.macaddress)
for entry in self._async_current_entries():
if format_mac(entry.data[CONF_MAC]) == mac:
self.hass.config_entries.async_update_entry(
entry,
data=entry.data | {CONF_HOST: discovery_info.ip},
)
self.hass.async_create_task(
self.hass.config_entries.async_reload(entry.entry_id)
)
return self.async_abort(reason="already_configured")
return self.async_abort(reason="unknown")
# Replace OAuth create entry with a fetch devices step
# LaMetric only use OAuth to get device information, but doesn't
# use it later on.

View File

@ -12,5 +12,6 @@
{
"deviceType": "urn:schemas-upnp-org:device:LaMetric:1"
}
]
],
"dhcp": [{ "registered_devices": true }]
}

View File

@ -38,7 +38,8 @@
"link_local_address": "Link local addresses are not supported",
"missing_configuration": "The LaMetric integration is not configured. Please follow the documentation.",
"no_devices": "The authorized user has no LaMetric devices",
"no_url_available": "[%key:common::config_flow::abort::oauth2_no_url_available%]"
"no_url_available": "[%key:common::config_flow::abort::oauth2_no_url_available%]",
"unknown": "[%key:common::config_flow::error::unknown%]"
}
},
"issues": {

View File

@ -7,7 +7,8 @@
"link_local_address": "Link local addresses are not supported",
"missing_configuration": "The LaMetric integration is not configured. Please follow the documentation.",
"no_devices": "The authorized user has no LaMetric devices",
"no_url_available": "No URL available. For information about this error, [check the help section]({docs_url})"
"no_url_available": "No URL available. For information about this error, [check the help section]({docs_url})",
"unknown": "Unexpected error"
},
"error": {
"cannot_connect": "Failed to connect",

View File

@ -60,6 +60,7 @@ DHCP: list[dict[str, str | bool]] = [
{'domain': 'isy994', 'registered_devices': True},
{'domain': 'isy994', 'hostname': 'isy*', 'macaddress': '0021B9*'},
{'domain': 'isy994', 'hostname': 'polisy*', 'macaddress': '000DB9*'},
{'domain': 'lametric', 'registered_devices': True},
{'domain': 'lifx', 'macaddress': 'D073D5*'},
{'domain': 'lifx', 'registered_devices': True},
{'domain': 'litterrobot', 'hostname': 'litter-robot4'},

View File

@ -11,13 +11,14 @@ from demetriek import (
)
import pytest
from homeassistant.components.dhcp import DhcpServiceInfo
from homeassistant.components.lametric.const import DOMAIN
from homeassistant.components.ssdp import (
ATTR_UPNP_FRIENDLY_NAME,
ATTR_UPNP_SERIAL,
SsdpServiceInfo,
)
from homeassistant.config_entries import SOURCE_SSDP, SOURCE_USER
from homeassistant.config_entries import SOURCE_DHCP, SOURCE_SSDP, SOURCE_USER
from homeassistant.const import CONF_API_KEY, CONF_DEVICE, CONF_HOST, CONF_MAC
from homeassistant.core import HomeAssistant
from homeassistant.data_entry_flow import FlowResultType
@ -695,3 +696,50 @@ async def test_cloud_errors(
assert len(mock_lametric_config_flow.device.mock_calls) == 2
assert len(mock_lametric_config_flow.notify.mock_calls) == 1
assert len(mock_setup_entry.mock_calls) == 1
async def test_dhcp_discovery_updates_entry(
hass: HomeAssistant,
mock_config_entry: MockConfigEntry,
) -> None:
"""Test DHCP discovery updates config entries."""
mock_config_entry.add_to_hass(hass)
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": SOURCE_DHCP},
data=DhcpServiceInfo(
hostname="lametric",
ip="127.0.0.42",
macaddress="aa:bb:cc:dd:ee:ff",
),
)
assert result.get("type") == FlowResultType.ABORT
assert result.get("reason") == "already_configured"
assert mock_config_entry.data == {
CONF_API_KEY: "mock-from-fixture",
CONF_HOST: "127.0.0.42",
CONF_MAC: "AA:BB:CC:DD:EE:FF",
}
async def test_dhcp_unknown_device(
hass: HomeAssistant,
mock_config_entry: MockConfigEntry,
) -> None:
"""Test unknown DHCP discovery aborts flow."""
mock_config_entry.add_to_hass(hass)
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": SOURCE_DHCP},
data=DhcpServiceInfo(
hostname="lametric",
ip="127.0.0.42",
macaddress="aa:bb:cc:dd:ee:00",
),
)
assert result.get("type") == FlowResultType.ABORT
assert result.get("reason") == "unknown"