mirror of
https://github.com/home-assistant/core.git
synced 2025-07-15 09:17:10 +00:00
Raise on invalid (dis)arm code in manual alarm (#90579)
This commit is contained in:
parent
89dc6db5a7
commit
88a407361c
@ -29,6 +29,7 @@ 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
|
||||||
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
|
||||||
@ -285,56 +286,34 @@ class ManualAlarm(alarm.AlarmControlPanelEntity, RestoreEntity):
|
|||||||
|
|
||||||
async def async_alarm_disarm(self, code: str | None = None) -> None:
|
async def async_alarm_disarm(self, code: str | None = None) -> None:
|
||||||
"""Send disarm command."""
|
"""Send disarm command."""
|
||||||
if not self._async_validate_code(code, STATE_ALARM_DISARMED):
|
self._async_validate_code(code, STATE_ALARM_DISARMED)
|
||||||
return
|
|
||||||
|
|
||||||
self._state = STATE_ALARM_DISARMED
|
self._state = STATE_ALARM_DISARMED
|
||||||
self._state_ts = dt_util.utcnow()
|
self._state_ts = dt_util.utcnow()
|
||||||
self.async_write_ha_state()
|
self.async_write_ha_state()
|
||||||
|
|
||||||
async def async_alarm_arm_home(self, code: str | None = None) -> None:
|
async def async_alarm_arm_home(self, code: str | None = None) -> None:
|
||||||
"""Send arm home command."""
|
"""Send arm home command."""
|
||||||
if self.code_arm_required and not self._async_validate_code(
|
self._async_validate_code(code, STATE_ALARM_ARMED_HOME)
|
||||||
code, STATE_ALARM_ARMED_HOME
|
|
||||||
):
|
|
||||||
return
|
|
||||||
|
|
||||||
self._async_update_state(STATE_ALARM_ARMED_HOME)
|
self._async_update_state(STATE_ALARM_ARMED_HOME)
|
||||||
|
|
||||||
async def async_alarm_arm_away(self, code: str | None = None) -> None:
|
async def async_alarm_arm_away(self, code: str | None = None) -> None:
|
||||||
"""Send arm away command."""
|
"""Send arm away command."""
|
||||||
if self.code_arm_required and not self._async_validate_code(
|
self._async_validate_code(code, STATE_ALARM_ARMED_AWAY)
|
||||||
code, STATE_ALARM_ARMED_AWAY
|
|
||||||
):
|
|
||||||
return
|
|
||||||
|
|
||||||
self._async_update_state(STATE_ALARM_ARMED_AWAY)
|
self._async_update_state(STATE_ALARM_ARMED_AWAY)
|
||||||
|
|
||||||
async def async_alarm_arm_night(self, code: str | None = None) -> None:
|
async def async_alarm_arm_night(self, code: str | None = None) -> None:
|
||||||
"""Send arm night command."""
|
"""Send arm night command."""
|
||||||
if self.code_arm_required and not self._async_validate_code(
|
self._async_validate_code(code, STATE_ALARM_ARMED_NIGHT)
|
||||||
code, STATE_ALARM_ARMED_NIGHT
|
|
||||||
):
|
|
||||||
return
|
|
||||||
|
|
||||||
self._async_update_state(STATE_ALARM_ARMED_NIGHT)
|
self._async_update_state(STATE_ALARM_ARMED_NIGHT)
|
||||||
|
|
||||||
async def async_alarm_arm_vacation(self, code: str | None = None) -> None:
|
async def async_alarm_arm_vacation(self, code: str | None = None) -> None:
|
||||||
"""Send arm vacation command."""
|
"""Send arm vacation command."""
|
||||||
if self.code_arm_required and not self._async_validate_code(
|
self._async_validate_code(code, STATE_ALARM_ARMED_VACATION)
|
||||||
code, STATE_ALARM_ARMED_VACATION
|
|
||||||
):
|
|
||||||
return
|
|
||||||
|
|
||||||
self._async_update_state(STATE_ALARM_ARMED_VACATION)
|
self._async_update_state(STATE_ALARM_ARMED_VACATION)
|
||||||
|
|
||||||
async def async_alarm_arm_custom_bypass(self, code: str | None = None) -> None:
|
async def async_alarm_arm_custom_bypass(self, code: str | None = None) -> None:
|
||||||
"""Send arm custom bypass command."""
|
"""Send arm custom bypass command."""
|
||||||
if self.code_arm_required and not self._async_validate_code(
|
self._async_validate_code(code, STATE_ALARM_ARMED_CUSTOM_BYPASS)
|
||||||
code, STATE_ALARM_ARMED_CUSTOM_BYPASS
|
|
||||||
):
|
|
||||||
return
|
|
||||||
|
|
||||||
self._async_update_state(STATE_ALARM_ARMED_CUSTOM_BYPASS)
|
self._async_update_state(STATE_ALARM_ARMED_CUSTOM_BYPASS)
|
||||||
|
|
||||||
async def async_alarm_trigger(self, code: str | None = None) -> None:
|
async def async_alarm_trigger(self, code: str | None = None) -> None:
|
||||||
@ -383,18 +362,22 @@ class ManualAlarm(alarm.AlarmControlPanelEntity, RestoreEntity):
|
|||||||
|
|
||||||
def _async_validate_code(self, code, state):
|
def _async_validate_code(self, code, state):
|
||||||
"""Validate given code."""
|
"""Validate given code."""
|
||||||
if self._code is None:
|
if (
|
||||||
return True
|
state != STATE_ALARM_DISARMED and not self.code_arm_required
|
||||||
|
) or self._code is None:
|
||||||
|
return
|
||||||
|
|
||||||
if isinstance(self._code, str):
|
if isinstance(self._code, str):
|
||||||
alarm_code = self._code
|
alarm_code = self._code
|
||||||
else:
|
else:
|
||||||
alarm_code = self._code.async_render(
|
alarm_code = self._code.async_render(
|
||||||
parse_result=False, from_state=self._state, to_state=state
|
parse_result=False, from_state=self._state, to_state=state
|
||||||
)
|
)
|
||||||
check = not alarm_code or code == alarm_code
|
|
||||||
if not check:
|
if not alarm_code or code == alarm_code:
|
||||||
_LOGGER.warning("Invalid code given for %s", state)
|
return
|
||||||
return check
|
|
||||||
|
raise HomeAssistantError("Invalid alarm code provided")
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def extra_state_attributes(self) -> dict[str, Any]:
|
def extra_state_attributes(self) -> dict[str, Any]:
|
||||||
|
@ -26,6 +26,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.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
|
||||||
|
|
||||||
@ -224,12 +225,16 @@ 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
|
||||||
|
|
||||||
await hass.services.async_call(
|
with pytest.raises(HomeAssistantError, match=r"^Invalid alarm code provided$"):
|
||||||
alarm_control_panel.DOMAIN,
|
await hass.services.async_call(
|
||||||
service,
|
alarm_control_panel.DOMAIN,
|
||||||
{ATTR_ENTITY_ID: "alarm_control_panel.test", ATTR_CODE: CODE + "2"},
|
service,
|
||||||
blocking=True,
|
{
|
||||||
)
|
ATTR_ENTITY_ID: "alarm_control_panel.test",
|
||||||
|
ATTR_CODE: f"{CODE}2",
|
||||||
|
},
|
||||||
|
blocking=True,
|
||||||
|
)
|
||||||
|
|
||||||
assert hass.states.get(entity_id).state == STATE_ALARM_DISARMED
|
assert hass.states.get(entity_id).state == STATE_ALARM_DISARMED
|
||||||
|
|
||||||
@ -1082,7 +1087,8 @@ 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
|
||||||
|
|
||||||
await common.async_alarm_disarm(hass, entity_id=entity_id)
|
with pytest.raises(HomeAssistantError, match=r"^Invalid alarm code provided$"):
|
||||||
|
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
|
||||||
|
|
||||||
@ -1125,7 +1131,8 @@ 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
|
||||||
|
|
||||||
await common.async_alarm_disarm(hass, "def")
|
with pytest.raises(HomeAssistantError, match=r"^Invalid alarm code provided$"):
|
||||||
|
await common.async_alarm_disarm(hass, "def")
|
||||||
|
|
||||||
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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user