Layout Option A: vertical stack, HDD in corner
This commit is contained in:
93
matrix.py
93
matrix.py
@@ -4,12 +4,11 @@ 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]
|
||||
Layout (Option A - Vertical Stack):
|
||||
[Weather 24x24] [Out 21.5° 65%]
|
||||
[In 22.3° 58%]
|
||||
[12:31:05 centered]
|
||||
[HDD temps corner]
|
||||
"""
|
||||
from samplebase import SampleBase
|
||||
from rgbmatrix import graphics
|
||||
@@ -28,23 +27,23 @@ from netdata import get_hdd_temps
|
||||
def format_temp(value):
|
||||
"""Format temperature to one decimal place."""
|
||||
try:
|
||||
return f"{float(value):.1f}°"
|
||||
return f"{float(value):.1f}"
|
||||
except (ValueError, TypeError):
|
||||
return "N/A"
|
||||
return "?"
|
||||
|
||||
|
||||
def format_humidity(value):
|
||||
"""Format humidity as integer percentage."""
|
||||
try:
|
||||
return f"{int(float(value))}%"
|
||||
return f"{int(float(value))}"
|
||||
except (ValueError, TypeError):
|
||||
return "N/A"
|
||||
return "?"
|
||||
|
||||
|
||||
def get_temperature_color(temp):
|
||||
"""Determine color based on temperature value."""
|
||||
try:
|
||||
temp_value = float(str(temp).replace('°', '').strip())
|
||||
temp_value = float(temp) if isinstance(temp, (int, float)) else float(str(temp).replace('°', '').strip())
|
||||
if temp_value < 0:
|
||||
return graphics.Color(0, 100, 255)
|
||||
elif temp_value < 10:
|
||||
@@ -64,11 +63,7 @@ class Matrix64Display(SampleBase):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(Matrix64Display, self).__init__(*args, **kwargs)
|
||||
self.parser.add_argument(
|
||||
"-t", "--text",
|
||||
help="The text to scroll on the RGB LED panel",
|
||||
default="Hello world!"
|
||||
)
|
||||
self.parser.add_argument("-t", "--text", help="Text", default="")
|
||||
self.temperature = None
|
||||
self.humidity = None
|
||||
self.interior_temperature = None
|
||||
@@ -80,19 +75,16 @@ class Matrix64Display(SampleBase):
|
||||
def update_data(self):
|
||||
"""Fetch all data from APIs."""
|
||||
try:
|
||||
# Weather data
|
||||
weather = get_weather()
|
||||
if weather.get("temperature") is not None:
|
||||
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 = float(interior.get("temperature"))
|
||||
self.interior_humidity = interior.get("humidity")
|
||||
|
||||
except Exception as e:
|
||||
print(f"Error updating data: {e}")
|
||||
|
||||
@@ -104,7 +96,6 @@ class Matrix64Display(SampleBase):
|
||||
self.matrix.brightness = int(float(brightness)) / 10
|
||||
except Exception as e:
|
||||
self.matrix.brightness = 5
|
||||
print(f"Error updating brightness: {e}")
|
||||
|
||||
def update_hdd_temps(self):
|
||||
"""Update HDD temperatures."""
|
||||
@@ -124,12 +115,14 @@ class Matrix64Display(SampleBase):
|
||||
small_font.LoadFont(f"{font_dir}/4x6.bdf")
|
||||
|
||||
# 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(120, 120, 120) # Gray for labels
|
||||
time_color = graphics.Color(30, 90, 220)
|
||||
humidity_color = graphics.Color(80, 160, 255)
|
||||
hdd_color = graphics.Color(60, 60, 60)
|
||||
label_color = graphics.Color(100, 100, 100)
|
||||
degree_color = graphics.Color(150, 150, 150)
|
||||
percent_color = graphics.Color(100, 140, 180)
|
||||
|
||||
# Initial data fetch
|
||||
# Initial fetch
|
||||
self.update_brightness()
|
||||
self.update_data()
|
||||
self.update_hdd_temps()
|
||||
@@ -139,7 +132,6 @@ class Matrix64Display(SampleBase):
|
||||
time_str = f"{now.hour:02d}:{now.minute:02d}:{now.second:02d}"
|
||||
current_time = time.time()
|
||||
|
||||
# Update every 60 seconds
|
||||
if current_time - self.last_update >= 60:
|
||||
self.update_data()
|
||||
self.update_brightness()
|
||||
@@ -148,44 +140,43 @@ class Matrix64Display(SampleBase):
|
||||
|
||||
canvas.Clear()
|
||||
|
||||
# === Weather Icon (top-left, 24x24 area) ===
|
||||
# === Weather Icon (top-left, 24x24) ===
|
||||
draw_weather_icon(canvas, 0, 0, self.weather_desc)
|
||||
|
||||
# === Labels at top (right side) ===
|
||||
graphics.DrawText(canvas, small_font, 28, 6, label_color, "Out")
|
||||
graphics.DrawText(canvas, small_font, 48, 6, label_color, "In")
|
||||
|
||||
# === Temperatures (row below labels) ===
|
||||
# === Row 1: Outdoor - "Out" label + temp + humidity ===
|
||||
graphics.DrawText(canvas, small_font, 26, 6, label_color, "Out")
|
||||
if self.temperature is not None:
|
||||
temp_str = format_temp(self.temperature)
|
||||
temp_color = get_temperature_color(self.temperature)
|
||||
graphics.DrawText(canvas, data_font, 26, 14, temp_color, temp_str)
|
||||
|
||||
graphics.DrawText(canvas, small_font, 40, 6, temp_color, temp_str)
|
||||
if self.humidity is not None:
|
||||
hum_str = format_humidity(self.humidity)
|
||||
graphics.DrawText(canvas, small_font, 55, 6, humidity_color, hum_str)
|
||||
|
||||
# === Row 2: Indoor - "In" label + temp + humidity ===
|
||||
graphics.DrawText(canvas, small_font, 26, 14, label_color, "In")
|
||||
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, data_font, 46, 14, temp_color, temp_str)
|
||||
|
||||
# === Humidity (row below temps) ===
|
||||
if self.humidity is not None:
|
||||
hum_str = format_humidity(self.humidity)
|
||||
graphics.DrawText(canvas, data_font, 26, 22, humidity_color, hum_str)
|
||||
|
||||
graphics.DrawText(canvas, small_font, 40, 14, temp_color, temp_str)
|
||||
if self.interior_humidity is not None:
|
||||
hum_str = format_humidity(self.interior_humidity)
|
||||
graphics.DrawText(canvas, data_font, 46, 22, humidity_color, hum_str)
|
||||
graphics.DrawText(canvas, small_font, 55, 14, humidity_color, hum_str)
|
||||
|
||||
# === Time Display (centered) ===
|
||||
time_len = len(time_str) * 7
|
||||
time_x = (64 - time_len) // 2
|
||||
# === Time Display (centered, y=38) ===
|
||||
time_x = (64 - len(time_str) * 7) // 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(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, data_font, 10, 50, hdd_color, row1)
|
||||
graphics.DrawText(canvas, data_font, 10, 60, hdd_color, row2)
|
||||
# === HDD Temps (bottom-right corner) ===
|
||||
if self.hdd_temps and len(self.hdd_temps) > 1:
|
||||
# Compact: show all temps in 2 rows, right-aligned
|
||||
temps = [str(int(t[0])) for t in self.hdd_temps[1:] if t]
|
||||
if len(temps) >= 3:
|
||||
row1 = " ".join(temps[:3])
|
||||
graphics.DrawText(canvas, small_font, 40, 52, hdd_color, row1)
|
||||
if len(temps) > 3:
|
||||
row2 = " ".join(temps[3:6])
|
||||
graphics.DrawText(canvas, small_font, 40, 60, hdd_color, row2)
|
||||
|
||||
time.sleep(0.5)
|
||||
canvas = self.matrix.SwapOnVSync(canvas)
|
||||
|
||||
Reference in New Issue
Block a user