Search This Blog

Wednesday, 18 June 2025

ESP32 DENGAN FUNGSI CLIEN DAN AKSES POINT DAN FUNGSI PING SETING LEWAT WEB DAN BISA DI SAVE , BISA LEBIH DARI 1 NO HP

 #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

Tandon Air Otomatis (ESP32 Master & Display) + Kode Lengkap

  Panduan Lengkap Tandon Air Otomatis (ESP32 Master & Display) + Kode Lengkap Diperbarui: 09 August 2025 Artikel ini memandu Anda memban...