diff light.py @ 11:028ed39aa78f

more ts types; attempted multiplayer but the change events are managed wrong
author drewp@bigasterisk.com
date Sun, 28 Jan 2024 17:31:06 -0800
parents 9f427d8073c3
children 7cc004eafb82
line wrap: on
line diff
--- a/light.py	Sun Jan 28 16:53:35 2024 -0800
+++ b/light.py	Sun Jan 28 17:31:06 2024 -0800
@@ -1,6 +1,7 @@
 import asyncio
 import logging
 from dataclasses import dataclass, field
+from typing import Callable
 
 from color import Color
 
@@ -33,6 +34,8 @@
     online: bool | None = None
     latencyMs: float | None = None
 
+    notifyChanged: Callable | None = None
+
     def __post_init__(self):
         self.requestingDeviceColor = self.deviceColor(self.requestingColor)
 
@@ -54,27 +57,50 @@
         return DeviceColor(r=c.r, g=c.g, b=c.b)
 
     async def setColor(self, c: Color):
+        log.info(f'setColor from {self.requestingColor} to {c}')
+        if c == self.requestingColor:
+            return
         self.requestingColor = c
         self.requestingDeviceColor = self.deviceColor(self.requestingColor)
+        if self.notifyChanged:
+            self.notifyChanged()
 
 
 class Lights:
     _d: dict[str, Light] = {}
+    _changeSleepTask: asyncio.Task | None = None
 
     def __init__(self):
         self.add(Light('do-desk', 'topic1'))
         self.add(Light('do-desk2', 'topic2'))
 
     def add(self, d: Light):
+        d.notifyChanged = self.notifyChanged
         self._d[d.name] = d
 
+        self.notifyChanged()
+
     def byName(self, name: str) -> Light:
         return self._d[name]
 
     async def changes(self):  # yields None on any data change
         while True:
+            log.info('Lights has a change')
             yield None
-            await asyncio.sleep(1)  # todo
+            self._changeSleepTask = asyncio.create_task(self._sleep())
+            try:
+                await self._changeSleepTask
+            except asyncio.CancelledError:
+                pass
+            self._changeSleepTask = None
+
+    async def _sleep(self):
+        await asyncio.sleep(100)
+
+    def notifyChanged(self):
+        log.info('Lights.notifyChanged()')
+        if self._changeSleepTask is not None:
+            self._changeSleepTask.cancel()
 
     def to_dict(self):
         return {'lights': [d.to_dict() for d in sorted(self._d.values(), key=lambda r: r.name)]}