From 239928ede767501438d1cae2c55793adb8c3923d Mon Sep 17 00:00:00 2001 From: Michael McVady Date: Thu, 26 Feb 2026 10:55:14 -0500 Subject: add color picker --- app.py | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 67 insertions(+), 8 deletions(-) (limited to 'app.py') diff --git a/app.py b/app.py index 89a16cc..4db2c24 100644 --- a/app.py +++ b/app.py @@ -1,5 +1,5 @@ import logging -from colorsys import hsv_to_rgb +from colorsys import hsv_to_rgb, rgb_to_hsv from dataclasses import dataclass from random import randint @@ -8,7 +8,9 @@ from lifxlan import LifxLAN, Light from litestar import Litestar, get, post from litestar.contrib.jinja import JinjaTemplateEngine from litestar.di import Provide +from litestar.enums import RequestEncodingType from litestar.logging import LoggingConfig +from litestar.params import Body from litestar.response import Template from litestar.template import TemplateConfig @@ -17,9 +19,25 @@ TEMPLATE_STR = """ lux + -

{{ message }}

+

{{ message }}

+
+ +
@@ -37,10 +55,29 @@ class RGBColor: green: int blue: int + @classmethod + def from_hex(cls, hex_str: str) -> "RGBColor": + hex_str = hex_str.lstrip("#") + return cls( + red=int(hex_str[0:2], 16), + green=int(hex_str[2:4], 16), + blue=int(hex_str[4:6], 16), + ) + @property def hex(self) -> str: return "#%02X%02X%02X" % (self.red, self.green, self.blue) + @property + def hsbk(self) -> "HSBKColor": + h, s, v = rgb_to_hsv(self.red / 255, self.green / 255, self.blue / 255) + return HSBKColor( + hue=int(h * 65535), + saturation=int(s * 65535), + brightness=int(v * 65535), + kelvin=3500, + ) + @property def yit(self) -> int: yit = ((self.red * 299) + (self.green * 587) + (self.blue * 114)) // 1000 @@ -93,8 +130,7 @@ def get_random_hsbk_color() -> HSBKColor: ) -def random_color(lux: Light) -> Template: - hsbk = get_random_hsbk_color() +def _set_light_color(lux: Light, hsbk: HSBKColor) -> Template: log.info(f"Setting color to {hsbk} {hsbk.rgb}") try: @@ -105,7 +141,12 @@ def random_color(lux: Light) -> Template: log.exception("Error setting color") return Template( template_str=TEMPLATE_STR, - context={"color": DEFAULT_COLOR, "message": f"error: {str(e)}"}, + context={ + "background_color": DEFAULT_COLOR, + "color": "white", + "message": f"error: {str(e)}", + "current_color": DEFAULT_COLOR, + }, ) rgb = hsbk.rgb @@ -117,20 +158,38 @@ def random_color(lux: Light) -> Template: "background_color": rgb_hex, "color": text_color, "message": rgb_hex, + "current_color": rgb_hex, }, ) +def random_color(lux: Light) -> Template: + return _set_light_color(lux, get_random_hsbk_color()) + + +def chosen_color(lux: Light, hex_color: str) -> Template: + rgb = RGBColor.from_hex(hex_color) + return _set_light_color(lux, rgb.hsbk) + + @get("/") async def get_index(lux: Light = Provide(get_lux)) -> Template: """Return index""" return random_color(lux) +@dataclass +class ColorForm: + color: str + + @post("/") -async def post_index(lux: Light = Provide(get_lux)) -> Template: - """Update index""" - return random_color(lux) +async def post_index( + data: ColorForm = Body(media_type=RequestEncodingType.URL_ENCODED), + lux: Light = Provide(get_lux), +) -> Template: + """Set light to chosen color""" + return chosen_color(lux, data.color) app = Litestar( -- cgit v1.2.3