Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Synergi reader length unit parser #197

Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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