mirror of
https://github.com/ChuckBuilds/LEDMatrix.git
synced 2026-04-10 13:02:59 +00:00
AI bug squash sesh
This commit is contained in:
173
wiki/CACHE_STRATEGY.md
Normal file
173
wiki/CACHE_STRATEGY.md
Normal file
@@ -0,0 +1,173 @@
|
||||
# LEDMatrix Cache Strategy Analysis
|
||||
|
||||
## Current Implementation
|
||||
|
||||
Your LEDMatrix system uses a sophisticated multi-tier caching strategy that balances data freshness with API efficiency.
|
||||
|
||||
### Cache Duration Categories
|
||||
|
||||
#### 1. **Ultra Time-Sensitive Data (15-60 seconds)**
|
||||
- **Live Sports Scores**: Now respects sport-specific `live_update_interval` configuration
|
||||
- Soccer live data: Uses `soccer_scoreboard.live_update_interval` (default: 60 seconds)
|
||||
- NFL live data: Uses `nfl_scoreboard.live_update_interval` (default: 60 seconds)
|
||||
- NHL live data: Uses `nhl_scoreboard.live_update_interval` (default: 60 seconds)
|
||||
- NBA live data: Uses `nba_scoreboard.live_update_interval` (default: 60 seconds)
|
||||
- MLB live data: Uses `mlb.live_update_interval` (default: 60 seconds)
|
||||
- NCAA sports: Use respective `live_update_interval` configurations (default: 60 seconds)
|
||||
- **Current Weather**: 5 minutes (300 seconds)
|
||||
|
||||
#### 2. **Market Data (5-10 minutes)**
|
||||
- **Stocks**: 10 minutes (600 seconds) - market hours aware
|
||||
- **Crypto**: 5 minutes (300 seconds) - 24/7 trading
|
||||
- **Stock News**: 1 hour (3600 seconds)
|
||||
|
||||
#### 3. **Sports Data (5 minutes to 24 hours)**
|
||||
- **Recent Games**: 5 minutes (300 seconds)
|
||||
- **Upcoming Games**: 1 hour (3600 seconds)
|
||||
- **Season Schedules**: 24 hours (86400 seconds)
|
||||
- **Team Information**: 1 week (604800 seconds)
|
||||
|
||||
#### 4. **Static Data (1 week to 30 days)**
|
||||
- **Team Logos**: 30 days (2592000 seconds)
|
||||
- **Configuration Data**: 1 week (604800 seconds)
|
||||
|
||||
### Smart Cache Invalidation
|
||||
|
||||
Beyond time limits, the system uses content-based invalidation:
|
||||
|
||||
```python
|
||||
def has_data_changed(self, data_type: str, new_data: Dict[str, Any]) -> bool:
|
||||
"""Check if data has changed from cached version."""
|
||||
```
|
||||
|
||||
- **Weather**: Compares temperature and conditions
|
||||
- **Stocks**: Compares prices (only during market hours)
|
||||
- **Sports**: Compares scores, game status, inning details
|
||||
- **News**: Compares headlines and article IDs
|
||||
|
||||
### Market-Aware Caching
|
||||
|
||||
For stocks, the system extends cache duration during off-hours:
|
||||
|
||||
```python
|
||||
def _is_market_open(self) -> bool:
|
||||
"""Check if the US stock market is currently open."""
|
||||
# Only invalidates cache during market hours
|
||||
```
|
||||
|
||||
## Enhanced Cache Strategy
|
||||
|
||||
### Sport-Specific Live Update Intervals
|
||||
|
||||
The cache manager now automatically respects the `live_update_interval` configuration for each sport:
|
||||
|
||||
```python
|
||||
def get_sport_live_interval(self, sport_key: str) -> int:
|
||||
"""Get the live_update_interval for a specific sport from config."""
|
||||
config = self.config_manager.get_config()
|
||||
sport_config = config.get(f"{sport_key}_scoreboard", {})
|
||||
return sport_config.get("live_update_interval", 30)
|
||||
```
|
||||
|
||||
### Automatic Sport Detection
|
||||
|
||||
The cache manager automatically detects the sport from cache keys:
|
||||
|
||||
```python
|
||||
def get_sport_key_from_cache_key(self, key: str) -> Optional[str]:
|
||||
"""Extract sport key from cache key to determine appropriate live_update_interval."""
|
||||
# Maps cache key patterns to sport keys
|
||||
sport_patterns = {
|
||||
'nfl': ['nfl', 'football'],
|
||||
'nba': ['nba', 'basketball'],
|
||||
'mlb': ['mlb', 'baseball'],
|
||||
'nhl': ['nhl', 'hockey'],
|
||||
'soccer': ['soccer', 'football'],
|
||||
# ... etc
|
||||
}
|
||||
```
|
||||
|
||||
### Configuration Examples
|
||||
|
||||
**Current Configuration (config/config.json):**
|
||||
```json
|
||||
{
|
||||
"nfl_scoreboard": {
|
||||
"live_update_interval": 30,
|
||||
"enabled": true
|
||||
},
|
||||
"soccer_scoreboard": {
|
||||
"live_update_interval": 30,
|
||||
"enabled": false
|
||||
},
|
||||
"mlb": {
|
||||
"live_update_interval": 30,
|
||||
"enabled": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Cache Behavior:**
|
||||
- NFL live data: 30-second cache (from config)
|
||||
- Soccer live data: 30-second cache (from config)
|
||||
- MLB live data: 30-second cache (from config)
|
||||
|
||||
### Fallback Strategy
|
||||
|
||||
If configuration is unavailable, the system uses sport-specific defaults:
|
||||
|
||||
```python
|
||||
default_intervals = {
|
||||
'soccer': 60, # Soccer default
|
||||
'nfl': 60, # NFL default
|
||||
'nhl': 60, # NHL default
|
||||
'nba': 60, # NBA default
|
||||
'mlb': 60, # MLB default
|
||||
'milb': 60, # Minor league default
|
||||
'ncaa_fb': 60, # College football default
|
||||
'ncaa_baseball': 60, # College baseball default
|
||||
'ncaam_basketball': 60, # College basketball default
|
||||
}
|
||||
```
|
||||
|
||||
## Usage Examples
|
||||
|
||||
### Automatic Sport Detection
|
||||
```python
|
||||
# Cache manager automatically detects NFL and uses nfl_scoreboard.live_update_interval
|
||||
cached_data = cache_manager.get_with_auto_strategy("nfl_live_20241201")
|
||||
|
||||
# Cache manager automatically detects soccer and uses soccer_scoreboard.live_update_interval
|
||||
cached_data = cache_manager.get_with_auto_strategy("soccer_live_20241201")
|
||||
```
|
||||
|
||||
### Manual Sport Specification
|
||||
```python
|
||||
# Explicitly specify sport for custom cache keys
|
||||
cached_data = cache_manager.get_cached_data_with_strategy("custom_live_key", "sports_live")
|
||||
```
|
||||
|
||||
## Benefits
|
||||
|
||||
1. **Configuration-Driven**: Cache respects your sport-specific settings
|
||||
2. **Automatic Detection**: No manual cache duration management needed
|
||||
3. **Sport-Optimized**: Each sport uses its appropriate update interval
|
||||
4. **Backward Compatible**: Existing code continues to work
|
||||
5. **Flexible**: Easy to adjust intervals per sport in config
|
||||
|
||||
## Migration
|
||||
|
||||
The enhanced cache manager is backward compatible. Existing code will automatically benefit from sport-specific intervals without any changes needed.
|
||||
|
||||
To customize intervals for specific sports, simply update the `live_update_interval` in your `config/config.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"nfl_scoreboard": {
|
||||
"live_update_interval": 15 // More aggressive for NFL
|
||||
},
|
||||
"mlb": {
|
||||
"live_update_interval": 45 // Slower pace for MLB
|
||||
}
|
||||
}
|
||||
```
|
||||
245
wiki/CUSTOM_FEEDS_GUIDE.md
Normal file
245
wiki/CUSTOM_FEEDS_GUIDE.md
Normal file
@@ -0,0 +1,245 @@
|
||||
# Adding Custom RSS Feeds & Sports - Complete Guide
|
||||
|
||||
This guide shows you **3 different ways** to add custom RSS feeds like F1, MotoGP, or any personal feeds to your news manager.
|
||||
|
||||
## Quick Examples
|
||||
|
||||
### F1 Racing Feeds
|
||||
```bash
|
||||
# BBC F1 (Recommended - works well)
|
||||
python3 add_custom_feed_example.py add "BBC F1" "http://feeds.bbci.co.uk/sport/formula1/rss.xml"
|
||||
|
||||
# Motorsport.com F1
|
||||
python3 add_custom_feed_example.py add "Motorsport F1" "https://www.motorsport.com/rss/f1/news/"
|
||||
|
||||
# Formula1.com Official
|
||||
python3 add_custom_feed_example.py add "F1 Official" "https://www.formula1.com/en/latest/all.xml"
|
||||
```
|
||||
|
||||
### Other Sports
|
||||
```bash
|
||||
# MotoGP
|
||||
python3 add_custom_feed_example.py add "MotoGP" "https://www.motogp.com/en/rss/news"
|
||||
|
||||
# Tennis
|
||||
python3 add_custom_feed_example.py add "Tennis" "https://www.atptour.com/en/rss/news"
|
||||
|
||||
# Golf
|
||||
python3 add_custom_feed_example.py add "Golf" "https://www.pgatour.com/news.rss"
|
||||
|
||||
# Soccer/Football
|
||||
python3 add_custom_feed_example.py add "ESPN Soccer" "https://www.espn.com/espn/rss/soccer/news"
|
||||
```
|
||||
|
||||
### Personal/Blog Feeds
|
||||
```bash
|
||||
# Personal blog
|
||||
python3 add_custom_feed_example.py add "My Blog" "https://myblog.com/rss.xml"
|
||||
|
||||
# Tech news
|
||||
python3 add_custom_feed_example.py add "TechCrunch" "https://techcrunch.com/feed/"
|
||||
|
||||
# Local news
|
||||
python3 add_custom_feed_example.py add "Local News" "https://localnews.com/rss"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Method 1: Command Line (Easiest)
|
||||
|
||||
### Add a Feed
|
||||
```bash
|
||||
python3 add_custom_feed_example.py add "FEED_NAME" "RSS_URL"
|
||||
```
|
||||
|
||||
### List All Feeds
|
||||
```bash
|
||||
python3 add_custom_feed_example.py list
|
||||
```
|
||||
|
||||
### Remove a Feed
|
||||
```bash
|
||||
python3 add_custom_feed_example.py remove "FEED_NAME"
|
||||
```
|
||||
|
||||
### Example: Adding F1
|
||||
```bash
|
||||
# Step 1: Check current feeds
|
||||
python3 add_custom_feed_example.py list
|
||||
|
||||
# Step 2: Add BBC F1 feed
|
||||
python3 add_custom_feed_example.py add "BBC F1" "http://feeds.bbci.co.uk/sport/formula1/rss.xml"
|
||||
|
||||
# Step 3: Verify it was added
|
||||
python3 add_custom_feed_example.py list
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Method 2: Web Interface
|
||||
|
||||
1. **Open Web Interface**: Go to `http://your-display-ip:5000`
|
||||
2. **Navigate to News Tab**: Click the "News Manager" tab
|
||||
3. **Add Custom Feed**:
|
||||
- Enter feed name in "Feed Name" field (e.g., "BBC F1")
|
||||
- Enter RSS URL in "RSS Feed URL" field
|
||||
- Click "Add Feed" button
|
||||
4. **Enable the Feed**: Check the checkbox next to your new feed
|
||||
5. **Save Settings**: Click "Save News Settings"
|
||||
|
||||
---
|
||||
|
||||
## Method 3: Direct Config Edit
|
||||
|
||||
Edit `config/config.json` directly:
|
||||
|
||||
```json
|
||||
{
|
||||
"news_manager": {
|
||||
"enabled": true,
|
||||
"enabled_feeds": ["NFL", "NCAA FB", "BBC F1"],
|
||||
"custom_feeds": {
|
||||
"BBC F1": "http://feeds.bbci.co.uk/sport/formula1/rss.xml",
|
||||
"Motorsport F1": "https://www.motorsport.com/rss/f1/news/",
|
||||
"My Blog": "https://myblog.com/rss.xml"
|
||||
},
|
||||
"headlines_per_feed": 2
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Finding RSS Feeds
|
||||
|
||||
### Popular Sports RSS Feeds
|
||||
|
||||
| Sport | Source | RSS URL |
|
||||
|-------|--------|---------|
|
||||
| **F1** | BBC Sport | `http://feeds.bbci.co.uk/sport/formula1/rss.xml` |
|
||||
| **F1** | Motorsport.com | `https://www.motorsport.com/rss/f1/news/` |
|
||||
| **MotoGP** | Official | `https://www.motogp.com/en/rss/news` |
|
||||
| **Tennis** | ATP Tour | `https://www.atptour.com/en/rss/news` |
|
||||
| **Golf** | PGA Tour | `https://www.pgatour.com/news.rss` |
|
||||
| **Soccer** | ESPN | `https://www.espn.com/espn/rss/soccer/news` |
|
||||
| **Boxing** | ESPN | `https://www.espn.com/espn/rss/boxing/news` |
|
||||
| **UFC/MMA** | ESPN | `https://www.espn.com/espn/rss/mma/news` |
|
||||
|
||||
### How to Find RSS Feeds
|
||||
1. **Look for RSS icons** on websites
|
||||
2. **Check `/rss`, `/feed`, or `/rss.xml`** paths
|
||||
3. **Use RSS discovery tools** like RSS Feed Finder
|
||||
4. **Check site footers** for RSS links
|
||||
|
||||
### Testing RSS Feeds
|
||||
```bash
|
||||
# Test if a feed works before adding it
|
||||
python3 -c "
|
||||
import feedparser
|
||||
import requests
|
||||
url = 'YOUR_RSS_URL_HERE'
|
||||
try:
|
||||
response = requests.get(url, timeout=10)
|
||||
feed = feedparser.parse(response.content)
|
||||
print(f'SUCCESS: Feed works! Title: {feed.feed.get(\"title\", \"N/A\")}')
|
||||
print(f'{len(feed.entries)} articles found')
|
||||
if feed.entries:
|
||||
print(f'Latest: {feed.entries[0].title}')
|
||||
except Exception as e:
|
||||
print(f'ERROR: {e}')
|
||||
"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Advanced Configuration
|
||||
|
||||
### Controlling Feed Behavior
|
||||
|
||||
```json
|
||||
{
|
||||
"news_manager": {
|
||||
"headlines_per_feed": 3, // Headlines from each feed
|
||||
"scroll_speed": 2, // Pixels per frame
|
||||
"scroll_delay": 0.02, // Seconds between updates
|
||||
"rotation_enabled": true, // Rotate content to avoid repetition
|
||||
"rotation_threshold": 3, // Cycles before rotating
|
||||
"update_interval": 300 // Seconds between feed updates
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Feed Priority
|
||||
Feeds are displayed in the order they appear in `enabled_feeds`:
|
||||
```json
|
||||
"enabled_feeds": ["NFL", "BBC F1", "NCAA FB"] // NFL first, then F1, then NCAA
|
||||
```
|
||||
|
||||
### Custom Display Names
|
||||
You can use any display name for feeds:
|
||||
```bash
|
||||
python3 add_custom_feed_example.py add "Formula 1" "http://feeds.bbci.co.uk/sport/formula1/rss.xml"
|
||||
python3 add_custom_feed_example.py add "Basketball News" "https://www.espn.com/espn/rss/nba/news"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Feed Not Working?
|
||||
1. **Test the RSS URL** using the testing command above
|
||||
2. **Check for HTTPS vs HTTP** - some feeds require secure connections
|
||||
3. **Verify the feed format** - must be valid RSS or Atom
|
||||
4. **Check rate limiting** - some sites block frequent requests
|
||||
|
||||
### Common Issues
|
||||
- **403 Forbidden**: Site blocks automated requests (try different feed)
|
||||
- **SSL Errors**: Use HTTP instead of HTTPS if available
|
||||
- **No Content**: Feed might be empty or incorrectly formatted
|
||||
- **Slow Loading**: Increase timeout in news manager settings
|
||||
|
||||
### Feed Alternatives
|
||||
If one feed doesn't work, try alternatives:
|
||||
- **ESPN feeds** sometimes have access restrictions
|
||||
- **BBC feeds** are generally reliable
|
||||
- **Official sport websites** often have RSS feeds
|
||||
- **News aggregators** like Google News have topic-specific feeds
|
||||
|
||||
---
|
||||
|
||||
## Real-World Example: Complete F1 Setup
|
||||
|
||||
```bash
|
||||
# 1. List current setup
|
||||
python3 add_custom_feed_example.py list
|
||||
|
||||
# 2. Add multiple F1 sources for better coverage
|
||||
python3 add_custom_feed_example.py add "BBC F1" "http://feeds.bbci.co.uk/sport/formula1/rss.xml"
|
||||
python3 add_custom_feed_example.py add "Motorsport F1" "https://www.motorsport.com/rss/f1/news/"
|
||||
|
||||
# 3. Add other racing series
|
||||
python3 add_custom_feed_example.py add "MotoGP" "https://www.motogp.com/en/rss/news"
|
||||
|
||||
# 4. Verify all feeds work
|
||||
python3 simple_news_test.py
|
||||
|
||||
# 5. Check final configuration
|
||||
python3 add_custom_feed_example.py list
|
||||
```
|
||||
|
||||
Result: Your display will now rotate between NFL, NCAA FB, BBC F1, Motorsport F1, and MotoGP headlines!
|
||||
|
||||
---
|
||||
|
||||
## Pro Tips
|
||||
|
||||
1. **Start Small**: Add one feed at a time and test it
|
||||
2. **Mix Sources**: Use multiple sources for the same sport for better coverage
|
||||
3. **Monitor Performance**: Too many feeds can slow down updates
|
||||
4. **Use Descriptive Names**: "BBC F1" is better than just "F1"
|
||||
5. **Test Regularly**: RSS feeds can change or break over time
|
||||
6. **Backup Config**: Save your `config.json` before making changes
|
||||
|
||||
---
|
||||
|
||||
**Need help?** The news manager is designed to be flexible and user-friendly. Start with the command line method - it's the easiest way to get started!
|
||||
177
wiki/DYNAMIC_DURATION_GUIDE.md
Normal file
177
wiki/DYNAMIC_DURATION_GUIDE.md
Normal file
@@ -0,0 +1,177 @@
|
||||
# Dynamic Duration Feature - Complete Guide
|
||||
|
||||
The news manager now includes intelligent **dynamic duration calculation** that automatically determines the exact time needed to display all your selected headlines without cutting off mid-scroll.
|
||||
|
||||
## How It Works
|
||||
|
||||
### Automatic Calculation
|
||||
The system calculates the perfect display duration by:
|
||||
|
||||
1. **Measuring Text Width**: Calculates the exact pixel width of all headlines combined
|
||||
2. **Computing Scroll Distance**: Determines how far text needs to scroll (display width + text width)
|
||||
3. **Calculating Time**: Uses scroll speed and delay to compute exact timing
|
||||
4. **Adding Buffer**: Includes configurable buffer time for smooth transitions
|
||||
5. **Applying Limits**: Ensures duration stays within your min/max preferences
|
||||
|
||||
### Real-World Example
|
||||
With current settings (4 feeds, 2 headlines each):
|
||||
- **Total Headlines**: 8 headlines per cycle
|
||||
- **Estimated Duration**: 57 seconds
|
||||
- **Cycles per Hour**: ~63 cycles
|
||||
- **Result**: Perfect timing, no cut-offs
|
||||
|
||||
## Configuration Options
|
||||
|
||||
### Core Settings
|
||||
```json
|
||||
{
|
||||
"news_manager": {
|
||||
"dynamic_duration": true, // Enable/disable feature
|
||||
"min_duration": 30, // Minimum display time (seconds)
|
||||
"max_duration": 300, // Maximum display time (seconds)
|
||||
"duration_buffer": 0.1, // Buffer time (10% extra)
|
||||
"headlines_per_feed": 2, // Headlines from each feed
|
||||
"scroll_speed": 2, // Pixels per frame
|
||||
"scroll_delay": 0.02 // Seconds per frame
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Duration Scenarios
|
||||
|
||||
| Scenario | Headlines | Est. Duration | Cycles/Hour |
|
||||
|----------|-----------|---------------|-------------|
|
||||
| **Light** | 4 headlines | 30s (min) | 120 |
|
||||
| **Medium** | 6 headlines | 30s (min) | 120 |
|
||||
| **Current** | 8 headlines | 57s | 63 |
|
||||
| **Heavy** | 12 headlines | 85s | 42 |
|
||||
| **Maximum** | 20+ headlines | 300s (max) | 12 |
|
||||
|
||||
## Benefits
|
||||
|
||||
### Perfect Timing
|
||||
- **No Cut-offs**: Headlines never cut off mid-sentence
|
||||
- **Complete Cycles**: Always shows full rotation of all selected content
|
||||
- **Smooth Transitions**: Buffer time prevents jarring switches
|
||||
|
||||
### Intelligent Scaling
|
||||
- **Adapts to Content**: More feeds = longer duration automatically
|
||||
- **User Control**: Set your preferred min/max limits
|
||||
- **Flexible**: Works with any combination of feeds and headlines
|
||||
|
||||
### Predictable Behavior
|
||||
- **Consistent Experience**: Same content always takes same time
|
||||
- **Reliable Cycling**: Know exactly when content will repeat
|
||||
- **Configurable**: Adjust to your viewing preferences
|
||||
|
||||
## Usage Examples
|
||||
|
||||
### Command Line Testing
|
||||
```bash
|
||||
# Test dynamic duration calculations
|
||||
python3 test_dynamic_duration.py
|
||||
|
||||
# Check current status
|
||||
python3 test_dynamic_duration.py status
|
||||
```
|
||||
|
||||
### Configuration Changes
|
||||
```bash
|
||||
# Add more feeds (increases duration)
|
||||
python3 add_custom_feed_example.py add "Tennis" "https://www.atptour.com/en/rss/news"
|
||||
|
||||
# Check new duration
|
||||
python3 test_dynamic_duration.py status
|
||||
```
|
||||
|
||||
### Web Interface
|
||||
1. Go to `http://display-ip:5000`
|
||||
2. Click "News Manager" tab
|
||||
3. Adjust "Duration Settings":
|
||||
- **Min Duration**: Shortest acceptable cycle time
|
||||
- **Max Duration**: Longest acceptable cycle time
|
||||
- **Buffer**: Extra time for smooth transitions
|
||||
|
||||
## Advanced Configuration
|
||||
|
||||
### Fine-Tuning Duration
|
||||
```json
|
||||
{
|
||||
"min_duration": 45, // Increase for longer minimum cycles
|
||||
"max_duration": 180, // Decrease for shorter maximum cycles
|
||||
"duration_buffer": 0.15 // Increase buffer for more transition time
|
||||
}
|
||||
```
|
||||
|
||||
### Scroll Speed Impact
|
||||
```json
|
||||
{
|
||||
"scroll_speed": 3, // Faster scroll = shorter duration
|
||||
"scroll_delay": 0.015 // Less delay = shorter duration
|
||||
}
|
||||
```
|
||||
|
||||
### Content Control
|
||||
```json
|
||||
{
|
||||
"headlines_per_feed": 3, // More headlines = longer duration
|
||||
"enabled_feeds": [ // More feeds = longer duration
|
||||
"NFL", "NBA", "MLB", "NHL", "BBC F1", "Tennis"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Duration Too Short
|
||||
- **Increase** `min_duration`
|
||||
- **Add** more feeds or headlines per feed
|
||||
- **Decrease** `scroll_speed`
|
||||
|
||||
### Duration Too Long
|
||||
- **Decrease** `max_duration`
|
||||
- **Remove** some feeds
|
||||
- **Reduce** `headlines_per_feed`
|
||||
- **Increase** `scroll_speed`
|
||||
|
||||
### Jerky Transitions
|
||||
- **Increase** `duration_buffer`
|
||||
- **Adjust** `scroll_delay`
|
||||
|
||||
## Disable Dynamic Duration
|
||||
|
||||
To use fixed timing instead:
|
||||
```json
|
||||
{
|
||||
"dynamic_duration": false,
|
||||
"fixed_duration": 60 // Fixed 60-second cycles
|
||||
}
|
||||
```
|
||||
|
||||
## Technical Details
|
||||
|
||||
### Calculation Formula
|
||||
```
|
||||
total_scroll_distance = display_width + text_width
|
||||
frames_needed = total_scroll_distance / scroll_speed
|
||||
base_time = frames_needed * scroll_delay
|
||||
buffer_time = base_time * duration_buffer
|
||||
final_duration = base_time + buffer_time (within min/max limits)
|
||||
```
|
||||
|
||||
### Display Integration
|
||||
The display controller automatically:
|
||||
1. Calls `news_manager.get_dynamic_duration()`
|
||||
2. Uses returned value for display timing
|
||||
3. Switches to next mode after exact calculated time
|
||||
4. Logs duration decisions for debugging
|
||||
|
||||
## Best Practices
|
||||
|
||||
1. **Start Conservative**: Use default settings initially
|
||||
2. **Test Changes**: Use test script to preview duration changes
|
||||
3. **Monitor Performance**: Watch for smooth transitions
|
||||
4. **Adjust Gradually**: Make small changes to settings
|
||||
5. **Consider Viewing**: Match duration to your typical viewing patterns
|
||||
|
||||
The dynamic duration feature ensures your news ticker always displays complete, perfectly-timed content cycles regardless of how many feeds or headlines you configure!
|
||||
189
wiki/DYNAMIC_DURATION_STOCKS_IMPLEMENTATION.md
Normal file
189
wiki/DYNAMIC_DURATION_STOCKS_IMPLEMENTATION.md
Normal file
@@ -0,0 +1,189 @@
|
||||
# Dynamic Duration Implementation for Stocks and Stock News
|
||||
|
||||
## Overview
|
||||
|
||||
This document describes the implementation of dynamic duration functionality for the `stock_manager` and `stock_news_manager` classes, following the same pattern as the existing `news_manager`.
|
||||
|
||||
## What Was Implemented
|
||||
|
||||
### 1. Configuration Updates
|
||||
|
||||
Added dynamic duration settings to both `stocks` and `stock_news` sections in `config/config.json`:
|
||||
|
||||
```json
|
||||
"stocks": {
|
||||
"enabled": true,
|
||||
"update_interval": 600,
|
||||
"scroll_speed": 1,
|
||||
"scroll_delay": 0.01,
|
||||
"toggle_chart": true,
|
||||
"dynamic_duration": true,
|
||||
"min_duration": 30,
|
||||
"max_duration": 300,
|
||||
"duration_buffer": 0.1,
|
||||
"symbols": [...],
|
||||
"display_format": "{symbol}: ${price} ({change}%)"
|
||||
},
|
||||
"stock_news": {
|
||||
"enabled": true,
|
||||
"update_interval": 3600,
|
||||
"scroll_speed": 1,
|
||||
"scroll_delay": 0.01,
|
||||
"max_headlines_per_symbol": 1,
|
||||
"headlines_per_rotation": 2,
|
||||
"dynamic_duration": true,
|
||||
"min_duration": 30,
|
||||
"max_duration": 300,
|
||||
"duration_buffer": 0.1
|
||||
}
|
||||
```
|
||||
|
||||
### 2. Stock Manager Updates (`src/stock_manager.py`)
|
||||
|
||||
#### Added Dynamic Duration Properties
|
||||
```python
|
||||
# Dynamic duration settings
|
||||
self.dynamic_duration_enabled = self.stocks_config.get('dynamic_duration', True)
|
||||
self.min_duration = self.stocks_config.get('min_duration', 30)
|
||||
self.max_duration = self.stocks_config.get('max_duration', 300)
|
||||
self.duration_buffer = self.stocks_config.get('duration_buffer', 0.1)
|
||||
self.dynamic_duration = 60 # Default duration in seconds
|
||||
self.total_scroll_width = 0 # Track total width for dynamic duration calculation
|
||||
```
|
||||
|
||||
#### Added `calculate_dynamic_duration()` Method
|
||||
This method calculates the exact time needed to display all stocks based on:
|
||||
- Total scroll width of the content
|
||||
- Display width
|
||||
- Scroll speed and delay settings
|
||||
- Configurable buffer time
|
||||
- Min/max duration limits
|
||||
|
||||
#### Added `get_dynamic_duration()` Method
|
||||
Returns the calculated dynamic duration for use by the display controller.
|
||||
|
||||
#### Updated `display_stocks()` Method
|
||||
The method now calculates and stores the total scroll width and calls `calculate_dynamic_duration()` when creating the scrolling image.
|
||||
|
||||
### 3. Stock News Manager Updates (`src/stock_news_manager.py`)
|
||||
|
||||
#### Added Dynamic Duration Properties
|
||||
```python
|
||||
# Dynamic duration settings
|
||||
self.dynamic_duration_enabled = self.stock_news_config.get('dynamic_duration', True)
|
||||
self.min_duration = self.stock_news_config.get('min_duration', 30)
|
||||
self.max_duration = self.stock_news_config.get('max_duration', 300)
|
||||
self.duration_buffer = self.stock_news_config.get('duration_buffer', 0.1)
|
||||
self.dynamic_duration = 60 # Default duration in seconds
|
||||
self.total_scroll_width = 0 # Track total width for dynamic duration calculation
|
||||
```
|
||||
|
||||
#### Added `calculate_dynamic_duration()` Method
|
||||
Similar to the stock manager, calculates duration based on content width and scroll settings.
|
||||
|
||||
#### Added `get_dynamic_duration()` Method
|
||||
Returns the calculated dynamic duration for use by the display controller.
|
||||
|
||||
#### Updated `display_news()` Method
|
||||
The method now calculates and stores the total scroll width and calls `calculate_dynamic_duration()` when creating the scrolling image.
|
||||
|
||||
### 4. Display Controller Updates (`src/display_controller.py`)
|
||||
|
||||
#### Updated `get_current_duration()` Method
|
||||
Added dynamic duration handling for both `stocks` and `stock_news` modes:
|
||||
|
||||
```python
|
||||
# Handle dynamic duration for stocks
|
||||
if mode_key == 'stocks' and self.stocks:
|
||||
try:
|
||||
dynamic_duration = self.stocks.get_dynamic_duration()
|
||||
# Only log if duration has changed or we haven't logged this duration yet
|
||||
if not hasattr(self, '_last_logged_duration') or self._last_logged_duration != dynamic_duration:
|
||||
logger.info(f"Using dynamic duration for stocks: {dynamic_duration} seconds")
|
||||
self._last_logged_duration = dynamic_duration
|
||||
return dynamic_duration
|
||||
except Exception as e:
|
||||
logger.error(f"Error getting dynamic duration for stocks: {e}")
|
||||
# Fall back to configured duration
|
||||
return self.display_durations.get(mode_key, 60)
|
||||
|
||||
# Handle dynamic duration for stock_news
|
||||
if mode_key == 'stock_news' and self.news:
|
||||
try:
|
||||
dynamic_duration = self.news.get_dynamic_duration()
|
||||
# Only log if duration has changed or we haven't logged this duration yet
|
||||
if not hasattr(self, '_last_logged_duration') or self._last_logged_duration != dynamic_duration:
|
||||
logger.info(f"Using dynamic duration for stock_news: {dynamic_duration} seconds")
|
||||
self._last_logged_duration = dynamic_duration
|
||||
return dynamic_duration
|
||||
except Exception as e:
|
||||
logger.error(f"Error getting dynamic duration for stock_news: {e}")
|
||||
# Fall back to configured duration
|
||||
return self.display_durations.get(mode_key, 60)
|
||||
```
|
||||
|
||||
## How It Works
|
||||
|
||||
### Dynamic Duration Calculation
|
||||
|
||||
The dynamic duration is calculated using the following formula:
|
||||
|
||||
1. **Total Scroll Distance**: `display_width + total_scroll_width`
|
||||
2. **Frames Needed**: `total_scroll_distance / scroll_speed`
|
||||
3. **Base Time**: `frames_needed * scroll_delay`
|
||||
4. **Buffer Time**: `base_time * duration_buffer`
|
||||
5. **Final Duration**: `int(base_time + buffer_time)`
|
||||
|
||||
The final duration is then clamped between `min_duration` and `max_duration`.
|
||||
|
||||
### Integration with Display Controller
|
||||
|
||||
1. When the display controller needs to determine how long to show a particular mode, it calls `get_current_duration()`
|
||||
2. For `stocks` and `stock_news` modes, it calls the respective manager's `get_dynamic_duration()` method
|
||||
3. The manager returns the calculated duration based on the current content width
|
||||
4. The display controller uses this duration to determine how long to display the content
|
||||
|
||||
### Benefits
|
||||
|
||||
1. **Consistent Display Time**: Content is displayed for an appropriate amount of time based on its length
|
||||
2. **Configurable**: Users can adjust min/max durations and buffer percentages
|
||||
3. **Fallback Support**: If dynamic duration fails, it falls back to configured fixed durations
|
||||
4. **Performance**: Duration is calculated once when content is created, not on every frame
|
||||
|
||||
## Configuration Options
|
||||
|
||||
### Dynamic Duration Settings
|
||||
|
||||
- **`dynamic_duration`**: Enable/disable dynamic duration calculation (default: `true`)
|
||||
- **`min_duration`**: Minimum display duration in seconds (default: `30`)
|
||||
- **`max_duration`**: Maximum display duration in seconds (default: `300`)
|
||||
- **`duration_buffer`**: Buffer percentage to add for smooth cycling (default: `0.1` = 10%)
|
||||
|
||||
### Example Configuration
|
||||
|
||||
```json
|
||||
{
|
||||
"dynamic_duration": true,
|
||||
"min_duration": 20,
|
||||
"max_duration": 180,
|
||||
"duration_buffer": 0.15
|
||||
}
|
||||
```
|
||||
|
||||
This would:
|
||||
- Enable dynamic duration
|
||||
- Set minimum display time to 20 seconds
|
||||
- Set maximum display time to 3 minutes
|
||||
- Add 15% buffer time for smooth cycling
|
||||
|
||||
## Testing
|
||||
|
||||
The implementation has been tested to ensure:
|
||||
- Configuration is properly loaded
|
||||
- Dynamic duration calculation works correctly
|
||||
- Display controller integration is functional
|
||||
- Fallback behavior works when dynamic duration is disabled
|
||||
|
||||
## Compatibility
|
||||
|
||||
This implementation follows the exact same pattern as the existing `news_manager` dynamic duration functionality, ensuring consistency across the codebase and making it easy to maintain and extend.
|
||||
178
wiki/MILB_TROUBLESHOOTING.md
Normal file
178
wiki/MILB_TROUBLESHOOTING.md
Normal file
@@ -0,0 +1,178 @@
|
||||
# MiLB Manager Troubleshooting Guide
|
||||
|
||||
## **Issue Summary**
|
||||
The MiLB manager is no longer pulling accurate game information due to several factors, primarily the current offseason period.
|
||||
|
||||
## **Root Causes**
|
||||
|
||||
### 1. **Primary Issue: MiLB Offseason**
|
||||
- **Problem**: MiLB season runs from **April to September**
|
||||
- **Current Status**: We're in January 2025 (offseason)
|
||||
- **Impact**: No regular season games are scheduled during offseason
|
||||
- **Solution**: Enable test mode for offseason testing
|
||||
|
||||
### 2. **Secondary Issues**
|
||||
- **API Endpoint Changes**: MLB Stats API endpoints may have changed
|
||||
- **Sport ID Updates**: Some sport IDs might be outdated
|
||||
- **Team Mapping**: Team abbreviations may have changed
|
||||
|
||||
## **Solutions Implemented**
|
||||
|
||||
### **Immediate Fix: Enable Test Mode**
|
||||
```json
|
||||
{
|
||||
"milb": {
|
||||
"test_mode": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### **Code Improvements**
|
||||
1. **Season Awareness**: Added offseason detection
|
||||
2. **Better Logging**: More informative error messages
|
||||
3. **Test Mode Enhancement**: Improved test data
|
||||
|
||||
## **Diagnostic Tools Created**
|
||||
|
||||
### 1. **Basic API Test**
|
||||
```bash
|
||||
python test/test_milb_api.py
|
||||
```
|
||||
|
||||
### 2. **Comprehensive Diagnostic**
|
||||
```bash
|
||||
python test/diagnose_milb_issues.py
|
||||
```
|
||||
|
||||
## **Testing the Fixes**
|
||||
|
||||
### **Step 1: Run Diagnostic**
|
||||
```bash
|
||||
cd /path/to/LEDMatrix
|
||||
python test/diagnose_milb_issues.py
|
||||
```
|
||||
|
||||
### **Step 2: Test with Test Mode**
|
||||
1. Ensure `test_mode: true` in config
|
||||
2. Restart the display system
|
||||
3. Check if test games appear
|
||||
|
||||
### **Step 3: Verify API (When Season Returns)**
|
||||
```bash
|
||||
python test/test_milb_api.py
|
||||
```
|
||||
|
||||
## **Expected Behavior**
|
||||
|
||||
### **During Offseason (October-March)**
|
||||
- No real games found
|
||||
- Test mode shows sample games
|
||||
- Logs indicate offseason status
|
||||
|
||||
### **During Season (April-September)**
|
||||
- Real games should be found
|
||||
- Live games display correctly
|
||||
- Upcoming games show properly
|
||||
|
||||
## **Configuration Options**
|
||||
|
||||
### **Test Mode**
|
||||
```json
|
||||
{
|
||||
"milb": {
|
||||
"test_mode": true,
|
||||
"enabled": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### **Season Override (For Testing)**
|
||||
```json
|
||||
{
|
||||
"milb": {
|
||||
"test_mode": true,
|
||||
"force_season": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## **Common Issues and Solutions**
|
||||
|
||||
### **Issue: No Games Found**
|
||||
- **Cause**: Offseason or API issues
|
||||
- **Solution**: Enable test mode
|
||||
|
||||
### **Issue: API Errors**
|
||||
- **Cause**: Network or endpoint issues
|
||||
- **Solution**: Check internet connection and API status
|
||||
|
||||
### **Issue: Wrong Team Names**
|
||||
- **Cause**: Team mapping outdated
|
||||
- **Solution**: Update `milb_team_mapping.json`
|
||||
|
||||
### **Issue: Wrong Sport IDs**
|
||||
- **Cause**: MLB API changes
|
||||
- **Solution**: Update sport IDs in config
|
||||
|
||||
## **Monitoring and Logs**
|
||||
|
||||
### **Key Log Messages**
|
||||
- `"MiLB is currently in offseason"` - Normal during offseason
|
||||
- `"Using test mode data for MiLB"` - Test mode active
|
||||
- `"No games returned from API"` - API issue or offseason
|
||||
|
||||
### **Debug Mode**
|
||||
Enable debug logging to see detailed API calls:
|
||||
```python
|
||||
logger.setLevel(logging.DEBUG)
|
||||
```
|
||||
|
||||
## **Future Improvements**
|
||||
|
||||
### **Planned Enhancements**
|
||||
1. **Season Schedule Integration**: Use official season dates
|
||||
2. **API Fallback**: Multiple API endpoints
|
||||
3. **Caching Improvements**: Better cache management
|
||||
4. **Error Recovery**: Automatic retry mechanisms
|
||||
|
||||
### **Configuration Enhancements**
|
||||
```json
|
||||
{
|
||||
"milb": {
|
||||
"season_start_month": 4,
|
||||
"season_end_month": 9,
|
||||
"api_fallback": true,
|
||||
"cache_duration": 3600
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## **Contact and Support**
|
||||
|
||||
For additional issues:
|
||||
1. Run the diagnostic tools
|
||||
2. Check the logs for specific errors
|
||||
3. Verify network connectivity
|
||||
4. Test API endpoints directly
|
||||
|
||||
## **Quick Reference**
|
||||
|
||||
### **Enable Test Mode**
|
||||
```bash
|
||||
# Edit config/config.json
|
||||
# Change "test_mode": false to "test_mode": true
|
||||
```
|
||||
|
||||
### **Run Diagnostics**
|
||||
```bash
|
||||
python test/diagnose_milb_issues.py
|
||||
```
|
||||
|
||||
### **Test API Directly**
|
||||
```bash
|
||||
python test/test_milb_api.py
|
||||
```
|
||||
|
||||
### **Check Season Status**
|
||||
- **April-September**: Season active
|
||||
- **October-March**: Offseason (use test mode)
|
||||
245
wiki/NEWS_MANAGER_README.md
Normal file
245
wiki/NEWS_MANAGER_README.md
Normal file
@@ -0,0 +1,245 @@
|
||||
# Sports News Manager
|
||||
|
||||
A comprehensive RSS feed ticker system for displaying sports news headlines with dynamic scrolling and intelligent rotation.
|
||||
|
||||
## Features
|
||||
|
||||
### 🏈 Multiple Sports Feeds
|
||||
- **NFL**: Latest NFL news and updates
|
||||
- **NCAA Football**: College football news
|
||||
- **MLB**: Major League Baseball news
|
||||
- **NBA**: Basketball news and updates
|
||||
- **NHL**: Hockey news
|
||||
- **NCAA Basketball**: College basketball updates
|
||||
- **Big 10**: Big Ten conference news
|
||||
- **Top Sports**: General ESPN sports news
|
||||
- **Custom Feeds**: Add your own RSS feeds
|
||||
|
||||
### 📺 Smart Display Features
|
||||
- **Dynamic Length Detection**: Automatically calculates headline length and adjusts scroll timing
|
||||
- **Perfect Spacing**: Ensures headlines don't cut off mid-text or loop unnecessarily
|
||||
- **Intelligent Rotation**: Prevents repetitive content by rotating through different headlines
|
||||
- **Configurable Speed**: Adjustable scroll speed and timing
|
||||
- **Visual Separators**: Color-coded separators between different news sources
|
||||
|
||||
### ⚙️ Configuration Options
|
||||
- Enable/disable individual sports feeds
|
||||
- Set number of headlines per feed (1-5)
|
||||
- Adjust scroll speed and timing
|
||||
- Configure rotation behavior
|
||||
- Customize fonts and colors
|
||||
- Add custom RSS feeds
|
||||
|
||||
## Default RSS Feeds
|
||||
|
||||
The system comes pre-configured with these ESPN RSS feeds:
|
||||
|
||||
```
|
||||
MLB: http://espn.com/espn/rss/mlb/news
|
||||
NFL: http://espn.go.com/espn/rss/nfl/news
|
||||
NCAA FB: https://www.espn.com/espn/rss/ncf/news
|
||||
NHL: https://www.espn.com/espn/rss/nhl/news
|
||||
NBA: https://www.espn.com/espn/rss/nba/news
|
||||
TOP SPORTS: https://www.espn.com/espn/rss/news
|
||||
BIG10: https://www.espn.com/blog/feed?blog=bigten
|
||||
NCAA: https://www.espn.com/espn/rss/ncaa/news
|
||||
Other: https://www.coveringthecorner.com/rss/current.xml
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
### Command Line Management
|
||||
|
||||
Use the `enable_news_manager.py` script to manage the news manager:
|
||||
|
||||
```bash
|
||||
# Check current status
|
||||
python3 enable_news_manager.py status
|
||||
|
||||
# Enable news manager
|
||||
python3 enable_news_manager.py enable
|
||||
|
||||
# Disable news manager
|
||||
python3 enable_news_manager.py disable
|
||||
```
|
||||
|
||||
### Web Interface
|
||||
|
||||
Access the news manager through the web interface:
|
||||
|
||||
1. Open your browser to `http://your-display-ip:5000`
|
||||
2. Click on the "News Manager" tab
|
||||
3. Configure your preferred settings:
|
||||
- Enable/disable the news manager
|
||||
- Select which sports feeds to display
|
||||
- Set headlines per feed (1-5)
|
||||
- Configure scroll speed and timing
|
||||
- Add custom RSS feeds
|
||||
- Enable/disable rotation
|
||||
|
||||
### Configuration File
|
||||
|
||||
Direct configuration via `config/config.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"news_manager": {
|
||||
"enabled": true,
|
||||
"update_interval": 300,
|
||||
"scroll_speed": 2,
|
||||
"scroll_delay": 0.02,
|
||||
"headlines_per_feed": 2,
|
||||
"enabled_feeds": ["NFL", "NCAA FB"],
|
||||
"custom_feeds": {
|
||||
"My Team": "https://example.com/rss"
|
||||
},
|
||||
"rotation_enabled": true,
|
||||
"rotation_threshold": 3,
|
||||
"font_size": 12,
|
||||
"font_path": "/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf",
|
||||
"text_color": [255, 255, 255],
|
||||
"separator_color": [255, 0, 0]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## How It Works
|
||||
|
||||
### Dynamic Length Calculation
|
||||
|
||||
The system intelligently calculates the display time for each headline:
|
||||
|
||||
1. **Text Measurement**: Uses PIL to measure the exact pixel width of each headline
|
||||
2. **Scroll Distance**: Calculates total distance needed (text width + display width)
|
||||
3. **Timing Calculation**: Determines exact scroll time based on speed settings
|
||||
4. **Perfect Spacing**: Ensures smooth transitions between headlines
|
||||
|
||||
### Rotation Algorithm
|
||||
|
||||
Prevents repetitive content by:
|
||||
|
||||
1. **Tracking Display Count**: Monitors how many times each headline has been shown
|
||||
2. **Threshold Management**: After a configured number of cycles, rotates to new content
|
||||
3. **Feed Balancing**: Ensures even distribution across selected feeds
|
||||
4. **Freshness**: Prioritizes newer headlines when available
|
||||
|
||||
### Example Calculation
|
||||
|
||||
For a headline "Breaking: Major trade shakes up NFL draft prospects" (51 characters):
|
||||
|
||||
- **Estimated Width**: ~306 pixels (6 pixels per character average)
|
||||
- **Display Width**: 128 pixels
|
||||
- **Total Scroll Distance**: 306 + 128 = 434 pixels
|
||||
- **Scroll Speed**: 2 pixels per frame
|
||||
- **Frame Delay**: 0.02 seconds
|
||||
- **Total Time**: (434 ÷ 2) × 0.02 = 4.34 seconds
|
||||
|
||||
## Testing
|
||||
|
||||
### RSS Feed Test
|
||||
|
||||
Test the RSS feeds directly:
|
||||
|
||||
```bash
|
||||
python3 simple_news_test.py
|
||||
```
|
||||
|
||||
This will:
|
||||
- Test connectivity to ESPN RSS feeds
|
||||
- Parse sample headlines
|
||||
- Calculate scroll timing
|
||||
- Demonstrate rotation logic
|
||||
|
||||
### Integration Test
|
||||
|
||||
Test the full news manager without hardware dependencies:
|
||||
|
||||
```bash
|
||||
python3 test_news_manager.py
|
||||
```
|
||||
|
||||
## API Endpoints
|
||||
|
||||
The system provides REST API endpoints for external control:
|
||||
|
||||
- `GET /news_manager/status` - Get current status and configuration
|
||||
- `POST /news_manager/update` - Update configuration
|
||||
- `POST /news_manager/refresh` - Force refresh of news data
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Common Issues
|
||||
|
||||
1. **RSS Feed Not Loading**
|
||||
- Check internet connectivity
|
||||
- Verify RSS URL is valid
|
||||
- Check for rate limiting
|
||||
|
||||
2. **Slow Performance**
|
||||
- Reduce number of enabled feeds
|
||||
- Increase update interval
|
||||
- Check network latency
|
||||
|
||||
3. **Text Not Displaying**
|
||||
- Verify font path exists
|
||||
- Check text color settings
|
||||
- Ensure display dimensions are correct
|
||||
|
||||
### Debug Mode
|
||||
|
||||
Enable debug logging by setting the log level:
|
||||
|
||||
```python
|
||||
import logging
|
||||
logging.basicConfig(level=logging.DEBUG)
|
||||
```
|
||||
|
||||
## Customization
|
||||
|
||||
### Adding Custom Feeds
|
||||
|
||||
Add your own RSS feeds through the web interface or configuration:
|
||||
|
||||
```json
|
||||
"custom_feeds": {
|
||||
"My Local Team": "https://myteam.com/rss",
|
||||
"Sports Blog": "https://sportsblog.com/feed"
|
||||
}
|
||||
```
|
||||
|
||||
### Styling Options
|
||||
|
||||
Customize the appearance:
|
||||
|
||||
- **Font Size**: Adjust text size (8-24 pixels)
|
||||
- **Colors**: RGB values for text and separators
|
||||
- **Font Path**: Use different system fonts
|
||||
- **Scroll Speed**: 1-10 pixels per frame
|
||||
- **Timing**: 0.01-0.1 seconds per frame
|
||||
|
||||
## Performance
|
||||
|
||||
The news manager is optimized for:
|
||||
|
||||
- **Low Memory Usage**: Efficient caching and cleanup
|
||||
- **Network Efficiency**: Smart update intervals and retry logic
|
||||
- **Smooth Scrolling**: Consistent frame rates
|
||||
- **Fast Loading**: Parallel RSS feed processing
|
||||
|
||||
## Future Enhancements
|
||||
|
||||
Planned features:
|
||||
- Breaking news alerts
|
||||
- Team-specific filtering
|
||||
- Score integration
|
||||
- Social media feeds
|
||||
- Voice announcements
|
||||
- Mobile app control
|
||||
|
||||
## Support
|
||||
|
||||
For issues or questions:
|
||||
1. Check the troubleshooting section
|
||||
2. Review the logs for error messages
|
||||
3. Test individual RSS feeds
|
||||
4. Verify configuration settings
|
||||
Reference in New Issue
Block a user