NEWS
Rhasspy Offline Sprachsteuerung
-
@Tom10web sagte in Rhasspy Offline Sprachsteuerung:
Noch eine Frage, wie bekomme ich Rhasspy dazu, mir z.B. die Aussentemperatur anzusagen.
Direkte Sprachausgabe auf dem Rhasspy-Raspi haben wir auch noch nicht hinbekommen.
Evtl. wird das was, wenn die angekündigte Rhasspy Version 2.5 verfügbar ist. ( Vorschau auf das GUI: rhasspy-voltron ).Ich nutze momentan einen Workaround, in dem ich den entspr. Antworttext mit JavaScript generiere und diesen Text dann mit dem ioBroker PAW-Adapter an mein Tablet/Smartphone sende, wo dann die Sprachausgabe erfolgt.
Der Wert der Aussentemperatur (bzw. weiterer Temperaturen) muss natürlich bereits in einem ioBroker-Datenpunkt vorhanden sein.
Der Rhasspy-Sentence sieht bei mir so aus:
[Temperatur] temperatur_name = (temperatur) {name} temperatur_state = (draussen| wohnzimmer | keller | schlafzimmer | badewasser) {state} wie (warm | kalt) ist [es | das] [(im)] <temperatur_state>
Das entspr. Javascript:
const temperatur = 'mqtt.0.rhasspy.intent.Temperatur' // Temperatur //______________________________________________ // Temperaturen on({id: temperatur, change: "any"},function(obj) { let empf_code = getState(temperatur).val ; let empf_json = JSON.parse(empf_code); let name = empf_json.name; let state = empf_json.state; //log ("name: " + name + " state: " + state); if (state == "draussen") { let aussentemp_obj = "hm-rpc.2.CUX0100001.1.TEMPERATURE"; let aussenfeuchte_obj = "hm-rpc.2.CUX0100001.1.HUMIDITY"; let aussentemp_wert = getState(aussentemp_obj).val; let aussenfeuchte_wert = getState(aussenfeuchte_obj).val; let aussentemp_string = String(aussentemp_wert); let aussenfeuchte_string = String(aussenfeuchte_wert); let aussentemp = aussentemp_string.replace(".",","); let aussenfeuchte = aussenfeuchte_string.replace(".",","); //log ( " Aussen-Temperatur ist " + aussentemp + " Grad" ); sendTo("paw.0",'Tablet_Jörg',{tts: "Es sind " + aussentemp + " Grad draussen bei " + aussenfeuchte + " Prozent Luftfeuchtigkeit" }); } else if(state == "innen" || state == "wohnzimmer") { let innentemp_obj = "sonoff.0.Kodi-Stecker.AM2301_Temperature"; let innentemp_wert = getState(innentemp_obj).val; let innentemp_string = String(innentemp_wert); let innentemp = innentemp_string.replace(".",","); //log ( " Innen-Temperatur ist " + innentemp + " Grad" ); sendTo("paw.0",'Tablet_Jörg',{tts: "Es sind " + innentemp + " Grad im Wohnzimmer" }); } else if(state == "keller") { let kellertemp_obj = "hm-rpc.2.CUX0100008.1.TEMPERATURE"; let kellertemp_wert = getState(kellertemp_obj).val; let kellertemp_string = String(kellertemp_wert); let kellertemp = kellertemp_string.replace(".",","); //log ( " Keller-Temperatur ist " + kellertemp + " Grad" ); sendTo("paw.0",'Tablet_Jörg',{tts: "Es sind " + kellertemp + " Grad im Keller" }); } else if(state == "schlafzimmer") { let schlafzimmer_obj = "javascript.0.DHT22.Schlafzimmer.Temp"; let schlafzimmer_wert = getState(schlafzimmer_obj).val; let schlafzimmer_string = String(schlafzimmer_wert); let schlafzimmer = schlafzimmer_string.replace(".",","); //log ( " Schlafzimmer-Temperatur ist " + schlafzimmer + " Grad" ); sendTo("paw.0",'Tablet_Jörg',{tts: "Es sind " + schlafzimmer + " Grad im Schlafzimmer" }); } else if(state == "badewasser") { let badewasser_obj = "javascript.0.SolarParser.Daten5"; let badewasser_wert = getState(badewasser_obj).val; let badewasser_string = String(badewasser_wert); let badewassertemp = badewasser_string.replace(".",","); //log ( " Badewasser-Temperatur ist " + badewassertemp + " Grad" ); sendTo("paw.0",'Tablet_Jörg',{tts: "Das Badewasser hat " + badewassertemp + " Grad" }); } }); //______________________________________________
Hinweis:
Für die Sprachausgabe muß ich die Zahlenwerte in Strings konvertieren.Meine Temperaturwerte werden von verschiedenen Senoren geliefert:
Aussentemp/-feuchte über CUX von meiner 433 MHz Wetterstation.
(falls es interessiert, meine Wetterdaten gibt's auch online zu sehen: joergeli.de )
Innentemp über einen Sonoff Basic mit zusätzlichem DHT22/AM2301-Senor
Die restlichen Temperaturen über NodeMCUs, die mit Sketchen für DHT22 geflashed wurden. -
@Tom10web said in Rhasspy Offline Sprachsteuerung:
Welchen Vorteil haben die Slots, geht doch auch ohne, oder sind die für die LED Ansteuerung, (welche ich als letztes in Angriff nehme).
Hallo, das beantworte ich gerne. Zunächst: Alles, was funktioniert, ist natürlich machbar. Alles, was immer zuverlässig funktioniert, ist besser. Du wirst selbst rasch feststellen, dass die Anzahl deiner Sentences und auch deren Komplexität rasch zunehmen.
Bei mir kam es anfangs zu häufigen Fehlschaltungen, weil ich in den Sentences immer wieder Definitionen vorgenommen und Begriffe/Namen verwendet habe, die ich in einem anderen Sentence bereits definiert hatte. Das war nicht nur fehleranfällig, sondern wurde auch immer unübersichtlicher. Daher habe ich mich dazu entschlossen, alles, was ich in mehreren Sentences wiederverwenden kann, in den Slots zu hinterlegen.
Die Slots sind also sozusagen der Baukasten, mit dem man die Sentences aufbauen kann.
Neben der besseren Übersichtlichkeit ist auch die einfachere Pflege dieser Daten ein großer Vorteil. Beispiel: Stell dir vor, du möchtest ein weiteres Kommando für einen Schaltzustand hinzufügen, also zB zusätzlich zu "AUS" auch noch "WEG". Dann müsstest du in deinem Vorgehen jeden einzelnen Sentence ändern. Bei einer sauberen Trennung Sentences/Slots hingegen bräuchtest du nur ein einer Stelle in den Slots das neue Kommando mit aufzunehmen.
Fazit: Zuverlässige Funktion, Übersichtlichkeit und leichtere Pflege sind für mich die entscheidenden Vorteile, eine saubre Struktur bei den Slots zu verwenden.
@Tom10web said in Rhasspy Offline Sprachsteuerung:
Danke für das Angebot mit VIS, aber ich bleibe beim Habpanel,
Gerne und kein Problem. Aus welcher Oberfläche die Daten für mein Skript zur Steuerung der Rollos kommen, müsste eigentlich gleichgültig sein. Ich persönlich denke, dass es in einem Smart Home System mehr Sinn ergibt, die Rollos zeit- und eventgesteuert zu bedienen, als vor einer Bedienoberfläche zu sitzen, den Knopf "Runterfahren" zu drücken, um dann im richtigen Moment "Stop" auszulösen, wenn zB die gewünschte Beschattung erreicht wurde - zumal für ein Rollo in einem Zimmer, in das man keinen Einblick hat. Man kann natürlich auch mit dem Tablet in das Zimmer im zweiten Stock gehen, um das Rollo zu beobachten ;-))
Beste Grüße
Thomas -
Hallo Jörg,
WakeWord: Danke für den Tipp zum Testen. Das schaue ich mir nochmals an, in der Hoffnung, dass man den Test dann auch mit dem Browsermikrofon durchführen kann. Ansonsten kann ich ja immer noch auf das von dir gefundene Skript zurückgreifen. Gute Arbeit!
@joergeli said in Rhasspy Offline Sprachsteuerung:
Wenn ein Text z.B. via MQTT von ioBroker zum Rhasspy gesendet wird, muß ja eine WAV-Datei daraus erstellt werden.
Interessante Überlegung. Das führt mich zu der Frage, ob die wavs wirklich dynamisch erzeugt werden müssen, oder ob man dies gesamte, anzusagende Sequenz nicht aus verschiedenen wav-Dateien zusammenstückeln kann/muss, so dass das dynamische Generieren auf ein Minimum beschränkt werden kann, also zB "die Temperatur" (festes wav1) "im Wohnzimmer beträgt" (festes wav2) "neunundneunzig" (dynamisches wav3) "Grad" (festes wav4).
Das ist für mich nur so eine Überlegung, die ich im Auge behalten werde. Ich denke mir, dass dies auch ein zeitlicher Aspekt sein könnte. Je mehr neu generiert werden muss, um so länger dauert auch bis zur Ansage. Wir werden sehen...
Akustische Rückmeldung: Ich warte noch auf mein Kabel, welches erst Anfang März geliefert werden soll. Von daher hatte ich meine kleinen Lautsprecher noch nie in Betrieb. Momentan habe ich nur einen Ohrhörersatz vom iPhone angeschlossen. In deinem Fall einen kleinen Verstärker zu verwenden, ist sicher sinnvoll. Jetzt brauchst du natürlich wieder ein neues Gehäuse...
3D-Drucker: Wie gesagt: Ich habe bei dem gesamten Thema noch gar keine Erfahrung. Ich habe lediglich einige BIlder von selbst erstellten Druckexemplaren (zB bei Thingiverse) gesehen, deren Oberflächen absolut glatt erscheinen. Kann natürlich auch sein, dass hier manipuliert wurde...
Beste Grüße
Thomas -
Hallo Thomas,
@tobetobe sagte in Rhasspy Offline Sprachsteuerung:WakeWord: Danke für den Tipp zum Testen. Das schaue ich mir nochmals an, in der Hoffnung, dass man den Test dann auch mit dem Browsermikrofon durchführen kann. Ansonsten kann ich ja immer noch auf das von dir gefundene Skript zurückgreifen
Mit dem Browsermikrofon hatte ich es ja vorher erfolgreich direkt online durchgeführt.
In den Tipps der Rhasspy-Community liest man aber, daß es wohl besser wäre, das mit dem Mikrofon durchzuführen, welches final auch verwendet wird. Deshalb meine Klimmzüge mit dem Rhasspy-Mikrofon.
Hat dann bis dato auch rel. gut am finalen Standort des Rhasspy funktioniert.aaaber: Langsam treibt mich das Wakeword in den Wahnsinn.
Gestern kommt Frau nach Hause und sagt ein paar belanglose Sätze (ohne WakeWord), was zur Folge hat, daß wieder andauernd Fehlauslösungen kommen.
Ich habe jetzt, wie hier erwähnt, zusätzlich mit dem Gain (Verstärkungsfaktor) des Mikros experimentiert. Mein Profil diesbzgl. sieht jetzt so aus:"wake": { "command": { "program": "$RHASSPY_BASE_DIR/bin/mock-commands/sleep.sh" }, "precise": { "model": "okay-rhasspy.pb" }, "snowboy": { "audio_gain": "1.3", "model": "snowboy/liesel.pmdl", "sensitivity": "0.44" }, "system": "snowboy" }
also sensitivity runter gesetzt und audio_gain erhöht.
Das muß ich jetzt mal beobachten.Gruß
Jörg -
@tobetobe
Danke für die genaue Erklärung der Slots, hilft garantiert auch vielen die hier nur mitlesen.
Meine Rolladen sind schon über die Astrofunktion gesteuert(schließen zu 70% und bei TV aus zu 100%) ich möchte nur zusätzlich per Sprachbefehl eingreifen können. Was ja seit Gestern gut funktioniert, dank euch
Schönes Wochenende -
@joergeli said in Rhasspy Offline Sprachsteuerung:
aaaber: Langsam treibt mich das Wakew
Mikrofon: Vielen Dank - Wieder etwas dazugelernt
WakeWord: Nachdem ich mir ja auch schon zwei untaugliche WakeWords generiert hatte, steht mir dieser Wahnsinn wohl auch noch bevor...
Ich hatte mich ja schon mal zu meinen angelesenen Erkenntnissen über gute WakeWords ausgelassen und auch gaaaanz vorsichtig hinterfragt, ob "Lieselotte" den Ansprüchen an ein gutes WakWord wohl wirklich genügt. Ich glaube, es gibt zu viele Ähnlichkeiten in der Phonetik mit üblicher Wortwahl. Daher die Fehler.
Du kannst ja selbst testen, auf was dein Rhasspy so alles reagiert: Fieser/mieser Otto, tiefer Pott, lieber Gott, Liebe? Not! Hiebe Schrott, wieso not, ggf. sogar nur auf "Lotte"...
Bei "Snowboy" sind die Umlaute dominant. Hier funktioniert alles wie Oh Boy, Showboy, Oh oy usw. Nur kommen diese Umlaute nun mal eben im Deutschen nicht vor, sodass auch nicht so viel schief geht. Alle technischen Maßnahmen (Gain und Sensitivity zu optimieren) halte ich für Feinschliff, um das letzte Quäntchen zu optimieren. Ein "schlechtes" WakeWord" wird man damit allerdings nicht heilen können.
Sorry, dass ich das so deutlich auf den Punkt bringe, aber ich bin vom Gesagten wirklich überzeugt, da ich mich in meinem Nachrichtentechnikstudium mit Mustererkennung befasst habe. In aller Bescheidenheit ergänze ich: Die Weisheit mit Löffeln gefressen habe ich natürlich auch nicht!
Bis mir selbst ein "gutes" WakeWord einfällt, arbeite ich halt zunächst mit "Snowboy" weiter, um allem Ärger aus dem Weg zu gehen. Ich persönlich möchte momentan lieber die Gesamtfunktionalität im Auge behalten, die bei mir schon recht gut und zuverlässig ist. Die Sache mit den WakeWords lasse ich nebenher laufen. Vielleicht fällt uns ja gemeinsam ein supertolles 100%-Wort ein...
-
@tobetobe
Hallo Thomas,
es funktioniert nach ersten Tests mit den gain-Einstellungen jetzt schon besser - toi, toi, toi
Selbst auf Frau reagiert es jetzt und der Haussegen hängt wieder halbwegs gerade.
Wird allerdings mit einer geringeren Empfindlichkeit bei größerem Sprechabstand erkauft.Trotzdem wäre es schön, wenn wir ein besseres WakeWord finden, was aber kein Zungenbrecher werden soll.
Ich persönlich mag auch solche WakeWords nicht, die aus 2 Wörtern bestehen ( OK, Rhasspy - Hey, Google, etc.)Nebenbei:
Bei meinem Nachrichtentechnik-Studium (70er Jahre des letzten Jahrtausends) gab's noch keine Mikroprozessoren, da haben wir noch in Fortran auf Lochstreifen programmiertGruß
Jörg -
@joergeli said in Rhasspy Offline Sprachsteuerung:
Nebenbei:
Bei meinem Nachrichtentechnik-Studium (70er Jahre des letzten Jahrtausends) gab's noch keine Mikroprozessoren, da haben wir noch in Fortran auf Lochstreifen programmiertGibt ja gar nicht!!! Da haben wir etwas gemeinsam. Und der Ausdruck kam auf DIN A3 Nadeldruckern heraus. Ich hab dich für vieeel jünger gehalten...
Gruß
Thomas -
@tobetobe sagte in Rhasspy Offline Sprachsteuerung:
Ich hab dich für vieeel jünger gehalten...
nun ja, 62 Lenze, aber im Kopf immer noch ein Spielkind/Elektronik-Bastler geblieben
-
Hi,
ich benötige mal eure Unterstützung, ich habe snips und mehreren Satelliten erfolgreich mit fhem verbunden. Jetzt würde ich gerne dies auch mit iobroaker testen. Da aber seit Februar die snips Console abgeschaltet wurde kann ich mir darüber nicht mehr einen eigenen Assistenten mit der iobroaker app erstellen.Daher die Frage an euch, hat jemand noch eine assistant_proj_...zip Datei (Damals unter deploy assistant als Download) oder kann jemand von seinem funktionierenden System den Order /usr/share/snips/assistant als zip bereitstellen?
MFG BastianH
-
@BastianH
Hallo Bastian,
leider kann ich dir dabei nicht weiterhelfen. Als ich mich im Dez19 bei snips anmelden wollte, war die Plattform schon für Neuzugänge gesperrt. Am besten, du schaust mal im Smcon-Forum oder bei anderen "Gestrandeten" hier: Snips auf ioBroker ForumGrüße
Thomas -
@joergeli
Hi, wieder Wochenende, Zeit zum testen.
Versuche jetzt die LED Ansteuerung, die vorgegebenen Profile als Test funktionieren.
Wenn ich aber die virtuelle Umgebung für Python starte
source /home/pi/env/bin/activate
lande ich hier : (env) pi@raspberrypi:~$
und nicht im Ordner : (env) pi@Rhasspy:~/4mics_hat $
4mics_hat ist vorhanden und die Dateien liegen auch darin.
ich habe aber leider keine Ahnung von Python.
Und natürlich kommt dann diese Fehlermeldung
"pi@raspberrypi:~$ Virtuelle Umgebung gestartet
python: can't open file 'rhasspy_led_ring.py': [Errno 2] No such file or directory" , habe auch schon probiert das script eine Ebene höher (pi)
zu legen, auch keine Lösung, MQTT-Adresse und MQTT-Port sind angepasst, hat aber nichts direkt mit dem Scriptstart zu tun.
Muss "hermesledcontrol" deaktiviert werden, dies startet doch jedes mal wieder mit oder reicht es die LED-Muster zu entfernen?Oder besser doch warten, auf eine neue Version von Rhasspy, in der es implementiert ist ? (ich würde es trotzdem gerne hinbekommen)
-
@Tom10web
Hallo,
"hermesledcontrol" habe ich kpl. deaktiviert ( sudo systemctl stop hermesledcontrol) weil es sonst wohl in Konflikt zu meinem Workaround kommt.Nochmals meine einzelnen Schritte:
1.) Datei rhasspy_led_ring.py im Ordner /home/pi/4mics_hat mit folgendem Inhalt anlegen:import logging import time import paho.mqtt.client as mqtt from gpiozero import LED from pixel_ring import pixel_ring MQTT_IP = '192.168.192.29' MQTT_PORT = 1891 def on_message(client, userdata, message): if 'hermes/nlu/intentNotRecognized' == message.topic: logging.info('intent not recognized') pixel_ring.think() time.sleep(0.5) pixel_ring.off() if 'hermes/asr/textCaptured' == message.topic: logging.info('text recognized') pixel_ring.speak() time.sleep(2.5) pixel_ring.off() if 'rhasspy/de/transition/SnowboyWakeListener' == message.topic: if 'loaded' == str(message.payload.decode("utf-8")): logging.info('### Snowboy-Wake-Listener: listen') pixel_ring.listen() time.sleep(0.5) pixel_ring.off() if 'rhasspy/de/transition/WebrtcvadCommandListener' == message.topic: if 'loaded' == str(message.payload.decode("utf-8")): logging.info('### WebCard: listen') pixel_ring.think() time.sleep(1.5) pixel_ring.off() if 'rhasspy/speech-to-text/transcription' == message.topic: if 'loaded' != str(message.payload.decode("utf-8")): logging.info('### Text: listen') pixel_ring.speak() time.sleep(2.5) pixel_ring.off() if message.topic.startswith('hermes/intent/'): logging.info('intent ' + message.topic.rpartition('/')[-1]) # if 'rhasspy/de/transition/MaryTTSSentenceSpeaker' == message.topic: # state = str(message.payload.decode("utf-8")) # if 'speaking' == state: # logging.info('speaking') # pixel_ring.speak() # elif 'ready' == state: # logging.info('speaking done') # pixel_ring.off() if __name__ == '__main__': # logging.basicConfig(filename='test.log', level=logging.INFO) power = LED(5) power.on() pixel_ring.set_brightness(10) pixel_ring.change_pattern('echo') client = mqtt.Client('Rhasspy') client.connect(MQTT_IP, port=MQTT_PORT) client.on_message = on_message client.loop_start() client.subscribe('hermes/nlu/intentNotRecognized') client.subscribe('hermes/asr/textCaptured') client.subscribe('rhasspy/de/transition/SnowboyWakeListener') client.subscribe('rhasspy/de/transition/WebrtcvadCommandListener') client.subscribe('rhasspy/speech-to-text/transcription') client.subscribe('hermes/intent/#') client.subscribe('rhasspy/de/transition/MaryTTSSentenceSpeaker') logging.info('starting pixels') while True: try: time.sleep(3) except KeyboardInterrupt: client.loop_stop() break pixel_ring.off() power.off() time.sleep(1)
Im Script musst Du MQTT_IP und MQTT_PORT natürlich auf Deine eigenen Gegebenheiten anpassen
Dieses Python-Script reagiert auf die entspr. Rhasspy-Topics ( Befehl not recognized, Text recognized, Wakeword erkannt, etc.) und steuert dann den 4 Mics-Hat LED-Ring mit verschiedenen Mustern an.
2.)
Damit das Ganze automatisch, d.h. nach dem Booten funktioniert, habe ich folgende Zeile am Ende der Datei /home/pi/.profile ( sudo nano /home/pi/.profile) angehängt:(cd /home/pi/4mics_hat; echo "4Mic:Hat"; source /home/pi/env/bin/activate; echo "Virtuelle Umgebung gestartet"; python rhasspy_led_ring.py)&
Wichtig ist das & am Ende der Zeile!
Nach einem Reboot des Raspi sollte dann der LED-Ring bei Rhasspy-Sprachkommandos reagieren.
Das läuft bei mir soweit, ich werde diesbzgl. aber erst weitermachen, wenn Rhasspy 2.5 verfügbar ist.Gruß
Jörg -
@joergeli said in Rhasspy Offline Sprachsteuerung:
Nochmals meine einzelnen Schritte:
Hallo Jörg,
ich habe dein Skript noch immer nicht zum Laufen bekommen ;-((
Allerdings habe ich auf GitHub passend zu meinem Matrix Voice ein Skript zur Ansteuerung der LEDs über Rhasspy, also über Sprachkommando gefunden, welches auch funktioniert. Meine ersten Versuche, Code-Schnipsel aus deinem Skript bei mir einzubauen, waren erfolglos. Sos sieht das von mir verwendete Skript aus:Wie du siehst, findet mit diesem Skript auch eine Sprachausgabe auf dem Rhasspy statt. In diesem Zusammenhang habe ich mit den Settings gespielt, weil mir die Ausgabe mit eSpeak überhaupt nicht gefiel. In den Settings habe ich daher auf PicoTTS umgestellt und unter "Advanced" das Profil folgendermaßen ergänzt:
"text_to_speech": { "system": "picotts", "picotts": { "language": "de-DE" } }
Die Aussprache finde ich, ist völlig akzentfrei und die Stimme sehr angenehm.
Ich dachte, das könnte dich ggf auch interessieren.
Bis zum nächsten Mal
Thomas -
@tobetobe
Hallo Thomas,
wie gesagt, ich hatte ja geschrieben, daß ich nicht weiß, ob das Script mit Deinem Matrix-Voice funktioniert, weil da einige Sachen drin sind, die wohl speziell nur für das Respeaker Mic-Array zutreffen.Sprachausgabe direkt auf dem Rhasspy interessiert mich natürlich, muss aber erst noch meinen Mini-NF-Verstärker mit dem Rhasspy verbinden.
Ich nehme an, das "Herzstück" in Deinem Script ist die Zeile url = "http://localhost:12101/api/text-to-speech", wo die API angezapft wird?Kannst Du mal ein paar Beispiel-Sprachausgaben posten, weil ich mir momentan unter "say("Matrix ist jetzt: " + data["slots"]["color"])" nichts rechtes vorstellen kann.
Wird da sowas wie "Matrix ist jetzt Wohnzimmerlampe grün" gesprochen?Gruß
Jörg -
Hallo Jörg,
zunächst mal sorry, dass der Text im Spoiler so schlecht formatiert ist. Das ist mir beim Hineinkopieren gar nicht aufgefallen. Das ist von der ersten bis zur letzten Zeile im Spoiler der komplette Skript-Inhalt. Für die Sprachausgabe sind wahrscheinlich alle Zeilen mit der url "localhost" sowie mit dem Kommando "say" relevant. In der Sentences.ini steht bei mir:
[Led] ($synonyms_change_command) [(die | das | den)] device [auf] (red | green | blue | purple | yellow | black){color}
wobei "$synonyms_change_command" bei mir nur auf den Slot mit den Kommandos (Setze, stelle, mache, etc) verweist. Ansonsten gibt es in den Slots keine weiteren Informationen. Ich muss also per Sprachbefehl lediglich "Setze das Device auf green" eingeben. (Bei den Farben habe ich es der Einfachheit halber erst einmal bei den englischen Begriffen belassen).
So wie es für mich aussieht, müsste es für dein Mikrofon doch möglich sein, nicht nur die LEDs anzusteuern, sondern auch eine Sprachansage vorzunehmen. Wenn man das irgendwie hinbekommt, wäre das für mich der nächste Schritt, um auch Ansagen über Datum, Zeit, Wetter etc am Rhasspy ausgeben zu können. Die halte ich persönlich für interessanter, als eine zur LED-Anzeige redundante Statusinformation per Sprachausgabe.
Mich interessiert deine Meinung. Siehst du das auch so?
Gruß Thomas
-
@tobetobe
Hallo Thomas,
ja klar, "aussagekräftige" Sprachausgaben sind natürlich wünschenswert.
Die sind aber m.E. nur auf dem Rhasspy allein nicht realisierbar ( zumindest wenn man sich -wie ich- mit Python nicht auskennt).
Somit müssen sie an anderer Stelle, sprich: mit ioBroker erzeugt werden.Wie Du weißt, reagiere "ich" ja schon jetzt auf Rhasspy-Intents per JavaScript.
vereinfachtes Beispiel:
Frage an Rhasspy: Hat es heute geregnet?
-> Rhasspy sendet Intent mit Inhalt "geregnet" an ioBroker.
-> JavaScript reagiert auf "geregnet".
-> JavaScript generiert Antwort aus den vorhandenen Datenpunkten:
Regenmenge = 0 -> Antwort:"Nein, bisher war es trocken"
Regenmenge = 0 und Regendauer > 0 -> Antwort: "Ja, aber es gab nur geringen Niederschlag."
Regenmenge > 0 -> Antwort: "Ja, es hat heute xx Liter pro Quadratmeter geregnet."
-> entspr. Antwort wird mittels PAW-Adapter an Tablet gesendet und dort per Sprache ausgegeben.Wenn es - wie in Deinem Python-Script beschrieben - ausreicht, diese Antwort an die API von Rhasspy zu senden, dann sollte es mit say(antwort) möglich sein, die Antwort auf den Rhasspy-Lautsprecher(n) auszugeben.
Im Prinzip stelle ich mir das so vor:
-> Intent von Rhasspy wird in ioBroker empfangen.
-> ioBroker generiert per JavaScript die entspr. Antwort.
.> ioBroker schreibt die Antwort in einen eigenen Datenpunkt.
-> bei jeder Änderung dieses Datenpunktes wird der Inhalt des Datenpunktes ( = Antworttext) an Rhasspy gesendet.
-> Rhasspy reagiert mittels Python-Script auf diese Antwort und erzeugt mittels TexttoSpeech-engine die akustische Ausgabe.
Somit sollte es möglich sein, je nach Intent, beliebige Sprachausgaben auf dem Rhasspy zu erzeugen.
Der Nachteil dabei ist, daß man alle zutreffenden Antworten mittels JavaScript manuell erzeugen, d.h. selbst proggen muß.Ich werde am Wochenende mal probieren, ob mir das gelingt, momentan habe ich von der "Regierung" andere Prioritäten gesetzt bekommen
-
@joergeli said in Rhasspy Offline Sprachsteuerung:
( zumindest wenn man sich -wie ich- mit Python nicht auskennt).
das ist leider auch mein Problem
@joergeli said in Rhasspy Offline Sprachsteuerung:
Wenn es - wie in Deinem Python-Script beschrieben - ausreicht, diese Antwort an die API von Rhasspy zu senden, dann sollte es mit say(antwort) möglich sein, die Antwort auf den Rhasspy-Lautsprecher(n) auszugeben.
genau das wäre zu verifizieren, denn es wäre ja unabhängig vom verwendten Mikrofon@joergeli said in Rhasspy Offline Sprachsteuerung:
Im Prinzip stelle ich mir das so vor:
Dieser Überlegung zu einem Vorgehen würde ich mich zu 10% anschließen
@joergeli said in Rhasspy Offline Sprachsteuerung:
momentan habe ich von der "Regierung" andere Prioritäten gesetzt bekommen
ich schätze deine Meinung, möchte dich jedoch keinesfalls zu irgendetwas drängen. Auch habe ich überhaupt keine "Forderungen". Insofern fühl dich bitte vollkommen frei, so zu verfahren, wie du möchtest.
-
@tobetobe sagte in Rhasspy Offline Sprachsteuerung:
Dieser Überlegung zu einem Vorgehen würde ich mich zu 10% anschließen
... und bei den restlichen 90% hast Du Bedenken?
@tobetobe sagte in Rhasspy Offline Sprachsteuerung:
ich schätze deine Meinung, möchte dich jedoch keinesfalls zu irgendetwas drängen. Auch habe ich überhaupt keine "Forderungen". Insofern fühl dich bitte vollkommen frei, so zu verfahren, wie du möchtest.
Habe ich auch nicht so aufgefasst, mich juckt es ja selbst in den Fingern das zu testen
-
@joergeli said in Rhasspy Offline Sprachsteuerung:
... und bei den restlichen 90% hast Du Bedenken?
Erwischt!!! Ein Tipfehler...
Ich habe mich heute auch noch einmal intensiv mit dem Thema beschäftigt. Zunächst gibt es einen ganz einfachen Weg, Sprachausgaben auf dem Rhasspy mit dem jeweils aktivierten TTS-Modul (bei mir PicoTTS) zu testen. Hierzu in der Rhasspy-Oberfläche einfach auf das Feld mit der Versionsnummer klicken. Man erhält dann direkten Zugang zur API. Weiter unten gibt es dann die Möglichkeit, einen eigenen Text an den Rhasspy zu schicken, der dann über die Lautsprecherbuchse ausgegeben wird. Alternativ kann man die Seite auch durch Aufruf im Browser finden:
http://<IP>:12101/api/#/default/post_api_text_to_speech
Die Beschreibung zur API hier:
https://rhasspy.readthedocs.io/en/latest/reference/#http-api
Nun habe ich versucht, mithilfe vorhandener Skripts, Befehle an diese API-Schnittstelle zu senden. Zum Einen mit dem Befehl "send", zum Anderen mit "request" bzw. XMLHttpRequest. Für Letzteres mus "xmlhttprequest" als zusätzliches Modul im JS-Adapter eingetragen sein.
Hier meine beiden Skripte:
- Mit send:
// Skript zur Abfrage von Temperaturen var intentResult = $('mqtt.0.rhasspy.intent.*Temperature'); var intentArray = []; var url = "http://<IP>:12101/api/text-to-speech?repeat=false&play=true"; var method = "POST"; var shouldBeAsync = true; for(var i = 0; i < intentResult.length; i++) { log(intentResult[i]); intentArray.push(intentResult[i]); } on({id: intentArray, change: "any"}, function (obj) { // log(obj.newState.val); let intentObject = JSON.parse(obj.newState.val); if(intentObject.hasOwnProperty('device')) { var deviceID = intentObject.device; var state = intentObject.state; var value = getState(deviceID + state); var postData = value.val; log(value.val); sendTo('http://<IP>:12101/api/text-to-speech?repeat=false&play=true', 'send', 'value.val + "Grad Celsius"'); } });
Dieses gibt im Log die Temperatur richtig aus, sendet die Daten jedoch nicht an Rhasspy.
Bei dem Skript mit "request" bekomme ich schon Fehlermeldungen zu Zeile 8. Offensichtlich wird xmlhttprequest trotz im JS-Adapter installiertem Zusatzmodul nicht erkannt.
//Skript zur Abfrage von Temperaturen var intentResult = $('mqtt.0.rhasspy.intent.*Temperature'); var intentArray = []; var url = "http://192.168.13.157:12101/api/text-to-speech"; var method = "POST"; var shouldBeAsync = true; var request = new XMLHttpRequest(); for(var i = 0; i < intentResult.length; i++) { log(intentResult[i]); intentArray.push(intentResult[i]); } on({id: intentArray, change: "any"}, function (obj) { log(obj.newState.val); let intentObject = JSON.parse(obj.newState.val); if(intentObject.hasOwnProperty('device')) { var deviceID = intentObject.device; var state = intentObject.state; var value = getState(deviceID + state); var postData = value.val; request.open(method, url, shouldBeAsync); request.setRequestHeader("Content-Type", "text/plain;charset=UTF-8"); request.push(postData); // ggf. letzten Befehl alternativ mit .send statt mit .push log(postData); } });
Die dritte Möglichkeit wäre über jQuery, mit der ich mich jedoch noch nicht befasst habe. Hier mal ein Code-Fetzen:
/* jQuery.ajax({ method: "POST", url: "save.php", data: { image: canvasToDataURLString } }); */
Dies soweit nur zu deiner Info. Ich wende mich mal an andere Forenmitglieder, die sich schon mit ähnlichen Aufgabenstellungen befasst haben.
Gruß
Thomas