mirror of
https://github.com/home-assistant/core.git
synced 2025-07-23 05:07:41 +00:00
Add DHCP discovery flow to bosch_alarm (#142250)
* Add dhcp discovery * Update homeassistant/components/bosch_alarm/config_flow.py Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com> * put mac address in entry instead of unique id * Update host and mac via dhcp discovery * add mac to connections * Abort dhcp flow if there is already an ongoing flow * apply changes from review * apply change from review * remove outdated test * fix snapshots * apply change from review * clean definition for connections * update quality scale --------- Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
This commit is contained in:
parent
270780ef5f
commit
9bbc49e842
@ -7,10 +7,11 @@ from ssl import SSLError
|
||||
from bosch_alarm_mode2 import Panel
|
||||
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import CONF_HOST, CONF_PASSWORD, CONF_PORT, Platform
|
||||
from homeassistant.const import CONF_HOST, CONF_MAC, CONF_PASSWORD, CONF_PORT, Platform
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.exceptions import ConfigEntryAuthFailed, ConfigEntryNotReady
|
||||
from homeassistant.helpers import device_registry as dr
|
||||
from homeassistant.helpers.device_registry import CONNECTION_NETWORK_MAC
|
||||
|
||||
from .const import CONF_INSTALLER_CODE, CONF_USER_CODE, DOMAIN
|
||||
|
||||
@ -53,8 +54,11 @@ async def async_setup_entry(hass: HomeAssistant, entry: BoschAlarmConfigEntry) -
|
||||
|
||||
device_registry = dr.async_get(hass)
|
||||
|
||||
mac = entry.data.get(CONF_MAC)
|
||||
|
||||
device_registry.async_get_or_create(
|
||||
config_entry_id=entry.entry_id,
|
||||
connections={(CONNECTION_NETWORK_MAC, mac)} if mac else set(),
|
||||
identifiers={(DOMAIN, entry.unique_id or entry.entry_id)},
|
||||
name=f"Bosch {panel.model}",
|
||||
manufacturer="Bosch Security Systems",
|
||||
|
@ -6,12 +6,13 @@ import asyncio
|
||||
from collections.abc import Mapping
|
||||
import logging
|
||||
import ssl
|
||||
from typing import Any
|
||||
from typing import Any, Self
|
||||
|
||||
from bosch_alarm_mode2 import Panel
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.config_entries import (
|
||||
SOURCE_DHCP,
|
||||
SOURCE_RECONFIGURE,
|
||||
SOURCE_USER,
|
||||
ConfigFlow,
|
||||
@ -20,11 +21,14 @@ from homeassistant.config_entries import (
|
||||
from homeassistant.const import (
|
||||
CONF_CODE,
|
||||
CONF_HOST,
|
||||
CONF_MAC,
|
||||
CONF_MODEL,
|
||||
CONF_PASSWORD,
|
||||
CONF_PORT,
|
||||
)
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
from homeassistant.helpers.device_registry import format_mac
|
||||
from homeassistant.helpers.service_info.dhcp import DhcpServiceInfo
|
||||
|
||||
from .const import CONF_INSTALLER_CODE, CONF_USER_CODE, DOMAIN
|
||||
|
||||
@ -88,6 +92,12 @@ class BoschAlarmConfigFlow(ConfigFlow, domain=DOMAIN):
|
||||
"""Init config flow."""
|
||||
|
||||
self._data: dict[str, Any] = {}
|
||||
self.mac: str | None = None
|
||||
self.host: str | None = None
|
||||
|
||||
def is_matching(self, other_flow: Self) -> bool:
|
||||
"""Return True if other_flow is matching this flow."""
|
||||
return self.mac == other_flow.mac or self.host == other_flow.host
|
||||
|
||||
async def async_step_user(
|
||||
self, user_input: dict[str, Any] | None = None
|
||||
@ -96,9 +106,12 @@ class BoschAlarmConfigFlow(ConfigFlow, domain=DOMAIN):
|
||||
errors: dict[str, str] = {}
|
||||
|
||||
if user_input is not None:
|
||||
self.host = user_input[CONF_HOST]
|
||||
if self.source == SOURCE_USER:
|
||||
self._async_abort_entries_match({CONF_HOST: user_input[CONF_HOST]})
|
||||
try:
|
||||
# Use load_selector = 0 to fetch the panel model without authentication.
|
||||
(model, serial) = await try_connect(user_input, 0)
|
||||
(model, _) = await try_connect(user_input, 0)
|
||||
except (
|
||||
OSError,
|
||||
ConnectionRefusedError,
|
||||
@ -129,6 +142,55 @@ class BoschAlarmConfigFlow(ConfigFlow, domain=DOMAIN):
|
||||
errors=errors,
|
||||
)
|
||||
|
||||
async def async_step_dhcp(
|
||||
self, discovery_info: DhcpServiceInfo
|
||||
) -> ConfigFlowResult:
|
||||
"""Handle DHCP discovery."""
|
||||
self.mac = format_mac(discovery_info.macaddress)
|
||||
self.host = discovery_info.ip
|
||||
if self.hass.config_entries.flow.async_has_matching_flow(self):
|
||||
return self.async_abort(reason="already_in_progress")
|
||||
|
||||
for entry in self.hass.config_entries.async_entries(DOMAIN):
|
||||
if entry.data[CONF_MAC] == self.mac:
|
||||
result = self.hass.config_entries.async_update_entry(
|
||||
entry,
|
||||
data={
|
||||
**entry.data,
|
||||
CONF_HOST: discovery_info.ip,
|
||||
},
|
||||
)
|
||||
if result:
|
||||
self.hass.config_entries.async_schedule_reload(entry.entry_id)
|
||||
return self.async_abort(reason="already_configured")
|
||||
try:
|
||||
# Use load_selector = 0 to fetch the panel model without authentication.
|
||||
(model, _) = await try_connect(
|
||||
{CONF_HOST: discovery_info.ip, CONF_PORT: 7700}, 0
|
||||
)
|
||||
except (
|
||||
OSError,
|
||||
ConnectionRefusedError,
|
||||
ssl.SSLError,
|
||||
asyncio.exceptions.TimeoutError,
|
||||
):
|
||||
return self.async_abort(reason="cannot_connect")
|
||||
except Exception:
|
||||
_LOGGER.exception("Unexpected exception")
|
||||
return self.async_abort(reason="unknown")
|
||||
self.context["title_placeholders"] = {
|
||||
"model": model,
|
||||
"host": discovery_info.ip,
|
||||
}
|
||||
self._data = {
|
||||
CONF_HOST: discovery_info.ip,
|
||||
CONF_MAC: self.mac,
|
||||
CONF_MODEL: model,
|
||||
CONF_PORT: 7700,
|
||||
}
|
||||
|
||||
return await self.async_step_auth()
|
||||
|
||||
async def async_step_reconfigure(
|
||||
self, user_input: dict[str, Any] | None = None
|
||||
) -> ConfigFlowResult:
|
||||
@ -172,7 +234,7 @@ class BoschAlarmConfigFlow(ConfigFlow, domain=DOMAIN):
|
||||
else:
|
||||
if serial_number:
|
||||
await self.async_set_unique_id(str(serial_number))
|
||||
if self.source == SOURCE_USER:
|
||||
if self.source in (SOURCE_USER, SOURCE_DHCP):
|
||||
if serial_number:
|
||||
self._abort_if_unique_id_configured()
|
||||
else:
|
||||
@ -184,6 +246,7 @@ class BoschAlarmConfigFlow(ConfigFlow, domain=DOMAIN):
|
||||
)
|
||||
if serial_number:
|
||||
self._abort_if_unique_id_mismatch(reason="device_mismatch")
|
||||
|
||||
return self.async_update_reload_and_abort(
|
||||
self._get_reconfigure_entry(),
|
||||
data=self._data,
|
||||
|
@ -3,6 +3,11 @@
|
||||
"name": "Bosch Alarm",
|
||||
"codeowners": ["@mag1024", "@sanjay900"],
|
||||
"config_flow": true,
|
||||
"dhcp": [
|
||||
{
|
||||
"macaddress": "000463*"
|
||||
}
|
||||
],
|
||||
"documentation": "https://www.home-assistant.io/integrations/bosch_alarm",
|
||||
"integration_type": "device",
|
||||
"iot_class": "local_push",
|
||||
|
@ -46,8 +46,8 @@ rules:
|
||||
# Gold
|
||||
devices: done
|
||||
diagnostics: todo
|
||||
discovery-update-info: todo
|
||||
discovery: todo
|
||||
discovery-update-info: done
|
||||
discovery: done
|
||||
docs-data-update: todo
|
||||
docs-examples: todo
|
||||
docs-known-limitations: todo
|
||||
|
@ -1,5 +1,6 @@
|
||||
{
|
||||
"config": {
|
||||
"flow_title": "{model} ({host})",
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
@ -42,6 +43,7 @@
|
||||
"unknown": "[%key:common::config_flow::error::unknown%]"
|
||||
},
|
||||
"abort": {
|
||||
"already_in_progress": "[%key:common::config_flow::abort::already_in_progress%]",
|
||||
"already_configured": "[%key:common::config_flow::abort::already_configured_device%]",
|
||||
"reauth_successful": "[%key:common::config_flow::abort::reauth_successful%]",
|
||||
"reconfigure_successful": "[%key:common::config_flow::abort::reconfigure_successful%]",
|
||||
|
4
homeassistant/generated/dhcp.py
generated
4
homeassistant/generated/dhcp.py
generated
@ -108,6 +108,10 @@ DHCP: Final[list[dict[str, str | bool]]] = [
|
||||
"hostname": "bond-*",
|
||||
"macaddress": "F44E38*",
|
||||
},
|
||||
{
|
||||
"domain": "bosch_alarm",
|
||||
"macaddress": "000463*",
|
||||
},
|
||||
{
|
||||
"domain": "broadlink",
|
||||
"registered_devices": True,
|
||||
|
@ -13,7 +13,14 @@ from homeassistant.components.bosch_alarm.const import (
|
||||
CONF_USER_CODE,
|
||||
DOMAIN,
|
||||
)
|
||||
from homeassistant.const import CONF_HOST, CONF_MODEL, CONF_PASSWORD, CONF_PORT
|
||||
from homeassistant.const import (
|
||||
CONF_HOST,
|
||||
CONF_MAC,
|
||||
CONF_MODEL,
|
||||
CONF_PASSWORD,
|
||||
CONF_PORT,
|
||||
)
|
||||
from homeassistant.helpers.device_registry import format_mac
|
||||
|
||||
from tests.common import MockConfigEntry
|
||||
|
||||
@ -38,6 +45,12 @@ def extra_config_entry_data(
|
||||
return {CONF_MODEL: model_name} | config_flow_data
|
||||
|
||||
|
||||
@pytest.fixture(params=[None])
|
||||
def mac_address(request: pytest.FixtureRequest) -> str | None:
|
||||
"""Return entity mac address."""
|
||||
return request.param
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def config_flow_data(model: str) -> dict[str, Any]:
|
||||
"""Return extra config entry data."""
|
||||
@ -63,7 +76,7 @@ def model_name(model: str) -> str | None:
|
||||
@pytest.fixture
|
||||
def serial_number(model: str) -> str | None:
|
||||
"""Return extra config entry data."""
|
||||
if model == "solution_3000":
|
||||
if model == "b5512":
|
||||
return "1234567890"
|
||||
return None
|
||||
|
||||
@ -183,7 +196,9 @@ def mock_panel(
|
||||
|
||||
@pytest.fixture
|
||||
def mock_config_entry(
|
||||
extra_config_entry_data: dict[str, Any], serial_number: str | None
|
||||
extra_config_entry_data: dict[str, Any],
|
||||
serial_number: str | None,
|
||||
mac_address: str | None,
|
||||
) -> MockConfigEntry:
|
||||
"""Mock config entry for bosch alarm."""
|
||||
return MockConfigEntry(
|
||||
@ -194,6 +209,7 @@ def mock_config_entry(
|
||||
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,
|
||||
)
|
||||
|
@ -1,5 +1,5 @@
|
||||
# serializer version: 1
|
||||
# name: test_alarm_control_panel[amax_3000][alarm_control_panel.area1-entry]
|
||||
# name: test_alarm_control_panel[None-amax_3000][alarm_control_panel.area1-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
@ -33,7 +33,7 @@
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_alarm_control_panel[amax_3000][alarm_control_panel.area1-state]
|
||||
# name: test_alarm_control_panel[None-amax_3000][alarm_control_panel.area1-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'changed_by': None,
|
||||
@ -50,58 +50,7 @@
|
||||
'state': 'disarmed',
|
||||
})
|
||||
# ---
|
||||
# name: test_alarm_control_panel[b5512][alarm_control_panel.area1-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'alarm_control_panel',
|
||||
'entity_category': None,
|
||||
'entity_id': 'alarm_control_panel.area1',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': None,
|
||||
'original_name': None,
|
||||
'platform': 'bosch_alarm',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': <AlarmControlPanelEntityFeature: 3>,
|
||||
'translation_key': None,
|
||||
'unique_id': '01JQ917ACKQ33HHM7YCFXYZX51_area_1',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_alarm_control_panel[b5512][alarm_control_panel.area1-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'changed_by': None,
|
||||
'code_arm_required': False,
|
||||
'code_format': None,
|
||||
'friendly_name': 'Area1',
|
||||
'supported_features': <AlarmControlPanelEntityFeature: 3>,
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'alarm_control_panel.area1',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'disarmed',
|
||||
})
|
||||
# ---
|
||||
# name: test_alarm_control_panel[solution_3000][alarm_control_panel.area1-entry]
|
||||
# name: test_alarm_control_panel[None-b5512][alarm_control_panel.area1-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
@ -135,7 +84,58 @@
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_alarm_control_panel[solution_3000][alarm_control_panel.area1-state]
|
||||
# name: test_alarm_control_panel[None-b5512][alarm_control_panel.area1-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'changed_by': None,
|
||||
'code_arm_required': False,
|
||||
'code_format': None,
|
||||
'friendly_name': 'Area1',
|
||||
'supported_features': <AlarmControlPanelEntityFeature: 3>,
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'alarm_control_panel.area1',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'disarmed',
|
||||
})
|
||||
# ---
|
||||
# name: test_alarm_control_panel[None-solution_3000][alarm_control_panel.area1-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'alarm_control_panel',
|
||||
'entity_category': None,
|
||||
'entity_id': 'alarm_control_panel.area1',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': None,
|
||||
'original_name': None,
|
||||
'platform': 'bosch_alarm',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': <AlarmControlPanelEntityFeature: 3>,
|
||||
'translation_key': None,
|
||||
'unique_id': '01JQ917ACKQ33HHM7YCFXYZX51_area_1',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_alarm_control_panel[None-solution_3000][alarm_control_panel.area1-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'changed_by': None,
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,5 @@
|
||||
# serializer version: 1
|
||||
# name: test_diagnostics[amax_3000]
|
||||
# name: test_diagnostics[amax_3000-None]
|
||||
dict({
|
||||
'data': dict({
|
||||
'areas': list([
|
||||
@ -89,13 +89,14 @@
|
||||
'entry_data': dict({
|
||||
'host': '0.0.0.0',
|
||||
'installer_code': '**REDACTED**',
|
||||
'mac': None,
|
||||
'model': 'AMAX 3000',
|
||||
'password': '**REDACTED**',
|
||||
'port': 7700,
|
||||
}),
|
||||
})
|
||||
# ---
|
||||
# name: test_diagnostics[b5512]
|
||||
# name: test_diagnostics[b5512-None]
|
||||
dict({
|
||||
'data': dict({
|
||||
'areas': list([
|
||||
@ -180,105 +181,107 @@
|
||||
}),
|
||||
]),
|
||||
'protocol_version': '1.0.0',
|
||||
'serial_number': None,
|
||||
}),
|
||||
'entry_data': dict({
|
||||
'host': '0.0.0.0',
|
||||
'model': 'B5512 (US1B)',
|
||||
'password': '**REDACTED**',
|
||||
'port': 7700,
|
||||
}),
|
||||
})
|
||||
# ---
|
||||
# name: test_diagnostics[solution_3000]
|
||||
dict({
|
||||
'data': dict({
|
||||
'areas': list([
|
||||
dict({
|
||||
'alarms': list([
|
||||
]),
|
||||
'all_armed': False,
|
||||
'all_ready': True,
|
||||
'armed': False,
|
||||
'arming': False,
|
||||
'disarmed': True,
|
||||
'faults': 0,
|
||||
'id': 1,
|
||||
'name': 'Area1',
|
||||
'part_armed': False,
|
||||
'part_ready': True,
|
||||
'pending': False,
|
||||
'triggered': False,
|
||||
}),
|
||||
]),
|
||||
'doors': list([
|
||||
dict({
|
||||
'id': 1,
|
||||
'locked': True,
|
||||
'name': 'Main Door',
|
||||
'open': False,
|
||||
}),
|
||||
]),
|
||||
'firmware_version': '1.0.0',
|
||||
'history_events': list([
|
||||
]),
|
||||
'model': 'Solution 3000',
|
||||
'outputs': list([
|
||||
dict({
|
||||
'active': False,
|
||||
'id': 1,
|
||||
'name': 'Output A',
|
||||
}),
|
||||
]),
|
||||
'points': list([
|
||||
dict({
|
||||
'id': 0,
|
||||
'name': 'Window',
|
||||
'normal': True,
|
||||
'open': False,
|
||||
}),
|
||||
dict({
|
||||
'id': 1,
|
||||
'name': 'Door',
|
||||
'normal': True,
|
||||
'open': False,
|
||||
}),
|
||||
dict({
|
||||
'id': 2,
|
||||
'name': 'Motion Detector',
|
||||
'normal': True,
|
||||
'open': False,
|
||||
}),
|
||||
dict({
|
||||
'id': 3,
|
||||
'name': 'CO Detector',
|
||||
'normal': True,
|
||||
'open': False,
|
||||
}),
|
||||
dict({
|
||||
'id': 4,
|
||||
'name': 'Smoke Detector',
|
||||
'normal': True,
|
||||
'open': False,
|
||||
}),
|
||||
dict({
|
||||
'id': 5,
|
||||
'name': 'Glassbreak Sensor',
|
||||
'normal': True,
|
||||
'open': False,
|
||||
}),
|
||||
dict({
|
||||
'id': 6,
|
||||
'name': 'Bedroom',
|
||||
'normal': True,
|
||||
'open': False,
|
||||
}),
|
||||
]),
|
||||
'protocol_version': '1.0.0',
|
||||
'serial_number': '1234567890',
|
||||
}),
|
||||
'entry_data': dict({
|
||||
'host': '0.0.0.0',
|
||||
'mac': None,
|
||||
'model': 'B5512 (US1B)',
|
||||
'password': '**REDACTED**',
|
||||
'port': 7700,
|
||||
}),
|
||||
})
|
||||
# ---
|
||||
# name: test_diagnostics[solution_3000-None]
|
||||
dict({
|
||||
'data': dict({
|
||||
'areas': list([
|
||||
dict({
|
||||
'alarms': list([
|
||||
]),
|
||||
'all_armed': False,
|
||||
'all_ready': True,
|
||||
'armed': False,
|
||||
'arming': False,
|
||||
'disarmed': True,
|
||||
'faults': 0,
|
||||
'id': 1,
|
||||
'name': 'Area1',
|
||||
'part_armed': False,
|
||||
'part_ready': True,
|
||||
'pending': False,
|
||||
'triggered': False,
|
||||
}),
|
||||
]),
|
||||
'doors': list([
|
||||
dict({
|
||||
'id': 1,
|
||||
'locked': True,
|
||||
'name': 'Main Door',
|
||||
'open': False,
|
||||
}),
|
||||
]),
|
||||
'firmware_version': '1.0.0',
|
||||
'history_events': list([
|
||||
]),
|
||||
'model': 'Solution 3000',
|
||||
'outputs': list([
|
||||
dict({
|
||||
'active': False,
|
||||
'id': 1,
|
||||
'name': 'Output A',
|
||||
}),
|
||||
]),
|
||||
'points': list([
|
||||
dict({
|
||||
'id': 0,
|
||||
'name': 'Window',
|
||||
'normal': True,
|
||||
'open': False,
|
||||
}),
|
||||
dict({
|
||||
'id': 1,
|
||||
'name': 'Door',
|
||||
'normal': True,
|
||||
'open': False,
|
||||
}),
|
||||
dict({
|
||||
'id': 2,
|
||||
'name': 'Motion Detector',
|
||||
'normal': True,
|
||||
'open': False,
|
||||
}),
|
||||
dict({
|
||||
'id': 3,
|
||||
'name': 'CO Detector',
|
||||
'normal': True,
|
||||
'open': False,
|
||||
}),
|
||||
dict({
|
||||
'id': 4,
|
||||
'name': 'Smoke Detector',
|
||||
'normal': True,
|
||||
'open': False,
|
||||
}),
|
||||
dict({
|
||||
'id': 5,
|
||||
'name': 'Glassbreak Sensor',
|
||||
'normal': True,
|
||||
'open': False,
|
||||
}),
|
||||
dict({
|
||||
'id': 6,
|
||||
'name': 'Bedroom',
|
||||
'normal': True,
|
||||
'open': False,
|
||||
}),
|
||||
]),
|
||||
'protocol_version': '1.0.0',
|
||||
'serial_number': None,
|
||||
}),
|
||||
'entry_data': dict({
|
||||
'host': '0.0.0.0',
|
||||
'mac': None,
|
||||
'model': 'Solution 3000',
|
||||
'port': 7700,
|
||||
'user_code': '**REDACTED**',
|
||||
|
@ -1,5 +1,5 @@
|
||||
# serializer version: 1
|
||||
# name: test_sensor[amax_3000][sensor.area1_burglary_alarm_issues-entry]
|
||||
# name: test_sensor[None-amax_3000][sensor.area1_burglary_alarm_issues-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
@ -33,7 +33,7 @@
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_sensor[amax_3000][sensor.area1_burglary_alarm_issues-state]
|
||||
# name: test_sensor[None-amax_3000][sensor.area1_burglary_alarm_issues-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'friendly_name': 'Area1 Burglary alarm issues',
|
||||
@ -46,7 +46,7 @@
|
||||
'state': 'no_issues',
|
||||
})
|
||||
# ---
|
||||
# name: test_sensor[amax_3000][sensor.area1_faulting_points-entry]
|
||||
# name: test_sensor[None-amax_3000][sensor.area1_faulting_points-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
@ -80,7 +80,7 @@
|
||||
'unit_of_measurement': 'points',
|
||||
})
|
||||
# ---
|
||||
# name: test_sensor[amax_3000][sensor.area1_faulting_points-state]
|
||||
# name: test_sensor[None-amax_3000][sensor.area1_faulting_points-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'friendly_name': 'Area1 Faulting points',
|
||||
@ -94,7 +94,7 @@
|
||||
'state': '0',
|
||||
})
|
||||
# ---
|
||||
# name: test_sensor[amax_3000][sensor.area1_fire_alarm_issues-entry]
|
||||
# name: test_sensor[None-amax_3000][sensor.area1_fire_alarm_issues-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
@ -128,7 +128,7 @@
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_sensor[amax_3000][sensor.area1_fire_alarm_issues-state]
|
||||
# name: test_sensor[None-amax_3000][sensor.area1_fire_alarm_issues-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'friendly_name': 'Area1 Fire alarm issues',
|
||||
@ -141,7 +141,7 @@
|
||||
'state': 'no_issues',
|
||||
})
|
||||
# ---
|
||||
# name: test_sensor[amax_3000][sensor.area1_gas_alarm_issues-entry]
|
||||
# name: test_sensor[None-amax_3000][sensor.area1_gas_alarm_issues-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
@ -175,7 +175,7 @@
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_sensor[amax_3000][sensor.area1_gas_alarm_issues-state]
|
||||
# name: test_sensor[None-amax_3000][sensor.area1_gas_alarm_issues-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'friendly_name': 'Area1 Gas alarm issues',
|
||||
@ -188,196 +188,7 @@
|
||||
'state': 'no_issues',
|
||||
})
|
||||
# ---
|
||||
# name: test_sensor[b5512][sensor.area1_burglary_alarm_issues-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'sensor',
|
||||
'entity_category': None,
|
||||
'entity_id': 'sensor.area1_burglary_alarm_issues',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': None,
|
||||
'original_name': 'Burglary alarm issues',
|
||||
'platform': 'bosch_alarm',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'alarms_burglary',
|
||||
'unique_id': '01JQ917ACKQ33HHM7YCFXYZX51_area_1_alarms_burglary',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_sensor[b5512][sensor.area1_burglary_alarm_issues-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'friendly_name': 'Area1 Burglary alarm issues',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.area1_burglary_alarm_issues',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'no_issues',
|
||||
})
|
||||
# ---
|
||||
# name: test_sensor[b5512][sensor.area1_faulting_points-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'sensor',
|
||||
'entity_category': None,
|
||||
'entity_id': 'sensor.area1_faulting_points',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': None,
|
||||
'original_name': 'Faulting points',
|
||||
'platform': 'bosch_alarm',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'faulting_points',
|
||||
'unique_id': '01JQ917ACKQ33HHM7YCFXYZX51_area_1_faulting_points',
|
||||
'unit_of_measurement': 'points',
|
||||
})
|
||||
# ---
|
||||
# name: test_sensor[b5512][sensor.area1_faulting_points-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'friendly_name': 'Area1 Faulting points',
|
||||
'unit_of_measurement': 'points',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.area1_faulting_points',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': '0',
|
||||
})
|
||||
# ---
|
||||
# name: test_sensor[b5512][sensor.area1_fire_alarm_issues-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'sensor',
|
||||
'entity_category': None,
|
||||
'entity_id': 'sensor.area1_fire_alarm_issues',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': None,
|
||||
'original_name': 'Fire alarm issues',
|
||||
'platform': 'bosch_alarm',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'alarms_fire',
|
||||
'unique_id': '01JQ917ACKQ33HHM7YCFXYZX51_area_1_alarms_fire',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_sensor[b5512][sensor.area1_fire_alarm_issues-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'friendly_name': 'Area1 Fire alarm issues',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.area1_fire_alarm_issues',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'no_issues',
|
||||
})
|
||||
# ---
|
||||
# name: test_sensor[b5512][sensor.area1_gas_alarm_issues-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'sensor',
|
||||
'entity_category': None,
|
||||
'entity_id': 'sensor.area1_gas_alarm_issues',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': None,
|
||||
'original_name': 'Gas alarm issues',
|
||||
'platform': 'bosch_alarm',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'alarms_gas',
|
||||
'unique_id': '01JQ917ACKQ33HHM7YCFXYZX51_area_1_alarms_gas',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_sensor[b5512][sensor.area1_gas_alarm_issues-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'friendly_name': 'Area1 Gas alarm issues',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.area1_gas_alarm_issues',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'no_issues',
|
||||
})
|
||||
# ---
|
||||
# name: test_sensor[solution_3000][sensor.area1_burglary_alarm_issues-entry]
|
||||
# name: test_sensor[None-b5512][sensor.area1_burglary_alarm_issues-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
@ -411,7 +222,7 @@
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_sensor[solution_3000][sensor.area1_burglary_alarm_issues-state]
|
||||
# name: test_sensor[None-b5512][sensor.area1_burglary_alarm_issues-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'friendly_name': 'Area1 Burglary alarm issues',
|
||||
@ -424,7 +235,7 @@
|
||||
'state': 'no_issues',
|
||||
})
|
||||
# ---
|
||||
# name: test_sensor[solution_3000][sensor.area1_faulting_points-entry]
|
||||
# name: test_sensor[None-b5512][sensor.area1_faulting_points-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
@ -458,7 +269,7 @@
|
||||
'unit_of_measurement': 'points',
|
||||
})
|
||||
# ---
|
||||
# name: test_sensor[solution_3000][sensor.area1_faulting_points-state]
|
||||
# name: test_sensor[None-b5512][sensor.area1_faulting_points-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'friendly_name': 'Area1 Faulting points',
|
||||
@ -472,7 +283,7 @@
|
||||
'state': '0',
|
||||
})
|
||||
# ---
|
||||
# name: test_sensor[solution_3000][sensor.area1_fire_alarm_issues-entry]
|
||||
# name: test_sensor[None-b5512][sensor.area1_fire_alarm_issues-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
@ -506,7 +317,7 @@
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_sensor[solution_3000][sensor.area1_fire_alarm_issues-state]
|
||||
# name: test_sensor[None-b5512][sensor.area1_fire_alarm_issues-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'friendly_name': 'Area1 Fire alarm issues',
|
||||
@ -519,7 +330,7 @@
|
||||
'state': 'no_issues',
|
||||
})
|
||||
# ---
|
||||
# name: test_sensor[solution_3000][sensor.area1_gas_alarm_issues-entry]
|
||||
# name: test_sensor[None-b5512][sensor.area1_gas_alarm_issues-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
@ -553,7 +364,196 @@
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_sensor[solution_3000][sensor.area1_gas_alarm_issues-state]
|
||||
# name: test_sensor[None-b5512][sensor.area1_gas_alarm_issues-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'friendly_name': 'Area1 Gas alarm issues',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.area1_gas_alarm_issues',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'no_issues',
|
||||
})
|
||||
# ---
|
||||
# name: test_sensor[None-solution_3000][sensor.area1_burglary_alarm_issues-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'sensor',
|
||||
'entity_category': None,
|
||||
'entity_id': 'sensor.area1_burglary_alarm_issues',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': None,
|
||||
'original_name': 'Burglary alarm issues',
|
||||
'platform': 'bosch_alarm',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'alarms_burglary',
|
||||
'unique_id': '01JQ917ACKQ33HHM7YCFXYZX51_area_1_alarms_burglary',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_sensor[None-solution_3000][sensor.area1_burglary_alarm_issues-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'friendly_name': 'Area1 Burglary alarm issues',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.area1_burglary_alarm_issues',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'no_issues',
|
||||
})
|
||||
# ---
|
||||
# name: test_sensor[None-solution_3000][sensor.area1_faulting_points-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'sensor',
|
||||
'entity_category': None,
|
||||
'entity_id': 'sensor.area1_faulting_points',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': None,
|
||||
'original_name': 'Faulting points',
|
||||
'platform': 'bosch_alarm',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'faulting_points',
|
||||
'unique_id': '01JQ917ACKQ33HHM7YCFXYZX51_area_1_faulting_points',
|
||||
'unit_of_measurement': 'points',
|
||||
})
|
||||
# ---
|
||||
# name: test_sensor[None-solution_3000][sensor.area1_faulting_points-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'friendly_name': 'Area1 Faulting points',
|
||||
'unit_of_measurement': 'points',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.area1_faulting_points',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': '0',
|
||||
})
|
||||
# ---
|
||||
# name: test_sensor[None-solution_3000][sensor.area1_fire_alarm_issues-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'sensor',
|
||||
'entity_category': None,
|
||||
'entity_id': 'sensor.area1_fire_alarm_issues',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': None,
|
||||
'original_name': 'Fire alarm issues',
|
||||
'platform': 'bosch_alarm',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'alarms_fire',
|
||||
'unique_id': '01JQ917ACKQ33HHM7YCFXYZX51_area_1_alarms_fire',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_sensor[None-solution_3000][sensor.area1_fire_alarm_issues-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'friendly_name': 'Area1 Fire alarm issues',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.area1_fire_alarm_issues',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'no_issues',
|
||||
})
|
||||
# ---
|
||||
# name: test_sensor[None-solution_3000][sensor.area1_gas_alarm_issues-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'sensor',
|
||||
'entity_category': None,
|
||||
'entity_id': 'sensor.area1_gas_alarm_issues',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': None,
|
||||
'original_name': 'Gas alarm issues',
|
||||
'platform': 'bosch_alarm',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'alarms_gas',
|
||||
'unique_id': '01JQ917ACKQ33HHM7YCFXYZX51_area_1_alarms_gas',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_sensor[None-solution_3000][sensor.area1_gas_alarm_issues-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'friendly_name': 'Area1 Gas alarm issues',
|
||||
|
@ -1,5 +1,5 @@
|
||||
# serializer version: 1
|
||||
# name: test_switch[amax_3000][switch.main_door_cycling-entry]
|
||||
# name: test_switch[None-amax_3000][switch.main_door_cycling-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
@ -33,7 +33,7 @@
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_switch[amax_3000][switch.main_door_cycling-state]
|
||||
# name: test_switch[None-amax_3000][switch.main_door_cycling-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'friendly_name': 'Main Door Cycling',
|
||||
@ -46,7 +46,7 @@
|
||||
'state': 'off',
|
||||
})
|
||||
# ---
|
||||
# name: test_switch[amax_3000][switch.main_door_locked-entry]
|
||||
# name: test_switch[None-amax_3000][switch.main_door_locked-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
@ -80,7 +80,7 @@
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_switch[amax_3000][switch.main_door_locked-state]
|
||||
# name: test_switch[None-amax_3000][switch.main_door_locked-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'friendly_name': 'Main Door Locked',
|
||||
@ -93,7 +93,7 @@
|
||||
'state': 'on',
|
||||
})
|
||||
# ---
|
||||
# name: test_switch[amax_3000][switch.main_door_secured-entry]
|
||||
# name: test_switch[None-amax_3000][switch.main_door_secured-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
@ -127,7 +127,7 @@
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_switch[amax_3000][switch.main_door_secured-state]
|
||||
# name: test_switch[None-amax_3000][switch.main_door_secured-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'friendly_name': 'Main Door Secured',
|
||||
@ -140,7 +140,7 @@
|
||||
'state': 'off',
|
||||
})
|
||||
# ---
|
||||
# name: test_switch[amax_3000][switch.output_a-entry]
|
||||
# name: test_switch[None-amax_3000][switch.output_a-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
@ -174,7 +174,7 @@
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_switch[amax_3000][switch.output_a-state]
|
||||
# name: test_switch[None-amax_3000][switch.output_a-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'friendly_name': 'Output A',
|
||||
@ -187,195 +187,7 @@
|
||||
'state': 'off',
|
||||
})
|
||||
# ---
|
||||
# name: test_switch[b5512][switch.main_door_cycling-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'switch',
|
||||
'entity_category': None,
|
||||
'entity_id': 'switch.main_door_cycling',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': None,
|
||||
'original_name': 'Cycling',
|
||||
'platform': 'bosch_alarm',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'cycling',
|
||||
'unique_id': '01JQ917ACKQ33HHM7YCFXYZX51_door_1_cycling',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_switch[b5512][switch.main_door_cycling-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'friendly_name': 'Main Door Cycling',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'switch.main_door_cycling',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'off',
|
||||
})
|
||||
# ---
|
||||
# name: test_switch[b5512][switch.main_door_locked-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'switch',
|
||||
'entity_category': None,
|
||||
'entity_id': 'switch.main_door_locked',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': None,
|
||||
'original_name': 'Locked',
|
||||
'platform': 'bosch_alarm',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'locked',
|
||||
'unique_id': '01JQ917ACKQ33HHM7YCFXYZX51_door_1_locked',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_switch[b5512][switch.main_door_locked-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'friendly_name': 'Main Door Locked',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'switch.main_door_locked',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'on',
|
||||
})
|
||||
# ---
|
||||
# name: test_switch[b5512][switch.main_door_secured-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'switch',
|
||||
'entity_category': None,
|
||||
'entity_id': 'switch.main_door_secured',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': None,
|
||||
'original_name': 'Secured',
|
||||
'platform': 'bosch_alarm',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'secured',
|
||||
'unique_id': '01JQ917ACKQ33HHM7YCFXYZX51_door_1_secured',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_switch[b5512][switch.main_door_secured-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'friendly_name': 'Main Door Secured',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'switch.main_door_secured',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'off',
|
||||
})
|
||||
# ---
|
||||
# name: test_switch[b5512][switch.output_a-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'switch',
|
||||
'entity_category': None,
|
||||
'entity_id': 'switch.output_a',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': None,
|
||||
'original_name': None,
|
||||
'platform': 'bosch_alarm',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': '01JQ917ACKQ33HHM7YCFXYZX51_output_1',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_switch[b5512][switch.output_a-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'friendly_name': 'Output A',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'switch.output_a',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'off',
|
||||
})
|
||||
# ---
|
||||
# name: test_switch[solution_3000][switch.main_door_cycling-entry]
|
||||
# name: test_switch[None-b5512][switch.main_door_cycling-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
@ -409,7 +221,7 @@
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_switch[solution_3000][switch.main_door_cycling-state]
|
||||
# name: test_switch[None-b5512][switch.main_door_cycling-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'friendly_name': 'Main Door Cycling',
|
||||
@ -422,7 +234,7 @@
|
||||
'state': 'off',
|
||||
})
|
||||
# ---
|
||||
# name: test_switch[solution_3000][switch.main_door_locked-entry]
|
||||
# name: test_switch[None-b5512][switch.main_door_locked-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
@ -456,7 +268,7 @@
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_switch[solution_3000][switch.main_door_locked-state]
|
||||
# name: test_switch[None-b5512][switch.main_door_locked-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'friendly_name': 'Main Door Locked',
|
||||
@ -469,7 +281,7 @@
|
||||
'state': 'on',
|
||||
})
|
||||
# ---
|
||||
# name: test_switch[solution_3000][switch.main_door_secured-entry]
|
||||
# name: test_switch[None-b5512][switch.main_door_secured-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
@ -503,7 +315,7 @@
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_switch[solution_3000][switch.main_door_secured-state]
|
||||
# name: test_switch[None-b5512][switch.main_door_secured-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'friendly_name': 'Main Door Secured',
|
||||
@ -516,7 +328,7 @@
|
||||
'state': 'off',
|
||||
})
|
||||
# ---
|
||||
# name: test_switch[solution_3000][switch.output_a-entry]
|
||||
# name: test_switch[None-b5512][switch.output_a-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
@ -550,7 +362,195 @@
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_switch[solution_3000][switch.output_a-state]
|
||||
# name: test_switch[None-b5512][switch.output_a-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'friendly_name': 'Output A',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'switch.output_a',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'off',
|
||||
})
|
||||
# ---
|
||||
# name: test_switch[None-solution_3000][switch.main_door_cycling-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'switch',
|
||||
'entity_category': None,
|
||||
'entity_id': 'switch.main_door_cycling',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': None,
|
||||
'original_name': 'Cycling',
|
||||
'platform': 'bosch_alarm',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'cycling',
|
||||
'unique_id': '01JQ917ACKQ33HHM7YCFXYZX51_door_1_cycling',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_switch[None-solution_3000][switch.main_door_cycling-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'friendly_name': 'Main Door Cycling',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'switch.main_door_cycling',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'off',
|
||||
})
|
||||
# ---
|
||||
# name: test_switch[None-solution_3000][switch.main_door_locked-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'switch',
|
||||
'entity_category': None,
|
||||
'entity_id': 'switch.main_door_locked',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': None,
|
||||
'original_name': 'Locked',
|
||||
'platform': 'bosch_alarm',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'locked',
|
||||
'unique_id': '01JQ917ACKQ33HHM7YCFXYZX51_door_1_locked',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_switch[None-solution_3000][switch.main_door_locked-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'friendly_name': 'Main Door Locked',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'switch.main_door_locked',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'on',
|
||||
})
|
||||
# ---
|
||||
# name: test_switch[None-solution_3000][switch.main_door_secured-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'switch',
|
||||
'entity_category': None,
|
||||
'entity_id': 'switch.main_door_secured',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': None,
|
||||
'original_name': 'Secured',
|
||||
'platform': 'bosch_alarm',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'secured',
|
||||
'unique_id': '01JQ917ACKQ33HHM7YCFXYZX51_door_1_secured',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_switch[None-solution_3000][switch.main_door_secured-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'friendly_name': 'Main Door Secured',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'switch.main_door_secured',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'off',
|
||||
})
|
||||
# ---
|
||||
# name: test_switch[None-solution_3000][switch.output_a-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'switch',
|
||||
'entity_category': None,
|
||||
'entity_id': 'switch.output_a',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': None,
|
||||
'original_name': None,
|
||||
'platform': 'bosch_alarm',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': '01JQ917ACKQ33HHM7YCFXYZX51_output_1',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_switch[None-solution_3000][switch.output_a-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'friendly_name': 'Output A',
|
||||
|
@ -6,12 +6,12 @@ from unittest.mock import AsyncMock
|
||||
|
||||
import pytest
|
||||
|
||||
from homeassistant import config_entries
|
||||
from homeassistant.components.bosch_alarm.const import DOMAIN
|
||||
from homeassistant.config_entries import SOURCE_USER
|
||||
from homeassistant.const import CONF_HOST, CONF_MODEL, CONF_PORT
|
||||
from homeassistant.config_entries import SOURCE_DHCP, SOURCE_RECONFIGURE, SOURCE_USER
|
||||
from homeassistant.const import CONF_HOST, CONF_MAC, CONF_MODEL, CONF_PORT
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.data_entry_flow import FlowResultType
|
||||
from homeassistant.helpers.service_info.dhcp import DhcpServiceInfo
|
||||
|
||||
from . import setup_integration
|
||||
|
||||
@ -77,7 +77,7 @@ async def test_form_exceptions(
|
||||
"""Test we handle exceptions correctly."""
|
||||
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN, context={"source": config_entries.SOURCE_USER}
|
||||
DOMAIN, context={"source": SOURCE_USER}
|
||||
)
|
||||
assert result["type"] is FlowResultType.FORM
|
||||
assert result["step_id"] == "user"
|
||||
@ -174,13 +174,6 @@ async def test_entry_already_configured_host(
|
||||
result["flow_id"], {CONF_HOST: "0.0.0.0"}
|
||||
)
|
||||
|
||||
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
|
||||
)
|
||||
|
||||
assert result["type"] is FlowResultType.ABORT
|
||||
assert result["reason"] == "already_configured"
|
||||
|
||||
@ -200,7 +193,7 @@ async def test_entry_already_configured_serial(
|
||||
)
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"], {CONF_HOST: "0.0.0.0"}
|
||||
result["flow_id"], {CONF_HOST: "1.1.1.1"}
|
||||
)
|
||||
|
||||
assert result["type"] is FlowResultType.FORM
|
||||
@ -214,6 +207,140 @@ async def test_entry_already_configured_serial(
|
||||
assert result["reason"] == "already_configured"
|
||||
|
||||
|
||||
async def test_dhcp_can_finish(
|
||||
hass: HomeAssistant,
|
||||
mock_setup_entry: AsyncMock,
|
||||
mock_panel: AsyncMock,
|
||||
model_name: str,
|
||||
serial_number: str,
|
||||
config_flow_data: dict[str, Any],
|
||||
) -> None:
|
||||
"""Test DHCP discovery flow can finish right away."""
|
||||
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN,
|
||||
context={"source": SOURCE_DHCP},
|
||||
data=DhcpServiceInfo(
|
||||
hostname="test",
|
||||
ip="1.1.1.1",
|
||||
macaddress="34ea34b43b5a",
|
||||
),
|
||||
)
|
||||
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: "1.1.1.1",
|
||||
CONF_MAC: "34:ea:34:b4:3b:5a",
|
||||
CONF_PORT: 7700,
|
||||
CONF_MODEL: model_name,
|
||||
**config_flow_data,
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("exception", "message"),
|
||||
[
|
||||
(asyncio.exceptions.TimeoutError(), "cannot_connect"),
|
||||
(Exception(), "unknown"),
|
||||
],
|
||||
)
|
||||
async def test_dhcp_exceptions(
|
||||
hass: HomeAssistant,
|
||||
mock_setup_entry: AsyncMock,
|
||||
mock_panel: AsyncMock,
|
||||
model_name: str,
|
||||
serial_number: str,
|
||||
config_flow_data: dict[str, Any],
|
||||
exception: Exception,
|
||||
message: str,
|
||||
) -> None:
|
||||
"""Test DHCP discovery flow that fails to connect."""
|
||||
mock_panel.connect.side_effect = exception
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN,
|
||||
context={"source": SOURCE_DHCP},
|
||||
data=DhcpServiceInfo(
|
||||
hostname="test",
|
||||
ip="1.1.1.1",
|
||||
macaddress="34ea34b43b5a",
|
||||
),
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
assert result["type"] is FlowResultType.ABORT
|
||||
assert result["reason"] == message
|
||||
|
||||
|
||||
@pytest.mark.parametrize("mac_address", ["34ea34b43b5a"])
|
||||
async def test_dhcp_updates_host(
|
||||
hass: HomeAssistant,
|
||||
mock_setup_entry: AsyncMock,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
mock_panel: AsyncMock,
|
||||
mac_address: str | None,
|
||||
serial_number: str,
|
||||
config_flow_data: dict[str, Any],
|
||||
) -> None:
|
||||
"""Test DHCP updates host."""
|
||||
await setup_integration(hass, mock_config_entry)
|
||||
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN,
|
||||
context={"source": SOURCE_DHCP},
|
||||
data=DhcpServiceInfo(
|
||||
hostname="test",
|
||||
ip="4.5.6.7",
|
||||
macaddress=mac_address,
|
||||
),
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert result["type"] is FlowResultType.ABORT
|
||||
assert result["reason"] == "already_configured"
|
||||
assert mock_config_entry.data[CONF_HOST] == "4.5.6.7"
|
||||
|
||||
|
||||
@pytest.mark.parametrize("model", ["solution_3000", "amax_3000"])
|
||||
async def test_dhcp_abort_ongoing_flow(
|
||||
hass: HomeAssistant,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
mock_panel: AsyncMock,
|
||||
config_flow_data: dict[str, Any],
|
||||
) -> None:
|
||||
"""Test if a dhcp flow is aborted if there is already an ongoing flow."""
|
||||
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN, context={"source": SOURCE_USER}
|
||||
)
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"], {CONF_HOST: "0.0.0.0"}
|
||||
)
|
||||
|
||||
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_in_progress"
|
||||
|
||||
|
||||
async def test_reauth_flow_success(
|
||||
hass: HomeAssistant,
|
||||
mock_setup_entry: AsyncMock,
|
||||
@ -274,7 +401,6 @@ async def test_reauth_flow_error(
|
||||
)
|
||||
assert result["step_id"] == "reauth_confirm"
|
||||
assert result["errors"]["base"] == message
|
||||
|
||||
mock_panel.connect.side_effect = None
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
@ -301,7 +427,7 @@ async def test_reconfig_flow(
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN,
|
||||
context={
|
||||
"source": config_entries.SOURCE_RECONFIGURE,
|
||||
"source": SOURCE_RECONFIGURE,
|
||||
"entry_id": mock_config_entry.entry_id,
|
||||
},
|
||||
)
|
||||
@ -347,7 +473,7 @@ async def test_reconfig_flow_incorrect_model(
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN,
|
||||
context={
|
||||
"source": config_entries.SOURCE_RECONFIGURE,
|
||||
"source": SOURCE_RECONFIGURE,
|
||||
"entry_id": mock_config_entry.entry_id,
|
||||
},
|
||||
)
|
||||
|
Loading…
x
Reference in New Issue
Block a user