-
-
Notifications
You must be signed in to change notification settings - Fork 22
DYNAMIC_DURATION_STOCKS_IMPLEMENTATION
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.
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
}# 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 calculationThis 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
Returns the calculated dynamic duration for use by the display controller.
The method now calculates and stores the total scroll width and calls calculate_dynamic_duration() when creating the scrolling image.
# 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 calculationSimilar to the stock manager, calculates duration based on content width and scroll settings.
Returns the calculated dynamic duration for use by the display controller.
The method now calculates and stores the total scroll width and calls calculate_dynamic_duration() when creating the scrolling image.
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)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.
- 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
- 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
-
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%)
{
"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
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
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.