From 9a22cea15925831ddf96aa1406f76ba70e47e1e3 Mon Sep 17 00:00:00 2001 From: techartdev Date: Fri, 20 Feb 2026 17:31:58 +0200 Subject: [PATCH] Update changelog for version 0.1.17, improve chat history recovery, implement retry logic for backend history sync, and enhance message merging logic. --- CHANGELOG.md | 7 +++++ custom_components/openclaw/manifest.json | 2 +- .../openclaw/www/openclaw-chat-card.js | 27 +++++++++++++++++-- www/openclaw-chat-card.js | 27 +++++++++++++++++-- 4 files changed, 58 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6cad7e5..adb1ff1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,13 @@ All notable changes to the OpenClaw Home Assistant Integration will be documented in this file. +## [0.1.17] - 2026-02-20 + +### Fixed +- Improved chat history recovery after leaving and returning to dashboard. +- Card now retries backend history sync when websocket is not yet ready. +- History merge now updates when message count is unchanged but latest message content/timestamp differs. + ## [0.1.16] - 2026-02-20 ### Added diff --git a/custom_components/openclaw/manifest.json b/custom_components/openclaw/manifest.json index 5ebcdf6..e51d031 100644 --- a/custom_components/openclaw/manifest.json +++ b/custom_components/openclaw/manifest.json @@ -8,7 +8,7 @@ "iot_class": "local_polling", "issue_tracker": "https://github.com/techartdev/OpenClawHomeAssistant/issues", "requirements": [], - "version": "0.1.16", + "version": "0.1.17", "dependencies": ["conversation"], "after_dependencies": ["hassio", "lovelace"] } diff --git a/custom_components/openclaw/www/openclaw-chat-card.js b/custom_components/openclaw/www/openclaw-chat-card.js index 1423500..b5c3d90 100644 --- a/custom_components/openclaw/www/openclaw-chat-card.js +++ b/custom_components/openclaw/www/openclaw-chat-card.js @@ -59,6 +59,7 @@ class OpenClawChatCard extends HTMLElement { this._recognition = null; this._eventUnsubscribe = null; this._thinkingTimer = null; + this._historySyncRetryTimer = null; this._wakeWordEnabled = false; this._wakeWord = "hey openclaw"; this._alwaysVoiceMode = false; @@ -114,6 +115,10 @@ class OpenClawChatCard extends HTMLElement { this._unsubscribeEvents(); this._stopVoiceRecognition(); this._clearThinkingTimer(); + if (this._historySyncRetryTimer) { + clearTimeout(this._historySyncRetryTimer); + this._historySyncRetryTimer = null; + } } // ── Event subscription ────────────────────────────────────────────── @@ -217,7 +222,7 @@ class OpenClawChatCard extends HTMLElement { } } - async _syncHistoryFromBackend() { + async _syncHistoryFromBackend(retries = 6) { if (!this._hass) return; const sessionId = this._getSessionId(); @@ -244,7 +249,17 @@ class OpenClawChatCard extends HTMLElement { ); if (!validMessages.length) return; - if (validMessages.length > this._messages.length) { + const shouldReplace = + validMessages.length > this._messages.length || + (validMessages.length === this._messages.length && + validMessages.length > 0 && + this._messages.length > 0 && + (validMessages[validMessages.length - 1].content !== + this._messages[this._messages.length - 1].content || + validMessages[validMessages.length - 1].timestamp !== + this._messages[this._messages.length - 1].timestamp)); + + if (shouldReplace) { this._messages = validMessages; this._isProcessing = false; this._clearThinkingTimer(); @@ -254,6 +269,14 @@ class OpenClawChatCard extends HTMLElement { } } catch (err) { console.debug("OpenClaw: history sync skipped:", err); + if (retries > 0) { + if (this._historySyncRetryTimer) { + clearTimeout(this._historySyncRetryTimer); + } + this._historySyncRetryTimer = setTimeout(() => { + this._syncHistoryFromBackend(retries - 1); + }, 1500); + } } } diff --git a/www/openclaw-chat-card.js b/www/openclaw-chat-card.js index 1423500..b5c3d90 100644 --- a/www/openclaw-chat-card.js +++ b/www/openclaw-chat-card.js @@ -59,6 +59,7 @@ class OpenClawChatCard extends HTMLElement { this._recognition = null; this._eventUnsubscribe = null; this._thinkingTimer = null; + this._historySyncRetryTimer = null; this._wakeWordEnabled = false; this._wakeWord = "hey openclaw"; this._alwaysVoiceMode = false; @@ -114,6 +115,10 @@ class OpenClawChatCard extends HTMLElement { this._unsubscribeEvents(); this._stopVoiceRecognition(); this._clearThinkingTimer(); + if (this._historySyncRetryTimer) { + clearTimeout(this._historySyncRetryTimer); + this._historySyncRetryTimer = null; + } } // ── Event subscription ────────────────────────────────────────────── @@ -217,7 +222,7 @@ class OpenClawChatCard extends HTMLElement { } } - async _syncHistoryFromBackend() { + async _syncHistoryFromBackend(retries = 6) { if (!this._hass) return; const sessionId = this._getSessionId(); @@ -244,7 +249,17 @@ class OpenClawChatCard extends HTMLElement { ); if (!validMessages.length) return; - if (validMessages.length > this._messages.length) { + const shouldReplace = + validMessages.length > this._messages.length || + (validMessages.length === this._messages.length && + validMessages.length > 0 && + this._messages.length > 0 && + (validMessages[validMessages.length - 1].content !== + this._messages[this._messages.length - 1].content || + validMessages[validMessages.length - 1].timestamp !== + this._messages[this._messages.length - 1].timestamp)); + + if (shouldReplace) { this._messages = validMessages; this._isProcessing = false; this._clearThinkingTimer(); @@ -254,6 +269,14 @@ class OpenClawChatCard extends HTMLElement { } } catch (err) { console.debug("OpenClaw: history sync skipped:", err); + if (retries > 0) { + if (this._historySyncRetryTimer) { + clearTimeout(this._historySyncRetryTimer); + } + this._historySyncRetryTimer = setTimeout(() => { + this._syncHistoryFromBackend(retries - 1); + }, 1500); + } } }