mirror of
https://github.com/ChuckBuilds/LEDMatrix.git
synced 2026-04-12 13:42:59 +00:00
milb upcoming game debug logging
This commit is contained in:
@@ -151,10 +151,12 @@ class DisplayController:
|
|||||||
self.milb_live = MiLBLiveManager(self.config, self.display_manager, self.cache_manager) if milb_display_modes.get('milb_live', True) else None
|
self.milb_live = MiLBLiveManager(self.config, self.display_manager, self.cache_manager) if milb_display_modes.get('milb_live', True) else None
|
||||||
self.milb_recent = MiLBRecentManager(self.config, self.display_manager, self.cache_manager) if milb_display_modes.get('milb_recent', True) else None
|
self.milb_recent = MiLBRecentManager(self.config, self.display_manager, self.cache_manager) if milb_display_modes.get('milb_recent', True) else None
|
||||||
self.milb_upcoming = MiLBUpcomingManager(self.config, self.display_manager, self.cache_manager) if milb_display_modes.get('milb_upcoming', True) else None
|
self.milb_upcoming = MiLBUpcomingManager(self.config, self.display_manager, self.cache_manager) if milb_display_modes.get('milb_upcoming', True) else None
|
||||||
|
logger.info(f"MiLB managers initialized - live: {self.milb_live is not None}, recent: {self.milb_recent is not None}, upcoming: {self.milb_upcoming is not None}")
|
||||||
else:
|
else:
|
||||||
self.milb_live = None
|
self.milb_live = None
|
||||||
self.milb_recent = None
|
self.milb_recent = None
|
||||||
self.milb_upcoming = None
|
self.milb_upcoming = None
|
||||||
|
logger.info("MiLB managers disabled")
|
||||||
logger.info("MiLB managers initialized in %.3f seconds", time.time() - milb_time)
|
logger.info("MiLB managers initialized in %.3f seconds", time.time() - milb_time)
|
||||||
|
|
||||||
# Initialize Soccer managers if enabled
|
# Initialize Soccer managers if enabled
|
||||||
@@ -1137,6 +1139,7 @@ class DisplayController:
|
|||||||
manager_to_display = self.milb_recent
|
manager_to_display = self.milb_recent
|
||||||
elif self.current_display_mode == 'milb_upcoming' and self.milb_upcoming:
|
elif self.current_display_mode == 'milb_upcoming' and self.milb_upcoming:
|
||||||
manager_to_display = self.milb_upcoming
|
manager_to_display = self.milb_upcoming
|
||||||
|
logger.info("Set manager_to_display to milb_upcoming")
|
||||||
elif self.current_display_mode == 'soccer_recent' and self.soccer_recent:
|
elif self.current_display_mode == 'soccer_recent' and self.soccer_recent:
|
||||||
manager_to_display = self.soccer_recent
|
manager_to_display = self.soccer_recent
|
||||||
elif self.current_display_mode == 'soccer_upcoming' and self.soccer_upcoming:
|
elif self.current_display_mode == 'soccer_upcoming' and self.soccer_upcoming:
|
||||||
@@ -1169,6 +1172,8 @@ class DisplayController:
|
|||||||
logger.info(f"Showing {self.current_display_mode}")
|
logger.info(f"Showing {self.current_display_mode}")
|
||||||
self._last_logged_mode = self.current_display_mode
|
self._last_logged_mode = self.current_display_mode
|
||||||
|
|
||||||
|
logger.info(f"manager_to_display is {type(manager_to_display).__name__ if manager_to_display else 'None'}")
|
||||||
|
|
||||||
if self.current_display_mode == 'music' and self.music_manager:
|
if self.current_display_mode == 'music' and self.music_manager:
|
||||||
# Call MusicManager's display method
|
# Call MusicManager's display method
|
||||||
self.music_manager.display(force_clear=self.force_clear)
|
self.music_manager.display(force_clear=self.force_clear)
|
||||||
@@ -1230,6 +1235,7 @@ class DisplayController:
|
|||||||
# Special handling for live managers that need update before display
|
# Special handling for live managers that need update before display
|
||||||
if self.current_display_mode.endswith('_live') and hasattr(manager_to_display, 'update'):
|
if self.current_display_mode.endswith('_live') and hasattr(manager_to_display, 'update'):
|
||||||
manager_to_display.update()
|
manager_to_display.update()
|
||||||
|
logger.info(f"Calling display method for {self.current_display_mode}")
|
||||||
manager_to_display.display(force_clear=self.force_clear)
|
manager_to_display.display(force_clear=self.force_clear)
|
||||||
else:
|
else:
|
||||||
logger.warning(f"Manager {type(manager_to_display).__name__} for mode {self.current_display_mode} does not have a standard 'display' method.")
|
logger.warning(f"Manager {type(manager_to_display).__name__} for mode {self.current_display_mode} does not have a standard 'display' method.")
|
||||||
|
|||||||
@@ -641,6 +641,11 @@ class DisplayManager:
|
|||||||
except Exception:
|
except Exception:
|
||||||
# Fallback to direct save if replace not supported
|
# Fallback to direct save if replace not supported
|
||||||
self.image.save(self._snapshot_path, format='PNG')
|
self.image.save(self._snapshot_path, format='PNG')
|
||||||
|
# Try to make the snapshot world-readable so the web UI can read it regardless of user
|
||||||
|
try:
|
||||||
|
os.chmod(self._snapshot_path, 0o644)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
self._last_snapshot_ts = now
|
self._last_snapshot_ts = now
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
# Snapshot failures should never break display; log at debug to avoid noise
|
# Snapshot failures should never break display; log at debug to avoid noise
|
||||||
|
|||||||
@@ -211,6 +211,7 @@ class BaseMiLBManager:
|
|||||||
|
|
||||||
def _create_game_display(self, game_data: Dict[str, Any]) -> Image.Image:
|
def _create_game_display(self, game_data: Dict[str, Any]) -> Image.Image:
|
||||||
"""Create a display image for an MiLB game with team logos, score, and game state."""
|
"""Create a display image for an MiLB game with team logos, score, and game state."""
|
||||||
|
self.logger.info(f"[MiLB] Creating game display for: {game_data.get('away_team')} @ {game_data.get('home_team')}")
|
||||||
width = self.display_manager.matrix.width
|
width = self.display_manager.matrix.width
|
||||||
height = self.display_manager.matrix.height
|
height = self.display_manager.matrix.height
|
||||||
image = Image.new('RGB', (width, height), color=(0, 0, 0))
|
image = Image.new('RGB', (width, height), color=(0, 0, 0))
|
||||||
@@ -417,6 +418,7 @@ class BaseMiLBManager:
|
|||||||
|
|
||||||
def _fetch_milb_api_data(self, use_cache: bool = True) -> Dict[str, Any]:
|
def _fetch_milb_api_data(self, use_cache: bool = True) -> Dict[str, Any]:
|
||||||
"""Fetch MiLB game data from the MLB Stats API."""
|
"""Fetch MiLB game data from the MLB Stats API."""
|
||||||
|
self.logger.info("[MiLB] _fetch_milb_api_data called")
|
||||||
cache_key = "milb_live_api_data"
|
cache_key = "milb_live_api_data"
|
||||||
if use_cache:
|
if use_cache:
|
||||||
cached_data = self.cache_manager.get_with_auto_strategy(cache_key)
|
cached_data = self.cache_manager.get_with_auto_strategy(cache_key)
|
||||||
@@ -616,6 +618,7 @@ class BaseMiLBManager:
|
|||||||
self.cache_manager.set(cache_key, all_games)
|
self.cache_manager.set(cache_key, all_games)
|
||||||
else:
|
else:
|
||||||
self.logger.error(f"[MiLB] Cannot cache invalid data type: {type(all_games)}")
|
self.logger.error(f"[MiLB] Cannot cache invalid data type: {type(all_games)}")
|
||||||
|
self.logger.info(f"[MiLB] Returning {len(all_games)} games from API")
|
||||||
return all_games
|
return all_games
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -1531,6 +1534,7 @@ class MiLBUpcomingManager(BaseMiLBManager):
|
|||||||
|
|
||||||
def update(self):
|
def update(self):
|
||||||
"""Update upcoming games data."""
|
"""Update upcoming games data."""
|
||||||
|
self.logger.info("[MiLB] Update method called")
|
||||||
current_time = time.time()
|
current_time = time.time()
|
||||||
|
|
||||||
# Add a check to see if the manager is enabled
|
# Add a check to see if the manager is enabled
|
||||||
@@ -1602,6 +1606,7 @@ class MiLBUpcomingManager(BaseMiLBManager):
|
|||||||
new_upcoming_games = []
|
new_upcoming_games = []
|
||||||
|
|
||||||
self.logger.info(f"[MiLB] Processing {len(games)} games for upcoming games...")
|
self.logger.info(f"[MiLB] Processing {len(games)} games for upcoming games...")
|
||||||
|
self.logger.info(f"[MiLB] Games keys: {list(games.keys()) if games else 'None'}")
|
||||||
|
|
||||||
now_utc = datetime.now(timezone.utc)
|
now_utc = datetime.now(timezone.utc)
|
||||||
for game_id, game in games.items():
|
for game_id, game in games.items():
|
||||||
@@ -1646,6 +1651,7 @@ class MiLBUpcomingManager(BaseMiLBManager):
|
|||||||
# Sort by game time (soonest first) and limit to upcoming_games_to_show
|
# Sort by game time (soonest first) and limit to upcoming_games_to_show
|
||||||
new_upcoming_games.sort(key=lambda x: x.get('start_time', ''))
|
new_upcoming_games.sort(key=lambda x: x.get('start_time', ''))
|
||||||
new_upcoming_games = new_upcoming_games[:self.upcoming_games_to_show]
|
new_upcoming_games = new_upcoming_games[:self.upcoming_games_to_show]
|
||||||
|
self.logger.info(f"[MiLB] Found {len(new_upcoming_games)} upcoming games after processing")
|
||||||
|
|
||||||
# Compare new list with old list to see if an update is needed
|
# Compare new list with old list to see if an update is needed
|
||||||
if self.upcoming_games != new_upcoming_games:
|
if self.upcoming_games != new_upcoming_games:
|
||||||
@@ -1660,8 +1666,10 @@ class MiLBUpcomingManager(BaseMiLBManager):
|
|||||||
self.current_game_index = 0
|
self.current_game_index = 0
|
||||||
self.current_game = self.upcoming_games[0]
|
self.current_game = self.upcoming_games[0]
|
||||||
self.last_game_switch = current_time
|
self.last_game_switch = current_time
|
||||||
|
self.logger.info(f"[MiLB] Set current game to: {self.current_game.get('away_team')} @ {self.current_game.get('home_team')}")
|
||||||
else:
|
else:
|
||||||
self.current_game = None # No upcoming games
|
self.current_game = None # No upcoming games
|
||||||
|
self.logger.info("[MiLB] No upcoming games, cleared current game")
|
||||||
|
|
||||||
self.last_update = current_time
|
self.last_update = current_time
|
||||||
|
|
||||||
@@ -1671,7 +1679,7 @@ class MiLBUpcomingManager(BaseMiLBManager):
|
|||||||
|
|
||||||
def display(self, force_clear: bool = False):
|
def display(self, force_clear: bool = False):
|
||||||
"""Display upcoming games."""
|
"""Display upcoming games."""
|
||||||
self.logger.debug(f"[MiLB] Display called with {len(self.upcoming_games)} upcoming games")
|
self.logger.info(f"[MiLB] Display called with {len(self.upcoming_games)} upcoming games")
|
||||||
if not self.upcoming_games:
|
if not self.upcoming_games:
|
||||||
current_time = time.time()
|
current_time = time.time()
|
||||||
if current_time - self.last_warning_time > self.warning_cooldown:
|
if current_time - self.last_warning_time > self.warning_cooldown:
|
||||||
|
|||||||
@@ -63,12 +63,12 @@ class DisplayMonitor:
|
|||||||
# Prefer service-provided snapshot if available (works when ledmatrix service is running)
|
# Prefer service-provided snapshot if available (works when ledmatrix service is running)
|
||||||
if os.path.exists(snapshot_path):
|
if os.path.exists(snapshot_path):
|
||||||
# Read atomically by reopening; ignore partials by skipping this frame
|
# Read atomically by reopening; ignore partials by skipping this frame
|
||||||
img_bytes = None
|
|
||||||
try:
|
try:
|
||||||
with open(snapshot_path, 'rb') as f:
|
with open(snapshot_path, 'rb') as f:
|
||||||
img_bytes = f.read()
|
img_bytes = f.read()
|
||||||
except Exception:
|
except Exception:
|
||||||
img_bytes = None
|
img_bytes = None
|
||||||
|
|
||||||
if img_bytes:
|
if img_bytes:
|
||||||
img_str = base64.b64encode(img_bytes).decode()
|
img_str = base64.b64encode(img_bytes).decode()
|
||||||
# If we can infer dimensions from display_manager, include them; else leave 0
|
# If we can infer dimensions from display_manager, include them; else leave 0
|
||||||
@@ -84,16 +84,8 @@ class DisplayMonitor:
|
|||||||
# Yield and continue to next frame
|
# Yield and continue to next frame
|
||||||
socketio.sleep(0.1)
|
socketio.sleep(0.1)
|
||||||
continue
|
continue
|
||||||
# If we can infer dimensions from display_manager, include them; else leave 0
|
# If snapshot exists but couldn't be read (partial write/permissions), skip this frame
|
||||||
width = display_manager.width if display_manager else 0
|
# and try again on next loop rather than emitting an invalid payload.
|
||||||
height = display_manager.height if display_manager else 0
|
|
||||||
current_display_data = {
|
|
||||||
'image': img_str,
|
|
||||||
'width': width,
|
|
||||||
'height': height,
|
|
||||||
'timestamp': time.time()
|
|
||||||
}
|
|
||||||
socketio.emit('display_update', current_display_data)
|
|
||||||
elif display_manager and hasattr(display_manager, 'image'):
|
elif display_manager and hasattr(display_manager, 'image'):
|
||||||
# Fallback to in-process manager image
|
# Fallback to in-process manager image
|
||||||
img_buffer = io.BytesIO()
|
img_buffer = io.BytesIO()
|
||||||
|
|||||||
Reference in New Issue
Block a user