// Proyek 146 - Monitor Mesin Mini: Getar + Suhu + Jam Jalan
// Board: ESP32 DOIT DevKit V1 | Dashboard: klenik.ichibot.id
#include <WiFi.h>
#include <PubSubClient.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <Preferences.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_SERVIS = "ichibot/budi1234/p146/servis";
const char* TOPIK_LOG    = "ichibot/budi1234/p146/log";
const char* TOPIK_JALAN  = "ichibot/budi1234/p146/jalan";
const char* TOPIK_JAM    = "ichibot/budi1234/p146/jam";
const char* TOPIK_SUHU   = "ichibot/budi1234/p146/suhu";
const float SUHU_BAHAYA = 60;         // °C di badan mesin
const float SERVIS_SETIAP = 250;      // jam jalan sebelum perlu servis

const char* BROKER = "mqtt.ichibot.id";
WiFiClient wifi;
PubSubClient mqtt(wifi);
OneWire kabelData(4);
DallasTemperature probe(&kabelData);
Preferences memori;
const int GETAR = 27;
float jamJalan = 0;
unsigned long getarTerakhir = 0, terakhir = 0;
bool panas = false, servisDiingatkan = false;

void pesanMasuk(char* t, byte* isi, unsigned int panjang) {
  jamJalan = 0;                       // servis selesai: hitung ulang
  servisDiingatkan = false;
  memori.putFloat("jam", 0);
  mqtt.publish(TOPIK_SERVIS, "OFF");
  mqtt.publish(TOPIK_LOG, "Servis dicatat, jam jalan dihitung dari 0");
}

void langganan() {
  mqtt.subscribe(TOPIK_SERVIS);
}

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(GETAR, INPUT);
  probe.begin();
  memori.begin("mesin", false);
  jamJalan = memori.getFloat("jam", 0);
  sambungWiFi();
  mqtt.setServer(BROKER, 1883);
  mqtt.setCallback(pesanMasuk);
}

void loop() {
  if (!mqtt.connected()) sambungMQTT();
  mqtt.loop();
  if (digitalRead(GETAR) == HIGH) getarTerakhir = millis();

  if (millis() - terakhir < 10000) return;
  float detik = (millis() - terakhir) / 1000.0;
  terakhir = millis();

  bool jalan = millis() - getarTerakhir < 15000;   // ada getaran 15 detik terakhir = mesin hidup
  if (jalan) jamJalan += detik / 3600.0;
  probe.requestTemperatures();
  float suhu = probe.getTempCByIndex(0);

  mqtt.publish(TOPIK_JALAN, jalan ? "1" : "0");
  mqtt.publish(TOPIK_JAM, String(jamJalan, 1).c_str());
  if (suhu != DEVICE_DISCONNECTED_C) mqtt.publish(TOPIK_SUHU, String(suhu, 1).c_str());

  if (!panas && suhu > SUHU_BAHAYA) { panas = true; mqtt.publish(TOPIK_LOG, ("MESIN PANAS: " + String(suhu, 0) + " °C").c_str()); }
  if (panas && suhu < SUHU_BAHAYA - 5) panas = false;
  if (!servisDiingatkan && jamJalan >= SERVIS_SETIAP) {
    servisDiingatkan = true;
    mqtt.publish(TOPIK_LOG, "Waktunya servis (ganti oli/cek sabuk)");
  }
  static unsigned long simpan = 0;
  if (millis() - simpan > 300000) { simpan = millis(); memori.putFloat("jam", jamJalan); }   // simpan tiap 5 menit
}
