[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:
Christoph Weitkamp 2021-04-09 22:59:25 +02:00 committed by GitHub
parent 950033ba2f
commit e0f5e858c7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 278 additions and 56 deletions

View 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 |

View 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";

View File

@ -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;
}

View 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) {

View File

@ -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;
}

View 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;

View 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);
}
}

View File

@ -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">

View 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

View 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.

View File

@ -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>

View File

@ -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>