// hardware_firmware/sensor_node_esp32.ino
#include <WiFi.h>
#include <PubSubClient.h>

const char* ssid        = "TELCO_AGRO_IOT";
const char* password    = "Bismillah2026";
const char* mqtt_server = "10.0.0.5"; // IP Gateway Edge Telco
const int   mqtt_port   = 1883;

WiFiClient espClient;
PubSubClient client(espClient);

// Definisi Pin Penderia
#define PIN_SENSOR_O2   34
#define PIN_SENSOR_NH3  35
#define PIN_SENSOR_H2S  32

// Maklumat Pengenalan Voxel
const uint8_t VOXEL_X = 1;
const uint8_t VOXEL_Y = 1;
const uint8_t VOXEL_Z = 0; // Kandang Babi (Aras Lantai)

void setup() {
  Serial.begin(115200);
  pinMode(PIN_SENSOR_O2, INPUT);
  pinMode(PIN_SENSOR_NH3, INPUT);
  pinMode(PIN_SENSOR_H2S, INPUT);

  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("\n[WiFi] Bersambung.");

  client.setServer(mqtt_server, mqtt_port);
}

void loop() {
  if (!client.connected()) {
    reconnect();
  }
  client.loop();

  // 1. Bacaan Analog Sensor
  float rawO2  = analogRead(PIN_SENSOR_O2)  * (3.3 / 4095.0) * 6.5; // Anggaran 0-25%
  float rawNH3 = analogRead(PIN_SENSOR_NH3) * (100.0 / 4095.0);     // 0-100 ppm
  float rawH2S = analogRead(PIN_SENSOR_H2S) * (50.0 / 4095.0);      // 0-50 ppm

  // 2. Vectorization & Kuantisasi Int8 (Hanya 6 bait per paket)
  uint8_t payloadVector[6];
  payloadVector[0] = VOXEL_X;
  payloadVector[1] = VOXEL_Y;
  payloadVector[2] = VOXEL_Z;
  payloadVector[3] = (uint8_t)(constrain(rawO2 * 10, 0, 255)); // 20.4% -> 204
  payloadVector[4] = (uint8_t)(constrain(rawNH3, 0, 255));
  payloadVector[5] = (uint8_t)(constrain(rawH2S, 0, 255));

  // 3. Hantar Vektor Binari Melalui MQTT
  char topic[64];
  sprintf(topic, "telco/agro/voxel/%d_%d_%d/vector", VOXEL_X, VOXEL_Y, VOXEL_Z);
  client.publish(topic, payloadVector, 6);

  Serial.println("[Telemetry] Vektor 6-bait berjaya dihantar.");

  // Tidur mendalam (Deep Sleep) selama 5 minit untuk menjimatkan bateri
  esp_sleep_enable_timer_wakeup(5 * 60 * 1000000ULL);
  esp_deep_sleep_start();
}

void reconnect() {
  while (!client.connected()) {
    Serial.print("[MQTT] Menyambung semula...");
    if (client.connect("ESP32_Voxel_Node_01")) {
      Serial.println("Berjaya.");
    } else {
      delay(2000);
    }
  }
}
