This feature is only available to certain customers. If you are interested in using this feature, please contact Zepben for more information.
Intervention 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?
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. |
| CONTROLLED_LOAD_HOT_WATER | Similar to TARIFF_REFORM, modifies time of use patterns of customer electricity loads by applying load reshape profiles to eligible customers based on targeting criteria. |
| 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 distribution 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. |
InterventionConfig Parameters
| Parameter | Type | Used By | Description |
|---|---|---|---|
| base_work_package_id | TEXT (UUID) | All | ID of the base work package this intervention builds upon (It is only functionally required for COMMUNITY_BESS, LV_STATCOMS, DISTRIBUTION_TAP_OPTIMIZATION, but is recommended for all types for record-keeping purposes) |
| year_range | YearRange | COMMUNITY_BESS, LV_STATCOMS, DISTRIBUTION_TAP_OPTIMIZATION, DISTRIBUTION_TX_OLTC | Range of years to apply intervention (min_year, max_year), this should match the years of the underlying work package |
| intervention_type | InterventionClass | All | Type of intervention to apply |
| allocation_limit_per_year | INTEGER | COMMUNITY_BESS, LV_STATCOMS, DISTRIBUTION_TAP_OPTIMIZATION, DISTRIBUTION_TX_OLTC | Maximum number of interventions to install/apply per year |
| allocation_criteria | TEXT | TARIFF_REFORM, CONTROLLED_LOAD_HOT_WATER, COMMUNITY_BESS, LV_STATCOMS | References allocation criteria table name in database |
| candidate_generation | CandidateGenerationConfig | COMMUNITY_BESS, LV_STATCOMS, DISTRIBUTION_TAP_OPTIMIZATION, DISTRIBUTION_TX_OLTC | Configuration for identifying intervention candidates, contains different parameters depending on the intervention type |
| specific_allocation_instance | TEXT | COMMUNITY_BESS, LV_STATCOMS | Optional: specific instance to use; if omitted, system selects appropriate instance |
| phase_rebalance_proportions | PhaseRebalanceProportions | PHASE_REBALANCING | Target proportions for distributing customers across phases (A, B, C) |
| dvms | DvmsConfig | DVMS | Configuration for dynamic voltage management including voltage limits, percentiles, and regulator settings |
The intervention module is intended to run either on a single year or a range of contiguous years, not on multiple non-contiguous years. Attempting to do so will not result in an error, but will likely produce unexpected results.
For example:
- Valid:
{2026}, or{2026, 2027, 2028, 2029, 2030} - Invalid:
{2026, 2030}
TARIFF_REFORM and CONTROLLED_LOAD_HOT_WATER
Tariff Reform and Controlled Load Hot Water reference the same database tables.
Overview
These interventions modify the time of use patterns of customer electricity loads.
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
InterventionConfig(
base_work_package_id="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", # For record-keeping only
intervention_type=InterventionClass.TARIFF_REFORM # or InterventionClass.CONTROLLED_LOAD_HOT_WATER
allocation_criteria="load_reshape_strategy_1" # References criteria_name in load_reshape_strategies table
)
COMMUNITY_BESS
Community Battery Energy Storage Systems (BESS), also called Neighborhood 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 'spikey' 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. Candidates are prioritized by the combined sum of:
gen_exceeding_normal_voltage_cecv(generation causing voltage violations)load_exceeding_normal_thermal_voltage_vcr(load causing thermal/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. 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, based on the combined sum ofgen_exceeding_normal_voltage_cecvandload_exceeding_normal_thermal_voltage_vcr. - bess_allocation_criteria - Specifies battery placement and sizing rules
- 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
InterventionConfig(
base_work_package_id="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", # Required for this intervention type, used to query enhanced metrics
year_range=YearRange(
min_year=2026, # Earliest year to identify and apply intervention candidates
max_year=2030 # Latest year to identify and apply intervention candidates
)
allocation_limit_per_year=100, # Maximum number of batteries to install per year
intervention_type=InterventionClass.COMMUNITY_BESS,
candidate_generation=CandidateGenerationConfig(
type=CandidateGenerationType.CRITERIA, # Required for COMMUNITY_BESS
intervention_criteria_name="bess_threshold_set_1" # References intervention_candidate_criteria.name
),
allocation_criteria="bess_allocation_criteria_1", # References bess_allocation_criteria.name
specific_allocation_instance="bess_instance_1", # Optional. References bess_instances.name, if specified, only this battery type is used, otherwise, the smallest viable battery is selected
)
BESS Modes:
There are 5 valid modes that batteries can operate in, defined in the bess_instances table:
peakshave
Charges when load is low, discharges when load is high.
The target power level for discharging is defined by the kw_target_discharging parameter, and the target power level for charging is defined by the kw_target_charging parameter. The battery will attempt to keep the power at these levels, within the deadband defined by kw_band_charging and kw_band_discharging.
Example:
mode = peakshave, kw_target_charging = 10200, kw_target_discharging = 8500, kw_band_charging = 100 (not all values specificed, just the relevant ones)

The fleet can shave both the low and high peaks. Note that the charging of the fleet starts at midnight, as the system's loading drops below kw_target_charging at this time step.
time
Charges and discharges based on time of day. This mode operates on a fixed schedule, begining 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 discharging_rate until empty.
Example:
mode = time, charge_trigger = 1, discharge_trigger = 17, charge_rate = 100%, discharge_rate = 50%, reserve_percentage = 20,

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 typcially mean the battery cycles more accross a year than in peakshave mode.
Example:
mode = following, discharge_trigger = 18, charge_trigger = 1, reserve_percentage = 20, charge_rate = 100%, discharge_rate = 50%

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 (ie if configured incorrectly, there is nothing stopping a battery from discharging more than its maximum energy storage capacity).
Example:
mode = profile, profile_id = "bess_profile_1", reserve_percentage = 10

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, targeting the kw_target_discharging value.
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_thermal_voltage_vcr(load causing thermal/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 (ie ≥) 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_thermal_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
InterventionConfig(
base_work_package_id="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", # Required for this intervention type, used to query enhanced metrics
year_range=YearRange(
min_year=2026, # Earliest year to identify and apply intervention candidates
max_year=2030 # Latest year to identify and apply intervention candidates
),
allocation_limit_per_year=100, # Maximum number of LV STATCOMs to install per year
intervention_type=InterventionClass.LV_STATCOMS,
candidate_generation=CandidateGenerationConfig(
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
intervention_criteria_name="threshold_set_2"
),
allocation_criteria="lv_statcom_allocation_criteria_1", # References lv_statcom_allocation_criteria.name
specific_allocation_instance="lv_statcom_instance_1", # Optional: references lv_statcom_instances.name
# If specified, only this STATCOM type is used
# If omitted, first suitable instance (matching year/feeder) is selected
)
DVMS
Dynamic Voltage Management Systems (DVMS) provide real-time voltage regulation by automatically adjusting zone substation (feeder head) transformer taps based on customer voltage measurements.
Overview
DVMS addresses voltage quality issues through adaptive control of distribution transformer 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 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
Configuration Example
InterventionConfig(
base_work_package_id="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", # For record-keeping only
intervention_type=InterventionClass.DVMS,
dvms=DvmsConfig(
# Voltage acceptance criteria
lower_limit=0.9, # Minimum acceptable voltage (per unit)
upper_limit=1.1, # Maximum acceptable voltage (per unit)
lower_percentile=5, # Lower percentile of customer voltages to consider (excludes extreme low outliers)
upper_percentile=95, # Upper percentile of customer voltages to consider (excludes extreme high outliers)
max_iterations=3, # Maximum tap adjustment attempts per time step, after this the solver will move to the next time step regardless of success.
regulator_config=RegulatorConfig(
pu_target=1.0, # Target voltage (per unit)
pu_deadband_percent=12, # Deadband width as % of target (e.g., 12 → ±6% → 0.94-1.06 p.u. with target=1.0)
max_tap_change_per_step=2, # Maximum tap positions to change per iteration
allow_push_to_limit=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.
Use Case: Apply to networks known to have uneven single-phase customer distribution in the base network model.
Tables referenced: None - entirely configured via intervention parameters
Configuration Example
InterventionConfig(
base_work_package_id="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", # For record-keeping only
intervention_type=InterventionClass.PHASE_REBALANCING,
phase_rebalance_proportions=PhaseRebalanceProportions(
# 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 optimisation 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
This intervention analyses voltage metrics from the base work package to identify distribution transformers where a change to the static tap position is expected to improve annual voltage compliance. Unlike DVMS (which adjusts taps dynamically at each time step), distribution tap optimisation makes strategic, once-per-year adjustments based on observed historical patterns.
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.
No tables referenced — behaviour is controlled entirely by intervention parameters.
Applicability and annual allocation Tap optimisation is designed to be applicable to all distribution transformers by default (static improvements to persistent bias).
To approxiamte operational restrictions (ie a works program that has budget to modify only XX transformers per year), the intervention can be capped using allocation_limit_per_year. When a cap is applied, candidates are ranked and selected by severity, prioritising transformers with the largest magnitude of voltage excursions beyond network limits (largest deviation from acceptable bounds over the year).
Configuration example
InterventionConfig(
base_work_package_id="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", # Used to query voltage metrics from base scenario
year_range=YearRange(min_year=2026, max_year=2030), # Will perform analysis from min year to max year, inclusive.
allocation_limit_per_year=50, #optional, leave out to appply to an unlimited number of transformers per year
intervention_type=InterventionClass.DISTRIBUTION_TAP_OPTIMIZATION,
candidate_generation=CandidateGenerationConfig(
type=CandidateGenerationType.TAP_OPTIMIZATION, # Required for DISTRIBUTION_TAP_OPTIMIZATION
# Voltage thresholds (applied per measurement zone per year)
voltage_delta_avg_threshold=0.05,
voltage_under_limit_hours_threshold=48,
voltage_over_limit_hours_threshold=48,
# (details on the these metrics is explained below)
# Tap weighting thresholds (direction arbitration)
# Default values (-10.0, 10.0) are suitable for most cases
tap_weighting_factor_lower_threshold=-10.0,
tap_weighting_factor_upper_threshold=10.0
)
)
Key metrics and parameters
voltage_delta_avg (metric) voltage_delta_avg measures the typical within-zone spatial (geographic) voltage spread along the downstream circuit over the relevant time period. At each time step:
- For each phase, compute the voltage range across nodes in the measurement zone: ΔV_phs1(t) = phv.phs1.max(t) - phv.phs1.min(t) ΔV_phs2(t) = phv.phs2.max(t) - phv.phs2.min(t) ΔV_phs3(t) = phv.phs3.max(t) - phv.phs3.min(t)
- Take the maximum phase range (worst phase) at that time step: ΔV_max_phase(t) = max(ΔV_phs1(t), ΔV_phs2(t), ΔV_phs3(t))
- Average over time: voltage_delta_avg = Average_t(ΔV_max_phase(t)) Formula: Average(Max(phv.phs1.max - phv.phs1.min, phv.phs2.max - phv.phs2.min, phv.phs3.max - phv.phs3.min)) Interpretation: higher values indicate the measurement zone typically has a larger voltage difference between nodes (often reflecting weak LV networks, long runs, or phase imbalance).
voltage_delta_avg_threshold (swing gating / conservativeness control) voltage_delta_avg_threshold controls when the algorithm becomes more conservative with the size of tap step changes it recommends. When voltage_delta_avg is high (greater than this threshold), the downstream network is showing significant spatial voltage spread. In this condition, the algorithm limits itself to smaller (1-step) recommendations to reduce the risk of exacerbating voltage problems in weak LV networks. When voltage_delta_avg is low (less than or equal to this threshold), the measurement zone is more stable/uniform and the algorithm can recommend 2-step changes under “predominantly high/low” regimes. In practice: lowering voltage_delta_avg_threshold makes the algorithm conservative more often; increasing it makes 2-step recommendations more likely.
Persistence thresholds: voltage_under_limit_hours_threshold and voltage_over_limit_hours_threshold These parameters control how much duration of non-compliance is required before the algorithm treats an issue as persistent enough to justify a tap change.
-
voltage_under_limit_hours_threshold Minimum annual hours where voltages are below the acceptable lower bound before the zone is considered to have a persistent undervoltage issue.
-
voltage_over_limit_hours_threshold Minimum annual hours where voltages are above the acceptable upper bound before the zone is considered to have a persistent overvoltage issue.
The default values have been tuned through testing to avoid recommending tap changes due to short-lived or non-representative excursions.
Direction arbitration thresholds: tap_weighting_factor_lower_threshold & tap_weighting_factor_upper_threshold When both persistent undervoltage and overvoltage are present (both hour thresholds exceeded), the algorithm avoids exacerbating problems by applying a direction arbitration deadband.
It computes a tap weighting factor:
tapWeightingFactor = (|V99_avg - 1.0| * hours_over_limit) - (|V1_avg - 1.0| * hours_under_limit)
Interpretation: When tapWeightingFactor is positive that means that overvoltage dominates (high tail is more severe/persistent) When tapWeightingFactor is negative that means that undervoltage dominates (low tail is more severe/persistent)
What each threshold does:
-
tap_weighting_factor_upper_threshold sets how much overvoltage dominance is required to recommend a buck candidate. If tapWeightingFactor > tap_weighting_factor_upper_threshold, a buck candidate is added.
-
tap_weighting_factor_lower_threshold sets how much undervoltage dominance is required to recommend a boost candidate. If tapWeightingFactor < tap_weighting_factor_lower_threshold, a boost candidate is added.
-
If tap_weighting_factor_lower_threshold ≤ tapWeightingFactor ≤ tap_weighting_factor_upper_threshold, then no candidate is added (no tap change).
Why this matters: This deadband avoids recommending tap changes for situations where: there are both under- and over-voltage events, but neither side is dominant enough to justify moving the static tap position. This helps prevent small offsetting exceedances from driving tap changes that reduce overall annual steady-state compliance (e.g., improving one tail while increasing violations elsewhere). Default threshold values have been tuned through testing.
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_thermal_voltage_vcr(load causing thermal/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
InterventionConfig(
base_work_package_id="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", # Required for this intervention type, used to query enhanced metrics
year_range=YearRange(
min_year=2026, # Earliest year to identify and apply intervention candidates
max_year=2030 # Latest year to identify and apply intervention candidates
),
allocation_limit_per_year=50, # Maximum number of OLTCs to install per year
intervention_type=InterventionClass.DISTRIBUTION_TX_OLTC,
candidate_generation=CandidateGenerationConfig(
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
intervention_criteria_name="threshold_set_2"
),
allocation_criteria="distribution_transformer_oltc_allocation_criteria_1", # References distribution_transformer_oltc_allocation_criteria.name
specific_allocation_instance="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
)