#include <WiFi.h>
#include <WiFiClientSecure.h>
#include <UniversalTelegramBot.h>
#include <DHT.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
// DHT Sensor setup
#define DHTPIN 23 // Pin connected to DHT sensor
#define DHTTYPE DHT22 // Type of DHT sensor (DHT11 or DHT22)
// LCD I2C address and size
const int lcdAddress = 0x27; // Adjust to your LCD I2C address
const int lcdColumns = 16;
const int lcdRows = 2;
// Wi-Fi credentials
char ssid[] = "Wokwi-GUEST";
char password[] = "";
// Telegram bot token
#define BOTtoken "7705302352:AAEwXE7dGlUB5l94drJV489XPwhuO0u_TMg"
// DHT and LCD setup
DHT dht(DHTPIN, DHTTYPE);
LiquidCrystal_I2C lcd(lcdAddress, lcdColumns, lcdRows);
// Wi-Fi and Telegram bot setup
WiFiClientSecure client;
UniversalTelegramBot bot(BOTtoken, client);
// LED pin and state
const int ledPin = 2;
bool ledState = LOW;
// Threshold values
const float humidityThreshold = 55.0;
const float temperatureThreshold = 30.0;
// Timing settings
int botRequestDelay = 1000;
unsigned long lastTimeBotRan;
unsigned long lastNotificationTime = 0;
const unsigned long notificationInterval = 60000; // 1 minute interval for notifications
// Data kelembaban untuk prediksi SMA
float humidityData[5] = {50, 53, 54, 52, 58}; // Data kelembaban 5 hari terakhir
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 (from_name == "") from_name = "Guest";
// Command to get temperature
if (text == "/statussuhu") {
float temperature = dht.readTemperature();
String tempMessage = isnan(temperature) ?
"Failed to read temperature." :
"Suhu saat ini: " + String(temperature) + " °C";
bot.sendMessage(chat_id, tempMessage, "");
}
// Command to get humidity
if (text == "/statuskelembapan") {
float humidity = dht.readHumidity();
String humidityMessage = isnan(humidity) ?
"Failed to read humidity." :
"Kelembaban saat ini: " + String(humidity) + " %";
bot.sendMessage(chat_id, humidityMessage, "");
}
// Commands to control LED
if (text == "/ledon") {
bot.sendMessage(chat_id, "LED dinyalakan", "");
ledState = HIGH;
digitalWrite(ledPin, ledState);
}
if (text == "/ledoff") {
bot.sendMessage(chat_id, "LED dimatikan", "");
ledState = LOW;
digitalWrite(ledPin, ledState);
}
if (text == "/statusLED") {
String ledStatus = digitalRead(ledPin) ? "LED menyala" : "LED mati";
bot.sendMessage(chat_id, ledStatus, "");
}
// Start command with list of all available commands
if (text == "/start") {
String welcome = "Welcome " + from_name + ".\n";
welcome += "/statussuhu : Status Suhu\n";
welcome += "/statuskelembapan : Status Kelembapan\n";
welcome += "Gunakan perintah berikut untuk LED.\n";
welcome += "/ledon untuk menghidupkan LED\n";
welcome += "/ledoff untuk mematikan LED\n";
welcome += "/statusLED untuk mengetahui kondisi LED\n";
bot.sendMessage(chat_id, welcome, "Markdown");
}
}
}
// Fungsi untuk menghitung prediksi kelembaban menggunakan Simple Moving Average (SMA)
float predictHumidity() {
float sum = 0;
for (int i = 0; i < 5; i++) {
sum += humidityData[i];
}
return sum / 5; // Rata-rata dari 5 data terakhir
}
// Fungsi untuk menghitung persentase error antara nilai prediksi dan aktual
float calculateError(float actual, float predicted) {
return abs((actual - predicted) / actual) * 100;
}
void setup() {
Serial.begin(115200);
// DHT and LCD initialization
dht.begin();
lcd.init();
lcd.backlight();
// LED pin initialization
pinMode(ledPin, OUTPUT);
digitalWrite(ledPin, ledState);
// Wi-Fi connection
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
Serial.print("Connecting to Wi-Fi...");
while (WiFi.status() != WL_CONNECTED) {
Serial.print(".");
delay(500);
}
Serial.println("\nWiFi connected. IP address: ");
Serial.println(WiFi.localIP());
client.setInsecure(); // Connect to Telegram without certificate
}
void loop() {
// Display temperature and humidity on LCD
float temperature = dht.readTemperature();
float humidity = dht.readHumidity();
lcd.setCursor(0, 0);
lcd.print("Suhu: ");
lcd.print(isnan(temperature) ? "Error" : String(temperature) + "C");
lcd.setCursor(0, 1);
lcd.print("Lembab: ");
lcd.print(isnan(humidity) ? "Error" : String(humidity) + "%");
// Prediksi kelembaban hari berikutnya
float predictedHumidity = predictHumidity();
float error = calculateError(humidity, predictedHumidity);
// Tampilkan nilai aktual, prediksi, dan error di Serial Monitor
Serial.print("Nilai Aktual Kelembaban: ");
Serial.print(isnan(humidity) ? "Error" : String(humidity) + " %");
Serial.print(" | Nilai Prediksi Kelembaban: ");
Serial.print(String(predictedHumidity) + " %");
Serial.print(" | Error: ");
Serial.print(isnan(humidity) ? "Error" : String(error) + " %");
Serial.println();
// Cek apakah prediksi kelembaban melebihi threshold
if (predictedHumidity > humidityThreshold) {
String warningMessage = "Peringatan! Prediksi kelembaban melebihi batas:\n";
warningMessage += "Kelembaban Prediksi: " + String(predictedHumidity) + "%\n";
warningMessage += "Batas Kelembaban: " + String(humidityThreshold) + "%\n";
bot.sendMessage(String(bot.messages[0].chat_id), warningMessage, "");
// Matikan LED sebagai representasi server yang dimatikan
ledState = LOW;
digitalWrite(ledPin, ledState);
// Kirim pesan ke Telegram bahwa server telah dimatikan
bot.sendMessage(String(bot.messages[0].chat_id), "Server (LED) dimatikan otomatis karena prediksi kelembaban melebihi batas.", "");
}
// Update data kelembaban untuk prediksi SMA (geser data ke kiri dan tambahkan data terbaru)
for (int i = 0; i < 4; i++) {
humidityData[i] = humidityData[i + 1];
}
humidityData[4] = humidity; // Tambahkan data terbaru di posisi terakhir
// Handle Telegram bot messages every botRequestDelay interval
if (millis() > lastTimeBotRan + botRequestDelay) {
int numNewMessages = bot.getUpdates(bot.last_message_received + 1);
while (numNewMessages) {
handleNewMessages(numNewMessages);
numNewMessages = bot.getUpdates(bot.last_message_received + 1);
}
lastTimeBotRan = millis();
}
delay(3000);
}