Skip to content

Commit

Permalink
Merge pull request #20 from hostcc/feature/doorbell-support
Browse files Browse the repository at this point in the history
Doorbell support
  • Loading branch information
hostcc authored Jun 21, 2022
2 parents 8af1373 + 99ae9a5 commit 095e460
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 13 deletions.
8 changes: 8 additions & 0 deletions src/pyg90alarm/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,14 @@ class G90AlertTypes(IntEnum):
DOOR_OPEN_CLOSE = 4


class G90AlertSources(IntEnum):
"""
Defines possible sources of the alert sent by the panel.
"""
SENSOR = 1
DOORBELL = 12


class G90AlertStateChangeTypes(IntEnum):
"""
Defines types of alert for device state changes.
Expand Down
9 changes: 5 additions & 4 deletions src/pyg90alarm/device_notifications.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
G90AlertTypes,
G90AlertStateChangeTypes,
G90ArmDisarmTypes,
G90AlertSources,
)

_LOGGER = logging.getLogger(__name__)
Expand Down Expand Up @@ -75,7 +76,7 @@ class G90ArmDisarmInfo(namedtuple('G90ArmDisarmInfo',


class G90DeviceAlert(namedtuple('G90DeviceAlert',
['type', 'event_id', 'resv2', 'resv3',
['type', 'event_id', 'source', 'state',
'zone_name', 'device_id', 'unix_time',
'resv4', 'other'])):
"""
Expand Down Expand Up @@ -138,9 +139,9 @@ def _handle_notification(self, addr, notification):

def _handle_alert(self, addr, alert):
if alert.type == G90AlertTypes.DOOR_OPEN_CLOSE:
# `.resv3` field indicates whether the door is opened (1) or closed
# (0)
is_open = alert.resv3 == 1
is_open = (
alert.source == G90AlertSources.SENSOR and alert.state == 1
) or alert.source == G90AlertSources.DOORBELL
_LOGGER.debug('Door open_close alert: %s', alert)
G90Callback.invoke(self._door_open_close_cb,
alert.event_id, alert.zone_name,
Expand Down
23 changes: 19 additions & 4 deletions tests/test_notifications.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,12 +109,12 @@ def sock_data_awaitable(*args):
'ERROR:pyg90alarm.device_notifications:'
'Bad alert received from mocked:12345:'
" <lambda>() missing 9 required positional arguments: 'type',"
" 'event_id', 'resv2', 'resv3', 'zone_name', 'device_id',"
" 'event_id', 'source', 'state', 'zone_name', 'device_id',"
" 'unix_time', 'resv4', and 'other'",
'ERROR:pyg90alarm.device_notifications:'
'Bad alert received from mocked:12345:'
" __new__() missing 9 required positional arguments: 'type',"
" 'event_id', 'resv2', 'resv3', 'zone_name', 'device_id',"
" 'event_id', 'source', 'state', 'zone_name', 'device_id',"
" 'unix_time', 'resv4', and 'other'",
])
notifications.close()
Expand Down Expand Up @@ -153,8 +153,8 @@ def sock_data_awaitable(*args):
self.assertEqual(cm.output, [
'WARNING:pyg90alarm.device_notifications:'
'Unknown alert received from mocked:12345: type 999,'
' data G90DeviceAlert(type=999, event_id=100, resv2=1,'
" resv3=1, zone_name='Hall', device_id='DUMMYGUID',"
' data G90DeviceAlert(type=999, event_id=100, source=1,'
" state=1, zone_name='Hall', device_id='DUMMYGUID',"
" unix_time=1631545189, resv4=0, other=[''])"
])
notifications.close()
Expand Down Expand Up @@ -216,3 +216,18 @@ async def test_door_open_close_callback(self):
await asyncio.wait([future], timeout=0.1)
notifications.close()
door_open_close_cb.assert_called_once_with(100, 'Hall', True)

async def test_doorbell_callback(self):
future = self.loop.create_future()
door_open_close_cb = MagicMock()
door_open_close_cb.side_effect = lambda *args: future.set_result(True)
notifications = G90DeviceNotifications(
door_open_close_cb=door_open_close_cb, sock=self.socket_mock)
await notifications.listen()
asynctest.set_read_ready(self.socket_mock, self.loop)
self.socket_mock.recvfrom.return_value = (
b'[208,[4,111,12,0,"Doorbell","DUMMYGUID",1655745021,0,[""]]]\0',
('mocked', 12345))
await asyncio.wait([future], timeout=0.1)
notifications.close()
door_open_close_cb.assert_called_once_with(111, 'Doorbell', True)
10 changes: 5 additions & 5 deletions tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@ isolated_build = true

[testenv]
deps =
check-manifest >= 0.42
flake8
asynctest
pylint
coverage
check-manifest == 0.48
flake8 == 4.0.1
asynctest == 0.13.0
pylint == 2.13.9 # Most recent for Python 3.6
coverage == 6.2 # Most recent for Python 3.6
setenv =
# Ensure the module under test will be found under `src/` directory, in
# case of any test command below will attempt importing it. In particular,
Expand Down

0 comments on commit 095e460

Please sign in to comment.