From ab04e2c5013dfd33d4908e9510c12677d41e8cb9 Mon Sep 17 00:00:00 2001 From: Austin Mroczek Date: Sun, 10 Aug 2025 13:26:43 -0700 Subject: [PATCH] TotalConnect major test updates (#139672) Co-authored-by: Joostlek --- .../components/totalconnect/binary_sensor.py | 4 +- .../components/totalconnect/config_flow.py | 6 +- .../components/totalconnect/manifest.json | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- tests/components/totalconnect/__init__.py | 12 + tests/components/totalconnect/common.py | 473 -- tests/components/totalconnect/conftest.py | 249 ++ tests/components/totalconnect/const.py | 8 + .../totalconnect/fixtures/device_1.json | 12 + .../totalconnect/fixtures/zones.json | 658 +++ .../snapshots/test_alarm_control_panel.ambr | 12 +- .../snapshots/test_binary_sensor.ambr | 3852 ++++++++++++++++- .../totalconnect/snapshots/test_button.ambr | 550 ++- .../snapshots/test_diagnostics.ambr | 619 +++ .../totalconnect/test_alarm_control_panel.py | 829 ++-- .../totalconnect/test_binary_sensor.py | 88 +- tests/components/totalconnect/test_button.py | 104 +- .../totalconnect/test_config_flow.py | 364 +- .../totalconnect/test_diagnostics.py | 39 +- tests/components/totalconnect/test_init.py | 20 +- 21 files changed, 6374 insertions(+), 1531 deletions(-) delete mode 100644 tests/components/totalconnect/common.py create mode 100644 tests/components/totalconnect/conftest.py create mode 100644 tests/components/totalconnect/const.py create mode 100644 tests/components/totalconnect/fixtures/device_1.json create mode 100644 tests/components/totalconnect/fixtures/zones.json create mode 100644 tests/components/totalconnect/snapshots/test_diagnostics.ambr diff --git a/homeassistant/components/totalconnect/binary_sensor.py b/homeassistant/components/totalconnect/binary_sensor.py index 2f3802dc9a6..7cc8d7a5ebc 100644 --- a/homeassistant/components/totalconnect/binary_sensor.py +++ b/homeassistant/components/totalconnect/binary_sensor.py @@ -172,9 +172,9 @@ class TotalConnectZoneBinarySensor(TotalConnectZoneEntity, BinarySensorEntity): super().__init__(coordinator, zone, location_id, entity_description.key) self.entity_description = entity_description self._attr_extra_state_attributes = { - "zone_id": zone.zoneid, + "zone_id": str(zone.zoneid), "location_id": location_id, - "partition": zone.partition, + "partition": str(zone.partition), } @property diff --git a/homeassistant/components/totalconnect/config_flow.py b/homeassistant/components/totalconnect/config_flow.py index 3f5d05fda13..33e82dcaf53 100644 --- a/homeassistant/components/totalconnect/config_flow.py +++ b/homeassistant/components/totalconnect/config_flow.py @@ -105,11 +105,7 @@ class TotalConnectConfigFlow(ConfigFlow, domain=DOMAIN): }, ) else: - # Force the loading of locations using I/O - number_locations = await self.hass.async_add_executor_job( - self.client.get_number_locations, - ) - if number_locations < 1: + if self.client.get_number_locations() < 1: return self.async_abort(reason="no_locations") for location_id in self.client.locations: self.usercodes[location_id] = None diff --git a/homeassistant/components/totalconnect/manifest.json b/homeassistant/components/totalconnect/manifest.json index 6aff1ea392b..cd349cd3414 100644 --- a/homeassistant/components/totalconnect/manifest.json +++ b/homeassistant/components/totalconnect/manifest.json @@ -6,5 +6,5 @@ "documentation": "https://www.home-assistant.io/integrations/totalconnect", "iot_class": "cloud_polling", "loggers": ["total_connect_client"], - "requirements": ["total-connect-client==2025.1.4"] + "requirements": ["total-connect-client==2025.5"] } diff --git a/requirements_all.txt b/requirements_all.txt index a41f2809f2a..599f8031dfc 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -2965,7 +2965,7 @@ tololib==1.2.2 toonapi==0.3.0 # homeassistant.components.totalconnect -total-connect-client==2025.1.4 +total-connect-client==2025.5 # homeassistant.components.tplink_lte tp-connected==0.0.4 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 2d83bbfad62..668dd2ad35a 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -2442,7 +2442,7 @@ tololib==1.2.2 toonapi==0.3.0 # homeassistant.components.totalconnect -total-connect-client==2025.1.4 +total-connect-client==2025.5 # homeassistant.components.tplink_omada tplink-omada-client==1.4.4 diff --git a/tests/components/totalconnect/__init__.py b/tests/components/totalconnect/__init__.py index 180a00188cd..e7b358157cb 100644 --- a/tests/components/totalconnect/__init__.py +++ b/tests/components/totalconnect/__init__.py @@ -1 +1,13 @@ """Tests for the totalconnect component.""" + +from homeassistant.core import HomeAssistant + +from tests.common import MockConfigEntry + + +async def setup_integration(hass: HomeAssistant, config_entry: MockConfigEntry) -> None: + """Fixture for setting up the component.""" + config_entry.add_to_hass(hass) + + await hass.config_entries.async_setup(config_entry.entry_id) + await hass.async_block_till_done() diff --git a/tests/components/totalconnect/common.py b/tests/components/totalconnect/common.py deleted file mode 100644 index 34d451ec0b8..00000000000 --- a/tests/components/totalconnect/common.py +++ /dev/null @@ -1,473 +0,0 @@ -"""Common methods used across tests for TotalConnect.""" - -from typing import Any -from unittest.mock import patch - -from total_connect_client import ArmingState, ResultCode, ZoneStatus, ZoneType - -from homeassistant.components.totalconnect.const import ( - AUTO_BYPASS, - CODE_REQUIRED, - CONF_USERCODES, - DOMAIN, -) -from homeassistant.const import CONF_PASSWORD, CONF_USERNAME -from homeassistant.core import HomeAssistant -from homeassistant.setup import async_setup_component - -from tests.common import MockConfigEntry - -LOCATION_ID = 123456 - -DEVICE_INFO_BASIC_1 = { - "DeviceID": "987654", - "DeviceName": "test", - "DeviceClassID": 1, - "DeviceSerialNumber": "987654321ABC", - "DeviceFlags": "PromptForUserCode=0,PromptForInstallerCode=0,PromptForImportSecuritySettings=0,AllowUserSlotEditing=0,CalCapable=1,CanBeSentToPanel=0,CanArmNightStay=0,CanSupportMultiPartition=0,PartitionCount=0,MaxPartitionCount=0,OnBoardingSupport=0,PartitionAdded=0,DuplicateUserSyncStatus=0,PanelType=8,PanelVariant=1,BLEDisarmCapable=0,ArmHomeSupported=0,DuplicateUserCodeCheck=1,CanSupportRapid=0,IsKeypadSupported=1,WifiEnrollmentSupported=0,IsConnectedPanel=0,ArmNightInSceneSupported=0,BuiltInCameraSettingsSupported=0,ZWaveThermostatScheduleDisabled=0,MultipleAuthorityLevelSupported=0,VideoOnPanelSupported=0,EnableBLEMode=0,IsPanelWiFiResetSupported=0,IsCompetitorClearBypass=0,IsNotReadyStateSupported=0,isArmStatusWithoutExitDelayNotSupported=0", - "SecurityPanelTypeID": None, - "DeviceSerialText": None, -} -DEVICE_LIST = [DEVICE_INFO_BASIC_1] - -LOCATION_INFO_BASIC_NORMAL = { - "LocationID": LOCATION_ID, - "LocationName": "test", - "SecurityDeviceID": "987654", - "PhotoURL": "http://www.example.com/some/path/to/file.jpg", - "LocationModuleFlags": "Security=1,Video=0,Automation=0,GPS=0,VideoPIR=0", - "DeviceList": {"DeviceInfoBasic": DEVICE_LIST}, -} - -LOCATIONS = {"LocationInfoBasic": [LOCATION_INFO_BASIC_NORMAL]} - -MODULE_FLAGS = "Some=0,Fake=1,Flags=2" - -USER = { - "UserID": "1234567", - "Username": "username", - "UserFeatureList": "Master=0,User Administration=0,Configuration Administration=0", -} - -RESPONSE_SESSION_DETAILS = { - "ResultCode": ResultCode.SUCCESS.value, - "ResultData": "Success", - "SessionID": "12345", - "Locations": LOCATIONS, - "ModuleFlags": MODULE_FLAGS, - "UserInfo": USER, -} - -PARTITION_DISARMED = { - "PartitionID": "1", - "ArmingState": ArmingState.DISARMED, -} - -PARTITION_DISARMED2 = { - "PartitionID": "2", - "ArmingState": ArmingState.DISARMED, -} - -PARTITION_ARMED_STAY = { - "PartitionID": "1", - "ArmingState": ArmingState.ARMED_STAY, -} - -PARTITION_ARMED_STAY2 = { - "PartitionID": "2", - "ArmingState": ArmingState.DISARMED, -} - -PARTITION_ARMED_AWAY = { - "PartitionID": "1", - "ArmingState": ArmingState.ARMED_AWAY, -} - -PARTITION_ARMED_CUSTOM = { - "PartitionID": "1", - "ArmingState": ArmingState.ARMED_CUSTOM_BYPASS, -} - -PARTITION_ARMED_NIGHT = { - "PartitionID": "1", - "ArmingState": ArmingState.ARMED_STAY_NIGHT, -} - -PARTITION_ARMING = { - "PartitionID": "1", - "ArmingState": ArmingState.ARMING, -} -PARTITION_DISARMING = { - "PartitionID": "1", - "ArmingState": ArmingState.DISARMING, -} - -PARTITION_TRIGGERED_POLICE = { - "PartitionID": "1", - "ArmingState": ArmingState.ALARMING, -} - -PARTITION_TRIGGERED_FIRE = { - "PartitionID": "1", - "ArmingState": ArmingState.ALARMING_FIRE_SMOKE, -} - -PARTITION_TRIGGERED_CARBON_MONOXIDE = { - "PartitionID": "1", - "ArmingState": ArmingState.ALARMING_CARBON_MONOXIDE, -} - -PARTITION_UNKNOWN = { - "PartitionID": "1", - "ArmingState": "99999", -} - - -PARTITION_INFO_DISARMED = [PARTITION_DISARMED, PARTITION_DISARMED2] -PARTITION_INFO_ARMED_STAY = [PARTITION_ARMED_STAY, PARTITION_ARMED_STAY2] -PARTITION_INFO_ARMED_AWAY = [PARTITION_ARMED_AWAY] -PARTITION_INFO_ARMED_CUSTOM = [PARTITION_ARMED_CUSTOM] -PARTITION_INFO_ARMED_NIGHT = [PARTITION_ARMED_NIGHT] -PARTITION_INFO_ARMING = [PARTITION_ARMING] -PARTITION_INFO_DISARMING = [PARTITION_DISARMING] -PARTITION_INFO_TRIGGERED_POLICE = [PARTITION_TRIGGERED_POLICE] -PARTITION_INFO_TRIGGERED_FIRE = [PARTITION_TRIGGERED_FIRE] -PARTITION_INFO_TRIGGERED_CARBON_MONOXIDE = [PARTITION_TRIGGERED_CARBON_MONOXIDE] -PARTITION_INFO_UNKNOWN = [PARTITION_UNKNOWN] - -PARTITIONS_DISARMED = {"PartitionInfo": PARTITION_INFO_DISARMED} -PARTITIONS_ARMED_STAY = {"PartitionInfo": PARTITION_INFO_ARMED_STAY} -PARTITIONS_ARMED_AWAY = {"PartitionInfo": PARTITION_INFO_ARMED_AWAY} -PARTITIONS_ARMED_CUSTOM = {"PartitionInfo": PARTITION_INFO_ARMED_CUSTOM} -PARTITIONS_ARMED_NIGHT = {"PartitionInfo": PARTITION_INFO_ARMED_NIGHT} -PARTITIONS_ARMING = {"PartitionInfo": PARTITION_INFO_ARMING} -PARTITIONS_DISARMING = {"PartitionInfo": PARTITION_INFO_DISARMING} -PARTITIONS_TRIGGERED_POLICE = {"PartitionInfo": PARTITION_INFO_TRIGGERED_POLICE} -PARTITIONS_TRIGGERED_FIRE = {"PartitionInfo": PARTITION_INFO_TRIGGERED_FIRE} -PARTITIONS_TRIGGERED_CARBON_MONOXIDE = { - "PartitionInfo": PARTITION_INFO_TRIGGERED_CARBON_MONOXIDE -} -PARTITIONS_UNKNOWN = {"PartitionInfo": PARTITION_INFO_UNKNOWN} - -ZONE_NORMAL = { - "ZoneID": "1", - "ZoneDescription": "Security", - "ZoneStatus": ZoneStatus.FAULT, - "ZoneTypeId": ZoneType.SECURITY, - "PartitionId": "1", - "CanBeBypassed": 1, -} -ZONE_2 = { - "ZoneID": "2", - "ZoneDescription": "Fire", - "ZoneStatus": ZoneStatus.LOW_BATTERY, - "ZoneTypeId": ZoneType.FIRE_SMOKE, - "PartitionId": "1", - "CanBeBypassed": 1, -} -ZONE_3 = { - "ZoneID": "3", - "ZoneDescription": "Gas", - "ZoneStatus": ZoneStatus.TAMPER, - "ZoneTypeId": ZoneType.CARBON_MONOXIDE, - "PartitionId": "1", - "CanBeBypassed": 1, -} -ZONE_4 = { - "ZoneID": "4", - "ZoneDescription": "Motion", - "ZoneStatus": ZoneStatus.NORMAL, - "ZoneTypeId": ZoneType.INTERIOR_FOLLOWER, - "PartitionId": "1", - "CanBeBypassed": 1, -} -ZONE_5 = { - "ZoneID": "5", - "ZoneDescription": "Medical", - "ZoneStatus": ZoneStatus.NORMAL, - "ZoneTypeId": ZoneType.PROA7_MEDICAL, - "PartitionId": "1", - "CanBeBypassed": 0, -} -# 99 is an unknown ZoneType -ZONE_6 = { - "ZoneID": "6", - "ZoneDescription": "Unknown", - "ZoneStatus": ZoneStatus.NORMAL, - "ZoneTypeId": 99, - "PartitionId": "1", - "CanBeBypassed": 0, -} - -ZONE_7 = { - "ZoneID": 7, - "ZoneDescription": "Temperature", - "ZoneStatus": ZoneStatus.NORMAL, - "ZoneTypeId": ZoneType.MONITOR, - "PartitionId": "1", - "CanBeBypassed": 0, -} - -# ZoneType security that cannot be bypassed is a Button on the alarm panel -ZONE_8 = { - "ZoneID": 8, - "ZoneDescription": "Button", - "ZoneStatus": ZoneStatus.FAULT, - "ZoneTypeId": ZoneType.SECURITY, - "PartitionId": "1", - "CanBeBypassed": 0, -} - - -ZONE_INFO = [ZONE_NORMAL, ZONE_2, ZONE_3, ZONE_4, ZONE_5, ZONE_6, ZONE_7] -ZONES = {"ZoneInfo": ZONE_INFO} - -METADATA_DISARMED = { - "Partitions": PARTITIONS_DISARMED, - "Zones": ZONES, - "PromptForImportSecuritySettings": False, - "IsInACLoss": False, - "IsCoverTampered": False, - "Bell1SupervisionFailure": False, - "Bell2SupervisionFailure": False, - "IsInLowBattery": False, -} - -METADATA_ARMED_STAY = METADATA_DISARMED.copy() -METADATA_ARMED_STAY["Partitions"] = PARTITIONS_ARMED_STAY - -METADATA_ARMED_AWAY = METADATA_DISARMED.copy() -METADATA_ARMED_AWAY["Partitions"] = PARTITIONS_ARMED_AWAY - -METADATA_ARMED_CUSTOM = METADATA_DISARMED.copy() -METADATA_ARMED_CUSTOM["Partitions"] = PARTITIONS_ARMED_CUSTOM - -METADATA_ARMED_NIGHT = METADATA_DISARMED.copy() -METADATA_ARMED_NIGHT["Partitions"] = PARTITIONS_ARMED_NIGHT - -METADATA_ARMING = METADATA_DISARMED.copy() -METADATA_ARMING["Partitions"] = PARTITIONS_ARMING - -METADATA_DISARMING = METADATA_DISARMED.copy() -METADATA_DISARMING["Partitions"] = PARTITIONS_DISARMING - -METADATA_TRIGGERED_POLICE = METADATA_DISARMED.copy() -METADATA_TRIGGERED_POLICE["Partitions"] = PARTITIONS_TRIGGERED_POLICE - -METADATA_TRIGGERED_FIRE = METADATA_DISARMED.copy() -METADATA_TRIGGERED_FIRE["Partitions"] = PARTITIONS_TRIGGERED_FIRE - -METADATA_TRIGGERED_CARBON_MONOXIDE = METADATA_DISARMED.copy() -METADATA_TRIGGERED_CARBON_MONOXIDE["Partitions"] = PARTITIONS_TRIGGERED_CARBON_MONOXIDE - -METADATA_UNKNOWN = METADATA_DISARMED.copy() -METADATA_UNKNOWN["Partitions"] = PARTITIONS_UNKNOWN - -RESPONSE_DISARMED = { - "ResultCode": 0, - "PanelMetadataAndStatus": METADATA_DISARMED, - "ArmingState": ArmingState.DISARMED, -} -RESPONSE_ARMED_STAY = { - "ResultCode": 0, - "PanelMetadataAndStatus": METADATA_ARMED_STAY, - "ArmingState": ArmingState.ARMED_STAY, -} -RESPONSE_ARMED_AWAY = { - "ResultCode": 0, - "PanelMetadataAndStatus": METADATA_ARMED_AWAY, - "ArmingState": ArmingState.ARMED_AWAY, -} -RESPONSE_ARMED_CUSTOM = { - "ResultCode": 0, - "PanelMetadataAndStatus": METADATA_ARMED_CUSTOM, - "ArmingState": ArmingState.ARMED_CUSTOM_BYPASS, -} -RESPONSE_ARMED_NIGHT = { - "ResultCode": 0, - "PanelMetadataAndStatus": METADATA_ARMED_NIGHT, - "ArmingState": ArmingState.ARMED_STAY_NIGHT, -} -RESPONSE_ARMING = { - "ResultCode": 0, - "PanelMetadataAndStatus": METADATA_ARMING, - "ArmingState": ArmingState.ARMING, -} -RESPONSE_DISARMING = { - "ResultCode": 0, - "PanelMetadataAndStatus": METADATA_DISARMING, - "ArmingState": ArmingState.DISARMING, -} -RESPONSE_TRIGGERED_POLICE = { - "ResultCode": 0, - "PanelMetadataAndStatus": METADATA_TRIGGERED_POLICE, - "ArmingState": ArmingState.ALARMING, -} -RESPONSE_TRIGGERED_FIRE = { - "ResultCode": 0, - "PanelMetadataAndStatus": METADATA_TRIGGERED_FIRE, - "ArmingState": ArmingState.ALARMING_FIRE_SMOKE, -} -RESPONSE_TRIGGERED_CARBON_MONOXIDE = { - "ResultCode": 0, - "PanelMetadataAndStatus": METADATA_TRIGGERED_CARBON_MONOXIDE, - "ArmingState": ArmingState.ALARMING_CARBON_MONOXIDE, -} -RESPONSE_UNKNOWN = { - "ResultCode": 0, - "PanelMetadataAndStatus": METADATA_UNKNOWN, - "ArmingState": ArmingState.DISARMED, -} - -RESPONSE_ARM_SUCCESS = {"ResultCode": ResultCode.ARM_SUCCESS.value} -RESPONSE_ARM_FAILURE = {"ResultCode": ResultCode.COMMAND_FAILED.value} -RESPONSE_DISARM_SUCCESS = {"ResultCode": ResultCode.DISARM_SUCCESS.value} -RESPONSE_DISARM_FAILURE = { - "ResultCode": ResultCode.COMMAND_FAILED.value, - "ResultData": "Command Failed", -} -RESPONSE_USER_CODE_INVALID = { - "ResultCode": ResultCode.USER_CODE_INVALID.value, - "ResultData": "testing user code invalid", -} -RESPONSE_SUCCESS = {"ResultCode": ResultCode.SUCCESS.value} -RESPONSE_ZONE_BYPASS_SUCCESS = { - "ResultCode": ResultCode.SUCCESS.value, - "ResultData": "None", -} -RESPONSE_ZONE_BYPASS_FAILURE = { - "ResultCode": ResultCode.FAILED_TO_BYPASS_ZONE.value, - "ResultData": "None", -} - -USERNAME = "username@me.com" -PASSWORD = "password" -USERCODES = {LOCATION_ID: "7890"} -CONFIG_DATA = { - CONF_USERNAME: USERNAME, - CONF_PASSWORD: PASSWORD, - CONF_USERCODES: USERCODES, -} -CONFIG_DATA_NO_USERCODES = {CONF_USERNAME: USERNAME, CONF_PASSWORD: PASSWORD} - -OPTIONS_DATA = {AUTO_BYPASS: False, CODE_REQUIRED: False} -OPTIONS_DATA_CODE_REQUIRED = {AUTO_BYPASS: False, CODE_REQUIRED: True} - -PARTITION_DETAILS_1 = { - "PartitionID": "1", - "ArmingState": ArmingState.DISARMED.value, - "PartitionName": "Test1", -} - -PARTITION_DETAILS_2 = { - "PartitionID": "2", - "ArmingState": ArmingState.DISARMED.value, - "PartitionName": "Test2", -} - -PARTITION_DETAILS = {"PartitionDetails": [PARTITION_DETAILS_1, PARTITION_DETAILS_2]} -RESPONSE_PARTITION_DETAILS = { - "ResultCode": ResultCode.SUCCESS.value, - "ResultData": "testing partition details", - "PartitionsInfoList": PARTITION_DETAILS, -} - -ZONE_DETAILS_NORMAL = { - "PartitionId": "1", - "Batterylevel": "-1", - "Signalstrength": "-1", - "zoneAdditionalInfo": None, - "ZoneID": "1", - "ZoneStatus": ZoneStatus.NORMAL, - "ZoneTypeId": ZoneType.SECURITY, - "CanBeBypassed": 1, - "ZoneFlags": None, -} - -ZONE_STATUS_INFO = [ZONE_DETAILS_NORMAL] -ZONE_DETAILS = {"ZoneStatusInfoWithPartitionId": ZONE_STATUS_INFO} -ZONE_DETAIL_STATUS = {"Zones": ZONE_DETAILS} - -RESPONSE_GET_ZONE_DETAILS_SUCCESS = { - "ResultCode": 0, - "ResultData": "Success", - "ZoneStatus": ZONE_DETAIL_STATUS, -} - -TOTALCONNECT_REQUEST = ( - "homeassistant.components.totalconnect.TotalConnectClient.request" -) -TOTALCONNECT_GET_CONFIG = ( - "homeassistant.components.totalconnect.TotalConnectClient._get_configuration" -) -TOTALCONNECT_REQUEST_TOKEN = ( - "homeassistant.components.totalconnect.TotalConnectClient._request_token" -) - - -async def setup_platform( - hass: HomeAssistant, platform: Any, code_required: bool = False -) -> MockConfigEntry: - """Set up the TotalConnect platform.""" - # first set up a config entry and add it to hass - if code_required: - mock_entry = MockConfigEntry( - domain=DOMAIN, data=CONFIG_DATA, options=OPTIONS_DATA_CODE_REQUIRED - ) - else: - mock_entry = MockConfigEntry( - domain=DOMAIN, data=CONFIG_DATA, options=OPTIONS_DATA - ) - mock_entry.add_to_hass(hass) - - responses = [ - RESPONSE_SESSION_DETAILS, - RESPONSE_PARTITION_DETAILS, - RESPONSE_GET_ZONE_DETAILS_SUCCESS, - RESPONSE_DISARMED, - RESPONSE_DISARMED, - ] - - with ( - patch("homeassistant.components.totalconnect.PLATFORMS", [platform]), - patch( - TOTALCONNECT_REQUEST, - side_effect=responses, - ) as mock_request, - patch(TOTALCONNECT_GET_CONFIG, side_effect=None), - patch(TOTALCONNECT_REQUEST_TOKEN, side_effect=None), - ): - assert await async_setup_component(hass, DOMAIN, {}) - assert mock_request.call_count == 5 - await hass.async_block_till_done() - - return mock_entry - - -async def init_integration(hass: HomeAssistant) -> MockConfigEntry: - """Set up the TotalConnect integration.""" - # first set up a config entry and add it to hass - mock_entry = MockConfigEntry(domain=DOMAIN, data=CONFIG_DATA, options=OPTIONS_DATA) - mock_entry.add_to_hass(hass) - - responses = [ - RESPONSE_SESSION_DETAILS, - RESPONSE_PARTITION_DETAILS, - RESPONSE_GET_ZONE_DETAILS_SUCCESS, - RESPONSE_DISARMED, - RESPONSE_DISARMED, - ] - - with ( - patch( - TOTALCONNECT_REQUEST, - side_effect=responses, - ) as mock_request, - patch(TOTALCONNECT_GET_CONFIG, side_effect=None), - patch(TOTALCONNECT_REQUEST_TOKEN, side_effect=None), - ): - await hass.config_entries.async_setup(mock_entry.entry_id) - assert mock_request.call_count == 5 - await hass.async_block_till_done() - - return mock_entry diff --git a/tests/components/totalconnect/conftest.py b/tests/components/totalconnect/conftest.py new file mode 100644 index 00000000000..803fc052129 --- /dev/null +++ b/tests/components/totalconnect/conftest.py @@ -0,0 +1,249 @@ +"""Configure py.test.""" + +from collections.abc import Generator +from typing import Any +from unittest.mock import AsyncMock, patch + +import pytest +from total_connect_client import ArmingState, TotalConnectClient +from total_connect_client.device import TotalConnectDevice +from total_connect_client.location import TotalConnectLocation +from total_connect_client.partition import TotalConnectPartition +from total_connect_client.user import TotalConnectUser +from total_connect_client.zone import TotalConnectZone, ZoneStatus, ZoneType + +from homeassistant.components.totalconnect.const import ( + AUTO_BYPASS, + CODE_REQUIRED, + CONF_USERCODES, + DOMAIN, +) +from homeassistant.const import CONF_PASSWORD, CONF_USERNAME + +from .const import CODE, LOCATION_ID, PASSWORD, USERCODES, USERNAME + +from tests.common import ( + MockConfigEntry, + load_json_array_fixture, + load_json_object_fixture, +) + + +def create_mock_zone( + identifier: int, + partition: str, + description: str, + status: ZoneStatus, + zone_type_id: int, + can_be_bypassed: bool, + battery_level: int, + signal_strength: int, + sensor_serial_number: str | None, + loop_number: int | None, + response_type: str | None, + alarm_report_state: str | None, + supervision_type: str | None, + chime_state: str | None, + device_type: str | None, +) -> AsyncMock: + """Create a mock TotalConnectZone.""" + zone = AsyncMock(spec=TotalConnectZone, autospec=True) + zone.zoneid = identifier + zone.partition = partition + zone.description = description + zone.status = status + zone.zone_type_id = zone_type_id + zone.can_be_bypassed = can_be_bypassed + zone.battery_level = battery_level + zone.signal_strength = signal_strength + zone.sensor_serial_number = sensor_serial_number + zone.loop_number = loop_number + zone.response_type = response_type + zone.alarm_report_state = alarm_report_state + zone.supervision_type = supervision_type + zone.chime_state = chime_state + zone.device_type = device_type + zone.is_type_security.return_value = zone_type_id in ( + ZoneType.SECURITY, + ZoneType.ENTRY_EXIT1, + ZoneType.ENTRY_EXIT2, + ZoneType.PERIMETER, + ZoneType.INTERIOR_FOLLOWER, + ZoneType.TROUBLE_ALARM, + ZoneType.SILENT_24HR, + ZoneType.AUDIBLE_24HR, + ZoneType.INTERIOR_DELAY, + ZoneType.LYRIC_LOCAL_ALARM, + ZoneType.PROA7_GARAGE_MONITOR, + ) + zone.is_type_button.return_value = ( + zone.is_type_security.return_value and not can_be_bypassed + ) or zone_type_id in ( + ZoneType.PROA7_MEDICAL, + ZoneType.AUDIBLE_24HR, + ZoneType.SILENT_24HR, + ZoneType.RF_ARM_STAY, + ZoneType.RF_ARM_AWAY, + ZoneType.RF_DISARM, + ) + return zone + + +def create_mock_zone_from_dict( + zone_data: dict[str, Any], +) -> AsyncMock: + """Create a mock TotalConnectZone from a dictionary.""" + return create_mock_zone( + zone_data["ZoneID"], + zone_data["PartitionId"], + zone_data["ZoneDescription"], + ZoneStatus(zone_data["ZoneStatus"]), + zone_data["ZoneTypeId"], + zone_data["CanBeBypassed"], + zone_data.get("Batterylevel"), + zone_data.get("Signalstrength"), + (zone_data["zoneAdditionalInfo"] or {}).get("SensorSerialNumber"), + (zone_data["zoneAdditionalInfo"] or {}).get("LoopNumber"), + (zone_data["zoneAdditionalInfo"] or {}).get("ResponseType"), + (zone_data["zoneAdditionalInfo"] or {}).get("AlarmReportState"), + (zone_data["zoneAdditionalInfo"] or {}).get("ZoneSupervisionType"), + (zone_data["zoneAdditionalInfo"] or {}).get("ChimeState"), + (zone_data["zoneAdditionalInfo"] or {}).get("DeviceType"), + ) + + +@pytest.fixture +def mock_partition() -> TotalConnectPartition: + """Create a mock TotalConnectPartition.""" + partition = AsyncMock(spec=TotalConnectPartition, autospec=True) + partition.partitionid = 1 + partition.name = "Test1" + partition.is_stay_armed = False + partition.is_fire_armed = False + partition.is_fire_enabled = False + partition.is_common_armed = False + partition.is_common_enabled = False + partition.is_locked = False + partition.is_new_partition = False + partition.is_night_stay_enabled = 0 + partition.exit_delay_timer = 0 + partition.arming_state = ArmingState.DISARMED + return partition + + +@pytest.fixture +def mock_partition_2() -> TotalConnectPartition: + """Create a mock TotalConnectPartition.""" + partition = AsyncMock(spec=TotalConnectPartition, autospec=True) + partition.partitionid = 2 + partition.name = "Test2" + partition.is_stay_armed = False + partition.is_fire_armed = False + partition.is_fire_enabled = False + partition.is_common_armed = False + partition.is_common_enabled = False + partition.is_locked = False + partition.is_new_partition = False + partition.is_night_stay_enabled = 0 + partition.exit_delay_timer = 0 + partition.arming_state = ArmingState.DISARMED + return partition + + +@pytest.fixture +def mock_location( + mock_partition: AsyncMock, mock_partition_2: AsyncMock +) -> TotalConnectLocation: + """Create a mock TotalConnectLocation.""" + location = AsyncMock(spec=TotalConnectLocation, autospec=True) + location.location_id = LOCATION_ID + location.location_name = "Test Location" + location.security_device_id = 7654321 + location.set_usercode.return_value = True + location.partitions = {1: mock_partition, 2: mock_partition_2} + location.devices = { + 7654321: TotalConnectDevice(load_json_object_fixture("device_1.json", DOMAIN)) + } + location.zones = { + z["ZoneID"]: create_mock_zone_from_dict(z) + for z in load_json_array_fixture("zones.json", DOMAIN) + } + location.is_low_battery.return_value = False + location.is_cover_tampered.return_value = False + location.is_ac_loss.return_value = False + location.arming_state = ArmingState.DISARMED + location._module_flags = { + "can_bypass_zones": True, + "can_clear_bypass": True, + "can_set_usercodes": True, + } + location.ac_loss = False + location.low_battery = False + location.auto_bypass_low_battery = False + location.cover_tampered = False + return location + + +@pytest.fixture +def mock_client(mock_location: TotalConnectLocation) -> Generator[TotalConnectClient]: + """Mock a TotalConnectClient for testing.""" + with ( + patch( + "homeassistant.components.totalconnect.config_flow.TotalConnectClient", + autospec=True, + ) as mock_client, + patch( + "homeassistant.components.totalconnect.TotalConnectClient", new=mock_client + ), + ): + client = mock_client.return_value + client.get_number_locations.return_value = 1 + client.locations = {mock_location.location_id: mock_location} + client.usercodes = {mock_location.location_id: CODE} + client.auto_bypass_low_battery = False + client._module_flags = {} + client.retry_delay = 0 + client._invalid_credentials = False + user_mock = AsyncMock(spec=TotalConnectUser, autospec=True) + user_mock._master_user = True + user_mock._user_admin = True + user_mock._config_admin = True + user_mock.security_problem.return_value = False + user_mock._features = { + "can_set_usercodes": True, + "can_bypass_zones": True, + "can_clear_bypass": True, + } + setattr(client, "_user", user_mock) + yield client + + +@pytest.fixture +def code_required() -> bool: + """Return whether a code is required.""" + return False + + +@pytest.fixture +def mock_config_entry(code_required: bool) -> MockConfigEntry: + """Create a mock config entry for testing.""" + return MockConfigEntry( + domain=DOMAIN, + data={ + CONF_USERNAME: USERNAME, + CONF_PASSWORD: PASSWORD, + CONF_USERCODES: USERCODES, + }, + options={AUTO_BYPASS: False, CODE_REQUIRED: code_required}, + unique_id=USERNAME, + ) + + +@pytest.fixture +def mock_setup_entry() -> Generator[AsyncMock]: + """Mock the setup entry for TotalConnect.""" + with patch( + "homeassistant.components.totalconnect.async_setup_entry", + return_value=True, + ) as mock_setup: + yield mock_setup diff --git a/tests/components/totalconnect/const.py b/tests/components/totalconnect/const.py new file mode 100644 index 00000000000..60024c21011 --- /dev/null +++ b/tests/components/totalconnect/const.py @@ -0,0 +1,8 @@ +"""Constants for the Total Connect tests.""" + +LOCATION_ID = 1234567 +CODE = "7890" + +USERNAME = "username@me.com" +PASSWORD = "password" +USERCODES = {LOCATION_ID: "7890"} diff --git a/tests/components/totalconnect/fixtures/device_1.json b/tests/components/totalconnect/fixtures/device_1.json new file mode 100644 index 00000000000..8ff17092a7d --- /dev/null +++ b/tests/components/totalconnect/fixtures/device_1.json @@ -0,0 +1,12 @@ +{ + "DeviceID": 7654321, + "DeviceName": "test", + "DeviceClassID": 1, + "DeviceSerialNumber": "1234567890AB", + "DeviceFlags": "PromptForUserCode=0,PromptForInstallerCode=0,PromptForImportSecuritySettings=0,AllowUserSlotEditing=0,CalCapable=1,CanBeSentToPanel=1,CanArmNightStay=0,CanSupportMultiPartition=0,PartitionCount=0,MaxPartitionCount=4,OnBoardingSupport=0,PartitionAdded=0,DuplicateUserSyncStatus=0,PanelType=12,PanelVariant=1,BLEDisarmCapable=0,ArmHomeSupported=1,DuplicateUserCodeCheck=1,CanSupportRapid=0,IsKeypadSupported=0,WifiEnrollmentSupported=1,IsConnectedPanel=1,ArmNightInSceneSupported=1,BuiltInCameraSettingsSupported=0,ZWaveThermostatScheduleDisabled=0,MultipleAuthorityLevelSupported=1,VideoOnPanelSupported=1,EnableBLEMode=0,IsPanelWiFiResetSupported=0,IsCompetitorClearBypass=0,IsNotReadyStateSupported=0,isArmStatusWithoutExitDelayNotSupported=0,UserCodeLength=4,UserCodeLengthChanged=0,DoubleDisarmRequired=0,TMSCloudSupported=0,IsAVCEnabled=0", + "SecurityPanelTypeID": 12, + "DeviceSerialText": null, + "DeviceType": null, + "DeviceVariants": null, + "RestrictedPanel": 0 +} diff --git a/tests/components/totalconnect/fixtures/zones.json b/tests/components/totalconnect/fixtures/zones.json new file mode 100644 index 00000000000..2bb237f976b --- /dev/null +++ b/tests/components/totalconnect/fixtures/zones.json @@ -0,0 +1,658 @@ +[ + { + "PartitionId": 1, + "Batterylevel": -1, + "Signalstrength": -1, + "zoneAdditionalInfo": { + "SensorSerialNumber": "020000", + "LoopNumber": 1, + "ResponseType": "1", + "AlarmReportState": 1, + "ZoneSupervisionType": 0, + "ChimeState": 1, + "DeviceType": 0 + }, + "CanBeBypassed": 1, + "ZoneFlags": null, + "ZoneID": 2, + "ZoneStatus": 0, + "IsBypassableZone": 0, + "IsSensingZone": 1, + "ZoneDescription": "Security", + "AlarmTriggerTime": null, + "AlarmTriggerTimeLocalized": "2024-12-11T09:00:13", + "ZoneTypeId": 1 + }, + { + "PartitionId": 1, + "Batterylevel": -1, + "Signalstrength": -1, + "zoneAdditionalInfo": { + "SensorSerialNumber": "030000", + "LoopNumber": 1, + "ResponseType": "4", + "AlarmReportState": 1, + "ZoneSupervisionType": 0, + "ChimeState": 0, + "DeviceType": 2 + }, + "CanBeBypassed": 1, + "ZoneFlags": null, + "ZoneID": 3, + "ZoneStatus": 0, + "IsBypassableZone": 0, + "IsSensingZone": 1, + "ZoneDescription": "Fire", + "AlarmTriggerTime": null, + "AlarmTriggerTimeLocalized": "2024-06-02T15:41:05", + "ZoneTypeId": 9 + }, + { + "PartitionId": 1, + "Batterylevel": -1, + "Signalstrength": -1, + "zoneAdditionalInfo": { + "SensorSerialNumber": "040000", + "LoopNumber": 1, + "ResponseType": "4", + "AlarmReportState": 1, + "ZoneSupervisionType": 0, + "ChimeState": 0, + "DeviceType": 2 + }, + "CanBeBypassed": 1, + "ZoneFlags": null, + "ZoneID": 4, + "ZoneStatus": 0, + "IsBypassableZone": 0, + "IsSensingZone": 1, + "ZoneDescription": "Gas", + "AlarmTriggerTime": null, + "AlarmTriggerTimeLocalized": "2024-12-11T09:00:13", + "ZoneTypeId": 14 + }, + { + "PartitionId": 1, + "Batterylevel": -1, + "Signalstrength": -1, + "zoneAdditionalInfo": { + "SensorSerialNumber": "050000", + "LoopNumber": 1, + "ResponseType": "4", + "AlarmReportState": 1, + "ZoneSupervisionType": 0, + "ChimeState": 0, + "DeviceType": 2 + }, + "CanBeBypassed": 1, + "ZoneFlags": null, + "ZoneID": 5, + "ZoneStatus": 0, + "IsBypassableZone": 0, + "IsSensingZone": 1, + "ZoneDescription": "Unknown", + "AlarmTriggerTime": null, + "AlarmTriggerTimeLocalized": "2024-06-02T15:40:59", + "ZoneTypeId": 99 + }, + { + "PartitionId": 1, + "Batterylevel": -1, + "Signalstrength": -1, + "zoneAdditionalInfo": { + "SensorSerialNumber": "060000", + "LoopNumber": 1, + "ResponseType": "1", + "AlarmReportState": 1, + "ZoneSupervisionType": 1, + "ChimeState": 1, + "DeviceType": 0 + }, + "CanBeBypassed": 1, + "ZoneFlags": null, + "ZoneID": 6, + "ZoneStatus": 0, + "IsBypassableZone": 0, + "IsSensingZone": 1, + "ZoneDescription": "Temperature", + "AlarmTriggerTime": null, + "AlarmTriggerTimeLocalized": null, + "ZoneTypeId": 12 + }, + { + "PartitionId": 1, + "Batterylevel": 5, + "Signalstrength": 2, + "zoneAdditionalInfo": { + "SensorSerialNumber": "070000000000000A", + "LoopNumber": 2, + "ResponseType": "53", + "AlarmReportState": 0, + "ZoneSupervisionType": 0, + "ChimeState": 1, + "DeviceType": 15 + }, + "CanBeBypassed": 1, + "ZoneFlags": null, + "ZoneID": 7, + "ZoneStatus": 0, + "IsBypassableZone": 0, + "IsSensingZone": 1, + "ZoneDescription": "Doorbell Other", + "AlarmTriggerTime": null, + "AlarmTriggerTimeLocalized": null, + "ZoneTypeId": 53 + }, + { + "PartitionId": 1, + "Batterylevel": -1, + "Signalstrength": -1, + "zoneAdditionalInfo": { + "SensorSerialNumber": "080000", + "LoopNumber": 1, + "ResponseType": "3", + "AlarmReportState": 1, + "ZoneSupervisionType": 0, + "ChimeState": 1, + "DeviceType": 0 + }, + "CanBeBypassed": 1, + "ZoneFlags": null, + "ZoneID": 8, + "ZoneStatus": 1, + "IsBypassableZone": 0, + "IsSensingZone": 1, + "ZoneDescription": "Office Side Door", + "AlarmTriggerTime": null, + "AlarmTriggerTimeLocalized": null, + "ZoneTypeId": 3 + }, + { + "PartitionId": 1, + "Batterylevel": -1, + "Signalstrength": -1, + "zoneAdditionalInfo": { + "SensorSerialNumber": "090000", + "LoopNumber": 1, + "ResponseType": "3", + "AlarmReportState": 1, + "ZoneSupervisionType": 0, + "ChimeState": 1, + "DeviceType": 0 + }, + "CanBeBypassed": 1, + "ZoneFlags": null, + "ZoneID": 9, + "ZoneStatus": 0, + "IsBypassableZone": 0, + "IsSensingZone": 1, + "ZoneDescription": "Office Back Door", + "AlarmTriggerTime": null, + "AlarmTriggerTimeLocalized": null, + "ZoneTypeId": 3 + }, + { + "PartitionId": 1, + "Batterylevel": -1, + "Signalstrength": -1, + "zoneAdditionalInfo": { + "SensorSerialNumber": "100000", + "LoopNumber": 1, + "ResponseType": "1", + "AlarmReportState": 1, + "ZoneSupervisionType": 0, + "ChimeState": 1, + "DeviceType": 0 + }, + "CanBeBypassed": 1, + "ZoneFlags": null, + "ZoneID": 10, + "ZoneStatus": 0, + "IsBypassableZone": 0, + "IsSensingZone": 1, + "ZoneDescription": "Master Bedroom Door", + "AlarmTriggerTime": null, + "AlarmTriggerTimeLocalized": "2024-06-02T15:40:57", + "ZoneTypeId": 1 + }, + { + "PartitionId": 1, + "Batterylevel": -1, + "Signalstrength": -1, + "zoneAdditionalInfo": { + "SensorSerialNumber": "120000", + "LoopNumber": 1, + "ResponseType": "3", + "AlarmReportState": 1, + "ZoneSupervisionType": 0, + "ChimeState": 1, + "DeviceType": 0 + }, + "CanBeBypassed": 1, + "ZoneFlags": null, + "ZoneID": 12, + "ZoneStatus": 0, + "IsBypassableZone": 0, + "IsSensingZone": 1, + "ZoneDescription": "Dining Room Two Door", + "AlarmTriggerTime": null, + "AlarmTriggerTimeLocalized": null, + "ZoneTypeId": 3 + }, + { + "PartitionId": 1, + "Batterylevel": -1, + "Signalstrength": -1, + "zoneAdditionalInfo": { + "SensorSerialNumber": "130000", + "LoopNumber": 1, + "ResponseType": "3", + "AlarmReportState": 1, + "ZoneSupervisionType": 0, + "ChimeState": 1, + "DeviceType": 0 + }, + "CanBeBypassed": 1, + "ZoneFlags": null, + "ZoneID": 13, + "ZoneStatus": 0, + "IsBypassableZone": 0, + "IsSensingZone": 1, + "ZoneDescription": "Patio Door", + "AlarmTriggerTime": null, + "AlarmTriggerTimeLocalized": null, + "ZoneTypeId": 3 + }, + { + "PartitionId": 1, + "Batterylevel": -1, + "Signalstrength": -1, + "zoneAdditionalInfo": { + "SensorSerialNumber": "140000", + "LoopNumber": 1, + "ResponseType": "3", + "AlarmReportState": 1, + "ZoneSupervisionType": 0, + "ChimeState": 1, + "DeviceType": 1 + }, + "CanBeBypassed": 1, + "ZoneFlags": null, + "ZoneID": 14, + "ZoneStatus": 0, + "IsBypassableZone": 0, + "IsSensingZone": 1, + "ZoneDescription": "Living Room Window", + "AlarmTriggerTime": null, + "AlarmTriggerTimeLocalized": null, + "ZoneTypeId": 3 + }, + { + "PartitionId": 1, + "Batterylevel": -1, + "Signalstrength": -1, + "zoneAdditionalInfo": { + "SensorSerialNumber": "150000", + "LoopNumber": 1, + "ResponseType": "3", + "AlarmReportState": 1, + "ZoneSupervisionType": 0, + "ChimeState": 1, + "DeviceType": 1 + }, + "CanBeBypassed": 1, + "ZoneFlags": null, + "ZoneID": 15, + "ZoneStatus": 0, + "IsBypassableZone": 0, + "IsSensingZone": 1, + "ZoneDescription": "Living Room Two Window", + "AlarmTriggerTime": null, + "AlarmTriggerTimeLocalized": null, + "ZoneTypeId": 3 + }, + { + "PartitionId": 1, + "Batterylevel": -1, + "Signalstrength": -1, + "zoneAdditionalInfo": { + "SensorSerialNumber": "160000", + "LoopNumber": 1, + "ResponseType": "9", + "AlarmReportState": 1, + "ZoneSupervisionType": 0, + "ChimeState": 0, + "DeviceType": 4 + }, + "CanBeBypassed": 0, + "ZoneFlags": null, + "ZoneID": 16, + "ZoneStatus": 0, + "IsBypassableZone": 0, + "IsSensingZone": 1, + "ZoneDescription": "Apartment SmokeDetector", + "AlarmTriggerTime": null, + "AlarmTriggerTimeLocalized": "2024-04-28T09:42:29", + "ZoneTypeId": 9 + }, + { + "PartitionId": 1, + "Batterylevel": -1, + "Signalstrength": -1, + "zoneAdditionalInfo": { + "SensorSerialNumber": "170000", + "LoopNumber": 1, + "ResponseType": "9", + "AlarmReportState": 1, + "ZoneSupervisionType": 0, + "ChimeState": 0, + "DeviceType": 4 + }, + "CanBeBypassed": 0, + "ZoneFlags": null, + "ZoneID": 17, + "ZoneStatus": 0, + "IsBypassableZone": 0, + "IsSensingZone": 1, + "ZoneDescription": "Upstairs Hallway SmokeDetector", + "AlarmTriggerTime": null, + "AlarmTriggerTimeLocalized": "2024-04-28T09:53:57", + "ZoneTypeId": 9 + }, + { + "PartitionId": 1, + "Batterylevel": -1, + "Signalstrength": -1, + "zoneAdditionalInfo": { + "SensorSerialNumber": "180000", + "LoopNumber": 1, + "ResponseType": "9", + "AlarmReportState": 1, + "ZoneSupervisionType": 0, + "ChimeState": 0, + "DeviceType": 4 + }, + "CanBeBypassed": 0, + "ZoneFlags": null, + "ZoneID": 18, + "ZoneStatus": 0, + "IsBypassableZone": 0, + "IsSensingZone": 1, + "ZoneDescription": "Downstairs Hallway SmokeDetector", + "AlarmTriggerTime": null, + "AlarmTriggerTimeLocalized": "2024-04-28T09:47:10", + "ZoneTypeId": 9 + }, + { + "PartitionId": 1, + "Batterylevel": -1, + "Signalstrength": -1, + "zoneAdditionalInfo": { + "SensorSerialNumber": "190000", + "LoopNumber": 1, + "ResponseType": "9", + "AlarmReportState": 1, + "ZoneSupervisionType": 0, + "ChimeState": 0, + "DeviceType": 4 + }, + "CanBeBypassed": 0, + "ZoneFlags": null, + "ZoneID": 19, + "ZoneStatus": 0, + "IsBypassableZone": 0, + "IsSensingZone": 1, + "ZoneDescription": "Kid Bedroom SmokeDetector", + "AlarmTriggerTime": null, + "AlarmTriggerTimeLocalized": "2024-04-28T09:49:07", + "ZoneTypeId": 9 + }, + { + "PartitionId": 1, + "Batterylevel": -1, + "Signalstrength": -1, + "zoneAdditionalInfo": { + "SensorSerialNumber": "200000", + "LoopNumber": 1, + "ResponseType": "9", + "AlarmReportState": 1, + "ZoneSupervisionType": 0, + "ChimeState": 0, + "DeviceType": 4 + }, + "CanBeBypassed": 0, + "ZoneFlags": null, + "ZoneID": 20, + "ZoneStatus": 0, + "IsBypassableZone": 0, + "IsSensingZone": 1, + "ZoneDescription": "Guest Bedroom SmokeDetector", + "AlarmTriggerTime": null, + "AlarmTriggerTimeLocalized": "2024-04-28T09:50:20", + "ZoneTypeId": 9 + }, + { + "PartitionId": 1, + "Batterylevel": -1, + "Signalstrength": -1, + "zoneAdditionalInfo": { + "SensorSerialNumber": "210000", + "LoopNumber": 1, + "ResponseType": "14", + "AlarmReportState": 1, + "ZoneSupervisionType": 0, + "ChimeState": 0, + "DeviceType": 6 + }, + "CanBeBypassed": 0, + "ZoneFlags": null, + "ZoneID": 21, + "ZoneStatus": 0, + "IsBypassableZone": 0, + "IsSensingZone": 1, + "ZoneDescription": "Apartment CarbonMonoxideDetecto", + "AlarmTriggerTime": null, + "AlarmTriggerTimeLocalized": "2024-04-28T09:41:18", + "ZoneTypeId": 14 + }, + { + "PartitionId": 1, + "Batterylevel": -1, + "Signalstrength": -1, + "zoneAdditionalInfo": { + "SensorSerialNumber": "220000", + "LoopNumber": 1, + "ResponseType": "14", + "AlarmReportState": 1, + "ZoneSupervisionType": 0, + "ChimeState": 0, + "DeviceType": 6 + }, + "CanBeBypassed": 0, + "ZoneFlags": null, + "ZoneID": 22, + "ZoneStatus": 0, + "IsBypassableZone": 0, + "IsSensingZone": 1, + "ZoneDescription": "Downstairs Hallway CarbonMonoxid", + "AlarmTriggerTime": null, + "AlarmTriggerTimeLocalized": "2024-04-28T09:45:39", + "ZoneTypeId": 14 + }, + { + "PartitionId": 1, + "Batterylevel": -1, + "Signalstrength": -1, + "zoneAdditionalInfo": { + "SensorSerialNumber": "230000", + "LoopNumber": 1, + "ResponseType": "14", + "AlarmReportState": 1, + "ZoneSupervisionType": 0, + "ChimeState": 0, + "DeviceType": 6 + }, + "CanBeBypassed": 0, + "ZoneFlags": null, + "ZoneID": 23, + "ZoneStatus": 0, + "IsBypassableZone": 0, + "IsSensingZone": 1, + "ZoneDescription": "Upstairs Hallway CarbonMonoxideD", + "AlarmTriggerTime": null, + "AlarmTriggerTimeLocalized": "2024-04-28T09:52:37", + "ZoneTypeId": 14 + }, + { + "PartitionId": 1, + "Batterylevel": -1, + "Signalstrength": -1, + "zoneAdditionalInfo": { + "SensorSerialNumber": "240000", + "LoopNumber": 1, + "ResponseType": "9", + "AlarmReportState": 1, + "ZoneSupervisionType": 0, + "ChimeState": 0, + "DeviceType": 4 + }, + "CanBeBypassed": 0, + "ZoneFlags": null, + "ZoneID": 24, + "ZoneStatus": 0, + "IsBypassableZone": 0, + "IsSensingZone": 1, + "ZoneDescription": "Master Bedroom SmokeDetector", + "AlarmTriggerTime": null, + "AlarmTriggerTimeLocalized": null, + "ZoneTypeId": 9 + }, + { + "PartitionId": 1, + "Batterylevel": 5, + "Signalstrength": 3, + "zoneAdditionalInfo": { + "SensorSerialNumber": "250000000000000A", + "LoopNumber": 1, + "ResponseType": "23", + "AlarmReportState": 1, + "ZoneSupervisionType": 0, + "ChimeState": 0, + "DeviceType": 15 + }, + "CanBeBypassed": 1, + "ZoneFlags": null, + "ZoneID": 25, + "ZoneStatus": 0, + "IsBypassableZone": 0, + "IsSensingZone": 1, + "ZoneDescription": "Garage Side Other", + "AlarmTriggerTime": null, + "AlarmTriggerTimeLocalized": "2024-12-15T15:14:39", + "ZoneTypeId": 23 + }, + { + "PartitionId": 1, + "Batterylevel": 5, + "Signalstrength": 5, + "zoneAdditionalInfo": { + "SensorSerialNumber": "260000000000000A", + "LoopNumber": 1, + "ResponseType": "1", + "AlarmReportState": 1, + "ZoneSupervisionType": 0, + "ChimeState": 1, + "DeviceType": 0 + }, + "CanBeBypassed": 1, + "ZoneFlags": null, + "ZoneID": 26, + "ZoneStatus": 0, + "IsBypassableZone": 0, + "IsSensingZone": 1, + "ZoneDescription": "Front Door Door", + "AlarmTriggerTime": null, + "AlarmTriggerTimeLocalized": null, + "ZoneTypeId": 1 + }, + { + "PartitionId": 1, + "Batterylevel": -1, + "Signalstrength": -1, + "zoneAdditionalInfo": null, + "CanBeBypassed": 0, + "ZoneFlags": null, + "ZoneID": 800, + "ZoneStatus": 0, + "IsBypassableZone": 0, + "IsSensingZone": 0, + "ZoneDescription": "Master Bedroom Keypad", + "AlarmTriggerTime": null, + "AlarmTriggerTimeLocalized": null, + "ZoneTypeId": 50 + }, + { + "PartitionId": 1, + "Batterylevel": -1, + "Signalstrength": -1, + "zoneAdditionalInfo": null, + "CanBeBypassed": 0, + "ZoneFlags": null, + "ZoneID": 1995, + "ZoneStatus": 0, + "IsBypassableZone": 0, + "IsSensingZone": 0, + "ZoneDescription": "Zone 995 Fire", + "AlarmTriggerTime": null, + "AlarmTriggerTimeLocalized": null, + "ZoneTypeId": 9 + }, + { + "PartitionId": 1, + "Batterylevel": -1, + "Signalstrength": -1, + "zoneAdditionalInfo": null, + "CanBeBypassed": 0, + "ZoneFlags": null, + "ZoneID": 1996, + "ZoneStatus": 0, + "IsBypassableZone": 0, + "IsSensingZone": 0, + "ZoneDescription": "Zone 996 Medical", + "AlarmTriggerTime": null, + "AlarmTriggerTimeLocalized": null, + "ZoneTypeId": 15 + }, + { + "PartitionId": 1, + "Batterylevel": -1, + "Signalstrength": -1, + "zoneAdditionalInfo": null, + "CanBeBypassed": 0, + "ZoneFlags": null, + "ZoneID": 1998, + "ZoneStatus": 0, + "IsBypassableZone": 0, + "IsSensingZone": 0, + "ZoneDescription": "Zone 998 Other", + "AlarmTriggerTime": null, + "AlarmTriggerTimeLocalized": null, + "ZoneTypeId": 6 + }, + { + "PartitionId": 1, + "Batterylevel": -1, + "Signalstrength": -1, + "zoneAdditionalInfo": null, + "CanBeBypassed": 0, + "ZoneFlags": null, + "ZoneID": 1999, + "ZoneStatus": 0, + "IsBypassableZone": 0, + "IsSensingZone": 0, + "ZoneDescription": "Zone 999 Police", + "AlarmTriggerTime": null, + "AlarmTriggerTimeLocalized": null, + "ZoneTypeId": 7 + } +] diff --git a/tests/components/totalconnect/snapshots/test_alarm_control_panel.ambr b/tests/components/totalconnect/snapshots/test_alarm_control_panel.ambr index 174ab96e8dc..a79fe3832cd 100644 --- a/tests/components/totalconnect/snapshots/test_alarm_control_panel.ambr +++ b/tests/components/totalconnect/snapshots/test_alarm_control_panel.ambr @@ -1,5 +1,5 @@ # serializer version: 1 -# name: test_attributes[alarm_control_panel.test-entry] +# name: test_entities[alarm_control_panel.test-entry] EntityRegistryEntrySnapshot({ 'aliases': set({ }), @@ -30,11 +30,11 @@ 'suggested_object_id': None, 'supported_features': , 'translation_key': None, - 'unique_id': '123456', + 'unique_id': '1234567', 'unit_of_measurement': None, }) # --- -# name: test_attributes[alarm_control_panel.test-state] +# name: test_entities[alarm_control_panel.test-state] StateSnapshot({ 'attributes': ReadOnlyDict({ 'changed_by': None, @@ -51,7 +51,7 @@ 'state': 'disarmed', }) # --- -# name: test_attributes[alarm_control_panel.test_partition_2-entry] +# name: test_entities[alarm_control_panel.test_partition_2-entry] EntityRegistryEntrySnapshot({ 'aliases': set({ }), @@ -82,11 +82,11 @@ 'suggested_object_id': None, 'supported_features': , 'translation_key': 'partition', - 'unique_id': '123456_2', + 'unique_id': '1234567_2', 'unit_of_measurement': None, }) # --- -# name: test_attributes[alarm_control_panel.test_partition_2-state] +# name: test_entities[alarm_control_panel.test_partition_2-state] StateSnapshot({ 'attributes': ReadOnlyDict({ 'changed_by': None, diff --git a/tests/components/totalconnect/snapshots/test_binary_sensor.ambr b/tests/components/totalconnect/snapshots/test_binary_sensor.ambr index 75aaddf8572..55702b06acc 100644 --- a/tests/components/totalconnect/snapshots/test_binary_sensor.ambr +++ b/tests/components/totalconnect/snapshots/test_binary_sensor.ambr @@ -1,4 +1,940 @@ # serializer version: 1 +# name: test_entity_registry[binary_sensor.apartment_carbonmonoxidedetecto-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'binary_sensor', + 'entity_category': None, + 'entity_id': 'binary_sensor.apartment_carbonmonoxidedetecto', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': None, + 'platform': 'totalconnect', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': None, + 'unique_id': '1234567_21_zone', + 'unit_of_measurement': None, + }) +# --- +# name: test_entity_registry[binary_sensor.apartment_carbonmonoxidedetecto-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'smoke', + 'friendly_name': 'Apartment CarbonMonoxideDetecto', + 'location_id': 1234567, + 'partition': '1', + 'zone_id': '21', + }), + 'context': , + 'entity_id': 'binary_sensor.apartment_carbonmonoxidedetecto', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', + }) +# --- +# name: test_entity_registry[binary_sensor.apartment_carbonmonoxidedetecto_battery-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'binary_sensor', + 'entity_category': , + 'entity_id': 'binary_sensor.apartment_carbonmonoxidedetecto_battery', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': 'Battery', + 'platform': 'totalconnect', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': None, + 'unique_id': '1234567_21_low_battery', + 'unit_of_measurement': None, + }) +# --- +# name: test_entity_registry[binary_sensor.apartment_carbonmonoxidedetecto_battery-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'battery', + 'friendly_name': 'Apartment CarbonMonoxideDetecto Battery', + 'location_id': 1234567, + 'partition': '1', + 'zone_id': '21', + }), + 'context': , + 'entity_id': 'binary_sensor.apartment_carbonmonoxidedetecto_battery', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', + }) +# --- +# name: test_entity_registry[binary_sensor.apartment_carbonmonoxidedetecto_tamper-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'binary_sensor', + 'entity_category': , + 'entity_id': 'binary_sensor.apartment_carbonmonoxidedetecto_tamper', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': 'Tamper', + 'platform': 'totalconnect', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': None, + 'unique_id': '1234567_21_tamper', + 'unit_of_measurement': None, + }) +# --- +# name: test_entity_registry[binary_sensor.apartment_carbonmonoxidedetecto_tamper-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'tamper', + 'friendly_name': 'Apartment CarbonMonoxideDetecto Tamper', + 'location_id': 1234567, + 'partition': '1', + 'zone_id': '21', + }), + 'context': , + 'entity_id': 'binary_sensor.apartment_carbonmonoxidedetecto_tamper', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', + }) +# --- +# name: test_entity_registry[binary_sensor.apartment_smokedetector-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'binary_sensor', + 'entity_category': None, + 'entity_id': 'binary_sensor.apartment_smokedetector', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': None, + 'platform': 'totalconnect', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': None, + 'unique_id': '1234567_16_zone', + 'unit_of_measurement': None, + }) +# --- +# name: test_entity_registry[binary_sensor.apartment_smokedetector-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'smoke', + 'friendly_name': 'Apartment SmokeDetector', + 'location_id': 1234567, + 'partition': '1', + 'zone_id': '16', + }), + 'context': , + 'entity_id': 'binary_sensor.apartment_smokedetector', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', + }) +# --- +# name: test_entity_registry[binary_sensor.apartment_smokedetector_battery-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'binary_sensor', + 'entity_category': , + 'entity_id': 'binary_sensor.apartment_smokedetector_battery', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': 'Battery', + 'platform': 'totalconnect', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': None, + 'unique_id': '1234567_16_low_battery', + 'unit_of_measurement': None, + }) +# --- +# name: test_entity_registry[binary_sensor.apartment_smokedetector_battery-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'battery', + 'friendly_name': 'Apartment SmokeDetector Battery', + 'location_id': 1234567, + 'partition': '1', + 'zone_id': '16', + }), + 'context': , + 'entity_id': 'binary_sensor.apartment_smokedetector_battery', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', + }) +# --- +# name: test_entity_registry[binary_sensor.apartment_smokedetector_tamper-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'binary_sensor', + 'entity_category': , + 'entity_id': 'binary_sensor.apartment_smokedetector_tamper', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': 'Tamper', + 'platform': 'totalconnect', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': None, + 'unique_id': '1234567_16_tamper', + 'unit_of_measurement': None, + }) +# --- +# name: test_entity_registry[binary_sensor.apartment_smokedetector_tamper-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'tamper', + 'friendly_name': 'Apartment SmokeDetector Tamper', + 'location_id': 1234567, + 'partition': '1', + 'zone_id': '16', + }), + 'context': , + 'entity_id': 'binary_sensor.apartment_smokedetector_tamper', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', + }) +# --- +# name: test_entity_registry[binary_sensor.dining_room_two_door-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'binary_sensor', + 'entity_category': None, + 'entity_id': 'binary_sensor.dining_room_two_door', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': None, + 'platform': 'totalconnect', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': None, + 'unique_id': '1234567_12_zone', + 'unit_of_measurement': None, + }) +# --- +# name: test_entity_registry[binary_sensor.dining_room_two_door-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'smoke', + 'friendly_name': 'Dining Room Two Door', + 'location_id': 1234567, + 'partition': '1', + 'zone_id': '12', + }), + 'context': , + 'entity_id': 'binary_sensor.dining_room_two_door', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', + }) +# --- +# name: test_entity_registry[binary_sensor.dining_room_two_door_battery-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'binary_sensor', + 'entity_category': , + 'entity_id': 'binary_sensor.dining_room_two_door_battery', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': 'Battery', + 'platform': 'totalconnect', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': None, + 'unique_id': '1234567_12_low_battery', + 'unit_of_measurement': None, + }) +# --- +# name: test_entity_registry[binary_sensor.dining_room_two_door_battery-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'battery', + 'friendly_name': 'Dining Room Two Door Battery', + 'location_id': 1234567, + 'partition': '1', + 'zone_id': '12', + }), + 'context': , + 'entity_id': 'binary_sensor.dining_room_two_door_battery', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', + }) +# --- +# name: test_entity_registry[binary_sensor.dining_room_two_door_tamper-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'binary_sensor', + 'entity_category': , + 'entity_id': 'binary_sensor.dining_room_two_door_tamper', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': 'Tamper', + 'platform': 'totalconnect', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': None, + 'unique_id': '1234567_12_tamper', + 'unit_of_measurement': None, + }) +# --- +# name: test_entity_registry[binary_sensor.dining_room_two_door_tamper-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'tamper', + 'friendly_name': 'Dining Room Two Door Tamper', + 'location_id': 1234567, + 'partition': '1', + 'zone_id': '12', + }), + 'context': , + 'entity_id': 'binary_sensor.dining_room_two_door_tamper', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', + }) +# --- +# name: test_entity_registry[binary_sensor.doorbell_other-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'binary_sensor', + 'entity_category': None, + 'entity_id': 'binary_sensor.doorbell_other', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': None, + 'platform': 'totalconnect', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': None, + 'unique_id': '1234567_7_zone', + 'unit_of_measurement': None, + }) +# --- +# name: test_entity_registry[binary_sensor.doorbell_other-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'smoke', + 'friendly_name': 'Doorbell Other', + 'location_id': 1234567, + 'partition': '1', + 'zone_id': '7', + }), + 'context': , + 'entity_id': 'binary_sensor.doorbell_other', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', + }) +# --- +# name: test_entity_registry[binary_sensor.doorbell_other_battery-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'binary_sensor', + 'entity_category': , + 'entity_id': 'binary_sensor.doorbell_other_battery', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': 'Battery', + 'platform': 'totalconnect', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': None, + 'unique_id': '1234567_7_low_battery', + 'unit_of_measurement': None, + }) +# --- +# name: test_entity_registry[binary_sensor.doorbell_other_battery-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'battery', + 'friendly_name': 'Doorbell Other Battery', + 'location_id': 1234567, + 'partition': '1', + 'zone_id': '7', + }), + 'context': , + 'entity_id': 'binary_sensor.doorbell_other_battery', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', + }) +# --- +# name: test_entity_registry[binary_sensor.doorbell_other_tamper-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'binary_sensor', + 'entity_category': , + 'entity_id': 'binary_sensor.doorbell_other_tamper', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': 'Tamper', + 'platform': 'totalconnect', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': None, + 'unique_id': '1234567_7_tamper', + 'unit_of_measurement': None, + }) +# --- +# name: test_entity_registry[binary_sensor.doorbell_other_tamper-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'tamper', + 'friendly_name': 'Doorbell Other Tamper', + 'location_id': 1234567, + 'partition': '1', + 'zone_id': '7', + }), + 'context': , + 'entity_id': 'binary_sensor.doorbell_other_tamper', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', + }) +# --- +# name: test_entity_registry[binary_sensor.downstairs_hallway_carbonmonoxid-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'binary_sensor', + 'entity_category': None, + 'entity_id': 'binary_sensor.downstairs_hallway_carbonmonoxid', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': None, + 'platform': 'totalconnect', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': None, + 'unique_id': '1234567_22_zone', + 'unit_of_measurement': None, + }) +# --- +# name: test_entity_registry[binary_sensor.downstairs_hallway_carbonmonoxid-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'smoke', + 'friendly_name': 'Downstairs Hallway CarbonMonoxid', + 'location_id': 1234567, + 'partition': '1', + 'zone_id': '22', + }), + 'context': , + 'entity_id': 'binary_sensor.downstairs_hallway_carbonmonoxid', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', + }) +# --- +# name: test_entity_registry[binary_sensor.downstairs_hallway_carbonmonoxid_battery-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'binary_sensor', + 'entity_category': , + 'entity_id': 'binary_sensor.downstairs_hallway_carbonmonoxid_battery', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': 'Battery', + 'platform': 'totalconnect', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': None, + 'unique_id': '1234567_22_low_battery', + 'unit_of_measurement': None, + }) +# --- +# name: test_entity_registry[binary_sensor.downstairs_hallway_carbonmonoxid_battery-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'battery', + 'friendly_name': 'Downstairs Hallway CarbonMonoxid Battery', + 'location_id': 1234567, + 'partition': '1', + 'zone_id': '22', + }), + 'context': , + 'entity_id': 'binary_sensor.downstairs_hallway_carbonmonoxid_battery', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', + }) +# --- +# name: test_entity_registry[binary_sensor.downstairs_hallway_carbonmonoxid_tamper-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'binary_sensor', + 'entity_category': , + 'entity_id': 'binary_sensor.downstairs_hallway_carbonmonoxid_tamper', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': 'Tamper', + 'platform': 'totalconnect', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': None, + 'unique_id': '1234567_22_tamper', + 'unit_of_measurement': None, + }) +# --- +# name: test_entity_registry[binary_sensor.downstairs_hallway_carbonmonoxid_tamper-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'tamper', + 'friendly_name': 'Downstairs Hallway CarbonMonoxid Tamper', + 'location_id': 1234567, + 'partition': '1', + 'zone_id': '22', + }), + 'context': , + 'entity_id': 'binary_sensor.downstairs_hallway_carbonmonoxid_tamper', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', + }) +# --- +# name: test_entity_registry[binary_sensor.downstairs_hallway_smokedetector-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'binary_sensor', + 'entity_category': None, + 'entity_id': 'binary_sensor.downstairs_hallway_smokedetector', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': None, + 'platform': 'totalconnect', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': None, + 'unique_id': '1234567_18_zone', + 'unit_of_measurement': None, + }) +# --- +# name: test_entity_registry[binary_sensor.downstairs_hallway_smokedetector-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'smoke', + 'friendly_name': 'Downstairs Hallway SmokeDetector', + 'location_id': 1234567, + 'partition': '1', + 'zone_id': '18', + }), + 'context': , + 'entity_id': 'binary_sensor.downstairs_hallway_smokedetector', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', + }) +# --- +# name: test_entity_registry[binary_sensor.downstairs_hallway_smokedetector_battery-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'binary_sensor', + 'entity_category': , + 'entity_id': 'binary_sensor.downstairs_hallway_smokedetector_battery', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': 'Battery', + 'platform': 'totalconnect', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': None, + 'unique_id': '1234567_18_low_battery', + 'unit_of_measurement': None, + }) +# --- +# name: test_entity_registry[binary_sensor.downstairs_hallway_smokedetector_battery-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'battery', + 'friendly_name': 'Downstairs Hallway SmokeDetector Battery', + 'location_id': 1234567, + 'partition': '1', + 'zone_id': '18', + }), + 'context': , + 'entity_id': 'binary_sensor.downstairs_hallway_smokedetector_battery', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', + }) +# --- +# name: test_entity_registry[binary_sensor.downstairs_hallway_smokedetector_tamper-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'binary_sensor', + 'entity_category': , + 'entity_id': 'binary_sensor.downstairs_hallway_smokedetector_tamper', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': 'Tamper', + 'platform': 'totalconnect', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': None, + 'unique_id': '1234567_18_tamper', + 'unit_of_measurement': None, + }) +# --- +# name: test_entity_registry[binary_sensor.downstairs_hallway_smokedetector_tamper-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'tamper', + 'friendly_name': 'Downstairs Hallway SmokeDetector Tamper', + 'location_id': 1234567, + 'partition': '1', + 'zone_id': '18', + }), + 'context': , + 'entity_id': 'binary_sensor.downstairs_hallway_smokedetector_tamper', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', + }) +# --- # name: test_entity_registry[binary_sensor.fire-entry] EntityRegistryEntrySnapshot({ 'aliases': set({ @@ -30,7 +966,7 @@ 'suggested_object_id': None, 'supported_features': 0, 'translation_key': None, - 'unique_id': '123456_2_zone', + 'unique_id': '1234567_3_zone', 'unit_of_measurement': None, }) # --- @@ -39,16 +975,16 @@ 'attributes': ReadOnlyDict({ 'device_class': 'smoke', 'friendly_name': 'Fire', - 'location_id': 123456, + 'location_id': 1234567, 'partition': '1', - 'zone_id': '2', + 'zone_id': '3', }), 'context': , 'entity_id': 'binary_sensor.fire', 'last_changed': , 'last_reported': , 'last_updated': , - 'state': 'off', + 'state': 'on', }) # --- # name: test_entity_registry[binary_sensor.fire_battery-entry] @@ -82,7 +1018,7 @@ 'suggested_object_id': None, 'supported_features': 0, 'translation_key': None, - 'unique_id': '123456_2_low_battery', + 'unique_id': '1234567_3_low_battery', 'unit_of_measurement': None, }) # --- @@ -91,9 +1027,9 @@ 'attributes': ReadOnlyDict({ 'device_class': 'battery', 'friendly_name': 'Fire Battery', - 'location_id': 123456, + 'location_id': 1234567, 'partition': '1', - 'zone_id': '2', + 'zone_id': '3', }), 'context': , 'entity_id': 'binary_sensor.fire_battery', @@ -134,7 +1070,7 @@ 'suggested_object_id': None, 'supported_features': 0, 'translation_key': None, - 'unique_id': '123456_2_tamper', + 'unique_id': '1234567_3_tamper', 'unit_of_measurement': None, }) # --- @@ -143,16 +1079,328 @@ 'attributes': ReadOnlyDict({ 'device_class': 'tamper', 'friendly_name': 'Fire Tamper', - 'location_id': 123456, + 'location_id': 1234567, 'partition': '1', - 'zone_id': '2', + 'zone_id': '3', }), 'context': , 'entity_id': 'binary_sensor.fire_tamper', 'last_changed': , 'last_reported': , 'last_updated': , - 'state': 'off', + 'state': 'on', + }) +# --- +# name: test_entity_registry[binary_sensor.front_door_door-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'binary_sensor', + 'entity_category': None, + 'entity_id': 'binary_sensor.front_door_door', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': None, + 'platform': 'totalconnect', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': None, + 'unique_id': '1234567_26_zone', + 'unit_of_measurement': None, + }) +# --- +# name: test_entity_registry[binary_sensor.front_door_door-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'smoke', + 'friendly_name': 'Front Door Door', + 'location_id': 1234567, + 'partition': '1', + 'zone_id': '26', + }), + 'context': , + 'entity_id': 'binary_sensor.front_door_door', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', + }) +# --- +# name: test_entity_registry[binary_sensor.front_door_door_battery-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'binary_sensor', + 'entity_category': , + 'entity_id': 'binary_sensor.front_door_door_battery', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': 'Battery', + 'platform': 'totalconnect', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': None, + 'unique_id': '1234567_26_low_battery', + 'unit_of_measurement': None, + }) +# --- +# name: test_entity_registry[binary_sensor.front_door_door_battery-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'battery', + 'friendly_name': 'Front Door Door Battery', + 'location_id': 1234567, + 'partition': '1', + 'zone_id': '26', + }), + 'context': , + 'entity_id': 'binary_sensor.front_door_door_battery', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', + }) +# --- +# name: test_entity_registry[binary_sensor.front_door_door_tamper-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'binary_sensor', + 'entity_category': , + 'entity_id': 'binary_sensor.front_door_door_tamper', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': 'Tamper', + 'platform': 'totalconnect', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': None, + 'unique_id': '1234567_26_tamper', + 'unit_of_measurement': None, + }) +# --- +# name: test_entity_registry[binary_sensor.front_door_door_tamper-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'tamper', + 'friendly_name': 'Front Door Door Tamper', + 'location_id': 1234567, + 'partition': '1', + 'zone_id': '26', + }), + 'context': , + 'entity_id': 'binary_sensor.front_door_door_tamper', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', + }) +# --- +# name: test_entity_registry[binary_sensor.garage_side_other-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'binary_sensor', + 'entity_category': None, + 'entity_id': 'binary_sensor.garage_side_other', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': None, + 'platform': 'totalconnect', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': None, + 'unique_id': '1234567_25_zone', + 'unit_of_measurement': None, + }) +# --- +# name: test_entity_registry[binary_sensor.garage_side_other-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'smoke', + 'friendly_name': 'Garage Side Other', + 'location_id': 1234567, + 'partition': '1', + 'zone_id': '25', + }), + 'context': , + 'entity_id': 'binary_sensor.garage_side_other', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', + }) +# --- +# name: test_entity_registry[binary_sensor.garage_side_other_battery-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'binary_sensor', + 'entity_category': , + 'entity_id': 'binary_sensor.garage_side_other_battery', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': 'Battery', + 'platform': 'totalconnect', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': None, + 'unique_id': '1234567_25_low_battery', + 'unit_of_measurement': None, + }) +# --- +# name: test_entity_registry[binary_sensor.garage_side_other_battery-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'battery', + 'friendly_name': 'Garage Side Other Battery', + 'location_id': 1234567, + 'partition': '1', + 'zone_id': '25', + }), + 'context': , + 'entity_id': 'binary_sensor.garage_side_other_battery', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', + }) +# --- +# name: test_entity_registry[binary_sensor.garage_side_other_tamper-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'binary_sensor', + 'entity_category': , + 'entity_id': 'binary_sensor.garage_side_other_tamper', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': 'Tamper', + 'platform': 'totalconnect', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': None, + 'unique_id': '1234567_25_tamper', + 'unit_of_measurement': None, + }) +# --- +# name: test_entity_registry[binary_sensor.garage_side_other_tamper-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'tamper', + 'friendly_name': 'Garage Side Other Tamper', + 'location_id': 1234567, + 'partition': '1', + 'zone_id': '25', + }), + 'context': , + 'entity_id': 'binary_sensor.garage_side_other_tamper', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', }) # --- # name: test_entity_registry[binary_sensor.gas-entry] @@ -178,7 +1426,7 @@ 'name': None, 'options': dict({ }), - 'original_device_class': , + 'original_device_class': , 'original_icon': None, 'original_name': None, 'platform': 'totalconnect', @@ -186,25 +1434,25 @@ 'suggested_object_id': None, 'supported_features': 0, 'translation_key': None, - 'unique_id': '123456_3_zone', + 'unique_id': '1234567_4_zone', 'unit_of_measurement': None, }) # --- # name: test_entity_registry[binary_sensor.gas-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - 'device_class': 'gas', + 'device_class': 'smoke', 'friendly_name': 'Gas', - 'location_id': 123456, + 'location_id': 1234567, 'partition': '1', - 'zone_id': '3', + 'zone_id': '4', }), 'context': , 'entity_id': 'binary_sensor.gas', 'last_changed': , 'last_reported': , 'last_updated': , - 'state': 'off', + 'state': 'on', }) # --- # name: test_entity_registry[binary_sensor.gas_battery-entry] @@ -238,7 +1486,7 @@ 'suggested_object_id': None, 'supported_features': 0, 'translation_key': None, - 'unique_id': '123456_3_low_battery', + 'unique_id': '1234567_4_low_battery', 'unit_of_measurement': None, }) # --- @@ -247,16 +1495,16 @@ 'attributes': ReadOnlyDict({ 'device_class': 'battery', 'friendly_name': 'Gas Battery', - 'location_id': 123456, + 'location_id': 1234567, 'partition': '1', - 'zone_id': '3', + 'zone_id': '4', }), 'context': , 'entity_id': 'binary_sensor.gas_battery', 'last_changed': , 'last_reported': , 'last_updated': , - 'state': 'off', + 'state': 'on', }) # --- # name: test_entity_registry[binary_sensor.gas_tamper-entry] @@ -290,7 +1538,7 @@ 'suggested_object_id': None, 'supported_features': 0, 'translation_key': None, - 'unique_id': '123456_3_tamper', + 'unique_id': '1234567_4_tamper', 'unit_of_measurement': None, }) # --- @@ -299,9 +1547,9 @@ 'attributes': ReadOnlyDict({ 'device_class': 'tamper', 'friendly_name': 'Gas Tamper', - 'location_id': 123456, + 'location_id': 1234567, 'partition': '1', - 'zone_id': '3', + 'zone_id': '4', }), 'context': , 'entity_id': 'binary_sensor.gas_tamper', @@ -311,7 +1559,7 @@ 'state': 'on', }) # --- -# name: test_entity_registry[binary_sensor.medical-entry] +# name: test_entity_registry[binary_sensor.guest_bedroom_smokedetector-entry] EntityRegistryEntrySnapshot({ 'aliases': set({ }), @@ -324,7 +1572,7 @@ 'disabled_by': None, 'domain': 'binary_sensor', 'entity_category': None, - 'entity_id': 'binary_sensor.medical', + 'entity_id': 'binary_sensor.guest_bedroom_smokedetector', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -334,7 +1582,7 @@ 'name': None, 'options': dict({ }), - 'original_device_class': , + 'original_device_class': , 'original_icon': None, 'original_name': None, 'platform': 'totalconnect', @@ -342,80 +1590,28 @@ 'suggested_object_id': None, 'supported_features': 0, 'translation_key': None, - 'unique_id': '123456_5_zone', + 'unique_id': '1234567_20_zone', 'unit_of_measurement': None, }) # --- -# name: test_entity_registry[binary_sensor.medical-state] +# name: test_entity_registry[binary_sensor.guest_bedroom_smokedetector-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - 'device_class': 'safety', - 'friendly_name': 'Medical', - 'location_id': 123456, + 'device_class': 'smoke', + 'friendly_name': 'Guest Bedroom SmokeDetector', + 'location_id': 1234567, 'partition': '1', - 'zone_id': '5', + 'zone_id': '20', }), 'context': , - 'entity_id': 'binary_sensor.medical', + 'entity_id': 'binary_sensor.guest_bedroom_smokedetector', 'last_changed': , 'last_reported': , 'last_updated': , - 'state': 'off', + 'state': 'on', }) # --- -# name: test_entity_registry[binary_sensor.motion-entry] - EntityRegistryEntrySnapshot({ - 'aliases': set({ - }), - 'area_id': None, - 'capabilities': None, - 'config_entry_id': , - 'config_subentry_id': , - 'device_class': None, - 'device_id': , - 'disabled_by': None, - 'domain': 'binary_sensor', - 'entity_category': None, - 'entity_id': 'binary_sensor.motion', - 'has_entity_name': True, - 'hidden_by': None, - 'icon': None, - 'id': , - 'labels': set({ - }), - 'name': None, - 'options': dict({ - }), - 'original_device_class': , - 'original_icon': None, - 'original_name': None, - 'platform': 'totalconnect', - 'previous_unique_id': None, - 'suggested_object_id': None, - 'supported_features': 0, - 'translation_key': None, - 'unique_id': '123456_4_zone', - 'unit_of_measurement': None, - }) -# --- -# name: test_entity_registry[binary_sensor.motion-state] - StateSnapshot({ - 'attributes': ReadOnlyDict({ - 'device_class': 'motion', - 'friendly_name': 'Motion', - 'location_id': 123456, - 'partition': '1', - 'zone_id': '4', - }), - 'context': , - 'entity_id': 'binary_sensor.motion', - 'last_changed': , - 'last_reported': , - 'last_updated': , - 'state': 'off', - }) -# --- -# name: test_entity_registry[binary_sensor.motion_battery-entry] +# name: test_entity_registry[binary_sensor.guest_bedroom_smokedetector_battery-entry] EntityRegistryEntrySnapshot({ 'aliases': set({ }), @@ -428,7 +1624,7 @@ 'disabled_by': None, 'domain': 'binary_sensor', 'entity_category': , - 'entity_id': 'binary_sensor.motion_battery', + 'entity_id': 'binary_sensor.guest_bedroom_smokedetector_battery', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -446,28 +1642,28 @@ 'suggested_object_id': None, 'supported_features': 0, 'translation_key': None, - 'unique_id': '123456_4_low_battery', + 'unique_id': '1234567_20_low_battery', 'unit_of_measurement': None, }) # --- -# name: test_entity_registry[binary_sensor.motion_battery-state] +# name: test_entity_registry[binary_sensor.guest_bedroom_smokedetector_battery-state] StateSnapshot({ 'attributes': ReadOnlyDict({ 'device_class': 'battery', - 'friendly_name': 'Motion Battery', - 'location_id': 123456, + 'friendly_name': 'Guest Bedroom SmokeDetector Battery', + 'location_id': 1234567, 'partition': '1', - 'zone_id': '4', + 'zone_id': '20', }), 'context': , - 'entity_id': 'binary_sensor.motion_battery', + 'entity_id': 'binary_sensor.guest_bedroom_smokedetector_battery', 'last_changed': , 'last_reported': , 'last_updated': , - 'state': 'off', + 'state': 'on', }) # --- -# name: test_entity_registry[binary_sensor.motion_tamper-entry] +# name: test_entity_registry[binary_sensor.guest_bedroom_smokedetector_tamper-entry] EntityRegistryEntrySnapshot({ 'aliases': set({ }), @@ -480,7 +1676,7 @@ 'disabled_by': None, 'domain': 'binary_sensor', 'entity_category': , - 'entity_id': 'binary_sensor.motion_tamper', + 'entity_id': 'binary_sensor.guest_bedroom_smokedetector_tamper', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -498,25 +1694,1429 @@ 'suggested_object_id': None, 'supported_features': 0, 'translation_key': None, - 'unique_id': '123456_4_tamper', + 'unique_id': '1234567_20_tamper', 'unit_of_measurement': None, }) # --- -# name: test_entity_registry[binary_sensor.motion_tamper-state] +# name: test_entity_registry[binary_sensor.guest_bedroom_smokedetector_tamper-state] StateSnapshot({ 'attributes': ReadOnlyDict({ 'device_class': 'tamper', - 'friendly_name': 'Motion Tamper', - 'location_id': 123456, + 'friendly_name': 'Guest Bedroom SmokeDetector Tamper', + 'location_id': 1234567, 'partition': '1', - 'zone_id': '4', + 'zone_id': '20', }), 'context': , - 'entity_id': 'binary_sensor.motion_tamper', + 'entity_id': 'binary_sensor.guest_bedroom_smokedetector_tamper', 'last_changed': , 'last_reported': , 'last_updated': , - 'state': 'off', + 'state': 'on', + }) +# --- +# name: test_entity_registry[binary_sensor.kid_bedroom_smokedetector-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'binary_sensor', + 'entity_category': None, + 'entity_id': 'binary_sensor.kid_bedroom_smokedetector', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': None, + 'platform': 'totalconnect', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': None, + 'unique_id': '1234567_19_zone', + 'unit_of_measurement': None, + }) +# --- +# name: test_entity_registry[binary_sensor.kid_bedroom_smokedetector-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'smoke', + 'friendly_name': 'Kid Bedroom SmokeDetector', + 'location_id': 1234567, + 'partition': '1', + 'zone_id': '19', + }), + 'context': , + 'entity_id': 'binary_sensor.kid_bedroom_smokedetector', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', + }) +# --- +# name: test_entity_registry[binary_sensor.kid_bedroom_smokedetector_battery-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'binary_sensor', + 'entity_category': , + 'entity_id': 'binary_sensor.kid_bedroom_smokedetector_battery', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': 'Battery', + 'platform': 'totalconnect', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': None, + 'unique_id': '1234567_19_low_battery', + 'unit_of_measurement': None, + }) +# --- +# name: test_entity_registry[binary_sensor.kid_bedroom_smokedetector_battery-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'battery', + 'friendly_name': 'Kid Bedroom SmokeDetector Battery', + 'location_id': 1234567, + 'partition': '1', + 'zone_id': '19', + }), + 'context': , + 'entity_id': 'binary_sensor.kid_bedroom_smokedetector_battery', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', + }) +# --- +# name: test_entity_registry[binary_sensor.kid_bedroom_smokedetector_tamper-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'binary_sensor', + 'entity_category': , + 'entity_id': 'binary_sensor.kid_bedroom_smokedetector_tamper', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': 'Tamper', + 'platform': 'totalconnect', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': None, + 'unique_id': '1234567_19_tamper', + 'unit_of_measurement': None, + }) +# --- +# name: test_entity_registry[binary_sensor.kid_bedroom_smokedetector_tamper-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'tamper', + 'friendly_name': 'Kid Bedroom SmokeDetector Tamper', + 'location_id': 1234567, + 'partition': '1', + 'zone_id': '19', + }), + 'context': , + 'entity_id': 'binary_sensor.kid_bedroom_smokedetector_tamper', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', + }) +# --- +# name: test_entity_registry[binary_sensor.living_room_two_window-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'binary_sensor', + 'entity_category': None, + 'entity_id': 'binary_sensor.living_room_two_window', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': None, + 'platform': 'totalconnect', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': None, + 'unique_id': '1234567_15_zone', + 'unit_of_measurement': None, + }) +# --- +# name: test_entity_registry[binary_sensor.living_room_two_window-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'smoke', + 'friendly_name': 'Living Room Two Window', + 'location_id': 1234567, + 'partition': '1', + 'zone_id': '15', + }), + 'context': , + 'entity_id': 'binary_sensor.living_room_two_window', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', + }) +# --- +# name: test_entity_registry[binary_sensor.living_room_two_window_battery-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'binary_sensor', + 'entity_category': , + 'entity_id': 'binary_sensor.living_room_two_window_battery', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': 'Battery', + 'platform': 'totalconnect', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': None, + 'unique_id': '1234567_15_low_battery', + 'unit_of_measurement': None, + }) +# --- +# name: test_entity_registry[binary_sensor.living_room_two_window_battery-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'battery', + 'friendly_name': 'Living Room Two Window Battery', + 'location_id': 1234567, + 'partition': '1', + 'zone_id': '15', + }), + 'context': , + 'entity_id': 'binary_sensor.living_room_two_window_battery', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', + }) +# --- +# name: test_entity_registry[binary_sensor.living_room_two_window_tamper-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'binary_sensor', + 'entity_category': , + 'entity_id': 'binary_sensor.living_room_two_window_tamper', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': 'Tamper', + 'platform': 'totalconnect', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': None, + 'unique_id': '1234567_15_tamper', + 'unit_of_measurement': None, + }) +# --- +# name: test_entity_registry[binary_sensor.living_room_two_window_tamper-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'tamper', + 'friendly_name': 'Living Room Two Window Tamper', + 'location_id': 1234567, + 'partition': '1', + 'zone_id': '15', + }), + 'context': , + 'entity_id': 'binary_sensor.living_room_two_window_tamper', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', + }) +# --- +# name: test_entity_registry[binary_sensor.living_room_window-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'binary_sensor', + 'entity_category': None, + 'entity_id': 'binary_sensor.living_room_window', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': None, + 'platform': 'totalconnect', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': None, + 'unique_id': '1234567_14_zone', + 'unit_of_measurement': None, + }) +# --- +# name: test_entity_registry[binary_sensor.living_room_window-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'smoke', + 'friendly_name': 'Living Room Window', + 'location_id': 1234567, + 'partition': '1', + 'zone_id': '14', + }), + 'context': , + 'entity_id': 'binary_sensor.living_room_window', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', + }) +# --- +# name: test_entity_registry[binary_sensor.living_room_window_battery-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'binary_sensor', + 'entity_category': , + 'entity_id': 'binary_sensor.living_room_window_battery', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': 'Battery', + 'platform': 'totalconnect', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': None, + 'unique_id': '1234567_14_low_battery', + 'unit_of_measurement': None, + }) +# --- +# name: test_entity_registry[binary_sensor.living_room_window_battery-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'battery', + 'friendly_name': 'Living Room Window Battery', + 'location_id': 1234567, + 'partition': '1', + 'zone_id': '14', + }), + 'context': , + 'entity_id': 'binary_sensor.living_room_window_battery', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', + }) +# --- +# name: test_entity_registry[binary_sensor.living_room_window_tamper-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'binary_sensor', + 'entity_category': , + 'entity_id': 'binary_sensor.living_room_window_tamper', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': 'Tamper', + 'platform': 'totalconnect', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': None, + 'unique_id': '1234567_14_tamper', + 'unit_of_measurement': None, + }) +# --- +# name: test_entity_registry[binary_sensor.living_room_window_tamper-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'tamper', + 'friendly_name': 'Living Room Window Tamper', + 'location_id': 1234567, + 'partition': '1', + 'zone_id': '14', + }), + 'context': , + 'entity_id': 'binary_sensor.living_room_window_tamper', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', + }) +# --- +# name: test_entity_registry[binary_sensor.master_bedroom_door-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'binary_sensor', + 'entity_category': None, + 'entity_id': 'binary_sensor.master_bedroom_door', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': None, + 'platform': 'totalconnect', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': None, + 'unique_id': '1234567_10_zone', + 'unit_of_measurement': None, + }) +# --- +# name: test_entity_registry[binary_sensor.master_bedroom_door-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'smoke', + 'friendly_name': 'Master Bedroom Door', + 'location_id': 1234567, + 'partition': '1', + 'zone_id': '10', + }), + 'context': , + 'entity_id': 'binary_sensor.master_bedroom_door', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', + }) +# --- +# name: test_entity_registry[binary_sensor.master_bedroom_door_battery-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'binary_sensor', + 'entity_category': , + 'entity_id': 'binary_sensor.master_bedroom_door_battery', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': 'Battery', + 'platform': 'totalconnect', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': None, + 'unique_id': '1234567_10_low_battery', + 'unit_of_measurement': None, + }) +# --- +# name: test_entity_registry[binary_sensor.master_bedroom_door_battery-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'battery', + 'friendly_name': 'Master Bedroom Door Battery', + 'location_id': 1234567, + 'partition': '1', + 'zone_id': '10', + }), + 'context': , + 'entity_id': 'binary_sensor.master_bedroom_door_battery', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', + }) +# --- +# name: test_entity_registry[binary_sensor.master_bedroom_door_tamper-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'binary_sensor', + 'entity_category': , + 'entity_id': 'binary_sensor.master_bedroom_door_tamper', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': 'Tamper', + 'platform': 'totalconnect', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': None, + 'unique_id': '1234567_10_tamper', + 'unit_of_measurement': None, + }) +# --- +# name: test_entity_registry[binary_sensor.master_bedroom_door_tamper-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'tamper', + 'friendly_name': 'Master Bedroom Door Tamper', + 'location_id': 1234567, + 'partition': '1', + 'zone_id': '10', + }), + 'context': , + 'entity_id': 'binary_sensor.master_bedroom_door_tamper', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', + }) +# --- +# name: test_entity_registry[binary_sensor.master_bedroom_keypad-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'binary_sensor', + 'entity_category': None, + 'entity_id': 'binary_sensor.master_bedroom_keypad', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': None, + 'platform': 'totalconnect', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': None, + 'unique_id': '1234567_800_zone', + 'unit_of_measurement': None, + }) +# --- +# name: test_entity_registry[binary_sensor.master_bedroom_keypad-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'smoke', + 'friendly_name': 'Master Bedroom Keypad', + 'location_id': 1234567, + 'partition': '1', + 'zone_id': '800', + }), + 'context': , + 'entity_id': 'binary_sensor.master_bedroom_keypad', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', + }) +# --- +# name: test_entity_registry[binary_sensor.master_bedroom_keypad_battery-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'binary_sensor', + 'entity_category': , + 'entity_id': 'binary_sensor.master_bedroom_keypad_battery', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': 'Battery', + 'platform': 'totalconnect', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': None, + 'unique_id': '1234567_800_low_battery', + 'unit_of_measurement': None, + }) +# --- +# name: test_entity_registry[binary_sensor.master_bedroom_keypad_battery-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'battery', + 'friendly_name': 'Master Bedroom Keypad Battery', + 'location_id': 1234567, + 'partition': '1', + 'zone_id': '800', + }), + 'context': , + 'entity_id': 'binary_sensor.master_bedroom_keypad_battery', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', + }) +# --- +# name: test_entity_registry[binary_sensor.master_bedroom_keypad_tamper-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'binary_sensor', + 'entity_category': , + 'entity_id': 'binary_sensor.master_bedroom_keypad_tamper', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': 'Tamper', + 'platform': 'totalconnect', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': None, + 'unique_id': '1234567_800_tamper', + 'unit_of_measurement': None, + }) +# --- +# name: test_entity_registry[binary_sensor.master_bedroom_keypad_tamper-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'tamper', + 'friendly_name': 'Master Bedroom Keypad Tamper', + 'location_id': 1234567, + 'partition': '1', + 'zone_id': '800', + }), + 'context': , + 'entity_id': 'binary_sensor.master_bedroom_keypad_tamper', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', + }) +# --- +# name: test_entity_registry[binary_sensor.master_bedroom_smokedetector-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'binary_sensor', + 'entity_category': None, + 'entity_id': 'binary_sensor.master_bedroom_smokedetector', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': None, + 'platform': 'totalconnect', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': None, + 'unique_id': '1234567_24_zone', + 'unit_of_measurement': None, + }) +# --- +# name: test_entity_registry[binary_sensor.master_bedroom_smokedetector-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'smoke', + 'friendly_name': 'Master Bedroom SmokeDetector', + 'location_id': 1234567, + 'partition': '1', + 'zone_id': '24', + }), + 'context': , + 'entity_id': 'binary_sensor.master_bedroom_smokedetector', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', + }) +# --- +# name: test_entity_registry[binary_sensor.master_bedroom_smokedetector_battery-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'binary_sensor', + 'entity_category': , + 'entity_id': 'binary_sensor.master_bedroom_smokedetector_battery', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': 'Battery', + 'platform': 'totalconnect', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': None, + 'unique_id': '1234567_24_low_battery', + 'unit_of_measurement': None, + }) +# --- +# name: test_entity_registry[binary_sensor.master_bedroom_smokedetector_battery-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'battery', + 'friendly_name': 'Master Bedroom SmokeDetector Battery', + 'location_id': 1234567, + 'partition': '1', + 'zone_id': '24', + }), + 'context': , + 'entity_id': 'binary_sensor.master_bedroom_smokedetector_battery', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', + }) +# --- +# name: test_entity_registry[binary_sensor.master_bedroom_smokedetector_tamper-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'binary_sensor', + 'entity_category': , + 'entity_id': 'binary_sensor.master_bedroom_smokedetector_tamper', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': 'Tamper', + 'platform': 'totalconnect', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': None, + 'unique_id': '1234567_24_tamper', + 'unit_of_measurement': None, + }) +# --- +# name: test_entity_registry[binary_sensor.master_bedroom_smokedetector_tamper-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'tamper', + 'friendly_name': 'Master Bedroom SmokeDetector Tamper', + 'location_id': 1234567, + 'partition': '1', + 'zone_id': '24', + }), + 'context': , + 'entity_id': 'binary_sensor.master_bedroom_smokedetector_tamper', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', + }) +# --- +# name: test_entity_registry[binary_sensor.office_back_door-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'binary_sensor', + 'entity_category': None, + 'entity_id': 'binary_sensor.office_back_door', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': None, + 'platform': 'totalconnect', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': None, + 'unique_id': '1234567_9_zone', + 'unit_of_measurement': None, + }) +# --- +# name: test_entity_registry[binary_sensor.office_back_door-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'smoke', + 'friendly_name': 'Office Back Door', + 'location_id': 1234567, + 'partition': '1', + 'zone_id': '9', + }), + 'context': , + 'entity_id': 'binary_sensor.office_back_door', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', + }) +# --- +# name: test_entity_registry[binary_sensor.office_back_door_battery-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'binary_sensor', + 'entity_category': , + 'entity_id': 'binary_sensor.office_back_door_battery', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': 'Battery', + 'platform': 'totalconnect', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': None, + 'unique_id': '1234567_9_low_battery', + 'unit_of_measurement': None, + }) +# --- +# name: test_entity_registry[binary_sensor.office_back_door_battery-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'battery', + 'friendly_name': 'Office Back Door Battery', + 'location_id': 1234567, + 'partition': '1', + 'zone_id': '9', + }), + 'context': , + 'entity_id': 'binary_sensor.office_back_door_battery', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', + }) +# --- +# name: test_entity_registry[binary_sensor.office_back_door_tamper-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'binary_sensor', + 'entity_category': , + 'entity_id': 'binary_sensor.office_back_door_tamper', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': 'Tamper', + 'platform': 'totalconnect', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': None, + 'unique_id': '1234567_9_tamper', + 'unit_of_measurement': None, + }) +# --- +# name: test_entity_registry[binary_sensor.office_back_door_tamper-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'tamper', + 'friendly_name': 'Office Back Door Tamper', + 'location_id': 1234567, + 'partition': '1', + 'zone_id': '9', + }), + 'context': , + 'entity_id': 'binary_sensor.office_back_door_tamper', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', + }) +# --- +# name: test_entity_registry[binary_sensor.office_side_door-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'binary_sensor', + 'entity_category': None, + 'entity_id': 'binary_sensor.office_side_door', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': None, + 'platform': 'totalconnect', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': None, + 'unique_id': '1234567_8_zone', + 'unit_of_measurement': None, + }) +# --- +# name: test_entity_registry[binary_sensor.office_side_door-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'smoke', + 'friendly_name': 'Office Side Door', + 'location_id': 1234567, + 'partition': '1', + 'zone_id': '8', + }), + 'context': , + 'entity_id': 'binary_sensor.office_side_door', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', + }) +# --- +# name: test_entity_registry[binary_sensor.office_side_door_battery-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'binary_sensor', + 'entity_category': , + 'entity_id': 'binary_sensor.office_side_door_battery', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': 'Battery', + 'platform': 'totalconnect', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': None, + 'unique_id': '1234567_8_low_battery', + 'unit_of_measurement': None, + }) +# --- +# name: test_entity_registry[binary_sensor.office_side_door_battery-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'battery', + 'friendly_name': 'Office Side Door Battery', + 'location_id': 1234567, + 'partition': '1', + 'zone_id': '8', + }), + 'context': , + 'entity_id': 'binary_sensor.office_side_door_battery', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', + }) +# --- +# name: test_entity_registry[binary_sensor.office_side_door_tamper-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'binary_sensor', + 'entity_category': , + 'entity_id': 'binary_sensor.office_side_door_tamper', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': 'Tamper', + 'platform': 'totalconnect', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': None, + 'unique_id': '1234567_8_tamper', + 'unit_of_measurement': None, + }) +# --- +# name: test_entity_registry[binary_sensor.office_side_door_tamper-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'tamper', + 'friendly_name': 'Office Side Door Tamper', + 'location_id': 1234567, + 'partition': '1', + 'zone_id': '8', + }), + 'context': , + 'entity_id': 'binary_sensor.office_side_door_tamper', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', + }) +# --- +# name: test_entity_registry[binary_sensor.patio_door-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'binary_sensor', + 'entity_category': None, + 'entity_id': 'binary_sensor.patio_door', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': None, + 'platform': 'totalconnect', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': None, + 'unique_id': '1234567_13_zone', + 'unit_of_measurement': None, + }) +# --- +# name: test_entity_registry[binary_sensor.patio_door-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'smoke', + 'friendly_name': 'Patio Door', + 'location_id': 1234567, + 'partition': '1', + 'zone_id': '13', + }), + 'context': , + 'entity_id': 'binary_sensor.patio_door', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', + }) +# --- +# name: test_entity_registry[binary_sensor.patio_door_battery-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'binary_sensor', + 'entity_category': , + 'entity_id': 'binary_sensor.patio_door_battery', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': 'Battery', + 'platform': 'totalconnect', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': None, + 'unique_id': '1234567_13_low_battery', + 'unit_of_measurement': None, + }) +# --- +# name: test_entity_registry[binary_sensor.patio_door_battery-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'battery', + 'friendly_name': 'Patio Door Battery', + 'location_id': 1234567, + 'partition': '1', + 'zone_id': '13', + }), + 'context': , + 'entity_id': 'binary_sensor.patio_door_battery', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', + }) +# --- +# name: test_entity_registry[binary_sensor.patio_door_tamper-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'binary_sensor', + 'entity_category': , + 'entity_id': 'binary_sensor.patio_door_tamper', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': 'Tamper', + 'platform': 'totalconnect', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': None, + 'unique_id': '1234567_13_tamper', + 'unit_of_measurement': None, + }) +# --- +# name: test_entity_registry[binary_sensor.patio_door_tamper-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'tamper', + 'friendly_name': 'Patio Door Tamper', + 'location_id': 1234567, + 'partition': '1', + 'zone_id': '13', + }), + 'context': , + 'entity_id': 'binary_sensor.patio_door_tamper', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', }) # --- # name: test_entity_registry[binary_sensor.security-entry] @@ -542,7 +3142,7 @@ 'name': None, 'options': dict({ }), - 'original_device_class': , + 'original_device_class': , 'original_icon': None, 'original_name': None, 'platform': 'totalconnect', @@ -550,18 +3150,18 @@ 'suggested_object_id': None, 'supported_features': 0, 'translation_key': None, - 'unique_id': '123456_1_zone', + 'unique_id': '1234567_2_zone', 'unit_of_measurement': None, }) # --- # name: test_entity_registry[binary_sensor.security-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - 'device_class': 'door', + 'device_class': 'smoke', 'friendly_name': 'Security', - 'location_id': 123456, + 'location_id': 1234567, 'partition': '1', - 'zone_id': '1', + 'zone_id': '2', }), 'context': , 'entity_id': 'binary_sensor.security', @@ -602,7 +3202,7 @@ 'suggested_object_id': None, 'supported_features': 0, 'translation_key': None, - 'unique_id': '123456_1_low_battery', + 'unique_id': '1234567_2_low_battery', 'unit_of_measurement': None, }) # --- @@ -611,16 +3211,16 @@ 'attributes': ReadOnlyDict({ 'device_class': 'battery', 'friendly_name': 'Security Battery', - 'location_id': 123456, + 'location_id': 1234567, 'partition': '1', - 'zone_id': '1', + 'zone_id': '2', }), 'context': , 'entity_id': 'binary_sensor.security_battery', 'last_changed': , 'last_reported': , 'last_updated': , - 'state': 'off', + 'state': 'on', }) # --- # name: test_entity_registry[binary_sensor.security_tamper-entry] @@ -654,7 +3254,7 @@ 'suggested_object_id': None, 'supported_features': 0, 'translation_key': None, - 'unique_id': '123456_1_tamper', + 'unique_id': '1234567_2_tamper', 'unit_of_measurement': None, }) # --- @@ -663,16 +3263,16 @@ 'attributes': ReadOnlyDict({ 'device_class': 'tamper', 'friendly_name': 'Security Tamper', - 'location_id': 123456, + 'location_id': 1234567, 'partition': '1', - 'zone_id': '1', + 'zone_id': '2', }), 'context': , 'entity_id': 'binary_sensor.security_tamper', 'last_changed': , 'last_reported': , 'last_updated': , - 'state': 'off', + 'state': 'on', }) # --- # name: test_entity_registry[binary_sensor.temperature-entry] @@ -698,7 +3298,7 @@ 'name': None, 'options': dict({ }), - 'original_device_class': , + 'original_device_class': , 'original_icon': None, 'original_name': None, 'platform': 'totalconnect', @@ -706,25 +3306,25 @@ 'suggested_object_id': None, 'supported_features': 0, 'translation_key': None, - 'unique_id': '123456_7_zone', + 'unique_id': '1234567_6_zone', 'unit_of_measurement': None, }) # --- # name: test_entity_registry[binary_sensor.temperature-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - 'device_class': 'problem', + 'device_class': 'smoke', 'friendly_name': 'Temperature', - 'location_id': 123456, + 'location_id': 1234567, 'partition': '1', - 'zone_id': 7, + 'zone_id': '6', }), 'context': , 'entity_id': 'binary_sensor.temperature', 'last_changed': , 'last_reported': , 'last_updated': , - 'state': 'off', + 'state': 'on', }) # --- # name: test_entity_registry[binary_sensor.temperature_battery-entry] @@ -758,7 +3358,7 @@ 'suggested_object_id': None, 'supported_features': 0, 'translation_key': None, - 'unique_id': '123456_7_low_battery', + 'unique_id': '1234567_6_low_battery', 'unit_of_measurement': None, }) # --- @@ -767,16 +3367,16 @@ 'attributes': ReadOnlyDict({ 'device_class': 'battery', 'friendly_name': 'Temperature Battery', - 'location_id': 123456, + 'location_id': 1234567, 'partition': '1', - 'zone_id': 7, + 'zone_id': '6', }), 'context': , 'entity_id': 'binary_sensor.temperature_battery', 'last_changed': , 'last_reported': , 'last_updated': , - 'state': 'off', + 'state': 'on', }) # --- # name: test_entity_registry[binary_sensor.temperature_tamper-entry] @@ -810,7 +3410,7 @@ 'suggested_object_id': None, 'supported_features': 0, 'translation_key': None, - 'unique_id': '123456_7_tamper', + 'unique_id': '1234567_6_tamper', 'unit_of_measurement': None, }) # --- @@ -819,16 +3419,16 @@ 'attributes': ReadOnlyDict({ 'device_class': 'tamper', 'friendly_name': 'Temperature Tamper', - 'location_id': 123456, + 'location_id': 1234567, 'partition': '1', - 'zone_id': 7, + 'zone_id': '6', }), 'context': , 'entity_id': 'binary_sensor.temperature_tamper', 'last_changed': , 'last_reported': , 'last_updated': , - 'state': 'off', + 'state': 'on', }) # --- # name: test_entity_registry[binary_sensor.test_battery-entry] @@ -862,7 +3462,7 @@ 'suggested_object_id': None, 'supported_features': 0, 'translation_key': None, - 'unique_id': '123456_low_battery', + 'unique_id': '1234567_low_battery', 'unit_of_measurement': None, }) # --- @@ -871,7 +3471,7 @@ 'attributes': ReadOnlyDict({ 'device_class': 'battery', 'friendly_name': 'test Battery', - 'location_id': 123456, + 'location_id': 1234567, }), 'context': , 'entity_id': 'binary_sensor.test_battery', @@ -912,7 +3512,7 @@ 'suggested_object_id': None, 'supported_features': 0, 'translation_key': None, - 'unique_id': '123456_carbon_monoxide', + 'unique_id': '1234567_carbon_monoxide', 'unit_of_measurement': None, }) # --- @@ -921,7 +3521,7 @@ 'attributes': ReadOnlyDict({ 'device_class': 'carbon_monoxide', 'friendly_name': 'test Carbon monoxide', - 'location_id': 123456, + 'location_id': 1234567, }), 'context': , 'entity_id': 'binary_sensor.test_carbon_monoxide', @@ -962,7 +3562,7 @@ 'suggested_object_id': None, 'supported_features': 0, 'translation_key': 'police', - 'unique_id': '123456_police', + 'unique_id': '1234567_police', 'unit_of_measurement': None, }) # --- @@ -970,7 +3570,7 @@ StateSnapshot({ 'attributes': ReadOnlyDict({ 'friendly_name': 'test Police emergency', - 'location_id': 123456, + 'location_id': 1234567, }), 'context': , 'entity_id': 'binary_sensor.test_police_emergency', @@ -1011,7 +3611,7 @@ 'suggested_object_id': None, 'supported_features': 0, 'translation_key': None, - 'unique_id': '123456_power', + 'unique_id': '1234567_power', 'unit_of_measurement': None, }) # --- @@ -1020,7 +3620,7 @@ 'attributes': ReadOnlyDict({ 'device_class': 'power', 'friendly_name': 'test Power', - 'location_id': 123456, + 'location_id': 1234567, }), 'context': , 'entity_id': 'binary_sensor.test_power', @@ -1061,7 +3661,7 @@ 'suggested_object_id': None, 'supported_features': 0, 'translation_key': None, - 'unique_id': '123456_smoke', + 'unique_id': '1234567_smoke', 'unit_of_measurement': None, }) # --- @@ -1070,7 +3670,7 @@ 'attributes': ReadOnlyDict({ 'device_class': 'smoke', 'friendly_name': 'test Smoke', - 'location_id': 123456, + 'location_id': 1234567, }), 'context': , 'entity_id': 'binary_sensor.test_smoke', @@ -1111,7 +3711,7 @@ 'suggested_object_id': None, 'supported_features': 0, 'translation_key': None, - 'unique_id': '123456_tamper', + 'unique_id': '1234567_tamper', 'unit_of_measurement': None, }) # --- @@ -1120,7 +3720,7 @@ 'attributes': ReadOnlyDict({ 'device_class': 'tamper', 'friendly_name': 'test Tamper', - 'location_id': 123456, + 'location_id': 1234567, }), 'context': , 'entity_id': 'binary_sensor.test_tamper', @@ -1153,7 +3753,7 @@ 'name': None, 'options': dict({ }), - 'original_device_class': , + 'original_device_class': , 'original_icon': None, 'original_name': None, 'platform': 'totalconnect', @@ -1161,25 +3761,25 @@ 'suggested_object_id': None, 'supported_features': 0, 'translation_key': None, - 'unique_id': '123456_6_zone', + 'unique_id': '1234567_5_zone', 'unit_of_measurement': None, }) # --- # name: test_entity_registry[binary_sensor.unknown-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - 'device_class': 'door', + 'device_class': 'smoke', 'friendly_name': 'Unknown', - 'location_id': 123456, + 'location_id': 1234567, 'partition': '1', - 'zone_id': '6', + 'zone_id': '5', }), 'context': , 'entity_id': 'binary_sensor.unknown', 'last_changed': , 'last_reported': , 'last_updated': , - 'state': 'off', + 'state': 'on', }) # --- # name: test_entity_registry[binary_sensor.unknown_battery-entry] @@ -1213,7 +3813,7 @@ 'suggested_object_id': None, 'supported_features': 0, 'translation_key': None, - 'unique_id': '123456_6_low_battery', + 'unique_id': '1234567_5_low_battery', 'unit_of_measurement': None, }) # --- @@ -1222,16 +3822,16 @@ 'attributes': ReadOnlyDict({ 'device_class': 'battery', 'friendly_name': 'Unknown Battery', - 'location_id': 123456, + 'location_id': 1234567, 'partition': '1', - 'zone_id': '6', + 'zone_id': '5', }), 'context': , 'entity_id': 'binary_sensor.unknown_battery', 'last_changed': , 'last_reported': , 'last_updated': , - 'state': 'off', + 'state': 'on', }) # --- # name: test_entity_registry[binary_sensor.unknown_tamper-entry] @@ -1265,7 +3865,7 @@ 'suggested_object_id': None, 'supported_features': 0, 'translation_key': None, - 'unique_id': '123456_6_tamper', + 'unique_id': '1234567_5_tamper', 'unit_of_measurement': None, }) # --- @@ -1274,15 +3874,951 @@ 'attributes': ReadOnlyDict({ 'device_class': 'tamper', 'friendly_name': 'Unknown Tamper', - 'location_id': 123456, + 'location_id': 1234567, 'partition': '1', - 'zone_id': '6', + 'zone_id': '5', }), 'context': , 'entity_id': 'binary_sensor.unknown_tamper', 'last_changed': , 'last_reported': , 'last_updated': , - 'state': 'off', + 'state': 'on', + }) +# --- +# name: test_entity_registry[binary_sensor.upstairs_hallway_carbonmonoxided-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'binary_sensor', + 'entity_category': None, + 'entity_id': 'binary_sensor.upstairs_hallway_carbonmonoxided', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': None, + 'platform': 'totalconnect', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': None, + 'unique_id': '1234567_23_zone', + 'unit_of_measurement': None, + }) +# --- +# name: test_entity_registry[binary_sensor.upstairs_hallway_carbonmonoxided-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'smoke', + 'friendly_name': 'Upstairs Hallway CarbonMonoxideD', + 'location_id': 1234567, + 'partition': '1', + 'zone_id': '23', + }), + 'context': , + 'entity_id': 'binary_sensor.upstairs_hallway_carbonmonoxided', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', + }) +# --- +# name: test_entity_registry[binary_sensor.upstairs_hallway_carbonmonoxided_battery-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'binary_sensor', + 'entity_category': , + 'entity_id': 'binary_sensor.upstairs_hallway_carbonmonoxided_battery', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': 'Battery', + 'platform': 'totalconnect', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': None, + 'unique_id': '1234567_23_low_battery', + 'unit_of_measurement': None, + }) +# --- +# name: test_entity_registry[binary_sensor.upstairs_hallway_carbonmonoxided_battery-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'battery', + 'friendly_name': 'Upstairs Hallway CarbonMonoxideD Battery', + 'location_id': 1234567, + 'partition': '1', + 'zone_id': '23', + }), + 'context': , + 'entity_id': 'binary_sensor.upstairs_hallway_carbonmonoxided_battery', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', + }) +# --- +# name: test_entity_registry[binary_sensor.upstairs_hallway_carbonmonoxided_tamper-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'binary_sensor', + 'entity_category': , + 'entity_id': 'binary_sensor.upstairs_hallway_carbonmonoxided_tamper', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': 'Tamper', + 'platform': 'totalconnect', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': None, + 'unique_id': '1234567_23_tamper', + 'unit_of_measurement': None, + }) +# --- +# name: test_entity_registry[binary_sensor.upstairs_hallway_carbonmonoxided_tamper-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'tamper', + 'friendly_name': 'Upstairs Hallway CarbonMonoxideD Tamper', + 'location_id': 1234567, + 'partition': '1', + 'zone_id': '23', + }), + 'context': , + 'entity_id': 'binary_sensor.upstairs_hallway_carbonmonoxided_tamper', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', + }) +# --- +# name: test_entity_registry[binary_sensor.upstairs_hallway_smokedetector-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'binary_sensor', + 'entity_category': None, + 'entity_id': 'binary_sensor.upstairs_hallway_smokedetector', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': None, + 'platform': 'totalconnect', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': None, + 'unique_id': '1234567_17_zone', + 'unit_of_measurement': None, + }) +# --- +# name: test_entity_registry[binary_sensor.upstairs_hallway_smokedetector-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'smoke', + 'friendly_name': 'Upstairs Hallway SmokeDetector', + 'location_id': 1234567, + 'partition': '1', + 'zone_id': '17', + }), + 'context': , + 'entity_id': 'binary_sensor.upstairs_hallway_smokedetector', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', + }) +# --- +# name: test_entity_registry[binary_sensor.upstairs_hallway_smokedetector_battery-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'binary_sensor', + 'entity_category': , + 'entity_id': 'binary_sensor.upstairs_hallway_smokedetector_battery', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': 'Battery', + 'platform': 'totalconnect', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': None, + 'unique_id': '1234567_17_low_battery', + 'unit_of_measurement': None, + }) +# --- +# name: test_entity_registry[binary_sensor.upstairs_hallway_smokedetector_battery-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'battery', + 'friendly_name': 'Upstairs Hallway SmokeDetector Battery', + 'location_id': 1234567, + 'partition': '1', + 'zone_id': '17', + }), + 'context': , + 'entity_id': 'binary_sensor.upstairs_hallway_smokedetector_battery', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', + }) +# --- +# name: test_entity_registry[binary_sensor.upstairs_hallway_smokedetector_tamper-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'binary_sensor', + 'entity_category': , + 'entity_id': 'binary_sensor.upstairs_hallway_smokedetector_tamper', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': 'Tamper', + 'platform': 'totalconnect', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': None, + 'unique_id': '1234567_17_tamper', + 'unit_of_measurement': None, + }) +# --- +# name: test_entity_registry[binary_sensor.upstairs_hallway_smokedetector_tamper-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'tamper', + 'friendly_name': 'Upstairs Hallway SmokeDetector Tamper', + 'location_id': 1234567, + 'partition': '1', + 'zone_id': '17', + }), + 'context': , + 'entity_id': 'binary_sensor.upstairs_hallway_smokedetector_tamper', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', + }) +# --- +# name: test_entity_registry[binary_sensor.zone_995_fire-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'binary_sensor', + 'entity_category': None, + 'entity_id': 'binary_sensor.zone_995_fire', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': None, + 'platform': 'totalconnect', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': None, + 'unique_id': '1234567_1995_zone', + 'unit_of_measurement': None, + }) +# --- +# name: test_entity_registry[binary_sensor.zone_995_fire-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'smoke', + 'friendly_name': 'Zone 995 Fire', + 'location_id': 1234567, + 'partition': '1', + 'zone_id': '1995', + }), + 'context': , + 'entity_id': 'binary_sensor.zone_995_fire', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', + }) +# --- +# name: test_entity_registry[binary_sensor.zone_995_fire_battery-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'binary_sensor', + 'entity_category': , + 'entity_id': 'binary_sensor.zone_995_fire_battery', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': 'Battery', + 'platform': 'totalconnect', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': None, + 'unique_id': '1234567_1995_low_battery', + 'unit_of_measurement': None, + }) +# --- +# name: test_entity_registry[binary_sensor.zone_995_fire_battery-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'battery', + 'friendly_name': 'Zone 995 Fire Battery', + 'location_id': 1234567, + 'partition': '1', + 'zone_id': '1995', + }), + 'context': , + 'entity_id': 'binary_sensor.zone_995_fire_battery', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', + }) +# --- +# name: test_entity_registry[binary_sensor.zone_995_fire_tamper-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'binary_sensor', + 'entity_category': , + 'entity_id': 'binary_sensor.zone_995_fire_tamper', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': 'Tamper', + 'platform': 'totalconnect', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': None, + 'unique_id': '1234567_1995_tamper', + 'unit_of_measurement': None, + }) +# --- +# name: test_entity_registry[binary_sensor.zone_995_fire_tamper-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'tamper', + 'friendly_name': 'Zone 995 Fire Tamper', + 'location_id': 1234567, + 'partition': '1', + 'zone_id': '1995', + }), + 'context': , + 'entity_id': 'binary_sensor.zone_995_fire_tamper', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', + }) +# --- +# name: test_entity_registry[binary_sensor.zone_996_medical-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'binary_sensor', + 'entity_category': None, + 'entity_id': 'binary_sensor.zone_996_medical', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': None, + 'platform': 'totalconnect', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': None, + 'unique_id': '1234567_1996_zone', + 'unit_of_measurement': None, + }) +# --- +# name: test_entity_registry[binary_sensor.zone_996_medical-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'smoke', + 'friendly_name': 'Zone 996 Medical', + 'location_id': 1234567, + 'partition': '1', + 'zone_id': '1996', + }), + 'context': , + 'entity_id': 'binary_sensor.zone_996_medical', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', + }) +# --- +# name: test_entity_registry[binary_sensor.zone_996_medical_battery-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'binary_sensor', + 'entity_category': , + 'entity_id': 'binary_sensor.zone_996_medical_battery', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': 'Battery', + 'platform': 'totalconnect', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': None, + 'unique_id': '1234567_1996_low_battery', + 'unit_of_measurement': None, + }) +# --- +# name: test_entity_registry[binary_sensor.zone_996_medical_battery-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'battery', + 'friendly_name': 'Zone 996 Medical Battery', + 'location_id': 1234567, + 'partition': '1', + 'zone_id': '1996', + }), + 'context': , + 'entity_id': 'binary_sensor.zone_996_medical_battery', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', + }) +# --- +# name: test_entity_registry[binary_sensor.zone_996_medical_tamper-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'binary_sensor', + 'entity_category': , + 'entity_id': 'binary_sensor.zone_996_medical_tamper', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': 'Tamper', + 'platform': 'totalconnect', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': None, + 'unique_id': '1234567_1996_tamper', + 'unit_of_measurement': None, + }) +# --- +# name: test_entity_registry[binary_sensor.zone_996_medical_tamper-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'tamper', + 'friendly_name': 'Zone 996 Medical Tamper', + 'location_id': 1234567, + 'partition': '1', + 'zone_id': '1996', + }), + 'context': , + 'entity_id': 'binary_sensor.zone_996_medical_tamper', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', + }) +# --- +# name: test_entity_registry[binary_sensor.zone_998_other-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'binary_sensor', + 'entity_category': None, + 'entity_id': 'binary_sensor.zone_998_other', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': None, + 'platform': 'totalconnect', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': None, + 'unique_id': '1234567_1998_zone', + 'unit_of_measurement': None, + }) +# --- +# name: test_entity_registry[binary_sensor.zone_998_other-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'smoke', + 'friendly_name': 'Zone 998 Other', + 'location_id': 1234567, + 'partition': '1', + 'zone_id': '1998', + }), + 'context': , + 'entity_id': 'binary_sensor.zone_998_other', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', + }) +# --- +# name: test_entity_registry[binary_sensor.zone_998_other_battery-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'binary_sensor', + 'entity_category': , + 'entity_id': 'binary_sensor.zone_998_other_battery', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': 'Battery', + 'platform': 'totalconnect', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': None, + 'unique_id': '1234567_1998_low_battery', + 'unit_of_measurement': None, + }) +# --- +# name: test_entity_registry[binary_sensor.zone_998_other_battery-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'battery', + 'friendly_name': 'Zone 998 Other Battery', + 'location_id': 1234567, + 'partition': '1', + 'zone_id': '1998', + }), + 'context': , + 'entity_id': 'binary_sensor.zone_998_other_battery', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', + }) +# --- +# name: test_entity_registry[binary_sensor.zone_998_other_tamper-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'binary_sensor', + 'entity_category': , + 'entity_id': 'binary_sensor.zone_998_other_tamper', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': 'Tamper', + 'platform': 'totalconnect', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': None, + 'unique_id': '1234567_1998_tamper', + 'unit_of_measurement': None, + }) +# --- +# name: test_entity_registry[binary_sensor.zone_998_other_tamper-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'tamper', + 'friendly_name': 'Zone 998 Other Tamper', + 'location_id': 1234567, + 'partition': '1', + 'zone_id': '1998', + }), + 'context': , + 'entity_id': 'binary_sensor.zone_998_other_tamper', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', + }) +# --- +# name: test_entity_registry[binary_sensor.zone_999_police-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'binary_sensor', + 'entity_category': None, + 'entity_id': 'binary_sensor.zone_999_police', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': None, + 'platform': 'totalconnect', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': None, + 'unique_id': '1234567_1999_zone', + 'unit_of_measurement': None, + }) +# --- +# name: test_entity_registry[binary_sensor.zone_999_police-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'smoke', + 'friendly_name': 'Zone 999 Police', + 'location_id': 1234567, + 'partition': '1', + 'zone_id': '1999', + }), + 'context': , + 'entity_id': 'binary_sensor.zone_999_police', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', + }) +# --- +# name: test_entity_registry[binary_sensor.zone_999_police_battery-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'binary_sensor', + 'entity_category': , + 'entity_id': 'binary_sensor.zone_999_police_battery', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': 'Battery', + 'platform': 'totalconnect', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': None, + 'unique_id': '1234567_1999_low_battery', + 'unit_of_measurement': None, + }) +# --- +# name: test_entity_registry[binary_sensor.zone_999_police_battery-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'battery', + 'friendly_name': 'Zone 999 Police Battery', + 'location_id': 1234567, + 'partition': '1', + 'zone_id': '1999', + }), + 'context': , + 'entity_id': 'binary_sensor.zone_999_police_battery', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', + }) +# --- +# name: test_entity_registry[binary_sensor.zone_999_police_tamper-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'binary_sensor', + 'entity_category': , + 'entity_id': 'binary_sensor.zone_999_police_tamper', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': 'Tamper', + 'platform': 'totalconnect', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': None, + 'unique_id': '1234567_1999_tamper', + 'unit_of_measurement': None, + }) +# --- +# name: test_entity_registry[binary_sensor.zone_999_police_tamper-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'tamper', + 'friendly_name': 'Zone 999 Police Tamper', + 'location_id': 1234567, + 'partition': '1', + 'zone_id': '1999', + }), + 'context': , + 'entity_id': 'binary_sensor.zone_999_police_tamper', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', }) # --- diff --git a/tests/components/totalconnect/snapshots/test_button.ambr b/tests/components/totalconnect/snapshots/test_button.ambr index 4367b035cc8..db90af349cb 100644 --- a/tests/components/totalconnect/snapshots/test_button.ambr +++ b/tests/components/totalconnect/snapshots/test_button.ambr @@ -1,4 +1,100 @@ # serializer version: 1 +# name: test_entity_registry[button.dining_room_two_door_bypass-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'button', + 'entity_category': , + 'entity_id': 'button.dining_room_two_door_bypass', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Bypass', + 'platform': 'totalconnect', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': 'bypass', + 'unique_id': '1234567_12_bypass', + 'unit_of_measurement': None, + }) +# --- +# name: test_entity_registry[button.dining_room_two_door_bypass-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': 'Dining Room Two Door Bypass', + }), + 'context': , + 'entity_id': 'button.dining_room_two_door_bypass', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'unknown', + }) +# --- +# name: test_entity_registry[button.doorbell_other_bypass-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'button', + 'entity_category': , + 'entity_id': 'button.doorbell_other_bypass', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Bypass', + 'platform': 'totalconnect', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': 'bypass', + 'unique_id': '1234567_7_bypass', + 'unit_of_measurement': None, + }) +# --- +# name: test_entity_registry[button.doorbell_other_bypass-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': 'Doorbell Other Bypass', + }), + 'context': , + 'entity_id': 'button.doorbell_other_bypass', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'unknown', + }) +# --- # name: test_entity_registry[button.fire_bypass-entry] EntityRegistryEntrySnapshot({ 'aliases': set({ @@ -30,7 +126,7 @@ 'suggested_object_id': None, 'supported_features': 0, 'translation_key': 'bypass', - 'unique_id': '123456_2_bypass', + 'unique_id': '1234567_3_bypass', 'unit_of_measurement': None, }) # --- @@ -47,6 +143,102 @@ 'state': 'unknown', }) # --- +# name: test_entity_registry[button.front_door_door_bypass-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'button', + 'entity_category': , + 'entity_id': 'button.front_door_door_bypass', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Bypass', + 'platform': 'totalconnect', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': 'bypass', + 'unique_id': '1234567_26_bypass', + 'unit_of_measurement': None, + }) +# --- +# name: test_entity_registry[button.front_door_door_bypass-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': 'Front Door Door Bypass', + }), + 'context': , + 'entity_id': 'button.front_door_door_bypass', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'unknown', + }) +# --- +# name: test_entity_registry[button.garage_side_other_bypass-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'button', + 'entity_category': , + 'entity_id': 'button.garage_side_other_bypass', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Bypass', + 'platform': 'totalconnect', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': 'bypass', + 'unique_id': '1234567_25_bypass', + 'unit_of_measurement': None, + }) +# --- +# name: test_entity_registry[button.garage_side_other_bypass-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': 'Garage Side Other Bypass', + }), + 'context': , + 'entity_id': 'button.garage_side_other_bypass', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'unknown', + }) +# --- # name: test_entity_registry[button.gas_bypass-entry] EntityRegistryEntrySnapshot({ 'aliases': set({ @@ -78,7 +270,7 @@ 'suggested_object_id': None, 'supported_features': 0, 'translation_key': 'bypass', - 'unique_id': '123456_3_bypass', + 'unique_id': '1234567_4_bypass', 'unit_of_measurement': None, }) # --- @@ -95,7 +287,7 @@ 'state': 'unknown', }) # --- -# name: test_entity_registry[button.motion_bypass-entry] +# name: test_entity_registry[button.living_room_two_window_bypass-entry] EntityRegistryEntrySnapshot({ 'aliases': set({ }), @@ -108,7 +300,7 @@ 'disabled_by': None, 'domain': 'button', 'entity_category': , - 'entity_id': 'button.motion_bypass', + 'entity_id': 'button.living_room_two_window_bypass', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -126,17 +318,257 @@ 'suggested_object_id': None, 'supported_features': 0, 'translation_key': 'bypass', - 'unique_id': '123456_4_bypass', + 'unique_id': '1234567_15_bypass', 'unit_of_measurement': None, }) # --- -# name: test_entity_registry[button.motion_bypass-state] +# name: test_entity_registry[button.living_room_two_window_bypass-state] StateSnapshot({ 'attributes': ReadOnlyDict({ - 'friendly_name': 'Motion Bypass', + 'friendly_name': 'Living Room Two Window Bypass', }), 'context': , - 'entity_id': 'button.motion_bypass', + 'entity_id': 'button.living_room_two_window_bypass', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'unknown', + }) +# --- +# name: test_entity_registry[button.living_room_window_bypass-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'button', + 'entity_category': , + 'entity_id': 'button.living_room_window_bypass', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Bypass', + 'platform': 'totalconnect', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': 'bypass', + 'unique_id': '1234567_14_bypass', + 'unit_of_measurement': None, + }) +# --- +# name: test_entity_registry[button.living_room_window_bypass-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': 'Living Room Window Bypass', + }), + 'context': , + 'entity_id': 'button.living_room_window_bypass', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'unknown', + }) +# --- +# name: test_entity_registry[button.master_bedroom_door_bypass-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'button', + 'entity_category': , + 'entity_id': 'button.master_bedroom_door_bypass', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Bypass', + 'platform': 'totalconnect', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': 'bypass', + 'unique_id': '1234567_10_bypass', + 'unit_of_measurement': None, + }) +# --- +# name: test_entity_registry[button.master_bedroom_door_bypass-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': 'Master Bedroom Door Bypass', + }), + 'context': , + 'entity_id': 'button.master_bedroom_door_bypass', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'unknown', + }) +# --- +# name: test_entity_registry[button.office_back_door_bypass-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'button', + 'entity_category': , + 'entity_id': 'button.office_back_door_bypass', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Bypass', + 'platform': 'totalconnect', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': 'bypass', + 'unique_id': '1234567_9_bypass', + 'unit_of_measurement': None, + }) +# --- +# name: test_entity_registry[button.office_back_door_bypass-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': 'Office Back Door Bypass', + }), + 'context': , + 'entity_id': 'button.office_back_door_bypass', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'unknown', + }) +# --- +# name: test_entity_registry[button.office_side_door_bypass-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'button', + 'entity_category': , + 'entity_id': 'button.office_side_door_bypass', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Bypass', + 'platform': 'totalconnect', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': 'bypass', + 'unique_id': '1234567_8_bypass', + 'unit_of_measurement': None, + }) +# --- +# name: test_entity_registry[button.office_side_door_bypass-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': 'Office Side Door Bypass', + }), + 'context': , + 'entity_id': 'button.office_side_door_bypass', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'unknown', + }) +# --- +# name: test_entity_registry[button.patio_door_bypass-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'button', + 'entity_category': , + 'entity_id': 'button.patio_door_bypass', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Bypass', + 'platform': 'totalconnect', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': 'bypass', + 'unique_id': '1234567_13_bypass', + 'unit_of_measurement': None, + }) +# --- +# name: test_entity_registry[button.patio_door_bypass-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': 'Patio Door Bypass', + }), + 'context': , + 'entity_id': 'button.patio_door_bypass', 'last_changed': , 'last_reported': , 'last_updated': , @@ -174,7 +606,7 @@ 'suggested_object_id': None, 'supported_features': 0, 'translation_key': 'bypass', - 'unique_id': '123456_1_bypass', + 'unique_id': '1234567_2_bypass', 'unit_of_measurement': None, }) # --- @@ -191,6 +623,54 @@ 'state': 'unknown', }) # --- +# name: test_entity_registry[button.temperature_bypass-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'button', + 'entity_category': , + 'entity_id': 'button.temperature_bypass', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Bypass', + 'platform': 'totalconnect', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': 'bypass', + 'unique_id': '1234567_6_bypass', + 'unit_of_measurement': None, + }) +# --- +# name: test_entity_registry[button.temperature_bypass-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': 'Temperature Bypass', + }), + 'context': , + 'entity_id': 'button.temperature_bypass', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'unknown', + }) +# --- # name: test_entity_registry[button.test_bypass_all-entry] EntityRegistryEntrySnapshot({ 'aliases': set({ @@ -222,7 +702,7 @@ 'suggested_object_id': None, 'supported_features': 0, 'translation_key': 'bypass_all', - 'unique_id': '123456_bypass_all', + 'unique_id': '1234567_bypass_all', 'unit_of_measurement': None, }) # --- @@ -270,7 +750,7 @@ 'suggested_object_id': None, 'supported_features': 0, 'translation_key': 'clear_bypass', - 'unique_id': '123456_clear_bypass', + 'unique_id': '1234567_clear_bypass', 'unit_of_measurement': None, }) # --- @@ -287,3 +767,51 @@ 'state': 'unknown', }) # --- +# name: test_entity_registry[button.unknown_bypass-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'button', + 'entity_category': , + 'entity_id': 'button.unknown_bypass', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Bypass', + 'platform': 'totalconnect', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': 'bypass', + 'unique_id': '1234567_5_bypass', + 'unit_of_measurement': None, + }) +# --- +# name: test_entity_registry[button.unknown_bypass-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': 'Unknown Bypass', + }), + 'context': , + 'entity_id': 'button.unknown_bypass', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'unknown', + }) +# --- diff --git a/tests/components/totalconnect/snapshots/test_diagnostics.ambr b/tests/components/totalconnect/snapshots/test_diagnostics.ambr new file mode 100644 index 00000000000..026afca0920 --- /dev/null +++ b/tests/components/totalconnect/snapshots/test_diagnostics.ambr @@ -0,0 +1,619 @@ +# serializer version: 1 +# name: test_entry_diagnostics + dict({ + 'client': dict({ + 'auto_bypass_low_battery': False, + 'invalid_credentials': False, + 'module_flags': dict({ + }), + 'retry_delay': 0, + }), + 'locations': list([ + dict({ + 'ac_loss': False, + 'arming_state': dict({ + '__type': "", + 'repr': '', + }), + 'auto_bypass_low_battery': False, + 'cover_tampered': False, + 'devices': list([ + dict({ + 'class_id': 1, + 'device_id': 7654321, + 'flags': dict({ + 'AllowUserSlotEditing': '0', + 'ArmHomeSupported': '1', + 'ArmNightInSceneSupported': '1', + 'BLEDisarmCapable': '0', + 'BuiltInCameraSettingsSupported': '0', + 'CalCapable': '1', + 'CanArmNightStay': '0', + 'CanBeSentToPanel': '1', + 'CanSupportMultiPartition': '0', + 'CanSupportRapid': '0', + 'DoubleDisarmRequired': '0', + 'DuplicateUserCodeCheck': '1', + 'DuplicateUserSyncStatus': '0', + 'EnableBLEMode': '0', + 'IsAVCEnabled': '0', + 'IsCompetitorClearBypass': '0', + 'IsConnectedPanel': '1', + 'IsKeypadSupported': '0', + 'IsNotReadyStateSupported': '0', + 'IsPanelWiFiResetSupported': '0', + 'MaxPartitionCount': '4', + 'MultipleAuthorityLevelSupported': '1', + 'OnBoardingSupport': '0', + 'PanelType': '12', + 'PanelVariant': '1', + 'PartitionAdded': '0', + 'PartitionCount': '0', + 'PromptForImportSecuritySettings': '0', + 'PromptForInstallerCode': '0', + 'PromptForUserCode': '0', + 'TMSCloudSupported': '0', + 'UserCodeLength': '4', + 'UserCodeLengthChanged': '0', + 'VideoOnPanelSupported': '1', + 'WifiEnrollmentSupported': '1', + 'ZWaveThermostatScheduleDisabled': '0', + 'isArmStatusWithoutExitDelayNotSupported': '0', + }), + 'name': 'test', + 'security_panel_type_id': 12, + 'serial_number': '**REDACTED**', + 'serial_text': None, + }), + ]), + 'location_id': 1234567, + 'low_battery': False, + 'module_flags': dict({ + 'can_bypass_zones': True, + 'can_clear_bypass': True, + 'can_set_usercodes': True, + }), + 'name': 'Test Location', + 'partitions': list([ + dict({ + 'arming_state': dict({ + '__type': "", + 'repr': '', + }), + 'exit_delay_timer': 0, + 'is_common_enabled': False, + 'is_fire_enabled': False, + 'is_locked': False, + 'is_new_partition': False, + 'is_night_stay_enabled': 0, + 'is_stay_armed': False, + 'name': 'Test1', + 'partition_id': 1, + }), + dict({ + 'arming_state': dict({ + '__type': "", + 'repr': '', + }), + 'exit_delay_timer': 0, + 'is_common_enabled': False, + 'is_fire_enabled': False, + 'is_locked': False, + 'is_new_partition': False, + 'is_night_stay_enabled': 0, + 'is_stay_armed': False, + 'name': 'Test2', + 'partition_id': 2, + }), + ]), + 'security_device_id': 7654321, + 'zones': list([ + dict({ + 'alarm_report_state': 1, + 'battery_level': -1, + 'can_be_bypassed': 1, + 'chime_state': 1, + 'description': 'Security', + 'device_type': 0, + 'loop_number': 1, + 'partition': 1, + 'response_type': '1', + 'sensor_serial_number': '**REDACTED**', + 'signal_strength': -1, + 'status': 0, + 'supervision_type': 0, + 'zone_id': 2, + 'zone_type_id': 1, + }), + dict({ + 'alarm_report_state': 1, + 'battery_level': -1, + 'can_be_bypassed': 1, + 'chime_state': 0, + 'description': 'Fire', + 'device_type': 2, + 'loop_number': 1, + 'partition': 1, + 'response_type': '4', + 'sensor_serial_number': '**REDACTED**', + 'signal_strength': -1, + 'status': 0, + 'supervision_type': 0, + 'zone_id': 3, + 'zone_type_id': 9, + }), + dict({ + 'alarm_report_state': 1, + 'battery_level': -1, + 'can_be_bypassed': 1, + 'chime_state': 0, + 'description': 'Gas', + 'device_type': 2, + 'loop_number': 1, + 'partition': 1, + 'response_type': '4', + 'sensor_serial_number': '**REDACTED**', + 'signal_strength': -1, + 'status': 0, + 'supervision_type': 0, + 'zone_id': 4, + 'zone_type_id': 14, + }), + dict({ + 'alarm_report_state': 1, + 'battery_level': -1, + 'can_be_bypassed': 1, + 'chime_state': 0, + 'description': 'Unknown', + 'device_type': 2, + 'loop_number': 1, + 'partition': 1, + 'response_type': '4', + 'sensor_serial_number': '**REDACTED**', + 'signal_strength': -1, + 'status': 0, + 'supervision_type': 0, + 'zone_id': 5, + 'zone_type_id': 99, + }), + dict({ + 'alarm_report_state': 1, + 'battery_level': -1, + 'can_be_bypassed': 1, + 'chime_state': 1, + 'description': 'Temperature', + 'device_type': 0, + 'loop_number': 1, + 'partition': 1, + 'response_type': '1', + 'sensor_serial_number': '**REDACTED**', + 'signal_strength': -1, + 'status': 0, + 'supervision_type': 1, + 'zone_id': 6, + 'zone_type_id': 12, + }), + dict({ + 'alarm_report_state': 0, + 'battery_level': 5, + 'can_be_bypassed': 1, + 'chime_state': 1, + 'description': 'Doorbell Other', + 'device_type': 15, + 'loop_number': 2, + 'partition': 1, + 'response_type': '53', + 'sensor_serial_number': '**REDACTED**', + 'signal_strength': 2, + 'status': 0, + 'supervision_type': 0, + 'zone_id': 7, + 'zone_type_id': 53, + }), + dict({ + 'alarm_report_state': 1, + 'battery_level': -1, + 'can_be_bypassed': 1, + 'chime_state': 1, + 'description': 'Office Side Door', + 'device_type': 0, + 'loop_number': 1, + 'partition': 1, + 'response_type': '3', + 'sensor_serial_number': '**REDACTED**', + 'signal_strength': -1, + 'status': 1, + 'supervision_type': 0, + 'zone_id': 8, + 'zone_type_id': 3, + }), + dict({ + 'alarm_report_state': 1, + 'battery_level': -1, + 'can_be_bypassed': 1, + 'chime_state': 1, + 'description': 'Office Back Door', + 'device_type': 0, + 'loop_number': 1, + 'partition': 1, + 'response_type': '3', + 'sensor_serial_number': '**REDACTED**', + 'signal_strength': -1, + 'status': 0, + 'supervision_type': 0, + 'zone_id': 9, + 'zone_type_id': 3, + }), + dict({ + 'alarm_report_state': 1, + 'battery_level': -1, + 'can_be_bypassed': 1, + 'chime_state': 1, + 'description': 'Master Bedroom Door', + 'device_type': 0, + 'loop_number': 1, + 'partition': 1, + 'response_type': '1', + 'sensor_serial_number': '**REDACTED**', + 'signal_strength': -1, + 'status': 0, + 'supervision_type': 0, + 'zone_id': 10, + 'zone_type_id': 1, + }), + dict({ + 'alarm_report_state': 1, + 'battery_level': -1, + 'can_be_bypassed': 1, + 'chime_state': 1, + 'description': 'Dining Room Two Door', + 'device_type': 0, + 'loop_number': 1, + 'partition': 1, + 'response_type': '3', + 'sensor_serial_number': '**REDACTED**', + 'signal_strength': -1, + 'status': 0, + 'supervision_type': 0, + 'zone_id': 12, + 'zone_type_id': 3, + }), + dict({ + 'alarm_report_state': 1, + 'battery_level': -1, + 'can_be_bypassed': 1, + 'chime_state': 1, + 'description': 'Patio Door', + 'device_type': 0, + 'loop_number': 1, + 'partition': 1, + 'response_type': '3', + 'sensor_serial_number': '**REDACTED**', + 'signal_strength': -1, + 'status': 0, + 'supervision_type': 0, + 'zone_id': 13, + 'zone_type_id': 3, + }), + dict({ + 'alarm_report_state': 1, + 'battery_level': -1, + 'can_be_bypassed': 1, + 'chime_state': 1, + 'description': 'Living Room Window', + 'device_type': 1, + 'loop_number': 1, + 'partition': 1, + 'response_type': '3', + 'sensor_serial_number': '**REDACTED**', + 'signal_strength': -1, + 'status': 0, + 'supervision_type': 0, + 'zone_id': 14, + 'zone_type_id': 3, + }), + dict({ + 'alarm_report_state': 1, + 'battery_level': -1, + 'can_be_bypassed': 1, + 'chime_state': 1, + 'description': 'Living Room Two Window', + 'device_type': 1, + 'loop_number': 1, + 'partition': 1, + 'response_type': '3', + 'sensor_serial_number': '**REDACTED**', + 'signal_strength': -1, + 'status': 0, + 'supervision_type': 0, + 'zone_id': 15, + 'zone_type_id': 3, + }), + dict({ + 'alarm_report_state': 1, + 'battery_level': -1, + 'can_be_bypassed': 0, + 'chime_state': 0, + 'description': 'Apartment SmokeDetector', + 'device_type': 4, + 'loop_number': 1, + 'partition': 1, + 'response_type': '9', + 'sensor_serial_number': '**REDACTED**', + 'signal_strength': -1, + 'status': 0, + 'supervision_type': 0, + 'zone_id': 16, + 'zone_type_id': 9, + }), + dict({ + 'alarm_report_state': 1, + 'battery_level': -1, + 'can_be_bypassed': 0, + 'chime_state': 0, + 'description': 'Upstairs Hallway SmokeDetector', + 'device_type': 4, + 'loop_number': 1, + 'partition': 1, + 'response_type': '9', + 'sensor_serial_number': '**REDACTED**', + 'signal_strength': -1, + 'status': 0, + 'supervision_type': 0, + 'zone_id': 17, + 'zone_type_id': 9, + }), + dict({ + 'alarm_report_state': 1, + 'battery_level': -1, + 'can_be_bypassed': 0, + 'chime_state': 0, + 'description': 'Downstairs Hallway SmokeDetector', + 'device_type': 4, + 'loop_number': 1, + 'partition': 1, + 'response_type': '9', + 'sensor_serial_number': '**REDACTED**', + 'signal_strength': -1, + 'status': 0, + 'supervision_type': 0, + 'zone_id': 18, + 'zone_type_id': 9, + }), + dict({ + 'alarm_report_state': 1, + 'battery_level': -1, + 'can_be_bypassed': 0, + 'chime_state': 0, + 'description': 'Kid Bedroom SmokeDetector', + 'device_type': 4, + 'loop_number': 1, + 'partition': 1, + 'response_type': '9', + 'sensor_serial_number': '**REDACTED**', + 'signal_strength': -1, + 'status': 0, + 'supervision_type': 0, + 'zone_id': 19, + 'zone_type_id': 9, + }), + dict({ + 'alarm_report_state': 1, + 'battery_level': -1, + 'can_be_bypassed': 0, + 'chime_state': 0, + 'description': 'Guest Bedroom SmokeDetector', + 'device_type': 4, + 'loop_number': 1, + 'partition': 1, + 'response_type': '9', + 'sensor_serial_number': '**REDACTED**', + 'signal_strength': -1, + 'status': 0, + 'supervision_type': 0, + 'zone_id': 20, + 'zone_type_id': 9, + }), + dict({ + 'alarm_report_state': 1, + 'battery_level': -1, + 'can_be_bypassed': 0, + 'chime_state': 0, + 'description': 'Apartment CarbonMonoxideDetecto', + 'device_type': 6, + 'loop_number': 1, + 'partition': 1, + 'response_type': '14', + 'sensor_serial_number': '**REDACTED**', + 'signal_strength': -1, + 'status': 0, + 'supervision_type': 0, + 'zone_id': 21, + 'zone_type_id': 14, + }), + dict({ + 'alarm_report_state': 1, + 'battery_level': -1, + 'can_be_bypassed': 0, + 'chime_state': 0, + 'description': 'Downstairs Hallway CarbonMonoxid', + 'device_type': 6, + 'loop_number': 1, + 'partition': 1, + 'response_type': '14', + 'sensor_serial_number': '**REDACTED**', + 'signal_strength': -1, + 'status': 0, + 'supervision_type': 0, + 'zone_id': 22, + 'zone_type_id': 14, + }), + dict({ + 'alarm_report_state': 1, + 'battery_level': -1, + 'can_be_bypassed': 0, + 'chime_state': 0, + 'description': 'Upstairs Hallway CarbonMonoxideD', + 'device_type': 6, + 'loop_number': 1, + 'partition': 1, + 'response_type': '14', + 'sensor_serial_number': '**REDACTED**', + 'signal_strength': -1, + 'status': 0, + 'supervision_type': 0, + 'zone_id': 23, + 'zone_type_id': 14, + }), + dict({ + 'alarm_report_state': 1, + 'battery_level': -1, + 'can_be_bypassed': 0, + 'chime_state': 0, + 'description': 'Master Bedroom SmokeDetector', + 'device_type': 4, + 'loop_number': 1, + 'partition': 1, + 'response_type': '9', + 'sensor_serial_number': '**REDACTED**', + 'signal_strength': -1, + 'status': 0, + 'supervision_type': 0, + 'zone_id': 24, + 'zone_type_id': 9, + }), + dict({ + 'alarm_report_state': 1, + 'battery_level': 5, + 'can_be_bypassed': 1, + 'chime_state': 0, + 'description': 'Garage Side Other', + 'device_type': 15, + 'loop_number': 1, + 'partition': 1, + 'response_type': '23', + 'sensor_serial_number': '**REDACTED**', + 'signal_strength': 3, + 'status': 0, + 'supervision_type': 0, + 'zone_id': 25, + 'zone_type_id': 23, + }), + dict({ + 'alarm_report_state': 1, + 'battery_level': 5, + 'can_be_bypassed': 1, + 'chime_state': 1, + 'description': 'Front Door Door', + 'device_type': 0, + 'loop_number': 1, + 'partition': 1, + 'response_type': '1', + 'sensor_serial_number': '**REDACTED**', + 'signal_strength': 5, + 'status': 0, + 'supervision_type': 0, + 'zone_id': 26, + 'zone_type_id': 1, + }), + dict({ + 'alarm_report_state': None, + 'battery_level': -1, + 'can_be_bypassed': 0, + 'chime_state': None, + 'description': 'Master Bedroom Keypad', + 'device_type': None, + 'loop_number': None, + 'partition': 1, + 'response_type': None, + 'sensor_serial_number': None, + 'signal_strength': -1, + 'status': 0, + 'supervision_type': None, + 'zone_id': 800, + 'zone_type_id': 50, + }), + dict({ + 'alarm_report_state': None, + 'battery_level': -1, + 'can_be_bypassed': 0, + 'chime_state': None, + 'description': 'Zone 995 Fire', + 'device_type': None, + 'loop_number': None, + 'partition': 1, + 'response_type': None, + 'sensor_serial_number': None, + 'signal_strength': -1, + 'status': 0, + 'supervision_type': None, + 'zone_id': 1995, + 'zone_type_id': 9, + }), + dict({ + 'alarm_report_state': None, + 'battery_level': -1, + 'can_be_bypassed': 0, + 'chime_state': None, + 'description': 'Zone 996 Medical', + 'device_type': None, + 'loop_number': None, + 'partition': 1, + 'response_type': None, + 'sensor_serial_number': None, + 'signal_strength': -1, + 'status': 0, + 'supervision_type': None, + 'zone_id': 1996, + 'zone_type_id': 15, + }), + dict({ + 'alarm_report_state': None, + 'battery_level': -1, + 'can_be_bypassed': 0, + 'chime_state': None, + 'description': 'Zone 998 Other', + 'device_type': None, + 'loop_number': None, + 'partition': 1, + 'response_type': None, + 'sensor_serial_number': None, + 'signal_strength': -1, + 'status': 0, + 'supervision_type': None, + 'zone_id': 1998, + 'zone_type_id': 6, + }), + dict({ + 'alarm_report_state': None, + 'battery_level': -1, + 'can_be_bypassed': 0, + 'chime_state': None, + 'description': 'Zone 999 Police', + 'device_type': None, + 'loop_number': None, + 'partition': 1, + 'response_type': None, + 'sensor_serial_number': None, + 'signal_strength': -1, + 'status': 0, + 'supervision_type': None, + 'zone_id': 1999, + 'zone_type_id': 7, + }), + ]), + }), + ]), + 'user': dict({ + 'config_admin': True, + 'features': dict({ + 'can_bypass_zones': True, + 'can_clear_bypass': True, + 'can_set_usercodes': True, + }), + 'master': True, + 'security_problem': False, + 'user_admin': True, + }), + }) +# --- diff --git a/tests/components/totalconnect/test_alarm_control_panel.py b/tests/components/totalconnect/test_alarm_control_panel.py index 6f7d8163362..040cdf5d9ed 100644 --- a/tests/components/totalconnect/test_alarm_control_panel.py +++ b/tests/components/totalconnect/test_alarm_control_panel.py @@ -1,19 +1,16 @@ """Tests for the TotalConnect alarm control panel device.""" from datetime import timedelta -from unittest.mock import patch +from unittest.mock import AsyncMock, patch from freezegun.api import FrozenDateTimeFactory import pytest from syrupy.assertion import SnapshotAssertion -from total_connect_client.exceptions import ( - AuthenticationError, - ServiceUnavailable, - TotalConnectError, -) +from total_connect_client import ArmingState, ArmType +from total_connect_client.exceptions import BadResultCodeError, UsercodeInvalid from homeassistant.components.alarm_control_panel import ( - DOMAIN as ALARM_DOMAIN, + DOMAIN as ALARM_CONTROL_PANEL_DOMAIN, AlarmControlPanelState, ) from homeassistant.components.totalconnect.alarm_control_panel import ( @@ -21,593 +18,375 @@ from homeassistant.components.totalconnect.alarm_control_panel import ( SERVICE_ALARM_ARM_HOME_INSTANT, ) from homeassistant.components.totalconnect.const import DOMAIN -from homeassistant.components.totalconnect.coordinator import SCAN_INTERVAL -from homeassistant.config_entries import SOURCE_REAUTH, ConfigEntryState from homeassistant.const import ( + ATTR_CODE, ATTR_ENTITY_ID, SERVICE_ALARM_ARM_AWAY, SERVICE_ALARM_ARM_HOME, SERVICE_ALARM_ARM_NIGHT, SERVICE_ALARM_DISARM, - STATE_UNAVAILABLE, + Platform, ) from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError, ServiceValidationError from homeassistant.helpers import entity_registry as er -from homeassistant.helpers.entity_component import async_update_entity -from .common import ( - LOCATION_ID, - RESPONSE_ARM_FAILURE, - RESPONSE_ARM_SUCCESS, - RESPONSE_ARMED_AWAY, - RESPONSE_ARMED_CUSTOM, - RESPONSE_ARMED_NIGHT, - RESPONSE_ARMED_STAY, - RESPONSE_ARMING, - RESPONSE_DISARM_FAILURE, - RESPONSE_DISARM_SUCCESS, - RESPONSE_DISARMED, - RESPONSE_DISARMING, - RESPONSE_SUCCESS, - RESPONSE_UNKNOWN, - RESPONSE_USER_CODE_INVALID, - TOTALCONNECT_REQUEST, - USERCODES, - setup_platform, -) +from . import setup_integration +from .const import CODE -from tests.common import async_fire_time_changed, snapshot_platform +from tests.common import MockConfigEntry, async_fire_time_changed, snapshot_platform ENTITY_ID = "alarm_control_panel.test" ENTITY_ID_2 = "alarm_control_panel.test_partition_2" -CODE = "-1" DATA = {ATTR_ENTITY_ID: ENTITY_ID} DELAY = timedelta(seconds=10) +ARMING_HELPER = "homeassistant.components.totalconnect.alarm_control_panel.ArmingHelper" -async def test_attributes( - hass: HomeAssistant, entity_registry: er.EntityRegistry, snapshot: SnapshotAssertion + +async def test_entities( + hass: HomeAssistant, + entity_registry: er.EntityRegistry, + mock_client: AsyncMock, + mock_config_entry: MockConfigEntry, + snapshot: SnapshotAssertion, ) -> None: """Test the alarm control panel attributes are correct.""" - entry = await setup_platform(hass, ALARM_DOMAIN) with patch( - "homeassistant.components.totalconnect.TotalConnectClient.request", - return_value=RESPONSE_DISARMED, - ) as mock_request: - await async_update_entity(hass, ENTITY_ID) - await hass.async_block_till_done() - mock_request.assert_called_once() + "homeassistant.components.totalconnect.PLATFORMS", + [Platform.ALARM_CONTROL_PANEL], + ): + await setup_integration(hass, mock_config_entry) - await snapshot_platform(hass, entity_registry, snapshot, entry.entry_id) - assert mock_request.call_count == 1 + await snapshot_platform(hass, entity_registry, snapshot, mock_config_entry.entry_id) -async def test_arm_home_success( - hass: HomeAssistant, freezer: FrozenDateTimeFactory +@pytest.mark.parametrize("code_required", [False, True]) +@pytest.mark.parametrize( + ("service", "arm_type"), + [ + (SERVICE_ALARM_ARM_HOME, ArmType.STAY), + (SERVICE_ALARM_ARM_NIGHT, ArmType.STAY_NIGHT), + (SERVICE_ALARM_ARM_AWAY, ArmType.AWAY), + ], +) +async def test_arming( + hass: HomeAssistant, + mock_client: AsyncMock, + mock_partition: AsyncMock, + mock_config_entry: MockConfigEntry, + service: str, + arm_type: ArmType, ) -> None: - """Test arm home method success.""" - responses = [RESPONSE_DISARMED, RESPONSE_ARM_SUCCESS, RESPONSE_ARMED_STAY] - await setup_platform(hass, ALARM_DOMAIN) - with patch(TOTALCONNECT_REQUEST, side_effect=responses) as mock_request: - await async_update_entity(hass, ENTITY_ID) - await hass.async_block_till_done() - assert hass.states.get(ENTITY_ID).state == AlarmControlPanelState.DISARMED - assert hass.states.get(ENTITY_ID_2).state == AlarmControlPanelState.DISARMED - assert mock_request.call_count == 1 + """Test arming method success.""" + await setup_integration(hass, mock_config_entry) - await hass.services.async_call( - ALARM_DOMAIN, SERVICE_ALARM_ARM_HOME, DATA, blocking=True - ) - assert mock_request.call_count == 2 + entity_id = "alarm_control_panel.test" + assert hass.states.get(entity_id).state == AlarmControlPanelState.DISARMED - freezer.tick(DELAY) - async_fire_time_changed(hass) - await hass.async_block_till_done() - assert mock_request.call_count == 3 - assert hass.states.get(ENTITY_ID).state == AlarmControlPanelState.ARMED_HOME - # second partition should not be armed - assert hass.states.get(ENTITY_ID_2).state == AlarmControlPanelState.DISARMED + mock_partition.arming_state = ArmingState.ARMING + + await hass.services.async_call( + ALARM_CONTROL_PANEL_DOMAIN, + service, + {ATTR_ENTITY_ID: entity_id, ATTR_CODE: CODE}, + blocking=True, + ) + assert mock_partition.arm.call_args[1] == {"arm_type": arm_type, "usercode": ""} + + assert hass.states.get(entity_id).state == AlarmControlPanelState.ARMING -async def test_arm_home_failure(hass: HomeAssistant) -> None: - """Test arm home method failure.""" - responses = [RESPONSE_DISARMED, RESPONSE_ARM_FAILURE, RESPONSE_USER_CODE_INVALID] - await setup_platform(hass, ALARM_DOMAIN) - with patch(TOTALCONNECT_REQUEST, side_effect=responses) as mock_request: - await async_update_entity(hass, ENTITY_ID) - await hass.async_block_till_done() - assert hass.states.get(ENTITY_ID).state == AlarmControlPanelState.DISARMED - assert mock_request.call_count == 1 - - with pytest.raises(HomeAssistantError) as err: - await hass.services.async_call( - ALARM_DOMAIN, SERVICE_ALARM_ARM_HOME, DATA, blocking=True - ) - await hass.async_block_till_done() - assert f"{err.value}" == "Failed to arm home test" - assert hass.states.get(ENTITY_ID).state == AlarmControlPanelState.DISARMED - assert mock_request.call_count == 2 - - # config entry usercode is invalid - with pytest.raises(HomeAssistantError) as err: - await hass.services.async_call( - ALARM_DOMAIN, SERVICE_ALARM_ARM_HOME, DATA, blocking=True - ) - await hass.async_block_till_done() - assert f"{err.value}" == "Usercode is invalid, did not arm home" - assert hass.states.get(ENTITY_ID).state == AlarmControlPanelState.DISARMED - # should have started a re-auth flow - assert len(hass.config_entries.flow.async_progress_by_handler(DOMAIN)) == 1 - assert mock_request.call_count == 3 - - -async def test_arm_home_instant_success( - hass: HomeAssistant, freezer: FrozenDateTimeFactory +@pytest.mark.parametrize("code_required", [True]) +@pytest.mark.parametrize( + ("service", "arm_type"), + [ + (SERVICE_ALARM_ARM_HOME, ArmType.STAY), + (SERVICE_ALARM_ARM_NIGHT, ArmType.STAY_NIGHT), + (SERVICE_ALARM_ARM_AWAY, ArmType.AWAY), + ], +) +async def test_arming_invalid_usercode( + hass: HomeAssistant, + mock_client: AsyncMock, + mock_partition: AsyncMock, + mock_location: AsyncMock, + mock_config_entry: MockConfigEntry, + service: str, + arm_type: ArmType, ) -> None: - """Test arm home instant method success.""" - responses = [RESPONSE_DISARMED, RESPONSE_ARM_SUCCESS, RESPONSE_ARMED_STAY] - await setup_platform(hass, ALARM_DOMAIN) - with patch(TOTALCONNECT_REQUEST, side_effect=responses) as mock_request: - await async_update_entity(hass, ENTITY_ID) - await hass.async_block_till_done() - assert hass.states.get(ENTITY_ID).state == AlarmControlPanelState.DISARMED - assert hass.states.get(ENTITY_ID_2).state == AlarmControlPanelState.DISARMED - assert mock_request.call_count == 1 + """Test arming method with invalid usercode.""" + await setup_integration(hass, mock_config_entry) + entity_id = "alarm_control_panel.test" + assert hass.states.get(entity_id).state == AlarmControlPanelState.DISARMED + assert mock_location.get_panel_meta_data.call_count == 1 + + mock_partition.arming_state = ArmingState.ARMING + + with pytest.raises(ServiceValidationError, match="Incorrect code entered"): await hass.services.async_call( - DOMAIN, SERVICE_ALARM_ARM_HOME_INSTANT, DATA, blocking=True + ALARM_CONTROL_PANEL_DOMAIN, + service, + {ATTR_ENTITY_ID: entity_id, ATTR_CODE: "invalid_code"}, + blocking=True, ) - assert mock_request.call_count == 2 - - freezer.tick(DELAY) - async_fire_time_changed(hass) - await hass.async_block_till_done() - assert mock_request.call_count == 3 - assert hass.states.get(ENTITY_ID).state == AlarmControlPanelState.ARMED_HOME + assert mock_partition.arm.call_count == 0 + assert mock_location.get_panel_meta_data.call_count == 1 -async def test_arm_home_instant_failure(hass: HomeAssistant) -> None: - """Test arm home instant method failure.""" - responses = [RESPONSE_DISARMED, RESPONSE_ARM_FAILURE, RESPONSE_USER_CODE_INVALID] - await setup_platform(hass, ALARM_DOMAIN) - with patch(TOTALCONNECT_REQUEST, side_effect=responses) as mock_request: - await async_update_entity(hass, ENTITY_ID) - await hass.async_block_till_done() - assert hass.states.get(ENTITY_ID).state == AlarmControlPanelState.DISARMED - assert mock_request.call_count == 1 - - with pytest.raises(HomeAssistantError) as err: - await hass.services.async_call( - DOMAIN, SERVICE_ALARM_ARM_HOME_INSTANT, DATA, blocking=True - ) - await hass.async_block_till_done() - assert f"{err.value}" == "Failed to arm home instant test" - assert hass.states.get(ENTITY_ID).state == AlarmControlPanelState.DISARMED - assert mock_request.call_count == 2 - - # usercode is invalid - with pytest.raises(HomeAssistantError) as err: - await hass.services.async_call( - DOMAIN, SERVICE_ALARM_ARM_HOME_INSTANT, DATA, blocking=True - ) - await hass.async_block_till_done() - assert str(err.value) == "Usercode is invalid, did not arm home instant" - assert hass.states.get(ENTITY_ID).state == AlarmControlPanelState.DISARMED - # should have started a re-auth flow - assert len(hass.config_entries.flow.async_progress_by_handler(DOMAIN)) == 1 - assert mock_request.call_count == 3 - - -async def test_arm_away_instant_success( - hass: HomeAssistant, freezer: FrozenDateTimeFactory +@pytest.mark.parametrize("code_required", [False, True]) +async def test_disarming( + hass: HomeAssistant, + mock_client: AsyncMock, + mock_partition: AsyncMock, + mock_config_entry: MockConfigEntry, ) -> None: - """Test arm home instant method success.""" - responses = [RESPONSE_DISARMED, RESPONSE_ARM_SUCCESS, RESPONSE_ARMED_AWAY] - await setup_platform(hass, ALARM_DOMAIN) - with patch(TOTALCONNECT_REQUEST, side_effect=responses) as mock_request: - await async_update_entity(hass, ENTITY_ID) - await hass.async_block_till_done() - assert hass.states.get(ENTITY_ID).state == AlarmControlPanelState.DISARMED - assert hass.states.get(ENTITY_ID_2).state == AlarmControlPanelState.DISARMED - assert mock_request.call_count == 1 + """Test disarming method success.""" + await setup_integration(hass, mock_config_entry) - await hass.services.async_call( - DOMAIN, SERVICE_ALARM_ARM_AWAY_INSTANT, DATA, blocking=True - ) - assert mock_request.call_count == 2 + entity_id = "alarm_control_panel.test" + assert hass.states.get(entity_id).state == AlarmControlPanelState.DISARMED - freezer.tick(DELAY) - async_fire_time_changed(hass) - await hass.async_block_till_done() - assert mock_request.call_count == 3 - assert hass.states.get(ENTITY_ID).state == AlarmControlPanelState.ARMED_AWAY + mock_partition.arming_state = ArmingState.ARMING + + await hass.services.async_call( + ALARM_CONTROL_PANEL_DOMAIN, + SERVICE_ALARM_DISARM, + {ATTR_ENTITY_ID: entity_id, ATTR_CODE: CODE}, + blocking=True, + ) + assert mock_partition.disarm.call_args[1] == {"usercode": ""} + + assert hass.states.get(entity_id).state == AlarmControlPanelState.ARMING -async def test_arm_away_instant_failure(hass: HomeAssistant) -> None: - """Test arm home instant method failure.""" - responses = [RESPONSE_DISARMED, RESPONSE_ARM_FAILURE, RESPONSE_USER_CODE_INVALID] - await setup_platform(hass, ALARM_DOMAIN) - with patch(TOTALCONNECT_REQUEST, side_effect=responses) as mock_request: - await async_update_entity(hass, ENTITY_ID) - await hass.async_block_till_done() - assert hass.states.get(ENTITY_ID).state == AlarmControlPanelState.DISARMED - assert mock_request.call_count == 1 - - with pytest.raises(HomeAssistantError) as err: - await hass.services.async_call( - DOMAIN, SERVICE_ALARM_ARM_AWAY_INSTANT, DATA, blocking=True - ) - await hass.async_block_till_done() - assert f"{err.value}" == "Failed to arm away instant test" - assert hass.states.get(ENTITY_ID).state == AlarmControlPanelState.DISARMED - assert mock_request.call_count == 2 - - # usercode is invalid - with pytest.raises(HomeAssistantError) as err: - await hass.services.async_call( - DOMAIN, SERVICE_ALARM_ARM_AWAY_INSTANT, DATA, blocking=True - ) - await hass.async_block_till_done() - assert f"{err.value}" == "Usercode is invalid, did not arm away instant" - assert hass.states.get(ENTITY_ID).state == AlarmControlPanelState.DISARMED - # should have started a re-auth flow - assert len(hass.config_entries.flow.async_progress_by_handler(DOMAIN)) == 1 - assert mock_request.call_count == 3 - - -async def test_arm_away_success( - hass: HomeAssistant, freezer: FrozenDateTimeFactory +@pytest.mark.parametrize("code_required", [True]) +async def test_disarming_invalid_usercode( + hass: HomeAssistant, + mock_client: AsyncMock, + mock_partition: AsyncMock, + mock_location: AsyncMock, + mock_config_entry: MockConfigEntry, ) -> None: - """Test arm away method success.""" - responses = [RESPONSE_DISARMED, RESPONSE_ARM_SUCCESS, RESPONSE_ARMED_AWAY] - await setup_platform(hass, ALARM_DOMAIN) - with patch(TOTALCONNECT_REQUEST, side_effect=responses) as mock_request: - await async_update_entity(hass, ENTITY_ID) - await hass.async_block_till_done() - assert hass.states.get(ENTITY_ID).state == AlarmControlPanelState.DISARMED - assert mock_request.call_count == 1 + """Test disarming method with invalid usercode.""" + await setup_integration(hass, mock_config_entry) + entity_id = "alarm_control_panel.test" + assert hass.states.get(entity_id).state == AlarmControlPanelState.DISARMED + assert mock_location.get_panel_meta_data.call_count == 1 + + mock_partition.arming_state = ArmingState.ARMING + + with pytest.raises(ServiceValidationError, match="Incorrect code entered"): await hass.services.async_call( - ALARM_DOMAIN, SERVICE_ALARM_ARM_AWAY, DATA, blocking=True + ALARM_CONTROL_PANEL_DOMAIN, + SERVICE_ALARM_DISARM, + {ATTR_ENTITY_ID: entity_id, ATTR_CODE: "invalid_code"}, + blocking=True, ) - assert mock_request.call_count == 2 - - freezer.tick(DELAY) - async_fire_time_changed(hass) - await hass.async_block_till_done() - assert mock_request.call_count == 3 - assert hass.states.get(ENTITY_ID).state == AlarmControlPanelState.ARMED_AWAY + assert mock_partition.disarm.call_count == 0 + assert mock_location.get_panel_meta_data.call_count == 1 -async def test_arm_away_failure(hass: HomeAssistant) -> None: - """Test arm away method failure.""" - responses = [RESPONSE_DISARMED, RESPONSE_ARM_FAILURE, RESPONSE_USER_CODE_INVALID] - await setup_platform(hass, ALARM_DOMAIN) - with patch(TOTALCONNECT_REQUEST, side_effect=responses) as mock_request: - await async_update_entity(hass, ENTITY_ID) - await hass.async_block_till_done() - assert hass.states.get(ENTITY_ID).state == AlarmControlPanelState.DISARMED - assert mock_request.call_count == 1 - - with pytest.raises(HomeAssistantError) as err: - await hass.services.async_call( - ALARM_DOMAIN, SERVICE_ALARM_ARM_AWAY, DATA, blocking=True - ) - await hass.async_block_till_done() - assert f"{err.value}" == "Failed to arm away test" - assert hass.states.get(ENTITY_ID).state == AlarmControlPanelState.DISARMED - assert mock_request.call_count == 2 - - # usercode is invalid - with pytest.raises(HomeAssistantError) as err: - await hass.services.async_call( - ALARM_DOMAIN, SERVICE_ALARM_ARM_AWAY, DATA, blocking=True - ) - await hass.async_block_till_done() - assert f"{err.value}" == "Usercode is invalid, did not arm away" - assert hass.states.get(ENTITY_ID).state == AlarmControlPanelState.DISARMED - # should have started a re-auth flow - assert len(hass.config_entries.flow.async_progress_by_handler(DOMAIN)) == 1 - assert mock_request.call_count == 3 - - -async def test_disarm_success( - hass: HomeAssistant, freezer: FrozenDateTimeFactory +@pytest.mark.parametrize( + ("service", "arm_type"), + [ + (SERVICE_ALARM_ARM_HOME_INSTANT, ArmType.STAY_INSTANT), + (SERVICE_ALARM_ARM_AWAY_INSTANT, ArmType.AWAY_INSTANT), + ], +) +async def test_instant_arming( + hass: HomeAssistant, + mock_client: AsyncMock, + mock_partition: AsyncMock, + mock_config_entry: MockConfigEntry, + service: str, + arm_type: ArmType, ) -> None: - """Test disarm method success.""" - responses = [RESPONSE_ARMED_AWAY, RESPONSE_DISARM_SUCCESS, RESPONSE_DISARMED] - await setup_platform(hass, ALARM_DOMAIN) - with patch(TOTALCONNECT_REQUEST, side_effect=responses) as mock_request: - await async_update_entity(hass, ENTITY_ID) - await hass.async_block_till_done() - assert hass.states.get(ENTITY_ID).state == AlarmControlPanelState.ARMED_AWAY - assert mock_request.call_count == 1 + """Test instant arming method success.""" + await setup_integration(hass, mock_config_entry) - await hass.services.async_call( - ALARM_DOMAIN, SERVICE_ALARM_DISARM, DATA, blocking=True - ) - assert mock_request.call_count == 2 + entity_id = "alarm_control_panel.test" + assert hass.states.get(entity_id).state == AlarmControlPanelState.DISARMED - freezer.tick(DELAY) - async_fire_time_changed(hass) - await hass.async_block_till_done() - assert mock_request.call_count == 3 - assert hass.states.get(ENTITY_ID).state == AlarmControlPanelState.DISARMED + mock_partition.arming_state = ArmingState.ARMING + + await hass.services.async_call( + DOMAIN, + service, + {ATTR_ENTITY_ID: entity_id}, + blocking=True, + ) + assert mock_partition.arm.call_args[1] == {"arm_type": arm_type, "usercode": ""} + + assert hass.states.get(entity_id).state == AlarmControlPanelState.ARMING -async def test_disarm_failure(hass: HomeAssistant) -> None: - """Test disarm method failure.""" - responses = [ - RESPONSE_ARMED_AWAY, - RESPONSE_DISARM_FAILURE, - RESPONSE_USER_CODE_INVALID, - ] - await setup_platform(hass, ALARM_DOMAIN) - with patch(TOTALCONNECT_REQUEST, side_effect=responses) as mock_request: - await async_update_entity(hass, ENTITY_ID) - await hass.async_block_till_done() - assert hass.states.get(ENTITY_ID).state == AlarmControlPanelState.ARMED_AWAY - assert mock_request.call_count == 1 - - with pytest.raises(HomeAssistantError) as err: - await hass.services.async_call( - ALARM_DOMAIN, SERVICE_ALARM_DISARM, DATA, blocking=True - ) - await hass.async_block_till_done() - assert f"{err.value}" == "Failed to disarm test" - assert hass.states.get(ENTITY_ID).state == AlarmControlPanelState.ARMED_AWAY - assert mock_request.call_count == 2 - - # usercode is invalid - with pytest.raises(HomeAssistantError) as err: - await hass.services.async_call( - ALARM_DOMAIN, SERVICE_ALARM_DISARM, DATA, blocking=True - ) - await hass.async_block_till_done() - assert f"{err.value}" == "Usercode is invalid, did not disarm" - assert hass.states.get(ENTITY_ID).state == AlarmControlPanelState.ARMED_AWAY - # should have started a re-auth flow - assert len(hass.config_entries.flow.async_progress_by_handler(DOMAIN)) == 1 - assert mock_request.call_count == 3 - - -async def test_disarm_code_required( - hass: HomeAssistant, freezer: FrozenDateTimeFactory +@pytest.mark.parametrize( + ("exception", "suffix", "flows"), + [(UsercodeInvalid, "invalid_code", 1), (BadResultCodeError, "failed", 0)], +) +@pytest.mark.parametrize( + ("service", "prefix"), + [ + (SERVICE_ALARM_ARM_HOME, "arm_home"), + (SERVICE_ALARM_ARM_NIGHT, "arm_night"), + (SERVICE_ALARM_ARM_AWAY, "arm_away"), + ], +) +async def test_arming_exceptions( + hass: HomeAssistant, + mock_client: AsyncMock, + mock_partition: AsyncMock, + mock_location: AsyncMock, + mock_config_entry: MockConfigEntry, + service: str, + prefix: str, + exception: Exception, + suffix: str, + flows: int, ) -> None: - """Test disarm with code.""" - responses = [RESPONSE_ARMED_AWAY, RESPONSE_DISARM_SUCCESS, RESPONSE_DISARMED] - await setup_platform(hass, ALARM_DOMAIN, code_required=True) - with patch(TOTALCONNECT_REQUEST, side_effect=responses) as mock_request: - await async_update_entity(hass, ENTITY_ID) - await hass.async_block_till_done() - assert hass.states.get(ENTITY_ID).state == AlarmControlPanelState.ARMED_AWAY - assert mock_request.call_count == 1 + """Test arming method exceptions.""" + await setup_integration(hass, mock_config_entry) - # runtime user entered code is bad - DATA_WITH_CODE = DATA.copy() - DATA_WITH_CODE["code"] = "666" - with pytest.raises(ServiceValidationError, match="Incorrect code entered"): - await hass.services.async_call( - ALARM_DOMAIN, SERVICE_ALARM_DISARM, DATA_WITH_CODE, blocking=True - ) - assert hass.states.get(ENTITY_ID).state == AlarmControlPanelState.ARMED_AWAY - # code check means the call to total_connect never happens - assert mock_request.call_count == 1 + entity_id = "alarm_control_panel.test" + assert hass.states.get(entity_id).state == AlarmControlPanelState.DISARMED + assert mock_location.get_panel_meta_data.call_count == 1 - # runtime user entered code that is in config - DATA_WITH_CODE["code"] = USERCODES[LOCATION_ID] + mock_partition.arm.side_effect = exception + + mock_partition.arming_state = ArmingState.ARMING + + with pytest.raises(HomeAssistantError) as exc: await hass.services.async_call( - ALARM_DOMAIN, SERVICE_ALARM_DISARM, DATA_WITH_CODE, blocking=True + ALARM_CONTROL_PANEL_DOMAIN, + service, + {ATTR_ENTITY_ID: entity_id, ATTR_CODE: CODE}, + blocking=True, ) - await hass.async_block_till_done() - assert mock_request.call_count == 2 + assert mock_partition.arm.call_count == 1 - freezer.tick(DELAY) - async_fire_time_changed(hass) - await hass.async_block_till_done() - assert mock_request.call_count == 3 - assert hass.states.get(ENTITY_ID).state == AlarmControlPanelState.DISARMED + assert exc.value.translation_key == f"{prefix}_{suffix}" + + assert hass.states.get(entity_id).state == AlarmControlPanelState.DISARMED + assert mock_location.get_panel_meta_data.call_count == 1 + + assert len(hass.config_entries.flow.async_progress_by_handler(DOMAIN)) == flows -async def test_arm_night_success( - hass: HomeAssistant, freezer: FrozenDateTimeFactory +@pytest.mark.parametrize( + ("exception", "suffix", "flows"), + [(UsercodeInvalid, "invalid_code", 1), (BadResultCodeError, "failed", 0)], +) +@pytest.mark.parametrize( + ("service", "prefix"), + [ + (SERVICE_ALARM_ARM_HOME_INSTANT, "arm_home_instant"), + (SERVICE_ALARM_ARM_AWAY_INSTANT, "arm_away_instant"), + ], +) +async def test_instant_arming_exceptions( + hass: HomeAssistant, + mock_client: AsyncMock, + mock_partition: AsyncMock, + mock_location: AsyncMock, + mock_config_entry: MockConfigEntry, + service: str, + prefix: str, + exception: Exception, + suffix: str, + flows: int, ) -> None: - """Test arm night method success.""" - responses = [RESPONSE_DISARMED, RESPONSE_ARM_SUCCESS, RESPONSE_ARMED_NIGHT] - await setup_platform(hass, ALARM_DOMAIN) - with patch(TOTALCONNECT_REQUEST, side_effect=responses) as mock_request: - await async_update_entity(hass, ENTITY_ID) - await hass.async_block_till_done() - assert hass.states.get(ENTITY_ID).state == AlarmControlPanelState.DISARMED - assert mock_request.call_count == 1 + """Test arming method exceptions.""" + await setup_integration(hass, mock_config_entry) + entity_id = "alarm_control_panel.test" + assert hass.states.get(entity_id).state == AlarmControlPanelState.DISARMED + assert mock_location.get_panel_meta_data.call_count == 1 + + mock_partition.arm.side_effect = exception + + mock_partition.arming_state = ArmingState.ARMING + + with pytest.raises(HomeAssistantError) as exc: await hass.services.async_call( - ALARM_DOMAIN, SERVICE_ALARM_ARM_NIGHT, DATA, blocking=True + DOMAIN, + service, + {ATTR_ENTITY_ID: entity_id}, + blocking=True, ) - assert mock_request.call_count == 2 + assert mock_partition.arm.call_count == 1 - freezer.tick(DELAY) - async_fire_time_changed(hass) - await hass.async_block_till_done() - assert mock_request.call_count == 3 - assert hass.states.get(ENTITY_ID).state == AlarmControlPanelState.ARMED_NIGHT + assert exc.value.translation_key == f"{prefix}_{suffix}" + + assert hass.states.get(entity_id).state == AlarmControlPanelState.DISARMED + assert mock_location.get_panel_meta_data.call_count == 1 + + assert len(hass.config_entries.flow.async_progress_by_handler(DOMAIN)) == flows -async def test_arm_night_failure(hass: HomeAssistant) -> None: - """Test arm night method failure.""" - responses = [RESPONSE_DISARMED, RESPONSE_ARM_FAILURE, RESPONSE_USER_CODE_INVALID] - await setup_platform(hass, ALARM_DOMAIN) - with patch(TOTALCONNECT_REQUEST, side_effect=responses) as mock_request: - await async_update_entity(hass, ENTITY_ID) - await hass.async_block_till_done() - assert hass.states.get(ENTITY_ID).state == AlarmControlPanelState.DISARMED - assert mock_request.call_count == 1 - - with pytest.raises(HomeAssistantError) as err: - await hass.services.async_call( - ALARM_DOMAIN, SERVICE_ALARM_ARM_NIGHT, DATA, blocking=True - ) - await hass.async_block_till_done() - assert f"{err.value}" == "Failed to arm night test" - assert hass.states.get(ENTITY_ID).state == AlarmControlPanelState.DISARMED - assert mock_request.call_count == 2 - - # usercode is invalid - with pytest.raises(HomeAssistantError) as err: - await hass.services.async_call( - ALARM_DOMAIN, SERVICE_ALARM_ARM_NIGHT, DATA, blocking=True - ) - await hass.async_block_till_done() - assert f"{err.value}" == "Usercode is invalid, did not arm night" - assert hass.states.get(ENTITY_ID).state == AlarmControlPanelState.DISARMED - # should have started a re-auth flow - assert len(hass.config_entries.flow.async_progress_by_handler(DOMAIN)) == 1 - assert mock_request.call_count == 3 - - -async def test_arming(hass: HomeAssistant, freezer: FrozenDateTimeFactory) -> None: - """Test arming.""" - responses = [RESPONSE_DISARMED, RESPONSE_SUCCESS, RESPONSE_ARMING] - await setup_platform(hass, ALARM_DOMAIN) - with patch(TOTALCONNECT_REQUEST, side_effect=responses) as mock_request: - await async_update_entity(hass, ENTITY_ID) - await hass.async_block_till_done() - assert hass.states.get(ENTITY_ID).state == AlarmControlPanelState.DISARMED - assert mock_request.call_count == 1 - - await hass.services.async_call( - ALARM_DOMAIN, SERVICE_ALARM_ARM_NIGHT, DATA, blocking=True - ) - assert mock_request.call_count == 2 - - freezer.tick(DELAY) - async_fire_time_changed(hass) - await hass.async_block_till_done() - assert mock_request.call_count == 3 - assert hass.states.get(ENTITY_ID).state == AlarmControlPanelState.ARMING - - -async def test_disarming(hass: HomeAssistant, freezer: FrozenDateTimeFactory) -> None: - """Test disarming.""" - responses = [RESPONSE_ARMED_AWAY, RESPONSE_SUCCESS, RESPONSE_DISARMING] - await setup_platform(hass, ALARM_DOMAIN) - with patch(TOTALCONNECT_REQUEST, side_effect=responses) as mock_request: - await async_update_entity(hass, ENTITY_ID) - await hass.async_block_till_done() - assert hass.states.get(ENTITY_ID).state == AlarmControlPanelState.ARMED_AWAY - assert mock_request.call_count == 1 - - await hass.services.async_call( - ALARM_DOMAIN, SERVICE_ALARM_DISARM, DATA, blocking=True - ) - assert mock_request.call_count == 2 - - freezer.tick(DELAY) - async_fire_time_changed(hass) - await hass.async_block_till_done() - assert mock_request.call_count == 3 - assert hass.states.get(ENTITY_ID).state == AlarmControlPanelState.DISARMING - - -async def test_armed_custom(hass: HomeAssistant) -> None: - """Test armed custom.""" - responses = [RESPONSE_ARMED_CUSTOM] - await setup_platform(hass, ALARM_DOMAIN) - with patch(TOTALCONNECT_REQUEST, side_effect=responses) as mock_request: - await async_update_entity(hass, ENTITY_ID) - await hass.async_block_till_done() - assert ( - hass.states.get(ENTITY_ID).state - == AlarmControlPanelState.ARMED_CUSTOM_BYPASS - ) - assert mock_request.call_count == 1 - - -async def test_unknown(hass: HomeAssistant) -> None: - """Test unknown arm status.""" - responses = [RESPONSE_UNKNOWN] - await setup_platform(hass, ALARM_DOMAIN) - with patch(TOTALCONNECT_REQUEST, side_effect=responses) as mock_request: - await async_update_entity(hass, ENTITY_ID) - await hass.async_block_till_done() - assert hass.states.get(ENTITY_ID).state == STATE_UNAVAILABLE - assert mock_request.call_count == 1 - - -async def test_other_update_failures( - hass: HomeAssistant, freezer: FrozenDateTimeFactory +@pytest.mark.parametrize( + ("arming_state", "state"), + [ + (ArmingState.DISARMED, AlarmControlPanelState.DISARMED), + (ArmingState.DISARMED_BYPASS, AlarmControlPanelState.DISARMED), + (ArmingState.DISARMED_ZONE_FAULTED, AlarmControlPanelState.DISARMED), + (ArmingState.ARMED_STAY_NIGHT, AlarmControlPanelState.ARMED_NIGHT), + (ArmingState.ARMED_STAY_NIGHT_BYPASS_PROA7, AlarmControlPanelState.ARMED_NIGHT), + ( + ArmingState.ARMED_STAY_NIGHT_INSTANT_PROA7, + AlarmControlPanelState.ARMED_NIGHT, + ), + ( + ArmingState.ARMED_STAY_NIGHT_INSTANT_BYPASS_PROA7, + AlarmControlPanelState.ARMED_NIGHT, + ), + (ArmingState.ARMED_STAY, AlarmControlPanelState.ARMED_HOME), + (ArmingState.ARMED_STAY_PROA7, AlarmControlPanelState.ARMED_HOME), + (ArmingState.ARMED_STAY_BYPASS, AlarmControlPanelState.ARMED_HOME), + (ArmingState.ARMED_STAY_BYPASS_PROA7, AlarmControlPanelState.ARMED_HOME), + (ArmingState.ARMED_STAY_INSTANT, AlarmControlPanelState.ARMED_HOME), + (ArmingState.ARMED_STAY_INSTANT_PROA7, AlarmControlPanelState.ARMED_HOME), + (ArmingState.ARMED_STAY_INSTANT_BYPASS, AlarmControlPanelState.ARMED_HOME), + ( + ArmingState.ARMED_STAY_INSTANT_BYPASS_PROA7, + AlarmControlPanelState.ARMED_HOME, + ), + (ArmingState.ARMED_STAY_OTHER, AlarmControlPanelState.ARMED_HOME), + (ArmingState.ARMED_AWAY, AlarmControlPanelState.ARMED_AWAY), + (ArmingState.ARMED_AWAY_BYPASS, AlarmControlPanelState.ARMED_AWAY), + (ArmingState.ARMED_AWAY_INSTANT, AlarmControlPanelState.ARMED_AWAY), + (ArmingState.ARMED_AWAY_INSTANT_BYPASS, AlarmControlPanelState.ARMED_AWAY), + (ArmingState.ARMED_CUSTOM_BYPASS, AlarmControlPanelState.ARMED_CUSTOM_BYPASS), + (ArmingState.ARMING, AlarmControlPanelState.ARMING), + (ArmingState.DISARMING, AlarmControlPanelState.DISARMING), + (ArmingState.ALARMING, AlarmControlPanelState.TRIGGERED), + (ArmingState.ALARMING_FIRE_SMOKE, AlarmControlPanelState.TRIGGERED), + (ArmingState.ALARMING_CARBON_MONOXIDE, AlarmControlPanelState.TRIGGERED), + (ArmingState.ALARMING_CARBON_MONOXIDE_PROA7, AlarmControlPanelState.TRIGGERED), + ], +) +async def test_arming_state( + hass: HomeAssistant, + mock_client: AsyncMock, + mock_partition: AsyncMock, + mock_location: AsyncMock, + mock_config_entry: MockConfigEntry, + arming_state: ArmingState, + state: AlarmControlPanelState, + freezer: FrozenDateTimeFactory, ) -> None: - """Test other failures seen during updates.""" - responses = [ - RESPONSE_DISARMED, - ServiceUnavailable, - RESPONSE_DISARMED, - TotalConnectError, - RESPONSE_DISARMED, - ValueError, - ] - await setup_platform(hass, ALARM_DOMAIN) - with patch(TOTALCONNECT_REQUEST, side_effect=responses) as mock_request: - # first things work as planned - await async_update_entity(hass, ENTITY_ID) - await hass.async_block_till_done() - assert hass.states.get(ENTITY_ID).state == AlarmControlPanelState.DISARMED - assert mock_request.call_count == 1 + """Test arming state transitions.""" + await setup_integration(hass, mock_config_entry) - # then an error: ServiceUnavailable --> UpdateFailed - freezer.tick(SCAN_INTERVAL) - async_fire_time_changed(hass) - await hass.async_block_till_done(wait_background_tasks=True) - assert hass.states.get(ENTITY_ID).state == STATE_UNAVAILABLE - assert mock_request.call_count == 2 + entity_id = "alarm_control_panel.test" + assert hass.states.get(entity_id).state == AlarmControlPanelState.DISARMED - # works again - freezer.tick(SCAN_INTERVAL) - async_fire_time_changed(hass) - await hass.async_block_till_done(wait_background_tasks=True) - assert hass.states.get(ENTITY_ID).state == AlarmControlPanelState.DISARMED - assert mock_request.call_count == 3 + mock_partition.arming_state = arming_state - # then an error: TotalConnectError --> UpdateFailed - freezer.tick(SCAN_INTERVAL) - async_fire_time_changed(hass) - await hass.async_block_till_done(wait_background_tasks=True) - assert hass.states.get(ENTITY_ID).state == STATE_UNAVAILABLE - assert mock_request.call_count == 4 + freezer.tick(timedelta(seconds=30)) + async_fire_time_changed(hass) + await hass.async_block_till_done(wait_background_tasks=True) - # works again - freezer.tick(SCAN_INTERVAL) - async_fire_time_changed(hass) - await hass.async_block_till_done(wait_background_tasks=True) - assert hass.states.get(ENTITY_ID).state == AlarmControlPanelState.DISARMED - assert mock_request.call_count == 5 - - # unknown TotalConnect status via ValueError - freezer.tick(SCAN_INTERVAL) - async_fire_time_changed(hass) - await hass.async_block_till_done(wait_background_tasks=True) - assert hass.states.get(ENTITY_ID).state == STATE_UNAVAILABLE - assert mock_request.call_count == 6 - - -async def test_authentication_error(hass: HomeAssistant) -> None: - """Test other failures seen during updates.""" - entry = await setup_platform(hass, ALARM_DOMAIN) - - with patch(TOTALCONNECT_REQUEST, side_effect=AuthenticationError): - await async_update_entity(hass, ENTITY_ID) - await hass.async_block_till_done() - - assert entry.state is ConfigEntryState.LOADED - - flows = hass.config_entries.flow.async_progress() - assert len(flows) == 1 - - flow = flows[0] - assert flow.get("step_id") == "reauth_confirm" - assert flow.get("handler") == DOMAIN - - assert "context" in flow - assert flow["context"].get("source") == SOURCE_REAUTH - assert flow["context"].get("entry_id") == entry.entry_id + assert hass.states.get(entity_id).state == state diff --git a/tests/components/totalconnect/test_binary_sensor.py b/tests/components/totalconnect/test_binary_sensor.py index 8910487ea58..3083dd8c629 100644 --- a/tests/components/totalconnect/test_binary_sensor.py +++ b/tests/components/totalconnect/test_binary_sensor.py @@ -1,91 +1,29 @@ """Tests for the TotalConnect binary sensor.""" -from unittest.mock import patch +from unittest.mock import AsyncMock, patch from syrupy.assertion import SnapshotAssertion -from homeassistant.components.binary_sensor import ( - DOMAIN as BINARY_SENSOR, - BinarySensorDeviceClass, -) -from homeassistant.const import ATTR_FRIENDLY_NAME, STATE_OFF, STATE_ON +from homeassistant.const import Platform from homeassistant.core import HomeAssistant from homeassistant.helpers import entity_registry as er -from .common import RESPONSE_DISARMED, ZONE_NORMAL, setup_platform +from . import setup_integration -from tests.common import snapshot_platform - -ZONE_ENTITY_ID = "binary_sensor.security" -ZONE_LOW_BATTERY_ID = "binary_sensor.security_battery" -ZONE_TAMPER_ID = "binary_sensor.security_tamper" -PANEL_BATTERY_ID = "binary_sensor.test_battery" -PANEL_TAMPER_ID = "binary_sensor.test_tamper" -PANEL_POWER_ID = "binary_sensor.test_power" +from tests.common import MockConfigEntry, snapshot_platform async def test_entity_registry( - hass: HomeAssistant, entity_registry: er.EntityRegistry, snapshot: SnapshotAssertion + hass: HomeAssistant, + entity_registry: er.EntityRegistry, + mock_client: AsyncMock, + mock_config_entry: MockConfigEntry, + snapshot: SnapshotAssertion, ) -> None: - """Test the binary sensor is registered in entity registry.""" - entry = await setup_platform(hass, BINARY_SENSOR) - - await snapshot_platform(hass, entity_registry, snapshot, entry.entry_id) - - -async def test_state_and_attributes(hass: HomeAssistant) -> None: - """Test the binary sensor attributes are correct.""" - + """Test the alarm control panel attributes are correct.""" with patch( - "homeassistant.components.totalconnect.TotalConnectClient.request", - return_value=RESPONSE_DISARMED, + "homeassistant.components.totalconnect.PLATFORMS", [Platform.BINARY_SENSOR] ): - await setup_platform(hass, BINARY_SENSOR) + await setup_integration(hass, mock_config_entry) - state = hass.states.get(ZONE_ENTITY_ID) - assert state.state == STATE_ON - assert ( - state.attributes.get(ATTR_FRIENDLY_NAME) == ZONE_NORMAL["ZoneDescription"] - ) - assert state.attributes.get("device_class") == BinarySensorDeviceClass.DOOR - - state = hass.states.get(f"{ZONE_ENTITY_ID}_battery") - assert state.state == STATE_OFF - state = hass.states.get(f"{ZONE_ENTITY_ID}_tamper") - assert state.state == STATE_OFF - - # Zone 2 is fire with low battery - state = hass.states.get("binary_sensor.fire") - assert state.state == STATE_OFF - assert state.attributes.get("device_class") == BinarySensorDeviceClass.SMOKE - state = hass.states.get("binary_sensor.fire_battery") - assert state.state == STATE_ON - state = hass.states.get("binary_sensor.fire_tamper") - assert state.state == STATE_OFF - - # Zone 3 is gas with tamper - state = hass.states.get("binary_sensor.gas") - assert state.state == STATE_OFF - assert state.attributes.get("device_class") == BinarySensorDeviceClass.GAS - state = hass.states.get("binary_sensor.gas_battery") - assert state.state == STATE_OFF - state = hass.states.get("binary_sensor.gas_tamper") - assert state.state == STATE_ON - - # Zone 6 is unknown type, assume it is a security (door) sensor - state = hass.states.get("binary_sensor.unknown") - assert state.state == STATE_OFF - assert state.attributes.get("device_class") == BinarySensorDeviceClass.DOOR - state = hass.states.get("binary_sensor.unknown_battery") - assert state.state == STATE_OFF - state = hass.states.get("binary_sensor.unknown_tamper") - assert state.state == STATE_OFF - - # Zone 7 is temperature - state = hass.states.get("binary_sensor.temperature") - assert state.state == STATE_OFF - assert state.attributes.get("device_class") == BinarySensorDeviceClass.PROBLEM - state = hass.states.get("binary_sensor.temperature_battery") - assert state.state == STATE_OFF - state = hass.states.get("binary_sensor.temperature_tamper") - assert state.state == STATE_OFF + await snapshot_platform(hass, entity_registry, snapshot, mock_config_entry.entry_id) diff --git a/tests/components/totalconnect/test_button.py b/tests/components/totalconnect/test_button.py index 092b058e693..9492d815152 100644 --- a/tests/components/totalconnect/test_button.py +++ b/tests/components/totalconnect/test_button.py @@ -1,84 +1,64 @@ """Tests for the TotalConnect buttons.""" -from unittest.mock import patch +from unittest.mock import AsyncMock, patch -import pytest from syrupy.assertion import SnapshotAssertion -from total_connect_client.exceptions import FailedToBypassZone -from homeassistant.components.button import DOMAIN as BUTTON, SERVICE_PRESS -from homeassistant.const import ATTR_ENTITY_ID +from homeassistant.components.button import DOMAIN as BUTTON_DOMAIN, SERVICE_PRESS +from homeassistant.const import ATTR_ENTITY_ID, Platform from homeassistant.core import HomeAssistant from homeassistant.helpers import entity_registry as er -from .common import setup_platform +from . import setup_integration -from tests.common import snapshot_platform - -ZONE_BYPASS_ID = "button.security_bypass" -PANEL_CLEAR_ID = "button.test_clear_bypass" -PANEL_BYPASS_ID = "button.test_bypass_all" +from tests.common import MockConfigEntry, snapshot_platform async def test_entity_registry( - hass: HomeAssistant, entity_registry: er.EntityRegistry, snapshot: SnapshotAssertion + hass: HomeAssistant, + entity_registry: er.EntityRegistry, + mock_client: AsyncMock, + mock_config_entry: MockConfigEntry, + snapshot: SnapshotAssertion, ) -> None: """Test the button is registered in entity registry.""" - entry = await setup_platform(hass, BUTTON) + with patch("homeassistant.components.totalconnect.PLATFORMS", [Platform.BUTTON]): + await setup_integration(hass, mock_config_entry) - await snapshot_platform(hass, entity_registry, snapshot, entry.entry_id) + await snapshot_platform(hass, entity_registry, snapshot, mock_config_entry.entry_id) -@pytest.mark.parametrize( - ("entity_id", "tcc_request"), - [ - (ZONE_BYPASS_ID, "total_connect_client.zone.TotalConnectZone.bypass"), - ( - PANEL_BYPASS_ID, - "total_connect_client.location.TotalConnectLocation.zone_bypass_all", - ), - ], -) async def test_bypass_button( - hass: HomeAssistant, entity_id: str, tcc_request: str + hass: HomeAssistant, + mock_client: AsyncMock, + mock_config_entry: MockConfigEntry, + mock_location: AsyncMock, ) -> None: """Test pushing a bypass button.""" - responses = [FailedToBypassZone, None] - await setup_platform(hass, BUTTON) - with patch(tcc_request, side_effect=responses) as mock_request: - # try to bypass, but fails - with pytest.raises(FailedToBypassZone): - await hass.services.async_call( - domain=BUTTON, - service=SERVICE_PRESS, - service_data={ATTR_ENTITY_ID: entity_id}, - blocking=True, - ) - assert mock_request.call_count == 1 - - # try to bypass, works this time - await hass.services.async_call( - domain=BUTTON, - service=SERVICE_PRESS, - service_data={ATTR_ENTITY_ID: entity_id}, - blocking=True, - ) - assert mock_request.call_count == 2 - - -async def test_clear_button(hass: HomeAssistant) -> None: - """Test pushing the clear bypass button.""" - data = {ATTR_ENTITY_ID: PANEL_CLEAR_ID} - await setup_platform(hass, BUTTON) - TOTALCONNECT_REQUEST = ( - "total_connect_client.location.TotalConnectLocation.clear_bypass" + await setup_integration(hass, mock_config_entry) + await hass.services.async_call( + BUTTON_DOMAIN, + SERVICE_PRESS, + {ATTR_ENTITY_ID: "button.security_bypass"}, + blocking=True, ) - with patch(TOTALCONNECT_REQUEST) as mock_request: - await hass.services.async_call( - domain=BUTTON, - service=SERVICE_PRESS, - service_data=data, - blocking=True, - ) - assert mock_request.call_count == 1 + assert mock_location.zones[2].bypass.call_count == 1 + + +async def test_clear_button( + hass: HomeAssistant, + mock_client: AsyncMock, + mock_config_entry: MockConfigEntry, + mock_location: AsyncMock, +) -> None: + """Test pushing the clear bypass button.""" + await setup_integration(hass, mock_config_entry) + await hass.services.async_call( + BUTTON_DOMAIN, + SERVICE_PRESS, + {ATTR_ENTITY_ID: "button.test_clear_bypass"}, + blocking=True, + ) + + assert mock_location.clear_bypass.call_count == 1 diff --git a/tests/components/totalconnect/test_config_flow.py b/tests/components/totalconnect/test_config_flow.py index b7ac42c84b5..dbbff265129 100644 --- a/tests/components/totalconnect/test_config_flow.py +++ b/tests/components/totalconnect/test_config_flow.py @@ -1,6 +1,6 @@ """Tests for the TotalConnect config flow.""" -from unittest.mock import patch +from unittest.mock import AsyncMock, patch from total_connect_client.exceptions import AuthenticationError @@ -11,217 +11,235 @@ from homeassistant.components.totalconnect.const import ( DOMAIN, ) from homeassistant.config_entries import SOURCE_USER -from homeassistant.const import CONF_PASSWORD +from homeassistant.const import CONF_LOCATION, CONF_PASSWORD, CONF_USERNAME from homeassistant.core import HomeAssistant from homeassistant.data_entry_flow import FlowResultType -from .common import ( - CONFIG_DATA, - CONFIG_DATA_NO_USERCODES, - RESPONSE_DISARMED, - RESPONSE_GET_ZONE_DETAILS_SUCCESS, - RESPONSE_PARTITION_DETAILS, - RESPONSE_SESSION_DETAILS, - RESPONSE_SUCCESS, - RESPONSE_USER_CODE_INVALID, - TOTALCONNECT_GET_CONFIG, - TOTALCONNECT_REQUEST, - TOTALCONNECT_REQUEST_TOKEN, - USERNAME, - init_integration, -) +from . import setup_integration +from .const import LOCATION_ID, PASSWORD, USERNAME from tests.common import MockConfigEntry -async def test_user(hass: HomeAssistant) -> None: +async def test_full_flow( + hass: HomeAssistant, mock_setup_entry: AsyncMock, mock_client: AsyncMock +) -> None: """Test user step.""" - # user starts with no data entered, so show the user form result = await hass.config_entries.flow.async_init( - DOMAIN, - context={"source": SOURCE_USER}, - data=None, + DOMAIN, context={"source": SOURCE_USER} ) assert result["type"] is FlowResultType.FORM assert result["step_id"] == "user" + result = await hass.config_entries.flow.async_configure( + result["flow_id"], {CONF_USERNAME: USERNAME, CONF_PASSWORD: PASSWORD} + ) -async def test_user_show_locations(hass: HomeAssistant) -> None: - """Test user locations form.""" - # user/pass provided, so check if valid then ask for usercodes on locations form - responses = [ - RESPONSE_SESSION_DETAILS, - RESPONSE_PARTITION_DETAILS, - RESPONSE_GET_ZONE_DETAILS_SUCCESS, - RESPONSE_DISARMED, - RESPONSE_USER_CODE_INVALID, - RESPONSE_SUCCESS, - ] + assert result["type"] is FlowResultType.FORM + assert result["step_id"] == "locations" - with ( - patch( - TOTALCONNECT_REQUEST, - side_effect=responses, - ) as mock_request, - patch(TOTALCONNECT_GET_CONFIG, side_effect=None), - patch(TOTALCONNECT_REQUEST_TOKEN, side_effect=None), - patch( - "homeassistant.components.totalconnect.async_setup_entry", return_value=True - ), - ): - result = await hass.config_entries.flow.async_init( - DOMAIN, - context={"source": SOURCE_USER}, - data=CONFIG_DATA_NO_USERCODES, + result = await hass.config_entries.flow.async_configure( + result["flow_id"], {CONF_USERCODES: "7890"} + ) + assert result["type"] is FlowResultType.CREATE_ENTRY + assert result["data"] == { + CONF_PASSWORD: PASSWORD, + CONF_USERNAME: USERNAME, + CONF_USERCODES: {LOCATION_ID: "7890"}, + } + assert result["title"] == "Total Connect" + assert result["options"] == {} + assert result["result"].unique_id == USERNAME + + +async def test_login_errors( + hass: HomeAssistant, mock_setup_entry: AsyncMock, mock_client: AsyncMock +) -> None: + """Test login errors.""" + result = await hass.config_entries.flow.async_init( + DOMAIN, context={"source": SOURCE_USER} + ) + + assert result["type"] is FlowResultType.FORM + assert result["step_id"] == "user" + + with patch( + "homeassistant.components.totalconnect.config_flow.TotalConnectClient", + ) as client: + client.side_effect = AuthenticationError() + + result = await hass.config_entries.flow.async_configure( + result["flow_id"], {CONF_USERNAME: USERNAME, CONF_PASSWORD: PASSWORD} ) - # first it should show the locations form - assert result["type"] is FlowResultType.FORM - assert result["step_id"] == "locations" - # client should have sent four requests for init - assert mock_request.call_count == 4 + assert result["type"] is FlowResultType.FORM + assert result["step_id"] == "user" + assert result["errors"] == {"base": "invalid_auth"} - # user enters an invalid usercode - result2 = await hass.config_entries.flow.async_configure( - result["flow_id"], - user_input={CONF_USERCODES: "bad"}, - ) - assert result2["type"] is FlowResultType.FORM - assert result2["step_id"] == "locations" - # client should have sent 5th request to validate usercode - assert mock_request.call_count == 5 + result = await hass.config_entries.flow.async_configure( + result["flow_id"], {CONF_USERNAME: USERNAME, CONF_PASSWORD: PASSWORD} + ) - # user enters a valid usercode - result3 = await hass.config_entries.flow.async_configure( - result2["flow_id"], - user_input={CONF_USERCODES: "7890"}, - ) - assert result3["type"] is FlowResultType.CREATE_ENTRY - # client should have sent another request to validate usercode - assert mock_request.call_count == 6 + assert result["type"] is FlowResultType.FORM + assert result["step_id"] == "locations" + + result = await hass.config_entries.flow.async_configure( + result["flow_id"], {CONF_USERCODES: "7890"} + ) + assert result["type"] is FlowResultType.CREATE_ENTRY -async def test_abort_if_already_setup(hass: HomeAssistant) -> None: +async def test_usercode_errors( + hass: HomeAssistant, + mock_setup_entry: AsyncMock, + mock_client: AsyncMock, + mock_location: AsyncMock, +) -> None: + """Test user step with usercode errors.""" + result = await hass.config_entries.flow.async_init( + DOMAIN, context={"source": SOURCE_USER} + ) + + assert result["type"] is FlowResultType.FORM + assert result["step_id"] == "user" + + result = await hass.config_entries.flow.async_configure( + result["flow_id"], {CONF_USERNAME: USERNAME, CONF_PASSWORD: PASSWORD} + ) + + assert result["type"] is FlowResultType.FORM + assert result["step_id"] == "locations" + + mock_location.set_usercode.return_value = False + + result = await hass.config_entries.flow.async_configure( + result["flow_id"], {CONF_USERCODES: "7890"} + ) + + assert result["type"] is FlowResultType.FORM + assert result["step_id"] == "locations" + assert result["errors"] == {CONF_LOCATION: "usercode"} + + mock_location.set_usercode.return_value = True + + result = await hass.config_entries.flow.async_configure( + result["flow_id"], {CONF_USERCODES: "7890"} + ) + assert result["type"] is FlowResultType.CREATE_ENTRY + + +async def test_no_locations( + hass: HomeAssistant, + mock_setup_entry: AsyncMock, + mock_client: AsyncMock, + mock_location: AsyncMock, +) -> None: + """Test no locations found.""" + + mock_client.get_number_locations.return_value = 0 + result = await hass.config_entries.flow.async_init( + DOMAIN, context={"source": SOURCE_USER} + ) + + assert result["type"] is FlowResultType.FORM + assert result["step_id"] == "user" + + result = await hass.config_entries.flow.async_configure( + result["flow_id"], {CONF_USERNAME: USERNAME, CONF_PASSWORD: PASSWORD} + ) + + assert result["type"] is FlowResultType.ABORT + assert result["reason"] == "no_locations" + + +async def test_abort_if_already_setup( + hass: HomeAssistant, mock_config_entry: MockConfigEntry +) -> None: """Test abort if the account is already setup.""" - MockConfigEntry( - domain=DOMAIN, - data=CONFIG_DATA, - unique_id=USERNAME, - ).add_to_hass(hass) + mock_config_entry.add_to_hass(hass) - # Should fail, same USERNAME (flow) - with patch("homeassistant.components.totalconnect.config_flow.TotalConnectClient"): - result = await hass.config_entries.flow.async_init( - DOMAIN, - context={"source": SOURCE_USER}, - data=CONFIG_DATA, - ) + result = await hass.config_entries.flow.async_init( + DOMAIN, context={"source": SOURCE_USER} + ) + + assert result["type"] is FlowResultType.FORM + assert result["step_id"] == "user" + + result = await hass.config_entries.flow.async_configure( + result["flow_id"], {CONF_USERNAME: USERNAME, CONF_PASSWORD: PASSWORD} + ) assert result["type"] is FlowResultType.ABORT assert result["reason"] == "already_configured" -async def test_login_failed(hass: HomeAssistant) -> None: - """Test when we have errors during login.""" - with patch( - "homeassistant.components.totalconnect.config_flow.TotalConnectClient" - ) as client_mock: - client_mock.side_effect = AuthenticationError() - result = await hass.config_entries.flow.async_init( - DOMAIN, - context={"source": SOURCE_USER}, - data=CONFIG_DATA, - ) +async def test_reauth( + hass: HomeAssistant, + mock_setup_entry: AsyncMock, + mock_client: AsyncMock, + mock_config_entry: MockConfigEntry, +) -> None: + """Test login errors.""" + mock_config_entry.add_to_hass(hass) + result = await mock_config_entry.start_reauth_flow(hass) - assert result["type"] is FlowResultType.FORM - assert result["errors"] == {"base": "invalid_auth"} - - -async def test_reauth(hass: HomeAssistant) -> None: - """Test reauth.""" - entry = MockConfigEntry( - domain=DOMAIN, - data=CONFIG_DATA, - unique_id=USERNAME, - ) - entry.add_to_hass(hass) - - result = await entry.start_reauth_flow(hass) assert result["type"] is FlowResultType.FORM assert result["step_id"] == "reauth_confirm" - with ( - patch( - "homeassistant.components.totalconnect.config_flow.TotalConnectClient" - ) as client_mock, - patch( - "homeassistant.components.totalconnect.async_setup_entry", return_value=True - ), - ): - # first test with an invalid password - client_mock.side_effect = AuthenticationError() + result = await hass.config_entries.flow.async_configure( + result["flow_id"], {CONF_PASSWORD: "abc"} + ) + + assert result["type"] is FlowResultType.ABORT + assert result["reason"] == "reauth_successful" + + assert mock_config_entry.data[CONF_PASSWORD] == "abc" + + +async def test_reauth_errors( + hass: HomeAssistant, + mock_setup_entry: AsyncMock, + mock_client: AsyncMock, + mock_config_entry: MockConfigEntry, +) -> None: + """Test login errors.""" + mock_config_entry.add_to_hass(hass) + result = await mock_config_entry.start_reauth_flow(hass) + + assert result["type"] is FlowResultType.FORM + assert result["step_id"] == "reauth_confirm" + + with patch( + "homeassistant.components.totalconnect.config_flow.TotalConnectClient", + ) as client: + client.side_effect = AuthenticationError() result = await hass.config_entries.flow.async_configure( - result["flow_id"], user_input={CONF_PASSWORD: "password"} + result["flow_id"], {CONF_PASSWORD: PASSWORD} ) - assert result["type"] is FlowResultType.FORM - assert result["step_id"] == "reauth_confirm" - assert result["errors"] == {"base": "invalid_auth"} - # now test with the password valid - client_mock.side_effect = None + assert result["type"] is FlowResultType.FORM + assert result["step_id"] == "reauth_confirm" + assert result["errors"] == {"base": "invalid_auth"} - result = await hass.config_entries.flow.async_configure( - result["flow_id"], user_input={CONF_PASSWORD: "password"} - ) - assert result["type"] is FlowResultType.ABORT - assert result["reason"] == "reauth_successful" - await hass.async_block_till_done() + result = await hass.config_entries.flow.async_configure( + result["flow_id"], {CONF_PASSWORD: PASSWORD} + ) - assert len(hass.config_entries.async_entries()) == 1 + assert result["type"] is FlowResultType.ABORT + assert result["reason"] == "reauth_successful" -async def test_no_locations(hass: HomeAssistant) -> None: - """Test with no user locations.""" - responses = [ - RESPONSE_SESSION_DETAILS, - RESPONSE_PARTITION_DETAILS, - RESPONSE_GET_ZONE_DETAILS_SUCCESS, - RESPONSE_DISARMED, - ] - - with ( - patch( - TOTALCONNECT_REQUEST, - side_effect=responses, - ) as mock_request, - patch(TOTALCONNECT_GET_CONFIG, side_effect=None), - patch(TOTALCONNECT_REQUEST_TOKEN, side_effect=None), - patch( - "homeassistant.components.totalconnect.async_setup_entry", return_value=True - ), - patch( - "homeassistant.components.totalconnect.TotalConnectClient.get_number_locations", - return_value=0, - ), - ): - result = await hass.config_entries.flow.async_init( - DOMAIN, - context={"source": SOURCE_USER}, - data=CONFIG_DATA_NO_USERCODES, - ) - assert result["type"] is FlowResultType.ABORT - assert result["reason"] == "no_locations" - await hass.async_block_till_done() - - assert mock_request.call_count == 1 - - -async def test_options_flow(hass: HomeAssistant) -> None: +async def test_options_flow( + hass: HomeAssistant, + mock_setup_entry: AsyncMock, + mock_client: AsyncMock, + mock_config_entry: MockConfigEntry, +) -> None: """Test config flow options.""" - config_entry = await init_integration(hass) - result = await hass.config_entries.options.async_init(config_entry.entry_id) + await setup_integration(hass, mock_config_entry) + result = await hass.config_entries.options.async_init(mock_config_entry.entry_id) assert result["type"] is FlowResultType.FORM assert result["step_id"] == "init" @@ -231,8 +249,4 @@ async def test_options_flow(hass: HomeAssistant) -> None: ) assert result["type"] is FlowResultType.CREATE_ENTRY - assert config_entry.options == {AUTO_BYPASS: True, CODE_REQUIRED: False} - await hass.async_block_till_done() - - assert await hass.config_entries.async_unload(config_entry.entry_id) - await hass.async_block_till_done() + assert mock_config_entry.options == {AUTO_BYPASS: True, CODE_REQUIRED: False} diff --git a/tests/components/totalconnect/test_diagnostics.py b/tests/components/totalconnect/test_diagnostics.py index 2ad05c60936..7422ee36143 100644 --- a/tests/components/totalconnect/test_diagnostics.py +++ b/tests/components/totalconnect/test_diagnostics.py @@ -1,36 +1,29 @@ """Test TotalConnect diagnostics.""" -from homeassistant.components.diagnostics import REDACTED +from unittest.mock import AsyncMock + +from syrupy.assertion import SnapshotAssertion + from homeassistant.core import HomeAssistant -from .common import LOCATION_ID, init_integration +from . import setup_integration +from tests.common import MockConfigEntry from tests.components.diagnostics import get_diagnostics_for_config_entry from tests.typing import ClientSessionGenerator async def test_entry_diagnostics( - hass: HomeAssistant, hass_client: ClientSessionGenerator + hass: HomeAssistant, + mock_client: AsyncMock, + hass_client: ClientSessionGenerator, + snapshot: SnapshotAssertion, + mock_config_entry: MockConfigEntry, ) -> None: """Test config entry diagnostics.""" - entry = await init_integration(hass) + await setup_integration(hass, mock_config_entry) - result = await get_diagnostics_for_config_entry(hass, hass_client, entry) - - client = result["client"] - assert client["invalid_credentials"] is False - - user = result["user"] - assert user["master"] is False - - location = result["locations"][0] - assert location["location_id"] == LOCATION_ID - - device = location["devices"][0] - assert device["serial_number"] == REDACTED - - partition = location["partitions"][0] - assert partition["name"] == "Test1" - - zone = location["zones"][0] - assert zone["zone_id"] == "1" + assert ( + await get_diagnostics_for_config_entry(hass, hass_client, mock_config_entry) + == snapshot + ) diff --git a/tests/components/totalconnect/test_init.py b/tests/components/totalconnect/test_init.py index ba533e19798..b19f585965f 100644 --- a/tests/components/totalconnect/test_init.py +++ b/tests/components/totalconnect/test_init.py @@ -4,29 +4,23 @@ from unittest.mock import patch from total_connect_client.exceptions import AuthenticationError -from homeassistant.components.totalconnect.const import DOMAIN from homeassistant.config_entries import ConfigEntryState from homeassistant.core import HomeAssistant -from homeassistant.setup import async_setup_component -from .common import CONFIG_DATA +from . import setup_integration from tests.common import MockConfigEntry -async def test_reauth_started(hass: HomeAssistant) -> None: +async def test_reauth_start( + hass: HomeAssistant, + mock_config_entry: MockConfigEntry, +) -> None: """Test that reauth is started when we have login errors.""" - mock_entry = MockConfigEntry( - domain=DOMAIN, - data=CONFIG_DATA, - ) - mock_entry.add_to_hass(hass) - with patch( "homeassistant.components.totalconnect.TotalConnectClient", ) as mock_client: mock_client.side_effect = AuthenticationError() - assert await async_setup_component(hass, DOMAIN, {}) - await hass.async_block_till_done() + await setup_integration(hass, mock_config_entry) - assert mock_entry.state is ConfigEntryState.SETUP_ERROR + assert mock_config_entry.state is ConfigEntryState.SETUP_ERROR