diff --git a/bundles/org.openhab.binding.synopanalyzer/src/main/java/org/openhab/binding/synopanalyser/internal/discovery/SynopAnalyzerDiscoveryService.java b/bundles/org.openhab.binding.synopanalyzer/src/main/java/org/openhab/binding/synopanalyser/internal/discovery/SynopAnalyzerDiscoveryService.java index a6ceab6b4fd..860a579d003 100644 --- a/bundles/org.openhab.binding.synopanalyzer/src/main/java/org/openhab/binding/synopanalyser/internal/discovery/SynopAnalyzerDiscoveryService.java +++ b/bundles/org.openhab.binding.synopanalyzer/src/main/java/org/openhab/binding/synopanalyser/internal/discovery/SynopAnalyzerDiscoveryService.java @@ -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 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 = 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()); } diff --git a/bundles/org.openhab.binding.synopanalyzer/src/main/java/org/openhab/binding/synopanalyser/internal/synop/Overcast.java b/bundles/org.openhab.binding.synopanalyzer/src/main/java/org/openhab/binding/synopanalyser/internal/synop/Overcast.java index ed80912891e..decfe3c2be0 100644 --- a/bundles/org.openhab.binding.synopanalyzer/src/main/java/org/openhab/binding/synopanalyser/internal/synop/Overcast.java +++ b/bundles/org.openhab.binding.synopanalyzer/src/main/java/org/openhab/binding/synopanalyser/internal/synop/Overcast.java @@ -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; diff --git a/bundles/org.openhab.binding.synopanalyzer/src/main/java/org/openhab/binding/synopanalyzer/internal/SynopAnalyzerHandlerFactory.java b/bundles/org.openhab.binding.synopanalyzer/src/main/java/org/openhab/binding/synopanalyzer/internal/SynopAnalyzerHandlerFactory.java index 3edec5c9c38..aeaac3e11a3 100644 --- a/bundles/org.openhab.binding.synopanalyzer/src/main/java/org/openhab/binding/synopanalyzer/internal/SynopAnalyzerHandlerFactory.java +++ b/bundles/org.openhab.binding.synopanalyzer/src/main/java/org/openhab/binding/synopanalyzer/internal/SynopAnalyzerHandlerFactory.java @@ -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 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<>()); diff --git a/bundles/org.openhab.binding.synopanalyzer/src/main/java/org/openhab/binding/synopanalyzer/internal/handler/SynopAnalyzerHandler.java b/bundles/org.openhab.binding.synopanalyzer/src/main/java/org/openhab/binding/synopanalyzer/internal/handler/SynopAnalyzerHandler.java index 06a7df44105..28b7f5712f9 100644 --- a/bundles/org.openhab.binding.synopanalyzer/src/main/java/org/openhab/binding/synopanalyzer/internal/handler/SynopAnalyzerHandler.java +++ b/bundles/org.openhab.binding.synopanalyzer/src/main/java/org/openhab/binding/synopanalyzer/internal/handler/SynopAnalyzerHandler.java @@ -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 properties = new HashMap<>(); - - Optional 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 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 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 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 index 00000000000..70db3de5a2c --- /dev/null +++ b/bundles/org.openhab.binding.synopanalyzer/src/main/resources/OH-INF/i18n/synopanalyzer_fr.properties @@ -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 diff --git a/bundles/org.openhab.binding.synopanalyzer/src/main/resources/OH-INF/thing/thing-types.xml b/bundles/org.openhab.binding.synopanalyzer/src/main/resources/OH-INF/thing/thing-types.xml index 39b8f3983eb..3ee79409b70 100644 --- a/bundles/org.openhab.binding.synopanalyzer/src/main/resources/OH-INF/thing/thing-types.xml +++ b/bundles/org.openhab.binding.synopanalyzer/src/main/resources/OH-INF/thing/thing-types.xml @@ -6,14 +6,14 @@ - The Synop Analyzer binding decodes Synop messages + This is the interpretation of the last message of a given station. - + @@ -75,14 +75,16 @@ Number - Octa + Cloud cover estimation. + sun_clouds - + Number Cloud layer mitigation factor + sun_clouds @@ -90,6 +92,7 @@ String Overcast + sun_clouds @@ -117,6 +120,7 @@ DateTime Timestamp when data was observed + time