#include <WiFi.h>
#include <WebServer.h>
#include <ESP32Ping.h>
#include <Preferences.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
// OLED config
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
// SIM800L via HardwareSerial
HardwareSerial sim800(1); // UART1
#define SIM800_RX 16
#define SIM800_TX 17
Preferences prefs;
WebServer server(80);
// WiFi & Target
String ssid_sta, pass_sta, ssid_ap, pass_ap, phone_number;
IPAddress targetIP;
bool pingStatus = false; // false = DOWN, true = UP
String simSignal = "N/A";
String simNetwork = "Unknown";
// Load config from flash
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");
phone_number = prefs.getString("phone_number", "08112508805");
String ipString = prefs.getString("target_ip", "192.168.88.1");
targetIP.fromString(ipString);
prefs.end();
}
// Save config to flash
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.putString("phone_number", phone_number);
prefs.end();
}
// Update OLED
void updateDisplay() {
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.print("SSID: ");
display.println(ssid_sta);
display.print("WiFi: ");
display.println(WiFi.status() == WL_CONNECTED ? "Connected" : "Disconnected");
display.print("IP: ");
display.println(WiFi.localIP());
display.print("Ping: ");
display.println(pingStatus ? "UP" : "DOWN");
display.print("SIM: ");
display.println(simNetwork);
display.print("Signal: ");
display.println(simSignal);
display.display();
}
// Update SIM800L status
void updateSIMStatus() {
sim800.println("AT+CSQ");
delay(300);
String resp = "";
while (sim800.available()) {
resp += char(sim800.read());
}
int index = resp.indexOf("+CSQ:");
if (index >= 0) {
int rssi = resp.substring(index + 6).toInt();
simSignal = String(rssi);
}
sim800.println("AT+CREG?");
delay(300);
resp = "";
while (sim800.available()) {
resp += char(sim800.read());
}
if (resp.indexOf("+CREG: 0,1") >= 0 || resp.indexOf("+CREG: 0,5") >= 0) {
simNetwork = "OK";
} else {
simNetwork = "NO NET";
}
}
// Send SMS
void sendSMS(const String& number, const String& message) {
sim800.println("AT+CMGF=1");
delay(100);
sim800.print("AT+CMGS=\"");
sim800.print(number);
sim800.println("\"");
delay(500);
sim800.print(message);
sim800.write(26); // Ctrl+Z
delay(2000);
}
// Make Call
void makeCall(const String& number) {
sim800.print("ATD");
sim800.print(number);
sim800.println(";");
delay(10000); // 10 seconds call
sim800.println("ATH");
}
// Web root
void handleRoot() {
String status = pingStatus ? "UP" : "DOWN";
String color = pingStatus ? "green" : "red";
String html = "<!DOCTYPE html><html><head><title>ESP32 Config</title>";
html += "<meta http-equiv='refresh' content='10'></head><body>";
html += "<h1>ESP32 Config</h1>";
html += "<p>Status Ping: <b style='color:" + color + "'>" + status + "</b></p>";
html += "<p>Sinyal SIM: " + simSignal + "</p>";
html += "<p>Status SIM: " + simNetwork + "</p>";
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>";
html += "SSID AP: <input name='ssid_ap' value='" + ssid_ap + "'><br>";
html += "Password AP: <input type='password' name='pass_ap' value='" + pass_ap + "'><br>";
html += "IP Target: <input name='target_ip' value='" + targetIP.toString() + "'><br>";
html += "No HP Tujuan: <input name='phone_number' value='" + phone_number + "'><br>";
html += "<input type='submit' value='Simpan & Restart'>";
html += "</form></body></html>";
server.send(200, "text/html", html);
}
// Form handler
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"));
if (server.hasArg("phone_number")) phone_number = server.arg("phone_number");
saveConfig();
server.send(200, "text/html", "<h2>Restarting...</h2>");
delay(3000);
ESP.restart();
}
void setupWiFiClient() {
WiFi.begin(ssid_sta.c_str(), pass_sta.c_str());
Serial.print("Connecting to ");
Serial.println(ssid_sta);
int retry = 0;
while (WiFi.status() != WL_CONNECTED && retry < 20) {
delay(500);
Serial.print(".");
retry++;
}
Serial.println(WiFi.status() == WL_CONNECTED ? "\nConnected!" : "\nFailed!");
}
void setupAccessPoint() {
WiFi.softAP(ssid_ap.c_str(), pass_ap.c_str());
server.on("/", handleRoot);
server.on("/set", HTTP_POST, handleSet);
server.begin();
Serial.println("Web server started");
}
void setup() {
Serial.begin(115200);
sim800.begin(9600, SERIAL_8N1, SIM800_RX, SIM800_TX);
// OLED
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println("OLED not found");
while (1);
}
display.clearDisplay();
display.setCursor(0, 0);
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.println("Booting...");
display.display();
loadConfig();
setupWiFiClient();
setupAccessPoint();
updateSIMStatus();
updateDisplay();
}
void loop() {
server.handleClient();
static unsigned long lastPing = 0;
static bool hasAlerted = false;
if (millis() - lastPing > 10000) {
lastPing = millis();
Serial.print("Pinging ");
Serial.print(targetIP);
Serial.print("... ");
if (Ping.ping(targetIP)) {
Serial.println("OK");
pingStatus = true;
hasAlerted = false;
} else {
Serial.println("FAILED");
pingStatus = false;
if (!hasAlerted) {
sendSMS(phone_number, "Koneksi putus");
makeCall(phone_number);
hasAlerted = true;
}
}
updateSIMStatus();
updateDisplay();
}
}
No comments:
Post a Comment