#include <WiFi.h>
#include <UniversalTelegramBot.h>
#include <ArduinoJson.h>
#include <DHT.h>
#include <WiFiClientSecure.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define BOT_TOKEN "6003355104:AAFIJy5IMZXX2n9mHkDbS8IES2JMMr-C-zY"
#define CHAT_ID "6638725491"
#define WIFI_SSID "Wokwi-GUEST"
#define WIFI_PASSWORD ""
#define MIN_MOISTURE_THRESHOLD 58
#define DHTPIN 4
#define DHTTYPE DHT11
#define SOIL_MOISTURE_PIN 34
#define RELAY_PIN 25
#define NO_SENSOR_CONNECTION 16 // kondisi batas tidak koneksi alat sensor
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
DHT dht(DHTPIN, DHTTYPE);
WiFiClientSecure client;
UniversalTelegramBot bot(BOT_TOKEN, client);
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
float moisturePercentage;
bool shouldWater = false;
bool isConnected = false;
bool sensorConnected = true;
bool manualControl = false; // Manual control flag
void displayStatus() {
float h = dht.readHumidity();
float t = dht.readTemperature();
String moistureMsg = (moisturePercentage > MIN_MOISTURE_THRESHOLD) ? "KERING" : "BASAH";
String relayStatus = digitalRead(RELAY_PIN) == HIGH ? "ON" : "OFF";
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0, 0);
display.print("Temp: ");
display.print(t);
display.println(" C");
display.print("Humidity: ");
display.print(h);
display.println(" %");
display.print("Soil: ");
display.print(moisturePercentage);
display.println(" %");
display.print("Status: ");
display.print(moistureMsg);
display.print("\nRelay: ");
display.println(relayStatus);
display.display();
}
void analogSense() {
if (manualControl) return; // lewati moisture check jika di manual control mode
float soil = analogRead(SOIL_MOISTURE_PIN);
moisturePercentage = (soil / 4095) * 100;
String msg = (moisturePercentage > MIN_MOISTURE_THRESHOLD) ? "KERING" : "BASAH";
if (moisturePercentage <= NO_SENSOR_CONNECTION) {
sensorConnected = false;
Serial.println("Sensor tidak terhubung atau rusak");
Serial.print(moisturePercentage);
digitalWrite(RELAY_PIN, LOW);
if (isConnected) {
bot.sendMessage(CHAT_ID, "⚠️ Sensor kelembaban tanah tidak terhubung atau rusak,", "");
}
displayStatus();
} else {
sensorConnected = true;
if (moisturePercentage > MIN_MOISTURE_THRESHOLD) {
shouldWater = true;
if (isConnected) {
bot.sendMessage(CHAT_ID, String(msg) + "🚿 Mulai siram...");
}
} else {
shouldWater = false;
}
displayStatus();
}
}
void handleMessage(int numNewMessages) {
for (int i = 0; i < numNewMessages; i++) {
String chat_id = String(bot.messages[i].chat_id);
String text = bot.messages[i].text;
String from_name = bot.messages[i].from_name;
if (text == "/start") {
String welcome = "🌈🌳Selamat datang di Kebun Pintar " + from_name + ".\n";
welcome += "🌟 KLIK MENU AKSI 🌟\n\n";
welcome += "💧 /siram - siram manual jika sensor tidak berfungsi\n";
welcome += "🚫 /stop_siram - stop siram manual\n";
welcome += "📊 /status_sensor - lihat status sensor\n";
welcome += "🔌 /status_koneksi - lihat status koneksi\n";
bot.sendMessage(chat_id, welcome);
}
if (chat_id == CHAT_ID) {
if (text == "/status_sensor") {
float h = dht.readHumidity();
float t = dht.readTemperature();
int soilMoistureValue = analogRead(SOIL_MOISTURE_PIN);
int moisturePercentage = map(soilMoistureValue, 0, 4095, 0, 100);
String relayStatus = digitalRead(RELAY_PIN) == HIGH ? "ON" : "OFF";
String message;
if (isnan(h) || isnan(t)) {
message = "⚠️ Sensor DHT11 tidak terhubung atau rusak!";
if (isConnected) {
bot.sendMessage(CHAT_ID, message, "");
}
Serial.println(message);
}
if (!sensorConnected) {
message = "⚠️ Sensor Kelembaban tidak terhubung atau rusak!";
if (isConnected) {
bot.sendMessage(CHAT_ID, message, "");
}
Serial.println(message);
} else {
String msg = (moisturePercentage > MIN_MOISTURE_THRESHOLD) ? "KERING" : "BASAH";
message = "🌡️ Temperatur: " + String(t) + "°C\n";
message += "💧 Kelembaban tanah: " + String(msg) + "\n";
message += "🌫️ Kelembaban udara: " + String(h) + "%\n";
message += "🚰 Status relay pompa: " + relayStatus;
bot.sendMessage(CHAT_ID, message, "");
}
} else if (text == "/siram") {
if (!sensorConnected) {
manualControl = true;
shouldWater = true;
digitalWrite(RELAY_PIN, HIGH);
Serial.print("siram pompa on");
String relayStatus = digitalRead(RELAY_PIN) == HIGH ? "ON" : "OFF";
bot.sendMessage(CHAT_ID, "🚿 Mulai siram... pompa " + relayStatus, "");
} else {
bot.sendMessage(CHAT_ID, "⚠️ Perintah /siram hanya digunakan jika sensor kelembaban tidak terhubung atau rusak.", "");
}
} else if (text == "/stop_siram") {
if (!sensorConnected) {
manualControl = false;
shouldWater = false;
digitalWrite(RELAY_PIN, LOW);
Serial.print("stop siram");
String relayStatus = digitalRead(RELAY_PIN) == HIGH ? "ON" : "OFF";
bot.sendMessage(CHAT_ID, "🛑 Berhenti siram... pompa " + relayStatus, "");
} else {
bot.sendMessage(CHAT_ID, "⚠️ Perintah /stop_siram hanya dapat digunakan jika sensor kelembaban tidak terhubung atau rusak.", "");
}
} else if (text == "/status_koneksi") {
String statusMessage = isConnected ? " 🛰 Device online dan terkoneksi ke WiFi🛰." : "Device offline, tidak terkoneksi ke WiFi.";
bot.sendMessage(CHAT_ID, statusMessage, "");
}
}
}
}
void setup() {
client.setTimeout(2000);
client.setCACert(TELEGRAM_CERTIFICATE_ROOT);
Serial.begin(115200);
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
dht.begin();
pinMode(RELAY_PIN, OUTPUT);
digitalWrite(RELAY_PIN, LOW);
// Initialize OLED display
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("SSD1306 allocation failed"));
for (;;) ;
}
display.clearDisplay();
display.display();
// Attempt to connect to WiFi
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Connecting to WiFi...");
}
Serial.println("Connected to WiFi");
isConnected = true;
bot.sendMessage(CHAT_ID, "🌈 Halo.. BOT dimulai karena alat penyiraman anda aktif dan koneksi internet. Ketik /start untuk menu.");
}
void loop() {
analogSense(); // cek sensor kontinue
if (WiFi.status() == WL_CONNECTED) {
if (!isConnected) {
isConnected = true;
String ssid = WiFi.SSID();
bot.sendMessage(CHAT_ID, "🛰 Bot terkoneksi ke WiFi: " + ssid, "");
}
int numNewMessages = bot.getUpdates(bot.last_message_received + 1);
if (numNewMessages) {
handleMessage(numNewMessages);
}
} else {
if (isConnected) {
isConnected = false;
Serial.println("Gagal koneksi ke internet, sensor tetap running");
}
}
if (shouldWater) {
digitalWrite(RELAY_PIN, HIGH);
} else {
digitalWrite(RELAY_PIN, LOW);
}
displayStatus(); // Update OLED display
}