Update changelog for version 0.1.6, fix integration loading issues, and enhance frontend registration process

This commit is contained in:
techartdev
2026-02-20 15:34:11 +02:00
parent 2308ddfc45
commit c3311a6376
3 changed files with 44 additions and 48 deletions
+11
View File
@@ -2,6 +2,17 @@
All notable changes to the OpenClaw Home Assistant Integration will be documented in this file. All notable changes to the OpenClaw Home Assistant Integration will be documented in this file.
## [0.1.6] - 2025-01-01
### Fixed
- Integration "Not loaded" state caused by `hass.http.register_static_path()` being called in `async_setup` before the HTTP server is ready
- Removed `async_setup` and the synchronous `_async_register_static_path` helper
- `_async_register_frontend` is now a proper `async` function, safe to fire-and-forget from `async_setup_entry`
- Supports both the HA 2024.11+ `async_register_static_paths` / `StaticPathConfig` API and the legacy `register_static_path` API with automatic fallback to `/local/` URL
- Frontend registration errors are caught and logged as warnings — they can never crash the integration load
---
## [0.1.5] - 2026-02-20 ## [0.1.5] - 2026-02-20
### Added ### Added
+32 -47
View File
@@ -49,16 +49,6 @@ _CARD_URL = f"/openclaw/{_CARD_FILENAME}"
type OpenClawConfigEntry = ConfigEntry type OpenClawConfigEntry = ConfigEntry
async def async_setup(hass: HomeAssistant, config: dict) -> bool:
"""Global integration setup — runs once before any config entries.
Registers the static HTTP path for the chat card so the JS file is served
directly from inside the integration package, regardless of whether the
user installed via HACS or manually.
"""
_async_register_static_path(hass)
return True
# Service call schemas # Service call schemas
SEND_MESSAGE_SCHEMA = vol.Schema( SEND_MESSAGE_SCHEMA = vol.Schema(
{ {
@@ -111,7 +101,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: OpenClawConfigEntry) ->
_async_register_services(hass) _async_register_services(hass)
# Register the frontend card resource # Register the frontend card resource
_async_register_frontend(hass) hass.async_create_task(_async_register_frontend(hass))
# Listen for addon restart events to re-read token # Listen for addon restart events to re-read token
if addon_config_path: if addon_config_path:
@@ -177,50 +167,45 @@ def _async_setup_token_refresh(
# ── Frontend registration ───────────────────────────────────────────────────── # ── Frontend registration ─────────────────────────────────────────────────────
@callback async def _async_register_frontend(hass: HomeAssistant) -> None:
def _async_register_static_path(hass: HomeAssistant) -> None: """Register static path + Lovelace resource for the chat card.
"""Register the integration's www/ folder as a static HTTP path.
After this the card JS is always available at /openclaw/openclaw-chat-card.js Called as a fire-and-forget task from async_setup_entry.
regardless of how the integration was installed (HACS or manual). Wrapped entirely in try/except so it can NEVER crash the integration.
"""
static_key = f"{DOMAIN}_static_registered"
if hass.data.get(static_key):
return
hass.data[static_key] = True
if not _CARD_PATH.exists():
_LOGGER.warning(
"Chat card JS not found at %s — frontend resource will not be available",
_CARD_PATH,
)
return
hass.http.register_static_path(
f"/openclaw/{_CARD_FILENAME}",
str(_CARD_PATH),
cache_headers=True,
)
_LOGGER.debug("Registered static path: /openclaw/%s", _CARD_FILENAME)
@callback
def _async_register_frontend(hass: HomeAssistant) -> None:
"""Register the Lovelace custom card resource (called once per setup).
Adds the card URL to Lovelace's resource list so it loads on every
dashboard automatically. No manual step required.
""" """
frontend_key = f"{DOMAIN}_frontend_registered" frontend_key = f"{DOMAIN}_frontend_registered"
if hass.data.get(frontend_key): if hass.data.get(frontend_key):
return return
hass.data[frontend_key] = True hass.data[frontend_key] = True
# Ensure static path is registered (may have been missed if async_setup url = _CARD_URL
# didn't run, e.g. during a config entry reload).
_async_register_static_path(hass)
hass.async_create_task(_async_add_lovelace_resource(hass, _CARD_URL)) # ── Step 1: Serve the JS via a static HTTP path ───────────────────
if _CARD_PATH.exists() and hass.http is not None:
try:
# HA 2024.11+ — async_register_static_paths w/ StaticPathConfig
from homeassistant.components.http import StaticPathConfig # noqa: PLC0415
await hass.http.async_register_static_paths(
[StaticPathConfig(url, str(_CARD_PATH), cache_headers=True)]
)
_LOGGER.debug("Registered static path (new API): %s", url)
except (ImportError, AttributeError):
try:
# HA <2024.11 — synchronous register_static_path
hass.http.register_static_path(url, str(_CARD_PATH), True)
_LOGGER.debug("Registered static path (legacy API): %s", url)
except Exception as err: # noqa: BLE001
_LOGGER.debug("Could not register static path '%s': %s", url, err)
url = f"/local/{_CARD_FILENAME}" # fall back to /local/ URL
except Exception as err: # noqa: BLE001
_LOGGER.debug("Could not register static path '%s': %s", url, err)
url = f"/local/{_CARD_FILENAME}"
else:
# JS not in package (shouldn't happen) or HTTP not ready — try /local/
url = f"/local/{_CARD_FILENAME}"
# ── Step 2: Add to Lovelace resource store ───────────────────────
await _async_add_lovelace_resource(hass, url)
async def _async_add_lovelace_resource(hass: HomeAssistant, url: str) -> None: async def _async_add_lovelace_resource(hass: HomeAssistant, url: str) -> None:
+1 -1
View File
@@ -8,7 +8,7 @@
"iot_class": "local_polling", "iot_class": "local_polling",
"issue_tracker": "https://github.com/techartdev/OpenClawHomeAssistant/issues", "issue_tracker": "https://github.com/techartdev/OpenClawHomeAssistant/issues",
"requirements": [], "requirements": [],
"version": "0.1.5", "version": "0.1.6",
"dependencies": ["conversation"], "dependencies": ["conversation"],
"after_dependencies": ["hassio", "lovelace"] "after_dependencies": ["hassio", "lovelace"]
} }