#include <WiFi.h>
#include <WiFiClientSecure.h>
#include <UniversalTelegramBot.h>
#include <time.h>
// === WiFi Settings ===
const char* ssid = "Wokwi-GUEST";
const char* password = "";
// === Telegram Bot ===
#define BOT_TOKEN "8403154383:AAF0m21mhUwFKZ9M8TMxiyhoJguXnX-a1Kg"
#define CHAT_ID "-4944057888"
WiFiClientSecure client;
UniversalTelegramBot bot(BOT_TOKEN, client);
// === Sensor Configuration ===
const int trigPin = 5;
const int echoPin = 18;
const float SENSOR_HEIGHT_CM = 400.0;
float triggerLevelCM = 250.0;
unsigned long checkInterval = 30000;
bool alertSent = false;
// === Time Config ===
const char* ntpServer = "pool.ntp.org";
const long gmtOffset_sec = 7 * 3600;
const int daylightOffset_sec = 0;
unsigned long lastCheckTime = 0;
String getFormattedTime() {
struct tm timeinfo;
if (!getLocalTime(&timeinfo)) return "Unknown time";
char buffer[30];
strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", &timeinfo);
return String(buffer);
}
float readDistanceCM() {
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
long duration = pulseIn(echoPin, HIGH, 30000);
return duration * 0.034 / 2;
}
void sendWaterInfo(float distance) {
float height = SENSOR_HEIGHT_CM - distance;
String msg = "📊 *Info Ketinggian Air (" + getFormattedTime() + ")*\n";
msg += "• Jarak ke permukaan air: " + String(distance, 1) + " cm\n";
msg += "• Tinggi air saat ini: " + String(height, 1) + " cm\n";
msg += "• Batas trigger: " + String(triggerLevelCM, 1) + " cm\n";
msg += "• Interval cek: " + String(checkInterval / 1000) + " detik";
bot.sendMessage(CHAT_ID, msg, "Markdown");
}
void sendTelegramAlert(float distance) {
float height = SENSOR_HEIGHT_CM - distance;
String msg = "🚨 *PERINGATAN BANJIR!*\n";
msg += "• Waktu: " + getFormattedTime() + "\n";
msg += "• Tinggi air: " + String(height, 1) + " cm\n";
msg += "• Jarak ke air: " + String(distance, 1) + " cm\n";
msg += "🔁 Mengaktifkan alarm...";
bot.sendMessage(CHAT_ID, msg, "Markdown");
bot.sendMessage(CHAT_ID, "/triggerbuzz", "");
}
void handleTelegramMessages() {
int numNewMessages = bot.getUpdates(bot.last_message_received + 1);
for (int i = 0; i < numNewMessages; i++) {
String text = bot.messages[i].text;
String chat_id = bot.messages[i].chat_id;
String from_name = bot.messages[i].from_name;
if (text == "/start") {
String welcome = "👋 Halo, " + from_name + "!\n\n";
welcome += "Perintah yang tersedia:\n";
welcome += "• /status - Lihat ketinggian air\n";
welcome += "• /setlevel <cm> - Atur batas trigger\n";
welcome += "• /setinterval <s> - Atur interval pengecekan";
bot.sendMessage(chat_id, welcome, "");
}
else if (text == "/status") {
float distance = readDistanceCM();
sendWaterInfo(distance);
}
else if (text.startsWith("/setlevel ")) {
float val = text.substring(10).toFloat();
if (val > 0 && val < SENSOR_HEIGHT_CM) {
triggerLevelCM = val;
Serial.println("✅ Command received: /setlevel " + String(val));
bot.sendMessage(chat_id, "✅ *Trigger level* diatur ke " + String(val, 1) + " cm", "Markdown");
} else {
bot.sendMessage(chat_id, "❌ Nilai tidak valid. Harus antara 0 - " + String(SENSOR_HEIGHT_CM, 0) + " cm", "");
}
}
else if (text.startsWith("/setinterval ")) {
int val = text.substring(13).toInt();
if (val >= 10 && val <= 3600) {
checkInterval = val * 1000;
Serial.println("✅ Command received: /setinterval " + String(val));
bot.sendMessage(chat_id, "✅ *Interval pengecekan* diatur ke " + String(val) + " detik", "Markdown");
} else {
bot.sendMessage(chat_id, "❌ Interval harus antara 10 - 3600 detik", "");
}
}
else {
bot.sendMessage(chat_id, "❓ Perintah tidak dikenali.\n\nGunakan /start untuk melihat perintah yang tersedia.", "");
}
}
}
void setup() {
Serial.begin(115200);
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
WiFi.begin(ssid, password);
client.setInsecure();
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("🔌 Connecting to WiFi...");
}
Serial.println("✅ WiFi Connected");
bot.sendMessage(CHAT_ID, "🟢 Node Sensor aktif dan terhubung ke WiFi", "");
configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
delay(1000);
}
void loop() {
handleTelegramMessages();
unsigned long now = millis();
if (now - lastCheckTime > checkInterval) {
float distance = readDistanceCM();
float height = SENSOR_HEIGHT_CM - distance;
if (height >= triggerLevelCM && !alertSent) {
sendTelegramAlert(distance);
alertSent = true;
} else if (height < triggerLevelCM - 10) {
alertSent = false;
}
sendWaterInfo(distance);
lastCheckTime = now;
}
delay(1000);
}