mirror of
https://github.com/home-assistant/core.git
synced 2025-07-20 03:37:07 +00:00
Fix issues with bosch alarm dhcp discovery (#145034)
* fix issues with checking mac address for panels added manually * add test * don't allow discovery to pick up a host twice * make sure we validate tests without a mac address * check entry is loaded * Update config_flow.py * apply changes from review * assert unique id * assert unique id
This commit is contained in:
parent
f3f5fca0b9
commit
1ff5dd8ef5
@ -15,6 +15,7 @@ from homeassistant.config_entries import (
|
|||||||
SOURCE_DHCP,
|
SOURCE_DHCP,
|
||||||
SOURCE_RECONFIGURE,
|
SOURCE_RECONFIGURE,
|
||||||
SOURCE_USER,
|
SOURCE_USER,
|
||||||
|
ConfigEntryState,
|
||||||
ConfigFlow,
|
ConfigFlow,
|
||||||
ConfigFlowResult,
|
ConfigFlowResult,
|
||||||
)
|
)
|
||||||
@ -152,7 +153,7 @@ class BoschAlarmConfigFlow(ConfigFlow, domain=DOMAIN):
|
|||||||
return self.async_abort(reason="already_in_progress")
|
return self.async_abort(reason="already_in_progress")
|
||||||
|
|
||||||
for entry in self.hass.config_entries.async_entries(DOMAIN):
|
for entry in self.hass.config_entries.async_entries(DOMAIN):
|
||||||
if entry.data[CONF_MAC] == self.mac:
|
if entry.data.get(CONF_MAC) == self.mac:
|
||||||
result = self.hass.config_entries.async_update_entry(
|
result = self.hass.config_entries.async_update_entry(
|
||||||
entry,
|
entry,
|
||||||
data={
|
data={
|
||||||
@ -163,6 +164,21 @@ class BoschAlarmConfigFlow(ConfigFlow, domain=DOMAIN):
|
|||||||
if result:
|
if result:
|
||||||
self.hass.config_entries.async_schedule_reload(entry.entry_id)
|
self.hass.config_entries.async_schedule_reload(entry.entry_id)
|
||||||
return self.async_abort(reason="already_configured")
|
return self.async_abort(reason="already_configured")
|
||||||
|
if entry.data[CONF_HOST] == discovery_info.ip:
|
||||||
|
if (
|
||||||
|
not entry.data.get(CONF_MAC)
|
||||||
|
and entry.state is ConfigEntryState.LOADED
|
||||||
|
):
|
||||||
|
result = self.hass.config_entries.async_update_entry(
|
||||||
|
entry,
|
||||||
|
data={
|
||||||
|
**entry.data,
|
||||||
|
CONF_MAC: self.mac,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
if result:
|
||||||
|
self.hass.config_entries.async_schedule_reload(entry.entry_id)
|
||||||
|
return self.async_abort(reason="already_configured")
|
||||||
try:
|
try:
|
||||||
# Use load_selector = 0 to fetch the panel model without authentication.
|
# Use load_selector = 0 to fetch the panel model without authentication.
|
||||||
(model, _) = await try_connect(
|
(model, _) = await try_connect(
|
||||||
|
@ -201,15 +201,16 @@ def mock_config_entry(
|
|||||||
mac_address: str | None,
|
mac_address: str | None,
|
||||||
) -> MockConfigEntry:
|
) -> MockConfigEntry:
|
||||||
"""Mock config entry for bosch alarm."""
|
"""Mock config entry for bosch alarm."""
|
||||||
|
data = {
|
||||||
|
CONF_HOST: "0.0.0.0",
|
||||||
|
CONF_PORT: 7700,
|
||||||
|
CONF_MODEL: "bosch_alarm_test_data.model",
|
||||||
|
}
|
||||||
|
if mac_address:
|
||||||
|
data[CONF_MAC] = format_mac(mac_address)
|
||||||
return MockConfigEntry(
|
return MockConfigEntry(
|
||||||
domain=DOMAIN,
|
domain=DOMAIN,
|
||||||
unique_id=serial_number,
|
unique_id=serial_number,
|
||||||
entry_id="01JQ917ACKQ33HHM7YCFXYZX51",
|
entry_id="01JQ917ACKQ33HHM7YCFXYZX51",
|
||||||
data={
|
data=data | extra_config_entry_data,
|
||||||
CONF_HOST: "0.0.0.0",
|
|
||||||
CONF_PORT: 7700,
|
|
||||||
CONF_MODEL: "bosch_alarm_test_data.model",
|
|
||||||
CONF_MAC: mac_address and format_mac(mac_address),
|
|
||||||
}
|
|
||||||
| extra_config_entry_data,
|
|
||||||
)
|
)
|
||||||
|
@ -89,7 +89,6 @@
|
|||||||
'entry_data': dict({
|
'entry_data': dict({
|
||||||
'host': '0.0.0.0',
|
'host': '0.0.0.0',
|
||||||
'installer_code': '**REDACTED**',
|
'installer_code': '**REDACTED**',
|
||||||
'mac': None,
|
|
||||||
'model': 'AMAX 3000',
|
'model': 'AMAX 3000',
|
||||||
'password': '**REDACTED**',
|
'password': '**REDACTED**',
|
||||||
'port': 7700,
|
'port': 7700,
|
||||||
@ -185,7 +184,6 @@
|
|||||||
}),
|
}),
|
||||||
'entry_data': dict({
|
'entry_data': dict({
|
||||||
'host': '0.0.0.0',
|
'host': '0.0.0.0',
|
||||||
'mac': None,
|
|
||||||
'model': 'B5512 (US1B)',
|
'model': 'B5512 (US1B)',
|
||||||
'password': '**REDACTED**',
|
'password': '**REDACTED**',
|
||||||
'port': 7700,
|
'port': 7700,
|
||||||
@ -281,7 +279,6 @@
|
|||||||
}),
|
}),
|
||||||
'entry_data': dict({
|
'entry_data': dict({
|
||||||
'host': '0.0.0.0',
|
'host': '0.0.0.0',
|
||||||
'mac': None,
|
|
||||||
'model': 'Solution 3000',
|
'model': 'Solution 3000',
|
||||||
'port': 7700,
|
'port': 7700,
|
||||||
'user_code': '**REDACTED**',
|
'user_code': '**REDACTED**',
|
||||||
|
@ -309,6 +309,55 @@ async def test_dhcp_updates_host(
|
|||||||
assert mock_config_entry.data[CONF_HOST] == "4.5.6.7"
|
assert mock_config_entry.data[CONF_HOST] == "4.5.6.7"
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("serial_number", ["12345678"])
|
||||||
|
async def test_dhcp_discovery_if_panel_setup_config_flow(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
mock_setup_entry: AsyncMock,
|
||||||
|
mock_config_entry: MockConfigEntry,
|
||||||
|
mock_panel: AsyncMock,
|
||||||
|
serial_number: str,
|
||||||
|
model_name: str,
|
||||||
|
config_flow_data: dict[str, Any],
|
||||||
|
) -> None:
|
||||||
|
"""Test DHCP discovery doesn't fail if a different panel was set up via config flow."""
|
||||||
|
await setup_integration(hass, mock_config_entry)
|
||||||
|
|
||||||
|
# change out the serial number so we can test discovery for a different panel
|
||||||
|
mock_panel.serial_number = "789101112"
|
||||||
|
result = await hass.config_entries.flow.async_init(
|
||||||
|
DOMAIN,
|
||||||
|
context={"source": SOURCE_DHCP},
|
||||||
|
data=DhcpServiceInfo(
|
||||||
|
hostname="test",
|
||||||
|
ip="4.5.6.7",
|
||||||
|
macaddress="34ea34b43b5a",
|
||||||
|
),
|
||||||
|
)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
assert result["type"] is FlowResultType.FORM
|
||||||
|
assert result["step_id"] == "auth"
|
||||||
|
assert result["errors"] == {}
|
||||||
|
result = await hass.config_entries.flow.async_configure(
|
||||||
|
result["flow_id"],
|
||||||
|
config_flow_data,
|
||||||
|
)
|
||||||
|
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
assert result["type"] is FlowResultType.CREATE_ENTRY
|
||||||
|
assert result["title"] == f"Bosch {model_name}"
|
||||||
|
assert result["data"] == {
|
||||||
|
CONF_HOST: "4.5.6.7",
|
||||||
|
CONF_MAC: "34:ea:34:b4:3b:5a",
|
||||||
|
CONF_PORT: 7700,
|
||||||
|
CONF_MODEL: model_name,
|
||||||
|
**config_flow_data,
|
||||||
|
}
|
||||||
|
assert mock_config_entry.unique_id == serial_number
|
||||||
|
assert result["result"].unique_id == "789101112"
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("model", ["solution_3000", "amax_3000"])
|
@pytest.mark.parametrize("model", ["solution_3000", "amax_3000"])
|
||||||
async def test_dhcp_abort_ongoing_flow(
|
async def test_dhcp_abort_ongoing_flow(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
@ -341,6 +390,35 @@ async def test_dhcp_abort_ongoing_flow(
|
|||||||
assert result["reason"] == "already_in_progress"
|
assert result["reason"] == "already_in_progress"
|
||||||
|
|
||||||
|
|
||||||
|
async def test_dhcp_updates_mac(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
mock_setup_entry: AsyncMock,
|
||||||
|
mock_config_entry: MockConfigEntry,
|
||||||
|
mock_panel: AsyncMock,
|
||||||
|
model_name: str,
|
||||||
|
serial_number: str,
|
||||||
|
config_flow_data: dict[str, Any],
|
||||||
|
) -> None:
|
||||||
|
"""Test DHCP discovery flow updates mac if the previous entry did not have a mac address."""
|
||||||
|
await setup_integration(hass, mock_config_entry)
|
||||||
|
assert CONF_MAC not in mock_config_entry.data
|
||||||
|
|
||||||
|
result = await hass.config_entries.flow.async_init(
|
||||||
|
DOMAIN,
|
||||||
|
context={"source": SOURCE_DHCP},
|
||||||
|
data=DhcpServiceInfo(
|
||||||
|
hostname="test",
|
||||||
|
ip="0.0.0.0",
|
||||||
|
macaddress="34ea34b43b5a",
|
||||||
|
),
|
||||||
|
)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
assert result["type"] is FlowResultType.ABORT
|
||||||
|
assert result["reason"] == "already_configured"
|
||||||
|
assert mock_config_entry.data[CONF_MAC] == "34:ea:34:b4:3b:5a"
|
||||||
|
|
||||||
|
|
||||||
async def test_reauth_flow_success(
|
async def test_reauth_flow_success(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
mock_setup_entry: AsyncMock,
|
mock_setup_entry: AsyncMock,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user