Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
91782a7
Second commit
kavuribhavya Oct 23, 2018
f246627
Adding the markdown file
kavuribhavya Oct 23, 2018
3b8875c
Adding various linecode configurations
tareknrel Oct 31, 2018
890b307
fixing name typo and adding phases
tareknrel Nov 1, 2018
a5b6111
Transformers and Regulators
kavuribhavya Nov 7, 2018
7bd1953
Adding additional transformer test cases
tareknrel Nov 7, 2018
8873db0
Adding extra 4-node feeder case
tareknrel Nov 7, 2018
ef926bf
Adding extra transformer cases - specifically delta-wye single phase …
tareknrel Nov 7, 2018
672dd46
added new regulators from SMART-DS and other IEEE systems. Now includ…
tareknrel Nov 8, 2018
585bd89
Add more test cases
kavuribhavya Nov 15, 2018
bb6b93b
Removed the swap file
kavuribhavya Nov 15, 2018
23cc665
adding fuse test cases
tareknrel Nov 27, 2018
7abc130
ephasor transformers left-shifted and phase angle set by phase regard…
tareknrel Nov 27, 2018
668f3d3
adding faultrate information in test_line_length.dss
tareknrel Nov 27, 2018
efd776c
Updated Test Cases for all elements
kavuribhavya Dec 12, 2018
ffbf633
Added attributes only which are implemented till now
kavuribhavya Dec 12, 2018
58c3773
Changing names of testcases
kavuribhavya Dec 12, 2018
1b2db6f
Adding tests with vmin and vmax provided
tareknrel Feb 22, 2019
33e1fbf
different names for controllers
tareknrel Feb 22, 2019
57f9f99
Adding phase shift info based on connection type
tareknrel Feb 22, 2019
af20df4
adding vlimit parameters to test
tareknrel Feb 22, 2019
43301a7
Adding phase_shift to regulators
tareknrel Feb 22, 2019
e4166d8
Added two CTPrim examples
tareknrel Feb 22, 2019
4ae1b6d
adding tap information for regulators
tareknrel Feb 22, 2019
74d7bc6
Updated tests for Lines, capacitors and regulators
Mar 6, 2019
1eaa5ac
Merge branch 'master' into OpenDSS-unittests
tarekelgindy Mar 21, 2019
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
4 changes: 2 additions & 2 deletions ditto/formats/gridlabd/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ def __getitem__(self, k):

def __setitem__(self, k, v):
if k not in [p["name"] for p in self._properties]:
raise AttributeError(
"Unable to set {} with {} on {}".format(k, v, self.__class__.__name__)
print(
"Warning: Unable to set {} with {} on {}".format(k, v, self.__class__.__name__)
)
return setattr(self, "_{}".format(k), v)
6 changes: 6 additions & 0 deletions ditto/formats/gridlabd/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -701,6 +701,12 @@
]
},

"house":{
"parent":"node",
"properties":[
]
},

"load": {
"parent": "node",
"properties": [
Expand Down
158 changes: 150 additions & 8 deletions ditto/readers/gridlabd/read.py
Original file line number Diff line number Diff line change
Expand Up @@ -524,12 +524,12 @@ def parse(self, model, origin_datetime="2017 Jun 1 2:00PM"):
obj = entries[1].split(":")
obj_class = obj[0]
if (
obj_class == "house"
or obj_class == "solar"
#obj_class == "house"
obj_class == "solar"
or obj_class == "inverter"
or obj_class == "waterheater"
or obj_class == "climate"
or obj_class == "ZIPload"
#or obj_class == "ZIPload"
or obj_class == "tape.recorder"
or obj_class == "player"
or obj_class == "tape.collector"
Expand Down Expand Up @@ -653,7 +653,7 @@ def parse(self, model, origin_datetime="2017 Jun 1 2:00PM"):
except AttributeError:
pass

if obj_type == "triplex_node" or obj_type == "triplex_meter":
if obj_type == "triplex_node" or obj_type == "triplex_meter" or obj_type == "house":
api_node = Node(model)
try:
api_node.name = obj["name"]
Expand All @@ -677,6 +677,16 @@ def parse(self, model, origin_datetime="2017 Jun 1 2:00PM"):
api_node.phases = phases
except AttributeError:
pass
try:
parent = obj["parent"]
# Create a dummy line from house node to the parent
api_line = Line(model)
api_line.name=api_node.name+"_"+parent
api_line.from_element = parent
api_line.to_element = api_node.name
api_line.length = 0.01
except:
pass

if obj_type == "transformer":

Expand Down Expand Up @@ -915,7 +925,7 @@ def parse(self, model, origin_datetime="2017 Jun 1 2:00PM"):
windings.append(winding3)
api_transformer.windings = windings

if obj_type == "load":
if obj_type == "load" or obj_type=="ZIPload":

api_load = Load(model)
api_node = None
Expand Down Expand Up @@ -953,7 +963,7 @@ def parse(self, model, origin_datetime="2017 Jun 1 2:00PM"):
if not has_parent:
api_node.phases = list(map(lambda x: Unicode(x), phases))
except AttributeError:
pass
phases = ['']
num_phases = 0

# The use_zip parameter is used to determine whether the load is zip or not.
Expand Down Expand Up @@ -1346,8 +1356,140 @@ def parse(self, model, origin_datetime="2017 Jun 1 2:00PM"):

phaseloads.append(phaseload)

else:
num_phases = num_phases + 1
phaseload = PhaseLoad(model)
phaseload.phase = phase
phaseload.p = 0 # Default value
phaseload.q = 0
try:
complex_power = complex(obj["constant_power"])
p = complex_power.real
q = complex_power.imag
if (
p != 0
): # Assume that unless ZIP is specifically specified only one of constant_power, constant_current and constant_impedance is used. A real part of 0 means that I or Z is being used instead.
phaseload.p = p
phaseload.q = q
phaseload.model = (
1
) # The opendss model number (specifying constant power)
phaseload.use_zip = 0
phaseloads.append(phaseload)
continue
except AttributeError:
pass

try:
# Firstly check if it's using a non-zip model.
complex_impedance = complex(obj["constant_impedance"])
complex_voltage = complex(
obj["voltage"]
) # Needed to compute the power
if (
complex_impedance.real != 0
): # Assume that unless ZIP is specifically specified only one of constant_power, constant_current and constant_impedance is used. A real part of 0 means that I or P is being used instead.
p = (
(
(
complex_voltage.real ** 2
+ complex_voltage.imag ** 2
)
)
/ complex_impedance.conjugate()
).real
q = (
(
(
complex_voltage.real ** 2
+ complex_voltage.imag ** 2
)
)
/ complex_impedance.conjugate()
).imag
phaseload.p = p
phaseload.q = q
phaseload.model = (
2
) # The opendss model number (specifying constant impedance)
phaseload.use_zip = 0
phaseloads.append(phaseload)
continue
except AttributeError:
pass

try:
# Firstly check if it's using a non-zip model.
complex_current = complex(obj["constant_current"])
complex_voltage = complex(
obj["voltage"]
) # Needed to compute the power
p = (complex_voltage * complex_current.conjugate()).real
q = (complex_voltage * complex_current.conjugate()).imag
if (
complex_current.real != 0
): # Assume that unless ZIP is specifically specified only one of constant_power, constant_current and constant_impedance is used. A real part of 0 means that Z or P is being used instead.
phaseload.p = p
phaseload.q = q
phaseload.use_zip = 0
phaseload.model = (
5
) # The opendss model number (specifying constant current)
phaseloads.append(phaseload)
continue
except AttributeError:
pass

try:
base_power = float(obj["base_power"])
p = base_power
phaseload.p = p
except AttributeError:
pass
except ValueError:
data = obj["base_power"].split("*")
if data[0] in all_schedules:
phaseload.p = float(all_schedules[data[0]]) * float(
data[1]
)
if data[1] in all_schedules:
phaseload.p = float(all_schedules[data[1]]) * float(
data[0]
)

try:
# Require all six elements to compute the ZIP load model
current_fraction = float(obj["current_fraction"])
current_pf = float(obj["current_pf"])
power_fraction = float(obj["power_fraction"])
power_pf = float(obj["power_pf"])
impedance_fraction = float(obj["impedance_fraction"])
impedance_pf = float(obj["impedance_pf"])

phaseload.ppercentcurrent = current_fraction * current_pf
phaseload.qpercentcurrent = current_fraction * (
1 - current_pf
)
phaseload.ppercentpower = power_fraction * power_pf
phaseload.qpercentpower = power_fraction * (1 - power_pf)
phaseload.ppercentimpedance = (
impedance_fraction * impedance_pf
)
phaseload.qpercentimpedance = impedance_fraction * (
1 - impedance_pf
)
phaseload.use_zip = 1
except AttributeError:
pass

phaseloads.append(phaseload)


if num_phases > 0:
api_load.phase_loads = phaseloads
else:
import pdb;pdb.set_trace()


if obj_type == "fuse":
api_line = Line(model)
Expand Down Expand Up @@ -2185,12 +2327,12 @@ def parse(self, model, origin_datetime="2017 Jun 1 2:00PM"):
pass

try:
api_regulator.high_from = obj["from"]
api_regulator.from_element = obj["from"]
except AttributeError:
pass

try:
api_regulator.low_to = obj["to"]
api_regulator.to_element = obj["to"]
except AttributeError:
pass

Expand Down
69 changes: 67 additions & 2 deletions ditto/readers/opendss/read.py
Original file line number Diff line number Diff line change
Expand Up @@ -1235,6 +1235,7 @@ def parse_lines(self, model):
this_line_wireData_code = this_line_geometry["wire"]

# If empty, convert it to None
this_line_wireData = None
if this_line_wireData_code == "":
this_line_wireData_code = None

Expand All @@ -1253,8 +1254,6 @@ def parse_lines(self, model):
)
)
pass
else:
this_line_wireData = None

# If we have valid WireData
if this_line_wireData is not None:
Expand Down Expand Up @@ -1561,6 +1560,34 @@ def parse_transformers(self, model):
)
)

if (
N_windings >= 2
and data["conns"][0].lower() == "wye"
and data["conns"][1].lower() == "wye"
):
api_transformer.phase_shift = 0

if (
N_windings >= 2
and data["conns"][0].lower() == "delta"
and data["conns"][1].lower() == "delta"
):
api_transformer.phase_shift = 0

if (
N_windings >= 2
and data["conns"][0].lower() == "wye"
and data["conns"][1].lower() == "delta"
):
api_transformer.phase_shift = -30

if (
N_windings >= 2
and data["conns"][0].lower() == "delta"
and data["conns"][1].lower() == "wye"
):
api_transformer.phase_shift = -30

for w in range(N_windings):

windings.append(Winding(model))
Expand Down Expand Up @@ -1712,6 +1739,33 @@ def parse_regulators(self, model):

# Total number of windings
N_windings = int(trans["windings"])
if (
N_windings >= 2
and trans["conns"][0].lower() == "wye"
and trans["conns"][1].lower() == "wye"
):
api_regulator.phase_shift = 0

if (
N_windings >= 2
and trans["conns"][0].lower() == "delta"
and trans["conns"][1].lower() == "delta"
):
api_regulator.phase_shift = 0

if (
N_windings >= 2
and trans["conns"][0].lower() == "wye"
and trans["conns"][1].lower() == "delta"
):
api_regulator.phase_shift = -30

if (
N_windings >= 2
and trans["conns"][0].lower() == "delta"
and trans["conns"][1].lower() == "wye"
):
api_regulator.phase_shift = -30

# Initialize the list of Windings
api_regulator.windings = [Winding(model) for _ in range(N_windings)]
Expand All @@ -1725,6 +1779,13 @@ def parse_regulators(self, model):
]
except:
pass
try:
if trans["conns"][w].lower() == "wye":
api_regulator.windings[w].connection_type = "Y"
elif trans["conns"][w].lower() == "delta":
api_regulator.windings[w].connection_type = "D"
except:
pass

# nominal_voltage
for w in range(N_windings):
Expand Down Expand Up @@ -1799,6 +1860,10 @@ def parse_regulators(self, model):
api_regulator.windings[w].phase_windings[
p
].tap_position = float(trans["taps"][w])
if "TapNum" in data:
api_regulator.windings[w].phase_windings[
p
].tap_position = float(data["TapNum"])

# compensator_r
if "R" in data:
Expand Down
Loading