DWD - mknx/smarthome GitHub Wiki
This logic uses the DWD plugin to receive weather warnings and forecast from Deutscher Wetterdienst (DWD). Therefore I'm not going to translate the item and variable names and describe the logic in german.
Die Werte für die Orte und Bereiche heraussuchen geht wie folgt:
Mit dem Account von DWD auf ftp://ftp-outgoing2.dwd.de anmelden. Einen Account kann man hier anlegen http://kunden.dwd.de/gdsRegistration/gdsRegistrationStart.do
Aktuelle Werte: Nach /gds/specials/observations/tables/germany/ wechseln und eine Datei öffnen. In der Datei steht in der ersten Spalte die vorhandenen Stationen, hier die gewünschte aussuchen und unten in der Datei wetter.py bei "current = sh.dwd.current('Würzburg')" das "Würzburg" damit ersetzen.
Vorhersagen: Nach /gds/specials/forecasts/tables/germany/ wechseln und die passende Datei für sich aussuchen. Datei öffnen und in der ersten Spalte den gewünschten Ort aussuchen. In der Datei wetter.py unten bei "forecast = sh.dwd.forecast('Mitte', 'Würzburg')" das "Mitte" durch den Teil des Dateinamen ersetzen den man gewählt hat (z.B. aus "Daten_Nordost_nacht" den Namen zwischen den Unterstrichen auswählen also "Nordost") und "Würzburg" durch den gewählten Ort ersetzen.
UV-Index: Nach /gds/specials/warnings/FG/ wechseln und die Datei u_vindex12.xml öffnen, hier im XLM den gewünschten Ort aussuchen und unten in der Datei wetter.py bei "uvi = sh.dwd.uvi('Würzburg')" das "Würzburg" damit ersetzen.
Pollenvorhersage: In der Datei s_b31fg.xml unter /gds/specials/warnings/FG/ öffnen und den Namen seiner Region eintragen in der Datei wetter.py bei "pollen = sh.dwd.pollen('Mainfranken')".
Unwetter-Warnungen: Die Excel Tabelle unter gds/specials/warnings/legend_warnings.xls öffnen und den Reiter Regionen auswählen. Dort in Spalte "Kreis- / Stadt-Name" seine/n Stadt/Kreis suchen. In der Datei logics/wetter_warnungen.py die Zeile "warnings = sh.dwd.warnings('MS', 'WUEX')" den Wert 'MS' aus der Spalte "RZ" und 'WUEX' mit dem Wert aus Spalte "DWD-Kennung" + "X" ersetzen (aus WUE wird WUEX).
Eine Warnung vorweg: das ist mit Abstand das kompliziertete Plugin bzw. liefert es sehr viele Information die man verarbeiten kann/muss. Deswegen ist die item conf und die entsprechenden Logiken dafür etwas länger...
# items/wetter.conf
[wetter]
name = DWD Wetter
[[temperatur]]
name = Temperatur
type = num
visu = rrd
rrd = yes
[[niederschlag]]
name = Niederschlag
type = num
unit = mm
visu = rrd
rrd = yes
[[wetter]]
name = Wetter/Wolken
type = str
visu = div
[[luftdruck]]
name = Luftdruck
type = num
visu = div
[[windrichtung]]
name = Windrichtung
type = str
visu = div
[[windgeschwindigkeit]]
name = Windgeschwindigkeit
type = num
unit = km/h
visu = div
[[boen]]
name = Böen
type = str
visu = div
[[vorhersage]]
name = Wettervorhersage
type = list
visu = list
[[[d0]]]
name = Heute
[[[[frueh]]]]
[[[[[temperatur]]]]]
type = str
[[[[[wolken]]]]]
type = str
[[[[[wind]]]]]
type = str
[[[[mittag]]]]
[[[[[temperatur]]]]]
type = str
[[[[[wolken]]]]]
type = str
[[[[[wind]]]]]
type = str
[[[[spaet]]]]
[[[[[temperatur]]]]]
type = str
[[[[[wolken]]]]]
type = str
[[[[[wind]]]]]
type = str
[[[[nacht]]]]
[[[[[temperatur]]]]]
type = str
[[[[[wolken]]]]]
type = str
[[[[[wind]]]]]
type = str
[[[[uv]]]]
type = num
[[[[pollen]]]]
name = Pollenvorhersage
[[[[[graeser]]]]]
type = str
[[[[[roggen]]]]]
type = str
[[[d1]]]
name = Morgen
[[[[frueh]]]]
[[[[[temperatur]]]]]
type = num
[[[[[wolken]]]]]
type = str
[[[[[wind]]]]]
type = str
[[[[spaet]]]]
[[[[[temperatur]]]]]
type = num
[[[[[wolken]]]]]
type = str
[[[[[wind]]]]]
type = str
[[[[uv]]]]
type = num
[[[[pollen]]]]
name = Pollenvorhersage
[[[[[graeser]]]]]
type = str
[[[[[roggen]]]]]
type = str
[[[d2]]]
name = Übermorgen
[[[[frueh]]]]
[[[[[temperatur]]]]]
type = num
[[[[[wolken]]]]]
type = str
[[[[[wind]]]]]
type = str
[[[[spaet]]]]
[[[[[temperatur]]]]]
type = num
[[[[[wolken]]]]]
type = str
[[[[[wind]]]]]
type = str
[[[[uv]]]]
type = num
[[[[pollen]]]]
name = Pollenvorhersage
[[[[[graeser]]]]]
type = str
[[[[[roggen]]]]]
type = str
[[[d3]]]
name = In drei Tagen
[[[[frueh]]]]
[[[[[temperatur]]]]]
type = num
[[[[[wolken]]]]]
type = str
[[[[[wind]]]]]
type = str
[[[[spaet]]]]
[[[[[temperatur]]]]]
type = num
[[[[[wolken]]]]]
type = str
[[[[[wind]]]]]
type = str
[[warnungen]]
name = Wetterwarnungen
type = list
visu = list
[[[hitze]]]
type = bool
visu = checkbox
[[[uv]]]
type = bool
visu = checkbox
[[[wind]]]
type = bool
visu = checkbox
[[[regen]]]
type = bool
visu = checkbox
[[[nebel]]]
type = bool
visu = checkbox
[[[sturm]]]
type = bool
visu = checkbox
[[[schnee]]]
type = bool
visu = checkbox
[[[frost]]]
type = bool
visu = checkbox
[[[glaette]]]
type = bool
visu = checkbox
#!/usr/bin/env python
# vim: set encoding=utf-8 tabstop=4 softtabstop=4 shiftwidth=4 expandtab
#########################################################################
#
# logics/wetter.py
#
import dateutil.relativedelta
# icon mapping für die Visu
images = {
'bedeckt': '26.png',
'bewölkt': '26.png',
'Dunst oder flacher Nebel': '.png',
'gering bewölkt': '.png',
'Gewitter': '.png',
'Glatteisbildung': '.png',
'Graupelschauer': '.png',
'Hagelschauer': '.png',
'heiter': '30.png',
'in Wolken': '.png',
'kein signifikantes Wetter': '.png',
'kräftiger Graupelschauer': '.png',
'kräftiger Hagelschauer': '.png',
'kräftiger Regen': '12.png',
'kräftiger Regenschauer': '12.png',
'kräftiger Schneefall': '.png',
'kräftiger Schneeregen': '.png',
'kräftiger Schneeregenschauer': '.png',
'kräftiger Schneeschauer': '.png',
'leicht bewölkt': '.png',
'leichter Regen': '11.png',
'leichter Schneefall': '.png',
'leichter Schneeregen': '.png',
'Nebel': '20.png',
'Regen': '11.png',
'Regenschauer': '12.png',
'Sandsturm': '.png',
'Schneefall': '.png',
'Schneefegen': '.png',
'Schneeregen': '.png',
'Schneeregenschauer': '.png',
'Schneeschauer': '.png',
'schweres Gewitter': '.png',
'starkes Gewitter': '.png',
'wolkenlos': '31.png'
}
current = sh.dwd.current('Würzburg')
forecast = sh.dwd.forecast('Mitte', 'Würzburg')
uvi = sh.dwd.uvi('Würzburg')
pollen = sh.dwd.pollen('Mainfranken')
sh.dwd.ftp_quit()
# Datum für die einzelne Tage berechnen
d0 = sh.now().date()
d1 = (sh.now() + dateutil.relativedelta.relativedelta(days=1)).date()
d2 = (sh.now() + dateutil.relativedelta.relativedelta(days=2)).date()
d3 = (sh.now() + dateutil.relativedelta.relativedelta(days=3)).date()
# Current
if "TT" in current:
sh.wetter.temperatur(current["TT"])
if "RR1" in current:
sh.wetter.niederschlag(current["RR1"])
if "Luftd." in current:
sh.wetter.luftdruck(current["Luftd."])
if "FF" in current:
sh.wetter.windgeschwindigkeit(current["FF"])
if "DD" in current:
sh.wetter.windrichtung(current["DD"])
if "Wetter/Wolken" in current:
sh.wetter.wetter(current["Wetter/Wolken"])
if "Böen" in current:
if current["Böen"] == '---':
sh.wetter.boen('')
else:
sh.wetter.boen(current["Böen"])
# Forecast
items = { d0: sh.wetter.vorhersage.d0, d1: sh.wetter.vorhersage.d1, d2: sh.wetter.vorhersage.d2, d3: sh.wetter.vorhersage.d3}
for date in forecast:
if date.date() in items:
base = items[date.date()]
if date.hour == 6:
frame = base.frueh
elif date.hour == 12:
frame = base.mittag
elif date.hour == 23:
frame = base.nacht
else: # hour == 18
frame = base.spaet
frame.temperatur(forecast[date][0])
frame.wolken(forecast[date][1])
frame.wind(forecast[date][2])
logger.info(forecast)
vorhersage = []
day = ''
def forecaststring(day, forecast, images):
fc = ''
for date in sorted(forecast):
if date.strftime("%Y%m%d") == day:
if forecast[date][0] != '':
fc += '<img src="/img/weather/{1}"> {0} °C '.format(forecast[date][0], images[forecast[date][1]])
return fc
# Zusammenfassung für die Startseite
sh.wetter.vorhersage.d0(forecaststring(sh.wetter.vorhersage.d0, forecast, images))
sh.wetter.vorhersage.d1(forecaststring(sh.wetter.vorhersage.d1, forecast, images))
# Ausführlich für die Wetterseite
for date in sorted(forecast):
if date.date() > d1:
continue
if date.strftime("%A") != day:
vorhersage.append('<li data-role="list-divider">{0:%A}<p class="ui-li-aside">{0:%d.%m.%Y}</p></li>'.format(date))
day = date.strftime("%A")
if forecast[date][0] != '':
if forecast[date][1] in images:
vorhersage.append('<li><img src="/img/weather/{1}"> {0} °C {2} {3}</li>'.format(forecast[date][0], images[forecast[date][1]], forecast[date][1], forecast[date][2]))
else:
vorhersage.append('<li>{0} °C {1} {2}</li>'.format(forecast[date][0], forecast[date][1], forecast[date][2]))
sh.wetter.vorhersage(vorhersage)
# UV Index
for date in uvi:
if date.date() in items:
base = items[date.date()]
base.uv(uvi[date])
# Pollen
#logger.info('Pollen:{0}'.format(pollen))
#poltypes = {'Birke', 'Beifuss', 'Esche', 'Roggen', 'Ambrosia', 'Hasel', 'Erle', 'Graeser'}
for date in pollen:
if date.date() in items:
base = items[date.date()]
base.pollen.roggen(pollen[date].get('Roggen'))
base.pollen.graeser(pollen[date].get('Graeser'))
#!/usr/bin/env python
# vim: set encoding=utf-8 tabstop=4 softtabstop=4 shiftwidth=4 expandtab
#########################################################################
#
# logics/wetter_warnungen.py
#
import dateutil.relativedelta
warnings = sh.dwd.warnings('MS', 'WUEX')
sh.dwd.ftp_quit()
# Wetterwarnungen
types = {'Glätte': {'flag': False, 'item': sh.wetter.warnungen.glaette},
'Schnee': {'flag': False, 'item': sh.wetter.warnungen.schnee},
'Frost': {'flag': False, 'item': sh.wetter.warnungen.frost},
'Hitze': {'flag': False, 'item': sh.wetter.warnungen.hitze},
'UV': {'flag': False, 'item': sh.wetter.warnungen.uv},
'Nebel': {'flag': False, 'item': sh.wetter.warnungen.nebel},
'Regen': {'flag': False, 'item': sh.wetter.warnungen.regen},
'Sturm': {'flag': False, 'item': sh.wetter.warnungen.sturm},
'Wind': {'flag': False, 'item': sh.wetter.warnungen.wind}
}
warnungen = []
for warning in warnings:
if warning['kind'] in types:
types[warning['kind']]['flag'] = True
warnungen.append('<li><p style="font-weight:bold;">{2}</p><p>{3}</p><p class="ui-li-aside">{0:%a %H:%M}<br />{1:%a %H:%M}</p></li>'.format(warning['start'], warning['end'], warning['kind'], warning['desc']))
sh.wetter.warnungen(warnungen)
for typ in types:
types[typ]['item'](types[typ]['flag'])