Files
Astronome/backend/src/weather/openmeteo.rs
T
2026-04-10 00:14:10 +02:00

57 lines
1.5 KiB
Rust

use anyhow::Context;
use serde::{Deserialize, Serialize};
const OPENMETEO_URL: &str =
"https://api.open-meteo.com/v1/forecast?latitude=43.8167&longitude=4.1167\
&current=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<DewAlert> {
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<CurrentConditions> {
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,
})
}