← Manual home

V17 · Virtual Wheeling

The registered VW account, 15-minute allocation, and the consolidated 45-day refund Eskom actually pays.

1. This volume — the account Eskom actually registers

You own generators that pour energy into the public grid. You also have meters that drink from that same grid. You cannot run a private hose between them. The shared tank is the grid; Eskom watches both taps in the same fifteen minutes. That is the problem this volume solves.

Wheeling is the everyday word for moving energy across that shared tank from a private seller’s connection to a buyer’s. Classic physical wheeling still does that with nominations, losses and a delivered profile — taught in V0 §5 and settled in V8. Virtual wheeling is different: nobody reassigns electrons to your meters. Eskom still refunds you when fleet generation and enrolled load overlap in time.

The water-tank picture

Picture one big water tank — the national grid. Your generators pour in at one set of taps. Your enrolled meters drink at other taps. You cannot lay a private pipe. Eskom meters both sides in the same quarter-hour (a fifteen-minute slice; the chip on the page says “15-minute grain”).

For every litre a meter drank while the fleet was pouring in that quarter-hour, Eskom pays one refund to the party named on the account. Litres poured when no enrolled meter was drinking earn nothing — that is uncredited excess. The fill rule is “pour into the glass with the most room left first” (most uncovered consumption first). Nothing spills into the next quarter-hour or the next time-of-use window.

That picture stays for the whole volume. Chapters 4–5 turn it into the formula and the optimiser proof; chapter 8 shows the same glasses on the organisation page.

Teaching example — one Standard quarter-hour on a Virtual Wheeling account (not a demo stamp)
One quarter-hourFleet pours 100 kWh · fill most uncovered first
Fleet generation100 kWh
↓ fill · glass with most room first
1 · Meter A80 / 80 kWh
80 matched
2 · Meter B10 / 10 kWh
10 matched
Left in the tank10 kWh
uncredited excess
Matched (refunded)Uncredited excess

If both meters sit on a 50 c/kWh gen-wheeling rate, matched energy is 90 kWh and the refund is 90 × R 0.50 = R 45.00 (4,500 cents). The 10 kWh excess earns R 0. An equal 50/50 split would have matched only min(50, 80) + min(50, 10) = 60 kWh and wasted 40 — chapter 5 owns that proof.

What Eskom registers (and what it does not)

A Virtual PPA on this platform is one IPP, one off-taker site, and a strike-versus-credit settlement with the WER (Wheeled Energy Refund) netted inside a CfD (contract for difference). That is the product the Deal Room already sells — V7 §9.

Eskom registers something else. Eskom registers a Virtual Wheeling account: a named account holder, many generators and many off-taker meters enrolled against it, and one consolidated refund paid to that holder within the account’s payment term (45 days by default), computed per registered supply point per time-of-use window (Peak, Standard, Off-peak) at 15-minute grain.

This volume is that product. It does not replace the per-contract Virtual PPA. A site may be both a Virtual PPA counterparty and a VW portfolio member. The two paths never meet inside one statement — classic wheeling stays at 20-minute grain; Virtual Wheeling is 15-minute throughout.

Where this is taught. Physical vs virtual deals — V0 §5. The per-contract Virtual PPA — V7 · Deals. The WER kernel that both paths share — V8 · Settlement. The numbered, immutable document the refund becomes — V15 · Billing.

Words you need in this chapter

Word Plain meaning
Wheeling Moving energy across the shared grid; contracts decide who pays whom.
Virtual wheeling Same tank, no private hose: refund when fleet generation and enrolled load overlap in the same quarter-hour.
WER (Wheeled Energy Refund) Eskom’s credit on matched energy — the money on the credit note.
Virtual Wheeling account The named registration Eskom refunds: one holder, one banking detail, one due date. Distinct from a site’s VWA application status on Supply.
Quarter-hour / 15-minute grain The fifteen-minute slice Eskom uses for the whole VW path.
Gen-wheeling rate The c/kWh rate for that meter’s tariff category and TOU window.
Time-of-use (Peak, Standard, Off-peak) The tariff windows that set which rate applies.
Credit note The numbered Eskom document that carries the month’s refund.
Account holder The organisation named on the Virtual Wheeling account — the party Eskom pays.

Who the account holder is

The refund is paid to the party named on the Virtual Wheeling account, not to each meter owner. That is why the account is a first-class resource rather than a label on a contract: Eskom’s register has one row, one banking detail, one due date.

A private wire would be a hose between plant and factory. Physical wheeling is still a delivery story with losses. A Virtual PPA / CfD is a price hedge on one site. Virtual Wheeling is the water tank: many taps, one refund to the holder.

How this volume is ordered

Chapters 2–3 register the account and compose the portfolio. Chapters 4–5 compute the refund at 15-minute grain and explain why allocation matters. Chapters 6–7 issue the consolidated document. Chapters 8–10 are the two consoles and the municipal case. Chapters 11–12 close.

2. The VW account

Eskom will not pay a fleet of meters one by one. It pays one named holder. That holder is the Virtual Wheeling account — what Eskom issues a registration reference for.

The platform stores that reference as vwa_account_ref, and it is unique in the register: two organisations cannot both claim the same Eskom account. Think of it as the name plate on the shared water tank: every pour and every drink on this portfolio is booked against that one plate.

This is not the same word as a site’s VWA application status on Supply (Not Submitted / Pending / Registered / Conditional). That status is a per-site gate for virtual deals. The Virtual Wheeling account is the portfolio registration that receives the consolidated refund.

Registering

The account names:

Naming a pool for excess — or not

Uncredited excess is generation that the fill discarded because it landed above a meter’s consumption in that quarter-hour. The refund always reports it. It is routed only when the account names a trader pool in excess_trader_pool_id. Naming the pool is the opt-in. A portfolio that names none routes none. When routed, the excess leaves as a spill-credit line on the credit note.

Where this is taught. How the page shows the account strip — §8. The 45-day term and corrections — §7.

Follow along. Seat: OffTaker C. Path: Organisation → Wheeling → Virtual Wheeling. The account reference, the registration status and the 45-day term sit on the account strip (#vw-account) at the top of the page.

3. Portfolio membership

Generators and off-taker meters enrol on the same account. On the water tank, the fleet are the pour taps and the meters are the drinking glasses. The allocator needs both on the same footing, in the same fifteen-minute grain.

Membership is effective-dated. A meter that leaves in March and rejoins in August is two rows. The date is part of the identity so the rejoin cannot collide with March’s history — the audit trail a refund dispute reads.

The >100 kVA floor

Eskom will not register a supply point at or below 100 kVA. The platform refuses enrolment of an off-taker whose notified capacity (notified_capacity_kva) is not strictly above 100. A site at exactly 100 kVA is refused. The refusal names the site and the actual kVA.

Municipal off-takers are welcome

A municipal connection does not block enrolment. Municipal off-takers keep paying their municipal bills in full; the municipality stays revenue-neutral; the refund still reaches the account holder. That is the product, not an exception to it. Generators keep the existing Eskom-connection requirement.

Where this is taught. The municipal money path in full — §10. The enrolled tables on the page — §8 · Who is enrolled.

One grain

The account declares its grain (15 minutes). Every member must be able to supply that grain. A 20-minute meter on a 15-minute account is refused at join, with a message that names both grains and the member. There is no conversion. The VW path and the classic 20-minute wheeling path never meet inside one statement, so there is nothing to map.

4. How the refund is computed

Eskom evaluates the WER (Wheeled Energy Refund) per registered supply point, at 15-minute grain. In plain words: in every quarter-hour, take the energy a meter drank that the fleet had poured in that same quarter-hour, multiply by that meter’s gen-wheeling rate for the time-of-use window, get whole cents, then sum across meters and windows. That sum is the credit note.

Written as a formula:

R = Σ_meters Σ_TOU min(C_it, G_it) × WT_t

C_it is what meter i consumed in interval t. G_it is how much fleet generation the fill credited to that meter in the same interval. min() is the matched litre in the glass. WT_t is the gen-wheeling rate for that meter’s tariff category and TOU window.

min() is non-linear. A monthly or even a TOU-total min overstates the refund, because generation that missed consumption in one quarter-hour cannot be borrowed from another. Water poured at noon does not fill an evening glass. The platform therefore matches at interval grain and only then sums by time-of-use window.

Worked: one meter, one day

Take a single meter over 96 fifteen-minute intervals. In each interval the allocator has already decided how much of the fleet’s generation G_it is credited against that meter. The matched energy is min(C_it, G_it). Multiply by the NERSA gen-wheeling rate for that interval’s TOU bucket. Sum. That is the meter’s contribution to the consolidated refund.

A monthly total of consumption and a monthly total of generation, put through a single min, is a different (larger) number. It is not the refund.

The rate is keyed by the meter’s tariff category × TOU. A Nightsave meter has no peak bucket; crediting one at another category’s peak rate invents money. On the arithmetic table the Peak cell then says no peak window and contributes R 0.

Teaching cell: two meters, one quarter-hour

Fleet generates 100 kWh in one Standard quarter-hour. Meter A used 80 kWh, Meter B used 10 kWh. After the fill (chapter 5), matched energy is 90 kWh. At 50 c/kWh on both meters:

90 × R 0.50 = R 45.00 = 4,500 cents

The 10 kWh left in the tank is uncredited excess and earns R 0. Whole cents per meter per window, then summed — no second rounding on the portfolio.

Where this is taught. The fill that produces G_it — §5. How the page shows the working — §8 · How the refund was built.

CfD volume strikes and the refund

A virtual PPA’s volume strike caps the CfD payment, never WER. Settlement splits matched intervals chronologically at the strike and pays the CfD only on the within-strike share. The full matched volume still earns the applicable refund, including intervals wholly above the strike.

5. Allocation and the optimiser

The same kilowatt-hour of fleet generation is worth more when it is credited against a meter that actually consumed in that quarter-hour. Anything allocated above a meter’s consumption is discarded by min() — uncredited excess, real generation for which no refund is paid. The allocator exists to shrink it.

On the water tank: pour into the glass with the most room left first. Fill that glass up to what it used, then the next, until the pour runs out. Litres still in the tank after every drinking glass is full earn nothing in that quarter-hour. They do not wait for the next glass, the next quarter-hour, or the next TOU window.

Equal split versus greedy fill

Two shapes of the same interval show why the fill order matters.

Shape A — classic equal-split trap. One interval, 100 kWh generated, meter A consuming 100 kWh, meter B consuming nothing.

The refund doubles. The 50 kWh the equal split lost is uncredited excess.

Shape B — teaching example used on the page. One Standard quarter-hour, fleet 100 kWh, meter A used 80 kWh, meter B used 10 kWh.

At 50 c/kWh on both meters, greedy earns 90 × R 0.50 = R 45.00; the equal split would have earned only R 30.00 on the same pour.

The allocator is deterministic: ties break on member id, so a re-run of a settled month produces the same audit trail. It never draws generation from another interval or another TOU bucket.

Where this is taught. How the organisation page shows the fill table columns — §8 · Why each meter got what it got. The money formula — §4.

Batteries

A battery in the portfolio is a pseudo-meter. Metered discharge is generation in those intervals; metered charge is consumption. Moving energy from an over-supplied midday interval into an under-supplied peak interval converts uncredited excess into matched energy, because peak carries the highest gen-wheeling rate. Settlement reads the meter, not an hourly dispatch plan. On the page, Add storage under uncredited excess points at IPP Sites for that lever.

6. The consolidated refund

Eskom pays one WER (Wheeled Energy Refund) per Virtual Wheeling account per month. The document is an Eskom credit note, numbered from Eskom’s existing series, issued to the organisation that holds the account.

It is not a private artefact. Numbering, series allocation, and the immutability trigger that every other billing document obeys apply here too. The grain is the account, not the organisation: one organisation holding two VWA registrations receives two refunds for the same month.

On the water tank: one month’s pours and drinks become one payment to the name plate on the tank — not a cheque per glass.

How to read it

Each registered supply point has its own block. Inside the block, each time-of-use window shows matched kilowatt-hours, the NERSA gen-wheeling rate for that meter’s tariff category, and the integer cents. The document total is the sum of those cents. There is no second rounding at the portfolio.

Uncredited excess sits next to the money. It is generation the min() discarded in an interval because it landed above that interval’s consumption. The allocator exists to shrink that number. A month that looks fine on cents and loud on excess is a month whose generation profile missed the load.

Where this is taught. Billing numbering and immutability — V15. The organisation page’s amount, aging and PDF — §8. Eskom’s register of the same document — §9.

Follow along. Seat: OffTaker C. Path: Organisation → Wheeling → Virtual Wheeling. The month’s refund, the per-meter breakdown, and the excess figure are on the same page. June 2026 is the settled month.

7. Forty-five days, and what happens when a refund is wrong

Eskom pays the registered account holder within 45 days. That term is stored on the VW account and read at issue; it is not hardcoded on the way out. A silent fallback to the platform’s 30-day default would put the wrong date on a document that cannot afterwards be edited, so the issue path refuses a fallback.

A per-account override of the term (for example 60 days) is a commercial fact on that account and lands on that account’s documents. On the organisation page the chip reads {n}-day payment term; the due date and aging chip sit under this month’s refund.

A wrong refund is credit-noted, never edited

Billing documents are immutable after issue. The database trigger billing_documents_protect_issued() raises if an issued row is updated in place. The platform’s correction path is the same one every other document uses: a new version while the recipient has not yet seen it, a credit or debit note once they can.

That is why the 45-day term has to be right the first time. The cite strip on the page (#vw-cite) exists so you quote account, month, credit-note number and version, issued stamp, due date and allocation run before arguing a number.

Where this is taught. Billing immutability — V15. Citing the document on screen — §8 · Cite this version.

Excess routing is opt-in

Uncredited excess is always reported. It is routed to a trader pool only when the VW account names one (excess_trader_pool_id). Naming the pool is the switch. A portfolio that names none routes none; the statement still shows the excess. The routing line reuses the existing :spill_credit charge category.

Follow along. Seat: OffTaker C. Path: Organisation → Wheeling → Virtual Wheeling. The due date is 45 days from issue. Excess routing is the pool named on the account strip, or nothing.

8. The Virtual Wheeling section

The organisation console at /org/virtual-wheeling is the account holder’s seat. Page id #org-virtual-wheeling-page. Nav: Organisation app → Wheeling → Virtual Wheeling (hero-arrows-right-left). The page description reads: “The account Eskom refunds, who is enrolled under it, and this month’s consolidated Wheeled Energy Refund.”

It reads top to bottom as one story: the account Eskom pays, this month’s refund, how that number was built, the energy that earned nothing, why each meter got what it got, who is enrolled, and the facts to cite.

Where this is taught. What a Virtual Wheeling account is — §1 and §2. Membership rules — §3. The refund formula — §4. Why the fill order matters — §5. The credit note itself — §6. Municipal meters — §10. This chapter only explains what you see.

Follow along. Seat: OffTaker C. Path: Organisation → Wheeling → Virtual Wheeling. June 2026 is the settled month.

No account yet

When the organisation has no Virtual Wheeling account, the whole page is #vw-no-account. Title: No Virtual Wheeling account yet. The copy says the room fills in once the account is on record.

Three prerequisites sit under What has to exist first:

  1. Eskom’s registration reference for the account, its payment term (45 days by default) and its grain.
  2. Generators enrolled as the fleet, and meters enrolled as the load: each meter strictly above 100 kVA, on the account’s grain. Municipal meters are welcome.
  3. A settled month: the allocation run and Eskom’s credit note. Until then there is nothing to refund and nothing to show.

The account strip

When an account exists, #vw-account opens the page (green wash). The eyebrow reads Virtual Wheeling account · held by {org}. The H2 #vw-account-ref is Eskom’s vwa_account_ref.

One sentence explains the money: Eskom pays this account one consolidated Wheeled Energy Refund a month — fleet generation that an enrolled meter used in the same quarter-hour, credited at that meter’s gen-wheeling rate, paid to the org within payment_due_days of the credit note.

Chips #vw-account-chips:

Chip What it means
#vw-account-status Registered · since {date} (green); Conditional · since {date} (amber); Pending registration (amber); Deregistered or Deregistered · {date} (slate). Status is effective-dated, not a boolean.
{n}-minute grain Usually 15-minute grain. Prose on the page says quarter-hour.
{n}-day payment term Default 45.
{n} generators · {n} meters Who is enrolled.
Excess chip Green Excess routed to {pool}, or amber Excess reported, not routed.

Footer:

This month’s refund

#vw-month is the month card. The stepper is #vw-month-prev (aria Earlier month), #vw-month-label, #vw-month-next, plus pills #vw-refund-months for every month that already has a refund, so stepping is never blind.

When a statement exists

Label This month’s refund, amount #vw-refund-cents. Beneath it: Eskom credit note {number} · version {n} · issued {date}, then Due {date}, and chip #vw-document-state:

When a billing document exists, three controls:

Right column What earned it (#vw-story): generated kWh across N settled quarter-hours; matched kWh used by an enrolled meter in the same quarter-hour; else the other kWh (pct%) is uncredited excess linking #vw-excess; or “there is no uncredited excess this month.”

Bar #vw-energy-bar: green Matched, refunded and amber Uncredited excess, nothing.

Formula strip:

refund = Σ meters Σ windows matched kWh × gen-wheeling rate

“Whole cents per meter per time-of-use window, then summed. The credit note total is that sum, with no second rounding.”

Thread #vw-thread — four tiles:

Tile Links to Label
#vw-tile-generated #vw-members Fleet generated
#vw-tile-matched #vw-arithmetic Matched
#vw-tile-excess #vw-excess Uncredited excess
#vw-tile-refund #vw-arithmetic Refund
Teaching example — what the month bar and formula are saying (one Standard quarter-hour, both meters at 50 c/kWh)
One QHstandard
Fleet100 kWh generatedpours into the tank
fill order→A 80 + B 10
Matched90 kWh refundedat 50 c/kWh
Matched × rateR 45.0090 × 0.50
Uncredited excessR 0.0010 kWh left in the tank
Credit note cell4,500 centswhole cents, then summed

Empty month

Chip #vw-grade-chip-pending Not yet settled. Block #vw-empty-state: No refund yet for {Month}. A composed portfolio without a settled month is not a refund of zero; it is a month that has not been settled. Link #vw-latest-refund jumps to the latest settled month when one exists.

How the refund was built

#vw-arithmetic appears only when a statement exists. Title How {rand} was built. Sticky header: Meter | Peak | Standard | Off-peak | Meter total.

Each row #vw-meter-{id}: meter name links to /org/off-taker-sites; connection chip (Eskom or municipal); tariff; kVA; municipality when present. Each money cell shows cents on top and the kWh × rate working beneath. A Nightsave meter’s Peak cell notes no peak window and contributes R 0 — that tariff has no peak bucket, so inventing one would invent money.

Footer #vw-arithmetic-total: equals the credit note (check, green) or does not equal the credit note (rose). Footnotes: rate keyed by the meter’s Eskom tariff category and window; a municipal meter keeps paying its municipal bill; Eskom still refunds matched energy to this account. Empty body: No meter earned in this month: the run matched no energy.

Where this is taught. The formula and why interval grain matters — §4. Municipal bills — §10.

Uncredited excess

Amber card #vw-excess. Title from excess_title: Uncredited excess: {kWh} that earned nothing or Uncredited excess: none this month. Gloss: “The number you can act on. Surplus is never carried to another quarter-hour or another window.”

Buckets #vw-excess-peak, #vw-excess-standard, #vw-excess-offpeak. Estimate #vw-excess-estimate only when every meter shares one tariff category (≈ R … forgone); otherwise #vw-excess-no-estimate — “different tariff categories, so no single Rand value”.

Levers #vw-excess-levers:

  1. Enrol another meter → OffTaker Sites
  2. Add storage → IPP Sites (charge in surplus quarter-hours, discharge in peak; metered discharge counts as generation)
  3. Move flexible load into the surplus windows
  4. Route it to a trader pool — opt-in; leaves as a spill-credit line

Chip #vw-excess-routing: Routed to {pool} or Not routed · no pool named.

In the water-tank picture this is the litre still in the tank after every glass that was drinking has been filled. It does not wait for tomorrow’s thirst.

Why each meter got what it got

#vw-fill-order. Gloss: “The fill order, read from the run’s stored rows. Nothing is re-run for this page.”

Rule sentence on the page: most uncovered consumption first, up to what that meter used, then the next, until generation runs out. Nothing carried across quarter-hours or TOU windows. Ties break on member id, so a re-run is identical.

Day chips #vw-day-chips / #vw-day-{iso} when more than one day; else a single date. “times in SAST”. Interval chips #vw-interval-chips, or <select> #vw-interval-select when there are many. The selected quarter-hour lives in the URL (?at= and ?month=), so a row can be shared.

Summary #vw-interval-summary: fleet generated → filled into N meters → left over uncredited.

Table columns: #, Meter, Used, Filled, Matched, Still uncovered, Used vs filled (green bar). Footer #vw-fill-remaining Remaining generation after the fill. Tie note when all meters used the same kWh. “Rows come from allocation run {short id}”.

Empty #vw-fill-order-empty: No allocation rows were stored for this run, so there is no fill order to show.

Teaching example — reading the fill table

One Standard quarter-hour. Fleet generates 100 kWh. Meter A used 80 kWh, Meter B used 10 kWh.

# Meter Used Filled Matched Still uncovered
1 A 80 80 80 0
2 B 10 10 10 0
Remaining after the fill 10 uncredited

Fill visits A first (more uncovered use), then B. Remaining generation 10 kWh is uncredited excess. At 50 c/kWh on both meters the month arithmetic for this single window is 90 × R 0.50 = R 45.00. Equal split would have matched only 60 kWh — see §5; this page only shows what the columns mean.

Who is enrolled

#vw-members always appears when an account exists, even if the month is unsettled. Gloss: every member joined on the account’s grain; another grain is refused at join.

Fleet #vw-fleet: Generator (link /org/ipp-sites/sites), Technology, Export (MW, installed MWp under it), Member since + open or to {date}. Empty: No generator is enrolled. Without a fleet there is nothing to match.

Load #vw-load: counts N Eskom-connected · N municipal. Columns: Meter (link /org/off-taker-sites), Connection, Notified capacity with above the 100 kVA floor (check) or not above the 100 kVA floor (warning), Tariff, sets the rate, Member since. Empty: No meter is enrolled. Without load nothing can earn.

Footer: Eskom’s floor is strictly above 100 kVA; a site at exactly 100 kVA is refused and the refusal names the site and its kVA. A member that leaves and rejoins is two rows.

Cite this version

#vw-cite only with a statement. Fingerprint icon. Fields: account, month, credit note + version, issued stamp, due, allocation run. “Quote these before arguing a number. Eskom’s VWA register shows this same document: one document, two seats.”

Credit note modal

#vw-document-modal opens when you press View credit note. Kind label: Eskom credit note · Wheeled Energy Refund. Close event close_document. The same PDF is what Download PDF and Billing serve.

Before a month is settled

A composed portfolio without a settled month shows No refund yet, not R 0.00, with a link to the latest settled month. An organisation with no account sees what has to exist first (#vw-no-account above).

9. The VWA register

Eskom’s console at /eskom/virtual-contracts is the register. The address did not change; the placeholder did. Each row is a registered Virtual Wheeling account: its members, this month’s refund obligation, the due date, and how old an unpaid obligation is.

Aging is derived, never stored. The buckets are the same WB.Billing.Aging buckets every other unpaid document uses. A disputed refund still ages. The organisation page’s #vw-document-state chip uses those same buckets when a credit note is overdue.

The cents and the due date are the same billing document the account holder sees. One document, two seats. If those two screens ever disagree, that is a defect — stop and raise it.

The cite strip on the organisation page says the same thing in one line: quote the credit-note number and version before arguing; Eskom’s register shows this same document.

Where this is taught. The account holder’s view of the same month — §8. How the document is numbered — §6 and V15.

Follow along. Seat: Eskom. Path: Virtual Contracts.

10. Municipal off-takers

A municipal off-taker is welcome in a Virtual Wheeling portfolio. That is not decoration. It is the case the product turns on.

On the water tank the municipal meter is still a drinking glass. It keeps paying its municipal bill in full — the municipality stays revenue-neutral; it did not sell the energy and it does not issue the refund. Eskom still pays the registered account holder the WER (Wheeled Energy Refund) for matched energy at that meter.

The municipality does not see the VW refund on Munix. The account holder sees it on Organisation → Wheeling → Virtual Wheeling. Eskom sees the obligation on the VWA register. Three seats, one document, no second source.

On the arithmetic table a municipal row carries a municipal connection chip and the footnote: the meter keeps paying its municipal bill; Eskom still refunds matched energy to this account. On Who is enrolled the load header counts N Eskom-connected · N municipal.

The >100 kVA floor still applies. A municipal site at or below 100 kVA is refused at join, with the site and the actual kVA named in the refusal.

Where this is taught. Enrolment rules — §3. How the page marks the meter — §8 · How the refund was built and Who is enrolled.

Follow along. The demo portfolio enrols one municipal meter alongside three Eskom-connected meters.

11. Terms used in this volume

Term Meaning
Virtual Wheeling account The named registration Eskom issues a refund to. Identity is vwa_account_ref. Distinct from a site’s VWA application status.
Account holder The organisation named on the account — the party Eskom pays.
Portfolio membership A generator site or off-taker meter enrolled against an account, with an effective window.
Quarter-hour / 15-minute grain Eskom’s VW telemetry grain. The whole VW path uses it. Classic wheeling stays at 20 minutes. The chip says “15-minute grain”; prose says quarter-hour.
Gen-wheeling rate The c/kWh rate for a meter’s Eskom tariff category and TOU window.
Time-of-use (Peak, Standard, Off-peak) The tariff windows that pick which gen-wheeling rate applies.
Matched energy min(consumed, allocated) in one quarter-hour. The refund multiplies this by the gen-wheeling rate.
Uncredited excess Generation the fill discarded. Always reported; routed only when the account names a trader pool.
Fill order Most uncovered consumption first, then the next glass, until generation runs out. Ties break on member id.
Notified capacity The meter’s kVA. Enrolment requires strictly above 100 kVA.
Credit note The numbered Eskom document that carries the month’s consolidated WER.
Consolidated refund One numbered Eskom credit note per account per month, due in the account’s payment term (45 days by default).
Spill credit The charge category used when uncredited excess is routed to a named trader pool.
:VW_ACCOUNT grain Billing-document identity keyed on the VW account id, so two registrations under one organisation do not collide.

12. Reference card

Seat Path What you are looking at
Organisation /org/virtual-wheeling #org-virtual-wheeling-page Account strip, month’s refund, arithmetic, excess, fill order, members, cite
Eskom /eskom/virtual-contracts VWA register, members, obligation, 45-day aging
Demo build S09 then S10 One portfolio (2 generators, 4 meters, one municipal) and issued refunds
Rule Pin
Mixed grain is refused at join test/wb/wheeling/virtual_wheeling/vw_grain_validator_test.exs
Excess routed only when a pool is named test/wb/wheeling/virtual_wheeling/vw_excess_routing_test.exs
45-day term, never the 30-day fallback test/wb/wheeling/virtual_wheeling/vw_due_date_test.exs
Capacity floor is strictly above 100 kVA test/wb/wheeling/virtual_wheeling/vw_portfolio_membership_test.exs

A wrong refund is credit-noted or versioned. It is never edited in place.

Follow along. Seat: OffTaker C. Path: Organisation → Wheeling → Virtual Wheeling. June 2026 is the settled month. Open Eskom → Virtual Contracts for the same credit note on the other seat.