manifold/src/models/weather.rs

174 lines
4.5 KiB
Rust
Raw Normal View History

2023-08-30 15:53:24 +00:00
use crate::error::{ManifoldError, ManifoldResult};
2023-08-23 17:37:42 +00:00
use reqwest::Client;
use reqwest::header::CONTENT_TYPE;
2023-08-30 15:53:24 +00:00
use crate::models::fueltank::FuelTank;
2023-08-23 17:37:42 +00:00
#[derive(Debug, Deserialize)]
pub struct CurrentConditionInformation {
pub text: String,
pub icon: String,
pub code: i64,
}
#[derive(Debug, Deserialize)]
pub struct CurrentWeatherInformation {
pub last_updated: String,
pub last_updated_epoch: i64,
pub temp_c: f64,
pub temp_f: f64,
pub feelslike_c: f64,
pub feelslike_f: f64,
pub condition: CurrentConditionInformation,
pub wind_mph: f64,
pub wind_kph: f64,
pub wind_degree: i64,
pub wind_dir: String,
pub pressure_mb: f64,
pub pressure_in: f64,
pub precip_mm: f64,
pub precip_in: f64,
pub humidity: i64,
pub cloud: i64,
pub is_day: i64,
pub uv: f64,
pub gust_mph: f64,
pub gust_kph: f64,
pub dewpoint_c: Option<f64>,
pub dewpoint_f: Option<f64>,
}
#[derive(Debug, Deserialize)]
pub struct ForecastHour {
pub time_epoch: i64,
pub time: String,
pub temp_c: f64,
pub temp_f: f64,
pub condition: CurrentConditionInformation,
pub wind_mph: f64,
pub wind_kph: f64,
pub wind_degree: i64,
pub wind_dir: String,
pub pressure_mb: f64,
pub pressure_in: f64,
pub precip_mm: f64,
pub precip_in: f64,
pub humidity: i64,
pub cloud: i64,
pub feelslike_c: f64,
pub feelslike_f: f64,
pub windchill_c: f64,
pub windchill_f: f64,
pub heatindex_c: f64,
pub heatindex_f: f64,
pub dewpoint_c: f64,
pub dewpoint_f: f64,
pub will_it_rain: i64,
pub will_it_snow: i64,
pub is_day: i64,
pub vis_km: f64,
pub vis_miles: f64,
pub chance_of_rain: i64,
pub chance_of_snow: i64,
pub gust_mph: f64,
pub gust_kph: f64,
}
#[derive(Debug, Deserialize)]
pub struct DayWeather {
pub maxtemp_c: f64,
pub maxtemp_f: f64,
pub mintemp_c: f64,
pub mintemp_f: f64,
pub avgtemp_c: f64,
pub avgtemp_f: f64,
pub maxwind_mph: f64,
pub maxwind_kph: f64,
pub totalprecip_mm: f64,
pub totalprecip_in: f64,
pub avgvis_km: f64,
pub avgvis_miles: f64,
pub avghumidity: f64,
pub condition: CurrentConditionInformation,
pub uv: f64,
}
#[derive(Debug, Deserialize)]
pub struct DayAstro {
pub sunrise: String,
pub sunset: String,
pub moonrise: String,
pub moonset: String,
pub moon_phase: String,
pub moon_illumination: String
}
#[derive(Debug, Deserialize)]
pub struct ForecastDayWrapper {
pub forecastday: Vec<ForecastDay>
}
#[derive(Debug, Deserialize)]
pub struct ForecastDay {
pub date: String,
pub date_epoch: i64,
pub day: DayWeather,
pub astro: DayAstro,
pub hour: Vec<ForecastHour>
}
#[derive(Debug, Deserialize)]
pub struct LocationInformation {
pub name: String,
pub region: String,
pub country: String,
pub lat: f64,
pub lon: f64,
pub tz_id: String,
pub localtime_epoch: i64,
pub localtime: String,
}
#[derive(Debug, Deserialize)]
pub struct WeatherRequestResponse {
pub location: LocationInformation,
pub current: CurrentWeatherInformation,
}
#[derive(Debug, Deserialize)]
pub struct WeatherForecastRequestResponse {
pub location: LocationInformation,
pub current: CurrentWeatherInformation,
pub forecast: ForecastDayWrapper,
}
2023-08-30 15:53:24 +00:00
pub type Weather = FuelTank;
2023-08-23 17:37:42 +00:00
impl Weather {
2023-08-30 15:53:24 +00:00
pub async fn get_weather_forecast(&self, target: String) -> ManifoldResult<WeatherForecastRequestResponse> {
2023-08-23 17:37:42 +00:00
2023-08-30 15:53:24 +00:00
let target_url = format!("{}/forecast.json?key={}&q={}&days=2", self.source_uri, self.api_key.clone().ok_or_else(|| ManifoldError::from("No API key presented for Weather API"))?, &target);
2023-08-23 17:37:42 +00:00
let client = Client::new();
let result = client.get(target_url)
.header(CONTENT_TYPE, "application/json")
.send()
.await?
.text()
.await?;
debug!("{:?}", result);
let mut decoded_result: WeatherForecastRequestResponse = serde_json::from_str(&*result)?;
let temp = decoded_result.current.temp_c; let humid = decoded_result.current.humidity as f64;
decoded_result.current.dewpoint_c = Some(&temp - (14.55 + 0.114 * &temp) * (1.0 - (0.01 * &humid)) - num::pow((2.5 + 0.007 * &temp) * (1.0 - (0.01 * &humid)),3) - (15.9 + 0.117 * &temp) * num::pow(1.0 - (0.01 * &humid), 14));
decoded_result.current.dewpoint_f = Some((decoded_result.current.dewpoint_c.unwrap() * 1.8) + 32.0);
2023-08-30 15:53:24 +00:00
debug!("{:?}", &decoded_result);
2023-08-23 17:37:42 +00:00
Ok(decoded_result)
}
}