1. What this is, and why it exists
Follow along. Sign in as
ipp_2@webill.net(passwordsupersecret). Path: Generator sites → IPP2 Atlantis Wind → Strategy. You should see the Overview tab, where the chain in this chapter becomes a capacity decision.
Data. full_demo · seed 42 · IPP2 Atlantis Wind · worked figures are illustrative unless a later chapter stamps them otherwise · last checked 2026-07-18.
1.1 The IPP's problem
You own (or operate) a generator — usually solar or wind — that makes electricity whenever the weather allows. Energy with no buyer earns R 0. Your commercial job is to sell the gap: every useful hour that is still unsold, at a realised price that clears your cost of production (LCOE), without promising more than the plant can stand behind.
When you enter the spot market, the same site is the source of §7.2 standing data. Register it from BRP / Market → Market registry → Register generator site (V7 §3.9A): the site supplies meter, technology and emissions; the plant engineer declares ramps and capacities with provenance; only the System Operator certifies reserve. The wheeling site and the Trading Unit stay linked.
That job has two faces that this volume holds together:
Sell-side strategy screens (§4–§6, §5 HAF, §11 Plant, §12 Dashboard) — read the revenue gap (realised vs achieved, unsold %, concentration), check safe contractable capacity, rank buyers against your unsold shape, test TOU counters and firm blocks, and promote only what you can defend.
Allocation, forecast and contracting (§7–§9, §8 Forecast, §13 guard) — each hour, metered injection at your bus bar has to be split among off-takers; next month's generation has to be predicted; and the "still for sale" number has to be discounted for how reliable the plant has actually been. Four questions decide whether that works commercially:
- What is still for sale, and at what realised price? Unsold hours are the prospectus; celebrating achieved price while ignoring them is how plants under-earn LCOE (§4).
- Who gets served first? When generation runs short, someone is curtailed. A rank-1 priority customer expects to be made whole before a pro-rata customer sees a single kWh (§7).
- What will I generate next month, and how much of it is already promised? If your book is subscribed beyond what you'll produce, you must not sign another off-taker (§8).
- How reliable is that answer? A plant that has been volatile, curtailed, or has starved its lower tiers is not as "available" as its nameplate suggests — and a prospective buyer deserves a number that reflects that (§5).
This suite answers all four, and it never guesses: every figure you see is computed from metered data, settled allocations and signed contracts, and is reproducible from a stored snapshot. Trader and off-taker book flow stays in V3 · Strategy; this volume is the IPP seat's home.
1.2 The chain, end to end
Read the screens first when you are learning the revenue gap; then follow the allocation chain. Five programme pieces fit together in a line; each consumes the one before it. The same waterfall algorithm runs twice — once on metered energy (settlement) and once on forecast energy (obligations) — which is why the forecast is credible: it predicts using exactly the rules that will settle.
- Hierarchy — you place every off-taker into a tier (priority / pro-rata / fixed). This is the rulebook for the split.
- Settlement — every hour, metered generation is carved across those tiers by the waterfall, and the result is stored per off-taker.
- Forecast — once a month the engine predicts next month's generation and, running the same waterfall on the forecast, tells each off-taker what to expect and tells you what's left to sell.
- HAF — a bankable availability score discounts that "left to sell" figure for volatility, curtailment and past delivery.
- Widget — a prospective buyer sees a single sentence: "You can safely contract another N MWh next month."
1.3 Glossary — every abbreviation, up front
The suite is unapologetically acronym-heavy because each number has a precise definition. Here is the full set; each is explained again in context.
| Abbrev. | Name | What it is | Where you see it |
|---|---|---|---|
| AES | Available Energy for Sales | max(0, FG − ED_total) — the
MWh you can still offer to new buyers. |
Forecast §7, widget |
| ARF | Allocation Reliability Factor | What did off-takers historically receive vs contract? Settled ÷ expected, per tier and portfolio-wide. | HAF factor 3 |
| CO | Contractual Obligation | What each off-taker will actually receive — its ED pushed through the waterfall against FG. Never exceeds ED. | Forecast §6 |
| CSF | Contract Sensitivity Factor | Structural exposure of the buyer's chosen tier: PRIORITY 1.00 · FIXED 0.90 · PRO_RATA 0.80. | HAF factor 4 |
| ED | Expected Demand | What each off-taker will realistically ask
for next month:
min(historical allocation, contract ceiling). |
Forecast §6 |
| FG | Forecasted Generation | Next month's predicted generation: a weighted blend of the last two HAG months (seasonally normalised) and SM. | Forecast §2 |
| GAF | Generation Availability Factor | Can the plant physically cover its promises? Recent generation ÷ subscribed demand, capped at 1. | HAF factor 1 |
| HAF | Historical Availability Factor | Score in [0,1] — how much of your paper
availability is bankable, given evidence.
GAF × SF × ARF × CSF. |
Dashboard, widget |
| HAG | Historical Actual Generation | What the plant really made in a past month — metered kWh at the bus bar, summed monthly. | Forecast §1, HAF inputs |
| MAPE | Mean Absolute Percentage Error | Rolling forecast-vs-actual error; drives confidence bands and recalibration alerts. | Forecast §2 |
| P50 / P75 / P90 | Probability bands | FG at 50/75/90 % confidence. P90 is the conservative figure — 90 % of the time actuals land at or above it. | Forecast §2, §7 |
| PPA | Power Purchase Agreement | The physical contract between you and one off-taker. Its allocation rule decides the off-taker's tier. | Everywhere |
| SB | Subscription Balance | FG − ED_total. Negative =
oversubscribed (stop selling); positive = headroom. |
Forecast §7, alerts |
| SCE | Safe Contractable Energy | The widget's headline:
min(AES × HAF, capacity headroom), per prospective
tier. |
Widget, wizard guard |
| SF | Stability Factor | How trustworthy is the average? 1 − coefficient of variation of seasonally-detrended generation. | HAF factor 2 |
| SM | Seasonal Model | The expected generation for a month from the plant's resource model (irradiance/wind feed, same-month history, or P50 shape). | Forecast §2 |
| TOU | Time of Use | Peak / standard / off-peak buckets; contracts and forecasts can be split across them. | Contract terms, forecast |
Two concepts worth pinning before you read on:
- Bus-bar energy — every quantity in this suite is measured at the generator before losses; loss factors are applied later, per contract, by settlement's matcher. That keeps the allocation arithmetic clean and comparable.
- Effective-dated versioning — hierarchies and forecasts are never overwritten. A change creates a new version; the old one stays exactly as it was, so history always re-reads the way it settled.
2. Your fleet — the portfolio story
The Fleet tells the story of every generator site your organisation owns, as one picture: energy still looking for a buyer, which buyers the model leans on, and whether putting the plants together looks safer than adding them up one by one.
Think of a shelf of recipe books versus the kitchen. Each plant still cooks from its own book — it forecasts, sells, allocates and settles on its own IPP strategy. The fleet page is the kitchen noticeboard: it does not change a recipe, place a bid, or move energy. It reports.
The IPP’s problem, in plain words
Five plants can each look healthy while the organisation is still carrying unsold energy, leaning on one buyer, or assuming that a Cape wind farm and a Gauteng solar plant cancel each other’s bad hours when they do not. A wall of tiles does not answer those questions in order.
2.1 Read the glance header, then the story
The glance summarized the fleet’s sales opportunity as a percentage of unsold energy, then the four chapters sit under it. It presents the main aggregated statistics of the entire fleet with summarized coverage and calculation notes.
| On the page | This manual |
|---|---|
| 01 / The sales opportunity | §2.2 |
| 02 / Who the fleet depends on | §2.3 |
| 03 / Does a bigger fleet help? | §2.4 |
| 04 / The next chapter | §2.5 |
Recompute now and Export CSV are taught in §2.6. The story drawers exploring the fleet live in §2.2–§2.5.
2.2 The sales opportunity
01 / The sales opportunity. You cannot decide what to sell next if you do not know how much energy still has no buyer, and a wall of plant tiles hides that answer.
The big sentence is chosen from the saved fleet snapshot’s unsold % — generation with no buyer, as a share of total generation in that snapshot.
| Unsold in the snapshot | Headline you see |
|---|---|
| No usable percentage | First, establish how much energy is still available. |
| 90% or more | Almost all your energy still needs a buyer. |
| More than 50% | Most of your energy still needs a buyer. |
| Above 0% | Your fleet has buyers, with more energy left to sell. |
| 0% | All energy in this snapshot is reported as sold. |
A two-colour bar splits sold (brand green) from still to sell (amber).
The footer says what to do next: check evidence and recompute if there is no percentage; check that production can meet the commitments if everything is sold; otherwise find which sites still have volume, and when buyers can use it.
Unsold energy is not a Rand loss. It is volume that still needs a contract or a market bid. The site Sales desk is where you turn that volume into a plan (§6).
Under chapter 01, the snapshot date reads Fleet model snapshot · DD Mon YYYY, or No saved fleet snapshot yet. Beside it, How sure are we? opens the evidence drawer. Read that date before you compare a sales percentage with a buyer bar: the headline uses the saved snapshot; membership and buyer exposure are evaluated today.
Review the sales plan
Review the sales plan opens the sales drawer.The side-drawer panel lists today’s fleet members, ranked by the energy each still has to sell: the unsold share of its latest forecast × its annual P50. Each row is a plant name, its export megawatts and technology in words (50 MW · Solar PV), and on the right the unsold share. The site has a forecast. Under each row is one link, Open its sales plan → to that plant’s Sales desk.
In the side-drawer a fleet of one still lists that one plant. A site missing today’s snapshot still appears here if it is a fleet member — the missing-evidence card on the page is the warning, not a hidden row. An unsold percentage is a share of the site’s own forecast, so a small plant at 100 % unsold can sit below a large plant at 60 %.
How sure are we?
The sales sentence on chapter 01 can look finished when the picture behind it is old, missing a plant, or still a stand-in for how your plants behave together. Open this drawer before you act on that sentence, and before you trust chapter 03 when it says a bigger fleet is safer.
What it is for. The drawer is the evidence shelf for the noticeboard. It answers three questions in order: which numbers are a saved photograph and which are counted today, how many plants actually contributed, and whether “these plants cover each other” came from their own meters or from a published stand-in.
Five tiles are the compact stats that used to live on the page.
| Tile | What it is telling you | Note under the number |
|---|---|---|
| Capacity factor | Of all the hours the fleet could have run at full export, what share it actually produced. Bigger plants count more. This is a fleet energy share, not a health score for one plant. | Energy weighted · N of M sites |
| Unsold energy | The same unsold % family as the chapter 01 sentence: generation with no buyer, as a share of generation. | N of M sites |
| Imbalance cost | Each plant’s imbalance cost, added together into one Rand figure. | Summed site cost |
| Diversification benefit | How many Rand lower the combined-fleet shortfall is than adding each plant’s own shortfall. The platform name is diversification benefit. The shortfall itself is Value at Risk (VaR). | Against summed site VaR, or R 0 (fleet of one) |
| Generation profile | Whether the hourly shape is built. Ready means every expected hour (P50) has its more cautious twin (P90). Partial means some expected hours lack that twin. Not built means there is no expected shape yet. | {N} hourly points for P50 and correlated P90 · correlation v{version} |
Volume correlation — estimated and n
You need this list because chapter 03’s “a bigger fleet helps” claim is only true when a bad hour at one plant is a good hour at another. If your wind farm and your solar plant sag on the same hours, owning both does not protect you. The model can only say they cover each other if it knows how their generation moves together. That knowledge is volume correlation. Without it, the green “combined fleet” bar in chapter 03 is a story with no evidence.
Everyday picture: two rain gauges on one farm. If they fill on the same hours, a storm hits both roofs. If one fills while the other stays dry, the farm still catches water. Volume correlation is that comparison for generation, one pair of plants at a time. A value near 1 means they move together. A value near 0 means they miss each other. The drawer does not print that number. It prints where the number came from.
Volume correlation is the question (do these two plants move together?). The heading is the answer you can check (whose answer is this — history, a register, or a person?). In Assumption sources. each row is two plant names, each with its organisation, an arrow between them, and a badge:
| Badge you see | What it means |
|---|---|
| estimated (n = 720 h) | The pair was measured from hours both plants actually have a history
point. n is how many of those shared hours were used.
720 h is the shortest sample that qualifies: 30 × 24 hours.
A thicker history prints a larger n,
(n = 4,380 h). |
| default — no history yet | There were not enough shared hours, so the pair uses the technology-and-province register below. n is not printed. |
| manual | Someone set this pair on purpose. n is not printed. |
The register, used only while a pair is still default — no history yet:
| Pair | Same province | Different province |
|---|---|---|
| Solar–solar | 0.80 | 0.55 |
| Wind–wind | 0.50 | 0.25 |
| Solar–wind | 0.10 | 0.10 |
| Battery with battery | 0.00 | 0.00 |
Read 0.80 as “these two solar plants in one province are assumed to sag together most of the time.” Read 0.10 as “solar and wind are assumed to miss each other.” A pair the register does not name stays at 0. Those numbers are a published stand-in, not your meters. When shared history reaches 720 hours, a later version can replace the stand-in for reporting. The old version stays, so you can still see what the model used.
A fleet of one has nothing to compare. The list says Fleet of one — no site pairs. Chapter 03 says the same thing in its own words: one site cannot spread risk.
The nightly fleet job, or Recompute now when you cannot wait, may measure pairs on the first of the month (§2.6). Closing this drawer does not measure them.
2.3 Who the fleet depends on
#fleet-buyers-story is labelled 02 / Who the
fleet depends on.
The reader’s problem, in a kitchen picture: you can sell jam from three stalls and still have one customer. If that restaurant stops buying, all three stalls feel it. Chapter 02 groups each buyer once, even when they take energy from two plants, so you see dependence, not a duplicated name per site.
The bars (#fleet-buyers-chart) are modelled exposure in
Rand — an adverse-price picture. They are not last month’s invoices and
not revenue. Think of them as: if prices move against this position,
how much of that pain sits with this buyer?
| Positive buyers | Headline you see |
|---|---|
| None | Buyer exposure is not yet visible in this model. |
| One | One buyer carries all the positive modelled exposure. |
| Two | Two buyers carry all the modelled buyer exposure. |
| Three or more | Modelled buyer exposure is spread across N buyers. |
At most three named buyers are drawn; further names collapse into
Other buyers (N). A buyer with no positive exposure is
counted in a quiet note (N other buyers have no positive exposure
reported), not drawn as a bar. If nothing is positive, the empty
copy is No positive buyer exposure is reported. This does not
establish that buyer risk is absent
(#fleet-buyers-empty).
The footer says As sales grow, watch how much depends on each
buyer. See buyer exposure
(#fleet-open-buyers) opens the buyers drawer.
See buyer exposure
Chapter 04’s second row does not open this panel; it opens Deals › Contracts (§2.5). There is still no Counterparties tab. A buyer that purchases from two plants appears once, with megawatts and adverse Rand exposure summed.
| Your problem | The on-page bars hide names after the third buyer, and they hide megawatts and the price basis. You need the full table before you add another contract with the same organisation. |
| Click path | Chapter 02 footer → See buyer exposure
(#fleet-open-buyers). |
| Drawer title | Who the fleet depends on |
| First paragraph | Each buyer is grouped once across sites. These adverse-scenario exposure amounts are not unpaid invoices or revenue. |
That first sentence is the whole job of this drawer. The number in
Exposure is modelled exposure — a
picture of if prices move against this open position, how much of
that pain sits with this name? It is not last month’s invoice, not
revenue you have already earned, and not a cash call you will definitely
pay. The nightly fleet job stores the same family as
COUNTERPARTY_EXPOSURE_R. Membership and this table are
evaluated today; they can disagree with the saved sales
snapshot under chapter 01.
Everyday picture: you do not wait for the grocer’s bill to ask “if fruit prices jump, how much of that jump sits with this restaurant?” You take the open order book, pick the unkind price, and write one Rand figure per customer. That is this table.
Inside: heading Counterparty exposure across sites
(#fleet-counterparties) and the sentence A buyer
appearing at several plants is grouped once here. Column labels
stay visible while you scroll (thead is sticky). The
columns:
| Column | What you read |
|---|---|
| Organization name | The buyer (or the other side) as an organisation name, not a counterparty id. Unattributed is a visible row when the model cannot name a party. |
| MW | Position size grouped onto that name, in megawatts. Two plants selling to the same organisation add together. |
| Adverse basis | Which price tail valued
the position. The grade sits in the middle of the cell.
A caption sits under it. A dash (—) means no basis was
stored. |
| Exposure | Modelled exposure in
Rand (COUNTERPARTY_EXPOSURE_R), with comma thousands
(R 19,200). |
What the Adverse basis cell says
Adverse basis is the book’s unkind price, not the buyer’s invoice. The engine groups each site’s open position by the other organisation, then values megawatts × hours at one tail:
- Short — you still owe that buyer energy. If they stop taking it, you may have to buy replacement. High prices hurt. The book uses the high tail p90.
- Long — you have leftover energy against that name. Low prices hurt: leftover can be cheap to sell. The book uses the low tail p10.
Those grades are price tails (how expensive or cheap the market looks), not generation P50 / P90 (how much the plant makes). They are the book’s bad case. They are not “the buyer’s bad case” on this screen, even though a high p90 price is also a buyer’s expensive hour in the forecast cells.
The cell copy, quoted exactly. The grade is lowercase and bold, centred, with the caption centred under it:
| Grade in the middle | Caption under it |
|---|---|
| p90 | 1-in-10 high price · short, buying replacement energy |
| p10 | 1-in-10 low price · long, selling leftover energy |
| (none) | — (no caption) |
1-in-10 is the plain reading of the tail: p90 is a high price that only about one hour in ten clears above, and p10 a low price that only about one hour in ten clears below. Short means the fleet is short versus that buyer: buying replacement energy can be expensive. Long means leftover energy that may have to be sold cheaply. A SUPPLY pool membership is treated as short; a DEMAND pool membership is treated as long. If one name ends up with both sides, megawatts and Rand still add; the printed grade is the last side the model stored for that row.
Worked numbers: how one Exposure cell is made
Data. Mechanism from the counterparty-exposure engine (hours = 24; default tails p10 = R 800/MWh, p90 = R 1,400/MWh). Toy positions, not today’s IPP 2 invoices. The drawer uses the same arithmetic on whatever open positions the fleet has today.
| Position | Side | Grade | Arithmetic | Exposure you would see |
|---|---|---|---|---|
| 5 MW sold to Harbour Steel | short | p90 | 5 × 24 × 1,400 |
R 168,000 |
| 3 MW leftover vs Leftover Power Desk | long | p10 | 3 × 24 × 800 |
R 57,600 |
Same megawatts at p90 cost more than at p10, because replacement is the expensive tail and leftover is the cheap tail. That is the pattern: the caption tells you which unkind price was used; the Exposure column is that price × megawatts × hours.
Done looks like this: you can name who you depend on, you can read whether each row is p90 (short, buying replacement energy) or p10 (long, selling leftover energy), you know whether one organisation dominates, and you have not added those Rand figures to unsold energy or to VaR.
Edges. There is still no Counterparties tab. Fleet
risk limits create alerts only (#fleet-limit-breaches) and
do not block site bids. A quiet on-page note about zero-exposure buyers
is not a hidden table row — open the drawer to see every grouped name
the model has. Closing the drawer (X, backdrop, or Escape) returns you
to chapter 02; nothing is saved.
2.4 Does a bigger fleet help?
#fleet-risk-story is labelled 03 / Does a bigger
fleet help?
The reader’s problem: owning two plants feels safer than owning one. It is safer only when their bad hours miss each other. If the Cape wind farm and the Gauteng solar plant both sag in the same modelled month, a bigger fleet does not help.
Everyday picture: a bakery with two ovens. Oven A can have a bad month. Oven B can have a bad month. If you add “A’s worst month” to “B’s worst month”, you are assuming both ovens have their worst month at the same time. If they bake in different weather, their bad months often miss each other. The bakery’s worst month is then milder than the sum of the two worst months. That milder number is the combined fleet. The sum of the two worst months is Sites added together.
The on-page copy says: Compare the combined fleet’s risk estimate with the sites added together. A smaller fleet bar means the model shows a benefit.
The chart (#fleet-risk-chart) appears when a monthly
distribution exists and the correlation matrix was not
refused. Two bars:
| Bar on screen | What it is | How it is made |
|---|---|---|
| Sites added together (slate) | Each plant’s one-month VaR-95, then those amounts added | Pretend each plant has its bad month on its own, then add the bad-month marks. |
| Combined fleet (brand green) | One-month VaR-95 of the fleet as one book | Walk the same made-up months for every plant together, so a good hour at one plant can offset a bad hour at another when the pair assumption says they do not move in lockstep. Then take the bad-month mark on that combined result. |
The caption is One-month risk · 95% model threshold · the distribution date.
| Situation | Headline you see (#fleet-risk-headline) |
|---|---|
| Today’s risk run refused | Today’s risk estimate was refused. |
| No monthly comparison | The fleet’s risk comparison is not ready yet. |
| One fleet member | One site cannot spread risk across a fleet. |
| Combined VaR lower | The model shows lower risk when sites work together. |
| Combined VaR higher | The model shows higher risk for the combined fleet. |
| Same either way | No risk reduction is shown yet. |
If the monthly run is simply missing, the chart is withheld
(#fleet-risk-unavailable): A valid monthly fleet
distribution and site comparison are needed before showing this
chart.
If today’s risk run was refused, the chart is
withheld too, and a rose status box sits inside the card instead
(#fleet-correlation-refused):
Today’s risk run was refused. Correlation table vN says how closely each pair of sites rises and falls together, and its pairs contradict one another. The model would not build an estimate on it, so there is no fleet risk figure for today.
Fix the manual pairs under Review the assumptions, or remove them so the defaults apply, then Recompute now.
A second link, Review the assumptions
(#fleet-open-refused-assumptions), then sits beside
Understand the estimate and opens the evidence drawer
at the pair list (How sure are we?). Fix
or remove the manual pairs there, then press
Recompute now (§2.6).
The footer names how many site-pair assumptions still use defaults (N of M site-pair assumptions use defaults. Operating history is needed to judge the benefit.). A fleet of one says A fleet of one has no site-pair assumptions to compare. When every pair has a non-default source: Review the dates and evidence behind the site-pair assumptions before relying on this estimate.
Value at Risk, in plain words
Value at Risk (VaR) is not “the most you can lose” and not cash sitting in a till. It is a modelled shortfall against the average leftover.
Picture the bakery again. The model imagines many months of every oven together: weather, prices, how much each oven baked. Most imagined months cluster around an average leftover. VaR-95 is the gap from that average down to a poor leftover. In 95 of 100 imagined months you miss the average by less than this Rand amount; in the worst 5 you miss it by this amount or more. The platform term is loss relative to expected.
The green Combined fleet bar, and the tile One-month VaR-95, are that gap for a one-month sample. How to read a made-up day versus a made-up month, what to do with the two tiles, and every field in Distribution data are taught under Understand the estimate. The next headings stay with the two bars on the page.
How the two bars are calculated
The fleet run follows the ordinary site strategy and stochastic work:
- It shares one market-price path across sites (the bakery sees the same price weather).
- It draws each site’s volume error, then mixes those errors through the current volume correlation matrix. Plants the matrix says move together tend to miss on the same hours.
- It scores each site’s margin on each path (higher is better).
- Sites added together: compute VaR-95 on each site’s
path margins, then add those VaRs
(
SUM_OF_SITE_VAR_95_R). - Combined fleet: add the sites’ margins path by
path, then compute one VaR-95 on that summed list
(
var_95_ron the one-month distribution). - Diversification
benefit is
max(sites added together − combined fleet, 0). If the combined book looks riskier, the benefit tile shows R 0; chapter 03 still tells you the combined bar is longer.
If the matrix is not a valid correlation — technically, not positive
semi-definite, which in plain words means its pairs contradict one
another — the platform refuses it rather than quietly
changing it. That refusal is the rose box inside chapter 03
(#fleet-correlation-refused): no stochastic snapshot is
written from that version, and chapter 03 withholds the chart.
Worked numbers: sites added together versus combined fleet
Data. Mechanism from the fleet-estate seed used for every multi-site fleet book (full_demo · seed 42). Toy path margins, not today’s IPP 2 invoices. The on-page bars use the same arithmetic on whatever one-month snapshot is stored.
The seed walks five made-up months (shown here already multiplied for the one-month horizon):
| Path | Plant A margin | Plant B margin | Combined (A + B) |
|---|---|---|---|
| 1 | R 2,400 | R 4,800 | R 7,200 |
| 2 | R 2,880 | R 3,600 | R 6,480 |
| 3 | R 1,920 | R 5,280 | R 7,200 |
| 4 | R 2,160 | R 4,320 | R 6,480 |
| 5 | R 2,640 | R 6,000 | R 8,640 |
Average month: plant A R 2,400, plant B R 4,800, combined R 7,200. At 95% with five paths the loss quantile is the worst slip: A R 1,920, B R 3,600, combined R 6,480.
| Label on screen | Arithmetic | Result |
|---|---|---|
| Sites added together | (2,400 − 1,920) + (4,800 − 3,600) |
R 1,680 |
| Combined fleet / One-month VaR-95 | 7,200 − 6,480 |
R 720 |
| Diversification benefit | max(1,680 − 720, 0) |
R 960 |
The combined bakery’s bad month is R 960 milder than adding the two ovens’ bad months. That is the pattern to expect when chapter 03 says The model shows lower risk when sites work together. A fleet of one cannot show this split: both bars would be the same plant, and the benefit tile reads R 0 (fleet of one).
| View | Average month | Bad-month mark | VaR-95 |
|---|---|---|---|
| Plant A alone | R 2,400 | R 1,920 | R 480 |
| Plant B alone | R 4,800 | R 3,600 | R 1,200 |
| Sites added together | — | — | R 1,680 |
| Combined fleet | R 7,200 | R 6,480 | R 720 |
| Diversification benefit (never negative on the tile) | R 960 ✓ | ||
Do not add this VaR to unsold energy or to buyer exposure. They measure different jobs.
Understand the estimate
Understand the estimate
(#fleet-open-risk) opens the risk drawer. The title in the
green bar is What the risk estimate means. The
title-row Recompute now and Export CSV
buttons stay in §2.6.
| Your problem | Chapter 03 shows two bars and a date. You still need to know what a made-up day or month is, how to read the two VaR-95 tiles, what to do with them, and what each number in Distribution data is. |
| Click path | Chapter 03 footer #fleet-open-risk. |
| Drawer title | What the risk estimate means |
| First paragraph | Value at Risk is a modelled loss threshold for a chosen period. A 95% threshold is not a maximum loss; worse outcomes remain possible. |
Follow along. Seat: IPP 2 (
ipp_2@webill.net, passwordsupersecret) on full_demo · seed 42. Path: IPP Sites → Fleet → chapter 03 Understand the estimate. You should see the title What the risk estimate means, then One-day VaR-95 R 30 and One-month VaR-95 R 720. Open Distribution data for the 1 day and 1 month rows.
Read the headings below in order: a made-up day or month, what VaR-95 means, how the two tiles differ, what to do, then every field in Distribution data.
A made-up day or month
The model cannot wait for the next hundred real days. It writes a pile of made-up days (and, separately, a pile of made-up months) for the whole bakery.
Think of one slip of paper. On that slip the model writes: what the weather did, what prices did, and how much each oven baked. Then it adds up the leftover money the book would have kept that day. That leftover is the margin on that slip — Rand the book keeps after costs, not a page margin. One slip is one path: one made-up day of the fleet, or one made-up month of the fleet.
The pile is not a forecast you will invoice. It is a set of “what if this day (or this month) went like this?” stories, written so a bad leftover can be compared with a typical leftover.
| Everyday picture | On this drawer |
|---|---|
| One imagined bakery day, all ovens baking together | One path on the 1 day sample |
| One imagined bakery month, all ovens baking together | One path on the 1 month sample |
| The whole pile of imagined days | The daily distribution |
| The whole pile of imagined months | The monthly distribution |
The two piles are baked separately. A made-up month is not “a made-up day written thirty times.” Weather and prices in a month do not behave like thirty copies of one day.
On seed 42 the fleet-estate pack writes five slips per pile (small on purpose, so you can add them by hand). The meaning of 95 is still “95 in 100”: five slips do the same job as a larger pile, with rougher marks.
What VaR-95 means
VaR-95 answers one question: on a bad slip, how far below the average leftover do we fall?
It does not answer “how much cash will I have to pay?” It is not a pile of rands you already hold. It is a gap — how much worse than typical the leftover is, at a chosen mark.
The platform convention is loss relative to expected. In kitchen steps:
- Take every slip in the pile. Read the leftover on each slip.
- Find the average leftover (add them up, divide by how many slips).
- Find the poor mark: the leftover that leaves only the worst 5 in 100 slips below it.
- VaR-95 is average minus that poor mark.
In 95 of 100 made-up days (or months), the shortfall against the average is smaller than this Rand amount. In the worst 5, the shortfall is this amount or worse. Worse slips remain possible. The first paragraph of the drawer says that: a 95% threshold is not a maximum loss.
Data. full_demo · seed 42 · fleet-estate slips used for every multi-site fleet book. Toy leftovers, not today’s IPP 2 invoices. The drawer uses the same gap on whatever snapshot is stored.
The one-day pile on that seed (already added across the two ovens):
| Slip | Combined leftover |
|---|---|
| 1 | R 300 |
| 2 | R 270 |
| 3 | R 300 |
| 4 | R 270 |
| 5 | R 360 |
Average leftover: (300 + 270 + 300 + 270 + 360) / 5 =
R 300. The poor mark with five slips is the worst
leftover, R 270. Then:
VaR-95 = 300 − 270 = R 30
That R 30 is the One-day VaR-95 tile. It means: relative to a typical imagined day, a bad imagined day is R 30 lighter. It does not mean you will be asked for R 30, and it is not unsold energy.
The one-month pile on the same seed is those leftovers × 24 so you can see the arithmetic. That is a demo shortcut, not how a live month is built: a nightly run walks a real month on its own, and you must not turn a live one-day tile into a month by multiplying. Average month R 7,200, poor mark R 6,480, gap R 720. That R 720 is the One-month VaR-95 tile and the green Combined fleet bar taught above.
One-day VaR-95 and one-month VaR-95
The drawer eyebrow is Fleet risk. The heading is
Risk estimates and their evidence
(#fleet-risk). Under it, one line spells the abbreviation
out: VaR-95 (Value at Risk at 95 %) is the loss the model expects to
beat on 95 days in 100. Two tiles sit side by side. They are
two piles, not one number written two ways.
| Tile you see | Id | What the big number is | How to read it |
|---|---|---|---|
| One-day VaR-95 | #fleet-var-one-day |
The gap on the made-up-day pile | “On a bad imagined day, we miss the average day by about this many rands.” |
| One-month VaR-95 | #fleet-var-one-month |
The gap on the made-up-month pile — the same family as the green Combined fleet bar | “On a bad imagined month, we miss the average month by about this many rands.” |
Under each tile, a note that starts with the date that pile was run:
| When a snapshot exists | When it does not |
|---|---|
| DD Mon YYYY · sum of sites R … · benefit R … — for example 16 Sep 2026 · sum of sites R 1,234 · benefit R 56 | No fleet distribution yet |
sum of sites is sites added together for
that pile: each oven’s own VaR-95, then those gaps
added. benefit is diversification benefit
on that pile: max(sum of sites − this tile, 0). On seed 42
the one-day note ends sum of sites R 70 · benefit R 40, and the
one-month note ends sum of sites R 1,680 · benefit R 960, each
after its run date. Amounts use comma thousands.
When today’s risk run was refused. A rose box
(#fleet-risk-refused) sits above the tiles:
These figures are not today’s. Today’s risk run was refused: site-pair correlation table vN contradicts itself, so no new estimate was written. The figures below are from the last accepted run on DD Mon YYYY.
Both VaR tiles then turn amber. The numbers are still the last accepted run’s; the run date at the start of each note says how old they are. Fix the pairs through Review the assumptions and press Recompute now (§2.6).
A bigger VaR-95 means a larger modelled miss versus the average — the poor leftover sits farther below typical. A smaller number means a milder miss. Smaller is not “safe.” It is a shorter gap.
Do not turn the one-day tile into a month by multiplying by 30, or by the square root of 30. Those shortcuts pretend each day is a fresh coin flip. This book is judged monthly, and the month pile is sampled on its own. If the day tile is R 30 and the month tile is R 720, read each as its own sentence.
If a tile has no snapshot, the value is Not available (not R 0). R 0 on a tile that has a snapshot would mean the poor leftover matches the average — a different claim.
What to do with the numbers
These tiles do not place a bid, sign a contract, or move energy. They tell you whether to slow down, whom to ask, and which drawer to open next.
- Read the dates first. Under the first paragraph: Latest daily distribution: … Latest monthly distribution: … These may differ from the fleet model snapshot date. A zero imbalance cost does not prove operations are free of risk. A missing date prints Open. If a date is Open, that pile was not run — do not compare the tiles with chapter 01’s sales percentage or with each other.
- Read the one-month tile first. The organisation is judged on a month. That number is the green bar in chapter 03. Use the one-day tile as a same-day twin, not as the number you take to a monthly meeting.
- Compare the bakery with the ovens. Look at sum of sites under One-month VaR-95. If the tile is smaller than that sum, the model says the ovens’ bad months miss each other (the pattern of R 720 versus R 1,680 above). If the tile is larger, or benefit is R 0 on a fleet of several plants, a bigger fleet is not helping in this run.
- Open How sure are we? when the story depends on a
guess. Press Review the assumptions
(
#fleet-risk-open-assumptions) — it switches this drawer to How sure are we? so you can read the pair badges without walking back to chapter 01. Open it when any pair still says default — no history yet, when sites are missing today’s snapshot, or when the rose box These figures are not today’s. (#fleet-risk-refused) sits above the tiles. Combined-fleet VaR uses those pair assumptions; a default pair is a register value, not overlapping plant history. - Combined versus sites-added-together matters when you are deciding whether a new plant in another weather region actually offsets, or whether two wind farms in the same province just double the same bad week. It does not matter as a scoreboard for a fleet of one: both views are the same plant, and the benefit tile reads R 0 (fleet of one).
- Take the one-month number to Sales when chapter 01 still shows a large unsold percentage and you need to know whether a new contract would sit on a book whose bad month already misses the average by a lot. Sales still lives on each site’s Sales desk; this drawer does not sell the gap.
- Take it to the board when the one-month gap is large compared with what the organisation can absorb, when combined looks worse than sites added together, or when most pairs are still defaults. Take the dates and the assumption badges with you, not the VaR tile alone.
Do not add VaR to unsold energy or to buyer exposure. They measure different jobs: volume still looking for a buyer, pain sitting with a named buyer, and a shortfall against an average leftover.
When to worry. A date that says Open; a tile that says Not available; amber tiles under These figures are not today’s.; a combined bar longer than Sites added together; benefit R 0 on more than one plant; many default — no history yet badges. When not to treat it as an alarm. A smaller tile than last month, by itself; a fleet of one (there is nothing to spread); a zero imbalance-cost tile in How sure are we? (that tile is a different job).
Done looks like this: you can say the one-month number in a sentence (“we miss the average imagined month by about R 720 at the 95% mark”), you know whether it is lower than Sites added together, and you have opened the assumptions when any pair still says default — no history yet.
Edges. Recompute now writes fleet snapshots only (§2.6). It does not rewrite site allocation runs. A refused correlation writes no new estimate: the tiles keep the last accepted run’s figures, in amber, under the rose box — or Not available if no run was ever accepted. Closing the drawer (X, backdrop, or Escape) returns you to chapter 03; nothing is saved.
Distribution data
Fold Distribution data
(#fleet-fan-data) under the two tiles. The summary label is
Distribution data. Inside is a table with uppercase
headers. The fold shows only these columns:
Horizon, P05, P50,
P95. It does not print a mean, a min, a max, a sample
count, or extra grades such as P10 or P90 — those can exist on the
stored snapshot; they are not on this screen.
Each row is one pile. Labels, quoted exactly: 1 day and 1 month. A pile with no snapshot is omitted (no blank row). If both piles are missing, the table has no body rows and this empty copy prints under it: No fleet distribution has been run yet.
P05 / P50 / P95 here are leftovers on the slips (Rand the book keeps on a poor / middle / strong imagined day or month). They are not generation P50 / P90, not price P10 / P50 / P90, and not VaR-95. VaR-95 is a gap. These three cells are levels.
Amounts use comma thousands (R 6,480). A missing cell on
a row that does exist renders as R 0 (the
drawer treats an empty leftover as zero). That is not the same empty
state as a missing row.
1 day — every field you see
Data. full_demo · seed 42 · IPP 2 fleet book · fleet-estate one-day slips (
[100, 120, 80, 90, 110]and[200, 150, 220, 180, 250], then added path by path). Same toy leftovers as the one-day worked example above.
| Field on screen | Unit | Plain meaning | How it relates to VaR-95 | Seed 42 |
|---|---|---|---|---|
| Latest daily distribution (date line) | Date, or Open | The day this one-day pile was stored. Open means no daily pile yet. | Dates the tile; it is not the VaR amount. | The run date (DD Mon YYYY), or Open if
that snapshot is missing |
| One-day VaR-95 (tile value) | Rand, or Not available | The gap: average imagined-day leftover minus the poor leftover. | This is one-day VaR-95. | R 30 |
| Note under the tile | Run date, then a Rand sentence, or No fleet distribution yet | The date the one-day pile was run. sum of sites is each oven’s own one-day VaR-95 added. benefit is how much smaller the combined gap is than that sum (never below zero). | The tile is the combined gap; the note is the oven-by-oven twin and the difference. | {run date} · sum of sites R 70 · benefit R 40 |
| Horizon | Label 1 day | Which pile this table row belongs to. | Tells you the leftover cells sit on the same pile as One-day VaR-95. | 1 day |
| P05 | Rand | A poor leftover: about 5 in 100 imagined days are worse than this. | Near the poor leftover used in the gap. VaR-95 ≈ average − this neighbourhood. It is not the gap itself. | R 270 |
| P50 | Rand | The middle leftover: half the imagined days are lighter, half heavier. | A typical middle leftover. VaR uses the average, which can differ from P50. On this tiny seed they match (R 300). | R 300 |
| P95 | Rand | A strong leftover: only about 5 in 100 imagined days are better than this. | The lucky tail. A large P95 does not shrink VaR-95; VaR looks at the poor side versus the average. | R 348 |
Read the one-day row as a fan of leftovers: poor R
270, middle R 300, strong R
348. The tile R 30 is 300 − 270
on this seed (average minus poor mark). If P05 and P95 sit far apart,
the imagined days spread widely; the VaR tile can still be small if the
poor mark sits close to the average.
1 month — every field you see
Data. Same seed and ovens; the pack stores the month pile as those day leftovers × 24. That is how this demo was written, not a rule you should apply to a live one-day tile.
| Field on screen | Unit | Plain meaning | How it relates to VaR-95 | Seed 42 |
|---|---|---|---|---|
| Latest monthly distribution (date line) | Date, or Open | The day this one-month pile was stored. Open means no monthly pile yet. | Dates the green bar and the one-month tile. | The run date (DD Mon YYYY), or Open if
that snapshot is missing |
| One-month VaR-95 (tile value) | Rand, or Not available | The gap: average imagined-month leftover minus the poor leftover. | This is one-month VaR-95 — the green Combined fleet bar. | R 720 |
| Note under the tile | Run date, then a Rand sentence, or No fleet distribution yet | The date the one-month pile was run, then sum of sites and benefit for the month pile (the same family as chapter 03). | Compare the tile with sum of sites to see whether the bakery is milder than the ovens added. | {run date} · sum of sites R 1,680 · benefit R 960 |
| Horizon | Label 1 month | Which pile this table row belongs to. | Tells you the leftover cells sit on the same pile as One-month VaR-95. | 1 month |
| P05 | Rand | A poor leftover for a made-up month. | Near the poor leftover in VaR-95 = average − poor mark.
On this seed the poor mark is R 6,480. |
R 6,480 |
| P50 | Rand | The middle leftover for a made-up month. | Middle, not the gap. On this seed it matches the average (R 7,200). | R 7,200 |
| P95 | Rand | A strong leftover for a made-up month. | Lucky tail of the month pile. It does not replace the VaR tile. | R 8,352 |
| Horizon | P05 | P50 | P95 | VaR-95 (tile) |
|---|---|---|---|---|
| 1 day | R 270 | R 300 | R 348 | R 30 |
| 1 month | R 6,480 | R 7,200 | R 8,352 | R 720 |
| VaR-95 is the gap, not a fourth leftover. Empty fold copy: No fleet distribution has been run yet. | — | |||
Do not add P05 to VaR-95. One is a leftover on a poor slip; the other is how far that neighbourhood sits below the average.
Empty states, in one place:
| What you see | When |
|---|---|
| Open after Latest daily distribution: or Latest monthly distribution: | That pile has no stored date |
| Not available on a VaR tile | That pile has no snapshot |
| No fleet distribution yet under a tile | Same — no snapshot for that tile |
| No fleet distribution has been run yet. under the fold | Both piles are missing; no table rows |
| Only one table row | Only one pile exists; the other horizon is omitted |
| R 0 in a P05 / P50 / P95 cell | That leftover was stored empty and the drawer prints zero |
The date line also says the distribution dates may differ from the fleet model snapshot under chapter 01. Read both dates before you compare a sales percentage with a VaR tile.
2.5 The next chapter
#fleet-next-chapter is labelled 04 / The next
chapter. The heading is Three practical places to
focus. It is not a fourth chart, and it does not reopen the
drawers from chapters 01–03. Those chapters explain; each row here
leaves the dashboard to act.
Think of the noticeboard again. Chapters 01–03 are the notices. Chapter 04 is three doors out of the kitchen: to the stall that sells, to the order book, and to the delivery log.
Each row has a number, a title, a one-line detail, and one action; the row’s id sits on that action.
| # | Title you see | Detail | Action (id) | Where it goes |
|---|---|---|---|---|
| 01 | Turn available energy into a sales plan, or Keep the sales plan aligned with production when unsold is 0% | {Site} has the most energy still to sell. Its Sales desk ranks the buyers that fit its hours. | Open its Sales desk
(#fleet-next-sales) |
That site’s Sales desk |
| 02 | Keep buyer dependence visible | Before adding a contract, check which buyers already hold the fleet’s signed and active agreements. | Open contracts
(#fleet-next-buyers) |
Deals › Contracts (V7 §6) |
| 03 | Keep the model grounded in operating history | Metered intervals replace default assumptions about how sites offset one another’s production swings. | Import intervals
(#fleet-next-evidence) |
The Import intervals modal (V2 §7.7) |
Done for chapter 04: you have opened the Sales desk of the site with the most energy to sell, checked which buyers already hold signed and active contracts, and — if the pair list is still mostly defaults — imported metered intervals. The footnote under the four chapters reminds you: unsold energy, buyer exposure and fleet risk are different measures. Do not add them together.
Row 01 — turn available energy into a sales plan
This is the first row on chapter 04. It picks the fleet member with the most energy still to sell — the unsold share of its latest forecast × its annual P50, the same ranking as the sales drawer (Review the sales plan) — and names it.
| Your problem | Chapter 01 named a fleet unsold percentage. You still have to pick a plant and a buyer. |
| Title you see | Turn available energy into a sales plan — or Keep the sales plan aligned with production when the snapshot unsold is 0%. |
| Detail under the title | {Site} has the most energy still to sell. Its Sales desk ranks the buyers that fit its hours. |
| Action | Open its Sales desk
(#fleet-next-sales) — opens that site’s Sales desk (§6). |
| When no site has unsold energy | The detail reads Each site’s Sales desk ranks the buyers that
fit its hours. and the action is Open the Sites
register (same id), which opens
/org/ipp-sites/sites. |
Done looks like this: you are on the named site’s Sales desk, reading the candidates that fit its unsold hours (§6.4 step 2), and you have not treated the fleet unsold % as cash already lost.
Where this is taught. The ranked site list behind this row: §2.2 Review the sales plan. Selling the gap: §6.
Row 02 — keep buyer dependence visible
This is the second row. It opens the contract register rather than the buyers drawer, because the question before a new contract is who already holds one.
| Your problem | You are about to add a contract. You need to see which buyers already hold the fleet’s signed and active agreements. |
| Title you see | Keep buyer dependence visible |
| Detail under the title | Before adding a contract, check which buyers already hold the fleet’s signed and active agreements. |
| Action | Open contracts (#fleet-next-buyers) —
opens Deals › Contracts
(/org/deals/contracts). |
For the modelled Rand each buyer carries, stay on the Fleet page and use chapter 02’s See buyer exposure (§2.3). Do not add those Rand figures to unsold energy or to VaR.
Done looks like this: you can name the buyers who already hold signed or active agreements, and you know whether a new contract would deepen dependence on one of them.
Where this is taught. The contracts register: V7 §6. Columns, adverse basis, and the worked Exposure cells: §2.3 See buyer exposure.
Row 03 — keep the model grounded in operating history
This is the third row. Pair assumptions stay default — no history yet until the plants have enough overlapping metered history. This row is the way to supply it.
| Your problem | Chapter 03 says a bigger fleet helps only when bad hours miss each other. While the pairs are defaults, that is a register guess, not your plants’ history. |
| Title you see | Keep the model grounded in operating history |
| Detail under the title | Metered intervals replace default assumptions about how sites offset one another’s production swings. |
| Action | Import intervals
(#fleet-next-evidence) — opens the same Import intervals
modal as the header button. |
To read which pairs are still defaults first, open How sure are we? under chapter 01 (How sure are we?). Imported intervals count towards the next pair estimate, which the fleet job makes on the first of the month (§2.6); they do not change today’s figures.
Done looks like this: the modal has shown Imported N intervals, and you know that a pair moves from default to estimated only once enough overlapping hours exist (720 by default) and the monthly estimate has run.
Where this is taught. The modal, the file schema and every refusal: V2 §7.7. Tiles, Volume correlation, badges, and n: §2.2 How sure are we? and Volume correlation.
2.6 Export CSV and Recompute now
The four chapters and their drawers teach what the numbers mean (§2.2–§2.5). This section is the two buttons on the top right of the Fleet title row: how to refresh the noticeboard, and how to take a copy off the page.
Everyday picture: the Fleet page is a kitchen noticeboard. Recompute now reprints the board from today’s books. Export CSV photocopies three chapters of that board into a spreadsheet. Neither button bakes a plant’s own recipe — that bake is Run Forecast Now on one site’s Overview.
Follow along. Seat: IPP 2 (
ipp_2@webill.net, passwordsupersecret) on full_demo · seed 42. Path: IPP Sites → Fleet (/org/ipp-sites). On the right of Your fleet, at a glance you should see the white Export CSV then the dark Recompute now. Click Export CSV: the browser downloadsfleet-YYYY-MM-DD.csv. Click Recompute now: it reads Queuing… for a moment, then the flash reads Fleet recompute queued. It runs in the background; refresh in a minute to see the rebuilt model. Reload after the job has finished to see a new snapshot date.
Where the buttons sit
Both live on the Fleet tab only — GET
/org/ipp-sites (the same page as
/org/fleet). They sit in the title row
(#fleet-dashboard-header), in the right-hand action cluster
(#fleet-dashboard-actions), after the glance identity and
after Explore the fleet when you own sites.
| Control | Id | What you see | Tooltip |
|---|---|---|---|
| Export CSV | #fleet-export |
White ghost button with a download icon, left of the dark one | None |
| Recompute now | #fleet-recompute |
Dark Terminal-Ink button with a refresh icon, far right — the only filled action on the row | Opens below the button: Rebuilds the fleet model and risk estimate from today’s site forecasts. It also runs every night; results appear here when the background run finishes. |
They stay visible on the empty card (No generator sites owned — nothing to aggregate). Explore the fleet hides when you own no sites; these two do not.
Who may click. Anyone signed into the organisation who can open IPP Sites → Fleet. The buttons are not hidden behind a second role, not disabled on an empty fleet, and not reserved for an operator seat.
Recompute now
Recompute now queues the same worker the clock uses
at night (WB.Strategy.Workers.RunFleet), scoped to
this organisation’s fleet book and
today’s date.
It is not Overview Run Forecast Now. That button sits on one plant, shows Running…, and seals that plant’s forecast snapshot. This button reprints the fleet noticeboard. It does not open a spinner, and it does not walk a site’s allocation waterfall.
| Your problem | The story is a saved picture. Sites, contracts, or pair history moved, and you do not want to wait for tonight. |
| Click path | IPP Sites → Fleet → title row, top right → dark
Recompute now (#fleet-recompute). |
| What happens, in order | 1. The button reads Queuing… while the page queues one fleet job for today’s date. 2. The flash says what happened (table below). 3. The numbers on the page do not change yet. 4. The worker reprints the fleet book (steps below). 5. You reload Fleet (or leave and come back) to read the new picture. |
The flash, quoted exactly:
| When | Flash |
|---|---|
| The job was queued | Fleet recompute queued. It runs in the background; refresh in a minute to see the rebuilt model. |
| A fleet recompute was already queued or running (a click within the last five minutes) | A fleet recompute is already queued or running, so it was not queued twice. The new model appears here when that run finishes. |
| The job could not be queued (red error flash) | Could not queue the fleet recompute. Try again in a moment; the nightly run still rebuilds the model. |
What the worker does, in order, for this fleet:
- Reconciles membership — who is an active member today.
- On the first of the month only, may estimate site-pair volume correlations if that day has no estimate yet. Other days keep the pairs you already have.
- Stores fleet KPIs (capacity factor, unsold %, imbalance cost, diversification) and grouped buyer exposure.
- Writes a fleet risk snapshot dated today.
- Samples the one-day and one-month distributions when the correlation
matrix is usable. If the matrix was refused, or the fleet has no
members, this last step is skipped; on a refusal, chapter 03’s rose box
(
#fleet-correlation-refused) explains why.
Done looks like this: you saw Fleet recompute
queued. It runs in the background; …; after a reload, chapter 01’s
date (#fleet-story-basis) reads Fleet model snapshot ·
DD Mon YYYY for today; the amber Last fleet run…
chip (#fleet-stale) in the page top bar
has cleared (it only shows when there is no snapshot, or the latest is
more than two days old); and How sure are we? /
Understand the estimate show the new tiles. If
stochastic sampling was skipped, the KPI snapshot can still be new while
the VaR tiles stay Not available.
What it does not do. It does not rewrite a site’s allocation run, site risk snapshot, or site distribution. It does not place a bid, move energy, or change a contract. It does not estimate pairs except on the first of the month. It does not wait on the page until the job finishes — Queuing… lasts only while the job is queued, not while it runs. A second click within about five minutes is treated as the same queued job, not a second run; the flash then says A fleet recompute is already queued or running, so it was not queued twice.
Edges. An empty fleet still queues the job:
membership is reconciled and KPIs are stored; the distribution sample is
skipped because there are no members. If the job cannot be queued at
all, the red flash Could not queue the fleet recompute. … says
so; the nightly run still rebuilds the model. Failures while the job
runs are written to the operations log, not flashed on this page — if
the snapshot date does not move after a reload, ask operations to check
the strategy queue (V21 §3). The
stale chip is a date label, not a traffic light on the button.
What runs while you sleep
You do not have to press the button every day. The same worker runs
for every fleet book at 03:15
(15 3 * * * on the platform clock). That nightly pass does
the same five steps: reconcile membership, maybe estimate pairs on the
first of the month, store KPIs and buyer exposure, write the fleet
snapshot, then sample the one-day and one-month distributions when the
correlation is usable.
The button is that pass now, for your organisation only. Use it when the amber chip says the picture is old, when you just recorded a departure, or when you cannot wait for 03:15. Leave it alone when tonight’s run is soon enough.
-
03:15
Nightly
RunFleet— every organisation’s fleet book - You Recompute now — this organisation, today’s date, same worker
Where this is taught. The nightly fleet worker is catalogued in V21 §3. The day’s clock preview is V0 §6.
Export CSV
Export CSV downloads today’s fleet evidence as a text file. It is a photocopy of three chapters of the noticeboard — the KPI keys, the active members, and the pair-assumption sources — not the story sentences and not the buyer table.
| Your problem | You need the membership, KPI keys, and pair sources in a spreadsheet — for a board pack, an analyst, or an audit — without retyping the drawers. |
| Click path | IPP Sites → Fleet → title row, top right →
Export CSV (#fleet-export). |
| Address | GET /org/fleet.csv (same organisation session as the
page). |
| File you get | fleet-YYYY-MM-DD.csv, named with today’s UTC
date. |
What happens, in order. The browser requests
/org/fleet.csv. The server builds four columns from
today’s book (not from the saved sales headline if that
snapshot is older). The response is
text/csv; charset=utf-8, offered as an attachment. The
Fleet page does not flash and does not change.
Done looks like this: your browser’s download list
has fleet-YYYY-MM-DD.csv, and opening it shows a header row
plus one data row per metric, per active site, and per site pair.
What the file contains
Every field is wrapped in double quotes. A quote inside a value is
doubled (" → ""). Rows end with a newline.
Encoding is UTF-8. This is the platform’s evidence
dump, not a Microsoft Excel template — Excel and Numbers will open it if
you pick UTF-8 / comma.
The header, quoted exactly: record, key,
value, source.
record |
key |
value |
source |
Which chapter of the story |
|---|---|---|---|---|
metric |
The KPI name (below) | The number as stored | Always fleet |
How sure are we? tiles — capacity factor, unsold, imbalance, diversification |
site |
The plant’s name | Export capacity in megawatts | The plant’s technology (for example
WIND) |
Explore the fleet / sales-plan list — today’s active members |
correlation |
The pair as site-id:site-id (two identifiers, not the
plant names) |
The correlation version number | SOURCE:Nh — for example ESTIMATED:720h or
DEFAULT:0h |
Volume correlation / Assumption sources |
The metric keys, quoted exactly:
| Key in the file | Tile it matches |
|---|---|
FLEET_CAPACITY_FACTOR_PCT |
Capacity factor |
FLEET_UNSOLD_PCT |
Unsold energy |
FLEET_IMBALANCE_COST_R |
Imbalance cost |
DIVERSIFICATION_BENEFIT_R |
One-day diversification benefit |
DIVERSIFICATION_BENEFIT_1M_R |
One-month diversification benefit (the family of the green Combined fleet bar) |
Those KPI rows are computed today for the current
month, the same way membership and buyer exposure are evaluated today.
They can disagree with a saved sales snapshot under
chapter 01. Read #fleet-story-basis before you treat an
exported unsold percentage as the headline you just saw.
Worked rows: what a short file looks like
Data. Mechanism from
GET /org/fleet.csv(quoted UTF-8). Toy values so you can see the threerecordkinds — not a claim about today’s IPP 2 totals.
"record","key","value","source"
"metric","FLEET_UNSOLD_PCT","98.8","fleet"
"site","IPP2 Atlantis Wind","50.0","WIND"
"correlation","aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee:ffffffff-0000-1111-2222-333333333333","1","ESTIMATED:720h"
Read it as: one KPI (unsold 98.8%), one active member (50 MW wind),
one pair whose assumption is estimated from 720 overlapping hours. The
pair key is two site identifiers; the plant names live
on the site rows.
Who it is for. A finance or risk person who works in a spreadsheet; an auditor who needs today’s membership and pair sources beside the on-screen tiles; anyone preparing a board pack who must not retype the drawers. It is not a sales invoice, not last month’s settlement, and not a file you send to a buyer.
What it does not do. It does not include the buyer-exposure table (organisation name, MW, adverse basis, Rand). It does not include story headlines, the sold / still-to-sell bar, or Distribution data (P05 / P50 / P95). It does not change the fleet book. It is not the curtailment Export CSV on a plant claim (§10).
Edges. An empty fleet still downloads: you get the
metric rows (often zeros) and no site rows. A missing
organisation session returns 404 with the body
Fleet not found — sign in again and open Fleet from
IPP Sites. The file is scoped to the signed-in
organisation; you cannot pull another organisation’s fleet by editing
the address. Closing the download dialog does not recompute
anything.
Words on this screen
| Word on screen | Plain meaning |
|---|---|
| Recompute now | Queue today’s fleet reprint for this organisation. Flash: Fleet recompute queued. It runs in the background; refresh in a minute to see the rebuilt model. |
| Export CSV | Download fleet-YYYY-MM-DD.csv — KPI keys, today’s fleet
members, pair sources |
| Fleet recompute queued. … | The job is on the strategy queue. Reload later; the
page does not wait. …already queued or running, so it was not queued
twice means an earlier click is still in hand |
| Last fleet run … / No fleet snapshot yet | Amber date chip (#fleet-stale) in the page top bar when
the snapshot is missing or more than two days old |
| Unsold energy | Share of modelled generation with no buyer in the saved snapshot (unsold %) |
| Modelled exposure | Adverse-price Rand against a named (or unattributed) buyer, not an
invoice (COUNTERPARTY_EXPOSURE_R) |
| Adverse basis | The price tail that valued the row: centred p90 /
p10, then
1-in-10 high price · short, buying replacement energy or
1-in-10 low price · long, selling leftover energy |
| Sites added together | Sum of each site’s VaR-95, as if each bad month happened on its own |
| Combined fleet | VaR-95 after the same paths are added together, so offsets can appear |
| VaR-95 | 95% Value at Risk — shortfall against the average leftover on one pile of made-up days or months |
| One-day VaR-95 | That shortfall on the daily sample — a separate pile from the month, not the month divided by 30 |
| One-month VaR-95 | That shortfall on the monthly sample — the green bar in chapter 03 |
| Distribution data | Fold of leftovers: Horizon, P05, P50, P95 for 1 day and 1 month (P05 / P50 / P95) |
| Diversification benefit | How much lower fleet VaR is than the sum of site VaRs (zero for a fleet of one; floored at zero) |
| P50 / P90 profile | Expected versus conservative generation shape, hour by hour (P50 / P90) |
| Capacity factor | Energy-weighted actual energy as a share of export capacity × time — not a plant-health score |
The headline uses the saved fleet snapshot.
Membership, buyer exposure, and the CSV are evaluated
today. Read the snapshot date under chapter 01
(#fleet-story-basis) before you compare a sales percentage
with a buyer bar or with an exported unsold key.
Where this is taught. One plant’s profit-and-loss narration is §12 Dashboard. Selling the gap is §6 Sales. The Sites register is V2 §4.1; recording a departure is taught above. Importing metered intervals is V2 §7.7. Run Forecast Now on one plant is §4 Overview. The nightly fleet worker is catalogued in V21 §3.
3. Sites
A site is one plant. The IPP Fleet in §2 is every plant your organisation owns, as one picture. This chapter is the site-level book: how you open one generator and walk its strategy tabs.
Think of the fleet page as the kitchen noticeboard and each site as its own recipe book. The noticeboard tells you what is still to sell across the shelf. You still cook from one book at a time — forecast, sell, allocate and settle on that plant alone.
Open IPP Sites in the Wheeling sidebar. The room has two tabs:
| Tab | Address | Job |
|---|---|---|
| Fleet (default) | /org/ipp-sites |
The four-chapter portfolio story (§2) |
| Sites | /org/ipp-sites/sites |
The site register — one row per plant, then that plant’s workspace |
The Sites tab is the register of generator sites
(which site needs you, and where to go), taught field by field
in V2 §4.1. Press a
site’s name for its quick view, then Open site
workspace, or follow the row’s Next step. Old
/org/fleet still opens the Fleet tab.
The site workspace
(/org/ipp-sites/sites/{id}/{tab}) gathers the screens this
volume teaches under five tabs. Site details (top
right) holds the complete site record and Site lifecycle &
fleet membership (§2).
| Workspace tab | Tooltip | What it holds | Taught in |
|---|---|---|---|
| Operations | Plant, meter data, infrastructure, and curtailment. | The plant model, Plant live, meter history and interval coverage, curtailment claims | §11 · V2 §7.2 · §10 |
| Performance | Measured performance, forecasts, revenue and risk in one workspace. | The Overview panels, then a fold of measured performance and revenue analysis | §4 |
| Allocation | Allocation rules, forecasts and settled energy in one place. | Allocation rules, allocation forecast, settled allocations | §7 · §8 · §9 |
| Commercial | Sales, contracts, and commercial commitments. | Open proposals, contract commitments, the Sales desk | §6 |
| Dashboard | The site’s story since commissioning: earnings, losses, health and what to do next. | The site story | §12 |
The plant model at the top of Operations lists the
plant’s facts with comma thousands and at most three decimals, for
example 118,260.0 MWh.
The browser tab names the page the way the sidebar and tabs do: the register reads Sites · IPP Sites · Webill Green, and a workspace reads {Site name} · {Tab} · Webill Green — for example IPP1 Sandton Solar · Performance · Webill Green. A panel hosted inside a tab keeps that title rather than showing its own. The room chip in the top bar (IPP SITES) is a link back to the room’s first page, the Fleet tab.
The top bar carries Manual
(#ipp-sites-manual), which opens this volume at the chapter
for the view you are on, in a new tab. On the register it opens this
chapter and sits right of the N sites chip. On the workspace
each tab opens its home chapter — Operations §11, Performance §4, Allocation §7,
Commercial §6, Dashboard §12 — and the onboarding form opens V2 §4. The
screens that still open on their own under
/org/generator-sites/{id}/strategy/… do the same —
Allocation · Forecast opens §8, Outcomes §9, Curtailment §10, Plant §11 and the battery contract §20; the sales proposal studio and
the proposal review page open V7 §3.
3.1 Getting in — the IPP strategy area
Thread part 4: the IPP programme for IPP2 Atlantis Wind — what the plant has promised, what it can still sell, and why a buyer should trust that answer.
You need to know what your plant has promised, what it can still sell, and why a buyer should trust that answer. Start from the generator: every number in this area belongs to one generator site and its physical PPAs — not a trader portfolio view.
Follow along. Seat:
ipp_2@webill.net(passwordsupersecret). Path: Generator sites → IPP2 Atlantis Wind → Strategy. You should see six tabs, left to right: Overview · Sales · Allocation · Curtailment · Plant · Dashboard. Allocation is one tab; it opens on Rules · hierarchy, with a mode switch for Forecast · next month and Outcomes · settled.
Data. full_demo · seed 42 · IPP2 Atlantis Wind · stage S03/S07 · last checked 2026-09-13.
3.1.1 Find the right generator first
- Open IPP Sites in the org navigation.
- Select IPP2 Atlantis Wind (not a trader pool, not an off-taker).
- Choose Strategy in the site navigation — the plant name stays in context as you change tabs.
The site boundary matters: its meter supplies generation, its active physical PPAs supply eligible buyers, and its hierarchy supplies the allocation rule. Mixing plants would break conservation checks later.
If you arrive from a contract register or a counterparty link, follow the generator deep-link rather than guessing from a commercial total.
3.2 Read the tabs in order
The strategy bar is six tabs, left to right. Each tab answers one question. Treat them as a walk, not a menu you skip around: size the gap, try to sell it, then prove who is served, recover a held-back hour if one happened, check what the plant is doing now, and only then read the plant’s story since it switched on.
flowchart LR
A[Overview] --> B[Sales]
B --> C[Allocation]
C --> D[Curtailment]
D --> E[Plant]
E --> F[Dashboard]
The old stand-alone HAF (Historical Availability Factor), Hierarchy, Forecast and Allocations tabs have not gone away — their screens now live inside Sales and the Allocation tab, and the old addresses still open the right place.
Think of Allocation as one folder with three sheets.
The bar shows the folder once. Inside it,
#allocation-mode-bar is the three-way switch: Rules
· hierarchy (the written order of who is served),
Forecast · next month (what that order leaves to sell),
Outcomes · settled (the receipt of a month that already
ran). Clicking Allocation always opens Rules
(…/strategy/hierarchy). Hover the tab for the same
three-line hint the product shows.
| Tab | Question it answers | What you do |
|---|---|---|
| Overview | How big is the gap, and what is it worth? | Read the gap hero (sold vs still for sale), the ranked next best actions, the unsold profile, buyers, weather and the price rail (§4) |
| Sales | Who should buy the gap, on what terms, and is that better than the market? | Work the five-step Sales Desk: the gap and its market value → who could absorb it → build the deal → profit and risk vs holding → compare and decide (§6). The TOU (time-of-use) and firm-block pricing tools and the safe capacity widget open beside the deal builder (§6.7, §6.8, §5) |
| Allocation | Who is served first, what next month leaves to sell, and what a settled month actually paid? | Stay on this one tab and switch mode. Rules · hierarchy — edit the cascade, preview a draft against the last settled month, publish an effective-dated version (§7). Forecast · next month — generation forecast → obligations tier by tier → AES (Available Energy for Sales), with P90 (nine months in ten the plant makes at least this much) (§8). Outcomes · settled — replay a settled month through the in-force hierarchy with a conservation check (§9) |
| Curtailment | Was the plant held back, and can we recover the energy that was ready? | Read drafts the ended instruction created, prepare evidence, lodge, and record payment (§10) |
| Plant | What is the plant doing now, and is the feed honest? | Read today’s measured output, register the feed, grant consent, and download traces (§11) |
| Dashboard | What is the story of this plant since it switched on? | Read six chapters: verdict, the river of money, sunlight to margin, where the money came from, where the losses came from, the health check and the next chapter (§12) |
Four ways through the area:
- Sell the gap: Overview (how big, how much it is worth) → Sales (who could absorb it, what the deal earns against holding for SAWEM — the South African Wholesale Electricity Market) → promote a draft into V7.
- Stand behind promises: Allocation (Rules, then Outcomes, then Forecast) → Dashboard health check → contracting guard (§13).
- Recover a cap: an ended System Operator cap opens a draft on Curtailment — review, lodge, record payment (§10).
- See every plant as one picture: IPP Sites → Fleet — not a sixth strategy tab. That four-chapter story is §2.
Strategy tabs IPP2
| Tab 1 | Signal 2 | Action 3 |
|---|---|---|
| Overview | Gap headline · Still for sale · Safely contractable | Take the top-ranked next best action |
| Sales | Option 0 (hold for SAWEM) · candidate fit · advantage / risk | Simulate, compare, then Build Proposal |
| Allocation | Mode bar: Rules · Forecast · Outcomes · in-force version · SELLING / FULLY SUBSCRIBED / OVERSUBSCRIBED | Publish Rules before promising a tier; read Forecast before sales calls; open Outcomes to prove last month |
| Curtailment | Draft claims from ended System Operator caps | Review, lodge, record payment |
| Plant | Fresh or stale feed · active / available MW | Open the register; do not bid the next hours on a dead feed |
| Dashboard | Net since commissioning · confidence bar | Rank the three moves for the next quarter |
- 1Tab is scoped to this generator only — six entries, Allocation once.
- 2Signal is the first number to trust on that page.
- 3Action is what a sell desk does next.
Note. Bookmarks to the retired HAF tab open Sales; the safe capacity widget is in the Sales pricing tools and its headline is also a link on the Overview gap hero. Bookmarks to Hierarchy, Forecast and Allocations open the matching Allocation mode, with that one tab marked active.
3.3 What you can change
All pages are org-scoped. Another organisation’s generator is not reachable here.
Some seats are read-only: you see the cascade, reports and traces, but Publish, Re-run and acknowledgement controls are hidden and the Rules board shows a Read-only badge. That is not a failed save — it separates commercial review from actions that version a rule or mint an auditable report. Ask a generator administrator to make the controlled change, then return to inspect the new version.
3.4 First five minutes
| Step | Screen | What to note |
|---|---|---|
| 1 | Overview | The gap headline; Still for sale and what it is worth at LCOE; the top-ranked next best action |
| 2 | Sales · step 1 | Option 0 · hold and sell on SAWEM — the baseline every deal must beat; Safely contractable next month on the price-rail card |
| 3 | Sales · steps 2–5 | Pick the top candidate, run one Simulate Sale, read the verdict against holding, then the comparison table |
| 4 | Allocation | One tab. On Rules · hierarchy: in-force version date, and whether a draft has unpublished changes. Switch to Forecast · next month: verdict pill SELLING · FULLY SUBSCRIBED · OVERSUBSCRIBED, and AES at P90. Open Outcomes · settled only if you need last month’s replay |
| 5 | Curtailment | Draft claims from ended System Operator caps, if any |
| 6 | Dashboard | The verdict sentence, the confidence bar (settled vs estimated months), and the three ranked moves |
Where this is taught. Lifecycle spine: V0 §4. Revenue-gap Overview: §4. Allocation rules: §7. Settlement consumption of the carve: V8 §6. Contracts: V7. V3 pointer chapter: V3 §14.
Previously in the thread → V3 §21 · demo walkthrough. Next in the thread → V4 §4 · Overview (then §6 · Sales · §7 · Allocation rules).
4. Overview — revenue-gap-first
Thread part 4, continued: IPP2 Atlantis Wind’s first screen — how much of the plant is still for sale, what that gap is worth, and whether what has sold pays for the whole plant.
Follow along. Seat:
ipp_2@webill.net. Path: Generator sites → IPP2 Atlantis Wind → Strategy → Overview. You should see a one-line headline over a sold / unsold bar, a ranked list of next best actions below that card, then the panel When your energy is available — and what those hours earn (#ipp-generation-story): the 24-hour unsold profile, the plant-assumptions fold, and Value of your generation hours. Under that, three small panels: Who buys what you’ve sold, Weather outlook, and Price vs cost, on one line. Explanations (#overview-explanations-open) sits on the assumptions strip — §4.8.
The IPP’s problem, in plain words
You run a plant. Every hour it makes energy; some of it has a buyer under a PPA and the rest is spilled — generated, metered, and paid for by nobody. The trap is that the numbers a plant is usually judged by hide the spill: the price on the energy that did sell can look healthy while the plant as a whole earns far below its cost.
Overview exists to keep the spill in the headline. It answers, in this order: how much of the plant is sold and how much is still for sale; what the unsold part is worth and what it earns today (always R 0); what the one next best action is; which hours the gap sits in; whether the hours you do generate have been historically cheap or dear against the market; who is buying what has sold; whether the next three days of weather will give you energy to sell at all; and whether the whole plant covers its cost. Everything on the page except the generation-hour card is built from the latest forecast run — the strategy engine’s allocation of a typical day of generation across your contracts — so it is a picture of the book as it stands, not a settled statement. The generation-hour card is a historical market-price check on the same plant; it is not this run’s contracted earnings.
What you see (top → bottom)
| Block | What it shows | Where the number comes from |
|---|---|---|
| Assumptions strip + Explanations + ⚙ LCOE / params + Run Forecast Now | The line LCOE 48 c/kWh · replacement 210 c/kWh, the A–Z drawer, the two cost dials, and the button that seals a new snapshot | Drawer §4.8; book params (§4.3); the nightly forecast run |
| Gap hero | A one-sentence headline (“Sold 4 %, unsold 96 %…”), a sold / still-for-sale bar, then two columns: Contracted (energy, buyer organisations, achieved price, revenue) and Still for sale (energy, the hours it is concentrated in, worth at LCOE, earning today, safely contractable) and the unsold-share sparkline over recent runs | Latest risk snapshot + its allocation lines; SCE from the latest FINAL monthly forecast (§5) |
| Next best actions | Up to three actions, each with the rand at stake and a link to the screen where the work is done | Derived from the snapshot: spill hours, realised vs LCOE, buyer concentration |
| Unsold profile (24h) | Contracted stacked under Unsold for a typical day, day/night wash, tomorrow’s P50 as a dashed line, an intensity strip per hour, and a fold Solar PV / Wind / … assumptions & forecast basis | Allocation lines by SAST hour; the weather-driven P50 forecast; the site plant profile (§4.2) |
| Value of your generation hours | Historical market price of the hours this plant generated, against the average market hour | Latest daily capture benchmark (#ipp-capture; §4.4) |
| Who buys what you’ve sold | Revenue share per named buyer and the Revenue HHI meter | Priced ALLOCATION lines of the latest run (#ipp-buyers;
§4.5) |
| Weather outlook | P50 generation for the next three calendar days against what is already committed | Weather-backed P50 series + ALLOCATION hours
(#ipp-weather-outlook; §4.6) |
| Price vs cost, on one line | Realised, LCOE, achieved and replacement as four marks in c/kWh | Snapshot metrics + book params (#ipp-price-rail; §4.7) |
On the site workspace these panels open the Performance tab (§3); a fold under them, Measured performance & revenue analysis, holds the timeline, revenue sources, losses, availability and forecast evidence.
Concepts and abbreviations on this screen
| Term | Meaning here |
|---|---|
| Realised | Revenue ÷ all generation — unsold hours count as 0 c. The honest headline. On the price rail it reads in c/kWh. |
| Achieved c/kWh | Average price on the energy that did sell — ignores the gap. Flattering when under-contracted. |
| Still for sale / Unsold | Generation with no buyer in the forecast run — the revenue gap, as energy and as a share. |
| Worth at LCOE | The unsold energy priced at your own cost of generation — the minimum it would need to earn to break even. |
| Concentrated in | The daytime window that holds most of the unsold energy — the shape a buyer or a bid must fit. |
| Safely contractable | Next month’s SCE for the tier a buyer would sign under — what you can promise without over-promising (§5). |
| Revenue HHI | Buyer concentration; 1.0 means one buyer takes all the revenue. The buyers panel is the picture; the meter is the number. |
| vs LCOE | Realised minus LCOE; negative means the plant under-earns. The price rail’s verdict states it in c/kWh. |
| Buyer organisations | Distinct organisations paying in the forecast run (2 · 1 dominant). One organisation can hold several contracts, so this can be smaller than the site’s contract count. |
| Generation-hour value (capture) | What the hours this plant generated were worth on the market, against the average hour. Not Bid Desk capture rate (accepted ÷ offered), and not this run’s contracted earnings. |
| P50 (generation) | The expected generation case: output met or exceeded about half the time. The conservative twin is P90. |
| Committed | Energy the latest forecast run already sold into those hours — the contracted stack, not a weather number. |
| Replacement (on the rail) | Your planning guess for buying energy in if a firm promise misses. It is a cost mark, not a sale price. The dial is §4.3. |
| Snapshot / forecast run | The sealed set of numbers a nightly (or Run Forecast Now) run produced. Overview never recomputes them. |
| Plant profile | The optional engineering recipe on the site (tilt, turbines, inflow, heat rate). The Unsold profile fold shows it; default means the engine’s technology shape is in use. |
The revenue-gap trap — achieved can look fine while realised is red
Imagine a bakery that bakes 100 loaves a day but only has customers for 60. The baker can truthfully say “I sell bread at R 65 a loaf” — that is the achieved price on the loaves that sold. But 40 loaves went to waste and earned nothing, so the bakery’s true income per loaf baked is only 0.6 × R 65 = R 39. If each loaf costs R 48 to bake (LCOE), the shop is losing money even while the sales team celebrates R 65.
A power plant works the same way. Sunshine and wind arrive whether or not you have a buyer. Celebrating the price on the sold slice while ignoring the unsold mountain is how plants quietly under-earn their LCOE.
Worked example — why “Realised” is the honest number
Data. Illustrative solar plant sized for teaching the KPI maths (same numbers the Overview cards walk). Demo walkthrough on the seeded cast: §21.
| Input | Value |
|---|---|
| Annual generation | 43,800 MWh |
| Share sold | 60% → 26,280 MWh sold · 17,520 MWh unsold |
| Achieved price on sold energy | 65 c/kWh = 650 R/MWh |
| Book LCOE | 48 c/kWh = 480 R/MWh |
Step 1 — revenue from what sold.
revenue = 26,280 MWh × 650 R/MWh = R 17,082,000
Step 2 — achieved price (what sales celebrates).
achieved = revenue ÷ sold MWh = 17,082,000 ÷ 26,280 = **650 R/MWh**
(65 c/kWh)
Unsold hours never enter this fraction — so achieved stays high even when most of the plant is idle commercially.
Step 3 — realised price (what the plant actually earns per MWh generated).
realised = revenue ÷ *all* generation = 17,082,000 ÷ 43,800 = **390 R/MWh**
Or equivalently:
realised = sold fraction × achieved = 0.6 × 650 = **390 R/MWh**.
Step 4 — compare to LCOE.
LCOE is 480 R/MWh. Realised 390 is 90 R/MWh below cost. The plant is underwater at the realised level while the sales team still quotes 65 c.
The page’s price rail (§4.7) shows the same three prices in c/kWh — realised 39 c, LCOE 48 c, achieved 65 c — because 1 c/kWh is 10 R/MWh. Its verdict reads the gap the same way: under-earns by 9 c/kWh.
Step 5 — fill the gap (even at a modest price).
Suppose you sell the remaining 17,520 MWh at a modest 55 c/kWh (= 550 R/MWh) — below your current achieved, but above zero:
extra revenue = 17,520 × 550 = R 9,636,000
new total revenue = 17,082,000 + 9,636,000 = R 26,718,000
new realised = 26,718,000 ÷ 43,800 ≈ **610 R/MWh** — now
above the 480 R/MWh LCOE.
The lesson the two cards are glued together to teach: filling unsold volume at a “worse” unit price can still rescue the plant, because realised cares about every MWh generated, not only the pretty ones.
4.1 The gap hero and the next best actions
The top of the page is one sentence and one bar. The sentence is written from the numbers — “Sold 4 %, unsold 96 % — R 5.9 m a month spilling” on a thinly contracted plant; “This plant is fully contracted” on a full book. The bar underneath shows the same split: solid green for sold, hatched amber for still for sale, with a marker at the sold share.
Two columns sit under the bar.
| Column | Rows | Read it as |
|---|---|---|
| Contracted (green rule) | energy · Buyer organisations · Achieved c/kWh · Revenue | What has found a buyer and what it earns. Achieved is the price on this energy only. |
| Still for sale (amber rule) | energy · Concentrated in · Worth at LCOE · Earning today · Safely contractable | What has not. Earning today is always R 0 — that is the point. Safely contractable links to Sales, where you choose the tier. |
Buyer organisations counts the distinct organisations paying for this plant’s energy in the forecast run, for example 2 · 1 dominant (1 · sole buyer when there is one; 1 dominant when one of several takes more than half the money). One organisation can hold several contracts, so the figure can be smaller than the site’s contract count.
Below the columns, when there are at least two forecast runs, a sparkline shows the unsold share run by run with a one-line verdict — “stable”, “shrinking” or “growing”.
Next best actions
The panel below the hero ranks up to three actions by the rand at stake and links each to the screen where the work is done:
| Trigger | Action shown | Where it sends you |
|---|---|---|
| Unsold energy in a daytime window | Find buyers for the 09h–15h spill — the window’s share of the gap and its worth | Sales (§6) |
| Realised below LCOE | Reprice or re-contract below-cost volume — c/kWh below cost | Dashboard (§12) |
| Revenue HHI high | Diversify: buyer takes 60 % of revenue | Allocation · Rules (§7) |
When none fire the panel reads Fully contracted at a healthy margin.
4.2 Unsold profile (24h) and the three small panels
The chart stacks Contracted under Unsold for each hour of a typical day, with a day/night wash so the solar window is obvious. Two period buttons switch the view:
- Typical day — the forecast run’s average day, with tomorrow’s P50 forecast drawn as a dashed line over it. Where the dashed line sits above the stack, the weather says you will have more energy to sell than the run assumed; where it sits below, less.
- Tomorrow (P50) — the weather-driven profile itself, when a forecast has been issued.
The intensity strip under the chart is the same unsold energy as one row of 24 cells, darker where more energy has no buyer. It is the shape the Sales desk scores buyers against.
Under the fold, still inside this same panel, Value of your
generation hours (#ipp-capture) asks a different
question: when this plant did generate, were those hours cheap
or dear against the market? It is history, not this run — taught in §4.4. The three small cards
under the panel — buyers, weather, price — then put a name, a weather
check, and a cost check on what the run did sell (§4.5, §4.6, §4.7).
How to read it (step by step)
- Find the tallest amber. That is the hour to sell first.
- Compare the amber to the dashed P50 line. Tall amber under a low line means the gap is partly a forecast artefact; tall amber under a high line is real, sellable energy.
- Read the Concentrated in row on the hero. If it names a daytime window, look for daytime load on Sales; if the amber is evening-heavy, a pure daytime factory will not finish the job.
- Open Solar PV / Wind / … assumptions & forecast
basis (
#ipp-plant-assumptions) and check whether the chart is using a captured profile or the engine default (below). - Read Value of your generation hours (§4.4). A high capture % with a tall amber stack means the hours are valuable but nobody has bought them yet. A low capture % with a full book means you sold into cheap hours.
- Then the three small panels: who takes the money (§4.5), whether the next three days have energy to sell (§4.6), and whether realised covers LCOE (§4.7).
Plant assumptions & forecast basis
The 24-hour chart is the plant on the road. The fold under it is the spec plate on the door — the engineering facts the forecast uses when it has no better measured series. A solar site that faces west does not spill at the same hours as one that faces north. A wind site with turbines down for maintenance is not the same plant as the nameplate on the directory card. This fold is where Overview shows that difference.
Follow along. Seat:
ipp_2@webill.net. Path: Generator sites → IPP2 Atlantis Wind → Strategy → Overview, then the panel When your energy is available — and what those hours earn. You should see a green Wind chip (#ipp-profile-technology) and a closed fold Wind assumptions & forecast basis. Click it. The card#ipp-overview-technologyopens inside the fold. On IPP1 Sandton Solar the same fold is titled Solar PV assumptions & forecast basis.
Data. full_demo · seed 42 · IPP2 Atlantis Wind · last checked 2026-09-13.
Where it lives, and what the title is
The fold sits at the bottom of the Unsold profile panel
(#ipp-generation-story), under the chart (or under the
empty “Run a forecast to see when your generation is contracted or
still for sale” line if no snapshot exists yet). The fold is closed
until you click it. Capture — Value of your generation
hours — sits under the fold, still in the same panel
(§4.4). A thermal
Dispatch economics card is not in this fold;
it is the first card on Overview and is taught in §18.5.
The summary always reads Solar PV assumptions & forecast basis, Wind assumptions & forecast basis, and so on. The name is the same as the chip next to Unsold profile (24h):
| Site technology | Chip and fold title |
|---|---|
| Solar PV | Solar PV |
| Wind | Wind |
| Hydro, run-of-river | Run-of-river hydro |
| Hydro, storage | Hydro |
| Hybrid | Hybrid |
| Diesel, gas, biomass, coal, BESS, pumped storage | The technology name with underscores turned into spaces |
flowchart TB
A[Open Unsold profile] --> B[Read the technology chip]
B --> C["Click Solar PV / Wind / Hydro assumptions & forecast basis"]
C --> D{Is a plant profile captured?}
D -->|Yes · amber pill says profile| E[Read P90/P50 and the fact tiles]
D -->|No · amber pill says default| F[Engine uses the technology default]
F --> G[Add profile on IPP Sites]
E --> H[If a fact is wrong, edit the profile. This fold does not save]
- Scroll to When your energy is available — and what those hours earn.
- Read the technology chip. That is which recipe the fold will open.
- Click Solar PV / Wind / … assumptions & forecast basis.
- Read the amber pill: profile (you captured facts) or default (the engine is using its built-in shape for that technology).
- Read P90/P50. That is how much the conservative forecast is allowed to sit below the expected one.
- Scan the tiles that shape hours (tables below). Treat pad sizes, SCADA strings and nested layout maps as the plant notebook, not as the reason the 09h bar is tall.
- If the pill says default, follow Add
profile to IPP Sites (
/org/ipp-sites/sites) and capture the facts in the wizard’s Plant profile step (V2 §4.7, §18).
What the card is for
A plant profile is the optional engineering record on the generator site: how the panels sit, how many turbines stand, how the river is meant to run, what the thermal machine costs to start. The forecast engine already has a default shape per technology (solar peaks in daylight, wind is flatter, hydro run-of-river follows the month, a thermal peaker has a dispatchable day). Capturing a profile does not rewrite a snapshot you have already sealed. It changes the input the next Run Forecast Now (and the nightly run) will use, unless a measured or nominated series already outranks it (§17, §18.2).
Think of it as writing the recipe on the tin. The bakery still has to bake (Run Forecast Now) before Overview’s 24-hour chart changes.
The chrome, word by word
| Control | Id | What it means |
|---|---|---|
| Fold summary | #ipp-plant-assumptions |
Closed by default. Click to open or close. |
| Heading | #ipp-overview-technology
h2 |
Repeats the technology name. |
| Amber pill | #ipp-overview-technology-basis |
profile = facts were captured. default = no profile, engine default. |
| Empty state | #ipp-overview-technology-missing |
Dashed box: “No plant profile — engine uses the existing technology default.” plus Add profile. |
| P90/P50 line | #ipp-overview-technology-p90 |
The ratio, then either “technology ratio capped by declared availability” or “existing default”. |
| Fact tiles | #ipp-overview-technology-{field} |
One tile per stored field. Label is the field name with underscores as spaces (for example Hub height m, Availability pct). Value, then a tag profile or missing. |
| Derived DC/AC | #ipp-overview-derived-dc-ac |
Solar only, and only when DC/AC was left blank but installed DC and inverter capacity are present. |
| Wind nameplate warning | #ipp-overview-wind-capacity-warning |
Amber: turbine count × rated MW differs from installed capacity by more than 1%. |
| Hybrid conservation | #ipp-overview-technology-conservation |
One January weekday: generation MWh, kWh clipped, and the conservation sentence. |
A tile whose value was never supplied shows Not supplied and the missing tag. That is honest emptiness, not a failed load. Nested maps (layout blobs) may print as a technical list — they are stored engineering, not something you edit in this fold.
This fold is read-only. There is no Save here. Changing a fact means editing the site on IPP Sites, then running a new forecast if you need the 24-hour chart to move.
P90 / P50 on this card
P50 / P90 here is a generation grade, not a market-price band. P50 is the middle case: in half of similar months the plant makes at least this much. P90 is the conservative case: nine times in ten it makes at least this much, so P90 sits below P50. The card prints their ratio (P90 ÷ P50). A ratio of 0.86 means the conservative forecast is 86 % of the expected one.
When no profile is captured, the engine uses a technology default:
| Technology | Default P90/P50 |
|---|---|
| Solar PV | 0.94 |
| Wind | 0.86 |
| Hydro (run-of-river) | 0.90 |
| Hydro (storage) | 0.95 |
| Hybrid | 0.92 |
| Diesel | 0.97 |
| Biomass | 0.92 |
| Battery (BESS) / pumped storage | 1.00 |
When a profile is captured and it carries Availability pct, the ratio is the lower of that default and availability ÷ 100. Example: wind default 0.86, availability 97 % → still 0.86. Wind availability 80 % → 0.80. Declared availability can only tighten the conservative case; it cannot loosen it past the technology default.
A live weather model that already supplies its own P90/P50 spread wins over this ratio (§17.3).
Tiles that shape the hours (by technology)
Open the fold on the technology you actually run. The chip tells you which table to use. Capture and validation of these fields is V2 §4.7 and §18; this page only teaches how to read them.
Solar PV
| Tile you will see | In plain words |
|---|---|
| Tracking | FIXED — panels stay put. SINGLE_AXIS — rows tilt through the day. DUAL_AXIS — tables follow the sun two ways. |
| Tilt deg | How steep the panels sit: 0 is flat, 90 is upright. |
| Azimuth deg | Which way they face. 0 is north in the southern-hemisphere convention used here. |
| Soiling loss pct | Energy lost to dust on the glass. |
| Annual degradation pct | How much the panels lose each year as they age. |
| Dc ac ratio | How much panel DC capacity sits in front of the inverters. Higher than 1.0 is common. If this tile is missing, the derived line below may still show DC/AC from installed DC ÷ inverter capacity. |
| Bifacial? | Whether the back of the panel also makes power. |
| Module technology | The panel type (for example mono PERC). |
Wind
| Tile you will see | In plain words |
|---|---|
| Turbine count | How many turbines stand on this site. |
| Rated mw per turbine | Nameplate megawatts of one machine. |
| Hub height m | How high the rotor centre sits above the ground — the height the wind-speed forecast is converted to (§17.2). |
| Rotor diameter m | The circle the blades sweep, edge to edge. |
| Availability pct | The share of time the machines are expected to be able to run. Caps P90/P50 when it is tighter than 0.86. |
| Turbine model / Iec class | Manufacturer model and the wind-class the turbines are certified for. |
| Cut in / rated / cut out speed ms | The wind speeds at which the turbine starts, reaches nameplate, and shuts down. |
If turbine count × rated MW is more than 1 % away from the site’s installed capacity, the amber warning appears. That is a data-quality check, not a forecast rewrite. Review the engineering data on IPP Sites.
Hydro (including run-of-river and pumped storage)
| Tile you will see | In plain words |
|---|---|
| Kind | RUN_OF_RIVER — output follows the river. STORAGE — a dam holds water so you can choose when to generate. |
| Inflow shape | Twelve monthly factors, January to December, that say how much water arrives through the year. |
| Max mwh per day / week | A cap on energy the plant is allowed or able to make. |
| Baseload? | Whether the plant is meant to run as a flat background machine (flat 24-hour shape) instead of a hydro peaking shape. |
| Design head m / design flow | The drop and the flow the turbines were built for. |
| Storage energy / pump capacity / cycle efficiency | Pumped-storage only: how much the reservoir holds, how hard it can pump, and what share of pumping energy you get back. |
Thermal (diesel, gas, biomass, coal)
| Tile you will see | In plain words |
|---|---|
| Fuel / Cycle | What it burns and which thermal cycle it is. |
| Heat rate gj per mwh | How much fuel energy it takes to make 1 MWh. |
| Availability pct | As for wind — can tighten P90/P50. |
| Variable om r per mwh and start costs | What it costs to run and to start (hot ≤ warm ≤ cold). |
| Baseload? | A tick here gives a flat 24-hour shape instead of the peaker-style day. |
| Min run / down time, ramp, min stable load | How fast and how long the machine can move. |
Hybrid
| Tile you will see | In plain words |
|---|---|
| Solar site id / Wind site id | Which same-organisation plants this composite is built from. |
| Bess asset id | Optional battery on the same organisation. |
| Export cap mw | The shared clip at the gate. |
| Dispatch policy | How the default representative day moves energy (by default, shift available energy toward the evening inside battery limits). |
The conservation line under a hybrid card is one January weekday: source energy minus storage losses and clipping should equal the generation shown. §18.3 owns that model.
What this fold does not do
| Misconception | Reality |
|---|---|
| “Opening the fold rebuilds the 24-hour chart” | No. It only shows the recipe. Run Forecast Now seals a new snapshot. |
| “I can edit tilt or hub height here” | No. The fold is read-only. Edit the site, then re-run. |
| “default means the page is broken” | No. It means nobody captured a profile yet; the technology shape still runs. |
| “P90/P50 on this card is a market price” | No. It is a generation grade. Price P10/P50/P90 lives on the Bid Desk. |
| “Every tile changes tomorrow’s P50 line” | Pad sizes, SCADA text and nested layout maps are evidence. Hours come from the shape, availability, weather conversion and measured series. |
| “Capture (the card below) is the same as this fold” | Capture is the price your hours earned against the average market hour (§4.4). This fold is the physical recipe. |
Worked walk — IPP2 Atlantis Wind
On the seeded wind site the chip reads Wind. Opening
the fold shows Wind assumptions & forecast basis.
The P90/P50 line uses the wind default 0.86 unless a
captured availability is tighter than 86 %. If the site has no
wind_profile yet, the dashed empty state appears and the
pill says default — the 24-hour stack still draws, from
the engine’s wind shape, not from a blank chart.
That is the pattern on your own plant: chip names the recipe, the fold shows whether you wrote it down, and missing tiles tell you which facts are still a guess.
Where this is taught. Filling and validating the profile: V2 §4.7 and V4 §18. How weather turns irradiance or hub height into megawatt-hours: §17. How to read the capture card under this fold: §4.4. The cannibalisation maths: §19.
4.3 LCOE & params
This is the IPP’s cost dial on Overview: two numbers that say what the plant costs to produce and what it would cost to buy energy if you promised firm hours the plant could not make. Everything else on the page — Realised, Unsold, the 24h profile — is about what happened. These two dials are about what “good” means.
Where it lives. Top of Overview, next to Run
Forecast Now: an assumptions strip shows the current values,
and ⚙ LCOE / params opens the modal titled
“LCOE & assumptions”
(#ipp-params-modal).
Short steps — open, edit, save
- On Overview, read the strip: LCOE … c/kWh · replacement … c/kWh (seed defaults: LCOE 48 c/kWh · replacement 210 c/kWh).
- Click ⚙ LCOE / params (cog). The modal LCOE & assumptions opens.
- Edit one or both number fields (step 0.1). Leave a field alone if you only need to change the other.
- Click Save to write the book, or Cancel / the × close control to discard. Success flash: “Assumptions updated.” Failure flash: “Could not update assumptions.”
- Re-read the strip and the price rail (realised vs LCOE). Press Run Forecast Now only when the sealed snapshot (Realised, Unsold %, profile) itself must rebuild — not merely because you moved the LCOE yardstick.
Save vs Run Forecast Now
| Step | What you do | What the product does |
|---|---|---|
| Open | Click ⚙ LCOE / params | Shows modal with current
lcoe_ckwh and replacement_ckwh |
| Edit | Change one or both numbers | Local form only until Save |
| Save | Click Save | Writes book params; flash “Assumptions updated.”; closes modal; reloads Overview from the existing snapshot + new params |
| Cancel / × | Close without Save | No write |
| Run Forecast Now | Click the primary button | Seals a new risk snapshot (Realised, Unsold, HHI, profile, …) |
Rule of thumb. Save = store the cost dials (strip, vs LCOE, and the “below LCOE” next-best prompt update immediately). Run Forecast Now = rebuild how much energy sold / earned — needed after membership or contract changes, not after an LCOE-only edit.
Each field in detail
The modal exposes exactly two fields (plus Cancel /
Save). Seeded defaults come from the IPP book seed
(WB.Strategy.Book.SeedIpp):
LCOE (c/kWh)
| UI label | LCOE (c/kWh) |
| Book key | lcoe_ckwh |
| Unit | Cents per kilowatt-hour (input step 0.1) |
| Default | 48.0 (= 480 R/MWh via × 10) |
| What it means | Your plant’s levelised cost of energy — the all-in long-run cost to produce 1 kWh (capex, connection, O&M, finance), averaged over the plant’s life. It is the floor Overview uses when asking “did the whole plant earn enough?” |
| Where it shows | Assumptions strip (“LCOE 48
c/kWh”); vs LCOE card (= Realised R/MWh −
lcoe_ckwh × 10); Next best actions when Realised < that
R/MWh yardstick |
| What it changes on Save | Strip value; vs LCOE
magnitude and rose tone when negative; the “Realised price is below
LCOE” next-best prompt. Sales also reads it as a default
energy-price suggestion when you open a sale
(nonzero_or(65.0) if the stored value is zero) |
| What it does not change | Sealed Realised / Achieved / Unsold % / Revenue HHI / the 24h profile (those stay on the snapshot until Run Forecast Now). Contract prices already signed. Replacement-cost maths on Firm viability |
Plain picture. Think of LCOE as the bakery’s cost per loaf. Changing it does not bake more loaves or find more customers — it only changes whether the shop’s average income looks above or below cost.
Replacement cost (c/kWh)
| UI label | Replacement cost (c/kWh) |
| Book key | replacement_ckwh |
| Unit | Cents per kilowatt-hour (input step 0.1) |
| Default | 210.0 |
| What it means | What you assume it costs to buy market energy if you promised firm delivery in named hours and the plant could not generate. The downside price in “should I sign this firm block?” |
| Where it shows | Assumptions strip (“replacement
210 c/kWh”). Not used by Overview’s
realised-vs-LCOE comparison. Consumed on Firm viability
(§6.8) and the Sales firm-block check:
expected margin = price − replacement × P(short) |
| What it changes on Save | Strip value immediately; later Firm / Sales firm checks read the new number. Overview Realised / vs LCOE / Unsold stay untouched |
| What it does not change | Whether you are above or below LCOE; the unsold profile; buyer concentration |
Plain picture. If you promise a factory evening power and the sun has set, someone still has to supply those kWh. Replacement cost is your planning guess for that buy-in price — often much higher than LCOE, because market / top-up energy is dearer than your own plant’s long-run cost.
| Param | Seed default | R/MWh equivalent | Overview uses it? | Firm / Sales uses it? |
|---|---|---|---|---|
LCOE
(lcoe_ckwh) |
48.0 c/kWh | 480 R/MWh | Yes — vs LCOE + NBA | Sales default offer price hint |
Replacement
(replacement_ckwh) |
210.0 c/kWh | 2,100 R/MWh | Strip only | Firm viability + Sales firm-block check |
Why change either dial (or both)
| Scenario | Change | Example | Why |
|---|---|---|---|
| Finance refreshed the plant’s true LCOE | Set LCOE to their figure | 48 → 52 | vs LCOE and the “below LCOE” prompt must match the board pack, not the seed demo number |
| Stress-test: “what if cost is higher?” | Raise LCOE | 48 → 55 | vs LCOE goes more negative sooner — shows how thin the margin is |
| Softer cost story for a low-capex site | Lower LCOE | 48 → 40 | Same Realised can flip from rose to healthy — document that you moved the yardstick |
| Firm evening offer looks too cheap / too dear | Change replacement | 210 → 180 or 250 | Firm expected margin = price − replacement × P(short) — higher replacement makes decline more likely |
| Board pack on firm risk only | Replacement only | — | Overview KPIs unchanged; Firm tab / Sales firm check use the new downside |
| Full plant economics + firm story | Change both | LCOE 50 · replacement 230 | Cost floor and firm buy-in price stay consistent with the same pack |
| Exploring only | Edit · Save | — | Strip + vs LCOE update without waiting on a forecast rebuild |
What LCOE / params do NOT change (limits / misconceptions)
| Misconception | Reality |
|---|---|
| “Save rewrites Realised / Unsold instantly” | Those metrics live on the snapshot. Save only changes the LCOE comparison (and the strip). Rebuild with Run Forecast Now when generation / contracts changed |
| “Replacement turns the vs LCOE comparison” | No — vs LCOE uses LCOE
only (Realised − lcoe_ckwh × 10) |
| “This modal edits PPA prices” | No — signed contract c/kWh stay on the deals; these are planning dials on the book |
| “I must re-run forecast after every LCOE tweak” | Only if you also need a fresh sealed snapshot; LCOE-only → Save is enough for Overview’s yardstick |
| “Defaults are universal industry truth” | Seed defaults (48 / 210) are the product’s starting point for new IPP books — replace with your plant’s figures |
| “LCOE and replacement are the same kind of cost” | LCOE = long-run own production cost. Replacement = buy-in cost when firm promises miss. Different jobs, different magnitudes |
Worked micro-example — moving LCOE only
Suppose the sealed snapshot still shows Realised 390 R/MWh (same plant as the §3 worked example) and the strip still shows seed LCOE 48 c/kWh:
| Book LCOE | Yardstick (× 10) | vs LCOE | Next-best LCOE prompt? |
|---|---|---|---|
| 48.0 (default) | 480 R/MWh | 390 − 480 = −90 (rose) | Yes — “below LCOE” |
| 35.0 (you Save) | 350 R/MWh | 390 − 350 = +40 | No (for this trigger) |
| 55.0 (you Save) | 550 R/MWh | 390 − 550 = −160 (rose) | Yes |
Realised stayed 390 the whole time — only the yardstick moved. That is why Overview treats LCOE as a dial, not as generation data.
Follow along. Seat: an IPP operator on the demo cast (e.g. open Strategy from an eligible row on IPP Sites). Path: Overview. You should see the sold / unsold bar, Achieved in the Contracted column, Unsold on the Still for sale side, and realised vs LCOE on the price rail. Open ⚙ LCOE / params — both fields should show the seed defaults (48.0 / 210.0) until someone saved different values. Compare with a trader pool Overview (V3 §3) — traders lead with margin; IPPs lead with the revenue gap. Off-taker ⚙ Assumptions is the buyer twin (escalation % · spill credit) — V3 §13.1.5.
Data. full_demo · seed 42 · stage S09 (settlement matrix) · last re-derived 2026-07-18 against the full_demo manifest. Extreme gap numbers on a thinly contracted demo plant are walked in §21.
Safe contractable headroom (AES / SCE / HAF band) shows on the gap hero’s Safely contractable row and in full on Sales — §5.
The Unsold profile fold Solar PV / Wind / … assumptions & forecast basis is taught in §4.2. How to capture those facts, and thermal Dispatch economics, stay in §18.
4.3 The Capture card
How to read Value of your generation hours on Overview is taught in §4.4. The cannibalisation maths, floor-hour policy and market-indexed vPPA comparators stay in §19.
This heading is kept so older links still land. Do not treat it as a second card.
4.4 Value of your generation hours
The 24-hour chart says when the plant makes energy. This
card, still inside When your energy is available — and what
those hours earn, asks what those hours were worth on the
market. Title: Value of your generation hours.
Subtitle on the right: Capture · daily benchmark (D1).
DOM id #ipp-capture.
Think of a fruit stall that only opens at noon, when every other stall is also open. Noon fruit is cheap because the street is flooded. A stall that is open at dawn, when almost nobody else has fruit, earns more per box even if it sells the same number of boxes. This card is that comparison for a power plant: did your generation coincide with cheap hours or dear ones?
It is not what your PPAs paid you. It is not the forecast value of unsold energy on the gap hero. The intro on the card says so: Historical market value of your generation hours, not contracted earnings or the forecast value of your unsold energy.
It is also not Bid Desk capture rate (accepted ÷ offered volume). Same English word, different job. Here capture means: the price your generation hours earned, as a share of the average market hour. The glossary name is generation-hour value.
flowchart TB
A[Hours the plant generated] --> C[Your generation hours R/MWh]
B[Every market hour that day] --> D[Market average R/MWh]
C --> E[Capture % = yours ÷ average]
D --> E
E --> F[Below 100%: you generated in cheaper hours]
E --> G[At or above 100%: you generated in dearer hours]
What you see, line by line
| On the card | What it is |
|---|---|
| Summary sentence | Your generation hours captured X% of the average market price in the latest daily benchmark. X is the capture percentage, two decimal places. |
Sparkline
(#ipp-capture-trend) |
Daily capture % over the last 30 daily (D1) observations, oldest on the left. Drawn only when at least two observations exist. |
Help line
(#ipp-capture-desc) |
Your hours’ price against the average hour’s price. Below 100 means your generation coincides with cheaper hours. |
| Your generation hours | Captured price, R /MWh — the volume-weighted market price in the hours this plant generated. |
| Market average | Baseload price, R /MWh — what a flat generator (equal MWh every hour) would have earned on the same days. |
Benchmark date
(#ipp-capture-date) |
The calendar day of this daily row. |
| Coverage line | N of M days — how many days
in the window had both a price and a volume — then the
floor-hour rule used for this row (see below). |
How to read the percentage
Capture 100% means your hours were worth the same as the average hour. 84% means they were worth about sixteen percent less — the plant generated when the market was cheap. 110% means the plant generated when the market was dear.
The bakery picture in §3 still holds, but it answers a different question. Realised asks “did the whole plant earn its cost, counting unsold hours as R 0?” Capture asks “when it did generate, were those hours the cheap ones?” You can be fully contracted (realised healthy) and still capture poorly, if the contracts sit in a glut. You can capture well and still spill, if nobody has bought the dear hours yet.
Data. The numbers below are the same mock summer / winter pair §19 uses, so the card and the maths chapter agree. A measured estate can differ.
| Season (illustrative solar day) | Your hours | Market average | Capture % |
|---|---|---|---|
| Summer | R 721.10/MWh | R 859.17/MWh | 83.93% |
| Winter | R 923.12/MWh | R 934.17/MWh | 98.82% |
Summer solar is the glut case: many plants make power together, those hours cheapen, capture falls. Winter is closer to the average hour.
Empty states and pills
| What you see | What it means | What to do |
|---|---|---|
| No capture benchmark yet — the first is built the morning after the first published price. | No daily row exists for this site. | Wait for the first published market price (the morning after). Overview will not invent a number. |
| Capture rate unavailable for this benchmark. The available prices and date are shown below. | A row exists but the percentage could not be formed. Prices and the date are still shown. | Read R/MWh and the date; do not treat “—” as 0%. |
| stale · as of date | Today is more than 2 days
after the benchmark date (the policy’s stale_after_days,
default 2). |
Do not steer a sale on it. The date is on the pill. |
| profile-based · low confidence | The volume used a typical-day profile, not hourly metered generation. | Treat the % as a shape check, not a measured result. |
| demo market price | The price series is the internal demo
market (INTERNAL_MARKET), not a live SAWEM series. |
Fine on the demo cast. On a live book, this pill means you are still on the demo series. |
The pills can appear together. A published demo price does not turn a profile into metered generation.
Floor hours
Some hours the market price sits on a floor — the lowest the rules allow. The coverage line names how this row treated them:
| Line you will see | What it did |
|---|---|
| floor-hour energy counts; revenue is zero | Those kWh stay in the volume (they pull the average down) and contribute R 0. The default. |
| floor hours excluded from pricing | Those hours are dropped from both the price and the energy sides. |
Changing the convention changes the answer. Old rows keep the convention they were built with.
Where this is taught. How to read this card: this section. The cannibalisation maths, floor-hour policy, market-indexed vPPA comparators and the technology strip: §19. The same card title Capture (not embedded) also appears on Sales and the Dashboard; the numbers are the same daily benchmark.
4.5 Who buys what you’ve sold
Three small cards sit under the generation-story panel, in this
order: buyers, weather, price. The first is Who buys what you’ve
sold (#ipp-buyers). Intro
(#ipp-buyers-intro): Revenue share by buyer over the
forecast run — the basis of the revenue HHI.
If you sold 100 loaves and 80 of them went to one café, you do not have three customers in any useful sense — you have one customer and two hobbies. This panel is that picture for the plant: who takes the money from what the latest run already sold, and how concentrated that money is.
It only counts priced ALLOCATION lines — energy that found a buyer at a sale price. Spill (unsold) is not a buyer. A line with no sale price does not appear.
flowchart TB
A[Priced ALLOCATION lines in the latest run] --> B[Group by destination membership]
B --> C[Name: PPA other side, else pool, else Unnamed buyer]
C --> D[Sum rand, largest first]
D --> E[Bar per name + share % + R]
A --> F[Snapshot Revenue HHI]
F --> G[Meter 0 to 1.0]
Each row
When there are priced sales, each row is:
| Piece | What it is |
|---|---|
| Name | The organisation on the other side of the physical or virtual PPA. If that is missing, the destination pool name. If that is missing too, Unnamed buyer. |
| Share | That name’s rand as a percentage of all priced sales in the run, whole percent. |
| Rand | The same revenue, shortened:
R 35 / R 450 k / R 5.9 m. |
| Bar | The same share as a width. The largest buyer’s bar is brand green; the others are slate. |
Rows are largest first. Two memberships that resolve to the same organisation name are added together on the bars.
Empty state: No priced sales in the latest run yet. The plant may still be generating — those hours are unsold, so they have no buyer to name.
The HHI meter
Under the bars: HHI as a two-decimal number, a green → amber → rose bar from 0 to 1.0, a tick at the current value, and the legend 1.0 = one buyer.
HHI (Herfindahl–Hirschman Index) here is Revenue HHI: the sum of each buyer’s squared share of revenue. It lives on the latest risk snapshot. Overview does not recompute it from the bars; the bars and the meter both start from the same run.
| Book | Shares | HHI | Read it as |
|---|---|---|---|
| One buyer | 100% | 1.00 | Sole buyer. The tick sits at the rose end. |
| Two equal buyers | 50% + 50% | 0.50² + 0.50² = 0.50 | Diversified into two. The diversify action does not fire (the trigger is above 0.50). |
| One dominant | 70% + 30% | 0.70² + 0.30² = 0.58 | One name takes most of the money. Next best actions may show Diversify. |
| Three equal | ~33% each | ≈ 0.33 | Comfortably spread. |
The meter is the same number as the old Revenue HHI KPI. Next best actions fire Diversify: buyer takes … of revenue when HHI is greater than 0.5, and send you to Allocation · Rules (§7).
Careful. The bars name organisations (memberships with the same display name are merged). The meter counts destination memberships in the snapshot. If two memberships of the same buyer keep different names — one a pool, one an organisation — the bars can look more concentrated than the meter, or the other way round. Believe the names for “who”, and the meter for “how concentrated the snapshot thinks you are”.
Worked walk — two buyers
Suppose the latest run sold R 1,000,000 of priced energy: OffTaker C Midrand DC takes R 700,000 (70%), a second buyer takes R 300,000 (30%).
- The first row is OffTaker C, 70% · R 700 k, green bar.
- The second row is the other name, 30% · R 300 k, slate bar.
- HHI = 0.70² + 0.30² = 0.58. The tick sits just past halfway, into the amber.
- Because 0.58 > 0.5, next best actions include diversify.
That is the pattern on your own plant: largest name, then the rest, then whether the meter has crossed one-half.
Where this is taught. Reading this panel: this section. The lifetime sources ledger on the Dashboard (every physical PPA since commissioning, plus RECs and SAWEM with their zeros): §12.4. How allocation decides which membership is filled: §7. Fleet-wide counterparty exposure: §2.
4.6 Weather outlook
The middle small card is Weather outlook
(#ipp-weather-outlook). Intro
(#ipp-weather-outlook-intro): Will there be energy to
sell? P50 generation for the next three days against what is already
committed.
The 24-hour unsold chart is a typical day. This card is the next three calendar days of weather-backed generation. A windless Tuesday does not care that your typical Tuesday is windy. If tomorrow’s P50 sits under what you have already sold into those hours, you have nothing extra to offer — and you may be short against the book.
P50 here is a generation grade: the expected case, output met or exceeded about half the time. It is not a market-price P50 from the Bid Desk.
flowchart TB
A[Weather feed for this site] --> B[P50 MODEL series]
B --> C[Tomorrow tile]
B --> D[Next weekday tile]
B --> E[Day after that]
F[ALLOCATION kWh in the latest run] --> G[Committed on each tile]
C --> H[Compare P50 to committed]
D --> H
E --> H
H --> I[Amber if this day is under 80% of the best of the three]
Grade, freshness, skill
Above the tiles, when a series exists:
| Chip or line | What it is telling you |
|---|---|
| ● P50 series · fresh | The active model series is the expected (P50) grade, and the newest issue is still inside that provider’s freshness window. |
| ● P50 series plus Stale forecast | The same series, but the newest issue is older than the freshness window (or there is no issue at all). Do not plan a sale as if this were this morning’s weather. |
Skill line
(#ipp-weather-skill) |
How well past day-ahead P50s matched what the plant actually made, then where the P90 band came from. |
The skill half of that line:
| Text | Meaning |
|---|---|
| no scorecard | No paired forecast-versus-actual row yet. |
| no paired observations | A scorecard row exists but it has zero hours. |
| nMAE x% · P90 coverage y% · N hours | A real scorecard. |
nMAE (normalised mean absolute error) is “how far off, as a share of typical output”. Smaller is better. P90 coverage is the share of hours where actual generation was at or above the conservative P90. If the P90 is well built, that share sits near 90%. N hours is how many hours went into those two scores.
After the middle dot, the P90 origin, in words:
| Origin | In plain words |
|---|---|
| P90 from provider spread | The weather feed itself published a range of outcomes. That spread wins. |
| P90 from technology ratio | No provider spread. The engine scaled P50 by the same P90/P50 ratio the plant-assumptions fold shows (wind default 0.86, solar 0.94, and so on). |
Overview and the Dashboard print the same English labels.
The three tiles
The card always looks three days ahead from now (not including today). Empty days — no weather-backed model points for that calendar date — are dropped, so you may see fewer than three tiles. A day the provider has only partly issued keeps its tile but no total: the forecast horizon (72 hours by default) often ends a few night hours into the last day, and that day shows — with Forecast not issued yet · 2 of 24 hours in rather than a 0 kWh that would read like a dark day.
| Piece | What it is |
|---|---|
| Label | First tile: Tomorrow. The next two: weekday name (Mon, Tue, …). |
| Big number | That day’s P50 generation, summed across hours. Units step: kWh, then MWh from 1,000 kWh, then GWh from 1,000,000 kWh. |
| Note | The committed energy, then the word
committed — energy the latest run already allocated
(sold) into those hours. Example: 4.0 MWh committed. |
| Amber card | This day’s P50 is under 80% of the best of the three tiles. The note becomes Lower output · then the same committed figure. Only fully issued days count towards the best, and a partly issued day is never amber. |
| Partly issued day | — and Forecast not issued yet · N of 24 hours in. It has no P50 total yet; it fills in when the provider issues the rest of the day. |
A day that is merely lower than committed is not automatically amber. Amber is relative to the other two outlook days: a still week with one calmer day flags that calmer day. Compare the big P50 to the committed line yourself: if committed is larger than P50, the book is selling more than this weather now says the plant will make.
Careful. The 24-hour chart’s contracted stack is a typical day from the run. The outlook tiles are calendar weather. If the run’s hours do not fall on tomorrow’s clock, committed on a tile can be small or a dash of kWh even while the typical-day chart is fully stacked. Believe the chart for the shape of the book; believe the tiles for whether the next three days have wind or sun.
Empty state (#ipp-weather-no-forecast): No
weather forecast for this site yet — run a forecast to fetch
one. Press Run Forecast Now on Overview, or
wait for the nightly run. The card will not draw three zeroes and call
them a forecast.
Footer: Weather data by Open-Meteo.com (CC BY 4.0) — the attribution the live default provider requires, shown whether tiles are present or not. The demo estate uses a mock that never opens a socket; the sentence still names the licensed source the live adapter uses.
Worked walk — one quiet day
Suppose the three P50s are 12.0 MWh, 5.0 MWh, 11.0 MWh, and each day has 4.0 MWh already committed.
- Best of the three is 12.0. Eighty percent of that is 9.6.
- Tomorrow (12.0) and the third day (11.0) stay ordinary.
- The middle day (5.0) is under 9.6, so it goes amber with Lower output · 4.0 MWh committed.
- 5.0 is still above 4.0 committed, so there is a little extra to sell even on the quiet day — just much less than on the other two.
If that quiet day’s P50 had been 3.0 MWh against 4.0 committed, you would be short against the book on that calendar day, whatever the typical-day chart says.
Where this is taught. How irradiance or hub-height wind becomes megawatt-hours, P50/P90 grades, issued-at versus fetched-at, and live versus mock providers: §17. Weather as a platform object: V0 §11. The same panel assembler also feeds the Dashboard weather card.
4.7 Price vs cost, on one line
The right-hand small card is Price vs cost, on one
line (#ipp-price-rail). Intro
(#ipp-price-rail-intro): Realised counts unsold hours
at 0 c — that is why it sits so far below what buyers actually pay. All
prices in c/kWh.
Four prices, one ruler, all in c/kWh — the same unit as the assumptions strip and the LCOE modal. Each mark prints its value in bold — for example 3.5 c, 48 c, 85 c or 210 c — with its name (realised, LCOE, achieved, replacement) next to it. The bakery from the top of the chapter is this picture: the price on the loaves that sold, the cost to bake, the true income per loaf baked, and what it would cost to buy bread in if you had promised a café a delivery you could not bake.
| Mark | What it is | Colour on the rail |
|---|---|---|
| realised | Revenue ÷ all generation. Unsold hours count as 0 c. Always shown, even when it is 0 c. | Rose when it sits below LCOE; otherwise slate. |
| LCOE | Your book’s levelised cost (lcoe_ckwh). The
yardstick. |
Slate. |
| achieved | Average price on energy that did sell
(effective_price_ckwh). |
Green when it is at or above LCOE; rose when even the sold slice is below cost. |
| replacement | Your firm buy-in guess (replacement cost). Shown only when it is greater than zero. | Slate. |
Marks with a zero value are omitted, except realised. They are sorted left-to-right by size. Labels alternate above and below the rail so they do not sit on top of each other, and the labels nearest either end read inwards so they stay inside the card. The rail’s right-hand end is the largest mark — so replacement (seed 210 c) often sits far right and bunches realised, LCOE and achieved on the left. That is scale, not a statement that replacement is a sale price.
flowchart LR
A[Realised] --> D[Verdict]
B[LCOE] --> D
C[Achieved] --> D
E[Replacement] --> F[Scale only on this rail]
D --> G[Plant covers its cost?]
D --> H[Sold energy above LCOE?]
D --> I[Unsold the main leak?]
The verdict sentence
Under the rail, one or two sentences (price_verdict),
also in c/kWh:
First sentence — the sold slice.
| Condition | Sentence |
|---|---|
| Achieved is 0 c | No priced sales yet. |
| Achieved ≥ LCOE | Energy that sells earns N× LCOE. (N is achieved ÷ LCOE, one decimal.) |
| Achieved < LCOE | Even the energy that sells earns below LCOE. |
Second sentence — the whole plant. The wording depends on realised versus LCOE and how large the gap is:
| Condition | Sentence |
|---|---|
| Realised ≥ LCOE | The plant covers its cost. |
| Realised < LCOE and unsold > 20% | The plant under-earns by X c/kWh mainly because P% of it earns nothing. |
| Realised < LCOE, unsold ≤ 20% | The plant under-earns by X c/kWh. |
X is LCOE minus realised in c/kWh, to one decimal (a whole number drops the decimal). P is the unsold share. A thinly sold demo plant reads, for example, Energy that sells earns 1.8× LCOE. The plant under-earns by 44.5 c/kWh mainly because 96% of it earns nothing. That second sentence is the revenue-gap trap from the top of the chapter, in one line.
Worked walk — the same 43,800 MWh plant
Using the chapter’s worked plant (60% sold at 65 c, LCOE 48 c, replacement 210 c):
| Mark | On the rail | Same price in R/MWh (the arithmetic above) |
|---|---|---|
| realised | 39 c (rose, below LCOE) | 390 |
| LCOE | 48 c | 480 |
| achieved | 65 c (green, above LCOE) | 650 |
| replacement | 210 c | 2,100 |
The rail runs to 210 c, so 39 / 48 / 65 sit in the left third. Verdict:
- 65 ÷ 48 ≈ 1.4, so Energy that sells earns 1.4× LCOE.
- Unsold is 40% (> 20%), and
48 − 39 = 9, so The plant under-earns by 9 c/kWh mainly because 40% of it earns nothing.
That is exactly Steps 3–4 at the top of this chapter, drawn.
Saving a new LCOE in ⚙ LCOE / params moves the LCOE mark and rewrites the verdict without a new forecast run. Realised and achieved stay put until Run Forecast Now. Replacement on this rail is the same dial; Overview’s realised-versus-LCOE comparison does not use it — Firm viability does (§4.3, §6.8).
What this rail is not
| Misconception | Reality |
|---|---|
| “The marks are R/MWh” | They are c/kWh, like the assumptions strip and the Reprice or re-contract below-cost volume next best action (§4.1), which reads Realised 39 c/kWh vs LCOE 48 c/kWh. Only the capture benchmark (§4.4) still states R/MWh. |
| “Replacement is what buyers pay” | It is what you assume it costs to buy energy in for a missed firm hour. |
| “Moving LCOE changes realised” | Only the yardstick moves. The snapshot still holds realised. |
| “This is the capture card” | Capture (#ipp-capture) is historical market
value of generation hours. This rail is this run’s realised /
achieved against your cost dials. |
The five snapshot figures that used to sit as cards under a fold — Realised, Achieved, Unsold, Revenue HHI, vs LCOE — are the same numbers already on this page: unsold on the gap hero, achieved in the Contracted column, HHI on the buyers meter, realised / LCOE / achieved on this rail.
4.8 Explanations sidebar
Every abbreviation on this Overview also lives in a right-hand drawer so you do not have to leave the page to look a letter-cluster up.
Explanations
(#overview-explanations-open) sits on the assumptions
strip, to the left of ⚙ LCOE / params and Run
Forecast Now. It does not start a forecast and it does not open
the assumptions modal.
Think of it as the card catalogue for this one screen: press the button, find the word, close the drawer, keep working.
flowchart LR
A[Press Explanations] --> B[Right-hand drawer]
B --> C[Scroll A–Z]
C --> D[Close X / backdrop / Escape]
D --> E[Overview as you left it]
The drawer is the same chrome as Allocation
Explanations and the site-card drawer on Generator
Sites: it opens on the right, branded green header,
title Explanations, X top-right.
Eyebrow: Generator Overview. Close: header X
(#overview-explanations-drawer-close), the dimmed backdrop,
or Escape.
The body is one alphabetic list (leading “The” ignored, case-insensitive). First term Achieved, last Worth at LCOE. Each abbreviation is spelled out on first use in its own row — AES (Available Energy for Sales), HAF (Historical Availability Factor), LCOE (Levelised Cost of Energy), SCE (Safe Contractable Energy), SAST (South African Standard Time). The OffTaker Overview uses the same button and drawer with a different list (V5 §4.11).
The list also carries the words this tab borrows from its neighbours:
ARF
(Allocation Reliability Factor) — the share of a buyer’s
demand actually met, shown on each Allocation member card; Buyer
organisations — distinct organisations paying in the forecast
run, which can be fewer than the contracts; and VaR 95 (Value at Risk) —
the fleet dashboard’s risk estimate. The tier word is
Pro-rata, spelt as the Allocation tab spells it (never
PRO_RATA): Safely contractable quotes next month as a
Pro-rata buyer. R/MWh says 10 R/MWh is 1 c/kWh,
and that the capture benchmark reads in R/MWh while the price rail, the
Reprice or re-contract next best action and the tab’s other
prices are c/kWh. Realised says unsold hours count as 0
c.
Spot-check ids:
#overview-explanations-term-aes-available-energy-for-sales,
#overview-explanations-term-lcoe-levelised-cost-of-energy,
#overview-explanations-term-sce-safe-contractable-energy,
#overview-explanations-term-arf-allocation-reliability-factor,
#overview-explanations-term-buyer-organisations,
#overview-explanations-term-var-95-value-at-risk.
The concepts table above is still the teaching home for why realised differs from achieved. The drawer is the lookup.
5. HAF — the capacity check
Thread part 4, continued: before IPP2 Atlantis Wind promises a buyer another block, how much can it safely still sell?
The seller’s problem, in plain words
A buyer asks: “Can you give me 4 MW firm next month?” Your paper answer is the forecast’s Available Energy for Sales — what is left after the book you already hold. But paper availability is not bankable availability. A plant that made 70 % of its forecast last quarter, or whose lower tiers were starved in three of the last six months, should promise less than its AES says.
HAF — the Historical Availability Factor — is the
discount that turns paper availability into a bankable number. It
multiplies four factors, each in [0, 1]: how much of the
book the plant physically covered (GAF), how stable its
generation has been (SF), how reliably each tier was
actually served (ARF), and how exposed the buyer’s
chosen tier is (CSF). The result, applied to AES and
capped by capacity headroom, is SCE — Safe Contractable
Energy: the one sentence a prospective buyer gets, “you can
safely contract another N MWh next month”.
How to view the HAF
HAF (Historical Availability Factor) is not a tab of its own. The strategy bar is Overview · Sales · Allocation · Curtailment · Plant · Dashboard (§3.2). There is no HAF button to click.
Think of Overview as the shop window: one number that says how many loaves you can still honestly promise. Sales is the back room: you pick which promise level the buyer would sign under, and you see why that number is that size. The Dashboard fold is the notebook that explains a weak month.
Follow along. Seat:
ipp_2@webill.net(passwordsupersecret). Path: Generator sites → IPP2 Atlantis Wind → Strategy → Overview. In the gap hero’s Still for sale column, find Safely contractable (#ipp-safely-contractable). Click that number. You land on Sales. Then click Firm viability · safe capacity (#subtab-firm-btn) in the Pricing tools bar (#sales-pricing-tools). Scroll to Safe contractable capacity (#sales-capacity). You should see the capacity widget — or the grey No data · No history chip on a brand-new site.
flowchart TB
A[Overview · Safely contractable] --> C[Sales]
B[Sales tab] --> D[Pricing tools]
D --> E[Firm viability · safe capacity]
C --> E
F["Old bookmark …/strategy/haf"] --> C
E --> G[Capacity widget: SCE · band · factors · trend]
G --> H[Dashboard health fold if you need why]
From Overview — the headline
- Sit as an IPP operator. On the demo that is
ipp_2@webill.net. - Open IPP Sites (or Generator
sites) → IPP2 Atlantis Wind →
Strategy. Overview is the landing tab. URL:
/org/generator-sites/<site-id>/strategy. - In the gap hero, Still for sale column, read Safely contractable. That is next month’s SCE (Safe Contractable Energy) for a Pro-rata buyer: the band chip, then a line such as 5,752 MWh next month as a Pro-rata buyer.
- Click the number (
#ipp-safely-contractable). It opens Sales (/org/generator-sites/<site-id>/strategy/sales) so you can choose the tier.
From Sales — the full widget
- Same seat and plant. Click the Sales tab, or arrive from the Overview link above.
- Find Pricing tools
(
#sales-pricing-tools) above the deal builder. Two buttons: TOU pricing and Firm viability · safe capacity. - Click Firm viability · safe capacity (shield icon,
#subtab-firm-btn). It opens as a drawer from the right, over the desk; Escape, the X or a click on the dimmed page closes it. - The firm-block card comes first in the drawer
(
#sales-firm-tool— that card answers “should I sign this evening block?” and is taught in §6.8). Scroll down the drawer to Safe contractable capacity (#sales-capacity). Intro id#sales-capacity-intro. The widget itself isdata-role="capacity-widget". - Guarantee lines, if any, sit in
#haf-availabilityabove the widget. With no enabled guarantee the box says No enabled guarantee.
Old bookmark
/org/generator-sites/<site-id>/strategy/haf still
exists so old links keep working. It flashes
#ipp-haf-redirect (Redirecting to Sales…) and
opens Sales. It does not reopen a stand-alone HAF
tab.
What you see when the widget is open
You are in the right place when you see these pieces. This chapter already owns what each one means — this list is only so you can match the screen.
| Piece | Where on the widget |
|---|---|
| Title Historical availability factor (HAF) | data-role="haf-widget-title" |
| You can safely contract another N MWh, then next month as a Pro-rata off-taker (the tier in words) | data-role="sce-headline" |
| Band chip — High · Bankable, Good · Reliable, Moderate · Caution, Low · Not bankable or No data · No history | data-role="haf-band-chip" |
| Gauge | #haf-gauge-PRIORITY / #haf-gauge-FIXED /
#haf-gauge-PRO_RATA |
| Tier chips Priority · Fixed · Pro-rata, each with its SCE (Pro-rata · 845 MWh); the chosen chip is dark | data-role="tier-selector" |
Evidence rows Forecast generation (P50),
Already contracted (ED), Not yet contracted
(AES) and Remaining capacity, MWh with comma
thousands (14,208 MWh) |
data-role="evidence" |
| An amber note when the forecast counted no demand from signed PPAs (ED) | #haf-obligations-note |
How this is worked out, folded:
GAF × SF × ARF × CSF = HAF and a legend of every
abbreviation on the widget |
#haf-how-worked-out — the four discounts §5.5 already teaches |
| Twelve-month trend | #haf-trend-spark |
| No data · No history | data-role="widget-no-data" — under three months of
history; contract-based ceiling only |
To ask why the score moved, open Dashboard → the health chapter → Availability detail (§5.8, §12.7). Compact chips of the same widget also appear on generator search cards.
When you meet HAF now
| Where | What you see | Use it for |
|---|---|---|
| Overview gap hero → Safely contractable | The SCE headline for a Pro-rata buyer (5,752 MWh next month as a Pro-rata buyer) and its band chip, as a link | The first size check before opening Sales |
| Sales → step 1 price-rail card → Safely contractable next month | The same headline beside the market baseline | Sizing a bid or a deal against the safe figure |
| Sales → Firm viability · safe capacity tool | The full capacity widget: tier chips (Priority · Fixed · Pro-rata), SCE per tier, band, the GAF/SF/ARF/CSF line under How this is worked out, trend | Choosing the tier the buyer would sign under and reading the decomposition |
| Dashboard → Chapter 5 → Availability detail (folded) | Gauge, factor bars, 12-month trend, month × tier reliability matrix, shortfall / spill log | Diagnosing why availability moved |
| Allocation · Forecast | AES (P50 / P90) that HAF discounts | The paper figure before the discount |
What you see in the capacity widget (top → bottom)
| Element | What it shows |
|---|---|
| Tier selector | Priority · Fixed · Pro-rata chips — the tier the prospective buyer would hold |
| SCE headline | “Safely contract another N MWh next month” for that tier, with the band chip |
| Gauge | HAF for that tier on a 0–1 dial, coloured by band |
| Decomposition line | GAF × SF × ARF × CSF = HAF,
each factor to two decimals, folded under How this is worked
out with the abbreviation legend |
| Badges | Forecast status (FINAL / PROVISIONAL), completeness, capacity headroom in MW |
| Trend | HAF month by month for the last twelve FINAL forecasts |
| No data state | Under three months of history the widget shows the contract-based figure and says so; it never invents a score |
The rest of this chapter defines every term (§5.1), teaches the gauge and trend (§5.2, §5.3), walks the scenarios (§5.4), details the four factors (§5.5), works one plant to three tier answers (§5.6) and lays out the per-tier SCE menu (§5.7).
5.1 Every term and concept on this screen
Read these as glossary cards for the labels you will actually see. Full factor maths live in §5.5; the worked one-plant example is §5.6.
HAF — Historical Availability Factor
What it is. A score from 0 to 1
(shown on the gauge as 0–100%) answering: “how much of
this plant’s paper availability is bankable for the
buyer seat I am considering?” Product of four discounts:
GAF × SF × ARF × CSF, each clamped to [0, 1] — never a
bonus.
Why it is on HAF. The whole tab exists to show this score (and the MWh it unlocks). Without HAF you would sell the raw leftover forecast and hope.
Plain reading. 56.3% on the dial means “treat a bit over half of the leftover as safely contractable for this tier.” Higher is better.
SCE — Safe Contractable Energy
What it is. The big headline number: “You
can safely contract another N MWh” next month as the
selected tier.
SCE = min(AES × HAF_tier, remaining capacity headroom).
Why it is on HAF. This is the menu size for new contracts. The contracting guard (§13) compares proposal volume to the same SCE.
Plain reading. Treat SCE as the honest offer size for that tier — not the raw AES leftover.
AES — Available Energy for Sales
What it is. Evidence row “Not yet contracted
(AES)”: max(0, FG − ED_total) — megawatt-hours the
latest FINAL monthly forecast still shows as unsold.
Why it is on HAF. SCE starts from AES, then discounts it by HAF. AES = 0 means the book is already full (or oversubscribed) — there is nothing safe left to grow into.
Plain reading. “Paper leftover before the honesty discount.”
FG (P50) — Forecasted Generation
What it is. Evidence row “Forecast generation (P50)”: next month’s predicted generation at the 50% confidence band (median case).
Why it is on HAF. Diligence context — what generation the leftover was carved from. Deeper forecast story: §8.
Plain reading. “What we expect the plant to make next month (middle case).”
ED — Already contracted (Expected Demand)
What it is. Evidence row “Already contracted
(ED)”: total expected demand already spoken for by existing
off-takers next month (ed_total_mwh), as the latest
forecast run counted it.
Why it is on HAF. AES = FG − ED (when positive). A high ED against a modest FG is why GAF (and HAF) often sit below 1. When the forecast run counted no demand but the site has signed PPAs, AES and SCE are too high, and an amber note under the evidence says so: The September 2026 forecast counted no demand from this site’s 4 signed PPAs, so it may overstate what is safe to sell. Contract commitments on the Commercial tab (§6.1) counts those contracts directly.
Plain reading. “What the current book is already asking for.”
Remaining capacity (MW)
What it is. Evidence row “Remaining
capacity”: the site’s saleable export capacity in
MW (export_capacity_mw), or
— if unset. Soft cap on how much firm energy you can
honestly sell.
Why it is on HAF. Energy without firm capacity is not sellable as firm; SCE is also capped by capacity headroom, not only by AES × HAF.
Plain reading. “How much MW of plant is still free to back new deals.”
Tier — PRIORITY · FIXED · PRO_RATA
What it is. The buyer’s seat in the allocation waterfall (§7). The tier selector has three chips; each shows the tier in words and its SCE, Pro-rata · 845 MWh. Default selection: Pro-rata.
Why it is on HAF. HAF is contract-aware: the same plant shows a higher HAF / SCE for PRIORITY than for PRO_RATA, because those buyers experience very different plants when generation runs short.
Plain reading. Click the tier you would actually offer; do not read PRIORITY SCE and sell a PRO_RATA deal.
Band chip (High / Good / Moderate / Low / No data)
What it is. Colour pill under the gauge (below the
SCE message): {Band} · {plain label} —
e.g. Moderate · Caution, Good ·
Reliable, or No data · No history before there
is a score. Formal band thresholds ():
| Band on chip | HAF | Plain label / meaning |
|---|---|---|
| High | ≥ 0.85 (≥ 85%) | Bankable — contract with confidence |
| Good | 0.70 – 0.85 | Reliable — minor discount |
| Moderate | 0.50 – 0.70 | Caution — meaningful shortfall risk |
| Low | < 0.50 | Not bankable — do not grow the book |
| No data | — | No history (< 3 months) — contract-based only |
Why it is on HAF. The dial shows the number; the chip shows whether that number is a green light, an amber caution, or a stop.
Plain reading. Prefer the chip over vibes — Low means do not grow the book; No data means you have no scored SCE yet.
GAF · SF · ARF · CSF (decomposition line)
What it is. Mono footer:
HAF = GAF a.bb × SF c.dd × ARF e.ff × CSF g.hh.
| Factor | Plain question |
|---|---|
| GAF | Can recent generation cover the book? |
| SF | How stable is generation (seasonality stripped)? |
| ARF | Did buyers historically get what they were owed? |
| CSF | How exposed is this tier structurally? PRIORITY 1.00 · FIXED 0.90 · PRO_RATA 0.80 |
Why it is on HAF. Instant “which discount is biting?” without opening Dashboard. Only CSF changes when you click a different tier; GAF / SF / ARF are shared evidence.
Plain reading. If one factor is clearly lowest, that is where the story is — then read §5.5 and open Dashboard for live bars.
HAF trend (sparkline / line chart)
What it is. A multi-line chart under the decomposition when monthly history exists: one series named HAF, Y in %, X months labelled like Oct. ’25.
Why it is on HAF. A single month’s band can look fine while the trend is falling into a curtailed or oversubscribed window.
Plain reading. Watch direction and dips — not only the latest point. (Series is the plant’s stored PRO_RATA HAF history; the gauge still follows the selected tier.)
5.2 How to read the gauge
What the dial is. An ECharts gauge
(gauge_chart) for the selected tier’s HAF,
scaled 0–100 with unit %. There is
no target tick on this screen — the fill is a simple
progress arc to the needle (sky blue on a grey track). The band
badge under the dial carries the Good / Moderate / … colour
meaning; do not expect the dial rim itself to be striped into band
colours.
Centered stack (top → bottom). Nothing sits beside the dial — the full widget stacks in one centred column:
- Bold title: Historical availability factor (HAF)
- SCE message: eyebrow You can safely contract another · huge N MWh (comma thousands) · next month as a {Tier} off-taker, the tier in words — next month as a Pro-rata off-taker
- Gauge dial (centre %)
- Band badge under the dial
- Tier chips → evidence (and the obligations note, when it applies) → How this is worked out, folded → trend
Step-by-step
- Read the SCE message above the dial. That MWh is
what you can put in front of a buyer for this tier —
already
AES × HAF(and capacity-capped). - Read the centre %. That is
HAF_tier × 100, rounded to one decimal (e.g. 56.3% for HAF 0.563). - Read the band badge under the dial. Map % → band with the table in §5.1. High / Good = grow carefully; Moderate = shrink offers / price risk; Low = stop growing; No data = no scored dial (see scenario below).
- Click another tier chip. Gauge %, SCE message, band badge, CSF in the folded decomposition, and the dark chip all update. PRIORITY should show a higher % and SCE than PRO_RATA on the same plant.
- Cross-check evidence. If AES is 0 or tiny, a pretty gauge still means “almost nothing left to sell.” If Remaining capacity is — or very low, firm offers are capacity-bound.
Good vs bad (cheat sheet)
| Gauge / chip | Meaning | React |
|---|---|---|
| High % + High/Good chip + healthy SCE | Bankable leftover for that tier | Sales can size offers near SCE |
| Mid % + Moderate | Caution — meaningful shortfall risk | Smaller offers; prefer stronger tier or wait |
| Low % + Low | Not bankable | Do not grow the book; open Forecast / Dashboard |
| No data (no dial) | < 3 months history | Contract-based ceiling only; explicit caveat |
| High % but AES ≈ 0 | Score is fine; leftover is gone | Stop selling; you are full / oversubscribed |
Good · Reliable — needle high, lime chip
Represents: PRIORITY-class score on the worked plant (~0.704). React: SCE is the menu; Sales may offer near that MWh for this tier.
Moderate · Caution — mid dial, amber chip
Represents: default PRO_RATA view on the §5.6 worked example (HAF 0.563 → SCE 845 MWh). React: sell, but size to SCE and expect the guard to warn above it.
Low · Not bankable — needle left, red chip
Represents: HAF under 0.50 — book too big, delivery weak, or both. React: pause new volume; open Dashboard / §5.5 to see which of GAF, SF, ARF is dragging.
5.3 How to read the trend graph
What the chart is. When the plant has monthly HAF
history, a multi-line chart appears under the
decomposition (multi_line_chart, id
haf-trend-spark). If there is no history, the chart is
simply not rendered (no empty-plot placeholder on this
tab).
What each axis is
| Axis | What it shows | Plain reading tip |
|---|---|---|
| Horizontal (X) | Forecast months, oldest → newest | Labels use Format.axis_month:
a month like 2025-10 renders as Oct. ’25
(abbreviated month, period, abbreviated year) |
| Vertical (Y) | HAF in percent | Stored HAF (0–1) × 100 — same unit family as the gauge |
| Series / legend | One series named HAF | Built from each month’s stored
PRO_RATA HAF (haf_pro_rata) — it does
not re-filter when you click PRIORITY / FIXED |
So: tier buttons change the gauge and SCE; the trend line is the plant’s PRO_RATA history — useful as a reliability spine, not as a per-tier rewrite.
Step-by-step
- Find the latest month on the right (e.g. Dec. ’25). Compare its height to the gauge’s PRO_RATA reading — they should rhyme.
- Scan left for dips. A sharp drop often marks a curtailed or oversubscribed month entering the trailing window (§5.8 · §12.7).
- Check the Y scale. Values are % (e.g. 56, not 0.56). Three split lines are typical on the LiveView chart.
- Do not confuse with Overview’s 24h Unsold profile. That chart is hourly kWh sold-vs-unsold (§4.2); this one is monthly bankability %.
- If the chart is missing and the chip is not No data, history may still be thin on PRO_RATA points — use the gauge + evidence rows, then Forecast / backfill (§14).
How the axes read
Represents: X months as Mon. ’YY; Y
percent; one HAF line. React: read slope and the latest
point before you trust a single gauge snapshot.
5.4 Scenarios — what you might see, and how to react
Illustrative pictures only — numbers rhyme with the §5.6 worked plant where noted (AES 1,500 MWh · PRO_RATA HAF 0.563 · SCE 845 MWh).
1 · Healthy Pro-rata leftover (Moderate)
Represents: default tab — SCE message above, gauge mid, amber badge under the dial, trend gently soft. React: take Overview’s unsold shape to Sales, but size new PPAs to ~845 MWh PRO_RATA (or click PRIORITY / FIXED for those menus).
2 · Same plant, PRIORITY selected
Represents: tier click only — CSF rises to 1.00; message, gauge and badge jump; decomposition’s last factor changes; trend line stays the PRO_RATA history. React: only quote the PRIORITY SCE if the contract will actually be PRIORITY.
3 · Trend dipping (curtailment entering the window)
Represents: monthly bankability sliding — often SF (volatility / curtailment) or GAF (book vs generation). React: do not size Sales off last summer’s SCE; open Dashboard factor bars and Forecast for the weak months (§5.5 · §13 alerts).
4 · AES gone — oversubscribed book
Represents: evidence row AES at 0 (or SB negative on Forecast). Gauge may still show a mid band from history, but headline SCE is ~0. React: stop new offers; fix the book / generation story on Forecast — HAF cannot invent leftover energy.
5 · No data — young plant
Represents: < 3 months of history — widget
no_data state; no gauge, no scored SCE, no trend. Fallback
ceiling uses AES (or FG) with an explicit caveat.
React: contract carefully on paper ceilings; the guard
stays quiet on HAF oversubscription until history exists
(§13).
6 · Low band — do not grow
Represents: product of weak factors under 0.50. Decomposition shows where it hurts. React: freeze Sales growth; repair coverage / delivery / volatility before quoting new MWh — see §5.5.
Scenario cheat sheet
| Picture | Likely on screen | Action |
|---|---|---|
| Moderate + solid SCE | Default PRO_RATA leftover | Sell up to SCE; guard above it |
| PRIORITY click lifts % / SCE | CSF 1.00 | Only if the deal is really PRIORITY |
| Trend dipping | HAF % falling month-on-month | Dashboard + Forecast before Sales |
| AES ≈ 0 | SCE ~0 even if band mid | Stop selling — book full |
| No data | Grey chip, caveat copy | Paper ceiling only; build history |
| Low chip | < 50% | Do not grow the book |
How to use it (short path)
- Open the widget as above: Safely contractable on Overview, or Sales → Pricing tools → Firm viability · safe capacity, after you already know there is a revenue gap, or when a buyer asks “how much can you really stand behind?”.
- Select the tier you expect to offer (PRIORITY buyers see a higher HAF / SCE than PRO_RATA on the same plant — §5.6).
- Treat the SCE headline as the menu size for new contracts; the contracting guard (§13) will compare proposal volume against this same evidence.
- When the band is Low, AES is zero (oversubscribed), or the trend is falling hard, pause new offers and open Forecast / Dashboard for the underlying month.
- For factor maths, bands and the annotated widget walkthrough, continue below (§5.5–§5.9).
Where this is taught. How to open the widget: above. Tab order: §3.2. Factor maths: §5.5. Widget annotation: §5.9. Guard: §13. Revenue-gap KPIs remain on §4 Overview.
5.5 The four factors, in detail
December says 1,500 MWh is for sale. Should a buyer believe it? HAF (Historical Availability Factor) is a score from 0 to 1 that discounts your paper availability for the things a buyer actually cares about — and it is contract-aware: a priority buyer sees a higher HAF than a pro-rata buyer on the very same plant, because they would experience a very different plant.
HAF is the product of four discounts, each clamped to [0, 1]. The clamp matters: each factor is a discount, never a bonus — a plant that outperforms is simply “fully available”, not more. And the product means a weakness in any one dimension compresses the whole score: a stable, well-allocating plant that is simply oversubscribed is not safe to contract, and neither is an under-subscribed but wildly volatile one.
| Factor | Question | Formula | What moves it |
|---|---|---|---|
| GAF Generation Availability |
Can the plant physically cover its promises? | min(1, AvgGen₃ₘ / AvgObligations)
— trailing 3-month generation (seasonally corrected) over the book’s
subscribed demand |
Oversubscription pushes it down; growing generation or a trimmed book pulls it up. GAF < 1 means the book already exceeds recent output. |
| SF Stability |
How much can you trust the average? | max(0, 1 − σ/μ) over the
seasonally detrended 12-month series HAG/SM |
Volatility and curtailment lower it. Detrending matters: a solar plant’s summer/winter swing is expected shape, not instability — raw σ would punish every seasonal plant. Curtailed months stay in (instability is real for the buyer); meter-gap months are excluded (data missing ≠ plant missing). |
| ARF Allocation Reliability |
What did off-takers actually receive vs contract? | min(1, settled allocations / expected demand)
over the trailing window — computed portfolio-wide and per
tier |
Delivery history. Tiers fail unequally:
the waterfall protects PRIORITY and starves FIXED first, so
ARF_PRIORITY can be 0.99 while ARF_FIXED is
0.55 on the same plant. |
| CSF Contract Sensitivity |
How exposed is the buyer’s chosen tier, structurally? | PRIORITY 1.00 · FIXED 0.90 · PRO_RATA 0.80 (fixed lookup) | The prospective buyer’s intended tier. CSF encodes the contract’s promise (FIXED holds a defined entitlement, PRO_RATA only a share of the remainder); ARF encodes the plant’s reality. Keeping both means a young plant with no shortfall history still prices tier risk — and on a tight book the worse of the two dominates. |
Data. HAF worked values below are illustrative and use the §8 forecast example · full_demo seed 42 supplies the screen context · last checked 2026-07-18.
5.6 HAF worked — one plant, three answers
Continuing the same solar IPP into August:
- GAF — trailing generation (13,200 + 12,800 +
12,100)/3 = 12,700 MWh against subscribed demand 16,000:
min(1, 12,700/16,000) = 0.794. The book is bigger than the plant — that alone knocks 21% off availability. - SF — the 12-month series has σ = 454.6 around μ =
12,700 → CV = 0.036, so
SF = 1 − 0.036 = 0.964. A steady plant. - ARF — off-takers received 92% of expected demand
over the trailing year:
0.920. - CSF — depends on where the prospective buyer would sit.
× CSF per prospective tier ⇒ HAF:
HAF(PRIORITY) = 0.794 × 0.964 × 0.920 × 1.00 = 0.704 →
Good · Reliable
HAF(FIXED) = 0.794 × 0.964 × 0.920 × 0.90 = 0.634 →
Moderate · Caution
HAF(PRO_RATA) = 0.794 × 0.964 × 0.920 × 0.80 = 0.563 →
Moderate · Caution
Same plant, three different answers — which is exactly the contract-accuracy a buyer deserves.
Why does the score move? A curtailed month raises volatility in the detrended series and pulls SF down. An oversubscribed season starves the fixed tier and pulls its ARF down while GAF drops too. Every movement is traceable to settled evidence — never to a manual adjustment.
5.7 Safe Contractable Energy — the per-tier menu
SCE is the number a prospective buyer should trust — December’s 1,500 MWh of AES discounted by the HAF of the tier they’d be buying into, and capped by capacity headroom (energy without firm capacity is not sellable as firm):
SCE = min( AES × HAF_tier, remaining capacity headroom )
SCE = 1,500 × HAF_tier, capacity
headroom permitting.
Read it as a menu: the same December surplus supports a 1,056 MWh priority deal, a 951 MWh fixed block, or an 845 MWh pro-rata share — the difference is purely how much protection each seat in the waterfall gives the buyer. The contracting guard (§13) compares proposal volume to this same SCE.
5.8 The availability detail on the Dashboard
The Dashboard’s Availability (HAF) block is folded under Chapter 5 (health check): gauge, tier fulfilment matrix, shortfall / spill log. Open the fold when the Availability · HAF vital sign is amber or red and you want to know which factor moved. Field guide: §12.7.
| Panel | Question it answers |
|---|---|
| Gauge | What is HAF for the PRO_RATA tier this month, and which band is that? |
| Factor breakdown | Which of GAF, SF, ARF (and CSF) is pulling the score down? |
| HAF trend (12 months) | Is the score sliding, stable or recovering? |
| Reliability matrix | Month × tier: what share of each tier’s expected demand was actually served? |
| Shortfall & spill log | Which months were oversubscribed (shortfall) and which spilled, with the MWh? |
Each panel is taught in §12.7. The Availability vital sign above the fold summarises the same data in one number and a sparkline, and the availability slide row in the loss ledger prices any decline from the best month (§12.5).
5.9 The capacity widget — annotated
The widget is the seller’s answer to “how much can I promise?”, rendered identically wherever it appears. On Sales open Firm viability · safe capacity in the pricing tools bar; in the drawer, the widget sits under the firm-block card as Safe contractable capacity.
- Tier selector. Click the tier the buyer would sign under. Only CSF changes between tiers; GAF, SF and ARF are the plant’s.
- Headline. SCE for that tier,
min(AES × HAF_tier, capacity headroom). On a PRIORITY promise it is larger; on PRO_RATA smaller. - Band chip. High · Bankable, Good · Reliable, Moderate · Caution, Low · Not bankable or No data · No history — the sales meaning of each is in §15.2.
- How this is worked out. Folded under the evidence: the four factors, so a buyer’s adviser can check the arithmetic, and a legend of every abbreviation on the widget.
- Badges. FINAL or PROVISIONAL with completeness %, and the capacity headroom in MW that caps the headline.
- Trend. Twelve months of HAF; a downward run is the cue to open the Dashboard fold before quoting.
Careful. A firm block the buyer asks for must fit inside the SCE for their tier — the firm-viability card beside the widget checks price, the widget checks volume. The contracting guard (§13) repeats the volume check when the proposal is built.
Where this is taught. The Sales pricing tools: §6.7 and §6.8. Forecast AES before the discount: §8.1.6. The Dashboard fold: §12.7.
Guarantee versus measured availability
The Sales capacity section shows each active enabled contract’s guaranteed percentage, trailing measured percentage and periods below the guarantee. With no enabled guarantee, it says so; missing measurements are shown as no evidence. The old HAF route redirects here. GAF, stability, allocation reliability, tier factors and safe contractable energy retain their existing arithmetic.
6. Sales — the Sales Desk
Thread part 4, continued: IPP2 Atlantis Wind has energy nobody is buying. Who should buy it, on what terms, and is any of that better than selling it on the day-ahead market?
Follow along. Seat:
ipp_2@webill.net. Path: Generator sites → IPP2 Atlantis Wind → Strategy → Sales. You should see a five-step rail across the top, the gap band with Option 0 · hold and sell on SAWEM, a candidate finder on the left (above the builder on a window narrower than 1280 px), and an empty deal builder that asks you to pick a candidate.
Data. full_demo · seed 42 · IPP2 Atlantis Wind · stage S09 · last re-derived 2026-09-03. The DAM price forecast the desk values the gap against is the trailing-quantile SMP forecast (
WB.Brp.PriceForecast). Examples that name IPP1 Sandton Solar — forecast run v101, SIM Menlyn Park Load, SIM Gateway Umhlanga — were read on seatipp_1@webill.neton 2026-09-28 and move with that seat’s data.
6.1 What this screen is for
The desk answers one question in five steps: given the energy I cannot place today, which deal — or no deal — leaves me best off after risk?
- The gap and its market value. What you are selling and what the day-ahead market would pay for those same hours. The market is Option 0: the baseline every contract must beat.
- Who could absorb it. Off-takers and traders ranked by fit to the unsold shape, with how much of the gap each would actually take and which contract routes are open to them today.
- Build the deal. Capacity, strike, term and shape, seeded by the advisor, on the route you choose — physical PPA, Eskom VPPA or via a trader.
- Profit and risk vs holding. One simulation, judged against Option 0: advantage and risk as two scores, five risk gauges, and the price at which the market would have been the better choice.
- Compare and decide. Every simulation and the hold option on one table and one chart, ranked by balanced, advantage, lowest risk or certainty. Then Build Proposal — nothing here signs anything.
The old TOU pricing and Firm viability tabs are now pricing tools. Each opens as a drawer from the right, over the desk, so the terms it feeds stay where they are; they are taught in §6.7 and §6.8. The capacity widget sits inside the firm tool (§5).
On the site workspace the desk is the Commercial
tab’s third panel, headed Sales desk (Sell
available energy: find the next buyer, test the deal and compare it with
holding for the market.), under open proposals and Contract
commitments (#ipp-contract-commitments). There the
step rail is left out and the gap band (step 1) is folded under
Available energy, market pricing & risk context
(#sales-market-context); once you open it, it stays open
while you work. Contract commitments is the headroom check before you
sell: four tiles — Physical PPAs, Virtual
PPAs, Contracted energy and Remaining
saleable energy — and View site contracts into
Deals. Contracted energy takes its annual figure from
the best evidence it has, in this order:
| Basis | When | What the tile shows |
|---|---|---|
| Stated volumes | Every signed or active physical PPA states an annual volume | {X} MWh/yr · Physical PPAs · annual volume |
| Capacity share of P50 | A PPA states no annual volume but has a contracted capacity: it
counts as contracted MW ÷ export MW × annual P50, capped at
the whole P50 |
≈ 1,000.0 MWh/yr · 1 PPA estimated from its capacity share of P50 |
| Latest forecast run | A PPA has neither a volume nor a capacity: the tile uses what the latest forecast run allocated to buyers, annualised over the days it covers — the same figure Performance shows under Contracted | ≈ {X} MWh/yr · From the latest forecast run · N PPAs state no annual volume (1 PPA states … for one) |
| None | No forecast run either | — · N PPAs missing annual volume |
Whenever the figure is estimated, Remaining saleable energy (annual P50 less commitments and reservations) adds · estimated to its note: Annual P50 less commitments & reservations · estimated. Reservations awaiting signature are estimated the same way. On the seeded IPP1 Sandton Solar the tile reads ≈ 4,866.9 MWh/yr from the latest forecast run — the 4.9 GWh Performance shows — and Remaining saleable energy reads 113,393.1 MWh/yr.
6.2 What the desk looks like (top → bottom)
| Block | What it is |
|---|---|
| Step rail | Five steps; a step lights as you reach it (3 when a candidate is picked, 4 when it has a simulation, 5 when there is something to compare) |
| Gap band (step 1) | Three cards: the gap chart (unsold kWh by hour with the SAWEM P10–P90 band and P50 line) and its c/kWh market line, the price rail with what a kWh of the gap is worth and its legend, plus safely contractable, the gap window, day-ahead bidding and the forecast used, and Option 0 · hold and sell on SAWEM |
| Who could absorb the gap (step 2) | Count chip, search box, six filter chips, one mixed list of candidate cards. Below 1280 px wide the list sits above the builder, two cards a row |
| Pricing tools | TOU pricing and Firm viability · safe capacity buttons; each opens a drawer from the right |
| Build the deal (step 3) | The selected candidate, the contract route switch, four term cards with sliders and warnings, demand pool, route advice, Simulate Sale and, after a run, Build Proposal |
| Simulated Impact (step 4) | One card per run: four deltas with before → after, the verdict against holding, five risk gauges, the forecast it was judged against, the vs-market line |
| Compare and decide (step 5) | The ranked table with the hold option as row 0, then the risk-against-advantage chart. They sit side by side only on a window 1536 px or wider |
6.3 Ideas you need (in plain language)
| Idea | Plain words |
|---|---|
| Unsold profile / the gap | Generation with no buyer, hour by hour on a typical day. The shape you are selling. |
| Option 0 · hold and sell on SAWEM | Do nothing bilateral; bid the gap day-ahead. Valued at the hourly P50 price for your unsold hours from the newest day-ahead forecast that prices them, less a 5 % imbalance allowance, with P10 and P90 as the poor and good price years. A forecast run whose every price is 0 is skipped, never read as a market worth R 0. The option has no counterparty, no term and no certainty for financing — which is why it carries risk of its own. |
| Price rail | Where a kilowatt-hour of the gap sits: 0 c earned today (spilled energy) · LCOE, your cost · your floor (LCOE plus margin) · the day-ahead P50 in your technology’s hours · achieved on sold energy · the buyer’s replacement cost. A buyer’s offer reads as a position on this rail. |
| Shape fit | Cosine similarity between a buyer’s hourly demand and your unsold hours, 0–100 (fit score). High fit means daytime load for daytime spill. |
| Could take | The energy the allocation waterfall would actually give a candidate, as GWh a year and as a share of the gap. A trader can take the whole gap; an off-taker only where its load overlaps. It is not what the buyer asks for: the card shows that separately. |
| Route | How the sale is contracted: Physical PPA (wheeled, seats the buyer in the hierarchy), Eskom VPPA (a financial settlement against the buyer’s Eskom tariff; open only when the pair passes the eligibility blockers), Via trader (the trader takes the whole gap, prices off the market). |
| Advantage | Margin uplift over holding for the term at P50, as a share of the gap’s market value, 0–100. |
| Risk | A weighted blend of five components, 0–100: Margin@Risk (the share
of the expected, P50, margin lost if volumes come in low, at P90),
concentration (revenue HHI after the deal), shape / firmness, price lock
(term length, fixed vs indexed) and counterparty readiness. Weights are
book assumptions (sales_risk_weights). |
| Certainty (P10) | What the deal still earns in a poor price year; the hold option’s certainty is its P10 value. |
| Terms badge | Deals on identical capacity, price, term, contract type and pool share a badge (Terms A, B…) so buyer-to-buyer comparisons stay fair. It was called the Params badge before 3.27.51. |
| Simulation / run | Every Simulate Sale creates a new run (run 1, run 2…) of a hypothetical deal; the live book is never changed. Runs are saved: leave the desk and come back, and they are still in the comparison. |
6.4 The process, step by step
Step 1 — read the gap and its market value
The headline says how much energy a year is unsold and that every deal is judged against what SAWEM would pay for it. One sentence then puts that market in c/kWh: At the day-ahead forecast your unsold hours earn 92.1 c/kWh at P50; the whole day averages 93.4 c/kWh. Under it, the gap chart draws the unsold kWh by hour (amber) with the DAM price band for the same hours (blue): when the amber peak sits where the blue is lowest the chart says so — gap peaks when the market is cheapest. The capture card beside it, Your technology’s realised capture · last 30 days, is history, not the forecast (Captured forecast and realised capture).
The price-rail card answers what a kWh of the gap is worth.
Its markers alternate above and below the line, so two close prices
never print over each other, and a legend under the rail lists every
price with its colour and meaning (#sales-price-legend).
Then:
| Line | What it says |
|---|---|
| Safely contractable next month | The safe figure for a new Pro-rata buyer, with comma thousands and the band: 5,752 MWh · pro-rata tier · moderate (§5) |
| Gap concentrated in | The window and its share of the spill |
| Day-ahead bidding | open · the plant is BRP-registered, or closed · the plant is not BRP-registered |
| Day-ahead forecast | The forecast run every market number on the desk comes from: v101 · built 19 September 2026 · 5.0 % imbalance allowance. A run more than seven days old carries an amber stale chip |
The price forecast is refreshed daily from the day-ahead market’s clearing prices. A refresh over days with no clearing prices writes a run whose every price is 0. The desk skips such runs for the newest run that prices an hour, and says so under the card: The 4 newest forecast runs carried no prices, so this older one is used. (The newest forecast run carried no prices, so this one is used. for one.)
Option 0 · hold and sell on SAWEM is the third card: the P50 value a year, then P10 and P90, then the note that decides its risk — no counterparty, no term, no certainty for financing when you are registered, needs BRP registration before you can bid when you are not. When no forecast run prices the month the card says so, the chart card’s sentence turns amber — No day-ahead forecast prices these hours yet, so there is no market price to compare a deal with. — and deals are shown against spilling the energy for nothing.
Step 2 — who could absorb the gap
One list mixes off-takers and traders. Simulated candidates sort first by their simulation rank; everyone else sorts by shape fit. On a window 1280 px or wider the list runs down the left of the builder; narrower, it sits above the builder, two cards a row. Each card shows:
- the name, a role line (off-taker · Retail · Municipality · City of Tshwane · Cross-municipal (via Eskom transmission) · 6,570,000 kWh/mo), and a shape fit score with a sparkline of the buyer’s load over your unsold hours;
- a could take bar — could take 61.9 GWh/yr · 54 % of the gap — and, when the buyer states an annual volume, what it asks for: asks for 5,256 MWh/yr. The two differ: could take is what your unsold hours could give this buyer, asks for is what the buyer wants;
- route chips — PPA, Eskom VPPA ready, or VPPA · IPP network operator must be Eskom when the route is closed, plus metered history or no history · contract profile;
- Simulated ×n, the #rank badge and the run’s Terms badge once you have simulated it, and the best run’s line (Best: run 1 · 50.0 MW · 60.0 c/kWh · 10y · +R 3.6 m margin a month · unsold −71.5 pp);
- a folded Details & buyer preferences block: organisation, address, connection, business, monthly consumption, topology, and the buyer’s declared tariff, spill, curtailment, REC, term, volume and shortfall preferences. Once opened it stays open while the page updates.
Search matches the words on the card — name, organisation,
municipality, business category and address — so manufacturing
finds every manufacturer. Or filter with the chips:
Suggested (everyone, ranked), Daytime
shape, Absorbs ≥ 25 %,
VPPA-ready, Traders,
Simulated. The count chip
(#sales-candidate-count) reads 16 candidates, or
3 of 16 while a search or filter hides some. When nothing
matches, the empty list says No candidate matches this search or
filter. and offers Show all candidates, which
clears both.
Buyers of the same category share a load shape, so they share a shape fit (several cards can all read 90.3). Among equal fits the list ranks by how much of the gap each would absorb, largest first. The footnote under the list says so, and says what the two numbers mean: Shape fit compares a buyer’s hourly demand with your unsold hours (100 means the same shape). “Could take” is the energy the allocation would actually send them.
Each buyer’s name is a real button
(#offtaker-candidate-{id}-select, or
#trader-candidate-{id}-select on a trader card):
Tab reaches it, and Enter or
Space selects that buyer. Clicking anywhere on the card
still selects it too. Selecting scrolls the builder into view, so a card
far down the list never leaves its terms off screen.
Step 3 — build the deal
Click a card. The builder opens as Build the deal · name with the candidate’s fit and a Clear control. Then:
- Contract route. Physical PPA · Eskom VPPA · Via
trader. A route the candidate cannot take is disabled, and hovering it
says Closed today. See what it still needs below. The suggested
route is preselected — VPPA when it is open and the buyer wants an
indexed or TOU-linked price, otherwise PPA; traders go via trader. The
route advice paragraph under the terms explains why.
When a physical PPA is chosen and the Eskom VPPA route is closed for one
reason, the advice names it (The virtual route is closed today:
…). When it is closed for more than one, the advice says The
Eskom VPPA route is closed today; the checklist below is what it still
needs. The checklist is folded, because it is about a route you did
not choose: Eskom VPPA is closed today: 10 things it still
needs (
#sales-route-blockers). Open it to see each blocker on its own line; it stays open while you change terms. - Four term cards. Each has a number, a slider and a
hint from the advisor, and each checks what you type against the site:
- Capacity (MW) — hint: knee at X MW · ceiling Y
MW saleable. The knee comes from the last capacity sweep; the
ceiling is the plant’s saleable MW. The seed covers the buyer’s stated
annual volume at the plant’s capacity factor, never more than the plant
can sell. On IPP1 Sandton Solar (27 % capacity factor), SIM Menlyn Park
Load asks for 5,256 MWh a year, so it seeds 2.22 MW
(
5,256 ÷ (0.27 × 8,760)), not the whole plant. Above the ceiling the card says More than the 50 MW this plant can sell. Lower it to simulate. in red, Simulate Sale is disabled beside Lower the capacity to simulate., and the server refuses the run as well. Below the ceiling but more than a quarter above the buyer’s ask, an amber line says how far over; at 20 MW: About 47,304 MWh a year, 9.0× the 5,256 MWh the buyer asks for. - Strike / price (c/kWh) — hint, for example floor 50 c · SAWEM P50 92.1 c · replacement 210 c. The SAWEM P50 part is left out when it would be 0 c (no forecast hour overlaps your unsold hours). The seed is the price-card ask, never raw LCOE. A strike under the floor reads Below your 50 c floor (LCOE plus margin): every kWh sold loses money.; one over the replacement cost reads Above the 210 c replacement cost: the buyer can buy cheaper elsewhere. Both are amber warnings: you can still simulate.
- Term (years) — hint: the buyer’s asked term and whether they want a fixed or indexed price.
- Shape — As-generated or TOU-shaped. Either way the simulation pays the strike on every kWh as generated; TOU-shaped records that the strike stands for a multiplier set’s average price over your generation, which Use as strike in TOU pricing sets (§6.7). The hint reads the best TOU set at the strike you are building (A time-of-use tariff at this strike would average N c), or says No time-of-use set beats a flat price in this plant’s hours. It ends with the firm evening block in words: covered by generation, only with a battery, or not viable, the plant can’t cover it.
- Capacity (MW) — hint: knee at X MW · ceiling Y
MW saleable. The knee comes from the last capacity sweep; the
ceiling is the plant’s saleable MW. The seed covers the buyer’s stated
annual volume at the plant’s capacity factor, never more than the plant
can sell. On IPP1 Sandton Solar (27 % capacity factor), SIM Menlyn Park
Load asks for 5,256 MWh a year, so it seeds 2.22 MW
(
- Demand pool. Which demand bucket the simulated sale is booked into; its allocation rules decide which hours reach this buyer. The route preselects the matching pool.
- Simulate Sale. A busy overlay holds the page while the engine runs the deal and, for the risk read, a second pass at P90 supply. After the first run the emphasis moves: Build Proposal becomes the green button and Simulate again, which creates the next run, the plain one beside it.
Step 4 — profit and risk vs holding
Each Simulated Impact card carries the run (Run 1), the Terms badge and the route badge, then:
- Four deltas with before → after: margin for the month window (and the annualised figure) in short Rand, +R 3.1 m; realised price plant-wide in c/kWh; unsold share of site generation; revenue HHI (buyer concentration).
- The verdict sentence — Beats holding for the market by R 9.8 m a year at P50 — and by R 22.6 m in a poor price year — with advantage N / 100 and risk N / 100 chips. When the two answers point different ways the sentence says so: Loses R 17.5 m a year against holding at P50 — but beats it by R 37.4 m in a poor price year (a poor price year, P10, is when holding earns least).
- Five risk gauges — Margin@Risk, Concentration, Shape / firmness, Price lock, Counterparty — each with its value and a one-line note.
- The forecast it was judged against — Compared with the day-ahead forecast built 19 September 2026, 9 days ago; newer forecast runs carried no prices. The age appears when the run is more than a week old. With no forecast at all the line turns amber: No day-ahead forecast prices these hours, so this compares the deal with spilling the energy for nothing, not with the market.
- The vs-market line — the advantage at P50, at market P10 and at market P90, and you lose to the market only if SAWEM averages above N c in your hours.
- Build Proposal, which runs the price and capacity sweeps and opens a private draft in the Deal Room (V7). Nothing reaches the other side until you send it.
Step 5 — compare and decide
The comparison appears after the first simulation, and it survives leaving the page: runs are saved, and the desk brings back every run for the current window that has results, including runs made in an earlier visit or by a colleague. The Simulated filter lists their buyers.
Compare and decide comes first, full width. The table ranks each deal with the hold option as row 0: deal and terms (SIM Gateway Umhlanga · run 1, 50.0 MW · 60.0 c/kWh · 10y, its Terms badge), route, vs hold /yr, P10 floor, advantage and risk (with bars on a window 1280 px or wider), and the run’s action. Switch the sort with Rank by: balanced (advantage less half the risk), advantage, lowest risk, certainty (P10). The Same terms chips filter the table — and the candidate list — to one Terms badge or to the selected candidate’s latest terms, so you compare buyers on identical terms.
The last column says what you can do with each run:
| The row shows | Meaning |
|---|---|
| Build Proposal → | The run can become a draft |
| proposal drafted | A draft already exists; the run’s impact card offers Open its draft |
| draft discarded | The run’s draft was discarded under an earlier release; simulate again to build from it |
| Remove run | Asks first (Remove this run from the comparison? It can’t be brought back.), then discards the run and confirms Run removed from the comparison. Not offered while a draft exists |
Discarding a draft in the studio sends its run back to the comparison, ready to build again.
The Risk against advantage chart follows, with its explanation beside it (on a window 1536 px or wider it sits to the left of the table instead). It plots every deal by risk (right is riskier) and advantage over holding (up is more money); the shaded corner is where you want to be, and the dashed line is the hold option at advantage 0. Dots carry the table’s rank numbers, so the table is the legend: Each dot’s number is its rank in Compare and decide; 0 is holding for the market.
What the system recommends, and why
The desk recommends in four places, and each recommendation shows its working:
| Where | Recommendation | Working |
|---|---|---|
| Candidate order | Who to look at first | Simulated deals by rank, then shape fit to the unsold hours, then — among equal fits — how much of the gap each could take |
| Route switch | The preselected route | VPPA only when the eligibility blockers pass and the buyer wants an indexed price; traders via trader; otherwise PPA |
| Term seeds | Capacity, strike, term | The advisor’s price card and capacity knee, with capacity held to the buyer’s stated annual volume; the buyer’s declared asks |
| Verdict and rank | Whether the deal beats holding, and where it ranks | Advantage vs Option 0 at P50 / P10 / P90; the five-component risk blend with book weights |
The desk never recommends signing. The comparison ranks; Build Proposal starts the negotiation flow.
6.5 Same-terms comparison and the Terms badges
Two deals on different capacity, price or term are different deals, not different buyers. The desk fingerprints every simulation’s terms and labels identical sets Terms A, Terms B, and so on (the Params badges of earlier releases). The badge appears on the candidate card, on the Simulated Impact card and on the comparison row; the Same terms chips under the comparison heading filter to one badge, to same as selected, or back to all deals. Filtering also narrows the candidate list to the buyers who carry that badge, so you can walk a shortlist on one set of terms.
6.6 Worked example — sell midday unsold into a high-fit factory
Data. Illustrative, on the shape of a 50 MW solar plant with 96 % unsold, LCOE 48 c, SAWEM P50 72.7 c in the unsold hours.
| Input | Value |
|---|---|
| Unsold, typical day | 311 MWh, 68 % of it 08h–13h |
| Option 0 (hold), a year | P50 R 78.6 m · P10 R 59.1 m · P90 R 124.0 m |
| Candidate | Cold-storage off-taker, fit 91, absorbs 34 % of the gap, Eskom VPPA ready, metered history |
| Terms | 6 MW · 78 c · 7 yrs · as-generated · Eskom VPPA |
Simulate. The engine allocates the deal’s energy and prices it: margin uplift in the month window +R 2.7 m (≈ R 32.8 m a year); the hold value of the same energy at P50 is R 23.0 m a year, so the advantage is +R 9.8 m a year. At market P10 the advantage widens to +R 22.6 m; at market P90 it narrows to −R 4.1 m — you lose to the market only if SAWEM averages above 78 c in your hours. Risk components: Margin@Risk 14 % (P90 volumes), concentration 0.62 after the deal, shape low (as-generated), price lock 7 years fixed, counterparty ready — blended risk 38. The comparison places it first on balanced; a second run at 81 c on a physical PPA ranks higher on advantage and lower on lowest risk because its concentration is worse.
Finding the price where the margin reaches zero
The vs-market line prints it: you lose to the market only if
SAWEM averages above N c in your hours. It is the strike at which
the deal’s margin uplift equals the hold value of the same energy —
d_margin ÷ (absorbed MWh × 10 × (1 − imbalance)). Move the
Strike / price slider and simulate again to see the
verdict flip from beats holding to loses against
holding; the floor on the price hint is the book’s LCOE + margin,
below which no deal should go regardless of the market.
6.7 TOU pricing — is that multiplier set worth it?
Route:
…/generator-sites/<id>/strategy/sales ·
Tab: Sales → TOU pricing pricing tool,
a drawer from the right (#sales-tou-tool)
On-screen chrome: base-price input + ranked
multiplier table (tou_multiplier_table) with a "Best set:
…" narration line, and a Use as strike button on each
row while a candidate is selected.
The seller's problem, in plain words
You sell electricity. A buyer often rejects a simple flat price ("65 c/kWh, every hour") and counters with a time-shaped offer:
"We'll pay 1.3× your base in peak hours, 1.0× in standard, and 0.7× in off-peak."
That can sound generous — peak is "expensive", so a 1.3× peak uplift looks like a win. For you, it is only a win if your plant actually generates in the hours that carry the uplift, and does not dump most of its energy into the discounted hours.
A solar plant makes almost nothing at 19:00 (evening peak) and a great deal around midday (usually standard on the Megaflex weekday clock). Accepting a big peak multiplier while giving away off-peak (and sometimes standard) can quietly cost hundreds of thousands of Rand a year — even when the brochure looks attractive.
The TOU pricing pricing tool on Sales exists for one job: take your plant's generation shape, apply each candidate multiplier set hour by hour under the same SAST TOU calendar the engine uses everywhere else, and rank the sets by effective price — best first — so you can see which counter is actually worth it.
This tab does not sign a deal. It is a pricing calculator beside the deal builder (§6). Use it when a buyer (or you) floats a TOU-linked counter; Use as strike carries the set you pick into the deal, and the negotiation carries the shape (V7).
When to open TOU pricing vs the deal builder vs Firm
| You care about… | Open | Why |
|---|---|---|
| "Which buyer fits my unsold hours?" | Sales Desk (§6) | Fit score, simulate, promote |
| "Is this peak/standard/off-peak multiplier counter good for my plant?" | TOU pricing (this tool) | Shape-weighted effective c/kWh + Δ R/yr |
| "Can I stand behind a firm evening block?" | Firm viability (§6.8) | Physical shortfall risk, not multipliers |
6.7.1 Every concept on this screen
Read these as glossary cards for the labels you will actually see. The full Megaflex hour map lives in V2 §8.2; this section only needs enough clock to price a counter.
TOU — Time of Use
What it is. A clock that splits every SAST hour into one of three buckets: peak, standard, or off-peak. South Africa's common reference is the Eskom Megaflex table (weekday peaks move between high and low season; Saturdays have almost no peak; Sundays are all off-peak).
Why it is in this tool. Multiplier counters price by bucket. Without TOU you only have a flat c/kWh.
Plain reading. "Which tariff period is this hour?"
Peak / standard / off-peak
What they are. The three TOU buckets. On a high-season weekday, peak is morning + evening rush; standard fills most of the working day and shoulder evenings; off-peak is night and late evening. Exact hours: day strips below / V2 §8.2.
Why they matter for a seller. Your plant's energy lands unevenly across the three. Solar: lots of standard, little peak, some off-peak. Wind: often heavy off-peak.
Plain reading. Peak ≠ "when I make money" — it is "when the grid tariff is expensive". Your generation may not match.
Base price (c/kWh)
What it is. The number in the Base price
(c/kWh) input. The starting unit price before multipliers. With
a candidate selected, the drawer opens with the strike you are building,
so every row compares like with like. With none, it starts from the
book's lcoe_ckwh when that is set, otherwise
65.
Why it is in this tool. Every candidate set is
base × multiplier per hour. Change the base and the whole
table recomputes live (phx-change="recompute_tou").
Plain reading. "The flat sticker we are comparing against."
Multiplier set (peak / standard / off-peak)
What it is. Three factors, written like 1.3 / 1.0 / 0.7, meaning pay 1.3× base in peak, 1.0× in standard, 0.7× in off-peak. The table shows each set in one column, Peak / standard / off-peak, in that order. The Sales tab ships three fixed candidates a solar IPP typically weighs:
| Set (pk / std / off) | Story the buyer is telling |
|---|---|
| 1.3 / 1.0 / 0.7 | "Peak premium, off-peak discount" |
| 1.0 / 1.0 / 1.0 | Flat — same as the base |
| 0.9 / 1.1 / 0.7 | "Standard uplift, softer peak, off-peak discount" |
Why it is in this tool. Those three rows are the comparison. The table does not invent other sets on this screen.
Plain reading. "Three price shapes to try on your generation."
Effective price
What it is. The single c/kWh that answers: "If I sold all of this plant's modelled annual generation under this multiplier set, what average price would I actually earn?" Formula in §5.7.3.
Why it is in this tool. Comparing raw multipliers is misleading; effective price folds in when you generate.
Plain reading. "My true average selling price under this counter."
Δ R/yr (delta Rand per year)
What it is. Annual Rand change versus selling the same generation at the flat base (multipliers all 1.0), in whole Rand with comma thousands. Positive = the set beats flat; negative = it loses money vs flat (−R 1,212,181); R 0 for the flat row itself.
Why it is in this tool. A 1 c/kWh gap on tens of GWh/year is real money. The column turns the abstract effective price into a yearly cheque.
Plain reading. "How much richer or poorer than flat, per year."
Best set (narration line)
What it is. The sentence above the table:
Best set: p/s/o — effective N c/kWh (Δ
R/yr vs flat). The engine sorts rows highest
effective first; the top row is tinted emerald
(bg-emerald-50).
Why it is in this tool. Instant answer without scanning every cell.
Plain reading. "Winner for this plant at this base."
Shape / generation profile
What it is. Hour-by-hour how much the plant is expected to make (P50 technology shape × capacity), rolled over a representative SAST year. The advisor weights each hour's price by that hour's kWh.
Why it is in this tool. Two plants with the same base and the same multiplier set can get different effective prices — because their shapes differ.
Plain reading. "When your electrons actually show up."
6.7.2 The Megaflex day — when is peak?
You do not need to memorise every cell. You do need the intuition that evening peak is often when solar is asleep, and midday is usually standard, not peak.
Solar tip: the midday hump (roughly 10:00–16:00) sits in standard on both weekday strips — not peak. A peak multiplier buys hours your panels barely serve; a standard uplift buys the hours you actually sell. Full weekend strips: V2 §8.2.
Generation vs TOU buckets
Represents: solar output under the weekday clock. React: treat a peak-only premium as nearly worthless until you have storage or a different technology; negotiate the standard factor (and resist a deep off-peak cut on night/shoulder energy you still make).
6.7.3 How effective price is calculated
Every hour of a representative year gets:
- a generation amount (kWh) from the plant's P50 shape, and
- a TOU tag (peak / standard / off-peak) from the engine calendar.
For one multiplier set:
Effective price
effective price = Σ (generation(h) × base × multiplier(TOU of h)) ÷ Σ generation(h)
In words: weight each hour's base × multiplier by how
much energy that hour produces, then divide by total energy. Flat
multipliers (1 / 1 / 1) always collapse to exactly the
base.
Display note. The advisor stores effective price to 2 decimals (e.g. 63.89). The table's
ckwh/1formatter may show one decimal on screen (63.9). Δ R/yr shows whole Rand with comma thousands (e.g. −R 486,369). This chapter quotes the 2-dp advisor figures so the arithmetic matches the tests.
6.7.4 How to use the TOU pricing tool
Follow along. Seat: IPP demo user on a solar generator strategy book (
full_demo· seed 42). Path: Generator sites → (site) → Strategy → Sales → TOU pricing. You should see a base input and a three-row table with a "Best set:" line.
Step-by-step
Open Sales, pick a candidate, then click TOU pricing in the Pricing tools bar above the deal builder. The tool opens as a drawer from the right, over the desk; Escape, the X or a click on the dimmed page closes it, and focus returns to the button.
Read the base price. It opens at the strike you are building. Confirm it is the sticker you are negotiating from, or type the one you want to stress.
Optionally type a new base (step 0.1). The table recomputes as you change it — no separate Submit.
Read the Best set line first. That is the winner at this base.
Scan the table top → bottom (already sorted best-first):
Column What to look at Peak / standard / off-peak The row’s three multipliers, in that order Effective (c/kWh) Shape-weighted c/kWh — higher is better for you Δ vs flat, R/yr Yearly Rand vs flat — negative means "worse than flat" Interpret the emerald row. If flat (1 / 1 / 1) is on top, the "attractive" counters lose money on your shape — push back or restructure (raise standard, soften the off-peak cut, or stay flat).
Carry the set into the deal. Use as strike on a row puts that set’s effective price in Strike / price, sets Shape to TOU-shaped, closes the drawer and confirms: Strike set to 58.3 c/kWh, the 1.3 / 1.0 / 0.7 set’s effective price. Then simulate. In the negotiation, price terms that match where your energy lives; do not gift multipliers for hours you do not generate into.
If the conversation turns to a firm evening block (not multipliers), switch to Firm viability (§6.8) — different question.
6.7.5 Worked examples
Data. Advisor maths · representative year 2026 · solar fixture P50 43,800 MWh/yr · 20 MW export (same shape family as IPP-STRATEGY §3.1 /
PricingAdvisortests). Shares below are engine-computed under the live SAST calendar (≈ 13% peak · 64% standard · 23% off-peak for this solar shape).
Example A — base 65 c/kWh, demo solar plant (the screen's headline)
Under the engine's SAST TOU calendar this plant's generation lands ≈ 13% in peak, 64% in standard, 23% in off-peak hours. The three candidate sets:
Worked example — base 65 c/kWh, the demo solar plant
| Set (pk/std/off) | Effective c/kWh | Δ R/yr vs flat |
|---|---|---|
| 1.0 / 1.0 / 1.0 (flat) | 65.00 ✓ | 0 |
| 0.9 / 1.1 / 0.7 | 63.89 | −R 486 000 |
| 1.3 / 1.0 / 0.7 | 63.14 | −R 812 000 |
Both "attractive-looking" sets lose this plant money: the 0.7 off-peak discount applies to ~23% of its generation, which outweighs a peak uplift it can barely generate into (~13%) or a modest standard uplift. The flat price wins — worth roughly R 486k–812k a year over the counters. The general rule the table teaches: never trade away price in hours you actually generate to gain a multiplier in hours you don't. A solar plant should treat a peak multiplier as nearly worthless — it is asleep at 19:00 — and negotiate the standard-hour price instead, where its energy actually lives.
What it means for the seller. Saying yes to 1.3 / 1.0 / 0.7 because "peak is 30% higher" would cost about R 812k/yr versus staying flat at 65.
How to react. Counter with flat, or insist on a higher standard factor and a shallower off-peak cut. Do not treat the peak 1.3 as compensation for the 0.7.
Effective c/kWh by set
Represents: Best-first order on the LiveView table. React: emerald row = flat; walk away from both counters or renegotiate standard / off-peak.
Example B — a tiny day, so the formula is visible
Ignore seasons for a moment. Suppose one day the plant makes exactly 100 kWh in three hours, base 65 c/kWh, set 1.3 / 1.0 / 0.7:
| Hour | TOU | Gen kWh | Multiplier | Revenue contribution (c) |
|---|---|---|---|---|
| 08:00 | peak | 10 | 1.3 | 10 × 65 × 1.3 = 845 |
| 12:00 | standard | 70 | 1.0 | 70 × 65 × 1.0 = 4,550 |
| 23:00 | off-peak | 20 | 0.7 | 20 × 65 × 0.7 = 910 |
| Σ | 100 | 6,305 |
Effective = 6,305 ÷ 100 = 63.05 c/kWh — already below the 65 flat sticker, even though peak paid 1.3×. The 70 kWh at 1.0× and 20 kWh at 0.7× dominate.
What it means. Volume beats brochure multipliers.
How to react. Ask: "What share of my year sits in each bucket?" — which is exactly what the tool answers for the full year.
Example C — same solar plant, raise only the standard factor
The tab's fixed candidates do not include a custom set, but the maths still teaches the negotiation. Using Example A's ~13 / 64 / 23 split as rough weights on base 65:
| Set (pk/std/off) | Rough effective | vs flat |
|---|---|---|
| 1.3 / 1.0 / 0.7 (screen row) | 63.14 (engine) | −R 812k |
| Imagined 1.0 / 1.15 / 0.85 | ~66+ (directionally) | beats flat if standard uplift outweighs the soft off-peak cut |
You do not need the imagined row on screen — the lesson is: move money into the bucket where your MWh live (standard for solar), and stop paying for peak theatre.
How to react in the room. "I'll take a standard uplift; I won't finance your peak story with my off-peak and midday."
Example D — same three sets on a wind-shaped year
Same base 65, same three candidates, but a wind P50 shape at the same annual energy. Engine shares land roughly 15% peak · 32% standard · 53% off-peak — overnight energy is huge.
| Set (pk/std/off) | Effective c/kWh | Δ R/yr vs flat |
|---|---|---|
| 1.0 / 1.0 / 1.0 | 65.00 ✓ | 0 |
| 1.3 / 1.0 / 0.7 | 57.46 | ≈ −R 3.3m |
| 0.9 / 1.1 / 0.7 | 55.77 | ≈ −R 4.0m |
What it means. The 0.7 off-peak discount now hits more than half of generation. Both "peak premium" stories are catastrophic for this shape — worse than for solar.
How to react. Flat (or an off-peak uplift) matters more than peak theatre. Open this site's Sales → TOU pricing rather than copying another plant's spreadsheet. The tab always reweights to your technology shape.
Solar ≈ 13 / 64 / 23
React: protect standard; peak uplift is weak sauce.
Wind ≈ 15 / 32 / 53
React: a 0.7 off-peak cut is existential; do not copy solar counters.
Example E — change the base, ranking stays shape-driven
Type base 80 instead of 65 on the same solar plant. Every effective price scales with the base; flat remains exactly 80.00 and still ranks first against these two discounted sets — the gaps widen in Rand terms because Δ R/yr = (effective − base) × annual kWh ÷ 100.
What it means. Raising the sticker does not rescue a bad multiplier shape; it magnifies the yearly damage of a bad shape.
How to react. Fix the multipliers (or stay flat); do not hope a higher base hides a 0.7 off-peak.
6.7.6 What good looks like — seller cheat sheet
| You see… | It means… | React |
|---|---|---|
| Flat 1/1/1 on top (emerald) | Counters lose vs flat on your shape | Prefer flat, or demand better standard / softer off-peak |
| A non-flat set on top with + Δ R/yr | That shape pays you more than flat | Worth negotiating toward; still Simulate on the desk |
| Big peak multiplier, still losing | Peak hours are a small share of your MWh | Sell the peak story back; buy standard (solar) or off-peak (wind) |
| Wind-like deep negative Δ | Off-peak discount hits most of the year | Reject 0.7-style cuts; reopen with your site's table |
| Numbers ≠ buyer spreadsheet | Different assumed peak/std/off split | Insist on shape-weighted maths (V3 FAQ) |
Rule of thumb. Multipliers are only as valuable as the kWh that touch them. The TOU tab is the scale that weighs those kWh.
6.7.7 Bridges and caveats
- Back to the desk. Once terms look right, Use as strike on the winning row, then Simulate the buyer (§6). The simulation pays that effective price on every kWh as generated: the set’s average over your generation, not the set hour by hour. The TOU-linked shape itself belongs in the real proposal.
- Firm blocks are separate. Evening guaranteed MW is §6.8, not this toolle.
- Candidate sets are fixed on this screen. SalesLive
compares the three solar-weighing sets listed in §5.7.1. Custom multipliers belong in negotiation /
contract terms (
TOU_LINKEDin V7); use this tool to learn which direction helps your shape. - Calendar truth. Effective prices use the engine's SAST / Megaflex classifier — the same family as metering. Older brochure numbers that assumed "solar is ~98% standard" will not match; trust the tool (recorded divergence vs an early spec illustration — the product shows live advisor output).
- Overview context. Why filling unsold volume matters even below a flattering achieved price: §4.
Because the maths is your real shape against the real calendar, run your own numbers — not the brochure's, and not another plant's.
6.8 Firm viability — should I sign a firm block?
Route:
…/generator-sites/<id>/strategy/sales ·
Tab: Sales → Firm viability pricing
tool, a drawer from the right (#sales-firm-tool)
On-screen chrome: intro copy
(#sales-firm-intro) · Firm price (c/kWh)
input · firm-viability card (verdict badge · Expected
margin in c/kWh · Chance the plant falls short
as a percentage · optional Margin with the battery) ·
battery footnote ("Battery marginal N c/kWh applied." / "No
active battery on this site.")
The seller's problem, in plain words
A buyer sometimes wants more than a flat or TOU-shaped price. They want firm power in named hours — for example, "guarantee us power from 18:00–20:00, every weekday we care about." They will often pay a premium for that promise, because their factory / shift needs those hours whether or not the sun is shining.
That premium is only real money if you can physically stand behind it. If your solar plant is asleep at 19:00 and you still signed "firm evening", you must buy replacement energy from the market (or discharge a battery) to honour the contract. Buy-in at 210 c/kWh against a firm sale at 140 c/kWh is not a premium — it is a 70c loss on every short kWh.
The Firm viability pricing tool exists for one job: take a proposed firm evening-block price, compare it to your plant's generation shape in those hours, fold in the book's replacement cost, and tell you — before you sign — whether the deal is:
| Verdict on screen | Plain meaning |
|---|---|
| Accept | The plant can self-generate this block; expected margin is positive |
| Needs storage | As-generated you lose money, but a battery covers the shortfall at a positive margin |
| Decline | Neither self-generation nor storage (if any) makes the block pay |
This tab does not sign a deal. It is a physical + economic check beside the deal builder (§6) and TOU pricing (§6.7). Use it when the conversation turns from "what multiplier?" to "can you guarantee these evening hours?"
When to open Firm viability vs TOU vs the deal builder
| You care about… | Open | Why |
|---|---|---|
| "Which buyer fits my unsold hours?" | Sales Desk (§6) | Fit score, simulate, promote |
| "Is this peak/standard/off-peak multiplier counter good for my plant?" | TOU pricing (§6.7) | Shape-weighted effective c/kWh |
| "Can I stand behind a firm evening block?" | Firm viability (this tool) | Shortfall risk × replacement cost, not multipliers |
6.8.1 Every concept on this screen
Read these as glossary cards for the labels you will actually see.
The engine check behind the card is
PricingAdvisor.firm_block_check/5 (same maths the demo
walkthrough quotes).
Firm / firm block
What it is. A delivery promise for named hours, not "whatever the plant happens to make". On this Sales tab the block is fixed as the evening block: SAST hours 18, 19, and 20 (the card title reads Firm evening block).
Why it is in this tool. Buyers pay for certainty in those hours. Certainty has a physical cost if your plant is dark then.
Plain reading. "I promise those hours — rain or shine (or night)."
Firm price (c/kWh)
What it is. The number in the Firm price
(c/kWh) input. The sticker the buyer would pay for energy in
the firm block. On load the screen seeds 140. Change it
and the card recomputes live
(phx-change="recompute_firm").
What we are ascertaining. "At this offered price, does the economics still work once shortfall risk is priced in?"
Plain reading. "What they pay me per firm kWh."
Replacement cost (c/kWh)
What it is. Your book's assumption for buying market
/ top-up energy when you cannot self-generate a promised firm hour. Seed
default 210.0 c/kWh (replacement_ckwh).
Set it on Overview → ⚙ LCOE / params (§4.3); this tool reads it —
it does not edit it.
What we are ascertaining. "If I am short, how dear is the buy-in that keeps the promise?"
Plain reading. "The pain price when the plant cannot deliver."
Shortfall (in this check)
What it is. An hour inside the firm block where the
plant's modelled generation is too weak to self-firm —
specifically, below half of the plant's peak hourly
output in the representative year (firm_threshold = 0.5).
Those hours would need replacement energy (or battery discharge) if sold
firm.
What we are ascertaining. "In these promised hours, how often is the plant asleep / too quiet?"
Plain reading. "Hours I promised but cannot fill from the panels alone."
P(short)
What it is. The share of block-hour samples (across
the representative year) that fall short by the rule above. Shown on the
card as Chance the plant falls short, a whole
percentage. Solar at 18–20 → typically 100 %
(essentially every sample is short). A strong midday block → 0
%. The formulas in this section write it P(short),
a probability from 0 to 1.
What we are ascertaining. "How often, in probability terms, will I need a replacement plan for this block?"
Plain reading. "Chance I cannot self-cover the promise." · Glossary P(short).
Expected margin (c/kWh)
What it is. The card's headline economics for selling the block as-generated (no battery yet), shown with its sign and unit, −70 c/kWh:
expected margin = firm price − replacement cost × P(short)
Positive → the premium survives the shortfall risk. Negative → every "firm" kWh you cannot generate eats margin (or worse).
What we are ascertaining. "After pricing the expected buy-in, is this block still worth signing on plant alone?"
Plain reading. "My expected cents left after the shortfall tax."
Firm verdict (Accept / Needs storage / Decline)
What it is. The coloured badge on the card (Firm verdict):
| Badge | When the engine picks it | Narration under the numbers |
|---|---|---|
| Accept (green check) | Expected margin > 0 | "The plant can self-generate this block — sell it firm." |
| Needs storage (amber battery) | Expected margin ≤ 0, but price − battery marginal > 0 | "As-generated this block loses money, but a battery covers the shortfall at a positive margin." |
| Decline (red X) | Expected margin ≤ 0 and no positive storage rescue | "The plant can't reliably cover this block and has no storage — decline the firm term." |
What we are ascertaining. "One-glance go / conditional go / stop."
Margin with the battery / battery marginal (c/kWh)
What it is. When a storage cost is known, the card
adds a Margin with the battery line:
firm price − battery marginal. The footnote shows either
"Battery marginal N c/kWh applied." or "No active battery on
this site."
Where the marginal comes from. An active battery
asset on the site (degradation cost as proxy), or —
when you are evaluating adding storage — the book param
bess_marginal_ckwh (solar sites cannot hold a live
BessAsset in domain rules, so the param is how you ask "would a battery
make this work?").
What we are ascertaining. "If I serve the shortfall from storage instead of buying 210c market energy, does the premium still clear?"
Plain reading. "Cost of discharging a kWh from the battery into the promise." · Spreads / stored-marginal idea: V3 §10.2.
6.8.2 The expected-margin formula
Buyers pay a premium for firm delivery in named hours. The premium is only real if your plant can physically stand behind it — and this card checks, before you sign:
Expected margin
expected margin = price − replacement cost × P(short)
where P(short) is the probability your generation falls short in the block's hours (computed from your plant's hourly shape: the share of block-hour samples below half the plant's peak output).
Why multiply by P(short)? If you are short half the
time (P(short) = 0.5), you do not pay full replacement on every kWh —
you pay it on the expected short share. If you are short always (1.0),
the formula collapses to price − replacement — the harsh
evening-solar case.
Display note. The advisor rounds expected margin and BESS margin to 2 decimals; P(short) to 3. The card shows the margins with their sign in c/kWh (
ckwh/1may drop to one decimal) and P(short) as a whole percentage (1.000 reads 100 %). This chapter quotes the advisor figures so arithmetic matches the tests.
6.8.3 How to use the Firm viability tool
Follow along. Seat: IPP demo user on a solar generator strategy book (
full_demo· seed 42). Path: Generator sites → (site) → Strategy → Sales → Firm viability. You should see the intro line about accept / needs storage / decline, a firm-price input at 140, and a card — typically ❌ Decline with Chance the plant falls short 100 % and Expected margin −70 c/kWh when there is no battery.
Step-by-step
Open Sales, then click Firm viability · safe capacity in the Pricing tools bar (shield icon). The tool opens as a drawer from the right; Escape, the X or a click on the dimmed page closes it.
Read the intro (
#sales-firm-intro): it states the three outcomes in one sentence — accept if you can cover it, needs storage if a battery would, decline if neither pays.Confirm replacement cost (if the deal is sensitive). Glance at Overview assumptions / open ⚙ LCOE / params (§4.3) — default 210.0. This tab does not edit it; wrong replacement → wrong verdict.
Read or type Firm price (step 0.1). Default 140. The card recomputes as you change it — no separate Submit.
Read the verdict badge first, then the numbers:
Line What to look at Expected margin As-generated cents after shortfall tax Chance the plant falls short How often the plant cannot self-cover the block Margin with the battery (if shown) Margin if the shortfall is served from storage Read the footnote. "No active battery…" means Decline cannot flip to Needs storage unless you set
bess_marginal_ckwh(or add a battery where the domain allows). "Battery marginal N…" means that cost is already in the Margin with the battery line.Interpret, then act:
Verdict Typical next move Accept Firm term is physically standable — carry price into the deal builder / negotiation Needs storage Do not sign the evening block alone; couple it with a storage decision (or walk) Decline Refuse the firm evening promise, or restructure (different hours, as-generated, or much higher price) If the conversation is only about multipliers (peak / standard / off-peak), switch back to TOU pricing (§6.7) — different question.
6.8.4 Worked scenarios
Data. Advisor maths · evening block hours [18, 19, 20] · solar fixture P50 43,800 MWh/yr · 20 MW export (same family as IPP-STRATEGY §3.3 /
PricingAdvisortests). Replacement 210 c/kWh unless noted. Battery marginal 88.9 c/kWh when storage is in play (M4 stored-marginal illustration).
Scenario A — solar plant, firm evening block, no battery (Decline)
Worked example — solar evening block, no battery
Block 18:00–20:00 at 140 c/kWh,
replacement 210 c/kWh. A solar plant generates
essentially nothing in those hours: P(short) = 1.0, so
expected margin = 140 − 210 × 1.0 = −70 c/kWh
→ ❌ Decline. Every firm evening kWh would be bought back from the market at a 70c loss.
What we ascertained. The premium is fake once shortfall is priced: you sell at 140 and buy at 210 whenever the sun is down — which is the whole block.
How to react. Do not sign firm evening on plant alone. Push as-generated / daytime firm / TOU instead, or bring storage into the conversation (Scenario B).
Daylight vs 18–20 promise
Read it: the firm window sits where the solar area is flat on the floor. React: Decline on plant alone — or open the storage conversation.
Scenario B — same evening block, with a battery (Needs storage)
Worked example — same block, with battery
Same block and prices. If the plant has storage whose marginal discharge cost is 88.9 c/kWh (charge cost, efficiency and degradation included — the §10.2 stored-marginal-cost idea), the block can be served from the battery at
BESS margin = 140 − 88.9 = +51.1 c/kWh
→ 🔋 Needs storage: the deal is good if and only if the battery is part of it. The card still shows Expected margin −70 c/kWh (as-generated unchanged) and Margin with the battery +51.1 c/kWh so the contract conversation and the capex conversation happen together.
What we ascertained. Market buy-in at 210 destroys the deal; battery discharge at ~89 clears a healthy margin — but only if that storage is real (asset or modelled param).
How to react. Sign the firm evening term together with the storage plan, or neither. Do not treat "Needs storage" as a soft Accept.
The battery marginal comes from the site's active battery asset (its
degradation cost) when one exists; a solar site evaluating
adding storage can set the candidate marginal as a book param
(bess_marginal_ckwh) — so "would a battery make this deal
work?" is answerable before any battery is bought.
Scenario C — midday block the plant can self-generate (Accept)
Worked example — midday block
A midday block instead
(11:00–13:00): the plant over-generates those hours,
P(short) = 0, expected margin +140 c/kWh →
✅ Accept.
What we ascertained. Firm is not automatically dangerous — firm evening on solar is. When the promise sits on the generation mountain, P(short) collapses and the full firm price is expected margin.
How to react. Firm daytime / shoulder blocks that match your shape can be Accept at the same sticker that Declines at 18:00. Use the tool's evening check for evening offers; do not assume the same verdict for every named window.
Screen note. SalesLive's Firm tab is wired to the evening block
[18, 19, 20]. The midday Accept case is the advisor's contrast example (same function, different hours) — it teaches why hour choice matters even when the on-screen block is evening-only.
11–13 sits on generation
Read it: promise overlaps the peak. React: Accept — firm here is self-backed.
Scenario D — raise the firm price, evening still Declines
Same solar evening, replacement 210, still no battery. Type firm price 200 instead of 140:
Price nudge at P(short) = 1.0
expected margin = 200 − 210 × 1.0 = −10 c/kWh → still Decline
Even 220 only clears 220 − 210 = +10 →
Accept as-generated — but you are now pricing firm
evening above replacement, which is a different commercial
story (buyer may not pay it).
What we ascertained. A modest premium over LCOE / daytime offers does not rescue a P(short) = 1 evening block while replacement is 210. You need either storage, a much higher firm sticker, or a different block.
How to react. Do not "nudge the price" and hope;
watch whether price actually exceeds
replacement × P(short).
Scenario E — soften replacement cost (LCOE / params dial)
Keep firm price 140, evening solar, no battery. On Overview set replacement from 210 → 120 (stress: "what if buy-in is cheaper?"):
Soft replacement assumption
expected margin = 140 − 120 × 1.0 = +20 c/kWh → Accept
Optimistic replacement turns Decline into Accept without changing the plant.
What we ascertained. The verdict is only as honest as your replacement assumption.
How to react. Change replacement only when the board pack / market view really changed (§4.3). Do not "fix" Firm viability by quietly lowering replacement.
Scenario F — Needs storage flips back to Decline (expensive battery)
Evening solar, price 140, replacement 210, but battery marginal 150 c/kWh:
| Line | Value |
|---|---|
| Expected margin | 140 − 210 × 1.0 = −70 |
| Margin with the battery | 140 − 150 = −10 |
| Verdict | ❌ Decline (storage does not rescue) |
What we ascertained. "Has a battery" is not enough — the marginal must sit below the firm price. An expensive discharge path still declines.
How to react. Fix storage economics or refuse the firm evening term; Needs storage is not automatic.
6.8.5 What good looks like — seller cheat sheet
| You see… | It means… | React |
|---|---|---|
| ❌ Decline, chance of falling short ≈ 100 %, margin ≈ price − replacement | Plant cannot self-cover the block | Refuse firm evening alone; open storage or different hours |
| 🔋 Needs storage, margin with the battery positive, expected still negative | Battery rescues; plant alone does not | Couple contract + storage decision |
| ✅ Accept, chance of falling short ≈ 0 % | Shape covers the promised hours | Firm term is standable; still Simulate on the desk |
| Accept only after you raised price above replacement | Buyer must fund full buy-in avoidance | Confirm they will actually pay that sticker |
| Accept only after you lowered replacement | Assumption changed, not the plant | Document why replacement moved (§4.3) |
| Footnote "No active battery…" and you hoped for Needs storage | No marginal in play | Set bess_marginal_ckwh to model, or add storage where
allowed |
| Attractive evening multiplier on TOU tab, Decline here | Different questions | TOU ≠ firm guarantee (§6.7) |
Rule of thumb. A firm premium is real only when price > replacement × P(short) (as-generated), or when storage clears price > battery marginal. Everything else is theatre.
6.8.6 Bridges and caveats
- Back to the desk. Once the verdict is Accept (or Needs storage with a real storage plan), return to §6 and Simulate the buyer under terms that match — this tool never promotes a proposal by itself.
- TOU is separate. Multiplier counters live in §6.7. Firm viability answers "can I guarantee these hours?", not "which peak factor is best?".
- Replacement lives on Overview. Edit
replacement_ckwhunder ⚙ LCOE / params (§4.3); Firm viability only consumes it. - Evening block is fixed on this screen. SalesLive checks hours 18 / 19 / 20. Midday Accept (Scenario C) is the advisor contrast case — same maths, different hours — not a second dropdown on the tab.
- Threshold is half of peak. An hour is "short" when generation < 50% of the plant's peak hourly sample in the representative year — a deliberate conservative self-firm bar, not a weather forecast.
- Demo seat. full_demo solar often shows Decline at 140 with no battery; Needs storage appears when a marginal is available — V3 §21.
Because the check is your shape against your replacement and (optional) battery marginal, run your own numbers — not the buyer's brochure firm premium.
Captured forecast and realised capture
The hold comparison uses the forecast price weighted by your unsold hours; the whole-day average in the same sentence (…; the whole day averages 93.4 c/kWh.) gives every hour equal weight. A third figure, the capture card Your technology’s realised capture · last 30 days, describes observed market prices in R/MWh. It is historical evidence, not a promise about the hold option, and the verdict never uses it: the verdict names the forecast run it was judged against.
7. Allocation · Rules — the cascade
Thread part 4, continued: when IPP2 Atlantis Wind makes less than its buyers want, who is served first?
Follow along. Seat:
ipp_2@webill.net. Path: Generator sites → IPP2 Atlantis Wind → Strategy → Allocation, mode Rules · hierarchy. You should see the mode switch (Rules · Forecast · Outcomes) with a status note under each, an Explanations button on the right of that bar, the versions rail, the cascade board with Priority, Pro-rata and Fixed buckets flowing into Surplus, and a right-hand rail with Changes vs …, If this draft had been in force in … and Where the cascade runs dry. Explanations (#allocation-explanations-open) opens a right-hand drawer of every abbreviation and term used on Allocation — one alphabetic list from AES through Surplus, including amber reached Surplus — did not run dry.
Data. full_demo · seed 42 · IPP2 Atlantis Wind · stage S07 · last checked 2026-09-03.
The seller’s problem, in plain words
Three buyers hold PPAs on one plant. In a good hour there is energy for all of them and some to spare; in a poor hour there is not. Somebody has to decide, in advance and in writing, who is short. That decision is the allocation hierarchy: every buyer sits in a tier — PRIORITY (ranked, filled in order), PRO_RATA (an equal tier that shares the remainder proportionally), FIXED (a capped entitlement, filled last) — and metered generation cascades down the tiers each hour. Whatever is left is Surplus: unallocated generation, which is exactly the gap the Sales desk sells.
The same cascade runs twice. Settlement runs it on metered energy, hour by hour (§9); the forecast runs it on next month’s expected generation (§8). Rules is where you write it, and it is versioned: publishing writes a new effective-dated version and never recomputes a month that has already settled.
What you want to achieve on this screen
- Put every active PPA’s buyer in the right tier, in the right rank, with the right Fixed entitlement — and see what that rule did last month on the same card.
- Check a draft against reality before publishing: the last settled month re-carved through the draft, member by member.
- Publish with an effective date, and read back what changed against any earlier version.
When to open Rules vs the other modes
| You want to… | Open |
|---|---|
| Change who is served first, or add a Fixed entitlement | Rules (this mode) |
| See what next month’s carve leaves to sell | Forecast (§8) |
| Prove what a settled month actually paid each buyer | Outcomes (§9) |
| Sell the Surplus | Sales (§6) — the Surplus outlet links there |
7.1 The three tiers
Think of the plant's metered generation as a jug of water. Each hour you pour it down three buckets in order. Whatever is left after the third bucket is surplus — not re-offered to hierarchy members in that hour.
Energy flows PRIORITY → PRO_RATA → FIXED → surplus. The table names each step, including surplus. The fixed tier is the shock absorber: it only fills in high-generation hours, which is exactly its commercial intent — and, as you'll see in §5, exactly why its reliability evidence (ARF) reads lower on a tight book.
| Tier | Meaning | Order and basis | How it is served | Short-hour result | What cannot happen | Typical buyer |
|---|---|---|---|---|---|---|
| PRIORITY | Served first, in strict rank order. | Ascending, unique rank | Each rank is filled to its full demand before the next rank sees any energy. | Fill each demand to the running remainder. In a short hour, exactly one priority off-taker can be partially served; every rank below it gets zero. | A lower rank cannot receive while a higher rank is unfilled. | An anchor customer paying for firmness. |
| PRO_RATA | Served second, proportionally. | One equal tier; same-hour demand | Each off-taker receives its share of the tier’s combined same-hour demand from whatever remains. | Apply one scale to every member. Shortfall scales everyone down by the same factor — no one in the tier is preferred. | A member cannot take another member’s proportional share. | A portfolio buyer comfortable sharing risk. |
| FIXED | Served last, up to a fixed entitlement. | After pro-rata; fixed entitlement | Each holds a defined kWh/h entitlement. On shortfall all entitlements scale down together; the entitlement is also a cap — a FIXED off-taker never receives more, even when surplus exists. Additionally capped at actual demand. | Scale entitlements, then cap at actual demand. | A member cannot receive above its entitlement just because surplus exists. | A baseload block priced for interruptibility. |
| Surplus | Unallocated generation left after the three tiers. | After all three tiers | Keep the remaining generation. | Keep the remaining generation. | It is not re-offered to a hierarchy member in that hour. | None — leftover is yours; the Sales desk sells it. |
PRIORITY — "me first, in order"
What it is. A ranked queue. Rank #1
is filled to demand before #2 sees a single kWh. Ranks
are unique and contiguous after every edit (the board renumbers
1..n automatically).
When to use it. Anchor / firmness buyers who paid for being ahead of the pack.
Short-hour picture. At most one priority member is partially served; everyone below that rank gets zero.
FIXED — "a capped block, last"
What it is. Served after pro-rata, up to a typed entitlement (kWh/h). On shortfall, entitlements scale together; even in surplus a FIXED member never receives above entitlement (and never above actual demand).
When to use it. Interruptible baseload — cheap energy that is honest about being the shock absorber.
Short-hour picture. Fills only when priority + pro-rata left something; often zero on tight hours (which is why ARF looks lower on a tight book — §5).
Surplus — "what remains yours"
What it is. Generation left after all three tiers are served. It is not poured back into hierarchy members that hour.
What we are ascertaining. "After honouring the published rulebook, how much is still mine to sell / spill / market?"
Plain reading. "Leftover after the rulebook."
7.2 Each tier in isolation — worked
Before composing them, see how each rule divides the same shortage. Three off-takers — A demands 600, B 500, C 400 MWh (total 1,500) — but the plant injects only 1,000 MWh. Same inputs, three very different splits:
PRIORITY maths (same shortage)
A rank 1 → min(600, 1000) = 600 (full)
B rank 2 → min(500, 1000 − 600) = 400 (partial)
C rank 3 → min(400, 0) = 0 (starved)
Rank is everything. Exactly one member can be partial; everyone below gets nothing.
PRO_RATA maths (same shortage)
scale = 1000 / 1500 = ⅔
A → 600 × ⅔ = 400
B → 500 × ⅔ ≈ 333
C → 400 × ⅔ ≈ 267
Basis is same-hour demand — a bigger consumer automatically gets a bigger share of the remainder.
FIXED maths (same shortage)
entitlements 500 + 500 + 500 = 1,500
scale = min(1, 1000/1500) = ⅔
each → 500 × ⅔ ≈ 333
Equal entitlements → equal split; unequal entitlements scale proportionally, then each is still capped at actual demand.
- PRIORITY: A is made completely whole (600), B takes
what's left (
min(500, 1000−600) = 400), C gets nothing. Rank is everything. - PRO_RATA: everyone is scaled by the same factor
1000/1500 = ⅔. A's share is600/1500 = 40%of the pool → 400 MWh. The basis is same-hour demand, so the split needs a single pass — a bigger consumer automatically gets a bigger share. - FIXED: entitlements (500 each, total 1,500) scale
by
min(1, 1000/1500) = ⅔→ 333 each. With equal entitlements this is an equal split; unequal entitlements scale proportionally.
PRIORITY protects the top
Read it: C is fully starved so A stays whole. React: only put buyers here who paid for that privilege.
PRO_RATA shares the haircut
Read it: pain is proportional to demand. React: default home for peer portfolio buyers.
7.3 The cascade board — every field and control
The board is the rule drawn as the thing it is: generation enters at the top and falls through three tier buckets into Surplus, with remainder flows down between them. When a settled month exists, its metered generation heads the board and each bucket shows what it took; each member card carries an outcome bar for the same month, so a rule and its result sit together.
Layout at a glance
| Region | What it holds |
|---|---|
| Mode switch | Rules · Forecast · Outcomes, each with a status note (Rules: n unpublished change(s) or in force vN; Outcomes: the last settled month and whether it conserved) |
| Versions rail | One chip per published version — vN, the effective window, member count — with the in force version marked and the selected one ringed; a dashed draft chip appears when there are unpublished changes |
| Effective date · Reset · Publish vN+1 | The controls on an editable seat; a Read-only badge otherwise. Publish is disabled while nothing has changed (§7.4) |
| The cascade | 1 · Priority (ranked), 2 · Pro-rata (equal tier), 3 · Fixed (capped entitlement) buckets, then the amber Surplus outlet with unallocated generation — available for sale and Sell the gap → Sales |
| Changes vs … | Added · Removed · Re-ranked / re-tiered — what Publish would write. The heading names the version and its start date, for example Changes vs v1 (from 1 Jan 2026) |
| If this draft had been in force in … | The last settled month re-carved through the draft: actual, under draft, Δ per member, plus the Surplus row and a conservation check |
| Where the cascade runs dry | For each hour of a typical day in the last settled month, the tier in which generation was exhausted — buyers below it got nothing. Taught in §7.9 |
The last settled month on this page — on the member cards, in the draft preview and in the dry strip — is the last completed month with a settled period. It is never the current month, which is still running, and never a later draft period dated ahead: in September 2026 it is August, not October.
Moving members — three equivalent gestures
- Drag a card between buckets, or within Priority to re-rank.
- Arrows on the card move it up or down a tier (and up or down a rank in Priority).
- Type a Fixed entitlement inline (kWh per hour) — required, and greater than zero, for every card in the Fixed bucket.
Every gesture updates the draft chip, the Changes panel and the preview at once. Nothing is written until Publish.
Every field on a member card
| Field | Meaning |
|---|---|
| Off-taker name + PPA reference | One card per buyer; a buyer with two PPAs on this plant is still one card |
| Rank badge (#n) | Priority only; the board renumbers 1..n as you drag |
| Contracted (MWh/yr) | The PPA’s allocated energy |
| Trailing demand | What the buyer actually drew in the last settled month |
| Entitlement (kWh/h) | Fixed only — the hourly cap the tier scales |
| Outcome bar | Share of the buyer’s demand met in the last settled month, from Outcomes. The line above it reads {month} share {energy} · {share}% · ARF {ratio} |
| ARF | Hover or focus the dotted ARF for Allocation
Reliability Factor: the share of this buyer’s demand the month actually
met (allocated ÷ demand). The ratio after it is that share as a
decimal (0.93) — ARF |
| added by contract cue | The card came from membership sync when a PPA went active, not from a publish |
Claim-draft when the board is empty
A plant with active PPAs and no published hierarchy shows No hierarchy yet and seeds a draft from the PPAs’ own allocation rules, one card per buyer. Publish it to put a first version in force; until then settlement carves on the contracts’ claims and the Rules status note says so.
7.4 Draft, preview, publish
Publish workflow (step-by-step)
- Move cards and set entitlements. The dashed draft chip counts the changes; Changes vs vN lists them.
- Read If this draft had been in force in month. Each member shows what it actually received, what it would have received under the draft, and the Δ; the Surplus row shows what the change frees or consumes; the conservation line proves the re-carve still sums to the meter. When the draft matches the in-force version the panel says so.
- Read Where the cascade runs dry (§7.9). It is the last settled month’s typical day under the rule that was in force then — not a preview of this draft. The draft check is the panel above it. If a buyer sat below the tier where that hour ran dry, they got nothing in that hour.
- Set Effective (defaults to today). A version effective mid-month governs settlement from that day; earlier days stay on the previous version.
- Click Publish vN+1. It reads Publishing… while it works. Validation marks any card that blocks it (A fixed entitlement greater than zero is required; This off-taker already appears in the hierarchy). On success the flash reads Published a new hierarchy version, the chip becomes solid and in force, and the Outcomes note updates.
Publish is disabled while nothing has changed. Hover it for No changes to publish. Edit a rule, rank or entitlement first. Changing only the Effective date is not a change: move a card, re-rank it or edit an entitlement first. The first version of a hierarchy can always be published, because there is nothing in force to compare it with.
Reset discards the draft back to the selected version. There is no Remove control: a buyer leaves the board when their PPA leaves the active set and membership sync (or a later publish) drops them — the Removed column records that.
7.5 Versions and effective dates
Every version is immutable. The rail orders them by effective date; click a chip to select it and the Changes panel diffs the draft against that version instead of the in-force one. Outcomes links back here with the version that was in force when a settled month started (Carved under v3 · in force at period start), and the Forecast records the version reference it ran under.
Version chip window
Each chip shows vN, the window (from 1 Jan 2026* or 1 Jan → 14 Mar 2026) and the member count. Only one version is in force at a time; the others are history.
Changes panel (Added / Removed / Re-ranked · re-tiered)
Three columns, each a list of buyer names, under a heading that names the version compared against and the day it started — Changes vs v1 (from 1 Jan 2026). Added and Removed compare membership; Re-ranked / re-tiered lists buyers whose tier, rank or entitlement differs from the selected version.
Removed members
A buyer on the selected version who is not on the draft appears under Removed. That is a record of membership sync, not an action you took on the board; to bring a buyer back, their PPA must be active.
7.6 Worked scenarios
> Data. Illustrative one-hour carves · same family as §6.1–§6.2 · > full_demo / Atlantis Wind narrative where named. Generation and > demand in MWh for readability.
Scenario A — short hour, priority protects the anchor
Setup. Generation 90. Priority rank 1 demands 40. Pro-rata buyers together demand 80. Fixed holds a 20 kWh/h entitlement.
| Stage | What happens | Result |
|---|---|---|
| PRIORITY #1 | Fill 40 | 50 remains |
| PRO_RATA | Share 50 across 80 of demand | ~18.75 + ~31.25 |
| FIXED | Nothing left | 0 |
| Surplus | 0 | — |
What we ascertained. The anchor is whole; peers share the leftover; fixed absorbs the entire shortfall (gets nothing).
How to react. If fixed was sold as "almost firm," the commercial story is wrong — either re-tier, reprice, or set expectations with the Allocations / Forecast evidence (§9, §8).
Scenario B — plentiful hour, fixed finally fills
Setup. Same hierarchy, generation 200. Priority 40 + pro-rata 80 = 120 consumed; 80 remains for fixed (capped by entitlement and demand).
What we ascertained. Fixed is a high-generation seat. Reliability metrics for FIXED will look worse than PRIORITY on a tight book — that is the design, not a bug (§5).
How to react. Use FIXED for interruptible baseload pricing, not for customers who need evening certainty.
Scenario C — first publish from claim-draft
Setup. New generator, two active physical PPAs for two different buyers, no published hierarchy yet. Open Hierarchy.
What you see. Two cards (one per buyer), both defaulting to PRO_RATA. Empty version bar: No published versions yet. Diff compares against "the current draft" baseline story.
What we ascertained. Claims seeded the board so you are not publishing into a vacuum — but settlement still waits for Publish.
How to react. Move the anchor to Priority, set any Fixed entitlements, set Effective, Publish. Then check Allocations after the next settled period.
Scenario D — two PPAs, one buyer → one card
Setup. Buyer A holds two active physical PPAs on the same generator. Membership sync / claim-draft runs.
What you see. One member card for
Buyer A (not two). The backing physical_ppa_id prefers the
PPA already on the in-force hierarchy when present.
What we ascertained. The waterfall is per off-taker, not per contract line. Duplicate buyer rows would break the "appear only once" publish rule.
How to react. Do not expect a second card for the second PPA. Adjust tier once for that buyer; commercial energy still settles through the claims engine with that single hierarchy seat.
Scenario E — mid-month re-version
Setup. Version V1 in force from the 1st. On the 15th you publish V2 (Effective = the 15th) that promotes a peer into Priority #2.
What we ascertained. Hours 1–14 keep V1's carve; hours from the 15th use V2. Superseded V1 remains readable and is the version settlement selects for any historic hour inside its window.
How to react. Prefer Effective dates that match the commercial promise ("from the 1st of next month") so month reports are easier to explain. Use the version bar + diff before publish so legal / commercial sign off on the story.
Scenario F — drag vs click, same outcome
Setup. Card in Pro-rata; you want it in Priority as the new #1.
| Gesture | Steps |
|---|---|
| Click | Press → Priority on the card, then drag it to the top
of Priority |
| Drag | Drop the card onto the Priority bucket, then drag within Priority to rank #1 |
What we ascertained. Both paths update the same draft; Publish is still required. Viewers cannot do either.
How to react. Use whichever gesture fits the device — click on a precise desktop pass; drag when rearranging several seats at once.
A · tight (90)
Read it: fixed gets nothing. React: sell FIXED as interruptible.
B · plentiful (200)
Read it: same rulebook, kinder hour. React: surplus is not "extra FIXED."
7.7 What good looks like — reading the Rules board
You opened Allocation → Rules · hierarchy. You need to know whether the picture is healthy enough to publish, or to explain to a buyer.
Think of the board as a seating plan for one dinner service. Each card is one guest. The three buckets are the tables, in serving order. A healthy plan has every guest at the right table, a published version in force, and no red error on a card. The kitchen (settlement) cooks from the published plan, not from the scribbles you have not saved.
Follow along. Seat:
ipp_2@webill.net. Path: IPP Sites → the generator → Strategy → Allocation → Rules · hierarchy. Address:/org/generator-sites/<id>/strategy/hierarchy.
The healthy picture
All of these can be true at once:
- The Versions rail shows at least one chip. One chip has the green in force badge. That version is the rule settlement uses for hours in its window.
- The mode note on Rules · hierarchy reads in force · no unpublished changes (or read-only if you may only look).
- Every active buyer has one card. Cards sit in 1 · Priority, 2 · Pro-rata, or 3 · Fixed for a reason you can say out loud (§7.1).
- Every card in Fixed has an entitlement greater than zero (kWh per hour). That number is the cap for that buyer in that tier.
- If a month has already settled, each card can show a small share bar for that month, and the right rail shows Where the cascade runs dry (§7.9).
If a dashed draft chip is showing, the seating plan on screen is not yet the published one. Read Changes vs …, then Publish.
flowchart LR
A[Look at the board] --> B{Does it match the healthy picture?}
B -->|yes| C[You can explain the rule]
B -->|no| D[Use the pictures below]
D --> E[Fix the cards]
E --> F[Publish]
Twelve pictures you will actually see
Each block is one screen state. The words in italics are the product’s own copy.
1 · First time — no published rule
You see. No published versions yet. Or the dashed empty: No hierarchy yet. Active physical PPAs on this generator appear here as off-taker cards (one per buyer); publish to put a version in force.
It means. You have not published a version. Active contracts may still place cards on the board so you are not starting from a blank page. Settlement does not treat that as an in force hierarchy until you Publish.
Do this. Put anchors in Priority. Put interruptible buyers in Fixed and type their kWh/h. Set Effective. Click Publish.
2 · Every card sits in Pro-rata
You see. The Priority and Fixed buckets are empty. Every card is in 2 · Pro-rata.
It means. A newly active contract joins here by default. That is the equal-share table, not a mistake.
Do this. Move the buyer who paid to be first into Priority. Move the buyer who accepted a cap into Fixed. Leave peers in Pro-rata.
3 · Two contracts, still one card
You see. One buyer name, one card, even though they hold two physical PPAs on this plant.
It means. The waterfall is per buyer, not per contract line. Two cards for the same buyer would fail publish (This off-taker already appears in the hierarchy.).
Do this. Edit that one card. Look up the second contract on the deal, not on this board.
4 · Red text on a Fixed card
You see. A red message on the card: A fixed entitlement greater than zero is required. The flash may say Fix the highlighted cards before publishing.
It means. Fixed is a capped block. Zero or blank is not a cap.
Do this. Type a kWh per hour greater than zero. Click away from the box. Publish again.
5 · Red text "already appears"
You see. This off-taker already appears in the hierarchy.
It means. The same buyer is on the draft twice.
Do this. Publish stays blocked until that buyer appears once. There is no Remove button. Reset puts the selected version back on the board if you cannot see how the second seat appeared.
6 · A dashed draft chip
You see. A dashed chip labelled draft, with n change(s) and unpublished. Changes vs … lists Added, Removed, or Re-ranked / re-tiered.
It means. The board on screen is not the in force version. Nothing has been written yet.
Do this. Read the Changes list. Read If this draft had been in force in month when it appears. Then Publish, or Reset to throw the draft away.
7 · Names under Removed
You see. Buyer names in the Removed column of Changes vs ….
It means. The version you compared against still had those buyers. The draft does not. That usually happens after their contract left the active set. You did not press a Remove button — there is none.
Do this. Treat it as a record, not a command. To bring a buyer back, their physical PPA must be active again. See Removed members.
8 · You are looking at an old version
You see. An in force badge on a chip whose window has an end date, or a selected chip that is not the open-ended one.
It means. You are reading history. Edits you publish will still be a new version; they do not rewrite the old chip.
Do this. Click the open-ended in force chip before you arrange today’s rule.
9 · Read-only badge
You see. An eye icon and Read-only. No Publish, Reset, or Effective date.
It means. This session may look, not edit.
Do this. Ask someone with an editor seat to publish.
10 · Outcomes disagrees after you published
You see. Outcomes · settled still shows last month’s split. It does not match the new board.
It means. Outcomes replays hours that already settled. Each hour uses the version that was in force in that hour. Publishing never recomputes a settled month. The page subtitle says so.
Do this. Check the Effective date you published. Open the version link on Outcomes. The hour-by-hour proof is §9.
11 · No dry-strip yet
You see. A dashed card: No settled month yet. Once settlement has run, each card shows its result, this rail previews the draft against real generation, and the exhaustion strip appears. Cards may say no settled month yet.
It means. There is no last settled month to colour Where the cascade runs dry.
Do this. Wait until a month settles. The strip is taught in §7.9.
12 · The dry-strip is there
You see. Where the cascade runs dry, twenty-four cells with 0h and 23h under the strip, and the legend on its own line below: Ran dry in: ■ Priority ■ Pro-rata ■ Fixed · ■ reached Surplus — did not run dry. Some cells may be slate grey.
It means. Each cell is one clock hour of a typical day in the last settled month. Grey hover is no settled hour. Amber reached Surplus — did not run dry means leftover existed that hour — yours, not re-poured into Fixed. Do not read amber as a warning that the jug emptied.
Do this. Read §7.9. Do not treat a grey cell as a fourth tier.
7.8 Limits you should know
These are how the screen is built. They are not bugs. Each block is one limit, in the order you will bump into it.
1. Moving a card is not live yet
The board you drag is a draft. Settlement still uses the published version that is in force for that hour.
Publish writes a new version with an Effective date. Until that succeeds, and until that date covers the hour, nothing in settlement changes. Reset throws the draft away and puts the selected version back on the board.
2. This screen writes the rule. Outcomes shows the receipt
| Screen | Mode | Job |
|---|---|---|
| This page | Rules · hierarchy | Write who is served first, second, last |
| Same Allocation tab | Outcomes · settled | Show what a settled month actually paid |
| Same Allocation tab | Forecast · next month | Show what next month’s expected generation leaves to sell |
Outcomes does not rewrite itself when you drag a card. §9 is the receipt. §8 is the next month.
3. One buyer, one card
The waterfall is per buyer (the off-taker), not per contract line.
If a buyer holds two physical PPAs on this plant, you still see one card. Publish refuses a second seat for the same buyer.
4. New buyers start in Pro-rata
When a physical PPA becomes active, the new card lands in 2 · Pro-rata. The card may show added by contract.
That is the default equal-share table. If they paid for Priority or accepted a Fixed cap, move them on purpose, then Publish.
5. Fixed cannot take leftover
A Fixed buyer’s entitlement (kWh per hour) is a ceiling.
Even when the plant makes more than the book, Fixed never receives above that ceiling (and never above that hour’s actual demand). What is left after all three tiers is Surplus. Surplus is not poured back. The Sales desk sells it (§6).
6. "Trailing demand" is last month’s draw
The card can show how much that buyer actually used in the last settled month. That is a hint for you while you arrange seats.
The hour that later settles uses that hour’s demand (and, for Fixed, the entitlement cap). Trailing demand is not a target you type.
7. Effective is a calendar day
The Effective date is a calendar day. In the publish path it starts at midnight UTC of that date.
A version that starts on the 15th governs from that day. Hours before the 15th stay on the previous version. Prefer the first of a month when you want one story for the whole month.
8. Viewers can look, not publish
A Read-only session sees the board and the rails. It does not get Publish, Reset, or the date box.
Ask an editor seat to change the rule.
9. The dry strip is last month, not this draft
Where the cascade runs dry colours the last settled month.
Dragging a card does not recolour it. The what if is the panel If this draft had been in force in month. The strip is taught in §7.9.
10. Buyers leave when the contract leaves
There is no Remove button.
When a buyer’s physical PPA is no longer in the active set, the next update of the board drops them. They then appear under Removed when you compare against the older version.
If a draft still shows a struck-through card from an old version, Publish will fail until that seat is dropped. See Removed members.
7.9 Where the cascade runs dry
The board in §7.1 writes the order. This rail answers a narrower question: in a typical hour of the last settled month, how far down that order did the plant’s energy actually go?
Think of the same jug. Each hour you pour PRIORITY → PRO_RATA
→ FIXED → Surplus. When the jug is empty, whoever still waits
below that point gets nothing. The product names that moment Where the cascade
runs dry (#hierarchy-exhaustion). The
twenty-four coloured cells under the heading are the exhaustion strip
(#hierarchy-exhaustion-strip). They are not a second
rulebook, and they are not the draft preview.
This is not the market debit-note cascade (someone else’s unpaid invoice). It is this plant’s Global Allocation Hierarchy waterfall.
Follow along. Seat:
ipp_2@webill.net(passwordsupersecret). Path: IPP Sites → pick the generator → Strategy → Allocation (the tab opens Rules · hierarchy). Address:/org/generator-sites/<id>/strategy/hierarchy. You should see the heading Where the cascade runs dry on the right-hand rail when a settled month exists, or the dashed No settled month yet card if none has.
Data. full_demo · seed 42 · IPP2 Atlantis Wind · last settled month on that plant · last checked 2026-09-14. The four-hour numbers below are the same illustrative family as §7.6 and the Outcomes 640 kWh gate — they teach the colour rule, not a seeded Atlantis strip.
How you open this screen
- Open IPP Sites in the org sidebar, then the
Sites directory
(
/org/ipp-sites/sites). - Open the generator and choose Strategy. The plant’s six tabs are Overview · Sales · Allocation · Curtailment · Plant · Dashboard (§3.2).
- Click Allocation. That tab always lands on
Rules · hierarchy
(
#allocation-mode-rules). The address is/org/generator-sites/<generator-site-id>/strategy/hierarchy. Hover the tab for the product hint: Rules: how generation is carved across off-takers · Forecast: next month’s carve · Outcomes: who got what, settled. - Stay on Rules · hierarchy. The page heading is Allocation rules. The mode note reads Rules decide who is served when the plant generates; publishing never recomputes a settled month.
- On a wide screen the cascade board is on the left. The right rail stacks Changes vs …, then If this draft had been in force in month, then Where the cascade runs dry. On a narrow screen those blocks stack under the board.
The same strip also sits under Allocation by hour in
Outcomes · settled
(#ipp-allocations-exhaustion).
Where this is taught. Hour-by-hour members, the waterfall table and conservation live in §9. This section teaches the Rules-rail card only.
What “runs dry” means, in product language
§7.1 already names the four steps. This card does not repeat that table. It only asks: which of those four steps was the last one that received energy in that hour?
| Last step that received energy | Product tooltip (hover a cell) | Who went without |
|---|---|---|
| Surplus left over | every tier served — surplus left over | Nobody in the hierarchy. Leftover is yours. |
| FIXED received some, Surplus is zero | ran dry in Fixed | The jug emptied while filling Fixed. Fixed may be partial. |
| PRO_RATA received some, Fixed received none | ran dry in Pro-rata — Fixed got nothing | Every Fixed buyer got zero that hour. |
| PRIORITY only — or nothing allocated | ran dry in Priority — lower tiers got nothing | Pro-rata and Fixed got zero. |
The page heading is Where the cascade runs dry — which tier, at which clock hour — not a calendar date. The intro sentence on the card is:
For each hour of a typical {month} day, the tier in which generation was exhausted. Buyers below that tier got nothing in that hour.
{month} is the last settled month’s label, such as
Jun 2026 (%b %Y on that month).
A purple Priority cell does not mean Priority failed. It means the jug ran out inside Priority: rank 1 may be whole, a lower Priority rank may be partial, and everyone below Priority is empty. That is the short-hour picture already in §7.1.
An amber reached Surplus cell means the cascade did not run dry. Every tier that asked was served, and leftover remains. The legend prints that colour as ■ reached Surplus — did not run dry so amber is not read as a warning. Hover still says every tier served — surplus left over.
What the card actually shows
Panel: #hierarchy-exhaustion ·
Strip: #hierarchy-exhaustion-strip ·
data-role="exhaustion-strip"
There is no table on this card. There is a heading, one sentence of help, twenty-four cells, and a legend.
| Piece | What it is |
|---|---|
| Heading | Where the cascade runs dry |
| Help line | The typical-day sentence above, with the settled month named |
| Strip | Twenty-four short cells in a row, one per SAST (South African Standard Time) clock hour |
| Left label | 0h, under the first cell |
| Right label | 23h, under the last cell |
| Legend | On its own line under the hour labels, wrapping if the card is
narrow: Ran dry in: then ■ Priority
(violet) · ■ Pro-rata (blue) · ■ Fixed
(teal) · ■ reached Surplus — did not run dry
(amber) |
| Hover | {hh} · {tooltip} — hour labels are 00h …
23h, for example
19h · ran dry in Pro-rata — Fixed got nothing |
Slate grey is not a fifth tier. Hover reads no settled hour: that clock time has no settled interval in the month, so there is nothing to colour.
The strip has no click action. It does not open Outcomes, does not select a version, and does not change when you drag a card.
flowchart TB
A[Last settled month on this generator] --> B[Each settled hour: last tier that received kWh]
B --> C{Surplus greater than zero?}
C -->|yes| D[reached Surplus — did not run dry]
C -->|no| E{Fixed received any kWh?}
E -->|yes| F[ran dry in Fixed]
E -->|no| G{Pro-rata received any kWh?}
G -->|yes| H[ran dry in Pro-rata — Fixed got nothing]
G -->|no| I[ran dry in Priority — lower tiers got nothing]
D --> J[Group hours by SAST clock 0–23]
F --> J
H --> J
I --> J
J --> K[Most common colour wins that cell]
K --> L[Grey if that clock hour never settled]
The same steps in words:
- Take every settled hour of the latest completed month — before the current one — that has a non-reversed settlement period on this generator’s physical PPAs.
- For that hour, look at how much went to Priority, Pro-rata, Fixed and Surplus (generation minus those three).
- Colour the hour by the deepest step that received any energy: Surplus if leftover exists; else Fixed if Fixed received any; else Pro-rata if Pro-rata received any; else Priority.
- Convert the hour to SAST (UTC plus two hours) and drop it into one of the twenty-four clock buckets.
- If several calendar days share the same clock hour, the cell shows the most frequent colour. That is what a typical {month} day means — not an average of kilowatt-hours, and not one named date.
- A clock hour with no settled interval stays grey.
How this sits next to PRIORITY / PRO_RATA / FIXED / Surplus
The §7.1 table stays the home for the four steps. Here it is only the legend behind the colours:
- A Priority cell is a short hour of the kind §7.1 already described: at most one Priority member is partial; Pro-rata and Fixed are empty.
- A Pro-rata cell means Priority was filled and the remainder was shared; Fixed is empty. Peers in Pro-rata share the haircut.
- A Fixed cell means the shock absorber finally saw energy, but nothing was left as Surplus. Fixed is still capped by entitlement and demand — leftover, if any, would have been Surplus, not extra Fixed.
- A reached Surplus cell is the plentiful-hour story: leftover stays yours. Sales sells it (§6).
The draft preview (If this draft had been in force in
month) is the what if. This strip is the
what did. Changing a tier, rank or entitlement updates the
preview when the draft differs from the in-force version. It does
not recolour #hierarchy-exhaustion.
Empty and edge states
| You see | When the code renders it |
|---|---|
| Dashed No hierarchy yet. Active physical PPAs on this generator appear here as off-taker cards (one per buyer); publish to put a version in force. | The draft has no member cards. The whole cascade-and-rail grid, including this card, is hidden. |
Dashed #hierarchy-no-outcomes: No settled month
yet. Once settlement has run, each card shows its result, this rail
previews the draft against real generation, and the exhaustion strip
appears. |
There are cards, but this generator has no latest settled month, or that month has no hourly rows. |
#hierarchy-exhaustion with a mostly grey strip |
A month settled, but only some clock hours have intervals (a short test month does this). Hover those cells: no settled hour. |
Heading names Jun 2026 (or another
%b %Y) |
That is the latest settled month, not the month you picked on Outcomes. Rules always loads the latest completed month with a settled period — never the current month or a draft period dated ahead. |
There is no empty sentence inside the strip itself. Grey cells are the empty state for a clock hour.
Read-only viewers see the same card. Publishing is hidden; the strip is not.
Worked four hours — how a cell gets its colour
Data. Illustrative · four UTC hours on 1 Jun 2026 · generation 60 / 135 / 205 / 240 kWh · same conservation family as the Outcomes 640 kWh gate (
60 + 135 + 205 + 240 = 640). SAST is UTC+2, so06:00UTC is 08h on the strip.
| UTC hour | SAST cell | Priority | Pro-rata | Fixed | Surplus | Colour and tooltip |
|---|---|---|---|---|---|---|
| 06:00 | 08h | 60 | 0 | 0 | 0 | Priority · ran dry in Priority — lower tiers got nothing |
| 09:00 | 11h | 75 | 60 | 0 | 0 | Pro-rata · ran dry in Pro-rata — Fixed got nothing |
| 12:00 | 14h | 75 | 100 | 30 | 0 | Fixed · ran dry in Fixed |
| 13:00 | 15h | 75 | 100 | 50 | 15 | reached Surplus · every tier served — surplus left over |
Conservation still holds in each row: allocated + surplus = generation. The strip does not print those kilowatt-hours. Hover the cell for the tier sentence; open Outcomes for the numbers.
If June had thirty days and twenty of the 19h cells ran dry in Priority, the 19h cell on Rules is Priority — even if ten evenings reached Surplus. The typical day is a vote, not a blend.
What good looks like
You can point at a clock hour and say which allocation tier was the last to drink, and therefore which buyers were empty. You have not published anything. If you want a different typical evening, you still move cards, read the draft preview, then Publish.
Previously in the thread → V3 §21 · demo walkthrough (and the deal that populated this hierarchy in V7 §7). Next in the thread → V9 §12 · worked delivery day.
8. Allocation · Forecast — next month’s carve
Thread part 4, continued: before IPP2 Atlantis Wind promises anything for next month, what will the plant make, who is owed what, and what is left?
Follow along. Seat:
ipp_2@webill.net(passwordsupersecret). Path: Generator sites → IPP2 Atlantis Wind → Strategy → Allocation, mode Forecast · next month. Address:/org/generator-sites/<id>/strategy/forecast. You should see the sticky mode bar (Rules · hierarchy · Forecast · next month · Outcomes · settled) with Explanations on the right, the page heading Next month’s carve, a month picker, then one headline sentence over a five-column bridge, the cascade table beside two rails, and Forecast said, settlement did beside Rolling outlook. Weekly skill, Compare providers, and Grid Code packs are not on this page — they live on Dashboard under Forecast evidence (§12.6).
Data. full_demo · seed 42 · IPP2 Atlantis Wind · stage S07 · last checked 2026-09-14. Sections §8.2, §8.3, §8.4 and §8.6 are one running example (same plant, same nine-buyer book, numbers that carry forward). August 14,208 MWh and December 17,500 MWh are the documented engine receipt (the same figures the Forecast tests stamp). Your seeded month may differ in absolute MWh; the reading pattern stays. §8.5 is the picker and versions — it is not part of that arithmetic.
The seller’s problem, in plain words
A buyer's adviser will ask three things before they sign: what the plant will make next month, what the existing book will take, and what is left to sell. If those answers use a friendlier split than settlement will later apply, the report is a guess.
Forecast is that report. Think of next month's expected generation as a jug of water. The published allocation hierarchy is the order of glasses. Forecast pours the jug once, on paper, before the month starts. Rules writes the order. Outcomes later proves what the meter actually poured.
The runner writes the report on the 5th of each month. Re-run writes a new version. Old versions stay readable. The page never recomputes in the browser — it reads the stored monthly forecast.
What you want to achieve on this screen
- Read one sentence that says expect / owe / leftover (or shortfall).
- See the same cascade Rules published, applied to next month's FG (Forecasted Generation).
- Know whether to freeze sales, hold, or pass leftover through HAF (Historical Availability Factor) before Sales.
- Audit which hierarchy version and which forecast version you are looking at.
When to open Forecast vs the other modes
| You want to… | Open |
|---|---|
| Know what is left to sell next month, and at what confidence | Forecast (this mode) |
| Change who is served first | Rules (§7) — the report records which version it ran under |
| Check what a settled month actually delivered | Outcomes (§9) — the Forecast said, settlement did card on this page links there |
| Discount leftover into safe contractable energy | The capacity widget on Sales (§5); the verdict here is before that discount |
flowchart LR
A[Rules · write the order] --> B[Forecast · pour next month on paper]
B --> C[Outcomes · prove a settled month]
B --> D[Sales · price what is left]
- Publish who drinks first on Rules.
- Open Forecast for the month you might sell.
- If leftover exists, take it to Sales (and HAF) — do not treat the leftover as a firm contract volume.
- After the month settles, Outcomes is the receipt. The drift card on Forecast already points there.
How this chapter is arranged
- §8.1 is the page: mode bar, picker, headline, cascade, rails, then the two side cards.
- §8.1.8 and §8.1.9 are those two side cards — what they are for, what the numbers mean, what to do.
- Weekly Forecast skill, Compare providers, and Grid Code forecast packs are on Dashboard, not here. Frozen id §8.1.10 is the bridge.
- §8.2, §8.3, §8.4 and §8.6 are one running example — same plant, same book, numbers that carry forward (gate).
- §8.5 is the month picker and versions. Skip it while you walk the arithmetic.
- §8.7 and §8.8 are the lookup and the bridges. They are not the example.
8.1 The story on the page
The heading is Next month’s carve. The subtitle says
the rules are applied to what the plant is expected to make. There is no
AES / AM / CO letter-cluster in that heading —
Explanations
(#allocation-explanations-open) on the sticky
#allocation-mode-bar opens the shared A–Z drawer (AES
through Surplus). Those expansions are not printed in the Forecast
heading.
While the page loads you see Loading forecast…
(#strategy-page-loading). Then, top to bottom:
| On the page (top → bottom) | Id / role | What it answers |
|---|---|---|
| Sticky mode bar | #allocation-mode-bar ·
#allocation-mode-forecast |
Which Allocation sheet you are on. Forecast's note looks like Aug 2026 · v1 · FINAL 98%. Wide screens also show: Forecast is the rules applied to what the plant is expected to make; re-running writes a new version. |
| Explanations | #allocation-explanations-open |
Same right-hand drawer as Rules and Outcomes. First term AES, last Surplus, including amber reached Surplus — did not run dry. |
| Intro line | #ipp-forecast-intro |
Month-ahead reports; generated on the 5th; re-run writes a new version. |
| Month bar | ‹ ›, type="month", status badge, vN of M,
Versions, Re-run |
Which month and which stored version you are reading. |
| Version history | data-role="version-drawer" |
Every version of this month, with status and hierarchy label. |
| Empty state | data-role="empty-state" |
No forecast for YYYY-MM yet. Editors: Use “Re-run” to produce one. |
| Amber banner | data-role="viewing-old" |
Viewing vN (STATUS) — an earlier, immutable version. |
| Headline + bridge | #aes-verdict · #forecast-headline ·
#forecast-bridge |
One sentence, the verdict pill, five columns, three leftover cards. Deep read: §8.1.6. |
| Who we owe, and who gets served | #co-table |
Buyer rows in cascade order, with a methodology stamp. Deep read: §8.1.4 · §8.1.5. |
| How we got N MWh | #fg-panel |
P50 / P75 / P90 and the open Calculation. Deep read: §8.1.3. |
| What the plant actually made | #hag-panel |
Two lag months vs the seasonal model. Deep read: §8.1.2. |
| Forecast said, settlement did | #forecast-vs-settled |
Last month's paper carve vs what Outcomes paid. One sentence and what to do: §8.1.8. |
| Rolling outlook | #forecast-outlook |
This month plus the next three runs (or no run yet). One sentence and what to do: §8.1.9. |
| Forecast skill / Compare providers / Grid Code packs | not on this URL | Those three cards live on Dashboard → Forecast
evidence (#ipp-forecast-evidence-quality). Bridge: §8.1.10. Deep teaching: §17.8 · §17.9. |
Read the page top to bottom the first time — verdict, then who is served, then how the generation number was built. Read it bottom to top (HAG → FG → cascade → headline) when a buyer disputes the verdict.
The old five report sections are still on the page as receipts. They are not labelled Section 1…5 on screen. This chapter keeps those subsection numbers because the formulas and worked examples are taught against them.
flowchart TB
A[Pick the forecast month] --> B{A stored run exists?}
B -->|No| C[Empty state — wait for the 5th or Re-run]
B -->|Yes| D[Read the headline: expect / owe / leftover]
D --> E[Read the cascade: who is short]
E --> F[Open Calculation and HAG if someone challenges FG]
F --> G[Check status FINAL vs PROVISIONAL]
G --> H{Verdict}
H -->|OVERSUBSCRIBED| I[Freeze new sales — call Fixed first]
H -->|FULLY SUBSCRIBED| J[Hold — the book is a lid]
H -->|SELLING| K[Pass AES through HAF then Sales]
- Confirm the month picker matches the month you are deciding on.
- If the empty state shows, you have no stored run — wait or Re-run.
- Read the headline and the coloured pill before any table.
- Use the cascade as the call list.
- Only then open the FG / HAG rails if the generation number is in dispute.
- Do not sell hard off a PROVISIONAL badge.
- React from the verdict: freeze, hold, or take leftover to HAF.
8.1.1 Every concept on this screen
Read these as cards for the labels you will actually see. Explanations repeats the Allocation set (AES through Surplus) in A–Z order. This list is the Forecast-only reading.
HAG — Historical Actual Generation
What it is. Metered energy the plant really produced in a past month, shown against the seasonal model for that month.
Why it is on this tab. The forecast starts from evidence, not hope. The HAG rail feeds the FG formula.
Plain reading. "What we actually made — and what a normal year would have expected."
SM — Seasonal model
What it is. The plant's expected MWh for a calendar month in a typical year. On the chart it is the second series (Seasonal model).
Why it matters. Dividing HAG by SM gives a performance index: above 1.0 beat the season; below 1.0 under-performed.
Plain reading. "What a typical May / June / July looks like for this site."
FG — Forecasted Generation (P50)
What it is. Next month's central generation estimate. Built from the two most recent HAG months, seasonally normalised, plus a weight on next month's SM (§8.2).
Why it is on this tab. Everything downstream treats
FG as the month's generation pool (G = FG).
Plain reading. "Our best single number for what the plant will make."
P50 / P75 / P90
What they are. Confidence bands around FG. P50 / P75 / P90:
P50 is the central estimate. P75 /
P90 sit lower — volumes you expect to meet or beat 75%
/ 90% of the time, driven by trailing MAPE (or a
default 0.85 × FG before history exists).
Why they matter. Quote P90 to a cautious counterparty. Use P50 for the commercial carve and AES (P50).
Plain reading. "P50 = expected. P90 = the cautious floor."
ED — Expected Demand
What it is. What each off-taker will realistically
ask for next month:
ED = min(historical allocation, contract ceiling). (ED.)
Plain reading. "What we should plan to serve this buyer — not what they wish they'd take."
CO — Contractual Obligation
What it is. What each buyer is expected to
receive after the waterfall runs on FG. Never exceeds
that buyer's ED. (CO.) Sum of CO equals
min(FG, ED_total).
Plain reading. "What the published rule says they get from this forecast."
SB — Subscription Balance
What it is. SB = FG − ED_total. (SB.) Negative = the book
asked for more than the forecast can deliver
(oversubscribed). Positive = headroom.
Why it matters. AES never goes negative — it floors at zero — so you need SB to see how deep the hole is.
Plain reading. "Book size minus plant outlook. Red gap = stop selling."
AES — Available Energy for Sales
What it is. AES = max(0, SB) — MWh
still offerable to new buyers after existing obligations. Shown as
AES (P50) and a more cautious AES
(P90).
Plain reading. "What's left to sell — or zero if you're already over."
FINAL / PROVISIONAL / SUPERSEDED
What they are. Report status badges.
| Badge | Meaning |
|---|---|
| FINAL | Meter completeness has qualified — use for sales decisions |
| PROVISIONAL | Completeness still below the final bar (~95%) — treat cautiously |
| SUPERSEDED | An older version replaced by a newer run — still readable, never edited |
Plain reading. "FINAL = bankable snapshot. PROVISIONAL = waiting on meters. SUPERSEDED = history."
MAPE — Mean Absolute Percentage Error
What it is. Rolling forecast-vs-actual error. The FG Calculation quotes trailing MAPE when present; it drives how wide the P90 band sits.
Plain reading. "How wrong have we been lately? Wider MAPE → wider caution band."
Covered bar, Flags, P90 dry
Covered. A fill bar for that row's Fulfilment (CO ÷ ED).
Flags. Amber capped by contract; green no history · contract profile; muted contract N when a contracted-energy figure is stored.
P90 dry. Amber row: A P90 month runs dry here — buyers on and below this tier would be short; warn them ahead of time. (P90 month runs dry.) This is not the Rules hourly strip Where the cascade runs dry.
8.1.2 What the plant actually made — the HAG rail
Panel: #hag-panel ·
Chart: #hag-chart · Title on
screen: What the plant actually made
This rail sits on the right, under How we got N MWh. It is the evidence strip behind the formula — not the first block on the page.
For the selected forecast month the LiveView builds a compact three-point series from the stored inputs snapshot:
| Chart category (example) | What it is |
|---|---|
| Two months back | HAG₂ and SM₂ (both known) |
| Last month | HAG₁, SM₁, and completeness % |
| Forecast month | SM only — HAG is not yet measured (the chart plots HAG as empty / 0) |
How to read the graph
| Chart piece | How to read it | How to react |
|---|---|---|
| X-axis | Full month name + year (June 2026) |
Confirm you are looking at the lag months for this forecast |
| Y-axis | Energy in MWh | Compare heights, not "looks about right" |
| HAG series | Actual metered volume | If HAG ≪ model for both lags, expect a softer FG |
| Seasonal model series | Climate / resource expectation | Gap HAG−model = performance story |
| Legend (bottom) | Names the two series | Match colour → series before arguing a number |
Help tips on the table headers:
| Header | Tip on screen |
|---|---|
| Model (MWh) | Expected generation for this month in a typical year — the seasonal / resource model. |
| Perf. index | Actual ÷ model — above 1 beat the season; below 1 under-performed. |
| Completeness | Share of expected meter evidence present for the month — below ~95% keeps the forecast provisional. |
Perf. index colour. Green above 1, rose below 1, slate at 1.00, a dash when HAG or the model is missing (the forecast month).
Empty series: No metered history yet. — a young plant; FG will lean harder on SM and default P90.
What we are ascertaining. Is the plant healthy relative to its own season — or are we forecasting from a damaged baseline?
8.1.3 How we got N MWh — the FG rail
Panel: #fg-panel ·
Calc: data-role="fg-calc" · Title
on screen: How we got 14 208 MWh (the P50, with a thin
space in the thousands)
This rail is the month-ahead generation answer. The rest of the report treats that number as the plant's supply pool.
The three cards
They are the same forecast family, at three confidence levels — not three unrelated guesses. Subtitles are printed on the cards:
| Card | Subtitle on screen (#fg-p50-desc /
#fg-p75-desc / #fg-p90-desc) |
How to react |
|---|---|---|
| P50 | Central estimate — half the months you expect to meet or beat this. | This is FG. The cascade and AES (P50) use it as the supply pool |
| P75 | Soft-month check — how a below-average month still looks. | Internal risk conversation — not usually the number you quote externally |
| P90 | Conservative floor — quote this when the buyer wants certainty. | Quote to a cautious counterparty; read AES (P90) the same way |
"P" = percentile of confidence, not a price. A plant
with a strong recent track record keeps P90 close to P50. A young plant
may default P90 to roughly 0.85 × FG until MAPE history
exists.
The Calculation block
Under the three cards sits an open <details> strip
titled Calculation (seasonally normalised) or
Calculation (raw).
| Label | What it means | How to react |
|---|---|---|
| seasonally normalised | Lag months were scaled by season: last month's performance (HAG ÷ its SM) was applied to next month's SM | The bankable path the report prefers. Walk §8.2 if you need every term |
| raw | The blend used the lag MWh without that seasonal scaling | Ask why (missing SM, incomplete lags, young plant). Do not silently "fix" to normalised in a private spreadsheet |
The formula line looks like:
FG = 0.5·HAG₁(13200) + 0.3·HAG₂(12800) + 0.2·SM(14000) = 14208
When present: Trailing MAPE N% drives the P90 band.
Why this rail exists. Buyers and sales need a bankable "what will the plant make?" before the month starts. The HAG rail shows evidence; this rail turns that evidence into the pool (
G = FG) that the cascade and the headline carve.
8.1.4 Who we owe — the cascade
Panel: #co-table ·
Rows: data-role="co-row" · Title
on screen: Who we owe, and who gets served
The intro on the card: Each buyer's expected demand and contractual obligation for the month, in the order the cascade serves them. The bar is how much of their expected demand the P50 forecast covers.
Think of FG as a tank of water. Buyers drink in published order.
Tier heading rows (data-role="tier-heading") print in
cascade order:
| Heading | Rule text on screen |
|---|---|
| 1 · Priority | served first, in rank order |
| 2 · Pro-rata | served second, in proportion to demand |
| 3 · Fixed | served last, entitlements scaled together on shortfall |
Each heading also shows takes N MWh · N buyer(s). An empty tier reads No buyers on this tier.
Every column on a buyer row
| Column | Plain English | How to react |
|---|---|---|
| Off-taker / PPA | Buyer name (or a short id) plus the agreement ref underneath | Match it to Rules and to the contract desk's name |
| Tier | Chip: Priority #N, Pro-rata, or
Fixed · ≤ e when an entitlement is stored |
Treat Fixed rows as the shortfall call list |
| ED (MWh) | Expected Demand — history capped by the contract ceiling | Do not "fix" ED in a spreadsheet — it came from the stored lines |
| CO (MWh) | Contractual Obligation — what the waterfall expects them to receive | Bold. Never above that row's ED |
| Covered | Fill bar (data-role="co-fill") for Fulfilment |
A short bar on Fixed while Priority is full is usually by design |
| Fulfilment | CO ÷ ED as a percentage |
Green at or above 99.5%, amber from 75%, rose below. Call the % |
| Flags | capped by contract · no history · contract profile · contract N | A new buyer with no history is planned from the contract profile, not from a blank |
Help tips: ED is what this buyer will realistically ask for (history capped by their contract ceiling); CO is what the waterfall allocates to them from forecasted generation. Never above their ED; Fulfilment is share of their Expected Demand covered by CO — CO ÷ ED.
The P90 dry marker
When a conservative (P90) generation month would empty inside a tier,
an amber row (data-role="p90-dry") sits under that
tier:
A P90 month runs dry here — buyers on and below this tier would be short; warn them ahead of time.
Warn those buyers before the month starts. Do not confuse this with the Rules hourly strip (§7.9).
The Available for sale footer
The last row (data-role="aes-row") is not a buyer:
| Cell | What it shows |
|---|---|
| Name | Available for sale |
| Chip | SURPLUS |
| ED | — |
| CO | AES (P50) |
| Covered / Fulfilment | what survives the cascade · N at P90 |
| Flags | Link safely contractable → Sales |
That leftover is the start of a Sales conversation, not a contract volume. Pass it through HAF (§5).
Virtual memo rows
The table can render italic (virtual) lines
with memo — excluded from CO/AES. The built Forecast LiveView
does not currently pass those memos — you will see
physical lines only. Virtual paper still does not consume CO or AES.
What "good", "watch", and "bad" look like
| Reading | What the table usually shows | What it means |
|---|---|---|
| Good | Every physical row at ~100% Fulfilment | FG covers the book. Read the headline next: FULLY SUBSCRIBED or SELLING |
| Watch | Priority (and maybe Pro-rata) at 100%; Fixed soft | Designed oversubscription. Freeze new firm sales; call Fixed |
| Bad | Pro-rata or Priority also below 100% | Deep hole. Stop selling. SB shows how deep |
| P90 warning | Amber dry row on an early tier | Even if P50 looks fine, a poor month shorts that tier and everyone below |
8.1.5 The methodology stamp
Stamp: #am-trace · sits
on the cascade card, not as a separate ordered list
The old report printed every buyer as min(ED X) → CO Y.
That list is not on the built page. Drink order is the
three tier headings. The stamp is the receipt of which rule and
which run mode carved the month.
Looks like:
Run mode aggregate · carved with v3 (link
#forecast-hierarchy-link)
or, with no resolved hierarchy:
· hierarchy first-8-of-uuid
| Piece | How to read it | How to react |
|---|---|---|
| Run mode | aggregate (one monthly pour) or hourly
(shaped, then summed) |
Do not mix an aggregate Forecast with an hourly mental model when reconciling to settlement |
| carved with label | The hierarchy version that was in force when this forecast version was created | Open Rules on that version before arguing tiers |
Amber stale chip
(data-role="hierarchy-stale") |
{in-force label} is in force now — re-run to refresh the carve | Today's published board is newer than this report. Re-run if you want the live rule |
Why the stamp exists. Forecast does not invent a sales waterfall. It runs the same Allocation Methodology settlement uses — Priority → Pro-rata → Fixed — against FG. The stamp freezes which board the runner believed. Re-publishing Rules does not rewrite an old forecast.
8.1.6 Headline, verdict and leftover
Panel: #aes-verdict ·
Headline: #forecast-headline ·
Pill: data-role="aes-verdict" ·
Bridge: #forecast-bridge ·
Cards: #aes-sb-desc ·
#aes-p50-desc · #aes-p90-desc
This is the first story block under the picker — not a last "Section 5". One sentence, one pill, five columns, three numbers.
The headline sentence
The LiveView prints one of three tails. Owe is
CO total (what the waterfall expects to deliver), not
ED total (what the book asked for). Thousands use a thin space
(14 208).
| Situation | Shape you will read |
|---|---|
| Book bigger than FG | August 2026: we expect 14 208 MWh, owe 14 208 MWh, — oversubscribed by 1 792 MWh, so lower tiers will be short |
| Leftover on P50, but P90 would empty a tier | …owe N MWh, and can sell X MWh — unless a poor month arrives, when Priority runs short (or Pro-rata / Fixed) |
| Leftover even at P90 | …and can sell X MWh even in a poor month |
The explainer under the headline: Forecast generation enters on the left and is carved through the hierarchy in tier order. What survives the last tier is available energy for sales. The dashed marker is the P90 case: the same rules on a conservative month.
The verdict pill
Exactly one string, then · N MWh at P90 when AES (P90) is present.
| On-screen text | Colour on the LiveView | When | Plain meaning |
|---|---|---|---|
| OVERSUBSCRIBED | Rose (bg-rose-50) |
SB < 0 |
Book > FG(P50). AES cards are 0. Freeze new sales. |
| FULLY SUBSCRIBED | Amber (bg-amber-50) |
SB ≥ 0 and AES (P50) = 0 |
Exact fill — nothing short, nothing left. Hold. |
| SELLING — X available | Amber | AES (P50) > 0 | Headroom X is AES (P50), printed to one decimal
(e.g. 1500.0). Pass through HAF. |
| — | Muted | SB missing | No usable balance |
Careful. SELLING and FULLY SUBSCRIBED are amber, not green. Only OVERSUBSCRIBED is rose. Oversubscription is tested first.
The bridge
Five columns (data-role="bridge-column"):
- Forecast generation — P50 height; subtitle P50 · N at P90.
- Priority — −N MWh; N buyer(s) · obligation (or none).
- Pro-rata — same shape.
- Fixed — same shape.
- Available for sale (AES · P50) or Shortfall (obligations exceed forecast) in rose.
A dashed line on a column is the P90 remainder. The Shortfall column has no P90 dash. Legend under the columns: Forecast generation P50, each tier's obligations, Available for sale, P90 remainder.
The three leftover cards
| Card | Subtitle | Number is |
|---|---|---|
| Subscription balance | Headroom check — positive means room to sell; negative means freeze new deals. | FG(P50) − ED_total (can be negative,
e.g. -1792.0) |
| AES (P50) | Saleable leftover — what the central forecast still has to place. | max(0, SB) |
| AES (P90) | Conservative leftover — quote this when the buyer wants certainty. | max(0, FG(P90) − ED_total) |
Optional footnote: Capacity headroom: N MW saleable. That is megawatts of export, not MWh of AES. Do not convert with a napkin "hours in a month" in a sales call.
Conservation (why AES never goes red)
SB = FG(P50) − ED_total (can be negative)
AES(P50) = max(0, SB) (never negative)
AES(P90) = max(0, FG(P90) − ED_total)
Σ CO = min(FG(P50), ED_total)
If someone says "AES is −1,792," they are looking at SB.
8.1.7 Chrome — month picker, status, versions, empty state
Controls sit in one white bar under the mode switch (same facts in §8.5):
| Control | What it does | How to react |
|---|---|---|
| ‹ › and month input | Select forecast month (select_month /
shift_month) |
Always check the month before arguing numbers |
| Status badge | FINAL / PROVISIONAL / SUPERSEDED plus completeness % | Do not sell hard off PROVISIONAL |
| vN of M | Live version among this month's stored runs | Confirm you are on the live version |
| Versions (N) | Opens the version history list | Open superseded versions read-only to audit |
Re-run (data-role="rerun") |
MonthlyForecastRunner.run_for/2 |
Editors only. Creates a new version; flash Re-ran the forecast — a new version is now live. |
| Empty state | No forecast for YYYY-MM yet. | Editors: Re-run; viewers: wait for the 5th |
| Amber banner | Viewing vN (STATUS) — an earlier, immutable version. | Switch back before deciding |
Viewer vs editor. Viewers see picker, badge, and
versions. Re-run is hidden when the session role is
viewer.
The scheduled job is the 5th of each month (Oban
MonthlyForecastRunner — §14).
A superseded version stays readable. The page never overwrites it.
8.1.8 Forecast said, settlement did
One sentence. This card is last month's report card: what Forecast wrote on paper versus what Outcomes later paid each buyer.
Panel: #forecast-vs-settled · sits
left, beside Rolling outlook · Title on
screen: Forecast said, settlement did — Jul 2026 (the
label is last month, not the month in the picker).
Intro on the card: Last month's forecast carve against what settlement actually allocated. The gap is forecast error, and it tells you which buyers to trust the forecast for.
The problem this card solves
You are looking at this month's Forecast to decide whether to sell. A buyer may ask: "Last time you showed me a carve, did the meters agree?" This card is that check. It puts two slips for the same past month next to each other: what Forecast promised, and what Outcomes later recorded.
The card is not about the month in the picker. If the picker says August, this card is July (when July has both a live forecast and a settled month).
What you need before numbers appear
Both of these must already exist:
- A live (not superseded) forecast for last month.
- A settled Outcomes month for that same month.
If either is missing, the card prints:
Needs a forecast for last month and a settled month to compare it with. (
data-role="no-drift")
That empty line is an empty comparison. It is not a claim that the forecast was perfect.
flowchart LR
A[Last month's Forecast] --> C[This card]
B[Last month's Outcomes] --> C
C --> D[Open month → Outcomes]
- Last month's Forecast stored each buyer's CO (Contractual Obligation) — what the paper waterfall expected them to receive.
- Outcomes stored what settlement allocated (kilowatt-hours, shown here as megawatt-hours).
- The card subtracts: settled − forecast = Δ MWh.
- Open {Mon YYYY} → Outcomes opens the full receipt (§9).
What each number means
| Column | Plain meaning | What to do with it |
|---|---|---|
| Buyer | The named off-taker (or a short id if the name is missing) | Match the name to the cascade and to Rules |
| Forecast | That buyer's CO from last month's live forecast, in MWh | This is the paper promise |
| Settled | What Outcomes allocated to them, in MWh (stored kWh ÷ 1,000) | This is the meter receipt |
| Δ MWh | Settled minus forecast | Green: they received more than the paper said. Rose: they received less. A dash: the gap is tiny (about 0.05 MWh or less) |
The last row is Surplus — leftover after every buyer, on paper versus after settlement. Same three numbers: forecast leftover, settled leftover, Δ.
Under the table a one-line verdict names the plant, not a buyer: Generation came in N% under forecast. or … over forecast. Then the Outcomes link.
What "done" looks like, and what to do
| You see… | It means… | Do this |
|---|---|---|
| Empty copy (Needs a forecast…) | Last month cannot be compared yet | Wait until both a forecast and a settlement exist. Do not treat the empty card as "zero error" |
| Small Δ on every row | Last month's paper was close | Trust this month's Forecast more when you talk to buyers |
| Large rose Δ on one buyer | Settlement paid them less than the paper | Open Outcomes for that month. Ask whether demand, meters, or the hierarchy version moved |
| Generation under forecast | The plant made less than last month's FG | Expect this month's P90 band to matter more; do not raise AES |
| Generation over forecast | The plant made more than last month's FG | Surplus on Outcomes may be fatter than last month's AES — still pass new leftover through HAF |
Do not type last month's Δ into this month's Forecast. Each month is its own stored version. Use the gap to judge trust, then decide on this month's headline (§8.1.6).
Where this is taught. The settled receipt — Members, hours, conservation — is §9. This card is only the Forecast-side comparison. Glossary: Forecast vs settled.
8.1.9 Rolling outlook
One sentence. This card is the next four months of the diary: the month you picked, plus the next three, each showing generation and leftover — or no run yet.
Panel: #forecast-outlook · sits
right, beside Forecast said, settlement did ·
Title on screen: Rolling outlook
Intro on the card: The same carve for the months ahead, where a run exists. Months without a run are marked.
The problem this card solves
The headline and cascade are one month — the month in the picker. A seller also needs the next pages of the diary: is September already run? Does October still say no run yet? Rolling outlook is those four small cards in a row.
What each card is
There are always four tiles: this run (the picker month) plus the next three calendar months.
| You see on a tile | Plain meaning | Do this |
|---|---|---|
| Aug 2026 · this run | The month you are reading in the headline | Use the headline and cascade for the sell / hold / freeze decision |
| Sep 2026 · final (or provisional) | A later live forecast exists | Open that month in the picker if you need its cascade. Treat provisional as direction only |
| Sep 2026 · no run yet and Runs on the 5th. | No stored forecast for that month | Wait for the 5th (or authorised Re-run). Do not invent leftover |
| Bar + N MWh · sell X | N is FG (P50). X is AES (P50). Slate bar = obligations; amber bar = leftover | X is paper leftover, not a contract volume |
A month with no run has no bar.
The footer — safe leftover, then Sales
Under the four tiles the page repeats capacity in two units:
| Footer piece | What it is | What you do |
|---|---|---|
| Capacity headroom N MW saleable | Export megawatts still free on the site | Soft capacity check. Do not convert MW to MWh with a napkin "hours in a month" |
| Safely contractable next month plus the HAF capacity line | SCE (Safe Contractable Energy) for a Pro-rata seat, with a band chip. Or no FINAL forecast yet / up to N MWh · contract-based, no history | Contract inside SCE, not inside raw AES |
| Price it → Sales | Opens the Sales desk for this plant | Only after HAF / SCE. Sales is §6 |
What "done" looks like
You can name four months. For the picker month you can say FG and AES in one breath. For any later month you can say either "run exists (final / provisional)" or "runs on the 5th." You have not treated sell X as a signed volume.
Where this is taught. The honesty discount from AES to SCE is §5. Sales is §6. Glossary: Rolling outlook.
8.1.10 Forecast skill, Compare providers, Grid Code packs
These three cards are not on Allocation → Forecast. They do not pour next month's jug and they do not change the running example in §8.2–§8.6.
They live on Dashboard, chapter 5, in a closed fold
under the three-column operating-evidence strip — the same click-to-open
chrome as Availability detail. The summary is Forecast evidence
— skill, providers, Grid Code packs
(#ipp-forecast-evidence-quality). Path: Generator
sites → … → Strategy → Dashboard. Address:
/org/generator-sites/<id>/strategy/dashboard.
Where this is taught. Click path and the on-page table: §12.6. Scorecard arithmetic: §17.8. Pack categories and XML: §17.9.
Running example. One plant, one book, numbers that carry forward. The arithmetic is a solar IPP (Independent Power Producer) with nine buyers whose expected demand totals 16,000 MWh. That is the documented engine receipt — the same 14,208 / 17,500 figures the Forecast tests stamp — not IPP2 Atlantis Wind's seeded picker month. §8.2 builds August FG = 14,208 MWh. §8.3 pours that 14,208 through the book. §8.4 keeps the same book and asks what a 17,500 MWh December looks like. §8.6 is how those two months look on the Forecast screen (and a few other live states). §8.5 is the month picker and versions — skip it while you walk the arithmetic, then come back.
flowchart TB
A[§8.2 Build August FG 14,208] --> B[§8.3 Pour August — OVERSUBSCRIBED]
B --> C[§8.4 Same book, December 17,500 — SELLING]
C --> D[§8.6 Read August and December on the screen]
E[§8.5 Picker and versions — not the example] -.-> D
- Build the August generation number from two lag months and the seasonal model (§8.2).
- Carve that number through the nine-buyer book (§8.3).
- Keep the same book; raise generation to December (§8.4).
- Pause at §8.5 only if you need the picker — it is not new arithmetic.
- Read both months on the LiveView (§8.6 A and B).
8.2 FG worked — from meter readings to a bankable forecast
Still the same example. Part 1 of 4 — build the August generation number. Inputs below are the solar IPP's June / July meters and seasonal model. The 14,208 MWh result is the jug §8.3 pours.
The forecast blends what the plant recently did with what the season should deliver:
FG formula (default weights)
FG = α·HAG₁·(SMₘ/SM₁) + β·HAG₂·(SMₘ/SM₂) + γ·SMₘ
defaults: α = 0.5, β = 0.3, γ = 0.2
The ratios are the trick. HAG₁/SM₁ is last month's
performance index. Multiplying by SMₘ
applies that health reading to next month's season, instead of
dragging last season's raw volume forward.
Worked example — solar IPP forecasting August:
| Input | Meaning | Value (MWh) |
|---|---|---|
HAG_Jul |
metered generation, last month (m−1) | 13,200 |
HAG_Jun |
metered generation, two months back (m−2) | 12,800 |
SM_Aug |
seasonal expectation for the forecast month | 14,000 |
SM_Jul |
seasonal expectation for July | 13,000 |
SM_Jun |
seasonal expectation for June | 12,500 |
Raw blend (no normalisation)
0.5×13,200 + 0.3×12,800 + 0.2×14,000
= 6,600 + 3,840 + 2,800
= 13,240 MWh
Seasonally normalised (the bankable variant the report uses)
α-term: 0.5 × 13,200 × (14,000/13,000) = 7,107.7
July index 13,200/13,000 = 1.015
β-term: 0.3 × 12,800 × (14,000/12,500) = 4,300.8
June index 12,800/12,500 = 1.024
γ-term: 0.2 × 14,000 = 2,800.0
FG_Aug = 7,107.7 + 4,300.8 + 2,800.0 ≈ 14,208 MWh
(vs 13,240 raw)
The normalised figure is higher because both lag months beat
their seasonal expectation — the plant is demonstrably healthy going
into a sunnier month. Every one of these inputs appears in
Calculation on #fg-panel, so you can
recompute the headline by hand.
Confidence bands. The central FG is treated as P50.
P75/P90 come from the plant's own trailing forecast-error distribution
(MAPE over recent forecast-vs-actual pairs); before any history exists,
P90 defaults to 0.85 × FG. Quote P90 to a cautious
counterparty.
8.3 August — an oversubscribed month, end to end
Still the same example. Part 2 of 4 — pour the 14,208 MWh from §8.2 through the nine-buyer book (ED total 16,000 MWh). §8.6 scenario A is this month on the screen.
Each off-taker's expected demand is
ED = min(historical allocation, contract ceiling). The
waterfall then runs with G = FG:
| Tier | Off-taker | ED (MWh) | Waterfall step | CO (MWh) | Fulfilment |
|---|---|---|---|---|---|
| PRIORITY r1 | P1 | 2,200 | min(2,200, 14,208) |
2,200 | 100% |
| PRIORITY r2 | P2 | 1,800 | min(1,800, 12,008) |
1,800 | 100% |
| PRIORITY r3 | P3 | 1,500 | min(1,500, 10,208) |
1,500 | 100% |
| PRO_RATA | R1 | 3,500 | remainder 8,708 ≥ tier demand 7,000 → full | 3,500 | 100% |
| PRO_RATA | R2 | 2,100 | full | 2,100 | 100% |
| PRO_RATA | R3 | 1,400 | full | 1,400 | 100% |
| FIXED | F1 | 1,400 | remainder 1,708 < TF 3,500 → scale 0.488 | 683.2 | 48.8% |
| FIXED | F2 | 1,400 | × 0.488 | 683.2 | 48.8% |
| FIXED | F3 | 700 | × 0.488 | 341.6 | 48.8% |
| Totals | ED_total = 16,000 | CO_total = 14,208 |
August verdict arithmetic
SB = FG − ED_total = 14,208 − 16,000 = −1,792 MWh → OVERSUBSCRIBED
AES = max(0, SB) = 0 → nothing to offer
Headline owe is 14,208 (CO total), not 16,000. The 1,792 hole lives in SB and in the Shortfall column.
On the LiveView for this month you should see: rose OVERSUBSCRIBED; headline we expect 14 208 MWh, owe 14 208 MWh, — oversubscribed by 1 792 MWh, so lower tiers will be short; Subscription balance −1792.0; AES (P50)/(P90) 0; bridge last column Shortfall; Fixed rows at 48.8% Fulfilment (rose); Priority / Pro-rata at 100%.
8.4 December — a selling month, for contrast
Still the same example. Part 3 of 4 — same nine buyers, still ED total 16,000 MWh. Only the generation number changes:
FG_Dec = 17,500 MWh. §8.6 scenario B is this month on the screen.
The waterfall serves every tier in full:
December verdict arithmetic
SB_Dec = AES_Dec = 17,500 − 16,000 = +1,500 MWh
Pill: SELLING — 1500.0 available (amber). Headline owe is 16 000 (CO = ED). Bridge last column Available for sale.
How to react. Do not sell the full 1,500 as firm paper — open HAF §5 and contract only within SCE for the intended tier. Then take candidates into Sales (§6).
8.5 Month picker, status, versions, re-run
Not the running example. This section is the month picker, status badge, Versions list, and Re-run. It does not continue the 14,208 / 17,500 arithmetic. The same chrome is taught in §8.1.7. Return to the example at §8.6.
The same chrome as §8.1.7, in short:
- The month picker (and the ‹ › arrows) moves between months.
- The status badge shows FINAL or PROVISIONAL with the completeness % — provisional means last month's meter data wasn't yet ~95% complete.
- The Versions list shows every version of the selected month; opening a superseded one shows it read-only.
- Re-run (authorised roles) recomputes the month and switches to the new version. Every re-run supersedes — it never overwrites.
Schedule reminder. The Oban cron fires
MonthlyForecastRunner on the 5th of each
month (§14.1). The intro line on
the page states the same product truth.
Viewer vs editor. Viewers see picker, badge, and
versions. Re-run is hidden when the session role is
viewer.
8.6 Worked scenarios — reading the screen
Still the same example. Part 4 of 4 — scenarios A and B are August (§8.3) and December (§8.4) on the Forecast LiveView. Scenarios C–I are other live states (provisional, re-run, knife-edge, P90 dry, empty drift, old version). They do not change the 14,208 / 17,500 book.
Data. Scenarios A–B reuse the §8.3 / §8.4 arithmetic · C–I walk LiveView states · full_demo seed 42 for pathing.
Scenario A — August OVERSUBSCRIBED (freeze sales)
What you see. Rose OVERSUBSCRIBED; headline owe 14 208 and oversubscribed by 1 792; SB −1792.0; AES 0; Fixed Fulfilment ~48.8%; Priority and Pro-rata at 100%; bridge last column Shortfall.
What we ascertained. The plant outlook cannot cover the book. The shortfall is designed to land on Fixed first.
How to react. Freeze new sales. Call Fixed-tier account managers with the Fulfilment %. Do not drag Hierarchy mid-pitch without a published re-version and a Forecast Re-run.
Scenario B — December SELLING (headroom before HAF)
What you see. Amber SELLING — 1500.0 available; SB = AES = +1,500; every CO row at 100%; bridge last column Available for sale; footer link safely contractable → Sales.
What we ascertained. Genuine paper surplus after obligations.
How to react. Open HAF → read SCE for the tier you intend to sell → only then price it on Sales. AES is the start of the sell conversation, not the contract volume.
Scenario C — PROVISIONAL because meters are late
What you see. Badge PROVISIONAL · 88%; sections still populated from available evidence.
How to react. Chase the meter feed (§14.3). Prefer the FINAL version for a board-level sell decision.
Scenario D — Re-run after hierarchy publish
What you see. After Re-run: flash Re-ran the forecast — a new version is now live; Versions lists v2 (live) and v1 (SUPERSEDED). Before the re-run, the cascade stamp may show the amber stale chip.
How to react. Decide on v2. Keep v1 only for "what did we believe on the 5th?".
Scenario E — Fully subscribed (knife-edge)
What you see. Amber FULLY SUBSCRIBED; SB 0; AES 0; all physical rows at 100%.
How to react. Do not sell more. Do not celebrate "full" as surplus.
Scenario F — Reading the HAG rail before arguing FG
What you see. Chart categories June 2026, July 2026, August 2026. Perf. index green / slate; Calculation labelled seasonally normalised; P50 14208.
How to react. If someone challenges FG, start at
#hag-chart and the Perf. index column, then walk the
Calculation. Argue inputs, not vibes.
Scenario G — P90 dry on an early tier
What you see. Headline may still show leftover at
P50, plus unless a poor month arrives, when Priority runs
short. Amber data-role="p90-dry" under Priority.
How to react. Warn Priority and everyone below. Do not pitch P50 leftover as firm.
Scenario H — No drift yet
What you see. Needs a forecast for last month and a settled month to compare it with.
How to react. That is an empty comparison, not a zero-error claim. Open Outcomes only after both sides exist.
Scenario I — Viewing an earlier version
What you see. Amber Viewing v1 (SUPERSEDED) — an earlier, immutable version. Headline numbers may be the old FG.
How to react. Switch back to the live version before a sell decision.
8.7 What good looks like — seller cheat sheet
Not the running example. This is the seller lookup after you have walked §8.2–§8.6.
| You see… | It means… | React |
|---|---|---|
| Rose OVERSUBSCRIBED, SB negative, AES 0, Shortfall column | Book > FG | Freeze sales; warn Fixed by Fulfilment % |
| Amber SELLING — X available, AES = X | Headroom after obligations | Pass X through HAF → SCE before contracting |
| Amber FULLY SUBSCRIBED | Exact fit | Hold; one new deal oversubscribes |
| PROVISIONAL · low completeness | Meters incomplete | Direction only; await FINAL |
| FINAL · Versions shows prior SUPERSEDED | Live evidence qualified | Prefer live version for decisions |
| Fixed Fulfilment ≪ 100%, Priority 100% | Waterfall working as designed | Expectation management, not a "bug" |
| Amber P90 month runs dry here | Conservative month shorts that tier | Warn those buyers; do not sell the P50−P90 gap |
| Hierarchy stale chip | A newer Rules version is in force | Re-run if you want the live board |
| HAG ≪ Seasonal model on both lags | Weak performance index | Expect softer FG; check outages / resource |
| Empty state for the month | No run yet | Wait for 5th or authorised Re-run |
| Viewing amber "earlier version" banner | Read-only history | Switch back to live before selling |
| Drift empty copy | Last month cannot be compared yet | Not a claim that forecast error is zero |
| Attractive AES, HAF band MODERATE/POOR | Paper surplus ≠ safe surplus | Contract inside SCE (§5) |
Rule of thumb. SB tells you whether to sell; AES tells you how much paper is left; HAF / SCE tells you how much of that paper is safe; Versions tells you which story you are looking at.
8.8 Bridges and caveats
Not the running example. Limits and bridges after the walk.
- Next stop when AES > 0. §5 discounts AES into SCE; §13 contracting guard blocks unacknowledged over-SCE activations; §6 Sales finds who fits the leftover shape.
- Hierarchy is the rule, Forecast is the prediction. Changing tiers mid-month does not rewrite an old forecast version — Re-run (or wait for the next scheduled run) against the published hierarchy (§7).
- Settlement uses meters; Forecast uses FG. Same
waterfall, different
G. Credibility comes from that shared rule (§9). Last month's comparison is §8.1.8. - Cron vs button. The 5th-of-month Oban job is the normal path; Re-run is the authorised exception. Ops cadence and alerts: §14.
- Virtual PPAs. They do not consume CO or AES. The cascade does not currently list virtual memo rows (the LiveView does not pass them).
- MW footnote ≠ MWh AES. Capacity headroom (MW saleable) is site export context; commercial leftover energy is AES in MWh.
- Skill / packs. Not on Forecast. Dashboard chapter
5,
#ipp-forecast-evidence-quality— §12.6. Deep teaching: §17.8 and §17.9. - Illustrative arithmetic. August 14,208 / December 17,500 figures are the documented worked set; your seeded demo months may differ in absolute MWh while preserving the same reading pattern.
- Demo seat.
ipp_2@webill.net→ Atlantis Wind → Strategy → Forecast — V3 §21.
Because every input is persisted on the forecast version, recompute from the page — do not re-teach the month from a private spreadsheet that cannot be audited.
9. Allocation · Outcomes — who got what
Thread part 4, continued: IPP2 Atlantis Wind’s July has settled. Where did every metered kilowatt-hour go, and does it add up?
Follow along. Seat:
ipp_2@webill.net. Path: Generator sites → IPP2 Atlantis Wind → Strategy → Allocation, mode Outcomes · settled. You should see the month picker with the conservation badge and Carved under vN* · in force at period start*, a headline Where N GWh went in July 2026 over a tier split bar, then the Members table beside Tier fill and Claims, the Allocation by hour chart with its exhaustion strip, and the Hourly waterfall. Explanations on the mode switch (#allocation-explanations-open) opens the shared right-hand drawer: one A–Z list of abbreviations and terms (AES through Surplus), including ARF, Conserved, and amber reached Surplus — did not run dry.
The seller’s problem, in plain words
A buyer’s statement says they received 1 240 MWh. Your meter says the
plant made 3 100 MWh. Where did the rest go, and was the split the one
the published rule promised? Outcomes replays a settled month from the
persisted settlement intervals — nothing here is recomputed — and proves
the identity Σ allocations + surplus = metered generation
for the month and for every hour.
When to open Outcomes vs the other modes
| You want to… | Open |
|---|---|
| Prove what a settled month paid each named buyer | Outcomes (this mode) |
| Change the rule that will carve next month | Rules (§7) — the version link on this page opens the version that governed |
| See what the forecast expected against what settled | Forecast (§8) — its Forecast vs settled card |
9.1 Where each off-taker's demand comes from
The waterfall needs one number per off-taker per hour: its demand
D(h). Settlement resolves it from the best available
source, falling through four levels:
Two caps apply on top of whatever the ladder returns: the contract's hourly ceiling (contracted capacity × 1,000 kWh/h) and the remaining headroom under the annual volume cap — once an off-taker's annual cap is hit, its demand resolves to zero for the rest of the contract year.
On the Allocations screen, hours settled against incomplete meter data carry a provisional badge on the Hourly waterfall row (ladder step 4). They re-settle automatically once the real data lands.
9.2 The hourly waterfall
When settlement runs, it resolves your metered generation once and
carves it through the in-force hierarchy, hour by hour. With
R the running remainder:
- PRIORITY — in ascending rank order, each off-taker
takes
min(demand, R). Each rank is filled completely before the next sees anything. - PRO_RATA — with
R₂left and tier demandTD: each off-taker getsmin(D, R₂ × D/TD). On shortfall everyone scales byR₂/TD; on sufficiency everyone gets full demand and the excess flows on. - FIXED — with
R₃left and total entitlementTF: each getsentitlement × min(1, R₃/TF), further capped at its actual demand. - SURPLUS — whatever still remains is yours to sell. Surplus is never retroactively re-offered to hierarchy members within the same hour.
The Members table names every buyer (and a Surplus row) for the period. The chart defaults to one series per member (+ Surplus); toggle Tiers when the member count is large. Collapsed waterfall rows still show tier totals; expand an hour for that hour's per-member split. Open Hierarchy (§7) when you need to change who sits in each tier — this tab only replays outcomes.
9.3 A worked day, hour by hour
The canonical example from the allocation methodology: one IPP, nine off-takers, three per tier. Demands are held constant across the day so you can watch the generation level alone decide who gets what:
| Tier | Off-taker | Parameter | Hourly demand / entitlement (MWh) |
|---|---|---|---|
| PRIORITY | P1 | rank 1 | 30 |
| PRIORITY | P2 | rank 2 | 25 |
| PRIORITY | P3 | rank 3 | 20 |
| PRO_RATA | R1 | 50% of tier demand | 50 |
| PRO_RATA | R2 | 30% of tier demand | 30 |
| PRO_RATA | R3 | 20% of tier demand | 20 |
| FIXED | F1 | entitlement | 20 |
| FIXED | F2 | entitlement | 20 |
| FIXED | F3 | entitlement | 10 |
Tier totals: PRIORITY 75, PRO_RATA 100, FIXED 50 — a full stack of 225 MWh/h. Four hours are chosen so generation runs out in a different tier each time:
Follow the arithmetic for the two scaled hours:
09:00 — G = 135 (Pro-rata scales)
PRIORITY takes its full 75 (30+25+20), leaving R₂ = 60
against tier demand TD = 100 → scale
60/100 = 0.6.
R1: 60 × 50/100 = 30 · R2: 60 × 30/100 = 18
· R3: 60 × 20/100 = 12. FIXED receives nothing.
Σ = 75 + 60 = 135 = G ✓ — conservation holds.
12:00 — G = 205 (Fixed scales)
PRIORITY 75 full, PRO_RATA 100 full, leaving R₃ = 30
against total entitlement TF = 50 → scale
30/50 = 0.6.
F1: 20 × 0.6 = 12 · F2: 20 × 0.6 = 12 · F3:
10 × 0.6 = 6.
Σ = 75 + 100 + 30 = 205 = G ✓
And the period roll-up — exactly what the Allocations page's Roll-up: Σ = … kWh line describes when you sum every hour:
| Off-taker | 06:00 | 09:00 | 12:00 | 13:00 | Total (MWh) | Of demand |
|---|---|---|---|---|---|---|
| P1 (rank 1) | 30 | 30 | 30 | 30 | 120 | 100% |
| P2 (rank 2) | 25 | 25 | 25 | 25 | 100 | 100% |
| P3 (rank 3) | 5 | 20 | 20 | 20 | 65 | 81% |
| R1 | 0 | 30 | 50 | 50 | 130 | 65% |
| R2 | 0 | 18 | 30 | 30 | 78 | 65% |
| R3 | 0 | 12 | 20 | 20 | 52 | 65% |
| F1 | 0 | 0 | 12 | 20 | 32 | 40% |
| F2 | 0 | 0 | 12 | 20 | 32 | 40% |
| F3 | 0 | 0 | 6 | 10 | 16 | 40% |
| Surplus | 0 | 0 | 0 | 15 | 15 | — |
| Σ (= G) | 60 | 135 | 205 | 240 | 640 | — |
Read the last column: the tiers degrade in the promised order. Priority ranks 1–2 are untouched even in the worst hour; rank 3 loses only in the worst hour; the pro-rata tier shares shortfall equally (all 65%); the fixed tier — the shock absorber — fills only in high-generation hours (40%). This is the pattern to expect on your own Allocations page whenever generation is tight.
9.4 Conservation & rounding
This section is the Outcomes proof that a settled month still adds up. It is not a side note on waterfall maths. After settlement writes the month, you open the same Allocation tab, switch to Outcomes · settled, and read whether every metered kilowatt-hour is still on the table.
Think of the plant's meter as a jug. Settlement poured that jug through the published allocation hierarchy (§7), glass by glass. Conserved means every drop is either in a buyer's glass or still in the jug as Surplus. Nothing vanished; nothing appeared from nowhere.
Follow along. Seat:
ipp_2@webill.net(passwordsupersecret). Path: Generator sites → IPP2 Atlantis Wind → Strategy → Allocation, mode Outcomes · settled. Address:/org/generator-sites/<id>/strategy/allocations?month=2026-07. You should see the heading Who got what, the sticky mode bar (#allocation-mode-bar) with a note like Jul 2026 · conserved, the month picker with a green Conserved badge (data-role="conservation-badge"), then Where N went, Members, Allocation by hour with the exhaustion strip, and the Hourly waterfall. Explanations (#allocation-explanations-open) opens the shared right-hand drawer; the Conserved term reads Σ allocations + surplus reconciles to metered generation (within 1 kWh).
Data. full_demo · seed 42 · IPP2 Atlantis Wind · last checked 2026-09-14. Field-by-field cards stay in §9.5. This section is why the conservation stamp lives on Outcomes, and how to read it.
Why this sits in chapter 9
Chapter 9 is the monthly receipt — the settled replay. §9.1 through §9.3 teach how demand is resolved and how the waterfall carves an hour. Conservation is the check that those carves still equal the meter. It belongs here because Outcomes is the only Allocation mode that replays persisted settlement intervals and stamps the month Conserved or Conservation error. Rules writes the seating plan. Forecast pours next month on paper. Neither of those is this receipt.
9.4.1 Open Outcomes — the click path
- Sign in as the IPP organisation that owns the plant.
- Open Generator sites, pick the site, then Strategy → Allocation.
- On the sticky bar, press Outcomes · settled
(
#allocation-mode-outcomes). - Confirm the address carries
?month=YYYY-MMwhen you arrived from the mode bar or from Forecast's Open {Mon YYYY} → Outcomes link. - Use ◀ / the month input / ▶ to pick a settled month — usually last month, once the runner has written intervals (§14).
- Read the green Conserved badge before any buyer conversation.
The shareable address is
/org/generator-sites/:id/strategy/allocations?month=YYYY-MM.
The mode bar builds that link when a month is in hand. The on-page
picker and chevrons reload the month in the session; they do not rewrite
the address bar. If you open /allocations with no
month query, the page loads the current calendar month —
which is often empty until that month settles.
Empty copy: No settled intervals for this period. That is not a receipt yet. Pick another month or wait for settlement.
9.4.2 Receipt, draft, and paper
Three different objects share the Allocation tab. Do not mix them.
| Object | Mode | What it is | Does it rewrite the month? |
|---|---|---|---|
| Receipt | Outcomes · settled | Persisted settlement intervals for a chosen month. Nothing is recomputed. The conservation badge is the stamp on this receipt. | No — this is the history buyers argue against |
| Draft | Rules · hierarchy | An unpublished seating plan. The card If this draft had been in force in … re-carves last month through the draft and shows its own conservation tick — a preview, not a rewrite | Publishing never recomputes a settled month (§7) |
| Paper | Forecast · next month | Next month's carve on FG (Forecasted Generation). A guess you can sell from, not a meter proof | After the month settles, compare paper to this receipt (§8.1.8) |
A draft on Rules is a seating plan you have not published. A settlement period may also pass through a DRAFT status on the PPA page before it is ready — that is a different word (V8 §11). Outcomes only shows hours that already have persisted intervals.
9.4.3 Who uses it, and when
The IPP commercial desk and anyone who must answer a buyer's statement. Open Outcomes after the month has settled — typically the last complete month — when a statement says "we received 1,240 MWh" and your meter says the plant made 3,100 MWh.
Do not open Outcomes to change who is served next month (that is Rules) or to price leftover you have not yet sold (that is Forecast, then Sales). Use it to prove what already happened, and to check that the books still balance before you quote a number.
flowchart TB
A[Month settles] --> B[Open Allocation → Outcomes]
B --> C[Confirm month and Conserved]
C --> D{Badge}
D -->|Conserved| E[Read Members and hours with buyers]
D -->|Conservation error| F[Stop — fix meters / settlement]
D -->|Empty| G[Wrong month or runner not yet]
- Wait until settlement has written intervals.
- Open Outcomes · settled for that month.
- Read Conserved before Members or the waterfall.
- A red Conservation error stops the commercial conversation (§9.6).
9.4.4 The identity and the 1 kWh tolerance
The books must always balance. Formally, for every hour:
Conservation identity
Σ allocations + surplus = metered generation
Exact in decimal arithmetic. On Outcomes, an hour (and the month) is
Conserved when
|Priority + Pro-rata + Fixed + Surplus − Generation| ≤ 1 kWh
— the LiveView tolerance. Residue from 3-decimal kWh storage is assigned
to surplus so a member's rounded figure is never nudged to make
the identity hold.
Settlement verifies the identity for every settled hour. The month
badge is green only when every hour in the picker
passes. In the worked day above:
625 allocated + 15 surplus = 640 generated — every hour
individually and the day in aggregate.
Where this is taught. The settlement ledger's Σ = 0 proof (money across parties) is V8 §1.2. This section is the IPP energy identity on Outcomes.
9.4.5 Where the proof lives on Outcomes
The same identity appears in several places. They must agree.
| Place | Id / role | What you read |
|---|---|---|
| Mode note | #allocation-mode-outcomes |
Mon YYYY · conserved or conservation error |
| Month bar badge | data-role="conservation-badge" |
Green Conserved or red Conservation error |
| Explanations drawer | #allocation-explanations-open → term
Conserved |
The one-line definition above. Same drawer on Rules and Forecast |
| Members footer | #ipp-allocations-members |
Σ = generation … ✓ (or ✗). Surplus row is first-class so the proof sits in the table |
| Hourly waterfall ticks | #ipp-allocations-waterfall ·
data-role="trace-table" |
Green check or red warning per hour, same 1 kWh test |
| Roll-up | data-role="rollup" |
Σ of Priority + Pro-rata + Fixed + Surplus across every row; when conserved it equals Σ Generation (§9.5.4) |
| Allocation by hour | #ipp-allocations-by-hour ·
#allocation-stack |
The dark Generation line should sit on the top of the stack |
| Exhaustion strip | #ipp-allocations-exhaustion |
Where the cascade ran dry each clock hour — or amber reached Surplus — did not run dry. Grey = no settled hour. Same grammar as Rules (§7.9) |
Hour sort vs the chart. The waterfall
Hour header (#hourly-waterfall-hour-sort)
is a button. It reorders table rows oldest-first or newest-first. It
does not reorder #allocation-stack or the
exhaustion strip — those stay in clock order from the persisted
hours.
Amber leftover is not a warning. Surplus on the strip, on the Members Surplus row, and on midday waterfall rows means every hierarchy seat was served and leftover existed. That is reached Surplus — did not run dry. It can appear on Outcomes as well as on Rules. Treat it as historical leftover, not as "the jug emptied."
Claims (#ipp-allocations-claims) has
its own tick — physical + virtual against generation. That is a
reconciliation, not this energy identity. Honesty note: §9.5.0a.
Every panel on the page is catalogued in §9.5. The operator pictures (healthy receipt, red badge, empty month) are §9.6.
9.5 Reading the Outcomes page
What you see (top → bottom)
| Block | What it shows |
|---|---|
| Mode switch | Rules · Forecast · Outcomes; the Outcomes note reads Jul 2026 · conserved (or conservation error) |
| Month bar | ◀ month ▶ picker, the conservation badge, and the provenance line Carved under v3 · in force at period start linking to that version in Rules |
| Where N GWh went in month | The tier split bar — Priority · Pro-rata · Fixed · Surplus (unallocated) as shares of metered generation, with member names on hover |
| Members | Who got what, by name: energy, share of generation, fulfilment against their demand, tier, with the Surplus row and the conservation line |
| Tier fill | Each tier’s allocation against its demand for the month |
| Claims on this generator | Physical and virtual claims reconciled against generation — a warning when claims oversell it |
| Allocation by hour | Stacked area by Members or by
Tiers, the metered Generation line
over it, day/night wash, and the exhaustion strip
(#ipp-allocations-exhaustion) — the tier where the cascade
ran dry each hour |
| Hourly waterfall | The settlement trace hour by hour (sticky labels, ten rows then scroll); expand a row for the per-member split under that hour’s rule; the Roll-up in kWh and MWh |
| Provenance footer | Source meter, carve path and the hierarchy-version honesty note |
Where this is taught. The same strip on Rules · hierarchy — heading Where the cascade runs dry, typical-day vote, colours, empty states — is V4 §7.9. Outcomes shows it under the hour chart; Rules shows it on the right-hand rail.
9.5.0 Members — who got what, by name
Panel:
#ipp-allocations-members · Table:
data-role="members-table"
This is the settled twin of Forecast's CO table: one row per member PPA, plus a Surplus (unallocated) row so the column sums to the meter. The panel subtitle on screen is Who got what, against their demand. ARF is the share of demand actually met.
The four energy columns — Demand, Allocated, Share, and ARF — answer two different questions. Demand and Allocated are kilowatt-hours for the whole month in the picker. Share and ARF are percentages built from those kilowatt-hours. They do not mean the same thing.
| Column | Unit on screen | Plain meaning | Formula |
|---|---|---|---|
| Demand | kWh (whole number) | What this buyer asked for in the month | Σ each settled interval's demand_kwh |
| Allocated | kWh (whole number, bold) | What settlement carved to them | Σ each settled interval's supply_kwh |
| Share | % (1 decimal) | Their slice of the plant | Allocated ÷ metered generation × 100 |
| ARF | % (1 decimal) | How much of their ask was met | Allocated ÷ Demand × 100 |
Share is not Allocated ÷ Demand. That ratio is ARF. Mixing the two is the usual desk mistake: a buyer can take a large Share of a tight plant and still show a soft ARF.
The other columns on the same table:
| Column | Meaning |
|---|---|
| # | Display order (Priority ranks first, then Pro-rata, then Fixed) |
| Member | Resolved buyer name + agreement ref — links to that PPA's settlements list (never a UUID prefix) |
| Rule | Chip: P · rank n / Pro-rata /
Fixed · ≤ e kWh/h, plus provisional when
demand fell to the provisional rung |
| Of demand | The ARF bar (data-role="arf-bar") — same ratio as ARF,
drawn as a fill capped at 100% width, coloured by the member's tier |
Footer: Σ = generation … ✓ when conservation holds (§9.4). The Surplus row is first-class so the proof lives in the table, not only on the badge.
Note. Tier attribution is reconstructed from the hierarchy version in force at period start (Phase 1). The provenance footer says so when a hierarchy is present — mid-period version changes are not yet windowed per hour on this screen. A
rules: vN →link on the panel opens that board.
Demand
What it is. The month's ask for this named buyer, in kilowatt-hours. The table prints a whole number (the LiveView rounds to 0 decimals).
Where the number comes from. Each settled hour
already stores a demand_kwh on that member's interval.
Outcomes adds those hours up. It does not re-run the
demand ladder. How an hour's demand was resolved — meter, nomination,
contracted profile, or the provisional zero — is §9.1.
What it is not. It is not the plant's generation. It is not the contract's annual volume. It is not Forecast's ED (Expected Demand) for next month — ED is the paper cousin on Forecast.
The footer Demand cell is the sum of every member's Demand. The Surplus (unallocated) row shows — here: leftover has no ask.
Allocated
What it is. The month's carve for this buyer — what they actually received — in kilowatt-hours. Printed bold.
Where the number comes from. Each settled hour
stores supply_kwh for that member. Outcomes adds those
hours up. Nothing on this page recomputes the waterfall; these are the
persisted figures.
How it relates to Demand. Allocated cannot tell a fulfilment story on its own. 1,240 kWh is generous if they asked for 1,240 kWh, and a shortfall if they asked for 2,000 kWh. That comparison is ARF.
The Surplus row's Allocated cell is leftover generation (unallocated kWh). The footer Allocated cell is Σ member Allocated + Surplus, and when the month is conserved that equals metered generation.
Share
What it is. This buyer's slice of the plant's metered generation for the month, as a percentage to one decimal.
Share = Allocated ÷ metered generation × 100
The denominator is the same generation total that Tier fill uses (§9.5.1). A Share of 18.8% means this buyer absorbed 18.8% of what the meter recorded — not 18.8% of what they asked for.
Surplus also has a Share. Leftover ÷ generation. The footer Share cell is 100%: members plus Surplus must cover the plant.
What a desk should notice.
- Quote Share when a buyer says "I took most of the plant."
- A large Share with a soft ARF means the plant was busy serving them and they were still short of their ask.
- A small Share with ARF at 100% means they were a small glass that filled completely.
- Share is not a reliability score. ARF is.
ARF
What it is. ARF (Allocation Reliability Factor) — fulfilment versus this buyer's Demand. On screen it is a percentage to one decimal, not a 0–1 ratio.
ARF = Allocated ÷ Demand × 100
The Explanations drawer (#allocation-explanations-open,
term ARF) says the same thing: the share of demand
actually met (allocated ÷ demand). On the Outcomes Members table it is
the period fulfilment column.
The Of demand bar is the same ratio drawn as a fill. The bar width is capped at 100%; the printed ARF is the number you quote.
Colour on the printed ARF (product classes, not a badge label):
| ARF on screen | Colour | Plain reading |
|---|---|---|
| 90% or above | Green | They were nearly or fully served against their ask |
| 75% up to 90% | Amber | Soft month for this buyer — set expectations |
| Above 0% and below 75% | Rose | Material shortfall versus their demand |
| 0% (or no demand to divide) | Slate | Nothing allocated, or Demand was zero so the ratio is defined as 0.0 |
Surplus has no ARF (the cell is —). Leftover is not a buyer and has no demand.
What a desk should notice.
- Quote ARF when a buyer says "I was short." Short means ARF below 100%, not a small Share.
- Priority ARF near 100% with Fixed ARF much lower is the waterfall doing its job (§9.6 picture 5).
- ARF at 100% does not mean they took the whole plant — look at Share for that.
- HAF also reports ARF (settled ÷ expected). That is the capacity screen's cousin (§5), not this table.
How the four relate
flowchart LR
A[Demand · kWh ask] --> C[ARF = Allocated ÷ Demand]
B[Allocated · kWh carve] --> C
B --> D[Share = Allocated ÷ Generation]
E[Metered generation] --> D
- Demand is the ask. Allocated is the carve.
- ARF compares those two — fulfilment versus the buyer.
- Share compares Allocated to the meter — slice of the plant.
- Σ Allocated (members) + Surplus Allocated must equal generation when the month is Conserved.
Take the four-hour worked day in §9.3 as if it were the whole period (640 MWh generated):
| Member | Demand | Allocated | Share of 640 | ARF |
|---|---|---|---|---|
| P1 (rank 1) | 120 | 120 | 18.8% | 100% |
| P3 (rank 3) | 80 | 65 | 10.2% | 81.3% |
| Surplus | — | 15 | 2.3% | — |
P1 was full (ARF 100%) and took about a fifth of the plant. P3 took a smaller slice and was short of their ask (ARF 81.3%). Same month, two different stories — that is why both columns exist.
Hour vs month. This table is the period roll-up. Expanding an Hourly waterfall row shows Demand / Allocated / Share for that hour only — no ARF column on the nested table (§9.5.3).
9.5.0a Claims — physical vs virtual reconciliation
Panel:
#ipp-allocations-claims
A second card on the same page (same month picker). It answers: do the claims on this generator oversell the plant?
| Field | Meaning |
|---|---|
| Generated | Metered generation for the month |
| Physical (n) | Σ attributed supply on physical PPAs |
| Virtual (n) | Σ attributed supply on virtual PPAs (period totals) |
| Unclaimed | Generation minus physical − virtual |
| Badge | Σ physical + Σ virtual ≤ generation when conserved |
Honesty. Scheduled settlement does not yet carve physical and virtual claims together (
run_claim_setis not on the cron path). This card is a reconciliation of attributed sums — not a claim-set carve table. When that path joins the runner, the same card upgrades without a new route.
9.5.1 Tier fill
Panel:
#ipp-allocations-tier-fill · Title on
screen: Tier fill
Three amber fill bars — one each for Priority, Pro-rata, and Fixed.
| Field on screen | What it is | How to read | What you learn |
|---|---|---|---|
| Tier label | Priority / Pro-rata / Fixed | Left column | Which hierarchy seat the bar belongs to |
| Fill bar | Amber bar over a grey track | Longer = that tier took a larger share of the month's metered generation | Where energy landed over the whole period |
| % | round(tier_allocated ÷ Σ generation × 100), capped at
100 |
Right of the bar | Period share of the plant's metered output |
Important. The bar is not "of that tier's demand". The LiveView uses total metered generation for the period as the ceiling for every bar (a demand proxy per tier is not meaningful once surplus is shared at plant level). A Priority bar at 45% means Priority absorbed 45% of the month's metered kWh — not that Priority buyers got 45% of what they asked for. For fulfilment-vs-demand, use the Members ARF column (§9.5.0), Forecast's CO table (§8.1.4), or the worked-day "Of demand" column above.
What to look for.
- Priority much thicker than Fixed on a tight month → waterfall doing its job (shock absorbed downstream).
- All three bars thin with a large Surplus on the chart → you under-sold relative to generation.
- A red conservation badge with healthy-looking bars → do not trust the fill until the books balance.
9.5.2 Allocation by hour
Panel:
#ipp-allocations-by-hour · Title on
screen: Allocation by hour
Chart intro
(#ipp-allocations-hourly-intro): stack shows each
member's share (or tiers); the Generation line is the meter.
Chart id: #allocation-stack ·
Day/night legend:
#allocation-day-night-legend · Mode
toggle: #allocation-chart-mode
(Members default · Tiers)
How to read the graph
| Piece | What it shows | Plain reading tip |
|---|---|---|
| X-axis | Hour buckets as 16 Jul 26 00
(Format.axis_hour) |
Compact day + 2-digit year + hour — not
2026-07-16 00:00 |
| Y-axis | Energy (kWh) for that hour | Taller stack = more generation that hour |
| Stacked areas (Members) | One series per named member + Surplus | Who ate the hour by buyer; Surplus on top when leftover |
| Stacked areas (Tiers) | Priority → Pro-rata → Fixed → Surplus (bottom → top) | Same waterfall grammar as before when member count is large |
| Generation line | Metered generation overlay | Should hug the top of the stack when conserved |
| Legend | Under the plot (legend_bottom: 2, extra
grid_bottom: 48) |
Match colour → series before arguing a number |
| Day/night wash | Amber daylight 06:30–17:30 (hour buckets 06–17); slate night | Soft dawn/dusk blend at the edges; sun/moon key above the chart |
What to look for (step by step).
- Does the Generation line sit on the stack top? If it floats above or cuts through, conservation is broken — check the badge and the table ticks.
- Where does the stack die? Early Priority-only hours = tight generation. Surplus ribbon on the top = sellable leftover that hour.
- Day vs night. Use the wash: daytime solar humps vs night wind / flat profiles tell different commercial stories.
- Match Tier fill. A thick Priority period bar should look like a large Priority share of the chart's area.
Dies inside Priority
Represents: generation runs out before Priority is full — lower tiers get nothing that hour (worked-day 06:00). React: expect Fixed fulfilment to look terrible on the period; do not promise Fixed buyers this shape will improve without more G or a hierarchy change.
Pro-rata scales
Represents: Priority complete; Pro-rata band present but Fixed absent (worked-day 09:00). React: Pro-rata buyers share shortfall equally — call them with the same % story.
Fixed scales
Represents: Priority + Pro-rata full; Fixed gets a scaled slice, still no Surplus (worked-day 12:00). React: Fixed is the shock absorber — this is the hour shape to show Fixed buyers when explaining a soft month.
Full stack + Surplus
Represents: every tier served; Surplus ribbon under the Generation line (worked-day 13:00). React: that Surplus is sellable history — compare to Forecast AES before promising the next month's leftover.
Day sold · night leftover
Represents: daytime hierarchy absorbs the solar hump; Surplus (or unsold-like leftover) swells in the night wash. React: use the sun/moon legend — evening/night leftover needs night load or firm product, not more noon buyers.
9.5.3 Hourly waterfall
Panel:
#ipp-allocations-waterfall · Title on
screen: Hourly waterfall
Table: data-role="trace-table" ·
Roll-up: data-role="rollup"
One row per settled hour. Column labels stay visible while you scroll
(thead.sticky inside
#ipp-allocations-waterfall-scroll). Ten hour rows fit in
the pane; extra hours scroll. Day hours (06–17, the sun window) shade
amber (bg-amber-50/50); night hours shade slate
(bg-slate-100/70). Each row carries
data-hour-band="day" or "night". Click the
chevron to expand the hour: a nested table lists that
hour's per-member Demand / Allocated / Share (same columns as Members,
hour-scoped).
Every column (collapsed)
| Column | What it shows | How to read | How to react |
|---|---|---|---|
| (▸) | Expand / collapse | Opens the per-member split for that hour | Use when Tier totals are not enough |
| Hour | Compact label 1 Jun 26 06 (axis_hour) plus
optional provisional badge. The Hour
header (#hourly-waterfall-hour-sort) sorts rows
oldest-first or newest-first — the hour chart and exhaustion strip do
not reorder (§9.4.5) |
Confirm the hour and whether meter data was incomplete | Provisional → expect an automatic re-settle; do not treat as final |
| Priority | kWh carved to Priority that hour | 0 when generation died earlier or tier empty | Low across many hours → plant was chronically tight |
| Pro-rata | kWh to Pro-rata | Appears once Priority is satisfied | Shared shortfall should look similar across Pro-rata buyers in Hierarchy |
| Fixed | kWh to Fixed | Last hierarchy seat before Surplus | Soft Fixed hours are expected when G is mid-range |
| Surplus | kWh left after the hierarchy | Only when G exceeds the filled stack | Historical sellable leftover — not a forecast |
| Generation | Metered generation for the hour (bold) | The ceiling the other columns must sum to (with Surplus) | If Generation disagrees with the stack, trust the conservation tick |
| (tick) | Green check / red warning | Conserved when
\|Priority+Pro-rata+Fixed+Surplus − Generation\| ≤ 1 kWh |
Red → escalate settlement / meters before commercial conversations |
Empty body: No settled intervals for this period.
9.5.4 What "Roll-up" means
Top-right of the Hourly waterfall panel:
Roll-up: Σ = N kWh
Plain meaning. Add every cell that is energy across every hour in the table:
Σ = Σ(Priority + Pro-rata + Fixed + Surplus) over all
rows.
When the month is conserved, that total equals Σ Generation for the same rows (within rounding). It is the period energy check in one number — the table's cousin of the green badge.
Data-driven example (worked day → screen)
Take the four methodology hours as if they were the only settled hours in June (units MWh here; the LiveView prints kWh with the same arithmetic):
Per-hour stacks
| Hour | Priority | Pro-rata | Fixed | Surplus | Generation |
|---|---|---|---|---|---|
| 06:00 | 60 | 0 | 0 | 0 | 60 |
| 09:00 | 75 | 60 | 0 | 0 | 135 |
| 12:00 | 75 | 100 | 30 | 0 | 205 |
| 13:00 | 75 | 100 | 50 | 15 | 240 |
Roll-up arithmetic
Priority Σ = 60+75+75+75 = 285
Pro-rata Σ = 0+60+100+100 = 260
Fixed Σ = 0+0+30+50 = 80
Surplus Σ = 0+0+0+15 = 15
Roll-up Σ = 285 + 260 + 80 + 15 = 640
Generation Σ = 60+135+205+240 = 640 ✓
What the screen would show
Roll-up: Σ = 640 kWh (rounded to 1 decimal in the
LiveView)
Badge: Conserved
Tier fill bars ≈ Priority 285/640 ≈ 45%, Pro-rata 41%, Fixed 13% (of period generation — not of demand).
If Roll-up and Σ Generation disagree by more than the 1 kWh tolerance, the badge flips to Conservation error and at least one row shows the red warning icon.
9.5.5 Using Members to answer a buyer
You have just learned each Outcomes panel. A buyer is on the phone with a statement. This section is the walk: which Members column to quote, and when to leave the month table for an hour.
§9.4 is the receipt proof — does the month still add up? §9.5.0 is what each column is. This section is what you do with those four columns. The twelve page pictures (red badge, empty month, Claims, and the rest) stay in §9.6.
The seller’s job, in plain words
Think of the plant's meter as a jug and each buyer as a glass (§9.4). Demand is how big their glass was. Allocated is how much you poured. Share is how much of the jug they took. ARF (Allocation Reliability Factor) is how full their glass is.
| Column | Everyday picture | Quote it when they say… |
|---|---|---|
| Demand | How big their glass was (kWh they asked for) | "How much was I entitled to this month?" |
| Allocated | How much you poured (kWh they received) | "How many kilowatt-hours did I get?" |
| Share | How much of the jug they took | "I took most of the plant." |
| ARF | How full their glass is | "I was short." |
Share is Allocated ÷ metered generation. ARF is Allocated ÷ Demand. They do not mean the same thing. Mixing them is the usual desk mistake.
The on-screen subtitle under Members says the same thing in one line: Who got what, against their demand. ARF is the share of demand actually met.
Follow along. Seat:
ipp_2@webill.net(passwordsupersecret). Path: Generator sites → IPP2 Atlantis Wind → Strategy → Allocation, mode Outcomes · settled. Address:/org/generator-sites/<id>/strategy/allocations?month=2026-07. You should see the heading Who got what, a green Conserved badge, then Members (#ipp-allocations-members) with Demand, Allocated, Share, and ARF. Explanations (#allocation-explanations-open) opens the A–Z drawer if a word is new.
Data. full_demo · seed 42 · IPP2 Atlantis Wind · last checked 2026-09-14. Formulas stay in §9.5.0. This section is the phone-call walk.
Open Outcomes, then walk the page
flowchart TB
A[Open Allocation → Outcomes for the statement month] --> B{Conserved?}
B -->|Empty or red| C[Stop — §9.6 pictures 2 and 3]
B -->|Green Conserved| D[Find the buyer on Members]
D --> E{What did they claim?}
E -->|I was short| F[Quote ARF]
E -->|I took most of the plant| G[Quote Share]
E -->|How many kWh| H[Quote Allocated next to Demand]
F --> I[Hours only if they ask when]
G --> I
H --> I
- Sign in as the IPP that owns the plant.
- Open Generator sites, pick the site, then Strategy → Allocation.
- Press Outcomes · settled
(
#allocation-mode-outcomes). - Match the month picker to the month on the buyer's statement. The
shareable address is
/org/generator-sites/:id/strategy/allocations?month=YYYY-MM. - Read the green Conserved badge
(
data-role="conservation-badge") before any number. A red Conservation error or No settled intervals for this period stops the call — those pictures are §9.6. - On Members, find the named buyer. Read all four columns before you speak.
- Quote ARF for shortfall, Share for "I took the plant", Allocated next to Demand for a kilowatt-hour.
- Open Allocation by hour or expand an Hourly waterfall row only when they ask when they were short.
If a word on the page is new, press Explanations
(#allocation-explanations-open). The drawer is one A–Z list
(AES through Surplus). The ARF term reads the share
of demand actually met (allocated ÷ demand). On the Outcomes Members
table it is the period fulfilment column. The
Conserved term is the 1 kWh identity from §9.4.
You see / It means / Do this
1 · They say they were short
You see. Their ARF is below 100% (amber from 75%, rose below 75% — §9.5.0). Allocated is smaller than Demand.
It means. Settlement did not fill their glass. Short means ARF, not a small Share. They can take a large slice of a tight plant and still be short of their ask.
Do this. Quote ARF and the two kilowatt-hour columns: "You asked for Demand; you received Allocated; that is ARF of your ask." Do not apologise with Share.
2 · They say they took most of the plant
You see. Their Share on Members. The footer Share cell is 100% because members plus Surplus cover the meter.
It means. Share is their slice of metered generation, not of their demand. A Share of 18.8% means they absorbed 18.8% of what the meter recorded.
Do this. Quote Share. If they were also full, say so with ARF at 100%. If they were short, say both numbers — large Share and soft ARF can be true together.
3 · Large Share, soft ARF
You see. A high Share next to an ARF well below 100%.
It means. The plant was busy serving them and they were still short of their ask. The jug was not big enough for that glass.
Do this. Set the expectation from ARF. Do not promise next month from this receipt — that is Forecast, then Sales (§8).
4 · Small Share, ARF at 100%
You see. A small Share and a green ARF at or near 100%.
It means. They were a small glass that filled completely. They did not take the plant; they got everything they asked for.
Do this. Quote ARF first. Use Share only if they claim volume against the fleet.
5 · Priority full, Fixed soft
You see. Priority ARF near 100%. Fixed ARF much
lower. Tier fill
(#ipp-allocations-tier-fill) thick on Priority, thin on
Fixed. The hour chart dies inside Priority or Pro-rata for many
hours.
It means. The published waterfall did its job. Fixed is the shock absorber. This is not a UI bug.
Do this. Set Fixed expectations from ARF. Open Rules only if you intend to change next month's seats — publishing will not rewrite this receipt (§7).
6 · Surplus leftover
You see. A Surplus (unallocated) row on Members: Demand and ARF are —, Allocated is leftover kWh, Share is leftover ÷ generation. Amber on the exhaustion strip reads reached Surplus — did not run dry. Midday waterfall Surplus cells can be greater than zero.
It means. Every hierarchy seat was served and leftover existed. Amber is leftover, not a warning that the jug emptied.
Do this. Treat Surplus as historical leftover. Do not sell next month from it. Compare it to Forecast AES (Available Energy for Sales) — leftover on paper for the month ahead — before you promise new buyers (§8.1.8).
7 · They ask when
You see. Allocation by hour
(#ipp-allocations-by-hour) and the Hourly
waterfall (#ipp-allocations-waterfall).
It means. Members is the month. An expanded waterfall row repeats Demand / Allocated / Share for that hour only — there is no ARF column on the nested table (§9.5.3).
Do this. Expand the hour they care about. The
Hour header (#hourly-waterfall-hour-sort)
reorders table rows oldest-first or newest-first. It does
not reorder the hour chart or the exhaustion strip —
those stay in clock order. Use the strip to say "you were short at
06:00, not at 13:00."
8 · A word on the page is new
You see. Abbreviations (ARF, AES, Conserved, Surplus) without a tooltip on the column header.
It means. The lookup is the shared Explanations drawer, not a second glossary on this page.
Do this. Press Explanations
(#allocation-explanations-open). Same drawer on Rules and
Forecast.
Worked numbers — same four hours as §9.3
Take the four-hour worked day in §9.3 as if it were the whole period (640 MWh generated):
| Member | Demand | Allocated | Share of 640 | ARF | What you say |
|---|---|---|---|---|---|
| P1 (rank 1) | 120 | 120 | 18.8% | 100% | "You were full. You took about a fifth of the plant." |
| P3 (rank 3) | 80 | 65 | 10.2% | 81.3% | "You were short of your ask. You did not take a large slice of the plant." |
| Surplus | — | 15 | 2.3% | — | "Leftover existed. That is history, not next month's sale." |
P1 and P3 are the same month and two different stories. That is why both Share and ARF exist.
What not to do on this walk.
- Do not quote a number when the badge is red or the month is empty — §9.6 pictures 2 and 3.
- Do not treat a provisional badge as final (§9.1).
- Do not add Claims physical and virtual into the Members split by hand (§9.5.0a).
- Do not expect the Hour sort button to move the chart.
Where this is taught. Column formulas: §9.5.0. The receipt stamp: §9.4. The twelve page pictures: §9.6.
9.5.6 Provenance footer
Panel:
#ipp-allocations-provenance
| Line | Meaning |
|---|---|
| Source meter | Generation meter ref(s) feeding the carve |
| Carve path | e.g. Hierarchy waterfall / Flat pro-rata to demand |
| Hierarchy | Version label + honesty note: attribution uses the version in force at period start |
| Open Rules mode | Link to publish or inspect the rule (§7) |
9.6 What you see on Outcomes — reading the receipt
You opened Allocation → Outcomes · settled. A buyer's statement says they received 1,240 MWh. Your meter says the plant made 3,100 MWh. This page is the receipt that must make those two numbers talk to each other.
Think of the settled month as a dinner that already happened. Rules wrote the seating plan. Forecast guessed how much food there would be. Outcomes is the washed-up plates: who got what, whether every kilowatt-hour is still on the table, and where the jug ran dry each hour. Nothing here is cooked again — the page replays persisted settlement intervals.
Follow along. Seat:
ipp_2@webill.net(passwordsupersecret). Path: Generator sites → IPP2 Atlantis Wind → Strategy → Allocation, mode Outcomes · settled. Address:/org/generator-sites/<id>/strategy/allocations. You should see the heading Who got what, the sticky mode bar with a note like Jul 2026 · conserved, the month picker with a green Conserved badge, then Where N went in July 2026 over a tier split, Members beside Tier fill and Claims, Allocation by hour with the exhaustion strip, the Hourly waterfall, and the provenance footer.
Data. full_demo · seed 42 · IPP2 Atlantis Wind · last checked 2026-09-14. Field-by-field teaching of each card stays in §9.5. This section is the operator reading: what a healthy receipt looks like, and what to do when it does not.
flowchart TB
A[Pick the settled month] --> B{Intervals exist?}
B -->|No| C[Empty copy — no receipt yet]
B -->|Yes| D[Read Conserved vs Conservation error]
D --> E[Read Where N went — who took the plant]
E --> F[Members ARF — who was short vs their ask]
F --> G[Hours + dry strip — when the jug emptied]
G --> H{Badge}
H -->|Conserved| I[Use the month with buyers]
H -->|Conservation error| J[Stop — fix meters / settlement first]
- Confirm the month picker matches the month on the statement.
- If the page says No settled intervals for this period, you are not looking at a receipt — pick another month or wait for settlement (§14).
- Read the Conserved badge before any buyer conversation.
- Read Where N went and Members for who received energy.
- Read Allocation by hour and the exhaustion strip for when the cascade ran dry.
- Expand an Hourly waterfall row only when the period totals are not enough.
- A red Conservation error stops the commercial conversation.
The healthy picture
All of these can be true at once:
- The mode note on Outcomes · settled reads Jul 2026 · conserved (month label will match the picker).
- The month bar shows a green Conserved badge
(
data-role="conservation-badge"). - The provenance line reads Carved under vN · in force at period start and the version link opens that board on Rules.
- Where N went in Month Year is a complete Priority · Pro-rata · Fixed · Surplus bar that you can hover for member names.
- Members names every buyer, ends with Surplus (unallocated), and the footer ticks Σ = generation … ✓.
- Allocation by hour has a Generation line that sits on top of the stack, and the exhaustion strip under it is populated.
- Hourly waterfall Roll-up equals Σ Generation (within 1 kWh), and the per-row ticks are green.
If any of those fail, use the pictures below — do not invent a private split.
1 · Green Conserved
You see. Badge Conserved. Mode note … · conserved. Members footer Σ = generation … ✓. Waterfall ticks green.
It means. For every settled hour,
Priority + Pro-rata + Fixed + Surplus matches metered
generation within 1 kWh. The identity is taught in §9.4.
Do this. You may use this month with buyers. Still read ARF before you promise that everyone was full.
2 · Red Conservation error
You see. Badge Conservation error. Mode note … · conservation error. At least one waterfall row shows a warning tick. Members footer will not show a clean tick.
It means. At least one hour does not add up. The books are not safe for a commercial argument.
Do this. Stop. Chase meters and the settlement runner (§14). Do not "fix" a buyer's kWh in a spreadsheet.
3 · Empty month
You see. No settled intervals for this period. No split bar, no hour chart. Waterfall body: No settled intervals for this period.
It means. Settlement has not written this month yet — or you picked a future / unused month.
Do this. Move the picker. Confirm the runner has run. Forecast for a next month is a different mode (§8).
4 · A named buyer's kWh
You see. Members
(#ipp-allocations-members): buyer name, agreement ref, rule
chip (P · rank n / Pro-rata /
Fixed · ≤ e kWh/h), Demand, Allocated, Share,
ARF.
It means. Allocated is what settlement carved to them. ARF is allocated ÷ demand — fulfilment versus their ask, not versus the plant. Share is allocated ÷ metered generation.
Do this. Quote ARF when a buyer says "I was short." Quote Share when they say "I took most of the plant." Deep columns: §9.5.0. The walk: §9.5.5.
5 · Soft Fixed, full Priority
You see. Priority ARF near 100%. Fixed ARF much lower. Tier fill: a thick Priority bar, a thin Fixed bar. Hour chart dies inside Priority or Pro-rata for many hours.
It means. The published waterfall did its job. Fixed is the shock absorber. This is not a UI bug.
Do this. Set Fixed expectations from ARF. Open Rules only if you intend to change next month's seats — publishing will not rewrite this receipt (§7).
6 · Surplus ribbon
You see. Surplus on the split bar, a Surplus row on Members, an amber/top ribbon on the hour chart, Surplus > 0 on midday waterfall rows.
It means. Every hierarchy seat was served that hour (or that month, on the period row) and leftover existed. Amber on the exhaustion strip is reached Surplus — did not run dry — leftover, not a warning that the jug emptied.
Do this. Treat Surplus as historical leftover. Compare it to Forecast AES before you promise next month (§8.1.8).
7 · Provisional hours
You see. A provisional badge on a waterfall Hour, or on a Members rule chip.
It means. Demand fell to the provisional rung — meter evidence was incomplete (§9.1). The hour can re-settle when the real data lands.
Do this. Do not treat those hours as final. Chase completeness (§14).
8 · Claims oversell warning
You see. Claims on this generator
(#ipp-allocations-claims) with Generated, Physical (n),
Virtual (n), Unclaimed, and a warning when claims oversell the
plant.
It means. This is a reconciliation of attributed sums — not a live claim-set carve. Scheduled settlement does not yet carve physical and virtual together.
Do this. Read the honesty note in §9.5.0a. Do not add virtual MWh into the Members physical split by hand.
9 · Generation line leaves the stack
You see. On Allocation by hour, the dark Generation line floats above the coloured stack, or cuts through it.
It means. Conservation is broken for those hours. The badge should already be red.
Do this. Trust the badge and the waterfall ticks, not a napkin re-stack. Same reaction as picture 2.
10 · Exhaustion strip — ran dry vs leftover
You see. #ipp-allocations-exhaustion
under the hour chart: 24 cells (or a month of hour cells) coloured by
the tier where the cascade emptied, or amber reached Surplus — did
not run dry. Grey is no settled hour.
It means. Each cell is when the jug emptied that hour, not how much MWh. Amber leftover is yours — not re-poured into Fixed.
Do this. Use it to explain timing to a buyer ("you were short at 06:00, not at 13:00"). The same strip on Rules is §7.9.
11 · Roll-up vs the badge
You see. Roll-up: Σ = N kWh and = M
MWh (data-role="rollup" /
rollup-mwh).
It means. The sum of every Priority + Pro-rata + Fixed + Surplus cell in the waterfall. When conserved, that equals Σ Generation. Worked arithmetic: §9.5.4.
Do this. If Roll-up and Σ Generation disagree by more than 1 kWh, you are in picture 2.
12 · Provenance disagrees with today's Rules board
You see. Carved under v3 · in force at period
start, but Rules now shows a newer in force chip.
Footer #ipp-allocations-provenance repeats the version
honesty note.
It means. This receipt used the board that was in force at period start. Mid-period publishes are not windowed per hour on this screen (Phase 1). Publishing never recomputes a settled month.
Do this. Open the version link
(#ipp-allocations-version-link). Argue this month against
that board. Change next month on Rules, then wait for Forecast
/ settlement — do not expect Outcomes to rewrite itself.
Bridge. Hierarchy publishes the rule (§7). Forecast rehearses it on FG (§8). Outcomes proves what settlement actually did on meters. Contract-scoped carve on a single PPA page — V8 §12. Operations / settlement runners: §14.
10. Curtailment claims — from the instruction to the money
The IPP’s recovery book: when the grid holds the plant back, this screen is the claim, the clock, the evidence, and the money that did or did not come back.
The IPP’s problem, in plain words
Sunshine and wind arrive whether or not the wires can take the power. When the System Operator (the body that runs the national grid minute to minute — since 2024 the National Transmission Company South Africa, NTCSA) tells your plant to generate less than it could, two losses can happen at once:
- Physical. The plant produced less. That is the curtailment — a cap on output for a window.
- Commercial. Energy you were ready to sell was not delivered, so nobody paid you for it unless a rule says you are still owed. That owed energy is deemed energy: energy treated as if it had been delivered, even though the cap stopped it.
A physical cap does not, by itself, put money in your account. Being paid needs a curtailment claim — a dated record that says which instruction caused the loss, how much energy was lost, how that number was worked out, what it is worth, when you sent it, and what was paid. This chapter is that record. The live instruction feed (acknowledge, ramp, reason code) lives with the System Operator; the commercial log that makes a non-dispatchable curtailment an instruction for market settlement is a different protection, taught in V12 §3.6. This chapter is the PPA / congestion-framework claim you lodge so deemed energy can be recovered.
Think of a bakery that had the ovens hot and the loaves ready, then a traffic officer closed the road to the shop for three hours. The officer’s ticket is the instruction. The claim form — how many loaves would have sold, at what price, with the weather and the meter attached — is this screen. The loaves that would have sold are deemed energy. Filing the form before the posted deadline is lodgement. A later cheque from the insurer is provisional payment; the final assessment is the final determination. You do not bake a new claim from a blank page. The ticket creates the draft; you check it, attach the evidence, and send it.
Follow along. Seat:
ipp_2@webill.net(passwordsupersecret). Path: Generator sites → (your wind or solar site) → Strategy → Curtailment (/org/generator-sites/:id/strategy/curtailment). You should see a clock strip for drafts, money totals, and a table of claims. The table opens on last SAST month (#curtailment-month-picker). An empty month reads No curtailment claims in {Month YYYY}. Pick the month of the instruction — the worked fixture in this chapter is March 2027.
Data. Worked money in this chapter is the platform fixture used by the claim tests (100 MW Eastern Cape wind, 10 March 2027, 10:00–13:00 SAST, 40 MW cap, 62.0 c/kWh, 100 % seller share). Illustrative, not a sealed
full_demostatement line. last checked 2026-09-10.
Words you need on this screen
| Plain English | Platform word | One-sentence meaning |
|---|---|---|
| The traffic officer’s ticket | SO instruction of kind CURTAILMENT | A cap (MW), a start, an end, a reason, and an external reference |
| Energy ready but not delivered because of the cap | Deemed energy | Potential output minus the greater of the meter and the cap, never below zero |
| The claim form | Curtailment claim | One stable reference (claim_ref) with insert-only
versions |
| Which recovery route applies | Curtailment regime | Congestion framework, PPA buyer pays, or uncompensated |
| Filing the form | Lodge | Mark the draft as sent, with evidence; the app does not email NTCSA by itself |
| First cheque | Provisional payment | Money recorded as received before the operator’s last word |
| The operator’s last word | Final determination | Energy (kWh) and Rand the counterparty finally accepts |
| Claim minus what was finally paid | Unrecovered | The positive remainder on a finished file; the fourth totals tile sums it |
| Asked minus the first cheque, on an open file | Cash at risk | The fifth totals tile; a Draft is not yet at risk |
| Typical unrecovered loss over a year | Annual exposure | The sixth tile; it ignores the month picker. Not a Money Room tile. |
10.1 From the instruction to recovery
Open Curtailment on a generator site’s Strategy
area. You do not type a new claim. An ended curtailment
instruction creates the draft. A replacement instruction that arrives
while the draft is still unlodged rewrites that draft as a new
version, keeping the same stable
claim_ref. After you lodge, a replacement does not silently
rewrite the sent claim.
The hourly job ClaimClock (20 * * * *,
minute 20 of every hour) does four passes:
- Find ended CURTAILMENT instructions for a generator site and open or refresh the draft.
- Flag an unlodged draft when fewer than 12 hours remain (amber Due soon).
- Escalate at the deadline (red Overdue). A historical replay can be overdue the moment it appears; it is not discarded.
- Retry drafts that still say pending inputs.
The ledger keeps together: instruction references, regime, deemed method, deemed energy, claimed Rand, payments, and the lodgement deadline. Deadlines on screen are SAST. The owner records actions. Traders whose active supply-pool membership holds the site can read claims and exports; they cannot record a new version. Who may lodge is §10.6.
flowchart TB
A[System Operator issues a curtailment cap] --> B[Window ends]
B --> C[ClaimClock opens or refreshes a DRAFT]
C --> D{Replacement instruction while still DRAFT?}
D -->|Yes| C
D -->|No| E{Compensation regime?}
E -->|Uncompensated| F[Close at once as UNCOMPENSATED]
E -->|Framework or PPA buyer| G[DRAFT sits on the Curtailment tab]
G --> H[You review, prepare evidence, lodge]
The same steps in words:
- The System Operator caps the plant.
- When the window is over, ClaimClock writes a draft with a stable
claim_refsuch asCC-<first eight of site id>-<YYYYMMDD>-<last eight of instruction>. - If a later instruction supersedes the earlier one before lodgement, the draft is versioned with the new instruction list.
- The regime is classified (table below). UNCOMPENSATED drafts close immediately — there is no lodgement clock.
- You work the remaining drafts on this tab.
| Regime | When it applies | Who the money is aimed at | What the draft does |
|---|---|---|---|
| CONGESTION_FRAMEWORK | Wind site in the Eastern or Western Cape, instruction reads as network congestion (not a system-event / emergency reason), and the dated framework rule is in force (seeded 1 Apr 2025 – 31 Mar 2028) | Public procurement PPA, explicitly ticked on the PPA’s curtailment terms → NTCSA (CPA). Otherwise an off-taker energy credit at the PPA price. Listing the site as public on the marketplace does not make it a public PPA. | Stays DRAFT with a 48-hour clock. A framework-connected wind site needs an effective wind curve and breakpoints before its first trading day. |
| SYSTEM_EVENT_PPA | The plant is not on that framework path, and the PPA’s grid-operator allocation is BUYER_RISK or DEEMED_ALWAYS | The PPA buyer, via settlement’s existing curtailment-credit line | Draft exists. Seller share is 0 % on this claim because the buyer already pays in settlement — you do not lodge this as an NTCSA claim for the same energy. |
| UNCOMPENSATED | Anything else: private plant outside the framework whose PPA leaves grid-operator curtailment with the seller (SELLER_RISK), or SHARED (there is not yet a negotiated split field on the terms) | Nobody on this ledger | Closed at once as UNCOMPENSATED. Shared risk still stores 50 % seller share on the claim for exposure maths; it is not a payable claim today. |
A system-event / emergency reason code on a wind site takes it off the congestion framework (the instruction is not treated as congestion). After 31 Mar 2028 the seeded framework row no longer matches, so the same Eastern Cape wind plant falls through the same table as any other site.
Where this is taught. How an instruction is issued, acknowledged and ramped is V12 §3.2. The operator’s Claims tab and Dispatch Desk column are V12 §7. PPA curtailment terms are negotiated in V7.
10.2 Read the estimate
The plant’s estimate of deemed energy is not the operator’s later determination. You lodge the plant estimate. They may pay a different quantity. Both stay on the claim.
What is being counted
For each full hour the meter can currently substantiate:
deemed kWh = potential kWh − max(metered kWh, cap kWh), then floored at zero.
- Potential is what the plant would have made (weather through the power curve, or another method below).
- Cap is the instruction’s MW limit turned into kWh
for that hour:
cap_kWh = cap_MW × 1,000 × minutes / 60. - Metered is what actually left the site.
If the plant itself failed to reach the cap, that shortfall is not deemed. If potential is 35 MWh and the cap is 40 MWh, deemed is 0 even if the meter shows 20 MWh — the grid did not stop you from making the 35 MWh you could. Curves already include their technical losses; the export does not apply a second loss factor.
A partial-hour window stays pending until finer evidence can support it. The current meter seam substantiates full hours only. Pending inputs names what is missing and blocks lodgement. It is never stored as a zero-energy claim.
Which method is used
The PPA’s preferred deemed-energy method is tried first when its
inputs exist. Otherwise the engine walks a chain and stops at
the first method that can compute. Missing inputs are named;
the next method is tried. The operator’s later figure is recorded as
payment, not silently used as the plant estimate unless nothing else can
be computed (SO_SCADA_ESTIMATE).
flowchart TB
A[PPA preferred method if named] --> B{Inputs exist?}
B -->|Yes| Z[Compute and stop]
B -->|No| C[Plant power curve]
C --> D{Curve and weather exist?}
D -->|Yes| Z
D -->|No| E[Historical average]
E --> F{At least 20 curtailment-free comparable hours?}
F -->|Yes| Z
F -->|No| G[Contracted PPA profile]
G --> H{PPA profile for those hours?}
H -->|Yes| Z
H -->|No| I[Operator estimate if explicitly supplied]
I --> J{Figure supplied?}
J -->|Yes| Z
J -->|No| K[PENDING INPUTS — cannot lodge]
| Method | What it uses | Refuses (stays pending) when |
|---|---|---|
| RESOURCE_POWER_CURVE (usual PPA default) | Issued weather and the site’s PV or wind curve (same conversion as the plant model) | No curve; no weather; weather issued after the hour; solar without GHI; wind that cannot be brought to hub height |
| HISTORICAL_AVG | Mean of comparable curtailment-free hours, scaled by interval length | Fewer than 20 comparable hours on any interval |
| CONTRACTED_PROFILE | The PPA contracted kWh for that hour | No physical PPA, or no profile kWh. The site’s uncontracted forecast shape is not substituted. |
| INDEPENDENT | An independent engineer’s signed kWh and reference | Either quantity or reference missing |
| SO_SCADA_ESTIMATE | An operator deemed quantity you supply | No operator figure. Never guessed from the cap alone. |
Worked example — three hours, then Rand
Inputs (Eastern Cape wind, public PPA, seller share 100 %):
| Input | Value |
|---|---|
| Installed / export | 100 MW |
| Instruction | 40 MW cap, 10:00–13:00 SAST on 10 March 2027 (08:00–11:00 UTC) |
| Potential (curve × weather) | 77.2 MW average across the three hours |
| Meter | 39,850 · 39,920 · 40,000 kWh (at or below the cap) |
| PPA energy price | 62.0 c/kWh |
| Seller share | 100 % |
Per hour the cap is 40 × 1,000 × 60 / 60 = 40,000 kWh.
Metered energy is at or below that, so
max(meter, cap) = 40,000 kWh. Deemed per hour is
77,200 − 40,000 = 37,200 kWh. Three hours:
37,200 + 37,200 + 37,200 = 111,600 kWh = 111.600 MWh.
Conservation for the window: potential 231.6 MWh =
allowed 120.0 MWh + deemed 111.6 MWh. ✓
Money:
claimed R = deemed kWh × rate c/kWh × seller share % / 100 / 100
R1: 111,600 × 62 × 100 / 100 / 100 = R 69,192.00
Stored as integer cents: 6,919,200. The screen prints R 69,192.00.
Inspect the recorded rate source before you prepare
a claim. A PPA must resolve unambiguously for contract-specific pricing
(PPA_TARIFF). If there is no PPA price, the regime’s
reference price may be used (REGIME_REFERENCE_PRICE, 65.0
c/kWh on the seeded framework row). If neither exists, the rate source
is NONE and claimed money stays empty.
10.3 The clock, review, and export CSV
You are still on Curtailment claims. §10.2 told you how deemed energy and Rand were counted. This step is the back-office job that sits between that estimate and lodging: check the draft while the clock is still open, freeze the slips that prove the number, and take a copy you can keep or attach.
Everyday picture, same bakery as the chapter opener: the traffic officer’s ticket already created the claim form. Review is reading that form and the weather, curve, and meter slips stapled to it. Prepare evidence is stamping the pack so nobody can swap a page later. Export CSV is photocopying the form. The evidence bundle is the sealed photocopy whose fingerprint matches the stamp. You have about two days after the road reopened to post the pack. Posting itself is §10.4.
Follow along. Seat:
ipp_2@webill.net(passwordsupersecret). Path: Generator sites → (Cape wind site) → Strategy → Curtailment (/org/generator-sites/:id/strategy/curtailment). Pick March 2027 on#curtailment-month-picker(the table defaults to last SAST month). Click Review on a Draft row (#open-claim-<id>). You should see the right-hand drawer#claim-drawer, then Export CSV at the foot. On an owner seat, Prepare evidence is the green button next to it.
Data. The CSV rows below are the platform claim-export fixture (
curtailment-claim-1, 100 MW Eastern Cape wind, 10 March 2027 10:00–13:00 SAST, 40 MW cap, 62.0 c/kWh). Same numbers as §10.2. Illustrative, not a sealedfull_demodownload. last checked 2026-09-16.
Why you are still on this tab
Three things share this section because they are one job:
| Plain English | Button or strip | Why it matters |
|---|---|---|
| How long you have to file | Clock strip #claim-clock-strip and the red/amber
deadline on the row |
An unlodged draft goes Due soon then Overdue. The money does not file itself. |
| Check the form before you send it | Review (#open-claim-<id>) |
Opens the drawer. You are looking at this version of this claim, not inventing a new one. |
| Take a spreadsheet copy | Export CSV / Evidence bundle CSV | A CSV (Comma-Separated Values) file is a text table any spreadsheet can open. You keep it, attach it, or prove later that the bytes have not changed. |
The table of claims — columns, badges, totals — is §10.7. This section is what happens after you press Review.
The lodgement clock
The normal deadline is 48 hours after the instruction ends. The PPA field emergency confirm hours (default 48) or the regime row can change it. The hourly ClaimClock job (minute 20 of every hour, taught in §10.1) flags an unlodged draft at the start of its final 12 hours and escalates at the deadline. Times on screen are SAST (South African Standard Time) — two hours ahead of UTC, no daylight saving.
- 13:00 D Instruction ends · DRAFT appears
- 01:00 D+2 Due soon (12 hours left)
- 13:00 D+2 Overdue if still unlodged
On the worked window that ended 13:00 SAST on 10 March 2027, lodgement is due 13:00 SAST on 12 March 2027. The row prints that as Due 12 Mar ’27 13:00:00, then Due soon · …, then red Overdue · …. A row with no compensation route prints No lodgement route — there is nothing to file.
The grey strip above the table (#claim-clock-strip)
counts drafts in the month you picked: N drafts in March
2027 awaiting lodgement. Deadlines are shown in SAST.
What happens, in order
flowchart TB
A[Open Strategy then Curtailment] --> B[Pick the instruction month]
B --> C{Rows in this month?}
C -->|No| D[Empty line: No curtailment claims in Month YYYY]
C -->|Yes| E[Click Review on the Draft]
E --> F[Read frozen inputs, versions, missing list]
F --> G{Deemed energy computed?}
G -->|No — pending inputs| H[Stop. You cannot lodge]
G -->|Yes| I[Owner: Prepare evidence]
I --> J[Read the SHA-256 fingerprint]
J --> K[Download Export CSV]
K --> L{Bundle already frozen?}
L -->|Yes| M[Download Evidence bundle CSV]
L -->|No — read-only or skipped Prepare| N
M --> N[Lodge — taught in 10.4]
The same steps in words:
- Open Strategy → Curtailment on the generator site.
Tab icon
hero-bolt-slash. Heading Curtailment claims. - Set Month (
#curtailment-month-picker) and, if you wish, Status (#curtailment-status-filter). The address becomes/org/generator-sites/:id/strategy/curtailment?month=2027-03(add&status=DRAFTto hide lodged rows). - Find the Draft whose clock is still open. Click Review.
- Read the drawer. If
#claim-missing-inputslists missing items, stop — lodgement is refused until those exist and the draft is recomputed. - On an owner seat, click Prepare evidence. Read the fingerprint.
- Click Export CSV. After a bundle exists, also click Evidence bundle CSV if you need the sealed bytes.
- Filing the draft is §10.4. Do not skip steps 4–5; the Record form will refuse a draft with no bundle.
Review — what you are looking at
Review does not send anything. It opens a right-hand
drawer (#claim-drawer) over a dim backdrop. Escape or the X
(#close-claim-drawer) closes it. The table stays on the
month you picked.
| Your problem | You need to see this claim’s frozen slips, its version history, and whether anything is still missing, before you freeze a pack or file it. |
| Click path | Generator sites → site → Strategy → Curtailment →
pick the month → Review on the row
(#open-claim-<id>). |
| Who may open it | Anyone who can see the tab — owner, viewer, or a trader with an active supply-pool membership. Who may prepare is §10.6. |
Claim drawer sample view
| On the drawer 1 | What it is 2 |
|---|---|
| CC-…-20270310-… · Draft · v1 | Stable claim reference, status badge, version chip |
| Amber missing-inputs line | Named gaps — empty when the estimate is computed |
| Setpoint / availability / meter quality | Honesty markers: ABSENT / UNKNOWN today |
| Frozen instructions, curves, weather and meter | The fold that shows the exact slips |
| Version 1 Draft · 10 Mar ’27 13:20:00 | History of this claim_ref |
| Export CSV · Prepare evidence | Foot of the drawer — help sentence above the green button |
-
1Header (
#claim-drawer-title) is the stableclaim_ref, not the plant name. Replacements keep the reference and bump the version. - 2You are reviewing the plant estimate — the number from §10.2 — not the operator’s later determination.
| Id | What you see | Plain meaning |
|---|---|---|
#claim-drawer-title |
The claim_ref |
One claim across replacements. Example shape:
CC-<first eight of site id>-<YYYYMMDD>-<last eight of instruction>. |
| Status badge | Draft, Lodged, … | Same words as the table. Colours: slate Draft, blue Lodged, amber Provisionally paid, green Reconciled, violet Closed, rose Disputed. |
v1 chip |
Version number | Each Record writes a new version. You are looking at the current one. |
#claim-missing-inputs |
Comma-separated names, or blank | What still blocks the estimate. Pending inputs is never stored as a zero-energy claim. |
#claim-stale-weather |
Weather issue exceeds its provider freshness window. Review the frozen issue time. | The weather used for that hour was issued too early. The number is still frozen; you decide whether to trust it. Hidden when every hour is fresh. |
#claim-evidence-markers |
Setpoint feedback: ABSENT · Availability: ABSENT · Meter quality: UNKNOWN (F12 pending) | Honesty labels, not missing data you can type in. Plant setpoint and availability feeds are not wired on this drawer yet; meter quality is not graded yet. The words stay until those integrations land. |
#claim-bundle-hash-label |
Sealed pack fingerprint (SHA-256). This stamps the file you will lodge. Nothing has been sent. | Caption above the hash. Shown whenever a bundle exists. |
#claim-bundle-hash |
A long hex string | Shown after Prepare (or when a bundle already
exists), under #claim-bundle-hash-label. This is the
SHA-256 (Secure Hash Algorithm, 256-bit) fingerprint —
a unique stamp of the exact sealed file. Two files with the same stamp
are the same bytes. |
#claim-frozen-inputs |
Fold: Frozen instructions, curves, weather and meter inputs | Open it to read the snapshot as stored. This is what the engine used, not a live re-read of today’s weather. |
#claim-versions |
Version N + badge + SAST time |
The insert-only history for this claim_ref. Older rows
stay; they are superseded, not deleted. |
#claim-email-template |
To / From / Subject / body | Only when the channel is Email template. Demo Mock does not show this block. The application still does not send mail. |
#claim-action-form |
Record list and fields | How you lodge and pay. On a Draft, Record offers
only Mark as sent (simulated when mock). Close
reason code (#claim-close-reason) is a list of
WITHDRAWN, HISTORICAL_NOT_LODGED, and
UNCOMPENSATED — pick one and record to close without
lodging. Hidden once the current version is Closed.
Taught in §10.4. |
#claim-export |
Export CSV | White button. Tooltip: Download this claim as a CSV ledger row. Always shown while the drawer is open. |
#claim-evidence-export |
Evidence bundle CSV | White button. Tooltip: Download the frozen evidence bundle as CSV. Shown only after a bundle exists. |
#prepare-claim-help |
Plain sentence above the foot buttons | Draft, owner seat. Before a pack: Prepare evidence seals this version’s hours, weather and meters into a pack. You cannot lodge until that pack exists. It does not send anything to the operator. After a pack: This draft is sealed. Lodge from Record when you are ready… Hidden for viewers and after the row leaves Draft. |
#prepare-claim |
Prepare evidence | Green button. Tooltip: Seals this version’s hours, weather and meters into a pack. You cannot lodge until that pack exists. Nothing is sent to the operator. Drafts only, owner seat. |
Empty and quiet states on the way in. No rows: No curtailment claims in March 2027. (or No Draft claims in March 2027. if you filtered). A foreign organisation cannot open another company’s site — the route raises not-found, and a guessed export address returns 404 Claim not found. Closing the drawer does not change the claim.
Prepare evidence — freeze the slips
Prepare evidence takes the slips already stored on
this version and writes a sealed pack. It does not
re-fetch weather. It does not email anyone. The drawer says so in
#prepare-claim-help before you press the button: you cannot
lodge until that pack exists, and nothing is sent to the operator. On
the demo Mock channel it also builds a simulated send
template (no To/From block). On Email template it fills
#claim-email-template so you can copy the cover note.
| Your problem | You cannot lodge until a bundle exists. You also need a fingerprint you can write on the cover note. |
| Click path | Drawer open on a Draft → green Prepare
evidence (#prepare-claim). |
| Who may press it | Users of the owning organisation whose role is not viewer. A viewer or a trader sees the drawer and can export, but not this button. |
What happens, in order.
- The page checks you may edit, the row is still Draft, and the builder can snapshot this version.
- The sealed file is stored. The drawer prints
#claim-bundle-hash-label(Nothing has been sent.) and the hex in#claim-bundle-hash.#prepare-claim-helpswitches to This draft is sealed. - Evidence bundle CSV appears next to Export CSV.
- A second click on the same version returns the same pack — it does not stamp a new fingerprint.
- If anything fails, the flash reads Could not prepare this claim. Typical causes: you are read-only, the row is no longer a draft, or the builder refused.
A revised draft (a replacement instruction, or a
recompute) is a new version. It needs its own Prepare.
Lodging the new version without that pack is refused
(bundle_missing). Later weather edits do
not rewrite a pack you already froze.
Careful. The stamp is proof of which bytes you sealed, not proof that NTCSA received them. A Mock
MOCK-…reference is cut from the same hash. It is never a receipt from the operator.
Two downloads — why they are not the same file
Both buttons download a .csv named
{claim_ref}-v{version}.csv, for example
CC-EC-WIND-1-20270310-1-v1.csv. Both are
GET /org/generator-sites/:site_id/strategy/curtailment/claims/:id/export.csv.
Evidence bundle CSV adds ?bundle=true.
| Button | Address | What the bytes are | When to use it |
|---|---|---|---|
| Export CSV | …/export.csv |
The platform’s live curtailment-claim-1 rendering
of this row: claim fields, Rand, each hour, and the honesty
markers. If a bundle exists, the bundle_sha256 cell is
filled. |
Your working copy — check the hours, attach a readable table, keep a desk file. |
| Evidence bundle CSV | …/export.csv?bundle=true |
The stored sealed bytes from Prepare. Their SHA-256
must match #claim-bundle-hash. Extra
evidence rows hold the frozen instruction, weather, curve
and meter snapshots as JSON. |
The file you treat as the pack you filed. After lodgement this is the one that matches the recorded hash. |
Neither file is an operator-approved NTCSA template. The format is
the platform’s own versioned dump. Excel or Numbers will open it if you
pick UTF-8 / comma. Cells that could be read as a spreadsheet formula
are prefixed with ' so they stay text.
What happens, in order, when you click either
button. The browser requests that address with your signed-in
session. The server checks the claim belongs to this site and is visible
to your organisation. The response is text/csv with
Content-Disposition: attachment. The Curtailment page does
not flash and does not change. A seat that cannot see the claim gets
404 Claim not found. — the file is not
leaked.
Done for a review-and-export pass looks like this:
the drawer is open on the right claim and version; missing-inputs is
empty (or you have stopped because it is not);
#claim-bundle-hash is showing; your download list has
{claim_ref}-v{version}.csv; if you also pulled the bundle,
a hash of those bytes matches the drawer. You have not lodged yet.
What each CSV column means
The file is not a single grid with one header. It is stacked sections. The first row of each block tells you which section you are in.
Claim block — each row is section,
key, value with section =
claim:
| Key | Plain meaning | Worked fixture |
|---|---|---|
renderer_version |
Which layout this file uses | curtailment-claim-1 |
claim_ref |
Stable claim reference | CC-EC-WIND-1-20270310-1 |
version |
Which insert-only row | 1 |
generator_site_id |
The plant | EC-WIND-1 |
registration_id |
Market registration, if any | WIND-REG |
physical_ppa_id |
The PPA that priced the claim | PPA-WIND |
regime |
Recovery route (§10.1) | CONGESTION_FRAMEWORK |
instruction_refs |
SO ticket id(s); replacements join with \| |
SO-2027-0310-0417 |
deemed_method |
How potential was computed (§10.2) | RESOURCE_POWER_CURVE |
deemed_method_source |
Why that method: PPA term vs fallback chain | PPA_TERM |
deemed_status |
COMPUTED or still pending |
COMPUTED |
deemed_kwh |
Plant estimate, kilowatt-hours | 111600.000 (= 111.600 MWh) |
rate_ckwh |
Price used, cents per kWh | 62.0000 |
claimed_cents |
Money as integer cents | 6919200 |
claimed_r |
Same money in Rand | 69192.00 (screen: R 69,192.00) |
inputs_hash |
Fingerprint of the inputs the engine saw | fixture-inputs on the toy file |
status |
Draft / Lodged / … | DRAFT |
window_start_sast / window_end_sast |
Cap window in SAST with offset | 2027-03-10T10:00:00+02:00 →
…T13:00:00+02:00 |
bundle_sha256 |
Sealed-pack fingerprint | Empty until Prepare; then the same hex as the drawer |
Hours block — after a header row the section is
intervals. One row per hour the estimate used:
| Column | Plain meaning | Worked hour (10:00 SAST) |
|---|---|---|
interval_start_sast |
Hour start in SAST | 2027-03-10T10:00:00+02:00 |
potential_kwh |
What the weather × curve would have made | 77200.000 |
metered_kwh |
What actually left the site | 39850.000 |
cap_kwh |
Instruction cap turned into kWh | 40000.000 |
deemed_kwh |
potential − max(meter, cap), floored at 0 |
37200.000 |
wind_ms_at_hub |
Wind speed at hub height (m/s) | 9.600000 |
ghi_w_m2 |
Solar irradiance. Empty on a wind hour | (blank) |
temperature_c |
Air temperature | 25 |
Three such hours:
37,200 + 37,200 + 37,200 = 111,600 kWh. That is the
conservation already proved in §10.2: potential
231.6 MWh = allowed 120.0 MWh + deemed
111.6 MWh. ✓
Honesty block — section =
evidence:
| Key | Value today | What it is saying |
|---|---|---|
setpoint_feedback |
ABSENT |
No plant-setpoint trace is stored on the claim yet. |
availability |
ABSENT |
No availability declaration is stored on the claim yet. |
meter_quality |
UNKNOWN (F12 pending) |
The meter kWh is used; its quality grade is not wired. |
technical_losses |
Included in curve; no second loss factor |
Do not apply another loss on the export. |
The bundle file repeats that claim/hours layout and
then appends further evidence rows whose values are JSON
snapshots of the instruction, weather points, curve, and meter
intervals. You do not edit those rows. You keep them so a later reader
can see exactly what was frozen.
Worked excerpt — what a short Export CSV looks like
Data. Bytes from
WB.Brp.ClaimExportagainst the §10.2 wind fixture. Toyclaim_refCC-EC-WIND-1-20270310-1.bundle_sha256is empty because this render is before Prepare.
"section","key","value"
"claim","renderer_version","curtailment-claim-1"
"claim","claim_ref","CC-EC-WIND-1-20270310-1"
"claim","deemed_kwh",111600.000
"claim","claimed_r",69192.00
"claim","window_start_sast","2027-03-10T10:00:00+02:00"
"intervals","2027-03-10T10:00:00+02:00",77200.000,39850.000,40000.000,37200.000,9.600000,,"25"
"evidence","setpoint_feedback","ABSENT"
Read it as: one draft claiming 111,600 kWh at R 69,192.00 for a window that started 10:00 SAST; the first hour made 37,200 kWh of deemed energy because potential 77,200 sat above a 40,000 kWh cap; setpoint evidence is honestly ABSENT.
Who the file is for. You, before you lodge; a colleague who works in a spreadsheet; an auditor who must see hours, not only the table total; the cover-note attachment on the email channel. It is not an invoice, not the operator’s determination, and not the Fleet Export CSV on §2.6.
Edges and refusals
- Prepare is hidden when your seat is read-only or the row is not Draft. Pressing it anyway (or after the row moved) flashes Could not prepare this claim.
- Evidence bundle CSV is hidden until a bundle
exists. Adding
?bundle=trueby hand before Prepare still returns the live Export CSV rendering — the controller only serves stored bytes when evidence is on the row. - A pending-inputs draft can still be reviewed and exported. The hours block may be empty. You cannot lodge it.
- UNCOMPENSATED rows have no lodgement clock. You can still open Review and take a copy so the loss is not silent.
- Guessing another organisation’s export address returns 404. The body is Claim not found.
- Closing the download dialog does not lodge, prepare, or change status.
- A Mock receipt, or a hash on a cover note, is never evidence that NTCSA received a claim.
Words on this drawer
| Word on screen | Plain meaning |
|---|---|
| Review | Open the drawer. Nothing is sent. |
| Prepare evidence | Freeze this version’s slips and show the SHA-256 stamp. |
| Export CSV | Download the live curtailment-claim-1 table for this
row. |
| Evidence bundle CSV | Download the sealed bytes whose hash matches the drawer. |
| SHA-256 | Fingerprint of those exact bytes. Same stamp ⇒ same file. |
| Frozen inputs | The instruction, curve, weather and meter snapshot the engine used. |
| ABSENT / UNKNOWN | Honesty: that feed or grade is not wired yet. Not a zero you typed. |
| Due / Due soon / Overdue | 48-hour clock (or the PPA/regime override), last 12 hours, then missed. |
| No lodgement route | This regime does not file — usually UNCOMPENSATED. |
| Simulated channel — nothing was sent | Amber pill #claim-mock-badge. Demo truth. |
Where this is taught. Filing the draft, channels, payments and close reasons are §10.4. Who may press Prepare versus who may only read is §10.6. The claims table itself is §10.7. The operator’s view of the same claims is V12 §7.
10.4 Lodge and reconcile
Lodging is filing the draft, not creating it. You cannot lodge until deemed energy is computed and an evidence bundle exists.
The place you do that filing — and every later payment, dispute, or
close — is the Record form in the Review drawer
(#claim-action-form). It is not one fixed set of boxes. The
status badge on the claim decides which
Record choices you get, which fields appear, and which
codes the ledger will accept. Think of it as a stamp
book: each press of Record new version writes
a new page and leaves the old page in the history. You never overwrite
the filed letter.
Where this is taught. Checking the drawer, the 48-hour clock, Prepare evidence, and both CSV downloads are §10.3. Who may press Record is §10.6.
Follow along. Seat:
ipp_2@webill.net(passwordsupersecret). Path: Generator sites → site → Strategy → Curtailment → Review (#open-claim-<id>). The form sits in the scroll of#claim-drawer, above the foot buttons. A viewer seat sees the drawer and can export, but not this form.
10.4.1 The Record form — who sees it, what it always does
| Your problem | You must move a claim from draft to paid (or closed) without inventing a step the ledger will refuse. |
| Click path | Curtailment tab → Review →
#claim-action-form. |
| Who may use it | Users of the owning organisation whose role is not viewer. A viewer or trader sees This seat can read claims only. if they somehow submit. |
| Hidden when | The current version is Closed, or you cannot edit. Export CSV can still be used. |
What happens, in order, when you press green
#record-claim (Record new version).
- The page checks you may edit and that a claim is selected.
- On a Draft, if Close reason code is one of WITHDRAWN, HISTORICAL_NOT_LODGED, or UNCOMPENSATED, the submit is treated as close, not lodge — even though Record still reads Mark as sent. Leave that list on Select a close reason if you mean to lodge.
- Any other status uses the Record list you picked.
An action that is illegal for this status is refused
(
illegal_action). - A success flash reads Claim version recorded. The badge and
version chip move on. History in
#claim-versionsgains a row. - A refusal flash reads Claim refused: plus the code (for
example
pending_inputs,bundle_missing,stale_version). A bad amount or timestamp reads Enter a valid amount, timestamp and reference.
The form changes as you pick Record
(phx-change="record_form"), except on a
Draft, where the lodge fields and the draft
close-reason list stay on screen together.
10.4.2 Every field on the form
These are the only boxes the form can show. Which ones you see depends on status and the Record choice, taught per status below.
| Id | Label on screen | What it is | Tooltip (product copy) |
|---|---|---|---|
#claim-record-action |
Record | The legal next step. The list is the whole menu — you cannot type a fourth action. | Changes with status (quoted in each status below). |
#claim-reference |
Message / payment reference (when lodging) or Payment reference | The channel or operator reference stored on this version. | Lodge: The message or channel reference for this lodgement. Payment: Required. The operator’s payment reference for this version. |
#claim-timestamp |
Timestamp | Instant with a UTC offset, for example
2027-03-11T09:14:00+02:00. The ledger prints it in
SAST (South African Standard Time). |
Enter ISO-8601 with a UTC offset. The ledger shows the same instant in SAST, for example 11 Mar ’27 09:14:00. Placeholder matches that example. |
#claim-amount |
Amount (R) | Rand for a provisional payment or a final determination. Stored as integer cents. | Required. Amount in Rand for this payment or determination. |
#claim-final-kwh |
Final energy (kWh) | Kilowatt-hours the operator finally accepts. Only on Final determination. | Required. The operator’s final energy figure in kilowatt-hours. |
#claim-close-reason |
Close reason code | Draft-only list. | Allowed on a Draft: WITHDRAWN, HISTORICAL_NOT_LODGED, or UNCOMPENSATED. Prompt: Select a close reason. |
#claim-dispute-reason |
Dispute reason | Free text. | Required. Say why you are disputing this claim. |
#claim-status-close-reason |
Close reason code | List for Close after Disputed or Reconciled. | Close reasons are codes, not free text. Only codes allowed for this status are listed. |
#claim-confirmed |
I confirm the message was sent (required for email) | Tick. Demo Mock does not need it. Email template lodgement is refused without it. | (no ⓘ) |
#record-claim |
Record new version | Submits the form. | — |
ISO-8601 is the dated clock string with an offset
(+02:00), not a bare calendar date. SAST
is two hours ahead of UTC.
The green Prepare evidence button is not on this form. It lives on the drawer foot, Draft only, and is taught in §10.3.
10.4.3 Draft
Status badge: slate Draft. Default Record:
Mark as sent (simulated when mock)
(lodge).
Record list — one row only. There is no Provisional, Final, Dispute, or Close in the list. Closing a draft is the Close reason code beside it, not a Record choice.
Record ⓘ: On a Draft the only Record action is Mark as sent. Pick a close reason code to withdraw the draft instead of lodging.
Fields always shown on a Draft (they do not hide when you change Record, because there is only one Record choice):
| Field | Required to lodge (Mock) | Required to lodge (Email template) | Required to close |
|---|---|---|---|
| Message / payment reference | No (Mock stores MOCK- plus the first sixteen characters
of the bundle hash if you leave it blank) |
Yes | No |
| Timestamp | No (the ledger uses now if blank) | Yes — the actual send instant | No |
| I confirm the message was sent | No | Yes | No |
| Close reason code | Leave on Select a close reason | Same | Pick WITHDRAWN, HISTORICAL_NOT_LODGED, or UNCOMPENSATED |
Hidden: Amount (R), Final energy (kWh), Dispute reason.
Also on the drawer, not the form: Prepare
evidence. You cannot lodge without a sealed pack
(bundle_missing). Pending inputs or empty claimed Rand is
pending_inputs.
Close codes on a Draft — what the ledger actually accepts.
| Code | What it means | The form lists it? | The ledger accepts it? |
|---|---|---|---|
| WITHDRAWN | You take the draft back. Nothing is filed. | Yes | Yes, on any Draft |
| HISTORICAL_NOT_LODGED | A past window you are not filing | Yes | Yes, on any Draft |
| UNCOMPENSATED | No compensation route | Yes, on every Draft | Only if this claim’s regime is already UNCOMPENSATED. A congestion-framework or PPA draft that picks it is refused. ClaimClock already auto-closes true uncompensated drafts. |
After a successful close the form disappears (status is Closed). After a successful lodge the form rebuilds for Lodged.
10.4.4 Lodged
Status badge: blue Lodged. Default Record: Provisional payment.
Record ⓘ: On a Lodged claim you can record a provisional payment, a final determination, or a dispute. You cannot lodge again or close until a later status.
| Record choice | Fields | Required | New status |
|---|---|---|---|
| Provisional payment | Payment reference, Timestamp, Amount (R) | All three | Provisionally paid |
| Final determination | Payment reference, Timestamp, Amount (R), Final energy (kWh) | All four | Reconciled (writes a reconciliation line) |
| Dispute | Dispute reason | The reason | Disputed |
Hidden: Prepare evidence, both draft close codes, confirmation tick, the post-reconcile close list. You cannot lodge a second time. You cannot close from Lodged.
Skipping the first cheque is allowed: Final determination from Lodged is legal. Provisional then becomes R 0.00 in the variance arithmetic.
10.4.5 Provisionally paid
Status badge: amber Provisionally paid. Default Record: Final determination.
Record ⓘ: After a provisional payment you can record the final determination or open a dispute.
| Record choice | Fields | Required | New status |
|---|---|---|---|
| Final determination | Payment reference, Timestamp, Amount (R), Final energy (kWh) | All four | Reconciled |
| Dispute | Dispute reason | The reason | Disputed |
Not in the list: Provisional payment (already done), lodge, close. A second provisional is refused.
A provisional payment does not close the claim. Cash at risk on the tab still counts this row until a final or a close.
10.4.6 Disputed
Status badge: rose Disputed. Default Record: Final determination.
Record ⓘ: On a Disputed claim you can record a corrected final determination or close as CONCEDED.
| Record choice | Fields | Required | New status |
|---|---|---|---|
| Final determination | Payment reference, Timestamp, Amount (R), Final energy (kWh) | All four | Reconciled |
| Close | Close reason code — CONCEDED only | That code | Closed |
You cannot dispute again from Disputed. You cannot lodge or record another provisional. CONCEDED means you drop the dispute — you are not recording a payment.
10.4.7 Reconciled
Status badge: green Reconciled. Default Record: Close.
Record ⓘ: On a Reconciled claim you can dispute the outcome or close with PAID_IN_FULL or ACCEPTED_VARIANCE.
| Record choice | Fields | Required | New status |
|---|---|---|---|
| Dispute | Dispute reason | The reason | Disputed (you can then record a corrected final) |
| Close | Close reason code — PAID_IN_FULL or ACCEPTED_VARIANCE | That code | Closed, if the ledger allows the code |
PAID_IN_FULL is accepted only when the reconciliation line is MATCHED (variance R 0.00) or WITHIN_TOLERANCE (inside the regime’s Rand / percent band, default the larger of R 50 and 0.1 %). A VARIANCE line — claimed and final disagree by more than that band — must use ACCEPTED_VARIANCE, or Dispute first. That is why the worked wind file below cannot close as paid in full.
Export CSV and Evidence bundle CSV stay on the foot. Reconciled is not the end of the file; it is the operator’s last word until you close or dispute. Those two downloads are taught in §10.3.
10.4.8 Closed
Status badge: violet Closed. There is no
Record form. #claim-action-form is omitted.
Prepare evidence is omitted. You can still open the
drawer, read history, and download CSV.
Close is a destination, not a status you Record from. How you arrived is the close reason stored on that version:
| Code | You arrived from |
|---|---|
| PAID_IN_FULL | Reconciled, matched or within tolerance |
| ACCEPTED_VARIANCE | Reconciled, you accepted the difference |
| CONCEDED | Disputed |
| WITHDRAWN | Draft |
| HISTORICAL_NOT_LODGED | Draft |
| UNCOMPENSATED | Draft whose regime is uncompensated (often ClaimClock, not this form) |
flowchart TB
subgraph draftForm [Draft form]
D1[Record: Mark as sent]
D2[Close reason empty → lodge]
D3[Close reason set → close]
end
D1 --> D2 --> L[Lodged]
D1 --> D3 --> C[Closed]
L --> P[Provisionally paid]
L --> R[Reconciled]
L --> X[Disputed]
P --> R
P --> X
R --> C
R --> X
X --> R
X --> C
How you lodge, click by click
- Open Strategy → Curtailment on the generator site.
- Find the DRAFT whose clock is still open.
- Click Review.
- If
#claim-missing-inputslists missing items, stop. Lodgement is refused until those exist and the draft is recomputed. - Click Prepare evidence. Read the hash.
- Optionally download Export CSV.
- Under Record, the only choice on a
Draft is Mark as sent (simulated when
mock). Fill the fields the channel needs (below). Leave
Close reason code on Select a close reason.
Click Record new version (
#record-claim). To withdraw the draft instead, pick WITHDRAWN, HISTORICAL_NOT_LODGED, or UNCOMPENSATED and record — the draft closes and nothing is lodged.
flowchart TB
A[DRAFT with computed deemed energy] --> B[Prepare evidence]
B --> C{Channel}
C -->|Mock demo| D[Record lodge — simulated receipt]
C -->|Email template| E[You send the cover note and CSV]
E --> F[Tick I confirm the message was sent]
F --> G[Timestamp with UTC offset + message reference]
D --> H[Status LODGED]
G --> H
H --> I[Record provisional payment]
I --> J[Record final determination]
J --> K{Match?}
K -->|Yes| L[Close PAID_IN_FULL]
K -->|Accept difference| M[Close ACCEPTED_VARIANCE]
J --> N[Dispute with a reason]
N --> J
Channels — what “sent” actually means
| Channel | What happens | What you must enter |
|---|---|---|
| Mock (demo default) | Status becomes LODGED. A MOCK-…
reference is stored from the bundle hash. The amber pill
Simulated channel — nothing was sent is the truth. |
Amount/timestamp fields are not the proof; Mock does not talk to NTCSA. |
| Email template | The drawer shows To / From / Subject / body. The application does not send mail and does not guess a mailbox. | Confirmation tick, actual send timestamp with UTC
offset (example 2027-03-11T09:14:00+02:00), and a
message reference. All three, or lodgement is refused. |
| Portal upload | Unavailable. | Refused as channel_not_available. |
You cannot lodge if the status is not DRAFT, deemed status is PENDING_INPUTS, claimed Rand is empty, evidence was not prepared, or your seat is read-only.
How it is paid out
Each recorded action writes a new version. The previous row is superseded; history is kept. Illegal jumps are refused (stale version if you act on an old copy). The tables below are the same rules as §10.4.3–§10.4.8, as a lookup.
A provisional payment does not close a claim. DISPUTED can be opened from LODGED, PROVISIONALLY_PAID or RECONCILED; a corrected final determination is another version. Close reasons are codes, not free text. On a Draft, Record lists only Mark as sent; the close-reason list is WITHDRAWN, HISTORICAL_NOT_LODGED, and UNCOMPENSATED.
| Record action | Allowed from | Required fields | New status |
|---|---|---|---|
| Provisional payment | LODGED | Amount in Rand, timestamp with offset, payment reference | PROVISIONALLY_PAID |
| Final determination | LODGED, PROVISIONALLY_PAID or DISPUTED | Amount in Rand, final energy (kWh), timestamp, reference | RECONCILED (writes a reconciliation line) |
| Dispute | LODGED, PROVISIONALLY_PAID or RECONCILED | A reason (required) | DISPUTED |
| Close | See reasons below | A close reason code | CLOSED |
Close reasons:
| Code | When it is allowed |
|---|---|
| PAID_IN_FULL | RECONCILED, and the line is matched or within tolerance |
| ACCEPTED_VARIANCE | RECONCILED (you accept the difference) |
| CONCEDED | DISPUTED — you drop the dispute |
| WITHDRAWN | DRAFT only |
| HISTORICAL_NOT_LODGED | DRAFT only |
| UNCOMPENSATED | DRAFT only, and only if the regime is already UNCOMPENSATED (the form lists it on every Draft; the ledger refuses it otherwise) |
Variance = final payment − provisional payment. Unrecovered = max(claim − final, 0). A provisional payment is not a close.
| Line | Energy | Amount |
|---|---|---|
| Plant claim (111.600 MWh × 62.0 c) | 111,600 kWh | R 69,192.00 |
| Provisional payment | — | R 67,208.00 |
| Final determination | 110,100 kWh | R 68,262.00 |
| Variance (final − provisional) | — | R 1,054.00 |
| Unrecovered (claim − final) | — | R 930.00 |
| Provisional + variance = final | R 68,262.00 ✓ | |
R 67,208.00 + R 1,054.00 = R 68,262.00. Unrecovered is measured against the original claim, not against the provisional. Closing PAID_IN_FULL is refused while the line is classified as a quantity variance — use ACCEPTED_VARIANCE or dispute first.
This is the pattern to expect on your own page: claimed, provisional and final as three numbers, variance under them, unrecovered only once a final exists.
Careful. Demo gallery rows can walk every status with Mock payments. Those are demonstrations, not received operator determinations.
10.5 Exposure and the Money Room
You now have three leftovers that sound like the same pile of money. They are not.
- What this plant typically fails to recover over a year.
- What this month’s finished claim files still owe you.
- What the organisation finance page lists as money left on the table in the period you picked.
The first is Annual exposure. The second is this tab’s Unrecovered tile (§10.7). The third is a Loss Ledger sentence on the Money Room — not a second Annual exposure tile.
Everyday picture, same bakery as the chapter opener: Annual exposure is the insurer’s typical year of storm damage after claims — last year’s pattern, priced, with an expected recovery already taken off. This month’s Unrecovered tile is the stack of closed tickets that paid short. The Money Room is the accountant’s notebook for the whole company: “what we left on the table this month.” It may list a finished shortfall. It does not reprint the insurer’s year card.
Follow along. Seat:
ipp_2@webill.net(passwordsupersecret). Path: Generator sites → (Cape wind site) → Strategy → Curtailment (/org/generator-sites/:id/strategy/curtailment). Look at the sixth white tile#curtailment-exposure. Then open Overview (the dashboard) and scroll to Chapter 4 — you should see a second white card#ipp-curtailment-exposure. Then open Money Room in the organisation sidebar (/org/money). You should not see a tile labelled Annual exposure.
What Exposure means
Exposure here is not “the claim in front of you” and not “cash still waiting on an open file.” Those are Claimed and Cash at risk.
Annual exposure is a year-ahead estimate of the seller’s unrecovered curtailed value on this generator site: if the grid keeps holding the plant back the way it usually does, and if recovery stays as it has been, how much Rand might you fail to get back over a year.
It is built from:
- a volume of curtailed energy (kilowatt-hours the plant was ready to make, but the cap stopped),
- a price (the PPA energy price — the Power Purchase Agreement — or the framework reference price),
- the seller share (how much of that loss sits with you),
- a recovery ratio (how much of past claims actually came back).
The tile prints a Rand amount, or the words no basis. It never invents R 0.00 when the engine cannot compute. A real zero would mean “we computed zero.” Missing inputs mean the words no basis.
Where you actually see it
The built product shows the same estimate in two IPP places. Neither is the Money Room. Neither is a dark tile.
| Screen | Path | Label on screen | Id | What it is |
|---|---|---|---|---|
| Curtailment claims | Generator sites → site → Strategy → Curtailment | Annual exposure | #curtailment-exposure |
Sixth white [data-role=stat-card] in
#claim-totals. Basis chip and limit line under the figure.
Ignores the month picker. How the six tiles look is §10.7. |
| IPP Dashboard · Chapter 4 | Generator sites → site → Strategy → Overview | Annual curtailment exposure | #ipp-curtailment-exposure |
A white card (bg-white) under the plant’s loss ledger.
Same compute. Basis under the figure. A Review claims
link back to this tab. No limit line on this card. |
| Money Room | Organisation sidebar · currency icon · /org/money |
(none) | — | There is no Annual exposure tile — not a dark tile,
not a white tile, not a #curtailment-exposure card. Panel 4
may list a different leftover (below). |
The dashboard Chapter 4 loss ledger row Curtailment unrecovered is yet another surface: it values finished shortfalls in the plant story. That ledger is §12.5. Do not read it as Annual exposure.
How the estimate is built
The engine is CurtailmentExposure.compute for
this site. Opening either IPP card recomputes it. A
nightly job also writes the same metrics onto the site’s strategy book
so a limit can be classified.
flowchart TB
A[This generator site] --> B{At least one year of deemed-energy history?}
B -->|Yes| C[Volume = trailing 12 months of deemed kWh]
C --> D[Basis: site curtailment history]
B -->|No| E{Framework rule has expected curtailment % and the site has P50 MWh?}
E -->|Yes| F[Volume = P50 MWh × expected curtailment %]
F --> G[Basis: framework expected rate]
E -->|No| H[no basis — tile refuses R 0.00]
D --> I{Price and recovery exist?}
G --> I
I -->|No| H
I -->|Yes| J[Exposure = volume × rate × share × leftover after recovery]
J --> K[White tile on Curtailment]
J --> L[White card on Dashboard]
J -.->|does not print here| M[Money Room]
The same steps in words:
- Look at claims on this site whose window started in the last twelve months and that have a deemed-energy figure.
- If that history exists, volume is the sum of those deemed kilowatt-hours. The line under the figure reads Estimated from this site’s curtailment history.
- If history is too short, and a congestion-framework rule is in force with an expected curtailment percentage, volume is the site’s P50 annual megawatt-hours (the median “normal year” energy) times that percentage. The line reads Estimated from the framework’s expected curtailment rate.
- If neither volume path works, or there is no price, or recovery cannot be stated, the tile prints no basis, and the line under it reads No curtailment history or framework rate yet, so there is nothing to estimate from.
- Price is the PPA energy price in cents per kilowatt-hour, or the framework reference price when there is no PPA price.
- Recovery is 0 % when the regime is UNCOMPENSATED (you are not meant to get this money back). Otherwise it is final ÷ claimed on this site’s already-paid claims in that year, capped between 0 and 1. If nothing has been paid yet, the regime’s expected recovery percentage is used.
- Exposure Rand =
volume kWh × rate c/kWh × seller share % / 100 / 100 × (1 − recovery).
A SHARED PPA still stores 50 % seller share for this maths even though there is no payable lodgement on that path today (§10.1).
Worked private solar (illustrative)
| Input | Value |
|---|---|
| Volume | 396 MWh = 396,000 kWh curtailed over a full year |
| Price | 85.0 c/kWh |
| Seller share | 100 % |
| Recovery | 0 (nothing came back) |
396,000 × 85 × 100 / 100 / 100 × (1 − 0) = R 336,600.00
That is the pattern to expect when history (or the framework default) gives a volume, a price exists, and recovery is zero: the year of lost energy, priced, all on the seller. A site that later recovers half of what it claims would show half that Rand.
Data. Illustrative private-solar year, not a sealed
full_demostatement line. The §10.2 / §10.4 wind fixture has no trailing year and no framework volume on the toy site, so its sixth tile prints no basis — that is honest, not a broken tile. last checked 2026-09-16.
The limit line
If the site’s strategy book has a limit on metric
CURTAILMENT_EXPOSURE_R, the Curtailment tile adds a line in
#curtailment-exposure-limit:
| Line | When |
|---|---|
| Within limit | The estimate sits inside the book limit (figure turns brand green) |
| Limit warning | The estimate is near the limit (amber) |
| Limit breached | The estimate is over the limit (rose) |
| No limit configured | The book has no CURTAILMENT_EXPOSURE_R limit
(slate) |
| No basis for limit assessment | The estimate itself is no basis (slate) |
The Dashboard card does not reprint that limit line. It shows the Rand (or no basis) and the basis chip only.
RefreshCurtailmentExposure runs daily at
02:40 SAST, after the nightly strategy run. It writes
CURTAILMENT_EXPOSURE_R and
CURTAILMENT_EXPOSURE_BASIS onto every generator-site book.
Opening the tile still recomputes; the nightly job is what the limit
classifier and other book readers persist.
What the Money Room shows — and does not
The Money Room
is the organisation energy profit-and-loss page at
/org/money. Currency icon in the organisation sidebar, next
to Billing. It answers “are we making money, what do we owe, what did we
leave on the table?” for the whole organisation, not
one plant’s claim drawer.
Where this is taught. The five panels, the period switcher (calendar month / year to date / rolling 12), grade chips, and the lineage drawer are V16 §7. Loss kinds and baselines are V16 §5. How a finalized claim becomes a recovery fact is V8 §7.10.
It does not show Annual exposure. There is no dark
tile, no white #curtailment-exposure card, no basis line
(Estimated from this site’s curtailment history and its
siblings), and no limit line on /org/money. If you opened
Money Room looking for the sixth Curtailment tile, you are in the wrong
room.
What it can show about curtailment is a Loss
Ledger sentence on Panel 4
(#money-panel4) — peach panel, heading What you are
leaving on the table. The kind is
curtailment_unrecovered. The sentence looks like:
Unrecovered curtailment — 111.6 MWh not deemed · ≈ R 930.00
That row is Unrecovered curtailment: finished-file leftover for the period you picked on Money Room, across the organisation, estimated and ex-VAT (Value-Added Tax excluded), never added to the P&L above. The ≈ prefix is the panel’s “estimated” mark. Confidence is high. The tooltip is the stored baseline: Compared with being paid the contract price for the curtailed energy…
| Money Room fact | Built behaviour |
|---|---|
| Which claims feed it | Current version only. Status RECONCILED or CLOSED. Not WITHDRAWN, not HISTORICAL_NOT_LODGED. Must have deemed energy and a rate. Drafts and superseded versions never inflate the panel. |
| Which window | The claim’s instruction window date, filtered to the Money Room period (that calendar month, that year-to-date, or that rolling 12) — not the Curtailment month picker. |
| The Rand | max(deemed kWh × rate − final paid, 0). A fully paid
file produces no row. |
| Display floor | Rows under R 100 collapse into and N smaller items. The peach total still includes them. |
| Empty copy | No avoidable losses recorded this period. Absence, not a fake R 0.00 exposure tile. |
A matching buyer-side curtailment-credit adjustment is excluded when it names the same claim, or the same contract and exact instruction window, so the same kilowatt-hour is not counted twice. That exclusion is V8 §7.10.
The Market Operator’s NERSA (National Energy Regulator of
South Africa) curtailment-cost CSV reports final
payments, not this year-ahead estimate and not a Money Room
tile. That download lives on the Market Operator accounts desk, not on
/org/money.
How the two rooms relate
They share a source (a finalized claim). They do not share a tile.
flowchart TB
A[Ended CURTAILMENT instruction] --> B[Draft then lodge]
B --> C[Final determination]
C --> D{Ask minus final still positive?}
D -->|Yes| E[Curtailment Unrecovered tile]
D -->|Yes| F[Money Room: Unrecovered curtailment]
D -->|No| G[No leftover row]
H[Trailing year or framework default] --> I[Annual exposure]
I --> J[Curtailment sixth white tile]
I --> K[Dashboard white card]
J -.->|not printed here| L[Money Room /org/money]
K -.->|not printed here| L
The same steps in words:
- The System Operator caps the plant. ClaimClock opens a draft (§10.1).
- You lodge and later record a final determination (§10.4).
- If claimed Rand minus final Rand is still positive, this tab’s Unrecovered tile (fourth of six) adds that remainder for the month you picked here.
- The same finished file can become a Money Room Panel 4 sentence for the organisation period that contains the instruction window. That is leftover this period, not a year-ahead card.
- Annual exposure is a different path: trailing year (or framework default) × price × (1 − recovery). Changing the Curtailment month picker does not move it. Opening Money Room does not print it.
| Leftover | Room | Follows | Formula in one line |
|---|---|---|---|
| Annual exposure | Curtailment #curtailment-exposure · Dashboard
#ipp-curtailment-exposure |
This site, trailing year / framework. Ignores both month pickers. | Typical unrecovered year |
| Unrecovered | Curtailment #claim-total-unrecovered |
This tab’s month + status, this site | Sum of max(claim − final, 0) on finished rows |
| Unrecovered curtailment | Money Room #money-panel4 |
Money Room period, whole organisation | Same leftover idea, as a peach Loss Ledger sentence with ≈ |
Worked walk — the §10.4 wind file
Same payments as §10.4: claimed R 69,192.00, final R 68,262.00.
R 69,192.00 − R 68,262.00 = R 930.00 unrecovered. ✓
On Curtailment for March 2027, the fourth tile can show R 930.00 (amber). On Money Room for March 2027, Panel 4 can show Unrecovered curtailment — 111.6 MWh not deemed · ≈ R 930.00 (R 930 is above the R 100 display floor). Annual exposure does not become R 930.00. On the toy wind fixture it stays no basis until a trailing year or a framework volume exists.
Careful. A Draft adds nothing to Money Room and nothing to Annual exposure’s recovery ratio. Scenario Lab can walk a claim through statuses — V14 — those scripts are not live System Operator determinations.
Where this is taught. The six tiles, including how Annual exposure ignores the month picker, are §10.7. Dashboard Chapter 4 and the
#ipp-curtailment-exposurecard are §12.5. Who may lodge is §10.6. Operator view V12 §7.
10.6 Who may lodge, who may only read
“Who can claim?” is two questions: who is owed money on this instruction, and which seat may press Record.
Who has a compensation route
flowchart TB
A[Ended CURTAILMENT instruction] --> B{Wind in Eastern or Western Cape, congestion, framework dates in force?}
B -->|Yes, public_ppa ticked on terms| C[Lodge toward NTCSA CPA]
B -->|Yes, private| D[Off-taker energy credit at PPA price]
B -->|No| E{PPA grid-operator risk is BUYER_RISK or DEEMED_ALWAYS?}
E -->|Yes| F[Buyer already pays in PPA settlement — not an NTCSA claim]
E -->|No| G[UNCOMPENSATED — no lodgement]
- You lodge toward the operator / framework when the site is CONGESTION_FRAMEWORK. That is the busy back-office path this tab is built for.
- You are already paid by the buyer when the PPA says the buyer bears grid-operator curtailment. Do not treat that as a second operator claim for the same kWh.
- You cannot recover on this ledger when the regime is UNCOMPENSATED (including SHARED until a split field exists on the terms). The closed row is still visible so the loss is not silent.
A framework-connected wind site that has no effective wind curve yet cannot register for its first trading day; without the curve the power-curve method stays pending.
Which seat may act
| Seat | Can see the tab | Can Prepare / Record |
|---|---|---|
| Users of the owning organisation, role not viewer | Yes | Yes |
| Viewer on the owning organisation | Yes | No — This seat can read claims only. |
| Trader whose book has an ACTIVE supply pool with an active membership that resolves to this site | Yes (claims and CSV) | No |
| Any other organisation | No — the route raises not-found | — |
The System Operator sees the same claims from the other side:
registry Claims tab and the Dispatch Desk
Claims column (V12 §7).
Read-only registry API:
/api/v1/registry/participants/:mpid/curtailment-claims and
/api/v1/registry/curtailment-claims/:claim_ref.
10.7 The Curtailment tab, field by field
Path: Generator sites → site → Strategy →
Curtailment. Tab icon hero-bolt-slash. Heading
Curtailment claims. Subtitle: From the instruction
to the evidence and the final determination.
Your problem on this tab is not finding the table. The table is the filing cabinet. The problem is reading the six white tiles above it before you open a drawer: how much you asked for this month, how much has already arrived, what is still waiting, what you already lost, and what a typical year of this plant looks like. Mix those five ideas and you will chase a draft as if it were an unpaid invoice, or treat a closed shortfall as if the operator still owed you this week.
Everyday picture, same bakery as the chapter opener: six envelopes on the counter. Three are the same claim at three stages (what you asked, the first cheque, the last word). Two are leftovers (still waiting versus already written off). The sixth is last year’s typical loss — it does not change when you pick a different month of tickets.
Follow along. Seat:
ipp_2@webill.net(passwordsupersecret). Path: Generator sites → (Cape wind site) → Strategy → Curtailment (/org/generator-sites/:id/strategy/curtailment). Set Month (#curtailment-month-picker) to March 2027. Leave Status (#curtailment-status-filter) on All statuses. You should see six tiles in#claim-totals, then the claims table. A month with no rows still shows the six tiles — the first five read R 0.00.
Data. Tile money below walks the §10.2 / §10.4 wind fixture (100 MW Eastern Cape wind, 10 March 2027, 10:00–13:00 SAST, 40 MW cap, 62.0 c/kWh, claimed R 69,192.00, provisional R 67,208.00, final R 68,262.00). Illustrative, not a sealed
full_demostatement line. last checked 2026-09-16.
What sits above the table (and is not a tile)
Read these first so the six tiles are not confused with the chrome around them.
| Block | Id | What it is |
|---|---|---|
| Mock pill | #claim-mock-badge |
Amber pill Simulated channel — nothing was sent. Demo truth. Not a money tile. Hidden when the channel is not Mock. |
| Month picker | #curtailment-month-picker (form
#curtailment-month-form) |
SAST calendar month. Default is last SAST month.
Chevrons #curtailment-month-prev /
#curtailment-month-next. You cannot page past the latest
claim month or the current SAST month. |
| Status filter | #curtailment-status-filter |
All statuses, or one of Draft, Lodged, Provisionally paid, Reconciled, Closed, Disputed. The tooltip says the table is already limited to the selected SAST month. |
| Clock strip | #claim-clock-strip |
Grey banner, not a [data-role=stat-card] tile. Copy:
N drafts in {Month YYYY} awaiting lodgement. Deadlines are shown in
SAST. N counts Draft rows that
survive both filters. A Lodged filter prints
0 drafts… even if drafts exist that month. |
Empty table copy (the tiles stay): No curtailment claims in {Month YYYY}. or, with a status filter, No {Status} claims in {Month YYYY}. Example: No Draft claims in March 2027.
flowchart TB
A[Month picker] --> C[Rows in this SAST month]
B[Status filter] --> C
C --> D[Clock strip: count of Drafts]
C --> E[Five money tiles: Claimed · Provisional · Final · Unrecovered · Cash at risk]
C --> F[Claims table]
G[This site, trailing year] --> H[Sixth tile: Annual exposure]
The same steps in words:
- Pick the month of the instruction. The address becomes
…/curtailment?month=2027-03. - Optionally pick a status. The address adds
&status=DRAFT(orLODGED,PROVISIONALLY_PAID,RECONCILED,CLOSED,DISPUTED). - The clock strip and the first five tiles re-sum only the rows you can see.
- Annual exposure does not re-sum. It is this plant’s year-ahead estimate, taught in §10.5.
The six tiles
The strip #claim-totals is a six-up grid (two columns on
a narrow screen, three in the middle, six on a wide one). Every child is
a white [data-role=stat-card] with a grey uppercase label,
a large Rand figure, and a green-wash hover — the same family as the
Fleet strip tiles on /org/ipp-sites. There is no seventh
money tile.
| Order | Id | Label on screen | data-tone |
Follows month + status? |
|---|---|---|---|---|
| 1 | #claim-total-claimed |
Claimed | neutral (slate figure) |
Yes |
| 2 | #claim-total-provisional |
Provisional | neutral |
Yes |
| 3 | #claim-total-final |
Final | neutral |
Yes |
| 4 | #claim-total-unrecovered |
Unrecovered | warn (amber figure) when the sum is greater than zero;
else neutral |
Yes |
| 5 | #claim-total-cash-at-risk |
Cash at risk | warn when the sum is greater than zero; else
neutral |
Yes |
| 6 | #curtailment-exposure |
Annual exposure | good / warn / bad from the
limit line; else neutral |
No — site year |
All six store money as integer cents and print with
a space after R and a comma from R
1,000.00 up (R 69,192.00). A missing cent field on
a row prints pending in the table. The
five month tiles never print pending: a nil field
counts as 0, so an empty or unpriced set of rows shows
R 0.00.
The six tiles sample view · after the §10.4 payments
| Claimed 1 | Provisional 2 | Final 3 | Unrecovered 4 | Cash at risk 5 | Annual exposure 6 |
|---|---|---|---|---|---|
| R 69,192.00 | R 67,208.00 | R 68,262.00 | R 930.00 | R 0.00 |
no basis No curtailment history or framework rate yet, so there is nothing to estimate from · No basis for limit assessment |
- 1Claimed is the sum of plant-estimate Rand on the visible rows — what you asked for.
- 2Provisional is the sum of first cheques recorded on those rows.
- 3Final is the sum of last-word Rand the counterparty accepted.
- 4Unrecovered is claimed minus final on closed or reconciled files (amber when above zero).
- 5Cash at risk is claimed minus provisional on files that are still open. After a final, this tile drops to R 0.00.
- 6Annual exposure is the site-year estimate. It does not use this month’s rows. A fixture site with no trailing year and no framework volume prints no basis.
How Claimed, Cash at risk, and Unrecovered differ
Think of three different leftover piles, not three names for one pile.
| Tile | Which rows count | Formula on each of those rows | Plain English |
|---|---|---|---|
| Claimed | Every visible row | Sum of claimed_cents (nil → 0) |
The asking price for this month’s tickets. |
| Cash at risk | Lodged, Provisionally paid, or Disputed only | max(claimed − provisional, 0) |
You have filed. The file is still open. This is what has not yet arrived as a first cheque. |
| Unrecovered | Closed or Reconciled, and the close reason is not WITHDRAWN or HISTORICAL_NOT_LODGED | max(claimed − final, 0) |
The file is finished. They paid less than you asked (or nothing). |
| Annual exposure | Not these rows | Site-year estimate (§10.5) | What this plant typically fails to recover over a year. |
A Draft adds to Claimed (if priced) and to the clock strip. It adds nothing to Cash at risk — you have not posted the form. It adds nothing to Unrecovered — the file is not finished. A UNCOMPENSATED close does feed Unrecovered when the row has a claimed amount: the loss is meant to stay visible.
Claimed — #claim-total-claimed
Your problem. “How much did we ask for, on the tickets I can see?”
What the number is. Sum of each visible row’s
plant-estimate Rand. Unit: South African Rand, two decimal places. Built
from claimed_cents (§10.2:
deemed kWh × rate c/kWh × seller share % / 100 / 100).
Empty / zero. R 0.00 when the month has no rows, every visible row is still pending a price, or you filtered to a status that has no priced rows. The table cell on an unpriced row still says pending; the tile does not.
Colour. Slate (data-tone="neutral"). No
badge.
Filters. Follows month and status. Filter to Draft on the wind fixture and this tile still shows R 69,192.00. Filter to Closed in an empty month and it drops to R 0.00.
Provisional — #claim-total-provisional
Your problem. “How much of a first cheque have we already recorded?”
What the number is. Sum of
provisional_cents on the visible rows. A
provisional payment is the first amount written on the
file before the operator’s last word — not provisional settlement
(that word is a different, earlier statement vintage). Unit: Rand.
Empty / zero. R 0.00 until you record a provisional payment (§10.4). A Draft or a Lodged row with no first cheque contributes zero.
Colour. Slate. No badge.
Filters. Follows month and status. A Draft filter hides a later provisional, so this tile can drop while Claimed still shows the asking price of the drafts.
Final — #claim-total-final
Your problem. “What did they finally accept, in Rand?”
What the number is. Sum of final_cents
on the visible rows. The final determination is the
counterparty’s last word on energy (kWh) and money. The kWh
lives on the row and in the drawer, not on this tile. Unit: Rand.
Empty / zero. R 0.00 until a final is recorded. Variance (final minus provisional) is not a tile — it sits under the row in the Claimed / payments column.
Colour. Slate. No badge.
Filters. Follows month and status. A Reconciled or Closed filter is the usual way to see only finished money.
Unrecovered — #claim-total-unrecovered
Your problem. “On files we already closed, how much of our ask never came back?”
What the number is. For each visible
Closed or Reconciled row that was not
withdrawn and not closed as HISTORICAL_NOT_LODGED:
max(claimed − final, 0), then sum. Nil
final_cents counts as 0, so a closed uncompensated file
with a claimed amount contributes the whole ask. Row maths: §10.4.
Empty / zero. R 0.00 while every visible file is still a draft, lodged, provisionally paid, or disputed — those leftovers belong on Cash at risk, not here. Also R 0.00 when you withdrew the only draft, or closed it as historical-not-lodged.
Colour. Amber figure (data-tone="warn")
when the sum is greater than zero; slate when zero. No extra badge.
Filters. Follows month and status. Filter to Draft and this tile is R 0.00 even if last month’s closed shortfall still exists — you are looking at drafts.
Cash at risk — #claim-total-cash-at-risk
Your problem. “On files we have already sent, how much of the ask has not yet arrived as a first cheque?”
What the number is. For each visible
Lodged, Provisionally paid, or
Disputed row that has a claimed amount:
max(claimed − provisional, 0), then sum. After a final the
row leaves this set, so the leftover moves off this tile (and, once
closed or reconciled, onto Unrecovered if anything
remains).
Empty / zero. R 0.00 on a Draft (you have not filed). R 0.00 after the file is Reconciled or Closed. R 0.00 when a lodged file’s first cheque already covers the ask.
Colour. Amber figure when the sum is greater than zero; slate when zero.
Filters. Follows month and status. Filter to Lodged on the wind fixture before any payment and this tile equals Claimed (R 69,192.00, amber). Filter to All statuses after the §10.4 final and it is R 0.00.
Annual exposure — #curtailment-exposure
Your problem. “If this plant keeps being held back the way it usually is, what might we fail to recover over a year?”
What the number is. A year-ahead
unrecovered estimate for this site, not a sum
of the table. Unit: Rand, or the words no basis (never
an invented R 0.00). Under the figure: the basis in
words — Estimated from this site’s curtailment history,
Estimated from the framework’s expected curtailment rate, or
No curtailment history or framework rate yet, so there is nothing to
estimate from — and a limit line in
#curtailment-exposure-limit. How the estimate is built, the
worked solar year, and the 02:40 refresh are §10.5.
Empty / zero. no basis when volume or price is missing. The limit line then reads No basis for limit assessment. A real R 0.00 would mean “we computed zero”, which this tile refuses to invent.
Colour. The figure follows the limit line:
Within limit is brand green (good);
Limit warning is amber (warn);
Limit breached is rose (bad); No
limit configured or No basis for limit
assessment stays slate.
Filters. Ignores month and status. Change March to February, or All statuses to Draft, and this tile stays put. It is the one envelope that is not this month’s tickets.
Worked walk — one wind claim through the six tiles
Same inputs as §10.2 and the payment lines in §10.4. Month = March 2027, status = All statuses, one visible row.
| When | Claimed | Provisional | Final | Unrecovered | Cash at risk |
|---|---|---|---|---|---|
| Draft (priced, not filed) | R 69,192.00 | R 0.00 | R 0.00 | R 0.00 | R 0.00 |
| Lodged (no payment yet) | R 69,192.00 | R 0.00 | R 0.00 | R 0.00 | R 69,192.00 (amber) |
| Provisionally paid R 67,208.00 | R 69,192.00 | R 67,208.00 | R 0.00 | R 0.00 | R 1,984.00 (amber) |
| Reconciled final R 68,262.00 | R 69,192.00 | R 67,208.00 | R 68,262.00 | R 930.00 (amber) | R 0.00 |
Arithmetic you can re-do:
- Cash at risk after the first cheque:
R 69,192.00 − R 67,208.00 = R 1,984.00. - Unrecovered after the last word:
R 69,192.00 − R 68,262.00 = R 930.00. - Variance on the row (not a tile):
R 68,262.00 − R 67,208.00 = R 1,054.00. - Conservation of the payments:
R 67,208.00 + R 1,054.00 = R 68,262.00✓
This is the pattern to expect on your own page: Claimed stays still once the estimate exists; Cash at risk lights amber while the file is open; Unrecovered lights amber only after the file finishes short; Annual exposure does not join this walk.
Pick Status → Draft on the reconciled month and the five money tiles collapse to R 0.00 — that finished row is hidden. The sixth tile does not move.
The claims table
Curtailment claims sample view
| Claim / window 1 | Regime / method 2 | Deemed 3 | Claimed / payments 4 | Status / deadline 5 | Evidence 6 |
|---|---|---|---|---|---|
|
CC-…-20270310-… 10 Mar 2027 10:00 SAST |
CONGESTION_FRAMEWORK RESOURCE_POWER_CURVE · PPA_TERM |
111.600 MWh |
R 69,192.00 Provisional R 67,208.00 Final R 68,262.00 Variance R 1,054.00 |
LODGED Due 12 Mar 2027 13:00 SAST |
Review |
- 1Claim / window is the stable reference and the window start in SAST. Replacements keep the reference and change the version.
- 2Regime / method is the recovery route and how deemed energy was computed (PPA term vs fallback chain).
- 3Deemed is MWh, or pending inputs when the estimate cannot be computed.
- 4Claimed / payments is the plant estimate, then provisional, final, and variance. Empty money prints as pending.
- 5Status / deadline is DRAFT / LODGED / … plus Due, Due soon, Overdue, or No lodgement route.
-
6Review opens the drawer
(
#claim-drawer). Escape or the X closes it. What you check and download there is §10.3.
Status badges on the row use data-role="claim-status":
slate Draft, blue Lodged, amber
Provisionally paid, green Reconciled,
violet Closed, rose Disputed.
The drawer Record form
(#claim-action-form) is taught status-by-status in §10.4: which Record choices, which
fields, and which close codes each badge allows. The form is hidden once
the current version is Closed.
10.8 Common questions
Can I create a claim by hand? No. Only an ended CURTAILMENT instruction (or a replacement of one) opens a draft.
Is this the same as acknowledging the SO feed? No. Acknowledge the instruction on the feed so the operational record is complete. Lodging this claim is the commercial recovery file. The commercial-log check that protects a renewable from balancing penalties is V12 §3.6.
Does Mock mean NTCSA has the file? No.
What is the difference between Export CSV and Evidence bundle CSV? Export CSV is the live readable table for this row. Evidence bundle CSV is the sealed bytes whose SHA-256 matches the drawer. Both are taught in §10.3.
Why is deemed pending on a two-hour-and-ten-minute window? Full hours only on the current meter seam.
Why did my SHARED PPA close as UNCOMPENSATED? The terms do not yet carry a negotiated split percentage. 50 % is stored for exposure; there is no payable lodgement on that path today.
Why is seller share 0 % on SYSTEM_EVENT_PPA? The buyer pays in settlement. This ledger does not double-count that as an operator claim.
Why is Cash at risk R 0.00 on a Draft that already shows Claimed R 69,192.00? You have not filed. Cash at risk only counts Lodged, Provisionally paid, and Disputed rows. The clock strip is what counts drafts. Taught in §10.7.
Why did Annual exposure stay put when I changed the month? That sixth tile is the site-year estimate, not this month’s tickets. §10.5 builds the number; §10.7 is the tile.
Is Annual exposure on the Money Room?
No. /org/money has no Annual exposure tile — dark or white.
Panel 4 may show Unrecovered curtailment, a period
leftover from finished files. §10.5.
Where this is taught. Operator view V12 §7. Settlement recovery V8 §7.10. ClaimClock runs at minute 20 of every hour; exposure refresh at 02:40 — taught in §10.1 and §10.5.
11. Your plant live — the historian for today
The IPP’s live register: what the plant is doing now, which pipe brought the reading, who may look at it, and the traces that freeze a curtailment window. This is the home. Dashboard (§12) only glances.
The IPP’s problem, in plain words
The profit story on Dashboard asks can this plant deliver what the next sale assumes? A forecast answers what the weather said. A settlement meter answers what the connection point billed, hours or days later. Neither tells you whether the machine is running now.
Think of a bakery that keeps two books. The till tape is the settlement meter — it is what the accountant trusts. The kitchen clock and the oven thermometer are the live feed: they tell the baker whether today’s loaves will actually leave the shop. This screen is that kitchen clock. The platform calls the page Your plant live. The compact strip on Dashboard (§12) is Plant now — a glance, not the register.
A feed that nobody consented to is a locked cupboard. The owner holds the key. A consent names another organisation and what they may see: the live panel, the raw samples, or the downloadable traces. A read grant never authorises a push. Battery health stays off the live panel.
Device readings inform today’s decisions. Settlement still uses the settlement meters. A plant with no telemetry stays forecast-only; there is no telemetry-absence penalty.
Follow along. Seat:
ipp_2@webill.net(passwordsupersecret). Path: Wheeling → IPP Sites → Sites → IPP2 Atlantis Wind → Open workspace → Operations. URL:/org/ipp-sites/sites/:id/operations. You should see Today’s measured output first, followed by the feed register. Device samples, Events and curtailment evidence, Collector kit and Consent open on demand. Use How to read this beside a section heading for its explanation. With no feed, Register the first feed opens the#plant-feed-form.
Data. full_demo · seed 42 · IPP2 Atlantis Wind. Mock panels and sample tables appear once a Mock feed has been registered and a push has landed. last checked 2026-10-06.
Words you need on this screen
| Plain English | Platform word | One-sentence meaning |
|---|---|---|
| The map of the kitchen | How this page fits together | The strip #plant-pipeline: collector → feed → readings
→ evidence → consent, each step with its live state |
| The kitchen clock | Plant now | Today’s measured output on #plant-now-{site id} |
| The full register | Your plant live | Operations — glance, feeds, samples, events, traces, consent |
| The pipe into the kitchen | Plant feed | Path, cadence, effective date, and whether pushes must be signed |
| Who may open the cupboard | Consent scope | LIVE_PANEL, SAMPLES, EVIDENCE — each grant includes the ones above it |
| A reading the engine may use | GOOD quality | Stale, flagged, late or estimated readings cannot drive the measured intraday decision |
| A frozen window | Curtailment evidence | A trace with a status, a shortfall in kWh, and a content hash |
11.1 What this screen is
Operations is a view in the IPP site workspace. It opens with today’s measured output and the feed register. The Live output, Meter history, Curtailment & claims and Plant & infrastructure links jump to those sections and move keyboard focus with you.
flowchart TB
O[Operations] --> L[Live output and feed register]
L --> M[Meter history and interval coverage]
M --> C[Curtailment and claims]
C --> P[Plant and infrastructure, open on demand]
- Check Today’s measured output. A missing or stale sample stays labelled; registered capacity does not stand in for a measured reading.
- Check Meter history & interval coverage for measured energy and missing reads. Section 11.9 below teaches this explorer and its import workflow.
- Check Curtailment & claims. §10 teaches the claim book and its period, status and evidence controls.
- Open Plant & infrastructure when you need the illustrative 3D model, registered site map or electrical diagram. 3D plant and Site map switch the inline view; Open infrastructure diagram opens a drawer. The diagram contains registered site data, not live readings.
The live register keeps its detailed work in disclosures:
| Section | What you do |
|---|---|
| Feed register | Choose a feed or open Register another feed; a first feed opens its form automatically |
| Device samples · {date} | Choose a trading day and inspect the chart and readings table |
| Events and curtailment evidence | Review events and frozen evidence traces |
| Collector kit · {path} feed | Read delivery instructions and download the telemetry template or schema |
| Consent · who else may read this feed | Grant or review another organisation’s access |
Open How to read this for a section’s explanation. The rest of this chapter teaches those sections in the same order. Collector kit Chapter 5 means the fifth section of this live register; Dashboard is taught in §12.
A consented trader sees the full Plant telemetry register in their own organisation, with the How this page fits together strip and a Dashboard back link. The live register applies the owner’s in-force consent scope.
11.2 How to open it
Open Wheeling → IPP Sites → Sites, choose a site,
then choose Open workspace → Operations. The direct
address is
/org/ipp-sites/sites/{generator_site_id}/operations.
The Dashboard Plant now → Open plant action also
leads to Operations. Existing
/org/generator-sites/{id}/strategy/plant bookmarks remain
supported; the site workspace is the current navigation path.
Seat: an IPP organisation user who owns the generator site. The owner must be a signed-in member to register a feed or grant consent. A stranger with no ownership and no consent does not discover the feed.
11.3 Chapter 1 · Today’s measured output
This is the kitchen clock. The chapter asks one question: what is the plant doing right now, and may I trust that number today?
The left-hand tell says: the latest reading each feed delivered, in megawatts. Fresh means the reading is younger than the feed’s deadline (three missed cadences by default). Available today fills only from a fresh reading of GOOD quality. The sparkline is the last 24 hours of hourly averages. Gaps are hours with missing or non-GOOD readings. Battery state of charge appears when the device reports it; state of health never appears on this panel.
The panel itself is #plant-now-{site id}, inside Chapter
1. The chapter already carries the eyebrow and the title, so the panel
has no second heading here. On Dashboard (§12) the same panel keeps its
own eyebrow Plant now.
When no feed is registered, the only sentence is No plant feed registered yet — register the first one in the Feed register below. (On Dashboard the sentence stays No plant feed registered — add one on the plant screen.) Scroll to Chapter 2 and fill the form. There is nothing to read until that pipe exists.
Each feed that the viewer may see is
#plant-now-feed-{feed id}. Read the block from the top:
| Word on the strip | What it is |
|---|---|
{kind} chip |
The path: push_api, gateway_mirror, or
mock. A mock chip means generated
demonstration readings |
| Fresh feed / Stale feed | Freshness is measured from the sample time against a feed-specific deadline (default: three cadences). Amber text means stale |
| as of {date, time} | Latest observation, as 18 August 2026, 11:00 |
| No sample received yet | Amber, in place of the freshness line, while the feed has never delivered a sample. It is not reported as a stale feed |
| Feed refusal: … | The last refusal payload, in rose, when the collector or push was rejected |
| Active / available | Latest active power and available capacity, in MW (device kW ÷ 1,000, two decimals). A dash means no figure |
| Setpoint | The instructed megawatts. If the device is in curtailment mode: amber · Curtailed ({setpoint %}%) |
| Units available | {units_available} / {units_total}, or dashes |
| Battery state of charge | {soc %}% — only when the latest sample carries a
charge. State of health does not appear here |
Available today
(#plant-availability-{feed id}) |
Megawatts from a fresh GOOD reading, or no fresh good reading. This number sits beside HAF on Dashboard; it does not change the HAF forecast |
Sparkline (#plant-sparkline-{feed id}) |
Last 24 hours of hourly average power. Missing or poor-quality hours stay blank |
| Quality line | If the latest sample is not GOOD:
{quality} · excluded from decisions |
The footer on every Plant now strip: Device readings inform today’s decisions. Settlement uses the settlement meters.
A reading arrives in this order:
- A push, a mirror CSV, or a mock tick arrives.
- The collector accepts the batch or writes a refusal.
- An accepted sample is stored with its quality and revision.
- A GOOD reading still inside the freshness window lights Fresh feed and fills Available today.
- Anything else stays off the measured intraday decision.
- Dashboard (§12) shows the same glance; it does not keep a second copy of the register.
What “done” looks like: Fresh feed, a time stamp, numbers in megawatts, Available today filled from a fresh GOOD reading, and a sparkline with few gaps. If the feed is Stale, do not bid the next 144 hours on it — restore the collector first (§12.8.7).
11.4 Chapter 2 · Feed register
This is the pipe. The chapter asks: how do readings get from the plant into this page, and which pipe are we reading below?
A plant feed is the registered path from the plant’s collector into the platform: which path it uses, how often the device reports, and from which trading day it is in force. Every reading, event and trace on this page arrived through one of these.
The left-hand tell says so in two short paragraphs, then: choose View feed to read that feed’s day in the chapters below. Registering a feed stores the pipe; it does not connect to the plant and it does not sign a data schedule.
The feed cards
The list is #plant-feeds. Each feed is a card
#plant-feed-{feed id}:
| Line on the card | What it is |
|---|---|
| {Path} feed | Push API feed, Mirror file feed or Mock feed |
| Shown below chip | This is the feed Chapters 3–6 are reading. The card also carries
aria-current="true" and a green ring |
| Fresh / Stale chip | The same freshness as Plant now |
| Signed pushes only chip | require_signature? is on |
| Provider {provider} · reports every {N} minutes · stale after {M} minutes without a reading | Cadence and the freshness deadline (three cadences by default) |
| In force since {date}[ until {date}] · last reading {HH:MM} SAST | Effective dates and the latest sample time |
| Last delivery refused: … (rose) | The last refusal payload |
View feed (#select-{feed id}) selects
that feed for Chapters 3–6 and re-reads the page in place. Press it when
you have more than one pipe and you want the day chart, the traces and
the collector kit to follow a different one.
With no feed the list is the single sentence
#plant-feeds-empty: No feed is registered for this site
yet. Until one exists there is no Plant now reading, no sample table and
no evidence, and the plant runs forecast-only. For the owner it
adds Register the first feed below.
A consented trader does not see a register form. They see
Your access to this feed · {scope}
(#plant-your-access) with one sentence for their scope, and
The owner grants scopes; a read grant never authorises a
push.
The register form
The owner form #plant-feed-form sits in a disclosure
#plant-feed-register. When there is no feed the summary
reads Register the first feed and the disclosure is
already open. Once one exists the summary reads Register another
feed and it starts closed.
The form’s own note: Choose the path your collector will use, how often the device reports and the first trading day the feed is in force. Open the Collector kit below for your operator’s delivery format and setup instructions.
Every field carries a tooltip. Fill them in this order:
| Field | Label on screen | What you choose |
|---|---|---|
kind |
Path | Push API (push_api): your collector
posts a JSON envelope. Mirror file
(gateway_mirror): your historian drops a CSV in the inbox.
Mock (mock): generated readings for
demonstration |
cadence_seconds |
Cadence | 5 minutes (300) or 10 minutes (600). The feed counts as stale after three missed cadences |
effective_from |
Effective from | The first date the feed is in force |
require_signature |
Require signed pushes | Checkbox. When ticked, unsigned pushes are refused |
| submit | Register feed
(#register-plant-feed) |
Stores the feed. Success flash: Feed registered |
A bad path, cadence or date flashes Check the feed path, cadence and date. A viewer who is not an authenticated owner member flashes An authenticated owner seat is required.
What “done” looks like: a feed card with a Shown below chip, the disclosure now titled Register another feed, and Chapters 3–6 visible for that pipe. Registering a feed stores the pipe. It does not execute a data schedule. Download the draft annex from Collector kit (§11.7); signing remains a separate commercial act.
The plant operates its collector and may nominate its operations and maintenance contractor. The platform does not install plant software and does not issue remote plant controls.
Vendor-cloud paths (Huawei FusionSolar, Sungrow iSolarCloud, SMA ennexOS, SolarEdge) remain closed until a signed customer data schedule, a vendor account and an approved network destination open that milestone. V2 §11 owns the schema and the inbox rules.
11.5 Chapter 3 · Device samples
This chapter appears only once a feed exists. It is today’s oven log: every reading the selected feed delivered on one South African trading day, at device cadence.
The title is Device samples · {date}, the trading day in long form. The left-hand tell says the chart and the table are the same readings; amber bands mark buckets where the device reported curtailment. A row that is not GOOD sits on amber and is excluded from decisions. A corrected reading arrives as a new revision; history is kept, nothing is overwritten.
Pick the day
The date controls sit on one row:
| Control | Id | What it does |
|---|---|---|
| ‹ | #plant-date-prev |
Step one trading day back |
| Trading date | #plant-date-form |
Type or pick a date. Tooltip: A South African trading day runs 00:00 to 24:00 SAST. |
| › | #plant-date-next |
Step one trading day forward |
| Today | #plant-date-today |
Jump back to today. Shown only when another day is selected |
Any of them reloads the tiles, the chart, the table and the events for that South African trading day (the query window is the SAST day, with the usual two-hour offset). A note on the right names the feed: {Path} feed · one reading every {N} minutes.
If the viewer’s consent is only LIVE_PANEL, the chapter shows
#plant-samples-locked instead of the readings:
Your consent covers the live panel only. The day’s samples, events and evidence need a SAMPLES or EVIDENCE grant from the owner.
That is the locked cupboard with only the clock face visible. Chapter 1 still works. The log does not.
Four tiles, then the chart, then the table
With SAMPLES granted, four tiles open the day:
| Tile | Id | Reads |
|---|---|---|
| Readings received | #plant-stat-samples |
{n} · of {expected} expected (86 400 ÷
cadence) |
| GOOD share | #plant-stat-good |
{pct}% · {n} usable in decisions; green when
every reading is GOOD, amber otherwise |
| Curtailed buckets | #plant-stat-curtailed |
{n} · device-reported curtailment; amber when
above zero |
| Peak active power | #plant-stat-peak |
{kW} kW · highest reading of the day |
A day with no readings shows #plant-samples-empty
(No readings arrived for this trading day. Check the collector’s
last delivery in the strip above, or step to another day.) and no
chart.
The day chart #plant-day-chart is active plant power
across the day, with hour gridlines at 00:00, 06:00, 12:00, 18:00 and
24:00. Missing buckets stay blank. Amber bands
(#curtailed-bucket-{unix}) mark reported curtailment. A
legend line follows: Line: active kW · amber bands: device-reported
curtailment · gaps: missing or non-GOOD readings.
The table caption: The same readings as the chart · kW at device
cadence · times in SAST. Headers are sticky: Time,
Active kW, Setpoint kW,
Quality, Revision, and — for the owner
— Device detail. The body is
#plant-samples.
Read a row like this:
- Time is
HH:MMSAST, with the full ISO stamp in the tooltip. - Active kW is what the machine made.
- Setpoint kW is what it was told to make. A Curtailed chip sits beside the setpoint when the device reported curtailment.
- Quality is a chip, green for GOOD and amber otherwise. A row that is not GOOD sits on an amber background.
- Revision counts corrections. A later tick never erases an earlier one.
- Device detail is a Signals
disclosure for the owner: SoC / SoH / hottest cell as
{soc}% / {soh}% / {temp}°C, then Extras (not used in decisions) as raw JSON. Extra vendor fields are retained for diagnosis. They never enter an engine.
Freshness is measured from the sample time, with a feed-specific deadline. Stale, suspect, flagged, late and estimated readings cannot supply the measured intraday decision.
A complete sequence of GOOD readings in the current hour supports a measured projection for that hour. When the device reports curtailment and a matching System Operator instruction is in force, the decision records the instructed deviation and mentions measured output. Missing, stale or incomplete coverage falls back to forecast drift and says so. The day-ahead forecast is unchanged.
For a battery, a fresh GOOD charge reading can anchor the remaining intraday plan. Capacity comes from the battery’s effective health register; executed hours remain intact. Without a usable reading the existing assumed or rolled-forward charge remains in use. Deep battery contract numbers stay on §20.
What “done” looks like: four tiles with numbers, a chart from 00:00 to 24:00 with few gaps, and a table whose Quality column is mostly green. Amber rows and chart gaps are the reason an hour fell back to the forecast — that is the So what of this chapter.
11.6 Chapter 4 · Events and traces
This chapter asks: what did today’s readings prove, and is there a frozen bundle a claim can cite?
The left-hand tell splits the answer in two. Events are flag transitions the platform derives from the samples: curtailment on and off, setpoint changes, trips, units leaving and returning, a feed going stale. A sustained export above the connection’s limit appears here as a provisional warning; the nightly meter scan stays authoritative. A curtailment trace freezes the device samples and the method inputs for one System Operator instruction window into a hashed bundle. It stays PARTIAL until enough independent meter evidence arrives.
The working surface is two cards side by side.
Left card — Events and provisional export warnings
Eyebrow Events · {date}. List #plant-events.
Each line is {HH:MM} {event} with a small derived
tag; the event kind is written in plain words (Curtailment on,
Setpoint changed, Feed stale). A sustained device
export above the effective MEC (Maximum Export
Capacity) tolerance appears as Provisional export
warning (MEC). The nightly meter scan remains authoritative.
Device warnings do not create excess charges. Runtime MEC is taught in
§16.
A quiet day shows #plant-events-empty (No flag
changed on this day: no curtailment, trip or stale spell was
detected.). A LIVE_PANEL viewer sees
#plant-events-locked (Events need a SAMPLES
grant.).
Right card — Frozen traces, newest first
Eyebrow Curtailment evidence · all windows for this feed.
List #plant-traces. Each card shows a status chip
(COMPLETE green, PARTIAL amber), the
window as {date} · {HH:MM}–{HH:MM}, then Shortfall
{kWh} kWh · method {method} · hash {first 12 characters}… with the
full hash in the tooltip, and Download evidence bundle
(#download-{trace id}).
Download needs EVIDENCE
for the trace’s window; a missing grant flashes Evidence not
found. No trace yet shows #plant-traces-empty (No
trace has been frozen for this feed yet. One appears after a System
Operator instruction window closes.). A viewer without EVIDENCE
sees #plant-traces-locked (Trace downloads need an
EVIDENCE grant.).
After an instruction ends, the trace builder freezes the device samples and method inputs. The PPA’s deemed-energy method takes precedence; otherwise the documented curtailment method chain applies. A trace stays PARTIAL without enough independent meter evidence. Retries can create a COMPLETE replacement linked to the earlier trace. Corrected samples create revisions and never rewrite an existing trace or its downloadable artifact. A new claim version can reference the trace hash; the NERSA pack carries that reference. The commercial claim book is §10.
What “done” looks like: events in time order on the left, and on the right a COMPLETE trace whose hash you can paste into a claim. The hash is the frozen loaf — later oven readings do not unbake it.
11.7 Chapters 5 and 6 · Collector kit and consent
Two chapters, both owner only and both only once a feed exists. Getting readings in and letting others read are different questions, so they sit as two chapters, not one block.
flowchart LR
A[Collector at the plant] --> B[Registered feed]
B --> C[Chapter 1 Plant now]
B --> D[Chapter 3 Device samples]
D --> E[Chapter 4 Events]
D --> F[Chapter 4 Frozen traces]
G[Chapter 6 Consent] -.-> C
G -.-> D
G -.-> E
G -.-> F
- The collector delivers into the feed you registered in Chapter 2.
- Plant now, the day log, events and traces all read that feed.
- Consent does not move energy. It only names who may look.
11.7.1 Chapter 5 · Collector kit
This chapter tells your operator what to deliver into the feed selected above. The left-hand tell: the plant, or its operations and maintenance contractor, owns and operates the collector. The platform hosts the endpoint and the inbox, validates each batch, and stores what it accepts. The template and the data schedule below are what your operator needs. The schedule is a draft annex; it becomes binding only under the executed PPA.
The left card, Deliver into this feed, names the selected feed’s path and cadence, then says what to deliver:
| Path | Delivery note |
|---|---|
| Push API | Your collector posts a telemetry.samples.v1 JSON
envelope to POST /api/v1/telemetry/samples with the site’s
registration credential: up to 288 samples per push, explicit
+02:00 offsets. Then either This feed refuses unsigned
pushes or Unsigned pushes are accepted on this feed |
| Mirror file | Your historian drops a telemetry.mirror.v1 CSV into the
operator-provided inbox; archived files carry an acceptance or refusal
sidecar |
| Mock | A generated demonstration feed; nothing has to be delivered |
Two downloads follow, each with a one-line description:
| Control | Id | What you get |
|---|---|---|
| Download supply CSV template | #plant-template |
plant-template.csv — the mirror file header for this
feed |
| Download data schedule | #plant-schedule |
plant-data-schedule.txt — the draft annex, with
consents |
CSV schema and delivery rules is a disclosure
#plant-schema. It names telemetry.mirror.v1:
explicit +02:00 timestamps, decimal strings, empty cells
for missing values, semicolon-separated alarms. Quality: good, flagged
or estimated. Maximum 288 rows, less than 24 hours per file. Off-grain
rows are rejected individually. The column list is printed under the
paragraph.
The right card, Who does what, is three lines:
- The plant or its O&M contractor owns, installs and operates the collector. Pushes or drops the files.
- The platform hosts the endpoint and the inbox, validates each batch, stores accepted readings and writes a refusal for the rest.
- Never remote plant control, setpoint writes, or settlement energy from device readings.
What “done” looks like: your operator has the template and the draft schedule, and the strip’s Collector step reads Fresh · last reading {HH:MM}. The platform still never connects to plant equipment.
11.7.2 Chapter 6 · Consent
This chapter is the key to the cupboard. By default only your organisation sees this feed. A consent names another organisation, a scope and a start date, and hangs on a clause in the PPA data schedule. Scopes are cumulative: SAMPLES includes LIVE_PANEL, EVIDENCE includes both. A read grant never authorises a push, and battery health never appears on LIVE_PANEL.
The left card, The three scopes, numbers them:
- LIVE_PANEL — Plant now only: the latest reading, its freshness and the 24-hour sparkline. Battery health never appears here.
- SAMPLES — Plant now plus the day chart, the sample table and the event list.
- EVIDENCE — Everything above plus the frozen curtailment traces and their downloadable bundles.
Under the list: Each scope includes the ones above it. Grants are effective-dated and opt-in.
The right card lists Grants on this feed · {n}. Rows
under #plant-consents read
{organisation name} {scope chip} from {date}[ until {date}] · {basis}.
With none, #plant-consents-empty says Only your
organisation can see this feed.
Then Grant access to another organisation, the form
#plant-consent-form:
| Field | Label | What it means |
|---|---|---|
grantee_organization_id |
Organisation | A select of the other organisations on the platform, prompt Choose an organisation. Required. Tooltip: they will see the site under Plant telemetry, without the IPP strategy tabs |
scope |
Scope | LIVE_PANEL · the glance only, SAMPLES · glance, chart, table, events, or EVIDENCE · everything, including trace bundles |
effective_from |
Effective from | First trading day the grant is in force |
basis_ref |
PPA clause / basis | The contractual sentence you are hanging the grant on |
| submit | Grant consent
(#grant-plant-consent) |
Success flash: Consent granted |
A bad date or scope flashes Check the consent date and scope.
A consented trader has neither Chapter 5 nor Chapter 6. Chapter 2 shows them Your access to this feed · {scope}, and step 5 of the strip reads Your scope · {scope}.
LIVE_PANEL opens Plant now. SAMPLES also opens the day chart and the sample table. EVIDENCE also opens trace downloads. The three are cumulative.
flowchart LR
A[Owner grants a scope] --> B{Which scope?}
B -->|LIVE_PANEL| C[Plant now glance only]
B -->|SAMPLES| D[Glance plus chart, table, events]
B -->|EVIDENCE| E[Glance, samples, and trace download]
C --> F[Trader chrome: Plant telemetry, no IPP tabs]
D --> F
E --> F
- The owner names a grantee, a scope, a start date and a basis.
- LIVE_PANEL opens Plant now — not the chart, not the traces.
- SAMPLES includes LIVE_PANEL, and opens the day chart, the sample table and the event list.
- EVIDENCE includes both, and opens Download evidence bundle.
- A consented trader lands on Plant telemetry without the IPP tabs. Unconsented organisations cannot discover the feed.
What “done” looks like: the grant list names the organisation, the
scope chip, and the basis clause. The strip’s Consent step reads
{n} grants. The trader can open Plant telemetry; they still
cannot push.
11.8 Empty, refused, and no-consent states
Walk the strip first. The status line usually names the chapter that needs you.
| What you see | Why | What to do |
|---|---|---|
| Step 1 No feed registered yet; Plant now No plant feed registered yet — register the first one in the Feed register below. | No in-force feed | Owner: the Register the first feed disclosure is
already open; fill #plant-feed-form and Register
feed |
| Step 2 Nothing delivered yet / Waiting for a feed | The feed exists but no batch has landed, or there is no feed yet | Point the collector at the kit in Chapter 5 |
| Step 2 Last delivery refused | The last batch was rejected | Read the rose line on the feed card; fix the CSV or the signature |
No #plant-day-chart |
No feed yet, samples not granted, or no readings on this day
(#plant-samples-empty) |
Grant SAMPLES, pick a feed, or step to another day |
Your consent covers the live panel only…
(#plant-samples-locked) |
Grant is LIVE_PANEL only | Owner grants SAMPLES or EVIDENCE |
| Stale feed in amber | Latest sample is older than three cadences (default) | Restore the collector; do not bid the next 144 hours on a dead feed (§12.8.7) |
| No sample received yet in amber | The feed is registered but has never delivered a sample | Point the collector at the kit in Chapter 5; once a sample lands the line shows Fresh feed or Stale feed with its time |
| Feed refusal in rose | The last batch was rejected | Read the refusal; fix the CSV or the signature |
{quality} · excluded from decisions |
Latest sample is not GOOD | Wait for a good tick; extras stay for diagnosis only |
| Amber sample rows | That tick was not GOOD | Revisions keep history; they do not rewrite a trace |
| Evidence not found. | No EVIDENCE grant, or the trace is not this site’s | Grant EVIDENCE for that window |
| No Battery state of charge tile | Latest sample has no soc_pct |
Normal on a wind or solar site without storage |
| No Chapter 5 or 6 | You are not the owner, or no feed exists yet | Owners see both once a feed exists; traders see Your access in Chapter 2 |
| Plant without telemetry | No feed at all | Forecast-only. No telemetry-absence penalty |
A plant without telemetry continues forecast-only. Device readings never replace settlement meters.
Where this is taught. The glance and the stale-telemetry rewrite: §12.6 and §12.8.7. Feed schema and the historian inbox: V2 §11. Push API and feed list: V13 §17. Collector workers: V21 §3 and V21 §11. Curtailment claims that cite a trace hash: §10. Battery contract numbers: §20.
11.9 Meter history and interval imports
A live device feed helps you operate today. Meter history & interval coverage is the separate settlement-meter record. Its Generation tab shows monthly kilowatt-hours split into Peak, Standard and Off-peak.
Open View energy data and choose a month for the same values in a table. Choose a month to see its days, then choose a day to see its 20-minute intervals. You can use the keyboard for each choice or click chart bars. All months and the month breadcrumb take you back. Chart and table times are UTC.
Choose Reads, then Month, to inspect coverage. The summary gives actual, expected and missing reads and days with gaps. View hourly coverage data shows the exact counts behind each heatmap cell. Hours outside the recorded window are blank. Refresh meter data keeps your tab, month and drill-down level and announces when the refresh completes.
Choose Import intervals to upload one CSV or JSON file, up to 5 MB. Download supply CSV template gives you a header and example row. Replace the example with your readings and the registered meter number shown in the dialog. This is a settlement-interval file; the Collector kit downloads a different format for plant telemetry.
Canonical intervals use 20 minutes, a start time with an explicit UTC
offset (such as 2026-10-01T00:00:00+02:00), and
non-negative energy with up to three decimal places. Supply rows need
kwh_export; use kwh_import=0 when there is no
import. Quality must be ACTUAL, ESTIMATED,
SUBSTITUTED or INTERPOLATED. Use
Published interval schema for the JSON envelope and
advanced fields.
Choose a file, then Validate file. Review the meter, supply direction, interval count, cadence, exported/imported energy and gaps. No readings are saved until you confirm Import N intervals. A success message states how many intervals were imported and how many gaps were reported; gaps are not filled. A refusal identifies the problem and imports nothing. Fix the file and choose it again. Escape or the close button dismisses the dialog and returns focus to its opener.
Tip. Use Find chapter in the manual’s contents, or your browser’s Find command (Ctrl+F or Command+F), to locate a word within this volume.
12. Dashboard — the story of the site
Thread part 4, continued: two years after IPP2 Atlantis Wind switched on, what has it earned, what has it lost, where did each come from, and how healthy is it?
Follow along. Seat:
ipp_2@webill.net. Path: Generator sites → IPP2 Atlantis Wind → Strategy → Dashboard. You should see a one-sentence verdict with a four-figure money spine and a confidence bar, then six chapters — each a short narration on the left and one chart on the right — and, folded under the health chapter, Forecast evidence and the availability scoreboard. Atlantis Wind has no battery, so Chapter 5 does not mention one.Follow along (battery). Same seat. Path: Generator sites → Rosslyn BESS → Strategy → Dashboard. Chapter 5 now has a seventh vital Battery · contract and, under the vitals, a card Open battery contract. That card is the path into §20.
Data. Every Rand on this page carries a grade. Settled and invoiced months come from the Money Room fact base (settlement ledger, market statements, documents — V16). Estimated months are rebuilt from the strategy engine’s actual-scenario runs, the meter registers and the contract prices. The confidence bar says which is which. On the demo dataset, until settlement has run for a site, the story is almost entirely estimated — and says so.
The seller’s problem, in plain words
An owner’s questions are simple and hard: have we made money since commissioning; where did it come from; where did it leak; is the plant healthy; what should we do next quarter?
The Dashboard answers those five in order, as one narrative. It reads from commissioning (the site’s COD, or the earliest record) to the current month, and it separates two kinds of loss that are usually confused: money out (the cost of generating at your LCOE) and money forgone (energy nobody was offered, valued at what the day-ahead market would have paid). Losses are always valued against a stated baseline and are never added into revenue.
Concepts and abbreviations on this screen
| Term | Meaning here |
|---|---|
| Since commissioning | From the site’s COD (or the earliest of metering, contracts, availability records) to the current month |
| Generated | Metered generation from the site meter’s registers, month by month; months without readings are estimated from P50 and availability and marked so (§12.1.1) |
| Earned | Revenue by stream: PPA sales, SAWEM day-ahead, certificates (§12.1.2) |
| Cost of generation | Generation × LCOE (the book’s lcoe_ckwh) — the plant’s
own cost, not a bill anyone sent (§12.1.3) |
| Net | Earned − cost of generation − other costs (network, fees) (§12.1.4) |
| Baseline | SAWEM day-ahead P50 for 08h–15h, less a 5 % imbalance allowance — what unsold energy would have earned |
| Forgone / never offered | Unsold energy at the baseline. The largest number on most plants |
| Grade | settled · invoiced · estimated, per month (§12.1.5) |
| Vital sign | One of six health measures with a two-year track and a status stripe (seven when this site has a battery) |
12.1 The verdict
The page opens at #ipp-story-verdict. Think of it as the
shop window of the plant’s accounts: one sentence that a board member
can read, four figures that prove it, and a card that says how much of
that story is a bank statement versus a pencil estimate.
The headline (#ipp-story-headline) is written from the
numbers — “A 50 MW plant that has sold 2 % of what it made. −R
96,400,000 against its own cost of generation, and R 140,000,000 of
daytime energy never offered to anyone.” Under it a short lede
names how much was generated since when (1 June 2026, not
June 2026), when buyers arrived and how much they took,
whether the market route is open and used, and whether the losses are
commercial or technical. If the meter has never recorded generation, the
headline says the story starts when the meter does.
The four figures sit in the money spine
(data-role="money-spine"): Generated,
Earned, Cost of generation, and
Net. They are one lifetime sum from commissioning (the
site’s COD, or the earliest of metering,
contracts, availability records, or the book’s first day) to the current
month. The money figures are exact, comma-grouped Rand
(R 4,800,000, never R 4.8 m), and no figure
wraps onto a second line: the spine shows two columns until the card is
wide enough, then all four in one row. Beside them, How sure is
this story (#ipp-story-grade) is the confidence
card: a bar of settled · invoiced ·
estimated months, the grading rule in one paragraph, and a row of
chips.
Read the verdict in this order:
- The headline states sold share, net against own cost, and energy never offered.
- The lede fills in generation since when, buyers, the market route, and whether losses are commercial or technical.
- The money spine sums Generated, Earned, Cost of generation, and Net.
- How sure is this story grades every month and never mixes those grades into one silent number.
12.1.1 Generated
Generated is how much energy the plant made in that lifetime, not how much it sold. It is the bakery’s loaves baked, including the ones that never left the shelf.
The large figure is megawatt-hours, or gigawatt-hours when the sum is
1,000 MWh or more (12.4 GWh, 310 MWh). The
line under it is N % of P50 plus, when the health chapter
has an availability vital, · availability … → ….
P50 here is a generation grade: the expected output, met or exceeded about half the time, taken from the site’s annual P50 and spread across the months. It is not a market-price P50.
Each month is filled like this:
- If the site meter has a register for the month, that reading is Generated.
- If it does not, the page estimates from the site’s P50 for the month multiplied by HAF (Historical Availability Factor) — how much of paper availability is bankable. That month’s HAF when it exists, else the latest HAF, else 1.0. Deep teaching: §5.
- Those months still count in the lifetime total. They are not hidden. Their honesty lives on the grade bar, not as a second Generated figure.
N % of P50 is Generated ÷ lifetime P50, as a percentage.
A plant that made 86 % of P50 is a little below the expected case. That
is weather and availability, not a sales failure. Unsold energy is a
different number, on Earned and in Chapter 4.
Empty: if no month has generation, Generated is not a fake zero story — the headline says there is no recorded generation yet.
12.1.2 Earned
Earned is money that came in, not energy that was made. It is the till, not the oven. Unsold kilowatt-hours count as zero here. They are never added as a pretend sale.
The large figure is grouped Rand (R 4,800,000,
R 450,000, R 35). Green type marks it as money
in. Amounts of 1,000 or more use a comma thousands separator
(R 1,000). Negatives keep the sign in front of
R (−R 5,604,000).
The line under it names who paid, when that is known:
| What you see | Meaning |
|---|---|
nothing sold yet |
No buyer, no certificate cash, no market settlement in the lifetime |
2 PPAs · 65.0 c |
Two PPAs (Power Purchase Agreements) at one shared price |
RECs R 120,000 |
REC (Renewable Energy Certificate) cash in the lifetime |
market R 80,000 |
SAWEM (South African Wholesale Electricity Market) day-ahead cash |
Where each Rand comes from:
| Stream | When it is used |
|---|---|
| PPA | A Money Room revenue fact that is not market and not certificates; or, on an estimated month, the actual-scenario run’s margin (or the sold energy × contract price) |
| Market | Day-ahead, flexible, intraday, or imbalance revenue facts |
| Certificates | Certificate revenue facts |
The lifetime Earned is PPA + market + certificates. Costs (network, fees) are not subtracted here; they leave through Net.
Where this is taught. Who the buyers are, and the price against LCOE: §12.4. The Money Room streams: V16 §7.
12.1.3 Cost of generation
Cost of generation is what it cost you to make the energy in Generated, at the plant’s own LCOE (Levelised Cost of Energy). It is not a bill anyone sent, and it is not the grid tariff. It is the bakery costing every loaf at the recipe cost, whether the loaf sold or not.
The large figure is grouped Rand. The line under it is the formula the page used:
LCOE {N} c × {Generated}
LCOE is held on the IPP book in c/kWh (default 48). One megawatt-hour is 1,000 kWh, so the Rand cost of a month is:
Generated MWh × LCOE c/kWh × 10 = Rand
The × 10 is the unit change from c/kWh to R/MWh. It is
the module’s only conversion. Edit LCOE on Overview (§4.3); the Dashboard re-reads the book.
This cost is charged on all generation, sold or not. That is why a thinly sold plant can show a large cost and a small Earned: you still baked the loaves.
12.1.4 Net
Net is Earned minus Cost of generation minus other costs (network and fees that arrived as Money Room cost facts). It is the shop’s result after paying its own recipe cost. It is not Earned minus the value of unsold energy. Forgone energy lives in the headline and in Chapter 4; it is never subtracted here, or you would count the same leftover twice.
The large figure is grouped Rand, rose when negative, green when
positive. The line under it is net per MWh generated:
(Earned − Cost of generation) ÷ Generated. That per-MWh
line does not divide other costs; the large Net figure
does subtract them.
| Sign | Read it as |
|---|---|
| Negative, large | The plant paid to make energy it mostly gave away |
| Negative, small | Cost still wins; sales are closing the gap |
| Positive | Earned cleared the plant’s own cost |
12.1.5 How sure is this story
The right-hand card (#ipp-story-grade) answers a
different question from the four figures. The spine says what
happened. This card says how much of that is a closed
book.
Think of three kinds of month in a shop’s accounts:
| Grade on screen | Colour on the bar | What it is |
|---|---|---|
| settled | Brand green | The Money Room has a profit-and-loss fact for this site and month, from the settlement ledger and market statements, and none of those facts is still only invoiced |
| invoiced | Sky blue | The Money Room has a fact, and at least one of them is still invoiced — billed, not yet the final settled month |
| estimated | Hatched slate | No Money Room fact. The page rebuilds the month from the strategy engine’s actual-scenario runs, the meter registers, and the contract prices |
The bar (data-role="grade-bar") is those three shares of
the lifetime, as percentages of months, not of Rand. A year of estimated
months and one settled month is still almost all hatched, even if that
one month was huge. The legend under the bar counts months:
settled · 0 months, invoiced · 0,
estimated · 24 months.
The grade is per month. An estimated month is still in the Generated and Earned totals; the bar is how you see that it is a rebuild.
The paragraph under the legend is the rule in plain words: settled months come from the settlement ledger and market statements; estimated months are rebuilt from actual-scenario runs, meters and contract prices. Losses are valued against a stated baseline (on the demo, SAWEM day-ahead P50 for 08h–15h, less 5 % imbalance allowance) and are never added into Earned.
On the demo dataset, until settlement has run for this site, the bar is almost entirely estimated — and says so. That is honest, not a fault.
Under the paragraph, chips (data-role="verdict-chips")
compress the health of the book:
| Chip | When it appears | Tone |
|---|---|---|
| availability slipping | The Availability · HAF vital is amber or red | Amber |
| N % sold | Generated is above zero. Rose when sold share is under 30 % | Green or rose |
| market route open, unused | The organisation is a BRP (Balance Responsible Party) and has placed no bids | Sky |
| bidding, nothing settled yet | Bids are in; market revenue is still zero | Sky |
| trading day-ahead | Market revenue is in | Sky |
| not BRP-registered | The organisation has no market registration | Amber |
| no penalties, no curtailment | Curtailment unrecovered, uninstructed imbalance, and shortfall penalties are all zero | Green |
They are a glance, not a fourth money figure. Chapter 5 and Chapter 6 unpack them.
Where this is taught. The Money Room fact base: V16 §7. Settlement statuses: V8 §11. The baseline price forecast: V10.
Worked month — how the four figures are built
Data. Method check, not a sealed demo stamp. LCOE 48 c/kWh as on the IPP book default (§4.3). One calendar month, so you can see the arithmetic the lifetime spine adds up.
| Input | Value |
|---|---|
| Metered generation | 12,000 MWh |
| P50 for the month | 14,000 MWh |
| Sold on PPAs | 240 MWh at 65.0 c/kWh |
| Market and certificates | R 0 |
| Other costs | R 0 |
| LCOE | 48 c/kWh |
- Generated is the meter: 12,000 MWh. Share of P50:
12,000 ÷ 14,000 = 86 %. - Earned is only what sold:
240 MWh × 65.0 c/kWh × 10 = R 156,000. - Cost of generation is all generation at LCOE:
12,000 MWh × 48 c × 10 = R 5,760,000. - Net =
156,000 − 5,760,000 − 0 = −R 5,604,000. - Net per MWh generated =
(156,000 − 5,760,000) ÷ 12,000 = −R 467 / MWh generated. - Sold share =
240 ÷ 12,000 = 2 %— the same 2 % sold the headline uses on a thinly contracted plant. - Unsold =
12,000 − 240 = 11,760 MWh. That energy is not in Earned. Its market value is forgone, on the headline and in Chapter 4.
This is the pattern to expect on your own page: the lifetime spine is those months added together. If this month has no Money Room fact, How sure is this story counts it as estimated and still includes it in the four figures.
12.2 Chapter 1 — the river of money
Think of the plant as a bakery that has been open since commissioning. Chapter 1 is not the shop window — that is the verdict (§12.1). This chapter is the river: every month’s cash flowing past the same zero line, so you can see when the till started, when the recipe cost never moved, and when leftover loaves were never offered to anyone.
Two cards sit in this chapter, in this order. Why the plan was missed is the latest closed month explained against its plan. Monthly Money is every month since commissioning on one chart. They answer different questions. Do not add them.
Follow along. Seat:
ipp_2@webill.net. Path: Generator sites → IPP2 Atlantis Wind → Strategy → Dashboard, then scroll to Chapter 1 · the river of money (#ipp-story-timeline). You should see a left-hand tell, then the plan bridge card, then Monthly money with a toggleable legend. On the demo, until settlement has run, the river is almost entirely estimated and the bridge often has nothing to compare yet — and says so.
- Read the left-hand title and the So what box. The title is written from the numbers.
- Read the plan bridge card for the latest closed month only. If that month is not closed with a plan, stop at the empty sentence. If the card is built, read Plan, Actual, then the seven steps.
- Read Monthly Money against the zero line: money in above, money out and forgone below.
- Use the legend chips if one series is drowning the others.
- Read the flags and the grade ticks under the axis.
- Then go to Chapter 2 — do not stay here to add up the lifetime steps.
Where this is taught. The four lifetime figures that this river adds up: §12.1. The lifetime waterfall that names which step took the money: §12.3. The seven-step bridge arithmetic: V16 §5.
12.2.1 Finding Chapter 1
| Cue | What it is |
|---|---|
| Seat | ipp_2@webill.net (organisation door; password
supersecret on the demo) |
| Menu | Generator sites → IPP2 Atlantis Wind → Strategy → Dashboard |
| Route | /org/generator-sites/:id/strategy/dashboard |
| Chapter | #ipp-story-timeline — eyebrow Chapter 1 · the
river of money |
| Bridge card | performance-bridge-{book id} — eyebrow Why the
plan was missed, Why actual beat the plan,
Plan met or Plan against actual (§12.2.5) |
| Chart | svg#ipp-story-timeline-chart |
| Legend | #ipp-story-timeline-legend and six chips
#ipp-story-timeline-legend-* |
The left column (lg:col-span-3) carries the eyebrow, a
title written from the story, two short paragraphs, and — when the plant
is thinly sold — a green So what box
(data-role="so-what"). The right column is the bridge, then
the chart.
The title is one of four sentences:
| When | Title on screen |
|---|---|
| Generated, sold share under 50 % | Every month the plant paid to make energy it gave away. |
| Generated, net above zero | The plant has earned more than it cost to run. |
| Generated, net still negative | Revenue has not yet covered the cost of generation. |
| No generation yet | The record starts when the meter does. |
The first tell paragraph is fixed: above the line is money in, by source; below it is money out and money forgone — the cost of generation and the value of unsold energy at the day-ahead price; the thin green line is net margin; flags mark what changed and when.
The second paragraph is the plant’s own reading. If no month has a sale, it says nothing sits above zero yet and the amber band is the whole of generation valued at the market price nobody has been offered. When buyers appear it names the first sale month, how much they lift the line, the monthly cost they sit against, and whether the amber shrinks. On a plant that sold less than half of what it made, the So what is: the shape of the loss has not changed since day one. It is a sales problem with a history, not a bad month.
Empty: if the meter has never recorded generation, the chapter still renders. The title says the record starts when the meter does.
12.2.2 Words, colours, flags and ticks
The chart card is the same white chapter card as the rest of the
story
(rounded-xl border border-slate-200 bg-white p-4 shadow-sm).
The header reads Monthly money · R million · {from} →
{to} (the span uses long dates,
e.g. 1 June 2026 → 1 July 2026). A slate chip on the right
says estimated months hatched.
The plot is in R million. The heavy slate line is
0. The left-hand ticks are + above zero
and − below it — those ticks stay in millions as the axis
unit. The last month of the net line is labelled in grouped Rand
(net −R 5,604,000), not compact m /
k.
| Legend chip | Colour on the plot | What it is |
|---|---|---|
| PPA sales | Brand green #059669 |
Money from PPAs (Power Purchase Agreements) that month |
| certificates | Teal #0f766e |
Cash from RECs (Renewable Energy Certificates) |
| SAWEM day-ahead | Sky #0284c7 |
SAWEM (South African Wholesale Electricity Market) day-ahead cash |
| cost of generation (LCOE) | Slate wash, slate stroke | Generation × LCOE (Levelised Cost of Energy) — not a bill anyone sent |
| unsold energy at market P50 | Amber wash, amber stroke | Unsold megawatt-hours at the market P50 (the middle day-ahead price), less the imbalance allowance. This is forgone, not a cost |
| net margin | Thin dark-green line #047857 |
Earned − cost of generation − other costs (network, fees). Forgone is not subtracted here |
When unsold energy has a value, the plot itself writes two labels in the lower band: unsold energy at market price · never offered, and cost of generation · LCOE {N} c. If there is no price forecast, the amber still draws at zero height and the lifetime forgone figure can read R 0 even while megawatt-hours sit unsold — the river cannot price what it has not been given a price for.
Flags sit on the top edge, with a dashed drop to the zero line. A flag label reads rightwards from its line, except near the right-hand edge, where it reads leftwards so it is not cut off. They are events, not money:
| Flag | When it appears |
|---|---|
| COD | The site’s COD (Commercial Operation Date), as that calendar month |
| metering live | The first month with a generation-meter reading |
| first FINAL HAF | The first HAF (Historical Availability Factor) forecast marked FINAL |
| N PPA(s) · MW · price | PPAs that started that month, with their count, contracted megawatts and the first price in c/kWh |
| first RECs | The first REC vintage month |
| BRP active | The organisation’s BRP (Balance Responsible Party) registration became ACTIVE |
Under the months a five-pixel strip is the money grade for that column: brand-green for settled, sky-blue for invoiced, hatched slate for estimated. The footer repeats it: green tick = settled month · blue = invoiced · hatched = estimated. A year of hatched ticks is honest, not a fault.
12.2.3 How to read Monthly Money
Read each month as a stack, not as a single bar.
Above 0 is money that came in. The stacks sit on the zero line and grow up: PPA sales first, then SAWEM day-ahead, then certificates. They are the same three streams as Earned on the verdict. A month with nothing above zero is a month nobody paid you. The plant still ran. The cost still sits below the line.
Below 0 is two different kinds of “down”, stacked, and they are never added into revenue:
| Band | What it is | What it is not |
|---|---|---|
| Cost of generation (slate, against the zero line) | What it cost you to bake that month’s energy at LCOE | A supplier invoice, a grid tariff, or forgone cash |
| Unsold at market P50 (amber, under the cost) | What the leftover energy would have earned at the baseline | A subtraction from Net, or a fifth money-spine figure |
Cost and forgone can dwarf the green sliver. The chart uses one linear scale above and below zero: a rand is the same height either side of the line, so a +R 0.6 m month never looks as large as a −R 10 m month. The ticks step in the same round amounts both ways, and each side ends on the first whole step past its largest bar. On a thinly sold plant the green stack is therefore short — that is the true size of the money in. Hiding a series (below) rescales the same way.
The net margin line is Earned minus cost of generation minus other costs. It is plotted above zero when the month cleared its own recipe cost, and below zero when it did not. It does not subtract the amber band. If you subtracted forgone here you would count the same leftover twice: once as “we did not earn it” and once as “we lost it”.
| Shape | Read it as | So what |
|---|---|---|
| Nothing above zero; slate and amber fill the month | You paid to make energy nobody was offered | A sales problem, or a closed market route — not a bad weather month |
| Green appears; amber stays as tall | Buyers arrived and took a fraction of the plant | Price may be fine; volume and reach are not |
| Green grows; amber shrinks | Contracts (or bids) are taking the leftover | The river is changing shape — that is the job |
| Net line still below zero after green appears | Sales have not yet cleared LCOE | You are selling, and still losing on every loaf baked |
A month with R 0 above zero and a large slate band is the bakery on a day with no customers: the ovens ran, the recipe cost was booked, the loaves stayed on the shelf. The shelf is the amber band only when a market price exists to value them. Without a price forecast the amber has nothing to stand on.
Where this is taught. How Generated, Earned, Cost and Net are built for one month: §12.1.1–§12.1.4. Who paid, at what price: §12.4. The seven lifetime loss kinds: §12.5.
Nothing above zero
Read it: every month is cost plus leftover. The net line lives in the lower band.
Buyers appear, amber stays
Read it: green lifts the net line a little; amber does not shrink. The contracts sold a fraction of the plant.
12.2.4 The toggleable legend
The six chips under the plot
(#ipp-story-timeline-legend) are buttons, not form
checkboxes. Each has aria-pressed="true" when its series is
drawn. Nothing starts hidden.
Click a chip (phx-click="toggle_timeline_series" on
#ipp-story-timeline-legend-ppa, -certificates,
-market, -cost, -unsold,
-net). The chip strikes through and
aria-pressed becomes false. That series’s
<g data-series="…"> leaves the SVG. The stacks that
remain close the gap: hide PPA sales and the market
stack sits on zero; hide cost of generation and the
amber band sits on zero. The plot rescales to the
series that are still on, still on one scale above and below zero.
Hiding the large amber band is how you make a small green stack easier
to read.
Click again to bring the series back. This is for reading, not for changing the book. The verdict figures and the bridge do not move.
12.2.5 Why the plan was missed
The card above the chart
(WB.WheelingWeb.BridgeComponents.bridge_strip, id
performance-bridge-{book id}) is the margin bridge. It asks a different
question from the river: for the latest closed month, why did
settled money miss the plan?
Its eyebrow names what the card shows. It reads Why the plan was missed when actual fell short of plan, Why actual beat the plan when actual was higher, and Plan met when the two match. While no bridge can be built — an open month, no plan in force, or missing inputs — it reads Plan against actual and says why.
Think of the plan as last month’s shopping list, and Actual as the till tape. The bridge is the seven-line note that walks from the list to the tape. It is not added to Monthly Money, not part of the P&L, and not added to the Loss Ledger. The caption on the card says so.
The heading under the eyebrow is the book label (the site name when
the generator is loaded) and the month in long English (1 July
2027, not 2027-07-01). Then one of these
states:
| State | What you see | What it means |
|---|---|---|
| open | This month is still open. The bridge is built on the 1st, on settled money. | You are still in the month. There is nothing honest to bridge |
| unsupported | Bridges are built for trader and IPP books. | Off-taker and fleet books do not use this card |
| no_plan | No plan was in force for this book in 1 July 2027, so there is nothing to bridge from. Run the engine before the month begins. | The strategy engine never wrote a plan of record |
| refused · empty plan | The monthly forecast has no sales to compare with settled delivery. | A forecast exists but it had no sales lines |
| refused · not built | The bridge has not been built. It needs the monthly forecast’s reference prices and settled delivery. | Inputs are missing |
| missing | No bridge yet. A completed monthly plan, its reference prices and settled actuals are required. | The fact builder has not written seven rows |
| retrospective | Amber line plan chosen after the month began · low confidence, then the bars | A plan was picked after the month started. Read it, do not trust it as a forecast |
| built | Plan R 11,985,000.00 and Actual R 10,703,250.00, then the seven steps | A conserved walk from plan to actual |
Plan, Actual, and each step use grouped Rand
(R 1,000.00, −R 5,604,000.00) — the same
format as the rest of the Dashboard.
On the demo dataset, until settlement has run for this site, expect missing or no_plan. That is the same honesty as a hatched grade bar.
When the bridge is built, read it in this order:
- Plan (
{id}-plan,data-cents) — what the plan of record said the month was worth. - Actual (
{id}-actual) — what settled. - The seven steps, always in this order, including zeros
(
{id}-volume…{id}-unexplained):
| Step on screen | Plain reading |
|---|---|
| volume | You delivered a different quantity than the plan |
| price | The average price moved |
| shape | The hours you delivered were not the hours the plan priced |
| imbalance | Market settlement for being off the schedule |
| contract | A fixed PPA protecting (or hurting) you against the market — this step can be positive for an IPP |
| leaks | Energy left on the table, valued at the plan’s captured price — not the Loss Ledger’s Rand |
| unexplained | The residual that makes the seven steps sum to Actual − Plan. Often a market fee |
Rose bars are negative steps; emerald bars are positive. Each step
has a fold How this step was counted
({id}-inputs-{step}). Open it for a short sentence in your
words, then the numbers that feed that step — planned and
actual sales in MWh, leaked energy, average prices in Rand per MWh, and
the capture factor (the share of the average price you
kept). The leftover step lists any named remainder, such as a market
fee. You will not see JSON, snake_case keys, fact ids, or source refs.
The Money Room copy of this card can also open a lineage drawer; the
Dashboard copy does not (lineage? is off).
| Edge | What you do |
|---|---|
| Open month | Wait for the 1st. Do not invent a mid-month bridge |
| No plan / missing | Run the engine before the month, then wait for settled actuals |
| Retrospective badge | Treat the walk as an after-the-fact story |
demo market price |
The price series is internal:DAM — a demo series, not a
live publish |
| Zeros on imbalance or leaks | The plant was not in a position to incur them, or nothing leaked. Leave them on the list |
How it sits next to Monthly Money: pick the same calendar month on the river. The green / teal / blue stack is that month’s Earned. The bridge’s Actual is the settled cousin of that stack for a closed month. The amber band is not a bridge step. Forgone lives on the river and in Chapter 4; the bridge explains plan versus settled cash.
Where this is taught. The conserved seven-step month (plan R 11,985,000 → actual R 10,703,250): V16 §5. The Money Room copy of the same card: V16 §7.
12.2.6 Worked month — one bar on the river
Data. Method check against the same one-month arithmetic as §12.1, not a sealed demo stamp. LCOE 48 c/kWh. Market P50 for the baseline 70.0 c/kWh, less 5 % imbalance allowance → 66.5 c/kWh.
| Input | Value |
|---|---|
| Metered generation | 12,000 MWh |
| Sold on PPAs | 240 MWh at 65.0 c/kWh |
| Market and certificates | R 0 |
| Other costs | R 0 |
| LCOE | 48 c/kWh |
| Baseline (unsold) | 66.5 c/kWh |
The plot axis is in R million (a tick of
0.16 is R 156,000). Bar and net labels on the screen show
grouped Rand.
- Money in (above 0) is only the PPA stack:
240 × 65.0 × 10 = R 156,000= R 0.156 m. - Cost of generation (slate, below 0):
12,000 × 48 × 10 = R 5,760,000= R 5.76 m. - Unsold:
12,000 − 240 = 11,760 MWh. Forgone:11,760 × 66.5 × 10 = R 7,820,400= R 7.82 m. - Net line (does not subtract forgone):
156,000 − 5,760,000 − 0 = −R 5,604,000= −R 5.60 m. - The green stack is R 0.156 m against R 5.76 m + R 7.82 m below the
line: about
0.156 ÷ 13.74 ≈ 1 %of the drawing, on the same scale as the bands below. Hide unsold energy at market P50 and the scale rebuilds against cost and the net line only; the green stack roughly doubles, to a few per cent of the height. It never looks as large as the cost.
This is the pattern to expect on your own page: a tall slate-and-amber month with a short green stack is a sales problem with a history. The lifetime spine in §12.1 is these months added together. Chapter 2 will say which lifetime step is large enough to fix.
If this month is still open, the bridge card reads Plan against actual and does not walk these numbers. If it is closed and a plan exists, the bridge’s Actual should sit near the R 156,000 till — then the seven steps explain why that till is not the plan.
12.3 Chapter 2 — from sunlight to margin
A lifetime waterfall from P50 potential at market
P50 to net margin
(#ipp-story-waterfall). Think of it as the bakery’s year
written as one long receipt: start with what every loaf the recipe
promised would have fetched at the street price, then take away — or add
back — each thing that happened, until you reach what the shop kept.
Every step is a signed amount, and the steps add up:
the running total lands exactly on Revenue earned, then
on Net margin.
The tell says so: Start with what the plant could have earned had every P50 kilowatt-hour been sold at the market price. Each step is a place the money left or came back, and the steps add up to net margin. The zeros are part of the story. The title names the two ends — R {potential} of potential became R {revenue} of revenue. (or No market price is loaded, so potential cannot be valued yet.).
| Step, in order | What it is | Sign |
|---|---|---|
| P50 potential at market P50 | Lifetime P50 generation valued at the market baseline | The starting total |
| Weather & availability | Months the plant made less than P50, valued at the baseline | Down |
| Months above P50 | Months the plant beat P50, valued the same way. Shown only when some months beat P50 | Up |
| Never offered to anyone | Unsold energy at the baseline — no buyer and no bid | Down |
| Curtailment · imbalance · penalties | The operational rows of the loss ledger (§12.5) | Down, often zero |
| Price paid vs market | What the sold energy fetched against the market value of the same energy | Up or down |
| Revenue earned | A subtotal: the running total lands on lifetime Earned | Subtotal |
| Cost of generation | Generation × LCOE | Down |
| Network & other costs | Money Room cost facts. Shown only when there are any | Down |
| Net margin | Earned − cost of generation − other costs, the verdict’s Net | The closing total |
Zero steps stay on the chart with their zero: a plant that has never traded cannot have imbalance, and a plant that was never curtailed says so. The annotation over Never offered to anyone names its share of the potential (N % of the potential left here). When never offered is the largest step, the so-what is that only one step is large enough to fix the business, and it is the one the Sales desk exists for; when the weather step is larger, it says the largest step is generation itself.
The second tell paragraph reads the steps back in Rand, for example: Weather and availability took R {X}: the plant made N % of P50. Months that beat P50 gave back R {X}. Never offered took R {X}: N % of what was made had no buyer and no bid. Curtailment, imbalance and penalties took nothing — the plant has not yet been in a position to incur them. The energy that was sold fetched R {X} more (or less) than the market would have paid for it. A sentence for network and other costs follows when there are any, and the Months that beat P50 sentence appears only when that step is on the chart.
Worked month — the steps add up
Data. Method check against the same one-month arithmetic as §12.1 and §12.5.8, not a sealed demo stamp. Baseline 66.5 c/kWh (R 665 / MWh), LCOE 48 c/kWh.
| Step | Arithmetic | Rand |
|---|---|---|
| P50 potential at market P50 | 14,000 × 665 |
R 9,310,000 |
| Weather & availability | (14,000 − 12,000) × 665 |
−R 1,330,000 |
| Months above P50 | — (the month was below P50; the step is not drawn) | — |
| Never offered to anyone | 11,760 × 665 |
−R 7,820,400 |
| Curtailment · imbalance · penalties | nothing incurred | R 0 |
| Price paid vs market | 156,000 − 240 × 665 = what 240 MWh fetched at 65 c less
their value at 66.5 c |
−R 3,600 |
| Revenue earned | the running total | R 156,000 |
| Cost of generation | 12,000 × 48 × 10 |
−R 5,760,000 |
| Net margin | the running total | −R 5,604,000 |
Conservation:
9,310,000 − 1,330,000 − 7,820,400 − 0 − 3,600 = 156,000 =
Earned ✓, and
156,000 − 5,760,000 = −5,604,000 = Net ✓.
The read paragraph on this month says the sold energy fetched R
3,600 less than the market would have paid for it — 65 c against a
66.5 c baseline — and the so-what points at Never offered to
anyone, the one step large enough to fix the business.
12.4 Chapter 3 — where the money came from
Think of the bakery’s till tape. Chapter 1 showed when the till moved. Chapter 2 showed which step took the money. This chapter is the tape itself: who paid, at what price against the cost of baking and against the street price, and how much of the till each name is.
That table is the sources ledger
(#ipp-story-sources-table). Every active physical PPA (Power Purchase Agreement) is a named
buyer row. Then two routes that could dwarf those lines sit on the same
table even when they have earned nothing: RECs (Renewable Energy
Certificates) and SAWEM (South African Wholesale
Electricity Market) day-ahead. A zero on those rows is the gap made
visible, not a missing line.
Follow along. Seat:
ipp_2@webill.net(passwordsupersecreton the demo). Path: Generator sites → IPP2 Atlantis Wind → Strategy → Dashboard, then scroll to Chapter 3 · where the money came from (#ipp-story-sources). You should see a left-hand tell, a green So what box when the page has a reading, and the white sources table. RECs (data-source-id='certificates') and SAWEM day-ahead (data-source-id='market') are always there. An active PPA appears as a named buyer with its price against LCOE (Levelised Cost of Energy) and the market.
- Read the left-hand title. It counts physical PPAs and prices, or it says nobody has paid yet.
- Read the So what. It judges the best contract price against LCOE and the market — volume and reach, or a price that loses money.
- Read each PPA row: who, since when, how much energy, the price rail, the Rand, the share bar, the eight-month spark.
- Read RECs and SAWEM day-ahead with their zeros. Those two routes are why a thin PPA book can still be a sales problem.
- Read Total earned. Achieved is the price on what sold. Realised is the price on everything the plant made. HHI (Herfindahl–Hirschman Index) is how concentrated the PPA till is.
Where this is taught. Who takes the money on the latest forecast run (Overview Who buys, one typical day): §4.5. Money Room streams (PPA, market, certificates) that grade a settled month: V16 §7 and V16 §8.2. This section is the lifetime till tape. It does not re-teach the four verdict figures (§12.1) or the waterfall steps (§12.3).
12.4.1 Finding Chapter 3
| Cue | What it is |
|---|---|
| Seat | ipp_2@webill.net (organisation door; password
supersecret on the demo) |
| Menu | Generator sites → IPP2 Atlantis Wind → Strategy → Dashboard |
| Route | /org/generator-sites/:id/strategy/dashboard |
| Chapter | #ipp-story-sources — eyebrow Chapter 3 · where
the money came from |
| Table | #ipp-story-sources-table |
| Buyer row | [data-role='source-row'] with
data-source-id = the PPA id |
| Certificates | [data-source-id='certificates'] |
| Market | [data-source-id='market'] |
| Total | [data-role='source-total'] |
The left column (lg:col-span-3) carries the eyebrow, a
title written from the story, two short paragraphs, and a green
So what box (data-role="so-what"). The
right column is the table.
The two tell paragraphs are fixed. The first: every Rand earned is listed by who paid it, at what price against the cost of generation and the market, and how much of the total it is. The second: the two routes that could dwarf these lines — the day-ahead market and certificates — are shown with their zeros so the gap is visible in the same table.
The title is written from the PPA rows, not from RECs or the market:
| When | Title on screen |
|---|---|
| No PPA buyer has a row | No buyer has paid for a kilowatt-hour yet. |
| One physical PPA, one price, and a start month | 1 physical PPA, one price, N months. |
| Several physical PPAs, the same price | N physical PPAs, one price, N months. — for example 3 physical PPAs, one price, 9 months. |
| Several physical PPAs, several prices | N physical PPAs, M prices, N months. |
Months is the span from the earliest Since date to the current month, at least one. The count is physical PPAs — one row each, and one buyer can hold several — not buyers, and not RECs or the market.
The So what is a price reading, using the highest PPA price on the table:
| When | So what |
|---|---|
| No PPA buyers | the plant has a price card and no counterparties; volume and reach come first. |
| Best price above LCOE and above the market P50 | {N} c is a good price (above market and LCOE). The problem is volume and reach, not price. |
| Best price above LCOE but not the market | {N} c clears LCOE but trails the market; the next contract should not. |
| Best price at or below LCOE | {N} c is below the cost of generation; every kilowatt-hour sold loses money. |
If there is no market price forecast, the first happy sentence drops the word market and and compares to LCOE only.
Empty: the chapter still renders with no PPA rows. The title says nobody has paid. The RECs and SAWEM rows stay, usually at R 0.
12.4.2 Words and columns
The table card is the same white chapter card as the rest of the
story
(rounded-xl border border-slate-200 bg-white p-4 shadow-sm).
Headers are sticky-looking uppercase labels. Amounts of 1,000 or more
use a comma thousands separator (R 1,000,
R 156,000). Dates use long English
(1 July 2026), the same date_long as the
verdict.
| Column | What it is |
|---|---|
| Source | The buyer name in bold, then a grey detail line. On RECs and SAWEM the name is the route, and the detail is the registry or the BRP (Balance Responsible Party) registration |
| Since | When that source started. A PPA uses its contract start. RECs use the first vintage month. SAWEM uses the registration effective date. Empty is an em dash |
| Energy | What that source took, as 240 MWh or
12.4 GWh once the sum is 1,000 MWh or more. RECs print
{N} MWh from the certificate quantity. SAWEM prints
0 GWh until it has earned, then an em dash (the row has
Rand, not a stored megawatt-hour) |
| Price vs LCOE · market | A short rail with three ticks, then the contract price in c. RECs do not use the rail. SAWEM uses the rail without a contract tick |
| Revenue | Lifetime Rand from that source (rand_grouped). Zero
RECs and zero market render slate, not ink |
| Share | On a PPA: a brand-green bar in a 90 px track, plus a whole percent. On RECs: a percent of all lifetime Earned, or an em dash when Earned is zero. On SAWEM: a status chip, not a percent. On the total: the revenue HHI |
| Trend | Last eight months of that PPA’s estimated Rand, as a brand-green
sparkline (data-role="spark"). RECs, SAWEM and the total
show an em dash |
A PPA share bar is that buyer’s Rand as a share of PPA buyer Rand only. It is not a share of Earned. One PPA and a large market till still shows 100 % on the PPA bar. The market chip sits in the same column so you do not add the percents.
The lifetime Earned figure on the verdict is PPA + market + certificates. This table’s Total earned is that same sum. Do not add the buyer rows to RECs and SAWEM in your head and then add the total again.
12.4.3 Each PPA buyer row
Each row is one ACTIVE physical PPA on this
generator that has a start date (data-role="source-row",
data-source-id = the PPA id). Rows sort largest
Rand first. A virtual (financial) hedge is not a row here.
The name is the other side of the deal: the off-taker site, or the trader, or the agreement reference if those names are missing. The grey line under the name is, in this order, whatever the contract has:
{off-taker \| trader} · physical PPA · {N} MW · {contract type} · {tariff} · {N} yrs
| Word on the line | Meaning |
|---|---|
| off-taker | The buyer is an offtaker site, not a trader |
| trader | The buyer is a trader book in the middle |
| physical PPA | Energy is wheeled. This ledger does not list virtual PPAs |
| {N} MW | Contracted capacity. Missing capacity uses the average of the other PPAs, or 1 MW if the plant has no export figure |
| as-generated / firm / capped / baseload / top / shaped | The contract type — the shape of the promise, lower-cased with a hyphen |
| fixed / tou / … | The tariff type, lower-cased |
| {N} yrs | The term in years |
Since is the contract start as
1 June 2026.
Energy and Revenue on an estimated month (no completed actual-scenario run) are the PPA’s capacity share of that month’s generation, priced at the contract c/kWh:
share = min(contracted MW ÷ plant export MW, 1)
MWh = Generated MWh × share
Rand = MWh × price c/kWh × 10
The × 10 is the same unit change as Cost of generation:
c/kWh to R/MWh. A 1 MW slice of a 50 MW plant is 2 % of the month.
Months before the start date, and months after the term ends, add
nothing.
A month that already has a completed actual-scenario run is not re-estimated onto the buyer row. That month still sits in lifetime Earned on the verdict. The row is the capacity-share rebuild of the months that still need one, so the page does not count the run twice.
The trend spark is those same monthly Rand figures
for the last eight months on the story, brand green
#059669, with a dot on the latest month. A flat line at
zero is a buyer who has not yet taken a kilowatt-hour in that
window.
12.4.4 RECs
The certificates row is always present
(data-source-id='certificates'). The bold name is
RECs. This is not a carbon credit and not a Money Room
cost.
| Piece | What you see |
|---|---|
| Detail, empty | no REC batches issued yet |
| Detail, with batches | {registry} · {N} certificates · {statuses} —
e.g. ZA-RECS · 10 certificates · allocated. Statuses are the
distinct batch statuses, lower-cased and comma-joined |
| Since | The first vintage month, or an em dash |
| Energy | {N} MWh — the sum of batch quantities, including
0 MWh |
| Price | A slate pill: priced on allocation when the row’s Rand is above zero; no price yet when it is not. There is no LCOE rail. A certificate is not an energy sale |
| Revenue | Lifetime certificate cash (totals.certificates_r).
Slate when R 0 |
| Share | That Rand as a percent of lifetime Earned, to one decimal when it is a sliver; an em dash when Earned is R 0 |
| Trend | An em dash |
On the demo dataset, until certificate batches exist for this site, expect the empty detail and R 0. That is honest. The row is there so you can see the route is unused.
Where this is taught. What a REC is, and that the platform is a mirror not a registry: V0 §10 · V19. Certificate cash as a Money Room stream: V16 §8.2.14.
12.4.5 SAWEM day-ahead
The market row is always present
(data-source-id='market'). The bold name is SAWEM
day-ahead. The detail line is the organisation’s BRP
registration, not a buyer name.
| Registration | Detail on screen |
|---|---|
| None | organisation not BRP-registered · route closed |
| ACTIVE | {code} active · {N} bids — e.g. BRP-IPP-1 active · 2
bids. The code falls back to BRP if it is missing |
| In progress | {code} registration in progress |
Since is the registration’s effective date
(agreement effective, or effective-from). Energy is
0 GWh while market Rand is zero, and an em dash once market
Rand is above zero — the row does not store a megawatt-hour.
The Share column is a chip, not a bar:
| Chip | When | Tone |
|---|---|---|
| route closed | No BRP registration | Amber |
| opening | A registration exists and is not yet ACTIVE | Amber |
| route open, unused | ACTIVE, and bid count is 0 | Sky |
| trading | ACTIVE, and at least one bid is on the book | Sky |
Those chips match the verdict chips market route open, unused / trading day-ahead / not BRP-registered (§12.1.5). They do not move lifetime Earned.
Revenue is lifetime market cash
(totals.market_r): day-ahead, flexible, intraday, or
imbalance facts when a Money Room month exists, otherwise R
0 on an estimated rebuild. Slate when zero.
The price cell is the rail without a contract tick,
labelled {N} c P50 in sky, or the words no SMP
forecast when the daytime SMP
(System Marginal Price) series is missing.
Where this is taught. What a BRP is and how the day-ahead door opens: V9 §1.3 · V10 §5. Market cash as a Money Room stream: V16 §8.2.
12.4.6 Price vs LCOE · market
The rail is an 80 px strip that fades from rose on the left to mint on the right. Three ticks sit on it. Hover a tick for its label.
| Tick | Colour | Meaning |
|---|---|---|
| LCOE | Slate (#64748b) |
The book’s lcoe_ckwh — default 48.0 c.
Tooltip LCOE 48.0 c. Edit it on Overview (§4.3) |
| market P50 | Sky (#0284c7) |
The daytime SAWEM day-ahead P50, averaged across the story’s months. Tooltip market P50 {N} c. This is the raw P50, not the 5 % imbalance-shaved baseline Chapter 4 uses to value leftover energy |
| Contract | Ink (#1e293b) |
This PPA’s energy_price_ckwh. The number after the rail
is {N} c (one decimal) |
The strip’s right-hand end is the larger of LCOE ×
2.5, 100 c, and the dearest buyer price on the
table. A 48 c LCOE therefore sits near 40 % of a 120 c rail
(48 × 2.5 = 120). A 65 c contract sits further right. A 150
c contract stretches the rail so every tick still fits.
On the SAWEM row the contract tick is omitted and the label is
{N} c P50. On RECs there is no rail.
Read the three ticks as a shop price-check: left of LCOE means every sold kilowatt-hour loses money against your own recipe; between LCOE and the market means you cleared cost but left street price on the table; right of both means the price is not the problem.
Overview’s Price vs cost rail is a cousin, also in c/kWh, on the latest run (§4.7). This rail is the lifetime buyer.
12.4.7 Total earned, achieved, realised and HHI
The last row (data-role="source-total") is
extra-bold.
| Cell | What it prints |
|---|---|
| Source | Total earned |
| Energy | Lifetime sold megawatt-hours (gwh of
totals.sold_mwh) |
| Price | lifetime · achieved {N} c/kWh on sold · realised {N} c/kWh on all generated — for example lifetime · achieved 64.4 c/kWh on sold · realised 1.7 c/kWh on all generated. The achieved clause is omitted when sold energy is zero |
| Revenue | Lifetime Earned, grouped Rand |
| Share | HHI 0.53 to two decimals, or an em dash when there are no PPA buyers |
| Trend | Empty |
Achieved price
is Earned ÷ sold energy, as c/kWh:
revenue_r ÷ sold_mwh ÷ 10. Unsold hours are ignored. A
plant that sold a sliver at 65 c looks fine here.
Realised
is Earned ÷ all generation, printed in c/kWh:
revenue_r ÷ gen_mwh ÷ 10. Unsold hours count as zero. This
is the honest plant number. On a 2 % sold book it is a cent or two per
kilowatt-hour while LCOE is 48 c.
Revenue HHI here is the sum of each PPA buyer’s squared share of PPA revenue. RECs and SAWEM are not in it. No buyers → em dash, not a fake 0.00.
| Book | Shares | HHI | Read it as |
|---|---|---|---|
| One buyer | 100 % | 1.00 | Sole customer. Chapter 5’s Buyer concentration vital is red |
| Two equal | 50 % + 50 % | 0.50 | Two names; the Dashboard vital turns amber at ≥ 0.5 and red at ≥ 0.7 |
| One dominant | 70 % + 30 % | 0.58 | One name takes most of the till |
| Three equal | ~33 % each | ≈ 0.33 | Comfortably spread |
Overview’s HHI meter is the same idea on the latest forecast run (§4.5). This cell is the lifetime PPA book. Believe Overview for “who takes tomorrow’s typical day”; believe this row for “who has paid since commissioning”.
| Source | Since | Energy | Price | Revenue | Share |
|---|---|---|---|---|---|
| Daytime Foundry · off-taker · physical PPA · 1.0 MW · as-generated · fixed · 10 yrs | 1 June 2026 | 240 MWh | 65.0 c (rail: LCOE 48 · market 70 · contract 65) | R 156,000 | 100 % |
| RECs · no REC batches issued yet | — | 0 MWh | no price yet | R 0 | — |
| SAWEM day-ahead · organisation not BRP-registered · route closed | — | 0 GWh | 70.0 c P50 | R 0 | route closed |
| Total earned · lifetime · achieved 65.0 c/kWh on sold · realised 1.3 c/kWh on all generated | R 156,000 | HHI 1.00 | |||
The three source rows add to Total earned. The 100 % bar and the HHI are among PPA buyers only — they do not include the two zero routes.
12.4.8 Empty states and edges
| Edge | What you see | What you do |
|---|---|---|
| No active physical PPA | Title No buyer has paid…; table starts at RECs | Sign a buyer, or open the market route. Volume and reach come first |
| PPA exists, estimated months only | Buyer row with energy, Rand, a 100 % bar, HHI 1.00 | Read the rail. If the price is fine, the leftover is still Chapter 4 |
| Two PPAs, one price | Title 2 physical PPAs, one price…; two bars that sum to 100 % | HHI tells you whether one name still owns the till |
| RECs unused | no REC batches issued yet · R 0 · no price yet | Leave the row. Do not hide it |
| Market unused, not a BRP | organisation not BRP-registered · route closed · amber chip | Registration is the door; Sales → Option 0 is the bid |
| Market unused, BRP active, no bids | {code} active · 0 bids · route open, unused | The door is open. The leftover is still never offered |
| Market earning, no stored MWh | Energy is an em dash; chip trading | Believe the Rand, not a missing megawatt-hour |
| No SMP forecast | Price cell no SMP forecast; so-what compares to LCOE only | The rail cannot mark a street price it has not been given |
| Actual-scenario month already run | That month is in lifetime Earned; it is not added again to the buyer row | Do not expect the buyer MWh to equal lifetime sold when those runs exist |
| Virtual PPA only | No buyer row for that hedge | This ledger is physical PPAs on this generator |
| Draft PPA, no start date | No row | The deal is not on the tape until it is ACTIVE with a start |
| Buyer concentration vital | Chapter 5 repeats this HHI as a stripe | Amber at ≥ 0.5, red at ≥ 0.7 (§12.6) |
12.4.9 Worked month — one buyer on the tape
Data. Method check against the same one-month arithmetic as §12.1 and §12.2.6, not a sealed demo stamp. LCOE 48 c/kWh. Daytime market P50 70.0 c/kWh (the rail mark). One 1.0 MW as-generated PPA on a 50 MW plant.
| Input | Value |
|---|---|
| Plant export | 50 MW |
| PPA | 1.0 MW · as-generated · fixed · 10 yrs · 65.0 c/kWh · since 1 June 2026 |
| Metered generation | 12,000 MWh |
| Market and certificates | R 0 |
| LCOE | 48 c/kWh |
| Market P50 (rail) | 70.0 c/kWh |
- Capacity share =
1.0 ÷ 50 = 0.02. - Buyer energy =
12,000 × 0.02 = 240 MWh. - Buyer revenue =
240 × 65.0 × 10 = R 156,000. - Share among PPA buyers = 100 %. HHI =
1.00² = 1.00. - Achieved on sold =
156,000 ÷ 240 ÷ 10 = 65.0 c. - Realised on all generation =
156,000 ÷ 12,000 ÷ 10 = 1.3 c/kWh(R 13 / MWh). - Against LCOE 48 c: the plant cleared 65 c on the sliver and 1.3 c on the bakery.
- The rail: LCOE 48, contract 65, market 70. 65.0 c clears LCOE but trails the market; the next contract should not. That is the so-what when this is the dearest buyer.
- Conservation:
R 156,000 + R 0 + R 0 = R 156,000= Total earned = the verdict’s Earned for the month.
This is the pattern to expect on your own page: a good-looking
65.0 c next to a 1.3 c/kWh realised
and an HHI 1.00 is a price that works on a sliver, a
plant that has not sold, and a till that depends on one name. Add a
second buyer at the same price for 30 % of the PPA till and HHI falls to
0.70² + 0.30² = 0.58 — still amber on the health vital,
still a concentration story.
The lifetime table is those months added together. Chapter 4 then values the 11,760 MWh nobody was offered. Chapter 6 prices the move that would put a second name, or a bid, on this tape.
12.5 Chapter 4 — where the losses came from
Chapter 3 is the till: who paid you. Chapter 4 is the leftover book — every way the plant did not get paid, each valued against a stated compared with what?, with the zeros left on the list so you can see a well-run machine next to a sales problem.
Think of the bakery again. The ovens ran. Some loaves sold. The rest sat on the shelf. This chapter prices the shelf at what the street market would have paid that afternoon, then lists the other leaks that are easy to confuse with that shelf: weather that never baked the loaf, a machine that slipped, the traffic officer who closed the road, a market fine, a contract penalty, a credit that expired. Those are seven questions. They are not seven slices of one pie. Do not add the seven Rand figures and expect the sum to match Net on the verdict.
The leftover on the shelf is forgone / never offered. It is money nobody was offered. It is not a bill, and it is not subtracted from Net. The verdict names it; Monthly Money draws it as the amber band; this chapter is where that number gets a row, a baseline, a confidence, and a clock that says when it happens.
Follow along. Seat:
ipp_2@webill.net(passwordsupersecreton the demo). Path: Generator sites → IPP2 Atlantis Wind → Strategy → Dashboard, then scroll to Chapter 4 · where the losses came from (#ipp-story-losses). You should see a left-hand tell, a green So what box, a white card with the loss ledger on the left and the heat strip on the right, then a second white card Annual curtailment exposure. On the demo, until settlement has run, the top row is usually Unsold, never offered and the operations rows stay zero — and say so.Data. Method check against the same one-month arithmetic as §12.1 and §12.2.6, not a sealed demo stamp. LCOE 48 c/kWh. Market P50 70.0 c/kWh, less 5 % imbalance allowance → 66.5 c/kWh. Lifetime headline figures on a thinly sold plant (
R 140,000,000never offered) are those months added together.
The left column (lg:col-span-3) is the eyebrow
Chapter 4 · where the losses came from, a title written
from the largest row, three short paragraphs, and a green So
what box (data-role="so-what"). The So
what is always the same: So what: predictable losses are
the cheapest kind to remove.
The title is one of three sentences:
| When | Title on screen |
|---|---|
| Every row is zero (or there is no row) | No valued losses yet. |
| The largest row is Unsold, never offered | One loss, {N} gigawatt-hours long. (or megawatt-hours when the leftover is under 1,000 MWh) |
| Another kind is larger | {that kind’s label} is the largest loss. |
The three tell paragraphs are fixed. The ledger values every kind the platform knows about against a stated baseline, with a confidence. Kinds that are zero stay on the list: a zero for curtailment or penalties is evidence of a well-run plant, and a zero for imbalance is evidence it has never traded. The heat strip shows when the unsold energy occurs — that is the shape a buyer or a bid has to fit. Annual exposure is the year-scale close of that same ledger: what the grid already took, and what you still stand to lose after claims.
The right column is two stacked white cards: the ledger plus heat
(#ipp-story-loss-ledger and
#ipp-story-heat-chart), then
#ipp-curtailment-exposure.
Where this is taught. The four lifetime figures this leftover sits beside: §12.1. The amber band on Monthly Money: §12.2.3. Who paid for the loaves that did sell: §12.4. The 24-hour unsold stack on Overview (one typical day, not the lifetime heat): §4.2. The Money Room’s organisation Loss Ledger (eleven kinds, never added to the P&L): V16 §5 and V16 §8.3. The Sales Desk that sells this shape: §6. Do not re-read this chapter for the verdict spine, the river, or the sources tape.
12.5.1 Finding Chapter 4
| Cue | What it is |
|---|---|
| Seat | ipp_2@webill.net (organisation door; password
supersecret on the demo) |
| Menu | Generator sites → IPP2 Atlantis Wind → Strategy → Dashboard |
| Route | /org/generator-sites/:id/strategy/dashboard |
| Chapter | #ipp-story-losses — eyebrow Chapter 4 · where
the losses came from |
| Ledger | #ipp-story-loss-ledger — seven rows,
data-role="loss-row" and data-kind |
| Heat | svg#ipp-story-heat-chart — hour × month, 06h–18h |
| Exposure | #ipp-curtailment-exposure — Annual curtailment
exposure, then Review claims |
Empty: if the meter has never recorded generation, the chapter still renders. The title can still say No valued losses yet. when every row is R 0 (no price to value leftover, or nothing leftover). The seven rows never disappear.
12.5.2 Every word on the ledger
The ledger card is the same white chapter card as the rest of the
story
(rounded-xl border border-slate-200 bg-white p-4 shadow-sm).
The header on the left reads Loss ledger · lifetime · baseline
in small print. The header on the right reads When the
unsold energy happens · by hour × month.
Each row is a three-column grid:
| Column | What you see | What it is |
|---|---|---|
| Kind | Bold label, then a grey line | The name of the question, then the baseline and the confidence (or a status sentence when the row is a rebuild) |
| Share bar | A 2.5-unit track | How large this row is against the largest row, not against a total. The largest bar fills the track. A live row is given at least 1.2 % width so a small number does not vanish |
| Rand and energy | Grouped Rand, then a small line | The valued leftover. Amounts of 1,000 or more use a comma
(R 1,000, R 7,820,400). If the row has energy,
the small line is megawatt-hours or gigawatt-hours
(11.8 GWh, 310 MWh). If energy is zero, the
small line is the confidence (high confidence) or an em
dash on a zero row |
data-kind on the row is the platform name. Use it when
you talk to support or when a test looks for a row.
data-kind |
Label on screen |
|---|---|
unsold_never_offered |
Unsold, never offered |
below_p50 |
Below P50 generation |
availability_slide |
Availability slide |
curtailment_unrecovered |
Curtailment unrecovered |
imbalance_uninstructed |
Imbalance, uninstructed |
shortfall_penalties |
Shortfall penalties |
banking_expired |
Banking expired · escalation drift |
A zero row (row.zero? when Rand is R 0
or less) goes slate grey. The share bar is empty. The small line is
—. That is evidence, not a missing line.
Bar colour: Unsold, never offered is amber (the same leftover colour as Monthly Money). Every other live row is slate. There is no green bar on this card — green is money in, and this card does not list money in.
Confidence on a live row is one of high, medium, or low. You read it on the grey line under the label. You only see the word confidence on the right when the row has no energy to print.
| Confidence | When the page uses it |
|---|---|
| high | A Money Room fact exists, or the row is an operations zero that the plant can prove (no SO instruction, no bid, no shortfall clause) |
| medium | The page rebuilt Unsold, never offered from generation minus sold, or the banking row is still watching contracts |
| low | Below P50 generation and Availability slide — modelled against the market price, not a closed ledger |
12.5.3 How a row gets its Rand
A Rand of leftover without compared with what? is a claim you cannot defend. Every row therefore carries a baseline — one human sentence, printed under the label.
The commercial leftover (unsold energy, energy below P50, a slide in availability) uses the same baseline price as the verdict and the amber band:
SAWEM day-ahead P50 for 08h–15h, less a 5 % imbalance allowance.
In plain words: take the middle DAM (Day-Ahead Market) price forecast for the plant’s daytime hours (08h–15h SAST), then keep 95 % of it. The 5 % is a haircut for the chance that a bid would not land exactly. The page stores that as 66.5 c/kWh when the raw P50 is 70.0 c/kWh.
One megawatt-hour at that baseline is:
baseline c/kWh × 10 × 0.95 = Rand per MWh
The × 10 is the unit change from c/kWh to R/MWh. The
× 0.95 is the imbalance allowance. It is the same
conversion as cost of generation, plus the haircut.
If the price forecast is missing, the baseline is empty and the commercial rows print R 0 even while megawatt-hours sit unsold. The page will not invent a street price. That is honest, not a fault. Monthly Money draws the amber at zero height in the same case.
When the Money Room already has facts for a kind, the row uses those facts (Rand and energy from the fact, confidence high, note ends settled). When it does not, the page rebuilds the commercial kinds from the meter, the contracts, HAF, and the baseline.
Where this is taught. How Generated and Earned are built for one month: §12.1.1–§12.1.2. The Money Room fact that can replace a rebuild: V16 §5. The price forecast behind the baseline: V10.
12.5.4 The seven kinds
Seven rows, always, in this order. A zero stays.
| Kind | Valued as | Zero means |
|---|---|---|
| Unsold, never offered | Unsold energy at SAWEM P50 less 5 % imbalance — or the Money Room’s spill facts when they exist | Every kilowatt-hour found a buyer or a bid |
| Below P50 generation | (month P50 − generation) at the baseline | The plant met its P50 |
| Availability slide | HAF below its best month × that month’s P50 × baseline, since the decline began | Availability is at its best recorded level |
| Curtailment unrecovered | System Operator instructions; finished claims on §10 | None received, or every claim was paid in full |
| Imbalance, uninstructed | Market settlement (plus gate-miss facts when they exist) | No market schedules to deviate from |
| Shortfall penalties | PPA ledger | No shortfall clause triggered |
| Banking expired · escalation drift | Spill and price clauses | No expired credit; fixed tariffs flagged watch |
Unsold, never offered is the shelf. Energy =
generation − sold, never below zero. Rand = that energy × the baseline.
The grey line reads at SAWEM P50 less 5 % imbalance · medium
confidence on a rebuild. When the Money Room has
spill_forfeited, market_uncaptured, or
spill_discount_gap facts, the row switches to those facts
and the line ends settled.
Below P50 generation is the loaf that was never baked. Each month’s P50 is the site’s annual P50 ÷ 12, times a southern-hemisphere seasonal weight (higher in summer, lower in winter — the same weights the story uses when a month has no meter). Energy = max(P50 − generation, 0). Rand = that energy × the baseline. The grey line is always weather + availability at market P50 · low confidence. Weather and a slipping machine both live in this number; the next row isolates the slip.
Availability slide asks a narrower question: did HAF fall from its best month, and what is that drop worth? The page finds the best recorded HAF, then every later month that sits below it. For each of those months:
(best HAF − this month's HAF) × this month's P50 × baseline
The grey line names the drop in long dates: HAF 0.86 → 0.79 since 1 March 2026 · estimated. When nothing has fallen, the line is no decline from the best month and the row is zero. This Rand can overlap the Below P50 story — it is a second question, not a second pile of megawatt-hours.
Curtailment unrecovered is the traffic officer. When
Money Room facts of kind curtailment_unrecovered exist, the
row uses them ({N} SO instructions · settled). When they do
not: no SO instructions received, or {N} instructions · not
yet valued. A zero here is good operations, not a missing screen.
The white card under the ledger is a different number —
the year-ahead estimate, taught in §12.5.6.
Imbalance, uninstructed is the market fine for being
off your own schedule. Facts: imbalance_uninstructed and
market_gate_misses (market settlement · settled).
Without facts: no market schedules to deviate from when you
have placed no bids, or {N} bids · not yet settled. A plant
that has never traded cannot have this loss. That zero is the proof.
Shortfall penalties is cash you paid because a PPA said you missed a promise. Facts: PPA ledger · settled. Without facts: {N} PPAs · no shortfall clause triggered.
Banking expired · escalation drift is two contract leaks on one row. Banking is leftover energy carried forward as a credit that then expired. Escalation drift is a price clause that ran ahead of the tariff it was meant to track. Facts of either kind make the row settled. Without facts the grey line watches the book: no contracts yet, escalating tariffs, or {N} of {M} PPAs fixed with no escalation · watch.
Where this is taught. How a curtailment claim is lodged and what unrecovered means on that tab: §10. The eleven Money Room kinds (this page folds three spill kinds into Unsold, never offered, and two banking kinds into the last row): V16 §8.3. HAF maths: §5. Do not re-teach who paid (§12.4).
12.5.5 The heat strip
The right-hand plot (svg#ipp-story-heat-chart, view box
420 × 300) is a calendar of leftover hours, not a second ledger. Months
run down. Hours run across from 06h to
18h SAST. Each cell is that month’s unsold
megawatt-hours × that hour’s share of the plant’s leftover shape. Darker
amber means more leftover in that hour. The scale is relative to the
darkest cell on this plant — it is not a Rand axis.
A dashed box outlines 08h–15h. The caption under the plot reads:
08h–15h holds {N} % of everything unsold
That window is the baseline’s daytime hours. It is also the shape a daytime factory, or a day-ahead bid, has to fit. If 90 % of the leftover sits in that box, a night-only buyer will not finish the job.
Hour labels print every other hour (6h, 8h,
… 18h). Month labels print the first month, the last month,
and each January in full (July 2026); other months are the
month name only (July).
Where the hourly shape comes from:
- The latest completed FORECAST run on this book, if it has SPILL lines — the leftover hours of that run, shifted into SAST.
- If there is no such run, a built-in daytime bell (small at 06h, tall through midday, almost gone by 18h). On that fallback the 08h–15h box typically holds about 90 % of the leftover.
The heat strip does not use the Money Room. It does not change when you hide a Monthly Money series. It answers when, not who paid.
| Shape | Read it as | So what |
|---|---|---|
| Dark box in 08h–15h, pale evenings | Leftover is daytime | A daytime buyer or a day-ahead bid fits |
| Dark in the shoulders, pale at noon | Leftover is morning and late afternoon | A 09h–17h factory still helps; a noon-only deal will not |
| Even wash, no dark cell | No leftover, or no price of shape | Check the Unsold, never offered row first |
| One month much darker than the rest | That month made (or sold) differently | Open Monthly Money for that column — do not treat the heat as a P&L |
Overview’s Unsold profile (24h) is the cousin for one typical day on the latest forecast. This strip is the lifetime of leftover hours. Do not add them.
Where this is taught. The 24-hour unsold stack and the intensity strip on Overview: §4.2. Who could absorb this shape: §6 · Who could absorb the gap. Chapter 6 prices the same leftover as a move: §12.8.
12.5.6 Annual curtailment exposure
Under the ledger sits a second white card,
#ipp-curtailment-exposure. The eyebrow is Annual
curtailment exposure. The large figure is grouped Rand with
cents (R 1,234.00) when the engine can compute, or the
words no basis when it cannot. It never invents
R 0.00 for a missing input. A real zero would mean “we
computed zero.” Missing inputs mean the words.
The small line under the figure is the basis, in
words: Estimated from this site’s curtailment history (this
site’s last twelve months of deemed energy), Estimated from the
framework’s expected curtailment rate (the congestion-framework
expected curtailment share of P50), or No curtailment history or
framework rate yet, so there is nothing to estimate from. Then a
green Review claims link to
/org/generator-sites/:id/strategy/curtailment.
This card is the same year-ahead estimate as Curtailment’s sixth
white tile. It has no limit line. It is
not the Curtailment unrecovered ledger
row (that row is lifetime facts, or a honest zero). It is
not a Money Room tile. There is no Annual exposure card
at /org/money.
| Number | Where | What it answers |
|---|---|---|
| Curtailment unrecovered | The ledger row | Lifetime leftover on finished (or not-yet-valued) instructions |
| Annual curtailment exposure | This white card | Typical unrecovered year on this site, after expected recovery |
| Unrecovered tile | Curtailment tab | This month’s finished files that paid short |
| Money Room Unrecovered curtailment | /org/money Panel 4 |
Organisation leftover in the period you picked |
Where this is taught. How the estimate is built, the three leftovers that sound the same, and why the Money Room has no Annual exposure tile: §10.5. The six Curtailment tiles: §10.7.
12.5.7 Edges, empties, and zeros
| Edge | What you see | What you do |
|---|---|---|
| No generation yet | Seven zero rows; title No valued losses yet. | Wait for the meter. Do not invent a leftover |
| Generation, no sales, price forecast present | Unsold, never offered is almost the whole story | Open Sales. The heat strip is the shape to sell |
| Generation, no sales, no price forecast | Unsold megawatt-hours, R 0 on the commercial rows | The page has no street price. The leftover is still real |
| Money Room facts for a kind | Grey line ends settled; confidence high | Trust that row over the rebuild |
| Bids in, nothing settled | Imbalance row {N} bids · not yet settled | Wait for market settlement. The zero is not “no risk” |
| SO instructions, not yet valued | Curtailment row {N} instructions · not yet valued | Open Review claims. Do not read Annual exposure as this row |
| Fixed PPAs, no escalation | Banking row {N} of {M} PPAs fixed with no escalation · watch | A watch, not a bill |
| Share bar looks like 100 % on one row | That row is the largest, not “all of the loss” | The bar is against the max, not a total |
| Adding the seven Rand figures | A number that matches nothing on the spine | Stop. They are seven questions |
What “done” looks like on this chapter: you can name the largest row, say whether it is commercial or operational, point at the hours the leftover sits in, and know whether Annual exposure is a real year-card or no basis. Chapter 6 then prices the move. Health (Chapter 5) tells you whether the machine can deliver it.
12.5.8 Worked leftover book
Data. Same method check as §12.1 and §12.2.6. One calendar month so you can see the arithmetic the lifetime ledger adds up.
| Input | Value |
|---|---|
| Metered generation | 12,000 MWh |
| P50 for the month | 14,000 MWh |
| Sold on PPAs | 240 MWh at 65.0 c/kWh |
| Market and certificates | R 0 |
| Baseline (unsold and below P50) | 66.5 c/kWh (70.0 × 0.95) |
| HAF this month vs best | no decline |
| SO instructions, bids, shortfall, banking facts | none |
Energy conservation (two different piles — do not mix them):
- Made versus expected:
12,000 + 2,000 = 14,000= P50 ✓ - Made versus sold:
240 + 11,760 = 12,000= Generated ✓
Rand on the ledger:
- Unsold, never offered =
11,760 × 66.5 × 10 = R 7,820,400(11.8 GWh on the small line). - Below P50 generation =
2,000 × 66.5 × 10 = R 1,330,000(2,000 MWh). - Availability slide = R 0 — no decline from the best month.
- Curtailment unrecovered = R 0 — no SO instructions received.
- Imbalance, uninstructed = R 0 — no market schedules to deviate from.
- Shortfall penalties = R 0 — 1 PPA · no shortfall clause triggered (or however many contracts the book holds).
- Banking expired · escalation drift = R 0 — watch if the PPA is fixed with no escalation.
The share bar: Unsold, never offered fills the track
(largest). Below P50 is
1,330,000 ÷ 7,820,400 ≈ 17 % of that track. Zeros have no
bar.
Do not add 7,820,400 + 1,330,000 into
Net. Net is still 156,000 − 5,760,000 = −R 5,604,000 —
Earned minus cost of generation. The leftover is the other question.
| Kind | Baseline (short) | MWh | Rand |
|---|---|---|---|
| Unsold, never offered | SAWEM P50 − 5 % | 11,760 | R 7,820,400 |
| Below P50 generation | weather + availability | 2,000 | R 1,330,000 |
| Availability slide | HAF vs best month | — | R 0 |
| Curtailment unrecovered | SO instructions | — | R 0 |
| Imbalance, uninstructed | market schedules | — | R 0 |
| Shortfall penalties | PPA ledger | — | R 0 |
| Banking expired · escalation drift | spill and price clauses | — | R 0 |
| Do not Σ these Rand into Net — they are seven questions | not a total | ||
The lifetime ledger is these months added together. On a thinly sold two-year plant the top row is the large never-offered figure in the headline. Operations zeros on that plant are the proof the loss is commercial.
This is the pattern to expect on your own page: one tall amber row, a smaller slate Below P50, and a run of honest zeros. Chapter 6 prices Bid the gap from the same baseline as row one, so the page’s leftover and its advice add up to the same number.
Where this is taught. The next-chapter moves that reuse these baselines: §12.8. The Sales desk Option 0 (hold and bid the gap): §6. Overview’s revenue-gap hero (latest run, not this lifetime book): §4.1.
12.6 Chapter 5 — health check
Six vital signs, each with its two-year sparkline and a status stripe (green · amber · red):
| Vital sign | Value | Turns amber / red when |
|---|---|---|
| Availability · HAF | latest HAF, was N | drop from the best month ≥ 0.02 / ≥ 0.08 |
| Contracted · latest plan (or Contracted · this month when there is no plan) | share of plant sold; note reference 85 % · 3 PPAs | < 70 % / < 30 % |
| Realised price · latest plan (or Realised price · lifetime) | c/kWh on all generation (3.5 c / kWh); note LCOE 48.0 c · achieved on sold 85.0 c | below LCOE × 1.2 / below LCOE |
| Buyer concentration · latest plan (or Buyer concentration) | revenue HHI; note lifetime 0.33 · top PPA is 33 % of revenue · target < 0.5 | ≥ 0.5 / ≥ 0.7 |
| Market readiness | registration status and bid count | active with no bids / not registered |
| Operations | curtailment · penalties · disputes | any non-zero |
Each commercial tile’s label states its basis. · latest plan means the figure is the book’s latest forecast snapshot; without one, Contracted falls back to this month’s metered split and Realised price to the lifetime figure. The notes count PPAs, not buyers, because each row of the sources ledger is a physical PPA and one buyer can hold several. Buyer concentration can differ between plan and lifetime, so its note leads with the lifetime HHI: the seeded IPP1 Sandton Solar shows 0.85 from its plan beside lifetime 0.33 — the same HHI 0.33 as Chapter 3’s Total earned row.
Under the vitals a one-line Last quarter summary — availability moved, the market route opened, certificates were issued, revenue averaged — and, folded, the Availability detail (§12.7).
12.6.1 When this site has a battery
Think of the battery’s warranty booklet sitting next to the plant’s service log. Chapter 5 is already asking can this plant deliver what the next sale assumes? If this generator site has a battery — a Bess asset on this site, not a neighbour — that booklet belongs in the same chapter. It is not a seventh chapter, and it is not a green strip above the story.
The page then adds a seventh vital Battery ·
contract (#ipp-story-vitals [data-key=battery]).
The number is cycles in the trailing 365 days when settled battery
months exist; otherwise it reads —. The stripe is
green, amber or red against the owner’s limits, or slate when there is
no settled month yet.
Below the vitals, #ipp-story-battery is the same white
chapter card as the rest of the health column. It prints three numbers
for the trailing year:
| Label on the card | What it is | Empty |
|---|---|---|
| Cycles to date | How many times the pack has been emptied, in energy terms | No settled month yet |
| Round-trip efficiency | How much of the energy you put in comes back out (η_rt) | No settled month yet |
| Availability | Hours the battery was not on an operator outage, as a share of the year | No settled month yet |
Under those numbers sits state of health (the dated
capacity test on the register, or nameplate assumed if none is
recorded) and Open battery contract. That link is the
only Dashboard path into the owner register
(/org/generator-sites/:id/strategy/battery). Wear, pack
replacement cost, capacity evidence and contracted reserves live there —
§20.
A site without a Bess asset does not show the vital, the card, or any battery sentence. Wind and solar sites on this seat stay silent. The green Battery contract banner that used to sit above the six chapters is gone.
The chapter title also watches the battery stripe: The battery contract is the other machine to watch when that vital is amber or red, and it keeps the commercial sentence when the book is unhealthy too.
- Open this site’s Dashboard.
- If this site has no Bess asset, Chapter 5 keeps six vitals.
- If it has one, Chapter 5 adds the seventh vital and the battery card.
- Open battery contract opens the owner register: wear, health, reserves.
- Chapter 6 still ranks three sales moves. The battery is not a fourth move (§12.8).
The chapter title is written from the stripes: Healthy machine, unhealthy business — and the machine is starting to slip when the commercial signs are red and availability is amber.
Under the vitals sits Operating evidence
(#ipp-operating-evidence): past availability, Plant
now, then Forecast evidence. The third column
is the next 144 hours (#ipp-forecast-evidence). Weekly
Forecast skill, Compare providers, and
Grid Code forecast packs sit in a fold under that strip
(#ipp-forecast-evidence-quality). Click the summary
Forecast evidence — skill, providers, Grid Code packs
to open it; it starts closed, the same chrome as Availability detail.
They are not on Allocation → Forecast (§8.1.10 is the bridge).
| Card on screen | Id | What it answers | Empty or honesty |
|---|---|---|---|
| Forecast skill | #forecast-skill-panel |
How wrong weekly weather models have been vs meters. Sticky column
labels; six rows visible, the rest scroll
(#forecast-skill-scroll) |
No scorecard yet… (#forecast-skill-empty) |
| Compare providers | #provider-comparison |
Which source has history for the latest week | tiles still render; no history |
| Grid Code forecast packs | #so-pack-panel |
What was filed for the System Operator. Six rows visible, the rest
scroll (#so-pack-scroll) |
No packs built yet. (#so-pack-empty) |
Do not rewrite next month’s commercial carve from one week’s nMAE.
XML download still uses
/strategy/forecast/so-pack/<id>.xml even though the
list is on Dashboard. Deep teaching: §17.8 and §17.9.
12.7 Availability detail (folded)
Under the health-chapter fold sits Availability (HAF): the gauge, factor breakdown, 12-month trend, month × tier reliability matrix, and the shortfall / spill log. The sub-sections below teach each panel.
Section heading on screen: Availability (HAF)
(data-role="haf-dashboard").
Section intro (#ipp-haf-section-intro):
Scoreboard: gauge, band, and GAF/SF/ARF. Trend, tier fulfilment, and
shortfall/spill sit below.
This is the reliability half of the Dashboard — a scoreboard, not the capacity screen. Full SCE / tier / factor maths live on the HAF tab (§5); this section is the field guide for the Dashboard layout. Bridge summary also in §5.8.
Scoreboard and always-on detail
| Layer | What is visible |
|---|---|
Scoreboard
(data-role="haf-scoreboard") |
HAF gauge panel + Factor breakdown (GAF / SF / ARF) |
Detail (#ipp-haf-detail,
data-role="haf-detail") |
12-month HAF trend · allocation reliability matrix · shortfall & spill log — always visible below the scoreboard |
Why this block is kept
What we are ascertaining. "Can this plant honestly stand behind the energy it is already selling — and is reliability drifting?"
Why before Revenue. A high Achieved price on a LOW-band plant is a trap: you are selling paper that history says you will not fully deliver. Fix reliability (or stop growing the book) before chasing more Sales volume.
Where the numbers come from
Source.
WB.Wheeling.Forecast.Dashboard.assemble/1 over persisted
monthly forecasts for this generator: latest FINAL forecast, 12-month
HAF trend, month × tier fulfilment matrix, shortfall/spill log.
Not computed in the view. The LiveView only renders stored fields — no new GAF/SF/ARF maths on the Dashboard.
12.7.1 HAF gauge panel
On-screen: no duplicate card
title — the section heading Availability (HAF) already
names the block. Panel data-role="haf-gauge-panel" carries
only the intro + dial + chip.
Panel intro (#ipp-haf-gauge-intro):
Current HAF and band — how bankable your surplus looks to a
buyer.
| Element | What it is |
|---|---|
| Dial | #haf-dash-gauge — 0–100% gauge of
PRO_RATA HAF (haf_pro_rata × 100) |
| Band chip | Colour badge beside the dial: High · Bankable /
Good · Reliable / Moderate · Caution /
Low · Not bankable |
| Empty copy | No HAF yet — needs at least three months of operating history. |
How to read the dial. The needle (and centre detail) show the PRO_RATA HAF as a percent. This dashboard gauge is a simple progress dial (sky-blue fill) — the band-coloured arc lives on the HAF-tab capacity widget, not here. Trust the chip for the band name.
Band thresholds (same palette as §5.1):
| Band | HAF range | Colour | Plain reading |
|---|---|---|---|
| High | ≥ 0.85 (≥ 85%) | Emerald | Bankable — contract with confidence |
| Good | 0.70 – 0.85 | Lime | Reliable — minor discount |
| Moderate | 0.50 – 0.70 | Amber | Caution — meaningful shortfall risk |
| Low | < 0.50 | Red | Not bankable — do not grow the book |
| No data | < 3 months history | Slate | Grey empty state on this panel |
Step-by-step example. Dial shows 56.3%, chip Moderate · Caution:
- Read: a bit over half of paper availability is bankable for a pro-rata seat.
- On Moderate — check factor bars (§12.7.2) and the matrix / log below.
- Before promoting a large Sales deal, open the capacity widget on Sales and read SCE for the actual tier you would sell (§5).
12.7.2 Factor breakdown
On-screen title: Factor
breakdown · data-role="factor-bars"
Panel intro (#ipp-haf-factors-intro):
GAF, SF, and ARF — the evidence discounts that multiply into
HAF.
Three horizontal bars (amber fill #059669 on a slate
track), each with the factor abbreviation and a two-decimal value:
| Bar | Full name | Asks |
|---|---|---|
| GAF | Generation Availability Factor | Did the plant make what it should? |
| SF | Stability Factor | Was output steady, or volatile / curtailed? |
| ARF | Allocation Reliability Factor | Did buyers actually get what they were owed? |
Why CSF is missing here. CSF (Contract Sensitivity Factor) depends on the prospective tier (PRIORITY 1.00 / FIXED 0.90 / PRO_RATA 0.80). The Dashboard always shows the portfolio factors; pick a tier on the HAF tab to see CSF in the decomposition line.
How to react.
| Pattern | Meaning | Next step |
|---|---|---|
| Short GAF | Book / forecast availability weak | Forecast FG / obligations (§8); stop overselling |
| Short SF | Volatility or curtailment | Check shortfall/spill log; ops / curtailment history |
| Short ARF | Delivery under hierarchy weak | Hierarchy + Allocations — FIXED often eats the pain (§7, §9) |
| All high, band still MODERATE | Product of factors (× CSF in the capacity widget) still middling | Do not grow PRO_RATA volume blindly |
12.7.3 HAF trend (12 months)
Lives in reliability detail
(#ipp-haf-detail) — always visible below the
scoreboard.
On-screen title: HAF trend (12 months) ·
chart id #haf-trend
Panel intro (#ipp-haf-trend-intro):
Twelve months of HAF — watch for a weak month entering the
window.
| Chart detail | Value |
|---|---|
| Series | One line: HAF (PRO_RATA × 100) |
| Colour | Palette index 0 — amber #059669 |
| X axis | Month labels (Jan. '26 style via
Format.axis_month) |
| Y axis | HAF % with % unit suffix |
| Empty | No trend yet. |
How to read. A dip when a bad / curtailed month enters the trailing window is the classic signal — the band can fall GOOD → MODERATE without any new contract signed. A rising line after a bad month exits the window is the recovery story.
Stable GOOD band
Represents: reliability holding. React: safe to keep selling within SCE; still watch ARF on the matrix.
Curtailed month enters the window
Represents: a weak month pulled the trailing HAF down. React: open factor bars + shortfall log; pause new volume until the band recovers or SCE shrinks honestly.
12.7.4 Allocation reliability matrix
Lives in reliability detail
(#ipp-haf-detail) — always visible below the
scoreboard.
On-screen title: Allocation reliability
(fulfilment %) · chart id #haf-reliability
Panel intro
(#ipp-haf-reliability-intro): Fulfilment % by month and
tier — whether Priority, Pro-rata, and Fixed buyers got what was
promised.
A heatmap: months across the X axis, tiers on the Y axis (PRIORITY · PRO_RATA · FIXED), cell colour = average fulfilment % for that tier that month.
| Chart detail | Value |
|---|---|
| Scale | 0 – 100 (fulfilment %) |
| Colours | Red #dc2626 → amber #fde68a → green
#16a34a (low → high) |
| Empty | No allocation history yet. |
Why it matters. This is the waterfall's habit made visible. On a tight book the FIXED row often ambers or reds while PRIORITY stays green — Fixed is the shock absorber by design (§7).
Step-by-step example.
- Scan the PRIORITY row — mostly green means anchors were made whole.
- Scan FIXED — repeated red cells mean interruptible buyers ate every short hour.
- If you are about to sell a FIXED block, this matrix is your honesty check: history says that seat under-delivers on this book.
12.7.5 Shortfall & spill log
Lives in reliability detail
(#ipp-haf-detail) — always visible below the
scoreboard.
On-screen title: Shortfall & spill log
· data-role="shortfall-spill-log"
Panel intro (#ipp-haf-shortfall-intro):
Months you were oversubscribed (shortfall) or had saleable leftover
(spill).
| Column | Meaning |
|---|---|
| Month | Forecast month label (YYYY-MM) |
| Subscription balance | SB (FG − ED). Negative renders red and tagged shortfall |
| Saleable (AES) | Unallocated forecast energy (P50) |
| Tag | shortfall when SB < 0, else spill |
Only notable months appear: SB < 0 or AES > 0. Empty body: No shortfall or spill months.
How to react.
| Row pattern | Meaning | Next step |
|---|---|---|
| Red SB, low AES | Oversubscribed — stop selling | Forecast AES verdict (§8.1.6) |
| Positive SB, AES > 0 tagged spill | Headroom / saleable surplus | Sales for that shape; check HAF band first |
| Alternating shortfall / spill | Book oscillating around knife-edge | Tighten hierarchy + sales discipline |
12.8 Chapter 6 — the next chapter
Chapter 4 priced the leftover on the shelf. Chapter 5 asked whether the machine can still bake. Chapter 6 is the three jobs for next quarter: sell the leftover at the street market this afternoon, find regular shops that want that shape of loaf, or fix the oven so you do not bake less next year. The page ranks those jobs by what each is worth a year. It does not sign a deal and it does not place a bid.
The leftover is forgone / never offered —
energy nobody was offered, valued at the same SAWEM day-ahead baseline as the loss
ledger. The three cards are the next chapter
(#ipp-story-next). They reuse that baseline so the page’s
losses and its advice add up to the same number.
Follow along. Seat:
ipp_2@webill.net(organisation door; passwordsupersecreton the demo). Path: Generator sites → IPP2 Atlantis Wind → Strategy → Dashboard, then scroll to Chapter 6 · the next chapter (#ipp-story-next). You should see a left-hand tell, three numbered cards (#ipp-story-actions), and — until settlement has run — a housekeeping line about estimated months. Atlantis Wind has no battery, so the tell does not mention one. On the demo the availability card usually opens with Restore telemetry, because Plant now is stale (§12.8.7).Data. Method check against the same one-month arithmetic as §12.1 and §12.5.8, then annualised the way the page does it (last twelve months, scaled to a year). LCOE 48 c/kWh. Market P50 70.0 c/kWh, less 5 % imbalance allowance → 66.5 c/kWh. One 1.0 MW as-generated PPA at 65.0 c/kWh on a 50 MW plant.
The left column (lg:col-span-3) is the eyebrow
Chapter 6 · the next chapter and a fixed title:
Three moves, ranked by annual value and qualified by the evidence above.
That title does not rewrite itself from the numbers. There is no green So what box on this chapter.
The tell is one paragraph, always: each move is priced from the same baselines as the loss ledger; the operating evidence in Chapter 5 says how confidently you can act today; each card links to the screen where the work is done. A second paragraph appears only when this site has a battery (§12.8.9).
The right column is one white chapter card. Inside it, three move
tiles (#ipp-story-actions), then the housekeeping line when
any month is still estimated.
Where this is taught. The leftover these moves price: §12.5. The Sales Desk the first two cards open: §6. Availability maths: §5. Plant now and the register behind Open plant: §11. Fleet chapter 04 / The next chapter is the cousin at fleet scale, not these three priced jobs: §2.5. The Money Room fact base: V16. The baseline price forecast: V10.
12.8.1 Finding Chapter 6
| Cue | What it is |
|---|---|
| Seat | ipp_2@webill.net (organisation door; password
supersecret on the demo) |
| Menu | Generator sites → IPP2 Atlantis Wind → Strategy → Dashboard |
| Route | /org/generator-sites/:id/strategy/dashboard |
| Chapter | #ipp-story-next — eyebrow Chapter 6 · the next
chapter |
| Cards | #ipp-story-actions — three tiles,
data-role="next-action" and data-key |
| Housekeeping | The slate line under the cards, only when estimated months remain |
| Battery sentence | Second left-hand paragraph, only when this site has a Bess asset |
Empty: the three cards never disappear. A brand-new site with no meter still shows three moves. The worth lines may say no price forecast to value it, no price guidance yet, or nothing to recover yet. That is honest, not a missing chapter.
Chapter 6 does not carry Annual curtailment
exposure. That card sits in Chapter 4
(#ipp-curtailment-exposure).
12.8.2 Every word on a move card
Each tile is data-role="next-action".
data-key is the platform name. Use it when you talk to
support or when a test looks for a card.
data-key |
Title you usually see | The other title |
|---|---|---|
bid |
Bid the gap into the day-ahead market | Register as a BRP and bid the gap day-ahead when the organisation is not an active BRP |
buyers |
Sign daytime buyers for the unsold shape | (one title) |
availability |
Arrest the availability slide when HAF has dropped 0.01 or more from its best month | Hold availability where it is when it has not. Stale Plant now rewrites this title — §12.8.7 |
The numbered circles 1 · 2 · 3 are rank, not a fixed
order of kinds. The page sorts the three cards by stored
worth, largest first. Card 1 gets the
green wash (border-brand-line bg-brand-wash) and a green
circle. Cards 2 and 3 stay white with
a slate circle. Read data-key if you need the kind; do not
assume bid is always on the left.
Every card prints the same four lines, top to bottom:
| Line | What you see | What it is |
|---|---|---|
| Number | 1, 2 or 3 in a 22-pixel circle | Rank this visit |
| Title | Bold 13-pixel heading | The job |
| Worth | Large green grouped Rand, or a refusal sentence | What the job is worth a year — read the unit |
| Body | Slate paragraph | Who can do it, and the energy or HAF points behind the Rand |
| Go | Green link ending → | The screen where the work is done |
Worth lines the page actually writes:
| When | Words on the green line |
|---|---|
| Bid, price forecast present | ≈ R 93,844,800 / yr (grouped Rand, no m /
k) |
| Bid, no daytime P50 | no price forecast to value it |
| Buyers, a price to compare | ≈ R 1,000 / yr per MW, or with the sign before the
currency when it is negative: ≈ −R 43,200 / yr per MW |
| Buyers, no achieved price and no LCOE fallback | no price guidance yet |
| Availability, drop ≥ 0.01 and a price forecast | ≈ R 8,937,600 / yr |
| Availability, no drop (or no price) | nothing to recover yet |
Read the unit before you treat #1 as the biggest pile of money. Bid and availability are year totals for the leftover or the slide. Buyers is per contracted megawatt. The rank compares those stored numbers as if they were the same unit. The green line is where the unit is printed. A buyers card can sit at #3 with a minus while bid sits at #1 with tens of millions — that is the page saying a new contract at today’s achieved price would lose to the market.
12.8.3 How a move gets its Rand
Think of the bakery again. The leftover loaves on the shelf are one pile. The premium a regular shop would pay above the street price is a different pile, counted per shop-front. The loaves you will fail to bake if the oven slips are a third pile. Do not add the three green lines and expect the sum to match Net or the loss-ledger total.
The street price is the same baseline as Chapter 4:
SAWEM day-ahead P50 for 08h–15h, less a 5 % imbalance allowance.
The page stores the raw daytime P50 (on the method check, 70.0 c/kWh) and applies the haircut when it turns a kilowatt-hour into Rand:
R per MWh = P50 c/kWh × 10 × 0.95
That is R 665 / MWh when P50 is 70.0 c. Writing it
as 66.5 c/kWh × 10 is the same number. One month of
leftover on the method check is still
11,760 × 66.5 × 10 = R 7,820,400.
The page then looks at the last twelve story months
(or fewer, if the plant is younger) and scales them to a year:
scale = 12 ÷ how many of those months exist. Three months
of history are multiplied by four. No months means every year-figure is
zero.
| Move | Formula (plain words) | Unit on the card |
|---|---|---|
| Bid | Last-twelve unsold megawatt-hours × scale × R 665 / MWh | / yr for the whole leftover |
| Buyers | (achieved c − P50 c × 0.95) × 10 × (year generation ÷ export MW) | / yr per MW |
| Availability | (best HAF − latest HAF) × site P50 MWh/year × R 665 / MWh | / yr for the slide |
Achieved is, in order: the book’s latest snapshot
EFFECTIVE_PRICE_CKWH; else the average contract price on
this site; else LCOE + 12 c when LCOE is
set. If none of those exist, the buyers card refuses with no price
guidance yet.
If the price forecast is missing, bid prints no price forecast to value it and the commercial leftover on Chapter 4 is R 0 in the same case. The page will not invent a street price.
If achieved exists but the forecast does not, buyers uses
achieved × 10 × MWh per MW with no market subtraction — a
cruder year-per-MW figure, and the body says on today’s unsold
hours instead of above what the market would pay.
Conservation against Chapter 4: one month’s Unsold, never
offered × 12 = the bid year-figure on this method check
(7,820,400 × 12 = R 93,844,800). That is the pattern to
expect on your own page when the leftover is the same every month.
12.8.4 Bid the gap — or register as a BRP
data-key="bid". This is the street-market job: offer the
leftover into the DAM (Day-Ahead
Market) yourself. It needs no counterparty and no term. It also
needs a BRP registration, or the market
door stays shut.
| Piece | What it is |
|---|---|
| Title, registered | Bid the gap into the day-ahead market — organisation
registration status is :ACTIVE |
| Title, not registered | Register as a BRP and bid the gap day-ahead |
| Body, registered, no bids | You are BRP-registered and have never bid. Then the unsold megawatts. |
| Body, registered, bids placed, none settled yet | You are BRP-registered and have placed 5 bids; none has settled yet. The bids are counted, not inferred from market revenue |
| Body, registered, bids placed and settled | You are BRP-registered and have placed 5 bids. |
| Body, not registered | The market route is closed until the organisation registers. |
| Energy line | {N.N} MW of unsold energy at the SAWEM P50, less imbalance. Needs no counterparty. |
| Go | Sales → Option 0 · hold and sell on SAWEM → |
Unsold megawatts are the leftover’s share of the plant:
unsold MW = export MW × (year unsold MWh ÷ year generated MWh)
On the method check that is
50 × 141,120 ÷ 144,000 = 49.0 MW. Almost the whole machine
is still on the shelf.
The go link opens this site’s Sales desk
(/org/generator-sites/:id/strategy/sales). It does not
place a bid. Option 0 · hold
and sell on SAWEM is the desk’s hold card: the P50 value of
the gap, with P10 and P90 around it. Chapter 6’s green line is the
Dashboard’s year-total cousin of that card, from the last twelve story
months, not the desk’s hourly gap chart.
Where this is taught. How to read Option 0, P10 / P50 / P90, and why holding still has risk: §6.3 and §6.4. How an organisation registers as a BRP: V10 §5 and V9 §3.
What “done” looks like on this card: you can say whether the door is open, how many megawatts sit unsold, and you have opened Option 0. You have not treated the green line as cash in the bank.
12.8.5 Sign daytime buyers
data-key="buyers". This is the regular-shop job: find
someone whose daytime load fits the leftover hours, and price the
megawatt against the street market.
| Piece | What it is |
|---|---|
| Title | Sign daytime buyers for the unsold shape |
| Worth | ≈ R {N} / yr per MW, or no price guidance
yet |
| Body, priced | At {N.N} c, each as-generated megawatt earns about R {N} a year above what the market would pay for the same hours. The Sales desk ranks who fits the shape. When the premium is negative the sentence turns round: …earns about R {N} a year less than the market would pay for the same hours. |
| Body, no market P50 | The same sentence, ending on today’s unsold hours instead of above what the market would pay |
| Body, no price at all | Set an LCOE and price card on the book to value each contracted megawatt. |
| Go | Sales → Who could absorb the gap → |
The premium is:
(achieved c − P50 c × 0.95) × 10 × (year generation MWh ÷ export MW)
On the method check, achieved is 65.0 c (the one PPA), export is 50 MW, year generation is 144,000 MWh, so MWh per MW is 2,880. Then:
R1: 70.0 × 0.95 = 66.5
R2: 65.0 − 66.5 = −1.5
R3: −1.5 × 10 × 2,880 = −R 43,200 / yr per MW
A minus is the page saying: a new as-generated megawatt at today’s
achieved price earns less than Option 0. The card
prints it as ≈ −R 43,200 / yr per MW, and the body says so
in words: At 65.0 c, each as-generated megawatt earns about R 43,200
a year less than the market would pay for the same hours. Chapter 3
already said 65.0 c clears LCOE but trails the market; the next
contract should not. This card puts a year-figure on that warning.
It will rank below a zero availability card.
The go link is the same Sales desk as bid, scrolled in your reading to Who could absorb the gap — off-takers and traders ranked by fit to the unsold shape. Chapter 6 does not pick a buyer and does not open a proposal.
Where this is taught. Fit, absorbs, and the candidate list: §6.4 step 2. The sources tape that produced 65.0 c: §12.4.9. The heat strip that shows when the leftover sits: §12.5.5.
What “done” looks like: you have read the unit (per MW), you know whether the premium is above or below the market, and you have opened the candidate list. You have not added this green line to the bid year-total.
12.8.6 Arrest or hold availability
data-key="availability". This is the oven job. It is not
a sale. It asks whether HAF has
slipped from its best recorded month, and what that slip is worth at P50
and the same baseline.
A drop is best HAF − latest HAF. The page treats a drop
under 0.01 as nothing to recover.
| When | Title | Worth | Body |
|---|---|---|---|
| Drop ≥ 0.01 and a price forecast | Arrest the availability slide | ≈ R {N} / yr |
{N} HAF points is {N.N} GWh a year at P50. Cheap to fix now; far more valuable once the plant is sold. |
| Drop < 0.01 | Hold availability where it is | nothing to recover yet | Availability is at its best recorded level. Every sale you make raises the price of a future slip. |
| Drop ≥ 0.01, no price forecast | Arrest the availability slide | nothing to recover yet | The GWh sentence still prints; the Rand cannot |
HAF points on the body are round(drop × 100) — an 0.08
drop prints 8 HAF points. Gigawatt-hours are
drop × site P50 MWh/year ÷ 1,000. The Rand is
drop × site P50 MWh/year × R 665 / MWh.
On a 168,000 MWh/year P50 (the 14,000 MWh method-check month × 12) and an 0.08 slide:
R1: 0.08 × 168,000 = 13,440 MWh = 13.4 GWh
R2: 13,440 × 665 = R 8,937,600 / yr
That is the cousin of Chapter 4’s Availability slide row, priced as a year of P50 at today’s drop, not as the lifetime sum of every month below the peak. The lifetime row can be larger. Do not expect the two Rand figures to match.
The go label says Allocation → Forecast · availability
factors →. The click opens Allocation →
Outcomes
(/org/generator-sites/:id/strategy/allocations), not the
Forecast sub-tab (/strategy/forecast). HAF factors also sit
on this Dashboard under Availability detail (§12.7) and on the HAF tab (§5). Read the label as “go work on availability”; land
where the link actually takes you.
When Plant now is stale, this card’s title and body change before you rank it (§12.8.7).
Where this is taught. Factor bars, the 12-month HAF trend, and the band chip: §12.7. The lifetime slide row: §12.5.4. Forecast FG and availability factors: §8.
12.8.7 When telemetry is stale
Chapter 5’s operating strip asks can the plant deliver what the next move assumes? Chapter 6 listens.
Fresh Plant now means at least one feed is not stale
and has a megawatt reading now
(available_mw_now). If that is missing, the page leaves bid
and buyers alone and rewrites only the availability card:
| Line | After the rewrite |
|---|---|
| Title | Restore telemetry, then arrest the HAF slide — even when there is no slide to arrest |
| Body | Restore a fresh device signal first. then the ordinary hold or arrest paragraph |
| Worth | Unchanged — still nothing to recover yet when the drop is under 0.01 |
On the demo, Atlantis Wind usually shows this rewrite. The test looks
for Restore telemetry on
#ipp-story-actions [data-role='next-action'][data-key='availability'].
Open plant is not a fourth move and it is not on
Chapter 6. It lives on Chapter 5’s Plant now strip
(#plant-open-{site id}). Click it. You leave Dashboard and
open the Plant tab (/strategy/plant).
Bookmarks that still carry ?plant=1 on the Dashboard URL
redirect to that tab.
| Cue | What it is |
|---|---|
| Open | #plant-open-{site id} on Plant now —
label Open plant with an arrow-up-right icon |
| Destination | The Plant tab — #ipp-plant, heading
Your plant live |
| Also | The same tab on the strategy bar, between Curtailment and Dashboard |
There is no #ipp-plant-drawer. The compact glance stays
on Chapter 5; the register, samples, consent and traces are the Plant
tab. Deep teaching of feeds, consent, samples and traces stays on §11. This section only records the
Dashboard click: Chapter 5 opens the Plant tab; Chapter 6 changes one
card until a feed is fresh.
What “done” looks like: Plant now shows a Fresh feed, the availability card drops the Restore telemetry title, and you know whether you are holding HAF or arresting a slide.
Where this is taught. The past → now → next strip: §12.6. Feeds, consent, and what a stale reading may not decide: §11.
12.8.8 Housekeeping — run settlement
Under the three cards, when any story month is still estimated, a slate line reads:
And one housekeeping move: run settlement for the contracted months so this story moves from {N} % estimated to settled-grade.
{N} is grade_share.estimated_pct, rounded.
On a site whose Money Room has no facts yet it is 100.
The line hides when every month is settled or invoiced.
This is not a fourth ranked card. It has no data-key, no
green worth, and no go link. It is the same confidence story as
How sure is this story on the verdict (§12.1.5): estimated months are rebuilt from
meters and contracts; settled months come from the Money Room.
Running settlement is an operations job, not a Chapter 6 click.
Where this is taught. Grades on the verdict bar: §12.1.5. Settlement statuses and a re-run: V8 §11.
12.8.9 When this site has a battery
Follow along (battery): same seat, Generator sites → Rosslyn BESS → Strategy → Dashboard → Chapter 6.
The left-hand tell adds one paragraph:
The battery does not rank here as a fourth sales move. Its constraint is already in Chapter 5: if cycles, efficiency or availability are against the contract, fix that register before you sell more of the gap it is meant to store.
There is still no fourth tile. #ipp-story-actions still
has three data-role="next-action" cards. The battery vital
and Open battery contract stay in Chapter 5 (§12.6.1). Atlantis Wind, and any site
without a Bess asset, stays
silent.
Where this is taught. The seventh vital and the battery card: §12.6.1. Wear, health, and reserves: §20.
12.8.10 Edges, empties, and refusals
| Edge | What you see | What you do |
|---|---|---|
| No generation yet | Three cards; bid worth near zero or no price forecast | Wait for the meter. Do not invent a leftover |
| Generation, no sales, price present | Bid is usually #1, large / yr |
Open Option 0. Check the heat strip for the shape |
| Generation, no price forecast | Bid no price forecast to value it; Chapter 4 commercial rows R 0 | The leftover is still real. Restore the DAM forecast |
| Achieved below the haircut market | Buyers prints a minus / yr per MW and ranks last |
Do not sign another megawatt at today’s achieved price |
| No LCOE and no contracts | Buyers no price guidance yet | Set lcoe_ckwh on the book (§4.3) |
| HAF at its best | Availability nothing to recover yet / Hold availability where it is | Sell; know a future slip gets more expensive |
| HAF down ≥ 0.01 | Arrest the availability slide and a year Rand | Fix reliability before growing the book |
| Plant now stale | Availability title starts Restore telemetry | Open plant from Chapter 5; do not bid the next 144 hours on a dead feed |
| All months estimated | Housekeeping names 100 % (or near it) | Trust the shape, not the last rand of the green line |
| Bess asset on this site | Second tell paragraph; still three cards | Fix the battery register in Chapter 5 if that vital is amber or red |
| Adding the three green lines | A number that matches nothing on the spine | Stop. They are three questions, and buyers is per MW |
What “done” looks like on this chapter: you can name the #1 card and its unit, you have followed its go link, you know whether telemetry or settlement still limits confidence, and you have not treated the leftover as cash.
12.8.11 Worked year — three jobs from one leftover
Data. Same method check as §12.1 and §12.5.8. Twelve identical months so the year-figures are that month × 12. Not a sealed demo stamp — your Dashboard last-twelve window may be shorter or lumpier.
| Input | Value |
|---|---|
| Plant export | 50 MW |
| Metered generation (one month) | 12,000 MWh |
| Sold on PPAs | 240 MWh at 65.0 c/kWh |
| Unsold | 11,760 MWh |
| Site P50 (illustration) | 168,000 MWh / yr (14,000 × 12) |
| Market P50 | 70.0 c/kWh |
| Baseline | 66.5 c/kWh (70.0 × 0.95) → R 665 / MWh |
| HAF this month vs best | no decline (drop < 0.01) |
| Plant now | stale on the demo |
| Months in the window | 12 (scale = 1) |
Year energy:
- Generated =
12,000 × 12 = 144,000 MWh. - Unsold =
11,760 × 12 = 141,120 MWh. - Conservation:
240 × 12 + 141,120 = 144,000= Generated ✓ - Unsold megawatts =
50 × 141,120 ÷ 144,000 = 49.0 MW. - Megawatt-hours per export megawatt =
144,000 ÷ 50 = 2,880.
Rand on the cards:
- Bid =
141,120 × 66.5 × 10 = R 93,844,800 / yr. Check against Chapter 4:7,820,400 × 12 = R 93,844,800✓ - Buyers =
(65.0 − 66.5) × 10 × 2,880 = −R 43,200 / yr per MW, printed≈ −R 43,200 / yr per MW. - Availability = nothing to recover yet — drop under 0.01. Body: Availability is at its best recorded level… On the demo the title is Restore telemetry, then arrest the HAF slide, and the body starts Restore a fresh device signal first.
Rank this visit: 1 bid (green wash),
2 availability (worth 0 beats −43,200),
3 buyers. If HAF had dropped 0.08, availability would
print 0.08 × 168,000 × 665 = R 8,937,600 / yr and stay #2,
still behind the leftover.
| Rank | data-key | Title (demo-typical) | Worth |
|---|---|---|---|
| 1 | bid | Bid the gap / Register as a BRP… | R 93,844,800 / yr |
| 2 | availability | Restore telemetry, then arrest the HAF slide | nothing to recover yet |
| 3 | buyers | Sign daytime buyers for the unsold shape | ≈ −R 43,200 / yr per MW |
| Do not Σ these into Net or the loss ledger — buyers is per MW | not a total | ||
Housekeeping under the cards names the estimated share (often 100 % until settlement has run). A Bess site adds a tell sentence and still keeps three cards.
This is the pattern to expect on your own page: bid first on a thinly sold plant, availability as a hold or a restore, buyers last when today’s achieved price trails the market.
Where this is taught. The one-month leftover these year-figures come from: §12.5.8. Option 0 on the Sales desk: §6.
12.9 Reading the page in two minutes
| Look at | Ask | Good looks like |
|---|---|---|
| Verdict sentence | Is the plant making or losing money since it switched on? | Net positive, sold share high, forgone small (§12.1) |
| Generated / Earned / Cost of generation | What did we make, take in, and cost ourselves? | Generated near P50; Earned clearing LCOE; Cost is own LCOE × generation, not a bill (§12.1.1–§12.1.3) |
| Confidence bar | How much of this is settled? | Mostly green; hatched only for the current month (§12.1.5) |
| River of money | When did the loss change shape? | Amber shrinking as green grows (§12.2) |
| Waterfall | Which step is large enough to matter? | Never offered small relative to potential |
| Sources ledger | Who pays, at what price, how concentrated? | Several buyers above LCOE and market; HHI < 0.5 (§12.4) |
| Loss ledger | Which losses are real and which are zeros that prove good operation? | Operations zeros; commercial losses falling |
| Vitals | Which stripes are red? | Commercial signs green; availability stable; Battery · contract present only when this site has a battery |
| Next chapter | What is the top move worth? | A move you can act on this quarter |
Where this is taught. The Money Room fact base and the loss valuers: V16 · Analytics. The baseline price forecast: V10 · Org bidding. Availability maths: §5. The Sales desk the first two moves lead to: §6.
Next in the thread → V4 §13 · Contracting with the guard.
Explain the revenue gap
The shared margin bridge is the plan bridge card in Chapter 1, captioned Why the plan was missed when the month fell short. Open months stay unbridged; a plan chosen after the month began carries a low-confidence label; for an IPP the contract step can be positive when a fixed PPA protects revenue against a falling market.
Where this is taught. How to read the card on this Dashboard: §12.2.5. The conserved seven-step month: V16 §5.
13. Contracting with the guard
You can agree a volume that fits the paper forecast but exceeds the energy the plant can safely support. The contracting guard makes that risk visible in the PPA flow and refuses to let an unacknowledged exception become active. It does not negotiate the deal for you; it records a conscious commercial decision against reproducible forecast evidence.
Data. Illustrative guard scenarios based on the §5 December example: AES 1,500 MWh; PRO_RATA HAF 0.563; SCE 845 MWh · full_demo seed 42 · last checked 2026-07-18.
13.1 What the guard compares
In the wizard’s Capacity & Allocation step, choose the generator, intended tier, and proposed energy. The panel reads the current forecast version and applies the tier’s HAF:
SCE = min(AES × HAF_tier, remaining capacity headroom)
For a PRO_RATA proposal in the worked example,
1,500 × 0.563 = 844.5, displayed as 845
MWh. The comparison is always between the proposed contractual
volume and the SCE for the selected tier; changing the tier changes the
CSF, HAF, and therefore the warning threshold. The screen also shows the
forecast month and evidence version, so you do not mistake an old
forecast for an approval.
13.2 Three outcomes in the wizard
Using the §4.7 numbers (PRO_RATA SCE = 845 MWh):
| Proposed result | Wizard behaviour | Can the proposal progress? | What is recorded |
|---|---|---|---|
| At or below SCE | Shows the available headroom without an exception warning | Yes | Forecast and capacity context on the proposal |
| Above SCE, acknowledgement ticked | Shows the amount above SCE and requires an explicit acknowledgement | Yes | Acknowledgement, actor, time, selected tier, and evidence snapshot |
| Above SCE, acknowledgement not ticked | Keeps the exception unresolved | It may be drafted, but it cannot activate | The validation reason remains visible |
| No HAF history | Shows the explicit no-data state rather than inventing a score | Yes, subject to normal contract checks | Contract-based ceiling and no-data caveat |
Within-SCE contracts, and sellers with no HAF history yet, are never warned as an oversubscription exception. The acknowledgement is stored on the contract itself, so a later audit can see exactly who accepted the risk and against which forecast. The same check runs again at activation: an over-SCE contract cannot become active until the acknowledgement exists.
13.3 Follow the exception through to activation
Follow along. Seat:
ipp_2@webill.net(passwordsupersecret). Path: Negotiations → New physical PPA → Capacity & Allocation; select IPP2 Atlantis Wind, then select a tier and enter a proposed monthly volume. You should see the capacity panel refresh before you submit the proposal.
- Read the selected forecast month, AES, HAF band, SCE, and remaining capacity headroom.
- Enter the proposed volume. If it is above SCE, read the difference rather than treating the amber warning as a technical failure.
- If commercial authority accepts that risk, tick the acknowledgement and continue. If it does not, reduce the volume, choose a different tier only when that matches the intended service, or wait for new forecast evidence.
- At activation, review the same capacity evidence again. A changed forecast can make a formerly comfortable proposal exceptional; the activation check protects against that stale decision.
Careful. An acknowledgement documents risk; it does not reserve generation, improve HAF, or change the hierarchy. Settlement still uses the hierarchy version effective in each hour.
13.4 Worked arithmetic — three proposals against one SCE
Data. Illustrative PRO_RATA SCE 845 MWh from AES 1,500 × HAF 0.563 (rounded). Same evidence version for all three rows.
| Proposal | Compare | Wizard path | Activation |
|---|---|---|---|
| 500 MWh | 500 ≤ 845 |
No exception warning | Normal |
| 1,200 MWh + ack | 1,200 − 845 = 355 over |
Checkbox + stored acknowledgement | Allowed |
| 1,200 MWh, no ack | same 355 over | Exception unresolved | Blocked |
Conservation of the commercial story: the SCE does not change when you acknowledge — only the audit trail does. Settlement still carves hours with the published hierarchy (§7), not with the SCE number.
13.5 Where the workflow belongs
The proposal, terms, counterparties, signatures, and normal activation path are taught in V7 · Deal Room. This chapter owns only the IPP capacity check that appears in that workflow. After activation, the physical PPA becomes eligible for the generator’s hierarchy; §7 explains the published allocation rule, and V8 · Settlement shows the resulting allocations. Forecast schedules that refresh SCE: §14. After the plant is running, metered export versus the same connection-agreement limit is §16 · Runtime MEC enforcement.
13.6 The measured-availability warning
An enabled proposed guarantee above trailing measured availability adds a warning to proposal review. For example, proposing 96% against 91.5% measured requires acknowledgement; proposing 90% does not. This is a warning, not an impossible-contract finding: acknowledge it deliberately to send. The measurement reflects contractual excuses and observed hours. It does not replace HAF or alter its factors.
14. Running it — schedules, backfills, alerts
You need fresh evidence before you sell the next month, but you also need late meter data to correct the record. The runners separate those jobs: a regular forecast creates a versioned commercial view, while settlement and controlled re-runs preserve the evidence trail behind it.
Data. Operational schedule · full_demo seed 42 exercises the same runners · time labels are SAST unless an environment’s scheduler configuration states otherwise · last checked 2026-07-18.
14.1 What runs when
- 5th · 04:00 MonthlyForecastRunner creates the next-month version
- Nightly Strategy refresh evaluates changed operational evidence
| Cadence | Runner or entry point | Work written | What you should check |
|---|---|---|---|
| Usual settlement cadence | Settlement pipeline | Metered allocations and completeness evidence | Provisional flags and conservation before relying on history |
| Nightly | Strategy refresh | Updated strategy-side evidence from new operational data | Whether a material change needs commercial attention |
| 5th of every month, 04:00 | MonthlyForecastRunner |
FG → CO → AES → HAF → SCE as a new forecast version | Verdict, subscription balance, HAF band, and any alerts |
| On authorised request | run_for/2 |
A superseding forecast version for a selected IPP/month | Why the prior version changed; never assume it was overwritten |
The forecast runner fans out one job per active IPP and de-duplicates concurrent work for the same generator and month. It uses the same waterfall as settlement, but on forecast generation. A run before the required meter completeness is reached is PROVISIONAL; a subsequent run becomes FINAL once the evidence qualifies.
14.2 Backfills and controlled re-runs
A fresh seeded environment runs the forecast schedule over its seeded history and current month, so forecast and HAF records are present without hand-editing. In an operating environment, backfill only the requested interval and retain the resulting versions:
mix wb.forecast_backfill --from YYYY-MM --to YYYY-MMUse it when historical forecasts are absent and you need a full HAF trend or MAPE history. It is not a substitute for repairing meters: missing meter evidence remains visible through completeness and provisional status.
For a hierarchy change under review, compare the allocation outcome rather than relying on a visual diff:
mix wb.replay_hierarchy_diff --generator ID --month YYYY-MMThe command re-settles the chosen month and prints the per-member change for sign-off. It does not retroactively rewrite the published settlement record; it gives you the evidence to decide whether an authorised re-run is appropriate.
14.3 Alerts and first response
Four conditions are emitted as telemetry for the IPP account team and operations:
| Alert | Trigger | What to do |
|---|---|---|
| Job failure | a forecast job fails after its retries | Ops: inspect and re-run
run_for/2 for the affected IPP/month. |
| Low completeness | meter completeness < 95% at final-run time | Chase the meter-data feed; the report stays PROVISIONAL until data lands. |
| Oversubscribed | SB < 0 for any IPP
(commercial alert, not an error) |
Freeze new sales; warn FIXED-tier off-takers of the expected fulfilment % (§7.3). |
| HAF band drop | band falls (e.g. GOOD → MODERATE) or HAF falls > 0.10 month-on-month | Open the dashboard: which factor moved — GAF (book too big), SF (volatility/curtailment) or ARF (delivery)? |
14.4 End-to-end month for the sell desk
| Day | What runs | What you do |
|---|---|---|
| Ongoing | Settlement pipeline | Watch Allocations for provisional hours |
| Nightly | Strategy refresh (V4/V8) | Check Overview if KPIs moved |
| 5th · 04:00 | MonthlyForecastRunner |
Open Forecast; read new version, verdict, SCE |
| Before sales calls | — | Confirm FINAL (or accept PROVISIONAL risk) |
| Hierarchy change | mix wb.replay_hierarchy_diff |
Compare members; decide authorised re-run |
| Missing history | mix wb.forecast_backfill |
Fill MAPE/HAF trend only — fix meters separately |
Follow along. Seat:
ipp_2@webill.net(passwordsupersecret). Path: Generator sites → IPP2 Atlantis Wind → Strategy → Forecast. Choose a report version and inspect its status badge, run time, and completeness before using its SCE in a sales discussion. Then open Dashboard and confirm which HAF factor moved if the band changed.
Where this is taught. Runner inventory and failure handling: V21 §3. Nightly book rhythm: V3 §18. Guard that consumes SCE: §13.
15. Reference card
Use this card when you need to explain a number on the IPP Strategy area without reopening the full calculation. It is a summary, not a replacement for the stored hierarchy and forecast version that produced a commercial decision.
Data. Formula and route reference · full_demo seed 42 · IPP2 Atlantis Wind demo seat:
ipp_2@webill.net/supersecret· last checked 2026-09-03.
15.1 Allocation rules
| Item | Rule |
|---|---|
| Waterfall order | PRIORITY → PRO_RATA → FIXED → surplus |
| PRIORITY | Fill in ascending unique rank:
allocation = min(demand, remainder). |
| PRO_RATA | Same-hour demand share:
allocation = remainder × demand / tier demand. |
| FIXED | allocation = entitlement × min(1, remainder / total entitlement),
then cap at actual demand. |
| Surplus | Remaining generator energy after all tiers; it is not re-offered within that hour. |
| Conservation | Σ allocations + surplus = metered generation; after
3-dp kWh rounding, residue goes to surplus (≤ 1 kWh). |
| Demand ladder | Metered consumption → firm/revised/indicative nomination →
contracted TOU profile → 0 plus provisional flag. Hourly
capacity and annual-volume caps always apply. |
| Tier | Commercial promise | CSF |
|---|---|---|
| PRIORITY | Rank protection before all other tiers | 1.00 |
| FIXED | Defined entitlement after priority and pro-rata | 0.90 |
| PRO_RATA | Equal-tier sharing of the remainder | 0.80 |
15.2 Forecast and availability formulas
| Measure | Formula | Read it as |
|---|---|---|
| FG | α·HAG₁·(SMₘ/SM₁) + β·HAG₂·(SMₘ/SM₂) + γ·SMₘ |
Next-month forecast; defaults
α, β, γ = 0.5, 0.3, 0.2. |
| ED | min(historical allocation, contract ceiling) |
Realistic demand used for the forecast waterfall. |
| CO | Forecast waterfall result per off-taker | It never exceeds ED. |
| SB | FG − ED_total |
Negative means oversubscribed. |
| AES | max(0, SB) |
Energy still available to sell before reliability discount. |
| HAF | HAF = GAF × SF × ARF × CSF |
Every factor is clamped to [0, 1]. |
| SCE | min(AES × HAF_tier, capacity headroom) |
Tier-specific safe contractable energy shown to a buyer. |
HAF factors: GAF is recent generation coverage; SF is seasonally-detrended stability; ARF is settled delivery reliability; CSF is the tier sensitivity above. No factor is manually boosted.
| HAF band | Value | Sales meaning |
|---|---|---|
| High | ≥ 0.85 | Bankable |
| Good | 0.70–0.85 | Reliable, minor discount |
| Moderate | 0.50–0.70 | Caution — meaningful shortfall risk |
| Low | < 0.50 | Not bankable — do not grow the book |
| No data | Under three months history | No history — use contract evidence; do not invent a score |
15.3 Statuses and decisions
| Status | Meaning | Next action |
|---|---|---|
| DRAFT hierarchy | Changes are not yet operational | Validate and publish an effective-dated version. |
| IN FORCE hierarchy | Governs the current hour | Use it to explain the live allocation order. |
| SUPERSEDED hierarchy | Historic version remains audit evidence | Select it to re-read historic settlement. |
| PROVISIONAL forecast | Completeness is below the final threshold | Treat SCE cautiously; await the automatic re-run. |
| FINAL forecast | Meter completeness has qualified | Use its versioned evidence for sales decisions. |
| OVERSUBSCRIBED | SB < 0; AES is zero |
Pause new sales and warn affected lower tiers. |
| Above-SCE proposal | Contract volume exceeds safe headroom | Acknowledge explicitly or reduce/restructure the proposal. |
| DRAFT curtailment claim | Ended instruction; not yet lodged | Review, prepare evidence, export CSV, then lodge before the 48-hour clock (§10.3 · §10.4). |
| LODGED / provisionally paid | Evidence sent; money may be in | Record provisional then final; a Mock receipt is not NTCSA receipt. |
| CLOSED claim | Paid, variance accepted, withdrawn, or uncompensated | Unrecovered (if any) can feed the Money Room. |
15.4 Routes and operating rhythm
| Need | Path or command |
|---|---|
| Review the gap, what it is worth, and the next best action | Generator sites → … → Strategy → Overview |
| Read generation-hour value, who buys, three-day weather, price vs cost | Same Overview: #ipp-capture · #ipp-buyers
· #ipp-weather-outlook · #ipp-price-rail (§4.4 · §4.5 · §4.6 ·
§4.7) |
| Value the gap against the market, rank buyers, simulate and compare deals | Generator sites → … → Strategy → Sales |
| Review safe contractable capacity (SCE / HAF) | Sales → Pricing tools → Firm viability · safe capacity (headline also on the Overview gap hero) |
| Price a TOU multiplier set or a firm block | Sales → Pricing tools → TOU pricing / Firm viability |
| Publish the allocation rule | Generator sites → … → Strategy → Allocation → Rules · hierarchy |
| Inspect forecast evidence | Generator sites → … → Strategy → Allocation → Forecast · next month |
| Trace settled hours (named members) | Generator sites → … → Strategy → Allocation → Outcomes · settled |
| Read today’s measured output, register a feed, grant consent | Generator sites → … → Strategy → Plant
(/org/generator-sites/:id/strategy/plant,
#ipp-plant) (§11) |
| Read the site’s profit-and-loss story and health check | Generator sites → … → Strategy → Dashboard |
| Read Generated, Earned, Cost of generation, and how sure the story is | Dashboard #ipp-story-verdict ·
#ipp-story-grade (§12.1) |
| Read this site’s battery contract (only when the site has a battery) | Dashboard → Chapter 5 → Open battery contract (§12.6.1 · §20) |
| Lodge or reconcile a curtailment claim | Generator sites → … → Strategy → Curtailment (§10) |
| Review a claim and export its CSV | Same tab → Review
(#open-claim-<id>) → Prepare
evidence / Export CSV / Evidence
bundle CSV (§10.3) |
| Read the portfolio story across every owned plant | IPP Sites → Fleet (/org/ipp-sites;
/org/fleet still opens it) (§2
· glance §2.1) |
| Read unsold energy and the sales plan | Fleet chapter 01 / The sales opportunity (§2.2) |
| See who the fleet depends on | Fleet chapter 02 / Who the fleet depends on (§2.3) |
| Compare sites added together vs combined fleet | Fleet chapter 03 / Does a bigger fleet help? (§2.4) |
| Act from the three next-chapter rows (Sales desk · contracts · Import intervals) | Fleet chapter 04 / The next chapter (§2.5) |
| Open the numbers behind the fleet story | How sure are we? / Understand the estimate / See buyer exposure drawers on Fleet |
| Recompute or export the fleet view | Title row, top right: Export CSV
(#fleet-export, GET /org/fleet.csv) ·
Recompute now (#fleet-recompute) (§2.6) |
| Backfill forecast history | mix wb.forecast_backfill --from YYYY-MM --to YYYY-MM |
| Compare hierarchy outcome | mix wb.replay_hierarchy_diff --generator ID --month YYYY-MM |
Old bookmarks still work: …/strategy/haf opens Sales;
…/strategy/hierarchy, …/strategy/forecast and
…/strategy/allocations open the matching Allocation
mode.
MonthlyForecastRunner runs on the 5th at
04:00. Strategy evidence refreshes nightly. For operational
ownership and runner catalogue detail, see V21 ·
Operations.
15.5 Worked-number check
The illustrative figures used in this volume are pinned by the
examples: raw FG 13,240 MWh; seasonally normalised FG
14,208 MWh; August ED_total 16,000 MWh,
SB −1,792 MWh, FIXED scale 0.488; December
AES 1,500 MWh; shared HAF factors
0.794 × 0.964 × 0.920; tier HAF
0.704 / 0.634 / 0.563; tier SCE
1,056 / 951 / 845 MWh.
15.6 Terms and bridges
- Allocation tier
- HAF, ARF, and SF
- AES and MAPE
- Settlement — taught in V8
- Curtailment claim, deemed energy, curtailment regime, evidence bundle — taught in §10 · bundle §10.3
- IPP Fleet, Value at Risk (VaR), combined fleet, sites added together, modelled exposure, adverse basis — taught in §2
Full glossary. Hub → Glossary.
Where this is taught. Contract terms and activation live in V7 · Deal Room; portfolio strategy belongs in V3 · Strategy; settlement and operations are owned by V8 and V21.
16. Runtime MEC enforcement
The contracting guard in §13 refuses a deal whose contracted megawatts would exceed the generator’s Maximum Export Capacity on paper, at activation. This chapter is the other half of that story: once the plant is running, the platform watches metered export against the same connection-agreement limit, continuously.
It does not curtail the plant. It does not invent a penalty. It flags a sustained breach so you can see it, and it books an excess charge only when the network operator has named a rate.
Follow along. Seat:
ipp_2@webill.net(passwordsupersecret) for the priced demo site Tshwane Solar Park (IPP 2);ipp_3@webill.netfor Buffalo City Hybrid Park, which can show the badge without a Rand figure. Paths: Generator sites (/org/ipp-sites) and Money (/org/money). full_demo seed 42.
16.1 What triggers the badge
On Generator sites, a rose MEC breach pill sits next to the technology badge when that site has a detected export episode in the last 30 days. One overnight inverter fault is one badge, not one per 20-minute interval.
The pill is a fact about export versus the connection-agreement limit
in force that night (MecLimit: megawatts, meter/CT
tolerance, effective dates). It is not an invoice. A site whose only
episode is older than the recency window is quiet again.
The activation-time guard in §13 is
unchanged. Signing a contract still checks Σ contracted MW against
export_capacity_mw. Runtime enforcement is a second watch
on the meter, not a rewrite of that check.
16.2 What the Money Room card says
Panel 5 on /org/money (Do next) shows
the same episode as a detector card: a plain sentence naming the site,
the peak export, the MEC, and how long the run lasted. Example:
Tshwane Solar Park exported 82 MW against a 76.5 MW MEC for 2
hours.
When the connection agreement names a penalty rate, the card can carry the Rand that rate implies. When it does not, the card still appears — with no Rand figure at all. Silence is not a dash, a zero, or “R —”. The network operator has not published a price, so the platform does not invent one.
16.3 The excess charge — and why silence is correct
:excess_charge already exists as a settlement category.
This chapter does not add a new kind of line. What is new is an optional
penalty_rate_r_per_kwh on the limit in force for the breach
window.
When that rate is on file and the site has exactly
one active physical PPA whose settlement period covers the window, the
nightly scan posts a matched pair: payable by the
generator, receivable by the network operator (Eskom or municipality,
matching the site’s connection). The two lines net to zero on the
period. Quantity is the energy above the limit; the source term is
mec_limit.penalty_rate_r_per_kwh.
When no rate is on file, or more than one active physical buyer shares the site, nothing posts. The finding and the badge remain. A later rate does not retroactively price an episode already scanned. A multi-buyer split is out of scope here — not a TODO hidden as a zero.
Careful. A missing penalty rate is a correct, expected state. Most connection agreements never name one. The platform must not quietly fill the gap, and the badge must not read as money owed when none has been set.
16.4 How the two guards read as one story
| Moment | What is compared | Where you see it | What it may write |
|---|---|---|---|
| Contract activation | Σ contracted MW vs export_capacity_mw |
PPA wizard capacity step (§13) | Refusal, or an acknowledged exception on the contract |
| Runtime, after midnight | Metered interval kW vs the MecLimit in force that
date |
Generator-site badge; Money Room Panel 5 | Optional :excess_charge pair, only if a rate is on
file |
Both watches exist so a plant that was legal at signature cannot quietly export above its MEC tonight without anyone on the organisation side seeing it. Neither watch is a control system: they detect, they surface, and they price only when the network operator has already named the price.
17. Where your forecast comes from
Route:
…/generator-sites/<id>/strategy/dashboard (weather
panel) · Bid desk: …/org/brp/bid-desk
(grade, provider, issued-at)
This chapter is the operator-facing account of weather-driven generation forecasting. The platform now has a weather provider. The demo estate runs on a simulated one — a deterministic mock that never opens a socket. Live providers exist behind configuration and are never the default.
The mock follows each site’s own sun. It works in local solar time — UTC shifted by the site’s longitude, one hour for every 15°, so Johannesburg (28° E) is about UTC + 1.9 hours — and its irradiance runs from about 06:00 to 18:00 solar time, peaking at solar noon. A demo solar forecast therefore makes no power after dusk, and its P50 line sits over the daylight hours of the site’s clock.
17.1 Issued at
A forecast has two timestamps:
- Issued at — the provider’s model-run time. This is the number that orders which forecast is in force. A bid placed at 03:00 is still explicable at 15:00 after the provider has reissued twice, because the 03:00 issue is kept.
- Fetched at — when we pulled the row. A re-poll of an unchanged model run updates this and nothing else.
The mock is the default in every environment. Turning a live feed on is a configuration change, not a rewrite.
17.2 How irradiance becomes megawatt-hours
A photovoltaic array converts global irradiance and ambient
temperature through the site’s installed DC capacity and a
stored performance ratio. The AC connection clip is the
same export_capacity_mw the synthetic shape already uses.
Night is a real zero — not a missing hour that falls back to a
climatological guess.
A wind site converts hub-height speed through a curve table the operator maintains: speed/power breakpoints, cut-in at the slowest row, cut-out to zero (not nameplate) above the fastest. A site with no table does not convert; a guessed curve would ride into a bid without a caveat.
17.3 P50 and P90
Grades follow the exceedance convention already documented in V3: P90 ≤ P50 ≤ P10 for generation. P90 is the low, bankable case. When the provider supplies a real spread, that spread wins over the technology fallback ratio.
A :MODEL series sits below a human :MANUAL
upload and above the synthesised profile. Hours the forecast covers take
model values; hours beyond the horizon keep the shape, so a 72-hour
forecast inside a twelve-month run does not blank eleven months.
The optional Open-Meteo ensemble supplies P90 from ensemble
spread: member 10th/50th/90th percentiles map to P90/P50/P10
exceedance grades. The central point forecast is retained. If the extra
call fails, the deterministic forecast still lands and the panel
identifies the synthetic fallback (P90 from the technology ratio).
Solcast requests both ghi10 and ghi90 for its
bands.
17.4 Live providers, behind configuration
A live weather feed can be switched on as a configuration change. The demo estate and the test suite never contact one — they run on the mock, and a check fails the build if that is no longer true.
When the feed is down, tomorrow’s bid is the synthesised per-technology shape, not an empty volume. A forecast older than its freshness window stops being preferred over that shape. Inside the window the model still wins; the bid desk badges it when it is going stale.
Which sites, if any, use a premium solar feed is a row on the site, not a deploy. No endpoint, credential or key appears here.
Operator pre-flight
GD6 remains open. Buy and approve a subscription
before arming pilot sites. Run mix wb.weather_arm_check
first. It lists resolved adapters, stored site routes, whether network
is forbidden, and remaining quotas without calling a provider or
printing credentials.
Configuration names are :weather_provider,
:open_meteo_base_url, :open_meteo_api_key,
:open_meteo_ensemble_base_url,
:open_meteo_ensemble_models,
:solcast_base_url, :solcast_api_key,
:weather_call_budget,
:weather_freshness_seconds, :weather_retry,
:weather_req_options, and
:weather_forbid_network. Runtime names include
WEATHER_OPEN_METEO_ENSEMBLE_BASE_URL and
WEATHER_OPEN_METEO_ENSEMBLE_MODELS (comma-separated). Keep
secrets in the deployment environment.
For an approved pilot, configure the live adapter and endpoints,
remove the network-forbidden override, and create a
SiteRoute row for the chosen PV site with provider
:solcast when required. Wind routed to Solcast is refused.
The ensemble request runs only with day-ahead fetches, never with drift.
A refusal leaves existing evidence visible; missing history says
no history.
The existing budget is an ETS counter per running
VM, not a durable monthly billing cap. The
open_meteo_ensemble budget is separate. Counters reserve
logical fetches; transport retries may add HTTP requests. Each request
may consume multiple provider-billed units; verify the purchased plan’s
accounting before launch. Resetting a VM resets these counters. Setup
refuses to run unless both weather and forecast-pack transports resolve
to Mock.
17.5 Stale forecasts
A stale badge means the model run is older than the freshness window for that provider. The bid that already used that run still shows the number, with the badge so the desk can see it aging. Once the window has expired, a new bid falls through to the synthesised shape so the desk never constructs tomorrow’s volume from nothing.
17.6 The drift loop
Through the delivery day the same provider is asked again, at a shorter horizon. That nowcast is converted through the same power curve and lands on the same model series. The desk does not get a second brain: the platform asks the intra-day decision it already has — carry inside the metering accuracy band, carry when an instruction is expected, or re-declare when the cliff past the band makes the intra-day market cheaper.
A weather-specific megawatt threshold is not part of this. The economic test is the whole reason that decision exists.
17.7 When the provider is down
Tomorrow’s bid is the synthesised per-technology shape. The bid desk says synthetic shape rather than showing a blank provider. The dashboard weather panel says No forecast — synthetic shape, which is not a forecast of zero. Night on a working forecast is a real zero; a missing forecast is a different claim.
17.8 Forecast skill and provider comparison
The Forecast page
(/org/generator-sites/<id>/strategy/forecast,
Allocation → Forecast · next month) is the month-ahead
carve (§8). Weekly skill by source, provider
and horizon — including Synthetic shape as the baseline
— lives on Dashboard chapter 5
(/org/generator-sites/<id>/strategy/dashboard,
#ipp-forecast-evidence-quality; on-page table: §12.6; bridge: §8.1.10). Each version records its
installed-capacity normaliser, paired hours and missing observations. A
week without meter evidence has zero paired hours and unavailable
metrics, never zero error.
nMAE, nRMSE and signed bias divide hourly error by export capacity in kW and report percent. Night hours count. MAPE omits zero actuals and can magnify small dawn errors. Pinball loss is in kWh; P90 is the lower 90% exceedance forecast, so its pinball quantile is 0.10. Coverage is measured, never hard-coded to 90%. The worked 10 MW, eight-hour example scores nMAE 5.44%, nRMSE 10.17%, bias +2.94%, P90 coverage 87.5%, and P90/P50/P10 pinball losses 276.9 / 271.9 / 88.1 kWh.
Day-ahead replay uses the preceding day’s 03:00 UTC cutoff for each SAST delivery day, with a 26-hour maximum age. Intraday replay uses one hour before delivery and a six-hour maximum age. Later model issues cannot improve an older score. A changed input hash appends a new evidence version.
The comparison cards use the same latest week, show each source’s weeks of history, and leave absent providers at no history. Mock rows demonstrate the screen; they do not establish which paid provider performs best.
17.9 Grid Code forecast packs
The IPP Dashboard (#so-pack-panel, under Forecast
evidence — §12.6) also lists System Operator
forecast packs. Category comes from inverter MVA, falling back to export
MW: below 1 is Category A, 1 to below 20 is B, and 20 or more is C.
Category A produces an explicit refusal. Missing capacity, missing model
coverage, and models older than 24 hours also produce refusal rows.
The weekly pack contains 168 hourly rows, starting at the next SAST midnight. It is due by 10:00 SAST on the issue day; the worker builds at 09:30. The rolling pack starts at the next full hour, contains six rows, and is due ten minutes before that hour; its worker runs at :40. Late status is frozen when built. A model beyond its freshness window but within 24 hours is marked stale.
Available MW is the lower of export capacity and effective MEC; an overlapping outage sets the hour to zero. Forecast and availability use three decimal places. Download XML from the pack row. Only the owning organization can download it. A first download moves BUILT to DOWNLOADED; downloading a PUSHED pack preserves PUSHED. Refused packs have a reason and no downloadable document.
rpp-forecast/v1 is our versioned
schema, validated against its bundled XSD, with explicit
+02:00 timestamps. It is not an operator-approved wire
contract; the current POC reference is the platform site identifier.
PUSHED currently means acknowledged by the mock transport, with a
MOCK- reference. No real SO endpoint is configured or
implied.
18. The technology card
18.1 Capture the plant once
The IPP wizard’s final Plant profile step is optional. Solar, wind, hydro, thermal and hybrid plants have different fields. A BESS site keeps its battery settings. Leaving the step empty preserves the existing forecast defaults; the Overview says No plant profile and offers an edit link.
Solar captures tracking, panel geometry and losses. Wind captures turbine geometry and availability. Hydro captures the river or storage kind, monthly inflow factors and daily or weekly water-energy limits. Thermal captures fuel, heat rate, operating cost, start costs and engineering limits. Start costs must be ordered hot ≤ warm ≤ cold. An invalid profile is refused on save.
18.2 Read the evidence
The Overview card distinguishes profile data, default forecasts and missing values. On Overview it lives inside the Unsold profile fold Solar PV / Wind / … assumptions & forecast basis (§4.2). It shows the P90/P50 ratio. Declared thermal availability can lower this ratio. A measured or nominated series still takes precedence over a default shape. Changing the profile changes the strategy input record; it does not rewrite historical runs.
Registry projections retain unknown water-resource capacity, contacts and storage limits as missing. Thermal hourly loading ramps derive from the captured per-minute rate. Start-up and shutdown ramps remain assumptions that the engineer should review.
18.3 Solar and storage together
A hybrid composition selects existing solar or wind sites and optionally an active battery from the same organisation. Each component has one composite owner. A book cannot include both a composite and its generation component. Removing the composition releases its claims.
The default combines generation, moves available energy into the evening within battery limits, and clips once to the shared export cap. The card reports clipped energy. A battery already dispatched as a book member takes precedence over this default shift. This representative-day model is not a multi-day storage optimiser.
18.4 A hydro site forecasts by its inflow
The Orange Weir Run-of-River demo captures twelve seasonal factors and a daily energy cap. With no historical seasonal forecast, its monthly forecast follows those factors. Run-of-river generation stays flat within each day and keeps the 0.90 P90 ratio. Water-energy and export limits can reduce delivered energy below unconstrained P50. Regional hydrology is a desk signal; it does not change a site’s measured generation.
18.5 Dispatch economics
A thermal profile adds the Dispatch economics card to Overview and Dashboard. Marginal cost is fuel price times heat rate, plus variable operating cost and the existing carbon assessment for one MWh. Every input row and the calculation hash can be inspected. Carbon amounts remain estimated until the separate carbon programme’s confirmation gates are satisfied.
The demo diesel profile produces R6,098.57/MWh using its sourced fuel price and the 2026 allowance register. The card compares emissions intensity with the dated benchmark. Forecast P10/P50/P90 running hours count hours whose price covers marginal cost; missing cells say not available. This is an economic screen, not a unit-commitment schedule.
Thermal offer prices cannot fall below marginal cost, including price-taker offers. If cost exceeds the market cap, or a required register input is missing, the offer is withheld. A peaker top-up draws only residual supply from its named thermal membership under the contract’s cap and tolerance.
19. Capture, cannibalisation and your PPA
Where this is taught. How to read the Overview card Value of your generation hours (
#ipp-capture): §4.4. This chapter is the maths: cannibalisation, floor hours, and market-indexed vPPA comparators.
A flat generator earns the average hourly price. Solar earns the prices available when the sun shines. If many solar plants produce together, those hours can become cheaper. Cannibalisation is 100 minus capture rate; a negative number means the generation shape earned more than the average.
In the demo summer series, the representative solar day captures R721.10/MWh against an R859.17/MWh average: 83.93%. In winter it captures R923.12/MWh against R934.17/MWh: 98.82%. These are examples from the mock price function. A measured estate can differ.
Market-indexed vPPA strike evidence shows Captured SMP (R30) and cannibalisation for SAWEM SMP or TOU-average floating legs. A flat strike comparison says how far the strike sits above the captured price. An Eskom credit-rate floating leg has a different basis and does not show this comparator.
The floor-hour policy is part of the evidence. Under the default, generation at or below the policy floor remains in volume and earns zero cash. Under exclusion, those hours leave the price and energy denominators. Changing conventions changes the answer; old observations retain their convention.
20. Your battery’s contract
This page is the owner’s battery contract register: the warranty booklet for the pack on this generator site. It is not a fourth Dashboard chapter. When this site has a Bess asset, the Dashboard’s health chapter (§12.6.1) weaves the trailing-year numbers into the story and points here. A site without a battery does not mention a battery on the Dashboard at all.
Follow along. Seat:
ipp_2@webill.net. Path: Generator sites → Rosslyn BESS → Strategy → Dashboard → Chapter 5 → Open battery contract. URL:/org/generator-sites/:id/strategy/battery. IPP2 Atlantis Wind has no battery: its Dashboard stays silent, and this register would say This site has no battery asset.
The owner controls the cycle-life curve, pack replacement cost, dated capacity evidence and contracted reserve register on this page. The trader’s BESS day view (V3 §10) sees cycles and round-trip efficiency because dispatch consumes those cycles. Health, replacement cost, availability and reserve revenue stay here.
20.1 Read the contract numbers
The three tiles use the trailing 365 days ending on the displayed date. They use current ACTUAL battery intervals, not forecast schedules; superseded runs and repeated owner/trader views do not add throughput twice. Before actual battery evidence, the tiles say No settled month yet.
| Metric | Calculation | Illustrative warn / breach limits |
|---|---|---|
| Cycles to date | Discharged kWh / effective capacity kWh | above 690 / 730 |
| Measured round-trip efficiency | Discharged / charged kWh × 100 | below 75% / 70% |
| Availability | Window hours less the union of recorded outage hours, divided by window hours | below 96% / 95% |
For 18.8 MWh effective capacity, 12,400 MWh discharged, 14,300 MWh charged and 310 outage hours, the values are 659.6 cycles, 86.7% and 96.5%. Availability is from operator outage records; an omitted outage cannot appear in that estimate. RTE stays absent when there is no charging denominator. Limits are editable contract data, not a certification of warranty compliance.
20.2 Record capacity and wear
Enter the effective date, health percentage, evidence source, test reference and recorder’s email. The register is append-only. Later tests apply from their effective dates; old dispatch audit rows retain the health used at the time. Health must be between 30% and 100%.
The wear editor accepts ten depth keys, 10 through 100, each with positive, decreasing cycle life and a non-decreasing marginal wear ladder. Load LFP default offers illustrative data; saving requires a positive cycling-attributed replacement cost and a source sentence. Record any residual-value allowance in that sentence. Clear the table to return to the configured flat wear model. Changes take effect on the next run and change its input fingerprint.
20.3 Reserve capacity and held opportunities
A commitment records category, direction, hourly window, MW, sustain duration, price, counterparty, contract reference and effective dates. The ending date is exclusive. Overlapping commitments of the same category and direction are refused; combined commitments must fit the battery’s power and usable storage. SCO is not supported as a battery commitment.
UP reduces discharge power and protects enough stored energy to sustain the service. DOWN reduces charging power and preserves storage headroom; BOTH applies both constraints. A 2 MW UP commitment from 17:00 to 21:00 at R220/MW/h earns R1,760 per day. Its capacity lines carry zero kWh. Revenue this month is drawn from the latest daily plan evidence, so repeated forecasts are not summed.
The 30-day cycle-cap strip shows days when the daily cycle budget clipped a profitable opportunity and the corresponding held Rand. It is evidence for reviewing the dispatch method, not a claim that an optimiser would recover every Rand. The current trigger is ten hit days and R10,000 in 30 days. Reserve-market clearing and an LP/MILP dispatcher remain separate backlog work.
The trader sees cycles and RTE because dispatch consumes those cycles. Health, replacement cost, availability and reserve revenue remain on the owner’s page.
