#include #include #include #include #include #include #include #include #include #include #include // ========== Konfigurasi ========== #define BOTtoken "7612422633:AAH898XXBYw1Ys0gMFrjoDXuq32EVZjw_c8" #define DHTPIN 4 #define DHTTYPE DHT11 #define SERVO_PIN 15 // ========== Inisialisasi ========== WiFiClientSecure client; UniversalTelegramBot bot(BOTtoken, client); DHT dht(DHTPIN, DHTTYPE); Servo servo; LiquidCrystal_I2C lcd(0x27, 16, 2); WiFiUDP ntpUDP; NTPClient timeClient(ntpUDP, "pool.ntp.org", 25200); // GMT+7 // ========== Variabel ========== String scheduledTime = ""; // Format "HH:mm" bool autoSend = false; unsigned long lastTime = 0; unsigned long timerDelay = 2000; bool sudahBeriHariIni = false; int lastDay = -1; String lastChatId = ""; // ========== Setup ========== void setup() { Serial.begin(115200); lcd.init(); lcd.backlight(); lcd.setCursor(0, 0); lcd.print("Smart Feeder"); lcd.setCursor(0, 1); lcd.print("Loading WiFi..."); dht.begin(); servo.attach(SERVO_PIN); servo.write(0); // Pastikan tertutup delay(500); WiFiManager wifiManager; wifiManager.autoConnect("SmartFeederAP"); lcd.clear(); lcd.setCursor(0, 0); lcd.print("WiFi Connected"); lcd.setCursor(0, 1); lcd.print(WiFi.localIP().toString()); client.setCACert(TELEGRAM_CERTIFICATE_ROOT); timeClient.begin(); delay(2000); lcd.clear(); } // ========== Loop ========== void loop() { timeClient.update(); String currentTime = timeClient.getFormattedTime().substring(0, 5); int currentDay = timeClient.getDay(); if (scheduledTime != "" && currentTime == scheduledTime && !sudahBeriHariIni) { Serial.println("⏰ Saatnya memberi pakan otomatis!"); bukaPakanOtomatis(); sudahBeriHariIni = true; lastDay = currentDay; } if (currentDay != lastDay) sudahBeriHariIni = false; if (autoSend && (millis() - lastTime > timerDelay)) { kirimDataDHT(lastChatId); lastTime = millis(); } updateLCD(); int numNewMessages = bot.getUpdates(bot.last_message_received + 1); while (numNewMessages) { handleNewMessages(numNewMessages); numNewMessages = bot.getUpdates(bot.last_message_received + 1); } } // ========== LCD ========== void updateLCD() { float h = dht.readHumidity(); float t = dht.readTemperature(); lcd.clear(); if (isnan(h) || isnan(t)) { lcd.setCursor(0, 0); lcd.print("Sensor error!"); } else { lcd.setCursor(0, 0); lcd.print("T:"); lcd.print(t, 1); lcd.print("C H:"); lcd.print(h, 0); lcd.print("%"); } lcd.setCursor(0, 1); if (scheduledTime == "") { lcd.print("Jadwal: - "); } else { lcd.print("Jadwal:"); lcd.print(scheduledTime); } } // ========== Handle Pesan ========== void handleNewMessages(int numNewMessages) { for (int i = 0; i < numNewMessages; i++) { String chat_id = bot.messages[i].chat_id; String text = bot.messages[i].text; lastChatId = chat_id; if (text == "/start") { String msg = "👋 Hai! Selamat datang di Smart Feeder 🐣\n\n" "📌 Perintah:\n" "📊 /status — Cek suhu & kelembaban\n" "📡 /mulai — Aktifkan monitoring\n" "🛑 /berhenti — Stop monitoring\n" "🍽 /bukapakan — Buka pakan\n" "🔒 /tutuppakan — Tutup pakan\n" "⏰ /setjadwal HH:mm — Atur jadwal\n" "📆 /jadwal — Cek jadwal\n" "🗑 /hapusjadwal — Hapus jadwal"; bot.sendMessage(chat_id, msg, "Markdown"); } else if (text == "/status") { kirimDataDHT(chat_id); } else if (text == "/mulai") { autoSend = true; bot.sendMessage(chat_id, "✅ Monitoring otomatis aktif.", "Markdown"); } else if (text == "/berhenti") { autoSend = false; bot.sendMessage(chat_id, "🛑 Monitoring otomatis berhenti.", "Markdown"); } else if (text == "/bukapakan") { bukaPakan(); bot.sendMessage(chat_id, "🍽 Pakan diberikan.", "Markdown"); } else if (text == "/tutuppakan") { servo.write(0); bot.sendMessage(chat_id, "🔒 Pakan ditutup.", "Markdown"); } else if (text.startsWith("/setjadwal ")) { String jam = text.substring(11); if (jam.length() == 5 && jam.charAt(2) == ':') { scheduledTime = jam; bot.sendMessage(chat_id, "⏰ Jadwal diatur ke " + jam + "", "Markdown"); } else { bot.sendMessage(chat_id, "⚠ Format salah. Gunakan /setjadwal HH:mm", "Markdown"); } } else if (text == "/jadwal") { if (scheduledTime != "") { bot.sendMessage(chat_id, "📆 Jadwal aktif: " + scheduledTime + "", "Markdown"); } else { bot.sendMessage(chat_id, "⚠ Jadwal belum diatur.", "Markdown"); } } else if (text == "/hapusjadwal") { scheduledTime = ""; bot.sendMessage(chat_id, "🗑 Jadwal dihapus.", "Markdown"); } else { bot.sendMessage(chat_id, "❓ Perintah tidak dikenali. Gunakan /start.", "Markdown"); } } } // ========== Fungsi Servo ========== void bukaPakan() { Serial.println("🔓 Membuka pakan..."); servo.write(90); // Buka delay(5000); // Tunggu 5 detik servo.write(0); // Tutup kembali Serial.println("🔒 Pakan ditutup."); } void bukaPakanOtomatis() { bukaPakan(); if (lastChatId != "") { bot.sendMessage(lastChatId, "🍽 Pakan otomatis diberikan pada " + scheduledTime, "Markdown"); } } void kirimDataDHT(String chat_id) { float h = dht.readHumidity(); float t = dht.readTemperature(); if (isnan(h) || isnan(t)) return; String msg = "📊 Data Sensor:\n" "🌡 Suhu: " + String(t) + "°C\n" "💧 Kelembaban: " + String(h) + "%"; bot.sendMessage(chat_id, msg, "Markdown"); }