Skip to content

Commit 7fd76bd

Browse files
authored
Merge pull request #3 from DAI-Lab/angela-branch
merged! and removed the sim.json file (it was generated from a test but not needed)
2 parents 435110c + 3c739fe commit 7fd76bd

File tree

11 files changed

+451
-335
lines changed

11 files changed

+451
-335
lines changed

pygridsim/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,4 @@
66
__email__ = '[email protected]'
77
__version__ = '0.1.0.dev1'
88

9-
from pygridsim.core import PyGridSim
9+
from pygridsim.core import PyGridSim as PyGridSim

pygridsim/configs.py

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
from pygridsim.enums import LoadType, LineType, GeneratorType, SourceType
2+
import pygridsim.defaults as defaults
3+
4+
LOAD_CONFIGURATIONS = {
5+
LoadType.HOUSE: {
6+
"kV": defaults.HOUSE_KV,
7+
"kW": defaults.HOUSE_KW,
8+
"kvar": defaults.HOUSE_KVAR
9+
},
10+
LoadType.COMMERCIAL: {
11+
"kV": defaults.COMMERCIAL_KV,
12+
"kW": defaults.COMMERCIAL_KW,
13+
"kvar": defaults.COMMERCIAL_KVAR
14+
},
15+
LoadType.INDUSTRIAL: {
16+
"kV": defaults.INDUSTRIAL_KV,
17+
"kW": defaults.INDUSTRIAL_KW,
18+
"kvar": defaults.INDUSTRIAL_KVAR
19+
}
20+
}
21+
22+
SOURCE_CONFIGURATIONS = {
23+
SourceType.TURBINE: {
24+
"kV": defaults.TURBINE_BASE_KV
25+
},
26+
SourceType.POWER_PLANT: {
27+
"kV": defaults.POWER_PLANT_KV
28+
},
29+
SourceType.LV_SUBSTATION: {
30+
"kV": defaults.LV_SUBSTATION_BASE_KV
31+
},
32+
SourceType.MV_SUBSTATION: {
33+
"kV": defaults.MV_SUBSTATION_BASE_KV
34+
},
35+
SourceType.HV_SUBSTATION: {
36+
"kV": defaults.HV_SUBSTATION_BASE_KV
37+
},
38+
SourceType.SHV_SUBSTATION: {
39+
"kV": defaults.SHV_SUBSTATION_BASE_KV
40+
},
41+
}
42+
43+
LINE_CONFIGURATIONS = {
44+
LineType.LV_LINE: {
45+
"length": defaults.LV_LINE_LENGTH
46+
},
47+
LineType.MV_LINE: {
48+
"length": defaults.MV_LINE_LENGTH
49+
},
50+
LineType.HV_LINE: {
51+
"length": defaults.HV_LINE_LENGTH
52+
}
53+
}
54+
55+
GENERATOR_CONFIGURATIONS = {
56+
GeneratorType.SMALL: {
57+
"kV": defaults.SMALL_GEN_KV,
58+
"kW": defaults.SMALL_GEN_KW,
59+
},
60+
GeneratorType.LARGE: {
61+
"kV": defaults.LARGE_GEN_KV,
62+
"kW": defaults.LARGE_GEN_KW,
63+
},
64+
GeneratorType.INDUSTRIAL: {
65+
"kV": defaults.INDUSTRIAL_GEN_KV,
66+
"kW": defaults.INDUSTRIAL_GEN_KW,
67+
}
68+
}

pygridsim/core.py

Lines changed: 133 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -1,153 +1,190 @@
11
# -*- coding: utf-8 -*-
22
from altdss import altdss
3-
from altdss import AltDSS, Transformer, Vsource, Load, LoadModel, LoadShape
4-
from dss.enums import LineUnits, SolveModes
5-
from pygridsim.parameters import make_load_node, make_source_node
6-
from pygridsim.results import query_solution
7-
from pygridsim.lines import make_line
8-
from pygridsim.transformers import make_transformer
9-
from pygridsim.enums import LineType, SourceType, LoadType
3+
from pygridsim.parameters import _make_load_node, _make_source_node, _make_generator, _make_pv
4+
from pygridsim.results import _query_solution, _export_results
5+
from pygridsim.lines import _make_line
106

117
"""Main module."""
128

139
class PyGridSim:
1410
def __init__(self):
15-
"""
16-
Initialize OpenDSS/AltDSS engine. Creates an Empty Circuit
11+
"""Initialize OpenDSS engine.
12+
13+
Instantiate an OpenDSS circuit that user can build circuit components on. Stores numbers of circuit components
14+
to ensure unique naming of repeat circuit components
15+
16+
Attributes:
17+
num_loads (int): Number of loads in circuit so far.
18+
num_lines (int): Number of lines in circuit so far.
19+
num_transformers (int): Number of transformers in circuit so far.
20+
num_pv (int): Number of PV systems in circuit so far.
21+
num_generators (int): Number generators in circuit so far.
1722
"""
1823
self.num_loads = 0
19-
self.num_sources = 0
2024
self.num_lines = 0
2125
self.num_transformers = 0
26+
self.num_pv = 0
27+
self.num_generators = 0
2228
altdss.ClearAll()
2329
altdss('new circuit.MyCircuit')
2430

25-
def add_load_nodes(self, params = {}, load_type: LoadType = LoadType.HOUSE, num = 1):
26-
"""
27-
When the user wants to manually add nodes, or make nodes with varying parameters.
31+
def add_load_nodes(self, load_type: str = "house", params: dict[str, int] = None, num: int = 1):
32+
"""Adds Load Node(s) to circuit.
33+
34+
Allows the user to add num load nodes, either with customized parameters or using a default load_type.
2835
2936
Args:
30-
params: load parameters for these manual additions
31-
lines: which nodes these new loads are connected to
32-
num (optional): number of loads to create with these parameters
33-
Return:
34-
List of load_nodes
37+
load_type (str, optional):
38+
Load type as a string, one of "house", "commercial", "industrial". Defaults to "house".
39+
params (dict[str, int], optional):
40+
Load parameters for these manual additions. Defaults to empty dictionary.
41+
num (int, optional):
42+
The number of loads to create with these parameters. Defaults to 1.
43+
44+
Returns:
45+
list[OpenDSS object]:
46+
A list of OpenDSS objects representing the load nodes created.
3547
"""
48+
params = params or dict()
3649
load_nodes = []
37-
for i in range(num):
38-
make_load_node(params, load_type, self.num_loads)
50+
for _ in range(num):
51+
_make_load_node(params, load_type, self.num_loads)
3952
self.num_loads += 1
53+
4054
return load_nodes
4155

42-
def add_source_nodes(self, params = {}, source_type: SourceType = SourceType.TURBINE, num_in_batch = 1, num=1):
43-
"""
44-
When the user wants to manually add nodes, or make nodes with varying parameters.
56+
def update_source(self, source_type: str = "turbine", params: dict[str, int] = None):
57+
"""Adds or updates source node in system.
58+
59+
If a Vsource node does not exist, it is created. Otherwise, its parameters are updated based on the provided values.
4560
4661
Args:
47-
params: load parameters for these manual additions
48-
lines: which nodes these new sources are connected to
49-
num (optional): number of sources to create with these parameters (removed for now)
50-
num_in_batch: how many to batch together directly (so they can't be connected to lines separately, etc.
51-
most common use case is if a house has 20 solar panels it's more useful to group them together)
52-
Return:
53-
List of source_nodes
54-
"""
55-
source_nodes = []
56-
for i in range(num):
57-
make_source_node(params, source_type, count=self.num_sources, num_in_batch=num_in_batch)
58-
self.num_sources += 1
59-
return source_nodes
62+
source_type (str, optional):
63+
The type of the source (one of "turbine", "powerplant", "lvsub", "mvsub", "hvsub", "shvsub"). Defaults to "turbine".
64+
params (dict[str, int], optional):
65+
A dictionary of parameters to configure the source node. Defaults to None.
6066
61-
def add_lines(self, connections, line_type: LineType = LineType.LV_LINE, params = {}, transformer = True):
67+
Returns:
68+
OpenDSS object:
69+
The OpenDSS object representing the source node.
6270
"""
63-
Specify all lines that the user wants to add. If redundant lines, doesn't add anything
71+
params = params or dict()
72+
return _make_source_node(params, source_type)
6473

65-
Args:
66-
connections: a list of new connections to add. Each item of the list follows the form (source1, load1)
67-
TODO: allow the input to also contain optional parameters
68-
"""
69-
for src, dst in connections:
70-
make_line(src, dst, line_type, self.num_lines, params, transformer)
71-
self.num_lines += 1
74+
def add_PVSystem(self, load_nodes: list[str], params: dict[str, int] = None, num_panels: int = 1):
75+
"""Adds a photovoltaic (PV) system to the specified load nodes.
7276
73-
def add_transformers(self, connections, params = {}):
74-
"""
75-
Specify all transformers that the user wants to add, same input style as lines.
77+
Adds PV system with num_panels to each of the listed load nodes. Can be customized with parameters.
7678
7779
Args:
78-
connections: a list of new transformers to add (where to add them), with these params
79-
TODO: remove
80-
"""
81-
for src, dst in connections:
82-
make_transformer(src, dst, self.num_transformers, params)
83-
self.num_transformers += 1
84-
80+
load_nodes (list[str]):
81+
A list of node names where the PV system will be connected.
82+
params (dict[str, int], optional):
83+
A dictionary of additional parameters for the PV system. Defaults to None.
84+
num_panels (int, optional):
85+
The number of PV panels in the system. Defaults to 1.
8586
86-
def view_load_nodes(self, indices = []):
87+
Returns:
88+
list[DSS objects]:
89+
A list of OpenDSS objects representing the PV systems created.
8790
"""
88-
View load nodes (what their parameters are) at the given indices.
91+
params = params or dict()
92+
if not load_nodes:
93+
raise ValueError("Need to enter load nodes to add PVSystem to")
8994

95+
PV_nodes = []
96+
for load in load_nodes:
97+
PV_nodes.append(_make_pv(load, params, num_panels, self.num_pv))
98+
self.num_pv += 1
99+
100+
return PV_nodes
101+
102+
def add_generator(self, num: int = 1, gen_type: str = "small", params: dict[str, int] = None):
103+
"""Adds generator(s) to the system.
104+
90105
Args:
91-
indices (optional): Which indices to view the nodes at.
92-
If none given, display all
106+
num (int, optional):
107+
The number of generator units to add. Defaults to 1.
108+
gen_type (str, optional):
109+
The type of generator (one of "small", "large", "industrial"). Defaults to "small".
110+
params (dict[str, int], optional):
111+
A dictionary of parameters to configure the generator. Defaults to None.
112+
113+
Returns:
114+
list[DSS objects]:
115+
A list of OpenDSS objects representing the generators created.
93116
"""
94-
load_nodes = []
95-
if not indices:
96-
indices = [i for i in range(self.num_loads)]
97-
98-
for idx in indices:
99-
load_obj = altdss.Load["load" + str(idx)]
100-
load_info = {}
101-
load_info["name"] = "load" + str(idx)
102-
load_info["kV"] = load_obj.kV
103-
load_info["kW"] = load_obj.kW
104-
load_info["kVar"] = load_obj.kvar
105-
load_nodes.append(load_info)
106-
return load_nodes
117+
params = params or dict()
118+
generators = []
119+
for _ in range(num):
120+
generators.append(_make_generator(params, gen_type, count=self.num_generators))
121+
self.num_generators += 1
122+
123+
return generators
107124

108125

109-
def view_source_node(self):
110-
"""
111-
View source nodes (what their parameters are) at the given indices.
126+
def add_lines(self, connections: list[tuple], line_type: str = "lv", params: dict[str, int] = None, transformer: bool = True):
127+
"""Adds lines to the system.
128+
129+
Adds electrical lines according to the given connections. Users can specify the parameters of the lines or otherwise use given line type options.
112130
113131
Args:
114-
indices (optional): Which indices to view the nodes at.
115-
If none given, display all
116-
117-
TODO once capability for more source nodes is initialized
132+
connections (list[tuple]):
133+
A list of tuples defining the connections between nodes.
134+
line_type (str, optional):
135+
The type of line (one of "lv", "mv", "hv"). Defaults to "lv".
136+
params (dict[str, int], optional):
137+
A dictionary of parameters to configure the lines. Defaults to None.
138+
transformer (bool, optional):
139+
Whether to include a transformer in the connection. Defaults to True.
140+
141+
Returns:
142+
None
118143
"""
119-
source_obj = altdss.Vsource["source"]
120-
source_info = {}
121-
source_info["name"] = "source"
122-
source_info["kV"] = source_obj.BasekV
123-
return source_info
144+
params = params or dict()
145+
for src, dst in connections:
146+
_make_line(src, dst, line_type, self.num_lines, params, transformer)
147+
self.num_lines += 1
124148

125149
def solve(self):
126-
"""
127-
Initialize "solve" mode in AltDSS, then allowing the user to query various results on the circuit
150+
"""Solves the OpenDSS circuit.
151+
152+
Initializes "solve" mode in OpenDSS, which then allows the user to query results on the circuit.
128153
129-
TODO: error handling here
154+
Returns:
155+
None
130156
"""
131157
altdss.Solution.Solve()
132158

133-
def results(self, queries):
134-
"""
135-
Allow the user to query for many results at once instead of learning how to manually query
159+
def results(self, queries: list[str], export_path = ""):
160+
"""Gets simulation results based on specified queries.
161+
162+
Allows the user to query for many results at once by providing a list of desired queries.
163+
164+
Args:
165+
queries (list[str]):
166+
A list of queries to the circuit ("Voltages", "Losses", "TotalPower")
167+
export_path (str, optional):
168+
The file path to export results. If empty, results are not exported. Defaults to "".
136169
137170
Returns:
138-
Results for each query, in a dictionary
171+
dict:
172+
A dictionary containing the fetched simulation results.
139173
"""
140174
results = {}
141175
for query in queries:
142-
results[query] = query_solution(query)
176+
results[query] = _query_solution(query)
177+
178+
if (export_path):
179+
_export_results(results, export_path)
180+
143181
return results
144182

145183
def clear(self):
146-
"""
147-
Must call after we are done using the circuit, or will cause re-creation errors.
184+
"""Clears the OpenDSS circuit.
148185
149-
We only work with one circuit at a time, can only have one PyGridSim object at a time.
150-
TODO: maybe this isn't necessary because it's done in the beginning
186+
Returns:
187+
None
151188
"""
152189
altdss.ClearAll()
153190
self.num_loads = 0

0 commit comments

Comments
 (0)