174 lines
4.5 KiB
Rust
174 lines
4.5 KiB
Rust
use crate::error::{ManifoldError, ManifoldResult};
|
|
use reqwest::Client;
|
|
use reqwest::header::CONTENT_TYPE;
|
|
use crate::models::fueltank::FuelTank;
|
|
|
|
#[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,
|
|
}
|
|
|
|
pub type Weather = FuelTank;
|
|
|
|
impl Weather {
|
|
|
|
pub async fn get_weather_forecast(&self, target: String) -> ManifoldResult<WeatherForecastRequestResponse> {
|
|
|
|
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);
|
|
|
|
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);
|
|
|
|
|
|
debug!("{:?}", &decoded_result);
|
|
|
|
Ok(decoded_result)
|
|
}
|
|
}
|