DEV Community

Cover image for ⚡ Dad Complains About Electric Bill, So I Built Him an Energy Dashboard and Found the Panels Lied ⚡
Anna Villarreal
Anna Villarreal Subscriber Community Curator

Posted on

⚡ Dad Complains About Electric Bill, So I Built Him an Energy Dashboard and Found the Panels Lied ⚡

Hacktoberfest Weekend Challenge: Build for a Friend Submission 🤝

This is a submission for the Hacktoberfest Weekend Challenge: Build for a Friend

What I Built

My dad recently complained about how high the electric bill was. Most of us know the feeling: the impending doom of being the culprit, because you're the "computer person." (We'll see about that, Dad!)

So I set out on a mission to prove I was not the sole contributor to the high electric bill, and I built my dad a resource to actually understand it. It turned into much more than a re-skinned utility app. It pulls together:

  • Live data from our solar panels, straight from the Enphase gateway on our home network, every minute, down to each individual panel
  • A Problems list that flags dead microinverters, panels producing less than their neighbors, expiring tokens, and big jumps in home usage
  • Government data on what our roof should produce: PVWatts, a model from the U.S. national renewable energy lab, drawn as markers on the monthly chart so we can see if we're falling short
  • Our actual electric bills from ComEd, combined with the solar data to work out how much power the house really uses, compared to last year and to the average Illinois home
  • Where the power goes: per-device and per-room usage from smart plugs in Home Assistant, ranked by what each one costs per month (Smart plugs ordered, not here yet!)
  • Dad's briefing: a short, plain-English note at the top of the dashboard, written by Gemma running locally on our home PC, that explains all of the above without a single chart

I'll be honest, it turned into chaos.

dashboard charts


The roof mystery

Everything was fun and games at first, connecting an API here, pulling in a spreadsheet there. Our solar company even has a free developer portal. Then I started digging deeper than I'd planned. I learned there was an optional consumption meter our system could have had, but it was never installed. I learned you can put devices on your circuit breaker to see which circuit (or room, like my brother's... cough cough) is using what at any moment.

We already knew two of the microinverters were bad. What alarmed me was when my app started warning that some random panels were underperforming: four more, reporting between 11% and 30% of their normal output. They weren't clustered in one area.

Confused, I stepped outside to see if a squirrel had built a house up there. Nope, just neatly positioned solar panels... wait. They run up the roof vertically. That's not what they look like on the map. I went in and out of the house several times, standing on chairs, taking pictures, and showing my dad. Dad! They are not horizontal!

strange panels

panels in new app

It took some convincing from a difficult angle, but I proved it. And it wasn't just the orientation. The official app (and mine, since it uses the same layout) shows two long rows and then a short row. What's actually on the roof is long, short, long. A bona fide discrepancy.

Here's why. Two to three years ago, storms ripped through the neighborhood and damaged our roof. Insurance covered it, but to fix a roof you have to take the solar panels down. The whole process took 18 months. When the panels went back up, everything seemed fine. Shortly after, the two microinverters stopped responding.

I'd been blaming the underperformers on wildfire smoke, a dust storm, and bird poop. Then it clicked: whoever reinstalled the panels never updated the map. The system reports panels in places they are not. To test it, I checked where a tree's shade actually lands. It does cover some panels. Just not the ones the map says are underperforming.

Why does this matter? If I point a technician at "the second panel in the first row" and it's really the one next to it, he "fixes" the wrong panel, says "you'll see it working tomorrow," and I can't prove anything. That could get expensive. Before I start directing people, I need to know exactly which panel is which. That call to the solar company is coming, and it's going to be a serious one.


So, was it me?

Not guilty

Partly in my defense: ComEd raised prices about 12% for all residents. Add two dead microinverters (plus whatever is going on with the mystery panels) and a full house, and the bill makes a lot more sense. To be fair, the dashboard also says the house really is using more power than last year, which is exactly why the smart plugs are next. Soon we'll know who.

DAD'S REACTION:
I have been instructed to contact Enphase and find out what is going on with the solar panels, at which point I will then be able to contact someone to come climb on the roof and do the actual fixing.


Demo

The live dashboard is password-protected because it shows our home's real data. A temporary view has been created for judges with password that expires in 30 days: Dev_judge$

Preview the drama in action:
Solar Dashboard


Code

Solar dashboard

Private dashboard for the home Enphase system: https://solar-dashboard-coral.vercel.app

Home PC ── collector/collector.mjs (every 60 s)
   ├─ Ollama (gemma3:4b, local) ── Dad's briefing every 6 h
   ├─ IQ Gateway (192.168.1.166, local API, owner token)
   └─ APC UPS (not yet — needs APC USB cable 940-0127)
        │ POST /api/ingest  (Bearer INGEST_SECRET)
        ▼
Vercel (Next.js 16) ── Upstash Redis ── dashboard page (DASHBOARD_PASSWORD)
        ▲
        └─ /api/cron/daily (Vercel Cron, 11:00 UTC) → Enphase cloud API v4
           summary + daily history, ~3 calls/day of the free 1,000/month

Collector

Runs from the Windows scheduled task Solar Dashboard Collector (starts at logon, hidden logs to collector/collector.log).

node collector/collector.mjs --once --print   # one reading, printed and pushed
node collector/collector.mjs --probe          # dump raw gateway JSON to collector/probe/
Enter fullscreen mode Exit fullscreen mode

Config is collector/.env (template: collector/.env.example). The gateway token expires yearly — the dashboard's Problems list warns 30 days ahead. Renew at https://entrez.enphaseenergy.com using the homeowner login (not…


How I Built It

Home PC ── collector (Node, every 60 s)
   ├─ Enphase IQ Gateway (local API, per-panel data)
   ├─ Home Assistant (smart plug wattage + rooms)
   └─ Ollama + Gemma 3 4B ── Dad's briefing every 6 h
        │
        ▼
Vercel (Next.js 16) ── Upstash Redis ── dashboard
        ▲
        └─ daily cron → Enphase cloud API (history)
Enter fullscreen mode Exit fullscreen mode
  • Next.js 16 on Vercel for the dashboard, with Upstash Redis for storage
  • A small Node collector on our home PC that reads the Enphase gateway on the local network and Home Assistant every minute
  • Enphase's cloud API (the free developer tier) for years of history, ComEd's Green Button export for the bills, and PVWatts for expected production

The open-source AI piece is Gemma 3 4B running in Ollama on that same home PC. A dashboard full of charts is great for me, but my dad doesn't want charts. He wants to know three things: is the solar working, why is the bill what it is, and does he need to do anything?

Every six hours the collector asks the dashboard for a small set of facts (today's production versus expected, the latest bill versus last year, the Problems list), hands them to Gemma with instructions to explain them like a helpful family member, and posts the result back to the top of the dashboard. It takes about 20 seconds. Here's a real one:

Overall, your solar panels produced a good amount of electricity this month.

  • The microinverters 202015011110 and 202101033131 are not reporting. You need to contact Enphase support immediately with the serial numbers to get these fixed under warranty.
  • Your electric bill is $270.48, which is much higher than last year's $46.12. This is because your home uses 76 kWh per day, compared to 44 kWh per day last year.
  • Solar panels covered 41% of your electricity use.

Dad's Briefing

Building the briefing turned up a bug, too. After sunset, the dashboard told us 0 of 23 panels were working, with 21 critical alerts. Microinverters run on the panels' own power, so after dark every one of them goes quiet, and the gateway's flags can't tell a dead unit from nightfall. If Gemma had read that, it would have told my dad his whole roof had died. Now a panel only counts as dead after a full day with no report.


Why Does Open Innovation Matter? 🤔

  • The data stays home. The briefing is built from our electric bills, our usage, and the details of our system. With a local model, none of that goes to an AI company. It never leaves the PC in our house.
  • It costs nothing to run. A note every six hours, forever, for $0. A paid API would turn a family tool into a monthly bill, which is a little ironic for an app about lowering the bill.
  • I can swap the model with one line. It's OLLAMA_MODEL=gemma3:4b in a config file. If a better small model comes out, or Dad wants it to sound different, I change one setting. No vendor, no migration.
  • Open data made the whole thing possible. The solar gateway has a local API on our network, PVWatts is free public data, and the utility exports bills in an open format. Being able to combine them is what exposed the panel mix-up in the first place.

My Agent Session

I built this with Claude Code, and every session is tracked with Entire, which links each AI session to the commits it produced.


Prize Categories

  • Best Use of Entire: every AI session in this build is saved and linked to its commits. I can run entire why on any line to see the prompt, session, and commit that produced it, and entire search across the whole build process. This is actually very organic feeling, and awesome. Example:

Navigating with Entire

  • Best Use of Gemma: Gemma 3 4B, running locally, is what turns the dashboard into something my dad can actually read. (Dad's Briefing) 😂

Top comments (1)

Collapse
 
ssapable profile image
ssapable •

"Dad! They are not horizontal!" is the best ending a dashboard post has had on DEV, so I turned the post into a 50-second hand-drawn cartoon: the bill landing on the computer person, the per-panel grid with the problems list and Dad's no-charts briefing, then the four panels at 11 to 30 percent, the chairs, and the roof that runs vertically while the map had it sideways. No strings, yours to use or ignore, on a plain page with no sign-up:

ssap-pa.github.io/scripttoon-samples/

If any number or detail is off, name the shot and I'll re-render it. One question: once you corrected the panel layout in your app, did the four "underperforming" panels turn out to be fine, or was one of them actually weak?