#include <WiFi.h>
#include <WiFiClientSecure.h>
#include <UniversalTelegramBot.h>
// #include <Preferences.h> // COMENTADO para evitar uso en simulador
#include "esp_system.h"
#include "esp_wifi.h"
// === CONFIGURACIÓN ===
#define WIFI_SSID "Wokwi-GUEST"
#define WIFI_PASSWORD ""
#define BOT_TOKEN "8324232816:AAGD87qj2oiIhwC4PvN32mBQaxUoKiP8X9M"
#define CHANNEL_CHAT_ID "@sanmiguel_tuc"
// === OBJETOS GLOBALES ===
WiFiClientSecure secured_client;
UniversalTelegramBot bot(BOT_TOKEN, secured_client);
// Preferences prefs; // COMENTADO para evitar escritura/lectura en simulador
// === VARIABLES DE CONTROL ===
long interval = 10000;
unsigned long previousMillis = 0;
int resetCount = 0;
// === DETECTAR SI ES SIMULADOR WOKWI ===
bool isSimulated() {
return WiFi.SSID() == "Wokwi-GUEST";
}
// === FUNCIÓN: MOTIVO DEL REINICIO (no afecta en Wokwi) ===
String getResetReason() {
switch (esp_reset_reason()) {
case ESP_RST_POWERON: return "🔌 Power On";
case ESP_RST_EXT: return "🔁 Pin externo";
case ESP_RST_SW: return "💻 Software (ESP.restart)";
case ESP_RST_PANIC: return "⚠️ Excepción (Crash)";
case ESP_RST_INT_WDT: return "⏱️ Watchdog (Interrupción)";
case ESP_RST_TASK_WDT: return "⏱️ Watchdog (Tarea bloqueada)";
case ESP_RST_WDT: return "⏱️ Watchdog general";
case ESP_RST_DEEPSLEEP: return "🌙 Deep Sleep";
case ESP_RST_BROWNOUT: return "⚡ Corte de tensión (Brownout)";
case ESP_RST_SDIO: return "🔁 SDIO";
default: return "❓ Desconocido";
}
}
// === ENVÍA DATOS SIMULADOS AL CANAL TELEGRAM ===
void sendSensorData() {
float temperatura = random(200, 400) / 10.0;
float humedad = random(300, 900) / 10.0;
int calidadAire = random(100, 500);
bool generadorEncendido = random(0, 2);
String estadoGenerador = generadorEncendido ? "Encendido 🔌" : "Apagado ❌";
String message = "📡 *Datos Sistema IoT San Miguel (Simulados):*\n";
message += "🌡️ Temperatura: *" + String(temperatura, 1) + " °C*\n";
message += "💧 Humedad: *" + String(humedad, 1) + " %*\n";
message += "🧪 Calidad del Aire: *" + String(calidadAire) + " ppm*\n";
message += "⚙️ Generador: *" + estadoGenerador + "*\n";
message += "\n👨💻 _Dev. for: Ing. Gambino_";
bot.sendMessage(CHANNEL_CHAT_ID, message, "Markdown");
}
// === MANEJO DE MENSAJES DE TELEGRAM ===
void handleNewMessages(int numNewMessages) {
for (int i = 0; i < numNewMessages; i++) {
String text = bot.messages[i].text;
String chat_id = bot.messages[i].chat_id;
// Ignora mensajes vacíos o que no sean comandos
if (text.length() == 0 || chat_id.length() == 0 || !text.startsWith("/")) {
continue;
}
if (text == "/menu") {
String reply = "📋 *Menú de Comandos:*\n\n";
reply += "📊 /DataSensores - Datos actuales\n";
reply += "🧹 /APreset - Borrar WiFi y reiniciar\n";
reply += "⏱️ /setInterval [seg] - Cambiar intervalo\n";
reply += "📈 /status - Estado general\n";
reply += "🔁 /reset - Reiniciar ESP32\n";
reply += "🖥️ /infoDevices - Info del dispositivo\n";
reply += "♻️ /clearResetCount - Resetear contador";
bot.sendMessage(chat_id, reply, "Markdown");
} else if (text == "/DataSensores") {
sendSensorData();
} else if (text == "/APreset") {
bot.sendMessage(chat_id, "⚠️ *APreset deshabilitado en simulador.*", "Markdown");
} else if (text.startsWith("/setInterval ")) {
String arg = text.substring(13);
int newInterval = arg.toInt() * 1000;
if (newInterval > 0) {
interval = newInterval;
// prefs.begin("system", false); // COMENTADO
// prefs.putInt("interval_ms", interval);
// prefs.end();
bot.sendMessage(chat_id, "⏱️ Intervalo cambiado a *" + arg + "* segundos.", "Markdown");
} else {
bot.sendMessage(chat_id, "⚠️ Intervalo inválido. Usa un número positivo.", "Markdown");
}
} else if (text == "/status") {
String message = "📈 *Estado General:*\n";
message += "🔁 Reinicios: *" + String(resetCount) + "*\n";
message += "⏱️ Intervalo: *" + String(interval / 1000) + " s*\n";
message += "📶 WiFi: *" + String(WiFi.status() == WL_CONNECTED ? "Conectado ✅" : "Desconectado ❌") + "*\n";
message += "📝 Último reinicio: *" + getResetReason() + "*";
bot.sendMessage(chat_id, message, "Markdown");
} else if (text == "/reset") {
bot.sendMessage(chat_id, "⚠️ *Reset deshabilitado en simulador.*", "Markdown");
} else if (text == "/clearResetCount") {
resetCount = 0;
// prefs.begin("system", false); // COMENTADO
// prefs.putInt("reset_count", resetCount);
// prefs.end();
bot.sendMessage(chat_id, "♻️ *Contador de reinicios reiniciado.*", "Markdown");
} else if (text == "/infoDevices") {
String message = "🖥️ *Info del Dispositivo:*\n";
message += "📍 Ubicación: *Casa*\n";
message += "🆔 ID: *" + String((uint32_t)ESP.getEfuseMac(), HEX) + "*\n";
message += "🔗 MAC: *" + WiFi.macAddress() + "*\n";
message += "🌐 Red: *" + String(WIFI_SSID) + "*\n";
message += "📡 IP: *" + WiFi.localIP().toString() + "*\n";
message += "📶 RSSI: *" + String(WiFi.RSSI()) + " dBm*\n";
message += "📡 MQTT: *ON* (simulado)\n";
message += "🌡️ Temp CPU: *" + String(random(300, 450) / 10.0) + " °C*\n";
unsigned long uptime = millis() / 1000;
char buffer[10];
sprintf(buffer, "%02lu:%02lu:%02lu", uptime / 3600, (uptime % 3600) / 60, uptime % 60);
message += "⏱️ Uptime: *" + String(buffer) + "*";
bot.sendMessage(chat_id, message, "Markdown");
} else {
bot.sendMessage(chat_id,
"❌ *Comando no reconocido.*\n"
"ℹ️ Usa */menu* para ver los comandos disponibles.",
"Markdown");
}
}
}
// === SETUP PRINCIPAL ===
void setup() {
Serial.begin(115200);
// prefs.begin("system", false); // COMENTADO
// bool doApreset = prefs.isKey("apreset_flag") && prefs.getBool("apreset_flag");
// Serial.println("🔍 apreset_flag: " + String(doApreset));
// prefs.end();
// Comentamos toda la lógica de APreset
// prefs.begin("system", false); // COMENTADO
// resetCount = prefs.getInt("reset_count", 0) + 1;
resetCount++; // simulado
// prefs.putInt("reset_count", resetCount);
// interval = prefs.getInt("interval_ms", 10000);
// prefs.end();
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
Serial.print("Conectando a WiFi");
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.print(".");
}
Serial.println("\n✅ Conectado");
secured_client.setInsecure(); // Para certificados en Wokwi
randomSeed(analogRead(0));
String bootMsg = "⚠️ *Sistema Iniciado (modo Wokwi)*\n";
bootMsg += "📅 Fecha/Hora: " + String(__DATE__) + " " + String(__TIME__) + "\n";
bootMsg += "📝 Motivo: *" + getResetReason() + "*\n";
bootMsg += "🔁 Reinicios: *" + String(resetCount) + "*\n";
bootMsg += "📶 WiFi: *" + String(WiFi.status() == WL_CONNECTED ? "✅" : "❌") + "*";
bot.sendMessage(CHANNEL_CHAT_ID, bootMsg, "Markdown");
}
// === LOOP PRINCIPAL ===
void loop() {
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;
sendSensorData();
}
int numMessages = bot.getUpdates(bot.last_message_received + 1);
if (numMessages > 0) {
handleNewMessages(numMessages);
}
delay(100);
}