Skip to content
All work

Case study · 02 / 06

Solar SCADA Platform

A configuration-driven SCADA platform for Alta Vision's solar plants and mini-grids in Sri Lanka — live OPC UA and MQTT telemetry from GoodWe inverters and SEC3000 controllers, on web, desktop, and mobile.

Largest plant on the platform, beside a 25 kW mini-grid
2 MW
OPC UA datapoints mapped in one plant config
~270
Offline PWA, Electron desktop, Capacitor mobile
3 form factors
Deployed across Alta Vision sites in Sri Lanka
In production
Screenshot of Solar SCADA & Mini-Grid Management Platform (Alta Vision)

Context

Alta Vision operates solar assets that range from a 25 kW office mini-grid in Athurugiriya to the 2 MW Ranna solar plant, each with different inverters, controllers, and data protocols. Off-the-shelf SCADA packages tie the operator to one vendor's hardware and assume reliable connectivity, which rural Sri Lankan sites do not have. The company needed one dashboard that could be re-pointed at any plant's OPC UA address space and keep running on-site even when connectivity drops.

I architected and built the platform end to end at Alta Vision: the Next.js application, the OPC UA/MQTT/WebSocket data layer, the per-plant configuration system, the AI-assisted datapoint generation, and the Electron and Capacitor packaging that puts the same codebase on plant PCs and phones.

01

One codebase, many plants: configuration as the product

Every screen is generated from a typed DataPoint config — OPC UA node ID, data type, scaling factor, unit, UI widget, category. Commissioning a new site means producing a new config file, not new React code: the repo carries per-plant configs for the Colombo office mini-grid, the Ranna 2 MW plant, and a university research site, with inject scripts that swap the active plant. The Colombo config alone maps roughly 270 node IDs covering GoodWe inverter and SEC3000 controller registers.

02

Talking to industrial hardware from Node

The data layer runs node-opcua against the plant's OPC UA server, with MQTT subscriptions and raw WebSockets feeding the browser in real time. Inverter registers arrive as scaled integers (5163 meaning 51.63 V), so every datapoint declares its factor and OPC UA data type explicitly — getting a type wrong corrupts a reading silently, which is why the config is the single source of truth rather than ad-hoc parsing in components.

03

AI-assisted commissioning instead of hand-typing register maps

Mapping hundreds of registers per site by hand was the slowest part of every deployment, so I added an AI configuration path: an OPC UA discovery pass dumps the server's address space, and a Gemini-backed API route generates candidate DataPoint definitions — names, units, scaling, widget types — for an engineer to review. A configurable AI assistant with plant telemetry in its context also answers operator questions on the dashboard.

04

Offline-first, because the grid edge has bad internet

Sites cannot depend on connectivity, so the app runs as a local PWA served from a plant PC, with SQLite/IndexedDB persistence, backup and restore endpoints, and Windows installer scripts for non-technical deployment. The same build packages as an Electron desktop app and a Capacitor mobile app that points at a configurable backend URL, so operators get identical dashboards on the control-room PC and their phone.

Stack & architecture

  • Next.js App Router + React 19 + TypeScript, with Zustand for client state
  • node-opcua client against plant OPC UA servers; MQTT and raw WebSocket streams to the browser
  • Typed per-plant DataPoint configs (node ID, data type, scale factor, widget) drive all UI rendering
  • Google Gemini API routes for AI datapoint generation and a telemetry-aware operator assistant
  • Single-line-diagram editor built on React Flow; drag-and-drop dashboards; Recharts for history
  • better-sqlite3 + IndexedDB for local persistence, with backup/restore API routes
  • Offline PWA plus Electron (Windows/macOS/Linux) and Capacitor (Android/iOS) packaging
  • Radix UI + Tailwind CSS v4, light/dark themes, alarm system with visual and audio alerts
  • Next.js
  • React
  • TypeScript
  • OPC UA
  • GoodWe SEC3000
  • AI Optimization

Where it stands