This feature is only available to certain customers. If you are interested in using this feature, please contact Zepben for more information.
Interventions Options
This is a reference guide to the different types of interventions available in the Hosting Capacity Module, along with their configuration options and examples.
For an explanation of what interventions are and how they work, including more details on how the Candidate Generation and Allocation process works, please see What are Interventions and why are they useful?. For a step-by-step guide to running one, including base work package requirements and common pitfalls, see How to run an Intervention Work Package.
List of Intervention types
| Intervention Type | Summary |
|---|---|
| TARIFF_REFORM | Modifies time of use patterns of customer electricity loads by applying load reshape profiles to eligible customers based on targeting criteria. Doesn't simulate tariffs directly, rather their load shape impacts |
| CONTROLLED_LOAD_HOT_WATER | Functionally identical to TARIFF_REFORM; provided as a separate type so controlled load hot water programs can be tracked separately from tariff reform programs. |
| COMMUNITY_BESS | Installs battery energy storage systems in low-voltage networks to address voltage and thermal constraints caused by high solar penetration or variable loads. Batteries are strategically placed at locations with the most severe network violations. |
| LV_STATCOMS | Deploys Static Synchronous Compensators (STATCOMs) that provide dynamic reactive power compensation to maintain network voltage stability. Responds rapidly to voltage fluctuations, particularly effective for networks with variable loads or distributed generation. |
| DVMS | Implements real-time, automated voltage regulation by continuously adjusting feeder head (zone substation) transformer taps based on customer voltage measurements. Most computationally intensive intervention as it operates at every simulation time step. |
| PHASE_REBALANCING | Redistributes single-phase customers across phases A, B, and C to correct imbalanced phase loading, reducing voltage imbalances and improving network efficiency. |
| DISTRIBUTION_TAP_OPTIMIZATION | Identifies zones with persistent voltage issues and determines optimal annual tap setting changes using heuristic analysis. Unlike DVMS, makes strategic yearly adjustments rather than real-time continuous control. |
| DISTRIBUTION_TX_OLTC | Retrofits distribution transformers with on-load tap changers (OLTCs) to enable dynamic voltage regulation under load conditions, improving voltage quality for downstream customers. |
| THERMAL_LINE_UPGRADE | Reinforces overloaded lines by replacing conductors from the catalogue, prioritised by import/export overload exposure and sized for the configured loading headroom. |
| VOLTAGE_LINE_UPGRADE | Reduces excessive voltage movement by selecting lower-impedance conductor replacements along contributing feeder lines. |
| THERMAL_TRANSFORMER_UPGRADE | Reinforces overloaded transformers with compatible catalogue replacements, prioritised by import/export overload exposure and sized for the configured loading headroom. |
candidateIntervention accepts one of the candidate-based types above except for TARIFF_REFORM, CONTROLLED_LOAD_HOT_WATER, DVMS, and PHASE_REBALANCING. phaseRebalanceProportions, dvms, and loadReshaping are independent of it and of each other, and can be combined with it in the same work package - see Stacking Interventions.
Intervention Scope
The Intervention Module is designed to work off a reference or base work package, which allows for testing with and without the intervention. For candidate-based interventions (candidateIntervention), it will use the results in Network Performance Metrics Enhanced to choose which areas to intervene in.
The base and intervention work packages should be run with the same work package configuration other than the intervention (e.g. settings for load time range, model parameters, network topology fixers, etc.) to ensure that the only difference is the intervention being modelled, and not unrelated settings changing results.
The Intervention Module requires a stricter set of conditions than regular work packages. Please ensure these criteria are met, as otherwise results may be erroneous.
-
Run either on a single year or a range of contiguous years, not on multiple non-contiguous years. For example:
{2027}or{2027, 2028, 2029, 2030}are valid, but{2027, 2030}is not supported. -
Set Measurement Zones at the transformer level only for candidate-based interventions that use measurement-zone metrics (COMMUNITY_BESS, LV_STATCOMS, DISTRIBUTION_TAP_OPTIMIZATION, DISTRIBUTION_TX_OLTC and VOLTAGE_LINE_UPGRADE), not at a switch/LV circuit head level. See the Meter Placement Config in Configuration Options and Measurement Zones.
InterventionConfigInput Parameters
InterventionConfigInput is a container for up to four independent intervention blocks. Any combination of them can be set on the same work package - see Stacking Interventions.
| Parameter | Type | Description |
|---|---|---|
| parentWorkPackageId | TEXT (UUID) | Required. ID of the work package this intervention builds upon. Can point at another intervention work package (not just a non-intervention baseline), but this only chains metrics for candidate generation, it does not carry that work package's applied changes forward. See Chaining via parentWorkPackageId. |
| candidateIntervention | CandidateInterventionConfigInput | Optional. Config for a single candidate-based intervention. Only one candidate intervention can be configured in a work package. |
| phaseRebalanceProportions | PhaseRebalanceProportionsInput | Optional. Target proportions for distributing customers across phases (A, B, C). |
| dvms | DvmsConfigInput | Optional. Configuration for dynamic voltage management including voltage limits, percentiles, and regulator settings. |
| loadReshaping | LoadReshapingConfigInput | Optional. Configuration for load reshaping (tariff reform, controlled load hot water, etc). |
CandidateInterventionConfigInput Parameters
| Parameter | Type | Used By | Description |
|---|---|---|---|
| interventionType | CandidateInterventionClass | All | Required. One of COMMUNITY_BESS, DISTRIBUTION_TX_OLTC, LV_STATCOMS, DISTRIBUTION_TAP_OPTIMIZATION, THERMAL_LINE_UPGRADE, VOLTAGE_LINE_UPGRADE, THERMAL_TRANSFORMER_UPGRADE. |
| allocationInstanceSelection | List[TEXT] | COMMUNITY_BESS, LV_STATCOMS, DISTRIBUTION_TX_OLTC, THERMAL_LINE_UPGRADE, VOLTAGE_LINE_UPGRADE, THERMAL_TRANSFORMER_UPGRADE | Optional list of instance or catalogue IDs to choose from, referencing the relevant table. Criteria-style interventions use instance name values (for example bess_instances.name); asset upgrade interventions use catalogue id values (conductor_catalog.id or transformer_catalog.id). If omitted, all instances in the table are considered (COMMUNITY_BESS), the first matching instance is used (LV_STATCOMS, DISTRIBUTION_TX_OLTC), or all matching catalogue rows are considered (asset upgrade interventions). Only one instance is allowed for DISTRIBUTION_TX_OLTC. |
| candidateGeneration | CandidateGenerationConfigInput | All | Required. Configuration for identifying intervention candidates; contains different parameters depending on the intervention type (see per-type examples below). Its type must match interventionType. |
| candidateAllocationCriteria | TEXT | COMMUNITY_BESS, LV_STATCOMS, DISTRIBUTION_TX_OLTC | Required for these types. References allocation criteria table name in database. Must be omitted for all other types, which allocate directly from candidateGeneration without a separate criteria table. |
| yearRange | YearRangeInput | All | Optional. Inclusive range of years to search for and apply interventions. minYear must be less than or equal to maxYear. For the asset upgrade types, every year in the range must also appear in forecastConfig.years; omit yearRange to use all years in the work package. |
| allocationLimitPerYear | DOUBLE | All | Optional. Maximum intervention allocation weight applied per year. The unit depends on the intervention type - see the note below. If omitted, defaults to 1000000.0, which is effectively uncapped for either unit. |
allocationLimitPerYearEach candidate carries an allocation weight, and allocationLimitPerYear caps the total weight applied in a single year. What that weight measures depends on what is being installed, so the same number means different things:
| Intervention type | Weight per candidate | So the limit is |
|---|---|---|
| THERMAL_LINE_UPGRADE, VOLTAGE_LINE_UPGRADE | The combined length of the lines being replaced, in metres | Metres of line replaced per year |
| All other types | 1.0 per candidate | Number of interventions per year |
CandidateGenerationConfigInput Parameters
GraphQL input types cannot be unions, so CandidateGenerationConfigInput uses the required type field to decide which other fields are used. Fields that do not apply to the selected type are ignored. type must match the interventionType it is configured under.
| Parameter | Type | Used When type Is | Default | Description |
|---|---|---|---|---|
| type | CandidateGenerationType | All | Required | Candidate generation method. One of CRITERIA, TAP_OPTIMIZATION, THERMAL_LINE_UPGRADE, VOLTAGE_LINE_UPGRADE, THERMAL_TRANSFORMER_UPGRADE. |
| interventionCriteriaName | TEXT | CRITERIA | Required | Name of the row in intervention_candidate_criteria used to select candidates from enhanced metrics in the parent work package. |
| sizingLookaheadYears | INTEGER | CRITERIA | 0 | Number of years after the first constraint violation to include when calculating required intervention capacity. Must be non-negative. Currently used by BESS sizing. |
| averageVoltageSpreadThreshold | INTEGER | TAP_OPTIMIZATION | Required | Average line voltage spread threshold under the transformer over the year, in volts. |
| voltageUnderLimitHoursThreshold | INTEGER | TAP_OPTIMIZATION | Required | Minimum annual hours below the nominal voltage range before a transformer is treated as persistently undervoltage. |
| voltageOverLimitHoursThreshold | INTEGER | TAP_OPTIMIZATION | Required | Minimum annual hours above the nominal voltage range before a transformer is treated as persistently overvoltage. |
| tapWeightingFactorLowerThreshold | DOUBLE | TAP_OPTIMIZATION | Required | Lower tap weighting threshold. Values below this threshold prioritise a positive tap adjustment (voltage boost). Usually negative. |
| tapWeightingFactorUpperThreshold | DOUBLE | TAP_OPTIMIZATION | Required | Upper tap weighting threshold. Values above this threshold prioritise a negative tap adjustment (voltage buck). Usually positive. |
| importValue | DOUBLE | THERMAL_LINE_UPGRADE, THERMAL_TRANSFORMER_UPGRADE | 1.0 | Risk multiplier for import (i.e. load) thermal overload energy, gives more or less priority to overload energy caused by import/load flow. A higher value raises the ranking of load-driven overloads. It changes prioritisation only; it does not change the required rating calculated for a candidate. Must be non-negative, and at least one of importValue or exportValue must be greater than 0.0. |
| exportValue | DOUBLE | THERMAL_LINE_UPGRADE, THERMAL_TRANSFORMER_UPGRADE | 0.1 | Risk multiplier for export (i.e. generation) thermal overload energy, gives more or less priority to overload energy caused by generation/export flow. A higher value raises the ranking of generation-driven transformer overloads. It changes prioritisation only; it does not change the required kVA calculated for a candidate. Must be non-negative, and at least one of importValue or exportValue must be greater than 0.0. |
| targetLoadingPct | DOUBLE | THERMAL_LINE_UPGRADE, THERMAL_TRANSFORMER_UPGRADE | 80.0 | Target loading percentage used to size the upgraded line conductor or transformer. The default of 80% means after upgrading a line the user can expect a minimum of 20% headroom on the new upgraded assets. Must be greater than 0.0. Lower values size for more headroom and so demand a larger conductor or transformer; if the catalogue has no entry big enough, the candidate is not upgraded and is no longer a valid intervention candidate. |
| targetVoltageSwingPu | DOUBLE | VOLTAGE_LINE_UPGRADE | 0.16 | Target voltage swing in p.u. This is one of the two settings that controls the detection of voltage driven interventions. Candiates for line upgrade are only generated from measurement_zones where the difference between min and max voltages over the modelled time period is greater than this value. The default is set of 0.16 which corresponds to 16% or the difference between 216v and 253v for a 230v nominal. Must be greater than 0.0. |
| voltageDeltaThresholdPu | DOUBLE | VOLTAGE_LINE_UPGRADE | 0.08 | Voltage delta threshold in p.u. Must be non-negative. |
| upstreamEffectivenessFactor | DOUBLE | VOLTAGE_LINE_UPGRADE | 1.0 | Effectiveness factor for upstream voltage line upgrades. Must be non-negative. |
| internalMzEffectivenessFactor | DOUBLE | VOLTAGE_LINE_UPGRADE | 0.5 | Effectiveness factor for internal measurement-zone voltage line upgrades. Must be non-negative. |
| defaultUpgradeReductionFactor | DOUBLE | VOLTAGE_LINE_UPGRADE | 0.6 | Default voltage reduction factor for upgraded lines. Must be non-negative. |
| targetHeadroomFactor | DOUBLE | VOLTAGE_LINE_UPGRADE | 1.1 | Headroom multiplier applied to voltage line upgrade sizing. Must be greater than 0.0. |
| minLineLengthM | DOUBLE | VOLTAGE_LINE_UPGRADE | 5.0 | Minimum line length in metres for voltage-line candidates. Must be non-negative. |
| minAvgAbsDeltaPu | DOUBLE | VOLTAGE_LINE_UPGRADE | 0.001 | Minimum average absolute voltage delta in p.u. for voltage-line candidates. Must be non-negative. |
For TAP_OPTIMIZATION, the underlying DTO has defaults of 40, 100, 100, -10.0, and 10.0 for the five tap optimisation fields above. The current GraphQL input requires those fields to be supplied when type is TAP_OPTIMIZATION.
The asset upgrade types - THERMAL_LINE_UPGRADE, VOLTAGE_LINE_UPGRADE and THERMAL_TRANSFORMER_UPGRADE - additionally require forecastConfig.years to be non-empty, free of duplicates, contiguous, and between 1 and 9999. They cannot be run from feederConfigs.
importValue and exportValue are relative weights, not currency values or percentages. For example, the default values of 1.0 and 0.1 make one unit of import overload energy count ten times as strongly as one unit of export overload energy when candidates are ranked. Setting both to 0.0 prevents candidate generation and is invalid; at least one must be greater than 0.0.
Supporting Input Types
YearRangeInput Parameters
| Parameter | Type | Description |
|---|---|---|
| minYear | INTEGER | Required. Earliest year in the candidate search and allocation range, inclusive. |
| maxYear | INTEGER | Required. Latest year in the candidate search and allocation range, inclusive. |
PhaseRebalanceProportionsInput Parameters
| Parameter | Type | Description |
|---|---|---|
| a | DOUBLE | Required. Relative target proportion of single-phase customers assigned to phase A. |
| b | DOUBLE | Required. Relative target proportion of single-phase customers assigned to phase B. |
| c | DOUBLE | Required. Relative target proportion of single-phase customers assigned to phase C. |
The three values are normalised internally, so they do not need to sum to 1.0. All values should be non-negative.
DvmsConfigInput Parameters
| Parameter | Type | Description |
|---|---|---|
| lowerLimit | DOUBLE | Required. Lower voltage limit, in p.u., considered acceptable for DVMS. |
| upperLimit | DOUBLE | Required. Upper voltage limit, in p.u., considered acceptable for DVMS. |
| lowerPercentile | DOUBLE | Required. Lowest percentile of customer voltages to consider when applying DVMS. |
| upperPercentile | DOUBLE | Required. Highest percentile of customer voltages to consider when applying DVMS. |
| maxIterations | INTEGER | Required. Number of DVMS iterations to attempt for each time step before moving on. |
| regulatorConfig | DvmsRegulatorConfigInput | Required. Voltage regulator settings used when the zone is already satisfactory according to the DVMS limits. |
DvmsRegulatorConfigInput Parameters
| Parameter | Type | Description |
|---|---|---|
| puTarget | DOUBLE | Required. Target p.u. voltage for average customer voltage regulation. |
| puDeadbandPercent | DOUBLE | Required. Width of the acceptable voltage window around puTarget, as percent p.u. |
| maxTapChangePerStep | INTEGER | Required. Maximum number of tap steps to move, in either direction, for each time step. |
| allowPushToLimit | BOOLEAN | Required. If true, the regulator can move some customers outside the DVMS limits, bounded by lowerPercentile and upperPercentile in DvmsConfigInput. |
LoadReshapingConfigInput Parameters
| Parameter | Type | Description |
|---|---|---|
| loadShapeCriteria | TEXT | Required. Name of the strategy set in load_reshape_strategies.criteria_name used to select loads for reshaping. |
Load Reshaping
Covers use cases such as tariff reform and controlled load hot water programs - both modify the time of use patterns of customer electricity loads via the same underlying logic and database tables.
Overview
Tables referenced:
- load_reshape_strategies - Defines targeting criteria and application rules. Strategies are applied in order of rank to matching customers (i.e. 1 gets applied first, then 2, etc.). A customer can only receive one load reshape, so once they have been assigned a strategy they are excluded from subsequent strategies. All specified filters must match for a customer to be eligible. NULL/omitted filters are ignored. Some filters will depend on what data is available. This table then references:
- load_reshape_instances - Contains the actual load modification profiles that are applied to customers.
Configuration Example
InterventionConfigInput(
parentWorkPackageId="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", # Required
loadReshaping=LoadReshapingConfigInput(
loadShapeCriteria="load_reshape_strategy_1" # References criteria_name in load_reshape_strategies table
)
)
COMMUNITY_BESS
Community Battery Energy Storage Systems (BESS), also called Neighbourhood BESS, are front-of-the-meter batteries installed in the low-voltage network to mitigate high load and generation issues, especially high solar penetration or very 'spiky' loads. This intervention addresses voltage and thermal constraint violations by strategically deploying batteries at identified problem locations.
Overview
The COMMUNITY_BESS intervention identifies candidate locations where network metrics exceed defined thresholds, then ranks and allocates battery installations based on the severity of constraints.
Tables referenced:
- intervention_candidate_criteria - Defines threshold conditions for identifying problem locations. This table defines the threshold conditions that measurement zones must exceed to qualify as intervention candidates. All specified (non-NULL) thresholds must be exceeded for a location to become a candidate.
- intervention_candidates - Stores identified candidates generated as per
intervention_candidate_criteriawith their rankings. Once the list of possible battery candidates has been generated following the rules in the intervention_candidate_criteria table, candidates are ranked based on the severity of constraints, based on the combined sum ofgen_exceeding_normal_thermal_voltage_cecvandload_exceeding_normal_thermal_voltage_vcracross all applicable years. This prioritization ensures that battery installations are targeted to locations with the most significant thermal and voltage issues, maximizing the impact of the intervention. - bess_allocation_criteria - Specifies battery placement and sizing rules (defaults are probably fine and are unlikely to need to be adjusted)
- bess_instances - Contains battery technical specifications and control parameters. Each instance defines a specific battery configuration that can be deployed.
- bess_profiles - Battery operational profiles to use if using
profilecontrol mode, uses the same table as the forecast profiles in non-intervention work packages.
Configuration Example
InterventionConfigInput(
parentWorkPackageId="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", # Required, used to query enhanced metrics
candidateIntervention=CandidateInterventionConfigInput(
interventionType=CandidateInterventionClass.COMMUNITY_BESS,
yearRange=YearRangeInput(minYear=2026, maxYear=2030), # Optional, defaults to the full range of years in the work package
allocationLimitPerYear=100, # Optional. Maximum number of batteries to install per year (not guaranteed to install all 100, as there may be reasons why it can't allocate a certain candidate, e.g. due to phasing)
candidateGeneration=CandidateGenerationConfigInput(
type=CandidateGenerationType.CRITERIA, # Required for COMMUNITY_BESS
interventionCriteriaName="bess_threshold_set_1", # References intervention_candidate_criteria.name
sizingLookaheadYears=3 # Optional, defaults to 0.
),
candidateAllocationCriteria="bess_allocation_criteria_1", # References bess_allocation_criteria.name
allocationInstanceSelection=["peakshave_150kw_3ph", "peakshave_100kw_3ph"], # Optional, pass in a single instance or more than one. If more than 1, they will be sized according to the logic below. If left as null, all available instances in the table will be used for sizing.
)
)
BESS Sizing
The system automatically selects the battery size for each candidate location using the following process, choosing from the instances passed in via the allocationInstanceSelection parameter, or the full bess_instances table if no list is passed in:
Required kW rating is calculated from thermal metrics
The candidate's required kW rating (min_bess_maxP_kw) is written to the intervention_candidates table during candidate generation, based on the maximum peak instantaneous kW across the first N years, where N is the sizingLookaheadYears, scaled based on the direction of the constraint:
- Load-driven thermal violation:
min_bess_maxP_kw=load_exceeding_normal_thermal_max_kw(from the base work package network_performance_metrics_enhanced table) - Generation-driven thermal violation:
min_bess_maxP_kw= 0.75 xgen_exceeding_normal_thermal_max_kw(from the base work package network_performance_metrics_enhanced table)
The 0.75 discount for generation-driven violations reflects that curtailing export is considered less critical than preventing an overload under load conditions. This factor is hardcoded.
Instance is selected from bess_instances
The system selects the most appropriate instance that meets the required capacity (meaning the smallest one that exceeds the minimum size), preferring instances that match the installation year and feeder if those filters are used. The instance's phasing must match the line at the chosen location.
The capacity_scaling_factor (set in bess_allocation_criteria) adds headroom above the calculated requirement. For example, a value of 1.2 means the selected instance must be rated at least 20% above the minimum required kW.
Example: there are 3 sizes in the list: 50kW, 75kW and 100kW. If a specific candidate has a base minimum size of 72kW:
- If
capacity_scaling_factor= 1.0, then the 75kW BESS would be chosen - If
capacity_scaling_factor= 1.2, then the minimum size = 72 x 1.2 = 86.4kW, meaning the 100kW BESS would be chosen.
If the minimum size is larger than any of the available instances, the largest matching one is selected.
If the minimum size is zero, the smallest matching one is selected.
The list is chosen via the allocationInstanceSelection parameter. If this is left out of the config or set to null, then all the instances in the table are chosen from.
If a single instance is given, e.g. allocationInstanceSelection=["standard_BESS"], then that instance will be applied to all suitable locations (it must still match phasing requirements; if not suitable, nothing will be allocated).
If a list of multiple values is given, then the sizing chooses from those, e.g. allocationInstanceSelection=["peakshave_50kw_3ph", "peakshave_100kw_3ph", "peakshave_150kw_3ph"]
BESS Modes
There are 5 valid modes that batteries can operate in, which are the allowable options for mode in the bess_instances table:
peakshave
Charges when load is low, discharges when load is high. This is measured against the LV transformer for that allocation.
The charge and discharge thresholds are expressed as a percentage of the target asset's kVA rating: the battery charges when the power falls below percentage_rated_kva_target_charging, and discharges when the power rises above percentage_rated_kva_target_discharging (both set in the bess_instances table). The battery will attempt to keep the power at these levels, within the deadband defined by percentage_rated_kva_deadband. This means the battery both fills in the load troughs while charging and shaves the peaks while discharging.
Note that depending on the load conditions on that transformer, there is no guarantee that the battery will cycle properly. If you put the charge threshold at 20%, but the base load on that transformer means it never gets below 30% of its rating, then it will never charge and is thus unable to discharge. Likewise, if the discharge percentage is set at 90%, and it never goes above that, it will never discharge.
Example:

time
Charges and discharges based on time of day. This mode operates on a fixed schedule, beginning charging and discharging at predetermined times regardless of real-time power conditions. In this mode, the battery will start to charge according to the charge_trigger and start to discharge based on the discharge_trigger parameters. The trigger values are integer values from 0-23 representing the hour of the day (in 24-hour format) when the action should occur. It will charge at the specified charging_rate until full, and discharge at the discharge_rate until empty.
Example:

following
For charging, this mode operates just like the time mode.
For discharging, this is similar to peakshave, but the difference is that there is no fixed target value. The target varies according to the power measured at the time specified in discharge_trigger property. Whatever the power level is at the time of discharge will be the target, and the battery will attempt to output within its allowed discharge rate to keep it at that value. In most scenarios, this will typically mean the battery cycles more across a year than in peakshave mode.
Example:

profile
When in this mode, the battery operates according to the profile specified in the profile_id, which links to the corresponding array in the bess_profiles table. That normalised profile will be scaled according to the size of the battery. Note that this does not do any validation on the battery size vs profile values, so it is up to the user to ensure that the profile is suitable for the battery size (i.e. if configured incorrectly, there is nothing stopping a battery from discharging more than its maximum energy storage capacity), and nothing stopping the battery from running at non-ideal times (e.g. charging at times of high demand).
Example:

time_peakshave
This mode is a hybrid of the time and peakshave modes. The battery will charge according to the time-based schedule defined by charge_trigger and charging_rate, but will discharge according to the peakshave logic. Note that the same caveat about setting the discharge % trigger applies as in peakshave mode.
For profile mode, the batteries are modelled as loads/generators in OpenDSS, whereas in the other modes, they are modelled as storage elements, which come with certain characteristics. For example, they assume the battery starts the year at 0% state of charge and have other basic parameters assigned that are not relevant in profile mode.
LV_STATCOMS
Low Voltage Static Synchronous Compensators (LV STATCOMs) are voltage regulating devices installed on LV networks to provide dynamic reactive power compensation. These power electronics-based devices act as either a source or sink of reactive AC power, rapidly responding to voltage fluctuations to maintain network stability.
Overview
Candidates are identified where network metrics exceed defined thresholds, then ranked and allocated based on the severity of constraints. Candidates are prioritized by the combined sum of:
gen_exceeding_normal_voltage_cecv(generation causing voltage violations)load_exceeding_normal_voltage_vcr(load causing voltage violations)
This sum is calculated across all applicable years for each candidate location.
Tables referenced:
- intervention_candidate_criteria - Defines threshold conditions for identifying problem locations. All specified (non-NULL) thresholds must be met or exceeded (i.e. ≥) for a location to become a candidate.
- intervention_candidates - Stores identified candidates with their rankings. Candidates are generated based on the criteria specified in
intervention_candidate_criteria. Candidates are ranked by the sum ofgen_exceeding_normal_voltage_cecvandload_exceeding_normal_voltage_vcracross all applicable years - lv_statcom_allocation_criteria - Specifies STATCOM placement rules and network compatibility requirements. The
minimum_x_r_ratiofilter ensures STATCOMs are only deployed where network characteristics allow effective reactive power support. Networks with insufficient inductance (low X/R ratio) may not benefit from STATCOM installation. - lv_statcom_instances - Contains the technical specifications and control parameters for STATCOM devices. Each instance defines a specific STATCOM configuration that can be deployed.
Configuration Example
InterventionConfigInput(
parentWorkPackageId="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", # Required, used to query enhanced metrics
candidateIntervention=CandidateInterventionConfigInput(
interventionType=CandidateInterventionClass.LV_STATCOMS,
yearRange=YearRangeInput(minYear=2026, maxYear=2030), # Optional, defaults to the full range of years in the work package
allocationLimitPerYear=100, # Optional. Maximum number of LV STATCOMs to install per year
candidateGeneration=CandidateGenerationConfigInput(
type=CandidateGenerationType.CRITERIA, # Required for LV_STATCOMS, references intervention_candidate_criteria.name
# Defines thresholds (e.g., min_voltage_outside_limits_hours), measurement zones exceeding ALL specified thresholds become candidates
interventionCriteriaName="threshold_set_2"
),
candidateAllocationCriteria="lv_statcom_allocation_criteria_1", # References lv_statcom_allocation_criteria.name
allocationInstanceSelection=["lv_statcom_instance_1"], # Optional: references lv_statcom_instances.name (if not specified, the first matching instance in the lv_statcom_instances table is used)
)
)
Unlike COMMUNITY_BESS, there is no sizing aspect to LV STATCOMs. When allocationInstanceSelection is omitted, the system simply selects the first instance that matches the year and feeder requirements in the lv_statcom_instances table. To avoid unexpected results, it is recommended to specify a particular instance explicitly.
minimum_x_r_ratio
When placing a STATCOM, the system traces the cable path from each downstream energy consumer back to the distribution transformer and accumulates the total reactance (X) and resistance (R) of each segment. For each candidate installation node along that path it computes:
X/R = (total reactance from transformer to node) / (total resistance from transformer to node)
If this ratio does not exceed minimum_x_r_ratio, the STATCOM is not placed at that node.
A STATCOM can only move voltages by sinking or sourcing VArs through the upstream reactance X. If voltage deviations in a network are primarily caused by resistance R (typical of short, resistive LV cable stubs), the STATCOM has little effect. Adjust this threshold to target areas where STATCOMs are best suited to providing voltage support and therefore likely to deliver the greatest value.
Guidance for setting it
| Value | Effect |
|---|---|
NULL or 0.0 | No filter - STATCOM can be placed anywhere regardless of network characteristics. |
~0.3 | Minimum recommended value. Permits STATCOMs at most candidate locations, including areas with predominantly resistive cable. |
~0.5 | Filters out rural or resistive sites where STATCOMs are less efficient, focusing placements on locations where reactive compensation is more effective. |
> 0.5 | Restricts placement to locations where STATCOMs are most effective - areas with higher network inductance where VAr injection has the greatest voltage impact. |
DVMS
Dynamic Voltage Management Systems (DVMS) provide real-time voltage regulation by automatically adjusting feeder head (zone substation) transformer taps based on customer voltage measurements. DVMS only adjusts feeder head taps: distribution transformer taps are not controlled.
Overview
DVMS addresses voltage quality issues through adaptive control of feeder head on-load tap changers (OLTCs). The system continuously monitors customer voltages and adjusts taps to maintain acceptable voltage levels as network conditions change.
Operation:
- Gathers voltage data from multiple customer measurement points downstream of each transformer
- Adjusts feeder head transformer taps at each simulation time step to keep customer voltages within target ranges
- Most computationally intensive intervention - requires solving the network one time step at a time (will add to solving time)
Tables referenced: None - entirely configured via intervention parameters
Any RegControl associated with the Zone Sub is disabled so it cannot affect transformer behaviour. The initial tap position is set to neutral. This may result in slower convergence at the start of a simulation, as it can take several time steps for the control loops to move the tap into an effective range.
Configuration Example
InterventionConfigInput(
parentWorkPackageId="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", # Required
# DVMS applies across all years covered by the work package - there is no separate year range for it
dvms=DvmsConfigInput(
# Voltage acceptance criteria
lowerLimit=0.9, # Minimum acceptable voltage (per unit)
upperLimit=1.1, # Maximum acceptable voltage (per unit)
lowerPercentile=5, # Lower percentile of customer voltages to consider (excludes extreme low outliers)
upperPercentile=95, # Upper percentile of customer voltages to consider (excludes extreme high outliers)
maxIterations=3, # Maximum tap adjustment attempts per time step, after this the solver will move to the next time step regardless of success.
regulatorConfig=DvmsRegulatorConfigInput(
puTarget=1.0, # Target voltage (per unit)
puDeadbandPercent=12, # Deadband width as % of target (e.g., 12 → +/-6% → 0.94-1.06 p.u. with target=1.0)
maxTapChangePerStep=2, # Maximum tap positions to change per iteration
allowPushToLimit=True # If true, allow tap changes that improve one side of voltage distribution even if worsening the other
)
)
)
PHASE_REBALANCING
Phase rebalancing redistributes single-phase customers across phases A, B, and C according to specified proportions to correct uneven phase loading.
Overview
This intervention addresses networks with imbalanced distribution of single-phase customers across the three phases. It reallocates customers to achieve a more balanced load distribution, reducing phase voltage imbalances and improving network efficiency.
Note that this intervention considers customers one by one and can be limited by what phases are available at a given location, so the actual achieved proportions may differ from the target proportions specified in the intervention parameters, especially in network areas with large spurs all on a single phase. Also note that this intervention targets customer count, not load, so even a perfect balance of customers may not result in a perfect balance of load across phases.
Tables referenced: None - entirely configured via intervention parameters
Configuration Example
InterventionConfigInput(
parentWorkPackageId="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", # Required
# Phase rebalancing applies across all years covered by the work package - there is no separate year range for it
phaseRebalanceProportions=PhaseRebalanceProportionsInput(
# Target proportions for redistributing single-phase customers
# Values do not need to sum to 1 (they are normalized internally), but all values must be non-negative
# For even distribution, use: a=1, b=1, c=1
a=0.25, # 25% of customers allocated to phase A
b=0.35, # 35% of customers allocated to phase B
c=0.4 # 40% of customers allocated to phase C
)
)
DISTRIBUTION_TAP_OPTIMIZATION
Distribution tap optimization identifies measurement zones with persistent voltage compliance issues and recommends static distribution transformer tap setting changes on an annual basis using heuristic analysis of voltage statistics from the base work package.
Overview
Key differences from DVMS
- Tap settings change at most once per transformer per year, not every time step.
- Not a real-time feedback system - candidates are generated from base work package results.
- Significantly less computationally intensive.
Tables referenced:
Candidate selection happens via the config values, NOT the intervention_candidate_criteria table. Candidates are stored in the intervention_candidates table.
Applicability and annual allocation Tap optimization is designed to be applicable to all distribution transformers by default (static improvements to persistent bias).
Unlike criteria-based interventions (COMMUNITY_BESS, LV_STATCOMS, DISTRIBUTION_TX_OLTC) where a candidate spans the full year range, each tap optimization candidate covers a single transformer in a single year. Tap positions are re-evaluated independently per simulation year, so the same transformer may be a candidate in multiple years with different recommended tap settings.
To approximate operational restrictions (i.e. a works program that has budget to modify only X transformers per year), the intervention can be capped using allocationLimitPerYear.
When a cap is applied, candidates are ranked by the p.u. deviation of the worst-case voltage percentile from nominal (1.0 p.u.) - V1 for boost candidates and V99 for buck candidates (defined below). The candidate with the greatest deviation ranks first.
Configuration example
InterventionConfigInput(
parentWorkPackageId="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", # Required, used to query voltage metrics from base scenario
candidateIntervention=CandidateInterventionConfigInput(
interventionType=CandidateInterventionClass.DISTRIBUTION_TAP_OPTIMIZATION,
yearRange=YearRangeInput(minYear=2026, maxYear=2030), # Optional, defaults to the full range of years in the work package
allocationLimitPerYear=50, # Optional, leave out to apply to an unlimited number of transformers per year
candidateGeneration=CandidateGenerationConfigInput(
type=CandidateGenerationType.TAP_OPTIMIZATION, # Required for DISTRIBUTION_TAP_OPTIMIZATION
# Voltage thresholds (applied per measurement zone per year)
averageVoltageSpreadThreshold=40,
voltageUnderLimitHoursThreshold=48,
voltageOverLimitHoursThreshold=48,
# (these metrics are explained below)
# Tap weighting thresholds (direction arbitration)
# Default values (-10.0, 10.0) are suitable for most cases
tapWeightingFactorLowerThreshold=-10.0,
tapWeightingFactorUpperThreshold=10.0
)
)
)
Key metrics and parameters
voltage_delta_avg (metric)
The average voltage range across nodes in the measurement zone, pooled across phases and timesteps over the relevant time period (not the worst-case phase per timestep — all phases are pooled together).
Average(phv.phs1.max - phv.phs1.min, phv.phs2.max - phv.phs2.min, phv.phs3.max - phv.phs3.min) pooled over all phases and timesteps
Higher values indicate larger typical voltage spread between nodes (weak networks, long runs, or phase imbalance). Note: voltage_delta_avg is in p.u. but is converted to volts for comparison with averageVoltageSpreadThreshold.
averageVoltageSpreadThreshold (swing gating)
When voltage_delta_avg (in volts) exceeds this threshold, the network has significant spatial voltage spread and the algorithm restricts itself to 1-step tap changes. Below it, 2-step changes may be recommended for clearly high or low voltage regimes. Specify in phase-to-phase volts (e.g. 40 = 40V = 10% of 400V nominal).
Persistence thresholds: voltageUnderLimitHoursThreshold and voltageOverLimitHoursThreshold
Minimum annual hours of under/overvoltage before the algorithm treats an issue as persistent enough to justify a tap change. Defaults have been tuned to avoid acting on short-lived or non-representative excursions.
voltageUnderLimitHoursThreshold: minimum hours below the lower voltage boundvoltageOverLimitHoursThreshold: minimum hours above the upper voltage bound
V1_avg and V99_avg (voltage distribution inputs)
V1_avg is the 1st percentile and V99_avg is the 99th percentile of average node voltages across the measurement zone in p.u. They characterise the low and high tails of the annual voltage distribution: V1_avg represents typical worst-case undervoltage conditions; V99_avg represents typical worst-case overvoltage conditions. Both are used throughout the decision logic and ranking below.
Direction arbitration: tapWeightingFactorLowerThreshold & tapWeightingFactorUpperThreshold
When both hour thresholds are exceeded, a weighting factor determines which side dominates before a direction is recommended:
tapWeightingFactor = (|V99_avg - 1.0| * hours_over_limit) - (|V1_avg - 1.0| * hours_under_limit)
- Positive (overvoltage dominates): if >
tapWeightingFactorUpperThreshold→ buck candidate - Negative (undervoltage dominates): if <
tapWeightingFactorLowerThreshold→ boost candidate - Within the deadband: no tap change recommended
This prevents small offsetting exceedances from driving tap changes that improve one voltage tail while worsening the other.
The directional p.u. thresholds within the decision logic (1.1, 0.94, 0.91, 1.075) are fixed and not user-configurable. Only the four parameters above (averageVoltageSpreadThreshold, voltageUnderLimitHoursThreshold, voltageOverLimitHoursThreshold, and the tap weighting factor thresholds) can be tuned.
DISTRIBUTION_TX_OLTC
Distribution Transformer On-Load Tap Changers (OLTC) enable voltage regulation at distribution transformers by allowing tap position changes under load conditions, without interrupting power supply.
Overview
This intervention retrofits existing distribution transformers with on-load tap changing capability, allowing dynamic voltage control to address network voltage issues. OLTCs provide automated tap adjustment in response to network conditions, improving voltage quality for downstream customers.
Candidates are identified where network metrics exceed defined thresholds, then ranked and allocated based on the severity of constraints. Candidates are prioritized by the combined sum of:
gen_exceeding_normal_voltage_cecv(generation causing voltage violations)load_exceeding_normal_voltage_vcr(load causing voltage violations)
This sum is calculated across all applicable years for each candidate location.
Tables referenced:
- intervention_candidate_criteria - Defines threshold conditions for identifying problem locations. All specified (non-NULL) thresholds must be exceeded for a location to become a candidate.
- intervention_candidates - Stores identified candidates with their rankings.
- distribution_transformer_oltc_allocation_criteria - Specifies OLTC installation rules and requirements
- distribution_transformer_oltc_instances - Contains OLTC technical specifications and control parameters. Each instance defines a specific OLTC configuration that can be deployed.
Configuration Example
InterventionConfigInput(
parentWorkPackageId="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", # Required, used to query enhanced metrics
candidateIntervention=CandidateInterventionConfigInput(
interventionType=CandidateInterventionClass.DISTRIBUTION_TX_OLTC,
yearRange=YearRangeInput(
minYear=2026, # Earliest year to identify and apply intervention candidates
maxYear=2030 # Latest year to identify and apply intervention candidates
), # Optional, defaults to the full range of years in the work package
allocationLimitPerYear=50, # Optional. Maximum number of OLTCs to install per year
candidateGeneration=CandidateGenerationConfigInput(
type=CandidateGenerationType.CRITERIA, # Required for DISTRIBUTION_TX_OLTC
# References intervention_candidate_criteria.name
# Defines thresholds (e.g., min_voltage_outside_limits_hours)
# Measurement zones exceeding ALL specified thresholds become candidates
interventionCriteriaName="threshold_set_2"
),
candidateAllocationCriteria="distribution_transformer_oltc_allocation_criteria_1", # References distribution_transformer_oltc_allocation_criteria.name
allocationInstanceSelection=["distribution_transformer_oltc_instance_1"], # Optional: references distribution_transformer_oltc_instances.name
# If specified, only this OLTC type is used
# If omitted, first suitable instance is selected
# Only 1 instance is allowed in this list
)
)
THERMAL_LINE_UPGRADE
Thermal line upgrade replaces overloaded line segments with a conductor catalogue entry that has enough current rating to bring the line loading back to the configured target loading percentage.
Why use this intervention?
Use THERMAL_LINE_UPGRADE when the study shows that one or more lines cannot carry the modelled load or generation without exceeding their normal thermal rating. A thermal overload can limit the amount of demand or distributed generation the network can host, and repeated overloads can indicate that the existing conductor is no longer adequate for the forecast.
The intervention tests a practical network solution: replacing the existing conductor with a compatible item from conductor_catalog. It ranks the lines with the greatest weighted thermal overload exposure, then sizes the replacement so that the observed peak current would remain below the configured target loading percentage.
Expected impact
- The selected conductor is applied to the original CIM line asset or assets that correspond to the overloaded simplified OpenDSS line. The intervention does not replace only the simplified study object.
- A lower
targetLoadingPctprovides more thermal headroom, but may require a larger catalogue conductor and increase the installed cost. If no compatible catalogue row is large enough, the candidate is not applied. importValueandexportValuechange which candidates are prioritised; they do not change the network model or the conductor rating required for an individual candidate.allocationLimitPerYearlimits the combined length of line that can be upgraded in each year. It represents delivery, programme, or budget capacity; it is not a promise that every metre within the limit will be allocated.- The benefit is estimated from the parent work package. Run and compare the intervention work package with its parent to confirm the resulting network loading, because changing one line can change flows elsewhere in the network.
Overview
This intervention is generated from asset-level thermal loading summaries in the parent work package. It does not use intervention_candidate_criteria or a separate allocation criteria table. Candidate generation finds simplified OpenDSS line assets with hours_over_normal > 0, maps them back to the original CIM AcLineSegment assets, calculates the required replacement current rating, ranks the candidates, then allocation applies a matching row from conductor_catalog.
Candidates are grouped by feeder and simplified line mRID. If a simplified line maps to multiple original CIM line segments, all mapped original lines are upgraded together as one candidate.
Candidates are ranked by:
score = importValue * overload_kwh_import + exportValue * overload_kwh_export
importValue and exportValue let you decide whether load-driven overloads, export-driven overloads, or both should drive prioritisation. A candidate with a score less than or equal to 0.0 is not generated.
The required conductor current rating is calculated from the peak current observed after the first overloaded year:
required_rating = max_current / (targetLoadingPct / 100.0)
For example, if a line reaches 220 A and targetLoadingPct is 80.0, the selected conductor must be rated at least 275 A. Lower targetLoadingPct values create more headroom but require larger catalogue entries.
Tables referenced:
- asset_level_thermal_loading_summary - Source results table used to identify overloaded line assets and calculate overload energy, maximum loading, and required rating.
- cim_to_opendss - Maps simplified OpenDSS lines back to the original CIM
AcLineSegmentmRIDs that will be upgraded. - intervention_candidates - Stores the generated candidate rows, including ranking, target original mRIDs, score, required rating, and line length.
- conductor_catalog - Selectable replacement conductor catalogue.
allocationInstanceSelectionfilters this table byidwhen supplied. - applied_line_upgrade - Output table containing the actual line upgrade allocations that were applied.
Configuration Example
InterventionConfigInput(
parentWorkPackageId="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", # Required, used to query asset-level thermal results
candidateIntervention=CandidateInterventionConfigInput(
interventionType=CandidateInterventionClass.THERMAL_LINE_UPGRADE,
yearRange=YearRangeInput(
minYear=2026,
maxYear=2030
), # Optional, defaults to the full range of years in the work package
allocationLimitPerYear=5000, # Optional. Maximum metres of line to upgrade per year
candidateGeneration=CandidateGenerationConfigInput(
type=CandidateGenerationType.THERMAL_LINE_UPGRADE,
importValue=1.0, # Optional, defaults to 1.0
exportValue=0.1, # Optional, defaults to 0.1
targetLoadingPct=80.0 # Optional, defaults to 80.0
),
allocationInstanceSelection=[
"lv_overhead_300a",
"lv_overhead_400a",
"lv_cable_400a"
] # Optional: conductor_catalog.id values. If omitted, all conductor_catalog rows are considered.
)
)
Do not set candidateAllocationCriteria for this intervention. The yearly allocation limit and years are taken from allocationLimitPerYear and yearRange.
Candidate Selection and Allocation
A thermal line upgrade candidate is generated only when all of the following are true:
- The parent work package has an
asset_level_thermal_loading_summaryrow for a simplified line asset in the selected scenario, feeder, and year range. - The asset has
hours_over_normal > 0. - The simplified line maps through
cim_to_opendssto at least one original CIMAcLineSegment. max_currentis available, so a required conductor rating can be calculated.- The weighted import/export overload score is greater than
0.0.
Allocation then selects the smallest viable conductor catalogue row for each target original line. A conductor is viable when it:
- Has
rated_current >= required_rating. - Matches the line voltage, either by
applicable_base_voltages_vor byvoltage_level. - Supports the line phase count and neutral requirement.
- Has the same
wire_info_classas the existing line:OverheadWireInfofor overhead lines andCableInfofor underground lines. - Does not increase the line positive-sequence impedance magnitude.
If a collapsed candidate maps to multiple original line segments, the same conductor catalogue row must be viable for every segment. If different target segments would choose different catalogue rows, no allocation is produced for that candidate.
allocationLimitPerYear is measured in metres for this intervention. Each candidate's weight is the combined length of the target original line segments (total_length_m).
THERMAL_TRANSFORMER_UPGRADE
Thermal transformer upgrade replaces overloaded transformers with a transformer catalogue entry sized to bring the transformer loading back to the configured target loading percentage.
Why use this intervention?
Use THERMAL_TRANSFORMER_UPGRADE when a distribution transformer is the asset limiting the amount of load or generation that can be connected downstream. The intervention looks for transformers that exceed their normal thermal rating in the parent study and tests a larger, compatible transformer from transformer_catalog.
This is a targeted capacity reinforcement: it increases the transformer's available apparent-power capacity rather than changing customer demand, generation, or operating controls. It is most useful when the transformer itself is the bottleneck identified by the study.
Expected impact
- The selected transformer is applied to the original CIM transformer corresponding to the overloaded simplified OpenDSS transformer.
- A lower
targetLoadingPctprovides more spare transformer capacity, but requires a larger catalogue transformer. If no compatible catalogue row is large enough, the candidate is not applied. importValueandexportValuechange which transformer candidates are prioritised; they do not change the required kVA for an individual candidate.allocationLimitPerYearlimits the number of transformers upgraded in each year, representing delivery, programme, or budget capacity.- This intervention addresses transformer thermal capacity. It does not by itself resolve voltage swing, voltage-limit, or downstream line constraints; those require the relevant voltage or line intervention and should be checked in the rerun.
Overview
This intervention is generated from asset-level thermal loading summaries in the parent work package. It does not use intervention_candidate_criteria or a separate allocation criteria table. Candidate generation finds simplified OpenDSS transformer assets with hours_over_normal > 0, calculates the required replacement kVA, ranks the candidates, then allocation applies a matching row from transformer_catalog.
Candidates are grouped by feeder and transformer mRID. They are ranked by the same weighted overload-energy score used for thermal line upgrades:
score = importValue * overload_kwh_import + exportValue * overload_kwh_export
The required transformer rating is calculated from the peak loading observed after the first overloaded year:
peak_loading_kva = normal_rating * max_loading_pct / 100.0
required_kva = peak_loading_kva / (targetLoadingPct / 100.0)
For example, if a 500 kVA transformer reaches 120% loading and targetLoadingPct is 80.0, the selected replacement must be rated at least 750 kVA.
Tables referenced:
- asset_level_thermal_loading_summary - Source results table used to identify overloaded transformer assets and calculate overload energy, peak loading, and required kVA.
- cim_to_opendss - Used to confirm that the overloaded asset is a simplified
PowerTransformer. - intervention_candidates - Stores the generated candidate rows, including ranking, score, required kVA, and peak loading.
- transformer_catalog - Selectable replacement transformer catalogue.
allocationInstanceSelectionfilters this table byidwhen supplied. - applied_transformer_upgrade - Output table containing the actual transformer upgrade allocations that were applied.
Configuration Example
InterventionConfigInput(
parentWorkPackageId="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", # Required, used to query asset-level thermal results
candidateIntervention=CandidateInterventionConfigInput(
interventionType=CandidateInterventionClass.THERMAL_TRANSFORMER_UPGRADE,
yearRange=YearRangeInput(
minYear=2026,
maxYear=2030
), # Optional, defaults to the full range of years in the work package
allocationLimitPerYear=25, # Optional. Maximum number of transformers to upgrade per year
candidateGeneration=CandidateGenerationConfigInput(
type=CandidateGenerationType.THERMAL_TRANSFORMER_UPGRADE,
importValue=1.0, # Optional, defaults to 1.0
exportValue=0.1, # Optional, defaults to 0.1
targetLoadingPct=80.0 # Optional, defaults to 80.0
),
allocationInstanceSelection=[
"dist_tx_750kva",
"dist_tx_1000kva"
] # Optional: transformer_catalog.id values. If omitted, all transformer_catalog rows are considered.
)
)
Do not set candidateAllocationCriteria for this intervention. The yearly allocation limit and years are taken from allocationLimitPerYear and yearRange.
Candidate Selection and Allocation
A thermal transformer upgrade candidate is generated only when all of the following are true:
- The parent work package has an
asset_level_thermal_loading_summaryrow for a simplified transformer asset in the selected scenario, feeder, and year range. - The asset has
hours_over_normal > 0. - The asset is mapped as a simplified
PowerTransformer. - The weighted import/export overload score is greater than
0.0.
Allocation selects the smallest viable transformer catalogue row. A transformer is viable when it:
- Has
rated_kva >= required_kva. - Matches the existing primary and secondary voltage, either by the applicable base-voltage lists or by the primary and secondary voltage-level fields.
- Supports the existing primary and secondary phase codes.
- Has the same transformer function kind as the existing transformer.
- Preferably has the same construction kind as the existing transformer. If no construction-matching row is viable, allocation falls back to rows that match the other requirements but not construction kind.
allocationLimitPerYear is a count for this intervention. Each candidate has a weight of 1.0.
VOLTAGE_LINE_UPGRADE
Voltage line upgrade replaces line segments to reduce voltage swing issues around transformer measurement zones. It uses asset-level voltage summaries to identify lines that contribute to voltage movement, then chooses lower-impedance conductor catalogue rows that are expected to capture the most voltage value per metre upgraded.
Why use this intervention?
Use VOLTAGE_LINE_UPGRADE when the study shows that customers in a transformer measurement zone experience excessive voltage movement and the contributing line impedance is a likely part of the problem. Long lines and lines carrying changing load or generation can contribute to voltage drop during import and voltage rise during export. Replacing a conductor with a lower-impedance compatible option can reduce that movement along the relevant path.
The intervention estimates which line replacements are most useful by combining the voltage problem in the measurement zone with each related line's observed voltage movement. It is intended to help compare reinforcement options across a feeder, not to guarantee a particular voltage result before the network is rerun.
Expected impact
- The intervention changes the conductor information on the original CIM line asset or assets mapped to the candidate simplified OpenDSS line. A simplified result line is evidence for the candidate; it is not the asset that is ultimately modified.
- A lower
targetVoltageSwingPuasks the candidate generator to address more of the observed voltage swing. This generally requires a larger impedance reduction and can reduce the number of catalogue options that remain viable. upstreamEffectivenessFactorandinternalMzEffectivenessFactorare heuristic factors used when estimating how much of a measurement-zone problem a line can influence. Changing them can change rankings without changing the network model directly.defaultUpgradeReductionFactoris a fallback estimate when the required impedance information is unavailable. Results based on the fallback should be treated as less certain.allocationLimitPerYearlimits the combined length of line that can be upgraded in each year. A candidate can still be skipped if the conductor catalogue cannot meet the voltage-reduction and compatibility requirements.- The estimate is path-based and may involve multiple original lines.
Overview
This intervention is generated from transformer-level enhanced metrics and asset-level voltage summaries in the parent work package. It does not use intervention_candidate_criteria or a separate allocation criteria table.
Candidate generation starts with transformer measurement zones that have voltage issues. A transformer zone is eligible in a year when:
- It is a transformer measurement zone.
- It has
maximum_section_voltageandminimum_section_voltage. - The sum of
load_exceeding_normal_thermal_voltage_vcrandgen_exceeding_normal_thermal_voltage_cecvis greater than0.0. - Either its voltage swing exceeds
targetVoltageSwingPu, or its maximum voltage delta exceedsvoltageDeltaThresholdPu.
The required correction for that transformer-zone year is:
All voltage values in this calculation are per-unit values on the measurement zone's voltage base. Multiply them by v_base only when converting the result for display in volts; compare them directly with the p.u. configuration values.
required_correction_pu = max(
maximum_section_voltage - minimum_section_voltage - targetVoltageSwingPu,
voltage_delta_max - voltageDeltaThresholdPu,
0.0
)
The generator then traces upstream lines from the transformer and downstream lines in the transformer's LV feeder. It maps those original CIM line mRIDs to simplified OpenDSS line assets, reads their asset_level_voltage_summary.avg_abs_delta, and attributes the transformer-zone value across related lines in proportion to each line's average absolute voltage delta.
Candidates are grouped by feeder and simplified line mRID. If a simplified line maps to multiple original CIM line segments, all mapped original lines are upgraded together as one candidate.
Tables referenced:
- network_performance_metrics_enhanced - Source table used to find transformer measurement zones with voltage swing or voltage-delta issues.
- asset_level_voltage_summary - Source table used to estimate how strongly each related line contributes to voltage movement.
- cim_to_opendss - Maps original CIM
AcLineSegmentassets to simplified OpenDSS line assets and back to the original line mRIDs that will be upgraded. - intervention_candidates - Stores the generated candidate rows, including target original mRIDs, recommended conductor, captured value, value per metre, and measurement-zone breakdown.
- conductor_catalog - Selectable replacement conductor catalogue.
allocationInstanceSelectionfilters this table byidduring candidate generation when supplied. - applied_line_upgrade - Output table containing the actual line upgrade allocations that were applied.
Configuration Example
InterventionConfigInput(
parentWorkPackageId="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", # Required, used to query voltage metrics and asset-level voltage results
candidateIntervention=CandidateInterventionConfigInput(
interventionType=CandidateInterventionClass.VOLTAGE_LINE_UPGRADE,
yearRange=YearRangeInput(
minYear=2026,
maxYear=2030
), # Optional, defaults to the full range of years in the work package
allocationLimitPerYear=5000, # Optional. Maximum metres of line to upgrade per year
candidateGeneration=CandidateGenerationConfigInput(
type=CandidateGenerationType.VOLTAGE_LINE_UPGRADE,
targetVoltageSwingPu=0.16, # Optional, defaults to 0.16
voltageDeltaThresholdPu=0.08, # Optional, defaults to 0.08
upstreamEffectivenessFactor=1.0, # Optional, defaults to 1.0
internalMzEffectivenessFactor=0.5, # Optional, defaults to 0.5
defaultUpgradeReductionFactor=0.6, # Optional, defaults to 0.6
targetHeadroomFactor=1.1, # Optional, defaults to 1.1
minLineLengthM=5.0, # Optional, defaults to 5.0
minAvgAbsDeltaPu=0.001 # Optional, defaults to 0.001
),
allocationInstanceSelection=[
"lv_overhead_low_impedance",
"lv_cable_low_impedance"
] # Optional: conductor_catalog.id values. If omitted, all conductor_catalog rows are considered.
)
)
Do not set candidateAllocationCriteria for this intervention. The yearly allocation limit and years are taken from allocationLimitPerYear and yearRange.
Voltage line upgrade configuration
This configuration controls which voltage issues qualify, how candidate line influence is estimated, which conductor options are available, and how much work can be applied each year.
Set both interventionType and candidateGeneration.type to VOLTAGE_LINE_UPGRADE. These select the voltage-line candidate-generation logic. candidateAllocationCriteria is not used and should be omitted.
Voltage thresholds and movement values are expressed in per-unit (p.u.) on the relevant measurement-zone voltage base.
| Configuration item | Why you might change it | Impact of the setting |
|---|---|---|
parentWorkPackageId | Select the baseline study whose measurement-zone and line-voltage results should drive the upgrade plan. | Changing the parent changes eligible zones, contributing lines, candidate values, and selected conductors. Keep the parent and intervention work packages otherwise comparable when measuring benefit. |
yearRange | Focus the reinforcement plan on particular forecast years. | Candidates are searched for and applied only within the inclusive range. For asset upgrades, every selected year must also exist in forecastConfig.years. |
allocationLimitPerYear | Represent the amount of line length that can be designed, procured, or constructed in one year. | The limit applies to the combined length of the original lines in each candidate. Lower limits can defer lower-ranked work to later years. |
allocationInstanceSelection | Restrict replacements to approved conductor catalogue IDs, such as standard low-impedance overhead or cable designs. | Only the selected catalogue rows are considered. A narrow selection may leave an otherwise eligible candidate without a viable conductor. If omitted, all catalogue rows are considered. |
targetVoltageSwingPu | Set the maximum preferred difference between the highest and lowest section voltage in a transformer measurement zone. | Lower values are stricter and require more correction, generally meaning a greater impedance reduction. A candidate may be dropped if no selected conductor can meet the target. |
voltageDeltaThresholdPu | Set an additional threshold for deciding whether a transformer zone has a material voltage issue. | A zone can qualify when either voltage swing exceeds targetVoltageSwingPu or voltage_delta_max exceeds this threshold. Lower values make more zones eligible; higher values focus the intervention on larger voltage deltas. |
upstreamEffectivenessFactor | Represent how strongly an upstream line is expected to influence voltage across the measurement zone. | Higher values increase the estimated benefit of upstream-line candidates and may move them higher in the ranking. This is an estimate of candidate value, not a direct change to simulated voltage. |
internalMzEffectivenessFactor | Represent how strongly a line inside the transformer’s measurement zone is expected to influence the voltage issue. Set to represent the number of circuits you have on average per transformer as a starting assumption. | Higher values increase the estimated benefit of internal-zone candidates and may move them higher in the ranking. The actual influence still depends on feeder topology and customer connections. |
defaultUpgradeReductionFactor | Provide a fallback estimate when impedance reduction cannot be calculated from existing line impedance metadata. | When metadata is available, reduction is calculated as 1.0 - selected_conductor_impedance / existing_line_impedance. Otherwise, this fallback is used. Higher values make a candidate appear more effective and may improve its ranking or allow it to meet the target. |
targetHeadroomFactor | Add sizing margin so the selected conductor is not based on the minimum estimated correction. | Higher values require a stronger estimated reduction. This may select a larger conductor or leave no viable catalogue option. |
minLineLengthM | Exclude very short mapped original lines that are unlikely to be useful standalone reinforcement targets. | Higher values remove more short lines from consideration. If any original line in a collapsed candidate is shorter than this value, the candidate may be skipped. |
minAvgAbsDeltaPu | Exclude related simplified lines with negligible observed voltage movement. | Higher values focus the plan on lines with stronger voltage contribution, but may omit longer or distributed contributors whose individual movement is small. |
These settings affect candidate eligibility, ranking, and conductor selection. They do not guarantee the final voltage outcome.
Candidate Ranking and Allocation
For each candidate line, the generator selects the lowest-cost viable conductor that can provide the required impedance reduction. Catalogue compatibility checks include:
- Rated current must be at least the existing line's rated current where the existing rating is available.
- Voltage must match, either by
applicable_base_voltages_vor byvoltage_level. - Phase support must cover the existing line phase count and neutral requirement.
wire_info_classmust match the existing line:OverheadWireInfofor overhead lines andCableInfofor underground lines.- Positive-sequence impedance must be low enough to meet the required impedance reduction.
The selected conductor is stored on the candidate as recommended_conductor_id. Allocation later applies that exact conductor catalogue row; if the row is not available, or none of the target original lines are present in the network, the candidate is not allocated.
Candidates are ranked by value_per_m, calculated as:
value_per_m = captured_value / total_length_m
captured_value estimates how much of the transformer-zone value the chosen conductor can address after impedance reduction and effectiveness factors are applied. The candidate's weight is total_length_m, so allocationLimitPerYear is measured in metres for this intervention.