uiprotect 5.0.0__tar.gz → 5.2.0__tar.gz

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.

Files changed (36) hide show
  1. {uiprotect-5.0.0 → uiprotect-5.2.0}/PKG-INFO +1 -1
  2. {uiprotect-5.0.0 → uiprotect-5.2.0}/pyproject.toml +1 -1
  3. {uiprotect-5.0.0 → uiprotect-5.2.0}/src/uiprotect/data/bootstrap.py +2 -3
  4. {uiprotect-5.0.0 → uiprotect-5.2.0}/src/uiprotect/data/devices.py +16 -16
  5. {uiprotect-5.0.0 → uiprotect-5.2.0}/LICENSE +0 -0
  6. {uiprotect-5.0.0 → uiprotect-5.2.0}/README.md +0 -0
  7. {uiprotect-5.0.0 → uiprotect-5.2.0}/src/uiprotect/__init__.py +0 -0
  8. {uiprotect-5.0.0 → uiprotect-5.2.0}/src/uiprotect/__main__.py +0 -0
  9. {uiprotect-5.0.0 → uiprotect-5.2.0}/src/uiprotect/api.py +0 -0
  10. {uiprotect-5.0.0 → uiprotect-5.2.0}/src/uiprotect/cli/__init__.py +0 -0
  11. {uiprotect-5.0.0 → uiprotect-5.2.0}/src/uiprotect/cli/backup.py +0 -0
  12. {uiprotect-5.0.0 → uiprotect-5.2.0}/src/uiprotect/cli/base.py +0 -0
  13. {uiprotect-5.0.0 → uiprotect-5.2.0}/src/uiprotect/cli/cameras.py +0 -0
  14. {uiprotect-5.0.0 → uiprotect-5.2.0}/src/uiprotect/cli/chimes.py +0 -0
  15. {uiprotect-5.0.0 → uiprotect-5.2.0}/src/uiprotect/cli/doorlocks.py +0 -0
  16. {uiprotect-5.0.0 → uiprotect-5.2.0}/src/uiprotect/cli/events.py +0 -0
  17. {uiprotect-5.0.0 → uiprotect-5.2.0}/src/uiprotect/cli/lights.py +0 -0
  18. {uiprotect-5.0.0 → uiprotect-5.2.0}/src/uiprotect/cli/liveviews.py +0 -0
  19. {uiprotect-5.0.0 → uiprotect-5.2.0}/src/uiprotect/cli/nvr.py +0 -0
  20. {uiprotect-5.0.0 → uiprotect-5.2.0}/src/uiprotect/cli/sensors.py +0 -0
  21. {uiprotect-5.0.0 → uiprotect-5.2.0}/src/uiprotect/cli/viewers.py +0 -0
  22. {uiprotect-5.0.0 → uiprotect-5.2.0}/src/uiprotect/data/__init__.py +0 -0
  23. {uiprotect-5.0.0 → uiprotect-5.2.0}/src/uiprotect/data/base.py +0 -0
  24. {uiprotect-5.0.0 → uiprotect-5.2.0}/src/uiprotect/data/convert.py +0 -0
  25. {uiprotect-5.0.0 → uiprotect-5.2.0}/src/uiprotect/data/nvr.py +0 -0
  26. {uiprotect-5.0.0 → uiprotect-5.2.0}/src/uiprotect/data/types.py +0 -0
  27. {uiprotect-5.0.0 → uiprotect-5.2.0}/src/uiprotect/data/user.py +0 -0
  28. {uiprotect-5.0.0 → uiprotect-5.2.0}/src/uiprotect/data/websocket.py +0 -0
  29. {uiprotect-5.0.0 → uiprotect-5.2.0}/src/uiprotect/exceptions.py +0 -0
  30. {uiprotect-5.0.0 → uiprotect-5.2.0}/src/uiprotect/py.typed +0 -0
  31. {uiprotect-5.0.0 → uiprotect-5.2.0}/src/uiprotect/release_cache.json +0 -0
  32. {uiprotect-5.0.0 → uiprotect-5.2.0}/src/uiprotect/stream.py +0 -0
  33. {uiprotect-5.0.0 → uiprotect-5.2.0}/src/uiprotect/test_util/__init__.py +0 -0
  34. {uiprotect-5.0.0 → uiprotect-5.2.0}/src/uiprotect/test_util/anonymize.py +0 -0
  35. {uiprotect-5.0.0 → uiprotect-5.2.0}/src/uiprotect/utils.py +0 -0
  36. {uiprotect-5.0.0 → uiprotect-5.2.0}/src/uiprotect/websocket.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: uiprotect
3
- Version: 5.0.0
3
+ Version: 5.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
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "uiprotect"
3
- version = "5.0.0"
3
+ version = "5.2.0"
4
4
  description = "Python API for Unifi Protect (Unofficial)"
5
5
  authors = ["UI Protect Maintainers <ui@koston.org>"]
6
6
  readme = "README.md"
@@ -4,7 +4,6 @@ from __future__ import annotations
4
4
 
5
5
  import asyncio
6
6
  import logging
7
- from copy import deepcopy
8
7
  from dataclasses import dataclass
9
8
  from datetime import datetime
10
9
  from typing import TYPE_CHECKING, Any
@@ -399,7 +398,7 @@ class Bootstrap(ProtectBaseObject):
399
398
  return None
400
399
 
401
400
  old_nvr = self.nvr.copy()
402
- self.nvr = self.nvr.update_from_dict(deepcopy(data))
401
+ self.nvr = self.nvr.update_from_dict(data)
403
402
 
404
403
  return WSSubscriptionMessage(
405
404
  action=WSAction.UPDATE,
@@ -455,7 +454,7 @@ class Bootstrap(ProtectBaseObject):
455
454
  return None
456
455
 
457
456
  old_obj = obj.copy()
458
- obj = obj.update_from_dict(deepcopy(data))
457
+ obj = obj.update_from_dict(data)
459
458
 
460
459
  if model_type is ModelType.EVENT:
461
460
  if TYPE_CHECKING:
@@ -1090,11 +1090,12 @@ class Camera(ProtectMotionDeviceModel):
1090
1090
  return updated
1091
1091
 
1092
1092
  def update_from_dict(self, data: dict[str, Any]) -> Camera:
1093
- # a message in the past is actually a singal to wipe the message
1094
- reset_at = data.get("lcd_message", {}).get("reset_at")
1095
- if reset_at is not None:
1096
- reset_at = from_js_time(reset_at)
1097
- if utc_now() > reset_at:
1093
+ # a message in the past is actually a signal to wipe the message
1094
+ if (reset_at := data.get("lcd_message", {}).get("reset_at")) is not None:
1095
+ if utc_now() > from_js_time(reset_at):
1096
+ # Important: Make a copy of the data before modifying it
1097
+ # since unifi_dict_to_dict will otherwise report incorrect changes
1098
+ data = data.copy()
1098
1099
  data["lcd_message"] = None
1099
1100
 
1100
1101
  return super().update_from_dict(data)
@@ -1134,11 +1135,9 @@ class Camera(ProtectMotionDeviceModel):
1134
1135
  smart_type: SmartDetectObjectType,
1135
1136
  ) -> Event | None:
1136
1137
  """Get the last smart detect event for given type."""
1137
- event_id = self.last_smart_detect_event_ids.get(smart_type)
1138
- if event_id is None:
1139
- return None
1140
-
1141
- return self._api.bootstrap.events.get(event_id)
1138
+ if event_id := self.last_smart_detect_event_ids.get(smart_type):
1139
+ return self._api.bootstrap.events.get(event_id)
1140
+ return None
1142
1141
 
1143
1142
  @property
1144
1143
  def last_smart_audio_detect_event(self) -> Event | None:
@@ -1222,19 +1221,20 @@ class Camera(ProtectMotionDeviceModel):
1222
1221
  """Get active smart detection types."""
1223
1222
  if self.use_global:
1224
1223
  return set(self.smart_detect_settings.object_types).intersection(
1225
- self.feature_flags.smart_detect_types,
1224
+ self.feature_flags.smart_detect_types
1226
1225
  )
1227
1226
  return set(self.smart_detect_settings.object_types)
1228
1227
 
1229
1228
  @property
1230
1229
  def active_audio_detect_types(self) -> set[SmartDetectAudioType]:
1231
1230
  """Get active audio detection types."""
1231
+ if not (enabled_audio_types := self.smart_detect_settings.audio_types):
1232
+ return set()
1232
1233
  if self.use_global:
1233
- return set(self.smart_detect_settings.audio_types or []).intersection(
1234
- self.feature_flags.smart_detect_audio_types or [],
1235
- )
1236
-
1237
- return set(self.smart_detect_settings.audio_types or [])
1234
+ if not (feature_audio_types := self.feature_flags.smart_detect_audio_types):
1235
+ return set()
1236
+ return set(feature_audio_types).intersection(enabled_audio_types)
1237
+ return set(enabled_audio_types)
1238
1238
 
1239
1239
  @property
1240
1240
  def is_motion_detection_on(self) -> bool:
File without changes
File without changes