#include <WiFi.h>
#include <PubSubClient.h>
#include <DHTesp.h>
DHTesp dht;
// Pin Sensor & Aktuator
#define DHT_PIN 4
#define TRIG_PIN 5
#define ECHO_PIN 18
#define PIR_PIN 21
#define BTN_PIN 27
#define RELAY_LAMPU 12
#define RELAY_POMPA 13
#define RELAY_ALARM 14
// WIFI
const char* ssid = "Wokwi-GUEST";
const char* password = "";
// MQTT BROKER
const char* mqtt_server = "test.mosquitto.org";
WiFiClient esp;
PubSubClient client(esp);
unsigned long lastMovement = 0;
bool lampuState = false;
bool pompaState = false;
bool alarmState = false;
// ---------------- WIFI ----------------
void setup_wifi() {
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) delay(300);
}
// ---------------- MQTT CALLBACK ----------------
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");
digitalWrite(RELAY_LAMPU, lampuState ? LOW : HIGH);
client.publish("sabet/iot/lampu/status", lampuState ? "ON" : "OFF");
}
if (String(topic) == "sabet/iot/pompa/cmd") {
pompaState = (msg == "ON");
digitalWrite(RELAY_POMPA, pompaState ? LOW : HIGH);
client.publish("sabet/iot/pompa/status", pompaState ? "ON" : "OFF");
}
if (String(topic) == "sabet/iot/alarm/cmd") {
alarmState = (msg == "ON");
digitalWrite(RELAY_ALARM, alarmState ? HIGH : LOW);
client.publish("sabet/iot/alarm/status", alarmState ? "ON" : "OFF");
}
}
// ---------------- MQTT RECONNECT ----------------
void reconnect() {
while (!client.connected()) {
if (client.connect("ESP32-Rumah")) {
client.subscribe("sabet/iot/lampu/cmd");
client.subscribe("sabet/iot/pompa/cmd");
client.subscribe("sabet/iot/alarm/cmd");
} else delay(1000);
}
}
// ---------------- LEVEL AIR ----------------
int hitungLevelAir() {
digitalWrite(TRIG_PIN, LOW);
delayMicroseconds(2);
digitalWrite(TRIG_PIN, HIGH);
delayMicroseconds(10);
digitalWrite(TRIG_PIN, LOW);
long durasi = pulseIn(ECHO_PIN, HIGH);
float jarak = durasi * 0.034 / 2;
return jarak;
}
// ---------------- SETUP ----------------
void setup() {
Serial.begin(115200);
dht.setup(DHT_PIN, DHTesp::DHT22);
pinMode(TRIG_PIN, OUTPUT);
pinMode(ECHO_PIN, INPUT);
pinMode(PIR_PIN, INPUT);
pinMode(BTN_PIN, INPUT_PULLUP);
pinMode(RELAY_LAMPU, OUTPUT);
pinMode(RELAY_POMPA, OUTPUT);
pinMode(RELAY_ALARM, OUTPUT);
digitalWrite(RELAY_LAMPU, HIGH);
digitalWrite(RELAY_POMPA, HIGH);
digitalWrite(RELAY_ALARM, LOW);
setup_wifi();
client.setServer(mqtt_server, 1883);
client.setCallback(callback);
}
// ---------------- LOOP ----------------
void loop() {
if (!client.connected()) reconnect();
client.loop();
// ==== SENSOR SUHU ====
TempAndHumidity data = dht.getTempAndHumidity();
client.publish("sabet/iot/suhu", String(data.temperature).c_str());
client.publish("sabet/iot/kelembaban", String(data.humidity).c_str());
// ==== LEVEL AIR ====
int level = hitungLevelAir();
client.publish("sabet/iot/levelair", String(level).c_str());
// ==== SENSOR GERAK ====
bool gerak = digitalRead(PIR_PIN);
client.publish("sabet/iot/gerak", gerak ? "Ada Orang" : "Tidak Ada");
// ---- Lampu auto ON jika ada orang ----
if (gerak) {
lampuState = true;
digitalWrite(RELAY_LAMPU, LOW);
client.publish("sabet/iot/lampu/status", "ON");
lastMovement = millis();
}
// ---- Lampu auto OFF setelah 10 detik tidak ada orang ----
if (!gerak && millis() - lastMovement > 10000) {
lampuState = false;
digitalWrite(RELAY_LAMPU, HIGH);
client.publish("sabet/iot/lampu/status", "OFF");
}
// ---- Tombol Manual Lampu ----
if (!digitalRead(BTN_PIN)) {
lampuState = !lampuState;
digitalWrite(RELAY_LAMPU, lampuState ? LOW : HIGH);
client.publish("sabet/iot/lampu/status", lampuState ? "ON" : "OFF");
delay(300);
}
// ==== Pompa otomatis ====
if (level >= 80) pompaState = false;
if (level < 40) pompaState = true;
digitalWrite(RELAY_POMPA, pompaState ? LOW : HIGH);
client.publish("sabet/iot/pompa/status", pompaState ? "ON" : "OFF");
delay(300);
}