]> git.basschouten.com Git - openhab-addons.git/commitdiff
[openweathermap] Added One Call API weather warnings (#10435)
authorChristoph Weitkamp <github@christophweitkamp.de>
Fri, 9 Apr 2021 20:59:25 +0000 (22:59 +0200)
committerGitHub <noreply@github.com>
Fri, 9 Apr 2021 20:59:25 +0000 (22:59 +0200)
* Added One Call API weather warnings

Signed-off-by: Christoph Weitkamp <github@christophweitkamp.de>
* Changed Channel title to event

Signed-off-by: Christoph Weitkamp <github@christophweitkamp.de>
12 files changed:
bundles/org.openhab.binding.openweathermap/README.md
bundles/org.openhab.binding.openweathermap/src/main/java/org/openhab/binding/openweathermap/internal/OpenWeatherMapBindingConstants.java
bundles/org.openhab.binding.openweathermap/src/main/java/org/openhab/binding/openweathermap/internal/config/OpenWeatherMapOneCallConfiguration.java
bundles/org.openhab.binding.openweathermap/src/main/java/org/openhab/binding/openweathermap/internal/connection/OpenWeatherMapConnection.java
bundles/org.openhab.binding.openweathermap/src/main/java/org/openhab/binding/openweathermap/internal/dto/onecall/Alert.java [new file with mode: 0644]
bundles/org.openhab.binding.openweathermap/src/main/java/org/openhab/binding/openweathermap/internal/dto/onecall/OpenWeatherMapOneCallAPIData.java
bundles/org.openhab.binding.openweathermap/src/main/java/org/openhab/binding/openweathermap/internal/handler/OpenWeatherMapOneCallHandler.java
bundles/org.openhab.binding.openweathermap/src/main/resources/OH-INF/config/config.xml
bundles/org.openhab.binding.openweathermap/src/main/resources/OH-INF/i18n/openweathermap.properties
bundles/org.openhab.binding.openweathermap/src/main/resources/OH-INF/i18n/openweathermap_de.properties
bundles/org.openhab.binding.openweathermap/src/main/resources/OH-INF/thing/channel-types.xml
bundles/org.openhab.binding.openweathermap/src/main/resources/OH-INF/thing/thing-types.xml

index d63422b117ae6d7d9ac5fa9b1ce374c21d7ee96a..00e49e47ba43ee1ab4a8e62ba0c8d5b21917a3b6 100644 (file)
@@ -103,12 +103,13 @@ Once the parameter `forecastHours` will be changed, the available channel groups
 
 ### One Call API Weather and Forecast
 
-| Parameter      | Description                                                                                                                    |
-|----------------|--------------------------------------------------------------------------------------------------------------------------------|
-| location       | Location of weather in geographical coordinates (latitude/longitude/altitude). **Mandatory**                                   |
+| Parameter      | Description                                                                                                                                                           |
+|----------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| location       | Location of weather in geographical coordinates (latitude/longitude/altitude). **Mandatory**                                                                          |
 | forecastMinutes| Number of minutes for minutely precipitation forecast. Optional, the default value is 0, so by default **no** minutely forecast data is fetched. (min="0", max="60"). |
-| forecastHours  | Number of hours for hourly forecast. Optional, the default value is 24 (min="0", max="48").                                    |
-| forecastDays   | Number of days for daily forecast (including todays forecast). Optional, the default value is 6 (min="0", max="8").            |
+| forecastHours  | Number of hours for hourly forecast. Optional, the default value is 24 (min="0", max="48").                                                                           |
+| forecastDays   | Number of days for daily forecast (including todays forecast). Optional, the default value is 6 (min="0", max="8").                                                   |
+| numberOfAlerts | Number of alerts to be shown. Optional, the default value is 0 (min="0", max="5").                                                                                    |
     
 ### One Call API History Data
 
@@ -232,7 +233,17 @@ See above for a description of the available channels.
 | forecastToday, forecastTomorrow, forecastDay2, ... forecastDay7  | apparent-day         | Number:Temperature   | Expected apparent temperature in the day. Only available in the One Call API      |
 | forecastToday, forecastTomorrow, forecastDay2, ... forecastDay7  | apparent-evening     | Number:Temperature   | Expected apparent temperature in the evening. Only available in the One Call API  |
 | forecastToday, forecastTomorrow, forecastDay2, ... forecastDay7  | apparent-night       | Number:Temperature   | Expected apparent temperature in the night. Only available in the One Call API    |
-     
+
+### One Call API Weather Warnings
+
+| Channel Group ID      | Channel ID  | Item Type | Description                                         |
+|-----------------------|-------------|-----------|-----------------------------------------------------|
+| alerts1, alerts2, ... | event       | String    | Type of the warning, e.g. FROST.                    |
+| alerts1, alerts2, ... | description | String    | A detailed description of the alert.                |
+| alerts1, alerts2, ... | onset       | DateTime  | Start Date and Time for which the warning is valid. |
+| alerts1, alerts2, ... | expires     | DateTime  | End Date and Time for which the warning is valid.   |
+| alerts1, alerts2, ... | source      | String    | The source of the alert. **Advanced**               |
+
 ### UV Index
 
 | Channel Group ID                                          | Channel ID | Item Type | Description                          |
index 3a72a1908b64950dc102743d05815f1b533b6e4d..eb5f57437290fdb634379e3177df4d60325e86ad 100644 (file)
@@ -65,6 +65,8 @@ public class OpenWeatherMapBindingConstants {
             BINDING_ID, "oneCallDaily");
     public static final ChannelGroupTypeUID CHANNEL_GROUP_TYPE_ONECALL_CURRENT = new ChannelGroupTypeUID(BINDING_ID,
             "oneCallCurrent");
+    public static final ChannelGroupTypeUID CHANNEL_GROUP_TYPE_ONECALL_ALERTS = new ChannelGroupTypeUID(BINDING_ID,
+            "oneCallAlerts");
 
     // List of all channel groups
     public static final String CHANNEL_GROUP_STATION = "station";
@@ -123,6 +125,11 @@ public class OpenWeatherMapBindingConstants {
     public static final String CHANNEL_SULPHUR_DIOXIDE = "sulphurDioxide";
     public static final String CHANNEL_AMMONIA = "ammonia";
     public static final String CHANNEL_PRECIPITATION = "precipitation";
+    public static final String CHANNEL_ALERT_EVENT = "event";
+    public static final String CHANNEL_ALERT_DESCRIPTION = "description";
+    public static final String CHANNEL_ALERT_ONSET = "onset";
+    public static final String CHANNEL_ALERT_EXPIRES = "expires";
+    public static final String CHANNEL_ALERT_SOURCE = "source";
 
     // List of all configuration
     public static final String CONFIG_FORECAST_DAYS = "forecastDays";
index 4308cc688fdc63bf0592c0722deca337ac73744d..7521d8128aed319e6861436a387b75d11b760227 100644 (file)
 package org.openhab.binding.openweathermap.internal.config;
 
 import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.openhab.binding.openweathermap.internal.handler.OpenWeatherMapOneCallHandler;
 
 /**
- * The {@link OpenWeatherMapOneCallConfiguration} is the class used to match the
- * {@link org.openhab.binding.openweathermap.internal.handler.OpenWeatherMapOneCallHandler}s configuration.
+ * The {@link OpenWeatherMapOneCallConfiguration} is the class used to match the {@link OpenWeatherMapOneCallHandler}s
+ * configuration.
  *
  * @author Wolfgang Klimt - Initial contribution
+ * @author Christoph Weitkamp - Added weather alerts
  */
 @NonNullByDefault
 public class OpenWeatherMapOneCallConfiguration extends OpenWeatherMapLocationConfiguration {
     public int forecastMinutes;
     public int forecastHours;
     public int forecastDays;
+    public int numberOfAlerts;
 }
index db25ed9fac398e9988bffd73f74faa97e1818168..f4310e60e3be5f2d05c9ff70077daf845519eeaa 100644 (file)
@@ -12,7 +12,6 @@
  */
 package org.openhab.binding.openweathermap.internal.connection;
 
-import static java.util.stream.Collectors.joining;
 import static org.eclipse.jetty.http.HttpMethod.GET;
 import static org.eclipse.jetty.http.HttpStatus.*;
 
@@ -21,6 +20,7 @@ import java.net.URLEncoder;
 import java.nio.charset.StandardCharsets;
 import java.time.ZoneId;
 import java.time.ZonedDateTime;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashMap;
 import java.util.List;
@@ -28,6 +28,7 @@ import java.util.Map;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
+import java.util.stream.Collectors;
 
 import org.eclipse.jdt.annotation.NonNullByDefault;
 import org.eclipse.jdt.annotation.Nullable;
@@ -293,12 +294,12 @@ public class OpenWeatherMapConnection {
     }
 
     /**
-     * Get Weather data from the OneCall API for the given location. See https://openweathermap.org/api/one-call-api for
-     * details
+     * Get Weather data from the One Call API for the given location. See https://openweathermap.org/api/one-call-api
+     * for details.
      *
      * @param location location represented as {@link PointType}
      * @param excludeMinutely if true, will not fetch minutely forecast data from the server
-     * @param excludeHourly if true, will not fethh hourly forecast data from the server
+     * @param excludeHourly if true, will not fetch hourly forecast data from the server
      * @param excludeDaily if true, will not fetch hourly forecast data from the server
      * @return
      * @throws JsonSyntaxException
@@ -306,32 +307,33 @@ public class OpenWeatherMapConnection {
      * @throws OpenWeatherMapConfigurationException
      */
     public synchronized @Nullable OpenWeatherMapOneCallAPIData getOneCallAPIData(@Nullable PointType location,
-            boolean excludeMinutely, boolean excludeHourly, boolean excludeDaily)
+            boolean excludeMinutely, boolean excludeHourly, boolean excludeDaily, boolean excludeAlerts)
             throws JsonSyntaxException, OpenWeatherMapCommunicationException, OpenWeatherMapConfigurationException {
         Map<String, String> params = getRequestParams(handler.getOpenWeatherMapAPIConfig(), location);
-        StringBuilder exclude = new StringBuilder("");
+        List<String> exclude = new ArrayList<>();
         if (excludeMinutely) {
-            exclude.append("minutely");
+            exclude.add("minutely");
         }
         if (excludeHourly) {
-            exclude.append(exclude.length() > 0 ? "," : "").append("hourly");
+            exclude.add("hourly");
         }
         if (excludeDaily) {
-            exclude.append(exclude.length() > 0 ? "," : "").append("daily");
+            exclude.add("daily");
+        }
+        if (excludeAlerts) {
+            exclude.add("alerts");
         }
         logger.debug("Exclude: '{}'", exclude);
-        if (exclude.length() > 0) {
-            params.put(PARAM_EXCLUDE, exclude.toString());
+        if (!exclude.isEmpty()) {
+            params.put(PARAM_EXCLUDE, exclude.stream().collect(Collectors.joining(",")));
         }
         return gson.fromJson(getResponseFromCache(buildURL(ONECALL_URL, params)), OpenWeatherMapOneCallAPIData.class);
     }
 
     /**
-     * Get the historical weather data from the OneCall API for the given location and the given number of days in the
-     * past.
-     * As of now, OpenWeatherMap supports this function for up to 5 days in the past. However, this may change in the
-     * future,
-     * so we don't enforce this limit here. See https://openweathermap.org/api/one-call-api for details
+     * Get the historical weather data from the One Call API for the given location and the given number of days in the
+     * past. As of now, OpenWeatherMap supports this function for up to 5 days in the past. However, this may change in
+     * the future, so we don't enforce this limit here. See https://openweathermap.org/api/one-call-api for details.
      *
      * @param location location represented as {@link PointType}
      * @param days number of days in the past, relative to the current time.
@@ -381,7 +383,7 @@ public class OpenWeatherMapConnection {
 
     private String buildURL(String url, Map<String, String> requestParams) {
         return requestParams.keySet().stream().map(key -> key + "=" + encodeParam(requestParams.get(key)))
-                .collect(joining("&", url + "?", ""));
+                .collect(Collectors.joining("&", url + "?", ""));
     }
 
     private String encodeParam(@Nullable String value) {
diff --git a/bundles/org.openhab.binding.openweathermap/src/main/java/org/openhab/binding/openweathermap/internal/dto/onecall/Alert.java b/bundles/org.openhab.binding.openweathermap/src/main/java/org/openhab/binding/openweathermap/internal/dto/onecall/Alert.java
new file mode 100644 (file)
index 0000000..29ede4c
--- /dev/null
@@ -0,0 +1,29 @@
+/**
+ * Copyright (c) 2010-2021 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.openweathermap.internal.dto.onecall;
+
+import com.google.gson.annotations.SerializedName;
+
+/**
+ * Generated Plain Old Java Objects class for {@link Alert} from JSON.
+ *
+ * @author Christoph Weitkamp - Initial contribution
+ */
+public class Alert {
+    public String event;
+    public int start;
+    public int end;
+    public String description;
+    @SerializedName("sender_name")
+    public String senderName;
+}
index 160c9825e77b6a5012ce7d984b3cdc77c0f667ab..be79e1bda9dfe245517db2f874ca0859a8106e65 100644 (file)
@@ -14,7 +14,8 @@ package org.openhab.binding.openweathermap.internal.dto.onecall;
 
 import java.util.List;
 
-import com.google.gson.annotations.Expose;
+import org.eclipse.jdt.annotation.Nullable;
+
 import com.google.gson.annotations.SerializedName;
 
 /**
@@ -26,33 +27,21 @@ import com.google.gson.annotations.SerializedName;
  * allow additional properties
  *
  * @author Wolfgang Klimt - Initial contribution
+ * @author Christoph Weitkamp - Added weather alerts
  */
 public class OpenWeatherMapOneCallAPIData {
 
-    @SerializedName("lat")
-    @Expose
     private double lat;
-    @SerializedName("lon")
-    @Expose
     private double lon;
-    @SerializedName("timezone")
-    @Expose
     private String timezone;
     @SerializedName("timezone_offset")
-    @Expose
     private int timezoneOffset;
-    @SerializedName("current")
-    @Expose
     private Current current;
-    @SerializedName("minutely")
-    @Expose
-    private List<Minutely> minutely = null;
-    @SerializedName("hourly")
-    @Expose
-    private List<Hourly> hourly = null;
-    @SerializedName("daily")
-    @Expose
-    private List<Daily> daily = null;
+    private List<Minutely> minutely;
+    private List<Hourly> hourly;
+    private List<Daily> daily;
+
+    public @Nullable List<Alert> alerts;
 
     public double getLat() {
         return lat;
index 52ba04d6d21f1fc013e72445fdd351b8a320bed8..9cd2d030847d5603a600411010aca9c401ed620a 100644 (file)
@@ -28,10 +28,19 @@ import org.openhab.binding.openweathermap.internal.config.OpenWeatherMapOneCallC
 import org.openhab.binding.openweathermap.internal.connection.OpenWeatherMapCommunicationException;
 import org.openhab.binding.openweathermap.internal.connection.OpenWeatherMapConfigurationException;
 import org.openhab.binding.openweathermap.internal.connection.OpenWeatherMapConnection;
-import org.openhab.binding.openweathermap.internal.dto.onecall.*;
+import org.openhab.binding.openweathermap.internal.dto.onecall.Alert;
+import org.openhab.binding.openweathermap.internal.dto.onecall.FeelsLike;
+import org.openhab.binding.openweathermap.internal.dto.onecall.OpenWeatherMapOneCallAPIData;
+import org.openhab.binding.openweathermap.internal.dto.onecall.Rain;
+import org.openhab.binding.openweathermap.internal.dto.onecall.Snow;
+import org.openhab.binding.openweathermap.internal.dto.onecall.Temp;
 import org.openhab.core.i18n.TimeZoneProvider;
 import org.openhab.core.library.types.QuantityType;
-import org.openhab.core.thing.*;
+import org.openhab.core.thing.Channel;
+import org.openhab.core.thing.ChannelUID;
+import org.openhab.core.thing.Thing;
+import org.openhab.core.thing.ThingStatus;
+import org.openhab.core.thing.ThingStatusDetail;
 import org.openhab.core.thing.binding.builder.ThingBuilder;
 import org.openhab.core.types.State;
 import org.openhab.core.types.UnDefType;
@@ -45,6 +54,7 @@ import com.google.gson.JsonSyntaxException;
  * the channels.
  *
  * @author Wolfgang Klimt - Initial contribution
+ * @author Christoph Weitkamp - Added weather alerts
  */
 @NonNullByDefault
 public class OpenWeatherMapOneCallHandler extends AbstractOpenWeatherMapHandler {
@@ -54,18 +64,22 @@ public class OpenWeatherMapOneCallHandler extends AbstractOpenWeatherMapHandler
     private static final String CHANNEL_GROUP_MINUTELY_FORECAST_PREFIX = "forecastMinutes";
     private static final String CHANNEL_GROUP_HOURLY_FORECAST_PREFIX = "forecastHours";
     private static final String CHANNEL_GROUP_DAILY_FORECAST_PREFIX = "forecastDay";
+    private static final String CHANNEL_GROUP_ALERTS_PREFIX = "alerts";
     private static final Pattern CHANNEL_GROUP_HOURLY_FORECAST_PREFIX_PATTERN = Pattern
             .compile(CHANNEL_GROUP_HOURLY_FORECAST_PREFIX + "([0-9]*)");
     private static final Pattern CHANNEL_GROUP_DAILY_FORECAST_PREFIX_PATTERN = Pattern
             .compile(CHANNEL_GROUP_DAILY_FORECAST_PREFIX + "([0-9]*)");
     private static final Pattern CHANNEL_GROUP_MINUTELY_FORECAST_PREFIX_PATTERN = Pattern
             .compile(CHANNEL_GROUP_MINUTELY_FORECAST_PREFIX + "([0-9]*)");
+    private static final Pattern CHANNEL_GROUP_ALERTS_PREFIX_PATTERN = Pattern
+            .compile(CHANNEL_GROUP_ALERTS_PREFIX + "([0-9]*)");
 
     private @Nullable OpenWeatherMapOneCallAPIData weatherData;
 
     private int forecastMinutes = 60;
     private int forecastHours = 24;
     private int forecastDays = 8;
+    private int numberOfAlerts = 0;
 
     public OpenWeatherMapOneCallHandler(Thing thing, final TimeZoneProvider timeZoneProvider) {
         super(thing, timeZoneProvider);
@@ -96,6 +110,12 @@ public class OpenWeatherMapOneCallHandler extends AbstractOpenWeatherMapHandler
                     "@text/offline.conf-error-not-supported-onecall-number-of-days");
             configValid = false;
         }
+        int newNumberOfAlerts = config.numberOfAlerts;
+        if (newNumberOfAlerts < 0) {
+            updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
+                    "@text/offline.conf-error-not-supported-onecall-number-of-alerts");
+            configValid = false;
+        }
 
         if (configValid) {
             logger.debug("Rebuilding thing '{}'.", getThing().getUID());
@@ -103,7 +123,6 @@ public class OpenWeatherMapOneCallHandler extends AbstractOpenWeatherMapHandler
             List<Channel> toBeRemovedChannels = new ArrayList<>();
             toBeAddedChannels
                     .addAll(createChannelsForGroup(CHANNEL_GROUP_ONECALL_CURRENT, CHANNEL_GROUP_TYPE_ONECALL_CURRENT));
-
             if (forecastMinutes != newForecastMinutes) {
                 logger.debug("forecastMinutes changed from {} to {}. Rebuilding minutely forecast channel groups.",
                         forecastMinutes, newForecastMinutes);
@@ -161,13 +180,29 @@ public class OpenWeatherMapOneCallHandler extends AbstractOpenWeatherMapHandler
                         toBeAddedChannels.addAll(createChannelsForGroup(CHANNEL_GROUP_FORECAST_TOMORROW,
                                 CHANNEL_GROUP_TYPE_ONECALL_DAILY_FORECAST));
                     }
-                    for (int i = Math.max(forecastDays, 2); i < newForecastDays; i++) {
+                    for (int i = Math.max(forecastDays, 2); i < newForecastDays; ++i) {
                         toBeAddedChannels.addAll(
                                 createChannelsForGroup(CHANNEL_GROUP_DAILY_FORECAST_PREFIX + Integer.toString(i),
                                         CHANNEL_GROUP_TYPE_ONECALL_DAILY_FORECAST));
                     }
                 }
                 forecastDays = newForecastDays;
+                if (numberOfAlerts != newNumberOfAlerts) {
+                    logger.debug("Rebuilding alerts channel groups.");
+                    if (numberOfAlerts > newNumberOfAlerts) {
+                        for (int i = newNumberOfAlerts + 1; i <= numberOfAlerts; ++i) {
+                            toBeRemovedChannels
+                                    .addAll(removeChannelsOfGroup(CHANNEL_GROUP_ALERTS_PREFIX + Integer.toString(i)));
+                        }
+                    } else {
+                        for (int i = numberOfAlerts + 1; i <= newNumberOfAlerts; ++i) {
+                            toBeAddedChannels
+                                    .addAll(createChannelsForGroup(CHANNEL_GROUP_ALERTS_PREFIX + Integer.toString(i),
+                                            CHANNEL_GROUP_TYPE_ONECALL_ALERTS));
+                        }
+                    }
+                    numberOfAlerts = newNumberOfAlerts;
+                }
             }
             logger.debug("toBeRemovedChannels: {}. toBeAddedChannels: {}", toBeRemovedChannels, toBeAddedChannels);
             ThingBuilder builder = editThing().withoutChannels(toBeRemovedChannels);
@@ -175,7 +210,6 @@ public class OpenWeatherMapOneCallHandler extends AbstractOpenWeatherMapHandler
                 builder.withChannel(channel);
             }
             updateThing(builder.build());
-            updateStatus(ThingStatus.ONLINE);
         }
     }
 
@@ -185,7 +219,7 @@ public class OpenWeatherMapOneCallHandler extends AbstractOpenWeatherMapHandler
         logger.debug("Update weather and forecast data of thing '{}'.", getThing().getUID());
         try {
             weatherData = connection.getOneCallAPIData(location, forecastMinutes == 0, forecastHours == 0,
-                    forecastDays == 0);
+                    forecastDays == 0, numberOfAlerts == 0);
             return true;
         } catch (JsonSyntaxException e) {
             logger.debug("JsonSyntaxException occurred during execution: {}", e.getLocalizedMessage(), e);
@@ -228,7 +262,11 @@ public class OpenWeatherMapOneCallHandler extends AbstractOpenWeatherMapHandler
                     updateMinutelyForecastChannel(channelUID, i - 1);
                     break;
                 }
-
+                Matcher alertsMatcher = CHANNEL_GROUP_ALERTS_PREFIX_PATTERN.matcher(channelGroupId);
+                if (alertsMatcher.find() && (i = Integer.parseInt(alertsMatcher.group(1))) >= 1) {
+                    updateAlertsChannel(channelUID, i);
+                    break;
+                }
                 break;
         }
     }
@@ -318,7 +356,6 @@ public class OpenWeatherMapOneCallHandler extends AbstractOpenWeatherMapHandler
                     state = getQuantityTypeState(snow == null ? 0 : snow.get1h(), MILLI(METRE));
                     break;
                 case CHANNEL_VISIBILITY:
-                    @Nullable
                     State tempstate = new QuantityType<>(localWeatherData.getCurrent().getVisibility(), METRE)
                             .toUnit(KILO(METRE));
                     state = (tempstate == null ? state : tempstate);
@@ -442,7 +479,6 @@ public class OpenWeatherMapOneCallHandler extends AbstractOpenWeatherMapHandler
                     state = getQuantityTypeState(forecastData.getClouds(), PERCENT);
                     break;
                 case CHANNEL_VISIBILITY:
-                    @Nullable
                     State tempstate = new QuantityType<>(localWeatherData.getCurrent().getVisibility(), METRE)
                             .toUnit(KILO(METRE));
                     state = (tempstate == null ? state : tempstate);
@@ -484,7 +520,6 @@ public class OpenWeatherMapOneCallHandler extends AbstractOpenWeatherMapHandler
                     channelGroupId);
             return;
         }
-        @Nullable
         OpenWeatherMapOneCallAPIData localWeatherData = weatherData;
         if (localWeatherData != null && localWeatherData.getDaily().size() > count) {
             org.openhab.binding.openweathermap.internal.dto.onecall.Daily forecastData = localWeatherData.getDaily()
@@ -609,7 +644,6 @@ public class OpenWeatherMapOneCallHandler extends AbstractOpenWeatherMapHandler
                     state = getDecimalTypeState(forecastData.getUvi());
                     break;
                 case CHANNEL_VISIBILITY:
-                    @Nullable
                     State tempstate = new QuantityType<>(localWeatherData.getCurrent().getVisibility(), METRE)
                             .toUnit(KILO(METRE));
                     state = (tempstate == null ? state : tempstate);
@@ -633,4 +667,42 @@ public class OpenWeatherMapOneCallHandler extends AbstractOpenWeatherMapHandler
             logger.debug("No weather data available to update channel '{}' of group '{}'.", channelId, channelGroupId);
         }
     }
+
+    /**
+     * Update the channel from the last OpenWeaterhMap data retrieved.
+     *
+     * @param channelUID the id identifying the channel to be updated
+     * @param count
+     */
+    private void updateAlertsChannel(ChannelUID channelUID, int count) {
+        String channelId = channelUID.getIdWithoutGroup();
+        String channelGroupId = channelUID.getGroupId();
+        OpenWeatherMapOneCallAPIData localWeatherData = weatherData;
+        List<Alert> alerts = localWeatherData != null ? localWeatherData.alerts : null;
+        State state = UnDefType.UNDEF;
+        if (alerts != null && alerts.size() > count) {
+            Alert alert = alerts.get(count - 1);
+            switch (channelId) {
+                case CHANNEL_ALERT_EVENT:
+                    state = getStringTypeState(alert.event);
+                    break;
+                case CHANNEL_ALERT_DESCRIPTION:
+                    state = getStringTypeState(alert.description);
+                    break;
+                case CHANNEL_ALERT_ONSET:
+                    state = getDateTimeTypeState(alert.start);
+                    break;
+                case CHANNEL_ALERT_EXPIRES:
+                    state = getDateTimeTypeState(alert.end);
+                    break;
+                case CHANNEL_ALERT_SOURCE:
+                    state = getStringTypeState(alert.senderName);
+                    break;
+            }
+            logger.debug("Update channel '{}' of group '{}' with new state '{}'.", channelId, channelGroupId, state);
+        } else {
+            logger.debug("No data available to update channel '{}' of group '{}'.", channelId, channelGroupId);
+        }
+        updateState(channelUID, state);
+    }
 }
index 002c9c0fa67fb1f1ec7b1e24672938c903860553..ff6d7024c843331271f9944c726e92145941de37 100644 (file)
                        <description>Number of minutes for minutely precipitation forecast.</description>
                        <default>0</default>
                </parameter>
+               <parameter name="numberOfAlerts" type="integer" min="0" max="5" step="1">
+                       <label>Number of Alerts</label>
+                       <description>Number of alerts to be shown.</description>
+                       <default>0</default>
+               </parameter>
        </config-description>
 
        <config-description uri="thing-type:openweathermap:onecall-history">
index 4c3d9f123fa7d29a08ae7ac0f8425fa14a1c5473..bb260043e59b6361a91c5e530cf82ba88e4c2c01 100644 (file)
@@ -13,6 +13,7 @@ offline.conf-error-not-supported-uvindex-number-of-days = The 'forecastDays' par
 offline.conf-error-not-supported-onecall-number-of-minutes = The 'forecastMinutes' parameter must be between 0 and 60.
 offline.conf-error-not-supported-onecall-number-of-hours = The 'forecastHours' parameter must be between 0 and 48.
 offline.conf-error-not-supported-onecall-number-of-days = The 'forecastDays' parameter must be between 0 and 7.
+offline.conf-error-not-supported-onecall-number-of-alerts = The 'numberOfAlerts' parameter must be greater than or equals to 0.
 
 # discovery result
 discovery.openweathermap.weather-and-forecast.api.local.label = Local Weather And Forecast
index 327534734d8619b0d8b775e9a581e2cd510a57b2..d00377ff118cf1f9811b4d30ac18653cdc83e62f 100644 (file)
@@ -94,6 +94,21 @@ thing-type.config.openweathermap.air-pollution.location.description = Ort der We
 thing-type.config.openweathermap.air-pollution.forecastHours.label = Stunden
 thing-type.config.openweathermap.air-pollution.forecastHours.description = Anzahl der Stunden für die Vorhersage der Luftqualität.
 
+thing-type.config.openweathermap.onecall.location.label = Ort der Wetterdaten
+thing-type.config.openweathermap.onecall.location.description = Ort der Wetterdaten in geographischen Koordinaten (Breitengrad/Längengrad/Höhe).
+
+thing-type.config.openweathermap.onecall.forecastMinutes.label = Minuten
+thing-type.config.openweathermap.onecall.forecastMinutes.description = Anzahl der Minuten für die Vorhersage von Niederschlag.
+
+thing-type.config.openweathermap.onecall.forecastHours.label = Stunden
+thing-type.config.openweathermap.onecall.forecastHours.description = Anzahl der Stunden für die Wettervorhersage.
+
+thing-type.config.openweathermap.onecall.forecastDays.label = Tage
+thing-type.config.openweathermap.onecall.forecastDays.description = Anzahl der Tage für die Wettervorhersage, inklusive aktueller Tag.
+
+thing-type.config.openweathermap.onecall.numberOfAlerts.label = Wetterwarnungen
+thing-type.config.openweathermap.onecall.numberOfAlerts.description = Anzahl der Wetterwarnungen.
+
 # channel group types
 channel-group-type.openweathermap.station.label = Wetterstation
 channel-group-type.openweathermap.station.description = Fasst Daten über die Wetterstation oder den Ort zusammen.
@@ -119,6 +134,12 @@ channel-group-type.openweathermap.airPollution.description = Fasst Daten 
 channel-group-type.openweathermap.airPollutionForecast.label = Vorhersage der Luftqualität
 channel-group-type.openweathermap.airPollutionForecast.description = Fasst Daten über die vorhergesagte Luftqualität zusammen.
 
+channel-group-type.openweathermap.oneCallCurrent.label = Aktuelles Wetter
+channel-group-type.openweathermap.oneCallCurrent.description = Fasst aktuelle Wetterdaten der One Call API zusammen.
+
+channel-group-type.openweathermap.oneCallAlerts.label = Wetterwarnungen
+channel-group-type.openweathermap.oneCallAlerts.description = Fasst Daten von Wetterwarnungen zusammen.
+
 # channel groups
 thing-type.openweathermap.weather-and-forecast.group.forecastHours03.label = Wettervorhersage für 3 Stunden
 thing-type.openweathermap.weather-and-forecast.group.forecastHours03.description = Fasst Daten der Wettervorhersage in den nächsten drei Stunden zusammen.
@@ -177,6 +198,24 @@ thing-type.openweathermap.uvindex.group.forecastDay4.description = Fasst Daten d
 thing-type.openweathermap.uvindex.group.forecastDay5.label = UV-Index für 5 Tage
 thing-type.openweathermap.uvindex.group.forecastDay5.description = Fasst Daten der UV-Index Vorhersage in fünf Tagen zusammen.
 
+thing-type.openweathermap.onecall.group.forecastToday.label = Wettervorhersage für heute
+thing-type.openweathermap.onecall.group.forecastToday.description = Fasst Daten der heutigen Wettervorhersage der One Call API zusammen.
+
+thing-type.openweathermap.onecall.group.forecastTomorrow.label = Wettervorhersage für morgen
+thing-type.openweathermap.onecall.group.forecastTomorrow.description = Fasst Daten der morgigen Wettervorhersage der One Call API zusammen.
+
+thing-type.openweathermap.onecall.group.forecastDay2.label = Wettervorhersage für übermorgen
+thing-type.openweathermap.onecall.group.forecastDay2.description = Fasst Daten der übermorgigen Wettervorhersage der One Call API zusammen.
+
+thing-type.openweathermap.onecall.group.forecastDay3.label = Wettervorhersage für 3 Tage
+thing-type.openweathermap.onecall.group.forecastDay3.description = Fasst Daten der Wettervorhersage in drei Tagen der One Call API zusammen.
+
+thing-type.openweathermap.onecall.group.forecastDay4.label = Wettervorhersage für 4 Tage
+thing-type.openweathermap.onecall.group.forecastDay4.description = Fasst Daten der Wettervorhersage in vier Tagen der One Call API zusammen.
+
+thing-type.openweathermap.onecall.group.forecastDay5.label = Wettervorhersage für 5 Tage
+thing-type.openweathermap.onecall.group.forecastDay5.description = Fasst Daten der Wettervorhersage in fünf Tagen der One Call API zusammen.
+
 # channel types
 channel-type.openweathermap.station-id.label = Station-ID
 channel-type.openweathermap.station-id.description = Zeigt die ID der Wetterstation oder des Ortes an.
@@ -349,6 +388,23 @@ channel-type.openweathermap.ammonia.description = Aktuelle Konzentration an Ammo
 channel-type.openweathermap.forecasted-ammonia.label = Vorhergesagter Ammoniak
 channel-type.openweathermap.forecasted-ammonia.description = Vorhergesagte Konzentration an Ammoniak.
 
+channel-type.openweathermap.alert-event.label = Art
+channel-type.openweathermap.alert-event.description = Art der Warnung, z.B. FROST.
+
+channel-type.openweathermap.alert-description.label = Beschreibung
+channel-type.openweathermap.alert-description.description = Zeigt die Beschreibung der Wetterwarnung an.
+
+channel-type.openweathermap.alert-onset.label = Gültig ab
+channel-type.openweathermap.alert-onset.description = Datum und Uhrzeit, ab dem die Warnung gültig ist.
+channel-type.openweathermap.alert-onset.state.pattern = %1$td.%1$tm.%1$tY %1$tH:%1$tM:%1$tS
+
+channel-type.openweathermap.alert-expires.label = Gültig bis
+channel-type.openweathermap.alert-expires.description = Datum und Uhrzeit, bis zu dem die Warnung gültig ist.
+channel-type.openweathermap.alert-expires.state.pattern = %1$td.%1$tm.%1$tY %1$tH:%1$tM:%1$tS
+
+channel-type.openweathermap.alert-source.label = Quelle
+channel-type.openweathermap.alert-source.description = Zeigt die Quelle der Wetterwarnung an.
+
 # thing status
 offline.conf-error-missing-apikey = Der Parameter 'API Schlüssel' muss konfiguriert werden.
 offline.conf-error-invalid-apikey = Ungültiger 'API Schlüssel'. Mehr Infos unter https://openweathermap.org/faq#error401.
index 9a7a4d39a6b83e97462078e3ddc0146151a3ad93..87a3d5cb037285310d5e794948d62d315e17de78 100644 (file)
                </channels>
        </channel-group-type>
 
+       <channel-group-type id="oneCallAlerts">
+               <label>Weather Warnings</label>
+               <description>Weather warnings issued for the requested location.</description>
+               <channels>
+                       <channel id="event" typeId="alert-event"/>
+                       <channel id="description" typeId="alert-description"/>
+                       <channel id="onset" typeId="alert-onset"/>
+                       <channel id="expires" typeId="alert-expires"/>
+                       <channel id="source" typeId="alert-source"/>
+               </channels>
+       </channel-group-type>
 
        <!-- Channels for OpenWeatherMap Binding -->
        <channel-type id="station-id">
                <category>Rain</category>
                <state readOnly="true" pattern="%.1f %unit%"/>
        </channel-type>
+
+       <channel-type id="alert-event">
+               <item-type>String</item-type>
+               <label>Type</label>
+               <description>Type of the warning, e.g. FROST.</description>
+               <state readOnly="true"/>
+       </channel-type>
+
+       <channel-type id="alert-description">
+               <item-type>String</item-type>
+               <label>Description</label>
+               <description>A detailed description of the alert.</description>
+               <state readOnly="true"/>
+       </channel-type>
+
+       <channel-type id="alert-onset">
+               <item-type>DateTime</item-type>
+               <label>Valid From</label>
+               <description>Start Date and Time for which the warning is valid.</description>
+               <category>Time</category>
+               <state readOnly="true" pattern="%1$tY-%1$tm-%1$td %1$tH:%1$tM:%1$tS"/>
+       </channel-type>
+
+       <channel-type id="alert-expires">
+               <item-type>DateTime</item-type>
+               <label>Valid To</label>
+               <description>End Date and Time for which the warning is valid.</description>
+               <category>Time</category>
+               <state readOnly="true" pattern="%1$tY-%1$tm-%1$td %1$tH:%1$tM:%1$tS"/>
+       </channel-type>
+
+       <channel-type id="alert-source" advanced="true">
+               <item-type>String</item-type>
+               <label>Source</label>
+               <description>Source of the alert.</description>
+               <state readOnly="true"/>
+       </channel-type>
 </thing:thing-descriptions>
index 2155ea55ba4082b8d551a5e228dcc808fbb12311..2fab59a36fc61a9c3054c5e18cf6db5b451faba6 100644 (file)
                        <channel-group id="forecastHours23" typeId="oneCallHourly"/>
                        <channel-group id="forecastHours24" typeId="oneCallHourly"/>
 
-
                        <channel-group id="forecastToday" typeId="oneCallDaily">
                                <label>One Call API Todays Forecast</label>
                                <description>This is the weather forecast for today from the one call API.</description>