1
0
This commit is contained in:
Jose
2025-05-30 19:28:12 +02:00
parent 3d9728874a
commit fc130cc92d
30 changed files with 429 additions and 282 deletions

View File

@@ -16,7 +16,9 @@
"string_view": "cpp",
"initializer_list": "cpp",
"system_error": "cpp",
"cmath": "cpp"
"cmath": "cpp",
"random": "cpp",
"limits": "cpp"
},
"github.copilot.enable": {
"*": true,

View File

@@ -5,6 +5,7 @@
#include "BME280.hpp"
#include "MQ7v2.hpp"
#include "GPS.hpp"
#include "MAX7219.hpp"
String serializeSensorValue(
int groupId,
@@ -16,12 +17,4 @@ String serializeSensorValue(
const MQ7Data_t &mq7,
const GPSData_t &gps);
String serializeActuatorStatus(
int actuatorId,
const String &deviceId,
int status,
long timestamp);
void deserializeSensorValue(HTTPClient &http, int httpResponseCode);
void deserializeActuatorStatus(HTTPClient &http, int httpResponseCode);
void deserializeDevice(HTTPClient &http, int httpResponseCode);
MAX7219Status_t deserializeActuatorStatus(HTTPClient &http, int httpResponseCode);

View File

@@ -10,6 +10,12 @@
#define CS_PIN 18
#define CLK_PIN 17
struct MAX7219Status_t
{
String status;
String actuatorStatus;
};
void MAX7219_Init();
void MAX7219_DisplayText(const char *text, textPosition_t align, uint16_t speed, uint16_t pause);
bool MAX7219_Animate();

View File

@@ -14,4 +14,5 @@ struct MQ7Data_t
};
void MQ7_Init();
MQ7Data_t MQ7_Read();
MQ7Data_t MQ7_Read();
MQ7Data_t MQ7_Read_Fake();

View File

@@ -3,6 +3,7 @@
#include "globals.hpp"
#include <WiFi.h>
#include <PubSubClient.h>
#include "RestClient.hpp"
#define USER "contaminus"
#define MQTT_PASSWORD "contaminus"

View File

@@ -3,4 +3,5 @@
#include <HTTPClient.h>
void getRequest(const String url, String &response);
void postRequest(const String url, const String &payload, String &response);
void postRequest(const String url, const String &payload, String &response);
void putRequest(const String url, const String &payload, String &response);

View File

@@ -1,5 +1,7 @@
#include <Arduino.h>
#define DEVICE_ROLE ACTUATOR // se cambia entre SENSOR y ACTUATOR
#define MQTT_URI "miarma.net"
#define API_URI "https://contaminus.miarma.net/api/v1/"
#define REST_PORT 443
@@ -10,13 +12,11 @@
#define GPS_ID 1
#define MAX7219_ID 1
#define ECO "Solo vehiculos electricos/hibridos"
#define ALL "Todo tipo de vehiculos"
#define DEBUG
#define SENSOR 0
#define ACTUATOR 1
#define DEBUG
extern const uint32_t DEVICE_ID;
extern const int GROUP_ID;
extern const int GROUP_ID;
extern String currentMessage;

View File

@@ -2,8 +2,6 @@
#include "globals.hpp"
#define DEVICE_ROLE SENSOR // se cambia entre SENSOR y ACTUATOR
#if DEVICE_ROLE == SENSOR
#warning "Compilando firmware para SENSOR"
#elif DEVICE_ROLE == ACTUATOR

View File

@@ -36,158 +36,53 @@ String serializeSensorValue(
return output;
}
String serializeActuatorStatus(const int actuatorId, const String &deviceId, const int status, const long timestamp)
{
DynamicJsonDocument doc(512);
doc["actuatorId"] = actuatorId;
doc["deviceId"] = deviceId;
doc["status"] = status;
doc["timestamp"] = timestamp;
String output;
serializeJson(doc, output);
Serial.println(output);
return output;
}
String serializeDevice(const String &deviceId, int groupId, const String &deviceName)
{
DynamicJsonDocument doc(512);
doc["deviceId"] = deviceId;
doc["groupId"] = groupId;
doc["deviceName"] = deviceName;
String output;
serializeJson(doc, output);
Serial.println(output);
return output;
}
void deserializeSensorValue(HTTPClient &http, int httpResponseCode)
MAX7219Status_t deserializeActuatorStatus(HTTPClient &http, int httpResponseCode)
{
if (httpResponseCode > 0)
{
#ifdef DEBUG
Serial.print("HTTP Response code: ");
Serial.println(httpResponseCode);
String responseJson = http.getString();
#endif
DynamicJsonDocument doc(ESP.getMaxAllocHeap());
DeserializationError error = deserializeJson(doc, responseJson);
if (error)
{
Serial.print(F("deserializeJson() failed: "));
Serial.println(error.f_str());
return;
}
String groupId = doc["groupId"];
String deviceId = doc["deviceId"];
JsonObject gps = doc["gps"];
int gpsId = gps["sensorId"];
float lat = gps["lat"];
float lon = gps["lon"];
JsonObject weather = doc["weather"];
int weatherId = weather["sensorId"];
float temp = weather["temperature"];
float hum = weather["humidity"];
float pres = weather["pressure"];
JsonObject co = doc["co"];
int coId = co["sensorId"];
float coVal = co["value"];
Serial.println("🛰 GPS:");
Serial.printf(" Sensor ID: %d\n Lat: %.6f Lon: %.6f\n", gpsId, lat, lon);
Serial.println("🌤 Weather:");
Serial.printf(" Sensor ID: %d\n Temp: %.2f°C Hum: %.2f%% Pressure: %.2f hPa\n", weatherId, temp, hum, pres);
Serial.println("🧪 CO:");
Serial.printf(" Sensor ID: %d\n CO: %.2f ppm\n", coId, coVal);
Serial.printf("🧾 Group ID: %s\n", groupId.c_str());
Serial.printf("🧾 Device ID: %s\n", deviceId.c_str());
}
else
{
Serial.print("Error code: ");
Serial.println(httpResponseCode);
}
}
void deserializeActuatorStatus(HTTPClient &http, int httpResponseCode)
{
if (httpResponseCode > 0)
{
Serial.print("HTTP Response code: ");
Serial.println(httpResponseCode);
String responseJson = http.getString();
DynamicJsonDocument doc(ESP.getMaxAllocHeap());
DeserializationError error = deserializeJson(doc, responseJson);
if (error)
{
#ifdef DEBUG
Serial.print(F("deserializeJson() failed: "));
Serial.println(error.f_str());
return;
#endif
return {
.status = "error",
.actuatorStatus = "Error"
};
}
JsonArray array = doc.as<JsonArray>();
for (JsonObject actuator : array)
{
int actuatorId = actuator["actuatorId"];
String deviceId = actuator["deviceId"];
int status = actuator["status"];
long timestamp = actuator["timestamp"];
String status = doc["status"] | "error";
String actuatorStatus = doc["actuatorStatus"] | "Unknown";
Serial.println("Actuator deserialized:");
Serial.printf(" ID: %d\n Device: %s\n Status: %d\n Time: %ld\n\n",
actuatorId, deviceId.c_str(), status, timestamp);
}
#ifdef DEBUG
Serial.println("Actuator status deserialized:");
Serial.printf(" Status: %s\n Actuator Status: %s\n\n", status.c_str(), actuatorStatus.c_str());
#endif
return {
.status = status,
.actuatorStatus = actuatorStatus
};
}
else
{
#ifdef DEBUG
Serial.print("Error code: ");
Serial.println(httpResponseCode);
#endif
return {
.status = "error",
.actuatorStatus = "HTTP error"
};
}
}
void deserializeDevice(HTTPClient &http, int httpResponseCode)
{
if (httpResponseCode > 0)
{
Serial.print("HTTP Response code: ");
Serial.println(httpResponseCode);
String responseJson = http.getString();
DynamicJsonDocument doc(ESP.getMaxAllocHeap());
DeserializationError error = deserializeJson(doc, responseJson);
if (error)
{
Serial.print(F("deserializeJson() failed: "));
Serial.println(error.f_str());
return;
}
JsonArray array = doc.as<JsonArray>();
for (JsonObject device : array)
{
String deviceId = device["deviceId"];
int groupId = device["groupId"];
String deviceName = device["deviceName"];
Serial.println("Device deserialized:");
Serial.printf(" ID: %s\n Group: %d\n Name: %s\n\n", deviceId.c_str(), groupId, deviceName.c_str());
}
}
else
{
Serial.print("Error code: ");
Serial.println(httpResponseCode);
}
}

View File

@@ -31,4 +31,20 @@ void postRequest(const String url, const String &payload, String &response)
response = "Error: " + String(httpCode);
}
httpClient.end();
}
void putRequest(const String url, const String &payload, String &response)
{
httpClient.begin(url);
httpClient.addHeader("Content-Type", "application/json");
int httpCode = httpClient.PUT(payload);
if (httpCode > 0)
{
response = httpClient.getString();
}
else
{
response = "Error: " + String(httpCode);
}
httpClient.end();
}

View File

@@ -1,7 +1,7 @@
#include "MqttClient.hpp"
extern WiFiClient wifiClient;
extern const char *currentMessage;
extern HTTPClient httpClient;
PubSubClient client(wifiClient);
@@ -20,14 +20,20 @@ void MQTT_OnReceived(char *topic, byte *payload, unsigned int length)
content.concat((char)payload[i]);
}
content.trim();
#ifdef DEBUG
Serial.println(content);
#endif
#if DEVICE_ROLE == ACTUATOR
if(content == "ECO")
if (content.equals("ECO"))
{
currentMessage = ECO;
}
else
currentMessage = "Vehiculos electricos/hibridos";
}
else if (content.equals("GAS"))
{
currentMessage = ALL;
currentMessage = "Todo tipo de vehiculos";
}
#endif
}
@@ -67,7 +73,7 @@ void MQTT_Handle(const char *MQTTClientName)
client.loop();
}
String buildTopic(int groupId, const String& deviceId, const String& topic)
String buildTopic(int groupId, const String &deviceId, const String &topic)
{
String topicString = "group/" + String(groupId) + "/device/" + deviceId + "/" + topic;
return topicString;

View File

@@ -29,5 +29,5 @@ GPSData_t GPS_Read()
GPSData_t GPS_Read_Fake()
{
float rnd = random(-0.0005, 0.0005);
return {37.358201f + rnd, -5.986640f + rnd};
return {37.326371f + rnd, -5.966001f + rnd};
}

View File

@@ -17,4 +17,20 @@ MQ7Data_t MQ7_Read()
bool d0 = digitalRead(MQ7_D0);
return {ppm, d0};
}
}
MQ7Data_t MQ7_Read_Fake()
{
float ppm;
bool d0;
if (random(0, 100) < 50) {
ppm = random(80, 500); // valores entre 101 y 500 ppm
d0 = true;
} else {
ppm = random(10, 79); // valores entre 10 y 99 ppm
d0 = false;
}
return {ppm, d0};
}

View File

@@ -9,7 +9,9 @@ TaskTimer mqttTimer{0, 5000};
#if DEVICE_ROLE == ACTUATOR
TaskTimer matrixTimer{0, 25};
const char *currentMessage = ALL;
TaskTimer displayTimer{0, 1000};
String currentMessage = "";
String lastMessage = "";
extern MD_Parola display;
#endif
@@ -35,7 +37,7 @@ void setup()
try
{
#if DEVICE_ROLE == SENSOR
BME280_Init();
Serial.println("Sensor BME280 inicializado");
@@ -48,7 +50,12 @@ void setup()
#if DEVICE_ROLE == ACTUATOR
MAX7219_Init();
Serial.println("Display inicializado");
writeMatrix(currentMessage);
writeMatrix(currentMessage.c_str());
String url = String(API_URI) + "groups/" + GROUP_ID + "/devices/" + String(DEVICE_ID, HEX) + "/actuators/" + MAX7219_ID + "/status";
getRequest(url, response);
MAX7219Status_t statusData = deserializeActuatorStatus(httpClient, httpClient.GET());
currentMessage = statusData.actuatorStatus;
#endif
}
catch (const char *e)
@@ -70,6 +77,19 @@ void loop()
}
matrixTimer.lastRun = now;
}
if (now - displayTimer.lastRun >= displayTimer.interval)
{
if (currentMessage != lastMessage)
{
writeMatrix(currentMessage.c_str());
lastMessage = currentMessage;
#ifdef DEBUG
Serial.println("Display actualizado");
#endif
}
displayTimer.lastRun = now;
}
#endif
if (now - globalTimer.lastRun >= globalTimer.interval)
@@ -99,9 +119,8 @@ void loop()
void writeMatrix(const char *message)
{
#ifdef DEBUG
Serial.println("Escribiendo en el display...");
Serial.println("Escribiendo mensaje: "); Serial.print(message);
#endif
MAX7219_DisplayText(message, PA_LEFT, 50, 0);
}
#endif
@@ -110,7 +129,7 @@ void writeMatrix(const char *message)
void readMQ7()
{
const float CO_THRESHOLD = 100.0f;
mq7Data = MQ7_Read();
mq7Data = MQ7_Read_Fake();
}
void readBME280()