]> git.basschouten.com Git - openhab-addons.git/commitdiff
[Synopanalyzer] Adding French localization, correction on overcast channel (#10113)
authorGaël L'hopital <gael@lhopital.org>
Wed, 17 Feb 2021 10:50:14 +0000 (11:50 +0100)
committerGitHub <noreply@github.com>
Wed, 17 Feb 2021 10:50:14 +0000 (11:50 +0100)
* Adding French localization of the binding
* Correction on overcast channel
* Correcting nullable issues

Signed-off-by: clinique <gael@lhopital.org>
bundles/org.openhab.binding.synopanalyzer/src/main/java/org/openhab/binding/synopanalyser/internal/discovery/SynopAnalyzerDiscoveryService.java
bundles/org.openhab.binding.synopanalyzer/src/main/java/org/openhab/binding/synopanalyser/internal/synop/Overcast.java
bundles/org.openhab.binding.synopanalyzer/src/main/java/org/openhab/binding/synopanalyzer/internal/SynopAnalyzerHandlerFactory.java
bundles/org.openhab.binding.synopanalyzer/src/main/java/org/openhab/binding/synopanalyzer/internal/handler/SynopAnalyzerHandler.java
bundles/org.openhab.binding.synopanalyzer/src/main/resources/OH-INF/i18n/synopanalyzer_fr.properties [new file with mode: 0644]
bundles/org.openhab.binding.synopanalyzer/src/main/resources/OH-INF/thing/thing-types.xml

index a6ceab6b4fd1163cd7eb6d878c42784a93c47178..860a579d0031d9e7100a09d9d2b69aa1de48ba25 100644 (file)
@@ -42,11 +42,12 @@ import org.slf4j.LoggerFactory;
  */
 @NonNullByDefault
 public class SynopAnalyzerDiscoveryService extends AbstractDiscoveryService {
-    private final Logger logger = LoggerFactory.getLogger(SynopAnalyzerDiscoveryService.class);
     private static final int DISCOVER_TIMEOUT_SECONDS = 5;
-    private LocationProvider locationProvider;
-    private final StationDB stationDB;
+
+    private final Logger logger = LoggerFactory.getLogger(SynopAnalyzerDiscoveryService.class);
     private final Map<Integer, Double> distances = new HashMap<>();
+    private final LocationProvider locationProvider;
+    private final StationDB stationDB;
 
     /**
      * Creates a SynopAnalyzerDiscoveryService with enabled autostart.
@@ -84,8 +85,8 @@ public class SynopAnalyzerDiscoveryService extends AbstractDiscoveryService {
 
         Integer nearestId = result.entrySet().iterator().next().getKey();
         Optional<Station> station = stationDB.stations.stream().filter(s -> s.idOmm == nearestId).findFirst();
-        thingDiscovered(DiscoveryResultBuilder.create(new ThingUID(THING_SYNOP, Integer.toString(nearestId)))
-                .withLabel("Synop : " + station.get().usualName)
+        thingDiscovered(DiscoveryResultBuilder.create(new ThingUID(THING_SYNOP, nearestId.toString()))
+                .withLabel(String.format("Synop : %s", station.get().usualName))
                 .withProperty(SynopAnalyzerConfiguration.STATION_ID, nearestId)
                 .withRepresentationProperty(SynopAnalyzerConfiguration.STATION_ID).build());
     }
index ed80912891ec8a890301b7c067cd6496ba5fc31f..decfe3c2be0dbd1577b7e2eaf439f36a74ce220e 100644 (file)
@@ -29,7 +29,7 @@ public enum Overcast {
     public static Overcast fromOcta(int octa) {
         if (octa == 0) {
             return Overcast.CLEAR_SKY;
-        } else if (octa > 0 && octa < 8) {
+        } else if (octa > 0 && octa < 9) {
             return Overcast.CLOUDY;
         } else if (octa == 9) {
             return Overcast.SKY_NOT_VISIBLE;
index 3edec5c9c387cc469a0984abf33b130f8810a2e1..aeaac3e11a348062dce073e8be74156607a6923e 100644 (file)
@@ -18,9 +18,8 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.io.Reader;
-import java.util.Collections;
+import java.nio.charset.StandardCharsets;
 import java.util.Hashtable;
-import java.util.Set;
 
 import org.eclipse.jdt.annotation.NonNullByDefault;
 import org.eclipse.jdt.annotation.Nullable;
@@ -55,28 +54,25 @@ import com.google.gson.Gson;
 @NonNullByDefault
 public class SynopAnalyzerHandlerFactory extends BaseThingHandlerFactory {
     private final Logger logger = LoggerFactory.getLogger(SynopAnalyzerHandlerFactory.class);
-    private static final Set<ThingTypeUID> SUPPORTED_THING_TYPES_UIDS = Collections.singleton(THING_SYNOP);
     private final LocationProvider locationProvider;
-    private final Gson gson;
-    private @NonNullByDefault({}) StationDB stationDB;
+    private final Gson gson = new Gson();
+    private @Nullable StationDB stationDB;
     private @Nullable ServiceRegistration<?> serviceReg;
 
     @Activate
     public SynopAnalyzerHandlerFactory(@Reference LocationProvider locationProvider) {
         this.locationProvider = locationProvider;
-        this.gson = new Gson();
     }
 
     @Override
     public boolean supportsThingType(ThingTypeUID thingTypeUID) {
-        return SUPPORTED_THING_TYPES_UIDS.contains(thingTypeUID);
+        return THING_SYNOP.equals(thingTypeUID);
     }
 
     @Override
     protected @Nullable ThingHandler createHandler(Thing thing) {
-        ThingTypeUID thingTypeUID = thing.getThingTypeUID();
-
-        return thingTypeUID.equals(THING_SYNOP) ? new SynopAnalyzerHandler(thing, locationProvider, stationDB) : null;
+        return supportsThingType(thing.getThingTypeUID()) ? new SynopAnalyzerHandler(thing, locationProvider, stationDB)
+                : null;
     }
 
     @Override
@@ -84,14 +80,14 @@ public class SynopAnalyzerHandlerFactory extends BaseThingHandlerFactory {
         super.activate(componentContext);
 
         try (InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream("/db/stations.json");
-                Reader reader = new InputStreamReader(is, "UTF-8");) {
+                Reader reader = new InputStreamReader(is, StandardCharsets.UTF_8);) {
 
-            stationDB = gson.fromJson(reader, StationDB.class);
-            registerDiscoveryService();
+            StationDB stations = gson.fromJson(reader, StationDB.class);
+            registerDiscoveryService(stations);
+            this.stationDB = stations;
             logger.debug("Discovery service for Synop Stations registered.");
         } catch (IOException e) {
             logger.warn("Unable to read synop stations database");
-            stationDB = new StationDB();
         }
     }
 
@@ -101,8 +97,8 @@ public class SynopAnalyzerHandlerFactory extends BaseThingHandlerFactory {
         super.deactivate(componentContext);
     }
 
-    private void registerDiscoveryService() {
-        SynopAnalyzerDiscoveryService discoveryService = new SynopAnalyzerDiscoveryService(stationDB, locationProvider);
+    private void registerDiscoveryService(StationDB stations) {
+        SynopAnalyzerDiscoveryService discoveryService = new SynopAnalyzerDiscoveryService(stations, locationProvider);
 
         serviceReg = bundleContext.registerService(DiscoveryService.class.getName(), discoveryService,
                 new Hashtable<>());
index 06a7df44105958c411c2c53ac89f4232dc514d77..28b7f5712f9a4d4890768409ed36bb02009b2755 100644 (file)
@@ -28,12 +28,12 @@ import java.util.concurrent.ScheduledFuture;
 import java.util.concurrent.TimeUnit;
 
 import javax.measure.quantity.Speed;
+import javax.ws.rs.HttpMethod;
 
 import org.eclipse.jdt.annotation.NonNullByDefault;
 import org.eclipse.jdt.annotation.Nullable;
 import org.openhab.binding.synopanalyser.internal.synop.Overcast;
 import org.openhab.binding.synopanalyser.internal.synop.StationDB;
-import org.openhab.binding.synopanalyser.internal.synop.StationDB.Station;
 import org.openhab.binding.synopanalyser.internal.synop.Synop;
 import org.openhab.binding.synopanalyser.internal.synop.SynopLand;
 import org.openhab.binding.synopanalyser.internal.synop.SynopMobile;
@@ -77,12 +77,11 @@ public class SynopAnalyzerHandler extends BaseThingHandler {
     private final Logger logger = LoggerFactory.getLogger(SynopAnalyzerHandler.class);
 
     private @Nullable ScheduledFuture<?> executionJob;
-    // private @NonNullByDefault({}) SynopAnalyzerConfiguration configuration;
     private @NonNullByDefault({}) String formattedStationId;
     private final LocationProvider locationProvider;
-    private final StationDB stationDB;
+    private final @Nullable StationDB stationDB;
 
-    public SynopAnalyzerHandler(Thing thing, LocationProvider locationProvider, StationDB stationDB) {
+    public SynopAnalyzerHandler(Thing thing, LocationProvider locationProvider, @Nullable StationDB stationDB) {
         super(thing);
         this.locationProvider = locationProvider;
         this.stationDB = stationDB;
@@ -95,20 +94,18 @@ public class SynopAnalyzerHandler extends BaseThingHandler {
         logger.info("Scheduling Synop update thread to run every {} minute for Station '{}'",
                 configuration.refreshInterval, formattedStationId);
 
-        if (thing.getProperties().isEmpty()) {
-            discoverAttributes(configuration.stationId);
+        StationDB stations = stationDB;
+        if (thing.getProperties().isEmpty() && stations != null) {
+            discoverAttributes(stations, configuration.stationId);
         }
 
         executionJob = scheduler.scheduleWithFixedDelay(this::updateSynopChannels, 0, configuration.refreshInterval,
                 TimeUnit.MINUTES);
-        updateStatus(ThingStatus.UNKNOWN);
     }
 
-    protected void discoverAttributes(int stationId) {
-        final Map<String, String> properties = new HashMap<>();
-
-        Optional<Station> station = stationDB.stations.stream().filter(s -> stationId == s.idOmm).findFirst();
-        station.ifPresent(s -> {
+    protected void discoverAttributes(StationDB stations, int stationId) {
+        stations.stations.stream().filter(s -> stationId == s.idOmm).findFirst().ifPresent(s -> {
+            Map<String, String> properties = new HashMap<>();
             properties.put("Usual name", s.usualName);
             properties.put("Location", s.getLocation());
 
@@ -119,9 +116,8 @@ public class SynopAnalyzerHandler extends BaseThingHandler {
 
                 properties.put("Distance", new QuantityType<>(distance, SIUnits.METRE).toString());
             }
+            updateProperties(properties);
         });
-
-        updateProperties(properties);
     }
 
     private Optional<Synop> getLastAvailableSynop() {
@@ -129,7 +125,7 @@ public class SynopAnalyzerHandler extends BaseThingHandler {
 
         String url = forgeURL();
         try {
-            String answer = HttpUtil.executeUrl("GET", url, REQUEST_TIMEOUT_MS);
+            String answer = HttpUtil.executeUrl(HttpMethod.GET, url, REQUEST_TIMEOUT_MS);
             List<String> messages = Arrays.asList(answer.split("\n"));
             if (!messages.isEmpty()) {
                 String message = messages.get(messages.size() - 1);
@@ -159,7 +155,9 @@ public class SynopAnalyzerHandler extends BaseThingHandler {
         synop.ifPresent(theSynop -> {
             getThing().getChannels().forEach(channel -> {
                 String channelId = channel.getUID().getId();
-                updateState(channelId, getChannelState(channelId, theSynop));
+                if (isLinked(channelId)) {
+                    updateState(channelId, getChannelState(channelId, theSynop));
+                }
             });
         });
     }
diff --git a/bundles/org.openhab.binding.synopanalyzer/src/main/resources/OH-INF/i18n/synopanalyzer_fr.properties b/bundles/org.openhab.binding.synopanalyzer/src/main/resources/OH-INF/i18n/synopanalyzer_fr.properties
new file mode 100644 (file)
index 0000000..70db3de
--- /dev/null
@@ -0,0 +1,44 @@
+# binding
+binding.synopanalyzer.name = Extension Synop Analyzer
+binding.synopanalyzer.description = Synop Analyzer permet de télécharger et interpréter les messages SYNOP.
+
+# thing type
+thing-type.synopanalyzer.synopanalyzer.label = Message Synop
+thing-type.synopanalyzer.synopanalyzer.description = Décodage du dernier message d'une station Synop.
+
+# channel types
+channel-type.synopanalyzer.wind-speed-beaufort.label = Beaufort
+channel-type.synopanalyzer.wind-speed-beaufort.description = Force du vent sur l'échelle Beaufort.
+
+channel-type.synopanalyzer.wind-direction.label = Direction du vent
+channel-type.synopanalyzer.wind-direction.description = Equivalent cardinal de la direction du vent.
+# Only translating those that needs a french adaptation (containing "W")
+channel-type.synopanalyzer.wind-direction.state.option.SSW = SSO
+channel-type.synopanalyzer.wind-direction.state.option.SW = SO
+channel-type.synopanalyzer.wind-direction.state.option.WSW = OSO
+channel-type.synopanalyzer.wind-direction.state.option.W = O
+channel-type.synopanalyzer.wind-direction.state.option.WNW = ONO
+channel-type.synopanalyzer.wind-direction.state.option.NW = NO
+channel-type.synopanalyzer.wind-direction.state.option.NNW = NNO
+
+channel-type.synopanalyzer.octa.label = Octa
+channel-type.synopanalyzer.octa.description = Evaluation de la couverture nuageuse.
+
+channel-type.synopanalyzer.attenuation-factor.label = Coefficient d'atténuation
+channel-type.synopanalyzer.attenuation-factor.description = Atténuation générée par la couverture nuageuse.
+
+channel-type.synopanalyzer.overcast.label = Couverture nuageuse
+channel-type.synopanalyzer.overcast.description = Appréciation de la couverture nuageuse.
+channel-type.synopanalyzer.overcast.state.option.CLEAR_SKY = Ciel dégagé
+channel-type.synopanalyzer.overcast.state.option.CLOUDY = Nuageux
+channel-type.synopanalyzer.overcast.state.option.SKY_NOT_VISIBLE = Ciel non visible
+
+channel-type.synopanalyzer.horizontal-visibility.label = Visibilité horizontale
+channel-type.synopanalyzer.horizontal-visibility.description = Ordre de grandeur de la visibilité horizontale.
+channel-type.synopanalyzer.horizontal-visibility.state.option.LESS_THAN_1 = Moins de 1 km
+channel-type.synopanalyzer.horizontal-visibility.state.option.LESS_THAN_10 = Entre 1 et 10 km
+channel-type.synopanalyzer.horizontal-visibility.state.option.LESS_THAN_50 = Entre 10 et 50 km
+channel-type.synopanalyzer.horizontal-visibility.state.option.MORE_THAN_50 = Plus de 50 km
+
+channel-type.synopanalyzer.time-utc.label = Horodatage
+channel-type.synopanalyzer.time-utc.description = Heure d'observation des mesures relevées
index 39b8f3983eb090373948bd3a92cd6a12296b75e4..3ee79409b708828e27c7bf8806c1a439042a553c 100644 (file)
@@ -6,14 +6,14 @@
 
        <thing-type id="synopanalyzer">
                <label>Synop Message</label>
-               <description>The Synop Analyzer binding decodes Synop messages</description>
+               <description>This is the interpretation of the last message of a given station.</description>
 
                <channels>
                        <channel id="temperature" typeId="system.outdoor-temperature"/>
                        <channel id="pressure" typeId="system.barometric-pressure"/>
                        <channel id="wind-angle" typeId="system.wind-direction"/>
-                       <channel id="wind-direction" typeId="wind-direction"/>
                        <channel id="wind-speed" typeId="system.wind-speed"/>
+                       <channel id="wind-direction" typeId="wind-direction"/>
                        <channel id="wind-speed-beaufort" typeId="wind-speed-beaufort"/>
                        <channel id="overcast" typeId="overcast"/>
                        <channel id="octa" typeId="octa"/>
        <channel-type id="octa">
                <item-type>Number</item-type>
                <label>Octa</label>
-               <description>Octa</description>
+               <description>Cloud cover estimation.</description>
+               <category>sun_clouds</category>
                <state readOnly="true" pattern="%d/8" min="0" max="8"/>
        </channel-type>
 
-       <channel-type id="attenuation-factor">
+       <channel-type id="attenuation-factor" advanced="true">
                <item-type>Number</item-type>
                <label>Mitigation Factor</label>
                <description>Cloud layer mitigation factor</description>
+               <category>sun_clouds</category>
                <state readOnly="true" pattern="%.1f" max="1" min="0"/>
        </channel-type>
 
@@ -90,6 +92,7 @@
                <item-type>String</item-type>
                <label>Overcast</label>
                <description>Overcast</description>
+               <category>sun_clouds</category>
                <state readOnly="true" pattern="%s">
                        <options>
                                <option value="CLEAR_SKY">Clear sky</option>
                <item-type>DateTime</item-type>
                <label>Observation Time</label>
                <description>Timestamp when data was observed</description>
+               <category>time</category>
                <state readOnly="true"/>
        </channel-type>