#define TINY_GSM_MODEM_SIM800 #define TINY_GSM_RX_BUFFER 256 #include #include #include #include const char FIREBASE_HOST[] = "tagps-fa005-default-rtdb.firebaseio.com"; const String FIREBASE_AUTH = "TXTe1aAaT8Rlx17eNBf9gZPQOVOClz8ydGGYA0Rd"; const int SSL_PORT = 443; const String GPS_PATH = "/location"; const String KONTROL_ALAT_PATH = "/kontrol_alat"; char apn[] = "internet"; char user[] = "wap"; char pass[] = "123wap"; #define GSM_RX_PIN 4 #define GSM_TX_PIN 2 #define GPS_RX_PIN 16 #define GPS_TX_PIN 17 #define RELAY_PIN 26 #define BUZZER_PIN 27 HardwareSerial sim800(1); TinyGsm modem(sim800); HardwareSerial neogps(2); TinyGPSPlus gps; TinyGsmClientSecure gsm_client_secure_modem(modem, 0); HttpClient http_client = HttpClient(gsm_client_secure_modem, FIREBASE_HOST, SSL_PORT); unsigned long previousMillis = 0; const long interval = 10000; bool currentRelayState = false; bool currentBuzzerState = false; void connectToInternet(); void postToFirebase(const char* method, const String & path, const String & data); bool getKontrolAlat(DynamicJsonDocument &doc); void handleGPSData(); void controlDevices(); void setup() { Serial.begin(115200); Serial.println("ESP32 serial initialize"); sim800.begin(9600, SERIAL_8N1, GSM_RX_PIN, GSM_TX_PIN); Serial.println("SIM800L serial initialize"); neogps.begin(9600, SERIAL_8N1, GPS_RX_PIN, GPS_TX_PIN); Serial.println("NeoGPS serial initialize (reading data from actual GPS sensor)"); delay(3000); pinMode(RELAY_PIN, OUTPUT); digitalWrite(RELAY_PIN, LOW); pinMode(BUZZER_PIN, OUTPUT); digitalWrite(BUZZER_PIN, LOW); Serial.println("Initializing modem..."); modem.restart(); String modemInfo = modem.getModemInfo(); Serial.print("Modem: "); Serial.println(modemInfo); connectToInternet(); http_client.setHttpResponseTimeout(30 * 1000); } void loop() { if (!modem.isNetworkConnected()) { Serial.println("Network disconnected, attempting to reconnect..."); connectToInternet(); } unsigned long currentMillis = millis(); if (currentMillis - previousMillis >= interval) { previousMillis = currentMillis; handleGPSData(); controlDevices(); } while (neogps.available() > 0) { gps.encode(neogps.read()); } } void connectToInternet() { Serial.print("Checking signal... "); Serial.println(modem.getSignalQuality()); Serial.print("Checking SIM... "); Serial.println(modem.getSimStatus()); Serial.print("Checking network registration... "); Serial.println(modem.isNetworkConnected() ? "Yes" : "No"); Serial.print("Mencoba terhubung ke APN: "); Serial.println(apn); int retry_count = 0; const int max_retries = 5; while (retry_count < max_retries) { if (modem.gprsConnect(apn, user, pass)) { Serial.println("GPRS connected successfully!"); return; } else { Serial.println("GPRS connect failed."); retry_count++; delay(1000); } } Serial.println("Failed to connect to GPRS after multiple retries."); } void postToFirebase(const char* method, const String & path, const String & data) { String response; int statusCode = 0; http_client.connect(FIREBASE_HOST, SSL_PORT); if(!http_client.connected()){ Serial.println("HTTP not connected for POST/PATCH."); return; } http_client.connectionKeepAlive(); String url = path + ".json"; url += "?auth=" + FIREBASE_AUTH; Serial.print("Method: "); Serial.println(method); Serial.print("URL: "); Serial.println(url); Serial.print("Data: "); Serial.println(data); String contentType = "application/json"; if (strcmp(method, "PATCH") == 0) { http_client.patch(url, contentType, data); } else if (strcmp(method, "PUT") == 0) { http_client.put(url, contentType, data); } else { Serial.println("Unsupported HTTP method for Firebase POST/PATCH."); return; } statusCode = http_client.responseStatusCode(); Serial.print("Status code: "); Serial.println(statusCode); response = http_client.responseBody(); Serial.print("Response: "); Serial.println(response); if (!http_client.connected()) { Serial.println(); http_client.stop(); Serial.println("HTTP disconnected after POST/PATCH."); if (!modem.isNetworkConnected()) { Serial.println("Reconnecting to network after HTTP disconnect..."); connectToInternet(); } } } bool getKontrolAlat(DynamicJsonDocument &doc) { String url = KONTROL_ALAT_PATH + ".json"; url += "?auth=" + FIREBASE_AUTH; http_client.connect(FIREBASE_HOST, SSL_PORT); if(!http_client.connected()){ Serial.println("HTTP not connected for GET."); return false; } http_client.connectionKeepAlive(); Serial.print("GET URL: "); Serial.println(url); http_client.get(url); int statusCode = http_client.responseStatusCode(); Serial.print("Status code: "); Serial.println(statusCode); String response = http_client.responseBody(); Serial.print("Response: "); Serial.println(response); if (statusCode == 200) { DeserializationError error = deserializeJson(doc, response); if (error) { Serial.print(F("deserializeJson() failed: ")); Serial.println(error.f_str()); return false; } return true; } else { if (!http_client.connected()) { Serial.println("Reconnecting to network after GET failure..."); connectToInternet(); } return false; } } void handleGPSData() { if (gps.location.isValid()) { String latitude = String(gps.location.lat(), 6); String longitude = String(gps.location.lng(), 6); Serial.print("MENGIRIM DATA GPS ASLI - Latitude= "); Serial.print(latitude); Serial.print(" Longitude= "); Serial.println(longitude); String gpsData = "{"; gpsData += "\"lat\":" + latitude + ","; gpsData += "\"lon\":" + longitude + ""; gpsData += "}"; postToFirebase("PATCH", GPS_PATH, gpsData); } else { Serial.println("Waiting for valid GPS data from sensor..."); } } void controlDevices() { DynamicJsonDocument doc(256); if (getKontrolAlat(doc)) { if (doc.containsKey("relay")) { bool newRelayState = doc["relay"]; if (newRelayState != currentRelayState) { currentRelayState = newRelayState; digitalWrite(RELAY_PIN, currentRelayState ? HIGH : LOW); Serial.print("Relay updated from Firebase to "); Serial.println(currentRelayState ? "ON" : "OFF"); } } else { Serial.println("Firebase path '/kontrol_alat' does not contain 'relay' key."); } if (doc.containsKey("buzzer")) { bool newBuzzerState = doc["buzzer"]; if (newBuzzerState != currentBuzzerState) { currentBuzzerState = newBuzzerState; digitalWrite(BUZZER_PIN, newBuzzerState ? HIGH : LOW); Serial.print("Buzzer updated from Firebase to "); Serial.println(newBuzzerState ? "ON" : "OFF"); } } else { Serial.println("Firebase path '/kontrol_alat' does not contain 'buzzer' key."); } } }