Modulentwicklung für Rhasspy Sprachassistent

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

Vorheriges Thema - Nächstes Thema

JensS

Ok, das vereinfacht die Sache. Noch einfacher wäre ein kurzes Beispiel gewesen.
Hier (als Info) mein aktueller Einstieg in den Dialog:sub WIKI{
my $ReturnHash = {
sendIntentNotRecognized => true,
intentFilter => [qq{de.fhem:ABC}],
customData => qq{WIKI },
text => qq{bitte buchstabiere}
};
return $ReturnHash;
}
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

Zitat von: JensS am 16 Juli 2021, 09:41:53
Ok, das vereinfacht die Sache.
:) ...ebend. Der Code sollte von der Struktur her schon so aufgebaut sein, dass es insgesamt relativ einfach ist, zu einem akzeptablen Ergebnis zu gelangen... Scheint halbwegs funktioniert zu haben 8) .

ZitatNoch einfacher wäre ein kurzes Beispiel gewesen.
Klar... Ich war nur erst mal froh, das innerhalb des Moduls soweit auf die Reihe gebracht zu haben ;D . Und "jemand" hat den Ball ja jetzt aufgenommen ;) .

Ich würde das Beispiel allerdings (ungetestet) so schreiben:
sub WIKI {
    my $ReturnHash = {
        sendIntentNotRecognized => q{true},
        intentFilter => [qw(de.fhem:ABC de.fhem:CancelAction)],
        customData => q{WIKI },
        text => q{bitte buchstabiere}
    };
    return $ReturnHash;
}

Für die Feinheiten - unsicher bin ich, ob
- man besser "return \$ReturnHash;" schreiben sollte, und
- "true" auch ohne Quotes ok ist oder ob das ohne Quotes erst (Perl-intern) irgendeine Sonderbehandlung braucht...
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

#827
Zitat von: Beta-User am 16 Juli 2021, 10:01:58Und "jemand" hat den Ball ja jetzt aufgenommen ;) .
Gern  :) .
"return \$ReturnHash;" bringt Fehler - "return $ReturnHash;" läuft.
true mit einfachen Quotes funktioniert genauso wie ohne Quotes.

p.s.
Der Dialog ist ziemlich empfindlich und bricht häufig mit sendIntentNotRecognized ab.
Ich nehme an, dass durch die etwas verzögerte Ausgabe des Textes (bitte buchstabiere, a, etc.), ein lokales Echo als Antwort erkannt wird. Mit text => q{} funktioniert es besser.
Leider hat das "ReSpeaker 2-Mics Pi HAT" kein internes Echo-Canceling und das macht es etwas aufwändiger.
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.

JensS

Habe ein seltsames Verhalten bei einem rhasspyShortCut.
i="Gartensprenger einschalten" f="set Gartensprenger on" n="Gartensprenger" c="Soll ich wirklich den Garten sprengen?" ct=10
Die Anweisung und die Rückfrage werden richtig erkannt und der dummy Gartensprenger wird auch geschalten.
Am dummy hängt ein Notify, welches $EVENT an ein FRM_Out-Device weitergibt. Das funktioniert nur in diesem Zusammenhang nicht. Bei der Eingabe von "set Gartensprenger on" läuft's.
Sieht so aus, als würde kein Event ausgelöst.
Jetzt kommt das Merkwürdige - bei:i="Beleuchtung einschalten" f="set Stehlampe on" n="Stehlampe" c="Soll ich die Stehlampe wirklich einschalten?" ct=10funktioniert es. Hier wird allerdings das Device (Zigbee2MQTT) direkt geschalten.
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

Vermutung:
Wir sind innerhalb einer Event-Verarbeitungsschleife. Die wird (u.a.) "per name" abgearbeitet (v.a., um unbeabsichtigte Schleifen zu verhindern). Damit ich nicht den kompletten Code in fhem.pl checken muss, wäre es gut, du könntest mal testen, ob es was ändert, wenn du
-  "Gartensprenger" umbenennst, so dass er z.B. mit "Z" beginnt (bzw. das notify?);
- den FRM_out als readingsProxy (statt dummy+notify) konfigurierst
- die Event-Priorität vom RHASSPY-Gerät änderst (Details siehe https://wiki.fhem.de/wiki/DevelopmentModuleIntro#X_Notify):
$hash->{NotifyOrderPrefix} = "45-";
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

Zitat von: Beta-User am 20 Juli 2021, 08:02:00
-  "Gartensprenger" umbenennst, so dass er z.B. mit "Z" beginnt (bzw. das notify?);
...funktioniert nicht.

Zitat- den FRM_out als readingsProxy (statt dummy+notify) konfigurierst
Den dummy brauche ich für weitere Abfragen (Zeitsteuerung inkl. Bodenfeuchte $ Regen). FRM_out kann direkt geschalten werden.

Zitat- die Event-Priorität vom RHASSPY-Gerät änderst (Details siehe https://wiki.fhem.de/wiki/DevelopmentModuleIntro#X_Notify):
Das geht doch nur im Modul selbst - also dummy.?

Mit einem DOIF ging es auch nicht, obwohl in verbose 5dummy set Gartensprenger onsteht.

Als Zwischenlösung lasse ich zwei Devices mit Perl schalten.i="Gartensprenger einschalten" p={fhem("set Gartensprenger on");; fhem("set FRM_13 on")} c="Soll ich wirklich den Garten sprengen?" ct=10
i="Gartensprenger ausschalten" p={fhem("set FRM_13 off");; fhem("set Gartensprenger off")} c="Soll ich den Gartensprenger wirklich ausschalten?" ct=10
n=... habe ich rausgenommen, da ich keinen Verweis im Modul gesehen habe.

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.

Beta-User

Danke für's testen, auch wenn ich manche Punkte noch nicht so recht nachvollziehen kann...:

Zitat von: JensS am 20 Juli 2021, 17:50:28
...funktioniert nicht.
Bezieht sich das auf beide Varianten? Auch das Umbenennen des notify?

Zitat
Den dummy brauche ich für weitere Abfragen (Zeitsteuerung inkl. Bodenfeuchte $ Regen). FRM_out kann direkt geschalten werden.
Nachvollziehbar.

Zitat
Das geht doch nur im Modul selbst - also dummy.?
Gemeint war wie geschrieben: im RHASSPY-Code. Da aber RHASSPY selbst gar nicht "notified" wird, war das wohl so oder so zu kurz gedacht.

ZitatMit einem DOIF ging es auch nicht, obwohl in verbose 5dummy set Gartensprenger onsteht.
DOIF kenne/verstehe ich nicht, aber mAn. ist das auch nicht anders wie bei notify. Vielleicht kommt es auf den trigger bzw. darauf an, dass NOTIFYDEV gesetzt/erkannt wird, wobei das ja der Fall zu sein scheint...?

Zitatn=... habe ich rausgenommen, da ich keinen Verweis im Modul gesehen habe.
Das ist mit einiger Sicherheit kontraproduktiv!

Zur Erläuterung: Das RHASSPY-Modul/parseFn gibt an fhem.pl eine Liste der Geräte zurück, die "getriggert" wurden. Welche, gibt man u.A. über diesen Parameter an. Fehlt er, wird nur der Name der RHASSPY-Instanz zurückgegeben (bzw. bei "fhem"-Befehlen kann es sein, dass die analysiert werden(? müßte ich nachsehen)).
Diese Liste wird dann von fhem.pl analysiert und es werden dann nur die  Event-Handler "informiert", die - bei  vorhandenem NOTIFYDEV - ein Gerät aus dieser Liste damit abdecken, oder die das Internal nicht gesetzt haben (aber damit tendenziell ineffizienter sind, weil sie alles selbst analysieren müssen).
Wenn das also klappt, liegt es entweder daran, dass die automatische Erkennung (bei mehreren Befehlen sicher nur teilweise!) funktioniert, oder der betreffende Eventhandler "unsauber" ist.

(Die Reihenfolge der Benachrichtigtung richtet sich dann nach dem Prio-Internal von oben, was z.B. hilft, wenn man ggf. durch einen Event-Handler erst noch einen Reading-Wert ändern will, bevor andere Event-Hanlder das Eregebnis analysieren...)

MAn. sollten wir das in jedem Fall sauber lösen... Ich habe nur weiter keine Idee, wo das Problem ggf. entstehen könnte, wenn "n=" gesetzt ist und NOTIFYDEV auf dieses Device zeigt. (=> show me...)
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

Zitat von: Beta-User am 21 Juli 2021, 08:03:14
Bezieht sich das auf beide Varianten? Auch das Umbenennen des notify?
Ja, beide Varianten (leider erfolglos) getestet.

ZitatVielleicht kommt es auf den trigger bzw. darauf an, dass NOTIFYDEV gesetzt/erkannt wird, wobei das ja der Fall zu sein scheint...?
Beim f=... ist das nachvollziehbar, bei p=... wird ja der set-Befehl auf Perl-Ebene abgesetzt und sollte auf jeden Fall greifen.

ZitatMAn. sollten wir das in jedem Fall sauber lösen... Ich habe nur weiter keine Idee, wo das Problem ggf. entstehen könnte, wenn "n=" gesetzt ist und NOTIFYDEV auf dieses Device zeigt. (=> show me...)
Bei der Perl-Variante werden Gartensprenger und FRM_13 durch die Perl-Anweisung geschaltet. Daher handelt es sich genau genommen um zwei NOTIFYDEV.

Kannst du testweise ein readingsSingleUpdate auf state setzen? Das ist zwar nicht die feine Art aber hilft eventuell bei der Lösungsfindung.

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.

Beta-User

...immer noch Missverständnisse...:
Zitat von: JensS am 21 Juli 2021, 16:44:50
Beim f=... ist das nachvollziehbar, bei p=... wird ja der set-Befehl auf Perl-Ebene abgesetzt und sollte auf jeden Fall greifen.
Es wird mAn. IMMER geschaltet, unabhängig davon, ob es als Perl- oder FHEM-Anweisung gekennzeichnet ist. Es kann nur sein, dass bei der Perl-Variante die Events (teilweise!) "sauberer" generiert werden bzw. die Liste der getriggerten Geräte nicht ganz so _unvollständig_ ist (wenn mehrere Geräte beteiligt sind);

Zitat
Daher handelt es sich genau genommen um zwei NOTIFYDEV.
NOTIFYDEV ist/war hier technisch zu verstehen, im Sinne eines ganz bestimmten Internals bei Eventhandlern. Vielleicht hilft https://forum.fhem.de/index.php/topic,117075.msg1115704.html#msg1115704 etwas weiter, um zu verstehen, was ich mit dem obigen konkret meine, im RHASSPY-Kontext (etwas versteckt) ggf. dann noch https://forum.fhem.de/index.php/topic,118979.msg1134879.html#msg1134879.

Zitat
Kannst du testweise ein readingsSingleUpdate auf state setzen? Das ist zwar nicht die feine Art aber hilft eventuell bei der Lösungsfindung.
a) weiß ich nicht genau, wie das gemeint ist, und
b) klingt es nach einem üblen Würgaround, der das eigentliche Problem vermutlich dann auch nicht beseitigt: Es MUSS von ParseFn() eine Liste der betroffenen Geräte zurückgeliefert werden, wenn man "seitlich vorbei" versucht, Events zu generieren, klappt das nicht wirklich ;) . (Oder man muß bewußt unsauber (= ineffizient in der Eventverarbeitung) arbeiten).
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

#834
NOTIFYDEV - eben das "Starting notify loop for dummy ..." fehlt. Egal ob mit einem dummy und f= (und n=) oder einem dummy mit p=.

Folgendes habe ich gerade (erfolglos) probiert:i="Gartensprenger einschalten" p={ my $TueHash = $defs{'Gartensprenger'};; readingsSingleUpdate($TueHash, "state", "on", 1)} c="Soll ich wirklich den Garten sprengen?" ct=10
Setze ich den Perl-Einzeiler in der Befehlszeile ab, wird ordentlich geschaltet.
Wenn ich auf die Frage "Soll ich den Garten wirklich sprengen?" mit "ja bitte" antworte, wird der Block ebenfalls ausfgeführt und ich erhalte statt "ok, mach ich" ein einfaches "on" als Sprachausgabe. Der Status vom dummy ändert sich aber ein Event wird nicht ausgelöst.

p.s.
Kann es sein, dass das shortCut zwischen einem readingsBeginUpdate und einem (noch nicht erfolgtem) readingsEndUpdate hängt?

p.p.s.
Hab's mal auf die Spitze getrieben und einen kompletten ReadingsUpdate-Durchlauf gemacht. Das funktioniert!i="Gartensprenger einschalten" p={ my $TueHash = $defs{'Gartensprenger'};; readingsBeginUpdate($TueHash);; readingsBulkUpdateIfChanged($TueHash, "state", "on", 1);; readingsEndUpdate($TueHash, 1)} c="Soll ich wirklich den Garten sprengen?" ct=10
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

Sieht nach einem bug bzw. einem Fehler in der Doku aus, versuch's mal mit "d=..." (#680 und #2823)
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

#836
Zitat von: Beta-User am 21 Juli 2021, 18:39:43
versuch's mal mit "d=..." (#680 und #2823)
...macht Sinn - funktioniert leider auch nicht.

Kurze Zwischenfrage zu u.a. #2824 und #2834:
Wäre     my $cmd    = $shortcut->{perl} if exists $shortcut->{perl}; richtigerer?  :o

Gruß Jens

p.s.
Da das Verhalten nur bei dummys auftritt und bei anderen Typen (z.B. FRM_out) nicht, könnte es auch eine Besonderheit im Eventhandling von 98_dummy.pm sein.
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

Ich wollte nur mal kurz vermelden: Bin eh noch da und lese brav mit. Kann nur nichts beitragen.
Aber habe gerade, wie immer knapp vor einem Urlaub, aus Langeweile wieder ein bisschen mit Rhasspy geredet. Und bin immer noch begeistert ob unser aller Arbeit :)

Beta-User

#838
Zitat von: drhirn am 22 Juli 2021, 11:37:42
Ich wollte nur mal kurz vermelden: Bin eh noch da und lese brav mit. Kann nur nichts beitragen.
Aber habe gerade, wie immer knapp vor einem Urlaub, aus Langeweile wieder ein bisschen mit Rhasspy geredet. Und bin immer noch begeistert ob unser aller Arbeit :)
Dann mal schönen Urlaub!

Im Anhang dann noch eine kleine Aktualisierung (s.u.), die aber weiter das "d=..." aus dem Shortcuts-Attribut (zur Doku passend) in "NAME" übernimmt. (Wir hatten irgendwann eine Diskussion darüber, ob das Kürzel "d" oder "n" sein sollte, weiß aber nicht mehr, wie wir das letztendlich entschieden hatten. Ich finde weiter n=>NAME verständlicher, aber da das auch in der Doku so stand, bleibt das erst mal so...).
Vielleicht schubst du das ins svn? MAn. ist v.a. das mit der verbesserten Doku "cool", ansonsten bin ich auch sehr froh, dass es im großen und ganzen keine größeren offenen Punkt gibt...

(OK, das mit dem komplexeren Dialog, aber da hat JensS jetzt ja auch mit dem myUtils-Buchstabieren ein sehr tolles Beispiel gebaut, mit dem man weiterarbeiten kann!)

Was das mit dem ausbleibenden DoTrigger-Anweisungen nach Dispatch angeht, habe ich mal noch eine Log-4-Meldung eingebaut, in der steht, welche Devices zurückgegeben werden.

Zitat von: JensS am 21 Juli 2021, 18:59:01
...macht Sinn - funktioniert leider auch nicht.
Wird denn im RHASSPY-Hash zu dem Shortcut "NAME" gefüllt?

Habe den Code kurz überflogen, und mAn. müßte das eigentlich im Rückgabe-Array landen, was da steht, es sei denn
- (bisher) es wird Perl ausgeführt, und dieser Code gibt etwas zurück. Das stand etwas anders in der Doku, ich hoffe, den Code jetzt auch an der Stelle entsprechend angepasst zu haben;
- die Devices existieren nicht.

ZitatKurze Zwischenfrage zu u.a. #2824 und #2834:
Wäre     my $cmd    = $shortcut->{perl} if exists $shortcut->{perl}; richtigerer?  :o
Doppelt nein:
- my $foo = "baa" if $baz; ist grundsätzlich eine "unzulässige" Anweisung. (Wenn, dann müßte man $foo vorher einführen);
- wenn der Hash nicht defined ist, bleibt $cmd undefined, und genau das wird später gecheckt.
Falls du strukturelle Zweifel hast (dahingehend, dass immer der erste (oder 2.) Zweig angefahren wird): Verbose 5 sollte Aufschluss geben ;) .

Zitat
Da das Verhalten nur bei dummys auftritt und bei anderen Typen (z.B. FRM_out) nicht, könnte es auch eine Besonderheit im Eventhandling von 98_dummy.pm sein.
Vermute eher, dass FRM_out ein (eigentlich) 2. Event wirft, wenn der Befehl von der Hardware ausgeführt wurde. So sollte es für eigentlich alle bidirektionalen Systeme sein.

Wir sollten als erstes checken, was an fhem.pl-Dispatch() zurückgegeben wird, beginnend mit der sauberen Übernahme in den RHASSPY-Hash als "NAME". Dann sehen wir weiter.
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