Skip to content

Latest commit

 

History

62 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

sparkmeter

All Contributors

Also known as ThunderCloud (when deployed to the cloud) or GroundBolt (when deployed to the base station on the ground)


Warning

Developer preview — not for production use.

This version is a developer preview, intended for evaluation and development only. It is not ready to manage a live micro-grid and must not be deployed to production or used for real customer metering or billing. Expect breaking changes between preview versions.

A web application used by utility companies to manage their micro-grids remotely.

Contributing

We accept pull requests! Read the instructions in our contribution guidelines for more details.

Flask CLI Commands

SparkMeter uses Flask CLI for management commands. All commands use uv run flask as the prefix.

User Management

# Create a user (interactive)
uv run flask user create

# Create a user with options
uv run flask user create -u username -e email@example.com -p password -r operator

# List all users
uv run flask user list

Available roles: operator (admin), vendor, api

Meter Management

# Create a new meter
uv run flask meter create -s SERIAL_NUMBER

# Create a meter with address
uv run flask meter create -s SERIAL_NUMBER --street1 "123 Main St"

# Remove a meter
uv run flask meter remove -s SERIAL_NUMBER

# Convert customer meter to totalizer
uv run flask meter convert-to-totalizer -s SERIAL_NUMBER

# Convert totalizer to customer meter
uv run flask meter convert-to-customer -s SERIAL_NUMBER -t TARIFF_NAME

Tariff Management

# Create a new tariff
uv run flask tariff create -n TARIFF_NAME -r RATE [-l LOAD_LIMIT]

# Example: Create tariff with rate 80 and load limit 12W
uv run flask tariff create -n ET1 -r 80 -l 12

# List all tariffs
uv run flask tariff list

Database Management

# Reset the database
uv run flask database reset --force

# Reset and load demo data
uv run flask database reset-demo --force

The bare commands resetdb, demo, and initdb still work as deprecated aliases.

Other Commands

# Run development server
uv run flask run

# Open interactive shell
uv run flask shell

# Show application status
uv run flask status

For Docker deployments, run the same commands inside the webapp container with docker compose exec:

docker compose exec ground uv run flask user create

Meter drivers

A meter driver is a separate service that reaches the meters through their gateway radio; Thundercloud talks to it over the HTTP+SSE contract (and optionally gRPC) of the Meter Driver Specification, version 1.4.0. Any driver that implements the spec's required contract works, including the meter-driver-emulator for development.

Run the driver as its own service, then register it from the running ground app under Global Settings > Meter Drivers > Register driver by entering the base URL of its HTTP service. Registration checks the driver's openapi.json against the spec and reports what is missing. The document's x-meter-driver block lists the driver's interfaces; when it advertises none, an http interface at the base URL is assumed. Selecting gRPC requires the driver to advertise a gRPC target. Registration also asks the driver which init fields it needs and writes them, with their types, to meter_driver_configs/<id>.json.

Fill in those fields under Global Settings > Meter Drivers > Edit config and save: the values are validated against the discovered fields and sent to the driver's init endpoint, and the outcome is recorded in the same file. The same init is re-sent whenever Thundercloud starts. Registered drivers become selectable per meter on the meter form.

The groundbolt-dev workspace runs a meter driver alongside the webapp for development, the meter-driver-emulator, so developing Thundercloud needs no gateway hardware and no vendor driver. Which driver a deployment uses is the deployment's choice, not a dependency of this application.

Development

Important

The development environment lives in the groundbolt-dev workspace, not in this repo. Start there: its README walks you through cloning this repo alongside its sibling components and bringing up the whole system with Docker Compose.

This webapp is one component of a larger system. On its own it has no database, no metering provider to talk to, and no ground↔cloud sync. The groundbolt-dev workspace runs all of those — the ground and cloud webapps, their Postgres databases, the SymmetricDS sync pair, and the sparknet-http metering provider — from a single compose file, which is why development setup happens there rather than here.

What stays in this repo:

  1. Docker — the self-contained unit-test harness (docker-compose.test.yml) and webapp-specific commands.
  2. Local — running just the webapp process directly on your machine, without Docker. Only useful for narrow webapp-only iteration; most people don't need this.

Docker

Dockerized development happens in the groundbolt-dev workspace, which clones this repo and its sibling component repos side by side and runs the whole system — the ground and cloud webapps, their databases, the SymmetricDS sync pair, and the sparknet-http metering provider — from a single compose file. See that repo's README for setup.

This repo's docker-compose.test.yml is the self-contained test harness: a throwaway Postgres plus the test-image runner, needing nothing outside this repo. It's what CI runs.

Useful commands

Run unit tests
$ docker compose -f docker-compose.test.yml run --rm test
Run a subset of unit tests

Override the test service's command with a pytest invocation. Any pytest arguments can be passed:

$ docker compose -f docker-compose.test.yml run --rm test uv run pytest <path/to/test>[::ClassName][::method_name]

For example, running the tests for the AddCustomer endpoint in the API:

docker compose -f docker-compose.test.yml run --rm test uv run pytest sparkmeter/api/tests/test_customerviews0.py::CustomerAddTest
Create a new database migration

Database schema migrations are managed via Alembic. To get started, you must first create a migration file:

uv run flask database new-revision "<short description of the migration>"

(Or run the same command inside the webapp container of a running Docker stack, via docker compose exec.)

This will generate a skeleton migration file in sparkmeter/alembic/versions/. From there, customize it your liking.

Tail the logs of a service

Logs for a single service can be tailed via

$ docker compose logs <service> --tail=500

Live logs from a service can be streamed via

$ docker compose logs <service> -f

To follow every service's logs in one stream:

$ docker compose logs -f

Local

Note

This is not the standard development setup — that's the groundbolt-dev workspace. The steps below run only the webapp process, directly on your machine: no metering provider, no cloud side, no sync. Use this only if you specifically want to iterate on webapp code without Docker (you'll need a local PostgreSQL — see OS Requirements).

To set up the webapp by itself locally, follow the steps below:

1. Setup the project and install the dependencies

Head to the dependencies section and make sure you have all the necessary tools installed before you proceed with this step.

$ uv sync --group dev

2. Create the database

For an empty database:

$ uv run flask database reset --force

Or, for a database pre-populated with demo data (this also resets, so there's no need to run both):

$ uv run flask database reset-demo --force

3. Create an admin user

Create an operator (admin) user:

$ uv run flask user create -u admin -e admin@example.com -p password -r operator

Or interactively:

$ uv run flask user create

4. Run the server

  1. You can now run the development web server using the following command:

    $ uv run flask run
  2. Open up your browser, and go http://localhost:5000/ and login with the credentials you created.

Installing Dependencies

Python Requirements

The requirements are kept in pyproject.toml where only the actual modules we want installed are kept. All child dependencies are calculated using uv to generate a uv.lock file of pinned packages.

The requirements are split into two groups. [project] dependencies holds only production requirements. [dependency-groups] dev is the development-only group.

To resync the venv from the lockfile:

uv sync --group dev

OS Requirements

Install uv per the instructions at docs.astral.sh/uv/getting-started/installation. uv manages Python, the virtual environment, and the locked dependencies.

If you plan to run the database locally (instead of via the postgres-ground Compose service), install PostgreSQL too.

If you plan to work on frontend assets under scripts/config/, install Node.js as well.

Ubuntu
$ sudo apt-get update
$ sudo apt-get install postgresql       # only for local-DB workflows
$ sudo apt-get install nodejs npm       # only for frontend work
macOS

Install Homebrew per the instructions at brew.sh, then:

$ brew install postgresql               # only for local-DB workflows
$ brew install node                     # only for frontend work

Contributors

Thanks goes to these wonderful people (emoji key):

Tristan Escalada
Tristan Escalada

💻 📖 🚇 🛡️ 🤔 🚧 📦 👀 🔧
Arthur Jacquiau-Chamski
Arthur Jacquiau-Chamski

🐛 💼 💻 🔣 📖 🎨 💡 🤔 🧑‍🏫 📦 📆 💬 🔬 👀 🔧 🌍 ⚠️ ✅ 📓
Johan Dahlin
Johan Dahlin

💻 📖 🚇 🛡️ 🤔 🚧 📦 👀 🔧 ⚠️ 🎨 🌍
shawnchurchill
shawnchurchill

⚠️ 🚇
Conrad Hollomon
Conrad Hollomon

💻 ⚠️ 📖 🚇
Duncan
Duncan

🚇 🔧 🚧
Lawrence Moore
Lawrence Moore

💻 ⚠️ 🎨
Sally Lee
Sally Lee

💻 ⚠️ 📖 🚇
Dan
Dan

💻 ⚠️ 🚇
Jon Thacker
Jon Thacker

💻 ⚠️ 📖 🚇
Aru Sahni
Aru Sahni

💻 ⚠️ 📖 🚇 🎨
Bill Young
Bill Young

🚇
Ben Postman
Ben Postman

🔧
Hisham Elsheshtawy
Hisham Elsheshtawy

💻 ⚠️ 📖 🚇
Martin Wagner
Martin Wagner

💻 ⚠️ 🚇 🎨
Daniel Berliner
Daniel Berliner

💻
Clay Sampson
Clay Sampson

🚇 🚧
LyncTechLLC
LyncTechLLC

💻 🐛 📖 🎨 🤔 🚧 🔌 🛡️ 🔧 ⚠️
James Ranson
James Ranson

📖 🚇 🛡️
A-Archambault
A-Archambault

🐛 💼 🔍 🤔 📣
Add your contributions

This project follows the all-contributors specification. Contributions of any kind welcome!

About

Web application for utility companies to manage micro-grids remotely. Deployed as ThunderCloud (cloud) or GroundBolt (base station).

Topics

Resources

Contributing

Security policy

Stars

9 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages