Updates

Typed updates change a module in place. Each update names a component by ComponentId and gives an absolute value with an explicit unit. You apply updates as a batch, and the batch is validated as a whole before anything changes.

case = parse("case9.m")
load = ComponentId("load", case.value.loads[1].component_id)   # "bus-5"

report = apply_updates!(case, [
    set_load_active_power(load, ActivePower(megawatts=91.5)),
    set_load_reactive_power(load, ReactivePower(megavars=31.0)),
])

report.connectivity_changed        # false
report.changes[1].component_id     # ComponentId("load", "bus-5")
report.changes[1].field            # "load_active_power"
case.value.loads[1].p_mw           # 91.5

The quantity types ActivePower, ReactivePower, and ApparentPower take exactly one unit keyword: ActivePower(watts=...) or ActivePower(megawatts=...), ReactivePower(vars=...) or ReactivePower(megavars=...), ApparentPower(volt_amperes=...) or ApparentPower(megavolt_amperes=...).

Update constructors

Operating point updates:

FunctionField changed
set_load_active_power, set_load_reactive_powera load's demand
set_generator_active_power, set_generator_reactive_powera generator's dispatch
set_generator_voltage_magnitudea generator's voltage setpoint, per unit
set_generator_in_service, set_branch_in_serviceservice status
set_transformer_tap_ratio, set_transformer_phase_shift_degreesa transformer branch
set_switch_closeda switch position

The network update is set_branch_thermal_rating. The power setters accept terminal= to address one terminal of a multiconductor element.

Applying a batch

apply_updates! validates every update before changing anything, so a batch with an unknown component or an invalid value throws PowerIOError and leaves the module as it was. On success the module's value is refreshed and case.value reflects the change; a BalancedNetwork you obtained before the call keeps the data from before it. The returned UpdateReport lists every UpdateChange and says whether a service status or switch change altered the energized topology.

Component ids for MATPOWER sources follow the reader's convention: loads and generators are "bus-N", branches are "F-T". Read the component_id field of the element rather than assuming a convention.

PowerIO.ApparentPowerType
ApparentPower(; volt_amperes) or ApparentPower(; megavolt_amperes)

Apparent power with an explicit unit.

source
PowerIO.NetworkUpdateType
NetworkUpdate

One change to network data. set_branch_thermal_rating is the network update in this release.

source
PowerIO.set_load_active_powerFunction
set_load_active_power(id::ComponentId, power::ActivePower; terminal=nothing)

An update that sets a load's active power. terminal selects one terminal of a multiconductor load.

source
PowerIO.apply_updates!Function
apply_updates!(m::PioModule, updates) -> UpdateReport

Validate the whole batch of OperatingPointUpdate and NetworkUpdate values, then apply it atomically. A failed batch throws PowerIOError and leaves the module unchanged. On success m.value is refreshed; values obtained before the call keep the pre-update data.

The call needs exclusive use of m: no other task may read m.diagnostics, m.producer, m.sources, or m.history, or pass m to emit, serialize, or another apply_updates!, until it returns. Values already obtained from m (a network and its elements) stay readable.

source
PowerIO.UpdateReportType
UpdateReport

What apply_updates! changed: changes::Vector{UpdateChange} and connectivity_changed, true when a service status or switch change altered the energized topology. length(report) is the number of changes.

source
PowerIO.UpdateChangeType
UpdateChange(component_id, field, terminal)

One change an applied batch made: the component, the field name such as "load_active_power" or "branch_thermal_rating", and the terminal when the change targeted one.

source