mirror of
https://github.com/ChuckBuilds/LEDMatrix.git
synced 2026-04-12 13:42:59 +00:00
add functionality for Live Game Priority
This commit is contained in:
@@ -78,6 +78,7 @@
|
|||||||
"nhl_live": true,
|
"nhl_live": true,
|
||||||
"nhl_recent": true,
|
"nhl_recent": true,
|
||||||
"nhl_upcoming": true
|
"nhl_upcoming": true
|
||||||
}
|
},
|
||||||
|
"live_game_duration": 20
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -102,6 +102,12 @@ class DisplayController:
|
|||||||
if self.nhl_recent: self.nhl_recent.update()
|
if self.nhl_recent: self.nhl_recent.update()
|
||||||
if self.nhl_upcoming: self.nhl_upcoming.update()
|
if self.nhl_upcoming: self.nhl_upcoming.update()
|
||||||
|
|
||||||
|
def _check_live_games(self) -> bool:
|
||||||
|
"""Check if there are any live games available."""
|
||||||
|
if not self.nhl_live:
|
||||||
|
return False
|
||||||
|
return bool(self.nhl_live.live_games)
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
"""Run the display controller, switching between displays."""
|
"""Run the display controller, switching between displays."""
|
||||||
if not self.available_modes:
|
if not self.available_modes:
|
||||||
@@ -116,12 +122,30 @@ class DisplayController:
|
|||||||
# Update data for all modules
|
# Update data for all modules
|
||||||
self._update_modules()
|
self._update_modules()
|
||||||
|
|
||||||
# Check for mode switch
|
# Check for live games
|
||||||
if current_time - self.last_switch > self.get_current_duration():
|
has_live_games = self._check_live_games()
|
||||||
|
|
||||||
|
# If we're in NHL live mode but there are no live games, skip to next mode
|
||||||
|
if self.current_display_mode == 'nhl_live' and not has_live_games:
|
||||||
self.current_mode_index = (self.current_mode_index + 1) % len(self.available_modes)
|
self.current_mode_index = (self.current_mode_index + 1) % len(self.available_modes)
|
||||||
self.current_display_mode = self.available_modes[self.current_mode_index]
|
self.current_display_mode = self.available_modes[self.current_mode_index]
|
||||||
|
logger.info(f"No live games, switching to: {self.current_display_mode}")
|
||||||
|
self.last_switch = current_time
|
||||||
|
self.force_clear = True
|
||||||
|
|
||||||
|
# Check for mode switch
|
||||||
|
elif current_time - self.last_switch > self.get_current_duration():
|
||||||
|
# If there are live games and we're not in NHL live mode, switch to it
|
||||||
|
if has_live_games and self.current_display_mode != 'nhl_live':
|
||||||
|
live_index = self.available_modes.index('nhl_live')
|
||||||
|
self.current_mode_index = live_index
|
||||||
|
self.current_display_mode = 'nhl_live'
|
||||||
|
logger.info("Live games available, switching to NHL live mode")
|
||||||
|
else:
|
||||||
|
self.current_mode_index = (self.current_mode_index + 1) % len(self.available_modes)
|
||||||
|
self.current_display_mode = self.available_modes[self.current_mode_index]
|
||||||
|
logger.info(f"Switching display to: {self.current_display_mode}")
|
||||||
|
|
||||||
logger.info(f"Switching display to: {self.current_display_mode}")
|
|
||||||
self.last_switch = current_time
|
self.last_switch = current_time
|
||||||
self.force_clear = True
|
self.force_clear = True
|
||||||
|
|
||||||
@@ -156,9 +180,12 @@ class DisplayController:
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
self.force_clear = False
|
self.force_clear = False
|
||||||
|
time.sleep(self.update_interval)
|
||||||
|
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
print("\nDisplay stopped by user")
|
logger.info("Display controller stopped by user")
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Error in display controller: {e}", exc_info=True)
|
||||||
finally:
|
finally:
|
||||||
self.display_manager.cleanup()
|
self.display_manager.cleanup()
|
||||||
|
|
||||||
|
|||||||
@@ -340,6 +340,10 @@ class NHLLiveManager(BaseNHLManager):
|
|||||||
self.no_data_interval = 300 # 5 minutes when no live games
|
self.no_data_interval = 300 # 5 minutes when no live games
|
||||||
self.last_update = 0
|
self.last_update = 0
|
||||||
self.logger.info("Initialized NHL Live Manager")
|
self.logger.info("Initialized NHL Live Manager")
|
||||||
|
self.live_games = [] # List to store all live games
|
||||||
|
self.current_game_index = 0 # Index to track which game to show
|
||||||
|
self.last_game_switch = 0 # Track when we last switched games
|
||||||
|
self.game_display_duration = self.nhl_config.get("live_game_duration", 20) # Display each live game for 20 seconds
|
||||||
|
|
||||||
# Initialize with test game only if test mode is enabled
|
# Initialize with test game only if test mode is enabled
|
||||||
if self.test_mode:
|
if self.test_mode:
|
||||||
@@ -355,6 +359,7 @@ class NHLLiveManager(BaseNHLManager):
|
|||||||
"game_time": "7:30 PM",
|
"game_time": "7:30 PM",
|
||||||
"game_date": "Apr 17"
|
"game_date": "Apr 17"
|
||||||
}
|
}
|
||||||
|
self.live_games = [self.current_game]
|
||||||
logging.info("[NHL] Initialized NHLLiveManager with test game: TB vs DAL")
|
logging.info("[NHL] Initialized NHLLiveManager with test game: TB vs DAL")
|
||||||
else:
|
else:
|
||||||
logging.info("[NHL] Initialized NHLLiveManager in live mode")
|
logging.info("[NHL] Initialized NHLLiveManager in live mode")
|
||||||
@@ -363,11 +368,12 @@ class NHLLiveManager(BaseNHLManager):
|
|||||||
"""Update live game data."""
|
"""Update live game data."""
|
||||||
current_time = time.time()
|
current_time = time.time()
|
||||||
# Use longer interval if no game data
|
# Use longer interval if no game data
|
||||||
interval = self.no_data_interval if not self.current_game else self.update_interval
|
interval = self.no_data_interval if not self.live_games else self.update_interval
|
||||||
|
|
||||||
if current_time - self.last_update >= interval:
|
if current_time - self.last_update >= interval:
|
||||||
self.logger.debug("Updating live game data")
|
self.logger.debug("Updating live game data")
|
||||||
self.last_update = current_time
|
self.last_update = current_time
|
||||||
|
|
||||||
if self.test_mode:
|
if self.test_mode:
|
||||||
# For testing, we'll just update the clock to show it's working
|
# For testing, we'll just update the clock to show it's working
|
||||||
if self.current_game:
|
if self.current_game:
|
||||||
@@ -389,7 +395,8 @@ class NHLLiveManager(BaseNHLManager):
|
|||||||
# Fetch live game data from ESPN API
|
# Fetch live game data from ESPN API
|
||||||
data = self._fetch_data()
|
data = self._fetch_data()
|
||||||
if data and "events" in data:
|
if data and "events" in data:
|
||||||
# Find the first live game involving favorite teams
|
# Find all live games involving favorite teams
|
||||||
|
new_live_games = []
|
||||||
for event in data["events"]:
|
for event in data["events"]:
|
||||||
details = self._extract_game_details(event)
|
details = self._extract_game_details(event)
|
||||||
if details and details["is_live"]:
|
if details and details["is_live"]:
|
||||||
@@ -397,13 +404,31 @@ class NHLLiveManager(BaseNHLManager):
|
|||||||
details["home_abbr"] in self.favorite_teams or
|
details["home_abbr"] in self.favorite_teams or
|
||||||
details["away_abbr"] in self.favorite_teams
|
details["away_abbr"] in self.favorite_teams
|
||||||
):
|
):
|
||||||
self.current_game = details
|
new_live_games.append(details)
|
||||||
logging.info(f"[NHL] Found live game: {details['away_abbr']} vs {details['home_abbr']}")
|
logging.info(f"[NHL] Found live game: {details['away_abbr']} vs {details['home_abbr']}")
|
||||||
break
|
|
||||||
|
if new_live_games:
|
||||||
|
# Only update the games list if we have new games
|
||||||
|
if not self.live_games or set(game["away_abbr"] + game["home_abbr"] for game in new_live_games) != set(game["away_abbr"] + game["home_abbr"] for game in self.live_games):
|
||||||
|
self.live_games = new_live_games
|
||||||
|
# If we don't have a current game or it's not in the new list, start from the beginning
|
||||||
|
if not self.current_game or self.current_game not in self.live_games:
|
||||||
|
self.current_game_index = 0
|
||||||
|
self.current_game = self.live_games[0]
|
||||||
|
self.last_game_switch = current_time
|
||||||
|
logging.info(f"[NHL] Starting with live game: {self.current_game['away_abbr']} vs {self.current_game['home_abbr']}")
|
||||||
else:
|
else:
|
||||||
# No live games found
|
# No live games found
|
||||||
|
self.live_games = []
|
||||||
self.current_game = None
|
self.current_game = None
|
||||||
logging.info("[NHL] No live games found")
|
logging.info("[NHL] No live games found")
|
||||||
|
|
||||||
|
# Check if it's time to switch games
|
||||||
|
if len(self.live_games) > 1 and (current_time - self.last_game_switch) >= self.game_display_duration:
|
||||||
|
self.current_game_index = (self.current_game_index + 1) % len(self.live_games)
|
||||||
|
self.current_game = self.live_games[self.current_game_index]
|
||||||
|
self.last_game_switch = current_time
|
||||||
|
logging.info(f"[NHL] Switching to live game: {self.current_game['away_abbr']} vs {self.current_game['home_abbr']}")
|
||||||
|
|
||||||
def display(self, force_clear: bool = False):
|
def display(self, force_clear: bool = False):
|
||||||
"""Display live game information."""
|
"""Display live game information."""
|
||||||
@@ -433,163 +458,56 @@ class NHLRecentManager(BaseNHLManager):
|
|||||||
def update(self):
|
def update(self):
|
||||||
"""Update recent game data."""
|
"""Update recent game data."""
|
||||||
current_time = time.time()
|
current_time = time.time()
|
||||||
|
if current_time - self.last_update >= self.update_interval:
|
||||||
# Check if it's time to switch games
|
|
||||||
if self.current_game and (current_time - self.last_game_switch) >= self.game_display_duration:
|
|
||||||
self.logger.debug("Game display duration reached, preparing to switch games")
|
|
||||||
self.last_game_switch = current_time
|
|
||||||
|
|
||||||
# Use longer interval if no game data
|
|
||||||
interval = self.no_data_interval if not self.games_list else self.update_interval
|
|
||||||
|
|
||||||
if current_time - self.last_update >= interval:
|
|
||||||
self.logger.debug("Updating recent game data")
|
self.logger.debug("Updating recent game data")
|
||||||
self.last_update = current_time
|
self.last_update = current_time
|
||||||
|
|
||||||
# Fetch data for the last few days
|
if self.test_mode:
|
||||||
today = datetime.now(timezone.utc).date()
|
# For testing, we'll just update the score to show it's working
|
||||||
dates_to_fetch = [
|
if self.current_game:
|
||||||
(today - timedelta(days=2)).strftime('%Y%m%d'),
|
self.current_game["home_score"] += 1
|
||||||
(today - timedelta(days=1)).strftime('%Y%m%d'),
|
logging.debug(f"[NHL] Updated test game score: {self.current_game['home_score']}")
|
||||||
today.strftime('%Y%m%d')
|
else:
|
||||||
]
|
# Fetch recent game data from ESPN API
|
||||||
|
data = self._fetch_data()
|
||||||
# Fetch and combine data from all days
|
|
||||||
all_events = []
|
|
||||||
for date_str in dates_to_fetch:
|
|
||||||
data = self._fetch_data(date_str)
|
|
||||||
if data and "events" in data:
|
if data and "events" in data:
|
||||||
all_events.extend(data["events"])
|
# Find all completed games involving favorite teams
|
||||||
|
new_recent_games = []
|
||||||
if all_events:
|
for event in data["events"]:
|
||||||
# Find all recent completed games involving favorite teams
|
details = self._extract_game_details(event)
|
||||||
recent_games = []
|
if details and details["is_final"] and details["is_within_window"]:
|
||||||
cutoff_time = datetime.now(timezone.utc) - timedelta(hours=self.recent_hours)
|
|
||||||
|
|
||||||
# Debug: Print all events to see what we're getting
|
|
||||||
print("\nDEBUG - All events from ESPN:")
|
|
||||||
for event in all_events:
|
|
||||||
try:
|
|
||||||
home_team = next(c for c in event["competitions"][0]["competitors"] if c.get("homeAway") == "home")
|
|
||||||
away_team = next(c for c in event["competitions"][0]["competitors"] if c.get("homeAway") == "away")
|
|
||||||
home_abbr = home_team["team"]["abbreviation"]
|
|
||||||
away_abbr = away_team["team"]["abbreviation"]
|
|
||||||
print(f"Game: {away_abbr} vs {home_abbr}")
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Error parsing event: {e}")
|
|
||||||
|
|
||||||
for event in all_events:
|
|
||||||
details = self._extract_game_details(event)
|
|
||||||
if details and details["is_final"] and details["start_time_utc"]:
|
|
||||||
# Check if game is within our time window
|
|
||||||
if details["start_time_utc"] > cutoff_time:
|
|
||||||
# Check if it involves favorite teams (if any are configured)
|
|
||||||
if not self.favorite_teams or (
|
if not self.favorite_teams or (
|
||||||
details["home_abbr"] in self.favorite_teams or
|
details["home_abbr"] in self.favorite_teams or
|
||||||
details["away_abbr"] in self.favorite_teams
|
details["away_abbr"] in self.favorite_teams
|
||||||
):
|
):
|
||||||
# Verify logo files exist for both teams
|
new_recent_games.append(details)
|
||||||
home_logo_path = os.path.join(self.logo_dir, f"{details['home_abbr']}.png")
|
logging.info(f"[NHL] Found recent game: {details['away_abbr']} vs {details['home_abbr']}")
|
||||||
away_logo_path = os.path.join(self.logo_dir, f"{details['away_abbr']}.png")
|
|
||||||
|
|
||||||
if not os.path.exists(home_logo_path):
|
|
||||||
logging.warning(f"[NHL] Home logo not found: {home_logo_path}")
|
|
||||||
continue
|
|
||||||
if not os.path.exists(away_logo_path):
|
|
||||||
logging.warning(f"[NHL] Away logo not found: {away_logo_path}")
|
|
||||||
continue
|
|
||||||
|
|
||||||
recent_games.append(details)
|
|
||||||
|
|
||||||
# Sort games by start time, most recent first
|
|
||||||
recent_games.sort(key=lambda x: x["start_time_utc"], reverse=True)
|
|
||||||
|
|
||||||
if recent_games:
|
|
||||||
# Group games by team
|
|
||||||
team_games = {}
|
|
||||||
for game in recent_games:
|
|
||||||
for team in self.favorite_teams:
|
|
||||||
if game["home_abbr"] == team or game["away_abbr"] == team:
|
|
||||||
if team not in team_games:
|
|
||||||
team_games[team] = []
|
|
||||||
team_games[team].append(game)
|
|
||||||
|
|
||||||
# Debug: Print all favorite team games we found
|
if new_recent_games:
|
||||||
print("\nDEBUG - Favorite team games found:")
|
# Sort games by start time (most recent first)
|
||||||
for team, games in team_games.items():
|
new_recent_games.sort(key=lambda x: x["start_time"], reverse=True)
|
||||||
print(f"\n{team} games:")
|
|
||||||
for game in games:
|
|
||||||
print(f" {game['away_abbr']} vs {game['home_abbr']}")
|
|
||||||
|
|
||||||
# Find the first team that has games
|
|
||||||
first_team_with_games = None
|
|
||||||
for team in self.favorite_teams:
|
|
||||||
if team in team_games and team_games[team]:
|
|
||||||
first_team_with_games = team
|
|
||||||
break
|
|
||||||
|
|
||||||
if first_team_with_games:
|
|
||||||
# If we don't have a current game or it's not in the new list, start from the beginning
|
|
||||||
if not self.current_game or self.current_game not in recent_games:
|
|
||||||
self.current_team_index = self.favorite_teams.index(first_team_with_games)
|
|
||||||
self.current_game_index = 0
|
|
||||||
self.current_game = team_games[first_team_with_games][0]
|
|
||||||
self.last_game_switch = current_time
|
|
||||||
logging.info(f"[NHL] Starting with {first_team_with_games} game: {self.current_game['away_abbr']} vs {self.current_game['home_abbr']}")
|
|
||||||
else:
|
|
||||||
# Find which team we're currently showing
|
|
||||||
for i, team in enumerate(self.favorite_teams):
|
|
||||||
if team in team_games and self.current_game in team_games[team]:
|
|
||||||
self.current_team_index = i
|
|
||||||
self.current_game_index = team_games[team].index(self.current_game)
|
|
||||||
break
|
|
||||||
|
|
||||||
# Only switch games if we've displayed the current game for the full duration
|
# Only update the games list if we have new games
|
||||||
if (current_time - self.last_game_switch) >= self.game_display_duration:
|
if not self.recent_games or set(game["away_abbr"] + game["home_abbr"] for game in new_recent_games) != set(game["away_abbr"] + game["home_abbr"] for game in self.recent_games):
|
||||||
# Get the current team's games
|
self.recent_games = new_recent_games
|
||||||
current_team = self.favorite_teams[self.current_team_index]
|
# If we don't have a current game or it's not in the new list, start from the beginning
|
||||||
current_team_games = team_games.get(current_team, [])
|
if not self.current_game or self.current_game not in self.recent_games:
|
||||||
|
self.current_game_index = 0
|
||||||
if current_team_games:
|
self.current_game = self.recent_games[0]
|
||||||
# Move to next game for current team
|
|
||||||
self.current_game_index = (self.current_game_index + 1) % len(current_team_games)
|
|
||||||
self.current_game = current_team_games[self.current_game_index]
|
|
||||||
self.last_game_switch = current_time
|
self.last_game_switch = current_time
|
||||||
|
logging.info(f"[NHL] Starting with recent game: {self.current_game['away_abbr']} vs {self.current_game['home_abbr']}")
|
||||||
# If we've shown all games for this team, move to next team
|
|
||||||
if self.current_game_index == 0:
|
|
||||||
# Find the next team that has games
|
|
||||||
next_team = None
|
|
||||||
for i in range(len(self.favorite_teams)):
|
|
||||||
next_team_index = (self.current_team_index + i + 1) % len(self.favorite_teams)
|
|
||||||
next_team = self.favorite_teams[next_team_index]
|
|
||||||
if next_team in team_games and team_games[next_team]:
|
|
||||||
self.current_team_index = next_team_index
|
|
||||||
self.current_game = team_games[next_team][0]
|
|
||||||
self.last_game_switch = current_time
|
|
||||||
logging.info(f"[NHL] Switching to {next_team} game: {self.current_game['away_abbr']} vs {self.current_game['home_abbr']}")
|
|
||||||
break
|
|
||||||
|
|
||||||
# If no next team has games, go back to the first team with games
|
|
||||||
if not next_team or next_team not in team_games or not team_games[next_team]:
|
|
||||||
self.current_team_index = self.favorite_teams.index(first_team_with_games)
|
|
||||||
self.current_game = team_games[first_team_with_games][0]
|
|
||||||
self.last_game_switch = current_time
|
|
||||||
logging.info(f"[NHL] No more games, returning to {first_team_with_games} game: {self.current_game['away_abbr']} vs {self.current_game['home_abbr']}")
|
|
||||||
|
|
||||||
if self.current_game:
|
|
||||||
logging.info(f"[NHL] Displaying recent game: {self.current_game['away_abbr']} vs {self.current_game['home_abbr']}")
|
|
||||||
else:
|
|
||||||
logging.info("[NHL] No current game to display")
|
|
||||||
else:
|
else:
|
||||||
logging.info("[NHL] No recent games found for favorite teams")
|
# No recent games found
|
||||||
|
self.recent_games = []
|
||||||
self.current_game = None
|
self.current_game = None
|
||||||
else:
|
logging.info("[NHL] No recent games found")
|
||||||
logging.info("[NHL] No recent games found")
|
|
||||||
self.current_game = None
|
# Check if it's time to switch games
|
||||||
else:
|
if len(self.recent_games) > 1 and (current_time - self.last_game_switch) >= self.game_display_duration:
|
||||||
logging.info("[NHL] No events found in the last few days")
|
self.current_game_index = (self.current_game_index + 1) % len(self.recent_games)
|
||||||
self.current_game = None
|
self.current_game = self.recent_games[self.current_game_index]
|
||||||
|
self.last_game_switch = current_time
|
||||||
|
logging.info(f"[NHL] Switching to recent game: {self.current_game['away_abbr']} vs {self.current_game['home_abbr']}")
|
||||||
|
|
||||||
def display(self, force_clear: bool = False):
|
def display(self, force_clear: bool = False):
|
||||||
"""Display recent game information."""
|
"""Display recent game information."""
|
||||||
|
|||||||
Reference in New Issue
Block a user