changeset 21:b8201490c731

more light types
author drewp@bigasterisk.com
date Mon, 29 Jan 2024 12:27:08 -0800
parents 24a574108365
children 178e020289c1
files color_convert.py light.py protocols.py
diffstat 3 files changed, 100 insertions(+), 28 deletions(-) [+]
line wrap: on
line diff
--- a/color_convert.py	Mon Jan 29 11:52:43 2024 -0800
+++ b/color_convert.py	Mon Jan 29 12:27:08 2024 -0800
@@ -18,19 +18,31 @@
     cw: float = 0
     ww: float = 0
     brightness: float = 0
+    temp: float = 0
 
     def summary(self) -> dict:
         return dict([(k, round(v, 3)) for k, v in self.__dict__.items() if v > 0])
 
+
 # fix this to send what z2m likes
 def zbConv(c: Color) -> DeviceColor:
     return DeviceColor(r=c.r, g=c.g, b=c.b, brightness=max(c.r, c.g, c.b))
 
+
+def ikeaWhiteConv(c: Color) -> DeviceColor:
+    return DeviceColor(brightness=max(c.r, c.g, c.b), temp=454)
+
+
 def oneWhiteConv(c: Color) -> DeviceColor:
     return DeviceColor(r=c.r, g=c.g, b=c.b, w=max(c.r, c.g, c.b))
 
+def brightnessConv(c: Color) -> DeviceColor:
+    return DeviceColor(brightness=max(c.r, c.g, c.b))
+
+
 def twoWhitesConv(c: Color) -> DeviceColor:
-    return DeviceColor(r=c.r, g=c.g, b=c.b, cw=max(c.r, c.g, c.b))
+    return DeviceColor(r=c.r, g=c.g, b=c.b, cw=max(c.r, c.g, c.b), ww=0)
+
 
 def relayConv(c: Color) -> DeviceColor:
-    return DeviceColor(brightness=1 if (max(c.r, c.g, c.b) > 0) else 0)
\ No newline at end of file
+    return DeviceColor(brightness=1 if (max(c.r, c.g, c.b) > 0) else 0)
--- a/light.py	Mon Jan 29 11:52:43 2024 -0800
+++ b/light.py	Mon Jan 29 12:27:08 2024 -0800
@@ -4,9 +4,9 @@
 from typing import Callable
 
 from color import Color
-from color_convert import DeviceColor, oneWhiteConv, relayConv, twoWhitesConv, zbConv
+from color_convert import DeviceColor, brightnessConv, ikeaWhiteConv, oneWhiteConv, relayConv, twoWhitesConv, zbConv
 from mqtt_io import MqttIo
-from protocols import ShellyGen1WebTransport, SonoffRelayTransport, TasmotaWebTransport, Transport, ZigbeeTransport
+from protocols import ShellyGen1WebTransport, SonoffRelayTransport, TasmotaWebTransport, Transport, ZigbeeTransport, zbBrightnessMessage, zbRelayMessage, zbWhiteSpectrumMessage
 
 log = logging.getLogger('lite')
 
@@ -80,6 +80,24 @@
     return Light(name=name, convertColor=relayConv, transport=SonoffRelayTransport(mqtt, topic))
 
 
+def makeZbIkeaWhiteTemp(mqtt: MqttIo, name: str, ieee: str) -> Light:
+    return Light(name=name, convertColor=ikeaWhiteConv, transport=ZigbeeTransport(mqtt, name, ieee, msg=zbWhiteSpectrumMessage))
+
+
+def makeZbBrightness(mqtt: MqttIo, name: str, ieee: str) -> Light:
+    return Light(name=name, convertColor=brightnessConv, transport=ZigbeeTransport(mqtt, name, ieee, msg=zbBrightnessMessage))
+
+
+def makeZbRelay(mqtt: MqttIo, name: str, ieee: str) -> Light:
+    return Light(name=name, convertColor=relayConv, transport=ZigbeeTransport(mqtt, name, ieee, msg=zbRelayMessage))
+
+
+def makeEspBrightness(mqtt: MqttIo, name: str, topicPrefix: str) -> Light:
+    return Light(name=name,
+                 convertColor=brightnessConv,
+                 transport=ZigbeeTransport(mqtt, name, '', topic=lambda *arg: topicPrefix + '/command', msg=zbBrightnessMessage))
+
+
 class Lights:
     _d: dict[str, Light] = {}
 
@@ -88,27 +106,20 @@
 
         self.add(makeZbBar(mqtt, 'do-bar', '0xa4c13844948d2da4'))
         self.add(makeTasmota('do-lamp', 'tasmota-9E2AB7-2743'))
+        self.add(makeTasmota('li-high-shelf', 'light-li-ceil'))
+        self.add(makeTasmota('tr-door', 'light-tr-door'))
         self.add(makeShellyRGW2('ki-ceiling', 'shellyrgbw2-e868e7f34c35'))
         self.add(makeShellyRGW2('ki-counter', 'shellyrgbw2-e868e7f34cb2'))
-        # br-floor	online=online | metric=1 (graph)	lqi=93	bright=12
-        # br-wall	online=online | metric=1 (graph)	lqi=30	bright=0
 
-        # en	online=online | metric=1 (graph)	lqi=36	bright=216
-        # ft-ceil	online=online | metric=1 (graph)	lqi=96	bright=252
-        # go-high	online=online | metric=1 (graph)	lqi=93	bright=253
-        # li-toys	online=online | metric=1 (graph)	lqi=96	bright=28
-        # py	online=online | metric=1 (graph)	lqi=93	bright=216
-        # rr-lamp	online=offline | metric=0 (graph)	lqi=...	bright=...
-        # sh-top	online=online | metric=1 (graph)	lqi=93	bright=254
-        # ws-hanging	online=online | metric=1 (graph)	lqi=39	bright=...
-        # light-li-high-shelf	uptimesec=2232334	wifi=-65	dim=100 color=0000002FD0
-        # light-sh	uptimesec=...	wifi=...	dim=... color=...
-        # light-tr-wall	uptimesec=5082251	wifi=-38	dim=34 color=5700000000
+        self.add(makeZbIkeaWhiteTemp(mqtt, 'br-floor', '0x000b57fffedabd20'))
+        self.add(makeZbIkeaWhiteTemp(mqtt, 'br-wall', '0x14b457fffe2dab6e'))
+        self.add(makeZbIkeaWhiteTemp(mqtt, 'en', '0x000b57fffe988959'))
+        self.add(makeZbIkeaWhiteTemp(mqtt, 'py', '0x000b57fffeaf42cd'))
+        self.add(makeZbIkeaWhiteTemp(mqtt, 'rr-lamp', '0x000b57fffe32e5a5'))
 
-        # wled-ft-hanging	offline		#FFA000 bright=128
-        # string-tr	online		#8CFF82 bright=128
-        # light-tr-ball	online		#808A03 bright=12
-        # string-hr	online		#C9FFDC bright=131
+        self.add(makeZbBrightness(mqtt, 'go-high', '0x847127fffebb3efa'))
+
+        self.add(makeZbRelay(mqtt, 'ws-hanging', '0xd0cf5efffe720b46'))
 
         self.add(makeSonoffRelay(mqtt, 'li-lamp0', 'sonoff_0'))
         self.add(makeSonoffRelay(mqtt, 'li-lamp1', 'sonoff_1'))
@@ -116,6 +127,25 @@
         self.add(makeSonoffRelay(mqtt, 'li-lamp3', 'sonoff_3'))
         self.add(makeSonoffRelay(mqtt, 'li-lamp4', 'sonoff_4'))
 
+        self.add(makeEspBrightness(mqtt, 'ws-high0', 'workshop/light/high0'))
+        self.add(makeEspBrightness(mqtt, 'ws-high1', 'workshop/light/high1'))
+        self.add(makeEspBrightness(mqtt, 'ws-high2', 'workshop/light/high2'))
+        self.add(makeEspBrightness(mqtt, 'ws-high3', 'workshop/light/high3'))
+        self.add(makeEspBrightness(mqtt, 'ws-kid', 'workshop/light/kid'))
+        self.add(makeEspBrightness(mqtt, 'ws-sewing', 'workshop/light/sewing'))
+
+        # ft-ceil
+        # li-toys
+        # sh-top
+        # light-sh
+        # ga-hanging
+
+        # wled:
+        #  string-tr
+        #  string-hr
+        #  light-tr-ball
+        #  wled-ft-hanging
+
     def add(self, d: Light):
         d.notifyChanged = self.notifyChanged
         self._d[d.name] = d
--- a/protocols.py	Mon Jan 29 11:52:43 2024 -0800
+++ b/protocols.py	Mon Jan 29 12:27:08 2024 -0800
@@ -6,6 +6,7 @@
 
 log = logging.getLogger('prot')
 
+
 class Transport:
 
     def linked(self):
@@ -15,25 +16,54 @@
         raise TypeError
 
 
-def zigbeeHexMessage(dc: DeviceColor) -> dict:
-    msg: dict = {"transition": 0, "brightness": int(255 * dc.brightness)}
-    c = "#%02x%02x%02x" % (int(dc.r * 255), int(dc.g * 255), int(dc.b * 255))
-    msg["color"] = {"hex": c}
-    return msg
+def to8(x: float):
+    return int(x * 255)
+
+
+def zbColorMessage(dc: DeviceColor) -> dict:
+    return {
+        "transition": 0,
+        "brightness": to8(dc.brightness),
+        "color": {
+            "hex": "#%02x%02x%02x" % (to8(dc.r), to8(dc.g), to8(dc.b))
+        },
+    }
+
 
+def zbBrightnessMessage(dc: DeviceColor) -> dict:
+    return {
+        "transition": 0,
+        "brightness": to8(dc.brightness),
+    }
+
+
+def zbWhiteSpectrumMessage(dc: DeviceColor) -> dict:
+    return {
+        "transition": 0,
+        "brightness": to8(dc.brightness),
+        # temperature todo
+    }
+
+def zbRelayMessage(dc: DeviceColor) -> dict:
+    return {'state': 'ON' if dc.brightness else 'OFF'}
+
+def z2mSet(name):
+    return f'zigbee/{name}/set'
 
 class ZigbeeTransport(Transport):
 
-    def __init__(self, mqtt: MqttIo, name: str, ieee: str):
+    def __init__(self, mqtt: MqttIo, name: str, ieee: str, topic=z2mSet, msg=zbColorMessage):
         self.mqtt = mqtt
         self.name = name
         self.ieee = ieee
+        self.topic=topic
+        self.msg = msg
 
     def linked(self):
         return {'url': f'https://bigasterisk.com/zigbee/console/#/device/{self.ieee}/info', 'label': self.name}
 
     async def send(self, dc: DeviceColor):
-        await self.mqtt.publish(f'zigbee/{self.name}/set', json.dumps(zigbeeHexMessage(dc)))
+        await self.mqtt.publish(self.topic(self.name), json.dumps(self.msg(dc)))
 
 
 class SonoffRelayTransport(Transport):