uiprotect 1.2.2__py3-none-any.whl → 1.4.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/api.py +2 -2
- uiprotect/data/bootstrap.py +62 -67
- uiprotect/data/convert.py +4 -0
- uiprotect/data/types.py +44 -13
- uiprotect/data/user.py +1 -1
- {uiprotect-1.2.2.dist-info → uiprotect-1.4.0.dist-info}/METADATA +1 -1
- {uiprotect-1.2.2.dist-info → uiprotect-1.4.0.dist-info}/RECORD +10 -10
- {uiprotect-1.2.2.dist-info → uiprotect-1.4.0.dist-info}/LICENSE +0 -0
- {uiprotect-1.2.2.dist-info → uiprotect-1.4.0.dist-info}/WHEEL +0 -0
- {uiprotect-1.2.2.dist-info → uiprotect-1.4.0.dist-info}/entry_points.txt +0 -0
uiprotect/api.py
CHANGED
|
@@ -1146,7 +1146,7 @@ class ProtectApiClient(BaseApiClient):
|
|
|
1146
1146
|
|
|
1147
1147
|
async def get_devices_raw(self, model_type: ModelType) -> list[dict[str, Any]]:
|
|
1148
1148
|
"""Gets a raw device list given a model_type"""
|
|
1149
|
-
return await self.api_request_list(
|
|
1149
|
+
return await self.api_request_list(model_type.devices_key)
|
|
1150
1150
|
|
|
1151
1151
|
async def get_devices(
|
|
1152
1152
|
self,
|
|
@@ -1703,7 +1703,7 @@ class ProtectApiClient(BaseApiClient):
|
|
|
1703
1703
|
|
|
1704
1704
|
async def adopt_device(self, model_type: ModelType, device_id: str) -> None:
|
|
1705
1705
|
"""Adopts a device"""
|
|
1706
|
-
key =
|
|
1706
|
+
key = model_type.devices_key
|
|
1707
1707
|
data = await self.api_request_obj(
|
|
1708
1708
|
"devices/adopt",
|
|
1709
1709
|
method="post",
|
uiprotect/data/bootstrap.py
CHANGED
|
@@ -80,12 +80,9 @@ CAMERA_EVENT_ATTR_MAP: dict[EventType, tuple[str, str]] = {
|
|
|
80
80
|
}
|
|
81
81
|
|
|
82
82
|
|
|
83
|
-
def _process_light_event(event: Event) -> None:
|
|
84
|
-
if event.
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
if _event_is_in_range(event, event.light.last_motion):
|
|
88
|
-
event.light.last_motion_event_id = event.id
|
|
83
|
+
def _process_light_event(event: Event, light: Light) -> None:
|
|
84
|
+
if _event_is_in_range(event, light.last_motion):
|
|
85
|
+
light.last_motion_event_id = event.id
|
|
89
86
|
|
|
90
87
|
|
|
91
88
|
def _event_is_in_range(event: Event, dt: datetime | None) -> bool:
|
|
@@ -95,22 +92,20 @@ def _event_is_in_range(event: Event, dt: datetime | None) -> bool:
|
|
|
95
92
|
)
|
|
96
93
|
|
|
97
94
|
|
|
98
|
-
def _process_sensor_event(event: Event) -> None:
|
|
99
|
-
if event.sensor is None:
|
|
100
|
-
return
|
|
95
|
+
def _process_sensor_event(event: Event, sensor: Sensor) -> None:
|
|
101
96
|
if event.type is EventType.MOTION_SENSOR:
|
|
102
|
-
if _event_is_in_range(event,
|
|
103
|
-
|
|
97
|
+
if _event_is_in_range(event, sensor.motion_detected_at):
|
|
98
|
+
sensor.last_motion_event_id = event.id
|
|
104
99
|
elif event.type in {EventType.SENSOR_CLOSED, EventType.SENSOR_OPENED}:
|
|
105
|
-
if _event_is_in_range(event,
|
|
106
|
-
|
|
100
|
+
if _event_is_in_range(event, sensor.open_status_changed_at):
|
|
101
|
+
sensor.last_contact_event_id = event.id
|
|
107
102
|
elif event.type is EventType.SENSOR_EXTREME_VALUE:
|
|
108
|
-
if _event_is_in_range(event,
|
|
109
|
-
|
|
110
|
-
|
|
103
|
+
if _event_is_in_range(event, sensor.extreme_value_detected_at):
|
|
104
|
+
sensor.extreme_value_detected_at = event.end
|
|
105
|
+
sensor.last_value_event_id = event.id
|
|
111
106
|
elif event.type is EventType.SENSOR_ALARM:
|
|
112
|
-
if _event_is_in_range(event,
|
|
113
|
-
|
|
107
|
+
if _event_is_in_range(event, sensor.alarm_triggered_at):
|
|
108
|
+
sensor.last_value_event_id = event.id
|
|
114
109
|
|
|
115
110
|
|
|
116
111
|
_CAMERA_SMART_AND_LINE_EVENTS = {
|
|
@@ -120,10 +115,7 @@ _CAMERA_SMART_AND_LINE_EVENTS = {
|
|
|
120
115
|
_CAMERA_SMART_AUDIO_EVENT = EventType.SMART_AUDIO_DETECT
|
|
121
116
|
|
|
122
117
|
|
|
123
|
-
def _process_camera_event(event: Event) -> None:
|
|
124
|
-
if (camera := event.camera) is None:
|
|
125
|
-
return
|
|
126
|
-
|
|
118
|
+
def _process_camera_event(event: Event, camera: Camera) -> None:
|
|
127
119
|
event_type = event.type
|
|
128
120
|
dt_attr, event_attr = CAMERA_EVENT_ATTR_MAP[event_type]
|
|
129
121
|
dt: datetime | None = getattr(camera, dt_attr)
|
|
@@ -205,8 +197,8 @@ class Bootstrap(ProtectBaseObject):
|
|
|
205
197
|
)
|
|
206
198
|
data["macLookup"] = {}
|
|
207
199
|
data["idLookup"] = {}
|
|
208
|
-
for model_type in ModelType.
|
|
209
|
-
key =
|
|
200
|
+
for model_type in ModelType.bootstrap_models_types_set():
|
|
201
|
+
key = model_type.devices_key
|
|
210
202
|
items: dict[str, ProtectModel] = {}
|
|
211
203
|
for item in data[key]:
|
|
212
204
|
if (
|
|
@@ -242,8 +234,8 @@ class Bootstrap(ProtectBaseObject):
|
|
|
242
234
|
if "idLookup" in data:
|
|
243
235
|
del data["idLookup"]
|
|
244
236
|
|
|
245
|
-
for model_type in ModelType.
|
|
246
|
-
attr =
|
|
237
|
+
for model_type in ModelType.bootstrap_models_types_set():
|
|
238
|
+
attr = model_type.devices_key
|
|
247
239
|
if attr in data and isinstance(data[attr], dict):
|
|
248
240
|
data[attr] = list(data[attr].values())
|
|
249
241
|
|
|
@@ -310,7 +302,7 @@ class Bootstrap(ProtectBaseObject):
|
|
|
310
302
|
if ref is None:
|
|
311
303
|
return None
|
|
312
304
|
|
|
313
|
-
devices: dict[str, ProtectModelWithId] = getattr(self,
|
|
305
|
+
devices: dict[str, ProtectModelWithId] = getattr(self, ref.model.devices_key)
|
|
314
306
|
return cast(ProtectAdoptableDeviceModel, devices.get(ref.id))
|
|
315
307
|
|
|
316
308
|
def get_device_from_id(self, device_id: str) -> ProtectAdoptableDeviceModel | None:
|
|
@@ -318,16 +310,17 @@ class Bootstrap(ProtectBaseObject):
|
|
|
318
310
|
ref = self.id_lookup.get(device_id)
|
|
319
311
|
if ref is None:
|
|
320
312
|
return None
|
|
321
|
-
devices: dict[str, ProtectModelWithId] = getattr(self,
|
|
313
|
+
devices: dict[str, ProtectModelWithId] = getattr(self, ref.model.devices_key)
|
|
322
314
|
return cast(ProtectAdoptableDeviceModel, devices.get(ref.id))
|
|
323
315
|
|
|
324
316
|
def process_event(self, event: Event) -> None:
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
317
|
+
event_type = event.type
|
|
318
|
+
if event_type in CAMERA_EVENT_ATTR_MAP and (camera := event.camera):
|
|
319
|
+
_process_camera_event(event, camera)
|
|
320
|
+
elif event_type is EventType.MOTION_LIGHT and (light := event.light):
|
|
321
|
+
_process_light_event(event, light)
|
|
322
|
+
elif event_type is EventType.MOTION_SENSOR and (sensor := event.sensor):
|
|
323
|
+
_process_sensor_event(event, sensor)
|
|
331
324
|
|
|
332
325
|
self.events[event.id] = event
|
|
333
326
|
|
|
@@ -351,21 +344,24 @@ class Bootstrap(ProtectBaseObject):
|
|
|
351
344
|
|
|
352
345
|
def _process_add_packet(
|
|
353
346
|
self,
|
|
347
|
+
model_type: ModelType,
|
|
354
348
|
packet: WSPacket,
|
|
355
349
|
data: dict[str, Any],
|
|
356
350
|
) -> WSSubscriptionMessage | None:
|
|
357
|
-
obj = create_from_unifi_dict(data, api=self._api)
|
|
358
|
-
|
|
359
|
-
|
|
351
|
+
obj = create_from_unifi_dict(data, api=self._api, model_type=model_type)
|
|
352
|
+
if model_type is ModelType.EVENT:
|
|
353
|
+
if TYPE_CHECKING:
|
|
354
|
+
assert isinstance(obj, Event)
|
|
360
355
|
self.process_event(obj)
|
|
361
|
-
|
|
356
|
+
if model_type is ModelType.NVR:
|
|
357
|
+
if TYPE_CHECKING:
|
|
358
|
+
assert isinstance(obj, NVR)
|
|
362
359
|
self.nvr = obj
|
|
363
|
-
elif (
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
key = f"{obj.model.value}s"
|
|
360
|
+
elif model_type in ModelType.bootstrap_models_types_set():
|
|
361
|
+
if TYPE_CHECKING:
|
|
362
|
+
assert isinstance(obj, ProtectAdoptableDeviceModel)
|
|
363
|
+
assert isinstance(obj.model, ModelType)
|
|
364
|
+
key = obj.model.devices_key
|
|
369
365
|
if not self._api.ignore_unadopted or (
|
|
370
366
|
obj.is_adopted and not obj.is_adopted_by_other
|
|
371
367
|
):
|
|
@@ -388,9 +384,12 @@ class Bootstrap(ProtectBaseObject):
|
|
|
388
384
|
new_obj=obj,
|
|
389
385
|
)
|
|
390
386
|
|
|
391
|
-
def _process_remove_packet(
|
|
392
|
-
|
|
393
|
-
|
|
387
|
+
def _process_remove_packet(
|
|
388
|
+
self, model_type: ModelType, packet: WSPacket
|
|
389
|
+
) -> WSSubscriptionMessage | None:
|
|
390
|
+
devices: dict[str, ProtectDeviceModel] | None = getattr(
|
|
391
|
+
self, model_type.devices_key, None
|
|
392
|
+
)
|
|
394
393
|
|
|
395
394
|
if devices is None:
|
|
396
395
|
return None
|
|
@@ -450,12 +449,12 @@ class Bootstrap(ProtectBaseObject):
|
|
|
450
449
|
|
|
451
450
|
def _process_device_update(
|
|
452
451
|
self,
|
|
452
|
+
model_type: ModelType,
|
|
453
453
|
packet: WSPacket,
|
|
454
454
|
action: dict[str, Any],
|
|
455
455
|
data: dict[str, Any],
|
|
456
456
|
ignore_stats: bool,
|
|
457
457
|
) -> WSSubscriptionMessage | None:
|
|
458
|
-
model_type = action["modelKey"]
|
|
459
458
|
remove_keys = (
|
|
460
459
|
STATS_AND_IGNORE_DEVICE_KEYS if ignore_stats else IGNORE_DEVICE_KEYS
|
|
461
460
|
)
|
|
@@ -463,33 +462,31 @@ class Bootstrap(ProtectBaseObject):
|
|
|
463
462
|
del data[key]
|
|
464
463
|
# `last_motion` from cameras update every 100 milliseconds when a motion event is active
|
|
465
464
|
# this overrides the behavior to only update `last_motion` when a new event starts
|
|
466
|
-
if model_type
|
|
465
|
+
if model_type is ModelType.CAMERA and "lastMotion" in data:
|
|
467
466
|
del data["lastMotion"]
|
|
468
467
|
# nothing left to process
|
|
469
468
|
if not data:
|
|
470
469
|
self._create_stat(packet, None, True)
|
|
471
470
|
return None
|
|
472
471
|
|
|
473
|
-
|
|
474
|
-
devices: dict[str, ProtectModelWithId] = getattr(self, key)
|
|
472
|
+
devices: dict[str, ProtectModelWithId] = getattr(self, model_type.devices_key)
|
|
475
473
|
action_id: str = action["id"]
|
|
476
474
|
if action_id not in devices:
|
|
477
475
|
# ignore updates to events that phase out
|
|
478
|
-
if model_type
|
|
476
|
+
if model_type is not ModelType.EVENT:
|
|
479
477
|
_LOGGER.debug("Unexpected %s: %s", key, action_id)
|
|
480
478
|
return None
|
|
481
479
|
|
|
482
480
|
obj = devices[action_id]
|
|
483
|
-
model = obj.model
|
|
484
481
|
data = obj.unifi_dict_to_dict(data)
|
|
485
482
|
old_obj = obj.copy()
|
|
486
483
|
obj = obj.update_from_dict(deepcopy(data))
|
|
487
484
|
|
|
488
|
-
if
|
|
485
|
+
if model_type is ModelType.EVENT:
|
|
489
486
|
if TYPE_CHECKING:
|
|
490
487
|
assert isinstance(obj, Event)
|
|
491
488
|
self.process_event(obj)
|
|
492
|
-
elif
|
|
489
|
+
elif model_type is ModelType.CAMERA:
|
|
493
490
|
if TYPE_CHECKING:
|
|
494
491
|
assert isinstance(obj, Camera)
|
|
495
492
|
if "last_ring" in data and obj.last_ring:
|
|
@@ -497,7 +494,7 @@ class Bootstrap(ProtectBaseObject):
|
|
|
497
494
|
_LOGGER.debug("last_ring for %s (%s)", obj.id, is_recent)
|
|
498
495
|
if is_recent:
|
|
499
496
|
obj.set_ring_timeout()
|
|
500
|
-
elif
|
|
497
|
+
elif model_type is ModelType.SENSOR:
|
|
501
498
|
if TYPE_CHECKING:
|
|
502
499
|
assert isinstance(obj, Sensor)
|
|
503
500
|
if "alarm_triggered_at" in data and obj.alarm_triggered_at:
|
|
@@ -539,13 +536,14 @@ class Bootstrap(ProtectBaseObject):
|
|
|
539
536
|
self._create_stat(packet, None, True)
|
|
540
537
|
return None
|
|
541
538
|
|
|
542
|
-
|
|
539
|
+
model_type = ModelType.from_string(model_key)
|
|
540
|
+
if models and model_type not in models:
|
|
543
541
|
self._create_stat(packet, None, True)
|
|
544
542
|
return None
|
|
545
543
|
|
|
546
544
|
action_action: str = action["action"]
|
|
547
545
|
if action_action == "remove":
|
|
548
|
-
return self._process_remove_packet(packet)
|
|
546
|
+
return self._process_remove_packet(model_type, packet)
|
|
549
547
|
|
|
550
548
|
if not data:
|
|
551
549
|
self._create_stat(packet, None, True)
|
|
@@ -553,16 +551,13 @@ class Bootstrap(ProtectBaseObject):
|
|
|
553
551
|
|
|
554
552
|
try:
|
|
555
553
|
if action_action == "add":
|
|
556
|
-
return self._process_add_packet(packet, data)
|
|
554
|
+
return self._process_add_packet(model_type, packet, data)
|
|
557
555
|
if action_action == "update":
|
|
558
|
-
if
|
|
556
|
+
if model_type is ModelType.NVR:
|
|
559
557
|
return self._process_nvr_update(packet, data, ignore_stats)
|
|
560
|
-
|
|
561
|
-
if (
|
|
562
|
-
model_key in ModelType.bootstrap_models_set()
|
|
563
|
-
or model_key == _ModelType_Event_value
|
|
564
|
-
):
|
|
558
|
+
if model_type in ModelType.bootstrap_models_types_and_event_set():
|
|
565
559
|
return self._process_device_update(
|
|
560
|
+
model_type,
|
|
566
561
|
packet,
|
|
567
562
|
action,
|
|
568
563
|
data,
|
|
@@ -583,7 +578,7 @@ class Bootstrap(ProtectBaseObject):
|
|
|
583
578
|
msg = f"Validation error processing event: {action['id']}. Ignoring event."
|
|
584
579
|
else:
|
|
585
580
|
try:
|
|
586
|
-
model_type = ModelType(action["modelKey"])
|
|
581
|
+
model_type = ModelType.from_string(action["modelKey"])
|
|
587
582
|
device_id: str = action["id"]
|
|
588
583
|
task = asyncio.create_task(self.refresh_device(model_type, device_id))
|
|
589
584
|
self._refresh_tasks.add(task)
|
|
@@ -616,7 +611,7 @@ class Bootstrap(ProtectBaseObject):
|
|
|
616
611
|
self.nvr = device
|
|
617
612
|
else:
|
|
618
613
|
devices: dict[str, ProtectModelWithId] = getattr(
|
|
619
|
-
self,
|
|
614
|
+
self, model_type.devices_key
|
|
620
615
|
)
|
|
621
616
|
devices[device.id] = device
|
|
622
617
|
_LOGGER.debug("Successfully refresh model: %s %s", model_type, device_id)
|
uiprotect/data/convert.py
CHANGED
|
@@ -63,6 +63,7 @@ def create_from_unifi_dict(
|
|
|
63
63
|
data: dict[str, Any],
|
|
64
64
|
api: ProtectApiClient | None = None,
|
|
65
65
|
klass: type[ProtectModel] | None = None,
|
|
66
|
+
model_type: ModelType | None = None,
|
|
66
67
|
) -> ProtectModel:
|
|
67
68
|
"""
|
|
68
69
|
Helper method to read the `modelKey` from a UFP JSON dict and convert to currect Python class.
|
|
@@ -71,6 +72,9 @@ def create_from_unifi_dict(
|
|
|
71
72
|
if "modelKey" not in data:
|
|
72
73
|
raise DataDecodeError("No modelKey")
|
|
73
74
|
|
|
75
|
+
if model_type is not None and klass is None:
|
|
76
|
+
klass = MODEL_TO_CLASS.get(model_type)
|
|
77
|
+
|
|
74
78
|
if klass is None:
|
|
75
79
|
klass = get_klass_from_dict(data)
|
|
76
80
|
|
uiprotect/data/types.py
CHANGED
|
@@ -2,7 +2,7 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
import enum
|
|
4
4
|
from collections.abc import Callable, Coroutine
|
|
5
|
-
from functools import cache
|
|
5
|
+
from functools import cache, cached_property
|
|
6
6
|
from typing import Any, Literal, Optional, TypeVar, Union
|
|
7
7
|
|
|
8
8
|
from packaging.version import Version as BaseVersion
|
|
@@ -109,31 +109,62 @@ class ModelType(str, UnknownValuesEnumMixin, enum.Enum):
|
|
|
109
109
|
RECORDING_SCHEDULE = "recordingSchedule"
|
|
110
110
|
UNKNOWN = "unknown"
|
|
111
111
|
|
|
112
|
+
@cached_property
|
|
113
|
+
def devices_key(self) -> str:
|
|
114
|
+
"""Return the devices key."""
|
|
115
|
+
return f"{self.value}s"
|
|
116
|
+
|
|
117
|
+
@classmethod
|
|
118
|
+
@cache
|
|
119
|
+
def from_string(cls, value: str) -> ModelType:
|
|
120
|
+
return cls(value)
|
|
121
|
+
|
|
112
122
|
@staticmethod
|
|
113
123
|
@cache
|
|
114
|
-
def
|
|
124
|
+
def bootstrap_model_types() -> tuple[ModelType, ...]:
|
|
125
|
+
"""Return the bootstrap models as a tuple."""
|
|
115
126
|
# TODO:
|
|
116
127
|
# legacyUFV
|
|
117
128
|
# display
|
|
118
|
-
|
|
119
129
|
return (
|
|
120
|
-
ModelType.CAMERA
|
|
121
|
-
ModelType.USER
|
|
122
|
-
ModelType.GROUP
|
|
123
|
-
ModelType.LIVEVIEW
|
|
124
|
-
ModelType.VIEWPORT
|
|
125
|
-
ModelType.LIGHT
|
|
126
|
-
ModelType.BRIDGE
|
|
127
|
-
ModelType.SENSOR
|
|
128
|
-
ModelType.DOORLOCK
|
|
129
|
-
ModelType.CHIME
|
|
130
|
+
ModelType.CAMERA,
|
|
131
|
+
ModelType.USER,
|
|
132
|
+
ModelType.GROUP,
|
|
133
|
+
ModelType.LIVEVIEW,
|
|
134
|
+
ModelType.VIEWPORT,
|
|
135
|
+
ModelType.LIGHT,
|
|
136
|
+
ModelType.BRIDGE,
|
|
137
|
+
ModelType.SENSOR,
|
|
138
|
+
ModelType.DOORLOCK,
|
|
139
|
+
ModelType.CHIME,
|
|
140
|
+
)
|
|
141
|
+
|
|
142
|
+
@staticmethod
|
|
143
|
+
@cache
|
|
144
|
+
def bootstrap_models() -> tuple[str, ...]:
|
|
145
|
+
"""Return the bootstrap models strings as a tuple."""
|
|
146
|
+
return tuple(
|
|
147
|
+
model_type.value for model_type in ModelType.bootstrap_model_types()
|
|
130
148
|
)
|
|
131
149
|
|
|
132
150
|
@staticmethod
|
|
133
151
|
@cache
|
|
134
152
|
def bootstrap_models_set() -> set[str]:
|
|
153
|
+
"""Return the set of bootstrap models strings as a set."""
|
|
135
154
|
return set(ModelType.bootstrap_models())
|
|
136
155
|
|
|
156
|
+
@staticmethod
|
|
157
|
+
@cache
|
|
158
|
+
def bootstrap_models_types_set() -> set[ModelType]:
|
|
159
|
+
"""Return the set of bootstrap models as a set."""
|
|
160
|
+
return set(ModelType.bootstrap_model_types())
|
|
161
|
+
|
|
162
|
+
@staticmethod
|
|
163
|
+
@cache
|
|
164
|
+
def bootstrap_models_types_and_event_set() -> set[ModelType]:
|
|
165
|
+
"""Return the set of bootstrap models and the event model as a set."""
|
|
166
|
+
return ModelType.bootstrap_models_types_set() | {ModelType.EVENT}
|
|
167
|
+
|
|
137
168
|
|
|
138
169
|
@enum.unique
|
|
139
170
|
class EventType(str, ValuesEnumMixin, enum.Enum):
|
uiprotect/data/user.py
CHANGED
|
@@ -54,7 +54,7 @@ class Permission(ProtectBaseObject):
|
|
|
54
54
|
if self.obj_ids == {"self"} or self.obj_ids is None:
|
|
55
55
|
return None
|
|
56
56
|
|
|
57
|
-
devices = getattr(self._api.bootstrap,
|
|
57
|
+
devices = getattr(self._api.bootstrap, self.model.devices_key)
|
|
58
58
|
return [devices[oid] for oid in self.obj_ids]
|
|
59
59
|
|
|
60
60
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
uiprotect/__init__.py,sha256=llnQNtiBfwQG8IkQXovvFz4LZeFjrJx7XdmmUhu3a9E,289
|
|
2
2
|
uiprotect/__main__.py,sha256=C_bHCOkv5qj6WMy-6ELoY3Y6HDhLxOa1a30CzmbZhsg,462
|
|
3
|
-
uiprotect/api.py,sha256=
|
|
3
|
+
uiprotect/api.py,sha256=t3E1wMja0av6ENtvXJHGv70WC6NCCWbF_wFIJxOLS0I,66463
|
|
4
4
|
uiprotect/cli/__init__.py,sha256=sSLW9keVQOkgFcMW18HTDjRrt9sJ0KWjn9DJDA6f9Pc,8658
|
|
5
5
|
uiprotect/cli/backup.py,sha256=ZiS7RZnJGKI8TJKLW2cOUzkRM8nyTvE5Ov_jZZGtvSM,36708
|
|
6
6
|
uiprotect/cli/base.py,sha256=zpTm2kyJe_GLixnv3Uadke__iRLh64AEwQzp-2hqS7g,7730
|
|
@@ -15,12 +15,12 @@ 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
17
|
uiprotect/data/base.py,sha256=kkPrRhvJV7igGyB3wv1fDvWH26Xzlbz94BjJkDiTvU4,38375
|
|
18
|
-
uiprotect/data/bootstrap.py,sha256=
|
|
19
|
-
uiprotect/data/convert.py,sha256=
|
|
18
|
+
uiprotect/data/bootstrap.py,sha256=INRUEbLWnsEJuzlcoFlm7RAT-WPx6odje3aD092QKGo,21465
|
|
19
|
+
uiprotect/data/convert.py,sha256=8h6Il_DhMkPRDPj9F_rA2UZIlTuchS3BQD24peKpk2A,2185
|
|
20
20
|
uiprotect/data/devices.py,sha256=Nq3bOko5PFf5LvEBoD4JV8kmbq50laRdh3VHMWX7t-0,111809
|
|
21
21
|
uiprotect/data/nvr.py,sha256=jwJEl4o2kbvoYFB9wSJPghNj0905847-86ElT51nNs0,47580
|
|
22
|
-
uiprotect/data/types.py,sha256=
|
|
23
|
-
uiprotect/data/user.py,sha256=
|
|
22
|
+
uiprotect/data/types.py,sha256=1dj9jCk7btAa2hkiEo1Y5NoAFsQtOroCWT6KQKqG5eo,17213
|
|
23
|
+
uiprotect/data/user.py,sha256=Wb-ZWSwIJbyUbfVuENtUYbuW-uftHNDcoMH85dvEjkw,7071
|
|
24
24
|
uiprotect/data/websocket.py,sha256=WZJVA7EfYuKYMv-9jmvGgMWXKzE9ES25SKv1NQ2eHjc,6281
|
|
25
25
|
uiprotect/exceptions.py,sha256=kgn0cRM6lTtgLza09SDa3ZiX6ue1QqHCOogQ4qu6KTQ,965
|
|
26
26
|
uiprotect/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -30,8 +30,8 @@ uiprotect/test_util/__init__.py,sha256=d2g7afa0LSdixQ0kjEDYwafDFME_UlW2LzxpamZ2B
|
|
|
30
30
|
uiprotect/test_util/anonymize.py,sha256=f-8ijU-_y9r-uAbhIPn0f0I6hzJpAkvJzc8UpWihObI,8478
|
|
31
31
|
uiprotect/utils.py,sha256=6OLY8hNiCzk418PjJJIlFW7jjPzVt1vxBKEzBSqMeTk,18418
|
|
32
32
|
uiprotect/websocket.py,sha256=IzDPyqbzrkOMREvahN-e2zdvVD0VABSCWy6jSoCwOT0,7299
|
|
33
|
-
uiprotect-1.
|
|
34
|
-
uiprotect-1.
|
|
35
|
-
uiprotect-1.
|
|
36
|
-
uiprotect-1.
|
|
37
|
-
uiprotect-1.
|
|
33
|
+
uiprotect-1.4.0.dist-info/LICENSE,sha256=INx18jhdbVXMEiiBANeKEbrbz57ckgzxk5uutmmcxGk,1111
|
|
34
|
+
uiprotect-1.4.0.dist-info/METADATA,sha256=BZe2l7Ns5304fpwkOl7u7HuJA8AjTg9D0ilGahzubEs,10984
|
|
35
|
+
uiprotect-1.4.0.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
|
36
|
+
uiprotect-1.4.0.dist-info/entry_points.txt,sha256=J78AUTPrTTxgI3s7SVgrmGqDP7piX2wuuEORzhDdVRA,47
|
|
37
|
+
uiprotect-1.4.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|