bo4e_core/bo/
controllable_resource.rs1use serde::{Deserialize, Serialize};
6
7use crate::com::Address;
8use crate::enums::{ControllableResourceType, Division, EnergyDirection};
9use crate::traits::{Bo4eMeta, Bo4eObject};
10
11#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
32#[serde(rename_all = "camelCase")]
33pub struct ControllableResource {
34 #[serde(flatten)]
36 pub meta: Bo4eMeta,
37
38 #[serde(skip_serializing_if = "Option::is_none")]
40 pub controllable_resource_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 resource_type: Option<ControllableResourceType>,
49
50 #[serde(skip_serializing_if = "Option::is_none")]
52 pub energy_direction: Option<EnergyDirection>,
53
54 #[serde(skip_serializing_if = "Option::is_none")]
56 pub address: Option<Address>,
57
58 #[serde(skip_serializing_if = "Option::is_none")]
60 pub description: Option<String>,
61
62 #[serde(skip_serializing_if = "Option::is_none")]
64 pub controllable_power: Option<f64>,
65
66 #[serde(skip_serializing_if = "Option::is_none")]
68 pub min_activation_time: Option<i32>,
69
70 #[serde(skip_serializing_if = "Option::is_none")]
72 pub max_activation_time: Option<i32>,
73
74 #[serde(skip_serializing_if = "Option::is_none")]
76 pub ramp_up_time: Option<i32>,
77
78 #[serde(skip_serializing_if = "Option::is_none")]
80 pub ramp_down_time: Option<i32>,
81
82 #[serde(skip_serializing_if = "Option::is_none")]
84 pub technical_resource_id: Option<String>,
85
86 #[serde(skip_serializing_if = "Option::is_none")]
88 pub market_location_id: Option<String>,
89
90 #[serde(skip_serializing_if = "Option::is_none")]
92 pub is_active: Option<bool>,
93}
94
95impl Bo4eObject for ControllableResource {
96 fn type_name_german() -> &'static str {
97 "SteuerbareRessource"
98 }
99
100 fn type_name_english() -> &'static str {
101 "ControllableResource"
102 }
103
104 fn meta(&self) -> &Bo4eMeta {
105 &self.meta
106 }
107
108 fn meta_mut(&mut self) -> &mut Bo4eMeta {
109 &mut self.meta
110 }
111}
112
113#[cfg(test)]
114mod tests {
115 use super::*;
116
117 #[test]
118 fn test_controllable_resource_creation() {
119 let resource = ControllableResource {
120 controllable_resource_id: Some("SR001".to_string()),
121 division: Some(Division::Electricity),
122 resource_type: Some(ControllableResourceType::OnOff),
123 ..Default::default()
124 };
125
126 assert_eq!(resource.controllable_resource_id, Some("SR001".to_string()));
127 }
128
129 #[test]
130 fn test_serialize() {
131 let resource = ControllableResource {
132 meta: Bo4eMeta::with_type("SteuerbareRessource"),
133 controllable_resource_id: Some("SR001".to_string()),
134 ..Default::default()
135 };
136
137 let json = serde_json::to_string(&resource).unwrap();
138 assert!(json.contains(r#""_typ":"SteuerbareRessource""#));
139 }
140
141 #[test]
142 fn test_roundtrip() {
143 let resource = ControllableResource {
144 meta: Bo4eMeta::with_type("SteuerbareRessource"),
145 controllable_resource_id: Some("SR001".to_string()),
146 division: Some(Division::Electricity),
147 resource_type: Some(ControllableResourceType::OnOff),
148 controllable_power: Some(50.0),
149 min_activation_time: Some(15),
150 is_active: Some(true),
151 ..Default::default()
152 };
153
154 let json = serde_json::to_string(&resource).unwrap();
155 let parsed: ControllableResource = serde_json::from_str(&json).unwrap();
156 assert_eq!(resource, parsed);
157 }
158
159 #[test]
160 fn test_bo4e_object_impl() {
161 assert_eq!(
162 ControllableResource::type_name_german(),
163 "SteuerbareRessource"
164 );
165 assert_eq!(
166 ControllableResource::type_name_english(),
167 "ControllableResource"
168 );
169 }
170}