Fix time deserialization for iso8601 dates with missing timezone flag
This commit is contained in:
parent
1fd48a9e30
commit
b72e0d956e
73
src/api.rs
73
src/api.rs
@ -1,7 +1,7 @@
|
|||||||
use std::{io, time::{Duration, Instant}};
|
use std::{io, time::{Duration, Instant}};
|
||||||
|
|
||||||
use chrono::{DateTime, NaiveDateTime, Utc};
|
use chrono::NaiveDateTime;
|
||||||
use serde::{de::DeserializeOwned, Deserialize, Serialize};
|
use serde::{de::DeserializeOwned, Deserialize, Deserializer, Serialize};
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
use tracing::{debug, info, instrument};
|
use tracing::{debug, info, instrument};
|
||||||
|
|
||||||
@ -15,8 +15,13 @@ pub struct Context {
|
|||||||
const API_BASE: &'static str = "https://api.easee.com/api/";
|
const API_BASE: &'static str = "https://api.easee.com/api/";
|
||||||
const REFRESH_TOKEN_DELAY: Duration = Duration::from_secs(600);
|
const REFRESH_TOKEN_DELAY: Duration = Duration::from_secs(600);
|
||||||
|
|
||||||
fn parse_iso8601(s: &str) -> Result<NaiveDateTime, ApiError> {
|
|
||||||
Ok(NaiveDateTime::parse_from_str(s, "%Y-%m-%dT%H:%M:%S%.f")?)
|
|
||||||
|
fn parse_iso8601<'d, D: Deserializer<'d>>(de: D) -> Result<NaiveDateTime, D::Error> {
|
||||||
|
use serde::de::Error;
|
||||||
|
let s = <&str as Deserialize>::deserialize(de)?;
|
||||||
|
Ok(NaiveDateTime::parse_from_str(s, "%Y-%m-%dT%H:%M:%S%.f")
|
||||||
|
.map_err(D::Error::custom)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Debug)]
|
#[derive(Deserialize, Debug)]
|
||||||
@ -26,8 +31,11 @@ pub struct Charger {
|
|||||||
pub name: String,
|
pub name: String,
|
||||||
pub product_code: u32,
|
pub product_code: u32,
|
||||||
pub color: Option<i32>,
|
pub color: Option<i32>,
|
||||||
pub created_on: DateTime<Utc>,
|
#[serde(deserialize_with="parse_iso8601")]
|
||||||
pub updated_on: DateTime<Utc>,
|
pub created_on: NaiveDateTime,
|
||||||
|
|
||||||
|
#[serde(deserialize_with="parse_iso8601")]
|
||||||
|
pub updated_on: NaiveDateTime,
|
||||||
pub level_of_access: u32,
|
pub level_of_access: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -42,40 +50,42 @@ pub struct ChargerState {
|
|||||||
pub energy_per_hour: f64,
|
pub energy_per_hour: f64,
|
||||||
|
|
||||||
#[serde(rename="wiFiRSSI")]
|
#[serde(rename="wiFiRSSI")]
|
||||||
pub wifi_rssi: u32,
|
pub wifi_rssi: Option<i32>,
|
||||||
|
|
||||||
#[serde(rename="cellRSSI")]
|
#[serde(rename="cellRSSI")]
|
||||||
pub cell_rssi: u32,
|
pub cell_rssi: Option<i32>,
|
||||||
|
|
||||||
#[serde(rename="localRSSI")]
|
#[serde(rename="localRSSI")]
|
||||||
pub local_rssi: u32,
|
pub local_rssi: Option<i32>,
|
||||||
pub output_phase: u32,
|
pub output_phase: u32,
|
||||||
pub dynamic_circuit_current_p1: u32,
|
pub dynamic_circuit_current_p1: u32,
|
||||||
pub dynamic_circuit_current_p2: u32,
|
pub dynamic_circuit_current_p2: u32,
|
||||||
pub dynamic_circuit_current_p3: u32,
|
pub dynamic_circuit_current_p3: u32,
|
||||||
pub latest_pulse: DateTime<Utc>,
|
|
||||||
|
//#[serde(deserialize_with="parse_iso8601")]
|
||||||
|
//pub latest_pulse: NaiveDateTime,
|
||||||
pub charger_firmware: u32,
|
pub charger_firmware: u32,
|
||||||
pub voltage: f64,
|
pub voltage: f64,
|
||||||
|
|
||||||
#[serde(rename="chargerRAT")]
|
#[serde(rename="chargerRAT")]
|
||||||
pub charger_rat: u32,
|
pub charger_rat: u32,
|
||||||
pub lock_cable_permanently: bool,
|
pub lock_cable_permanently: bool,
|
||||||
pub in_current_t2: f64,
|
pub in_current_t2: Option<f64>,
|
||||||
pub in_current_t3: f64,
|
pub in_current_t3: Option<f64>,
|
||||||
pub in_current_t4: f64,
|
pub in_current_t4: Option<f64>,
|
||||||
pub in_current_t5: f64,
|
pub in_current_t5: Option<f64>,
|
||||||
pub output_current: f64,
|
pub output_current: f64,
|
||||||
pub is_online: bool,
|
pub is_online: bool,
|
||||||
pub in_voltage_t1_t2: f64,
|
pub in_voltage_t1_t2: Option<f64>,
|
||||||
pub in_voltage_t1_t3: f64,
|
pub in_voltage_t1_t3: Option<f64>,
|
||||||
pub in_voltage_t1_t4: f64,
|
pub in_voltage_t1_t4: Option<f64>,
|
||||||
pub in_voltage_t1_t5: f64,
|
pub in_voltage_t1_t5: Option<f64>,
|
||||||
pub in_voltage_t2_t3: f64,
|
pub in_voltage_t2_t3: Option<f64>,
|
||||||
pub in_voltage_t2_t4: f64,
|
pub in_voltage_t2_t4: Option<f64>,
|
||||||
pub in_voltage_t2_t5: f64,
|
pub in_voltage_t2_t5: Option<f64>,
|
||||||
pub in_voltage_t3_t4: f64,
|
pub in_voltage_t3_t4: Option<f64>,
|
||||||
pub in_voltage_t3_t5: f64,
|
pub in_voltage_t3_t5: Option<f64>,
|
||||||
pub in_voltage_t4_t5: f64,
|
pub in_voltage_t4_t5: Option<f64>,
|
||||||
pub led_mode: u32,
|
pub led_mode: u32,
|
||||||
pub cable_rating: f64,
|
pub cable_rating: f64,
|
||||||
pub dynamic_charger_current: f64,
|
pub dynamic_charger_current: f64,
|
||||||
@ -87,18 +97,18 @@ pub struct ChargerState {
|
|||||||
pub circuit_total_phase_conductor_current_l3: f64,
|
pub circuit_total_phase_conductor_current_l3: f64,
|
||||||
pub reason_for_no_current: u32,
|
pub reason_for_no_current: u32,
|
||||||
|
|
||||||
#[serde(rename="WifiAPEnabled")]
|
#[serde(rename="wiFiAPEnabled")]
|
||||||
pub wifi_ap_enabled: bool,
|
pub wifi_ap_enabled: bool,
|
||||||
pub lifetime_energy: f64,
|
pub lifetime_energy: f64,
|
||||||
pub offline_max_circuit_current_p1: u32,
|
pub offline_max_circuit_current_p1: u32,
|
||||||
pub offline_max_circuit_current_p2: u32,
|
pub offline_max_circuit_current_p2: u32,
|
||||||
pub offline_max_circuit_current_p3: u32,
|
pub offline_max_circuit_current_p3: u32,
|
||||||
pub error_code: u32,
|
pub error_code: u32,
|
||||||
pub fault_error_code: u32,
|
pub fatal_error_code: u32,
|
||||||
pub eq_available_current_p1: f64,
|
pub eq_available_current_p1: Option<f64>,
|
||||||
pub eq_available_current_p2: f64,
|
pub eq_available_current_p2: Option<f64>,
|
||||||
pub eq_available_current_p3: f64,
|
pub eq_available_current_p3: Option<f64>,
|
||||||
pub derated_current: f64,
|
pub derated_current: Option<f64>,
|
||||||
pub derating_active: bool,
|
pub derating_active: bool,
|
||||||
pub connected_to_cloud: bool,
|
pub connected_to_cloud: bool,
|
||||||
|
|
||||||
@ -142,6 +152,9 @@ pub enum ApiError {
|
|||||||
#[error("unexpected data: {1} when processing {0}")]
|
#[error("unexpected data: {1} when processing {0}")]
|
||||||
UnexpectedData(serde_json::Value, serde_json::Error),
|
UnexpectedData(serde_json::Value, serde_json::Error),
|
||||||
|
|
||||||
|
#[error("could not deserialize time string")]
|
||||||
|
DeserializeFail,
|
||||||
|
|
||||||
#[error("format error: {0}")]
|
#[error("format error: {0}")]
|
||||||
FormatError(#[from] chrono::ParseError)
|
FormatError(#[from] chrono::ParseError)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user