Modulentwicklung für Rhasspy Sprachassistent

Begonnen von drhirn, 11 März 2021, 15:59:50

Vorheriges Thema - Nächstes Thema

Prof. Dr. Peter Henning

Eine der wichtigsten Sachen bei Benutzungsoberflächen (auch sprachbasierten) ist die Modellbildung. Der Benutzer oder die Benutzerin müssen immer wissen, warum etwas geschieht. Wenn also ein System eine zufällige Handlung ausführt, muss also eine Erklärung geliefert werden: "Ich nehme an, Du meinst das Gerät X" - das "warum" ist hier also eine Annahme des Systems.

LG

pah

Beta-User

Im Nebenthread ist eine Aktualisierung zu finden, die zumindest das "mach etwas lauter" nachvollziehbarer handhaben müßte.

Bisher wurde so eine Anweisung über "getActiveDeviceForIntentAndType()" geschleust, die einfach der erste "angeschaltete" Element aus den Listen "inside room" bzw. "outside  room" geliefert hatte - dabei war wirklich ein "for keys" vorgeschaltet, also ein gewisses Zufallselement integriert.

Jetzt kann man getDeviceByIntentAndType() gleich so aufrufen, dass nur angeschaltete Devices kommen, was für "SetNumeric" keine weiteren Probleme aufwirft, da das sowieso damit umgehen kann, dass ggf. mehrere Devices geliefert werden und dann nachgefragt werden muss.

Die "getActive"-Anfrage gab es dann noch in handleIntentMediaControls(), da ist das jetzt ebenfalls umgestellt (aber noch nicht getestet).

(Irgendwie hatte es mich schon gewundert, dass da noch keiner drübergestolpert gewesen war)...

Durch die Umstellung kann es allerdings auch ansonsten zu einem geänderten Verhalten kommen, da die "prio"-Vorgaben jetzt auch berücksichtigt werden müßten. Nach meinem Verständnis ist das aber in jeden Fall eine Verbesserung... (also z.B.: Wenn Verstärker und Fernseher an ist, verweist "prio" immer auf den Verstärker). (Kann aber sein, dass man eine eigene Priorisierung für den "an"-Fall vorsehen sollte?)

Zitat von: Prof. Dr. Peter Henning am 29 Mai 2022, 10:06:38
Wenn also ein System eine zufällige Handlung ausführt, muss also eine Erklärung geliefert werden: "Ich nehme an, Du meinst das Gerät X" - das "warum" ist hier also eine Annahme des Systems.
Na ja, eigentlich sollte man mAn. komplett zufällige Verhaltensweisen gar nicht erst "einplanen", von daher ist/war das hier nach meinem Verständnis gar nicht der "warum"-Fall. Sowas könnte aber eine Rolle spielen, wenn man Wahrscheinlichkeiten (oder schlechte "confidence"-Werte) berücksichtigt.
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: MiLight@ESP-GW, BT@OpenMQTTGw | MySensors: seriell, v.a. 2.3.1@RS485 | ZWave | ZigBee@deCONZ | SIGNALduino | MapleCUN | RHASSPY
svn: u.a MySensors, Weekday-&RandomTimer, Twilight,  div. attrTemplate-files

drhirn

Zitat von: Beta-User am 30 Mai 2022, 14:05:37
Durch die Umstellung kann es allerdings auch ansonsten zu einem geänderten Verhalten kommen, da die "prio"-Vorgaben jetzt auch berücksichtigt werden müßten. Nach meinem Verständnis ist das aber in jeden Fall eine Verbesserung... (also z.B.: Wenn Verstärker und Fernseher an ist, verweist "prio" immer auf den Verstärker). (Kann aber sein, dass man eine eigene Priorisierung für den "an"-Fall vorsehen sollte?)

Wie setz ich die nochmal?

Beta-User

Lt. commandref:
attr sensor_outside_main rhasspySpecials priority:inRoom=temperature outsideRoom=temperature,humidity,pressureMein Verstärker (teils zum Testen):
attr Yamaha_Main rhasspySpecials scenes:scene1="Musik hören" scene2="Film ansehen" scene3=none scene4="vorderen Eingang auswählen"\
priority: inRoom=volume outsideRoom=volume,scene\
confirm: SetOnOff="wirklich $target $Value schalten?" SetScene


Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: MiLight@ESP-GW, BT@OpenMQTTGw | MySensors: seriell, v.a. 2.3.1@RS485 | ZWave | ZigBee@deCONZ | SIGNALduino | MapleCUN | RHASSPY
svn: u.a MySensors, Weekday-&RandomTimer, Twilight,  div. attrTemplate-files

drhirn

Ah ja, hatte ich mir am Wochenende eh schon mal angesehen. Ich verstehe aber leider die Bedeutung von "inRoom" und "outsideRoom" nicht so richtig. Kannst du mir das bitte schnell erklären? Danke!

Beta-User

Hmm, kann's ja mal versuchen:
"inRoom" gibt die Priorisierung vor, wenn es mehrere Geräte im Raum (={Room} bzw. aus siteId abgeleitet) gibt, die passen können.
"outsideRoom" kommt erst dann zum Tragen, wenn es kein passendes Gerät im Raum gibt und "irgendwo" gesucht werden muss, ob irgendwas passendes gefunden wird.

In meinem Beispiel - es gibt hier noch einen Verstärker, der ist aber im Esszimmer (der andere im Wohnzimmer):
attr Yamaha_Zone2 rhasspySpecials priority:inRoom=volume
Wenn du also "mach lauter" sagst, wird immer einer dieser beiden angesprochen werden (wenn angeschaltet), obwohl es mind. noch ein weiteres Gerät in diesen beiden Räumen gibt, das auch "volume"-Kommandos versteht (und RHASSPY bekannt ist, ein MPD-Device).
Im/für das Esszimmer gesprochen wirkt der Befehl eben auf "zone2", sonst auf den "main".
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: MiLight@ESP-GW, BT@OpenMQTTGw | MySensors: seriell, v.a. 2.3.1@RS485 | ZWave | ZigBee@deCONZ | SIGNALduino | MapleCUN | RHASSPY
svn: u.a MySensors, Weekday-&RandomTimer, Twilight,  div. attrTemplate-files

drhirn

Danke!
Mich verwirrt, dass du in den Beispielen bei outsideRoom immer mehrere Einträge hast. In der CRef auch. Wenn ich die Lautstärke schalten will, sind mir doch Szenen egal. Und wenn ich die Temperatur wissen will (CRef), muss ich Luftfeuchtigkeit und Luftdruck doch nicht wissen!?
Oder ist das so zu verstehen, dass du 5 Räume hast, in denen jeweils Thermometer hängen. Im sechsten ist keiner. Wenn du aber in Raum 6 nach der Luftfeuchtigkeit fragst, willst du immer den Wert aus Raum 1 haben?

Beta-User

Na ja, wie geschrieben: Teils sind meine eigenen Beispiele auch so, weil ich das zum Testen brauch(t)e ::) ...
Tatsächlich sind in praktisch allen Räumen Thermometer vorhanden, das ist eher ein Rest aus dem "outsideRoom"-Test. Nicht überall vorhanden sind aber z.B.  Luftdruck-Sensoren. Wenn ich aber den Luftdruck wissen will, dann eigentlich immer den von draußen.

Die Kritik an den "Szenen" (oder allgemein: den Mehrfach-Angaben) kann ich nicht ganz nachvollziehen, prinzipiell geht es (auch) darum zu zeigen, dass man nicht darauf beschränkt ist, ein einziges "Schlüsselwort" für diese Priorisierungen anzugeben. Und für die Frage, wie man es denn "gut" macht mit all den vielen Optionen gibt es sogar einen ganzen Thread ;D ... (Da ist es nur ziemlich ruhig ??? ).
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: MiLight@ESP-GW, BT@OpenMQTTGw | MySensors: seriell, v.a. 2.3.1@RS485 | ZWave | ZigBee@deCONZ | SIGNALduino | MapleCUN | RHASSPY
svn: u.a MySensors, Weekday-&RandomTimer, Twilight,  div. attrTemplate-files

drhirn

Das war keine Kritik. Find's grundsätzlich sogar gut. Sieht man gleich, dass mehrere Optionen möglich sind. Ich hab's nur einfach nicht verstanden ;)

Beta-User

...ist ja auch nicht unbedingt selbsterklärend, das alles...
"outsideRoom" kommt bei mir auch eher selten vor, "inRoom" aber schon. Hier vielleicht noch zwei+ Beispiele betr. die Temperatur-Regelung:

Esszimmer - es gibt einen Raumthermostat, über den läuft alles - Abfragen und "set"-Anweisungen. Es gibt noch viel mehr Thermometer (bzw. "desired-temp"-Geräte)...

Thermostat_EssZi_Climate     priority:inRoom=desired-temp,temperature,humidity


Wohnzimmer: Kein Raumthermostat, die Homematic-RT-DN bekommen eine virtuelle Temperatur (vom "Raumfuehler) und arbeiten im Team => man muss nur einen ändern, dann bekommt der andere das irgendwann auch mit...
Raumfuehler_Wohnzimmer     priority:inRoom=temperature
Thermostat_Wohnzimmer_SSO_Clima     priority:inRoom=desired-temp
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: MiLight@ESP-GW, BT@OpenMQTTGw | MySensors: seriell, v.a. 2.3.1@RS485 | ZWave | ZigBee@deCONZ | SIGNALduino | MapleCUN | RHASSPY
svn: u.a MySensors, Weekday-&RandomTimer, Twilight,  div. attrTemplate-files

Beta-User

Zitat von: Prof. Dr. Peter Henning am 28 Mai 2022, 19:59:09Beispiel:


----> Starting dialog
[Babble_DoIt] Input:  bitte spiele musik
              Ergebnis: Category=1.3.0: Gerät=musik Ort=none Verb=spielen Ziel=none /
              Antwort:  {speak('Tab2.EG','Das mache ich gerne, bitte sage mir wo Du gerade bist')}
---->
[Babble_DoIt] Input:  ich bin im wohnzimmer
              Ergebnis: Category=3.4.7: Gerät=ich Ort=wohnzimmer Verb=none Ziel=none /
              Antwort:  {speak('Tab2.EG','Von wem soll ich im wohnzimmer Musik spielen? ')}
---->
[Babble_DoIt] Input:  von den pogues
              Ergebnis: Category=3.2.5: Gerät=pogues Ort=none Verb=none Ziel=den /
              Antwort:  {speak('Tab2.EG','OK, ich werde im wohnzimmer die spezielle Musik pogues von   spielen ')}
----> Ending dialog

...nicht dass du denkst, ich hätte die Herausforderung übersehen ::) ...

Sollen wir zu diesem Intent(kreis) einen separaten Thread starten?

Da wirbeln bei mir im Moment ziemlich viele unfertige Gedanken durcheinander, angefangen von der Frage, ob es sinnvoll ist, meine Sammlung zu "versloten" (https://community.rhasspy.org/t/whats-the-craziest-thing-you-can-or-cannot-do-with-rhasspy/3648/24; ich habe da arge Bedenken, dass das nicht ein heilloses Chaos hingäbe, schon alleine wegen der Interpreten/Alben-Namen in den diversen Sprachen, die man halt so in einer normalen Sammlung hat), oder ob man nicht besser/auch einen "allgemeinen Buchstabier-Choice-Auswerte-Code" bereitstellen sollte bis hin zu der spaßigen Frage, wie man das am besten umsetzt, wenn nicht zwangsläufig in jedem Raum dieselbe Ausgabe-Methode anwendbar ist....

Von daher würden mich Details zu der von dir gezeigten Lösung sehr interessieren!
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: MiLight@ESP-GW, BT@OpenMQTTGw | MySensors: seriell, v.a. 2.3.1@RS485 | ZWave | ZigBee@deCONZ | SIGNALduino | MapleCUN | RHASSPY
svn: u.a MySensors, Weekday-&RandomTimer, Twilight,  div. attrTemplate-files

Beta-User

Wollte euch mal kurz an meinen Versuchen zur Vorbereitung für einen eventuellen "allgemeinen Buchstabier-Choice-Auswerte-Code" teilhaben lassen...

Man nehme:

- einen neuen slot, der diverse Buchstabiertafeln enthält (siehe Anhang):
( a | Alfa | Anton | Albert | Augsburg | Aachen ):a
( ä | Alfa-Echo | Ärger | Änderung | Umlaut-A | Umlaut Aachen ):ä
( be | Bravo | Berta | Bruno | Bernhard | Berlin ):b
( ze | Charlie | Cäsar | Cottbus ):c
( zeha | Charlie-Hotel | Charlotte | Chemnitz [Hamburg]):ch
( de | Delta | Dora | David | Düsseldorf ):d
( e | Echo | Emil | Essen ):e
( äf | Foxtrot | Friedrich | Fritz | Frankfurt ):f


- eine "kleine" Ergänzung in "Choice":
[de.fhem:Choice]
choose= ( nimm [bitte] | [bitte] nimm | ich hätte gerne | [ich] (wähle|nehme) )
letter= ($de.letters | (0..9) | ( leerzeichen | platz |  nächstes wort ):space | ( bindestrich | strich |  minus ):- | ( Apostroph):' )

<choose> [( den (Song | Titel ){Type:title} | das Album{Type:album} | die Platte{Type:album} | den ( Interpreten | Sänger ){Type:artist} | die ( Band | Gruppe ){Type:artist} )] <letter>{L1} <letter>{L2} [<letter>{L3} [<letter>{L4} [<letter>{L5} [<letter>{L6} [<letter>{L7} [<letter>{L8} [<letter>{L9} [<letter>{L10} [<letter>{L11} [<letter>{L12} [<letter>{L13} [<letter>{L14} [<letter>{L15} ]]]]]]]]]]]]] [und] <letter>{Llast}


Dann lasse man Rhasspy in Ruhe trainieren (öhm, mein Server kam da an seine Grenzen...), und schon kann man sich sauberen Buchstabensalat liefern lassen, denn man ohne weitere auch wieder zusammenkleben könnte...

Beispiel (zur Demo mit explizitem Leerzeichen):
Zitatich hätte gerne die band berlin ludwig ida nürnberg Köln strich eins acht zwei platz
{"L1":"b","L2":"l","L3":"i","L4":"n","L5":"k","L6":"-","L7":1,"L8":8,"L9":2,"Llast":"space","Type":"artist","confidence":1,"customData":null,"input":"ich hätte gerne die artist b l i n k - 1 8 2 space","intent":"Choice","lang":"de","rawInput":"ich hätte gerne die band berlin ludwig ida nürnberg Köln strich eins acht zwei platz","requestType":"voice","sessionId":"defhem_0_testmode","siteId":"defhem"}

So weit so gut...
Das ganze zerstört nur leider den bisher fluffigen Performance-Eindruck, die Rhasspy auf meiner ollen Murmel hinterlassen hat => Neue Hardware oder andere Lösung :'( ... (klar, man kann das gleich an einigen Enden abspecken, aber dann ist es vermutlich weniger intuitiv).

Na ja, soviel jedenfalls  erst mal dazu...

Die gestrige Version ist (um überflüssigen Code erleichtert) eingecheckt, es gab ja keine rechtzeitigen Beschwerden, sondern eher keine Klagen über die letzten Änderungen ::) .
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: MiLight@ESP-GW, BT@OpenMQTTGw | MySensors: seriell, v.a. 2.3.1@RS485 | ZWave | ZigBee@deCONZ | SIGNALduino | MapleCUN | RHASSPY
svn: u.a MySensors, Weekday-&RandomTimer, Twilight,  div. attrTemplate-files

drhirn

Jössas Maria!
"Erste Allgemeine Verunsicherung"
"Electric Light Orchestra"
"Earth, Wind & Fire"
"Fury in the Slaughterhouse"
"Fragements of Unbecoming"
"Me First And The Gimme Gimmes"
Da wirst beim Buchstabieren ja alt :D

Beta-User

Lustig sind auch
Van der Graaf Generator
George Thorogood & The Destroyers
Albert King with Stevie Ray Vaughan


Na ja, nachdem bei "den paar Buchstaben" schon einige "unbekannte Wörter" dabei waren, wird es bei ausländischen Band- und Künstlernamen dann halt vermutlich lustig....
Der Trick wäre ggf. der, einige wenige Buchstaben ausreichen zu lassen für eine regex-basierte Suche. Mit normalen Tastatureingaben klappt das ja eigentlich auch ganz ordentlich und fix (in meinem Fall MPD+MALP).
(Falls jemand noch den Buchstabiercode von JensS im Hinterkopf parat hat: Da sehe ich das Problem, dass zu kurze Sequenzen dann gerne nach "IntentNotRecognized" gehen würden (wenn/solange Choice deaktiviert ist. Das Abfangen dieses Effekts finde ich in "CancelAction" besser aufgehoben.)

Oder hat da jemand Erfahrung, wie gut das mit kompletten Künstlernamen klappt? (Also nicht nur bei 10-20...). Ich fürchte halt, dass der Nacharbeitsaufwand (bis zur "Sprechbarkeit") nicht zu schaffen wäre...
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: MiLight@ESP-GW, BT@OpenMQTTGw | MySensors: seriell, v.a. 2.3.1@RS485 | ZWave | ZigBee@deCONZ | SIGNALduino | MapleCUN | RHASSPY
svn: u.a MySensors, Weekday-&RandomTimer, Twilight,  div. attrTemplate-files

JensS

Hier nochmal die Buchstabier-Sub für die Wikipedia:sub ABC{
my $data = shift // return;
my $Buchstabe = shift // return;
my $SessionJSON = decode_json($data);
my $SessionID = $SessionJSON->{'sessionId'};
my $SiteID = $SessionJSON->{'siteId'};
my $CustomData = $SessionJSON->{'customData'}.$Buchstabe;
if ($Buchstabe ne "suche"){
my $ReturnHash = {
sendIntentNotRecognized => q{true},
intentFilter => [qq{de.fhem:ABC}],
customData => $CustomData,
text => $Buchstabe
};
return $ReturnHash;
}
else{
$CustomData =~ s/WIKI de.fhem:ABC //g;
$CustomData =~ s/suche//g;
Wikipedia($data,$CustomData);
}
}

Der Intent [ABC] ist per Standard deaktiviert und wird bei Bedarf plus Cancel-Intent als Filter gesetzt.
Wenn das Wort "suche" erkannt wird, ruft der else-Zweig die Wikipedia-Sub mit den Session-Daten und CustomData auf.
Das würde auch mit eine Regex-Sub gehen...

Das Problem bei der Erkennung von einzelnen Buchstaben wie "a" ist, dass die ASR schon auf den Sprecher hört, obwohl aus dem Lautsprecher noch Sprachausgabe tönt. Echocanceling ist dabei unerläasslich oder man verzichtet auf die akustische Rückgabe der gesprochenen Buchstaben. Bei der Langversion (nach DIN) "Anton" ist daher die Erkennung besser.

Gruß Jens
Debian auf APU2C4, HM-CFG-USB2, SIGNALduino, HM-ES-PMSw1-Pl, TFA 30.3121, TFA 30.3125, ITS-150, PIR-5000, configurable Firmata USB & LAN, 1-wire: DS-18B20, DS-18S20, DS-2408, DS-2413, diverse I2C-Komponenten, zigbee2mqtt, ESPEasy etc.