How to run a Hosting Capacity Work Package
This feature is only available to certain customers. If you are interested in using this feature, please contact Zepben for more information.
This guide shows a basic Python example for starting an LV Hosting Capacity work package through the Energy Workbench Python client.
An intrinsic work package estimates additional import or export capacity by adding synthetic load or generation to selected network locations until configured voltage or thermal limits are reached. For a conceptual overview of how this works and what the results mean, see What is Intrinsic Hosting Capacity Mode?.
Prerequisites
Before running an intrinsic work package, you need:
- Access to an Energy Workbench server.
- Credentials with permission to create hosting capacity work packages (
HC_WORK_PACKAGE:CREATE). - Python and the
zepben.easpackage installed. - The feeder mRIDs, scenario names, and years you want to run.
pip install zepben.eas
Minimal Example
Create an EasClient, build an IntrinsicWorkPackageInput, then submit it using Mutation.run_intrinsic_work_package.
from datetime import datetime
import asyncio
from zepben.eas.client.eas_client import EasClient
from zepben.eas import (
Mutation,
IntrinsicInitialLoadStateConfigInput,
IntrinsicInitialStateSelectorMode,
IntrinsicSyfConfigInput,
IntrinsicWorkPackageInput,
)
client = EasClient(
host=eas_server_host,
port=eas_server_port,
protocol=eas_server_protocol,
access_token=eas_server_access_token,
verify_certificate=eas_server_verify_certificate,
ca_filename=eas_server_ca_filename,
)
work_package = IntrinsicWorkPackageInput(
syf=IntrinsicSyfConfigInput(
feeders=["feeder-mrid-1"],
scenario="base",
year=2025,
),
initialStateSelector=IntrinsicInitialLoadStateConfigInput(
selectorMode=IntrinsicInitialStateSelectorMode.FIXED_TIME,
startTime=datetime.fromisoformat("2024-01-11T12:00:00"),
includeLoads=True,
includeExistingDer=True,
loadScalingFactor=1.0,
derScalingFactor=1.0,
),
)
async def main():
result = await client.mutation(
Mutation.run_intrinsic_work_package(
work_package,
work_package_name="Example intrinsic work package",
)
)
print(result)
asyncio.run(main())
The mutation returns the new work package ID if the request is accepted.
Required Configuration
SYF Config
syf defines the work package scope.
| Field | Required | Notes |
|---|---|---|
| feeders | Yes | List of feeder mRIDs. Must contain at least one feeder. Each feeder is solved independently. |
| year | Yes | Forecast year (integer). |
| scenario | No | Scenario name used when selecting the initial state. Defaults to "base" on the server if omitted. |
Initial State Selector Config
initialStateSelector defines the starting load and generation state for the run.
| Field | Required | Notes |
|---|---|---|
| selectorMode | Yes | One of ZERO_LOAD, FIXED_LOAD, PEAK_FEEDER_IMPORT, PEAK_FEEDER_EXPORT, or FIXED_TIME. |
| startTime | Yes | Required for all modes. For FIXED_TIME, this is the exact load time to use. For PEAK_FEEDER_IMPORT and PEAK_FEEDER_EXPORT, this is the start of the period to search for the peak. For ZERO_LOAD and FIXED_LOAD, this determines the network topology snapshot (switching state) used for the run. |
| endTime | Conditional | Required for PEAK_FEEDER_IMPORT and PEAK_FEEDER_EXPORT. Must be after startTime. |
| perCustomerLoadWatts | Conditional | Required for FIXED_LOAD; rejected for other selector modes. |
| perCustomerGenWatts | Conditional | Required for FIXED_LOAD; rejected for other selector modes. |
| perCustomerLoadVar | Conditional | Required for FIXED_LOAD; rejected for other selector modes. |
| perCustomerGenVar | Conditional | Required for FIXED_LOAD; rejected for other selector modes. |
| includeLoads | No | Whether existing loads should be included in initial load states. Defaults to true. Only supported for FIXED_TIME, PEAK_FEEDER_IMPORT, and PEAK_FEEDER_EXPORT. |
| includeExistingDer | No | Whether existing DER should be included in initial load states. Defaults to true. Only supported for FIXED_TIME, PEAK_FEEDER_IMPORT, and PEAK_FEEDER_EXPORT. See Adjusting the Existing Load and DER for what this means and where the data comes from. |
| loadScalingFactor | No | Scaling factor applied to existing loads in initial load states. Defaults to 1.0. Only supported for FIXED_TIME, PEAK_FEEDER_IMPORT, and PEAK_FEEDER_EXPORT. |
| derScalingFactor | No | Scaling factor applied to existing DER in initial load states. Defaults to 1.0. Only supported for FIXED_TIME, PEAK_FEEDER_IMPORT, and PEAK_FEEDER_EXPORT. |
FIXED_TIME - snapshot of actual load and generation at a specific moment:
initialStateSelector=IntrinsicInitialLoadStateConfigInput(
selectorMode=IntrinsicInitialStateSelectorMode.FIXED_TIME,
startTime=datetime.fromisoformat("2024-01-11T12:00:00"),
includeLoads=True,
includeExistingDer=True,
)
PEAK_FEEDER_EXPORT - worst-case export moment in a time window (most conservative for solar hosting capacity):
initialStateSelector=IntrinsicInitialLoadStateConfigInput(
selectorMode=IntrinsicInitialStateSelectorMode.PEAK_FEEDER_EXPORT,
startTime=datetime.fromisoformat("2024-01-01T00:00:00"),
endTime=datetime.fromisoformat("2024-12-31T23:59:59"),
includeLoads=True,
includeExistingDer=True,
)
PEAK_FEEDER_IMPORT - worst-case import moment (most conservative for load growth or EV assessments):
initialStateSelector=IntrinsicInitialLoadStateConfigInput(
selectorMode=IntrinsicInitialStateSelectorMode.PEAK_FEEDER_IMPORT,
startTime=datetime.fromisoformat("2024-01-01T00:00:00"),
endTime=datetime.fromisoformat("2024-12-31T23:59:59"),
includeLoads=True,
includeExistingDer=True,
)
ZERO_LOAD - empty network, no existing load or DER. Produces a theoretical upper bound on network capacity:
initialStateSelector=IntrinsicInitialLoadStateConfigInput(
selectorMode=IntrinsicInitialStateSelectorMode.ZERO_LOAD,
startTime=datetime.fromisoformat("2024-01-01T00:00:00"),
)
FIXED_LOAD - uniform per-customer baseline, useful for standardised comparisons across feeders:
initialStateSelector=IntrinsicInitialLoadStateConfigInput(
selectorMode=IntrinsicInitialStateSelectorMode.FIXED_LOAD,
startTime=datetime.fromisoformat("2024-01-01T00:00:00"),
perCustomerLoadWatts=500.0,
perCustomerGenWatts=0.0,
perCustomerLoadVar=0.0,
perCustomerGenVar=0.0,
)
Common Optional Configuration
Search Config
Use search to control the intrinsic capacity search.
work_package.search = IntrinsicSearchConfigInput(
stepKwPerCustomer=5.0,
maxSteps=1000,
stopOnHvViolation=True,
lockOutCapacityZoneOnViolation=True,
)
| Field | Default | Restriction |
|---|---|---|
| stepKwPerCustomer | 1.0 | |
| maxSteps | 1000 | Must be 10000 or less. |
| stopOnHvViolation | true | Stops the search when HV violations are observed. |
| lockOutCapacityZoneOnViolation | true | Stops incrementing additional import/export in a capacity zone after it violates constraints. |
Injection Resource Config
Use injectionResource to control whether the intrinsic resource is modelled as export generation or import load.
work_package.injectionResource = IntrinsicInjectionResourceConfigInput(
method=IntrinsicInjectionResourceMethod.EXPORT_GENERATION,
loadModelType=IntrinsicLoadModelType.NEGATIVE_LOAD,
powerFactor=0.95,
phaseMatching=IntrinsicPhaseMatching.MATCH_CUSTOMER_PHASES,
)
| Field | Default | Notes |
|---|---|---|
| method | EXPORT_GENERATION | Use EXPORT_GENERATION for export hosting capacity or IMPORT_LOAD for import capacity. |
| loadModelType | NEGATIVE_LOAD | Use PV_SYSTEM only when a PV profile is available. |
| pvProfileId | None | Required when loadModelType is PV_SYSTEM (Must exist in the hosting capacity input database). |
| powerFactor | 1.0 | |
| phaseMatching | MATCH_CUSTOMER_PHASES | Currently the only exposed option. |
Allocation Config
Use allocation to control how intrinsic capacity is distributed.
from zepben.eas import (
IntrinsicAllocationConfigInput,
IntrinsicAllocationMethod,
IntrinsicAllocationScope,
IntrinsicExistingCapacityBasis,
)
work_package.allocation = IntrinsicAllocationConfigInput(
method=IntrinsicAllocationMethod.WEIGHTED_BY_EXISTING_CUSTOMER,
scope=IntrinsicAllocationScope.WITHIN_MEASUREMENT_ZONE,
existingCapacityBasis=IntrinsicExistingCapacityBasis.EXISTING_EXPORT_KW,
)
| Field | Default | Notes |
|---|---|---|
| method | UNIFORM_PER_INCLUDED_CUSTOMER | Use WEIGHTED_BY_EXISTING_CUSTOMER to weight by existing import or export. |
| scope | None | Required when method is WEIGHTED_BY_EXISTING_CUSTOMER. Values: FEEDER_WIDE, WITHIN_MEASUREMENT_ZONE. |
| existingCapacityBasis | None | Required when method is WEIGHTED_BY_EXISTING_CUSTOMER. Values: EXISTING_EXPORT_KW, EXISTING_IMPORT_KW. |
Constraints Config
Use constraints to enable voltage and thermal limits. Supplying an hv or lv block enables that constraint.
from zepben.eas import (
IntrinsicConstraintsConfigInput,
IntrinsicHvVoltageConstraintInput,
IntrinsicLvVoltageConstraintInput,
IntrinsicRatingBasis,
IntrinsicThermalConstraintInput,
IntrinsicThermalConstraintsInput,
IntrinsicVoltageConstraintsInput,
)
work_package.constraints = IntrinsicConstraintsConfigInput(
voltage=IntrinsicVoltageConstraintsInput(
hv=IntrinsicHvVoltageConstraintInput(minPu=0.95, maxPu=1.05),
lv=IntrinsicLvVoltageConstraintInput(min=216.0, max=253.0),
),
thermal=IntrinsicThermalConstraintsInput(
hv=IntrinsicThermalConstraintInput(
percentOfRating=100.0,
ratingBasis=IntrinsicRatingBasis.NORMAL,
),
lv=IntrinsicThermalConstraintInput(
percentOfRating=100.0,
ratingBasis=IntrinsicRatingBasis.NORMAL,
),
),
)
Model Configuration
The model field uses the same model configuration input (HcModelConfigInput) as a normal hosting capacity work package, so use the existing work package model configuration options when you need to override model generation behaviour.
Monitoring The Run
After the mutation returns a work package ID, use the standard work package manager or progress APIs described in How to run a work package and How to manage work packages.
Understanding the Results
Once the work package completes, results are written to the Intrinsic Hosting Capacity output tables. For a guide on interpreting those results - including how to read headroom values, what it means when a result hits maxSteps, and how to trace binding constraints - see Understanding Intrinsic Results.