Update changelog for version 0.1.9, enhance Lovelace resource registration, improve frontend registration retries, and update minimum Home Assistant version
This commit is contained in:
@@ -2,6 +2,25 @@
|
||||
|
||||
All notable changes to the OpenClaw Home Assistant Integration will be documented in this file.
|
||||
|
||||
## [0.1.9] - 2026-02-20
|
||||
|
||||
### Fixed
|
||||
- Updated Lovelace resource registration to use Home Assistant 2026.2 storage API (`hass.data[LOVELACE_DATA].resources`) with legacy fallback.
|
||||
- Prevented silent resource-registration failure caused by reading the old `hass.data["lovelace"]` key only.
|
||||
|
||||
### Changed
|
||||
- Updated `hacs.json` minimum Home Assistant version to `2026.2.0`.
|
||||
|
||||
## [0.1.8] - 2026-02-20
|
||||
|
||||
### Fixed
|
||||
- Removed false-positive config-flow warning for `enable_openai_api=false` when Supervisor options are missing or use a different schema.
|
||||
- Frontend auto-registration no longer gets stuck after an early startup failure.
|
||||
- Card resource registration now retries for longer and can recover on integration reload.
|
||||
|
||||
### Changed
|
||||
- Frontend registration task is now de-duplicated while running and marked complete only after successful Lovelace resource creation.
|
||||
|
||||
## [0.1.7] - 2026-02-20
|
||||
|
||||
### Fixed
|
||||
|
||||
@@ -13,6 +13,11 @@ from typing import Any
|
||||
|
||||
import voluptuous as vol
|
||||
|
||||
try:
|
||||
from homeassistant.components.lovelace.const import LOVELACE_DATA
|
||||
except ImportError: # pragma: no cover
|
||||
LOVELACE_DATA = "lovelace"
|
||||
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import EVENT_HOMEASSISTANT_STARTED
|
||||
from homeassistant.core import HomeAssistant, ServiceCall, callback
|
||||
@@ -175,15 +180,21 @@ async def _async_register_frontend(hass: HomeAssistant) -> None:
|
||||
Called as a fire-and-forget task from async_setup_entry.
|
||||
Wrapped entirely in try/except so it can NEVER crash the integration.
|
||||
"""
|
||||
frontend_key = f"{DOMAIN}_frontend_registration_started"
|
||||
if hass.data.get(frontend_key):
|
||||
frontend_done_key = f"{DOMAIN}_frontend_registered"
|
||||
frontend_task_key = f"{DOMAIN}_frontend_registration_task"
|
||||
|
||||
if hass.data.get(frontend_done_key):
|
||||
return
|
||||
|
||||
existing_task = hass.data.get(frontend_task_key)
|
||||
if existing_task and not existing_task.done():
|
||||
return
|
||||
hass.data[frontend_key] = True
|
||||
|
||||
async def _register_with_retries() -> None:
|
||||
for _ in range(12):
|
||||
for _ in range(60):
|
||||
url = await _async_register_static_path(hass)
|
||||
if url and await _async_add_lovelace_resource(hass, url):
|
||||
hass.data[frontend_done_key] = True
|
||||
return
|
||||
await asyncio.sleep(5)
|
||||
|
||||
@@ -193,9 +204,17 @@ async def _async_register_frontend(hass: HomeAssistant) -> None:
|
||||
_CARD_URL,
|
||||
)
|
||||
|
||||
hass.async_create_task(_register_with_retries())
|
||||
task = hass.async_create_task(_register_with_retries())
|
||||
hass.data[frontend_task_key] = task
|
||||
|
||||
def _clear_task(_fut: asyncio.Future) -> None:
|
||||
hass.data.pop(frontend_task_key, None)
|
||||
|
||||
task.add_done_callback(_clear_task)
|
||||
|
||||
async def _on_ha_started(_event) -> None:
|
||||
if hass.data.get(frontend_done_key):
|
||||
return
|
||||
await _register_with_retries()
|
||||
|
||||
hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STARTED, _on_ha_started)
|
||||
@@ -230,15 +249,20 @@ async def _async_register_static_path(hass: HomeAssistant) -> str | None:
|
||||
|
||||
async def _async_add_lovelace_resource(hass: HomeAssistant, url: str) -> bool:
|
||||
"""Add the card URL to Lovelace's resource store if not already present."""
|
||||
# Lovelace stores resources in hass.data["lovelace"]["resources"].
|
||||
# It is a ResourceStorageCollection with:
|
||||
# Lovelace stores resources in hass.data[LOVELACE_DATA].resources on
|
||||
# modern Home Assistant versions (fallback to legacy dict key below).
|
||||
# Resource collection supports:
|
||||
# .async_items() → list of {"id", "res_type", "url"} dicts
|
||||
# .async_create_item(data) → persists a new resource
|
||||
lovelace_data = hass.data.get("lovelace")
|
||||
lovelace_data = hass.data.get(LOVELACE_DATA) or hass.data.get("lovelace")
|
||||
if not lovelace_data:
|
||||
return False
|
||||
|
||||
resource_collection = lovelace_data.get("resources")
|
||||
if isinstance(lovelace_data, dict):
|
||||
resource_collection = lovelace_data.get("resources")
|
||||
else:
|
||||
resource_collection = getattr(lovelace_data, "resources", None)
|
||||
|
||||
if resource_collection is None:
|
||||
return False
|
||||
|
||||
|
||||
@@ -163,9 +163,13 @@ async def _async_try_discover_addon(hass: HomeAssistant) -> dict[str, Any] | Non
|
||||
)
|
||||
return None
|
||||
|
||||
# Warn early if the OpenAI-compatible API is disabled — /v1/models will return
|
||||
# HTML and the connection probe will fail with a misleading error.
|
||||
if not addon_options.get("enable_openai_api", False):
|
||||
# Warn only when Supervisor explicitly reports the option as disabled.
|
||||
# If the key is missing (older/newer addon schema), do not warn.
|
||||
enable_openai_api = addon_options.get("enable_openai_api")
|
||||
if enable_openai_api is None and isinstance(addon_options.get("gateway"), dict):
|
||||
enable_openai_api = addon_options["gateway"].get("enable_openai_api")
|
||||
|
||||
if enable_openai_api is False:
|
||||
_LOGGER.warning(
|
||||
"Addon option 'enable_openai_api' is false. "
|
||||
"The integration requires this to be enabled. "
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
"iot_class": "local_polling",
|
||||
"issue_tracker": "https://github.com/techartdev/OpenClawHomeAssistant/issues",
|
||||
"requirements": [],
|
||||
"version": "0.1.7",
|
||||
"version": "0.1.9",
|
||||
"dependencies": ["conversation"],
|
||||
"after_dependencies": ["hassio", "lovelace"]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user