Skip to content

Commit

Permalink
feat(experimental): add managed sectors to control only part of avail…
Browse files Browse the repository at this point in the history
…able areas (#146)
  • Loading branch information
palazzem authored Feb 17, 2024
1 parent 4ad727e commit 52e1d74
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 1 deletion.
9 changes: 8 additions & 1 deletion custom_components/econnect_metronet/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
from . import services
from .const import (
CONF_DOMAIN,
CONF_EXPERIMENTAL,
CONF_SCAN_INTERVAL,
CONF_SYSTEM_URL,
DOMAIN,
Expand Down Expand Up @@ -102,9 +103,15 @@ async def async_setup_entry(hass: HomeAssistant, config: ConfigEntry) -> bool:
Raises:
Any exceptions raised by the coordinator or the setup process will be propagated up to the caller.
"""
# Enable experimental settings from the configuration file
# NOTE: While it's discouraged to use YAML configurations for integrations, this approach
# ensures that we can experiment with new settings we can break without notice.
experimental = hass.data[DOMAIN].get(CONF_EXPERIMENTAL, {})

# Initialize Components
scan_interval = config.options.get(CONF_SCAN_INTERVAL, SCAN_INTERVAL_DEFAULT)
client = ElmoClient(config.data[CONF_SYSTEM_URL], config.data[CONF_DOMAIN])
device = AlarmDevice(client, config.options)
device = AlarmDevice(client, {**config.options, **experimental})
coordinator = AlarmCoordinator(hass, device, scan_interval)
await coordinator.async_config_entry_first_refresh()

Expand Down
1 change: 1 addition & 0 deletions custom_components/econnect_metronet/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
CONF_AREAS_ARM_NIGHT = "areas_arm_night"
CONF_AREAS_ARM_VACATION = "areas_arm_vacation"
CONF_SCAN_INTERVAL = "scan_interval"
CONF_MANAGE_SECTORS = "managed_sectors"
DEVICE_CLASS_SECTORS = "sector"
DOMAIN = "econnect_metronet"
NOTIFICATION_MESSAGE = (
Expand Down
11 changes: 11 additions & 0 deletions custom_components/econnect_metronet/devices.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
CONF_AREAS_ARM_HOME,
CONF_AREAS_ARM_NIGHT,
CONF_AREAS_ARM_VACATION,
CONF_MANAGE_SECTORS,
NOTIFICATION_MESSAGE,
)
from .helpers import split_code
Expand Down Expand Up @@ -60,6 +61,7 @@ def __init__(self, connection, config=None):

# Load user configuration
config = config or {}
self._managed_sectors = config.get(CONF_MANAGE_SECTORS) or []
self._sectors_away = config.get(CONF_AREAS_ARM_AWAY) or []
self._sectors_home = config.get(CONF_AREAS_ARM_HOME) or []
self._sectors_night = config.get(CONF_AREAS_ARM_NIGHT) or []
Expand Down Expand Up @@ -291,6 +293,15 @@ def update(self):
self._last_ids[q.ALERTS] = alerts.get("last_id", 0)
self._last_ids[q.PANEL] = panel.get("last_id", 0)

# Filter out the sectors that are not managed
# NOTE: this change is internal and not exposed to users as the feature is experimental. Further
# development requires that users can register multiple devices and alarm panels to control
# sectors in a more granular way. See: https://github.com/palazzem/ha-econnect-alarm/issues/95
if self._managed_sectors:
self._inventory[q.SECTORS] = {
k: v for k, v in self._inventory[q.SECTORS].items() if v["element"] in self._managed_sectors
}

# Update the internal state machine (mapping state)
self.state = self.get_state()

Expand Down
17 changes: 17 additions & 0 deletions tests/test_devices.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
CONF_AREAS_ARM_HOME,
CONF_AREAS_ARM_NIGHT,
CONF_AREAS_ARM_VACATION,
CONF_MANAGE_SECTORS,
)
from custom_components.econnect_metronet.devices import AlarmDevice

Expand All @@ -30,6 +31,7 @@ def test_device_constructor(client):
assert device._inventory == {}
assert device._sectors == {}
assert device._last_ids == {10: 0, 9: 0, 11: 0, 12: 0}
assert device._managed_sectors == []
assert device._sectors_away == []
assert device._sectors_home == []
assert device._sectors_night == []
Expand All @@ -44,13 +46,15 @@ def test_device_constructor_with_config(client):
CONF_AREAS_ARM_HOME: [3, 4],
CONF_AREAS_ARM_NIGHT: [1, 2, 3],
CONF_AREAS_ARM_VACATION: [5, 3],
CONF_MANAGE_SECTORS: [1, 2, 3, 4, 5],
}
device = AlarmDevice(client, config=config)
# Test
assert device._connection == client
assert device._inventory == {}
assert device._sectors == {}
assert device._last_ids == {10: 0, 9: 0, 11: 0, 12: 0}
assert device._managed_sectors == [1, 2, 3, 4, 5]
assert device._sectors_away == [1, 2, 3, 4, 5]
assert device._sectors_home == [3, 4]
assert device._sectors_night == [1, 2, 3]
Expand All @@ -65,13 +69,15 @@ def test_device_constructor_with_config_empty(client):
CONF_AREAS_ARM_HOME: None,
CONF_AREAS_ARM_NIGHT: None,
CONF_AREAS_ARM_VACATION: None,
CONF_MANAGE_SECTORS: None,
}
device = AlarmDevice(client, config=config)
# Test
assert device._connection == client
assert device._inventory == {}
assert device._sectors == {}
assert device._last_ids == {10: 0, 9: 0, 11: 0, 12: 0}
assert device._managed_sectors == []
assert device._sectors_away == []
assert device._sectors_home == []
assert device._sectors_night == []
Expand Down Expand Up @@ -578,6 +584,17 @@ def test_device_inventory_update_success(client, mocker):
assert device._inventory == inventory


def test_device_inventory_update_managed_sectors(alarm_device):
# Ensure that only managed sectors are updated
alarm_device._managed_sectors = [2, 3]
# Test
alarm_device.update()
assert alarm_device._inventory[q.SECTORS] == {
1: {"element": 2, "activable": True, "id": 2, "index": 1, "name": "S2 Bedroom", "status": True},
2: {"element": 3, "activable": False, "id": 3, "index": 2, "name": "S3 Outdoor", "status": False},
}


class TestInputsView:
def test_property_populated(self, alarm_device):
"""Should check if the device property is correctly populated"""
Expand Down

0 comments on commit 52e1d74

Please sign in to comment.