Upload files to "/"
This commit is contained in:
parent
366a49907f
commit
7ace429544
|
|
@ -0,0 +1,318 @@
|
|||
#include <Wire.h>
|
||||
#include "Adafruit_SHT31.h"
|
||||
#include <WiFi.h>
|
||||
#include <Firebase_ESP_Client.h>
|
||||
#include <RTClib.h>
|
||||
|
||||
// ================= WIFI =================
|
||||
#define WIFI_SSID "Toge"
|
||||
#define WIFI_PASSWORD "123123123"
|
||||
|
||||
// ================= FIREBASE =================
|
||||
#define DATABASE_URL "https://smarttoge-default-rtdb.firebaseio.com/"
|
||||
#define DATABASE_SECRET "0CWsHxiRJar3qXSx4uGX385rf0VAnpKKOhQ1wbok"
|
||||
|
||||
// ================= PIN =================
|
||||
#define RELAY_PIN 5
|
||||
|
||||
// ================= OBJECT =================
|
||||
Adafruit_SHT31 sht31 = Adafruit_SHT31();
|
||||
RTC_DS3231 rtc;
|
||||
|
||||
FirebaseData fbdo;
|
||||
FirebaseAuth auth;
|
||||
FirebaseConfig config;
|
||||
|
||||
FirebaseJson json;
|
||||
FirebaseJsonData result;
|
||||
|
||||
// ================= VAR GLOBAL =================
|
||||
bool relayOn = false;
|
||||
bool pumpRunning = false;
|
||||
bool pumpManual = false;
|
||||
bool humidityNotifSent = false;
|
||||
bool wateringDoneNotifSent = false;
|
||||
String activeScheduleKey = "";
|
||||
|
||||
|
||||
// TIMER
|
||||
unsigned long lastSensor = 0;
|
||||
unsigned long lastFirebase = 0;
|
||||
unsigned long lastSchedule = 0;
|
||||
unsigned long lastManual = 0;
|
||||
|
||||
// DATA GLOBAL
|
||||
float suhu = 0;
|
||||
float kelembaban = 0;
|
||||
|
||||
String rtcDate = "";
|
||||
String rtcTime = "";
|
||||
|
||||
// ================= SET RTC DARI SERIAL =================
|
||||
void setRTCFromSerial() {
|
||||
|
||||
if (Serial.available()) {
|
||||
|
||||
String input = Serial.readStringUntil('\n');
|
||||
input.trim();
|
||||
|
||||
int year, month, day, hour, minute, second;
|
||||
|
||||
if (sscanf(input.c_str(), "%d-%d-%d %d:%d:%d",
|
||||
&year, &month, &day,
|
||||
&hour, &minute, &second) == 6) {
|
||||
|
||||
rtc.adjust(DateTime(year, month, day, hour, minute, second));
|
||||
|
||||
Serial.println("RTC berhasil di-set!");
|
||||
} else {
|
||||
Serial.println("Format salah! Gunakan: YYYY-MM-DD HH:MM:SS");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ================= SETUP =================
|
||||
void setup() {
|
||||
|
||||
Serial.begin(115200);
|
||||
|
||||
pinMode(RELAY_PIN, OUTPUT);
|
||||
digitalWrite(RELAY_PIN, HIGH);
|
||||
|
||||
Wire.begin(21, 22);
|
||||
|
||||
if (!sht31.begin(0x44)) {
|
||||
Serial.println("Sensor tidak ditemukan!");
|
||||
while (1);
|
||||
}
|
||||
|
||||
if (!rtc.begin()) {
|
||||
Serial.println("RTC tidak ditemukan!");
|
||||
while (1);
|
||||
}
|
||||
|
||||
// Set otomatis kalau RTC kehilangan daya
|
||||
if (rtc.lostPower()) {
|
||||
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
|
||||
}
|
||||
|
||||
Serial.println("Masukkan waktu RTC format:");
|
||||
Serial.println("YYYY-MM-DD HH:MM:SS");
|
||||
|
||||
// ================= WIFI =================
|
||||
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
|
||||
Serial.print("Connecting WiFi");
|
||||
|
||||
while (WiFi.status() != WL_CONNECTED) {
|
||||
Serial.print(".");
|
||||
delay(500);
|
||||
}
|
||||
|
||||
Serial.println("\nWiFi Connected");
|
||||
|
||||
config.database_url = DATABASE_URL;
|
||||
config.signer.tokens.legacy_token = DATABASE_SECRET;
|
||||
|
||||
Firebase.begin(&config, &auth);
|
||||
Firebase.reconnectWiFi(true);
|
||||
}
|
||||
|
||||
// ================= LOOP =================
|
||||
void loop() {
|
||||
|
||||
setRTCFromSerial(); // 🔥 input waktu dari serial
|
||||
|
||||
unsigned long nowMillis = millis();
|
||||
|
||||
// ================= SENSOR =================
|
||||
if (nowMillis - lastSensor > 2000) {
|
||||
lastSensor = nowMillis;
|
||||
|
||||
suhu = sht31.readTemperature();
|
||||
kelembaban = sht31.readHumidity();
|
||||
|
||||
DateTime now = rtc.now();
|
||||
|
||||
char tgl[11];
|
||||
sprintf(tgl, "%02d-%02d-%04d", now.day(), now.month(), now.year());
|
||||
rtcDate = String(tgl);
|
||||
|
||||
char jam[9];
|
||||
sprintf(jam, "%02d:%02d:%02d", now.hour(), now.minute(), now.second());
|
||||
rtcTime = String(jam);
|
||||
|
||||
Serial.println("Sensor Update");
|
||||
}
|
||||
|
||||
// ================= MANUAL =================
|
||||
if (nowMillis - lastManual > 2000) {
|
||||
lastManual = nowMillis;
|
||||
|
||||
if (Firebase.RTDB.getBool(&fbdo, "/pump/status")) {
|
||||
pumpManual = fbdo.boolData();
|
||||
}
|
||||
}
|
||||
|
||||
// ================= SCHEDULE =================
|
||||
if (nowMillis - lastSchedule > 15000) {
|
||||
lastSchedule = nowMillis;
|
||||
|
||||
relayOn = false;
|
||||
|
||||
if (Firebase.RTDB.getJSON(&fbdo, "/schedules")) {
|
||||
|
||||
json = fbdo.jsonObject();
|
||||
size_t len = json.iteratorBegin();
|
||||
|
||||
String key, value;
|
||||
int type;
|
||||
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
|
||||
json.iteratorGet(i, type, key, value);
|
||||
|
||||
String scheduleTime, scheduleDate, scheduleStatus;
|
||||
|
||||
if (json.get(result, key + "/time"))
|
||||
scheduleTime = result.to<String>();
|
||||
|
||||
if (json.get(result, key + "/date"))
|
||||
scheduleDate = result.to<String>();
|
||||
|
||||
if (json.get(result, key + "/status"))
|
||||
scheduleStatus = result.to<String>();
|
||||
|
||||
int schHour = 0, schMinute = 0;
|
||||
sscanf(scheduleTime.c_str(), "%d:%d", &schHour, &schMinute);
|
||||
|
||||
DateTime now = rtc.now();
|
||||
int hour = now.hour();
|
||||
int minute = now.minute();
|
||||
|
||||
if (rtcDate == scheduleDate &&
|
||||
(hour > schHour || (hour == schHour && minute >= schMinute)) &&
|
||||
scheduleStatus == "idle" &&
|
||||
kelembaban < 85) {
|
||||
|
||||
relayOn = true;
|
||||
|
||||
activeScheduleKey = key;
|
||||
|
||||
Firebase.RTDB.setString(
|
||||
&fbdo,
|
||||
"/schedules/" + key + "/status",
|
||||
"watering");
|
||||
|
||||
Serial.println("TRIGGER SCHEDULE");
|
||||
}
|
||||
|
||||
else if (scheduleStatus == "watering" && !pumpRunning) {
|
||||
Firebase.RTDB.setString(&fbdo,
|
||||
"/schedules/" + key + "/status",
|
||||
"done");
|
||||
}
|
||||
}
|
||||
|
||||
json.iteratorEnd();
|
||||
}
|
||||
}
|
||||
|
||||
// ================= RELAY =================
|
||||
if (pumpManual) {
|
||||
digitalWrite(RELAY_PIN, LOW);
|
||||
}
|
||||
|
||||
else if (relayOn && !pumpRunning) {
|
||||
|
||||
digitalWrite(RELAY_PIN, LOW);
|
||||
pumpRunning = true;
|
||||
|
||||
Serial.println("POMPA ON");
|
||||
}
|
||||
|
||||
// ================= AUTO OFF SAAT KELEMBAPAN >= 85 =================
|
||||
if (pumpRunning && kelembaban >= 85) {
|
||||
|
||||
digitalWrite(RELAY_PIN, HIGH);
|
||||
|
||||
pumpRunning = false;
|
||||
relayOn = false;
|
||||
|
||||
Serial.println("POMPA OFF - KELEMBAPAN SUDAH 85%");
|
||||
|
||||
// UPDATE STATUS JADWAL MENJADI DONE
|
||||
if (activeScheduleKey != "") {
|
||||
|
||||
Firebase.RTDB.setString(
|
||||
&fbdo,
|
||||
"/schedules/" + activeScheduleKey + "/status",
|
||||
"done");
|
||||
|
||||
activeScheduleKey = "";
|
||||
}
|
||||
|
||||
// NOTIFIKASI
|
||||
Firebase.RTDB.setString(
|
||||
&fbdo,
|
||||
"/notification/type",
|
||||
"watering_done");
|
||||
|
||||
Firebase.RTDB.setString(
|
||||
&fbdo,
|
||||
"/notification/message",
|
||||
"Penyiraman selesai. Kelembapan telah mencapai 85%");
|
||||
|
||||
Firebase.RTDB.setInt(
|
||||
&fbdo,
|
||||
"/notification/timestamp",
|
||||
millis());
|
||||
|
||||
wateringDoneNotifSent = true;
|
||||
}
|
||||
|
||||
// ================= DEFAULT OFF =================
|
||||
if (!relayOn && !pumpRunning && !pumpManual) {
|
||||
digitalWrite(RELAY_PIN, HIGH);
|
||||
}
|
||||
|
||||
// ================= FIREBASE UPDATE =================
|
||||
if (nowMillis - lastFirebase > 5000) {
|
||||
lastFirebase = nowMillis;
|
||||
|
||||
Firebase.RTDB.setFloat(&fbdo, "/sht/temperature", suhu);
|
||||
Firebase.RTDB.setFloat(&fbdo, "/sht/humidity", kelembaban);
|
||||
Firebase.RTDB.setString(&fbdo, "/sht/time", rtcTime);
|
||||
Firebase.RTDB.setString(&fbdo, "/sht/date", rtcDate);
|
||||
|
||||
// ================= NOTIFIKASI KELEMBAPAN =================
|
||||
if (kelembaban < 70) {
|
||||
|
||||
if (!humidityNotifSent) {
|
||||
|
||||
Firebase.RTDB.setString(
|
||||
&fbdo,
|
||||
"/notification/type",
|
||||
"humidity_low");
|
||||
|
||||
Firebase.RTDB.setString(
|
||||
&fbdo,
|
||||
"/notification/message",
|
||||
"Kelembapan rendah, segera lakukan penyiraman");
|
||||
|
||||
Firebase.RTDB.setInt(
|
||||
&fbdo,
|
||||
"/notification/timestamp",
|
||||
millis());
|
||||
|
||||
humidityNotifSent = true;
|
||||
wateringDoneNotifSent = false;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
humidityNotifSent = false;
|
||||
}
|
||||
|
||||
Serial.println("Firebase Update");
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue