diff --git a/bundles/org.openhab.binding.openweathermap/README.md b/bundles/org.openhab.binding.openweathermap/README.md index d63422b11..00e49e47b 100644 --- a/bundles/org.openhab.binding.openweathermap/README.md +++ b/bundles/org.openhab.binding.openweathermap/README.md @@ -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 | diff --git a/bundles/org.openhab.binding.openweathermap/src/main/java/org/openhab/binding/openweathermap/internal/OpenWeatherMapBindingConstants.java b/bundles/org.openhab.binding.openweathermap/src/main/java/org/openhab/binding/openweathermap/internal/OpenWeatherMapBindingConstants.java index 3a72a1908..eb5f57437 100644 --- a/bundles/org.openhab.binding.openweathermap/src/main/java/org/openhab/binding/openweathermap/internal/OpenWeatherMapBindingConstants.java +++ b/bundles/org.openhab.binding.openweathermap/src/main/java/org/openhab/binding/openweathermap/internal/OpenWeatherMapBindingConstants.java @@ -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"; diff --git a/bundles/org.openhab.binding.openweathermap/src/main/java/org/openhab/binding/openweathermap/internal/config/OpenWeatherMapOneCallConfiguration.java b/bundles/org.openhab.binding.openweathermap/src/main/java/org/openhab/binding/openweathermap/internal/config/OpenWeatherMapOneCallConfiguration.java index 4308cc688..7521d8128 100644 --- a/bundles/org.openhab.binding.openweathermap/src/main/java/org/openhab/binding/openweathermap/internal/config/OpenWeatherMapOneCallConfiguration.java +++ b/bundles/org.openhab.binding.openweathermap/src/main/java/org/openhab/binding/openweathermap/internal/config/OpenWeatherMapOneCallConfiguration.java @@ -13,16 +13,19 @@ 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; } diff --git a/bundles/org.openhab.binding.openweathermap/src/main/java/org/openhab/binding/openweathermap/internal/connection/OpenWeatherMapConnection.java b/bundles/org.openhab.binding.openweathermap/src/main/java/org/openhab/binding/openweathermap/internal/connection/OpenWeatherMapConnection.java index db25ed9fa..f4310e60e 100644 --- a/bundles/org.openhab.binding.openweathermap/src/main/java/org/openhab/binding/openweathermap/internal/connection/OpenWeatherMapConnection.java +++ b/bundles/org.openhab.binding.openweathermap/src/main/java/org/openhab/binding/openweathermap/internal/connection/OpenWeatherMapConnection.java @@ -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 params = getRequestParams(handler.getOpenWeatherMapAPIConfig(), location); - StringBuilder exclude = new StringBuilder(""); + List 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 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 index 000000000..29ede4ce3 --- /dev/null +++ b/bundles/org.openhab.binding.openweathermap/src/main/java/org/openhab/binding/openweathermap/internal/dto/onecall/Alert.java @@ -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; +} diff --git a/bundles/org.openhab.binding.openweathermap/src/main/java/org/openhab/binding/openweathermap/internal/dto/onecall/OpenWeatherMapOneCallAPIData.java b/bundles/org.openhab.binding.openweathermap/src/main/java/org/openhab/binding/openweathermap/internal/dto/onecall/OpenWeatherMapOneCallAPIData.java index 160c9825e..be79e1bda 100644 --- a/bundles/org.openhab.binding.openweathermap/src/main/java/org/openhab/binding/openweathermap/internal/dto/onecall/OpenWeatherMapOneCallAPIData.java +++ b/bundles/org.openhab.binding.openweathermap/src/main/java/org/openhab/binding/openweathermap/internal/dto/onecall/OpenWeatherMapOneCallAPIData.java @@ -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 = null; - @SerializedName("hourly") - @Expose - private List hourly = null; - @SerializedName("daily") - @Expose - private List daily = null; + private List minutely; + private List hourly; + private List daily; + + public @Nullable List alerts; public double getLat() { return lat; diff --git a/bundles/org.openhab.binding.openweathermap/src/main/java/org/openhab/binding/openweathermap/internal/handler/OpenWeatherMapOneCallHandler.java b/bundles/org.openhab.binding.openweathermap/src/main/java/org/openhab/binding/openweathermap/internal/handler/OpenWeatherMapOneCallHandler.java index 52ba04d6d..9cd2d0308 100644 --- a/bundles/org.openhab.binding.openweathermap/src/main/java/org/openhab/binding/openweathermap/internal/handler/OpenWeatherMapOneCallHandler.java +++ b/bundles/org.openhab.binding.openweathermap/src/main/java/org/openhab/binding/openweathermap/internal/handler/OpenWeatherMapOneCallHandler.java @@ -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 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 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); + } } diff --git a/bundles/org.openhab.binding.openweathermap/src/main/resources/OH-INF/config/config.xml b/bundles/org.openhab.binding.openweathermap/src/main/resources/OH-INF/config/config.xml index 002c9c0fa..ff6d7024c 100644 --- a/bundles/org.openhab.binding.openweathermap/src/main/resources/OH-INF/config/config.xml +++ b/bundles/org.openhab.binding.openweathermap/src/main/resources/OH-INF/config/config.xml @@ -135,6 +135,11 @@ Number of minutes for minutely precipitation forecast. 0 + + + Number of alerts to be shown. + 0 + diff --git a/bundles/org.openhab.binding.openweathermap/src/main/resources/OH-INF/i18n/openweathermap.properties b/bundles/org.openhab.binding.openweathermap/src/main/resources/OH-INF/i18n/openweathermap.properties index 4c3d9f123..bb260043e 100644 --- a/bundles/org.openhab.binding.openweathermap/src/main/resources/OH-INF/i18n/openweathermap.properties +++ b/bundles/org.openhab.binding.openweathermap/src/main/resources/OH-INF/i18n/openweathermap.properties @@ -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 diff --git a/bundles/org.openhab.binding.openweathermap/src/main/resources/OH-INF/i18n/openweathermap_de.properties b/bundles/org.openhab.binding.openweathermap/src/main/resources/OH-INF/i18n/openweathermap_de.properties index 327534734..d00377ff1 100644 --- a/bundles/org.openhab.binding.openweathermap/src/main/resources/OH-INF/i18n/openweathermap_de.properties +++ b/bundles/org.openhab.binding.openweathermap/src/main/resources/OH-INF/i18n/openweathermap_de.properties @@ -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. diff --git a/bundles/org.openhab.binding.openweathermap/src/main/resources/OH-INF/thing/channel-types.xml b/bundles/org.openhab.binding.openweathermap/src/main/resources/OH-INF/thing/channel-types.xml index 9a7a4d39a..87a3d5cb0 100644 --- a/bundles/org.openhab.binding.openweathermap/src/main/resources/OH-INF/thing/channel-types.xml +++ b/bundles/org.openhab.binding.openweathermap/src/main/resources/OH-INF/thing/channel-types.xml @@ -290,6 +290,17 @@ + + + Weather warnings issued for the requested location. + + + + + + + + @@ -769,4 +780,41 @@ Rain + + + String + + Type of the warning, e.g. FROST. + + + + + String + + A detailed description of the alert. + + + + + DateTime + + Start Date and Time for which the warning is valid. + Time + + + + + DateTime + + End Date and Time for which the warning is valid. + Time + + + + + String + + Source of the alert. + + diff --git a/bundles/org.openhab.binding.openweathermap/src/main/resources/OH-INF/thing/thing-types.xml b/bundles/org.openhab.binding.openweathermap/src/main/resources/OH-INF/thing/thing-types.xml index 2155ea55b..2fab59a36 100644 --- a/bundles/org.openhab.binding.openweathermap/src/main/resources/OH-INF/thing/thing-types.xml +++ b/bundles/org.openhab.binding.openweathermap/src/main/resources/OH-INF/thing/thing-types.xml @@ -233,7 +233,6 @@ - This is the weather forecast for today from the one call API.