pycololight 2.0.0__tar.gz → 2.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.
- pycololight-2.2.0/CHANGELOG.md +73 -0
- {pycololight-2.0.0 → pycololight-2.2.0}/PKG-INFO +10 -16
- {pycololight-2.0.0 → pycololight-2.2.0}/README.md +5 -5
- {pycololight-2.0.0 → pycololight-2.2.0}/pycololight/__init__.py +21 -9
- {pycololight-2.0.0 → pycololight-2.2.0}/pycololight/constants.py +9 -1
- {pycololight-2.0.0 → pycololight-2.2.0}/pycololight/effects.py +15 -15
- pycololight-2.2.0/pycololight/py.typed +0 -0
- {pycololight-2.0.0 → pycololight-2.2.0}/pycololight/pycololight.py +50 -50
- pycololight-2.2.0/pyproject.toml +47 -0
- pycololight-2.2.0/pyproject.toml.orig +43 -0
- pycololight-2.0.0/CHANGELOG.md +0 -52
- pycololight-2.0.0/pyproject.toml +0 -22
- pycololight-2.0.0/setup.py +0 -26
- {pycololight-2.0.0 → pycololight-2.2.0}/LICENSE +0 -0
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## [2.2.0](https://github.com/BazaJayGee66/pycololight/compare/2.1.0...2.2.0) (2026-11-01)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* add full type hints and ship a py.typed marker ([#9](https://github.com/BazaJayGee66/pycololight/issues/9)) ([03da40a](https://github.com/BazaJayGee66/pycololight/commit/03da40a8eb01bdf6e38eb11621ffcc3ac1850f63))
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Bug Fixes
|
|
12
|
+
|
|
13
|
+
* open a socket per call so polls and commands can't share one ([#6](https://github.com/BazaJayGee66/pycololight/issues/6)) ([16aba29](https://github.com/BazaJayGee66/pycololight/commit/16aba298bc8dc8326df326c7f289c2fb74be0efe))
|
|
14
|
+
* report no brightness while the light is off ([#7](https://github.com/BazaJayGee66/pycololight/issues/7)) ([66e38d1](https://github.com/BazaJayGee66/pycololight/commit/66e38d1413d76ba68a7db2200dfc97add92a190e))
|
|
15
|
+
|
|
16
|
+
## 2.1.0
|
|
17
|
+
|
|
18
|
+
### New Features
|
|
19
|
+
|
|
20
|
+
- Add ability to set timeout for device
|
|
21
|
+
|
|
22
|
+
## 2.0.0
|
|
23
|
+
|
|
24
|
+
This release enables support for the cololight strip device.
|
|
25
|
+
|
|
26
|
+
### New Features
|
|
27
|
+
|
|
28
|
+
- Add support for the cololight strip device
|
|
29
|
+
- Add dynamic effects for the cololight strip device
|
|
30
|
+
- Add custom effects for the cololight strip device
|
|
31
|
+
|
|
32
|
+
### Breaking Changes
|
|
33
|
+
|
|
34
|
+
- A device (`hexagon` or `strip`) must now be passed when creating `PyCololight` object
|
|
35
|
+
|
|
36
|
+
## 1.0.0
|
|
37
|
+
|
|
38
|
+
### New Features
|
|
39
|
+
|
|
40
|
+
- Add state to get light state (on/off) and brightness - Thanks [@pim12345](https://github.com/pim12345)
|
|
41
|
+
|
|
42
|
+
### Fixes
|
|
43
|
+
|
|
44
|
+
- Add missing exceptions
|
|
45
|
+
- Add BrightnessException if brightness not between 0 and 100
|
|
46
|
+
- Refactor for simpler code
|
|
47
|
+
- Rename `include_default_effects` to `restore_default_effects`
|
|
48
|
+
- Remove `count` property
|
|
49
|
+
- Add type hints, and docstring
|
|
50
|
+
|
|
51
|
+
## 0.0.2
|
|
52
|
+
|
|
53
|
+
### New Features
|
|
54
|
+
|
|
55
|
+
### Fixes
|
|
56
|
+
|
|
57
|
+
- Refactor for simpler code
|
|
58
|
+
|
|
59
|
+
## 0.0.1
|
|
60
|
+
|
|
61
|
+
Initial Release
|
|
62
|
+
|
|
63
|
+
### New Features
|
|
64
|
+
|
|
65
|
+
- Turn On
|
|
66
|
+
- Turn Off
|
|
67
|
+
- Set brightness
|
|
68
|
+
- Set colour
|
|
69
|
+
- Set effect
|
|
70
|
+
- Include/Exclude default effects
|
|
71
|
+
- Add custom effect
|
|
72
|
+
|
|
73
|
+
### Fixes
|
|
@@ -1,16 +1,11 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: pycololight
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.2.0
|
|
4
4
|
Summary: A Python3 wrapper for interacting with LifeSmart Cololight
|
|
5
|
-
Home-page: https://github.com/BazaJayGee66/pycololight
|
|
6
|
-
License: MIT
|
|
7
5
|
Author: BazaJayGee66
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
Classifier: Programming Language :: Python :: 3.10
|
|
12
|
-
Classifier: Programming Language :: Python :: 3.8
|
|
13
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
License-File: LICENSE
|
|
8
|
+
Requires-Python: >=3.12
|
|
14
9
|
Project-URL: Repository, https://github.com/BazaJayGee66/pycololight
|
|
15
10
|
Description-Content-Type: text/markdown
|
|
16
11
|
|
|
@@ -48,11 +43,11 @@ light.effect = "Sunrise"
|
|
|
48
43
|
|
|
49
44
|
# Create custom effect
|
|
50
45
|
light.add_custom_effect(
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
46
|
+
name="custom effect",
|
|
47
|
+
colour_scheme="Shadow",
|
|
48
|
+
colour="Red, Yellow",
|
|
49
|
+
cycle_speed=11,
|
|
50
|
+
mode=1,
|
|
56
51
|
)
|
|
57
52
|
|
|
58
53
|
# Turn off
|
|
@@ -60,4 +55,3 @@ light.on = 0
|
|
|
60
55
|
```
|
|
61
56
|
|
|
62
57
|
Mapping of modes for custom effects can be found [here](https://github.com/BazaJayGee66/pycololight/blob/main/MODES.md)
|
|
63
|
-
|
|
@@ -32,11 +32,11 @@ light.effect = "Sunrise"
|
|
|
32
32
|
|
|
33
33
|
# Create custom effect
|
|
34
34
|
light.add_custom_effect(
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
35
|
+
name="custom effect",
|
|
36
|
+
colour_scheme="Shadow",
|
|
37
|
+
colour="Red, Yellow",
|
|
38
|
+
cycle_speed=11,
|
|
39
|
+
mode=1,
|
|
40
40
|
)
|
|
41
41
|
|
|
42
42
|
# Turn off
|
|
@@ -1,15 +1,27 @@
|
|
|
1
|
+
from .effects import (
|
|
2
|
+
ColourException,
|
|
3
|
+
ColourSchemeException,
|
|
4
|
+
CycleSpeedException,
|
|
5
|
+
Effects,
|
|
6
|
+
ModeExecption,
|
|
7
|
+
)
|
|
1
8
|
from .pycololight import (
|
|
2
|
-
PyCololight,
|
|
3
|
-
DefaultEffectExecption,
|
|
4
9
|
BrightnessException,
|
|
10
|
+
DefaultEffectExecption,
|
|
11
|
+
PyCololight,
|
|
5
12
|
UnavailableException,
|
|
6
13
|
UnsupportedDeviceException,
|
|
7
14
|
)
|
|
8
15
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
ColourSchemeException,
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
+
__all__ = [
|
|
17
|
+
"BrightnessException",
|
|
18
|
+
"ColourException",
|
|
19
|
+
"ColourSchemeException",
|
|
20
|
+
"CycleSpeedException",
|
|
21
|
+
"DefaultEffectExecption",
|
|
22
|
+
"Effects",
|
|
23
|
+
"ModeExecption",
|
|
24
|
+
"PyCololight",
|
|
25
|
+
"UnavailableException",
|
|
26
|
+
"UnsupportedDeviceException",
|
|
27
|
+
]
|
|
@@ -1,6 +1,14 @@
|
|
|
1
|
+
from typing import TypedDict
|
|
2
|
+
|
|
1
3
|
COMMAND_PREFIX = "535a30300000000000"
|
|
2
4
|
|
|
3
|
-
|
|
5
|
+
|
|
6
|
+
class ColourScheme(TypedDict):
|
|
7
|
+
decimal: int
|
|
8
|
+
colours: tuple[str, ...]
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
CUSTOM_EFFECT_COLOURS: dict[str, ColourScheme] = {
|
|
4
12
|
"Breath": {
|
|
5
13
|
"decimal": 128,
|
|
6
14
|
"colours": (
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
from .constants import (
|
|
2
2
|
CUSTOM_EFFECT_COLOURS,
|
|
3
|
+
DEFAULT_EFFECTS,
|
|
3
4
|
HEXAGON_CUSTOM_EFFECT_MODES,
|
|
4
5
|
STRIP_CUSTOM_EFFECT_MODES,
|
|
5
|
-
DEFAULT_EFFECTS,
|
|
6
6
|
STRIP_DYANMIC_EFFECTS,
|
|
7
7
|
)
|
|
8
8
|
|
|
@@ -28,13 +28,13 @@ class Effects:
|
|
|
28
28
|
Effects for cololight devices
|
|
29
29
|
"""
|
|
30
30
|
|
|
31
|
-
def __init__(self, device) -> None:
|
|
31
|
+
def __init__(self, device: str) -> None:
|
|
32
32
|
self._device = device
|
|
33
33
|
self._default_effects = DEFAULT_EFFECTS.copy()
|
|
34
34
|
self._dynamic_effects = self._device_dynamic_effects()
|
|
35
35
|
self._modes = self._device_modes()
|
|
36
36
|
|
|
37
|
-
def _cycle_speed_hex(self, cycle_speed, mode):
|
|
37
|
+
def _cycle_speed_hex(self, cycle_speed: int, mode: int) -> str:
|
|
38
38
|
if not 1 <= cycle_speed <= 32:
|
|
39
39
|
raise CycleSpeedException
|
|
40
40
|
if mode in [2]:
|
|
@@ -44,10 +44,10 @@ class Effects:
|
|
|
44
44
|
else:
|
|
45
45
|
cycle_speed_value = list(reversed(range(33)))[cycle_speed - 1]
|
|
46
46
|
|
|
47
|
-
cycle_speed_hex = "{:02x}"
|
|
47
|
+
cycle_speed_hex = f"{cycle_speed_value:02x}"
|
|
48
48
|
return cycle_speed_hex
|
|
49
49
|
|
|
50
|
-
def _colour_hex(self, colour_scheme, colour, mode):
|
|
50
|
+
def _colour_hex(self, colour_scheme: str, colour: str, mode: int) -> str:
|
|
51
51
|
if colour_scheme not in self.custom_effect_colour_schemes():
|
|
52
52
|
raise ColourSchemeException
|
|
53
53
|
if colour not in self.custom_effect_colour_scheme_colours(colour_scheme):
|
|
@@ -59,16 +59,16 @@ class Effects:
|
|
|
59
59
|
# These modes have a lower starting decimal of 128
|
|
60
60
|
starting_decimal = starting_decimal - 128
|
|
61
61
|
colour_decimal = starting_decimal + colour_key
|
|
62
|
-
colour_hex = "{:02x}"
|
|
62
|
+
colour_hex = f"{colour_decimal:02x}"
|
|
63
63
|
return colour_hex
|
|
64
64
|
|
|
65
|
-
def _mode_hex(self, mode):
|
|
65
|
+
def _mode_hex(self, mode: int) -> tuple[str, str]:
|
|
66
66
|
if not 1 <= mode <= len(self._modes):
|
|
67
67
|
raise ModeExecption
|
|
68
68
|
|
|
69
69
|
return self._modes[mode - 1]
|
|
70
70
|
|
|
71
|
-
def _device_dynamic_effects(self):
|
|
71
|
+
def _device_dynamic_effects(self) -> dict[str, list[str]]:
|
|
72
72
|
if self._device == "strip":
|
|
73
73
|
dynamic_effects = STRIP_DYANMIC_EFFECTS.copy()
|
|
74
74
|
else:
|
|
@@ -76,7 +76,7 @@ class Effects:
|
|
|
76
76
|
|
|
77
77
|
return dynamic_effects
|
|
78
78
|
|
|
79
|
-
def _device_modes(self):
|
|
79
|
+
def _device_modes(self) -> list[tuple[str, str]]:
|
|
80
80
|
if self._device == "hexagon":
|
|
81
81
|
modes = HEXAGON_CUSTOM_EFFECT_MODES.copy()
|
|
82
82
|
if self._device == "strip":
|
|
@@ -84,7 +84,7 @@ class Effects:
|
|
|
84
84
|
|
|
85
85
|
return modes
|
|
86
86
|
|
|
87
|
-
def _device_mode_lower(self, mode):
|
|
87
|
+
def _device_mode_lower(self, mode: int) -> bool:
|
|
88
88
|
hexagon_lower_modes = [13, 14, 15, 22, 23, 24]
|
|
89
89
|
strip_lower_modes = [10]
|
|
90
90
|
|
|
@@ -96,21 +96,21 @@ class Effects:
|
|
|
96
96
|
return mode in lower_modes
|
|
97
97
|
|
|
98
98
|
@property
|
|
99
|
-
def default_effects(self) -> dict:
|
|
99
|
+
def default_effects(self) -> dict[str, list[str]]:
|
|
100
100
|
"""
|
|
101
101
|
Returns a dict of default effects with names and command hex values for the device.
|
|
102
102
|
"""
|
|
103
103
|
return self._default_effects
|
|
104
104
|
|
|
105
105
|
@property
|
|
106
|
-
def dynamic_effects(self) -> dict:
|
|
106
|
+
def dynamic_effects(self) -> dict[str, list[str]]:
|
|
107
107
|
"""
|
|
108
108
|
Returns a dict of dynamic effects with names and command hex values for the device.
|
|
109
109
|
"""
|
|
110
110
|
return self._dynamic_effects
|
|
111
111
|
|
|
112
112
|
@property
|
|
113
|
-
def effects(self) -> dict:
|
|
113
|
+
def effects(self) -> dict[str, list[str]]:
|
|
114
114
|
"""
|
|
115
115
|
Return a dict of all effects with names and command hex values for the device.
|
|
116
116
|
"""
|
|
@@ -139,13 +139,13 @@ class Effects:
|
|
|
139
139
|
|
|
140
140
|
return custom_effect_hex
|
|
141
141
|
|
|
142
|
-
def custom_effect_colour_schemes(self) -> list:
|
|
142
|
+
def custom_effect_colour_schemes(self) -> list[str]:
|
|
143
143
|
"""
|
|
144
144
|
Returns a list of the available colour schemes for custom efects.
|
|
145
145
|
"""
|
|
146
146
|
return list(CUSTOM_EFFECT_COLOURS.keys())
|
|
147
147
|
|
|
148
|
-
def custom_effect_colour_scheme_colours(self, colour_scheme) -> list:
|
|
148
|
+
def custom_effect_colour_scheme_colours(self, colour_scheme: str) -> list[str]:
|
|
149
149
|
"""
|
|
150
150
|
Returns a list of the available colours for a given colour schemes for custom efects.
|
|
151
151
|
"""
|
|
File without changes
|
|
@@ -29,28 +29,36 @@ class PyCololight:
|
|
|
29
29
|
"""
|
|
30
30
|
|
|
31
31
|
def __init__(
|
|
32
|
-
self,
|
|
33
|
-
|
|
32
|
+
self,
|
|
33
|
+
device: str,
|
|
34
|
+
host: str,
|
|
35
|
+
port: int = 8900,
|
|
36
|
+
timeout: float = 4,
|
|
37
|
+
default_effects: bool = True,
|
|
38
|
+
dynamic_effects: bool = False,
|
|
39
|
+
) -> None:
|
|
34
40
|
self.supported_devices = ["hexagon", "strip"]
|
|
35
41
|
self.device = self._check_supported_devices(device)
|
|
36
42
|
self.host = host
|
|
37
43
|
self.port = port
|
|
44
|
+
self.timeout = timeout
|
|
38
45
|
self._counter = 1
|
|
39
46
|
self._on = False
|
|
40
|
-
self._brightness = None
|
|
41
|
-
self._colour = None
|
|
42
|
-
self._effect = None
|
|
47
|
+
self._brightness: int | None = None
|
|
48
|
+
self._colour: tuple[int, int, int] | None = None
|
|
49
|
+
self._effect: str | None = None
|
|
43
50
|
self._device_effects = Effects(device)
|
|
44
51
|
self._effects = self._initial_effects(default_effects, dynamic_effects)
|
|
45
|
-
self._sock = None
|
|
46
52
|
|
|
47
|
-
def _check_supported_devices(self, device):
|
|
53
|
+
def _check_supported_devices(self, device: str) -> str:
|
|
48
54
|
if device not in self.supported_devices:
|
|
49
55
|
raise UnsupportedDeviceException
|
|
50
56
|
else:
|
|
51
57
|
return device
|
|
52
58
|
|
|
53
|
-
def _initial_effects(
|
|
59
|
+
def _initial_effects(
|
|
60
|
+
self, default_effects: bool, dynamic_effects: bool
|
|
61
|
+
) -> dict[str, list[str]]:
|
|
54
62
|
initial_effects = {}
|
|
55
63
|
|
|
56
64
|
if default_effects:
|
|
@@ -60,39 +68,29 @@ class PyCololight:
|
|
|
60
68
|
|
|
61
69
|
return initial_effects
|
|
62
70
|
|
|
63
|
-
def _toggle_counter(self):
|
|
71
|
+
def _toggle_counter(self) -> None:
|
|
64
72
|
self._counter = 2 if self._counter == 1 else 1
|
|
65
73
|
|
|
66
|
-
def _get_counter(self):
|
|
74
|
+
def _get_counter(self) -> str:
|
|
67
75
|
count = f"000000000000000000000000000000000{self._counter}0000000000000000000"
|
|
68
76
|
self._toggle_counter()
|
|
69
77
|
return count
|
|
70
78
|
|
|
71
|
-
def
|
|
72
|
-
|
|
73
|
-
|
|
79
|
+
def _send(self, commands: list[bytes], response: bool = False) -> bytes | None:
|
|
80
|
+
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as sock:
|
|
81
|
+
sock.settimeout(self.timeout)
|
|
82
|
+
for command in commands:
|
|
83
|
+
sock.sendto(command, (self.host, self.port))
|
|
74
84
|
|
|
75
|
-
|
|
76
|
-
|
|
85
|
+
if response:
|
|
86
|
+
try:
|
|
87
|
+
return sock.recvfrom(4096)[0]
|
|
88
|
+
except TimeoutError:
|
|
89
|
+
raise UnavailableException
|
|
77
90
|
|
|
78
|
-
|
|
79
|
-
self._socket_connect()
|
|
80
|
-
for command in commands:
|
|
81
|
-
self._sock.sendto(command, (self.host, self.port))
|
|
91
|
+
return None
|
|
82
92
|
|
|
83
|
-
|
|
84
|
-
self._socket_close()
|
|
85
|
-
|
|
86
|
-
def _receive(self):
|
|
87
|
-
try:
|
|
88
|
-
data = self._sock.recvfrom(4096)[0]
|
|
89
|
-
self._socket_close()
|
|
90
|
-
return data
|
|
91
|
-
except socket.timeout:
|
|
92
|
-
self._socket_close()
|
|
93
|
-
raise UnavailableException
|
|
94
|
-
|
|
95
|
-
def _get_config(self, config_type):
|
|
93
|
+
def _get_config(self, config_type: str) -> str:
|
|
96
94
|
if config_type == "command":
|
|
97
95
|
config = f"{COMMAND_PREFIX}20{self._get_counter()}4010301c"
|
|
98
96
|
elif config_type == "effect":
|
|
@@ -103,20 +101,21 @@ class PyCololight:
|
|
|
103
101
|
return config
|
|
104
102
|
|
|
105
103
|
@property
|
|
106
|
-
def state(self):
|
|
104
|
+
def state(self) -> None:
|
|
107
105
|
"""
|
|
108
106
|
Gets state (on/off) and brightness from device, and updates local state.
|
|
109
107
|
"""
|
|
110
|
-
self._send(
|
|
108
|
+
data = self._send(
|
|
111
109
|
[bytes.fromhex(f"{self._get_config('state')}")],
|
|
112
110
|
response=True,
|
|
113
111
|
)
|
|
114
|
-
data
|
|
112
|
+
assert data is not None
|
|
115
113
|
if data[40] == 207:
|
|
116
114
|
self._on = True
|
|
117
115
|
self._brightness = data[41]
|
|
118
116
|
elif data[40] == 206:
|
|
119
117
|
self._on = False
|
|
118
|
+
self._brightness = None
|
|
120
119
|
else:
|
|
121
120
|
return
|
|
122
121
|
|
|
@@ -128,7 +127,7 @@ class PyCololight:
|
|
|
128
127
|
return self._on
|
|
129
128
|
|
|
130
129
|
@on.setter
|
|
131
|
-
def on(self, brightness: int):
|
|
130
|
+
def on(self, brightness: int) -> None:
|
|
132
131
|
"""
|
|
133
132
|
Turns the device on with desired brightness, or turns the device off if brightness is 0.
|
|
134
133
|
"""
|
|
@@ -137,18 +136,19 @@ class PyCololight:
|
|
|
137
136
|
self.brightness = brightness
|
|
138
137
|
else:
|
|
139
138
|
self._on = False
|
|
139
|
+
self._brightness = None
|
|
140
140
|
command = bytes.fromhex("{}{}".format(self._get_config("command"), "e1e"))
|
|
141
141
|
self._send([command])
|
|
142
142
|
|
|
143
143
|
@property
|
|
144
|
-
def brightness(self) -> int:
|
|
144
|
+
def brightness(self) -> int | None:
|
|
145
145
|
"""
|
|
146
146
|
Returns the current set brightness.
|
|
147
147
|
"""
|
|
148
148
|
return self._brightness
|
|
149
149
|
|
|
150
150
|
@brightness.setter
|
|
151
|
-
def brightness(self, brightness: int):
|
|
151
|
+
def brightness(self, brightness: int) -> None:
|
|
152
152
|
"""
|
|
153
153
|
Sets the brightness of the device.
|
|
154
154
|
"""
|
|
@@ -166,14 +166,14 @@ class PyCololight:
|
|
|
166
166
|
self._send([command])
|
|
167
167
|
|
|
168
168
|
@property
|
|
169
|
-
def colour(self) -> tuple:
|
|
169
|
+
def colour(self) -> tuple[int, int, int] | None:
|
|
170
170
|
"""
|
|
171
171
|
Returns the current set colour hue.
|
|
172
172
|
"""
|
|
173
173
|
return self._colour
|
|
174
174
|
|
|
175
175
|
@colour.setter
|
|
176
|
-
def colour(self, colour: tuple):
|
|
176
|
+
def colour(self, colour: tuple[int, int, int]) -> None:
|
|
177
177
|
"""
|
|
178
178
|
Sets the colour of the device.
|
|
179
179
|
"""
|
|
@@ -187,14 +187,14 @@ class PyCololight:
|
|
|
187
187
|
self._send([command])
|
|
188
188
|
|
|
189
189
|
@property
|
|
190
|
-
def effect(self) -> str:
|
|
190
|
+
def effect(self) -> str | None:
|
|
191
191
|
"""
|
|
192
192
|
Returns the current set effect name.
|
|
193
193
|
"""
|
|
194
194
|
return self._effect
|
|
195
195
|
|
|
196
196
|
@effect.setter
|
|
197
|
-
def effect(self, effect: str):
|
|
197
|
+
def effect(self, effect: str) -> None:
|
|
198
198
|
"""
|
|
199
199
|
Set the effect of the device.
|
|
200
200
|
"""
|
|
@@ -212,39 +212,39 @@ class PyCololight:
|
|
|
212
212
|
self._send(commands)
|
|
213
213
|
|
|
214
214
|
@property
|
|
215
|
-
def default_effects(self) -> list:
|
|
215
|
+
def default_effects(self) -> list[str]:
|
|
216
216
|
"""
|
|
217
217
|
Returns a list of names of the default effects for the device.
|
|
218
218
|
"""
|
|
219
219
|
return list(self._device_effects.default_effects.keys())
|
|
220
220
|
|
|
221
221
|
@property
|
|
222
|
-
def dynamic_effects(self) -> list:
|
|
222
|
+
def dynamic_effects(self) -> list[str]:
|
|
223
223
|
"""
|
|
224
224
|
Returns a list of names of the dynamic effects for the device.
|
|
225
225
|
"""
|
|
226
226
|
return list(self._device_effects.dynamic_effects.keys())
|
|
227
227
|
|
|
228
228
|
@property
|
|
229
|
-
def effects(self) -> list:
|
|
229
|
+
def effects(self) -> list[str]:
|
|
230
230
|
"""
|
|
231
231
|
Returns a list of names of the effects saved for the device.
|
|
232
232
|
"""
|
|
233
233
|
return list(self._effects.keys())
|
|
234
234
|
|
|
235
|
-
def restore_effects(self, effects: list):
|
|
235
|
+
def restore_effects(self, effects: list[str]) -> None:
|
|
236
236
|
"""
|
|
237
237
|
Restors the given default/dynamic effects, to the saved effects of the device.
|
|
238
238
|
"""
|
|
239
239
|
for effect in effects:
|
|
240
|
-
if effect not in self._device_effects.effects
|
|
240
|
+
if effect not in self._device_effects.effects:
|
|
241
241
|
raise DefaultEffectExecption
|
|
242
242
|
|
|
243
243
|
self._effects[effect] = self._device_effects.effects[effect]
|
|
244
244
|
|
|
245
245
|
def add_custom_effect(
|
|
246
246
|
self, name: str, colour_scheme: str, colour: str, cycle_speed: int, mode: int
|
|
247
|
-
):
|
|
247
|
+
) -> None:
|
|
248
248
|
"""
|
|
249
249
|
Adds a custom effect, to the saved effects of the device.
|
|
250
250
|
"""
|
|
@@ -254,13 +254,13 @@ class PyCololight:
|
|
|
254
254
|
|
|
255
255
|
self._effects[name] = [custom_effect_hex]
|
|
256
256
|
|
|
257
|
-
def custom_effect_colour_schemes(self) -> list:
|
|
257
|
+
def custom_effect_colour_schemes(self) -> list[str]:
|
|
258
258
|
"""
|
|
259
259
|
Returns a list of the available colour schemes for custom efects.
|
|
260
260
|
"""
|
|
261
261
|
return self._device_effects.custom_effect_colour_schemes()
|
|
262
262
|
|
|
263
|
-
def custom_effect_colour_scheme_colours(self, colour_scheme) -> list:
|
|
263
|
+
def custom_effect_colour_scheme_colours(self, colour_scheme: str) -> list[str]:
|
|
264
264
|
"""
|
|
265
265
|
Returns a list of the available colours for a given colour schemes for custom efects.
|
|
266
266
|
"""
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "pycololight"
|
|
3
|
+
version = "2.2.0"
|
|
4
|
+
description = "A Python3 wrapper for interacting with LifeSmart Cololight"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
license = "MIT"
|
|
7
|
+
license-files = ["LICENSE"]
|
|
8
|
+
requires-python = ">=3.12"
|
|
9
|
+
dependencies = []
|
|
10
|
+
|
|
11
|
+
[[project.authors]]
|
|
12
|
+
name = "BazaJayGee66"
|
|
13
|
+
|
|
14
|
+
[project.urls]
|
|
15
|
+
Repository = "https://github.com/BazaJayGee66/pycololight"
|
|
16
|
+
|
|
17
|
+
[dependency-groups]
|
|
18
|
+
dev = [
|
|
19
|
+
"mypy==2.4.1",
|
|
20
|
+
"pytest>=9,<10",
|
|
21
|
+
"pytest-cov>=7,<8",
|
|
22
|
+
"ruff==0.17.3",
|
|
23
|
+
]
|
|
24
|
+
|
|
25
|
+
[build-system]
|
|
26
|
+
requires = ["uv_build>=0.13.6,<0.14.0"]
|
|
27
|
+
build-backend = "uv_build"
|
|
28
|
+
|
|
29
|
+
[tool.uv.build-backend]
|
|
30
|
+
module-root = ""
|
|
31
|
+
source-include = ["CHANGELOG.md"]
|
|
32
|
+
|
|
33
|
+
[tool.pytest]
|
|
34
|
+
testpaths = ["tests"]
|
|
35
|
+
|
|
36
|
+
[tool.ruff.lint]
|
|
37
|
+
extend-select = [
|
|
38
|
+
"I",
|
|
39
|
+
"UP",
|
|
40
|
+
]
|
|
41
|
+
|
|
42
|
+
[tool.ruff.lint.per-file-ignores]
|
|
43
|
+
"tests/*" = ["B018"]
|
|
44
|
+
|
|
45
|
+
[tool.mypy]
|
|
46
|
+
files = ["pycololight"]
|
|
47
|
+
disallow_untyped_defs = true
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "pycololight"
|
|
3
|
+
version = "2.2.0"
|
|
4
|
+
description = "A Python3 wrapper for interacting with LifeSmart Cololight"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
license = "MIT"
|
|
7
|
+
license-files = ["LICENSE"]
|
|
8
|
+
authors = [{ name = "BazaJayGee66" }]
|
|
9
|
+
requires-python = ">=3.12"
|
|
10
|
+
dependencies = []
|
|
11
|
+
|
|
12
|
+
[project.urls]
|
|
13
|
+
Repository = "https://github.com/BazaJayGee66/pycololight"
|
|
14
|
+
|
|
15
|
+
[dependency-groups]
|
|
16
|
+
dev = [
|
|
17
|
+
"mypy==2.4.1",
|
|
18
|
+
"pytest>=9,<10",
|
|
19
|
+
"pytest-cov>=7,<8",
|
|
20
|
+
"ruff==0.17.3",
|
|
21
|
+
]
|
|
22
|
+
|
|
23
|
+
[build-system]
|
|
24
|
+
requires = ["uv_build>=0.13.6,<0.14.0"]
|
|
25
|
+
build-backend = "uv_build"
|
|
26
|
+
|
|
27
|
+
[tool.uv.build-backend]
|
|
28
|
+
module-root = ""
|
|
29
|
+
source-include = ["CHANGELOG.md"]
|
|
30
|
+
|
|
31
|
+
[tool.pytest]
|
|
32
|
+
testpaths = ["tests"]
|
|
33
|
+
|
|
34
|
+
[tool.ruff.lint]
|
|
35
|
+
extend-select = ["I", "UP"]
|
|
36
|
+
|
|
37
|
+
[tool.ruff.lint.per-file-ignores]
|
|
38
|
+
# Reading PyCololight.state polls the device, so tests read it as a bare expression.
|
|
39
|
+
"tests/*" = ["B018"]
|
|
40
|
+
|
|
41
|
+
[tool.mypy]
|
|
42
|
+
files = ["pycololight"]
|
|
43
|
+
disallow_untyped_defs = true
|
pycololight-2.0.0/CHANGELOG.md
DELETED
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
# 2.0.0
|
|
2
|
-
|
|
3
|
-
This release enables support for the cololight strip device.
|
|
4
|
-
|
|
5
|
-
## New Features
|
|
6
|
-
|
|
7
|
-
- Add support for the cololight strip device
|
|
8
|
-
- Add dynamic effects for the cololight strip device
|
|
9
|
-
- Add custom effects for the cololight strip device
|
|
10
|
-
|
|
11
|
-
## Breaking Changes
|
|
12
|
-
|
|
13
|
-
- A device (`hexagon` or `strip`) must now be passed when creating `PyCololight` object
|
|
14
|
-
|
|
15
|
-
# 1.0.0
|
|
16
|
-
|
|
17
|
-
## New Features
|
|
18
|
-
|
|
19
|
-
- Add state to get light state (on/off) and brightness - Thanks [@pim12345](https://github.com/pim12345)
|
|
20
|
-
|
|
21
|
-
## Fixes
|
|
22
|
-
|
|
23
|
-
- Add missing exceptions
|
|
24
|
-
- Add BrightnessException if brightness not between 0 and 100
|
|
25
|
-
- Refactor for simpler code
|
|
26
|
-
- Rename `include_default_effects` to `restore_default_effects`
|
|
27
|
-
- Remove `count` property
|
|
28
|
-
- Add type hints, and docstring
|
|
29
|
-
|
|
30
|
-
# 0.0.2
|
|
31
|
-
|
|
32
|
-
## New Features
|
|
33
|
-
|
|
34
|
-
## Fixes
|
|
35
|
-
|
|
36
|
-
- Refactor for simpler code
|
|
37
|
-
|
|
38
|
-
# 0.0.1
|
|
39
|
-
|
|
40
|
-
Initial Release
|
|
41
|
-
|
|
42
|
-
## New Features
|
|
43
|
-
|
|
44
|
-
- Turn On
|
|
45
|
-
- Turn Off
|
|
46
|
-
- Set brightness
|
|
47
|
-
- Set colour
|
|
48
|
-
- Set effect
|
|
49
|
-
- Include/Exclude default effects
|
|
50
|
-
- Add custom effect
|
|
51
|
-
|
|
52
|
-
## Fixes
|
pycololight-2.0.0/pyproject.toml
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
[tool.poetry]
|
|
2
|
-
authors = ["BazaJayGee66"]
|
|
3
|
-
description = "A Python3 wrapper for interacting with LifeSmart Cololight"
|
|
4
|
-
include = ["CHANGELOG.md"]
|
|
5
|
-
license = "MIT"
|
|
6
|
-
name = "pycololight"
|
|
7
|
-
readme = "README.md"
|
|
8
|
-
repository = "https://github.com/BazaJayGee66/pycololight"
|
|
9
|
-
version = "2.0.0"
|
|
10
|
-
|
|
11
|
-
[tool.poetry.dependencies]
|
|
12
|
-
python = "^3.8"
|
|
13
|
-
|
|
14
|
-
[tool.poetry.dev-dependencies]
|
|
15
|
-
black = "21.5b1"
|
|
16
|
-
pylint = "2.8.2"
|
|
17
|
-
pytest = "6.2.4"
|
|
18
|
-
pytest-cov = "^2.12.1"
|
|
19
|
-
|
|
20
|
-
[build-system]
|
|
21
|
-
build-backend = "poetry.core.masonry.api"
|
|
22
|
-
requires = ["poetry-core>=1.0.0"]
|
pycololight-2.0.0/setup.py
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
# -*- coding: utf-8 -*-
|
|
2
|
-
from setuptools import setup
|
|
3
|
-
|
|
4
|
-
packages = \
|
|
5
|
-
['pycololight']
|
|
6
|
-
|
|
7
|
-
package_data = \
|
|
8
|
-
{'': ['*']}
|
|
9
|
-
|
|
10
|
-
setup_kwargs = {
|
|
11
|
-
'name': 'pycololight',
|
|
12
|
-
'version': '2.0.0',
|
|
13
|
-
'description': 'A Python3 wrapper for interacting with LifeSmart Cololight',
|
|
14
|
-
'long_description': '# pycololight\n\nA Python3 wrapper for interacting with LifeSmart Cololight.\n\nSupports the following cololight devices:\n\n- hexagon\n- strip\n\n## Usage\n\n```python\nfrom pycololight import PyCololight\n\n# Setup hexagon device\nlight = PyCololight(device="hexagon", host="1.1.1.1")\n\n# Setup strip device, and include dynamic effects\nlight = PyCololight(device="strip", host="1.1.1.1", dynamic_effects=True)\n\n# Turn on at 60% brightness\nlight.on = 60\n\n# Set brightness to 70%\nlight.brightness = 70\n\n# Set light colour\nlight.colour = (255, 127, 255)\n\n# Set effect\nlight.effect = "Sunrise"\n\n# Create custom effect\nlight.add_custom_effect(\n name="custom effect",\n colour_scheme="Shadow",\n colour="Red, Yellow",\n cycle_speed=11,\n mode=1\n)\n\n# Turn off\nlight.on = 0\n```\n\nMapping of modes for custom effects can be found [here](https://github.com/BazaJayGee66/pycololight/blob/main/MODES.md)\n',
|
|
15
|
-
'author': 'BazaJayGee66',
|
|
16
|
-
'author_email': None,
|
|
17
|
-
'maintainer': None,
|
|
18
|
-
'maintainer_email': None,
|
|
19
|
-
'url': 'https://github.com/BazaJayGee66/pycololight',
|
|
20
|
-
'packages': packages,
|
|
21
|
-
'package_data': package_data,
|
|
22
|
-
'python_requires': '>=3.8,<4.0',
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
setup(**setup_kwargs)
|
|
File without changes
|