ENERGY METER

 #include <WiFi.h>

#include <WebServer.h>

#include <ESPmDNS.h>


// ==== KONFIGURASI WIFI RUMAH (MODE KLIEN) ====

const char* ssid = "Dara@home";       // SSID WiFi rumah Anda

const char* password = "rejeki88";    // Sandi WiFi rumah Anda


WebServer server(8888); // Web server di port 8888


// Definisikan hostname untuk mDNS Anda

const char* mdnsHostname = "glosindo-server"; // Akan diakses via http://glosindo-server.local:8888


// Variabel untuk menyimpan data sensor (simulasi)

float voltage = 0.0;

float current = 0.0;

float power = 0.0; // Daya instan dalam Watt


// Variabel untuk akumulasi energi

float energyWhPerSecond = 0.0; // Energi dalam Watt-detik (tampilan laju)

float energyWhPerMinute = 0.0; // Energi dalam Watt-menit (tampilan laju)

float energyWhPerHour = 0.0;   // Energi dalam Watt-jam (tampilan laju)

float energyWhPerDay = 0.0;    // Energi dalam Watt-jam (akumulasi harian)

float totalEnergyWh = 0.0;     // Total energi akumulasi secara keseluruhan


unsigned long lastSensorReadTime = 0;

const long sensorReadInterval = 2000; // Baca sensor setiap 2 detik


unsigned long lastEnergyCalcTime = 0;

const long energyCalcInterval = 1000; // Hitung energi setiap 1 detik untuk akurasi


// Variabel untuk melacak perubahan hari

unsigned long lastDayChangeTime = 0;


// Fungsi untuk membaca/mensimulasikan data sensor daya

void readSensors() {

  // --- Simulasi Pembacaan Daya ---

  voltage = random(2200, 2400) / 10.0; // Dari 220.0V hingga 240.0V

  current = random(50, 200) / 100.0;    // Dari 0.5A hingga 2.0A

  power = voltage * current;            // Hitung daya


  Serial.print("Sensor Read: V="); Serial.print(voltage);

  Serial.print("V, I="); Serial.print(current);

  Serial.print("A, P="); Serial.print(power); Serial.println("W");

}


// Fungsi untuk mengupdate akumulasi energi

void updateEnergyConsumption() {

  unsigned long currentTime = millis();

  unsigned long elapsedTime = currentTime - lastEnergyCalcTime;


  if (elapsedTime >= energyCalcInterval) {

    // Hitung energi dalam Watt-jam untuk interval ini

    float powerInWatts = power; // Gunakan daya instan saat ini

    float energyThisIntervalWh = (powerInWatts * (float)elapsedTime) / (1000.0 * 3600.0); // Waktu dalam jam


    // Akumulasi total energi

    totalEnergyWh += energyThisIntervalWh;


    // Hitung laju konsumsi per detik, menit, jam (berdasarkan daya instan saat ini)

    energyWhPerSecond = powerInWatts / 3600.0; // Daya dalam Wh/detik

    energyWhPerMinute = powerInWatts / 60.0;   // Daya dalam Wh/menit

    energyWhPerHour   = powerInWatts;          // Daya dalam Wh/jam (asumsi daya konstan selama 1 jam)


    // Akumulasi energi harian

    energyWhPerDay += energyThisIntervalWh;


    Serial.print("Energy Accumulation: Total="); Serial.print(totalEnergyWh, 2); Serial.print(" Wh, ");

    Serial.print("Hourly Rate="); Serial.print(energyWhPerHour, 2); Serial.print(" Wh/h, ");

    Serial.print("Daily Acc.="); Serial.print(energyWhPerDay, 2); Serial.println(" Wh/day");


    lastEnergyCalcTime = currentTime;

  }

}


// Handler untuk halaman utama (root)

void handleRoot() {

  String html = R"rawliteral(

<!DOCTYPE html>

<html>

<head>

<meta name="viewport" content="width=device-width, initial-scale=1">

<meta charset="UTF-8">

<title>Glosindo-server Power Monitor</title>

<style>

  html { font-family: Arial, Helvetica, sans-serif; text-align: center; }

  body { margin: 0; background-color: #f4f4f4; }

  .header { background-color: #4CAF50; color: white; padding: 15px; font-size: 24px; }

  .card-container { display: flex; flex-wrap: wrap; justify-content: center; padding: 20px; }

  .card {

    background-color: white;

    border-radius: 8px;

    box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);

    margin: 10px;

    padding: 20px;

    width: 280px;

    text-align: left;

  }

  .card h2 { color: #333; margin-top: 0; }

  .card p { font-size: 1.2em; color: #666; }

  .value { font-size: 2.5em; font-weight: bold; color: #007bff; margin-top: 10px; }

  .unit { font-size: 0.8em; color: #888; margin-left: 5px; }

</style>

</head>

<body>

<div class="header">

  <h1>Glosindo-server Power Monitor</h1>

</div>

<div class="card-container">

  <div class="card">

    <h2>Tegangan</h2>

    <p class="value"><span id="voltageVal">0.00</span><span class="unit">V</span></p>

  </div>

  <div class="card">

    <h2>Arus</h2>

    <p class="value"><span id="currentVal">0.00</span><span class="unit">A</span></p>

  </div>

  <div class="card">

    <h2>Daya Instan</h2>

    <p class="value"><span id="powerVal">0.00</span><span class="unit">W</span></p>

  </div>

  <div class="card">

    <h2>Konsumsi/Jam</h2>

    <p class="value"><span id="energyHourlyRateVal">0.00</span><span class="unit">Wh/h</span></p>

  </div>

  <div class="card">

    <h2>Konsumsi Harian</h2>

    <p class="value"><span id="energyDailyAccVal">0.00</span><span class="unit">Wh</span></p>

  </div>

  <div class="card">

    <h2>Total Energi</h2>

    <p class="value"><span id="totalEnergyVal">0.00</span><span class="unit">Wh</span></p>

  </div>

</div>


<script>

  function updateSensorData() {

    fetch('/data')

      .then(response => response.json())

      .then(data => {

        document.getElementById('voltageVal').innerText = data.voltage.toFixed(2);

        document.getElementById('currentVal').innerText = data.current.toFixed(2);

        document.getElementById('powerVal').innerText = data.power.toFixed(2);

        document.getElementById('energyHourlyRateVal').innerText = data.energyWhPerHour.toFixed(2);

        document.getElementById('energyDailyAccVal').innerText = data.energyWhPerDay.toFixed(2);

        document.getElementById('totalEnergyVal').innerText = data.totalEnergy.toFixed(2);

      })

      .catch(error => console.error('Error fetching data:', error));

  }


  // Perbarui data setiap 2 detik

  setInterval(updateSensorData, 2000);

  // Panggil pertama kali saat halaman dimuat

  updateSensorData();

</script>


</body>

</html>

)rawliteral";

  server.send(200, "text/html", html);

}


// Handler untuk mengirim data sensor dalam format JSON

void handleData() {

  String json = "{";

  json += "\"voltage\": " + String(voltage) + ",";

  json += "\"current\": " + String(current) + ",";

  json += "\"power\": " + String(power) + ",";

  json += "\"energyWhPerSecond\": " + String(energyWhPerSecond) + ",";

  json += "\"energyWhPerMinute\": " + String(energyWhPerMinute) + ",";

  json += "\"energyWhPerHour\": " + String(energyWhPerHour) + ",";

  json += "\"energyWhPerDay\": " + String(energyWhPerDay) + ",";

  json += "\"totalEnergy\": " + String(totalEnergyWh);

  json += "}";

  server.send(200, "application/json", json);

}


void setup() {

  Serial.begin(115200);


  Serial.print("Connecting to ");

  Serial.println(ssid);

  WiFi.begin(ssid, password);


  while (WiFi.status() != WL_CONNECTED) {

    delay(500);

    Serial.print(".");

  }


  Serial.println("");

  Serial.println("WiFi connected.");

  Serial.print("IP address: ");

  Serial.println(WiFi.localIP());


  // Inisialisasi mDNS

  if (!MDNS.begin(mdnsHostname)) {

    Serial.println("Error setting up MDNS responder!");

  } else {

    Serial.print("mDNS responder started with hostname: ");

    Serial.print(mdnsHostname);

    Serial.println(".local");

    MDNS.addService("http", "tcp", 8888);

  }


  // Atur handler

  server.on("/", handleRoot);

  server.on("/data", handleData);


  server.begin();

  Serial.println("Web Server started on port 8888");

  Serial.print("Access at: http://");

  Serial.print(WiFi.localIP());

  Serial.println(":8888/");

  Serial.print("Or via mDNS: http://");

  Serial.print(mdnsHostname);

  Serial.println(".local:8888/");


  // Baca sensor pertama kali saat setup

  readSensors();

  lastEnergyCalcTime = millis(); // Inisialisasi waktu perhitungan energi

  lastDayChangeTime = millis();

} // Ini adalah kurung kurawal penutup untuk setup()


void loop() {

  server.handleClient(); // Tangani permintaan klien


  // Perbarui data sensor daya secara periodik

  if (millis() - lastSensorReadTime >= sensorReadInterval) {

    readSensors();

    lastSensorReadTime = millis();

  }


  // Hitung akumulasi energi secara periodik

  updateEnergyConsumption();


  // Reset konsumsi harian setiap 24 jam (86.400.000 ms)

  // Perhatikan: ini akan mereset dari waktu ESP32 dinyalakan, bukan jam 00:00 aktual

  if (millis() - lastDayChangeTime >= 86400000UL) { // 24 jam dalam milidetik

    energyWhPerDay = 0.0;

    lastDayChangeTime = millis();

    Serial.println("Daily energy consumption reset.");

  }

  // Catatan: Untuk akumulasi per tahun, Anda perlu menyimpan nilai daily di ESP32

  // (misalnya ke LittleFS atau RTC memory) dan mengakumulasikannya selama setahun.

  // Ini memerlukan penanganan data non-volatile yang lebih kompleks.

} // Ini adalah kurung kurawal penutup untuk loop()

Comments