-
-
Notifications
You must be signed in to change notification settings - Fork 32.3k
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
arlo: Add alarm control panel component #9711
Changes from all commits
2c00a52
abbf8e3
028f507
d3566e6
bef6685
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
""" | ||
This component provides HA alarm_control_panel support for Arlo. | ||
|
||
For more details about this platform, please refer to the documentation at | ||
https://home-assistant.io/components/alarm_control_panel.arlo/ | ||
""" | ||
import asyncio | ||
import logging | ||
import voluptuous as vol | ||
|
||
from homeassistant.components.arlo import (DATA_ARLO, CONF_ATTRIBUTION) | ||
from homeassistant.components.alarm_control_panel import (AlarmControlPanel, | ||
PLATFORM_SCHEMA) | ||
from homeassistant.const import (ATTR_ATTRIBUTION, STATE_ALARM_ARMED_AWAY, | ||
STATE_ALARM_ARMED_HOME, STATE_ALARM_DISARMED) | ||
from homeassistant.helpers import config_validation as cv | ||
|
||
DEPENDENCIES = ['arlo'] | ||
|
||
_LOGGER = logging.getLogger(__name__) | ||
|
||
CONF_HOME_MODE_NAME = 'home_mode_name' | ||
ICON = 'mdi:security' | ||
ARMED = "armed" | ||
DISARMED = "disarmed" | ||
|
||
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ | ||
vol.Optional(CONF_HOME_MODE_NAME, default=ARMED): cv.string, | ||
}) | ||
|
||
|
||
@asyncio.coroutine | ||
def async_setup_platform(hass, config, async_add_devices, discovery_info=None): | ||
"""Set up Arlo Base Stations.""" | ||
data = hass.data[DATA_ARLO] | ||
|
||
if not data.base_stations: | ||
return | ||
|
||
home_mode_name = config.get(CONF_HOME_MODE_NAME) | ||
base_stations = [] | ||
for base_station in data.base_stations: | ||
base_stations.append(ArloBaseStation(base_station, home_mode_name)) | ||
async_add_devices(base_stations, True) | ||
|
||
|
||
class ArloBaseStation(AlarmControlPanel): | ||
"""An AlarmControlPanel implementation for Arlo.""" | ||
|
||
def __init__(self, data, home_mode_name): | ||
"""Initialize the alarm control panel.""" | ||
self._base_station = data | ||
self._home_mode_name = home_mode_name | ||
self._state = None | ||
|
||
@property | ||
def icon(self): | ||
"""Return icon.""" | ||
return ICON | ||
|
||
@property | ||
def state(self): | ||
"""Return the state of the device.""" | ||
return self._state | ||
|
||
@asyncio.coroutine | ||
def async_update(self): | ||
"""Update the state of the device.""" | ||
# PyArlo sometimes returns None for mode. So retry 3 times before | ||
# returning None. | ||
num_retries = 3 | ||
i = 0 | ||
while i < num_retries: | ||
mode = self._base_station.mode | ||
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. Is I/O happening here? If so that should be moved to a 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. Thank you for pointing this out. Yes it does I/O. Have moved it to the async_update method. |
||
if mode: | ||
self._state = self._get_state_from_mode(mode) | ||
return | ||
i += 1 | ||
self._state = None | ||
|
||
@asyncio.coroutine | ||
def async_alarm_disarm(self, code=None): | ||
"""Send disarm command.""" | ||
self._base_station.mode = DISARMED | ||
|
||
@asyncio.coroutine | ||
def async_alarm_arm_away(self, code=None): | ||
"""Send arm away command.""" | ||
self._base_station.mode = ARMED | ||
|
||
@asyncio.coroutine | ||
def async_alarm_arm_home(self, code=None): | ||
"""Send arm home command. Uses custom mode.""" | ||
self._base_station.mode = self._home_mode_name | ||
|
||
@property | ||
def name(self): | ||
"""Return the name of the base station.""" | ||
return self._base_station.name | ||
|
||
@property | ||
def device_state_attributes(self): | ||
"""Return the state attributes.""" | ||
return { | ||
ATTR_ATTRIBUTION: CONF_ATTRIBUTION, | ||
'device_id': self._base_station.device_id | ||
} | ||
|
||
def _get_state_from_mode(self, mode): | ||
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. Docstring is missing. |
||
"""Convert Arlo mode to HA state.""" | ||
if mode == ARMED: | ||
return STATE_ALARM_ARMED_AWAY | ||
elif mode == DISARMED: | ||
return STATE_ALARM_DISARMED | ||
elif mode == self._home_mode_name: | ||
return STATE_ALARM_ARMED_HOME | ||
return None |
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.
Is this configurable on the Arlo device? Is that why this should be configurable here?
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.
Arlo base station only has two modes by default. Armed and Disarmed. But users can create custom modes on the arlo app. Since HA alarm panel component has the notion of 'home' mode, this configuration just let's them map one of their 'custom' modes as 'home' mode. If they don't have one, then home and away modes are the same (and the status will always say armed_away).
Sorry if i wasn't clear in the description. :)