FHEM und Rhasspy

Begonnen von drhirn, 28 Juli 2020, 14:28:50

Vorheriges Thema - Nächstes Thema

JensS

Danke, das war's! Bei "Licht an" geht jetzt im jeweiligen Standardraum das Licht an.
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.

cb2sela

Guten Abend,

kann mir mal jemand aufs Pferd helfen? Ich kenne die ganzen Vorgeschichten mit SNIPS nicht und kämpfe mich seit vielen Stunden von Hürde zu Hürde weiter.

Vorhandene Zutaten:

  • Eine FHEM Installation mit internem MQTT2_SERVER und u.a. einer Gosund SP111, die ich z.B. mit "set MQTT2_SP111a on" auch erfolgreich schalten kann.
  • Eine Rhasspy Installation auf einem anderen Raspberry, die soweit funktioniert, dass sie auf ein Wakeword reagiert und "schalte die Wohnzimmerlampe ein" auch versteht. Der interne MQTT-Server ist auf Port nach außen 12183 verfügbar.

Ich habe die 10_STE.pm installiert und fehlende Dependencies (DateTime.pm und Pluggable.pm) behoben.

In Rhasspy gibt es diesen Sentence:
[de.fhem:SetOnOff]
light_name = (wohnzimmerlampe | garagenlicht) {name}
light_state = (an | ein | aus) {state}
schalte (die | das) <light_name> <light_state>

In FHEM habe ich angelegt:

define RhasspyMQTT MQTT 192.168.178.54:12183
define Rhasspy STE RhasspyMQTT Wohnzimmer
attr Rhasspy room Rhasspy
attr RhasspyMQTT room Rhasspy

und mein Gosund-Gerät noch angereichert:
attr MQTT2_SP111a room Rhasspy,MQTT2_DEVICE
attr MQTT2_SP111a rhasspyName Wohnzimmerlampe
attr MQTT2_SP111a rhasspyRoom Wohnzimmer
attr MQTT2_SP111a rhasspyMapping SetOnOff:cmdOn=on,cmdOff=off\
GetOnOff:currentValue=state,valueOff=off


Wenn ich zu Rhasspy sage "Schalte die Wohnzimmerlampe an" kommt in Fhem an:
{"input":"schalte die wohnzimmerlampe an","intent":"SetOnOff","name":"wohnzimmerlampe","probability":1,"rawInput":"schalte die wohnzimmerlampe an","requestType":"voice","sessionId":"default-terminator-1d5674a2-30d3-4f7e-babe-e8e1b1d088b8","siteId":"default","state":"an"}
aber er sagt mir "Da ist etwas schief gegangen" und es ändert sich nichts.

Im fhem.log bekomme ich:

2020.12.15 15:52:21 1: PERL WARNING: Use of uninitialized value in substitution (s///) at ./FHEM/10_STE.pm line 697.
2020.12.15 15:52:21 1: PERL WARNING: Use of uninitialized value $value in concatenation (.) or string at ./FHEM/10_STE.pm line 723.
2020.12.15 15:52:26 1: PERL WARNING: Use of uninitialized value in split at ./FHEM/10_STE.pm line 312.
2020.12.15 15:52:26 1: PERL WARNING: Use of uninitialized value $attrString in split at ./FHEM/10_STE.pm line 569.


Was mache ich noch falsch?

Gibts noch irgendwo eine andere Doku außer der https://github.com/Thyraz/Snips-Fhem? Irgendwas Schritt für Schritt-mäßiges, das auch die ganzen Stolpersteine und geänderten Raumnamen etc. berücksichtigt?


drhirn

Probier mal:


[de.fhem:SetOnOff]
schalte (die | das) (wohnzimmerlampe | garagenlicht){Device} (an | ein | aus){Value}

cb2sela

Danke Dir.
Rhasspy ist durch die Änderung freundlicher geworden und sagt jetzt zwar "Mache ich doch sehr gerne" aber FHEM schaltet nicht. Angekommene Nachricht ist


{"Device":"wohnzimmerlampe","Value":"aus","input":"schalte die wohnzimmerlampe aus","intent":"SetOnOff","probability":1,"rawInput":"schalte die wohnzimmerlampe aus","requestType":"voice","sessionId":"default-terminator-f24d1e07-3ee1-4534-bcff-9fd5bc308be8","siteId":"default"}


Im fhem.log bekomme ich :


2020.12.15 18:12:42 1: devspec2array off\: Unmatched ( in regex; marked by <-- HERE in m/^( <-- HERE off\)$/ at fhem.pl line 1323.

2020.12.15 18:12:42 1: stacktrace:
2020.12.15 18:12:42 1:     main::devspec2array                 called by fhem.pl (1943)
2020.12.15 18:12:42 1:     main::CommandSet                    called by fhem.pl (1247)
2020.12.15 18:12:42 1:     main::AnalyzeCommand                called by ./FHEM/10_STE.pm (622)
2020.12.15 18:12:42 1:     main::STE_runCmd                    called by ./FHEM/10_STE.pm (1088)
2020.12.15 18:12:42 1:     main::STE_handleIntentSetOnOff      called by ./FHEM/10_STE.pm (793)
2020.12.15 18:12:42 1:     main::STE_onmessage                 called by fhem.pl (3814)
2020.12.15 18:12:42 1:     main::CallFn                        called by ./FHEM/00_MQTT.pm (550)
2020.12.15 18:12:42 1:     MQTT::__ANON__                      called by FHEM/GPUtils.pm (75)
2020.12.15 18:12:42 1:     GPUtils::GP_ForallClients           called by ./FHEM/00_MQTT.pm (560)
2020.12.15 18:12:42 1:     MQTT::Read                          called by fhem.pl (3814)
2020.12.15 18:12:42 1:     main::CallFn                        called by fhem.pl (755)
2020.12.15 18:12:42 1: default/icoEverything.png

drhirn

Versteh ich nicht. Kann ich nicht nachvollziehen. Sieht bei mir auch gleich aus, was via MQTT ankommt:
{"Device":"wohnzimmerlampe","Value":"aus","input":"schalte die wohnzimmerlampe aus","intent":"SetOnOff","probability":1,"rawInput":"schalte die wohnzimmerlampe aus","requestType":"voice","sessionId":"a1a85c82-3951-4acc-988d-3768ee17653f","siteId":"default"}

Kannst du bitte mal das Mapping ändern? Das GetOnOff weglassen.

attr MQTT2_SP111a rhasspyMapping SetOnOff:cmdOn=on,cmdOff=off

Mich irritiert, dass "off" in der Fehlermeldung beanstandet wird.

cb2sela

Sapperlot! Du bist gut! Ohne GetOnOff gehts! Erste Lampe erfolgreich per Spracheingabe gesteuert - ich bin begeistert! :)

Ich hatte das ursprüngliche Attribut einfach so oben in die Eingabezeile eingegeben. Inklusive des Backslash und der neuen Zeile, also so:

attr MQTT2_SP111a rhasspyMapping SetOnOff:cmdOn=on,cmdOff=off\
GetOnOff:currentValue=state,valueOff=off


Wie wäre es denn richtig gewesen?

Kannst Du mich noch in die richtige Richtung schubsen und auf Doku / Threads verweisen, was ich in Rhasspy und FHEM machen muss, um mir  z.B. die Temperatur eines Temperatursensors vorlesen zu lassen?

Arbeitet irgendjemand an einer Einsteiger-Doku für das Modul 10_STE.pm?

drhirn

Ohne Backslash wäre richtig. Ein Mapping pro Zeile.

Es gibt leider - außer im GitHub von Thyraz - nirgends eine Doku. Aber lass dich nicht aufhalten ;)

drhirn

Es wird euch nicht freuen, aber ich habe gerade endlich die 10_STE.pm in 10_RHASSPY.pm umbenannt. Ihr müsstet also das Modul einbinden und euer Device ändern.
Funktional hat sich nichts verändert. Habe nur eine kurze CommandRef hinzugefügt.

cb2sela

Ich arbeite grade an einer kleinen Getting Started Anleitung. Ich denke, dass die alten FHEM-Hasen die schon von SNIPS kommen vieles automatisch richtig machen, währen der Gelegenheits-FHEM-Nutzer wie ich von Fallstrick zu Fallstrick stolpert und dasteht wie der Ochs vorm Berg.

Bevor ich besagte Anleitung in den nächsten Tagen poste habe ich aber noch ein paar Fragen, die ich gerne klären möchte.

Bitte beachtet: Ich habe noch nie an öffentlichem / fremden Code mitgearbeitet. Wenn ich also irgendwelche Netiquetten verletze oder dumme Fragen habe, dann steinigt mich nicht gleich.

Fürs Erste habe ich noch ein paar Warnings und Fehler im Log:

2020.12.16 15:18:40 1: PERL WARNING: Use of uninitialized value in substitution (s///) at ./FHEM/10_STE.pm line 697.

Das ist die Zeile mit:
     ($data->{'intent'} = $decoded->{'intent'}{'intentName'}) =~ s/^.*.://;
Ursache imho: Nicht alle Datensätze enthalten einen Intent. Wenn ich mein Wakeword terminator sage kommt er einmal an dieser Stelle vorbei und $decoded enthält an dieser Stelle nur:
$VAR1 = {
          'customData' => 'terminator',
          'siteId' => 'default',
          'sessionId' => 'default-terminator-58ecbae3-d036-4d54-b404-20b2ee1969a4',
          'lang' => undef
        };
also weder einen intent noch probability, input oder rawinput.

Ich weiß nicht, ob es korrekt ist, dass Rhasspy schon mit dem wakeword alleine hier aufschlägt und ob sich das an der Quelle abstellen lässt. Ansonsten würde ich so etwas vorschlagen:



    698     # Standard-Keys auslesen
    699     # Wenn nur das Wakeword ankommt gibt es diverse Felder nicht im JSON. Diese Felder werden ggf. nicht befüllt.
    700     if (exists($decoded->{'intent'})) {
    701         ($data->{'intent'} = $decoded->{'intent'}{'intentName'}) =~ s/^.*.://;
    702         $data->{'probability'} = $decoded->{'intent'}{'confidenceScore'};
    703     }
    704     $data->{'sessionId'} = $decoded->{'sessionId'};
    705     $data->{'siteId'} = $decoded->{'siteId'};
    706     $data->{'input'} = $decoded->{'input'} unless !exists($decoded->{'input'});
    707     $data->{'rawInput'} = $decoded->{'rawInput'} unless !exists($decoded->{'rawInput'});


Nächste Warning:

2020.12.16 16:00:35 1: PERL WARNING: Use of uninitialized value in split at ./FHEM/10_STE.pm line 312.
Das ist die Zeile mit:
    my @rows = split(/\n/, AttrVal($hash->{NAME},"shortcuts",undef));
$hash->{NAME} ist bei mir 'NAME' => 'Rhasspy' und AttrVal($hash->{NAME},"shortcuts",undef) ergibt in der Tat undef. Somit wird @rows nichts.
Muss ich zwingend ein attribut shortcuts setzen und wenn ja auf was?

Nächster:
PERL WARNING: Use of uninitialized value $attrString in split at ./FHEM/10_STE.pm line 569.
Das ist die Zeile:
my $attrString = AttrVal($device, $reading, undef);
Bei mir wird device = 'Rhasspy' und reading = 'response'
AttrVal('Rhasspy', 'reading', undef) wird wohl undef. Ich verstehe noch nicht genau, was hier schief läuft.

Viele Grüße

drhirn

Ich hab die Warnungen nicht immer. Eigentlich nur sehr selten. Weiß nicht genau, was man da tun müsste, um sie zu provozieren.

Hast du deine Änderung getestet?

Sind alles nur Warnungen - die so natürlich auch schon im Snips-Modul waren -, darum habe ich mich bisher nicht wirklich darum gekümmert. Nur bei denen, bei denen mein spärliches Perl-Wissen gereicht hat.

cb2sela

Ich habe mir nun einen github account eingerichtet und lese mich grad noch in die Funktionsweise von git und github ein.

Meinen Senf zum Code würde ich dann über github bei Dir einkippen, damit dieser Thread hier nicht zugemüllt wird.

(Die besagten Warnings kann ich reproduzierbar erzeugen. Details dazu dann per github).

drhirn

Sehr gut!

Erster Pull Request ist schon gemerged. War auch mein erstes Mal ;).

Übrigens: Früher war die Zeitansage richtig so. Da hat sich wohl bei Rhasspy was geändert.

cb2sela

Für alle Anfänger und Gelegenheits-FHEM-Nutzer wie mich, die gerne erste Schritte mit Rhasspy gehen möchten habe ich ein kleines gettingstarted geschrieben.

https://github.com/cb2sela/fhem-rhasspy-gettingstarted

Es reflektiert eine für mich persönlich funktionierende Anleitung Stand 2020-12 mit buster-lite-2020-08 auf zwei Raspberry PIs und soll die ersten Schritte für all diejenigen erleichtern, die sich zum ersten mal mit dem Thema beschäftigen.

Sturi2011

#73
Hallo,

damit das Beispiel auch tatsächlich mit "ein" funktioniert,

1085              my $cmd = (($value eq 'an')||($value eq 'ein')) ? $cmdOn : $cmdOff;
1092              $numericValue = (($value eq 'an')||($value eq 'ein')) ? 1 : 0;

zumindest hat das bei mir geholfen...und war natürlich quatsch - in der Kurzdoku fehlt irgendwie das Thema Slots ;)

Klasse Arbeit.

Gruß Andreas

Dreggwatz

Hi zusammen und ein gutes Neues noch,

meine Frau hat bei einer Bekannten einen Narren an Alexa Sprachsteuerung gefunden und hätte dies bei uns auch gerne. Für mich kommt aber nur eine Offline Sprachsteuerung in Frage und überhaupt muss es bei mir über FHEM laufen damit ich auch alles ansteuern kann. Meine Wunschsprachein- und Ausgabe wäre in diversen Räumen ein SONOS ONE. Bevor ich mir aber so ein Teil zulege und schlussendlich es nicht funktioniert bin ich über Google und SNIPS hier gelandet.

Kann mir jemand kurzer Hand sagen ob mit einem RasPi4 mit FHEM, Rhasspy und mehreren SONOS die Sprachsteuerung realisierbar ist?

Ein PS3eye hab ich sogar noch im Keller rumfliegen... und könnte damit ja schon mal rumspielen bevor ich mich in Unkosten stürze

Danke