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
53 changes: 35 additions & 18 deletions docs/docs/creating_and_uploading_studies.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,17 @@ Hence, you should ensure that both the servers are running for this example. Gui

## Getting Started

Ensure that you have installed the required dependencies and imported the libraries. For this example, we will use `json`, `geojson`, `zepben.eas` and `zepben.evolve` libraries.
Ensure that you have installed the required dependencies and imported the libraries. For this example, we will use `json`, `geojson`, `zepben.eas` and `zepben.ewb` libraries.
Information about connecting to the Energy Workbench Server can be found in the [Connecting to the EWB Server](connecting-to-ewb.mdx) tutorial.


```python
import json
from geojson import Feature, LineString, FeatureCollection, Point
from zepben.eas import Study, Result, GeoJsonOverlay, EasClient
from zepben.evolve import connect_with_token, NetworkConsumerClient, AcLineSegment, EnergyConsumer
from zepben.protobuf.nc.nc_requests_pb2 import INCLUDE_ENERGIZED_LV_FEEDERS
from zepben.eas import StudyInput, StudyResultInput, GeoJsonOverlayInput, Mutation
from zepben.ewb import AcLineSegment, EnergyConsumer, connect_with_token, NetworkConsumerClient, IncludedEnergizedContainers

from zepben.examples.utils import eas_client_from_config
```

## Connecting to the EWB gRPC Service
Expand All @@ -35,32 +36,44 @@ Here, we connect to the EWB Server, using the `connect_with_token` function.

```python
with open("../config.json") as f:
c = json.loads(f.read())
_config = json.loads(f.read())
c_ewb = _config["ewb"]
c_eas = _config["eas"]

channel = connect_with_token(host=c["host"], access_token=c["access_token"], rpc_port=c["rpc_port"])
channel = connect_with_token(**c_ewb)

```
You will need to replace the values in the config.json file with the appropriate configuration for your environment. The config file should look like this:
You will need to replace the values in the config.json file with the appropriate configuration for your environment. The config file has separate `ewb` and `eas` sections - each section's keys are passed straight through as kwargs to the matching client, so they must match its constructor args. It should look like this:

```json
{
"host": "EWB Hostname",
"access_token": "your_access_token",
"rpc_port": 1234
"ewb": {
"host": "EWB Hostname",
"rpc_port": 1234,
"ca_filename": null,
"access_token": "your_access_token"
},
"eas": {
"host": "EAS Hostname",
"port": 1234,
"protocol": "https",
"ca_filename": null,
"access_token": "your_access_token"
}
}
```
More information about connecting to the EWB Server using different methods can be found in the [Connecting to the EWB Server](connecting-to-ewb.mdx) tutorial.

You will need to specify the mRID of the feeder that you want to fetch, ensuring that the feeder with the specified mRID exists.
Then, create a `NetworkConsumerClient` and retrieve the network service.
The `get_equipment_container` method is used to fetch information about the specified feeder (feeder_mrid).
The `INCLUDE_ENERGIZED_LV_FEEDERS` flag indicates that the client should include information about energized LV (Low Voltage) feeders in the response.
The `IncludedEnergizedContainers.LV_FEEDERS` flag indicates that the client should include information about energized LV (Low Voltage) feeders in the response.


```python
feeder_mrid = "LV007"
grpc_client = NetworkConsumerClient(grpc_channel)
await grpc_client.get_equipment_container(feeder_mrid, include_energized_containers=INCLUDE_ENERGIZED_LV_FEEDERS)
await grpc_client.get_equipment_container(feeder_mrid, include_energized_containers=IncludedEnergizedContainers.LV_FEEDERS)
network = grpc_client.service
```

Expand All @@ -70,15 +83,15 @@ We use the `EasClient` to connect to the Evolve App Server. `EasClient` is a cla
For the examples in this tutorial, we will use the following code to connect to the EAS.

```python
eas_client = EasClient(host=c["host"], port=c["rpc_port"], protocol="https", access_token=c["access_token"])
eas_client = eas_client_from_config(c_eas, asynchronous=True)
```

- **host** - The domain of the Evolve App Server, e.g. "evolve.local"
- **port** - The port on which to make requests to the Evolve App Server, e.g. 7624
- **access_token** - The personal access token you generated from the UI.
- **protocol** - The protocol to use for connecting to EAS. Either http or https.

Note: Ensure that the values for host, port, and token are correctly provided in the config.json file.
Note: Ensure that the values for host, port, and token are correctly provided in the `eas` section of the config.json file.

## Create Results for Energy Consumers Density Example

Expand Down Expand Up @@ -107,7 +120,8 @@ ec_result = StudyResultInput(
geoJsonOverlay=GeoJsonOverlayInput(
data=FeatureCollection(ec_geojson),
styles=["ec-heatmap"] # Select which Mapbox layers to show for this result
)
),
sections=[]
)
```

Expand Down Expand Up @@ -159,7 +173,8 @@ lv_lines_result = StudyResultInput(
geoJsonOverlay=GeoJsonOverlayInput(
data=FeatureCollection(lv_lines_geojson),
styles=["lv-lines", "lv-lengths"] # Select which Mapbox layers to show for this result
)
),
sections=[]
)
```

Expand Down Expand Up @@ -228,7 +243,7 @@ The following styles are used for "lv_lines" and "lv_lengths". Note that you wil
## Create and Upload Studies

Once you have created the Results for the studies, the next step is to create and upload the study on EAS.
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.
A data class (`StudyInput`) 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 = StudyInput(
Expand All @@ -253,7 +268,9 @@ 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.upload_study(study)
response = await eas_client.mutation(Mutation.add_studies([study]))
print(response)

await eas_client.close()
```

Expand Down
2 changes: 1 addition & 1 deletion docs/docs/network_model_ingest.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ Folder naming and internal file formatting is customer-specific - Zepben will pr

## Part 2: Running the ingestion kick-off script

Once your model folder is in place, run the example script to trigger the ingest. It first connects to the Evolve App Server using an `EasClient`, built from the same `config.json` values (`eas_host`, `eas_port`, `eas_protocol`, `access_token`, etc.) used throughout the other EAS examples. See [Creating and Uploading Studies](creating_and_uploading_studies.mdx) for a breakdown of these connection values.
Once your model folder is in place, run the example script to trigger the ingest. It first connects to the Evolve App Server using an `EasClient`, built from the `eas` section of `config.json` (`host`, `port`, `protocol`, `access_token`, etc.) used throughout the other EAS examples. See [Creating and Uploading Studies](creating_and_uploading_studies.mdx) for a breakdown of these connection values.

It then triggers the ingest via `Mutation.execute_ingestor`, passing an `IngestorConfigInput` with `key="dataStorePath"` and `value` set to your folder name from Part 1. `run_config` is a list, so more key/value pairs can be added if Zepben provides other ingestor configuration options for your environment.

Expand Down
5 changes: 3 additions & 2 deletions src/zepben/examples/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
from pathlib import Path

# root dir of repo if cloned
CONFIG_DIR = f"{Path(__file__).parent.parent.parent.parent}/"
# Directory this package lives in, i.e. src/zepben/examples, which is where config.json
# is expected to live (see utils.py::get_client and the various scripts that open "config.json").
CONFIG_DIR = f"{Path(__file__).parent}/"
5 changes: 2 additions & 3 deletions src/zepben/examples/all_ratings_csv.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,9 @@ class EquipmentWithRating:

def _get_client():
with open('config.json') as f:
c = json.load(f)
c = json.load(f)['ewb']

# Connect to server
channel = connect_with_token(host=c["host"], access_token=c["access_token"], rpc_port=c["rpc_port"])
channel = connect_with_token(**c)
return NetworkConsumerClient(channel)


Expand Down
4 changes: 2 additions & 2 deletions src/zepben/examples/cim/extract_hv_customers.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@
from zepben.examples import CONFIG_DIR

with open(f"{CONFIG_DIR}/config.json") as f:
c = json.loads(f.read())
c = json.loads(f.read())["ewb"]


async def extract_hv_customers_for_feeder(feeder_mrid: str):
channel = connect_with_token(host=c["host"], access_token=c["access_token"], rpc_port=c["rpc_port"], ca_filename=c["ca_path"])
channel = connect_with_token(**c)
network_client = NetworkConsumerClient(channel=channel)
network = network_client.service

Expand Down
4 changes: 2 additions & 2 deletions src/zepben/examples/cim/extract_lv_substations.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@
from zepben.examples import CONFIG_DIR

with open(f"{CONFIG_DIR}/config.json") as f:
c = json.loads(f.read())
c = json.loads(f.read())["ewb"]


async def extract_lv_substations_for_feeder(feeder_mrid: str):
channel = connect_with_token(host=c["host"], access_token=c["access_token"], rpc_port=c["rpc_port"], ca_filename=c["ca_path"])
channel = connect_with_token(**c)
network_client = NetworkConsumerClient(channel=channel)
network = network_client.service

Expand Down
4 changes: 2 additions & 2 deletions src/zepben/examples/cim/extract_per_phase_wire_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@
from zepben.examples import CONFIG_DIR

with open(f"{CONFIG_DIR}/config.json") as f:
c = json.loads(f.read())
c = json.loads(f.read())["ewb"]


async def extract_wire_info_per_phase(feeder_mrid: str):
channel = connect_with_token(host=c["host"], rpc_port=c["rpc_port"], access_token=c["access_token"], ca_filename=c["ca_path"])
channel = connect_with_token(**c)
network_client = NetworkConsumerClient(channel=channel)
network = network_client.service
(await network_client.get_equipment_container(feeder_mrid,
Expand Down
8 changes: 2 additions & 6 deletions src/zepben/examples/connecting_to_grpc_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,14 +114,10 @@ async def connect_using_token():
from zepben.ewb import connect_with_token, NetworkConsumerClient

with open("config.json") as f:
c = json.load(f)
c = json.load(f)["ewb"]

print("Connecting to EWB..")
channel = connect_with_token(
host=c["host"],
access_token=c["access_token"],
rpc_port=c["rpc_port"]
)
channel = connect_with_token(**c)
client = NetworkConsumerClient(channel)
print("Connection established..")
print("Printing network hierarchy..")
Expand Down
2 changes: 1 addition & 1 deletion src/zepben/examples/current_state_manipulations.py
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ async def main():

# noinspection PyTypeChecker
with open('config.json') as f:
config = json.load(f)
config = json.load(f)['ewb']
async with connect_with_token(**config) as secure_channel:
await run_simple(NetworkConsumerClient(secure_channel))
await run_swap_feeder(NetworkConsumerClient(secure_channel))
Expand Down
4 changes: 2 additions & 2 deletions src/zepben/examples/dsub_from_nmi.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@


with open("config.json") as f:
c = json.loads(f.read())
c = json.loads(f.read())["ewb"]


def _trace(start_item, results, stop_condition):
Expand All @@ -44,7 +44,7 @@ def step_action(step: NetworkTraceStep, context: StepContext):


async def main(mrid: str, feeder_mrid: str):
channel = connect_with_token(host=c["host"], access_token=c["access_token"], rpc_port=c["rpc_port"])
channel = connect_with_token(**c)
client = NetworkConsumerClient(channel)
await client.get_equipment_container(feeder_mrid, include_energized_containers=IncludedEnergizedContainers.LV_FEEDERS)
network = client.service
Expand Down
13 changes: 8 additions & 5 deletions src/zepben/examples/element_network_hierarchy.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@

"""
For every piece of `ConductingEquipment` downstream of a feeder, records a row with its equipment type,
nominal voltage, length (where applicable), and the nearest upstream fuse, distribution transformer,
regulator and breaker mrid — so an `element_id` can be related back to its measurement zones.
nominal voltage, length (where applicable), and the nearest upstream protection device (fuse or LV
circuit breaker), distribution transformer, regulator and breaker mrid — so an `element_id` can be
related back to its measurement zones.
"""
import asyncio
import json
Expand All @@ -24,7 +25,7 @@

def _get_client() -> NetworkConsumerClient:
with open('config.json') as f:
config = json.load(f)
config = json.load(f)['ewb']
return NetworkConsumerClient(connect_with_token(**config))


Expand All @@ -35,7 +36,7 @@ def _build_row(equip: ConductingEquipment, upstream: dict) -> dict:
'element_type': type(equip).__name__,
'nominal_voltage': equip.base_voltage_value,
'length': getattr(equip, 'length', None) if isinstance(equip, Conductor) else None,
'upstream_fuse_mrid': getattr(upstream.get('upstream_fuse'), 'mrid', None),
'upstream_protection_device_mrid': getattr(upstream.get('upstream_protection_device'), 'mrid', None),
'distribution_power_transformer_mrid': getattr(upstream.get('distribution_power_transformer'), 'mrid', None),
'regulator_mrid': getattr(upstream.get('regulator'), 'mrid', None),
'breaker_mrid': getattr(upstream.get('breaker'), 'mrid', None),
Expand Down Expand Up @@ -63,8 +64,10 @@ def compute_next_value(self, next_item: NetworkTraceStep, current_item: NetworkT
equip = next_item.path.to_equipment
if isinstance(equip, Breaker):
upstream['breaker'] = equip
if equip.base_voltage_value is not None and equip.base_voltage_value <= 1000:
upstream['upstream_protection_device'] = equip
elif isinstance(equip, Fuse):
upstream['upstream_fuse'] = equip
upstream['upstream_protection_device'] = equip
elif isinstance(equip, PowerTransformer):
if equip.function == TransformerFunctionKind.distributionTransformer:
upstream['distribution_power_transformer'] = equip
Expand Down
3 changes: 1 addition & 2 deletions src/zepben/examples/energy_consumer_device_hierarchy.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,8 @@ class EnergyConsumerDeviceHierarchy:

def _get_client():
with open('config.json') as f:
config = json.load(f)
config = json.load(f)['ewb']

# Connect to server
channel = connect_with_token(**config)
return NetworkConsumerClient(channel)

Expand Down
11 changes: 4 additions & 7 deletions src/zepben/examples/export_open_dss_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,10 @@
from time import sleep
import requests

from zepben.examples.utils import eas_client_from_config

with open("config.json") as f:
c = json.loads(f.read())
c = json.loads(f.read())["eas"]


async def get_opendss_model(eas_client, model_id: int):
Expand Down Expand Up @@ -104,12 +106,7 @@ def download_generated_model(eas_client: EasClient, output_file_name: str, model


async def open_dss_export(export_file_name: str):
eas_client = EasClient(
host=c["host"],
port=c["rpc_port"],
access_token=c["access_token"],
asynchronous=True
)
eas_client = eas_client_from_config(c, asynchronous=True)

# Run an opendss export
print("Sending OpenDss model export request to EAS")
Expand Down
4 changes: 2 additions & 2 deletions src/zepben/examples/fetching_network_hierarchy.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@
from zepben.ewb import connect_with_token, NetworkConsumerClient

with open("config.json") as f:
c = json.loads(f.read())
c = json.loads(f.read())["ewb"]


async def main():
# See connecting_to_grpc_service.py for examples of each connect function
print("Connecting to EWB..")
channel = connect_with_token(host=c["host"], access_token=c["access_token"], rpc_port=c["rpc_port"])
channel = connect_with_token(**c)
client = NetworkConsumerClient(channel)
print("Connection established..")
# Fetch network hierarchy
Expand Down
4 changes: 2 additions & 2 deletions src/zepben/examples/fetching_network_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ async def main():
# See connecting_to_grpc_service.py for examples of each connect function
print("Connecting to EWB..")
with open("config.json") as f:
c = json.loads(f.read())
channel = connect_with_token(host=c["host"], access_token=c["access_token"], rpc_port=c["rpc_port"])
c = json.loads(f.read())["ewb"]
channel = connect_with_token(**c)
feeder_mrid = "WD24"
print(f"Fetching {feeder_mrid}")
# Note you should create a new client for each Feeder you retrieve
Expand Down
8 changes: 2 additions & 6 deletions src/zepben/examples/find_isolation_section_from_equipment.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,9 @@

async def main(conductor_mrid: str, feeder_mrid: str):
with open("config.json") as f:
c = json.loads(f.read())
c = json.loads(f.read())["ewb"]

channel = connect_with_token(
host=c["host"],
access_token=c["access_token"],
rpc_port=c["rpc_port"]
)
channel = connect_with_token(**c)
client = NetworkConsumerClient(channel)
await client.get_equipment_container(
feeder_mrid, include_energized_containers=IncludedEnergizedContainers.LV_FEEDERS
Expand Down
6 changes: 3 additions & 3 deletions src/zepben/examples/id_csv_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@

from zepben.ewb import NetworkConsumerClient, connect_with_token, ConductingEquipment, Feeder, IncludedEnergizedContainers

with open("./config.json") as f:
c = json.loads(f.read())
with open("config.json") as f:
c = json.loads(f.read())["ewb"]

"""
This is a basic example that shows how to export a CSV of all the conducting equipment in a feeder.
Expand All @@ -26,7 +26,7 @@


async def connect():
channel = connect_with_token(host=c["host"], rpc_port=c["rpc_port"], access_token=c["access_token"], ca_filename=c["ca_path"])
channel = connect_with_token(**c)
network_client = NetworkConsumerClient(channel=channel)

network_hierarchy = (await network_client.get_network_hierarchy()).throw_on_error().value
Expand Down
Loading
Loading