Skip to main content
Version: Next
Only available for some customers

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 TypeSummary
TARIFF_REFORMModifies time of use patterns of customer electricity loads by applying load reshape profiles to eligible customers based on targeting criteria.
CONTROLLED_LOAD_HOT_WATERSimilar 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_BESSInstalls 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_STATCOMSDeploys 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.
DVMSImplements 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_REBALANCINGRedistributes single-phase customers across phases A, B, and C to correct imbalanced phase loading, reducing voltage imbalances and improving network efficiency.
DISTRIBUTION_TAP_OPTIMIZATIONIdentifies 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_OLTCRetrofits distribution transformers with on-load tap changers (OLTCs) to enable dynamic voltage regulation under load conditions, improving voltage quality for downstream customers.

InterventionConfig Parameters

ParameterTypeUsed ByDescription
base_work_package_idTEXT (UUID)AllID 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_rangeYearRangeCOMMUNITY_BESS, LV_STATCOMS, DISTRIBUTION_TAP_OPTIMIZATION, DISTRIBUTION_TX_OLTCRange of years to apply intervention (min_year, max_year), this should match the years of the underlying work package
intervention_typeInterventionClassAllType of intervention to apply
allocation_limit_per_yearINTEGERCOMMUNITY_BESS, LV_STATCOMS, DISTRIBUTION_TAP_OPTIMIZATION, DISTRIBUTION_TX_OLTCMaximum number of interventions to install/apply per year
allocation_criteriaTEXTTARIFF_REFORM, CONTROLLED_LOAD_HOT_WATER, COMMUNITY_BESS, LV_STATCOMSReferences allocation criteria table name in database
candidate_generationCandidateGenerationConfigCOMMUNITY_BESS, LV_STATCOMS, DISTRIBUTION_TAP_OPTIMIZATION, DISTRIBUTION_TX_OLTCConfiguration for identifying intervention candidates, contains different parameters depending on the intervention type
specific_allocation_instanceTEXTCOMMUNITY_BESS, LV_STATCOMSOptional: specific instance to use; if omitted, system selects appropriate instance
phase_rebalance_proportionsPhaseRebalanceProportionsPHASE_REBALANCINGTarget proportions for distributing customers across phases (A, B, C)
dvmsDvmsConfigDVMSConfiguration for dynamic voltage management including voltage limits, percentiles, and regulator settings
interventions is intended to run on a single year or contiguous range of years

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_criteria with their rankings, based on the combined sum of gen_exceeding_normal_voltage_cecv and load_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 profile control 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 of gen_exceeding_normal_voltage_cecv and load_exceeding_normal_thermal_voltage_vcr across all applicable years
  • lv_statcom_allocation_criteria - Specifies STATCOM placement rules and network compatibility requirements. The minimum_x_r_ratio filter 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:

  1. 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)
  2. 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))
  3. 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.

Exact Algorithm Logic

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:

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
)