Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion homeassistant/components/alarm_control_panel/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ def alarm_arm_custom_bypass(hass, code=None, entity_id=None):
@asyncio.coroutine
def async_setup(hass, config):
"""Track states and offer events for sensors."""
component = EntityComponent(
component = hass.data[DOMAIN] = EntityComponent(
logging.getLogger(__name__), DOMAIN, hass, SCAN_INTERVAL)

yield from component.async_setup(config)
Expand Down Expand Up @@ -154,6 +154,17 @@ def async_alarm_service_handler(service):
return True


async def async_setup_entry(hass, entry):
"""Setup 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)


# pylint: disable=no-self-use
class AlarmControlPanel(Entity):
"""An abstract class for alarm control devices."""

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
"""
Support for HomematicIP alarm control panel.

For more details about this component, please refer to the documentation at
https://home-assistant.io/components/alarm_control_panel.homematicip_cloud/
"""

import logging

from homeassistant.const import (
STATE_ALARM_ARMED_AWAY, STATE_ALARM_ARMED_HOME, STATE_ALARM_DISARMED,
STATE_ALARM_TRIGGERED)
from homeassistant.components.alarm_control_panel import AlarmControlPanel
from homeassistant.components.homematicip_cloud import (
HomematicipGenericDevice, DOMAIN as HMIPC_DOMAIN,
HMIPC_HAPID)


DEPENDENCIES = ['homematicip_cloud']

_LOGGER = logging.getLogger(__name__)

HMIP_OPEN = 'OPEN'
HMIP_ZONE_AWAY = 'EXTERNAL'
HMIP_ZONE_HOME = 'INTERNAL'


async def async_setup_platform(hass, config, async_add_devices,
discovery_info=None):
"""Set up the HomematicIP alarm control devices."""
pass


async def async_setup_entry(hass, config_entry, async_add_devices):
"""Set up the HomematicIP alarm control panel from a config entry."""
from homematicip.aio.group import AsyncSecurityZoneGroup

home = hass.data[HMIPC_DOMAIN][config_entry.data[HMIPC_HAPID]].home
devices = []
for group in home.groups:
if isinstance(group, AsyncSecurityZoneGroup):
devices.append(HomematicipSecurityZone(home, group))

if devices:
async_add_devices(devices)


class HomematicipSecurityZone(HomematicipGenericDevice, AlarmControlPanel):
"""Representation of an HomematicIP security zone group."""

def __init__(self, home, device):
"""Initialize the security zone group."""
device.modelType = 'Group-SecurityZone'
device.windowState = ''
super().__init__(home, device)

@property
def state(self):
"""Return the state of the device."""
if self._device.active:
if (self._device.sabotage or self._device.motionDetected or
self._device.windowState == HMIP_OPEN):
return STATE_ALARM_TRIGGERED

if self._device.label == HMIP_ZONE_HOME:
return STATE_ALARM_ARMED_HOME
return STATE_ALARM_ARMED_AWAY

return STATE_ALARM_DISARMED

async def async_alarm_disarm(self, code=None):
"""Send disarm command."""
await self._home.set_security_zones_activation(False, False)

async def async_alarm_arm_home(self, code=None):
"""Send arm home command."""
await self._home.set_security_zones_activation(True, False)

async def async_alarm_arm_away(self, code=None):
"""Send arm away command."""
await self._home.set_security_zones_activation(True, True)

@property
def device_state_attributes(self):
"""Return the state attributes of the alarm control device."""
return None

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a code comment why we need to overwrite this property and return None. This would look weird not knowing about the parent class implementation.

1 change: 1 addition & 0 deletions homeassistant/components/homematicip_cloud/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
DOMAIN = 'homematicip_cloud'

COMPONENTS = [
'alarm_control_panel',
'binary_sensor',
'climate',
'light',
Expand Down
8 changes: 5 additions & 3 deletions tests/components/homematicip_cloud/test_hap.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,10 @@ async def test_hap_setup_works(aioclient_mock):
assert await hap.async_setup() is True

assert hap.home is home
assert len(hass.config_entries.async_forward_entry_setup.mock_calls) == 5
assert len(hass.config_entries.async_forward_entry_setup.mock_calls) == 6
assert hass.config_entries.async_forward_entry_setup.mock_calls[0][1] == \
(entry, 'alarm_control_panel')
assert hass.config_entries.async_forward_entry_setup.mock_calls[1][1] == \
(entry, 'binary_sensor')


Expand Down Expand Up @@ -104,10 +106,10 @@ async def test_hap_reset_unloads_entry_if_setup():

assert hap.home is home
assert len(hass.services.async_register.mock_calls) == 0
assert len(hass.config_entries.async_forward_entry_setup.mock_calls) == 5
assert len(hass.config_entries.async_forward_entry_setup.mock_calls) == 6

hass.config_entries.async_forward_entry_unload.return_value = \
mock_coro(True)
await hap.async_reset()

assert len(hass.config_entries.async_forward_entry_unload.mock_calls) == 5
assert len(hass.config_entries.async_forward_entry_unload.mock_calls) == 6