battery-passport-kit: checking EU battery passport data

A command-line tool that turns CSV rows into EU battery passport records, validates them against the BatteryPass-Ready schemas and reports missing required elements per data element group.

The problem

From 18 February 2027 the EU Battery Regulation (EU) 2023/1542 requires a digital battery passport for EV batteries, LMT batteries (e-bikes, scooters) and industrial batteries above 2 kWh. Each passport is a structured record of 85 to 120 mandatory data elements, depending on category and stage.

The BatteryPass-Ready consortium publishes JSON schemas for these records. A company that has to produce passports usually holds the data in spreadsheets or in exports from ERP or PLM systems. It has to bring that data into the schema format, find the required elements that are still missing, and decide which parts each role may read.

How it works

battery-passport-kit bundles the BatteryPass-Ready data model 2.0.1 and provides a command bpkit with these subcommands:

  • template writes a CSV template with one column per data element.
  • from-csv creates one passport JSON per row, fills in units and other fixed values, and validates each passport.
  • validate checks passports against the schema, including dates, URIs, ISO 8601 durations and code lists.
  • report lists missing required elements per data element group and flags empty elements that the regulation makes mandatory only for some batteries.
  • view prints the part of a passport that a role (public, authorities, repairer, ...) may read, based on the access annotations in the schema.
  • qr creates the QR code that links the physical battery to its passport.

It covers all five battery categories, each in two stages: feb27 for the requirements from 18 February 2027 and full for all requirements, including carbon footprint and supply chain due diligence, which apply later.

The repository contains a CSV file with two fictional EV batteries. In the second row the battery mass and the cycle life test standard are left empty on purpose. Run locally, the import and the report give this output:

$ bpkit from-csv examples/ev-feb27.csv --category ev -o passports
passports/EXC77-000001.json: valid
passports/EXC77-000002.json: 2 problem(s), see `bpkit report passports/EXC77-000002.json`

$ bpkit report passports/EXC77-000002.json
passports/EXC77-000002.json  category ev, stage feb27, data model 2.0.1
Required elements: 100/102 filled, schema problems: 2

group                                          required   optional
dppHeader                                           7/7        0/2
batteryMaterialsAndComposition                      9/9        2/3
circularityAndResourceEfficiency                  16/16       7/14
identifiersAndProductData                         15/16        1/6
performanceAndDurability                          45/46      11/38
symbolsLabelsAndDocumentationOfConformity           8/8       5/12

Missing required elements:
  batteryPassportData.identifiersAndProductData.batteryMass.gramKilogramValue
  batteryPassportData.performanceAndDurability.cycleLifeReferenceTest

Empty elements that are mandatory for some batteries (check whether they apply):
  batteryPassportData.identifiersAndProductData.warrantyPeriod
  batteryPassportData.symbolsLabelsAndDocumentationOfConformity.symbolsForCadmiumAndLead

Schema problems:
  batteryPassportData.identifiersAndProductData.batteryMass: 'gramKilogramValue' is a required property
  batteryPassportData.performanceAndDurability: 'cycleLifeReferenceTest' is a required property

Testing

For every category and both stages, a test checks that the complete placeholder passport validates, has no missing required elements and is detected as the right category. Other tests check that the feb27 elements are a subset of the full elements, and that a removed required element, an empty object that needs at least one field and invalid values (the date 2027-13-40, a capacity fade of 140 percent, an unknown battery status) are reported.

The role test checks that the public view hides the economic operator ID and that the view for authorities contains it. The CSV tests check list values, hazardous substance entries, filled-in constants and the rejection of unknown columns and non-numeric values. An end-to-end test runs import, validation, report, view and QR code generation through the command line.

There are 23 tests. CI runs them on Python 3.10, 3.11, 3.12 and 3.13, together with ruff check and ruff format --check, and then runs the README example, where the report for the second passport has to fail.

Limitations

  • The schemas are the consortium's proposal and are marked as work in progress. They are not an official EU format, and the delegated and implementing acts are still evolving. Results should be checked against the current Data Attribute Longlist at thebatterypass.eu.
  • JSON schema cannot express which elements are mandatory only under conditions, for example the lead and cadmium symbols. report lists the empty ones as items to check and does not decide.
  • The tool creates and checks passport data. It does not host passports or provide the registry, access control or data carrier that the regulation requires.
  • It is not legal advice.

The bundled schemas are licensed under CC BY 4.0 by the BatteryPass-Ready Consortium. The code and installation instructions are at github.com/Jwrede/battery-passport-kit.