"""Renders local weather station history for the web UI.""" from __future__ import annotations import json from datetime import datetime from gibil.classes.models import WeatherStationObservation from astrape_oracle.classes.datasets import WeatherStationDisplayDataset class WeatherStationDisplay: """Renders local weather station history for the Astrape web UI.""" def render(self) -> str: return """

Weather Station

Local Ecowitt history

""" def data_payload( self, dataset: WeatherStationDisplayDataset | None = None, ) -> str: if dataset is None: dataset = WeatherStationDisplayDataset(observations=[]) observations = [ self._observation(observation) for observation in dataset.observations ] return json.dumps( { "now": datetime.now().astimezone().isoformat(), "observations": observations, "stats": self._stats(observations), } ) def _observation( self, observation: WeatherStationObservation, ) -> dict[str, object]: return { "observed_at": self._iso(observation.observed_at), "received_at": self._iso(observation.received_at), "source": observation.source, "temperature_c": observation.temperature_c, "relative_humidity_pct": observation.relative_humidity_pct, "dew_point_c": observation.dew_point_c, "pressure_hpa": observation.pressure_hpa, "wind_speed_m_s": observation.wind_speed_m_s, "wind_gust_m_s": observation.wind_gust_m_s, "wind_max_m_s": observation.wind_max_m_s, "wind_direction_deg": observation.wind_direction_deg, "solar_radiation_w_m2": observation.solar_radiation_w_m2, "uv_index": observation.uv_index, "rain_rate_mm_h": observation.rain_rate_mm_h, "rain_event_mm": observation.rain_event_mm, "rain_hourly_mm": observation.rain_hourly_mm, "rain_daily_mm": observation.rain_daily_mm, "rain_weekly_mm": observation.rain_weekly_mm, "rain_monthly_mm": observation.rain_monthly_mm, "rain_yearly_mm": observation.rain_yearly_mm, "indoor_temperature_c": observation.indoor_temperature_c, "indoor_humidity_pct": observation.indoor_humidity_pct, "absolute_pressure_hpa": observation.absolute_pressure_hpa, "relative_pressure_hpa": observation.relative_pressure_hpa, } def _stats(self, observations: list[dict[str, object]]) -> dict[str, object]: latest = observations[-1] if observations else {} return { "latest_temperature_c": latest.get("temperature_c"), "latest_relative_humidity_pct": latest.get("relative_humidity_pct"), "latest_rain_daily_mm": latest.get("rain_daily_mm"), "max_solar_radiation_w_m2": self._max_value( observations, "solar_radiation_w_m2" ), "max_rain_rate_mm_h": self._max_value(observations, "rain_rate_mm_h"), "max_wind_gust_m_s": self._max_value(observations, "wind_gust_m_s"), } def _max_value( self, observations: list[dict[str, object]], key: str, ) -> float | None: values = [ value for observation in observations if isinstance((value := observation.get(key)), (int, float)) ] if not values: return None return float(max(values)) def _iso(self, value: datetime) -> str: return value.isoformat()