Als ich Text2Speech Modul gesehen habe, hatte ich gleich einige Ideen, was man damit alles anfangen kann. :)
Eine davor war, die aktuellen Wetterdaten und die Vorhersage vorlesen zu lassen. Funktioniert wunderbar. Die entsprechenden Codefragmente habe ich in dem Modul-Thread zwar bereits gepostet, da jedoch diese dort kaum jemand später finden wird, habe ich mich entschlossen, das ganz noch mal hier zu wiederholen. Vielleicht findet noch jemand nützlich... ;)
Also der Reihe nach...
Zuerst die notwendigen FHEM-Devices:
1. Das Text2Speak-Device heißt bei mir 'tts'
2. Mein Temperatur/Feuchte-Sensor heißt 'GSD_1.4'
3. Das Weather-Modul heißt 'Wetter'
(Die Namen könnt ihr natürlich leicht anpassen. s. weiter...)
Jetzt der Code, packt den in irgendein Modul, 99_myUtils.pm ist ok.
Die Konstanten, die die Geräte-Namen festlegen:
use constant {
DEVICE_NAME_TTS => "tts",
DEVICE_NAME_TH => "GSD_1.4",
DEVICE_NAME_WEATHER => "Wetter",
};
Die zwei Methoden, die die eigentliche Sprachausgabe auslösen: speakWetterDaten(;$) und speakWetterVorhersage(;$).
Zum Testen kann man sie (wenn alles fertig eingetragen ist) direkt in der FHEM-Console (oder eben in der Commandline des Webinterfaces) eingeben:
{speakWetterDaten()}
und
{speakWetterVorhersage()}
Beide haben optionale Parameter, diese sind im Quellcode beschrieben.
###############################################################################
# Sagt Wetterdaten an
# Param: Art: Variante der Aussage:
# 0: Kurzansage, 1: Normal
###############################################################################
sub speakWetterDaten(;$) {
my($art)=@_;
if(!defined($art)){$art=1;}
# TODO: Sauber / Abstraktionslayer erstellen
my $temp = prepareNumToSpeak(rundeZahl0(ReadingsVal(+DEVICE_NAME_TH,"temperature","unbekannt")));
my $humi = prepareNumToSpeak(rundeZahl0(ReadingsVal(+DEVICE_NAME_TH,"humidity","unbekannt")));
if($art==0) {
#speak("Aussentemperatur ".$temp." Grad. Feuchtigkeit ".$humi." Prozent.",0);
speak($temp." Grad. Feuchtigkeit ".$humi." Prozent.",0);
}
if($art==1) {
#speak("Die Aussentemperatur betraegt ".$temp." Grad. Die Luftfeuchtigkeit liegt bei ".$humi." Prozent.",0);
speak("Temperatur ".$temp." Grad. Luftfeuchtigkeit ".$humi." Prozent.",0);
}
}
###############################################################################
# Sagt Wettervorhersage an.
# Parameter: Tag: Zahl 1-5 (1-heute, 2-morgen,...) Defaul=2
###############################################################################
sub speakWetterVorhersage(;$) {
my ($day) = @_;
if(!defined($day)) {$day=2;}
# TODO: Sauber / Abstraktionslayer erstellen
my $t1= ReadingsVal(+DEVICE_NAME_WEATHER,"fc".$day."_condition",undef);
my $t2= ReadingsVal(+DEVICE_NAME_WEATHER,"fc".$day."_low_c",undef);
my $t3= ReadingsVal(+DEVICE_NAME_WEATHER,"fc".$day."_high_c",undef);
my $text = "";
if($day==1) {
#$text = "Wetter heute ";
$text = "Heute ";
}
if($day==2) {
$text = "Morgen ";
}
if($day==3) {
$text = "Uebermorgen ";
}
if($day>3) {
$text = "Wetter in ".($day-1)." Tagen ";
}
if(defined($t1) && defined($t2) && defined($t3)) {
$text.=$t1.". ";
$text.="Temperatur von ".$t2." bis ".$t3." Grad.";
if($day==1) {
# gefuehlte Temperatur
my $tg= ReadingsVal(+DEVICE_NAME_WEATHER,"wind_chill",undef);
#$text.="Gefuehlte Temperatur aktuell ".$tg." Grad.";
$text.="Gefuehlte ".$tg." Grad.";
my $tw= ReadingsVal(+DEVICE_NAME_WEATHER,"wind_speed",undef);
#$text.="Windgeschwindigkeit ".$tw." Kilometer pro Stunde.";
$text.="Wind ".$tw." Kilometer pro Stunde.";
}
} else {
$text="Leider keine Vorhersage verfuegbar.";
}
speak($text,0);
}
und dann noch etwas an notwendigen Hilfsroutinen:
###############################################################################
# Bereitet Zahlen zur Ansage auf.
# Ersetzt Kommas und Punkte durch das Wort 'Komma'.
###############################################################################
sub prepareNumToSpeak($) {
my($text) = @_;
$text =~ s/\./Komma/g;
$text =~ s/,/Komma/g;
return $text;
}
# Rundet eine Zahl ohne Nachkommastellen
sub rundeZahl0($) {
my($val)=@_;
# Prüfen, ob numerisch
if(int($val)>0) {
$val = int($val+0.5);
}
return $val;
}
# Rundet eine Zahl mit 1-er Nachkommastelle
sub rundeZahl1($) {
my($val)=@_;
# Prüfen, ob numerisch
if(int($val)>0) {
$val = int(10*$val+0.5)/10;
}
return $val;
}
###############################################################################
# Bereitet Texte zur Ansage auf.
# Ersetzt Umlaute (ä=ae etc.)
###############################################################################
sub prepareTextToSpeak($) {
my($text) = @_;
# TODO: Ist halt noch nicht fertig geworden ;)
return $text;
}
ja, und dann die Methode, die den TTS-Modul anspricht. Die Lautstärke wird je nach Tageszeit geändert (also Nachts leiser etc.)
######################################################
# Sprachausgabe ueber Text2Speak Modul
# Parameter:
# - text: Auszugebender Text
# - volume (optional) - Lautstaerke
# (wenn nicht vorhaneden: wird aktuell gesetzte
# Lautstaerke benutzt,
# wenn 1 oder groesser: dieser Wert wird benutzt,
# wenn 0: adaptiv gesetzt je nach Fageszeit
# (also Nachts wesentlich leiser)
# (ggf. spaeter adaptiv durch ermitteln der Zimmerlautstaerke)
######################################################
sub speak($;$) {
my($text,$volume)=@_;
if(defined ($volume)) {
if(int($volume) >=1) {
fhem("set ".+DEVICE_NAME_TTS." volume ".$volume);
} else {
if(int($volume) == 0) {
# Adaptiv
my ($sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst) = localtime;
# 5 - sehr leise
# 10 - ok
# 50 - gut hoerbar
# 100 - default / gut laut
#
# 20:00 - 22:00 => 10
# 22:00 - 05:00 => 5
# 05:00 - 07:00 => 10
# 07:00 - 08:00 => 50
# 08:00 - 20:00 => 100
if ($hour>=20 && $hour<22) {$volume=18}
if ($hour>=22 || $hour<5) {$volume=8}
if ($hour>=5 && $hour<7) {$volume=15}
if ($hour>=7 && $hour<8) {$volume=40}
if ($hour>=8 && $hour<20) {$volume=100}
fhem("set ".+DEVICE_NAME_TTS." volume ".$volume);
}
}
}
fhem("set ".+DEVICE_NAME_TTS." tts ".prepareTextToSpeak($text));
}
Ich hoffe, ich habe nichts vergessen...
Wie kann man das Ganze sinnvoll einsetzen? Na zum Beispiel indem man die Methoden auf ein Funkbutton oder ein Bewegungsmelder legt und sich so jeden Morgen nach dem Aufstehen auf die Welt da draußen vorbereiten lässt ;D
Was braucht man an Hardware? Außer Wettersensoren werden aktive Boxen oder etwas in der Art benötigt, die an den Line-Out Ausgang des Rechners angeschlossen werden. Und natürlich etwas zum Aktivieren der Ansage.
Ich nutze einen in der Wand installierten Lautsprecher (http://www.pollin.de/shop/dt/MDI2OTUzOTk-/HiFi_Car_HiFi_Video_TV/Lautsprecher/Lautsprecherboxen/Decken_Einbau_Lautsprecher.html, lässt sich in einer tiefen UP-Dose installieren) der über eine kleine 3Watt Verstärkerplatine an meinen Cubietruck angeschlossen ist.
In der Zwischenzeit habe ich ein anderes interessantes Modul zur Wettervorharsage gesehen (PROPLANTA). Muss ich mir später genauer ansehen und ggf. auch für die Sprachausgabe verwenden.
Weiterhin lasse ich mir den Status der Fenster (ob welche geöffnet/gekippt sind, wie viele und wo) bei Verlassen des Hauses vorlesen und die Dauer der Abwesenheit beim Zurückkommen, habe auch einige Sonderschaltungen (z.B. einen ganz anderen Ton der Türklingel zum Halloween), aber das ist schon ein weiteres Thema...
Grüße,
Alexander
Tolle Arbeit
Danke :)
Sehr schick :)
Wäre was für das Wiki, meinst nicht?
Jetzt im WIKI: http://www.fhemwiki.de/wiki/Wetter_vorlesen_lassen
Erst mal Danke :)
Zitat{speakWetterDaten()}
Da war mal was...
Ich muss mich nur wieder erinnern wie ich es damals gemacht hatte:
Mit einem Dummy und einem Notify dazu könntest du es einfach mit einem
Zitatset TTS_Wetter heute
aufrufen
(hoffe das war jetzt kein kompletter Unsinn; wenn ich Zeit finde, probiere ich das mal aus)
Ungetestet:
Wir brauchen einen Dummy:
define TTS_Wetter_Heute dummy
Ein Notify welches auf den Dummy reagiert
define TTS_Wetter_Heute_Vorlesen notify TTS_Wetter_Heute {speakWetterDaten($EVENT)}
Dann müsste es so gehen:
set TTS_Wetter_Heute
set TTS_Wetter_Heute 0
set TTS_Wetter_Heute 1
Wie gesagt, ungetestet, habe das noch nicht am laufen. Vielleicht testet es mal wer?
Solange man nicht auf SAVE klickt, ist nach einem Neustart alles wieder weg ;)
Auf den ersten Blick muss das so gehen, aber was ist die Anwendung dafür? Irgendwas mit WebCMD in Webinterface? Oder wo ist es nicht einfacher, direkt eine Perl-Funktion aufzurufen?
Soll ich das Posting wieder löschen?
Nein, wieso?
Das war überhaupt keine Kritik. Ich war nur neugierig. ;) Villeicht habe ich eine nützliche Möglichkeit der Verwendung übersehen (passiert mir gat nicht so selten, betriebsblind ;D )
Dann bitte ich um Entschuldigung. Hatte es tatsächlich als Kritik aufgefasst und war deshalb ziemlich erstaunt, da ich dies nicht erwartet hatte.
Was den Einsatz angeht:
Viele Beispiele in der Commandref sind z.B. fhem-Syntax, nicht Perl.
Gerade für Anfänger dürfte es so leichter sein, denke ich wenigstens.
Hast du mal ausprobiert ob es so überhaupt stimmt? Würde mich interessieren :)
(Ich kann leider im Moment nicht)
So entstehen Missverständnisse :o
Tut mir leid, wenn meine Antwort unhöflich klang. :(
Die Anweisungen habe ich gerade getestet.
set TTS_Wetter_Heute funktioniert so natürlich nicht, das FHEM an dieser stelle ein Wert erwartet (no set value specified), aber mit 0 oder 1 tut das wie gewünscht. Ich denke, damit könnte man z.B. ein Button auf der Weboberfläche herzaubern.
Grüße,
Alexander
Schwamm drüber :)
Danke fürs ausprobieren :)
Du hast recht. Ohne Parameter ist Asche.
Magst den Dummy und das Notify noch ins Wiki dazuschreiben?
Oder wie bauen es schnell noch aus. Mit einem WebCmd und einer EventMap
Ja, ich denke, mit WebCmd und EventMap wird sich das ganz gut im Wiki machen ;)
Hallo,
ich habe das so wie beschrieben eingebaut. Was mich irritiert ist diese Konstante "unbekannt".
my $temp = prepareNumToSpeak(rundeZahl0(ReadingsVal(+DEVICE_NAME_TH,"temperature","unbekannt")));
my $humi = prepareNumToSpeak(rundeZahl0(ReadingsVal(+DEVICE_NAME_TH,"humidity","unbekannt")));
Was muss dort stehen?
Denn vorgelesen wird das Wetter nicht.
Immer diese Anfängerfehler, sorry.
Danke
Thomas
unbekannt steht nur für den Defaultwert wenn das Reading nicht gelesen werden kann (weil nicht vorhanden).
Das ist aber in der commandref unter ReadingsVal eindeutig beschrieben.
hat also nichts damit zu tun dass es bei Dir nicht funktioniert.
Gruß
Dan
Vielen Dank....
Problem ist und bleibt wie ich das konkret aufrufe, dass z.B. um 06:00 Uhr das Wetter vorgelesen wird.
Wiki hin und her - klar lese ich dort auch, doch zum Ergebnis hat das auch nicht geführt.
Gruß
Thomas
Zitat von: Elbgeist am 17 August 2016, 14:53:45
Vielen Dank....
Problem ist und bleibt wie ich das konkret aufrufe, dass z.B. um 06:00 Uhr das Wetter vorgelesen wird.
Wiki hin und her - klar lese ich dort auch, doch zum Ergebnis hat das auch nicht geführt.
Gruß
Thomas
Das war aber nicht Deine ursprüngliche Frage. Du fragtest was es mit dem unbekannt auf sich hat.
Um Deine aktuelle Frage zu beantworten:
Das könnte man z.B. per at machen:
define at_Wetter_6uhr at *06:00:00 {speakWetterDaten()}
Gruß
Dan
Hi Dan,
ja ich weiß, ich wollte nicht zu gierig sein mit Fragen.
Ich weiß Deine Hilfsbereitschaft zu schätzen, es ist samt Wiki auch als Anfänger nicht immer so durchsichtig.
Habe Deinen Vorschlag mal angelegt und Verbose auf 5 gesetzt - FHEM will mit mir nicht sprechen.
Log:
2016.08.17 15:02:00 5: exec at command at_Wetteransage_6uhr
2016.08.17 15:02:00 5: redefine at command at_Wetteransage_6uhr as *15:02:00 {speakWetterDaten()}
Text2Speech geht aber, das habe ich schon getestet - wie im Wiki angegeben.
Hast Du vielleicht noch eine Idee, bitte?
Gruß
Thomas
Die am Anfang definierten Konstanten auch mit den (für Dein FHEM) richtigen Werten (Gerätenamen) gefüttert?
use constant {
DEVICE_NAME_TTS => "tts",
DEVICE_NAME_TH => "GSD_1.4",
DEVICE_NAME_WEATHER => "Wetter",
};
Gruß
Dan
Ja, Wetterdaten kommen damit von Yahoo und funktionieren auch.
use constant {
DEVICE_NAME_TTS => "MyTTS",
DEVICE_NAME_TH => "TH_Balkon",
DEVICE_NAME_WEATHER => "Wetterbericht",
};
TTS geht wie bereits erwähnt, TH_Balkon liefert Temperatur und Luftfeuchte, Wetterbericht klappt auch.
Gruß
Thomas
TTS funktioniert wirklich? Getestet?
Gibt es beim Device TH_Balkon wirklich Readings für temperature und humidity ?
Was passiert bei einem
{speakWetterDaten()}
in der FHEM Eingabezeile?
Wenn absolut nichts geht, dann kann man nur Stück für Stück Log Ausgaben mit einbauen und schauen an welcher Stelle es hakt.
Gruß
Dan
EDIT: FHEM ist aktuell?
Hi Dan,
FHEM ist aktualisiert und auf neuestem Stand.
TTS ist mit dem obligatorischen Satz
Zitatset MyTTS tts Das ist ein Test. Jetzt prüfen wir, ob wir etwas aus dem angeschlossenen Lautsprecher hören. Beim ersten Mal haben wir allerdings noch Sprechpausen. Spätestens beim zweiten Durchlauf ist der Textfluss flüssiger.
getestet und gestern funktionierte das. Heute geht das nicht mehr.....
Grund dafür, ich hatte gestern noch ein attr Volume_Adjust hinzugefügt weil es ein bisschen leise war. Anscheinend hat das blockiert, wieso auch immer. Attribut wieder raus, TTS spricht wieder und Wetter geht auch.
Vielen Dank für Deine gebotene Hilfe, hat mich zumindest wieder auf den richtigen Pfad gebracht.
Gruß
Thomas
Gerne, manchmal hilft darüber zu philosophieren schon, weil einem auf einmal klar wird dass man irgendwas anderes verbastelt hat...
Gruß
Dan
Hallo, ich habe die Temperaturansage mittels eines DOIF und AMAD auf einem Fire Tablet realisiert. Vielleicht hilft´s ja..
[[du_temp] eq "on" and TX29DTH_IT_1:temperature] >5.0) (set Fire ttsMsg die aktuelle Aussentemperatur beträgt [TX29DTH_IT_1:temperature] Grad) DOELSEIF ([du_temp] eq "on" and [TX29DTH_IT_1:temperature] <5.0) (set Fire ttsMsg Achtung! Frostgefahr!Die aktuelle Aussentemperatur beträgt [TX29DTH_IT_1:temperature] Grad)
Gruß Jürgen K.
Zitat von: juergen012 am 17 August 2016, 18:17:06
Hallo, ich habe die Temperaturansage mittels eines DOIF und AMAD auf einem Fire Tablet realisiert. Vielleicht hilft´s ja.
Hallo Jürgen,
vielen Dank, das nehme ich gerne mit.
Gruß
Thomas
Bin gerade über dieses Beitrag gestolpert.
Baue mir gerade etwas ähnliches, hatte es schon mit dem Yahoo Wetter Modul umgesetzt, aber das liefert relativ ungenaue Werte, deshalb will ich auch Proplanta umsteigen. Um die Ausgabe ein wenig natürlicher zu machen formuliere ich die Condition um. Für Yahoo gibt es eine vollständige Liste aller Möglichkeiten, für Proplanta kann ich leider nix ähnliches finden.
Wenn ich das richtig sehe gibt es 14 Zustände, follgende kenne ich schon.
Zitat1
2 heiter
3 wolkig
4 stark bewoelkt
5 bedeckt
6 Regenschauer
7 Regen
8
9
10
11
12 Nebel
13
14
Vielleicht kann mir jemand eine vollständige Liste zukommen lassen, oder hilft mir die liste zu vervollständigen.
Zitat von: mrbreil am 13 Oktober 2016, 11:14:06
Um die Ausgabe ein wenig natürlicher zu machen formuliere ich die Condition um. Für Yahoo gibt es eine vollständige Liste aller Möglichkeiten...
Wo gibt es die denn? Konnte mit Suchen bisher nichts finden.
Danke.
Gruß
Dan
https://forum.fhem.de/index.php/topic,21375.msg206030.html#msg206030
Da sind alle Möglichkeiten aufgelistet.
Merci, danach habe ich schon hin und wider gesucht.
Dank der Auflistung konnte ich nun auch mein "ist/sind" richtig setzen.
Gruß
Dan
Hallo zusammen,
wie hört sich die Ausgabe den an? Ich habe mir bei YouTube ein paar Beispiele von speak und SVOX angehört aber die warn ja sehr "blechern"
Kann jemand vielleicht eine Ausgabe als MP3 hier zum Probehören bereitstellen. Ich bin nämlich gerade in der Planungsphase und das würde mich sehr interessieren.
Ich habe bei Youtube etwas gefunden aber da waren das MP3 Dateien die von der Homematic Funk Glocke abgespielt werden, die MP3 sind vorher erstellt worden.
Vielen Dank vorab.
Gruß Eddie
Hier was in der gewünschten Sprache eintippen und auf den Lautsprecher klicken.
https://translate.google.de
Das ist die default TTS Stimme.
Gruß
Dan
Ah. Super! Hört sich nicht schlecht, an bei manchen Kommas bzw Punkten springt sie schnell drüber aber so hört sich das schon brauchbar an und ist gut verständlich.