Skip to content

Commit f80f352

Browse files
committed
Merge branch 'main' into packaging
2 parents e7b922b + f7ea1cc commit f80f352

File tree

6 files changed

+115
-17
lines changed

6 files changed

+115
-17
lines changed

pygridsim/core.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ def __init__(self):
2020
self.num_lines = 0
2121
self.num_transformers = 0
2222
altdss.ClearAll()
23-
#altdss('new circuit.IEEE13Nodeckt')
2423
altdss('new circuit.MyCircuit')
2524

2625
def add_load_nodes(self, params = {}, load_type: LoadType = LoadType.HOUSE, num = 1):

pygridsim/defaults.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,4 +67,11 @@
6767
NUM_WINDINGS = 2
6868
XHL = 2
6969
PRIMARY_CONN = Connection.delta
70-
SECONDARY_CONN = Connection.wye
70+
SECONDARY_CONN = Connection.wye
71+
72+
"""
73+
Valid parameter lists
74+
"""
75+
VALID_LOAD_PARAMS = ["kV", "kW", "kVar", "phases"]
76+
VALID_SOURCE_PARAMS = ["kV", "phases", "frequency"]
77+
VALID_LINE_TRANSFORMER_PARAMS = ["length", "XHL", "Conns"]

pygridsim/lines.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from altdss import altdss
22
from altdss import Transformer, Connection
33
import pygridsim.defaults as defaults
4-
from pygridsim.parameters import get_param, random_param
4+
from pygridsim.parameters import get_param, random_param, check_valid_params
55
from dss.enums import LineUnits
66

77
def make_line(src, dst, line_type, count, params = {}, transformer = True):
@@ -15,13 +15,17 @@ def make_line(src, dst, line_type, count, params = {}, transformer = True):
1515
Returns:
1616
Line object that was created
1717
"""
18+
check_valid_params(params, defaults.VALID_LINE_TRANSFORMER_PARAMS)
1819
line = altdss.Line.new('line' + str(count))
1920
line.Phases = defaults.PHASES
2021
line.Length = get_param(params, "length", random_param(line_type.value))
2122
line.Bus1 = src
2223
line.Bus2 = dst
2324
line.Units = LineUnits.km
2425

26+
if (line.Length) < 0:
27+
raise ValueError("Cannot have negative length")
28+
2529
if not transformer:
2630
return
2731

@@ -33,4 +37,4 @@ def make_line(src, dst, line_type, count, params = {}, transformer = True):
3337
transformer.Buses = [src, dst]
3438
transformer.Conns = get_param(params, "Conns", [defaults.PRIMARY_CONN, defaults.SECONDARY_CONN])
3539
transformer.kVs = [altdss.Vsource[src].BasekV, altdss.Load[dst].kV]
36-
transformer.end_edit()
40+
transformer.end_edit()

pygridsim/parameters.py

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,12 @@ def get_param(params, name, default):
3131
else:
3232
return default
3333

34+
def check_valid_params(params, valid_params):
35+
# Invalid parameter handling
36+
for param in params:
37+
if param not in valid_params:
38+
raise KeyError(f"Parameter {param} is not supported")
39+
3440
def make_load_node(load_params, load_type, count):
3541
"""
3642
Make a load node with the parmeters given, filling in with defaults for
@@ -44,13 +50,18 @@ def make_load_node(load_params, load_type, count):
4450
Return:
4551
load object
4652
"""
53+
check_valid_params(load_params, defaults.VALID_LOAD_PARAMS)
54+
4755
load : Load = altdss.Load.new('load' + str(count))
4856
load.Bus1 = 'load' + str(count)
4957
load.Phases = get_param(load_params, "phases", defaults.PHASES)
5058
load.kV = get_param(load_params, "kV", random_param(load_type.value["kV"]))
5159
load.kW = get_param(load_params, "kW", random_param(load_type.value["kW"]))
5260
load.kvar = get_param(load_params, "kVar", random_param(load_type.value["kVar"]))
5361
load.Daily = 'default'
62+
63+
if (load.kV) < 0:
64+
raise ValueError("Cannot have negative voltage in load")
5465
return load
5566

5667
def make_source_node(source_params, source_type, count, num_in_batch = 1):
@@ -70,11 +81,15 @@ def make_source_node(source_params, source_type, count, num_in_batch = 1):
7081
TODO: There is a whole set of other vsource properties to set, like impedance and resistance
7182
https://github.com/dss-extensions/AltDSS-Python/blob/2b6fa7e5961cedaf8482c07d377b20bdab4a1bee/altdss/Vsource.py#L694
7283
"""
84+
check_valid_params(source_params, defaults.VALID_SOURCE_PARAMS)
85+
7386
source = altdss.Vsource[0]
74-
#source = altdss.Vsource['source' + str(count)]
75-
#source: Vsource = altdss.Vsource.new('source' + str(count))
7687
source.Bus1 = 'source'
7788
source.Phases = get_param(source_params, "phases", defaults.PHASES)
7889
source.BasekV = get_param(source_params, "kV", num_in_batch*random_param(source_type.value))
7990
source.Frequency = get_param(source_params, "frequency", defaults.FREQUENCY)
91+
92+
if (source.BasekV) < 0:
93+
raise ValueError("Cannot have negative voltage in source")
94+
8095
return source

pygridsim/results.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,12 @@ def query_solution(query):
2121
bus_vmags[bus_name] = float(bus_vmag)
2222
return bus_vmags
2323
case "Losses":
24-
# Currently has some minimal value like e-13, because there is no transformer
25-
return altdss.Losses()
24+
# Parse it to output active power loss, reactive power loss, instead of just complex number.
25+
vector_losses = altdss.Losses()
26+
losses = {}
27+
losses["Active Power Loss"] = vector_losses.real
28+
losses["Reactive Power Loss"] = vector_losses.imag
29+
return losses
2630
case "TotalPower":
2731
return altdss.TotalPower()
2832
case _:

tests/test_circuit.py

Lines changed: 78 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -28,16 +28,16 @@ def tearDown(self):
2828
"""Tear down test fixtures, if any."""
2929
#altdss.ClearAll()
3030

31-
def test_00_basic(self):
31+
def test_000_basic(self):
3232
circuit = PyGridSim()
3333
circuit.add_source_nodes()
3434
circuit.add_load_nodes()
3535
circuit.add_lines([("source", "load0")])
3636
circuit.solve()
37-
print(circuit.results(["BusVMag"]))
37+
print(circuit.results(["Voltages"]))
3838
circuit.clear()
3939

40-
def test_01_one_source_one_load(self):
40+
def test_001_one_source_one_load(self):
4141
circuit = PyGridSim()
4242
circuit.add_source_nodes(source_type=SourceType.TURBINE)
4343
circuit.add_load_nodes(num=1, load_type=LoadType.HOUSE)
@@ -49,7 +49,7 @@ def test_01_one_source_one_load(self):
4949
print(circuit.results(["Voltages", "Losses"]))
5050
circuit.clear()
5151

52-
def test_02_one_source_one_load_no_transformer(self):
52+
def test_002_one_source_one_load_no_transformer(self):
5353
# doesn't throw error, but should have stranger output VMag
5454
circuit = PyGridSim()
5555
circuit.add_source_nodes(source_type=SourceType.TURBINE)
@@ -59,7 +59,7 @@ def test_02_one_source_one_load_no_transformer(self):
5959
print(circuit.results(["Voltages", "Losses"]))
6060
circuit.clear()
6161

62-
def test_03_one_source_one_load_exhaustive(self):
62+
def test_003_one_source_one_load_exhaustive(self):
6363
for line_type in LineType:
6464
for source_type in SourceType:
6565
for load_type in LoadType:
@@ -73,7 +73,7 @@ def test_03_one_source_one_load_exhaustive(self):
7373
circuit.clear()
7474

7575

76-
def test_04_one_source_multi_load(self):
76+
def test_004_one_source_multi_load(self):
7777
circuit = PyGridSim()
7878
circuit.add_source_nodes(num_in_batch=10, source_type=SourceType.SOLAR_PANEL)
7979
circuit.add_load_nodes(num=4, load_type=LoadType.HOUSE)
@@ -82,15 +82,15 @@ def test_04_one_source_multi_load(self):
8282
print(circuit.results(["Voltages"]))
8383
circuit.clear()
8484

85-
def test_05_bad_query(self):
85+
def test_005_bad_query(self):
8686
circuit = PyGridSim()
8787
circuit.add_source_nodes()
8888
circuit.add_load_nodes()
8989
circuit.add_lines([("source", "load0")])
9090
circuit.solve()
9191
print(circuit.results(["BadQuery"]))
9292

93-
def test_06_multi_source_bad(self):
93+
def test_006_multi_source_bad(self):
9494
circuit = PyGridSim()
9595
#circuit.add_source_nodes(num_in_batch=10, num=2, source_type=SourceType.SOLAR_PANEL)
9696
#circuit.add_load_nodes(num=1, load_type=LoadType.HOUSE)
@@ -106,8 +106,77 @@ class TestCustomizedCircuit(unittest.TestCase):
106106

107107
def setUp(self):
108108
"""Set up test fixtures, if any."""
109+
print("\nTest", self._testMethodName)
110+
111+
112+
def tearDown(self):
113+
"""Tear down test fixtures, if any."""
109114
pass
110115

116+
def test_100_one_source_one_load(self):
117+
circuit = PyGridSim()
118+
circuit.add_source_nodes(params={"kV": 100})
119+
circuit.add_load_nodes(num=1, params={"kV": 10, "kW": 20, "kVar":1})
120+
circuit.add_lines([("source", "load0")], params={"length": 20})
121+
circuit.solve()
122+
print(circuit.results(["Voltages", "Losses"]))
123+
circuit.clear()
124+
125+
def test_100_one_source_multi_load(self):
126+
"""
127+
Creates 10 loads, some of which are connected to source. all loads and lines here have the same params
128+
"""
129+
circuit = PyGridSim()
130+
circuit.add_source_nodes(params={"kV": 100})
131+
circuit.add_load_nodes(num=10, params={"kV": 10, "kW": 20, "kVar":1})
132+
circuit.add_lines([("source", "load0"), ("source", "load4"), ("source", "load6")], params={"length": 20})
133+
circuit.solve()
134+
print(circuit.results(["Voltages", "Losses"]))
135+
circuit.clear()
136+
137+
def test_101_bad_parameter(self):
138+
"""
139+
Should error with a bad parameter and tell the user which parameter is bad
140+
"""
141+
circuit = PyGridSim()
142+
with self.assertRaises(KeyError):
143+
circuit.add_source_nodes(params={"kV": 50, "badParam": 100})
144+
145+
def test_102_negative_inputs(self):
146+
"""
147+
Should error with negative kv or negative length
148+
"""
149+
circuit = PyGridSim()
150+
151+
with self.assertRaises(Exception):
152+
# openDSS has its own exception for this case
153+
circuit.add_load_nodes(params={"kV": -1})
154+
155+
with self.assertRaises(ValueError):
156+
circuit.add_source_nodes(params={"kV": -1})
157+
158+
# properly add load and source, then create invalid line
159+
with self.assertRaises(ValueError):
160+
circuit.add_lines([("source", "load0")], params={"length": -100})
161+
162+
def test_103_invalid_nodes_in_line(self):
163+
circuit = PyGridSim()
164+
circuit.add_load_nodes()
165+
circuit.add_source_nodes()
166+
with self.assertRaises(ValueError):
167+
# only has source, load0 for now but tries to add another one
168+
circuit.add_lines([("source", "load5")])
169+
170+
171+
class TestLargeCircuit(unittest.TestCase):
172+
"""
173+
Test very large circuit (i.e. to the size of a neighborhood)
174+
"""
175+
def setUp(self):
176+
"""Set up test fixtures, if any."""
177+
print("\nTest", self._testMethodName)
178+
179+
111180
def tearDown(self):
112181
"""Tear down test fixtures, if any."""
113-
pass
182+
pass

0 commit comments

Comments
 (0)