diff --git a/CHANGELOG.md b/CHANGELOG.md index d2112a8..6ad5a22 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -58,6 +58,28 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added +- **Room Template Library — R1 (vertical slice)** (`room_library.py`, `room_templates/`, two new MCP + tools; tool count **28 → 30**). Compose a **new** KNX project from a list of parametrised room + templates ("constructor"). The template format is a deliberate public contract (`room_templates/SCHEMA.md`): + `schema_version`, a **locale-neutral semantic `slot_id`** (identity never comes from a human name), + `labels.{ru,en}` for presentation, **per-slot** `basic`/`comfort` presets (not one monolithic room + level — a house can mix comfort climate with basic lighting), and parameters where `area_m2` is an + explicit **hint** with provenance, never a normative fact. Six built-in rooms ship: bedroom, children, + living, kitchen, bathroom, corridor. Templates describe **functions** (function-first); logic + (presence→light) is declared as non-executable `automation_intents` metadata only. + A separate resolved IR (its own dataclasses — **not** the public `GARecord`) drives allocation + (main = domain, middle = role, sub sequential) with a hard error on sub-address exhaustion (never a + silent overflow). Critically, the composer writes a **real `.knxproj` (ZIP of ETS XML) and re-reads it + through the standard `load_project`** — the same path used for third-party projects — so generation + never touches the classifier and is validated by the real reader. New tools: + `validate_room_template(template?, path?)` (schema check) and + `compose_rooms(rooms, language="ru", project_name?, output_dir?, dry_run=true)` — outputs an allocation + `manifest`, ETS GA **XML/CSV** via the existing generators, and a device **BOM proposal** from the + device library. New projects only, dry-run by default; docking into an existing project and exact + device selection are R2. The generated house passes all four linters (naming / missing-status / DPT / + policy) with **0 errors and 0 warnings**. `tests/test_room_library.py` (golden RU/EN, idempotency, + permutation invariance, address-exhaustion error, round-trip 0-error lint, negative-oracle manifest). + - **Explainable aggregate scores** (`advanced.py`, `handover.py`). Every headline percentage now ships the numbers behind it instead of a bare figure: Matter readiness, the completeness grade and command/status coverage each carry a `math` block with the numerator, denominator, the exact formula diff --git a/README.md b/README.md index 848f666..99b59f7 100644 --- a/README.md +++ b/README.md @@ -250,7 +250,7 @@ keyring handling, and the recommended workflow). --- -## MCP tools (28) +## MCP tools (30) **Read** | Tool | Purpose | @@ -296,6 +296,12 @@ keyring handling, and the recommended workflow). | `project_report(output_path?, name_regex?)` | Markdown report | | `workspace_info()` | workspace path + safety guarantees | +**Room Library** (R1 — compose a new project from room templates) +| Tool | Purpose | +|------|---------| +| `validate_room_template(template?, path?)` | validate a room template (built-in slot_id or a custom YAML) against the R1 schema | +| `compose_rooms(rooms, language="ru", project_name?, output_dir?, dry_run=true)` | build a **new** project from a list of rooms → allocation `manifest`, ETS GA XML/CSV, device `bom` proposal; generated `.knxproj` is re-read by the standard loader and linted (0 errors / 0 warnings). New projects only, dry-run by default. | + --- ## Typical workflow @@ -356,7 +362,7 @@ nickol-knx-mcp/ │ ├── generate_ha.py # Home Assistant KNX YAML generation │ ├── generate_ets.py # ETS XML + CSV generation │ ├── report.py # Markdown report -│ └── server.py # FastMCP server, 28 tools, confined writes +│ └── server.py # FastMCP server, 30 tools, confined writes ├── tests/test_pipeline.py ├── examples/claude_desktop_config.json ├── skills/ diff --git a/pyproject.toml b/pyproject.toml index 0ce502d..5bf6526 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -40,3 +40,6 @@ build-backend = "setuptools.build_meta" [tool.setuptools] packages = ["nickol_knx_mcp"] + +[tool.setuptools.package-data] +nickol_knx_mcp = ["room_templates/*.yaml", "room_templates/*.md"]