mirror of
https://github.com/home-assistant/core.git
synced 2025-11-09 10:59:40 +00:00
* Added support for security system, switch and thermostat * Processing review * Only perform set call when the call didn't come from HomeKit * Added support for alarm_code * Take into account review remarks * Provide tests for HomeKit security systems, switches and thermostats * Support STATE_AUTO * Guard if state exists * Improve support for thermostat auto mode * Provide both high and low at the same time for home assistant * Set default values within accepted ranges * Added tests for auto mode * Fix thermostat test error * Use attributes.get instead of indexing for safety * Avoid hardcoded attributes in tests
93 lines
3.7 KiB
Python
93 lines
3.7 KiB
Python
"""Class to hold all alarm control panel accessories."""
|
|
import logging
|
|
|
|
from homeassistant.const import (
|
|
STATE_ALARM_ARMED_AWAY, STATE_ALARM_ARMED_HOME,
|
|
STATE_ALARM_ARMED_NIGHT, STATE_ALARM_DISARMED,
|
|
ATTR_ENTITY_ID, ATTR_CODE)
|
|
from homeassistant.helpers.event import async_track_state_change
|
|
|
|
from . import TYPES
|
|
from .accessories import HomeAccessory, add_preload_service
|
|
from .const import (
|
|
SERV_SECURITY_SYSTEM, CHAR_CURRENT_SECURITY_STATE,
|
|
CHAR_TARGET_SECURITY_STATE)
|
|
|
|
_LOGGER = logging.getLogger(__name__)
|
|
|
|
HASS_TO_HOMEKIT = {STATE_ALARM_DISARMED: 3, STATE_ALARM_ARMED_HOME: 0,
|
|
STATE_ALARM_ARMED_AWAY: 1, STATE_ALARM_ARMED_NIGHT: 2}
|
|
HOMEKIT_TO_HASS = {c: s for s, c in HASS_TO_HOMEKIT.items()}
|
|
STATE_TO_SERVICE = {STATE_ALARM_DISARMED: 'alarm_disarm',
|
|
STATE_ALARM_ARMED_HOME: 'alarm_arm_home',
|
|
STATE_ALARM_ARMED_AWAY: 'alarm_arm_away',
|
|
STATE_ALARM_ARMED_NIGHT: 'alarm_arm_night'}
|
|
|
|
|
|
@TYPES.register('SecuritySystem')
|
|
class SecuritySystem(HomeAccessory):
|
|
"""Generate an SecuritySystem accessory for an alarm control panel."""
|
|
|
|
def __init__(self, hass, entity_id, display_name, alarm_code=None):
|
|
"""Initialize a SecuritySystem accessory object."""
|
|
super().__init__(display_name, entity_id, 'ALARM_SYSTEM')
|
|
|
|
self._hass = hass
|
|
self._entity_id = entity_id
|
|
self._alarm_code = alarm_code
|
|
|
|
self.flag_target_state = False
|
|
|
|
self.service_alarm = add_preload_service(self, SERV_SECURITY_SYSTEM)
|
|
self.char_current_state = self.service_alarm. \
|
|
get_characteristic(CHAR_CURRENT_SECURITY_STATE)
|
|
self.char_current_state.value = 3
|
|
self.char_target_state = self.service_alarm. \
|
|
get_characteristic(CHAR_TARGET_SECURITY_STATE)
|
|
self.char_target_state.value = 3
|
|
|
|
self.char_target_state.setter_callback = self.set_security_state
|
|
|
|
def run(self):
|
|
"""Method called be object after driver is started."""
|
|
state = self._hass.states.get(self._entity_id)
|
|
self.update_security_state(new_state=state)
|
|
|
|
async_track_state_change(self._hass, self._entity_id,
|
|
self.update_security_state)
|
|
|
|
def set_security_state(self, value):
|
|
"""Move security state to value if call came from HomeKit."""
|
|
_LOGGER.debug("%s: Set security state to %d",
|
|
self._entity_id, value)
|
|
self.flag_target_state = True
|
|
hass_value = HOMEKIT_TO_HASS[value]
|
|
service = STATE_TO_SERVICE[hass_value]
|
|
|
|
params = {ATTR_ENTITY_ID: self._entity_id}
|
|
if self._alarm_code is not None:
|
|
params[ATTR_CODE] = self._alarm_code
|
|
self._hass.services.call('alarm_control_panel', service, params)
|
|
|
|
def update_security_state(self, entity_id=None,
|
|
old_state=None, new_state=None):
|
|
"""Update security state after state changed."""
|
|
if new_state is None:
|
|
return
|
|
|
|
hass_state = new_state.state
|
|
if hass_state not in HASS_TO_HOMEKIT:
|
|
return
|
|
current_security_state = HASS_TO_HOMEKIT[hass_state]
|
|
self.char_current_state.set_value(current_security_state)
|
|
_LOGGER.debug("%s: Updated current state to %s (%d)",
|
|
self._entity_id, hass_state,
|
|
current_security_state)
|
|
|
|
if not self.flag_target_state:
|
|
self.char_target_state.set_value(current_security_state,
|
|
should_callback=False)
|
|
elif self.char_target_state.get_value() \
|
|
== self.char_current_state.get_value():
|
|
self.flag_target_state = False
|