mirror of
https://github.com/NickoScope/nickol-knx-mcp.git
synced 2026-10-21 03:07:06 +02:00
Found on a real 1312-GA house: a room with floor heating, a convector and an AC unit became
ONE climate (convector setpoint, AC controller mode, AC fan speed as the valve). Room 1.09
matched 2.09 and a central "09." GA, "Kids room 1" took "Kids room 2 temperature", and valves
came from light brightness and blind position statuses. The zone was the room alone: device
words were stripped as qualifiers, "А/С" vanishes in the tokenizer, the floor digit of "1.09"
is dropped.
Now a climate is assembled per room AND device type (floor, wall, radiator/convector, fan
coil, AC; RU/EN/DE words, removed from the zone as whole words):
- room code "N.NN" only at the start of a name, and it must match on both sides;
- standalone numbers of the anchor must be in a device member; a shared room sensor's
numbers must be among the anchor's; digits in dotted codes and values do not count;
- an untyped GA is shared room data: any role if the room has one device, otherwise only
the current temperature, which several devices may reuse; with a room code the room's
untyped sensor qualifies even without the device's extra words;
- a word that sets another device of the room apart keeps its GAs away;
- control roles must be unambiguous: more than one candidate -> review climate_ambiguous;
- two mode GAs that cannot be told apart -> review climate_duplicate_anchor, not dropped;
- only 20.102 / 20.105 anchor; valve needs a valve word; AC never gets a valve;
- stable address order, so results never depend on parse order.
Two gates. Own audit on seven real projects, every changed entity inspected: no control GA
used by two climates, no address lost; house 16 -> 33 climates (one per device), manual
review 33 -> 12; flat 7 -> 9; HDL 3 -> 5; demo 6 -> 13; villa 23 -> 21 with the 3 it cannot
disambiguate sent to review instead of guessed. LLM council (three models + devil's
advocate, sanitised packet): accept with hardening; its P0s (same-type devices, silent
first pick) and P1s (mid-name codes, dotted digits, non-102/105 anchors, generic valve
words) are all in this commit, with tests E and F covering its failure catalogue.
Out of scope, recorded: identically named rooms of different flats without room codes, and
lexical identity in general -> device-channel identity ("lever 0").
Also works around a mypy 2.3.1 parse error on a comment right after a compound if.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
422 lines
10 KiB
JSON
422 lines
10 KiB
JSON
{
|
|
"projects": {
|
|
"demo": {
|
|
"categories": {
|
|
"diagnostics": 5,
|
|
"energy": 4,
|
|
"hvac": 78,
|
|
"lighting": 91,
|
|
"scene": 4,
|
|
"sensor": 30,
|
|
"shutter": 24,
|
|
"unknown": 2
|
|
},
|
|
"devices": 0,
|
|
"file_digest": "77273cacf3f9",
|
|
"findings_by_code": {
|
|
"central_macro_no_status": 2,
|
|
"duplicate_name": 1,
|
|
"inconsistent_dpt": 1,
|
|
"missing_dpt": 1,
|
|
"missing_status_address": 2,
|
|
"missing_value_status": 1,
|
|
"scene_no_status": 4,
|
|
"subdpt_suspect": 1
|
|
},
|
|
"findings_by_severity": {
|
|
"error": 1,
|
|
"info": 6,
|
|
"warning": 6
|
|
},
|
|
"group_addresses": 238,
|
|
"ha_entities": {
|
|
"binary_sensor": 13,
|
|
"climate": 13,
|
|
"cover": 6,
|
|
"light": 25,
|
|
"sensor": 25,
|
|
"switch": 6
|
|
},
|
|
"ha_review_items": 55,
|
|
"suggestion_hints": {
|
|
"channels": 0,
|
|
"diagnostics_skipped": 0,
|
|
"duplicates_skipped": 0,
|
|
"fallback": 0,
|
|
"pseudo_channels": 0,
|
|
"review": 0,
|
|
"sensors": 0,
|
|
"skipped_fb_covered": 0,
|
|
"structural": 0,
|
|
"subunits": 0,
|
|
"unwired_flagged": 0
|
|
},
|
|
"suggestions_by_platform": {}
|
|
},
|
|
"hdl-ets6": {
|
|
"categories": {
|
|
"diagnostics": 5,
|
|
"hvac": 206,
|
|
"lighting": 425,
|
|
"sensor": 34,
|
|
"shutter": 135,
|
|
"unknown": 54
|
|
},
|
|
"devices": 53,
|
|
"file_digest": "a360d74c65ef",
|
|
"findings_by_code": {
|
|
"duplicate_name": 156,
|
|
"inconsistent_dpt": 15,
|
|
"line_without_coupler": 1,
|
|
"missing_dpt": 107,
|
|
"missing_status_address": 92,
|
|
"missing_value_status": 132,
|
|
"name_too_short": 1,
|
|
"relative_only_dimming": 20,
|
|
"reserve_without_dpt": 81,
|
|
"status_pairing_summary": 1
|
|
},
|
|
"findings_by_severity": {
|
|
"error": 107,
|
|
"info": 83,
|
|
"warning": 416
|
|
},
|
|
"group_addresses": 859,
|
|
"ha_entities": {
|
|
"binary_sensor": 66,
|
|
"climate": 5,
|
|
"cover": 1,
|
|
"expose": 1,
|
|
"light": 180,
|
|
"sensor": 51,
|
|
"switch": 42
|
|
},
|
|
"ha_review_items": 402,
|
|
"suggestion_hints": {
|
|
"channels": 229,
|
|
"diagnostics_skipped": 2,
|
|
"duplicates_skipped": 4,
|
|
"fallback": 0,
|
|
"pseudo_channels": 151,
|
|
"review": 41,
|
|
"sensors": 37,
|
|
"skipped_fb_covered": 0,
|
|
"structural": 80,
|
|
"subunits": 0,
|
|
"unwired_flagged": 29
|
|
},
|
|
"suggestions_by_platform": {
|
|
"binary_sensor": 14,
|
|
"light": 79,
|
|
"sensor": 23,
|
|
"switch": 1
|
|
}
|
|
},
|
|
"mixed-small": {
|
|
"categories": {
|
|
"hvac": 58,
|
|
"lighting": 95,
|
|
"sensor": 2,
|
|
"unknown": 12
|
|
},
|
|
"devices": 14,
|
|
"file_digest": "bfaf0f366105",
|
|
"findings_by_code": {
|
|
"central_macro_no_status": 5,
|
|
"line_without_coupler": 1,
|
|
"missing_dpt": 21,
|
|
"missing_status_address": 4,
|
|
"missing_value_status": 1,
|
|
"status_pairing_summary": 1
|
|
},
|
|
"findings_by_severity": {
|
|
"error": 21,
|
|
"info": 7,
|
|
"warning": 5
|
|
},
|
|
"group_addresses": 167,
|
|
"ha_entities": {
|
|
"expose": 1,
|
|
"light": 29,
|
|
"sensor": 19,
|
|
"switch": 3
|
|
},
|
|
"ha_review_items": 68,
|
|
"suggestion_hints": {
|
|
"channels": 52,
|
|
"diagnostics_skipped": 0,
|
|
"duplicates_skipped": 0,
|
|
"fallback": 0,
|
|
"pseudo_channels": 23,
|
|
"review": 7,
|
|
"sensors": 23,
|
|
"skipped_fb_covered": 0,
|
|
"structural": 7,
|
|
"subunits": 0,
|
|
"unwired_flagged": 1
|
|
},
|
|
"suggestions_by_platform": {
|
|
"binary_sensor": 8,
|
|
"climate": 6,
|
|
"light": 1,
|
|
"sensor": 15
|
|
}
|
|
},
|
|
"shutters-medium": {
|
|
"categories": {
|
|
"diagnostics": 9,
|
|
"hvac": 162,
|
|
"lighting": 93,
|
|
"sensor": 9,
|
|
"shutter": 36,
|
|
"unknown": 40
|
|
},
|
|
"devices": 34,
|
|
"file_digest": "8ed1f5a53c9c",
|
|
"findings_by_code": {
|
|
"central_macro_no_status": 2,
|
|
"dpt_mismatch_co": 1,
|
|
"duplicate_name": 55,
|
|
"inconsistent_dpt": 2,
|
|
"missing_dpt": 42,
|
|
"missing_status_address": 64,
|
|
"missing_value_status": 1,
|
|
"relative_only_dimming": 4,
|
|
"status_pairing_summary": 1
|
|
},
|
|
"findings_by_severity": {
|
|
"error": 42,
|
|
"info": 3,
|
|
"warning": 127
|
|
},
|
|
"group_addresses": 349,
|
|
"ha_entities": {
|
|
"binary_sensor": 5,
|
|
"cover": 8,
|
|
"expose": 1,
|
|
"light": 10,
|
|
"sensor": 87,
|
|
"switch": 48
|
|
},
|
|
"ha_review_items": 202,
|
|
"suggestion_hints": {
|
|
"channels": 135,
|
|
"diagnostics_skipped": 8,
|
|
"duplicates_skipped": 4,
|
|
"fallback": 0,
|
|
"pseudo_channels": 106,
|
|
"review": 61,
|
|
"sensors": 38,
|
|
"skipped_fb_covered": 0,
|
|
"structural": 65,
|
|
"subunits": 0,
|
|
"unwired_flagged": 2
|
|
},
|
|
"suggestions_by_platform": {
|
|
"binary_sensor": 13,
|
|
"climate": 2,
|
|
"cover": 4,
|
|
"light": 59,
|
|
"sensor": 25
|
|
}
|
|
},
|
|
"zennio-flat": {
|
|
"categories": {
|
|
"diagnostics": 47,
|
|
"energy": 39,
|
|
"hvac": 201,
|
|
"lighting": 179,
|
|
"scene": 4,
|
|
"sensor": 70,
|
|
"shutter": 49,
|
|
"unknown": 96
|
|
},
|
|
"devices": 41,
|
|
"file_digest": "d980991b0f9e",
|
|
"findings_by_code": {
|
|
"central_macro_no_status": 1,
|
|
"dpt_mismatch_co": 11,
|
|
"dpt_on_logic_object": 1,
|
|
"duplicate_name": 6,
|
|
"inconsistent_dpt": 2,
|
|
"line_without_coupler": 1,
|
|
"missing_dpt": 6,
|
|
"missing_status_address": 11,
|
|
"missing_value_status": 8,
|
|
"reserve_without_dpt": 23,
|
|
"safety_input_no_status": 22,
|
|
"status_pairing_summary": 1,
|
|
"subdpt_suspect": 2
|
|
},
|
|
"findings_by_severity": {
|
|
"error": 6,
|
|
"info": 49,
|
|
"warning": 40
|
|
},
|
|
"group_addresses": 685,
|
|
"ha_entities": {
|
|
"binary_sensor": 49,
|
|
"climate": 9,
|
|
"cover": 7,
|
|
"expose": 1,
|
|
"light": 75,
|
|
"sensor": 106,
|
|
"switch": 79
|
|
},
|
|
"ha_review_items": 287,
|
|
"suggestion_hints": {
|
|
"channels": 179,
|
|
"diagnostics_skipped": 21,
|
|
"duplicates_skipped": 4,
|
|
"fallback": 0,
|
|
"pseudo_channels": 6,
|
|
"review": 57,
|
|
"sensors": 70,
|
|
"skipped_fb_covered": 0,
|
|
"structural": 79,
|
|
"subunits": 71,
|
|
"unwired_flagged": 0
|
|
},
|
|
"suggestions_by_platform": {
|
|
"binary_sensor": 35,
|
|
"climate": 13,
|
|
"cover": 4,
|
|
"light": 56,
|
|
"sensor": 35,
|
|
"switch": 6
|
|
}
|
|
},
|
|
"zennio-house-1312": {
|
|
"categories": {
|
|
"diagnostics": 47,
|
|
"energy": 14,
|
|
"hvac": 388,
|
|
"lighting": 509,
|
|
"scene": 1,
|
|
"sensor": 123,
|
|
"shutter": 91,
|
|
"unknown": 139
|
|
},
|
|
"devices": 88,
|
|
"file_digest": "25d93b4dfb30",
|
|
"findings_by_code": {
|
|
"central_macro_no_status": 1,
|
|
"dpt_mismatch_co": 4,
|
|
"duplicate_name": 25,
|
|
"inconsistent_dpt": 3,
|
|
"line_without_coupler": 1,
|
|
"missing_dpt": 9,
|
|
"missing_status_address": 35,
|
|
"missing_value_status": 1,
|
|
"reserve_without_dpt": 25,
|
|
"safety_input_no_status": 32,
|
|
"status_pairing_summary": 1,
|
|
"subdpt_suspect": 2
|
|
},
|
|
"findings_by_severity": {
|
|
"error": 9,
|
|
"info": 60,
|
|
"warning": 70
|
|
},
|
|
"group_addresses": 1312,
|
|
"ha_entities": {
|
|
"binary_sensor": 88,
|
|
"climate": 33,
|
|
"cover": 11,
|
|
"expose": 1,
|
|
"light": 232,
|
|
"sensor": 119,
|
|
"switch": 95
|
|
},
|
|
"ha_review_items": 559,
|
|
"suggestion_hints": {
|
|
"channels": 305,
|
|
"diagnostics_skipped": 40,
|
|
"duplicates_skipped": 15,
|
|
"fallback": 0,
|
|
"pseudo_channels": 3,
|
|
"review": 118,
|
|
"sensors": 102,
|
|
"skipped_fb_covered": 0,
|
|
"structural": 178,
|
|
"subunits": 201,
|
|
"unwired_flagged": 0
|
|
},
|
|
"suggestions_by_platform": {
|
|
"binary_sensor": 82,
|
|
"climate": 35,
|
|
"cover": 9,
|
|
"light": 105,
|
|
"sensor": 20,
|
|
"switch": 29
|
|
}
|
|
},
|
|
"zennio-large": {
|
|
"categories": {
|
|
"diagnostics": 150,
|
|
"energy": 1,
|
|
"hvac": 802,
|
|
"lighting": 1748,
|
|
"scene": 2,
|
|
"sensor": 225,
|
|
"shutter": 357,
|
|
"unknown": 361
|
|
},
|
|
"devices": 275,
|
|
"file_digest": "d305fb55d52e",
|
|
"findings_by_code": {
|
|
"central_macro_no_status": 26,
|
|
"dpt_mismatch_co": 2,
|
|
"dpt_on_logic_object": 3,
|
|
"duplicate_name": 25,
|
|
"line_without_coupler": 1,
|
|
"missing_dpt": 32,
|
|
"missing_status_address": 58,
|
|
"missing_value_status": 38,
|
|
"reserve_without_dpt": 169,
|
|
"safety_input_no_status": 47,
|
|
"scene_no_status": 2,
|
|
"status_pairing_summary": 1,
|
|
"topology_segment_limit": 1
|
|
},
|
|
"findings_by_severity": {
|
|
"error": 32,
|
|
"info": 250,
|
|
"warning": 123
|
|
},
|
|
"group_addresses": 3646,
|
|
"ha_entities": {
|
|
"binary_sensor": 89,
|
|
"climate": 21,
|
|
"cover": 40,
|
|
"expose": 1,
|
|
"light": 412,
|
|
"sensor": 350,
|
|
"switch": 319
|
|
},
|
|
"ha_review_items": 1577,
|
|
"suggestion_hints": {
|
|
"channels": 983,
|
|
"diagnostics_skipped": 53,
|
|
"duplicates_skipped": 157,
|
|
"fallback": 0,
|
|
"pseudo_channels": 328,
|
|
"review": 220,
|
|
"sensors": 367,
|
|
"skipped_fb_covered": 0,
|
|
"structural": 513,
|
|
"subunits": 309,
|
|
"unwired_flagged": 20
|
|
},
|
|
"suggestions_by_platform": {
|
|
"binary_sensor": 254,
|
|
"climate": 28,
|
|
"cover": 92,
|
|
"light": 356,
|
|
"sensor": 113,
|
|
"switch": 37
|
|
}
|
|
}
|
|
}
|
|
}
|