package devices import ( "encoding/json" "fmt" "math/rand" "time" "iot-base-station/pkg/mqtt" ) // TemperatureSensor 温度传感器模拟器 type TemperatureSensor struct { ID string Name string Location string MinTemp float64 MaxTemp float64 Interval time.Duration client mqtt.Client topic string running bool stopChan chan bool } // TemperatureData 温度数据 type TemperatureData struct { DeviceID string `json:"device_id"` Temperature float64 `json:"temperature"` Humidity float64 `json:"humidity"` Timestamp time.Time `json:"timestamp"` Location string `json:"location"` Status string `json:"status"` } // NewTemperatureSensor 创建温度传感器模拟器 func NewTemperatureSensor(id, name, location string, minTemp, maxTemp float64, interval time.Duration) *TemperatureSensor { return &TemperatureSensor{ ID: id, Name: name, Location: location, MinTemp: minTemp, MaxTemp: maxTemp, Interval: interval, topic: fmt.Sprintf("iot/data/%s/temperature", id), stopChan: make(chan bool), } } // Connect 连接到MQTT代理 func (s *TemperatureSensor) Connect(broker string) error { // 创建MQTT客户端 opts := mqtt.NewClientOptions() opts.AddBroker(broker) opts.SetClientID(s.ID) opts.SetCleanSession(true) // 连接MQTT代理 client := mqtt.NewClient(opts) if token := client.Connect(); token.Wait() && token.Error() != nil { return fmt.Errorf("failed to connect to MQTT broker: %w", token.Error()) } s.client = client return nil } // Start 启动传感器 func (s *TemperatureSensor) Start() { if s.running { return } s.running = true go s.run() } // Stop 停止传感器 func (s *TemperatureSensor) Stop() { if !s.running { return } s.running = false s.stopChan <- true } // run 运行传感器 func (s *TemperatureSensor) run() { ticker := time.NewTicker(s.Interval) defer ticker.Stop() // 发送初始状态 s.sendStatus("online") for { select { case <-ticker.C: // 生成随机温度数据 temp := s.MinTemp + rand.Float64()*(s.MaxTemp-s.MinTemp) humidity := 30.0 + rand.Float64()*40.0 // 30-70%湿度 // 创建温度数据 data := TemperatureData{ DeviceID: s.ID, Temperature: temp, Humidity: humidity, Timestamp: time.Now(), Location: s.Location, Status: "normal", } // 检查温度是否异常 if temp > s.MaxTemp*0.9 || temp < s.MinTemp*1.1 { data.Status = "warning" s.sendAlert(fmt.Sprintf("温度异常: %.2f°C", temp)) } // 发送数据 s.sendData(data) case <-s.stopChan: // 发送离线状态 s.sendStatus("offline") return } } } // sendData 发送数据 func (s *TemperatureSensor) sendData(data TemperatureData) { if s.client == nil { return } payload, err := json.Marshal(data) if err != nil { fmt.Printf("Failed to marshal temperature data: %v\n", err) return } if err := s.client.Publish(s.topic, 1, false, payload); err != nil { fmt.Printf("Failed to publish temperature data: %v\n", err) return } fmt.Printf("Sent temperature data from %s: %.2f°C\n", s.ID, data.Temperature) } // sendStatus 发送状态 func (s *TemperatureSensor) sendStatus(status string) { if s.client == nil { return } topic := fmt.Sprintf("iot/status/%s", s.ID) payload := map[string]interface{}{ "status": status, "timestamp": time.Now(), } data, err := json.Marshal(payload) if err != nil { fmt.Printf("Failed to marshal status data: %v\n", err) return } if err := s.client.Publish(topic, 1, true, data); err != nil { fmt.Printf("Failed to publish status data: %v\n", err) return } fmt.Printf("Sent status from %s: %s\n", s.ID, status) } // sendAlert 发送告警 func (s *TemperatureSensor) sendAlert(message string) { if s.client == nil { return } topic := fmt.Sprintf("iot/event/%s", s.ID) payload := map[string]interface{}{ "type": "alert", "severity": "warning", "message": message, "timestamp": time.Now(), } data, err := json.Marshal(payload) if err != nil { fmt.Printf("Failed to marshal alert data: %v\n", err) return } if err := s.client.Publish(topic, 1, false, data); err != nil { fmt.Printf("Failed to publish alert data: %v\n", err) return } fmt.Printf("Sent alert from %s: %s\n", s.ID, message) } // Disconnect 断开连接 func (s *TemperatureSensor) Disconnect() { if s.client != nil { s.client.Disconnect(250) } }