diff --git a/README.md b/README.md index d0747f5..26be08f 100755 --- a/README.md +++ b/README.md @@ -60,6 +60,21 @@ Key advantages in short: The card is registered automatically — no need to add a Lovelace resource manually. +> **Card doesn't load (`Custom element doesn't exist: houseplan-card`) or you manage Lovelace +> resources in YAML?** Add the resource manually pointing at the URL the integration *serves*: +> +> ```yaml +> resources: +> - url: /houseplan_files/houseplan-card.js +> type: module +> ``` +> +> Do **not** use `/custom_components/houseplan/frontend/houseplan-card.js` — that is the file +> on disk, which Home Assistant does not serve over HTTP (you'll get a `text/plain` MIME error +> and the element never registers). The correct, integration-served URL is +> `/houseplan_files/houseplan-card.js`. Both cards (`houseplan-card` and +> `houseplan-space-card`) ship in that one file — no separate resource is needed. + ### Manually 1. Copy the `custom_components/houseplan` folder into the `config/custom_components` directory of your Home Assistant. diff --git a/README.ru.md b/README.ru.md index dcfa732..5ae7ba7 100644 --- a/README.ru.md +++ b/README.ru.md @@ -60,6 +60,21 @@ House Plan показывает ваш умный дом так, как он в Карточка подключается автоматически — добавлять ресурс Lovelace вручную не нужно. +> **Карточка не грузится (`Custom element doesn't exist: houseplan-card`) или вы ведёте ресурсы +> Lovelace в YAML?** Добавьте ресурс вручную, указав URL, который *раздаёт сама интеграция*: +> +> ```yaml +> resources: +> - url: /houseplan_files/houseplan-card.js +> type: module +> ``` +> +> **Не** используйте `/custom_components/houseplan/frontend/houseplan-card.js` — это путь к файлу +> на диске, который Home Assistant не отдаёт по HTTP (получите ошибку MIME `text/plain`, и элемент +> не зарегистрируется). Правильный URL, который раздаёт интеграция, — `/houseplan_files/houseplan-card.js`. +> Обе карточки (`houseplan-card` и `houseplan-space-card`) лежат в этом одном файле — отдельный ресурс +> не нужен. + ### Вручную 1. Скопируйте папку `custom_components/houseplan` в каталог `config/custom_components` вашего Home Assistant. diff --git a/custom_components/houseplan/__init__.py b/custom_components/houseplan/__init__.py index 8fd120f..3a09e7c 100755 --- a/custom_components/houseplan/__init__.py +++ b/custom_components/houseplan/__init__.py @@ -79,8 +79,21 @@ async def async_setup_entry(hass: HomeAssistant, entry: HouseplanConfigEntry) -> # start of the mobile app). If the resource registry is unavailable (YAML-mode # Lovelace, old versions) — fall back to extra_module_url. module_url = f"{FRONTEND_URL}?v={VERSION}" - if not await _register_lovelace_resource(hass, module_url): + registered = await _register_lovelace_resource(hass, module_url) + if not registered: add_extra_js_url(hass, module_url) + # Tell the user exactly where the card lives — the #1 support issue is people adding a + # Lovelace resource pointing at the on-disk path (/custom_components/...), which HA does + # not serve (wrong MIME → "Custom element doesn't exist"). The correct served URL is below. + if registered: + _LOGGER.info("House Plan card auto-registered as a Lovelace resource: %s", module_url) + else: + _LOGGER.info( + "House Plan card is served at %s . Lovelace resources look YAML-managed — add it " + "manually under `resources:` as { url: %s, type: module }. Do NOT use the on-disk " + "path /custom_components/houseplan/frontend/houseplan-card.js (HA does not serve it).", + module_url, module_url, + ) await async_check_plan_files(hass, entry) return True diff --git a/custom_components/houseplan/__pycache__/__init__.cpython-310.pyc b/custom_components/houseplan/__pycache__/__init__.cpython-310.pyc index 19070f3..c1a8b86 100644 Binary files a/custom_components/houseplan/__pycache__/__init__.cpython-310.pyc and b/custom_components/houseplan/__pycache__/__init__.cpython-310.pyc differ diff --git a/custom_components/houseplan/const.py b/custom_components/houseplan/const.py index 83a8f47..411bba9 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.16.1" +VERSION = "1.16.2" DEFAULT_CONFIG: dict = { "spaces": [], diff --git a/custom_components/houseplan/frontend/houseplan-card.js b/custom_components/houseplan/frontend/houseplan-card.js index 53f09be..cb6b95c 100755 --- a/custom_components/houseplan/frontend/houseplan-card.js +++ b/custom_components/houseplan/frontend/houseplan-card.js @@ -1388,4 +1388,4 @@ const t=globalThis,e=t.ShadowRoot&&(void 0===t.ShadyCSS||t.ShadyCSS.nativeShadow - `}}pe.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}},pe.styles=Wt,customElements.get("houseplan-card")||customElements.define("houseplan-card",pe),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.16.1 ","background:#3ea6ff;color:#04121f;font-weight:700",""); + `}}pe.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}},pe.styles=Wt,customElements.get("houseplan-card")||customElements.define("houseplan-card",pe),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.16.2 ","background:#3ea6ff;color:#04121f;font-weight:700",""); diff --git a/custom_components/houseplan/manifest.json b/custom_components/houseplan/manifest.json index 8952484..7c8bd09 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.16.1" + "version": "1.16.2" } diff --git a/dist/houseplan-card.js b/dist/houseplan-card.js index 53f09be..cb6b95c 100755 --- a/dist/houseplan-card.js +++ b/dist/houseplan-card.js @@ -1388,4 +1388,4 @@ const t=globalThis,e=t.ShadowRoot&&(void 0===t.ShadyCSS||t.ShadyCSS.nativeShadow - `}}pe.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}},pe.styles=Wt,customElements.get("houseplan-card")||customElements.define("houseplan-card",pe),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.16.1 ","background:#3ea6ff;color:#04121f;font-weight:700",""); + `}}pe.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}},pe.styles=Wt,customElements.get("houseplan-card")||customElements.define("houseplan-card",pe),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.16.2 ","background:#3ea6ff;color:#04121f;font-weight:700",""); diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 0457eb5..9d88ece 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -1,5 +1,16 @@ # Changelog +## v1.16.2 — 2026-07-11 (docs+log: correct card resource URL — fixes "Custom element doesn't exist") +- **Support issue #2**: users adding a Lovelace resource that points at the on-disk path + `/custom_components/houseplan/frontend/houseplan-card.js` get a `text/plain` MIME error and + "Custom element doesn't exist: houseplan-card" — HA does not serve `custom_components/` over + HTTP. The integration serves the card at **`/houseplan_files/houseplan-card.js`** (verified: + `200 text/javascript`) and auto-registers it as a Lovelace resource in storage mode. +- README (en+ru) now documents the correct URL and the common mistake, incl. a YAML-mode + `resources:` snippet. +- On setup the integration logs (INFO) the exact served URL and, when Lovelace resources are + YAML-managed, how to add it manually — so the fix is discoverable from the logs. + ## v1.16.1 — 2026-07-08 (space-card shows room fills as configured) - **The static `houseplan-space-card` now renders room fills exactly as configured on the full card** (temperature / signal / lights coloring), as a snapshot of the states passed diff --git a/docs/STATUS.md b/docs/STATUS.md index 0cf405d..20ea76e 100644 --- a/docs/STATUS.md +++ b/docs/STATUS.md @@ -13,7 +13,7 @@ | Item | State | |---|---| -| Version | **v1.16.1** everywhere (manifest, const.py, package.json, CARD_VERSION) | +| Version | **v1.16.2** 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/9004** (queue ≈2 months as of 2026-07). Lesson: #8995 was auto-closed by hacs-bot — the PR body MUST be their exact template with every checkbox ticked and all 3 links (release, HACS action run, hassfest run); a custom body gets closed without discussion | diff --git a/package.json b/package.json index 035c2b7..67743bd 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "houseplan-card", - "version": "1.16.1", + "version": "1.16.2", "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 37b9610..8e1b6ec 100755 --- a/src/houseplan-card.ts +++ b/src/houseplan-card.ts @@ -26,7 +26,7 @@ import './space-card'; import { cardStyles } from './styles'; import { langOf, t, type I18nKey } from './i18n'; -const CARD_VERSION = '1.16.1'; +const CARD_VERSION = '1.16.2'; 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';