Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
39 changes: 25 additions & 14 deletions gridappsd-python-lib/gridappsd/simulation.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,13 @@ def asdict(self):
for k, v in self.__dict__.items():
if isinstance(v, ConfigBase):
built[k] = v.asdict()
elif isinstance(v, list):
built[k] = []
for item in v:
if isinstance(item, ConfigBase):
built[k].append(item.asdict())
else:
built[k].append(item)
else:
built[k] = v
return built
Expand All @@ -49,17 +56,20 @@ class ModelCreationConfig(ConfigBase):

@dataclass
class SimulationArgs(ConfigBase):
start_time: str = field(default="1655321830")
duration: str = field(default="300")
simulator: str = field(default="GridLAB-D")
timestep_frequency: str = field(default="1000")
timestep_increment: str = field(default="1000")
run_realtime: bool = field(default=True)
pause_after_measurements: bool = field(default=False)
simulation_name: str = field(default="ieee13nodeckt")
power_flow_solver_method: str = field(default="NR")
model_creation_config: ModelCreationConfig = field(default_factory=ModelCreationConfig)

start_time: str = field(default = "1655321830")
duration: str = field(default = "300")
timestep_frequency: str = field(default = "1000")
timestep_increment: str = field(default = "1000")
run_realtime: bool = field(default = True)
pause_after_measurements: bool = field(default = False)
simulation_name: str = field(default = "ieee13nodeckt")


@dataclass
class SimulatorArgs(ConfigBase):
simulator: str = field(default = "GridLAB-D")
model_creation_config: ModelCreationConfig = field(default_factory = ModelCreationConfig)
power_flow_solver_method: str = field(default = "NR")

# __default_simulation_args__ = SimulationArgs()

Expand Down Expand Up @@ -94,13 +104,14 @@ class ServiceConfig(ConfigBase):
@dataclass
class PowerSystemConfig(ConfigBase):
Line_name: str
GeographicalRegion_name: str | None = field(default=None)
SubGeographicalRegion_name: str | None = field(default=None)
GeographicalRegion_name: str = field(default = None)
SubGeographicalRegion_name: str = field(default = None)
simulator_config: SimulatorArgs = field(default_factory=SimulatorArgs)


@dataclass
class SimulationConfig(ConfigBase):
power_system_config: PowerSystemConfig
power_system_configs: list[PowerSystemConfig] = field(default_factory=list)
application_configs: list[ApplicationConfig] = field(default_factory=list)
simulation_config: SimulationArgs = field(default_factory=SimulationArgs)
service_configs: list[ServiceConfig] = field(default_factory=list)
Expand Down
97 changes: 59 additions & 38 deletions gridappsd-python-lib/tests/test_simulation.py
Original file line number Diff line number Diff line change
@@ -1,43 +1,64 @@
# import json
# # from pprint import pprint
# import logging
# import os
# import sys
# import time
# import pytest
import json
import logging
import os
import sys
import time
import pytest
from datetime import datetime, timezone

# logging.basicConfig(stream=sys.stdout, level=logging.DEBUG)
logging.basicConfig(stream=sys.stdout, level=logging.DEBUG)

# from gridappsd import GridAPPSD, topics as t
# from gridappsd.simulation import Simulation
from gridappsd import GridAPPSD, topics as t
from gridappsd.simulation import Simulation, PowerSystemConfig, SimulationArgs, SimulationConfig

# # The directory containing this file
# HERE = os.path.dirname(__file__)
simulation_is_complete = False
measurements_received = 0

# def base_config():
# data = {"power_system_config":{"SubGeographicalRegion_name":"_ABEB635F-729D-24BF-B8A4-E2EF268D8B9E","GeographicalRegion_name":"_73C512BD-7249-4F50-50DA-D93849B89C43","Line_name":"_49AD8E07-3BF9-A4E2-CB8F-C3722F837B62"},"simulation_config":{"power_flow_solver_method":"NR","duration":120,"simulation_name":"ieee13nodeckt","simulator":"GridLAB-D","start_time":1605418946,"run_realtime":False,"simulation_output":{},"model_creation_config":{"load_scaling_factor":1.0,"triplex":"y","encoding":"u","system_frequency":60,"voltage_multiplier":1.0,"power_unit_conversion":1.0,"unique_names":"y","schedule_name":"ieeezipload","z_fraction":0.0,"i_fraction":1.0,"p_fraction":0.0,"randomize_zipload_fractions":False,"use_houses":False},"simulation_broker_port":51044,"simulation_broker_location":"127.0.0.1"},"application_config":{"applications":[]},"service_configs":[],"test_config":{"randomNum":{"seed":{"value":185213303967438},"nextNextGaussian":0.0,"haveNextNextGaussian":False},"events":[],"testInput":True,"testOutput":True,"appId":"","testId":"1468836560","testType":"simulation_vs_expected","storeMatches":False},"simulation_request_type":"NEW"}
# # with open("{HERE}/simulation_fixtures/13_node_2_min_base.json".format(HERE=HERE)) as fp:
# # data = json.load(fp)
# return data
@pytest.fixture
def createGadObject():
gad_user = os.environ.get('GRIDAPPSD_USER')
if gad_user is None:
os.environ['GRIDAPPSD_USER'] = 'system'
gad_password = os.environ.get('GRIDAPPSD_PASSWORD')
if gad_password is None:
os.environ['GRIDAPPSD_PASSWORD'] = 'manager'
return GridAPPSD()

# def test_simulation_no_duplicate_measurement_timestamps(gridappsd_client: GridAPPSD):
# num_measurements = 0
# timestamps = set()

# def measurement(sim, timestamp, measurement):
# nonlocal num_measurements
# num_measurements += 1
# assert timestamp not in timestamps
# timestamps.add(timestamp)

# gapps = gridappsd_client
# sim = Simulation(gapps, base_config())
# sim.add_onmeasurement_callback(measurement)
# sim.start_simulation()
# sim.run_loop()

# # did we get a measurement?
# assert num_measurements > 0

# # if empty then we know the simulation did not work.
# assert timestamps
def test_createSimulations(createGadObject):
gadObj = createGadObject
response = gadObj.query_model_info()
models = response.get("data", {}).get("models", {})
start_time = int(datetime(year=2025, month=1, day=1, hour=0, minute=0, second=0, microsecond=0, tzinfo=timezone.utc).timestamp())
simulationArgs = SimulationArgs(start_time=f"{start_time}",
duration="120",
run_realtime=False,
pause_after_measurements=False)
sim_config = SimulationConfig(simulation_config=simulationArgs)
modelsToRun = [
"49AD8E07-3BF9-A4E2-CB8F-C3722F837B62", # IEEE 13 Node Test Feeder
"C1C3E687-6FFD-C753-582B-632A27E28507" # IEEE 123 Node Test Feeder
]
for m in models:
if m.get("modelId") not in modelsToRun:
continue
line_name = m.get("modelId")
subregion_name = m.get("subRegionId")
region_name = m.get("regionId")
psc = PowerSystemConfig(Line_name=line_name,
SubGeographicalRegion_name=subregion_name,
GeographicalRegion_name=region_name)
sim_config.power_system_configs.append(psc)
sim_obj = Simulation(gapps=gadObj, run_config=sim_config)
def on_measurement(sim, ts, m):
global measurements_received
measurements_received += 1
def on_simulation_complete(sim):
global simulation_is_complete
simulation_is_complete = True
sim_obj.add_onmeasurement_callback(on_measurement)
sim_obj.add_oncomplete_callback(on_simulation_complete)
sim_obj.start_simulation()
while not simulation_is_complete:
time.sleep(1)
assert measurements_received == 1
gadObj.disconnect()
Loading