Skip to content
Draft
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
14 changes: 7 additions & 7 deletions docs/docs/creating_and_uploading_studies.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,9 @@ ec_geojson = []
Now, we will create a `Result` object named "Energy Consumers" with a GeoJSON overlay. The GeoJSON overlay includes the collected GeoJSON features in a `FeatureCollection` and a style named "ec-heatmap".

```python
ec_result = Result(
ec_result = StudyResultInput(
name="Energy Consumers",
geo_json_overlay=GeoJsonOverlay(
geoJsonOverlay=GeoJsonOverlayInput(
data=FeatureCollection(ec_geojson),
styles=["ec-heatmap"] # Select which Mapbox layers to show for this result
)
Expand Down Expand Up @@ -154,9 +154,9 @@ lv_lines_geojson = []
Now, we will create a `Result` object named "LV Lines" with a GeoJSON overlay. The GeoJSON overlay includes the collected GeoJSON features in a FeatureCollection.

```python
lv_lines_result = Result(
lv_lines_result = StudyResultInput(
name="LV Lines",
geo_json_overlay=GeoJsonOverlay(
geoJsonOverlay=GeoJsonOverlayInput(
data=FeatureCollection(lv_lines_geojson),
styles=["lv-lines", "lv-lengths"] # Select which Mapbox layers to show for this result
)
Expand Down Expand Up @@ -231,7 +231,7 @@ Once you have created the Results for the studies, the next step is to create an
A data class (`Study`) represents an Evolve App Server study. The user need to provide information such as name, descriptions, tags, results, and styles to successfully create a study.

```python
study = Study(
study = StudyInput(
name="Example Study",
description="Example study with two results.",
tags=["example"],
Expand All @@ -253,8 +253,8 @@ Note: Each layer may have an entry in the legend via the metadata["zb:legend"] f
The final step after creating the study is to upload it on the EAS and close the EAS client, as follows.

```python
await eas_client.async_upload_study(study)
await eas_client.aclose()
await eas_client.upload_study(study)
await eas_client.close()
```

## Output (Studies)
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ authors = [
{name = "Zeppelin Bend", email = "oss@zepben.com"}
]
dependencies = [
"zepben.eas==0.27.0b1",
"zepben.eas==1.0.0b1",
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

todo: Doesn't seem to exist, is this incorrect, or is there another PR that needs to be merged first?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, sorted it out. This is blocked by zepben/eas-client-python#58

"zepben.ewb==1.1.0b14",
"numba==0.60.0",
"geojson==2.5.0",
Expand Down
122 changes: 70 additions & 52 deletions src/zepben/examples/export_open_dss_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,9 @@
import json
from datetime import datetime

from zepben.eas.client.opendss import OpenDssConfig
from zepben.eas.client.work_package import GeneratorConfig, ModelConfig, FeederScenarioAllocationStrategy, SolveConfig, RawResultsConfig, \
MeterPlacementConfig, SwitchMeterPlacementConfig, SwitchClass
from zepben.eas import EasClient, TimePeriod, FixedTime
from zepben.eas import EasClient, OpenDssModelInput, OpenDssModulesConfigInput, OpenDssModelGenerationSpecInput, OpenDssModelOptionsInput, \
OpenDssCommonConfigInput, HcGeneratorConfigInput, TimePeriodInput, FixedTimeInput, HcModelConfigInput, HcSolveConfigInput, HcNodeLevelResultsConfigInput, \
HcRawResultsConfigInput, HcMeterPlacementConfigInput, HcSwitchMeterPlacementConfigInput, HcSwitchClass, HcFeederScenarioAllocationStrategy
from time import sleep
import requests

Expand Down Expand Up @@ -69,62 +68,81 @@ def open_dss_export(export_file_name: str):
eas_client = EasClient(
host=c["host"],
port=c["rpc_port"],
access_token=c["access_token"]
access_token=c["access_token"],
)

# Run an opendss export
print("Sending OpenDss model export request to EAS")

response = eas_client.run_opendss_export(
OpenDssConfig(
scenario="base",
year=2025,
feeder="<FEEDER_MRID>",
load_time=TimePeriod(
start_time=datetime.fromisoformat("2024-04-01T00:00"),
end_time=datetime.fromisoformat("2025-04-01T00:00")
),
# For fixed time export example, pass load_time a FixedTime object
#load_time=FixedTime(
# time=datetime.fromisoformat("2024-04-01T00:00")
#),
generator_config=GeneratorConfig(
model=ModelConfig(
meter_placement_config=MeterPlacementConfig(
feeder_head=True,
dist_transformers=True,
# Include meters for any switch that has a name that starts with 'LV Circuit Head' and is a Fuse or Disconnector
switch_meter_placement_configs=[SwitchMeterPlacementConfig(
meter_switch_class=SwitchClass.DISCONNECTOR,
name_pattern="LV Circuit Head.*"
), SwitchMeterPlacementConfig(
meter_switch_class=SwitchClass.FUSE,
name_pattern="LV Circuit Head.*"
)]
),
load_vmax_pu=1.2,
load_vmin_pu=0.8,
p_factor_base_exports=-1,
p_factor_base_imports=1,
p_factor_forecast_pv=0.98,
fix_single_phase_loads=True,
max_single_phase_load=15000.0,
max_load_service_line_ratio=1.0,
max_load_lv_line_ratio=2.0,
max_load_tx_ratio=2.0,
max_gen_tx_ratio=4.0,
fix_overloading_consumers=True,
fix_undersized_service_lines=True,
feeder_scenario_allocation_strategy=FeederScenarioAllocationStrategy.ADDITIVE,
closed_loop_v_reg_enabled=True,
closed_loop_v_reg_set_point=0.9825,
seed=123,
OpenDssModelInput(
generationSpec=OpenDssModelGenerationSpecInput(
modelOptions=OpenDssModelOptionsInput(
scenario="base",
year=2025,
feeder="<FEEDER_MRID>",
),
solve=SolveConfig(step_size_minutes=30.0),
raw_results=RawResultsConfig(True, True, True, True, True)
modulesConfiguration=OpenDssModulesConfigInput(
common=OpenDssCommonConfigInput(
timePeriod=TimePeriodInput(
startTime=datetime.fromisoformat("2024-04-01T00:00"),
endTime=datetime.fromisoformat("2025-04-01T00:00")
),
# For fixed time export example, pass load_time a FixedTimeInput object
# fixedTime=FixedTimeInput(
# loadTime=datetime.fromisoformat("2024-04-01T00:00")
# )
),
generator=HcGeneratorConfigInput(
model=HcModelConfigInput(
meterPlacementConfig=HcMeterPlacementConfigInput(
feederHead=True,
distTransformers=True,
# Include meters for any switch that has a name that starts with 'LV Circuit Head' and is a Fuse or Disconnector
switchMeterPlacementConfigs=[
HcSwitchMeterPlacementConfigInput(
meterSwitchClass=HcSwitchClass.DISCONNECTOR,
namePattern="LV Circuit Head.*"
), HcSwitchMeterPlacementConfigInput(
meterSwitchClass=HcSwitchClass.FUSE,
namePattern="LV Circuit Head.*"
)
]
),
loadVMaxPu=1.2,
loadVMinPu=0.8,
pFactorBaseExports=-1,
pFactorBaseImports=1,
pFactorForecastPv=0.98,
fixSinglePhaseLoads=True,
maxSinglePhaseLoad=15000.0,
maxLoadServiceLineRatio=1.0,
maxLoadLvLineRatio=2.0,
maxLoadTxRatio=2.0,
maxGenTxRatio=4.0,
fixOverloadingConsumers=True,
fixUndersizedServiceLines=True,
feederScenarioAllocationStrategy=HcFeederScenarioAllocationStrategy.ADDITIVE,
closedLoopVRegEnabled=True,
closedLoopVRegSetPoint=0.9825,
seed=123,

),
solve=HcSolveConfigInput(
stepSizeMinutes=30
),
rawResults=HcRawResultsConfigInput(
energyMetersRaw=True,
energyMeterVoltagesRaw=True,
overloadsRaw=True,
resultsPerMeter=True,
voltageExceptionsRaw=True,
),
),
)
),
model_name=export_file_name,
is_public=True
isPublic=True,
modelName=export_file_name,
)
)
print(f"Raw 'run_opendss_export' response: '{response}'")
Expand Down
20 changes: 10 additions & 10 deletions src/zepben/examples/request_feeder_load_analysis_study.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import asyncio
import sys

from zepben.eas.client.feeder_load_analysis_input import FeederLoadAnalysisInput
from zepben.eas import FeederLoadAnalysisInput

from zepben.examples.utils import get_config_dir, get_client

Expand All @@ -18,18 +18,18 @@ async def main(argv):
eas_client = get_client(config_dir)
print("Connection established..")
# Fire off a feeder load analysis study
feeder_load_analysis_token = await eas_client.async_run_feeder_load_analysis_report(
feeder_load_analysis_token = await eas_client.run_feeder_load_analysis_report(
FeederLoadAnalysisInput(
feeders=["feeder1", "feeder2"],
substations=None,
sub_geographical_regions=None,
geographical_regions=None,
start_date="2022-04-01",
end_date="2022-12-31",
fetch_lv_network=True,
process_feeder_loads=True,
process_coincident_loads=True,
aggregate_at_feeder_level=False,
subGeographicalRegions=None,
geographicalRegions=None,
startDate="2022-04-01",
endDate="2022-12-31",
fetchLvNetwork=True,
processFeederLoads=True,
processCoincidentLoads=True,
aggregateAtFeederLevel=False,
output="Test"
)
)
Expand Down
25 changes: 12 additions & 13 deletions src/zepben/examples/request_forecast_feeder_load_analysis_study.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@
import asyncio
import sys

from zepben.eas.client.feeder_load_analysis_input import FeederLoadAnalysisInput
from zepben.eas.client.fla_forecast_config import FlaForecastConfig
from zepben.eas import FeederLoadAnalysisInput, FlaForecastConfigInput

from zepben.examples.utils import get_config_dir, get_client

Expand All @@ -22,18 +21,18 @@ async def main(argv):
feeder_load_analysis_token = await eas_client.async_run_feeder_load_analysis_report(
FeederLoadAnalysisInput(
feeders=["feeder1", "feeder2"],
start_date="2022-04-01",
end_date="2022-12-31",
fetch_lv_network=True,
process_feeder_loads=True,
process_coincident_loads=True,
aggregate_at_feeder_level=False,
startDate="2022-04-01",
endDate="2022-12-31",
fetchLvNetwork=True,
processFeederLoads=True,
processCoincidentLoads=True,
aggregateAtFeederLevel=False,
output="Test",
fla_forecast_config=FlaForecastConfig(
scenario_id='1',
flaForecastConfig=FlaForecastConfigInput(
scenarioID='1',
year=2029,
pv_upgrade_threshold=6500, ##Premise with existing PV will gain additional PV until the threshold wattage is reached.
bess_upgrade_threshold=6500, ##Premise with existing battery will gain additional battery until the threshold wattage is reached.
pvUpgradeThreshold=6500, ##Premise with existing PV will gain additional PV until the threshold wattage is reached.
bessUpgradeThreshold=6500, ##Premise with existing battery will gain additional battery until the threshold wattage is reached.
seed=12345 ##Seed can be set to keep modification of forecast network consistent between studies.
)
)
Expand All @@ -43,7 +42,7 @@ async def main(argv):

# Feeder Load Analysis Study results can be retrieved from back end storage set up with EAS.

await eas_client.aclose()
await eas_client.close()


if __name__ == "__main__":
Expand Down
31 changes: 21 additions & 10 deletions src/zepben/examples/studies/creating_and_uploading_study.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import json

from geojson import Feature, LineString, FeatureCollection, Point
from zepben.eas import Study, Result, GeoJsonOverlay, EasClient
from zepben.eas import StudyInput, StudyResultInput, GeoJsonOverlayInput, EasClient, Mutation
from zepben.ewb import AcLineSegment, EnergyConsumer, connect_with_token, NetworkConsumerClient, IncludedEnergizedContainers
# A study is a geographical visualisation of data that is drawn on top of the network.
# This data is typically the result of a load flow simulation.
Expand All @@ -24,7 +24,12 @@
async def main():
# Fetch network model from Energy Workbench's gRPC service (see ../connecting_to_grpc_service.py for examples on different connection functions)
print("Connecting to EWB..")
grpc_channel = connect_with_token(host=c["host"], access_token=c["access_token"], rpc_port=c["rpc_port"])
grpc_channel = connect_with_token(
host=c["host"],
access_token=c["access_token"],
rpc_port=c["rpc_port"]
)

feeder_mrid = "WD24"
grpc_client = NetworkConsumerClient(grpc_channel)
print("Connection established..")
Expand All @@ -43,9 +48,9 @@ async def main():
)
ec_geojson.append(ec_feature)

ec_result = Result(
ec_result = StudyResultInput(
name="Energy Consumers",
geo_json_overlay=GeoJsonOverlay(
geoJsonOverlay=GeoJsonOverlayInput(
data=FeatureCollection(ec_geojson),
styles=["ec-heatmap"] # Select which Mapbox layers to show for this result
)
Expand All @@ -64,16 +69,16 @@ async def main():
)
lv_lines_geojson.append(line_feature)

lv_lines_result = Result(
lv_lines_result = StudyResultInput(
name="LV Lines",
geo_json_overlay=GeoJsonOverlay(
geoJsonOverlay=GeoJsonOverlayInput(
data=FeatureCollection(lv_lines_geojson),
styles=["lv-lines", "lv-lengths"] # Select which Mapbox layers to show for this result
)
)

# Create and upload the study.
study = Study(
study = StudyInput(
name="Example Study",
description="Example study with two results.",
tags=["example"], # Tags make it easy to search for studies in a large list of them.
Expand All @@ -84,16 +89,22 @@ async def main():
)
print("Study created..")
print("Connecting to EAS..")
eas_client = EasClient(host=c["host"], port=c["rpc_port"], protocol="https", access_token=c["access_token"])
eas_client = EasClient(
host=c["host"],
port=c["rpc_port"],
protocol="https",
access_token=c["access_token"],
asynchronous=True
)

print("Connection established..")

print("Uploading study...")
response = await eas_client.async_upload_study(study)
response = await eas_client.mutation(Mutation.add_studies([study]))
print(response)
print("Study uploaded! Please check the Evolve Web App.")

await eas_client.aclose()
await eas_client.close()


if __name__ == "__main__":
Expand Down
Loading
Loading