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 final String CONTAMINUS_EB = "contaminus.eventbus";
|
||||||
public static Logger LOGGER = LoggerFactory.getLogger(Constants.APP_NAME);
|
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 GROUPS = RAW_API_PREFIX + "/groups";
|
||||||
public static final String GROUP = RAW_API_PREFIX + "/groups/:groupId";
|
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 = 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 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 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 = 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 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_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_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_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_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() {
|
private Constants() {
|
||||||
throw new AssertionError("Utility class cannot be instantiated.");
|
throw new AssertionError("Utility class cannot be instantiated.");
|
||||||
|
|||||||
@@ -4,136 +4,54 @@ import java.util.Map;
|
|||||||
|
|
||||||
import com.google.gson.Gson;
|
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.buffer.Buffer;
|
||||||
import io.vertx.core.json.JsonObject;
|
import io.vertx.core.json.JsonObject;
|
||||||
import io.vertx.ext.web.client.HttpRequest;
|
import io.vertx.ext.web.client.HttpRequest;
|
||||||
import io.vertx.ext.web.client.WebClient;
|
import io.vertx.ext.web.client.WebClient;
|
||||||
|
|
||||||
public class RestClientUtil {
|
public class RestClientUtil {
|
||||||
|
|
||||||
public WebClient client;
|
|
||||||
private Gson gson;
|
|
||||||
|
|
||||||
public RestClientUtil(WebClient client) {
|
|
||||||
gson = new Gson();
|
|
||||||
this.client = client;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
private final WebClient client;
|
||||||
* Get request utility
|
private final Gson gson;
|
||||||
*
|
|
||||||
* @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());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
public RestClientUtil(WebClient client) {
|
||||||
|
this.client = client;
|
||||||
|
this.gson = new Gson();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
public <T> Future<T> getRequest(int port, String host, String resource, Class<T> classType) {
|
||||||
* Get request utility
|
return client.getAbs(host + ":" + port + resource)
|
||||||
*
|
.send()
|
||||||
* @param <T> Type of result enveloped in JSON response
|
.map(response -> gson.fromJson(response.bodyAsString(), classType));
|
||||||
* @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);
|
|
||||||
|
|
||||||
params.forEach((key, value) -> {
|
public <T> Future<T> getRequestWithParams(int port, String host, String resource, Class<T> classType,
|
||||||
httpRequest.addQueryParam(key, value);
|
Map<String, String> params) {
|
||||||
});
|
HttpRequest<Buffer> httpRequest = client.getAbs(host + ":" + port + "/" + resource);
|
||||||
|
params.forEach(httpRequest::addQueryParam);
|
||||||
|
|
||||||
httpRequest.send(elem -> {
|
return httpRequest.send()
|
||||||
if (elem.succeeded()) {
|
.map(response -> gson.fromJson(response.bodyAsString(), classType));
|
||||||
promise.complete(gson.fromJson(elem.result().bodyAsString(), classType));
|
}
|
||||||
} else {
|
|
||||||
promise.fail(elem.cause());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
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));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
public <B, T> Future<T> putRequest(int port, String host, String resource, B body, Class<T> classType) {
|
||||||
* Post request utility
|
JsonObject jsonBody = new JsonObject(gson.toJson(body));
|
||||||
*
|
return client.putAbs(host + ":" + port + "/" + resource)
|
||||||
* @param <B> Type of body enveloped in JSON request
|
.sendJsonObject(jsonBody)
|
||||||
* @param <T> Type of result enveloped in JSON response
|
.map(response -> gson.fromJson(response.bodyAsString(), classType));
|
||||||
* @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 Future<String> deleteRequest(int port, String host, String resource) {
|
||||||
* Put request utility
|
return client.deleteAbs(host + ":" + port + "/" + resource)
|
||||||
*
|
.send()
|
||||||
* @param <B> Type of body enveloped in JSON request
|
.map(response -> response.bodyAsString());
|
||||||
* @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());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,13 +36,16 @@ import net.miarma.contaminus.db.DatabaseManager;
|
|||||||
import net.miarma.contaminus.db.DatabaseProvider;
|
import net.miarma.contaminus.db.DatabaseProvider;
|
||||||
import net.miarma.contaminus.db.QueryBuilder;
|
import net.miarma.contaminus.db.QueryBuilder;
|
||||||
import net.miarma.contaminus.entities.Actuator;
|
import net.miarma.contaminus.entities.Actuator;
|
||||||
|
import net.miarma.contaminus.entities.COValue;
|
||||||
import net.miarma.contaminus.entities.Device;
|
import net.miarma.contaminus.entities.Device;
|
||||||
|
import net.miarma.contaminus.entities.GpsValue;
|
||||||
import net.miarma.contaminus.entities.Group;
|
import net.miarma.contaminus.entities.Group;
|
||||||
import net.miarma.contaminus.entities.Sensor;
|
import net.miarma.contaminus.entities.Sensor;
|
||||||
import net.miarma.contaminus.entities.ViewLatestValues;
|
import net.miarma.contaminus.entities.ViewLatestValues;
|
||||||
import net.miarma.contaminus.entities.ViewPollutionMap;
|
import net.miarma.contaminus.entities.ViewPollutionMap;
|
||||||
import net.miarma.contaminus.entities.ViewSensorHistory;
|
import net.miarma.contaminus.entities.ViewSensorHistory;
|
||||||
import net.miarma.contaminus.entities.ViewSensorValue;
|
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.GET, Constants.SENSOR).handler(this::getSensorById);
|
||||||
router.route(HttpMethod.POST, Constants.SENSORS).handler(this::addSensor);
|
router.route(HttpMethod.POST, Constants.SENSORS).handler(this::addSensor);
|
||||||
router.route(HttpMethod.PUT, Constants.SENSOR).handler(this::updateSensor);
|
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
|
// Actuator Routes
|
||||||
router.route(HttpMethod.GET, Constants.ACTUATORS).handler(this::getAllActuators);
|
router.route(HttpMethod.GET, Constants.ACTUATORS).handler(this::getAllActuators);
|
||||||
@@ -185,7 +192,7 @@ public class DataLayerAPIVerticle extends AbstractVerticle {
|
|||||||
.onSuccess(result -> {
|
.onSuccess(result -> {
|
||||||
context.response()
|
context.response()
|
||||||
.putHeader("content-type", "application/json; charset=utf-8")
|
.putHeader("content-type", "application/json; charset=utf-8")
|
||||||
.end(gson.toJson(SingleJsonResponse.of("Group added successfully")));
|
.end(gson.toJson(result, Group.class));
|
||||||
})
|
})
|
||||||
.onFailure(err -> {
|
.onFailure(err -> {
|
||||||
context.fail(500, err);
|
context.fail(500, err);
|
||||||
@@ -200,7 +207,7 @@ public class DataLayerAPIVerticle extends AbstractVerticle {
|
|||||||
.onSuccess(result -> {
|
.onSuccess(result -> {
|
||||||
context.response()
|
context.response()
|
||||||
.putHeader("content-type", "application/json; charset=utf-8")
|
.putHeader("content-type", "application/json; charset=utf-8")
|
||||||
.end(gson.toJson(SingleJsonResponse.of("Group updated successfully")));
|
.end(gson.toJson(result, Group.class));
|
||||||
})
|
})
|
||||||
.onFailure(err -> {
|
.onFailure(err -> {
|
||||||
context.fail(500, err);
|
context.fail(500, err);
|
||||||
@@ -248,7 +255,7 @@ public class DataLayerAPIVerticle extends AbstractVerticle {
|
|||||||
.onSuccess(result -> {
|
.onSuccess(result -> {
|
||||||
context.response()
|
context.response()
|
||||||
.putHeader("content-type", "application/json; charset=utf-8")
|
.putHeader("content-type", "application/json; charset=utf-8")
|
||||||
.end(gson.toJson(SingleJsonResponse.of("Device added successfully")));
|
.end(gson.toJson(result, Device.class));
|
||||||
})
|
})
|
||||||
.onFailure(err -> {
|
.onFailure(err -> {
|
||||||
context.fail(500, err);
|
context.fail(500, err);
|
||||||
@@ -263,7 +270,7 @@ public class DataLayerAPIVerticle extends AbstractVerticle {
|
|||||||
.onSuccess(result -> {
|
.onSuccess(result -> {
|
||||||
context.response()
|
context.response()
|
||||||
.putHeader("content-type", "application/json; charset=utf-8")
|
.putHeader("content-type", "application/json; charset=utf-8")
|
||||||
.end(gson.toJson(SingleJsonResponse.of("Device updated successfully")));
|
.end(gson.toJson(result, Device.class));
|
||||||
})
|
})
|
||||||
.onFailure(err -> {
|
.onFailure(err -> {
|
||||||
context.fail(500, err);
|
context.fail(500, err);
|
||||||
@@ -319,7 +326,7 @@ public class DataLayerAPIVerticle extends AbstractVerticle {
|
|||||||
.onSuccess(result -> {
|
.onSuccess(result -> {
|
||||||
context.response()
|
context.response()
|
||||||
.putHeader("content-type", "application/json; charset=utf-8")
|
.putHeader("content-type", "application/json; charset=utf-8")
|
||||||
.end(gson.toJson(SingleJsonResponse.of("Sensor added successfully")));
|
.end(gson.toJson(result, Sensor.class));
|
||||||
})
|
})
|
||||||
.onFailure(err -> {
|
.onFailure(err -> {
|
||||||
context.fail(500, err);
|
context.fail(500, err);
|
||||||
@@ -334,13 +341,61 @@ public class DataLayerAPIVerticle extends AbstractVerticle {
|
|||||||
.onSuccess(result -> {
|
.onSuccess(result -> {
|
||||||
context.response()
|
context.response()
|
||||||
.putHeader("content-type", "application/json; charset=utf-8")
|
.putHeader("content-type", "application/json; charset=utf-8")
|
||||||
.end(gson.toJson(SingleJsonResponse.of("Sensor updated successfully")));
|
.end(gson.toJson(result, Sensor.class));
|
||||||
})
|
})
|
||||||
.onFailure(err -> {
|
.onFailure(err -> {
|
||||||
context.fail(500, 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) {
|
private void getAllActuators(RoutingContext context) {
|
||||||
Integer groupId = Integer.parseInt(context.request().getParam("groupId"));
|
Integer groupId = Integer.parseInt(context.request().getParam("groupId"));
|
||||||
String deviceId = context.request().getParam("deviceId");
|
String deviceId = context.request().getParam("deviceId");
|
||||||
@@ -390,7 +445,7 @@ public class DataLayerAPIVerticle extends AbstractVerticle {
|
|||||||
.onSuccess(result -> {
|
.onSuccess(result -> {
|
||||||
context.response()
|
context.response()
|
||||||
.putHeader("content-type", "application/json; charset=utf-8")
|
.putHeader("content-type", "application/json; charset=utf-8")
|
||||||
.end(gson.toJson(SingleJsonResponse.of("Actuator added successfully")));
|
.end(gson.toJson(result, Actuator.class));
|
||||||
})
|
})
|
||||||
.onFailure(err -> {
|
.onFailure(err -> {
|
||||||
context.fail(500, err);
|
context.fail(500, err);
|
||||||
@@ -405,7 +460,7 @@ public class DataLayerAPIVerticle extends AbstractVerticle {
|
|||||||
.onSuccess(result -> {
|
.onSuccess(result -> {
|
||||||
context.response()
|
context.response()
|
||||||
.putHeader("content-type", "application/json; charset=utf-8")
|
.putHeader("content-type", "application/json; charset=utf-8")
|
||||||
.end(gson.toJson(SingleJsonResponse.of("Actuator updated successfully")));
|
.end(gson.toJson(result, Actuator.class));
|
||||||
})
|
})
|
||||||
.onFailure(err -> {
|
.onFailure(err -> {
|
||||||
context.fail(500, err);
|
context.fail(500, err);
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import java.util.Arrays;
|
|||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.stream.Stream;
|
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
import com.google.gson.GsonBuilder;
|
import com.google.gson.GsonBuilder;
|
||||||
@@ -13,6 +12,7 @@ import io.vertx.core.AbstractVerticle;
|
|||||||
import io.vertx.core.Promise;
|
import io.vertx.core.Promise;
|
||||||
import io.vertx.core.Vertx;
|
import io.vertx.core.Vertx;
|
||||||
import io.vertx.core.http.HttpMethod;
|
import io.vertx.core.http.HttpMethod;
|
||||||
|
import io.vertx.core.json.JsonObject;
|
||||||
import io.vertx.ext.web.Router;
|
import io.vertx.ext.web.Router;
|
||||||
import io.vertx.ext.web.RoutingContext;
|
import io.vertx.ext.web.RoutingContext;
|
||||||
import io.vertx.ext.web.client.WebClient;
|
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 io.vertx.ext.web.handler.CorsHandler;
|
||||||
import net.miarma.contaminus.common.ConfigManager;
|
import net.miarma.contaminus.common.ConfigManager;
|
||||||
import net.miarma.contaminus.common.Constants;
|
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.ViewLatestValues;
|
||||||
import net.miarma.contaminus.entities.ViewPollutionMap;
|
import net.miarma.contaminus.entities.ViewPollutionMap;
|
||||||
import net.miarma.contaminus.entities.ViewSensorHistory;
|
import net.miarma.contaminus.entities.ViewSensorHistory;
|
||||||
import net.miarma.contaminus.entities.ViewSensorValue;
|
import net.miarma.contaminus.entities.ViewSensorValue;
|
||||||
|
import net.miarma.contaminus.entities.WeatherValue;
|
||||||
import net.miarma.contaminus.util.RestClientUtil;
|
import net.miarma.contaminus.util.RestClientUtil;
|
||||||
|
|
||||||
public class LogicLayerAPIVerticle extends AbstractVerticle {
|
public class LogicLayerAPIVerticle extends AbstractVerticle {
|
||||||
@@ -55,6 +58,7 @@ public class LogicLayerAPIVerticle extends AbstractVerticle {
|
|||||||
|
|
||||||
router.route().handler(BodyHandler.create());
|
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.LATEST_VALUES).handler(this::getDeviceLatestValues);
|
||||||
router.route(HttpMethod.GET, Constants.POLLUTION_MAP).handler(this::getDevicePollutionMap);
|
router.route(HttpMethod.GET, Constants.POLLUTION_MAP).handler(this::getDevicePollutionMap);
|
||||||
router.route(HttpMethod.GET, Constants.HISTORY).handler(this::getDeviceHistory);
|
router.route(HttpMethod.GET, Constants.HISTORY).handler(this::getDeviceHistory);
|
||||||
@@ -68,93 +72,100 @@ public class LogicLayerAPIVerticle extends AbstractVerticle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void getDeviceLatestValues(RoutingContext context) {
|
private void getDeviceLatestValues(RoutingContext context) {
|
||||||
String deviceId = context.request().getParam("deviceId");
|
String deviceId = context.request().getParam("deviceId");
|
||||||
|
restClient.getRequest(configManager.getDataApiPort(), "http://" + configManager.getHost(),
|
||||||
Promise<ViewLatestValues[]> resultList = Promise.promise();
|
Constants.VIEW_LATEST_VALUES, ViewLatestValues[].class)
|
||||||
resultList.future().onComplete(complete -> {
|
.onSuccess(result -> {
|
||||||
if (complete.succeeded()) {
|
List<ViewLatestValues> aux = Arrays.stream(result)
|
||||||
List<ViewLatestValues> aux = Stream.of(complete.result())
|
.filter(elem -> deviceId.equals(elem.getDeviceId()))
|
||||||
.filter(elem -> deviceId.equals(elem.getDeviceId()))
|
.toList();
|
||||||
.toList();
|
context.response().putHeader("content-type", "application/json; charset=utf-8").end(gson.toJson(aux));
|
||||||
|
})
|
||||||
context.response()
|
.onFailure(err -> context.fail(500, err));
|
||||||
.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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void getDevicePollutionMap(RoutingContext context) {
|
private void getDevicePollutionMap(RoutingContext context) {
|
||||||
String deviceId = context.request().getParam("deviceId");
|
String deviceId = context.request().getParam("deviceId");
|
||||||
|
restClient.getRequest(configManager.getDataApiPort(), "http://" + configManager.getHost(),
|
||||||
Promise<ViewPollutionMap[]> resultList = Promise.promise();
|
Constants.VIEW_POLLUTION_MAP, ViewPollutionMap[].class)
|
||||||
|
.onSuccess(result -> {
|
||||||
resultList.future().onComplete(complete -> {
|
List<ViewPollutionMap> aux = Arrays.asList(result).stream()
|
||||||
if (complete.succeeded()) {
|
.filter(elem -> deviceId.equals(elem.getDeviceId()))
|
||||||
List<ViewPollutionMap> aux = Arrays.asList(complete.result()).stream()
|
.toList();
|
||||||
.filter(elem -> deviceId.equals(elem.getDeviceId()))
|
context.response().putHeader("content-type", "application/json; charset=utf-8").end(gson.toJson(aux));
|
||||||
.toList();
|
})
|
||||||
|
.onFailure(err -> context.fail(500, err));
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void getDeviceHistory(RoutingContext context) {
|
private void getDeviceHistory(RoutingContext context) {
|
||||||
String deviceId = context.request().getParam("deviceId");
|
String deviceId = context.request().getParam("deviceId");
|
||||||
|
restClient.getRequest(configManager.getDataApiPort(), "http://" + configManager.getHost(),
|
||||||
Promise<ViewSensorHistory[]> resultList = Promise.promise();
|
Constants.VIEW_SENSOR_HISTORY, ViewSensorHistory[].class)
|
||||||
|
.onSuccess(result -> {
|
||||||
resultList.future().onComplete(complete -> {
|
List<ViewSensorHistory> aux = Arrays.asList(result).stream()
|
||||||
if (complete.succeeded()) {
|
.filter(elem -> deviceId.equals(elem.getDeviceId()))
|
||||||
List<ViewSensorHistory> aux = Arrays.asList(complete.result()).stream()
|
.toList();
|
||||||
.filter(elem -> deviceId.equals(elem.getDeviceId()))
|
context.response().putHeader("content-type", "application/json; charset=utf-8").end(gson.toJson(aux));
|
||||||
.toList();
|
})
|
||||||
|
.onFailure(err -> context.fail(500, err));
|
||||||
context.response()
|
}
|
||||||
.putHeader("content-type", "application/json; charset=utf-8")
|
|
||||||
.end(gson.toJson(aux));
|
private void getSensorValues(RoutingContext context) {
|
||||||
} else {
|
int sensorId = Integer.parseInt(context.request().getParam("sensorId"));
|
||||||
context.fail(500, complete.cause());
|
restClient.getRequest(configManager.getDataApiPort(), "http://" + configManager.getHost(),
|
||||||
}
|
Constants.VIEW_SENSOR_VALUES, ViewSensorValue[].class)
|
||||||
});
|
.onSuccess(result -> {
|
||||||
|
List<ViewSensorValue> aux = Arrays.asList(result).stream()
|
||||||
this.restClient.getRequest(configManager.getDataApiPort(), "http://" + configManager.getHost(),
|
.filter(val -> val.getSensorId() == sensorId)
|
||||||
Constants.VIEW_SENSOR_HISTORY, ViewSensorHistory[].class, resultList);
|
.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) {
|
private void addBatch(RoutingContext context) {
|
||||||
Integer sensorId = Integer.parseInt(context.request().getParam("sensorId"));
|
JsonObject body = context.body().asJsonObject();
|
||||||
|
if (body == null) {
|
||||||
Promise<ViewSensorValue[]> resultList = Promise.promise();
|
context.response().setStatusCode(400).end("Missing JSON body");
|
||||||
|
return;
|
||||||
resultList.future().onComplete(complete -> {
|
}
|
||||||
if (complete.succeeded()) {
|
|
||||||
List<ViewSensorValue> aux = Arrays.asList(complete.result()).stream()
|
String groupId = body.getString("groupId");
|
||||||
.filter(val -> val.getSensorId() == sensorId)
|
String deviceId = body.getString("deviceId");
|
||||||
.toList();
|
|
||||||
|
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()
|
context.response()
|
||||||
.putHeader("content-type", "application/json; charset=utf-8")
|
.setStatusCode(201)
|
||||||
.end(gson.toJson(aux));
|
.putHeader("Content-Type", "application/json")
|
||||||
} else {
|
.end(new JsonObject().put("status", "success").put("inserted", 3).encode());
|
||||||
context.fail(500, complete.cause());
|
})
|
||||||
}
|
.onFailure(err -> context.fail(500, err));
|
||||||
});
|
}
|
||||||
|
|
||||||
this.restClient.getRequest(configManager.getDataApiPort(), "http://" + configManager.getHost(),
|
|
||||||
Constants.VIEW_SENSOR_VALUES, ViewSensorValue[].class, resultList);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -7,15 +7,14 @@
|
|||||||
#include "GPS.hpp"
|
#include "GPS.hpp"
|
||||||
|
|
||||||
String serializeSensorValue(
|
String serializeSensorValue(
|
||||||
int sensorId,
|
int groupId,
|
||||||
const String &deviceId,
|
const String &deviceId,
|
||||||
const String &sensorType,
|
int gpsSensorId,
|
||||||
const String &unit,
|
int weatherSensorId,
|
||||||
int sensorStatus,
|
int coSensorId,
|
||||||
const BME280Data_t &bme,
|
const BME280Data_t &bme,
|
||||||
const MQ7Data_t &mq7,
|
const MQ7Data_t &mq7,
|
||||||
const GPSData_t &gps,
|
const GPSData_t &gps);
|
||||||
long timestamp);
|
|
||||||
|
|
||||||
String serializeActuatorStatus(
|
String serializeActuatorStatus(
|
||||||
int actuatorId,
|
int actuatorId,
|
||||||
|
|||||||
@@ -2,5 +2,5 @@
|
|||||||
|
|
||||||
#include <HTTPClient.h>
|
#include <HTTPClient.h>
|
||||||
|
|
||||||
void getRequest(HTTPClient &httpClient, const String url, String &response);
|
void getRequest(const String url, String &response);
|
||||||
void postRequest(HTTPClient &httpClient, const String url, const String &payload, String &response);
|
void postRequest(const String url, const String &payload, String &response);
|
||||||
@@ -4,6 +4,8 @@
|
|||||||
#define REST_PORT 443
|
#define REST_PORT 443
|
||||||
#define MQTT_PORT 1883
|
#define MQTT_PORT 1883
|
||||||
|
|
||||||
|
#define GROUP_ID 1
|
||||||
|
|
||||||
#define MQ7_ID 1
|
#define MQ7_ID 1
|
||||||
#define BME280_ID 2
|
#define BME280_ID 2
|
||||||
#define GPS_ID 3
|
#define GPS_ID 3
|
||||||
@@ -48,4 +50,5 @@ void readBME280();
|
|||||||
void readGPS();
|
void readGPS();
|
||||||
void writeMatrix(const char *message);
|
void writeMatrix(const char *message);
|
||||||
void printAllData();
|
void printAllData();
|
||||||
|
void sendSensorData();
|
||||||
uint32_t getChipID();
|
uint32_t getChipID();
|
||||||
@@ -1,30 +1,34 @@
|
|||||||
#include "JsonTools.hpp"
|
#include "JsonTools.hpp"
|
||||||
|
|
||||||
String serializeSensorValue(
|
String serializeSensorValue(
|
||||||
int sensorId,
|
int groupId,
|
||||||
const String &deviceId,
|
const String &deviceId,
|
||||||
const String &sensorType,
|
int gpsSensorId,
|
||||||
const String &unit,
|
int weatherSensorId,
|
||||||
int sensorStatus,
|
int coSensorId,
|
||||||
const BME280Data_t &bme,
|
const BME280Data_t &bme,
|
||||||
const MQ7Data_t &mq7,
|
const MQ7Data_t &mq7,
|
||||||
const GPSData_t &gps,
|
const GPSData_t &gps)
|
||||||
long timestamp)
|
|
||||||
{
|
{
|
||||||
DynamicJsonDocument doc(1024);
|
DynamicJsonDocument doc(1024);
|
||||||
|
|
||||||
doc["sensorId"] = sensorId;
|
doc["groupId"] = groupId;
|
||||||
doc["deviceId"] = deviceId;
|
doc["deviceId"] = deviceId;
|
||||||
doc["sensorType"] = sensorType;
|
|
||||||
doc["unit"] = unit;
|
JsonObject gpsObj = doc.createNestedObject("gps");
|
||||||
doc["sensorStatus"] = sensorStatus;
|
gpsObj["sensorId"] = gpsSensorId;
|
||||||
doc["temperature"] = bme.temperature;
|
gpsObj["lat"] = gps.lat;
|
||||||
doc["humidity"] = bme.humidity;
|
gpsObj["lon"] = gps.lon;
|
||||||
doc["pressure"] = bme.pressure;
|
|
||||||
doc["carbonMonoxide"] = mq7.co;
|
JsonObject weather = doc.createNestedObject("weather");
|
||||||
doc["lat"] = gps.lat;
|
weather["sensorId"] = weatherSensorId;
|
||||||
doc["lon"] = gps.lon;
|
weather["temperature"] = bme.temperature;
|
||||||
doc["timestamp"] = timestamp;
|
weather["humidity"] = bme.humidity;
|
||||||
|
weather["pressure"] = bme.pressure;
|
||||||
|
|
||||||
|
JsonObject co = doc.createNestedObject("co");
|
||||||
|
co["sensorId"] = coSensorId;
|
||||||
|
co["value"] = mq7.co;
|
||||||
|
|
||||||
String output;
|
String output;
|
||||||
serializeJson(doc, output);
|
serializeJson(doc, output);
|
||||||
@@ -68,6 +72,7 @@ void deserializeSensorValue(HTTPClient &http, int httpResponseCode)
|
|||||||
Serial.print("HTTP Response code: ");
|
Serial.print("HTTP Response code: ");
|
||||||
Serial.println(httpResponseCode);
|
Serial.println(httpResponseCode);
|
||||||
String responseJson = http.getString();
|
String responseJson = http.getString();
|
||||||
|
|
||||||
DynamicJsonDocument doc(ESP.getMaxAllocHeap());
|
DynamicJsonDocument doc(ESP.getMaxAllocHeap());
|
||||||
DeserializationError error = deserializeJson(doc, responseJson);
|
DeserializationError error = deserializeJson(doc, responseJson);
|
||||||
|
|
||||||
@@ -78,26 +83,35 @@ void deserializeSensorValue(HTTPClient &http, int httpResponseCode)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
JsonArray array = doc.as<JsonArray>();
|
String groupId = doc["groupId"];
|
||||||
for (JsonObject sensor : array)
|
String deviceId = doc["deviceId"];
|
||||||
{
|
|
||||||
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"];
|
|
||||||
|
|
||||||
Serial.println("Sensor deserialized:");
|
JsonObject gps = doc["gps"];
|
||||||
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",
|
int gpsId = gps["sensorId"];
|
||||||
sensorId, deviceId.c_str(), sensorType.c_str(), unit.c_str(), sensorStatus,
|
float lat = gps["lat"];
|
||||||
temperature, humidity, carbonMonoxide, lat, lon, timestamp);
|
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
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ void getRequest(const String url, String &response)
|
|||||||
httpClient.end();
|
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.begin(url);
|
||||||
httpClient.addHeader("Content-Type", "application/json");
|
httpClient.addHeader("Content-Type", "application/json");
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ TaskTimer matrixTimer{0, 25};
|
|||||||
TaskTimer globalTimer{0, 60000};
|
TaskTimer globalTimer{0, 60000};
|
||||||
|
|
||||||
extern HTTPClient httpClient;
|
extern HTTPClient httpClient;
|
||||||
|
String response;
|
||||||
extern MD_Parola display;
|
extern MD_Parola display;
|
||||||
|
|
||||||
MQ7Data_t mq7Data;
|
MQ7Data_t mq7Data;
|
||||||
@@ -59,6 +60,8 @@ void loop()
|
|||||||
printAllData();
|
printAllData();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
sendSensorData();
|
||||||
|
|
||||||
globalTimer.lastRun = now;
|
globalTimer.lastRun = now;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -136,6 +139,41 @@ void printAllData()
|
|||||||
Serial.println(mq7Data.threshold);
|
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 getChipID()
|
||||||
{
|
{
|
||||||
uint32_t chipId = 0;
|
uint32_t chipId = 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user