audio fix, js duplication removal
This commit is contained in:
@@ -2,6 +2,13 @@
|
||||
|
||||
All notable changes to the OpenClaw Home Assistant Integration will be documented in this file.
|
||||
|
||||
## [0.1.19] - 2026-02-20
|
||||
|
||||
### Changed
|
||||
- Made `custom_components/openclaw/www/openclaw-chat-card.js` the single source of truth for card implementation.
|
||||
- Replaced root `www/openclaw-chat-card.js` with a tiny loader shim that imports `/openclaw/openclaw-chat-card.js`.
|
||||
- Removed manual-maintenance duplication between two full card script files.
|
||||
|
||||
## [0.1.18] - 2026-02-20
|
||||
|
||||
### Fixed
|
||||
|
||||
@@ -24,9 +24,8 @@ A native Home Assistant integration for communicating with the
|
||||
### Manual
|
||||
|
||||
1. Copy `custom_components/openclaw/` into your HA `config/custom_components/` directory
|
||||
2. Copy `www/openclaw-chat-card.js` into `config/www/`
|
||||
3. Restart Home Assistant
|
||||
4. Add the integration via Settings → Devices & Services
|
||||
2. Restart Home Assistant
|
||||
3. Add the integration via Settings → Devices & Services
|
||||
|
||||
## Prerequisites
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
"iot_class": "local_polling",
|
||||
"issue_tracker": "https://github.com/techartdev/OpenClawHomeAssistant/issues",
|
||||
"requirements": [],
|
||||
"version": "0.1.18",
|
||||
"version": "0.1.19",
|
||||
"dependencies": ["conversation"],
|
||||
"after_dependencies": ["hassio", "lovelace"]
|
||||
}
|
||||
|
||||
@@ -64,6 +64,8 @@ class OpenClawChatCard extends HTMLElement {
|
||||
this._wakeWord = "hey openclaw";
|
||||
this._alwaysVoiceMode = false;
|
||||
this._voiceStatus = "";
|
||||
this._voiceRetryTimer = null;
|
||||
this._voiceRetryCount = 0;
|
||||
}
|
||||
|
||||
// ── HA card interface ───────────────────────────────────────────────
|
||||
@@ -120,6 +122,10 @@ class OpenClawChatCard extends HTMLElement {
|
||||
clearTimeout(this._historySyncRetryTimer);
|
||||
this._historySyncRetryTimer = null;
|
||||
}
|
||||
if (this._voiceRetryTimer) {
|
||||
clearTimeout(this._voiceRetryTimer);
|
||||
this._voiceRetryTimer = null;
|
||||
}
|
||||
}
|
||||
|
||||
// ── Event subscription ──────────────────────────────────────────────
|
||||
@@ -445,7 +451,21 @@ class OpenClawChatCard extends HTMLElement {
|
||||
|
||||
this._recognition.onerror = (event) => {
|
||||
console.error("OpenClaw: Speech recognition error:", event.error);
|
||||
this._voiceStatus = `Voice error: ${event.error}`;
|
||||
const err = event?.error || "unknown";
|
||||
if (err === "network") {
|
||||
this._voiceStatus =
|
||||
"Voice network error: browser speech service unavailable. Check internet and retry.";
|
||||
} else if (err === "not-allowed") {
|
||||
this._voiceStatus = "Microphone access denied. Allow mic permission for this site.";
|
||||
} else if (err === "audio-capture") {
|
||||
this._voiceStatus = "No microphone available.";
|
||||
} else {
|
||||
this._voiceStatus = `Voice error: ${err}`;
|
||||
}
|
||||
|
||||
if (this._isVoiceMode && ["network", "audio-capture", "no-speech"].includes(err)) {
|
||||
this._scheduleVoiceRetry();
|
||||
}
|
||||
this._render();
|
||||
};
|
||||
|
||||
@@ -472,10 +492,40 @@ class OpenClawChatCard extends HTMLElement {
|
||||
this._recognition.abort();
|
||||
this._recognition = null;
|
||||
}
|
||||
if (this._voiceRetryTimer) {
|
||||
clearTimeout(this._voiceRetryTimer);
|
||||
this._voiceRetryTimer = null;
|
||||
}
|
||||
this._voiceRetryCount = 0;
|
||||
this._isVoiceMode = false;
|
||||
this._voiceStatus = "";
|
||||
}
|
||||
|
||||
_scheduleVoiceRetry() {
|
||||
if (!this._isVoiceMode) return;
|
||||
if (this._voiceRetryCount >= 6) {
|
||||
this._voiceStatus =
|
||||
"Voice retry stopped after repeated errors. Toggle voice mode to try again.";
|
||||
this._render();
|
||||
return;
|
||||
}
|
||||
|
||||
if (this._voiceRetryTimer) {
|
||||
clearTimeout(this._voiceRetryTimer);
|
||||
}
|
||||
|
||||
const delayMs = Math.min(1000 * (this._voiceRetryCount + 1), 6000);
|
||||
this._voiceRetryCount += 1;
|
||||
this._voiceStatus = `Voice reconnecting in ${Math.ceil(delayMs / 1000)}s…`;
|
||||
this._render();
|
||||
|
||||
this._voiceRetryTimer = setTimeout(() => {
|
||||
this._voiceRetryTimer = null;
|
||||
if (!this._isVoiceMode) return;
|
||||
this._startVoiceRecognition();
|
||||
}, delayMs);
|
||||
}
|
||||
|
||||
_toggleVoiceMode() {
|
||||
this._isVoiceMode = !this._isVoiceMode;
|
||||
if (this._isVoiceMode) {
|
||||
|
||||
+5
-1003
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user