From 142313aa8feec9663b025934b3092b87e77cd557 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Beamonte?= Date: Sat, 18 Feb 2023 23:08:34 -0500 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20[feature]=20Add=20support=20for=20`?= =?UTF-8?q?KeyFob`=20sensors?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/qolsysgw/mqtt/updater.py | 2 ++ apps/qolsysgw/qolsys/sensors.py | 6 ++++ tests/end-to-end/test_qolsysgw.py | 28 ++++++++++++++++++- tests/integration/test_qolsys_events.py | 25 ++++++++++++++++- tests/mock_modules/testutils/fixtures_data.py | 13 +++++++++ 5 files changed, 72 insertions(+), 2 deletions(-) diff --git a/apps/qolsysgw/mqtt/updater.py b/apps/qolsysgw/mqtt/updater.py index 2270ed5..2b4fe13 100644 --- a/apps/qolsysgw/mqtt/updater.py +++ b/apps/qolsysgw/mqtt/updater.py @@ -16,6 +16,7 @@ from qolsys.sensors import QolsysSensorFreeze from qolsys.sensors import QolsysSensorGlassBreak from qolsys.sensors import QolsysSensorHeat +from qolsys.sensors import QolsysSensorKeyFob from qolsys.sensors import QolsysSensorKeypad from qolsys.sensors import QolsysSensorMotion from qolsys.sensors import QolsysSensorSiren @@ -442,6 +443,7 @@ class MqttWrapperQolsysSensor(MqttWrapper): QolsysSensorKeypad: 'safety', QolsysSensorAuxiliaryPendant: 'safety', QolsysSensorSiren: 'safety', + QolsysSensorKeyFob: 'safety', } def __init__(self, sensor: QolsysSensor, *args, **kwargs): diff --git a/apps/qolsysgw/qolsys/sensors.py b/apps/qolsysgw/qolsys/sensors.py index 366e19b..f23fdb1 100644 --- a/apps/qolsysgw/qolsys/sensors.py +++ b/apps/qolsysgw/qolsys/sensors.py @@ -320,3 +320,9 @@ class QolsysSensorSiren(QolsysSensor, _QolsysSensorWithoutUpdates): @classmethod def from_json(cls, data, common=None): return cls.from_json_subclass('Siren', data, common) + + +class QolsysSensorKeyFob(QolsysSensor, _QolsysSensorWithoutUpdates): + @classmethod + def from_json(cls, data, common=None): + return cls.from_json_subclass('KeyFob', data, common) diff --git a/tests/end-to-end/test_qolsysgw.py b/tests/end-to-end/test_qolsysgw.py index f632746..edcd7eb 100644 --- a/tests/end-to-end/test_qolsysgw.py +++ b/tests/end-to-end/test_qolsysgw.py @@ -464,6 +464,19 @@ async def _check_initial_state(self, ctx): 'entity_id': 'binary_sensor.my_siren_sensor', 'state': 'off', }, + { + 'attributes': { + 'device_class': 'safety', + 'friendly_name': 'My KeyFob Sensor', + 'group': 'mobileintrusion', + 'zone_alarm_type': 0, + 'zone_physical_type': 3, + 'zone_type': 102, + 'tampered': False, + }, + 'entity_id': 'binary_sensor.my_keyfob_sensor', + 'state': 'off', + }, ] self._check_entity_states(ctx, expected_states, msg='Initial state') @@ -485,7 +498,7 @@ async def _check_panel_events(self, ctx): ] closed_entities = [100, 110, 111, 120, 121, 130, 140, 141, 150, - 200, 210, 220, 230, 240, 250, 260] + 200, 210, 220, 230, 240, 250, 260, 270] open_entities = [101] tamper_entities = [100, 110, 111, 210] untamper_entities_to_open = [100] @@ -831,6 +844,19 @@ def zone_active_event(zone_id, closed=False): 'entity_id': 'binary_sensor.my_siren_sensor', 'state': 'on', }, + { + 'attributes': { + 'device_class': 'safety', + 'friendly_name': 'My KeyFob Sensor', + 'group': 'mobileintrusion', + 'zone_alarm_type': 0, + 'zone_physical_type': 3, + 'zone_type': 102, + 'tampered': False, + }, + 'entity_id': 'binary_sensor.my_keyfob_sensor', + 'state': 'on', + }, ] self._check_entity_states(ctx, expected_states, msg='Panel events') diff --git a/tests/integration/test_qolsys_events.py b/tests/integration/test_qolsys_events.py index 875926d..866c7e6 100644 --- a/tests/integration/test_qolsys_events.py +++ b/tests/integration/test_qolsys_events.py @@ -15,6 +15,7 @@ from qolsys.sensors import QolsysSensorFreeze from qolsys.sensors import QolsysSensorGlassBreak from qolsys.sensors import QolsysSensorHeat +from qolsys.sensors import QolsysSensorKeyFob from qolsys.sensors import QolsysSensorKeypad from qolsys.sensors import QolsysSensorMotion from qolsys.sensors import QolsysSensorPanelGlassBreak @@ -256,7 +257,7 @@ async def test_integration_event_info_summary_initializes_all_entities(self): with self.subTest(msg='Partition 1 is properly configured'): partition1 = state.partition(1) - self.assertEqual(7, len(partition1.sensors)) + self.assertEqual(8, len(partition1.sensors)) self.assertEqual(1, partition1.id) self.assertEqual('partition1', partition1.name) self.assertEqual('DISARM', partition1.status) @@ -645,6 +646,28 @@ async def test_integration_event_info_summary_initializes_all_entities(self): expected_enabled_by_default=False, ) + with self.subTest(msg='Sensor 270 is properly configured'): + sensor270 = partition1.zone(270) + self.assertEqual(QolsysSensorKeyFob, sensor270.__class__) + self.assertEqual('002-0070', sensor270.id) + self.assertEqual('My KeyFob Sensor', sensor270.name) + self.assertEqual('mobileintrusion', sensor270.group) + self.assertEqual('Closed', sensor270.status) + self.assertEqual('0', sensor270.state) + self.assertEqual(270, sensor270.zone_id) + self.assertEqual(3, sensor270.zone_physical_type) + self.assertEqual(0, sensor270.zone_alarm_type) + self.assertEqual(102, sensor270.zone_type) + self.assertEqual(1, sensor270.partition_id) + + await self._check_sensor_mqtt_messages( + gw=gw, + sensor_flat_name='my_keyfob_sensor', + sensor_state=sensor270, + expected_device_class='safety', + expected_enabled_by_default=False, + ) + async def _test_integration_event_info_secure_arm(self, from_secure_arm, to_secure_arm): panel, gw, _, _ = await self._ready_panel_and_gw( diff --git a/tests/mock_modules/testutils/fixtures_data.py b/tests/mock_modules/testutils/fixtures_data.py index 65d5eee..bb9ef88 100644 --- a/tests/mock_modules/testutils/fixtures_data.py +++ b/tests/mock_modules/testutils/fixtures_data.py @@ -245,6 +245,19 @@ def get_summary(secure_arm=False, partition_ids=None, 'zone_type': 14, 'partition_id': 1, }, + { + 'id': '002-0070', + 'type': 'KeyFob', + 'name': 'My KeyFob Sensor', + 'group': 'mobileintrusion', + 'status': 'Closed', + 'state': '0', + 'zone_id': 270, + 'zone_physical_type': 3, + 'zone_alarm_type': 0, + 'zone_type': 102, + 'partition_id': 1, + }, ], }, ],