Add RestoreEntity to template alarm_control_panel (#125844)
This commit is contained in:
parent
a2a049c5cc
commit
d855f70e3b
2 changed files with 93 additions and 8 deletions
|
@ -4,6 +4,7 @@ from __future__ import annotations
|
||||||
|
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
import logging
|
import logging
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
|
@ -29,12 +30,14 @@ from homeassistant.const import (
|
||||||
STATE_ALARM_PENDING,
|
STATE_ALARM_PENDING,
|
||||||
STATE_ALARM_TRIGGERED,
|
STATE_ALARM_TRIGGERED,
|
||||||
STATE_UNAVAILABLE,
|
STATE_UNAVAILABLE,
|
||||||
|
STATE_UNKNOWN,
|
||||||
)
|
)
|
||||||
from homeassistant.core import HomeAssistant, callback
|
from homeassistant.core import HomeAssistant, callback
|
||||||
from homeassistant.exceptions import TemplateError
|
from homeassistant.exceptions import TemplateError
|
||||||
import homeassistant.helpers.config_validation as cv
|
import homeassistant.helpers.config_validation as cv
|
||||||
from homeassistant.helpers.entity import async_generate_entity_id
|
from homeassistant.helpers.entity import async_generate_entity_id
|
||||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
|
from homeassistant.helpers.restore_state import RestoreEntity
|
||||||
from homeassistant.helpers.script import Script
|
from homeassistant.helpers.script import Script
|
||||||
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
|
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
|
||||||
|
|
||||||
|
@ -103,7 +106,9 @@ PLATFORM_SCHEMA = ALARM_CONTROL_PANEL_PLATFORM_SCHEMA.extend(
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
async def _async_create_entities(hass, config):
|
async def _async_create_entities(
|
||||||
|
hass: HomeAssistant, config: dict[str, Any]
|
||||||
|
) -> list[AlarmControlPanelTemplate]:
|
||||||
"""Create Template Alarm Control Panels."""
|
"""Create Template Alarm Control Panels."""
|
||||||
alarm_control_panels = []
|
alarm_control_panels = []
|
||||||
|
|
||||||
|
@ -133,18 +138,18 @@ async def async_setup_platform(
|
||||||
async_add_entities(await _async_create_entities(hass, config))
|
async_add_entities(await _async_create_entities(hass, config))
|
||||||
|
|
||||||
|
|
||||||
class AlarmControlPanelTemplate(TemplateEntity, AlarmControlPanelEntity):
|
class AlarmControlPanelTemplate(TemplateEntity, AlarmControlPanelEntity, RestoreEntity):
|
||||||
"""Representation of a templated Alarm Control Panel."""
|
"""Representation of a templated Alarm Control Panel."""
|
||||||
|
|
||||||
_attr_should_poll = False
|
_attr_should_poll = False
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
hass,
|
hass: HomeAssistant,
|
||||||
object_id,
|
object_id: str,
|
||||||
config,
|
config: dict,
|
||||||
unique_id,
|
unique_id: str | None,
|
||||||
):
|
) -> None:
|
||||||
"""Initialize the panel."""
|
"""Initialize the panel."""
|
||||||
super().__init__(
|
super().__init__(
|
||||||
hass, config=config, fallback_name=object_id, unique_id=unique_id
|
hass, config=config, fallback_name=object_id, unique_id=unique_id
|
||||||
|
@ -153,6 +158,7 @@ class AlarmControlPanelTemplate(TemplateEntity, AlarmControlPanelEntity):
|
||||||
ENTITY_ID_FORMAT, object_id, hass=hass
|
ENTITY_ID_FORMAT, object_id, hass=hass
|
||||||
)
|
)
|
||||||
name = self._attr_name
|
name = self._attr_name
|
||||||
|
assert name is not None
|
||||||
self._template = config.get(CONF_VALUE_TEMPLATE)
|
self._template = config.get(CONF_VALUE_TEMPLATE)
|
||||||
self._disarm_script = None
|
self._disarm_script = None
|
||||||
self._attr_code_arm_required: bool = config[CONF_CODE_ARM_REQUIRED]
|
self._attr_code_arm_required: bool = config[CONF_CODE_ARM_REQUIRED]
|
||||||
|
@ -216,6 +222,19 @@ class AlarmControlPanelTemplate(TemplateEntity, AlarmControlPanelEntity):
|
||||||
)
|
)
|
||||||
self._attr_supported_features = supported_features
|
self._attr_supported_features = supported_features
|
||||||
|
|
||||||
|
async def async_added_to_hass(self) -> None:
|
||||||
|
"""Restore last state."""
|
||||||
|
await super().async_added_to_hass()
|
||||||
|
if (
|
||||||
|
(last_state := await self.async_get_last_state()) is not None
|
||||||
|
and last_state.state not in (STATE_UNKNOWN, STATE_UNAVAILABLE)
|
||||||
|
and last_state.state in _VALID_STATES
|
||||||
|
# The trigger might have fired already while we waited for stored data,
|
||||||
|
# then we should not restore state
|
||||||
|
and self._state is None
|
||||||
|
):
|
||||||
|
self._state = last_state.state
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def state(self) -> str | None:
|
def state(self) -> str | None:
|
||||||
"""Return the state of the device."""
|
"""Return the state of the device."""
|
||||||
|
|
|
@ -17,8 +17,13 @@ from homeassistant.const import (
|
||||||
STATE_ALARM_DISARMED,
|
STATE_ALARM_DISARMED,
|
||||||
STATE_ALARM_PENDING,
|
STATE_ALARM_PENDING,
|
||||||
STATE_ALARM_TRIGGERED,
|
STATE_ALARM_TRIGGERED,
|
||||||
|
STATE_UNAVAILABLE,
|
||||||
|
STATE_UNKNOWN,
|
||||||
)
|
)
|
||||||
from homeassistant.core import Event, HomeAssistant, callback
|
from homeassistant.core import Event, HomeAssistant, State, callback
|
||||||
|
from homeassistant.setup import async_setup_component
|
||||||
|
|
||||||
|
from tests.common import assert_setup_component, mock_restore_cache
|
||||||
|
|
||||||
TEMPLATE_NAME = "alarm_control_panel.test_template_panel"
|
TEMPLATE_NAME = "alarm_control_panel.test_template_panel"
|
||||||
PANEL_NAME = "alarm_control_panel.test"
|
PANEL_NAME = "alarm_control_panel.test"
|
||||||
|
@ -400,3 +405,64 @@ async def test_code_config(
|
||||||
state = hass.states.get(TEMPLATE_NAME)
|
state = hass.states.get(TEMPLATE_NAME)
|
||||||
assert state.attributes.get("code_format") == code_format
|
assert state.attributes.get("code_format") == code_format
|
||||||
assert state.attributes.get("code_arm_required") == code_arm_required
|
assert state.attributes.get("code_arm_required") == code_arm_required
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(("count", "domain"), [(1, "alarm_control_panel")])
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"config",
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"alarm_control_panel": {
|
||||||
|
"platform": "template",
|
||||||
|
"panels": {"test_template_panel": TEMPLATE_ALARM_CONFIG},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
],
|
||||||
|
)
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
("restored_state", "initial_state"),
|
||||||
|
[
|
||||||
|
(STATE_ALARM_ARMED_AWAY, STATE_ALARM_ARMED_AWAY),
|
||||||
|
(STATE_ALARM_ARMED_CUSTOM_BYPASS, STATE_ALARM_ARMED_CUSTOM_BYPASS),
|
||||||
|
(STATE_ALARM_ARMED_HOME, STATE_ALARM_ARMED_HOME),
|
||||||
|
(STATE_ALARM_ARMED_NIGHT, STATE_ALARM_ARMED_NIGHT),
|
||||||
|
(STATE_ALARM_ARMED_VACATION, STATE_ALARM_ARMED_VACATION),
|
||||||
|
(STATE_ALARM_ARMING, STATE_ALARM_ARMING),
|
||||||
|
(STATE_ALARM_DISARMED, STATE_ALARM_DISARMED),
|
||||||
|
(STATE_ALARM_PENDING, STATE_ALARM_PENDING),
|
||||||
|
(STATE_ALARM_TRIGGERED, STATE_ALARM_TRIGGERED),
|
||||||
|
(STATE_UNAVAILABLE, STATE_UNKNOWN),
|
||||||
|
(STATE_UNKNOWN, STATE_UNKNOWN),
|
||||||
|
("faulty_state", STATE_UNKNOWN),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
async def test_restore_state(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
count,
|
||||||
|
domain,
|
||||||
|
config,
|
||||||
|
restored_state,
|
||||||
|
initial_state,
|
||||||
|
) -> None:
|
||||||
|
"""Test restoring template alarm control panel."""
|
||||||
|
|
||||||
|
fake_state = State(
|
||||||
|
"alarm_control_panel.test_template_panel",
|
||||||
|
restored_state,
|
||||||
|
{},
|
||||||
|
)
|
||||||
|
mock_restore_cache(hass, (fake_state,))
|
||||||
|
with assert_setup_component(count, domain):
|
||||||
|
assert await async_setup_component(
|
||||||
|
hass,
|
||||||
|
domain,
|
||||||
|
config,
|
||||||
|
)
|
||||||
|
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
await hass.async_start()
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
state = hass.states.get("alarm_control_panel.test_template_panel")
|
||||||
|
assert state.state == initial_state
|
||||||
|
|
Loading…
Add table
Reference in a new issue