-
-
Notifications
You must be signed in to change notification settings - Fork 18
WIKI_ARCHITECTURE
The LEDMatrix system is built with a modular, extensible architecture that separates concerns and allows for easy maintenance and extension. This guide explains how all components work together.
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β LEDMatrix System β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β βββββββββββββββ βββββββββββββββ βββββββββββββββ β
β β Display β β Display β β Display β β
β β Controller β β Manager β β Managers β β
β β β β β β β β
β β β’ Main Loop β β β’ Hardware β β β’ Weather β β
β β β’ Rotation β β β’ Rendering β β β’ Stocks β β
β β β’ Schedulingβ β β’ Fonts β β β’ Sports β β
β β β’ Live Mode β β β’ Graphics β β β’ Music β β
β βββββββββββββββ βββββββββββββββ βββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β βββββββββββββββ βββββββββββββββ βββββββββββββββ β
β β Config β β Cache β β Web β β
β β Manager β β Manager β β Interface β β
β β β β β β β β
β β β’ Settings β β β’ Data β β β’ Control β β
β β β’ Validationβ β β’ Persistenceβ β β’ Status β β
β β β’ Loading β β β’ Fallbacks β β β’ Settings β β
β βββββββββββββββ βββββββββββββββ βββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Purpose: Main orchestrator that manages the entire display system.
Responsibilities:
- Initialize all display managers
- Control display rotation and timing
- Handle live game priority
- Manage system scheduling
- Coordinate data updates
- Handle error recovery
Key Methods:
class DisplayController:
def __init__(self):
# Initialize all managers and configuration
def run(self):
# Main display loop
def _update_modules(self):
# Update all enabled modules
def _check_live_games(self):
# Check for live games and prioritize
def _rotate_team_games(self, sport):
# Rotate through team gamesData Flow:
- Load configuration
- Initialize display managers
- Start main loop
- Check for live games
- Rotate through enabled displays
- Handle scheduling and timing
Purpose: Low-level hardware interface and graphics rendering.
Responsibilities:
- Initialize RGB LED matrix hardware
- Handle font loading and management
- Provide drawing primitives
- Manage display buffers
- Handle hardware configuration
- Provide text rendering utilities
Key Features:
class DisplayManager:
def __init__(self, config):
# Initialize hardware and fonts
def draw_text(self, text, x, y, color, font):
# Draw text on display
def update_display(self):
# Update physical display
def clear(self):
# Clear display
def draw_weather_icon(self, condition, x, y, size):
# Draw weather iconsHardware Interface:
- RGB Matrix library integration
- GPIO pin management
- PWM timing control
- Double buffering for smooth updates
- Font rendering (TTF and BDF)
Purpose: Load, validate, and manage system configuration.
Responsibilities:
- Load JSON configuration files
- Validate configuration syntax
- Provide default values
- Handle configuration updates
- Manage secrets and API keys
Configuration Sources:
class ConfigManager:
def load_config(self):
# Load main config.json
def load_secrets(self):
# Load config_secrets.json
def validate_config(self):
# Validate configuration
def get_defaults(self):
# Provide default valuesConfiguration Structure:
- Main settings in
config/config.json - API keys in
config/config_secrets.json - Validation and error handling
- Default value fallbacks
Purpose: Intelligent data caching to reduce API calls and improve performance.
Responsibilities:
- Store API responses
- Manage cache expiration
- Handle cache persistence
- Provide fallback data
- Optimize storage usage
Cache Strategy:
class CacheManager:
def get(self, key):
# Retrieve cached data
def set(self, key, data, ttl):
# Store data with expiration
def is_valid(self, key):
# Check if cache is still valid
def clear_expired(self):
# Remove expired cache entriesCache Locations (in order of preference):
-
~/.ledmatrix_cache/(user's home directory) -
/var/cache/ledmatrix/(system cache directory) -
/tmp/ledmatrix_cache/(temporary directory)
All display managers follow a consistent interface:
class BaseManager:
def __init__(self, config, display_manager):
self.config = config
self.display_manager = display_manager
self.cache_manager = CacheManager()
def update_data(self):
"""Fetch and process new data"""
pass
def display(self, force_clear=False):
"""Render content to display"""
pass
def is_enabled(self):
"""Check if manager is enabled"""
return self.config.get('enabled', False)
def get_duration(self):
"""Get display duration"""
return self.config.get('duration', 30)Each manager follows this pattern:
- Initialization: Load configuration and setup
- Data Fetching: Retrieve data from APIs or local sources
- Caching: Store data using CacheManager
- Processing: Transform raw data into display format
- Rendering: Use DisplayManager to show content
- Cleanup: Return control to main controller
- API Failures: Fall back to cached data
- Network Issues: Use last known good data
- Invalid Data: Filter out bad entries
- Hardware Errors: Graceful degradation
- Configuration Errors: Use safe defaults
Each sport follows a three-manager pattern:
# Live games (currently playing)
class NHLLiveManager(BaseSportsManager):
def fetch_games(self):
# Get currently playing games
def display_games(self):
# Show live scores and status
# Recent games (completed)
class NHLRecentManager(BaseSportsManager):
def fetch_games(self):
# Get recently completed games
def display_games(self):
# Show final scores
# Upcoming games (scheduled)
class NHLUpcomingManager(BaseSportsManager):
def fetch_games(self):
# Get scheduled games
def display_games(self):
# Show game times and matchupsCommon functionality shared by all sports:
class BaseSportsManager:
def __init__(self, config, display_manager):
# Common initialization
def fetch_espn_data(self, sport, endpoint):
# Fetch from ESPN API
def process_game_data(self, games):
# Process raw game data
def display_game(self, game):
# Display individual game
def get_team_logo(self, team_abbr):
# Load team logo
def format_score(self, score):
# Format score displayAll sports use ESPN's API for data:
def fetch_espn_data(self, sport, endpoint):
url = f"http://site.api.espn.com/apis/site/v2/sports/{sport}/{endpoint}"
response = requests.get(url)
return response.json()Supported Sports:
- NHL (hockey)
- NBA (basketball)
- MLB (baseball)
- NFL (football)
- NCAA Football
- NCAA Basketball
- NCAA Baseball
- Soccer (multiple leagues)
- MiLB (minor league baseball)
class StockManager:
def __init__(self, config, display_manager):
# Initialize stock and crypto settings
def fetch_stock_data(self, symbol):
# Fetch from Yahoo Finance
def fetch_crypto_data(self, symbol):
# Fetch crypto data
def display_stocks(self):
# Show stock ticker
def display_crypto(self):
# Show crypto pricesclass StockNewsManager:
def __init__(self, config, display_manager):
# Initialize news settings
def fetch_news(self, symbols):
# Fetch financial news
def display_news(self):
# Show news headlinesclass WeatherManager:
def __init__(self, config, display_manager):
# Initialize weather settings
def fetch_weather(self):
# Fetch from OpenWeatherMap
def display_current_weather(self):
# Show current conditions
def display_hourly_forecast(self):
# Show hourly forecast
def display_daily_forecast(self):
# Show daily forecastclass WeatherIcons:
def __init__(self):
# Load weather icon definitions
def get_icon(self, condition):
# Get icon for weather condition
def draw_icon(self, condition, x, y, size):
# Draw weather iconclass MusicManager:
def __init__(self, display_manager, config):
# Initialize music settings
def start_polling(self):
# Start background polling
def update_music_display(self):
# Update music information
def display_spotify(self):
# Display Spotify info
def display_ytm(self):
# Display YouTube Music infoclass SpotifyClient:
def __init__(self, config):
# Initialize Spotify API
def authenticate(self):
# Handle OAuth authentication
def get_current_track(self):
# Get currently playing trackclass YTMClient:
def __init__(self, config):
# Initialize YTM companion server
def get_current_track(self):
# Get current track from YTMDclass WebInterface:
def __init__(self, config):
# Initialize Flask app
def start_server(self):
# Start web server
def get_status(self):
# Get system status
def control_display(self, action):
# Control display actionsFeatures:
- System status monitoring
- Display control (start/stop)
- Configuration management
- Service management
- Real-time status updates
[Unit]
Description=LEDMatrix Display Service
After=network.target
[Service]
Type=simple
User=root
WorkingDirectory=/home/ledpi/LEDMatrix
ExecStart=/usr/bin/python3 display_controller.py
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.targetService Features:
- Automatic startup
- Crash recovery
- Log management
- Resource monitoring
config.json β ConfigManager β DisplayController β Display Managers
API Sources β CacheManager β Display Managers β Display Manager
Display Managers β Display Manager β RGB Matrix β LED Display
Web Interface β Display Controller β Display Managers
- API Response Caching: Store API responses with TTL
- Processed Data Caching: Cache processed display data
- Font Caching: Cache loaded fonts
- Image Caching: Cache team logos and icons
- Memory Usage: Monitor and optimize memory usage
- CPU Usage: Minimize processing overhead
- Network Usage: Optimize API calls
- Storage Usage: Manage cache storage
- API Failures: Use cached data
- Network Issues: Retry with exponential backoff
- Hardware Errors: Graceful degradation
- Configuration Errors: Use safe defaults
- Create Manager Class: Extend base manager pattern
- Add Configuration: Add to config.json
- Register in Controller: Add to DisplayController
- Add Assets: Include logos, icons, fonts
- Test Integration: Verify with main system
class CustomManager(BaseManager):
def __init__(self, config, display_manager):
super().__init__(config, display_manager)
def update_data(self):
# Fetch custom data
def display(self, force_clear=False):
# Display custom content- Separate Secrets: Store in config_secrets.json
- Environment Variables: Support for env vars
- Access Control: Restrict file permissions
- Key Rotation: Support for key updates
- HTTPS Only: Use secure API endpoints
- Rate Limiting: Respect API limits
- Error Handling: Don't expose sensitive data
- Logging: Secure log management
import logging
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s:%(name)s:%(message)s'
)- API Health: Monitor API availability
- Display Health: Monitor display functionality
- Cache Health: Monitor cache performance
- System Health: Monitor system resources
This architecture provides a solid foundation for the LEDMatrix system while maintaining flexibility for future enhancements and customizations.