home-assistant/homeassistant/components/alarm_control_panel/__init__.py
Ville Skyttä 99c7608fb4 Lint config cleanups (#28864)
* Remove bunch of unneeded lint exclusions

* Use symbolic names instead of identifiers in pylint disables

* Tighten scope of some pylint disables
2019-11-25 22:40:08 -08:00

201 lines
5.8 KiB
Python

"""Component to interface with an alarm control panel."""
from abc import abstractmethod
from datetime import timedelta
import logging
import voluptuous as vol
from homeassistant.const import (
ATTR_CODE,
ATTR_CODE_FORMAT,
SERVICE_ALARM_ARM_AWAY,
SERVICE_ALARM_ARM_CUSTOM_BYPASS,
SERVICE_ALARM_ARM_HOME,
SERVICE_ALARM_ARM_NIGHT,
SERVICE_ALARM_DISARM,
SERVICE_ALARM_TRIGGER,
)
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.config_validation import ( # noqa: F401
ENTITY_SERVICE_SCHEMA,
PLATFORM_SCHEMA,
PLATFORM_SCHEMA_BASE,
)
from homeassistant.helpers.entity import Entity
from homeassistant.helpers.entity_component import EntityComponent
from .const import (
SUPPORT_ALARM_ARM_AWAY,
SUPPORT_ALARM_ARM_CUSTOM_BYPASS,
SUPPORT_ALARM_ARM_HOME,
SUPPORT_ALARM_ARM_NIGHT,
SUPPORT_ALARM_TRIGGER,
)
DOMAIN = "alarm_control_panel"
SCAN_INTERVAL = timedelta(seconds=30)
ATTR_CHANGED_BY = "changed_by"
FORMAT_TEXT = "text"
FORMAT_NUMBER = "number"
ATTR_CODE_ARM_REQUIRED = "code_arm_required"
ENTITY_ID_FORMAT = DOMAIN + ".{}"
ALARM_SERVICE_SCHEMA = ENTITY_SERVICE_SCHEMA.extend(
{vol.Optional(ATTR_CODE): cv.string}
)
async def async_setup(hass, config):
"""Track states and offer events for sensors."""
component = hass.data[DOMAIN] = EntityComponent(
logging.getLogger(__name__), DOMAIN, hass, SCAN_INTERVAL
)
await component.async_setup(config)
component.async_register_entity_service(
SERVICE_ALARM_DISARM, ALARM_SERVICE_SCHEMA, "async_alarm_disarm"
)
component.async_register_entity_service(
SERVICE_ALARM_ARM_HOME,
ALARM_SERVICE_SCHEMA,
"async_alarm_arm_home",
[SUPPORT_ALARM_ARM_HOME],
)
component.async_register_entity_service(
SERVICE_ALARM_ARM_AWAY,
ALARM_SERVICE_SCHEMA,
"async_alarm_arm_away",
[SUPPORT_ALARM_ARM_AWAY],
)
component.async_register_entity_service(
SERVICE_ALARM_ARM_NIGHT,
ALARM_SERVICE_SCHEMA,
"async_alarm_arm_night",
[SUPPORT_ALARM_ARM_NIGHT],
)
component.async_register_entity_service(
SERVICE_ALARM_ARM_CUSTOM_BYPASS,
ALARM_SERVICE_SCHEMA,
"async_alarm_arm_custom_bypass",
[SUPPORT_ALARM_ARM_CUSTOM_BYPASS],
)
component.async_register_entity_service(
SERVICE_ALARM_TRIGGER,
ALARM_SERVICE_SCHEMA,
"async_alarm_trigger",
[SUPPORT_ALARM_TRIGGER],
)
return True
async def async_setup_entry(hass, entry):
"""Set up a config entry."""
return await hass.data[DOMAIN].async_setup_entry(entry)
async def async_unload_entry(hass, entry):
"""Unload a config entry."""
return await hass.data[DOMAIN].async_unload_entry(entry)
class AlarmControlPanel(Entity):
"""An abstract class for alarm control devices."""
@property
def code_format(self):
"""Regex for code format or None if no code is required."""
return None
@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 True
def alarm_disarm(self, code=None):
"""Send disarm command."""
raise NotImplementedError()
def async_alarm_disarm(self, code=None):
"""Send disarm command.
This method must be run in the event loop and returns a coroutine.
"""
return self.hass.async_add_executor_job(self.alarm_disarm, code)
def alarm_arm_home(self, code=None):
"""Send arm home command."""
raise NotImplementedError()
def async_alarm_arm_home(self, code=None):
"""Send arm home command.
This method must be run in the event loop and returns a coroutine.
"""
return self.hass.async_add_executor_job(self.alarm_arm_home, code)
def alarm_arm_away(self, code=None):
"""Send arm away command."""
raise NotImplementedError()
def async_alarm_arm_away(self, code=None):
"""Send arm away command.
This method must be run in the event loop and returns a coroutine.
"""
return self.hass.async_add_executor_job(self.alarm_arm_away, code)
def alarm_arm_night(self, code=None):
"""Send arm night command."""
raise NotImplementedError()
def async_alarm_arm_night(self, code=None):
"""Send arm night command.
This method must be run in the event loop and returns a coroutine.
"""
return self.hass.async_add_executor_job(self.alarm_arm_night, code)
def alarm_trigger(self, code=None):
"""Send alarm trigger command."""
raise NotImplementedError()
def async_alarm_trigger(self, code=None):
"""Send alarm trigger command.
This method must be run in the event loop and returns a coroutine.
"""
return self.hass.async_add_executor_job(self.alarm_trigger, code)
def alarm_arm_custom_bypass(self, code=None):
"""Send arm custom bypass command."""
raise NotImplementedError()
def async_alarm_arm_custom_bypass(self, code=None):
"""Send arm custom bypass command.
This method must be run in the event loop and returns a coroutine.
"""
return self.hass.async_add_executor_job(self.alarm_arm_custom_bypass, code)
@property
@abstractmethod
def supported_features(self) -> int:
"""Return the list of supported features."""
@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,
}
return state_attr