forked from home-assistant/core
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Notify user if arming or disarming totalconnect alarm fails (home-ass…
- Loading branch information
1 parent
1186c2c
commit 98a056f
Showing
6 changed files
with
294 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
"""Common methods used across tests for TotalConnect.""" | ||
from total_connect_client import TotalConnectClient | ||
|
||
from homeassistant.components.totalconnect import DOMAIN | ||
from homeassistant.const import CONF_PASSWORD, CONF_USERNAME | ||
from homeassistant.setup import async_setup_component | ||
|
||
from tests.async_mock import patch | ||
from tests.common import MockConfigEntry | ||
|
||
LOCATION_INFO_BASIC_NORMAL = { | ||
"LocationID": "123456", | ||
"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": None, | ||
} | ||
|
||
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_AUTHENTICATE = { | ||
"ResultCode": 0, | ||
"SessionID": 1, | ||
"Locations": LOCATIONS, | ||
"ModuleFlags": MODULE_FLAGS, | ||
"UserInfo": USER, | ||
} | ||
|
||
PARTITION_DISARMED = { | ||
"PartitionID": "1", | ||
"ArmingState": TotalConnectClient.TotalConnectLocation.DISARMED, | ||
} | ||
|
||
PARTITION_ARMED_STAY = { | ||
"PartitionID": "1", | ||
"ArmingState": TotalConnectClient.TotalConnectLocation.ARMED_STAY, | ||
} | ||
|
||
PARTITION_ARMED_AWAY = { | ||
"PartitionID": "1", | ||
"ArmingState": TotalConnectClient.TotalConnectLocation.ARMED_AWAY, | ||
} | ||
|
||
PARTITION_INFO_DISARMED = {0: PARTITION_DISARMED} | ||
PARTITION_INFO_ARMED_STAY = {0: PARTITION_ARMED_STAY} | ||
PARTITION_INFO_ARMED_AWAY = {0: PARTITION_ARMED_AWAY} | ||
|
||
PARTITIONS_DISARMED = {"PartitionInfo": PARTITION_INFO_DISARMED} | ||
PARTITIONS_ARMED_STAY = {"PartitionInfo": PARTITION_INFO_ARMED_STAY} | ||
PARTITIONS_ARMED_AWAY = {"PartitionInfo": PARTITION_INFO_ARMED_AWAY} | ||
|
||
ZONE_NORMAL = { | ||
"ZoneID": "1", | ||
"ZoneDescription": "Normal", | ||
"ZoneStatus": TotalConnectClient.ZONE_STATUS_NORMAL, | ||
"PartitionId": "1", | ||
} | ||
|
||
ZONE_INFO = [ZONE_NORMAL] | ||
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 | ||
|
||
RESPONSE_DISARMED = {"ResultCode": 0, "PanelMetadataAndStatus": METADATA_DISARMED} | ||
RESPONSE_ARMED_STAY = {"ResultCode": 0, "PanelMetadataAndStatus": METADATA_ARMED_STAY} | ||
RESPONSE_ARMED_AWAY = {"ResultCode": 0, "PanelMetadataAndStatus": METADATA_ARMED_AWAY} | ||
|
||
RESPONSE_ARM_SUCCESS = {"ResultCode": TotalConnectClient.TotalConnectClient.ARM_SUCCESS} | ||
RESPONSE_ARM_FAILURE = { | ||
"ResultCode": TotalConnectClient.TotalConnectClient.COMMAND_FAILED | ||
} | ||
RESPONSE_DISARM_SUCCESS = { | ||
"ResultCode": TotalConnectClient.TotalConnectClient.DISARM_SUCCESS | ||
} | ||
RESPONSE_DISARM_FAILURE = { | ||
"ResultCode": TotalConnectClient.TotalConnectClient.COMMAND_FAILED, | ||
"ResultData": "Command Failed", | ||
} | ||
|
||
|
||
async def setup_platform(hass, platform): | ||
"""Set up the TotalConnect platform.""" | ||
# first set up a config entry and add it to hass | ||
mock_entry = MockConfigEntry( | ||
domain=DOMAIN, | ||
data={CONF_USERNAME: "user@email.com", CONF_PASSWORD: "password"}, | ||
) | ||
mock_entry.add_to_hass(hass) | ||
|
||
responses = [RESPONSE_AUTHENTICATE, RESPONSE_DISARMED] | ||
|
||
with patch("homeassistant.components.totalconnect.PLATFORMS", [platform]), patch( | ||
"zeep.Client", autospec=True | ||
), patch( | ||
"homeassistant.components.totalconnect.TotalConnectClient.TotalConnectClient.request", | ||
side_effect=responses, | ||
) as mock_request, patch( | ||
"homeassistant.components.totalconnect.TotalConnectClient.TotalConnectClient.get_zone_details", | ||
return_value=True, | ||
): | ||
assert await async_setup_component(hass, DOMAIN, {}) | ||
assert mock_request.call_count == 2 | ||
await hass.async_block_till_done() | ||
|
||
return mock_entry |
153 changes: 153 additions & 0 deletions
153
tests/components/totalconnect/test_alarm_control_panel.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,153 @@ | ||
"""Tests for the TotalConnect alarm control panel device.""" | ||
import pytest | ||
|
||
from homeassistant.components.alarm_control_panel import DOMAIN as ALARM_DOMAIN | ||
from homeassistant.const import ( | ||
ATTR_ENTITY_ID, | ||
ATTR_FRIENDLY_NAME, | ||
SERVICE_ALARM_ARM_AWAY, | ||
SERVICE_ALARM_ARM_HOME, | ||
SERVICE_ALARM_DISARM, | ||
STATE_ALARM_ARMED_AWAY, | ||
STATE_ALARM_ARMED_HOME, | ||
STATE_ALARM_DISARMED, | ||
) | ||
|
||
from .common import ( | ||
RESPONSE_ARM_FAILURE, | ||
RESPONSE_ARM_SUCCESS, | ||
RESPONSE_ARMED_AWAY, | ||
RESPONSE_ARMED_STAY, | ||
RESPONSE_DISARM_FAILURE, | ||
RESPONSE_DISARM_SUCCESS, | ||
RESPONSE_DISARMED, | ||
setup_platform, | ||
) | ||
|
||
from tests.async_mock import patch | ||
|
||
ENTITY_ID = "alarm_control_panel.test" | ||
CODE = "-1" | ||
DATA = {ATTR_ENTITY_ID: ENTITY_ID} | ||
|
||
|
||
async def test_attributes(hass): | ||
"""Test the alarm control panel attributes are correct.""" | ||
with patch( | ||
"homeassistant.components.totalconnect.TotalConnectClient.TotalConnectClient.request", | ||
return_value=RESPONSE_DISARMED, | ||
) as mock_request: | ||
await setup_platform(hass, ALARM_DOMAIN) | ||
state = hass.states.get(ENTITY_ID) | ||
assert state.state == STATE_ALARM_DISARMED | ||
mock_request.assert_called_once() | ||
assert state.attributes.get(ATTR_FRIENDLY_NAME) == "test" | ||
|
||
|
||
async def test_arm_home_success(hass): | ||
"""Test arm home method success.""" | ||
responses = [RESPONSE_DISARMED, RESPONSE_ARM_SUCCESS, RESPONSE_ARMED_STAY] | ||
with patch( | ||
"homeassistant.components.totalconnect.TotalConnectClient.TotalConnectClient.request", | ||
side_effect=responses, | ||
): | ||
await setup_platform(hass, ALARM_DOMAIN) | ||
assert STATE_ALARM_DISARMED == hass.states.get(ENTITY_ID).state | ||
|
||
await hass.services.async_call( | ||
ALARM_DOMAIN, SERVICE_ALARM_ARM_HOME, DATA, blocking=True | ||
) | ||
|
||
await hass.async_block_till_done() | ||
assert STATE_ALARM_ARMED_HOME == hass.states.get(ENTITY_ID).state | ||
|
||
|
||
async def test_arm_home_failure(hass): | ||
"""Test arm home method failure.""" | ||
responses = [RESPONSE_DISARMED, RESPONSE_ARM_FAILURE, RESPONSE_DISARMED] | ||
with patch( | ||
"homeassistant.components.totalconnect.TotalConnectClient.TotalConnectClient.request", | ||
side_effect=responses, | ||
): | ||
await setup_platform(hass, ALARM_DOMAIN) | ||
assert STATE_ALARM_DISARMED == hass.states.get(ENTITY_ID).state | ||
|
||
with pytest.raises(Exception) as e: | ||
await hass.services.async_call( | ||
ALARM_DOMAIN, SERVICE_ALARM_ARM_HOME, DATA, blocking=True | ||
) | ||
await hass.async_block_till_done() | ||
assert f"{e.value}" == "TotalConnect failed to arm home test." | ||
assert STATE_ALARM_DISARMED == hass.states.get(ENTITY_ID).state | ||
|
||
|
||
async def test_arm_away_success(hass): | ||
"""Test arm away method success.""" | ||
responses = [RESPONSE_DISARMED, RESPONSE_ARM_SUCCESS, RESPONSE_ARMED_AWAY] | ||
with patch( | ||
"homeassistant.components.totalconnect.TotalConnectClient.TotalConnectClient.request", | ||
side_effect=responses, | ||
): | ||
await setup_platform(hass, ALARM_DOMAIN) | ||
assert STATE_ALARM_DISARMED == hass.states.get(ENTITY_ID).state | ||
|
||
await hass.services.async_call( | ||
ALARM_DOMAIN, SERVICE_ALARM_ARM_AWAY, DATA, blocking=True | ||
) | ||
await hass.async_block_till_done() | ||
assert STATE_ALARM_ARMED_AWAY == hass.states.get(ENTITY_ID).state | ||
|
||
|
||
async def test_arm_away_failure(hass): | ||
"""Test arm away method failure.""" | ||
responses = [RESPONSE_DISARMED, RESPONSE_ARM_FAILURE, RESPONSE_DISARMED] | ||
with patch( | ||
"homeassistant.components.totalconnect.TotalConnectClient.TotalConnectClient.request", | ||
side_effect=responses, | ||
): | ||
await setup_platform(hass, ALARM_DOMAIN) | ||
assert STATE_ALARM_DISARMED == hass.states.get(ENTITY_ID).state | ||
|
||
with pytest.raises(Exception) as e: | ||
await hass.services.async_call( | ||
ALARM_DOMAIN, SERVICE_ALARM_ARM_AWAY, DATA, blocking=True | ||
) | ||
await hass.async_block_till_done() | ||
assert f"{e.value}" == "TotalConnect failed to arm away test." | ||
assert STATE_ALARM_DISARMED == hass.states.get(ENTITY_ID).state | ||
|
||
|
||
async def test_disarm_success(hass): | ||
"""Test disarm method success.""" | ||
responses = [RESPONSE_ARMED_AWAY, RESPONSE_DISARM_SUCCESS, RESPONSE_DISARMED] | ||
with patch( | ||
"homeassistant.components.totalconnect.TotalConnectClient.TotalConnectClient.request", | ||
side_effect=responses, | ||
): | ||
await setup_platform(hass, ALARM_DOMAIN) | ||
assert STATE_ALARM_ARMED_AWAY == hass.states.get(ENTITY_ID).state | ||
|
||
await hass.services.async_call( | ||
ALARM_DOMAIN, SERVICE_ALARM_DISARM, DATA, blocking=True | ||
) | ||
await hass.async_block_till_done() | ||
assert STATE_ALARM_DISARMED == hass.states.get(ENTITY_ID).state | ||
|
||
|
||
async def test_disarm_failure(hass): | ||
"""Test disarm method failure.""" | ||
responses = [RESPONSE_ARMED_AWAY, RESPONSE_DISARM_FAILURE, RESPONSE_ARMED_AWAY] | ||
with patch( | ||
"homeassistant.components.totalconnect.TotalConnectClient.TotalConnectClient.request", | ||
side_effect=responses, | ||
): | ||
await setup_platform(hass, ALARM_DOMAIN) | ||
assert STATE_ALARM_ARMED_AWAY == hass.states.get(ENTITY_ID).state | ||
|
||
with pytest.raises(Exception) as e: | ||
await hass.services.async_call( | ||
ALARM_DOMAIN, SERVICE_ALARM_DISARM, DATA, blocking=True | ||
) | ||
await hass.async_block_till_done() | ||
assert f"{e.value}" == "TotalConnect failed to disarm test." | ||
assert STATE_ALARM_ARMED_AWAY == hass.states.get(ENTITY_ID).state |