[openweathermap] Added One Call API weather warnings (#10435)
* 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>
This commit is contained in:
parent
950033ba2f
commit
e0f5e858c7
@ -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 |
|
||||
|
||||
@ -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";
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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;
|
||||
}
|
||||
@ -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;
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -135,6 +135,11 @@
|
||||
<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">
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -290,6 +290,17 @@
|
||||
</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">
|
||||
@ -769,4 +780,41 @@
|
||||
<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>
|
||||
|
||||
@ -233,7 +233,6 @@
|
||||
<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>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user