Hallo zusammen,
seit ein paar Tagen habe ich angefangen, die ganzen HomeMatic Komponenten die ich habe, auch mal mit meinem RPi zu verbinden.
Ich hänge nun an einer Sache, wo ich nicht weiß an welcher Stelle ich mich blöd anstelle: Ich möchte, dass sobald ein Fenster geöffnet wird, nach X Minuten eine Ansage auf dem am RPi angeschlossenen Lautsprecher ausgegeben wird. In der Ansage soll das Fenster genannt werden, welches geöffnet ist.
Die Ansage selbst auszugeben ist dank eSpeak überhaupt kein problem:
espeak -vde "Fenster offen: Raum"
Natürlich möchte ich jetzt, das anstelle Raum der Raum genannt wird, wo der Kontakt geöffnet wurde. Die Kontakte haben bei mir das Namensschema Wohnung.<Raum>.Device.Fenster1. Bei jedem dieser habe ich definiert:
attr Wohnung3.<Raum>.Device.Fenster1 userattr speakText
attr Wohnung3.<Raum>.Device.Fenster1 speakText Fenster abc
Ich möchte jetzt, dass der Inhalt aus speakText an ein Skript übergeben wird, wo ich dann via eSpeak den übergebenen Text ausgeben lasse.
Soweit glaube ich es so verstanden zu haben, dass ein Watchdog für meinen Fall das richtige wäre:
define Fenster.Offen watchdog .*.Device.Fenster[0-9]{1,2}:open 00:05:00 .*.Device.Fenster[0-9]{1,2}:closed {\
DebianMail('em@il.de', 'Fenster offen: % @', '') ;; \
}
Mein nächster Gedankengang ist, dass ich via ReadingVal nur die Variable speakText auslesen müsste und die dann über einen Aufruf system("xyz.sh") usw. übergeben könnte. Dafür müsste ich aber genau wissen, welches Gerät gerade den Watchdog triggerd und da hänge ich momentan. Weder in % noch in $NAME wenn ich testweise eine Mail versende, ist ein Value gespeichert den ich bei ReadingsVal verwenden kann.
Zum testen triggere ich den Watchdog mit
trigger Wohnung3.Wohnzimmer.Device.Fenster1 open
so das meinem Verständnis nach in % (oder $NAME) dann "Wohnung3.Wohnzimmer.Device.Fenster1" stehen sollte. Ich würde dann einfach mit einem
my $speakText = (ReadingsVal("%", "speakText", ""))
mir den Text holen und dann wäre die Sache schon so gut wie gegessen.
Wo in der ganzen Kette habe ich Verständnisfehler?
- Triggere ich den Watchdog richtig?
- Wo finde ich eine Variable mit dem Auslöser, mit dem ich arbeiten kann?
- Ist meine weitere Vorgehens- bzw. Denkweise richtig?
wenn ich das richtig sehe, ist speaktext ein attibut bei dir. zum lesen von attributen gibt es "AttrVal("wz", "room", "none")". => commandref.
Zitat von: frank am 31 Dezember 2014, 13:47:10
wenn ich das richtig sehe, ist speaktext ein attibut bei dir. zum lesen von attributen gibt es "AttrVal("wz", "room", "none")". => commandref.
Okay, Danke! Nachvollziehbar! Vor lauter Wald sieht man gar keine Bäume mehr ;)
Niemand der mir sagen kann aus welcher Variable ich das auslösende Device ermitteln kann?
nimm %NAME für das auslösende Device.
Geht leider auch nicht. Kann es sein, dass der Watchdog nur für "spezielle" Situationen vorgesehen ist und nicht für solche, wie ich ihn verwenden möchte?
Der Watchdog kann nur auf ein Device sinnvoll triggern.
Also die selbe Methode für verschiedene Devices benötigt je einen eigenen Watchdog.
Okay Danke! Dann schau ich lieber mal, ob ich mit einem notify Konstrukt inkl. passender RegEx usw. was gebacken bekomme. Bin da eher der Freund von etwas das universell funktioniert als irgendwelchem speziellem Gedöns.
Hallo das ganze Thema interessiert mir auch da ich diese dann auch benutzen kann als Klingel oder als Waschmaschine Fertig Meldung. Kannst du mir erklären wie du das sound auf deine Raspberry bekommt und wie du das schritt für schritt gemacht hast?
Ich würde bald dazu mal ein How-To bzw. Code-Schnippsel zur Verfügung stellen. Hab zwar schon was am laufen, ist aber noch nicht so optimal.
Problem ist z.B., wenn du mehrere Ansagen hast die nahezu zeitgleich zutreffen, dürfen die ja trotzdem nicht überlagert werden. D.h. ich werde so eine Art Queue implementieren, in der man die Ansagen rein schmeißen kann und die werden der Reihe nach abgespielt. Ich gebe Rückmeldung zur gegebenen Zeit.
Ok das ist in Ordnung, und wie macht du die Ansagen? Ich habe mir gedacht mehrere Bluetooth-Lautsprecher zu Kaufen so dass die ansage durch das ganze haus zu hören ist.
Überlege mich im Moment welche Lautsprecher am besten funktionieren und nicht zuviel Strom ziehen.
Bis vor kurzem habe ich einfach an meinen RPi einen Lautsprecher angeschlossen gehabt, den es mal bei den Pringles gab (Siehe: http://3.bp.blogspot.com/-nHuQ6SEaI3g/UMyP67C-KjI/AAAAAAAAFcQ/Z7AF0w7v-wg/s1600/Pringle+Lautsprecher2.jpg).
Da das räumlich natürlich begrenzt war, habe ich mich ebenso wie du umgesehen was machbar ist und bin dann auch beim Thema Bluetooth Lautsprecher gelandet. Hier bin ich aber auf ein unerwartetes Problem gestoßen, dass gesprochene Texte die ich mir via Google TTS als MP3 geholt habe, immer am Ende um eine 1/2 Sekunde abgeschnitten wurden.
Ich hatte den Lautsprecher schon eingepackt gehabt und wollte ihn zurückschicken, als mich dann doch nochmal der Ehrgeiz gepackt hat. Nach etwas rumprobieren habe ich dann herausgefunden, dass es in Kombination Bluetooth / VLC von der Kommandozeile problemlos funktioniert (alle anderen Player haben das beschriebene Problem). Ob es am Format liegt, ALSA irgendwelche Probleme hat, keine Ahnung.
Aktuell probiere ich jetzt noch etwas weiter, um zu schauen wie zuverlässig das ganze ist. Ob und wie das mit mehreren Lautsprechern funktioniert, kann ich dir nicht sagen. Könnte mir vorstellen, dass es Probleme mit der Latenz geben könnte wenn du mehrere zeitgleich ansprichst.
Super Idee. Ich bastele jetzt auch mit ein Verstärker und Lautsprechers. Ich schallte die Verstärker Anlage ein mit ein Funk Steckdose (die Verstärker ist angeschlossen an Raspbarry) dann mache ich ein Sleep Kommando für 3 Sekunden damit die Anlage richtig an ist und dann benutze ich die Ansagen. Danach schalte ich die Anlage verzögert aus. Bis jetzt klappt die probe schon ganz gut!
Das vorteil hier ist, kein Stromverbrauch vom Verstärker und ich kann da richtig ein Sound machen mit dem Anlage!
Das Nachteil ich muss ein paar Kabel ziehen durch das Haus!
Und vielleicht ein weiteres Nachteil, die erste Ansage kommt verzögert aus der Anlage.
Für andere Losungen stehe ich auch offen also bitte Posten, danke!
So, jetzt mehr :)
Implementierung: Fenster auf Ansage nach X MinutenAlso, Ausgangslage bei mir: Ich habe meine Geräte so benannt, dass Ort und Gerät erkennbar sind. D.h. im Wohnzimmer hat z.B. der Fensteraktor den Namen
Wohnung.Wohnzimmer.Device.Fenster1
und ist dem Raum "Raum | Wohnzimmer" zugeordnet. Soweit sogut, aber nichts was dazu tauglich ist, verständlich ausgesprochen zu werden.
Also habe ich bei allen Fenster- und Türaktoren ein eigenes Attribut definiert mit dem Inhalt, was ausgesprochen werden soll.
Zu sprechende Text zuordnenIm konkreten Beispiel sehen die zusätzlichen Zeilen so aus:
attr Wohnung.Wohnzimmer.Device.Fenster1 userattr speakText
attr Wohnung.Wohnzimmer.Device.Fenster1 speakText Fenster Wohnzimmer
D.h., das was beim Attribut speakText steht, möchte ich zur Sprachausgabe verwenden.
Sprachausgabe einrichtenSo, jetzt kommt der interessante Teil damit man auch FHEM dazu bekommt, was auszusprechen:
define Fenster.Status.Offen notify Wohnung..*.Device.(Fenster|Tuer)[0-9]{1,2}:open {\
if($defs{"@.Reminder"}) {\
return;;\
} \
\
my $deftype = $defs{"@"}{TYPE};;\
Log 3, "@: Type ".$deftype;;\
return if ( $deftype ne "CUL_HM" );;\
\
my $currentTempOutside = ReadingsVal("Wetter.Yahoo", "temp_c", "0");;\
Log 3, "@: Temperatur ".$currentTempOutside;;\
\
if($currentTempOutside <= 16.0) {\
Log 3, "@: Reminder set";;\
fhem("define @.Reminder at +*00:05:00 trigger Fenster.Status.Check @");;\
} else { \
Log 3, "@: Reminder not set";;\
} \
}
define Fenster.Status.Geschlossen notify Wohnung..*.Device.(Fenster|Tuer)[0-9]{1,2}.*:closed {\
if (($defs{"@.Reminder"})) {\
Log 3, "@: Reminder unset";;\
fhem("delete @.Reminder");;\
}\
}
define Fenster.Status.Check notify Fenster.Status.Check {\
my $device = "%";;\
my $deviceState = ReadingsVal("$device", "State", "nA");;\
Log 3, "@: $device -> ".Value("$device");;\
if(Value("$device") =~ /open/) {\
Log 3, "@: $device -> Schliessen!";;\
my $speakText = AttrVal("$device", "speakText", "");;\
system('/opt/fhem/plugins/ttsqueue/ttsqueue-cli.sh add "Bitte '.$speakText.' schliessen" &');;\
}\
}
Erklärung, was dort passiert:
- Fenster.Status.Offen
Mit dem Notify Fenster.Status.Offen registriere ich, ob ein Fenster geöffnet wird. Zuerst schaue ich, ob schon eine Erinnerung gesetzt wurde für das geöffnete Fenster, kann ja mal passieren das irgendwo ein Status verschluckt wird und ich will verhindern, das Mehrfachansagen kommen. Anschließend mache ich noch eine Überprüfung, ob es ich um einen Homematic Aktor handelt, wenn Nein, springe ich direkt aus.
Nun gehe ich hin und lese aus "Wetter.Yahoo" aus, eine Wetterabfrage über die Yahoo-API, welche Temperatur aktuell draußen herscht. Ist die Temperatur kleiner gleich 16 Grad, triggere ich als nächstes das Notify Fenster.Status.Check nach 5 Minuten, ist die Temperatur drüber, passiert nichts weiter.
- Fenster.Status.Geschlossen
Hier checke ich einfach nur bei Schließen des Fensters, ob ein Reminder gesetzt ist. Wenn Ja, lösche ich den und fertig.
- Fenster.Status.Check
Hier lese ich zuerst mal den aktuellen Status des Fensters aus, kann ja sein dass zwischenzeitlich das Fenster geschlossen wurde. Ist das Fenster noch offen, rufe ich das entsprechende Shell-Skript auf dass für die Sprachausgabe zuständig ist. Hier lese ich auch die Entsprechende Eigenschaft speakText des jeweiligen Gerätes aus um die dann an das Shell-Skript zu übergeben. Das Shell-Skript ist der Client zu ttsqueue (mehr dazu weiter unten)
Was es zu beachten gilt, wenn man es für eigene Zwecke einsetzt: Man muss auf jeden Fall die "Regel" (Regular Expression) anpassen, die auf die eigenen Geräte anspringt. Da Ihr eure Geräte sicherlich anders benannt habt, ist die Anpassung notwendig.
TTSQueueIch möchte gerne zukünftig noch mehr via Sprachausgabe erledigen. Problem ist dabei, dass wenn man mehrere Sachen kurz hintereinander hat, die ausgegeben werden soll, würden die sich überschneiden, würde man die einfach nur an ein stupides Skript / Programm übergeben. Mein Ansatz hier ist, eine Queue umzustzen in der die Ansagen "eingereiht" werden können und der Reihe nach abgearbeitet werden. Hierbei hat man nicht nur die Möglichkeit, Ansagen abspielen zu lassen sondern ggf. auch noch zu einem späteren Zeitpunkt wieder raus zu holen bevor die abgespielt wurden, falls sich z.B. zwischenzeitlich irgendetwas erledigt hat.
Um Ansagen abspielen zu lassen, verwendet man ttsqueue-cli.sh. Die Parameter sollten soweit selbsterklärend sein (Hilfe wird angezeigt, wenn das Skript ohne weitere Parameter aufgerufen wird).
Wichtig ist, dass man den Daemon startet. Dieser läuft ständig im Hintergrund und überwacht ein Queue-Verzeichnis auf neue Ansagen. Wird dort eine abgelegt, spielt dieser die dann entsprechend hintereinander ab.
Das Hauptproblem, wo man auf die schnelle reinlaufen könnte bei der ganzen Sache sind die Berechtigungen. Da fhem mit einem eigenen Benutzer fhem betrieben wird, habe ich ttsqueue so konzipiert das es auch mit entsprechenden Benutzerberechtigungen funktioniert. Man muss nur entsprechenden Benutzer in der Konfiguration eintragen und beachten, dass der Benutzer die Berechtigungen hat, auf das Audio-Device zuzugreifen.
Download: https://github.com/prodigy7/ttsqueue
HardwareIch habe meinem RPi einen Bluetooth-Dongle verpasst und steuere über diesen einen Bluetooth-Lautsprecher an (Der hier: http://www.amazon.de/gp/product/B00AY27V0Q?psc=1&redirect=true&ref_=oh_aui_detailpage_o01_s00). Genannten Lautsprecher kann ich empfehlen (Nein, ich arbeite nicht für Amazon)! Hat ordentlich Wums, satten Klang und Lautstärke und man kann ihn via USB-Kabel an irgendein Gerät permanent zum Laden dran hängen das einen USB-Port hat.
Würde mich freuen, wenn der eine oder andere auch noch was damit anfangen kann.
Das sieht sehr gut aus, damit kann ich Woll was anfangen! wenn ich mehr zeit habe werde ich mir das mall ausprobieren. Danke@!
Noch einige Fragen zum Bluetooth und Lautsprecher:
1.Was mich noch interessiert was deine Reichweite so ist mit dem Bluetooth stick und dem Lautsprecher?
2.Hört mann dann noch Neben Gerausche beim Lautsprecher wenn die da unbenutzt rum steht oder hört mann im dann einfach nicht?
3.Geht es zum beispiel durch ein Wand hin und wie weit ist dann die Entfernung?
4.Kann mann mehrere Bluetooth Lautsprecher gleichzeitig anschließen damit mann das im Ganzen Haus Hören kann? (dann kann ich mein Alte Libra Klingel damit auch Ersetzen im Haus)
5.Kann mann dann die Lautsprecher die ganze zeit ans Netz betreiben?
Ich Frage das da ich mich entscheiden Woll wie ich weiter vorgehe um die Stimme ins ganze Haus zu hören und keine Ansage mehr zu verpassen.
Danke im voraus!
Zitat von: Wouter-h am 20 Februar 2015, 22:53:211.Was mich noch interessiert was deine Reichweite so ist mit dem Bluetooth stick und dem Lautsprecher?
Kann ich dir nichts im Detail dazu sagen. Würde ich auf allgemeine Berichte im Internet zum Thema Reichweite und Bluetooth verweisen
Zitat von: Wouter-h am 20 Februar 2015, 22:53:212.Hört mann dann noch Neben Gerausche beim Lautsprecher wenn die da unbenutzt rum steht oder hört mann im dann einfach nicht?
Man hört ihn nicht
Zitat von: Wouter-h am 20 Februar 2015, 22:53:213.Geht es zum beispiel durch ein Wand hin und wie weit ist dann die Entfernung?
Siehe Punkt 1 ;) Bei mir geht es durch eine Wand problemlos.
Zitat von: Wouter-h am 20 Februar 2015, 22:53:214.Kann mann mehrere Bluetooth Lautsprecher gleichzeitig anschließen damit mann das im Ganzen Haus Hören kann? (dann kann ich mein Alte Libra Klingel damit auch Ersetzen im Haus)
Keine Ahnung. Musst du ausprobieren.
Zitat von: Wouter-h am 20 Februar 2015, 22:53:215.Kann mann dann die Lautsprecher die ganze zeit ans Netz betreiben?
Antwort siehe vorheriger Post von mir ;)