AI bug squash sesh

This commit is contained in:
Chuck
2025-08-09 21:00:25 -05:00
parent 79cbc46f9b
commit 85d63243c7
13 changed files with 41 additions and 9 deletions

View File

@@ -5,3 +5,4 @@ eventlet>=0.33.3
Pillow>=10.0.0 Pillow>=10.0.0
psutil>=5.9.0 psutil>=5.9.0
werkzeug>=2.3.0 werkzeug>=2.3.0
freetype-py>=2.3.0

View File

@@ -347,6 +347,16 @@ class DisplayController:
# Update display durations to include all modes # Update display durations to include all modes
self.display_durations = self.config['display'].get('display_durations', {}) self.display_durations = self.config['display'].get('display_durations', {})
# Backward-compatibility: map legacy weather keys to current keys if provided in config
try:
if 'weather' in self.display_durations and 'weather_current' not in self.display_durations:
self.display_durations['weather_current'] = self.display_durations['weather']
if 'hourly_forecast' in self.display_durations and 'weather_hourly' not in self.display_durations:
self.display_durations['weather_hourly'] = self.display_durations['hourly_forecast']
if 'daily_forecast' in self.display_durations and 'weather_daily' not in self.display_durations:
self.display_durations['weather_daily'] = self.display_durations['daily_forecast']
except Exception:
pass
# Add defaults for soccer if missing # Add defaults for soccer if missing
default_durations = { default_durations = {
'clock': 15, 'clock': 15,

View File

@@ -108,7 +108,7 @@ class DisplayManager:
self.draw = ImageDraw.Draw(self.image) self.draw = ImageDraw.Draw(self.image)
self.draw.text((10, 10), "Matrix Error", fill=(255, 0, 0)) self.draw.text((10, 10), "Matrix Error", fill=(255, 0, 0))
logger.error(f"Matrix initialization failed, using fallback mode. Error: {e}") logger.error(f"Matrix initialization failed, using fallback mode. Error: {e}")
raise # Do not raise here; allow fallback mode so web preview and non-hardware environments work
@property @property
def width(self): def width(self):
@@ -229,8 +229,8 @@ class DisplayManager:
pixel_x = x + glyph_left + j pixel_x = x + glyph_left + j
pixel_y = y - glyph_top + i pixel_y = y - glyph_top + i
# Only draw if within bounds # Only draw if within bounds
if (0 <= pixel_x < self.matrix.width and if (0 <= pixel_x < self.width and
0 <= pixel_y < self.matrix.height): 0 <= pixel_y < self.height):
self.draw.point((pixel_x, pixel_y), fill=color) self.draw.point((pixel_x, pixel_y), fill=color)
# Move to next character # Move to next character
@@ -353,7 +353,7 @@ class DisplayManager:
# Calculate x position if not provided (center text) # Calculate x position if not provided (center text)
if x is None: if x is None:
text_width = self.get_text_width(text, current_font) text_width = self.get_text_width(text, current_font)
x = (self.matrix.width - text_width) // 2 x = (self.width - text_width) // 2
# Set default y position if not provided # Set default y position if not provided
if y is None: if y is None:
@@ -567,7 +567,18 @@ class DisplayManager:
def cleanup(self): def cleanup(self):
"""Clean up resources.""" """Clean up resources."""
self.matrix.Clear() if hasattr(self, 'matrix') and self.matrix is not None:
try:
self.matrix.Clear()
except Exception as e:
logger.warning(f"Error clearing matrix during cleanup: {e}")
# Ensure image/draw are reset to a blank state
if hasattr(self, 'image') and hasattr(self, 'draw'):
try:
self.image = Image.new('RGB', (self.width, self.height))
self.draw = ImageDraw.Draw(self.image)
except Exception:
pass
# Reset the singleton state when cleaning up # Reset the singleton state when cleaning up
DisplayManager._instance = None DisplayManager._instance = None
DisplayManager._initialized = False DisplayManager._initialized = False

View File

@@ -337,7 +337,11 @@ class BaseNCAABaseballManager:
away_spread = f"+{away_spread}" away_spread = f"+{away_spread}"
# Define colors for odds text # Define colors for odds text
odds_font = self.display_manager.status_font # Use a small readable font for odds; fall back to default if not available
try:
odds_font = ImageFont.truetype("assets/fonts/4x6-font.ttf", 6)
except IOError:
odds_font = ImageFont.load_default()
odds_color = (255, 0, 0) # Red text odds_color = (255, 0, 0) # Red text
outline_color = (0, 0, 0) # Black outline outline_color = (0, 0, 0) # Black outline

View File

@@ -318,7 +318,11 @@ class BaseNHLManager:
# Log game details for debugging # Log game details for debugging
self.logger.debug(f"[NHL] Extracted game details: {details['away_abbr']} vs {details['home_abbr']}") self.logger.debug(f"[NHL] Extracted game details: {details['away_abbr']} vs {details['home_abbr']}")
self.logger.debug(f"[NHL] Game status: is_final={details['is_final']}, is_within_window={details['is_within_window']}") # Use .get() to avoid KeyError if optional keys are missing
self.logger.debug(
f"[NHL] Game status: is_final={details.get('is_final')}, "
f"is_upcoming={details.get('is_upcoming')}, is_live={details.get('is_live')}"
)
# Validate logo files # Validate logo files
for team in ["home", "away"]: for team in ["home", "away"]:

View File

@@ -393,8 +393,10 @@ def system_action():
result = subprocess.run(['sudo', 'reboot'], result = subprocess.run(['sudo', 'reboot'],
capture_output=True, text=True) capture_output=True, text=True)
elif action == 'git_pull': elif action == 'git_pull':
home_dir = str(Path.home())
project_dir = os.path.join(home_dir, 'LEDMatrix')
result = subprocess.run(['git', 'pull'], result = subprocess.run(['git', 'pull'],
capture_output=True, text=True, cwd='/workspace') capture_output=True, text=True, cwd=project_dir, check=False)
else: else:
return jsonify({ return jsonify({
'status': 'error', 'status': 'error',