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 )
}
}