bo4e_core/com/
load_curve_data.rs1use chrono::{DateTime, Utc};
4use serde::{Deserialize, Serialize};
5
6use crate::enums::Unit;
7use crate::traits::{Bo4eMeta, Bo4eObject};
8
9#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
29#[serde(rename_all = "camelCase")]
30pub struct LoadCurveData {
31 #[serde(flatten)]
33 pub meta: Bo4eMeta,
34
35 #[serde(skip_serializing_if = "Option::is_none")]
37 pub timestamp: Option<DateTime<Utc>>,
38
39 #[serde(skip_serializing_if = "Option::is_none")]
41 pub power_value: Option<f64>,
42
43 #[serde(skip_serializing_if = "Option::is_none")]
45 pub power_unit: Option<Unit>,
46
47 #[serde(skip_serializing_if = "Option::is_none")]
49 pub energy_value: Option<f64>,
50
51 #[serde(skip_serializing_if = "Option::is_none")]
53 pub energy_unit: Option<Unit>,
54
55 #[serde(skip_serializing_if = "Option::is_none")]
57 pub interval_minutes: Option<i32>,
58
59 #[serde(skip_serializing_if = "Option::is_none")]
61 pub obis_code: Option<String>,
62
63 #[serde(skip_serializing_if = "Option::is_none")]
65 pub measurement_location_id: Option<String>,
66}
67
68impl Bo4eObject for LoadCurveData {
69 fn type_name_german() -> &'static str {
70 "Lastkurvendaten"
71 }
72
73 fn type_name_english() -> &'static str {
74 "LoadCurveData"
75 }
76
77 fn meta(&self) -> &Bo4eMeta {
78 &self.meta
79 }
80
81 fn meta_mut(&mut self) -> &mut Bo4eMeta {
82 &mut self.meta
83 }
84}
85
86#[cfg(test)]
87mod tests {
88 use super::*;
89 use chrono::TimeZone;
90
91 #[test]
92 fn test_load_curve_data() {
93 let data = LoadCurveData {
94 timestamp: Some(Utc.with_ymd_and_hms(2024, 1, 15, 12, 15, 0).unwrap()),
95 power_value: Some(125.5),
96 power_unit: Some(Unit::Kilowatt),
97 interval_minutes: Some(15),
98 ..Default::default()
99 };
100
101 let json = serde_json::to_string(&data).unwrap();
102 assert!(json.contains("125.5"));
103 assert!(json.contains("15"));
104 }
105
106 #[test]
107 fn test_with_energy() {
108 let data = LoadCurveData {
109 timestamp: Some(Utc::now()),
110 power_value: Some(100.0),
111 power_unit: Some(Unit::Kilowatt),
112 energy_value: Some(25.0),
113 energy_unit: Some(Unit::KilowattHour),
114 interval_minutes: Some(15),
115 ..Default::default()
116 };
117
118 let json = serde_json::to_string(&data).unwrap();
119 assert!(json.contains("100"));
120 assert!(json.contains("25"));
121 }
122
123 #[test]
124 fn test_roundtrip() {
125 let data = LoadCurveData {
126 timestamp: Some(Utc::now()),
127 power_value: Some(999.99),
128 power_unit: Some(Unit::Kilowatt),
129 obis_code: Some("1-0:1.4.0".to_string()),
130 ..Default::default()
131 };
132
133 let json = serde_json::to_string(&data).unwrap();
134 let parsed: LoadCurveData = serde_json::from_str(&json).unwrap();
135 assert_eq!(data.power_value, parsed.power_value);
136 assert_eq!(data.obis_code, parsed.obis_code);
137 }
138
139 #[test]
140 fn test_bo4e_object_impl() {
141 assert_eq!(LoadCurveData::type_name_german(), "Lastkurvendaten");
142 assert_eq!(LoadCurveData::type_name_english(), "LoadCurveData");
143 }
144}