From 5b7f4c29e11889ebc12bb6156ccc413d85b1e4ba Mon Sep 17 00:00:00 2001 From: "Edgar P. Burkhart" Date: Mon, 11 Nov 2024 17:53:25 +0100 Subject: [PATCH] Add topic for color change without switch on, add toggle on joystick click --- oin_ha/display/__init__.py | 85 +++++++++++++++++++++++++++----------- 1 file changed, 60 insertions(+), 25 deletions(-) diff --git a/oin_ha/display/__init__.py b/oin_ha/display/__init__.py index d2dd9d4..5104719 100644 --- a/oin_ha/display/__init__.py +++ b/oin_ha/display/__init__.py @@ -32,28 +32,39 @@ class Display: "availability_topic": self.availability_topic, } - self.main_light = Light("LED", self.uid, "led", self.sense, **options) + self.main_light = Light( + "LED", self.uid, "led", self.sense, mqttc=self.mqttc, **options + ) def publish_discovery(self): - self.main_light.publish_discovery(self.mqttc) + self.main_light.publish_discovery() def publish_online(self): self.subscribe() self.mqttc.publish(self.availability_topic, "online", retain=True) def subscribe(self): - self.main_light.subscribe(self.mqttc) + self.main_light.subscribe() def on_message(self, *args, **kwargs): self.main_light.on_message(*args, **kwargs) class Light: - def __init__(self, name, parent_uid, slug, sense, n=3, **kwargs): + _colors = { + "Bleu": [0, 0, 255], + "Blanc": [255, 255, 255], + "Rouge": [255, 0, 0], + "Verte": [0, 255, 0], + "Jaune": [255, 255, 0], + } + + def __init__(self, name, parent_uid, slug, sense, mqttc, n=6, **kwargs): self.name = name self.parent_uid = parent_uid self.slug = slug self.sense = sense + self.mqttc = mqttc self.options = kwargs self._switch = False @@ -68,17 +79,18 @@ class Light: self.sense.stick.direction_right = self.switch_screen self.sense.stick.direction_left = self.switch_screen_rev + self.sense.stick.direction_middle = self.toggle - def publish_discovery(self, mqttc): + def publish_discovery(self): for i in range(self._n): - mqttc.publish( + self.mqttc.publish( self.get_discovery_topic(i), json.dumps( { "command_topic": self.command_topic(i, "command"), "effect_command_topic": self.command_topic(i, "effect"), "effect_list": ["Low Light", "Normal"], - "effect_state_topie": self.state_topic, + "effect_state_topic": self.state_topic, "effect_value_template": "{{ value_json.effect }}", "icon": "mdi:dots-grid", "name": f"{self.name} {i}", @@ -95,14 +107,15 @@ class Light: ), retain=True, ) - self.publish_state(mqttc) + self.publish_state() - def subscribe(self, mqttc): + def subscribe(self): for i in range(self._n): - mqttc.subscribe(self.command_topic(i, "command")) - mqttc.subscribe(self.command_topic(i, "effect")) - mqttc.subscribe(self.command_topic(i, "rgb")) - mqttc.subscribe(self.command_topic(i, "value")) + self.mqttc.subscribe(self.command_topic(i, "command")) + self.mqttc.subscribe(self.command_topic(i, "effect")) + self.mqttc.subscribe(self.command_topic(i, "rgb")) + self.mqttc.subscribe(self.command_topic(i, "value")) + self.mqttc.subscribe(self.command_topic(i, "action_color")) def on_message(self, client, userdata, message): data = message.payload.decode() @@ -115,19 +128,20 @@ class Light: case [*rgb]: self.set_color(int(i), list(map(int, rgb))) case [self.base_topic, i, "effect"]: - self.sense.low_light = data == "Low Light" + self.low_light = data == "Low Light" case [self.base_topic, i, "value"]: self.set_value(int(i), data) + case [self.base_topic, i, "action_color"]: + self.set_color(int(i), self._colors.get(data, [0, 0, 0]), False) case _: return - self.publish_state(client) - def publish_state(self, mqttc): - mqttc.publish( + def publish_state(self): + self.mqttc.publish( self.state_topic, json.dumps( { - "effect": "Low Light" if self.sense.low_light else "Normal", + "effect": "Low Light" if self.low_light else "Normal", "rgb": self.rgb, "state": self.state, } @@ -164,6 +178,7 @@ class Light: self.update_value() else: self.sense.clear() + self.publish_state() @property def state(self): @@ -173,12 +188,13 @@ class Light: def color(self): return self._color - def set_color(self, i, value): + def set_color(self, i, value, switch=True): self._color[i] = value - if not self.switch: + if switch and not self.switch: self.switch = True if i == self._i: self.display_value() + self.publish_state() @property def rgb(self): @@ -188,6 +204,15 @@ class Light: def value(self): return f"{self._pres[self._i]} {self._values[self._i]}" + @property + def low_light(self): + return self.sense.low_light + + @low_light.setter + def low_light(self, value): + self.sense.low_light = value + self.publish_state() + def set_value(self, i, value): match value.split(): case [val]: @@ -198,6 +223,7 @@ class Light: self._values[i] = val if i == self._i: self.display_value() + self.publish_state() def update_value(self): if not self.switch: @@ -207,17 +233,16 @@ class Light: self.display_value() return - self.timer.cancel() - pixels = self.to_pixels(self._pres[self._i]) self.sense.set_pixels(pixels) - self.timer = Timer(0.25, self.display_value, kwargs=dict(timer=True)) + self.timer = Timer(0.5, self.display_value, kwargs=dict(timer=True)) self.timer.start() def display_value(self, timer=False): if (not timer and self.timer.is_alive()) or not self.switch: return + self.timer.cancel() pixels = self.to_pixels(self._values[self._i]) self.sense.set_pixels(pixels) @@ -234,9 +259,19 @@ class Light: def switch_screen(self, event): if event.action == ACTION_RELEASED: self._i = (self._i + 1) % self._n - self.update_value() + self.switch = True def switch_screen_rev(self, event): if event.action == ACTION_RELEASED: self._i = (self._i - 1) % self._n - self.update_value() + self.switch = True + + def toggle(self, event): + if event.action == ACTION_RELEASED: + if not self.switch: + self.low_light = False + self.switch = True + elif self.low_light: + self.switch = False + else: + self.low_light = True