.
This commit is contained in:
parent
0a8ced6490
commit
16075c670a
@ -4,8 +4,8 @@ import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"strings" // TAMBAHAN: Untuk membersihkan spasi/enter gaib
|
||||
"s-class-backend/models"
|
||||
"strings"
|
||||
|
||||
"github.com/joho/godotenv"
|
||||
"gorm.io/driver/postgres"
|
||||
@ -32,13 +32,13 @@ func ConnectDatabase() {
|
||||
fmt.Printf("[DEBUG] Host: %s | Port: %s | User: %s | DB: %s\n", dbHost, dbPort, dbUser, dbName)
|
||||
fmt.Printf("[DEBUG] Panjang karakter password yang dibaca Golang: %d\n", len(dbPassword))
|
||||
|
||||
dsn := fmt.Sprintf("host=%s user=%s password=%s dbname=%s port=%s sslmode=disable TimeZone=Asia/Jakarta",
|
||||
dsn := fmt.Sprintf("host=%s user=%s password=%s dbname=%s port=%s sslmode=disable TimeZone=Asia/Jakarta",
|
||||
dbHost, dbUser, dbPassword, dbName, dbPort)
|
||||
|
||||
database, err := gorm.Open(postgres.Open(dsn), &gorm.Config{
|
||||
DisableForeignKeyConstraintWhenMigrating: true,
|
||||
})
|
||||
|
||||
|
||||
if err != nil {
|
||||
fmt.Println("[ERROR FATAL KONEKSI DB]:", err)
|
||||
panic("Gagal koneksi ke database!")
|
||||
@ -54,4 +54,4 @@ func ConnectDatabase() {
|
||||
|
||||
fmt.Println("Sukses terkoneksi ke Database PostgreSQL!")
|
||||
DB = database
|
||||
}
|
||||
}
|
||||
|
||||
@ -8,6 +8,8 @@ import (
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"s-class-backend/config" // IMPORT WAJIB UNTUK KONEKSI DATABASE
|
||||
|
||||
mqtt "github.com/eclipse/paho.mqtt.golang"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
@ -18,7 +20,6 @@ type DeviceControlRequest struct {
|
||||
Action string `json:"action"`
|
||||
}
|
||||
|
||||
// Struct baru untuk menangkap input Token dari layar ESP32
|
||||
type VerifyRequest struct {
|
||||
Token string `json:"token"`
|
||||
}
|
||||
@ -29,7 +30,6 @@ type VerifyRequest struct {
|
||||
func VerifyHardwareCode(c *gin.Context) {
|
||||
var req VerifyRequest
|
||||
|
||||
// 1. Tangkap JSON { "token": "..." } dari ESP32
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "Format token tidak valid"})
|
||||
return
|
||||
@ -37,41 +37,64 @@ func VerifyHardwareCode(c *gin.Context) {
|
||||
|
||||
tokenInput := req.Token
|
||||
sekarang := time.Now()
|
||||
var jamSelesai time.Time
|
||||
isTokenValid := false
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// 2. LOGIKA DATABASE PENGGANTI (Silakan sesuaikan dengan model GORM-mu)
|
||||
// ---------------------------------------------------------------------
|
||||
/* // CONTOH ASLI JIKA SUDAH MENGHUBUNGKAN KE DATABASE:
|
||||
var jadwal models.Booking
|
||||
if err := db.Where("token = ?", tokenInput).First(&jadwal).Error; err != nil {
|
||||
c.JSON(http.StatusUnauthorized, gin.H{"error": "Token salah atau tidak ditemukan"})
|
||||
return
|
||||
}
|
||||
jamSelesai := jadwal.JamSelesai
|
||||
*/
|
||||
// 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
|
||||
}
|
||||
var result ResultTime
|
||||
|
||||
// SIMULASI SEMENTARA (Hapus bagian ini jika query DB di atas sudah aktif):
|
||||
// Mengatur jam selesai kelas pada jam 19:00:00 di hari ini sebagai sampel waktu
|
||||
jamSelesai := time.Date(sekarang.Year(), sekarang.Month(), sekarang.Day(), 19, 0, 0, 0, sekarang.Location())
|
||||
|
||||
// Tampilkan log di terminal backend
|
||||
fmt.Printf("[VERIFY] Token masuk: %s | Jam Selesai: %v\n", tokenInput, jamSelesai)
|
||||
// ---------------------------------------------------------------------
|
||||
// 1. Cek di tabel bookings (Redeem Code)
|
||||
errBooking := config.DB.Table("bookings").
|
||||
Select("end_time").
|
||||
Where("redeem_code = ?", tokenInput).
|
||||
Scan(&result).Error
|
||||
|
||||
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).
|
||||
Scan(&result).Error
|
||||
|
||||
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
|
||||
selisihWaktu := jamSelesai.Sub(sekarang)
|
||||
// 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 / Kelas Selesai
|
||||
// 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 ke ESP32 beserta nilai duration_minutes
|
||||
// 5. Kirim balasan sukses ke ESP32 beserta durasinya
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"status": "success",
|
||||
"message": "Token Valid, Akses Diberikan",
|
||||
"message": "Token Valid",
|
||||
"duration_minutes": sisaMenit,
|
||||
})
|
||||
}
|
||||
@ -86,13 +109,11 @@ func ControlHardware(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
// --- SKENARIO 1: KONTROL LAMPU (Via MQTT ke ESP32 Relay) ---
|
||||
if req.Device == "lampu1" || req.Device == "lampu2" {
|
||||
broker := os.Getenv("MQTT_BROKER")
|
||||
user := os.Getenv("MQTT_USER")
|
||||
pass := os.Getenv("MQTT_PASSWORD")
|
||||
|
||||
// Setup Konfigurasi Klien MQTT Golang
|
||||
opts := mqtt.NewClientOptions()
|
||||
opts.AddBroker(broker)
|
||||
opts.SetUsername(user)
|
||||
@ -106,10 +127,7 @@ func ControlHardware(c *gin.Context) {
|
||||
}
|
||||
defer client.Disconnect(250)
|
||||
|
||||
// Tentukan Topik
|
||||
topic := fmt.Sprintf("sclass/d101/%s", req.Device)
|
||||
|
||||
// Publish Pesan
|
||||
token := client.Publish(topic, 0, false, req.Action)
|
||||
token.Wait()
|
||||
|
||||
@ -120,7 +138,6 @@ func ControlHardware(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
// --- SKENARIO 2: KONTROL AC & PROYEKTOR (Via Home Assistant) ---
|
||||
if req.Device == "ac" || req.Device == "projector" {
|
||||
haURL := os.Getenv("HA_URL")
|
||||
haToken := os.Getenv("HA_TOKEN")
|
||||
@ -169,7 +186,6 @@ func ControlHardware(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
// Jika device tidak dikenali
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "Device tidak dikenali sistem"})
|
||||
}
|
||||
|
||||
@ -180,7 +196,6 @@ func GetPowerStatus(c *gin.Context) {
|
||||
haURL := os.Getenv("HA_URL")
|
||||
haToken := os.Getenv("HA_TOKEN")
|
||||
|
||||
// Ganti dengan Entity ID sensor daya kamu di Home Assistant
|
||||
entityID := "sensor.kwh_meter_power"
|
||||
apiURL := fmt.Sprintf("%s/api/states/%s", haURL, entityID)
|
||||
|
||||
@ -199,7 +214,6 @@ func GetPowerStatus(c *gin.Context) {
|
||||
var result map[string]interface{}
|
||||
json.NewDecoder(resp.Body).Decode(&result)
|
||||
|
||||
// Ambil nilai state (angka watt)
|
||||
powerStr, ok := result["state"].(string)
|
||||
if !ok {
|
||||
c.JSON(http.StatusOK, gin.H{"power": 0})
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user