API reference¶
Data¶
openenergy.data.series ¶
Validated time series (prices, capacity factors) on a regular UTC grid.
PriceSeries
dataclass
¶
Prices in currency/MWh, each timestamp labelling the start of its interval.
ProfileSeries
dataclass
¶
Capacity factors in [0, 1] for one technology; clipped counts values capped on load.
fill_gaps ¶
fill_gaps(
series: PriceSeries, max_gap_hours: float
) -> tuple[PriceSeries, int]
fill_gaps(
series: ProfileSeries, max_gap_hours: float
) -> tuple[ProfileSeries, int]
fill_gaps(
series: IntensitySeries, max_gap_hours: float
) -> tuple[IntensitySeries, int]
fill_gaps(series, max_gap_hours)
Linearly interpolate interior gaps no longer than max_gap_hours.
Returns the filled series and the number of intervals filled.
openenergy.data.opsd ¶
Open Power System Data (OPSD) time-series CSV source.
OPSDCsvSource ¶
Reads day-ahead prices and capacity-factor profiles from an OPSD singleindex CSV.
prices ¶
prices(zone, start=None, end=None)
Day-ahead prices for zone over whole UTC days, start and end inclusive.
profile ¶
profile(zone, technology, start=None, end=None)
Capacity factors for technology in zone, capped to [0, 1].
series ¶
series(column, start=None, end=None)
Any column as a validated series over whole UTC days, start and end inclusive.
generation ¶
generation(zone, technology, start=None, end=None)
Actual generation in MW for technology (e.g. solar, wind).
openenergy.data.ember ¶
GB hourly day-ahead prices from Ember, converted to GBP with ECB reference rates.
EmberPriceSource ¶
Reads gb_day_ahead_ember.csv and ecb_gbp_per_eur.csv written by the fetch script.
rates defaults to ecb_gbp_per_eur.csv next to the price file.
prices ¶
prices(zone='GB_GBN', start=None, end=None)
Hourly GBP/MWh over whole UTC days, start and end inclusive.
gb_prices ¶
gb_prices(paths, start, end)
GB hourly day-ahead prices from OPSD and/or Ember files, earlier files taking priority.
Each file's type is read from its header. A later file only adds hours outside the span already covered, never filling gaps inside it (Ember interpolates its own gaps). Returns the prices and the attribution of every file that supplied at least one value.
openenergy.data.update ¶
Download the latest GB day-ahead prices (Ember) and ECB GBP rates.
cache_dir ¶
cache_dir()
$XDG_CACHE_HOME/openenergy/prices, defaulting to ~/.cache/openenergy/prices.
update_prices ¶
update_prices(directory)
Write Ember hourly UK prices (EUR, unchanged) and ECB daily GBP rates to directory.
Returns the price file, its number of hours and the first and last UTC hour.
openenergy.data.carbon ¶
GB carbon intensity from NESO's Carbon Intensity API extract.
IntensitySeries
dataclass
¶
Average grid carbon intensity in gCO2/kWh (= kg/MWh).
rejected counts values outside [0, 1000] that were treated as missing.
CarbonIntensitySource ¶
Reads utc_timestamp, forecast, actual half-hourly CSVs written by the fetch script.
intensity ¶
intensity(kind='actual', start=None, end=None, step=None)
Intensity over whole UTC days, optionally averaged to a coarser step.
An averaged interval is missing unless every half-hour in it is present.
openenergy.data.neso ¶
GB half-hourly generation by fuel from NESO's historic generation mix extract.
GenerationMixSource ¶
Reads the utc_timestamp, <fuels>, generation CSV written by the fetch script.
mix ¶
mix(start=None, end=None, step=None)
Generation by fuel and in total (MW) over whole UTC days, start/end inclusive.
Averaging to a coarser step leaves an interval missing unless every half-hour
in it is present.
openenergy.data.response ¶
GB dynamic frequency response (DC, DM, DR): auction clearing prices and utilisation.
Service
dataclass
¶
A response product: low exports when frequency falls, high imports when it rises.
envelope lists (deviation beyond 50 Hz, fraction of contracted MW) points after the
deadband, from NESO's Response Services Service Terms; delivery is linear between them.
delivered ¶
delivered(frequency_hz)
Fraction of the contracted MW delivered at each frequency sample.
ResponseMarket
dataclass
¶
Clearing prices (GBP/MW/h) per delivery block and monthly utilisation per service.
prices is indexed by block start (UTC) with an end column and one column per
service; utilisation is indexed by month start (UTC).
utilisation_at ¶
utilisation_at(starts)
Each block's monthly factors; months without frequency data use the overall mean.
ResponseSource ¶
Reads the block prices and monthly utilisation CSVs written by the fetch script.
utilisation ¶
utilisation(frequency_hz)
Average delivery per contracted MW (= MWh per MW per hour) over the samples.
openenergy.data.fleet ¶
GB fleet capacity, efficiency, fuel prices and carbon prices for the system model.
SystemInputs ¶
Reads the system CSVs written by scripts/fetch_system_data.py from one directory.
unit_parameters ¶
unit_parameters()
Unit size (MW), minimum stable output (share) and start cost (GBP/MW) by technology.
efficiency ¶
efficiency(year)
Fleet-average thermal efficiency (gross calorific value) for year.
A blank value (no station of that type ran) falls back to the latest earlier year.
fuel_prices ¶
fuel_prices(index)
GBP per MWh of fuel at each timestamp, from the quarter it falls in.
Blank (suppressed) prices carry forward from the latest earlier quarter.
carbon_prices ¶
carbon_prices(index)
ETS price (GBP/t) and carbon price support (GBP/MWh of fuel) at each timestamp.
Each row applies from its valid_from date (1 April) to the next. The ETS is the EU
ETS to 2020 and the UK ETS from 2021; prices in USD or EUR convert at the stored ECB
rates. Files with only eu_ets_usd_per_t (v3.1 and earlier) are still read.
openenergy.data.interconnectors ¶
GB interconnectors: capacity (NESO register), in-service dates and flows (Elexon), and neighbouring markets' day-ahead prices (Ember).
Interconnector
dataclass
¶
One GB link: firm import and export capacity (TEC) and the day it entered service.
in_service comes from the bundled Elexon flows (see IN_SERVICE_DAYS), or is None
if the link was already in service when the record starts. import_availability and
export_availability are the shares of a price taker's trade the link actually made
(availability_from_flows); 1 when no fitted file is present.
NeighbourPriceSource ¶
Reads europe_day_ahead_ember.csv (EUR/MWh) and converts with the ECB rate file.
prices ¶
prices(neighbour, index, max_gap_hours=3)
GBP/MWh on index; gaps up to max_gap_hours are interpolated.
interconnectors ¶
interconnectors(system_dir)
Built links from interconnectors.csv with in-service dates from the flow record,
and their availability from interconnector_availability.csv when present.
availability_from_flows ¶
availability_from_flows(system_dir, gb_prices, neighbours)
Per link, the share of a price taker's imports and exports that actually flowed.
A price taker on gb_prices (actual hourly GBP/MWh, the fitting years) imports at
full capacity whenever GB is dearer than the neighbour and exports whenever it is
cheaper, from the day the link entered service. Each share is the actual energy
(Elexon) over that trade, at most 1. Modelled prices are never used. Links with no
trade in the period get the mean of the others.
interconnector_flows ¶
interconnector_flows(system_dir)
Daily MWh per link, columns <fuel type>_import_mwh and _export_mwh.
openenergy.data.fes ¶
NESO Future Energy Scenarios: capacity, storage and demand by pathway and year.
FesSource ¶
openenergy.data.quality ¶
Transparent filters for telemetry glitches in metered time series.
flag_glitches ¶
flag_glitches(
values, spike_fraction=0.25, dropout_fraction=0.5
)
Flag isolated spikes and dropouts in a smooth series such as demand.
A spike deviates from its centred 5-interval median by more than spike_fraction
of the series' 99th percentile; a dropout falls below dropout_fraction of its
centred 7-day median. Genuine ramps sit on their rolling median, so are not flagged.
Assets¶
openenergy.assets.battery ¶
Battery specification, state and physics.
BatteryState
dataclass
¶
Physical state carried between intervals.
BatterySpec
dataclass
¶
Battery ratings. SOC limits are fractions of usable (degraded) energy.
DispatchOutcome
dataclass
¶
State after a dispatch and the stored energy at each interval boundary.
apply_dispatch ¶
apply_dispatch(
spec,
state,
charge_mw,
discharge_mw,
step_hours,
response_charge_mw=None,
response_discharge_mw=None,
)
Apply a charge/discharge schedule (MW per interval) and return the new state.
response_charge_mw/response_discharge_mw are average power moved by frequency
response in each interval; they may overlap (low and high services in one interval).
age ¶
age(spec, state, hours)
Advance calendar age and recompute state of health from lifetime totals.
openenergy.assets.renewable ¶
Renewable plants driven by capacity-factor profiles.
RenewableSpec
dataclass
¶
A plant of capacity_mw whose output declines by degradation_per_year.
generation_mw ¶
generation_mw(profile, start_age_years=0.0)
Available output in MW: capacity x capacity factor x (1 - degradation)^age.
Age is start_age_years at the first interval of profile and grows with time.
Dispatch¶
openenergy.dispatch.arbitrage ¶
Single-battery energy arbitrage as a mixed-integer linear programme (HiGHS).
DispatchConfig
dataclass
¶
Optimisation settings.
end_soc is a fraction of usable energy; None means return to the starting energy.
max_cycles caps equivalent full cycles over the horizon (the backtest scales it by
the days planned, so it stays a per-day cap). lookahead_days makes the backtest plan
each day together with that many following days of forecasts, settling only the first;
the end-energy target then applies at the end of the last day.
DispatchPlan
dataclass
¶
Optimal schedule in MW per interval and stored energy at each boundary (T+1).
With frequency response, reserve_mw is MW held per block and service, and
response_charge_mw/response_discharge_mw the expected average power it moves.
expected_revenue covers energy; expected_response the availability payments.
Reserve
dataclass
¶
Frequency-response options over a horizon.
block maps each interval to a row of price (-1 where nothing can be reserved).
price (GBP/MW/h) and utilisation (MWh delivered per MW per hour) have one row
per block and one column per service. fixed holds MW already committed (NaN where
free). beyond_hours is how long each block runs past the horizon end; the plan keeps
enough energy to stay idle through it. With energy_paid, delivered energy is bought
or sold at the interval's price; otherwise it is free, as under NESO's ABSVD adjustment.
optimise_dispatch ¶
optimise_dispatch(
spec,
state,
prices,
step_hours,
config=None,
reserve=None,
)
Maximise arbitrage (and response) revenue less degradation cost over the horizon.
energy_window ¶
energy_window(spec, state, config)
Stored-energy bounds and the end-of-horizon target, in MWh.
openenergy.dispatch.colocated ¶
A renewable plant and a battery behind one grid connection.
GridConnection
dataclass
¶
Connection limits in MW; premium_per_mwh is paid on renewable output delivered.
import_limit_mw defaults to the export limit; set it to 0 to forbid grid charging.
ColocatedPlan
dataclass
¶
Flows in MW per interval; export_mw is net (negative when importing).
optimise_colocated ¶
optimise_colocated(
spec,
state,
available_mw,
prices,
step_hours,
grid,
config=None,
)
Maximise market revenue plus premium less degradation cost for plant and battery.
dispatch_plant ¶
dispatch_plant(available_mw, prices, step_hours, grid)
A plant on its own: export up to the limit unless price plus premium is negative.
Forecasting¶
openenergy.forecast.baseline ¶
Baseline price forecasters.
Forecaster ¶
Bases: Protocol
Predicts prices for index from history observed before the decision time.
PerfectForesight ¶
Returns the actual prices; the upper-bound benchmark.
NaiveLastWeek ¶
Same interval one week earlier, or two weeks earlier where that is missing.
NoisyForesight ¶
Actual prices plus Gaussian error, seeded per forecast window for reproducibility.
openenergy.forecast.ml ¶
Gradient-boosted price forecaster (requires the openenergy[forecast] extra).
GradientBoostingForecaster ¶
Histogram gradient boosting on calendar and lagged prices, trained chronologically.
make_features ¶
make_features(index, prices, lead_hours)
Calendar and lagged-price features; lags at or after the decision time are NaN.
The decision time for an interval is its UTC day start minus lead_hours, matching
the backtest, so training rows see exactly what a live forecast would.
Backtesting and metrics¶
openenergy.backtest.engine ¶
Rolling day-ahead backtest: plan on forecasts, settle at actual prices.
BacktestConfig
dataclass
¶
lead_hours: how long before each UTC day the plan is fixed (12 = noon the day before).
Site
dataclass
¶
Renewable output (MW, on the price grid) sharing grid with the battery.
Output is known when planning (perfect generation foresight).
Carbon
dataclass
¶
Actual grid carbon intensity (gCO2/kWh) for accounting and, with a price, for dispatch.
planning sets what dispatch sees: last_week uses the same interval a week earlier
(two weeks if missing), cut off at the decision time like prices; actual uses the
real values and is an upper bound. NESO's archived "forecast" is not used: it is the
last forecast before each half-hour, so planning on it the day before would look ahead.
Reported money stays market revenue.
BacktestResult
dataclass
¶
Interval and daily results; skipped maps unsimulated days to the reason.
PlantResult
dataclass
¶
A renewable plant operated on its own connection.
run_backtest ¶
run_backtest(
spec,
prices,
forecaster,
config=None,
days=None,
site=None,
carbon=None,
response=None,
)
Simulate each UTC day in order; the battery ages through every calendar day in range.
With a site, the battery shares a grid connection with renewable output. With
carbon, emissions are reported and a carbon price steers dispatch. With
response, frequency-response availability is sold alongside trading.
run_plant_backtest ¶
run_plant_backtest(
site, prices, forecaster, config=None, days=None
)
The plant alone: curtail when forecast price plus premium is negative, settle at actual.
openenergy.backtest.response ¶
Frequency response stacked with trading in the rolling backtest.
Response
dataclass
¶
Frequency-response services the battery may sell alongside trading.
MW for each block are fixed in the plan for the day the block starts in and paid the
actual clearing price. forecast sets the price planned on: previous_day uses the
latest earlier block at the same time of day whose result was public at the decision
time; actual uses the clearing price itself (an upper bound). energy_paid buys
and sells the energy delivered at the trading price instead of treating it as free.
DayReserve
dataclass
¶
A day's reserve options, the actual clearing prices of its blocks and their market rows.
Stacking ¶
openenergy.metrics.summary ¶
Summary metrics for backtest results.
Summary
dataclass
¶
Headline results. Money is in currency; energy in MWh.
For a co-located site, revenue covers the whole site and the plant fields are set;
per-MW and captured-spread figures apply to battery-only runs. With frequency response,
revenue includes response_revenue (availability payments).
summarise ¶
summarise(result, benchmark=None)
Summarise result; capture_ratio compares with benchmark on common days.
openenergy.metrics.capture ¶
Captured price: what the market pays a generator for the hours it actually produces.
CaptureMetrics
dataclass
¶
Market value of a generation profile. Prices in currency/MWh, energy in MWh.
capture_metrics ¶
capture_metrics(
prices, generation_mw, capacity_mw, label="all"
)
Captured price, capture rate and related metrics over intervals with both values.
Capture rate is captured price divided by the time-weighted (baseload) price.
capture_by_year ¶
capture_by_year(prices, profile)
Capture metrics per calendar year (UTC) for 1 MW of profile.
System analysis¶
openenergy.system.netload ¶
Net load: demand left for dispatchable plant once wind and solar are subtracted.
NetLoadStats
dataclass
¶
One calendar year of net load. Power in MW, energy in MWh, price slope per GW.
Ramps are 99th percentiles of absolute changes, so a single bad reading cannot set them.
SystemData
dataclass
¶
Load, wind and solar (MW) and price on one UTC index.
load_flagged counts load readings removed as telemetry glitches.
load_system ¶
load_system(
source, zone, start=None, end=None, clean_load=True
)
Load, wind and solar generation and day-ahead price, with load glitches removed.
net_load ¶
net_load(system, scale_wind=1.0, scale_solar=1.0)
Load minus wind and solar, each scaled to model more (or less) installed capacity.
surplus ¶
surplus(net, must_run_mw=0.0)
Renewable output the system cannot use: how far net load falls below the must-run floor.
duration_curve ¶
duration_curve(net)
Values sorted high to low, indexed by the share of time at or above each value.
netload_by_year ¶
netload_by_year(
system, scale_wind=1.0, scale_solar=1.0, must_run_mw=0.0
)
Net-load statistics per UTC calendar year.
The price slope is only meaningful for the system as it was, so it is omitted when renewables are scaled.
openenergy.system.storage ¶
How much system surplus a storage fleet can absorb.
FleetResult
dataclass
¶
Surplus absorbed by a fleet of power_mw and hours duration; energy in MWh.
residual is net load after storage, relative to the must-run floor's surplus rule.
absorb_surplus ¶
absorb_surplus(
net,
power_mw,
hours,
eta_charge=0.95,
eta_discharge=0.95,
must_run_mw=0.0,
)
Charge from surplus (net load below must_run_mw), release when net load is above it.
Greedy in time order: release only as much as keeps net load at or above the floor, so storage never creates new surplus. Missing hours are idle.
sizing_grid ¶
sizing_grid(
net,
powers_mw,
hours,
eta_charge=0.95,
eta_discharge=0.95,
must_run_mw=0.0,
)
absorb_surplus for every power and duration combination.
System model¶
openenergy.system.model ¶
System dispatch: what runs each hour, at what cost, and the price it implies.
Generator
dataclass
¶
One generator or tranche: available MW and marginal cost (GBP/MWh) per snapshot.
must_run units produce exactly their available output (historic profiles).
emissions_t_per_mwh is tCO2 per MWh of electricity.
Storage
dataclass
¶
Storage optimised in the dispatch; efficiency is round trip.
Link
dataclass
¶
A price-taking interconnector to a neighbouring market.
It imports when GB's price is above price (the neighbour's, GBP/MWh) and exports
when below, up to import_mw and export_mw in each snapshot. hurdle (GBP/MWh)
is added to imports and taken off exports (losses and trading costs).
SystemSpec
dataclass
¶
Demand (MW), generators, storage and links on one bus, all on the demand's UTC index.
SystemResult
dataclass
¶
Dispatch outcome. Power in MW per snapshot; storage is net discharge.
Unit commitment adds start_price (marginal price including start costs),
units_online and starts per committed tranche. With links, links holds each
link's net flow (MW, positive into GB).
solve ¶
solve(spec, backend='auto', commitment=None)
Dispatch spec at least cost.
Without storage every hour is independent and the merit order is the exact optimum,
so auto uses it; with storage auto uses PyPSA (pip install openenergy[system]).
With commitment, thermal units have start-up costs and minimum stable output and days
are solved in turn with a lookahead (storage included). The merit order and unit
commitment dispatch links as two generators each (see _flatten_links), which gives
the same prices as PyPSA's links.
result_frames ¶
result_frames(spec, dispatch)
Generation frame, renewable curtailment and emissions from a T x G dispatch array.
openenergy.system.fleet ¶
Build a GB system from the generation mix, fleet data and stated assumptions.
FleetAssumptions
dataclass
¶
Stated, configurable modelling assumptions; none is fitted to prices.
Each thermal group is split into tranches of equal size whose efficiencies spread
evenly over the fleet average plus or minus the spread (fractions, e.g. 0.04 = 4 pp).
Peaking plant (gas turbines and oil engines) is one tranche costed as gas.
Adjustments
dataclass
¶
Scenario changes to the historic system.
scale multiplies historic profiles (wind, solar, nuclear, imports, ...) and demand;
capacity_mw replaces installed thermal capacity (ccgt, coal, peaking);
fuel_price_scale multiplies gas or coal prices; ets_gbp_per_t replaces the ETS
price (EU ETS to 2020, UK ETS from 2021); carbon_price_support keeps or removes the
GB top-up.
thermal_generators ¶
thermal_generators(
index, inputs, assumptions=None, adjustments=None
)
CCGT, coal and peaking tranches with short-run marginal cost (GBP/MWh) per period.
build_system ¶
build_system(
mix,
inputs,
assumptions=None,
adjustments=None,
storage=(),
voll=DEFAULT_VOLL,
links=(),
)
GB on one bus for one calendar year of the generation mix (MW per period).
Demand is NESO's total generation (scaled by scale['demand']). Fixed profiles keep
their (scaled) historic output; wind and solar can be curtailed; thermal plant follows
the merit order; links trade with neighbours.
openenergy.system.merit ¶
Merit-order dispatch: each period independently, cheapest available plant first.
merit_order ¶
merit_order(spec)
Exact least-cost dispatch for a system without storage.
Must-run units run at their profile. The rest are stacked by marginal cost; the price is the cost of the last unit needed, or the value of lost load when capacity runs out.
openenergy.system.validate ¶
Backcast: rebuild history with the system model and measure how far it is from reality.
BackcastYear
dataclass
¶
Model vs reality for one year. Prices in GBP/MWh, energy in TWh, emissions in MtCO2.
emissions_mt_actual_mix applies the model's emission factors and fleet-average
efficiencies to the gas and coal that actually ran, so the two emission figures differ
only because of dispatch.
backcast ¶
backcast(
mix,
inputs,
prices,
assumptions=None,
adjustments=None,
storage=(),
backend="auto",
commitment=None,
price="marginal",
)
Solve each calendar year of mix and compare with actual prices and fuel use.
Nothing is fitted: assumptions are applied as given and the gap is the finding.
price chooses which modelled price is compared (start needs commitment).
write_backcast ¶
write_backcast(
result,
directory,
assumptions=None,
commitment=None,
price="marginal",
price_attribution=(OPSD_ATTRIBUTION,),
)
Write backcast.csv (per year), hourly.csv and summary.json with sources.
openenergy.system.scenario ¶
System scenarios: one GB year with changes, and optionally a battery valued on its prices.
StorageSection ¶
Bases: _Strict
Storage added to the system; power_mw: 0 leaves it out (handy in sweeps).
InterconnectorSection ¶
Bases: _Strict
fixed keeps historic imports; links trades at neighbours' actual prices.
prices defaults to prices/europe_day_ahead_ember.csv next to the system data.
availability: flows uses each link's availability fitted from its flows; a number
from 0 to 1 applies to every link instead.
FesSection ¶
Bases: _Strict
A NESO FES pathway and year applied to the weather year (system.year).
Storage efficiencies are stated assumptions; FES does not publish them.
data defaults to fes/ next to the system data.
SystemSection ¶
Bases: _Strict
SystemSummary
dataclass
¶
One scenario year. Prices GBP/MWh, energy TWh, emissions MtCO2, cost GBP million.
run_system_scenario ¶
run_system_scenario(scenario)
Solve the scenario year and, if a battery is given, backtest it on the modelled prices.
The battery plans on forecasts from modelled history only, exactly as on market prices.
write_system_outputs ¶
write_system_outputs(run, directory)
Write dispatch.csv (hourly price and output by technology) and summary.json.
system_sweep ¶
system_sweep(path, grid)
Run a system scenario for every combination of grid values, in grid order.
openenergy.system.forward ¶
Forward scenarios: NESO FES pathways and interconnector links on a historic weather year.
FesChanges
dataclass
¶
What a FES pathway and year change on the weather year's system.
fes_changes ¶
fes_changes(
source,
pathway,
year,
base_year,
thermal_mw,
battery_efficiency,
ldes_efficiency,
)
Ratios of FES year to FES base_year applied to the weather year's system.
thermal_mw is the weather year's installed CCGT and peaking capacity (DUKES); both
scale with FES gas. Coal is zero (FES has none). FES batteries are added in full, and
long-duration storage beyond the base year's (pumped storage keeps its historic output).
links ¶
links(
index,
system_dir,
prices_path,
scale=1.0,
hurdle=0.0,
availability=None,
)
One price-taking link per GB interconnector in service on each snapshot.
availability None uses each link's import and export availability fitted from
flows (interconnector_availability.csv); a number applies to every link.
price_column ¶
price_column(pathway, year)
Column name for a pathway and year in data/scenarios/fes_prices.csv.
Scenarios¶
openenergy.scenario ¶
YAML scenarios: load, validate, run and write results.
AssetsSection ¶
Bases: _Strict
Renewable plants sharing the battery's grid connection.
GridSection ¶
Bases: _Strict
Shared connection; export defaults to total plant capacity, import to export.
CarbonSection ¶
Bases: _Strict
Carbon intensity file, an optional carbon price, and what dispatch plans on.
ResponseSection ¶
Bases: _Strict
Frequency-response services sold alongside trading (GB dynamic response).
Scenario ¶
Bases: _Strict
Colocation
dataclass
¶
Site total against the same plant and battery on separate connections (common days).
load_scenario ¶
load_scenario(path)
Read and validate a scenario; relative data paths resolve against the file.
parse_assignment ¶
parse_assignment(text)
Parse dotted.key=v1,v2 into the key and YAML-typed values.
apply_overrides ¶
apply_overrides(raw, overrides)
A copy of raw with each dotted key set, creating nested mappings as needed.
run_scenario ¶
run_scenario(scenario)
Backtest the scenario and, unless it is already perfect foresight, its benchmark.
write_outputs ¶
write_outputs(run, directory)
Write intervals.csv, daily.csv and summary.json; returns the directory.
With a perfect-foresight benchmark, its daily results go to benchmark_daily.csv.
Reports¶
openenergy.report.load ¶
Read the outputs written by run, system run, system validate and sweep.
BatteryOutput
dataclass
¶
A battery or co-located site backtest (openenergy run).
SystemOutput
dataclass
¶
One GB system scenario year (openenergy system run).
BackcastOutput
dataclass
¶
A system backcast (openenergy system validate).
SweepOutput
dataclass
¶
A sweep results table; keys are the swept settings, in column order.
load_output ¶
load_output(path)
Read one output directory (or a sweep CSV), detecting its kind from the files.
openenergy.report.figures ¶
Chart functions: pandas in, plotly figure out (no file I/O, reusable in an app).
cumulative_revenue ¶
cumulative_revenue(
runs, currency="GBP", title="Cumulative revenue"
)
One line per named daily revenue series, summed over time.
revenue_by_market ¶
revenue_by_market(daily, currency='GBP')
Monthly trading and frequency-response revenue, stacked.
state_of_charge ¶
state_of_charge(intervals)
Stored energy at the end of each interval, as a day by hour heat map.
site_by_month ¶
site_by_month(daily)
Plant energy available and curtailed per month (co-located sites).
generation_by_month ¶
generation_by_month(dispatch, step_hours=1.0)
Stacked monthly generation (TWh) by technology.
price_duration ¶
price_duration(series, currency='GBP')
Prices sorted from highest to lowest, one line per series, on a 0-100% axis.
mean_by ¶
mean_by(series, by='hour', currency='GBP')
Mean of each series by hour of day or by month.
system_by_month ¶
system_by_month(dispatch, step_hours=1.0)
Curtailment (TWh) and fossil emissions (MtCO2) by month.
model_vs_actual_by_year ¶
model_vs_actual_by_year(years, pairs)
Grouped bars of model and actual per year; pairs maps a label to a column stem.
sweep_effect ¶
sweep_effect(table, key)
Mean revenue per MW-year at each value of one swept setting.
openenergy.report.document ¶
Assemble output directories into one HTML report.
build_report ¶
build_report(outputs, title='OpenEnergy report', cdn=False)
One self-contained HTML document (plotly.js inlined unless cdn).
Web app¶
openenergy.app.runs ¶
What the app runs: one battery request, checked and run on historic or pathway prices.
Request
dataclass
¶
A battery of hours duration valued per MW (revenue scales with power).
year is the historic year for history and the FES year for scenario.
from_prices ¶
from_prices(prices, hours, forecast)
The request for a Request.prices token, or None if it names nothing known.
run ¶
run(request, data, power_mw=1.0)
Backtest the request and its perfect-foresight benchmark on the bundled data.
openenergy.app.results ¶
Results for the app: a compact per-MW summary and daily revenue, precomputed or live.
Result
dataclass
¶
One request's per-MW results; daily has revenue and benchmark_revenue.
Store ¶
The precomputed results, read once.
requests ¶
requests(hours, forecast)
Precomputed requests for one duration and forecast, in grid order.
from_output ¶
from_output(request, output, precomputed)
Per-MW summary and daily revenue from a 1 MW run.
openenergy.app.server ¶
FastAPI routes: HTML pages and a JSON API on the same requests.
api_result ¶
api_result(request)
Per-MW results for one battery: precomputed when available, else run now.
result_page ¶
result_page(request, power_mw=1.0)
The answer page: at once when precomputed, else a progress message while it runs.
explore_page ¶
explore_page(
hours="2",
forecast="naive_last_week",
services="none",
power_mw=1.0,
)
Value by year and by pathway for one battery, from the precomputed results.
compare_page ¶
compare_page(
item=[],
hours="2",
forecast="naive_last_week",
power_mw=1.0,
)
Up to three precomputed results side by side; the URL is the shareable comparison.
Errors¶
openenergy.errors ¶
Exceptions raised by OpenEnergy.
OpenEnergyError ¶
Bases: Exception
Base class for all OpenEnergy errors.
ConfigError ¶
Bases: OpenEnergyError
A scenario or component is configured with invalid values.
DataError ¶
Bases: OpenEnergyError
Input data is missing, malformed or inconsistent.
DispatchError ¶
Bases: OpenEnergyError
A dispatch plan cannot be produced or applied.
InfeasibleDispatchError ¶
Bases: DispatchError
The dispatch optimisation has no feasible solution.