Releases: NickoScope/nickol-knx-mcp
Release list
v0.8.0 — lessons from a second naming school
Field-validated against a real 859-GA as-built project (anonymised).
Added
- Positional command/status pairing (#4): parallel status middles with 1:1 duplicated names + self-reporting commands (actuator R+T object on the command GA). Missing-status warnings on the field project: 339 → 89 (the real ones).
- App-program parser v2 (#6): merges
<ComObjectRef>-level names/DPTs/flags over stub base objects (conservative, disagreements →dpt_variants, never guessed); picks the newest ApplicationVersion instead of list position. Unverified DPTs on 15 field device models: 4341 → 1167 (−73%).
Fixed
main_group_unnamednow reads authoritative GroupRange names (#3).- Completeness grader counts pattern-named ranges (a middle called «Сцены») and Russian plural forms (#5).
- Dependency pin
mcp>=1.10,<2(SDK v2 renames FastMCP → MCPServer).
Full changelog: https://github.com/NickoScope/nickol-knx-mcp/blob/main/CHANGELOG.md
v0.7.0 — exact device models: local catalog + app-program parser (25 tools)
What's new
Exact device decomposition from a local catalog
decompose_device can now return the exact vendor object model instead of a generic recipe. Point the NICKOL_KNX_CATALOG env var at a device-library YAML file or directory and matching devices come back as source: catalog-exact — real per-channel blocks, object counts, app-program version, and first-instance objects with their true DPTs. Anything not in the catalog falls back to the built-in recipes (source: recipe-approximate); with the env unset, behaviour is unchanged. Objects the vendor app-program leaves without a DatapointType stay dpt: null — never guessed. The catalog itself is vendor data kept local, not shipped.
New tool: parse_devices_from_project (now 25 MCP tools)
A deterministic parser (appprog_parser.py) that extracts exact device comm-object models from the M-* application programs inside a .knxproj / .knxprod: order number (via the nested <Product>), app-program version, DPST-x-y → x.00y, per-channel block/stride detection, and a coverage manifest. Read-only and PII-safe — it never reads the client project (P-*/0.xml). With output_path it writes device-library YAML into the workspace, closing the loop: parse → catalog → decompose_device (catalog-exact).
Full changelog: v0.6.0...v0.7.0
v0.6.0 — roadmap complete
Completes the roadmap — the tool now validates, repairs, generates (HA / ETS / handover / IoT), diffs, grades and drafts acceptance protocols, all design-time & read-only.
B-tier
- B2 — climate-correctness review (
generate_ha.py): controller/operation modes made explicit, setpoint-shift command and state paired, and a flag for any mode object lacking a state address. - B3 — semantic project diff (
diffproj.py;diff_projects/diff_loaded): added / removed / DPT-changed / renamed / security-changed group addresses between two.knxprojversions. - B4 — acceptance test protocol (
advanced.py;generate_test_protocol): per-function commissioning checklist in Markdown. - B5 — Matter readiness (
advanced.py;check_matter): which functions round-trip cleanly to a Matter cluster. - B6 — energy scaffold (
advanced.py;check_energy): metering/energy DPT coverage + PV/battery/EVSE scaffold.
C-tier
- C1 — KNX IoT semantic export (
iot.py;generate_knx_iot): KNX IoT Turtle/RDF skeleton. - C2 — naming suggestions (
advanced.py;suggest_names): naming-hygiene proposals. - C3 — as-built completeness grader (
advanced.py;grade_completeness): bare skeleton vs as-built, by professional-pattern presence.
A-tier quick wins
- A5 — HA Areas/voice documented as UI-only concerns.
- A6 — time/date
exposeblock for DPT-19.001 clock broadcast.
All changes are design-time and read-only; the server never touches the KNX bus. Full notes in CHANGELOG.md.
v0.5.0 — repair-suggestion engine
From validator to repairer. Previous releases flagged problems in a .knxproj; this one starts proposing the fix. The headline is a repair-suggestion engine that turns each finding into a concrete, reviewable change, alongside two new detectors for gaps that silently break the Home Assistant layer.
Added
- B1 — repair-suggestion engine (
repair.py, new module; new MCP toolsuggest_repairs). For each finding it proposes a concrete fix rather than only naming the problem: infer a DPT for a group address that has none, correct a suspect sub-DPT, synthesise a status/feedback GA in a free address slot, or add an absolute-brightness GA for a relative-only dimmer. Suggestions only — a human reviews them, and accepted new GAs feedgenerate_ets_group_addresses; the server never writes to ETS or the bus. On a real 3646-GA project it produced 145 proposals: 32 set-DPT, 1 change-DPT, and 112 synthesised status GAs. - A2 — relative-only-dimming detector (
analyze.py,relative_only_dimmingfinding). A3.007relative dimmer with no5.001absolute-brightness GA in its zone is flagged, because Home Assistant cannot set a brightness level from relative dimming alone. - A3 — cover invert / travel-time surfacing (
generate_ha.py). The cover review reason is nowverify_cover_invertand carries a note listing the actuator-dependent flags that are not in the.knxproj(invert_position/invert_updown/invert_angle,travelling_time_up/travelling_time_down), plus a warning when a cover's position lacks a state address.
Full changelog: https://github.com/NickoScope/nickol-knx-mcp/blob/main/CHANGELOG.md
v0.4.0 — sub-DPT linter + KNX Secure posture
Two new lint dimensions: does the DPT sub-type match what the name promises, and is the project's KNX Secure posture consistent. This release adds a conservative sub-DPT sanity linter and a report-only KNX Data Secure posture summary (no key material ever touched), plus itemised QA findings in the handover pack.
Added
- A1 — sub-DPT sanity linter (surfaced by
check_dpt/analyze_allas thesubdpt_suspectfinding). When a GA name implies a specific DPT sub-type (temperature →9.001, power →14.056, brightness/position →5.001), the linter flags a wrong sub-type or a wrong main type. Multilingual, deliberately conservative — it only fires on unambiguous names. - A4 — KNX Data Secure posture (
secure_posture(), new MCP toolcheck_secure). Report-only summary: secured vs plaintext GA counts, middle groups mixing secure + plaintext objects, and a keyring (.knxkeys) handover checklist. Reads only the per-GASecurityflag — no key material is read, derived, or emitted. - KNX Secure posture section in the handover pack — section 5 of
handover.mdrewritten from a flat count into the full posture section (counts, mixed-group flag, keyring checklist). - Itemised QA findings in the handover pack — section 6 lists the actual 🔴 errors and 🟡 warnings (address + name, grouped by check), not just totals.
v0.3.0 — device library + spec→structure
Spec→structure: a device library and a design methodology, plus the as-built handover pack.
This release turns the tool from a .knxproj validator into a design aid: from a project spec you can now expand each device into its group-address recipe and reason about the whole structure. Shipped alongside the Track B project handover pack and a set of noise-reduction refinements, the latter two driven by a second real signed Zennio project (a 3646-GA multi-vendor villa, 5× larger, no ETS Functions).
Added
- Device library +
decompose_device— one device is not one GA (new MCP toolsdecompose_device+list_device_recipes). Each actuator channel expands into command / status / dimming (3.007) / absolute value / position (5.001) / HVAC mode (20.102/20.105) / colour (232.600/251.600) objects, each with its DPT. Given a manufacturer order number, device type or alias (e.g.ZDIDBDX4,dimmer,JRA/S,presence detector) and a channel count, it returns the objects a professional wires per channel and the total GA count — so a spec/ТЗ device list becomes a group-address structure. Recipes span switch, dimmer, RGBW LED, shutter/blind, floor-heating, AC gateway, DALI, presence, metering, leak and touch-panel families across Zennio + ABB. Generic vendor facts compiled from KNX manufacturer ETS databases and public docs (typical-wired subset, not the full master menu). docs/spec-to-structure.md— the spec→structure methodology. The reverse of validation (design a structure from a spec), thedecompose_devicepipeline, and an honest measured account: ~90 % is reproducible (taxonomy, domains, logic structure, command/status pairing, DPT discipline); the exact per-device object count is not — it varies 2–9× between projects, so predict a range, never a false-precise number.generate_handover_pack— the as-built commissioning deliverable (Track B). From a read-only.knxproj:handover.md(equipment inventory, GA-domain map, command/status coverage %, KNX Secure scope, QA state), a standalonetopology.svg, the fullgroup-addresses.csvandha-package.yaml.- De-noise refinements: divider/separator scratch detection,
[LF]logic-object DPT awareness (INFO not warning), and central-macro status tolerance (fan-out broadcasts surface as INFO).
Fixed
- Handover domain names now read main/middle range names from the project's
GroupRangesinstead of a mislabelableGARecord.main_name.
Full changelog: https://github.com/NickoScope/nickol-knx-mcp/blob/main/CHANGELOG.md
v0.2.0 — colour/climate assembly + GA-intent noise reduction
Colour/climate entity assembly and GA-intent noise reduction — two feature tracks driven by real ETS projects.
Highlights
- Colour & climate entity assembly (Track A). Colour control is now folded into the HA
lightentity — RGB (DPT 232.600), RGBW (251.600), xyY (242.600) and absolute colour-temperature (7.600), each with its status, matched to the zone's light by identity. KNXclimateentities are generated, anchored on an HVAC mode (20.102/20.105) and emitted only when the HA-required minimum is present (otherwise routed to review, so an invalid entity is never written). New DPTs: 232.600 / 251.600 / 242.600 / 7.600 / 20.105 / 1.100. - B1 status-pairing fix. A command now only takes a status whose identity nests with its own (a shared zone token is not enough), and a status maps to exactly one entity — stopping cross-borrowed brightness state on real files.
- GA-intent noise reduction (Track D). Every group address is classified
functional/reserve/logic/scratch. Intentional non-functional GAs no longer "cry wolf". Validated on a real 685-GA Zennio project: false errors cut 29 → 6 and missing-status noise 79 → 45, while preserving all 12 genuinedpt_mismatch_cocatches.
New regression tests cover colour assembly, the B1 borrow guard, climate generation and the GA-intent patterns.
See the CHANGELOG for full detail.
v0.1.2 — Home Assistant mapping quality
v0.1.2 — Home Assistant mapping quality
A second hardening pass, driven by running the tool against more real public ETS projects spanning ETS 4.2 / 5.0 / 5.5 / 6 — yene/knxproj (DemoCase, 94 GAs), tuxedo0801/KnxProjParser, dataheld/knxray, and whaeuser/open-knxviewer. Zero crashes across the whole corpus; three new regression tests (six total).
These are quality fixes to the generated Home Assistant config — the tool now produces materially more complete and correct entities on messy, real-world .knxproj files.
✨ Improved
- Dimmable lights are assembled completely. A light now collects both its on/off status (1.x) and brightness status (5.x) through identity-based pairing, folds the on/off command into the same
lightentity (no more duplicateswitch), and pairs correctly even when the device identity is a single name token — e.g.HaloSpotLeft.A.VALUE↔HaloSpotLeft.A.STATE%. Switches gained the same identity-based status pairing, so far more entities now report real state. - Wider, safer shutter detection. A cover's up/down is recognised on canonical DPT 1.008 or any 1.x command named up/down (
UP/DOWN,auf/ab); stop is recognised on DPT 1.007 / 1.010 / 1.017 or a "stop / stopp / стоп" name. Position and stop siblings attach only to the same shutter (zone-identity guard), so multiple blinds in one main group no longer cross-wire. Real ETS4/5 projects that use1.001+1.017now map to full covers with position + state. - Date / time / text DPTs recognised (10.001 time, 11.001 date, 19.001 date-and-time, 16.000/16.001 character string): routed to
reviewasmanual_datetime/manual_text— pointing you at HA KNX's dedicated date/time/text platforms — instead of an opaqueunmapped_dpt.
🧪 Still a beta — testers welcome
Validation so far uses third-party fixtures. Real ETS projects vary enormously, so please try it on your own .knxproj (read-only, never touches a bus) and file a Real-project test report. See CONTRIBUTING.md.
Full changelog: v0.1.1...v0.1.2
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
v0.1.0 — public beta
First public beta of nickol-knx-mcp — a design-time KNX/ETS6 assistant as an MCP server.
Reads .knxproj (read-only), validates naming/DPT/status, and generates Home Assistant KNX YAML + ETS-importable group addresses (XML/CSV). No live bus access — confined-workspace writes only.
🧪 We need testers
The pipeline passes an end-to-end smoke test on a synthetic 16-GA project, but real-world .knxproj testing is just starting. If you have an ETS5/ETS6 project, please try it (it's read-only and safe) and file a Real-project test report issue. See CONTRIBUTING.md.
Highlights
- 12 MCP tools (load/analyze/report + HA & ETS generators)
- Safety-by-design: no networking/bus dependency at all
- MIT licensed, CI on Python 3.10–3.12
- English + Russian docs
Full notes: CHANGELOG.md