[Voicecontrol] Button für Fhemweb

Begonnen von schwatter, 14 März 2026, 17:25:25

Vorheriges Thema - Nächstes Thema

schwatter

Hallo zusammen,

ich möchte euch das Projekt "VoiceControl" vorstellen. Mit dem JavaScript voicecontrol.js ist es möglich, Sprachbefehle direkt im Browser in Text umzuwandeln (Speech-to-Text) und an FHEM zu übertragen.

Das Konzept:
Die erkannten Befehle werden im Device "global" im Reading "STT" abgelegt. Dieses Reading dient als zentraler Einstiegspunkt und kann ganz flexibel über ein notify, DOIF oder andere Event-Handler ausgewertet werden.

Es gibt zwei Varianten:

1. Web-Variante (voicecontrol.js):
Ideal für die Nutzung am Desktop oder auf mobilen Geräten. Unterstützt Push-to-Talk und einen bedingt Always-On-Modus.

2. Hardware-Variante (voicecontrol_echo_s3r.js):
In Verbindung mit einem M5Stack Atom Echo S3 kann eine dedizierte Hardware-Lösung realisiert werden, die permanent auf ein Wakeword lauscht.

Wichtiger Hinweis zur Kompatibilität:
Da das System im Backend die Google Web Speech API nutzt, funktioniert es aktuell nur mit Chrome oder Chromium-basierten Browsern (z. B. Chrome, Edge, Fully Browser). Firefox unterstützt diese API derzeit leider nicht.

Dokumentation & Wiki:
Eine detaillierte Anleitung zur Einrichtung und Beispiele für die Auswertung findet ihr im Wiki:
https://wiki.fhem.de/wiki/FHEMWEB/VoiceControl:_Web-STT_%26_Hardware-Wakeword

Alle benötigten Dateien findet ihr im Anhang. Viel Spaß beim Ausprobieren!

Gruß
schwatter

schwatter

Aso, ich hatte auch mit webkitSpeechRecognition gespielt. Aber mein Chrome lässt mich nicht das Mikro
unter http freischalten. Da ist wohl https erforderlich  :( Oder irre ich mich?

Gruß schwatter

Dr. Boris Neubert

Zitat von: schwatter am 14 März 2026, 17:25:25defmod VoiceControl dummy
attr VoiceControl readingList state
attr VoiceControl room Test
attr VoiceControl setList state

setstate VoiceControl off
setstate VoiceControl 2026-03-14 17:24:00 state off

Wie ist denn das Widget mit dem Dummy verknüpft? Braucht man da nicht noch ein widgetOverride?
FHEM-Developer seit 2007, Mitgründer und Förder-Mitglied des FHEM e.V.
Bitte keine unaufgeforderten privaten Nachrichten!

schwatter

Das ist in dem JS voicebutton.js fest drinne

    function voiceOn() {
      console.log("Voice ON");
      FW_cmd('/fhem?cmd=set VoiceControl state on&XHR=1');
    }

    function voiceOff() {
      console.log("Voice OFF");
      FW_cmd('/fhem?cmd=set VoiceControl state off&XHR=1');
    }

Gruß schwatter

schwatter

Oh,

ok ich bin etwas weiter. Wer wie ich noch http benutzt kann in Chrome z.B
chrome://flags/#unsafely-treat-insecure-origin-as-secure aktivieren und in dem Feld
darunter den Link zu Fhem eintragen: http://192.168.1.76:8084
Jetzt habe ich zugriff auf das Mikro, bzw es ist freigeschaltet. Ich schaue mal.

Gruß schwatter

schwatter

Super,

jetzt funktioniert es. Am Laptop spinnt das Mikro. Konnte auf dem Handy gerade erfolgreich in den
state vom Dummy VoiceControl VoicetoText übertragen. Dazu beim sprechen den Button halten.
Update im ersten Post.

Gruß schwatter

rudolfkoenig

Ich habe f18.js mit STT erweitert.

Im Select-Style/f18 Menu gibt es einw STT Option, was das Micro oben einschaltet.

Beim Druecken auf das Micro kommt ein Dialog, da kann man was sagen, und das Ergebnis zu FHEM schicken.
In FHEM wird im dazugehoerigen FHEMWEB ein STT Reading gesetzt bzw. ein Event ausgeloest.
Die Sprache (DE oder EN) haengt vom "attr global language" ab, Voreinstellung ist EN.
Ich habe es mit Chromium, deutsch und englisch getestet. Es funktioniert auch ohne https.

schwatter

#7
Funktioniert!  :)

Aber bei mir mit http auf Chrome Android auch erst nachdem ich Insecure... aktiviert habe.
Vorher wird das Micro nicht aktiviert.

Edit:
Und bei mir werden relativ schnell doppelte/dreifache Wörter aufgenommen.
setstate WEBphone 2026-03-14 21:59:52 STT EsszimmerEsszimmerEsszimmerEsszimmer Licht Licht aus
Gruß schwatter

schwatter

Update im ersten Post.
Beispiel notify für den Voicebutton hinzugefügt.

Gruß schwatter

Beta-User

Wow!

Vielen Dank erst mal an euch beide!!! Kommt mir vor wie Ostern und Weihnachten zusammen ;D .

Habe erst mal zum Testen Rudis Variante aktiviert, weil das "direkt in FHEM" ohne große Umwege für die Allgemeinheit zur Verfügung steht. Erste Eindrücke (http):

- unter firefox@Linux kam "SpeechRecognition Interface missing"
- selbes Gerät, Chromium: Dialogfeld öffnet sich, aber ohne die Einstellung "chrome://flags/#unsafely-treat-insecure-origin-as-secure" passiert nichts. Wenn das für die FHEMWEB-Instanz freigegeben wird, kommt die Anfrage, ob man das Mikro freigeben will => OK. Leider wird dann aber immer noch nichts aufgenommen, das Mikro an sich ist aber an.

- firefox unter Android: wieder "SpeechRecognition Interface missing"
- chrome, Android: Nach Freigabe von "unsafely" und Mikrozugriff: Aufnahme, aber mit Wortwiederholungen (s.u.)
- fully, Android: Funktioniert ootb, aber mit Wortwiederholungen

Wortwiederholungen meint: Aus "Das ist ein Test" wird "setstate WEB 2026-03-15 07:19:02 STT dasdas istdas ist ein Test".
Es werden also (bereits im Dialogfeld so sichtbar) alle bereits erkannten Bestandteile wiederholt, sobald das nächste Wort fertig ist.

Ich vermute, dass man das Dialogfeld nach jedem Wort erst wieder leeren sollte?


Anmerkungen, Wünsche und Anregungen ::) :
  • Für "submit" würde ich mir (optional?) wünschen, dass das einfach nach einer "üblichen Ruhepause" beim Sprechen dann abgeschickt wird. Also: 2 Sekunden "silence" => automatisch absenden
  • Die Lösung via FHEMWEB hat mich zunächst irritiert, aber das ist generisch und funktioniert prinzipiell auf jedem Endgerät. SUPER!
  • Die Kehrseite: Einfache Texteingaben und notify sind nur ein sehr kleiner Ausschnitt dessen, was ich mir eigentlich vorstelle: Im Kern sollte das Ganze "dialogisch" ablaufen können, s.u.
  • Das Dialogfeld ist pragmatisch, aber als "hübsch" (im Sinne eines modern ausschauenden User-Interfaces) kann man das nicht wirklich bezeichnen ;D

Zum etwas größeren Bild, was schwebt mir eigentlich vor?

Verschiedene Endgeräte sollen dialogisch (per Sprachein- und -ausgabe) mit FHEM interagieren können.

Also sowas sollte möglich sein:
Zitat von: Beta-User am 19 November 2025, 07:31:05(ich) "Mach deutlich lauter"
(Handy) "soll das Radio im Wohnzimmer oder in der Küche lauter gemacht werden?"
(Anm: Sowas kann bei RHASSPY vorkommen, wenn grade beide Audio-Geräte angeschaltet sind und unklar ist, in welchem Raum sich der Sprechende befindet...)

Oder für sowas:
(ich) "Schalte den Fernseher aus"
(Handy) "soll ich wirklich den Fernseher ausschalten?"
(ich) "ja, mach!" (oder "ja bitte")
(Handy) "wird erledigt" (oder "okay", "aber gerne doch", "Aye, Sir!" usw.)

Hier läuft sowas (zumindest im Moment) mit RHASSPY, das ginge aber wohl genausogut mit Babble oder anderen FHEM-Methoden.

Dazu notwändig wäre m.E., dass man
  • zum einen identifizieren kann, von welchem Endgerät der STT-Text kam
  • dahin dann eine Rückmeldung (entweder Audio oder als TTS-Anweisung) senden kann, und
  • optimalerweise nach Ende der Ausgabe dieser Rückmeldung die Möglichkeit hätte, das Mikro wieder für weitere Eingaben zu aktivieren
Vermutlich liese sich der f18-js-Teil relativ leicht dahingehend aufbohren, dass zumindest klar ist, welche IP-Adresse das betreffende Endgerät hat, super wäre, direkt die betreffende Browser-Seite (asynchron) wieder ansprechen zu können (jedenfalls, solange diese offen ist). Keine Ahnung, ob das besonders kompliziert wäre...

Viele Wünsche, ich weiß O:-) .
Server: HP-elitedesk@Debian 13, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: ZigBee2mqtt, MiLight@ESP-GW, BT@OpenMQTTGw | ZWave | SIGNALduino | MapleCUN | RHASSPY
svn: u.a Weekday-&RandomTimer, Twilight,  div. attrTemplate-files, MySensors

schwatter

#10
Moin,

- Ich finde FHEMWEB nicht ideal. Besser sowas wie global. Das ist leichter bei mehreren FHEMWEB's. Ein Knotenpunkt. Deswegen habe ich den dummy.
- Zu Dialog führen. Kann der Text nicht einfach per notify an Rhasspy weitergereicht werden?

Gruß schwatter

schwatter

Update im ersten Post - voicecontrol.js

- Der Text wird jetzt mit setreading nach global STT geschrieben. Dummy fällt weg.
- Es gibt eine 2te Bubble für den erkannten Text.

Gruß schwatter

Beta-User

#12
Zitat von: schwatter am 15 März 2026, 08:54:52- Zu Dialog führen. Kann der Text nicht einfach per notify an Rhasspy weitergereicht werden?
RHASSPY hat eine NotifyFn() und setzt -abängig von der Konfiguration- NOTIFYDEF derzeit maximal auf "TYPE=(AMADCommBridge|AMADDevice|ROOMMATE|GUEST),global"

AMAD.* ist der "historische" Weg, um über TTS-Ereignisse und das Ende von Sprachausgaben informiert zu werden, ROOMMATE und GUEST dienen zum Chatten (hier via Telegram). In allen Fällen wird "angefragter Text" dann an Rhasspy bzw. die dortige Intent-Auswertung übergeben und das Ergebnis dann wieder in FHEM verarbeitet, alles selbstredend asynchron. RHASSPY "merkt" sich dabei, wohin ggf. dann welche Rückmeldung von Rhasspy zu senden ist, so dass auch - theoretisch - viele parallele Sitzungen möglich sind.

 
Zitat von: schwatter am 15 März 2026, 08:54:52- Ich finde FHEMWEB nicht ideal. Besser sowas wie global. Das ist leichter bei mehreren FHEMWEB's. Ein Knotenpunkt. Deswegen habe ich den dummy.
Für meine Zwecke ist es letztlich egal, wo das Event ausgelöst wird. Das NOTIFYDEF auf TYPE=FHEMWEB auszuweiten wäre jedenfalls kein Problem, und auch (in den meisten Installationen) begrenzter als alle dummy-TYPE-Instanzen mit auszuwerten. Events an "global" (zusätzlich anders) auszuwerten ginge selbstredend auch.

Unabhängig davon: AMADCommBridge nimmt die TTS-Info entgegen UND auch die Info, von welcher AMADDevice-Instanz die Anfrage stammt. So kann RHASSPY die zu sprechende Antwort genau dahin schicken, wo die Anweisung ursprünglich her war. (Für ROOMMATE|GUEST ist es sowieso klar).
Für meine Zwecke MUSS es also in jedem Fall eine zweite Info geben, wohin die Antwort (bzw. ggf. Rückfrage...) gesendet werden soll.

"Schön" wäre es, wenn auch das Ende einer von FHEM ausgelösten Sprachausgabe signalisiert werden könnte, und dafür erscheint mir "global" nicht der passende Ort zu sein; das ist bei FHEMWEB schon schwierig, weil da ja mehrere Sitzungen offen sein können...
Server: HP-elitedesk@Debian 13, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: ZigBee2mqtt, MiLight@ESP-GW, BT@OpenMQTTGw | ZWave | SIGNALduino | MapleCUN | RHASSPY
svn: u.a Weekday-&RandomTimer, Twilight,  div. attrTemplate-files, MySensors

rudolfkoenig

Das Firefox Problem habe ich jetzt in Prinzip (s.u.) gefixt.
Zum Aktivieren muss in about:config media.webspeech.recognition.enable auf true gesetzt werden.
Dann oeffnet sich das Dialog, nach Sprachaufnahme kommt aber die Meldung: Error connecting to the service.
Chrome@Android meldet bei mir nichtmal Audio started, keine Ahnung, was da falsch laeuft.

Die Doppelung der Texte lag vielleicht an stt.interimResults=true, das habe ich jetzt entfernt.
Bei mir hat das keinen Unterschied bewirkt.

Die anderen Punkte:
- eine eindeutige Zuordnung des Clients ist kein Problem, will aber (mit dem Rest auch) abwarten, welchen Weg wir gehen wollen
- Sprachausgabe ist laut Doku moeglich, habs aber nicht getestet
- Dialog veraltet: ich habe gerne ein Feedback, solange die Erkennung nicht perfekt ist. Was schwebt Dir vor?

HTTPS mit einem gueltigen Zertifikat hat den Vorteil, dass man damit eine WebApp installieren kann, was wiederum Benachrichtigungen empfangen kann (ungetestet).
Weiss (noch) nicht, ob man damit auch Sprachausgabe ausloesen kann, bin eher skeptisch.
Gueltige Zertifikate kann man auch selbst erstellen, das Zertifikat muss auf dem Client dann installiert werden.

schwatter

Ich habe jetzt auch versucht bei Firefox mit http Zugriff zu bekommen. Klappt nicht.
Habe in about:config folgende auf true gesetzt. Aber auch danach kein Glück:
media.webspeech.recognition.enable true
media.devices.enumerate.legacy.enabled true
media.getusermedia.insecure.enabled true

Du hattest ja manifest schon hinzugefügt. Wäre es nicht sinnvoll, dem User direkt beim installieren
https zur Verfügung zu stellen, ohne das er sich mit der Einrichtung beschäftigen muss.

Gruß schwatter