Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
488d4ba
Point development setup at the groundbolt-dev workspace
tescalada Sep 22, 2026
e14ac90
Post driver init to /v1/init and stop deriving a gRPC target from the…
tescalada Sep 22, 2026
c50e4f5
Validate driver contracts against the spec's required routes and x-me…
tescalada Sep 22, 2026
f069d4e
Build the driver init payload from the discovered required fields
tescalada Sep 22, 2026
af82de8
Subscribe to /v1/events with only the X-Client-Id header
tescalada Sep 22, 2026
ac991e2
Recognize only the spec's event type names on the SSE stream
tescalada Sep 22, 2026
3ec649e
Test the driver client end to end against a spec-only driver
tescalada Sep 22, 2026
cbfff30
Check contract operations, guard document shapes, and split interface…
tescalada Sep 22, 2026
2c8cc53
Refuse a gRPC selection the contract cannot honor at registration time
tescalada Sep 22, 2026
2ba699a
Keep ASGI startup alive when a saved gRPC selection has no target
tescalada Sep 22, 2026
ca93866
Leave init-value checks to the config validator
tescalada Sep 22, 2026
f23a5d7
Emit only type, event_id and data from the gRPC event stream
tescalada Sep 22, 2026
5cbe4da
Document meter drivers against the Meter Driver Specification
tescalada Sep 22, 2026
377dc95
Offer optional InitRequest properties as optional init fields
tescalada Sep 24, 2026
ace7dc8
Render unset gRPC submessages as their defaults
tescalada Sep 24, 2026
5eff7bf
Keep a healthy driver online when /v1/status is not an object
tescalada Sep 24, 2026
717ca1c
Expect the optional channel in the spec-only driver reconcile test
tescalada Sep 24, 2026
d71df42
Merge branch 'main' into driver-spec-conformance
tescalada Sep 24, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 20 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,17 +103,29 @@ docker compose exec ground uv run flask user create

## Meter drivers

Thundercloud is not tied to any one meter driver. It talks to a driver over the HTTP+SSE
contract (and optionally gRPC) from the Thunder-Cloud 2.0 Open Source Meter Driver
Specification, so any compliant driver works — SparkNet-Http or a third party's.
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](https://github.com/EarthSpark/meter-driver-spec), 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. Registered drivers become selectable per meter on the meter form.

The groundbolt-dev workspace metarepo runs `sparknet-http` as part of its stack for
convenience during development; that is a choice of that stack, not a dependency of this
application.
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](https://github.com/EarthSpark/groundbolt-dev) 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

Expand Down
4 changes: 4 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ dependencies = [
"meter-driver-spec @ https://github.com/EarthSpark/meter-driver-spec/releases/download/v1.4.0/meter_driver_spec-1.4.0-py3-none-any.whl",
"protobuf",
"grpcio",
# sparkmeter.config.provider_settings catches pydantic.ValidationError
# raised by the meter-driver-spec models, so pydantic is a dependency of
# this package and not only of meter-driver-spec.
"pydantic",
"click",

# dates and times
Expand Down
2 changes: 2 additions & 0 deletions sparkmeter/config/configviews.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ def meter_driver_edit(provider_id):
provider_details = get_live_interface_details(
provider["base_url"],
selected_interface=provider["selected_interface"],
provider=provider,
)

form = MeterDriverSettingsForm(
Expand Down Expand Up @@ -171,6 +172,7 @@ def meter_driver_config(provider_id):
provider_details = get_live_interface_details(
provider["base_url"],
selected_interface=provider["selected_interface"],
provider=provider,
)
form = MeterDriverConfigEditorForm(
formdata=request.form if request.method == "POST" else None,
Expand Down
Loading
Loading