From 748115857f80c743138ad268d2ab611fa52e9576 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20L=27hopital?= Date: Sat, 4 Dec 2021 16:55:48 +0100 Subject: [PATCH] [Sagercaster] Reintroducing timestamp channel (#11665) [Sagercaster] Reintroducing timestamp channel Signed-off-by: clinique Signed-off-by: Michael Schmidt --- .../org.openhab.binding.sagercaster/README.md | 9 +- .../internal/SagerCasterBindingConstants.java | 2 + .../internal/SagerCasterHandlerFactory.java | 1 + .../internal/caster/SagerPrediction.java | 49 ++++++ .../{ => caster}/SagerWeatherCaster.java | 73 ++++----- .../internal/handler/SagerCasterHandler.java | 141 ++++++++---------- .../OH-INF/i18n/sagercaster.properties | 24 +-- .../OH-INF/i18n/sagercaster_fr.properties | 2 + .../resources/OH-INF/thing/thing-types.xml | 18 ++- 9 files changed, 189 insertions(+), 130 deletions(-) create mode 100644 bundles/org.openhab.binding.sagercaster/src/main/java/org/openhab/binding/sagercaster/internal/caster/SagerPrediction.java rename bundles/org.openhab.binding.sagercaster/src/main/java/org/openhab/binding/sagercaster/internal/{ => caster}/SagerWeatherCaster.java (89%) diff --git a/bundles/org.openhab.binding.sagercaster/README.md b/bundles/org.openhab.binding.sagercaster/README.md index 485b76918219..c9eadf8a1675 100644 --- a/bundles/org.openhab.binding.sagercaster/README.md +++ b/bundles/org.openhab.binding.sagercaster/README.md @@ -6,7 +6,8 @@ The Sager Weathercaster is a scientific instrument for accurate prediction of th * To operate, this binding will need to use channel values provided by other means (e.g. Weather Binding, Netatmo, a 1-Wire personal weather station...) -* This binding buffers readings for some hours before producing weather forecasts(wind direction and sea level pressure). SagerWeatherCaster needs an observation period of minimum 6 hours. +* This binding buffers readings for some hours before producing weather forecasts(wind direction and sea level pressure). +SagerWeatherCaster needs an observation period of minimum 6 hours. For these reasons, this binding is not a binding in the usual sense. @@ -24,9 +25,11 @@ The binding itself does not require any configuration. | Name | Type | Description | |--------------------|----------|--------------------------------------------------------------------------| -| location | Location | Latitude and longitude of the desired weather forecast. | +| location (*) | Location | Latitude and longitude of the desired weather forecast. | | observation-period | int | Minimum delay (in hours) before producing forecasts. Defaulted to 6. | +(*) Only latitude is used by the algorithm. + ## Channels The binding will use some input channels, that can be configured directly with profiles (sample below). @@ -41,6 +44,8 @@ The binding will use some input channels, that can be configured directly with p | wind-speed-beaufort | input |Number | Wind speed expressed using the Beaufort scale | | pressure | input |Number:Pressure | Sea level pressure | | wind-angle | input |Number:Angle | Wind direction | +| temperature | input |Number:Temperature | Outside temperature | +| timestamp | output |DateTime | Timestamp of the last forecast update | | forecast | output |String | Description of the weather forecast | | velocity | output |String | Description of the expected wind evolution | | velocity-beaufort | output |Number | Expected wind evolution using the Beaufort scale | diff --git a/bundles/org.openhab.binding.sagercaster/src/main/java/org/openhab/binding/sagercaster/internal/SagerCasterBindingConstants.java b/bundles/org.openhab.binding.sagercaster/src/main/java/org/openhab/binding/sagercaster/internal/SagerCasterBindingConstants.java index f4865f6121bf..7b1eef621478 100644 --- a/bundles/org.openhab.binding.sagercaster/src/main/java/org/openhab/binding/sagercaster/internal/SagerCasterBindingConstants.java +++ b/bundles/org.openhab.binding.sagercaster/src/main/java/org/openhab/binding/sagercaster/internal/SagerCasterBindingConstants.java @@ -48,6 +48,8 @@ public class SagerCasterBindingConstants { public static final String CHANNEL_WINDEVOLUTION = "wind-evolution"; public static final String CHANNEL_PRESSURETREND = "pressure-trend"; public static final String CHANNEL_TEMPERATURETREND = "temperature-trend"; + public static final String CHANNEL_TIMESTAMP = "timestamp"; + // Input channel ids public static final String CHANNEL_CLOUDINESS = "cloudiness"; public static final String CHANNEL_IS_RAINING = "is-raining"; diff --git a/bundles/org.openhab.binding.sagercaster/src/main/java/org/openhab/binding/sagercaster/internal/SagerCasterHandlerFactory.java b/bundles/org.openhab.binding.sagercaster/src/main/java/org/openhab/binding/sagercaster/internal/SagerCasterHandlerFactory.java index aa8b7ff7998f..ad9f8c644836 100644 --- a/bundles/org.openhab.binding.sagercaster/src/main/java/org/openhab/binding/sagercaster/internal/SagerCasterHandlerFactory.java +++ b/bundles/org.openhab.binding.sagercaster/src/main/java/org/openhab/binding/sagercaster/internal/SagerCasterHandlerFactory.java @@ -19,6 +19,7 @@ import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; +import org.openhab.binding.sagercaster.internal.caster.SagerWeatherCaster; import org.openhab.binding.sagercaster.internal.handler.SagerCasterHandler; import org.openhab.core.thing.Thing; import org.openhab.core.thing.ThingTypeUID; diff --git a/bundles/org.openhab.binding.sagercaster/src/main/java/org/openhab/binding/sagercaster/internal/caster/SagerPrediction.java b/bundles/org.openhab.binding.sagercaster/src/main/java/org/openhab/binding/sagercaster/internal/caster/SagerPrediction.java new file mode 100644 index 000000000000..dae13ba4e85d --- /dev/null +++ b/bundles/org.openhab.binding.sagercaster/src/main/java/org/openhab/binding/sagercaster/internal/caster/SagerPrediction.java @@ -0,0 +1,49 @@ +/** + * Copyright (c) 2010-2021 Contributors to the openHAB project + * + * See the NOTICE file(s) distributed with this work for additional + * information. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0 + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.openhab.binding.sagercaster.internal.caster; + +import org.eclipse.jdt.annotation.NonNullByDefault; + +/** + * This class holds the result of the SagerCaster algorithm + * + * @author Gaël L'hopital - Initial contribution + */ +@NonNullByDefault +public class SagerPrediction { + private final String prediction; + + public SagerPrediction(String sagerCode) { + this.prediction = sagerCode; + } + + public String getSagerCode() { + return prediction; + } + + public String getForecast() { + return Character.toString(prediction.charAt(0)); + } + + public String getWindVelocity() { + return Character.toString(prediction.charAt(1)); + } + + public String getWindDirection() { + return Character.toString(prediction.charAt(2)); + } + + public String getWindDirection2() { + return prediction.length() > 3 ? Character.toString(prediction.charAt(3)) : SagerWeatherCaster.UNDEF; + } +} diff --git a/bundles/org.openhab.binding.sagercaster/src/main/java/org/openhab/binding/sagercaster/internal/SagerWeatherCaster.java b/bundles/org.openhab.binding.sagercaster/src/main/java/org/openhab/binding/sagercaster/internal/caster/SagerWeatherCaster.java similarity index 89% rename from bundles/org.openhab.binding.sagercaster/src/main/java/org/openhab/binding/sagercaster/internal/SagerWeatherCaster.java rename to bundles/org.openhab.binding.sagercaster/src/main/java/org/openhab/binding/sagercaster/internal/caster/SagerWeatherCaster.java index 21f05dc296a8..fbaa8eaac3c8 100644 --- a/bundles/org.openhab.binding.sagercaster/src/main/java/org/openhab/binding/sagercaster/internal/SagerWeatherCaster.java +++ b/bundles/org.openhab.binding.sagercaster/src/main/java/org/openhab/binding/sagercaster/internal/caster/SagerWeatherCaster.java @@ -53,7 +53,7 @@ * 378 possible forecasts determined from 4996 dial codes. */ -package org.openhab.binding.sagercaster.internal; +package org.openhab.binding.sagercaster.internal.caster; import java.io.IOException; import java.io.InputStream; @@ -76,6 +76,7 @@ @Component(service = SagerWeatherCaster.class, scope = ServiceScope.SINGLETON) @NonNullByDefault public class SagerWeatherCaster { + public final static String UNDEF = "-"; // Northern Polar Zone & Northern Tropical Zone private final static String[] NPZDIRECTIONS = { "S", "SW", "W", "NW", "N", "NE", "E", "SE" }; // Northern Temperate Zone @@ -88,7 +89,7 @@ public class SagerWeatherCaster { private final Logger logger = LoggerFactory.getLogger(SagerWeatherCaster.class); private final Properties forecaster = new Properties(); - private Optional prevision = Optional.empty(); + private Optional prevision = Optional.empty(); private String[] usedDirections = NTZDIRECTIONS; // Defaulted to Northern Zone private int currentBearing = -1; @@ -238,7 +239,7 @@ private String getCompass() { private void updatePrediction() { int zWind = Arrays.asList(usedDirections).indexOf(getCompass()); - String d1 = "-"; + String d1 = UNDEF; switch (zWind) { case 0: if (windEvolution == 3) { @@ -319,39 +320,27 @@ private void updatePrediction() { } String forecast = forecaster.getProperty( d1 + String.valueOf(sagerPressure) + String.valueOf(pressureEvolution) + String.valueOf(nubes)); - prevision = (forecast != null) ? Optional.of(new Prevision(forecast)) : Optional.empty(); + prevision = Optional.ofNullable(forecast != null ? new SagerPrediction(forecast) : null); } public String getForecast() { - if (prevision.isPresent()) { - char forecast = prevision.get().zForecast; - return Character.toString(forecast); - } - return "-"; + return prevision.map(p -> p.getForecast()).orElse(UNDEF); } public String getWindVelocity() { - if (prevision.isPresent()) { - char windVelocity = prevision.get().zWindVelocity; - return Character.toString(windVelocity); - } - return "-"; + return prevision.map(p -> p.getWindVelocity()).orElse(UNDEF); } public String getWindDirection() { - if (prevision.isPresent()) { - int direction = prevision.get().zWindDirection; - return String.valueOf(direction); - } - return "-"; + return prevision.map(p -> p.getWindDirection()).orElse(UNDEF); } public String getWindDirection2() { - if (prevision.isPresent()) { - int direction = prevision.get().zWindDirection2; - return String.valueOf(direction); - } - return "-"; + return prevision.map(p -> p.getWindDirection2()).orElse(UNDEF); + } + + public String getSagerCode() { + return prevision.map(p -> p.getSagerCode()).orElse(UNDEF); } public void setLatitude(double latitude) { @@ -370,17 +359,31 @@ public void setLatitude(double latitude) { } } - private class Prevision { - public final char zForecast; - public final char zWindVelocity; - public final int zWindDirection; - public final int zWindDirection2; - - public Prevision(String forecast) { - zForecast = forecast.charAt(0); - zWindVelocity = forecast.charAt(1); - zWindDirection = Character.getNumericValue(forecast.charAt(2)); - zWindDirection2 = (forecast.length() > 3) ? Character.getNumericValue(forecast.charAt(3)) : -1; + public int getPredictedBeaufort() { + int result = currentBeaufort; + switch (getWindVelocity()) { + case "N": + result += 1; + break; + case "F": + result = 4; + break; + case "S": + result = 6; + break; + case "G": + result = 8; + break; + case "W": + result = 10; + break; + case "H": + result = 12; + break; + case "D": + result -= 1; + break; } + return result; } } diff --git a/bundles/org.openhab.binding.sagercaster/src/main/java/org/openhab/binding/sagercaster/internal/handler/SagerCasterHandler.java b/bundles/org.openhab.binding.sagercaster/src/main/java/org/openhab/binding/sagercaster/internal/handler/SagerCasterHandler.java index 79065e6ac662..b2e91af13743 100644 --- a/bundles/org.openhab.binding.sagercaster/src/main/java/org/openhab/binding/sagercaster/internal/handler/SagerCasterHandler.java +++ b/bundles/org.openhab.binding.sagercaster/src/main/java/org/openhab/binding/sagercaster/internal/handler/SagerCasterHandler.java @@ -16,9 +16,9 @@ import static org.openhab.core.library.unit.MetricPrefix.HECTO; import java.math.BigDecimal; +import java.time.ZonedDateTime; import java.util.ArrayList; import java.util.List; -import java.util.Optional; import java.util.concurrent.TimeUnit; import javax.measure.quantity.Angle; @@ -26,8 +26,9 @@ import javax.measure.quantity.Temperature; import org.eclipse.jdt.annotation.NonNullByDefault; -import org.openhab.binding.sagercaster.internal.SagerWeatherCaster; import org.openhab.binding.sagercaster.internal.WindDirectionStateDescriptionProvider; +import org.openhab.binding.sagercaster.internal.caster.SagerWeatherCaster; +import org.openhab.core.library.types.DateTimeType; import org.openhab.core.library.types.DecimalType; import org.openhab.core.library.types.OnOffType; import org.openhab.core.library.types.QuantityType; @@ -36,6 +37,7 @@ import org.openhab.core.thing.ChannelUID; import org.openhab.core.thing.Thing; import org.openhab.core.thing.ThingStatus; +import org.openhab.core.thing.ThingUID; import org.openhab.core.thing.binding.BaseThingHandler; import org.openhab.core.types.Command; import org.openhab.core.types.RefreshType; @@ -58,11 +60,12 @@ public class SagerCasterHandler extends BaseThingHandler { private final WindDirectionStateDescriptionProvider stateDescriptionProvider; - private final ExpiringMap> pressureCache = new ExpiringMap<>(); - private final ExpiringMap> temperatureCache = new ExpiringMap<>(); - private final ExpiringMap> bearingCache = new ExpiringMap<>(); + private final ExpiringMap pressureCache = new ExpiringMap<>(); + private final ExpiringMap temperatureCache = new ExpiringMap<>(); + private final ExpiringMap bearingCache = new ExpiringMap<>(); - private int currentTemp = 0; + private double currentTemp = 0; + private String currentSagerCode = SagerWeatherCaster.UNDEF; public SagerCasterHandler(Thing thing, WindDirectionStateDescriptionProvider stateDescriptionProvider, SagerWeatherCaster sagerWeatherCaster) { @@ -73,15 +76,17 @@ public SagerCasterHandler(Thing thing, WindDirectionStateDescriptionProvider sta @Override public void initialize() { - String location = (String) getConfig().get(CONFIG_LOCATION); int observationPeriod = ((BigDecimal) getConfig().get(CONFIG_PERIOD)).intValue(); - String latitude = location.split(",")[0]; - sagerWeatherCaster.setLatitude(Double.parseDouble(latitude)); long period = TimeUnit.HOURS.toMillis(observationPeriod); pressureCache.setObservationPeriod(period); bearingCache.setObservationPeriod(period); temperatureCache.setObservationPeriod(period); + + String location = (String) getConfig().get(CONFIG_LOCATION); + String latitude = location.split(",")[0]; + sagerWeatherCaster.setLatitude(Double.parseDouble(latitude)); defineWindDirectionStateDescriptions(); + updateStatus(ThingStatus.ONLINE); } @@ -95,10 +100,9 @@ private void defineWindDirectionStateDescriptions() { } options.add(new StateOption("9", "Shifting / Variable winds")); - stateDescriptionProvider.setStateOptions(new ChannelUID(getThing().getUID(), GROUP_OUTPUT, CHANNEL_WINDFROM), - options); - stateDescriptionProvider.setStateOptions(new ChannelUID(getThing().getUID(), GROUP_OUTPUT, CHANNEL_WINDTO), - options); + ThingUID thingUID = getThing().getUID(); + stateDescriptionProvider.setStateOptions(new ChannelUID(thingUID, GROUP_OUTPUT, CHANNEL_WINDFROM), options); + stateDescriptionProvider.setStateOptions(new ChannelUID(thingUID, GROUP_OUTPUT, CHANNEL_WINDTO), options); } @Override @@ -109,7 +113,7 @@ public void handleCommand(ChannelUID channelUID, Command command) { String id = channelUID.getIdWithoutGroup(); switch (id) { case CHANNEL_CLOUDINESS: - logger.debug("Octa cloud level changed, updating forecast"); + logger.debug("Cloud level changed, updating forecast"); if (command instanceof QuantityType) { QuantityType cloudiness = (QuantityType) command; scheduler.submit(() -> { @@ -127,26 +131,17 @@ public void handleCommand(ChannelUID channelUID, Command command) { postNewForecast(); }); } else { - logger.debug("Channel '{}' can only accept Switch type commands.", channelUID); + logger.debug("Channel '{}' accepts Switch commands.", channelUID); } break; case CHANNEL_RAIN_QTTY: logger.debug("Rain status updated, updating forecast"); if (command instanceof QuantityType) { - QuantityType newQtty = (QuantityType) command; - scheduler.submit(() -> { - sagerWeatherCaster.setRaining(newQtty.doubleValue() > 0); - postNewForecast(); - }); + updateRain((QuantityType) command); } else if (command instanceof DecimalType) { - DecimalType newQtty = (DecimalType) command; - scheduler.submit(() -> { - sagerWeatherCaster.setRaining(newQtty.doubleValue() > 0); - postNewForecast(); - }); + updateRain((DecimalType) command); } else { - logger.debug("Channel '{}' can accept Number, Number:Speed, Number:Length type commands.", - channelUID); + logger.debug("Channel '{}' accepts Number, Number:(Speed|Length) commands.", channelUID); } break; case CHANNEL_WIND_SPEED: @@ -165,12 +160,13 @@ public void handleCommand(ChannelUID channelUID, Command command) { logger.debug("Sea-level pressure updated, updating forecast"); if (command instanceof QuantityType) { @SuppressWarnings("unchecked") - QuantityType newPressure = ((QuantityType) command) + QuantityType pressQtty = ((QuantityType) command) .toUnit(HECTO(SIUnits.PASCAL)); - if (newPressure != null) { - pressureCache.put(newPressure); - pressureCache.getAgedValue().ifPresentOrElse(pressure -> scheduler.submit(() -> { - sagerWeatherCaster.setPressure(newPressure.doubleValue(), pressure.doubleValue()); + if (pressQtty != null) { + double newPressureValue = pressQtty.doubleValue(); + pressureCache.put(newPressureValue); + pressureCache.getAgedValue().ifPresentOrElse(oldPressure -> scheduler.submit(() -> { + sagerWeatherCaster.setPressure(newPressureValue, oldPressure); updateChannelString(GROUP_OUTPUT, CHANNEL_PRESSURETREND, String.valueOf(sagerWeatherCaster.getPressureEvolution())); postNewForecast(); @@ -182,14 +178,13 @@ public void handleCommand(ChannelUID channelUID, Command command) { logger.debug("Temperature updated"); if (command instanceof QuantityType) { @SuppressWarnings("unchecked") - QuantityType newTemperature = ((QuantityType) command) + QuantityType tempQtty = ((QuantityType) command) .toUnit(SIUnits.CELSIUS); - if (newTemperature != null) { - temperatureCache.put(newTemperature); - currentTemp = newTemperature.intValue(); - Optional> agedTemperature = temperatureCache.getAgedValue(); - agedTemperature.ifPresent(temperature -> { - double delta = newTemperature.doubleValue() - temperature.doubleValue(); + if (tempQtty != null) { + currentTemp = tempQtty.doubleValue(); + temperatureCache.put(currentTemp); + temperatureCache.getAgedValue().ifPresent(oldTemperature -> { + double delta = currentTemp - oldTemperature; String trend = (delta > 3) ? "1" : (delta > 0.3) ? "2" : (delta > -0.3) ? "3" : (delta > -3) ? "4" : "5"; updateChannelString(GROUP_OUTPUT, CHANNEL_TEMPERATURETREND, trend); @@ -201,12 +196,12 @@ public void handleCommand(ChannelUID channelUID, Command command) { logger.debug("Updated wind direction, updating forecast"); if (command instanceof QuantityType) { @SuppressWarnings("unchecked") - QuantityType newAngle = (QuantityType) command; - bearingCache.put(newAngle); - Optional> agedAngle = bearingCache.getAgedValue(); - agedAngle.ifPresent(angle -> { + QuantityType angleQtty = (QuantityType) command; + int newAngleValue = angleQtty.intValue(); + bearingCache.put(newAngleValue); + bearingCache.getAgedValue().ifPresent(oldAngle -> { scheduler.submit(() -> { - sagerWeatherCaster.setBearing(newAngle.intValue(), angle.intValue()); + sagerWeatherCaster.setBearing(newAngleValue, oldAngle); updateChannelString(GROUP_OUTPUT, CHANNEL_WINDEVOLUTION, String.valueOf(sagerWeatherCaster.getWindEvolution())); postNewForecast(); @@ -220,42 +215,36 @@ public void handleCommand(ChannelUID channelUID, Command command) { } } + private void updateRain(Number newQtty) { + scheduler.submit(() -> { + sagerWeatherCaster.setRaining(newQtty.doubleValue() > 0); + postNewForecast(); + }); + } + private void postNewForecast() { - String forecast = sagerWeatherCaster.getForecast(); - // Sharpens forecast if current temp is below 2 degrees, likely to be flurries rather than shower - forecast += SHOWERS.contains(forecast) ? (currentTemp > 2) ? "1" : "2" : ""; + String newSagerCode = sagerWeatherCaster.getSagerCode(); + if (!newSagerCode.equals(currentSagerCode)) { + logger.debug("Sager prediction changed to {}", newSagerCode); + currentSagerCode = newSagerCode; + updateChannelTimeStamp(GROUP_OUTPUT, CHANNEL_TIMESTAMP, ZonedDateTime.now()); + String forecast = sagerWeatherCaster.getForecast(); + // Sharpens forecast if current temp is below 2 degrees, likely to be flurries rather than shower + forecast += SHOWERS.contains(forecast) ? (currentTemp > 2) ? "1" : "2" : ""; - updateChannelString(GROUP_OUTPUT, CHANNEL_FORECAST, forecast); - updateChannelString(GROUP_OUTPUT, CHANNEL_WINDFROM, sagerWeatherCaster.getWindDirection()); - updateChannelString(GROUP_OUTPUT, CHANNEL_WINDTO, sagerWeatherCaster.getWindDirection2()); + updateChannelString(GROUP_OUTPUT, CHANNEL_FORECAST, forecast); + updateChannelString(GROUP_OUTPUT, CHANNEL_WINDFROM, sagerWeatherCaster.getWindDirection()); + updateChannelString(GROUP_OUTPUT, CHANNEL_WINDTO, sagerWeatherCaster.getWindDirection2()); + updateChannelString(GROUP_OUTPUT, CHANNEL_VELOCITY, sagerWeatherCaster.getWindVelocity()); + updateChannelDecimal(GROUP_OUTPUT, CHANNEL_VELOCITY_BEAUFORT, sagerWeatherCaster.getPredictedBeaufort()); + } + } - String velocity = sagerWeatherCaster.getWindVelocity(); - updateChannelString(GROUP_OUTPUT, CHANNEL_VELOCITY, velocity); - int predictedBeaufort = sagerWeatherCaster.getBeaufort(); - switch (velocity) { - case "N": - predictedBeaufort += 1; - break; - case "F": - predictedBeaufort = 4; - break; - case "S": - predictedBeaufort = 6; - break; - case "G": - predictedBeaufort = 8; - break; - case "W": - predictedBeaufort = 10; - break; - case "H": - predictedBeaufort = 12; - break; - case "D": - predictedBeaufort -= 1; - break; + private void updateChannelTimeStamp(String group, String channelId, ZonedDateTime zonedDateTime) { + ChannelUID id = new ChannelUID(getThing().getUID(), group, channelId); + if (isLinked(id)) { + updateState(id, new DateTimeType(zonedDateTime)); } - updateChannelDecimal(GROUP_OUTPUT, CHANNEL_VELOCITY_BEAUFORT, predictedBeaufort); } private void updateChannelString(String group, String channelId, String value) { diff --git a/bundles/org.openhab.binding.sagercaster/src/main/resources/OH-INF/i18n/sagercaster.properties b/bundles/org.openhab.binding.sagercaster/src/main/resources/OH-INF/i18n/sagercaster.properties index a8eb7a0716a1..36d25ccac2f6 100644 --- a/bundles/org.openhab.binding.sagercaster/src/main/resources/OH-INF/i18n/sagercaster.properties +++ b/bundles/org.openhab.binding.sagercaster/src/main/resources/OH-INF/i18n/sagercaster.properties @@ -43,6 +43,8 @@ rainingDescription = Is it currently raining ? beaufortLabel = Beaufort beaufortDescription = Wind speed using Beaufort Scale pressureDescription = Barometric pressure at sea level. +timestampChannelLabel = Timestamp +timestampChannelDescription = Timestamp of the last weather forecast update. # channel options forecast0 = Not enough historic data to study pressure evolution, wait a bit ... @@ -52,33 +54,33 @@ forecastC = Fair and cooler forecastD = Unsettled forecastE = Unsettled and warmer forecastF = Unsettled and cooler -forecastG = Increasing cloudiness or overcast followed by Precipitation or showers/Flurries -forecastG1 = Increasing cloudiness or overcast followed by Precipitation or showers -forecastG2 = Increasing cloudiness or overcast followed by Precipitation or Flurries -forecastH = Increasing cloudiness or overcast followed by Precipitation or showers and warmer +forecastG = Increasing cloudiness or overcast followed by precipitation or showers/flurries +forecastG1 = Increasing cloudiness or overcast followed by precipitation or showers +forecastG2 = Increasing cloudiness or overcast followed by precipitation or flurries +forecastH = Increasing cloudiness or overcast followed by precipitation or showers and warmer forecastJ = Showers -forecastK = Showers/Flurries and warmer +forecastK = Showers/flurries and warmer forecastK1 = Showers and warmer forecastK2 = Flurries and warmer -forecastL = Showers/Flurries and cooler +forecastL = Showers/flurries and cooler forecastL1 = Showers and cooler forecastL2 = Flurries and cooler forecastM = Precipitation forecastN = Precipitation and warmer forecastP = Precipitation and turning cooler; then improvement likely in 24 hours -forecastR = Precipitation or showers/Flurries followed by improvement (within 12 hours) +forecastR = Precipitation or showers/flurries followed by improvement (within 12 hours) forecastR1 = Precipitation or showers followed by improvement (within 12 hours) forecastR2 = Precipitation or flurries followed by improvement (within 12 hours) -forecastS = Precipitation or showers/Flurries followed by improvement (within 12 hours) and becoming cooler +forecastS = Precipitation or showers/flurries followed by improvement (within 12 hours) and becoming cooler forecastS1 = Precipitation or showers followed by improvement (within 12 hours) and becoming cooler forecastS2 = Precipitation or flurries followed by improvement (within 12 hours) and becoming cooler -forecastT = Precipitation or showers/Flurries followed by improvement early in period (within 6 hours) +forecastT = Precipitation or showers/flurries followed by improvement early in period (within 6 hours) forecastT1 = Precipitation or showers followed by improvement early in period (within 6 hours) forecastT2 = Precipitation or flurries followed by improvement early in period (within 6 hours) -forecastU = Precipitation or showers/Flurries by improvement early in period (within 6 hours) and becoming cooler +forecastU = Precipitation or showers/flurries by improvement early in period (within 6 hours) and becoming cooler forecastU1 = Precipitation or showers by improvement early in period (within 6 hours) and becoming cooler forecastU2 = Precipitation or flurries by improvement early in period (within 6 hours) and becoming cooler -forecastW = Precipitation or showers/Flurries followed by fair early in period (within 6 hours) and becoming cooler +forecastW = Precipitation or showers/flurries followed by fair early in period (within 6 hours) and becoming cooler forecastW1 = Precipitation or showers followed by fair early in period (within 6 hours) and becoming cooler forecastW2 = Precipitation or flurries followed by fair early in period (within 6 hours) and becoming cooler forecastX = Unsettled followed by fair diff --git a/bundles/org.openhab.binding.sagercaster/src/main/resources/OH-INF/i18n/sagercaster_fr.properties b/bundles/org.openhab.binding.sagercaster/src/main/resources/OH-INF/i18n/sagercaster_fr.properties index 6f6720285e51..557ef119aef0 100644 --- a/bundles/org.openhab.binding.sagercaster/src/main/resources/OH-INF/i18n/sagercaster_fr.properties +++ b/bundles/org.openhab.binding.sagercaster/src/main/resources/OH-INF/i18n/sagercaster_fr.properties @@ -43,6 +43,8 @@ rainingDescription = Pleut-il actuellement ? beaufortLabel = Beaufort beaufortDescription = Force du vent mesurée sur l'échelle Beaufort pressureDescription = Pression barométrique au niveau de la mer. +timestampChannelLabel = Horodatage +timestampChannelDescription = Horodatage de la dernière mise à jour de la prévision météo. # channel options forecast0 = Patientez encore un peu pour une prédiction diff --git a/bundles/org.openhab.binding.sagercaster/src/main/resources/OH-INF/thing/thing-types.xml b/bundles/org.openhab.binding.sagercaster/src/main/resources/OH-INF/thing/thing-types.xml index 60b0c1e7926e..5b372f6988e0 100644 --- a/bundles/org.openhab.binding.sagercaster/src/main/resources/OH-INF/thing/thing-types.xml +++ b/bundles/org.openhab.binding.sagercaster/src/main/resources/OH-INF/thing/thing-types.xml @@ -72,6 +72,7 @@ @text/tempTrendDescription + @@ -163,6 +164,7 @@ String @text/trendDescription + Line @@ -174,19 +176,23 @@ - + DateTime - - @text/timestampDescription - Observation time - + + @text/timestampChannelDescription + Time + + Status + Timestamp + + Number:Dimensionless @text/cloudinessDescription - Clouds + Sun_Clouds