Bump version to 0.1.55, fix chat scrolling issues, restore requestAnimationFrame, and improve entity ID lookups

This commit is contained in:
techartdev
2026-02-23 16:38:24 +02:00
parent aae2e25600
commit bb13ac9237
5 changed files with 34 additions and 19 deletions
+8
View File
@@ -2,6 +2,14 @@
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.55] - 2026-02-23
### Fixed
- Fixed chat always scrolling to the TOP instead of bottom on every message (both user and bot).
- Restored `requestAnimationFrame` in `_scrollToBottom()` — synchronous scrollTop assignment after innerHTML replacement does not persist in shadow DOM before the browser finalizes layout.
- Changed `_render()` to only upgrade `_autoScrollPinned` to `true` (never downgrade), preventing a race condition where rapid re-renders set it to `false` permanently.
- Fixed "Gateway: Unknown" badge — entity ID lookup now matches `sensor.openclaw*status` and `binary_sensor.openclaw*connected` patterns, covering `has_entity_name` variants like `sensor.openclaw_assistant_status`.
## [0.1.53] - 2026-02-23 ## [0.1.53] - 2026-02-23
### Fixed ### Fixed
+1 -1
View File
@@ -93,7 +93,7 @@ _CARD_PATH = Path(__file__).parent / "www" / _CARD_FILENAME
# URL at which the card JS is served (registered via register_static_path) # URL at which the card JS is served (registered via register_static_path)
_CARD_STATIC_URL = f"/openclaw/{_CARD_FILENAME}" _CARD_STATIC_URL = f"/openclaw/{_CARD_FILENAME}"
# Versioned URL used for Lovelace resource registration to avoid stale browser cache # Versioned URL used for Lovelace resource registration to avoid stale browser cache
_CARD_URL = f"{_CARD_STATIC_URL}?v=0.1.53" _CARD_URL = f"{_CARD_STATIC_URL}?v=0.1.55"
OpenClawConfigEntry = ConfigEntry OpenClawConfigEntry = ConfigEntry
+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.54", "version": "0.1.55",
"dependencies": ["conversation"], "dependencies": ["conversation"],
"after_dependencies": ["hassio", "lovelace"] "after_dependencies": ["hassio", "lovelace"]
} }
@@ -13,7 +13,7 @@
* + subscribes to openclaw_message_received events. * + subscribes to openclaw_message_received events.
*/ */
const CARD_VERSION = "0.3.11"; const CARD_VERSION = "0.3.12";
// Max time (ms) to show the thinking indicator before falling back to an error // Max time (ms) to show the thinking indicator before falling back to an error
const THINKING_TIMEOUT_MS = 120_000; const THINKING_TIMEOUT_MS = 120_000;
@@ -145,12 +145,16 @@ class OpenClawChatCard extends HTMLElement {
const statusEntity = const statusEntity =
states["sensor.openclaw_status"] || states["sensor.openclaw_status"] ||
stateEntries.find(([entityId]) => entityId.startsWith("sensor.openclaw_status"))?.[1] || stateEntries.find(([entityId]) =>
entityId.startsWith("sensor.openclaw") && entityId.includes("status")
)?.[1] ||
null; null;
const binaryEntity = const binaryEntity =
states["binary_sensor.openclaw_connected"] || states["binary_sensor.openclaw_connected"] ||
stateEntries.find(([entityId]) => entityId.startsWith("binary_sensor.openclaw_connected"))?.[1] || stateEntries.find(([entityId]) =>
entityId.startsWith("binary_sensor.openclaw") && entityId.includes("connected")
)?.[1] ||
null; null;
const status = String(statusEntity?.state || "").toLowerCase(); const status = String(statusEntity?.state || "").toLowerCase();
@@ -163,17 +167,18 @@ class OpenClawChatCard extends HTMLElement {
const states = this._hass?.states || {}; const states = this._hass?.states || {};
const stateEntries = Object.entries(states); const stateEntries = Object.entries(states);
const exactStatus = states["sensor.openclaw_status"];
const exactConnected = states["binary_sensor.openclaw_connected"];
const statusEntity = const statusEntity =
exactStatus || states["sensor.openclaw_status"] ||
stateEntries.find(([entityId]) => entityId.startsWith("sensor.openclaw_status"))?.[1] || stateEntries.find(([entityId]) =>
entityId.startsWith("sensor.openclaw") && entityId.includes("status")
)?.[1] ||
null; null;
const binaryEntity = const binaryEntity =
exactConnected || states["binary_sensor.openclaw_connected"] ||
stateEntries.find(([entityId]) => entityId.startsWith("binary_sensor.openclaw_connected"))?.[1] || stateEntries.find(([entityId]) =>
entityId.startsWith("binary_sensor.openclaw") && entityId.includes("connected")
)?.[1] ||
null; null;
const status = String(statusEntity?.state || "").toLowerCase(); const status = String(statusEntity?.state || "").toLowerCase();
@@ -1782,10 +1787,12 @@ class OpenClawChatCard extends HTMLElement {
} }
_scrollToBottom(force = false) { _scrollToBottom(force = false) {
requestAnimationFrame(() => {
const container = this.shadowRoot?.querySelector(".messages"); const container = this.shadowRoot?.querySelector(".messages");
if (container && (force || this._autoScrollPinned)) { if (container && (force || this._autoScrollPinned)) {
container.scrollTop = container.scrollHeight; container.scrollTop = container.scrollHeight;
} }
});
} }
_formatTime(isoString) { _formatTime(isoString) {
@@ -1802,8 +1809,8 @@ class OpenClawChatCard extends HTMLElement {
_render() { _render() {
const previousContainer = this.shadowRoot?.querySelector(".messages"); const previousContainer = this.shadowRoot?.querySelector(".messages");
if (previousContainer) { if (previousContainer && this._isNearBottom(previousContainer)) {
this._autoScrollPinned = this._isNearBottom(previousContainer); this._autoScrollPinned = true;
} }
const config = this._config; const config = this._config;
+1 -1
View File
@@ -1,7 +1,7 @@
(async () => { (async () => {
try { try {
if (!customElements.get("openclaw-chat-card")) { if (!customElements.get("openclaw-chat-card")) {
const src = "/openclaw/openclaw-chat-card.js?v=0.1.54"; const src = "/openclaw/openclaw-chat-card.js?v=0.1.55";
console.info("OpenClaw loader importing", src); console.info("OpenClaw loader importing", src);
await import(src); await import(src);
} }