changeset 9:9f427d8073c3

redo data model; add ui colors
author drewp@bigasterisk.com
date Sun, 28 Jan 2024 16:53:08 -0800
parents 181a86533286
children 140633abfa2a
files color.py light.py src/main.ts
diffstat 3 files changed, 81 insertions(+), 37 deletions(-) [+]
line wrap: on
line diff
--- a/color.py	Sun Jan 28 16:51:36 2024 -0800
+++ b/color.py	Sun Jan 28 16:53:08 2024 -0800
@@ -37,3 +37,11 @@
     def hex(self):
         r, g, b = int(self.r * 255), int(self.g * 255), int(self.b * 255)
         return '#%02x%02x%02x' % (r, g, b)
+
+    @classmethod
+    def fromHex(cls, h: str):
+        return cls(
+            r=int(h[1:3], 16) / 255,
+            g=int(h[3:5], 16) / 255,
+            b=int(h[5:7], 16) / 255,
+        )
--- a/light.py	Sun Jan 28 16:51:36 2024 -0800
+++ b/light.py	Sun Jan 28 16:53:08 2024 -0800
@@ -1,42 +1,69 @@
 import asyncio
 import logging
-from dataclasses import dataclass
+from dataclasses import dataclass, field
 
 from color import Color
 
 log = logging.getLogger('light')
 
 
+@dataclass(frozen=True)
+class DeviceColor:
+    """neutral representation of the adjusted color that we send to a device"""
+    r: float = 0
+    g: float = 0
+    b: float = 0
+    w: float = 0
+    x: float = 0
+    y: float = 0
+
+    def summary(self) -> dict:
+        return dict([(k, round(v, 3)) for k, v in self.__dict__.items() if v > 0])
+
+
 @dataclass
 class Light:
     name: str
     address: str
-    online: bool
-    colorRequest: Color
-    colorMessage: dict
-    colorCurrent: Color
-    latencyMs: float
+
+    requestingColor: Color = Color.fromHex('#000000')
+    requestingDeviceColor: DeviceColor = DeviceColor()
+
+    emittingColor: Color = Color.fromHex('#000000')
+    online: bool | None = None
+    latencyMs: float | None = None
+
+    def __post_init__(self):
+        self.requestingDeviceColor = self.deviceColor(self.requestingColor)
 
     def to_dict(self):
-        return {
-            'light': {
-                'name': self.name,
-                'address': self.address,
-                'online': self.online,
-                'colorRequest': self.colorRequest.to_js(),
-                'colorMessage': self.colorMessage,
-                'colorCurrent': self.colorCurrent.to_js(),
-                'latencyMs': self.latencyMs,
-            }
+        d = {
+            'name': self.name,
+            'address': self.address,
+            'requestingColor': self.requestingColor.hex(),
+            'requestingDeviceColor': self.requestingDeviceColor.summary(),
+            'emittingColor': self.emittingColor.hex(),
+            'online': self.online,
+            'latencyMs': self.latencyMs,
         }
 
+        return {'light': d}
+
+    def deviceColor(self, c: Color) -> DeviceColor:
+        # do LUT here
+        return DeviceColor(r=c.r, g=c.g, b=c.b)
+
+    async def setColor(self, c: Color):
+        self.requestingColor = c
+        self.requestingDeviceColor = self.deviceColor(self.requestingColor)
+
 
 class Lights:
     _d: dict[str, Light] = {}
 
     def __init__(self):
-        self.add(Light('do-desk', 'topic1', True, Color('#ff0000'), {'r': 255}, Color('#000000'), 100))
-        self.add(Light('do-desk2', 'topic2', True, Color('#ff00ff'), {'r': 255}, Color('#000000'), 200))
+        self.add(Light('do-desk', 'topic1'))
+        self.add(Light('do-desk2', 'topic2'))
 
     def add(self, d: Light):
         self._d[d.name] = d
--- a/src/main.ts	Sun Jan 28 16:51:36 2024 -0800
+++ b/src/main.ts	Sun Jan 28 16:53:08 2024 -0800
@@ -26,12 +26,21 @@
         margin: 3px;
         vertical-align: middle;
       }
+      .col-group-1 {
+        background: #e0ecf4;
+      }
+      .col-group-2 {
+        background: #e0f3db;
+      }
+      .col-group-3 {
+        background: #fee8c8;
+      }
     `,
   ];
 
   // bug https://github.com/lit/lit/issues/4305
-  @(state as any)() lights: object[] = [];
-  @(state as any)() reportTime: Date = new Date(0);
+  @((state as any)()) lights: object[] = [];
+  @((state as any)()) reportTime: Date = new Date(0);
 
   connectedCallback(): void {
     super.connectedCallback();
@@ -48,27 +57,27 @@
 
       <table>
         <tr>
-          <th>light</th>
-          <th>address</th>
-          <th>online</th>
-          <th>color request</th>
-          <th>color message</th>
-          <th>color current</th>
-          <th>latency</th>
+          <th class="col-group-1">light</th>
+          <th class="col-group-1">address</th>
+          <th class="col-group-2">requested color</th>
+          <th class="col-group-2">requested device color</th>
+          <th class="col-group-3">emitting color</th>
+          <th class="col-group-3">online</th>
+          <th class="col-group-3">latency</th>
         </tr>
         ${this.lights.map(
           (d: any) => html`
             <tr>
-              <td>${d.light.name}</td>
-              <td><code>${d.light.address}</code></td>
-              <td>${d.light.online ? "✔" : ""}</td>
-              <td>
-                <code>${d.light.colorRequest}</code>
-                <input type="color" @input=${this.onColorRequest.bind(this, d.light.name)} value="${d.light.colorRequest}" />
+              <td class="col-group-1">${d.light.name}</td>
+              <td class="col-group-1"><code>${d.light.address}</code></td>
+              <td class="col-group-2">
+                <code>${d.light.requestingColor}</code>
+                <input type="color" @input=${this.onRequestingColor.bind(this, d.light.name)} .value="${d.light.requestingColor}" />
               </td>
-              <td><code>${JSON.stringify(d.light.colorMessage)}</code></td>
-              <td>${d.light.colorCurrent} <span class="color" style="background: ${d.light.colorCurrent}"></span></td>
-              <td>${d.light.latencyMs} ms</td>
+              <td class="col-group-2"><code>${JSON.stringify(d.light.requestingDeviceColor)}</code></td>
+              <td class="col-group-3">${d.light.emittingColor} <span class="color" style="background: ${d.light.emittingColor}"></span></td>
+              <td class="col-group-3">${d.light.online ? "✔" : ""}</td>
+              <td class="col-group-3">${d.light.latencyMs} ms</td>
             </tr>
           `
         )}
@@ -81,7 +90,7 @@
       <bigast-loginbar></bigast-loginbar>
     `;
   }
-  onColorRequest(lightName: string, ev: InputEvent) {
+  onRequestingColor(lightName: string, ev: InputEvent) {
     const value = (ev.target as HTMLInputElement).value;
     const url = new URL("api/output", location as any);
     url.searchParams.append("light", lightName);