// Proyek 139 - Penghitung Produk di Konveyor Mini
// Board: NodeMCU ESP8266 V3 | Dashboard: klenik.ichibot.id
#include <ESP8266WiFi.h>
#include <PubSubClient.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_JUMLAH = "ichibot/budi1234/p139/jumlah";
const char* TOPIK_ULANG  = "ichibot/budi1234/p139/ulang";
const char* TOPIK_TARGET = "ichibot/budi1234/p139/target";
const char* TOPIK_LOG    = "ichibot/budi1234/p139/log";
const char* TOPIK_LAJU   = "ichibot/budi1234/p139/laju";

const char* BROKER = "mqtt.ichibot.id";
WiFiClient wifi;
PubSubClient mqtt(wifi);
const int SENSOR = D5;                // E18-D80NK: LOW saat ada benda
long jumlah = 0, target = 100;
int perMenit = 0;
bool adaTadi = false, targetTercapai = false;
unsigned long lewatTerakhir = 0, menitTerakhir = 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_TARGET) target = p.toInt();
  else if (topik == TOPIK_ULANG && p == "ON") {
    jumlah = 0;
    targetTercapai = false;
    mqtt.publish(TOPIK_JUMLAH, "0", true);
    mqtt.publish(TOPIK_ULANG, "OFF");
  }
}

void langganan() {
  mqtt.subscribe(TOPIK_TARGET);
  mqtt.subscribe(TOPIK_ULANG);
}

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);
  pinMode(SENSOR, INPUT_PULLUP);      // keluaran E18 butuh pull-up
  sambungWiFi();
  mqtt.setServer(BROKER, 1883);
  mqtt.setCallback(pesanMasuk);
}

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

  bool ada = digitalRead(SENSOR) == LOW;
  if (ada && !adaTadi && millis() - lewatTerakhir > 150) {   // satu benda = satu hitungan
    lewatTerakhir = millis();
    jumlah++;
    perMenit++;
    mqtt.publish(TOPIK_JUMLAH, String(jumlah).c_str(), true);
    if (!targetTercapai && jumlah >= target) {
      targetTercapai = true;
      mqtt.publish(TOPIK_LOG, ("Target " + String(target) + " produk tercapai!").c_str());
    }
  }
  adaTadi = ada;

  if (millis() - menitTerakhir >= 60000) {
    menitTerakhir = millis();
    mqtt.publish(TOPIK_LAJU, String(perMenit).c_str());
    perMenit = 0;
  }
}
