264 lines
7.0 KiB
C++
264 lines
7.0 KiB
C++
#define TINY_GSM_MODEM_SIM800
|
|
#define TINY_GSM_RX_BUFFER 256
|
|
|
|
#include <TinyGPSPlus.h>
|
|
#include <TinyGsmClient.h>
|
|
#include <ArduinoHttpClient.h>
|
|
#include <ArduinoJson.h>
|
|
|
|
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.");
|
|
}
|
|
}
|
|
} |