Add DHCP discovery to lamarzocco (#129675)
* Add DHCP discovery to lamarzocco * ensure serial is upper * shorten pattern * parametrize across modelspull/129724/head^2
parent
ed3376352d
commit
eddab96a69
|
@ -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:
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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",
|
||||
)
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue