Update alarm control panel and deconz alarm event to reflect the finalized implementation in deCONZ (#54936)
* Update alarm control panel and deconz alarm event to reflect the new implementation in deCONZ * Bump dependency to v83
This commit is contained in:
parent
4d452dbccf
commit
6ad0e0220a
8 changed files with 294 additions and 236 deletions
|
@ -5,13 +5,19 @@ from pydeconz.sensor import (
|
|||
ANCILLARY_CONTROL_ARMED_AWAY,
|
||||
ANCILLARY_CONTROL_ARMED_NIGHT,
|
||||
ANCILLARY_CONTROL_ARMED_STAY,
|
||||
ANCILLARY_CONTROL_ARMING_AWAY,
|
||||
ANCILLARY_CONTROL_ARMING_NIGHT,
|
||||
ANCILLARY_CONTROL_ARMING_STAY,
|
||||
ANCILLARY_CONTROL_DISARMED,
|
||||
ANCILLARY_CONTROL_ENTRY_DELAY,
|
||||
ANCILLARY_CONTROL_EXIT_DELAY,
|
||||
ANCILLARY_CONTROL_IN_ALARM,
|
||||
AncillaryControl,
|
||||
)
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.components.alarm_control_panel import (
|
||||
DOMAIN,
|
||||
FORMAT_NUMBER,
|
||||
SUPPORT_ALARM_ARM_AWAY,
|
||||
SUPPORT_ALARM_ARM_HOME,
|
||||
SUPPORT_ALARM_ARM_NIGHT,
|
||||
|
@ -21,40 +27,39 @@ from homeassistant.const import (
|
|||
STATE_ALARM_ARMED_AWAY,
|
||||
STATE_ALARM_ARMED_HOME,
|
||||
STATE_ALARM_ARMED_NIGHT,
|
||||
STATE_ALARM_ARMING,
|
||||
STATE_ALARM_DISARMED,
|
||||
STATE_ALARM_PENDING,
|
||||
STATE_ALARM_TRIGGERED,
|
||||
)
|
||||
from homeassistant.core import callback
|
||||
from homeassistant.helpers import entity_platform
|
||||
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
||||
|
||||
from .const import NEW_SENSOR
|
||||
from .deconz_device import DeconzDevice
|
||||
from .gateway import get_gateway_from_config_entry
|
||||
|
||||
PANEL_ENTRY_DELAY = "entry_delay"
|
||||
PANEL_EXIT_DELAY = "exit_delay"
|
||||
PANEL_NOT_READY_TO_ARM = "not_ready_to_arm"
|
||||
|
||||
SERVICE_ALARM_PANEL_STATE = "alarm_panel_state"
|
||||
CONF_ALARM_PANEL_STATE = "panel_state"
|
||||
SERVICE_ALARM_PANEL_STATE_SCHEMA = {
|
||||
vol.Required(CONF_ALARM_PANEL_STATE): vol.In(
|
||||
[
|
||||
PANEL_ENTRY_DELAY,
|
||||
PANEL_EXIT_DELAY,
|
||||
PANEL_NOT_READY_TO_ARM,
|
||||
]
|
||||
)
|
||||
}
|
||||
|
||||
DECONZ_TO_ALARM_STATE = {
|
||||
ANCILLARY_CONTROL_ARMED_AWAY: STATE_ALARM_ARMED_AWAY,
|
||||
ANCILLARY_CONTROL_ARMED_NIGHT: STATE_ALARM_ARMED_NIGHT,
|
||||
ANCILLARY_CONTROL_ARMED_STAY: STATE_ALARM_ARMED_HOME,
|
||||
ANCILLARY_CONTROL_ARMING_AWAY: STATE_ALARM_ARMING,
|
||||
ANCILLARY_CONTROL_ARMING_NIGHT: STATE_ALARM_ARMING,
|
||||
ANCILLARY_CONTROL_ARMING_STAY: STATE_ALARM_ARMING,
|
||||
ANCILLARY_CONTROL_DISARMED: STATE_ALARM_DISARMED,
|
||||
ANCILLARY_CONTROL_ENTRY_DELAY: STATE_ALARM_PENDING,
|
||||
ANCILLARY_CONTROL_EXIT_DELAY: STATE_ALARM_PENDING,
|
||||
ANCILLARY_CONTROL_IN_ALARM: STATE_ALARM_TRIGGERED,
|
||||
}
|
||||
|
||||
|
||||
def get_alarm_system_for_unique_id(gateway, unique_id: str):
|
||||
"""Retrieve alarm system unique ID is registered to."""
|
||||
for alarm_system in gateway.api.alarm_systems.values():
|
||||
if unique_id in alarm_system.devices:
|
||||
return alarm_system
|
||||
|
||||
|
||||
async def async_setup_entry(hass, config_entry, async_add_entities) -> None:
|
||||
"""Set up the deCONZ alarm control panel devices.
|
||||
|
||||
|
@ -63,8 +68,6 @@ async def async_setup_entry(hass, config_entry, async_add_entities) -> None:
|
|||
gateway = get_gateway_from_config_entry(hass, config_entry)
|
||||
gateway.entities[DOMAIN] = set()
|
||||
|
||||
platform = entity_platform.async_get_current_platform()
|
||||
|
||||
@callback
|
||||
def async_add_alarm_control_panel(sensors=gateway.api.sensors.values()) -> None:
|
||||
"""Add alarm control panel devices from deCONZ."""
|
||||
|
@ -75,15 +78,12 @@ async def async_setup_entry(hass, config_entry, async_add_entities) -> None:
|
|||
if (
|
||||
sensor.type in AncillaryControl.ZHATYPE
|
||||
and sensor.uniqueid not in gateway.entities[DOMAIN]
|
||||
and get_alarm_system_for_unique_id(gateway, sensor.uniqueid)
|
||||
):
|
||||
|
||||
entities.append(DeconzAlarmControlPanel(sensor, gateway))
|
||||
|
||||
if entities:
|
||||
platform.async_register_entity_service(
|
||||
SERVICE_ALARM_PANEL_STATE,
|
||||
SERVICE_ALARM_PANEL_STATE_SCHEMA,
|
||||
"async_set_panel_state",
|
||||
)
|
||||
async_add_entities(entities)
|
||||
|
||||
config_entry.async_on_unload(
|
||||
|
@ -102,7 +102,7 @@ class DeconzAlarmControlPanel(DeconzDevice, AlarmControlPanelEntity):
|
|||
|
||||
TYPE = DOMAIN
|
||||
|
||||
_attr_code_arm_required = False
|
||||
_attr_code_format = FORMAT_NUMBER
|
||||
_attr_supported_features = (
|
||||
SUPPORT_ALARM_ARM_AWAY | SUPPORT_ALARM_ARM_HOME | SUPPORT_ALARM_ARM_NIGHT
|
||||
)
|
||||
|
@ -110,16 +110,12 @@ class DeconzAlarmControlPanel(DeconzDevice, AlarmControlPanelEntity):
|
|||
def __init__(self, device, gateway) -> None:
|
||||
"""Set up alarm control panel device."""
|
||||
super().__init__(device, gateway)
|
||||
self._service_to_device_panel_command = {
|
||||
PANEL_ENTRY_DELAY: self._device.entry_delay,
|
||||
PANEL_EXIT_DELAY: self._device.exit_delay,
|
||||
PANEL_NOT_READY_TO_ARM: self._device.not_ready_to_arm,
|
||||
}
|
||||
self.alarm_system = get_alarm_system_for_unique_id(gateway, device.uniqueid)
|
||||
|
||||
@callback
|
||||
def async_update_callback(self, force_update: bool = False) -> None:
|
||||
"""Update the control panels state."""
|
||||
keys = {"armed", "reachable"}
|
||||
keys = {"panel", "reachable"}
|
||||
if force_update or (
|
||||
self._device.changed_keys.intersection(keys)
|
||||
and self._device.state in DECONZ_TO_ALARM_STATE
|
||||
|
@ -133,20 +129,16 @@ class DeconzAlarmControlPanel(DeconzDevice, AlarmControlPanelEntity):
|
|||
|
||||
async def async_alarm_arm_away(self, code: None = None) -> None:
|
||||
"""Send arm away command."""
|
||||
await self._device.arm_away()
|
||||
await self.alarm_system.arm_away(code)
|
||||
|
||||
async def async_alarm_arm_home(self, code: None = None) -> None:
|
||||
"""Send arm home command."""
|
||||
await self._device.arm_stay()
|
||||
await self.alarm_system.arm_stay(code)
|
||||
|
||||
async def async_alarm_arm_night(self, code: None = None) -> None:
|
||||
"""Send arm night command."""
|
||||
await self._device.arm_night()
|
||||
await self.alarm_system.arm_night(code)
|
||||
|
||||
async def async_alarm_disarm(self, code: None = None) -> None:
|
||||
"""Send disarm command."""
|
||||
await self._device.disarm()
|
||||
|
||||
async def async_set_panel_state(self, panel_state: str) -> None:
|
||||
"""Send panel_state command."""
|
||||
await self._service_to_device_panel_command[panel_state]()
|
||||
await self.alarm_system.disarm(code)
|
||||
|
|
|
@ -1,25 +1,20 @@
|
|||
"""Representation of a deCONZ remote or keypad."""
|
||||
|
||||
from pydeconz.sensor import (
|
||||
ANCILLARY_CONTROL_ARMED_AWAY,
|
||||
ANCILLARY_CONTROL_ARMED_NIGHT,
|
||||
ANCILLARY_CONTROL_ARMED_STAY,
|
||||
ANCILLARY_CONTROL_DISARMED,
|
||||
ANCILLARY_CONTROL_EMERGENCY,
|
||||
ANCILLARY_CONTROL_FIRE,
|
||||
ANCILLARY_CONTROL_INVALID_CODE,
|
||||
ANCILLARY_CONTROL_PANIC,
|
||||
AncillaryControl,
|
||||
Switch,
|
||||
)
|
||||
|
||||
from homeassistant.const import (
|
||||
CONF_CODE,
|
||||
CONF_DEVICE_ID,
|
||||
CONF_EVENT,
|
||||
CONF_ID,
|
||||
CONF_UNIQUE_ID,
|
||||
CONF_XY,
|
||||
STATE_ALARM_ARMED_AWAY,
|
||||
STATE_ALARM_ARMED_HOME,
|
||||
STATE_ALARM_ARMED_NIGHT,
|
||||
STATE_ALARM_DISARMED,
|
||||
)
|
||||
from homeassistant.core import callback
|
||||
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
||||
|
@ -31,11 +26,11 @@ from .deconz_device import DeconzBase
|
|||
CONF_DECONZ_EVENT = "deconz_event"
|
||||
CONF_DECONZ_ALARM_EVENT = "deconz_alarm_event"
|
||||
|
||||
DECONZ_TO_ALARM_STATE = {
|
||||
ANCILLARY_CONTROL_ARMED_AWAY: STATE_ALARM_ARMED_AWAY,
|
||||
ANCILLARY_CONTROL_ARMED_NIGHT: STATE_ALARM_ARMED_NIGHT,
|
||||
ANCILLARY_CONTROL_ARMED_STAY: STATE_ALARM_ARMED_HOME,
|
||||
ANCILLARY_CONTROL_DISARMED: STATE_ALARM_DISARMED,
|
||||
SUPPORTED_DECONZ_ALARM_EVENTS = {
|
||||
ANCILLARY_CONTROL_EMERGENCY,
|
||||
ANCILLARY_CONTROL_FIRE,
|
||||
ANCILLARY_CONTROL_INVALID_CODE,
|
||||
ANCILLARY_CONTROL_PANIC,
|
||||
}
|
||||
|
||||
|
||||
|
@ -155,31 +150,23 @@ class DeconzEvent(DeconzBase):
|
|||
|
||||
|
||||
class DeconzAlarmEvent(DeconzEvent):
|
||||
"""Alarm control panel companion event when user inputs a code."""
|
||||
"""Alarm control panel companion event when user interacts with a keypad."""
|
||||
|
||||
@callback
|
||||
def async_update_callback(self, force_update=False):
|
||||
"""Fire the event if reason is that state is updated."""
|
||||
"""Fire the event if reason is new action is updated."""
|
||||
if (
|
||||
self.gateway.ignore_state_updates
|
||||
or "action" not in self._device.changed_keys
|
||||
or self._device.action not in SUPPORTED_DECONZ_ALARM_EVENTS
|
||||
):
|
||||
return
|
||||
|
||||
try:
|
||||
state, code, _area = self._device.action.split(",")
|
||||
except (AttributeError, ValueError):
|
||||
return
|
||||
|
||||
if state not in DECONZ_TO_ALARM_STATE:
|
||||
return
|
||||
|
||||
data = {
|
||||
CONF_ID: self.event_id,
|
||||
CONF_UNIQUE_ID: self.serial,
|
||||
CONF_DEVICE_ID: self.device_id,
|
||||
CONF_EVENT: DECONZ_TO_ALARM_STATE[state],
|
||||
CONF_CODE: code,
|
||||
CONF_EVENT: self._device.action,
|
||||
}
|
||||
|
||||
self.gateway.hass.bus.async_fire(CONF_DECONZ_ALARM_EVENT, data)
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
"config_flow": true,
|
||||
"documentation": "https://www.home-assistant.io/integrations/deconz",
|
||||
"requirements": [
|
||||
"pydeconz==82"
|
||||
"pydeconz==83"
|
||||
],
|
||||
"ssdp": [
|
||||
{
|
||||
|
|
|
@ -63,25 +63,3 @@ remove_orphaned_entries:
|
|||
example: "00212EFFFF012345"
|
||||
selector:
|
||||
text:
|
||||
|
||||
alarm_panel_state:
|
||||
name: Alarm panel state
|
||||
description: Put keypad panel in an intermediate state, to help with visual and audible cues to the user.
|
||||
target:
|
||||
entity:
|
||||
integration: deconz
|
||||
domain: alarm_control_panel
|
||||
fields:
|
||||
panel_state:
|
||||
name: Panel state
|
||||
description: >-
|
||||
- "entry_delay": make panel beep until panel is disarmed. Beep interval is long.
|
||||
- "exit_delay": make panel beep until panel is set to armed state. Beep interval is short.
|
||||
- "not_ready_to_arm": turn on yellow status led on the panel. Indicate not all conditions for arming are met.
|
||||
required: true
|
||||
selector:
|
||||
select:
|
||||
options:
|
||||
- "entry_delay"
|
||||
- "exit_delay"
|
||||
- "not_ready_to_arm"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue