Skip to content

Commit ab66180

Browse files
authored
Update fast-search-card.js
1 parent 1dd5aae commit ab66180

File tree

1 file changed

+59
-137
lines changed

1 file changed

+59
-137
lines changed

dist/fast-search-card.js

Lines changed: 59 additions & 137 deletions
Original file line numberDiff line numberDiff line change
@@ -12307,7 +12307,7 @@ class FastSearchCard extends HTMLElement {
1230712307
}
1230812308

1230912309
async speakTTS(text, entityId) {
12310-
// 🛡️ Race Condition Protection
12310+
// 🛡️ Race Condition Protection (bleibt unverändert)
1231112311
if (this.isTTSActive) {
1231212312
console.log('⚠️ TTS bereits aktiv, ignoriere neuen Aufruf');
1231312313
return false;
@@ -12323,54 +12323,70 @@ class FastSearchCard extends HTMLElement {
1232312323

1232412324
try {
1232512325
console.log(`🗣️ Speaking: "${text}" on ${entityId}`);
12326-
12327-
// 🔍 Erweiterte Player-State-Erkennung
12326+
12327+
// Player-Status speichern (bleibt unverändert)
1232812328
const playerState = await this.getEnhancedPlayerState(entityId);
12329-
const wasPlaying = playerState.isActuallyPlaying;
12330-
12331-
console.log(`🎵 Enhanced player analysis:`, playerState);
12332-
12333-
// 💾 Status für Auto-Resume speichern
12334-
this.ttsPlayerWasPlaying = wasPlaying ? entityId : null;
12335-
this.ttsStartedAt = Date.now();
12336-
12337-
// 💾 VOLLSTÄNDIGEN Player-Zustand speichern
12338-
if (wasPlaying) {
12329+
if (playerState.isActuallyPlaying) {
12330+
this.ttsPlayerWasPlaying = entityId;
1233912331
const state = this._hass.states[entityId];
1234012332
this.savedPlayerContext = {
1234112333
entityId: entityId,
1234212334
mediaContentId: state.attributes.media_content_id,
1234312335
mediaContentType: state.attributes.media_content_type || 'music',
1234412336
mediaPosition: state.attributes.media_position || 0,
12345-
volumeLevel: state.attributes.volume_level,
12346-
mediaTitle: state.attributes.media_title,
12347-
mediaArtist: state.attributes.media_artist
1234812337
};
12349-
console.log('💾 Saved player context:', this.savedPlayerContext);
12350-
}
12351-
12352-
// ⏸️ Intelligentes Pausieren
12353-
if (wasPlaying) {
12338+
console.log('💾 Player-Kontext gespeichert:', this.savedPlayerContext);
1235412339
await this.smartPausePlayer(entityId);
1235512340
}
12356-
12357-
// 🎤 TTS mit verbessertem Fallback-System
12341+
12342+
// Button-Status aktualisieren (bleibt unverändert)
1235812343
this.updateTTSButtonState('speaking');
12344+
12345+
// TTS ausführen (bleibt unverändert)
1235912346
await this.executeSmartTTS(text, entityId);
12347+
12348+
// --- NEUE, ROBUSTERE LOGIK ---
12349+
// Berechne eine dynamische Wartezeit basierend auf der Textlänge.
12350+
// Annahme: ca. 80ms pro Zeichen + 1.5 Sekunden Puffer.
12351+
const calculatedDelay = text.length * 80 + 1500;
12352+
console.log(`⏳ Berechnete TTS-Dauer: ${calculatedDelay}ms`);
12353+
12354+
// Starte den Timer zur Wiederherstellung
12355+
this.ttsResumeTimeout = setTimeout(() => {
12356+
console.log('⏰ Timer abgelaufen, starte Wiederherstellung.');
12357+
this.resumePlayback();
12358+
}, calculatedDelay);
12359+
// --- ENDE NEUE LOGIK ---
1236012360

12361-
// 🎧 Event-basierte TTS-Überwachung (ersetzt Timer)
12362-
await this.startTTSMonitoring(entityId);
12361+
// --- ENTFERNT ---
12362+
// Die alte, unzuverlässige Überwachung wird entfernt.
12363+
// await this.startTTSMonitoring(entityId);
1236312364

1236412365
return true;
12365-
12366+
1236612367
} catch (error) {
1236712368
console.error('❌ TTS Error:', error);
1236812369
this.updateTTSButtonState('error');
12369-
await this.cleanupTTSState();
12370+
// Im Fehlerfall sofort aufräumen
12371+
clearTimeout(this.ttsResumeTimeout);
12372+
await this.finalizeTTSProcess();
1237012373
return false;
1237112374
}
1237212375
}
1237312376

12377+
// in der FastSearchCard-Klasse
12378+
12379+
async resumePlayback() {
12380+
console.log('▶️ Starte Musik-Wiederherstellung...');
12381+
if (this.ttsPlayerWasPlaying && this.savedPlayerContext) {
12382+
await this.restorePlayerContext();
12383+
} else {
12384+
console.log('🤷 Keine Musik zum Wiederherstellen.');
12385+
}
12386+
// Nach der Wiederherstellung den Prozess finalisieren
12387+
await this.finalizeTTSProcess();
12388+
}
12389+
1237412390
// 🔍 ERWEITERTE PLAYER-STATE-ERKENNUNG
1237512391
async getEnhancedPlayerState(entityId) {
1237612392
const state = this._hass.states[entityId];
@@ -12525,124 +12541,30 @@ class FastSearchCard extends HTMLElement {
1252512541
}
1252612542
}
1252712543

12528-
async startTTSMonitoring(entityId) {
12529-
console.log('🎧 Starting TTS monitoring...');
12530-
12531-
let ttsStarted = false;
12532-
let lastPosition = null;
12533-
let lastMediaId = null;
12534-
let positionStableCount = 0;
12535-
let checksWithoutChange = 0;
12536-
12537-
// Speichere initiale Werte
12538-
const initialState = this._hass.states[entityId];
12539-
const initialMediaId = initialState?.attributes?.media_content_id;
12540-
12541-
this.ttsMonitorInterval = setInterval(async () => {
12542-
const currentState = this._hass.states[entityId];
12543-
if (!currentState) return;
12544-
12545-
const currentPosition = currentState.attributes?.media_position;
12546-
const currentMediaId = currentState.attributes?.media_content_id;
12547-
const isPlaying = currentState.state === 'playing';
12548-
12549-
// TTS Start erkennen
12550-
if (!ttsStarted && isPlaying) {
12551-
ttsStarted = true;
12552-
console.log('🎤 TTS started');
12553-
checksWithoutChange = 0;
12554-
}
12555-
12556-
// TTS Ende erkennen durch verschiedene Methoden:
12557-
if (ttsStarted) {
12558-
// Methode 1: Player ist nicht mehr playing
12559-
if (currentState.state !== 'playing') {
12560-
console.log('🎉 TTS completed - player stopped');
12561-
clearInterval(this.ttsMonitorInterval);
12562-
this.ttsMonitorInterval = null;
12563-
await this.restorePlayerContext();
12564-
await this.finalizeTTSProcess(entityId);
12565-
return;
12566-
}
12567-
12568-
// Methode 2: Media ID hat sich geändert (zurück zur Original-Musik)
12569-
if (currentMediaId && currentMediaId !== lastMediaId && currentMediaId === this.savedPlayerContext?.mediaContentId) {
12570-
console.log('🎉 TTS completed - original media restored');
12571-
clearInterval(this.ttsMonitorInterval);
12572-
this.ttsMonitorInterval = null;
12573-
await this.finalizeTTSProcess(entityId);
12574-
return;
12575-
}
12576-
12577-
// Methode 3: Position bewegt sich nicht mehr (TTS fertig, aber Player noch "playing")
12578-
if (currentPosition !== undefined && currentPosition !== null) {
12579-
if (currentPosition === lastPosition) {
12580-
positionStableCount++;
12581-
if (positionStableCount > 10) { // 1 Sekunde keine Bewegung
12582-
console.log('🎉 TTS completed - position stable');
12583-
clearInterval(this.ttsMonitorInterval);
12584-
this.ttsMonitorInterval = null;
12585-
await this.restorePlayerContext();
12586-
await this.finalizeTTSProcess(entityId);
12587-
return;
12588-
}
12589-
} else {
12590-
positionStableCount = 0;
12591-
}
12592-
}
12593-
12594-
// Methode 4: Keine Attribute-Änderungen für längere Zeit
12595-
const hasChanges = JSON.stringify(currentState.attributes) !== JSON.stringify(initialState.attributes);
12596-
if (!hasChanges) {
12597-
checksWithoutChange++;
12598-
if (checksWithoutChange > 20) { // 2 Sekunden keine Änderungen
12599-
console.log('🎉 TTS completed - no attribute changes');
12600-
clearInterval(this.ttsMonitorInterval);
12601-
this.ttsMonitorInterval = null;
12602-
await this.restorePlayerContext();
12603-
await this.finalizeTTSProcess(entityId);
12604-
return;
12605-
}
12606-
} else {
12607-
checksWithoutChange = 0;
12608-
}
12609-
}
12610-
12611-
lastPosition = currentPosition;
12612-
lastMediaId = currentMediaId;
12613-
12614-
}, 100); // Alle 100ms prüfen
12615-
12616-
// Kürzeres Sicherheits-Timeout - 10 Sekunden sollten reichen
12617-
setTimeout(() => {
12618-
if (this.ttsMonitorInterval) {
12619-
console.log('⚠️ TTS monitoring timeout (10s)');
12620-
clearInterval(this.ttsMonitorInterval);
12621-
this.ttsMonitorInterval = null;
12622-
this.restorePlayerContext();
12623-
this.finalizeTTSProcess(entityId);
12624-
}
12625-
}, 10000); // Reduziert von 30 auf 10 Sekunden
12626-
}
12627-
12628-
// 🏁 TTS-PROZESS FINALISIEREN
12629-
async finalizeTTSProcess(entityId) {
12544+
// in der FastSearchCard-Klasse
12545+
12546+
async finalizeTTSProcess() {
1263012547
console.log('🏁 Finalizing TTS process...');
1263112548

12632-
// Aufräumen
12549+
// Aufräumen (bleibt unverändert)
1263312550
await this.cleanupTTSState();
1263412551

12635-
// Button zurücksetzen
12552+
// Button zurücksetzen (bleibt unverändert)
1263612553
this.updateTTSButtonState('ready');
1263712554

12638-
// Monitor-Interval löschen
12639-
if (this.ttsMonitorInterval) {
12640-
clearInterval(this.ttsMonitorInterval);
12641-
this.ttsMonitorInterval = null;
12642-
}
12555+
// Timer-Timeout sicherheitshalber löschen
12556+
clearTimeout(this.ttsResumeTimeout);
12557+
this.ttsResumeTimeout = null;
12558+
12559+
// --- ENTFERNT ---
12560+
// Das Monitor-Interval existiert nicht mehr.
12561+
// if (this.ttsMonitorInterval) {
12562+
// clearInterval(this.ttsMonitorInterval);
12563+
// this.ttsMonitorInterval = null;
12564+
// }
1264312565

1264412566
console.log('✅ TTS process finalized');
12645-
}
12567+
}
1264612568

1264712569

1264812570
// 🧹 CLEANUP STATE

0 commit comments

Comments
 (0)