Perl - Modul 10_RHASSPY.pm "professionalisieren"

Begonnen von drhirn, 18 Februar 2021, 17:02:31

Vorheriges Thema - Nächstes Thema

Beta-User

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


Beta-User

#152
...anbei der Versuch, das qq() an etwas anderer Stelle (erst mal nur für die genannte Timer-Rückmeldung; geändert u.a. Zeile 1956) zu plazieren. Das "Problem" ist, dass man die Variablen zur richtigen Zeit auflösen muss...

Wenn das vollends klappt, würde ich vorschlagen, mal mit den default answers weiterzumachen?

Was $language angeht, ist mir jetzt auch so langsam klar, dass das so nicht bleiben kann ::) . Wir werden das wohl ersetzen müssen durch $hash->{language} und jeweils zur Laufzeit auflösen (ggf., indem wir das in eine kürzere Variable packen).
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's leider auch nicht.
Ich glaub, wir müssen die Sätze einfach aufteilen und zur Laufzeit zusammen stückeln. Am besten so, dass man einzelne Stücke via Attribut ändern kann.

Aber können wir das Sprach-Feature vorerst pausieren? Auch wenn's dir Spaß zu machen scheint? Ich würde das Modul gerne mal auf Herz und Nieren testen und dann ein paar Baustellen aufräumen. Shortcuts z.B. Und sollte dann noch CRef und GitHub-Doku anpassen. Damit wir wiedermal einen stabilen Stand bekommen. Und nebenbei sollte ich auch wieder mal meinen Arbeitgeber glücklich stellen ;)

drhirn

get_unique liefert z.B. immer nur einen Wert zurück. Und ich versteh nicht ganz, was da passiert. Woher kommen $seen, $a und $b her? Und warum wird %seen nicht verwendet?

Beta-User

Ad get_unique: Das ist "eigentlich" nur ausgelagert, was z.B. "schon immer" (noch) in RHASSPY_allRhasspyChannels steht.

Die modifizierte Form kam durch Perlcritic und den im/über der Funktion stehenden Link aus stackoverflow, da habe ich jetzt auch den Hinweis gefunden, dass das Probleme geben kann, wenn das array nicht sortiert ist.

Würde daher die Vor-Sortiererei mal noch austesten:
sub get_unique {
    my @arr    = sort shift; #we may need to sort, see https://stackoverflow.com/a/30448251
    my $sorted = shift; #true if shall be sorted (longest first!)
    my %seen;
   
    #method 2 from https://stackoverflow.com/a/43873983
    my @unique = grep {!$seen{$_}++} @arr;

    return @unique if !$sorted;

    my @sorted = sort { length($b) <=> length($a) } @unique;
    return @sorted;
}
%seen wird definiert, und dann die noch nicht vorhandenen Hash-Elemente mit "Zahlen" belegt. Ist also eigentlich auch nichts anderes wie das, was vorher da stand, nur etwas komprimierter. Wenn's nicht funktioniert, muss da dann einfach statt "method 2" die alte Zeile rein:
# Doubletten rausfiltern
%roomsHash = map { if (defined($_)) { $_, 1 } else { () } } @rooms;
@rooms = keys %roomsHash;

Wobei %roomsHash eben %seen heißt und @rooms @unique...

$a und $b sind "Perl-specials": Laufvariablen für's sortieren. Daher gibt es Leute, die dringlich darauf hinweisen, dass deren Verwendung im "normalen" Kontext nicht stattfinden sollte (das ist der Hintergrund, weswegen ich jedes Mal, wenn mir eines vor die Flinte läuft @a in @arr umbenenne ;) ).



Was das $language-Thema angeht, habe ich vernommen, dass wir eine Pause einlegen sollten. Ich _glaube_ aber, dass der Aufwand für den Rückbau fast größer ist wie der Versuch, das vollends (in Grundzügen) in den bereits angelegten Teilen erst mal zum Laufen zu bringen und werde das noch in diese Richtung angehen (ich habe mal wieder was übersehen, als ich vorhin geantwortet habe: der Plan war schon immer, eigentlich auf den internen Hash zuzugreifen und eigentlich in den meisten Fällen auf $language verzichten zu können (nach der Initialisierung)...

Sätze aufteilen kann nicht die Lösung sein, das macht es nur unnötig kompliziert. Die Sprachkonfiguration muss m.E. stattdessen in separate files, wobei je nach Sprache bzw. Userkonfiguration dann genau eine ausgewählt/eingelesen wird.

Muss mal hirnen, wie ich ggf. den Rückmeldesatz testweise ermitteln kann, da wäre es hilfreich, noch einen topic-message-Datensatz zu haben, mit dem das ausgelöst 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

Danke für die Infos! Ich schau mir das an. Im Moment wundere ich mich noch ein bißchen, dass in get_unique nicht alle Devices ankommen. Aber das kann meinem fehlendem Perl-Grundverständnis geschuldet sein.

Guter Hinweis mit $a und $b!

Rückbau? Warum sollten wir etwas zurück bauen? Der Timer ist gerichtet, wenn man eine Zeile ein- und eine andere auskommentiert. Der Rest funktioniert ja soweit. Sofern man kein Reload des Moduls macht ;).

Topic für welchen Rückmeldesatz hättest du gerne?

Beta-User

#157
Zitat von: drhirn am 02 März 2021, 10:22:25
Danke für die Infos! Ich schau mir das an. Im Moment wundere ich mich noch ein bißchen, dass in get_unique nicht alle Devices ankommen. Aber das kann meinem fehlendem Perl-Grundverständnis geschuldet sein.
Na ja, nach dem, was du schilderst, kommen nicht alle raus...
Aber vielleicht hast du recht und man müsste erst mal checken, ob da alles reingeht, was soll... Hab's jedenfalls so umgestellt, dass nur die Referenz auf das Array übergeben wird, sollte so oder so besser sein...

Zitat
Rückbau? Warum sollten wir etwas zurück bauen? Der Timer ist gerichtet, wenn man eine Zeile ein- und eine andere auskommentiert. Der Rest funktioniert ja soweit. Sofern man kein Reload des Moduls macht ;) .
Guter Hinweis! Das mit dem Auskommentieren wäre eine Idee, dann können wir ggf. auch weiter recht einfach testen :) .
Jetzt sollte das ganze auch einen reload des Moduls überleben, derselbe Webfehler war btw. auch in $prefix drin gewesen, hoffe, das auch an der Stelle beseitigt zu haben.

ZitatTopic für welchen Rückmeldesatz hättest du gerne?
Eigentlich weniger der Rückmeldesatz, sondern das Timer-Kommando; was dann rauskommt, sollte ja im Reading "voiceResponse" zu sehen sein, oder? Werden die Parameter aufgelöst, müßte da dann ja auch was lesbares stehen...
Na ja, wie dem auch sei, die "Default"-Answers berücksichtigen jedenfalls die Sprache (brauchte ich zum Testen...).

Mal sehen, wann wir die Frage bekommen, wann man den Hash über eine externe Datei einlesen kann, damit das Ding spanisch (oder französisch) spricht...
(Ziel wäre, den englischen default (?) im Modul zu lassen, und alles andere extern. So hat man ein "Musterpattern" für einen JSON-Editor im Modul und kann dann ggf. eigene Sprachdateien dafür erstellen...
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

Aha, aha, jetzt kommen alle Devices an. Sehr gut! Doppelte Einträge werden aber nicht mehr gelöscht. Und bei mehreren "devices" ist eine eckige Umklammerung zuviel:

Updating Rhasspy Slots with data (de): {"de.fhem.Color":["grün","blau","gelb","rot"],"de.fhem.Device":[["Musik","deckenlampe","licht","lampe","radio","licht"]],"de.fhem.MediaChannels":[["orf eins","orf zwei","orf drei"]],"de.fhem.NumericType":["Helligkeit"],"de.fhem.Room":[["bad","küche","bad","wohnzimmer","schlafzimmer"]]}


Die Sprache übersteht einen Reload. Gute Arbeit!

Bzgl. Timer:

Msg: hermes/intent/de.fhem_SetTimer => {"input": "taimer im bad auf 10 minuten", "intent": {"intentName": "de.fhem:SetTimer", "confidenceScore": 1.0}, "siteId": "wohnzimmer", "id": null, "slots": [{"entity": "de.fhem.Room", "value": {"kind": "Unknown", "value": "bad"}, "slotName": "Room", "rawValue": "bad", "confidence": 1.0, "range": {"start": 10, "end": 13, "rawStart": 10, "rawEnd": 13}}, {"entity": "rhasspy/number", "value": {"kind": "Number", "value": 10}, "slotName": "Value", "rawValue": "zehn", "confidence": 1.0, "range": {"start": 18, "end": 20, "rawStart": 18, "rawEnd": 22}}, {"entity": "Unit", "value": {"kind": "Unknown", "value": "minuten"}, "slotName": "Unit", "rawValue": "minuten", "confidence": 1.0, "range": {"start": 21, "end": 28, "rawStart": 23, "rawEnd": 30}}], "sessionId": "wohnzimmer-snowboy-a4ab8b5e-da43-402f-bf90-4dc8a6bb17d7", "customData": null, "asrTokens": [[{"value": "taimer", "confidence": 1.0, "rangeStart": 0, "rangeEnd": 6, "time": null}, {"value": "im", "confidence": 1.0, "rangeStart": 7, "rangeEnd": 9, "time": null}, {"value": "bad", "confidence": 1.0, "rangeStart": 10, "rangeEnd": 13, "time": null}, {"value": "auf", "confidence": 1.0, "rangeStart": 14, "rangeEnd": 17, "time": null}, {"value": "10", "confidence": 1.0, "rangeStart": 18, "rangeEnd": 20, "time": null}, {"value": "minuten", "confidence": 1.0, "rangeStart": 21, "rangeEnd": 28, "time": null}]], "asrConfidence": null, "rawInput": "taimer im bad auf zehn minuten", "wakewordId": "snowboy", "lang": null}

AT sieht dann so aus:
defmod timer_bad at 2021-03-02T13:35:17 set Rhasspy speak siteId="bad" text="taimer abgelaufen";;setreading Rhasspy timer_bad 0

voiceResponse:
Taimer in $room gesetzt auf $value $unit.

Beta-User

#159
Hmm, dann vermutlich besser nicht die Referenz übergeben, sort könnte genügen? Hab's mal ohne Referenzierung... (Um dann auf unter 100 violations zu kommen, habe ich das get_unique() noch an anderer Stelle eingebaut. 8) ). 

Bzgl. Sprache:  ;D 8) ;D
Die ersten Schnipsel für FileRead sind jetzt auch drin, aber das ist noch nicht effektiv funktional und braucht nach dem Fertigstellen dann noch Tests.

Jetzt klappt das auch mit den Variablen, aber man braucht einen ziemlichen Umweg, habe daher noch RHASSPY_EvalSpecialsDefaults() etwas optimiert.
Wird halt "tricky" werden zu erklären, wann welche Variablen gehen und wann nicht.

Nachtrag: Wenn ich noch ein Beispiel für CustomIntent (Attribut + myUtils-Codeschnipsel) bekomme, kann ggf. auch mal checken, ob man das noch vereinfachen kann bzw. auch im helper-hash vorhalten. Werde im Moment aber aus dem Code nicht recht schlau, was der eigentlich im einzelnen tun soll...
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

Jetzt ist da halt wieder das Problem, dass nur ein Device/Raum/etc. übergeben wird ;)

drhirn

#161
print Dumper(@arr) in Zeile 385 bring:

$VAR1 = 'Musik';


print Dumper(@devices) in Zeile 433 meldet

$VAR1 = 'Musik';
$VAR2 = 'deckenlampe';
$VAR3 = 'licht';
$VAR4 = 'lampe';
$VAR5 = 'radio';
$VAR6 = 'licht';


Und ein print Dumper (@_) in Zeile 381

$VAR1 = 'Musik';
$VAR2 = 'deckenlampe';
$VAR3 = 'licht';
$VAR4 = 'lampe';
$VAR5 = 'radio';
$VAR6 = 'licht';
$VAR7 = 1;


Sehr verwirrend

Und wenn das für's Verständnis hilft, hier ist die DEF der "Deckenlampe":

defmod lampe1 dummy
attr lampe1 userattr lightSceneParamsToSave lightSceneRestoreOnlyIfChanged:1,0 rhasspyChannels:textField-long rhasspyColors:textField-long
attr lampe1 readingList brightness rgb
attr lampe1 rhasspyChannels orf eins=set lampe1 on\
orf zwei=set lampe1 off\
orf drei=set lampe1 on
attr lampe1 rhasspyColors rot=rgb FF0000\
grün=rgb 00FF00\
blau=rgb 0000FF\
gelb=rgb 00F000
attr lampe1 rhasspyMapping SetOnOff:cmdOn=on,cmdOff=off\
GetOnOff:currentVal=state,valueOff=off\
GetNumeric:currentVal=brightness,type=Helligkeit\
SetNumeric:currentVal=brightness,minVal=0,maxVal=255,map=percent,cmd=brightness,step=1,type=Helligkeit\

attr lampe1 rhasspyName deckenlampe,licht
attr lampe1 rhasspyRoom küche,bad
attr lampe1 room Rhasspy
attr lampe1 setList brightness rgb toggle on off
attr lampe1 useSetExtensions 1

Beta-User

#162
Hmm, habe zwischenzeitlich wieder in Richtung der Ausgangsversion umgebaut.

Das hier ist dir vermutlich entgangen:
Zitat von: Beta-User am 02 März 2021, 15:28:45
Nachtrag: Wenn ich noch ein Beispiel für CustomIntent (Attribut + myUtils-Codeschnipsel) bekomme, kann ggf. auch mal checken, ob man das noch vereinfachen kann bzw. auch im helper-hash vorhalten. Werde im Moment aber aus dem Code nicht recht schlau, was der eigentlich im einzelnen tun soll...
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

#163
Updating Rhasspy Slots with data (de): {"de.fhem.Color":["HASH(0x56360372fdf8)"],"de.fhem.Device":["HASH(0x56360372f870)"].... :D

Sorry, das ist mir wirklich entgangen. Ich hab nur den einen Custom Intent von JensS. Hab das nie verwendet. Der sieht aber auf jeden Fall so aus:


sub Respeak(){
    my $name = "Rhasspy"; # Rhasspy durch eigenen Rhasspy-Device-Namen ersetzen
    my $Response = ReadingsVal($name,"voiceResponse","Ich kann mich nicht mehr erinnern");
    return $Response;
}


Und das Rhasspy-Attribut dazu:

attr Rhasspy rhasspyIntents Respeak=Respeak()



--edit--
Da wäre noch die Erklärung von Thyraz dazu für's Snips-Modul: https://github.com/Thyraz/Snips-Fhem#f%C3%BCr-fortgeschrittene-eigene-custom-intents-erstellen-und-in-fhem-darauf-reagieren

Beta-User

#164
OK, das könnte weiterhelfen...

Hab's jetzt an anderer Stelle dereferenziert und vollends (?) auf die get_unique() umgebaut...

Was custom intent angeht, scheint das via parseParams dann wirklich einfacher zu gehen, mal sehen.
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