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
6 changes: 4 additions & 2 deletions changelog.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
# EAS Python client
## [0.20.0] - UNRELEASED
### Breaking Changes
* None.
* `FixedTimeLoadOverride` now takes in optional list of floats instead of optional float for its variable.

### New Features
* None.
* Modification to `ModelConfig` to allow more customization for model generation
* Added support for separate `vMinPu` and `vMaxPu` with load and generators.
* Added support for `ctPrimScalingFactor` which is required when calculating new `ctPrim` value when feeder proxy loads are not in use.

### Enhancements
* None.
Expand Down
62 changes: 37 additions & 25 deletions src/zepben/eas/client/eas_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ async def async_get_work_package_cost_estimation(self, work_package: WorkPackage
]
} if isinstance(config.load_time, TimePeriod) else None,
"fixedTime": config.load_time and {
"loadTime": config.load_time.time.isoformat(),
"loadTime": config.load_time.load_time.isoformat(),
"overrides": config.load_time.load_overrides and [
{
"loadId": key,
Expand All @@ -260,7 +260,7 @@ async def async_get_work_package_cost_estimation(self, work_package: WorkPackage
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.fetch_load_time.isoformat(),
"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()}
Expand All @@ -270,8 +270,10 @@ async def async_get_work_package_cost_estimation(self, work_package: WorkPackage
"generatorConfig": work_package.generator_config and {
"model": work_package.generator_config.model and {
"vmPu": work_package.generator_config.model.vm_pu,
"vMinPu": work_package.generator_config.model.vmin_pu,
"vMaxPu": work_package.generator_config.model.vmax_pu,
"loadVMinPu": work_package.generator_config.model.load_vmin_pu,
"loadVMaxPu": work_package.generator_config.model.load_vmax_pu,
"genVMinPu": work_package.generator_config.model.gen_vmin_pu,
"genVMaxPu": work_package.generator_config.model.gen_vmax_pu,
"loadModel": work_package.generator_config.model.load_model,
"collapseSWER": work_package.generator_config.model.collapse_swer,
"calibration": work_package.generator_config.model.calibration,
Expand Down Expand Up @@ -320,6 +322,7 @@ async def async_get_work_package_cost_estimation(self, work_package: WorkPackage
"defaultLoadVar": work_package.generator_config.model.default_load_var,
"defaultGenVar": work_package.generator_config.model.default_gen_var,
"transformerTapSettings": work_package.generator_config.model.transformer_tap_settings,
"ctPrimScalingFactor": work_package.generator_config.model.ct_prim_scaling_factor,
},
"solve": work_package.generator_config.solve and {
"normVMinPu": work_package.generator_config.solve.norm_vmin_pu,
Expand Down Expand Up @@ -465,7 +468,7 @@ async def async_run_hosting_capacity_work_package(self, work_package: WorkPackag
]
} if isinstance(config.load_time, TimePeriod) else None,
"fixedTime": config.load_time and {
"loadTime": config.load_time.time.isoformat(),
"loadTime": config.load_time.load_time.isoformat(),
"overrides": config.load_time.load_overrides and [
{
"loadId": key,
Expand All @@ -491,7 +494,7 @@ async def async_run_hosting_capacity_work_package(self, work_package: WorkPackag
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.time.isoformat(),
"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()}
Expand All @@ -501,8 +504,10 @@ async def async_run_hosting_capacity_work_package(self, work_package: WorkPackag
"generatorConfig": work_package.generator_config and {
"model": work_package.generator_config.model and {
"vmPu": work_package.generator_config.model.vm_pu,
"vMinPu": work_package.generator_config.model.vmin_pu,
"vMaxPu": work_package.generator_config.model.vmax_pu,
"loadVMinPu": work_package.generator_config.model.load_vmin_pu,
"loadVMaxPu": work_package.generator_config.model.load_vmax_pu,
"genVMinPu": work_package.generator_config.model.gen_vmin_pu,
"genVMaxPu": work_package.generator_config.model.gen_vmax_pu,
"loadModel": work_package.generator_config.model.load_model,
"collapseSWER": work_package.generator_config.model.collapse_swer,
"calibration": work_package.generator_config.model.calibration,
Expand Down Expand Up @@ -550,7 +555,8 @@ async def async_run_hosting_capacity_work_package(self, work_package: WorkPackag
"defaultGenWatts": work_package.generator_config.model.default_gen_watts,
"defaultLoadVar": work_package.generator_config.model.default_load_var,
"defaultGenVar": work_package.generator_config.model.default_gen_var,
"transformerTapSettings": work_package.generator_config.model.transformer_tap_settings
"transformerTapSettings": work_package.generator_config.model.transformer_tap_settings,
"ctPrimScalingFactor": work_package.generator_config.model.ct_prim_scaling_factor,
},
"solve": work_package.generator_config.solve and {
"normVMinPu": work_package.generator_config.solve.norm_vmin_pu,
Expand Down Expand Up @@ -1045,17 +1051,17 @@ async def async_run_opendss_export(self, config: OpenDssConfig):
},
"modulesConfiguration": {
"common": {
**({"fixedTime": {"loadTime": config.load_time.time.isoformat(),
"overrides": 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 config.load_time.load_overrides.items()
]
}} if isinstance(config.load_time, FixedTime) else {}),
**({"fixedTime": {"loadTime": config.load_time.load_time.isoformat(),
"overrides": 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 config.load_time.load_overrides.items()
]
}} if isinstance(config.load_time, FixedTime) else {}),
**({"timePeriod": {
"startTime": config.load_time.start_time.isoformat(),
"endTime": config.load_time.end_time.isoformat(),
Expand All @@ -1073,8 +1079,10 @@ async def async_run_opendss_export(self, config: OpenDssConfig):
**({"generator": {
**({"model": {
"vmPu": config.generator_config.model.vm_pu,
"vMinPu": config.generator_config.model.vmin_pu,
"vMaxPu": config.generator_config.model.vmax_pu,
"loadVMinPu": config.generator_config.model.load_vmin_pu,
"loadVMaxPu": config.generator_config.model.load_vmax_pu,
"genVMinPu": config.generator_config.model.gen_vmin_pu,
"genVMaxPu": config.generator_config.model.gen_vmax_pu,
"loadModel": config.generator_config.model.load_model,
"collapseSWER": config.generator_config.model.collapse_swer,
"calibration": config.generator_config.model.calibration,
Expand Down Expand Up @@ -1122,7 +1130,8 @@ async def async_run_opendss_export(self, config: OpenDssConfig):
"defaultGenWatts": config.generator_config.model.default_gen_watts,
"defaultLoadVar": config.generator_config.model.default_load_var,
"defaultGenVar": config.generator_config.model.default_gen_var,
"transformerTapSettings": config.generator_config.model.transformer_tap_settings
"transformerTapSettings": config.generator_config.model.transformer_tap_settings,
"ctPrimScalingFactor": config.generator_config.model.ct_prim_scaling_factor,
}} if config.generator_config.model else {}),
**({"solve": {
"normVMinPu": config.generator_config.solve.norm_vmin_pu,
Expand Down Expand Up @@ -1246,8 +1255,10 @@ async def async_get_paged_opendss_models(
generator {
model {
vmPu
vMinPu
vMaxPu
loadVMinPu
loadVMaxPu
genVMinPu
genVMaxPu
loadModel
collapseSWER
calibration
Expand Down Expand Up @@ -1293,6 +1304,7 @@ async def async_get_paged_opendss_models(
defaultLoadVar
defaultGenVar
transformerTapSettings
ctPrimScalingFactor
}
solve {
normVMinPu
Expand Down
31 changes: 22 additions & 9 deletions src/zepben/eas/client/work_package.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,8 +145,8 @@ class FixedTime:
present for the provided time in the load database for accurate results.
"""

def __init__(self, time: datetime, load_overrides: Optional[Dict[str, FixedTimeLoadOverride]] = None):
self.time = time.replace(tzinfo=None)
def __init__(self, load_time: datetime, load_overrides: Optional[Dict[str, FixedTimeLoadOverride]] = None):
self.load_time = load_time.replace(tzinfo=None)
self.load_overrides = load_overrides


Expand Down Expand Up @@ -212,17 +212,25 @@ class ModelConfig:
vm_pu: Optional[float] = None
"""Voltage per-unit of voltage source."""

vmin_pu: Optional[float] = None
load_vmin_pu: Optional[float] = None
"""
Minimum per unit voltage for which the load model selected and generator model is assumed to apply. Below this value, the load/gen model reverts to a
constant impedance model. For generator model used, this is used to determine the upper current limit. For example, if Vminpu is 0.90 then the current
limit is (1/0.90) = 111%.
Minimum per unit voltage for which the load model selected is assumed to apply. Below this value, the load model reverts to a constant impedance model.
"""

vmax_pu: Optional[float] = None
load_vmax_pu: Optional[float] = None
"""
Maximum per unit voltage for which the load model selected and generator model is assumed to apply. Above this value, the load/gen model reverts to a
constant impedance model.
Maximum per unit voltage for which the load model selected is assumed to apply. Above this value, the load model reverts to a constant impedance model.
"""

gen_vmin_pu: Optional[float] = None
"""
Minimum per unit voltage for which the generator model is assumed to apply. Below this value, the gen model reverts to a constant impedance model.
For generator model used, this is used to determine the upper current limit. For example, if Vminpu is 0.90 then the current limit is (1/0.90) = 111%.
"""

gen_vmax_pu: Optional[float] = None
"""
Maximum per unit voltage for which the generator model is assumed to apply. Above this value, the gen model reverts to a constant impedance model.
"""

load_model: Optional[int] = None
Expand Down Expand Up @@ -438,6 +446,11 @@ class ModelConfig:
The name of the set of distribution transformer tap settings to be applied to the model from an external source.
"""

ct_prim_scaling_factor: Optional[float] = None
"""
Optional setting for scaling factor of calculated CTPrim for zone sub transformers.
"""


class SolveMode(Enum):
YEARLY = "YEARLY"
Expand Down
25 changes: 17 additions & 8 deletions test/test_eas_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -805,8 +805,10 @@ def run_opendss_export_request_handler(request):
"generator": {
"model": {
"vmPu": 1.0,
"vMinPu": 0.80,
"vMaxPu": 1.15,
"loadVMinPu": 0.80,
"loadVMaxPu": 1.15,
"genVMinPu": 0.50,
"genVMaxPu": 2.00,
"loadModel": 1,
"collapseSWER": False,
"calibration": False,
Expand Down Expand Up @@ -861,7 +863,8 @@ def run_opendss_export_request_handler(request):
"defaultGenWatts": [50.0, 150.0, 250.0],
"defaultLoadVar": [10.0, 20.0, 30.0],
"defaultGenVar": [5.0, 15.0, 25.0],
"transformerTapSettings": "tap-3"
"transformerTapSettings": "tap-3",
"ctPrimScalingFactor": 2.0
},
"solve": {
"normVMinPu": 0.9,
Expand Down Expand Up @@ -904,8 +907,10 @@ def run_opendss_export_request_handler(request):
generator_config=GeneratorConfig(
ModelConfig(
vm_pu=1.0,
vmin_pu=0.80,
vmax_pu=1.15,
load_vmin_pu=0.80,
load_vmax_pu=1.15,
gen_vmin_pu=0.50,
gen_vmax_pu=2.00,
load_model=1,
collapse_swer=False,
calibration=False,
Expand Down Expand Up @@ -954,7 +959,8 @@ def run_opendss_export_request_handler(request):
default_gen_watts=[50.0, 150.0, 250.0],
default_load_var=[10.0, 20.0, 30.0],
default_gen_var=[5.0, 15.0, 25.0],
transformer_tap_settings="tap-3"
transformer_tap_settings="tap-3",
ct_prim_scaling_factor=2.0
),
SolveConfig(
norm_vmin_pu=0.9,
Expand Down Expand Up @@ -1070,8 +1076,10 @@ def test_run_opendss_export_valid_certificate_success(ca: trustme.CA, httpserver
generator {
model {
vmPu
vMinPu
vMaxPu
loadVMinPu
loadVMaxPu
genVMinPu
genVMaxPu
loadModel
collapseSWER
calibration
Expand Down Expand Up @@ -1117,6 +1125,7 @@ def test_run_opendss_export_valid_certificate_success(ca: trustme.CA, httpserver
defaultLoadVar
defaultGenVar
transformerTapSettings
ctPrimScalingFactor
}
solve {
normVMinPu
Expand Down