casambi-bt-revamped 0.3.8.dev1__tar.gz → 0.3.8.dev3__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.
- {casambi_bt_revamped-0.3.8.dev1/src/casambi_bt_revamped.egg-info → casambi_bt_revamped-0.3.8.dev3}/PKG-INFO +1 -1
- {casambi_bt_revamped-0.3.8.dev1 → casambi_bt_revamped-0.3.8.dev3}/setup.cfg +1 -1
- {casambi_bt_revamped-0.3.8.dev1 → casambi_bt_revamped-0.3.8.dev3}/src/CasambiBt/_client.py +27 -13
- {casambi_bt_revamped-0.3.8.dev1 → casambi_bt_revamped-0.3.8.dev3}/src/CasambiBt/_unit.py +20 -2
- {casambi_bt_revamped-0.3.8.dev1 → casambi_bt_revamped-0.3.8.dev3/src/casambi_bt_revamped.egg-info}/PKG-INFO +1 -1
- {casambi_bt_revamped-0.3.8.dev1 → casambi_bt_revamped-0.3.8.dev3}/LICENSE +0 -0
- {casambi_bt_revamped-0.3.8.dev1 → casambi_bt_revamped-0.3.8.dev3}/README.md +0 -0
- {casambi_bt_revamped-0.3.8.dev1 → casambi_bt_revamped-0.3.8.dev3}/pyproject.toml +0 -0
- {casambi_bt_revamped-0.3.8.dev1 → casambi_bt_revamped-0.3.8.dev3}/src/CasambiBt/__init__.py +0 -0
- {casambi_bt_revamped-0.3.8.dev1 → casambi_bt_revamped-0.3.8.dev3}/src/CasambiBt/_cache.py +0 -0
- {casambi_bt_revamped-0.3.8.dev1 → casambi_bt_revamped-0.3.8.dev3}/src/CasambiBt/_casambi.py +0 -0
- {casambi_bt_revamped-0.3.8.dev1 → casambi_bt_revamped-0.3.8.dev3}/src/CasambiBt/_constants.py +0 -0
- {casambi_bt_revamped-0.3.8.dev1 → casambi_bt_revamped-0.3.8.dev3}/src/CasambiBt/_discover.py +0 -0
- {casambi_bt_revamped-0.3.8.dev1 → casambi_bt_revamped-0.3.8.dev3}/src/CasambiBt/_encryption.py +0 -0
- {casambi_bt_revamped-0.3.8.dev1 → casambi_bt_revamped-0.3.8.dev3}/src/CasambiBt/_keystore.py +0 -0
- {casambi_bt_revamped-0.3.8.dev1 → casambi_bt_revamped-0.3.8.dev3}/src/CasambiBt/_network.py +0 -0
- {casambi_bt_revamped-0.3.8.dev1 → casambi_bt_revamped-0.3.8.dev3}/src/CasambiBt/_operation.py +0 -0
- {casambi_bt_revamped-0.3.8.dev1 → casambi_bt_revamped-0.3.8.dev3}/src/CasambiBt/errors.py +0 -0
- {casambi_bt_revamped-0.3.8.dev1 → casambi_bt_revamped-0.3.8.dev3}/src/CasambiBt/py.typed +0 -0
- {casambi_bt_revamped-0.3.8.dev1 → casambi_bt_revamped-0.3.8.dev3}/src/casambi_bt_revamped.egg-info/SOURCES.txt +0 -0
- {casambi_bt_revamped-0.3.8.dev1 → casambi_bt_revamped-0.3.8.dev3}/src/casambi_bt_revamped.egg-info/dependency_links.txt +0 -0
- {casambi_bt_revamped-0.3.8.dev1 → casambi_bt_revamped-0.3.8.dev3}/src/casambi_bt_revamped.egg-info/requires.txt +0 -0
- {casambi_bt_revamped-0.3.8.dev1 → casambi_bt_revamped-0.3.8.dev3}/src/casambi_bt_revamped.egg-info/top_level.txt +0 -0
|
@@ -233,18 +233,23 @@ class CasambiClient:
|
|
|
233
233
|
self._callbackQueue.put_nowait((handle, data))
|
|
234
234
|
|
|
235
235
|
async def _processCallbacks(self) -> None:
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
236
|
+
try:
|
|
237
|
+
while True:
|
|
238
|
+
handle, data = await self._callbackQueue.get()
|
|
239
|
+
|
|
240
|
+
# Try to loose any races here.
|
|
241
|
+
# Otherwise a state change caused by the last packet might not have been handled yet
|
|
242
|
+
await asyncio.sleep(0.001)
|
|
243
|
+
await self._activityLock.acquire()
|
|
244
|
+
try:
|
|
245
|
+
self._callbackMulitplexer(handle, data)
|
|
246
|
+
finally:
|
|
247
|
+
self._callbackQueue.task_done()
|
|
248
|
+
self._activityLock.release()
|
|
249
|
+
except asyncio.CancelledError:
|
|
250
|
+
# Task cancelled during shutdown; log at debug and exit cleanly.
|
|
251
|
+
self._logger.debug("Callback processing task cancelled during shutdown.")
|
|
252
|
+
raise
|
|
248
253
|
|
|
249
254
|
def _callbackMulitplexer(
|
|
250
255
|
self, handle: BleakGATTCharacteristic, data: bytes
|
|
@@ -759,8 +764,17 @@ class CasambiClient:
|
|
|
759
764
|
self._logger.info("Disconnecting...")
|
|
760
765
|
|
|
761
766
|
if self._callbackTask is not None:
|
|
767
|
+
# Cancel and await the background callback task to avoid
|
|
768
|
+
# 'Task was destroyed but it is pending' warnings.
|
|
762
769
|
self._callbackTask.cancel()
|
|
763
|
-
|
|
770
|
+
try:
|
|
771
|
+
await self._callbackTask
|
|
772
|
+
except asyncio.CancelledError:
|
|
773
|
+
pass
|
|
774
|
+
except Exception:
|
|
775
|
+
self._logger.debug("Callback task finished with exception during disconnect.", exc_info=True)
|
|
776
|
+
finally:
|
|
777
|
+
self._callbackTask = None
|
|
764
778
|
|
|
765
779
|
if self._gattClient is not None and self._gattClient.is_connected:
|
|
766
780
|
try:
|
|
@@ -111,6 +111,7 @@ class UnitState:
|
|
|
111
111
|
self._colorsource: ColorSource | None = None
|
|
112
112
|
self._xy: tuple[float, float] | None = None
|
|
113
113
|
self._slider: int | None = None
|
|
114
|
+
self._onoff: bool | None = None
|
|
114
115
|
|
|
115
116
|
def _check_range(
|
|
116
117
|
self, value: int | float, min: int | float, max: int | float
|
|
@@ -269,9 +270,20 @@ class UnitState:
|
|
|
269
270
|
def slider(self) -> None:
|
|
270
271
|
self.slider = None
|
|
271
272
|
|
|
272
|
-
|
|
273
|
-
|
|
273
|
+
@property
|
|
274
|
+
def onoff(self) -> bool | None:
|
|
275
|
+
return self._onoff
|
|
276
|
+
|
|
277
|
+
@onoff.setter
|
|
278
|
+
def onoff(self, value: bool) -> None:
|
|
279
|
+
self._onoff = value
|
|
274
280
|
|
|
281
|
+
@onoff.deleter
|
|
282
|
+
def onoff(self) -> None:
|
|
283
|
+
self._onoff = None
|
|
284
|
+
|
|
285
|
+
def __repr__(self) -> str:
|
|
286
|
+
return f"UnitState(dimmer={self.dimmer}, vertical={self._vertical}, rgb={self.rgb.__repr__()}, white={self.white}, temperature={self.temperature}, colorsource={self.colorsource}, xy={self.xy}, slider={self.slider}, onoff={self.onoff})"
|
|
275
287
|
|
|
276
288
|
# TODO: Make unit immutable (refactor state, on, online out of it)
|
|
277
289
|
@dataclass(init=True, repr=True)
|
|
@@ -308,6 +320,8 @@ class Unit:
|
|
|
308
320
|
@property
|
|
309
321
|
def is_on(self) -> bool:
|
|
310
322
|
"""Determine whether the unit is turned on."""
|
|
323
|
+
if self.unitType.get_control(UnitControlType.ONOFF) and self._state:
|
|
324
|
+
return self._on and self._state.onoff is True
|
|
311
325
|
if self.unitType.get_control(UnitControlType.DIMMER) and self._state:
|
|
312
326
|
return (
|
|
313
327
|
self._on and self._state.dimmer is not None and self._state.dimmer > 0
|
|
@@ -385,6 +399,8 @@ class Unit:
|
|
|
385
399
|
elif c.type == UnitControlType.SLIDER and state.slider is not None:
|
|
386
400
|
scale = UnitState.SLIDER_RESOLUTION - c.length
|
|
387
401
|
scaledValue = state.slider >> scale
|
|
402
|
+
elif c.type == UnitControlType.ONOFF and state.onoff is not None:
|
|
403
|
+
scaledValue = 1 if state.onoff else 0
|
|
388
404
|
|
|
389
405
|
# Use default if unsupported type or unset value in state
|
|
390
406
|
else:
|
|
@@ -477,6 +493,8 @@ class Unit:
|
|
|
477
493
|
elif c.type == UnitControlType.SLIDER:
|
|
478
494
|
scale = UnitState.SLIDER_RESOLUTION - c.length
|
|
479
495
|
self._state.slider = cInt << scale
|
|
496
|
+
elif c.type == UnitControlType.ONOFF:
|
|
497
|
+
self._state.onoff = cInt != 0
|
|
480
498
|
elif c.type == UnitControlType.UNKOWN:
|
|
481
499
|
# Might be useful for implementing more state types
|
|
482
500
|
_LOGGER.debug(
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{casambi_bt_revamped-0.3.8.dev1 → casambi_bt_revamped-0.3.8.dev3}/src/CasambiBt/_constants.py
RENAMED
|
File without changes
|
{casambi_bt_revamped-0.3.8.dev1 → casambi_bt_revamped-0.3.8.dev3}/src/CasambiBt/_discover.py
RENAMED
|
File without changes
|
{casambi_bt_revamped-0.3.8.dev1 → casambi_bt_revamped-0.3.8.dev3}/src/CasambiBt/_encryption.py
RENAMED
|
File without changes
|
{casambi_bt_revamped-0.3.8.dev1 → casambi_bt_revamped-0.3.8.dev3}/src/CasambiBt/_keystore.py
RENAMED
|
File without changes
|
|
File without changes
|
{casambi_bt_revamped-0.3.8.dev1 → casambi_bt_revamped-0.3.8.dev3}/src/CasambiBt/_operation.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|