2 * Copyright (c) 2010-2021 Contributors to the openHAB project
4 * See the NOTICE file(s) distributed with this work for additional
7 * This program and the accompanying materials are made available under the
8 * terms of the Eclipse Public License 2.0 which is available at
9 * http://www.eclipse.org/legal/epl-2.0
11 * SPDX-License-Identifier: EPL-2.0
13 package org.openhab.binding.openweathermap.internal.handler;
15 import static org.openhab.binding.openweathermap.internal.OpenWeatherMapBindingConstants.*;
16 import static org.openhab.core.library.unit.MetricPrefix.*;
17 import static org.openhab.core.library.unit.SIUnits.*;
18 import static org.openhab.core.library.unit.Units.*;
20 import java.util.ArrayList;
21 import java.util.List;
22 import java.util.regex.Matcher;
23 import java.util.regex.Pattern;
25 import org.eclipse.jdt.annotation.NonNullByDefault;
26 import org.eclipse.jdt.annotation.Nullable;
27 import org.openhab.binding.openweathermap.internal.config.OpenWeatherMapOneCallConfiguration;
28 import org.openhab.binding.openweathermap.internal.connection.OpenWeatherMapCommunicationException;
29 import org.openhab.binding.openweathermap.internal.connection.OpenWeatherMapConfigurationException;
30 import org.openhab.binding.openweathermap.internal.connection.OpenWeatherMapConnection;
31 import org.openhab.binding.openweathermap.internal.dto.onecall.*;
32 import org.openhab.core.i18n.TimeZoneProvider;
33 import org.openhab.core.library.types.QuantityType;
34 import org.openhab.core.thing.*;
35 import org.openhab.core.thing.binding.builder.ThingBuilder;
36 import org.openhab.core.types.State;
37 import org.openhab.core.types.UnDefType;
38 import org.slf4j.Logger;
39 import org.slf4j.LoggerFactory;
41 import com.google.gson.JsonSyntaxException;
44 * The {@link OpenWeatherMapOneCallHandler} is responsible for handling commands, which are sent to one of
47 * @author Wolfgang Klimt - Initial contribution
50 public class OpenWeatherMapOneCallHandler extends AbstractOpenWeatherMapHandler {
52 private final Logger logger = LoggerFactory.getLogger(OpenWeatherMapOneCallHandler.class);
54 private static final String CHANNEL_GROUP_MINUTELY_FORECAST_PREFIX = "forecastMinutes";
55 private static final String CHANNEL_GROUP_HOURLY_FORECAST_PREFIX = "forecastHours";
56 private static final String CHANNEL_GROUP_DAILY_FORECAST_PREFIX = "forecastDay";
57 private static final Pattern CHANNEL_GROUP_HOURLY_FORECAST_PREFIX_PATTERN = Pattern
58 .compile(CHANNEL_GROUP_HOURLY_FORECAST_PREFIX + "([0-9]*)");
59 private static final Pattern CHANNEL_GROUP_DAILY_FORECAST_PREFIX_PATTERN = Pattern
60 .compile(CHANNEL_GROUP_DAILY_FORECAST_PREFIX + "([0-9]*)");
61 private static final Pattern CHANNEL_GROUP_MINUTELY_FORECAST_PREFIX_PATTERN = Pattern
62 .compile(CHANNEL_GROUP_MINUTELY_FORECAST_PREFIX + "([0-9]*)");
64 private @Nullable OpenWeatherMapOneCallAPIData weatherData;
66 private int forecastMinutes = 60;
67 private int forecastHours = 24;
68 private int forecastDays = 8;
70 public OpenWeatherMapOneCallHandler(Thing thing, final TimeZoneProvider timeZoneProvider) {
71 super(thing, timeZoneProvider);
75 public void initialize() {
77 logger.debug("Initialize OpenWeatherMapOneCallHandler handler '{}'.", getThing().getUID());
78 OpenWeatherMapOneCallConfiguration config = getConfigAs(OpenWeatherMapOneCallConfiguration.class);
80 boolean configValid = true;
81 int newForecastMinutes = config.forecastMinutes;
82 if (newForecastMinutes < 0 || newForecastMinutes > 60) {
83 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
84 "@text/offline.conf-error-not-supported-onecall-number-of-minutes");
87 int newForecastHours = config.forecastHours;
88 if (newForecastHours < 0 || newForecastHours > 48) {
89 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
90 "@text/offline.conf-error-not-supported-onecall-number-of-hours");
93 int newForecastDays = config.forecastDays;
94 if (newForecastDays < 0 || newForecastDays > 8) {
95 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
96 "@text/offline.conf-error-not-supported-onecall-number-of-days");
101 logger.debug("Rebuilding thing '{}'.", getThing().getUID());
102 List<Channel> toBeAddedChannels = new ArrayList<>();
103 List<Channel> toBeRemovedChannels = new ArrayList<>();
105 .addAll(createChannelsForGroup(CHANNEL_GROUP_ONECALL_CURRENT, CHANNEL_GROUP_TYPE_ONECALL_CURRENT));
107 if (forecastMinutes != newForecastMinutes) {
108 logger.debug("forecastMinutes changed from {} to {}. Rebuilding minutely forecast channel groups.",
109 forecastMinutes, newForecastMinutes);
110 if (forecastMinutes > newForecastMinutes) {
111 for (int i = newForecastMinutes + 1; i <= forecastMinutes; i++) {
112 toBeRemovedChannels.addAll(removeChannelsOfGroup(
113 CHANNEL_GROUP_MINUTELY_FORECAST_PREFIX + ((i < 10) ? "0" : "") + Integer.toString(i)));
116 for (int i = forecastMinutes + 1; i <= newForecastMinutes; i++) {
117 toBeAddedChannels.addAll(createChannelsForGroup(
118 CHANNEL_GROUP_MINUTELY_FORECAST_PREFIX + ((i < 10) ? "0" : "") + Integer.toString(i),
119 CHANNEL_GROUP_TYPE_ONECALL_MINUTELY_FORECAST));
122 forecastMinutes = newForecastMinutes;
124 if (forecastHours != newForecastHours) {
125 logger.debug("ForecastHours changed from {} to {}. Rebuilding hourly forecast channel groups.",
126 forecastHours, newForecastHours);
127 if (forecastHours > newForecastHours) {
128 for (int i = newForecastHours + 1; i <= forecastHours; i++) {
129 toBeRemovedChannels.addAll(removeChannelsOfGroup(
130 CHANNEL_GROUP_HOURLY_FORECAST_PREFIX + ((i < 10) ? "0" : "") + Integer.toString(i)));
133 for (int i = forecastHours + 1; i <= newForecastHours; i++) {
134 toBeAddedChannels.addAll(createChannelsForGroup(
135 CHANNEL_GROUP_HOURLY_FORECAST_PREFIX + ((i < 10) ? "0" : "") + Integer.toString(i),
136 CHANNEL_GROUP_TYPE_ONECALL_HOURLY_FORECAST));
139 forecastHours = newForecastHours;
141 if (forecastDays != newForecastDays) {
142 logger.debug("ForecastDays changed from {} to {}. Rebuilding daily forecast channel groups.",
143 forecastDays, newForecastDays);
144 if (forecastDays > newForecastDays) {
145 if (newForecastDays < 1) {
146 toBeRemovedChannels.addAll(removeChannelsOfGroup(CHANNEL_GROUP_FORECAST_TODAY));
148 if (newForecastDays < 2) {
149 toBeRemovedChannels.addAll(removeChannelsOfGroup(CHANNEL_GROUP_FORECAST_TOMORROW));
151 for (int i = newForecastDays; i < forecastDays; ++i) {
152 toBeRemovedChannels.addAll(
153 removeChannelsOfGroup(CHANNEL_GROUP_DAILY_FORECAST_PREFIX + Integer.toString(i)));
156 if (forecastDays == 0 && newForecastDays > 0) {
157 toBeAddedChannels.addAll(createChannelsForGroup(CHANNEL_GROUP_FORECAST_TODAY,
158 CHANNEL_GROUP_TYPE_ONECALL_DAILY_FORECAST));
160 if (forecastDays <= 1 && newForecastDays > 1) {
161 toBeAddedChannels.addAll(createChannelsForGroup(CHANNEL_GROUP_FORECAST_TOMORROW,
162 CHANNEL_GROUP_TYPE_ONECALL_DAILY_FORECAST));
164 for (int i = Math.max(forecastDays, 2); i < newForecastDays; i++) {
165 toBeAddedChannels.addAll(
166 createChannelsForGroup(CHANNEL_GROUP_DAILY_FORECAST_PREFIX + Integer.toString(i),
167 CHANNEL_GROUP_TYPE_ONECALL_DAILY_FORECAST));
170 forecastDays = newForecastDays;
172 logger.debug("toBeRemovedChannels: {}. toBeAddedChannels: {}", toBeRemovedChannels, toBeAddedChannels);
173 ThingBuilder builder = editThing().withoutChannels(toBeRemovedChannels);
174 for (Channel channel : toBeAddedChannels) {
175 builder.withChannel(channel);
177 updateThing(builder.build());
178 updateStatus(ThingStatus.ONLINE);
183 protected boolean requestData(OpenWeatherMapConnection connection)
184 throws OpenWeatherMapCommunicationException, OpenWeatherMapConfigurationException {
185 logger.debug("Update weather and forecast data of thing '{}'.", getThing().getUID());
187 weatherData = connection.getOneCallAPIData(location, forecastMinutes == 0, forecastHours == 0,
190 } catch (JsonSyntaxException e) {
191 logger.debug("JsonSyntaxException occurred during execution: {}", e.getLocalizedMessage(), e);
197 protected void updateChannel(ChannelUID channelUID) {
198 String channelGroupId = channelUID.getGroupId();
199 logger.debug("OneCallHandler: updateChannel {}, groupID {}", channelUID, channelGroupId);
200 switch (channelGroupId) {
201 case CHANNEL_GROUP_ONECALL_CURRENT:
202 updateCurrentChannel(channelUID);
204 case CHANNEL_GROUP_ONECALL_TODAY:
205 updateDailyForecastChannel(channelUID, 0);
207 case CHANNEL_GROUP_ONECALL_TOMORROW:
208 updateDailyForecastChannel(channelUID, 1);
212 Matcher hourlyForecastMatcher = CHANNEL_GROUP_HOURLY_FORECAST_PREFIX_PATTERN.matcher(channelGroupId);
213 if (hourlyForecastMatcher.find() && (i = Integer.parseInt(hourlyForecastMatcher.group(1))) >= 1
215 updateHourlyForecastChannel(channelUID, (i - 1));
218 Matcher dailyForecastMatcher = CHANNEL_GROUP_DAILY_FORECAST_PREFIX_PATTERN.matcher(channelGroupId);
219 if (dailyForecastMatcher.find() && (i = Integer.parseInt(dailyForecastMatcher.group(1))) >= 1
221 updateDailyForecastChannel(channelUID, i);
224 Matcher minutelyForecastMatcher = CHANNEL_GROUP_MINUTELY_FORECAST_PREFIX_PATTERN
225 .matcher(channelGroupId);
226 if (minutelyForecastMatcher.find() && (i = Integer.parseInt(minutelyForecastMatcher.group(1))) >= 1
228 updateMinutelyForecastChannel(channelUID, i - 1);
237 * Update the channel from the last OpenWeatherMap data retrieved.
239 * @param channelUID the id identifying the channel to be updated
241 private void updateCurrentChannel(ChannelUID channelUID) {
242 String channelId = channelUID.getIdWithoutGroup();
243 String channelGroupId = channelUID.getGroupId();
244 OpenWeatherMapOneCallAPIData localWeatherData = weatherData;
245 if (localWeatherData != null) {
246 State state = UnDefType.UNDEF;
248 case CHANNEL_STATION_LOCATION:
249 state = getPointTypeState(localWeatherData.getLat(), localWeatherData.getLon());
251 case CHANNEL_TIME_STAMP:
252 state = getDateTimeTypeState(localWeatherData.getCurrent().getDt());
254 case CHANNEL_SUNRISE:
255 state = getDateTimeTypeState(localWeatherData.getCurrent().getSunrise());
258 state = getDateTimeTypeState(localWeatherData.getCurrent().getSunset());
260 case CHANNEL_CONDITION:
261 if (!localWeatherData.getCurrent().getWeather().isEmpty()) {
262 state = getStringTypeState(localWeatherData.getCurrent().getWeather().get(0).getDescription());
265 case CHANNEL_CONDITION_ID:
266 if (!localWeatherData.getCurrent().getWeather().isEmpty()) {
267 state = getStringTypeState(
268 Integer.toString(localWeatherData.getCurrent().getWeather().get(0).getId()));
271 case CHANNEL_CONDITION_ICON:
272 if (!localWeatherData.getCurrent().getWeather().isEmpty()) {
273 state = getRawTypeState(OpenWeatherMapConnection
274 .getWeatherIcon(localWeatherData.getCurrent().getWeather().get(0).getIcon()));
277 case CHANNEL_CONDITION_ICON_ID:
278 if (!localWeatherData.getCurrent().getWeather().isEmpty()) {
279 state = getStringTypeState(localWeatherData.getCurrent().getWeather().get(0).getIcon());
282 case CHANNEL_TEMPERATURE:
283 state = getQuantityTypeState(localWeatherData.getCurrent().getTemp(), CELSIUS);
285 case CHANNEL_APPARENT_TEMPERATURE:
286 state = getQuantityTypeState(localWeatherData.getCurrent().getFeelsLike(), CELSIUS);
288 case CHANNEL_PRESSURE:
289 state = getQuantityTypeState(localWeatherData.getCurrent().getPressure(), HECTO(PASCAL));
291 case CHANNEL_HUMIDITY:
292 state = getQuantityTypeState(localWeatherData.getCurrent().getHumidity(), PERCENT);
294 case CHANNEL_DEW_POINT:
295 state = getQuantityTypeState(localWeatherData.getCurrent().getDewPoint(), CELSIUS);
297 case CHANNEL_WIND_SPEED:
298 state = getQuantityTypeState(localWeatherData.getCurrent().getWindSpeed(), METRE_PER_SECOND);
300 case CHANNEL_WIND_DIRECTION:
301 state = getQuantityTypeState(localWeatherData.getCurrent().getWindDeg(), DEGREE_ANGLE);
303 case CHANNEL_GUST_SPEED:
304 state = getQuantityTypeState(localWeatherData.getCurrent().getWindGust(), METRE_PER_SECOND);
306 case CHANNEL_CLOUDINESS:
307 state = getQuantityTypeState(localWeatherData.getCurrent().getClouds(), PERCENT);
309 case CHANNEL_UVINDEX:
310 state = getDecimalTypeState(localWeatherData.getCurrent().getUvi());
313 Rain rain = localWeatherData.getCurrent().getRain();
314 state = getQuantityTypeState(rain == null ? 0 : rain.get1h(), MILLI(METRE));
317 Snow snow = localWeatherData.getCurrent().getSnow();
318 state = getQuantityTypeState(snow == null ? 0 : snow.get1h(), MILLI(METRE));
320 case CHANNEL_VISIBILITY:
322 State tempstate = new QuantityType<>(localWeatherData.getCurrent().getVisibility(), METRE)
323 .toUnit(KILO(METRE));
324 state = (tempstate == null ? state : tempstate);
327 // This should not happen
328 logger.warn("Unknown channel id {} in onecall current weather data", channelId);
331 logger.debug("Update channel '{}' of group '{}' with new state '{}'.", channelId, channelGroupId, state);
332 updateState(channelUID, state);
334 logger.debug("No weather data available to update channel '{}' of group '{}'.", channelId, channelGroupId);
338 private void updateMinutelyForecastChannel(ChannelUID channelUID, int count) {
339 String channelId = channelUID.getIdWithoutGroup();
340 String channelGroupId = channelUID.getGroupId();
341 OpenWeatherMapOneCallAPIData localWeatherData = weatherData;
342 if (forecastMinutes == 0) {
344 "Can't update channel group {} because forecastMinutes is set to '0'. Please adjust config accordingly",
348 if (localWeatherData != null && localWeatherData.getMinutely().size() > count) {
349 org.openhab.binding.openweathermap.internal.dto.onecall.Minutely forecastData = localWeatherData
350 .getMinutely().get(count);
351 State state = UnDefType.UNDEF;
353 case CHANNEL_TIME_STAMP:
354 state = getDateTimeTypeState(forecastData.getDt());
356 case CHANNEL_PRECIPITATION:
357 double precipitation = forecastData.getPrecipitation();
358 state = getQuantityTypeState(precipitation, MILLI(METRE));
361 // This should not happen
362 logger.warn("Unknown channel id {} in onecall minutely weather data", channelId);
365 logger.debug("Update channel '{}' of group '{}' with new state '{}'.", channelId, channelGroupId, state);
366 updateState(channelUID, state);
368 logger.debug("No weather data available to update channel '{}' of group '{}'.", channelId, channelGroupId);
373 * Update the channel from the last OpenWeatherMap data retrieved.
375 * @param channelUID the id identifying the channel to be updated
376 * @param count the number of the hour referenced by the channel
378 private void updateHourlyForecastChannel(ChannelUID channelUID, int count) {
379 String channelId = channelUID.getIdWithoutGroup();
380 String channelGroupId = channelUID.getGroupId();
381 if (forecastHours == 0) {
383 "Can't update channel group {} because forecastHours is set to '0'. Please adjust config accordingly",
387 OpenWeatherMapOneCallAPIData localWeatherData = weatherData;
388 if (localWeatherData != null && localWeatherData.getHourly().size() > count) {
389 org.openhab.binding.openweathermap.internal.dto.onecall.Hourly forecastData = localWeatherData.getHourly()
391 State state = UnDefType.UNDEF;
393 case CHANNEL_TIME_STAMP:
394 state = getDateTimeTypeState(forecastData.getDt());
396 case CHANNEL_CONDITION:
397 if (!forecastData.getWeather().isEmpty()) {
398 state = getStringTypeState(forecastData.getWeather().get(0).getDescription());
401 case CHANNEL_CONDITION_ID:
402 if (!forecastData.getWeather().isEmpty()) {
403 state = getStringTypeState(Integer.toString(forecastData.getWeather().get(0).getId()));
406 case CHANNEL_CONDITION_ICON:
407 if (!forecastData.getWeather().isEmpty()) {
408 state = getRawTypeState(
409 OpenWeatherMapConnection.getWeatherIcon(forecastData.getWeather().get(0).getIcon()));
412 case CHANNEL_CONDITION_ICON_ID:
413 if (!forecastData.getWeather().isEmpty()) {
414 state = getStringTypeState(forecastData.getWeather().get(0).getIcon());
417 case CHANNEL_TEMPERATURE:
418 state = getQuantityTypeState(forecastData.getTemp(), CELSIUS);
420 case CHANNEL_APPARENT_TEMPERATURE:
421 state = getQuantityTypeState(forecastData.getFeelsLike(), CELSIUS);
423 case CHANNEL_PRESSURE:
424 state = getQuantityTypeState(forecastData.getPressure(), HECTO(PASCAL));
426 case CHANNEL_HUMIDITY:
427 state = getQuantityTypeState(forecastData.getHumidity(), PERCENT);
429 case CHANNEL_DEW_POINT:
430 state = getQuantityTypeState(forecastData.getDewPoint(), CELSIUS);
432 case CHANNEL_WIND_SPEED:
433 state = getQuantityTypeState(forecastData.getWindSpeed(), METRE_PER_SECOND);
435 case CHANNEL_WIND_DIRECTION:
436 state = getQuantityTypeState(forecastData.getWindDeg(), DEGREE_ANGLE);
438 case CHANNEL_GUST_SPEED:
439 state = getQuantityTypeState(forecastData.getWindGust(), METRE_PER_SECOND);
441 case CHANNEL_CLOUDINESS:
442 state = getQuantityTypeState(forecastData.getClouds(), PERCENT);
444 case CHANNEL_VISIBILITY:
446 State tempstate = new QuantityType<>(localWeatherData.getCurrent().getVisibility(), METRE)
447 .toUnit(KILO(METRE));
448 state = (tempstate == null ? state : tempstate);
449 case CHANNEL_PRECIP_PROBABILITY:
450 state = getQuantityTypeState(forecastData.getPop() * 100.0, PERCENT);
453 Rain rain = forecastData.getRain();
454 state = getQuantityTypeState(rain == null ? 0 : rain.get1h(), MILLI(METRE));
457 Snow snow = forecastData.getSnow();
458 state = getQuantityTypeState(snow == null ? 0 : snow.get1h(), MILLI(METRE));
461 // This should not happen
462 logger.warn("Unknown channel id {} in onecall hourly weather data", channelId);
465 logger.debug("Update channel '{}' of group '{}' with new state '{}'.", channelId, channelGroupId, state);
466 updateState(channelUID, state);
468 logger.debug("No weather data available to update channel '{}' of group '{}'.", channelId, channelGroupId);
473 * Update the channel from the last OpenWeatherMap data retrieved.
475 * @param channelUID the id identifying the channel to be updated
478 private void updateDailyForecastChannel(ChannelUID channelUID, int count) {
479 String channelId = channelUID.getIdWithoutGroup();
480 String channelGroupId = channelUID.getGroupId();
481 if (forecastDays == 0) {
483 "Can't update channel group {} because forecastDays is set to '0'. Please adjust config accordingly",
488 OpenWeatherMapOneCallAPIData localWeatherData = weatherData;
489 if (localWeatherData != null && localWeatherData.getDaily().size() > count) {
490 org.openhab.binding.openweathermap.internal.dto.onecall.Daily forecastData = localWeatherData.getDaily()
492 State state = UnDefType.UNDEF;
496 case CHANNEL_TIME_STAMP:
497 state = getDateTimeTypeState(forecastData.getDt());
499 case CHANNEL_SUNRISE:
500 state = getDateTimeTypeState(forecastData.getSunrise());
503 state = getDateTimeTypeState(forecastData.getSunset());
505 case CHANNEL_CONDITION:
506 if (!forecastData.getWeather().isEmpty()) {
507 state = getStringTypeState(forecastData.getWeather().get(0).getDescription());
510 case CHANNEL_CONDITION_ID:
511 if (!forecastData.getWeather().isEmpty()) {
512 state = getStringTypeState(Integer.toString(forecastData.getWeather().get(0).getId()));
515 case CHANNEL_CONDITION_ICON:
516 if (!forecastData.getWeather().isEmpty()) {
517 state = getRawTypeState(
518 OpenWeatherMapConnection.getWeatherIcon(forecastData.getWeather().get(0).getIcon()));
521 case CHANNEL_CONDITION_ICON_ID:
522 if (!forecastData.getWeather().isEmpty()) {
523 state = getStringTypeState(forecastData.getWeather().get(0).getIcon());
526 case CHANNEL_MIN_TEMPERATURE:
527 temp = forecastData.getTemp();
529 state = getQuantityTypeState(temp.getMin(), CELSIUS);
532 case CHANNEL_MAX_TEMPERATURE:
533 temp = forecastData.getTemp();
535 state = getQuantityTypeState(temp.getMax(), CELSIUS);
538 case CHANNEL_MORNING_TEMPERATURE:
539 temp = forecastData.getTemp();
541 state = getQuantityTypeState(temp.getMorn(), CELSIUS);
544 case CHANNEL_DAY_TEMPERATURE:
545 temp = forecastData.getTemp();
547 state = getQuantityTypeState(temp.getDay(), CELSIUS);
550 case CHANNEL_EVENING_TEMPERATURE:
551 temp = forecastData.getTemp();
553 state = getQuantityTypeState(temp.getEve(), CELSIUS);
556 case CHANNEL_NIGHT_TEMPERATURE:
557 temp = forecastData.getTemp();
559 state = getQuantityTypeState(temp.getNight(), CELSIUS);
563 case CHANNEL_APPARENT_DAY:
564 feelsLike = forecastData.getFeelsLike();
565 if (feelsLike != null) {
566 state = getQuantityTypeState(feelsLike.getDay(), CELSIUS);
569 case CHANNEL_APPARENT_MORNING:
570 feelsLike = forecastData.getFeelsLike();
571 if (feelsLike != null) {
572 state = getQuantityTypeState(feelsLike.getMorn(), CELSIUS);
575 case CHANNEL_APPARENT_EVENING:
576 feelsLike = forecastData.getFeelsLike();
577 if (feelsLike != null) {
578 state = getQuantityTypeState(feelsLike.getEve(), CELSIUS);
581 case CHANNEL_APPARENT_NIGHT:
582 feelsLike = forecastData.getFeelsLike();
583 if (feelsLike != null) {
584 state = getQuantityTypeState(feelsLike.getNight(), CELSIUS);
587 case CHANNEL_PRESSURE:
588 state = getQuantityTypeState(forecastData.getPressure(), HECTO(PASCAL));
590 case CHANNEL_HUMIDITY:
591 state = getQuantityTypeState(forecastData.getHumidity(), PERCENT);
593 case CHANNEL_WIND_SPEED:
594 state = getQuantityTypeState(forecastData.getWindSpeed(), METRE_PER_SECOND);
596 case CHANNEL_WIND_DIRECTION:
597 state = getQuantityTypeState(forecastData.getWindDeg(), DEGREE_ANGLE);
599 case CHANNEL_GUST_SPEED:
600 state = getQuantityTypeState(forecastData.getWindGust(), METRE_PER_SECOND);
602 case CHANNEL_CLOUDINESS:
603 state = getQuantityTypeState(forecastData.getClouds(), PERCENT);
605 case CHANNEL_DEW_POINT:
606 state = getQuantityTypeState(forecastData.getDewPoint(), CELSIUS);
608 case CHANNEL_UVINDEX:
609 state = getDecimalTypeState(forecastData.getUvi());
611 case CHANNEL_VISIBILITY:
613 State tempstate = new QuantityType<>(localWeatherData.getCurrent().getVisibility(), METRE)
614 .toUnit(KILO(METRE));
615 state = (tempstate == null ? state : tempstate);
616 case CHANNEL_PRECIP_PROBABILITY:
617 state = getQuantityTypeState(forecastData.getPop() * 100.0, PERCENT);
620 state = getQuantityTypeState(forecastData.getRain(), MILLI(METRE));
623 state = getQuantityTypeState(forecastData.getSnow(), MILLI(METRE));
626 // This should not happen
627 logger.warn("Unknown channel id {} in onecall daily weather data", channelId);
630 logger.debug("Update channel '{}' of group '{}' with new state '{}'.", channelId, channelGroupId, state);
631 updateState(channelUID, state);
633 logger.debug("No weather data available to update channel '{}' of group '{}'.", channelId, channelGroupId);