]> git.basschouten.com Git - openhab-addons.git/commitdiff
[SagerCaster] binding internals enhancement (#11295)
authorGaël L'hopital <gael@lhopital.org>
Thu, 21 Oct 2021 19:10:00 +0000 (21:10 +0200)
committerGitHub <noreply@github.com>
Thu, 21 Oct 2021 19:10:00 +0000 (21:10 +0200)
* Added semantic tags
Make it ready for online translation of texts.
Small code improvements

Signed-off-by: Gaël L'hopital <gael@lhopital.org>
* Update sagercaster_fr.properties

* Correcting encoding for DE resource file.

Signed-off-by: clinique <gael@lhopital.org>
* Code review corrections

Signed-off-by: clinique <gael@lhopital.org>
* Still some code refinings

* Corrections following lolodomo feed-backs.

Signed-off-by: clinique <gael@lhopital.org>
* Still some corrections

Signed-off-by: clinique <gael@lhopital.org>
* Enhanced discovery

Signed-off-by: clinique <gael@lhopital.org>
bundles/org.openhab.binding.sagercaster/src/main/java/org/openhab/binding/sagercaster/internal/SagerCasterBindingConstants.java
bundles/org.openhab.binding.sagercaster/src/main/java/org/openhab/binding/sagercaster/internal/SagerCasterHandlerFactory.java
bundles/org.openhab.binding.sagercaster/src/main/java/org/openhab/binding/sagercaster/internal/SagerWeatherCaster.java
bundles/org.openhab.binding.sagercaster/src/main/java/org/openhab/binding/sagercaster/internal/discovery/SagerCasterDiscoveryService.java
bundles/org.openhab.binding.sagercaster/src/main/java/org/openhab/binding/sagercaster/internal/handler/ExpiringMap.java
bundles/org.openhab.binding.sagercaster/src/main/java/org/openhab/binding/sagercaster/internal/handler/SagerCasterHandler.java
bundles/org.openhab.binding.sagercaster/src/main/resources/OH-INF/binding/binding.xml
bundles/org.openhab.binding.sagercaster/src/main/resources/OH-INF/i18n/sagercaster.properties [new file with mode: 0644]
bundles/org.openhab.binding.sagercaster/src/main/resources/OH-INF/i18n/sagercaster_de.properties
bundles/org.openhab.binding.sagercaster/src/main/resources/OH-INF/i18n/sagercaster_fr.properties
bundles/org.openhab.binding.sagercaster/src/main/resources/OH-INF/thing/thing-types.xml

index aacd92956938f58478df568e85a698426d0dca86..f4865f6121bf16bbdd0f13cdd18e4165b0c6e2b0 100644 (file)
@@ -12,6 +12,8 @@
  */
 package org.openhab.binding.sagercaster.internal;
 
+import java.util.Set;
+
 import org.eclipse.jdt.annotation.NonNullByDefault;
 import org.openhab.core.thing.ThingTypeUID;
 
@@ -35,7 +37,6 @@ public class SagerCasterBindingConstants {
     public static final String CONFIG_PERIOD = "observation-period";
 
     // List of all Channel Groups Group Channel ids
-    public static final String GROUP_INPUT = "input";
     public static final String GROUP_OUTPUT = "output";
 
     // Output channel ids
@@ -55,4 +56,8 @@ public class SagerCasterBindingConstants {
     public static final String CHANNEL_TEMPERATURE = "temperature";
     public static final String CHANNEL_PRESSURE = "pressure";
     public static final String CHANNEL_WIND_ANGLE = "wind-angle";
+
+    // Some algorythms constants
+    public final static String FORECAST_PENDING = "0";
+    public final static Set<String> SHOWERS = Set.of("G", "K", "L", "R", "S", "T", "U", "W");
 }
index 9cd79feb9e605da525b6a954388c1b77d92755f5..aa8b7ff7998fd86bdcc9a6647e3dbab70858e19f 100644 (file)
@@ -58,9 +58,8 @@ public class SagerCasterHandlerFactory extends BaseThingHandlerFactory {
     protected @Nullable ThingHandler createHandler(Thing thing) {
         ThingTypeUID thingTypeUID = thing.getThingTypeUID();
 
-        if (thingTypeUID.equals(THING_TYPE_SAGERCASTER)) {
-            return new SagerCasterHandler(thing, stateDescriptionProvider, sagerWeatherCaster);
-        }
-        return null;
+        return thingTypeUID.equals(THING_TYPE_SAGERCASTER)
+                ? new SagerCasterHandler(thing, stateDescriptionProvider, sagerWeatherCaster)
+                : null;
     }
 }
index f629c7ea85a56f1919d4921e25e985831bc160fa..21f05dc296a8bb24746e1460e0157cdcb61d7b4a 100644 (file)
@@ -76,8 +76,6 @@ import org.slf4j.LoggerFactory;
 @Component(service = SagerWeatherCaster.class, scope = ServiceScope.SINGLETON)
 @NonNullByDefault
 public class SagerWeatherCaster {
-    private final Properties forecaster = new Properties();
-
     // Northern Polar Zone & Northern Tropical Zone
     private final static String[] NPZDIRECTIONS = { "S", "SW", "W", "NW", "N", "NE", "E", "SE" };
     // Northern Temperate Zone
@@ -88,9 +86,10 @@ public class SagerWeatherCaster {
     private final static String[] STZDIRECTIONS = { "S", "SE", "E", "NE", "N", "NW", "W", "SW" };
 
     private final Logger logger = LoggerFactory.getLogger(SagerWeatherCaster.class);
+    private final Properties forecaster = new Properties();
 
     private Optional<Prevision> prevision = Optional.empty();
-    private @NonNullByDefault({}) String[] usedDirections;
+    private String[] usedDirections = NTZDIRECTIONS; // Defaulted to Northern Zone
 
     private int currentBearing = -1;
     private int windEvolution = -1; // Whether the wind during the last 6 hours has changed its direction by
@@ -105,9 +104,8 @@ public class SagerWeatherCaster {
 
     @Activate
     public SagerWeatherCaster() {
-        InputStream input = Thread.currentThread().getContextClassLoader()
-                .getResourceAsStream("/sagerForecaster.properties");
-        try {
+        try (InputStream input = Thread.currentThread().getContextClassLoader()
+                .getResourceAsStream("/sagerForecaster.properties")) {
             forecaster.load(input);
         } catch (IOException e) {
             logger.warn("Error during Sager Forecaster startup", e);
@@ -120,9 +118,9 @@ public class SagerWeatherCaster {
 
     public void setBearing(int newBearing, int oldBearing) {
         int windEvol = sagerWindTrend(oldBearing, newBearing);
-        if ((windEvol != this.windEvolution) || (newBearing != currentBearing)) {
-            this.currentBearing = newBearing;
-            this.windEvolution = windEvol;
+        if ((windEvol != windEvolution) || (newBearing != currentBearing)) {
+            currentBearing = newBearing;
+            windEvolution = windEvol;
             updatePrediction();
         }
     }
@@ -130,40 +128,40 @@ public class SagerWeatherCaster {
     public void setPressure(double newPressure, double oldPressure) {
         int newSagerPressure = sagerPressureLevel(newPressure);
         int pressEvol = sagerPressureTrend(newPressure, oldPressure);
-        if ((pressEvol != this.pressureEvolution) || (newSagerPressure != sagerPressure)) {
-            this.sagerPressure = newSagerPressure;
-            this.pressureEvolution = pressEvol;
+        if ((pressEvol != pressureEvolution) || (newSagerPressure != sagerPressure)) {
+            sagerPressure = newSagerPressure;
+            pressureEvolution = pressEvol;
             updatePrediction();
         }
     }
 
     public void setCloudLevel(int cloudiness) {
-        this.cloudLevel = cloudiness;
+        cloudLevel = cloudiness;
         sagerNubesUpdate();
     }
 
-    public void setRaining(boolean raining) {
-        this.raining = raining;
+    public void setRaining(boolean isRaining) {
+        raining = isRaining;
         sagerNubesUpdate();
     }
 
     public void setBeaufort(int beaufortIndex) {
         if (currentBeaufort != beaufortIndex) {
-            this.currentBeaufort = beaufortIndex;
+            currentBeaufort = beaufortIndex;
             updatePrediction();
         }
     }
 
     public int getBeaufort() {
-        return this.currentBeaufort;
+        return currentBeaufort;
     }
 
     public int getWindEvolution() {
-        return this.windEvolution;
+        return windEvolution;
     }
 
     public int getPressureEvolution() {
-        return this.pressureEvolution;
+        return pressureEvolution;
     }
 
     private void sagerNubesUpdate() {
@@ -182,50 +180,43 @@ public class SagerWeatherCaster {
             result = 5; // raining
         }
         if (result != nubes) {
-            this.nubes = result;
+            nubes = result;
             updatePrediction();
         }
     }
 
     private static int sagerPressureLevel(double current) {
-        int result = 1;
         if (current > 1029.46) {
-            result = 1;
+            return 1;
         } else if (current > 1019.3) {
-            result = 2;
+            return 2;
         } else if (current > 1012.53) {
-            result = 3;
+            return 3;
         } else if (current > 1005.76) {
-            result = 4;
+            return 4;
         } else if (current > 999) {
-            result = 5;
+            return 5;
         } else if (current > 988.8) {
-            result = 6;
+            return 6;
         } else if (current > 975.28) {
-            result = 7;
-        } else {
-            result = 8;
+            return 7;
         }
-        return result;
+        return 8;
     }
 
     private static int sagerPressureTrend(double current, double historic) {
         double evol = current - historic;
-        int result = 0;
 
         if (evol > 1.4) {
-            result = 1; // Rising Rapidly
+            return 1; // Rising Rapidly
         } else if (evol > 0.68) {
-            result = 2; // Rising Slowly
+            return 2; // Rising Slowly
         } else if (evol > -0.68) {
-            result = 3; // Normal
+            return 3; // Normal
         } else if (evol > -1.4) {
-            result = 4; // Decreasing Slowly
-        } else {
-            result = 5; // Decreasing Rapidly
+            return 4; // Decreasing Slowly
         }
-
-        return result;
+        return 5; // Decreasing Rapidly
     }
 
     private static int sagerWindTrend(double historic, double position) {
@@ -241,7 +232,7 @@ public class SagerWeatherCaster {
 
     private String getCompass() {
         double step = 360.0 / NTZDIRECTIONS.length;
-        double b = Math.floor((this.currentBearing + (step / 2.0)) / step);
+        double b = Math.floor((currentBearing + (step / 2.0)) / step);
         return NTZDIRECTIONS[(int) (b % NTZDIRECTIONS.length)];
     }
 
@@ -335,36 +326,32 @@ public class SagerWeatherCaster {
         if (prevision.isPresent()) {
             char forecast = prevision.get().zForecast;
             return Character.toString(forecast);
-        } else {
-            return "-";
         }
+        return "-";
     }
 
     public String getWindVelocity() {
         if (prevision.isPresent()) {
             char windVelocity = prevision.get().zWindVelocity;
             return Character.toString(windVelocity);
-        } else {
-            return "-";
         }
+        return "-";
     }
 
     public String getWindDirection() {
         if (prevision.isPresent()) {
             int direction = prevision.get().zWindDirection;
             return String.valueOf(direction);
-        } else {
-            return "-";
         }
+        return "-";
     }
 
     public String getWindDirection2() {
         if (prevision.isPresent()) {
             int direction = prevision.get().zWindDirection2;
             return String.valueOf(direction);
-        } else {
-            return "-";
         }
+        return "-";
     }
 
     public void setLatitude(double latitude) {
index 8ad3363106769273e72df756fffba9c9fa669b4a..f22cf1803bf87e177b3489e22e2b5a27d3fd415b 100644 (file)
@@ -14,10 +14,9 @@ package org.openhab.binding.sagercaster.internal.discovery;
 
 import static org.openhab.binding.sagercaster.internal.SagerCasterBindingConstants.*;
 
-import java.util.Arrays;
-import java.util.HashSet;
 import java.util.Map;
 import java.util.Objects;
+import java.util.Set;
 import java.util.concurrent.ScheduledFuture;
 import java.util.concurrent.TimeUnit;
 
@@ -26,10 +25,12 @@ import org.eclipse.jdt.annotation.Nullable;
 import org.openhab.core.config.discovery.AbstractDiscoveryService;
 import org.openhab.core.config.discovery.DiscoveryResultBuilder;
 import org.openhab.core.config.discovery.DiscoveryService;
+import org.openhab.core.i18n.LocaleProvider;
 import org.openhab.core.i18n.LocationProvider;
+import org.openhab.core.i18n.TranslationProvider;
 import org.openhab.core.library.types.PointType;
-import org.openhab.core.thing.ThingTypeUID;
 import org.openhab.core.thing.ThingUID;
+import org.osgi.service.component.annotations.Activate;
 import org.osgi.service.component.annotations.Component;
 import org.osgi.service.component.annotations.Reference;
 import org.slf4j.Logger;
@@ -43,20 +44,26 @@ import org.slf4j.LoggerFactory;
 @NonNullByDefault
 @Component(service = DiscoveryService.class, configurationPid = "discovery.sagercaster")
 public class SagerCasterDiscoveryService extends AbstractDiscoveryService {
-    private final Logger logger = LoggerFactory.getLogger(SagerCasterDiscoveryService.class);
     private static final int DISCOVER_TIMEOUT_SECONDS = 30;
     private static final int LOCATION_CHANGED_CHECK_INTERVAL = 60;
-    private @NonNullByDefault({}) LocationProvider locationProvider;
-    private @NonNullByDefault({}) ScheduledFuture<?> sagerCasterDiscoveryJob;
-    private @Nullable PointType previousLocation;
+    private static final ThingUID SAGER_CASTER_THING = new ThingUID(THING_TYPE_SAGERCASTER, LOCAL);
+
+    private final Logger logger = LoggerFactory.getLogger(SagerCasterDiscoveryService.class);
+    private final LocationProvider locationProvider;
 
-    private static final ThingUID sagerCasterThing = new ThingUID(THING_TYPE_SAGERCASTER, LOCAL);
+    private @Nullable ScheduledFuture<?> discoveryJob;
+    private @Nullable PointType previousLocation;
 
     /**
      * Creates a SagerCasterDiscoveryService with enabled autostart.
      */
-    public SagerCasterDiscoveryService() {
-        super(new HashSet<>(Arrays.asList(new ThingTypeUID(BINDING_ID, "-"))), DISCOVER_TIMEOUT_SECONDS, true);
+    @Activate
+    public SagerCasterDiscoveryService(final @Reference LocaleProvider localeProvider,
+            final @Reference TranslationProvider i18nProvider, final @Reference LocationProvider locationProvider) {
+        super(Set.of(THING_TYPE_SAGERCASTER), DISCOVER_TIMEOUT_SECONDS, true);
+        this.locationProvider = locationProvider;
+        this.localeProvider = localeProvider;
+        this.i18nProvider = i18nProvider;
     }
 
     @Override
@@ -82,8 +89,8 @@ public class SagerCasterDiscoveryService extends AbstractDiscoveryService {
 
     @Override
     protected void startBackgroundDiscovery() {
-        if (sagerCasterDiscoveryJob == null) {
-            sagerCasterDiscoveryJob = scheduler.scheduleWithFixedDelay(() -> {
+        if (discoveryJob == null) {
+            discoveryJob = scheduler.scheduleWithFixedDelay(() -> {
                 PointType currentLocation = locationProvider.getLocation();
                 if (currentLocation != null && !Objects.equals(currentLocation, previousLocation)) {
                     logger.debug("Location has been changed from {} to {}: Creating new discovery results",
@@ -99,28 +106,19 @@ public class SagerCasterDiscoveryService extends AbstractDiscoveryService {
 
     @Override
     protected void stopBackgroundDiscovery() {
+        ScheduledFuture<?> localJob = discoveryJob;
         logger.debug("Stopping Sager Weathercaster background discovery");
-        if (sagerCasterDiscoveryJob != null && !sagerCasterDiscoveryJob.isCancelled()) {
-            if (sagerCasterDiscoveryJob.cancel(true)) {
-                sagerCasterDiscoveryJob = null;
+        if (localJob != null && !localJob.isCancelled()) {
+            if (localJob.cancel(true)) {
+                discoveryJob = null;
                 logger.debug("Stopped SagerCaster device background discovery");
             }
         }
     }
 
     public void createResults(PointType location) {
-        String propGeolocation;
-        propGeolocation = String.format("%s,%s", location.getLatitude(), location.getLongitude());
-        thingDiscovered(DiscoveryResultBuilder.create(sagerCasterThing).withLabel("Local Sager Weathercaster")
+        String propGeolocation = String.format("%s,%s", location.getLatitude(), location.getLongitude());
+        thingDiscovered(DiscoveryResultBuilder.create(SAGER_CASTER_THING).withLabel("Local Weather Forecast")
                 .withRepresentationProperty(CONFIG_LOCATION).withProperty(CONFIG_LOCATION, propGeolocation).build());
     }
-
-    @Reference
-    protected void setLocationProvider(LocationProvider locationProvider) {
-        this.locationProvider = locationProvider;
-    }
-
-    protected void unsetLocationProvider(LocationProvider locationProvider) {
-        this.locationProvider = null;
-    }
 }
index 612a8be336528e130b05818710c011abe18ec771..ea54fe0666adf4f6f09b8153799db9b577f63112 100644 (file)
@@ -37,11 +37,10 @@ class ExpiringMap<T> {
     public void put(T newValue) {
         long now = System.currentTimeMillis();
         values.put(now, newValue);
-        Optional<Long> eldestKey = values.keySet().stream().filter(key -> key < now - eldestAge).findFirst();
-        if (eldestKey.isPresent()) {
-            agedValue = Optional.ofNullable(values.get(eldestKey.get()));
-            values.entrySet().removeIf(map -> map.getKey() <= eldestKey.get());
-        }
+        values.keySet().stream().filter(key -> key < now - eldestAge).findFirst().ifPresent(eldest -> {
+            agedValue = Optional.ofNullable(values.get(eldest));
+            values.entrySet().removeIf(map -> map.getKey() <= eldest);
+        });
     }
 
     public Optional<T> getAgedValue() {
index 322da57cdcd33cdb3d38b4315d98a776cff8278c..79065e6ac662b36d666c06df7e94494423c182a2 100644 (file)
@@ -17,16 +17,11 @@ import static org.openhab.core.library.unit.MetricPrefix.HECTO;
 
 import java.math.BigDecimal;
 import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashSet;
 import java.util.List;
 import java.util.Optional;
-import java.util.Set;
 import java.util.concurrent.TimeUnit;
 
 import javax.measure.quantity.Angle;
-import javax.measure.quantity.Dimensionless;
 import javax.measure.quantity.Pressure;
 import javax.measure.quantity.Temperature;
 
@@ -56,19 +51,19 @@ import org.slf4j.LoggerFactory;
  */
 @NonNullByDefault
 public class SagerCasterHandler extends BaseThingHandler {
-    private final static String FORECAST_PENDING = "0";
-    private final static Set<String> SHOWERS = Collections
-            .unmodifiableSet(new HashSet<>(Arrays.asList("G", "K", "L", "R", "S", "T", "U", "W")));
 
     private final Logger logger = LoggerFactory.getLogger(SagerCasterHandler.class);
+
     private final SagerWeatherCaster sagerWeatherCaster;
+
     private final WindDirectionStateDescriptionProvider stateDescriptionProvider;
-    private int currentTemp = 0;
 
     private final ExpiringMap<QuantityType<Pressure>> pressureCache = new ExpiringMap<>();
     private final ExpiringMap<QuantityType<Temperature>> temperatureCache = new ExpiringMap<>();
     private final ExpiringMap<QuantityType<Angle>> bearingCache = new ExpiringMap<>();
 
+    private int currentTemp = 0;
+
     public SagerCasterHandler(Thing thing, WindDirectionStateDescriptionProvider stateDescriptionProvider,
             SagerWeatherCaster sagerWeatherCaster) {
         super(thing);
@@ -82,7 +77,7 @@ public class SagerCasterHandler extends BaseThingHandler {
         int observationPeriod = ((BigDecimal) getConfig().get(CONFIG_PERIOD)).intValue();
         String latitude = location.split(",")[0];
         sagerWeatherCaster.setLatitude(Double.parseDouble(latitude));
-        long period = TimeUnit.SECONDS.toMillis(observationPeriod);
+        long period = TimeUnit.HOURS.toMillis(observationPeriod);
         pressureCache.setObservationPeriod(period);
         bearingCache.setObservationPeriod(period);
         temperatureCache.setObservationPeriod(period);
@@ -116,8 +111,7 @@ public class SagerCasterHandler extends BaseThingHandler {
                 case CHANNEL_CLOUDINESS:
                     logger.debug("Octa cloud level changed, updating forecast");
                     if (command instanceof QuantityType) {
-                        @SuppressWarnings("unchecked")
-                        QuantityType<Dimensionless> cloudiness = (QuantityType<Dimensionless>) command;
+                        QuantityType<?> cloudiness = (QuantityType<?>) command;
                         scheduler.submit(() -> {
                             sagerWeatherCaster.setCloudLevel(cloudiness.intValue());
                             postNewForecast();
@@ -127,7 +121,7 @@ public class SagerCasterHandler extends BaseThingHandler {
                 case CHANNEL_IS_RAINING:
                     logger.debug("Rain status updated, updating forecast");
                     if (command instanceof OnOffType) {
-                        OnOffType isRaining = ((OnOffType) command);
+                        OnOffType isRaining = (OnOffType) command;
                         scheduler.submit(() -> {
                             sagerWeatherCaster.setRaining(isRaining == OnOffType.ON);
                             postNewForecast();
@@ -139,13 +133,13 @@ public class SagerCasterHandler extends BaseThingHandler {
                 case CHANNEL_RAIN_QTTY:
                     logger.debug("Rain status updated, updating forecast");
                     if (command instanceof QuantityType) {
-                        QuantityType<?> newQtty = ((QuantityType<?>) command);
+                        QuantityType<?> newQtty = (QuantityType<?>) command;
                         scheduler.submit(() -> {
                             sagerWeatherCaster.setRaining(newQtty.doubleValue() > 0);
                             postNewForecast();
                         });
                     } else if (command instanceof DecimalType) {
-                        DecimalType newQtty = ((DecimalType) command);
+                        DecimalType newQtty = (DecimalType) command;
                         scheduler.submit(() -> {
                             sagerWeatherCaster.setRaining(newQtty.doubleValue() > 0);
                             postNewForecast();
@@ -175,18 +169,12 @@ public class SagerCasterHandler extends BaseThingHandler {
                                 .toUnit(HECTO(SIUnits.PASCAL));
                         if (newPressure != null) {
                             pressureCache.put(newPressure);
-                            Optional<QuantityType<Pressure>> agedPressure = pressureCache.getAgedValue();
-                            if (agedPressure.isPresent()) {
-                                scheduler.submit(() -> {
-                                    sagerWeatherCaster.setPressure(newPressure.doubleValue(),
-                                            agedPressure.get().doubleValue());
-                                    updateChannelString(GROUP_OUTPUT, CHANNEL_PRESSURETREND,
-                                            String.valueOf(sagerWeatherCaster.getPressureEvolution()));
-                                    postNewForecast();
-                                });
-                            } else {
-                                updateChannelString(GROUP_OUTPUT, CHANNEL_FORECAST, FORECAST_PENDING);
-                            }
+                            pressureCache.getAgedValue().ifPresentOrElse(pressure -> scheduler.submit(() -> {
+                                sagerWeatherCaster.setPressure(newPressure.doubleValue(), pressure.doubleValue());
+                                updateChannelString(GROUP_OUTPUT, CHANNEL_PRESSURETREND,
+                                        String.valueOf(sagerWeatherCaster.getPressureEvolution()));
+                                postNewForecast();
+                            }), () -> updateChannelString(GROUP_OUTPUT, CHANNEL_FORECAST, FORECAST_PENDING));
                         }
                     }
                     break;
@@ -200,12 +188,12 @@ public class SagerCasterHandler extends BaseThingHandler {
                             temperatureCache.put(newTemperature);
                             currentTemp = newTemperature.intValue();
                             Optional<QuantityType<Temperature>> agedTemperature = temperatureCache.getAgedValue();
-                            if (agedTemperature.isPresent()) {
-                                double delta = newTemperature.doubleValue() - agedTemperature.get().doubleValue();
+                            agedTemperature.ifPresent(temperature -> {
+                                double delta = newTemperature.doubleValue() - temperature.doubleValue();
                                 String trend = (delta > 3) ? "1"
                                         : (delta > 0.3) ? "2" : (delta > -0.3) ? "3" : (delta > -3) ? "4" : "5";
                                 updateChannelString(GROUP_OUTPUT, CHANNEL_TEMPERATURETREND, trend);
-                            }
+                            });
                         }
                     }
                     break;
@@ -216,14 +204,14 @@ public class SagerCasterHandler extends BaseThingHandler {
                         QuantityType<Angle> newAngle = (QuantityType<Angle>) command;
                         bearingCache.put(newAngle);
                         Optional<QuantityType<Angle>> agedAngle = bearingCache.getAgedValue();
-                        if (agedAngle.isPresent()) {
+                        agedAngle.ifPresent(angle -> {
                             scheduler.submit(() -> {
-                                sagerWeatherCaster.setBearing(newAngle.intValue(), agedAngle.get().intValue());
+                                sagerWeatherCaster.setBearing(newAngle.intValue(), angle.intValue());
                                 updateChannelString(GROUP_OUTPUT, CHANNEL_WINDEVOLUTION,
                                         String.valueOf(sagerWeatherCaster.getWindEvolution()));
                                 postNewForecast();
                             });
-                        }
+                        });
                     }
                     break;
                 default:
@@ -270,14 +258,14 @@ public class SagerCasterHandler extends BaseThingHandler {
         updateChannelDecimal(GROUP_OUTPUT, CHANNEL_VELOCITY_BEAUFORT, predictedBeaufort);
     }
 
-    protected void updateChannelString(String group, String channelId, String value) {
+    private void updateChannelString(String group, String channelId, String value) {
         ChannelUID id = new ChannelUID(getThing().getUID(), group, channelId);
         if (isLinked(id)) {
             updateState(id, new StringType(value));
         }
     }
 
-    protected void updateChannelDecimal(String group, String channelId, int value) {
+    private void updateChannelDecimal(String group, String channelId, int value) {
         ChannelUID id = new ChannelUID(getThing().getUID(), group, channelId);
         if (isLinked(id)) {
             updateState(id, new DecimalType(value));
index 072559afa3b4db73d6a71267f71b6581e6eea412..b243cddfacba986054610982fcc79e3c60a8c781 100644 (file)
@@ -3,7 +3,7 @@
        xmlns:binding="https://openhab.org/schemas/binding/v1.0.0"
        xsi:schemaLocation="https://openhab.org/schemas/binding/v1.0.0 https://openhab.org/schemas/binding-1.0.0.xsd">
 
-       <name>SagerCaster Binding</name>
-       <description>The Sager Weathercaster is a scientific instrument for accurate prediction of the weather.</description>
+       <name>@text/bindingName</name>
+       <description>@text/bindingDescription</description>
 
 </binding:binding>
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
new file mode 100644 (file)
index 0000000..a8eb7a0
--- /dev/null
@@ -0,0 +1,108 @@
+# binding
+bindingName = SagerCaster Binding
+bindingDescription = The Sager Weathercaster is a scientific instrument for accurate prediction of the weather.
+
+# thing
+sagercasterLabel = SagerCaster Thing
+sagercasterDescription = This thing represents a forecast for a given location.
+
+# ting configuration
+locationLabel = Location
+locationDescription = Your geo coordinates separated with comma (e.g. "37.8,-122.4").
+observationLabel = Observation Period
+observationDescription = Sager WeatherCaster needs a minimum representative period of time to produce meaningfull results (defaults to 6 hours).
+
+# channel groups
+inputLabel = Inputs
+inputDescription = The channels used to build the forecast results
+outputLabel = Results
+outputDescription = Results of the Sager Weathercaster algorithm
+
+# channels
+windVelocity = Wind Velocity
+windFrom = Wind from
+windTo = Wind to
+pressureTrendLabel = Pressure Trend
+pressureTrendDescription = Pressure evolution trend over observation delay
+tempTrendLabel = Temperature Trend
+tempTrendDescription = Temperature evolution trend over observation delay
+forecastLabel = Weather Forecast
+windDirectionLabel = Wind Direction
+windEvolutionLabel = Wind Evolution
+windEvolutionDescription = Wind bearing evolution trend over observation delay
+trendLabel = Measure Trend
+trendDescription = Measure evolution trend over observation delay
+timestampLabel = Calculation Time
+timestampDescription = Weather forecast calculation date and time
+cloudinessLabel = Cloudiness
+cloudinessDescription = Current cloudiness.
+rainQttyLabel = Rain Quantity
+rainQttyDescription = Current rain quantity
+rainingLabel = Raining
+rainingDescription = Is it currently raining ?
+beaufortLabel = Beaufort
+beaufortDescription = Wind speed using Beaufort Scale
+pressureDescription = Barometric pressure at sea level.
+
+# channel options
+forecast0 = Not enough historic data to study pressure evolution, wait a bit ...
+forecastA = Fair
+forecastB = Fair and warmer
+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
+forecastJ = Showers
+forecastK = Showers/Flurries and warmer
+forecastK1 = Showers and warmer
+forecastK2 = Flurries and warmer
+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)
+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
+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)
+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
+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
+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
+forecastY = Unsettled followed by fair early in period (within 6 hours) and becoming cooler
+
+velocityN = Probably increasing
+velocityF = Moderate to fresh
+velocityS = Strong winds may precede gales over open water
+velocityG = Gale
+velocityW = Dangerous gale (whole gale)
+velocityH = Hurricane
+velocityD = Diminishing, or moderating somewhat if current winds are of fresh to strong velocity
+velocityU = No important change. Some tendency for slight increase in winds during day, diminishing in evening
+
+evolution1 = Steady
+evolution2 = Veering
+evolution3 = Backing
+
+trend1 = Rising Rapidly
+trend2 = Rising Slowly
+trend3 = Normal
+trend4 = Decreasing Slowly
+trend5 = Decreasing Rapidly
+# Discovery result
+discovery.sagercaster.sagercaster.local.label = Local Weather Forecast
+
index edd15ac9c5ca3c0d1a3141d1a4fcdce6f61fd9c7..7df1835da03ef092da80c3e73ea379462d64ccfc 100644 (file)
@@ -1,63 +1,66 @@
 # binding
-binding.sagercaster.name = SagerCaster Binding
-binding.sagercaster.description = Die SagerCaster-Erweiterung wird zur Erstellung von Wettervorhersagen verwendet.
+bindingName = SagerCaster Binding
+bindingDescription = Die SagerCaster-Erweiterung wird zur Erstellung von Wettervorhersagen verwendet.
 
-# channel types
-channel-type.sagercaster.forecast.state.option.0 = Warten Sie etwas länger auf eine Vorhersage
-channel-type.sagercaster.forecast.state.option.A = Gutes Wetter
-channel-type.sagercaster.forecast.state.option.B = Gutes Wetter und Erwärmung
-channel-type.sagercaster.forecast.state.option.C = Gutes Wetter und Abkühlung
-channel-type.sagercaster.forecast.state.option.D = Instabil
-channel-type.sagercaster.forecast.state.option.E = Instabil und Erwärmung
-channel-type.sagercaster.forecast.state.option.F = Instabil und Abkühlung
-channel-type.sagercaster.forecast.state.option.G = Zunehmende Bewölkung oder sehr bewölkt, gefolgt von Niederschlag oder Schauern / Schnee
-channel-type.sagercaster.forecast.state.option.G1 = Zunehmende oder sehr trübe Bewölkung, gefolgt von Niederschlag oder Schauern
-channel-type.sagercaster.forecast.state.option.G2 = Zunehmende Bewölkung oder sehr bewölkt, gefolgt von Niederschlag oder Schnee
-channel-type.sagercaster.forecast.state.option.H = Zunehmende Bewölkung oder sehr bewölkt, gefolgt von Niederschlag oder Schauern und Erwärmung
-channel-type.sagercaster.forecast.state.option.J = Regengüsse
-channel-type.sagercaster.forecast.state.option.K = Regengüsse / Schnee und Erwärmung
-channel-type.sagercaster.forecast.state.option.K1 = Regengüsse und Erwärmung
-channel-type.sagercaster.forecast.state.option.K2 = Schnee und Erwärmung
-channel-type.sagercaster.forecast.state.option.L = Regengüsse / Schnee und Abkühlung
-channel-type.sagercaster.forecast.state.option.L1 = Regengüsse und Abkühlung
-channel-type.sagercaster.forecast.state.option.L2 = Regengüsse und Abkühlung
-channel-type.sagercaster.forecast.state.option.M = Niederschlag
-channel-type.sagercaster.forecast.state.option.N = Niederschlag und Erwärmung
-channel-type.sagercaster.forecast.state.option.P = Niederschlag und Abkühlung dann wahrscheinliche Besserung innerhalb von 24 Stunden
-channel-type.sagercaster.forecast.state.option.R = Niederschlag oder Schauer / Schnee und Besserung innerhalb von 12 Stunden
-channel-type.sagercaster.forecast.state.option.R1 = Niederschlag oder Schauer und Besserung innerhalb von 12 Stunden
-channel-type.sagercaster.forecast.state.option.R2 = Niederschlag oder Schnee und Besserung innerhalb von 12 Stunden
-channel-type.sagercaster.forecast.state.option.S = Niederschlag oder Schauer / Schnee und Verbesserung innerhalb von 12 Stunden und Abkühlung
-channel-type.sagercaster.forecast.state.option.S1 = Niederschlag oder Regengüsse und Besserung innerhalb von 12 Stunden und Erfrischung
-channel-type.sagercaster.forecast.state.option.S2 = Niederschlag oder Schnee und Verbesserung innerhalb von 12 Stunden und Abkühlung
-channel-type.sagercaster.forecast.state.option.T = Niederschlag oder Schauer / Schnee und schnelle Besserung innerhalb von 6 Stunden
-channel-type.sagercaster.forecast.state.option.T1 = Niederschlag oder Schauer und schnelle Besserung innerhalb von 6 Stunden
-channel-type.sagercaster.forecast.state.option.T2 = Niederschlag oder Schnee und schnelle Besserung innerhalb von 6 Stunden
-channel-type.sagercaster.forecast.state.option.U = Niederschlag oder Schauer / Schnee und schnelle Besserung innerhalb von 6 Stunden, dann Abkühlung
-channel-type.sagercaster.forecast.state.option.U1 = Niederschlag oder Schauer und schnelle Besserung innerhalb von 6 Stunden, dann Abkühlung
-channel-type.sagercaster.forecast.state.option.U2 = Niederschlag oder Schnee und schnelle Besserung innerhalb von 6 Stunden, dann Abkühlung
-channel-type.sagercaster.forecast.state.option.W = Niederschlag oder Schauer / Schnee, gefolgt von gutem Wetter innerhalb von 6 Stunden und Erfrischung
-channel-type.sagercaster.forecast.state.option.W1 = Niederschlag oder Schauer, gefolgt von gutem Wetter innerhalb von 6 Stunden und Erfrischung
-channel-type.sagercaster.forecast.state.option.W2 = Niederschlag oder Schnee, gefolgt von gutem Wetter innerhalb von 6 Stunden und Abkühlung
-channel-type.sagercaster.forecast.state.option.X = Instabil, gefolgt von gutem Wetter
-channel-type.sagercaster.forecast.state.option.Y = Instabil, gefolgt von gutem Wetter innerhalb von 6 Stunden und Erfrischung
+# thing
+sagercasterLabel = SagerCaster Thing
+sagercasterDescription = Dieses Thing stellt eine Vorhersage für einen bestimmten Standort dar.
 
-channel-type.sagercaster.velocity.state.option.N = Wahrscheinlich steigend
-channel-type.sagercaster.velocity.state.option.F = Mäßig bis frisch
-channel-type.sagercaster.velocity.state.option.S = Starke Winde können dem Sturm im offenen Raum vorausgehen
-channel-type.sagercaster.velocity.state.option.G = Sturm
-channel-type.sagercaster.velocity.state.option.W = Gefährlicher Sturm
-channel-type.sagercaster.velocity.state.option.H = Orkan
-channel-type.sagercaster.velocity.state.option.D = Abkühlend oder moderat, wenn die aktuellen Winde kühl oder stark sind
-channel-type.sagercaster.velocity.state.option.U = Keine wesentliche Änderung. Tendenz zur Zunahme während des Tages, Abnahme am Abend.
+# channel types
+forecast0 = Warten Sie etwas länger auf eine Vorhersage
+forecastA = Gutes Wetter
+forecastB = Gutes Wetter und Erwärmung
+forecastC = Gutes Wetter und Abkühlung
+forecastD = Instabil
+forecastE = Instabil und Erwärmung
+forecastF = Instabil und Abkühlung
+forecastG = Zunehmende Bewölkung oder sehr bewölkt, gefolgt von Niederschlag oder Schauern / Schnee
+forecastG1 = Zunehmende oder sehr trübe Bewölkung, gefolgt von Niederschlag oder Schauern
+forecastG2 = Zunehmende Bewölkung oder sehr bewölkt, gefolgt von Niederschlag oder Schnee
+forecastH = Zunehmende Bewölkung oder sehr bewölkt, gefolgt von Niederschlag oder Schauern und Erwärmung
+forecastJ = Regengüsse
+forecastK = Regengüsse / Schnee und Erwärmung
+forecastK1 = Regengüsse und Erwärmung
+forecastK2 = Schnee und Erwärmung
+forecastL = Regengüsse / Schnee und Abkühlung
+forecastL1 = Regengüsse und Abkühlung
+forecastL2 = Regengüsse und Abkühlung
+forecastM = Niederschlag
+forecastN = Niederschlag und Erwärmung
+forecastP = Niederschlag und Abkühlung dann wahrscheinliche Besserung innerhalb von 24 Stunden
+forecastR = Niederschlag oder Schauer / Schnee und Besserung innerhalb von 12 Stunden
+forecastR1 = Niederschlag oder Schauer und Besserung innerhalb von 12 Stunden
+forecastR2 = Niederschlag oder Schnee und Besserung innerhalb von 12 Stunden
+forecastS = Niederschlag oder Schauer / Schnee und Verbesserung innerhalb von 12 Stunden und Abkühlung
+forecastS1 = Niederschlag oder Regengüsse und Besserung innerhalb von 12 Stunden und Erfrischung
+forecastS2 = Niederschlag oder Schnee und Verbesserung innerhalb von 12 Stunden und Abkühlung
+forecastT = Niederschlag oder Schauer / Schnee und schnelle Besserung innerhalb von 6 Stunden
+forecastT1 = Niederschlag oder Schauer und schnelle Besserung innerhalb von 6 Stunden
+forecastT2 = Niederschlag oder Schnee und schnelle Besserung innerhalb von 6 Stunden
+forecastU = Niederschlag oder Schauer / Schnee und schnelle Besserung innerhalb von 6 Stunden, dann Abkühlung
+forecastU1 = Niederschlag oder Schauer und schnelle Besserung innerhalb von 6 Stunden, dann Abkühlung
+forecastU2 = Niederschlag oder Schnee und schnelle Besserung innerhalb von 6 Stunden, dann Abkühlung
+forecastW = Niederschlag oder Schauer / Schnee, gefolgt von gutem Wetter innerhalb von 6 Stunden und Erfrischung
+forecastW1 = Niederschlag oder Schauer, gefolgt von gutem Wetter innerhalb von 6 Stunden und Erfrischung
+forecastW2 = Niederschlag oder Schnee, gefolgt von gutem Wetter innerhalb von 6 Stunden und Abkühlung
+forecastX = Instabil, gefolgt von gutem Wetter
+forecastY = Instabil, gefolgt von gutem Wetter innerhalb von 6 Stunden und Erfrischung
 
-channel-type.sagercaster.wind-evolution.state.option.1 = Stabil
-channel-type.sagercaster.wind-evolution.state.option.2 = Stätig
-channel-type.sagercaster.wind-evolution.state.option.3 = Variabel
+velocityN = Wahrscheinlich steigend
+velocityF = Mäßig bis frisch
+velocityS = Starke Winde können dem Sturm im offenen Raum vorausgehen
+velocityG = Sturm
+velocityW = Gefährlicher Sturm
+velocityH = Orkan
+velocityD = Abkühlend oder moderat, wenn die aktuellen Winde kühl oder stark sind
+velocityU = Keine wesentliche Änderung. Tendenz zur Zunahme während des Tages, Abnahme am Abend.
 
-channel-type.sagercaster.trend.state.option.1 = Schneller Anstieg
-channel-type.sagercaster.trend.state.option.2 = Langsamer Anstieg
-channel-type.sagercaster.trend.state.option.3 = Stabil
-channel-type.sagercaster.trend.state.option.4 = Mäßiger Rückgang
-channel-type.sagercaster.trend.state.option.5 = Schneller Rückgang
+evolution1 = Stabil
+evolution2 = Stätig
+evolution3 = Variabel
 
+trend1 = Schneller Anstieg
+trend2 = Langsamer Anstieg
+trend3 = Stabil
+trend4 = Mäßiger Rückgang
+trend5 = Schneller Rückgang
index ecd6f1048b35870dfc64f949775a88e02695547a..505b2a0d4e7fb48725dd72a502a34c609a2659e3 100644 (file)
 # binding
-binding.sagercaster.name = Extension SagerCaster
-binding.sagercaster.description = L'extension SagerCaster permet d'établir des prévisions météo.
+bindingName = Extension SagerCaster
+bindingDescription = Sager Weathercaster est un instrument scientifique pour produire des prédicitions météo précises.
+
+# thing
+sagercasterLabel = SagerCaster Thing
+sagercasterDescription = Représente la prévision pour une localisation donnée.
+
+# ting configuration
+locationLabel = Emplacement
+locationDescription = Vos coordonnées géographiques séparées par une virgule (p.e. "37.8,-122.4").
+observationLabel = Période d'observation
+observationDescription = Sager WeatherCaster requiert une période d'observation minimale pour produire des résultats significatifs (6 heures par défaut).
+
+# channel groups
+inputLabel = Entrées
+inputDescription = Canaux utilisés pour produire des résultats de prévisions
+outputLabel = Résultats
+outputDescription = Résultats produits par l'algorithme Sager Weathercaster
+
+# channels
+windVelocity = Force du Vent
+windFrom = Vent de
+windTo = Vent vers
+pressureTrendLabel = Tendance Pression
+pressureTrendDescription = Evolution de la pression au cours de la période d'observation
+tempTrendLabel = Tendance température
+tempTrendDescription = Evolution de la température au cours de la période d'observation
+forecastLabel = Prévision météo
+windDirectionLabel = Direction du Vent
+windEvolutionLabel = Evolution du Vent
+windEvolutionDescription = Tendance de l'évolution du vent au cours de la période d'observation
+trendLabel = Tendance
+trendDescription = Evolution de la mesure au cours de la période d'observation
+timestampLabel = Horodatage de la prévision
+timestampDescription = Date et heure de calcul de la prévision météo.
+cloudinessLabel = Nébulosité
+cloudinessDescription = Qualification de la couverture nuageuse.
+rainQttyLabel = Quantité de pluie
+rainQttyDescription = Quantité d'eau tombée
+rainingLabel = Pluie
+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.
 
 # channel types
-channel-type.sagercaster.forecast.state.option.0 = Patientez encore un peu pour une prédiction
-channel-type.sagercaster.forecast.state.option.A = Beau-temps
-channel-type.sagercaster.forecast.state.option.B = Beau-temps et réchauffement
-channel-type.sagercaster.forecast.state.option.C = Beau-temps et rafraichissement
-channel-type.sagercaster.forecast.state.option.D = Instable
-channel-type.sagercaster.forecast.state.option.E = Instable et réchauffement
-channel-type.sagercaster.forecast.state.option.F = Instable et rafraichissement
-channel-type.sagercaster.forecast.state.option.G = Nébulosité croissante ou très nuageux suivi de précititations ou averses / neige
-channel-type.sagercaster.forecast.state.option.G1 = Nébulosité croissante ou très nuageux suivi de précititations ou averses
-channel-type.sagercaster.forecast.state.option.G2 = Nébulosité croissante ou très nuageux suivi de précititations ou neige
-channel-type.sagercaster.forecast.state.option.H = Nébulosité croissante ou très nuageux suivi de précititations ou averses et réchauffement
-channel-type.sagercaster.forecast.state.option.J = Averses
-channel-type.sagercaster.forecast.state.option.K = Averses / neige et réchauffement
-channel-type.sagercaster.forecast.state.option.K1 = Averses et réchauffement
-channel-type.sagercaster.forecast.state.option.K2 = Neige et réchauffement
-channel-type.sagercaster.forecast.state.option.L = Averses / neige et rafraichissement
-channel-type.sagercaster.forecast.state.option.L1 = Averses et rafraichissement
-channel-type.sagercaster.forecast.state.option.L2 = Neige et rafraichissement
-channel-type.sagercaster.forecast.state.option.M = Précipitations
-channel-type.sagercaster.forecast.state.option.N = Précipitations et réchauffement
-channel-type.sagercaster.forecast.state.option.P = Précipitations et rafraichissement puis amélioration probable dans les 24 heures
-channel-type.sagercaster.forecast.state.option.R = Précipitations ou averses / neige et amélioration dans les 12 heures
-channel-type.sagercaster.forecast.state.option.R1 = Précipitations ou averses et amélioration dans les 12 heures
-channel-type.sagercaster.forecast.state.option.R2 = Précipitations ou neige et amélioration dans les 12 heures
-channel-type.sagercaster.forecast.state.option.S = Précipitations ou averses / neige et amélioration dans les 12 heures et rafraichissement
-channel-type.sagercaster.forecast.state.option.S1 = Précipitations ou averses et amélioration dans les 12 heures et rafraichissement
-channel-type.sagercaster.forecast.state.option.S2 = Précipitations ou neige et amélioration dans les 12 heures et rafraichissement
-channel-type.sagercaster.forecast.state.option.T = Précipitations ou averses / neige et amélioration rapide dans les 6 heures
-channel-type.sagercaster.forecast.state.option.T1 = Précipitations ou averses et amélioration rapide dans les 6 heures
-channel-type.sagercaster.forecast.state.option.T2 = Précipitations ou neige et amélioration rapide dans les 6 heures
-channel-type.sagercaster.forecast.state.option.U = Précipitations ou averses / neige et amélioration rapide dans les 6 heures puis rafraichissement
-channel-type.sagercaster.forecast.state.option.U1 = Précipitations ou averses et amélioration rapide dans les 6 heures puis rafraichissement
-channel-type.sagercaster.forecast.state.option.U2 = Précipitations ou neige et amélioration rapide dans les 6 heures puis rafraichissement
-channel-type.sagercaster.forecast.state.option.W = Précipitations ou averses / neige suivi de beau temps rapide dans les 6 heures et rafraichissement
-channel-type.sagercaster.forecast.state.option.W1 = Précipitations ou averses suivi de beau temps rapide dans les 6 heures et rafraichissement
-channel-type.sagercaster.forecast.state.option.W2 = Précipitations ou neige suivi de beau temps rapide dans les 6 heures et rafraichissement
-channel-type.sagercaster.forecast.state.option.X = Instable suivi de beau temps
-channel-type.sagercaster.forecast.state.option.Y = Instable suivi de beau temps rapide dans les 6 heures et rafraichissement
+forecast0 = Patientez encore un peu pour une prédiction
+forecastA = Beau-temps
+forecastB = Beau-temps et réchauffement
+forecastC = Beau-temps et rafraichissement
+forecastD = Instable
+forecastE = Instable et réchauffement
+forecastF = Instable et rafraichissement
+forecastG = Nébulosité croissante ou très nuageux suivi de précipitations ou averses / neige
+forecastG1 = Nébulosité croissante ou très nuageux suivi de précipitations ou averses
+forecastG2 = Nébulosité croissante ou très nuageux suivi de précipitations ou neige
+forecastH = Nébulosité croissante ou très nuageux suivi de précipitations ou averses et réchauffement
+forecastJ = Averses
+forecastK = Averses / neige et réchauffement
+forecastK1 = Averses et réchauffement
+forecastK2 = Neige et réchauffement
+forecastL = Averses / neige et rafraichissement
+forecastL1 = Averses et rafraichissement
+forecastL2 = Neige et rafraichissement
+forecastM = Précipitations
+forecastN = Précipitations et réchauffement
+forecastP = Précipitations et rafraichissement puis amélioration probable dans les 24 heures
+forecastR = Précipitations ou averses / neige et amélioration dans les 12 heures
+forecastR1 = Précipitations ou averses et amélioration dans les 12 heures
+forecastR2 = Précipitations ou neige et amélioration dans les 12 heures
+forecastS = Précipitations ou averses / neige et amélioration dans les 12 heures et rafraichissement
+forecastS1 = Précipitations ou averses et amélioration dans les 12 heures et rafraichissement
+forecastS2 = Précipitations ou neige et amélioration dans les 12 heures et rafraichissement
+forecastT = Précipitations ou averses / neige et amélioration rapide dans les 6 heures
+forecastT1 = Précipitations ou averses et amélioration rapide dans les 6 heures
+forecastT2 = Précipitations ou neige et amélioration rapide dans les 6 heures
+forecastU = Précipitations ou averses / neige et amélioration rapide dans les 6 heures puis rafraichissement
+forecastU1 = Précipitations ou averses et amélioration rapide dans les 6 heures puis rafraichissement
+forecastU2 = Précipitations ou neige et amélioration rapide dans les 6 heures puis rafraichissement
+forecastW = Précipitations ou averses / neige suivi de beau temps rapide dans les 6 heures et rafraichissement
+forecastW1 = Précipitations ou averses suivi de beau temps rapide dans les 6 heures et rafraichissement
+forecastW2 = Précipitations ou neige suivi de beau temps rapide dans les 6 heures et rafraichissement
+forecastX = Instable suivi de beau temps
+forecastY = Instable suivi de beau temps rapide dans les 6 heures et rafraichissement
+
+velocityN = Probablement en augmentation
+velocityF = Modéré à frais
+velocityS = Vents forts pouvant précéder tempête en espace ouvert
+velocityG = Tempête
+velocityW = Tempête dangereuse
+velocityH = Ouragan
+velocityD = Décroissant ou en modération si les vents actuels sont frais ou forts
+velocityU = Pas de changement notable. Tendance pour augmentation progressive dans la journée, diminution dans la soirée.
 
-channel-type.sagercaster.velocity.state.option.N = Probablement en augmentation
-channel-type.sagercaster.velocity.state.option.F = Modéré à frais
-channel-type.sagercaster.velocity.state.option.S = Vents forts pouvant précéder tempête en espace ouvert
-channel-type.sagercaster.velocity.state.option.G = Tempête
-channel-type.sagercaster.velocity.state.option.W = Tempête dangereuse
-channel-type.sagercaster.velocity.state.option.H = Ouragan
-channel-type.sagercaster.velocity.state.option.D = Décroissant ou en modération si les vents actuels sont frais ou forts
-channel-type.sagercaster.velocity.state.option.U = Pas de changement notable. Tendance pour augmentation progressive dans la journée, diminution dans la soirée.
+evolution1 = Stable
+evolution2 = Horaire
+evolution3 = Anti-horaire
 
-channel-type.sagercaster.wind-evolution.state.option.1 = Stable
-channel-type.sagercaster.wind-evolution.state.option.2 = Horaire
-channel-type.sagercaster.wind-evolution.state.option.3 = Anti-horaire
+trend1 = Augmentation rapide
+trend2 = Augmentation lente
+trend3 = Stable
+trend4 = Baisse modérée
+trend5 = Baisse rapide
 
-channel-type.sagercaster.trend.state.option.1 = Augmentation rapide
-channel-type.sagercaster.trend.state.option.2 = Augmentation lente
-channel-type.sagercaster.trend.state.option.3 = Stable
-channel-type.sagercaster.trend.state.option.4 = Baisse modérée
-channel-type.sagercaster.trend.state.option.5 = Baisse rapide
+# Discovery result
+discovery.sagercaster.sagercaster.local.label = Prévision Météo Locale
 
index dcebb004ee516c8ee6f1420f6d453005db349265..60b0c1e7926eb26caf3e7536f5f62eba1ed7a5b4 100644 (file)
@@ -5,9 +5,8 @@
        xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
 
        <thing-type id="sagercaster">
-               <label>SagerCaster Thing</label>
-               <description>This thing represents a forecast for a given location</description>
-
+               <label>@text/sagercasterLabel</label>
+               <description>@text/sagercasterDescription</description>
 
                <channel-groups>
                        <channel-group id="input" typeId="input"/>
                <config-description>
                        <parameter name="location" type="text" required="true"
                                pattern="^[-+]?([1-8]?\d(\.\d+)?|90(\.0+)?)[,]\s*[-+]?(180(\.0+)?|((1[0-7]\d)|([1-9]?\d))(\.\d+)?)$">
-                               <label>Location</label>
+                               <label>@text/locationLabel</label>
                                <context>location</context>
-                               <description>Your geo coordinates separated with comma (e.g. "37.8,-122.4").</description>
+                               <description>@text/locationDescription</description>
                        </parameter>
 
                        <parameter name="observation-period" type="integer" min="0" max="6" required="true">
-                               <label>Observation Period</label>
-                               <description>SagerWeatherCaster needs a minimum representative period of time to produce meaningfull results.
-                                       Defaults to 6 hours</description>
+                               <label>@text/observationLabel</label>
+                               <description>@text/observationDescription</description>
                                <default>6</default>
                        </parameter>
 
                </config-description>
        </thing-type>
 
-
        <channel-group-type id="input">
-               <label>Inputs</label>
-               <description>The channels used to build the forecast results</description>
+               <label>@text/inputLabel</label>
+               <description>@text/inputDescription</description>
                <channels>
                        <channel id="cloudiness" typeId="cloudiness"/>
                        <channel id="is-raining" typeId="is-raining"/>
                        <channel id="rain-qtty" typeId="rain-qtty"/>
                        <channel id="wind-speed-beaufort" typeId="wind-speed-beaufort"/>
-                       <channel id="pressure" typeId="pressure"/>
-                       <channel id="temperature" typeId="temperature"/>
-                       <channel id="wind-angle" typeId="wind-angle-rw"/>
+                       <channel id="pressure" typeId="system.barometric-pressure">
+                               <label>@text/pressureDescription</label>
+                       </channel>
+                       <channel id="temperature" typeId="system.outdoor-temperature"/>
+                       <channel id="wind-angle" typeId="system.wind-direction"/>
                </channels>
        </channel-group-type>
 
        <channel-group-type id="output">
-               <label>Results</label>
-               <description>Results of the Sager Weathercaster algorithm</description>
+               <label>@text/outputLabel</label>
+               <description>@text/outputDescription</description>
                <channels>
                        <channel id="forecast" typeId="forecast"/>
                        <channel id="velocity" typeId="velocity"/>
                        <channel id="velocity-beaufort" typeId="wind-speed-beaufort">
-                               <label>Wind Velocity</label>
+                               <label>@text/windVelocity</label>
                        </channel>
                        <channel id="wind-from" typeId="wind-direction">
-                               <label>Wind From</label>
+                               <label>@text/windFrom</label>
                        </channel>
                        <channel id="wind-to" typeId="wind-direction">
-                               <label>Wind To</label>
+                               <label>@text/windTo</label>
                        </channel>
                        <channel id="wind-evolution" typeId="wind-evolution"/>
                        <channel id="pressure-trend" typeId="trend">
-                               <label>Pressure Trend</label>
-                               <description>Pressure Evolution trend over observation delay</description>
+                               <label>@text/pressureTrendLabel</label>
+                               <description>@text/pressureTrendDescription</description>
                        </channel>
                        <channel id="temperature-trend" typeId="trend">
-                               <label>Temperature Trend</label>
-                               <description>Temperature Evolution trend over observation delay</description>
+                               <label>@text/tempTrendLabel</label>
+                               <description>@text/tempTrendDescription</description>
                        </channel>
                </channels>
        </channel-group-type>
 
        <channel-type id="forecast">
                <item-type>String</item-type>
-               <label>Weather Forecast</label>
+               <label>@text/forecastLabel</label>
                <state readOnly="true" pattern="%s">
                        <options>
-                               <option value="0">Not enough historic data to study pressure evolution, wait a bit ...</option>
-                               <option value="A">Fair</option>
-                               <option value="B">Fair and warmer</option>
-                               <option value="C">Fair and cooler</option>
-                               <option value="D">Unsettled</option>
-                               <option value="E">Unsettled and warmer</option>
-                               <option value="F">Unsettled and cooler</option>
-                               <option value="G">Increasing cloudiness or overcast followed by Precipitation or showers/Flurries</option>
-                               <option value="G1">Increasing cloudiness or overcast followed by Precipitation or showers</option>
-                               <option value="G2">Increasing cloudiness or overcast followed by Precipitation or Flurries</option>
-                               <option value="H">Increasing cloudiness or overcast followed by Precipitation or showers and warmer</option>
-                               <option value="J">Showers</option>
-                               <option value="K">Showers/Flurries and warmer</option>
-                               <option value="K1">Showers and warmer</option>
-                               <option value="K2">Flurries and warmer</option>
-                               <option value="L">Showers/Flurries and cooler</option>
-                               <option value="L1">Showers and cooler</option>
-                               <option value="L2">Flurries and cooler</option>
-                               <option value="M">Precipitation</option>
-                               <option value="N">Precipitation and warmer</option>
-                               <option value="P">Precipitation and turning cooler; then improvement likely in 24 hours</option>
-                               <option value="R">Precipitation or showers/Flurries followed by improvement (within 12 hours)</option>
-                               <option value="R1">Precipitation or showers followed by improvement (within 12 hours)</option>
-                               <option value="R2">Precipitation or flurries followed by improvement (within 12 hours)</option>
-                               <option value="S">Precipitation or showers/Flurries followed by improvement (within 12 hours) and becoming cooler</option>
-                               <option value="S1">Precipitation or showers followed by improvement (within 12 hours) and becoming cooler</option>
-                               <option value="S2">Precipitation or flurries followed by improvement (within 12 hours) and becoming cooler</option>
-                               <option value="T">Precipitation or showers/Flurries followed by improvement early in period (within 6 hours)</option>
-                               <option value="T1">Precipitation or showers followed by improvement early in period (within 6 hours)</option>
-                               <option value="T2">Precipitation or flurries followed by improvement early in period (within 6 hours)</option>
-                               <option value="U">Precipitation or showers/Flurries by improvement early in period (within 6 hours) and becoming
-                                       cooler</option>
-                               <option value="U1">Precipitation or showers by improvement early in period (within 6 hours) and becoming cooler</option>
-                               <option value="U2">Precipitation or flurries by improvement early in period (within 6 hours) and becoming cooler</option>
-                               <option value="W">Precipitation or showers/Flurries followed by fair early in period (within 6 hours) and
-                                       becoming cooler</option>
-                               <option value="W1">Precipitation or showers followed by fair early in period (within 6 hours) and becoming cooler</option>
-                               <option value="W2">Precipitation or flurries followed by fair early in period (within 6 hours) and becoming cooler</option>
-                               <option value="X">Unsettled followed by fair</option>
-                               <option value="Y">Unsettled followed by fair early in period (within 6 hours) and becoming cooler</option>
+                               <option value="0">@text/forecast0</option>
+                               <option value="A">@text/forecastA</option>
+                               <option value="B">@text/forecastB</option>
+                               <option value="C">@text/forecastC</option>
+                               <option value="D">@text/forecastD</option>
+                               <option value="E">@text/forecastE</option>
+                               <option value="F">@text/forecastF</option>
+                               <option value="G">@text/forecastG</option>
+                               <option value="G1">@text/forecastG1</option>
+                               <option value="G2">@text/forecastG2</option>
+                               <option value="H">@text/forecastH</option>
+                               <option value="J">@text/forecastJ</option>
+                               <option value="K">@text/forecastK</option>
+                               <option value="K1">@text/forecastK1</option>
+                               <option value="K2">@text/forecastK2</option>
+                               <option value="L">@text/forecastL</option>
+                               <option value="L1">@text/forecastL1</option>
+                               <option value="L2">@text/forecastL2</option>
+                               <option value="M">@text/forecastM</option>
+                               <option value="N">@text/forecastN</option>
+                               <option value="P">@text/forecastP</option>
+                               <option value="R">@text/forecastR</option>
+                               <option value="R1">@text/forecastR1</option>
+                               <option value="R2">@text/forecastR2</option>
+                               <option value="S">@text/forecastS</option>
+                               <option value="S1">@text/forecastS1</option>
+                               <option value="S2">@text/forecastS2</option>
+                               <option value="T">@text/forecastT</option>
+                               <option value="T1">@text/forecastT1</option>
+                               <option value="T2">@text/forecastT2</option>
+                               <option value="U">@text/forecastU</option>
+                               <option value="U1">@text/forecastU1</option>
+                               <option value="U2">@text/forecastU2</option>
+                               <option value="W">@text/forecastW</option>
+                               <option value="W1">@text/forecastW1</option>
+                               <option value="W2">@text/forecastW2</option>
+                               <option value="X">@text/forecastX</option>
+                               <option value="Y">@text/forecastY</option>
                        </options>
                </state>
        </channel-type>
 
        <channel-type id="velocity">
                <item-type>String</item-type>
-               <label>Wind Velocity</label>
+               <label>@text/windVelocity</label>
                <state readOnly="true" pattern="%s">
                        <options>
-                               <option value="N">Probably increasing</option>
-                               <option value="F">Moderate to fresh</option>
-                               <option value="S">Strong winds may precede gales over open water)</option>
-                               <option value="G">Gale</option>
-                               <option value="W">Dangerous gale (whole gale)</option>
-                               <option value="H">Hurricane</option>
-                               <option value="D">Diminishing, or moderating somewhat if current winds are of fresh to strong velocity</option>
-                               <option value="U">No important change. Some tendency for slight increase in winds during day, diminishing in
-                                       evening</option>
+                               <option value="N">@text/velocityN</option>
+                               <option value="F">@text/velocityF</option>
+                               <option value="S">@text/velocityS</option>
+                               <option value="G">@text/velocityG</option>
+                               <option value="W">@text/velocityW</option>
+                               <option value="H">@text/velocityH</option>
+                               <option value="D">@text/velocityD</option>
+                               <option value="U">@text/velocityU</option>
                        </options>
                </state>
        </channel-type>
 
        <channel-type id="wind-direction">
                <item-type>String</item-type>
-               <label>Wind Direction</label>
-               <description>Wind direction</description>
+               <label>@text/windDirectionLabel</label>
                <category>Wind</category>
                <state readOnly="true" pattern="%s"/>
        </channel-type>
 
-       <channel-type id="wind-angle-rw">
-               <item-type>Number:Angle</item-type>
-               <label>Wind Angle</label>
-               <description>Wind Angle</description>
-               <category>Wind</category>
-               <state readOnly="false" pattern="%.0f %unit%"/>
-       </channel-type>
-
        <channel-type id="wind-evolution" advanced="true">
                <item-type>String</item-type>
-               <label>Wind Evolution</label>
-               <description>Wind bearing evolution trend over observation delay</description>
+               <label>@text/windEvolutionLabel</label>
+               <description>@text/windEvolutionDescription</description>
                <state readOnly="true" pattern="%s">
                        <options>
-                               <option value="1">Steady</option>
-                               <option value="2">Veering</option>
-                               <option value="3">Backing</option>
+                               <option value="1">@text/evolution1</option>
+                               <option value="2">@text/evolution2</option>
+                               <option value="3">@text/evolution3</option>
                        </options>
                </state>
        </channel-type>
 
        <channel-type id="trend" advanced="true">
                <item-type>String</item-type>
-               <label>Measure Trend</label>
-               <description>Measure evolution trend over observation delay</description>
+               <label>@text/trendLabel</label>
+               <description>@text/trendDescription</description>
                <state readOnly="true" pattern="%s">
                        <options>
-                               <option value="1">Rising Rapidly</option>
-                               <option value="2">Rising Slowly</option>
-                               <option value="3">Normal</option>
-                               <option value="4">Decreasing Slowly</option>
-                               <option value="5">Decreasing Rapidly</option>
+                               <option value="1">@text/trend1</option>
+                               <option value="2">@text/trend2</option>
+                               <option value="3">@text/trend3</option>
+                               <option value="4">@text/trend4</option>
+                               <option value="5">@text/trend5</option>
                        </options>
                </state>
        </channel-type>
 
        <channel-type id="timestamp" advanced="true">
                <item-type>DateTime</item-type>
-               <label>Calculation Time</label>
-               <description>Weather forecast calculation date and time</description>
+               <label>@text/timestampLabel</label>
+               <description>@text/timestampDescription</description>
                <category>Observation time</category>
                <state readOnly="true"></state>
        </channel-type>
 
        <channel-type id="cloudiness">
                <item-type>Number:Dimensionless</item-type>
-               <label>Cloudiness</label>
-               <description>Current cloudiness.</description>
+               <label>@text/cloudinessLabel</label>
+               <description>@text/cloudinessDescription</description>
                <category>Clouds</category>
                <state min="0" max="100" pattern="%d %%"/>
        </channel-type>
 
        <channel-type id="rain-qtty" advanced="true">
                <item-type>Number</item-type>
-               <label>Rain Quantity</label>
-               <description>Current rain quantity</description>
+               <label>@text/rainQttyLabel</label>
+               <description>@text/rainQttyDescription</description>
                <category>Rain</category>
+               <tags>
+                       <tag>Measurement</tag>
+                       <tag>Rain</tag>
+               </tags>
                <state pattern="%.2f %unit%"/>
        </channel-type>
 
        <channel-type id="is-raining">
                <item-type>Switch</item-type>
-               <label>Raining</label>
-               <description>Is it currently raining ?</description>
+               <label>@text/rainingLabel</label>
+               <description>@text/rainingDescription</description>
                <category>Rain</category>
+               <tags>
+                       <tag>Status</tag>
+                       <tag>Rain</tag>
+               </tags>
        </channel-type>
 
        <channel-type id="wind-speed-beaufort">
                <item-type>Number</item-type>
-               <label>Beaufort</label>
-               <description>Wind speed using Beaufort Scale</description>
+               <label>@text/beaufortLabel</label>
+               <description>@text/beaufortDescription</description>
                <category>Wind</category>
+               <tags>
+                       <tag>Measurement</tag>
+                       <tag>Wind</tag>
+               </tags>
                <state min="0" max="12" pattern="%d"/>
        </channel-type>
 
-       <channel-type id="pressure">
-               <item-type>Number:Pressure</item-type>
-               <label>Sea Level Pressure</label>
-               <description>Sea Level Pressure</description>
-               <category>Pressure</category>
-               <state pattern="%.3f %unit%"/>
-       </channel-type>
-
-       <channel-type id="temperature">
-               <item-type>Number:Temperature</item-type>
-               <label>Temperature</label>
-               <description>Current temperature</description>
-               <category>Temperature</category>
-               <state pattern="%.1f %unit%"/>
-       </channel-type>
 </thing:thing-descriptions>