Add DHCP discovery to lamarzocco (#129675)

* Add DHCP discovery to lamarzocco

* ensure serial is upper

* shorten pattern

* parametrize across models
pull/129724/head^2
Josef Zweck 2024-11-03 09:44:35 +01:00 committed by GitHub
parent ed3376352d
commit eddab96a69
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 109 additions and 4 deletions

View File

@ -14,6 +14,7 @@ from homeassistant.components.bluetooth import (
BluetoothServiceInfo,
async_discovered_service_info,
)
from homeassistant.components.dhcp import DhcpServiceInfo
from homeassistant.config_entries import (
SOURCE_REAUTH,
SOURCE_RECONFIGURE,
@ -103,6 +104,15 @@ class LmConfigFlow(ConfigFlow, domain=DOMAIN):
errors["base"] = "machine_not_found"
else:
self._config = data
# if DHCP discovery was used, auto fill machine selection
if CONF_HOST in self._discovered:
return await self.async_step_machine_selection(
user_input={
CONF_HOST: self._discovered[CONF_HOST],
CONF_MACHINE: self._discovered[CONF_MACHINE],
}
)
# if Bluetooth discovery was used, only select host
return self.async_show_form(
step_id="machine_selection",
data_schema=vol.Schema(
@ -258,6 +268,27 @@ class LmConfigFlow(ConfigFlow, domain=DOMAIN):
return await self.async_step_user()
async def async_step_dhcp(
self, discovery_info: DhcpServiceInfo
) -> ConfigFlowResult:
"""Handle discovery via dhcp."""
serial = discovery_info.hostname.upper()
await self.async_set_unique_id(serial)
self._abort_if_unique_id_configured()
_LOGGER.debug(
"Discovered La Marzocco machine %s through DHCP at address %s",
discovery_info.hostname,
discovery_info.ip,
)
self._discovered[CONF_MACHINE] = serial
self._discovered[CONF_HOST] = discovery_info.ip
return await self.async_step_user()
async def async_step_reauth(
self, entry_data: Mapping[str, Any]
) -> ConfigFlowResult:

View File

@ -18,6 +18,17 @@
"codeowners": ["@zweckj"],
"config_flow": true,
"dependencies": ["bluetooth_adapters"],
"dhcp": [
{
"hostname": "gs[0-9][0-9][0-9][0-9][0-9][0-9]"
},
{
"hostname": "lm[0-9][0-9][0-9][0-9][0-9][0-9]"
},
{
"hostname": "mr[0-9][0-9][0-9][0-9][0-9][0-9]"
}
],
"documentation": "https://www.home-assistant.io/integrations/lamarzocco",
"integration_type": "device",
"iot_class": "cloud_polling",

View File

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

View File

@ -75,11 +75,11 @@ def device_fixture() -> MachineModel:
@pytest.fixture
def mock_device_info() -> LaMarzoccoDeviceInfo:
def mock_device_info(device_fixture: MachineModel) -> LaMarzoccoDeviceInfo:
"""Return a mocked La Marzocco device info."""
return LaMarzoccoDeviceInfo(
model=MachineModel.GS3_AV,
serial_number="GS01234",
model=device_fixture,
serial_number=SERIAL_DICT[device_fixture],
name="GS3",
communication_key="token",
)

View File

@ -2,13 +2,20 @@
from unittest.mock import MagicMock, patch
from lmcloud.const import MachineModel
from lmcloud.exceptions import AuthFail, RequestNotSuccessful
from lmcloud.models import LaMarzoccoDeviceInfo
import pytest
from homeassistant.components.dhcp import DhcpServiceInfo
from homeassistant.components.lamarzocco.config_flow import CONF_MACHINE
from homeassistant.components.lamarzocco.const import CONF_USE_BLUETOOTH, DOMAIN
from homeassistant.config_entries import SOURCE_BLUETOOTH, SOURCE_USER, ConfigEntryState
from homeassistant.config_entries import (
SOURCE_BLUETOOTH,
SOURCE_DHCP,
SOURCE_USER,
ConfigEntryState,
)
from homeassistant.const import (
CONF_HOST,
CONF_MAC,
@ -435,6 +442,50 @@ async def test_bluetooth_discovery_errors(
}
@pytest.mark.parametrize(
"device_fixture",
[MachineModel.LINEA_MICRA, MachineModel.LINEA_MINI, MachineModel.GS3_AV],
)
async def test_dhcp_discovery(
hass: HomeAssistant,
mock_lamarzocco: MagicMock,
mock_cloud_client: MagicMock,
mock_device_info: LaMarzoccoDeviceInfo,
) -> None:
"""Test dhcp discovery."""
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.FORM
assert result["step_id"] == "user"
with patch(
"homeassistant.components.lamarzocco.config_flow.LaMarzoccoLocalClient.validate_connection",
return_value=True,
):
result2 = await hass.config_entries.flow.async_configure(
result["flow_id"],
USER_INPUT,
)
assert result2["type"] is FlowResultType.CREATE_ENTRY
assert result2["data"] == {
**USER_INPUT,
CONF_HOST: "192.168.1.42",
CONF_MACHINE: mock_lamarzocco.serial_number,
CONF_MODEL: mock_device_info.model,
CONF_NAME: mock_device_info.name,
CONF_TOKEN: mock_device_info.communication_key,
}
async def test_options_flow(
hass: HomeAssistant,
mock_lamarzocco: MagicMock,