pyg90alarm 1.16.1__py3-none-any.whl → 1.17.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pyg90alarm/alarm.py +96 -1
- pyg90alarm/const.py +17 -0
- pyg90alarm/device_notifications.py +135 -34
- pyg90alarm/history.py +40 -16
- {pyg90alarm-1.16.1.dist-info → pyg90alarm-1.17.0.dist-info}/METADATA +1 -1
- {pyg90alarm-1.16.1.dist-info → pyg90alarm-1.17.0.dist-info}/RECORD +9 -9
- {pyg90alarm-1.16.1.dist-info → pyg90alarm-1.17.0.dist-info}/LICENSE +0 -0
- {pyg90alarm-1.16.1.dist-info → pyg90alarm-1.17.0.dist-info}/WHEEL +0 -0
- {pyg90alarm-1.16.1.dist-info → pyg90alarm-1.17.0.dist-info}/top_level.txt +0 -0
pyg90alarm/alarm.py
CHANGED
|
@@ -63,6 +63,7 @@ from .const import (
|
|
|
63
63
|
LOCAL_NOTIFICATIONS_HOST,
|
|
64
64
|
LOCAL_NOTIFICATIONS_PORT,
|
|
65
65
|
G90ArmDisarmTypes,
|
|
66
|
+
G90RemoteButtonStates,
|
|
66
67
|
)
|
|
67
68
|
from .base_cmd import (G90BaseCommand, G90BaseCommandData)
|
|
68
69
|
from .paginated_result import G90PaginatedResult, G90PaginatedResponse
|
|
@@ -109,8 +110,18 @@ if TYPE_CHECKING:
|
|
|
109
110
|
Callable[[G90ArmDisarmTypes], None],
|
|
110
111
|
Callable[[G90ArmDisarmTypes], Coroutine[None, None, None]]
|
|
111
112
|
]
|
|
113
|
+
SosCallback = Union[
|
|
114
|
+
Callable[[int, str, bool], None],
|
|
115
|
+
Callable[[int, str, bool], Coroutine[None, None, None]]
|
|
116
|
+
]
|
|
117
|
+
RemoteButtonPressCallback = Union[
|
|
118
|
+
Callable[[int, str, G90RemoteButtonStates], None],
|
|
119
|
+
Callable[
|
|
120
|
+
[int, str, G90RemoteButtonStates], Coroutine[None, None, None]
|
|
121
|
+
]
|
|
122
|
+
]
|
|
112
123
|
# Sensor-related callbacks for `G90Sensor` class - despite that class
|
|
113
|
-
# stores them, the
|
|
124
|
+
# stores them, the invocation is done by the `G90Alarm` class hence these
|
|
114
125
|
# are defined here
|
|
115
126
|
SensorStateCallback = Union[
|
|
116
127
|
Callable[[bool], None],
|
|
@@ -157,6 +168,10 @@ class G90Alarm(G90DeviceNotifications):
|
|
|
157
168
|
self._door_open_close_cb: Optional[DoorOpenCloseCallback] = None
|
|
158
169
|
self._alarm_cb: Optional[AlarmCallback] = None
|
|
159
170
|
self._low_battery_cb: Optional[LowBatteryCallback] = None
|
|
171
|
+
self._sos_cb: Optional[SosCallback] = None
|
|
172
|
+
self._remote_button_press_cb: Optional[
|
|
173
|
+
RemoteButtonPressCallback
|
|
174
|
+
] = None
|
|
160
175
|
self._reset_occupancy_interval = reset_occupancy_interval
|
|
161
176
|
self._alert_config: Optional[G90AlertConfigFlags] = None
|
|
162
177
|
self._sms_alert_when_armed = False
|
|
@@ -671,6 +686,86 @@ class G90Alarm(G90DeviceNotifications):
|
|
|
671
686
|
def low_battery_callback(self, value: LowBatteryCallback) -> None:
|
|
672
687
|
self._low_battery_cb = value
|
|
673
688
|
|
|
689
|
+
async def on_sos(
|
|
690
|
+
self, event_id: int, zone_name: str, is_host_sos: bool
|
|
691
|
+
) -> None:
|
|
692
|
+
"""
|
|
693
|
+
Invoked when SOS alert is triggered. Fires corresponding callback if
|
|
694
|
+
set by the user with :attr:`.sos_callback`.
|
|
695
|
+
|
|
696
|
+
Please note the method is for internal use by the class.
|
|
697
|
+
|
|
698
|
+
:param event_id: Index of the sensor triggered alarm
|
|
699
|
+
:param zone_name: Sensor name
|
|
700
|
+
:param is_host_sos:
|
|
701
|
+
Flag indicating if the SOS alert is triggered by the panel itself
|
|
702
|
+
(host)
|
|
703
|
+
"""
|
|
704
|
+
_LOGGER.debug('on_sos: %s %s %s', event_id, zone_name, is_host_sos)
|
|
705
|
+
G90Callback.invoke(self._sos_cb, event_id, zone_name, is_host_sos)
|
|
706
|
+
|
|
707
|
+
# Also report the event as alarm for unification, hard-coding the
|
|
708
|
+
# sensor name in case of host SOS
|
|
709
|
+
await self.on_alarm(event_id, 'Host SOS' if is_host_sos else zone_name)
|
|
710
|
+
|
|
711
|
+
if not is_host_sos:
|
|
712
|
+
# Also report the remote button press for SOS - the panel will not
|
|
713
|
+
# send corresponding alert
|
|
714
|
+
await self.on_remote_button_press(
|
|
715
|
+
event_id, zone_name, G90RemoteButtonStates.SOS
|
|
716
|
+
)
|
|
717
|
+
|
|
718
|
+
@property
|
|
719
|
+
def sos_callback(self) -> Optional[SosCallback]:
|
|
720
|
+
"""
|
|
721
|
+
SOS callback, which is invoked when SOS alert is triggered.
|
|
722
|
+
"""
|
|
723
|
+
return self._sos_cb
|
|
724
|
+
|
|
725
|
+
@sos_callback.setter
|
|
726
|
+
def sos_callback(self, value: SosCallback) -> None:
|
|
727
|
+
self._sos_cb = value
|
|
728
|
+
|
|
729
|
+
async def on_remote_button_press(
|
|
730
|
+
self, event_id: int, zone_name: str, button: G90RemoteButtonStates
|
|
731
|
+
) -> None:
|
|
732
|
+
"""
|
|
733
|
+
Invoked when remote button is pressed. Fires corresponding callback if
|
|
734
|
+
set by the user with :attr:`.remote_button_press_callback`.
|
|
735
|
+
|
|
736
|
+
Please note the method is for internal use by the class.
|
|
737
|
+
|
|
738
|
+
:param event_id: Index of the sensor triggered alarm
|
|
739
|
+
:param zone_name: Sensor name
|
|
740
|
+
:param button: The button pressed
|
|
741
|
+
"""
|
|
742
|
+
_LOGGER.debug(
|
|
743
|
+
'on_remote_button_press: %s %s %s', event_id, zone_name, button
|
|
744
|
+
)
|
|
745
|
+
G90Callback.invoke(
|
|
746
|
+
self._remote_button_press_cb, event_id, zone_name, button
|
|
747
|
+
)
|
|
748
|
+
|
|
749
|
+
# Also report the event as sensor activity for unification (remote is
|
|
750
|
+
# just a special type of the sensor)
|
|
751
|
+
await self.on_sensor_activity(event_id, zone_name, True)
|
|
752
|
+
|
|
753
|
+
@property
|
|
754
|
+
def remote_button_press_callback(
|
|
755
|
+
self
|
|
756
|
+
) -> Optional[RemoteButtonPressCallback]:
|
|
757
|
+
"""
|
|
758
|
+
Remote button press callback, which is invoked when remote button is
|
|
759
|
+
pressed.
|
|
760
|
+
"""
|
|
761
|
+
return self._remote_button_press_cb
|
|
762
|
+
|
|
763
|
+
@remote_button_press_callback.setter
|
|
764
|
+
def remote_button_press_callback(
|
|
765
|
+
self, value: RemoteButtonPressCallback
|
|
766
|
+
) -> None:
|
|
767
|
+
self._remote_button_press_cb = value
|
|
768
|
+
|
|
674
769
|
async def listen_device_notifications(self) -> None:
|
|
675
770
|
"""
|
|
676
771
|
Starts internal listener for device notifications/alerts.
|
pyg90alarm/const.py
CHANGED
|
@@ -187,8 +187,11 @@ class G90AlertTypes(IntEnum):
|
|
|
187
187
|
"""
|
|
188
188
|
Defines types of alerts sent by the alarm panel.
|
|
189
189
|
"""
|
|
190
|
+
HOST_SOS = 1
|
|
190
191
|
STATE_CHANGE = 2
|
|
191
192
|
ALARM = 3
|
|
193
|
+
SENSOR_ACTIVITY = 4
|
|
194
|
+
# Retained for compatibility, deprecated
|
|
192
195
|
DOOR_OPEN_CLOSE = 4
|
|
193
196
|
|
|
194
197
|
|
|
@@ -245,3 +248,17 @@ class G90HistoryStates(IntEnum):
|
|
|
245
248
|
LOW_BATTERY = 10
|
|
246
249
|
WIFI_CONNECTED = 11
|
|
247
250
|
WIFI_DISCONNECTED = 12
|
|
251
|
+
REMOTE_BUTTON_ARM_AWAY = 13
|
|
252
|
+
REMOTE_BUTTON_ARM_HOME = 14
|
|
253
|
+
REMOTE_BUTTON_DISARM = 15
|
|
254
|
+
REMOTE_BUTTON_SOS = 16
|
|
255
|
+
|
|
256
|
+
|
|
257
|
+
class G90RemoteButtonStates(IntEnum):
|
|
258
|
+
"""
|
|
259
|
+
Defines possible states for remote control buttons.
|
|
260
|
+
"""
|
|
261
|
+
ARM_AWAY = 0
|
|
262
|
+
ARM_HOME = 1
|
|
263
|
+
DISARM = 2
|
|
264
|
+
SOS = 3
|
|
@@ -39,6 +39,7 @@ from .const import (
|
|
|
39
39
|
G90ArmDisarmTypes,
|
|
40
40
|
G90AlertSources,
|
|
41
41
|
G90AlertStates,
|
|
42
|
+
G90RemoteButtonStates,
|
|
42
43
|
)
|
|
43
44
|
|
|
44
45
|
_LOGGER = logging.getLogger(__name__)
|
|
@@ -136,11 +137,13 @@ class G90DeviceNotifications(DatagramProtocol):
|
|
|
136
137
|
# Sensor activity notification
|
|
137
138
|
if notification.kind == G90NotificationTypes.SENSOR_ACTIVITY:
|
|
138
139
|
g90_zone_info = G90ZoneInfo(*notification.data)
|
|
140
|
+
|
|
139
141
|
_LOGGER.debug('Sensor notification: %s', g90_zone_info)
|
|
140
142
|
G90Callback.invoke(
|
|
141
143
|
self.on_sensor_activity,
|
|
142
144
|
g90_zone_info.idx, g90_zone_info.name
|
|
143
145
|
)
|
|
146
|
+
|
|
144
147
|
return
|
|
145
148
|
|
|
146
149
|
# Arm/disarm notification
|
|
@@ -149,18 +152,66 @@ class G90DeviceNotifications(DatagramProtocol):
|
|
|
149
152
|
*notification.data)
|
|
150
153
|
# Map the state received from the device to corresponding enum
|
|
151
154
|
state = G90ArmDisarmTypes(g90_armdisarm_info.state)
|
|
155
|
+
|
|
152
156
|
_LOGGER.debug('Arm/disarm notification: %s',
|
|
153
157
|
state)
|
|
154
158
|
G90Callback.invoke(self.on_armdisarm, state)
|
|
159
|
+
|
|
155
160
|
return
|
|
156
161
|
|
|
157
162
|
_LOGGER.warning('Unknown notification received from %s:%s:'
|
|
158
163
|
' kind %s, data %s',
|
|
159
164
|
addr[0], addr[1], notification.kind, notification.data)
|
|
160
165
|
|
|
166
|
+
def _handle_alert_sensor_activity(self, alert: G90DeviceAlert) -> bool:
|
|
167
|
+
"""
|
|
168
|
+
Handles sensor activity alert.
|
|
169
|
+
"""
|
|
170
|
+
if alert.source == G90AlertSources.REMOTE:
|
|
171
|
+
_LOGGER.debug('Remote button press alert: %s', alert)
|
|
172
|
+
G90Callback.invoke(
|
|
173
|
+
self.on_remote_button_press,
|
|
174
|
+
alert.event_id, alert.zone_name,
|
|
175
|
+
G90RemoteButtonStates(alert.state)
|
|
176
|
+
)
|
|
177
|
+
|
|
178
|
+
return True
|
|
179
|
+
|
|
180
|
+
if alert.state in (
|
|
181
|
+
G90AlertStates.DOOR_OPEN, G90AlertStates.DOOR_CLOSE
|
|
182
|
+
):
|
|
183
|
+
is_open = (
|
|
184
|
+
alert.source == G90AlertSources.SENSOR
|
|
185
|
+
and alert.state == G90AlertStates.DOOR_OPEN # noqa: W503
|
|
186
|
+
) or alert.source == G90AlertSources.DOORBELL
|
|
187
|
+
|
|
188
|
+
_LOGGER.debug('Door open_close alert: %s', alert)
|
|
189
|
+
G90Callback.invoke(
|
|
190
|
+
self.on_door_open_close,
|
|
191
|
+
alert.event_id, alert.zone_name, is_open
|
|
192
|
+
)
|
|
193
|
+
|
|
194
|
+
return True
|
|
195
|
+
|
|
196
|
+
if (
|
|
197
|
+
alert.source == G90AlertSources.SENSOR
|
|
198
|
+
and alert.state == G90AlertStates.LOW_BATTERY # noqa: W503
|
|
199
|
+
):
|
|
200
|
+
_LOGGER.debug('Low battery alert: %s', alert)
|
|
201
|
+
G90Callback.invoke(
|
|
202
|
+
self.on_low_battery,
|
|
203
|
+
alert.event_id, alert.zone_name
|
|
204
|
+
)
|
|
205
|
+
|
|
206
|
+
return True
|
|
207
|
+
|
|
208
|
+
return False
|
|
209
|
+
|
|
161
210
|
def _handle_alert(
|
|
162
211
|
self, addr: Tuple[str, int], alert: G90DeviceAlert
|
|
163
212
|
) -> None:
|
|
213
|
+
handled = False
|
|
214
|
+
|
|
164
215
|
# Stop processing when alert is received from the device with different
|
|
165
216
|
# GUID
|
|
166
217
|
if self.device_id and alert.device_id != self.device_id:
|
|
@@ -170,31 +221,8 @@ class G90DeviceNotifications(DatagramProtocol):
|
|
|
170
221
|
)
|
|
171
222
|
return
|
|
172
223
|
|
|
173
|
-
if alert.type == G90AlertTypes.
|
|
174
|
-
|
|
175
|
-
G90AlertStates.DOOR_OPEN, G90AlertStates.DOOR_CLOSE
|
|
176
|
-
):
|
|
177
|
-
is_open = (
|
|
178
|
-
alert.source == G90AlertSources.SENSOR
|
|
179
|
-
and alert.state == G90AlertStates.DOOR_OPEN # noqa: W503
|
|
180
|
-
) or alert.source == G90AlertSources.DOORBELL
|
|
181
|
-
_LOGGER.debug('Door open_close alert: %s', alert)
|
|
182
|
-
G90Callback.invoke(
|
|
183
|
-
self.on_door_open_close,
|
|
184
|
-
alert.event_id, alert.zone_name, is_open
|
|
185
|
-
)
|
|
186
|
-
return
|
|
187
|
-
|
|
188
|
-
if (
|
|
189
|
-
alert.source == G90AlertSources.SENSOR
|
|
190
|
-
and alert.state == G90AlertStates.LOW_BATTERY # noqa: W503
|
|
191
|
-
):
|
|
192
|
-
_LOGGER.debug('Low battery alert: %s', alert)
|
|
193
|
-
G90Callback.invoke(
|
|
194
|
-
self.on_low_battery,
|
|
195
|
-
alert.event_id, alert.zone_name
|
|
196
|
-
)
|
|
197
|
-
return
|
|
224
|
+
if alert.type == G90AlertTypes.SENSOR_ACTIVITY:
|
|
225
|
+
handled = self._handle_alert_sensor_activity(alert)
|
|
198
226
|
|
|
199
227
|
if alert.type == G90AlertTypes.STATE_CHANGE:
|
|
200
228
|
# Define the mapping between device state received in the alert, to
|
|
@@ -209,25 +237,46 @@ class G90DeviceNotifications(DatagramProtocol):
|
|
|
209
237
|
G90AlertStateChangeTypes.DISARM: G90ArmDisarmTypes.DISARM
|
|
210
238
|
}
|
|
211
239
|
|
|
212
|
-
state = alarm_arm_disarm_state_map.get(alert.event_id)
|
|
240
|
+
state = alarm_arm_disarm_state_map.get(alert.event_id, None)
|
|
213
241
|
if state:
|
|
214
242
|
# We received the device state change related to arm/disarm,
|
|
215
243
|
# invoke the corresponding callback
|
|
216
244
|
_LOGGER.debug('Arm/disarm state change: %s', state)
|
|
217
245
|
G90Callback.invoke(self.on_armdisarm, state)
|
|
218
|
-
|
|
246
|
+
|
|
247
|
+
handled = True
|
|
219
248
|
|
|
220
249
|
if alert.type == G90AlertTypes.ALARM:
|
|
221
|
-
|
|
250
|
+
# Remote SOS
|
|
251
|
+
if alert.source == G90AlertSources.REMOTE:
|
|
252
|
+
_LOGGER.debug('SOS: %s', alert.zone_name)
|
|
253
|
+
G90Callback.invoke(
|
|
254
|
+
self.on_sos, alert.event_id, alert.zone_name, False
|
|
255
|
+
)
|
|
256
|
+
# Regular alarm
|
|
257
|
+
else:
|
|
258
|
+
_LOGGER.debug('Alarm: %s', alert.zone_name)
|
|
259
|
+
G90Callback.invoke(
|
|
260
|
+
self.on_alarm,
|
|
261
|
+
alert.event_id, alert.zone_name
|
|
262
|
+
)
|
|
263
|
+
handled = True
|
|
264
|
+
|
|
265
|
+
# Host SOS
|
|
266
|
+
if alert.type == G90AlertTypes.HOST_SOS:
|
|
267
|
+
zone_name = 'Host SOS'
|
|
268
|
+
|
|
269
|
+
_LOGGER.debug('SOS: Host')
|
|
222
270
|
G90Callback.invoke(
|
|
223
|
-
self.
|
|
224
|
-
alert.event_id, alert.zone_name
|
|
271
|
+
self.on_sos, alert.event_id, zone_name, True
|
|
225
272
|
)
|
|
226
|
-
return
|
|
227
273
|
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
274
|
+
handled = True
|
|
275
|
+
|
|
276
|
+
if not handled:
|
|
277
|
+
_LOGGER.warning('Unknown alert received from %s:%s:'
|
|
278
|
+
' type %s, data %s',
|
|
279
|
+
addr[0], addr[1], alert.type, alert)
|
|
231
280
|
|
|
232
281
|
# Implementation of datagram protocol,
|
|
233
282
|
# https://docs.python.org/3/library/asyncio-protocol.html#datagram-protocols
|
|
@@ -307,11 +356,16 @@ class G90DeviceNotifications(DatagramProtocol):
|
|
|
307
356
|
async def on_armdisarm(self, state: G90ArmDisarmTypes) -> None:
|
|
308
357
|
"""
|
|
309
358
|
Invoked when device is armed or disarmed.
|
|
359
|
+
|
|
360
|
+
:param state: State of the device
|
|
310
361
|
"""
|
|
311
362
|
|
|
312
363
|
async def on_sensor_activity(self, idx: int, name: str) -> None:
|
|
313
364
|
"""
|
|
314
365
|
Invoked on sensor activity.
|
|
366
|
+
|
|
367
|
+
:param idx: Index of the sensor.
|
|
368
|
+
:param name: Name of the sensor.
|
|
315
369
|
"""
|
|
316
370
|
|
|
317
371
|
async def on_door_open_close(
|
|
@@ -319,16 +373,55 @@ class G90DeviceNotifications(DatagramProtocol):
|
|
|
319
373
|
) -> None:
|
|
320
374
|
"""
|
|
321
375
|
Invoked when door sensor reports it opened or closed.
|
|
376
|
+
|
|
377
|
+
:param event_id: Index of the sensor reporting the event.
|
|
378
|
+
:param zone_name: Name of the sensor that reports door open/close.
|
|
379
|
+
:param is_open: Indicates if the door is open.
|
|
322
380
|
"""
|
|
323
381
|
|
|
324
382
|
async def on_low_battery(self, event_id: int, zone_name: str) -> None:
|
|
325
383
|
"""
|
|
326
384
|
Invoked when a sensor reports it is low on battery.
|
|
385
|
+
|
|
386
|
+
:param event_id: Index of the sensor.
|
|
387
|
+
:param zone_name: Name of the sensor that reports low battery.
|
|
327
388
|
"""
|
|
328
389
|
|
|
329
390
|
async def on_alarm(self, event_id: int, zone_name: str) -> None:
|
|
330
391
|
"""
|
|
331
392
|
Invoked when device triggers the alarm.
|
|
393
|
+
|
|
394
|
+
:param event_id: Index of the sensor.
|
|
395
|
+
:param zone_name: Name of the zone that triggered the alarm.
|
|
396
|
+
"""
|
|
397
|
+
|
|
398
|
+
async def on_remote_button_press(
|
|
399
|
+
self, event_id: int, zone_name: str, button: G90RemoteButtonStates
|
|
400
|
+
) -> None:
|
|
401
|
+
"""
|
|
402
|
+
Invoked when a remote button is pressed.
|
|
403
|
+
|
|
404
|
+
Please note there will only be call to the method w/o invoking
|
|
405
|
+
:meth:`G90DeviceNotifications.on_sensor_activity`.
|
|
406
|
+
|
|
407
|
+
:param event_id: Index of the sensor associated with the remote.
|
|
408
|
+
:param zone_name: Name of the sensor that reports remote button press.
|
|
409
|
+
:param button: The button pressed on the remote
|
|
410
|
+
"""
|
|
411
|
+
|
|
412
|
+
async def on_sos(
|
|
413
|
+
self, event_id: int, zone_name: str, is_host_sos: bool
|
|
414
|
+
) -> None:
|
|
415
|
+
"""
|
|
416
|
+
Invoked when SOS is triggered.
|
|
417
|
+
|
|
418
|
+
Please note that the panel might not set its status to alarm
|
|
419
|
+
internally, so that :meth:`G90DeviceNotifications` might need an
|
|
420
|
+
explicit call in the derived class to simulate that.
|
|
421
|
+
|
|
422
|
+
:param event_id: Index of the sensor.
|
|
423
|
+
:param zone_name: Name of the sensor that reports SOS.
|
|
424
|
+
:param is_host_sos: Indicates if the SOS is host-initiated.
|
|
332
425
|
"""
|
|
333
426
|
|
|
334
427
|
async def listen(self) -> None:
|
|
@@ -378,4 +471,12 @@ class G90DeviceNotifications(DatagramProtocol):
|
|
|
378
471
|
|
|
379
472
|
@device_id.setter
|
|
380
473
|
def device_id(self, device_id: str) -> None:
|
|
474
|
+
# Under not yet identified circumstances the device ID might be empty
|
|
475
|
+
# string provided by :meth:`G90Alarm.get_host_info` - disallow that
|
|
476
|
+
if not device_id or len(device_id.strip()) == 0:
|
|
477
|
+
_LOGGER.debug(
|
|
478
|
+
'Device ID is empty or contains whitespace only, not setting'
|
|
479
|
+
)
|
|
480
|
+
return
|
|
481
|
+
|
|
381
482
|
self._device_id = device_id
|
pyg90alarm/history.py
CHANGED
|
@@ -32,15 +32,17 @@ from .const import (
|
|
|
32
32
|
G90AlertStates,
|
|
33
33
|
G90AlertStateChangeTypes,
|
|
34
34
|
G90HistoryStates,
|
|
35
|
+
G90RemoteButtonStates,
|
|
35
36
|
)
|
|
36
37
|
from .device_notifications import G90DeviceAlert
|
|
37
38
|
|
|
38
39
|
_LOGGER = logging.getLogger(__name__)
|
|
39
40
|
|
|
40
41
|
|
|
41
|
-
# The state of the incoming history entries are mixed of `G90AlertStates
|
|
42
|
-
# `G90AlertStateChangeTypes`, depending on entry
|
|
43
|
-
# dictionaries, since enums used for keys have
|
|
42
|
+
# The state of the incoming history entries are mixed of `G90AlertStates`,
|
|
43
|
+
# `G90AlertStateChangeTypes` and `G90RemoteButtonStates`, depending on entry
|
|
44
|
+
# type - hence separate dictionaries, since enums used for keys have
|
|
45
|
+
# conflicting values
|
|
44
46
|
states_mapping_alerts = {
|
|
45
47
|
G90AlertStates.DOOR_CLOSE:
|
|
46
48
|
G90HistoryStates.DOOR_CLOSE,
|
|
@@ -71,6 +73,17 @@ states_mapping_state_changes = {
|
|
|
71
73
|
G90HistoryStates.WIFI_DISCONNECTED,
|
|
72
74
|
}
|
|
73
75
|
|
|
76
|
+
states_mapping_remote_buttons = {
|
|
77
|
+
G90RemoteButtonStates.ARM_AWAY:
|
|
78
|
+
G90HistoryStates.REMOTE_BUTTON_ARM_AWAY,
|
|
79
|
+
G90RemoteButtonStates.ARM_HOME:
|
|
80
|
+
G90HistoryStates.REMOTE_BUTTON_ARM_HOME,
|
|
81
|
+
G90RemoteButtonStates.DISARM:
|
|
82
|
+
G90HistoryStates.REMOTE_BUTTON_DISARM,
|
|
83
|
+
G90RemoteButtonStates.SOS:
|
|
84
|
+
G90HistoryStates.REMOTE_BUTTON_SOS,
|
|
85
|
+
}
|
|
86
|
+
|
|
74
87
|
|
|
75
88
|
@dataclass
|
|
76
89
|
class ProtocolData:
|
|
@@ -112,7 +125,7 @@ class G90History:
|
|
|
112
125
|
"""
|
|
113
126
|
try:
|
|
114
127
|
return G90AlertTypes(self._protocol_data.type)
|
|
115
|
-
except ValueError:
|
|
128
|
+
except (ValueError, KeyError):
|
|
116
129
|
_LOGGER.warning(
|
|
117
130
|
"Can't interpret '%s' as alert type (decoded protocol"
|
|
118
131
|
" data '%s', raw data '%s')",
|
|
@@ -125,18 +138,33 @@ class G90History:
|
|
|
125
138
|
"""
|
|
126
139
|
State for the history entry.
|
|
127
140
|
"""
|
|
141
|
+
# No meaningful state for SOS alerts initiated by the panel itself
|
|
142
|
+
# (host)
|
|
143
|
+
if self.type == G90AlertTypes.HOST_SOS:
|
|
144
|
+
return None
|
|
145
|
+
|
|
128
146
|
try:
|
|
147
|
+
# State of the remote indicate which button has been pressed
|
|
148
|
+
if (
|
|
149
|
+
self.type in [
|
|
150
|
+
G90AlertTypes.SENSOR_ACTIVITY, G90AlertTypes.ALARM
|
|
151
|
+
] and self.source == G90AlertSources.REMOTE
|
|
152
|
+
):
|
|
153
|
+
return states_mapping_remote_buttons[
|
|
154
|
+
G90RemoteButtonStates(self._protocol_data.state)
|
|
155
|
+
]
|
|
156
|
+
|
|
129
157
|
# Door open/close or alert types, mapped against `G90AlertStates`
|
|
130
158
|
# using `state` incoming field
|
|
131
159
|
if self.type in [
|
|
132
|
-
G90AlertTypes.
|
|
160
|
+
G90AlertTypes.SENSOR_ACTIVITY, G90AlertTypes.ALARM
|
|
133
161
|
]:
|
|
134
162
|
return G90HistoryStates(
|
|
135
163
|
states_mapping_alerts[
|
|
136
164
|
G90AlertStates(self._protocol_data.state)
|
|
137
165
|
]
|
|
138
166
|
)
|
|
139
|
-
except ValueError:
|
|
167
|
+
except (ValueError, KeyError):
|
|
140
168
|
_LOGGER.warning(
|
|
141
169
|
"Can't interpret '%s' as alert state (decoded protocol"
|
|
142
170
|
" data '%s', raw data '%s')",
|
|
@@ -151,7 +179,7 @@ class G90History:
|
|
|
151
179
|
G90AlertStateChangeTypes(self._protocol_data.event_id)
|
|
152
180
|
]
|
|
153
181
|
)
|
|
154
|
-
except ValueError:
|
|
182
|
+
except (ValueError, KeyError):
|
|
155
183
|
_LOGGER.warning(
|
|
156
184
|
"Can't interpret '%s' as state change (decoded protocol"
|
|
157
185
|
" data '%s', raw data '%s')",
|
|
@@ -166,13 +194,14 @@ class G90History:
|
|
|
166
194
|
Source of the history entry.
|
|
167
195
|
"""
|
|
168
196
|
try:
|
|
169
|
-
# Device state changes
|
|
170
|
-
# `G90AlertSources` using `source` incoming field
|
|
197
|
+
# Device state changes, open/close or alarm events are mapped
|
|
198
|
+
# against `G90AlertSources` using `source` incoming field
|
|
171
199
|
if self.type in [
|
|
172
|
-
G90AlertTypes.STATE_CHANGE, G90AlertTypes.
|
|
200
|
+
G90AlertTypes.STATE_CHANGE, G90AlertTypes.SENSOR_ACTIVITY,
|
|
201
|
+
G90AlertTypes.ALARM
|
|
173
202
|
]:
|
|
174
203
|
return G90AlertSources(self._protocol_data.source)
|
|
175
|
-
except ValueError:
|
|
204
|
+
except (ValueError, KeyError):
|
|
176
205
|
_LOGGER.warning(
|
|
177
206
|
"Can't interpret '%s' as alert source (decoded protocol"
|
|
178
207
|
" data '%s', raw data '%s')",
|
|
@@ -180,11 +209,6 @@ class G90History:
|
|
|
180
209
|
)
|
|
181
210
|
return None
|
|
182
211
|
|
|
183
|
-
# Alarm will have `SENSOR` as the source, since that is likely what
|
|
184
|
-
# triggered it
|
|
185
|
-
if self.type == G90AlertTypes.ALARM:
|
|
186
|
-
return G90AlertSources.SENSOR
|
|
187
|
-
|
|
188
212
|
# Other sources are assumed to be initiated by device itself
|
|
189
213
|
return G90AlertSources.DEVICE
|
|
190
214
|
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
pyg90alarm/__init__.py,sha256=5AITRm5jZSzuQaL7PS8fZZMZb4-IuGRhSqyAdfTt0Cs,2236
|
|
2
|
-
pyg90alarm/alarm.py,sha256=
|
|
2
|
+
pyg90alarm/alarm.py,sha256=N4A-R3_R39FR2jtwuAtHr1r4H8H_1HxBMfNizYFOK1E,35773
|
|
3
3
|
pyg90alarm/base_cmd.py,sha256=Bz7yoZ0RpkcjWARya664DKAPo3goD6BeaKtuW-hA804,9902
|
|
4
4
|
pyg90alarm/callback.py,sha256=3JsD_JChmZD24OyjaCP-PxxuBDBX7myGYhkM4RN7bk4,3742
|
|
5
5
|
pyg90alarm/config.py,sha256=2YtIgdT7clQXmYvkdn_fhIdS05CY8E1Yc90R8_tAmRI,1961
|
|
6
|
-
pyg90alarm/const.py,sha256=
|
|
7
|
-
pyg90alarm/device_notifications.py,sha256=
|
|
6
|
+
pyg90alarm/const.py,sha256=0EkfCtySEPi6W0TO-j-F1y7_MVFaMOuKDY1Bx6QGDDQ,6617
|
|
7
|
+
pyg90alarm/device_notifications.py,sha256=2ZiQNKlSOFYK9eZgP_u4KtRuB9PG0o4Q9fS-Emi9MIw,16578
|
|
8
8
|
pyg90alarm/discovery.py,sha256=fwyBHDCKGej06OwhpbVCHYTRU9WWkeYysAFgv3FiwqI,3575
|
|
9
9
|
pyg90alarm/exceptions.py,sha256=eiOcRe7D18EIPyPFDNU9DdFgbnkwPmkiLl8lGPOhBNw,1475
|
|
10
|
-
pyg90alarm/history.py,sha256=
|
|
10
|
+
pyg90alarm/history.py,sha256=5NfgB0V-7TZlMNHEjtRbOA0ZtJfQTgh2ysZIg5RM7ck,9080
|
|
11
11
|
pyg90alarm/host_info.py,sha256=4lFIaFEpYd3EvgNrDJmKijTrzX9i29nFISLLlXGnkmE,2759
|
|
12
12
|
pyg90alarm/host_status.py,sha256=4XhuilBzB8XsXkpeWj3PAVpmDPcTnBBOYunO21Flabo,1862
|
|
13
13
|
pyg90alarm/paginated_cmd.py,sha256=vJ8slMS7aNLpkAxnIe25EHstusYy1bYTl1j306ps-MQ,4439
|
|
@@ -20,8 +20,8 @@ pyg90alarm/definitions/sensors.py,sha256=rKOu21ZpI44xk6aMh_vBjniFqnsNTc1CKwAvnv4
|
|
|
20
20
|
pyg90alarm/entities/__init__.py,sha256=hHb6AOiC4Tz--rOWiiICMdLaZDs1Tf_xpWk_HeS_gO4,66
|
|
21
21
|
pyg90alarm/entities/device.py,sha256=f_LHvKCAqTEebZ4mrRh3CpPUI7o-OvpvOfyTRCbftJs,2818
|
|
22
22
|
pyg90alarm/entities/sensor.py,sha256=4r8ouAYTZB8ih8I4ncWdQOaifYsRxaC-ukY9jvnrRvk,16139
|
|
23
|
-
pyg90alarm-1.
|
|
24
|
-
pyg90alarm-1.
|
|
25
|
-
pyg90alarm-1.
|
|
26
|
-
pyg90alarm-1.
|
|
27
|
-
pyg90alarm-1.
|
|
23
|
+
pyg90alarm-1.17.0.dist-info/LICENSE,sha256=f884inRbeNv-O-hbwz62Ro_1J8xiHRTnJ2cCx6A0WvU,1070
|
|
24
|
+
pyg90alarm-1.17.0.dist-info/METADATA,sha256=LLdZ_3HEA3rIlt1VnNPSIrH5QR5OP68XrlcDT_FN6wk,7714
|
|
25
|
+
pyg90alarm-1.17.0.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
|
|
26
|
+
pyg90alarm-1.17.0.dist-info/top_level.txt,sha256=czHiGxYMyTk5QEDTDb0EpPiKqUMRa8zI4zx58Ii409M,11
|
|
27
|
+
pyg90alarm-1.17.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|