From 256acab0be40839b810e99dc146881a1a1eaf201 Mon Sep 17 00:00:00 2001 From: ChuckBuilds <33324927+ChuckBuilds@users.noreply.github.com> Date: Sun, 25 May 2025 15:33:33 -0500 Subject: [PATCH] more robust triggers for activating and deactivating ytm music --- src/display_controller.py | 60 ++++++++++++++++++++++++++------------- src/music_manager.py | 41 ++++++++++++-------------- 2 files changed, 59 insertions(+), 42 deletions(-) diff --git a/src/display_controller.py b/src/display_controller.py index 314b7443..0f79f464 100644 --- a/src/display_controller.py +++ b/src/display_controller.py @@ -675,12 +675,16 @@ class DisplayController: if not is_currently_live: # --- Currently in a Regular Mode (or just exited Live) --- + previous_mode_before_switch = self.current_display_mode # Capture mode before potential change + if has_live_games: # Not currently live, but live games ARE available. Switch IN. - # (This check ensures we only switch *in* if we weren't already live) - new_mode = f"{live_sport_type}_live" # live_sport_type has the highest priority - if self.current_display_mode != new_mode: # Avoid unnecessary resets if somehow already correct + new_mode = f"{live_sport_type}_live" + if self.current_display_mode != new_mode: logger.info(f"Switching into LIVE mode: {new_mode} from {self.current_display_mode}") + if previous_mode_before_switch == 'music' and self.music_manager: + logger.info("Deactivating music manager due to switch from music to live mode.") + self.music_manager.deactivate_music_display() self.current_display_mode = new_mode self.force_clear = True self.last_switch = current_time @@ -695,37 +699,55 @@ class DisplayController: # No live games detected, and not in live mode. Regular rotation. needs_switch = False if self.current_display_mode.endswith('_live'): - # This case handles the explicit transition OUT of live mode + # This case handles the explicit transition OUT of live mode # initiated in the block above. logger.info(f"Transitioning from live mode to regular rotation.") - needs_switch = True - # Find the next *regular* mode index cleanly + needs_switch = True + # current_mode_index would have been advanced if coming from regular timer expiry. + # If coming from live mode exit, we need to ensure it's set for the *next* regular mode. + # The logic below assumes current_mode_index is for the *new* mode. try: - # Find where we *would* be if we weren't live - # This assumes self.current_mode_index tracks the regular rotation position - self.current_mode_index = (self.current_mode_index + 1) % len(self.available_modes) - except Exception: # Catch potential issues if available_modes changed etc. - logger.warning("Error advancing regular mode index after live mode exit. Resetting.") - self.current_mode_index = 0 - - if not self.available_modes: # Safety check + # If previous_mode_before_switch was a live mode, current_mode_index might be stale. + # We need to find the next available regular mode from self.available_modes + # This part can be tricky. Let's assume current_mode_index is either current or needs +1. + # If just exiting live, self.current_mode_index hasn't been incremented by timer logic yet. + # So, we just use its current value to pick from available_modes. + # If it was already pointing at 'music' and music is next, it's fine. + # If it was stale, it will pick an available mode. + pass # The original logic for picking mode is below. + except Exception: + logger.warning("Error finding next regular mode index after live mode exit. Resetting.") + self.current_mode_index = 0 + + if not self.available_modes: logger.error("No available regular modes to switch to!") - self.current_display_mode = 'none' # Or handle error appropriately - # Consider exiting or sleeping + self.current_display_mode = 'none' else: - self.current_display_mode = self.available_modes[self.current_mode_index] + # This is where the new regular mode is chosen after exiting live + new_regular_mode_after_live = self.available_modes[self.current_mode_index] + if previous_mode_before_switch == 'music' and self.music_manager and new_regular_mode_after_live != 'music': + logger.info(f"Deactivating music manager due to switch from music (via live exit) to {new_regular_mode_after_live}.") + self.music_manager.deactivate_music_display() + # If previous_mode_before_switch was live, and new_regular_mode_after_live is music, MusicManager.display will handle activation. + self.current_display_mode = new_regular_mode_after_live + elif current_time - self.last_switch >= self.get_current_duration(): # Regular timer expired, advance to next mode logger.debug(f"Timer expired for regular mode {self.current_display_mode}. Switching.") - # Advance calendar event *before* potentially switching away if self.current_display_mode == 'calendar' and self.calendar: self.calendar.advance_event() needs_switch = True self.current_mode_index = (self.current_mode_index + 1) % len(self.available_modes) - self.current_display_mode = self.available_modes[self.current_mode_index] + new_mode_after_timer = self.available_modes[self.current_mode_index] + if previous_mode_before_switch == 'music' and self.music_manager and new_mode_after_timer != 'music': + logger.info(f"Deactivating music manager due to timer switch from music to {new_mode_after_timer}.") + self.music_manager.deactivate_music_display() + # If switching to music, MusicManager.display will handle activation. + self.current_display_mode = new_mode_after_timer if needs_switch: + # This log now reflects the already updated self.current_display_mode logger.info(f"Switching to regular mode: {self.current_display_mode}") self.force_clear = True self.last_switch = current_time diff --git a/src/music_manager.py b/src/music_manager.py index 408cb2cf..6ece5ec6 100644 --- a/src/music_manager.py +++ b/src/music_manager.py @@ -446,15 +446,12 @@ class MusicManager: # Method moved from DisplayController and renamed def display(self, force_clear: bool = False): - if force_clear: # When DisplayController switches to music mode, it likely sets force_clear=True + if force_clear: # When DisplayController switches to music mode self.display_manager.clear() - # If force_clear is used to initiate/reset the music display, we should activate. - self.activate_music_display() - # Note: current_track_info might be empty this exact frame if YTM just connected. - # The logic below will show "Nothing Playing" if so for this frame, - # but YTM connection is now active and data should arrive for the next frame. + self.activate_music_display() # Ensure YTM connection is initiated and is_music_display_active is true + # current_track_info might be stale this frame, leading to "Nothing Playing" initially, + # but YTM connection will be active to receive updates. - # Use self.current_track_info which is updated by _poll_music_data or YTM direct update display_info = self.current_track_info if not display_info or not display_info.get('is_playing', False) or display_info.get('title') == 'Nothing Playing': @@ -464,15 +461,12 @@ class MusicManager: logger.info("Music Screen (MusicManager): Nothing playing or info unavailable.") self._last_nothing_playing_log_time = time.time() - # Only deactivate if: - # 1. Music display was previously active. - # 2. force_clear was FALSE in this call (meaning we are not in the initial activation frame). - if not force_clear and self.is_music_display_active: - self.deactivate_music_display() + # DEACTIVATION LOGIC REMOVED FROM HERE. + # YTM will remain connected as long as the music display mode is active. + # Deactivation is handled by stop_polling or an explicit call if DisplayController + # signals a mode change away from music. # Ensure screen is clear if not already by force_clear. - # If force_clear was true, it was cleared at the top. - # If force_clear was false and we are here, we need to clear for "Nothing Playing". if not force_clear: self.display_manager.clear() @@ -481,24 +475,25 @@ class MusicManager: y_pos = (self.display_manager.matrix.height // 2) - 4 self.display_manager.draw_text("Nothing Playing", x=x_pos, y=y_pos, font=self.display_manager.regular_font) self.display_manager.update_display() + self.scroll_position_title = 0 self.scroll_position_artist = 0 - self.title_scroll_tick = 0 + self.title_scroll_tick = 0 self.artist_scroll_tick = 0 - self.album_art_image = None # Clear album art if nothing is playing - self.last_album_art_url = None # Also clear the URL + self.album_art_image = None + self.last_album_art_url = None return # If we've reached here, it means we are about to display actual music info. - # Ensure music display components (like YTM connection) are active. - # This will be true if force_clear was set, or if it was active from a previous frame. - # If it's somehow not active (e.g., error or specific sequence), activate it. + # Ensure music display components (like YTM connection) are active if not already. if not self.is_music_display_active: - self.activate_music_display() # This will attempt to connect YTM if needed + # This might be called if display() is invoked when music mode is already considered + # active by DisplayController but is_music_display_active is False in MusicManager + # (e.g. after an error or unexpected state). + self.activate_music_display() # Ensure screen is cleared if not force_clear but needed (e.g. transition from "Nothing Playing" to actual music) - # If force_clear was true, screen is already blank and ready. - if not force_clear: + if not force_clear: # If force_clear was true, screen is already blank and ready. self.display_manager.draw.rectangle([0, 0, self.display_manager.matrix.width, self.display_manager.matrix.height], fill=(0, 0, 0)) # Album Art Configuration