mirror of
https://github.com/home-assistant/core.git
synced 2025-07-19 03:07:37 +00:00
Improve code quality in Manual alarm (#123142)
* Improve code quality in Manual alarm * Review * Remove helper * Remove unique id * Reset demo and fix unique id * next_state variable * Fixes * Is helper * Fix unique id * exception message * Fix mypy
This commit is contained in:
parent
14c2ca85ec
commit
11d2258afc
@ -295,6 +295,7 @@ homeassistant.components.lookin.*
|
|||||||
homeassistant.components.luftdaten.*
|
homeassistant.components.luftdaten.*
|
||||||
homeassistant.components.madvr.*
|
homeassistant.components.madvr.*
|
||||||
homeassistant.components.mailbox.*
|
homeassistant.components.mailbox.*
|
||||||
|
homeassistant.components.manual.*
|
||||||
homeassistant.components.map.*
|
homeassistant.components.map.*
|
||||||
homeassistant.components.mastodon.*
|
homeassistant.components.mastodon.*
|
||||||
homeassistant.components.matrix.*
|
homeassistant.components.matrix.*
|
||||||
|
@ -30,7 +30,7 @@ async def async_setup_entry(
|
|||||||
"""Set up the Demo config entry."""
|
"""Set up the Demo config entry."""
|
||||||
async_add_entities(
|
async_add_entities(
|
||||||
[
|
[
|
||||||
ManualAlarm( # type:ignore[no-untyped-call]
|
ManualAlarm(
|
||||||
hass,
|
hass,
|
||||||
"Security",
|
"Security",
|
||||||
"demo_alarm_control_panel",
|
"demo_alarm_control_panel",
|
||||||
|
@ -3,12 +3,12 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import datetime
|
import datetime
|
||||||
import logging
|
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
from homeassistant.components.alarm_control_panel import (
|
from homeassistant.components.alarm_control_panel import (
|
||||||
|
PLATFORM_SCHEMA as ALARM_CONTROL_PANEL_PLATFORM_SCHEMA,
|
||||||
AlarmControlPanelEntity,
|
AlarmControlPanelEntity,
|
||||||
AlarmControlPanelEntityFeature,
|
AlarmControlPanelEntityFeature,
|
||||||
CodeFormat,
|
CodeFormat,
|
||||||
@ -19,7 +19,6 @@ from homeassistant.const import (
|
|||||||
CONF_DELAY_TIME,
|
CONF_DELAY_TIME,
|
||||||
CONF_DISARM_AFTER_TRIGGER,
|
CONF_DISARM_AFTER_TRIGGER,
|
||||||
CONF_NAME,
|
CONF_NAME,
|
||||||
CONF_PLATFORM,
|
|
||||||
CONF_TRIGGER_TIME,
|
CONF_TRIGGER_TIME,
|
||||||
CONF_UNIQUE_ID,
|
CONF_UNIQUE_ID,
|
||||||
STATE_ALARM_ARMED_AWAY,
|
STATE_ALARM_ARMED_AWAY,
|
||||||
@ -33,15 +32,16 @@ from homeassistant.const import (
|
|||||||
STATE_ALARM_TRIGGERED,
|
STATE_ALARM_TRIGGERED,
|
||||||
)
|
)
|
||||||
from homeassistant.core import HomeAssistant, callback
|
from homeassistant.core import HomeAssistant, callback
|
||||||
from homeassistant.exceptions import HomeAssistantError
|
from homeassistant.exceptions import ServiceValidationError
|
||||||
import homeassistant.helpers.config_validation as cv
|
import homeassistant.helpers.config_validation as cv
|
||||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
from homeassistant.helpers.event import async_track_point_in_time
|
from homeassistant.helpers.event import async_track_point_in_time
|
||||||
from homeassistant.helpers.restore_state import RestoreEntity
|
from homeassistant.helpers.restore_state import RestoreEntity
|
||||||
|
from homeassistant.helpers.template import Template
|
||||||
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
|
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
|
||||||
import homeassistant.util.dt as dt_util
|
import homeassistant.util.dt as dt_util
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
DOMAIN = "manual"
|
||||||
|
|
||||||
CONF_ARMING_STATES = "arming_states"
|
CONF_ARMING_STATES = "arming_states"
|
||||||
CONF_CODE_TEMPLATE = "code_template"
|
CONF_CODE_TEMPLATE = "code_template"
|
||||||
@ -85,7 +85,7 @@ ATTR_PREVIOUS_STATE = "previous_state"
|
|||||||
ATTR_NEXT_STATE = "next_state"
|
ATTR_NEXT_STATE = "next_state"
|
||||||
|
|
||||||
|
|
||||||
def _state_validator(config):
|
def _state_validator(config: dict[str, Any]) -> dict[str, Any]:
|
||||||
"""Validate the state."""
|
"""Validate the state."""
|
||||||
for state in SUPPORTED_PRETRIGGER_STATES:
|
for state in SUPPORTED_PRETRIGGER_STATES:
|
||||||
if CONF_DELAY_TIME not in config[state]:
|
if CONF_DELAY_TIME not in config[state]:
|
||||||
@ -101,7 +101,7 @@ def _state_validator(config):
|
|||||||
return config
|
return config
|
||||||
|
|
||||||
|
|
||||||
def _state_schema(state):
|
def _state_schema(state: str) -> vol.Schema:
|
||||||
"""Validate the state."""
|
"""Validate the state."""
|
||||||
schema = {}
|
schema = {}
|
||||||
if state in SUPPORTED_PRETRIGGER_STATES:
|
if state in SUPPORTED_PRETRIGGER_STATES:
|
||||||
@ -120,63 +120,64 @@ def _state_schema(state):
|
|||||||
|
|
||||||
PLATFORM_SCHEMA = vol.Schema(
|
PLATFORM_SCHEMA = vol.Schema(
|
||||||
vol.All(
|
vol.All(
|
||||||
{
|
ALARM_CONTROL_PANEL_PLATFORM_SCHEMA.extend(
|
||||||
vol.Required(CONF_PLATFORM): "manual",
|
{
|
||||||
vol.Optional(CONF_NAME, default=DEFAULT_ALARM_NAME): cv.string,
|
vol.Optional(CONF_NAME, default=DEFAULT_ALARM_NAME): cv.string,
|
||||||
vol.Optional(CONF_UNIQUE_ID): cv.string,
|
vol.Optional(CONF_UNIQUE_ID): cv.string,
|
||||||
vol.Exclusive(CONF_CODE, "code validation"): cv.string,
|
vol.Exclusive(CONF_CODE, "code validation"): cv.string,
|
||||||
vol.Exclusive(CONF_CODE_TEMPLATE, "code validation"): cv.template,
|
vol.Exclusive(CONF_CODE_TEMPLATE, "code validation"): cv.template,
|
||||||
vol.Optional(CONF_CODE_ARM_REQUIRED, default=True): cv.boolean,
|
vol.Optional(CONF_CODE_ARM_REQUIRED, default=True): cv.boolean,
|
||||||
vol.Optional(CONF_DELAY_TIME, default=DEFAULT_DELAY_TIME): vol.All(
|
vol.Optional(CONF_DELAY_TIME, default=DEFAULT_DELAY_TIME): vol.All(
|
||||||
cv.time_period, cv.positive_timedelta
|
cv.time_period, cv.positive_timedelta
|
||||||
),
|
),
|
||||||
vol.Optional(CONF_ARMING_TIME, default=DEFAULT_ARMING_TIME): vol.All(
|
vol.Optional(CONF_ARMING_TIME, default=DEFAULT_ARMING_TIME): vol.All(
|
||||||
cv.time_period, cv.positive_timedelta
|
cv.time_period, cv.positive_timedelta
|
||||||
),
|
),
|
||||||
vol.Optional(CONF_TRIGGER_TIME, default=DEFAULT_TRIGGER_TIME): vol.All(
|
vol.Optional(CONF_TRIGGER_TIME, default=DEFAULT_TRIGGER_TIME): vol.All(
|
||||||
cv.time_period, cv.positive_timedelta
|
cv.time_period, cv.positive_timedelta
|
||||||
),
|
),
|
||||||
vol.Optional(
|
vol.Optional(
|
||||||
CONF_DISARM_AFTER_TRIGGER, default=DEFAULT_DISARM_AFTER_TRIGGER
|
CONF_DISARM_AFTER_TRIGGER, default=DEFAULT_DISARM_AFTER_TRIGGER
|
||||||
): cv.boolean,
|
): cv.boolean,
|
||||||
vol.Optional(CONF_ARMING_STATES, default=SUPPORTED_ARMING_STATES): vol.All(
|
vol.Optional(
|
||||||
cv.ensure_list, [vol.In(SUPPORTED_ARMING_STATES)]
|
CONF_ARMING_STATES, default=SUPPORTED_ARMING_STATES
|
||||||
),
|
): vol.All(cv.ensure_list, [vol.In(SUPPORTED_ARMING_STATES)]),
|
||||||
vol.Optional(STATE_ALARM_ARMED_AWAY, default={}): _state_schema(
|
vol.Optional(STATE_ALARM_ARMED_AWAY, default={}): _state_schema(
|
||||||
STATE_ALARM_ARMED_AWAY
|
STATE_ALARM_ARMED_AWAY
|
||||||
),
|
),
|
||||||
vol.Optional(STATE_ALARM_ARMED_HOME, default={}): _state_schema(
|
vol.Optional(STATE_ALARM_ARMED_HOME, default={}): _state_schema(
|
||||||
STATE_ALARM_ARMED_HOME
|
STATE_ALARM_ARMED_HOME
|
||||||
),
|
),
|
||||||
vol.Optional(STATE_ALARM_ARMED_NIGHT, default={}): _state_schema(
|
vol.Optional(STATE_ALARM_ARMED_NIGHT, default={}): _state_schema(
|
||||||
STATE_ALARM_ARMED_NIGHT
|
STATE_ALARM_ARMED_NIGHT
|
||||||
),
|
),
|
||||||
vol.Optional(STATE_ALARM_ARMED_VACATION, default={}): _state_schema(
|
vol.Optional(STATE_ALARM_ARMED_VACATION, default={}): _state_schema(
|
||||||
STATE_ALARM_ARMED_VACATION
|
STATE_ALARM_ARMED_VACATION
|
||||||
),
|
),
|
||||||
vol.Optional(STATE_ALARM_ARMED_CUSTOM_BYPASS, default={}): _state_schema(
|
vol.Optional(
|
||||||
STATE_ALARM_ARMED_CUSTOM_BYPASS
|
STATE_ALARM_ARMED_CUSTOM_BYPASS, default={}
|
||||||
),
|
): _state_schema(STATE_ALARM_ARMED_CUSTOM_BYPASS),
|
||||||
vol.Optional(STATE_ALARM_DISARMED, default={}): _state_schema(
|
vol.Optional(STATE_ALARM_DISARMED, default={}): _state_schema(
|
||||||
STATE_ALARM_DISARMED
|
STATE_ALARM_DISARMED
|
||||||
),
|
),
|
||||||
vol.Optional(STATE_ALARM_TRIGGERED, default={}): _state_schema(
|
vol.Optional(STATE_ALARM_TRIGGERED, default={}): _state_schema(
|
||||||
STATE_ALARM_TRIGGERED
|
STATE_ALARM_TRIGGERED
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
),
|
||||||
_state_validator,
|
_state_validator,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def setup_platform(
|
async def async_setup_platform(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
config: ConfigType,
|
config: ConfigType,
|
||||||
add_entities: AddEntitiesCallback,
|
async_add_entities: AddEntitiesCallback,
|
||||||
discovery_info: DiscoveryInfoType | None = None,
|
discovery_info: DiscoveryInfoType | None = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Set up the manual alarm platform."""
|
"""Set up the manual alarm platform."""
|
||||||
add_entities(
|
async_add_entities(
|
||||||
[
|
[
|
||||||
ManualAlarm(
|
ManualAlarm(
|
||||||
hass,
|
hass,
|
||||||
@ -184,8 +185,8 @@ def setup_platform(
|
|||||||
config.get(CONF_UNIQUE_ID),
|
config.get(CONF_UNIQUE_ID),
|
||||||
config.get(CONF_CODE),
|
config.get(CONF_CODE),
|
||||||
config.get(CONF_CODE_TEMPLATE),
|
config.get(CONF_CODE_TEMPLATE),
|
||||||
config.get(CONF_CODE_ARM_REQUIRED),
|
config[CONF_CODE_ARM_REQUIRED],
|
||||||
config.get(CONF_DISARM_AFTER_TRIGGER, DEFAULT_DISARM_AFTER_TRIGGER),
|
config[CONF_DISARM_AFTER_TRIGGER],
|
||||||
config,
|
config,
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
@ -206,28 +207,25 @@ class ManualAlarm(AlarmControlPanelEntity, RestoreEntity):
|
|||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
hass,
|
hass: HomeAssistant,
|
||||||
name,
|
name: str,
|
||||||
unique_id,
|
unique_id: str | None,
|
||||||
code,
|
code: str | None,
|
||||||
code_template,
|
code_template: Template | None,
|
||||||
code_arm_required,
|
code_arm_required: bool,
|
||||||
disarm_after_trigger,
|
disarm_after_trigger: bool,
|
||||||
config,
|
config: dict[str, Any],
|
||||||
):
|
) -> None:
|
||||||
"""Init the manual alarm panel."""
|
"""Init the manual alarm panel."""
|
||||||
self._state = STATE_ALARM_DISARMED
|
self._state = STATE_ALARM_DISARMED
|
||||||
self._hass = hass
|
self._hass = hass
|
||||||
self._attr_name = name
|
self._attr_name = name
|
||||||
self._attr_unique_id = unique_id
|
self._attr_unique_id = unique_id
|
||||||
if code_template:
|
self._code = code_template or code or None
|
||||||
self._code = code_template
|
|
||||||
else:
|
|
||||||
self._code = code or None
|
|
||||||
self._attr_code_arm_required = code_arm_required
|
self._attr_code_arm_required = code_arm_required
|
||||||
self._disarm_after_trigger = disarm_after_trigger
|
self._disarm_after_trigger = disarm_after_trigger
|
||||||
self._previous_state = self._state
|
self._previous_state = self._state
|
||||||
self._state_ts = None
|
self._state_ts: datetime.datetime = dt_util.utcnow()
|
||||||
|
|
||||||
self._delay_time_by_state = {
|
self._delay_time_by_state = {
|
||||||
state: config[state][CONF_DELAY_TIME]
|
state: config[state][CONF_DELAY_TIME]
|
||||||
@ -253,7 +251,9 @@ class ManualAlarm(AlarmControlPanelEntity, RestoreEntity):
|
|||||||
if self._state == STATE_ALARM_TRIGGERED:
|
if self._state == STATE_ALARM_TRIGGERED:
|
||||||
if self._within_pending_time(self._state):
|
if self._within_pending_time(self._state):
|
||||||
return STATE_ALARM_PENDING
|
return STATE_ALARM_PENDING
|
||||||
trigger_time = self._trigger_time_by_state[self._previous_state]
|
trigger_time: datetime.timedelta = self._trigger_time_by_state[
|
||||||
|
self._previous_state
|
||||||
|
]
|
||||||
if (
|
if (
|
||||||
self._state_ts + self._pending_time(self._state) + trigger_time
|
self._state_ts + self._pending_time(self._state) + trigger_time
|
||||||
) < dt_util.utcnow():
|
) < dt_util.utcnow():
|
||||||
@ -270,25 +270,27 @@ class ManualAlarm(AlarmControlPanelEntity, RestoreEntity):
|
|||||||
return self._state
|
return self._state
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def _active_state(self):
|
def _active_state(self) -> str:
|
||||||
"""Get the current state."""
|
"""Get the current state."""
|
||||||
if self.state in (STATE_ALARM_PENDING, STATE_ALARM_ARMING):
|
if self.state in (STATE_ALARM_PENDING, STATE_ALARM_ARMING):
|
||||||
return self._previous_state
|
return self._previous_state
|
||||||
return self._state
|
return self._state
|
||||||
|
|
||||||
def _arming_time(self, state):
|
def _arming_time(self, state: str) -> datetime.timedelta:
|
||||||
"""Get the arming time."""
|
"""Get the arming time."""
|
||||||
return self._arming_time_by_state[state]
|
arming_time: datetime.timedelta = self._arming_time_by_state[state]
|
||||||
|
return arming_time
|
||||||
|
|
||||||
def _pending_time(self, state):
|
def _pending_time(self, state: str) -> datetime.timedelta:
|
||||||
"""Get the pending time."""
|
"""Get the pending time."""
|
||||||
return self._delay_time_by_state[self._previous_state]
|
delay_time: datetime.timedelta = self._delay_time_by_state[self._previous_state]
|
||||||
|
return delay_time
|
||||||
|
|
||||||
def _within_arming_time(self, state):
|
def _within_arming_time(self, state: str) -> bool:
|
||||||
"""Get if the action is in the arming time window."""
|
"""Get if the action is in the arming time window."""
|
||||||
return self._state_ts + self._arming_time(state) > dt_util.utcnow()
|
return self._state_ts + self._arming_time(state) > dt_util.utcnow()
|
||||||
|
|
||||||
def _within_pending_time(self, state):
|
def _within_pending_time(self, state: str) -> bool:
|
||||||
"""Get if the action is in the pending time window."""
|
"""Get if the action is in the pending time window."""
|
||||||
return self._state_ts + self._pending_time(state) > dt_util.utcnow()
|
return self._state_ts + self._pending_time(state) > dt_util.utcnow()
|
||||||
|
|
||||||
@ -377,7 +379,7 @@ class ManualAlarm(AlarmControlPanelEntity, RestoreEntity):
|
|||||||
self._state_ts + arming_time,
|
self._state_ts + arming_time,
|
||||||
)
|
)
|
||||||
|
|
||||||
def _async_validate_code(self, code, state):
|
def _async_validate_code(self, code: str | None, state: str) -> None:
|
||||||
"""Validate given code."""
|
"""Validate given code."""
|
||||||
if (
|
if (
|
||||||
state != STATE_ALARM_DISARMED and not self.code_arm_required
|
state != STATE_ALARM_DISARMED and not self.code_arm_required
|
||||||
@ -394,24 +396,28 @@ class ManualAlarm(AlarmControlPanelEntity, RestoreEntity):
|
|||||||
if not alarm_code or code == alarm_code:
|
if not alarm_code or code == alarm_code:
|
||||||
return
|
return
|
||||||
|
|
||||||
raise HomeAssistantError("Invalid alarm code provided")
|
raise ServiceValidationError(
|
||||||
|
"Invalid alarm code provided",
|
||||||
|
translation_domain=DOMAIN,
|
||||||
|
translation_key="invalid_code",
|
||||||
|
)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def extra_state_attributes(self) -> dict[str, Any]:
|
def extra_state_attributes(self) -> dict[str, Any]:
|
||||||
"""Return the state attributes."""
|
"""Return the state attributes."""
|
||||||
if self.state in (STATE_ALARM_PENDING, STATE_ALARM_ARMING):
|
if self.state in (STATE_ALARM_PENDING, STATE_ALARM_ARMING):
|
||||||
return {
|
prev_state: str | None = self._previous_state
|
||||||
ATTR_PREVIOUS_STATE: self._previous_state,
|
state: str | None = self._state
|
||||||
ATTR_NEXT_STATE: self._state,
|
elif self.state == STATE_ALARM_TRIGGERED:
|
||||||
}
|
prev_state = self._previous_state
|
||||||
if self.state == STATE_ALARM_TRIGGERED:
|
state = None
|
||||||
return {
|
else:
|
||||||
ATTR_PREVIOUS_STATE: self._previous_state,
|
prev_state = None
|
||||||
}
|
state = None
|
||||||
return {}
|
return {ATTR_PREVIOUS_STATE: prev_state, ATTR_NEXT_STATE: state}
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
def async_scheduled_update(self, now):
|
def async_scheduled_update(self, now: datetime.datetime) -> None:
|
||||||
"""Update state at a scheduled point in time."""
|
"""Update state at a scheduled point in time."""
|
||||||
self.async_write_ha_state()
|
self.async_write_ha_state()
|
||||||
|
|
||||||
@ -420,13 +426,13 @@ class ManualAlarm(AlarmControlPanelEntity, RestoreEntity):
|
|||||||
await super().async_added_to_hass()
|
await super().async_added_to_hass()
|
||||||
if state := await self.async_get_last_state():
|
if state := await self.async_get_last_state():
|
||||||
self._state_ts = state.last_updated
|
self._state_ts = state.last_updated
|
||||||
if hasattr(state, "attributes") and ATTR_NEXT_STATE in state.attributes:
|
if next_state := state.attributes.get(ATTR_NEXT_STATE):
|
||||||
# If in arming or pending state we record the transition,
|
# If in arming or pending state we record the transition,
|
||||||
# not the current state
|
# not the current state
|
||||||
self._state = state.attributes[ATTR_NEXT_STATE]
|
self._state = next_state
|
||||||
else:
|
else:
|
||||||
self._state = state.state
|
self._state = state.state
|
||||||
|
|
||||||
if hasattr(state, "attributes") and ATTR_PREVIOUS_STATE in state.attributes:
|
if prev_state := state.attributes.get(ATTR_PREVIOUS_STATE):
|
||||||
self._previous_state = state.attributes[ATTR_PREVIOUS_STATE]
|
self._previous_state = prev_state
|
||||||
self._async_set_state_update_events()
|
self._async_set_state_update_events()
|
||||||
|
7
homeassistant/components/manual/strings.json
Normal file
7
homeassistant/components/manual/strings.json
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"exceptions": {
|
||||||
|
"invalid_code": {
|
||||||
|
"message": "Invalid alarm code provided"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
10
mypy.ini
10
mypy.ini
@ -2706,6 +2706,16 @@ disallow_untyped_defs = true
|
|||||||
warn_return_any = true
|
warn_return_any = true
|
||||||
warn_unreachable = true
|
warn_unreachable = true
|
||||||
|
|
||||||
|
[mypy-homeassistant.components.manual.*]
|
||||||
|
check_untyped_defs = true
|
||||||
|
disallow_incomplete_defs = true
|
||||||
|
disallow_subclassing_any = true
|
||||||
|
disallow_untyped_calls = true
|
||||||
|
disallow_untyped_decorators = true
|
||||||
|
disallow_untyped_defs = true
|
||||||
|
warn_return_any = true
|
||||||
|
warn_unreachable = true
|
||||||
|
|
||||||
[mypy-homeassistant.components.map.*]
|
[mypy-homeassistant.components.map.*]
|
||||||
check_untyped_defs = true
|
check_untyped_defs = true
|
||||||
disallow_incomplete_defs = true
|
disallow_incomplete_defs = true
|
||||||
|
@ -9,6 +9,10 @@ import pytest
|
|||||||
from homeassistant.components import alarm_control_panel
|
from homeassistant.components import alarm_control_panel
|
||||||
from homeassistant.components.alarm_control_panel import AlarmControlPanelEntityFeature
|
from homeassistant.components.alarm_control_panel import AlarmControlPanelEntityFeature
|
||||||
from homeassistant.components.demo import alarm_control_panel as demo
|
from homeassistant.components.demo import alarm_control_panel as demo
|
||||||
|
from homeassistant.components.manual.alarm_control_panel import (
|
||||||
|
ATTR_NEXT_STATE,
|
||||||
|
ATTR_PREVIOUS_STATE,
|
||||||
|
)
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
ATTR_CODE,
|
ATTR_CODE,
|
||||||
ATTR_ENTITY_ID,
|
ATTR_ENTITY_ID,
|
||||||
@ -28,7 +32,7 @@ from homeassistant.const import (
|
|||||||
STATE_ALARM_TRIGGERED,
|
STATE_ALARM_TRIGGERED,
|
||||||
)
|
)
|
||||||
from homeassistant.core import CoreState, HomeAssistant, State
|
from homeassistant.core import CoreState, HomeAssistant, State
|
||||||
from homeassistant.exceptions import HomeAssistantError
|
from homeassistant.exceptions import ServiceValidationError
|
||||||
from homeassistant.setup import async_setup_component
|
from homeassistant.setup import async_setup_component
|
||||||
import homeassistant.util.dt as dt_util
|
import homeassistant.util.dt as dt_util
|
||||||
|
|
||||||
@ -227,7 +231,7 @@ async def test_with_invalid_code(hass: HomeAssistant, service, expected_state) -
|
|||||||
|
|
||||||
assert hass.states.get(entity_id).state == STATE_ALARM_DISARMED
|
assert hass.states.get(entity_id).state == STATE_ALARM_DISARMED
|
||||||
|
|
||||||
with pytest.raises(HomeAssistantError, match=r"^Invalid alarm code provided$"):
|
with pytest.raises(ServiceValidationError, match=r"^Invalid alarm code provided$"):
|
||||||
await hass.services.async_call(
|
await hass.services.async_call(
|
||||||
alarm_control_panel.DOMAIN,
|
alarm_control_panel.DOMAIN,
|
||||||
service,
|
service,
|
||||||
@ -1089,7 +1093,7 @@ async def test_disarm_during_trigger_with_invalid_code(hass: HomeAssistant) -> N
|
|||||||
|
|
||||||
assert hass.states.get(entity_id).state == STATE_ALARM_PENDING
|
assert hass.states.get(entity_id).state == STATE_ALARM_PENDING
|
||||||
|
|
||||||
with pytest.raises(HomeAssistantError, match=r"^Invalid alarm code provided$"):
|
with pytest.raises(ServiceValidationError, match=r"^Invalid alarm code provided$"):
|
||||||
await common.async_alarm_disarm(hass, entity_id=entity_id)
|
await common.async_alarm_disarm(hass, entity_id=entity_id)
|
||||||
|
|
||||||
assert hass.states.get(entity_id).state == STATE_ALARM_PENDING
|
assert hass.states.get(entity_id).state == STATE_ALARM_PENDING
|
||||||
@ -1133,7 +1137,7 @@ async def test_disarm_with_template_code(hass: HomeAssistant) -> None:
|
|||||||
state = hass.states.get(entity_id)
|
state = hass.states.get(entity_id)
|
||||||
assert state.state == STATE_ALARM_ARMED_HOME
|
assert state.state == STATE_ALARM_ARMED_HOME
|
||||||
|
|
||||||
with pytest.raises(HomeAssistantError, match=r"^Invalid alarm code provided$"):
|
with pytest.raises(ServiceValidationError, match=r"^Invalid alarm code provided$"):
|
||||||
await common.async_alarm_disarm(hass, "def")
|
await common.async_alarm_disarm(hass, "def")
|
||||||
|
|
||||||
state = hass.states.get(entity_id)
|
state = hass.states.get(entity_id)
|
||||||
@ -1411,8 +1415,8 @@ async def test_restore_state_triggered(hass: HomeAssistant, previous_state) -> N
|
|||||||
|
|
||||||
state = hass.states.get(entity_id)
|
state = hass.states.get(entity_id)
|
||||||
assert state
|
assert state
|
||||||
assert state.attributes["previous_state"] == previous_state
|
assert state.attributes[ATTR_PREVIOUS_STATE] == previous_state
|
||||||
assert "next_state" not in state.attributes
|
assert state.attributes[ATTR_NEXT_STATE] is None
|
||||||
assert state.state == STATE_ALARM_TRIGGERED
|
assert state.state == STATE_ALARM_TRIGGERED
|
||||||
|
|
||||||
future = time + timedelta(seconds=121)
|
future = time + timedelta(seconds=121)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user