bo4e_core/bo/
load_profile.rs1use serde::{Deserialize, Serialize};
6
7use crate::com::{LoadProfileValue, TimePeriod};
8use crate::enums::{Division, EnergyDirection, MeasurementType, Unit};
9use crate::traits::{Bo4eMeta, Bo4eObject};
10
11#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
32#[serde(rename_all = "camelCase")]
33pub struct LoadProfile {
34 #[serde(flatten)]
36 pub meta: Bo4eMeta,
37
38 #[serde(skip_serializing_if = "Option::is_none")]
40 pub load_profile_id: Option<String>,
41
42 #[serde(skip_serializing_if = "Option::is_none")]
44 pub division: Option<Division>,
45
46 #[serde(skip_serializing_if = "Option::is_none")]
48 pub energy_direction: Option<EnergyDirection>,
49
50 #[serde(skip_serializing_if = "Option::is_none")]
52 pub measurement_type: Option<MeasurementType>,
53
54 #[serde(skip_serializing_if = "Option::is_none")]
56 pub unit: Option<Unit>,
57
58 #[serde(skip_serializing_if = "Option::is_none")]
60 pub validity_period: Option<TimePeriod>,
61
62 #[serde(default, skip_serializing_if = "Vec::is_empty")]
64 pub values: Vec<LoadProfileValue>,
65
66 #[serde(skip_serializing_if = "Option::is_none")]
68 pub market_location_id: Option<String>,
69
70 #[serde(skip_serializing_if = "Option::is_none")]
72 pub metering_location_id: Option<String>,
73
74 #[serde(skip_serializing_if = "Option::is_none")]
76 pub obis_code: Option<String>,
77
78 #[serde(skip_serializing_if = "Option::is_none")]
80 pub interval_minutes: Option<i32>,
81
82 #[serde(skip_serializing_if = "Option::is_none")]
84 pub standard_profile_type: Option<String>,
85}
86
87impl Bo4eObject for LoadProfile {
88 fn type_name_german() -> &'static str {
89 "Lastgang"
90 }
91
92 fn type_name_english() -> &'static str {
93 "LoadProfile"
94 }
95
96 fn meta(&self) -> &Bo4eMeta {
97 &self.meta
98 }
99
100 fn meta_mut(&mut self) -> &mut Bo4eMeta {
101 &mut self.meta
102 }
103}
104
105#[cfg(test)]
106mod tests {
107 use super::*;
108
109 #[test]
110 fn test_load_profile_creation() {
111 let profile = LoadProfile {
112 load_profile_id: Some("LP001".to_string()),
113 division: Some(Division::Electricity),
114 energy_direction: Some(EnergyDirection::FeedOut),
115 ..Default::default()
116 };
117
118 assert_eq!(profile.load_profile_id, Some("LP001".to_string()));
119 }
120
121 #[test]
122 fn test_serialize() {
123 let profile = LoadProfile {
124 meta: Bo4eMeta::with_type("Lastgang"),
125 load_profile_id: Some("LP001".to_string()),
126 ..Default::default()
127 };
128
129 let json = serde_json::to_string(&profile).unwrap();
130 assert!(json.contains(r#""_typ":"Lastgang""#));
131 }
132
133 #[test]
134 fn test_roundtrip() {
135 let profile = LoadProfile {
136 meta: Bo4eMeta::with_type("Lastgang"),
137 load_profile_id: Some("LP001".to_string()),
138 division: Some(Division::Electricity),
139 energy_direction: Some(EnergyDirection::FeedOut),
140 unit: Some(Unit::Kilowatt),
141 interval_minutes: Some(15),
142 ..Default::default()
143 };
144
145 let json = serde_json::to_string(&profile).unwrap();
146 let parsed: LoadProfile = serde_json::from_str(&json).unwrap();
147 assert_eq!(profile, parsed);
148 }
149
150 #[test]
151 fn test_bo4e_object_impl() {
152 assert_eq!(LoadProfile::type_name_german(), "Lastgang");
153 assert_eq!(LoadProfile::type_name_english(), "LoadProfile");
154 }
155}