diff --git a/CODEOWNERS b/CODEOWNERS
index 3513dc5a8c6a3..f5386c50cd680 100644
--- a/CODEOWNERS
+++ b/CODEOWNERS
@@ -41,6 +41,7 @@
/bundles/org.openhab.binding.doorbird/ @mhilbush
/bundles/org.openhab.binding.dscalarm/ @RSStephens
/bundles/org.openhab.binding.dsmr/ @Hilbrand
+/bundles/org.openhab.binding.dwdpollenflug/ @DerOetzi
/bundles/org.openhab.binding.dwdunwetter/ @limdul79
/bundles/org.openhab.binding.elerotransmitterstick/ @vbier
/bundles/org.openhab.binding.enocean/ @fruggy83
diff --git a/bom/openhab-addons/pom.xml b/bom/openhab-addons/pom.xml
index bdf9078065638..2b07da53437d5 100644
--- a/bom/openhab-addons/pom.xml
+++ b/bom/openhab-addons/pom.xml
@@ -194,6 +194,11 @@
org.openhab.binding.dsmr
${project.version}
+
+ org.openhab.addons.bundles
+ org.openhab.binding.dwdpollenflug
+ ${project.version}
+
org.openhab.addons.bundles
org.openhab.binding.dwdunwetter
diff --git a/bundles/org.openhab.binding.dwdpollenflug/.classpath b/bundles/org.openhab.binding.dwdpollenflug/.classpath
new file mode 100644
index 0000000000000..14ba193a4882c
--- /dev/null
+++ b/bundles/org.openhab.binding.dwdpollenflug/.classpath
@@ -0,0 +1,49 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/bundles/org.openhab.binding.dwdpollenflug/.project b/bundles/org.openhab.binding.dwdpollenflug/.project
new file mode 100644
index 0000000000000..3cf695e17193f
--- /dev/null
+++ b/bundles/org.openhab.binding.dwdpollenflug/.project
@@ -0,0 +1,23 @@
+
+
+ org.openhab.binding.dwdpollenflug
+
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ org.eclipse.m2e.core.maven2Builder
+
+
+
+
+
+ org.eclipse.jdt.core.javanature
+ org.eclipse.m2e.core.maven2Nature
+
+
diff --git a/bundles/org.openhab.binding.dwdpollenflug/NOTICE b/bundles/org.openhab.binding.dwdpollenflug/NOTICE
new file mode 100644
index 0000000000000..38d625e349232
--- /dev/null
+++ b/bundles/org.openhab.binding.dwdpollenflug/NOTICE
@@ -0,0 +1,13 @@
+This content is produced and maintained by the openHAB project.
+
+* Project home: https://www.openhab.org
+
+== Declared Project Licenses
+
+This program and the accompanying materials are made available under the terms
+of the Eclipse Public License 2.0 which is available at
+https://www.eclipse.org/legal/epl-2.0/.
+
+== Source Code
+
+https://github.com/openhab/openhab-addons
diff --git a/bundles/org.openhab.binding.dwdpollenflug/README.md b/bundles/org.openhab.binding.dwdpollenflug/README.md
new file mode 100644
index 0000000000000..af20a6a7c2580
--- /dev/null
+++ b/bundles/org.openhab.binding.dwdpollenflug/README.md
@@ -0,0 +1,198 @@
+# DWDPollenflug Binding
+
+The "Deutsche Wetterdienst" (DWD) reports the current pollen count index for Germany on a daily base and a forecast for tomorrow and the day after tomorrow.
+This binding allows you to retrieve this data for your region or partregion. You can find a map of the data here:
+
+https://isabel.dwd.de/DE/leistungen/gefahrenindizespollen/gefahrenindexpollen.html
+
+
+## Supported Things
+
+This binding supports a bridge thing (`bridge`), which polls the dataset for Germany in an adjustable interval.
+And it supports a region thing (`region`), representing the data for all pollen types of a region or partregion.
+
+## Thing Configuration
+
+### Bridge
+
+| Property | Default | Required | Description |
+| --------- | :-----: | :------: | ------------------------------------------------------------------------------------ |
+| `refresh` | 30 | no | Define the interval for polling the data from DWD in minutes. Minimum is 15 minutes. |
+
+### Region
+
+| Property | Default | Required | Description |
+| ---------- | :-----: | :------: | -------------------------------------------------------------------------------------------------------- |
+| `regionID` | - | yes | In PaperUI just select the region you want to display data for. For files-configuration see table below. |
+
+#### Manual region or partregion selection ####
+
+The region ID is the partregion_id or if there is no partregion the region_id from this [json](https://opendata.dwd.de/climate_environment/health/alerts/s31fg.json) of DWD.
+You can refer to the following table.
+
+| regionID | Region | Partregion |
+| -------- | ------------------------------ | -------------------------------------------------- |
+| 11 | Schleswig-Holstein und Hamburg | Inseln und Marschen |
+| 12 | Schleswig-Holstein und Hamburg | Geest, Schleswig-Holstein und Hamburg |
+| 20 | Mecklenburg-Vorpommern | - |
+| 31 | Niedersachsen und Bremen | Westl. Niedersachsen/Bremen |
+| 32 | Niedersachsen und Bremen | Östl. Niedersachsen |
+| 41 | Nordrhein-Westfalen | Rhein.-Westfäl. Tiefland |
+| 42 | Nordrhein-Westfalen | Ostwestfalen |
+| 43 | Nordrhein-Westfalen | Mittelgebirge NRW |
+| 50 | Brandenburg und Berlin | - |
+| 61 | Sachsen-Anhalt | Tiefland Sachsen-Anhalt |
+| 62 | Sachsen-Anhalt | Harz |
+| 71 | Thüringen | Tiefland Thüringen |
+| 72 | Thüringen | Mittelgebirge Thüringen |
+| 81 | Sachsen | Tiefland Sachsen |
+| 82 | Sachsen | Mittelgebirge Sachsen |
+| 91 | Hessen | Nordhessen und hess. Mittelgebirge |
+| 92 | Hessen | Rhein-Main |
+| 101 | Rheinland-Pfalz und Saarland | Rhein, Pfalz, Nahe und Mosel |
+| 102 | Rheinland-Pfalz und Saarland | Mittelgebirgsbereich Rheinland-Pfalz |
+| 103 | Rheinland-Pfalz und Saarland | Saarland |
+| 111 | Baden-Württemberg | Oberrhein und unteres Neckartal |
+| 112 | Baden-Württemberg | Hohenlohe/mittlerer Neckar/Oberschwaben |
+| 113 | Baden-Württemberg | Mittelgebirge Baden-Württemberg |
+| 121 | Bayern | Allgäu/Oberbayern/Bay. Wald |
+| 122 | Bayern | Donauniederungen |
+| 123 | Bayern | Bayern n. der Donau, o. Bayr. Wald, o. Mainfranken |
+| 124 | Bayern | Mainfranken |
+
+## Channels
+
+The bridge thing has following channels:
+
+| channel | description |
+| --------------------- | ---------------------------------------------- |
+| `updates#refreshed` | Hold the time of the bridge's last refresh |
+| `updates#last_update` | The time when data was last updated by DWD |
+| `updates#next_update` | The time when data will be updated next by DWD |
+
+For each of the eight pollen types reported by DWD the region thing has three channels for today, tomorrow and the day after tomorrow.
+
+| channels | pollen type | german name |
+| ---------------------- | ----------- | ----------- |
+| `alder#today` | alder | Erle |
+| `alder#tomorrow` | | |
+| `alder#dayafter_to` | | |
+| `ambrosia#today` | ambrosia | Ambrosia |
+| `ambrosia#tomorrow` | | |
+| `ambrosia#dayafter_to` | | |
+| `ash#today` | ash-tree | Esche |
+| `ash#tomorrow` | | |
+| `ash#dayafter_to` | | |
+| `birch#today` | birch | Birke |
+| `birch#tomorrow` | | |
+| `birch#dayafter_to` | | |
+| `grasses#today` | grasses | Gräser |
+| `grasses#tomorrow` | | |
+| `grasses#dayafter_to` | | |
+| `hazel#today` | hazel | Hasel |
+| `hazel#tomorrow` | | |
+| `hazel#dayafter_to` | | |
+| `mugwort#today` | mugwort | Beifuß |
+| `mugwort#tomorrow` | | |
+| `mugwort#dayafter_to` | | |
+| `rye#today` | rye | Roggen |
+| `rye#tomorrow` | | |
+| `rye#dayafter_to` | | |
+
+There are the following possible string values:
+
+| value | description |
+| ----- | --------------------------- |
+| -1 | not specified |
+| 0 | no pollen pollution |
+| 0-1 | no to low pollen count |
+| 1 | low pollen count |
+| 1-2 | low to medium pollen count |
+| 2 | medium pollen count |
+| 2-3 | medium to high pollen count |
+| 3 | high pollen count |
+
+## Full Example
+
+### Things file for region "Brandenburg und Berlin" and partregion "Bayern - Mainfranken" ###
+
+```
+Bridge dwdpollenflug:bridge:dwd "DWD pollen count Bridge" [refresh="15"] {
+ Thing region region50 "DWD pollen count region" @ "APIS" [regionID="50"]
+ Thing region partregion124 "DWD pollen count partregion" @ "APIS" [regionID="124"]
+}
+```
+
+### Items example for region "Brandenburg und Berlin" and pollen type ash-tree ###
+
+```
+String pollenTodayEsche
+ "Esche [MAP(pollen.map):%s]"
+ {channel="dwdpollenflug:region:dwd:region50:ash#today"}
+
+String pollenTomorrowEsche
+ "Esche morgen [MAP(pollen.map):%s]"
+ {channel="dwdpollenflug:region:dwd:region50:ash#tomorrow"}
+
+String pollenDayAfterTomorrowEsche
+ "Esche übermorgen [MAP(pollen.map):%s]"
+ {channel="dwdpollenflug:region:dwd:region50:ash#dayafter_to"}
+
+```
+
+### Transform map file pollen.map ###
+
+```
+0=keine (0)
+0-1=keine bis gering (0-1)
+1=gering (1)
+1-2=gering bis mittel (1-2)
+2=mittel (2)
+2-3=mittel bis hoch (2-3)
+3=hoch (3)
+-1=keine Daten
+-=keine Daten
+NULL=keine Daten
+```
+
+### Sitemap example for region "Brandenburg und Berlin" and pollen type ash-tree ###
+
+```
+Text label="Pollenflugindex" {
+ Frame {
+ Text item=pollenTodayEsche
+ valuecolor=[=="3"="#f00014",
+ =="2-3"="#f00014",
+ =="2"="#ff9900",
+ =="1-2"="#ff9900",
+ =="1"="#ffff00",
+ =="0-1"="#00c83c"] {
+ Frame {
+ Text item=pollenTodayEsche
+ valuecolor=[=="3"="#f00014",
+ =="2-3"="#f00014",
+ =="2"="#ff9900",
+ =="1-2"="#ff9900",
+ =="1"="#ffff00",
+ =="0-1"="#00c83c"]
+
+ Text item=pollenTomorrowEsche
+ valuecolor=[=="3"="#f00014",
+ =="2-3"="#f00014",
+ =="2"="#ff9900",
+ =="1-2"="#ff9900",
+ =="1"="#ffff00",
+ =="0-1"="#00c83c"]
+
+ Text item=pollenDayAfterTomorrowEsche
+ valuecolor=[=="3"="#f00014",
+ =="2-3"="#f00014",
+ =="2"="#ff9900",
+ =="1-2"="#ff9900",
+ =="1"="#ffff00",
+ =="0-1"="#00c83c"]
+ }
+ }
+ }
+}
+```
diff --git a/bundles/org.openhab.binding.dwdpollenflug/pom.xml b/bundles/org.openhab.binding.dwdpollenflug/pom.xml
new file mode 100644
index 0000000000000..d98e4238b45ad
--- /dev/null
+++ b/bundles/org.openhab.binding.dwdpollenflug/pom.xml
@@ -0,0 +1,16 @@
+
+
+
+ 4.0.0
+
+
+ org.openhab.addons.bundles
+ org.openhab.addons.reactor.bundles
+ 2.5.4-SNAPSHOT
+
+
+ org.openhab.binding.dwdpollenflug
+
+ openHAB Add-ons :: Bundles :: DWDPollenflug Binding
+
+
diff --git a/bundles/org.openhab.binding.dwdpollenflug/src/main/feature/feature.xml b/bundles/org.openhab.binding.dwdpollenflug/src/main/feature/feature.xml
new file mode 100644
index 0000000000000..e4e5901453f68
--- /dev/null
+++ b/bundles/org.openhab.binding.dwdpollenflug/src/main/feature/feature.xml
@@ -0,0 +1,9 @@
+
+
+ mvn:org.openhab.core.features.karaf/org.openhab.core.features.karaf.openhab-core/${ohc.version}/xml/features
+
+
+ openhab-runtime-base
+ mvn:org.openhab.addons.bundles/org.openhab.binding.dwdpollenflug/${project.version}
+
+
diff --git a/bundles/org.openhab.binding.dwdpollenflug/src/main/java/org/openhab/binding/dwdpollenflug/internal/DWDPollenflugBindingConstants.java b/bundles/org.openhab.binding.dwdpollenflug/src/main/java/org/openhab/binding/dwdpollenflug/internal/DWDPollenflugBindingConstants.java
new file mode 100644
index 0000000000000..83498093978af
--- /dev/null
+++ b/bundles/org.openhab.binding.dwdpollenflug/src/main/java/org/openhab/binding/dwdpollenflug/internal/DWDPollenflugBindingConstants.java
@@ -0,0 +1,62 @@
+/**
+ * Copyright (c) 2010-2020 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.dwdpollenflug.internal;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.smarthome.core.thing.ThingTypeUID;
+
+/**
+ * The {@link DWDPollenflugBindingConstants} class defines common constants, which are
+ * used across the whole binding.
+ *
+ * @author Johannes Ott - Initial contribution
+ */
+@NonNullByDefault
+public class DWDPollenflugBindingConstants {
+
+ private static final String BINDING_ID = "dwdpollenflug";
+
+ // bridge
+ public static final ThingTypeUID THING_TYPE_BRIDGE = new ThingTypeUID(BINDING_ID, "bridge");
+
+ // List of all Thing Type UIDs
+ public static final ThingTypeUID THING_TYPE_REGION = new ThingTypeUID(BINDING_ID, "region");
+
+ // Channels of pollen groups
+ public static final String CHANNEL_TODAY = "today";
+ public static final String CHANNEL_TOMORROW = "tomorrow";
+ public static final String CHANNEL_DAYAFTER_TO = "dayafter_to";
+
+ // Channels of region update
+ public static final String CHANNEL_UPDATES = "updates";
+ public static final String CHANNEL_REFRESHED = "refreshed";
+ public static final String CHANNEL_NEXT_UPDATE = "next_update";
+ public static final String CHANNEL_LAST_UPDATE = "last_update";
+ public static final String CHANNEL_UPDATED = "updated";
+
+ public static final String TRIGGER_REFRESHED = "REFRESHED";
+
+ // Bridge config properties
+ public static final String REFRESH = "refresh";
+
+ // Bridge properties
+ public static final String PROPERTY_SENDER = "sender";
+ public static final String PROPERTY_NAME = "name";
+
+ // Region config properties
+ public static final String REGION_ID = "regionID";
+
+ // Region properties
+ public static final String PROPERTY_REGION_NAME = "region_name";
+ public static final String PROPERTY_PARTREGION_NAME = "partregion_name";
+}
diff --git a/bundles/org.openhab.binding.dwdpollenflug/src/main/java/org/openhab/binding/dwdpollenflug/internal/DWDPollenflugHandlerFactory.java b/bundles/org.openhab.binding.dwdpollenflug/src/main/java/org/openhab/binding/dwdpollenflug/internal/DWDPollenflugHandlerFactory.java
new file mode 100644
index 0000000000000..4e236775e30de
--- /dev/null
+++ b/bundles/org.openhab.binding.dwdpollenflug/src/main/java/org/openhab/binding/dwdpollenflug/internal/DWDPollenflugHandlerFactory.java
@@ -0,0 +1,75 @@
+/**
+ * Copyright (c) 2010-2020 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.dwdpollenflug.internal;
+
+import static org.openhab.binding.dwdpollenflug.internal.DWDPollenflugBindingConstants.*;
+
+import java.util.Collections;
+import java.util.Set;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.jetty.client.HttpClient;
+import org.eclipse.smarthome.core.thing.Bridge;
+import org.eclipse.smarthome.core.thing.Thing;
+import org.eclipse.smarthome.core.thing.ThingTypeUID;
+import org.eclipse.smarthome.core.thing.binding.BaseThingHandlerFactory;
+import org.eclipse.smarthome.core.thing.binding.ThingHandler;
+import org.eclipse.smarthome.core.thing.binding.ThingHandlerFactory;
+import org.eclipse.smarthome.io.net.http.HttpClientFactory;
+import org.openhab.binding.dwdpollenflug.internal.handler.DWDPollenflugBridgeHandler;
+import org.openhab.binding.dwdpollenflug.internal.handler.DWDPollenflugRegionHandler;
+import org.osgi.service.component.annotations.Activate;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Reference;
+
+/**
+ * The {@link DWDPollenflugHandlerFactory} is responsible for creating things and thing
+ * handlers.
+ *
+ * @author Johannes Ott - Initial contribution
+ */
+@NonNullByDefault
+@Component(configurationPid = "binding.dwdpollenflug", service = ThingHandlerFactory.class)
+public class DWDPollenflugHandlerFactory extends BaseThingHandlerFactory {
+
+ private static final Set SUPPORTED_THING_TYPES_UIDS = Collections
+ .unmodifiableSet(Stream.of(THING_TYPE_BRIDGE, THING_TYPE_REGION).collect(Collectors.toSet()));
+
+ private final HttpClient httpClient;
+
+ @Activate
+ public DWDPollenflugHandlerFactory(final @Reference HttpClientFactory httpClientFactory) {
+ this.httpClient = httpClientFactory.getCommonHttpClient();
+ }
+
+ @Override
+ public boolean supportsThingType(ThingTypeUID thingTypeUID) {
+ return SUPPORTED_THING_TYPES_UIDS.contains(thingTypeUID);
+ }
+
+ @Override
+ protected @Nullable ThingHandler createHandler(Thing thing) {
+ ThingTypeUID thingTypeUID = thing.getThingTypeUID();
+
+ if (THING_TYPE_BRIDGE.equals(thingTypeUID)) {
+ return new DWDPollenflugBridgeHandler((Bridge) thing, httpClient);
+ } else if (THING_TYPE_REGION.equals(thingTypeUID)) {
+ return new DWDPollenflugRegionHandler(thing);
+ }
+
+ return null;
+ }
+}
diff --git a/bundles/org.openhab.binding.dwdpollenflug/src/main/java/org/openhab/binding/dwdpollenflug/internal/DWDPollingException.java b/bundles/org.openhab.binding.dwdpollenflug/src/main/java/org/openhab/binding/dwdpollenflug/internal/DWDPollingException.java
new file mode 100644
index 0000000000000..26d3de7073652
--- /dev/null
+++ b/bundles/org.openhab.binding.dwdpollenflug/src/main/java/org/openhab/binding/dwdpollenflug/internal/DWDPollingException.java
@@ -0,0 +1,34 @@
+/**
+ * Copyright (c) 2010-2020 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.dwdpollenflug.internal;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+
+/**
+ * The {@link DWDPollingException} class is the exception for all polling errors.
+ *
+ * @author Johannes Ott - Initial contribution
+ */
+@NonNullByDefault
+public class DWDPollingException extends Exception {
+
+ private static final long serialVersionUID = 1L;
+
+ public DWDPollingException(String message) {
+ super(message);
+ }
+
+ public DWDPollingException(String message, Throwable throwable) {
+ super(message, throwable);
+ }
+}
diff --git a/bundles/org.openhab.binding.dwdpollenflug/src/main/java/org/openhab/binding/dwdpollenflug/internal/config/DWDPollenflugBridgeConfiguration.java b/bundles/org.openhab.binding.dwdpollenflug/src/main/java/org/openhab/binding/dwdpollenflug/internal/config/DWDPollenflugBridgeConfiguration.java
new file mode 100644
index 0000000000000..ea73d371cc69f
--- /dev/null
+++ b/bundles/org.openhab.binding.dwdpollenflug/src/main/java/org/openhab/binding/dwdpollenflug/internal/config/DWDPollenflugBridgeConfiguration.java
@@ -0,0 +1,29 @@
+/**
+ * Copyright (c) 2010-2020 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.dwdpollenflug.internal.config;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+
+/**
+ * Configuration for the {@link DWDPollenflugBridgeHandler}
+ *
+ * @author Johannes Ott - Initial contribution
+ */
+@NonNullByDefault
+public class DWDPollenflugBridgeConfiguration {
+ public int refresh = 30;
+
+ public boolean isValid() {
+ return refresh >= 15;
+ }
+}
diff --git a/bundles/org.openhab.binding.dwdpollenflug/src/main/java/org/openhab/binding/dwdpollenflug/internal/config/DWDPollenflugRegionConfiguration.java b/bundles/org.openhab.binding.dwdpollenflug/src/main/java/org/openhab/binding/dwdpollenflug/internal/config/DWDPollenflugRegionConfiguration.java
new file mode 100644
index 0000000000000..87fe8de2661ee
--- /dev/null
+++ b/bundles/org.openhab.binding.dwdpollenflug/src/main/java/org/openhab/binding/dwdpollenflug/internal/config/DWDPollenflugRegionConfiguration.java
@@ -0,0 +1,29 @@
+/**
+ * Copyright (c) 2010-2020 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.dwdpollenflug.internal.config;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+
+/**
+ * Configuration for the {@link DWDPollenflugRegionHandler}
+ *
+ * @author Johannes Ott - Initial contribution
+ */
+@NonNullByDefault
+public class DWDPollenflugRegionConfiguration {
+ public int regionID;
+
+ public boolean isValid() {
+ return regionID > 0;
+ }
+}
diff --git a/bundles/org.openhab.binding.dwdpollenflug/src/main/java/org/openhab/binding/dwdpollenflug/internal/dto/DWDPollenflug.java b/bundles/org.openhab.binding.dwdpollenflug/src/main/java/org/openhab/binding/dwdpollenflug/internal/dto/DWDPollenflug.java
new file mode 100644
index 0000000000000..b3edfa797bc7e
--- /dev/null
+++ b/bundles/org.openhab.binding.dwdpollenflug/src/main/java/org/openhab/binding/dwdpollenflug/internal/dto/DWDPollenflug.java
@@ -0,0 +1,111 @@
+/**
+ * Copyright (c) 2010-2020 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.dwdpollenflug.internal.dto;
+
+import static org.openhab.binding.dwdpollenflug.internal.DWDPollenflugBindingConstants.*;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.time.ZoneId;
+import java.time.ZonedDateTime;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+import com.google.gson.annotations.SerializedName;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.smarthome.core.library.types.DateTimeType;
+import org.eclipse.smarthome.core.types.State;
+import org.eclipse.smarthome.core.types.UnDefType;
+
+/**
+ * The {@link DWDPollenflug} class is internal DWD data structure.
+ *
+ * @author Johannes Ott - Initial contribution
+ */
+@NonNullByDefault
+public class DWDPollenflug {
+ private String sender = "";
+
+ private String name = "";
+
+ private final Date created = new Date();
+
+ @SerializedName("next_update")
+ private @Nullable String nextUpdate;
+
+ @SerializedName("last_update")
+ private @Nullable String lastUpdate;
+
+ @SerializedName("content")
+ private @Nullable Set regions;
+
+ public Map getProperties() {
+ Map map = new HashMap<>();
+
+ map.put(PROPERTY_NAME, name);
+ map.put(PROPERTY_SENDER, sender);
+
+ return Collections.unmodifiableMap(map);
+ }
+
+ public Map getChannelsStateMap() {
+ Map map = new HashMap<>();
+
+ map.put(CHANNEL_UPDATES + "#" + CHANNEL_REFRESHED, parseDate(created));
+ map.put(CHANNEL_UPDATES + "#" + CHANNEL_LAST_UPDATE, parseDate(lastUpdate));
+ map.put(CHANNEL_UPDATES + "#" + CHANNEL_NEXT_UPDATE, parseDate(nextUpdate));
+
+ return Collections.unmodifiableMap(map);
+ }
+
+ private State parseDate(final @Nullable String dateString) {
+ try {
+ if (dateString != null) {
+ SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm");
+ Date date = formatter.parse(dateString.replace("Uhr", "").trim());
+ return parseDate(date);
+ }
+
+ return UnDefType.NULL;
+ } catch (ParseException e) {
+ return UnDefType.NULL;
+ }
+ }
+
+ private State parseDate(final @Nullable Date date) {
+ if (date == null) {
+ return UnDefType.NULL;
+ } else {
+ ZonedDateTime zoned = ZonedDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());
+ return new DateTimeType(zoned);
+ }
+ }
+
+ public @Nullable DWDRegion getRegion(int key) {
+ final Set localRegions = regions;
+ if (localRegions != null) {
+ for (DWDRegion region : localRegions) {
+ if (region.getRegionID() == key) {
+ return region;
+ }
+ }
+ }
+
+ return null;
+ }
+}
diff --git a/bundles/org.openhab.binding.dwdpollenflug/src/main/java/org/openhab/binding/dwdpollenflug/internal/dto/DWDPollenflugPollen.java b/bundles/org.openhab.binding.dwdpollenflug/src/main/java/org/openhab/binding/dwdpollenflug/internal/dto/DWDPollenflugPollen.java
new file mode 100644
index 0000000000000..4e03734e74518
--- /dev/null
+++ b/bundles/org.openhab.binding.dwdpollenflug/src/main/java/org/openhab/binding/dwdpollenflug/internal/dto/DWDPollenflugPollen.java
@@ -0,0 +1,39 @@
+/**
+ * Copyright (c) 2010-2020 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.dwdpollenflug.internal.dto;
+
+/**
+ * The {@link DWDPollenflug} class is internal DWD data structure.
+ *
+ * @author Johannes Ott - Initial contribution
+ */
+public enum DWDPollenflugPollen {
+ AMBROSIA("ambrosia"),
+ BEIFUSS("mugwort"),
+ BIRKE("birch"),
+ ERLE("alder"),
+ ESCHE("ash"),
+ GRAESER("grasses"),
+ HASEL("hazel"),
+ ROGGEN("rye");
+
+ private final String channelName;
+
+ private DWDPollenflugPollen(String channelName) {
+ this.channelName = channelName;
+ }
+
+ public String getChannelName() {
+ return channelName;
+ }
+}
diff --git a/bundles/org.openhab.binding.dwdpollenflug/src/main/java/org/openhab/binding/dwdpollenflug/internal/dto/DWDPollentypeJSON.java b/bundles/org.openhab.binding.dwdpollenflug/src/main/java/org/openhab/binding/dwdpollenflug/internal/dto/DWDPollentypeJSON.java
new file mode 100644
index 0000000000000..e1188299f460d
--- /dev/null
+++ b/bundles/org.openhab.binding.dwdpollenflug/src/main/java/org/openhab/binding/dwdpollenflug/internal/dto/DWDPollentypeJSON.java
@@ -0,0 +1,32 @@
+/**
+ * Copyright (c) 2010-2020 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.dwdpollenflug.internal.dto;
+
+import com.google.gson.annotations.SerializedName;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+
+/**
+ * DTO for data per pollen type
+ *
+ * @author Johannes Ott - Initial contribution
+ */
+@NonNullByDefault
+public class DWDPollentypeJSON {
+ public String today = "-1";
+
+ public String tomorrow = "-1";
+
+ @SerializedName("dayafter_to")
+ public String dayAfterTomorrow = "-1";
+}
diff --git a/bundles/org.openhab.binding.dwdpollenflug/src/main/java/org/openhab/binding/dwdpollenflug/internal/dto/DWDRegion.java b/bundles/org.openhab.binding.dwdpollenflug/src/main/java/org/openhab/binding/dwdpollenflug/internal/dto/DWDRegion.java
new file mode 100644
index 0000000000000..aa1772346411f
--- /dev/null
+++ b/bundles/org.openhab.binding.dwdpollenflug/src/main/java/org/openhab/binding/dwdpollenflug/internal/dto/DWDRegion.java
@@ -0,0 +1,80 @@
+/**
+ * Copyright (c) 2010-2020 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.dwdpollenflug.internal.dto;
+
+import static org.openhab.binding.dwdpollenflug.internal.DWDPollenflugBindingConstants.*;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import com.google.gson.annotations.SerializedName;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.smarthome.core.library.types.StringType;
+import org.eclipse.smarthome.core.types.State;
+
+/**
+ * The {@link DWDRegion} class holds the internal data representation of each Region
+ *
+ * @author Johannes Ott - Initial contribution
+ */
+@NonNullByDefault
+public class DWDRegion {
+ @SerializedName("region_id")
+ public int regionID = 0;
+
+ @SerializedName("region_name")
+ public String regionName = "";
+
+ @SerializedName("partregion_id")
+ public int partRegionID = 0;
+
+ @SerializedName("partregion_name")
+ public String partRegionName = "";
+
+ @SerializedName("Pollen")
+ private @Nullable Map pollen;
+
+ public Map getProperties() {
+ Map map = new HashMap<>();
+ map.put(PROPERTY_REGION_NAME, regionName);
+ map.put(PROPERTY_PARTREGION_NAME, partRegionName);
+ return Collections.unmodifiableMap(map);
+ }
+
+ public int getRegionID() {
+ if (partRegionID > 0) {
+ return partRegionID;
+ }
+ return regionID;
+ }
+
+ public Map getChannelsStateMap() {
+ final Map localPollen = pollen;
+ if (localPollen != null) {
+ Map map = new HashMap<>();
+ localPollen.forEach((k, jsonType) -> {
+ final String pollenType = DWDPollenflugPollen.valueOf(k.toUpperCase()).getChannelName();
+ map.put(pollenType + "#" + CHANNEL_TODAY, new StringType(jsonType.today));
+ map.put(pollenType + "#" + CHANNEL_TOMORROW, new StringType(jsonType.tomorrow));
+ map.put(pollenType + "#" + CHANNEL_DAYAFTER_TO, new StringType(jsonType.dayAfterTomorrow));
+ });
+
+ return Collections.unmodifiableMap(map);
+ }
+
+ return Collections.emptyMap();
+ }
+}
diff --git a/bundles/org.openhab.binding.dwdpollenflug/src/main/java/org/openhab/binding/dwdpollenflug/internal/handler/DWDPollenflugBridgeHandler.java b/bundles/org.openhab.binding.dwdpollenflug/src/main/java/org/openhab/binding/dwdpollenflug/internal/handler/DWDPollenflugBridgeHandler.java
new file mode 100644
index 0000000000000..a34bcbb159122
--- /dev/null
+++ b/bundles/org.openhab.binding.dwdpollenflug/src/main/java/org/openhab/binding/dwdpollenflug/internal/handler/DWDPollenflugBridgeHandler.java
@@ -0,0 +1,211 @@
+/**
+ * Copyright (c) 2010-2020 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.dwdpollenflug.internal.handler;
+
+import java.net.URI;
+import java.util.Set;
+import java.net.SocketTimeoutException;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+import com.google.gson.Gson;
+import com.google.gson.JsonSyntaxException;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.jetty.client.HttpClient;
+import org.eclipse.jetty.client.HttpResponse;
+import org.eclipse.jetty.client.api.Request;
+import org.eclipse.jetty.client.api.Result;
+import org.eclipse.jetty.client.util.BufferingResponseListener;
+import org.eclipse.jetty.http.HttpMethod;
+import org.eclipse.smarthome.core.thing.Bridge;
+import org.eclipse.smarthome.core.thing.ChannelUID;
+import org.eclipse.smarthome.core.thing.Thing;
+import org.eclipse.smarthome.core.thing.ThingStatus;
+import org.eclipse.smarthome.core.thing.ThingStatusDetail;
+import org.eclipse.smarthome.core.thing.binding.BaseBridgeHandler;
+import org.eclipse.smarthome.core.thing.binding.ThingHandler;
+import org.eclipse.smarthome.core.types.Command;
+import org.eclipse.smarthome.core.types.RefreshType;
+import org.openhab.binding.dwdpollenflug.internal.DWDPollingException;
+import org.openhab.binding.dwdpollenflug.internal.config.DWDPollenflugBridgeConfiguration;
+import org.openhab.binding.dwdpollenflug.internal.dto.DWDPollenflug;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * The {@link DWDPollenflugBridgeHandler} is the handler for bridge thing
+ *
+ * @author Johannes Ott - Initial contribution
+ */
+@NonNullByDefault
+public class DWDPollenflugBridgeHandler extends BaseBridgeHandler {
+ private static final String DWD_URL = "https://opendata.dwd.de/climate_environment/health/alerts/s31fg.json";
+
+ private final Logger logger = LoggerFactory.getLogger(DWDPollenflugBridgeHandler.class);
+
+ private DWDPollenflugBridgeConfiguration bridgeConfig = new DWDPollenflugBridgeConfiguration();
+ private @Nullable ScheduledFuture> pollingJob;
+ private @Nullable DWDPollenflug pollenflug;
+ private final Set regionListeners = ConcurrentHashMap.newKeySet();
+ private final HttpClient client;
+ private final Gson gson = new Gson();
+
+ public DWDPollenflugBridgeHandler(Bridge bridge, HttpClient client) {
+ super(bridge);
+ this.client = client;
+ }
+
+ @Override
+ public void handleCommand(ChannelUID channelUID, Command command) {
+ if (command instanceof RefreshType) {
+ final DWDPollenflug localPollenflug = pollenflug;
+ if (localPollenflug != null) {
+ notifyOnUpdate(localPollenflug);
+ }
+ }
+ }
+
+ @Override
+ public void initialize() {
+ logger.debug("Initializing DWD Pollenflug bridge handler");
+ bridgeConfig = getConfigAs(DWDPollenflugBridgeConfiguration.class);
+
+ if (bridgeConfig.isValid()) {
+ startPolling();
+ updateStatus(ThingStatus.ONLINE);
+ } else {
+ updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
+ "Refresh interval has to be at least 15 minutes.");
+ }
+ }
+
+ @Override
+ public void dispose() {
+ logger.debug("Handler disposed.");
+ stopPolling();
+ }
+
+ private void startPolling() {
+ final ScheduledFuture> localPollingJob = this.pollingJob;
+ if (localPollingJob == null || localPollingJob.isCancelled()) {
+ logger.debug("Start polling.");
+ pollingJob = scheduler.scheduleWithFixedDelay(this::poll, 0, bridgeConfig.refresh, TimeUnit.MINUTES);
+ }
+ }
+
+ private void stopPolling() {
+ final ScheduledFuture> localPollingJob = this.pollingJob;
+ if (localPollingJob != null && !localPollingJob.isCancelled()) {
+ logger.debug("Stop polling.");
+ localPollingJob.cancel(true);
+ pollingJob = null;
+ }
+ }
+
+ private void poll() {
+ logger.debug("Polling");
+ requestRefresh().handle((resultPollenflug, pollException) -> {
+ if (resultPollenflug == null) {
+ if (pollException == null) {
+ updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR);
+ } else {
+ updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
+ pollException.getMessage());
+ }
+ } else {
+ updateStatus(ThingStatus.ONLINE);
+ notifyOnUpdate(resultPollenflug);
+ }
+
+ return null;
+ });
+ }
+
+ private CompletableFuture<@Nullable DWDPollenflug> requestRefresh() {
+ CompletableFuture<@Nullable DWDPollenflug> f = new CompletableFuture<>();
+ Request request = client.newRequest(URI.create(DWD_URL));
+
+ request.method(HttpMethod.GET).timeout(2000, TimeUnit.SECONDS).send(new BufferingResponseListener() {
+ @NonNullByDefault({})
+ @Override
+ public void onComplete(Result result) {
+ final HttpResponse response = (HttpResponse) result.getResponse();
+ if (result.getFailure() != null) {
+ Throwable e = result.getFailure();
+ if (e instanceof SocketTimeoutException || e instanceof TimeoutException) {
+ f.completeExceptionally(new DWDPollingException("Request timeout", e));
+ } else {
+ f.completeExceptionally(new DWDPollingException("Request failed", e));
+ }
+ } else if (response.getStatus() != 200) {
+ f.completeExceptionally(new DWDPollingException(getContentAsString()));
+ } else {
+ try {
+ DWDPollenflug pollenflugJSON = gson.fromJson(getContentAsString(), DWDPollenflug.class);
+ f.complete(pollenflugJSON);
+ } catch (JsonSyntaxException ex2) {
+ f.completeExceptionally(new DWDPollingException("Parsing of response failed"));
+ }
+ }
+ }
+ });
+
+ return f;
+ }
+
+ @Override
+ public void childHandlerInitialized(ThingHandler childHandler, Thing childThing) {
+ if (childHandler instanceof DWDPollenflugRegionHandler) {
+ logger.debug("Register region listener.");
+ final DWDPollenflugRegionHandler regionListener = (DWDPollenflugRegionHandler) childHandler;
+ if (regionListeners.add(regionListener)) {
+ final DWDPollenflug localPollenflug = pollenflug;
+ if (localPollenflug != null) {
+ regionListener.notifyOnUpdate(localPollenflug);
+ }
+ } else {
+ logger.warn("Tried to add listener {} but it was already present. This is probably an error.",
+ childHandler);
+ }
+ }
+ }
+
+ @Override
+ public void childHandlerDisposed(ThingHandler childHandler, Thing childThing) {
+ if (childHandler instanceof DWDPollenflugRegionHandler) {
+ logger.debug("Unregister region listener.");
+ if (!regionListeners.remove((DWDPollenflugRegionHandler) childHandler)) {
+ logger.warn("Tried to remove listener {} but it was not registered. This is probably an error.",
+ childHandler);
+ }
+ }
+ }
+
+ public void notifyOnUpdate(@Nullable DWDPollenflug newPollenflug) {
+ if (newPollenflug != null) {
+ pollenflug = newPollenflug;
+ updateProperties(newPollenflug.getProperties());
+ regionListeners.forEach(listener -> listener.notifyOnUpdate(newPollenflug));
+ newPollenflug.getChannelsStateMap().forEach(this::updateState);
+ }
+ }
+
+ public @Nullable DWDPollenflug getPollenflug() {
+ return pollenflug;
+ }
+}
diff --git a/bundles/org.openhab.binding.dwdpollenflug/src/main/java/org/openhab/binding/dwdpollenflug/internal/handler/DWDPollenflugRegionHandler.java b/bundles/org.openhab.binding.dwdpollenflug/src/main/java/org/openhab/binding/dwdpollenflug/internal/handler/DWDPollenflugRegionHandler.java
new file mode 100644
index 0000000000000..a4482e7527d02
--- /dev/null
+++ b/bundles/org.openhab.binding.dwdpollenflug/src/main/java/org/openhab/binding/dwdpollenflug/internal/handler/DWDPollenflugRegionHandler.java
@@ -0,0 +1,112 @@
+/**
+ * Copyright (c) 2010-2020 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.dwdpollenflug.internal.handler;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.smarthome.core.thing.Bridge;
+import org.eclipse.smarthome.core.thing.ChannelUID;
+import org.eclipse.smarthome.core.thing.Thing;
+import org.eclipse.smarthome.core.thing.ThingStatus;
+import org.eclipse.smarthome.core.thing.ThingStatusDetail;
+import org.eclipse.smarthome.core.thing.binding.BaseThingHandler;
+import org.eclipse.smarthome.core.thing.binding.ThingHandler;
+import org.eclipse.smarthome.core.types.Command;
+import org.eclipse.smarthome.core.types.RefreshType;
+import org.openhab.binding.dwdpollenflug.internal.config.DWDPollenflugRegionConfiguration;
+import org.openhab.binding.dwdpollenflug.internal.dto.DWDPollenflug;
+import org.openhab.binding.dwdpollenflug.internal.dto.DWDRegion;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * The {@link DWDPollenflugRegionHandler} is the handler for bridge thing
+ *
+ * @author Johannes Ott - Initial contribution
+ */
+@NonNullByDefault
+public class DWDPollenflugRegionHandler extends BaseThingHandler {
+
+ private final Logger logger = LoggerFactory.getLogger(DWDPollenflugRegionHandler.class);
+
+ private DWDPollenflugRegionConfiguration thingConfig = new DWDPollenflugRegionConfiguration();
+
+ public DWDPollenflugRegionHandler(Thing thing) {
+ super(thing);
+ }
+
+ @Override
+ public void initialize() {
+ logger.debug("Initializing DWD Pollenflug region handler");
+ thingConfig = getConfigAs(DWDPollenflugRegionConfiguration.class);
+
+ if (thingConfig.isValid()) {
+ DWDPollenflugBridgeHandler handler = getBridgeHandler();
+ if (handler == null) {
+ updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, "Bridge handler missing");
+ } else {
+ updateStatus(ThingStatus.ONLINE);
+ }
+ } else {
+ updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, "No valid region id given.");
+ }
+ }
+
+ private synchronized @Nullable DWDPollenflugBridgeHandler getBridgeHandler() {
+ Bridge bridge = getBridge();
+ if (bridge != null) {
+ ThingHandler handler = bridge.getHandler();
+ if (handler instanceof DWDPollenflugBridgeHandler) {
+ DWDPollenflugBridgeHandler bridgeHandler = (DWDPollenflugBridgeHandler) handler;
+ return bridgeHandler;
+ }
+ }
+
+ return null;
+ }
+
+ @Override
+ public void dispose() {
+ logger.debug("DWDPollenflug region handler disposes.");
+ }
+
+ @Override
+ public void handleCommand(ChannelUID channelUID, Command command) {
+ if (command instanceof RefreshType) {
+ refresh();
+ }
+ }
+
+ private void refresh() {
+ DWDPollenflugBridgeHandler handler = getBridgeHandler();
+ if (handler != null) {
+ DWDPollenflug pollenflug = handler.getPollenflug();
+ if (pollenflug != null) {
+ notifyOnUpdate(pollenflug);
+ }
+ }
+ }
+
+ public void notifyOnUpdate(DWDPollenflug pollenflug) {
+ DWDRegion region = pollenflug.getRegion(thingConfig.regionID);
+ if (region == null) {
+ updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, "Region not found");
+ return;
+ }
+
+ updateStatus(ThingStatus.ONLINE);
+ updateProperties(region.getProperties());
+
+ region.getChannelsStateMap().forEach(this::updateState);
+ }
+}
diff --git a/bundles/org.openhab.binding.dwdpollenflug/src/main/resources/ESH-INF/binding/binding.xml b/bundles/org.openhab.binding.dwdpollenflug/src/main/resources/ESH-INF/binding/binding.xml
new file mode 100644
index 0000000000000..8ba0620c7c198
--- /dev/null
+++ b/bundles/org.openhab.binding.dwdpollenflug/src/main/resources/ESH-INF/binding/binding.xml
@@ -0,0 +1,10 @@
+
+
+
+ DWD Pollenflug Binding
+ This is the binding for DWDPollenflug.
+ Johannes Ott
+
+
diff --git a/bundles/org.openhab.binding.dwdpollenflug/src/main/resources/ESH-INF/i18n/dwdpollenflug_de.properties b/bundles/org.openhab.binding.dwdpollenflug/src/main/resources/ESH-INF/i18n/dwdpollenflug_de.properties
new file mode 100644
index 0000000000000..4c23588250dc8
--- /dev/null
+++ b/bundles/org.openhab.binding.dwdpollenflug/src/main/resources/ESH-INF/i18n/dwdpollenflug_de.properties
@@ -0,0 +1,46 @@
+#binding
+binding.dwdpollenflug.name = DWD Pollenflugindex
+binding.dwdpollenflug.description = Binding um den Pollenflugindex des deutschen Wetterdienstes anzuzeigen
+
+#bridge
+thing-type.dwdpollenflug.bridge.label = DWD Pollenflugindex - Bridge
+thing-type.dwdpollenflug.bridge.description = Bridge um den Pollenflugindex des DWDs abzurufen.
+
+#bridge config
+thing-type.config.dwdpollenflug.bridge.refresh.label = Aktualisierungsinterval
+thing-type.config.dwdpollenflug.bridge.refresh.description = Zeit zwischen zwei API-Anfragen in Minuten. Minimum 15 Minuten.
+
+#thing types
+thing-type.dwdpollenflug.region.label = DWD Pollenflugindex Region
+thing-type.dwdpollenflug.region.description = Pollenflugindex f\u00FCr eine bestimmte Region oder Teilregion
+thing-type.dwdpollenflug.region.group.updates.label = Aktualisierung
+thing-type.dwdpollenflug.region.group.updates.description = Informationen zur Aktualisierung
+thing-type.dwdpollenflug.region.group.alder.label=Erle
+thing-type.dwdpollenflug.region.group.alder.description=Informationen f\u00FCr Erle
+thing-type.dwdpollenflug.region.group.ambrosia.label=Ambrosia
+thing-type.dwdpollenflug.region.group.ambrosia.description=Informationen f\u00FCr Ambrosia
+thing-type.dwdpollenflug.region.group.ash.label=Esche
+thing-type.dwdpollenflug.region.group.ash.description=Informationen f\u00FCr Esche
+thing-type.dwdpollenflug.region.group.birch.label=Birke
+thing-type.dwdpollenflug.region.group.birch.description=Informationen f\u00FCr Birke
+thing-type.dwdpollenflug.region.group.grasses.label=Gr\u00E4sser
+thing-type.dwdpollenflug.region.group.grasses.description=Informationen f\u00FCr Gr\u00E4sser
+thing-type.dwdpollenflug.region.group.hazel.label=Hasel
+thing-type.dwdpollenflug.region.group.hazel.description=Informationen f\u00FCr Hasel
+thing-type.dwdpollenflug.region.group.mugwort.label=Beifu\u00DF
+thing-type.dwdpollenflug.region.group.mugwort.description=Informationen f\u00FCr Beifu\u00DF
+thing-type.dwdpollenflug.region.group.rye.label=Roggen
+thing-type.dwdpollenflug.region.group.rye.description=Informationen f\u00FCr Roggen
+
+#thing region config
+thing-type.config.dwdpollenflug.region.regionID.label = Region
+thing-type.config.dwdpollenflug.region.regionID.description = Die Teilregion oder Region die angezeigt werden soll.
+
+#channel-group-type
+channel-group-type.dwdpollenflug.pollentype.channel.today.label = Heute
+channel-group-type.dwdpollenflug.pollentype.channel.tomorrow.label = Morgen
+channel-group-type.dwdpollenflug.pollentype.channel.dayafter_to.label = \u00DCbermorgen
+
+channel-group-type.dwdpollenflug.updates.channel.refreshed.label = Letzte Aktualisierung Bridge
+channel-group-type.dwdpollenflug.updates.channel.last_update.label = Letzte Aktualisierung DWD
+channel-group-type.dwdpollenflug.updates.channel.next_update.label = N\u00E4chste Aktualisierung DWD
diff --git a/bundles/org.openhab.binding.dwdpollenflug/src/main/resources/ESH-INF/thing/bridge.xml b/bundles/org.openhab.binding.dwdpollenflug/src/main/resources/ESH-INF/thing/bridge.xml
new file mode 100644
index 0000000000000..d103e0ac2aa67
--- /dev/null
+++ b/bundles/org.openhab.binding.dwdpollenflug/src/main/resources/ESH-INF/thing/bridge.xml
@@ -0,0 +1,51 @@
+
+
+
+
+
+ Bridge for accessing pollen count index data of the DWD
+
+
+
+
+
+
+
+
+
+
+
+
+ 30
+
+ Time between two API requests in minutes. Minimum 15 minutes.
+
+
+
+
+
+
+
+ Information about data state
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ DateTime
+
+
+
+
diff --git a/bundles/org.openhab.binding.dwdpollenflug/src/main/resources/ESH-INF/thing/region.xml b/bundles/org.openhab.binding.dwdpollenflug/src/main/resources/ESH-INF/thing/region.xml
new file mode 100644
index 0000000000000..eaf5b7968a3fd
--- /dev/null
+++ b/bundles/org.openhab.binding.dwdpollenflug/src/main/resources/ESH-INF/thing/region.xml
@@ -0,0 +1,113 @@
+
+
+
+
+
+
+
+
+
+ Pollen count index for a region or partregion
+
+
+
+
+ Information for alder
+
+
+
+ Information for ambrosia
+
+
+
+ Information for ash tree
+
+
+
+ Information for birch
+
+
+
+ Information for grasses
+
+
+
+ Information for hazel
+
+
+
+ Information for mugwort
+
+
+
+ Information for rye
+
+
+
+
+
+
+
+
+
+
+
+ The partregion or region that should be reported.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ For each pollen type there are three channels for today, tomorrow and day after tomorrow
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ String
+
+
+
+
diff --git a/bundles/pom.xml b/bundles/pom.xml
index 33c23dab3bb6e..33d563d63b33e 100644
--- a/bundles/pom.xml
+++ b/bundles/pom.xml
@@ -74,6 +74,7 @@
org.openhab.binding.doorbird
org.openhab.binding.dscalarm
org.openhab.binding.dsmr
+ org.openhab.binding.dwdpollenflug
org.openhab.binding.dwdunwetter
org.openhab.binding.elerotransmitterstick
org.openhab.binding.enocean