Allow dhcp discovery to update host for lamarzocco (#131047)

This commit is contained in:
Josef Zweck 2024-11-26 10:57:46 +01:00 committed by GitHub
parent d2f862b7b9
commit 666b908242
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 92 additions and 11 deletions

View File

@ -26,6 +26,7 @@ from homeassistant.config_entries import (
OptionsFlow, OptionsFlow,
) )
from homeassistant.const import ( from homeassistant.const import (
CONF_ADDRESS,
CONF_HOST, CONF_HOST,
CONF_MAC, CONF_MAC,
CONF_MODEL, CONF_MODEL,
@ -284,7 +285,12 @@ class LmConfigFlow(ConfigFlow, domain=DOMAIN):
serial = discovery_info.hostname.upper() serial = discovery_info.hostname.upper()
await self.async_set_unique_id(serial) await self.async_set_unique_id(serial)
self._abort_if_unique_id_configured() self._abort_if_unique_id_configured(
updates={
CONF_HOST: discovery_info.ip,
CONF_ADDRESS: discovery_info.macaddress,
}
)
_LOGGER.debug( _LOGGER.debug(
"Discovered La Marzocco machine %s through DHCP at address %s", "Discovered La Marzocco machine %s through DHCP at address %s",
@ -294,6 +300,7 @@ class LmConfigFlow(ConfigFlow, domain=DOMAIN):
self._discovered[CONF_MACHINE] = serial self._discovered[CONF_MACHINE] = serial
self._discovered[CONF_HOST] = discovery_info.ip self._discovered[CONF_HOST] = discovery_info.ip
self._discovered[CONF_ADDRESS] = discovery_info.macaddress
return await self.async_step_user() return await self.async_step_user()

View File

@ -6,7 +6,8 @@ from dataclasses import dataclass
from pylamarzocco.const import FirmwareType from pylamarzocco.const import FirmwareType
from pylamarzocco.lm_machine import LaMarzoccoMachine from pylamarzocco.lm_machine import LaMarzoccoMachine
from homeassistant.helpers.device_registry import DeviceInfo from homeassistant.const import CONF_ADDRESS
from homeassistant.helpers.device_registry import CONNECTION_NETWORK_MAC, DeviceInfo
from homeassistant.helpers.entity import EntityDescription from homeassistant.helpers.entity import EntityDescription
from homeassistant.helpers.update_coordinator import CoordinatorEntity from homeassistant.helpers.update_coordinator import CoordinatorEntity
@ -47,6 +48,17 @@ class LaMarzoccoBaseEntity(
serial_number=device.serial_number, serial_number=device.serial_number,
sw_version=device.firmware[FirmwareType.MACHINE].current_version, sw_version=device.firmware[FirmwareType.MACHINE].current_version,
) )
if coordinator.config_entry.data.get(CONF_ADDRESS):
self._attr_device_info.update(
DeviceInfo(
connections={
(
CONNECTION_NETWORK_MAC,
coordinator.config_entry.data[CONF_ADDRESS],
)
}
)
)
class LaMarzoccoEntity(LaMarzoccoBaseEntity): class LaMarzoccoEntity(LaMarzoccoBaseEntity):

View File

@ -19,6 +19,9 @@
"config_flow": true, "config_flow": true,
"dependencies": ["bluetooth_adapters"], "dependencies": ["bluetooth_adapters"],
"dhcp": [ "dhcp": [
{
"registered_devices": true
},
{ {
"hostname": "gs[0-9][0-9][0-9][0-9][0-9][0-9]" "hostname": "gs[0-9][0-9][0-9][0-9][0-9][0-9]"
}, },

View File

@ -49,7 +49,7 @@ rules:
# Gold # Gold
devices: done devices: done
diagnostics: done diagnostics: done
discovery-update-info: todo discovery-update-info: done
discovery: discovery:
status: done status: done
comment: | comment: |

View File

@ -276,6 +276,10 @@ DHCP: Final[list[dict[str, str | bool]]] = [
"hostname": "polisy*", "hostname": "polisy*",
"macaddress": "000DB9*", "macaddress": "000DB9*",
}, },
{
"domain": "lamarzocco",
"registered_devices": True,
},
{ {
"domain": "lamarzocco", "domain": "lamarzocco",
"hostname": "gs[0-9][0-9][0-9][0-9][0-9][0-9]", "hostname": "gs[0-9][0-9][0-9][0-9][0-9][0-9]",

View File

@ -11,7 +11,13 @@ from pylamarzocco.models import LaMarzoccoDeviceInfo
import pytest import pytest
from homeassistant.components.lamarzocco.const import DOMAIN from homeassistant.components.lamarzocco.const import DOMAIN
from homeassistant.const import CONF_HOST, CONF_MODEL, CONF_NAME, CONF_TOKEN from homeassistant.const import (
CONF_ADDRESS,
CONF_HOST,
CONF_MODEL,
CONF_NAME,
CONF_TOKEN,
)
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from . import SERIAL_DICT, USER_INPUT, async_init_integration from . import SERIAL_DICT, USER_INPUT, async_init_integration
@ -40,6 +46,7 @@ def mock_config_entry(
data=USER_INPUT data=USER_INPUT
| { | {
CONF_MODEL: mock_lamarzocco.model, CONF_MODEL: mock_lamarzocco.model,
CONF_ADDRESS: "00:00:00:00:00:00",
CONF_HOST: "host", CONF_HOST: "host",
CONF_TOKEN: "token", CONF_TOKEN: "token",
CONF_NAME: "GS3", CONF_NAME: "GS3",

View File

@ -97,6 +97,10 @@
'config_entries': <ANY>, 'config_entries': <ANY>,
'configuration_url': None, 'configuration_url': None,
'connections': set({ 'connections': set({
tuple(
'mac',
'00:00:00:00:00:00',
),
}), }),
'disabled_by': None, 'disabled_by': None,
'entry_type': None, 'entry_type': None,

View File

@ -18,6 +18,7 @@ from homeassistant.config_entries import (
ConfigEntryState, ConfigEntryState,
) )
from homeassistant.const import ( from homeassistant.const import (
CONF_ADDRESS,
CONF_HOST, CONF_HOST,
CONF_MAC, CONF_MAC,
CONF_MODEL, CONF_MODEL,
@ -483,6 +484,7 @@ async def test_dhcp_discovery(
assert result2["type"] is FlowResultType.CREATE_ENTRY assert result2["type"] is FlowResultType.CREATE_ENTRY
assert result2["data"] == { assert result2["data"] == {
**USER_INPUT, **USER_INPUT,
CONF_ADDRESS: "aa:bb:cc:dd:ee:ff",
CONF_HOST: "192.168.1.42", CONF_HOST: "192.168.1.42",
CONF_MACHINE: mock_lamarzocco.serial_number, CONF_MACHINE: mock_lamarzocco.serial_number,
CONF_MODEL: mock_device_info.model, CONF_MODEL: mock_device_info.model,
@ -491,6 +493,36 @@ async def test_dhcp_discovery(
} }
async def test_dhcp_already_configured_and_update(
hass: HomeAssistant,
mock_lamarzocco: MagicMock,
mock_cloud_client: MagicMock,
mock_config_entry: MockConfigEntry,
) -> None:
"""Test discovered IP address change."""
old_ip = mock_config_entry.data[CONF_HOST]
old_address = mock_config_entry.data[CONF_ADDRESS]
mock_config_entry.add_to_hass(hass)
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": SOURCE_DHCP},
data=DhcpServiceInfo(
ip="192.168.1.42",
hostname=mock_lamarzocco.serial_number,
macaddress="aa:bb:cc:dd:ee:ff",
),
)
assert result["type"] is FlowResultType.ABORT
assert result["reason"] == "already_configured"
assert mock_config_entry.data[CONF_HOST] != old_ip
assert mock_config_entry.data[CONF_HOST] == "192.168.1.42"
assert mock_config_entry.data[CONF_ADDRESS] != old_address
assert mock_config_entry.data[CONF_ADDRESS] == "aa:bb:cc:dd:ee:ff"
async def test_options_flow( async def test_options_flow(
hass: HomeAssistant, hass: HomeAssistant,
mock_lamarzocco: MagicMock, mock_lamarzocco: MagicMock,

View File

@ -10,7 +10,14 @@ from websockets.protocol import State
from homeassistant.components.lamarzocco.config_flow import CONF_MACHINE from homeassistant.components.lamarzocco.config_flow import CONF_MACHINE
from homeassistant.components.lamarzocco.const import DOMAIN from homeassistant.components.lamarzocco.const import DOMAIN
from homeassistant.config_entries import SOURCE_REAUTH, ConfigEntryState from homeassistant.config_entries import SOURCE_REAUTH, ConfigEntryState
from homeassistant.const import CONF_HOST, CONF_MAC, CONF_NAME, EVENT_HOMEASSISTANT_STOP from homeassistant.const import (
CONF_HOST,
CONF_MAC,
CONF_MODEL,
CONF_NAME,
CONF_TOKEN,
EVENT_HOMEASSISTANT_STOP,
)
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.helpers import issue_registry as ir from homeassistant.helpers import issue_registry as ir
@ -81,20 +88,22 @@ async def test_invalid_auth(
async def test_v1_migration( async def test_v1_migration(
hass: HomeAssistant, hass: HomeAssistant,
mock_config_entry: MockConfigEntry,
mock_cloud_client: MagicMock, mock_cloud_client: MagicMock,
mock_lamarzocco: MagicMock, mock_lamarzocco: MagicMock,
) -> None: ) -> None:
"""Test v1 -> v2 Migration.""" """Test v1 -> v2 Migration."""
common_data = {
**USER_INPUT,
CONF_HOST: "host",
CONF_MAC: "aa:bb:cc:dd:ee:ff",
}
entry_v1 = MockConfigEntry( entry_v1 = MockConfigEntry(
domain=DOMAIN, domain=DOMAIN,
version=1, version=1,
unique_id=mock_lamarzocco.serial_number, unique_id=mock_lamarzocco.serial_number,
data={ data={
**USER_INPUT, **common_data,
CONF_HOST: "host",
CONF_MACHINE: mock_lamarzocco.serial_number, CONF_MACHINE: mock_lamarzocco.serial_number,
CONF_MAC: "aa:bb:cc:dd:ee:ff",
}, },
) )
@ -103,8 +112,11 @@ async def test_v1_migration(
await hass.async_block_till_done() await hass.async_block_till_done()
assert entry_v1.version == 2 assert entry_v1.version == 2
assert dict(entry_v1.data) == dict(mock_config_entry.data) | { assert dict(entry_v1.data) == {
CONF_MAC: "aa:bb:cc:dd:ee:ff" **common_data,
CONF_NAME: "GS3",
CONF_MODEL: mock_lamarzocco.model,
CONF_TOKEN: "token",
} }