Skip to main content

surge_network/network/
protection.rs

1// SPDX-License-Identifier: LicenseRef-PolyForm-Noncommercial-1.0.0
2//! Protection equipment data types (IEC 61970-302 Protection package).
3//!
4//! Stores relay settings, auto-reclose sequences, and synchrocheck parameters
5//! parsed from CGMES protection profile data. These are informational/metadata
6//! types — they do not affect power flow computation but are preserved for
7//! downstream protection coordination tools (e.g., surge-fault TCC analysis).
8
9use serde::{Deserialize, Serialize};
10
11/// Overcurrent relay settings (IEC 61970-302 CurrentRelay).
12#[derive(Debug, Clone, Default, Serialize, Deserialize)]
13pub struct CurrentRelaySettings {
14    /// CIM mRID.
15    pub mrid: String,
16    /// Relay name.
17    pub name: String,
18    /// Phase pickup current (A).
19    pub phase_pickup_a: Option<f64>,
20    /// Ground pickup current (A).
21    pub ground_pickup_a: Option<f64>,
22    /// Negative-sequence pickup (A).
23    pub neg_seq_pickup_a: Option<f64>,
24    /// Phase time dial (s).
25    pub phase_time_dial_s: Option<f64>,
26    /// Ground time dial (s).
27    pub ground_time_dial_s: Option<f64>,
28    /// Neg-seq time dial (s).
29    pub neg_seq_time_dial_s: Option<f64>,
30    /// True = inverse-time characteristic, false = definite-time.
31    pub inverse_time: bool,
32    /// Directional element.
33    pub directional: bool,
34    /// Bus where CTs are located.
35    pub bus: Option<u32>,
36    /// Protected switch/breaker mRID.
37    pub protected_switch_mrid: Option<String>,
38}
39
40/// Distance relay settings (IEC 61970-302 DistanceRelay / zones).
41#[derive(Debug, Clone, Default, Serialize, Deserialize)]
42pub struct DistanceRelaySettings {
43    /// CIM mRID.
44    pub mrid: String,
45    /// Relay name.
46    pub name: String,
47    /// Forward reach (Ohm).
48    pub forward_reach_ohm: Option<f64>,
49    /// Forward blind reach (Ohm).
50    pub forward_blind_ohm: Option<f64>,
51    /// Backward/reverse reach (Ohm).
52    pub backward_reach_ohm: Option<f64>,
53    /// Backward blind reach (Ohm).
54    pub backward_blind_ohm: Option<f64>,
55    /// MHO characteristic angle (degrees).
56    pub mho_angle_deg: Option<f64>,
57    /// Z0/Z1 compensation ratio.
58    pub zero_seq_rx_ratio: Option<f64>,
59    /// Zero-sequence forward reach (Ohm).
60    pub zero_seq_reach_ohm: Option<f64>,
61    /// Bus where CTs/VTs are located.
62    pub bus: Option<u32>,
63    /// Protected switch mRID.
64    pub protected_switch_mrid: Option<String>,
65}
66
67/// A single auto-reclose shot.
68#[derive(Debug, Clone, Default, Serialize, Deserialize)]
69pub struct RecloseShot {
70    /// Shot number (1-based).
71    pub step: u32,
72    /// Reclose delay (s).
73    pub delay_s: f64,
74}
75
76/// Auto-reclose sequence for a breaker.
77#[derive(Debug, Clone, Default, Serialize, Deserialize)]
78pub struct RecloseSequenceData {
79    /// Protected switch/breaker mRID.
80    pub protected_switch_mrid: String,
81    /// Ordered reclose shots.
82    pub shots: Vec<RecloseShot>,
83}
84
85/// Synchrocheck relay settings (IEC 61970-302 SynchrocheckRelay).
86#[derive(Debug, Clone, Default, Serialize, Deserialize)]
87pub struct SynchrocheckSettings {
88    /// CIM mRID.
89    pub mrid: String,
90    /// Relay name.
91    pub name: String,
92    /// Maximum angle difference (degrees).
93    pub max_angle_diff_deg: Option<f64>,
94    /// Maximum frequency difference (Hz).
95    pub max_freq_diff_hz: Option<f64>,
96    /// Maximum voltage magnitude difference (pu).
97    pub max_volt_diff_pu: Option<f64>,
98    /// Bus where relay is located.
99    pub bus: Option<u32>,
100    /// Protected switch mRID.
101    pub protected_switch_mrid: Option<String>,
102}
103
104/// Container for all protection equipment data.
105#[derive(Debug, Clone, Default, Serialize, Deserialize)]
106pub struct ProtectionData {
107    /// Overcurrent relays.
108    pub current_relays: Vec<CurrentRelaySettings>,
109    /// Distance/impedance relays.
110    pub distance_relays: Vec<DistanceRelaySettings>,
111    /// Auto-reclose sequences.
112    pub reclose_sequences: Vec<RecloseSequenceData>,
113    /// Synchrocheck relays.
114    pub synchrocheck_relays: Vec<SynchrocheckSettings>,
115}
116
117impl ProtectionData {
118    /// Returns true if no protection equipment has been loaded.
119    pub fn is_empty(&self) -> bool {
120        self.current_relays.is_empty()
121            && self.distance_relays.is_empty()
122            && self.reclose_sequences.is_empty()
123            && self.synchrocheck_relays.is_empty()
124    }
125}