voice fixes when conversation is stopped

This commit is contained in:
techartdev
2026-02-20 20:36:25 +02:00
parent d1b3fb1d57
commit e29bbdb128
6 changed files with 48 additions and 6 deletions
+13
View File
@@ -2,6 +2,19 @@
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.28] - 2026-02-20
### Fixed
- Treat `SpeechRecognition` `aborted` events as expected stop behavior (no error status/no noisy console error) when voice is intentionally stopped.
- Added a stop-request guard to avoid restart/error churn during recognition shutdown.
- Synchronized release versioning so manifest, frontend loader URL, and backend card resource URL all use the same cache-busting version.
## [0.1.27] - 2026-02-20
### Changed
- Improved backward compatibility for older Home Assistant Core builds by removing Python 3.12-only type alias syntax in integration runtime code.
- Added fallback import handling for `ConfigFlowResult` in config flow type hints.
## [0.1.26] - 2026-02-20 ## [0.1.26] - 2026-02-20
### Added ### Added
+2 -2
View File
@@ -76,9 +76,9 @@ _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.26" _CARD_URL = f"{_CARD_STATIC_URL}?v=0.1.28"
type OpenClawConfigEntry = ConfigEntry OpenClawConfigEntry = ConfigEntry
# Service call schemas # Service call schemas
+11 -1
View File
@@ -14,7 +14,17 @@ from typing import Any
import voluptuous as vol import voluptuous as vol
from homeassistant.config_entries import ConfigEntry, ConfigFlow, ConfigFlowResult, OptionsFlow try:
from homeassistant.config_entries import (
ConfigEntry,
ConfigFlow,
ConfigFlowResult,
OptionsFlow,
)
except ImportError:
from homeassistant.config_entries import ConfigEntry, ConfigFlow, OptionsFlow
ConfigFlowResult = dict[str, Any]
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.helpers.aiohttp_client import async_get_clientsession from homeassistant.helpers.aiohttp_client import async_get_clientsession
+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.26", "version": "0.1.28",
"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.2.6"; const CARD_VERSION = "0.2.7";
// 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;
@@ -72,6 +72,7 @@ class OpenClawChatCard extends HTMLElement {
this._integrationVoiceLanguage = null; this._integrationVoiceLanguage = null;
this._allowBraveWebSpeechIntegration = false; this._allowBraveWebSpeechIntegration = false;
this._voiceBackendBlocked = false; this._voiceBackendBlocked = false;
this._voiceStopRequested = false;
} }
// ── HA card interface ─────────────────────────────────────────────── // ── HA card interface ───────────────────────────────────────────────
@@ -491,6 +492,7 @@ class OpenClawChatCard extends HTMLElement {
_startVoiceRecognition() { _startVoiceRecognition() {
this._voiceBackendBlocked = false; this._voiceBackendBlocked = false;
this._voiceStopRequested = false;
const allowBraveWebSpeech = const allowBraveWebSpeech =
this._config.allow_brave_webspeech || this._allowBraveWebSpeechIntegration; this._config.allow_brave_webspeech || this._allowBraveWebSpeechIntegration;
@@ -556,6 +558,13 @@ class OpenClawChatCard extends HTMLElement {
this._recognition.onerror = (event) => { this._recognition.onerror = (event) => {
const err = event?.error || "unknown"; const err = event?.error || "unknown";
if (err === "aborted") {
if (this._voiceStopRequested) {
return;
}
console.debug("OpenClaw: Speech recognition aborted");
return;
}
if (err === "network") { if (err === "network") {
console.warn("OpenClaw: Speech recognition network error"); console.warn("OpenClaw: Speech recognition network error");
} else { } else {
@@ -594,6 +603,15 @@ class OpenClawChatCard extends HTMLElement {
}; };
this._recognition.onend = () => { this._recognition.onend = () => {
if (this._voiceStopRequested) {
this._voiceStopRequested = false;
if (!this._isVoiceMode) {
this._voiceStatus = "";
this._render();
}
return;
}
if (this._isVoiceMode) { if (this._isVoiceMode) {
// Restart recognition in voice mode // Restart recognition in voice mode
try { try {
@@ -613,6 +631,7 @@ class OpenClawChatCard extends HTMLElement {
_stopVoiceRecognition() { _stopVoiceRecognition() {
if (this._recognition) { if (this._recognition) {
this._voiceStopRequested = true;
this._recognition.abort(); this._recognition.abort();
this._recognition = null; this._recognition = null;
} }
+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.26"; const src = "/openclaw/openclaw-chat-card.js?v=0.1.28";
console.info("OpenClaw loader importing", src); console.info("OpenClaw loader importing", src);
await import(src); await import(src);
} }