Portfolio & site detail
The portfolio view, the site → inverter → string → optimiser hierarchy, and how the data flows from upstream APIs into both.
The portfolio view
The dashboard at /dashboard is your morning view. It shows every site in your org with the headline numbers an O&M team actually opens at 09:00:
- Power now — current kW output, refreshed every poll.
- Today — kWh generated since midnight, site-local.
- Performance ratio — actual generation against the weather-normalised expectation.
- Δ 7d — change vs the rolling 7-day baseline for the same time of day.
- Cases — open case count per site, colour-coded by highest severity.
The default sort is worst-first: anything in a critical state floats to the top. You can group by client, region or installer, or sort by name / size / output. The sort applies to the fleet map too — pins change colour and ring size based on status and capacity.
Site detail
Click any row to drill into the site. Site detail mirrors the electrical hierarchy:
- Site — meta (address, capacity, owner, install date, warranty clocks), today's generation, this month's revenue, hero photo and the right-rail contact card.
- Inverter — per-inverter power, temperature, uptime, firmware version and serial number.
- String / MPPT — voltage and current per channel, side-by-side. Outliers stand out instantly.
- Optimiser — when the upstream API exposes per-optimiser data (SolarEdge with the right tier), each module's state is visible as a coloured tile. Twelve of fourteen offline on string C reads at a glance.
Tabs across the top: Overview, Equipment, Alerts, Cases, Visits, Reports, Documents, Settings.
Charts and the time-range selector
Every chart respects a shared range selector: 24H, 7D, 30D and 1Y. Units adapt automatically — power-per-hour for 24H, energy-per-day for 7D/30D, energy-per-month for 1Y.
Two charts deserve a word:
- Generation vs expected — the actual output curve overlaid on the weather-normalised model band. When the actual sits inside the band you're performing as expected for that day's weather; when it dips below for an hour the alert engine notices.
- Performance ratio over time — daily PR with a 30-day rolling line, so seasonal drift and step changes after a service visit both show up.
Polling cadence
Two cron schedules drive the data:
- SolarEdge: every 15 minutes. Telemetry arrives in 15-minute buckets upstream, so faster polling wouldn't help.
- Solis Cloud: every 5 minutes. The Solis API publishes 5-minute readings and we pull at that cadence.
- Open-Meteo weather: hourly. See weather & expected generation for what we do with it.
Stale data handling
"Power now" and the Live indicator are gated against staleness. If a site hasn't reported in over twice its polling interval, the headline number greys out and a "last seen" timestamp appears. We won't keep showing the value from last hour as if it's current.