From a67aca5b455962c561cea969de5668294c14dc19 Mon Sep 17 00:00:00 2001 From: Chuck <33324927+ChuckBuilds@users.noreply.github.com> Date: Tue, 8 Apr 2025 18:03:17 -0500 Subject: [PATCH] Display updates trying to fix weather icons --- src/display_controller.py | 45 +++++++++++++++++++++------------------ src/weather_manager.py | 35 +++++++++++++++++++++++++----- 2 files changed, 54 insertions(+), 26 deletions(-) diff --git a/src/display_controller.py b/src/display_controller.py index 294f4a39..9951aa5e 100644 --- a/src/display_controller.py +++ b/src/display_controller.py @@ -30,19 +30,15 @@ class DisplayController: try: while True: current_time = time.time() - rotation_interval = self.config['display'].get('rotation_interval', 30) - - # Track if we're switching modes - switching_modes = False # Check if we need to switch display mode - if current_time - self.last_switch > rotation_interval: + if current_time - self.last_switch > self.config['display'].get('rotation_interval', 30): # Cycle through: clock -> current weather -> hourly forecast -> daily forecast if self.current_display == 'clock': self.current_display = 'weather' elif self.current_display == 'weather': self.current_display = 'hourly' - self.scroll_position = 0 + self.scroll_position = 0 # Reset scroll position when switching to hourly elif self.current_display == 'hourly': self.current_display = 'daily' else: # daily @@ -50,30 +46,37 @@ class DisplayController: logger.info("Switching display to: %s", self.current_display) self.last_switch = current_time - switching_modes = True self.display_manager.clear() # Clear display when switching modes + force_clear = True + else: + force_clear = False # Update scroll position for hourly forecast if needed - if self.current_display == 'hourly' and current_time - self.last_scroll > self.scroll_interval: - self.scroll_position += self.scroll_speed - self.last_scroll = current_time - - # Reset scroll position if we've gone through all forecasts - if self.scroll_position > self.display_manager.matrix.width * 3: # Approximate width of all forecasts - self.scroll_position = 0 + if self.current_display == 'hourly': + if current_time - self.last_scroll > self.scroll_interval: + self.scroll_position += self.scroll_speed + self.last_scroll = current_time + + # Reset scroll position if we've gone through all forecasts + if self.scroll_position > self.display_manager.matrix.width * 3: + self.scroll_position = 0 + force_clear = True # Clear when resetting scroll - # Display current screen (only force clear when switching modes) + # Display current screen if self.current_display == 'clock': - self.clock.display_time(force_clear=switching_modes) + self.clock.display_time(force_clear=force_clear) elif self.current_display == 'weather': - self.weather.display_weather(force_clear=switching_modes) + self.weather.display_weather(force_clear=force_clear) elif self.current_display == 'hourly': - self.weather.display_hourly_forecast(self.scroll_position, force_clear=switching_modes) + self.weather.display_hourly_forecast(self.scroll_position, force_clear=force_clear) else: # daily - self.weather.display_daily_forecast(force_clear=switching_modes) + self.weather.display_daily_forecast(force_clear=force_clear) - # Sleep for a short interval - time.sleep(0.02) + # Sleep longer when not scrolling + if self.current_display == 'hourly': + time.sleep(0.05) # 50ms for smooth scrolling + else: + time.sleep(0.1) # 100ms for static displays except KeyboardInterrupt: print("\nDisplay stopped by user") diff --git a/src/weather_manager.py b/src/weather_manager.py index 5e6eadfa..ab59f723 100644 --- a/src/weather_manager.py +++ b/src/weather_manager.py @@ -35,6 +35,7 @@ class WeatherManager: self.hourly_forecast = None self.daily_forecast = None self.scroll_position = 0 + self.last_draw_time = 0 # Add draw time tracking to reduce flickering def _fetch_weather(self) -> None: """Fetch current weather and forecast data from OpenWeatherMap API.""" @@ -184,8 +185,14 @@ class WeatherManager: if not self.hourly_forecast: return - # Always clear when drawing hourly forecast to prevent ghosting - self.display_manager.clear() + current_time = time.time() + # Only update if forced or enough time has passed (100ms minimum between updates) + if not force_clear and current_time - self.last_draw_time < 0.1: + return + + # Clear display when starting new scroll + if force_clear: + self.display_manager.clear() # Calculate base positions display_width = self.display_manager.matrix.width @@ -193,6 +200,10 @@ class WeatherManager: forecast_width = display_width // 2 # Each forecast takes half the width icon_size = 12 # Slightly smaller icons for better fit + # Create a new image for this frame + self.display_manager.image = Image.new('RGB', (self.display_manager.matrix.width, self.display_manager.matrix.height)) + self.display_manager.draw = ImageDraw.Draw(self.display_manager.image) + # Create the forecast display for i, forecast in enumerate(self.hourly_forecast): # Calculate x position with scrolling @@ -236,6 +247,10 @@ class WeatherManager: fill=(64, 64, 64) # Dim gray line ) + # Update the display + self.display_manager.update_display() + self.last_draw_time = current_time + def display_daily_forecast(self, force_clear: bool = False) -> None: """Display 3-day forecast information.""" if not self.daily_forecast: @@ -243,8 +258,14 @@ class WeatherManager: if not self.daily_forecast: return - # Always clear when drawing daily forecast - self.display_manager.clear() + current_time = time.time() + # Only update if forced or enough time has passed + if not force_clear and current_time - self.last_draw_time < 0.1: + return + + # Create new image for this frame + self.display_manager.image = Image.new('RGB', (self.display_manager.matrix.width, self.display_manager.matrix.height)) + self.display_manager.draw = ImageDraw.Draw(self.display_manager.image) # Calculate layout parameters display_width = self.display_manager.matrix.width @@ -290,4 +311,8 @@ class WeatherManager: self.display_manager.draw.line( [(sep_x, 0), (sep_x, display_height)], fill=(64, 64, 64) # Dim gray line - ) \ No newline at end of file + ) + + # Update the display + self.display_manager.update_display() + self.last_draw_time = current_time \ No newline at end of file