#include <WiFi.h>
#include <PubSubClient.h>
#include <TinyGPS++.h>

// Konfigurasi WiFi
const char* ssid = "Wokwi-GUEST";
const char* password = "";

// Konfigurasi MQTT
const char* mqtt_server = "broker.hivemq.com";
WiFiClient espClient;
PubSubClient client(espClient);

// Inisialisasi GPS dengan HardwareSerial
HardwareSerial SerialGPS(1);  // Menggunakan UART1
TinyGPSPlus gps;

// Sensor Pin Definitions
#define DO_PIN 34
#define TDS_PIN 35
#define TEMP_PIN 36
#define TURB_PIN 39

void setup() {
  Serial.begin(115200);
  SerialGPS.begin(9600, SERIAL_8N1, 16, 17); // RX = GPIO16, TX = GPIO17 (gunakan pin yang sesuai)
  
  // Inisialisasi WiFi
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("Connected to Wi-Fi");

  // Setup MQTT
  client.setServer(mqtt_server, 1883);
  while (!client.connected()) {
    Serial.print("Connecting to MQTT...");
    if (client.connect("ESP32SwarmClient")) {
      Serial.println("connected");
    } else {
      Serial.print("failed with state ");
      Serial.print(client.state());
      delay(2000);
    }
  }

  // Inisialisasi sensor pins
  pinMode(DO_PIN, INPUT);
  pinMode(TDS_PIN, INPUT);
  pinMode(TEMP_PIN, INPUT);
  pinMode(TURB_PIN, INPUT);
}
void loop() {
  // Update GPS data
  while (SerialGPS.available() > 0) {
    gps.encode(SerialGPS.read());
  }

  if (!client.connected()) {
    // Reconnect MQTT if disconnected
    while (!client.connected()) {
      Serial.print("Reconnecting to MQTT...");
      if (client.connect("ESP32SwarmClient")) {
        Serial.println("connected");
      } else {
        Serial.print("failed with state ");
        Serial.print(client.state());
        delay(2000);
      }
    }
  }

  // Publikasi data sensor
  publishSensorData();

  client.loop(); // Keep MQTT connection alive
  delay(5000); // Delay between sensor data sends
}

void publishSensorData() {
  char msg[128];
  float latitude = gps.location.isValid() ? gps.location.lat() : 0.0;
  float longitude = gps.location.isValid() ? gps.location.lng() : 0.0;

  // Membaca data sensor
  float doValue = analogRead(DO_PIN) * (3.3 / 4095.0);
  float tdsValue = analogRead(TDS_PIN) * (3.3 / 4095.0);
  float tempValue = analogRead(TEMP_PIN) * (3.3 / 4095.0);
  float turbidityValue = analogRead(TURB_PIN) * (3.3 / 4095.0);

  // Mengirim data sebagai JSON string
  snprintf(msg, sizeof(msg), "{\"lat\": %f, \"lng\": %f, \"do\": %f, \"tds\": %f, \"temp\": %f, \"turb\": %f}", 
           latitude, longitude, doValue, tdsValue, tempValue, turbidityValue);
  
  client.publish("swarm/data", msg);
  Serial.println("Data published to MQTT");
}