Victron VEConfigure .rvms and .rvsc configuration files without VEConfigure: format, checksum, settings table, editor.
Trust in a tool that writes configuration to a battery inverter has to be earned by evidence you can re-run yourself. This page lists what we test, what the evidence does and does not cover, and a recipe for verifying the toolkit on your own system before you let it write anything.
Everything runs against the real device files in fixtures/ (see docs/FIXTURES.md). There are no
synthetic fixtures for the format itself.
| file | what it proves |
|---|---|
tests/test_sections.py |
Every good fixture parses, every section checksum validates, the pointer chain is contiguous and ends at EOF, parse then serialize is byte-exact, rebuilding pointers and checksums from payloads reproduces the input byte-for-byte, the historical formula (sum32(block[2:]) + 0x6142000F) equals the plain word sum, the header sections are identical across the corpus, and the three deliberately broken files are detected. |
tests/test_claims.py |
Every checkable claim in docs/FIELDS.md and mk2vsc/units.py, checked on all 178 inverter blocks of the 89 well-formed fixtures: serial position, firmware word, slot bytes, assistant-flag encoding, the +10 upload-form shift (setting 5 reads 120 V on every block under the offset model), timestamps are plausible unix times, CONFIRMED/HIGH fields decode to physically sensible values, grid-code flag tracks GUI-authored installs, the retracted SOC field is the high byte of setting 88, region 128 to 189 is unprogrammed on bare blocks, and the field table itself is internally consistent (every CONFIRMED/HIGH entry states evidence). |
tests/test_writer.py |
Edit then revert reproduces the original file byte-for-byte; an edit to all inverters changes only the intended bytes plus checksums; edits on ESS blocks leave the assistant area untouched; unverified fields, flag registers, unknown serials, out-of-range values, upload-form input and corrupt input are refused; the archived prepared files from the 2026-07-20 charge-profile corrections are reproduced exactly from their baselines. |
tests/test_diff.py |
Two real consecutive downloads differ only in bookkeeping; the pair whose blocks swapped file position is invisible when compared by serial while a positional diff shows dozens of differences; a stub download is reported as a content change; a GUI export and the device’s re-download of it agree on every setting. |
tests/test_qualify.py |
Inverter disagreement fails; intended values pass on the corrected file and fail on the mismatched one; wrong-system serials fail; the stub fails; the rollback file that caused the month-long regression is caught. |
tests/test_assistants.py |
Bare blocks have the empty header and the free-space counter relation holds; GUI-installed ESS has exactly one 704 and one 1152 byte record per system; the 1152 byte body is identical across systems; the stub is detected on all six stub blocks. |
tests/test_manifest.py |
Every fixture is in the manifest with a matching sha256 and size, and no two fixtures have the same content. |
tests/test_cli.py |
Exit codes and output of every subcommand. |
Run it:
python -m venv .venv
.venv/bin/pip install -e '.[test]'
.venv/bin/pytest
528 tests, under two seconds.
92 unique files (89 well-formed, 178 inverter blocks, plus 3 negative controls), 8 inverters in 4 two-inverter split-phase systems, one
firmware version (2729560), one format version (1.33), downloads spanning June to September 2026.
Three files are deliberately broken and listed in tests/conftest.py KNOWN_BAD with the reason:
a file with deliberately stale checksums (a negative control for the validator).
What the corpus does not cover, and therefore what the tests cannot promise:
.rvsc files. We have none.A claim test failing on a file from outside this envelope is the expected way to learn something.
The short form is one command: mk2vsc census <download> prints structure, checksum status, whether the
device schema parsed, whether every setting lies inside the schema’s range, and the key values per
inverter. Compare the key values with VEConfigure or VRM. If everything agrees, the model holds on your
hardware; if not, you have a finding worth an issue. The longer form:
mk2vsc diff a.rvms b.rvms should say
ONLY BOOKKEEPING and exit 0. This checks that the parser, the by-serial comparison, and the
bookkeeping model (pointer, save timestamp, checksum) hold on your firmware.mk2vsc validate a.rvms. All checksums OK means the checksum model is exactly what your device
and your VEConfigure version compute. If any section reads BAD on a genuine download, stop: the
integrity model does not hold for your files, and nothing else here should be trusted until it
is understood.mk2vsc show a.rvms. Compare absorption, float, charge current and the AC input current limit
with VEConfigure’s Charger and General tabs or the VRM device page. If they match, the
settings-array mapping holds for your block layout. The line under each inverter is the same
self-check census runs: alignment OK (+0x059, 138/138 in range) means every scorable setting
lies inside the range the file’s own schema declares for it; ALIGNMENT SUSPECT means the
numbers on that block are not to be trusted. A row marked at minimum of allowed range or
at maximum of allowed range is a physical setting (V, A, Ah, Hz) typed as the extreme value
VEConfigure accepts, where that extreme is not the default; on our corpus that marks exactly the
inverters commissioned with absorption = float = 48.00 V.fixtures/ (and to the manifest, see
docs/FIXTURES.md). Claim tests that fail are findings, not bugs in your file.When a claim test fails on your file, open an issue with the file (device downloads contain
inverter serials and nothing else identifying) and the output of mk2vsc census and
mk2vsc show --all --json.
For each of the four live uploads that established the writer:
diff against the prepared file reports only the save timestamp, pointers and
checksums; every setting verbatim.The first was float 54.0 to 54.1 V on both inverters of one system (2026-07-20), chosen because a 0.1 V change cannot hurt anything and is unambiguous to read back. The same day the charge profiles of four systems were corrected the same way.
Code changes to the parser, writer or field table are reviewed independently before merge, with the test suite green and, for anything touching the writer, an edit-and-revert byte-identity check on every fixture. We treat a new field-table entry at CONFIRMED as requiring a live read-back, and at HIGH as requiring a corpus-wide consistency check plus a public reference or a matching GUI screenshot.
| area | status | evidence |
|---|---|---|
| Section grammar and checksum | proven | every section of all 92 unique files (115 counting archive duplicates); four live uploads accepted; byte-exact round trip on every fixture |
| Settings array as VE.Bus setting IDs 0 to 191 | strong | absorption/float anchor IDs 2/3; IDs 5, 6, 65, 73, 81, 88 corroborate on every block; one firmware only |
| Individual fields | mixed | all 192 IDs carry VEConfigure’s identifier; decode confidence 4 CONFIRMED (written and read back live), 68 HIGH, 9 MEDIUM, 12 LOW, 99 UNKNOWN (reserved and grid-code slots, mostly 0 or 0xffff); docs/FIELDS.md lists each with its evidence |
| Guarded writer | proven for its surface | edit-and-revert byte identity on every fixture; reproduces the archived prepared files; 4 live uploads |
| By-serial diff and bookkeeping model | proven | real consecutive downloads, including the swapped-order pair |
| Qualifier | proven against its motivating incident | catches the 2026-08-14 rollback file (fixture); the 2026-08-21 one-inverter GUI write is the case the agreement check was written for, but we hold no fixture from that day |
| Assistant records | read; remove and reinstall | record framing, sizes and the stub signature; mk2vsc assistant removed and reinstalled ESS on one live system (2026-09-04) with re-downloads verified; the record body and the 72-byte ESS tail are not understood |
| First-time assistant install (graft) | experimental, gated | mk2vsc.experimental behind --i-accept-the-risk; reproduces every August 2026 attempt file byte-for-byte; the device stored them and no system started (docs/ESS_INJECTION.md) |
| Grid code | not touched | flag read only; the dealer password is out of scope by policy |