Battery Twin Envelope (BTE): an open specification and reference SDK for expressing and exchanging battery digital twins
Project description
battwin
The Battery Twin Envelope (BTE): an open specification — plus reference SDK — for expressing and exchanging battery digital twins.
A battery digital twin is, as a data artifact, a composition: an identity, a
specification, one or more models, an estimated state, and links to
measurement data. Today every platform encapsulates that composition
privately. battwin defines it openly, as a small immutable JSON document —
the twin envelope — that references existing open standards instead of
reinventing them:
BattINFO records ─────┐ (identity & specification, by IRI)
BPX / BattMo params ──┼──▶ Battery Twin Envelope (.twin.json) ──▶ registries,
BDF datasets & feeds ─┘ (models & data, by reference) platforms,
archives
Envelopes are documents, not engines: how a twin is hosted, simulated, or synchronized is an implementation concern; how it is expressed is a community concern. The full format is defined in SPEC.md.
Installation
pip install battwin
Dependencies: pydantic and jsonschema — nothing else. The optional
battwin[shacl] extra (pyshacl) adds a third, SHACL-based validation layer
over the JSON-LD rendering.
Quickstart
from battwin import new_envelope, save, validate_file
twin = new_envelope(label="Bench cell 001", chemistry="LFP")
save(twin, "bench-cell-001.twin.json")
assert validate_file("bench-cell-001.twin.json") == []
Updating a twin creates a new, hash-chained version — envelopes are immutable:
from datetime import datetime, timezone
from battwin import StateSnapshot, load, save
v1 = load("bench-cell-001.twin.json")
v2 = v1.next_version(
state=StateSnapshot(
as_of=datetime.now(timezone.utc),
state_of_charge=0.8,
method="coulomb_counting",
source_data="data/SINTEF__001__20260707_001.bdf.csv",
)
)
assert v2.version.previous == v1.content_hash() # verifiable lineage
save(v2, "bench-cell-001.v2.twin.json")
And from the command line:
battwin init --label "Bench cell 001" --chemistry LFP -o cell.twin.json
battwin validate cell.twin.json
battwin validate --shacl cell.twin.json # + SHACL shapes layer (battwin[shacl])
battwin show cell.twin.json
battwin diff cell.twin.json cell.v2.twin.json # checks the version chain
battwin schema # print the packaged JSON Schema
battwin context # print the packaged JSON-LD context
battwin schema and battwin context print the language-neutral contracts to
stdout, so non-Python consumers can pull them without touching the SDK.
What's in an envelope
{
"bte_version": "0.1.1",
"id": "urn:bte:energizer-cr2032:demo-001",
"identity": { "label": "...", "serial_number": "...", "battinfo_iri": "...", "passport_id": "..." },
"specification": { "battinfo_record": "https://w3id.org/battinfo/cell-spec/...", "chemistry": "Li/MnO2" },
"models": [ { "kind": "bpx", "name": "...", "source": "params.bpx.json", "validity": { "...": "..." } } ],
"state": { "as_of": "2026-07-07T12:00:00Z", "state_of_charge": 0.82, "energy_throughput_kwh": 0.00013, "equivalent_full_cycles": 0.0006, "method": "coulomb_counting" },
"data": [ { "kind": "bdf", "uri": "data/SINTEF__DEMO-001__20260707_001.bdf.csv", "role": "cycling" } ],
"provenance": { "created": "...", "created_by": "...", "tool": "battwin/0.4.0" },
"extensions": { "lab:fixture_id": "bench-07" },
"version": { "number": 2, "previous": "sha256:...", "changed": ["state"], "timestamp": "..." }
}
Vendor- or tool-specific facts that aren't (yet) canonical go in extensions
under namespaced keys — see SPEC.md §3.8.
A complete example lives at examples/cr2032.twin.json.
Envelopes also render as JSON-LD (save(..., jsonld=True)) using the packaged
context, so they slot into linked-data pipelines alongside BattINFO — and with
the battwin[shacl] extra installed, battwin validate --shacl checks that
rendering against the packaged SHACL shapes as a third validation layer.
Non-goals
battwin deliberately does not:
- run simulations (that's PyBaMM, BattMo, and the platforms built on them);
- host twins or define sync/REST protocols;
- manage fleets or tenants;
- acquire measurement data (see battfeed for source→BDF collection, and the BDF toolchain for files at rest);
- replace BattINFO, BPX, or BDF — it composes them by reference.
Related projects
| Project | Role relative to battwin |
|---|---|
| BattINFO | semantic records the envelope references for identity/spec |
| BDF / batterydf | time-series datasets the envelope links in data[] |
| BPX | parameter sets bound in models[] |
| battfeed | collects live source data into the BDF files a twin links |
Python support
Python 3.10 – 3.12.
Acknowledgements
This project has received support from European Union research and innovation programs under grant agreement 101103997 – DigiBatt.
License
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file battwin-0.4.0.tar.gz.
File metadata
- Download URL: battwin-0.4.0.tar.gz
- Upload date:
- Size: 36.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
77ed37387d65b27b80c632cb3669b2da30247e93aea322f46da232a51e0f7e81
|
|
| MD5 |
ec57d8028da127dbfc7758ce0a9a9d34
|
|
| BLAKE2b-256 |
71577d5801347fed3a8b99af4318e88f731d867ecd09acacaf248704f2d61623
|
Provenance
The following attestation bundles were made for battwin-0.4.0.tar.gz:
Publisher:
publish.yml on DigiBatt/battwin
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
battwin-0.4.0.tar.gz -
Subject digest:
77ed37387d65b27b80c632cb3669b2da30247e93aea322f46da232a51e0f7e81 - Sigstore transparency entry: 2211609478
- Sigstore integration time:
-
Permalink:
DigiBatt/battwin@4cb31c88f0f344f8f19a5d5014172356e46232cd -
Branch / Tag:
refs/tags/v0.4.0 - Owner: https://github.com/DigiBatt
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@4cb31c88f0f344f8f19a5d5014172356e46232cd -
Trigger Event:
push
-
Statement type:
File details
Details for the file battwin-0.4.0-py3-none-any.whl.
File metadata
- Download URL: battwin-0.4.0-py3-none-any.whl
- Upload date:
- Size: 30.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cb9ea7a88111d6c07f5ba8bc29ef951e9b5b7c0288c608cb5dfc3564d355229e
|
|
| MD5 |
0d268015efd995357c794046e20c5339
|
|
| BLAKE2b-256 |
28b01470f49ad17e1c09be9c4663c319f877f4ed973c8fba8b10e733b4cffe7b
|
Provenance
The following attestation bundles were made for battwin-0.4.0-py3-none-any.whl:
Publisher:
publish.yml on DigiBatt/battwin
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
battwin-0.4.0-py3-none-any.whl -
Subject digest:
cb9ea7a88111d6c07f5ba8bc29ef951e9b5b7c0288c608cb5dfc3564d355229e - Sigstore transparency entry: 2211609514
- Sigstore integration time:
-
Permalink:
DigiBatt/battwin@4cb31c88f0f344f8f19a5d5014172356e46232cd -
Branch / Tag:
refs/tags/v0.4.0 - Owner: https://github.com/DigiBatt
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@4cb31c88f0f344f8f19a5d5014172356e46232cd -
Trigger Event:
push
-
Statement type: