bo4e_core/bo/
time_series.rs1use serde::{Deserialize, Serialize};
6
7use crate::com::{TimePeriod, TimeSeriesValue};
8use crate::enums::{Division, MeasurementType, Unit};
9use crate::traits::{Bo4eMeta, Bo4eObject};
10
11#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
31#[cfg_attr(feature = "json-schema", derive(schemars::JsonSchema))]
32#[cfg_attr(feature = "json-schema", schemars(rename = "Zeitreihe"))]
33#[serde(rename_all = "camelCase")]
34pub struct TimeSeries {
35 #[serde(flatten)]
37 pub meta: Bo4eMeta,
38
39 #[serde(skip_serializing_if = "Option::is_none")]
41 #[cfg_attr(feature = "json-schema", schemars(rename = "zeitreiheId"))]
42 pub time_series_id: Option<String>,
43
44 #[serde(skip_serializing_if = "Option::is_none")]
46 #[cfg_attr(feature = "json-schema", schemars(rename = "sparte"))]
47 pub division: Option<Division>,
48
49 #[serde(skip_serializing_if = "Option::is_none")]
51 #[cfg_attr(feature = "json-schema", schemars(rename = "messart"))]
52 pub measurement_type: Option<MeasurementType>,
53
54 #[serde(skip_serializing_if = "Option::is_none")]
56 #[cfg_attr(feature = "json-schema", schemars(rename = "einheit"))]
57 pub unit: Option<Unit>,
58
59 #[serde(skip_serializing_if = "Option::is_none")]
61 #[cfg_attr(feature = "json-schema", schemars(rename = "gueltigkeitszeitraum"))]
62 pub validity_period: Option<TimePeriod>,
63
64 #[serde(default, skip_serializing_if = "Vec::is_empty")]
66 #[cfg_attr(feature = "json-schema", schemars(rename = "zeitreihenwerte"))]
67 pub values: Vec<TimeSeriesValue>,
68
69 #[serde(skip_serializing_if = "Option::is_none")]
71 #[cfg_attr(feature = "json-schema", schemars(rename = "marktlokationsId"))]
72 pub market_location_id: Option<String>,
73
74 #[serde(skip_serializing_if = "Option::is_none")]
76 #[cfg_attr(feature = "json-schema", schemars(rename = "messlokationsId"))]
77 pub metering_location_id: Option<String>,
78
79 #[serde(skip_serializing_if = "Option::is_none")]
81 #[cfg_attr(feature = "json-schema", schemars(rename = "beschreibung"))]
82 pub description: Option<String>,
83
84 #[serde(skip_serializing_if = "Option::is_none")]
86 #[cfg_attr(feature = "json-schema", schemars(rename = "obisKennzahl"))]
87 pub obis_code: Option<String>,
88
89 #[serde(skip_serializing_if = "Option::is_none")]
91 #[cfg_attr(feature = "json-schema", schemars(rename = "version"))]
92 pub series_version: Option<String>,
93
94 #[serde(skip_serializing_if = "Option::is_none")]
96 #[cfg_attr(feature = "json-schema", schemars(rename = "aufloesung"))]
97 pub resolution_minutes: Option<i32>,
98}
99
100impl Bo4eObject for TimeSeries {
101 fn type_name_german() -> &'static str {
102 "Zeitreihe"
103 }
104
105 fn type_name_english() -> &'static str {
106 "TimeSeries"
107 }
108
109 fn meta(&self) -> &Bo4eMeta {
110 &self.meta
111 }
112
113 fn meta_mut(&mut self) -> &mut Bo4eMeta {
114 &mut self.meta
115 }
116}
117
118#[cfg(test)]
119mod tests {
120 use super::*;
121
122 #[test]
123 fn test_time_series_creation() {
124 let series = TimeSeries {
125 time_series_id: Some("TS001".to_string()),
126 division: Some(Division::Electricity),
127 ..Default::default()
128 };
129
130 assert_eq!(series.time_series_id, Some("TS001".to_string()));
131 }
132
133 #[test]
134 fn test_serialize() {
135 let series = TimeSeries {
136 meta: Bo4eMeta::with_type("Zeitreihe"),
137 time_series_id: Some("TS001".to_string()),
138 ..Default::default()
139 };
140
141 let json = serde_json::to_string(&series).unwrap();
142 assert!(json.contains(r#""_typ":"Zeitreihe""#));
143 }
144
145 #[test]
146 fn test_roundtrip() {
147 let series = TimeSeries {
148 meta: Bo4eMeta::with_type("Zeitreihe"),
149 time_series_id: Some("TS001".to_string()),
150 division: Some(Division::Electricity),
151 unit: Some(Unit::KilowattHour),
152 resolution_minutes: Some(15),
153 description: Some("Test time series".to_string()),
154 ..Default::default()
155 };
156
157 let json = serde_json::to_string(&series).unwrap();
158 let parsed: TimeSeries = serde_json::from_str(&json).unwrap();
159 assert_eq!(series, parsed);
160 }
161
162 #[test]
163 fn test_bo4e_object_impl() {
164 assert_eq!(TimeSeries::type_name_german(), "Zeitreihe");
165 assert_eq!(TimeSeries::type_name_english(), "TimeSeries");
166 }
167}