use anyhow::Context; use serde::{Deserialize, Serialize}; const OPENMETEO_URL: &str = "https://api.open-meteo.com/v1/forecast?latitude=43.8167&longitude=4.1167\ ¤t=temperature_2m,relative_humidity_2m,dew_point_2m&wind_speed_unit=ms"; #[derive(Debug, Clone, Serialize, Deserialize)] pub struct CurrentConditions { pub temp_c: f64, pub humidity_pct: f64, pub dew_point_c: f64, } #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(rename_all = "snake_case")] pub enum DewAlert { Warning, Critical, } pub fn dew_alert(temp_c: f64, dew_point_c: f64) -> Option { let margin = temp_c - dew_point_c; if margin < 2.0 { Some(DewAlert::Critical) } else if margin < 4.0 { Some(DewAlert::Warning) } else { None } } pub async fn fetch_openmeteo() -> anyhow::Result { let client = reqwest::Client::builder() .timeout(std::time::Duration::from_secs(30)) .build()?; let resp = client .get(OPENMETEO_URL) .send() .await .context("Open-Meteo request failed")?; let json: serde_json::Value = resp.json().await.context("Open-Meteo JSON parse failed")?; let current = &json["current"]; let temp = current["temperature_2m"].as_f64().unwrap_or(0.0); let humidity = current["relative_humidity_2m"].as_f64().unwrap_or(0.0); let dew = current["dew_point_2m"].as_f64().unwrap_or(temp - 10.0); Ok(CurrentConditions { temp_c: temp, humidity_pct: humidity, dew_point_c: dew, }) }