import logging import math from threading import Timer import bdfparser from sense_hat import SenseHat logger = logging.getLogger(__name__) COLORS = { "Bleu": [0, 0, 255], "Blanc": [255, 255, 255], "Rouge": [255, 0, 0], "Verte": [0, 127, 31], "Jaune": [255, 255, 0], "heat": [255, 0, 0], "heating": [255, 0, 0], "idle": [127, 0, 255], "off": [127, 127, 127], "on_setting": [255, 255, 0], "off_setting": [255, 255, 255], None: [0, 0, 0], } class Screen: def __init__(self): self.sense = SenseHat() self._value = "" self._tmp = False self._tmp_value = None self._mode = None self.font = bdfparser.Font("src/tom-thumb.bdf") self._secondary = dict() self._secondary_pixels = [[0, 0, 0]] * 8 self.timer = Timer(0, self.set_pixels) self._held = False self.sense.stick.direction_middle = self.stick_click @property def value(self): return self._value @value.setter def value(self, value): logger.debug(f"Updated value: <{value}>") self._value = format_value(value) if not self._tmp: self.set_pixels() @property def color(self): return COLORS.get(self.mode, [0, 0, 0]) @property def mode(self): return self._mode @mode.setter def mode(self, value): self._mode = value if not self._tmp: self.set_pixels() @property def tmp_value(self): return self._tmp_value @tmp_value.setter def tmp_value(self, value): logger.debug(f"Show value: <{value}>") self.timer.cancel() self._tmp_value = format_value(value) self.show_tmp() def show_tmp(self): self._tmp = True self.set_pixels( self.tmp_value, color=COLORS.get("off_setting" if self.mode == "off" else "on_setting"), ) self.timer = Timer(3, self.set_pixels) self.timer.start() def set_pixels(self, value=None, color=None, bg_color=[0, 0, 0]): if value is None: value = self.value self._tmp = False if color is None: color = self.color if value: pixels = [ color if x else bg_color for x in self.font.draw(value, mode=0).crop(8, 7).todata(3) ] else: pixels = 48 * [[0, 0, 0]] pixels += self.secondary_pixels self.sense.set_pixels(pixels) @property def secondary(self): return self._secondary @secondary.setter def secondary(self, value): self._secondary = value for idx in range(2): self._secondary_pixels[4 * idx : 4 * (idx + 1)] = [ COLORS.get(value.get(idx, None), [0, 0, 0]) ] * 4 if not self._tmp: self.set_pixels() @property def secondary_pixels(self): return self._secondary_pixels def stick_click(self, event): match (event.action, self._held): case ("held", False): self._held = True case ("released", True): self._held = False case ("released", False): self.show_tmp() def format_value(value): v = math.trunc(value) d = "." if (value - v) >= 0.5 else "" return f"{v}{d}"