/ data_loader.py
data_loader.py
1 import requests 2 import json 3 import logging 4 from typing import Tuple, Dict, Any 5 from config import APP_CONFIG, RIVERS, METRICS 6 7 logger = logging.getLogger(__name__) 8 9 def load_plot(station_id: str, title: str, plot_type: str = "temperature") -> Tuple[Dict, Dict]: 10 """ 11 Load plot data from hydrodaten.admin.ch 12 13 Args: 14 station_id: Station ID (e.g., "2135") 15 title: Plot title 16 plot_type: Either "temperature" or "flow" 17 18 Returns: 19 Tuple of (plot_data, latest_values) 20 """ 21 # Validate plot_type first 22 if plot_type not in METRICS: 23 raise ValueError(f"Invalid plot_type: {plot_type}. Must be one of {list(METRICS.keys())}") 24 25 try: 26 # Build URL based on plot type 27 if plot_type == "temperature": 28 url = f"{APP_CONFIG['DATA_BASE_URL']}{APP_CONFIG['TEMPERATURE_ENDPOINT']}".format(station_id=station_id) 29 else: 30 url = f"{APP_CONFIG['DATA_BASE_URL']}{APP_CONFIG['FLOW_ENDPOINT']}".format(station_id=station_id) 31 32 logger.debug(f"Fetching data from URL: {url}") 33 response = requests.get(url, timeout=10) 34 response.raise_for_status() 35 data = response.json() 36 37 # Add hover info for all data series in the plot 38 for series in data["plot"]["data"]: 39 if "hoverinfo" in series: 40 series["hoverinfo"] = "x+y+name" 41 42 # Extract latest measurements 43 latest_values = {} 44 if plot_type == "temperature": 45 # Get the latest temperature value 46 if data["plot"]["data"] and len(data["plot"]["data"]) > 0: 47 temp_data = data["plot"]["data"][0] 48 if ( 49 "x" in temp_data 50 and "y" in temp_data 51 and len(temp_data["x"]) > 0 52 and len(temp_data["y"]) > 0 53 ): 54 latest_values["value"] = temp_data["y"][-1] 55 latest_values["time"] = temp_data["x"][-1] 56 latest_values["unit"] = "°C" 57 else: 58 # For flow plots, there are usually multiple data series (flow and water level) 59 values = {} 60 for series in data["plot"]["data"]: 61 if ( 62 "x" in series 63 and "y" in series 64 and len(series["x"]) > 0 65 and len(series["y"]) > 0 66 ): 67 if "name" in series: 68 name = series["name"] 69 if "Abfluss" in name: 70 values["flow"] = { 71 "value": series["y"][-1], 72 "time": series["x"][-1], 73 "unit": "m³/s", 74 } 75 elif "Wasserstand" in name or "Pegel" in name: 76 values["level"] = { 77 "value": series["y"][-1], 78 "time": series["x"][-1], 79 "unit": "m", 80 } 81 latest_values = values 82 83 # Update the layout title with proper Dash format 84 data["plot"]["layout"]["title"] = {"text": title, "font": {"size": 24}} 85 return data["plot"], latest_values 86 87 except requests.exceptions.RequestException as e: 88 logger.error(f"Request failed for station {station_id}: {str(e)}") 89 return {}, {} 90 except json.JSONDecodeError as e: 91 logger.error(f"JSON parsing error for station {station_id}: {str(e)}") 92 return {}, {} 93 except Exception as e: 94 logger.error(f"Unexpected error for station {station_id}: {str(e)}") 95 return {}, {}