Skip to content

Commit

Permalink
Merge pull request #197 from opusonesolutions/synergi-reader-length-u…
Browse files Browse the repository at this point in the history
…nit-parser

Synergi reader length unit parser
  • Loading branch information
NicolasGensollen authored Oct 17, 2018
2 parents 054c952 + a74befc commit de411b2
Show file tree
Hide file tree
Showing 4 changed files with 213 additions and 67 deletions.
93 changes: 93 additions & 0 deletions ditto/readers/synergi/length_units.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
from enum import Enum


class SynergiValueType(Enum):
SUL = 'SUL'
MUL = 'MUL'
LUL = 'LUL'
Per_LUL = 'Per_LUL'


def convert_length_unit(value, value_type, length_units):
"""
Converts a Synergi value to an SI type.
The value is interpreted based on:
+----------+----------------+------------+
|value_type| length_units | Unit |
+==========+================+============+
| SUL | English2 | inch |
+----------+----------------+------------+
| SUL | English1 | inch |
+----------+----------------+------------+
| SUL | Metric | mm |
+----------+----------------+------------+
| MUL | English2 | foot |
+----------+----------------+------------+
| MUL | English1 | foot |
+----------+----------------+------------+
| MUL | Metric | m |
+----------+----------------+------------+
| LUL | English2 | mile |
+----------+----------------+------------+
| LUL | English1 | kft |
+----------+----------------+------------+
| LUL | Metric | km |
+----------+----------------+------------+
| Per_LUL | English2 | per mile |
+----------+----------------+------------+
| Per_LUL | English1 | per kft |
+----------+----------------+------------+
| Per_LUL | Metric | per km |
+----------+----------------+------------+
The return value is based on
SUL: metres
MUL: metres
LUL: metres
Per_LUL: per metre
"""

if not isinstance(value_type, SynergiValueType):
raise ValueError(
'convert_length_unit received an invalid value_type value'
' of {}'.format(value_type)
)

if not isinstance(length_units, str):
raise ValueError(
'convert_length_unit must be passed a string length_units'
' parameter. {} was received.'.format(length_units)
)

if length_units not in {'English2', 'English1', 'Metric'}:
raise ValueError(
'convert_length_unit received an invalid length unit {}'.format(
length_units
)
)

CONVERSION_FACTORS = {
'English2': {
SynergiValueType.SUL: 0.0254,
SynergiValueType.MUL: 0.3048,
SynergiValueType.LUL: 1609.34,
SynergiValueType.Per_LUL: 1/1609.34,
},
'English1': {
SynergiValueType.SUL: 0.0254,
SynergiValueType.MUL: 0.3048,
SynergiValueType.LUL: 304.8,
SynergiValueType.Per_LUL: 3.28084 * 10 ** -3,
},
'Metric': {
SynergiValueType.SUL: 10 ** -3,
SynergiValueType.MUL: 1.0,
SynergiValueType.LUL: 1e3,
SynergiValueType.Per_LUL: 10 ** -3,
}
}

factor = CONVERSION_FACTORS[length_units][value_type]
return value * factor
137 changes: 70 additions & 67 deletions ditto/readers/synergi/read.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@
from ditto.models.position import Position
from ditto.models.base import Unicode

from ditto.readers.synergi.length_units import (
convert_length_unit,
SynergiValueType,
)

logger = logging.getLogger(__name__)


Expand Down Expand Up @@ -625,7 +630,11 @@ def parse(self, model):
# Assumes MUL is medium unit length and this is feets
# Converts to meters then
#
api_line.length = LineLength[i] * 0.3048
api_line.length = convert_length_unit(
LineLength[i],
SynergiValueType.MUL,
LengthUnits
)

# From element
# Replace spaces with "_"
Expand Down Expand Up @@ -851,12 +860,6 @@ def parse(self, model):

# The Neutral will be handled seperately
if phase != "N":

# Assumes MUL is medium unit length = ft
# Convert to meters
#
coeff = 0.3048

# Set the position of the first wire
if (
idx == 0
Expand All @@ -865,15 +868,19 @@ def parse(self, model):
and "Position1_Y_MUL" in config
):
# Set X
api_wire.X = (
config["Position1_X_MUL"] * coeff
) # DiTTo is in meters
api_wire.X = convert_length_unit(
config["Position1_X_MUL"],
SynergiValueType.MUL,
LengthUnits
)

# Set Y
# Add the reference height
api_wire.Y = (
AveHeightAboveGround_MUL[i] + config["Position1_Y_MUL"]
) * coeff # DiTTo is in meters
api_wire.Y = convert_length_unit(
AveHeightAboveGround_MUL[i] + config["Position1_Y_MUL"],
SynergiValueType.MUL,
LengthUnits
)

# Set the position of the second wire
if (
Expand All @@ -883,15 +890,19 @@ def parse(self, model):
and "Position2_Y_MUL" in config
):
# Set X
api_wire.X = (
config["Position2_X_MUL"] * coeff
) # DiTTo is in meters
api_wire.X = convert_length_unit(
config["Position2_X_MUL"],
SynergiValueType.MUL,
LengthUnits
)

# Set Y
# Add the reference height
api_wire.Y = (
AveHeightAboveGround_MUL[i] + config["Position2_Y_MUL"]
) * coeff # DiTTo is in meters
api_wire.Y = convert_length_unit(
AveHeightAboveGround_MUL[i] + config["Position2_Y_MUL"],
SynergiValueType.MUL,
LengthUnits
)

# Set the position of the third wire
if (
Expand All @@ -901,15 +912,19 @@ def parse(self, model):
and "Position3_Y_MUL" in config
):
# Set X
api_wire.X = (
config["Position3_X_MUL"] * coeff
) # DiTTo is in meters
api_wire.X = convert_length_unit(
config["Position3_X_MUL"],
SynergiValueType.MUL,
LengthUnits
)

# Set Y
# Add the reference height
api_wire.Y = (
AveHeightAboveGround_MUL[i] + config["Position3_Y_MUL"]
) * coeff # DiTTo is in meters
api_wire.Y = convert_length_unit(
AveHeightAboveGround_MUL[i] + config["Position3_Y_MUL"],
SynergiValueType.MUL,
LengthUnits
)

# Set the characteristics of the first wire. Use PhaseConductorID
#
Expand Down Expand Up @@ -997,24 +1012,22 @@ def parse(self, model):
conductor_name_raw = NeutralConductorID[i]

# Set the Spacing of the neutral
#
# Assumes MUL is medium unit length = ft
# Convert to meters
#
coeff = 0.3048

if "Neutral_X_MUL" in config and "Neutral_Y_MUL" in config:

# Set X
api_wire.X = (
config["Neutral_X_MUL"] * coeff
api_wire.X = convert_length_unit(
config["Neutral_X_MUL"],
SynergiValueType.MUL,
LengthUnits
) # DiTTo is in meters

# Set Y
# Add the reference height
api_wire.Y = (
AveHeightAboveGround_MUL[i] + config["Neutral_Y_MUL"]
) * coeff # DiTTo is in meters
api_wire.Y = convert_length_unit(
AveHeightAboveGround_MUL[i] + config["Neutral_Y_MUL"],
SynergiValueType.MUL,
LengthUnits
)

# Set the characteristics of the wire:
# - GMR
Expand All @@ -1030,16 +1043,19 @@ def parse(self, model):
# Set the GMR of the conductor
# DiTTo is in meters and GMR is assumed to be given in feets
#
api_wire.gmr = (
conductor_mapping[conductor_name_raw]["CableGMR"] * 0.3048
api_wire.gmr = convert_length_unit(
conductor_mapping[conductor_name_raw]["CableGMR"],
SynergiValueType.MUL,
LengthUnits
)

# Set the Diameter of the conductor
# Diameter is assumed to be given in inches and is converted to meters here
#
api_wire.diameter = (
conductor_mapping[conductor_name_raw]["CableDiamOutside"]
* 0.0254
api_wire.diameter = convert_length_unit(
conductor_mapping[conductor_name_raw]["CableDiamOutside"],
SynergiValueType.SUL,
LengthUnits
)

# Set the Ampacity of the conductor
Expand All @@ -1062,11 +1078,11 @@ def parse(self, model):
# TODO: Change this once resistance is the per unit length resistance
#
if api_line.length is not None:
api_wire.resistance = (
api_wire.resistance = convert_length_unit(
conductor_mapping[conductor_name_raw]["CableResistance"]
* api_line.length
* 1.0
/ 1609.34
* api_line.length,
SynergiValueType.Per_LUL,
LengthUnits
)

# Add the new Wire to the line's list of wires
Expand Down Expand Up @@ -1110,29 +1126,16 @@ def parse(self, model):
# | Z0-Z+ Z0-Z+ Z0+2*Z+ |
# --------------------------

# TODO: Check that the following is correct...
# If LengthUnits is set to English2 or not defined , then assume miles
if LengthUnits == "English2" or LengthUnits is None:
coeff = 0.000621371
# Else, if LengthUnits is set to English1, assume kft
elif LengthUnits == "English1":
coeff = 3.28084 * 10 ** -3
# Else, if LengthUnits is set to Metric, assume km
elif LengthUnits == "Metric":
coeff = 10 ** -3
else:
raise ValueError(
"LengthUnits <{}> is not valid.".format(LengthUnits)
)

# Multiply by 1/3
coeff *= 1.0 / 3.0
r0 = convert_length_unit(r0, SynergiValueType.Per_LUL, LengthUnits) / 3.0
r1 = convert_length_unit(r1, SynergiValueType.Per_LUL, LengthUnits) / 3.0
x0 = convert_length_unit(x0, SynergiValueType.Per_LUL, LengthUnits) / 3.0
x1 = convert_length_unit(x1, SynergiValueType.Per_LUL, LengthUnits) / 3.0

# One phase case (One phase + neutral)
#
if NPhase == 2:
impedance_matrix = [
[coeff * complex(float(r0) + float(r1), float(x0) + float(x1))]
[complex(float(r0) + float(r1), float(x0) + float(x1))]
]

# Two phase case (Two phases + neutral)
Expand All @@ -1151,9 +1154,9 @@ def parse(self, model):
if b2 == 0:
b2 = float(x1)

b = coeff * complex(b1, b2)
b = complex(b1, b2)

a = coeff * complex(
a = complex(
(2 * float(r1) + float(r0)), (2 * float(x1) + float(x0))
)

Expand All @@ -1162,7 +1165,7 @@ def parse(self, model):
# Three phases case (Three phases + neutral)
#
if NPhase == 4:
a = coeff * complex(
a = complex(
(2 * float(r1) + float(r0)), (2 * float(x1) + float(x0))
)
b1 = float(r0) - float(r1)
Expand All @@ -1177,7 +1180,7 @@ def parse(self, model):
if b2 == 0:
b2 = float(x1)

b = coeff * complex(b1, b2)
b = complex(b1, b2)

impedance_matrix = [[a, b, b], [b, a, b], [b, b, a]]

Expand Down
Empty file.
Loading

0 comments on commit de411b2

Please sign in to comment.