Modulentwicklung für Rhasspy Sprachassistent

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

Vorheriges Thema - Nächstes Thema

Beta-User

#45
So, anbei mal die nächste Iteration:
Zitat von: Beta-User am 13 März 2021, 17:13:00
Das mit dem internen Hash für die ganzen Mappings etc. geht auch voran, der nächste Schritt wäre jetzt, die Kommandos so umzubauen, dass sie auf diesen internen Hash zugreifen; ich bin auch noch nicht sicher, ob er vollständig ist.

Soweit ich das bisher beurteilen kann, scheint das - nach einigen kleineren Erweiterungen an der Struktur - zu klappen. Die eine oder andere Kleinigkeit ist mir dann auch noch aufgefallen, Basis war deine 0.4.4beta von gestern.
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...



Betr. des Codepage-Problems:
Habe mal die Option reigeknödelt, "encoding" in der DEF anzugeben, also z.B. "encoding=cp-1252". Das gab aber Schwierigkeiten mit der de-cfg, daher habe ich das dort hart in UTF-8 belassen...
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

Super, werde ich gleich einbauen.

Ich hab derzeit die meisten Probleme mit Set- und GetNumeric.

Bei GetNumeric springen wir z.B. nie in das else von hier:

    if ($mappingType eq 'setTarget'
            || $mappingType=~ m{\A$internal_mappings->{regex}->{setTarget}\z}xim
            || $mappingType=~ m{\A$de_mappings->{regex}->{setTarget}\z}xim) {
        $response = $hash->{helper}{lng}->{Change}->{responses}->{setTarget};
    }
    else {
        $response =
            $hash->{helper}{lng}->{responses}->{Change}->{$mappingType}
        //  $hash->{helper}{lng}->{responses}->{Change}->{$de_mappings->{ToEn}->{$mappingType}}
        //  $hash->{helper}{lng}->{res ponses}->{Change}->{$type}
        //  $hash->{helper}{lng}->{responses}->{Change}->{$de_mappings->{ToEn}->{$type}};
        ;
        #my $isNumber = looks_like_number($value);
        $response = $response->{looks_like_number($value)} if ref $response eq 'HASH';
   }


Aber ich schreib das alles noch genau zusammen und liefer die DEF und Payloads.

Beta-User

#47
Hmm, auf die Schnelle scheint mir da die Logik falsch herum zu sein:

Erst checken, ob wir was spezifisches wissen (heutiges else), dann das etwas unspezifischere (heutiger if-Fall) und zu letzt eben die Auffanglösungen.

Ergäbe zum Testen:
    $response =
        $hash->{helper}{lng}->{Change}->{responses}->{$mappingType}
        //  $hash->{helper}{lng}->{Change}->{responses}->{$de_mappings->{ToEn}->{$mappingType}}
        //  $hash->{helper}{lng}->{Change}->{responses}->{$type}
        //  $hash->{helper}{lng}->{Change}->{responses}->{$de_mappings->{ToEn}->{$type}};
        ;
        $response = $response->{looks_like_number($value)} if ref $response eq 'HASH';

    if (!defined $response && (
            $mappingType=~ m{\A$internal_mappings->{regex}->{setTarget}\z}xim
            || $mappingType=~ m{\A$de_mappings->{regex}->{setTarget}\z}xim)) {
        $response = $hash->{helper}{lng}->{Change}->{responses}->{setTarget};
    }
    $response = $response            #we already are done? ...

Bin aber auf die Schnelle nicht sicher, ob das nicht eine neue Lücke in der Logik ergibt...

EDIT: da war auch der Hash noch nicht umgestellt gewesen, jetzt müsste es eher passen...
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

#48
Scheint der richtige Weg gewesen zu sein, auch, wenn es im Detail dann wieder "seltsam" war...

In der de-cfg fehlte  noch das response-mapping für "setTarget".

Wie dem auch sei, jetzt sollte alles wieder zusammenpassen (?)...
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

#49
Ok, GitHub ist akutell. Danke!

Ich hab gerade ein Verständnisproblem:
Wenn wir von der Annahme ausgehen, dass man bei einem Gerät Soll- und Ist-Temperatur ablesen kann. Wie könnten wir dann folgenden Satz auflösen?

"Wie ist die Temperatur der Heizung"

Die Mappings wären dann ja z.B.:


GetNumeric:currentVal=desired-temp,type=temperature
GetNumeric:currentVal=measured-temp,type=temperature


... In dem man SetTarget nimmt z.B. Ist dann nur ein Rhasspy-Problem.

drhirn

Ach, und weil ich gerade darüber gestolpert bin:

Gab's ein Device mit dem Reading temperature und einem entsprechenden GetNumeric Mapping, konnte man - glaube ich - fragen "wie warm ist es im schlafzimmer". Wäre sehr praktisch.

Beta-User

#51
Verständnisfrage meinerseits: Hat das bisher (bis V. 0.2.x) geklappt :o ?

Auf so eine unspezifische Frage sollte man dann den Messwert zurückgeben ;) . Wer den Sollwert haben will, sollte gezielt fragen ;D .

Im Ernst: Auf die Schnelle neige ich dazu, für Heizungsgeräte einen weiteren type (desired-temp) zuzulassen, wobei ich mir nicht sicher bin, ob das nicht schon geht. Jedenfalls sieht der Hash ganz ok aus, wenn ich das hier angebe:SetNumeric:currentVal=desired-temp,minVal=0,maxVal=255,cmd=desired-temp,step=1,type=desired-temp

Die Frage wäre dann eher, ob es Sinn macht, diesen verbreiteten Type in den Standard aufzunehmen (und v.a. auch eindeutige Rückmeldesätze vorzuhalten), und wie dann ggf. mit heutigen SetNummeric-Mappings umzugehen sein soll. Ich neige dazu, da ggf. keine Rücksicht auf bestehendes zu nehmen, v.a., wenn es bisher keine klare Antwort auf die Frage gab...

Habe auch noch etwas an der Komplexitäts-Schraube gedreht, weiß aber mal wieder nicht, ob das alles tut wie es soll (sieht aber so aus).

Zitat von: drhirn am 16 März 2021, 12:45:27
Ach, und weil ich gerade darüber gestolpert bin:

Gab's ein Device mit dem Reading temperature und einem entsprechenden GetNumeric Mapping, konnte man - glaube ich - fragen "wie warm ist es im schlafzimmer". Wäre sehr praktisch.
Das sollte - bei entsprechender Rhasspy-Zuarbeit - klappen, oder täuscht mich das?
Zumindest bekomme ich auf diese - etwas verbogene - Frage eine Antwort mit Komma:
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": "temperature"}, "slotName": "Type", "rawValue": "helligkeit", "confidence": 1.0, "range": {"start": 0, "end": 10, "rawStart": 0, "rawEnd": 10}}, {"entity": "de.fhem.Device", "value": {"kind": "Unknown", "value": "lampe"}, "slotName": "Device", "rawValue": "deckenlampe", "confidence": 1.0, "range": {"start": 11, "end": 22, "rawStart": 11, "rawEnd": 22}}, {"entity": "de.fhem.Room", "value": {"kind": "Unknown", "value": "wohnzimmer"}, "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": "temperature", "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}
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 16 März 2021, 13:00:11
Verständnisfrage meinerseits: Hat das bisher (bis V. 0.2.x) geklappt :o ?

Nein. Ist ein Feature-Request ;)

ZitatAuf so eine unspezifische Frage sollte man dann den Messwert zurückgeben ;) . Wer den Sollwert haben will, sollte gezielt fragen ;D .

Hehe, ja, eh. Ich sehe aber keine Möglichkeit, das in Rhasspy abzubilden. Außer wir nehmen einen extra type, wie du schreibst.

ZitatDie Frage wäre dann eher, ob es Sinn macht, diesen verbreiteten Type in den Standard aufzunehmen (und v.a. auch eindeutige Rückmeldesätze vorzuhalten), und wie dann ggf. mit heutigen SetNummeric-Mappings umzugehen sein soll.

Ja, können wir gerne machen.

ZitatZumindest bekomme ich auf diese - etwas verbogene - Frage eine Antwort mit Komma:

Ja, ist klar. Hast ja auch ein Device angegeben. Das fehlt in meinem Satz absichtlich.

Beta-User

Zitat
Hehe, ja, eh. Ich sehe aber keine Möglichkeit, das in Rhasspy abzubilden. Außer wir nehmen einen extra type, wie du schreibst.
Na ja, was man versuchen könnte, wäre zu schauen, ob es zwei "temperature"-Type Readings gibt, und dann mit "temperature"/"measured-temp"=>"temperature" und dem anderen als "desired-temp" zu antworten (neue "combined_temps"-Antwort).
In "setze"-Richtung sollte es sowieso nur eine Möglichkeit geben, mit Soll-Temperaturen umzugehen (von gewissen Doppelungen wie in ZWave abgesehen).
(aber vermutlich nicht mehr heute, ist evtl. kompliziert...)

ZitatJa, können wir gerne machen.
Sollte kein Hexenwerk sein und schadet m.E. auch nicht. Magst du das versuchen?

ZitatJa, ist klar. Hast ja auch ein Device angegeben. Das fehlt in meinem Satz absichtlich.
OK, soweit so klar, war ein feature-request ;D ....
=> schreib's mal auf die Liste
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

#54
Zitat von: drhirn am 16 März 2021, 13:08:29
Ja, ist klar. Hast ja auch ein Device angegeben. Das fehlt in meinem Satz absichtlich.
Hmm, das müßte früher mal funktioniert haben, oder ich hatte es (fast) nebenbei repariert. Jedenfalls war bei der Hash-Variante noch ein Fehler drin, der jetzt raus ist.
Will sagen: Jetzt sollte die Temperaturabfrage in einem Raum klappen, wenn es irgendwo ein "temperature"-Mapping dafür gibt...
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

Pfoahhh, funktioniert.


2021.03.16 14:38:20.538 5: RHASSPY: [Rhasspy] Parse (IO: rhasspyMQTT2): Msg: hermes/intent/de.fhem_GetNumeric => {"input": "temperature im wohnzimmer", "intent": {"intentName": "de.fhem:GetNumeric", "confidenceScore": 1.0}, "siteId": "default", "id": "8a9af3fa-10c9-4815-90f7-f698fadfb7c2", "slots": [{"entity": "Type", "value": {"kind": "Unknown", "value": "temperature"}, "slotName": "Type", "rawValue": "wie warm ist es", "confidence": 1.0, "range": {"start": 0, "end": 11, "rawStart": 0, "rawEnd": 15}}, {"entity": "de.fhem.Room", "value": {"kind": "Unknown", "value": "wohnzimmer"}, "slotName": "Room", "rawValue": "wohnzimmer", "confidence": 1.0, "range": {"start": 15, "end": 25, "rawStart": 19, "rawEnd": 29}}], "sessionId": "8a9af3fa-10c9-4815-90f7-f698fadfb7c2", "customData": null, "asrTokens": [[{"value": "temperature", "confidence": 1.0, "rangeStart": 0, "rangeEnd": 11, "time": null}, {"value": "im", "confidence": 1.0, "rangeStart": 12, "rangeEnd": 14, "time": null}, {"value": "wohnzimmer", "confidence": 1.0, "rangeStart": 15, "rangeEnd": 25, "time": null}]], "asrConfidence": null, "rawInput": "wie warm ist es im wohnzimmer", "wakewordId": null, "lang": null}
2021.03.16 14:38:20.539 5: Parsed value: temperature for key: Type
2021.03.16 14:38:20.539 5: Parsed value: wohnzimmer for key: Room
2021.03.16 14:38:20.539 5: Parsed value: 1 for key: probability
2021.03.16 14:38:20.540 5: Parsed value: default for key: siteId
2021.03.16 14:38:20.540 5: Parsed value: 8a9af3fa-10c9-4815-90f7-f698fadfb7c2 for key: sessionId
2021.03.16 14:38:20.541 5: Parsed value: GetNumeric for key: intent
2021.03.16 14:38:20.541 5: Parsed value: temperature im wohnzimmer for key: input
2021.03.16 14:38:20.541 5: Parsed value: wie warm ist es im wohnzimmer for key: rawInput
2021.03.16 14:38:20.542 5: handleIntentGetNumeric called
2021.03.16 14:38:20.543 4: Devices in Room wohnzimmer: Heizung
2021.03.16 14:38:20.543 4: Devices outside Room wohnzimmer:
2021.03.16 14:38:20.543 5: Heizung

Beta-User

 ;D
Warum so überrascht?!?

Das ganze hat einen Haken: Der Zugriff erfolgt "zufällig", da über den Hash:
for my $devs (keys %{$hash->{helper}{devicemap}{devices}}) {
Man kann daher nie sicher vorhersagen, welches von mehreren passenden Devices geliefert wird (bzw. eigentlich: in welcher Reihenfolge sie in den Zielarray landen).

Könnte man an dieser Stelle per sort-Anweisung(en) verhindern, dieses Thema des zufälligen Zugriffs taucht aber (uU) auch an anderer Stelle auf:
if ($fromHash) {
        $matchedMapping = $hash->{helper}{devicemap}{devices}{$device}{intents}{$intent}{type};

(Kann aber sein, dass auch der Hash nur einfach gefüllt werden kann, damit wäre es dann so, dass effektiv z.B. das letzte GetNummeric-temperature-Mapping im Hash landet.)
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

Gar nicht überrascht. Das hätte Begeisterung ausdrücken sollen. Mir fehlt da einfach das "Party"-Emoticon ;)

Naja, wenn wir jetzt beim Beispiel Heizung bleiben, ist eher nicht wahrscheinlich, dass es mehrere Geräte mit dem selben Mapping im selben Raum gibt. Man müsste also nur das nehmen, das im jeweiligen Raum vorkommt.

Beta-User

OK, das laß' ich gelten ;D 8) ;D ...

Es kann schon vorkommen, dass man mehrere Geräte im selben Raum hat, die dieselben Mappings haben können. Ist nur die Frage, ob das sinnvoll ist, das alles unter RHASSPY-Kontrolle zu bekommen. Beispiel:
Ein Raum, zwei Heizkörper (mit regelbarem Thermostat), ein Raumtemperatursensor oder Wand-Thermostat => 3 Ist-Temperaturen (optimalerweise: Identisch), 2-3 Soll-Temperaturen.
In meinen Settings wäre es egal, weil der Raumsensor den gemessenen Wert wiedergibt und es egal ist, an welchen ich die Zieltemp übermittle (gepeerte CUL_HM). Für ein ZWave-Setup sieht das aber uU. "etwas" anders aus, v.a., wenn man die neuen Optionen noch nicht nutzt, dem/n Thermostat/en die gemessene Temp des Raumsensors unterzuschieben...

Schon mit den "althergebrachten" expliziten rhasspyMappings muss man aufpassen, was man macht, aber lustig wird das dann, wenn wir in Richtung automatische Erkennung (aus genDevType) gehen...
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

Dein Beispiel ist genau mein Beispiel. Sehe ich nicht als Problem.

Aber ja, das mit genericDeviceType wird dann spannend. Aber da können wir das Modul ja rückfragen lassen ;)