#include <WiFi.h>
#include <WebServer.h>
#include <ESP32Ping.h>
#include <Preferences.h>
#include <SPIFFS.h>
#include <FS.h>
#include <HardwareSerial.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
Preferences prefs;
WebServer server(80);
HardwareSerial sim800(1);
String ssid_sta, pass_sta, ssid_ap, pass_ap;
IPAddress targetIP;
bool pingStatus = false;
std::vector<String> phoneNumbers;
int currentPhoneIndex = 0;
unsigned long lastCallTime = 0;
const unsigned long callInterval = 60000;
bool alertSent = false;
void loadConfig() {
prefs.begin("config", true);
ssid_sta = prefs.getString("ssid_sta", "Pareting");
pass_sta = prefs.getString("pass_sta", "istimewa2");
ssid_ap = prefs.getString("ssid_ap", "esp32");
pass_ap = prefs.getString("pass_ap", "rejeki88");
String ipString = prefs.getString("target_ip", "192.168.88.1");
targetIP.fromString(ipString);
prefs.end();
}
void saveConfig() {
prefs.begin("config", false);
prefs.putString("ssid_sta", ssid_sta);
prefs.putString("pass_sta", pass_sta);
prefs.putString("ssid_ap", ssid_ap);
prefs.putString("pass_ap", pass_ap);
prefs.putString("target_ip", targetIP.toString());
prefs.end();
}
void updateDisplay() {
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.print("SSID: "); display.println(ssid_sta);
display.print("Status: ");
display.println(WiFi.status() == WL_CONNECTED ? "Connected" : "Not Connected");
display.print("IP: "); display.println(WiFi.localIP());
display.print("Ping: ");
display.setTextColor(pingStatus ? SSD1306_WHITE : SSD1306_INVERSE);
display.println(pingStatus ? "UP" : "DOWN");
display.display();
}
void readPhoneNumbers() {
phoneNumbers.clear();
File file = SPIFFS.open("/phones.txt");
if (!file) return;
while (file.available()) {
String line = file.readStringUntil('\n');
line.trim();
if (line.length() > 0) phoneNumbers.push_back(line);
}
file.close();
}
void sendSMS(const String &number, const String &message) {
sim800.println("AT+CMGF=1");
delay(500);
sim800.print("AT+CMGS=\"");
sim800.print(number);
sim800.println("\"");
delay(500);
sim800.print(message);
sim800.write(26);
delay(5000);
}
void makeCall(const String &number) {
sim800.print("ATD");
sim800.print(number);
sim800.println(";");
delay(10000);
sim800.println("ATH");
}
void alertFailure() {
if (millis() - lastCallTime >= callInterval) {
if (!phoneNumbers.empty()) {
String number = phoneNumbers[currentPhoneIndex];
sendSMS(number, "Koneksi putus");
makeCall(number);
currentPhoneIndex = (currentPhoneIndex + 1) % phoneNumbers.size();
lastCallTime = millis();
}
}
}
void handleRoot() {
String html = "<!DOCTYPE html><html><head><meta charset='UTF-8'><title>ESP32 Konfigurasi</title></head><body>";
html += "<h2>Status Ping: <b style='color:" + String(pingStatus ? "green" : "red") + "'>" + String(pingStatus ? "UP" : "DOWN") + "</b></h2>";
html += "<form action='/set' method='POST'>";
html += "SSID Client: <input name='ssid_sta' value='" + ssid_sta + "'><br>";
html += "Password Client: <input type='password' name='pass_sta' value='" + pass_sta + "'><br><br>";
html += "SSID AP: <input name='ssid_ap' value='" + ssid_ap + "'><br>";
html += "Password AP: <input type='password' name='pass_ap' value='" + pass_ap + "'><br><br>";
html += "IP Target: <input name='target_ip' value='" + targetIP.toString() + "'><br><br>";
html += "Nomor HP (pisah baris):<br><textarea name='phones' rows='5' cols='30'>";
for (auto &p : phoneNumbers) html += p + "\n";
html += "</textarea><br><br><input type='submit' value='Simpan & Restart'></form></body></html>";
server.send(200, "text/html", html);
}
void handleSet() {
if (server.hasArg("ssid_sta")) ssid_sta = server.arg("ssid_sta");
if (server.hasArg("pass_sta")) pass_sta = server.arg("pass_sta");
if (server.hasArg("ssid_ap")) ssid_ap = server.arg("ssid_ap");
if (server.hasArg("pass_ap")) pass_ap = server.arg("pass_ap");
if (server.hasArg("target_ip")) targetIP.fromString(server.arg("target_ip"));
saveConfig();
if (server.hasArg("phones")) {
File file = SPIFFS.open("/phones.txt", FILE_WRITE);
if (file) {
file.print(server.arg("phones"));
file.close();
}
}
server.send(200, "text/html", "<h2>Tersimpan! Restarting...</h2><script>setTimeout(()=>location.href='/',3000);</script>");
delay(3000);
ESP.restart();
}
void setupWiFiClient() {
WiFi.begin(ssid_sta.c_str(), pass_sta.c_str());
for (int i = 0; i < 20 && WiFi.status() != WL_CONNECTED; i++) delay(500);
}
void setupAccessPoint() {
WiFi.softAP(ssid_ap.c_str(), pass_ap.c_str());
server.on("/", handleRoot);
server.on("/set", HTTP_POST, handleSet);
server.begin();
}
void setup() {
Serial.begin(115200);
sim800.begin(9600, SERIAL_8N1, 16, 17); // RX, TX
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) while (true);
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.println("Inisialisasi...");
display.display();
if (!SPIFFS.begin(true)) Serial.println("SPIFFS Failed");
loadConfig();
readPhoneNumbers();
setupWiFiClient();
setupAccessPoint();
updateDisplay();
}
void loop() {
server.handleClient();
static unsigned long lastPing = 0;
if (millis() - lastPing > 10000) {
lastPing = millis();
pingStatus = Ping.ping(targetIP);
updateDisplay();
if (!pingStatus) alertFailure();
else alertSent = false;
}
}
No comments:
Post a Comment