Praktikum ini melanjutkan materi sebelumnya tentang REST API sederhana dengan ESP32. Pada kesempatan ini Anda akan membangun sistem monitoring lampu cerdas berbasis sistem terdistribusi dengan menggunakan:

  • 1 Node ESP32
  • 2 Localhost Server
  • REST API berbasis HTTP

ESP32 bertindak sebagai smart node yang:

  • membaca sensor cahaya,
  • mengontrol lampu otomatis,
  • mengirim data monitoring ke dua server localhost.

Localhost 1 digunakan sebagai:

  • server monitoring utama,
  • dashboard visualisasi.

Localhost 2 digunakan sebagai:

  • backup server,
  • penyimpanan log cadangan.

Arsitektur Sistem

Uraian arsitektur sistem dapat dilihat pada Gambar berikut:

Alur Sistem

  1. Sensor LDR membaca intensitas cahaya.
  2. ESP32 memproses nilai sensor.
  3. ESP32 menentukan status lampu:
    1. gelap → lampu ON
    2. terang → lampu OFF
  4. ESP32 mengontrol LED otomatis.
  5. ESP32 mengirim data ke Localhost Server 1.
  6. ESP32 mengirim data backup ke Localhost Server 2.
  7. Dashboard monitoring menampilkan data real-time.

Alat dan Bahan

Alat dan bahan yang digunakan dalam project kali ini dapat dilihat sebagai berikut:

No

Komponen

Jumlah

1

ESP32 DevKit V1

1

2

Sensor LDR

1

3

LED

1

4

Resistor 10KΩ

1

5

Resistor 220Ω

1

6

Breadboard

1

7

Kabel Jumper

Secukupnya

8

Laptop/PC

2

9

WiFi

1

Software yang Digunakan

Install software berikut:

  • Arduino IDE
  • XAMPP
  • Browser (Chrome/Edge)

Rangkaian Hardware

Koneksi LDR ke ESP32

LDR

ESP32

VCC

3.3V

GND

GND

DATA

GPIO 34

Koneksi LED

LED

ESP32

Anoda

GPIO 2

Katoda

GND

Program ESP32

1. Install Library

Install library berikut:

  • WiFi.h
  • HTTPClient.h

2. Program ESP32

#include <WiFi.h>
#include <HTTPClient.h>

#define LDR_PIN 34
#define LED_PIN 2

const char* ssid = "NAMA_WIFI";
const char* password = "PASSWORD_WIFI";

// Ganti sesuai IP localhost
String server1 = "http://192.168.1.10/smart-lamp/server1/api.php";
String server2 = "http://192.168.1.10/smart-lamp/server2/api.php";

int threshold = 2000;

void sendData(String serverUrl, int ldrValue, String lampStatus){
  if(WiFi.status()== WL_CONNECTED){
    HTTPClient http;
    String url = serverUrl +
                 "?ldr=" + String(ldrValue) +
                 "&lamp=" + lampStatus;

    http.begin(url);
    int httpCode = http.GET();
    Serial.print("Kirim ke: ");
    Serial.println(serverUrl);
    Serial.print("HTTP Response: ");
    Serial.println(httpCode);
    http.end();
  }
}

void setup() {
  Serial.begin(115200);
  pinMode(LED_PIN, OUTPUT);
  WiFi.begin(ssid, password);
  Serial.print("Menghubungkan WiFi");
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("\nWiFi Terhubung");
  Serial.println(WiFi.localIP());
}

void loop() {
  int ldrValue = analogRead(LDR_PIN);
  String lampStatus;

  if(ldrValue < threshold){
    digitalWrite(LED_PIN, HIGH);
    lampStatus = "ON";
  }else{
    digitalWrite(LED_PIN, LOW);
    lampStatus = "OFF";
  }

  Serial.print("Nilai LDR : ");
  Serial.println(ldrValue);

  Serial.print("Status Lampu : ");
  Serial.println(lampStatus);

  sendData(server1, ldrValue, lampStatus);
  sendData(server2, ldrValue, lampStatus);

  delay(5000);

}

Penjelasan Program

  1. WiFi.begin()

Digunakan untuk menghubungkan ESP32 ke jaringan WiFi.

  1. analogRead()

Digunakan membaca nilai sensor cahaya LDR.

  1. digitalWrite()

Digunakan untuk mengontrol LED secara otomatis.

  1. HTTPClient

Digunakan untuk mengirim data ke localhost menggunakan HTTP GET.

  1. http.GET()

Digunakan untuk mengirim request ke server monitoring.

Membuat Localhost Server

Buat Struktur Folder

Masuk ke folder:

htdocs/smart-lamp/

Buat folder:

server1

server2

Struktur Folder

htdocs/
└── smart-lamp/
    ├── server1/
    │   ├── api.php
    │   ├── dashboard.php
    │   └── data.txt
    │
    └── server2/
        ├── api.php
        ├── dashboard.php
        └── data.txt

Membuat API server 1

File: server1/api.php

<?php


$ldr  = $_GET['ldr'];
$lamp = $_GET['lamp'];

$file = "data.txt";

$data = date("Y-m-d H:i:s") .
        " | LDR: " . $ldr .
        " | Lampu: " . $lamp . PHP_EOL;

file_put_contents($file, $data, FILE_APPEND);

echo "DATA RECEIVED SERVER 1";

?>

Membuat API Server 2

File: server2/api.php

<?php

$ldr  = $_GET['ldr'];
$lamp = $_GET['lamp'];

$file = "data.txt";

$data = date("Y-m-d H:i:s") .
        " | BACKUP | LDR: " . $ldr .
        " | Lampu: " . $lamp . PHP_EOL;

file_put_contents($file, $data, FILE_APPEND);

echo "DATA RECEIVED SERVER 2";

?>

Penjelasan

  1. $_GET

Digunakan menerima data dari ESP32.

  1. file_put_contents()

Digunakan menyimpan data monitoring ke file.

Membuat Dashboard Server 1

File: server1/dashboard.php

<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8">
<title>Smart Lamp Monitoring - Server 1</title>
<meta http-equiv="refresh" content="5">
<meta name="viewport" content="width=device-width, initial-scale=1.0">

<style>
*{
    box-sizing:border-box;
}

body{
    margin:0;
    font-family:'Segoe UI', Arial, sans-serif;
    background:linear-gradient(135deg,#eef4ff,#f8fbff);
    color:#1f2937;
    padding:30px;
}

.container{
    max-width:1000px;
    margin:auto;
}

.header{
    margin-bottom:24px;
}

.badge{
    display:inline-block;
    padding:8px 16px;
    border-radius:999px;
    background:#dbeafe;
    color:#1d4ed8;
    font-size:13px;
    font-weight:700;
    letter-spacing:.5px;
}

h1{
    margin:14px 0 8px;
    font-size:32px;
    color:#0f172a;
}

.subtitle{
    margin:0;
    color:#64748b;
    line-height:1.6;
}

.grid{
    display:grid;
    grid-template-columns:repeat(3,1fr);
    gap:18px;
    margin:28px 0;
}

.card{
    background:#ffffff;
    border-radius:20px;
    padding:22px;
    box-shadow:0 15px 35px rgba(15,23,42,.08);
    border:1px solid rgba(148,163,184,.25);
}

.stat-title{
    font-size:14px;
    color:#64748b;
    margin-bottom:8px;
}

.stat-value{
    font-size:26px;
    font-weight:800;
    color:#0f172a;
}

.status-online{
    color:#16a34a;
}

.log-card{
    background:#0f172a;
    color:#d1fae5;
    border-radius:22px;
    padding:24px;
    box-shadow:0 18px 40px rgba(15,23,42,.18);
}

.log-title{
    color:#ffffff;
    margin-top:0;
    margin-bottom:14px;
}

pre{
    margin:0;
    white-space:pre-wrap;
    font-size:14px;
    line-height:1.7;
    color:#22c55e;
    max-height:420px;
    overflow:auto;
}

.footer{
    margin-top:20px;
    text-align:center;
    font-size:13px;
    color:#64748b;
}

@media(max-width:768px){
    body{
        padding:18px;
    }

    h1{
        font-size:25px;
    }

    .grid{
        grid-template-columns:1fr;
    }
}

</style>
</head>

<body>

<div class="container">

    <div class="header">
        <span class="badge">SERVER 1 - MONITORING UTAMA</span>
        <h1>Sistem Monitoring Lampu Cerdas</h1>
        <p class="subtitle">
            Dashboard ini digunakan sebagai pusat monitoring utama untuk membaca data
            sensor LDR dan status lampu dari node ESP32.
        </p>
    </div>

    <div class="grid">
        <div class="card">
            <div class="stat-title">Status Node</div>
            <div class="stat-value status-online">ONLINE</div>
        </div>

        <div class="card">
            <div class="stat-title">Perangkat</div>
            <div class="stat-value">ESP32</div>
        </div>

        <div class="card">
            <div class="stat-title">Mode Sistem</div>
            <div class="stat-value">Auto</div>
        </div>
    </div>

    <div class="log-card">
        <h3 class="log-title">Log Data Sensor dan Status Lampu</h3>
        <pre><?php
            if(file_exists("data.txt")){
                echo file_get_contents("data.txt");
            }else{
                echo "Belum ada data.";
            }
        ?></pre>
    </div>

    <div class="footer">
        Distributed Smart Lamp Monitoring System - ESP32 & Localhost
    </div>

</div>

</body>
</html>

Membuat Dashboard Server 2

File: server2/dashboard.php

<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8">
<title>Smart Lamp Backup - Server 2</title>
<meta http-equiv="refresh" content="5">
<meta name="viewport" content="width=device-width, initial-scale=1.0">

<style>
*{
    box-sizing:border-box;
}

body{
    margin:0;
    font-family:'Segoe UI', Arial, sans-serif;
    background:linear-gradient(135deg,#fff7ed,#fffbeb);
    color:#1f2937;
    padding:30px;
}

.container{
    max-width:1000px;
    margin:auto;
}

.header{
    margin-bottom:24px;
}

.badge{
    display:inline-block;
    padding:8px 16px;
    border-radius:999px;
    background:#ffedd5;
    color:#c2410c;
    font-size:13px;
    font-weight:700;
    letter-spacing:.5px;
}

h1{
    margin:14px 0 8px;
    font-size:32px;
    color:#7c2d12;
}

.subtitle{
    margin:0;
    color:#78716c;
    line-height:1.6;
}

.grid{
    display:grid;
    grid-template-columns:repeat(3,1fr);
    gap:18px;
    margin:28px 0;
}

.card{
    background:#ffffff;
    border-radius:20px;
    padding:22px;
    box-shadow:0 15px 35px rgba(124,45,18,.08);
    border:1px solid rgba(251,146,60,.25);
}

.stat-title{
    font-size:14px;
    color:#78716c;
    margin-bottom:8px;
}

.stat-value{
    font-size:26px;
    font-weight:800;
    color:#7c2d12;
}

.status-active{
    color:#ea580c;
}

.log-card{
    background:#1c1917;
    color:#fef3c7;
    border-radius:22px;
    padding:24px;
    box-shadow:0 18px 40px rgba(124,45,18,.18);
}

.log-title{
    color:#ffffff;
    margin-top:0;
    margin-bottom:14px;
}

pre{
    margin:0;
    white-space:pre-wrap;
    font-size:14px;
    line-height:1.7;
    color:#facc15;
    max-height:420px;
    overflow:auto;
}

.footer{
    margin-top:20px;
    text-align:center;
    font-size:13px;
    color:#78716c;
}

@media(max-width:768px){
    body{
        padding:18px;
    }

    h1{
        font-size:25px;
    }

    .grid{
        grid-template-columns:1fr;
    }
}

</style>
</head>

<body>

<div class="container">

    <div class="header">
        <span class="badge">SERVER 2 - BACKUP LOGGING</span>
        <h1>Backup Monitoring Lampu Cerdas</h1>
        <p class="subtitle">
            Dashboard ini berfungsi sebagai server cadangan untuk menyimpan log data
            dari ESP32 apabila server utama tidak dapat digunakan.
        </p>
    </div>

    <div class="grid">
        <div class="card">
            <div class="stat-title">Status Backup</div>
            <div class="stat-value status-active">ACTIVE</div>
        </div>

        <div class="card">
            <div class="stat-title">Jenis Server</div>
            <div class="stat-value">Backup</div>
        </div>

        <div class="card">
            <div class="stat-title">Mode</div>
            <div class="stat-value">Logging</div>
        </div>
    </div>

    <div class="log-card">
        <h3 class="log-title">Backup Log Data</h3>
        <pre><?php
            if(file_exists("data.txt")){
                echo file_get_contents("data.txt");
            }else{
                echo "Belum ada data backup.";
            }
        ?></pre>
    </div>

    <div class="footer">
        Backup Server - Distributed Smart Lamp Monitoring System
    </div>

</div>

</body>
</html>

Menjalankan Sistem

Langkah 1

Jalankan:

  • Apache
  • MySQL

pada XAMPP.

Langkah 2

Upload program ESP32 menggunakan Arduino IDE.

Langkah 3

Pastikan:

  • ESP32,
  • Localhost 1,
  • Localhost 2

berada pada jaringan WiFi yang sama.

Langkah 4

Cari IP localhost:

Buka CMD:

ipconfig

Cari:

IPv4 Address

Contoh:

192.168.1.10

Langkah 5

Sesuaikan IP pada program ESP32:

String server1 = "http://192.168.1.10/smart-lamp/server1/api.php";
String server2 = "http://192.168.1.10/smart-lamp/server2/api.php";

Langkah 6

Buka browser:

Dashboard Server 1

http://localhost/smart-lamp/server1/dashboard.php

Dashboard Server 2

http://localhost/smart-lamp/server2/dashboard.php

Hasil yang Diharapkan

Dashboard menampilkan:

  • nilai sensor LDR,
  • status lampu,
  • waktu pengiriman data,
  • monitoring real-time,
  • backup logging.

Contoh:

2026-05-10 10:15:01 | LDR: 1800 | Lampu: ON
2026-05-10 10:15:06 | LDR: 2600 | Lampu: OFF

Analisis Sistem

1. Mengapa Disebut Sistem Terdistribusi?

Karena:

  • ESP32 dan localhost berjalan terpisah,
  • komunikasi menggunakan jaringan WiFi,
  • proses monitoring dibagi ke beberapa node,
  • data dikirim ke dua server berbeda.

2. Fungsi REST API

REST API digunakan sebagai media komunikasi antara ESP32 dan localhost.

3. Fungsi Server 1

Server 1 digunakan sebagai:

  • monitoring utama,
  • dashboard visualisasi,
  • pusat data sistem.

4. Fungsi Server 2

Server 2 digunakan sebagai:

  • backup logging,
  • redundansi data,
  • fault tolerance sederhana.