]> git.basschouten.com Git - openhab-addons.git/commitdiff
[Vigicrues] OH3 enhancements (#8952)
authorGaël L'hopital <gael@lhopital.org>
Mon, 9 Nov 2020 16:41:48 +0000 (17:41 +0100)
committerGitHub <noreply@github.com>
Mon, 9 Nov 2020 16:41:48 +0000 (08:41 -0800)
* Staging work
Saving my work
Vigicrues extensions for OH3
First code review
* Code review and some corrections
* Code review enhancements
Changed alert to Number

* Code review corrections
* Correcting my error
* Adressing SAT finding

Signed-off-by: clinique <gael@lhopital.org>
32 files changed:
bundles/org.openhab.binding.vigicrues/README.md
bundles/org.openhab.binding.vigicrues/src/main/java/org/openhab/binding/vigicrues/internal/StationConfiguration.java [new file with mode: 0644]
bundles/org.openhab.binding.vigicrues/src/main/java/org/openhab/binding/vigicrues/internal/VigiCruesBindingConstants.java
bundles/org.openhab.binding.vigicrues/src/main/java/org/openhab/binding/vigicrues/internal/VigiCruesConfiguration.java [deleted file]
bundles/org.openhab.binding.vigicrues/src/main/java/org/openhab/binding/vigicrues/internal/VigiCruesHandlerFactory.java
bundles/org.openhab.binding.vigicrues/src/main/java/org/openhab/binding/vigicrues/internal/api/ApiHandler.java [new file with mode: 0644]
bundles/org.openhab.binding.vigicrues/src/main/java/org/openhab/binding/vigicrues/internal/api/VigiCruesCertificateProvider.java [new file with mode: 0644]
bundles/org.openhab.binding.vigicrues/src/main/java/org/openhab/binding/vigicrues/internal/api/VigiCruesException.java [new file with mode: 0644]
bundles/org.openhab.binding.vigicrues/src/main/java/org/openhab/binding/vigicrues/internal/discovery/VigiCruesDiscoveryService.java [new file with mode: 0644]
bundles/org.openhab.binding.vigicrues/src/main/java/org/openhab/binding/vigicrues/internal/dto/hubeau/HubEauResponse.java [new file with mode: 0644]
bundles/org.openhab.binding.vigicrues/src/main/java/org/openhab/binding/vigicrues/internal/dto/opendatasoft/OpenDatasoftResponse.java [new file with mode: 0644]
bundles/org.openhab.binding.vigicrues/src/main/java/org/openhab/binding/vigicrues/internal/dto/opendatasoft/Parameters.java [new file with mode: 0644]
bundles/org.openhab.binding.vigicrues/src/main/java/org/openhab/binding/vigicrues/internal/dto/opendatasoft/Record.java [new file with mode: 0644]
bundles/org.openhab.binding.vigicrues/src/main/java/org/openhab/binding/vigicrues/internal/dto/opendatasoft/Refine.java [new file with mode: 0644]
bundles/org.openhab.binding.vigicrues/src/main/java/org/openhab/binding/vigicrues/internal/dto/opendatasoft/VigiCruesFields.java [new file with mode: 0644]
bundles/org.openhab.binding.vigicrues/src/main/java/org/openhab/binding/vigicrues/internal/dto/vigicrues/CdStationHydro.java [new file with mode: 0644]
bundles/org.openhab.binding.vigicrues/src/main/java/org/openhab/binding/vigicrues/internal/dto/vigicrues/InfoVigiCru.java [new file with mode: 0644]
bundles/org.openhab.binding.vigicrues/src/main/java/org/openhab/binding/vigicrues/internal/dto/vigicrues/TerEntVigiCru.java [new file with mode: 0644]
bundles/org.openhab.binding.vigicrues/src/main/java/org/openhab/binding/vigicrues/internal/dto/vigicrues/TronEntVigiCru.java [new file with mode: 0644]
bundles/org.openhab.binding.vigicrues/src/main/java/org/openhab/binding/vigicrues/internal/dto/vigicrues/VicANMoinsUn.java [new file with mode: 0644]
bundles/org.openhab.binding.vigicrues/src/main/java/org/openhab/binding/vigicrues/internal/handler/VigiCruesHandler.java
bundles/org.openhab.binding.vigicrues/src/main/java/org/openhab/binding/vigicrues/internal/json/OpenDatasoftResponse.java [deleted file]
bundles/org.openhab.binding.vigicrues/src/main/java/org/openhab/binding/vigicrues/internal/json/Parameters.java [deleted file]
bundles/org.openhab.binding.vigicrues/src/main/java/org/openhab/binding/vigicrues/internal/json/Record.java [deleted file]
bundles/org.openhab.binding.vigicrues/src/main/java/org/openhab/binding/vigicrues/internal/json/Refine.java [deleted file]
bundles/org.openhab.binding.vigicrues/src/main/java/org/openhab/binding/vigicrues/internal/json/VigiCruesFields.java [deleted file]
bundles/org.openhab.binding.vigicrues/src/main/resources/OH-INF/thing/thing-types.xml
bundles/org.openhab.binding.vigicrues/src/main/resources/picto/crue-0.svg [new file with mode: 0644]
bundles/org.openhab.binding.vigicrues/src/main/resources/picto/crue-1.svg [new file with mode: 0644]
bundles/org.openhab.binding.vigicrues/src/main/resources/picto/crue-2.svg [new file with mode: 0644]
bundles/org.openhab.binding.vigicrues/src/main/resources/picto/crue-3.svg [new file with mode: 0644]
bundles/org.openhab.binding.vigicrues/src/main/resources/vigicrues.cer [new file with mode: 0644]

index 744569a98129d3acddfd462233628132016e0bdb..cadece3d34460823e7e7ba56dc10b7342ad5c624 100644 (file)
@@ -23,7 +23,10 @@ Of course, you can add multiple Things, e.g. for getting measures for different
 
 ## Discovery
 
-This binding does not handle auto-discovery.
+You can discover stations based upon the system location.
+Select Vigicrues binding and click scan in order to discover new stations. 
+The first scan will proceed with stations located in a radius of 10 km. 
+This radius will increase by 10 km at each new scan.
 
 ## Binding Configuration
 
@@ -41,13 +44,31 @@ The thing has a few configuration parameters:
 
 ## Channels
 
+Once created, at first initialization, the thing will discover its capabilities (available data) using the webservices apis.
+Channels will be presented depending upon actual available data.
+
 The VigiCrues information that retrieved are made available with these channels:
 
-| Channel ID       | Item Type                 | Description                   |
-|------------------|---------------------------|-------------------------------|
-| observation-time | DateTime                  | Date and time of measurement  |
-| flow             | Number:VolumetricFlowRate | Volume of water per time unit |
-| height           | Number:Length             | Water height of the river     |
+| Channel ID       | Item Type                 | Description                                                |
+|------------------|---------------------------|------------------------------------------------------------|
+| observation-time | DateTime                  | Date and time of measurement                               |
+| flow             | Number:VolumetricFlowRate | Volume of water per time unit                              |
+| height           | Number:Length             | Water height of the river                                  |
+| relative-height  | Number:Dimensionless      | Current water level toward lowest historical flood         |
+| relative-flow    | Number:Dimensionless      | Current water flow tower lowest historical flood           |
+| alert (*)        | Number                    | Flooding alert level of the portion related to the station |
+| alert-icon       | Image                     | Pictogram associated to the alert level                    |
+| short-comment    | String                    | Description of the alert level                             |
+| comment          | String                    | Detailed informations regarding the ongoing event          |
+
+(*) Each alert level is described by a color : 
+
+| Code | Color  | Description                               |
+|------|--------|-------------------------------------------|
+| 0    | Green  | No particular vigilance                   |
+| 1    | Yellow | Be attentive to the flooding situation    |
+| 2    | Orange | Be "very vigilant" in the concerned areas |
+| 3    | Red    | Absolute vigilance required               |
 
 
 ## Full Example
diff --git a/bundles/org.openhab.binding.vigicrues/src/main/java/org/openhab/binding/vigicrues/internal/StationConfiguration.java b/bundles/org.openhab.binding.vigicrues/src/main/java/org/openhab/binding/vigicrues/internal/StationConfiguration.java
new file mode 100644 (file)
index 0000000..e83ba6a
--- /dev/null
@@ -0,0 +1,29 @@
+/**
+ * Copyright (c) 2010-2020 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.vigicrues.internal;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+
+/**
+ * The {@link StationConfiguration} is the class used to match the
+ * thing configuration.
+ *
+ * @author Gaël L'hopital - Initial contribution
+ */
+@NonNullByDefault
+public class StationConfiguration {
+    public static String ID = "id";
+
+    public String id = "";
+    public int refresh = 30;
+}
index 791a7c7a445f668e3d98a3bd9b6e4376feb21c43..50660cbce796dc41699dae6dc59f66fb027912b7 100644 (file)
@@ -28,17 +28,27 @@ import org.openhab.core.thing.ThingTypeUID;
 public class VigiCruesBindingConstants {
 
     public static final String BINDING_ID = "vigicrues";
-    public static final String OPENDATASOFT_URL = "https://public.opendatasoft.com/api/records/1.0/search/";
 
     // List of all Thing Type UIDs
-    public static final ThingTypeUID THING_TYPE_VIGI_CRUES = new ThingTypeUID(BINDING_ID, "station");
+    public static final ThingTypeUID THING_TYPE_STATION = new ThingTypeUID(BINDING_ID, "station");
 
     // List of all Channel id's
     public static final String OBSERVATION_TIME = "observation-time";
     public static final String HEIGHT = "height";
     public static final String FLOW = "flow";
-
+    public static final String ALERT = "alert";
     public static final String COMMENT = "comment";
-
-    public static final Set<ThingTypeUID> SUPPORTED_THING_TYPES_UIDS = Collections.singleton(THING_TYPE_VIGI_CRUES);
+    public static final String RELATIVE_PREFIX = "relative";
+    public static final String RELATIVE_HEIGHT = RELATIVE_PREFIX + "-" + HEIGHT;
+    public static final String RELATIVE_FLOW = RELATIVE_PREFIX + "-" + FLOW;
+    public static final String SHORT_COMMENT = "short-" + COMMENT;
+
+    // List of properties Labels
+    public static final String TRONCON = "Tronçon";
+    public static final String DISTANCE = "Distance";
+    public static final String RIVER = "Cours";
+    public static final String LOCATION = "Location";
+    public static final String FLOOD = "Crue";
+
+    public static final Set<ThingTypeUID> SUPPORTED_THING_TYPES_UIDS = Collections.singleton(THING_TYPE_STATION);
 }
diff --git a/bundles/org.openhab.binding.vigicrues/src/main/java/org/openhab/binding/vigicrues/internal/VigiCruesConfiguration.java b/bundles/org.openhab.binding.vigicrues/src/main/java/org/openhab/binding/vigicrues/internal/VigiCruesConfiguration.java
deleted file mode 100644 (file)
index 7148589..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-/**
- * Copyright (c) 2010-2020 Contributors to the openHAB project
- *
- * See the NOTICE file(s) distributed with this work for additional
- * information.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0
- *
- * SPDX-License-Identifier: EPL-2.0
- */
-package org.openhab.binding.vigicrues.internal;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-
-/**
- * The {@link VigiCruesConfiguration} is the class used to match the
- * thing configuration.
- *
- * @author Gaël L'hopital - Initial contribution
- */
-@NonNullByDefault
-public class VigiCruesConfiguration {
-    public String id = "";
-    public int refresh = 30;
-}
index f37b32681134245e23bec91c14fbe126d2c7bd41..03fe45c277988d0b9cc4b6b3ec0149d893e1783d 100644 (file)
  */
 package org.openhab.binding.vigicrues.internal;
 
-import static org.openhab.binding.vigicrues.internal.VigiCruesBindingConstants.*;
-
-import java.time.ZonedDateTime;
+import static org.openhab.binding.vigicrues.internal.VigiCruesBindingConstants.SUPPORTED_THING_TYPES_UIDS;
 
 import org.eclipse.jdt.annotation.NonNullByDefault;
 import org.eclipse.jdt.annotation.Nullable;
+import org.openhab.binding.vigicrues.internal.api.ApiHandler;
 import org.openhab.binding.vigicrues.internal.handler.VigiCruesHandler;
-import org.openhab.core.i18n.TimeZoneProvider;
+import org.openhab.core.i18n.LocationProvider;
 import org.openhab.core.thing.Thing;
 import org.openhab.core.thing.ThingTypeUID;
 import org.openhab.core.thing.binding.BaseThingHandlerFactory;
@@ -29,10 +28,6 @@ import org.osgi.service.component.annotations.Activate;
 import org.osgi.service.component.annotations.Component;
 import org.osgi.service.component.annotations.Reference;
 
-import com.google.gson.Gson;
-import com.google.gson.GsonBuilder;
-import com.google.gson.JsonDeserializer;
-
 /**
  * The {@link VigiCruesHandlerFactory} is responsible for creating things and thing
  * handlers.
@@ -42,17 +37,13 @@ import com.google.gson.JsonDeserializer;
 @Component(service = ThingHandlerFactory.class, configurationPid = "binding.vigicrues")
 @NonNullByDefault
 public class VigiCruesHandlerFactory extends BaseThingHandlerFactory {
-    private final Gson gson;
-    // Needed for converting UTC time to local time
-    private final TimeZoneProvider timeZoneProvider;
+    private final LocationProvider locationProvider;
+    private final ApiHandler apiHandler;
 
     @Activate
-    public VigiCruesHandlerFactory(@Reference TimeZoneProvider timeZoneProvider) {
-        this.timeZoneProvider = timeZoneProvider;
-        this.gson = new GsonBuilder()
-                .registerTypeAdapter(ZonedDateTime.class, (JsonDeserializer<ZonedDateTime>) (json, type,
-                        jsonDeserializationContext) -> ZonedDateTime.parse(json.getAsJsonPrimitive().getAsString()))
-                .create();
+    public VigiCruesHandlerFactory(@Reference ApiHandler apiHandler, @Reference LocationProvider locationProvider) {
+        this.locationProvider = locationProvider;
+        this.apiHandler = apiHandler;
     }
 
     @Override
@@ -63,11 +54,6 @@ public class VigiCruesHandlerFactory extends BaseThingHandlerFactory {
     @Override
     protected @Nullable ThingHandler createHandler(Thing thing) {
         ThingTypeUID thingTypeUID = thing.getThingTypeUID();
-
-        if (thingTypeUID.equals(THING_TYPE_VIGI_CRUES)) {
-            return new VigiCruesHandler(thing, timeZoneProvider, gson);
-        }
-
-        return null;
+        return supportsThingType(thingTypeUID) ? new VigiCruesHandler(thing, locationProvider, apiHandler) : null;
     }
 }
diff --git a/bundles/org.openhab.binding.vigicrues/src/main/java/org/openhab/binding/vigicrues/internal/api/ApiHandler.java b/bundles/org.openhab.binding.vigicrues/src/main/java/org/openhab/binding/vigicrues/internal/api/ApiHandler.java
new file mode 100644 (file)
index 0000000..05508eb
--- /dev/null
@@ -0,0 +1,110 @@
+/**
+ * Copyright (c) 2010-2020 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.vigicrues.internal.api;
+
+import java.io.IOException;
+import java.time.ZonedDateTime;
+import java.util.Locale;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.openhab.binding.vigicrues.internal.dto.hubeau.HubEauResponse;
+import org.openhab.binding.vigicrues.internal.dto.opendatasoft.OpenDatasoftResponse;
+import org.openhab.binding.vigicrues.internal.dto.vigicrues.CdStationHydro;
+import org.openhab.binding.vigicrues.internal.dto.vigicrues.InfoVigiCru;
+import org.openhab.binding.vigicrues.internal.dto.vigicrues.TerEntVigiCru;
+import org.openhab.binding.vigicrues.internal.dto.vigicrues.TronEntVigiCru;
+import org.openhab.core.i18n.TimeZoneProvider;
+import org.openhab.core.io.net.http.HttpUtil;
+import org.openhab.core.library.types.PointType;
+import org.osgi.service.component.annotations.Activate;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Reference;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import com.google.gson.JsonDeserializer;
+import com.google.gson.JsonSyntaxException;
+
+/**
+ * The {@link ApiHandler} is the responsible to call a given
+ * url and transform the answer in the appropriate dto class
+ *
+ * @author Gaël L'hopital - Initial contribution
+ */
+
+@Component(service = ApiHandler.class)
+@NonNullByDefault
+public class ApiHandler {
+    private static final int TIMEOUT_MS = 30000;
+    private final Gson gson;
+
+    @Activate
+    public ApiHandler(@Reference TimeZoneProvider timeZoneProvider) {
+        this.gson = new GsonBuilder().registerTypeAdapter(ZonedDateTime.class,
+                (JsonDeserializer<ZonedDateTime>) (json, type, jsonDeserializationContext) -> ZonedDateTime
+                        .parse(json.getAsJsonPrimitive().getAsString())
+                        .withZoneSameInstant(timeZoneProvider.getTimeZone()))
+                .create();
+    }
+
+    private <T> T execute(String url, Class<T> responseType) throws VigiCruesException {
+        String jsonResponse = "";
+        try {
+            jsonResponse = HttpUtil.executeUrl("GET", url, TIMEOUT_MS);
+            return gson.fromJson(jsonResponse, responseType);
+        } catch (IOException e) {
+            throw new VigiCruesException(e);
+        } catch (JsonSyntaxException e) {
+            throw new VigiCruesException(e);
+        }
+    }
+
+    public InfoVigiCru getTronconStatus(String tronconId) throws VigiCruesException {
+        final String BASE_URL = "https://www.vigicrues.gouv.fr/services/1/InfoVigiCru.jsonld/?TypEntVigiCru=8&CdEntVigiCru=%s";
+        return execute(String.format(BASE_URL, tronconId), InfoVigiCru.class);
+    }
+
+    public TronEntVigiCru getTroncon(String stationId) throws VigiCruesException {
+        final String BASE_URL = "https://www.vigicrues.gouv.fr/services/1/TronEntVigiCru.jsonld/?TypEntVigiCru=8&CdEntVigiCru=%s";
+        return execute(String.format(BASE_URL, stationId), TronEntVigiCru.class);
+    }
+
+    public TerEntVigiCru getTerritoire(String stationId) throws VigiCruesException {
+        final String BASE_URL = "https://www.vigicrues.gouv.fr/services/1/TerEntVigiCru.jsonld/?TypEntVigiCru=5&CdEntVigiCru=%s";
+        return execute(String.format(BASE_URL, stationId), TerEntVigiCru.class);
+    }
+
+    public CdStationHydro getStationDetails(String stationId) throws VigiCruesException {
+        final String BASE_URL = "https://www.vigicrues.gouv.fr/services/station.json/index.php?CdStationHydro=%s";
+        return execute(String.format(BASE_URL, stationId), CdStationHydro.class);
+    }
+
+    public OpenDatasoftResponse getMeasures(String stationId) throws VigiCruesException {
+        final String BASE_URL = "https://public.opendatasoft.com/api/records/1.0/search/?dataset=vigicrues&sort=timestamp&q=%s";
+        return execute(String.format(BASE_URL, stationId), OpenDatasoftResponse.class);
+    }
+
+    public HubEauResponse discoverStations(PointType location, int range) throws VigiCruesException {
+        final String BASE_URL = "https://hubeau.eaufrance.fr/api/v1/hydrometrie/referentiel/stations?format=json&size=2000";
+
+        return execute(
+                BASE_URL + String.format(Locale.US, "&latitude=%.2f&longitude=%.2f&distance=%d",
+                        location.getLatitude().floatValue(), location.getLongitude().floatValue(), range),
+                HubEauResponse.class);
+    }
+
+    public HubEauResponse discoverStations(String stationId) throws VigiCruesException {
+        final String BASE_URL = "https://hubeau.eaufrance.fr/api/v1/hydrometrie/referentiel/stations?format=json&size=2000";
+        return execute(BASE_URL + String.format("&code_station=%s", stationId), HubEauResponse.class);
+    }
+}
diff --git a/bundles/org.openhab.binding.vigicrues/src/main/java/org/openhab/binding/vigicrues/internal/api/VigiCruesCertificateProvider.java b/bundles/org.openhab.binding.vigicrues/src/main/java/org/openhab/binding/vigicrues/internal/api/VigiCruesCertificateProvider.java
new file mode 100644 (file)
index 0000000..dcc6bcc
--- /dev/null
@@ -0,0 +1,44 @@
+/**
+ * Copyright (c) 2010-2020 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.vigicrues.internal.api;
+
+import java.net.URL;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.openhab.core.io.net.http.TlsCertificateProvider;
+import org.osgi.service.component.annotations.Component;
+
+/**
+ * Provides a TrustManager for the VigiCrues SSL certificate
+ *
+ * @author Gaël L'hopital - Initial Contribution
+ */
+@Component
+@NonNullByDefault
+public class VigiCruesCertificateProvider implements TlsCertificateProvider {
+
+    @Override
+    public String getHostName() {
+        return "www.vigicrues.gouv.fr";
+    }
+
+    @Override
+    public URL getCertificate() {
+        URL resource = Thread.currentThread().getContextClassLoader().getResource("vigicrues.cer");
+        if (resource != null) {
+            return resource;
+        } else {
+            throw new IllegalStateException("Certifcate resource not found or not accessible");
+        }
+    }
+}
diff --git a/bundles/org.openhab.binding.vigicrues/src/main/java/org/openhab/binding/vigicrues/internal/api/VigiCruesException.java b/bundles/org.openhab.binding.vigicrues/src/main/java/org/openhab/binding/vigicrues/internal/api/VigiCruesException.java
new file mode 100644 (file)
index 0000000..35b0d0f
--- /dev/null
@@ -0,0 +1,37 @@
+/**
+ * Copyright (c) 2010-2020 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.vigicrues.internal.api;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+
+/**
+ * Exception for errors when using the VigiCrues API
+ *
+ * @author Gaël L'hopital - Initial contribution
+ */
+@NonNullByDefault
+public class VigiCruesException extends Exception {
+    private static final long serialVersionUID = -7781683052187130152L;
+
+    public VigiCruesException(Throwable e) {
+        super(null, e);
+    }
+
+    public VigiCruesException(String msg, Throwable cause) {
+        super(msg, cause);
+    }
+
+    public VigiCruesException(String msg) {
+        super(msg, null);
+    }
+}
diff --git a/bundles/org.openhab.binding.vigicrues/src/main/java/org/openhab/binding/vigicrues/internal/discovery/VigiCruesDiscoveryService.java b/bundles/org.openhab.binding.vigicrues/src/main/java/org/openhab/binding/vigicrues/internal/discovery/VigiCruesDiscoveryService.java
new file mode 100644 (file)
index 0000000..c2b9489
--- /dev/null
@@ -0,0 +1,81 @@
+/**
+ * Copyright (c) 2010-2020 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.vigicrues.internal.discovery;
+
+import static org.openhab.binding.vigicrues.internal.VigiCruesBindingConstants.*;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.openhab.binding.vigicrues.internal.StationConfiguration;
+import org.openhab.binding.vigicrues.internal.api.ApiHandler;
+import org.openhab.binding.vigicrues.internal.api.VigiCruesException;
+import org.openhab.binding.vigicrues.internal.dto.hubeau.HubEauResponse;
+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.LocationProvider;
+import org.openhab.core.library.types.PointType;
+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;
+import org.slf4j.LoggerFactory;
+
+/**
+ * The {@link VigiCruesDiscoveryService} searches for available
+ * hydro stations discoverable through API
+ *
+ * @author Gaël L'hopital - Initial contribution
+ */
+@Component(service = DiscoveryService.class, configurationPid = "discovery.vigicrues")
+@NonNullByDefault
+public class VigiCruesDiscoveryService extends AbstractDiscoveryService {
+    private static final int SEARCH_TIME = 5;
+
+    private final Logger logger = LoggerFactory.getLogger(VigiCruesDiscoveryService.class);
+    private final LocationProvider locationProvider;
+    private final ApiHandler apiHandler;
+
+    private int searchRange = 10;
+
+    @Activate
+    public VigiCruesDiscoveryService(@Reference ApiHandler apiHandler, @Reference LocationProvider locationProvider) {
+        super(SUPPORTED_THING_TYPES_UIDS, SEARCH_TIME, false);
+        this.apiHandler = apiHandler;
+        this.locationProvider = locationProvider;
+    }
+
+    @Override
+    public void startScan() {
+        PointType location = locationProvider.getLocation();
+        if (location != null) {
+            try {
+                HubEauResponse response = apiHandler.discoverStations(location, searchRange);
+                if (response.count > 0) {
+                    response.stations.stream().filter(station -> station.enService).forEach(station -> {
+                        thingDiscovered(DiscoveryResultBuilder
+                                .create(new ThingUID(THING_TYPE_STATION, station.codeStation))
+                                .withLabel(station.libelleStation).withRepresentationProperty(StationConfiguration.ID)
+                                .withProperty(StationConfiguration.ID, station.codeStation).build());
+                    });
+                } else {
+                    logger.info("No station exists in a neighbourhood of {} km", searchRange);
+                }
+            } catch (VigiCruesException e) {
+                logger.warn("Error discovering nearby hydro stations : {}", e.getMessage());
+            }
+            searchRange += 10;
+        }
+        stopScan();
+    }
+}
diff --git a/bundles/org.openhab.binding.vigicrues/src/main/java/org/openhab/binding/vigicrues/internal/dto/hubeau/HubEauResponse.java b/bundles/org.openhab.binding.vigicrues/src/main/java/org/openhab/binding/vigicrues/internal/dto/hubeau/HubEauResponse.java
new file mode 100644 (file)
index 0000000..3aea34b
--- /dev/null
@@ -0,0 +1,157 @@
+package org.openhab.binding.vigicrues.internal.dto.hubeau;
+
+import java.util.List;
+
+import com.google.gson.annotations.SerializedName;
+
+public class HubEauResponse {
+    public class StationData {
+        @SerializedName("en_service")
+        public boolean enService;
+
+        @SerializedName("code_station")
+        public String codeStation;
+
+        @SerializedName("libelle_station")
+        public String libelleStation;
+
+        @SerializedName("longitude_station")
+        public double longitudeStation;
+
+        @SerializedName("latitude_station")
+        public double latitudeStation;
+
+        @SerializedName("libelle_cours_eau")
+        public String libelleCoursEau;
+        /*
+         * Currently unused, maybe interesting in the future
+         *
+         * @SerializedName("code_site")
+         * public String codeSite;
+         *
+         * @SerializedName("libelle_site")
+         * public String libelleSite;
+         *
+         * @SerializedName("type_station")
+         * public String typeStation;
+         *
+         * @SerializedName("coordonnee_x_station")
+         * public int coordonneeXStation;
+         *
+         * @SerializedName("coordonnee_y_station")
+         * public int coordonneeYStation;
+         *
+         * @SerializedName("code_projection")
+         * public int codeProjection;
+         *
+         * @SerializedName("influence_locale_station")
+         * public int influenceLocaleStation;
+         *
+         * @SerializedName("commentaire_station")
+         * public String commentaireStation;
+         *
+         * @SerializedName("altitude_ref_alti_station")
+         * public double altitudeRefAltiStation;
+         *
+         * @SerializedName("code_systeme_alti_site")
+         * public int codeSystemeAltiSite;
+         *
+         * @SerializedName("code_commune_station")
+         * public String codeCommuneStation;
+         *
+         * @SerializedName("libelle_commune")
+         * public String libelleCommune;
+         *
+         * @SerializedName("code_departement")
+         * public String codeDepartement;
+         *
+         * @SerializedName("code_region")
+         * public String codeRegion;
+         *
+         * @SerializedName("libelle_region")
+         * public String libelleRegion;
+         *
+         * @SerializedName("code_cours_eau")
+         * public String codeCoursEau;
+         *
+         * @SerializedName("uri_cours_eau")
+         * public String uriCoursEau;
+         *
+         * @SerializedName("descriptif_station")
+         * public String descriptifStation;
+         *
+         * @SerializedName("date_maj_station")
+         * public String dateMajStation;
+         *
+         * @SerializedName("date_ouverture_station")
+         * public String dateOuvertureStation;
+         *
+         * @SerializedName("date_fermeture_station")
+         * public String dateFermetureStation;
+         *
+         * @SerializedName("commentaire_influence_locale_station")
+         * public String commentaireInfluenceLocaleStation;
+         *
+         * @SerializedName("code_regime_station")
+         * public int codeRegimeStation;
+         *
+         * @SerializedName("qualification_donnees_station")
+         * public int qualificationDonneesStation;
+         *
+         * @SerializedName("code_finalite_station")
+         * public int codeFinaliteStation;
+         *
+         * @SerializedName("type_contexte_loi_stat_station")
+         * public int typeContexteLoiStatStation;
+         *
+         * @SerializedName("type_loi_station")
+         * public int typeLoiStation;
+         *
+         * @SerializedName("code_sandre_reseau_station")
+         * public List<String> codeSandreReseauStation;
+         *
+         * @SerializedName("date_debut_ref_alti_station")
+         * public String dateDebutRefAltiStation;
+         *
+         * @SerializedName("date_activation_ref_alti_station")
+         * public String dateActivationRefAltiStation;
+         *
+         * @SerializedName("date_maj_ref_alti_station")
+         * public String dateMajRefAltiStation;
+         *
+         * @SerializedName("libelle_departement")
+         * public String libelleDepartement;
+         * public Geometry geometry;
+         */
+    }
+
+    public int count;
+    @SerializedName("data")
+    public List<StationData> stations;
+
+    /*
+     * Currently unused, maybe interesting in the future
+     * public String first;
+     * public String last;
+     * public String prev;
+     * public String next;
+     *
+     * @SerializedName("api_version")
+     * public String apiVersion;
+     *
+     * public class Crs {
+     * public String type;
+     * public Properties properties;
+     * }
+     *
+     * public class Properties {
+     * public String name;
+     * }
+     *
+     * public class Geometry {
+     * public String type;
+     * public Crs crs;
+     * public List<Double> coordinates;
+     * }
+     */
+}
diff --git a/bundles/org.openhab.binding.vigicrues/src/main/java/org/openhab/binding/vigicrues/internal/dto/opendatasoft/OpenDatasoftResponse.java b/bundles/org.openhab.binding.vigicrues/src/main/java/org/openhab/binding/vigicrues/internal/dto/opendatasoft/OpenDatasoftResponse.java
new file mode 100644 (file)
index 0000000..c033892
--- /dev/null
@@ -0,0 +1,52 @@
+/**
+ * Copyright (c) 2010-2020 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.vigicrues.internal.dto.opendatasoft;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+
+import com.google.gson.annotations.SerializedName;
+
+/**
+ * The {@link OpenDatasoftResponse} is the Java class used to map the JSON
+ * response to an opendatasoft endpoint request.
+ *
+ * @author Gaël L'hopital - Initial contribution
+ */
+@NonNullByDefault
+public class OpenDatasoftResponse {
+    @SerializedName("nhits")
+    private int nHits;
+    private @Nullable Parameters parameters;
+    private List<Record> records = new ArrayList<>();
+
+    public int getNHits() {
+        return nHits;
+    }
+
+    public Optional<Parameters> getParameters() {
+        Parameters parameters = this.parameters;
+        if (parameters != null) {
+            return Optional.of(parameters);
+        }
+        return Optional.empty();
+    }
+
+    public Optional<VigiCruesFields> getFirstRecord() {
+        return records.stream().findFirst().flatMap(Record::getFields);
+    }
+}
diff --git a/bundles/org.openhab.binding.vigicrues/src/main/java/org/openhab/binding/vigicrues/internal/dto/opendatasoft/Parameters.java b/bundles/org.openhab.binding.vigicrues/src/main/java/org/openhab/binding/vigicrues/internal/dto/opendatasoft/Parameters.java
new file mode 100644 (file)
index 0000000..c5cb5b1
--- /dev/null
@@ -0,0 +1,64 @@
+/**
+ * Copyright (c) 2010-2020 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.vigicrues.internal.dto.opendatasoft;
+
+import java.time.ZoneId;
+import java.util.Arrays;
+import java.util.Optional;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+
+/**
+ * The {@link Parameters} is the Java class used to map the JSON
+ * response to the webservice request.
+ *
+ * @author Gaël L'hopital - Initial contribution
+ */
+@NonNullByDefault
+public class Parameters {
+    private String[] dataset = {};
+    private String timezone = "";
+    private int rows;
+    private String format = "";
+    private @Nullable Refine refine;
+    private String[] facet = {};
+
+    public Optional<String> getDataset() {
+        return Arrays.stream(dataset).findFirst();
+    }
+
+    public ZoneId getTimezone() {
+        return ZoneId.of(timezone);
+    }
+
+    public int getRows() {
+        return rows;
+    }
+
+    public String getFormat() {
+        return format;
+    }
+
+    public Optional<Refine> getRefine() {
+        Refine refine = this.refine;
+        if (refine != null) {
+            return Optional.of(refine);
+        }
+        return Optional.empty();
+    }
+
+    public String[] getFacets() {
+        return facet;
+    }
+}
diff --git a/bundles/org.openhab.binding.vigicrues/src/main/java/org/openhab/binding/vigicrues/internal/dto/opendatasoft/Record.java b/bundles/org.openhab.binding.vigicrues/src/main/java/org/openhab/binding/vigicrues/internal/dto/opendatasoft/Record.java
new file mode 100644 (file)
index 0000000..cd67dee
--- /dev/null
@@ -0,0 +1,57 @@
+/**
+ * Copyright (c) 2010-2020 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.vigicrues.internal.dto.opendatasoft;
+
+import java.util.Optional;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+
+import com.google.gson.annotations.SerializedName;
+
+/**
+ * The {@link Record} is the Java class used to map the JSON
+ * response to the webservice request.
+ *
+ * @author Gaël L'hopital - Initial contribution
+ */
+@NonNullByDefault
+public class Record {
+    @SerializedName("datasetid")
+    private String datasetId = "";
+    @SerializedName("recordid")
+    private String recordId = "";
+    @SerializedName("record_timestamp")
+    private String recordTimestamp = "";
+    private @Nullable VigiCruesFields fields;
+
+    public String getDatasetId() {
+        return datasetId;
+    }
+
+    public String getRecordId() {
+        return recordId;
+    }
+
+    public String getRecordTimestamp() {
+        return recordTimestamp;
+    }
+
+    public Optional<VigiCruesFields> getFields() {
+        VigiCruesFields fields = this.fields;
+        if (fields != null) {
+            return Optional.of(fields);
+        }
+        return Optional.empty();
+    }
+}
diff --git a/bundles/org.openhab.binding.vigicrues/src/main/java/org/openhab/binding/vigicrues/internal/dto/opendatasoft/Refine.java b/bundles/org.openhab.binding.vigicrues/src/main/java/org/openhab/binding/vigicrues/internal/dto/opendatasoft/Refine.java
new file mode 100644 (file)
index 0000000..145dad5
--- /dev/null
@@ -0,0 +1,33 @@
+/**
+ * Copyright (c) 2010-2020 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.vigicrues.internal.dto.opendatasoft;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+
+import com.google.gson.annotations.SerializedName;
+
+/**
+ * The {@link Refine} is the Java class used to map the JSON
+ * response to the webservice request.
+ *
+ * @author Gaël L'hopital - Initial contribution
+ */
+@NonNullByDefault
+public class Refine {
+    @SerializedName("nom_dept")
+    private String departmentName = "";
+
+    public String getDepartmentName() {
+        return departmentName;
+    }
+}
diff --git a/bundles/org.openhab.binding.vigicrues/src/main/java/org/openhab/binding/vigicrues/internal/dto/opendatasoft/VigiCruesFields.java b/bundles/org.openhab.binding.vigicrues/src/main/java/org/openhab/binding/vigicrues/internal/dto/opendatasoft/VigiCruesFields.java
new file mode 100644 (file)
index 0000000..c813515
--- /dev/null
@@ -0,0 +1,60 @@
+/**
+ * Copyright (c) 2010-2020 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.vigicrues.internal.dto.opendatasoft;
+
+import java.time.ZonedDateTime;
+import java.util.Optional;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+
+import com.google.gson.annotations.SerializedName;
+
+/**
+ * The {@link VigiCruesFields} is the Java class used to map the JSON
+ * response to the webservice request.
+ *
+ * @author Gaël L'hopital - Initial contribution
+ */
+@NonNullByDefault
+public class VigiCruesFields {
+    @SerializedName("debit")
+    private @Nullable Double flow;
+    @SerializedName("hauteur")
+    private @Nullable Double height;
+    private @Nullable ZonedDateTime timestamp;
+
+    public Optional<ZonedDateTime> getTimestamp() {
+        ZonedDateTime timestamp = this.timestamp;
+        if (timestamp != null) {
+            return Optional.of(timestamp);
+        }
+        return Optional.empty();
+    }
+
+    public Optional<Double> getFlow() {
+        Double flow = this.flow;
+        if (flow != null) {
+            return Optional.of(flow);
+        }
+        return Optional.empty();
+    }
+
+    public Optional<Double> getHeight() {
+        Double height = this.height;
+        if (height != null) {
+            return Optional.of(height);
+        }
+        return Optional.empty();
+    }
+}
diff --git a/bundles/org.openhab.binding.vigicrues/src/main/java/org/openhab/binding/vigicrues/internal/dto/vigicrues/CdStationHydro.java b/bundles/org.openhab.binding.vigicrues/src/main/java/org/openhab/binding/vigicrues/internal/dto/vigicrues/CdStationHydro.java
new file mode 100644 (file)
index 0000000..e0adc42
--- /dev/null
@@ -0,0 +1,104 @@
+/**
+ * Copyright (c) 2010-2020 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.vigicrues.internal.dto.vigicrues;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+
+import org.openhab.binding.vigicrues.internal.VigiCruesBindingConstants;
+
+import com.google.gson.annotations.SerializedName;
+
+/**
+ * The {@link CdStationHydro} is the Java class used to map the JSON
+ * response to an vigicrue api endpoint request.
+ *
+ * @author Gaël L'hopital - Initial contribution
+ */
+public class CdStationHydro {
+
+    public class PereBoitEntVigiCru {
+        @SerializedName("CdEntVigiCru")
+        public String cdEntVigiCru;
+    }
+
+    public class CruesHistorique {
+        @SerializedName("LbUsuel")
+        public String name;
+        @SerializedName("ValHauteur")
+        public double height;
+        @SerializedName("ValDebit")
+        public double flow;
+
+        public Map<String, String> getDescription() {
+            Map<String, String> result = new HashMap<>();
+            if (height != 0) {
+                result.put(String.format("%s %s (%s)", VigiCruesBindingConstants.FLOOD,
+                        VigiCruesBindingConstants.HEIGHT, name), String.format(Locale.US, "%.2f m", height));
+            }
+            if (flow != 0) {
+                result.put(String.format("%s %s (%s)", VigiCruesBindingConstants.FLOOD, VigiCruesBindingConstants.FLOW,
+                        name), String.format(Locale.US, "%.2f m³/s", flow));
+            }
+            return result;
+        }
+    }
+
+    public class VigilanceCrues {
+        @SerializedName("PereBoitEntVigiCru")
+        public PereBoitEntVigiCru pereBoitEntVigiCru;
+        @SerializedName("CruesHistoriques")
+        public List<CruesHistorique> cruesHistoriques;
+        /*
+         * Currently unused, maybe interesting in the future
+         *
+         * @SerializedName("StationPrevision")
+         * public String stationPrevision;
+         *
+         * @SerializedName("Photo")
+         * public String photo;
+         *
+         * @SerializedName("ZoomInitial")
+         * public String zoomInitial;
+         */
+    }
+
+    @SerializedName("VigilanceCrues")
+    public VigilanceCrues vigilanceCrues;
+    /*
+     * Currently unused, maybe interesting in the future
+     *
+     * @SerializedName("VersionFlux")
+     * public String versionFlux;
+     *
+     * @SerializedName("CdStationHydro")
+     * public String cdStationHydro;
+     *
+     * @SerializedName("LbStationHydro")
+     * public String lbStationHydro;
+     *
+     * @SerializedName("LbCoursEau")
+     * public String lbCoursEau;
+     *
+     * @SerializedName("CdStationHydroAncienRef")
+     * public String cdStationHydroAncienRef;
+     *
+     * @SerializedName("CdCommune")
+     * public String cdCommune;
+     *
+     * @SerializedName("error_msg")
+     * public String errorMsg;
+     */
+}
diff --git a/bundles/org.openhab.binding.vigicrues/src/main/java/org/openhab/binding/vigicrues/internal/dto/vigicrues/InfoVigiCru.java b/bundles/org.openhab.binding.vigicrues/src/main/java/org/openhab/binding/vigicrues/internal/dto/vigicrues/InfoVigiCru.java
new file mode 100644 (file)
index 0000000..0151cc5
--- /dev/null
@@ -0,0 +1,56 @@
+/**
+ * Copyright (c) 2010-2020 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.vigicrues.internal.dto.vigicrues;
+
+import com.google.gson.annotations.SerializedName;
+
+/**
+ * The {@link InfoVigiCru} is the Java class used to map the JSON
+ * response to an vigicrue api endpoint request.
+ *
+ * @author Gaël L'hopital - Initial contribution
+ */
+public class InfoVigiCru {
+    public class VicInfoVigiCru {
+        @SerializedName("vic:NivInfoVigiCru")
+        public int vicNivInfoVigiCru;
+        @SerializedName("vic:SituActuInfoVigiCru")
+        public String vicSituActuInfoVigiCru;
+        @SerializedName("vic:QualifInfoVigiCru")
+        public String vicQualifInfoVigiCru;
+        /*
+         * Currently unused, maybe interesting in the future
+         *
+         * @SerializedName("vic:RefInfoVigiCru")
+         * private String vicRefInfoVigiCru;
+         *
+         * @SerializedName("vic:TypInfoVigiCru")
+         * private int vicTypInfoVigiCru;
+         *
+         * @SerializedName("vic:DtHrInfoVigiCru")
+         * private String vicDtHrInfoVigiCru;
+         *
+         * @SerializedName("vic:DtHrSuivInfoVigiCru")
+         * private String vicDtHrSuivInfoVigiCru;
+         *
+         * @SerializedName("vic:EstNivCalInfoVigiCru")
+         * private Boolean vicEstNivCalInfoVigiCru;
+         *
+         * @SerializedName("vic:StInfoVigiCru")
+         * private int vicStInfoVigiCru;
+         */
+    }
+
+    @SerializedName("vic:InfoVigiCru")
+    public VicInfoVigiCru vicInfoVigiCru;
+}
diff --git a/bundles/org.openhab.binding.vigicrues/src/main/java/org/openhab/binding/vigicrues/internal/dto/vigicrues/TerEntVigiCru.java b/bundles/org.openhab.binding.vigicrues/src/main/java/org/openhab/binding/vigicrues/internal/dto/vigicrues/TerEntVigiCru.java
new file mode 100644 (file)
index 0000000..3e6d1d6
--- /dev/null
@@ -0,0 +1,62 @@
+/**
+ * Copyright (c) 2010-2020 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.vigicrues.internal.dto.vigicrues;
+
+import java.util.List;
+
+import com.google.gson.annotations.SerializedName;
+
+/**
+ * The {@link TerEntVigiCru} is the Java class used to map the JSON
+ * response to an vigicrue api endpoint request.
+ *
+ * @author Gaël L'hopital - Initial contribution
+ */
+public class TerEntVigiCru {
+
+    public class VicTerEntVigiCru {
+        @SerializedName("vic:aNMoinsUn")
+        public List<VicANMoinsUn> vicANMoinsUn;
+        /*
+         * Currently unused, maybe interesting in the future
+         *
+         * @SerializedName("@id")
+         * public String id;
+         *
+         * @SerializedName("vic:CdEntVigiCru")
+         * public String vicCdEntVigiCru;
+         *
+         * @SerializedName("vic:TypEntVigiCru")
+         * public String vicTypEntVigiCru;
+         *
+         * @SerializedName("vic:LbEntVigiCru")
+         * public String vicLbEntVigiCru;
+         *
+         * @SerializedName("vic:DtHrCreatEntVigiCru")
+         * public String vicDtHrCreatEntVigiCru;
+         *
+         * @SerializedName("vic:DtHrMajEntVigiCru")
+         * public String vicDtHrMajEntVigiCru;
+         *
+         * @SerializedName("vic:StEntVigiCru")
+         * public String vicStEntVigiCru;
+         * public int count_aNMoinsUn;
+         *
+         * @SerializedName("LinkInfoCru")
+         * public String linkInfoCru;
+         */
+    }
+
+    @SerializedName("vic:TerEntVigiCru")
+    public VicTerEntVigiCru vicTerEntVigiCru;
+}
diff --git a/bundles/org.openhab.binding.vigicrues/src/main/java/org/openhab/binding/vigicrues/internal/dto/vigicrues/TronEntVigiCru.java b/bundles/org.openhab.binding.vigicrues/src/main/java/org/openhab/binding/vigicrues/internal/dto/vigicrues/TronEntVigiCru.java
new file mode 100644 (file)
index 0000000..b038368
--- /dev/null
@@ -0,0 +1,80 @@
+/**
+ * Copyright (c) 2010-2020 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.vigicrues.internal.dto.vigicrues;
+
+import java.util.List;
+import java.util.stream.Stream;
+
+import com.google.gson.annotations.SerializedName;
+
+/**
+ * The {@link TronEntVigiCru} is the Java class used to map the JSON
+ * response to an vigicrue api endpoint request.
+ *
+ * @author Gaël L'hopital - Initial contribution
+ */
+public class TronEntVigiCru {
+    public class VicStaEntVigiCru {
+        @SerializedName("vic:CdEntVigiCru")
+        public String vicCdEntVigiCru;
+    }
+
+    public class VicTronEntVigiCru {
+        @SerializedName("vic:aNMoinsUn")
+        public List<VicStaEntVigiCru> stations;
+        /*
+         * Currently unused, maybe interesting in the future
+         *
+         * @SerializedName("@id")
+         * public String id;
+         *
+         * @SerializedName("vic:CdEntVigiCru")
+         * public String vicCdEntVigiCru;
+         *
+         * @SerializedName("vic:TypEntVigiCru")
+         * public String vicTypEntVigiCru;
+         *
+         * @SerializedName("vic:LbEntVigiCru")
+         * public String vicLbEntVigiCru;
+         *
+         * @SerializedName("vic:DtHrCreatEntVigiCru")
+         * public String vicDtHrCreatEntVigiCru;
+         *
+         * @SerializedName("vic:DtHrMajEntVigiCru")
+         * public String vicDtHrMajEntVigiCru;
+         *
+         * @SerializedName("vic:StEntVigiCru")
+         * public String vicStEntVigiCru;
+         *
+         * @SerializedName("count_aNPlusUn")
+         * public Integer countANPlusUn;
+         *
+         * @SerializedName("count_aNMoinsUn")
+         * public Integer countANMoinsUn;
+         *
+         * @SerializedName("LinkInfoCru")
+         * public String linkInfoCru;
+         */
+    }
+
+    @SerializedName("vic:TronEntVigiCru")
+    private VicTronEntVigiCru tronTerEntVigiCru;
+
+    public Stream<VicStaEntVigiCru> getStations() {
+        if (tronTerEntVigiCru != null && tronTerEntVigiCru.stations != null) {
+            return tronTerEntVigiCru.stations.stream();
+        } else {
+            return Stream.empty();
+        }
+    }
+}
diff --git a/bundles/org.openhab.binding.vigicrues/src/main/java/org/openhab/binding/vigicrues/internal/dto/vigicrues/VicANMoinsUn.java b/bundles/org.openhab.binding.vigicrues/src/main/java/org/openhab/binding/vigicrues/internal/dto/vigicrues/VicANMoinsUn.java
new file mode 100644 (file)
index 0000000..afac4cb
--- /dev/null
@@ -0,0 +1,45 @@
+/**
+ * Copyright (c) 2010-2020 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.vigicrues.internal.dto.vigicrues;
+
+import com.google.gson.annotations.SerializedName;
+
+/**
+ * The {@link VicANMoinsUn} is the Java class used to map the JSON
+ * response to an vigicrue api endpoint request.
+ *
+ * @author Gaël L'hopital - Initial contribution
+ */
+public class VicANMoinsUn {
+    @SerializedName("vic.CdEntVigiCru")
+    public String vicCdEntVigiCru;
+
+    /*
+     * Currently unused, maybe interesting in the future
+     *
+     * @SerializedName("@id")
+     * private String id;
+     *
+     * @SerializedName("vic.TypEntVigiCru")
+     * private String vicTypEntVigiCru;
+     *
+     * @SerializedName("vic.LbEntVigiCru")
+     * private String vicLbEntVigiCru;
+     *
+     * @SerializedName("LinkEntity")
+     * private String linkEntity;
+     *
+     * @SerializedName("LinkInfoCru")
+     * private String linkInfoCru;
+     */
+}
index 1b6ff686a9a95959e30465c7062e8a2d24620620..02909f64f0ace769911280b79f14914e6422be70 100644 (file)
 package org.openhab.binding.vigicrues.internal.handler;
 
 import static org.openhab.binding.vigicrues.internal.VigiCruesBindingConstants.*;
-import static org.openhab.core.library.unit.SmartHomeUnits.CUBICMETRE_PER_SECOND;
-import static tec.uom.se.unit.Units.METRE;
 
 import java.io.IOException;
-import java.net.MalformedURLException;
+import java.io.InputStream;
 import java.time.ZonedDateTime;
-import java.util.Arrays;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
 import java.util.concurrent.ScheduledFuture;
 import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
 
 import javax.measure.Unit;
 
 import org.eclipse.jdt.annotation.NonNullByDefault;
 import org.eclipse.jdt.annotation.Nullable;
-import org.openhab.binding.vigicrues.internal.VigiCruesConfiguration;
-import org.openhab.binding.vigicrues.internal.json.OpenDatasoftResponse;
-import org.openhab.binding.vigicrues.internal.json.Record;
-import org.openhab.core.i18n.TimeZoneProvider;
-import org.openhab.core.io.net.http.HttpUtil;
+import org.openhab.binding.vigicrues.internal.StationConfiguration;
+import org.openhab.binding.vigicrues.internal.api.ApiHandler;
+import org.openhab.binding.vigicrues.internal.api.VigiCruesException;
+import org.openhab.binding.vigicrues.internal.dto.hubeau.HubEauResponse;
+import org.openhab.binding.vigicrues.internal.dto.opendatasoft.OpenDatasoftResponse;
+import org.openhab.binding.vigicrues.internal.dto.vigicrues.CdStationHydro;
+import org.openhab.binding.vigicrues.internal.dto.vigicrues.InfoVigiCru;
+import org.openhab.binding.vigicrues.internal.dto.vigicrues.TerEntVigiCru;
+import org.openhab.binding.vigicrues.internal.dto.vigicrues.TronEntVigiCru;
+import org.openhab.binding.vigicrues.internal.dto.vigicrues.VicANMoinsUn;
+import org.openhab.core.i18n.LocationProvider;
 import org.openhab.core.library.types.DateTimeType;
+import org.openhab.core.library.types.DecimalType;
+import org.openhab.core.library.types.PointType;
 import org.openhab.core.library.types.QuantityType;
+import org.openhab.core.library.types.RawType;
+import org.openhab.core.library.types.StringType;
+import org.openhab.core.library.unit.SIUnits;
+import org.openhab.core.library.unit.SmartHomeUnits;
+import org.openhab.core.thing.Channel;
 import org.openhab.core.thing.ChannelUID;
 import org.openhab.core.thing.Thing;
 import org.openhab.core.thing.ThingStatus;
 import org.openhab.core.thing.ThingStatusDetail;
 import org.openhab.core.thing.binding.BaseThingHandler;
+import org.openhab.core.thing.binding.builder.ThingBuilder;
 import org.openhab.core.types.Command;
 import org.openhab.core.types.RefreshType;
+import org.openhab.core.types.UnDefType;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.gson.Gson;
-
 /**
  * The {@link VigiCruesHandler} is responsible for querying the API and
  * updating channels
@@ -54,35 +70,124 @@ import com.google.gson.Gson;
  */
 @NonNullByDefault
 public class VigiCruesHandler extends BaseThingHandler {
-    private static final String URL = OPENDATASOFT_URL + "?dataset=vigicrues&sort=timestamp&q=";
-    private static final int TIMEOUT_MS = 30000;
     private final Logger logger = LoggerFactory.getLogger(VigiCruesHandler.class);
+    private final LocationProvider locationProvider;
 
-    // Time zone provider representing time zone configured in openHAB configuration
-    private final TimeZoneProvider timeZoneProvider;
-    private final Gson gson;
     private @Nullable ScheduledFuture<?> refreshJob;
-    private @Nullable String queryUrl;
+    private final ApiHandler apiHandler;
+
+    private List<QuantityType<?>> referenceHeights = new ArrayList<>();
+    private List<QuantityType<?>> referenceFlows = new ArrayList<>();
+    private @Nullable String portion;
 
-    public VigiCruesHandler(Thing thing, TimeZoneProvider timeZoneProvider, Gson gson) {
+    public VigiCruesHandler(Thing thing, LocationProvider locationProvider, ApiHandler apiHandler) {
         super(thing);
-        this.timeZoneProvider = timeZoneProvider;
-        this.gson = gson;
+        this.apiHandler = apiHandler;
+        this.locationProvider = locationProvider;
     }
 
     @Override
     public void initialize() {
         logger.debug("Initializing VigiCrues handler.");
 
-        VigiCruesConfiguration config = getConfigAs(VigiCruesConfiguration.class);
-        logger.debug("config station = {}", config.id);
+        StationConfiguration config = getConfigAs(StationConfiguration.class);
         logger.debug("config refresh = {} min", config.refresh);
 
         updateStatus(ThingStatus.UNKNOWN);
-        queryUrl = URL + config.id;
+
+        if (thing.getProperties().isEmpty()) {
+            Map<String, String> properties = discoverAttributes(config);
+            updateProperties(properties);
+        }
+        getReferences();
         refreshJob = scheduler.scheduleWithFixedDelay(this::updateAndPublish, 0, config.refresh, TimeUnit.MINUTES);
     }
 
+    private void getReferences() {
+        List<QuantityType<?>> heights = new ArrayList<>();
+        List<QuantityType<?>> flows = new ArrayList<>();
+        thing.getProperties().keySet().stream().filter(key -> key.startsWith(FLOOD)).forEach(key -> {
+            String value = thing.getProperties().get(key);
+            if (key.contains(FLOW)) {
+                flows.add(new QuantityType<>(value));
+            } else {
+                heights.add(new QuantityType<>(value));
+            }
+        });
+        referenceHeights = heights.stream().distinct().sorted().collect(Collectors.toList());
+        referenceFlows = flows.stream().distinct().sorted().collect(Collectors.toList());
+        portion = thing.getProperties().get(TRONCON);
+    }
+
+    private Map<String, String> discoverAttributes(StationConfiguration config) {
+        Map<String, String> properties = new HashMap<>();
+
+        ThingBuilder thingBuilder = editThing();
+        List<Channel> channels = new ArrayList<>(getThing().getChannels());
+
+        try {
+            HubEauResponse stationDetails = apiHandler.discoverStations(config.id);
+            stationDetails.stations.stream().findFirst().ifPresent(station -> {
+                PointType stationLocation = new PointType(
+                        String.format(Locale.US, "%f,%f", station.latitudeStation, station.longitudeStation));
+                properties.put(LOCATION, stationLocation.toString());
+                PointType serverLocation = locationProvider.getLocation();
+                if (serverLocation != null) {
+                    DecimalType distance = serverLocation.distanceFrom(stationLocation);
+                    properties.put(DISTANCE, new QuantityType<>(distance, SIUnits.METRE).toString());
+                }
+                properties.put(RIVER, station.libelleCoursEau);
+            });
+        } catch (VigiCruesException e) {
+            logger.info("Unable to retrieve station location details {} : {}", config.id, e.getMessage());
+        }
+
+        try {
+            CdStationHydro refineStation = apiHandler.getStationDetails(config.id);
+            if (refineStation.vigilanceCrues.cruesHistoriques == null) {
+                throw new VigiCruesException("No historical data available");
+            }
+            refineStation.vigilanceCrues.cruesHistoriques.stream()
+                    .forEach(crue -> properties.putAll(crue.getDescription()));
+            String codeTerritoire = refineStation.vigilanceCrues.pereBoitEntVigiCru.cdEntVigiCru;
+            TerEntVigiCru territoire = apiHandler.getTerritoire(codeTerritoire);
+            for (VicANMoinsUn troncon : territoire.vicTerEntVigiCru.vicANMoinsUn) {
+                TronEntVigiCru detail = apiHandler.getTroncon(troncon.vicCdEntVigiCru);
+                if (detail.getStations().anyMatch(s -> config.id.equalsIgnoreCase(s.vicCdEntVigiCru))) {
+                    properties.put(TRONCON, troncon.vicCdEntVigiCru);
+                    break;
+                }
+            }
+        } catch (VigiCruesException e) {
+            logger.info("Historical flooding data are not available {} : {}", config.id, e.getMessage());
+            channels.removeIf(channel -> (channel.getUID().getId().contains(RELATIVE_PREFIX)));
+        }
+
+        if (!properties.containsKey(TRONCON)) {
+            channels.removeIf(channel -> (channel.getUID().getId().contains(ALERT)));
+            channels.removeIf(channel -> (channel.getUID().getId().contains(COMMENT)));
+        }
+
+        try {
+            OpenDatasoftResponse measures = apiHandler.getMeasures(config.id);
+            measures.getFirstRecord().ifPresent(field -> {
+                if (field.getHeight().isEmpty()) {
+                    channels.removeIf(channel -> (channel.getUID().getId().contains(HEIGHT)));
+                }
+                if (field.getFlow().isEmpty()) {
+                    channels.removeIf(channel -> (channel.getUID().getId().contains(FLOW)));
+                }
+            });
+        } catch (VigiCruesException e) {
+            logger.warn("Unable to read measurements data {} : {}", config.id, e.getMessage());
+        }
+
+        thingBuilder.withChannels(channels);
+        updateThing(thingBuilder.build());
+
+        return properties;
+    }
+
     @Override
     public void dispose() {
         logger.debug("Disposing the VigiCrues handler.");
@@ -102,26 +207,43 @@ public class VigiCruesHandler extends BaseThingHandler {
     }
 
     private void updateAndPublish() {
+        StationConfiguration config = getConfigAs(StationConfiguration.class);
         try {
-            if (queryUrl != null) {
-                String response = HttpUtil.executeUrl("GET", queryUrl, TIMEOUT_MS);
-                updateStatus(ThingStatus.ONLINE);
-                OpenDatasoftResponse apiResponse = gson.fromJson(response, OpenDatasoftResponse.class);
-                Arrays.stream(apiResponse.getRecords()).findFirst().flatMap(Record::getFields).ifPresent(field -> {
-                    field.getHeight().ifPresent(height -> updateQuantity(HEIGHT, height, METRE));
-                    field.getFlow().ifPresent(flow -> updateQuantity(FLOW, flow, CUBICMETRE_PER_SECOND));
-                    field.getTimestamp().ifPresent(date -> updateDate(OBSERVATION_TIME, date));
+            OpenDatasoftResponse measures = apiHandler.getMeasures(config.id);
+            measures.getFirstRecord().ifPresent(field -> {
+                field.getHeight().ifPresent(height -> {
+                    updateQuantity(HEIGHT, height, SIUnits.METRE);
+                    updateRelativeMeasure(RELATIVE_HEIGHT, referenceHeights, height);
                 });
-            } else {
-                updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.DISABLED,
-                        "queryUrl should never be null, but it is !");
+                field.getFlow().ifPresent(flow -> {
+                    updateQuantity(FLOW, flow, SmartHomeUnits.CUBICMETRE_PER_SECOND);
+                    updateRelativeMeasure(RELATIVE_FLOW, referenceFlows, flow);
+                });
+                field.getTimestamp().ifPresent(date -> updateDate(OBSERVATION_TIME, date));
+            });
+            String currentPortion = this.portion;
+            if (currentPortion != null) {
+                InfoVigiCru status = apiHandler.getTronconStatus(currentPortion);
+                updateAlert(ALERT, status.vicInfoVigiCru.vicNivInfoVigiCru - 1);
+                updateString(SHORT_COMMENT, status.vicInfoVigiCru.vicSituActuInfoVigiCru);
+                updateString(COMMENT, status.vicInfoVigiCru.vicQualifInfoVigiCru);
             }
-        } catch (MalformedURLException e) {
-            updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
-                    String.format("Querying '%s' raised : %s", queryUrl, e.getMessage()));
-        } catch (IOException e) {
-            updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
-                    String.format("Error opening connection to VigiCrues webservice : {}", e.getMessage()));
+            updateStatus(ThingStatus.ONLINE);
+        } catch (VigiCruesException e) {
+            updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, e.getMessage());
+        }
+    }
+
+    private void updateString(String channelId, String value) {
+        if (isLinked(channelId)) {
+            updateState(channelId, new StringType(value));
+        }
+    }
+
+    private void updateRelativeMeasure(String channelId, List<QuantityType<?>> reference, double value) {
+        if (reference.size() > 0) {
+            double percent = value / reference.get(0).doubleValue() * 100;
+            updateQuantity(channelId, percent, SmartHomeUnits.PERCENT);
         }
     }
 
@@ -133,8 +255,27 @@ public class VigiCruesHandler extends BaseThingHandler {
 
     public void updateDate(String channelId, ZonedDateTime zonedDateTime) {
         if (isLinked(channelId)) {
-            ZonedDateTime localDateTime = zonedDateTime.withZoneSameInstant(timeZoneProvider.getTimeZone());
-            updateState(channelId, new DateTimeType(localDateTime));
+            updateState(channelId, new DateTimeType(zonedDateTime));
+        }
+    }
+
+    public void updateAlert(String channelId, int value) {
+        String channelIcon = channelId + "-icon";
+        if (isLinked(channelId)) {
+            updateState(channelId, new DecimalType(value));
+        }
+        if (isLinked(channelIcon)) {
+            byte[] resource = getResource(String.format("picto/crue-%d.svg", value));
+            updateState(channelIcon, resource != null ? new RawType(resource, "image/svg+xml") : UnDefType.UNDEF);
+        }
+    }
+
+    public byte @Nullable [] getResource(String iconPath) {
+        try (InputStream stream = VigiCruesHandler.class.getClassLoader().getResourceAsStream(iconPath)) {
+            return stream.readAllBytes();
+        } catch (IOException e) {
+            logger.warn("Unable to load ressource '{}' : {}", iconPath, e.getMessage());
         }
+        return null;
     }
 }
diff --git a/bundles/org.openhab.binding.vigicrues/src/main/java/org/openhab/binding/vigicrues/internal/json/OpenDatasoftResponse.java b/bundles/org.openhab.binding.vigicrues/src/main/java/org/openhab/binding/vigicrues/internal/json/OpenDatasoftResponse.java
deleted file mode 100644 (file)
index 0c59ed8..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/**
- * Copyright (c) 2010-2020 Contributors to the openHAB project
- *
- * See the NOTICE file(s) distributed with this work for additional
- * information.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0
- *
- * SPDX-License-Identifier: EPL-2.0
- */
-package org.openhab.binding.vigicrues.internal.json;
-
-import java.util.Optional;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
-
-import com.google.gson.annotations.SerializedName;
-
-/**
- * The {@link OpenDatasoftResponse} is the Java class used to map the JSON
- * response to an opendatasoft endpoint request.
- *
- * @author Gaël L'hopital - Initial contribution
- */
-@NonNullByDefault
-public class OpenDatasoftResponse {
-    @SerializedName("nhits")
-    private int nHits;
-    private @Nullable Parameters parameters;
-    private Record[] records = {};
-
-    public int getNHits() {
-        return nHits;
-    }
-
-    public Optional<Parameters> getParameters() {
-        Parameters parameters = this.parameters;
-        if (parameters != null) {
-            return Optional.of(parameters);
-        }
-        return Optional.empty();
-    }
-
-    public Record[] getRecords() {
-        return records;
-    }
-}
diff --git a/bundles/org.openhab.binding.vigicrues/src/main/java/org/openhab/binding/vigicrues/internal/json/Parameters.java b/bundles/org.openhab.binding.vigicrues/src/main/java/org/openhab/binding/vigicrues/internal/json/Parameters.java
deleted file mode 100644 (file)
index 6ffc2bd..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-/**
- * Copyright (c) 2010-2020 Contributors to the openHAB project
- *
- * See the NOTICE file(s) distributed with this work for additional
- * information.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0
- *
- * SPDX-License-Identifier: EPL-2.0
- */
-package org.openhab.binding.vigicrues.internal.json;
-
-import java.time.ZoneId;
-import java.util.Arrays;
-import java.util.Optional;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
-
-/**
- * The {@link Parameters} is the Java class used to map the JSON
- * response to the webservice request.
- *
- * @author Gaël L'hopital - Initial contribution
- */
-@NonNullByDefault
-public class Parameters {
-    private String[] dataset = {};
-    private String timezone = "";
-    private int rows;
-    private String format = "";
-    private @Nullable Refine refine;
-    private String[] facet = {};
-
-    public Optional<String> getDataset() {
-        return Arrays.stream(dataset).findFirst();
-    }
-
-    public ZoneId getTimezone() {
-        return ZoneId.of(timezone);
-    }
-
-    public int getRows() {
-        return rows;
-    }
-
-    public String getFormat() {
-        return format;
-    }
-
-    public Optional<Refine> getRefine() {
-        Refine refine = this.refine;
-        if (refine != null) {
-            return Optional.of(refine);
-        }
-        return Optional.empty();
-    }
-
-    public String[] getFacets() {
-        return facet;
-    }
-}
diff --git a/bundles/org.openhab.binding.vigicrues/src/main/java/org/openhab/binding/vigicrues/internal/json/Record.java b/bundles/org.openhab.binding.vigicrues/src/main/java/org/openhab/binding/vigicrues/internal/json/Record.java
deleted file mode 100644 (file)
index a7a2f8d..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-/**
- * Copyright (c) 2010-2020 Contributors to the openHAB project
- *
- * See the NOTICE file(s) distributed with this work for additional
- * information.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0
- *
- * SPDX-License-Identifier: EPL-2.0
- */
-package org.openhab.binding.vigicrues.internal.json;
-
-import java.util.Optional;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
-
-import com.google.gson.annotations.SerializedName;
-
-/**
- * The {@link Record} is the Java class used to map the JSON
- * response to the webservice request.
- *
- * @author Gaël L'hopital - Initial contribution
- */
-@NonNullByDefault
-public class Record {
-    @SerializedName("datasetid")
-    private String datasetId = "";
-    @SerializedName("recordid")
-    private String recordId = "";
-    @SerializedName("record_timestamp")
-    private String recordTimestamp = "";
-    private @Nullable VigiCruesFields fields;
-
-    public String getDatasetId() {
-        return datasetId;
-    }
-
-    public String getRecordId() {
-        return recordId;
-    }
-
-    public String getRecordTimestamp() {
-        return recordTimestamp;
-    }
-
-    public Optional<VigiCruesFields> getFields() {
-        VigiCruesFields fields = this.fields;
-        if (fields != null) {
-            return Optional.of(fields);
-        }
-        return Optional.empty();
-    }
-}
diff --git a/bundles/org.openhab.binding.vigicrues/src/main/java/org/openhab/binding/vigicrues/internal/json/Refine.java b/bundles/org.openhab.binding.vigicrues/src/main/java/org/openhab/binding/vigicrues/internal/json/Refine.java
deleted file mode 100644 (file)
index e98c8d9..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-/**
- * Copyright (c) 2010-2020 Contributors to the openHAB project
- *
- * See the NOTICE file(s) distributed with this work for additional
- * information.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0
- *
- * SPDX-License-Identifier: EPL-2.0
- */
-package org.openhab.binding.vigicrues.internal.json;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-
-import com.google.gson.annotations.SerializedName;
-
-/**
- * The {@link Refine} is the Java class used to map the JSON
- * response to the webservice request.
- *
- * @author Gaël L'hopital - Initial contribution
- */
-@NonNullByDefault
-public class Refine {
-    @SerializedName("nom_dept")
-    private String departmentName = "";
-
-    public String getDepartmentName() {
-        return departmentName;
-    }
-}
diff --git a/bundles/org.openhab.binding.vigicrues/src/main/java/org/openhab/binding/vigicrues/internal/json/VigiCruesFields.java b/bundles/org.openhab.binding.vigicrues/src/main/java/org/openhab/binding/vigicrues/internal/json/VigiCruesFields.java
deleted file mode 100644 (file)
index ec378db..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-/**
- * Copyright (c) 2010-2020 Contributors to the openHAB project
- *
- * See the NOTICE file(s) distributed with this work for additional
- * information.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0
- *
- * SPDX-License-Identifier: EPL-2.0
- */
-package org.openhab.binding.vigicrues.internal.json;
-
-import java.time.ZonedDateTime;
-import java.util.Optional;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
-
-import com.google.gson.annotations.SerializedName;
-
-/**
- * The {@link VigiCruesFields} is the Java class used to map the JSON
- * response to the webservice request.
- *
- * @author Gaël L'hopital - Initial contribution
- */
-@NonNullByDefault
-public class VigiCruesFields {
-    @SerializedName("debit")
-    private @Nullable Double flow;
-    @SerializedName("hauteur")
-    private @Nullable Double height;
-    private @Nullable ZonedDateTime timestamp;
-
-    public Optional<ZonedDateTime> getTimestamp() {
-        ZonedDateTime timestamp = this.timestamp;
-        if (timestamp != null) {
-            return Optional.of(timestamp);
-        }
-        return Optional.empty();
-    }
-
-    public Optional<Double> getFlow() {
-        Double flow = this.flow;
-        if (flow != null) {
-            return Optional.of(flow);
-        }
-        return Optional.empty();
-    }
-
-    public Optional<Double> getHeight() {
-        Double height = this.height;
-        if (height != null) {
-            return Optional.of(height);
-        }
-        return Optional.empty();
-    }
-}
index 2e7a1335142f6109db7fb82f2f00f2f577461728..11c496cab79e5215e6891f903628bb99cb332c7d 100644 (file)
 
                <channels>
                        <channel id="height" typeId="height"/>
+                       <channel id="relative-height" typeId="gauge">
+                               <label>Relative Height</label>
+                               <description>Current height toward historical floods.</description>
+                       </channel>
                        <channel id="flow" typeId="flow"/>
+                       <channel id="relative-flow" typeId="gauge">
+                               <label>Relative Flow</label>
+                               <description>Current flow toward historic floods.</description>
+                       </channel>
+                       <channel id="alert" typeId="alert-level"/>
+                       <channel id="alert-icon" typeId="alert-icon"/>
+                       <channel id="short-comment" typeId="comment">
+                               <label>Info Qualification</label>
+                       </channel>
+                       <channel id="comment" typeId="comment">
+                               <label>Situation</label>
+                       </channel>
                        <channel id="observation-time" typeId="observation-time"/>
                </channels>
 
+               <representation-property>id</representation-property>
+
                <config-description>
                        <parameter name="id" type="text" required="true">
                                <label>Identifiant</label>
@@ -32,6 +50,7 @@
        <channel-type id="flow">
                <item-type>Number:VolumetricFlowRate</item-type>
                <label>Current Flow</label>
+               <category>flow</category>
                <state readOnly="true" pattern="%.2f %unit%"/>
        </channel-type>
 
@@ -39,6 +58,7 @@
                <item-type>DateTime</item-type>
                <label>Observation Time</label>
                <description>Observation date and time</description>
+               <category>time</category>
                <state readOnly="true"/>
        </channel-type>
 
                <description>Water level in the river</description>
                <state readOnly="true" pattern="%.2f %unit%"/>
        </channel-type>
+
+       <channel-type id="gauge">
+               <item-type>Number:Dimensionless</item-type>
+               <label>Relative Measure</label>
+               <state readOnly="true" pattern="%.2f %unit%"/>
+       </channel-type>
+
+       <channel-type id="alert-level">
+               <item-type>Number</item-type>
+               <label>Alerte</label>
+               <state readOnly="true">
+                       <options>
+                               <option value="0">Vert</option>
+                               <option value="1">Jaune</option>
+                               <option value="2">Orange</option>
+                               <option value="3">Rouge</option>
+                       </options>
+               </state>
+       </channel-type>
+
+       <channel-type id="comment">
+               <item-type>String</item-type>
+               <label>Commentaire</label>
+               <state readOnly="true" pattern="%s"/>
+       </channel-type>
+
+       <channel-type id="alert-icon">
+               <item-type>Image</item-type>
+               <label>Pictogramme</label>
+               <description>Pictogramme associé au niveau d'alerte.</description>
+               <state readOnly="true"/>
+       </channel-type>
 </thing:thing-descriptions>
diff --git a/bundles/org.openhab.binding.vigicrues/src/main/resources/picto/crue-0.svg b/bundles/org.openhab.binding.vigicrues/src/main/resources/picto/crue-0.svg
new file mode 100644 (file)
index 0000000..f0a6fa2
--- /dev/null
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 78.271 84.645"><g id="indice-vert"><path d="M47.594 24.86c0 .233-.197.944-.59 2.123a480.704 480.704 0 0 1-2.656 7.733c-.432 1.22-.689 2.027-.77 2.421a89.557 89.557 0 0 1-1.414 4.134 133.507 133.507 0 0 0-1.533 4.367 82.549 82.549 0 0 1-1.42 4.311 678.77 678.77 0 0 0-1.533 4.307c-.316.869-.65 1.828-1.004 2.891a54.563 54.563 0 0 1-1.004 2.775 481.208 481.208 0 0 1-2.125 5.963 97.792 97.792 0 0 0-2.006 6.08c-.475 1.42-.943 2.5-1.418 3.246-.473.75-1.004 1.277-1.594 1.596-.592.313-1.281.49-2.064.531-.791.039-1.656.057-2.602.057-1.258 0-2.301-.039-3.125-.117-.828-.08-1.535-.371-2.127-.885-.59-.512-1.141-1.279-1.654-2.303-.51-1.021-1.043-2.479-1.596-4.369a710.439 710.439 0 0 0-7.375-21.898A1676.56 1676.56 0 0 1 .369 25.92a1.32 1.32 0 0 1-.119-.589v-.471c0-.787.193-1.379.592-1.773a2.828 2.828 0 0 1 1.416-.77 8.273 8.273 0 0 1 1.713-.175H7.69a4.96 4.96 0 0 1 2.008.415c.627.274 1.197.747 1.709 1.415.514.668.924 1.636 1.24 2.892.158.554.414 1.379.768 2.479.356 1.105.648 2.087.885 2.952a114.139 114.139 0 0 1 1.773 5.611 410.58 410.58 0 0 0 1.887 6.312c.315.871.631 1.873.947 3.014.31 1.141.666 2.264 1.06 3.365.078.234.217.725.412 1.477.197.746.473 1.514.826 2.301.356.785.75 1.494 1.182 2.121.432.633.967.947 1.596.947.551 0 1.059-.314 1.533-.947.473-.627.885-1.314 1.24-2.064.353-.744.629-1.455.826-2.123.195-.666.297-1.041.297-1.123.234-.863.51-1.828.824-2.891.313-1.063.592-2.025.826-2.893a71.07 71.07 0 0 0 .828-2.361c.313-.946.59-1.85.824-2.716.633-1.811 1.262-3.7 1.893-5.666a170.943 170.943 0 0 0 1.889-6.378c.391-1.493.783-2.654 1.178-3.483.395-.825.865-1.433 1.416-1.829.553-.393 1.223-.628 2.008-.706a29.256 29.256 0 0 1 2.832-.119h1.479c.59 0 1.16.077 1.711.235a3.584 3.584 0 0 1 1.418.768c.391.355.589.926.589 1.713z" fill="#28d761" stroke="#504d49" stroke-width=".5"/><path d="M78.271 77.531c0 3.926-9.189 7.113-20.523 7.113-11.336 0-20.523-3.188-20.523-7.113 0-3.928 9.187-7.109 20.523-7.109 11.334 0 20.523 3.182 20.523 7.109z" fill="#7c9fbb"/><ellipse cx="62.657" cy="78.139" rx="9.595" ry="2.639" fill="#63839b"/><path d="M62.656 16.214c0 .048-.053.154-.15.313a.903.903 0 0 1-.459.354c-.545.246-1.17.382-1.885.407-.715.025-1.445.036-2.189.036-.547 0-1.121-.007-1.732-.018a8.751 8.751 0 0 1-1.732-.203 1.903 1.903 0 0 1-.865-.425c-.238-.212-.355-.366-.355-.464V1.072c0-.05.049-.148.152-.293.102-.15.254-.276.457-.372.543-.248 1.189-.375 1.934-.388C56.578.004 57.293 0 57.973 0c.473 0 1.033.004 1.68.019.645.013 1.273.079 1.883.203.342.072.613.208.816.407.207.198.305.345.305.443v15.142zM62.656 36.682c0 .051-.053.157-.15.316a.89.89 0 0 1-.459.35c-.545.249-1.17.385-1.885.41-.715.022-1.445.035-2.189.035-.547 0-1.121-.005-1.732-.017a8.679 8.679 0 0 1-1.732-.202 1.869 1.869 0 0 1-.865-.428c-.238-.21-.355-.364-.355-.464v-15.14c0-.049.049-.147.152-.295a1.16 1.16 0 0 1 .457-.371c.543-.246 1.189-.375 1.934-.389a102.378 102.378 0 0 1 3.823 0c.645.014 1.273.08 1.883.205.342.073.613.209.816.407.207.195.305.346.305.443v15.14zM62.656 57.152c0 .047-.053.154-.15.314a.905.905 0 0 1-.459.352c-.545.246-1.17.383-1.885.408a74.944 74.944 0 0 1-3.921.017 8.603 8.603 0 0 1-1.732-.205 1.89 1.89 0 0 1-.865-.422c-.238-.213-.355-.367-.355-.465V42.013c0-.05.049-.15.152-.296.102-.15.254-.273.457-.373.543-.247 1.189-.376 1.934-.39.748-.012 1.463-.018 2.143-.018.473 0 1.033.006 1.68.018.645.014 1.273.082 1.883.205.342.072.613.208.816.407.207.198.305.345.305.446v15.14z" fill="#504d49"/><path d="M62.656 77.389c0 .051-.053.156-.15.314a.897.897 0 0 1-.459.357c-.545.244-1.17.379-1.885.404a67.95 67.95 0 0 1-3.921.019 8.751 8.751 0 0 1-1.732-.203 1.878 1.878 0 0 1-.865-.428c-.238-.211-.355-.363-.355-.465V62.252c0-.049.049-.148.152-.297.102-.15.254-.273.457-.371.543-.246 1.189-.375 1.934-.389.748-.012 1.463-.018 2.143-.018.473 0 1.033.006 1.68.018.645.014 1.273.08 1.883.205.342.072.613.209.816.404.207.199.305.348.305.447v15.138z" fill="#28d761" stroke="#504d49" stroke-width=".5"/></g></svg>
\ No newline at end of file
diff --git a/bundles/org.openhab.binding.vigicrues/src/main/resources/picto/crue-1.svg b/bundles/org.openhab.binding.vigicrues/src/main/resources/picto/crue-1.svg
new file mode 100644 (file)
index 0000000..7e3565f
--- /dev/null
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 78.271 84.645"><g id="indice-jaune"><path d="M47.594 24.86c0 .233-.197.944-.59 2.123a480.704 480.704 0 0 1-2.656 7.733c-.432 1.22-.689 2.027-.77 2.421a89.557 89.557 0 0 1-1.414 4.134 133.507 133.507 0 0 0-1.533 4.367 81.616 81.616 0 0 1-1.42 4.311 831.628 831.628 0 0 0-1.533 4.307c-.316.869-.649 1.828-1.004 2.891s-.692 1.992-1.004 2.775a481.208 481.208 0 0 1-2.125 5.963 98.462 98.462 0 0 0-2.006 6.08c-.475 1.42-.943 2.5-1.418 3.246-.473.75-1.004 1.277-1.594 1.596-.592.313-1.281.49-2.064.531-.791.039-1.656.057-2.602.057-1.258 0-2.301-.039-3.125-.117-.828-.08-1.535-.371-2.127-.885-.59-.512-1.141-1.279-1.653-2.303-.511-1.021-1.044-2.479-1.596-4.369a707.767 707.767 0 0 0-7.376-21.898A1691.504 1691.504 0 0 1 .369 25.92a1.32 1.32 0 0 1-.119-.589v-.471c0-.787.194-1.379.592-1.773a2.828 2.828 0 0 1 1.416-.77 8.273 8.273 0 0 1 1.713-.175H7.69a4.96 4.96 0 0 1 2.008.415c.627.274 1.197.747 1.71 1.415.513.668.923 1.636 1.239 2.892.158.554.414 1.379.769 2.479a72.92 72.92 0 0 1 .884 2.952 114.043 114.043 0 0 1 1.774 5.611c.63 2.164 1.258 4.271 1.888 6.312.313.871.63 1.873.946 3.014a45.059 45.059 0 0 0 1.062 3.365c.077.234.216.725.412 1.477.196.746.472 1.514.826 2.301.354.785.75 1.494 1.182 2.121.431.633.966.947 1.596.947.551 0 1.059-.314 1.533-.947.472-.627.884-1.314 1.239-2.064.354-.744.629-1.455.826-2.123.196-.666.297-1.041.297-1.123.234-.863.51-1.828.824-2.891.313-1.063.592-2.025.826-2.893.237-.629.513-1.416.829-2.361.311-.946.589-1.85.824-2.716a242.12 242.12 0 0 0 1.893-5.666 172.94 172.94 0 0 0 1.888-6.378c.391-1.493.783-2.654 1.179-3.483.394-.825.865-1.433 1.416-1.829.552-.393 1.222-.628 2.008-.706a29.22 29.22 0 0 1 2.831-.119h1.479c.59 0 1.16.077 1.711.235a3.577 3.577 0 0 1 1.418.768c.389.355.587.926.587 1.713z" fill="#ff0" stroke="#504d49" stroke-width=".5"/><path d="M78.271 77.531c0 3.926-9.189 7.113-20.523 7.113-11.336 0-20.523-3.188-20.523-7.113 0-3.928 9.188-7.109 20.523-7.109 11.334 0 20.523 3.182 20.523 7.109z" fill="#7c9fbb"/><ellipse cx="62.657" cy="78.139" rx="9.595" ry="2.639" fill="#63839b"/><path d="M62.656 16.214c0 .048-.053.154-.15.313a.903.903 0 0 1-.459.354c-.545.246-1.17.382-1.885.407-.715.025-1.445.036-2.19.036-.547 0-1.121-.007-1.732-.018a8.751 8.751 0 0 1-1.732-.203 1.903 1.903 0 0 1-.865-.425c-.238-.212-.355-.366-.355-.464V1.072c0-.05.049-.148.152-.293.102-.15.254-.276.457-.372.543-.248 1.189-.375 1.934-.388C56.578.004 57.293 0 57.973 0c.473 0 1.033.004 1.68.019.645.013 1.273.079 1.883.203.342.072.613.208.816.407.207.198.305.345.305.443v15.142zM62.656 36.682c0 .051-.053.157-.15.316a.89.89 0 0 1-.459.35c-.545.249-1.17.385-1.885.41-.715.022-1.445.035-2.19.035-.547 0-1.121-.005-1.732-.017a8.679 8.679 0 0 1-1.732-.202 1.869 1.869 0 0 1-.865-.428c-.238-.21-.355-.364-.355-.464v-15.14c0-.049.049-.147.152-.295a1.16 1.16 0 0 1 .457-.371c.543-.246 1.189-.375 1.934-.389a102.378 102.378 0 0 1 3.822 0c.645.014 1.273.08 1.883.205.342.073.613.209.816.407.207.195.305.346.305.443v15.14z" fill="#504d49"/><path d="M62.656 57.152c0 .047-.053.154-.15.314a.905.905 0 0 1-.459.352c-.545.246-1.17.383-1.885.408a74.944 74.944 0 0 1-3.922.017 8.603 8.603 0 0 1-1.732-.205 1.89 1.89 0 0 1-.865-.422c-.238-.213-.355-.367-.355-.465V42.013c0-.05.049-.15.152-.296.102-.15.254-.273.457-.373.543-.247 1.189-.376 1.934-.39.748-.012 1.463-.018 2.142-.018.473 0 1.033.006 1.68.018.645.014 1.273.082 1.883.205.342.072.613.208.816.407.207.198.305.345.305.446v15.14z" fill="#ff0" stroke="#504d49" stroke-width=".5"/><path d="M62.656 77.389c0 .051-.053.156-.15.314a.897.897 0 0 1-.459.357c-.545.244-1.17.379-1.885.404a67.96 67.96 0 0 1-3.922.019 8.751 8.751 0 0 1-1.732-.203 1.878 1.878 0 0 1-.865-.428c-.238-.211-.355-.363-.355-.465V62.252c0-.049.049-.148.152-.297.102-.15.254-.273.457-.371.543-.246 1.189-.375 1.934-.389.748-.012 1.463-.018 2.142-.018.473 0 1.033.006 1.68.018.645.014 1.273.08 1.883.205.342.072.613.209.816.404.207.199.305.348.305.447v15.138z" fill="#504d49"/></g></svg>
\ No newline at end of file
diff --git a/bundles/org.openhab.binding.vigicrues/src/main/resources/picto/crue-2.svg b/bundles/org.openhab.binding.vigicrues/src/main/resources/picto/crue-2.svg
new file mode 100644 (file)
index 0000000..3a000b2
--- /dev/null
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 78.272 84.645"><g id="indice-orange"><path d="M47.594 24.86c0 .233-.197.944-.59 2.123a480.704 480.704 0 0 1-2.656 7.733c-.432 1.22-.69 2.027-.77 2.421a88.378 88.378 0 0 1-1.414 4.134 133.507 133.507 0 0 0-1.533 4.367 82.222 82.222 0 0 1-1.42 4.31 747.465 747.465 0 0 0-1.533 4.307c-.317.869-.65 1.828-1.004 2.891a51.805 51.805 0 0 1-1.004 2.775 465.383 465.383 0 0 1-2.125 5.963 97.53 97.53 0 0 0-2.005 6.08c-.475 1.42-.944 2.5-1.418 3.246-.472.75-1.003 1.277-1.593 1.596-.592.313-1.281.49-2.065.531-.791.039-1.656.057-2.602.057-1.258 0-2.3-.039-3.124-.117-.829-.08-1.536-.371-2.127-.885-.589-.512-1.141-1.279-1.653-2.303-.51-1.021-1.045-2.479-1.596-4.369a706.87 706.87 0 0 0-7.376-21.898A1642.262 1642.262 0 0 1 .37 25.92a1.306 1.306 0 0 1-.12-.589v-.471c0-.787.194-1.379.592-1.773a2.828 2.828 0 0 1 1.416-.77 8.266 8.266 0 0 1 1.713-.175h3.718c.707 0 1.377.139 2.008.414.627.274 1.198.747 1.71 1.415.513.668.923 1.636 1.239 2.892.158.554.415 1.379.769 2.479.354 1.104.647 2.087.884 2.952a113.068 113.068 0 0 1 1.773 5.611 413.78 413.78 0 0 0 1.888 6.312c.314.871.63 1.873.946 3.014a45.059 45.059 0 0 0 1.062 3.365c.077.234.216.725.412 1.476.196.746.472 1.514.826 2.301.355.785.75 1.494 1.182 2.121.431.633.965.947 1.596.947.551 0 1.059-.314 1.533-.947.472-.627.884-1.314 1.239-2.064.354-.744.63-1.455.826-2.123.197-.666.297-1.041.297-1.123.235-.863.51-1.828.824-2.891.314-1.063.592-2.025.827-2.893.237-.629.513-1.416.829-2.361.312-.946.589-1.85.824-2.716.632-1.811 1.26-3.7 1.893-5.666a172.94 172.94 0 0 0 1.888-6.378c.39-1.493.783-2.654 1.178-3.483.393-.825.865-1.433 1.416-1.829.551-.393 1.222-.628 2.008-.707a29.256 29.256 0 0 1 2.832-.119h1.479c.59 0 1.16.077 1.711.235a3.574 3.574 0 0 1 1.418.769c.391.357.588.928.588 1.715z" fill="#fa0" stroke="#504d49" stroke-width=".5"/><path d="M78.272 77.531c0 3.926-9.189 7.113-20.523 7.113-11.336 0-20.524-3.188-20.524-7.113 0-3.928 9.188-7.109 20.524-7.109 11.333 0 20.523 3.182 20.523 7.109z" fill="#7c9fbb"/><ellipse cx="62.658" cy="78.139" rx="9.595" ry="2.639" fill="#63839b"/><path d="M62.657 16.214c0 .048-.053.154-.15.313a.903.903 0 0 1-.459.354c-.545.246-1.17.382-1.885.407-.715.025-1.445.036-2.189.036a96.9 96.9 0 0 1-1.733-.018 8.76 8.76 0 0 1-1.732-.203 1.903 1.903 0 0 1-.865-.425c-.238-.212-.355-.366-.355-.464V1.072c0-.05.049-.148.152-.293.102-.15.254-.276.457-.372.543-.248 1.189-.375 1.934-.388C56.579.004 57.293 0 57.973 0c.473 0 1.033.004 1.68.019.645.013 1.274.079 1.883.203.342.072.613.208.816.407.207.198.305.345.305.443v15.142z" fill="#504d49"/><path d="M62.657 36.682c0 .051-.053.157-.15.316a.89.89 0 0 1-.459.35c-.545.249-1.17.385-1.885.41-.715.023-1.445.035-2.189.035-.547 0-1.121-.005-1.733-.017a8.687 8.687 0 0 1-1.732-.202 1.869 1.869 0 0 1-.865-.428c-.238-.21-.355-.364-.355-.464v-15.14c0-.049.049-.147.152-.295a1.15 1.15 0 0 1 .457-.371c.543-.246 1.189-.375 1.934-.389a102.378 102.378 0 0 1 3.823 0c.645.014 1.274.08 1.883.205.342.073.613.209.816.407.207.195.305.346.305.443v15.14z" fill="#fa0" stroke="#504d49" stroke-width=".5"/><path d="M62.657 57.152c0 .047-.053.154-.15.314a.905.905 0 0 1-.459.352c-.545.246-1.17.383-1.885.408a75.085 75.085 0 0 1-3.922.017 8.611 8.611 0 0 1-1.732-.205 1.89 1.89 0 0 1-.865-.422c-.238-.213-.355-.367-.355-.465V42.013c0-.05.049-.15.152-.296.102-.15.254-.273.457-.373.543-.247 1.189-.376 1.934-.39.748-.012 1.463-.018 2.143-.018.473 0 1.033.006 1.68.018.645.014 1.274.082 1.883.205.342.072.613.208.816.407.207.198.305.345.305.446v15.14zM62.657 77.389c0 .051-.053.156-.15.314a.897.897 0 0 1-.459.357c-.545.244-1.17.379-1.885.404a65.179 65.179 0 0 1-3.922.019 8.76 8.76 0 0 1-1.732-.203 1.878 1.878 0 0 1-.865-.428c-.238-.211-.355-.363-.355-.465V62.252c0-.049.049-.148.152-.297.102-.15.254-.273.457-.371.543-.246 1.189-.375 1.934-.389.748-.012 1.463-.018 2.143-.018.473 0 1.033.006 1.68.018.645.014 1.274.08 1.883.205.342.072.613.209.816.404.207.199.305.348.305.447v15.138z" fill="#504d49"/></g></svg>
\ No newline at end of file
diff --git a/bundles/org.openhab.binding.vigicrues/src/main/resources/picto/crue-3.svg b/bundles/org.openhab.binding.vigicrues/src/main/resources/picto/crue-3.svg
new file mode 100644 (file)
index 0000000..5ac6ae2
--- /dev/null
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 78.272 84.895"><g id="indice-rouge"><path d="M47.594 25.11c0 .233-.196.944-.589 2.123a576.842 576.842 0 0 1-1.299 3.838 365.141 365.141 0 0 1-1.358 3.895c-.432 1.22-.689 2.027-.77 2.421a90.678 90.678 0 0 1-1.413 4.134 131.995 131.995 0 0 0-1.533 4.367 82.954 82.954 0 0 1-1.421 4.312 747.465 747.465 0 0 0-1.533 4.307c-.316.869-.649 1.828-1.004 2.891a52.449 52.449 0 0 1-1.004 2.775 476.542 476.542 0 0 1-2.125 5.963 97.53 97.53 0 0 0-2.005 6.08c-.475 1.419-.944 2.499-1.418 3.246-.472.75-1.003 1.277-1.593 1.596-.592.313-1.281.489-2.065.53-.79.04-1.656.058-2.602.058-1.258 0-2.3-.039-3.124-.117-.829-.08-1.536-.372-2.127-.885-.589-.513-1.141-1.279-1.653-2.303-.51-1.022-1.044-2.479-1.596-4.369a706.134 706.134 0 0 0-7.377-21.9A1671.14 1671.14 0 0 1 .371 26.171a1.303 1.303 0 0 1-.12-.589v-.471c0-.787.194-1.379.592-1.773a2.828 2.828 0 0 1 1.416-.77 8.266 8.266 0 0 1 1.713-.175H7.69a4.96 4.96 0 0 1 2.008.415c.627.274 1.198.747 1.71 1.415.513.668.923 1.636 1.239 2.892.158.554.415 1.379.769 2.479.354 1.104.647 2.087.884 2.952a113.068 113.068 0 0 1 1.773 5.611 413.96 413.96 0 0 0 1.888 6.313c.314.87.63 1.873.946 3.014a44.882 44.882 0 0 0 1.061 3.364c.077.235.216.726.412 1.478.196.746.472 1.513.826 2.3.355.786.75 1.495 1.182 2.122.431.633.965.947 1.596.947.551 0 1.059-.314 1.533-.947.472-.627.884-1.314 1.239-2.064.354-.745.63-1.455.826-2.124.197-.666.297-1.041.297-1.122.235-.864.51-1.828.824-2.891.314-1.062.592-2.025.827-2.893.237-.63.513-1.416.829-2.362.312-.946.589-1.85.824-2.716.632-1.811 1.26-3.7 1.893-5.666a172.94 172.94 0 0 0 1.888-6.378c.39-1.493.783-2.654 1.178-3.483.393-.825.865-1.433 1.416-1.829.551-.393 1.222-.628 2.008-.707a29.242 29.242 0 0 1 2.832-.119h1.479c.589 0 1.159.077 1.71.235a3.59 3.59 0 0 1 1.419.769c.391.354.588.925.588 1.712z" fill="red" stroke="#504d49" stroke-width=".5"/><path d="M78.272 77.782c0 3.926-9.19 7.113-20.524 7.113-11.335 0-20.523-3.188-20.523-7.113 0-3.928 9.188-7.109 20.523-7.109 11.334-.001 20.524 3.181 20.524 7.109z" fill="#7c9fbb"/><ellipse cx="62.658" cy="78.389" rx="9.594" ry="2.639" fill="#63839b"/><path d="M62.656 16.464c0 .048-.053.154-.15.313a.896.896 0 0 1-.458.354c-.546.246-1.171.382-1.886.407-.714.025-1.444.036-2.19.036-.547 0-1.121-.007-1.732-.018a8.76 8.76 0 0 1-1.732-.203 1.9 1.9 0 0 1-.864-.425c-.239-.212-.356-.366-.356-.464V1.322c0-.05.05-.148.152-.293.102-.15.254-.276.458-.372.542-.248 1.188-.375 1.933-.388.748-.015 1.463-.019 2.143-.019.473 0 1.033.004 1.68.019.644.013 1.274.079 1.883.203.343.072.613.208.816.407.207.198.305.345.305.443v15.142z" fill="red" stroke="#504d49" stroke-width=".5"/><path d="M62.656 36.932c0 .051-.053.157-.15.316a.884.884 0 0 1-.458.35c-.546.249-1.171.385-1.886.41a71.04 71.04 0 0 1-2.19.035c-.547 0-1.121-.005-1.732-.017a8.687 8.687 0 0 1-1.732-.202 1.865 1.865 0 0 1-.864-.428c-.239-.21-.356-.364-.356-.464v-15.14c0-.049.05-.147.152-.295s.254-.271.458-.371c.542-.246 1.188-.375 1.933-.389a102.378 102.378 0 0 1 3.823 0c.644.014 1.274.08 1.883.205.343.073.613.209.816.407.207.195.305.346.305.443v15.14zM62.656 57.403c0 .047-.053.154-.15.313a.894.894 0 0 1-.458.353c-.546.246-1.171.383-1.886.408a71.04 71.04 0 0 1-3.922.017 8.611 8.611 0 0 1-1.732-.205 1.886 1.886 0 0 1-.864-.422c-.239-.213-.356-.367-.356-.465v-15.14c0-.05.05-.15.152-.296.102-.15.254-.273.458-.373.542-.247 1.188-.376 1.933-.39.748-.012 1.463-.018 2.143-.018.473 0 1.033.006 1.68.018.644.014 1.274.082 1.883.205.343.072.613.208.816.407.207.198.305.345.305.446v15.142zM62.656 77.639c0 .051-.053.156-.15.314a.9.9 0 0 1-.458.357c-.546.244-1.171.378-1.886.404a67.857 67.857 0 0 1-3.922.019 8.76 8.76 0 0 1-1.732-.203 1.884 1.884 0 0 1-.864-.428c-.239-.211-.356-.363-.356-.465V62.502c0-.05.05-.148.152-.297.102-.15.254-.273.458-.371.542-.246 1.188-.375 1.933-.389a93.232 93.232 0 0 1 3.823 0c.644.014 1.274.08 1.883.204.343.072.613.209.816.405.207.199.305.348.305.447v15.138z" fill="#504d49"/></g></svg>
\ No newline at end of file
diff --git a/bundles/org.openhab.binding.vigicrues/src/main/resources/vigicrues.cer b/bundles/org.openhab.binding.vigicrues/src/main/resources/vigicrues.cer
new file mode 100644 (file)
index 0000000..fba00f3
--- /dev/null
@@ -0,0 +1,50 @@
+-----BEGIN CERTIFICATE-----
+MIII6DCCBtCgAwIBAgIRAKyivjc1wLX1ahBKQr2wLpwwDQYJKoZIhvcNAQELBQAw
+fTELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCURISU1ZT1RJUzEcMBoGA1UECwwTMDAw
+MiA0ODE0NjMwODEwMDAzNjEdMBsGA1UEYQwUTlRSRlItNDgxNDYzMDgxMDAwMzYx
+HTAbBgNVBAMMFENlcnRpZ25hIFNlcnZpY2VzIENBMB4XDTIwMDkxMDA4NDM0NloX
+DTIxMDkxMDA4NDM0NlowgZgxCzAJBgNVBAYTAkZSMRkwFwYDVQQHDBBQQVJJUyBM
+QSBERUZFTlNFMSAwHgYDVQQKDBdTRyBNSU4gVFJBTlMgRUNPTCBTT0xJRDEcMBoG
+A1UECwwTMDAwMiAxMzAwMTk1NDAwMDAyNTEaMBgGA1UEAwwRdmlnaWNydWVzLmdv
+dXYuZnIxEjAQBgNVBAUTCVMxNzQ1ODAxNDCCASIwDQYJKoZIhvcNAQEBBQADggEP
+ADCCAQoCggEBAOxiWSS7UVERcuH6PI4Itkm3hNos8wiwmbI1mtHht4a94h9gxzQ1
+U0t/wxYkOgzdQ3VCSNgX27YOEsfJKlqREx3AaSdztPW27mXCgl3+IOF6bm0UooIn
+gcl0inpGYJCI4Mb+2xEpmeJt2eEojQgiYQZVJuf2yOoNpCdNJlS/ym3LM1AQVxBm
+/Jl24KWbhr7cjPye0773jqckwf3JSFbqVtxinctVnnS+qdwn/hQP3nNBkXXKOnJM
+71vD7S4MwIMy3oQHK8oYmTwQpliju8rOIVKu099hiQAcegh5b33gG2RagHaTd6vb
+sunW5GBWS4IfhQurQT5pjKnVT4zpF/h4b+kCAwEAAaOCBEUwggRBMAkGA1UdEwQC
+MAAwDgYDVR0PAQH/BAQDAgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMBMGUGA1UdHwRe
+MFwwK6ApoCeGJWh0dHA6Ly9jcmwuY2VydGlnbmEuZnIvc2VydmljZXNjYS5jcmww
+LaAroCmGJ2h0dHA6Ly9jcmwuZGhpbXlvdGlzLmNvbS9zZXJ2aWNlc2NhLmNybDCB
+5AYIKwYBBQUHAQEEgdcwgdQwNgYIKwYBBQUHMAKGKmh0dHA6Ly9hdXRvcml0ZS5j
+ZXJ0aWduYS5mci9zZXJ2aWNlc2NhLmRlcjA4BggrBgEFBQcwAoYsaHR0cDovL2F1
+dG9yaXRlLmRoaW15b3Rpcy5jb20vc2VydmljZXNjYS5kZXIwLgYIKwYBBQUHMAGG
+Imh0dHA6Ly9zZXJ2aWNlc2NhLm9jc3AuY2VydGlnbmEuZnIwMAYIKwYBBQUHMAGG
+JGh0dHA6Ly9zZXJ2aWNlc2NhLm9jc3AuZGhpbXlvdGlzLmNvbTAdBgNVHQ4EFgQU
+nWuFMLSW73ZLFxHfrbThfMgS5n0wHwYDVR0jBBgwFoAUrOyGj0s3HLh/FxsZ0K7o
+TuM0XBIwMwYDVR0RBCwwKoIRdmlnaWNydWVzLmdvdXYuZnKCFXd3dy52aWdpY3J1
+ZXMuZ291di5mcjBUBgNVHSAETTBLMAgGBmeBDAECAjA/BgsqgXoBgTECBQEBATAw
+MC4GCCsGAQUFBwIBFiJodHRwczovL3d3dy5jZXJ0aWduYS5mci9hdXRvcml0ZXMv
+MIIB9AYKKwYBBAHWeQIEAgSCAeQEggHgAd4AdQBElGUusO7Or8RAB9io/ijA2uaC
+vtjLMbU/0zOWtbaBqAAAAXR3L2RPAAAEAwBGMEQCIDtx/No4sejdX5EvrDXcs4MD
+nqYZQymUgF6BEsDI8QBtAiAYOV8IqtH4+C2xMlaWWQSsu0+porprbou01OF7OaPM
+QQB2AG9Tdqwx8DEZ2JkApFEV/3cVHBHZAsEAKQaNsgiaN9kTAAABdHcvZRMAAAQD
+AEcwRQIgSxFpdehqbsWZavfyc9/qfRp3mZDwxgKWtYWvKWD3jCYCIQDzBkPoaS0R
+5NwUKNy5M74Mki6NOJOX3oKpw/lRjKd5ywB1AFzcQ5L+5qtFRLFemtRW5hA3+9X6
+R9yhc5SyXub2xw7KAAABdHcvZ4MAAAQDAEYwRAIgfKfHw+kC5FHov2fo3Igs0Umu
+FSmG65zKYv6C5idM+NoCIEddMJWt2e+K6ejFxILKGSzx2pyj5f8J0N0jBwjquQt0
+AHYA9lyUL9F3MCIUVBgIMJRWjuNNExkzv98MLyALzE7xZOMAAAF0dy9oWgAABAMA
+RzBFAiEAimauUItb/FhM/KFNrF6pKpq3msq69vf8szYg6HDKq4cCIApAx7DUecse
+TeUBpfeJa6618/Yx4HWlbEDjXyToS0LEMA0GCSqGSIb3DQEBCwUAA4ICAQAXkoT/
+QGyvyNx9MlSuVE+CqRYJd2h0UsQjU1tjNWIwT/grodh3M5eYMbPv+mG1Kg8a95lG
+PazIJCxhXde77NQF5yXDEY6D7SFqs5s+Ah/oCxmkRNY+ctIrV++lyl24cVrLuMgc
+QHxtIDveFEHH7KsqrhcHkzrTG2tWcxD3j9p+mZu1t4xuOT46WfONMOBv9I0O+jVV
+2LpR5Qblf6Rvr9a0OopYCeTYT2q91A2XR7hUDxFXBVt+AB3eIOqbRUj0J+1xMjhJ
+XhqiaJpGQDf0CvSVE+ej5nafV/+eCS11u9U20B9vBl8JTKGq7lr8jhL3IPOb/EQG
+whh6/aYGT6bRh0L68FXRCclVDjFI7sTP0ZKcjGi1oCdCHP7d00xWg8z5fY4lEdkR
+6TfpkqBoYF5pnsikoDxX/U52w2+KvU84aOhSf+LkGigDUu+4+FJw4q4hdfevgdVW
+gM7vS4LzLTwnaXh+qGipuiWUUz6ublhM6iLn8ff2T82I6ggTHSvRswZfZciRrp4r
+m63QWF1dPQdvRBIeuAp772gKnUATGNKDF5XhE8NFvvIiLDFjHsiTGSx8UUzrPRdd
+0LXhFz8Dx4ciG4Y6sKnJbp4Lsu/is12n6eAzhId8YZSE0FGLSShKB27cWJ+VyIad
+qkouOhMnN18+YFQsMZM6qISdOTz+jQlU+DOMBg==
+-----END CERTIFICATE-----