v0.1.1 — real-fixture hardening
v0.1.1 — real-fixture hardening
A hardening release. Every change below was found by running the tool end-to-end against real ETS5/ETS6 project files (the XKNX/xknxproject test fixtures), not the synthetic smoke test — which alone never exercised the real parser or the MCP server path. Five new regression tests now guard these cases, and CI runs them on Python 3.10–3.12.
🩹 Fixed
- Critical —
load_projectrecursed infinitely on every real.knxproj. The MCP tool functionload_projectshadowed the imported project loader of the same name, so it called itself instead of parsing, raisingRecursionErroron any real project. The tool's primary entry point was effectively unusable over MCP. It now delegates toload_project_file. The synthetic smoke test missed this entirely because it calls the parser directly, bypassing the server — exactly why real-file testing mattered.
✨ Added / improved
- ETS Function role pairing — the headline feature — is now actually implemented. command↔status pairs are taken from ETS Function roles (e.g.
SwitchOnOff↔InfoOnOff) via the newpairing.function_status_pairs(), used by bothcheck_missing_statusand the Home Assistant generator. Previously Functions were ignored entirely despite the README claiming they were the primary signal. As a result:- a feedback GA named only "Status" now pairs correctly (no name-token overlap required);
- HA entities get the correct
state_address; - function-paired commands are no longer false-flagged as missing a status.
- No silent drops in HA generation ("no silent caps"). Every group address is now either emitted as an entity or listed in the
reviewoutput, and the YAML header reports how many need manual review. Previously, GAs the generator could not classify simply disappeared. - Smarter shutter classification. German / directional names are recognised (
Behang,Lamelle,auf/ab,Raffstore,Markise, plus Russian equivalents). A shutter-looking command whose DPT lacks a sub-type now gets an actionableshutter_incomplete_dptreview hint (set 1.008 / 1.010 / 5.001 in ETS) instead of vanishing as "unknown". - Venetian slats handled as tilt. A slat GA (Lamelle / slat / ламель / tilt) is attached to its parent blind cover as
move_short_addressinstead of becoming a standalone cover; an unmatched slat is flaggedshutter_slat_unattachedfor manual attachment. - Diagnostics alarms are inputs. A 1-bit diagnostics GA (wind / frost / rain / smoke / leak alarm, fault) is now a read-only
binary_sensorinstead of a phantom command switch.
🧪 Still a beta — testers welcome
The validation above used third-party test fixtures. Real ETS projects are wonderfully diverse, so please try it on your own .knxproj (it's read-only and never touches a bus) and file a Real-project test report. See CONTRIBUTING.md.
Full changelog: v0.1.0...v0.1.1