uiprotect 0.1.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/__init__.py +13 -0
- uiprotect/__main__.py +24 -0
- uiprotect/api.py +1936 -0
- uiprotect/cli/__init__.py +314 -0
- uiprotect/cli/backup.py +1103 -0
- uiprotect/cli/base.py +238 -0
- uiprotect/cli/cameras.py +574 -0
- uiprotect/cli/chimes.py +180 -0
- uiprotect/cli/doorlocks.py +125 -0
- uiprotect/cli/events.py +258 -0
- uiprotect/cli/lights.py +119 -0
- uiprotect/cli/liveviews.py +65 -0
- uiprotect/cli/nvr.py +154 -0
- uiprotect/cli/sensors.py +278 -0
- uiprotect/cli/viewers.py +76 -0
- uiprotect/data/__init__.py +157 -0
- uiprotect/data/base.py +1116 -0
- uiprotect/data/bootstrap.py +634 -0
- uiprotect/data/convert.py +77 -0
- uiprotect/data/devices.py +3384 -0
- uiprotect/data/nvr.py +1520 -0
- uiprotect/data/types.py +630 -0
- uiprotect/data/user.py +236 -0
- uiprotect/data/websocket.py +236 -0
- uiprotect/exceptions.py +41 -0
- uiprotect/py.typed +0 -0
- uiprotect/release_cache.json +1 -0
- uiprotect/stream.py +166 -0
- uiprotect/test_util/__init__.py +531 -0
- uiprotect/test_util/anonymize.py +257 -0
- uiprotect/utils.py +610 -0
- uiprotect/websocket.py +225 -0
- uiprotect-0.1.0.dist-info/LICENSE +23 -0
- uiprotect-0.1.0.dist-info/METADATA +245 -0
- uiprotect-0.1.0.dist-info/RECORD +37 -0
- uiprotect-0.1.0.dist-info/WHEEL +4 -0
- uiprotect-0.1.0.dist-info/entry_points.txt +3 -0
uiprotect/data/types.py
ADDED
|
@@ -0,0 +1,630 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import enum
|
|
4
|
+
from collections.abc import Callable, Coroutine
|
|
5
|
+
from typing import Any, Literal, Optional, TypeVar, Union
|
|
6
|
+
|
|
7
|
+
from packaging.version import Version as BaseVersion
|
|
8
|
+
from pydantic.v1 import BaseModel, ConstrainedInt
|
|
9
|
+
from pydantic.v1.color import Color as BaseColor
|
|
10
|
+
from pydantic.v1.types import ConstrainedFloat, ConstrainedStr
|
|
11
|
+
|
|
12
|
+
KT = TypeVar("KT")
|
|
13
|
+
VT = TypeVar("VT")
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
DEFAULT = "DEFAULT_VALUE"
|
|
17
|
+
DEFAULT_TYPE = Literal["DEFAULT_VALUE"]
|
|
18
|
+
EventCategories = Literal[
|
|
19
|
+
"critical",
|
|
20
|
+
"update",
|
|
21
|
+
"admin",
|
|
22
|
+
"ring",
|
|
23
|
+
"motion",
|
|
24
|
+
"smart",
|
|
25
|
+
"iot",
|
|
26
|
+
]
|
|
27
|
+
|
|
28
|
+
ProgressCallback = Callable[[int, int, int], Coroutine[Any, Any, None]]
|
|
29
|
+
IteratorCallback = Callable[[int, Optional[bytes]], Coroutine[Any, Any, None]]
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class FixSizeOrderedDict(dict[KT, VT]):
|
|
33
|
+
"""A fixed size ordered dict."""
|
|
34
|
+
|
|
35
|
+
def __init__(self, *args: Any, max_size: int = 0, **kwargs: Any) -> None:
|
|
36
|
+
"""Create the FixSizeOrderedDict."""
|
|
37
|
+
self._max_size = max_size
|
|
38
|
+
super().__init__(*args, **kwargs)
|
|
39
|
+
|
|
40
|
+
def __setitem__(self, key: KT, value: VT) -> None:
|
|
41
|
+
"""Set an update up to the max size."""
|
|
42
|
+
dict.__setitem__(self, key, value)
|
|
43
|
+
if self._max_size > 0 and len(self) > 0 and len(self) > self._max_size:
|
|
44
|
+
del self[next(iter(self.keys()))]
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
class ValuesEnumMixin:
|
|
48
|
+
_values: list[str] | None = None
|
|
49
|
+
_values_normalized: dict[str, str] | None = None
|
|
50
|
+
|
|
51
|
+
@classmethod
|
|
52
|
+
def values(cls) -> list[str]:
|
|
53
|
+
if cls._values is None:
|
|
54
|
+
cls._values = [e.value for e in cls] # type: ignore[attr-defined]
|
|
55
|
+
return cls._values
|
|
56
|
+
|
|
57
|
+
@classmethod
|
|
58
|
+
def _missing_(cls, value: Any) -> Any | None:
|
|
59
|
+
if cls._values_normalized is None:
|
|
60
|
+
cls._values_normalized = {e.value.lower(): e for e in cls} # type: ignore[attr-defined]
|
|
61
|
+
|
|
62
|
+
value_normal = value
|
|
63
|
+
if isinstance(value, str):
|
|
64
|
+
value_normal = value.lower()
|
|
65
|
+
return cls._values_normalized.get(value_normal)
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
class UnknownValuesEnumMixin(ValuesEnumMixin):
|
|
69
|
+
@classmethod
|
|
70
|
+
def _missing_(cls, value: Any) -> Any | None:
|
|
71
|
+
# value always set in superclass _missing
|
|
72
|
+
return super()._missing_(value) or cls._values_normalized.get("unknown") # type: ignore[union-attr]
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
@enum.unique
|
|
76
|
+
class ModelType(str, UnknownValuesEnumMixin, enum.Enum):
|
|
77
|
+
CAMERA = "camera"
|
|
78
|
+
CLOUD_IDENTITY = "cloudIdentity"
|
|
79
|
+
EVENT = "event"
|
|
80
|
+
GROUP = "group"
|
|
81
|
+
LIGHT = "light"
|
|
82
|
+
LIVEVIEW = "liveview"
|
|
83
|
+
NVR = "nvr"
|
|
84
|
+
USER = "user"
|
|
85
|
+
USER_LOCATION = "userLocation"
|
|
86
|
+
VIEWPORT = "viewer"
|
|
87
|
+
BRIDGE = "bridge"
|
|
88
|
+
SENSOR = "sensor"
|
|
89
|
+
DOORLOCK = "doorlock"
|
|
90
|
+
SCHEDULE = "schedule"
|
|
91
|
+
CHIME = "chime"
|
|
92
|
+
DEVICE_GROUP = "deviceGroup"
|
|
93
|
+
RECORDING_SCHEDULE = "recordingSchedule"
|
|
94
|
+
UNKNOWN = "unknown"
|
|
95
|
+
|
|
96
|
+
@staticmethod
|
|
97
|
+
def bootstrap_models() -> tuple[str, ...]:
|
|
98
|
+
# TODO:
|
|
99
|
+
# legacyUFV
|
|
100
|
+
# display
|
|
101
|
+
|
|
102
|
+
return (
|
|
103
|
+
ModelType.CAMERA.value,
|
|
104
|
+
ModelType.USER.value,
|
|
105
|
+
ModelType.GROUP.value,
|
|
106
|
+
ModelType.LIVEVIEW.value,
|
|
107
|
+
ModelType.VIEWPORT.value,
|
|
108
|
+
ModelType.LIGHT.value,
|
|
109
|
+
ModelType.BRIDGE.value,
|
|
110
|
+
ModelType.SENSOR.value,
|
|
111
|
+
ModelType.DOORLOCK.value,
|
|
112
|
+
ModelType.CHIME.value,
|
|
113
|
+
)
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
@enum.unique
|
|
117
|
+
class EventType(str, ValuesEnumMixin, enum.Enum):
|
|
118
|
+
DISCONNECT = "disconnect"
|
|
119
|
+
FACTORY_RESET = "factoryReset"
|
|
120
|
+
PROVISION = "provision"
|
|
121
|
+
UPDATE = "update"
|
|
122
|
+
CAMERA_POWER_CYCLE = "cameraPowerCycling"
|
|
123
|
+
RING = "ring"
|
|
124
|
+
DOOR_ACCESS = "doorAccess"
|
|
125
|
+
RESOLUTION_LOWERED = "resolutionLowered"
|
|
126
|
+
POOR_CONNECTION = "poorConnection"
|
|
127
|
+
STREAM_RECOVERY = "streamRecovery"
|
|
128
|
+
MOTION = "motion"
|
|
129
|
+
RECORDING_DELETED = "recordingDeleted"
|
|
130
|
+
SMART_AUDIO_DETECT = "smartAudioDetect"
|
|
131
|
+
SMART_DETECT = "smartDetectZone"
|
|
132
|
+
SMART_DETECT_LINE = "smartDetectLine"
|
|
133
|
+
NO_SCHEDULE = "nonScheduledRecording"
|
|
134
|
+
RECORDING_MODE_CHANGED = "recordingModeChanged"
|
|
135
|
+
HOTPLUG = "hotplug"
|
|
136
|
+
FACE_GROUP_DETECTED = "faceGroupDetected"
|
|
137
|
+
CONSOLIDATED_RESOLUTION_LOWERED = "consolidatedResolutionLowered"
|
|
138
|
+
CONSOLIDATED_POOR_CONNECTION = "consolidatedPoorConnection"
|
|
139
|
+
CAMERA_CONNECTED = "cameraConnected"
|
|
140
|
+
CAMERA_REBOOTED = "cameraRebooted"
|
|
141
|
+
CAMERA_DISCONNECTED = "cameraDisconnected"
|
|
142
|
+
# ---
|
|
143
|
+
INSTALLED_DISK = "installed"
|
|
144
|
+
CORRUPTED_DB_RECOVERED = "corruptedDbRecovered"
|
|
145
|
+
OFFLINE = "offline"
|
|
146
|
+
OFF = "off"
|
|
147
|
+
REBOOT = "reboot"
|
|
148
|
+
FIRMWARE_UPDATE = "fwUpdate"
|
|
149
|
+
APP_UPDATE = "applicationUpdate"
|
|
150
|
+
APPLICATION_UPDATABLE = "applicationUpdatable"
|
|
151
|
+
ACCESS = "access"
|
|
152
|
+
DRIVE_FAILED = "driveFailed"
|
|
153
|
+
CAMERA_UTILIZATION_LIMIT_REACHED = "cameraUtilizationLimitReached"
|
|
154
|
+
CAMERA_UTILIZATION_LIMIT_EXCEEDED = "cameraUtilizationLimitExceeded"
|
|
155
|
+
DRIVE_SLOW = "driveSlow"
|
|
156
|
+
GLOBAL_RECORDING_MODE_CHANGED = "globalRecordingModeChanged"
|
|
157
|
+
NVR_SETTINGS_CHANGED = "nvrSettingsChanged"
|
|
158
|
+
# ---
|
|
159
|
+
UNADOPTED_DEVICE_DISCOVERED = "unadoptedDeviceDiscovered"
|
|
160
|
+
MULTIPLE_UNADOPTED_DEVICE_DISCOVERED = "multipleUnadoptedDeviceDiscovered"
|
|
161
|
+
DEVICE_ADOPTED = "deviceAdopted"
|
|
162
|
+
DEVICE_UNADOPTED = "deviceUnadopted"
|
|
163
|
+
UVF_DISCOVERED = "ufvDiscovered"
|
|
164
|
+
DEVICE_PASSWORD_UPDATE = "devicesPasswordUpdated" # noqa: S105
|
|
165
|
+
DEVICE_UPDATABLE = "deviceUpdatable"
|
|
166
|
+
MULTIPLE_DEVICE_UPDATABLE = "multipleDeviceUpdatable"
|
|
167
|
+
DEVICE_CONNECTED = "deviceConnected"
|
|
168
|
+
DEVICE_REBOOTED = "deviceRebooted"
|
|
169
|
+
DEVICE_DISCONNECTED = "deviceDisconnected"
|
|
170
|
+
NETWORK_DEVICE_OFFLINE = "networkDeviceOffline"
|
|
171
|
+
# ---
|
|
172
|
+
USER_LEFT = "userLeft"
|
|
173
|
+
USER_ARRIVED = "userArrived"
|
|
174
|
+
VIDEO_EXPORTED = "videoExported"
|
|
175
|
+
MIC_DISABLED = "microphoneDisabled"
|
|
176
|
+
VIDEO_DELETED = "videoDeleted"
|
|
177
|
+
SCHEDULE_CHANGED = "recordingScheduleChanged"
|
|
178
|
+
# ---
|
|
179
|
+
MOTION_SENSOR = "sensorMotion"
|
|
180
|
+
SENSOR_OPENED = "sensorOpened"
|
|
181
|
+
SENSOR_CLOSED = "sensorClosed"
|
|
182
|
+
SENSOR_ALARM = "sensorAlarm"
|
|
183
|
+
SENSOR_EXTREME_VALUE = "sensorExtremeValues"
|
|
184
|
+
SENSOR_WATER_LEAK = "sensorWaterLeak"
|
|
185
|
+
SENSOR_BATTERY_LOW = "sensorBatteryLow"
|
|
186
|
+
# ---
|
|
187
|
+
MOTION_LIGHT = "lightMotion"
|
|
188
|
+
# ---
|
|
189
|
+
DOORLOCK_OPEN = "doorlockOpened"
|
|
190
|
+
DOORLOCK_CLOSE = "doorlockClosed"
|
|
191
|
+
DOORLOCK_BATTERY_LOW = "doorlockBatteryLow"
|
|
192
|
+
# ---
|
|
193
|
+
DISRUPTED_CONDITIONS = "ringDisruptedConditions"
|
|
194
|
+
# ---
|
|
195
|
+
RECORDING_OFF = "recordingOff"
|
|
196
|
+
|
|
197
|
+
@staticmethod
|
|
198
|
+
def device_events() -> list[str]:
|
|
199
|
+
return [
|
|
200
|
+
EventType.MOTION.value,
|
|
201
|
+
EventType.RING.value,
|
|
202
|
+
EventType.SMART_DETECT.value,
|
|
203
|
+
]
|
|
204
|
+
|
|
205
|
+
@staticmethod
|
|
206
|
+
def motion_events() -> list[str]:
|
|
207
|
+
return [EventType.MOTION.value, EventType.SMART_DETECT.value]
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
@enum.unique
|
|
211
|
+
class StateType(str, ValuesEnumMixin, enum.Enum):
|
|
212
|
+
CONNECTED = "CONNECTED"
|
|
213
|
+
CONNECTING = "CONNECTING"
|
|
214
|
+
DISCONNECTED = "DISCONNECTED"
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
@enum.unique
|
|
218
|
+
class ProtectWSPayloadFormat(int, enum.Enum):
|
|
219
|
+
"""Websocket Payload formats."""
|
|
220
|
+
|
|
221
|
+
JSON = 1
|
|
222
|
+
UTF8String = 2
|
|
223
|
+
NodeBuffer = 3
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
@enum.unique
|
|
227
|
+
class SmartDetectObjectType(str, ValuesEnumMixin, enum.Enum):
|
|
228
|
+
PERSON = "person"
|
|
229
|
+
ANIMAL = "animal"
|
|
230
|
+
VEHICLE = "vehicle"
|
|
231
|
+
LICENSE_PLATE = "licensePlate"
|
|
232
|
+
PACKAGE = "package"
|
|
233
|
+
SMOKE = "alrmSmoke"
|
|
234
|
+
CMONX = "alrmCmonx"
|
|
235
|
+
SIREN = "alrmSiren"
|
|
236
|
+
BABY_CRY = "alrmBabyCry"
|
|
237
|
+
SPEAK = "alrmSpeak"
|
|
238
|
+
BARK = "alrmBark"
|
|
239
|
+
BURGLAR = "alrmBurglar"
|
|
240
|
+
CAR_HORN = "alrmCarHorn"
|
|
241
|
+
GLASS_BREAK = "alrmGlassBreak"
|
|
242
|
+
FACE = "face"
|
|
243
|
+
# old?
|
|
244
|
+
CAR = "car"
|
|
245
|
+
PET = "pet"
|
|
246
|
+
|
|
247
|
+
@property
|
|
248
|
+
def audio_type(self) -> SmartDetectAudioType | None:
|
|
249
|
+
return OBJECT_TO_AUDIO_MAP.get(self)
|
|
250
|
+
|
|
251
|
+
|
|
252
|
+
@enum.unique
|
|
253
|
+
class SmartDetectAudioType(str, ValuesEnumMixin, enum.Enum):
|
|
254
|
+
SMOKE = "alrmSmoke"
|
|
255
|
+
CMONX = "alrmCmonx"
|
|
256
|
+
SMOKE_CMONX = "smoke_cmonx"
|
|
257
|
+
SIREN = "alrmSiren"
|
|
258
|
+
BABY_CRY = "alrmBabyCry"
|
|
259
|
+
SPEAK = "alrmSpeak"
|
|
260
|
+
BARK = "alrmBark"
|
|
261
|
+
BURGLAR = "alrmBurglar"
|
|
262
|
+
CAR_HORN = "alrmCarHorn"
|
|
263
|
+
GLASS_BREAK = "alrmGlassBreak"
|
|
264
|
+
|
|
265
|
+
|
|
266
|
+
@enum.unique
|
|
267
|
+
class DetectionColor(str, ValuesEnumMixin, enum.Enum):
|
|
268
|
+
BLACK = "black"
|
|
269
|
+
BLUE = "blue"
|
|
270
|
+
BROWN = "brown"
|
|
271
|
+
GRAY = "gray"
|
|
272
|
+
GREEN = "green"
|
|
273
|
+
ORANGE = "orange"
|
|
274
|
+
PINK = "pink"
|
|
275
|
+
PURPLE = "purple"
|
|
276
|
+
RED = "red"
|
|
277
|
+
WHITE = "white"
|
|
278
|
+
YELLOW = "yellow"
|
|
279
|
+
|
|
280
|
+
|
|
281
|
+
OBJECT_TO_AUDIO_MAP = {
|
|
282
|
+
SmartDetectObjectType.SMOKE: SmartDetectAudioType.SMOKE,
|
|
283
|
+
SmartDetectObjectType.CMONX: SmartDetectAudioType.CMONX,
|
|
284
|
+
SmartDetectObjectType.SIREN: SmartDetectAudioType.SIREN,
|
|
285
|
+
SmartDetectObjectType.BABY_CRY: SmartDetectAudioType.BABY_CRY,
|
|
286
|
+
SmartDetectObjectType.SPEAK: SmartDetectAudioType.SPEAK,
|
|
287
|
+
SmartDetectObjectType.BARK: SmartDetectAudioType.BARK,
|
|
288
|
+
SmartDetectObjectType.BURGLAR: SmartDetectAudioType.BURGLAR,
|
|
289
|
+
SmartDetectObjectType.CAR_HORN: SmartDetectAudioType.CAR_HORN,
|
|
290
|
+
SmartDetectObjectType.GLASS_BREAK: SmartDetectAudioType.GLASS_BREAK,
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
|
|
294
|
+
@enum.unique
|
|
295
|
+
class DoorbellMessageType(str, ValuesEnumMixin, enum.Enum):
|
|
296
|
+
LEAVE_PACKAGE_AT_DOOR = "LEAVE_PACKAGE_AT_DOOR"
|
|
297
|
+
DO_NOT_DISTURB = "DO_NOT_DISTURB"
|
|
298
|
+
CUSTOM_MESSAGE = "CUSTOM_MESSAGE"
|
|
299
|
+
|
|
300
|
+
|
|
301
|
+
@enum.unique
|
|
302
|
+
class LightModeEnableType(str, ValuesEnumMixin, enum.Enum):
|
|
303
|
+
DARK = "dark"
|
|
304
|
+
ALWAYS = "fulltime"
|
|
305
|
+
NIGHT = "night"
|
|
306
|
+
|
|
307
|
+
|
|
308
|
+
@enum.unique
|
|
309
|
+
class LightModeType(str, ValuesEnumMixin, enum.Enum):
|
|
310
|
+
MOTION = "motion"
|
|
311
|
+
WHEN_DARK = "always"
|
|
312
|
+
MANUAL = "off"
|
|
313
|
+
SCHEDULE = "schedule"
|
|
314
|
+
|
|
315
|
+
|
|
316
|
+
@enum.unique
|
|
317
|
+
class VideoMode(str, ValuesEnumMixin, enum.Enum):
|
|
318
|
+
DEFAULT = "default"
|
|
319
|
+
HIGH_FPS = "highFps"
|
|
320
|
+
HOMEKIT = "homekit"
|
|
321
|
+
SPORT = "sport"
|
|
322
|
+
SLOW_SHUTTER = "slowShutter"
|
|
323
|
+
# should only be for unadopted devices
|
|
324
|
+
UNKNOWN = "unknown"
|
|
325
|
+
|
|
326
|
+
|
|
327
|
+
@enum.unique
|
|
328
|
+
class AudioStyle(str, UnknownValuesEnumMixin, enum.Enum):
|
|
329
|
+
NATURE = "nature"
|
|
330
|
+
NOISE_REDUCED = "noiseReduced"
|
|
331
|
+
|
|
332
|
+
|
|
333
|
+
@enum.unique
|
|
334
|
+
class RecordingMode(str, ValuesEnumMixin, enum.Enum):
|
|
335
|
+
ALWAYS = "always"
|
|
336
|
+
NEVER = "never"
|
|
337
|
+
SCHEDULE = "schedule"
|
|
338
|
+
DETECTIONS = "detections"
|
|
339
|
+
|
|
340
|
+
|
|
341
|
+
@enum.unique
|
|
342
|
+
class AnalyticsOption(str, ValuesEnumMixin, enum.Enum):
|
|
343
|
+
NONE = "none"
|
|
344
|
+
ANONYMOUS = "anonymous"
|
|
345
|
+
FULL = "full"
|
|
346
|
+
|
|
347
|
+
|
|
348
|
+
@enum.unique
|
|
349
|
+
class RecordingType(str, ValuesEnumMixin, enum.Enum):
|
|
350
|
+
TIMELAPSE = "timelapse"
|
|
351
|
+
CONTINUOUS = "rotating"
|
|
352
|
+
DETECTIONS = "detections"
|
|
353
|
+
|
|
354
|
+
|
|
355
|
+
@enum.unique
|
|
356
|
+
class ResolutionStorageType(str, ValuesEnumMixin, enum.Enum):
|
|
357
|
+
UHD = "4K"
|
|
358
|
+
HD = "HD"
|
|
359
|
+
FREE = "free"
|
|
360
|
+
|
|
361
|
+
|
|
362
|
+
@enum.unique
|
|
363
|
+
class IRLEDMode(str, UnknownValuesEnumMixin, enum.Enum):
|
|
364
|
+
AUTO = "auto"
|
|
365
|
+
ON = "on"
|
|
366
|
+
AUTO_NO_LED = "autoFilterOnly"
|
|
367
|
+
OFF = "off"
|
|
368
|
+
MANUAL = "manual"
|
|
369
|
+
CUSTOM = "custom"
|
|
370
|
+
UNKNOWN = "unknown"
|
|
371
|
+
|
|
372
|
+
|
|
373
|
+
@enum.unique
|
|
374
|
+
class MountType(str, ValuesEnumMixin, enum.Enum):
|
|
375
|
+
NONE = "none"
|
|
376
|
+
LEAK = "leak"
|
|
377
|
+
DOOR = "door"
|
|
378
|
+
WINDOW = "window"
|
|
379
|
+
GARAGE = "garage"
|
|
380
|
+
|
|
381
|
+
|
|
382
|
+
@enum.unique
|
|
383
|
+
class SensorType(str, ValuesEnumMixin, enum.Enum):
|
|
384
|
+
TEMPERATURE = "temperature"
|
|
385
|
+
LIGHT = "light"
|
|
386
|
+
HUMIDITY = "humidity"
|
|
387
|
+
|
|
388
|
+
|
|
389
|
+
@enum.unique
|
|
390
|
+
class SensorStatusType(str, UnknownValuesEnumMixin, enum.Enum):
|
|
391
|
+
OFFLINE = "offline"
|
|
392
|
+
UNKNOWN = "unknown"
|
|
393
|
+
SAFE = "safe"
|
|
394
|
+
NEUTRAL = "neutral"
|
|
395
|
+
LOW = "low"
|
|
396
|
+
HIGH = "high"
|
|
397
|
+
|
|
398
|
+
|
|
399
|
+
@enum.unique
|
|
400
|
+
class SleepStateType(str, ValuesEnumMixin, enum.Enum):
|
|
401
|
+
DISCONNECTED = "disconnected"
|
|
402
|
+
AWAKE = "awake"
|
|
403
|
+
START_SLEEP = "goingToSleep"
|
|
404
|
+
ASLEEP = "asleep"
|
|
405
|
+
WAKING = "waking"
|
|
406
|
+
|
|
407
|
+
|
|
408
|
+
@enum.unique
|
|
409
|
+
class AutoExposureMode(str, ValuesEnumMixin, enum.Enum):
|
|
410
|
+
MANUAL = "manual"
|
|
411
|
+
AUTO = "auto"
|
|
412
|
+
SHUTTER = "shutter"
|
|
413
|
+
FLICK50 = "flick50"
|
|
414
|
+
FLICK60 = "flick60"
|
|
415
|
+
|
|
416
|
+
|
|
417
|
+
@enum.unique
|
|
418
|
+
class FocusMode(str, ValuesEnumMixin, enum.Enum):
|
|
419
|
+
MANUAL = "manual"
|
|
420
|
+
AUTO = "auto"
|
|
421
|
+
ZTRIG = "ztrig"
|
|
422
|
+
TOUCH = "touch"
|
|
423
|
+
|
|
424
|
+
|
|
425
|
+
@enum.unique
|
|
426
|
+
class MountPosition(str, UnknownValuesEnumMixin, enum.Enum):
|
|
427
|
+
CEILING = "ceiling"
|
|
428
|
+
WALL = "wall"
|
|
429
|
+
DESK = "desk"
|
|
430
|
+
NONE = "none"
|
|
431
|
+
UNKNOWN = "unknown"
|
|
432
|
+
|
|
433
|
+
|
|
434
|
+
@enum.unique
|
|
435
|
+
class GeofencingSetting(str, ValuesEnumMixin, enum.Enum):
|
|
436
|
+
OFF = "off"
|
|
437
|
+
ALL_AWAY = "allAway"
|
|
438
|
+
|
|
439
|
+
|
|
440
|
+
@enum.unique
|
|
441
|
+
class MotionAlgorithm(str, ValuesEnumMixin, enum.Enum):
|
|
442
|
+
STABLE = "stable"
|
|
443
|
+
ENHANCED = "enhanced"
|
|
444
|
+
|
|
445
|
+
|
|
446
|
+
@enum.unique
|
|
447
|
+
class AudioCodecs(str, ValuesEnumMixin, enum.Enum):
|
|
448
|
+
AAC = "aac"
|
|
449
|
+
VORBIS = "vorbis"
|
|
450
|
+
OPUS = "opus"
|
|
451
|
+
|
|
452
|
+
|
|
453
|
+
@enum.unique
|
|
454
|
+
class LowMedHigh(str, ValuesEnumMixin, enum.Enum):
|
|
455
|
+
LOW = "low"
|
|
456
|
+
MEDIUM = "medium"
|
|
457
|
+
HIGH = "high"
|
|
458
|
+
|
|
459
|
+
|
|
460
|
+
@enum.unique
|
|
461
|
+
class StorageType(str, UnknownValuesEnumMixin, enum.Enum):
|
|
462
|
+
DISK = "hdd"
|
|
463
|
+
RAID = "raid"
|
|
464
|
+
SD_CARD = "sdcard"
|
|
465
|
+
INTERNAL_SSD = "internalSSD"
|
|
466
|
+
UNKNOWN = "UNKNOWN"
|
|
467
|
+
|
|
468
|
+
|
|
469
|
+
@enum.unique
|
|
470
|
+
class FirmwareReleaseChannel(str, ValuesEnumMixin, enum.Enum):
|
|
471
|
+
INTERNAL = "internal"
|
|
472
|
+
ALPHA = "alpha"
|
|
473
|
+
BETA = "beta"
|
|
474
|
+
RELEASE_CANDIDATE = "release-candidate"
|
|
475
|
+
RELEASE = "release"
|
|
476
|
+
|
|
477
|
+
|
|
478
|
+
@enum.unique
|
|
479
|
+
class ChimeType(int, enum.Enum):
|
|
480
|
+
NONE = 0
|
|
481
|
+
MECHANICAL = 300
|
|
482
|
+
DIGITAL = 1000
|
|
483
|
+
|
|
484
|
+
|
|
485
|
+
@enum.unique
|
|
486
|
+
class LockStatusType(str, ValuesEnumMixin, enum.Enum):
|
|
487
|
+
OPEN = "OPEN"
|
|
488
|
+
OPENING = "OPENING"
|
|
489
|
+
CLOSED = "CLOSED"
|
|
490
|
+
CLOSING = "CLOSING"
|
|
491
|
+
JAMMED_WHILE_CLOSING = "JAMMED_WHILE_CLOSING"
|
|
492
|
+
JAMMED_WHILE_OPENING = "JAMMED_WHILE_OPENING"
|
|
493
|
+
FAILED_WHILE_CLOSING = "FAILED_WHILE_CLOSING"
|
|
494
|
+
FAILED_WHILE_OPENING = "FAILED_WHILE_OPENING"
|
|
495
|
+
NOT_CALIBRATED = "NOT_CALIBRATED"
|
|
496
|
+
AUTO_CALIBRATION_IN_PROGRESS = "AUTO_CALIBRATION_IN_PROGRESS"
|
|
497
|
+
CALIBRATION_WAITING_OPEN = "CALIBRATION_WAITING_OPEN"
|
|
498
|
+
CALIBRATION_WAITING_CLOSE = "CALIBRATION_WAITING_CLOSE"
|
|
499
|
+
|
|
500
|
+
|
|
501
|
+
@enum.unique
|
|
502
|
+
class PermissionNode(str, UnknownValuesEnumMixin, enum.Enum):
|
|
503
|
+
CREATE = "create"
|
|
504
|
+
READ = "read"
|
|
505
|
+
WRITE = "write"
|
|
506
|
+
DELETE = "delete"
|
|
507
|
+
READ_MEDIA = "readmedia"
|
|
508
|
+
DELETE_MEDIA = "deletemedia"
|
|
509
|
+
READ_LIVE = "readlive"
|
|
510
|
+
UNKNOWN = "unknown"
|
|
511
|
+
|
|
512
|
+
|
|
513
|
+
@enum.unique
|
|
514
|
+
class HDRMode(str, UnknownValuesEnumMixin, enum.Enum):
|
|
515
|
+
NORMAL = "normal"
|
|
516
|
+
ALWAYS_ON = "superHdr"
|
|
517
|
+
|
|
518
|
+
|
|
519
|
+
@enum.unique
|
|
520
|
+
class LensType(str, enum.Enum):
|
|
521
|
+
NONE = "none"
|
|
522
|
+
FULL_360 = "360"
|
|
523
|
+
WIDE = "wide"
|
|
524
|
+
TELESCOPIC = "tele"
|
|
525
|
+
DLSR_17 = "m43"
|
|
526
|
+
|
|
527
|
+
|
|
528
|
+
class DoorbellText(ConstrainedStr):
|
|
529
|
+
max_length = 30
|
|
530
|
+
|
|
531
|
+
|
|
532
|
+
class ICRCustomValue(ConstrainedInt):
|
|
533
|
+
ge = 0
|
|
534
|
+
le = 10
|
|
535
|
+
|
|
536
|
+
|
|
537
|
+
class ICRLuxValue(ConstrainedInt):
|
|
538
|
+
ge = 1
|
|
539
|
+
le = 30
|
|
540
|
+
|
|
541
|
+
|
|
542
|
+
class LEDLevel(ConstrainedInt):
|
|
543
|
+
ge = 0
|
|
544
|
+
le = 6
|
|
545
|
+
|
|
546
|
+
|
|
547
|
+
class PercentInt(ConstrainedInt):
|
|
548
|
+
ge = 0
|
|
549
|
+
le = 100
|
|
550
|
+
|
|
551
|
+
|
|
552
|
+
class TwoByteInt(ConstrainedInt):
|
|
553
|
+
ge = 1
|
|
554
|
+
le = 255
|
|
555
|
+
|
|
556
|
+
|
|
557
|
+
class PercentFloat(ConstrainedFloat):
|
|
558
|
+
ge = 0
|
|
559
|
+
le = 100
|
|
560
|
+
|
|
561
|
+
|
|
562
|
+
class WDRLevel(ConstrainedInt):
|
|
563
|
+
ge = 0
|
|
564
|
+
le = 3
|
|
565
|
+
|
|
566
|
+
|
|
567
|
+
class ICRSensitivity(ConstrainedInt):
|
|
568
|
+
ge = 0
|
|
569
|
+
le = 3
|
|
570
|
+
|
|
571
|
+
|
|
572
|
+
class Percent(ConstrainedFloat):
|
|
573
|
+
ge = 0
|
|
574
|
+
le = 1
|
|
575
|
+
|
|
576
|
+
|
|
577
|
+
class RepeatTimes(ConstrainedInt):
|
|
578
|
+
ge = 1
|
|
579
|
+
le = 6
|
|
580
|
+
|
|
581
|
+
|
|
582
|
+
class PTZPositionDegree(BaseModel):
|
|
583
|
+
pan: float
|
|
584
|
+
tilt: float
|
|
585
|
+
zoom: int
|
|
586
|
+
|
|
587
|
+
|
|
588
|
+
class PTZPositionSteps(BaseModel):
|
|
589
|
+
focus: int
|
|
590
|
+
pan: int
|
|
591
|
+
tilt: int
|
|
592
|
+
zoom: int
|
|
593
|
+
|
|
594
|
+
|
|
595
|
+
class PTZPosition(BaseModel):
|
|
596
|
+
degree: PTZPositionDegree
|
|
597
|
+
steps: PTZPositionSteps
|
|
598
|
+
|
|
599
|
+
|
|
600
|
+
class PTZPresetPosition(BaseModel):
|
|
601
|
+
pan: int
|
|
602
|
+
tilt: int
|
|
603
|
+
zoom: int
|
|
604
|
+
|
|
605
|
+
|
|
606
|
+
class PTZPreset(BaseModel):
|
|
607
|
+
id: str
|
|
608
|
+
name: str
|
|
609
|
+
slot: int
|
|
610
|
+
ptz: PTZPresetPosition
|
|
611
|
+
|
|
612
|
+
|
|
613
|
+
CoordType = Union[Percent, int, float]
|
|
614
|
+
|
|
615
|
+
|
|
616
|
+
# TODO: fix when upgrading to pydantic v2
|
|
617
|
+
class Color(BaseColor):
|
|
618
|
+
def __eq__(self, o: object) -> bool:
|
|
619
|
+
if isinstance(o, Color):
|
|
620
|
+
return self.as_hex() == o.as_hex()
|
|
621
|
+
|
|
622
|
+
return super().__eq__(o)
|
|
623
|
+
|
|
624
|
+
|
|
625
|
+
class Version(BaseVersion):
|
|
626
|
+
def __str__(self) -> str:
|
|
627
|
+
super_str = super().__str__()
|
|
628
|
+
if self.pre is not None and self.pre[0] == "b":
|
|
629
|
+
super_str = super_str.replace("b", "-beta.")
|
|
630
|
+
return super_str
|