From 830a5dfbef202be14b4a2177119e440fc121882b Mon Sep 17 00:00:00 2001 From: Jimmy Tung Date: Wed, 9 Jul 2025 14:39:01 +1000 Subject: [PATCH 1/6] Add example for feeder-load-analysis study and update request power factory model Signed-off-by: Jimmy Tung --- changelog.md | 6 ++- .../request_feeder_load_analysis_study.py | 48 +++++++++++++++++++ .../examples/request_power_factory_models.py | 15 ++---- src/zepben/examples/sample_auth_config.json | 11 +++++ src/zepben/examples/utils.py | 34 +++++++++++++ 5 files changed, 102 insertions(+), 12 deletions(-) create mode 100644 src/zepben/examples/request_feeder_load_analysis_study.py create mode 100644 src/zepben/examples/sample_auth_config.json create mode 100644 src/zepben/examples/utils.py diff --git a/changelog.md b/changelog.md index 4b25366..da921a4 100644 --- a/changelog.md +++ b/changelog.md @@ -51,15 +51,17 @@ * Translating a CIM network model into a pandapower model * Requesting a PowerFactory model through the SDK * Manipulating the current state of the network, including swapping a zone open point. + * Added Example for requesting feeder load analysis study through EAS client. ### Enhancements * Limited power factory demo to 1 job at a time. * Added model download function to power factory demo * restrict installation to supported Python versions from 3.9 to 3.11 +* update request power factory models to use new authentication method ### Fixes * None. ### Notes -* Support `zepben.eas` up to 0.16.0. -* Support `zepben.evolve` up to 0.44.0. +* Support `zepben.eas` up to 0.19.0. +* Support `zepben.evolve` up to 0.45.0. diff --git a/src/zepben/examples/request_feeder_load_analysis_study.py b/src/zepben/examples/request_feeder_load_analysis_study.py new file mode 100644 index 0000000..ca6dc17 --- /dev/null +++ b/src/zepben/examples/request_feeder_load_analysis_study.py @@ -0,0 +1,48 @@ +# Copyright 2023 Zeppelin Bend Pty Ltd +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at https://mozilla.org/MPL/2.0/. +import asyncio +import sys + +from zepben.eas.client.feeder_load_analysis_input import FeederLoadAnalysisInput + +from zepben.examples.utils import get_config_dir, get_client + + +async def main(argv): + # See connecting_to_grpc_service.py for examples of each connect function + config_dir = get_config_dir(argv) + print("Connecting to EAS..") + 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( + FeederLoadAnalysisInput( + feeders=["BH11"], + substations=None, + subGeographicalRegions=None, + geographicalRegions=None, + startDate="2022-04-01", + endDate="2022-12-31", + fetchLvNetwork=True, + processFeederLoads=True, + processCoincidentLoads=True, + produceBasicReport=False, + produceConductorReport=True, + aggregateAtFeederLevel=False, + output="Test" + ) + ) + + print(f"Feeder Load Analysis study: {feeder_load_analysis_token['data']['runFeederLoadAnalysis']}") + + # Feeder Load Analysis Study results can be retrieved from back end storage set up with EAS. + + await eas_client.aclose() + + +if __name__ == "__main__": + loop = asyncio.get_event_loop() + loop.run_until_complete(main(sys.argv)) diff --git a/src/zepben/examples/request_power_factory_models.py b/src/zepben/examples/request_power_factory_models.py index faac08b..3e432b4 100644 --- a/src/zepben/examples/request_power_factory_models.py +++ b/src/zepben/examples/request_power_factory_models.py @@ -34,11 +34,8 @@ # graphQL endpoint access settings network_endpoint = 'https://{url}/api/network/graphql' api_endpoint = 'https://{url}/api/graphql' -audience = "https://{url}/" -issuer = "issuer_domain" -client_id = 'client_id' -username = 'username' -password = 'password' +#Generate a personal access token from the energy work bench UI and replace . +token = 'Bearer ' ### EXAMPLE QUERY ONLY ### # This is an example GraphQL query for the full network hierarchy. This is not used as part of this @@ -70,10 +67,8 @@ } } ''' -token_fetcher = get_token_fetcher(audience=audience, issuer=issuer, client_id=client_id, username=username, password=password) -tft = token_fetcher.fetch_token() -network_transport = RequestsHTTPTransport(url=network_endpoint, headers={'Authorization': tft}) -api_transport = RequestsHTTPTransport(url=api_endpoint, headers={'Authorization': tft}) +network_transport = RequestsHTTPTransport(url=network_endpoint, headers={'Authorization': token}) +api_transport = RequestsHTTPTransport(url=api_endpoint, headers={'Authorization': token}) network_client = Client(transport=network_transport) api_client = Client(transport=api_transport) @@ -261,7 +256,7 @@ def download_model(model_number): model_status = result['powerFactoryModelById']['state'] match model_status: case 'COMPLETED': - model = requests.get(model_url, headers={'Authorization': tft}) + model = requests.get(model_url, headers={'Authorization': token}) open(os.path.join(output_dir, file_name) + ".pfd", 'wb').write(model.content) print(file_name + ".pfd saved at " + output_dir) case "CREATION": diff --git a/src/zepben/examples/sample_auth_config.json b/src/zepben/examples/sample_auth_config.json new file mode 100644 index 0000000..824a871 --- /dev/null +++ b/src/zepben/examples/sample_auth_config.json @@ -0,0 +1,11 @@ +{ + "eas_server": { + "host": "", + "port": 1234, + "protocol": "https", + "client_id": "", + "access_token": "", + "verify_certificate": false, + "ca_filename": null + } +} \ No newline at end of file diff --git a/src/zepben/examples/utils.py b/src/zepben/examples/utils.py new file mode 100644 index 0000000..dd41aff --- /dev/null +++ b/src/zepben/examples/utils.py @@ -0,0 +1,34 @@ +import json +from typing import Dict + +from zepben.eas.client.eas_client import EasClient + +import logging +logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s: %(message)s') +logger = logging.getLogger() + + +# Default config dir is where the sample_auth_config sits. +def get_config_dir(argv): + return argv[1] if len(argv) > 1 else "." + + +def read_json_config(config_file_path: str) -> Dict: + file = open(config_file_path) + config_dict = json.load(file) + file.close() + return config_dict + + +def get_client(config_dir): + # Change sample_auth_config.json to any other file name + auth_config = read_json_config(f"{config_dir}/sample_auth_config.json") + + return EasClient( + host=auth_config["eas_server"]["host"], + port=auth_config["eas_server"]["port"], + protocol=auth_config["eas_server"]["protocol"], + access_token=auth_config["eas_server"]["access_token"], + verify_certificate=auth_config["eas_server"].get("verify_certificate", True), + ca_filename=auth_config["eas_server"].get("ca_filename") + ) From 48174eee6fe0c92e9ab5b9b1c1bbdf3cd3d96341 Mon Sep 17 00:00:00 2001 From: Jimmy Tung Date: Wed, 9 Jul 2025 14:40:53 +1000 Subject: [PATCH 2/6] change up example names Signed-off-by: Jimmy Tung --- src/zepben/examples/request_feeder_load_analysis_study.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/zepben/examples/request_feeder_load_analysis_study.py b/src/zepben/examples/request_feeder_load_analysis_study.py index ca6dc17..1c35c74 100644 --- a/src/zepben/examples/request_feeder_load_analysis_study.py +++ b/src/zepben/examples/request_feeder_load_analysis_study.py @@ -20,7 +20,7 @@ async def main(argv): # Fire off a feeder load analysis study feeder_load_analysis_token = await eas_client.async_run_feeder_load_analysis_report( FeederLoadAnalysisInput( - feeders=["BH11"], + feeders=["feeder1", "feeder2"], substations=None, subGeographicalRegions=None, geographicalRegions=None, From f0a15cdc39e168131e3f83f415bfa4268abd5b9a Mon Sep 17 00:00:00 2001 From: Jimmy Tung Date: Wed, 9 Jul 2025 14:54:04 +1000 Subject: [PATCH 3/6] Update copyright Signed-off-by: Jimmy Tung --- src/zepben/examples/request_feeder_load_analysis_study.py | 2 +- src/zepben/examples/utils.py | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/zepben/examples/request_feeder_load_analysis_study.py b/src/zepben/examples/request_feeder_load_analysis_study.py index 1c35c74..344ae9e 100644 --- a/src/zepben/examples/request_feeder_load_analysis_study.py +++ b/src/zepben/examples/request_feeder_load_analysis_study.py @@ -1,4 +1,4 @@ -# Copyright 2023 Zeppelin Bend Pty Ltd +# Copyright 2025 Zeppelin Bend Pty Ltd # # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this diff --git a/src/zepben/examples/utils.py b/src/zepben/examples/utils.py index dd41aff..fefec1e 100644 --- a/src/zepben/examples/utils.py +++ b/src/zepben/examples/utils.py @@ -1,3 +1,8 @@ +# Copyright 2025 Zeppelin Bend Pty Ltd +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at https://mozilla.org/MPL/2.0/. import json from typing import Dict From 484ddc8db4856ec64fb9eacc66df25598adc766e Mon Sep 17 00:00:00 2001 From: Jimmy Tung Date: Mon, 14 Jul 2025 09:52:00 +1000 Subject: [PATCH 4/6] Update variable naming change. Signed-off-by: Jimmy Tung --- .../request_feeder_load_analysis_study.py | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/zepben/examples/request_feeder_load_analysis_study.py b/src/zepben/examples/request_feeder_load_analysis_study.py index 344ae9e..b37ba6e 100644 --- a/src/zepben/examples/request_feeder_load_analysis_study.py +++ b/src/zepben/examples/request_feeder_load_analysis_study.py @@ -22,16 +22,16 @@ async def main(argv): FeederLoadAnalysisInput( feeders=["feeder1", "feeder2"], substations=None, - subGeographicalRegions=None, - geographicalRegions=None, - startDate="2022-04-01", - endDate="2022-12-31", - fetchLvNetwork=True, - processFeederLoads=True, - processCoincidentLoads=True, - produceBasicReport=False, - produceConductorReport=True, - aggregateAtFeederLevel=False, + 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, + produce_basic_report=False, + produce_conductor_report=True, + aggregate_at_feeder_level=False, output="Test" ) ) From 8da9a2449f59daf0879b1b2180634c39c46822ae Mon Sep 17 00:00:00 2001 From: Jimmy Tung Date: Fri, 18 Jul 2025 14:10:41 +1000 Subject: [PATCH 5/6] Update feeder load analysis example to reflect removal of report type options. Signed-off-by: Jimmy Tung --- src/zepben/examples/request_feeder_load_analysis_study.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/zepben/examples/request_feeder_load_analysis_study.py b/src/zepben/examples/request_feeder_load_analysis_study.py index b37ba6e..0e095e1 100644 --- a/src/zepben/examples/request_feeder_load_analysis_study.py +++ b/src/zepben/examples/request_feeder_load_analysis_study.py @@ -29,8 +29,6 @@ async def main(argv): fetch_lv_network=True, process_feeder_loads=True, process_coincident_loads=True, - produce_basic_report=False, - produce_conductor_report=True, aggregate_at_feeder_level=False, output="Test" ) From 88e2671d722be2e527c25c37f32c5616b3c2e536 Mon Sep 17 00:00:00 2001 From: Jimmy Tung Date: Tue, 26 Aug 2025 12:11:31 +1000 Subject: [PATCH 6/6] update changelog Signed-off-by: Jimmy Tung --- changelog.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelog.md b/changelog.md index da921a4..58acc53 100644 --- a/changelog.md +++ b/changelog.md @@ -64,4 +64,4 @@ ### Notes * Support `zepben.eas` up to 0.19.0. -* Support `zepben.evolve` up to 0.45.0. +* Support `zepben.evolve` up to 0.48.0.