]> git.basschouten.com Git - openhab-addons.git/commitdiff
[meteoalerte] Addressing Issue #8543 (#8961)
authorGaël L'hopital <gael@lhopital.org>
Mon, 9 Nov 2020 20:51:39 +0000 (21:51 +0100)
committerGitHub <noreply@github.com>
Mon, 9 Nov 2020 20:51:39 +0000 (12:51 -0800)
* [meteoalerte] Addressing Issue #8543

* Small change
* Adding charset to byte conversion

Signed-off-by: clinique <gael@lhopital.org>
bundles/org.openhab.binding.meteoalerte/README.md
bundles/org.openhab.binding.meteoalerte/src/main/java/org/openhab/binding/meteoalerte/internal/handler/MeteoAlerteHandler.java
bundles/org.openhab.binding.meteoalerte/src/main/java/org/openhab/binding/meteoalerte/internal/json/ApiResponse.java
bundles/org.openhab.binding.meteoalerte/src/main/resources/OH-INF/thing/thing-types.xml

index 29bccfe740d93292e875aff016a78477be850b76..6be47e9930cb63ea2f881db5d2f96fe229486984 100644 (file)
@@ -30,15 +30,15 @@ The Météo Alerte information that are retrieved is available as these channels
 | observation-time      | DateTime  | Date and time of report validity start        |
 | end-time              | DateTime  | Date and time of report validity end          |
 | comment               | String    | General comments on alerts for the department |
-| vent                  | String    | Wind alert level (*)                          |
-| pluie-inondation      | String    | Rain alert level (*)                          |
-| orage                 | String    | Storm alert level (*)                         |
-| inondation            | String    | Flood alert level (*)                         |
-| neige                 | String    | Snow alert level (*)                          |
-| canicule              | String    | Heat alert level (*)                          |
-| grand-froid           | String    | Cold alert level (*)                          |
-| avalanches            | String    | Avalanche alert level (*)                     |
-| vague-submersion      | String    | Wave submersion alert level (*)               |
+| vent                  | Number    | Wind alert level (*)                          |
+| pluie-inondation      | Number    | Rain alert level (*)                          |
+| orage                 | Number    | Storm alert level (*)                         |
+| inondation            | Number    | Flood alert level (*)                         |
+| neige                 | Number    | Snow alert level (*)                          |
+| canicule              | Number    | Heat alert level (*)                          |
+| grand-froid           | Number    | Cold alert level (*)                          |
+| avalanches            | Number    | Avalanche alert level (*)                     |
+| vague-submersion      | Number    | Wave submersion alert level (*)               |
 | pluie-inondation-icon | Image     | Pictogram of the Rain alert level             |
 | vent-icon             | Image     | Pictogram of the Wind alert level             |
 | orage-icon            | Image     | Pictogram of Storm alert level                |
@@ -72,14 +72,14 @@ meteoalert.items:
 ```
 Group gMeteoAlert "Alertes Météo" <weather> 
     String  MA_Dept78                    "Département 78 [%s]"   <aqi>       (gMeteoAlert)   {channel="meteoalerte:department:yvelines:comment"}
-    String  MA_etat_canicule             "Canicule [%s]"         <aqi>       (gMeteoAlert)   {channel="meteoalerte:department:yvelines:canicule"}
-    String  MA_etat_grand_froid          "Grand Froid [%s]"      <aqi>       (gMeteoAlert)   {channel="meteoalerte:department:yvelines:grand-froid"}
-    String  MA_etat_pluie_inondation     "Pluie-Inondation [%s]" <aqi>       (gMeteoAlert)   {channel="meteoalerte:department:yvelines:pluie-inondation"}
-    String  MA_etat_neige                "Neige [%s]"            <aqi>       (gMeteoAlert)   {channel="meteoalerte:department:yvelines:neige"}
-    String  MA_etat_vent                 "Vent [%s]"             <aqi>       (gMeteoAlert)   {channel="meteoalerte:department:yvelines:vent"}
-    String  MA_etat_inondation           "Inondation [%s]"       <aqi>       (gMeteoAlert)   {channel="meteoalerte:department:yvelines:inondation"}
-    String  MA_etat_orage                "Orage [%s]"            <aqi>       (gMeteoAlert)   {channel="meteoalerte:department:yvelines:orage"}
-    String  MA_etat_avalanche            "Avalanches [%s]"       <aqi>       (gMeteoAlert)   {channel="meteoalerte:department:yvelines:avalanches"}
+    Number  MA_etat_canicule             "Canicule [%s]"         <aqi>       (gMeteoAlert)   {channel="meteoalerte:department:yvelines:canicule"}
+    Number  MA_etat_grand_froid          "Grand Froid [%s]"      <aqi>       (gMeteoAlert)   {channel="meteoalerte:department:yvelines:grand-froid"}
+    Number  MA_etat_pluie_inondation     "Pluie-Inondation [%s]" <aqi>       (gMeteoAlert)   {channel="meteoalerte:department:yvelines:pluie-inondation"}
+    Number  MA_etat_neige                "Neige [%s]"            <aqi>       (gMeteoAlert)   {channel="meteoalerte:department:yvelines:neige"}
+    Number  MA_etat_vent                 "Vent [%s]"             <aqi>       (gMeteoAlert)   {channel="meteoalerte:department:yvelines:vent"}
+    Number  MA_etat_inondation           "Inondation [%s]"       <aqi>       (gMeteoAlert)   {channel="meteoalerte:department:yvelines:inondation"}
+    Number  MA_etat_orage                "Orage [%s]"            <aqi>       (gMeteoAlert)   {channel="meteoalerte:department:yvelines:orage"}
+    Number  MA_etat_avalanche            "Avalanches [%s]"       <aqi>       (gMeteoAlert)   {channel="meteoalerte:department:yvelines:avalanches"}
     
     Image       MA_icon_canicule         "Canicule"              <aqi>       (gMeteoAlert)   {channel="meteoalerte:department:yvelines:canicule-icon"}
     Image       MA_icon_grand_froid      "Grand Froid"           <aqi>       (gMeteoAlert)   {channel="meteoalerte:department:yvelines:grand-froid-icon"}
index e29a41fb5342feaec367e08278225428c149aa03..7dfcc29952c1fc1cf1d453e3c0b9fc101ebc1636 100644 (file)
@@ -14,18 +14,15 @@ package org.openhab.binding.meteoalerte.internal.handler;
 
 import static org.openhab.binding.meteoalerte.internal.MeteoAlerteBindingConstants.*;
 
-import java.io.BufferedReader;
 import java.io.IOException;
 import java.io.InputStream;
-import java.io.InputStreamReader;
 import java.net.MalformedURLException;
+import java.nio.charset.StandardCharsets;
 import java.time.ZonedDateTime;
 import java.util.AbstractMap;
-import java.util.Arrays;
 import java.util.Map;
 import java.util.concurrent.ScheduledFuture;
 import java.util.concurrent.TimeUnit;
-import java.util.stream.Collectors;
 
 import org.eclipse.jdt.annotation.NonNullByDefault;
 import org.eclipse.jdt.annotation.Nullable;
@@ -34,6 +31,7 @@ import org.openhab.binding.meteoalerte.internal.json.ApiResponse;
 import org.openhab.binding.meteoalerte.internal.json.ResponseFieldDTO.AlertLevel;
 import org.openhab.core.io.net.http.HttpUtil;
 import org.openhab.core.library.types.DateTimeType;
+import org.openhab.core.library.types.DecimalType;
 import org.openhab.core.library.types.RawType;
 import org.openhab.core.library.types.StringType;
 import org.openhab.core.thing.ChannelUID;
@@ -43,9 +41,8 @@ import org.openhab.core.thing.ThingStatusDetail;
 import org.openhab.core.thing.binding.BaseThingHandler;
 import org.openhab.core.types.Command;
 import org.openhab.core.types.RefreshType;
+import org.openhab.core.types.State;
 import org.openhab.core.types.UnDefType;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.FrameworkUtil;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -61,7 +58,7 @@ import com.google.gson.Gson;
 public class MeteoAlerteHandler extends BaseThingHandler {
     private static final String URL = "https://public.opendatasoft.com/api/records/1.0/search/?dataset=risques-meteorologiques-copy&"
             + "facet=etat_vent&facet=etat_pluie_inondation&facet=etat_orage&facet=etat_inondation&facet=etat_neige&facet=etat_canicule&"
-            + "facet=etat_grand_froid&facet=etat_avalanches&refine.nom_dept=";
+            + "facet=etat_grand_froid&facet=etat_avalanches&refine.nom_dept=%s";
     private static final int TIMEOUT_MS = 30000;
     private static final String UNKNOWN_COLOR = "b3b3b3";
     private static final Map<AlertLevel, String> ALERT_COLORS = Map.ofEntries(
@@ -91,7 +88,7 @@ public class MeteoAlerteHandler extends BaseThingHandler {
         logger.debug("config refresh = {}", config.refresh);
 
         updateStatus(ThingStatus.UNKNOWN);
-        queryUrl = URL + config.department;
+        queryUrl = String.format(URL, config.department);
         refreshJob = scheduler.scheduleWithFixedDelay(this::updateAndPublish, 0, config.refresh, TimeUnit.MINUTES);
     }
 
@@ -135,29 +132,30 @@ public class MeteoAlerteHandler extends BaseThingHandler {
      * @param channelId the id identifying the channel to be updated
      */
     private void updateChannels(ApiResponse apiResponse) {
-        Arrays.stream(apiResponse.getRecords()).findFirst()
-                .ifPresent((record) -> record.getResponseFieldDTO().ifPresent(fields -> {
-                    updateAlert(WIND, fields.getVent());
-                    updateAlert(RAIN, fields.getPluieInondation());
-                    updateAlert(STORM, fields.getOrage());
-                    updateAlert(FLOOD, fields.getInondation());
-                    updateAlert(SNOW, fields.getNeige());
-                    updateAlert(HEAT, fields.getCanicule());
-                    updateAlert(FREEZE, fields.getGrandFroid());
-                    updateAlert(AVALANCHE, fields.getAvalanches());
-                    updateAlert(WAVE, fields.getVagueSubmersion());
-                    updateState(COMMENT, new StringType(fields.getVigilanceComment()));
-                    fields.getDateInsert().ifPresent(date -> updateDate(OBSERVATION_TIME, date));
-                    fields.getDatePrevue().ifPresent(date -> updateDate(END_TIME, date));
-                }));
+        apiResponse.getRecords().findFirst().ifPresent((record) -> record.getResponseFieldDTO().ifPresent(fields -> {
+            updateAlert(WIND, fields.getVent());
+            updateAlert(RAIN, fields.getPluieInondation());
+            updateAlert(STORM, fields.getOrage());
+            updateAlert(FLOOD, fields.getInondation());
+            updateAlert(SNOW, fields.getNeige());
+            updateAlert(HEAT, fields.getCanicule());
+            updateAlert(FREEZE, fields.getGrandFroid());
+            updateAlert(AVALANCHE, fields.getAvalanches());
+            updateAlert(WAVE, fields.getVagueSubmersion());
+            updateState(COMMENT, new StringType(fields.getVigilanceComment()));
+            fields.getDateInsert().ifPresent(date -> updateDate(OBSERVATION_TIME, date));
+            fields.getDatePrevue().ifPresent(date -> updateDate(END_TIME, date));
+        }));
     }
 
-    public @Nullable String getResource(String iconPath) {
-        Bundle bundle = FrameworkUtil.getBundle(getClass());
-        try (InputStream stream = bundle.getResource(iconPath).openStream()) {
-            return new BufferedReader(new InputStreamReader(stream)).lines().collect(Collectors.joining("\n"));
-        } catch (IOException e) {
-            logger.warn("Unable to load ressource '{}' : {}", iconPath, e.getMessage());
+    public byte @Nullable [] getResource(String iconPath) {
+        ClassLoader classLoader = MeteoAlerteHandler.class.getClassLoader();
+        if (classLoader != null) {
+            try (InputStream stream = classLoader.getResourceAsStream(iconPath)) {
+                return stream != null ? stream.readAllBytes() : null;
+            } catch (IOException e) {
+                logger.warn("Unable to load ressource '{}' : {}", iconPath, e.getMessage());
+            }
         }
         return null;
     }
@@ -165,15 +163,17 @@ public class MeteoAlerteHandler extends BaseThingHandler {
     public void updateAlert(String channelId, AlertLevel value) {
         String channelIcon = channelId + "-icon";
         if (isLinked(channelId)) {
-            updateState(channelId, value != AlertLevel.UNKNOWN ? new StringType(value.name()) : UnDefType.UNDEF);
+            updateState(channelId, getAlertLevel(value));
         }
         if (isLinked(channelIcon)) {
-            String resource = getResource(String.format("picto/%s.svg", channelId));
-            if (resource != null) {
+            State result = UnDefType.UNDEF;
+            byte[] bytes = getResource(String.format("picto/%s.svg", channelId));
+            if (bytes != null) {
+                String resource = new String(bytes, StandardCharsets.UTF_8);
                 resource = resource.replaceAll(UNKNOWN_COLOR, ALERT_COLORS.getOrDefault(value, UNKNOWN_COLOR));
+                result = new RawType(resource.getBytes(StandardCharsets.UTF_8), "image/svg+xml");
             }
-            updateState(channelIcon,
-                    resource != null ? new RawType(resource.getBytes(), "image/svg+xml") : UnDefType.UNDEF);
+            updateState(channelIcon, result);
         }
     }
 
@@ -182,4 +182,19 @@ public class MeteoAlerteHandler extends BaseThingHandler {
             updateState(channelId, new DateTimeType(zonedDateTime));
         }
     }
+
+    public State getAlertLevel(AlertLevel alert) {
+        switch (alert) {
+            case GREEN:
+                return DecimalType.ZERO;
+            case YELLOW:
+                return new DecimalType(1);
+            case ORANGE:
+                return new DecimalType(2);
+            case RED:
+                return new DecimalType(3);
+            default:
+                return UnDefType.UNDEF;
+        }
+    }
 }
index 54119fcbacff15f759f96bc00f8414b32a8a2bfa..499efe01f002153981d76dfbb084a9adcca893c2 100644 (file)
  */
 package org.openhab.binding.meteoalerte.internal.json;
 
+import java.util.ArrayList;
+import java.util.List;
 import java.util.Optional;
+import java.util.stream.Stream;
 
 import org.eclipse.jdt.annotation.NonNullByDefault;
 import org.eclipse.jdt.annotation.Nullable;
@@ -30,7 +33,7 @@ public class ApiResponse {
     @SerializedName("nhits")
     private int nHits;
     private @Nullable Parameters parameters;
-    private Record[] records = {};
+    private List<Record> records = new ArrayList<>();
 
     public int getNHits() {
         return nHits;
@@ -44,7 +47,7 @@ public class ApiResponse {
         return Optional.empty();
     }
 
-    public Record[] getRecords() {
-        return records;
+    public Stream<Record> getRecords() {
+        return records.stream();
     }
 }
index b83f35eeb520768a47c3a131c58cce1774833faf..fafa8336ca59e3e27ba99d96e510a10baa09688f 100644 (file)
        </thing-type>
 
        <channel-type id="alert-level">
-               <item-type>String</item-type>
+               <item-type>Number</item-type>
                <label>Alerte</label>
                <state readOnly="true">
                        <options>
-                               <option value="GREEN">Vert</option>
-                               <option value="YELLOW">Jaune</option>
-                               <option value="ORANGE">Orange</option>
-                               <option value="RED">Rouge</option>
+                               <option value="0">Vert</option>
+                               <option value="1">Jaune</option>
+                               <option value="2">Orange</option>
+                               <option value="3">Rouge</option>
                        </options>
                </state>
        </channel-type>