|
|
@@ -0,0 +1,485 @@
|
|
|
+package cz.senslog.connector.fetch.fieldclimate;
|
|
|
+
|
|
|
+import cz.senslog.connector.config.model.DefaultConfig;
|
|
|
+import cz.senslog.connector.fetch.fieldclimate.auth.AuthenticationService;
|
|
|
+import cz.senslog.connector.http.HttpClient;
|
|
|
+import cz.senslog.connector.http.HttpRequest;
|
|
|
+import cz.senslog.connector.http.HttpResponse;
|
|
|
+import cz.senslog.connector.model.fieldclimate.FieldClimateModel;
|
|
|
+import cz.senslog.connector.model.fieldclimate.SensorDataInfo;
|
|
|
+import cz.senslog.connector.model.fieldclimate.StationData;
|
|
|
+import cz.senslog.connector.model.fieldclimate.StationInfo;
|
|
|
+import org.junit.jupiter.api.Assertions;
|
|
|
+import org.junit.jupiter.api.BeforeAll;
|
|
|
+import org.junit.jupiter.api.Test;
|
|
|
+import org.mockito.stubbing.Answer;
|
|
|
+
|
|
|
+import java.time.LocalDateTime;
|
|
|
+import java.util.HashMap;
|
|
|
+import java.util.List;
|
|
|
+import java.util.Map;
|
|
|
+
|
|
|
+import static cz.senslog.connector.http.HttpCode.OK;
|
|
|
+import static cz.senslog.connector.http.HttpCode.SERVER_ERROR;
|
|
|
+import static java.lang.String.format;
|
|
|
+import static java.time.format.DateTimeFormatter.ofPattern;
|
|
|
+import static java.util.Collections.emptyList;
|
|
|
+import static java.util.Collections.singletonList;
|
|
|
+import static org.junit.jupiter.api.Assertions.assertEquals;
|
|
|
+import static org.junit.jupiter.api.Assertions.assertTrue;
|
|
|
+import static org.mockito.ArgumentMatchers.any;
|
|
|
+import static org.mockito.Mockito.mock;
|
|
|
+import static org.mockito.Mockito.when;
|
|
|
+
|
|
|
+class FieldClimateFetcherTest {
|
|
|
+
|
|
|
+ private static FieldClimateConfig config;
|
|
|
+ private static AuthenticationService authService;
|
|
|
+ private static LocalDateTime startDate = LocalDateTime.of(2019, 9, 22, 0, 0,0);
|
|
|
+
|
|
|
+ @BeforeAll
|
|
|
+ static void init() {
|
|
|
+ DefaultConfig fcDConfig = new DefaultConfig("fcConfig", null);
|
|
|
+ fcDConfig.setProperty("stationsHost", new HashMap<String, String>(){{
|
|
|
+ put("domain", "https://api.fieldclimate.com/v1");
|
|
|
+ put("path", "/user/stations");
|
|
|
+ }});
|
|
|
+
|
|
|
+ fcDConfig.setProperty("stationDataHost", new HashMap<String, String>(){{
|
|
|
+ put("domain", "https://api.fieldclimate.com/v1");
|
|
|
+ put("path", "/data/normal/{station_id}/raw/from/{from}/to/{to}");
|
|
|
+ }});
|
|
|
+
|
|
|
+ fcDConfig.setProperty("stationTimeRangeHost", new HashMap<String, String>(){{
|
|
|
+ put("domain", "https://api.fieldclimate.com/v1");
|
|
|
+ put("path", "/data/{station_id}");
|
|
|
+ }});
|
|
|
+
|
|
|
+ fcDConfig.setProperty("authentication", new HashMap<String, String>(){{
|
|
|
+ put("publicKey", "3737ed4fe98fae975e54991216ed473c8d7db48662deff19");
|
|
|
+ put("privateKey", "ed2e4abacdaad1d542eeabcec4ee4f6c8fbf3b8bb167b84b");
|
|
|
+ }});
|
|
|
+
|
|
|
+ fcDConfig.setProperty("startDate", startDate);
|
|
|
+
|
|
|
+ config = new FieldClimateConfig(fcDConfig);
|
|
|
+ authService = new AuthenticationService(config.getAuthentication());
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ void init_GetStations() throws Exception {
|
|
|
+
|
|
|
+ HttpClient httpClient = mock(HttpClient.class);
|
|
|
+ when(httpClient.send(any(HttpRequest.class))).thenAnswer((Answer<HttpResponse>) invocationOnMock -> {
|
|
|
+ HttpRequest request = invocationOnMock.getArgument(0, HttpRequest.class);
|
|
|
+ String path = request.getUrl().getPath();
|
|
|
+ if (path.contains("/user/stations")) {
|
|
|
+ StationInfo stationInfo = new StationInfo();
|
|
|
+ StationInfo.Name stationName = new StationInfo.Name();
|
|
|
+ stationName.setOriginal("original_name");
|
|
|
+ stationInfo.setName(stationName);
|
|
|
+ String stationsJson = singletonList(stationInfo).toString();
|
|
|
+ return HttpResponse.newBuilder()
|
|
|
+ .status(OK).body(stationsJson).build();
|
|
|
+ }
|
|
|
+ return HttpResponse.newBuilder()
|
|
|
+ .status(SERVER_ERROR).build();
|
|
|
+ });
|
|
|
+ FieldClimateFetcher fetcher = new FieldClimateFetcher(config, authService, httpClient);
|
|
|
+
|
|
|
+ fetcher.init();
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ void init_StationsRequestError_Exception() {
|
|
|
+
|
|
|
+ HttpClient httpClient = mock(HttpClient.class);
|
|
|
+ when(httpClient.send(any(HttpRequest.class))).thenAnswer((Answer<HttpResponse>) invocationOnMock ->
|
|
|
+ HttpResponse.newBuilder().status(SERVER_ERROR).build()
|
|
|
+ );
|
|
|
+ FieldClimateFetcher fetcher = new FieldClimateFetcher(config, authService, httpClient);
|
|
|
+
|
|
|
+ Assertions.assertThrows(Exception.class, fetcher::init);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ void init_NoneStations_Exception() {
|
|
|
+
|
|
|
+ HttpClient httpClient = mock(HttpClient.class);
|
|
|
+ when(httpClient.send(any(HttpRequest.class))).thenAnswer((Answer<HttpResponse>) invocationOnMock -> {
|
|
|
+ HttpRequest request = invocationOnMock.getArgument(0, HttpRequest.class);
|
|
|
+ String path = request.getUrl().getPath();
|
|
|
+ if (path.contains("/user/stations")) {
|
|
|
+ return HttpResponse.newBuilder()
|
|
|
+ .status(OK).body(emptyList().toString()).build();
|
|
|
+ }
|
|
|
+
|
|
|
+ return HttpResponse.newBuilder().status(SERVER_ERROR).build();
|
|
|
+ });
|
|
|
+ FieldClimateFetcher fetcher = new FieldClimateFetcher(config, authService, httpClient);
|
|
|
+
|
|
|
+ Assertions.assertThrows(Exception.class, fetcher::init);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ void fetch_EmptyStationName_EmptyModel() throws Exception {
|
|
|
+ HttpClient httpClient = mock(HttpClient.class);
|
|
|
+ when(httpClient.send(any(HttpRequest.class))).thenAnswer((Answer<HttpResponse>) invocationOnMock -> {
|
|
|
+ HttpRequest request = invocationOnMock.getArgument(0, HttpRequest.class);
|
|
|
+ String path = request.getUrl().getPath();
|
|
|
+ if (path.contains("/user/stations")) {
|
|
|
+ StationInfo stationInfo = new StationInfo();
|
|
|
+ StationInfo.Name name = new StationInfo.Name();
|
|
|
+ name.setOriginal("");
|
|
|
+ stationInfo.setName(name);
|
|
|
+ List<StationInfo> stations = singletonList(stationInfo);
|
|
|
+ return HttpResponse.newBuilder()
|
|
|
+ .status(OK).body(stations.toString()).build();
|
|
|
+ }
|
|
|
+ return HttpResponse.newBuilder()
|
|
|
+ .status(SERVER_ERROR).build();
|
|
|
+ });
|
|
|
+ FieldClimateFetcher fetcher = new FieldClimateFetcher(config, authService, httpClient);
|
|
|
+ fetcher.init();
|
|
|
+
|
|
|
+ FieldClimateModel model = fetcher.fetch();
|
|
|
+
|
|
|
+ assertTrue(model.getStations().isEmpty());
|
|
|
+ assertEquals(startDate, model.getFrom());
|
|
|
+ assertEquals(startDate, model.getTo());
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ void fetch_StationTimeRangeRequestError_EmptyModel() throws Exception {
|
|
|
+ String stationName = "original_name";
|
|
|
+ HttpClient httpClient = mock(HttpClient.class);
|
|
|
+ when(httpClient.send(any(HttpRequest.class))).thenAnswer((Answer<HttpResponse>) invocationOnMock -> {
|
|
|
+ HttpRequest request = invocationOnMock.getArgument(0, HttpRequest.class);
|
|
|
+ String path = request.getUrl().getPath();
|
|
|
+ if (path.contains("/user/stations")) {
|
|
|
+ StationInfo stationInfo = new StationInfo();
|
|
|
+ StationInfo.Name name = new StationInfo.Name();
|
|
|
+ name.setOriginal(stationName);
|
|
|
+ stationInfo.setName(name);
|
|
|
+ List<StationInfo> stations = singletonList(stationInfo);
|
|
|
+ return HttpResponse.newBuilder()
|
|
|
+ .status(OK).body(stations.toString()).build();
|
|
|
+ }
|
|
|
+ if (path.contains("/data/"+stationName)) {
|
|
|
+ return HttpResponse.newBuilder()
|
|
|
+ .status(SERVER_ERROR).build();
|
|
|
+ }
|
|
|
+ return HttpResponse.newBuilder()
|
|
|
+ .status(SERVER_ERROR).build();
|
|
|
+ });
|
|
|
+ FieldClimateFetcher fetcher = new FieldClimateFetcher(config, authService, httpClient);
|
|
|
+ fetcher.init();
|
|
|
+
|
|
|
+ FieldClimateModel model = fetcher.fetch();
|
|
|
+
|
|
|
+ assertTrue(model.getStations().isEmpty());
|
|
|
+ assertEquals(startDate, model.getFrom());
|
|
|
+ assertEquals(startDate, model.getTo());
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ void fetch_StationTimeRangeBadData_EmptyModel() throws Exception {
|
|
|
+ String stationName = "original_name";
|
|
|
+ HttpClient httpClient = mock(HttpClient.class);
|
|
|
+ when(httpClient.send(any(HttpRequest.class))).thenAnswer((Answer<HttpResponse>) invocationOnMock -> {
|
|
|
+ HttpRequest request = invocationOnMock.getArgument(0, HttpRequest.class);
|
|
|
+ String path = request.getUrl().getPath();
|
|
|
+ if (path.contains("/user/stations")) {
|
|
|
+ StationInfo stationInfo = new StationInfo();
|
|
|
+ StationInfo.Name name = new StationInfo.Name();
|
|
|
+ name.setOriginal(stationName);
|
|
|
+ stationInfo.setName(name);
|
|
|
+ List<StationInfo> stations = singletonList(stationInfo);
|
|
|
+ return HttpResponse.newBuilder()
|
|
|
+ .status(OK).body(stations.toString()).build();
|
|
|
+ }
|
|
|
+ if (path.contains("/data/"+stationName)) {
|
|
|
+ String json = String.format("{\"min_date\":\"%s\",\"max_date\":\"%s\"}", "unknown", "unknown");
|
|
|
+ return HttpResponse.newBuilder().status(OK).body(json).build();
|
|
|
+ }
|
|
|
+ return HttpResponse.newBuilder()
|
|
|
+ .status(SERVER_ERROR).build();
|
|
|
+ });
|
|
|
+ FieldClimateFetcher fetcher = new FieldClimateFetcher(config, authService, httpClient);
|
|
|
+ fetcher.init();
|
|
|
+
|
|
|
+ FieldClimateModel model = fetcher.fetch();
|
|
|
+
|
|
|
+ assertTrue(model.getStations().isEmpty());
|
|
|
+ assertEquals(startDate, model.getFrom());
|
|
|
+ assertEquals(startDate, model.getTo());
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ void fetch_StationDataErrorRequest_EmptyModel() throws Exception {
|
|
|
+ String stationName = "original_name";
|
|
|
+ HttpClient httpClient = mock(HttpClient.class);
|
|
|
+ when(httpClient.send(any(HttpRequest.class))).thenAnswer((Answer<HttpResponse>) invocationOnMock -> {
|
|
|
+ HttpRequest request = invocationOnMock.getArgument(0, HttpRequest.class);
|
|
|
+ String path = request.getUrl().getPath();
|
|
|
+ if (path.contains("/user/stations")) {
|
|
|
+ StationInfo stationInfo = new StationInfo();
|
|
|
+ StationInfo.Name name = new StationInfo.Name();
|
|
|
+ name.setOriginal(stationName);
|
|
|
+ stationInfo.setName(name);
|
|
|
+ List<StationInfo> stations = singletonList(stationInfo);
|
|
|
+ return HttpResponse.newBuilder()
|
|
|
+ .status(OK).body(stations.toString()).build();
|
|
|
+ }
|
|
|
+ if (path.contains("/data/"+stationName)) {
|
|
|
+ String json = String.format("{\"min_date\":\"%s\",\"max_date\":\"%s\"}",
|
|
|
+ startDate.minusDays(1).format(ofPattern("yyyy-MM-dd HH:mm:ss")),
|
|
|
+ startDate.plusDays(1).format(ofPattern("yyyy-MM-dd HH:mm:ss"))
|
|
|
+ );
|
|
|
+ return HttpResponse.newBuilder().status(OK).body(json).build();
|
|
|
+ }
|
|
|
+ if (path.contains("/data/normal/"+stationName)) {
|
|
|
+ return HttpResponse.newBuilder()
|
|
|
+ .status(SERVER_ERROR).build();
|
|
|
+ }
|
|
|
+ return HttpResponse.newBuilder()
|
|
|
+ .status(SERVER_ERROR).build();
|
|
|
+ });
|
|
|
+ FieldClimateFetcher fetcher = new FieldClimateFetcher(config, authService, httpClient);
|
|
|
+ fetcher.init();
|
|
|
+
|
|
|
+ FieldClimateModel model = fetcher.fetch();
|
|
|
+
|
|
|
+ assertTrue(model.getStations().isEmpty());
|
|
|
+ assertEquals(startDate, model.getFrom());
|
|
|
+ assertEquals(startDate, model.getTo());
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ void fetch_StationDataBadJson_EmptyModel() throws Exception {
|
|
|
+ String stationName = "original_name";
|
|
|
+ HttpClient httpClient = mock(HttpClient.class);
|
|
|
+ when(httpClient.send(any(HttpRequest.class))).thenAnswer((Answer<HttpResponse>) invocationOnMock -> {
|
|
|
+ HttpRequest request = invocationOnMock.getArgument(0, HttpRequest.class);
|
|
|
+ String path = request.getUrl().getPath();
|
|
|
+ if (path.contains("/user/stations")) {
|
|
|
+ StationInfo stationInfo = new StationInfo();
|
|
|
+ StationInfo.Name name = new StationInfo.Name();
|
|
|
+ name.setOriginal(stationName);
|
|
|
+ stationInfo.setName(name);
|
|
|
+ List<StationInfo> stations = singletonList(stationInfo);
|
|
|
+ return HttpResponse.newBuilder()
|
|
|
+ .status(OK).body(stations.toString()).build();
|
|
|
+ }
|
|
|
+ if (path.contains("/data/"+stationName)) {
|
|
|
+ String json = String.format("{\"min_date\":\"%s\",\"max_date\":\"%s\"}",
|
|
|
+ startDate.minusDays(1).format(ofPattern("yyyy-MM-dd HH:mm:ss")),
|
|
|
+ startDate.plusDays(1).format(ofPattern("yyyy-MM-dd HH:mm:ss"))
|
|
|
+ );
|
|
|
+ return HttpResponse.newBuilder().status(OK).body(json).build();
|
|
|
+ }
|
|
|
+ if (path.contains("/data/normal/"+stationName)) {
|
|
|
+ return HttpResponse.newBuilder()
|
|
|
+ .status(OK).body("unknown").build();
|
|
|
+ }
|
|
|
+ return HttpResponse.newBuilder()
|
|
|
+ .status(SERVER_ERROR).build();
|
|
|
+ });
|
|
|
+ FieldClimateFetcher fetcher = new FieldClimateFetcher(config, authService, httpClient);
|
|
|
+ fetcher.init();
|
|
|
+
|
|
|
+ FieldClimateModel model = fetcher.fetch();
|
|
|
+
|
|
|
+ assertTrue(model.getStations().isEmpty());
|
|
|
+ assertEquals(startDate, model.getFrom());
|
|
|
+ assertEquals(startDate, model.getTo());
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ void fetch_Valid_Model() throws Exception {
|
|
|
+ String stationName = "original_name";
|
|
|
+ HttpClient httpClient = mock(HttpClient.class);
|
|
|
+ when(httpClient.send(any(HttpRequest.class))).thenAnswer((Answer<HttpResponse>) invocationOnMock -> {
|
|
|
+ HttpRequest request = invocationOnMock.getArgument(0, HttpRequest.class);
|
|
|
+ String path = request.getUrl().getPath();
|
|
|
+ if (path.contains("/user/stations")) {
|
|
|
+ StationInfo stationInfo = new StationInfo();
|
|
|
+ StationInfo.Name name = new StationInfo.Name();
|
|
|
+ name.setOriginal(stationName);
|
|
|
+ stationInfo.setName(name);
|
|
|
+ List<StationInfo> stations = singletonList(stationInfo);
|
|
|
+ return HttpResponse.newBuilder()
|
|
|
+ .status(OK).body(stations.toString()).build();
|
|
|
+ }
|
|
|
+ if (path.contains("/data/"+stationName)) {
|
|
|
+ String json = String.format("{\"min_date\":\"%s\",\"max_date\":\"%s\"}",
|
|
|
+ startDate.plusHours(1).format(ofPattern("yyyy-MM-dd HH:mm:ss")),
|
|
|
+ startDate.plusHours(2).format(ofPattern("yyyy-MM-dd HH:mm:ss"))
|
|
|
+ );
|
|
|
+ return HttpResponse.newBuilder().status(OK).body(json).build();
|
|
|
+ }
|
|
|
+ if (path.contains("/data/normal/"+stationName)) {
|
|
|
+ StationData data = new StationData();
|
|
|
+ data.setId(stationName);
|
|
|
+ SensorDataInfo dataInfo = new SensorDataInfo();
|
|
|
+ dataInfo.setName("sensorName");
|
|
|
+ dataInfo.setCh(1L);
|
|
|
+ dataInfo.setCode(2L);
|
|
|
+ dataInfo.setMac("mac");
|
|
|
+ dataInfo.setSerial("serial");
|
|
|
+ Map<String, Integer> aggrMap = new HashMap<>();
|
|
|
+ aggrMap.put("avg", 1);
|
|
|
+ dataInfo.setAggr(aggrMap);
|
|
|
+ Map<String, String> dataMap = new HashMap<>();
|
|
|
+ String sensorDataHash = format("%s_%s_%s_%s_%s",
|
|
|
+ dataInfo.getCh(), dataInfo.getMac(), dataInfo.getSerial(), dataInfo.getCode(), "avg");
|
|
|
+ dataMap.put(sensorDataHash, "100");
|
|
|
+ dataMap.put("date", startDate.plusHours(1).plusMinutes(5).format(ofPattern("yyyy-MM-dd HH:mm:ss")));
|
|
|
+ data.setSensors(singletonList(dataInfo));
|
|
|
+ data.setData(singletonList(dataMap));
|
|
|
+ String json = data.toString();
|
|
|
+ return HttpResponse.newBuilder()
|
|
|
+ .status(OK).body(json).build();
|
|
|
+ }
|
|
|
+ return HttpResponse.newBuilder()
|
|
|
+ .status(SERVER_ERROR).build();
|
|
|
+ });
|
|
|
+ FieldClimateFetcher fetcher = new FieldClimateFetcher(config, authService, httpClient);
|
|
|
+ fetcher.init();
|
|
|
+
|
|
|
+ FieldClimateModel model = fetcher.fetch();
|
|
|
+
|
|
|
+ assertEquals(startDate.plusHours(1), model.getFrom());
|
|
|
+ assertEquals(startDate.plusHours(2), model.getTo());
|
|
|
+
|
|
|
+ assertEquals(1, model.getStations().size());
|
|
|
+
|
|
|
+ StationData stationData = model.getStations().get(0);
|
|
|
+ assertEquals(stationName, stationData.getId());
|
|
|
+
|
|
|
+ assertEquals(1, stationData.getSensors().size());
|
|
|
+ assertEquals(1, stationData.getData().size());
|
|
|
+
|
|
|
+ SensorDataInfo dataInfo = stationData.getSensors().get(0);
|
|
|
+ Map<String, String> data = stationData.getData().get(0);
|
|
|
+ assertEquals("sensorName", dataInfo.getName());
|
|
|
+ String sensorDataHash = format("%s_%s_%s_%s_%s",
|
|
|
+ dataInfo.getCh(), dataInfo.getMac(), dataInfo.getSerial(), dataInfo.getCode(),
|
|
|
+ dataInfo.getAggr().entrySet().iterator().next().getKey());
|
|
|
+ assertEquals(100, Integer.valueOf(data.get(sensorDataHash)));
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+/*
|
|
|
+ @Test
|
|
|
+ void fetch() throws Exception {
|
|
|
+
|
|
|
+ FieldClimateFetcher fetcher = new FieldClimateFetcher(config, authService, HttpClient.newHttpSSLClient());
|
|
|
+
|
|
|
+ fetcher.init();
|
|
|
+
|
|
|
+ fetcher.fetch();
|
|
|
+ fetcher.fetch();
|
|
|
+
|
|
|
+
|
|
|
+ System.out.println(new FieldClimateModelSenslogV1ModelConverter().convert(fetcher.fetch()).getObservations());
|
|
|
+ }
|
|
|
+*/
|
|
|
+ /*
|
|
|
+ private void saveToCSV(FieldClimateModel model) throws IOException {
|
|
|
+
|
|
|
+ String [] header = new String[] {
|
|
|
+ "name", "ch", "code", "serial", "mac", "timestamp"
|
|
|
+ };
|
|
|
+
|
|
|
+ String [] valueType = new String[] {
|
|
|
+ "avg", "min", "last", "max", "sum", "time"
|
|
|
+ };
|
|
|
+
|
|
|
+ String delimiter = ";";
|
|
|
+
|
|
|
+ for (StationData station : model.getStations()) {
|
|
|
+
|
|
|
+ StringBuilder stationSheet = new StringBuilder();
|
|
|
+
|
|
|
+ // header
|
|
|
+ stationSheet.append(String.join(delimiter, header));
|
|
|
+ stationSheet.append(delimiter);
|
|
|
+ stationSheet.append(String.join(delimiter, valueType));
|
|
|
+ stationSheet.append("\n");
|
|
|
+
|
|
|
+ for (Map<String, String> stationData : station.getData()) {
|
|
|
+ String timestamp = stationData.getOrDefault("date", "");
|
|
|
+
|
|
|
+ Set<String> done = new HashSet<>();
|
|
|
+ for (Map.Entry<String, String> dataEntry : stationData.entrySet()) {
|
|
|
+ String key = dataEntry.getKey();
|
|
|
+ String value = dataEntry.getValue();
|
|
|
+
|
|
|
+ if (key.contains("_")) {
|
|
|
+ String [] cmp = key.split("_");
|
|
|
+
|
|
|
+ String ch = cmp[0];
|
|
|
+ String mac = cmp[1];
|
|
|
+ String serial = cmp[2];
|
|
|
+ String code = cmp[3];
|
|
|
+ String aggr = cmp[4];
|
|
|
+
|
|
|
+ SensorDataInfo sensor = findSensor(station.getSensors(), Integer.valueOf(ch), mac, serial, Integer.valueOf(code));
|
|
|
+
|
|
|
+ String sensorHash = format("%s_%s_%s_%s", sensor.getCh(), sensor.getMac(), sensor.getSerial(), sensor.getCode());
|
|
|
+
|
|
|
+ if (done.contains(sensorHash)) continue;
|
|
|
+
|
|
|
+ StringBuilder sensorBuilder = new StringBuilder();
|
|
|
+ sensorBuilder.append(sensor.getName()).append(delimiter);
|
|
|
+ sensorBuilder.append(sensor.getCh()).append(delimiter);
|
|
|
+ sensorBuilder.append(sensor.getCode()).append(delimiter);
|
|
|
+ sensorBuilder.append(sensor.getSerial()).append(delimiter);
|
|
|
+ sensorBuilder.append(sensor.getMac());
|
|
|
+ String sensorLine = sensorBuilder.toString();
|
|
|
+
|
|
|
+ StringBuilder valueBuilder = new StringBuilder();
|
|
|
+ for (String type : valueType) {
|
|
|
+
|
|
|
+ String sensorDataHash = format("%s_%s", sensorHash, type);
|
|
|
+
|
|
|
+ if (stationData.containsKey(sensorDataHash)) {
|
|
|
+ valueBuilder.append(stationData.get(sensorDataHash));
|
|
|
+ }
|
|
|
+ valueBuilder.append(delimiter);
|
|
|
+ }
|
|
|
+ String valuesLine = valueBuilder.toString();
|
|
|
+
|
|
|
+
|
|
|
+ stationSheet.append(sensorLine).append(delimiter)
|
|
|
+ .append(timestamp).append(delimiter)
|
|
|
+ .append(valuesLine).append("\n");
|
|
|
+
|
|
|
+ done.add(sensorHash);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ Path filePath = Paths.get("sensor_" + station.getStationId()+ ".csv");
|
|
|
+ Files.write(filePath, Collections.singleton(stationSheet.toString()));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private SensorDataInfo findSensor(List<SensorDataInfo> sensors, Integer ch, String mac, String serial, Integer code) {
|
|
|
+ for (SensorDataInfo sensor : sensors) {
|
|
|
+ if (sensor.getCode().equals(code) &&
|
|
|
+ sensor.getCh().equals(ch) &&
|
|
|
+ sensor.getMac().equals(mac) &&
|
|
|
+ sensor.getSerial().equals(serial)
|
|
|
+ ) {
|
|
|
+ return sensor;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ */
|
|
|
+}
|