Protection Relays
Protection Relay Functions, Schemes, and Systems
Each protection relay in the CIM model is implemented in a ProtectionRelayFunction
, which is composed of a collection of Sensor
s, thresholds that determine
the conditions that activate the relay, the time limits for each condition before activation, and the ProtectedSwitch
es to open when the relay is activated.
ProtectionRelayFunction
s may be grouped into ProtectionRelayScheme
s, each of which belong to a ProtectionRelaySystem
. A ProtectionRelaySystem
is a
physical piece of equipment containing a suite of ProtectionRelayFunction
s, such as a circuit breaker panel. They typically comprise two schemes: main and
failsafe.
Here is a contrived example of such a system modelled using the Evolve SDK:
from zepben.evolve import Breaker, CurrentTransformer, CurrentRelay, RelaySetting, UnitSymbol, ProtectionRelayScheme, ProtectionRelaySystem
def main():
# Breakers for stove, bathroom, and washer are for individual outlets,
# whereas the failsafe breaker can disconnect all appliances from power.
stove_breaker = Breaker("stoveBreaker")
bathroom_breaker = Breaker("bathroomBreaker")
washer_breaker = Breaker("washerBreaker")
failsafe_breaker = Breaker("failsafeBreaker")
stove_ct = CurrentTransformer("stoveCT")
bathroom_ct = CurrentTransformer("bathroomCT")
washer_ct = CurrentTransformer("washerCT")
failsafe_ct = CurrentTransformer("failsafeCT")
stove_cr = (CurrentRelay("stoveCR")
.add_protected_switch(stove_breaker)
.add_sensor(stove_ct)
.add_threshold(RelaySetting(UnitSymbol.A, 50.0))
.add_time_limit(0.5))
stove_breaker.add_relay_function(stove_cr)
stove_ct.add_relay_function(stove_cr)
bathroom_cr = (CurrentRelay("bathroomCR")
.add_protected_switch(bathroom_breaker)
.add_sensor(bathroom_ct)
.add_threshold(RelaySetting(UnitSymbol.A, 50.0))
.add_time_limit(0.5))
bathroom_breaker.add_relay_function(bathroom_cr)
bathroom_ct.add_relay_function(bathroom_cr)
washer_cr = (CurrentRelay("washerCR")
.add_protected_switch(washer_breaker)
.add_sensor(washer_ct)
.add_threshold(RelaySetting(UnitSymbol.A, 50.0))
.add_time_limit(0.5))
washer_breaker.add_relay_function(washer_cr)
washer_ct.add_relay_function(washer_cr)
failsafe_cr = (CurrentRelay("failsafeCR")
.add_protected_switch(failsafe_breaker)
.add_sensor(failsafe_ct)
.add_threshold(RelaySetting(UnitSymbol.A, 50.0))
.add_time_limit(0.5))
failsafe_breaker.add_relay_function(failsafe_cr)
failsafe_ct.add_relay_function(failsafe_cr)
main_scheme = (ProtectionRelayScheme("main")
.add_function(stove_cr)
.add_function(bathroom_cr)
.add_function(washer_cr))
stove_cr.add_scheme(main_scheme)
bathroom_cr.add_scheme(main_scheme)
washer_cr.add_scheme(main_scheme)
failsafe_scheme = (ProtectionRelayScheme("failsafe")
.add_function(failsafe_cr))
failsafe_cr.add_scheme(failsafe_scheme)
system = (ProtectionRelaySystem("system")
.add_scheme(main_scheme)
.add_scheme(failsafe_scheme))
main_scheme.system = system
failsafe_scheme.system = system
For brevity, this example excludes modelling of connectivity between the sensors and breakers.
Grounds and Ground Disconnectors
To aid in modelling protection systems, our network data model also supports explicit modelling of grounds and ground disconnectors:
from zepben.evolve import NetworkService, Terminal, Ground, GroundDisconnector, Junction
def main():
# junction --- ground disconnector --- ground
network_service = NetworkService()
ground_terminal = Terminal("ground-t1")
ground = (Ground("ground")
.add_terminal(ground_terminal))
gd_terminal1 = Terminal("gd-t1")
gd_terminal2 = Terminal("gd-t2")
gd = (GroundDisconnector("gd")
.add_terminal(gd_terminal1)
.add_terminal(gd_terminal2))
junction_terminal = Terminal("junction-t1")
junction = (Junction("junction")
.add_terminal(junction_terminal))
network_service.connect_terminals(junction_terminal, gd_terminal1)
network_service.connect_terminals(gd_terminal2, ground_terminal)
for io in [ground, ground_terminal, gd, gd_terminal1, gd_terminal2, junction, junction_terminal]:
network_service.add(io)
Series Compensators
The Evolve SDK also supports modelling series compensators, which are series capacitors and reactors or an AC transmission line without charging susceptance.
from zepben.evolve import NetworkService, Terminal, AcLineSegment, SeriesCompensator
def main():
# AC line 1 --- series compensator -- AC line 2
network_service = NetworkService()
acls1_terminal1 = Terminal("acls1-t1")
acls1_terminal2 = Terminal("acls1-t2")
acls1 = (AcLineSegment("acls1")
.add_terminal(acls1_terminal1)
.add_terminal(acls1_terminal2))
acls2_terminal1 = Terminal("acls2-t1")
acls2_terminal2 = Terminal("acls2-t2")
acls2 = (AcLineSegment("acls2")
.add_terminal(acls2_terminal1)
.add_terminal(acls2_terminal2))
sc_terminal1 = Terminal("sc-t1")
sc_terminal2 = Terminal("sc-t2")
sc = SeriesCompensator("sc")
# dummy (likely unrealistic) values
sc.r = 1.0
sc.r0 = 1.5
sc.x = 123.0
sc.x0 = 125.0
sc.varistor_voltage_threshold = 10
sc.varistor_rated_current = 5
sc.add_terminal(sc_terminal1)
sc.add_terminal(sc_terminal2)
network_service.connect_terminals(acls1_terminal2, sc_terminal1)
network_service.connect_terminals(sc_terminal2, acls2_terminal1)
for io in [acls1, acls1_terminal1, acls1_terminal2, acls2, acls2_terminal1, acls2_terminal2, sc, sc_terminal1, sc_terminal2]:
network_service.add(io)