@@ -201,6 +201,8 @@ impl TryFrom<&str> for CellSelection {
201201pub struct Options {
202202 pub location : location:: Location ,
203203 pub elevation : Option < Elevation > ,
204+ /// Attributes to request for minutely_15 forecast
205+ pub minutely_15 : Vec < String > ,
204206 /// Attributes to request in hourly intervals
205207 pub hourly : Vec < String > ,
206208 /// Attributes to request in daily intervals
@@ -213,6 +215,8 @@ pub struct Options {
213215 pub time_zone : Option < String > ,
214216 pub past_days : Option < u8 > ,
215217 pub forecast_days : Option < u8 > ,
218+ // max minutely_15 data points is 1536
219+ pub forecast_minutely_15 : Option < u16 > ,
216220 pub start_date : Option < chrono:: NaiveDate > ,
217221 pub end_date : Option < chrono:: NaiveDate > ,
218222 pub models : Option < Vec < String > > ,
@@ -225,6 +229,7 @@ impl Default for Options {
225229 Self {
226230 location : location:: Location :: default ( ) ,
227231 elevation : None ,
232+ minutely_15 : Vec :: new ( ) ,
228233 hourly : Vec :: new ( ) ,
229234 daily : Vec :: new ( ) ,
230235 current : Vec :: new ( ) ,
@@ -234,6 +239,7 @@ impl Default for Options {
234239 time_zone : Some ( "UTC" . into ( ) ) ,
235240 past_days : None ,
236241 forecast_days : None ,
242+ forecast_minutely_15 : None ,
237243 start_date : None ,
238244 end_date : None ,
239245 models : None ,
@@ -275,6 +281,10 @@ impl Options {
275281 if let Some ( v) = self . past_days {
276282 params. push ( ( "past_days" . into ( ) , v. to_string ( ) ) ) ;
277283 }
284+
285+ if let Some ( v) = self . forecast_minutely_15 {
286+ params. push ( ( "forecast_minutely_15" . into ( ) , v. to_string ( ) ) ) ;
287+ }
278288
279289 if let Some ( v) = self . forecast_days {
280290 params. push ( ( "forecast_days" . into ( ) , v. to_string ( ) ) ) ;
@@ -292,6 +302,10 @@ impl Options {
292302 params. push ( ( "current" . into ( ) , self . current . join ( "," ) ) ) ;
293303 }
294304
305+ if !self . minutely_15 . is_empty ( ) {
306+ params. push ( ( "minutely_15" . into ( ) , self . minutely_15 . join ( "," ) ) ) ;
307+ }
308+
295309 if !self . hourly . is_empty ( ) {
296310 params. push ( ( "hourly" . into ( ) , self . hourly . join ( "," ) ) ) ;
297311 }
@@ -329,6 +343,8 @@ struct ApiForecastResponse {
329343 pub timezone_abbreviation : Option < String > ,
330344 pub current_units : Option < HashMap < String , String > > ,
331345 pub current : Option < HashMap < String , serde_json:: Value > > ,
346+ pub minutely_15_units : Option < HashMap < String , String > > ,
347+ pub minutely_15 : Option < HashMap < String , serde_json:: Value > > ,
332348 pub hourly_units : Option < HashMap < String , String > > ,
333349 pub hourly : Option < HashMap < String , serde_json:: Value > > ,
334350 pub daily_units : Option < HashMap < String , String > > ,
@@ -348,6 +364,7 @@ pub struct ForecastResultHourly {
348364}
349365
350366pub type CurrentResult = ForecastResultHourly ;
367+ pub type ForecastResultMinutely15 = ForecastResultHourly ;
351368
352369#[ derive( Debug , Serialize , Deserialize , Default ) ]
353370pub struct ForecastResultDaily {
@@ -358,6 +375,7 @@ pub struct ForecastResultDaily {
358375#[ derive( Debug , Serialize , Deserialize , Default ) ]
359376pub struct ForecastResult {
360377 pub current : Option < CurrentResult > ,
378+ pub minutely_15 : Option < Vec < ForecastResultMinutely15 > > ,
361379 pub hourly : Option < Vec < ForecastResultHourly > > ,
362380 pub daily : Option < Vec < ForecastResultDaily > > ,
363381}
@@ -425,6 +443,56 @@ impl client::Client {
425443 // Get utc offset
426444 let utc_offset_seconds = api_res. utc_offset_seconds . unwrap_or ( 0 ) ;
427445
446+ // Minutely 15
447+ if let Some ( minutely_15) = api_res. minutely_15 {
448+ if let Some ( minutely_15_date_times) =
449+ extract_times ( & minutely_15, utc_offset_seconds) ?
450+ {
451+ if let Some ( minutely_15_units) = api_res. minutely_15_units {
452+ let mut minutely_15_result = Vec :: new ( ) ;
453+
454+ // Iterate on times
455+ for ( idx, time) in minutely_15_date_times. iter ( ) . enumerate ( ) {
456+ let mut minutely_15_rec = ForecastResultMinutely15 {
457+ datetime : * time,
458+ ..Default :: default ( )
459+ } ;
460+
461+ // Iterates on values
462+ for ( k, v) in minutely_15. iter ( ) {
463+ if k == "time" {
464+ continue ;
465+ }
466+
467+ let mut item = ForecastResultItem :: default ( ) ;
468+ let v_arr = match v. as_array ( ) {
469+ Some ( v) => v,
470+ None => {
471+ return Err ( "cannot decode properly json input" . into ( ) ) ;
472+ }
473+ } ;
474+
475+ let v_val = v_arr[ idx] . clone ( ) ;
476+ item. value = v_val;
477+
478+ // Try to find unit
479+ if let Some ( unit) = minutely_15_units. get ( k) {
480+ item. unit = Some ( unit. clone ( ) ) ;
481+ }
482+
483+ // Push to minutely_15 record
484+ minutely_15_rec. values . insert ( k. clone ( ) , item) ;
485+ }
486+
487+ // Push minutely_15 rec
488+ minutely_15_result. push ( minutely_15_rec) ;
489+ }
490+
491+ result. minutely_15 = Some ( minutely_15_result) ;
492+ }
493+ }
494+ }
495+
428496 // Hourly
429497 if let Some ( hourly) = api_res. hourly {
430498 if let Some ( hourly_date_times) = extract_times ( & hourly, utc_offset_seconds) ? {
@@ -586,6 +654,8 @@ mod tests {
586654
587655 opts. elevation = Some ( "nan" . try_into ( ) . unwrap ( ) ) ;
588656
657+ opts. minutely_15 . push ( "temperature_2m" . into ( ) ) ;
658+ opts. minutely_15 . push ( "windspeed_10m" . into ( ) ) ;
589659 opts. hourly . push ( "temperature_2m" . into ( ) ) ;
590660 opts. hourly . push ( "windspeed_120m" . into ( ) ) ;
591661 opts. daily . push ( "temperature_2m_max" . into ( ) ) ;
0 commit comments