Intention dieses Artikels

Im homematic Forum gibt es zahlreiche Artikel zu diesem Thema, die sich in den letzten Jahren angesammelt haben. Auch der homematic Guru hat hier einen ausführlichen Beitrag erstellt.


Letzten Endes verwenden alle ein Script aus dem Jahr 2014 mit mehr oder weniger Variationen. Dabei gibt es zwei Hauptprobleme.

  • Es wird ein wunderground API Key benötigt (Den bekommt man entweder gegen Gebühr, oder wenn man, wie ich, eine Station betreibt, die an wunderground meldet.)
  • Die API hat sich seit 2014 völlig verändert. 


Da ich mir keine teuren homematic Wetterkomponenten leisten will, unter anderem, weil es keine schicke Anzeige fürs Wohnzimmer dafür gibt, hole ich die Werte meiner Station eben über ein homematic Script ab.


Das Original des von mir verwendeten Scripts befindet sich hier


Leider hat es für den Veröffentlicher seinerzeit nicht richtig funktioniert. Ich habe daran drei Änderungen durchgeführt.

  • Die Daten werden über die homematic Exec Engine geholt.
  • Es wurde für jeden ermittelten Wert ein WriteLine(Variable) Wert eingesetzt.
  • Der Versuch den XML Header zu manipulieren wurde entfernt


Daraus ergibt sich ein Vorgehen, wie weitgehend in den anderen Lösungsvorschlägen beschrieben.


1. Anlegen der Systemvariablen

Die Sytemvariablen werden unter Einstellungen => Systemvariablen angelegt


VariableTypBeschreibung / BemerkungEinheit
W_StationZeichenketteabgefragte Wetterstation
W_AktualisierungZeichenketteAbfragezeit
W_TemperaturZahlgemeldete Temperatur°C
W_LuftfeuchteZahlgemeldete Luftfeuchte%
W_WindrichtgZahlWindrichtung in °°
W_WindgeschwindigkeitZahlWindgeschwindigkeit in km/hkm/h
W_WindboeenZahlWindböen Geschwindigkeitkm/h
W_LuftdruckZahlLuftdruckmbar
W_TaupunktZahlTaupunkt°C
W_UVZahlUV-Index
W_SolarZahlSolarleistung Watt/m²
W_RegenrateZahlRegen der letzten Stundemm/h
W_RegensummeZahlegen des letzten Tagesmm/d
W_HitzeindexZahlHitzeindex°C
W_Temp_gefuehlt ZahlWindChill Temperatur°C
AussentemperaturZeichenkette(Erweiterung E.Simdorn) Schöner formatierte Außentemperatur für Favoriten
LuftfeuchtigkeitZeichenkette(Erweiterung E.Simdorn)Schöner formatierte Luftfeuchtigkeit für Favoriten 

Die Systemvariablen kann man, zum Beispiel nach einem Test des Scriptes unter Geräte => Systemvariablen abfragen.

 2. Anpassen des Scriptes

Die Abfrage mit CUXD habe ich nicht verwendet, deswegen ist sie auskommentiert.

Im folgenden Script muss die gewünschte StationsID und der eigene API-Key ergänzt werden:


!Stand 7.04.2021 https://homematic-forum.de/forum/viewtopic.php?f=18&t=17209&hilit=senden&start=690
! Wetter api: stationID=Deine Wetterstation, apiKey=Dein apiKey der Wetterstation, units: m (metrisch) oder e(englisch), format: xml (gibt es auch als json)

var url = "http://api.weather.com/v2/pws/observations/current?stationId=DEINE_Station&format=xml&units=m&apiKey=DEIN_API-Key";

       !hier ist die Abfrage mit CUxD
       ! dom.GetObject("CUxD.CUX2801001:1.CMD_SETS").State("wget -q -O - '"#url#"'");
        !dom.GetObject("CUxD.CUX2801001:1.CMD_QUERY_RET").State(1);
        !string wetter_xml = dom.GetObject("CUxD.CUX2801001:1.CMD_RETS").State();
 
        !hier ist die Abfrage mit system.Exec
        string stdout;
        string stderr;
        system.Exec("wget -q -O - '"#url#"'", &stdout, &stderr);
        WriteLine(stdout);
        string wetter_xml = stdout;
        WriteLine(wetter_xml);
 
 
  
 !Daten mit Suchworten aus XML-File ausfiltern:

string word = "neighborhood";
integer word_laenge = word.Length();
integer word_position = wetter_xml.Find(word);
string daten = wetter_xml.Substr((word_position + word_laenge +1), 100);
integer word_position = daten.Find(word);
daten = daten.Substr(0, (word_position -2));
daten = daten;
WriteLine(daten);
dom.GetObject("W_Station").State(daten);

string word ="obsTimeLocal";
integer word_laenge = word.Length();
integer word_position = wetter_xml.Find(word);
string daten = wetter_xml.Substr((word_position + word_laenge +1), 100);
integer word_position = daten.Find(word);
daten = daten.Substr(0, (word_position -2));
!daten = daten.Substr(0, (word_position -11));
WriteLine(daten);
dom.GetObject("W_Aktualisierung").State(daten);

string word = "temp";
integer word_laenge = word.Length();
integer word_position = wetter_xml.Find(word);
string daten = wetter_xml.Substr((word_position + word_laenge +1), 100);
integer word_position = daten.Find(word);
daten = daten.Substr(0, (word_position -2));
real zahl = daten.ToFloat();
WriteLine(zahl);
dom.GetObject("W_Temperatur").State(zahl);
! *****
! Temperatur real in string umwandeln und anschliessend den Dezimalpunkt gegen ein Komma austauschen
string TextTemp = zahl.ToString(2);
integer TPunkt = TextTemp.Find(".");
string TextTemp1 = TextTemp.Substr(0, TPunkt);
TextTemp1 = TextTemp1 # ","# TextTemp.Substr(TPunkt +1, 2) # " Grad Celsius";
TextTemp = TextTemp1;
dom.GetObject('Aussentemperatur').Variable(TextTemp);
WriteLine(dom.GetObject('Aussentemperatur').Variable());
! *****
string word = "humidity";
integer word_laenge = word.Length();
integer word_position = wetter_xml.Find(word);
string daten = wetter_xml.Substr((word_position + word_laenge +1), 100);
integer word_position = daten.Find(word);
daten = daten.Substr(0, (word_position -2));
integer zahl = daten.ToFloat();
WriteLine(zahl);
dom.GetObject("W_Luftfeuchte").State(zahl);
! *****
string TextHumi = zahl.ToString(1);
integer TPunkt = TextHumi.Find(".");
string TextHumi1 = TextHumi.Substr(0, TPunkt);
TextHumi1 = TextHumi1 # ","# TextHumi.Substr(TPunkt +1, 2) # " %";
TextHumi = TextHumi1;
dom.GetObject('Luftfeuchtigkeit').Variable(TextHumi);
WriteLine(dom.GetObject('Luftfeuchtigkeit').Variable());
! *****

string word = "winddir";
integer word_laenge = word.Length();
integer word_position = wetter_xml.Find(word);
string daten = wetter_xml.Substr((word_position + word_laenge +1), 100);
integer word_position = daten.Find(word);
daten = daten.Substr(0, (word_position -2));
if (daten == -9999) {
daten = "0";
}
integer zahl = daten.ToFloat();
WriteLine(zahl);
dom.GetObject("W_Windrichtg").State(zahl);

string word = "windSpeed";
integer word_laenge = word.Length();
integer word_position = wetter_xml.Find(word);
string daten = wetter_xml.Substr((word_position + word_laenge +1), 100);
integer word_position = daten.Find(word);
daten = daten.Substr(0, (word_position -2));
integer zahl = daten.ToFloat();
WriteLine(zahl);
dom.GetObject("W_Windgeschwindigkeit").State(zahl);

string word = "windGust";
integer word_laenge = word.Length();
integer word_position = wetter_xml.Find(word);
string daten = wetter_xml.Substr((word_position + word_laenge +1), 100);
integer word_position = daten.Find(word);
daten = daten.Substr(0, (word_position -2));
integer zahl = daten.ToFloat();
WriteLine(zahl);
dom.GetObject("W_Windboeen").State(zahl);

string word = "pressure";
integer word_laenge = word.Length();
integer word_position = wetter_xml.Find(word);
string daten = wetter_xml.Substr((word_position + word_laenge +1), 100);
integer word_position = daten.Find(word);
daten = daten.Substr(0, (word_position -2));
integer zahl = daten.ToFloat();
WriteLine(zahl);
dom.GetObject("W_Luftdruck").State(zahl);

string word = "dewpt";
integer word_laenge = word.Length();
integer word_position = wetter_xml.Find(word);
string daten = wetter_xml.Substr((word_position + word_laenge +1), 100);
integer word_position = daten.Find(word);
daten = daten.Substr(0, (word_position -2));
real zahl = daten.ToFloat();
WriteLine(zahl);
dom.GetObject("W_Taupunkt").State(zahl);

string word = "windChill";
integer word_laenge = word.Length();
integer word_position = wetter_xml.Find(word);
string daten = wetter_xml.Substr((word_position + word_laenge +1), 100);
integer word_position = daten.Find(word);
daten = daten.Substr(0, (word_position -2));
real zahl = daten.ToFloat();
WriteLine(zahl);
dom.GetObject("W_Temp_gefuehlt").State(zahl);

string word = "heatIndex";
integer word_laenge = word.Length();
integer word_position = wetter_xml.Find(word);
string daten = wetter_xml.Substr((word_position + word_laenge +1), 100);
integer word_position = daten.Find(word);
daten = daten.Substr(0, (word_position -2));
real zahl = daten.ToFloat();
WriteLine(zahl);
dom.GetObject("W_Hitzeindex").State(zahl);

string word = "uv";
integer word_laenge = word.Length();
integer word_position = wetter_xml.Find(word);
string daten = wetter_xml.Substr((word_position + word_laenge +1), 100);
integer word_position = daten.Find(word);
daten = daten.Substr(0, (word_position -2));
integer zahl = daten.ToFloat();
WriteLine(zahl);
dom.GetObject("W_UV").State(zahl);

string word = "precipRate";
integer word_laenge = word.Length();
integer word_position = wetter_xml.Find(word);
string daten = wetter_xml.Substr((word_position + word_laenge +1), 100);
integer word_position = daten.Find(word);
daten = daten.Substr(0, (word_position -2));
real zahl = daten.ToFloat();
WriteLine(zahl);
dom.GetObject("W_Regenrate").State(zahl);

string word = "precipTotal";
integer word_laenge = word.Length();
integer word_position = wetter_xml.Find(word);
string daten = wetter_xml.Substr((word_position + word_laenge +1), 100);
integer word_position = daten.Find(word);
daten = daten.Substr(0, (word_position -2));
real zahl = daten.ToFloat();
WriteLine(zahl);
dom.GetObject("W_Regensumme").State(zahl);

string word = "solarRadiation";
integer word_laenge = word.Length();
integer word_position = wetter_xml.Find(word);
string daten = wetter_xml.Substr((word_position + word_laenge +1), 100);
integer word_position = daten.Find(word);
daten = daten.Substr(0, (word_position -2));
real zahl = daten.ToFloat();
WriteLine(zahl);
dom.GetObject("W_Solar").State(zahl);


 Das Script über die Zeitsteuerung der homematic starten:


Anzeige in der CCU

Wer will, kann sich jetzt die Variablen auf der Favoritenseite ausgeben lassen:

Die Seite wird mit Hilfe von Einstellungen => Favoriten => Neu erstellt.



Meine Station in der weathercloud: