From e1be076265247ce14c491f631bde05607750b2dc Mon Sep 17 00:00:00 2001 From: Joan Date: Wed, 31 Dec 2025 12:23:43 +0100 Subject: [PATCH] Improve layout: 1 decimal temps, humidity display, cleaner arrangement --- matrix.py | 96 +++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 68 insertions(+), 28 deletions(-) diff --git a/matrix.py b/matrix.py index 8de5f10..92fa3ac 100644 --- a/matrix.py +++ b/matrix.py @@ -3,6 +3,13 @@ Matrix64 LED Display - Main Entry Point Displays Home Assistant and Netdata data on a 64x64 LED matrix. + +Layout: + [Weather Icon 24x24] [Outdoor: Temp + Humidity] + [Indoor: Temp + Humidity] + [Time HH:MM:SS centered] + [HDD Temps row 1] + [HDD Temps row 2] """ from samplebase import SampleBase from rgbmatrix import graphics @@ -18,10 +25,26 @@ from home_assistant import ( from netdata import get_hdd_temps +def format_temp(value): + """Format temperature to one decimal place.""" + try: + return f"{float(value):.1f}°" + except (ValueError, TypeError): + return "N/A" + + +def format_humidity(value): + """Format humidity as integer percentage.""" + try: + return f"{int(float(value))}%" + except (ValueError, TypeError): + return "N/A" + + def get_temperature_color(temp): """Determine color based on temperature value.""" try: - temp_value = float(str(temp).replace('°C', '').strip()) + temp_value = float(str(temp).replace('°', '').strip()) if temp_value < 0: return graphics.Color(0, 100, 255) elif temp_value < 10: @@ -60,14 +83,14 @@ class Matrix64Display(SampleBase): # Weather data weather = get_weather() if weather.get("temperature") is not None: - self.temperature = f'{weather.get("temperature")}°C' + self.temperature = float(weather.get("temperature")) self.humidity = weather.get("humidity") self.weather_desc = get_weather_description() # Interior data interior = get_interior_weather() if interior.get("temperature") is not None: - self.interior_temperature = f'{interior.get("temperature")}°C' + self.interior_temperature = float(interior.get("temperature")) self.interior_humidity = interior.get("humidity") except Exception as e: @@ -91,14 +114,18 @@ class Matrix64Display(SampleBase): """Main display loop.""" canvas = self.matrix.CreateFrameCanvas() - # Load fonts (absolute paths to rpi-rgb-led-matrix fonts) + # Load fonts font_dir = "/home/pi/rpi-rgb-led-matrix/fonts" - font = graphics.Font() - font.LoadFont(f"{font_dir}/7x13.bdf") - temp_font = graphics.Font() - temp_font.LoadFont(f"{font_dir}/5x8.bdf") + time_font = graphics.Font() + time_font.LoadFont(f"{font_dir}/7x13.bdf") + small_font = graphics.Font() + small_font.LoadFont(f"{font_dir}/4x6.bdf") - text_color = graphics.Color(20, 75, 200) + # Colors + time_color = graphics.Color(20, 75, 200) + humidity_color = graphics.Color(100, 180, 255) # Light blue for humidity + hdd_color = graphics.Color(80, 80, 80) # Dim gray for HDD temps + label_color = graphics.Color(100, 100, 100) # Gray for labels # Initial data fetch self.update_brightness() @@ -119,30 +146,43 @@ class Matrix64Display(SampleBase): canvas.Clear() - # Time display - graphics.DrawText(canvas, font, 4, 42, text_color, time_str) - - # Weather icon + # === Weather Icon (top-left, 24x24 area) === draw_weather_icon(canvas, 0, 0, self.weather_desc) - # Outdoor temperature (right-aligned) - if self.temperature: - color = get_temperature_color(self.temperature) - length = graphics.DrawText(canvas, temp_font, 0, 0, color, self.temperature) - graphics.DrawText(canvas, temp_font, 64 - length, 8, color, self.temperature) + # === Outdoor Weather (right side, row 1) === + if self.temperature is not None: + temp_str = format_temp(self.temperature) + temp_color = get_temperature_color(self.temperature) + graphics.DrawText(canvas, small_font, 26, 6, temp_color, temp_str) + + if self.humidity is not None: + hum_str = format_humidity(self.humidity) + graphics.DrawText(canvas, small_font, 48, 6, humidity_color, hum_str) - # Interior temperature (right-aligned) - if self.interior_temperature: - color = get_temperature_color(self.interior_temperature) - length = graphics.DrawText(canvas, temp_font, 0, 0, color, self.interior_temperature) - graphics.DrawText(canvas, temp_font, 64 - length, 16, color, self.interior_temperature) + # === Indoor Weather (right side, row 2) === + if self.interior_temperature is not None: + temp_str = format_temp(self.interior_temperature) + temp_color = get_temperature_color(self.interior_temperature) + graphics.DrawText(canvas, small_font, 26, 14, temp_color, temp_str) + + if self.interior_humidity is not None: + hum_str = format_humidity(self.interior_humidity) + graphics.DrawText(canvas, small_font, 48, 14, humidity_color, hum_str) - # HDD temperatures + # === Labels for Out/In === + graphics.DrawText(canvas, small_font, 26, 22, label_color, "Out In") + + # === Time Display (centered) === + time_len = len(time_str) * 7 # 7x13 font is ~7px wide + time_x = (64 - time_len) // 2 + graphics.DrawText(canvas, time_font, time_x, 38, time_color, time_str) + + # === HDD Temperatures (bottom) === if self.hdd_temps and len(self.hdd_temps) > 4: - row1 = " ".join(str(t[0])[:2] for t in self.hdd_temps[1:4]) - row2 = " ".join(str(t[0])[:2] for t in self.hdd_temps[4:]) - graphics.DrawText(canvas, temp_font, 12, 52, text_color, row1) - graphics.DrawText(canvas, temp_font, 12, 60, text_color, row2) + row1 = " ".join(str(int(t[0]))[:2] for t in self.hdd_temps[1:4]) + row2 = " ".join(str(int(t[0]))[:2] for t in self.hdd_temps[4:]) + graphics.DrawText(canvas, small_font, 14, 50, hdd_color, row1) + graphics.DrawText(canvas, small_font, 14, 58, hdd_color, row2) time.sleep(0.5) canvas = self.matrix.SwapOnVSync(canvas)