1. Signing in — the five front doors, in practice
V0 §2 introduced the apps and seats; this chapter is the practical door-by-door walkthrough.
The landing page at / is a centered card titled
“Webill Green” — “Choose your application to sign
in.” — with five dark choice cards:
| Card | Subtitle | What clicking does |
|---|---|---|
| Organization | IPP / Trader / Off-taker | opens the organization picker |
| Eskom | National utility | resolves eskom@webill.net immediately |
| Utility | Local distributor | opens the municipality search |
| Market Operator | SAWEM MO | resolves mo@webill.net |
| System Operator | SAWEM SO | resolves so@webill.net |
- Organization — a dropdown, “Choose an organization…”, listing every organization by name. Picking one resolves its registered user’s email; if none is configured you’ll see “No user is configured for {name}.”
- Utility — a search box, “Start typing a
municipality name…”. Matching is fuzzy (substring plus closeness
scoring), so
tshwanefinds City of Tshwane · Gauteng; the top eight matches appear as you type. Selecting one resolves the municipality’s configured user. - The three operator cards need no picking — their seats are fixed.
Whichever door you choose, the final step is the same small form: the
resolved Email (read-only) and your
Password, posted as a real form submission so the
session cookie is set. On success you land on the app’s home:
/org/configuration, /eskom/virtual-contracts,
/munix/configuration, /mo or /so.
A Back arrow returns to the cards; Switch
application in any app header brings you back here later.
Follow along. Seat: Off-taker C (
offtaker_c@webill.net, passwordsupersecret— demo environments only). Path:/→ Organization → choose OffTaker C → Log in. You should see: the Configuration screen under the “OffTaker C” organization banner.
Careful. Your session carries exactly one context (an
organization, amunicipality, or an operator seat). Every screen re-checks it — opening another organization’s URL by hand redirects you out with a flash, not into their data.
2. Your organization — profile and accreditations
Before you trade a single kilowatt-hour, the platform and your
counterparties need two answers: who you are, and which paperwork you
hold. This screen is where you give them. Open
Organization, the first item in the sidebar
(/org/configuration). Its three tabs split the job:
| Tab | Address | What you keep there |
|---|---|---|
| Organization | /org/configuration |
your profile and your carbon participation |
| Accreditations | /org/configuration/accreditations |
the Eskom and municipal paperwork that lets you trade |
| Feeds & webhooks | /org/configuration/feeds |
the data coming in and the notices your systems receive |
Every tab carries a tooltip naming its purpose; it opens on hover and when you move to the tab with the keyboard. Manual, at the top right, opens the section of this chapter for the tab you are on.
Unsaved work is marked. A form’s Save button stays grey until you change something. Then an amber Unsaved changes chip appears beside it. Switching tabs keeps what you typed. Leaving the screen with unsaved changes asks first.
Errors sit on the field. When a save is refused, the field that needs fixing turns rose, with a sentence under it saying what to enter. The cursor moves there, and a toast at the top right confirms nothing was saved. It stays until you close it.
2.1 Profile
Three facts come first and cannot be edited here: Legal name, Status (Active or Inactive) and Organization type (for example Close corporation (CC)). They are set when the organization is registered. Below them is the form:
| Field | Notes |
|---|---|
| Trading name | the “trading as” name shown on the banner and to counterparties |
| B-BBEE level | your B-BBEE level: Level 1 through Level 8, or Non-compliant. Not recorded clears it. |
| Website | your public address, starting with https:// (for
example https://www.example.co.za) |
Each field’s ⓘ icon explains it. An incomplete address such as
apex is refused at the field. Save writes
immediately (“Organization profile saved.”).
2.2 Eskom trader accreditation
To trade wheeled energy on Eskom’s network you need your Eskom paperwork signed: the Trader Participation Agreement (TPA) and the Balancing & Settlement Agreement (BSA). The card tracks each as a checkbox plus its date:
- Trader Participation Agreement (TPA) + TPA date
- Balancing & Settlement Agreement (BSA) + BSA date
A date belongs to its agreement. It stays disabled until you tick the agreement, then it becomes required. Once saved, a date shows as text with a pencil; press the pencil to change it, or ✕ to cancel the change.
If you untick an agreement that already has a date, the date is struck through with “will be removed when you save.” Keep this date ticks the box again. Save goes ahead only when you mean it, and the confirmation names what was removed (“… The TPA date was removed.”).
The chip beside the heading reads Complete when the accreditation is complete: both agreements ticked and both dated. Otherwise it reads Incomplete, and a line beside it names what is missing (TPA not signed · BSA date missing).
2.3 Municipal accreditations
Each wheeling-enabled municipality you want to trade in needs its own
row: the municipal version of the Eskom paperwork. +
(Add municipal accreditation) opens an inline row. The
municipality list offers only municipalities whose wheeling status is
WHEELING and that you have not already added. When none is
left, + is disabled and its tooltip says No
wheeling municipality left to add. Per row:
| Column | Meaning |
|---|---|
| Municipality | who this accreditation is with. Select the heading to sort A→Z or
Z→A. The order is kept in the address (?sort=desc). |
| Status | Complete or Incomplete, as on the Eskom card |
| On trader register | has the municipality added you to its trader register? |
| Registration date | when |
| Agreement signed | is the municipal wheeling agreement signed? |
| Agreement date | when |
A row is Complete only when both boxes are ticked and both dates are present. As on the Eskom card, a date stays disabled until its box is ticked, and unticking a box clears its date.
2.4 Why this gates everything else
Accreditation is not decoration: the Trader Pools directory refuses to create pools for an unaccredited organization — “The Organization has not been accredited to trade either by Eskom or by any municipality which supports wheeling.” — and counterparties see your readiness when your sites appear in their market search. The gate uses the same rule as the chips: an agreement counts only when it is ticked and dated. Complete this screen before building the rest.
Follow along. Seat: Trader 1 (
trader_1@webill.net). Path: Organization → Accreditations. You should see: a Complete Eskom accreditation, and municipal accreditations for City of Johannesburg and City of Cape Town — Trader 1 is one of the fully-accredited demo seats.
Data. full_demo · seed 42 · stages S01/S03 (foundation & parties) · sealed 2026-07-15.
Business roles and legal form
An organisation can act as an IPP, trader, off-taker, network
operator or BRP service provider, including several roles at once. These
roles are separate from org_type, which records legal form.
An empty explicit role list falls back to owned generator sites,
off-taker sites and trader pools, plus registrations balancing another
organisation’s book.
2.5 Carbon participation
Carbon trading and the carbon-tax pack are optional. An organization joins them by applying to become a carbon participant, and an operator approves the application before the carbon rooms open. The Carbon participation card on the Organization tab is where you apply.
flowchart LR
A[Apply to participate] --> B[Confirm: Send application]
B --> C[Pending approval]
C -->|you withdraw| A
C -->|operator activates| D[Active]
C -->|operator refuses| E[Refused]
- Press Apply to participate. A panel explains what happens next; nothing is sent yet. Cancel closes it.
- Press Send application. The chip reads Pending approval (“Carbon participant registration submitted for operator review.”).
- While it is pending you can press Withdraw application, then Withdraw application again to confirm (Keep it backs out). Nothing has been activated, so you can apply again later.
- When an operator activates it, the chip reads Active and the carbon rooms appear in the sidebar. Once an operator decides, the application can no longer be withdrawn.
Where this is taught. The operator’s side, Activate and Refuse, is V11 §12. The tax year the profile unlocks is V20.
2.6 Feeds and webhooks
The Feeds & webhooks tab answers two questions: is our data arriving? and which of our systems hear about events here? Data feeds lists each meter and weather feed by name, with its key, a status chip (Receiving, Stale, No data yet, Refused, Upload on demand or Simulated) and its interval. Webhooks lets you register an HTTPS address for your own systems, choose its topics, and pause, rotate, delete or restore it later. Recent deliveries shows what was sent.
Where this is taught. Feeds, webhooks, topics, signing secrets and dead letters are taught in V21 §11, including how to create a webhook.
3. Off-taker sites — the buy side
An off-taker site is a place that consumes energy and wants to buy it wheeled. Its record answers four buyer questions the rest of the platform keeps asking: where and how is it connected (network, voltage, municipality), how much does it use (the demand estimates and its meter), and what does it want commercially (tariff preference, spill treatment, contract horizon), and what must be carried into a proposal (wheeling deposit position and the preferred remedy if supply falls short).
Where this is taught. The directory table, each column, and Portfolio summary & coverage notes: V5 §2.1. Who Needs attention keeps, and where Next step sends you: V5 §2.1.5. Creating a site on the OffTaker seat (every section, field, and refusal): V5 §2.3. Demand classes, spill as an object, and Edit: this chapter.
3.1 The directory
OffTaker Sites (/org/off-taker-sites)
is a table of registered consumption sites. Search, status, network, and
sort sit above it. Portfolio summary & coverage
notes is folded underneath.
Where this is taught. Every column header, the optional price and PPA columns, Needs attention, and the four summary tiles: V5 §2.1.
Site details
(#offtaker-workspace-details) opens the record drawer
(#offtaker-site-details-drawer) from a site you have
already opened. The drawer carries that site’s plumbing, including the
Trading Unit and network zone when they exist, the short verdict, and
Edit & complete site record. Close it with the X,
Escape, or the dimmed backdrop. The directory table has no BRP column. A
missing zone or Trading Unit is a warning under the site name, taught in
V5 §2.1.5.
3.2 Creating a site — the wizard, step by step
Add New Site
(#open-off-taker-site-wizard) creates a draft and opens
/org/off-taker-sites/onboarding/<id> — a
seven-section workspace, not the older six-step modal.
Where this is taught. The OffTaker-seat walk — every word, click path, section, field, refusal, draft rail, and what “done” looks like: V5 §2.3.
This chapter keeps the entity rules that workspace writes and that Edit still lets you change.
On create, Facility category plus Network service provider become the site’s Strategy Demand Classes — the tags that decide which trader-book demand pools may pick the site up. You do not tick those classes on the create workspace. The write-down is:
| Facility category | Classes written |
|---|---|
| Manufacturing · Mining · Cold storage | Industrial |
| Office · Retail · Hospital · Mixed use · Residential · Other | Commercial |
| Any category and Municipality connection | the row above, plus Municipal |
Trader Sales is not applied on create.
On Edit, a category change adds the recommended class(es) without wiping extras you already selected. There is no separate checkbox row on the onboarding workspace.
Note. A trader pool only accepts the site when at least one of these classes intersects the pool’s Demand roles (§5.3). Selecting both Industrial and Municipal widens which municipal and industrial books can pick you up.
Spill treatment on the site is an opening preference, not a signed rule. The same leftover energy can be written off, credited cheap, or banked:
Where this is taught. How settlement applies spill, banking and shortfall on a matched interval: V8 §2 · V8 §7. The create workspace fields: V5 §2.3.
3.3 Editing, and what locks
Edit (#off-taker-site-edit-<id>
in the detail drawer) opens the same onboarding
workspace used to create a site,
/org/off-taker-sites/onboarding/<id>, prefilled from
the live shop. The page shows an Editing chip
(#off-taker-onboarding-edit-badge) and Save
changes instead of Create off-taker site. Save
writes that site. It does not open a modal and it does
not create a second shop.
Think of it as taking the shop’s existing card back to the desk to correct a stamp — not starting a new card.
Two facts stay locked after registration:
| Locked | What you see |
|---|---|
| Network service provider | Eskom / Municipality shown as selected but not changeable |
| Physical address & location | map still shows the pin and municipality panel; address search and site-pin click/drag are disabled. You can still move the meter-point. |
Everything else remains editable across the same sections — site name and public flag, Eskom / VWA paperwork, voltage, meters and tariff, business category (which may add recommended Strategy Demand Classes without wiping extras), consumption estimates, preferences (including deposit status and shortfall remedy), and RECs.
Save & exit returns to
/org/off-taker-sites with the site still there. An edit
session does not appear on the amber Off-taker
site drafts rail — that rail is only for unfinished new
shops.
Where this is taught. The create walk (sections, fields, refusals): V5 §2.3.
3.4 BRP — Trading Unit and zone
Each site row carries a BRP column. The cell is blank until the organisation is an ACTIVE Market BRP with a BRP reference — a filed application that is still pending does not unlock it.
Once that seat is active: if the site is registered as a demand-side
Trading Unit, the cell shows the
TUID above the network zone (same colour swatch as
the SO/MO zone register). Click either to open
/org/trading-units.
If the site is not in a published network zone, the cell says No Market Zone instead of offering registration.
If there is no TUID and the site is allocated, Add Trading Unit opens a modal wizard — header BRP Standing Data OffTaker Registration, steps Identity · Zone · Delivery · Demand · Finance — that files §7.2 standing data and creates the demand-side unit.
Where this is taught. Every tab, every input, and the Market Operator inspection boards: V9 §3.9B.
Where a registered site’s location is not covered by the map, the zone line says Unassigned and names the nearest zone. A notice above the table explains what that blocks. The nearest zone is deliberately not used as an assignment: putting the site there would place it in the wrong balancing group.
Nothing about the site itself changes, and nothing about today’s trading is affected until the unit is registered. The full zone treatment is V12 §2.
3.5 What the market registry adds to a site
A site’s zone decides which market registration it can belong to. Its meter decides something else: who the market thinks is on the other side of the energy.
Every metering point registered in the market carries a counterparty — the party buying what you sell or selling what you buy through that meter. The platform derives it from your signed PPAs, so for a site with contracts in place there is usually nothing to enter. Two situations do reach you:
- A meter with no counterparty cannot be settled. If no signed contract names anyone at that point, the market registry shows it empty and lists it as an exception rather than guessing. The fix is a contract, not a form.
- A declaration can arrive naming you. When the party on the other side registers the meter first, you get it in a counterparty inbox to confirm or dispute. Leaving it unanswered leaves the point unsettleable for both of you.
Both live at BRP / Market → Market registry, taught in V9 §3.
3.6 What your consumption is worth, and to whom
This screen records how much the site uses. The wholesale market asks a second question: what each slice of that consumption is worth to you.
A consumer in the market can publish a ladder — this much I will drop readily, this much only at a real cost, this much only at severe cost, and this much I cannot drop at all. The market curtails from the cheapest rung down, so a site that publishes a genuine ladder gets paid when the market wants its flexibility.
Declaring the whole consumption must-serve is a real choice, and usually the right one. For most industrial loads there is no flexibility to publish, and the platform makes that one setting rather than a form to fill in. Being wrong in that direction only forgoes revenue. Being wrong the other way — publishing flexibility the site does not have — means being shed and unable to comply.
Two fields on this screen feed it: curtailment acceptance is the nearest existing signal of whether a ladder is even possible, and the site’s current tariff is the defensible starting point for what the rungs are worth. Neither is the answer: what a process is actually worth is a commercial conversation with the site, and the platform records which question was answered so a curtailment can be argued afterwards. Taught in V9 §3.
Careful. Connection type and physical location cannot change after registration — network matching and commercial scope were fixed against them.
Follow along. Seat: Off-taker C (
offtaker_c@webill.net). Path: OffTaker Sites. You should see two sites: OffTaker C Midrand DC (Cold Storage, Municipality/Johannesburg, 22kV, private, active) and George Eskom Plant (Manufacturing, Eskom, 22kV, public — with the full ESA/VWA registration story). Contracted counts are non-zero: this seat carries the rich settlement story.
Data. full_demo · seed 42 · stage S03 (parties) · sealed 2026-07-15.
4. Generator sites — the sell side
A generator site is an IPP’s plant. Its record carries everything a buyer, a network operator and the settlement engine will later rely on: the technology and its capacities, the grid connection and its paperwork, the transformer, the expected yield and its TOU shape, and the revenue meter.
Organisation ownership also drives the site’s effective-dated fleet membership. The membership begins no earlier than commercial operation and closes on an exclusive departure date; closing it preserves the site’s own record and strategy history. See V4 §2.
4.1 The directory
IPP Sites in the sidebar — its label reads
IPP Sites (n), where n is every generator site
the organisation holds, whatever its status (Active, Open, Inactive or
Closed) — opens the room on the Fleet tab
(/org/ipp-sites), the four-chapter portfolio story taught
in V4 §2.
Switch to Sites (/org/ipp-sites/sites) for
the register — the tab tooltip reads The register of generator sites
— which site needs you, and where to go. The tab label carries the
same count as the sidebar, for example Sites (7);
OffTaker Sites (n) and Trader Pools
(n) count every site or pool in the same way. The browser tab
reads Sites · IPP Sites · Webill Green.
The header is the same on both tabs: the heading IPP
Sites, one line (here Your generation sites, their status,
and the next step.), and on the right Import
intervals (#open-interval-import, a modal — §7.7) and the round
+ (#open-ipp-site-wizard). Its tooltip,
Add New Site, opens below the button, so it never covers
Import intervals. The + opens a blank
onboarding form; no draft exists until you save a first answer (§4.3).
Drafts. Unfinished registrations sit above the
register under IPP site drafts, one card each: the
draft’s name and N of 6 core sections, then its project stage
when one is set — for example 2 of 6 core sections · Grid
application. Click a card to resume at
/org/ipp-sites/onboarding/{id}. The old address
/org/ipp-sites/drafts opens this same register, and a
site’s quick view opens there just as it does here.
Search, attention and filters. One row of controls sits above the table:
| Control | What it does |
|---|---|
Search sites… (#ipp-sites-search) |
Matches a site’s name, technology and address. When only the address matches, the row adds a line Matched address: {address} so the hit is not a mystery. Pressing Enter does not reload the page |
Needs attention n
(#ipp-sites-attention) |
Shows only flagged sites; press again (×) to show all. While the register is still loading, the count is a pulsing placeholder, never a false 0 |
Filters & columns
(#ipp-sites-filter-toggle) |
Opens Status
(#ipp-sites-status-filter: All statuses · Active · Open ·
Inactive · Closed), Technology, Sort
(Attention first · Name A–Z · Name Z–A) and the checkbox Show
price, revenue & PPAs |
Clear filters
(#ipp-sites-clear-filters) |
Appears with Filtered view once any filter is on. It resets every filter and empties the search box, so the old text does not come back on the next filter change |
A site needs attention when it has an export-limit (MEC) finding, a missing Trading Unit registration, a market-zone problem, or more than half of its energy unsold. A site that simply has no buyer yet is not flagged: its Next step is Set up sales. The fold How to read this, under the table, says the same, and adds that a search also matches a site’s address.
The register table (#ipp-sites-table).
One row per site:
| Column | What it shows |
|---|---|
| Site / capacity | The site name (press it for the quick view), then the technology in
words — Solar PV, Wind,
Battery storage (never BESS) — with the
capacities, place and contract count, for example
0.5 MWp / 0.5 MWac (a fractional capacity keeps its
decimal). Amber warnings follow when they apply: MEC breach,
Trading Unit registration missing, No Market Zone |
| Status | Active, Open, Inactive or Closed, with a green dot while Active (§4.8) |
| Sold · forecast | The share of the site’s energy sold in its latest forecast, or a dash when it has none |
| Realised · c/kWh · Revenue · P50 · PPAs · Virtual PPAs | Only with Show price, revenue & PPAs on. PPAs and Virtual PPAs count signed and active agreements and link to them in Deals |
| Next step | One link to the screen that fixes the row: Review export limit, Review unsold energy, Review registration, Set up sales, Run forecast or Review performance |
The table scrolls with the page, so every row is reachable, and its header row sticks flush to the top of the page as you scroll. With Show price, revenue & PPAs on, the wider table keeps its own scroll box (up to 70 % of the window’s height) so it can also scroll sideways; the header then sticks to the top of that box. Under the table: N of M sites, How to read this, and Portfolio summary & coverage notes — the same strip as the Fleet tab’s Registered sites · sales snapshot (V4 §2.1).
The quick view (#fleet-detail-drawer).
Pressing a site name opens a right-hand drawer with the branded header —
eyebrow Generator site · quick view, the site name, a
status and a technology chip, and X. Inside: the
subtitle, a one-line verdict written from the numbers, the forecast
snapshot date and the site’s vitals. The verdict counts contracts, not
buyers, because one buyer can hold several — Sells 4 % of its energy
under 4 contracts at 85 c; the rest spills at the spill value. …,
or with no contract at zero. Also needs
attention lists the row’s warnings with Review details
→, and the fold What these figures mean
explains the vitals. The footer holds the row’s next step and
Open site workspace. Escape, the backdrop, or
X closes it.
The site workspace
(/org/ipp-sites/sites/{id}/{tab}) is where one plant’s work
happens — Operations, Performance, Allocation, Commercial and Dashboard,
mapped to their chapters in V4 §3.
Site details, top right, opens the site’s market
plumbing — the MEC breach and No BRP badges when they
apply and the BRP cell (§4.4) — then the complete site
record with Edit complete site record (§4.3), and the fold Site
lifecycle & fleet membership: Activate /
Deactivate (§4.8) and
Record departure (V4 §2).
The fold stays open after you press one of its buttons.
4.2 Creating a site — the wizard, step by step
Careful. Add New Site (the round + on IPP Sites) no longer opens the six-step wizard below. It opens a blank generator-site onboarding form at
/org/ipp-sites/onboarding/new, and nothing is saved until you enter the first answer (§4.3). The step tables in this section are kept as a field reference for the plant facts the platform asks for; on screen they sit in the onboarding form’s sections, and Create open site record on its readiness gate takes the place of Register IPP.
Think of the steps as answering six plain questions buyers and the network will ask later: where is the plant and on which network, which meter proves the export, what kind of plant and how big, how does it step up to the grid, how much energy does it typically make and when, what paperwork proves it may inject, and how it intends to handle excess energy, RECs, and the wheeling forecast in a proposal.
Step 1 · Site Details — Location, network & plant life.
| Field | Notes |
|---|---|
| Site Name * | human label for the plant (e.g. Tshwane Solar Park) |
| Connection Type * |
card pick — who owns the wires you inject into:
|
| Physical Address & Location * | type-ahead address search plus a click-to-place map pin; the pin resolves province, municipality and its wheeling status automatically. The side panel also shows GPS and, for Eskom, whether the chosen generator voltage looks like Transmission or Distribution |
| COD * | commercial operation date — the day the plant is (or will be) commercially online |
| Lifetime (years) * | how many years the plant is expected to run; the wizard shows the computed end-of-life date (= COD + lifetime) |
| Generator Connection Voltage |
optional — voltage at the grid injection point; informs the Eskom
Transmission vs Distribution hint. Options:
|
| Publicly listed site |
toggle (default on):
|
Careful. If the map pin lands outside any municipality, the wizard forces Connection Type to Eskom — there is no municipal network to connect to. The eligibility banner then tells you whether wheeling can work at this location (municipal sites need a municipality whose wheeling status is active).
Step 2 · Meter Details — Who measures the export. Typing a new number is registration: on Register IPP the wizard creates each device (or links an existing one you searched) and attaches the primary meter to the site.
| Field | Notes |
|---|---|
| Primary meter number * |
the revenue meter identifier (e.g. MTR-NERSA-GEN-…). Type ≥
5 characters and Search to pick an existing org meter,
or leave a new number and choose manufacturer/model so the wizard
creates it
|
| Meter manufacturer · model | optional — from the manufacturers registry; model list narrows after manufacturer |
| Check meter number | optional check meter — an independent second meter for verification; leave blank if you have none |
| Check meter manufacturer · model | same pattern as the primary; only needed when a check-meter number is entered |
| CT ratio · VT ratio | current- and voltage-transformer scaling for the metering installation (defaults 1.0). Must match the installation record filed with the network operator; NRS 057 expects class 0.2S / 0.5S revenue instruments |
Note. Check meters are recommended by NERSA for wheeling above about 1 MW. The site’s consumption explorer and settlement still read the primary meter; the check meter is the independent second witness.
Step 3 · Connection — What kind of plant, which trader pools it may join, and how big it is.
| Field | Notes |
|---|---|
| Technology Type * |
card pick — choosing one applies sensible capacity defaults and
recommends Strategy Supply Class(es) without wiping
extras you already selected:
|
| Strategy Supply Classes |
select all that apply — checkbox cards; a plant can
join more than one trader-book supply pool:
|
| Installed Cap. (MWp) * | nameplate DC size of the plant (panels STC, turbine rated MW, or BESS max DC discharge). Always ≥ Export Cap. — DC is clipped by inverters and the grid limit. i tooltip on the field |
| Export Cap. (MW) * | maximum AC power you may inject at the connection point — the hard ceiling for wheeling contracts. Also drives P50: Export × 8 760 × (Capacity Factor ÷ 100). i tooltip |
| Inverter Cap. (MVA) | total inverter fleet rating (real + reactive). At unity power factor MVA ≈ MW; if this sits below Export Cap., inverters become the binding export limit. i tooltip (left) |
Note. A trader pool only accepts the plant when at least one of these classes intersects the pool’s Supply roles (§5.3). Adding Flexible beside Firm widens which dispatchable books can pick you up.
Step 4 · Business — The step-up transformer. All fields required. Choosing Voltage Category cascades the allowed ratios, ratings and vector groups so you cannot pick an illegal combination.
| Field | Notes |
|---|---|
| Voltage Category * |
high-level step-up class — drives which voltage ratios, ratings, vector
groups and cooling options appear; must match the approved single-line
diagram. i tooltip. Options:
|
| Voltage Ratio * | primary / secondary voltages on the transformer (e.g. 11 kV / 22 kV). Offered list depends on Voltage Category; must match the network boundary voltages in the connection approval. i tooltip |
| Transformer Rating * | nameplate MVA of the unit — offered per Voltage Category (e.g. LV→MV up to ~10 MVA; MV→HV up to ~63 MVA). Can limit Export Cap. i tooltip |
| Vector Group * | winding connection and phase-shift code from the SLD (e.g. Dyn11). Options cascade with category (Dyn / Yyn / Yd / Ynd families). Used for protection coordination and parallel operation with the network |
| Impedance % * | short-circuit impedance offered for the chosen rating — used in network studies |
| Cooling Type * |
how the transformer sheds heat — affects thermal rating and overload
capability. i tooltip (left). Options:
|
| Ownership | fixed to IPP — the platform’s wheeling model assumes the generator owns its step-up transformer; you cannot select Eskom or Municipality here |
Step 5 · Consumption — Expected yield and when it arrives (optional to skip, but do it — strategy and contracting lean on these numbers). The banner says so: correctly completing this step feeds a recommended tariff structure when you later deal with a trader or off-taker.
| Field | Notes |
|---|---|
| Capacity Factor (%) * | slider — what share of “full export, all year” the plant actually delivers. Open the CF Calculator drawer (calculator button beside the field) to derive it from a metered sample — see CF Calculator below. Typical solar defaults around 22 %; wind around 40 %. Technology suggestion ranges appear under the slider. i tooltip |
| P50 Annual Energy Yield (MWh) * | annual energy with a 50 % chance of being exceeded over the plant life — the number counterparties use for PPA sizing. With Auto-calculate on: Export Cap. × 8 760 × (CF ÷ 100). i tooltip |
| Generation split CSV |
optional — click or drag-and-drop a .csv only. Required
columns: date_time_stamp (aliases:
date_time_Stamp, datetime_stamp,
date_timestamp), peak_kwh,
standard_kwh, off_peak_kwh. Invalid format is
discarded with listed issues. Valid files sum energy
per TOU bucket and set Peak / Standard / Off-Peak % (must total 100).
Download demo CSV fetches
priv/data/offtaker_consumption_data.csv
|
| Peak % · Standard % · Off-Peak % |
how annual energy splits across Eskom’s three time-of-use buckets.
Must sum to exactly 100 %. The three buckets:
|
CF Calculator
Why it exists. Capacity Factor is the share of “full export, all year” the plant really delivers — counterparties and P50 sizing lean on it. If you already have interval generation readings (SCADA, meter extract, or a commissioning sample), the CF Calculator turns that sample into a suggested % instead of guessing the slider.
Click CF Calculator beside Capacity Factor. A drawer opens from the right. On open it seeds Generation Power as Export Cap. × (current CF ÷ 100) with a 15-minute interval and 24 sample hours — a starting point you replace with your metered numbers.
| Input | What it is |
|---|---|
| 1. Data Reading Interval (Minutes) | length of each generation reading in the sample. Options: 5 (ratio 0.0833), 10 (0.1667), 15 (0.25, default), 30 (0.5), 60 (1.0). The interval ratio scales average power into energy for that reading length |
| 2. Total Hours in Sample | how long the sample covers (e.g. 24 for one day, 168 for a week) |
| 3. Generation Power (MW) | average AC export power over that sample (not nameplate Installed Cap.) |
| (from Step 3) Export Cap. (MW) | baseline ceiling — read-only in the results panel; theoretical full-export energy for the sample is Export × Hours |
What it calculates
- Actual Energy (MWh) — Interval Ratio × Generation Power × (60 ÷ Interval × Hours)
- Capacity Factor (%) — Actual Energy ÷ (Export Cap. × Hours) × 100, then clamped to 0–100
Apply to Wizard writes the rounded CF onto the slider and, when Auto-calculate is on, refreshes P50. Cancel closes without changing the step.
Follow along. Seat: IPP 2 (
ipp_2@webill.net). Path: IPP Sites → Add New Site → Step 3 set Export Cap. 60 MW → Step 5 → CF Calculator. Enter Interval 15, Hours 24, Generation Power 18. You should see Actual Energy 432 MWh, Capacity Factor 30.0 %. Apply to Wizard sets the slider; with Auto-calculate on, P50 becomes 60 × 8 760 × 0.30 = 157 680 MWh.
Note. Generation Power is the average export over the sample, not a single peak reading. A sunny midday spike alone will overstate CF; use a full day (or longer) that matches how the plant usually runs.
Careful. If Peak + Standard + Off-Peak ≠ 100 %, the step stays incomplete and Register IPP stays disabled. Solar plants put little energy into night Off-Peak; wind and BESS look different — that is why the presets change with technology.
Step 6 · Preferences — Grid paperwork, NERSA licensing & proposal inputs. Which connection-reference fields appear depends on Connection Type from Step 1. The commercial and forecast choices are recorded once on the plant and provide the starting position for each physical-PPA proposal; the final contract terms remain negotiable.
| Field | Notes |
|---|---|
| Grid Connection Status |
card pick — how far the plant is along the connection journey:
|
| (Eskom only) Grid Connection Approval * | approval reference for the connection |
| (Eskom only) CUOSA Reference * | Connection and Use of System Agreement number issued by Eskom. i tooltip |
| (Eskom only) Regulator Code Date * | when the IPP achieved compliance with the relevant Grid Code. i tooltip |
| (Municipality only) Municipal Connection Agreement * | the municipal connection agreement reference instead of the Eskom trio |
| Excess Generation Preference * |
the seller’s default commercial treatment for energy that cannot be
delivered to its PPA buyer:
|
| Eskom Buy-back Status * | the factual status of the arrangement that makes Eskom buy-back available: No arrangement, Application pending, or Active. Choose Active only once the signed arrangement is operational. |
| REC Registry * | where the plant issues renewable-energy certificates: Not registered, ZARECS, I-REC, or a supported Blockchain registry. Not registered is an explicit answer; it stores no registry on the plant. |
| Wheeling Forecast Status * | the status of the three-year wheeling forecast required by the network operator: Submitted, Pending, or Not required. Pending is not a confirmation that the registration condition has been met. |
| Schedule 2 Exemption |
toggle (default on):
|
| (if not exempt) NERSA License Number , Issue date , Expiry date * | required together when Schedule 2 is off |
Note. Schedule 2 on means the licence fields must stay empty; Schedule 2 off means all three licence fields are required — the wizard will not let you mix the two.
On the onboarding form, Create open site record on the readiness gate registers the site once the six core sections are complete (§4.3) — Open, or Active when the project stage is Operational; §4.8 explains when and how you promote it. The form’s Identity map can also place a point of connection away from the plant pin — §4.3A.
4.3 Editing, and what locks
One form creates and edits every generator site: generator
site onboarding (/org/ipp-sites/onboarding/…). It
has eight sections — Identity & location,
Plant & technology, Connection &
network, Metering, Regulatory
evidence and Generation profile (the six core
sections), then Market standing data and
Commercial defaults (optional). Complete them in any
order; each section saves on its own.
A new site starts blank. Add New
Site — the round + on either IPP Sites tab —
opens /org/ipp-sites/onboarding/new. The click creates
nothing, and the page says so: the eyebrow reads NEW GENERATOR
SITE, there is no Draft chip in the top bar
yet, the save state beside the progress bar reads Not saved yet ·
your first answer starts the draft, and the box beside it reads
Nothing saved yet — Create site unlocks once the 6
core sections are complete. The browser tab reads New IPP site
· IPP Sites · Webill Green. Then:
flowchart TB
A[Press the round plus] --> B[Blank form at onboarding/new]
B --> C{First answer entered?}
C -->|No, then Save and exit or Cancel| D[Nothing kept, back to Sites]
C -->|Yes| E[Draft created]
E --> F[Address becomes onboarding/draft id]
F --> G[Draft listed under IPP site drafts]
G --> H[Review readiness]
H -->|Six core sections complete, no values to fix| I[Create open site record]
- Moving between sections of a blank form saves nothing, and neither does ticking a map box or Same as site location, or pressing Check & mark complete. Only an answer does.
- The first answer you enter creates the draft. The address changes to
the draft’s own
/org/ipp-sites/onboarding/{id}, so a reload or the back button returns to the saved draft. It now appears under IPP site drafts on the register, and the browser tab reads {name} · IPP site draft · Webill Green. - Before that first answer, Save & exit says Nothing was entered, so no draft was kept. and Discard is a plain Cancel button (no confirmation) that says Nothing was saved, so there was no draft to discard. Once a draft exists, the top bar shows Draft, Save & exit says Draft saved. Resume it from IPP site drafts., and Discard asks first and deletes the saved draft.
- The progress line reads N of 6 core sections complete · 2 optional. The box beside it reads Draft saved — N sections to finish before the site can be created — until nothing is left, when it reads Ready to create site — The core sections are complete and their values check out. Only the six core sections move the bar, so it can reach the end while the two optional sections are still empty.
- Review readiness opens the readiness gate, a modal with the branded green header: eyebrow READINESS GATE, title Create generator site (or Save generator site when editing), and a close X labelled Close readiness review. Escape closes it too, and keyboard focus stays inside it while it is open.
- The gate lists all eight sections with their status — a section with a value to fix shows Fix values (§4.3B). Every row is a button: press one and the gate closes and that section opens. While core sections are missing, the amber note reads The draft is safe, but not ready. Open a section below to finish it. — or, on a blank form before the first answer, Nothing is saved yet. Open a section below to start; the draft is kept from your first answer. Both then say that late-stage evidence is requested only when the selected milestone makes it applicable.
- When the six core sections are complete and no section has a value to fix, Create open site record creates the site — Open, or Active when Project stage is Operational (§4.8). The button sits in the gate’s footer, below the list, so it stays in view on a short window.
Moving through the sections. Each section’s header counts Core section N of 6 or Optional section N of 2, the same way the progress bar does. On a window 1,280 px wide or more, the Site checklist sits beside the form and stays in view as you scroll. On a laptop-width window it sits above the form as a compact two-column grid of section names and statuses, so the form starts near the top. Either way, picking a section brings the form into view. At the foot of every section, Next: {next section} opens the next one, and the last section offers Review readiness instead. A saved draft reopens on its first unfinished core section, not on the last one you visited; if the connection drops and the page reconnects mid-edit, you stay where you were.
Explanations, at the top right of each section, opens plain-language notes on that section’s fields; press a choice to fill the field. On a wide window the panel sits beside the form, and the checklist shrinks to a column of section icons, each with a status dot — hover or focus one for its name and status. On a narrower window the panel opens over the page with a dimmed backdrop. X, the backdrop or Escape closes it. A label with an ⓘ explains its term on hover or focus — among them COD (commercial operation date), MEC (maximum export capacity), NMD (notified maximum demand), CUOSA (the connection and use-of-system agreement with Eskom), Nameplate basis (for solar, DC STC: the panels’ direct-current rating under standard test conditions) and Three-year forecast status.
Market standing data has no form and no Check & mark complete. It explains that the market registry keeps each unit’s market facts and versions every change, links to it with Open market registry, and offers Next: Commercial defaults.
Editing a live site. Edit complete site record, in the site workspace’s Site details (§4.1), opens the same form already filled from that plant — name, technology, capacities, meters, yield and the other sections you have on file. The browser tab reads Edit {name} · IPP Sites · Webill Green. Saving writes the same site; it does not register a second plant.
Address search and plant map clicks stay locked
after registration — you cannot move the generating-plant pin. The
Site and Point of connection overlay
ticks stay live so you can hide a marker or still place the electrical
node (§4.3A).
Network service provider (#onboarding-nsp)
on Connection & Network lists
Eskom and, when the plant pin is inside a municipal
boundary (or you have not placed a pin yet),
Municipality. On a new draft you choose the operator
there. After registration, Save changes does not
rewrite the live site’s connection type — the wires you already filed
stay. Everything else (name, meters, technology and capacities,
transformer, yield/TOU, regulatory references, excess-generation
preference, buy-back status, REC registry and wheeling forecast status)
stays editable. Save changes on the readiness gate
writes the update. Add New Site always starts a blank
form; only Edit complete site record reuses a live
site.
4.3A The identity map — plant and point of connection
The generating plant is not always where it meets the wires. Think of the plant as the house and the point of connection as the meter box on the street pole: often nearby, sometimes a substation down the road. Buyers and the network need both pins — the house, and the pole.
On generator-site onboarding
(/org/ipp-sites/onboarding/…) the Identity &
location section has one map. Two tick boxes sit above the
canvas (#onboarding-map-overlay). They are ordinary form
checkboxes — brand green when on — not the Deals / Contracts tab bar.
Each box only shows or hides its marker. Unticking does
not clear the longitude or latitude fields; tick again and the same pin
comes back.
Tick (id) |
What it shows | What a map click does while it is on |
|---|---|---|
Site (#map-show-site) |
The generating-plant pin (amber circle marked S) | If Point of connection is off, and the plant is not locked, a click places or moves the plant. That fills the physical address, province or state, plant longitude / latitude, and — in South Africa — municipality |
Point of connection
(#map-show-poc) |
The electrical-node marker (indigo square marked P) | A click places or moves the node. That fills Point of connection longitude and Point of connection latitude only — the plant pin stays put |
Both ticks start on. You may turn either off, or both. A click prefers the node whenever Point of connection is ticked. If both are empty, a click does nothing.
A point of connection is the electrical node where this plant meets the network. The two coordinate fields under the map are read-only: you do not type them. They follow the square marker.
If there is no square marker yet — a new draft before an address, a draft whose address was cleared, or Edit on a live site (Edit prefills the plant pin, not a separate node) — leave Point of connection ticked and click the map. The square marker appears at the click. The longitude and latitude fields update to that click. Click again, or drag the square, to move it.
Same as site location
(#poc-same-as-site) is a tick box under the hint. Tick it
when the electrical node is the plant: the square jumps onto
the amber site pin, and the two POC fields copy the plant longitude and
latitude. The tick is brand green when on — the same checked look as
every other form checkbox. If the plant pin is not placed yet, the box
stays empty and a flash says to place the site pin first; the form does
not invent a node.
Type at least six characters in Physical address for suggestions. The arrow keys move from the box into the list and back, Enter picks the highlighted suggestion, and Escape returns to the box.
When you first pick a physical address, the node defaults to the plant and the box is ticked. That is a starting guess, not a locked answer. Click or drag the square somewhere else and the box unticks. Tick it again to snap back to the plant.
After registration, Edit still locks address search and the plant pin. Point-of-connection clicks and Same as site location stay allowed — the plant pin does not move; the node can still match it or sit apart.
On Connection & Network, Network service
provider (#onboarding-nsp) is a select, not a
locked empty box. Eskom is always listed.
Municipality appears when you have not placed a plant
pin yet, or when that pin sits inside a municipal boundary that wheels —
the same rule as Connection Type in §4.2. A pin in
open country lists Eskom only.
flowchart TB
A[Open Identity and location] --> B{Is the node on the plant?}
B -->|Yes| C[Tick Same as site location]
C --> D[Square sits on the plant pin]
D --> E[Longitude and latitude copy the plant]
B -->|No, or no square yet| F[Leave Point of connection ticked]
F --> G[Click the map or drag the square]
G --> H[Fields follow the click]
G --> I[Same as site location unticks]
- Open IPP Sites and press the round + (Add New Site), resume a draft, or press Edit complete site record in a site’s Site details.
- Stay on Identity & location.
- If the node is the plant, tick Same as site location.
- Otherwise leave Point of connection
(
#map-show-poc) ticked. - If the canvas has no indigo square, click the map once.
- Read Point of connection latitude and Point of connection longitude — they now match that click, and the tick box is empty.
- Open Connection & Network and choose a Network service provider — at least Eskom is in the list.
Follow along. Seat: IPP 2 (
ipp_2@webill.net). Path: Organisation door → IPP Sites → + (Add New Site; or Edit complete site record in a site’s Site details) → Identity & location. Tick Same as site location after the plant pin is set — the indigo P square sits on the plant and the fields match. Then click away from the plant while Point of connection is ticked: the box unticks and the fields follow the new click. Untick Site or Point of connection — the marker hides, the numbers stay. Open Connection & Network and open Network service provider (#onboarding-nsp) — Eskom is there to choose.
Note. The overlay ticks and the separate node live on the onboarding form — for a new site and on Edit.
Where this is taught. Who owns the wires: §4.2. What Edit locks: §4.3.
4.3B When a section counts as complete
The form saves as you type, so it also saves a typing slip: an operating life of −5 years, or more export than the plant has installed. A checklist that only asked “is it filled in?” would pass those, and the site would be created with numbers nobody can use. So a section counts as complete only when every required answer is in and its values check out.
Fix values. A value that fails a check keeps its message under the field as soon as it saves. The value is still saved, so nothing you typed is lost. The section shows Fix values in the Site checklist and on the readiness gate, and Create open site record waits until it is fixed. Correct the value and the section moves on by itself. When you edit a live site, Save changes stays off while any section shows Fix values; a blank field on an older record does not hold it back.
A blank field is never a failed check — it is still needed. Only the fields your chosen technology or pathway shows are checked, so a value left behind by an earlier choice cannot block a section.
| Section | What is checked |
|---|---|
| Identity & location | Operating life is a whole number of years from 1 to 100 |
| Plant & technology | Installed, export and converter capacity are more than 0. Export is no more than installed capacity, and the converter (MVA) is at least the export capacity (MW). Batteries: round-trip efficiency 50–100 %, maximum SoC above minimum SoC. Thermal plants: heat rate at least 3.6 GJ/MWh, minimum stable load no more than installed capacity |
| Connection & network | MEC and NMD are not negative; transformer impedance is above 0 % and at most 100 % |
| Metering | CT and VT ratios are more than 0 |
| Regulatory evidence | The issue date is not before the application date; a generation licence expires after it is issued |
| Generation profile | Capacity factor above 0 % and at most 100 %; P50 and P90 more than 0; P90 no more than P50; P50 no more than the plant could make at full power all year (installed MW × 8,760 h); losses, degradation and auxiliary load 0–100 %; once any time-of-use period is entered, peak, standard and off-peak add up to 100 % (±0.5) |
| Commercial defaults | Minimum insurance cover and the plant emissions factor are not negative |
Check & mark complete is the question “is this section done?”, with the answer given beside the button you pressed:
flowchart TB
A[Press Check and mark complete] --> B[Section saved]
B --> C{Every required answer in, every value checks out?}
C -->|Yes| D[Green note: the section is complete]
C -->|No| E[Rose note above the button]
E --> F[Press a name to jump to its field]
F --> G[Fix it, and the note updates as you type]
G --> C
- The button, at the foot of each section, saves the section. On a blank form it saves nothing and only shows what the section needs.
- When the section is done, a green note above the button reads {Section} is complete. Every required answer is in and the values check out. An optional section reads {Section} checks out. It is optional, so nothing here holds back the site.
- Otherwise a rose note counts what is left — for example 4 answers still needed and 1 value to fix — then lists Still needed:, each blank answer as a small button, and To fix:, each failing value. Press any of them to jump to that field.
- Every blank required field in the section is marked Required at once, so you see the whole list rather than one browser bubble at a time.
- The note follows your edits: fix the last item and it turns green.
When two answers disagree. Capacity factor and P50
describe the same year’s energy twice, so the form compares them. Take
10 MW installed at a 25 % capacity factor:
10 × 8,760 × 0.25 = 21,900 MWh a year. If P50 says 1,000
MWh, the Generation profile shows an amber note: A 25 % capacity
factor on 10 MW installed comes to about 21,900 MWh a year, but P50 is
1,000 MWh. Check that both describe the same plant. Two buttons fix
it either way: Set P50 to 21,900 MWh, or Set
capacity factor to 1.1 %
(1,000 ÷ (10 × 8,760) = 1.1 %). This is a warning, not a
failed check, and it never holds the section back: a capacity factor is
often quoted on the export (AC) rating instead of the installed (DC)
one, so the note appears only when P50 sits more than 20 % away from
both readings.
Plant emissions factor, on Commercial defaults, starts blank. It is the plant’s own emissions for each unit of energy — solar, wind, hydro and battery plants usually report 0 — so no grid average is filled in for you, and clearing the field leaves it blank. The unit beside it (g CO₂/kWh or t/MWh) converts the number you see; the saved value is always t/MWh.
4.4 BRP — Trading Unit and zone
Each site’s BRP cell sits in its workspace’s Site details (§4.1). The cell is blank until the organisation is an ACTIVE Market BRP with a BRP reference — a filed application that is still pending does not unlock it.
Once that seat is active: if the site is registered as a generating
Trading Unit, the cell shows the
TUID above the network zone (same colour swatch as
the SO/MO zone register). Click either to open
/org/trading-units.
If the site is not in a published network zone, the cell says No Market Zone instead of offering registration.
If there is no TUID and the site is allocated, Register with Market opens the standing-data wizard (sticky tabs; Register appears only when every required field is complete).
Where this is taught. Every tab and every input: V9 §3.7. The four-seat wizard map: V9 §3.9B.
Where a registered site’s location is not covered by the map, the zone line says Unassigned and names the nearest zone. A notice above the table explains what that blocks. The nearest zone is deliberately not used as an assignment: putting the site there would place it in the wrong balancing group.
Nothing about the site itself changes, and nothing about today’s trading is affected until the unit is registered. The full zone treatment is V12 §2.
4.5 What the market registry adds to a site
The zone decides which market registration a site can join. The site’s meter decides who the market thinks is on the other side of its energy.
Every metering point in the market carries a counterparty — the party taking what this plant injects. The platform derives it from your signed PPAs, so a site with contracts in place usually needs nothing entered. Two situations reach you:
- A meter with no counterparty cannot be settled. No signed contract naming anyone at that point means nothing to derive from, so the market registry shows it empty and lists it as an exception rather than inventing a buyer. The fix is a contract.
- A virtual PPA does not supply one. It settles on price and delivers no energy, so it creates no pairing — but this plant is still injecting real electricity, and that injection still needs a counterparty: whoever actually takes it. A site whose only deal is virtual will show an exception here, and that is correct rather than a gap in the data.
Both live at BRP / Market → Market registry, taught in V9 §3.
4.6 And what the market asks about the plant itself
A site record says what the plant is: technology, installed capacity, export capacity, transformer, expected yield. The market asks a different question — what the plant can do, minute by minute — and requires an engineering review. Optional plant profiles now capture several of these answers:
- how fast it loads and de-loads, as four separate ramp rates;
- how long it must stay on once started, and off once stopped;
- what a start costs in Rand from hot, from warm and from cold;
- which of your three capacity figures is the one the market means.
That last one is worth pausing on. This screen holds installed capacity, inverter capacity and export capacity, and the market wants exactly one number: the most the plant can send out continuously. Export capacity is closest and is not automatically right — export capacity is sometimes set by a grid-connection agreement rather than by what the plant can produce. The platform will not pick for you, and it records which you chose and why, because the market requires the top of your price ladder to equal that figure exactly.
For solar and wind most of the rest is genuinely zero. For anything with a turbine they are real numbers from a plant engineer, and a zero that stands in for an unknown is the most expensive entry you can make — see V9 §3.8. Review the captured profile and the remaining answers at BRP / Market → Standing data.
Follow along. Seat: IPP 2 (
ipp_2@webill.net). Path: IPP Sites. You should see five sites — IPP2 Atlantis Wind (Wind 80/70, Municipality/Cape Town), Tshwane Solar Park (Solar 90/75, Eskom, 132kV), Durban Coastal Wind (Wind 100/90, Eskom), Jozi Grid BESS (BESS 50/40) and Rosslyn BESS (BESS 20/5 — the deliberately tiny battery). Stat cards: 340 MWp installed, 280 MWac export.
Data. full_demo · seed 42 · stage S03 (parties) · sealed 2026-07-15.
4.7 Optional plant profiles
The final wizard step captures technology-specific engineering data. Its Skip / clear profile action preserves default forecasting. Hydro inflows have twelve monthly cells; thermal profiles capture heat rate and ordered start costs; hybrids select same-organisation components. Read the captured card on Overview inside Solar PV / Wind / … assumptions & forecast basis (V4 §4.2). See V4 §18 for validation and default-versus-measured precedence. Captured profiles now supply the available registry engineering fields; the Standing data review still owns missing and assumed values.
Step 7 · Solar
Capture tracking, panel orientation, degradation and losses. If DC/AC ratio is omitted, the card derives it from installed DC capacity divided by inverter capacity. Weather performance parameters remain on the effective-dated SiteCurve.
Step 7 · Wind
Capture turbine count and rating, hub height and availability. A nameplate mismatch is a warning. A conflicting existing wind-curve hub height must be resolved before saving.
Step 7 · Hydro
Choose run-of-river, storage or pumped storage. Declare daily/weekly energy limits and twelve inflow factors if available. Unknown water-authority and storage engineering remain missing in the registry projection.
Step 7 · Thermal
Capture cycle, matching fuel, heat rate, operating cost, ordered start costs and operating limits. Heat rate below 3.6 GJ/MWh is refused. Missing fuel or emissions references leave cost unavailable.
Step 7 · Hybrid
Select same-organization solar or wind components and optional active BESS. The shared cap cannot exceed registered export capacity. A component can belong to only one composition, and a book cannot count both its composite and its generation component.
4.8 Site status — Open, Active, Inactive
Think of the plant record as a shop front. The shop can be fitted out but not yet open to trade (Open), trading (Active), temporarily shut with the sign still on the door (Inactive), or closed for good (Closed). That shop-front word is the generator site status in the register’s Status column — not the grid-connection milestone, not a contract state, and not the onboarding draft. The buttons that change it sit in the site workspace: Site details → Site lifecycle & fleet membership (§4.1).
| Status | What it means | Button in Site lifecycle & fleet membership |
|---|---|---|
| Open | The plant is registered and can be matched to buyers, but you have not marked it operational yet | Activate
(#ipp-site-activate-{id}) |
| Active | The plant is the live operational record | Deactivate (#ipp-site-deactivate-{id})
— rose hover, asks first |
| Inactive | You took it off the live floor; the register row and history stay | Activate |
| Closed | The site is closed for new activity | Activate (same restore as Inactive) |
How a site becomes Open. Every new site comes from the generator site onboarding form (Add New Site, the round +): Create open site record writes Open unless Project stage is Operational, in which case it writes Active. Project stage is only on the draft (Early development · Grid application · Construction · Commissioning · Operational). Once the site exists, that stage is not stored on the plant and Edit does not change status.
How Open becomes Active. Open the site’s workspace, press Site details, open Site lifecycle & fleet membership, and press Activate. The register’s Status reads Active with a green dot, and the button becomes Deactivate. The fold stays open after the press. Nothing else flips it: not COD arriving, not grid connection becoming Operational, not signing a PPA, and not Save changes in onboarding.
How Active becomes Inactive. Press Deactivate in the same fold. Confirm the prompt (Deactivate this site? It is marked Inactive and stays in the directory; Activate puts it back to Active.). The status reads Inactive, and the button becomes Activate, which puts it back to Active.
flowchart LR
Draft[Onboarding draft] -->|Project stage is Operational| Active[Active]
Draft -->|Any earlier stage| Open[Open]
Open -->|Activate| Active
Active -->|Deactivate| Inactive[Inactive]
Inactive -->|Activate| Active
Closed is a stored status with no separate Close chip. Activate on a Closed or Inactive site writes Active. Matching still treats Open and Active sites as candidates for new counterparties.
Follow along. Seat: an Organization door with at least one Open generator site (onboarding with a pre-operational project stage, or a demo plant seeded Open). Path: sidebar IPP Sites → Sites → the site’s name → Open site workspace → Site details → Site lifecycle & fleet membership → Activate. You should see the status become Active and the button flip to Deactivate.
Careful. Grid connection status (Application submitted · Budget quote received · Connected · Operational) is a different field. A plant can be Open and already Connected, or Active and still waiting on a quote. Change connection status in Edit; change the shop-front badge with Activate / Deactivate.
5. Trader pools — the commercial layer
A trader pool is a licensed trader’s trading vehicle: no site, no meter — a bundle of rights, treatments and protections under which it buys from generators and sells to consumers. One organization can run several pools with different policies (a renewables pool, an industrial pool, a metro pool…).
Where this is taught. The trader directory and strategy tabs: V6 · Trader. Creating and editing a pool on the onboarding workspace: V6 §2B. This chapter keeps the entity, directory and market-registration picture.
5.1 Accreditation gates the door
If your organization isn’t accredited (§2), the directory shows an amber notice instead of the create button: “The Organization has not been accredited to trade either by Eskom or by any municipality which supports wheeling.” Fix §2 first.
5.2 The directory
Trader Pools (sidebar) — “How each pool is trading, which one needs you, and where to go — the register of pools underneath.”
The landing. The page opens with what the fleet is
doing, before any table: a verdict written from the
numbers (“1 of 4 pools trade. T1 Renewables Pool is long with no
buyer for 96 % of its supply, and the plan loses R 12.2 m a month until
it sells; the other 3 have no members”), five fleet
tiles in a trader’s words (coverage · margin at plan · margin
at risk against its limit · spill · shortfall — unmet demand as a share
of demand, the same SHORTFALL_PCT as the book
(#trader-pools-stat-shortfall) — pools without members are
not averaged in). A pool that has never run, or a fleet with no trading
pools, shows — on Shortfall, the same dash as Spill and
Coverage. Then a Needs you rail ranking the pools that
want attention with a link to the screen that fixes each, and
one quiet card per pool. The card is a two-second scan:
name, status badge, the one-line
subtitle, the tone pill, and the vitals as inline figures (or the
one-line verdict on a not wired card). Click the card to open
the detail drawer (#fleet-detail-drawer).
A pool with nothing to judge gets a dashed not wired
card that says what the one setup step is; zeros are never shown as
health. Grades (forecast, estimated) say where the
figures come from. The landing loads with the page.
The detail drawer. Click a card and a right-hand panel opens with the branded header (eyebrow Trader pool, the pool name, close). The drawer carries one chip per registered Trading Unit — its id and its market zone with the zone’s colour dot, each opening the Trading Units register — or, only while the pool has no Trading Unit, Register with Market; then Regulator (the NERSA-style preview drawer) and Counterparties (the match search). Then the verdict, the vitals as compact tiles, the top Move, and the navigation chips — Overview · Book · Desk · Dashboard · Contracts · Edit · Archive. They are all neutral until hovered — green, except Archive, which hovers rose because it is the one destructive action. Archive asks first, then marks the pool Suspended; a pool that is not Active shows Activate in the same place, which puts it back to Active. Escape, the backdrop, or the header close shuts the drawer. Search, the Status filter and the name sort sit under the fleet tiles.
The landing filters by Status (All / Active / Suspended / Expired / Revoked):
| Column | What it shows |
|---|---|
| Pool Name | public (green check) / private (red cross) dot; name with the status badge beneath it (Active · Suspended · Expired · Revoked) |
| BRP | blank unless the organisation is an ACTIVE Market BRP with a BRP code. Then: a count of registered Trading Units — hover for each TUID and colour-coded zone; click the count to open Trading Units. Otherwise Register with Market opens the pool Trading Unit wizard (any published zone; one unit per selected zone) |
| Physical · Virtual | non-clickable counts of AGREED / SIGNED / ACTIVE physical PPAs and virtual PPAs (— when none) |
| Actions | Strategy (straight to the pool’s book — no seeding step; trader books seed themselves) · Regulator Preview (document-check icon — same NERSA-style drawer as the create wizard) · Edit Pool |
5.3 Creating a pool — the wizard, step by step
New Trader Pool opens the five-step wizard. You can jump to any step from the stepper; incomplete steps show a red warning (hover for what is still needed), completed steps a green check. There is no Continue button — Register Pool appears in the footer only when every step is green.
Think of the wizard as answering five plain questions counterparties and the regulator will ask later: who is this pool and is it licensed, where may it trade and which strategy roles does it claim, what may it do under its licence, how do network charges and imbalance land commercially, and what protections does it offer off-takers.
Step 1 · Core Profile — Identity, licence posture & marketplace visibility.
| Field | Notes |
|---|---|
| Pool Name * | human label for the trading vehicle (e.g. T1 Renewables Pool) |
| Schedule 2 Exemption |
toggle (default on) — whether this pool claims Schedule
2 exemption from a full NERSA trading licence:
|
| NERSA License Number * | shown only when Schedule 2 is off — the licence identifier on the NERSA certificate |
| License Issue Date * · Effective Date · License Expiry Date * | shown only when Schedule 2 is off — issue and expiry are required; effective date is optional (when the licence takes effect if later than issue) |
| Initial Pool Status * |
card pick — lifecycle state at registration. Must be
Active to register (other picks show Registration
Not Available):
|
| Public Pool |
toggle (default on):
|
Step 2 · Network — Where the pool may operate, which strategy roles it claims, and whether it settles by nomination.
| Field | Notes |
|---|---|
| Network Access Rights * |
card pick — which wires the pool is accredited to trade across. Cards
are disabled where your organisation’s accreditations (§2) don’t reach:
|
| Cross-Border Permission | toggle (default off) — whether the licence/mandate allows energy that crosses national borders |
| Supply roles |
select all that apply (default
Flexible) — which generator / trader supply
pool archetypes this book’s strategy may take members from. Fixed at
creation (locked when editing):
|
| Demand roles |
select all that apply (default Trader
Sales) — which off-taker demand pool archetypes this
book may serve. An off-taker joins only when at least one of its
Strategy Demand Classes (§3.2) intersects this list.
Fixed at creation:
|
| Nomination capable |
toggle (default on) — a meterless pool settles by
nomination rather than meter
reads. Fixed at creation:
|
Step 3 · Activities — What the licence allows, and what it forbids.
| Field | Notes |
|---|---|
| Permitted Activities * |
select all that apply (defaults: Buy / Sell / Wheel
Energy) — the operational scope the pool claims under its mandate:
|
| Licence Prohibitions & Restrictions |
optional multi-select — hard limits written into the licence or
operating mandate:
|
Step 4 · Commercial — How network charges and imbalance exposure are allocated.
| Field | Notes |
|---|---|
| Wheeling Charge Treatment * |
select all that apply — how Use-of-System / wheeling
charges reach customers under this pool’s policy:
|
| Balancing Cost Treatment * |
card pick (single) — who carries imbalance / mismatch exposure:
|
Step 5 · Protections — Off-taker safeguards the pool commits to. Filter the cards by All / Pricing / Operations / Data & Audit. Sensible defaults are pre-ticked (Price Caps, No Unilateral Price Changes, Billing Transparency, Balancing Cost Protection, Dispute Resolution). At least one measure is required.
| Field | Notes |
|---|---|
| Off-taker protection measures * |
select all that apply — contractual safeguards offered
to off-takers served through the pool:
|
When all five steps are green, Register Pool appears in the footer.
5.4 Editing
Edit in the detail drawer
(#trader-pool-edit-<id>) opens the same onboarding
workspace used to create a pool
(/org/trader-pools/onboarding/<case id>), prefilled
from the live pool. It does not open a modal. Save
writes the same pool — it does not create a second one.
Think of it as reopening the shop’s licence file, not opening a
second shop. The chrome says Editing (not Draft). There
is no Discard — you cannot throw the live pool away from here.
Save & exit returns you to Trader Pools without
writing the pool; section answers stay on the edit case so you can
reopen them. Review readiness then Save
changes writes the answers onto the existing pool and returns
to /org/trader-pools.
Explanations
(#trader-pool-onboarding-explanations) opens a right-hand
list of plain-language notes for this section. Click a
choice to fill that input. Close with the header X, or
press the control again. Same drawer chrome as OffTaker site onboarding:
branded green header, title Explanations,
X top-right.
All fields stay editable regardless of contracts — a pool is policy, not priced physics — except the strategy compatibility classes (eligible supply and demand roles) and nomination capability, which are set at creation only and stay locked on the Network section.
flowchart LR
A[Open a pool card] --> B[Drawer Edit]
B --> C[Onboarding workspace in edit mode]
C --> D[Save and exit]
C --> E[Review readiness then Save changes]
D --> F[Back to Trader Pools]
E --> F
5.5 Registering the pool with the Market
The pool list carries a BRP column. It stays blank until the organisation is an ACTIVE Market BRP. After that:
- Register with Market — opens a three-step wizard (Identity · Zones · Finance). The Zones step lists every published network zone. A trader may register the pool in any of them — member location is not a gate. Select all zones ticks or clears every unpublished zone; each card has its own check mark. You can register more than one Trading Unit in one pass (one per selected zone, because a unit may not span zones, §2.1(212)(a)).
- Count — how many Trading Units this pool has
registered. Hover the number for each TUID and its
colour-coded zone; click through to Trading Units
(
/org/trading-units). Register with Market stays available beside the count until every published zone has a unit.
Where this is taught. Identity · Zones · Finance, Select all zones, and the official-name pattern: V9 §3.9B.3.
The map itself is provisional — see V12 §2.
5.6 What the market registry adds to a pool
The pool is yours to shape. Once it trades, the market keeps its own record of the same sites, and the two are not identical:
| Here (a pool) | In the market registry |
|---|---|
| One pool, however many zones | One Trading Unit per zone |
| Members are sites you added | Points of delivery are the meters those sites are metered at |
| A member is yours alone | Every meter has a counterparty — the party on the other side of the energy |
The registry lives at BRP / Market → Market registry and is taught in V9 §3. Two things there change how you read this screen:
- The BRP column is the registry’s answer for this pool: one Trading Unit per zone you registered.
- A meter with no counterparty cannot be settled, even though the pool looks complete here. The registry lists those separately; a pool that is fine on this page can still have unsettleable points on that one.
Follow along. Seat: Trader 1 (
trader_1@webill.net). Path: Trader Pools. You should see four active public pools: Trader 1 Portfolio and T1 Renewables Pool (Both networks, Trader-Borne balancing, Full Pass-Through), T1 Industrial Pool (Eskom, Pass-Through, Blended) and T1 Metro Pool (Municipality, Shared, Partial Pass-Through + Blended). For contrast: Trader 2’s Trader 2 Portfolio is private, and Trader 3’s only pool is Suspended.
Data. full_demo · seed 42 · stage S03 (parties) · sealed 2026-07-15.
6. Meters and devices
Everything the platform ever settles, forecasts or charges starts at a meter. A meter is a device — a row in your organization’s device registry — and a site points at it directly.
6.1 The device record
| Field | Meaning |
|---|---|
| Device number | the identifier everywhere on screen
(e.g. MTR-NERSA-GEN-1002); searchable |
| Device type | ELECTRICITY for wheeling meters (the registry also
carries WATER, GAS, GENERATOR,
CONCENTRATOR, LORAWAN) |
| Status | ALLOCATED (owned by your org) · INSTALLED
(on a site) · REMOVED · UNALLOCATED |
| Reads per day | the expected read cadence — the wheeling standard is 72, one read every 20 minutes |
| Read indexes | which registers the meter
reports — TOU-split kWh (PEAK_KWH, STD_KWH,
OFF_KWH), export registers for generators, kvarh, kVA… |
| Manufacturer / model | the hardware, from the manufacturers registry |
| Comms | how it reports (NBIOT, SIGFOX,
CALLBACK, … or NONE) |
6.2 How a meter attaches to a site
A generator site requires a meter — you cannot create one without it (the wizard creates or assigns the device as part of site creation). It may also carry an optional check meter, the independent second meter used for verification.
An off-taker site also registers its meters in the wizard (§3.2): you enter the primary meter number (and optional manufacturer / model) — there is no registry search — and Register creates the device and links it. An optional check meter is registered the same way as a second device. Without a primary meter the site has no consumption history, no settlement source, and its Consumption view will say “No meter is assigned to this site.”
Trader pools have no meter at all — that is the point of a trader: where a meter cannot speak, a nomination does (V3 §9).
6.3 What the meter measures
A wheeling meter reports cumulative registers — ever-increasing counters, one per TOU period, on each side:
- Demand side (off-taker meters): peak / standard / off-peak kWh consumed.
- Supply side (generator meters): export registers — peak / standard / off-peak kWh injected.
The platform never uses a register value directly; it uses the difference between two consecutive readings — chapter 7 — which is why a missed reading never loses energy, only detail.
Follow along. Seat: IPP 2 (
ipp_2@webill.net). Path: IPP Sites → IPP2 Atlantis Wind row → the meter isMTR-NERSA-GEN-1002, 72 reads per day. Every seeded site’s meter follows the sameMTR-…convention.
Data. full_demo · seed 42 · stage S03 (parties: 16 meter devices) · sealed 2026-07-15.
7. From readings to intervals — the data pipeline
The problem: meters report cumulative counters at points in time; settlement, forecasting and strategy need energy per 20-minute interval, split by TOU period. The pipeline between the two is small, deterministic, and worth understanding once — every chart in the platform sits on it.
7.1 The pipeline
- A reading is a snapshot of the meter’s cumulative registers at one timestamp — at 72 reads/day, one every 20 minutes.
- The deriver subtracts the previous reading’s registers from this one’s, register by register. Deltas are clamped at zero (a cumulative register never decreases; noise is absorbed) and rounded to 4 decimals. Generator meters are read from their export registers, off-taker meters from their consumption registers — the result lands in the same shape.
- The interval row carries the period’s peak / standard / off-peak kWh plus its start and end time. A late or missing reading doesn’t lose energy — the next delta simply covers a longer window (the interval’s minutes say so).
- Roll-ups aggregate intervals into daily and monthly series per meter (peak/std/off sums plus covered minutes), refreshed automatically every hour.
Where readings come from depends on the environment: in demo builds, deterministic history is written by the setup’s backfill (stage S05 — twelve months, sealed and checksummed) and live ticks can be switched on explicitly (S15); in production they arrive from the meters’ comms. Either way, everything downstream is identical.
7.2 The consumption explorer
A site row’s Meter action opens the consumption explorer. On an IPP site that is the modal “Meter {device number}”. On an off-taker site it is the Operations page. Both have two tabs. The figures below sketch what each tab looks like for OffTaker C Midrand DC (same numbers as the follow-along).
Where this is taught. On an off-taker site the explorer is inline on Operations. View energy data and choose a month, the Reads month and hourly coverage table, and Site location are in V5 §3.2–§3.4.
Consumption — a stacked bar chart split by TOU (red Peak, amber Standard, green Off-Peak). It drills three levels: All months → click a month → daily → click a day → 20-minute. The breadcrumb above the chart walks you back up. (“Tip: click a bar to drill into daily / 20-minute detail.”)
On All months, South African high season months (June · July · August) are shaded amber with bold amber axis labels; the other months are low season (slate labels). A legend above the chart names both — the same season split tariffs use (§8).
When you drill to a day, the breadcrumb and chart
title show the weekday beside the date (for example
15 Jun 2026 · Monday).
On a generator’s meter the same explorer measures what the plant exported, so the chart titles say so: Monthly generation (kWh), Daily generation — {month} (kWh) and 20-minute generation — {day} (kWh). You meet it inline on an IPP site’s workspace, Operations tab, under Meter history & interval coverage. An off-taker’s meter keeps consumption in the same titles. On either kind, months after the current month are never shown as metered — a setup or lab run can write readings ahead, and the history does not present them as measured.
All months — TOU stacks
Read it: each stack is one month’s Peak + Standard + Off-Peak. The amber band is high season; June’s outline marks the month the follow-along opens (peak 205,333 + standard 481,600 + off-peak 481,067 = 1,168,000 kWh).
Day drill — 20-minute bars · 12 Jun 2026 · Thursday
Read it: each column is one 20-minute interval after you click a day. The title keeps the weekday beside the date; click a month first if you are still on All months.
Reads — the read-coverage view for a selected month: stat tiles (Reads, Expected in window, Gaps in window, Days w/ gaps) above a heatmap — one cell per hour per day; a fully-covered hour has 3 × 20-minute reads; the greener the cell, the more complete; red cells are missing reads. The offtaker page’s month picker and View hourly coverage data table are in V5 §3.3.
Healthy month — almost every hour green
Read it: rows are days, columns are hours. Settlement-source meters in the demo look like this — Gaps in window = 0, Days w/ gaps = 0.
Gap hour — red cell (gallery device)
Read it: one red hour means three missing 20-minute reads. The deliberate demo gap lives on the gallery device in §7.3 — settlement meters stay complete.
When a meter has no consumption and no reads yet,
the explorer offers Generate Reads: choose how many
months back (1–24), then build 20-minute history from the start of that
first month through the latest completed interval today. Off-taker sites
spread estimated monthly demand by TOU; generator sites
shape export (ex_*) energy from
installed capacity and technology (solar little at
night, wind, BESS evening dispatch, hydro, hybrid, coal baseload, gas
morning and evening peak) — same empty-state UI on both directories.
Overlay SIM meters such as MTR-NERSA-SIM-GEN-12 (coal) use
those same shapes.
Follow along. Seat: Off-taker C (
offtaker_c@webill.net). Path: OffTaker Sites → OffTaker C Midrand DC → Operations (the directory Meter action opens the same page). On the Consumption tab, the June 2026 bar sits in the high-season band and totals 1,168,000 kWh — peak 205,333 + standard 481,600 + off-peak 481,067 (Σ ✓; the cold-storage profile scales to the site’s 1,200,000 kWh/month estimate). Drill into any June day and the 20-minute bars appear with the weekday next to the date.
Data. full_demo · seed 42 · stage S05 (meter history: 12 months, 20-min cadence, 191,013 readings platform-wide) · sealed 2026-07-15 · re-derived from the monthly roll-up on 2026-07-18.
7.3 Seeing a gap
The demo dataset ships one deliberate gap so you can see what
incomplete looks like without breaking any settlement story:
the gallery device CODEX-DEMO-GALLERY-MISSING-READ is
missing exactly one hour’s reads (three 20-minute slots, fourteen days
before the history window’s end). On its Reads tab that hour is a red
cell, Gaps in window shows 3, and Days w/
gaps shows 1. Every settlement-source meter in the
demo set is complete — the gap lives only in the gallery.
Where this is taught. How settlement consumes intervals (and what a provisional hour means when data is late): V8 §3. How the demo history is generated and sealed: V21 · Operations §4 · §6.
7.6 Quality, vintage and revisions
ACTUAL is a meter value. ESTIMATED, SUBSTITUTED and INTERPOLATED record how a replacement was obtained. PROVISIONAL is first-received data; VERIFIED requires reconciliation evidence; REVISED records a correction. The original row remains in history, stamped as superseded. Current readers and continuous aggregates exclude it. Operations shows quality and vintage counts separately from gap coverage. A complete month may contain estimated or provisional rows; Consumption shows estimated energy contributions and each raw interval’s quality and vintage.
A FINAL settlement supplies a verification watermark for its meter. Legacy intervals after that watermark, or on devices without FINAL evidence, remain provisional. Unknown legacy feed provenance stays unknown.
7.7 Importing interval files
Demo history is already planted (stage S05). Import
intervals is for when a person brings a file of
20-minute energy the meters did not tick in live — a utility export, a
gap you filled from another system, or a first load before comms exist.
It is a MANUAL feed
(meter:import:canonical). Nothing is “late” until you press
the button.
Think of a bank paying-in slip. The bank prints the columns. You fill every required box. If one line is wrong they hand the whole envelope back — they do not guess a missing meter or invent a missing 20 minutes. That all-or-nothing rule is atomic import.
When you would use it, and why
Use it when the energy must enter the same interval store settlement and the consumption explorer already read — and you hold that energy as a file, not as a live meter stream.
| Situation | Why a file, not a live tick | Typical seat |
|---|---|---|
| A site is new and comms are not in yet | You still need charts and a first settlement month | Off-taker or IPP directory |
| The utility sent a CSV of last month | Their file is the legal meter record for those hours | Off-taker (import kWh) or IPP (export kWh) |
| You corrected a gap from another historian | The Reads heatmap showed a hole; you now have the missing buckets | Same site as the gap |
| You are rehearsing an upload in demo | Mock canonical fixture speaks the same schema without a vendor | Either directory |
Do not use it to replace plant “now” telemetry (V4 §11) or carbon inverter readings. Those are other pipes. Do not use it to change TOU labels — Webill classifies peak / standard / off-peak from the timestamp (§8).
Where this is taught. The register of import feeds (canonical, mock, and the two utility dialects that are not on this form yet) is V21 §11. Quality and vintage words are §7.6.
Words you need
| Plain English | Platform word | Meaning here |
|---|---|---|
| The house template for a file | wb-interval-1 | The published schema. JSON or CSV. No extra columns |
| The translator you pick | File adapter | canonical (real file) or mock (same shape,
practice) |
| Who the row is about | meter_ref | Must equal a device number your organisation already owns |
| The start of the 20-minute bucket | interval_start | ISO-8601 with a UTC offset (+02:00 or Z).
Not a local clock without a zone |
| How long the bucket is | interval_minutes | Must be 20 on this feed. 15 / 30 / 60 exist in the schema but refuse here |
| Energy drawn from the grid / site | kwh_import | Required on an off-taker (demand) upload |
| Energy sent out by the plant | kwh_export | Required on an IPP (supply) upload; off-taker files may omit it |
| How the figure was obtained | quality | ACTUAL, ESTIMATED,
SUBSTITUTED, or INTERPOLATED — mandatory |
| How sure we are | vintage | PROVISIONAL (default), VERIFIED, or
REVISED |
| Your own row id | source_ref | Optional. Kept on the feed attempt so you can match the utility’s line |
| All or nothing | Atomic | One bad row refuses the file. Nothing is written |
CSV is a spreadsheet saved as text (comma-separated
values). JSON is the same facts wrapped in
{ … }. kWh is kilowatt-hours.
kvarh is reactive energy — allowed on the schema,
optional. TOU is time-of-use (peak / standard /
off-peak).
Where to click
Both directories use the same control. Import
intervals (#open-interval-import) sits in the
directory header, on the right beside the round +
(Add New Site); the title and its one-line description
are on the left. Press it and #interval-import-modal opens.
There is no hanging drawer at the top of the page. The only difference
after upload: OffTaker stores kwh_import; IPP stores
kwh_export.
Follow along. Seat:
offtaker_c@webill.net(Organization; passwordsupersecret). Path: OffTaker Sites → press Import intervals (#open-interval-import) next to Add New Site. You should see:#interval-import-modalwith a branded header and the line Upload metered readings as CSV or JSON. Each row needs a start time with its UTC offset, the interval length and a reading quality. A file with an unknown column is refused whole, so nothing half-imports. Then File adapter (Canonical CSV / JSON, or Mock canonical fixture), a file picker (.csvor.json, 5 MB), Validate file — disabled, with Choose a file to validate. under it — and Published interval schema (opens in a new tab).
On an IPP seat the click path is the same, and it works from either
tab: open IPP Sites, press Import
intervals (#open-interval-import) in the header on
Fleet or Sites, and
#interval-import-modal opens. The Fleet tab’s chapter 04
row Import intervals
(#fleet-next-evidence, V4 §2.5) and a site
workspace’s Operations tab (Meter history &
interval coverage) open the same modal. After upload the
platform stores kwh_export, not
kwh_import.
| Control | What it does |
|---|---|
| File adapter | canonical reads your bytes. mock
is the same parser — pick it when the file is a practice fixture, not a
live utility drop |
| File picker | One file. .csv or .json only |
| Validate file | Disabled until a file is chosen, with the hint Choose a file to validate. Then: parse → validate every row → check every meter is yours → preview direction and energy totals. No readings are saved until Import N intervals. It reads Validating… while it works |
Published interval schema (opens in a new tab)
(#interval-import-schema) |
Opens GET /api/v1/publication/interval-schema — the
machine copy of the tables below — in a new browser tab, so the modal
stays open |
Verdict (#interval-import-verdict) |
A coloured box under the button. Green on success: Imported N intervals. G gaps reported; no gaps were filled. Rose on a refusal, announced to screen readers as an alert: File refused; nothing was imported. {reason} Fix the file and import it again. (§7.7.7) |
The canonical schemas
The published id is wb-interval-1.
Extra columns are not “ignored” — they refuse the file. The feed key on
a JSON envelope must be exactly meter:import:canonical when
the adapter is Canonical (or meter:import:mock when you
picked Mock).
JSON envelope
| Field | Required | What to put |
|---|---|---|
schema |
yes | the string wb-interval-1 |
feed_key |
yes | meter:import:canonical (or
meter:import:mock) |
intervals |
yes | an array of row objects. No other top-level keys |
Each interval row
| Column | Required | Rules |
|---|---|---|
meter_ref |
yes | Device number on a meter this organisation owns |
interval_start |
yes | Interval start. Must include an offset
(2026-06-12T06:00:00+02:00 or …Z). A time
without a zone is a naive timestamp and refuses the
file |
interval_minutes |
yes | Integer. Allowed in the schema: 15, 20, 30, 60. This feed’s grain is
20 — any other value is
grain_mismatch |
kwh_import |
yes (demand) | Decimal string or number, not negative, at most
three digits after the point (12.345) |
kwh_export |
yes on IPP uploads | Same decimal rule. Off-taker files may leave it empty |
kvarh_import / kvarh_export |
no | Same decimal rule if present |
quality |
yes | ACTUAL · ESTIMATED ·
SUBSTITUTED · INTERPOLATED |
vintage |
no | PROVISIONAL (used if omitted) · VERIFIED ·
REVISED |
source_ref |
no | Your line id. Stored on the feed attempt |
CSV is the same columns as a header row, then one data row per
interval. No schema / feed_key wrapper. A
UTF-8 BOM is tolerated. Quoted commas and Windows line endings are fine.
Duplicate header names or a short/long data row refuse the file.
There is no TOU column. If you add tou
or peak_kwh, the file is refused
(unmapped_columns). Webill puts the energy into peak,
standard, or off-peak from interval_start.
A sample upload
OffTaker C Midrand DC, meter
MTR-OTS-thin_offtaker_c_private, two consecutive 20-minute
buckets on Friday 12 June 2026 (high season). Energy is estimated from a
utility extract, still provisional.
JSON (Canonical adapter):
{
"schema": "wb-interval-1",
"feed_key": "meter:import:canonical",
"intervals": [
{
"meter_ref": "MTR-OTS-thin_offtaker_c_private",
"interval_start": "2026-06-12T06:00:00+02:00",
"interval_minutes": 20,
"kwh_import": "18.250",
"quality": "ESTIMATED",
"vintage": "PROVISIONAL",
"source_ref": "utility-row-0600"
},
{
"meter_ref": "MTR-OTS-thin_offtaker_c_private",
"interval_start": "2026-06-12T06:20:00+02:00",
"interval_minutes": 20,
"kwh_import": "17.800",
"quality": "ESTIMATED",
"vintage": "PROVISIONAL",
"source_ref": "utility-row-0620"
}
]
}The same facts as CSV:
meter_ref,interval_start,interval_minutes,kwh_import,quality,vintage,source_ref
MTR-OTS-thin_offtaker_c_private,2026-06-12T06:00:00+02:00,20,18.250,ESTIMATED,PROVISIONAL,utility-row-0600
MTR-OTS-thin_offtaker_c_private,2026-06-12T06:20:00+02:00,20,17.800,ESTIMATED,PROVISIONAL,utility-row-0620
An IPP file looks the same except the energy column you care about is
kwh_export, and you open the same modal on IPP
Sites.
Data. Teaching clip — not a sealed S05 checksum. Device number is the frozen OffTaker C Midrand DC meter. Grain and feed key match
meter:import:canonical. Last checked 2026-09-08.
What happens once the file is uploaded
flowchart TB
A[You choose adapter and file, press Validate file] --> B{Parse CSV or JSON}
B -->|bad envelope or columns| R[Refuse. Write nothing]
B -->|rows parsed| C[Validate every row against wb-interval-1 and 20-minute grain]
C -->|any row fails| R
C -->|all rows ok| D{Every meter_ref is a device this organisation owns?}
D -->|unknown or another org| R
D -->|all yours| P[Check stored conflicts and preview dates, quality and totals]
P --> Q[You confirm Import N intervals]
Q --> E[One database transaction]
E --> F[Each row: pick kwh_import or kwh_export]
F --> G[Webill classifies TOU from interval_start]
G --> H[Write one interval: only that TOU bucket holds the kWh]
H --> I[Record OK on meter:import:canonical with file SHA-256 and source_ref]
I --> J[Verdict: Imported N. G gaps reported; none filled]
- Parse. JSON must be exactly
{ schema, feed_key, intervals }. CSV must have a unique header and even rows. - Validate. Unknown columns, missing required fields,
naive times, negative energy, more than three decimal places, a
quality/vintage you invented, mixed or wrong grain, or the same
meter+start twice (
duplicate_interval) — the whole file is refused. - Ownership.
meter_refis looked up asdevice_numberon your organisation. One foreign meter refuses every row, including the good ones. - Preview and confirm. Review meter, demand/import or supply/export direction, interval count, cadence, energy totals and gaps, first/last timestamps in SAST and UTC, quality/vintage counts and sample rows. Any already-recorded timestamp refuses the whole file before confirmation. No readings are saved yet. Confirm Import N intervals, or replace the file. A site workspace accepts only that site’s meter; the downloaded template fills it in.
- Write (all or none). Stored timestamps are checked
again. Imports add new intervals; they never overwrite existing
readings, including superseded originals. Ask the meter data operator to
correct stored evidence. For an off-taker,
kwh_importis stored. For an IPP,kwh_exportmust be present. The platform asks the tariff calendar which TOU bucket that start falls in, then writes one interval: peak or standard or off-peak holds the kWh; the other two are zero. Quality, vintage, and the import feed id travel with the row. - Evidence. The feed attempt keeps the file’s SHA-256
hash and each row’s
source_reffor ninety days (and the latest attempt always). A refusal is recorded asREFUSEDwith the reason — still nothing in the interval store. - Gaps. If your file jumps from 06:00 to 06:40, the verdict reports a gap. Webill does not invent 06:20. The Reads heatmap will show that hole until you import it.
- What you see next. Open the explorer (§7.2). The new buckets appear on the day drill. Estimation-limit checks refresh for those meters. Settlement reads the same interval table (V8 §3).
Done looks like: the green verdict names how many
intervals were imported; gaps (if any) are counted, not filled; the
consumption explorer shows those hours; /ops/feeds shows
meter:import:canonical with a fresh last-success (when you
are on a demo build).
What refuses the file
A refusal is the rose box File refused; nothing was imported. {reason} Fix the file and import it again. The reason is in plain words. When a row is at fault it starts with the row number — Row 3: the start time has no UTC offset (add +02:00). — and when several rows fail, the first one is named and the rest are counted: (2 more rows with problems).
| You did this | The reason you see | What to fix |
|---|---|---|
| No file chosen | Nothing — Validate file stays disabled, with Choose a file to validate. | Pick a file |
Extra column (tou, notes, …) |
unknown column tou. (or unknown columns tou, notes.) | Delete it. TOU is classified here |
JSON feed_key is not this adapter’s key |
the JSON file names a different feed. | Use meter:import:canonical (or mock) |
Time like 2026-06-12T06:00:00 (no zone) |
the start time has no UTC offset (add +02:00). | Add +02:00 or Z |
interval_minutes is 15 or 30 |
the interval length must be 20 minutes for this import feed. | Request a 20-minute export from the provider; 30/60-minute readings are not automatically converted |
meter_ref not on your org |
a meter number is not registered to this organisation. | Use the device number from the site’s meter |
IPP file with empty kwh_export |
a supply row has no exported energy. | Fill export kWh |
| Two rows, same meter and start | the same meter and start time appear twice. | Keep one |
| A required value left empty | a required value is empty. | Fill it |
| Negative energy, or more than three decimals | an energy value is negative. · an energy value is not a number (up to 3 decimals). | Correct the figure |
| A quality or vintage you invented | the reading quality is not a known value. · the reading vintage is not a known value. | Use the words in §7.7.4 |
| An empty file, or a quote never closed | the file is empty. · a quoted value is never closed. | Re-export the file |
| Any single row error | Nothing imported | Fix that row and send the file again |
Live ticks and setup backfill use other feeds
(meter:device_ingest, meter:setup_backfill,
meter:live_simulator). They are not this modal. Attribution
rules for those writers (manifest hashes, S15) stay with V21 §6.
Utility dialects — not on the form yet
Two more adapters exist in code: Eskom MV90
(eskom_mv90) and Municipal AMI
(municipal_ami). They map a utility’s column names and a
SAST clock onto wb-interval-1. They are
not in the File adapter list until operations enables
them after agreeing the exact export. A vendor’s product name on a file
is not enough.
| Adapter | Typical columns | Clock rule |
|---|---|---|
| Eskom MV90 | Meter, IntervalEnd, Minutes,
ImportKWh, … |
SAST interval end → UTC interval start |
| Municipal AMI | meter_number, local_start,
minutes, import_kwh, … |
SAST interval start |
Until they are enabled, pick Canonical and convert the export yourself, or ask operations to turn the dialect on.
8. Tariffs and reference data
Two kinds of priced facts underpin every bill, statement and strategy number: tariffs (what energy costs a consumer) and Eskom’s network reference tables (what the wires cost, and how much energy the wires lose). Org users mostly read these; they are maintained in the Eskom and Munix apps (V8).
8.1 The anatomy of a tariff
A tariff belongs to Eskom or to one municipality, and is built from:
- Charges — the billable components. Each charge has
an index (what it meters: kWh, kVA, account, …) and a
frequency (per period, day, month, year). An energy charge is
KWH × MONTH; a fixed service charge isACCOUNT × MONTH. A charge may carry block steps (tiered thresholds) and may be a feed-in. - Season and TOU bindings — a charge can differ by season (HIGH = winter months, LOW = the rest) and by TOU period. Seasons are month lists; TOU calendars define which hours of a weekday / Saturday / Sunday are peak, standard and off-peak — and must cover all 24 hours.
- Rates — the priced cells. When a tariff is permutated, each charge gets one rate per applicable season × TOU combination (both → 6 rates; season-only → 2; TOU-only → 3; neither → 1), created as Pending and priced/activated in the Eskom or Munix app (rate permutation).
Worked example — a seeded municipal tariff. City of Johannesburg CODEX TOU has two charges: JHB municipal energy (KWH / MONTH) and JHB municipal service (ACCOUNT / MONTH). Its rates: energy HIGH·PEAK 313.45 c/kWh (Active), LOW·OFF 119.20 (Pending), HIGH·STANDARD 206.10 (Inactive); service 986.00 R (Active). One tariff, four priced cells, three lifecycle states — exactly what the tariff screens show. The six Eskom tariff shells (Megaflex, Miniflex, Ruraflex, Nightsave Urban Large, Nightsave Rural, Businessrate 1) are seeded the same way; off-taker sites in the demo reference Megaflex.
8.2 Which hour is peak? The TOU clock
Interval data is classified on the SAST calendar (no daylight
saving): high season = June–August. Weekday peak
windows shift with season; Saturdays have a morning
standard band and no peak; Sundays are entirely
off-peak. This clock is what splits every interval,
chart bar and settlement total into peak / standard / off-peak
(WB.Tariff.TouClassifier).
Read it: each cell is one SAST hour. High-season weekday peak is 07:00–09:59 and 18:00–19:59; low-season weekday peak is 06:00–08:59 and 17:00–18:59. Saturday standard is 08:00–11:59 only; Sunday never leaves off-peak.
8.3 The Eskom reference tables
Three effective-dated lookup tables — the physics-and-wires facts of chapter V0 §1 — browsable under Eskom app → Loss Factors (V19 §1):
Transmission loss factors (TLF) — keyed by customer type. Generators are keyed by zone alone: Cape 0.9710, Karoo 0.9950, Kwazulu-Natal 1.0040, Mpumalanga 1.0210, Vaal 1.0200, Waterberg 1.0230. Loads are keyed by zone + distance band: Zone 0 (≤300 km) 1.0112, Zone 1 1.0213, Zone 2 1.0316, Zone 3 (>900 km) 1.0419. The seeded vintage is effective 2026-03-01 → 2027-03-01.
Distribution loss factors (DLF) — keyed by voltage tier × urban/rural: <500V urban 1.1111, rural 1.1527; ≥500V–<66kV urban 1.0957, rural 1.1412; 66–132kV urban 1.0611; >132kV urban 1.0000. (The lower the voltage, the more the wires lose.)
Use-of-System charges (UoS) — keyed by charge category (DUoS load urban/rural, TUoS gen, DUoS gen), optionally narrowed by voltage tier or transmission zone: capacity and demand charges (R/kVA), an ancillary c/kWh, and the wheeling admin fee — e.g. DUoS Load Urban <500V: capacity R 34.79, demand R 65.96, ancillary 0.80 c/kWh, admin R 180.00/day for connections above 1 MVA.
A worked lookup. Settling a June 2026 interval for a
generator in the Cape zone:
TLF(generator, Cape, 2026-06-15) → the row effective
2026-03-01 → 0.9710 — injected energy is scaled by it
before anything is priced. The same date for a Zone 0 load within 300 km
→ 1.0112. Effective dating means next year’s NERSA
determination is loaded as new rows starting 2027-03-01; history keeps
settling against the old ones.
Where this is taught. How these factors and charges enter a settlement line by line: V8 §4. Maintaining the tables and pricing rates: V21 · Operations (planned, M7).
Data. full_demo · seed 42 · stages S01/S02 (tariffs & reference: 10 TLF, 8 DLF, 7 UoS rows from the NERSA CSVs) · sealed 2026-07-15 · values re-derived from the database on 2026-07-18.
8.4 Fuel prices
The Eskom app’s Fuel prices register holds a fuel, an effective date window, a price in R/GJ, and the source behind it. A missing fuel is not priced at zero. The plant’s heat rate converts this price to fuel cost per MWh; the dispatch card adds variable operations and the estimated carbon assessment. See the operator procedure before replacing a reference row.
9. Municipalities
A municipality is the platform’s model of a local distributor: its name, province, boundary polygon (which is how the map pin resolves your site’s municipality), and — the fact everything turns on — its wheeling status:
| Status | Meaning | On the maps |
|---|---|---|
| WHEELING | wheeling-enabled — sites here can buy wheeled energy; the municipality can be accredited with (§2.3) | green |
| PARTIAL | partially enabled | light green |
| PILOT | pilot programme | orange |
| NONE | not enabled | red |
The full South African municipal register is imported from the national dataset; each demo municipality of interest (Johannesburg, Cape Town, Tshwane, eThekwini, Buffalo City, Mangaung, and the smaller Stellenbosch and George) carries its real boundary and province.
Where municipalities touch your work as an org user:
- Site creation (§3–4): the map pin resolves the municipality and its wheeling status; the eligibility banner and the connection-type choice follow from it.
- Accreditation (§2.3): only WHEELING municipalities can be added.
- Tariffs (§8.1): a municipal site’s tariff dropdown offers that municipality’s tariffs.
- Market search (V7 §2): the map legend colours candidates by their municipality’s status.
The municipality’s own side — its profile, wheeling participation and tariffs — is maintained by the municipal officer in the Munix app, taught in V21 · Operations §2.
10. Worked example — standing up the cast
This is part 1 of the thread (V0 §4): the entities every later volume’s examples run on. All of it exists ready-made in the demo dataset — follow along by inspecting; recreate any piece by walking the wizards of §§3–5 with the values below.
Data. full_demo · seed 42 · stages S01–S05 · sealed 2026-07-15 · M8 gate re-check 2026-07-18 · commit
925037a.
10.1 The thread’s two story lines
The direct line — IPP 2’s IPP2 Atlantis Wind sells straight to OffTaker C’s Midrand DC: one seller, one buyer, municipal wheeling. The chain line — IPP 3’s Midrand Hybrid (Eskom-connected) sells to Trader 1’s T1 Renewables Pool, which resells to OffTaker A’s Rosebank Mall (and lays off a slice to Trader 2’s T2 Flex Pool — the trader-to-trader leg). Both lines already carry ACTIVE contracts in the demo; V1 shows how they were made.
10.2 Standing up the buyer (Off-taker C’s playbook)
- Configuration (§2): profile complete; Eskom accreditation signed (OffTaker C is one of the fully-accredited seats).
- OffTaker Sites → Add New Site (V5 §2.3; demand-class
write-down §3.2):
OffTaker C Midrand DC — Municipality connection resolved by
dropping the pin in Midrand (Johannesburg, WHEELING); Cold Storage
(create writes Industrial + Municipal); 22kV; enter meter
MTR-OTS-thin_offtaker_c_privateas a new device; tariff City of Johannesburg CODEX TOU; demand 1,200,000 kWh/month ≈ 14,400 MWh/yr; requested 12,000 MWh/yr (the ~85 % rule); 10-year horizon, Fixed preference, REC on. - Verify data is flowing (§7.2): the consumption explorer shows twelve months of history — June 2026 totals 1,168,000 kWh.
10.3 Standing up the seller (IPP 2’s playbook)
- Configuration: complete, accredited (Eskom + JHB + CPT).
- IPP Sites → Add New Site (the round
+, a blank onboarding form — §4.3; field reference §4.2):
IPP2 Atlantis Wind — project stage Operational; pin in Atlantis
(City of Cape Town), Municipality connection; Wind; installed 80 MWp,
export 70 MW, inverter 75 MVA; CF 38 % → P50 232,960 MWh; TOU split
20/45/35; transformer 11kV/66kV · 5 MVA · Dyn11 · 6.5 % · ONAF; COD
2024-09-01, 25-year life; meter
MTR-NERSA-GEN-1002; Schedule 2 not exempt — NERSA licenseNERSA-GEN-1002(2023-03-01 → 2043-03-01). - The site lists Active, public, with its wind pill — and appears in buyers’ market searches from that moment.
10.4 Standing up the trader (Trader 1’s playbook)
- Configuration: Eskom TPA and BSA signed; municipal accreditations for Johannesburg and Cape Town — without these, §5.1’s amber notice blocks pool creation.
- Trader Pools → Add New Pool (§5.3): T1 Renewables Pool — Active, public; Both networks; Buy / Sell / Wheel Energy; nomination-capable; Trader-Borne balancing; Full Pass-Through wheeling charges; the default protection set plus Price Caps and Dispute Resolution.
10.5 You are ready to deal when…
- your organization’s accreditation icons are green (§2);
- every site shows Active with a meter and, for buyers, a tariff;
- the consumption explorer shows history for every settlement meter, and its Reads tab shows no unexplained gaps (§7.3);
- sellers’ capacities, TOU splits and licences are final — they lock once the first contract signs (§3.3, §4.3);
- your counterparties can see you: public sites and pools appear in market search, private ones don’t (V7 §2).
Previously in the thread → V0 §4 · Lifecycle spine. Next in the thread → V7 §7 · the physical deal (and V7 §8 · the virtual deal). Later for these entities: strategy books in V3, the IPP programme in V4.
11. Plant feeds
A plant feed identifies a generator site, delivery path, cadence and effective period. Its signal list is derived from the site’s technology: solar irradiance and temperature, wind speed/direction and available units, or battery charge/health/temperature. A battery feed binds the site’s battery asset. The feed also has an entry in the operational feed registry.
11.1 Delivery and responsibility
The plant owns its collector. The platform hosts a push endpoint and an operator-configured file inbox; it does not install plant software or issue plant controls. Register Push API, Mirror file, or Mock on the owner’s plant screen. Choose five- or ten-minute cadence and the start date. The default freshness allowance is three cadences. Signed pushes can be required per feed.
The standard draft data schedule lists schema, path, cadence, latency, signals, collector responsibility, consent scope and forecast fallback. Download it for contract preparation. The stored artifact is a hashed draft, and signing remains a separate commercial act.
11.2 Historian mirror CSV
Download the feed-specific template and schema. The first line must be exactly:
# schema=telemetry.mirror.v1 feed=<plant-feed-uuid> tz=+02:00
Keep the template’s named columns; their order may change and
quality may be omitted. Quote CSV values containing commas
or newlines. Empty cells mean absent values; alarms are separated by
semicolons. Use decimal strings, kW for power and percent for charge and
setpoint. Every timestamp needs an explicit offset, for example
2026-08-18T11:00:00+02:00. A ten-minute feed uses six
buckets per hour.
Deliver files into the feed’s directory in the operator’s configured
inbox. The sweep archives accepted files under processed/,
refusals under rejected/, with a .reason
sidecar. A partially valid file reports rejected row indexes. The
original bytes are retained as an artifact. Repeating identical
normalised content returns the original batch; changed buckets receive a
new revision.
11.3 Consent and vendor gates
Consent is effective-dated and names the grantee organisation. LIVE_PANEL, SAMPLES and EVIDENCE are cumulative read scopes; the owner’s registration remains responsible for pushes. Battery health does not appear in LIVE_PANEL. No grant means the other organisation sees no feed.
Huawei FusionSolar, Sungrow iSolarCloud, SMA ennexOS and SolarEdge are reserved provider values. Their live adapters and pull jobs are not opened. Opening a cloud path needs a signed data schedule naming it, the customer’s vendor account and an approved egress destination. Commercial provider rows require a credential reference and cannot be activated while the trigger is unmet. Development, test and production defaults resolve the Mock with network access forbidden.
