package connect import ( "FireLeave_tool/logger" "encoding/json" "fmt" "os" "strconv" "time" ) const BuzzerGPIO = 109 // TriggerBuzzer 触发蜂鸣器响指定秒数 func TriggerBuzzer(seconds int) { if seconds <= 0 { seconds = 10 } fmt.Printf("Buzzer starting to ring for %d seconds...\n", seconds) gpioPath := fmt.Sprintf("/sys/class/gpio/gpio%d", BuzzerGPIO) // 1. 强制导出( os.WriteFile("/sys/class/gpio/export", []byte(strconv.Itoa(BuzzerGPIO)), 0666) time.Sleep(50 * time.Millisecond) // 2. 强制设为输出 os.WriteFile(fmt.Sprintf("%s/direction", gpioPath), []byte("out"), 0666) time.Sleep(10 * time.Millisecond) // 3. 拉高 → 响 if err := os.WriteFile(fmt.Sprintf("%s/value", gpioPath), []byte("1"), 0666); err != nil { fmt.Printf("Failed to set GPIO high: %v\n", err) } else { fmt.Println("GPIO109 set high → Buzzer ringing!") } time.Sleep(time.Duration(seconds) * time.Second) // 4. 拉低 → 停 if err := os.WriteFile(fmt.Sprintf("%s/value", gpioPath), []byte("0"), 0666); err != nil { fmt.Printf("Failed to set GPIO low: %v\n", err) } else { fmt.Println("GPIO109 set low → Buzzer stopped") } } func HandleBuzzerAlert(message []byte) { logger.Logger.Printf("Received platform alert push → Raw message: %s", string(message)) type PublishMsg struct { Topic string `json:"topic"` Content json.RawMessage `json:"content"` // 保持原始字节 } var pub PublishMsg if err := json.Unmarshal(message, &pub); err != nil { logger.Logger.Printf("Outer parsing failed: %v", err) go TriggerBuzzer(3) return } var realCmd struct { Type int `json:"type"` BuzzerDuration interface{} `json:"buzzer_duration,omitempty"` } if err := json.Unmarshal(pub.Content, &realCmd); err == nil { } else { var contentStr string if json.Unmarshal(pub.Content, &contentStr) != nil { logger.Logger.Printf("Content is neither string nor JSON → Using default 3 seconds") go TriggerBuzzer(3) return } logger.Logger.Printf("Detected escaped content → Second parsing: %s", contentStr) if err := json.Unmarshal([]byte(contentStr), &realCmd); err != nil { logger.Logger.Printf("Second parsing failed: %v → Using default 3 seconds", err) go TriggerBuzzer(3) return } } if realCmd.Type != 1 { logger.Logger.Printf("Not a sound/light alert command (type=%d), ignoring", realCmd.Type) return } duration := 3 switch v := realCmd.BuzzerDuration.(type) { case float64: duration = int(v) case string: if n, err := strconv.Atoi(v); err == nil { duration = n } case int: duration = v case nil: duration = 3 } if duration <= 0 || duration > 300 { duration = 3 } logger.Logger.Printf("Platform alert command → Local sound/light alarm ringing for %d seconds!!!", duration) go TriggerBuzzer(duration) }