update hardware go
This commit is contained in:
parent
5e38ec30bc
commit
292580e089
@ -146,13 +146,9 @@ func VerifyHardwareCode(c *gin.Context) {
|
|||||||
|
|
||||||
client := mqtt.NewClient(opts)
|
client := mqtt.NewClient(opts)
|
||||||
if tokenMQTT := client.Connect(); tokenMQTT.Wait() && tokenMQTT.Error() == nil {
|
if tokenMQTT := client.Connect(); tokenMQTT.Wait() && tokenMQTT.Error() == nil {
|
||||||
// Buka Gembok Relay
|
|
||||||
client.Publish("sclass/d101/auth", 0, true, "UNLOCK").Wait()
|
client.Publish("sclass/d101/auth", 0, true, "UNLOCK").Wait()
|
||||||
|
|
||||||
// Opsional: Nyalakan Lampu Otomatis saat login
|
|
||||||
client.Publish("sclass/d101/lampu1", 0, false, "on").Wait()
|
client.Publish("sclass/d101/lampu1", 0, false, "on").Wait()
|
||||||
client.Publish("sclass/d101/lampu2", 0, false, "on").Wait()
|
client.Publish("sclass/d101/lampu2", 0, false, "on").Wait()
|
||||||
|
|
||||||
client.Disconnect(250)
|
client.Disconnect(250)
|
||||||
fmt.Printf("[MQTT] Perintah UNLOCK dan ON dikirim (Sisa Menit: %d)\n", sisaMenit)
|
fmt.Printf("[MQTT] Perintah UNLOCK dan ON dikirim (Sisa Menit: %d)\n", sisaMenit)
|
||||||
} else {
|
} else {
|
||||||
@ -268,7 +264,7 @@ func ControlHardware(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// =========================================================================
|
// =========================================================================
|
||||||
// HELPER: MENGAMBIL STATE DARI HOME ASSISTANT
|
// HELPER 1: MENGAMBIL ANGKA DARI HOME ASSISTANT (Untuk Daya/Watt)
|
||||||
// =========================================================================
|
// =========================================================================
|
||||||
func fetchHAState(haURL string, haToken string, entityID string) float64 {
|
func fetchHAState(haURL string, haToken string, entityID string) float64 {
|
||||||
apiURL := fmt.Sprintf("%s/api/states/%s", haURL, entityID)
|
apiURL := fmt.Sprintf("%s/api/states/%s", haURL, entityID)
|
||||||
@ -294,11 +290,40 @@ func fetchHAState(haURL string, haToken string, entityID string) float64 {
|
|||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ubah string angka menjadi float
|
|
||||||
val, _ := strconv.ParseFloat(stateStr, 64)
|
val, _ := strconv.ParseFloat(stateStr, 64)
|
||||||
return val
|
return val
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// =========================================================================
|
||||||
|
// HELPER 2: MENGAMBIL STATUS TEKS DARI HOME ASSISTANT (Untuk ON/OFF)
|
||||||
|
// =========================================================================
|
||||||
|
func fetchHAStringState(haURL string, haToken string, entityID string) string {
|
||||||
|
apiURL := fmt.Sprintf("%s/api/states/%s", haURL, entityID)
|
||||||
|
|
||||||
|
req, _ := http.NewRequest("GET", apiURL, nil)
|
||||||
|
req.Header.Set("Authorization", "Bearer "+haToken)
|
||||||
|
req.Header.Set("Content-Type", "application/json")
|
||||||
|
|
||||||
|
client := &http.Client{Timeout: 3 * time.Second}
|
||||||
|
resp, err := client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return "off"
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
var result map[string]interface{}
|
||||||
|
if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
|
||||||
|
return "off"
|
||||||
|
}
|
||||||
|
|
||||||
|
stateStr, ok := result["state"].(string)
|
||||||
|
if !ok {
|
||||||
|
return "off"
|
||||||
|
}
|
||||||
|
|
||||||
|
return stateStr
|
||||||
|
}
|
||||||
|
|
||||||
// =========================================================================
|
// =========================================================================
|
||||||
// FUNGSI 3: MENDAPATKAN STATUS DAYA DARI 3 MCB SEKALIGUS
|
// FUNGSI 3: MENDAPATKAN STATUS DAYA DARI 3 MCB SEKALIGUS
|
||||||
// =========================================================================
|
// =========================================================================
|
||||||
@ -330,21 +355,18 @@ func GlobalPowerControl(c *gin.Context) {
|
|||||||
haURL := os.Getenv("HA_URL")
|
haURL := os.Getenv("HA_URL")
|
||||||
haToken := os.Getenv("HA_TOKEN")
|
haToken := os.Getenv("HA_TOKEN")
|
||||||
|
|
||||||
// Tentukan service HA berdasarkan request
|
|
||||||
service := "turn_off"
|
service := "turn_off"
|
||||||
if req.Action == "on" {
|
if req.Action == "on" {
|
||||||
service = "turn_on"
|
service = "turn_on"
|
||||||
}
|
}
|
||||||
apiURL := fmt.Sprintf("%s/api/services/switch/%s", haURL, service)
|
apiURL := fmt.Sprintf("%s/api/services/switch/%s", haURL, service)
|
||||||
|
|
||||||
// Daftar MCB yang akan dieksekusi secara berurutan
|
|
||||||
mcbs := []string{
|
mcbs := []string{
|
||||||
"switch.wifi_smart_meter_pro_switch", // Umum
|
"switch.wifi_smart_meter_pro_switch", // Umum
|
||||||
"switch.wifi_smart_meter_pro_2_switch", // AC1
|
"switch.wifi_smart_meter_pro_2_switch", // AC1
|
||||||
"switch.wifi_smart_meter_pro_3_switch", // AC2
|
"switch.wifi_smart_meter_pro_3_switch", // AC2
|
||||||
}
|
}
|
||||||
|
|
||||||
// Looping untuk eksekusi satu per satu
|
|
||||||
for i, mcb := range mcbs {
|
for i, mcb := range mcbs {
|
||||||
payload := map[string]string{"entity_id": mcb}
|
payload := map[string]string{"entity_id": mcb}
|
||||||
jsonPayload, _ := json.Marshal(payload)
|
jsonPayload, _ := json.Marshal(payload)
|
||||||
@ -363,13 +385,11 @@ func GlobalPowerControl(c *gin.Context) {
|
|||||||
|
|
||||||
fmt.Printf("[MCB] Sinyal %s dikirim ke %s\n", req.Action, mcb)
|
fmt.Printf("[MCB] Sinyal %s dikirim ke %s\n", req.Action, mcb)
|
||||||
|
|
||||||
// Berikan jeda 1 detik, KECUALI untuk iterasi terakhir
|
|
||||||
if i < len(mcbs)-1 {
|
if i < len(mcbs)-1 {
|
||||||
time.Sleep(1 * time.Second)
|
time.Sleep(1 * time.Second)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Jika dimatikan paksa, update cache perangkat IoT menjadi mati semua
|
|
||||||
if req.Action == "off" {
|
if req.Action == "off" {
|
||||||
DeviceStatusCache["lampu1"] = "off"
|
DeviceStatusCache["lampu1"] = "off"
|
||||||
DeviceStatusCache["lampu2"] = "off"
|
DeviceStatusCache["lampu2"] = "off"
|
||||||
@ -384,11 +404,49 @@ func GlobalPowerControl(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// =========================================================================
|
// =========================================================================
|
||||||
// FUNGSI 5: MENGIRIM STATUS REAL-TIME KE WEB FRONTEND
|
// FUNGSI 5: MENGIRIM STATUS REAL-TIME KE WEB FRONTEND (SENSOR FUSION)
|
||||||
// =========================================================================
|
// =========================================================================
|
||||||
func GetHardwareStatus(c *gin.Context) {
|
func GetHardwareStatus(c *gin.Context) {
|
||||||
|
haURL := os.Getenv("HA_URL")
|
||||||
|
haToken := os.Getenv("HA_TOKEN")
|
||||||
|
|
||||||
|
// 1. Cek status fisik MCB di Home Assistant
|
||||||
|
mcbUmum := fetchHAStringState(haURL, haToken, "switch.wifi_smart_meter_pro_switch")
|
||||||
|
mcbAC1 := fetchHAStringState(haURL, haToken, "switch.wifi_smart_meter_pro_2_switch")
|
||||||
|
|
||||||
|
// 2. Ambil data dari Cache (Perintah terakhir dari Web/ESP32 melalui IR/MQTT)
|
||||||
|
statusLampu1 := DeviceStatusCache["lampu1"]
|
||||||
|
statusLampu2 := DeviceStatusCache["lampu2"]
|
||||||
|
statusProyektor := DeviceStatusCache["projector"]
|
||||||
|
statusAC := DeviceStatusCache["ac"]
|
||||||
|
|
||||||
|
// 3. LOGIKA SENSOR FUSION (Penggabungan Fisik & Virtual)
|
||||||
|
// Jika listrik MCB fisik terputus, maka otomatis perangkat di jalur tersebut PASTI MATI (off),
|
||||||
|
// mengabaikan apapun status terakhir yang ada di memori Cache.
|
||||||
|
if mcbUmum == "off" {
|
||||||
|
statusLampu1 = "off"
|
||||||
|
statusLampu2 = "off"
|
||||||
|
statusProyektor = "off"
|
||||||
|
|
||||||
|
// Sinkronkan kembali cache agar tidak ada "state" nyangkut
|
||||||
|
DeviceStatusCache["lampu1"] = "off"
|
||||||
|
DeviceStatusCache["lampu2"] = "off"
|
||||||
|
DeviceStatusCache["projector"] = "off"
|
||||||
|
}
|
||||||
|
|
||||||
|
if mcbAC1 == "off" {
|
||||||
|
statusAC = "off"
|
||||||
|
DeviceStatusCache["ac"] = "off"
|
||||||
|
}
|
||||||
|
|
||||||
|
// Kirim data yang sudah divalidasi ke Web dan Layar ESP32
|
||||||
c.JSON(http.StatusOK, gin.H{
|
c.JSON(http.StatusOK, gin.H{
|
||||||
"status": "success",
|
"status": "success",
|
||||||
"data": DeviceStatusCache,
|
"data": map[string]string{
|
||||||
|
"lampu1": statusLampu1,
|
||||||
|
"lampu2": statusLampu2,
|
||||||
|
"projector": statusProyektor,
|
||||||
|
"ac": statusAC,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user