GridSense ⚡
End-to-end platform for real-time solar generation forecasting and power quality monitoring — from raw inverter data to live public dashboard.
Live dashboard → your-app.streamlit.app | API docs → your-api.fly.dev/docs
What it does
GridSense transforms raw data from solar inverters and electrical grid sensors into generation forecasts and disturbance alerts — all running in production, fully tested, and installable with a single command.
pip install gridsense
from gridsense.pq.classifier import PQClassifier
from gridsense.battery.soc import SoCEstimator
import numpy as np
# Classify a power quality disturbance from a raw voltage waveform
clf = PQClassifier.load()
waveform = np.sin(2 * np.pi * 60 * np.linspace(0, 1, 1024))
result = clf.predict(waveform)
print(result)
# PQResult(label='normal', confidence=0.98, timestamp=...)
# Estimate battery State of Charge
est = SoCEstimator(capacity_ah=10.0, initial_soc=0.85)
soc = est.update(current_a=-2.5, dt_seconds=15)
print(f"SoC: {soc * 100:.1f}%")
# SoC: 84.9%
Architecture
flowchart TD
subgraph Sources["Data Sources"]
A[Solar Inverter\nModbus RTU/TCP]
B[Weather API\nINMET Brazil]
C[Battery Sensors\nLi-Ion 3S Pack]
end
subgraph Core["Platform Core · gridsense package"]
direction TB
D[gridsense.ingest\nmodbus · weather · battery]
E[gridsense.forecast\nsolar · trainer · monitor]
F[gridsense.pq\nfeatures · classifier · events]
G[gridsense.battery\nsoc]
end
subgraph Infra["Infrastructure"]
H[(TimescaleDB\nTime-series hypertables)]
I[Prefect\nDAG orchestration]
J[Evidently AI\nDrift detection]
end
subgraph Outputs["Outputs"]
K[FastAPI REST\n/predict /events /soc]
L[Streamlit Dashboard\nPublic · Live]
end
A --> D
B --> D
C --> D
D --> H
I -->|15 min cadence| D
H --> E
H --> F
H --> G
E --> J
E --> K
F --> K
G --> K
K --> L
Model Performance
Evaluated on 90 days of synthetic Brazilian solar data (Florianópolis, SC).
| Metric | Value |
|---|---|
| Solar forecast MAE | ~0.18 kW |
| Solar forecast RMSE | ~0.26 kW |
| PQ classifier accuracy | ~97 % (6-class, synthetic IEEE 1159) |
| PQ classifier F1 (macro) | ~0.96 |
| SoC estimator error | < 1 % over full charge cycle |
| Test coverage | ≥ 80 % |
Quick Start
Install
pip install gridsense
Run the full stack locally (Docker)
git clone https://github.com/YOUR_USERNAME/gridsense.git
cd gridsense
docker-compose up --build
| Service | URL |
|---|---|
| FastAPI | http://localhost:8000/docs |
| Streamlit | http://localhost:8501 |
| Prefect UI | http://localhost:4200 |
| TimescaleDB | localhost:5432 |
Development install
git clone https://github.com/YOUR_USERNAME/gridsense.git
cd gridsense
pip install -e ".[dev,dashboard]"
make test-unit
make lint
Project Structure
gridsense/
├── src/gridsense/
│ ├── pq/ # Power quality: DWT features, classifier, event log
│ ├── battery/ # Li-Ion SoC estimation (Coulomb Counting + OCV)
│ ├── ingest/ # Modbus reader, INMET weather client
│ ├── forecast/ # Solar forecaster, trainer, drift monitor
│ ├── db/ # TimescaleDB connection + SQLAlchemy ORM models
│ └── api/ # FastAPI app, routers, Pydantic schemas
├── pipelines/ # Prefect flows: ingest, forecast, retrain
├── dashboard/ # Streamlit app
├── tests/
│ ├── unit/ # ~80 tests, no external deps
│ └── integration/ # FastAPI ASGI tests
├── docker/ # Dockerfiles for api, pipeline, dashboard
├── docker-compose.yml
├── pyproject.toml
├── Makefile # make test-all · make release · make docker-up
└── TESTING.md # Step-by-step testing guide
Data Sources (Brazil)
| Source | URL | Notes |
|---|---|---|
| INMET (weather) | https://apitempo.inmet.gov.br | Free, no auth. Station A801 = Florianópolis |
| ANEEL (solar gen) | https://dadosabertos.aneel.gov.br | CSV, monthly update |
| Synthetic PQ waveforms | Generated locally | Per IEEE 1159-2019 standard |
Roadmap
- Phase 1 — Testable core (PQ + Battery modules, CI)
- Phase 2 — Data & orchestration (DB, ingest, forecast, Prefect)
- Phase 3 — API, dashboard, open source release
- Phase 4 — Live data from INMET A801, real model metrics
- Phase 5 — Kalman Filter SoC estimator
- Phase 6 — MQTT ingestion for real Modbus inverters
Contributing
See CONTRIBUTING.md and good first issues.
License
MIT — see LICENSE.
Metadata
Release files for gridsense 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| gridsense-0.1.0.tar.gz | 58.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| gridsense-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 95.3 kB
Release files / gridsense-0.1.0.tar.gz
| Download URL | gridsense-0.1.0.tar.gz |
|---|---|
| Size | 58.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
7a6d6ca35672a64081d84753dfa093c47cfa2eddaf8187a25e73b7176b480568
|
|
BLAKE2b-256 checksum How to use checksums |
3134492c84c38350dfdecbf11c4081c02826ee170ee3db36e6b06b2e40d7bf47
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.14
|
Release files / gridsense-0.1.0-py3-none-any.whl
| Download URL | gridsense-0.1.0-py3-none-any.whl |
|---|---|
| Size | 37.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
4e6799538c74b83efa4a28153a2ce0f54ca25de1eb3d6f404c837ce86af8e3e0
|
|
BLAKE2b-256 checksum How to use checksums |
235d93a1b0a6ea7c3aba4e23f0a41f47144ac245631c9d4fe443b23450e0362d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.14
|