diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 0000000..db1979c --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -0,0 +1,36 @@ +name: Bug report +description: Something in House Plan does not work as expected +labels: [bug] +body: + - type: input + id: version + attributes: + label: House Plan version + placeholder: v1.13.0 + validations: + required: true + - type: input + id: ha_version + attributes: + label: Home Assistant version + placeholder: "2026.6" + validations: + required: true + - type: textarea + id: what + attributes: + label: What happened / what did you expect? + description: Steps to reproduce help a lot. + validations: + required: true + - type: textarea + id: logs + attributes: + label: Logs / browser console errors + description: "Settings → System → Logs (search: houseplan) and the browser console (F12)." + render: text + - type: textarea + id: diagnostics + attributes: + label: Diagnostics + description: "Settings → Devices & services → House Plan → ⋯ → Download diagnostics (personal fields are redacted automatically)." diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml new file mode 100644 index 0000000..60a3638 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -0,0 +1,14 @@ +name: Feature request +description: An idea to make House Plan better +labels: [enhancement] +body: + - type: textarea + id: problem + attributes: + label: What problem would this solve? + validations: + required: true + - type: textarea + id: proposal + attributes: + label: How do you imagine it working? diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..6b45cac --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,39 @@ +# Contributing to House Plan + +Thanks for your interest! The project is one HACS package: a storage **integration** +(`custom_components/houseplan/`, Python) and a **Lovelace card** (`src/`, TypeScript + Lit). + +## Five-minute setup + +```bash +git clone https://github.com/Matysh/houseplan-card && cd houseplan-card +npm ci # frontend toolchain +npm run typecheck # tsc --noEmit (strict) +npm test # node:test — pure logic, i18n parity, tap-action security +npm run build # tsc + rollup → dist/houseplan-card.js +pip install pytest voluptuous && python -m pytest tests_backend -q # pure backend tests +``` + +The HA-harness backend tests (`tests_backend/test_ha_*.py`) need Python ≥3.13 and +`pytest-homeassistant-custom-component home-assistant-frontend`; CI runs them on +every push — locally they are skipped when `homeassistant` is not importable. + +## Ground rules + +- **Docs in the same commit**: CHANGELOG entry for user-visible changes; + `docs/STATUS.md` for state changes; `docs/DEVELOPMENT.md` for new gotchas. +- Every UI string goes through `src/i18n/.json` (tests enforce en/ru key parity). + Adding a language = adding one JSON file + registering it in `src/i18n.ts`. +- The built card must be committed in sync: `cp dist/houseplan-card.js + custom_components/houseplan/frontend/` (CI compares them byte-for-byte). +- Tap actions have a security model (locks/alarms never toggle from the plan) — + see `resolveTapAction` in `src/logic.ts`; don't weaken it. +- Follow the Integration Quality Scale where applicable — + `custom_components/houseplan/quality_scale.yaml` tracks the self-assessment. + +## Architecture + +Start with `docs/ARCHITECTURE.md` (data model, WS API, coordinate system) and +`docs/STATUS.md` (current state). Release: bump the version in `package.json`, +`manifest.json`, `const.py`, `CARD_VERSION`, tag `vX.Y.Z`, publish a GitHub release — +the workflow attaches the card bundle. diff --git a/README.md b/README.md index 3e72a3b..d0747f5 100755 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ **A live map of your home right inside Home Assistant: floors, rooms and devices on a real floor plan — with live states, temperature and signal strength. Everything is configured with the mouse, without a single line of YAML.** -![Interactive house plan with devices](docs/images/01-plan.png) +![House Plan demo](docs/images/demo.gif) 🇷🇺 [Документация на русском](README.ru.md) diff --git a/README.ru.md b/README.ru.md index 5d4e0e2..dcfa732 100644 --- a/README.ru.md +++ b/README.ru.md @@ -2,7 +2,7 @@ **Живая карта вашего дома прямо в Home Assistant: этажи, комнаты и устройства на настоящем плане — с реальными состояниями, температурой и уровнем сигнала. Всё настраивается мышкой, без единой строчки YAML.** -![Интерактивный план дома с устройствами](docs/images/01-plan.png) +![House Plan demo](docs/images/demo.gif) 🇬🇧 [English documentation](README.md) diff --git a/custom_components/houseplan/const.py b/custom_components/houseplan/const.py index 0451ad9..7122657 100755 --- a/custom_components/houseplan/const.py +++ b/custom_components/houseplan/const.py @@ -11,7 +11,7 @@ PLANS_DIR = "houseplan/plans" # relative to the HA configuration directory FILES_URL = "/houseplan_files/files" FILES_DIR = "houseplan/files" CONF_ADMIN_ONLY = "admin_only" -VERSION = "1.13.0" +VERSION = "1.13.1" DEFAULT_CONFIG: dict = { "spaces": [], diff --git a/custom_components/houseplan/frontend/houseplan-card.js b/custom_components/houseplan/frontend/houseplan-card.js index dde57cf..9d2f264 100755 --- a/custom_components/houseplan/frontend/houseplan-card.js +++ b/custom_components/houseplan/frontend/houseplan-card.js @@ -1175,4 +1175,4 @@ const t=globalThis,e=t.ShadowRoot&&(void 0===t.ShadyCSS||t.ShadyCSS.nativeShadow - `}}Bt.properties={hass:{attribute:!1},_config:{state:!0},_space:{state:!0},_layout:{state:!0},_devices:{state:!0},_tip:{state:!0},_selId:{state:!0},_toast:{state:!0},_serverCfg:{state:!0},_markup:{state:!0},_tool:{state:!0},_path:{state:!0},_cursorPt:{state:!0},_areaSel:{state:!0},_nameSel:{state:!0},_roomDialog:{state:!0},_spaceDialog:{state:!0},_infoCard:{state:!0},_rulesDialog:{state:!0},_importDialog:{state:!0},_markerDialog:{state:!0},_zoom:{state:!0},_view:{state:!0}},Bt.styles=Ut,customElements.get("houseplan-card")||customElements.define("houseplan-card",Bt),window.customCards=window.customCards||[],window.customCards.find(t=>"houseplan-card"===t.type)||window.customCards.push({type:"houseplan-card",name:"House Plan Card",description:"Interactive house plan: spaces, rooms and devices with live states and drag layout."}),console.info("%c HOUSEPLAN-CARD %c v1.13.0 ","background:#3ea6ff;color:#04121f;font-weight:700",""); + `}}Bt.properties={hass:{attribute:!1},_config:{state:!0},_space:{state:!0},_layout:{state:!0},_devices:{state:!0},_tip:{state:!0},_selId:{state:!0},_toast:{state:!0},_serverCfg:{state:!0},_markup:{state:!0},_tool:{state:!0},_path:{state:!0},_cursorPt:{state:!0},_areaSel:{state:!0},_nameSel:{state:!0},_roomDialog:{state:!0},_spaceDialog:{state:!0},_infoCard:{state:!0},_rulesDialog:{state:!0},_importDialog:{state:!0},_markerDialog:{state:!0},_zoom:{state:!0},_view:{state:!0}},Bt.styles=Ut,customElements.get("houseplan-card")||customElements.define("houseplan-card",Bt),window.customCards=window.customCards||[],window.customCards.find(t=>"houseplan-card"===t.type)||window.customCards.push({type:"houseplan-card",name:"House Plan Card",description:"Interactive house plan: spaces, rooms and devices with live states and drag layout."}),console.info("%c HOUSEPLAN-CARD %c v1.13.1 ","background:#3ea6ff;color:#04121f;font-weight:700",""); diff --git a/custom_components/houseplan/manifest.json b/custom_components/houseplan/manifest.json index ad59a2f..94eceb9 100755 --- a/custom_components/houseplan/manifest.json +++ b/custom_components/houseplan/manifest.json @@ -16,5 +16,5 @@ "issue_tracker": "https://github.com/Matysh/houseplan-card/issues", "requirements": [], "single_config_entry": true, - "version": "1.13.0" + "version": "1.13.1" } diff --git a/dist/houseplan-card.js b/dist/houseplan-card.js index dde57cf..9d2f264 100755 --- a/dist/houseplan-card.js +++ b/dist/houseplan-card.js @@ -1175,4 +1175,4 @@ const t=globalThis,e=t.ShadowRoot&&(void 0===t.ShadyCSS||t.ShadyCSS.nativeShadow - `}}Bt.properties={hass:{attribute:!1},_config:{state:!0},_space:{state:!0},_layout:{state:!0},_devices:{state:!0},_tip:{state:!0},_selId:{state:!0},_toast:{state:!0},_serverCfg:{state:!0},_markup:{state:!0},_tool:{state:!0},_path:{state:!0},_cursorPt:{state:!0},_areaSel:{state:!0},_nameSel:{state:!0},_roomDialog:{state:!0},_spaceDialog:{state:!0},_infoCard:{state:!0},_rulesDialog:{state:!0},_importDialog:{state:!0},_markerDialog:{state:!0},_zoom:{state:!0},_view:{state:!0}},Bt.styles=Ut,customElements.get("houseplan-card")||customElements.define("houseplan-card",Bt),window.customCards=window.customCards||[],window.customCards.find(t=>"houseplan-card"===t.type)||window.customCards.push({type:"houseplan-card",name:"House Plan Card",description:"Interactive house plan: spaces, rooms and devices with live states and drag layout."}),console.info("%c HOUSEPLAN-CARD %c v1.13.0 ","background:#3ea6ff;color:#04121f;font-weight:700",""); + `}}Bt.properties={hass:{attribute:!1},_config:{state:!0},_space:{state:!0},_layout:{state:!0},_devices:{state:!0},_tip:{state:!0},_selId:{state:!0},_toast:{state:!0},_serverCfg:{state:!0},_markup:{state:!0},_tool:{state:!0},_path:{state:!0},_cursorPt:{state:!0},_areaSel:{state:!0},_nameSel:{state:!0},_roomDialog:{state:!0},_spaceDialog:{state:!0},_infoCard:{state:!0},_rulesDialog:{state:!0},_importDialog:{state:!0},_markerDialog:{state:!0},_zoom:{state:!0},_view:{state:!0}},Bt.styles=Ut,customElements.get("houseplan-card")||customElements.define("houseplan-card",Bt),window.customCards=window.customCards||[],window.customCards.find(t=>"houseplan-card"===t.type)||window.customCards.push({type:"houseplan-card",name:"House Plan Card",description:"Interactive house plan: spaces, rooms and devices with live states and drag layout."}),console.info("%c HOUSEPLAN-CARD %c v1.13.1 ","background:#3ea6ff;color:#04121f;font-weight:700",""); diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 30ab654..0d46375 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## v1.13.1 — 2026-07-05 (distribution materials) +- **Demo GIF** in the README — recorded on a fully synthetic demo home (no real + floor plans): live states, tap-to-toggle, drag, zoom, info card, space tabs. +- GitHub issue templates (bug report with diagnostics hint, feature request), + `CONTRIBUTING.md` (5-minute setup, ground rules, architecture pointers), + Discussions enabled. + ## v1.13.0 — 2026-07-05 (universality: floors import, icon rules, tap actions) - **Floors import wizard**: on first run, if the HA registry has floors, the card offers to create a space per floor — names prefilled, the (mandatory) plan image is diff --git a/docs/STATUS.md b/docs/STATUS.md index 6eda394..b07b21b 100644 --- a/docs/STATUS.md +++ b/docs/STATUS.md @@ -13,7 +13,7 @@ | Item | State | |---|---| -| Version | **v1.13.0** everywhere (manifest, const.py, package.json, CARD_VERSION) | +| Version | **v1.13.1** everywhere (manifest, const.py, package.json, CARD_VERSION) | | GitHub | https://github.com/Matysh/houseplan-card — branch `main`, releases v1.9.3…v1.11.2 | | CI | `.github/workflows/validate.yml` (hacs + hassfest + frontend + backend) — **fully green** since v1.11.1; `release.yml` auto-attaches the card bundle (needs `permissions: contents: write`, fixed) | | HACS | Works as custom repository (id 1290210112 on the home instance). **Inclusion PR: https://github.com/hacs/default/pull/8995** (queue ≈2 months as of 2026-07) | @@ -37,6 +37,9 @@ uninstall cleanup, HA-harness tests in CI, quality_scale.yaml. - **v1.13.0** — universality: floors-import wizard, editable icon rules (+device_class fallback), tap actions with a security model, i18n dictionaries in JSON, light-theme pass. +- **v1.13.1** — distribution: synthetic-home demo GIF in the README, issue templates, + CONTRIBUTING.md, Discussions. Forum/Reddit drafts are in the user folder + (`posts_drafts.md`) awaiting manual posting. ## Where things live @@ -55,7 +58,11 @@ `~/.git-credentials`. Revoke after the HACS queue clears, or re-issue when needed. 3. Stale files on the mount that cannot be deleted from the sandbox: `src/data/` leftovers, `brand_preview.png`, old nested bundle copies — ignore, git is authoritative. -4. Roadmap next: see ROADMAP.md (quality-scale conformance is the next big theme). +4. Roadmap: phases 7–10 are DONE (v1.12.0 quality scale, v1.13.0 universality, + v1.13.1 distribution). Next candidates: replace the remaining real-house README + screenshots with synthetic ones; measure backend coverage (>95% goal); mypy strict. +5. The demo harness lives in /tmp/demo (synthetic home: demo.html + capture.mjs) — + rebuildable from this repo + docs/DEVELOPMENT.md notes; frames → PIL → GIF. ## How to resume work in a fresh session (checklist) diff --git a/docs/images/demo.gif b/docs/images/demo.gif new file mode 100644 index 0000000..6378c61 Binary files /dev/null and b/docs/images/demo.gif differ diff --git a/package.json b/package.json index 365584c..f5c62a6 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "houseplan-card", - "version": "1.13.0", + "version": "1.13.1", "description": "Interactive house plan Lovelace card for Home Assistant", "license": "MIT", "type": "module", diff --git a/src/houseplan-card.ts b/src/houseplan-card.ts index 3395ce7..12be343 100755 --- a/src/houseplan-card.ts +++ b/src/houseplan-card.ts @@ -23,7 +23,7 @@ import './editor'; import { cardStyles } from './styles'; import { langOf, t, type I18nKey } from './i18n'; -const CARD_VERSION = '1.13.0'; +const CARD_VERSION = '1.13.1'; const LS_KEY = 'houseplan_card_layout_v1'; const LS_CFG = 'houseplan_card_cfg_v1'; // cache of the server config+layout for instant rendering const LS_ZOOM = 'houseplan_card_zoom_v1';