fixed rest on cpp; added batch endpoint
This commit is contained in:
@@ -10,7 +10,7 @@ public class Constants {
|
||||
public static final String CONTAMINUS_EB = "contaminus.eventbus";
|
||||
public static Logger LOGGER = LoggerFactory.getLogger(Constants.APP_NAME);
|
||||
|
||||
/* API Endpoints */
|
||||
/* API Endpoints */
|
||||
public static final String GROUPS = RAW_API_PREFIX + "/groups";
|
||||
public static final String GROUP = RAW_API_PREFIX + "/groups/:groupId";
|
||||
|
||||
@@ -24,17 +24,19 @@ public class Constants {
|
||||
public static final String SENSOR = RAW_API_PREFIX + "/groups/:groupId/devices/:deviceId/sensors/:sensorId";
|
||||
public static final String SENSOR_VALUES = API_PREFIX + "/groups/:groupId/devices/:deviceId/sensors/:sensorId/values";
|
||||
|
||||
public static final String BATCH = API_PREFIX + "/batch";
|
||||
public static final String ADD_GPS_VALUE = RAW_API_PREFIX + "/groups/:groupId/devices/:deviceId/sensors/:sensorId/gps_values";
|
||||
public static final String ADD_WEATHER_VALUE = RAW_API_PREFIX + "/groups/:groupId/devices/:deviceId/sensors/:sensorId/weather_values";
|
||||
public static final String ADD_CO_VALUE = RAW_API_PREFIX + "/groups/:groupId/devices/:deviceId/sensors/:sensorId/co_values";
|
||||
|
||||
public static final String ACTUATORS = RAW_API_PREFIX + "/groups/:groupId/devices/:deviceId/actuators";
|
||||
public static final String ACTUATOR = RAW_API_PREFIX + "/groups/:groupId/devices/:deviceId/actuators/:actuator_id";
|
||||
public static final String ACTUATOR_STATUS = API_PREFIX + "/groups/:groupId/devices/:deviceId/actuators/:actuator_id/status";
|
||||
|
||||
|
||||
public static final String VIEW_LATEST_VALUES = RAW_API_PREFIX + "/v_latest_values";
|
||||
public static final String VIEW_POLLUTION_MAP = RAW_API_PREFIX + "/v_pollution_map";
|
||||
public static final String VIEW_SENSOR_HISTORY = RAW_API_PREFIX + "/v_sensor_history_by_device";
|
||||
public static final String VIEW_SENSOR_VALUES = RAW_API_PREFIX + "/v_sensor_values";
|
||||
public static final String VIEW_CO_BY_DEVICE = RAW_API_PREFIX + "/v_co_by_device";
|
||||
public static final String VIEW_GPS_BY_DEVICE = RAW_API_PREFIX + "/v_gps_by_device";
|
||||
public static final String VIEW_WEATHER_BY_DEVICE = RAW_API_PREFIX + "/v_weather_by_device";
|
||||
|
||||
private Constants() {
|
||||
throw new AssertionError("Utility class cannot be instantiated.");
|
||||
|
||||
@@ -4,136 +4,54 @@ import java.util.Map;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
|
||||
import io.vertx.core.Promise;
|
||||
import io.vertx.core.Future;
|
||||
import io.vertx.core.buffer.Buffer;
|
||||
import io.vertx.core.json.JsonObject;
|
||||
import io.vertx.ext.web.client.HttpRequest;
|
||||
import io.vertx.ext.web.client.WebClient;
|
||||
|
||||
public class RestClientUtil {
|
||||
|
||||
public WebClient client;
|
||||
private Gson gson;
|
||||
|
||||
public RestClientUtil(WebClient client) {
|
||||
gson = new Gson();
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get request utility
|
||||
*
|
||||
* @param <T> Type of result enveloped in JSON response
|
||||
* @param port Port
|
||||
* @param host Host address
|
||||
* @param resource URI where resource is provided
|
||||
* @param classType Type of result enveloped in JSON response
|
||||
* @param promise Promise to be executed on call finish
|
||||
*/
|
||||
public <T> void getRequest(Integer port, String host, String resource, Class<T> classType, Promise<T> promise) {
|
||||
client.getAbs(host + ":" + port + resource).send(elem -> {
|
||||
if (elem.succeeded()) {
|
||||
promise.complete(gson.fromJson(elem.result().bodyAsString(), classType));
|
||||
} else {
|
||||
promise.fail(elem.cause());
|
||||
}
|
||||
});
|
||||
private final WebClient client;
|
||||
private final Gson gson;
|
||||
|
||||
}
|
||||
public RestClientUtil(WebClient client) {
|
||||
this.client = client;
|
||||
this.gson = new Gson();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get request utility
|
||||
*
|
||||
* @param <T> Type of result enveloped in JSON response
|
||||
* @param port Port
|
||||
* @param host Host address
|
||||
* @param resource URI where resource is provided
|
||||
* @param classType Type of result enveloped in JSON response
|
||||
* @param promise Promise to be executed on call finish
|
||||
* @param params Map with key-value entries for call parameters
|
||||
*/
|
||||
public <T> void getRequestWithParams(Integer port, String host, String resource, Class<T> classType,
|
||||
Promise<T> promise, Map<String, String> params) {
|
||||
HttpRequest<Buffer> httpRequest = client.getAbs(host + ":" + port + "/" + resource);
|
||||
public <T> Future<T> getRequest(int port, String host, String resource, Class<T> classType) {
|
||||
return client.getAbs(host + ":" + port + resource)
|
||||
.send()
|
||||
.map(response -> gson.fromJson(response.bodyAsString(), classType));
|
||||
}
|
||||
|
||||
params.forEach((key, value) -> {
|
||||
httpRequest.addQueryParam(key, value);
|
||||
});
|
||||
public <T> Future<T> getRequestWithParams(int port, String host, String resource, Class<T> classType,
|
||||
Map<String, String> params) {
|
||||
HttpRequest<Buffer> httpRequest = client.getAbs(host + ":" + port + "/" + resource);
|
||||
params.forEach(httpRequest::addQueryParam);
|
||||
|
||||
httpRequest.send(elem -> {
|
||||
if (elem.succeeded()) {
|
||||
promise.complete(gson.fromJson(elem.result().bodyAsString(), classType));
|
||||
} else {
|
||||
promise.fail(elem.cause());
|
||||
}
|
||||
});
|
||||
return httpRequest.send()
|
||||
.map(response -> gson.fromJson(response.bodyAsString(), classType));
|
||||
}
|
||||
|
||||
}
|
||||
public <B, T> Future<T> postRequest(int port, String host, String resource, B body, Class<T> classType) {
|
||||
JsonObject jsonBody = new JsonObject(gson.toJson(body));
|
||||
return client.postAbs(host + ":" + port + "/" + resource)
|
||||
.sendJsonObject(jsonBody)
|
||||
.map(response -> gson.fromJson(response.bodyAsString(), classType));
|
||||
}
|
||||
|
||||
/**
|
||||
* Post request utility
|
||||
*
|
||||
* @param <B> Type of body enveloped in JSON request
|
||||
* @param <T> Type of result enveloped in JSON response
|
||||
* @param port Port
|
||||
* @param host Host address
|
||||
* @param resource URI where resource is provided
|
||||
* @param classType Type of result enveloped in JSON response
|
||||
* @param promise Promise to be executed on call finish
|
||||
*/
|
||||
public <B, T> void postRequest(Integer port, String host, String resource, Object body, Class<T> classType,
|
||||
Promise<T> promise) {
|
||||
JsonObject jsonBody = new JsonObject(gson.toJson(body));
|
||||
client.postAbs(host + ":" + port + "/" + resource).sendJsonObject(jsonBody, elem -> {
|
||||
if (elem.succeeded()) {
|
||||
Gson gson = new Gson();
|
||||
promise.complete(gson.fromJson(elem.result().bodyAsString(), classType));
|
||||
} else {
|
||||
promise.fail(elem.cause());
|
||||
}
|
||||
});
|
||||
}
|
||||
public <B, T> Future<T> putRequest(int port, String host, String resource, B body, Class<T> classType) {
|
||||
JsonObject jsonBody = new JsonObject(gson.toJson(body));
|
||||
return client.putAbs(host + ":" + port + "/" + resource)
|
||||
.sendJsonObject(jsonBody)
|
||||
.map(response -> gson.fromJson(response.bodyAsString(), classType));
|
||||
}
|
||||
|
||||
/**
|
||||
* Put request utility
|
||||
*
|
||||
* @param <B> Type of body enveloped in JSON request
|
||||
* @param <T> Type of result enveloped in JSON response
|
||||
* @param port Port
|
||||
* @param host Host address
|
||||
* @param resource URI where resource is provided
|
||||
* @param classType Type of result enveloped in JSON response
|
||||
* @param promise Promise to be executed on call finish
|
||||
*/
|
||||
public <B, T> void putRequest(Integer port, String host, String resource, Object body, Class<T> classType,
|
||||
Promise<T> promise) {
|
||||
JsonObject jsonBody = new JsonObject(gson.toJson(body));
|
||||
client.putAbs(host + ":" + port + "/" + resource).sendJsonObject(jsonBody, elem -> {
|
||||
if (elem.succeeded()) {
|
||||
Gson gson = new Gson();
|
||||
promise.complete(gson.fromJson(elem.result().bodyAsString(), classType));
|
||||
} else {
|
||||
promise.fail(elem.cause());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete request utility
|
||||
*
|
||||
* @param port Port
|
||||
* @param host Host address
|
||||
* @param resource URI where resource is provided
|
||||
* @param promise Promise to be executed on call finish
|
||||
*/
|
||||
public void deleteRequest(Integer port, String host, String resource, Promise<String> promise) {
|
||||
client.deleteAbs(host + ":" + port + "/" + resource).send(elem -> {
|
||||
if (elem.succeeded()) {
|
||||
promise.complete(elem.result().bodyAsString());
|
||||
} else {
|
||||
promise.fail(elem.cause());
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
public Future<String> deleteRequest(int port, String host, String resource) {
|
||||
return client.deleteAbs(host + ":" + port + "/" + resource)
|
||||
.send()
|
||||
.map(response -> response.bodyAsString());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,13 +36,16 @@ import net.miarma.contaminus.db.DatabaseManager;
|
||||
import net.miarma.contaminus.db.DatabaseProvider;
|
||||
import net.miarma.contaminus.db.QueryBuilder;
|
||||
import net.miarma.contaminus.entities.Actuator;
|
||||
import net.miarma.contaminus.entities.COValue;
|
||||
import net.miarma.contaminus.entities.Device;
|
||||
import net.miarma.contaminus.entities.GpsValue;
|
||||
import net.miarma.contaminus.entities.Group;
|
||||
import net.miarma.contaminus.entities.Sensor;
|
||||
import net.miarma.contaminus.entities.ViewLatestValues;
|
||||
import net.miarma.contaminus.entities.ViewPollutionMap;
|
||||
import net.miarma.contaminus.entities.ViewSensorHistory;
|
||||
import net.miarma.contaminus.entities.ViewSensorValue;
|
||||
import net.miarma.contaminus.entities.WeatherValue;
|
||||
|
||||
|
||||
/*
|
||||
@@ -119,6 +122,10 @@ public class DataLayerAPIVerticle extends AbstractVerticle {
|
||||
router.route(HttpMethod.GET, Constants.SENSOR).handler(this::getSensorById);
|
||||
router.route(HttpMethod.POST, Constants.SENSORS).handler(this::addSensor);
|
||||
router.route(HttpMethod.PUT, Constants.SENSOR).handler(this::updateSensor);
|
||||
router.route(HttpMethod.POST, Constants.ADD_GPS_VALUE).handler(this::addGpsValue);
|
||||
router.route(HttpMethod.POST, Constants.ADD_WEATHER_VALUE).handler(this::addWeatherValue);
|
||||
router.route(HttpMethod.POST, Constants.ADD_CO_VALUE).handler(this::addCoValue);
|
||||
|
||||
|
||||
// Actuator Routes
|
||||
router.route(HttpMethod.GET, Constants.ACTUATORS).handler(this::getAllActuators);
|
||||
@@ -185,7 +192,7 @@ public class DataLayerAPIVerticle extends AbstractVerticle {
|
||||
.onSuccess(result -> {
|
||||
context.response()
|
||||
.putHeader("content-type", "application/json; charset=utf-8")
|
||||
.end(gson.toJson(SingleJsonResponse.of("Group added successfully")));
|
||||
.end(gson.toJson(result, Group.class));
|
||||
})
|
||||
.onFailure(err -> {
|
||||
context.fail(500, err);
|
||||
@@ -200,7 +207,7 @@ public class DataLayerAPIVerticle extends AbstractVerticle {
|
||||
.onSuccess(result -> {
|
||||
context.response()
|
||||
.putHeader("content-type", "application/json; charset=utf-8")
|
||||
.end(gson.toJson(SingleJsonResponse.of("Group updated successfully")));
|
||||
.end(gson.toJson(result, Group.class));
|
||||
})
|
||||
.onFailure(err -> {
|
||||
context.fail(500, err);
|
||||
@@ -248,7 +255,7 @@ public class DataLayerAPIVerticle extends AbstractVerticle {
|
||||
.onSuccess(result -> {
|
||||
context.response()
|
||||
.putHeader("content-type", "application/json; charset=utf-8")
|
||||
.end(gson.toJson(SingleJsonResponse.of("Device added successfully")));
|
||||
.end(gson.toJson(result, Device.class));
|
||||
})
|
||||
.onFailure(err -> {
|
||||
context.fail(500, err);
|
||||
@@ -263,7 +270,7 @@ public class DataLayerAPIVerticle extends AbstractVerticle {
|
||||
.onSuccess(result -> {
|
||||
context.response()
|
||||
.putHeader("content-type", "application/json; charset=utf-8")
|
||||
.end(gson.toJson(SingleJsonResponse.of("Device updated successfully")));
|
||||
.end(gson.toJson(result, Device.class));
|
||||
})
|
||||
.onFailure(err -> {
|
||||
context.fail(500, err);
|
||||
@@ -319,7 +326,7 @@ public class DataLayerAPIVerticle extends AbstractVerticle {
|
||||
.onSuccess(result -> {
|
||||
context.response()
|
||||
.putHeader("content-type", "application/json; charset=utf-8")
|
||||
.end(gson.toJson(SingleJsonResponse.of("Sensor added successfully")));
|
||||
.end(gson.toJson(result, Sensor.class));
|
||||
})
|
||||
.onFailure(err -> {
|
||||
context.fail(500, err);
|
||||
@@ -334,13 +341,61 @@ public class DataLayerAPIVerticle extends AbstractVerticle {
|
||||
.onSuccess(result -> {
|
||||
context.response()
|
||||
.putHeader("content-type", "application/json; charset=utf-8")
|
||||
.end(gson.toJson(SingleJsonResponse.of("Sensor updated successfully")));
|
||||
.end(gson.toJson(result, Sensor.class));
|
||||
})
|
||||
.onFailure(err -> {
|
||||
context.fail(500, err);
|
||||
});
|
||||
}
|
||||
|
||||
private void addGpsValue(RoutingContext context) {
|
||||
JsonObject body = context.body().asJsonObject();
|
||||
GpsValue gpsValue = gson.fromJson(body.toString(), GpsValue.class);
|
||||
|
||||
gpsValueDAO.insert(gpsValue)
|
||||
.onSuccess(result -> {
|
||||
context.response()
|
||||
.setStatusCode(201)
|
||||
.putHeader("Content-Type", "application/json")
|
||||
.end(gson.toJson(result, GpsValue.class));
|
||||
})
|
||||
.onFailure(err -> {
|
||||
context.fail(500, err);
|
||||
});
|
||||
}
|
||||
|
||||
private void addWeatherValue(RoutingContext context) {
|
||||
JsonObject body = context.body().asJsonObject();
|
||||
WeatherValue weatherValue = gson.fromJson(body.toString(), WeatherValue.class);
|
||||
|
||||
weatherValueDAO.insert(weatherValue)
|
||||
.onSuccess(result -> {
|
||||
context.response()
|
||||
.setStatusCode(201)
|
||||
.putHeader("Content-Type", "application/json")
|
||||
.end(gson.toJson(result, WeatherValue.class));
|
||||
})
|
||||
.onFailure(err -> {
|
||||
context.fail(500, err);
|
||||
});
|
||||
}
|
||||
|
||||
private void addCoValue(RoutingContext context) {
|
||||
JsonObject body = context.body().asJsonObject();
|
||||
COValue coValue = gson.fromJson(body.toString(), COValue.class);
|
||||
|
||||
coValueDAO.insert(coValue)
|
||||
.onSuccess(result -> {
|
||||
context.response()
|
||||
.setStatusCode(201)
|
||||
.putHeader("Content-Type", "application/json")
|
||||
.end(gson.toJson(result, COValue.class));
|
||||
})
|
||||
.onFailure(err -> {
|
||||
context.fail(500, err);
|
||||
});
|
||||
}
|
||||
|
||||
private void getAllActuators(RoutingContext context) {
|
||||
Integer groupId = Integer.parseInt(context.request().getParam("groupId"));
|
||||
String deviceId = context.request().getParam("deviceId");
|
||||
@@ -390,7 +445,7 @@ public class DataLayerAPIVerticle extends AbstractVerticle {
|
||||
.onSuccess(result -> {
|
||||
context.response()
|
||||
.putHeader("content-type", "application/json; charset=utf-8")
|
||||
.end(gson.toJson(SingleJsonResponse.of("Actuator added successfully")));
|
||||
.end(gson.toJson(result, Actuator.class));
|
||||
})
|
||||
.onFailure(err -> {
|
||||
context.fail(500, err);
|
||||
@@ -405,7 +460,7 @@ public class DataLayerAPIVerticle extends AbstractVerticle {
|
||||
.onSuccess(result -> {
|
||||
context.response()
|
||||
.putHeader("content-type", "application/json; charset=utf-8")
|
||||
.end(gson.toJson(SingleJsonResponse.of("Actuator updated successfully")));
|
||||
.end(gson.toJson(result, Actuator.class));
|
||||
})
|
||||
.onFailure(err -> {
|
||||
context.fail(500, err);
|
||||
|
||||
@@ -4,7 +4,6 @@ import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
@@ -13,6 +12,7 @@ import io.vertx.core.AbstractVerticle;
|
||||
import io.vertx.core.Promise;
|
||||
import io.vertx.core.Vertx;
|
||||
import io.vertx.core.http.HttpMethod;
|
||||
import io.vertx.core.json.JsonObject;
|
||||
import io.vertx.ext.web.Router;
|
||||
import io.vertx.ext.web.RoutingContext;
|
||||
import io.vertx.ext.web.client.WebClient;
|
||||
@@ -21,10 +21,13 @@ import io.vertx.ext.web.handler.BodyHandler;
|
||||
import io.vertx.ext.web.handler.CorsHandler;
|
||||
import net.miarma.contaminus.common.ConfigManager;
|
||||
import net.miarma.contaminus.common.Constants;
|
||||
import net.miarma.contaminus.entities.COValue;
|
||||
import net.miarma.contaminus.entities.GpsValue;
|
||||
import net.miarma.contaminus.entities.ViewLatestValues;
|
||||
import net.miarma.contaminus.entities.ViewPollutionMap;
|
||||
import net.miarma.contaminus.entities.ViewSensorHistory;
|
||||
import net.miarma.contaminus.entities.ViewSensorValue;
|
||||
import net.miarma.contaminus.entities.WeatherValue;
|
||||
import net.miarma.contaminus.util.RestClientUtil;
|
||||
|
||||
public class LogicLayerAPIVerticle extends AbstractVerticle {
|
||||
@@ -55,6 +58,7 @@ public class LogicLayerAPIVerticle extends AbstractVerticle {
|
||||
|
||||
router.route().handler(BodyHandler.create());
|
||||
|
||||
router.route(HttpMethod.POST, Constants.BATCH).handler(this::addBatch);
|
||||
router.route(HttpMethod.GET, Constants.LATEST_VALUES).handler(this::getDeviceLatestValues);
|
||||
router.route(HttpMethod.GET, Constants.POLLUTION_MAP).handler(this::getDevicePollutionMap);
|
||||
router.route(HttpMethod.GET, Constants.HISTORY).handler(this::getDeviceHistory);
|
||||
@@ -68,93 +72,100 @@ public class LogicLayerAPIVerticle extends AbstractVerticle {
|
||||
}
|
||||
|
||||
private void getDeviceLatestValues(RoutingContext context) {
|
||||
String deviceId = context.request().getParam("deviceId");
|
||||
|
||||
Promise<ViewLatestValues[]> resultList = Promise.promise();
|
||||
resultList.future().onComplete(complete -> {
|
||||
if (complete.succeeded()) {
|
||||
List<ViewLatestValues> aux = Stream.of(complete.result())
|
||||
.filter(elem -> deviceId.equals(elem.getDeviceId()))
|
||||
.toList();
|
||||
|
||||
context.response()
|
||||
.putHeader("content-type", "application/json; charset=utf-8")
|
||||
.end(gson.toJson(aux));
|
||||
} else {
|
||||
context.fail(500, complete.cause());
|
||||
}
|
||||
});
|
||||
|
||||
this.restClient.getRequest(configManager.getDataApiPort(), "http://" + configManager.getHost(),
|
||||
Constants.VIEW_LATEST_VALUES, ViewLatestValues[].class, resultList);
|
||||
String deviceId = context.request().getParam("deviceId");
|
||||
restClient.getRequest(configManager.getDataApiPort(), "http://" + configManager.getHost(),
|
||||
Constants.VIEW_LATEST_VALUES, ViewLatestValues[].class)
|
||||
.onSuccess(result -> {
|
||||
List<ViewLatestValues> aux = Arrays.stream(result)
|
||||
.filter(elem -> deviceId.equals(elem.getDeviceId()))
|
||||
.toList();
|
||||
context.response().putHeader("content-type", "application/json; charset=utf-8").end(gson.toJson(aux));
|
||||
})
|
||||
.onFailure(err -> context.fail(500, err));
|
||||
}
|
||||
|
||||
|
||||
private void getDevicePollutionMap(RoutingContext context) {
|
||||
String deviceId = context.request().getParam("deviceId");
|
||||
|
||||
Promise<ViewPollutionMap[]> resultList = Promise.promise();
|
||||
|
||||
resultList.future().onComplete(complete -> {
|
||||
if (complete.succeeded()) {
|
||||
List<ViewPollutionMap> aux = Arrays.asList(complete.result()).stream()
|
||||
.filter(elem -> deviceId.equals(elem.getDeviceId()))
|
||||
.toList();
|
||||
|
||||
context.response()
|
||||
.putHeader("content-type", "application/json; charset=utf-8")
|
||||
.end(gson.toJson(aux));
|
||||
} else {
|
||||
context.fail(500, complete.cause());
|
||||
}
|
||||
});
|
||||
|
||||
this.restClient.getRequest(configManager.getDataApiPort(), "http://" + configManager.getHost(),
|
||||
Constants.VIEW_POLLUTION_MAP, ViewPollutionMap[].class, resultList);
|
||||
}
|
||||
|
||||
String deviceId = context.request().getParam("deviceId");
|
||||
restClient.getRequest(configManager.getDataApiPort(), "http://" + configManager.getHost(),
|
||||
Constants.VIEW_POLLUTION_MAP, ViewPollutionMap[].class)
|
||||
.onSuccess(result -> {
|
||||
List<ViewPollutionMap> aux = Arrays.asList(result).stream()
|
||||
.filter(elem -> deviceId.equals(elem.getDeviceId()))
|
||||
.toList();
|
||||
context.response().putHeader("content-type", "application/json; charset=utf-8").end(gson.toJson(aux));
|
||||
})
|
||||
.onFailure(err -> context.fail(500, err));
|
||||
}
|
||||
|
||||
private void getDeviceHistory(RoutingContext context) {
|
||||
String deviceId = context.request().getParam("deviceId");
|
||||
|
||||
Promise<ViewSensorHistory[]> resultList = Promise.promise();
|
||||
|
||||
resultList.future().onComplete(complete -> {
|
||||
if (complete.succeeded()) {
|
||||
List<ViewSensorHistory> aux = Arrays.asList(complete.result()).stream()
|
||||
.filter(elem -> deviceId.equals(elem.getDeviceId()))
|
||||
.toList();
|
||||
|
||||
context.response()
|
||||
.putHeader("content-type", "application/json; charset=utf-8")
|
||||
.end(gson.toJson(aux));
|
||||
} else {
|
||||
context.fail(500, complete.cause());
|
||||
}
|
||||
});
|
||||
|
||||
this.restClient.getRequest(configManager.getDataApiPort(), "http://" + configManager.getHost(),
|
||||
Constants.VIEW_SENSOR_HISTORY, ViewSensorHistory[].class, resultList);
|
||||
String deviceId = context.request().getParam("deviceId");
|
||||
restClient.getRequest(configManager.getDataApiPort(), "http://" + configManager.getHost(),
|
||||
Constants.VIEW_SENSOR_HISTORY, ViewSensorHistory[].class)
|
||||
.onSuccess(result -> {
|
||||
List<ViewSensorHistory> aux = Arrays.asList(result).stream()
|
||||
.filter(elem -> deviceId.equals(elem.getDeviceId()))
|
||||
.toList();
|
||||
context.response().putHeader("content-type", "application/json; charset=utf-8").end(gson.toJson(aux));
|
||||
})
|
||||
.onFailure(err -> context.fail(500, err));
|
||||
}
|
||||
|
||||
private void getSensorValues(RoutingContext context) {
|
||||
int sensorId = Integer.parseInt(context.request().getParam("sensorId"));
|
||||
restClient.getRequest(configManager.getDataApiPort(), "http://" + configManager.getHost(),
|
||||
Constants.VIEW_SENSOR_VALUES, ViewSensorValue[].class)
|
||||
.onSuccess(result -> {
|
||||
List<ViewSensorValue> aux = Arrays.asList(result).stream()
|
||||
.filter(val -> val.getSensorId() == sensorId)
|
||||
.toList();
|
||||
context.response().putHeader("content-type", "application/json; charset=utf-8").end(gson.toJson(aux));
|
||||
})
|
||||
.onFailure(err -> context.fail(500, err));
|
||||
}
|
||||
|
||||
private void getSensorValues(RoutingContext context) {
|
||||
Integer sensorId = Integer.parseInt(context.request().getParam("sensorId"));
|
||||
|
||||
Promise<ViewSensorValue[]> resultList = Promise.promise();
|
||||
|
||||
resultList.future().onComplete(complete -> {
|
||||
if (complete.succeeded()) {
|
||||
List<ViewSensorValue> aux = Arrays.asList(complete.result()).stream()
|
||||
.filter(val -> val.getSensorId() == sensorId)
|
||||
.toList();
|
||||
|
||||
private void addBatch(RoutingContext context) {
|
||||
JsonObject body = context.body().asJsonObject();
|
||||
if (body == null) {
|
||||
context.response().setStatusCode(400).end("Missing JSON body");
|
||||
return;
|
||||
}
|
||||
|
||||
String groupId = body.getString("groupId");
|
||||
String deviceId = body.getString("deviceId");
|
||||
|
||||
JsonObject gps = body.getJsonObject("gps");
|
||||
JsonObject weather = body.getJsonObject("weather");
|
||||
JsonObject co = body.getJsonObject("co");
|
||||
|
||||
if (deviceId == null || gps == null || weather == null || co == null) {
|
||||
context.response().setStatusCode(400).end("Missing required fields");
|
||||
return;
|
||||
}
|
||||
|
||||
GpsValue gpsValue = gson.fromJson(gps.toString(), GpsValue.class);
|
||||
WeatherValue weatherValue = gson.fromJson(weather.toString(), WeatherValue.class);
|
||||
COValue coValue = gson.fromJson(co.toString(), COValue.class);
|
||||
|
||||
gpsValue.setDeviceId(deviceId);
|
||||
weatherValue.setDeviceId(deviceId);
|
||||
coValue.setDeviceId(deviceId);
|
||||
|
||||
String host = "http://" + configManager.getHost();
|
||||
int port = configManager.getDataApiPort();
|
||||
|
||||
String gpsPath = Constants.ADD_GPS_VALUE.replace(":groupId", groupId).replace(":deviceId", deviceId);
|
||||
String weatherPath = Constants.ADD_WEATHER_VALUE.replace(":groupId", groupId).replace(":deviceId", deviceId);
|
||||
String coPath = Constants.ADD_CO_VALUE.replace(":groupId", groupId).replace(":deviceId", deviceId);
|
||||
|
||||
restClient.postRequest(port, host, gpsPath, gpsValue, GpsValue.class)
|
||||
.compose(_ -> restClient.postRequest(port, host, weatherPath, weatherValue, WeatherValue.class))
|
||||
.compose(_ -> restClient.postRequest(port, host, coPath, coValue, COValue.class))
|
||||
.onSuccess(_ -> {
|
||||
context.response()
|
||||
.putHeader("content-type", "application/json; charset=utf-8")
|
||||
.end(gson.toJson(aux));
|
||||
} else {
|
||||
context.fail(500, complete.cause());
|
||||
}
|
||||
});
|
||||
|
||||
this.restClient.getRequest(configManager.getDataApiPort(), "http://" + configManager.getHost(),
|
||||
Constants.VIEW_SENSOR_VALUES, ViewSensorValue[].class, resultList);
|
||||
}
|
||||
.setStatusCode(201)
|
||||
.putHeader("Content-Type", "application/json")
|
||||
.end(new JsonObject().put("status", "success").put("inserted", 3).encode());
|
||||
})
|
||||
.onFailure(err -> context.fail(500, err));
|
||||
}
|
||||
}
|
||||
@@ -7,15 +7,14 @@
|
||||
#include "GPS.hpp"
|
||||
|
||||
String serializeSensorValue(
|
||||
int sensorId,
|
||||
int groupId,
|
||||
const String &deviceId,
|
||||
const String &sensorType,
|
||||
const String &unit,
|
||||
int sensorStatus,
|
||||
int gpsSensorId,
|
||||
int weatherSensorId,
|
||||
int coSensorId,
|
||||
const BME280Data_t &bme,
|
||||
const MQ7Data_t &mq7,
|
||||
const GPSData_t &gps,
|
||||
long timestamp);
|
||||
const GPSData_t &gps);
|
||||
|
||||
String serializeActuatorStatus(
|
||||
int actuatorId,
|
||||
|
||||
@@ -2,5 +2,5 @@
|
||||
|
||||
#include <HTTPClient.h>
|
||||
|
||||
void getRequest(HTTPClient &httpClient, const String url, String &response);
|
||||
void postRequest(HTTPClient &httpClient, const String url, const String &payload, String &response);
|
||||
void getRequest(const String url, String &response);
|
||||
void postRequest(const String url, const String &payload, String &response);
|
||||
@@ -4,6 +4,8 @@
|
||||
#define REST_PORT 443
|
||||
#define MQTT_PORT 1883
|
||||
|
||||
#define GROUP_ID 1
|
||||
|
||||
#define MQ7_ID 1
|
||||
#define BME280_ID 2
|
||||
#define GPS_ID 3
|
||||
@@ -48,4 +50,5 @@ void readBME280();
|
||||
void readGPS();
|
||||
void writeMatrix(const char *message);
|
||||
void printAllData();
|
||||
void sendSensorData();
|
||||
uint32_t getChipID();
|
||||
@@ -1,30 +1,34 @@
|
||||
#include "JsonTools.hpp"
|
||||
|
||||
String serializeSensorValue(
|
||||
int sensorId,
|
||||
int groupId,
|
||||
const String &deviceId,
|
||||
const String &sensorType,
|
||||
const String &unit,
|
||||
int sensorStatus,
|
||||
int gpsSensorId,
|
||||
int weatherSensorId,
|
||||
int coSensorId,
|
||||
const BME280Data_t &bme,
|
||||
const MQ7Data_t &mq7,
|
||||
const GPSData_t &gps,
|
||||
long timestamp)
|
||||
const GPSData_t &gps)
|
||||
{
|
||||
DynamicJsonDocument doc(1024);
|
||||
|
||||
doc["sensorId"] = sensorId;
|
||||
doc["groupId"] = groupId;
|
||||
doc["deviceId"] = deviceId;
|
||||
doc["sensorType"] = sensorType;
|
||||
doc["unit"] = unit;
|
||||
doc["sensorStatus"] = sensorStatus;
|
||||
doc["temperature"] = bme.temperature;
|
||||
doc["humidity"] = bme.humidity;
|
||||
doc["pressure"] = bme.pressure;
|
||||
doc["carbonMonoxide"] = mq7.co;
|
||||
doc["lat"] = gps.lat;
|
||||
doc["lon"] = gps.lon;
|
||||
doc["timestamp"] = timestamp;
|
||||
|
||||
JsonObject gpsObj = doc.createNestedObject("gps");
|
||||
gpsObj["sensorId"] = gpsSensorId;
|
||||
gpsObj["lat"] = gps.lat;
|
||||
gpsObj["lon"] = gps.lon;
|
||||
|
||||
JsonObject weather = doc.createNestedObject("weather");
|
||||
weather["sensorId"] = weatherSensorId;
|
||||
weather["temperature"] = bme.temperature;
|
||||
weather["humidity"] = bme.humidity;
|
||||
weather["pressure"] = bme.pressure;
|
||||
|
||||
JsonObject co = doc.createNestedObject("co");
|
||||
co["sensorId"] = coSensorId;
|
||||
co["value"] = mq7.co;
|
||||
|
||||
String output;
|
||||
serializeJson(doc, output);
|
||||
@@ -68,6 +72,7 @@ void deserializeSensorValue(HTTPClient &http, int httpResponseCode)
|
||||
Serial.print("HTTP Response code: ");
|
||||
Serial.println(httpResponseCode);
|
||||
String responseJson = http.getString();
|
||||
|
||||
DynamicJsonDocument doc(ESP.getMaxAllocHeap());
|
||||
DeserializationError error = deserializeJson(doc, responseJson);
|
||||
|
||||
@@ -78,26 +83,35 @@ void deserializeSensorValue(HTTPClient &http, int httpResponseCode)
|
||||
return;
|
||||
}
|
||||
|
||||
JsonArray array = doc.as<JsonArray>();
|
||||
for (JsonObject sensor : array)
|
||||
{
|
||||
int sensorId = sensor["sensorId"];
|
||||
String deviceId = sensor["deviceId"];
|
||||
String sensorType = sensor["sensorType"];
|
||||
String unit = sensor["unit"];
|
||||
int sensorStatus = sensor["sensorStatus"];
|
||||
float temperature = sensor["temperature"];
|
||||
float humidity = sensor["humidity"];
|
||||
float carbonMonoxide = sensor["carbonMonoxide"];
|
||||
float lat = sensor["lat"];
|
||||
float lon = sensor["lon"];
|
||||
long timestamp = sensor["timestamp"];
|
||||
String groupId = doc["groupId"];
|
||||
String deviceId = doc["deviceId"];
|
||||
|
||||
Serial.println("Sensor deserialized:");
|
||||
Serial.printf(" ID: %d\n Device: %s\n Type: %s\n Unit: %s\n Status: %d\n Temp: %.2f\n Hum: %.2f\n CO: %.2f\n Lat: %.6f\n Lon: %.6f\n Time: %ld\n\n",
|
||||
sensorId, deviceId.c_str(), sensorType.c_str(), unit.c_str(), sensorStatus,
|
||||
temperature, humidity, carbonMonoxide, lat, lon, timestamp);
|
||||
}
|
||||
JsonObject gps = doc["gps"];
|
||||
int gpsId = gps["sensorId"];
|
||||
float lat = gps["lat"];
|
||||
float lon = gps["lon"];
|
||||
|
||||
JsonObject weather = doc["weather"];
|
||||
int weatherId = weather["sensorId"];
|
||||
float temp = weather["temperature"];
|
||||
float hum = weather["humidity"];
|
||||
float pres = weather["pressure"];
|
||||
|
||||
JsonObject co = doc["co"];
|
||||
int coId = co["sensorId"];
|
||||
float coVal = co["value"];
|
||||
|
||||
Serial.println("🛰 GPS:");
|
||||
Serial.printf(" Sensor ID: %d\n Lat: %.6f Lon: %.6f\n", gpsId, lat, lon);
|
||||
|
||||
Serial.println("🌤 Weather:");
|
||||
Serial.printf(" Sensor ID: %d\n Temp: %.2f°C Hum: %.2f%% Pressure: %.2f hPa\n", weatherId, temp, hum, pres);
|
||||
|
||||
Serial.println("🧪 CO:");
|
||||
Serial.printf(" Sensor ID: %d\n CO: %.2f ppm\n", coId, coVal);
|
||||
|
||||
Serial.printf("🧾 Group ID: %s\n", groupId.c_str());
|
||||
Serial.printf("🧾 Device ID: %s\n", deviceId.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -17,7 +17,7 @@ void getRequest(const String url, String &response)
|
||||
httpClient.end();
|
||||
}
|
||||
|
||||
void postRequest(const String url, String &payload, String &response)
|
||||
void postRequest(const String url, const String &payload, String &response)
|
||||
{
|
||||
httpClient.begin(url);
|
||||
httpClient.addHeader("Content-Type", "application/json");
|
||||
|
||||
@@ -9,6 +9,7 @@ TaskTimer matrixTimer{0, 25};
|
||||
TaskTimer globalTimer{0, 60000};
|
||||
|
||||
extern HTTPClient httpClient;
|
||||
String response;
|
||||
extern MD_Parola display;
|
||||
|
||||
MQ7Data_t mq7Data;
|
||||
@@ -59,6 +60,8 @@ void loop()
|
||||
printAllData();
|
||||
#endif
|
||||
|
||||
sendSensorData();
|
||||
|
||||
globalTimer.lastRun = now;
|
||||
}
|
||||
}
|
||||
@@ -136,6 +139,41 @@ void printAllData()
|
||||
Serial.println(mq7Data.threshold);
|
||||
}
|
||||
|
||||
void sendSensorData()
|
||||
{
|
||||
const String deviceId = String(DEVICE_ID, HEX);
|
||||
|
||||
// Validaciones básicas (puedes añadir más si quieres)
|
||||
bool gpsValid = gpsData.lat != 0.0f && gpsData.lon != 0.0f;
|
||||
bool weatherValid = bme280Data.temperature != 0.0f &&
|
||||
bme280Data.humidity != 0.0f &&
|
||||
bme280Data.pressure != 0.0f;
|
||||
bool coValid = mq7Data.co >= 0.0f;
|
||||
|
||||
if (!gpsValid || !weatherValid || !coValid)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
Serial.println("❌ Datos inválidos. No se envía el batch.");
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
String json = serializeSensorValue(GROUP_ID, deviceId,
|
||||
GPS_ID, BME280_ID, MQ7_ID,
|
||||
bme280Data, mq7Data, gpsData);
|
||||
|
||||
#ifdef DEBUG
|
||||
Serial.println("📤 Enviando datos al servidor...");
|
||||
#endif
|
||||
|
||||
postRequest(String(SERVER_IP) + "/batch", json, response);
|
||||
|
||||
#ifdef DEBUG
|
||||
Serial.println("📬 Respuesta del servidor:");
|
||||
Serial.println(response);
|
||||
#endif
|
||||
}
|
||||
|
||||
uint32_t getChipID()
|
||||
{
|
||||
uint32_t chipId = 0;
|
||||
|
||||
Reference in New Issue
Block a user