mirror of
https://github.com/ChuckBuilds/LEDMatrix.git
synced 2026-04-10 13:02:59 +00:00
add functionality for Live Game Priority
This commit is contained in:
@@ -78,6 +78,7 @@
|
||||
"nhl_live": true,
|
||||
"nhl_recent": 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_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):
|
||||
"""Run the display controller, switching between displays."""
|
||||
if not self.available_modes:
|
||||
@@ -116,12 +122,30 @@ class DisplayController:
|
||||
# Update data for all modules
|
||||
self._update_modules()
|
||||
|
||||
# Check for mode switch
|
||||
if current_time - self.last_switch > self.get_current_duration():
|
||||
# Check for live games
|
||||
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_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.force_clear = True
|
||||
|
||||
@@ -156,9 +180,12 @@ class DisplayController:
|
||||
continue
|
||||
|
||||
self.force_clear = False
|
||||
time.sleep(self.update_interval)
|
||||
|
||||
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:
|
||||
self.display_manager.cleanup()
|
||||
|
||||
|
||||
@@ -340,6 +340,10 @@ class NHLLiveManager(BaseNHLManager):
|
||||
self.no_data_interval = 300 # 5 minutes when no live games
|
||||
self.last_update = 0
|
||||
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
|
||||
if self.test_mode:
|
||||
@@ -355,6 +359,7 @@ class NHLLiveManager(BaseNHLManager):
|
||||
"game_time": "7:30 PM",
|
||||
"game_date": "Apr 17"
|
||||
}
|
||||
self.live_games = [self.current_game]
|
||||
logging.info("[NHL] Initialized NHLLiveManager with test game: TB vs DAL")
|
||||
else:
|
||||
logging.info("[NHL] Initialized NHLLiveManager in live mode")
|
||||
@@ -363,11 +368,12 @@ class NHLLiveManager(BaseNHLManager):
|
||||
"""Update live game data."""
|
||||
current_time = time.time()
|
||||
# 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:
|
||||
self.logger.debug("Updating live game data")
|
||||
self.last_update = current_time
|
||||
|
||||
if self.test_mode:
|
||||
# For testing, we'll just update the clock to show it's working
|
||||
if self.current_game:
|
||||
@@ -389,7 +395,8 @@ class NHLLiveManager(BaseNHLManager):
|
||||
# Fetch live game data from ESPN API
|
||||
data = self._fetch_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"]:
|
||||
details = self._extract_game_details(event)
|
||||
if details and details["is_live"]:
|
||||
@@ -397,13 +404,31 @@ class NHLLiveManager(BaseNHLManager):
|
||||
details["home_abbr"] in self.favorite_teams or
|
||||
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']}")
|
||||
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:
|
||||
# No live games found
|
||||
self.live_games = []
|
||||
self.current_game = None
|
||||
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):
|
||||
"""Display live game information."""
|
||||
@@ -433,163 +458,56 @@ class NHLRecentManager(BaseNHLManager):
|
||||
def update(self):
|
||||
"""Update recent game data."""
|
||||
current_time = time.time()
|
||||
|
||||
# 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:
|
||||
if current_time - self.last_update >= self.update_interval:
|
||||
self.logger.debug("Updating recent game data")
|
||||
self.last_update = current_time
|
||||
|
||||
# Fetch data for the last few days
|
||||
today = datetime.now(timezone.utc).date()
|
||||
dates_to_fetch = [
|
||||
(today - timedelta(days=2)).strftime('%Y%m%d'),
|
||||
(today - timedelta(days=1)).strftime('%Y%m%d'),
|
||||
today.strftime('%Y%m%d')
|
||||
]
|
||||
|
||||
# Fetch and combine data from all days
|
||||
all_events = []
|
||||
for date_str in dates_to_fetch:
|
||||
data = self._fetch_data(date_str)
|
||||
if self.test_mode:
|
||||
# For testing, we'll just update the score to show it's working
|
||||
if self.current_game:
|
||||
self.current_game["home_score"] += 1
|
||||
logging.debug(f"[NHL] Updated test game score: {self.current_game['home_score']}")
|
||||
else:
|
||||
# Fetch recent game data from ESPN API
|
||||
data = self._fetch_data()
|
||||
if data and "events" in data:
|
||||
all_events.extend(data["events"])
|
||||
|
||||
if all_events:
|
||||
# Find all recent completed games involving favorite teams
|
||||
recent_games = []
|
||||
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)
|
||||
# Find all completed games involving favorite teams
|
||||
new_recent_games = []
|
||||
for event in data["events"]:
|
||||
details = self._extract_game_details(event)
|
||||
if details and details["is_final"] and details["is_within_window"]:
|
||||
if not self.favorite_teams or (
|
||||
details["home_abbr"] in self.favorite_teams or
|
||||
details["away_abbr"] in self.favorite_teams
|
||||
):
|
||||
# Verify logo files exist for both teams
|
||||
home_logo_path = os.path.join(self.logo_dir, f"{details['home_abbr']}.png")
|
||||
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)
|
||||
new_recent_games.append(details)
|
||||
logging.info(f"[NHL] Found recent game: {details['away_abbr']} vs {details['home_abbr']}")
|
||||
|
||||
# Debug: Print all favorite team games we found
|
||||
print("\nDEBUG - Favorite team games found:")
|
||||
for team, games in team_games.items():
|
||||
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
|
||||
if new_recent_games:
|
||||
# Sort games by start time (most recent first)
|
||||
new_recent_games.sort(key=lambda x: x["start_time"], reverse=True)
|
||||
|
||||
# Only switch games if we've displayed the current game for the full duration
|
||||
if (current_time - self.last_game_switch) >= self.game_display_duration:
|
||||
# Get the current team's games
|
||||
current_team = self.favorite_teams[self.current_team_index]
|
||||
current_team_games = team_games.get(current_team, [])
|
||||
|
||||
if current_team_games:
|
||||
# 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]
|
||||
# Only update the games list if we have new games
|
||||
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):
|
||||
self.recent_games = new_recent_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.recent_games:
|
||||
self.current_game_index = 0
|
||||
self.current_game = self.recent_games[0]
|
||||
self.last_game_switch = current_time
|
||||
|
||||
# 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")
|
||||
logging.info(f"[NHL] Starting with recent game: {self.current_game['away_abbr']} vs {self.current_game['home_abbr']}")
|
||||
else:
|
||||
logging.info("[NHL] No recent games found for favorite teams")
|
||||
# No recent games found
|
||||
self.recent_games = []
|
||||
self.current_game = None
|
||||
else:
|
||||
logging.info("[NHL] No recent games found")
|
||||
self.current_game = None
|
||||
else:
|
||||
logging.info("[NHL] No events found in the last few days")
|
||||
self.current_game = None
|
||||
logging.info("[NHL] No recent games found")
|
||||
|
||||
# Check if it's time to switch games
|
||||
if len(self.recent_games) > 1 and (current_time - self.last_game_switch) >= self.game_display_duration:
|
||||
self.current_game_index = (self.current_game_index + 1) % len(self.recent_games)
|
||||
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):
|
||||
"""Display recent game information."""
|
||||
|
||||
Reference in New Issue
Block a user