57 lines
1.5 KiB
Rust
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\
|
|
¤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<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,
|
|
})
|
|
}
|