DWD global weather (warning) integration

This is a feature request to include the ability to pull or get pushed information from the DWD (Deutscher Wetterdienst), the national German weather service.

This service not only releases detailed forecasts for the weather, it also issues warnings for serious weather conditions, there are several categories, like snowstorms, hailstorm, heavy rain, thunderstorms, which then get a detailed start and end for each region as well as a severely-level.

This could be quite useful for automation in Germany.

Btw:
Sadly this service is limited to Germany only and I don’t know a service which offers those detailed warnings on a global bases just picking up the data from each national weather service - this would be gorgeous.

So if somebody got some sparetime for setting up such service, this would be gorgeous. :slight_smile:

Just to give you some impression which data is available by this service:

And this are some of the “warning” categories, you see the filter-view for the pushes here.

Would be nice! +1

The documentation of the API is extensive and they offer everything from raw data to nice graphics for usage by third partys.

Really lovely!

http://www.dwd.de/DE/wetter/warnungen_aktuell/objekt_einbindung/objekteinbindung.html

1 Like

FAdditionally the DWD also provides global data via FTP-Access (after registration) wherever they get data from other weather stations around the world.

https://www.dwd.de/EN/ourservices/gds/gds.html

I guess this would be a good datasource for a global weather plugin for access beside the existing freemium DarkSky plugin.

I bet they would enjoy a larger userbase for their services.

We just need to make sure, that we check the timestamps from a directory listing and only pull new files if they really changed (according to the timestamps), to not excessively causing unneeded traffic.

The datasource is FTP, but I guess it’s fine, Python got a nice FTP client which allows easy access to the files on a FTP side.

I think we should head in this direction, because it would allow one plugin to cover more than just Germany.

Edit: Replaced link with the link to the English version.

This is my implementation:

Did anyone do any automation to send push notifications when a weather warning is coming?
if yes, can we share it, please?

Thanks in advance
/ Ralf

I’m creating a html mail and send it via smtp.

sensor:
  - platform: dwd_weather_warnings
    region_name: Kreis und Stadt Würzburg

  - platform: template
    sensors:
      dwd_warn_count:
        value_template: '{{ states.sensor.dwdweatherwarnings_current_warning_level.attributes.warning_count }}'


automation:
  - alias: send_dwd_warning
    initial_state: True
    trigger:
      - platform: state
        entity_id: sensor.dwd_warn_count
      - platform: state
        entity_id: sensor.dwdweatherwarnings_current_warning_level
    condition:
      condition: template
      value_template: '{{ (trigger.to_state.state != trigger.from_state.state) and trigger.to_state.state | int > 0 }}'
    action:
      - condition: state
        entity_id: script.send_dwd_warn_mail
        state: 'off'
      - service: homeassistant.turn_on
        entity_id: script.send_dwd_warn_mail


script:
  send_dwd_warn_mail:
    sequence:
      - delay:
          seconds: 10
      - service: notify.ios_iphone
        data: 
          title: "DWD Wetterwarnung!"
          message: "Aktuelle Warnung kommt per Mail."
      - service: shell_command.get_warn_image
      - delay:
          minutes: 1
      - service: notify.gmail_smtp
        data_template:
          title: 'DWD Wetterwarnung!'
          message: ' '
          data:
            images:
              - warnungen_gemeinde_map_bay.png
            html: >
              <!DOCTYPE html><html><head><style>a, h3, h4 {font-family: arial;}</style></head><body>
              <h3>{{ states.sensor.dwdweatherwarnings_current_warning_level.attributes.region_name }}</h3>
              {% if states.sensor.dwdweatherwarnings_current_warning_level.attributes.warning_1_headline is defined %}
                <h3>{{ states.sensor.dwdweatherwarnings_current_warning_level.attributes.warning_1_headline }}</h3>
                Warnstufe: {{ states.sensor.dwdweatherwarnings_current_warning_level.attributes.warning_1_level }}
                <br>
                Von: {{ as_timestamp(states.sensor.dwdweatherwarnings_current_warning_level.attributes.warning_1_start) | timestamp_custom("%a %d.%m.%Y %H:%M",true) }}
                <br>
                Bis: {{ as_timestamp(states.sensor.dwdweatherwarnings_current_warning_level.attributes.warning_1_end) | timestamp_custom("%a %d.%m.%Y %H:%M",true) }}
                <br>
                {{ states.sensor.dwdweatherwarnings_current_warning_level.attributes.warning_1_description }}
                <br>
                <br>
              {% endif %}
              {% if states.sensor.dwdweatherwarnings_current_warning_level.attributes.warning_2_headline is defined %}
                <h3>{{ states.sensor.dwdweatherwarnings_current_warning_level.attributes.warning_2_headline }}</h3>
                Warnstufe: {{ states.sensor.dwdweatherwarnings_current_warning_level.attributes.warning_2_level }}
                <br>
                Von: {{ as_timestamp(states.sensor.dwdweatherwarnings_current_warning_level.attributes.warning_2_start) | timestamp_custom("%a %d.%m.%Y %H:%M",true) }}
                <br>
                Bis: {{ as_timestamp(states.sensor.dwdweatherwarnings_current_warning_level.attributes.warning_2_end) | timestamp_custom("%a %d.%m.%Y %H:%M",true) }}
                <br>
                {{ states.sensor.dwdweatherwarnings_current_warning_level.attributes.warning_2_description }}
                <br>
                <br>
              {% endif %}
              {% if states.sensor.dwdweatherwarnings_current_warning_level.attributes.warning_3_headline is defined %}
                <h3>{{ states.sensor.dwdweatherwarnings_current_warning_level.attributes.warning_3_headline }}</h3>
                Warnstufe: {{ states.sensor.dwdweatherwarnings_current_warning_level.attributes.warning_3_level }}
                <br>
                Von: {{ as_timestamp(states.sensor.dwdweatherwarnings_current_warning_level.attributes.warning_3_start) | timestamp_custom("%a %d.%m.%Y %H:%M",true) }}
                <br>
                Bis: {{ as_timestamp(states.sensor.dwdweatherwarnings_current_warning_level.attributes.warning_3_end) | timestamp_custom("%a %d.%m.%Y %H:%M",true) }}
                <br>
                {{ states.sensor.dwdweatherwarnings_current_warning_level.attributes.warning_3_description }}
                <br>
                <br>
              {% endif %}
              {% if states.sensor.dwdweatherwarnings_current_warning_level.attributes.warning_4_headline is defined %}
                <h3>{{ states.sensor.dwdweatherwarnings_current_warning_level.attributes.warning_4_headline }}</h3>
                Warnstufe: {{ states.sensor.dwdweatherwarnings_current_warning_level.attributes.warning_4_level }}
                <br>
                Von: {{ as_timestamp(states.sensor.dwdweatherwarnings_current_warning_level.attributes.warning_4_start) | timestamp_custom("%a %d.%m.%Y %H:%M",true) }}
                <br>
                Bis: {{ as_timestamp(states.sensor.dwdweatherwarnings_current_warning_level.attributes.warning_4_end) | timestamp_custom("%a %d.%m.%Y %H:%M",true) }}
                <br>
                {{ states.sensor.dwdweatherwarnings_current_warning_level.attributes.warning_4_description }}
                <br>
                <br>
              {% endif %}
              <a href="http://www.dwd.de/DWD/warnungen/warnapp_gemeinden/json/warnungen_gemeinde_map_bay.png">Aktuelle Warnkarte</a>
              <br>
              <img class="rounded" alt="Warnkarte" src="cid:warnungen_gemeinde_map_bay.png" /></body></html>


shell_command:
  get_warn_image: 'wget http://www.dwd.de/DWD/warnungen/warnapp_gemeinden/json/warnungen_gemeinde_map_bay.png -q -O warnungen_gemeinde_map_bay.png'

This generates a mail like this.

1 Like

A few days ago it seems DWD has changed to HTTPS and redirects every request vom http:// to https:// which makes the integration fail:

Error fetching data: <PreparedRequest [GET]> from https://www.dwd.de/DWD/warnungen/warnapp_landkreise/json/warnings.json?jsonp=loadWarnings failed with HTTPSConnectionPool(host=‘www.dwd.de’, port=443): Max retries exceeded with url: /DWD/warnungen/warnapp_landkreise/json/warnings.json?jsonp=loadWarnings (Caused by SSLError(SSLError(1, ‘[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:720)’),))

Good to know theat i’m not the only one.

There was a problem with the certificate which DWD fixed lately.

thx for sharing, nice work.

Can someone please adapt it for telegram, instead of sending email?

or does someone already use it with telegram, and can share the code?

my beginner copied code from different sources works (DWD WarnWetter markdown card):

send_dwd_warn_mail:
  sequence:
    - delay:
        seconds: 10
    - service: notify.ha_telegram
      data:
        title: 'DWD Wetterwarnung:'
        message: >-
          {% set current_count =
          state_attr("sensor.warnwetter_current_warning_level", "warning_count")
          %} {% set advance_count =
          state_attr("sensor.warnwetter_advance_warning_level", "warning_count")
          %} {% if ((current_count == 0) and (advance_count == 0)) %} Keine
          Warnungen {% else %}
            {% for i in range(current_count) %}
              {% set headline = state_attr("sensor.warnwetter_current_warning_level", "warning_" ~ loop.index ~ "_headline") %}
              {% set description = state_attr("sensor.warnwetter_current_warning_level", "warning_" ~ loop.index ~ "_description") %}
              {% set level = state_attr("sensor.warnwetter_current_warning_level", "warning_" ~ loop.index ~ "_level") %}
              {% set time_start = state_attr("sensor.warnwetter_current_warning_level", "warning_" ~ loop.index ~ "_start") %}
              {% set time_end = state_attr("sensor.warnwetter_current_warning_level", "warning_" ~ loop.index ~ "_end") %}
            {{ headline }}
            {{ time_start.strftime("%a %H:%M") ~ " - " ~ time_end.strftime("%a %H:%M") }}
            *{{ description }}*
            {% if not loop.last %}***{% endif %}
            {% endfor %}
            {% if ((current_count != 0) and (advance_count != 0)) %}***{% endif %}
            {% for i in range(advance_count) %}
              {% set headline = state_attr("sensor.warnwetter_advance_warning_level", "warning_" ~ loop.index ~ "_headline") %}
              {% set description = state_attr("sensor.warnwetter_advance_warning_level", "warning_" ~ loop.index ~ "_description") %}
              {% set level = state_attr("sensor.warnwetter_advance_warning_level", "warning_" ~ loop.index ~ "_level") %}
              {% set time_start = state_attr("sensor.warnwetter_advance_warning_level", "warning_" ~ loop.index ~ "_start") %}
              {% set time_end = state_attr("sensor.warnwetter_advance_warning_level", "warning_" ~ loop.index ~ "_end") %}
            {{ headline }}
            {{ time_start.strftime("%a %H:%M") ~ " - " ~ time_end.strftime("%a %H:%M") }}
            *{{ description }}*
            {% if not loop.last %}***{% endif %}
            {% endfor %}
          {% endif %}     
        
1 Like

does anyone find a solution and can share this here?

I use an http api i created from my own website. It uses DWD mosmix Data.
Here is the config for it:

sensor:
  - platform: rest
    name: mwe
    scan_interval: 300
    json_attributes:
      - temp
      - temp5cm
      - dewpoint
      - windchill
      - humidity
      - totalprecipitation
      - probfog
      - irradiance
      - visibility
      - windspeed
      - winddir
    resource: https://morgenwirdes.de/api/v3/outdoor.php?plz=84051
    value_template: "{{ value_json.temp }}"
  - platform: template
    sensors:
      mwe_temp:
        friendly_name: "Temperatur 2m"
        value_template: "{{ state_attr('sensor.mwe', 'temp') }}"
        unit_of_measurement: "°C"
      mwe_temp5cm:
        friendly_name: "Temperatur 5cm"
        value_template: "{{ state_attr('sensor.mwe', 'temp5cm') }}"
        unit_of_measurement: "°C"
      mwe_dewpoint:
        friendly_name: "Taupunkt"
        value_template: "{{ state_attr('sensor.mwe', 'dewpoint') }}"
        unit_of_measurement: "°C"
      mwe_windchill:
        friendly_name: "Gefühlte Temperatur"
        value_template: "{{ state_attr('sensor.mwe', 'windchill') }}"
        unit_of_measurement: "°C"
      mwe_humidity:
        friendly_name: "Luftfeuchte"
        value_template: "{{ state_attr('sensor.mwe', 'humidity') }}"
        unit_of_measurement: "%"
      mwe_totalprecipitation:
        friendly_name: "Niederschlag"
        value_template: "{{ state_attr('sensor.mwe', 'totalprecipitation') }}"
        unit_of_measurement: "l/m2"
      mwe_probfog:
        friendly_name: "Nebelwahrscheinlichkeit"
        value_template: "{{ state_attr('sensor.mwe', 'probfog') }}"
        unit_of_measurement: "%"
      mwe_irradiance:
        friendly_name: "Globalstrahlung"
        value_template: "{{ state_attr('sensor.mwe', 'irradiance') }}"
        unit_of_measurement: "W/m2"
      mwe_visibility:
        friendly_name: "Sicht"
        value_template: "{{ state_attr('sensor.mwe', 'visibility') }}"
        unit_of_measurement: "m"
      mwe_windspeed:
        friendly_name: "Windgeschwindigkeit"
        value_template: "{{ state_attr('sensor.mwe', 'windspeed') }}"
        unit_of_measurement: "km/h"
      mwe_winddir:
        friendly_name: "Windrichtung"
        value_template: "{{ state_attr('sensor.mwe', 'winddir') }}"
        unit_of_measurement: "°"

I also have pre rendered gifs for the rain radar service

https://morgenwirdes.de/api/v3/gif4.php?plz=84051&delay=70&type=1&zoomlvl=3&bar=1&map=0&textcol=ffffff&bgcol=8393c9

and a lot more apis. If you are interested just write me a pm or reply here