Skip to content

Commit 2e01a71

Browse files
authored
Add OpenDss export example (#25)
Signed-off-by: vince <vince.white@zepben.com>
1 parent 478bd41 commit 2e01a71

File tree

2 files changed

+126
-1
lines changed

2 files changed

+126
-1
lines changed

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
package_dir={'': 'src'},
2121
python_requires='>=3.9, <3.13',
2222
install_requires=[
23-
"zepben.eas==0.17.1",
23+
"zepben.eas==0.19.0",
2424
"zepben.evolve==0.48.0",
2525
"numba==0.60.0",
2626
"geojson==2.5.0",
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
# Copyright 2025 Zeppelin Bend Pty Ltd
2+
#
3+
# This Source Code Form is subject to the terms of the Mozilla Public
4+
# License, v. 2.0. If a copy of the MPL was not distributed with this
5+
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
6+
from datetime import datetime
7+
8+
from zepben.eas.client.opendss import OpenDssConfig
9+
from zepben.eas.client.work_package import GeneratorConfig, ModelConfig, LoadPlacement, FeederScenarioAllocationStrategy, SolveConfig, RawResultsConfig, \
10+
MeterPlacementConfig, SwitchMeterPlacementConfig, SwitchClass
11+
from zepben.eas import EasClient, TimePeriod
12+
from time import sleep
13+
import requests
14+
15+
16+
def wait_for_export(eas_client: EasClient, model_id: int):
17+
# Wait for OpenDss model export to complete
18+
wait_limit_seconds = 3000
19+
step_seconds = 2
20+
total = 0
21+
print(f"Waiting for model generation ({wait_limit_seconds} seconds) ", end='')
22+
# Retrieve the model information for the model we just requested
23+
model = eas_client.get_opendss_model(model_id)
24+
while model["state"] != "COMPLETED":
25+
model = eas_client.get_opendss_model(model_id)
26+
print(".", end='')
27+
sleep(step_seconds)
28+
total += step_seconds
29+
if total > wait_limit_seconds:
30+
raise TimeoutError("Timed out waiting for model export to complete.")
31+
32+
33+
def download_generated_model(eas_client: EasClient, output_file_name: str, model_id: int):
34+
url = eas_client.get_opendss_model_download_url(model_id)
35+
if url == f'Model with id {model_id} is still being created':
36+
print(url)
37+
print("Download failed.")
38+
return
39+
40+
print(f"\nURL (30 second expiry): {url}", )
41+
42+
file_name = f"{output_file_name}-{model_id}.zip"
43+
print(f"Downloading model zip to: {file_name}")
44+
45+
try:
46+
with open(file_name, mode="wb") as file:
47+
file.write(requests.get(url).content)
48+
print("Download complete.")
49+
except Exception as error:
50+
print("Download failed.")
51+
print(error)
52+
53+
54+
def test_open_dss_export(export_file_name: str):
55+
eas_client = EasClient(
56+
"<EAS_HOSTNAME>",
57+
443,
58+
access_token="<PERSONAL_ACCESS_TOKEN>"
59+
)
60+
61+
# Run an opendss export
62+
print("Sending OpenDss model export request to EAS")
63+
64+
response = eas_client.run_opendss_export(
65+
OpenDssConfig(
66+
scenario="Base",
67+
year=2024,
68+
feeder="<FEEDER_ID>",
69+
load_time=TimePeriod(
70+
datetime.strptime("2024-04-01T00:00:00", "%Y-%m-%dT%H:%M:%S"),
71+
datetime.strptime("2025-04-01T00:00:00", "%Y-%m-%dT%H:%M:%S")
72+
),
73+
generator_config=GeneratorConfig(
74+
model=ModelConfig(
75+
meter_placement_config=MeterPlacementConfig(
76+
feeder_head=True,
77+
dist_transformers=True,
78+
switch_meter_placement_configs=[SwitchMeterPlacementConfig(
79+
meter_switch_class=SwitchClass.DISCONNECTOR,
80+
name_pattern=".*Circuit Head Switch.*"
81+
)]
82+
),
83+
vmax_pu=1.2,
84+
vmin_pu=0.8,
85+
p_factor_base_exports=-1,
86+
p_factor_base_imports=1,
87+
p_factor_forecast_pv=0.98,
88+
fix_single_phase_loads=True,
89+
max_single_phase_load=15000.0,
90+
max_load_service_line_ratio=1.0,
91+
max_load_lv_line_ratio=2.0,
92+
max_load_tx_ratio=2.0,
93+
max_gen_tx_ratio=4.0,
94+
fix_overloading_consumers=True,
95+
fix_undersized_service_lines=True,
96+
feeder_scenario_allocation_strategy=FeederScenarioAllocationStrategy.ADDITIVE,
97+
closed_loop_v_reg_enabled=True,
98+
closed_loop_v_reg_set_point=0.9825,
99+
seed=123,
100+
),
101+
solve=SolveConfig(step_size_minutes=30.0),
102+
raw_results=RawResultsConfig(True, True, True, True, True)
103+
),
104+
model_name=export_file_name,
105+
is_public=True
106+
)
107+
)
108+
print(f"Raw 'run_opendss_export' response: '{response}'")
109+
model_id = response["data"]["createOpenDssModel"]
110+
print(f"New OpenDss model export id: {model_id}")
111+
112+
try:
113+
wait_for_export(eas_client, int(model_id))
114+
115+
# Request a download URL from EAS and download to a local file
116+
download_generated_model(eas_client, export_file_name, int(model_id))
117+
118+
except TimeoutError:
119+
print("\nERROR: Timed out waiting for model export to complete.")
120+
121+
eas_client.close()
122+
123+
124+
if __name__ == "__main__":
125+
test_open_dss_export("test_export-model")

0 commit comments

Comments
 (0)