-
-
Notifications
You must be signed in to change notification settings - Fork 37.5k
Add alarm control panel support to ZHA #49080
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Adminiuga
merged 25 commits into
home-assistant:dev
from
dmulcahey:dm/zha-ias-ace-support
Apr 27, 2021
Merged
Changes from all commits
Commits
Show all changes
25 commits
Select commit
Hold shift + click to select a range
0e8d7ea
start implementation of IAS ACE
dmulcahey 44109fc
starting alarm control panel
dmulcahey 8f23561
enums
dmulcahey 0016242
use new enums from zigpy
dmulcahey e9cb11c
fix import
dmulcahey f8fd3b6
write state
dmulcahey 6a3eb45
fix registries after rebase
dmulcahey b76d00d
remove extra line
dmulcahey 77f9c70
cleanup
dmulcahey bfe97ff
fix deprecation warning
dmulcahey 5447b76
updates to catch up with codebase evolution
dmulcahey 6d03c42
minor updates
dmulcahey 3cf241f
cleanup
dmulcahey 547b22c
implement more ias ace functionality
dmulcahey a0fd5d8
cleanup
dmulcahey 687adc7
make config helper work for supplied section
dmulcahey ae7deb4
connect to configuration
dmulcahey df78920
use ha async_create_task
dmulcahey 83bac1e
add some tests
dmulcahey 85f8510
remove unused restore method
dmulcahey ef77ddc
update tests
dmulcahey e370adc
add tests from panel POV
dmulcahey dd414c6
dynamically include alarm control panel config
dmulcahey b36f668
fix import
dmulcahey d6ba89a
Merge branch 'dev' into dm/zha-ias-ace-support
Adminiuga File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,174 @@ | ||
| """Alarm control panels on Zigbee Home Automation networks.""" | ||
| import functools | ||
| import logging | ||
|
|
||
| from zigpy.zcl.clusters.security import IasAce | ||
|
|
||
| from homeassistant.components.alarm_control_panel import ( | ||
| ATTR_CHANGED_BY, | ||
| ATTR_CODE_ARM_REQUIRED, | ||
| ATTR_CODE_FORMAT, | ||
| DOMAIN, | ||
| FORMAT_TEXT, | ||
| SUPPORT_ALARM_ARM_AWAY, | ||
| SUPPORT_ALARM_ARM_HOME, | ||
| SUPPORT_ALARM_ARM_NIGHT, | ||
| SUPPORT_ALARM_TRIGGER, | ||
| AlarmControlPanelEntity, | ||
| ) | ||
| from homeassistant.components.zha.core.typing import ZhaDeviceType | ||
| from homeassistant.const import ( | ||
| STATE_ALARM_ARMED_AWAY, | ||
| STATE_ALARM_ARMED_HOME, | ||
| STATE_ALARM_ARMED_NIGHT, | ||
| STATE_ALARM_DISARMED, | ||
| STATE_ALARM_TRIGGERED, | ||
| ) | ||
| from homeassistant.core import callback | ||
| from homeassistant.helpers.dispatcher import async_dispatcher_connect | ||
|
|
||
| from .core import discovery | ||
| from .core.channels.security import ( | ||
| SIGNAL_ALARM_TRIGGERED, | ||
| SIGNAL_ARMED_STATE_CHANGED, | ||
| IasAce as AceChannel, | ||
| ) | ||
| from .core.const import ( | ||
| CHANNEL_IAS_ACE, | ||
| CONF_ALARM_ARM_REQUIRES_CODE, | ||
| CONF_ALARM_FAILED_TRIES, | ||
| CONF_ALARM_MASTER_CODE, | ||
| DATA_ZHA, | ||
| DATA_ZHA_DISPATCHERS, | ||
| SIGNAL_ADD_ENTITIES, | ||
| ZHA_ALARM_OPTIONS, | ||
| ) | ||
| from .core.helpers import async_get_zha_config_value | ||
| from .core.registries import ZHA_ENTITIES | ||
| from .entity import ZhaEntity | ||
|
|
||
| _LOGGER = logging.getLogger(__name__) | ||
|
|
||
|
|
||
| STRICT_MATCH = functools.partial(ZHA_ENTITIES.strict_match, DOMAIN) | ||
|
|
||
| IAS_ACE_STATE_MAP = { | ||
| IasAce.PanelStatus.Panel_Disarmed: STATE_ALARM_DISARMED, | ||
| IasAce.PanelStatus.Armed_Stay: STATE_ALARM_ARMED_HOME, | ||
| IasAce.PanelStatus.Armed_Night: STATE_ALARM_ARMED_NIGHT, | ||
| IasAce.PanelStatus.Armed_Away: STATE_ALARM_ARMED_AWAY, | ||
| IasAce.PanelStatus.In_Alarm: STATE_ALARM_TRIGGERED, | ||
| } | ||
|
|
||
|
|
||
| async def async_setup_entry(hass, config_entry, async_add_entities): | ||
| """Set up the Zigbee Home Automation alarm control panel from config entry.""" | ||
| entities_to_create = hass.data[DATA_ZHA][DOMAIN] | ||
|
|
||
| unsub = async_dispatcher_connect( | ||
| hass, | ||
| SIGNAL_ADD_ENTITIES, | ||
| functools.partial( | ||
| discovery.async_add_entities, async_add_entities, entities_to_create | ||
| ), | ||
| ) | ||
| hass.data[DATA_ZHA][DATA_ZHA_DISPATCHERS].append(unsub) | ||
|
|
||
|
|
||
| @STRICT_MATCH(channel_names=CHANNEL_IAS_ACE) | ||
| class ZHAAlarmControlPanel(ZhaEntity, AlarmControlPanelEntity): | ||
| """Entity for ZHA alarm control devices.""" | ||
|
|
||
| def __init__(self, unique_id, zha_device: ZhaDeviceType, channels, **kwargs): | ||
| """Initialize the ZHA alarm control device.""" | ||
| super().__init__(unique_id, zha_device, channels, **kwargs) | ||
| cfg_entry = zha_device.gateway.config_entry | ||
| self._channel: AceChannel = channels[0] | ||
| self._channel.panel_code = async_get_zha_config_value( | ||
| cfg_entry, ZHA_ALARM_OPTIONS, CONF_ALARM_MASTER_CODE, "1234" | ||
| ) | ||
| self._channel.code_required_arm_actions = async_get_zha_config_value( | ||
| cfg_entry, ZHA_ALARM_OPTIONS, CONF_ALARM_ARM_REQUIRES_CODE, False | ||
| ) | ||
| self._channel.max_invalid_tries = async_get_zha_config_value( | ||
| cfg_entry, ZHA_ALARM_OPTIONS, CONF_ALARM_FAILED_TRIES, 3 | ||
| ) | ||
|
|
||
| async def async_added_to_hass(self): | ||
| """Run when about to be added to hass.""" | ||
| await super().async_added_to_hass() | ||
| self.async_accept_signal( | ||
| self._channel, SIGNAL_ARMED_STATE_CHANGED, self.async_set_armed_mode | ||
| ) | ||
| self.async_accept_signal( | ||
| self._channel, SIGNAL_ALARM_TRIGGERED, self.async_alarm_trigger | ||
| ) | ||
|
|
||
| @callback | ||
| def async_set_armed_mode(self) -> None: | ||
| """Set the entity state.""" | ||
| self.async_write_ha_state() | ||
|
|
||
| @property | ||
| def code_format(self): | ||
| """Regex for code format or None if no code is required.""" | ||
| return FORMAT_TEXT | ||
|
|
||
| @property | ||
| def changed_by(self): | ||
| """Last change triggered by.""" | ||
| return None | ||
|
|
||
| @property | ||
| def code_arm_required(self): | ||
| """Whether the code is required for arm actions.""" | ||
| return self._channel.code_required_arm_actions | ||
|
|
||
| async def async_alarm_disarm(self, code=None): | ||
| """Send disarm command.""" | ||
| self._channel.arm(IasAce.ArmMode.Disarm, code, 0) | ||
| self.async_write_ha_state() | ||
|
|
||
| async def async_alarm_arm_home(self, code=None): | ||
| """Send arm home command.""" | ||
| self._channel.arm(IasAce.ArmMode.Arm_Day_Home_Only, code, 0) | ||
| self.async_write_ha_state() | ||
|
|
||
| async def async_alarm_arm_away(self, code=None): | ||
| """Send arm away command.""" | ||
| self._channel.arm(IasAce.ArmMode.Arm_All_Zones, code, 0) | ||
| self.async_write_ha_state() | ||
|
|
||
| async def async_alarm_arm_night(self, code=None): | ||
| """Send arm night command.""" | ||
| self._channel.arm(IasAce.ArmMode.Arm_Night_Sleep_Only, code, 0) | ||
| self.async_write_ha_state() | ||
|
|
||
| async def async_alarm_trigger(self, code=None): | ||
| """Send alarm trigger command.""" | ||
| self.async_write_ha_state() | ||
|
|
||
| @property | ||
| def supported_features(self) -> int: | ||
| """Return the list of supported features.""" | ||
| return ( | ||
| SUPPORT_ALARM_ARM_HOME | ||
| | SUPPORT_ALARM_ARM_AWAY | ||
| | SUPPORT_ALARM_ARM_NIGHT | ||
| | SUPPORT_ALARM_TRIGGER | ||
| ) | ||
|
|
||
| @property | ||
| def state(self): | ||
| """Return the state of the entity.""" | ||
| return IAS_ACE_STATE_MAP.get(self._channel.armed_state) | ||
|
|
||
| @property | ||
| def state_attributes(self): | ||
| """Return the state attributes.""" | ||
| state_attr = { | ||
| ATTR_CODE_FORMAT: self.code_format, | ||
| ATTR_CHANGED_BY: self.changed_by, | ||
| ATTR_CODE_ARM_REQUIRED: self.code_arm_required, | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These attributes are already handled by the base alarm control panel entity class. It's enough to implement the corresponding properties. |
||
| } | ||
| return state_attr | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be
extra_state_attributes.