#include <WiFi.h>
#include <HTTPClient.h>
#include <time.h>
const char* ssid = "Wokwi-GUEST";
const char* password = "";
const char* firebaseHost = "https://arduino-flood-alert-default-rtdb.asia-southeast1.firebasedatabase.app/";
const char* firebaseAuth = "AIzaSyCE9NjabPOxvOeILmsOcnZWCearFn1OmyE";
const char* ntpServer = "pool.ntp.org";
const int trigPin = 5;
const int echoPin = 18;
#define SOUND_SPEED 0.034
#define BRIDGE_HEIGHT_M 8.0
#define MEASUREMENT_INTERVAL 5000
String phoneNumber = "628112332551";
String apiKey = "3843210";
unsigned long lastMeasurementTime = 0;
int lastFloodStage = 0;
void setupWiFi() {
WiFi.begin(ssid, password);
Serial.print("Connecting to WiFi");
while (WiFi.status() != WL_CONNECTED) {
Serial.print(".");
delay(500);
}
Serial.println("\nWiFi Connected");
Serial.println("IP Address: " + WiFi.localIP().toString());
}
void setupTime() {
configTime(0, 0, ntpServer);
Serial.print("Waiting for NTP time sync...");
struct tm timeinfo;
while (!getLocalTime(&timeinfo)) {
Serial.print(".");
delay(500);
}
Serial.println("\nTime synchronized");
}
unsigned long getEpochTime() {
struct tm timeinfo;
if (!getLocalTime(&timeinfo)) {
Serial.println("Failed to obtain time");
return 0;
}
return mktime(&timeinfo);
}
void setup() {
Serial.begin(115200);
setupWiFi();
setupTime();
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
}
float measureDistance() {
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
long duration = pulseIn(echoPin, HIGH);
return (duration * SOUND_SPEED / 2) / 100.0; // Distance in meters
}
void sendDataToFirebase(float distance) {
if (WiFi.status() == WL_CONNECTED) {
HTTPClient http;
String url = String(firebaseHost) + "/water-level.json?auth=" + firebaseAuth;
String jsonPayload = "{\"distance\":";
jsonPayload += String((BRIDGE_HEIGHT_M * 100) - (distance * 100));
jsonPayload += ", \"unixTimestamp\":";
jsonPayload += String(getEpochTime());
jsonPayload += "}";
http.begin(url);
http.addHeader("Content-Type", "application/json");
int httpResponseCode = http.POST(jsonPayload);
if (httpResponseCode > 0) {
Serial.println("Data sent successfully");
} else {
Serial.println("Error sending data: " + String(httpResponseCode));
}
http.end();
} else {
Serial.println("WiFi not connected, data not sent");
}
}
String urlEncode(String str) {
String encodedString = "";
char c;
char code0;
char code1;
for (int i = 0; i < str.length(); i++) {
c = str.charAt(i);
if (isalnum(c)) {
encodedString += c;
} else {
code1 = (c & 0xf) + '0';
if ((c & 0xf) > 9) {
code1 = (c & 0xf) - 10 + 'A';
}
c = (c >> 4) & 0xf;
code0 = c + '0';
if (c > 9) {
code0 = c - 10 + 'A';
}
encodedString += '%';
encodedString += code0;
encodedString += code1;
}
}
return encodedString;
}
void sendMessage(String message) {
// Encode pesan agar aman dalam URL
String encodedMessage = urlEncode(message);
String url = "https://api.callmebot.com/whatsapp.php?phone=" + phoneNumber + "&apikey=" + apiKey + "&text=" + encodedMessage;
HTTPClient http;
http.begin(url);
http.addHeader("Content-Type", "application/x-www-form-urlencoded");
// Menggunakan metode GET sesuai dengan API CallMeBot
int httpResponseCode = http.GET();
if (httpResponseCode == 200) {
Serial.println("Message sent successfully");
} else {
Serial.println("Error sending the message");
Serial.print("HTTP response code: ");
Serial.println(httpResponseCode);
}
http.end();
}
void checkFloodLevel(float distance) {
int floodStage = 0;
String message;
if (distance > 7.0) {
floodStage = 3;
message = "Tenggelam, air sudah setinggi " + String(distance, 2) + " meter!";
} else if (distance > 6.0) {
floodStage = 2;
message = "Waspada, air sudah setinggi " + String(distance, 2) + " meter!";
} else if (distance > 5.0) {
floodStage = 1;
message = "Siaga, air sudah setinggi " + String(distance, 2) + " meter!";
}
if (floodStage > lastFloodStage) {
sendMessage(message);
lastFloodStage = floodStage;
} else if (floodStage < lastFloodStage) {
lastFloodStage = floodStage; // Reset jika level air turun
}
}
void loop() {
unsigned long currentMillis = millis();
if (currentMillis - lastMeasurementTime >= MEASUREMENT_INTERVAL) {
lastMeasurementTime = currentMillis;
float distance = measureDistance();
Serial.print("Distance (cm): ");
Serial.println((BRIDGE_HEIGHT_M * 100) - (distance * 100));
sendDataToFirebase(distance);
checkFloodLevel(BRIDGE_HEIGHT_M - distance);
}
}