diff --git a/backend/controllers/hardwarecontroller.go b/backend/controllers/hardwarecontroller.go index ea34060..7cce450 100644 --- a/backend/controllers/hardwarecontroller.go +++ b/backend/controllers/hardwarecontroller.go @@ -8,7 +8,7 @@ import ( "os" "time" - "s-class-backend/config" // IMPORT WAJIB UNTUK KONEKSI DATABASE + "s-class-backend/config" // Import database mqtt "github.com/eclipse/paho.mqtt.golang" "github.com/gin-gonic/gin" @@ -24,7 +24,9 @@ type VerifyRequest struct { Token string `json:"token"` } -// --- CACHE STATUS HARDWARE (Mengingat status terakhir perangkat) --- +// ========================================================================= +// CACHE STATUS HARDWARE (Mengingat status terakhir perangkat untuk Web Admin) +// ========================================================================= var DeviceStatusCache = map[string]string{ "lampu1": "off", "lampu2": "off", @@ -48,13 +50,11 @@ func VerifyHardwareCode(c *gin.Context) { var jamSelesai time.Time isTokenValid := false - // Struktur penampung jam selesai dari database type ResultTime struct { - JamSelesai time.Time `gorm:"column:end_time"` // PASTIKAN NAMA KOLOM 'end_time' SESUAI DENGAN YANG ADA DI DATABASE + JamSelesai time.Time `gorm:"column:end_time"` } var result ResultTime - // 1. Cek di tabel bookings (Redeem Code) errBooking := config.DB.Table("bookings"). Select("end_time"). Where("redeem_code = ?", tokenInput). @@ -63,9 +63,7 @@ func VerifyHardwareCode(c *gin.Context) { if errBooking == nil && !result.JamSelesai.IsZero() { jamSelesai = result.JamSelesai isTokenValid = true - fmt.Println("[VERIFY] Token ditemukan di tabel bookings!") } else { - // 2. Cek di tabel class_schedules (Kode MK) errSchedule := config.DB.Table("class_schedules"). Select("end_time"). Where("kode_mk = ?", tokenInput). @@ -74,32 +72,31 @@ func VerifyHardwareCode(c *gin.Context) { if errSchedule == nil && !result.JamSelesai.IsZero() { jamSelesai = result.JamSelesai isTokenValid = true - fmt.Println("[VERIFY] Token ditemukan di tabel class_schedules!") } } - // Jika token tidak ditemukan di kedua tabel (Token Acak/Salah) if !isTokenValid { - fmt.Printf("[VERIFY] Token %s SALAH atau tidak ditemukan.\n", tokenInput) c.JSON(http.StatusUnauthorized, gin.H{"error": "Token salah atau tidak ditemukan"}) return } - // 3. Kalkulasi Selisih Waktu - // Gabungkan tanggal hari ini dengan jam dari database jamSelesaiHariIni := time.Date(sekarang.Year(), sekarang.Month(), sekarang.Day(), jamSelesai.Hour(), jamSelesai.Minute(), jamSelesai.Second(), 0, sekarang.Location()) selisihWaktu := jamSelesaiHariIni.Sub(sekarang) sisaMenit := int(selisihWaktu.Minutes()) - // 4. Proteksi Jika Waktu Sudah Habis (Lebih dari jam selesai) if sisaMenit <= 0 { c.JSON(http.StatusForbidden, gin.H{"error": "Waktu peminjaman sudah habis"}) return } - // 5. Kirim balasan sukses ke ESP32 beserta durasinya + // ------------------------------------------------------------- + // OPTIONAL: Jika token benar, paksa otomatis catat Lampu ON di Web + // ------------------------------------------------------------- + DeviceStatusCache["lampu1"] = "on" + DeviceStatusCache["lampu2"] = "on" + c.JSON(http.StatusOK, gin.H{ "status": "success", "message": "Token Valid", @@ -117,6 +114,7 @@ func ControlHardware(c *gin.Context) { return } + // --- BLOK KONTROL LAMPU --- if req.Device == "lampu1" || req.Device == "lampu2" { broker := os.Getenv("MQTT_BROKER") user := os.Getenv("MQTT_USER") @@ -139,15 +137,17 @@ func ControlHardware(c *gin.Context) { token := client.Publish(topic, 0, false, req.Action) token.Wait() + // ⭐ SIMPAN STATUS TERBARU LAMPU KE MEMORI GOLANG DeviceStatusCache[req.Device] = req.Action c.JSON(http.StatusOK, gin.H{ "status": "success", - "message": fmt.Sprintf("Berhasil mengirim perintah %s ke %s via MQTT", req.Action, req.Device), + "message": fmt.Sprintf("Berhasil mengirim perintah %s ke %s", req.Action, req.Device), }) return } + // --- BLOK KONTROL AC & PROYEKTOR --- if req.Device == "ac" || req.Device == "projector" { haURL := os.Getenv("HA_URL") haToken := os.Getenv("HA_TOKEN") @@ -189,6 +189,9 @@ func ControlHardware(c *gin.Context) { } defer resp.Body.Close() + // ⭐ SIMPAN STATUS TERBARU AC/PROYEKTOR KE MEMORI GOLANG + DeviceStatusCache[req.Device] = req.Action + c.JSON(http.StatusOK, gin.H{ "status": "success", "message": fmt.Sprintf("Berhasil memicu scene %s", entityID), @@ -234,11 +237,11 @@ func GetPowerStatus(c *gin.Context) { } // ========================================================================= -// FUNGSI 4: MENGAMBIL STATUS PERANGKAT SECARA REAL-TIME +// FUNGSI 4: MENGIRIM STATUS REAL-TIME KE WEB FRONTEND // ========================================================================= func GetHardwareStatus(c *gin.Context) { c.JSON(http.StatusOK, gin.H{ "status": "success", "data": DeviceStatusCache, }) -} \ No newline at end of file +}