Cambios backend/frontend
This commit is contained in:
@@ -94,6 +94,12 @@
|
|||||||
<version>2.19.0</version>
|
<version>2.19.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.vertx</groupId>
|
||||||
|
<artifactId>vertx-web-api-contract</artifactId>
|
||||||
|
<version>4.5.1</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
|||||||
@@ -10,33 +10,36 @@ 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);
|
||||||
|
|
||||||
|
public static final int SENSOR_ROLE = 0;
|
||||||
|
public static final int ACTUATOR_ROLE = 1;
|
||||||
|
|
||||||
/* API Endpoints */
|
/* API Endpoints */
|
||||||
public static final String GROUPS = RAW_API_PREFIX + "/groups";
|
public static final String GROUPS = RAW_API_PREFIX + "/groups"; // GET, POST
|
||||||
public static final String GROUP = RAW_API_PREFIX + "/groups/:groupId";
|
public static final String GROUP = RAW_API_PREFIX + "/groups/:groupId"; // GET, PUT
|
||||||
|
|
||||||
public static final String DEVICES = RAW_API_PREFIX + "/groups/:groupId/devices";
|
public static final String DEVICES = RAW_API_PREFIX + "/groups/:groupId/devices"; // GET, POST
|
||||||
public static final String DEVICE = RAW_API_PREFIX + "/groups/:groupId/devices/:deviceId";
|
public static final String DEVICE = RAW_API_PREFIX + "/groups/:groupId/devices/:deviceId"; // GET, PUT
|
||||||
public static final String LATEST_VALUES = API_PREFIX + "/groups/:groupId/devices/:deviceId/latest-values";
|
public static final String LATEST_VALUES = API_PREFIX + "/groups/:groupId/devices/:deviceId/latest-values"; // GET
|
||||||
public static final String POLLUTION_MAP = API_PREFIX + "/groups/:groupId/devices/:deviceId/pollution-map";
|
public static final String POLLUTION_MAP = API_PREFIX + "/groups/:groupId/devices/:deviceId/pollution-map"; // GET
|
||||||
public static final String HISTORY = API_PREFIX + "/groups/:groupId/devices/:deviceId/history";
|
public static final String HISTORY = API_PREFIX + "/groups/:groupId/devices/:deviceId/history"; // GET
|
||||||
|
|
||||||
public static final String SENSORS = RAW_API_PREFIX + "/groups/:groupId/devices/:deviceId/sensors";
|
public static final String SENSORS = RAW_API_PREFIX + "/groups/:groupId/devices/:deviceId/sensors"; // GET, POST
|
||||||
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"; // GET, PUT
|
||||||
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"; // GET
|
||||||
|
|
||||||
public static final String BATCH = API_PREFIX + "/batch";
|
public static final String BATCH = API_PREFIX + "/batch"; // POST
|
||||||
public static final String ADD_GPS_VALUE = RAW_API_PREFIX + "/groups/:groupId/devices/:deviceId/sensors/:sensorId/gps_values";
|
public static final String ADD_GPS_VALUE = RAW_API_PREFIX + "/groups/:groupId/devices/:deviceId/sensors/:sensorId/gps_values"; // POST
|
||||||
public static final String ADD_WEATHER_VALUE = RAW_API_PREFIX + "/groups/:groupId/devices/:deviceId/sensors/:sensorId/weather_values";
|
public static final String ADD_WEATHER_VALUE = RAW_API_PREFIX + "/groups/:groupId/devices/:deviceId/sensors/:sensorId/weather_values"; // POST
|
||||||
public static final String ADD_CO_VALUE = RAW_API_PREFIX + "/groups/:groupId/devices/:deviceId/sensors/:sensorId/co_values";
|
public static final String ADD_CO_VALUE = RAW_API_PREFIX + "/groups/:groupId/devices/:deviceId/sensors/:sensorId/co_values"; // POST
|
||||||
|
|
||||||
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"; // GET, POST
|
||||||
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"; // GET, PUT
|
||||||
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"; // GET
|
||||||
|
|
||||||
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"; // GET
|
||||||
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"; // GET
|
||||||
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"; // GET
|
||||||
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"; // GET
|
||||||
|
|
||||||
private Constants() {
|
private Constants() {
|
||||||
throw new AssertionError("Utility class cannot be instantiated.");
|
throw new AssertionError("Utility class cannot be instantiated.");
|
||||||
|
|||||||
@@ -24,16 +24,16 @@ public class VoronoiZoneDetector {
|
|||||||
|
|
||||||
private static class Zone {
|
private static class Zone {
|
||||||
Polygon polygon;
|
Polygon polygon;
|
||||||
String actuatorId;
|
Integer groupId;
|
||||||
|
|
||||||
public Zone(Polygon polygon, String actuatorId) {
|
public Zone(Polygon polygon, Integer groupId) {
|
||||||
this.polygon = polygon;
|
this.polygon = polygon;
|
||||||
this.actuatorId = actuatorId;
|
this.groupId = groupId;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private final List<Zone> zones = new ArrayList<>();
|
private static final List<Zone> zones = new ArrayList<>();
|
||||||
private final GeometryFactory geometryFactory = new GeometryFactory();
|
private static final GeometryFactory geometryFactory = new GeometryFactory();
|
||||||
private final Gson gson = new Gson();
|
private final Gson gson = new Gson();
|
||||||
|
|
||||||
public VoronoiZoneDetector(String geojsonUrl, boolean isUrl) throws Exception {
|
public VoronoiZoneDetector(String geojsonUrl, boolean isUrl) throws Exception {
|
||||||
@@ -54,10 +54,10 @@ public class VoronoiZoneDetector {
|
|||||||
for (int i = 0; i < features.size(); i++) {
|
for (int i = 0; i < features.size(); i++) {
|
||||||
JsonObject feature = features.get(i).getAsJsonObject();
|
JsonObject feature = features.get(i).getAsJsonObject();
|
||||||
|
|
||||||
String actuatorId = feature
|
Integer groupId = feature
|
||||||
.getAsJsonObject("properties")
|
.getAsJsonObject("properties")
|
||||||
.get("actuatorId")
|
.get("groupId")
|
||||||
.getAsString();
|
.getAsInt();
|
||||||
|
|
||||||
JsonObject geometryJson = feature.getAsJsonObject("geometry");
|
JsonObject geometryJson = feature.getAsJsonObject("geometry");
|
||||||
String geometryStr = gson.toJson(geometryJson);
|
String geometryStr = gson.toJson(geometryJson);
|
||||||
@@ -65,36 +65,22 @@ public class VoronoiZoneDetector {
|
|||||||
Geometry geometry = reader.read(geometryStr);
|
Geometry geometry = reader.read(geometryStr);
|
||||||
|
|
||||||
if (geometry instanceof Polygon polygon) {
|
if (geometry instanceof Polygon polygon) {
|
||||||
zones.add(new Zone(polygon, actuatorId));
|
zones.add(new Zone(polygon, groupId));
|
||||||
} else {
|
} else {
|
||||||
Constants.LOGGER.error("⚠️ Geometría ignorada: no es un polígono");
|
Constants.LOGGER.error("⚠️ Geometría ignorada: no es un polígono");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getZoneForPoint(double lon, double lat) {
|
public static Integer getZoneForPoint(double lon, double lat) {
|
||||||
Point p = geometryFactory.createPoint(new Coordinate(lon, lat));
|
Point p = geometryFactory.createPoint(new Coordinate(lon, lat));
|
||||||
|
|
||||||
for (Zone z : zones) {
|
for (Zone z : zones) {
|
||||||
if (z.polygon.covers(p)) {
|
if (z.polygon.covers(p)) {
|
||||||
return z.actuatorId;
|
return z.groupId;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return null; // no está dentro de ninguna zona
|
return null; // no está dentro de ninguna zona
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] args) throws Exception {
|
|
||||||
VoronoiZoneDetector detector = new VoronoiZoneDetector("https://miarma.net/files/voronoi_sevilla_geovoronoi.geojson", true);
|
|
||||||
|
|
||||||
double lon = -5.9752;
|
|
||||||
double lat = 37.3887;
|
|
||||||
|
|
||||||
String actuatorId = detector.getZoneForPoint(lon, lat);
|
|
||||||
if (actuatorId != null) {
|
|
||||||
System.out.println("📍 El punto pertenece al actuator: " + actuatorId);
|
|
||||||
} else {
|
|
||||||
System.out.println("🚫 El punto no pertenece a ninguna zona");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ public class Device {
|
|||||||
private String deviceId;
|
private String deviceId;
|
||||||
private Integer groupId;
|
private Integer groupId;
|
||||||
private String deviceName;
|
private String deviceName;
|
||||||
|
private Integer deviceRole;
|
||||||
|
|
||||||
public Device() {}
|
public Device() {}
|
||||||
|
|
||||||
@@ -16,13 +17,16 @@ public class Device {
|
|||||||
this.deviceId = row.getString("deviceId");
|
this.deviceId = row.getString("deviceId");
|
||||||
this.groupId = row.getInteger("groupId");
|
this.groupId = row.getInteger("groupId");
|
||||||
this.deviceName = row.getString("deviceName");
|
this.deviceName = row.getString("deviceName");
|
||||||
|
this.deviceRole = row.getInteger("deviceRole");
|
||||||
}
|
}
|
||||||
|
|
||||||
public Device(String deviceId, Integer groupId, String deviceName) {
|
public Device(String deviceId, Integer groupId, String deviceName, Integer deviceRole) {
|
||||||
super();
|
super();
|
||||||
this.deviceId = deviceId;
|
this.deviceId = deviceId;
|
||||||
this.groupId = groupId;
|
this.groupId = groupId;
|
||||||
this.deviceName = deviceName;
|
this.deviceName = deviceName;
|
||||||
|
this.deviceRole = deviceRole;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getDeviceId() {
|
public String getDeviceId() {
|
||||||
@@ -49,9 +53,13 @@ public class Device {
|
|||||||
this.deviceName = deviceName;
|
this.deviceName = deviceName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Integer getDeviceRole() {
|
||||||
|
return deviceRole;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDevice(Integer deviceRole) {
|
||||||
|
this.deviceRole = deviceRole;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -474,6 +474,7 @@ public class DataLayerAPIVerticle extends AbstractVerticle {
|
|||||||
|
|
||||||
dbManager.execute(query, ViewLatestValues.class,
|
dbManager.execute(query, ViewLatestValues.class,
|
||||||
onSuccess -> {
|
onSuccess -> {
|
||||||
|
Constants.LOGGER.info(gson.toJson(onSuccess));
|
||||||
context.response()
|
context.response()
|
||||||
.putHeader("content-type", "application/json; charset=utf-8")
|
.putHeader("content-type", "application/json; charset=utf-8")
|
||||||
.end(gson.toJson(onSuccess));
|
.end(gson.toJson(onSuccess));
|
||||||
|
|||||||
@@ -25,7 +25,9 @@ import io.vertx.mqtt.MqttClient;
|
|||||||
import io.vertx.mqtt.MqttClientOptions;
|
import io.vertx.mqtt.MqttClientOptions;
|
||||||
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.common.VoronoiZoneDetector;
|
||||||
import net.miarma.contaminus.entities.COValue;
|
import net.miarma.contaminus.entities.COValue;
|
||||||
|
import net.miarma.contaminus.entities.Device;
|
||||||
import net.miarma.contaminus.entities.GpsValue;
|
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;
|
||||||
@@ -155,7 +157,7 @@ public class LogicLayerAPIVerticle extends AbstractVerticle {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
String groupId = body.getString("groupId");
|
String groupId = body.getString("groupId");
|
||||||
String deviceId = body.getString("deviceId");
|
String deviceId = body.getString("deviceId");
|
||||||
|
|
||||||
JsonObject gps = body.getJsonObject("gps");
|
JsonObject gps = body.getJsonObject("gps");
|
||||||
@@ -171,30 +173,45 @@ public class LogicLayerAPIVerticle extends AbstractVerticle {
|
|||||||
WeatherValue weatherValue = gson.fromJson(weather.toString(), WeatherValue.class);
|
WeatherValue weatherValue = gson.fromJson(weather.toString(), WeatherValue.class);
|
||||||
COValue coValue = gson.fromJson(co.toString(), COValue.class);
|
COValue coValue = gson.fromJson(co.toString(), COValue.class);
|
||||||
|
|
||||||
// MQTT publish =============================
|
if(!VoronoiZoneDetector.getZoneForPoint(gpsValue.getLat(), gpsValue.getLon())
|
||||||
float coAmount = coValue.getValue();
|
.equals(Integer.valueOf(groupId))) {
|
||||||
Constants.LOGGER.info("CO amount received: " + coAmount);
|
Constants.LOGGER.info("El dispositivo no ha medido en su zona");
|
||||||
String topic = buildTopic(Integer.parseInt(groupId), deviceId, "matrix");
|
return;
|
||||||
Constants.LOGGER.info("Topic: " + topic);
|
|
||||||
if (mqttClient.isConnected()) {
|
|
||||||
Constants.LOGGER.info("🟢 Publishing to MQTT topic: " + topic + " with value: " + coAmount);
|
|
||||||
mqttClient.publish(topic, Buffer.buffer(coAmount >= 80.0f ? "ECO" : "GAS"),
|
|
||||||
MqttQoS.AT_LEAST_ONCE, false, false);
|
|
||||||
Constants.LOGGER.info("🟢 Message published to MQTT topic: " + topic);
|
|
||||||
}
|
}
|
||||||
// ============================================
|
|
||||||
|
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);
|
||||||
|
String devicesPath = Constants.DEVICES.replace(":groupId", groupId);
|
||||||
|
|
||||||
|
restClient.getRequest(port, host, devicesPath, Device[].class)
|
||||||
|
.onSuccess(ar -> {
|
||||||
|
Arrays.stream(ar)
|
||||||
|
.filter(d -> d.getDeviceRole().equals(Constants.ACTUATOR_ROLE))
|
||||||
|
.forEach(d -> {
|
||||||
|
float coAmount = coValue.getValue();
|
||||||
|
Constants.LOGGER.info("CO amount received: " + coAmount);
|
||||||
|
String topic = buildTopic(Integer.parseInt(groupId), d.getDeviceId(), "matrix");
|
||||||
|
Constants.LOGGER.info("Topic: " + topic);
|
||||||
|
if (mqttClient.isConnected()) {
|
||||||
|
Constants.LOGGER.info("🟢 Publishing to MQTT topic: " + topic + " with value: " + coAmount);
|
||||||
|
mqttClient.publish(topic, Buffer.buffer(coAmount >= 80.0f ? "ECO" : "GAS"),
|
||||||
|
MqttQoS.AT_LEAST_ONCE, false, false);
|
||||||
|
Constants.LOGGER.info("🟢 Message published to MQTT topic: " + topic);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
})
|
||||||
|
.onFailure(err -> {
|
||||||
|
context.fail(500, err);
|
||||||
|
});
|
||||||
|
|
||||||
gpsValue.setDeviceId(deviceId);
|
gpsValue.setDeviceId(deviceId);
|
||||||
weatherValue.setDeviceId(deviceId);
|
weatherValue.setDeviceId(deviceId);
|
||||||
coValue.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)
|
restClient.postRequest(port, host, gpsPath, gpsValue, GpsValue.class)
|
||||||
.compose(_ -> restClient.postRequest(port, host, weatherPath, weatherValue, WeatherValue.class))
|
.compose(_ -> restClient.postRequest(port, host, weatherPath, weatherValue, WeatherValue.class))
|
||||||
.compose(_ -> restClient.postRequest(port, host, coPath, coValue, COValue.class))
|
.compose(_ -> restClient.postRequest(port, host, coPath, coValue, COValue.class))
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ public class MainVerticle extends AbstractVerticle {
|
|||||||
File baseDir = new File(this.configManager.getBaseDir());
|
File baseDir = new File(this.configManager.getBaseDir());
|
||||||
if (!baseDir.exists()) {
|
if (!baseDir.exists()) {
|
||||||
baseDir.mkdirs();
|
baseDir.mkdirs();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void copyDefaultConfig() {
|
private void copyDefaultConfig() {
|
||||||
|
|||||||
@@ -1,18 +0,0 @@
|
|||||||
package net.miarma.contaminus.verticles;
|
|
||||||
|
|
||||||
import io.vertx.core.AbstractVerticle;
|
|
||||||
import io.vertx.core.Promise;
|
|
||||||
|
|
||||||
public class MqttVerticle extends AbstractVerticle {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void start(Promise<Void> startPromise) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void stop(Promise<Void> startPromise) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
325
backend/src/main/resources/openapi.yml
Normal file
325
backend/src/main/resources/openapi.yml
Normal file
@@ -0,0 +1,325 @@
|
|||||||
|
openapi: 3.0.0
|
||||||
|
info:
|
||||||
|
title: ContaminUS API
|
||||||
|
version: 1.0.0
|
||||||
|
description: Documentación de la API del proyecto ContaminUS
|
||||||
|
servers:
|
||||||
|
- url: http://localhost:8888
|
||||||
|
description: Servidor local de desarrollo
|
||||||
|
paths:
|
||||||
|
/api/v1/groups/{groupId}/devices/{deviceId}/latest-values:
|
||||||
|
get:
|
||||||
|
summary: Últimos valores de los sensores del dispositivo
|
||||||
|
parameters:
|
||||||
|
- name: groupId
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
- name: deviceId
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: Operación exitosa
|
||||||
|
/api/v1/groups/{groupId}/devices/{deviceId}/pollution-map:
|
||||||
|
get:
|
||||||
|
summary: Mapa de contaminación del dispositivo
|
||||||
|
parameters:
|
||||||
|
- name: groupId
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
- name: deviceId
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: Operación exitosa
|
||||||
|
/api/v1/groups/{groupId}/devices/{deviceId}/history:
|
||||||
|
get:
|
||||||
|
summary: Historial de valores del dispositivo
|
||||||
|
parameters:
|
||||||
|
- name: groupId
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
- name: deviceId
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: Operación exitosa
|
||||||
|
/api/v1/groups/{groupId}/devices/{deviceId}/sensors/{sensorId}/values:
|
||||||
|
get:
|
||||||
|
summary: Valores del sensor
|
||||||
|
parameters:
|
||||||
|
- name: groupId
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
- name: deviceId
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
- name: sensorId
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: Operación exitosa
|
||||||
|
/api/raw/v1/groups:
|
||||||
|
get:
|
||||||
|
summary: Lista de grupos
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: Operación exitosa
|
||||||
|
/api/raw/v1/groups/{groupId}:
|
||||||
|
get:
|
||||||
|
summary: Información de un grupo
|
||||||
|
parameters:
|
||||||
|
- name: groupId
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: Operación exitosa
|
||||||
|
/api/raw/v1/groups/{groupId}/devices:
|
||||||
|
get:
|
||||||
|
summary: Lista de dispositivos de un grupo
|
||||||
|
parameters:
|
||||||
|
- name: groupId
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: Operación exitosa
|
||||||
|
/api/raw/v1/groups/{groupId}/devices/{deviceId}:
|
||||||
|
get:
|
||||||
|
summary: Información de un dispositivo
|
||||||
|
parameters:
|
||||||
|
- name: groupId
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
- name: deviceId
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: Operación exitosa
|
||||||
|
/api/raw/v1/groups/{groupId}/devices/{deviceId}/sensors:
|
||||||
|
get:
|
||||||
|
summary: Lista de sensores
|
||||||
|
parameters:
|
||||||
|
- name: groupId
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
- name: deviceId
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: Operación exitosa
|
||||||
|
/api/raw/v1/groups/{groupId}/devices/{deviceId}/sensors/{sensorId}:
|
||||||
|
get:
|
||||||
|
summary: Información de un sensor
|
||||||
|
parameters:
|
||||||
|
- name: groupId
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
- name: deviceId
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
- name: sensorId
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: Operación exitosa
|
||||||
|
/api/raw/v1/groups/{groupId}/devices/{deviceId}/actuators:
|
||||||
|
get:
|
||||||
|
summary: Lista de actuadores
|
||||||
|
parameters:
|
||||||
|
- name: groupId
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
- name: deviceId
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: Operación exitosa
|
||||||
|
/api/raw/v1/groups/{groupId}/devices/{deviceId}/actuators/{actuator_id}:
|
||||||
|
get:
|
||||||
|
summary: Información de un actuador
|
||||||
|
parameters:
|
||||||
|
- name: groupId
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
- name: deviceId
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
- name: actuator_id
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: Operación exitosa
|
||||||
|
/api/v1/groups/{groupId}/devices/{deviceId}/actuators/{actuator_id}/status:
|
||||||
|
get:
|
||||||
|
summary: Estado de un actuador
|
||||||
|
parameters:
|
||||||
|
- name: groupId
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
- name: deviceId
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
- name: actuator_id
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: Operación exitosa
|
||||||
|
/api/raw/v1/v_latest_values:
|
||||||
|
get:
|
||||||
|
summary: Vista de últimos valores
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: Operación exitosa
|
||||||
|
/api/raw/v1/v_pollution_map:
|
||||||
|
get:
|
||||||
|
summary: Vista de mapa de contaminación
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: Operación exitosa
|
||||||
|
/api/raw/v1/v_sensor_history_by_device:
|
||||||
|
get:
|
||||||
|
summary: Vista de historial de sensores
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: Operación exitosa
|
||||||
|
/api/raw/v1/v_sensor_values:
|
||||||
|
get:
|
||||||
|
summary: Vista de valores de sensores
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: Operación exitosa
|
||||||
|
/api/v1/batch:
|
||||||
|
post:
|
||||||
|
summary: Insertar batch de datos
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: Operación exitosa
|
||||||
|
/api/raw/v1/groups/{groupId}/devices/{deviceId}/sensors/{sensorId}/gps_values:
|
||||||
|
post:
|
||||||
|
summary: Insertar valor GPS
|
||||||
|
parameters:
|
||||||
|
- name: groupId
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
- name: deviceId
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
- name: sensorId
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: Operación exitosa
|
||||||
|
/api/raw/v1/groups/{groupId}/devices/{deviceId}/sensors/{sensorId}/weather_values:
|
||||||
|
post:
|
||||||
|
summary: Insertar valor climático
|
||||||
|
parameters:
|
||||||
|
- name: groupId
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
- name: deviceId
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
- name: sensorId
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: Operación exitosa
|
||||||
|
/api/raw/v1/groups/{groupId}/devices/{deviceId}/sensors/{sensorId}/co_values:
|
||||||
|
post:
|
||||||
|
summary: Insertar valor de CO
|
||||||
|
parameters:
|
||||||
|
- name: groupId
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
- name: deviceId
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
- name: sensorId
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: Operación exitosa
|
||||||
2220
frontend/package-lock.json
generated
2220
frontend/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -21,10 +21,12 @@
|
|||||||
"leaflet": "^1.9.4",
|
"leaflet": "^1.9.4",
|
||||||
"leaflet.heat": "^0.2.0",
|
"leaflet.heat": "^0.2.0",
|
||||||
"react": "^19.0.0",
|
"react": "^19.0.0",
|
||||||
|
"react-bootstrap": "^2.10.10",
|
||||||
"react-chartjs-2": "^5.3.0",
|
"react-chartjs-2": "^5.3.0",
|
||||||
"react-dom": "^19.0.0",
|
"react-dom": "^19.0.0",
|
||||||
"react-leaflet": "^5.0.0",
|
"react-leaflet": "^5.0.0",
|
||||||
"react-router-dom": "^7.3.0"
|
"react-router-dom": "^7.3.0",
|
||||||
|
"swagger-ui-react": "^5.22.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@eslint/js": "^9.19.0",
|
"@eslint/js": "^9.19.0",
|
||||||
|
|||||||
453
frontend/public/apidoc.json
Normal file
453
frontend/public/apidoc.json
Normal file
@@ -0,0 +1,453 @@
|
|||||||
|
{
|
||||||
|
"name": "ContaminUS",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"logic_api": [
|
||||||
|
{
|
||||||
|
"method": "POST",
|
||||||
|
"path": "/api/v1/batch",
|
||||||
|
"description": "Añadir los valores de los sensores (batch)",
|
||||||
|
"params": [
|
||||||
|
{
|
||||||
|
"name": "deviceId",
|
||||||
|
"type": "integer",
|
||||||
|
"description": "ID del dispositivo",
|
||||||
|
"in": "body",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "sensorId",
|
||||||
|
"type": "integer",
|
||||||
|
"description": "ID del sensor",
|
||||||
|
"in": "body",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "lat",
|
||||||
|
"type": "float",
|
||||||
|
"description": "Latitud",
|
||||||
|
"in": "body",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "lon",
|
||||||
|
"type": "float",
|
||||||
|
"description": "Longitud",
|
||||||
|
"in": "body",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "temperature",
|
||||||
|
"type": "float",
|
||||||
|
"description": "Temperatura",
|
||||||
|
"in": "body",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "humidity",
|
||||||
|
"type": "float",
|
||||||
|
"description": "Humedad",
|
||||||
|
"in": "body",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "pressure",
|
||||||
|
"type": "float",
|
||||||
|
"description": "Presión",
|
||||||
|
"in": "body",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "value",
|
||||||
|
"type": "float",
|
||||||
|
"description": "Valor de CO",
|
||||||
|
"in": "body",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "timestamp",
|
||||||
|
"type": "long",
|
||||||
|
"description": "Marca temporal del valor",
|
||||||
|
"in": "body",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"method": "GET",
|
||||||
|
"path": "/api/v1/groups/:groupId/devices/:deviceId/latest-values",
|
||||||
|
"description": "Obtener los últimos valores de un dispositivo",
|
||||||
|
"params": [
|
||||||
|
{
|
||||||
|
"name": "groupId",
|
||||||
|
"type": "integer",
|
||||||
|
"description": "ID del grupo",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "deviceId",
|
||||||
|
"type": "integer",
|
||||||
|
"description": "ID del dispositivo",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"method": "GET",
|
||||||
|
"path": "/api/v1/groups/:groupId/devices/:deviceId/pollution-map",
|
||||||
|
"description": "Obtener el mapa de contaminación de un dispositivo",
|
||||||
|
"params": [
|
||||||
|
{
|
||||||
|
"name": "groupId",
|
||||||
|
"type": "integer",
|
||||||
|
"description": "ID del grupo",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "deviceId",
|
||||||
|
"type": "integer",
|
||||||
|
"description": "ID del dispositivo",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"method": "GET",
|
||||||
|
"path": "/api/v1/groups/:groupId/devices/:deviceId/history",
|
||||||
|
"description": "Obtener el histórico de un dispositivo",
|
||||||
|
"params": [
|
||||||
|
{
|
||||||
|
"name": "groupId",
|
||||||
|
"type": "integer",
|
||||||
|
"description": "ID del grupo",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "deviceId",
|
||||||
|
"type": "integer",
|
||||||
|
"description": "ID del dispositivo",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"method": "GET",
|
||||||
|
"path": "/api/v1/groups/:groupId/devices/:deviceId/sensors/:sensorId/values",
|
||||||
|
"description": "Obtener los valores de un sensor específico",
|
||||||
|
"params": [
|
||||||
|
{
|
||||||
|
"name": "groupId",
|
||||||
|
"type": "integer",
|
||||||
|
"description": "ID del grupo",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "deviceId",
|
||||||
|
"type": "integer",
|
||||||
|
"description": "ID del dispositivo",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "sensorId",
|
||||||
|
"type": "integer",
|
||||||
|
"description": "ID del sensor",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"method": "GET",
|
||||||
|
"path": "/api/v1/groups/:groupId/devices/:deviceId/actuators/:actuator_id/status",
|
||||||
|
"description": "Obtener el estado de un actuador",
|
||||||
|
"params": [
|
||||||
|
{
|
||||||
|
"name": "groupId",
|
||||||
|
"type": "integer",
|
||||||
|
"description": "ID del grupo",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "deviceId",
|
||||||
|
"type": "integer",
|
||||||
|
"description": "ID del dispositivo",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "actuator_id",
|
||||||
|
"type": "integer",
|
||||||
|
"description": "ID del actuador",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"raw_api": [
|
||||||
|
{
|
||||||
|
"method": "GET",
|
||||||
|
"path": "/api/raw/v1/groups",
|
||||||
|
"description": "Obtener todos los grupos"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"method": "POST",
|
||||||
|
"path": "/api/raw/v1/groups",
|
||||||
|
"description": "Crear un nuevo grupo",
|
||||||
|
"params": [
|
||||||
|
{
|
||||||
|
"name": "groupId",
|
||||||
|
"type": "integer",
|
||||||
|
"description": "ID del grupo",
|
||||||
|
"in": "body",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "groupName",
|
||||||
|
"type": "string",
|
||||||
|
"description": "Nombre del grupo",
|
||||||
|
"in": "body",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"method": "GET",
|
||||||
|
"path": "/api/raw/v1/groups/:groupId/devices",
|
||||||
|
"description": "Obtener todos los dispositivos de un grupo",
|
||||||
|
"params": [
|
||||||
|
{
|
||||||
|
"name": "groupId",
|
||||||
|
"type": "integer",
|
||||||
|
"description": "ID del grupo",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"method": "POST",
|
||||||
|
"path": "/api/raw/v1/groups/:groupId/devices",
|
||||||
|
"description": "Crear un nuevo dispositivo en un grupo",
|
||||||
|
"params": [
|
||||||
|
{
|
||||||
|
"name": "deviceId",
|
||||||
|
"type": "integer",
|
||||||
|
"description": "ID del dispositivo",
|
||||||
|
"in": "body",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "groupId",
|
||||||
|
"type": "integer",
|
||||||
|
"description": "ID del grupo",
|
||||||
|
"in": "body",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "deviceName",
|
||||||
|
"type": "string",
|
||||||
|
"description": "Nombre del dispositivo",
|
||||||
|
"in": "body",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"method": "GET",
|
||||||
|
"path": "/api/raw/v1/groups/:groupId/devices/:deviceId",
|
||||||
|
"description": "Obtener un dispositivo de un grupo",
|
||||||
|
"params": [
|
||||||
|
{
|
||||||
|
"name": "groupId",
|
||||||
|
"type": "integer",
|
||||||
|
"description": "ID del grupo",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "deviceId",
|
||||||
|
"type": "integer",
|
||||||
|
"description": "ID del dispositivo",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"method": "PUT",
|
||||||
|
"path": "/api/raw/v1/groups/:groupId/devices/:deviceId",
|
||||||
|
"description": "Actualizar un dispositivo de un grupo",
|
||||||
|
"params": [
|
||||||
|
{
|
||||||
|
"name": "groupId",
|
||||||
|
"type": "integer",
|
||||||
|
"description": "ID del grupo",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "deviceId",
|
||||||
|
"type": "integer",
|
||||||
|
"description": "ID del dispositivo",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"method": "GET",
|
||||||
|
"path": "/api/raw/v1/groups/:groupId/devices/:deviceId/sensors",
|
||||||
|
"description": "Obtener todos los sensores de un dispositivo",
|
||||||
|
"params": [
|
||||||
|
{
|
||||||
|
"name": "groupId",
|
||||||
|
"type": "integer",
|
||||||
|
"description": "ID del grupo",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "deviceId",
|
||||||
|
"type": "integer",
|
||||||
|
"description": "ID del dispositivo",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"method": "POST",
|
||||||
|
"path": "/api/raw/v1/groups/:groupId/devices/:deviceId/sensors",
|
||||||
|
"description": "Crear un nuevo sensor",
|
||||||
|
"params": [
|
||||||
|
{
|
||||||
|
"name": "sensorId",
|
||||||
|
"type": "integer",
|
||||||
|
"description": "ID del sensor",
|
||||||
|
"in": "body",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "deviceName",
|
||||||
|
"type": "string",
|
||||||
|
"description": "Nombre del dispositivo",
|
||||||
|
"in": "body",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"method": "GET",
|
||||||
|
"path": "/api/raw/v1/groups/:groupId/devices/:deviceId/sensors/:sensorId",
|
||||||
|
"description": "Obtener un sensor específico",
|
||||||
|
"params": [
|
||||||
|
{
|
||||||
|
"name": "groupId",
|
||||||
|
"type": "integer",
|
||||||
|
"description": "ID del grupo",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "deviceId",
|
||||||
|
"type": "integer",
|
||||||
|
"description": "ID del dispositivo",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "sensorId",
|
||||||
|
"type": "integer",
|
||||||
|
"description": "ID del sensor",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"method": "PUT",
|
||||||
|
"path": "/api/raw/v1/groups/:groupId/devices/:deviceId/sensors/:sensorId",
|
||||||
|
"description": "Actualizar un sensor específico",
|
||||||
|
"params": [
|
||||||
|
{
|
||||||
|
"name": "groupId",
|
||||||
|
"type": "integer",
|
||||||
|
"description": "ID del grupo",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "deviceId",
|
||||||
|
"type": "integer",
|
||||||
|
"description": "ID del dispositivo",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "sensorId",
|
||||||
|
"type": "integer",
|
||||||
|
"description": "ID del sensor",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"method": "GET",
|
||||||
|
"path": "/api/raw/v1/groups/:groupId/devices/:deviceId/sensors/:sensorId/values",
|
||||||
|
"description": "Obtener los valores de un sensor",
|
||||||
|
"params": [
|
||||||
|
{
|
||||||
|
"name": "groupId",
|
||||||
|
"type": "integer",
|
||||||
|
"description": "ID del grupo",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "deviceId",
|
||||||
|
"type": "integer",
|
||||||
|
"description": "ID del dispositivo",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "sensorId",
|
||||||
|
"type": "integer",
|
||||||
|
"description": "ID del sensor",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"method": "GET",
|
||||||
|
"path": "/api/raw/v1/v_latest_values",
|
||||||
|
"description": "Vista: últimos valores registrados"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"method": "GET",
|
||||||
|
"path": "/api/raw/v1/v_pollution_map",
|
||||||
|
"description": "Vista: mapa de contaminación"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"method": "GET",
|
||||||
|
"path": "/api/raw/v1/v_sensor_history_by_device",
|
||||||
|
"description": "Vista: histórico de sensores por dispositivo"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"method": "GET",
|
||||||
|
"path": "/api/raw/v1/v_sensor_values",
|
||||||
|
"description": "Vista: valores individuales de sensores"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -11,6 +11,7 @@ import GroupView from '@/pages/GroupView.jsx'
|
|||||||
|
|
||||||
import { Routes, Route } from 'react-router-dom'
|
import { Routes, Route } from 'react-router-dom'
|
||||||
import ContentWrapper from './components/layout/ContentWrapper'
|
import ContentWrapper from './components/layout/ContentWrapper'
|
||||||
|
import Docs from './pages/Docs'
|
||||||
|
|
||||||
const App = () => {
|
const App = () => {
|
||||||
|
|
||||||
@@ -23,6 +24,7 @@ const App = () => {
|
|||||||
<Route path="/" element={<Groups />} />
|
<Route path="/" element={<Groups />} />
|
||||||
<Route path="/groups/:groupId" element={<GroupView />} />
|
<Route path="/groups/:groupId" element={<GroupView />} />
|
||||||
<Route path="/groups/:groupId/devices/:deviceId" element={<Dashboard />} />
|
<Route path="/groups/:groupId/devices/:deviceId" element={<Dashboard />} />
|
||||||
|
<Route path="/docs" element={<Docs url={"/apidoc.json"} />} />
|
||||||
</Routes>
|
</Routes>
|
||||||
</ContentWrapper>
|
</ContentWrapper>
|
||||||
</>
|
</>
|
||||||
|
|||||||
74
frontend/src/components/ApiDocs.jsx
Normal file
74
frontend/src/components/ApiDocs.jsx
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import { Accordion } from 'react-bootstrap';
|
||||||
|
import 'bootstrap/dist/css/bootstrap.min.css';
|
||||||
|
|
||||||
|
const ApiDocs = ({ json }) => {
|
||||||
|
if (!json) return <p className="text-muted">No hay documentación disponible.</p>;
|
||||||
|
|
||||||
|
const renderEndpoints = (endpoints) => (
|
||||||
|
<Accordion>
|
||||||
|
{endpoints.map((ep, index) => (
|
||||||
|
<Accordion.Item eventKey={index.toString()} key={index}>
|
||||||
|
<Accordion.Header>
|
||||||
|
<span className={`badge bg-${getMethodColor(ep.method)} me-2 text-uppercase`}>{ep.method}</span>
|
||||||
|
<code>{ep.path}</code>
|
||||||
|
</Accordion.Header>
|
||||||
|
<Accordion.Body>
|
||||||
|
{ep.description && <p className="mb-2">{ep.description}</p>}
|
||||||
|
|
||||||
|
{ep.params?.length > 0 && (
|
||||||
|
<div className="d-flex flex-column gap-2 mt-3">
|
||||||
|
{ep.params.map((param, i) => (
|
||||||
|
<div key={i} className="bg-light border rounded px-3 py-2">
|
||||||
|
<div className="d-flex justify-content-between flex-wrap mb-1">
|
||||||
|
<strong>{param.name}</strong>
|
||||||
|
<span className="badge bg-secondary">{param.in}</span>
|
||||||
|
</div>
|
||||||
|
<div className="small text-muted">
|
||||||
|
<div><strong>Tipo:</strong> {param.type}</div>
|
||||||
|
<div><strong>¿Requerido?:</strong> {param.required ? 'Sí' : 'No'}</div>
|
||||||
|
{param.description && <div><strong>Descripción:</strong> {param.description}</div>}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</Accordion.Body>
|
||||||
|
</Accordion.Item>
|
||||||
|
))}
|
||||||
|
</Accordion>
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="container p-4 bg-white rounded-4 border">
|
||||||
|
<h1 className="fw-bold mb-5 text-dark">{json.name} <small className="text-muted fs-5">v{json.version}</small></h1>
|
||||||
|
|
||||||
|
<h3 className="mb-3 text-dark">API de Lógica</h3>
|
||||||
|
{renderEndpoints(json.logic_api)}
|
||||||
|
|
||||||
|
<h3 className="mb-3 text-dark mt-5">API de Datos (Raw)</h3>
|
||||||
|
{renderEndpoints(json.raw_api)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const getMethodColor = (method) => {
|
||||||
|
switch (method.toUpperCase()) {
|
||||||
|
case 'GET': return 'success';
|
||||||
|
case 'POST': return 'primary';
|
||||||
|
case 'PUT': return 'warning';
|
||||||
|
case 'DELETE': return 'danger';
|
||||||
|
default: return 'secondary';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
ApiDocs.propTypes = {
|
||||||
|
json: PropTypes.shape({
|
||||||
|
name: PropTypes.string.isRequired,
|
||||||
|
version: PropTypes.string.isRequired,
|
||||||
|
logic_api: PropTypes.array,
|
||||||
|
raw_api: PropTypes.array
|
||||||
|
}).isRequired
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ApiDocs;
|
||||||
@@ -86,8 +86,8 @@ const SummaryCardsContent = () => {
|
|||||||
|
|
||||||
|
|
||||||
if (data) {
|
if (data) {
|
||||||
let coData = data[1];
|
let coData = data[2];
|
||||||
let tempData = data[2];
|
let tempData = data[1];
|
||||||
|
|
||||||
CardsData[0].content = tempData.temperature + "°C";
|
CardsData[0].content = tempData.temperature + "°C";
|
||||||
CardsData[0].status = "Temperatura actual";
|
CardsData[0].status = "Temperatura actual";
|
||||||
|
|||||||
34
frontend/src/pages/Docs.jsx
Normal file
34
frontend/src/pages/Docs.jsx
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
import ApiDocs from '@/components/ApiDocs';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import { useEffect, useState } from 'react';
|
||||||
|
|
||||||
|
const Docs = ({ url }) => {
|
||||||
|
const [json, setJson] = useState(null);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const fetchDocs = async () => {
|
||||||
|
try {
|
||||||
|
const response = await fetch(url);
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error('Network response was not ok');
|
||||||
|
}
|
||||||
|
const data = await response.json();
|
||||||
|
setJson(data);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error fetching API docs:', error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
fetchDocs();
|
||||||
|
}, [url]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ApiDocs json={json} />
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Docs.propTypes = {
|
||||||
|
url: PropTypes.string.isRequired,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Docs;
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
import '@/css/Home.css';
|
|
||||||
|
|
||||||
const Home = () => {
|
|
||||||
return (
|
|
||||||
<div className='container mt-5 text-center align-items-center justify-content-center'>
|
|
||||||
<h1 className="display-1 color-animated-bold mb-4">No sé que poner XD</h1>
|
|
||||||
<img className="img-fluid image-animated-bold" src="/images/etsii.gif" />
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
export default Home;
|
|
||||||
694
hardware/swagger.json
Normal file
694
hardware/swagger.json
Normal file
@@ -0,0 +1,694 @@
|
|||||||
|
{
|
||||||
|
"name": "ContaminUS",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"basePath": "/api",
|
||||||
|
"endpoints": [
|
||||||
|
{
|
||||||
|
"method": "GET",
|
||||||
|
"path": "/raw/v1/groups",
|
||||||
|
"description": "Obtener todos los grupos"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"method": "POST",
|
||||||
|
"path": "/raw/v1/groups",
|
||||||
|
"description": "Crear un nuevo grupo",
|
||||||
|
"params": [
|
||||||
|
{
|
||||||
|
"name": "groupId",
|
||||||
|
"type": "integer",
|
||||||
|
"description": "ID del grupo",
|
||||||
|
"in": "body",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "groupName",
|
||||||
|
"type": "string",
|
||||||
|
"description": "Nombre del grupo",
|
||||||
|
"in": "body",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"method": "GET",
|
||||||
|
"path": "/raw/v1/groups/:groupId/devices/:deviceId/sensors",
|
||||||
|
"description": "Obtener todos los sensores de un dispositivo",
|
||||||
|
"params": [
|
||||||
|
{
|
||||||
|
"name": "groupId",
|
||||||
|
"type": "integer",
|
||||||
|
"description": "ID del grupo",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "deviceId",
|
||||||
|
"type": "integer",
|
||||||
|
"description": "ID del dispositivo",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"method": "POST",
|
||||||
|
"path": "/raw/v1/groups/:groupId/devices/:deviceId/sensors",
|
||||||
|
"description": "Crear un nuevo sensor en un dispositivo",
|
||||||
|
"params": [
|
||||||
|
{
|
||||||
|
"name": "sensorId",
|
||||||
|
"type": "integer",
|
||||||
|
"description": "ID del sensor",
|
||||||
|
"in": "body",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "deviceName",
|
||||||
|
"type": "string",
|
||||||
|
"description": "Nombre del dispositivo",
|
||||||
|
"in": "body",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"method": "GET",
|
||||||
|
"path": "/raw/v1/groups/:groupId/devices/:deviceId/sensors/:sensorId",
|
||||||
|
"description": "Obtener un sensor específico de un dispositivo",
|
||||||
|
"params": [
|
||||||
|
{
|
||||||
|
"name": "groupId",
|
||||||
|
"type": "integer",
|
||||||
|
"description": "ID del grupo",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "deviceId",
|
||||||
|
"type": "integer",
|
||||||
|
"description": "ID del dispositivo",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "sensorId",
|
||||||
|
"type": "integer",
|
||||||
|
"description": "ID del sensor",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"method": "PUT",
|
||||||
|
"path": "/raw/v1/groups/:groupId/devices/:deviceId/sensors/:sensorId",
|
||||||
|
"description": "Actualizar un sensor específico de un dispositivo",
|
||||||
|
"params": [
|
||||||
|
{
|
||||||
|
"name": "groupId",
|
||||||
|
"type": "integer",
|
||||||
|
"description": "ID del grupo",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "deviceId",
|
||||||
|
"type": "integer",
|
||||||
|
"description": "ID del dispositivo",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "sensorId",
|
||||||
|
"type": "integer",
|
||||||
|
"description": "ID del sensor",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"method": "GET",
|
||||||
|
"path": "/raw/v1/groups/:groupId/devices/:deviceId/sensors/:sensorId/values",
|
||||||
|
"description": "Obtener los valores de un sensor específico de un dispositivo",
|
||||||
|
"params": [
|
||||||
|
{
|
||||||
|
"name": "groupId",
|
||||||
|
"type": "integer",
|
||||||
|
"description": "ID del grupo",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "deviceId",
|
||||||
|
"type": "integer",
|
||||||
|
"description": "ID del dispositivo",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "sensorId",
|
||||||
|
"type": "integer",
|
||||||
|
"description": "ID del sensor",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
{
|
||||||
|
"method": "GET",
|
||||||
|
"path": "/raw/v1/groups/:groupId/devices",
|
||||||
|
"description": "Obtener todos los dispostivos de un grupo específico",
|
||||||
|
"params": [
|
||||||
|
{
|
||||||
|
"name": "groupId",
|
||||||
|
"type": "integer",
|
||||||
|
"description": "ID del grupo",
|
||||||
|
"in": "body",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"method": "POST",
|
||||||
|
"path": "/raw/v1/groups/:groupId/devices",
|
||||||
|
"description": "Crear un nuevo dispostivo perteneciente a un grupo",
|
||||||
|
"params": [
|
||||||
|
{
|
||||||
|
"name": "deviceId",
|
||||||
|
"type": "integer",
|
||||||
|
"description": "ID del dispositivo",
|
||||||
|
"in": "body",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "groupId",
|
||||||
|
"type": "integer",
|
||||||
|
"description": "ID del grupo",
|
||||||
|
"in": "body",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "deviceName",
|
||||||
|
"type": "string",
|
||||||
|
"description": "Nombre del dispositivo",
|
||||||
|
"in": "body",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"method": "GET",
|
||||||
|
"path": "/raw/v1/groups/:groupId/devices/:deviceId",
|
||||||
|
"description": "Obtener un dispositivo de un grupo",
|
||||||
|
"params": [
|
||||||
|
{
|
||||||
|
"name": "groupId",
|
||||||
|
"type": "integer",
|
||||||
|
"description": "ID del grupo",
|
||||||
|
"in": "body",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "deviceId",
|
||||||
|
"type": "integer",
|
||||||
|
"description": "ID del dispositivo",
|
||||||
|
"in": "body",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"method": "PUT",
|
||||||
|
"path": "/raw/v1/groups/:groupId/devices/:deviceId",
|
||||||
|
"description": "Actualiza un dispositivo de un grupo",
|
||||||
|
"params": [
|
||||||
|
{
|
||||||
|
"name": "groupId",
|
||||||
|
"type": "integer",
|
||||||
|
"description": "ID del grupo",
|
||||||
|
"in": "body",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "deviceId",
|
||||||
|
"type": "integer",
|
||||||
|
"description": "ID del dispositivo",
|
||||||
|
"in": "body",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"method": "GET",
|
||||||
|
"path": "/raw/v1/groups/:groupId/devices/:deviceId/latest-values",
|
||||||
|
"description": "Obtener los últimos valores de un dispositivo perteneciente a un grupo",
|
||||||
|
"params": [
|
||||||
|
{
|
||||||
|
"name": "groupId",
|
||||||
|
"type": "integer",
|
||||||
|
"description": "ID del grupo",
|
||||||
|
"in": "body",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "deviceId",
|
||||||
|
"type": "integer",
|
||||||
|
"description": "ID del dispositivo",
|
||||||
|
"in": "body",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"method": "GET",
|
||||||
|
"path": "/raw/v1/groups/:groupId/devices/:deviceId/latest-values",
|
||||||
|
"description": "Obtener los últimos valores de un dispositivo perteneciente a un grupo",
|
||||||
|
"params": [
|
||||||
|
{
|
||||||
|
"name": "groupId",
|
||||||
|
"type": "integer",
|
||||||
|
"description": "ID del grupo",
|
||||||
|
"in": "body",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "deviceId",
|
||||||
|
"type": "integer",
|
||||||
|
"description": "ID del dispositivo",
|
||||||
|
"in": "body",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"method": "GET",
|
||||||
|
"path": "/raw/v1/groups/:groupId/devices/:deviceId/latest-values",
|
||||||
|
"description": "Obtiene el histórico de valores para un dispositivo de un grupo",
|
||||||
|
"params": [
|
||||||
|
{
|
||||||
|
"name": "groupId",
|
||||||
|
"type": "integer",
|
||||||
|
"description": "ID del grupo",
|
||||||
|
"in": "body",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "deviceId",
|
||||||
|
"type": "integer",
|
||||||
|
"description": "ID del dispositivo",
|
||||||
|
"in": "body",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"method": "POST",
|
||||||
|
"path": "/batch",
|
||||||
|
"description": "Añadir los valores de los 3 sensores",
|
||||||
|
"params": [
|
||||||
|
{
|
||||||
|
"name": "deviceId",
|
||||||
|
"type": "integer",
|
||||||
|
"description": "ID del dispositivo",
|
||||||
|
"in": "body",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "sensorId",
|
||||||
|
"type": "integer",
|
||||||
|
"description": "ID del sensor",
|
||||||
|
"in": "body",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "lat",
|
||||||
|
"type": "float",
|
||||||
|
"description": "Latitud",
|
||||||
|
"in": "body",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "lon",
|
||||||
|
"type": "float",
|
||||||
|
"description": "Longitud",
|
||||||
|
"in": "body",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "temperature",
|
||||||
|
"type": "float",
|
||||||
|
"description": "Temperatura",
|
||||||
|
"in": "body",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "humidity",
|
||||||
|
"type": "float",
|
||||||
|
"description": "Humedad",
|
||||||
|
"in": "body",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "pressure",
|
||||||
|
"type": "float",
|
||||||
|
"description": "Presión",
|
||||||
|
"in": "body",
|
||||||
|
"required": true
|
||||||
|
},{
|
||||||
|
"name": "value",
|
||||||
|
"type": "float",
|
||||||
|
"description": "Valor de CO",
|
||||||
|
"in": "body",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "timestamp",
|
||||||
|
"type": "long",
|
||||||
|
"description": "Momento en el que se añadió el valor del CO",
|
||||||
|
"in": "body",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"method": "POST",
|
||||||
|
"path": "/groups/:groupId/devices/:deviceId/sensors/:sensorId/gps_values",
|
||||||
|
"description": "Añadir un valor del GPS",
|
||||||
|
"params": [
|
||||||
|
{
|
||||||
|
"name": "valueID",
|
||||||
|
"type": "integer",
|
||||||
|
"description": "ID del valor",
|
||||||
|
"in": "body",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "deviceId",
|
||||||
|
"type": "integer",
|
||||||
|
"description": "ID del dispositivo",
|
||||||
|
"in": "body",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "sensorId",
|
||||||
|
"type": "integer",
|
||||||
|
"description": "ID del sensor",
|
||||||
|
"in": "body",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "lat",
|
||||||
|
"type": "float",
|
||||||
|
"description": "Latitud",
|
||||||
|
"in": "body",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "lon",
|
||||||
|
"type": "float",
|
||||||
|
"description": "Longitud",
|
||||||
|
"in": "body",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "timestamp",
|
||||||
|
"type": "long",
|
||||||
|
"description": "Momento en el que se añadió el valor del GPS",
|
||||||
|
"in": "body",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"method": "POST",
|
||||||
|
"path": "/groups/:groupId/devices/:deviceId/sensors/:sensorId/weather_values",
|
||||||
|
"description": "Añadir un valor del clima",
|
||||||
|
"params": [
|
||||||
|
{
|
||||||
|
"name": "valueId",
|
||||||
|
"type": "integer",
|
||||||
|
"description": "ID del valor",
|
||||||
|
"in": "body",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "deviceId",
|
||||||
|
"type": "integer",
|
||||||
|
"description": "ID del dispositivo",
|
||||||
|
"in": "body",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "sensorId",
|
||||||
|
"type": "integer",
|
||||||
|
"description": "ID del sensor",
|
||||||
|
"in": "body",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "temperature",
|
||||||
|
"type": "float",
|
||||||
|
"description": "Temperatura",
|
||||||
|
"in": "body",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "humidity",
|
||||||
|
"type": "float",
|
||||||
|
"description": "Humedad",
|
||||||
|
"in": "body",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "pressure",
|
||||||
|
"type": "float",
|
||||||
|
"description": "Presión",
|
||||||
|
"in": "body",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "timestamp",
|
||||||
|
"type": "long",
|
||||||
|
"description": "Momento en el que se añadió el valor del clima",
|
||||||
|
"in": "body",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"method": "POST",
|
||||||
|
"path": "/groups/:groupId/devices/:deviceId/sensors/:sensorId/co_values",
|
||||||
|
"description": "Añadir un valor de CO",
|
||||||
|
"params": [
|
||||||
|
{
|
||||||
|
"name": "valueId",
|
||||||
|
"type": "integer",
|
||||||
|
"description": "ID del valor",
|
||||||
|
"in": "body",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "deviceId",
|
||||||
|
"type": "integer",
|
||||||
|
"description": "ID del dispositivo",
|
||||||
|
"in": "body",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "sensorId",
|
||||||
|
"type": "integer",
|
||||||
|
"description": "ID del sensor",
|
||||||
|
"in": "body",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "value",
|
||||||
|
"type": "float",
|
||||||
|
"description": "Valor de CO",
|
||||||
|
"in": "body",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "timestamp",
|
||||||
|
"type": "long",
|
||||||
|
"description": "Momento en el que se añadió el valor del CO",
|
||||||
|
"in": "body",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"method": "GET",
|
||||||
|
"path": "/raw/v1/groups/:groupId/devices/:deviceId/actuators",
|
||||||
|
"description": "Obtener todos los actuadores pertenecientes a un dispositivo de un grupo específico",
|
||||||
|
"params": [
|
||||||
|
{
|
||||||
|
"name": "groupId",
|
||||||
|
"type": "integer",
|
||||||
|
"description": "ID del grupo",
|
||||||
|
"in": "body",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "deviceId",
|
||||||
|
"type": "integer",
|
||||||
|
"description": "ID del dispositivo",
|
||||||
|
"in": "body",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"method": "POST",
|
||||||
|
"path": "/raw/v1/groups/:groupId/devices/:deviceId/actuators",
|
||||||
|
"description": "Añadir un nuevo actuador para un dispositivo perteneciente a un grupo",
|
||||||
|
"params": [
|
||||||
|
{
|
||||||
|
"name": "actuatorId",
|
||||||
|
"type": "integer",
|
||||||
|
"description": "ID del actuador",
|
||||||
|
"in": "body",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "deviceId",
|
||||||
|
"type": "integer",
|
||||||
|
"description": "ID del dispositivo",
|
||||||
|
"in": "body",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "status",
|
||||||
|
"type": "string",
|
||||||
|
"description": "Modo del actuador (GAS/ECO)",
|
||||||
|
"in": "body",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "timestamp",
|
||||||
|
"type": "long",
|
||||||
|
"description": "Momento en el que se inicializó el actuador",
|
||||||
|
"in": "body",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"method": "GET",
|
||||||
|
"path": "/raw/v1/groups/:groupId/devices/:deviceId/actuators/:actuator_id",
|
||||||
|
"description": "Obtener el actuadores perteneciente a un dispositivo de un grupo específico",
|
||||||
|
"params": [
|
||||||
|
{
|
||||||
|
"name": "groupId",
|
||||||
|
"type": "integer",
|
||||||
|
"description": "ID del grupo",
|
||||||
|
"in": "body",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "deviceId",
|
||||||
|
"type": "integer",
|
||||||
|
"description": "ID del dispositivo",
|
||||||
|
"in": "body",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "actuator_id",
|
||||||
|
"type": "integer",
|
||||||
|
"description": "ID del actuador",
|
||||||
|
"in": "body",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"method": "POST",
|
||||||
|
"path": "/raw/v1/groups/:groupId/devices/:deviceId/actuators/:actuator_id",
|
||||||
|
"description": "Actualizar un actuador para un dispositivo perteneciente a un grupo",
|
||||||
|
"params": [
|
||||||
|
{
|
||||||
|
"name": "groupId",
|
||||||
|
"type": "integer",
|
||||||
|
"description": "ID del grupo",
|
||||||
|
"in": "body",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "deviceId",
|
||||||
|
"type": "integer",
|
||||||
|
"description": "ID del dispositivo",
|
||||||
|
"in": "body",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "actuator_id",
|
||||||
|
"type": "integer",
|
||||||
|
"description": "ID del actuador",
|
||||||
|
"in": "body",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"method": "GET",
|
||||||
|
"path": "/raw/v1/groups/:groupId/devices/:deviceId/actuators/:actuator_id/status",
|
||||||
|
"description": "Obtener el estado de un actuador perteneciente a un dispositivo en un grupo",
|
||||||
|
"params": [
|
||||||
|
{
|
||||||
|
"name": "groupId",
|
||||||
|
"type": "integer",
|
||||||
|
"description": "ID del grupo",
|
||||||
|
"in": "body",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "deviceId",
|
||||||
|
"type": "integer",
|
||||||
|
"description": "ID del dispositivo",
|
||||||
|
"in": "body",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "actuator_id",
|
||||||
|
"type": "integer",
|
||||||
|
"description": "ID del actuador",
|
||||||
|
"in": "body",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"method": "GET",
|
||||||
|
"path": "/raw/v1/v_latest_values",
|
||||||
|
"description": "Obtener la vista de últimos valores",
|
||||||
|
"params": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"method": "GET",
|
||||||
|
"path": "/raw/v1/v_pollution_map",
|
||||||
|
"description": "Obtener la vista de contaminación de un mapa",
|
||||||
|
"params": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"method": "GET",
|
||||||
|
"path": "/raw/v1/v_sensor_history_by_device",
|
||||||
|
"description": "Obtener la vista del historico de sensores por dispositivo",
|
||||||
|
"params": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"method": "GET",
|
||||||
|
"path": "/raw/v1/v_sensor_values",
|
||||||
|
"description": "Obtener vista de valores dee sensores",
|
||||||
|
"params": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user