232 lines
8.1 KiB
C++
232 lines
8.1 KiB
C++
#include <Wire.h>
|
|
#include "RTClib.h"
|
|
#include <WiFi.h>
|
|
#include <NTPClient.h>
|
|
#include <WiFiUdp.h>
|
|
#include <WiFiClientSecure.h>
|
|
#include <UniversalTelegramBot.h>
|
|
|
|
RTC_DS3231 rtc;
|
|
|
|
// Pin relay
|
|
const int relayPin = 15;
|
|
|
|
// Waktu untuk mematikan relay
|
|
const int relayOffHour[2] = {8, 16};
|
|
const int relayOffMinute[2] = {0, 0};
|
|
int relayDuration = 10;
|
|
bool relayTriggered[2] = {false, false};
|
|
|
|
// Definisikan NTP Client untuk sinkronisasi waktu
|
|
WiFiUDP ntpUDP;
|
|
NTPClient timeClient(ntpUDP, "pool.ntp.org", 7 * 3600);
|
|
|
|
// Pin untuk sensor kelembaban tanah
|
|
const int soilMoisturePin = 34;
|
|
|
|
// Pin untuk sensor water level
|
|
const int waterLevelPin = 32;
|
|
|
|
// Kalibrasi sensor kelembaban tanah
|
|
const int airValue = 4095;
|
|
const int waterValue = 600;
|
|
|
|
// Kalibrasi sensor water level
|
|
const int emptyLevelValue = 420; // Nilai analog ketika tangki kosong (sesuaikan dengan pengukuran)
|
|
const int fullLevelValue = 1260; // Nilai analog ketika tangki penuh (sesuaikan dengan pengukuran)
|
|
|
|
// Inisialisasi objek bot Telegram
|
|
#define BOT_TOKEN "7384958342:AAH6j5ozS6bZ3YL2iZ9RLpwU-wOe3jjBpjc"
|
|
#define CHAT_ID "1351963764"
|
|
WiFiClientSecure client;
|
|
UniversalTelegramBot bot(BOT_TOKEN, client);
|
|
|
|
unsigned long lastTimeBotRan;
|
|
unsigned long lastRelayCheck = 0;
|
|
bool relayState = HIGH;
|
|
bool manualRelayRequest = false;
|
|
unsigned long manualRelayStartTime = 0;
|
|
int manualRelayDuration = 0;
|
|
|
|
void sendTelegramMessage(String message) {
|
|
bot.sendMessage(CHAT_ID, message, "");
|
|
}
|
|
|
|
// Fungsi untuk membaca kelembaban tanah
|
|
int readSoilMoisture() {
|
|
int soilMoistureValue = analogRead(soilMoisturePin);
|
|
int moisturePercentage = map(soilMoistureValue, airValue, waterValue, 0, 100);
|
|
moisturePercentage = constrain(moisturePercentage, 0, 100);
|
|
return moisturePercentage;
|
|
}
|
|
|
|
// Fungsi untuk membaca level air
|
|
int readWaterLevel() {
|
|
int waterLevelValue = analogRead(waterLevelPin);
|
|
// Kalibrasi nilai level air jika diperlukan
|
|
int levelPercentage = map(waterLevelValue, emptyLevelValue, fullLevelValue, 0, 100);
|
|
levelPercentage = constrain(levelPercentage, 0, 100);
|
|
return levelPercentage;
|
|
}
|
|
|
|
void setup() {
|
|
Serial.begin(115200);
|
|
pinMode(relayPin, OUTPUT);
|
|
digitalWrite(relayPin, HIGH);
|
|
pinMode(soilMoisturePin, INPUT);
|
|
pinMode(waterLevelPin, INPUT);
|
|
|
|
if (!rtc.begin()) {
|
|
Serial.println("RTC tidak ditemukan!");
|
|
while (1);
|
|
}
|
|
if (rtc.lostPower()) {
|
|
Serial.println("RTC kehilangan daya, mengatur ulang waktu!");
|
|
}
|
|
|
|
// Hubungkan ke WiFi
|
|
WiFi.begin("GenZ", "12345678");
|
|
while (WiFi.status() != WL_CONNECTED) {
|
|
delay(1000);
|
|
Serial.println("Connecting to WiFi...");
|
|
}
|
|
Serial.println("Connected to WiFi");
|
|
|
|
// Mulai NTP client dan sinkronisasi waktu
|
|
timeClient.begin();
|
|
while (!timeClient.update()) {
|
|
timeClient.forceUpdate();
|
|
}
|
|
rtc.adjust(DateTime(timeClient.getEpochTime()));
|
|
|
|
client.setCACert(TELEGRAM_CERTIFICATE_ROOT); // Add root certificate for api.telegram.org
|
|
lastTimeBotRan = millis();
|
|
}
|
|
|
|
void handleNewMessages(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, " + from_name + ".\n";
|
|
welcome += "Gunakan perintah berikut untuk mendapatkan nilai sensor atau mengatur durasi relay:\n";
|
|
welcome += "/waterlevel - untuk mendapatkan nilai sensor level air\n";
|
|
welcome += "/soilmoisture - untuk mendapatkan nilai sensor kelembaban tanah\n";
|
|
welcome += "/set10s - untuk mengatur durasi relay menjadi 10 detik\n";
|
|
welcome += "/set15s - untuk mengatur durasi relay menjadi 15 detik\n";
|
|
welcome += "/set20s - untuk mengatur durasi relay menjadi 20 detik\n";
|
|
welcome += "/manualon - untuk menyalakan relay secara manual\n";
|
|
welcome += "/manualoff - untuk mematikan relay secara manual\n";
|
|
bot.sendMessage(chat_id, welcome, "");
|
|
} else if (text == "/waterlevel") {
|
|
int levelPercentage = readWaterLevel();
|
|
String message;
|
|
if (levelPercentage < 20) {
|
|
message = "Peringatan! Level air sangat rendah: " + String(levelPercentage) + "%. Segera isi ulang!";
|
|
} else if (levelPercentage < 50) {
|
|
message = "Level air rendah: " + String(levelPercentage) + "%. ketinggian air sedang.";
|
|
} else if (levelPercentage < 80) {
|
|
message = "Level air cukup: " + String(levelPercentage) + "%. ketinggian air aman.";
|
|
} else {
|
|
message = "Level air tinggi: " + String(levelPercentage) + "%. Tidak perlu tindakan.";
|
|
}
|
|
bot.sendMessage(chat_id, message, "");
|
|
} else if (text == "/soilmoisture") {
|
|
int moisturePercentage = readSoilMoisture();
|
|
String message;
|
|
if (moisturePercentage < 20) {
|
|
message = "Peringatan! Kelembaban tanah sangat rendah: " + String(moisturePercentage) + "%. Segera siram!";
|
|
} else if (moisturePercentage < 50) {
|
|
message = "Kelembaban tanah rendah: " + String(moisturePercentage) + "%. Periksa ketersediaan air.";
|
|
} else if (moisturePercentage < 80) {
|
|
message = "Kelembaban tanah cukup: " + String(moisturePercentage) + "%. Kondisi baik.";
|
|
} else {
|
|
message = "Kelembaban tanah tinggi: " + String(moisturePercentage) + "%. Tidak perlu tindakan.";
|
|
}
|
|
bot.sendMessage(chat_id, message, "");
|
|
} else if (text == "/set10s") {
|
|
relayDuration = 10;
|
|
bot.sendMessage(chat_id, "Durasi relay telah diatur menjadi 10 detik", "");
|
|
} else if (text == "/set15s") {
|
|
relayDuration = 15;
|
|
bot.sendMessage(chat_id, "Durasi relay telah diatur menjadi 15 detik", "");
|
|
} else if (text == "/set20s") {
|
|
relayDuration = 20;
|
|
bot.sendMessage(chat_id, "Durasi relay telah diatur menjadi 20 detik", "");
|
|
} else if (text == "/manualon") {
|
|
manualRelayRequest = true;
|
|
manualRelayDuration = relayDuration; // Gunakan durasi yang sudah ditentukan
|
|
manualRelayStartTime = millis();
|
|
bot.sendMessage(chat_id, "Relay telah dinyalakan secara manual selama " + String(manualRelayDuration) + " detik", "");
|
|
} else if (text == "/manualoff") {
|
|
digitalWrite(relayPin, HIGH);
|
|
relayState = HIGH;
|
|
manualRelayRequest = false;
|
|
bot.sendMessage(chat_id, "Relay telah dimatikan secara manual", "");
|
|
} else {
|
|
String message = "Perintah tidak dikenal. Gunakan /start untuk melihat perintah yang tersedia.";
|
|
bot.sendMessage(chat_id, message, "");
|
|
}
|
|
}
|
|
}
|
|
|
|
void loop() {
|
|
DateTime now = rtc.now();
|
|
Serial.print("Waktu sekarang: ");
|
|
Serial.print(now.hour());
|
|
Serial.print(':');
|
|
Serial.print(now.minute());
|
|
Serial.print(':');
|
|
Serial.println(now.second());
|
|
|
|
int moisturePercentage = readSoilMoisture();
|
|
Serial.print("Kelembaban Tanah: ");
|
|
Serial.print(moisturePercentage);
|
|
Serial.println("%");
|
|
|
|
int levelPercentage = readWaterLevel();
|
|
Serial.print("Level Air: ");
|
|
Serial.print(levelPercentage);
|
|
Serial.println("%");
|
|
|
|
if (manualRelayRequest) {
|
|
if (millis() - manualRelayStartTime < manualRelayDuration * 1000) {
|
|
digitalWrite(relayPin, LOW);
|
|
relayState = LOW;
|
|
} else {
|
|
digitalWrite(relayPin, HIGH);
|
|
relayState = HIGH;
|
|
manualRelayRequest = false;
|
|
}
|
|
} else {
|
|
if (millis() - lastRelayCheck >= 1000) { // Periksa relay setiap detik
|
|
for (int i = 0; i < 2; i++) {
|
|
if (now.hour() == relayOffHour[i] && now.minute() == relayOffMinute[i] && !relayTriggered[i]) {
|
|
Serial.println("Mematikan relay...");
|
|
digitalWrite(relayPin, LOW);
|
|
relayState = LOW;
|
|
relayTriggered[i] = true; // Set relay as triggered for this time slot
|
|
lastRelayCheck = millis();
|
|
}
|
|
}
|
|
if (relayState == LOW && (millis() - lastRelayCheck >= relayDuration * 1000)) {
|
|
Serial.println("Menyalakan relay...");
|
|
digitalWrite(relayPin, HIGH);
|
|
relayState = HIGH;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Periksa pesan baru dari bot Telegram setiap 1 detik
|
|
if (millis() - lastTimeBotRan > 1000) {
|
|
int numNewMessages = bot.getUpdates(bot.last_message_received + 1);
|
|
while (numNewMessages) {
|
|
handleNewMessages(numNewMessages);
|
|
numNewMessages = bot.getUpdates(bot.last_message_received + 1);
|
|
}
|
|
lastTimeBotRan = millis();
|
|
}
|
|
}
|