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.
We accept pull requests! Read the instructions in our contribution guidelines for more details.
SparkMeter uses Flask CLI for management commands. All commands use uv run flask as the prefix.
# 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 listAvailable roles: operator (admin), vendor, api
# 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# 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# Reset the database
uv run flask database reset --force
# Reset and load demo data
uv run flask database reset-demo --forceThe bare commands resetdb, demo, and initdb still work as deprecated aliases.
# Run development server
uv run flask run
# Open interactive shell
uv run flask shell
# Show application status
uv run flask statusFor Docker deployments, run the same commands inside the webapp container with docker compose exec:
docker compose exec ground uv run flask user createThis document is to help you get the development environment up and running. You can choose between two options, hit either of the links below for more details:
Dockerized development happens in the groundbolt-dev workspace metarepo, 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.
$ docker compose -f docker-compose.test.yml run --rm testOverride 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::CustomerAddTestDatabase 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.
Logs for a single service can be tailed via
$ docker compose logs <service> --tail=500Live logs from a service can be streamed via
$ docker compose logs <service> -fTo follow every service's logs in one stream:
$ docker compose logs -fTo setup a development environment locally, you need to follow the steps below:
Head to the dependencies section and make sure you have all the necessary tools installed before you proceed with this step.
$ uv sync --group devFor an empty database:
$ uv run flask database reset --forceOr, 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 --forceCreate an operator (admin) user:
$ uv run flask user create -u admin -e admin@example.com -p password -r operatorOr interactively:
$ uv run flask user create-
You can now run the development web server using the following command:
$ uv run flask run
-
Open up your browser, and go http://localhost:5000/ and login with the credentials you created.
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 devInstall 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.
$ sudo apt-get update
$ sudo apt-get install postgresql # only for local-DB workflows
$ sudo apt-get install nodejs npm # only for frontend work
Install Homebrew per the instructions at brew.sh, then:
$ brew install postgresql # only for local-DB workflows
$ brew install node # only for frontend work
Thanks goes to these wonderful people (emoji key):
This project follows the all-contributors specification. Contributions of any kind welcome!