package business import ( "fmt" "strconv" "time" "Dynamic_environmental_detection/logger" ) type SensorData struct { DeviceUUID string TaskID string Address string SensorType SensorType Facility string RawData []byte Timestamp time.Time Error error } // DataCollector 数据采集器 type DataCollector struct { modbusConfig *ModbusConfig lastReadTime time.Time } // NewDataCollector 创建数据采集器 func NewDataCollector(config *ModbusConfig) *DataCollector { return &DataCollector{ modbusConfig: config, lastReadTime: time.Now().Add(-config.SensorInterval), } } // ReadSensorData 读取单个传感器数据(使用新的Modbus客户端) func (dc *DataCollector) ReadSensorData(sensorConfig SensorConfig) (*SensorData, error) { // 确保通信间隔 dc.ensureCommunicationInterval() // 获取寄存器配置(只包含地址和数量) registerConfig, err := GetRegisterConfig(sensorConfig.GetSensorType()) if err != nil { return nil, fmt.Errorf("Failed to get register configuration: %v", err) } // 关键:直接把 facility 当作 Modbus 从站地址(SlaveID) slaveID, err := strconv.Atoi(sensorConfig.Facility) if err != nil || slaveID < 1 || slaveID > 247 { return nil, fmt.Errorf("Invalid facility value, cannot be used as SlaveID: %s (DeviceUUID: %s)", sensorConfig.Facility, sensorConfig.DeviceUUID) } slaveIDByte := byte(slaveID) // 日志:用真实的 slaveID(来自 facility) logger.Logger.Printf("Reading sensor data - Device: %s, SlaveID: %d (from facility=%s), Addr: %d, Count: %d", sensorConfig.DeviceUUID, slaveID, sensorConfig.Facility, registerConfig.RegisterAddress, registerConfig.RegisterCount) // 使用 facility 作为 SlaveID 创建客户端 client, err := NewDebugModbusClient(dc.modbusConfig, slaveIDByte) if err != nil { return nil, fmt.Errorf("Failed to create Modbus client: %v", err) } defer client.Close() // 读取寄存器数据 rawData, err := client.ReadHoldingRegisters( registerConfig.RegisterAddress, registerConfig.RegisterCount, ) if err != nil { return nil, fmt.Errorf("Failed to read sensor data (DeviceUUID: %s): %v", sensorConfig.DeviceUUID, err) } sensorData := &SensorData{ DeviceUUID: sensorConfig.DeviceUUID, TaskID: sensorConfig.TaskID, Address: sensorConfig.Address, SensorType: sensorConfig.GetSensorType(), Facility: sensorConfig.Facility, RawData: rawData, Timestamp: time.Now(), } // 成功日志也用真实的 slaveID logger.Logger.Printf("Successfully read sensor data - DeviceUUID: %s, SlaveID: %d (from facility=%s), RawData: %v", sensorConfig.DeviceUUID, slaveID, sensorConfig.Facility, rawData) // 更新最后读取时间 dc.lastReadTime = time.Now() return sensorData, nil } // ensureCommunicationInterval 确保通信间隔 func (dc *DataCollector) ensureCommunicationInterval() { elapsed := time.Since(dc.lastReadTime) if elapsed < dc.modbusConfig.SensorInterval { sleepTime := dc.modbusConfig.SensorInterval - elapsed logger.Logger.Printf("Waiting for 485 communication interval: %v", sleepTime) time.Sleep(sleepTime) } } // BatchReadSensorData 批量读取所有传感器数据 func (dc *DataCollector) BatchReadSensorData(sensorConfigs []SensorConfig) ([]*SensorData, []error) { var results []*SensorData var errors []error // 按传感器类型分组,优化读取顺序 groupedConfigs := groupSensorsByType(sensorConfigs) for _, configs := range groupedConfigs { for _, config := range configs { sensorData, err := dc.ReadSensorData(config) if err != nil { errors = append(errors, err) // 如果连续错误,增加等待时间 if len(errors) > 2 { logger.Logger.Printf("Detected consecutive communication errors, increasing bus stabilization time") time.Sleep(dc.modbusConfig.BusResetDelay * 2) } continue } results = append(results, sensorData) } } return results, errors } // groupSensorsByType 按传感器类型分组 func groupSensorsByType(configs []SensorConfig) map[SensorType][]SensorConfig { groups := make(map[SensorType][]SensorConfig) for _, config := range configs { sensorType := config.GetSensorType() groups[sensorType] = append(groups[sensorType], config) } return groups }