1 # Copyright (C) 2010 Richard Lincoln
3 # This library is free software; you can redistribute it and/or
4 # modify it under the terms of the GNU Lesser General Public
5 # License as published by the Free Software Foundation; either
6 # version 2.1 of the License, or (at your option) any later version.
8 # This library is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 # Lesser General Public License for more details.
13 # You should have received a copy of the GNU Lesser General Public
14 # License along with this library; if not, write to the Free Software
15 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA, USA
17 from CIM14
.IEC61970
.Wires
.ACLineSegment
import ACLineSegment
19 class DistributionLineSegment(ACLineSegment
):
20 """Extends ACLineSegment with references to a library of standard types from which electrical parameters can be calculated, as follows: - calculate electrical parameters from asset data, using associated ConductorInfo, with values then multiplied by Conductor.length to produce a matrix model. - calculate unbalanced electrical parameters from associated PerLengthPhaseImpedance, then multiplied by Conductor.length to produce a matrix model. - calculate transposed electrical parameters from associated PerLengthSequenceImpedance, then multiplied by Conductor.length to produce a sequence model. For symmetrical, transposed 3ph lines, it is sufficient to use inherited ACLineSegment attributes, which describe sequence impedances and admittances for the entire length of the segment. Known issue: Attributes expressing impedances and admittances in PerLengthSequenceImpedance and PhaseImpedanceData use Resistance, etc., which describe pre-calculated, full length of segment, while we should have a longitudinal unit, per length. Taking 'r' as example, its 'unit'=Ohm, but the value is effectively in Ohm/m, so the value needs to be multiplied by Conductor.length. This is against the whole idea of unit data types and is semantically wrong, but base CIM does not have the required data types at this moment. Until the revision of unit modelling in CIM, applications need to deduce and locally handle appending '/m' for units and ensure they multiply the values by Conductor.length.
23 def __init__(self
, ConductorInfo
=None, PhaseImpedance
=None, SequenceImpedance
=None, *args
, **kw_args
):
24 """Initialises a new 'DistributionLineSegment' instance.
26 @param ConductorInfo: Conductor data of this conductor segment.
27 @param PhaseImpedance: Phase impedance of this conductor segment; used for unbalanced model.
28 @param SequenceImpedance: Sequence impedance of this conductor segment; used for balanced model.
30 self
._ConductorInfo
= None
31 self
.ConductorInfo
= ConductorInfo
33 self
._PhaseImpedance
= None
34 self
.PhaseImpedance
= PhaseImpedance
36 self
._SequenceImpedance
= None
37 self
.SequenceImpedance
= SequenceImpedance
39 super(DistributionLineSegment
, self
).__init
__(*args
, **kw_args
)
45 _refs
= ["ConductorInfo", "PhaseImpedance", "SequenceImpedance"]
48 def getConductorInfo(self
):
49 """Conductor data of this conductor segment.
51 return self
._ConductorInfo
53 def setConductorInfo(self
, value
):
54 if self
._ConductorInfo
is not None:
55 filtered
= [x
for x
in self
.ConductorInfo
.ConductorSegments
if x
!= self
]
56 self
._ConductorInfo
._ConductorSegments
= filtered
58 self
._ConductorInfo
= value
59 if self
._ConductorInfo
is not None:
60 if self
not in self
._ConductorInfo
._ConductorSegments
:
61 self
._ConductorInfo
._ConductorSegments
.append(self
)
63 ConductorInfo
= property(getConductorInfo
, setConductorInfo
)
65 def getPhaseImpedance(self
):
66 """Phase impedance of this conductor segment; used for unbalanced model.
68 return self
._PhaseImpedance
70 def setPhaseImpedance(self
, value
):
71 if self
._PhaseImpedance
is not None:
72 filtered
= [x
for x
in self
.PhaseImpedance
.ConductorSegments
if x
!= self
]
73 self
._PhaseImpedance
._ConductorSegments
= filtered
75 self
._PhaseImpedance
= value
76 if self
._PhaseImpedance
is not None:
77 if self
not in self
._PhaseImpedance
._ConductorSegments
:
78 self
._PhaseImpedance
._ConductorSegments
.append(self
)
80 PhaseImpedance
= property(getPhaseImpedance
, setPhaseImpedance
)
82 def getSequenceImpedance(self
):
83 """Sequence impedance of this conductor segment; used for balanced model.
85 return self
._SequenceImpedance
87 def setSequenceImpedance(self
, value
):
88 if self
._SequenceImpedance
is not None:
89 filtered
= [x
for x
in self
.SequenceImpedance
.ConductorSegments
if x
!= self
]
90 self
._SequenceImpedance
._ConductorSegments
= filtered
92 self
._SequenceImpedance
= value
93 if self
._SequenceImpedance
is not None:
94 if self
not in self
._SequenceImpedance
._ConductorSegments
:
95 self
._SequenceImpedance
._ConductorSegments
.append(self
)
97 SequenceImpedance
= property(getSequenceImpedance
, setSequenceImpedance
)