The system, in short
Our house in Mosgiel runs off a grid-connected solar and battery system. I built an insulated plant-room shed in the garden to hold it. 27 panels on the roof make power through the day, a ~16 kWh battery holds it for the evening, and software I wrote — kaitiaki-hiko — decides when to store each kilowatt-hour, use it, or send it to the grid. The aim is to cut our carbon, with a lower bill following on.
The numbers that matter
The fixed system specs, alongside live figures that update from the meter each morning.
What the system is doing right now
This isn't a live stream. Press the button to pull one reading straight from the system.
Return on investment
The model uses our confirmed tariffs and real winter usage. Generation and full-year figures are still being measured.
Progress to payback tracking
Real savings since the array came online: avoided grid imports plus export earnings, net of the ~5% mortgage cost on the money that paid for it, counting up toward the total system cost.
Measured vs projected early estimate
The tracker above is real money, but every day in it is midwinter, the two darkest months of the year. Scaling that measured performance up the site's solar-radiation seasonal curve gives a first estimate of the full-year return.
Capital cost
| Energy system (solar + Victron + battery + electrical) | $32,651 |
| Shed (shell, pad, framing, cladding) | $1,487 |
| Total CAPEX | $34,138 |
Simple payback
| Annual saving | Payback | ROI |
|---|---|---|
| $3,000 | 11.4 yr | 8.8% |
| $3,930 (base) | 8.7 yr | 11.5% |
| $5,200 | 6.6 yr | 15.2% |
As grid prices rise, every self-consumed kWh saves more; at +5%/yr the base payback drops toward about 8 years.
Time-of-use tariffs confirmed
ecotricity ecoSOLAR plan (Aurora network, partially-controlled), marginal c/kWh. Components are ex GST; the all-in row adds GST. Network peak = 7am–12pm & 5pm–10pm, every day.
| Import — what you pay | Off-peak | Peak |
|---|---|---|
| Energy + EA levy (ex GST) | 17.16 | 17.16 |
| Network (ex GST) | 8.87 | 14.87 |
| All-in (incl GST) | 29.93 | 36.84 |
Real bill (June 2026)
1,530 kWh imported over 30 days = 51 kWh/day, at $19.11/day incl GST (~39% in the peak window). Fixed charges add ~$2.04/day incl GST — Aurora lines, metering and the climate-positive premium. Export is negligible — about 99% self-consumed.


Projected solar — next week
Predicted daily generation for the coming days, using yr.no as the default forecast. The scale is fixed to the system's best day so far, so you can read each day against full capacity.
Which forecast predicts our solar best
Success = a day predicted within ±30% (or ±3 kWh) of what the array actually made, by how far ahead the forecast was issued. We track overall and the last 30 days, and run on whichever model scores best.
Where every kilowatt-hour came from
The past week's daily energy, stacked: grid import at the base, solar used in the house, then solar exported on top.
Solar & grid use over time
Daily totals from the system meter since the array came online.
Week by week
Each week's daily solar and grid use, with the change on the week before. Page back through earlier weeks with the arrows.
Charging the MG4 on our own sun
Our MG4, bought in 2023, is the household's only car — currently 40,000 km on the odometer. Its odometer, battery charge and range are now read straight from the car over MG iSMART, and it charges through the house on a Tuya charging pile, so every charge lands in the home energy data and I can see how much of it came from our solar rather than the grid.
Live from the car MG iSMART
Charging so far measuring
Logged every minute from the charger's own meter since —, split solar-vs-grid by what the house was doing at the time. Battery discharge counts as stored solar.
What it costs to drive estimated
Total running cost per kilometre: the grid electricity the car actually needed, plus Road User Charges of 7.6c/km (NZ EVs pay RUC on every km), plus ~2c/km servicing. Distance is estimated from energy at ~18 kWh/100 km between odometer updates.
The MG4 on our power
A petrol car, same road
Fuel (pump price already includes road tax) plus 7c/km servicing — oil, brakes, plugs, filters, transmission — against just ~2c/km for the EV (NZ industry figures). Like-for-like with the EV's electricity + RUC + servicing.
Method: the charger's energy counter is read each minute and split solar-vs-grid by the concurrent house mix. Distance and cost-per-km are estimated from energy at the efficiency shown; the grid share is priced on the real time-of-use tariff, plus Road User Charges at the current NZ EV rate (7.6c/km). The charging hardware is in the System details tab.
Keeping it road-legal
Prepaid Road User Charges and the Warrant of Fitness, tracked against the odometer and the calendar. I get a phone reminder as each nears due, and update the figures in Home Assistant when I buy more RUC or renew the WoF.
Road User Charges
Warrant of Fitness
How the energy flows
A grid-connected Victron ESS with AC-coupled solar. Panels feed a Solis grid-tie inverter; a Victron MultiPlus-II manages the battery, the grid, and backup power.
PV serves the house first → surplus charges the battery → the remainder exports to the grid (Ecotricity). After dark the battery discharges to cover load; the grid only tops up. On a power cut the Victron carries essential loads in under 20 ms.
Component inventory
| Component | Identification | Key specs |
|---|---|---|
| Battery inverter/charger | Victron MultiPlus-II 48/10000/140-100 | 10 kVA / 8000 W cont · charge 140 A ≈ 7 kW · <20 ms UPS |
| PV inverter | Solis S6-GR1P10K single-phase grid-tie + datalogger | 10 kW · dual-MPPT · AS/NZS 4777.2 |
| Battery | 48 V LiFePO₄, 16S | 314 Ah ≈ 16.1 kWh nominal |
| BMS | JK BMS (Jikong) | Active balance · RS485/CAN |
| PV DC isolators | 2 × NLINE NL432PV | AS 60947.3 · IP66 |
| PV array | 27 × 450 W panels, 2 strings | 12.15 kWp DC · 1.22× the 10 kW inverter |
| Retailer | Ecotricity — ISO 14067 climate positive | Time-of-use plan, Aurora network |
A day in the life: use the sun first, store the rest
The hardware follows this priority order by default; the software refines it.
The battery carried the house through the night.
PV covers the house directly — zero cost, zero carbon.
Surplus charges the battery, then exports the remainder.
The battery discharges to cover the most expensive, highest-carbon hours.
Grid tops up only when it's both cheap and clean.
What the house actually uses
Half-hourly meter data, 25 May – 13 Jun 2026 (20 midwinter days). The battery exists to shift the load that lands in the expensive peak windows.
~53 kWh / day
Midwinter average demand across the 20-day window.
47% in peak
Share of consumption in the ~37c/kWh peak windows — the load the battery time-shifts.
The EV is the load
Our EV is the household's only car, driving 30–90 km a day (the weekday Mosgiel↔Dunedin commute, ice hockey and other trips), and it's charged through the house. That's the bulk of the demand, and the obvious thing to move onto midday sun rather than the evening peak.
The plant room
A purpose-built, insulated shed in Mosgiel — built by hand — houses the whole energy system.
Why a separate shed
I built the shed myself and kept it detached from the house on purpose. A big lithium battery and inverter are better off in their own structure with their own air space, so the only building that touches the house is the garage, not the energy store. That keeps the heat, the noise and any fault risk out of the living space.
Building the Shed
I dug down and filled the hole 1.6m x 1.1m with AP2 gravel to 100mm. Then 18x20kg bags of concrete set with a rebates of 30mmx20mm so the walls of the Rite 2 shed sit below the conrete floor. Outside 1530 × 1080mm. Internal framing in 100×50 mm with a damp course; 15 mm ply on three sides, 6 mm on the street side, then 6 mm fibre-cement cladding. Roof: fibre-cement → Expol insulation → building paper → steel. Bolted down with 8 concrete screws and 10 roof screws.
Running my AI work on stored sun
A lot of my work involves AI. Where it makes sense I run that compute on the array's surplus, so midday sun does local processing instead of exporting cheaply. When a job can't wait for the sun it runs on ISO 14067 climate-positive grid power instead.
AI for coding
Most of my AI use is as a coding partner. I work with agents to build and maintain projects like PVEbot (a Discord moderation bot for extremism prevention), the Six-Animal-Model site, and the system this page describes.
University work
For teaching and research I run AI assistance on my work machine, keeping that separate from the home setup.
Local batch processing
For my own work I run models locally with Ollama to analyse documents and encode information. It stays on my machine and none of it is urgent, so it batches well.
Two clean pathways to run a job
Every batch job takes one of two lanes, both clean, chosen by how long it can wait.
Lane 1: guaranteed solar
Deferrable work waits for real surplus. It runs only when the panels are making more than the house is using and the battery is already full. No grid draw at all, just spare sun that would otherwise export at about 19c.
Lane 2: certified-green grid
Work that can't wait for the sun still runs clean. Our retailer Ecotricity is ISO 14067 certified climate positive, offsetting more carbon than its electricity emits, so grid power here is renewable and net-negative. The job runs now and the power is still green.
How the solar-gated queue works
Local models run under Ollama on the workstation GPU; a small scheduler decides when to let them loose.
Deferrable by design
Jobs are document analysis and encoding. They're private and not time-critical, so they can wait hours for the sun. Each one is a shell script (an ollama run … call) dropped into a queue folder.
Power-source-aware gate
Every ~2 minutes the runner reads live solar from the Victron system and releases a job only when surplus ≥ 1.2 kW and the battery is ≥ 80%. A lower 400 W stop threshold gives hysteresis, so a running job's own draw doesn't flap the gate off.
One at a time
The GPU runs a single model at once; finished jobs move to done/, failures to failed/, each with its log. When the sun dips the queue pauses and resumes later, so no job is lost.
Why local, not the cloud
Running my own models isn't just about power. Water, privacy and control matter too.
No water for cooling
Big AI data centres shed heat with evaporative cooling that uses fresh water, a real and growing draw on local supply. This GPU is air-cooled in the shed. It uses no water, and its waste heat warms the plant room instead of a cooling tower.
Data sovereignty
Documents are analysed on my own machine and nothing is uploaded to a foreign cloud. The data never leaves the house, so it stays private and under NZ jurisdiction because of how it's built, not because of a policy promise.
Compute sovereignty
My own hardware, running open-weight models I control. No dependence on an overseas provider's API, its pricing, throttling or uptime. It's self-hosted and runs off my own roof.
kaitiaki-hiko (guardian of electricity)
The software sits on top of the hardware. It isn't only there to save money. It tries to make sure every kilowatt-hour we move avoids carbon rather than causing it, and that we can measure the difference.
Safe by default
It boots monitor-only. Control is gated behind two explicit flags and dry-runs for weeks before it ever touches the inverter.
One write path
Nothing commands the inverter except through safety.clamp() — enforcing SOC limits, the LiFePO₄ cold-charge block, and BMS faults.
Carbon-aware
The goal is to charge when the grid is cheap and clean, and discharge when it's expensive or high-carbon. It optimises on price and gCO₂/kWh together, not price on its own.