"use client"; import { useState, useEffect } from "react"; import { Activity, Power, AlertTriangle, Lightbulb, Wind, Projector, Zap } from "lucide-react"; export default function PowerMonitoringPage() { // ========================================================================= // 1. DEKLARASI STATE UNTUK KELAS D101 // ========================================================================= const [powerData, setPowerData] = useState({ umum: 0, ac1: 0, ac2: 0 }); const [deviceStatus, setDeviceStatus] = useState({ "Lampu 1": false, "Lampu 2": false, "AC": false, "Proyektor": false, }); const [isRelayOn, setIsRelayOn] = useState(true); // Status apakah ruangan terkunci/terbuka const [lastUpdate, setLastUpdate] = useState("Menunggu data..."); // ========================================================================= // 2. FUNGSI FETCH DATA DARI BACKEND GOLANG // ========================================================================= // A. Tarik Data Daya dari 3 MCB (Umum, AC1, AC2) const fetchPowerStatus = async () => { try { // Pastikan route ini sesuai dengan router.GET di main.go Golang kamu const response = await fetch("http://172.17.172.17:8080/api/hardware/power-status"); if (response.ok) { const data = await response.json(); setPowerData({ umum: parseFloat(data.umum) || 0, ac1: parseFloat(data.ac1) || 0, ac2: parseFloat(data.ac2) || 0, }); const now = new Date(); setLastUpdate(`${now.getHours().toString().padStart(2, '0')}:${now.getMinutes().toString().padStart(2, '0')}:${now.getSeconds().toString().padStart(2, '0')}`); } } catch (err) { console.error("Gagal mengambil data daya:", err); } }; // B. Tarik Data Status Perangkat IoT const fetchDeviceStatus = async () => { try { const response = await fetch("http://172.17.172.17:8080/api/hardware/status"); const result = await response.json(); if (result.status === "success") { const backendData = result.data; setDeviceStatus({ "Lampu 1": backendData.lampu1 === "on", "Lampu 2": backendData.lampu2 === "on", "AC": backendData.ac === "on", "Proyektor": backendData.projector === "on", }); // Jika semua mati dan gemboknya aktif, bisa kita asumsikan ruangan off // Tergantung bagaimana logika "auth" kamu di frontend } } catch (err) { console.error("Gagal sinkronisasi status perangkat:", err); } }; // ========================================================================= // 3. INISIALISASI & POLLING (AUTO-REFRESH 3 DETIK) // ========================================================================= useEffect(() => { fetchPowerStatus(); fetchDeviceStatus(); const interval = setInterval(() => { fetchPowerStatus(); fetchDeviceStatus(); }, 3000); return () => clearInterval(interval); }, []); // ========================================================================= // 4. FUNGSI KONTROL DEVICE & CUT OFF // ========================================================================= const handleDeviceToggle = async (deviceName: string) => { // Tentukan kunci array state yang benar const key = deviceName as keyof typeof deviceStatus; const currentStatus = deviceStatus[key]; const actionType = currentStatus ? "off" : "on"; if (currentStatus) { if (!window.confirm(`Apakah Anda yakin ingin mematikan ${deviceName}?`)) return; } let backendDevice = ""; if (deviceName === 'AC') backendDevice = "ac"; else if (deviceName === 'Proyektor') backendDevice = "projector"; else if (deviceName === 'Lampu 1') backendDevice = "lampu1"; else if (deviceName === 'Lampu 2') backendDevice = "lampu2"; // Optimistic UI (Berubah cepat di layar) setDeviceStatus(prev => ({ ...prev, [key]: !currentStatus })); try { const response = await fetch("http://172.17.172.17:8080/api/hardware/control", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ device: backendDevice, action: actionType }), }); if (!response.ok) { setDeviceStatus(prev => ({ ...prev, [key]: currentStatus })); const errorData = await response.json(); alert(`GAGAL: ${errorData.error || "Server menolak perintah"}`); } } catch (error) { console.error("Error API:", error); setDeviceStatus(prev => ({ ...prev, [key]: currentStatus })); alert("GAGAL: Tidak dapat terhubung ke Server Golang."); } }; // FUNGSI CUT OFF 3 MCB SEKALIGUS const handleCutOff = async () => { if (!window.confirm(`PERINGATAN FATAL: Anda yakin ingin memutus 3 MCB Daya di Kelas D101 secara paksa?`)) return; try { const response = await fetch("http://172.17.172.17:8080/api/cutoff", { method: "POST", }); if (response.ok) { alert(`Daya di Kelas D101 berhasil diputus!`); setIsRelayOn(false); fetchPowerStatus(); // Paksa update layar agar jadi 0 Watt fetchDeviceStatus(); // Paksa update icon perangkat mati } else { alert("Gagal memutus daya. Cek koneksi server."); } } catch (error) { console.error(error); alert("Terjadi kesalahan jaringan saat memutus daya."); } }; // Hitung total daya const totalPower = powerData.umum + powerData.ac1 + powerData.ac2; // ========================================================================= // 5. TAMPILAN UI (RENDER) // ========================================================================= return (
Pantau beban 3 MCB utama & kendalikan perangkat Kelas D101.
Update terakhir: {lastUpdate}
Lampu, Proyektor & Stop Kontak
Air Conditioner Unit 1
Air Conditioner Unit 2