cursor rules (#87)

This commit is contained in:
Chuck
2025-09-29 21:42:12 -04:00
committed by GitHub
parent 1b52928e1a
commit e584026bda
12 changed files with 545 additions and 1 deletions

View File

@@ -0,0 +1,38 @@
---
globs: *.py
---
# Python Coding Standards
## Code Quality Principles
- **Simplicity First**: Prefer clear, readable code over clever optimizations
- **Explicit over Implicit**: Make intentions clear through naming and structure
- **Fail Fast**: Validate inputs and handle errors early
- **Documentation**: Use docstrings for classes and complex functions
## Naming Conventions
- **Classes**: PascalCase (e.g., `NHLRecentManager`)
- **Functions/Variables**: snake_case (e.g., `fetch_game_data`)
- **Constants**: UPPER_SNAKE_CASE (e.g., `ESPN_NHL_SCOREBOARD_URL`)
- **Private methods**: Leading underscore (e.g., `_fetch_data`)
## Error Handling
- **Logging**: Use structured logging with context (e.g., `[NHL Recent]`)
- **Exceptions**: Catch specific exceptions, not bare `except:`
- **User-friendly messages**: Explain what went wrong and potential solutions
- **Graceful degradation**: Continue operation when non-critical features fail
## Manager Pattern
All sports managers should follow this structure:
```python
class BaseManager:
def __init__(self, config, display_manager, cache_manager)
def update(self) # Fetch and process data
def display(self, force_clear=False) # Render to display
```
## Configuration Management
- **Type hints**: Use for function parameters and return values
- **Configuration validation**: Check required fields on initialization
- **Default values**: Provide sensible defaults in code, not config
- **Environment awareness**: Handle different deployment contexts

View File

@@ -0,0 +1,42 @@
---
globs: config/*.json,src/*.py
---
# Configuration Management
## Configuration Structure
- **Main config**: [config/config.json](mdc:config/config.json) - Primary configuration
- **Secrets**: [config/config_secrets.json](mdc:config/config_secrets.json) - API keys and sensitive data
- **Templates**: [config/config.template.json](mdc:config/config.template.json) - Default values
## Configuration Principles
- **Validation**: Check required fields and data types on startup
- **Defaults**: Provide sensible defaults in code, not just config
- **Environment awareness**: Handle development vs production differences
- **Security**: Never commit secrets to version control
## Manager Configuration Pattern
```python
def __init__(self, config, display_manager, cache_manager):
self.mode_config = config.get("sport_scoreboard", {})
self.favorite_teams = self.mode_config.get("favorite_teams", [])
self.show_favorite_only = self.mode_config.get("show_favorite_teams_only", False)
```
## Required Configuration Sections
- **Display settings**: Update intervals, display durations
- **API settings**: Timeouts, retry logic, rate limiting
- **Background service**: Threading, caching, priority settings
- **Team preferences**: Favorite teams, filtering options
## Configuration Validation
- **Type checking**: Ensure numeric values are numbers, lists are lists
- **Range validation**: Check that intervals are reasonable
- **Dependency checking**: Verify required services are available
- **Fallback values**: Provide defaults when config is missing or invalid
## Best Practices
- **Documentation**: Comment complex configuration options
- **Examples**: Provide working examples in templates
- **Migration**: Handle configuration changes between versions
- **Testing**: Validate configuration in test environments

View File

@@ -0,0 +1,50 @@
---
globs: src/*.py
---
# Error Handling and Logging
## Logging Standards
- **Structured prefixes**: Use consistent tags like `[NHL Recent]`, `[NFL Live]`
- **Context information**: Include relevant details (team names, game status, dates)
- **Appropriate levels**:
- `info`: Normal operations and status updates
- `debug`: Detailed information for troubleshooting
- `warning`: Non-critical issues that should be noted
- `error`: Problems that need attention
## Error Handling Patterns
```python
try:
data = self._fetch_data()
if not data or 'events' not in data:
self.logger.warning("[Manager] No events found in API response")
return
except requests.exceptions.RequestException as e:
self.logger.error(f"[Manager] API error: {e}")
return None
```
## User-Friendly Messages
- **Explain the situation**: "No games available during off-season"
- **Provide context**: "NHL season typically runs October-June"
- **Suggest solutions**: "Check back when season starts"
- **Distinguish issues**: API problems vs no data vs filtering results
## Graceful Degradation
- **Fallback content**: Show alternative games when favorites unavailable
- **Cached data**: Use cached data when API fails
- **Service continuity**: Continue operation when non-critical features fail
- **Clear communication**: Explain what's happening to users
## Debugging Support
- **Comprehensive logging**: Log API responses, filtering results, display updates
- **State tracking**: Log current state and transitions
- **Performance monitoring**: Track timing and resource usage
- **Error context**: Include stack traces for debugging
## Off-Season Awareness
- **Seasonal messaging**: Different messages for different times of year
- **Helpful context**: Explain why no games are available
- **Future planning**: Mention when season starts
- **Realistic expectations**: Set appropriate expectations during off-season

View File

@@ -0,0 +1,51 @@
---
alwaysApply: true
---
# Git Workflow and Branching
## Branch Naming Conventions
- **Features**: `feature/description-of-feature` (e.g., `feature/weather-forecast-improvements`)
- **Bug fixes**: `fix/description-of-bug` (e.g., `fix/nhl-manager-improvements`)
- **Hotfixes**: `hotfix/critical-issue-description`
- **Refactoring**: `refactor/description-of-refactor`
## Commit Message Format
```
type(scope): description
[optional body]
[optional footer]
```
**Types**: feat, fix, docs, style, refactor, test, chore
**Examples**:
- `feat(nhl): Add enhanced logging for data visibility`
- `fix(display): Resolve rendering performance issue`
- `docs(api): Update ESPN API integration guide`
## Pull Request Guidelines
- **Self-review**: Review your own PR before requesting review
- **Testing**: Test thoroughly on Raspberry Pi hardware
- **Documentation**: Update relevant documentation if needed
- **Clean history**: Squash commits if necessary for clean history
## Code Review Checklist
- **Code Quality**: Proper error handling, logging, type hints
- **Architecture**: Follows project patterns, doesn't break existing functionality
- **Performance**: No negative impact on display performance
- **Testing**: Works on Raspberry Pi hardware
- **Documentation**: Comments added for complex logic
## Merge Strategies
- **Squash and Merge**: Preferred for feature branches and bug fixes
- **Merge Commit**: For complex features with multiple logical commits
- **Rebase and Merge**: For simple, single-commit changes
## Best Practices
- **Keep branches small and focused**
- **Commit frequently with meaningful messages**
- **Update branch regularly with main**
- **Test changes incrementally**
- **Delete feature branches after merge**

View File

@@ -0,0 +1,23 @@
---
alwaysApply: true
---
# LEDMatrix Project Structure
## Core Architecture
- **Main entry point**: [run.py](mdc:run.py) - Primary application launcher
- **Configuration**: [config/config.json](mdc:config/config.json) - Main configuration file
- **Display management**: [src/display_controller.py](mdc:src/display_controller.py) - Core display logic
- **Web interface**: [web_interface_v2.py](mdc:web_interface_v2.py) - Modern web UI
## Source Code Organization
- **Managers**: [src/](mdc:src/) - All sports/weather/stock managers
- **Assets**: [assets/](mdc:assets/) - Logos, fonts, and static resources
- **Tests**: [test/](mdc:test/) - Unit and integration tests
- **Documentation**: [LEDMatrix.wiki/](mdc:LEDMatrix.wiki/) - Comprehensive guides
## Key Design Principles
- **Single Responsibility**: Each manager handles one sport/domain
- **Consistent Patterns**: All managers follow similar structure
- **Configuration-Driven**: Behavior controlled via [config/config.json](mdc:config/config.json)
- **Raspberry Pi Focus**: Optimized for Pi hardware, not Windows development

View File

@@ -0,0 +1,41 @@
---
alwaysApply: true
---
# Raspberry Pi Development Guidelines
## Hardware Constraints
- **Pi-only execution**: Code must run on Raspberry Pi, not Windows development machine
- **LED matrix library**: Uses [rpi-rgb-led-matrix-master/](mdc:rpi-rgb-led-matrix-master/) for hardware control
- **Memory limitations**: Optimize for Pi's limited RAM
- **Performance**: Consider Pi's CPU capabilities in design
## Development Workflow
- **Local development**: Write and test code on Windows
- **Pi deployment**: Deploy and test on actual Pi hardware
- **SSH access**: Use SSH for Pi-based testing and debugging
- **Service management**: Use systemd services for production deployment
## Testing Strategy
- **Unit tests**: Test logic without hardware dependencies
- **Integration tests**: Test with mock display managers
- **Hardware tests**: Validate on actual Pi with LED matrix
- **Performance tests**: Monitor memory and CPU usage
## Deployment Considerations
- **Service files**: [ledmatrix.service](mdc:ledmatrix.service), [ledmatrix-web.service](mdc:ledmatrix-web.service)
- **Installation scripts**: [first_time_install.sh](mdc:first_time_install.sh), [install_service.sh](mdc:install_service.sh)
- **Dependencies**: [requirements.txt](mdc:requirements.txt) for Pi environment
- **Permissions**: Handle file permissions for Pi user
## Performance Optimization
- **Caching**: Use [src/cache_manager.py](mdc:src/cache_manager.py) for data persistence
- **Background services**: Non-blocking data fetching
- **Memory management**: Clean up resources regularly
- **Display optimization**: Minimize unnecessary redraws
## Debugging on Pi
- **Logging**: Comprehensive logging for remote debugging
- **Error reporting**: Clear error messages for troubleshooting
- **Status monitoring**: Health checks and status reporting
- **Remote access**: Web interface for configuration and monitoring

View File

@@ -0,0 +1,42 @@
---
globs: src/*_managers.py
---
# Sports Manager Development
## Manager Architecture
All sports managers inherit from base classes and follow consistent patterns:
- **Base classes**: [src/nhl_managers.py](mdc:src/nhl_managers.py), [src/nfl_managers.py](mdc:src/nfl_managers.py)
- **Common functionality**: Data fetching, caching, display rendering
- **Configuration-driven**: Behavior controlled via config sections
## Required Methods
```python
def __init__(self, config, display_manager, cache_manager)
def update(self) # Fetch fresh data
def display(self, force_clear=False) # Render current data
```
## Data Flow Pattern
1. **Fetch**: Get data from API (with caching)
2. **Process**: Extract relevant game information
3. **Filter**: Apply favorite team preferences
4. **Display**: Render to LED matrix
## Logging Standards
- **Structured prefixes**: `[NHL Recent]`, `[NFL Live]`, etc.
- **Context information**: Include team names, game status, dates
- **Debug levels**: Use appropriate log levels (info, debug, warning, error)
- **User-friendly messages**: Explain what's happening and why
## Error Handling
- **API failures**: Log and continue with cached data if available
- **No data scenarios**: Distinguish between API issues vs no games available
- **Off-season awareness**: Provide helpful context during non-active periods
- **Fallback behavior**: Show alternative content when preferred content unavailable
## Configuration Integration
- **Required settings**: Validate on initialization
- **Optional settings**: Provide sensible defaults
- **Background service**: Use for non-blocking data fetching
- **Caching strategy**: Implement intelligent cache management

View File

@@ -0,0 +1,51 @@
---
globs: test/*.py,src/*.py
---
# Testing Standards
## Test Organization
- **Test directory**: [test/](mdc:test/) - All test files
- **Unit tests**: Test individual components in isolation
- **Integration tests**: Test component interactions
- **Hardware tests**: Validate on Raspberry Pi with actual LED matrix
## Testing Principles
- **Test behavior, not implementation**: Focus on what the code does, not how
- **Mock external dependencies**: Use mocks for APIs, display managers, cache
- **Test edge cases**: Empty data, API failures, configuration errors
- **Pi-specific testing**: Validate hardware integration
## Test Structure
```python
def test_manager_initialization():
"""Test that manager initializes with valid config"""
config = {"sport_scoreboard": {"enabled": True}}
manager = ManagerClass(config, mock_display, mock_cache)
assert manager.enabled == True
def test_api_failure_handling():
"""Test graceful handling of API failures"""
# Test that system continues when API fails
# Verify fallback to cached data
# Check appropriate error logging
```
## Mock Patterns
- **Display Manager**: Mock for testing without hardware
- **Cache Manager**: Mock for testing data persistence
- **API responses**: Mock for consistent test data
- **Configuration**: Use test-specific configs
## Test Categories
- **Unit tests**: Individual manager methods
- **Integration tests**: Manager interactions with services
- **Configuration tests**: Validate config loading and validation
- **Error handling tests**: API failures, invalid data, edge cases
## Testing Best Practices
- **Descriptive names**: Test names should explain what they test
- **Single responsibility**: Each test should verify one thing
- **Independent tests**: Tests should not depend on each other
- **Clean setup/teardown**: Reset state between tests
- **Pi compatibility**: Ensure tests work in Pi environment

Submodule LEDMatrix.wiki updated: a01c72e156...fbd8d89a18

76
clear_nhl_cache.py Normal file
View File

@@ -0,0 +1,76 @@
#!/usr/bin/env python3
"""
Script to clear NHL cache so managers will fetch fresh data.
"""
import sys
import os
import json
from datetime import datetime
# Add the src directory to the path
sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'src'))
def clear_nhl_cache():
"""Clear NHL cache to force fresh data fetch."""
print("Clearing NHL cache...")
try:
from cache_manager import CacheManager
# Create cache manager
cache_manager = CacheManager()
# Clear NHL cache for current season
now = datetime.now()
season_year = now.year
if now.month < 9:
season_year = now.year - 1
cache_key = f"nhl_api_data_{season_year}"
print(f"Clearing cache key: {cache_key}")
# Clear the cache
cache_manager.clear_cache(cache_key)
print(f"Successfully cleared cache for {cache_key}")
# Also clear any other NHL-related cache keys
nhl_keys = [
f"nhl_api_data_{season_year}",
f"nhl_api_data_{season_year-1}",
f"nhl_api_data_{season_year+1}",
"nhl_live_games",
"nhl_recent_games",
"nhl_upcoming_games"
]
for key in nhl_keys:
try:
cache_manager.clear_cache(key)
print(f"Cleared cache key: {key}")
except:
pass # Key might not exist
print("NHL cache cleared successfully!")
print("NHL managers will now fetch fresh data from ESPN API.")
except ImportError as e:
print(f"Could not import cache manager: {e}")
print("This script needs to be run on the Raspberry Pi where the cache manager is available.")
except Exception as e:
print(f"Error clearing cache: {e}")
def main():
"""Main function."""
print("=" * 50)
print("NHL Cache Clearer")
print("=" * 50)
clear_nhl_cache()
print("\n" + "=" * 50)
print("Cache clearing complete!")
print("=" * 50)
if __name__ == "__main__":
main()

21
fix_nhl_cache.sh Normal file
View File

@@ -0,0 +1,21 @@
#!/bin/bash
"""
Script to fix NHL cache issues on Raspberry Pi.
This will clear the NHL cache and restart the display service.
"""
echo "=========================================="
echo "Fixing NHL Cache Issues"
echo "=========================================="
# Clear NHL cache
echo "Clearing NHL cache..."
python3 clear_nhl_cache.py
# Restart the display service to force fresh data fetch
echo "Restarting display service..."
sudo systemctl restart ledmatrix.service
echo "NHL cache cleared and service restarted!"
echo "NHL managers should now fetch fresh data from ESPN API."
echo "Check the logs to see if NHL games are now being displayed."

View File

@@ -0,0 +1,109 @@
#!/usr/bin/env python3
"""
Test script to debug NHL manager data fetching issues.
This will help us understand why NHL managers aren't finding games.
"""
import sys
import os
from datetime import datetime, timedelta
import pytz
# Add the src directory to the path so we can import the managers
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', 'src'))
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
def test_nhl_season_logic():
"""Test the NHL season logic."""
print("Testing NHL season logic...")
now = datetime.now(pytz.utc)
print(f"Current date: {now}")
print(f"Current month: {now.month}")
# Test the off-season logic
if now.month in [6, 7, 8]: # Off-season months (June, July, August)
print("Status: Off-season")
elif now.month == 9: # September
print("Status: Pre-season (should have games)")
elif now.month == 10 and now.day < 15: # Early October
print("Status: Early season")
else:
print("Status: Regular season")
# Test season year calculation
season_year = now.year
if now.month < 9:
season_year = now.year - 1
print(f"Season year: {season_year}")
print(f"Cache key would be: nhl_api_data_{season_year}")
def test_espn_api_direct():
"""Test the ESPN API directly to see what data is available."""
print("\nTesting ESPN API directly...")
import requests
url = "https://site.api.espn.com/apis/site/v2/sports/hockey/nhl/scoreboard"
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
}
# Test with current date range
now = datetime.now(pytz.utc)
start_date = (now - timedelta(days=30)).strftime("%Y%m%d")
end_date = (now + timedelta(days=30)).strftime("%Y%m%d")
date_range = f"{start_date}-{end_date}"
params = {
"dates": date_range,
"limit": 1000
}
try:
response = requests.get(url, params=params, headers=headers, timeout=15)
response.raise_for_status()
data = response.json()
events = data.get('events', [])
print(f"Found {len(events)} events in API response")
if events:
print("Sample events:")
for i, event in enumerate(events[:3]):
print(f" {i+1}. {event.get('name', 'Unknown')} on {event.get('date', 'Unknown')}")
# Check status distribution
status_counts = {}
for event in events:
competitions = event.get('competitions', [])
if competitions:
status = competitions[0].get('status', {}).get('type', {})
state = status.get('state', 'unknown')
status_counts[state] = status_counts.get(state, 0) + 1
print(f"\nStatus distribution:")
for status, count in status_counts.items():
print(f" {status}: {count} games")
else:
print("No events found in API response")
except Exception as e:
print(f"Error testing API: {e}")
def main():
"""Run all tests."""
print("=" * 60)
print("NHL Manager Debug Test")
print("=" * 60)
test_nhl_season_logic()
test_espn_api_direct()
print("\n" + "=" * 60)
print("Debug test complete!")
print("=" * 60)
if __name__ == "__main__":
main()