HueBLE 2.2.3__tar.gz → 2.2.4__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.
- {hueble-2.2.3 → hueble-2.2.4}/HueBLE.egg-info/PKG-INFO +39 -2
- {hueble-2.2.3 → hueble-2.2.4}/HueBLE.py +109 -15
- {hueble-2.2.3 → hueble-2.2.4}/PKG-INFO +39 -2
- {hueble-2.2.3 → hueble-2.2.4}/README.md +38 -1
- {hueble-2.2.3 → hueble-2.2.4}/pyproject.toml +1 -1
- {hueble-2.2.3 → hueble-2.2.4}/tests/test_HueBLE.py +20 -0
- {hueble-2.2.3 → hueble-2.2.4}/HueBLE.egg-info/SOURCES.txt +0 -0
- {hueble-2.2.3 → hueble-2.2.4}/HueBLE.egg-info/dependency_links.txt +0 -0
- {hueble-2.2.3 → hueble-2.2.4}/HueBLE.egg-info/requires.txt +0 -0
- {hueble-2.2.3 → hueble-2.2.4}/HueBLE.egg-info/top_level.txt +0 -0
- {hueble-2.2.3 → hueble-2.2.4}/LICENSE.txt +0 -0
- {hueble-2.2.3 → hueble-2.2.4}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: HueBLE
|
|
3
|
-
Version: 2.2.
|
|
3
|
+
Version: 2.2.4
|
|
4
4
|
Summary: Python module for controlling and monitoring Bluetooth Philips Hue bulbs
|
|
5
5
|
Author-email: Harvey Lelliott <harveylelliott@duck.com>
|
|
6
6
|
License: MIT License
|
|
@@ -64,7 +64,8 @@ Python module for controlling Bluetooth Philips Hue lights.
|
|
|
64
64
|
|
|
65
65
|
This Python module enables you to control Philips Hue Bluetooth lights directly
|
|
66
66
|
from your computer, without the need for a Hue bridge or ZigBee dongle.
|
|
67
|
-
It leverages the Bleak library to interact with Bluetooth Philips Hue lights
|
|
67
|
+
It leverages the Bleak library to interact with Bluetooth Philips Hue lights including
|
|
68
|
+
the smart plugs.
|
|
68
69
|
|
|
69
70
|
|
|
70
71
|
## Features
|
|
@@ -73,10 +74,13 @@ It leverages the Bleak library to interact with Bluetooth Philips Hue lights.
|
|
|
73
74
|
- 🌗 Brightness control
|
|
74
75
|
- 🌡️ Colour temp control
|
|
75
76
|
- 🌈 XY colour control
|
|
77
|
+
- ✨ Built-in effects with custom colour and speed
|
|
78
|
+
- ⏱️ Custom transitions, including instant changes
|
|
76
79
|
- ❔ Light state (power/brightness/temp/colour)
|
|
77
80
|
- ⚙️ Light configuration (name)
|
|
78
81
|
- 📊 Light metadata (manufacturer/model/zigbee address)
|
|
79
82
|
- 🤜 Supports push & polling models
|
|
83
|
+
- 🔌 Hue smart plug support
|
|
80
84
|
- 🔂 Simple structure
|
|
81
85
|
- 📜 Mediocre documentation
|
|
82
86
|
- ✔️ More emojis than strictly necessary
|
|
@@ -177,6 +181,39 @@ if __name__ == "__main__":
|
|
|
177
181
|
```
|
|
178
182
|
|
|
179
183
|
|
|
184
|
+
### Transitions
|
|
185
|
+
|
|
186
|
+
Power, brightness, colour temperature and colour changes can use a custom
|
|
187
|
+
transition time.
|
|
188
|
+
|
|
189
|
+
```python
|
|
190
|
+
await light.set_power(True, transition_ms=0)
|
|
191
|
+
await light.set_brightness(254, transition_ms=100)
|
|
192
|
+
await light.set_colour_temp(250, transition_ms=400)
|
|
193
|
+
await light.set_colour_xy(0.3, 0.4, transition_ms=200)
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
`transition_ms=0` makes the change instant. Transition times use 100 ms steps.
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
### Effects
|
|
200
|
+
|
|
201
|
+
HueBLE supports Hue effects such as Candle, Fireplace, Sunrise and Sunset.
|
|
202
|
+
Effects can use a custom colour, brightness and speed.
|
|
203
|
+
|
|
204
|
+
```python
|
|
205
|
+
await light.set_colour_effect(
|
|
206
|
+
0.30,
|
|
207
|
+
0.14,
|
|
208
|
+
254,
|
|
209
|
+
HueBLE.EffectType.CANDLE,
|
|
210
|
+
128,
|
|
211
|
+
)
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
Effect speed ranges from `0` (slowest) to `255` (fastest).
|
|
215
|
+
|
|
216
|
+
|
|
180
217
|
### Demo program
|
|
181
218
|
|
|
182
219
|
A more fully featured demo program can be found in ``` examples/demo.py ``` which demonstrates all of the implemented features.
|
|
@@ -129,6 +129,10 @@ UNPACK_EFFECT_API_TEMPERATURE_WITH_EFFECT = "<xxBxxBxxHxxBxxB"
|
|
|
129
129
|
#: data stream unpack format string for decoding plain temperature without effect (effect API)
|
|
130
130
|
UNPACK_EFFECT_API_TEMPERATURE_WITHOUT_EFFECT = "<xxBxxBxxH"
|
|
131
131
|
|
|
132
|
+
#: data stream unpack format string for decoding the onoff-only report (effect API),
|
|
133
|
+
#: sent by devices that only support on/off, e.g. the Hue smart plug
|
|
134
|
+
UNPACK_EFFECT_API_ONOFF_ONLY = "<xxB"
|
|
135
|
+
|
|
132
136
|
|
|
133
137
|
_LOGGER = logging.getLogger(__name__)
|
|
134
138
|
|
|
@@ -139,9 +143,11 @@ class EffectType(Enum):
|
|
|
139
143
|
CANDLE = 0x01
|
|
140
144
|
FIREPLACE = 0x02
|
|
141
145
|
PRISM = 0x03
|
|
146
|
+
SUNRISE = 0x09
|
|
142
147
|
SPARKLE = 0x0A
|
|
143
148
|
OPAL = 0x0B
|
|
144
149
|
GLISTEN = 0x0C
|
|
150
|
+
SUNSET = 0x0D
|
|
145
151
|
UNDERWATER = 0x0E
|
|
146
152
|
COSMOS = 0x0F
|
|
147
153
|
SUNBEAM = 0x10
|
|
@@ -161,10 +167,26 @@ class EffectCommands(Enum):
|
|
|
161
167
|
BRIGHTNESS = "0201"
|
|
162
168
|
TEMPERATURE = "0302"
|
|
163
169
|
COLOURXY = "0404"
|
|
170
|
+
TRANSITION_TIME = "0502"
|
|
164
171
|
EFFECT = "0601"
|
|
165
172
|
EFFECT_SPEED = "0801"
|
|
166
173
|
|
|
167
174
|
|
|
175
|
+
def _transition_tlv(transition_ms: int) -> bytes:
|
|
176
|
+
if not isinstance(transition_ms, int):
|
|
177
|
+
raise TypeError("transition_ms must be an integer")
|
|
178
|
+
if transition_ms < 0 or transition_ms % 100 != 0:
|
|
179
|
+
raise ValueError("transition_ms must be a non-negative multiple of 100")
|
|
180
|
+
|
|
181
|
+
units = transition_ms // 100
|
|
182
|
+
if units > 0xFFFF:
|
|
183
|
+
raise ValueError("transition_ms is too large")
|
|
184
|
+
|
|
185
|
+
return bytes.fromhex(EffectCommands.TRANSITION_TIME.value) + units.to_bytes(
|
|
186
|
+
2, "little"
|
|
187
|
+
)
|
|
188
|
+
|
|
189
|
+
|
|
168
190
|
class HueBleError(Exception):
|
|
169
191
|
"""
|
|
170
192
|
Base exception of HueBLE.
|
|
@@ -475,10 +497,19 @@ class HueBleLight(object):
|
|
|
475
497
|
f"""Light "{self.name}" has informed us of a new"""
|
|
476
498
|
f""" colour temp state of ({self.colour_temp})"""
|
|
477
499
|
)
|
|
500
|
+
elif len(data) == 3:
|
|
501
|
+
# device only reports its onoff value (e.g. smart plug)
|
|
502
|
+
onoff = unpack(UNPACK_EFFECT_API_ONOFF_ONLY, data)[0]
|
|
503
|
+
self._power_on = bool(onoff)
|
|
504
|
+
|
|
505
|
+
_LOGGER.debug(
|
|
506
|
+
f"""Light "{self.name}" has informed us of a new"""
|
|
507
|
+
f""" power state ({self._power_on})"""
|
|
508
|
+
)
|
|
478
509
|
else:
|
|
479
510
|
# so far unkown
|
|
480
511
|
_LOGGER.warning(
|
|
481
|
-
"unrecognized effect response with length {len(data)}: {data}"
|
|
512
|
+
f"unrecognized effect response with length {len(data)}: {data}"
|
|
482
513
|
)
|
|
483
514
|
|
|
484
515
|
if effect_state_changed:
|
|
@@ -1211,6 +1242,11 @@ class HueBleLight(object):
|
|
|
1211
1242
|
if write_state:
|
|
1212
1243
|
self._colour_temp = colour_temp
|
|
1213
1244
|
self._power_on = bool(onoff)
|
|
1245
|
+
elif len(buf) == 3:
|
|
1246
|
+
# device only reports its onoff value (e.g. smart plug)
|
|
1247
|
+
onoff = unpack(UNPACK_EFFECT_API_ONOFF_ONLY, buf)[0]
|
|
1248
|
+
if write_state:
|
|
1249
|
+
self._power_on = bool(onoff)
|
|
1214
1250
|
else:
|
|
1215
1251
|
# so far unkown
|
|
1216
1252
|
_LOGGER.warning(
|
|
@@ -1223,28 +1259,77 @@ class HueBleLight(object):
|
|
|
1223
1259
|
"""Sets the name of the light. Not tested, use at own risk."""
|
|
1224
1260
|
await self._write_gatt(UUID_NAME, str.encode(name))
|
|
1225
1261
|
|
|
1226
|
-
async def set_power(self, on: bool):
|
|
1262
|
+
async def set_power(self, on: bool, transition_ms: int | None = None):
|
|
1227
1263
|
"""Sets the power state of the light."""
|
|
1228
|
-
|
|
1264
|
+
if transition_ms is None:
|
|
1265
|
+
await self._write_gatt(UUID_POWER, bytes([1 if on else 0]))
|
|
1266
|
+
return
|
|
1229
1267
|
|
|
1230
|
-
|
|
1268
|
+
buf = (
|
|
1269
|
+
bytes.fromhex(EffectCommands.ONOFF.value)
|
|
1270
|
+
+ bytes([1 if on else 0])
|
|
1271
|
+
+ _transition_tlv(transition_ms)
|
|
1272
|
+
)
|
|
1273
|
+
await self._write_gatt(UUID_EFFECTS, buf)
|
|
1274
|
+
|
|
1275
|
+
async def set_brightness(
|
|
1276
|
+
self, brightness: int, transition_ms: int | None = None
|
|
1277
|
+
):
|
|
1231
1278
|
"""Sets the brightness from an integer between 0 and 255"""
|
|
1232
|
-
|
|
1279
|
+
brightness = max(min(brightness, 254), 1)
|
|
1280
|
+
if transition_ms is None:
|
|
1281
|
+
await self._write_gatt(UUID_BRIGHTNESS, bytes([brightness]))
|
|
1282
|
+
return
|
|
1283
|
+
|
|
1284
|
+
buf = (
|
|
1285
|
+
bytes.fromhex(EffectCommands.BRIGHTNESS.value)
|
|
1286
|
+
+ bytes([brightness])
|
|
1287
|
+
+ _transition_tlv(transition_ms)
|
|
1288
|
+
)
|
|
1289
|
+
await self._write_gatt(UUID_EFFECTS, buf)
|
|
1233
1290
|
|
|
1234
|
-
async def set_colour_temp(
|
|
1291
|
+
async def set_colour_temp(
|
|
1292
|
+
self, colour_temp: int, transition_ms: int | None = None
|
|
1293
|
+
):
|
|
1235
1294
|
"""Sets the temperature from an int between 153 and 500.
|
|
1236
1295
|
Uses mireds."""
|
|
1237
1296
|
temp = max(min(int(colour_temp), 500), 153)
|
|
1238
|
-
|
|
1239
|
-
|
|
1297
|
+
data = temp.to_bytes(2, "little")
|
|
1298
|
+
if transition_ms is None:
|
|
1299
|
+
await self._write_gatt(UUID_TEMPERATURE, data)
|
|
1300
|
+
return
|
|
1301
|
+
|
|
1302
|
+
buf = (
|
|
1303
|
+
bytes.fromhex(EffectCommands.TEMPERATURE.value)
|
|
1304
|
+
+ data
|
|
1305
|
+
+ _transition_tlv(transition_ms)
|
|
1306
|
+
)
|
|
1307
|
+
await self._write_gatt(UUID_EFFECTS, buf)
|
|
1240
1308
|
|
|
1241
|
-
async def set_colour_xy(
|
|
1309
|
+
async def set_colour_xy(
|
|
1310
|
+
self, x: float, y: float, transition_ms: int | None = None
|
|
1311
|
+
):
|
|
1242
1312
|
"""Sets the XY colour coordinates from floats between 0.0 and 1.0."""
|
|
1243
|
-
|
|
1244
|
-
|
|
1313
|
+
data = pack("<HH", int(x * 0xFFFF), int(y * 0xFFFF))
|
|
1314
|
+
if transition_ms is None:
|
|
1315
|
+
await self._write_gatt(UUID_XY_COLOUR, data)
|
|
1316
|
+
return
|
|
1317
|
+
|
|
1318
|
+
buf = (
|
|
1319
|
+
bytes.fromhex(EffectCommands.COLOURXY.value)
|
|
1320
|
+
+ data
|
|
1321
|
+
+ _transition_tlv(transition_ms)
|
|
1322
|
+
)
|
|
1323
|
+
await self._write_gatt(UUID_EFFECTS, buf)
|
|
1245
1324
|
|
|
1246
1325
|
async def set_colour_effect(
|
|
1247
|
-
self,
|
|
1326
|
+
self,
|
|
1327
|
+
x: float,
|
|
1328
|
+
y: float,
|
|
1329
|
+
brightness: int,
|
|
1330
|
+
effect: EffectType,
|
|
1331
|
+
effect_speed: int,
|
|
1332
|
+
transition_ms: int | None = None,
|
|
1248
1333
|
):
|
|
1249
1334
|
"""
|
|
1250
1335
|
Sets XY colour, brightness, effect and effect speed.
|
|
@@ -1268,7 +1353,7 @@ class HueBleLight(object):
|
|
|
1268
1353
|
bytes.fromhex(EffectCommands.EFFECT.value),
|
|
1269
1354
|
max(min(effect.value, 254), 1),
|
|
1270
1355
|
bytes.fromhex(EffectCommands.EFFECT_SPEED.value),
|
|
1271
|
-
max(min(effect_speed,
|
|
1356
|
+
max(min(effect_speed, 255), 0),
|
|
1272
1357
|
)
|
|
1273
1358
|
else:
|
|
1274
1359
|
# if no effect is selected we can just operate in colourxy mode and ommit the effect data in the transfer
|
|
@@ -1282,10 +1367,17 @@ class HueBleLight(object):
|
|
|
1282
1367
|
int(x * 0xFFFF),
|
|
1283
1368
|
int(y * 0xFFFF),
|
|
1284
1369
|
)
|
|
1370
|
+
if transition_ms is not None:
|
|
1371
|
+
buf += _transition_tlv(transition_ms)
|
|
1285
1372
|
await self._write_gatt(UUID_EFFECTS, buf)
|
|
1286
1373
|
|
|
1287
1374
|
async def set_temperature_effect(
|
|
1288
|
-
self,
|
|
1375
|
+
self,
|
|
1376
|
+
colour_temp: int,
|
|
1377
|
+
brightness: int,
|
|
1378
|
+
effect: EffectType,
|
|
1379
|
+
effect_speed: int,
|
|
1380
|
+
transition_ms: int | None = None,
|
|
1289
1381
|
):
|
|
1290
1382
|
"""
|
|
1291
1383
|
Sets colour temperature, brightness, effect and effect speed.
|
|
@@ -1309,7 +1401,7 @@ class HueBleLight(object):
|
|
|
1309
1401
|
bytes.fromhex(EffectCommands.EFFECT.value),
|
|
1310
1402
|
max(min(effect.value, 254), 1),
|
|
1311
1403
|
bytes.fromhex(EffectCommands.EFFECT_SPEED.value),
|
|
1312
|
-
max(min(effect_speed,
|
|
1404
|
+
max(min(effect_speed, 255), 0),
|
|
1313
1405
|
)
|
|
1314
1406
|
else:
|
|
1315
1407
|
# if no effect is selected we can just operate in colourxy mode and ommit the effect data in the transfer
|
|
@@ -1322,6 +1414,8 @@ class HueBleLight(object):
|
|
|
1322
1414
|
bytes.fromhex(EffectCommands.TEMPERATURE.value),
|
|
1323
1415
|
temperature,
|
|
1324
1416
|
)
|
|
1417
|
+
if transition_ms is not None:
|
|
1418
|
+
buf += _transition_tlv(transition_ms)
|
|
1325
1419
|
await self._write_gatt(UUID_EFFECTS, buf)
|
|
1326
1420
|
|
|
1327
1421
|
@property
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: HueBLE
|
|
3
|
-
Version: 2.2.
|
|
3
|
+
Version: 2.2.4
|
|
4
4
|
Summary: Python module for controlling and monitoring Bluetooth Philips Hue bulbs
|
|
5
5
|
Author-email: Harvey Lelliott <harveylelliott@duck.com>
|
|
6
6
|
License: MIT License
|
|
@@ -64,7 +64,8 @@ Python module for controlling Bluetooth Philips Hue lights.
|
|
|
64
64
|
|
|
65
65
|
This Python module enables you to control Philips Hue Bluetooth lights directly
|
|
66
66
|
from your computer, without the need for a Hue bridge or ZigBee dongle.
|
|
67
|
-
It leverages the Bleak library to interact with Bluetooth Philips Hue lights
|
|
67
|
+
It leverages the Bleak library to interact with Bluetooth Philips Hue lights including
|
|
68
|
+
the smart plugs.
|
|
68
69
|
|
|
69
70
|
|
|
70
71
|
## Features
|
|
@@ -73,10 +74,13 @@ It leverages the Bleak library to interact with Bluetooth Philips Hue lights.
|
|
|
73
74
|
- 🌗 Brightness control
|
|
74
75
|
- 🌡️ Colour temp control
|
|
75
76
|
- 🌈 XY colour control
|
|
77
|
+
- ✨ Built-in effects with custom colour and speed
|
|
78
|
+
- ⏱️ Custom transitions, including instant changes
|
|
76
79
|
- ❔ Light state (power/brightness/temp/colour)
|
|
77
80
|
- ⚙️ Light configuration (name)
|
|
78
81
|
- 📊 Light metadata (manufacturer/model/zigbee address)
|
|
79
82
|
- 🤜 Supports push & polling models
|
|
83
|
+
- 🔌 Hue smart plug support
|
|
80
84
|
- 🔂 Simple structure
|
|
81
85
|
- 📜 Mediocre documentation
|
|
82
86
|
- ✔️ More emojis than strictly necessary
|
|
@@ -177,6 +181,39 @@ if __name__ == "__main__":
|
|
|
177
181
|
```
|
|
178
182
|
|
|
179
183
|
|
|
184
|
+
### Transitions
|
|
185
|
+
|
|
186
|
+
Power, brightness, colour temperature and colour changes can use a custom
|
|
187
|
+
transition time.
|
|
188
|
+
|
|
189
|
+
```python
|
|
190
|
+
await light.set_power(True, transition_ms=0)
|
|
191
|
+
await light.set_brightness(254, transition_ms=100)
|
|
192
|
+
await light.set_colour_temp(250, transition_ms=400)
|
|
193
|
+
await light.set_colour_xy(0.3, 0.4, transition_ms=200)
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
`transition_ms=0` makes the change instant. Transition times use 100 ms steps.
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
### Effects
|
|
200
|
+
|
|
201
|
+
HueBLE supports Hue effects such as Candle, Fireplace, Sunrise and Sunset.
|
|
202
|
+
Effects can use a custom colour, brightness and speed.
|
|
203
|
+
|
|
204
|
+
```python
|
|
205
|
+
await light.set_colour_effect(
|
|
206
|
+
0.30,
|
|
207
|
+
0.14,
|
|
208
|
+
254,
|
|
209
|
+
HueBLE.EffectType.CANDLE,
|
|
210
|
+
128,
|
|
211
|
+
)
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
Effect speed ranges from `0` (slowest) to `255` (fastest).
|
|
215
|
+
|
|
216
|
+
|
|
180
217
|
### Demo program
|
|
181
218
|
|
|
182
219
|
A more fully featured demo program can be found in ``` examples/demo.py ``` which demonstrates all of the implemented features.
|
|
@@ -15,7 +15,8 @@ Python module for controlling Bluetooth Philips Hue lights.
|
|
|
15
15
|
|
|
16
16
|
This Python module enables you to control Philips Hue Bluetooth lights directly
|
|
17
17
|
from your computer, without the need for a Hue bridge or ZigBee dongle.
|
|
18
|
-
It leverages the Bleak library to interact with Bluetooth Philips Hue lights
|
|
18
|
+
It leverages the Bleak library to interact with Bluetooth Philips Hue lights including
|
|
19
|
+
the smart plugs.
|
|
19
20
|
|
|
20
21
|
|
|
21
22
|
## Features
|
|
@@ -24,10 +25,13 @@ It leverages the Bleak library to interact with Bluetooth Philips Hue lights.
|
|
|
24
25
|
- 🌗 Brightness control
|
|
25
26
|
- 🌡️ Colour temp control
|
|
26
27
|
- 🌈 XY colour control
|
|
28
|
+
- ✨ Built-in effects with custom colour and speed
|
|
29
|
+
- ⏱️ Custom transitions, including instant changes
|
|
27
30
|
- ❔ Light state (power/brightness/temp/colour)
|
|
28
31
|
- ⚙️ Light configuration (name)
|
|
29
32
|
- 📊 Light metadata (manufacturer/model/zigbee address)
|
|
30
33
|
- 🤜 Supports push & polling models
|
|
34
|
+
- 🔌 Hue smart plug support
|
|
31
35
|
- 🔂 Simple structure
|
|
32
36
|
- 📜 Mediocre documentation
|
|
33
37
|
- ✔️ More emojis than strictly necessary
|
|
@@ -128,6 +132,39 @@ if __name__ == "__main__":
|
|
|
128
132
|
```
|
|
129
133
|
|
|
130
134
|
|
|
135
|
+
### Transitions
|
|
136
|
+
|
|
137
|
+
Power, brightness, colour temperature and colour changes can use a custom
|
|
138
|
+
transition time.
|
|
139
|
+
|
|
140
|
+
```python
|
|
141
|
+
await light.set_power(True, transition_ms=0)
|
|
142
|
+
await light.set_brightness(254, transition_ms=100)
|
|
143
|
+
await light.set_colour_temp(250, transition_ms=400)
|
|
144
|
+
await light.set_colour_xy(0.3, 0.4, transition_ms=200)
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
`transition_ms=0` makes the change instant. Transition times use 100 ms steps.
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
### Effects
|
|
151
|
+
|
|
152
|
+
HueBLE supports Hue effects such as Candle, Fireplace, Sunrise and Sunset.
|
|
153
|
+
Effects can use a custom colour, brightness and speed.
|
|
154
|
+
|
|
155
|
+
```python
|
|
156
|
+
await light.set_colour_effect(
|
|
157
|
+
0.30,
|
|
158
|
+
0.14,
|
|
159
|
+
254,
|
|
160
|
+
HueBLE.EffectType.CANDLE,
|
|
161
|
+
128,
|
|
162
|
+
)
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
Effect speed ranges from `0` (slowest) to `255` (fastest).
|
|
166
|
+
|
|
167
|
+
|
|
131
168
|
### Demo program
|
|
132
169
|
|
|
133
170
|
A more fully featured demo program can be found in ``` examples/demo.py ``` which demonstrates all of the implemented features.
|
|
@@ -393,6 +393,26 @@ async def test_commands(
|
|
|
393
393
|
},
|
|
394
394
|
id="unknown_effect",
|
|
395
395
|
),
|
|
396
|
+
pytest.param(
|
|
397
|
+
{
|
|
398
|
+
HueBLE.UUID_MANUFACTURER: "Philippe Hue".encode(),
|
|
399
|
+
HueBLE.UUID_MODEL: "Fancy new light".encode(),
|
|
400
|
+
HueBLE.UUID_FW_VERSION: "1.7.10".encode(),
|
|
401
|
+
HueBLE.UUID_ZIGBEE_ADDRESS: bytes.fromhex("00010203040506070809"),
|
|
402
|
+
HueBLE.UUID_NAME: "L A M P".encode(),
|
|
403
|
+
# on/off-only device (e.g. smart plug): only the onoff TLV is reported
|
|
404
|
+
HueBLE.UUID_EFFECTS: bytes.fromhex("010100"),
|
|
405
|
+
},
|
|
406
|
+
{
|
|
407
|
+
"manufacturer": "Philippe Hue",
|
|
408
|
+
"model": "Fancy new light",
|
|
409
|
+
"firmware": "1.7.10",
|
|
410
|
+
"zigbee_address": "00:01:02:03:04:05:06:07:08:09",
|
|
411
|
+
"name_in_app": "L A M P",
|
|
412
|
+
"power_state": False,
|
|
413
|
+
},
|
|
414
|
+
id="effect_onoff_only",
|
|
415
|
+
),
|
|
396
416
|
],
|
|
397
417
|
)
|
|
398
418
|
async def test_poll_state(
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|