diff --git a/src/music_manager.py b/src/music_manager.py index e90b4d14..e353e7c7 100644 --- a/src/music_manager.py +++ b/src/music_manager.py @@ -775,7 +775,7 @@ class MusicManager: self.title_scroll_tick = 0 # --- Artist --- - y_pos_artist = y_pos_title + line_height_title + padding_between_lines - 5 + y_pos_artist = y_pos_title + line_height_title + padding_between_lines artist_width = self.display_manager.get_text_width(artist, font_artist_album) current_artist_display_text = artist if artist_width > text_area_width: diff --git a/templates/index.html b/templates/index.html index c2ae23a9..84e891b6 100644 --- a/templates/index.html +++ b/templates/index.html @@ -489,6 +489,71 @@
GPIO slowdown factor (0-5)
+
+ + +
Scan mode for LED matrix (0-1)
+
+
+ + +
PWM bits for brightness control (1-11)
+
+
+ + +
PWM dither bits (0-4)
+
+
+ + +
PWM LSB nanoseconds (50-500)
+
+
+ +
+ +
+
Disable hardware pulsing
+
+
+ +
+ +
+
Inverse color display
+
+
+ +
+ +
+
Show refresh rate on display
+
+
+ + +
Limit refresh rate in Hz (1-1000)
+
+
+ +
+ +
+
Use short date format for display
+
@@ -547,6 +612,170 @@
How long to show word of the day
+
+ + +
How long to show hourly forecast
+
+
+ + +
How long to show daily forecast
+
+
+ + +
How long to show stock news
+
+
+ + +
How long to show odds ticker
+
+ + + +
+
+

Sports Durations

+
+ + +
How long to show NHL live games
+
+
+ + +
How long to show NHL recent games
+
+
+ + +
How long to show NHL upcoming games
+
+
+ + +
How long to show NBA live games
+
+
+ + +
How long to show NBA recent games
+
+
+ + +
How long to show NBA upcoming games
+
+
+ + +
How long to show NFL live games
+
+
+ + +
How long to show NFL recent games
+
+
+ + +
How long to show NFL upcoming games
+
+
+
+

More Sports Durations

+
+ + +
How long to show NCAA FB live games
+
+
+ + +
How long to show NCAA FB recent games
+
+
+ + +
How long to show NCAA FB upcoming games
+
+
+ + +
How long to show NCAA Baseball live games
+
+
+ + +
How long to show NCAA Baseball recent games
+
+
+ + +
How long to show NCAA Baseball upcoming games
+
+
+ + +
How long to show MLB live games
+
+
+ + +
How long to show MLB recent games
+
+
+ + +
How long to show MLB upcoming games
+
+
+ + +
How long to show MiLB live games
+
+
+ + +
How long to show MiLB recent games
+
+
+ + +
How long to show MiLB upcoming games
+
+
+ + +
How long to show Soccer live games
+
+
+ + +
How long to show Soccer recent games
+
+
+ + +
How long to show Soccer upcoming games
+
+
+ + +
How long to show NCAA Basketball live games
+
+
+ + +
How long to show NCAA Basketball recent games
+
+
+ + +
How long to show NCAA Basketball upcoming games
+
@@ -654,6 +883,76 @@
Only display games involving your favorite teams
+ +
+ +
+ +
+
Enable test mode for MLB
+
+ +
+ + +
How often to update MLB data
+
+ +
+ + +
How often to update live MLB games
+
+ +
+ + +
How often to update live odds for MLB
+
+ +
+ + +
How often to update odds for MLB
+
+ +
+ + +
How often to update recent MLB games
+
+ +
+ + +
How often to update upcoming MLB games
+
+ +
+ + +
Number of recent games to display
+
+ +
+ + +
Number of upcoming games to display
+
+ +
+ +
+ +
+
Show team records
+
@@ -1041,6 +1340,70 @@
How long to display each live game
+ +
+ +
+ +
+
Enable test mode for MiLB
+
+ +
+ + +
How often to update MiLB data
+
+ +
+ + +
How often to update live MiLB games
+
+ +
+ + +
How often to update recent MiLB games
+
+ +
+ + +
How often to update upcoming MiLB games
+
+ +
+ + +
Number of recent games to display
+
+ +
+ + +
Number of upcoming games to display
+
+ +
+ +
+ +
+
Show team records
+
+ +
+ + +
Number of days ahead to fetch upcoming games
+
@@ -1161,6 +1524,12 @@
How often to update weather data (300-3600 seconds)
+
+ + +
Weather display format (use {temp}, {condition}, {humidity}, etc.)
+
+ @@ -1202,6 +1571,35 @@
How often to update stock data
+
+ + +
Scroll speed for stock ticker (1-10)
+
+ +
+ + +
Scroll delay for stock ticker (0.01-1.0 seconds)
+
+ +
+ +
+ +
+
Display mini charts alongside stock ticker data
+
+ +
+ + +
Stock display format (use {symbol}, {price}, {change}, etc.)
+
+ @@ -1237,6 +1635,23 @@
How often to update crypto data
+
+ + +
Crypto display format (use {symbol}, {price}, {change}, etc.)
+
+ +
+ +
+ +
+
Display mini charts alongside crypto ticker data
+
+ @@ -1316,6 +1731,30 @@
How often to update stock news
+
+ + +
Scroll speed for stock news (1-10)
+
+ +
+ + +
Scroll delay for stock news (0.01-1.0 seconds)
+
+ +
+ + +
Maximum headlines to show per stock symbol
+
+ +
+ + +
Number of headlines to show per rotation
+
+ @@ -1342,6 +1781,99 @@
How often to update odds
+
+ +
+ +
+
Only show odds for favorite teams
+
+ +
+ + +
Number of games to show per favorite team
+
+ +
+ + +
Maximum games to show per league
+
+ +
+ +
+ +
+
Show only odds without game details
+
+ +
+ + +
How to sort the odds ticker
+
+ +
+ +
+ + +
+
Comma-separated list of enabled leagues
+
+ +
+ + +
Scroll speed for odds ticker (1-10)
+
+ +
+ + +
Scroll delay for odds ticker (0.01-1.0 seconds)
+
+ +
+ +
+ +
+
Loop the odds ticker continuously
+
+ +
+ + +
Number of days ahead to fetch odds for
+
+ +
+ +
+ +
+
Show broadcast channel logos
+
+ @@ -1400,6 +1932,53 @@
Custom text to display on the LED matrix
+
+ + +
Path to the font file for text display
+
+ +
+ + +
Font size for text display (1-20)
+
+ +
+ +
+ +
+
Enable text scrolling
+
+ +
+ + +
Scroll speed for text (1-100)
+
+ +
+ + +
Text color as RGB values (0-255, comma-separated)
+
+ +
+ + +
Background color as RGB values (0-255, comma-separated)
+
+ +
+ + +
Gap width for scrolling text (0-100 pixels)
+
+
@@ -1432,6 +2011,27 @@
How often to update word of the day
+
+ + +
How often to rotate between different 'of the day' items
+
+ +
+ + +
How often to rotate subtitles
+
+ +
+ +
+ + +
+
Order of categories to display
+
+ @@ -1521,6 +2121,18 @@
Comma-separated calendar names
+
+ + +
Path to Google Calendar credentials file
+
+ +
+ + +
Path to Google Calendar token file
+
+ @@ -2187,11 +2799,20 @@ chain_length: parseInt(formData.get('chain_length')), parallel: parseInt(formData.get('parallel')), brightness: parseInt(formData.get('brightness')), - hardware_mapping: formData.get('hardware_mapping') + hardware_mapping: formData.get('hardware_mapping'), + scan_mode: parseInt(formData.get('scan_mode')), + pwm_bits: parseInt(formData.get('pwm_bits')), + pwm_dither_bits: parseInt(formData.get('pwm_dither_bits')), + pwm_lsb_nanoseconds: parseInt(formData.get('pwm_lsb_nanoseconds')), + disable_hardware_pulsing: formData.get('disable_hardware_pulsing') === 'on', + inverse_colors: formData.get('inverse_colors') === 'on', + show_refresh_rate: formData.get('show_refresh_rate') === 'on', + limit_refresh_rate_hz: parseInt(formData.get('limit_refresh_rate_hz')) }, runtime: { gpio_slowdown: parseInt(formData.get('gpio_slowdown')) - } + }, + use_short_date_format: formData.get('use_short_date_format') === 'on' } }; @@ -2227,7 +2848,8 @@ weather: { enabled: formData.get('weather_enabled') === 'on', units: formData.get('weather_units'), - update_interval: parseInt(formData.get('weather_update_interval')) + update_interval: parseInt(formData.get('weather_update_interval')), + display_format: formData.get('weather_display_format') }, location: { city: formData.get('weather_city'), @@ -2268,7 +2890,11 @@ stocks: { enabled: formData.get('stocks_enabled') === 'on', symbols: symbols, - update_interval: parseInt(formData.get('stocks_update_interval')) + update_interval: parseInt(formData.get('stocks_update_interval')), + scroll_speed: parseInt(formData.get('stocks_scroll_speed')), + scroll_delay: parseFloat(formData.get('stocks_scroll_delay')), + toggle_chart: formData.get('stocks_toggle_chart') === 'on', + display_format: formData.get('stocks_display_format') } }; @@ -2305,7 +2931,9 @@ crypto: { enabled: formData.get('crypto_enabled') === 'on', symbols: symbols, - update_interval: parseInt(formData.get('crypto_update_interval')) + update_interval: parseInt(formData.get('crypto_update_interval')), + display_format: formData.get('crypto_display_format'), + toggle_chart: formData.get('crypto_toggle_chart') === 'on' } }; @@ -2380,7 +3008,9 @@ enabled: formData.get('calendar_enabled') === 'on', max_events: parseInt(formData.get('calendar_max_events')), update_interval: parseInt(formData.get('calendar_update_interval')), - calendars: calendars + calendars: calendars, + credentials_file: formData.get('calendar_credentials_file'), + token_file: formData.get('calendar_token_file') } }; @@ -2465,7 +3095,38 @@ calendar: parseInt(formData.get('calendar_duration')), youtube: parseInt(formData.get('youtube_duration')), text_display: parseInt(formData.get('text_display_duration')), - of_the_day: parseInt(formData.get('of_the_day_duration')) + of_the_day: parseInt(formData.get('of_the_day_duration')), + hourly_forecast: parseInt(formData.get('hourly_forecast_duration')), + daily_forecast: parseInt(formData.get('daily_forecast_duration')), + stock_news: parseInt(formData.get('stock_news_duration')), + odds_ticker: parseInt(formData.get('odds_ticker_duration')), + nhl_live: parseInt(formData.get('nhl_live_duration')), + nhl_recent: parseInt(formData.get('nhl_recent_duration')), + nhl_upcoming: parseInt(formData.get('nhl_upcoming_duration')), + nba_live: parseInt(formData.get('nba_live_duration')), + nba_recent: parseInt(formData.get('nba_recent_duration')), + nba_upcoming: parseInt(formData.get('nba_upcoming_duration')), + nfl_live: parseInt(formData.get('nfl_live_duration')), + nfl_recent: parseInt(formData.get('nfl_recent_duration')), + nfl_upcoming: parseInt(formData.get('nfl_upcoming_duration')), + ncaa_fb_live: parseInt(formData.get('ncaa_fb_live_duration')), + ncaa_fb_recent: parseInt(formData.get('ncaa_fb_recent_duration')), + ncaa_fb_upcoming: parseInt(formData.get('ncaa_fb_upcoming_duration')), + ncaa_baseball_live: parseInt(formData.get('ncaa_baseball_live_duration')), + ncaa_baseball_recent: parseInt(formData.get('ncaa_baseball_recent_duration')), + ncaa_baseball_upcoming: parseInt(formData.get('ncaa_baseball_upcoming_duration')), + mlb_live: parseInt(formData.get('mlb_live_duration')), + mlb_recent: parseInt(formData.get('mlb_recent_duration')), + mlb_upcoming: parseInt(formData.get('mlb_upcoming_duration')), + milb_live: parseInt(formData.get('milb_live_duration')), + milb_recent: parseInt(formData.get('milb_recent_duration')), + milb_upcoming: parseInt(formData.get('milb_upcoming_duration')), + soccer_live: parseInt(formData.get('soccer_live_duration')), + soccer_recent: parseInt(formData.get('soccer_recent_duration')), + soccer_upcoming: parseInt(formData.get('soccer_upcoming_duration')), + ncaam_basketball_live: parseInt(formData.get('ncaam_basketball_live_duration')), + ncaam_basketball_recent: parseInt(formData.get('ncaam_basketball_recent_duration')), + ncaam_basketball_upcoming: parseInt(formData.get('ncaam_basketball_upcoming_duration')) } } }; @@ -2574,7 +3235,11 @@ const config = { stock_news: { enabled: formData.get('stock_news_enabled') === 'on', - update_interval: parseInt(formData.get('stock_news_update_interval')) + update_interval: parseInt(formData.get('stock_news_update_interval')), + scroll_speed: parseInt(formData.get('stock_news_scroll_speed')), + scroll_delay: parseFloat(formData.get('stock_news_scroll_delay')), + max_headlines_per_symbol: parseInt(formData.get('stock_news_max_headlines_per_symbol')), + headlines_per_rotation: parseInt(formData.get('stock_news_headlines_per_rotation')) } }; @@ -2609,7 +3274,18 @@ const config = { odds_ticker: { enabled: formData.get('odds_ticker_enabled') === 'on', - update_interval: parseInt(formData.get('odds_ticker_update_interval')) + update_interval: parseInt(formData.get('odds_ticker_update_interval')), + show_favorite_teams_only: formData.get('odds_ticker_show_favorite_teams_only') === 'on', + games_per_favorite_team: parseInt(formData.get('odds_ticker_games_per_favorite_team')), + max_games_per_league: parseInt(formData.get('odds_ticker_max_games_per_league')), + show_odds_only: formData.get('odds_ticker_show_odds_only') === 'on', + sort_order: formData.get('odds_ticker_sort_order'), + enabled_leagues: formData.get('odds_ticker_enabled_leagues').split(',').map(s => s.trim()).filter(s => s), + scroll_speed: parseInt(formData.get('odds_ticker_scroll_speed')), + scroll_delay: parseFloat(formData.get('odds_ticker_scroll_delay')), + loop: formData.get('odds_ticker_loop') === 'on', + future_fetch_days: parseInt(formData.get('odds_ticker_future_fetch_days')), + show_channel_logos: formData.get('odds_ticker_show_channel_logos') === 'on' } }; @@ -2680,7 +3356,14 @@ const config = { text_display: { enabled: formData.get('text_display_enabled') === 'on', - text: formData.get('text_display_text') + text: formData.get('text_display_text'), + font_path: formData.get('text_display_font_path'), + font_size: parseInt(formData.get('text_display_font_size')), + scroll: formData.get('text_display_scroll') === 'on', + scroll_speed: parseInt(formData.get('text_display_scroll_speed')), + text_color: formData.get('text_display_text_color').split(',').map(s => parseInt(s.trim())), + background_color: formData.get('text_display_background_color').split(',').map(s => parseInt(s.trim())), + scroll_gap_width: parseInt(formData.get('text_display_scroll_gap_width')) }, display: { display_durations: { @@ -2720,7 +3403,10 @@ const config = { of_the_day: { enabled: formData.get('of_the_day_enabled') === 'on', - update_interval: parseInt(formData.get('of_the_day_update_interval')) + update_interval: parseInt(formData.get('of_the_day_update_interval')), + display_rotate_interval: parseInt(formData.get('of_the_day_display_rotate_interval')), + subtitle_rotate_interval: parseInt(formData.get('of_the_day_subtitle_rotate_interval')), + category_order: formData.get('of_the_day_category_order').split(',').map(s => s.trim()).filter(s => s) } }; diff --git a/web_interface.py b/web_interface.py index 760282a8..2a51e688 100644 --- a/web_interface.py +++ b/web_interface.py @@ -95,6 +95,7 @@ def save_config_route(): symbols = request.form.get('stocks_symbols', '').split(',') main_config['stocks']['symbols'] = [s.strip() for s in symbols if s.strip()] main_config['stocks']['update_interval'] = int(request.form.get('stocks_update_interval', 600)) + main_config['stocks']['toggle_chart'] = 'stocks_toggle_chart' in request.form # Update crypto settings if 'crypto_enabled' in request.form: @@ -102,6 +103,7 @@ def save_config_route(): symbols = request.form.get('crypto_symbols', '').split(',') main_config['crypto']['symbols'] = [s.strip() for s in symbols if s.strip()] main_config['crypto']['update_interval'] = int(request.form.get('crypto_update_interval', 600)) + main_config['crypto']['toggle_chart'] = 'crypto_toggle_chart' in request.form # Update music settings if 'music_enabled' in request.form: