Modulentwicklung für Rhasspy Sprachassistent

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

Vorheriges Thema - Nächstes Thema

drhirn

Mir machen gerade folgende beiden Sätze sorgen:

"Stell die Heizung wärmer"
"Stell die Heizung höher"

V.a., wenn man auch noch z.B. eine Rollo hat:

"Stell den Rollo höher"

Ich kann die Rhasspy-Sentences nicht so bauen, dass Rhasspy unterscheiden kann, was gemeint ist.

stell $Device{Device} höher{Change:tempUp}
ist der gleiche gesprochene Satz wie
stell $Device{Device} höher{Change:setUp}

Weißt du, was ich meine?

Das Modul müsste entscheiden, was beim übermittelten Device zu tun ist. Führt uns wieder zu genericDeviceType. Oder wieder zurück zu {Type}.

Oder hast du das eh schon berücksichtigt?

Beta-User

#61
Hast du das Beispiel mal praktisch durchgespielt?

Wenn ich auf den Code starre, meine ich, dass $device immer durchschlägt, und dann eben "notfalls" ein nicht zum $type passendes Mapping genommen wird... (Möglicherweise geht es aber dann später schief, wenn "Change" relevant wird, aber eigentlich ist das dann wieder losgelöst von $type und es wird nur die Richtung ermittelt...?)

Ansonsten müßten wir überlegen, ob diese These richtig ist:
ZitatIch kann die Rhasspy-Sentences nicht so bauen, dass Rhasspy unterscheiden kann, was gemeint ist.

Und nein, ich habe nicht unbedingt absichtlich alles mögliche berücksichtigt, so weit habe ich das Rhasspy-Universum noch nicht durchflogen :P .

EDIT:
These erhärtet, Device schlägt wohl durch, danach interessiert nur noch die Richtung:
hermes/intent/de.fhem_SetNumeric {"input": "mach radio lauter", "intent": {"intentName": "de.fhem:SetNumeric", "confidenceScore": 0.6666666666666667}, "siteId": "default", "id": "cf521ed9-8de4-4bc2-82ae-77ed9a854e0c", "slots": [{"entity": "de.fhem.Device", "value": {"kind": "Unknown", "value": "radio"}, "slotName": "Device", "rawValue": "radio", "confidence": 1.0, "range": {"start": 5, "end": 10, "rawStart": 5, "rawEnd": 10}}, {"entity": "Change", "value": {"kind": "Unknown", "value": "tempUp"}, "slotName": "Change", "rawValue": "tempUp", "confidence": 1.0, "range": {"start": 11, "end": 17, "rawStart": 11, "rawEnd": 17}}], "sessionId": "cf521ed9-8de4-4bc2-82ae-77ed9a854e0c", "customData": null, "asrTokens": [[{"value": "mach", "confidence": 1.0, "rangeStart": 0, "rangeEnd": 4, "time": null}, {"value": "radio", "confidence": 1.0, "rangeStart": 5, "rangeEnd": 10, "time": null}, {"value": "tempUp", "confidence": 1.0, "rangeStart": 11, "rangeEnd": 17, "time": null}]], "asrConfidence": null, "rawInput": "mach das radio lauter", "wakewordId": null, "lang": null}
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

Kann's gerade nicht testen weil siehe weiter unten. Aber sieht so aus, als ob's wirklich funktioniert.

Größeres Problem: Das Sammeln von Devices, Rooms, etc. funktioniert nicht richtig. Und zwar dann nicht mehr, wenn ich davor ein reinit devicemap aufgerufen habe.

Ein updateSlots liefert mir dann
Updating Rhasspy Slots with data (de): {"de.fhem.Color":["grün","gelb","blau","rot"],"de.fhem.Device":["lampe1","Heizung","lampe2","RXV777"],"de.fhem.MediaChannels":["orf eins","orf zwei","orf drei"],"de.fhem.NumericType":[null],"de.fhem.Room":["küche","bad","wohnzimmer","schlafzimmer"]}

Device und NumericType hat da also Probleme.

Bei Device liegt das daran, dass die rhasspyNames nicht im $hash vorkommen. Weil sie in _analyze_rhassypAttr auch gar nicht rein geschrieben werden so wie ich das sehe. Hat das einen speziellen Grund?

Beta-User

#63
Zitat von: drhirn am 17 März 2021, 13:23:39
Bei Device liegt das daran, dass die rhasspyNames nicht im $hash vorkommen. Weil sie in _analyze_rhassypAttr auch gar nicht rein geschrieben werden so wie ich das sehe. Hat das einen speziellen Grund?
Na ja, die Frage ist, wie der Hash sinnvollerweise ausgewertet werden kann. Und da die "Names" nicht unbedingt eindeutig sind, macht es m.E. nicht den großen Sinn, dazu eine separate Struktur anzulegen. Ziel sollte eigentlich sein, über die Struktur immer auf schnelle Weise zu einem eindeutigen Ergebnis zu kommen. Daher kann es auch sein, dass das ganze im Bereich der Colors etc. noch zu einfach gestrickt ist... (kann sein bedeutet wohl eher: vermutlich ist...).

Die Art und Weise, wie die vorhandene Struktur ausgewertet wurde, war aber in jedem Fall fehlerhaft (auch noch zu Set/GetNumeric). Das sollte jetzt beides behoben sein.
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

Hmm, dann müssten wir für updateSlots ein neues Argument einführen, dass RHASSPY_allRhasspy[...] auf jeden Fall anweist, selbst zu suchen, anstatt den Hash zu nehmen.

Beta-User

...auf gar keinen Fall ;D ...

Dann wären die "fremden" Infos ja weg (oder wir gehen von unterschiedlichen Infos aus, je nach Auswertung => auch nicht gut!)...

Ablauf muss sein: updateSlots initiiert Neueinlesen des Hashes, danach wird der als Grundlage genommen.
Daher muss er alles enthalten, was erforderlich ist (vermutete Lücken: siehe vorhin), und dann auch die Auswertung (für den Versand an Rhasspy) so sein, dass alles drin ist.
Wie gesagt: zwei Bugs habe ich gefunden, für den Moment sollte es wieder vollständig sein, was jetzt aus dem Hash gelesen wird...
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

Okeoke  ;D

Mir ist aufgefallen, dass man reinit devicemap nach einem Neustart explizit aufrufen muss. Sonst ist der Hash leer. Ist das Absicht?

Beta-User

Zitat von: drhirn am 17 März 2021, 14:49:35
Mir ist aufgefallen, dass man reinit devicemap nach einem Neustart explizit aufrufen muss. Sonst ist der Hash leer. Ist das Absicht?
Zitat von: Beta-User am 15 März 2021, 17:34:05
[....] Die interne Struktur wird jetzt verwendet, wenn sie vorhanden ist, was derzeit bedeutet, dass man das aktiv Anschubsen muss. Finde ich für Testzwecke erst mal ganz gut.
Wenn das soweit ok ist und geprüft, könnte man dann die Hash-Generierung in firstInit() mit aufrufen (da sind alle Attribute auch von nachfolgenden defines vorhanden) und dann noch in "set ... updateSlots" (dort dann ziemlich vorne!) mit reinknödeln, das scheint ja eigentlich nur miteinander Sinn zu machen.

Hat dann aber zur Folge, dass Rhasspy dann die englischen "type" (also "brightness" statt "Helligkeit" zu sehen bekommt, selbst, wenn da heute im Mapping der deutsche Begriff steht. Weiß nicht, ob das Schwierigkeiten verursacht.

Next steps (nach "Zwangshash") wären dann:
- Ausbau der nicht mehr benötigten Code-Teile
- Auswertung von genericDeviceType & Co...
Die Bedingung ist aus meiner Sicht noch nicht hinreichend verifiziert ;) . Was man (recht einfach) tun könnte, wäre die Hash-Generierung (etc.) automatisch zu machen, wenn z.B. "usehash=1" in der DEF angegeben ist (parseParams ist was sehr hilfreiches, oder...?).
Wenn wir einfachere Testmöglichkeiten haben wollen, müßten wir auch eine Option anbieten, nach dem Testen im Echtsystem dann auch wieder den Hash zu löschen...

Ich habe aber derzeit keine Ahnung, ob das z.B. für JensS derzeit relevant ist. @JensS: Ich vermute, du nutzt die Variante, die mit deinen myUtils wieder gut umgehen kann?
Hast du Optionen zum Testen, oder ist das jedesmal im Hauptsystem und daher aufwändig zu wechseln?



@drhirn:
Was anderes noch. Es gibt im Hash jetzt teilweise eine Ebene zu viel (unter intents), nämlich - soweit ich das bisher überblicken kann - immer dann, wenn Set/GetNumeric im Spiel ist. Das hat mit dem leeren type zu tun und sieht irgendwie unschön aus, selbst wenn es funktioniert...
Daher die Frage: Ist es richtig, dass man diese Art der Unterstruktur nur bei diesen beiden intents benötigt? Oder kann es sowas auch bei [SG]etOnOff geben?

Anders gesagt: Ich fürchte, wir sind noch nicht ganz soweit...
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

Ja, ich habe nur das Produktivsystem und bin daher nur begrenzt leidenfähig. Ich nutze die Version aus meinem Fork. https://github.com/jens-schiffke/fhem-rhasspy/blob/master/10_RHASSPY.pm
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.

drhirn

Ach, entschuldige! Mein Hirn...

Jens verwendet - soweit ich das verstanden habe - immer sein Produktiv-System. Deswegen hätte ich mal um die Custom Intents gebeten. Damit ich die testen kann.

Wenn ich dich richtig verstanden habe, meinst du das hier?

'RXV777' => {
                                       'intents' => {
                                                      'SetNumeric' => {
                                                                        'volume' => {
                                                                                      'type' => 'volume',
                                                                                      'currentVal' => 'volume',
                                                                                      'step' => '10',
                                                                                      'maxVal' => '100',
                                                                                      'cmd' => 'volume',
                                                                                      'minVal' => '0'
                                                                                    }
                                                                      },
                                                      'MediaControls' => {
                                                                           '' => {
                                                                                   'cmdBack' => 'previous',
                                                                                   'cmdPause' => 'pause',
                                                                                   'cmdStop' => 'stop',
                                                                                   'cmdFwd' => 'next',
                                                                                   'cmdPlay' => 'play',
                                                                                   'type' => undef
                                                                                 }
                                                                         },
                                                      'GetOnOff' => {
                                                                      '' => {
                                                                              'currentVal' => 'state',
                                                                              'type' => undef,
                                                                              'valueOff' => 'off'
                                                                            }
                                                                    },
                                                      'SetOnOff' => {
                                                                      '' => {
                                                                              'cmdOn' => 'on',
                                                                              'cmdOff' => 'off',
                                                                              'type' => undef
                                                                            }
                                                                    }
                                                    },

JensS

Einige CustomIntents sind im Rhasspy-Thread veröffentlicht. Zum Testen der Übergabe in und von der sub, erstellt besser einen speziellen Intent, der alle Möglichkeiten abbildet und Logs ausgibt.
Wobei mir nicht klar ist, weshalb man alles testen muss.
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.

Beta-User

Nevermind, mir geht auch hin und wieder was raus...

Zeigt aber, dass es wichtig wäre, erst mal - soweit als möglich - Kompabilität und eine Art Testmodus anzubieten.

Jens ist halt noch ganz in der "alten Welt" verhaftet. Ich _glaube_, dass es relativ gefahrlos und unaufwändig wäre, erst mal den Schritt auf die "no-Hash"-Variante mit dem aktuellen Modul zu gehen. Alternativ könntest du (ungetestet...) das Modul auch umbenennen und nach einer sehr kleinen Änderung des Namens der Initialize-Funktion sogar beides parallel betreiben, wobei dann sinnvollerweise eine andere fhemId und einen anderen Präfix gesetzt werden sollte. Dann könntest du das eine oder andere auch so testen (allerdings zu dem Preis, dass ggf. zusätzliche Attribute erforderlich werden).
Bei Interesse schreibe ich gerne, wie das geht, zumindest bei meinen Tests zu Twilight habe ich das auch so gemacht...

@Jens (bzw. ggf. weitere Tester): Für eine Rückmeldung, ob der Aufwand aus deiner/eurer Sicht Sinn macht, wäre ich dir/euch sehr verbunden, eine Anleitung/eine entsprechend angepaßte Datei kann ich gerne liefern...

Alternative:
Testsystem aufbauen und ggf. (z.B. mit FHEM2FHEM) einen Teil "clonen" und dann in dem Testsystem (ebenfalls mit anderer fhemId) eben die "neue Welt" austesten.

Leider kann ich im Moment nicht wirklich sicher sagen, wie stabil das alles ist. Meine Tests sehen zwar ok aus, sind aber bisher nicht wirklich umfangreich (ich will eigentlich erst zumindest einen Teil der genericDeviceType-Geschichten "ausschlachten" können).
Da fällt mir ein: Es sollte eine Option geben, dass RHASSPY die "tpischen Attribute" ggf. selbst in die globalen (? oder user-) Attribute einfügt, falls sie nicht da sind...
(Wenn das fertig wäre, könnte man RHASSPY ggf. auch in die Sprachsteuerungs-attrTemplate mit aufnehmen, was ggf. die Ersteinrichtung neuer Devices vereinfachen kann).

Zitat von: JensS am 17 März 2021, 17:19:49
Einige CustomIntents sind im Rhasspy-Thread veröffentlicht. Zum Testen der Übergabe in und von der sub, erstellt besser einen speziellen Intent, der alle Möglichkeiten abbildet und Logs ausgibt.
Wobei mir nicht klar ist, weshalb man alles testen muss.
Was die Custom-Geschichte angeht, meine ich, dass man ggf. nur noch checken müßte, ob der angeorderte HASH verwertbar ist; da bin ich bisher schlicht nicht dazu gekommen, und bisher gab es auch relativ wenig Bedarf, überhaupt was anzufordern. Aber das mit den "Klatrextelementen" sollte ja jetzt gehen, und an der Stelle sollten auch keine Änderungen mehr kommen.

Auch am Sprach-"hash" dürfte das meiste erledigt sein, ggf. würde ich nur noch überlegen, ob man eine Variante baut, die dann erlaubt, die eigenen von den default-Sätzen zu trennen (und dann den konsolidierten Hash als Grundlage nimmt).

Von daher ginge es jetzt erst mal darum, die Struktur des "devicemap"-Hashes zu finalisieren und dann zu testen, ob das alles klappt, wie es soll. Dafür wären Tester sehr willkommen (zumindest, sobald das mit dem folgenden geklärt ist und in der Basis läuft...)



Ja, gemeint war diese Zwischenstufe
Zitat{
  '' => {
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

Jens ist in der Welt verankert, die funktioniert.  ;)
Danke für das Angebot aber von weiteren Teststellungen sehe ich ab.
Generell ist die Nutzung von Hash eine gute Sache, wenn man einen großen Dachboden bzw. Speicher hat.
Die Geräte sind alle in %defs und können zur Laufzeit abgerufen werden. Im "alten Modul" wurde die JSON-Message bereits in einen Hash geladen - also für mich ist das kein Quantensprung.
Die Entkopplung der Begriffe in eine Sprachdatei finde ich gut, sollte aber eindeutig und gut verständlich sein.
Insgesamt begrüße ich die Modernisierung. Sie sollte halt funktionieren und den User nicht einschränken.
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.

drhirn

Zitat von: Beta-User am 17 März 2021, 17:28:43
Ja, gemeint war diese Zwischenstufe

Ahh, hat ein bisschen gedauert. Mein Hirn... ;)

Ja, nein, mir fällt jetzt spontan kein Intent ein, der mehrfach Sinn machen würde. Außer eben Get/SetNumeric.

Aber wir können bei den anderen Intents ja einfach einen Platzhalter nehmen wenn das einfacher ist.

Beta-User

Zitat von: drhirn am 17 März 2021, 18:09:21
Ja, nein, mir fällt jetzt spontan kein Intent ein, der mehrfach Sinn machen würde. Außer eben Get/SetNumeric.

Aber wir können bei den anderen Intents ja einfach einen Platzhalter nehmen wenn das einfacher ist.
Muss mal schauen, was da wie Sinn macht; vermutlich ist es dann einfacher, diese beiden halt separat abzuarbeiten bzw. einen eigenen Zweig dafür vorzuhalten.

@JensS:
Verständliche Position. Ich empfinde das bisher (und vermutlich auch in Zukunft) auch nicht als funktionalen Quantensprung, wenn man ein funktionierendes System hat und weiß, wo/wie man die Sätze anpassen kann, wenn man Bedarf sieht. Das ganze "beglückt" eher neue User...
Sehe zwar nicht, wo (evtl. abgesehen von dem Trigger-Thema, das aber auch weitgehend gelöst sein sollte) jetzt Einschränkungen wären, aber vermutlich übersehe ich mal wieder was.
Bzgl. der Eindeutigkeit/Verständlichkeit der Sprachdatei: Falls es Vorschläge gibt: her damit...
MAn. ist es jetzt "erträglich" - es gibt einen halbwegs aussagekräftigen "Label" und eine recht flache Struktur samt Beispielen, so dass man das m.E. jetzt recht gut selbst anpassen (oder übersetzen) könnte, und die Rückmeldungen sind jetzt auch etwas spezifischer, an welcher Stelle ggf. der "finde mein Device"-Prozess nicht geklappt hat (was aber ja sowieso die Ausnahme sein sollte).
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