7.1 KiB
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:
"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
# 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
# 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:
# 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:
- Total Scroll Distance:
display_width + total_scroll_width - Frames Needed:
total_scroll_distance / scroll_speed - Base Time:
frames_needed * scroll_delay - Buffer Time:
base_time * duration_buffer - Final Duration:
int(base_time + buffer_time)
The final duration is then clamped between min_duration and max_duration.
Integration with Display Controller
- When the display controller needs to determine how long to show a particular mode, it calls
get_current_duration() - For
stocksandstock_newsmodes, it calls the respective manager'sget_dynamic_duration()method - The manager returns the calculated duration based on the current content width
- The display controller uses this duration to determine how long to display the content
Benefits
- Consistent Display Time: Content is displayed for an appropriate amount of time based on its length
- Configurable: Users can adjust min/max durations and buffer percentages
- Fallback Support: If dynamic duration fails, it falls back to configured fixed durations
- 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
{
"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.