#include <WiFi.h>
#include <WebServer.h>
#include <ESPmDNS.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <time.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
// --- KONFIGURASI WIFI ---
const char* ssid = "Dara@home";
const char* password = "rejeki88";
const char* mdnsHostname = "glosindo-server";
// --- PING STATS ---
const char* pingHost = "google.com";
float lastPingTimeMs = 0.0;
bool isInternetConnected = false;
unsigned long lastPingAttemptTime = 0;
const long pingInterval = 5000;
// --- WEB SERVER ---
WebServer server(8888);
// --- SENSOR & ENERGI ---
float voltage = 0, current = 0, power = 0;
float energyWhPerSecond = 0, energyWhPerMinute = 0, energyWhPerHour = 0, energyWhPerDay = 0, totalEnergyWh = 0;
unsigned long lastSensorReadTime = 0;
const long sensorReadInterval = 2000;
unsigned long lastEnergyCalcTime = 0;
const long energyCalcInterval = 1000;
unsigned long lastDayChangeTime = 0;
// --- OLED ---
unsigned long lastOledUpdate = 0;
const long oledInterval = 3000;
int oledPage = 0;
void readSensors() {
voltage = random(2200, 2400) / 10.0;
current = random(50, 200) / 100.0;
power = voltage * current;
Serial.printf("Sensor: V=%.2f V, I=%.2f A, P=%.2f W\n", voltage, current, power);
}
void updateEnergyConsumption() {
unsigned long now = millis();
if (now - lastEnergyCalcTime >= energyCalcInterval) {
float deltaHours = (now - lastEnergyCalcTime) / 3600000.0;
float e = power * deltaHours;
totalEnergyWh += e;
energyWhPerSecond = power / 3600.0;
energyWhPerMinute = power / 60.0;
energyWhPerHour = power;
energyWhPerDay += e;
lastEnergyCalcTime = now;
Serial.printf("Energi: total %.2f Wh, hour rate %.2f Wh/h, daily %.2f Wh/day\n",
totalEnergyWh, energyWhPerHour, energyWhPerDay);
}
}
void performPing() {
if (WiFi.status() != WL_CONNECTED) {
isInternetConnected = false;
Serial.println("WiFi belum terhubung");
return;
}
IPAddress ip;
if (!WiFi.hostByName(pingHost, ip)) {
isInternetConnected = false;
Serial.println("DNS resolve gagal");
return;
}
WiFiClient client;
unsigned long start = millis();
if (client.connect(ip, 80)) {
lastPingTimeMs = millis() - start;
isInternetConnected = true;
Serial.printf("Ping %s: %.2f ms\n", pingHost, lastPingTimeMs);
client.stop();
} else {
lastPingTimeMs = 0;
isInternetConnected = false;
Serial.printf("Ping ke %s gagal\n", pingHost);
}
}
void handleRoot() {
String html = "<!DOCTYPE html><html><head><meta charset='UTF-8'><meta name='viewport' content='width=device-width,initial-scale=1'>";
html += "<title>Glosindo Power Monitor</title><style>body{font-family:Arial;text-align:center;}</style></head><body>";
html += "<h2>Monitor Energi & Internet</h2>";
html += "<p><strong>Tegangan:</strong> " + String(voltage) + " V</p>";
html += "<p><strong>Arus:</strong> " + String(current) + " A</p>";
html += "<p><strong>Daya:</strong> " + String(power) + " W</p>";
html += "<p><strong>Energi Jam:</strong> " + String(energyWhPerHour) + " Wh</p>";
html += "<p><strong>Energi Harian:</strong> " + String(energyWhPerDay) + " Wh</p>";
html += "<p><strong>Total Energi:</strong> " + String(totalEnergyWh) + " Wh</p>";
html += "<p><strong>Status Internet:</strong> " + String(isInternetConnected ? "ONLINE" : "OFFLINE") + "</p>";
html += "<p><strong>Ping:</strong> " + String(lastPingTimeMs) + " ms</p></body></html>";
server.send(200, "text/html", html);
}
void handleData() {
String json = "{";
json += "\"voltage\":" + String(voltage) + ",";
json += "\"current\":" + String(current) + ",";
json += "\"power\":" + String(power) + ",";
json += "\"energyWhPerHour\":" + String(energyWhPerHour) + ",";
json += "\"energyWhPerDay\":" + String(energyWhPerDay) + ",";
json += "\"totalEnergy\":" + String(totalEnergyWh) + ",";
json += "\"lastPingTimeMs\":" + String(lastPingTimeMs) + ",";
json += "\"isInternetConnected\":" + String(isInternetConnected ? "true" : "false");
json += "}";
server.send(200, "application/json", json);
}
void updateOledDisplay() {
if (millis() - lastOledUpdate >= oledInterval) {
lastOledUpdate = millis();
oledPage = (oledPage + 1) % 3;
display.clearDisplay();
display.setCursor(0, 0);
if (oledPage == 0) {
display.println("== Sensor Listrik ==");
display.printf("Teg: %.1f V\n", voltage);
display.printf("Arus: %.2f A\n", current);
display.printf("Daya: %.1f W\n", power);
} else if (oledPage == 1) {
display.println("== Energi ==");
display.printf("Jam: %.2f Wh\n", energyWhPerHour);
display.printf("Hari: %.2f Wh\n", energyWhPerDay);
display.printf("Total: %.2f Wh\n", totalEnergyWh);
} else if (oledPage == 2) {
time_t now = time(nullptr);
struct tm *t = localtime(&now);
display.println("== Waktu & Status ==");
display.printf("%02d:%02d:%02d\n", t->tm_hour, t->tm_min, t->tm_sec);
display.printf("WiFi: %s\n", WiFi.status() == WL_CONNECTED ? "Online" : "Offline");
display.printf("Ping: %.0f ms\n", lastPingTimeMs);
}
display.display();
}
}
void setup() {
Serial.begin(115200);
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("OLED gagal diinisialisasi"));
while (true);
}
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.println("Glosindo Monitor");
display.display();
delay(1000);
WiFi.begin(ssid, password);
Serial.print("Menghubungkan ke WiFi");
while (WiFi.status() != WL_CONNECTED) {
delay(500); Serial.print(".");
}
Serial.printf("\nTerhubung! IP: %s\n", WiFi.localIP().toString().c_str());
if (MDNS.begin(mdnsHostname)) {
MDNS.addService("http", "tcp", 8888);
Serial.printf("mDNS aktif: http://%s.local:8888\n", mdnsHostname);
}
configTime(7 * 3600, 0, "pool.ntp.org", "time.nist.gov");
server.on("/", handleRoot);
server.on("/data", handleData);
server.begin();
randomSeed(micros());
readSensors();
lastSensorReadTime = lastEnergyCalcTime = lastDayChangeTime = millis();
performPing();
lastPingAttemptTime = millis();
}
void loop() {
server.handleClient();
if (millis() - lastSensorReadTime >= sensorReadInterval) {
readSensors();
lastSensorReadTime = millis();
}
updateEnergyConsumption();
if (millis() - lastPingAttemptTime >= pingInterval) {
performPing();
lastPingAttemptTime = millis();
}
if (millis() - lastDayChangeTime >= 86400000UL) {
energyWhPerDay = 0;
lastDayChangeTime = millis();
Serial.println("Reset energi harian.");
}
updateOledDisplay();
}
Comments
Post a Comment