FHEM und Rhasspy

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

Vorheriges Thema - Nächstes Thema

drhirn

Du kannst dich generell an die Snips-Anleitung halten. Funktioniert alles gleich. Wenn nicht, steht's hier im Thread.

Thargor

Ah, super. Da habe ich erstmal was zu lesen.

Funktioniert bei euch das Speak Kommando?

JensS

Ja, in FHEM und im Web-Interface von RHASSPY.
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.

Thargor

Ich habe hier eine Server+Satellit Struktur (siehe Screenshot) und da klappt es leider nicht aus FHEM. Vom Satellit aus kann ich eine Sprachausgabe starten. Hat jemand auch so eine Struktur und kann die Sprachausgabe von FHEM starten?


drhirn

Wie sieht denn dein Befehl aus?
Muss so sein:
set <name> speak siteId="satellite" text="das ist ein test"

Thargor

#50
Vielen Dank. Die ID habe ich natürlich nicht angegeben. So klappt es.

JensS

#51
Momentan bastle ich an einer Wetterabfrage über FHEM.
Dazu habe ich bisher zwei eigene Intents (Temperatur, Wind) erstellt. Diese kann ich einzeln und zusammen abfragen.
[de.fhem:Wetter]
Tagbezug = ( heute:0-7 | morgen:8-15 | übermorgen:16-23 )

wie wird die Temperatur <Tagbezug>{Temperatur}
woher weht der Wind <Tagbezug>{Wind}
wie wird <Tagbezug>{Temperatur} das Wetter <Tagbezug>{Wind}

Die dritte Abfrage ist blöd, da ich "Wie ist morgen das Wetter morgen" fragen muss.
Kann man eine erkannte Rule auf zwei Itents gleichzeitig anwenden, so dass ich das zweite "morgen" weglassen kann?

Gruß Jens

"attr Rhasspy rhasspyIntents Wetter=Wetter_Rhasspy(Temperatur,Wind,Niederschlag)"
defmod Openweather JsonMod https://api.openweathermap.org/data/2.5/forecast?lat=xx.xxxxxx&lon=xx.xxxxxx&unit=metric&exclude=daily&cnt=24&lang=de&appid=4ecc11bb9298ee1476c6a5xxxxxxxxxx
attr Openweather interval 05 00 * * *
attr Openweather readingList complete()
attr Openweather room Labor


sub Wetter_Rhasspy($){
my ($Temperatur,$Wind,$Niederschlag) = @_;
my $response;

if ($Temperatur ne ""){
my @Zeiten = split(/-/,$Temperatur);
my $Hoechststemp;
my $Tiefsttemp;

for (my $i=$Zeiten[0];$i<$Zeiten[1];$i++){
if ($i==$Zeiten[0]){$Hoechststemp = ReadingsNum("Openweather","list.$i.main.temp_max",0)};
if (ReadingsNum("Openweather","list.$i.main.temp_max",0) > $Hoechststemp){$Hoechststemp = ReadingsNum("Openweather","list.$i.main.temp_max",0)};
if ($i==$Zeiten[0]){$Tiefsttemp = ReadingsNum("Openweather","list.$i.main.temp_min",0)};
if (ReadingsNum("Openweather","list.$i.main.temp_max",0) < $Tiefsttemp){$Tiefsttemp = ReadingsNum("Openweather","list.$i.main.temp_min",0)};
}

$Hoechststemp = sprintf("%.0f",$Hoechststemp - 273.15);
$Tiefsttemp = sprintf("%.0f",$Tiefsttemp - 273.15);

$response = "Die Höchsttemperatur beträgt $Hoechststemp Grad Celsius und die Tiefsttemperatur $Tiefsttemp Grad";
};
if ($Temperatur ne "" && $Wind ne ""){$response = $response." - "};
if ($Wind ne ""){
my @Zeiten = split(/-/,$Wind);
my $Windrichtung = 0;
my $Windname;
my $Windstaerke = 0;
my $Windbezeichnung;
for (my $i=$Zeiten[0];$i<$Zeiten[1];$i++){
my $Windwert = ReadingsNum("Openweather","list.$i.wind.speed","");
if ($Windwert > $Windstaerke) {$Windstaerke = $Windwert};
};
if ($Windstaerke >= 0){ $Windbezeichnung = "herrscht Windstille"};
if ($Windstaerke > 0.2){ $Windbezeichnung = "weht ein leiser Zug"};
if ($Windstaerke > 1.5){ $Windbezeichnung = "weht eine leichte Brise"};
if ($Windstaerke > 3.3){ $Windbezeichnung = "weht eine schwache Brise"};
if ($Windstaerke > 5.4){ $Windbezeichnung = "weht eine mäßige Brise"};
if ($Windstaerke > 7.9){ $Windbezeichnung = "weht eine frische Brise"};
if ($Windstaerke > 10.7){ $Windbezeichnung = "weht ein starker Wind"};
if ($Windstaerke > 13.8){ $Windbezeichnung = "weht ein steifer Wind"};
if ($Windstaerke > 17.1){ $Windbezeichnung = "weht ein stürmischer Wind"};
if ($Windstaerke > 20.7){ $Windbezeichnung = "droht Sturm"};
if ($Windstaerke > 24.4){ $Windbezeichnung = "droht starker Sturm"};
if ($Windstaerke > 28.4){ $Windbezeichnung = "droht orkanartiger Sturm"};
if ($Windstaerke > 32.6){ $Windbezeichnung = "droht Orkan"};

$response = $response."Es $Windbezeichnung aus ";

for (my $i=$Zeiten[0];$i<$Zeiten[1];$i++){
$Windrichtung = $Windrichtung + ReadingsNum("Openweather","list.$i.wind.deg","");
};
$Windrichtung = $Windrichtung /  ($Zeiten[1] - $Zeiten[0]);
if ($Windrichtung >= 0){ $Windname = "Nord"};
if ($Windrichtung > 23){ $Windname = "Nordost"};
if ($Windrichtung > 68){ $Windname = "Ost"};
if ($Windrichtung > 113){ $Windname = "Südost"};
if ($Windrichtung > 158){ $Windname = "Süd"};
if ($Windrichtung > 203){ $Windname = "Südwest"};
if ($Windrichtung > 248){ $Windname = "West"};
if ($Windrichtung > 293){ $Windname = "Nordwest"};
if ($Windrichtung > 338){ $Windname = "Nord"};

$response = $response.$Windname;
};
if ($response eq ""){$response="keine Daten vorhanden"};
return $response;

}
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.

Thargor

#52
Danke für dein Beispiel. Das war Anregung mich auch mal damit zu beschäftigen.

Ich glaube nicht, dass man den <Tagbezug> zwei Tags zuweisen kann.

Was aber geht ist einen neuen Tag einzuführen:

attr Rhasspy rhasspyIntents Wetter=Wetter_Rhasspy(Temperatur,Wind,Niederschlag,Wetter)

wie wird das Wetter <Tagbezug>{Wetter}
wie wird <Tagbezug>{Temperatur}{Wetter} das Wetter


sub Wetter_Rhasspy($){
my ($Temperatur,$Wind,$Niederschlag,$Wetter) = @_;
my $response;

if ($Wetter ne "")
{
$Temperatur=$Wetter;
$Wind=$Wetter
}


Halte uns/mich bitte weiter auf dem Laufenden :-)

JensS

#53
Danke für deinen Rat. Ich habe in der Zwischenzeit einiges über JSGF gelesen und keine Möglichkeit gefunden, das in der Sentences.ini umzusetzen.
Ich werd's so machen wie du vorgeschlagen hast. Die vielen verschiedenen Zeiträume und Antwortmöglichkeiten in eine sub zu quetschen, ist jetzt die Herrausforderung. Wenn was Brauchbares bei raus kommt, ersetze ich den Code im vorigen Post.

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.

thomy_h

Hallo zusammen,

bin auch gerade dabei, rhasspy mit fhem zum Laufen zu bringen. Dabei fiel mir folgendes auf:

Muss es in 10_STE.pm ab Zeile 362 (getDeviceByName) nicht !defined($room) statt !defined($device) heißen?


           if (!defined($room) || grep( /^$room$/i, @rooms)) {
                $device = $_;
           }


Begründung:
Das device soll doch sicher nur dann matchen, wenn der rhasspyRoom auch übereinstimmt, so der denn definiert wurde.
So wie es da steht, wird aber das erste device bei dem der rhasspyName stimmt gematcht, egal was im rhasspyRoom steht.
Das führt dann u.a. auch dazu, dass Aktionen ausgeführt werden, obwohl der genannte Raum gar nicht existiert.

z.B.

device1
rhasspyName licht
rhasspyRoom wohnzimmer

device2
rhasspyName licht
rhasspyRoom buero

Auf Intent SetOnOff("esszimmer", "licht", "an") geht das licht im wohnzimmer an. Vermutlich würde bei "licht" auch immer nur das "wohnzimmer" angehen, egal welchen Raum ich nenne. Das hab ich allerdings noch nicht getestet, bin erst am Anfang :)

Ändert man $device in $room, kommt auf o.g. Intent zumindest mal korrekt die response "da ist wohl etwas schiefgegangen", weil "licht" und "esszimmer" nicht existiert und auch "licht" ohne Raum nicht existiert.

ich hoffe ich hab nichts übersehen, ... ansonsten tolles Projekt :)

drhirn

Warum? Es wird ja das Device gesucht, nicht der Room. Wenn kein Room da ist, wir ein Standardraum genommen. Wenn ich das richtig sehe, der aus der siteId.

JensS

Hinter das Geheimnis des Standardraumes bin ich auch noch nicht gestiegen. In FHEM ist der letzte Parameter der STE-Bridge-Definition der Standardraum. Dabei ist es egal, welche siteId der Rhasspy hat. In der Konfiguration finde ich auch keinen Hinweis dazu. Ich bin mal wieder ratlos...
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.

drhirn

Ah, ja, so war das. Der Standardraum ist der aus der Definition. Ich roste ein ;)

JensS

Nun würde ich gern dem Satelliten SZ den Standardraum Schlafzimmer zuweisen - nur wie?
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

rhasspyRoom Attribut der Devices einfach so benennen, wie der Satellit heißt. MQTT-Messages vom Satelliten sollten ja mit einer siteId befüllt sein. Und die siteId hast du in den Einstellungen des Satelliten ja vergeben. Ist im Sprachbefehl also kein Raumname vorhanden, wird die siteId genommen.