Forráskód Böngészése

Added 'allowedStation' for FieldClimate

Lukas Cerny 5 éve
szülő
commit
4dd8d15d77

+ 18 - 3
config/fieldclimateSenslog1.yaml

@@ -35,9 +35,24 @@ settings:
         <<: *fieldClimateApiDomain
         path: "/data/{station_id}"
 
-      blockedStations:
-        - "0120821D"
-        - "0120821E"
+      allowedStation:
+        # station_id:
+        "0120821E":
+            # sensor_id: [channel]
+            - 17153: [4062, 4063, 4064, 4065, 4066, 4067, 4068, 4069, 4070, 4071, 4072, 4073]
+            - 19969: [4038, 4039, 4040, 4041, 4042, 4043, 4044, 4045, 4046, 4047, 4048, 4049]
+            - 20228: [4050, 4051, 4052, 4053, 4054, 4055, 4056, 4057, 4058, 4059, 4060, 4061]
+
+        # station_id: [sensor_id]
+        "00208048": [4, 5, 6, 49, 143, 506, 507, 600]
+
+        # station_id:
+        "0120821D":
+            #sensor_id: [channel]
+            - 17153: [4062, 4063, 4064, 4065, 4066, 4067, 4068, 4069, 4070, 4071, 4072, 4073]
+            - 19969: [4038, 4039, 4040, 4041, 4042, 4043, 4044, 4045, 4046, 4047, 4048, 4049]
+            - 20228: [4050, 4051, 4052, 4053, 4054, 4055, 4056, 4057, 4058, 4059, 4060, 4061]
+
 
       sessionProxy:
         user: "vilcini"

+ 95 - 0
connector-fetch-fieldclimate/src/main/java/cz/senslog/connector/fetch/fieldclimate/AllowedStation.java

@@ -0,0 +1,95 @@
+package cz.senslog.connector.fetch.fieldclimate;
+
+import cz.senslog.connector.model.config.PropertyConfig;
+import cz.senslog.connector.model.fieldclimate.SensorType;
+
+import java.util.*;
+
+class AllowedStation {
+
+    private static class Sensor {
+        final Integer id;
+        final Set<Integer> channels;
+        Sensor(Integer id, Set<Integer> channels) {
+            this.id = id;
+            this.channels = channels;
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (this == o) return true;
+            if (o == null || getClass() != o.getClass()) return false;
+            Sensor sensor = (Sensor) o;
+            return id.equals(sensor.id);
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(id);
+        }
+    }
+
+    private final Map<String, Map<Integer, Sensor>> stations;
+
+    AllowedStation(PropertyConfig config) {
+        Set<Long> sensorTypes = SensorType.getIDs();
+        Set<String> attributes = config.getAttributes();
+        Map<String, Map<Integer, Sensor>> stations = new HashMap<>(attributes.size());
+        for (String stationId : attributes) {
+            Object attrValue = config.getProperty(stationId);
+            if (attrValue instanceof List) {
+                List<?> sensors = (List<?>)attrValue;
+                for (Object sensor : sensors) {
+                    if (sensor instanceof Map) {
+                        Map<?, ?> sensorMap = (Map<?, ?>)sensor;
+                        for (Map.Entry<?, ?> sensorEntry : sensorMap.entrySet()) {
+                            if (sensorEntry.getKey() instanceof Integer) {
+                                Integer sensorId = (Integer)sensorEntry.getKey();
+                                if (!sensorTypes.contains(sensorId.longValue())) {
+                                    throw new UnsupportedOperationException(String.format(
+                                            "For allowed sensor '%s' does not exist converter.", sensorId)
+                                    );
+                                }
+                                if (sensorEntry.getValue() instanceof List) {
+                                    List<?> channels = (List<?>)sensorEntry.getValue();
+                                    Set<Integer> channelsNew = new HashSet<>(channels.size());
+                                    for (Object channel : channels) {
+                                        if (channel instanceof Integer) {
+                                            channelsNew.add((Integer)channel);
+                                        }
+                                    }
+                                    stations.computeIfAbsent(stationId, k -> new HashMap<>())
+                                            .put(sensorId, new Sensor(sensorId, channelsNew));
+                                }
+                            }
+                        }
+                    } else if (sensor instanceof Integer) {
+                        Integer sensorId = (Integer)sensor;
+                        if (!sensorTypes.contains(sensorId.longValue())) {
+                            throw new UnsupportedOperationException(String.format(
+                                    "For allowed sensor '%s' does not exist converter.", sensorId)
+                            );
+                        }
+                        stations.computeIfAbsent(stationId, k -> new HashMap<>())
+                                .put(sensorId, new Sensor(sensorId, Collections.emptySet()));
+                    }
+                }
+            }
+        }
+
+        this.stations = stations;
+    }
+
+    public boolean isAllowed(String stationId) {
+        return stations.containsKey(stationId);
+    }
+
+    public boolean isAllowed(String stationId, Long sensorId) {
+        return isAllowed(stationId) && stations.get(stationId).containsKey(sensorId.intValue());
+    }
+
+    public boolean isAllowed(String stationId, Long sensorId, Long channel) {
+        return isAllowed(stationId, sensorId) &&
+                stations.get(stationId).get(sensorId.intValue()).channels.contains(channel.intValue());
+    }
+}

+ 4 - 4
connector-fetch-fieldclimate/src/main/java/cz/senslog/connector/fetch/fieldclimate/FieldClimateConfig.java

@@ -20,7 +20,7 @@ public class FieldClimateConfig {
     private final AuthConfig authentication;
     private final Integer period;
     private final FieldClimateSessionProxyConfig sessionProxy;
-    private final Set<String> blockedStations;
+    private final AllowedStation allowedStation;
     private final TimeZone timeZone;
 
     public FieldClimateConfig(DefaultConfig config) {
@@ -30,7 +30,7 @@ public class FieldClimateConfig {
         this.stationTimeRangeHost = new HostConfig(config.getPropertyConfig("stationTimeRangeHost"));
         this.authentication = new AuthConfig(config.getPropertyConfig("authentication"));
         this.period = config.getIntegerProperty("period");
-        this.blockedStations = config.getSetProperty("blockedStations", String.class);
+        this.allowedStation = new AllowedStation(config.getPropertyConfig("allowedStation"));
         this.timeZone = TimeZone.getTimeZone(config.getStringProperty("timeZone"));
 
         this.sessionProxy = config.containsProperty("sessionProxy") ?
@@ -61,8 +61,8 @@ public class FieldClimateConfig {
         return period;
     }
 
-    public Set<String> getBlockedStations() {
-        return blockedStations;
+    public AllowedStation getAllowedStation() {
+        return allowedStation;
     }
 
     public TimeZone getTimeZone() {

+ 32 - 6
connector-fetch-fieldclimate/src/main/java/cz/senslog/connector/fetch/fieldclimate/FieldClimateFetcher.java

@@ -11,9 +11,7 @@ import cz.senslog.common.http.HttpRequest;
 import cz.senslog.common.http.HttpResponse;
 import cz.senslog.common.http.URLBuilder;
 import cz.senslog.connector.model.api.ProxySessionModel;
-import cz.senslog.connector.model.fieldclimate.FieldClimateModel;
-import cz.senslog.connector.model.fieldclimate.StationData;
-import cz.senslog.connector.model.fieldclimate.StationInfo;
+import cz.senslog.connector.model.fieldclimate.*;
 import cz.senslog.common.util.Tuple;
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
@@ -96,8 +94,8 @@ public class FieldClimateFetcher implements ConnectorFetcher<FieldClimateSession
         }
 
         stationInfos = new ArrayList<>(stations.size());
-        for (StationInfo station : stations) { // TODO change to whitelist
-            if (!config.getBlockedStations().contains(station.getName().getOriginal())) {
+        for (StationInfo station : stations) {
+            if (config.getAllowedStation().isAllowed(station.getName().getOriginal())) {
                 stationInfos.add(station);
             }
         }
@@ -183,21 +181,49 @@ public class FieldClimateFetcher implements ConnectorFetcher<FieldClimateSession
                     continue;
                 }
 
+                List<SensorDataInfo> filteredSensors = new ArrayList<>(stationData.getSensors().size());
+                for (SensorDataInfo sensor : stationData.getSensors()) {
+                    if (SensorType.of(sensor.getCode()).isChanneled()) {
+                        if (config.getAllowedStation().isAllowed(stationId, sensor.getCode(), sensor.getCh())) {
+                            filteredSensors.add(sensor);
+                        }
+                    } else if (config.getAllowedStation().isAllowed(stationId, sensor.getCode())) {
+                        filteredSensors.add(sensor);
+                    }
+                }
+
                 stationData.setId(stationId);
+                stationData.setSensors(filteredSensors);
 
                 OffsetDateTime latestTimestamp = OffsetDateTime.MIN;
+                List<Map<String, String>> filteredDataList = new ArrayList<>(stationData.getData().size());
                 for (Map<String, String> sensorDataMap : stationData.getData()) {
+                    Map<String, String> filteredSensorData = new HashMap<>(sensorDataMap.size());
+
                     String strDate = sensorDataMap.getOrDefault("date", "");
                     final DateTimeFormatter formatter = ofPattern("yyyy-MM-dd HH:mm:ss");
                     LocalDateTime date = LocalDateTime.parse(strDate, formatter);
                     ZonedDateTime zonedDate = ZonedDateTime.of(date, config.getTimeZone().toZoneId());
                     OffsetDateTime timestamp = zonedDate.toOffsetDateTime();
-                    sensorDataMap.put("date", timestamp.format(ISO_OFFSET_DATE_TIME));
+                    filteredSensorData.put("date", timestamp.format(ISO_OFFSET_DATE_TIME));
+
+                    for (SensorDataInfo sensor : filteredSensors) {
+                        for (String aggrType : sensor.getAggr().keySet()) {
+                            String sensorDataHash = format("%s_%s_%s_%s_%s",
+                                    sensor.getCh(), sensor.getMac(), sensor.getSerial(), sensor.getCode(), aggrType);
+                            if (sensorDataMap.containsKey(sensorDataHash)) {
+                                filteredSensorData.put(sensorDataHash, sensorDataMap.get(sensorDataHash));
+                            }
+                        }
+                    }
+
+                    filteredDataList.add(filteredSensorData);
 
                     if (latestTimestamp.isBefore(timestamp)) {
                         latestTimestamp = timestamp;
                     }
                 }
+                stationData.setData(filteredDataList);
 
                 localTo = latestTimestamp.isAfter(localTo) ? latestTimestamp : localTo;
 

+ 4 - 0
connector-model/src/main/java/cz/senslog/connector/model/config/PropertyConfig.java

@@ -178,6 +178,10 @@ public class PropertyConfig {
         return config;
     }
 
+    public Set<String> getAttributes() {
+        return properties.keySet();
+    }
+
     private String getNewPropertyId(String name) {
         return id + PATH_DELIMITER + name;
     }

+ 0 - 1
connector-model/src/main/java/cz/senslog/connector/model/converter/FieldClimateModelSenslogV1ModelConverter.java

@@ -22,7 +22,6 @@ import static cz.senslog.connector.model.fieldclimate.SensorType.Group.POSITION;
 import static cz.senslog.connector.model.fieldclimate.SensorType.countOfGroup;
 import static java.lang.String.format;
 import static java.time.format.DateTimeFormatter.ISO_OFFSET_DATE_TIME;
-import static java.time.format.DateTimeFormatter.ISO_ZONED_DATE_TIME;
 
 public class FieldClimateModelSenslogV1ModelConverter implements Converter<FieldClimateModel, SenslogV1Model> {
 

+ 13 - 2
connector-model/src/main/java/cz/senslog/connector/model/fieldclimate/SensorType.java

@@ -1,7 +1,6 @@
 package cz.senslog.connector.model.fieldclimate;
 
-import java.util.HashMap;
-import java.util.Map;
+import java.util.*;
 
 /**
  * The enum {@code SensorType} represents type of sensor
@@ -82,6 +81,10 @@ public enum SensorType {
         return group != null;
     }
 
+    public boolean isChanneled() {
+        return group != null && group.equals(Group.MULTICHANNEL);
+    }
+
     public Group getGroup() {
         return group;
     }
@@ -100,6 +103,14 @@ public enum SensorType {
         return count;
     }
 
+    public static Set<Long> getIDs() {
+        Set<Long> ids = new HashSet<>(values().length);
+        for (SensorType value : values()) {
+            ids.add(value.code);
+        }
+        return ids;
+    }
+
     public static SensorType of(long code) {
         return VALUES.getOrDefault(code, null);
     }