Skip to content

Commit ded71ea

Browse files
committed
Merge remote-tracking branch 'origin/matpower-parser' into develop
2 parents 7b9669c + cbd1155 commit ded71ea

4 files changed

Lines changed: 679 additions & 0 deletions

File tree

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ lxml = "^5.3.0"
1919
opendssdirect-py = {extras = ["extras"], version = "^0.9.4"}
2020
jschon= {extras = ["requests"], version = "^0.11.1"}
2121
openpyxl = "^3.1.5"
22+
grg-mpdata = "^0.1.1"
2223

2324
[tool.poetry.group.dev.dependencies]
2425
pytest = "^8.3.3"

ravens/parsers/__init__.py

Whitespace-only changes.

ravens/parsers/itd2ravens.py

Lines changed: 219 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,219 @@
1+
import json
2+
import uuid
3+
4+
from ravens import RavensData
5+
6+
7+
def import_json(file):
8+
with open(file) as f:
9+
return json.load(f)
10+
11+
12+
# a similar function can be found on stackexchange
13+
14+
15+
def merge_dicts(dict1, dict2):
16+
"""
17+
Merges two nested dictionaries without overwriting any entries in the original dictionary.
18+
19+
Args:
20+
dict1 (dict): The original dictionary.
21+
dict2 (dict): The dictionary to be added to the original dictionary.
22+
23+
Returns:
24+
dict: The merged dictionary.
25+
"""
26+
result = dict1.copy()
27+
for key, value in dict2.items():
28+
if key in result and isinstance(result[key], dict) and isinstance(value, dict):
29+
result[key] = merge_dicts(result[key], value)
30+
else:
31+
result[key] = value
32+
return result
33+
34+
35+
# I used the AI portal to write this function
36+
37+
38+
def merge_TD(folder, t_ravens, d_dss, bd_json, feeder_name, merged_file_name, num_feeders):
39+
"""
40+
Right now, this looks like it can only handle a single feeder.
41+
The solution is to run this merge_TD for each distribution
42+
dss file. The first run should define t_ravens as the
43+
transmission RAVENS file (json). The subsequent runs should use the merged file for t_ravens.
44+
Note that, if this works, the transmission equipment and
45+
connectivity node keys should stay the same. For the
46+
distribution network, any keys which are also present
47+
in the transmission system will be appended with _d
48+
in the distribution feeder. For multinetwork, the keys
49+
for the second dist will have _d_d at the end, third
50+
_d_d_d, etc.
51+
"""
52+
dd = RavensData().import_dss(d_dss)
53+
dd.dump("temp_dd_file.json")
54+
dd_dict = import_json("temp_dd_file.json")
55+
56+
transmission_dict = import_json(t_ravens)
57+
58+
# This part of the function extracts all of the keys
59+
# from the distribution network and overwrites them
60+
# with identifiers
61+
62+
lines = []
63+
lines_keys = []
64+
try:
65+
lines = list(dd.iter["ACLineSegment"].keys())
66+
lines_keys = copy.deepcopy(lines)
67+
for line in range(len(lines)):
68+
lines[line] = "ACLineSegment::'" + lines[line] + "'"
69+
except:
70+
lines = []
71+
72+
trnfmrs = []
73+
trnfmrs_keys = []
74+
try:
75+
trnfmrs = list(dd.iter["PowerTransformer"].keys())
76+
trnfmrs_keys = copy.deepcopy(trnfmrs)
77+
for trn in range(len(trnfmrs)):
78+
trnfmrs[trn] = "PowerTransformer::'" + trnfmrs[trn] + "'"
79+
except:
80+
trnfmrs = []
81+
82+
nodes = list(dd.iter["ConnectivityNode"].keys())
83+
nodes_keys = list(dd.iter["ConnectivityNode"].keys())
84+
for bus in range(len(nodes)):
85+
nodes[bus] = "ConnectivityNode::'" + nodes[bus] + "'"
86+
87+
shunts = []
88+
shunts_keys = []
89+
try:
90+
shunts = list(dd.iter["LinearShuntCompensator"].keys())
91+
shunts_keys = copy.deepcopy(shunts)
92+
for shunt in range(len(shunts)):
93+
shunts[shunt] = "LinearShuntCompensator::'" + shunts[shunt] + "'"
94+
except:
95+
shunts = []
96+
97+
more_shunts = []
98+
more_shunts_keys = []
99+
try:
100+
more_shunts = list(dd.iter["ShuntCompensator"].keys())
101+
more_shunts_keys = copy.deepcopy(shunts)
102+
for shunt in range(len(more_shunts)):
103+
more_shunts[shunt] = "ShuntCompensator::'" + more_shunts[shunt] + "'"
104+
except:
105+
more_shunts = []
106+
107+
loads = []
108+
loads_keys = []
109+
try:
110+
loads = list(dd.iter["EnergyConsumer"].keys())
111+
loads_keys = copy.deepcopy(loads)
112+
for ld in range(len(loads)):
113+
loads[ld] = "EnergyConsumer::'" + loads[ld] + "'"
114+
except:
115+
loads = []
116+
117+
srcs = []
118+
srcs_keys = []
119+
try:
120+
srcs = list(dd.iter["EnergySource"].keys())
121+
srcs_keys = copy.deepcopy(srcs)
122+
for src in range(len(srcs)):
123+
srcs[src] = "EnergySource::'" + srcs[src] + "'"
124+
except:
125+
srcs = []
126+
127+
gens = []
128+
gens_keys = []
129+
try:
130+
gens = list(dd.iter["RotatingMachine"].keys())
131+
gens_keys = copy.deepcopy(gens)
132+
for gen in range(len(gens)):
133+
gens[gen] = "RotatingMachine::'" + gens[gen] + "'"
134+
except:
135+
gens = []
136+
137+
switches = []
138+
switch_keys = []
139+
try:
140+
switches = list(dd.iter["Switch"].keys())
141+
switch_keys = copy.deepcopy(switches)
142+
for switch in range(len(switches)):
143+
switches[switch] = "Switch::'" + switches[switch] + "'"
144+
except:
145+
switches = []
146+
print(switches)
147+
148+
batteries = []
149+
battery_keys = []
150+
try:
151+
batteries = list(dd.iter["PowerElectronicsConnection"].keys())
152+
battery_keys = copy.deepcopy(gens)
153+
for battery in range(len(batteries)):
154+
batteries[battery] = "PowerElectronicsConnection::'" + batteries[battery] + "'"
155+
except:
156+
batteries = []
157+
158+
the_feeder = {
159+
feeder_name: {
160+
"Ravens.cimObjectType": "Feeder",
161+
"IdentifiedObject.mRID": str(uuid.uuid4()),
162+
"IdentifiedObject.name": "the_feeder",
163+
"ConnectivityNodeContainer.ConnectivityNodes": nodes,
164+
"EquipmentContainer.Equipments": lines + trnfmrs + shunts + loads + srcs + gens + batteries + switches + more_shunts, # TODO: add other equipments as encountered (routine)
165+
}
166+
}
167+
168+
itd_dict = merge_dicts(transmission_dict, dd_dict)
169+
170+
itd_dict.update(the_feeder)
171+
172+
bndry = import_json(bd_json)
173+
174+
# pulls the bus where the voltage source is located
175+
dist_bus = dd_dict["PowerSystemResource"]["Equipment"]["ConductingEquipment"]["EnergyConnection"]["EnergySource"]["source"]["ConductingEquipment.Terminals"][0]["Terminal.ConnectivityNode"]
176+
print("the distribution bus is ", dist_bus)
177+
energy_src = dd_dict["PowerSystemResource"]["Equipment"]["ConductingEquipment"]["EnergyConnection"]["EnergySource"]["source"]
178+
179+
# create a line for each boundary connection
180+
181+
# current_num_lines = len(itd_dict['PowerSystemResource']['Equipment']['ConductingEquipment']['Conductor']['ACLineSegment'])
182+
current_num_lines = 0
183+
bd_lines = {}
184+
for bd in range(len(bndry)):
185+
bdl = {
186+
"line_bd_"
187+
+ str(bd + 1 + current_num_lines): {
188+
"Ravens.cimObjectType": "ACLineSegment",
189+
"IdentifiedObject.mRID": str(uuid.uuid4()),
190+
"IdentifiedObject.name": "line_bd_" + str(bd + 1),
191+
"Equipment.inService": True,
192+
"ACLineSegment.r": energy_src["EnergySource.r"],
193+
"ACLineSegment.x": energy_src["EnergySource.x"],
194+
"ConductingEquipment.Terminals": [
195+
{
196+
"Ravens.cimObjectType": "Terminal",
197+
"IdentifiedObject.mRID": str(uuid.uuid4()),
198+
"IdentifiedObject.name": "line_bd_" + str(bd + 1 + current_num_lines) + "_T",
199+
"ACDCTerminal.sequenceNumber": 1,
200+
"Terminal.ConnectivityNode": "ConnectivityNode::'" + bndry[bd]["transmission_boundary"] + "'",
201+
},
202+
{
203+
"Ravens.cimObjectType": "Terminal",
204+
"IdentifiedObject.mRID": str(uuid.uuid4()),
205+
"IdentifiedObject.name": "line_bd_" + str(bd + 1 + current_num_lines) + "_D",
206+
"ACDCTerminal.sequenceNumber": 2,
207+
"Terminal.ConnectivityNode": dist_bus,
208+
},
209+
],
210+
}
211+
}
212+
bd_lines.update(bdl)
213+
214+
# add them to the itd_dict
215+
216+
itd_dict["PowerSystemResource"]["Equipment"]["ConductingEquipment"]["Conductor"]["ACLineSegment"].update(bd_lines)
217+
218+
with open(folder + "/" + merged_file_name + ".json", "w") as fp:
219+
json.dump(itd_dict, fp, indent=2)

0 commit comments

Comments
 (0)