mirror of
https://github.com/home-assistant/core.git
synced 2025-07-19 03:07:37 +00:00
Add instant arming for totalconnect (#60156)
Co-authored-by: J. Nick Koston <nick@koston.org>
This commit is contained in:
parent
f75b325ab2
commit
3198211a7f
@ -21,12 +21,16 @@ from homeassistant.const import (
|
||||
STATE_ALARM_TRIGGERED,
|
||||
)
|
||||
from homeassistant.exceptions import HomeAssistantError
|
||||
from homeassistant.helpers import entity_platform
|
||||
from homeassistant.helpers.update_coordinator import CoordinatorEntity
|
||||
|
||||
from .const import DOMAIN
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
SERVICE_ALARM_ARM_AWAY_INSTANT = "arm_away_instant"
|
||||
SERVICE_ALARM_ARM_HOME_INSTANT = "arm_home_instant"
|
||||
|
||||
|
||||
async def async_setup_entry(hass, entry, async_add_entities) -> None:
|
||||
"""Set up TotalConnect alarm panels based on a config entry."""
|
||||
@ -48,6 +52,21 @@ async def async_setup_entry(hass, entry, async_add_entities) -> None:
|
||||
|
||||
async_add_entities(alarms, True)
|
||||
|
||||
# Set up services
|
||||
platform = entity_platform.async_get_current_platform()
|
||||
|
||||
platform.async_register_entity_service(
|
||||
SERVICE_ALARM_ARM_AWAY_INSTANT,
|
||||
None,
|
||||
"async_alarm_arm_away_instant",
|
||||
)
|
||||
|
||||
platform.async_register_entity_service(
|
||||
SERVICE_ALARM_ARM_HOME_INSTANT,
|
||||
None,
|
||||
"async_alarm_arm_home_instant",
|
||||
)
|
||||
|
||||
|
||||
class TotalConnectAlarm(CoordinatorEntity, alarm.AlarmControlPanelEntity):
|
||||
"""Represent an TotalConnect status."""
|
||||
@ -201,3 +220,31 @@ class TotalConnectAlarm(CoordinatorEntity, alarm.AlarmControlPanelEntity):
|
||||
raise HomeAssistantError(
|
||||
f"TotalConnect failed to arm night {self._name}."
|
||||
) from error
|
||||
|
||||
async def async_alarm_arm_home_instant(self, code=None):
|
||||
"""Send arm home instant command."""
|
||||
await self.hass.async_add_executor_job(self._arm_home_instant)
|
||||
await self.coordinator.async_request_refresh()
|
||||
|
||||
def _arm_home_instant(self):
|
||||
"""Arm home instant synchronous."""
|
||||
try:
|
||||
ArmingHelper(self._partition).arm_stay_instant()
|
||||
except BadResultCodeError as error:
|
||||
raise HomeAssistantError(
|
||||
f"TotalConnect failed to arm home instant {self._name}."
|
||||
) from error
|
||||
|
||||
async def async_alarm_arm_away_instant(self, code=None):
|
||||
"""Send arm away instant command."""
|
||||
await self.hass.async_add_executor_job(self._arm_away_instant)
|
||||
await self.coordinator.async_request_refresh()
|
||||
|
||||
def _arm_away_instant(self, code=None):
|
||||
"""Arm away instant synchronous."""
|
||||
try:
|
||||
ArmingHelper(self._partition).arm_away_instant()
|
||||
except BadResultCodeError as error:
|
||||
raise HomeAssistantError(
|
||||
f"TotalConnect failed to arm away instant {self._name}."
|
||||
) from error
|
||||
|
15
homeassistant/components/totalconnect/services.yaml
Normal file
15
homeassistant/components/totalconnect/services.yaml
Normal file
@ -0,0 +1,15 @@
|
||||
arm_away_instant:
|
||||
name: Arm Away Instant
|
||||
description: Arm Away with zero entry delay.
|
||||
target:
|
||||
entity:
|
||||
integration: totalconnect
|
||||
domain: alarm_control_panel
|
||||
|
||||
arm_home_instant:
|
||||
name: Arm Home Instant
|
||||
description: Arm Home with zero entry delay.
|
||||
target:
|
||||
entity:
|
||||
integration: totalconnect
|
||||
domain: alarm_control_panel
|
@ -5,6 +5,11 @@ from unittest.mock import patch
|
||||
import pytest
|
||||
|
||||
from homeassistant.components.alarm_control_panel import DOMAIN as ALARM_DOMAIN
|
||||
from homeassistant.components.totalconnect import DOMAIN
|
||||
from homeassistant.components.totalconnect.alarm_control_panel import (
|
||||
SERVICE_ALARM_ARM_AWAY_INSTANT,
|
||||
SERVICE_ALARM_ARM_HOME_INSTANT,
|
||||
)
|
||||
from homeassistant.const import (
|
||||
ATTR_ENTITY_ID,
|
||||
ATTR_FRIENDLY_NAME,
|
||||
@ -121,6 +126,82 @@ async def test_arm_home_failure(hass: HomeAssistant) -> None:
|
||||
assert mock_request.call_count == 2
|
||||
|
||||
|
||||
async def test_arm_home_instant_success(hass: HomeAssistant) -> None:
|
||||
"""Test arm home instant method success."""
|
||||
responses = [RESPONSE_DISARMED, RESPONSE_ARM_SUCCESS, RESPONSE_ARMED_STAY]
|
||||
with patch(TOTALCONNECT_REQUEST, side_effect=responses) as mock_request:
|
||||
await setup_platform(hass, ALARM_DOMAIN)
|
||||
assert hass.states.get(ENTITY_ID).state == STATE_ALARM_DISARMED
|
||||
assert hass.states.get(ENTITY_ID_2).state == STATE_ALARM_DISARMED
|
||||
assert mock_request.call_count == 1
|
||||
|
||||
await hass.services.async_call(
|
||||
DOMAIN, SERVICE_ALARM_ARM_HOME_INSTANT, DATA, blocking=True
|
||||
)
|
||||
assert mock_request.call_count == 2
|
||||
|
||||
async_fire_time_changed(hass, dt.utcnow() + DELAY)
|
||||
await hass.async_block_till_done()
|
||||
assert mock_request.call_count == 3
|
||||
assert hass.states.get(ENTITY_ID).state == STATE_ALARM_ARMED_HOME
|
||||
|
||||
|
||||
async def test_arm_home_instant_failure(hass: HomeAssistant) -> None:
|
||||
"""Test arm home instant method failure."""
|
||||
responses = [RESPONSE_DISARMED, RESPONSE_ARM_FAILURE]
|
||||
with patch(TOTALCONNECT_REQUEST, side_effect=responses) as mock_request:
|
||||
await setup_platform(hass, ALARM_DOMAIN)
|
||||
assert hass.states.get(ENTITY_ID).state == STATE_ALARM_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}" == "TotalConnect failed to arm home instant test."
|
||||
assert hass.states.get(ENTITY_ID).state == STATE_ALARM_DISARMED
|
||||
assert mock_request.call_count == 2
|
||||
|
||||
|
||||
async def test_arm_away_instant_success(hass: HomeAssistant) -> None:
|
||||
"""Test arm home instant method success."""
|
||||
responses = [RESPONSE_DISARMED, RESPONSE_ARM_SUCCESS, RESPONSE_ARMED_AWAY]
|
||||
with patch(TOTALCONNECT_REQUEST, side_effect=responses) as mock_request:
|
||||
await setup_platform(hass, ALARM_DOMAIN)
|
||||
assert hass.states.get(ENTITY_ID).state == STATE_ALARM_DISARMED
|
||||
assert hass.states.get(ENTITY_ID_2).state == STATE_ALARM_DISARMED
|
||||
assert mock_request.call_count == 1
|
||||
|
||||
await hass.services.async_call(
|
||||
DOMAIN, SERVICE_ALARM_ARM_AWAY_INSTANT, DATA, blocking=True
|
||||
)
|
||||
assert mock_request.call_count == 2
|
||||
|
||||
async_fire_time_changed(hass, dt.utcnow() + DELAY)
|
||||
await hass.async_block_till_done()
|
||||
assert mock_request.call_count == 3
|
||||
assert hass.states.get(ENTITY_ID).state == STATE_ALARM_ARMED_AWAY
|
||||
|
||||
|
||||
async def test_arm_away_instant_failure(hass: HomeAssistant) -> None:
|
||||
"""Test arm home instant method failure."""
|
||||
responses = [RESPONSE_DISARMED, RESPONSE_ARM_FAILURE]
|
||||
with patch(TOTALCONNECT_REQUEST, side_effect=responses) as mock_request:
|
||||
await setup_platform(hass, ALARM_DOMAIN)
|
||||
assert hass.states.get(ENTITY_ID).state == STATE_ALARM_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}" == "TotalConnect failed to arm away instant test."
|
||||
assert hass.states.get(ENTITY_ID).state == STATE_ALARM_DISARMED
|
||||
assert mock_request.call_count == 2
|
||||
|
||||
|
||||
async def test_arm_home_invalid_usercode(hass: HomeAssistant) -> None:
|
||||
"""Test arm home method with invalid usercode."""
|
||||
responses = [RESPONSE_DISARMED, RESPONSE_USER_CODE_INVALID]
|
||||
|
Loading…
x
Reference in New Issue
Block a user