131 lines
3.8 KiB
Go
131 lines
3.8 KiB
Go
package business
|
||
|
||
import (
|
||
"encoding/binary"
|
||
"fmt"
|
||
"math"
|
||
|
||
"Dynamic_environmental_detection/logger"
|
||
)
|
||
|
||
// ProcessedSensorData 处理后的传感器数据
|
||
type ProcessedSensorData struct {
|
||
DeviceUUID string `json:"device_uuid"`
|
||
TaskID string `json:"task_id"`
|
||
Address string `json:"address"`
|
||
SensorType SensorType `json:"sensor_type"`
|
||
Facility string `json:"facility"`
|
||
Values []float64 `json:"values"` // 处理后的数值
|
||
Status int `json:"status"` // 状态值 (0或1)
|
||
Timestamp int64 `json:"timestamp"` // 时间戳
|
||
Error string `json:"error,omitempty"`
|
||
}
|
||
|
||
// DataProcessor 数据处理器
|
||
type DataProcessor struct{}
|
||
|
||
// NewDataProcessor 创建数据处理器
|
||
func NewDataProcessor() *DataProcessor {
|
||
return &DataProcessor{}
|
||
}
|
||
|
||
// ProcessSensorData 处理传感器原始数据
|
||
func (dp *DataProcessor) ProcessSensorData(sensorData *SensorData) (*ProcessedSensorData, error) {
|
||
processed := &ProcessedSensorData{
|
||
DeviceUUID: sensorData.DeviceUUID,
|
||
TaskID: sensorData.TaskID,
|
||
Address: sensorData.Address,
|
||
SensorType: sensorData.SensorType,
|
||
Facility: sensorData.Facility,
|
||
Timestamp: sensorData.Timestamp.Unix(),
|
||
}
|
||
|
||
if sensorData.Error != nil {
|
||
processed.Error = sensorData.Error.Error()
|
||
return processed, sensorData.Error
|
||
}
|
||
|
||
switch sensorData.SensorType {
|
||
case SensorTypeTemperatureHumidity:
|
||
|
||
if len(sensorData.RawData) >= 4 {
|
||
|
||
humidity := float64(binary.BigEndian.Uint16(sensorData.RawData[0:2]))
|
||
temperature := float64(binary.BigEndian.Uint16(sensorData.RawData[2:4]))
|
||
|
||
temperature = temperature / 10.0
|
||
humidity = humidity / 10.0
|
||
|
||
processed.Values = []float64{temperature, humidity}
|
||
logger.Logger.Printf("Temperature and Humidity Sensor Data - Temperature: %.1f°C, humidity: %.1f%%",
|
||
temperature, humidity)
|
||
} else {
|
||
return nil, fmt.Errorf("Insufficient data length for temperature and humidity sensor: %d", len(sensorData.RawData))
|
||
}
|
||
|
||
case SensorTypeWaterLeak, SensorTypeSmoke:
|
||
// 水浸和烟雾传感器:1个寄存器,返回状态值
|
||
if len(sensorData.RawData) >= 2 {
|
||
status := int(binary.BigEndian.Uint16(sensorData.RawData[0:2]))
|
||
processed.Status = status
|
||
processed.Values = []float64{float64(status)}
|
||
|
||
sensorName := GetSensorTypeName(sensorData.SensorType)
|
||
statusText := "online"
|
||
if status == 1 {
|
||
statusText = "alarm"
|
||
}
|
||
logger.Logger.Printf("%sstate - %s: %d (%s)",
|
||
sensorName, sensorData.DeviceUUID, status, statusText)
|
||
} else {
|
||
return nil, fmt.Errorf("%sInsufficient sensor data length: %d",
|
||
GetSensorTypeName(sensorData.SensorType), len(sensorData.RawData))
|
||
}
|
||
|
||
default:
|
||
return nil, fmt.Errorf("Unknown sensor type: %d", sensorData.SensorType)
|
||
}
|
||
|
||
return processed, nil
|
||
}
|
||
|
||
// BatchProcessSensorData 批量处理传感器数据
|
||
func (dp *DataProcessor) BatchProcessSensorData(sensorDataList []*SensorData) ([]*ProcessedSensorData, []error) {
|
||
var results []*ProcessedSensorData
|
||
var errors []error
|
||
|
||
for _, sensorData := range sensorDataList {
|
||
processed, err := dp.ProcessSensorData(sensorData)
|
||
if err != nil {
|
||
errors = append(errors, err)
|
||
continue
|
||
}
|
||
results = append(results, processed)
|
||
}
|
||
|
||
return results, errors
|
||
}
|
||
|
||
// IsDataValid 检查数据是否有效
|
||
func (dp *DataProcessor) IsDataValid(processedData *ProcessedSensorData) bool {
|
||
switch processedData.SensorType {
|
||
case SensorTypeTemperatureHumidity:
|
||
// 温湿度合理性检查
|
||
if len(processedData.Values) != 2 {
|
||
return false
|
||
}
|
||
temperature := processedData.Values[0]
|
||
humidity := processedData.Values[1]
|
||
return !math.IsNaN(temperature) && !math.IsNaN(humidity) &&
|
||
temperature >= -50 && temperature <= 100 &&
|
||
humidity >= 0 && humidity <= 100
|
||
|
||
case SensorTypeWaterLeak, SensorTypeSmoke:
|
||
// 状态传感器检查
|
||
return processedData.Status == 0 || processedData.Status == 1
|
||
|
||
default:
|
||
return false
|
||
}
|
||
}
|