From 3c0572d7b81d44d35ef60329c3d64295a6ddea98 Mon Sep 17 00:00:00 2001 From: Jimmy Tung Date: Tue, 19 Aug 2025 16:37:13 +1000 Subject: [PATCH 1/5] added span level threshold related functionality. Signed-off-by: Jimmy Tung --- changelog.md | 1 + src/zepben/eas/client/work_package.py | 12 ++++++++++++ test/test_eas_client.py | 11 ++++++++--- 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/changelog.md b/changelog.md index d05450f..eeeaecc 100644 --- a/changelog.md +++ b/changelog.md @@ -7,6 +7,7 @@ ### New Features * Added optional fields to `ModelConfig` to control network simplification: `simplify_network`, `collapse_negligible_impedances`, and `combine_common_impedances`. * Added optional `node_level_results` field to `GeneratorConfig`. This `NodeLevelResultsConfig` allows the configuration of node level power flow results from OpenDss. +* Introduce `span_level_threshold` and `simplify_plsi` into `work_package` so it can be passed through for hosting capacity studies. ### Enhancements * None. diff --git a/src/zepben/eas/client/work_package.py b/src/zepben/eas/client/work_package.py index 0da70af..f12b15b 100644 --- a/src/zepben/eas/client/work_package.py +++ b/src/zepben/eas/client/work_package.py @@ -467,6 +467,18 @@ class ModelConfig: Optional setting for scaling factor of calculated CTPrim for zone sub transformers. """ + span_level_threshold: Optional[float] = None + """ + Optional setting to include designedRating of conductor being considered during network simplification and also replace + Wireinfo.ratedCurrent for normAmps and emergAmps assignment in LineCode. (if threshold is 50%, set as 50.0) + """ + + simplify_plsi: Optional[bool] = None + """ + Optional setting to indicate if per length sequence impedance should be normalized during network simplification. + Must also provide a valid span_level_threshold for this to take effect. + """ + class SolveMode(Enum): YEARLY = "YEARLY" diff --git a/test/test_eas_client.py b/test/test_eas_client.py index ad51163..b55ab62 100644 --- a/test/test_eas_client.py +++ b/test/test_eas_client.py @@ -7,7 +7,7 @@ import random import ssl import string -from datetime import datetime, timezone, timedelta +from datetime import datetime from http import HTTPStatus from unittest import mock @@ -1023,6 +1023,7 @@ def test_run_hosting_capacity_calibration_with_explicit_transformer_tap_settings httpserver.check_assertions() assert res == {"result": "success"} + def get_hosting_capacity_calibration_sets_request_handler(request): actual_body = json.loads(request.data.decode()) query = " ".join(actual_body['query'].split()) @@ -1152,7 +1153,9 @@ def run_opendss_export_request_handler(request): "defaultLoadVar": [10.0, 20.0, 30.0], "defaultGenVar": [5.0, 15.0, 25.0], "transformerTapSettings": "tap-3", - "ctPrimScalingFactor": 2.0 + "ctPrimScalingFactor": 2.0, + "spanLevelThreshold": 50.0, + "simplifyPLSI": True }, "solve": { "normVMinPu": 0.9, @@ -1261,7 +1264,9 @@ def run_opendss_export_request_handler(request): default_load_var=[10.0, 20.0, 30.0], default_gen_var=[5.0, 15.0, 25.0], transformer_tap_settings="tap-3", - ct_prim_scaling_factor=2.0 + ct_prim_scaling_factor=2.0, + span_level_threshold=50.0, + simplify_plsi=True ), SolveConfig( norm_vmin_pu=0.9, From fab4bcbe47b53dbed6d73379fed7c355b6bdc045 Mon Sep 17 00:00:00 2001 From: Jimmy Tung Date: Fri, 22 Aug 2025 10:02:30 +1000 Subject: [PATCH 2/5] Update for changes to the added variables. Signed-off-by: Jimmy Tung --- changelog.md | 5 +++++ src/zepben/eas/client/eas_client.py | 8 +++++++ src/zepben/eas/client/work_package.py | 23 +++++++++++++++----- test/test_eas_client.py | 31 +++++++++++++++++++++------ 4 files changed, 56 insertions(+), 11 deletions(-) diff --git a/changelog.md b/changelog.md index eeeaecc..3a01d63 100644 --- a/changelog.md +++ b/changelog.md @@ -8,6 +8,11 @@ * Added optional fields to `ModelConfig` to control network simplification: `simplify_network`, `collapse_negligible_impedances`, and `combine_common_impedances`. * Added optional `node_level_results` field to `GeneratorConfig`. This `NodeLevelResultsConfig` allows the configuration of node level power flow results from OpenDss. * Introduce `span_level_threshold` and `simplify_plsi` into `work_package` so it can be passed through for hosting capacity studies. +* Introduce new variables into `work_package` so it can be passed through for hosting capacity studies. + * `use_span_level_threshold` + * `rating_threshold` + * `simplify_plsi_threshold` + * `emerg_amp_scaling` ### Enhancements * None. diff --git a/src/zepben/eas/client/eas_client.py b/src/zepben/eas/client/eas_client.py index dde8dd6..e4d09d2 100644 --- a/src/zepben/eas/client/eas_client.py +++ b/src/zepben/eas/client/eas_client.py @@ -241,6 +241,10 @@ def generator_config_to_json(self, generator_config: Optional[GeneratorConfig]) "defaultGenVar": generator_config.model.default_gen_var, "transformerTapSettings": generator_config.model.transformer_tap_settings, "ctPrimScalingFactor": generator_config.model.ct_prim_scaling_factor, + "useSpanLevelThreshold": work_package.generator_config.model.use_span_level_threshold, + "ratingThreshold": work_package.generator_config.model.rating_threshold, + "simplifyPLSIThreshold": work_package.generator_config.model.simplify_plsi_threshold, + "emergAmpScaling": work_package.generator_config.model.emerg_amp_scaling }, "solve": generator_config.solve and { "normVMinPu": generator_config.solve.norm_vmin_pu, @@ -1310,6 +1314,10 @@ async def async_get_paged_opendss_models( defaultGenVar transformerTapSettings ctPrimScalingFactor + useSpanLevelThreshold + ratingThreshold + simplifyPLSIThreshold + emergAmpScaling } solve { normVMinPu diff --git a/src/zepben/eas/client/work_package.py b/src/zepben/eas/client/work_package.py index f12b15b..bbb8ada 100644 --- a/src/zepben/eas/client/work_package.py +++ b/src/zepben/eas/client/work_package.py @@ -467,16 +467,29 @@ class ModelConfig: Optional setting for scaling factor of calculated CTPrim for zone sub transformers. """ - span_level_threshold: Optional[float] = None + use_span_level_threshold: bool = False """ - Optional setting to include designedRating of conductor being considered during network simplification and also replace - Wireinfo.ratedCurrent for normAmps and emergAmps assignment in LineCode. (if threshold is 50%, set as 50.0) + set to true if designRating is to be used for current comparison during collapse of CommonImpedance AcLineSegment. """ - simplify_plsi: Optional[bool] = None + rating_threshold: Optional[float] = None + """ + Optional setting to loosen current comparison between conductors during network simplification by providing a threshold + of allowed differences. + Set as a % value, i.e put as 50.0 if threshold is 50% + """ + + simplify_plsi_threshold: Optional[float] = None """ Optional setting to indicate if per length sequence impedance should be normalized during network simplification. - Must also provide a valid span_level_threshold for this to take effect. + Connected AcLineSegment with Per Length Sequence Impedance value difference within the threshold will be normalized. + Set as a % value, i.e put as 50.0 if threshold is 50% + """ + + emerg_amp_scaling: Optional[float] = None + """ + Scaling factor for emergency current rating in lineCodes. + Set as a factor value, i.e put as 1.5 if scaling is 150% """ diff --git a/test/test_eas_client.py b/test/test_eas_client.py index b55ab62..ffde47a 100644 --- a/test/test_eas_client.py +++ b/test/test_eas_client.py @@ -769,6 +769,10 @@ def hosting_capacity_run_calibration_with_calibration_time_request_handler(reque 'pFactorForecastPv': None, 'seed': None, 'simplifyNetwork': None, + 'useSpanLevelThreshold': False, + 'ratingThreshold': None, + 'simplifyPLSIThreshold': None, + 'emergAmpScaling': None, 'splitPhaseDefaultLoadLossPercentage': None, 'splitPhaseLVKV': None, 'swerVoltageToLineVoltage': None, @@ -872,6 +876,10 @@ def hosting_capacity_run_calibration_with_generator_config_request_handler(reque 'pFactorForecastPv': None, 'seed': None, 'simplifyNetwork': None, + 'useSpanLevelThreshold': False, + 'ratingThreshold': None, + 'simplifyPLSIThreshold': None, + 'emergAmpScaling': None, 'splitPhaseDefaultLoadLossPercentage': None, 'splitPhaseLVKV': None, 'swerVoltageToLineVoltage': None, @@ -969,6 +977,10 @@ def hosting_capacity_run_calibration_with_partial_model_config_request_handler(r 'pFactorForecastPv': None, 'seed': None, 'simplifyNetwork': None, + 'useSpanLevelThreshold': False, + 'ratingThreshold': None, + 'simplifyPLSIThreshold': None, + 'emergAmpScaling': None, 'splitPhaseDefaultLoadLossPercentage': None, 'splitPhaseLVKV': None, 'swerVoltageToLineVoltage': None, @@ -1154,8 +1166,10 @@ def run_opendss_export_request_handler(request): "defaultGenVar": [5.0, 15.0, 25.0], "transformerTapSettings": "tap-3", "ctPrimScalingFactor": 2.0, - "spanLevelThreshold": 50.0, - "simplifyPLSI": True + "useSpanLevelThreshold": True, + "ratingThreshold": 20.0, + "simplifyPLSIThreshold": 20.0, + "emergAmpScaling": 1.8 }, "solve": { "normVMinPu": 0.9, @@ -1265,8 +1279,10 @@ def run_opendss_export_request_handler(request): default_gen_var=[5.0, 15.0, 25.0], transformer_tap_settings="tap-3", ct_prim_scaling_factor=2.0, - span_level_threshold=50.0, - simplify_plsi=True + use_span_level_threshold=True, + rating_threshold=20.0, + simplify_plsi_threshold=20.0, + emerg_amp_scaling= 1.8 ), SolveConfig( norm_vmin_pu=0.9, @@ -1338,8 +1354,7 @@ def test_run_opendss_export_valid_certificate_success(ca: trustme.CA, httpserver ) OPENDSS_CONFIG.load_time = FixedTime(datetime(2022, 4, 1), {"meter1": FixedTimeLoadOverride([1.0], [2.0], [3.0], [4.0])}) - httpserver.expect_oneshot_request("/api/graphql").respond_with_handler( - run_opendss_export_request_handler) + httpserver.expect_oneshot_request("/api/graphql").respond_with_handler(run_opendss_export_request_handler) res = eas_client.run_opendss_export(OPENDSS_CONFIG) httpserver.check_assertions() assert res == {"result": "success"} @@ -1445,6 +1460,10 @@ def test_run_opendss_export_valid_certificate_success(ca: trustme.CA, httpserver defaultGenVar transformerTapSettings ctPrimScalingFactor + useSpanLevelThreshold + ratingThreshold + simplifyPLSIThreshold + emergAmpScaling } solve { normVMinPu From 6f4e122878086be926b4ee22500053ce033acc09 Mon Sep 17 00:00:00 2001 From: Jimmy Tung Date: Tue, 26 Aug 2025 16:10:51 +1000 Subject: [PATCH 3/5] Rebase Signed-off-by: Jimmy Tung --- src/zepben/eas/client/eas_client.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/zepben/eas/client/eas_client.py b/src/zepben/eas/client/eas_client.py index e4d09d2..e5edc95 100644 --- a/src/zepben/eas/client/eas_client.py +++ b/src/zepben/eas/client/eas_client.py @@ -241,10 +241,10 @@ def generator_config_to_json(self, generator_config: Optional[GeneratorConfig]) "defaultGenVar": generator_config.model.default_gen_var, "transformerTapSettings": generator_config.model.transformer_tap_settings, "ctPrimScalingFactor": generator_config.model.ct_prim_scaling_factor, - "useSpanLevelThreshold": work_package.generator_config.model.use_span_level_threshold, - "ratingThreshold": work_package.generator_config.model.rating_threshold, - "simplifyPLSIThreshold": work_package.generator_config.model.simplify_plsi_threshold, - "emergAmpScaling": work_package.generator_config.model.emerg_amp_scaling + "useSpanLevelThreshold": generator_config.model.use_span_level_threshold, + "ratingThreshold": generator_config.model.rating_threshold, + "simplifyPLSIThreshold": generator_config.model.simplify_plsi_threshold, + "emergAmpScaling": generator_config.model.emerg_amp_scaling }, "solve": generator_config.solve and { "normVMinPu": generator_config.solve.norm_vmin_pu, From 892ef38a8209dba4c2e3eb54b59157bc3c7daa6d Mon Sep 17 00:00:00 2001 From: Jimmy Tung Date: Thu, 4 Sep 2025 16:47:06 +1000 Subject: [PATCH 4/5] Fix loadoverride decoding for forecastconfigs and rebase Signed-off-by: Jimmy Tung --- src/zepben/eas/client/eas_client.py | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/src/zepben/eas/client/eas_client.py b/src/zepben/eas/client/eas_client.py index e5edc95..3a181b0 100644 --- a/src/zepben/eas/client/eas_client.py +++ b/src/zepben/eas/client/eas_client.py @@ -320,15 +320,27 @@ def work_package_config_to_json(self, work_package: Optional[WorkPackageConfig]) "timePeriod": { "startTime": work_package.syf_config.load_time.start_time.isoformat(), "endTime": work_package.syf_config.load_time.end_time.isoformat(), - "overrides": work_package.syf_config.load_time.load_overrides and { - key: value.__dict__ - for key, value in work_package.syf_config.load_time.load_overrides.items()} + "overrides": work_package.syf_config.load_time.load_overrides and [ + { + "loadId": key, + "loadWattsOverride": value.load_watts, + "genWattsOverride": value.gen_watts, + "loadVarOverride": value.load_var, + "genVarOverride": value.gen_var, + } for key, value in work_package.syf_config.load_time.load_overrides.items() + ] } if isinstance(work_package.syf_config.load_time, TimePeriod) else None, "fixedTime": work_package.syf_config.load_time and { "loadTime": work_package.syf_config.load_time.load_time.isoformat(), - "overrides": work_package.syf_config.load_time.load_overrides and { - key: value.__dict__ - for key, value in work_package.syf_config.load_time.load_overrides.items()} + "overrides": work_package.syf_config.load_time.load_overrides and [ + { + "loadId": key, + "loadWattsOverride": value.load_watts, + "genWattsOverride": value.gen_watts, + "loadVarOverride": value.load_var, + "genVarOverride": value.gen_var, + } for key, value in work_package.syf_config.load_time.load_overrides.items() + ] } if isinstance(work_package.syf_config.load_time, FixedTime) else None } if isinstance(work_package.syf_config, ForecastConfig) else None, "qualityAssuranceProcessing": work_package.quality_assurance_processing, From 147a4736addc570e7e6733476d431f23b828ca06 Mon Sep 17 00:00:00 2001 From: Kurt Greaves Date: Thu, 4 Sep 2025 17:28:21 +1000 Subject: [PATCH 5/5] Update comments Signed-off-by: Kurt Greaves --- src/zepben/eas/client/work_package.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/zepben/eas/client/work_package.py b/src/zepben/eas/client/work_package.py index bbb8ada..11c746f 100644 --- a/src/zepben/eas/client/work_package.py +++ b/src/zepben/eas/client/work_package.py @@ -469,26 +469,26 @@ class ModelConfig: use_span_level_threshold: bool = False """ - set to true if designRating is to be used for current comparison during collapse of CommonImpedance AcLineSegment. + Set to true if `AcLineSegment.designRating` is to be used for conductor rated current in the model. """ rating_threshold: Optional[float] = None """ - Optional setting to loosen current comparison between conductors during network simplification by providing a threshold - of allowed differences. + Optional setting to loosen rated current comparison between conductors during network simplification by providing a threshold + of allowed differences. Neighbouring conductors within this threshold and matching impedance's will be collapsed. Set as a % value, i.e put as 50.0 if threshold is 50% """ simplify_plsi_threshold: Optional[float] = None """ - Optional setting to indicate if per length sequence impedance should be normalized during network simplification. - Connected AcLineSegment with Per Length Sequence Impedance value difference within the threshold will be normalized. + Optional setting to indicate if sequence impedance's should be normalized during network simplification. + Connected AcLineSegments with PerLengthSequenceImpedance value differences within the threshold will be normalized. Set as a % value, i.e put as 50.0 if threshold is 50% """ emerg_amp_scaling: Optional[float] = None """ - Scaling factor for emergency current rating in lineCodes. + Scaling factor for emergency current rating for conductors. Set as a factor value, i.e put as 1.5 if scaling is 150% """