// Proyek 131 - Timbangan Digital 5 kg HX711
// Board: ESP32 DOIT DevKit V1 | Dashboard: klenik.ichibot.id
#include <WiFi.h>
#include <PubSubClient.h>
#include <HX711.h>

// ===== ISI DULU =====
const char* WIFI_NAMA = "nama-wifi-kamu";
const char* WIFI_PASS = "password-wifi-kamu";

// topic MQTT: ganti budi1234 dengan KODE-mu (sama dengan di dashboard Klenik)
const char* TOPIK_NOL       = "ichibot/budi1234/p131/nol";
const char* TOPIK_LOG       = "ichibot/budi1234/p131/log";
const char* TOPIK_KALIBRASI = "ichibot/budi1234/p131/kalibrasi";
const char* TOPIK_BERAT     = "ichibot/budi1234/p131/berat";
float FAKTOR = 420.0;                 // angka mentah per gram, isi setelah kalibrasi

const char* BROKER = "mqtt.ichibot.id";
WiFiClient wifi;
PubSubClient mqtt(wifi);
HX711 timbangan;
const int PIN_DT = 26, PIN_SCK = 27;
unsigned long terakhir = 0;

void pesanMasuk(char* t, byte* isi, unsigned int panjang) {
  String topik = t;
  String p;
  for (unsigned int i = 0; i < panjang; i++) p += (char)isi[i];
  if (topik == TOPIK_NOL && p == "ON") {
    timbangan.tare(20);               // berat sekarang dianggap 0
    mqtt.publish(TOPIK_NOL, "OFF");
  } else if (topik == TOPIK_KALIBRASI) {   // taruh benda yang beratnya diketahui, kirim gramnya
    float gram = p.toFloat();
    if (gram > 0) {
      timbangan.set_scale(1);
      float mentah = timbangan.get_units(20);
      FAKTOR = mentah / gram;
      timbangan.set_scale(FAKTOR);
      mqtt.publish(TOPIK_LOG, ("FAKTOR baru: " + String(FAKTOR, 2) + " (tulis di kode)").c_str());
    }
  }
}

void langganan() {
  mqtt.subscribe(TOPIK_NOL);
  mqtt.subscribe(TOPIK_KALIBRASI);
}

void sambungWiFi() {
  WiFi.begin(WIFI_NAMA, WIFI_PASS);
  Serial.print("WiFi");
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println(" OK, IP " + WiFi.localIP().toString());
}

void sambungMQTT() {
  while (!mqtt.connected()) {
    if (mqtt.connect(WiFi.macAddress().c_str())) {
      Serial.println("Terhubung ke Klenik");
      langganan();
    } else {
      Serial.println("Broker gagal, coba lagi 3 detik");
      delay(3000);
    }
  }
}
void setup() {
  Serial.begin(115200);
  timbangan.begin(PIN_DT, PIN_SCK);
  timbangan.set_scale(FAKTOR);
  timbangan.tare(20);                 // wadah kosong saat menyala = 0 gram
  sambungWiFi();
  mqtt.setServer(BROKER, 1883);
  mqtt.setCallback(pesanMasuk);
}

void loop() {
  if (!mqtt.connected()) sambungMQTT();
  mqtt.loop();

  if (millis() - terakhir >= 1000 && timbangan.is_ready()) {
    terakhir = millis();
    float gram = timbangan.get_units(10);
    if (fabs(gram) < 2) gram = 0;     // buang getaran kecil di sekitar nol
    Serial.printf("%.1f g\n", gram);
    mqtt.publish(TOPIK_BERAT, String(gram, 0).c_str());
  }
}
