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",
|
"embedded-plots",
|
||||||
"linux-embedded-hal",
|
"linux-embedded-hal",
|
||||||
"profont",
|
"profont",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
"ssd1675",
|
"ssd1675",
|
||||||
"tinybmp",
|
"tinybmp",
|
||||||
]
|
]
|
||||||
|
@ -422,6 +424,12 @@ dependencies = [
|
||||||
"either",
|
"either",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "itoa"
|
||||||
|
version = "1.0.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6c8af84674fe1f223a982c933a0ee1086ac4d4052aa0fb8060c12c6ad838e754"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "jpeg-decoder"
|
name = "jpeg-decoder"
|
||||||
version = "0.1.22"
|
version = "0.1.22"
|
||||||
|
@ -635,6 +643,15 @@ dependencies = [
|
||||||
"miniz_oxide 0.3.7",
|
"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]]
|
[[package]]
|
||||||
name = "profont"
|
name = "profont"
|
||||||
version = "0.5.0"
|
version = "0.5.0"
|
||||||
|
@ -644,6 +661,15 @@ dependencies = [
|
||||||
"embedded-graphics",
|
"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]]
|
[[package]]
|
||||||
name = "rand"
|
name = "rand"
|
||||||
version = "0.6.5"
|
version = "0.6.5"
|
||||||
|
@ -839,6 +865,12 @@ dependencies = [
|
||||||
"semver 1.0.13",
|
"semver 1.0.13",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ryu"
|
||||||
|
version = "1.0.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "scoped_threadpool"
|
name = "scoped_threadpool"
|
||||||
version = "0.1.9"
|
version = "0.1.9"
|
||||||
|
@ -896,6 +928,37 @@ version = "0.7.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
|
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]]
|
[[package]]
|
||||||
name = "serial-core"
|
name = "serial-core"
|
||||||
version = "0.4.0"
|
version = "0.4.0"
|
||||||
|
@ -953,6 +1016,17 @@ version = "1.2.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
|
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]]
|
[[package]]
|
||||||
name = "sysfs_gpio"
|
name = "sysfs_gpio"
|
||||||
version = "0.6.1"
|
version = "0.6.1"
|
||||||
|
@ -992,6 +1066,12 @@ dependencies = [
|
||||||
"nom",
|
"nom",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-ident"
|
||||||
|
version = "1.0.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c4f5b37a154999a8f3f98cc23a628d850e154479cd94decf3414696e12e31aaf"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "vcell"
|
name = "vcell"
|
||||||
version = "0.1.3"
|
version = "0.1.3"
|
||||||
|
|
|
@ -15,6 +15,10 @@ profont = "0.5.0"
|
||||||
ssd1675 = { git = "https://github.com/Feliix42/ssd1675" }
|
ssd1675 = { git = "https://github.com/Feliix42/ssd1675" }
|
||||||
#ssd1675 = { path = "../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 }
|
linux-embedded-hal = { version = "0.3.2", optional = true }
|
||||||
embedded-graphics-simulator = { version = "0.3.0", 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