uiprotect 4.0.0__py3-none-any.whl → 4.2.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.
Potentially problematic release.
This version of uiprotect might be problematic. Click here for more details.
- uiprotect/data/base.py +7 -15
- uiprotect/data/bootstrap.py +11 -14
- uiprotect/data/devices.py +28 -32
- uiprotect/data/nvr.py +28 -42
- {uiprotect-4.0.0.dist-info → uiprotect-4.2.0.dist-info}/METADATA +2 -1
- {uiprotect-4.0.0.dist-info → uiprotect-4.2.0.dist-info}/RECORD +9 -9
- {uiprotect-4.0.0.dist-info → uiprotect-4.2.0.dist-info}/LICENSE +0 -0
- {uiprotect-4.0.0.dist-info → uiprotect-4.2.0.dist-info}/WHEEL +0 -0
- {uiprotect-4.0.0.dist-info → uiprotect-4.2.0.dist-info}/entry_points.txt +0 -0
uiprotect/data/base.py
CHANGED
|
@@ -11,6 +11,7 @@ from ipaddress import IPv4Address
|
|
|
11
11
|
from typing import TYPE_CHECKING, Any, NamedTuple, TypeVar
|
|
12
12
|
from uuid import UUID
|
|
13
13
|
|
|
14
|
+
from convertertools import pop_dict_set_if_none, pop_dict_tuple
|
|
14
15
|
from pydantic.v1 import BaseModel
|
|
15
16
|
from pydantic.v1.fields import SHAPE_DICT, SHAPE_LIST, PrivateAttr
|
|
16
17
|
|
|
@@ -551,10 +552,7 @@ class ProtectModel(ProtectBaseObject):
|
|
|
551
552
|
exclude: set[str] | None = None,
|
|
552
553
|
) -> dict[str, Any]:
|
|
553
554
|
data = super().unifi_dict(data=data, exclude=exclude)
|
|
554
|
-
|
|
555
|
-
if "modelKey" in data and data["modelKey"] is None:
|
|
556
|
-
del data["modelKey"]
|
|
557
|
-
|
|
555
|
+
pop_dict_set_if_none(data, {"modelKey"})
|
|
558
556
|
return data
|
|
559
557
|
|
|
560
558
|
|
|
@@ -955,13 +953,10 @@ class ProtectAdoptableDeviceModel(ProtectDeviceModel):
|
|
|
955
953
|
exclude: set[str] | None = None,
|
|
956
954
|
) -> dict[str, Any]:
|
|
957
955
|
data = super().unifi_dict(data=data, exclude=exclude)
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
"wifiConnectionState",
|
|
961
|
-
|
|
962
|
-
):
|
|
963
|
-
if key in data and data[key] is None:
|
|
964
|
-
del data[key]
|
|
956
|
+
pop_dict_set_if_none(
|
|
957
|
+
data,
|
|
958
|
+
{"wiredConnectionState", "wifiConnectionState", "bluetoothConnectionState"},
|
|
959
|
+
)
|
|
965
960
|
return data
|
|
966
961
|
|
|
967
962
|
@classmethod
|
|
@@ -1072,10 +1067,7 @@ class ProtectMotionDeviceModel(ProtectAdoptableDeviceModel):
|
|
|
1072
1067
|
exclude: set[str] | None = None,
|
|
1073
1068
|
) -> dict[str, Any]:
|
|
1074
1069
|
data = super().unifi_dict(data=data, exclude=exclude)
|
|
1075
|
-
|
|
1076
|
-
if "lastMotionEventId" in data:
|
|
1077
|
-
del data["lastMotionEventId"]
|
|
1078
|
-
|
|
1070
|
+
pop_dict_tuple(data, ("lastMotionEventId",))
|
|
1079
1071
|
return data
|
|
1080
1072
|
|
|
1081
1073
|
@property
|
uiprotect/data/bootstrap.py
CHANGED
|
@@ -10,6 +10,7 @@ from datetime import datetime
|
|
|
10
10
|
from typing import TYPE_CHECKING, Any
|
|
11
11
|
|
|
12
12
|
from aiohttp.client_exceptions import ServerDisconnectedError
|
|
13
|
+
from convertertools import pop_dict_set, pop_dict_tuple
|
|
13
14
|
from pydantic.v1 import PrivateAttr, ValidationError
|
|
14
15
|
|
|
15
16
|
from ..exceptions import ClientError
|
|
@@ -230,9 +231,7 @@ class Bootstrap(ProtectBaseObject):
|
|
|
230
231
|
) -> dict[str, Any]:
|
|
231
232
|
data = super().unifi_dict(data=data, exclude=exclude)
|
|
232
233
|
|
|
233
|
-
|
|
234
|
-
if key in data:
|
|
235
|
-
del data[key]
|
|
234
|
+
pop_dict_tuple(data, ("events", "captureWsStats", "macLookup", "idLookup"))
|
|
236
235
|
for model_type in ModelType.bootstrap_models_types_set:
|
|
237
236
|
attr = model_type.devices_key # type: ignore[attr-defined]
|
|
238
237
|
if attr in data and isinstance(data[attr], dict):
|
|
@@ -385,8 +384,7 @@ class Bootstrap(ProtectBaseObject):
|
|
|
385
384
|
ignore_stats: bool,
|
|
386
385
|
) -> WSSubscriptionMessage | None:
|
|
387
386
|
if ignore_stats:
|
|
388
|
-
|
|
389
|
-
del data[key]
|
|
387
|
+
pop_dict_set(data, STATS_KEYS)
|
|
390
388
|
# nothing left to process
|
|
391
389
|
if not data:
|
|
392
390
|
return None
|
|
@@ -435,8 +433,7 @@ class Bootstrap(ProtectBaseObject):
|
|
|
435
433
|
model_type, IGNORE_DEVICE_KEYS
|
|
436
434
|
)
|
|
437
435
|
|
|
438
|
-
|
|
439
|
-
del data[key]
|
|
436
|
+
pop_dict_set(data, remove_keys)
|
|
440
437
|
|
|
441
438
|
# nothing left to process
|
|
442
439
|
if not data and not is_ping_back:
|
|
@@ -447,7 +444,7 @@ class Bootstrap(ProtectBaseObject):
|
|
|
447
444
|
if action_id not in devices:
|
|
448
445
|
# ignore updates to events that phase out
|
|
449
446
|
if model_type is not ModelType.EVENT:
|
|
450
|
-
_LOGGER.debug("Unexpected %s: %s",
|
|
447
|
+
_LOGGER.debug("Unexpected %s: %s", model_type, action_id)
|
|
451
448
|
return None
|
|
452
449
|
|
|
453
450
|
obj = devices[action_id]
|
|
@@ -492,9 +489,7 @@ class Bootstrap(ProtectBaseObject):
|
|
|
492
489
|
capture_ws_stats = self.capture_ws_stats
|
|
493
490
|
action = packet.action_frame.data
|
|
494
491
|
data = packet.data_frame.data
|
|
495
|
-
if capture_ws_stats
|
|
496
|
-
action = deepcopy(action)
|
|
497
|
-
data = deepcopy(data)
|
|
492
|
+
keys = list(data) if capture_ws_stats else None
|
|
498
493
|
|
|
499
494
|
new_update_id: str | None = action["newUpdateId"]
|
|
500
495
|
if new_update_id is not None:
|
|
@@ -505,11 +500,13 @@ class Bootstrap(ProtectBaseObject):
|
|
|
505
500
|
)
|
|
506
501
|
|
|
507
502
|
if capture_ws_stats:
|
|
503
|
+
if TYPE_CHECKING:
|
|
504
|
+
assert keys is not None
|
|
508
505
|
self._ws_stats.append(
|
|
509
506
|
WSStat(
|
|
510
|
-
model=
|
|
511
|
-
action=
|
|
512
|
-
keys=
|
|
507
|
+
model=action["modelKey"],
|
|
508
|
+
action=action["action"],
|
|
509
|
+
keys=keys,
|
|
513
510
|
keys_set=[] if message is None else list(message.changed_data),
|
|
514
511
|
size=len(packet.raw),
|
|
515
512
|
filtered=message is None,
|
uiprotect/data/devices.py
CHANGED
|
@@ -12,6 +12,7 @@ from ipaddress import IPv4Address
|
|
|
12
12
|
from pathlib import Path
|
|
13
13
|
from typing import TYPE_CHECKING, Any, Literal, cast
|
|
14
14
|
|
|
15
|
+
from convertertools import pop_dict_set_if_none, pop_dict_tuple
|
|
15
16
|
from pydantic.v1.fields import PrivateAttr
|
|
16
17
|
|
|
17
18
|
from ..exceptions import BadRequest, NotAuthorized, StreamError
|
|
@@ -341,10 +342,7 @@ class ISPSettings(ProtectBaseObject):
|
|
|
341
342
|
exclude: set[str] | None = None,
|
|
342
343
|
) -> dict[str, Any]:
|
|
343
344
|
data = super().unifi_dict(data=data, exclude=exclude)
|
|
344
|
-
|
|
345
|
-
if "focusMode" in data and data["focusMode"] is None:
|
|
346
|
-
del data["focusMode"]
|
|
347
|
-
|
|
345
|
+
pop_dict_set_if_none(data, {"focusMode"})
|
|
348
346
|
return data
|
|
349
347
|
|
|
350
348
|
|
|
@@ -611,10 +609,7 @@ class StorageStats(ProtectBaseObject):
|
|
|
611
609
|
exclude: set[str] | None = None,
|
|
612
610
|
) -> dict[str, Any]:
|
|
613
611
|
data = super().unifi_dict(data=data, exclude=exclude)
|
|
614
|
-
|
|
615
|
-
if "rate" in data and data["rate"] is None:
|
|
616
|
-
del data["rate"]
|
|
617
|
-
|
|
612
|
+
pop_dict_set_if_none(data, {"rate"})
|
|
618
613
|
return data
|
|
619
614
|
|
|
620
615
|
|
|
@@ -1053,21 +1048,21 @@ class Camera(ProtectMotionDeviceModel):
|
|
|
1053
1048
|
]
|
|
1054
1049
|
|
|
1055
1050
|
data = super().unifi_dict(data=data, exclude=exclude)
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1051
|
+
pop_dict_tuple(
|
|
1052
|
+
data,
|
|
1053
|
+
(
|
|
1054
|
+
"lastRingEventId",
|
|
1055
|
+
"lastSmartDetect",
|
|
1056
|
+
"lastSmartAudioDetect",
|
|
1057
|
+
"lastSmartDetectEventId",
|
|
1058
|
+
"lastSmartAudioDetectEventId",
|
|
1059
|
+
"lastSmartDetects",
|
|
1060
|
+
"lastSmartAudioDetects",
|
|
1061
|
+
"lastSmartDetectEventIds",
|
|
1062
|
+
"lastSmartAudioDetectEventIds",
|
|
1063
|
+
"talkbackStream",
|
|
1064
|
+
),
|
|
1065
|
+
)
|
|
1071
1066
|
if "lcdMessage" in data and data["lcdMessage"] is None:
|
|
1072
1067
|
data["lcdMessage"] = {}
|
|
1073
1068
|
|
|
@@ -2783,15 +2778,16 @@ class Sensor(ProtectAdoptableDeviceModel):
|
|
|
2783
2778
|
exclude: set[str] | None = None,
|
|
2784
2779
|
) -> dict[str, Any]:
|
|
2785
2780
|
data = super().unifi_dict(data=data, exclude=exclude)
|
|
2786
|
-
|
|
2787
|
-
|
|
2788
|
-
|
|
2789
|
-
|
|
2790
|
-
|
|
2791
|
-
|
|
2792
|
-
|
|
2793
|
-
|
|
2794
|
-
|
|
2781
|
+
pop_dict_tuple(
|
|
2782
|
+
data,
|
|
2783
|
+
(
|
|
2784
|
+
"lastMotionEventId",
|
|
2785
|
+
"lastContactEventId",
|
|
2786
|
+
"lastValueEventId",
|
|
2787
|
+
"lastAlarmEventId",
|
|
2788
|
+
"extremeValueDetectedAt",
|
|
2789
|
+
),
|
|
2790
|
+
)
|
|
2795
2791
|
return data
|
|
2796
2792
|
|
|
2797
2793
|
@property
|
uiprotect/data/nvr.py
CHANGED
|
@@ -16,6 +16,7 @@ from uuid import UUID
|
|
|
16
16
|
import aiofiles
|
|
17
17
|
import orjson
|
|
18
18
|
from aiofiles import os as aos
|
|
19
|
+
from convertertools import pop_dict_set_if_none, pop_dict_tuple
|
|
19
20
|
from pydantic.v1.fields import PrivateAttr
|
|
20
21
|
|
|
21
22
|
from ..exceptions import BadRequest, NotAuthorized
|
|
@@ -145,11 +146,7 @@ class EventThumbnailAttributes(ProtectBaseObject):
|
|
|
145
146
|
exclude: set[str] | None = None,
|
|
146
147
|
) -> dict[str, Any]:
|
|
147
148
|
data = super().unifi_dict(data=data, exclude=exclude)
|
|
148
|
-
|
|
149
|
-
for key in DELETE_KEYS_THUMB.intersection(data):
|
|
150
|
-
if data[key] is None:
|
|
151
|
-
del data[key]
|
|
152
|
-
|
|
149
|
+
pop_dict_set_if_none(data, DELETE_KEYS_THUMB)
|
|
153
150
|
return data
|
|
154
151
|
|
|
155
152
|
|
|
@@ -171,10 +168,7 @@ class EventDetectedThumbnail(ProtectBaseObject):
|
|
|
171
168
|
exclude: set[str] | None = None,
|
|
172
169
|
) -> dict[str, Any]:
|
|
173
170
|
data = super().unifi_dict(data=data, exclude=exclude)
|
|
174
|
-
|
|
175
|
-
if "name" in data and data["name"] is None:
|
|
176
|
-
del data["name"]
|
|
177
|
-
|
|
171
|
+
pop_dict_set_if_none(data, {"name"})
|
|
178
172
|
return data
|
|
179
173
|
|
|
180
174
|
|
|
@@ -309,11 +303,7 @@ class Event(ProtectModelWithId):
|
|
|
309
303
|
exclude: set[str] | None = None,
|
|
310
304
|
) -> dict[str, Any]:
|
|
311
305
|
data = super().unifi_dict(data=data, exclude=exclude)
|
|
312
|
-
|
|
313
|
-
for key in DELETE_KEYS_EVENT.intersection(data):
|
|
314
|
-
if data[key] is None:
|
|
315
|
-
del data[key]
|
|
316
|
-
|
|
306
|
+
pop_dict_set_if_none(data, DELETE_KEYS_EVENT)
|
|
317
307
|
return data
|
|
318
308
|
|
|
319
309
|
@property
|
|
@@ -632,30 +622,29 @@ class UOSDisk(ProtectBaseObject):
|
|
|
632
622
|
data["estimate"] /= 1000
|
|
633
623
|
|
|
634
624
|
if "state" in data and data["state"] == "nodisk":
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
625
|
+
pop_dict_tuple(
|
|
626
|
+
data,
|
|
627
|
+
(
|
|
628
|
+
"action",
|
|
629
|
+
"ata",
|
|
630
|
+
"bad_sector",
|
|
631
|
+
"estimate",
|
|
632
|
+
"firmware",
|
|
633
|
+
"healthy",
|
|
634
|
+
"life_span",
|
|
635
|
+
"model",
|
|
636
|
+
"poweronhrs",
|
|
637
|
+
"progress",
|
|
638
|
+
"reason",
|
|
639
|
+
"rpm",
|
|
640
|
+
"sata",
|
|
641
|
+
"serial",
|
|
642
|
+
"tempature",
|
|
643
|
+
"temperature",
|
|
644
|
+
"threshold",
|
|
645
|
+
"type",
|
|
646
|
+
),
|
|
647
|
+
)
|
|
659
648
|
return data
|
|
660
649
|
|
|
661
650
|
@property
|
|
@@ -739,10 +728,7 @@ class SystemInfo(ProtectBaseObject):
|
|
|
739
728
|
exclude: set[str] | None = None,
|
|
740
729
|
) -> dict[str, Any]:
|
|
741
730
|
data = super().unifi_dict(data=data, exclude=exclude)
|
|
742
|
-
|
|
743
|
-
if data is not None and "ustorage" in data and data["ustorage"] is None:
|
|
744
|
-
del data["ustorage"]
|
|
745
|
-
|
|
731
|
+
pop_dict_set_if_none(data, {"ustorage"})
|
|
746
732
|
return data
|
|
747
733
|
|
|
748
734
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: uiprotect
|
|
3
|
-
Version: 4.
|
|
3
|
+
Version: 4.2.0
|
|
4
4
|
Summary: Python API for Unifi Protect (Unofficial)
|
|
5
5
|
Home-page: https://github.com/uilibs/uiprotect
|
|
6
6
|
Author: UI Protect Maintainers
|
|
@@ -21,6 +21,7 @@ Requires-Dist: aiofiles (>=23)
|
|
|
21
21
|
Requires-Dist: aiohttp (>=3.9.0)
|
|
22
22
|
Requires-Dist: aioshutil (>=1.3)
|
|
23
23
|
Requires-Dist: async-timeout (>=3.0.1)
|
|
24
|
+
Requires-Dist: convertertools (>=0.5.0)
|
|
24
25
|
Requires-Dist: dateparser (>=1.1.0)
|
|
25
26
|
Requires-Dist: orjson (>=3.9.15)
|
|
26
27
|
Requires-Dist: packaging (>=23)
|
|
@@ -14,11 +14,11 @@ uiprotect/cli/nvr.py,sha256=TwxEg2XT8jXAbOqv6gc7KFXELKadeItEDYweSL4_-e8,4260
|
|
|
14
14
|
uiprotect/cli/sensors.py,sha256=fQtcDJCVxs4VbAqcavgBy2ABiVxAW3GXtna6_XFBp2k,8153
|
|
15
15
|
uiprotect/cli/viewers.py,sha256=2cyrp104ffIvgT0wYGIO0G35QMkEbFe7fSVqLwDXQYQ,2171
|
|
16
16
|
uiprotect/data/__init__.py,sha256=OcfuJl2qXfHcj_mdnrHhzZ5tEIZrw8auziX5IE7dn-I,2938
|
|
17
|
-
uiprotect/data/base.py,sha256=
|
|
18
|
-
uiprotect/data/bootstrap.py,sha256=
|
|
17
|
+
uiprotect/data/base.py,sha256=J2ytJqWJIsFq7vXYG4gfp2c-mrj5gqa3UhmItF0MWbI,35033
|
|
18
|
+
uiprotect/data/bootstrap.py,sha256=l1r2eHsjdE6subYAllvdaXOs26-dQDcnrDBxF2fenbI,20500
|
|
19
19
|
uiprotect/data/convert.py,sha256=8h6Il_DhMkPRDPj9F_rA2UZIlTuchS3BQD24peKpk2A,2185
|
|
20
|
-
uiprotect/data/devices.py,sha256=
|
|
21
|
-
uiprotect/data/nvr.py,sha256=
|
|
20
|
+
uiprotect/data/devices.py,sha256=VRehNQHJFefwnAfBwC72QG5tzs5z86uOAfbr9Fu4R2g,109832
|
|
21
|
+
uiprotect/data/nvr.py,sha256=8M-62AG4q1k71eX-DaFcdO52QWG4zO9X5Voj0Tj9D5A,46598
|
|
22
22
|
uiprotect/data/types.py,sha256=3CocULpkdTgF4is1nIEDYIlwf2EOkNNM7L4kJ7NkAwM,17654
|
|
23
23
|
uiprotect/data/user.py,sha256=YvgXJKV4_y-bm0eySWz9f_ie9aR5lpVn17t9H0Pix8I,6998
|
|
24
24
|
uiprotect/data/websocket.py,sha256=5-yM6yr8NrxKJjBPQlGVXXQUTcksF-UavligKYjJQ3k,6770
|
|
@@ -30,8 +30,8 @@ uiprotect/test_util/__init__.py,sha256=whiOUb5LfDLNT3AQG6ISiKtAqO2JnhCIdFavhWDK4
|
|
|
30
30
|
uiprotect/test_util/anonymize.py,sha256=f-8ijU-_y9r-uAbhIPn0f0I6hzJpAkvJzc8UpWihObI,8478
|
|
31
31
|
uiprotect/utils.py,sha256=G0WkMXpCky2Cc4jynFDFFxAcVaZX4F01OXKa6cx9pho,20121
|
|
32
32
|
uiprotect/websocket.py,sha256=D5DZrMzo434ecp8toNxOB5HM193kVwYw42yEcg99yMw,8029
|
|
33
|
-
uiprotect-4.
|
|
34
|
-
uiprotect-4.
|
|
35
|
-
uiprotect-4.
|
|
36
|
-
uiprotect-4.
|
|
37
|
-
uiprotect-4.
|
|
33
|
+
uiprotect-4.2.0.dist-info/LICENSE,sha256=INx18jhdbVXMEiiBANeKEbrbz57ckgzxk5uutmmcxGk,1111
|
|
34
|
+
uiprotect-4.2.0.dist-info/METADATA,sha256=0Wq8hI7efhmNMHGUJQQvDtN5WeB0tIAdNwbRnYNsIZ0,11009
|
|
35
|
+
uiprotect-4.2.0.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
|
36
|
+
uiprotect-4.2.0.dist-info/entry_points.txt,sha256=J78AUTPrTTxgI3s7SVgrmGqDP7piX2wuuEORzhDdVRA,47
|
|
37
|
+
uiprotect-4.2.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|