uiprotect 0.11.0__py3-none-any.whl → 0.12.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.

@@ -18,7 +18,7 @@ except ImportError:
18
18
  from pydantic import PrivateAttr, ValidationError # type: ignore[assignment]
19
19
 
20
20
  from ..exceptions import ClientError
21
- from ..utils import utc_now
21
+ from ..utils import normalize_mac, utc_now
22
22
  from .base import (
23
23
  RECENT_EVENT_MAX,
24
24
  ProtectBaseObject,
@@ -226,7 +226,7 @@ class Bootstrap(ProtectBaseObject):
226
226
  items[item["id"]] = item
227
227
  data["idLookup"][item["id"]] = ref
228
228
  if "mac" in item:
229
- cleaned_mac = item["mac"].lower().replace(":", "")
229
+ cleaned_mac = normalize_mac(item["mac"])
230
230
  data["macLookup"][cleaned_mac] = ref
231
231
  data[key] = items
232
232
 
@@ -312,8 +312,7 @@ class Bootstrap(ProtectBaseObject):
312
312
 
313
313
  def get_device_from_mac(self, mac: str) -> ProtectAdoptableDeviceModel | None:
314
314
  """Retrieve a device from MAC address."""
315
- mac = mac.lower().replace(":", "").replace("-", "").replace("_", "")
316
- ref = self.mac_lookup.get(mac)
315
+ ref = self.mac_lookup.get(normalize_mac(mac))
317
316
  if ref is None:
318
317
  return None
319
318
 
@@ -378,7 +377,7 @@ class Bootstrap(ProtectBaseObject):
378
377
  elif (
379
378
  isinstance(obj, ProtectAdoptableDeviceModel)
380
379
  and obj.model is not None
381
- and obj.model.value in ModelType.bootstrap_models()
380
+ and obj.model.value in ModelType.bootstrap_models_set()
382
381
  ):
383
382
  key = obj.model.value + "s"
384
383
  if not self.api.ignore_unadopted or (
@@ -387,7 +386,7 @@ class Bootstrap(ProtectBaseObject):
387
386
  getattr(self, key)[obj.id] = obj
388
387
  ref = ProtectDeviceRef(model=obj.model, id=obj.id)
389
388
  self.id_lookup[obj.id] = ref
390
- self.mac_lookup[obj.mac.lower().replace(":", "")] = ref
389
+ self.mac_lookup[normalize_mac(obj.mac)] = ref
391
390
  else:
392
391
  _LOGGER.debug("Unexpected bootstrap model type for add: %s", obj.model)
393
392
  return None
@@ -403,23 +402,19 @@ class Bootstrap(ProtectBaseObject):
403
402
  new_obj=obj,
404
403
  )
405
404
 
406
- def _process_remove_packet(
407
- self,
408
- packet: WSPacket,
409
- data: dict[str, Any] | None,
410
- ) -> WSSubscriptionMessage | None:
411
- model = packet.action_frame.data.get("modelKey")
412
- device_id = packet.action_frame.data.get("id")
405
+ def _process_remove_packet(self, packet: WSPacket) -> WSSubscriptionMessage | None:
406
+ model: str | None = packet.action_frame.data.get("modelKey")
413
407
  devices = getattr(self, f"{model}s", None)
414
408
 
415
409
  if devices is None:
416
410
  return None
417
411
 
412
+ device_id: str = packet.action_frame.data["id"]
418
413
  self.id_lookup.pop(device_id, None)
419
414
  device = devices.pop(device_id, None)
420
415
  if device is None:
421
416
  return None
422
- self.mac_lookup.pop(device.mac.lower().replace(":", ""), None)
417
+ self.mac_lookup.pop(normalize_mac(device.mac), None)
423
418
 
424
419
  self._create_stat(packet, None, False)
425
420
  return WSSubscriptionMessage(
@@ -489,12 +484,11 @@ class Bootstrap(ProtectBaseObject):
489
484
 
490
485
  key = f"{model_type}s"
491
486
  devices = getattr(self, key)
492
- if action["id"] in devices:
493
- if action["id"] not in devices:
494
- raise ValueError(
495
- f"Unknown device update for {model_type}: { action['id']}",
496
- )
497
- obj: ProtectModelWithId = devices[action["id"]]
487
+ action_id: str = action["id"]
488
+ if action_id in devices:
489
+ if action_id not in devices:
490
+ raise ValueError(f"Unknown device update for {model_type}: {action_id}")
491
+ obj: ProtectModelWithId = devices[action_id]
498
492
  data = obj.unifi_dict_to_dict(data)
499
493
  old_obj = obj.copy()
500
494
  obj = obj.update_from_dict(deepcopy(data))
@@ -517,7 +511,7 @@ class Bootstrap(ProtectBaseObject):
517
511
  if is_recent:
518
512
  obj.set_alarm_timeout()
519
513
 
520
- devices[action["id"]] = obj
514
+ devices[action_id] = obj
521
515
 
522
516
  self._create_stat(packet, data, False)
523
517
  return WSSubscriptionMessage(
@@ -529,8 +523,8 @@ class Bootstrap(ProtectBaseObject):
529
523
  )
530
524
 
531
525
  # ignore updates to events that phase out
532
- if model_type != ModelType.EVENT.value:
533
- _LOGGER.debug("Unexpected %s: %s", key, action["id"])
526
+ if model_type != _ModelType_Event_value:
527
+ _LOGGER.debug("Unexpected %s: %s", key, action_id)
534
528
  return None
535
529
 
536
530
  def process_ws_packet(
@@ -557,7 +551,7 @@ class Bootstrap(ProtectBaseObject):
557
551
 
558
552
  action_action: str = action["action"]
559
553
  if action_action == "remove":
560
- return self._process_remove_packet(packet, data)
554
+ return self._process_remove_packet(packet)
561
555
 
562
556
  if not data:
563
557
  self._create_stat(packet, None, True)
@@ -596,7 +590,7 @@ class Bootstrap(ProtectBaseObject):
596
590
  else:
597
591
  try:
598
592
  model_type = ModelType(action["modelKey"])
599
- device_id = action["id"]
593
+ device_id: str = action["id"]
600
594
  task = asyncio.create_task(self.refresh_device(model_type, device_id))
601
595
  self._refresh_tasks.add(task)
602
596
  task.add_done_callback(self._refresh_tasks.discard)
uiprotect/utils.py CHANGED
@@ -624,3 +624,9 @@ def clamp_value(value: float, step_size: float) -> float:
624
624
  """Clamps value to multiples of step size."""
625
625
  ratio = 1 / step_size
626
626
  return int(value * ratio) / ratio
627
+
628
+
629
+ @lru_cache(maxsize=1024)
630
+ def normalize_mac(mac: str) -> str:
631
+ """Normalize MAC address."""
632
+ return mac.lower().replace(":", "").replace("-", "").replace("_", "")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: uiprotect
3
- Version: 0.11.0
3
+ Version: 0.12.0
4
4
  Summary: Python API for Unifi Protect (Unofficial)
5
5
  Home-page: https://github.com/uilibs/uiprotect
6
6
  License: MIT
@@ -15,7 +15,7 @@ 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=ex-UC9CJUtzxMFqtYokSiXM8pNHVBqCzq7r8WrEf1Mw,37178
18
- uiprotect/data/bootstrap.py,sha256=e84W72zg6MZCgaYEunr6CCvd5b7Hb-GDSDEvfEGEt0Y,21556
18
+ uiprotect/data/bootstrap.py,sha256=RcqIiIk8z5QKDMnrWB7ZZDlBouesx2xQGN02wEl-B9s,21416
19
19
  uiprotect/data/convert.py,sha256=rOQplUMIdTMD2SbAx_iI9BNPDscnhDvyRVLEMDhtADg,2047
20
20
  uiprotect/data/devices.py,sha256=LHVBT8ihMAZen7gIlQNbiYxukRrBpi_TNKNmV_5R6Xc,111705
21
21
  uiprotect/data/nvr.py,sha256=OJso6oewA_jY7ovKbD2U2Onp1GqheT5bCW0F6dC53DQ,47570
@@ -28,10 +28,10 @@ uiprotect/release_cache.json,sha256=NamnSFy78hOWY0DPO87J9ELFCAN6NnVquv8gQO75ZG4,
28
28
  uiprotect/stream.py,sha256=McV3XymKyjn-1uV5jdQHcpaDjqLS4zWyMASQ8ubcyb4,4924
29
29
  uiprotect/test_util/__init__.py,sha256=d2g7afa0LSdixQ0kjEDYwafDFME_UlW2LzxpamZ2BC0,18556
30
30
  uiprotect/test_util/anonymize.py,sha256=f-8ijU-_y9r-uAbhIPn0f0I6hzJpAkvJzc8UpWihObI,8478
31
- uiprotect/utils.py,sha256=kXEr1xEoPAwUYuVPd6QoVnTf8MQwzQXQQ4JLyJsiRfY,18219
31
+ uiprotect/utils.py,sha256=ItYUrIhCbvdvIO3Q_MI9jQFnFs5OouqfsO_SXWeQZPM,18389
32
32
  uiprotect/websocket.py,sha256=iMTdchymaCgVHsmY1bRbxkcymqt6WQircIHYNxCu178,7289
33
- uiprotect-0.11.0.dist-info/LICENSE,sha256=INx18jhdbVXMEiiBANeKEbrbz57ckgzxk5uutmmcxGk,1111
34
- uiprotect-0.11.0.dist-info/METADATA,sha256=xyc8Jqihak81Xrqx9GhCDmIdJLGT-1CMsTfUDXVWskw,10985
35
- uiprotect-0.11.0.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
36
- uiprotect-0.11.0.dist-info/entry_points.txt,sha256=J78AUTPrTTxgI3s7SVgrmGqDP7piX2wuuEORzhDdVRA,47
37
- uiprotect-0.11.0.dist-info/RECORD,,
33
+ uiprotect-0.12.0.dist-info/LICENSE,sha256=INx18jhdbVXMEiiBANeKEbrbz57ckgzxk5uutmmcxGk,1111
34
+ uiprotect-0.12.0.dist-info/METADATA,sha256=13ADAWhiHnb4kCgVFsioRdR_pYLaGG4vDYQzdDfIcU0,10985
35
+ uiprotect-0.12.0.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
36
+ uiprotect-0.12.0.dist-info/entry_points.txt,sha256=J78AUTPrTTxgI3s7SVgrmGqDP7piX2wuuEORzhDdVRA,47
37
+ uiprotect-0.12.0.dist-info/RECORD,,