Skip to content

Commit e76faf6

Browse files
David P. Chassinaivanova5snyk-bot
authored
Release 4.3.7 (#171)
Signed-off-by: David P. Chassin <dchassin@slac.stanford.edu> Signed-off-by: Alyona Teyber <Ivanova.alyona5@gmail.com> Signed-off-by: David P. Chassin <david.chassin@me.com> Co-authored-by: Alyona Teyber <Ivanova.alyona5@gmail.com> Co-authored-by: snyk-bot <snyk-bot@snyk.io>
1 parent abf328d commit e76faf6

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

67 files changed

+5136
-23
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
pandas>=1.3.5
2+
numpy>=1.22.2 # not directly required, pinned by Snyk to avoid a vulnerability

converters/Makefile.mk

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ dist_pkgdata_DATA += converters/mdb-table2glm-player.py
3131
# omd -> glm
3232
dist_pkgdata_DATA += converters/omd2glm.py
3333

34+
# py->glm
35+
dist_pkgdata_DATA += converters/py2glm.py
36+
3437
# tmy3 -> glm
3538
dist_pkgdata_DATA += converters/tmy32glm.py
3639

converters/autotest/.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,5 @@ solver_nr_profile.csv
99
table2glm_input_noclass.glm
1010
table2glm_input_noname.glm
1111
table2glm_input.glm
12+
pypower_casedata.py
13+
pypower_results.py

converters/csv-ami2glm-player.py

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,19 @@ def write_player(file, obj, node_ID, phase) :
5050
file.write('object player {\n')
5151
file.write('\tparent "' + obj + '";\n')
5252
file.write('\tfile "' + os.path.join(folder_name,str(node_ID)) + '.csv";\n')
53-
file.write(f'\tproperty constant_power_{phase};\n')
53+
for p in phase :
54+
file.write(f'\tproperty constant_power_{p};\n')
5455
file.write('}\n')
5556

57+
def filter_dict_by_min_value(input_dict, patterns):
58+
result_dict = {}
59+
for pattern in patterns:
60+
pattern_dictionary = {key: value for key, value in input_dict.items() if pattern in key}
61+
min_value = min(pattern_dictionary.values())
62+
min_dict = {key: value for key, value in pattern_dictionary.items() if value == min_value}
63+
result_dict.update(min_dict)
64+
return list(result_dict.keys())
65+
5666
def convert(input_files, output_file, options={}):
5767

5868
if type(input_files) is dict:
@@ -106,6 +116,8 @@ def convert(input_files, output_file, options={}):
106116
df.to_csv(os.path.join(folder_name,os.path.basename(output_file)), index=False)
107117
elif os.path.splitext(output_file)[1]=='.glm' :
108118
phase_dict = {}
119+
load_list = {}
120+
load_list_filtered = {}
109121
with open(output_file, mode='w') as file :
110122
file.write('module tape;\n')
111123

@@ -114,11 +126,27 @@ def convert(input_files, output_file, options={}):
114126
continue
115127
for obj,val in network["objects"].items() :
116128
if "load" in val["class"] and node_ID in obj:
117-
node_phase = ''.join([x for x in 'ABC' if x in val['phases']])
129+
volts = float(val['nominal_voltage'].split(' ')[0])
130+
if 'k' in val['nominal_voltage'].split(' ')[1] :
131+
load_list[obj] = volts*1000
132+
elif 'M' in val['nominal_voltage'].split(' ')[1] :
133+
load_list[obj] = volts*1000000
134+
else :
135+
load_list[obj] = volts
136+
load_phase = ''.join([x for x in 'ABC' if x in val['phases']])
137+
phase_dict[node_ID]=load_phase
138+
139+
140+
# Grabbing only loads on the low side of the Transformer
141+
load_list_filtered = filter_dict_by_min_value(load_list,node_ID_set)
142+
for load_ID in load_list_filtered :
143+
for obj, val in network["objects"].items() :
144+
if load_ID==obj :
145+
load_phase = ''.join([x for x in 'ABC' if x in val['phases']])
118146
parent = val["parent"]
119-
phase_dict[node_ID]=node_phase
120-
for p in node_phase :
121-
write_player(file, obj, node_ID, p)
147+
for node_ID in node_ID_set :
148+
if node_ID in load_ID :
149+
write_player(file, obj, node_ID, load_phase)
122150

123151
new_column_names = {
124152
'reading_dttm': 'timestamp',

converters/py2glm.py

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
import json
2+
import os
3+
import sys, getopt
4+
import datetime
5+
import importlib, copy
6+
from importlib import util
7+
8+
9+
config = {"input":"py","output":"glm","type":["pypower"]}
10+
11+
def help():
12+
return """py2glm.py -i <inputfile> -o <outputfile> [options...]
13+
-c|--config output converter configuration data
14+
-h|--help output this help
15+
-i|--ifile <filename> [REQUIRED] PY input file
16+
-o|--ofile <filename> [OPTIONAL] GLM output file name
17+
-t|--type type of input file
18+
-N|--name do not autoname objects
19+
"""
20+
21+
def main():
22+
filename_py = None
23+
filename_glm = None
24+
py_type = 'pypower'
25+
autoname = True
26+
try :
27+
opts, args = getopt.getopt(sys.argv[1:],
28+
"chi:o:t:N",
29+
["config","help","ifile=","ofile=","type=","name"],
30+
)
31+
except getopt.GetoptError:
32+
sys.exit(2)
33+
if not opts :
34+
print('ERROR [py2glm.py]: missing command arguments')
35+
sys.exit(2)
36+
for opt, arg in opts:
37+
if opt in ("-c","--config"):
38+
print(config)
39+
sys.exit()
40+
elif opt in ("-h","--help"):
41+
print(help())
42+
sys.exit()
43+
elif opt in ("-i", "--ifile"):
44+
filename_py = arg
45+
elif opt in ("-o", "--ofile"):
46+
filename_glm = arg
47+
elif opt in ("-t", "--type"):
48+
py_type = arg
49+
elif opt in ("-N","--name"):
50+
autoname = False
51+
else :
52+
print(f"ERROR [py2glm.py]: {opt}={arg} is not a valid option")
53+
sys.exit(1)
54+
55+
if not filename_py:
56+
print(f"ERROR [py2glm.py]: input filename not specified")
57+
sys.exit(1)
58+
59+
try:
60+
convert(
61+
ifile = filename_py,
62+
ofile = filename_glm,
63+
options = dict(
64+
py_type = py_type,
65+
autoname = autoname),
66+
)
67+
except Exception as err:
68+
print(f"ERROR [py2glm.py]: {err}")
69+
import traceback
70+
traceback.print_exception(err,file=sys.stderr)
71+
sys.exit(9)
72+
73+
def convert(ifile,ofile,options={}):
74+
"""Default converter is pypower case"""
75+
76+
py_type = options['py_type'] if 'py_type' in options else "pypower"
77+
autoname = options['autoname'] if 'autoname' in options else True
78+
79+
assert(py_type in ['pypower'])
80+
81+
modspec = util.spec_from_file_location("glm",ifile)
82+
modname = os.path.splitext(ifile)[0]
83+
mod = importlib.import_module(os.path.basename(modname))
84+
casedef = getattr(mod,os.path.basename(modname))
85+
data = casedef()
86+
87+
NL='\n'
88+
with open(ofile,"w") as glm:
89+
glm.write(f"""// generated by {' '.join(sys.argv)}
90+
module pypower
91+
{{
92+
version {data['version']};
93+
baseMVA {data['baseMVA']};
94+
}}
95+
""")
96+
97+
for name,spec in dict(
98+
# pypower properties must be in the save order as the case array columns
99+
bus = "bus_i type Pd Qd Gs Bs area Vm Va baseKV zone Vmax Vmin",
100+
gen = "bus Pg Qg Qmax Qmin Vg mBase status Pmax Pmin Pc1 Pc2 Qc1min"\
101+
+ " Qc1max Qc2min Qc2max ramp_agc ramp_10 ramp_30 ramp_q apf",
102+
branch = "fbus tbus r x b rateA rateB rateC ratio angle status angmin angmax",
103+
).items():
104+
glm.write(f"{NL}//{NL}// {name}{NL}//{NL}")
105+
for n,line in enumerate(data[name]):
106+
oname = f"{NL} name pp_{name}_{n+1};" if autoname else ""
107+
glm.write(f"""object pypower.{name}
108+
{{{oname}
109+
{NL.join([f" {x} {line[n]};" for n,x in enumerate(spec.split())])}
110+
}}
111+
""")
112+
if 'gencost' in data:
113+
glm.write("\n//\n// gencost\n//\n")
114+
for n,line in enumerate(data['gencost']):
115+
model = line[0]
116+
startup = line[1]
117+
shutdown = line[2]
118+
count = line[3]
119+
costs = line[4:]
120+
assert(len(costs)==count)
121+
oname = f"{NL} name pp_gencost_{n};" if autoname else ""
122+
glm.write(f"""object pypower.gencost
123+
{{{oname}
124+
model {int(model)};
125+
startup {startup};
126+
shutdown {shutdown};
127+
costs "{','.join([str(x) for x in costs])}";
128+
}}
129+
""")
130+
131+
if __name__ == '__main__':
132+
main()
133+
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
[[/Converters/Import/Ami_data]] -- AMI data import
2+
3+
# Synopsis
4+
5+
GLM:
6+
7+
~~~
8+
#input "casefile.py" -t pypower [-N|--name]
9+
~~~
10+
11+
Shell:
12+
13+
~~~
14+
$ gridlabd convert -i inputfile.py -o outputfile.glm -t pypower [-N|--name]
15+
~~~
16+
17+
# Description
18+
19+
The `py2glm.py` converter support conversion of PyPower case files to GLM
20+
models. The `-N|--name` option suppresses autonaming of PyPower objects.
21+
22+
# See also
23+
24+
* [[/Module/Pypower]]

0 commit comments

Comments
 (0)