lifx-async 4.7.1__py3-none-any.whl → 4.7.3__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/api.py CHANGED
@@ -126,8 +126,9 @@ class DeviceGroup:
126
126
  exc_val: BaseException | None,
127
127
  exc_tb: TracebackType | None,
128
128
  ) -> None:
129
- """Exit async context manager."""
130
- pass
129
+ """Exit async context manager and close all device connections."""
130
+ for device in self._devices:
131
+ await device.connection.close()
131
132
 
132
133
  def __iter__(
133
134
  self,
lifx/devices/ceiling.py CHANGED
@@ -23,16 +23,13 @@ import logging
23
23
  import time
24
24
  from dataclasses import asdict, dataclass
25
25
  from pathlib import Path
26
- from typing import TYPE_CHECKING, Any, cast
26
+ from typing import Any, cast
27
27
 
28
28
  from lifx.color import HSBK
29
29
  from lifx.devices.matrix import MatrixLight, MatrixLightState
30
30
  from lifx.exceptions import LifxError
31
31
  from lifx.products import get_ceiling_layout, is_ceiling_product
32
32
 
33
- if TYPE_CHECKING:
34
- pass
35
-
36
33
  _LOGGER = logging.getLogger(__name__)
37
34
 
38
35
 
@@ -622,6 +619,65 @@ class CeilingLight(MatrixLight):
622
619
  determined_colors = await self._determine_downlight_brightness()
623
620
  await self.set_downlight_colors(determined_colors, duration)
624
621
 
622
+ async def set_power(self, level: bool | int, duration: float = 0.0) -> None:
623
+ """Set light power state, capturing component colors before turning off.
624
+
625
+ Overrides Light.set_power() to capture the current uplight and downlight
626
+ colors before turning off the entire light. This allows subsequent calls
627
+ to turn_uplight_on() or turn_downlight_on() to restore the colors that
628
+ were active just before the light was turned off.
629
+
630
+ The captured colors preserve hue, saturation, and kelvin values even if
631
+ a component was already off (brightness=0). The brightness will be
632
+ determined at turn-on time using the standard brightness inference logic.
633
+
634
+ Args:
635
+ level: True/65535 to turn on, False/0 to turn off
636
+ duration: Transition duration in seconds (default 0.0)
637
+
638
+ Raises:
639
+ ValueError: If integer value is not 0 or 65535
640
+ LifxDeviceNotFoundError: If device is not connected
641
+ LifxTimeoutError: If device does not respond
642
+ LifxUnsupportedCommandError: If device doesn't support this command
643
+
644
+ Example:
645
+ ```python
646
+ # Turn off entire ceiling light (captures colors for later)
647
+ await ceiling.set_power(False)
648
+
649
+ # Later, turn on just the uplight with its previous color
650
+ await ceiling.turn_uplight_on()
651
+
652
+ # Or turn on just the downlight with its previous colors
653
+ await ceiling.turn_downlight_on()
654
+ ```
655
+ """
656
+ # Determine if we're turning off
657
+ if isinstance(level, bool):
658
+ turning_off = not level
659
+ elif isinstance(level, int):
660
+ if level not in (0, 65535):
661
+ raise ValueError(f"Power level must be 0 or 65535, got {level}")
662
+ turning_off = level == 0
663
+ else:
664
+ raise TypeError(f"Expected bool or int, got {type(level).__name__}")
665
+
666
+ # If turning off, capture current colors for both components
667
+ if turning_off:
668
+ # Always capture colors - even if brightness is 0, the hue/sat/kelvin
669
+ # are still useful for turn_on. Brightness will be determined at
670
+ # turn-on time using the standard inference logic.
671
+ self._stored_uplight_state = await self.get_uplight_color()
672
+ self._stored_downlight_state = await self.get_downlight_colors()
673
+
674
+ # Persist if enabled
675
+ if self._state_file:
676
+ self._save_state_to_file()
677
+
678
+ # Call parent to perform actual power change
679
+ await super().set_power(level, duration)
680
+
625
681
  async def turn_downlight_off(
626
682
  self, colors: HSBK | list[HSBK] | None = None, duration: float = 0.0
627
683
  ) -> None:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: lifx-async
3
- Version: 4.7.1
3
+ Version: 4.7.3
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>
@@ -1,12 +1,12 @@
1
1
  lifx/__init__.py,sha256=aiMLKLhmcXADJyeISNHIZ_Nuc6jEhPG8-I_R3peWpwo,2610
2
- lifx/api.py,sha256=PFS2b28ow40kCQvT_MKvBLZD6fKCbvsoOQFtiODDrPE,33861
2
+ lifx/api.py,sha256=XV2CJLi3N9UpbZuqVE56K-MEsSaqOte9WhcBbhkmHQM,33962
3
3
  lifx/color.py,sha256=wcmeeiBmOAjunInERNd6rslKvBEpV4vfjwwiZ8v7H8A,17877
4
4
  lifx/const.py,sha256=cf_O_3TqJjIBXF1tI35PkJ1JOhmy4tRt14PSa63pilA,3471
5
5
  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=qXZeTGAnPbKpnMyEOI2DsffC9HddmWzsW_Q_Fnkpwkw,33087
9
+ lifx/devices/ceiling.py,sha256=q1aVqnYA0C32-c2J6GaYriaqgam9pKkSvV8IVVsIOf0,35661
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
@@ -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.7.1.dist-info/METADATA,sha256=Zrtws6NJBuCkoGw4dUBUJ6IPG2c5JW_BLJeKALgYY6U,2609
46
- lifx_async-4.7.1.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
47
- lifx_async-4.7.1.dist-info/licenses/LICENSE,sha256=eBz48GRA3gSiWn3rYZAz2Ewp35snnhV9cSqkVBq7g3k,1832
48
- lifx_async-4.7.1.dist-info/RECORD,,
45
+ lifx_async-4.7.3.dist-info/METADATA,sha256=SruPlVJQdCTtWKsJHzQDYpgJooaDxgfP2KiVF1XyPZY,2609
46
+ lifx_async-4.7.3.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
47
+ lifx_async-4.7.3.dist-info/licenses/LICENSE,sha256=eBz48GRA3gSiWn3rYZAz2Ewp35snnhV9cSqkVBq7g3k,1832
48
+ lifx_async-4.7.3.dist-info/RECORD,,