knx-prod
Cross-platform .knxprod generator for KNX ETS product databases — no Windows, no ETS, no .NET required.
Part of the knx-rs repository.
What it does
Takes a monolithic KNX product XML and generates a signed .knxprod ZIP archive importable by ETS. The XML can come from OpenKNXproducer or be generated from Rust code via an xtask (see knx-rs README).
The pipeline:
- Parse — extract metadata (namespace, manufacturer ID, application ID)
- Split — split monolithic XML into Catalog.xml, Hardware.xml, Application.xml
- Sign — compute registration-relevant MD5 hash, patch fingerprint into IDs
- Package — ZIP into
.knxprod
The hard part: hashing
The Hash attribute on <ApplicationProgram> is computed by the closed-source Knx.Ets.XmlSigning.dll. This crate contains a clean-room Rust reimplementation, verified byte-exact against the original C# DLL across 28 test files from 5 manufacturers:
| Source | Files | Status |
|---|---|---|
| MDT (Leakage, AKK, BE, JAL) | 4 | ✅ |
| Gira (Tastsensor, Busankoppler, Dimmaktor) | 3 | ✅ |
| ABB (SBRU, SBCU, SBSU) | 5 | ✅ |
| Siemens (LK, UP204, RDG, QAA, QFA, QPA, OCT) | 9 | ✅ |
| OpenKNX (SmartHomeBridge, LogicModule) | 2 | ✅ |
| Minimal synthetic | 1 | ✅ |
| + 4 additional prebytes-verified | 4 | ✅ |
All 89 registration-relevant element types from the ETS registry are implemented. See HASHING.md for the full algorithm documentation.
Usage
CLI
As a library
use Path;
use generate_knxprod;
generate_knxprod.expect;
Hash only
use hash_application_program;
let xml = read_to_string.unwrap;
let result = hash_application_program.unwrap;
println!;
println!;
Testing
# Unit tests (fast, all fixtures included)
# OpenKNX integration tests (requires download, ~8s)
How the hash works
The algorithm was reconstructed through analysis of the ETS signing process. Key aspects:
- Forward-only XML reader with recursively sorted children at each level
.NET InvariantCulturestring comparison for sort order (not ASCII)- All 89 registration-relevant element types with typed attribute serialization
- Empty
<Script />elements trigger an overshoot scan across element boundaries TypeFloatattributes serialized as IEEE 754 doubles- Parent-conditional ordering for
ParameterRefRefelements - CDATA sections, XML entity decoding,
\r\nnormalization
Full details in HASHING.md.
License
GPL-3.0-only