import time class WeatherDisplay: def __init__(self, display): self.display = display self.text_padding = 4 self.last_displayed_data = None self.time_update_running = False self.time_thread = None def weathercode_to_text(self, weathercode): if weathercode == 0: return 'Clear Sky' elif weathercode == 1: return 'Mainly Clear' elif weathercode == 2: return 'Partly Cloudy' elif weathercode == 3: return 'Overcast' elif weathercode in [45, 48]: return 'Foggy' elif weathercode in [51, 53, 55]: return 'Light Rain' elif weathercode in [56, 57]: return 'Freezing Rain' elif weathercode in [61, 63, 65]: return 'Moderate Rain' elif weathercode in [66, 67]: return 'Heavy Rain' elif weathercode in [71, 73, 75]: return 'Snow Fall' elif weathercode == 77: return 'Snow Grains' elif weathercode in [80, 81, 82]: return 'Rain Showers' elif weathercode in [85, 86]: return 'Snow Showers' elif weathercode == 95: return 'Thunderstorm' elif weathercode in [96, 99]: return 'Thunderstorm with Hail' else: return 'Unknown Weather' if force_full_update: self.display.clear() else: # Create a clean buffer but don't send to display yet self.display.fill(self.display.black) text_x = self.text_padding text_y = 8 update_regions = [] temp_text = f"Temp: {weather_data.get('max_temp', 0):.0f}/{weather_data.get('min_temp', 0):.0f}C" if force_full_update or not self.last_displayed_data or \ self.last_displayed_data.get('max_temp') != weather_data.get('max_temp') or \ self.last_displayed_data.get('miget_wen_temp') != weather_data.get('min_temp'): self.display.text(temp_text, text_x, text_y) update_regions.append((0, text_y, 16, text_y + 8)) weathercode = weather_data.get('weathercode', 0) weather_text = self.weathercode_to_text(weathercode) if force_full_update or not self.last_displayed_data or \ self.last_displayed_data.get('weathercode') != weathercode: self.display.text(f"{weather_text}", text_x, text_y + 12) update_regions.append((0, text_y + 12, 16, text_y + 20)) precip_text = f"Precip: {weather_data.get('precip_mm', 0):.1f}mm" if force_full_update or not self.last_displayed_data or \ self.last_displayed_data.get('precip_mm') != weather_data.get('precip_mm'): self.display.text(precip_text, text_x, text_y + 24) update_regions.append((0, text_y + 24, 16, text_y + 32)) date_text = weather_data.get('date', '') if date_text and len(date_text) >= 10: year = date_text[0:4] month = date_text[5:7] day = date_text[8:10] date_text = f"{day}-{month}-{year}" if force_full_update or not self.last_displayed_data or \ self.last_displayed_data.get('date') != weather_data.get('date'): self.display.text(f"Date: {date_text}", text_x, text_y + 36) update_regions.append((0, text_y + 36, 16, text_y + 44)) self.last_displayed_data = dict(weather_data) self.last_displayed_data['view_type'] = 'detailed' if force_full_update: self.display.show() else: if update_regions: min_y = min(region[1] for region in update_regions) max_y = max(region[3] for region in update_regions) self.display.show(0, min_y, 16, max_y) else: pass def display_weather(self, weather_data): """Detailed view with max/min temps, description, precip, date.""" if 'daily' in weather_data: d = weather_data['daily'] weather_data = { 'max_temp': d['temperature_2m_max'][0], 'min_temp': d['temperature_2m_min'][0], 'weathercode':d['weathercode'][0], 'precip_mm': d['precipitation_sum'][0], 'date': d['time'][0], } force_full_update = ( self.last_displayed_data is None or self.last_displayed_data.get('view_type') != 'detailed' ) if force_full_update: self.display.clear() else: self.display.fill(self.display.black) text_x = self.text_padding text_y = 8 update_regions = [] temp_text = f"Temp: {weather_data.get('max_temp', 0):.0f}/" \ f"{weather_data.get('min_temp', 0):.0f}C" if (force_full_update or self.last_displayed_data.get('max_temp') != weather_data.get('max_temp') or self.last_displayed_data.get('min_temp') != weather_data.get('min_temp') ): self.display.text(temp_text, text_x, text_y) update_regions.append((text_y, text_y + 8)) code = weather_data.get('weathercode', 0) desc = self.weathercode_to_text(code) if (force_full_update or self.last_displayed_data.get('weathercode') != code ): self.display.text(desc, text_x, text_y + 12) update_regions.append((text_y + 12, text_y + 20)) precip = f"Precip: {weather_data.get('precip_mm', 0):.1f}mm" if (force_full_update or self.last_displayed_data.get('precip_mm') != weather_data.get('precip_mm') ): self.display.text(precip, text_x, text_y + 24) update_regions.append((text_y + 24, text_y + 32)) raw_date = weather_data.get('date', '') if raw_date and len(raw_date) >= 10: dd = raw_date[8:10]; mm = raw_date[5:7]; yyyy = raw_date[0:4] formatted = f"Date: {dd}-{mm}-{yyyy}" if (force_full_update or self.last_displayed_data.get('date') != raw_date ): self.display.text(formatted, text_x, text_y + 36) update_regions.append((text_y + 36, text_y + 44)) self.last_displayed_data = dict(weather_data) self.last_displayed_data['view_type'] = 'detailed' if force_full_update: self.display.show() return if update_regions: min_y = min(r[0] for r in update_regions) max_y = max(r[1] for r in update_regions) page_count = self.display.height // 8 self.display.show(1, min_y, page_count, max_y) def display_simple_weather(self, weather_data): force_full_update = self.last_displayed_data is None or self.last_displayed_data.get('view_type') != 'simple' if force_full_update: self.display.clear() else: self.display.fill(self.display.black) text_x = self.text_padding center_y = self.display.height // 2 update_regions = [] temp_text = f"{weather_data.get('current_temp', 0):.0f}C" if force_full_update or not self.last_displayed_data or \ self.last_displayed_data.get('current_temp') != weather_data.get('current_temp'): self.display.text(temp_text, text_x, center_y - 8, scale=2) update_regions.append((0, center_y - 8, 16, center_y + 8)) # Scaled text is 16px high weather_desc = self.weathercode_to_text(weather_data.get('weathercode', 0)) if force_full_update or not self.last_displayed_data or \ self.last_displayed_data.get('weathercode') != weather_data.get('weathercode'): self.display.text(weather_desc, text_x, center_y + 12) update_regions.append((0, center_y + 12, 16, center_y + 20)) current_time_tuple = time.localtime(time.time()) current_time = f"{current_time_tuple[3]:02d}:{current_time_tuple[4]:02d}:{current_time_tuple[5]:02d}" if current_time and (force_full_update or not self.last_displayed_data or \ self.last_displayed_data.get('current_time') != current_time): self.display.text(current_time, text_x, center_y + 24) update_regions.append((0, center_y + 24, 16, center_y + 32)) self.last_displayed_data = dict(weather_data) self.last_displayed_data['view_type'] = 'simple' if force_full_update: self.display.show() else: if update_regions: min_y = min(region[1] for region in update_regions) max_y = max(region[3] for region in update_regions) self.display.show(0, min_y, 16, max_y) else: pass def reset_display(self): """Clear display and reset last displayed data.""" self.display.clear() self.display.show() self.last_displayed_data = None