lifx-async 4.6.0__py3-none-any.whl → 4.7.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.
lifx/devices/ceiling.py CHANGED
@@ -242,8 +242,12 @@ class CeilingLight(MatrixLight):
242
242
  state = cast(CeilingLightState, self._state)
243
243
  state.uplight_color = uplight_color
244
244
  state.downlight_colors = downlight_colors
245
- state.uplight_is_on = uplight_color.brightness > 0
246
- state.downlight_is_on = any(c.brightness > 0 for c in downlight_colors)
245
+ state.uplight_is_on = bool(
246
+ self.state.power > 0 and uplight_color.brightness > 0
247
+ )
248
+ state.downlight_is_on = bool(
249
+ self.state.power > 0 and any(c.brightness > 0 for c in downlight_colors)
250
+ )
247
251
 
248
252
  @classmethod
249
253
  async def from_ip(
lifx/devices/multizone.py CHANGED
@@ -604,6 +604,8 @@ class MultiZoneLight(Light):
604
604
  colors: list[HSBK],
605
605
  duration: float = 0.0,
606
606
  apply: ExtendedAppReq = ExtendedAppReq.APPLY,
607
+ *,
608
+ fast: bool = False,
607
609
  ) -> None:
608
610
  """Set colors for multiple zones efficiently (up to 82 zones per call).
609
611
 
@@ -615,12 +617,15 @@ class MultiZoneLight(Light):
615
617
  colors: List of HSBK colors to set (max 82)
616
618
  duration: Transition duration in seconds (default 0.0)
617
619
  apply: Application mode (default APPLY)
620
+ fast: If True, send fire-and-forget without waiting for response.
621
+ Use for high-frequency animations (>20 updates/second).
618
622
 
619
623
  Raises:
620
624
  ValueError: If colors list is too long or zone index is invalid
621
625
  LifxDeviceNotFoundError: If device is not connected
622
- LifxTimeoutError: If device does not respond
626
+ LifxTimeoutError: If device does not respond (only when fast=False)
623
627
  LifxUnsupportedCommandError: If device doesn't support this command
628
+ (only when fast=False)
624
629
 
625
630
  Example:
626
631
  ```python
@@ -630,6 +635,11 @@ class MultiZoneLight(Light):
630
635
  for i in range(10)
631
636
  ]
632
637
  await light.set_extended_color_zones(0, colors)
638
+
639
+ # High-speed animation loop
640
+ for frame in animation_frames:
641
+ await light.set_extended_color_zones(0, frame, fast=True)
642
+ await asyncio.sleep(0.033) # ~30 FPS
633
643
  ```
634
644
  """
635
645
  if zone_index < 0:
@@ -637,7 +647,9 @@ class MultiZoneLight(Light):
637
647
  if len(colors) > 82:
638
648
  raise ValueError(f"Too many colors: {len(colors)} (max 82 per request)")
639
649
  if len(colors) == 0:
640
- raise ValueError("Colors list cannot be empty") # Convert to protocol HSBK
650
+ raise ValueError("Colors list cannot be empty")
651
+
652
+ # Convert to protocol HSBK
641
653
  protocol_colors = [color.to_protocol() for color in colors]
642
654
 
643
655
  # Pad to 82 colors if needed
@@ -647,17 +659,25 @@ class MultiZoneLight(Light):
647
659
  # Convert duration to milliseconds
648
660
  duration_ms = int(duration * 1000)
649
661
 
650
- # Send request
651
- result = await self.connection.request(
652
- packets.MultiZone.SetExtendedColorZones(
653
- duration=duration_ms,
654
- apply=apply,
655
- index=zone_index,
656
- colors_count=len(colors),
657
- colors=protocol_colors,
658
- ),
662
+ packet = packets.MultiZone.SetExtendedColorZones(
663
+ duration=duration_ms,
664
+ apply=apply,
665
+ index=zone_index,
666
+ colors_count=len(colors),
667
+ colors=protocol_colors,
659
668
  )
660
- self._raise_if_unhandled(result)
669
+
670
+ if fast:
671
+ # Fire-and-forget: no ack, no response, no waiting
672
+ await self.connection.send_packet(
673
+ packet,
674
+ ack_required=False,
675
+ res_required=False,
676
+ )
677
+ else:
678
+ # Standard: wait for response and check for errors
679
+ result = await self.connection.request(packet)
680
+ self._raise_if_unhandled(result)
661
681
 
662
682
  _LOGGER.debug(
663
683
  {
@@ -678,6 +698,7 @@ class MultiZoneLight(Light):
678
698
  ],
679
699
  "duration": duration_ms,
680
700
  "apply": apply.name,
701
+ "fast": fast,
681
702
  },
682
703
  }
683
704
  )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: lifx-async
3
- Version: 4.6.0
3
+ Version: 4.7.0
4
4
  Summary: A modern, type-safe, async Python library for controlling LIFX lights
5
5
  Author-email: Avi Miller <me@dje.li>
6
6
  Maintainer-email: Avi Miller <me@dje.li>
@@ -6,12 +6,12 @@ lifx/exceptions.py,sha256=pikAMppLn7gXyjiQVWM_tSvXKNh-g366nG_UWyqpHhc,815
6
6
  lifx/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
7
  lifx/devices/__init__.py,sha256=4b5QtO0EFWxIqN2lUYgM8uLjWyHI5hUcReiF9QCjCGw,1061
8
8
  lifx/devices/base.py,sha256=0G2PCJRNeIPkMCIw68x0ijn6gUIwh2jFlex8SN4Hs1Y,63530
9
- lifx/devices/ceiling.py,sha256=Y4lwLWyQr8KtrwX3FMo3R_WKBn7CBxk-pNUsjfPXLgk,32981
9
+ lifx/devices/ceiling.py,sha256=qXZeTGAnPbKpnMyEOI2DsffC9HddmWzsW_Q_Fnkpwkw,33087
10
10
  lifx/devices/hev.py,sha256=T5hvt2q_vdgPBvThx_-M7n5pZu9pL0y9Fs3Zz_KL0NM,15588
11
11
  lifx/devices/infrared.py,sha256=ePk9qxX_s-hv5gQMvio1Vv8FYiCd68HF0ySbWgSrvuU,8130
12
12
  lifx/devices/light.py,sha256=gk92lhViUWINGaxDWbs4qn8Stnn2fGCfRkC5Kk0Q-hI,34087
13
13
  lifx/devices/matrix.py,sha256=AVNM2071NFtPg3Eq7kZ3asRGus36He02iDDvIa8RaQ0,41951
14
- lifx/devices/multizone.py,sha256=8OJ6zP5xgSCmlMQDj2mLUZ352EMkbYMbDZ1X-Cux7AU,32786
14
+ lifx/devices/multizone.py,sha256=zQj0qKxWccHAmkIpqIcGzZsKjCQL-_bAquz78o0Izng,33570
15
15
  lifx/effects/__init__.py,sha256=4DF31yp7RJic5JoltMlz5dCtF5KQobU6NOUtLUKkVKE,1509
16
16
  lifx/effects/base.py,sha256=YO0Hbg2VYHKPtfYnWxmrtzYoPGOi9BUXhn8HVFKv5IM,10283
17
17
  lifx/effects/colorloop.py,sha256=kuuyENJS2irAN8vZAFsDa2guQdDbmmc4PJNiyZTfFPE,15840
@@ -42,7 +42,7 @@ lifx/theme/canvas.py,sha256=4h7lgN8iu_OdchObGDgbxTqQLCb-FRKC-M-YCWef_i4,8048
42
42
  lifx/theme/generators.py,sha256=nq3Yvntq_h-eFHbmmow3LcAdA_hEbRRaP5mv9Bydrjk,6435
43
43
  lifx/theme/library.py,sha256=tKlKZNqJp8lRGDnilWyDm_Qr1vCRGGwuvWVS82anNpQ,21326
44
44
  lifx/theme/theme.py,sha256=qMEx_8E41C0Cc6f083XHiAXEglTv4YlXW0UFsG1rQKg,5521
45
- lifx_async-4.6.0.dist-info/METADATA,sha256=MONJFD1mggSLhTieobasroj1mECAgXBS2IndKq9Poq0,2609
46
- lifx_async-4.6.0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
47
- lifx_async-4.6.0.dist-info/licenses/LICENSE,sha256=eBz48GRA3gSiWn3rYZAz2Ewp35snnhV9cSqkVBq7g3k,1832
48
- lifx_async-4.6.0.dist-info/RECORD,,
45
+ lifx_async-4.7.0.dist-info/METADATA,sha256=msfJopOW0E5xcAV6WciD_JgaZy7PRmxza_e9KOnUNUE,2609
46
+ lifx_async-4.7.0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
47
+ lifx_async-4.7.0.dist-info/licenses/LICENSE,sha256=eBz48GRA3gSiWn3rYZAz2Ewp35snnhV9cSqkVBq7g3k,1832
48
+ lifx_async-4.7.0.dist-info/RECORD,,