Skip to main content

cimstructs/
PhaseTapChangerLinear.rs

1/// Describes a tap changer with a linear relation between the tap step and the phase angle difference across the transformer. This is a mathematical model that is an approximation of a real phase tap changer. The phase angle is computed as stepPhaseShiftIncrement times the tap position. The voltage magnitude of both sides is the same.
2#[derive(Debug, Default, Clone, serde::Serialize, serde::Deserialize)]
3pub struct PhaseTapChangerLinear {
4    #[serde(flatten)]
5    pub base: super::PhaseTapChanger,
6    /// Phase shift per step position. A positive value indicates a positive angle variation from the Terminal at the PowerTransformerEnd, where the TapChanger is located, into the transformer. The actual phase shift increment might be more accurately computed from the symmetrical or asymmetrical models or a tap step table lookup if those are available.
7    #[serde(skip_serializing_if = "Option::is_none")]
8    pub step_phase_shift_increment: Option<f64>,
9    /// The reactance depends on the tap position according to a 'u' shaped curve. The maximum reactance (xMax) appears at the low and high tap positions. Depending on the ā€œuā€ curve the attribute can be either higher or lower than PowerTransformerEnd.x.
10    #[serde(skip_serializing_if = "Option::is_none")]
11    pub x_max: Option<f64>,
12    /// The reactance depends on the tap position according to a 'u' shaped curve. The minimum reactance (xMin) appears at the mid tap position. PowerTransformerEnd.x shall be consistent with PhaseTapChangerLinear.xMin and PhaseTapChangerNonLinear.xMin. In case of inconsistency, PowerTransformerEnd.x shall be used.
13    #[serde(skip_serializing_if = "Option::is_none")]
14    pub x_min: Option<f64>,
15}
16impl crate::base::CimElement for PhaseTapChangerLinear {
17    fn mrid(&self) -> &str { &self.base.base.base.base.id }
18    fn type_name(&self) -> &'static str { "PhaseTapChangerLinear" }
19    fn as_any(&self) -> &dyn std::any::Any { self }
20    fn to_json_value(&self) -> serde_json::Value {
21        serde_json::to_value(self).unwrap_or(serde_json::Value::Null)
22    }
23    fn to_block(&self) -> crate::base::RdfBlock {
24        let mut block = self.base.to_block();
25        block.type_name = "PhaseTapChangerLinear".to_string();
26        if let Some(v) = self.step_phase_shift_increment {
27            block.fields.insert("PhaseTapChangerLinear.stepPhaseShiftIncrement".into(), crate::base::FieldValue::Text(v.to_string()));
28        }
29        if let Some(v) = self.x_max {
30            block.fields.insert("PhaseTapChangerLinear.xMax".into(), crate::base::FieldValue::Text(v.to_string()));
31        }
32        if let Some(v) = self.x_min {
33            block.fields.insert("PhaseTapChangerLinear.xMin".into(), crate::base::FieldValue::Text(v.to_string()));
34        }
35        block
36    }
37}
38
39impl PhaseTapChangerLinear {
40    pub fn from_block(b: &crate::base::RdfBlock) -> Self {
41        let mut obj = Self::default();
42        obj.base.base.base.base.id.clone_from(&b.mrid);
43        for (key, val) in &b.fields {
44            match key.as_str() {
45                "PhaseTapChangerLinear.stepPhaseShiftIncrement" => {
46                    match val {
47                        crate::base::FieldValue::Text(sv) => { if let Ok(v) = sv.trim().parse() { obj.step_phase_shift_increment = Some(v); } }
48                        crate::base::FieldValue::TextList(svs) => {
49                            if let Some(sv) = svs.last() { if let Ok(v) = sv.trim().parse() { obj.step_phase_shift_increment = Some(v); } }
50                        }
51                        _ => {}
52                    }
53                }
54                "PhaseTapChangerLinear.xMax" => {
55                    match val {
56                        crate::base::FieldValue::Text(sv) => { if let Ok(v) = sv.trim().parse() { obj.x_max = Some(v); } }
57                        crate::base::FieldValue::TextList(svs) => {
58                            if let Some(sv) = svs.last() { if let Ok(v) = sv.trim().parse() { obj.x_max = Some(v); } }
59                        }
60                        _ => {}
61                    }
62                }
63                "PhaseTapChangerLinear.xMin" => {
64                    match val {
65                        crate::base::FieldValue::Text(sv) => { if let Ok(v) = sv.trim().parse() { obj.x_min = Some(v); } }
66                        crate::base::FieldValue::TextList(svs) => {
67                            if let Some(sv) = svs.last() { if let Ok(v) = sv.trim().parse() { obj.x_min = Some(v); } }
68                        }
69                        _ => {}
70                    }
71                }
72                "PhaseTapChanger.TransformerEnd" => {
73                    if let crate::base::FieldValue::Resource(sv) = val {
74                        obj.base.transformer_end = Some(crate::base::MridRef { mrid: sv.clone() });
75                    }
76                }
77                "TapChanger.TapChangerControl" => {
78                    if let crate::base::FieldValue::Resource(sv) = val {
79                        obj.base.base.tap_changer_control = Some(crate::base::MridRef { mrid: sv.clone() });
80                    }
81                }
82                "TapChanger.controlEnabled" => {
83                    match val {
84                        crate::base::FieldValue::Text(sv) => { obj.base.base.control_enabled = Some(sv.trim() == "true"); }
85                        crate::base::FieldValue::TextList(svs) => {
86                            if let Some(sv) = svs.last() { obj.base.base.control_enabled = Some(sv.trim() == "true"); }
87                        }
88                        _ => {}
89                    }
90                }
91                "TapChanger.highStep" => {
92                    match val {
93                        crate::base::FieldValue::Text(sv) => { if let Ok(v) = sv.trim().parse() { obj.base.base.high_step = Some(v); } }
94                        crate::base::FieldValue::TextList(svs) => {
95                            if let Some(sv) = svs.last() { if let Ok(v) = sv.trim().parse() { obj.base.base.high_step = Some(v); } }
96                        }
97                        _ => {}
98                    }
99                }
100                "TapChanger.lowStep" => {
101                    match val {
102                        crate::base::FieldValue::Text(sv) => { if let Ok(v) = sv.trim().parse() { obj.base.base.low_step = Some(v); } }
103                        crate::base::FieldValue::TextList(svs) => {
104                            if let Some(sv) = svs.last() { if let Ok(v) = sv.trim().parse() { obj.base.base.low_step = Some(v); } }
105                        }
106                        _ => {}
107                    }
108                }
109                "TapChanger.ltcFlag" => {
110                    match val {
111                        crate::base::FieldValue::Text(sv) => { obj.base.base.ltc_flag = Some(sv.trim() == "true"); }
112                        crate::base::FieldValue::TextList(svs) => {
113                            if let Some(sv) = svs.last() { obj.base.base.ltc_flag = Some(sv.trim() == "true"); }
114                        }
115                        _ => {}
116                    }
117                }
118                "TapChanger.neutralStep" => {
119                    match val {
120                        crate::base::FieldValue::Text(sv) => { if let Ok(v) = sv.trim().parse() { obj.base.base.neutral_step = Some(v); } }
121                        crate::base::FieldValue::TextList(svs) => {
122                            if let Some(sv) = svs.last() { if let Ok(v) = sv.trim().parse() { obj.base.base.neutral_step = Some(v); } }
123                        }
124                        _ => {}
125                    }
126                }
127                "TapChanger.neutralU" => {
128                    match val {
129                        crate::base::FieldValue::Text(sv) => { if let Ok(v) = sv.trim().parse() { obj.base.base.neutral_u = Some(v); } }
130                        crate::base::FieldValue::TextList(svs) => {
131                            if let Some(sv) = svs.last() { if let Ok(v) = sv.trim().parse() { obj.base.base.neutral_u = Some(v); } }
132                        }
133                        _ => {}
134                    }
135                }
136                "TapChanger.normalStep" => {
137                    match val {
138                        crate::base::FieldValue::Text(sv) => { if let Ok(v) = sv.trim().parse() { obj.base.base.normal_step = Some(v); } }
139                        crate::base::FieldValue::TextList(svs) => {
140                            if let Some(sv) = svs.last() { if let Ok(v) = sv.trim().parse() { obj.base.base.normal_step = Some(v); } }
141                        }
142                        _ => {}
143                    }
144                }
145                "TapChanger.step" => {
146                    match val {
147                        crate::base::FieldValue::Text(sv) => { if let Ok(v) = sv.trim().parse() { obj.base.base.step = Some(v); } }
148                        crate::base::FieldValue::TextList(svs) => {
149                            if let Some(sv) = svs.last() { if let Ok(v) = sv.trim().parse() { obj.base.base.step = Some(v); } }
150                        }
151                        _ => {}
152                    }
153                }
154                "IdentifiedObject.description" => {
155                    match val {
156                        crate::base::FieldValue::Text(sv) => { obj.base.base.base.base.description = sv.clone(); }
157                        crate::base::FieldValue::TextList(svs) => {
158                            if let Some(sv) = svs.last() { obj.base.base.base.base.description = sv.clone(); }
159                        }
160                        _ => {}
161                    }
162                }
163                "IdentifiedObject.energyIdentCodeEic" => {
164                    match val {
165                        crate::base::FieldValue::Text(sv) => { obj.base.base.base.base.energy_ident_code_eic = sv.clone(); }
166                        crate::base::FieldValue::TextList(svs) => {
167                            if let Some(sv) = svs.last() { obj.base.base.base.base.energy_ident_code_eic = sv.clone(); }
168                        }
169                        _ => {}
170                    }
171                }
172                "IdentifiedObject.mRID" => {
173                    match val {
174                        crate::base::FieldValue::Text(sv) => { obj.base.base.base.base.m_rid = sv.clone(); }
175                        crate::base::FieldValue::TextList(svs) => {
176                            if let Some(sv) = svs.last() { obj.base.base.base.base.m_rid = sv.clone(); }
177                        }
178                        _ => {}
179                    }
180                }
181                "IdentifiedObject.name" => {
182                    match val {
183                        crate::base::FieldValue::Text(sv) => { obj.base.base.base.base.name = sv.clone(); }
184                        crate::base::FieldValue::TextList(svs) => {
185                            if let Some(sv) = svs.last() { obj.base.base.base.base.name = sv.clone(); }
186                        }
187                        _ => {}
188                    }
189                }
190                "IdentifiedObject.shortName" => {
191                    match val {
192                        crate::base::FieldValue::Text(sv) => { obj.base.base.base.base.short_name = sv.clone(); }
193                        crate::base::FieldValue::TextList(svs) => {
194                            if let Some(sv) = svs.last() { obj.base.base.base.base.short_name = sv.clone(); }
195                        }
196                        _ => {}
197                    }
198                }
199                _ => {}
200            }
201        }
202        obj
203    }
204}