Perl - Modul 10_RHASSPY.pm "professionalisieren"

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

Vorheriges Thema - Nächstes Thema

drhirn

playWav geht nicht mehr. $namedParams ist leer.
Drum hatte ich das umgebaut. In $cmd steht eh alles drinnen, was wir brauchen.

drhirn

Aber mal was ganz was anderes, damit ich das auch noch verstehe.

Ich hab - weil ich gerade eine neu bekommen habe - einen Shelly Motion mit dem Rhasspy-MQTT verbunden. Und die "subscriptions" vom MQTT2_CLIENT um "shellies/+" ergänzt.

Das Device sieht so aus:

defmod MQTT2_rhasspyMQTT2 MQTT2_DEVICE rhasspyMQTT2
attr MQTT2_rhasspyMQTT2 IODev rhasspyMQTT2
attr MQTT2_rhasspyMQTT2 model shellymotion
attr MQTT2_rhasspyMQTT2 readingList rhasspyMQTT2:shellies/announce:.* { json2nameValue($EVENT) }\
rhasspyMQTT2:shellies/shellymotionsensor-60A42397610C/status:.* { json2nameValue($EVENT) }\
rhasspyMQTT2:shellies/shellymotionsensor-60A42397610C/online:.*  online


Stimmt das so? Irgendwie glaube ich ja. Weil zumindest die "annouce"-Readings angelegt und aktualisiert werden. Alle anderen aber nicht.

Da ich mir sicher bin, dass die Frage irgendwann kommt: Ist das die richtige Vorgangsweise und wie bekomme ich die anderen Readings auch noch?

Beta-User

#182
Zitat von: drhirn am 05 März 2021, 15:19:12
playWav geht nicht mehr. $namedParams ist leer.
Drum hatte ich das umgebaut. In $cmd steht eh alles drinnen, was wir brauchen.
OK, anbei der Versuch, das playWav wieder auf deinen Stand zurückzudrehen, Media Control sollte jetzt auch spanisch können...
(Falls du Test-dummies und topic/payload hast, kann ich gerne auch versuchen, das zu testen...)

(Werde noch versuchen, auch die noch fehlenden "isNumber"-Referenzen zu ergänzen, dann sollte das erst mal soweit vollständig sein).

Zitat von: drhirn am 05 März 2021, 15:39:43
Aber mal was ganz was anderes, damit ich das auch noch verstehe.
[...]
Da ich mir sicher bin, dass die Frage irgendwann kommt: Ist das die richtige Vorgangsweise und wie bekomme ich die anderen Readings auch noch?
Prinzipiell sollte das Erweitern der subscriptions (und Aktivieren von autocreate/simple) der richtige Weg sein, es kommt ja auch was an.

ABER: Man sollte bei CLIENT ein "Sortierdevice" zwischenschalten, weil sonst alles, was über den CLIENT kommt erst man per autocreate dem Device zugeschlagen wird, das die passende CID hat, also bei dir MQTT2_rhasspyMQTT2 (CID: rhasspyMQTT2). Daher: dieses Device via attrTemplate (General bridge oder so) mit einer bridgeRegexp versehen. Dann verhält sich das (bei default-Topics in den externen Clients wie dem Shelly) zusammen fast wie MQTT2_SERVER und "sortiert" passenden Input dann jeweils in ein eigenes Device.

Das ganze hat aber noch einen "Haken": über den "shellies/"-Topic kommen auch die an die Shelly gerichteten Kommandos wieder zurück. Daher sollte man die via ignoreRegexp am IO "ausknipsen".
Das war jetzt die "Kurzform"...

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

Und die bridgeRegexp, lass ich die so? Shellie kommt ja vor. Oder soll ich da alle anderen Einträge löschen?

Beta-User

Zitat von: JensS am 05 März 2021, 15:47:10
@drhirn && Beta-User
Die Möglichkeiten von Rhasspy sind u.a. durch CustomIntents erweiterbar. Ist es möglich/ratsam, die Erweiterungen in separate .pms in einem Unterordner RHASSPY zu legen und diese über Github zentral zur Verfügung zu stellen? So könnte man sich sein Rhasspy, je nach Bedarf, durch wenige Anpassungen zusammenstellen.
Vielleicht nochmal in dem Zusammenhang eine kurze Bezugnahme auf das hier:
Zitat von: Beta-User am 04 März 2021, 08:04:54
- Der Parser für die eigenen Intents ist umgebaut, und der Weg macht nach meinem jetzigen Verständnis auch Sinn, wenn man Parameter aus der Rhasspy-Analyse mitgeben will (wie bei der Wikipedia-Anfrage). Anm.: Für parameterlose Perl-aufrufe ist m.E. der Shortcuts-Weg der elegantere.

Allerdings ist mir völlig unklar, warum da scheinbar immer der $hash (->RHASSPY-Instanz) mit übergeben wird? Müßte eigentlich bei der hier üblichen Notation der Perl-Funktionen in myUtils mit Prototypen Mismatches werfen. Aber vielleicht übersehe ich auch mal wieder was...
Stand: Ungetestet.

Generell bin ich bei drhirn: Wenn es möglich ist, die Aufgabe außerhalb von FHEM abzuwickeln, haben vermutlich mehr Leute was davon, wenn man die Möglichkeiten der Rhasspy-scripte erweitert.

Ich sehe daher die beiden Optionen "Shortcut" und "rhasspyIntents" eher als Option, flexibel eine Interaktion zu ermöglichen, bei der wirklich FHEM benötigt wird.
Interessiert mich in der Perl-Verarbeitung nichts, was Rhasspy an Infos mitschickt, sollte m.E. der "Shortcut"-Weg gewählt werden, da sind (hoffentlich) die Möglichkeiten einfacher, z.B. über den "r:"-Parameter auch sprach-agnostische Rückmeldungen einzubauen (will sagen: kann der User leichter anpassen, wie wenn er in myUtils rumfrickeln muss).
NUR, wenn für die Weiterverarbeitung in Perl Parameter aus der Vorverarbeitung in Rhasspy übergeben werden sollen, macht es m.E. überhaupt Sinn, über rhassypIntents zu gehen.
(So würde ich das auch in der cref darstellen; ad cref noch: ich würde empfehlen, die "named parameter"-Darstellung dort aufzunehmen, die "alte" Schreibweise ist nur ein Kompabilitäts-feature...)

(Ggf. könnten wir überlegen, ob wir die Option in Shortcuts einbauen sollten, $data komplett zu bekommen; funktioniert evtl. sogar heute schon). Dann macht rhassypIntents an sich wenig Sinn (außer für Kompabilität und um es dem geneigten User zu ersparen, ausdrückliche Hash-Werte abzufragen).

Mit beiden Parsern habe ich mich aber nur soweit beschäftigt, dass es kompatibel sein sollte; kann durchaus sein, dass es Optimierungsmöglichkeiten gibt.

Zitat von: drhirn am 05 März 2021, 16:16:43
Und die bridgeRegexp, lass ich die so? Shellie kommt ja vor. Oder soll ich da alle anderen Einträge löschen?
Laß, wie ist, schadet kaum. Du wirst sonst irgendwann wieder an mich denken, wenn du einen Tasmota in Betrieb nimmst oder sonst irgendwas, was grade noch nicht rumfleucht...
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

#185
So, zum krönenden Abschluss noch was zum Testen, jetzt sollte es auch spanische (oder zumindest englische) Rückmeldungen aus RHASSPY_handleIntentGetNumeric() geben können, und ein paar Klammern etc. habe ich auch noch "erlegt" (in der Hoffnung, dass es trotzdem noch korrekt tut, aber übersichtlicher ist...
(McCabe meint, es sei einfacher, aber das halte ich für ein Gerücht ;D ...)
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: Beta-User am 04 März 2021, 08:04:54
Allerdings ist mir völlig unklar, warum da scheinbar immer der $hash (->RHASSPY-Instanz) mit übergeben wird? Müßte eigentlich bei der hier üblichen Notation der Perl-Funktionen in myUtils mit Prototypen Mismatches werfen. Aber vielleicht übersehe ich auch mal wieder was...
Ok, habe jetzt rund um die App-Beiträge gesehen, wann es eingebaut wurde.

Rückmeldung: Finde das in der jetzigen Form nicht gut, das Prinzip sollte sein, dass man zurückbekommt, was man "bestellt", dann wird auch der Unterschied zu "Shortcuts" für den Anwender m.E. klarer erkennbar.
Würde daher vorschlagen, dass wir ein paar "Keywords" einbauen, damit man "HASH", "NAME" und "DATA" "bestellen" kann, also optional. V.a. an @JensS: Einwände oder bessere Vorschläge?

Zitat von: Beta-User am 04 März 2021, 16:33:17
Wenn das klappt, müßte man erst überlegen, ob die JSON-Struktur so "gut" (auch im Sinne von ggf. ausbaufähig) ist [...]
Die Hash-Struktur war irgendwie sehr aus dem Handgelenk geschüttelt, wenn es also mit den ganzen Referenzierungen klappt wie erhofft, sollte man die m.E. schnellstmöglich überarbeiten, ich glaube nämlich _nicht_, dass mir an der Stelle mehr gelungen ist wie "funktioniert halt irgendwie und ist nicht komplett seltsam"...
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

@JensS:
Danke für die schnelle Rückmeldung.
So?
sub RHASSPY_handleCustomIntent {
    my $hash       = shift // return;
    my $intentName = shift;
    my $data       = shift;
   
    if (!defined $hash->{helper}{custom} || !defined $hash->{helper}{custom}{$intentName}) {
        Log3($hash->{NAME}, 2, "handleIntentShortcuts called with invalid $intentName key");
        return;
    }
    my $custom = $hash->{helper}{custom}{$intentName};
    Log3($hash->{NAME}, 5, "handleCustomIntent called with $intentName key");
   
    my ($intent, $response, $room);

    if (exists $data->{Device} ) {
      $room = RHASSPY_roomName($hash, $data);
      $data->{Device} = RHASSPY_getDeviceByName($hash, $room, $data->{Device}); #Beta-User: really...?
    }

    my $subName = $custom->{function};
    my @paramNames = $custom->{args};

    if (defined $subName) { #might not be necessary...
        my @params;
        for (@paramNames) {
            if ($_ eq 'NAME') {
               $_ = $hash->{NAME};
            } elsif ($_ eq 'HASH') {
               $_ = $hash;
            } elsif ($_ eq 'DATA') {
                $_ = $data;
            } elsif (defined $data->{$_}) {   
                $_ = $data->{$_}
            }
        }
        my $params = join q{,}, @params;
        my $cmd = qq{ $subName( $params) };
        Log3($hash->{NAME}, 5, "Calling sub: $cmd");
        my $error = AnalyzePerlCommand($hash, $cmd);
        $response = $error if $error !~ m{Please.define.*first}x;
     
    }
    $response = $response // RHASSPY_getResponse($hash, 'DefaultError');

    # Antwort senden
    return RHASSPY_respond ($hash, $data->{requestType}, $data->{sessionId}, $data->{siteId}, $response);
}

(Wobei mir grade 'DefaultError' komisch vorkommt...)
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: JensS am 06 März 2021, 11:09:39
@Beta-User
Wie sieht dann mein Respeak 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;
}


Gruß Jens
Biete mal 3-4 Alternativen an:
1. Aufruf ohne Parameter im Attribut: (Respeak=Respeak())
a)
Deine Variante sollte wie bisher funktionieren (mit deiner Version der sub in der .pm müßte es eigentlich einen Prototype-missmatch gegeben haben?).
b)
ohne Prototype gingen beide Varianten der sub in  der .pm:
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;
}


2. Aufruf mit Parameter im Attribut:
Wenn man die eigentlichen features dieses Attributs nutzen will, kann man (im Attribut) mit Parameter definieren; jetzt sollten gehen:
a) Respeak(NAME)

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

Erläuterung: "//" ist "Perl-defined-or-operator. Gibt es was zum shiften, wird das als $name verwendet, ansonsten eben der dahinter hart vercodete Name.
Dies Variante funktioniert also auch, wenn man keinen NAME-Parameter angegeben hat...

b) Respeak(HASH)
sub Respeak {
my $hash = shift // return;
my $name = $hash->{NAME};
my $Response = ReadingsVal($name,"voiceResponse","Ich kann mich nicht mehr erinnern");
return $Response;
}

Hier geht dann ohne HASH nichts mehr...

So sieht man auch, warum es a) bisher ggf. Probleme gab, wenn man das "Zwangshash" übersehen hatte ($hash wird btw. in FHEM üblicherweise als erster Parameter übergeben...),
b) warum die shift-Variante ggf. direkter ist, was Ersatzwert-Zuweisung angeht;
c) dass das mit den Prototype-Definitionen nicht in allen Fällen (auch für Einsteiter) hilfreich ist.

Hoffe, das halbwegs verständlich aufgedröhselt zu haben?

(Anm.: Das feature "spiel's noch einmal, Sam!" würde ich als Standardfeature ansehen und vorschlagen, es direkt in das Modul zu integrieren. Soll aber der Maintainer entscheiden :P .
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: JensS am 06 März 2021, 13:06:52
@Beta-User
Alternative 2.a) hatte ich genau so gemacht. [...] Allerdings bringt shift nichts - es wird immer die Ersetzung bei undef gemacht. Sobald ich "Rhasspie" schreibe, hat Alexa Alzheimer.
::)
Zu schnell gestrickt meinerseits.

So könnte es klappen:
sub RHASSPY_handleCustomIntent {
    my $hash       = shift // return;
    my $intentName = shift;
    my $data       = shift;
   
    if (!defined $hash->{helper}{custom} || !defined $hash->{helper}{custom}{$intentName}) {
        Log3($hash->{NAME}, 2, "handleIntentShortcuts called with invalid $intentName key");
        return;
    }
    my $custom = $hash->{helper}{custom}{$intentName};
    Log3($hash->{NAME}, 5, "handleCustomIntent called with $intentName key");
   
    my ($intent, $response, $room);

    if (exists $data->{Device} ) {
      $room = RHASSPY_roomName($hash, $data);
      $data->{Device} = RHASSPY_getDeviceByName($hash, $room, $data->{Device}); #Beta-User: really...?
    }

    my $subName = $custom->{function};
    my @params = $custom->{args};

    if (defined $subName) { #might not be necessary...
        for (@params) {
            if ($_ eq 'NAME') {
               $_ = $hash->{NAME};
            } elsif ($_ eq 'DATA') {
                $_ = $data;
            } elsif (defined $data->{$_}) {   
                $_ = $data->{$_}
            }
        }
        my $params = join q{,}, @params;
        my $cmd = qq{ $subName( $params) };
        Log3($hash->{NAME}, 5, "Calling sub: $cmd");
        my $error = AnalyzePerlCommand($hash, $cmd);
        $response = $error if $error !~ m{Please.define.*first}x;
     
    }
    $response = $response // RHASSPY_getResponse($hash, 'DefaultError');

    # Antwort senden
    return RHASSPY_respond ($hash, $data->{requestType}, $data->{sessionId}, $data->{siteId}, $response);
}

"HASH" habe ich gleich wieder rausgeworfen, weil es m.E. ausreicht, wenn man eines von beidem zurückgibt. Habe zugunsten des NAME entschieden; für die Anwender ist es in der Regel einfacher, und wer Funktionen für "intern" vorbereiten will, kann den Hash auch aus %defs holen...
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

Mal für den Merkzettel:
Befehl nur mit Bestätigung ausführen, https://forum.fhem.de/index.php/topic,118986.0.html.

Vermutlich wäre sowas nicht allzu schwer zu verwirklichen, wenn man es erlaubt, genau einen Befehl zu "parken", zumindest iVm. "Shortcut". Da würde man einfach einen weiteren Parameter dazupacken (c=1 für "confirmation required" oder "c='soll ich wirklich den Server neu starten' ).

Nur, weil ich grade drüber gestolpert bin...
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

Hab jetzt auch die letzten Änderungen ins GitHub übernommen (0.4.0beta). Danke!

Zitat von: Beta-User am 05 März 2021, 17:27:32
und ein paar Klammern etc. habe ich auch noch "erlegt" (in der Hoffnung, dass es trotzdem noch korrekt tut, aber übersichtlicher ist...

Ist lustig, ich bin gewöhnt, dass man in jeder Programmiersprache, die ich "kenne", Klammern (richtig) setzen MUSS. Macht mich fertig, dass das da nicht so ist ;). Ich persönlich find's mit Klammern übrigens übersichtlicher.

Und jetzt seh ich mir den Rest eurer Unterhaltung an. Mir ist da im Überfliegen eine gute Idee von dir ins Auge gesprungen.

drhirn

Mir ist gerade etwas beim Intent MediaControls bezüglich Sprache aufgefallen:

Man definiert einen Satz in Rhasspy z.B. so:
starte{Command:play} die wiedergabe $de.fhem.Device{Device}

Das Zeug in geschwungener Klammer, unter welchem "Namen" der Text davor in FHEM ankommt.
Z.B. bei Device wäre das dann Device=>Radio

Man kann aber für einen erkannten Text auch angeben, was in FHEM ankommen soll. Passiert in diesem Beispiel bei "{Command:play}". Wenn ich also "starte Radio" spreche, kommt in FHEM play Radio an.

play, stop, ... dürfen wir also nicht aus dem Sprach-File nehmen. Das muss immer gleich bleiben.

Wir können natürlich schon die jeweilige Sprache nehmen. Dann laufen wir aber Gefahr, dass der User etwas anderes in seinen Rhasspy-Sentences eingetragen hat, was wir in unserer Sprach-Datei haben.

Dasselbe auch bei GetNumeric.

Ich bastel dir übrigens gerade eine Liste mit Payloads, damit du testen kannst.

drhirn

Das folgende File ist auch im GitHub. Ist ein Test-Device und Payloads für alle momentan verfügbaren Intents.

In der CRef habe ich übrigens ganz unten eine ToDo-Liste angehängt.


----Device----
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,response=Okidoki\
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\
Status:response=Die Temperatur in der Küche beträgt [lampe1:brightness] Grad\
MediaControls:cmdPlay=play,cmdPause=pause,cmdStop=stop,cmdBack=previous,cmdFwd=next\

attr lampe1 rhasspyName deckenlampe,licht,radio
attr lampe1 rhasspyRoom küche,bad
attr lampe1 room Rhasspy
attr lampe1 setList brightness rgb toggle on off play stop pause next previous

----Payloads----
SetMute
Msg: hermes/intent/de.fhem_SetMute => {"input": "on", "intent": {"intentName": "de.fhem:SetMute", "confidenceScore": 1.0}, "siteId": "wohnzimmer", "id": null, "slots": [{"entity": "Value", "value": {"kind": "Unknown", "value": "on"}, "slotName": "Value", "rawValue": "gute nacht", "confidence": 1.0, "range": {"start": 0, "end": 2, "rawStart": 0, "rawEnd": 10}}], "sessionId": "wohnzimmer-snowboy-4db538ac-d4ad-4633-af0d-79134ea856c7", "customData": null, "asrTokens": [[{"value": "on", "confidence": 1.0, "rangeStart": 0, "rangeEnd": 2, "time": null}]], "asrConfidence": null, "rawInput": "gute nacht", "wakewordId": "snowboy", "lang": null}
Msg: hermes/intent/de.fhem_SetMute => {"input": "off", "intent": {"intentName": "de.fhem:SetMute", "confidenceScore": 1.0}, "siteId": "wohnzimmer", "id": null, "slots": [{"entity": "Value", "value": {"kind": "Unknown", "value": "off"}, "slotName": "Value", "rawValue": "guten morgen", "confidence": 1.0, "range": {"start": 0, "end": 3, "rawStart": 0, "rawEnd": 12}}], "sessionId": "wohnzimmer-snowboy-9cafa03f-726f-4076-a123-25634dd8899f", "customData": null, "asrTokens": [[{"value": "off", "confidence": 1.0, "rangeStart": 0, "rangeEnd": 3, "time": null}]], "asrConfidence": null, "rawInput": "guten morgen", "wakewordId": "snowboy", "lang": null}

Shortcuts:
Msg: hermes/intent/de.fhem_Shortcuts => {"input": "ton an", "intent": {"intentName": "de.fhem:Shortcuts", "confidenceScore": 1.0}, "siteId": "wohnzimmer", "id": null, "slots": [], "sessionId": "wohnzimmer-snowboy-cc4118d8-cb3b-4eb5-b4ed-99f18bb0fd85", "customData": null, "asrTokens": [[{"value": "ton", "confidence": 1.0, "rangeStart": 0, "rangeEnd": 3, "time": null}, {"value": "an", "confidence": 1.0, "rangeStart": 4, "rangeEnd": 6, "time": null}]], "asrConfidence": null, "rawInput": "ton an", "wakewordId": "snowboy", "lang": null}

SetOnOff:
Msg: hermes/intent/de.fhem_SetOnOff => {"input": "licht küche aus", "intent": {"intentName": "de.fhem:SetOnOff", "confidenceScore": 1.0}, "siteId": "wohnzimmer", "id": null, "slots": [{"entity": "de.fhem.Device", "value": {"kind": "Unknown", "value": "licht"}, "slotName": "Device", "rawValue": "licht", "confidence": 1.0, "range": {"start": 0, "end": 5, "rawStart": 0, "rawEnd": 5}}, {"entity": "de.fhem.Room", "value": {"kind": "Unknown", "value": "küche"}, "slotName": "Room", "rawValue": "küche", "confidence": 1.0, "range": {"start": 6, "end": 11, "rawStart": 6, "rawEnd": 11}}, {"entity": "OnOffValue", "value": {"kind": "Unknown", "value": "aus"}, "slotName": "Value", "rawValue": "aus", "confidence": 1.0, "range": {"start": 12, "end": 15, "rawStart": 12, "rawEnd": 15}}], "sessionId": "wohnzimmer-snowboy-2ee5ec15-58f4-41ad-aef7-63ec373714ab", "customData": null, "asrTokens": [[{"value": "licht", "confidence": 1.0, "rangeStart": 0, "rangeEnd": 5, "time": null}, {"value": "küche", "confidence": 1.0, "rangeStart": 6, "rangeEnd": 11, "time": null}, {"value": "aus", "confidence": 1.0, "rangeStart": 12, "rangeEnd": 15, "time": null}]], "asrConfidence": null, "rawInput": "licht küche aus", "wakewordId": "snowboy", "lang": null}

GetOnOff:
Msg: hermes/intent/de.fhem_GetOnOff => {"input": "läuft radio wohnzimmer", "intent": {"intentName": "de.fhem:GetOnOff", "confidenceScore": 1.0}, "siteId": "wohnzimmer", "id": null, "slots": [{"entity": "Status", "value": {"kind": "Unknown", "value": "läuft"}, "slotName": "Status", "rawValue": "läuft", "confidence": 1.0, "range": {"start": 0, "end": 5, "rawStart": 0, "rawEnd": 5}}, {"entity": "de.fhem.Device", "value": {"kind": "Unknown", "value": "radio"}, "slotName": "Device", "rawValue": "radio", "confidence": 1.0, "range": {"start": 6, "end": 11, "rawStart": 6, "rawEnd": 11}}, {"entity": "de.fhem.Room", "value": {"kind": "Unknown", "value": "wohnzimmer"}, "slotName": "Room", "rawValue": "wohnzimmer", "confidence": 1.0, "range": {"start": 12, "end": 22, "rawStart": 12, "rawEnd": 22}}], "sessionId": "wohnzimmer-snowboy-9b65e415-bbd3-408b-80ae-651a0c9b7c2e", "customData": null, "asrTokens": [[{"value": "läuft", "confidence": 1.0, "rangeStart": 0, "rangeEnd": 5, "time": null}, {"value": "radio", "confidence": 1.0, "rangeStart": 6, "rangeEnd": 11, "time": null}, {"value": "wohnzimmer", "confidence": 1.0, "rangeStart": 12, "rangeEnd": 22, "time": null}]], "asrConfidence": null, "rawInput": "läuft radio wohnzimmer", "wakewordId": "snowboy", "lang": null}

SetNumeric:
Msg: hermes/intent/de.fhem_SetNumeric => {"input": "deckenlampe auf 50 prozent", "intent": {"intentName": "de.fhem:SetNumeric", "confidenceScore": 1.0}, "siteId": "wohnzimmer", "id": null, "slots": [{"entity": "de.fhem.Device", "value": {"kind": "Unknown", "value": "deckenlampe"}, "slotName": "Device", "rawValue": "deckenlampe", "confidence": 1.0, "range": {"start": 0, "end": 11, "rawStart": 0, "rawEnd": 11}}, {"entity": "rhasspy/number", "value": {"kind": "Number", "value": 50}, "slotName": "Value", "rawValue": "fünfzig", "confidence": 1.0, "range": {"start": 16, "end": 18, "rawStart": 16, "rawEnd": 23}}, {"entity": "Unit", "value": {"kind": "Unknown", "value": "prozent"}, "slotName": "Unit", "rawValue": "prozent", "confidence": 1.0, "range": {"start": 19, "end": 26, "rawStart": 24, "rawEnd": 31}}], "sessionId": "wohnzimmer-snowboy-0ae191fc-c0d7-47f5-9ead-8d19e7302c39", "customData": null, "asrTokens": [[{"value": "deckenlampe", "confidence": 1.0, "rangeStart": 0, "rangeEnd": 11, "time": null}, {"value": "auf", "confidence": 1.0, "rangeStart": 12, "rangeEnd": 15, "time": null}, {"value": "50", "confidence": 1.0, "rangeStart": 16, "rangeEnd": 18, "time": null}, {"value": "prozent", "confidence": 1.0, "rangeStart": 19, "rangeEnd": 26, "time": null}]], "asrConfidence": null, "rawInput": "deckenlampe auf fünfzig prozent", "wakewordId": "snowboy", "lang": null}
Msg: hermes/intent/de.fhem_SetNumeric => {"input": "deckenlampe auf 25", "intent": {"intentName": "de.fhem:SetNumeric", "confidenceScore": 1.0}, "siteId": "wohnzimmer", "id": null, "slots": [{"entity": "de.fhem.Device", "value": {"kind": "Unknown", "value": "deckenlampe"}, "slotName": "Device", "rawValue": "deckenlampe", "confidence": 1.0, "range": {"start": 0, "end": 11, "rawStart": 0, "rawEnd": 11}}, {"entity": "rhasspy/number", "value": {"kind": "Number", "value": 25}, "slotName": "Value", "rawValue": "fünfundzwanzig", "confidence": 1.0, "range": {"start": 16, "end": 18, "rawStart": 16, "rawEnd": 30}}], "sessionId": "wohnzimmer-snowboy-8f199cba-d4c6-46e5-989e-08ec167c20ea", "customData": null, "asrTokens": [[{"value": "deckenlampe", "confidence": 1.0, "rangeStart": 0, "rangeEnd": 11, "time": null}, {"value": "auf", "confidence": 1.0, "rangeStart": 12, "rangeEnd": 15, "time": null}, {"value": "25", "confidence": 1.0, "rangeStart": 16, "rangeEnd": 18, "time": null}]], "asrConfidence": null, "rawInput": "deckenlampe auf fünfundzwanzig", "wakewordId": "snowboy", "lang": null}

GetNumeric:
Msg: hermes/intent/de.fhem_GetNumeric => {"input": "Helligkeit deckenlampe im bad", "intent": {"intentName": "de.fhem:GetNumeric", "confidenceScore": 1.0}, "siteId": "wohnzimmer", "id": null, "slots": [{"entity": "Type", "value": {"kind": "Unknown", "value": "Helligkeit"}, "slotName": "Type", "rawValue": "helligkeit", "confidence": 1.0, "range": {"start": 0, "end": 10, "rawStart": 0, "rawEnd": 10}}, {"entity": "de.fhem.Device", "value": {"kind": "Unknown", "value": "deckenlampe"}, "slotName": "Device", "rawValue": "deckenlampe", "confidence": 1.0, "range": {"start": 11, "end": 22, "rawStart": 11, "rawEnd": 22}}, {"entity": "de.fhem.Room", "value": {"kind": "Unknown", "value": "bad"}, "slotName": "Room", "rawValue": "bad", "confidence": 1.0, "range": {"start": 26, "end": 29, "rawStart": 26, "rawEnd": 29}}], "sessionId": "wohnzimmer-snowboy-b6d9df29-fb48-48b5-b0bb-1658e229e8dd", "customData": null, "asrTokens": [[{"value": "Helligkeit", "confidence": 1.0, "rangeStart": 0, "rangeEnd": 10, "time": null}, {"value": "deckenlampe", "confidence": 1.0, "rangeStart": 11, "rangeEnd": 22, "time": null}, {"value": "im", "confidence": 1.0, "rangeStart": 23, "rangeEnd": 25, "time": null}, {"value": "bad", "confidence": 1.0, "rangeStart": 26, "rangeEnd": 29, "time": null}]], "asrConfidence": null, "rawInput": "helligkeit deckenlampe im bad", "wakewordId": "snowboy", "lang": null}

Status:
Msg: hermes/intent/de.fhem_Status => {"input": "wie ist der status licht bad", "intent": {"intentName": "de.fhem:Status", "confidenceScore": 1.0}, "siteId": "wohnzimmer", "id": null, "slots": [{"entity": "Status", "value": {"kind": "Unknown", "value": "status"}, "slotName": "Status", "rawValue": "status", "confidence": 1.0, "range": {"start": 12, "end": 18, "rawStart": 12, "rawEnd": 18}}, {"entity": "de.fhem.Device", "value": {"kind": "Unknown", "value": "licht"}, "slotName": "Device", "rawValue": "licht", "confidence": 1.0, "range": {"start": 19, "end": 24, "rawStart": 19, "rawEnd": 24}}, {"entity": "de.fhem.Room", "value": {"kind": "Unknown", "value": "bad"}, "slotName": "Room", "rawValue": "bad", "confidence": 1.0, "range": {"start": 25, "end": 28, "rawStart": 25, "rawEnd": 28}}], "sessionId": "wohnzimmer-snowboy-6906f9f6-f7bf-416c-bc07-78da7bc2ef7d", "customData": null, "asrTokens": [[{"value": "wie", "confidence": 1.0, "rangeStart": 0, "rangeEnd": 3, "time": null}, {"value": "ist", "confidence": 1.0, "rangeStart": 4, "rangeEnd": 7, "time": null}, {"value": "der", "confidence": 1.0, "rangeStart": 8, "rangeEnd": 11, "time": null}, {"value": "status", "confidence": 1.0, "rangeStart": 12, "rangeEnd": 18, "time": null}, {"value": "licht", "confidence": 1.0, "rangeStart": 19, "rangeEnd": 24, "time": null}, {"value": "bad", "confidence": 1.0, "rangeStart": 25, "rangeEnd": 28, "time": null}]], "asrConfidence": null, "rawInput": "wie ist der status licht bad", "wakewordId": "snowboy", "lang": null}

MediaControls:
Msg: hermes/intent/de.fhem_MediaControls => {"input": "previous lied radio bad", "intent": {"intentName": "de.fhem:MediaControls", "confidenceScore": 1.0}, "siteId": "wohnzimmer", "id": null, "slots": [{"entity": "Command", "value": {"kind": "Unknown", "value": "previous"}, "slotName": "Command", "rawValue": "voriges", "confidence": 1.0, "range": {"start": 0, "end": 8, "rawStart": 0, "rawEnd": 7}}, {"entity": "de.fhem.Device", "value": {"kind": "Unknown", "value": "radio"}, "slotName": "Device", "rawValue": "radio", "confidence": 1.0, "range": {"start": 14, "end": 19, "rawStart": 13, "rawEnd": 18}}, {"entity": "de.fhem.Room", "value": {"kind": "Unknown", "value": "bad"}, "slotName": "Room", "rawValue": "bad", "confidence": 1.0, "range": {"start": 20, "end": 23, "rawStart": 19, "rawEnd": 22}}], "sessionId": "wohnzimmer-snowboy-7b7bdb95-93f5-4a3a-b386-d3cff3e37828", "customData": null, "asrTokens": [[{"value": "previous", "confidence": 1.0, "rangeStart": 0, "rangeEnd": 8, "time": null}, {"value": "lied", "confidence": 1.0, "rangeStart": 9, "rangeEnd": 13, "time": null}, {"value": "radio", "confidence": 1.0, "rangeStart": 14, "rangeEnd": 19, "time": null}, {"value": "bad", "confidence": 1.0, "rangeStart": 20, "rangeEnd": 23, "time": null}]], "asrConfidence": null, "rawInput": "voriges lied radio bad", "wakewordId": "snowboy", "lang": null}

GetTime:
Msg: hermes/intent/de.fhem_GetTime => {"input": "wie spät ist es", "intent": {"intentName": "de.fhem:GetTime", "confidenceScore": 1.0}, "siteId": "wohnzimmer", "id": null, "slots": [], "sessionId": "wohnzimmer-snowboy-e0312349-ae17-4e92-905a-cce515525efe", "customData": null, "asrTokens": [[{"value": "wie", "confidence": 1.0, "rangeStart": 0, "rangeEnd": 3, "time": null}, {"value": "spät", "confidence": 1.0, "rangeStart": 4, "rangeEnd": 8, "time": null}, {"value": "ist", "confidence": 1.0, "rangeStart": 9, "rangeEnd": 12, "time": null}, {"value": "es", "confidence": 1.0, "rangeStart": 13, "rangeEnd": 15, "time": null}]], "asrConfidence": null, "rawInput": "wie spät ist es", "wakewordId": "snowboy", "lang": null}

GetWeekday:
Msg: hermes/intent/de.fhem_GetWeekday => {"input": "welcher tag ist heute", "intent": {"intentName": "de.fhem:GetWeekday", "confidenceScore": 1.0}, "siteId": "wohnzimmer", "id": null, "slots": [], "sessionId": "wohnzimmer-snowboy-02724c86-d588-45e4-9a7e-5a17345b04f8", "customData": null, "asrTokens": [[{"value": "welcher", "confidence": 1.0, "rangeStart": 0, "rangeEnd": 7, "time": null}, {"value": "tag", "confidence": 1.0, "rangeStart": 8, "rangeEnd": 11, "time": null}, {"value": "ist", "confidence": 1.0, "rangeStart": 12, "rangeEnd": 15, "time": null}, {"value": "heute", "confidence": 1.0, "rangeStart": 16, "rangeEnd": 21, "time": null}]], "asrConfidence": null, "rawInput": "welcher tag ist heute", "wakewordId": "snowboy", "lang": null}

MediaChannels:
Msg: hermes/intent/de.fhem_MediaChannels => {"input": "Schalte um auf orf zwei", "intent": {"intentName": "de.fhem:MediaChannels", "confidenceScore": 1.0}, "siteId": "wohnzimmer", "id": null, "slots": [{"entity": "de.fhem.MediaChannels", "value": {"kind": "Unknown", "value": "orf zwei"}, "slotName": "Channel", "rawValue": "orf zwei", "confidence": 1.0, "range": {"start": 15, "end": 23, "rawStart": 15, "rawEnd": 23}}], "sessionId": "wohnzimmer-snowboy-6665801a-8946-4ff2-82a8-d3be87fcc60c", "customData": null, "asrTokens": [[{"value": "Schalte", "confidence": 1.0, "rangeStart": 0, "rangeEnd": 7, "time": null}, {"value": "um", "confidence": 1.0, "rangeStart": 8, "rangeEnd": 10, "time": null}, {"value": "auf", "confidence": 1.0, "rangeStart": 11, "rangeEnd": 14, "time": null}, {"value": "orf", "confidence": 1.0, "rangeStart": 15, "rangeEnd": 18, "time": null}, {"value": "zwei", "confidence": 1.0, "rangeStart": 19, "rangeEnd": 23, "time": null}]], "asrConfidence": null, "rawInput": "schalte um auf orf zwei", "wakewordId": "snowboy", "lang": null}

SetColor:
Msg: hermes/intent/de.fhem_SetColor => {"input": "schalte deckenlampe blau", "intent": {"intentName": "de.fhem:SetColor", "confidenceScore": 1.0}, "siteId": "wohnzimmer", "id": null, "slots": [{"entity": "de.fhem.Device", "value": {"kind": "Unknown", "value": "deckenlampe"}, "slotName": "Device", "rawValue": "deckenlampe", "confidence": 1.0, "range": {"start": 8, "end": 19, "rawStart": 8, "rawEnd": 19}}, {"entity": "de.fhem.Color", "value": {"kind": "Unknown", "value": "blau"}, "slotName": "Color", "rawValue": "blau", "confidence": 1.0, "range": {"start": 20, "end": 24, "rawStart": 20, "rawEnd": 24}}], "sessionId": "wohnzimmer-snowboy-cad9a0ea-d333-4fde-81a9-924fb576cbc0", "customData": null, "asrTokens": [[{"value": "schalte", "confidence": 1.0, "rangeStart": 0, "rangeEnd": 7, "time": null}, {"value": "deckenlampe", "confidence": 1.0, "rangeStart": 8, "rangeEnd": 19, "time": null}, {"value": "blau", "confidence": 1.0, "rangeStart": 20, "rangeEnd": 24, "time": null}]], "asrConfidence": null, "rawInput": "schalte deckenlampe blau", "wakewordId": "snowboy", "lang": null}

SetTimer:
Msg: hermes/intent/de.fhem_SetTimer => {"input": "taimer im wohnzimmer auf 10 sekunden", "intent": {"intentName": "de.fhem:SetTimer", "confidenceScore": 1.0}, "siteId": "wohnzimmer", "id": null, "slots": [{"entity": "de.fhem.Room", "value": {"kind": "Unknown", "value": "wohnzimmer"}, "slotName": "Room", "rawValue": "wohnzimmer", "confidence": 1.0, "range": {"start": 10, "end": 20, "rawStart": 10, "rawEnd": 20}}, {"entity": "rhasspy/number", "value": {"kind": "Number", "value": 10}, "slotName": "Value", "rawValue": "zehn", "confidence": 1.0, "range": {"start": 25, "end": 27, "rawStart": 25, "rawEnd": 29}}, {"entity": "Unit", "value": {"kind": "Unknown", "value": "sekunden"}, "slotName": "Unit", "rawValue": "sekunden", "confidence": 1.0, "range": {"start": 28, "end": 36, "rawStart": 30, "rawEnd": 38}}], "sessionId": "wohnzimmer-snowboy-63e0d711-7842-4e99-9a65-9a764c9952b3", "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": "wohnzimmer", "confidence": 1.0, "rangeStart": 10, "rangeEnd": 20, "time": null}, {"value": "auf", "confidence": 1.0, "rangeStart": 21, "rangeEnd": 24, "time": null}, {"value": "10", "confidence": 1.0, "rangeStart": 25, "rangeEnd": 27, "time": null}, {"value": "sekunden", "confidence": 1.0, "rangeStart": 28, "rangeEnd": 36, "time": null}]], "asrConfidence": null, "rawInput": "taimer im wohnzimmer auf zehn sekunden", "wakewordId": "snowboy", "lang": null}

Beta-User

#194
So, habe mal wieder etwas nachgedacht und getestet, und will euch weder meine Gedanken noch den Code vorenthalten...

Was ich schon immer "seltsam" fand, war das mit dem "Zwangsraum". Daher gibt es jetzt als Vorschlag einen Parameter für die DEF mit dem sinnigen Namen "devspec". Damit kann man jetzt (hoffentlich) z.B. auch folgendes machen (auch für das folgende: alle Parameter sind optional!):
defmod RHASSPY RHASSPY devspec=room=Rhasspy,room=MQTT2_DEVICE,lampe3,alexaName=.+

Weiter habe ich den Verdacht, dass man ggf. auch weitere Topics bzw. Unterscheidungsmerkmale braucht, wenn man z.B. unterschiedliche FHEM-Instanzen und/oder mehrere User hat, die unterschiedliches dürfen bzw. per RHASSPY ansteuern können sollen. Daher gibt es jetzt vorsorglich mal den Vorschlag, eine "fhemId" vergeben zu können...?
defmod RHASSPY RHASSPY fhemId=fhem2

Generell scheint es so zu sein, dass wir auf der "de->en"-Mapping-Seite ziemlich beschäftigt damit sind, zwischenzeitlich(!) unglücklich gewordene Entscheidungen aus der Vergangenheit wieder gradezubiegen. Paradebeispiel:
starte{Command:play} die wiedergabe $de.fhem.Device{Device}Da frage ich mich, warum dann nicht gleich das passende Mapping an dieser Stelle mitgegeben wird:starte{Command:cmdPlay} die wiedergabe $de.fhem.Device{Device}Das ist auch für einen Franzosen vermutlich recht einfach anzupassen, oder...?
Na jedenfalls sollte der Code mit obiger Schreibweise klarkommen, und daneben noch die "alten" mappings (einschl. "zurück") verstehen, die aber bitte möglichst a) von den Usern umgestellt und b) von der Doku nicht mehr beworben werden sollten.
Da das dann a) statisch ist und b) direkt im Code verwendet werden kann, ist es aus der cfg ganz raus ;) .

Merksatz an der Stelle: "Weniger ist mehr".

Da ich vermute, dass das mit "Helligkeit" und evtl. den meisten anderen "deutschen" Keywords ähnlich ist, würde ich anregen, das mal in diese Richtung zu überdenken.



Was CustomIntents angeht, habe ich zumindest das Respeak mit NAME repariert, ob das ganze auch funktioniert, wenn andere Elemente und insbesondere DATA angefordert werden, habe ich noch nicht ausgetestet...



Was die ToDo's angeht, ist das eine oder andere erledigt, insbesondere die set-Anweisungen sollten jetzt alle triggernd durchlaufen.

Was das "get" angeht, bin ich grade noch etwas ratlos, wie ich das angehen kann bzw. wie eigentlich der Aktionspunkt aussieht.



Vielleicht noch ein paar Hintergedanken zum Thema rhasspyRoom/devspec und mapping:
Wenn "brightness" nicht mehr Helligkeit heißt, kann man auch "raten", dass ein setter/Reading "brightness" ggf. der Wert ist, den man wissen bzw. steuern will, eventuell wäre sogar "pct" in der FHEM-Welt die erste Wahl, die man austestet.
Und wenn es keinen rhasspyName gibt, aber einen alexaName und die devspec paßt, warum sollte man dann nicht die homebridgeMappings ausschlachten und das Device durch RHASSPY ansteuerbar machen?
Das setzt aber ggf. etwas mehr Logik bei der Auswertung der Parameter voraus, von daher wäre an der Stelle ggf. dann wieder der Gedanke: Pack' alles relevante in einen Hash und lies es von da...
Das ist auch der gedankliche Hintergrund, warum die Aktualisierung der language nicht als eigener setter hart vercodet ist, sondern "reinit" künftig auch weitere Parameter zulassen könnte ("devices" oder "all", um mal was völlig willkürliches in den Raum zu werfen...)

Jetzt wünsche ich erst mal viel Spaß beim Testen und freue mich über Rückmeldungen zu meinen Gedanken...
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