Daten von Wetterstation per SONOS Sprachausgabe

Begonnen von visionsurfer, 30 Oktober 2016, 11:42:52

Vorheriges Thema - Nächstes Thema

visionsurfer

Hallo,

ich habe das Sonos Modul erfolgreich installiert. Alles läuft bestens. Auch schon verschiedene Sprachansagen.

Zusätzlich hab ich bei mir auf dem Dach eine Wetterstation. Dort hab ich wetterstation_temp und wetterstation_regen definiert. Bei Regen wird mir der State ja oder nein angezeigt und bei der Temperatur steht die aktuelle Temperatur in Celsius.

Nun wollte ich mir gerne eine Sprachausgabe bauen, mit dem Ziel das ich morgens z.B. folgendes gesagt bekomme:

Es ist XY Grad, der Sonnenaufgang ist um XY Uhr und es regnet nicht.

Ich dachte mir, ich fang mal einfach und klein an:

So sieht mein List von der wetterstation_temp aus:


Internals:
   DEF        0/1/3:dpt9.001
   DEVNAME    wetterstation_temp
   IODev      KNX
   KNX_MSGCNT 146
   KNX_RAWMSG C1001w01030744
   KNX_TIME   2016-10-30 11:27:33
   LASTInputDev KNX
   MSGCNT     146
   NAME       wetterstation_temp
   NR         269
   NTFY_ORDER 50-wetterstation_temp
   STATE      18.60 °C
   TYPE       KNX
   Gaddr:
     1          0/1/3
   Gcode:
     1          0103
   Model:
     1          dpt9.001
   Readings:
     2016-10-30 11:27:33   getG1           18.60 °C
     2016-10-30 11:27:33   last-sender     1/0/1
     2016-10-30 11:27:33   state           18.60 °C
   Readingsname:
Attributes:
   IODev      KNX
   room       Wetter
   webCmd     :


Jetzt dachte ich in meinem Leichtsinn, ich kann das einfach mal wie folgt testen:

set Sonos_Esszimmer Speak 45 de Aktuelle Aussentemperatur ist [wetterstation_temp:state] Grad.

Das funktioniert schon fast. Wie man in meinem List sehen kann, steht bei state noch dieses "&ded;C" dabei. Das ließt Sonos nun als Fließtext mit vor.

Wie kann ich das weg bekommen, das er einfach nur 18,6 Grad liest ?
Das ist ja wahrscheinlich nur eine Kleinigkeit ?

Schwieriger wird es dann, wenn ich ja in dem gleichen Satz vorlesen lassen möchte, ob es regnet oder nicht. Mein List sieht dort so aus:


Internals:
   DEF        0/1/1:dpt1.002
   DEVNAME    wetterstation_regen
   IODev      KNX
   NAME       wetterstation_regen
   NR         281
   NTFY_ORDER 50-wetterstation_regen
   STATE      nein
   TYPE       KNX
   Gaddr:
     1          0/1/1
   Gcode:
     1          0101
   Model:
     1          dpt1.002
   Readings:
     2016-10-29 13:50:13   getG1           false
     2016-10-29 13:50:13   last-sender     1/0/1
     2016-10-29 13:50:13   state           false
Attributes:
   IODev      KNX
   eventMap   false:nein true:ja
   room       Wetter
   webCmd     :


Ich muss ja erst mal ermitteln wie der STATE ist ? Also ja oder nein. Hier bin ich mir unschlüssig wie ich das mache.
Sehr wahrscheinlich mit einem DOIF. Geht das mit FHEM eigenen befehlen oder muss ich dafür aufwendig irgendwelche Abfragen in Perl programmieren ?

Für Sonnenaufgang und Untergang muss ich mir erst mal anschauen woher ich die Daten bekommen. Ich hab gelesen das es da was mit Sunset usw. gibt. Lassen wir das erst mal außen vor. Das ist dann das I Tüpfelchen :)

Grüße,
Visionsurfer





DeeSPe

Nur mal nebenbei, ich habe das mittels zwei Funktionen (speakWetterDaten, speakWetterVorhersage) erledigt und dem "msg audio" Befehl.

Das was Du gezeigt hast soll ein DOIF werden oder? Kenne mich mit DOIF zwar nicht aus, aber was Du suchst ist glaube ich das hier:
set Sonos_Esszimmer Speak 45 de Aktuelle Aussentemperatur ist [wetterstation_temp:state:d] Grad.

Gruß
Dan
MAINTAINER: 22_HOMEMODE, 98_Hyperion, 98_FileLogConvert, 98_serviced

Als kleine Unterstützung für meine Programmierungen könnt ihr mir gerne einen Kaffee spendieren: https://buymeacoff.ee/DeeSPe

CoolTux

Deine Temperatur Ansage sieht wie ein DOIF aus. Wenn dem so ist schreibst du einfach

[wetterstation_temp:state:d]

Dann nimmt er nur Zahlenwerte.
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net

visionsurfer

Hallo,

na erst mal ist es ja quasi noch gar nichts. Ich hab das ganze ja nur durch einen SET Befehl einmalig getestet. Aber so funktioniert es. Zwar noch nicht 100% perfekt, aber 99%.

Jetzt redet Sonos und sagte noch einundzwanzig komma sechs null grad.

Ich denke damit er nicht noch null sagt, muss ich im eigentlichen Device wahrscheinlich irgendwie das Format verändert. Also nur auf eine Stelle nach dem Komma. So es das halt 21,6 heißt und nicht 21,60 ?

Das ist ja wahrscheinlich Einstellungssache beim Device.



Wie gesagt noch ist es nur Spielerei. Erst jetzt will ich dann sehen, wie ich wahrscheinlich aus einem DOIF einen kompletten Satz bekomme. Wie oben beschrieben "Aktuelle Außentemperatur ist XY und es regnet gerade nicht, oder Aktuelle Außentemperatur ist XY und es regnet.

Wobei jetzt wo ich den Satz schreibe, fällt mir eine Lösung ein. Wahrscheinlich doch einfacher als ich mir gedacht habe. Ich muss ja nur nach dem Motto arbeiten:

Wenn regen = ja, dann spiele Satz XY
oder
Wenn regen = nein, dann spiele Satz Z

Im jeweiligen Satz kann ich ja immer die Temperatur mit einbauen. Dann hätte ich es glaube ich so wie ich es will.


@DeeSPe:
O.K. aber das ist doch dann vorgefertigte Wettervorhersagen, oder ? Also für deinen Ort oder Region ?
Ich möchte mit Echtzeitdaten von meiner Wetterstation auf dem Dach arbeiten.
Die allgemeinen Wetterdaten, sind halt nur "allgemein". Können passen, können aber auch nicht passen. Meine Wetterstation ist dann sehr genau. Morgens, wissen dann der Hund und ich, ob es regnet oder nicht :)

Grüße,
Visionsurfer

DeeSPe

Meine anzusagenden Wetterdaten sind ein Mix aus meinen eigenen Daten wie Außentemp. und Luftfeuchtigkeit und den Daten die das Weather Modul bereit stellt.
Dazu habe ich den Wiki Artikel benutzt und auf meine Bedürfnisse angepasst und erweitert.
Kann ich bei Bedarf gerne zur Verfügung stellen.

Gruß
Dan
MAINTAINER: 22_HOMEMODE, 98_Hyperion, 98_FileLogConvert, 98_serviced

Als kleine Unterstützung für meine Programmierungen könnt ihr mir gerne einen Kaffee spendieren: https://buymeacoff.ee/DeeSPe

visionsurfer

Hi,

ok. Dann ist es natürlich was anderes. Ja würde mich interessieren, wie du es gemacht hast. Würde mich freuen, wenn du da was zur Verfügung stellen könntest.

Grüße,
Visionsurfer

DeeSPe

Im Prinzip wie im Wiki.

Alles in die 99_myUtils.pm.

Erst mal zwei Konstanten für den Wettersensor und das Weather Modul:
use constant
{
  # Aussentemperatur- und Luftfeuchtigkeitssensor
  DEVICE_NAME_TH      => "bz_Sensor1",
  # örtliches Wetter (Weather Modul)
  DEVICE_NAME_WEATHER => "Berlin",
};


Zwei Hilfsfunktionen um Zahlen zu runden:
# Rundet eine Zahl ohne Nachkommastellen
sub rundeZahl0($)
{
  my ($val) = @_;
  return int($val+0.5);
}

# Rundet eine Zahl mit 1-er Nachkommastelle
sub rundeZahl1($)
{
  my ($val) = @_;
  return sprintf("%.1f",$val)*1;
}


Und dann zwei Funktionen für Wetteransage und Wettervorhersage:
###############################################################################
# Sagt Wetterdaten an
#  Param: Art: Variante der Aussage:
#         0: Kurzansage, 1: Normal
###############################################################################
sub speakWetterDaten(;$)
{
  my ($art) = @_;
  $art = 1 if (!defined $art);
  my $temp = rundeZahl1(ReadingsVal(+DEVICE_NAME_TH,"temperature","unbekannt"));
  my $humi = rundeZahl0(ReadingsVal(+DEVICE_NAME_TH,"humidity","unbekannt"));
  my $cond = ReadingsVal(+DEVICE_NAME_WEATHER,"condition","unbekanntes Wetter");
  my $pres = ReadingsVal(+DEVICE_NAME_WEATHER,"pressure",1000);
  my $tren = ReadingsVal(+DEVICE_NAME_WEATHER,"pressure_trend_txt","gleichbleibend");
  my $istsind = $cond =~ /^(.und.|.Gewitter|.chauer)$/ ? "sind" : "ist";
  my $text = "$cond, $temp °C, Luftfeuchtigkeit $humi %, Luftdruck $pres Hektopascal.";
  $text = "Es $istsind $cond bei $temp °C und $humi % Luftfeuchtigkeit. Der Luftdruck ist $tren bei $pres Hektopascal."
    if ($art == 1);
  fhem "msg audio $text"
}

###############################################################################
# Sagt Wettervorhersage an.
#  Parameter: Tag: Zahl 1-5 (1-heute, 2-morgen,...) Defaul=2
###############################################################################
sub speakWetterVorhersage(;$)
{
  my ($day) = @_;
  $day = 2 if (!defined $day);
  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 = "Heute ";
  $text = "Morgen "                       if ($day == 2);
  $text = "Übermorgen "                   if ($day == 3);
  $text = "Wetter in ".($day-1)." Tagen " if ($day >  3);
  if (defined $t1 && defined $t2 && defined $t3)
  {
    $text.= $t1.".";
    $text.=" Temperatur von ".$t2." bis ".$t3." Grad Celsius.";
    if ($day == 1)
    {
      my $tg = ReadingsVal(+DEVICE_NAME_WEATHER,"wind_chill",undef);
      $text.= " Gefühlte Temperatur aktuell ".$tg." Grad Celsius." if (defined $tg);
      my $tw = ReadingsVal(+DEVICE_NAME_WEATHER,"wind_speed",undef);
      $text.= " Windgeschwindigkeit ".$tw." Kilometer pro Stunde." if (defined $tw);
    }
  }
  else
  {
    $text = "Leider keine Wettervorhersage verfügbar.";
  }
  fhem "msg audio $text";
}


Über "msg audio" wird dann alles auf meinem Sonos ausgegeben.
Lässt sich natürlich um beliebige andere Werte erweitern.

Falls was nicht klar sein sollte, frag einfach.

Gruß
Dan

EDIT: Falls Du msg noch nicht eingerichtet hast, dann nimm Dir am Besten dafür schon mal einen Abend Zeit. 8)
MAINTAINER: 22_HOMEMODE, 98_Hyperion, 98_FileLogConvert, 98_serviced

Als kleine Unterstützung für meine Programmierungen könnt ihr mir gerne einen Kaffee spendieren: https://buymeacoff.ee/DeeSPe

TomLee

Mir gings vor wenigen Wochen wie dir,darum hier noch ein weiterer Lösungsansatz zu:

ZitatIch denke damit er nicht noch null sagt, muss ich im eigentlichen Device wahrscheinlich irgendwie das Format verändert. Also nur auf eine Stelle nach dem Komma. So es das halt 21,6 heißt und nicht 21,60 ?

Das ist ja wahrscheinlich Einstellungssache beim Device.

Du erstellst wie schon selbst erkannt in jedem Device ein userreadings, hier beispielsweise das Device KG_Innensensor_Heizraum :

temperaturegerundet {sprintf('%.1f', ReadingsVal('KG_Innensensor_Heizraum','temperature',0));}

Das Ergebnis ist ein zusätzliches gerundetes Reading mit dem Namen temperaturegerundet. ☺

Das Wetter lass ich mir morgens vorlesen nachdem mein Wecklicht meinen Schlafraum voll erleuchtet mit diesem Code ,ebenfalls in die 99_myUtils gepackt:

sub Aufstehen($)
{
   my ($we) = @_;

   #hier können alle Schaltaktionen aufgerufen werden, die beim Aufstehen zu starten sind

wakeUp(30,"Mi_Wecklicht");
fhem("define Mi_Wecklichtatoff at +00:45:00 set Mi_Wecklicht off");

{my $temp = "|Temple| Guten Morgen Thomas . Die Außentemperatur beträgt zur Zeit :" .ReadingsVal("Aussensensor","temperature","unbekannt"). " °. Die Tageshöchsttemperatur liegt bei :".ReadingsVal("WetterMustadt","fc1_high_c","unbekannt"). "°. Die Wohnzimmer Temperatur bei :".ReadingsVal("OG_Innensensor_Wohnzimmer","temperaturegerundet","unbekannt")."°.";;fhem("define Sonostonausgabe at +00:24:37 set Sonos_Wohnzimmer_PLAY3 Speak 15 de $temp;set Sonos_Wohnzimmer_PLAY3 Volume 5")};
fhem("define Radioweckeroeffnen at +00:25:04 set Sonos_Wohnzimmer_PLAY3 StartRadio SWR4%20Rheinland-Pfalz");
fhem("define Sonostonausgabe2 at +00:27:00 set Sonos_Wohnzimmer_PLAY3 Volume 10");
fhem("define Sonostonausgabe3 at +00:29:00 set Sonos_Wohnzimmer_PLAY3 Volume 15");
fhem("define Sonostonausgabe4 at +00:30:00 set Sonos_Wohnzimmer_PLAY3 Volume 18");
fhem("define Radioweckerstop at +00:45:05 set Sonos_Wohnzimmer_PLAY3 Stop");

}





visionsurfer

Hi,

ich muss den Thread leider noch mal ausgraben. Ich versuche gerade meine Wetterdaten so einzustellen das SONOS nicht immer 7 komma vier null grad vorliest.
Ich möchte das es einfach sagt 7,4 Grad.

Dazu habe ich folgenden Code bei meinem Device eingefügt:

attr wetterstation_temp temperaturegerundet {sprintf('%.1f', ReadingsVal('wetterstation_temp','getG1',0));}

Ich hab jetzt auch ein neues Reading im Device, aber es steht dort 0.0

Was ist an meinem Code falsch ?

Hier mal das List vom Device:



Save config
Buero
Flur
Lounge
AMAD
CUL_HM
Essen
GaesteWC
Geräte
Gruppen
HUEDevice
Hauptbad
Helene
KNX
Kueche
Schlafzimmer
Sonos
TV
Unsorted
Wetter
icoEverything Everything
Logfile
Commandref
Remote doc
Edit files
Select style
Event monitor

Internals:
   DEF        0/1/3:dpt9.001
   DEVNAME    wetterstation_temp
   IODev      KNX
   KNX_MSGCNT 543
   KNX_RAWMSG C1001w010303ac
   KNX_TIME   2016-11-05 18:26:33
   LASTInputDev KNX
   MSGCNT     543
   NAME       wetterstation_temp
   NR         269
   NTFY_ORDER 50-wetterstation_temp
   STATE      9.40 °C
   TYPE       KNX
   Gaddr:
     1          0/1/3
   Gcode:
     1          0103
   Model:
     1          dpt9.001
   Readings:
     2016-11-05 18:26:33   getG1           9.40 °C
     2016-11-05 18:26:33   last-sender     1/0/1
     2016-11-05 18:26:33   state           9.40 °C
     2016-11-05 18:26:33   temperaturegerundet 0.0
   Readingsname:
Attributes:
   IODev      KNX
   room       Wetter
   userReadings temperaturegerundet {sprintf('%.1f', ReadingsVal('wetterstation_temp','getG1',0));}
   webCmd     :


Grüße,
Visionsurfer

DeeSPe

attr wetterstation_temp userReadings temperaturegerundet {sprintf('%.1f', ReadingsNum('wetterstation_temp','getG1',0));}
Damit sollte es gehen!

Würde es aber nur vor der Sonos Ausgabe runden und kein extra userReading dafür bemühen.

Gruß
Dan
MAINTAINER: 22_HOMEMODE, 98_Hyperion, 98_FileLogConvert, 98_serviced

Als kleine Unterstützung für meine Programmierungen könnt ihr mir gerne einen Kaffee spendieren: https://buymeacoff.ee/DeeSPe