From 9abf0a6440d8019c59fb7e56cc39fefd4eb1c8e3 Mon Sep 17 00:00:00 2001 From: Florian Hotze Date: Sun, 26 Nov 2023 15:42:24 +0100 Subject: [PATCH 01/13] [openweathermap] Add support for persisting OneCall API forecasts Implement time series support introduced by https://github.com/openhab/openhab-core/pull/3597. Signed-off-by: Florian Hotze --- .../handler/OpenWeatherMapOneCallHandler.java | 565 +++++++++++------- .../resources/OH-INF/thing/channel-types.xml | 56 ++ .../resources/OH-INF/thing/thing-types.xml | 7 + 3 files changed, 416 insertions(+), 212 deletions(-) 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 6049aaf71ec53..db36c8bb68dad 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 @@ -16,7 +16,9 @@ import static org.openhab.core.library.unit.MetricPrefix.*; import static org.openhab.core.library.unit.SIUnits.*; import static org.openhab.core.library.unit.Units.*; +import static org.openhab.core.types.TimeSeries.Policy.REPLACE; +import java.time.Instant; import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; @@ -30,6 +32,8 @@ import org.openhab.binding.openweathermap.internal.dto.forecast.daily.FeelsLikeTemp; import org.openhab.binding.openweathermap.internal.dto.forecast.daily.Temp; import org.openhab.binding.openweathermap.internal.dto.onecall.Alert; +import org.openhab.binding.openweathermap.internal.dto.onecall.Daily; +import org.openhab.binding.openweathermap.internal.dto.onecall.Hourly; import org.openhab.binding.openweathermap.internal.dto.onecall.Precipitation; import org.openhab.core.i18n.CommunicationException; import org.openhab.core.i18n.ConfigurationException; @@ -42,6 +46,7 @@ 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.TimeSeries; import org.openhab.core.types.UnDefType; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -54,6 +59,7 @@ * * @author Wolfgang Klimt - Initial contribution * @author Christoph Weitkamp - Added weather alerts + * @author Florian Hotze - Added support for persisting forecasts */ @NonNullByDefault public class OpenWeatherMapOneCallHandler extends AbstractOpenWeatherMapHandler { @@ -61,8 +67,11 @@ public class OpenWeatherMapOneCallHandler extends AbstractOpenWeatherMapHandler private final Logger logger = LoggerFactory.getLogger(OpenWeatherMapOneCallHandler.class); private static final String CHANNEL_GROUP_MINUTELY_FORECAST_PREFIX = "forecastMinutes"; + private static final String CHANNEL_GROUP_MINUTELY_TIMESERIES_PREFIX = "forecastMinutely"; private static final String CHANNEL_GROUP_HOURLY_FORECAST_PREFIX = "forecastHours"; + private static final String CHANNEL_GROUP_HOURLY_TIMESERIES_PREFIX = "forecastHourly"; private static final String CHANNEL_GROUP_DAILY_FORECAST_PREFIX = "forecastDay"; + private static final String CHANNEL_GROUP_DAILY_TIMESERIES_PREFIX = "forecastDaily"; 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]*)"); @@ -240,6 +249,15 @@ protected void updateChannel(ChannelUID channelUID) { case CHANNEL_GROUP_ONECALL_TOMORROW: updateDailyForecastChannel(channelUID, 1); break; + case CHANNEL_GROUP_MINUTELY_TIMESERIES_PREFIX: + updateMinutelyForecastTimeSeries(channelUID); + break; + case CHANNEL_GROUP_HOURLY_TIMESERIES_PREFIX: + updateHourlyForecastTimeSeries(channelUID); + break; + case CHANNEL_GROUP_DAILY_TIMESERIES_PREFIX: + updateDailyForecastTimeSeries(channelUID); + break; default: int i; Matcher hourlyForecastMatcher = CHANNEL_GROUP_HOURLY_FORECAST_PREFIX_PATTERN.matcher(channelGroupId); @@ -412,8 +430,47 @@ private void updateMinutelyForecastChannel(ChannelUID channelUID, int count) { } } + private void updateMinutelyForecastTimeSeries(ChannelUID channelUID) { + String channelId = channelUID.getIdWithoutGroup(); + String channelGroupId = channelUID.getGroupId(); + OpenWeatherMapOneCallAPIData localWeatherData = weatherData; + if (forecastMinutes == 0) { + logger.warn( + "Can't update channel group {} because forecastMinutes is set to '0'. Please adjust config accordingly", + channelGroupId); + return; + } + if (channelId.equals(CHANNEL_TIME_STAMP)) { + logger.debug("Channel `{}` of group '{}' is no supported time-series channel.", channelId, channelGroupId); + return; + } + if (localWeatherData != null && !localWeatherData.getMinutely().isEmpty()) { + List forecastData = localWeatherData + .getMinutely(); + TimeSeries timeSeries = new TimeSeries(REPLACE); + forecastData.forEach((m) -> { + if (channelId.equals(CHANNEL_PRECIPITATION)) { + State state = UnDefType.UNDEF; + Instant timestamp = Instant.ofEpochSecond(m.getDt()); + double precipitation = m.getPrecipitation(); + state = getQuantityTypeState(precipitation, MILLI(METRE)); + timeSeries.add(timestamp, state); + } else { + // This should not happen + logger.warn("Unknown channel id {} in onecall minutely weather data", channelId); + return; + } + }); + logger.debug("Update channel '{}' of group '{}' with new time-series '{}'.", channelId, channelGroupId, + timeSeries); + sendTimeSeries(channelUID, timeSeries); + } else { + logger.debug("No weather data available to update channel '{}' of group '{}'.", channelId, channelGroupId); + } + } + /** - * Update the channel from the last OpenWeatherMap data retrieved. + * Update the hourly forecast channel from the last OpenWeatherMap data retrieved. * * @param channelUID the id identifying the channel to be updated * @param count the index of the hourly data referenced by the channel (hour 1 is count 0) @@ -431,79 +488,7 @@ private void updateHourlyForecastChannel(ChannelUID channelUID, int count) { if (localWeatherData != null && localWeatherData.getHourly().size() > count) { org.openhab.binding.openweathermap.internal.dto.onecall.Hourly forecastData = localWeatherData.getHourly() .get(count); - State state = UnDefType.UNDEF; - switch (channelId) { - case CHANNEL_TIME_STAMP: - state = getDateTimeTypeState(forecastData.getDt()); - break; - case CHANNEL_CONDITION: - if (!forecastData.getWeather().isEmpty()) { - state = getStringTypeState(forecastData.getWeather().get(0).getDescription()); - } - break; - case CHANNEL_CONDITION_ID: - if (!forecastData.getWeather().isEmpty()) { - state = getStringTypeState(Integer.toString(forecastData.getWeather().get(0).getId())); - } - break; - case CHANNEL_CONDITION_ICON: - if (!forecastData.getWeather().isEmpty()) { - state = getRawTypeState( - OpenWeatherMapConnection.getWeatherIcon(forecastData.getWeather().get(0).getIcon())); - } - break; - case CHANNEL_CONDITION_ICON_ID: - if (!forecastData.getWeather().isEmpty()) { - state = getStringTypeState(forecastData.getWeather().get(0).getIcon()); - } - break; - case CHANNEL_TEMPERATURE: - state = getQuantityTypeState(forecastData.getTemp(), CELSIUS); - break; - case CHANNEL_APPARENT_TEMPERATURE: - state = getQuantityTypeState(forecastData.getFeelsLike(), CELSIUS); - break; - case CHANNEL_PRESSURE: - state = getQuantityTypeState(forecastData.getPressure(), HECTO(PASCAL)); - break; - case CHANNEL_HUMIDITY: - state = getQuantityTypeState(forecastData.getHumidity(), PERCENT); - break; - case CHANNEL_DEW_POINT: - state = getQuantityTypeState(forecastData.getDewPoint(), CELSIUS); - break; - case CHANNEL_WIND_SPEED: - state = getQuantityTypeState(forecastData.getWindSpeed(), METRE_PER_SECOND); - break; - case CHANNEL_WIND_DIRECTION: - state = getQuantityTypeState(forecastData.getWindDeg(), DEGREE_ANGLE); - break; - case CHANNEL_GUST_SPEED: - state = getQuantityTypeState(forecastData.getWindGust(), METRE_PER_SECOND); - break; - case CHANNEL_CLOUDINESS: - state = getQuantityTypeState(forecastData.getClouds(), PERCENT); - break; - case CHANNEL_VISIBILITY: - State tempstate = new QuantityType<>(localWeatherData.getCurrent().getVisibility(), METRE) - .toUnit(KILO(METRE)); - state = (tempstate == null ? state : tempstate); - case CHANNEL_PRECIP_PROBABILITY: - state = getQuantityTypeState(forecastData.getPop() * 100.0, PERCENT); - break; - case CHANNEL_RAIN: - Precipitation rain = forecastData.getRain(); - state = getQuantityTypeState(rain == null ? 0 : rain.get1h(), MILLI(METRE)); - break; - case CHANNEL_SNOW: - Precipitation snow = forecastData.getSnow(); - state = getQuantityTypeState(snow == null ? 0 : snow.get1h(), MILLI(METRE)); - break; - default: - // This should not happen - logger.warn("Unknown channel id {} in onecall hourly weather data", channelId); - break; - } + State state = getHourlyForecastState(channelId, forecastData, localWeatherData); logger.debug("Update channel '{}' of group '{}' with new state '{}'.", channelId, channelGroupId, state); updateState(channelUID, state); } else { @@ -512,7 +497,123 @@ private void updateHourlyForecastChannel(ChannelUID channelUID, int count) { } /** - * Update the channel from the last OpenWeatherMap data retrieved. + * Update the hourly forecast time series channel from the last OpenWeatherMap data retrieved. + * + * @param channelUID the id identifying the channel to be updated + */ + private void updateHourlyForecastTimeSeries(ChannelUID channelUID) { + String channelId = channelUID.getIdWithoutGroup(); + String channelGroupId = channelUID.getGroupId(); + if (forecastHours == 0) { + logger.warn( + "Can't update channel group {} because forecastHours is set to '0'. Please adjust config accordingly", + channelGroupId); + return; + } + if (channelId.equals(CHANNEL_TIME_STAMP) || channelId.equals(CHANNEL_CONDITION) + || channelId.equals(CHANNEL_CONDITION_ID) || channelId.equals(CHANNEL_CONDITION_ICON) + || channelId.equals(CHANNEL_CONDITION_ICON_ID)) { + logger.debug("Channel `{}` of group '{}' is no supported time-series channel.", channelId, channelGroupId); + return; + } + OpenWeatherMapOneCallAPIData localWeatherData = weatherData; + if (localWeatherData != null && !localWeatherData.getHourly().isEmpty()) { + List forecastData = localWeatherData + .getHourly(); + TimeSeries timeSeries = new TimeSeries(REPLACE); + forecastData.forEach((h) -> { + Instant timestamp = Instant.ofEpochSecond(h.getDt()); + State state = getHourlyForecastState(channelId, h, localWeatherData); + timeSeries.add(timestamp, state); + }); + logger.debug("Update channel '{}' of group '{}' with new time-series '{}'.", channelId, channelGroupId, + timeSeries); + sendTimeSeries(channelUID, timeSeries); + } else { + logger.debug("No weather data available to update channel '{}'.", channelId); + } + } + + private State getHourlyForecastState(String channelId, Hourly forecastData, + OpenWeatherMapOneCallAPIData localWeatherData) { + State state = UnDefType.UNDEF; + switch (channelId) { + case CHANNEL_TIME_STAMP: + state = getDateTimeTypeState(forecastData.getDt()); + break; + case CHANNEL_CONDITION: + if (!forecastData.getWeather().isEmpty()) { + state = getStringTypeState(forecastData.getWeather().get(0).getDescription()); + } + break; + case CHANNEL_CONDITION_ID: + if (!forecastData.getWeather().isEmpty()) { + state = getStringTypeState(Integer.toString(forecastData.getWeather().get(0).getId())); + } + break; + case CHANNEL_CONDITION_ICON: + if (!forecastData.getWeather().isEmpty()) { + state = getRawTypeState( + OpenWeatherMapConnection.getWeatherIcon(forecastData.getWeather().get(0).getIcon())); + } + break; + case CHANNEL_CONDITION_ICON_ID: + if (!forecastData.getWeather().isEmpty()) { + state = getStringTypeState(forecastData.getWeather().get(0).getIcon()); + } + break; + case CHANNEL_TEMPERATURE: + state = getQuantityTypeState(forecastData.getTemp(), CELSIUS); + break; + case CHANNEL_APPARENT_TEMPERATURE: + state = getQuantityTypeState(forecastData.getFeelsLike(), CELSIUS); + break; + case CHANNEL_PRESSURE: + state = getQuantityTypeState(forecastData.getPressure(), HECTO(PASCAL)); + break; + case CHANNEL_HUMIDITY: + state = getQuantityTypeState(forecastData.getHumidity(), PERCENT); + break; + case CHANNEL_DEW_POINT: + state = getQuantityTypeState(forecastData.getDewPoint(), CELSIUS); + break; + case CHANNEL_WIND_SPEED: + state = getQuantityTypeState(forecastData.getWindSpeed(), METRE_PER_SECOND); + break; + case CHANNEL_WIND_DIRECTION: + state = getQuantityTypeState(forecastData.getWindDeg(), DEGREE_ANGLE); + break; + case CHANNEL_GUST_SPEED: + state = getQuantityTypeState(forecastData.getWindGust(), METRE_PER_SECOND); + break; + case CHANNEL_CLOUDINESS: + state = getQuantityTypeState(forecastData.getClouds(), PERCENT); + break; + case CHANNEL_VISIBILITY: + State tempstate = new QuantityType<>(localWeatherData.getCurrent().getVisibility(), METRE) + .toUnit(KILO(METRE)); + state = (tempstate == null ? state : tempstate); + case CHANNEL_PRECIP_PROBABILITY: + state = getQuantityTypeState(forecastData.getPop() * 100.0, PERCENT); + break; + case CHANNEL_RAIN: + Precipitation rain = forecastData.getRain(); + state = getQuantityTypeState(rain == null ? 0 : rain.get1h(), MILLI(METRE)); + break; + case CHANNEL_SNOW: + Precipitation snow = forecastData.getSnow(); + state = getQuantityTypeState(snow == null ? 0 : snow.get1h(), MILLI(METRE)); + break; + default: + // This should not happen + logger.warn("Unknown channel id {} in OneCall hourly weather data", channelId); + break; + } + return state; + } + + /** + * Update the daily forecast channel from the last OpenWeatherMap data retrieved. * * @param channelUID the id identifying the channel to be updated * @param count the index of the daily data referenced by the channel (today is count 0) @@ -530,143 +631,7 @@ private void updateDailyForecastChannel(ChannelUID channelUID, int count) { if (localWeatherData != null && localWeatherData.getDaily().size() > count) { org.openhab.binding.openweathermap.internal.dto.onecall.Daily forecastData = localWeatherData.getDaily() .get(count); - State state = UnDefType.UNDEF; - Temp temp; - FeelsLikeTemp feelsLike; - switch (channelId) { - case CHANNEL_TIME_STAMP: - state = getDateTimeTypeState(forecastData.getDt()); - break; - case CHANNEL_SUNRISE: - state = getDateTimeTypeState(forecastData.getSunrise()); - break; - case CHANNEL_SUNSET: - state = getDateTimeTypeState(forecastData.getSunset()); - break; - case CHANNEL_CONDITION: - if (!forecastData.getWeather().isEmpty()) { - state = getStringTypeState(forecastData.getWeather().get(0).getDescription()); - } - break; - case CHANNEL_CONDITION_ID: - if (!forecastData.getWeather().isEmpty()) { - state = getStringTypeState(Integer.toString(forecastData.getWeather().get(0).getId())); - } - break; - case CHANNEL_CONDITION_ICON: - if (!forecastData.getWeather().isEmpty()) { - state = getRawTypeState( - OpenWeatherMapConnection.getWeatherIcon(forecastData.getWeather().get(0).getIcon())); - } - break; - case CHANNEL_CONDITION_ICON_ID: - if (!forecastData.getWeather().isEmpty()) { - state = getStringTypeState(forecastData.getWeather().get(0).getIcon()); - } - break; - case CHANNEL_MIN_TEMPERATURE: - temp = forecastData.getTemp(); - if (temp != null) { - state = getQuantityTypeState(temp.getMin(), CELSIUS); - } - break; - case CHANNEL_MAX_TEMPERATURE: - temp = forecastData.getTemp(); - if (temp != null) { - state = getQuantityTypeState(temp.getMax(), CELSIUS); - } - break; - case CHANNEL_MORNING_TEMPERATURE: - temp = forecastData.getTemp(); - if (temp != null) { - state = getQuantityTypeState(temp.getMorn(), CELSIUS); - } - break; - case CHANNEL_DAY_TEMPERATURE: - temp = forecastData.getTemp(); - if (temp != null) { - state = getQuantityTypeState(temp.getDay(), CELSIUS); - } - break; - case CHANNEL_EVENING_TEMPERATURE: - temp = forecastData.getTemp(); - if (temp != null) { - state = getQuantityTypeState(temp.getEve(), CELSIUS); - } - break; - case CHANNEL_NIGHT_TEMPERATURE: - temp = forecastData.getTemp(); - if (temp != null) { - state = getQuantityTypeState(temp.getNight(), CELSIUS); - } - break; - - case CHANNEL_APPARENT_DAY: - feelsLike = forecastData.getFeelsLike(); - if (feelsLike != null) { - state = getQuantityTypeState(feelsLike.getDay(), CELSIUS); - } - break; - case CHANNEL_APPARENT_MORNING: - feelsLike = forecastData.getFeelsLike(); - if (feelsLike != null) { - state = getQuantityTypeState(feelsLike.getMorn(), CELSIUS); - } - break; - case CHANNEL_APPARENT_EVENING: - feelsLike = forecastData.getFeelsLike(); - if (feelsLike != null) { - state = getQuantityTypeState(feelsLike.getEve(), CELSIUS); - } - break; - case CHANNEL_APPARENT_NIGHT: - feelsLike = forecastData.getFeelsLike(); - if (feelsLike != null) { - state = getQuantityTypeState(feelsLike.getNight(), CELSIUS); - } - break; - case CHANNEL_PRESSURE: - state = getQuantityTypeState(forecastData.getPressure(), HECTO(PASCAL)); - break; - case CHANNEL_HUMIDITY: - state = getQuantityTypeState(forecastData.getHumidity(), PERCENT); - break; - case CHANNEL_WIND_SPEED: - state = getQuantityTypeState(forecastData.getWindSpeed(), METRE_PER_SECOND); - break; - case CHANNEL_WIND_DIRECTION: - state = getQuantityTypeState(forecastData.getWindDeg(), DEGREE_ANGLE); - break; - case CHANNEL_GUST_SPEED: - state = getQuantityTypeState(forecastData.getWindGust(), METRE_PER_SECOND); - break; - case CHANNEL_CLOUDINESS: - state = getQuantityTypeState(forecastData.getClouds(), PERCENT); - break; - case CHANNEL_DEW_POINT: - state = getQuantityTypeState(forecastData.getDewPoint(), CELSIUS); - break; - case CHANNEL_UVINDEX: - state = getDecimalTypeState(forecastData.getUvi()); - break; - case CHANNEL_VISIBILITY: - State tempstate = new QuantityType<>(localWeatherData.getCurrent().getVisibility(), METRE) - .toUnit(KILO(METRE)); - state = (tempstate == null ? state : tempstate); - case CHANNEL_PRECIP_PROBABILITY: - state = getQuantityTypeState(forecastData.getPop() * 100.0, PERCENT); - break; - case CHANNEL_RAIN: - state = getQuantityTypeState(forecastData.getRain(), MILLI(METRE)); - break; - case CHANNEL_SNOW: - state = getQuantityTypeState(forecastData.getSnow(), MILLI(METRE)); - break; - default: - // This should not happen - logger.warn("Unknown channel id {} in onecall daily weather data", channelId); - break; - } + State state = getDailyForecastState(channelId, forecastData, localWeatherData); logger.debug("Update channel '{}' of group '{}' with new state '{}'.", channelId, channelGroupId, state); updateState(channelUID, state); } else { @@ -674,6 +639,182 @@ private void updateDailyForecastChannel(ChannelUID channelUID, int count) { } } + private void updateDailyForecastTimeSeries(ChannelUID channelUID) { + String channelId = channelUID.getIdWithoutGroup(); + String channelGroupId = channelUID.getGroupId(); + if (forecastDays == 0) { + logger.warn( + "Can't update channel group {} because forecastDays is set to '0'. Please adjust config accordingly", + channelGroupId); + return; + } + if (channelId.equals(CHANNEL_TIME_STAMP) || channelId.equals(CHANNEL_SUNRISE) + || channelId.equals(CHANNEL_SUNSET) || channelId.equals(CHANNEL_CONDITION) + || channelId.equals(CHANNEL_CONDITION_ID) || channelId.equals(CHANNEL_CONDITION_ICON) + || channelId.equals(CHANNEL_CONDITION_ICON_ID)) { + logger.debug("Channel `{}` of group '{}' is no supported time-series channel.", channelId, channelGroupId); + return; + } + OpenWeatherMapOneCallAPIData localWeatherData = weatherData; + if (localWeatherData != null && !localWeatherData.getDaily().isEmpty()) { + List forecastData = localWeatherData + .getDaily(); + TimeSeries timeSeries = new TimeSeries(REPLACE); + forecastData.forEach((d) -> { + Instant timestamp = Instant.ofEpochSecond(d.getDt()); + State state = getDailyForecastState(channelId, d, localWeatherData); + timeSeries.add(timestamp, state); + }); + logger.debug("Update channel '{}' of group '{}' with new time-series '{}'.", channelId, channelGroupId, + timeSeries); + sendTimeSeries(channelUID, timeSeries); + } else { + logger.debug("No weather data available to update channel '{}'.", channelId); + } + } + + private State getDailyForecastState(String channelId, Daily forecastData, + OpenWeatherMapOneCallAPIData localWeatherData) { + State state = UnDefType.UNDEF; + FeelsLikeTemp feelsLike; + Temp temp; + switch (channelId) { + case CHANNEL_TIME_STAMP: + state = getDateTimeTypeState(forecastData.getDt()); + break; + case CHANNEL_SUNRISE: + state = getDateTimeTypeState(forecastData.getSunrise()); + break; + case CHANNEL_SUNSET: + state = getDateTimeTypeState(forecastData.getSunset()); + break; + case CHANNEL_CONDITION: + if (!forecastData.getWeather().isEmpty()) { + state = getStringTypeState(forecastData.getWeather().get(0).getDescription()); + } + break; + case CHANNEL_CONDITION_ID: + if (!forecastData.getWeather().isEmpty()) { + state = getStringTypeState(Integer.toString(forecastData.getWeather().get(0).getId())); + } + break; + case CHANNEL_CONDITION_ICON: + if (!forecastData.getWeather().isEmpty()) { + state = getRawTypeState( + OpenWeatherMapConnection.getWeatherIcon(forecastData.getWeather().get(0).getIcon())); + } + break; + case CHANNEL_CONDITION_ICON_ID: + if (!forecastData.getWeather().isEmpty()) { + state = getStringTypeState(forecastData.getWeather().get(0).getIcon()); + } + break; + case CHANNEL_MIN_TEMPERATURE: + temp = forecastData.getTemp(); + if (temp != null) { + state = getQuantityTypeState(temp.getMin(), CELSIUS); + } + break; + case CHANNEL_MAX_TEMPERATURE: + temp = forecastData.getTemp(); + if (temp != null) { + state = getQuantityTypeState(temp.getMax(), CELSIUS); + } + break; + case CHANNEL_MORNING_TEMPERATURE: + temp = forecastData.getTemp(); + if (temp != null) { + state = getQuantityTypeState(temp.getMorn(), CELSIUS); + } + break; + case CHANNEL_DAY_TEMPERATURE: + temp = forecastData.getTemp(); + if (temp != null) { + state = getQuantityTypeState(temp.getDay(), CELSIUS); + } + break; + case CHANNEL_EVENING_TEMPERATURE: + temp = forecastData.getTemp(); + if (temp != null) { + state = getQuantityTypeState(temp.getEve(), CELSIUS); + } + break; + case CHANNEL_NIGHT_TEMPERATURE: + temp = forecastData.getTemp(); + if (temp != null) { + state = getQuantityTypeState(temp.getNight(), CELSIUS); + } + break; + + case CHANNEL_APPARENT_DAY: + feelsLike = forecastData.getFeelsLike(); + if (feelsLike != null) { + state = getQuantityTypeState(feelsLike.getDay(), CELSIUS); + } + break; + case CHANNEL_APPARENT_MORNING: + feelsLike = forecastData.getFeelsLike(); + if (feelsLike != null) { + state = getQuantityTypeState(feelsLike.getMorn(), CELSIUS); + } + break; + case CHANNEL_APPARENT_EVENING: + feelsLike = forecastData.getFeelsLike(); + if (feelsLike != null) { + state = getQuantityTypeState(feelsLike.getEve(), CELSIUS); + } + break; + case CHANNEL_APPARENT_NIGHT: + feelsLike = forecastData.getFeelsLike(); + if (feelsLike != null) { + state = getQuantityTypeState(feelsLike.getNight(), CELSIUS); + } + break; + case CHANNEL_PRESSURE: + state = getQuantityTypeState(forecastData.getPressure(), HECTO(PASCAL)); + break; + case CHANNEL_HUMIDITY: + state = getQuantityTypeState(forecastData.getHumidity(), PERCENT); + break; + case CHANNEL_WIND_SPEED: + state = getQuantityTypeState(forecastData.getWindSpeed(), METRE_PER_SECOND); + break; + case CHANNEL_WIND_DIRECTION: + state = getQuantityTypeState(forecastData.getWindDeg(), DEGREE_ANGLE); + break; + case CHANNEL_GUST_SPEED: + state = getQuantityTypeState(forecastData.getWindGust(), METRE_PER_SECOND); + break; + case CHANNEL_CLOUDINESS: + state = getQuantityTypeState(forecastData.getClouds(), PERCENT); + break; + case CHANNEL_DEW_POINT: + state = getQuantityTypeState(forecastData.getDewPoint(), CELSIUS); + break; + case CHANNEL_UVINDEX: + state = getDecimalTypeState(forecastData.getUvi()); + break; + case CHANNEL_VISIBILITY: + State tempstate = new QuantityType<>(localWeatherData.getCurrent().getVisibility(), METRE) + .toUnit(KILO(METRE)); + state = (tempstate == null ? state : tempstate); + case CHANNEL_PRECIP_PROBABILITY: + state = getQuantityTypeState(forecastData.getPop() * 100.0, PERCENT); + break; + case CHANNEL_RAIN: + state = getQuantityTypeState(forecastData.getRain(), MILLI(METRE)); + break; + case CHANNEL_SNOW: + state = getQuantityTypeState(forecastData.getSnow(), MILLI(METRE)); + break; + default: + // This should not happen + logger.warn("Unknown channel id {} in OneCall daily weather data", channelId); + break; + } + return state; + } + /** * Update the channel from the last OpenWeaterhMap data retrieved. * 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 fc11c45e22dbc..0e790a8e1acc0 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 @@ -169,6 +169,14 @@ + + + Minutely precipitation delivered by the One Call API. + + + + + Minutely precipitation delivered by the One Call API. @@ -178,6 +186,26 @@ + + + Hourly weather forecast delivered by the One Call API. + + + + + + + + + + + + + + + + + Hourly weather forecast delivered by the One Call API. @@ -203,6 +231,34 @@ + + + Daily weather forecast delivered by the One Call API. + + + + + + + + + + + + + + + + + + + + + + + + + Daily weather forecast delivered by the One Call API. 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 2fab59a36fc61..18ab4f9eefd4f 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 @@ -142,6 +142,9 @@ + + + @@ -208,6 +211,8 @@ + + @@ -233,6 +238,8 @@ + + This is the weather forecast for today from the one call API. From 2e020afd0ead6d23623b008c9edf78293b8a0b1a Mon Sep 17 00:00:00 2001 From: Florian Hotze Date: Sun, 26 Nov 2023 16:30:27 +0100 Subject: [PATCH 02/13] [openweathermap] Update docs Signed-off-by: Florian Hotze --- .../README.md | 95 +++++++++++-------- 1 file changed, 58 insertions(+), 37 deletions(-) diff --git a/bundles/org.openhab.binding.openweathermap/README.md b/bundles/org.openhab.binding.openweathermap/README.md index 1543fbeb45d44..a66f13bbc6eec 100644 --- a/bundles/org.openhab.binding.openweathermap/README.md +++ b/bundles/org.openhab.binding.openweathermap/README.md @@ -50,6 +50,7 @@ New Subscribers to the One Call API will require setting the API version to 3.0 The thing `onecall` supports the [current and forecast weather data](https://openweathermap.org/api/one-call-api#how) for a specific location using the One Call API. It requires coordinates of the location of your interest. You can add as many `onecall` things for different locations to your setup as you like to observe. +It also supports persisting forecast data using time series support, please read [Persisting Time Series](#persisting-time-series). ### One Call API History Data @@ -128,7 +129,7 @@ Once the parameter `forecastHours` will be changed, the available channel groups | station | name | String | Name of the weather station or the city. | | station | location | Location | Location of the weather station or the city. | -These channels are not supported in the One Call API +These channels are not supported in the One Call API. ### Current Weather @@ -165,10 +166,12 @@ The "3h" value will be divided by three to always have an estimated value for on Where available, the One Call API provides a minutely precipitation forecast for the next 60 minutes. -| Channel Group ID | Channel ID | Item Type | Description | -|--------------------------------------------------------|----------------------|----------------------|----------------------------------------------------------------------------| -| forecastMinutes01 ... forecastMinutes60 | time-stamp | DateTime | Time of data forecasted. | -| forecastMinutes01 ... forecastMinutes60 | precipitation | Number:Length | Expected precipitation volume. | +| Channel Group ID | Channel ID | Item Type | Description | +|-----------------------------------------------------------|---------------|---------------|-----------------------------------------------------------------| +| forecastMinutes01 ... forecastMinutes60 | time-stamp | DateTime | Time of data forecasted. | +| forecastMinutely, forecastMinutes01 ... forecastMinutes60 | precipitation | Number:Length | Expected precipitation volume. | + +The `forecastMinutely` channel group provides time series support. ### 3 Hour Forecast @@ -197,42 +200,45 @@ Where available, the One Call API provides a minutely precipitation forecast for ### One Call API Hourly Forecast The One Call API provides hourly forecasts for 48 hours. -The Channel Group IDs for those are `forecastHours01` to `forecastHours48`. +The Channel Group IDs for those are `forecastHours01` to `forecastHours48`, and `forecastHourly` for channels with time series support. See above for a description of the available channels. +The `forecastHourly` channel group provides all channels as described above, except `time-stamp`, `sunrise`, `sunset`, `condition`, `condition-id`, `icon`, and `icon-id`. ### Daily Forecast -| Channel Group ID | Channel ID | Item Type | Description | -|------------------------------------------------------------------|----------------------|----------------------|-----------------------------------------------------------------------------------| -| forecastToday, forecastTomorrow, forecastDay2, ... forecastDay16 | time-stamp | DateTime | Date of data forecasted. | -| forecastToday, forecastTomorrow, forecastDay2, ... forecastDay16 | sunrise | DateTime | Time of sunrise for the given day. | -| forecastToday, forecastTomorrow, forecastDay2, ... forecastDay16 | sunset | DateTime | Time of sunset for the given day. | -| forecastToday, forecastTomorrow, forecastDay2, ... forecastDay16 | condition | String | Forecast weather condition. | -| forecastToday, forecastTomorrow, forecastDay2, ... forecastDay16 | condition-id | String | Id of the forecasted weather condition. **Advanced** | -| forecastToday, forecastTomorrow, forecastDay2, ... forecastDay16 | icon | Image | Icon representing the forecasted weather condition. | -| forecastToday, forecastTomorrow, forecastDay2, ... forecastDay16 | icon-id | String | Id of the icon representing the forecasted weather condition. **Advanced** | -| forecastToday, forecastTomorrow, forecastDay2, ... forecastDay16 | apparent-temperature | Number:Temperature | Forecasted apparent temperature. Not available in the One Call API | -| forecastToday, forecastTomorrow, forecastDay2, ... forecastDay16 | min-temperature | Number:Temperature | Minimum forecasted temperature of a day. | -| forecastToday, forecastTomorrow, forecastDay2, ... forecastDay16 | max-temperature | Number:Temperature | Maximum forecasted temperature of a day. | -| forecastToday, forecastTomorrow, forecastDay2, ... forecastDay16 | pressure | Number:Pressure | Forecasted barometric pressure. | -| forecastToday, forecastTomorrow, forecastDay2, ... forecastDay16 | humidity | Number:Dimensionless | Forecasted atmospheric humidity. | -| forecastToday, forecastTomorrow, forecastDay2, ... forecastDay16 | wind-speed | Number:Speed | Forecasted wind speed. | -| forecastToday, forecastTomorrow, forecastDay2, ... forecastDay16 | wind-direction | Number:Angle | Forecasted wind direction. | -| forecastToday, forecastTomorrow, forecastDay2, ... forecastDay16 | gust-speed | Number:Speed | Forecasted gust speed. **Advanced** | -| forecastToday, forecastTomorrow, forecastDay2, ... forecastDay16 | cloudiness | Number:Dimensionless | Forecasted cloudiness. | -| forecastToday, forecastTomorrow, forecastDay2, ... forecastDay16 | rain | Number:Length | Expected rain volume of a day. | -| forecastToday, forecastTomorrow, forecastDay2, ... forecastDay16 | snow | Number:Length | Expected snow volume of a day. | -| forecastToday, forecastTomorrow, forecastDay2, ... forecastDay7 | dew-point | Number:Temperature | Expected dew-point. Only available in the One Call API | -| forecastToday, forecastTomorrow, forecastDay2, ... forecastDay7 | uvindex | Number | Forecasted Midday UV Index. Only available in the One Call API | -| forecastToday, forecastTomorrow, forecastDay2, ... forecastDay7 | precip-probability | Number:Dimensionless | Precipitation probability. | -| forecastToday, forecastTomorrow, forecastDay2, ... forecastDay7 | morning-temperature | Number:Temperature | Expected morning temperature. Only available in the One Call API | -| forecastToday, forecastTomorrow, forecastDay2, ... forecastDay7 | day-temperature | Number:Temperature | Expected day-temperature. Only available in the One Call API | -| forecastToday, forecastTomorrow, forecastDay2, ... forecastDay7 | evening-temperature | Number:Temperature | Expected evening-temperature. Only available in the One Call API | -| forecastToday, forecastTomorrow, forecastDay2, ... forecastDay7 | night-temperature | Number:Temperature | Expected night-temperature. Only available in the One Call API | -| forecastToday, forecastTomorrow, forecastDay2, ... forecastDay7 | apparent-morning | Number:Temperature | Expected apparent temperature in the morning. Only available in the One Call API | -| 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 | +| Channel Group ID | Channel ID | Item Type | Description | +|---------------------------------------------------------------------------------|----------------------|----------------------|----------------------------------------------------------------------------------| +| forecastToday, forecastTomorrow, forecastDay2, ... forecastDay16 | time-stamp | DateTime | Date of data forecasted. | +| forecastToday, forecastTomorrow, forecastDay2, ... forecastDay16 | sunrise | DateTime | Time of sunrise for the given day. | +| forecastToday, forecastTomorrow, forecastDay2, ... forecastDay16 | sunset | DateTime | Time of sunset for the given day. | +| forecastToday, forecastTomorrow, forecastDay2, ... forecastDay16 | condition | String | Forecast weather condition. | +| forecastToday, forecastTomorrow, forecastDay2, ... forecastDay16 | condition-id | String | Id of the forecasted weather condition. **Advanced** | +| forecastToday, forecastTomorrow, forecastDay2, ... forecastDay16 | icon | Image | Icon representing the forecasted weather condition. | +| forecastToday, forecastTomorrow, forecastDay2, ... forecastDay16 | icon-id | String | Id of the icon representing the forecasted weather condition. **Advanced** | +| forecastDaily, forecastToday, forecastTomorrow, forecastDay2, ... forecastDay16 | apparent-temperature | Number:Temperature | Forecasted apparent temperature. Not available in the One Call API | +| forecastDaily, forecastToday, forecastTomorrow, forecastDay2, ... forecastDay16 | min-temperature | Number:Temperature | Minimum forecasted temperature of a day. | +| forecastDaily, forecastToday, forecastTomorrow, forecastDay2, ... forecastDay16 | max-temperature | Number:Temperature | Maximum forecasted temperature of a day. | +| forecastDaily, forecastToday, forecastTomorrow, forecastDay2, ... forecastDay16 | pressure | Number:Pressure | Forecasted barometric pressure. | +| forecastDaily, forecastToday, forecastTomorrow, forecastDay2, ... forecastDay16 | humidity | Number:Dimensionless | Forecasted atmospheric humidity. | +| forecastDaily, forecastToday, forecastTomorrow, forecastDay2, ... forecastDay16 | wind-speed | Number:Speed | Forecasted wind speed. | +| forecastDaily, forecastToday, forecastTomorrow, forecastDay2, ... forecastDay16 | wind-direction | Number:Angle | Forecasted wind direction. | +| forecastDaily, forecastToday, forecastTomorrow, forecastDay2, ... forecastDay16 | gust-speed | Number:Speed | Forecasted gust speed. **Advanced** | +| forecastDaily, forecastToday, forecastTomorrow, forecastDay2, ... forecastDay16 | cloudiness | Number:Dimensionless | Forecasted cloudiness. | +| forecastDaily, forecastToday, forecastTomorrow, forecastDay2, ... forecastDay16 | rain | Number:Length | Expected rain volume of a day. | +| forecastDaily, forecastToday, forecastTomorrow, forecastDay2, ... forecastDay16 | snow | Number:Length | Expected snow volume of a day. | +| forecastDaily, forecastToday, forecastTomorrow, forecastDay2, ... forecastDay7 | dew-point | Number:Temperature | Expected dew-point. Only available in the One Call API | +| forecastDaily, forecastToday, forecastTomorrow, forecastDay2, ... forecastDay7 | uvindex | Number | Forecasted Midday UV Index. Only available in the One Call API | +| forecastDaily, forecastToday, forecastTomorrow, forecastDay2, ... forecastDay7 | precip-probability | Number:Dimensionless | Precipitation probability. | +| forecastDaily, forecastToday, forecastTomorrow, forecastDay2, ... forecastDay7 | morning-temperature | Number:Temperature | Expected morning temperature. Only available in the One Call API | +| forecastDaily, forecastToday, forecastTomorrow, forecastDay2, ... forecastDay7 | day-temperature | Number:Temperature | Expected day-temperature. Only available in the One Call API | +| forecastDaily, forecastToday, forecastTomorrow, forecastDay2, ... forecastDay7 | evening-temperature | Number:Temperature | Expected evening-temperature. Only available in the One Call API | +| forecastDaily, forecastToday, forecastTomorrow, forecastDay2, ... forecastDay7 | night-temperature | Number:Temperature | Expected night-temperature. Only available in the One Call API | +| forecastDaily, forecastToday, forecastTomorrow, forecastDay2, ... forecastDay7 | apparent-morning | Number:Temperature | Expected apparent temperature in the morning. Only available in the One Call API | +| forecastDaily, forecastToday, forecastTomorrow, forecastDay2, ... forecastDay7 | apparent-day | Number:Temperature | Expected apparent temperature in the day. Only available in the One Call API | +| forecastDaily, forecastToday, forecastTomorrow, forecastDay2, ... forecastDay7 | apparent-evening | Number:Temperature | Expected apparent temperature in the evening. Only available in the One Call API | +| forecastDaily, forecastToday, forecastTomorrow, forecastDay2, ... forecastDay7 | apparent-night | Number:Temperature | Expected apparent temperature in the night. Only available in the One Call API | + +The `forecastDaily` channel group provides time series support. ### One Call API Weather Warnings @@ -268,6 +274,21 @@ The `uvindex` channel is also available in the current data and the daily foreca | current, forecastHours01, forecastHours02, ... forecastHours120 | sulphurDioxide | Number:Density | Current or forecasted concentration of sulphur dioxide. | | current, forecastHours01, forecastHours02, ... forecastHours120 | ammonia | Number:Density | Current or forecasted concentration of ammonia. | +## Persisting Time Series + +The binding offers support for persisting forecast values for most channels of the [One Call API Weather and Forecast](#one-call-api-weather-and-forecast) Thing. +The recommended persistence strategy is `forecast`, as it ensures a clean history without redundancy. + +### Configuration + +Make sure you have a persistence service installed and ready for use. + +To configure persisting forecast data, create and link Items to those channels with time series support (as usual). +Next, enable persistence for these Items using the `forecast` persistence strategy. +Finally, open MainUI, search for one of the newly created Items, open the analyzer and select a future time range. + +To access forecast data stored in persistence from scripts and rules, use the [Persistence Extensions]({{base}}/configuration/persistence.html#persistence-extensions-in-scripts-and-rules). + ## Full Example ### Things From 183bd9b81079816807d34347cbab947b35fb2bec Mon Sep 17 00:00:00 2001 From: Florian Hotze Date: Mon, 27 Nov 2023 12:17:31 +0100 Subject: [PATCH 03/13] [openweathermap] Add Thing update instructions Signed-off-by: Florian Hotze --- .../resources/OH-INF/thing/thing-types.xml | 3 + .../resources/OH-INF/update/instructions.xml | 118 ++++++++++++++++++ 2 files changed, 121 insertions(+) create mode 100644 bundles/org.openhab.binding.openweathermap/src/main/resources/OH-INF/update/instructions.xml 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 18ab4f9eefd4f..bc9a2aad61b89 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 @@ -274,6 +274,9 @@ + + 1 + location diff --git a/bundles/org.openhab.binding.openweathermap/src/main/resources/OH-INF/update/instructions.xml b/bundles/org.openhab.binding.openweathermap/src/main/resources/OH-INF/update/instructions.xml new file mode 100644 index 0000000000000..7eadd39843724 --- /dev/null +++ b/bundles/org.openhab.binding.openweathermap/src/main/resources/OH-INF/update/instructions.xml @@ -0,0 +1,118 @@ + + + + + + + openweathermap:precipitation + + + + system:outdoor-temperature + + + openweathermap:apparent-temperature + + + system:barometric-pressure + + + system:atmospheric-humidity + + + openweathermap:dew-point + + + system:wind-speed + + + system:wind-direction + + + openweathermap:gust-speed + + + openweathermap:cloudiness + + + openweathermap:precip-probability + + + openweathermap:rain + + + openweathermap:snow + + + openweathermap:visibility + + + + openweathermap:morning-temperature + + + openweathermap:day-temperature + + + openweathermap:evening-temperature + + + openweathermap:night-temperature + + + openweathermap:forecasted-min-outdoor-temperature + + + openweathermap:forecasted-max-outdoor-temperature + + + openweathermap:apparent-morning + + + openweathermap:apparent-day + + + openweathermap:apparent-evening + + + openweathermap:apparent-night + + + system:barometric-pressure + + + system:atmospheric-humidity + + + openweathermap:dew-point + + + system:wind-speed + + + system:wind-direction + + + openweathermap:gust-speed + + + openweathermap:cloudiness + + + openweathermap:forecasted-uvindex + + + openweathermap:precip-probability + + + openweathermap:rain + + + openweathermap:snow + + + + + From 1ec4e5147edd9857f3eb82bd69bb6ea2c74177dc Mon Sep 17 00:00:00 2001 From: Florian Hotze Date: Wed, 13 Dec 2023 21:02:23 +0100 Subject: [PATCH 04/13] [openweathermap] Add time-series support for remaining OneCall API hourly and daily channels Signed-off-by: Florian Hotze --- .../README.md | 14 ++++----- .../handler/OpenWeatherMapOneCallHandler.java | 9 ++---- .../resources/OH-INF/thing/channel-types.xml | 10 +++++++ .../resources/OH-INF/update/instructions.xml | 30 +++++++++++++++++++ 4 files changed, 49 insertions(+), 14 deletions(-) diff --git a/bundles/org.openhab.binding.openweathermap/README.md b/bundles/org.openhab.binding.openweathermap/README.md index a66f13bbc6eec..4048c479bbff8 100644 --- a/bundles/org.openhab.binding.openweathermap/README.md +++ b/bundles/org.openhab.binding.openweathermap/README.md @@ -202,19 +202,19 @@ The `forecastMinutely` channel group provides time series support. The One Call API provides hourly forecasts for 48 hours. The Channel Group IDs for those are `forecastHours01` to `forecastHours48`, and `forecastHourly` for channels with time series support. See above for a description of the available channels. -The `forecastHourly` channel group provides all channels as described above, except `time-stamp`, `sunrise`, `sunset`, `condition`, `condition-id`, `icon`, and `icon-id`. +The `forecastHourly` channel group provides all channels as described above with time series support, except `time-stamp`. ### Daily Forecast | Channel Group ID | Channel ID | Item Type | Description | |---------------------------------------------------------------------------------|----------------------|----------------------|----------------------------------------------------------------------------------| | forecastToday, forecastTomorrow, forecastDay2, ... forecastDay16 | time-stamp | DateTime | Date of data forecasted. | -| forecastToday, forecastTomorrow, forecastDay2, ... forecastDay16 | sunrise | DateTime | Time of sunrise for the given day. | -| forecastToday, forecastTomorrow, forecastDay2, ... forecastDay16 | sunset | DateTime | Time of sunset for the given day. | -| forecastToday, forecastTomorrow, forecastDay2, ... forecastDay16 | condition | String | Forecast weather condition. | -| forecastToday, forecastTomorrow, forecastDay2, ... forecastDay16 | condition-id | String | Id of the forecasted weather condition. **Advanced** | -| forecastToday, forecastTomorrow, forecastDay2, ... forecastDay16 | icon | Image | Icon representing the forecasted weather condition. | -| forecastToday, forecastTomorrow, forecastDay2, ... forecastDay16 | icon-id | String | Id of the icon representing the forecasted weather condition. **Advanced** | +| forecastDaily, forecastToday, forecastTomorrow, forecastDay2, ... forecastDay16 | sunrise | DateTime | Time of sunrise for the given day. | +| forecastDaily, forecastToday, forecastTomorrow, forecastDay2, ... forecastDay16 | sunset | DateTime | Time of sunset for the given day. | +| forecastDaily, forecastToday, forecastTomorrow, forecastDay2, ... forecastDay16 | condition | String | Forecast weather condition. | +| forecastDaily, forecastToday, forecastTomorrow, forecastDay2, ... forecastDay16 | condition-id | String | Id of the forecasted weather condition. **Advanced** | +| forecastDaily, forecastToday, forecastTomorrow, forecastDay2, ... forecastDay16 | icon | Image | Icon representing the forecasted weather condition. | +| forecastDaily, forecastToday, forecastTomorrow, forecastDay2, ... forecastDay16 | icon-id | String | Id of the icon representing the forecasted weather condition. **Advanced** | | forecastDaily, forecastToday, forecastTomorrow, forecastDay2, ... forecastDay16 | apparent-temperature | Number:Temperature | Forecasted apparent temperature. Not available in the One Call API | | forecastDaily, forecastToday, forecastTomorrow, forecastDay2, ... forecastDay16 | min-temperature | Number:Temperature | Minimum forecasted temperature of a day. | | forecastDaily, forecastToday, forecastTomorrow, forecastDay2, ... forecastDay16 | max-temperature | Number:Temperature | Maximum forecasted temperature of a day. | 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 db36c8bb68dad..2572191269a81 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 @@ -510,9 +510,7 @@ private void updateHourlyForecastTimeSeries(ChannelUID channelUID) { channelGroupId); return; } - if (channelId.equals(CHANNEL_TIME_STAMP) || channelId.equals(CHANNEL_CONDITION) - || channelId.equals(CHANNEL_CONDITION_ID) || channelId.equals(CHANNEL_CONDITION_ICON) - || channelId.equals(CHANNEL_CONDITION_ICON_ID)) { + if (channelId.equals(CHANNEL_TIME_STAMP)) { logger.debug("Channel `{}` of group '{}' is no supported time-series channel.", channelId, channelGroupId); return; } @@ -648,10 +646,7 @@ private void updateDailyForecastTimeSeries(ChannelUID channelUID) { channelGroupId); return; } - if (channelId.equals(CHANNEL_TIME_STAMP) || channelId.equals(CHANNEL_SUNRISE) - || channelId.equals(CHANNEL_SUNSET) || channelId.equals(CHANNEL_CONDITION) - || channelId.equals(CHANNEL_CONDITION_ID) || channelId.equals(CHANNEL_CONDITION_ICON) - || channelId.equals(CHANNEL_CONDITION_ICON_ID)) { + if (channelId.equals(CHANNEL_TIME_STAMP)) { logger.debug("Channel `{}` of group '{}' is no supported time-series channel.", channelId, channelGroupId); return; } 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 0e790a8e1acc0..52f4337a0bfd4 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 @@ -190,6 +190,10 @@ Hourly weather forecast delivered by the One Call API. + + + + @@ -235,6 +239,12 @@ Daily weather forecast delivered by the One Call API. + + + + + + diff --git a/bundles/org.openhab.binding.openweathermap/src/main/resources/OH-INF/update/instructions.xml b/bundles/org.openhab.binding.openweathermap/src/main/resources/OH-INF/update/instructions.xml index 7eadd39843724..284c6fb87f6ee 100644 --- a/bundles/org.openhab.binding.openweathermap/src/main/resources/OH-INF/update/instructions.xml +++ b/bundles/org.openhab.binding.openweathermap/src/main/resources/OH-INF/update/instructions.xml @@ -9,6 +9,18 @@ openweathermap:precipitation + + openweathermap:condition + + + openweathermap:condition-id + + + openweathermap:icon + + + openweathermap:icon-id + system:outdoor-temperature @@ -49,6 +61,24 @@ openweathermap:visibility + + openweathermap:sunrise + + + openweathermap:sunset + + + openweathermap:condition + + + openweathermap:condition-id + + + openweathermap:icon + + + openweathermap:icon-id + openweathermap:morning-temperature From f8fb049343a33d2b41ec7e5efca1f5d024d42b9d Mon Sep 17 00:00:00 2001 From: Florian Hotze Date: Wed, 13 Dec 2023 21:03:53 +0100 Subject: [PATCH 05/13] [openweathermap] Rename channel groups: Remove "Time Series" Signed-off-by: Florian Hotze --- .../src/main/resources/OH-INF/thing/channel-types.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) 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 52f4337a0bfd4..8b353c1524550 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 @@ -170,7 +170,7 @@ - + Minutely precipitation delivered by the One Call API. @@ -187,7 +187,7 @@ - + Hourly weather forecast delivered by the One Call API. @@ -236,7 +236,7 @@ - + Daily weather forecast delivered by the One Call API. From 4620b040c111576a8c3b2601b237c30aeaddb5ba Mon Sep 17 00:00:00 2001 From: Florian Hotze Date: Wed, 13 Dec 2023 21:24:01 +0100 Subject: [PATCH 06/13] [openweathermap] Do not create the hourly & daily channel groups by default Signed-off-by: Florian Hotze --- .../README.md | 16 +++++----- .../handler/OpenWeatherMapOneCallHandler.java | 29 ++++--------------- .../main/resources/OH-INF/config/config.xml | 18 +++++++----- 3 files changed, 25 insertions(+), 38 deletions(-) diff --git a/bundles/org.openhab.binding.openweathermap/README.md b/bundles/org.openhab.binding.openweathermap/README.md index 4048c479bbff8..64d98c2478904 100644 --- a/bundles/org.openhab.binding.openweathermap/README.md +++ b/bundles/org.openhab.binding.openweathermap/README.md @@ -104,13 +104,15 @@ 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** | -| 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"). | -| numberOfAlerts | Number of alerts to be shown. Optional, the default value is 0 (min="0", max="5"). | +| Parameter | Description | +|-----------------|---------------------------------------------------------------------------------------------------------------------------------------| +| location | Location of weather in geographical coordinates (latitude/longitude/altitude). **Mandatory** | +| forecastMinutes | Number of minutes for minutely precipitation forecast as minutely channels. Optional, the default value is 0 (min="0", max="60"). | +| forecastHours | Number of hours for hourly forecast as hourly channels. Optional, the default value is 0 (min="0", max="48"). | +| forecastDays | Number of days for daily forecast (including todays forecast) as daily channels. Optional, the default value is 0 (min="0", max="8"). | +| numberOfAlerts | Number of alerts to be shown. Optional, the default value is 0 (min="0", max="5"). | + +Set `forecastMinutes`, `forecastHours` and `forecastDays` to `0` if you only want to use the channels with time series support. ### One Call API History Data 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 2572191269a81..b283684afe1b9 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 @@ -84,9 +84,10 @@ public class OpenWeatherMapOneCallHandler extends AbstractOpenWeatherMapHandler private @Nullable OpenWeatherMapOneCallAPIData weatherData; - private int forecastMinutes = 60; - private int forecastHours = 24; - private int forecastDays = 8; + // forecastMinutes, -Hours and -Days determine the number of channel groups to create for each type + private int forecastMinutes = 0; + private int forecastHours = 0; + private int forecastDays = 0; private int numberOfAlerts = 0; public OpenWeatherMapOneCallHandler(Thing thing, final TimeZoneProvider timeZoneProvider) { @@ -226,8 +227,8 @@ protected boolean requestData(OpenWeatherMapConnection connection) throws CommunicationException, ConfigurationException { logger.debug("Update weather and forecast data of thing '{}'.", getThing().getUID()); try { - weatherData = connection.getOneCallAPIData(location, forecastMinutes == 0, forecastHours == 0, - forecastDays == 0, numberOfAlerts == 0); + // Include minutely, hourly and daily data as this is needed for the time series channels + weatherData = connection.getOneCallAPIData(location, false, false, false, numberOfAlerts == 0); return true; } catch (JsonSyntaxException e) { logger.debug("JsonSyntaxException occurred during execution: {}", e.getMessage(), e); @@ -434,12 +435,6 @@ private void updateMinutelyForecastTimeSeries(ChannelUID channelUID) { String channelId = channelUID.getIdWithoutGroup(); String channelGroupId = channelUID.getGroupId(); OpenWeatherMapOneCallAPIData localWeatherData = weatherData; - if (forecastMinutes == 0) { - logger.warn( - "Can't update channel group {} because forecastMinutes is set to '0'. Please adjust config accordingly", - channelGroupId); - return; - } if (channelId.equals(CHANNEL_TIME_STAMP)) { logger.debug("Channel `{}` of group '{}' is no supported time-series channel.", channelId, channelGroupId); return; @@ -504,12 +499,6 @@ private void updateHourlyForecastChannel(ChannelUID channelUID, int count) { private void updateHourlyForecastTimeSeries(ChannelUID channelUID) { String channelId = channelUID.getIdWithoutGroup(); String channelGroupId = channelUID.getGroupId(); - if (forecastHours == 0) { - logger.warn( - "Can't update channel group {} because forecastHours is set to '0'. Please adjust config accordingly", - channelGroupId); - return; - } if (channelId.equals(CHANNEL_TIME_STAMP)) { logger.debug("Channel `{}` of group '{}' is no supported time-series channel.", channelId, channelGroupId); return; @@ -640,12 +629,6 @@ private void updateDailyForecastChannel(ChannelUID channelUID, int count) { private void updateDailyForecastTimeSeries(ChannelUID channelUID) { String channelId = channelUID.getIdWithoutGroup(); String channelGroupId = channelUID.getGroupId(); - if (forecastDays == 0) { - logger.warn( - "Can't update channel group {} because forecastDays is set to '0'. Please adjust config accordingly", - channelGroupId); - return; - } if (channelId.equals(CHANNEL_TIME_STAMP)) { logger.debug("Channel `{}` of group '{}' is no supported time-series channel.", channelId, channelGroupId); return; 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 728a2c7a96ce6..6725f0004101b 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 @@ -130,18 +130,20 @@ Location of weather in geographical coordinates (latitude/longitude/altitude). - - Number of days for daily forecast, including the current day. - 6 + + Number of days for daily forecast, including the current day and determining how many daily channels are + created. + 0 - - Number of hours for hourly forecast. - 12 + + Number of hours for hourly forecast, determining how many hourly channels are created. + 0 - - Number of minutes for minutely precipitation forecast. + + Number of minutes for minutely precipitation forecast, determining how many minutely channels are + created. 0 From 113bc9000b01ee49530f545b205079aff00def73 Mon Sep 17 00:00:00 2001 From: Florian Hotze Date: Wed, 13 Dec 2023 21:24:58 +0100 Subject: [PATCH 07/13] [openweathermap] Address review regarding README & Minor README improvement Signed-off-by: Florian Hotze --- bundles/org.openhab.binding.openweathermap/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bundles/org.openhab.binding.openweathermap/README.md b/bundles/org.openhab.binding.openweathermap/README.md index 64d98c2478904..7c675fd4e2b17 100644 --- a/bundles/org.openhab.binding.openweathermap/README.md +++ b/bundles/org.openhab.binding.openweathermap/README.md @@ -71,7 +71,7 @@ Once the system location will be changed, the background discovery updates the c | Parameter | Description | |-----------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | apikey | API key to access the OpenWeatherMap API. **Mandatory** | -| refreshInterval | Specifies the refresh interval (in minutes). Optional, the default value is 60, the minimum value is 1. | +| refreshInterval | Specifies the refresh interval (in minutes). Optional, the default value is 60, the minimum value is 1. | | language | Language to be used by the OpenWeatherMap API. Optional, valid values are: `ar`, `bg`, `ca`, `de`, `el`, `en`, `es`, `fa`, `fi`, `fr`, `gl`, `hr`, `hu`, `it`, `ja`, `kr`, `la`, `lt`, `mk`, `nl`, `pl`, `pt`, `ro`, `ru`, `se`, `sk`, `sl`, `tr`, `ua`, `vi`, `zh_cn`, `zh_tw`. | ### Current Weather And Forecast @@ -287,7 +287,7 @@ Make sure you have a persistence service installed and ready for use. To configure persisting forecast data, create and link Items to those channels with time series support (as usual). Next, enable persistence for these Items using the `forecast` persistence strategy. -Finally, open MainUI, search for one of the newly created Items, open the analyzer and select a future time range. +Finally, open the UI, search for one of the newly created Items, open the analyzer and select a future time range. To access forecast data stored in persistence from scripts and rules, use the [Persistence Extensions]({{base}}/configuration/persistence.html#persistence-extensions-in-scripts-and-rules). From 5d94e6838550f91c38e698a2a825e0689a6e616e Mon Sep 17 00:00:00 2001 From: Florian Hotze Date: Wed, 13 Dec 2023 21:49:26 +0100 Subject: [PATCH 08/13] [openweathermap] Fix update instructions Signed-off-by: Florian Hotze --- .../src/main/resources/OH-INF/update/instructions.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/bundles/org.openhab.binding.openweathermap/src/main/resources/OH-INF/update/instructions.xml b/bundles/org.openhab.binding.openweathermap/src/main/resources/OH-INF/update/instructions.xml index 284c6fb87f6ee..238adb654cc8d 100644 --- a/bundles/org.openhab.binding.openweathermap/src/main/resources/OH-INF/update/instructions.xml +++ b/bundles/org.openhab.binding.openweathermap/src/main/resources/OH-INF/update/instructions.xml @@ -16,10 +16,10 @@ openweathermap:condition-id - openweathermap:icon + openweathermap:condition-icon - openweathermap:icon-id + openweathermap:condition-icon-id system:outdoor-temperature @@ -74,10 +74,10 @@ openweathermap:condition-id - openweathermap:icon + openweathermap:condition-icon - openweathermap:icon-id + openweathermap:condition-icon-id openweathermap:morning-temperature From 2ca7199a4a316e03d4d9d00a90f92d030c400e6f Mon Sep 17 00:00:00 2001 From: Florian Hotze Date: Wed, 13 Dec 2023 21:51:28 +0100 Subject: [PATCH 09/13] [openweathermap] Regenerate default translations Signed-off-by: Florian Hotze --- .../OH-INF/i18n/openweathermap.properties | 22 ++++++++++++------- 1 file changed, 14 insertions(+), 8 deletions(-) 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 8bfd0c26132f3..8bc59e69b3a79 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 @@ -74,10 +74,10 @@ thing-type.openweathermap.weather-api.description = Provides access to the OpenW # thing types config -bridge-type.config.openweathermap.weather-api.apikey.label = API Key -bridge-type.config.openweathermap.weather-api.apikey.description = API key to access the OpenWeatherMap API. bridge-type.config.openweathermap.weather-api.apiVersion.label = One Call API Version bridge-type.config.openweathermap.weather-api.apiVersion.description = One Call API version (defaults to 2.5, version 3.0 is available, but needs different subscription). +bridge-type.config.openweathermap.weather-api.apikey.label = API Key +bridge-type.config.openweathermap.weather-api.apikey.description = API key to access the OpenWeatherMap API. bridge-type.config.openweathermap.weather-api.language.label = Language bridge-type.config.openweathermap.weather-api.language.description = Language to be used by the OpenWeatherMap API. bridge-type.config.openweathermap.weather-api.language.option.af = Afrikaans @@ -136,12 +136,12 @@ thing-type.config.openweathermap.onecall-history.historyDay.label = History Day thing-type.config.openweathermap.onecall-history.historyDay.description = Relative number of days in the past for historical data. thing-type.config.openweathermap.onecall-history.location.label = Location of Weather thing-type.config.openweathermap.onecall-history.location.description = Location of weather in geographical coordinates (latitude/longitude/altitude). -thing-type.config.openweathermap.onecall.forecastDays.label = Number of Days -thing-type.config.openweathermap.onecall.forecastDays.description = Number of days for daily forecast, including the current day. -thing-type.config.openweathermap.onecall.forecastHours.label = Number of Hours -thing-type.config.openweathermap.onecall.forecastHours.description = Number of hours for hourly forecast. -thing-type.config.openweathermap.onecall.forecastMinutes.label = Number of Minutes -thing-type.config.openweathermap.onecall.forecastMinutes.description = Number of minutes for minutely precipitation forecast. +thing-type.config.openweathermap.onecall.forecastDays.label = Number of Daily Forecast Channels +thing-type.config.openweathermap.onecall.forecastDays.description = Number of days for daily forecast, including the current day and determining how many daily channels are created. +thing-type.config.openweathermap.onecall.forecastHours.label = Number of Hourly Forecast Channels +thing-type.config.openweathermap.onecall.forecastHours.description = Number of hours for hourly forecast, determining how many hourly channels are created. +thing-type.config.openweathermap.onecall.forecastMinutes.label = Number of Minutely Forecast Channels +thing-type.config.openweathermap.onecall.forecastMinutes.description = Number of minutes for minutely precipitation forecast, determining how many minutely channels are created. thing-type.config.openweathermap.onecall.location.label = Location of Weather thing-type.config.openweathermap.onecall.location.description = Location of weather in geographical coordinates (latitude/longitude/altitude). thing-type.config.openweathermap.onecall.numberOfAlerts.label = Number of Alerts @@ -173,14 +173,20 @@ channel-group-type.openweathermap.oneCallCurrent.label = One Call API Current We channel-group-type.openweathermap.oneCallCurrent.description = Current weather data from the One Call API. channel-group-type.openweathermap.oneCallDaily.label = One Call API Daily Forecast channel-group-type.openweathermap.oneCallDaily.description = Daily weather forecast delivered by the One Call API. +channel-group-type.openweathermap.oneCallDailyTimeSeries.label = One Call API Daily Forecast +channel-group-type.openweathermap.oneCallDailyTimeSeries.description = Daily weather forecast delivered by the One Call API. channel-group-type.openweathermap.oneCallHistory.label = One Call API Historical Weather channel-group-type.openweathermap.oneCallHistory.description = Historical weather data from the One Call API at this point in time the given day. channel-group-type.openweathermap.oneCallHistoryHours.label = One Call API Hourly Historical Weather Data channel-group-type.openweathermap.oneCallHistoryHours.description = Historical weather data from the One Call API per hour. channel-group-type.openweathermap.oneCallHourly.label = One Call API Hourly Forecast channel-group-type.openweathermap.oneCallHourly.description = Hourly weather forecast delivered by the One Call API. +channel-group-type.openweathermap.oneCallHourlyTimeSeries.label = One Call API Hourly Forecast +channel-group-type.openweathermap.oneCallHourlyTimeSeries.description = Hourly weather forecast delivered by the One Call API. channel-group-type.openweathermap.oneCallMinutely.label = One Call API Minutely Forecast channel-group-type.openweathermap.oneCallMinutely.description = Minutely precipitation delivered by the One Call API. +channel-group-type.openweathermap.oneCallMinutelyTimeSeries.label = One Call API Minutely Forecast +channel-group-type.openweathermap.oneCallMinutelyTimeSeries.description = Minutely precipitation delivered by the One Call API. channel-group-type.openweathermap.station.label = Weather Station channel-group-type.openweathermap.station.description = This is a weather station. channel-group-type.openweathermap.station.channel.location.description = Location of the weather station or the city. From 073812f3ad8329e6f3ec7316df59a71da10e21f8 Mon Sep 17 00:00:00 2001 From: Florian Hotze Date: Wed, 13 Dec 2023 21:51:44 +0100 Subject: [PATCH 10/13] [openweathermap] Add links to time series configuration in README Signed-off-by: Florian Hotze --- bundles/org.openhab.binding.openweathermap/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bundles/org.openhab.binding.openweathermap/README.md b/bundles/org.openhab.binding.openweathermap/README.md index 7c675fd4e2b17..bde32137d87f7 100644 --- a/bundles/org.openhab.binding.openweathermap/README.md +++ b/bundles/org.openhab.binding.openweathermap/README.md @@ -173,7 +173,7 @@ Where available, the One Call API provides a minutely precipitation forecast for | forecastMinutes01 ... forecastMinutes60 | time-stamp | DateTime | Time of data forecasted. | | forecastMinutely, forecastMinutes01 ... forecastMinutes60 | precipitation | Number:Length | Expected precipitation volume. | -The `forecastMinutely` channel group provides time series support. +The `forecastMinutely` channel group provides [time series support](#persisting-time-series). ### 3 Hour Forecast @@ -204,7 +204,7 @@ The `forecastMinutely` channel group provides time series support. The One Call API provides hourly forecasts for 48 hours. The Channel Group IDs for those are `forecastHours01` to `forecastHours48`, and `forecastHourly` for channels with time series support. See above for a description of the available channels. -The `forecastHourly` channel group provides all channels as described above with time series support, except `time-stamp`. +The `forecastHourly` channel group provides all channels as described above with [time series support](#persisting-time-series), except `time-stamp`. ### Daily Forecast @@ -240,7 +240,7 @@ The `forecastHourly` channel group provides all channels as described above with | forecastDaily, forecastToday, forecastTomorrow, forecastDay2, ... forecastDay7 | apparent-evening | Number:Temperature | Expected apparent temperature in the evening. Only available in the One Call API | | forecastDaily, forecastToday, forecastTomorrow, forecastDay2, ... forecastDay7 | apparent-night | Number:Temperature | Expected apparent temperature in the night. Only available in the One Call API | -The `forecastDaily` channel group provides time series support. +The `forecastDaily` channel group provides [time series support](#persisting-time-series). ### One Call API Weather Warnings From c6135fad8f58569cffd2bfb94e72117cd67c1159 Mon Sep 17 00:00:00 2001 From: Florian Hotze Date: Thu, 14 Dec 2023 08:38:15 +0100 Subject: [PATCH 11/13] Revert changes to default number of forecastDays & -Hours Signed-off-by: Florian Hotze --- .../src/main/resources/OH-INF/config/config.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 6725f0004101b..58c40dc36e1ca 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 @@ -133,12 +133,12 @@ Number of days for daily forecast, including the current day and determining how many daily channels are created. - 0 + 6 Number of hours for hourly forecast, determining how many hourly channels are created. - 0 + 12 From d47e5e60584b9ef2da4cae61b0013f4b5376b98b Mon Sep 17 00:00:00 2001 From: Florian Hotze Date: Thu, 14 Dec 2023 08:46:14 +0100 Subject: [PATCH 12/13] README: Revert default config changes Signed-off-by: Florian Hotze --- bundles/org.openhab.binding.openweathermap/README.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/bundles/org.openhab.binding.openweathermap/README.md b/bundles/org.openhab.binding.openweathermap/README.md index bde32137d87f7..23eb14c0723b9 100644 --- a/bundles/org.openhab.binding.openweathermap/README.md +++ b/bundles/org.openhab.binding.openweathermap/README.md @@ -108,11 +108,12 @@ Once the parameter `forecastHours` will be changed, the available channel groups |-----------------|---------------------------------------------------------------------------------------------------------------------------------------| | location | Location of weather in geographical coordinates (latitude/longitude/altitude). **Mandatory** | | forecastMinutes | Number of minutes for minutely precipitation forecast as minutely channels. Optional, the default value is 0 (min="0", max="60"). | -| forecastHours | Number of hours for hourly forecast as hourly channels. Optional, the default value is 0 (min="0", max="48"). | -| forecastDays | Number of days for daily forecast (including todays forecast) as daily channels. Optional, the default value is 0 (min="0", max="8"). | +| forecastHours | Number of hours for hourly forecast as hourly channels. Optional, the default value is 12 (min="0", max="48"). | +| forecastDays | Number of days for daily forecast (including todays forecast) as daily channels. 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"). | Set `forecastMinutes`, `forecastHours` and `forecastDays` to `0` if you only want to use the channels with time series support. +In a future release, this will become the default setting as usage of the time series channels instead is encouraged. ### One Call API History Data @@ -206,6 +207,8 @@ The Channel Group IDs for those are `forecastHours01` to `forecastHours48`, and See above for a description of the available channels. The `forecastHourly` channel group provides all channels as described above with [time series support](#persisting-time-series), except `time-stamp`. +In a future release, the `forecastHours01` to `forecastHours48` channel groups won't be created anymore by default as usage of the time series channels instead is encouraged. + ### Daily Forecast | Channel Group ID | Channel ID | Item Type | Description | @@ -242,6 +245,8 @@ The `forecastHourly` channel group provides all channels as described above with The `forecastDaily` channel group provides [time series support](#persisting-time-series). +In a future release, the `forecastToday` to `forecastDay7` channel groups won't be created anymore by default as usage of the time series channels instead is encouraged. + ### One Call API Weather Warnings | Channel Group ID | Channel ID | Item Type | Description | From 79ddbea62e5a3fc1b75bc26f22336c00613f3288 Mon Sep 17 00:00:00 2001 From: Florian Hotze Date: Thu, 14 Dec 2023 18:46:08 +0100 Subject: [PATCH 13/13] [openweathermap] Revert change to vars Signed-off-by: Florian Hotze --- .../internal/handler/OpenWeatherMapOneCallHandler.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 b283684afe1b9..ef3ceb3c58f5e 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 @@ -86,8 +86,8 @@ public class OpenWeatherMapOneCallHandler extends AbstractOpenWeatherMapHandler // forecastMinutes, -Hours and -Days determine the number of channel groups to create for each type private int forecastMinutes = 0; - private int forecastHours = 0; - private int forecastDays = 0; + private int forecastHours = 12; + private int forecastDays = 6; private int numberOfAlerts = 0; public OpenWeatherMapOneCallHandler(Thing thing, final TimeZoneProvider timeZoneProvider) {