Parallele Alexa-Ausgaben

Begonnen von Superposchi, 07 Juni 2023, 22:20:27

Vorheriges Thema - Nächstes Thema

Superposchi

Hallo zusammen,
ich habe mittlerweile diverseste Aktionen mit einer Ansage kombiniert um mich darüber informieren zu lassen.
Natürlich kommt es nun unweigerlich vor, dass verschiedene Ansagen von unterschiedlichen Devices exakt im gleichen Moment ausgelöst werden. Dann wird nur eine Ansage ausgeführt und die Andere "geschluckt".

Gibt es irgend eine Möglichkeit die verschiedenen Ansagen quasi zu Sammeln und dann zusammen als ein String vom Echo ausgeben zu lassen?

locodriver

Du sagst es selbst: alle Ausgaben in einem String zusammen fügen und diesen dann ausgeben...

z.b. Auszug aus der myUtils:

if ($count == 0) {$text1 = "Alle Türen und Fenster sind geschlossen.";}
elsif ($count == 1) {$text1 = "Achtung! Eine Tür bzw ein Fenster ist nicht geschlossen.";}
else  {$text1 = "Achtung! ".$count." Türen bzw Fenster sind nicht geschlossen."};


my $text2 = "Die Heizung ist momentan ausgeschaltet.";
if (Value("Heizung") eq "Ein") {$text2 = "Die Heizung arbeitet momentan in der Betriebsart ".Value("BAjetzt").". Im Wohnzimmer ist eine Solltemperatur von ".ReadingsNum("WZ_Hk0","desired-temp",-1)." °C vorgegeben, aktuell sind ".ReadingsNum("WZ_Hk0","measured-temp",-1)." °C erreicht."};



{fhem("set WZ_Echo_Dot speak $text1"." "."$text2")};
}

Wenn die Ereignisse "zufällig" eintreffen, dann darfst du diese nicht direkt ausgeben, sondern musst diese abfangen und nacheinander in den String packen.
fhem 6.0 auf Rpi3 Bookworm
HM-LAN-CFG (FW 0.965), HM-MOD-UART, 2x HM-TC-IT-WM-W-EU, 4x HM-Sec-RHS und 3x HM-CC-RT-DN, 6x HM-LC-Bl1-FM mit je 1x Somfy-Motor,
2x HM-LC-SW2-FM für Licht und Lüfter, 2x HM-PB-6-WM55, Alexa, Jeelinkcross, CUL, CUNO2, IR-Blaster

Superposchi

Und genau dieses Abfangen bereitet mir Probleme.

Z.b. Hatte ich gestern die Situation, das eine Geburtstagserinnerung zeitgleich mit der Erinnerung für den Saugroboter kam.
Geburtstag ist immer unterschiedlicher Tag, der Saugroboter jeden 3. Tag wenn nicht anderweitig gereinigt wurde (nur als Notschaltung).
Genauso gibt es aber Terminerinnerungen, Sporterinnerungen und und und.

Im Augenblick werden die alle jeweils aus einem DOIF per myUtils-code an einen oder mehrere Echos gesand.

Wie bekomme ich die stattdessen in einen String und diesen dann in die Ansage rein?

binford6000

Ich finde es nicht mehr im Forum...
Hab das hier (aus dem Forum) im Einsatz:

## tts cueing...
sub ttsAddQueue($) {
  my ($text) = @_;
  my $cnt = 1;
  while (ReadingsVal('tts','queue-' . $cnt,'FREI') ne 'FREI') {
    $cnt++;
  } 
  fhem("setreading tts queue-$cnt $text");
  fhem("setreading tts cnt $cnt");
  return undef;
}

sub ttsSayQueue($) {
  my ($device) = @_;
  my $text;
  my $cnt = ReadingsNum('tts','cnt',0);
  my $sonosbridge = ReadingsVal("SonosBridge","connected",0);
  if ($cnt > 0) {
    for (my $i = 1; $i <= $cnt; $i++) {
      $text .= ReadingsVal('tts','queue-' . $i,'').'. ';
    }
    #if (InternalVal($device,'TYPE','undef') eq "dummy") {
if (InternalVal($device,'TYPE','undef') eq "echodevice") {
      fhem("set $device speak $text");
      fhem("deletereading tts queue-.*");
      fhem("setreading tts cnt 0")
    }
    elsif (InternalVal($device,'TYPE','undef') eq "MQTT2_DEVICE") {
      if ($sonosbridge == 2) {
        fhem("set $device speak de-DE Vicki 15 $text");
        fhem("deletereading tts queue-.*");
        fhem("setreading tts cnt 0")
      }
    }
    else {
      fhem("msg push $text");
      fhem("deletereading tts queue-.*");
      fhem("setreading tts cnt 0")
    }
  }
  return undef;
}

tts ist der dummy zum Sammeln. Ich habe mir noch zum einfacheren Aufrufen zwei cmd-Aliase gebaut:

defmod c_ttscue cmdalias ttscue .* AS {ttsAddQueue($EVENT)}
defmod c_ttssay cmdalias ttssay .* AS {ttsSayQueue($EVENT)}


Vielleicht hilft dir das ja weiter.
VG Sebastian

Superposchi

Ich bin mit Perl leider noch nicht fit, daher ein paar Nachfragen.

Im ersten teil wird die Ansage an das Reading "queue-$cnt" des Device tts übergeben, richtig?
Was ich nicht verstehe ist der Zähler "cnt"?

Verstehe ich richtig, dass jeder Readingseintrag als Schleife nacheinander ausgegeben wird?
Wenn ja passiert ja durch die Arbeitsweise von fhem doch wieder alles zeitgleich, oder nicht?
Ich verstehe auch noch nicht die Abfrage für sonos, wenn die Ausgabe auf einem Eche erfolgt.

Vielleicht könntest du etwas erklärenden Text hinzufügen.

binford6000

ZitatWas ich nicht verstehe ist der Zähler "cnt"?

defmod tts dummy

setstate tts In Warteschlange: 5
setstate tts 2023-06-08 18:58:56 cnt 5
setstate tts 2023-06-08 18:58:36 queue-1 Das
setstate tts 2023-06-08 18:58:40 queue-2 ist
setstate tts 2023-06-08 18:58:43 queue-3 eine
setstate tts 2023-06-08 18:58:52 queue-4 zusammengesetzte
setstate tts 2023-06-08 18:58:56 queue-5 Nachricht
setstate tts 2023-05-21 18:29:55 state off


ZitatIch verstehe auch noch nicht die Abfrage für sonos, wenn die Ausgabe auf einem Eche erfolgt.

Ich hab halt beides. Bei Bewegung im Raum wird das jeweilige Device für ttssay aufgerufen.

binford6000

ZitatVielleicht könntest du etwas erklärenden Text hinzufügen.

if ($cnt > 0) {
    for (my $i = 1; $i <= $cnt; $i++) {
      $text .= ReadingsVal('tts','queue-' . $i,'').'. ';
    }

Der Code sammelt die unterschiedlichen Nachrichten aus den Readings queue-1-n und setzt sie zu einem String zusammen.
Der wird dann am/anden gewünschten Device(s) ausgegeben. Damit werden keine Nachrichten 'verschluckt'. Das war doch deine Anforderung...

Superposchi

Ja richtig.
Ich komme nur nicht damit klar wie die Ansagen gesammelt werden.
Werden Sie in unterschiedliche Readings geschrieben und dann als Schleife nach einander ausgegeben
oder
werden die Ansagen in einen einzigen String zusammen gesetzt?

Bei letzterem stellt sich für mich die Frage wie in Perl Inhalt an einen bestehenden String angefangen wird.

Grundsätzlich stellt sich mir aber die Frage wie dann die Speak-Funktion aufgerufen wird. Irgendwie muss die Funktion ja mitbekommen, das was in dem tts-device abgelegt ist.

Sorry für die Verständnisprobleme, aber ich komme mit Perl einfach nicht klar.

binford6000

ZitatWerden Sie in unterschiedliche Readings geschrieben und dann als Schleife nach einander ausgegeben
oder werden die Ansagen in einen einzigen String zusammen gesetzt?
Die Ansagen werden im tts dummy in den einzelnen Readings queue-1 bis queue-n gespeichert und dann zu einem Gesamt-String zusammengesetzt.

ZitatBei letzterem stellt sich für mich die Frage wie in Perl Inhalt an einen bestehenden String angefangen wird.
$text .= "Neue Ansage"
setzt "Neue Ansage" and den Vorhandenen $text String an. 

ZitatGrundsätzlich stellt sich mir aber die Frage wie dann die Speak-Funktion aufgerufen wird. Irgendwie muss die Funktion ja mitbekommen, das was in dem tts-device abgelegt ist.

Das wird in ttsSayQueue gemacht:
  • Die Ansagen werden zusammengesetzt
  • Dann wird die zusammengesetzte Ansage auf einem Gerät ausgegeben.
  • In meinem Fall übergebe ich das Device an die Funktion da sie Raum-Abhängig aufgerufen wird.
    Man könnte auch einfach den speak Befehl direkt ausgeben.

VG Sebastian


Superposchi

Hab jetzt ein paar Tage drüber geprügelt.
Wäre folgender Ansatz sinnvoll und nicht zu kompliziert:
Alle Ansagen werden nicht an den Echo geschickt, sondern in einem Reading als 1 String gesammelt gesammelt. Alle paar Minuten wird geprüft ob in dem Reading was entfernt
Halten ist oder nicht. Falls ja, wird das an den Echo gesendet und das Reading gelöscht.

Theoretisch könnte ich dann sogar zwei Readings bauen, für jeden Echo ein eigenes.