Skip to main content

cimstructs/
ExcIEEEAC8B.rs

1/// IEEE 421.5-2005 type AC8B model. This model represents a PID voltage regulator with either a brushless exciter or DC exciter. The AVR in this model consists of PID control, with separate constants for the proportional (KPR), integral (KIR), and derivative (KDR) gains. The representation of the brushless exciter (TE, KE, SE, KC, KD) is similar to the model type AC2A. The type AC8B model can be used to represent static voltage regulators applied to brushless excitation systems. Digitally based voltage regulators feeding DC rotating main exciters can be represented with the AC type AC8B model with the parameters KC and KD set to 0. For thyristor power stages fed from the generator terminals, the limits VRMAX and VRMIN should be a function of terminal voltage: VT x VRMAX and VT x VRMIN. Reference: IEEE 421.5-2005, 6.8.
2#[derive(Debug, Default, Clone, serde::Serialize, serde::Deserialize)]
3pub struct ExcIEEEAC8B {
4    #[serde(flatten)]
5    pub base: super::ExcitationSystemDynamics,
6    /// Voltage regulator gain (KA) (> 0). Typical value = 1.
7    #[serde(skip_serializing_if = "Option::is_none")]
8    pub ka: Option<f64>,
9    /// Rectifier loading factor proportional to commutating reactance (KC) (>= 0). Typical value = 0,55.
10    #[serde(skip_serializing_if = "Option::is_none")]
11    pub kc: Option<f64>,
12    /// Demagnetizing factor, a function of exciter alternator reactances (KD) (>= 0). Typical value = 1,1.
13    #[serde(skip_serializing_if = "Option::is_none")]
14    pub kd: Option<f64>,
15    /// Voltage regulator derivative gain (KDR) (>= 0). Typical value = 10.
16    #[serde(skip_serializing_if = "Option::is_none")]
17    pub kdr: Option<f64>,
18    /// Exciter constant related to self-excited field (KE). Typical value = 1.
19    #[serde(skip_serializing_if = "Option::is_none")]
20    pub ke: Option<f64>,
21    /// Voltage regulator integral gain (KIR) (>= 0). Typical value = 5.
22    #[serde(skip_serializing_if = "Option::is_none")]
23    pub kir: Option<f64>,
24    /// Voltage regulator proportional gain (KPR) (> 0 if ExcIEEEAC8B.kir = 0). Typical value = 80.
25    #[serde(skip_serializing_if = "Option::is_none")]
26    pub kpr: Option<f64>,
27    /// Exciter saturation function value at the corresponding exciter voltage, VE1, back of commutating reactance (SE[VE1]) (>= 0). Typical value = 0,3.
28    #[serde(skip_serializing_if = "Option::is_none")]
29    pub seve1: Option<f64>,
30    /// Exciter saturation function value at the corresponding exciter voltage, VE2, back of commutating reactance (SE[VE2]) (>= 0). Typical value = 3.
31    #[serde(skip_serializing_if = "Option::is_none")]
32    pub seve2: Option<f64>,
33    /// Voltage regulator time constant (TA) (>= 0). Typical value = 0.
34    #[serde(skip_serializing_if = "Option::is_none")]
35    pub ta: Option<f64>,
36    /// Lag time constant (TDR) (> 0). Typical value = 0,1.
37    #[serde(skip_serializing_if = "Option::is_none")]
38    pub tdr: Option<f64>,
39    /// Exciter time constant, integration rate associated with exciter control (TE) (> 0). Typical value = 1,2.
40    #[serde(skip_serializing_if = "Option::is_none")]
41    pub te: Option<f64>,
42    /// Exciter alternator output voltages back of commutating reactance at which saturation is defined (VE1) (> 0). Typical value = 6,5.
43    #[serde(skip_serializing_if = "Option::is_none")]
44    pub ve1: Option<f64>,
45    /// Exciter alternator output voltages back of commutating reactance at which saturation is defined (VE2) (> 0). Typical value = 9.
46    #[serde(skip_serializing_if = "Option::is_none")]
47    pub ve2: Option<f64>,
48    /// Minimum exciter voltage output (VEMIN) (<= 0). Typical value = 0.
49    #[serde(skip_serializing_if = "Option::is_none")]
50    pub vemin: Option<f64>,
51    /// Exciter field current limit reference (VFEMAX). Typical value = 6.
52    #[serde(skip_serializing_if = "Option::is_none")]
53    pub vfemax: Option<f64>,
54    /// Maximum voltage regulator output (VRMAX) (> 0). Typical value = 35.
55    #[serde(skip_serializing_if = "Option::is_none")]
56    pub vrmax: Option<f64>,
57    /// Minimum voltage regulator output (VRMIN) (<= 0). Typical value = 0.
58    #[serde(skip_serializing_if = "Option::is_none")]
59    pub vrmin: Option<f64>,
60}
61impl crate::base::CimElement for ExcIEEEAC8B {
62    fn mrid(&self) -> &str { &self.base.base.base.id }
63    fn type_name(&self) -> &'static str { "ExcIEEEAC8B" }
64    fn as_any(&self) -> &dyn std::any::Any { self }
65    fn to_json_value(&self) -> serde_json::Value {
66        serde_json::to_value(self).unwrap_or(serde_json::Value::Null)
67    }
68    fn to_block(&self) -> crate::base::RdfBlock {
69        let mut block = self.base.to_block();
70        block.type_name = "ExcIEEEAC8B".to_string();
71        if let Some(v) = self.ka {
72            block.fields.insert("ExcIEEEAC8B.ka".into(), crate::base::FieldValue::Text(v.to_string()));
73        }
74        if let Some(v) = self.kc {
75            block.fields.insert("ExcIEEEAC8B.kc".into(), crate::base::FieldValue::Text(v.to_string()));
76        }
77        if let Some(v) = self.kd {
78            block.fields.insert("ExcIEEEAC8B.kd".into(), crate::base::FieldValue::Text(v.to_string()));
79        }
80        if let Some(v) = self.kdr {
81            block.fields.insert("ExcIEEEAC8B.kdr".into(), crate::base::FieldValue::Text(v.to_string()));
82        }
83        if let Some(v) = self.ke {
84            block.fields.insert("ExcIEEEAC8B.ke".into(), crate::base::FieldValue::Text(v.to_string()));
85        }
86        if let Some(v) = self.kir {
87            block.fields.insert("ExcIEEEAC8B.kir".into(), crate::base::FieldValue::Text(v.to_string()));
88        }
89        if let Some(v) = self.kpr {
90            block.fields.insert("ExcIEEEAC8B.kpr".into(), crate::base::FieldValue::Text(v.to_string()));
91        }
92        if let Some(v) = self.seve1 {
93            block.fields.insert("ExcIEEEAC8B.seve1".into(), crate::base::FieldValue::Text(v.to_string()));
94        }
95        if let Some(v) = self.seve2 {
96            block.fields.insert("ExcIEEEAC8B.seve2".into(), crate::base::FieldValue::Text(v.to_string()));
97        }
98        if let Some(v) = self.ta {
99            block.fields.insert("ExcIEEEAC8B.ta".into(), crate::base::FieldValue::Text(v.to_string()));
100        }
101        if let Some(v) = self.tdr {
102            block.fields.insert("ExcIEEEAC8B.tdr".into(), crate::base::FieldValue::Text(v.to_string()));
103        }
104        if let Some(v) = self.te {
105            block.fields.insert("ExcIEEEAC8B.te".into(), crate::base::FieldValue::Text(v.to_string()));
106        }
107        if let Some(v) = self.ve1 {
108            block.fields.insert("ExcIEEEAC8B.ve1".into(), crate::base::FieldValue::Text(v.to_string()));
109        }
110        if let Some(v) = self.ve2 {
111            block.fields.insert("ExcIEEEAC8B.ve2".into(), crate::base::FieldValue::Text(v.to_string()));
112        }
113        if let Some(v) = self.vemin {
114            block.fields.insert("ExcIEEEAC8B.vemin".into(), crate::base::FieldValue::Text(v.to_string()));
115        }
116        if let Some(v) = self.vfemax {
117            block.fields.insert("ExcIEEEAC8B.vfemax".into(), crate::base::FieldValue::Text(v.to_string()));
118        }
119        if let Some(v) = self.vrmax {
120            block.fields.insert("ExcIEEEAC8B.vrmax".into(), crate::base::FieldValue::Text(v.to_string()));
121        }
122        if let Some(v) = self.vrmin {
123            block.fields.insert("ExcIEEEAC8B.vrmin".into(), crate::base::FieldValue::Text(v.to_string()));
124        }
125        block
126    }
127}
128
129impl ExcIEEEAC8B {
130    pub fn from_block(b: &crate::base::RdfBlock) -> Self {
131        let mut obj = Self::default();
132        obj.base.base.base.id.clone_from(&b.mrid);
133        for (key, val) in &b.fields {
134            match key.as_str() {
135                "ExcIEEEAC8B.ka" => {
136                    match val {
137                        crate::base::FieldValue::Text(sv) => { if let Ok(v) = sv.trim().parse() { obj.ka = Some(v); } }
138                        crate::base::FieldValue::TextList(svs) => {
139                            if let Some(sv) = svs.last() { if let Ok(v) = sv.trim().parse() { obj.ka = Some(v); } }
140                        }
141                        _ => {}
142                    }
143                }
144                "ExcIEEEAC8B.kc" => {
145                    match val {
146                        crate::base::FieldValue::Text(sv) => { if let Ok(v) = sv.trim().parse() { obj.kc = Some(v); } }
147                        crate::base::FieldValue::TextList(svs) => {
148                            if let Some(sv) = svs.last() { if let Ok(v) = sv.trim().parse() { obj.kc = Some(v); } }
149                        }
150                        _ => {}
151                    }
152                }
153                "ExcIEEEAC8B.kd" => {
154                    match val {
155                        crate::base::FieldValue::Text(sv) => { if let Ok(v) = sv.trim().parse() { obj.kd = Some(v); } }
156                        crate::base::FieldValue::TextList(svs) => {
157                            if let Some(sv) = svs.last() { if let Ok(v) = sv.trim().parse() { obj.kd = Some(v); } }
158                        }
159                        _ => {}
160                    }
161                }
162                "ExcIEEEAC8B.kdr" => {
163                    match val {
164                        crate::base::FieldValue::Text(sv) => { if let Ok(v) = sv.trim().parse() { obj.kdr = Some(v); } }
165                        crate::base::FieldValue::TextList(svs) => {
166                            if let Some(sv) = svs.last() { if let Ok(v) = sv.trim().parse() { obj.kdr = Some(v); } }
167                        }
168                        _ => {}
169                    }
170                }
171                "ExcIEEEAC8B.ke" => {
172                    match val {
173                        crate::base::FieldValue::Text(sv) => { if let Ok(v) = sv.trim().parse() { obj.ke = Some(v); } }
174                        crate::base::FieldValue::TextList(svs) => {
175                            if let Some(sv) = svs.last() { if let Ok(v) = sv.trim().parse() { obj.ke = Some(v); } }
176                        }
177                        _ => {}
178                    }
179                }
180                "ExcIEEEAC8B.kir" => {
181                    match val {
182                        crate::base::FieldValue::Text(sv) => { if let Ok(v) = sv.trim().parse() { obj.kir = Some(v); } }
183                        crate::base::FieldValue::TextList(svs) => {
184                            if let Some(sv) = svs.last() { if let Ok(v) = sv.trim().parse() { obj.kir = Some(v); } }
185                        }
186                        _ => {}
187                    }
188                }
189                "ExcIEEEAC8B.kpr" => {
190                    match val {
191                        crate::base::FieldValue::Text(sv) => { if let Ok(v) = sv.trim().parse() { obj.kpr = Some(v); } }
192                        crate::base::FieldValue::TextList(svs) => {
193                            if let Some(sv) = svs.last() { if let Ok(v) = sv.trim().parse() { obj.kpr = Some(v); } }
194                        }
195                        _ => {}
196                    }
197                }
198                "ExcIEEEAC8B.seve1" => {
199                    match val {
200                        crate::base::FieldValue::Text(sv) => { if let Ok(v) = sv.trim().parse() { obj.seve1 = Some(v); } }
201                        crate::base::FieldValue::TextList(svs) => {
202                            if let Some(sv) = svs.last() { if let Ok(v) = sv.trim().parse() { obj.seve1 = Some(v); } }
203                        }
204                        _ => {}
205                    }
206                }
207                "ExcIEEEAC8B.seve2" => {
208                    match val {
209                        crate::base::FieldValue::Text(sv) => { if let Ok(v) = sv.trim().parse() { obj.seve2 = Some(v); } }
210                        crate::base::FieldValue::TextList(svs) => {
211                            if let Some(sv) = svs.last() { if let Ok(v) = sv.trim().parse() { obj.seve2 = Some(v); } }
212                        }
213                        _ => {}
214                    }
215                }
216                "ExcIEEEAC8B.ta" => {
217                    match val {
218                        crate::base::FieldValue::Text(sv) => { if let Ok(v) = sv.trim().parse() { obj.ta = Some(v); } }
219                        crate::base::FieldValue::TextList(svs) => {
220                            if let Some(sv) = svs.last() { if let Ok(v) = sv.trim().parse() { obj.ta = Some(v); } }
221                        }
222                        _ => {}
223                    }
224                }
225                "ExcIEEEAC8B.tdr" => {
226                    match val {
227                        crate::base::FieldValue::Text(sv) => { if let Ok(v) = sv.trim().parse() { obj.tdr = Some(v); } }
228                        crate::base::FieldValue::TextList(svs) => {
229                            if let Some(sv) = svs.last() { if let Ok(v) = sv.trim().parse() { obj.tdr = Some(v); } }
230                        }
231                        _ => {}
232                    }
233                }
234                "ExcIEEEAC8B.te" => {
235                    match val {
236                        crate::base::FieldValue::Text(sv) => { if let Ok(v) = sv.trim().parse() { obj.te = Some(v); } }
237                        crate::base::FieldValue::TextList(svs) => {
238                            if let Some(sv) = svs.last() { if let Ok(v) = sv.trim().parse() { obj.te = Some(v); } }
239                        }
240                        _ => {}
241                    }
242                }
243                "ExcIEEEAC8B.ve1" => {
244                    match val {
245                        crate::base::FieldValue::Text(sv) => { if let Ok(v) = sv.trim().parse() { obj.ve1 = Some(v); } }
246                        crate::base::FieldValue::TextList(svs) => {
247                            if let Some(sv) = svs.last() { if let Ok(v) = sv.trim().parse() { obj.ve1 = Some(v); } }
248                        }
249                        _ => {}
250                    }
251                }
252                "ExcIEEEAC8B.ve2" => {
253                    match val {
254                        crate::base::FieldValue::Text(sv) => { if let Ok(v) = sv.trim().parse() { obj.ve2 = Some(v); } }
255                        crate::base::FieldValue::TextList(svs) => {
256                            if let Some(sv) = svs.last() { if let Ok(v) = sv.trim().parse() { obj.ve2 = Some(v); } }
257                        }
258                        _ => {}
259                    }
260                }
261                "ExcIEEEAC8B.vemin" => {
262                    match val {
263                        crate::base::FieldValue::Text(sv) => { if let Ok(v) = sv.trim().parse() { obj.vemin = Some(v); } }
264                        crate::base::FieldValue::TextList(svs) => {
265                            if let Some(sv) = svs.last() { if let Ok(v) = sv.trim().parse() { obj.vemin = Some(v); } }
266                        }
267                        _ => {}
268                    }
269                }
270                "ExcIEEEAC8B.vfemax" => {
271                    match val {
272                        crate::base::FieldValue::Text(sv) => { if let Ok(v) = sv.trim().parse() { obj.vfemax = Some(v); } }
273                        crate::base::FieldValue::TextList(svs) => {
274                            if let Some(sv) = svs.last() { if let Ok(v) = sv.trim().parse() { obj.vfemax = Some(v); } }
275                        }
276                        _ => {}
277                    }
278                }
279                "ExcIEEEAC8B.vrmax" => {
280                    match val {
281                        crate::base::FieldValue::Text(sv) => { if let Ok(v) = sv.trim().parse() { obj.vrmax = Some(v); } }
282                        crate::base::FieldValue::TextList(svs) => {
283                            if let Some(sv) = svs.last() { if let Ok(v) = sv.trim().parse() { obj.vrmax = Some(v); } }
284                        }
285                        _ => {}
286                    }
287                }
288                "ExcIEEEAC8B.vrmin" => {
289                    match val {
290                        crate::base::FieldValue::Text(sv) => { if let Ok(v) = sv.trim().parse() { obj.vrmin = Some(v); } }
291                        crate::base::FieldValue::TextList(svs) => {
292                            if let Some(sv) = svs.last() { if let Ok(v) = sv.trim().parse() { obj.vrmin = Some(v); } }
293                        }
294                        _ => {}
295                    }
296                }
297                "ExcitationSystemDynamics.SynchronousMachineDynamics" => {
298                    if let crate::base::FieldValue::Resource(sv) = val {
299                        obj.base.synchronous_machine_dynamics = Some(crate::base::MridRef { mrid: sv.clone() });
300                    }
301                }
302                "DynamicsFunctionBlock.enabled" => {
303                    match val {
304                        crate::base::FieldValue::Text(sv) => { obj.base.base.enabled = Some(sv.trim() == "true"); }
305                        crate::base::FieldValue::TextList(svs) => {
306                            if let Some(sv) = svs.last() { obj.base.base.enabled = Some(sv.trim() == "true"); }
307                        }
308                        _ => {}
309                    }
310                }
311                "IdentifiedObject.description" => {
312                    match val {
313                        crate::base::FieldValue::Text(sv) => { obj.base.base.base.description = sv.clone(); }
314                        crate::base::FieldValue::TextList(svs) => {
315                            if let Some(sv) = svs.last() { obj.base.base.base.description = sv.clone(); }
316                        }
317                        _ => {}
318                    }
319                }
320                "IdentifiedObject.energyIdentCodeEic" => {
321                    match val {
322                        crate::base::FieldValue::Text(sv) => { obj.base.base.base.energy_ident_code_eic = sv.clone(); }
323                        crate::base::FieldValue::TextList(svs) => {
324                            if let Some(sv) = svs.last() { obj.base.base.base.energy_ident_code_eic = sv.clone(); }
325                        }
326                        _ => {}
327                    }
328                }
329                "IdentifiedObject.mRID" => {
330                    match val {
331                        crate::base::FieldValue::Text(sv) => { obj.base.base.base.m_rid = sv.clone(); }
332                        crate::base::FieldValue::TextList(svs) => {
333                            if let Some(sv) = svs.last() { obj.base.base.base.m_rid = sv.clone(); }
334                        }
335                        _ => {}
336                    }
337                }
338                "IdentifiedObject.name" => {
339                    match val {
340                        crate::base::FieldValue::Text(sv) => { obj.base.base.base.name = sv.clone(); }
341                        crate::base::FieldValue::TextList(svs) => {
342                            if let Some(sv) = svs.last() { obj.base.base.base.name = sv.clone(); }
343                        }
344                        _ => {}
345                    }
346                }
347                "IdentifiedObject.shortName" => {
348                    match val {
349                        crate::base::FieldValue::Text(sv) => { obj.base.base.base.short_name = sv.clone(); }
350                        crate::base::FieldValue::TextList(svs) => {
351                            if let Some(sv) = svs.last() { obj.base.base.base.short_name = sv.clone(); }
352                        }
353                        _ => {}
354                    }
355                }
356                _ => {}
357            }
358        }
359        obj
360    }
361}