Define Data Structures for the OpenWeather API
This commit is contained in:
parent
985b42c20b
commit
a21a9c57cd
3 changed files with 261 additions and 0 deletions
80
Cargo.lock
generated
80
Cargo.lock
generated
|
@ -400,6 +400,8 @@ dependencies = [
|
|||
"embedded-plots",
|
||||
"linux-embedded-hal",
|
||||
"profont",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"ssd1675",
|
||||
"tinybmp",
|
||||
]
|
||||
|
@ -422,6 +424,12 @@ dependencies = [
|
|||
"either",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6c8af84674fe1f223a982c933a0ee1086ac4d4052aa0fb8060c12c6ad838e754"
|
||||
|
||||
[[package]]
|
||||
name = "jpeg-decoder"
|
||||
version = "0.1.22"
|
||||
|
@ -635,6 +643,15 @@ dependencies = [
|
|||
"miniz_oxide 0.3.7",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.43"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0a2ca2c61bc9f3d74d2886294ab7b9853abd9c1ad903a3ac7815c58989bb7bab"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "profont"
|
||||
version = "0.5.0"
|
||||
|
@ -644,6 +661,15 @@ dependencies = [
|
|||
"embedded-graphics",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.6.5"
|
||||
|
@ -839,6 +865,12 @@ dependencies = [
|
|||
"semver 1.0.13",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09"
|
||||
|
||||
[[package]]
|
||||
name = "scoped_threadpool"
|
||||
version = "0.1.9"
|
||||
|
@ -896,6 +928,37 @@ version = "0.7.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.142"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e590c437916fb6b221e1d00df6e3294f3fccd70ca7e92541c475d6ed6ef5fee2"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.142"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "34b5b8d809babe02f538c2cfec6f2c1ed10804c0e5a6a041a049a4f5588ccc2e"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.83"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "38dd04e3c8279e75b31ef29dbdceebfe5ad89f4d0937213c53f7d49d01b3d5a7"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"ryu",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serial-core"
|
||||
version = "0.4.0"
|
||||
|
@ -953,6 +1016,17 @@ version = "1.2.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.99"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "58dbef6ec655055e20b86b15a8cc6d439cca19b667537ac6a1369572d151ab13"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sysfs_gpio"
|
||||
version = "0.6.1"
|
||||
|
@ -992,6 +1066,12 @@ dependencies = [
|
|||
"nom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c4f5b37a154999a8f3f98cc23a628d850e154479cd94decf3414696e12e31aaf"
|
||||
|
||||
[[package]]
|
||||
name = "vcell"
|
||||
version = "0.1.3"
|
||||
|
|
|
@ -15,6 +15,10 @@ profont = "0.5.0"
|
|||
ssd1675 = { git = "https://github.com/Feliix42/ssd1675" }
|
||||
#ssd1675 = { path = "../ssd1675" }
|
||||
|
||||
# for parsing the weather api data
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0"
|
||||
|
||||
linux-embedded-hal = { version = "0.3.2", optional = true }
|
||||
embedded-graphics-simulator = { version = "0.3.0", optional = true }
|
||||
|
||||
|
|
|
@ -0,0 +1,177 @@
|
|||
//! Rust data types representing a subset of the weather data returned by the OpenWeather [One
|
||||
//! Call](https://openweathermap.org/api/one-call-3) API.
|
||||
//!
|
||||
//! The response fields are described in detail
|
||||
//! [here](https://openweathermap.org/api/one-call-3#parameter).
|
||||
#![allow(dead_code)]
|
||||
|
||||
use serde::Deserialize;
|
||||
|
||||
|
||||
/// Response from the OpenWeather API with both current and forecast data for a given location.
|
||||
#[derive(Deserialize)]
|
||||
pub struct WeatherData {
|
||||
/// Latitude
|
||||
lat: f32,
|
||||
/// Longitude
|
||||
lon: f32,
|
||||
/// Name of the current timezone
|
||||
timezone: String,
|
||||
/// Timezone offset from UTC
|
||||
timezone_offset: i32,
|
||||
/// Current weather situation
|
||||
current: CurrentWeather,
|
||||
/// Minutely wheather information (optional; unused and excluded by API call
|
||||
#[serde(skip_deserializing)]
|
||||
minutely: Vec<()>,
|
||||
/// Weather Information for the coming hours
|
||||
hourly: Vec<HourlyWeather>,
|
||||
/// Weather information for the next days _(unused at the moment)_
|
||||
#[serde(skip_deserializing)]
|
||||
daily: Vec<()>,
|
||||
/// Currently active wheather alerts
|
||||
#[serde(default)]
|
||||
alerts: Vec<WeatherAlert>
|
||||
}
|
||||
|
||||
/// Current weather data.
|
||||
#[derive(Deserialize)]
|
||||
pub struct CurrentWeather {
|
||||
#[serde(flatten)]
|
||||
data: CommonWeatherInfo,
|
||||
/// Sunrise time (Unix Timestamp, UTC)
|
||||
sunrise: u64,
|
||||
/// Sunset time (Unix Timestamp, UTC)
|
||||
sunset: u64,
|
||||
}
|
||||
|
||||
/// Weather Forecast for a specific hour in the future.
|
||||
#[derive(Deserialize)]
|
||||
pub struct HourlyWeather {
|
||||
#[serde(flatten)]
|
||||
data: CommonWeatherInfo,
|
||||
/// Probability of precipitation (values range from 0 to 1).
|
||||
pop: f32
|
||||
}
|
||||
|
||||
/// Common weather information shared among different forecast types.
|
||||
///
|
||||
/// This struct is not instantiated by the API but merely introduced by the `Deserializer`.
|
||||
#[derive(Deserialize)]
|
||||
pub struct CommonWeatherInfo {
|
||||
/// Current time (Unix Timestamp, UTC)
|
||||
dt: u64,
|
||||
/// Current temperature
|
||||
temp: f32,
|
||||
/// Temperature according to human perception
|
||||
feels_like: f32,
|
||||
/// Atmospheric Pressure at sea level (hPa)
|
||||
pressure: u32,
|
||||
/// Air Humidity in %
|
||||
humidity: u8,
|
||||
/// Dew Point (temperature below which water droplets begin to form)
|
||||
dew_point: f32,
|
||||
/// Cloudiness in %
|
||||
clouds: u8,
|
||||
/// Current UV Index
|
||||
uvi: f32,
|
||||
/// Average Visibility in metres (max: 10.000m)
|
||||
visibility: u16,
|
||||
/// Wind Speed
|
||||
wind_speed: f32,
|
||||
/// Wind Gust (optional)
|
||||
wind_gust: f32,
|
||||
/// Wind direction in degrees
|
||||
wind_deg: u16,
|
||||
/// Rain
|
||||
rain: Option<Precipitation>,
|
||||
/// Snow
|
||||
snow: Option<Precipitation>,
|
||||
/// Weather
|
||||
weather: Vec<WeatherDetails>,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct WeatherAlert {
|
||||
/// Name of the alert source.
|
||||
sender_name: String,
|
||||
/// Name of the Event
|
||||
event: String,
|
||||
/// Date and time of the start of the alert (Unix Timestamp, UTC)
|
||||
start: u64,
|
||||
/// Date and time of the end of the alert (Unix Timestamp, UTC)
|
||||
end: u64,
|
||||
/// Description of the alert (localized).
|
||||
description: String,
|
||||
/// Type(s) of severe weather.
|
||||
tags: Vec<String>,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct Precipitation {
|
||||
/// Precipitation volume in the last hour in mm
|
||||
#[serde(rename = "1h")]
|
||||
hour: u16,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct WeatherDetails {
|
||||
#[serde(rename = "id")]
|
||||
condition: WeatherCondition,
|
||||
main: String,
|
||||
description: String,
|
||||
icon: String
|
||||
}
|
||||
|
||||
/// Weather Condition
|
||||
///
|
||||
/// This information is deserialized from a unsigned int returned by the Open Weather API according
|
||||
/// to [this
|
||||
/// specification](https://openweathermap.org/weather-conditions#Weather-Condition-Codes-2).
|
||||
/// It ignores the fine details within weather conditions (e.g. heavy thunderstorm and light
|
||||
/// thunderstorm both map to `Thunderstorm`).
|
||||
#[derive(Deserialize)] //Debug)]
|
||||
#[serde(from = "u16")]
|
||||
pub enum WeatherCondition {
|
||||
Thunderstorm,
|
||||
Drizzle,
|
||||
Rain,
|
||||
Snow,
|
||||
Mist,
|
||||
Smoke,
|
||||
Haze,
|
||||
SandDust,
|
||||
Fog,
|
||||
Sand,
|
||||
Dust,
|
||||
Ash,
|
||||
Squall,
|
||||
Tornado,
|
||||
Clear,
|
||||
Clouds,
|
||||
}
|
||||
|
||||
impl From<u16> for WeatherCondition {
|
||||
fn from(value: u16) -> Self {
|
||||
match value {
|
||||
200 ..= 299 => Self::Thunderstorm,
|
||||
300 ..= 399 => Self::Drizzle,
|
||||
500 ..= 599 => Self::Rain,
|
||||
600 ..= 699 => Self::Snow,
|
||||
701 => Self::Mist,
|
||||
711 => Self::Smoke,
|
||||
721 => Self::Haze,
|
||||
731 => Self::SandDust,
|
||||
741 => Self::Fog,
|
||||
751 => Self::Sand,
|
||||
761 => Self::Dust,
|
||||
762 => Self::Ash,
|
||||
771 => Self::Squall,
|
||||
781 => Self::Tornado,
|
||||
800 => Self::Clear,
|
||||
801..=804 => Self::Clouds,
|
||||
// NOTE(feliix42): There's no `Error` mapping or something like that.
|
||||
_ => Self::Clear,
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue