#include <WiFi.h>
#include <PubSubClient.h>
#include <DHTesp.h>
// ========================
// WIFI
// ========================
const char* ssid = "Wokwi-GUEST";
const char* password = "";
// MQTT Broker
const char* mqtt_server = "broker.hivemq.com";
WiFiClient espClient;
PubSubClient client(espClient);
// ========================
// PIN SESUAI PERMINTAAN
// ========================
#define DHT_PIN 13
#define TRIG_PIN 18
#define ECHO_PIN 5
#define PIR_PIN 21
#define BTN_PIN 27
#define RELAY_LAMPU 32
#define RELAY_POMPA 26
#define RELAY_PEMANAS 14
#define RELAY_KIPAS 12
#define RELAY_ALARM 2
// ========================
DHTesp dht;
bool lampuState = false;
bool pompaState = false;
bool pemanasState = false;
bool kipasState = false;
bool alarmState = false;
unsigned long lastMovement = 0;
// ========================
// WIFI CONNECT
// ========================
void setup_wifi() {
WiFi.begin(ssid, password);
Serial.print("Menghubungkan WiFi");
while (WiFi.status() != WL_CONNECTED) {
Serial.print(".");
delay(300);
}
Serial.println("\n✔ WiFi Connected!");
}
// ========================
// MQTT MESSAGE HANDLER
// ========================
void callback(char* topic, byte* payload, unsigned int length) {
String msg = "";
for (int i = 0; i < length; i++)
msg += (char)payload[i];
if (String(topic) == "sabet/iot/lampu/cmd")
lampuState = (msg == "ON");
if (String(topic) == "sabet/iot/pompa/cmd")
pompaState = (msg == "ON");
if (String(topic) == "sabet/iot/pemanas/cmd")
pemanasState = (msg == "ON");
if (String(topic) == "sabet/iot/kipas/cmd")
kipasState = (msg == "ON");
if (String(topic) == "sabet/iot/alarm/cmd")
alarmState = (msg == "ON");
}
// =======================
// Koneksi MQTT (Versi kamu + PubSubClient)
// =======================
void connectMQTT() {
Serial.print("Menghubungkan MQTT");
while (!client.connected()) {
if (client.connect("ESP32Client")) {
Serial.println("\n✔ MQTT Connected!");
client.subscribe("sabet/iot/#");
} else {
Serial.print(".");
delay(500);
}
}
}
float jarakAir() {
digitalWrite(TRIG_PIN, LOW);
delayMicroseconds(5);
digitalWrite(TRIG_PIN, HIGH);
delayMicroseconds(10);
digitalWrite(TRIG_PIN, LOW);
long duration = pulseIn(ECHO_PIN, HIGH, 30000);
if (duration == 0) return 0;
float cm = duration * 0.0343 / 2;
return cm;
}
// ========================
// SETUP
// ========================
void setup() {
Serial.begin(115200);
pinMode(RELAY_LAMPU, OUTPUT);
pinMode(RELAY_POMPA, OUTPUT);
pinMode(RELAY_PEMANAS, OUTPUT);
pinMode(RELAY_KIPAS, OUTPUT);
pinMode(RELAY_ALARM, OUTPUT);
pinMode(PIR_PIN, INPUT);
pinMode(BTN_PIN, INPUT_PULLUP);
pinMode(TRIG_PIN, OUTPUT);
pinMode(ECHO_PIN, INPUT);
dht.setup(DHT_PIN, DHTesp::DHT22);
setup_wifi();
client.setServer(mqtt_server, 1883);
client.setCallback(callback);
connectMQTT();
}
// ========================
// LOOP
// ========================
void loop() {
if (!client.connected()) connectMQTT();
client.loop();
bool gerak = digitalRead(PIR_PIN);
if (gerak) {
lampuState = true;
lastMovement = millis();
} else {
if (millis() - lastMovement > 10000)
lampuState = false;
}
if (!digitalRead(BTN_PIN)) {
lampuState = !lampuState;
delay(300);
}
TempAndHumidity data = dht.getTempAndHumidity();
float suhu = data.temperature;
float hum = data.humidity;
float level = jarakAir();
// ====== LOGIKA OTOMATIS ======
if (level >= 80) pompaState = false;
if (level < 40) pompaState = true;
if (suhu > 32) kipasState = true;
if (suhu < 30) kipasState = false;
if (suhu < 20) pemanasState = true;
if (suhu > 25) pemanasState = false;
// ===== OUTPUT RELAY =====
digitalWrite(RELAY_LAMPU, lampuState);
digitalWrite(RELAY_POMPA, pompaState);
digitalWrite(RELAY_PEMANAS, pemanasState);
digitalWrite(RELAY_KIPAS, kipasState);
digitalWrite(RELAY_ALARM, alarmState);
// ===== MQTT PUBLISH =====
client.publish("sabet/iot/suhu", String(suhu).c_str());
client.publish("sabet/iot/kelembaban", String(hum).c_str());
client.publish("sabet/iot/levelair", String(level).c_str());
client.publish("sabet/iot/gerak", gerak ? "Ada Orang" : "Tidak Ada Orang");
client.publish("sabet/iot/lampu/status", lampuState ? "ON" : "OFF");
client.publish("sabet/iot/pompa/status", pompaState ? "ON" : "OFF");
client.publish("sabet/iot/pemanas/status", pemanasState ? "ON" : "OFF");
client.publish("sabet/iot/kipas/status", kipasState ? "ON" : "OFF");
client.publish("sabet/iot/alarm/status", alarmState ? "ON" : "OFF");
// =========================
// SERIAL PRINT MODERN
// =========================
Serial.println("┌──────────────────────────────────────────────┐");
Serial.println("│ MONITORING RUMAH PINTAR - MQTT │");
Serial.println("└──────────────────────────────────────────────┘");
Serial.println();
Serial.println("🏠 Status Ruangan:");
Serial.print(" Suhu : "); Serial.print(suhu); Serial.println(" °C");
Serial.print(" Kelembaban : "); Serial.print(hum); Serial.println(" %");
Serial.print(" Level Air : "); Serial.print(level); Serial.println(" cm");
Serial.print(" Gerakan : "); Serial.println(gerak ? "Ada Orang 👤" : "Tidak Ada Orang ❌");
Serial.println();
Serial.println("💡 Aktuator:");
Serial.print(" Lampu : "); Serial.println(lampuState ? "ON 🔆" : "OFF 🌑");
Serial.print(" Pompa : "); Serial.println(pompaState ? "ON 💧" : "OFF ❌");
Serial.print(" Kipas : "); Serial.println(kipasState ? "ON 🌀" : "OFF ❌");
Serial.print(" Pemanas : "); Serial.println(pemanasState ? "ON 🔥" : "OFF ❌");
Serial.print(" Alarm : "); Serial.println(alarmState ? "ON 🚨" : "OFF ❌");
delay(2000);
}