forked from paul/sinoptik
Add retrieval of pollen and UVI metrics for Buienradar provider
This commit is contained in:
parent
5dc51b4c02
commit
46531a76bd
|
@ -8,7 +8,7 @@ use rocket::serde::Serialize;
|
|||
use crate::maps::MapsHandle;
|
||||
use crate::position::Position;
|
||||
use crate::providers;
|
||||
use crate::providers::buienradar::Item as BuienradarItem;
|
||||
use crate::providers::buienradar::{Item as BuienradarItem, Sample as BuienradarSample};
|
||||
use crate::providers::luchtmeetnet::Item as LuchtmeetnetItem;
|
||||
|
||||
/// The current forecast for a specific location.
|
||||
|
@ -50,7 +50,7 @@ pub(crate) struct Forecast {
|
|||
|
||||
/// The pollen in the air (when asked for).
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pollen: Option<()>,
|
||||
pollen: Option<Vec<BuienradarSample>>,
|
||||
|
||||
/// The precipitation (when asked for).
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
|
@ -58,7 +58,7 @@ pub(crate) struct Forecast {
|
|||
|
||||
/// The UV index (when asked for).
|
||||
#[serde(rename = "UVI", skip_serializing_if = "Option::is_none")]
|
||||
uvi: Option<()>,
|
||||
uvi: Option<Vec<BuienradarSample>>,
|
||||
}
|
||||
|
||||
impl Forecast {
|
||||
|
@ -115,7 +115,7 @@ impl Metric {
|
|||
pub(crate) async fn forecast(
|
||||
position: Position,
|
||||
metrics: Vec<Metric>,
|
||||
_maps_handle: &MapsHandle,
|
||||
maps_handle: &MapsHandle,
|
||||
) -> Forecast {
|
||||
let mut forecast = Forecast::new(position);
|
||||
|
||||
|
@ -136,11 +136,17 @@ pub(crate) async fn forecast(
|
|||
Metric::O3 => forecast.o3 = providers::luchtmeetnet::get(position, metric).await,
|
||||
Metric::PAQI => forecast.paqi = Some(()),
|
||||
Metric::PM10 => forecast.pm10 = providers::luchtmeetnet::get(position, metric).await,
|
||||
Metric::Pollen => forecast.pollen = Some(()),
|
||||
Metric::Precipitation => {
|
||||
forecast.precipitation = providers::buienradar::get(position, metric).await
|
||||
Metric::Pollen => {
|
||||
forecast.pollen =
|
||||
providers::buienradar::get_samples(position, metric, maps_handle).await
|
||||
}
|
||||
Metric::Precipitation => {
|
||||
forecast.precipitation = providers::buienradar::get_items(position, metric).await
|
||||
}
|
||||
Metric::UVI => {
|
||||
forecast.uvi =
|
||||
providers::buienradar::get_samples(position, metric, maps_handle).await
|
||||
}
|
||||
Metric::UVI => forecast.uvi = Some(()),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -22,7 +22,10 @@ use std::f64::consts::PI;
|
|||
/// [`Position::lon_as_i32`]).
|
||||
#[derive(Clone, Copy, Debug, Default)]
|
||||
pub(crate) struct Position {
|
||||
/// The latitude of the position.
|
||||
pub(crate) lat: f64,
|
||||
|
||||
/// The longitude of the position.
|
||||
pub(crate) lon: f64,
|
||||
}
|
||||
|
||||
|
|
|
@ -12,12 +12,16 @@ use csv::ReaderBuilder;
|
|||
use reqwest::Url;
|
||||
use rocket::serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::maps::MapsHandle;
|
||||
use crate::position::Position;
|
||||
use crate::Metric;
|
||||
|
||||
/// The base URL for the Buienradar API.
|
||||
const BUIENRADAR_BASE_URL: &str = "https://gpsgadget.buienradar.nl/data/raintext";
|
||||
|
||||
/// The Buienradar pollen/UV index map sample.
|
||||
pub(crate) type Sample = crate::maps::Sample;
|
||||
|
||||
/// A row in the precipitation text output.
|
||||
///
|
||||
/// This is an intermediate type used to represent rows of the output.
|
||||
|
@ -110,6 +114,62 @@ async fn get_precipitation(position: Position) -> Option<Vec<Item>> {
|
|||
rdr.deserialize().collect::<Result<_, _>>().ok()
|
||||
}
|
||||
|
||||
/// Retrieves the Buienradar forecasted pollen samples for the provided position.
|
||||
///
|
||||
/// Returns [`None`] if the sampling fails.
|
||||
///
|
||||
/// If the result is [`Some`] if will be cached for 1 hour for the given position.
|
||||
#[cached(
|
||||
time = 3_600,
|
||||
key = "Position",
|
||||
convert = r#"{ position }"#,
|
||||
option = true
|
||||
)]
|
||||
async fn get_pollen(position: Position, maps_handle: &MapsHandle) -> Option<Vec<Sample>> {
|
||||
maps_handle
|
||||
.lock()
|
||||
.expect("Maps handle mutex was poisoned")
|
||||
.pollen_sample(position)
|
||||
}
|
||||
|
||||
/// Retrieves the Buienradar forecasted UV index samples for the provided position.
|
||||
///
|
||||
/// Returns [`None`] if the sampling fails.
|
||||
///
|
||||
/// If the result is [`Some`] if will be cached for 1 day for the given position.
|
||||
#[cached(
|
||||
time = 86_400,
|
||||
key = "Position",
|
||||
convert = r#"{ position }"#,
|
||||
option = true
|
||||
)]
|
||||
async fn get_uvi(position: Position, maps_handle: &MapsHandle) -> Option<Vec<Sample>> {
|
||||
maps_handle
|
||||
.lock()
|
||||
.expect("Maps handle mutex was poisoned")
|
||||
.uvi_sample(position)
|
||||
}
|
||||
|
||||
/// Retrieves the Buienradar forecasted map samples for the provided position.
|
||||
///
|
||||
/// It only supports the following metric:
|
||||
/// * [`Metric::Pollen`]
|
||||
/// * [`Metric::UVI`]
|
||||
///
|
||||
/// Returns [`None`] if retrieval or deserialization fails, or if the metric is not supported by
|
||||
/// this provider.
|
||||
pub(crate) async fn get_samples(
|
||||
position: Position,
|
||||
metric: Metric,
|
||||
maps_handle: &MapsHandle,
|
||||
) -> Option<Vec<Sample>> {
|
||||
match metric {
|
||||
Metric::Pollen => get_pollen(position, maps_handle).await,
|
||||
Metric::UVI => get_uvi(position, maps_handle).await,
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Retrieves the Buienradar forecasted items for the provided position.
|
||||
///
|
||||
/// It only supports the following metric:
|
||||
|
@ -117,7 +177,7 @@ async fn get_precipitation(position: Position) -> Option<Vec<Item>> {
|
|||
///
|
||||
/// Returns [`None`] if retrieval or deserialization fails, or if the metric is not supported by
|
||||
/// this provider.
|
||||
pub(crate) async fn get(position: Position, metric: Metric) -> Option<Vec<Item>> {
|
||||
pub(crate) async fn get_items(position: Position, metric: Metric) -> Option<Vec<Item>> {
|
||||
match metric {
|
||||
Metric::Precipitation => get_precipitation(position).await,
|
||||
_ => None,
|
||||
|
|
Loading…
Reference in New Issue