feat: 新增 485 的解析
This commit is contained in:
parent
6e643497a1
commit
419a5c940e
201
main.go
201
main.go
@ -130,18 +130,61 @@ func startUDP() {
|
|||||||
|
|
||||||
// 检查数据是否为RS485格式
|
// 检查数据是否为RS485格式
|
||||||
if len(rawData) == 25 && rawData[0] == 0x24 {
|
if len(rawData) == 25 && rawData[0] == 0x24 {
|
||||||
|
log.Println("=== 检测到RS485设备数据 ===")
|
||||||
|
|
||||||
|
// 生成源码字符串(用于日志记录)
|
||||||
|
sourceHex := strings.ReplaceAll(strings.TrimSpace(hexDump), "\n", " ")
|
||||||
|
log.Printf("源码: %s", sourceHex)
|
||||||
|
|
||||||
// 解析RS485数据
|
// 解析RS485数据
|
||||||
hexStr := strings.ReplaceAll(hexDump, "\n", " ")
|
protocol := model.NewProtocol(rawData)
|
||||||
parseHexData(hexStr)
|
rs485Protocol := model.NewRS485Protocol(rawData)
|
||||||
|
|
||||||
|
// 获取设备ID
|
||||||
|
idParts, err := protocol.GetCompleteID()
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("获取设备ID失败: %v", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// 解析RS485数据
|
||||||
|
rs485Data, err := rs485Protocol.ParseRS485Data()
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("解析RS485数据失败: %v", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加设备ID和时间戳
|
||||||
|
rs485Data.DeviceID = idParts.Complete.Hex
|
||||||
|
rs485Data.ReceivedAt = time.Now()
|
||||||
|
rs485Data.RawDataHex = sourceHex
|
||||||
|
|
||||||
|
// 打印解析结果到日志
|
||||||
|
log.Println("=== RS485解析结果 ===")
|
||||||
|
log.Printf("设备ID: RS485-%s", rs485Data.DeviceID)
|
||||||
|
log.Printf("温度: %.2f°C", rs485Data.Temperature)
|
||||||
|
log.Printf("湿度: %.1f%%", rs485Data.Humidity)
|
||||||
|
log.Printf("风速: %.5f m/s", rs485Data.WindSpeed)
|
||||||
|
log.Printf("风向: %.1f°", rs485Data.WindDirection)
|
||||||
|
log.Printf("降雨量: %.3f mm", rs485Data.Rainfall)
|
||||||
|
log.Printf("光照: %.1f lux", rs485Data.Light)
|
||||||
|
log.Printf("紫外线: %.1f", rs485Data.UV)
|
||||||
|
log.Printf("气压: %.2f hPa", rs485Data.Pressure)
|
||||||
|
log.Printf("接收时间: %s", rs485Data.ReceivedAt.Format("2006-01-02 15:04:05"))
|
||||||
|
|
||||||
// 注册设备
|
// 注册设备
|
||||||
protocol := model.NewProtocol(rawData)
|
stationID := fmt.Sprintf("RS485-%s", rs485Data.DeviceID)
|
||||||
idParts, err := protocol.GetCompleteID()
|
|
||||||
if err == nil {
|
|
||||||
stationID := fmt.Sprintf("RS485-%s", idParts.Complete.Hex)
|
|
||||||
model.RegisterDevice(stationID, addr)
|
model.RegisterDevice(stationID, addr)
|
||||||
log.Printf("设备 %s 已注册,IP: %s", stationID, addr.String())
|
log.Printf("设备 %s 已注册,IP: %s", stationID, addr.String())
|
||||||
}
|
|
||||||
|
// 可选:保存到数据库
|
||||||
|
// err = model.SaveWeatherData(rs485Data, string(rawData))
|
||||||
|
// if err != nil {
|
||||||
|
// log.Printf("保存数据到数据库失败: %v", err)
|
||||||
|
// } else {
|
||||||
|
// log.Printf("数据已成功保存到数据库")
|
||||||
|
// }
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// 尝试解析WIFI数据
|
// 尝试解析WIFI数据
|
||||||
data, deviceType, err := model.ParseData(rawData)
|
data, deviceType, err := model.ParseData(rawData)
|
||||||
@ -166,14 +209,6 @@ func startUDP() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 暂时不保存到数据库
|
|
||||||
// err = model.SaveWeatherData(data, string(rawData))
|
|
||||||
// if err != nil {
|
|
||||||
// log.Printf("保存数据到数据库失败: %v", err)
|
|
||||||
// } else {
|
|
||||||
// log.Printf("数据已成功保存到数据库")
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -258,49 +293,151 @@ func parseHexData(hexStr string) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 打印原始数据
|
||||||
|
log.Println("=== 原始数据分析 ===")
|
||||||
|
log.Printf("输入的十六进制字符串: %s", hexStr)
|
||||||
|
log.Printf("解析后的字节数组长度: %d", len(data))
|
||||||
|
log.Printf("字节数组内容: %v", data)
|
||||||
|
|
||||||
|
// 按索引打印每个字节
|
||||||
|
for i, b := range data {
|
||||||
|
log.Printf("索引[%2d]: 0x%02X (%d)", i, b, b)
|
||||||
|
}
|
||||||
|
|
||||||
// 检查数据有效性
|
// 检查数据有效性
|
||||||
if !model.ValidateRS485Data(data) {
|
if !model.ValidateRS485Data(data) {
|
||||||
log.Printf("无效的RS485数据格式: 长度=%d, 起始字节=%02X", len(data), data[0])
|
log.Printf("无效的RS485数据格式: 长度=%d, 起始字节=%02X", len(data), data[0])
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.Println("\n=== 使用Protocol.go标准解析 ===")
|
||||||
|
|
||||||
// 创建协议解析器
|
// 创建协议解析器
|
||||||
protocol := model.NewProtocol(data)
|
protocol := model.NewProtocol(data)
|
||||||
rs485Protocol := model.NewRS485Protocol(data)
|
rs485Protocol := model.NewRS485Protocol(data)
|
||||||
|
|
||||||
// 获取设备ID
|
// 1. 解析设备ID
|
||||||
|
log.Println("--- 设备ID解析 ---")
|
||||||
idParts, err := protocol.GetCompleteID()
|
idParts, err := protocol.GetCompleteID()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("获取设备ID失败: %v", err)
|
log.Printf("获取设备ID失败: %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
log.Printf("HSB (索引21): 0x%02X = %d", data[21], data[21])
|
||||||
|
log.Printf("MSB (索引22): 0x%02X = %d", data[22], data[22])
|
||||||
|
log.Printf("LSB (索引1): 0x%02X = %d", data[1], data[1])
|
||||||
|
log.Printf("完整设备ID: %s", idParts.Complete.Hex)
|
||||||
|
|
||||||
// 解析RS485数据
|
// 2. 解析温度
|
||||||
|
log.Println("--- 温度解析 ---")
|
||||||
|
temp, err := protocol.GetTemperature()
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("获取温度失败: %v", err)
|
||||||
|
} else {
|
||||||
|
log.Printf("TMP_H (bit29-31): %s (0x%X)", temp.TmpH.Binary, temp.TmpH.Value)
|
||||||
|
log.Printf("TMP_M (bit32-35): %s (0x%X)", temp.TmpM.Binary, temp.TmpM.Value)
|
||||||
|
log.Printf("TMP_L (bit36-39): %s (0x%X)", temp.TmpL.Binary, temp.TmpL.Value)
|
||||||
|
log.Printf("原始值: 0x%X = %d", temp.Complete.RawValue, temp.Complete.RawValue)
|
||||||
|
log.Printf("温度: %.2f°C", temp.Complete.Value)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 解析湿度
|
||||||
|
log.Println("--- 湿度解析 ---")
|
||||||
|
humidity, err := protocol.GetHumidity()
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("获取湿度失败: %v", err)
|
||||||
|
} else {
|
||||||
|
log.Printf("HM_H (bit40-43): %s (0x%X)", humidity.HmH.Binary, humidity.HmH.Value)
|
||||||
|
log.Printf("HM_L (bit44-47): %s (0x%X)", humidity.HmL.Binary, humidity.HmL.Value)
|
||||||
|
log.Printf("原始值: 0x%02X = %d", humidity.Complete.RawValue, humidity.Complete.RawValue)
|
||||||
|
log.Printf("湿度: %d%%", humidity.Complete.Value)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. 解析风速
|
||||||
|
log.Println("--- 风速解析 ---")
|
||||||
|
windSpeed, err := protocol.GetWindSpeed()
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("获取风速失败: %v", err)
|
||||||
|
} else {
|
||||||
|
log.Printf("WSP_FLAG: %v", windSpeed.WspFlag.Value)
|
||||||
|
log.Printf("WSP_H (bit48-51): %s (0x%X)", windSpeed.WspH.Binary, windSpeed.WspH.Value)
|
||||||
|
log.Printf("WSP_L (bit52-55): %s (0x%X)", windSpeed.WspL.Binary, windSpeed.WspL.Value)
|
||||||
|
log.Printf("原始值: 0x%X = %d", windSpeed.Complete.RawValue, windSpeed.Complete.RawValue)
|
||||||
|
log.Printf("风速: %.5f m/s", windSpeed.Complete.Value)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5. 解析风向
|
||||||
|
log.Println("--- 风向解析 ---")
|
||||||
|
windDir, err := protocol.GetWindDirection()
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("获取风向失败: %v", err)
|
||||||
|
} else {
|
||||||
|
log.Printf("DIR_H: %s (0x%X)", windDir.DirH.Binary, windDir.DirH.Value)
|
||||||
|
log.Printf("DIR_M: %s (0x%X)", windDir.DirM.Binary, windDir.DirM.Value)
|
||||||
|
log.Printf("DIR_L: %s (0x%X)", windDir.DirL.Binary, windDir.DirL.Value)
|
||||||
|
log.Printf("原始值: 0x%X = %d", windDir.Complete.Value, windDir.Complete.Value)
|
||||||
|
log.Printf("风向: %.1f°", windDir.Complete.Degree)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 6. 解析降雨量
|
||||||
|
log.Println("--- 降雨量解析 ---")
|
||||||
|
rainfall, err := protocol.GetRainfall()
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("获取降雨量失败: %v", err)
|
||||||
|
} else {
|
||||||
|
log.Printf("原始值: 0x%X = %d", rainfall.Complete.RawValue, rainfall.Complete.RawValue)
|
||||||
|
log.Printf("降雨量: %.3f mm", rainfall.Complete.Value)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 7. 解析光照
|
||||||
|
log.Println("--- 光照解析 ---")
|
||||||
|
light, err := protocol.GetLight()
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("获取光照失败: %v", err)
|
||||||
|
} else {
|
||||||
|
log.Printf("原始值: 0x%X = %d", light.Complete.RawValue, light.Complete.RawValue)
|
||||||
|
log.Printf("光照: %.1f lux", light.Complete.Value)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 8. 解析UV指数
|
||||||
|
log.Println("--- UV指数解析 ---")
|
||||||
|
uv, err := protocol.GetUVIndex()
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("获取UV指数失败: %v", err)
|
||||||
|
} else {
|
||||||
|
log.Printf("原始值: 0x%X = %d", uv.Complete.RawValue, uv.Complete.RawValue)
|
||||||
|
log.Printf("UV指数: %.1f uW/c㎡", uv.Complete.Value)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 9. 解析气压
|
||||||
|
log.Println("--- 气压解析 ---")
|
||||||
|
pressure, err := protocol.GetPressure()
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("获取气压失败: %v", err)
|
||||||
|
} else {
|
||||||
|
log.Printf("原始值: 0x%X = %d", pressure.Complete.RawValue, pressure.Complete.RawValue)
|
||||||
|
log.Printf("气压: %.2f hPa", pressure.Complete.Value)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Println("\n=== RS485协议统一解析结果 ===")
|
||||||
|
// 使用修正后的RS485解析
|
||||||
rs485Data, err := rs485Protocol.ParseRS485Data()
|
rs485Data, err := rs485Protocol.ParseRS485Data()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("解析RS485数据失败: %v", err)
|
log.Printf("解析RS485数据失败: %v", err)
|
||||||
return
|
return
|
||||||
}
|
} else {
|
||||||
|
|
||||||
// 添加设备ID和时间戳
|
|
||||||
rs485Data.DeviceID = idParts.Complete.Hex
|
rs485Data.DeviceID = idParts.Complete.Hex
|
||||||
rs485Data.ReceivedAt = time.Now()
|
rs485Data.ReceivedAt = time.Now()
|
||||||
rs485Data.RawDataHex = fmt.Sprintf("%X", data)
|
rs485Data.RawDataHex = fmt.Sprintf("%X", data)
|
||||||
|
|
||||||
// 打印解析结果
|
log.Printf("设备ID: RS485-%s", rs485Data.DeviceID)
|
||||||
log.Println("=== RS485数据解析结果 ===")
|
|
||||||
log.Printf("原始数据: %s", hexStr)
|
|
||||||
log.Printf("设备ID: %s (HSB=%s, MSB=%s, LSB=%s)",
|
|
||||||
idParts.Complete.Hex,
|
|
||||||
idParts.HSB.Hex,
|
|
||||||
idParts.MSB.Hex,
|
|
||||||
idParts.LSB.Hex)
|
|
||||||
log.Printf("温度: %.2f°C", rs485Data.Temperature)
|
log.Printf("温度: %.2f°C", rs485Data.Temperature)
|
||||||
log.Printf("湿度: %.1f%%", rs485Data.Humidity)
|
log.Printf("湿度: %.1f%%", rs485Data.Humidity)
|
||||||
|
log.Printf("风速: %.5f m/s", rs485Data.WindSpeed)
|
||||||
log.Printf("风向: %.1f°", rs485Data.WindDirection)
|
log.Printf("风向: %.1f°", rs485Data.WindDirection)
|
||||||
log.Printf("风速: %.2f m/s", rs485Data.WindSpeed)
|
log.Printf("降雨量: %.3f mm", rs485Data.Rainfall)
|
||||||
log.Printf("降雨量: %.2f mm", rs485Data.Rainfall)
|
log.Printf("光照: %.1f lux", rs485Data.Light)
|
||||||
log.Printf("光照: %.2f lux", rs485Data.Light)
|
log.Printf("紫外线: %.1f", rs485Data.UV)
|
||||||
log.Printf("紫外线: %.2f", rs485Data.UV)
|
|
||||||
log.Printf("气压: %.2f hPa", rs485Data.Pressure)
|
log.Printf("气压: %.2f hPa", rs485Data.Pressure)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -774,45 +774,55 @@ type RS485WeatherData struct {
|
|||||||
RawDataHex string // 原始数据十六进制
|
RawDataHex string // 原始数据十六进制
|
||||||
}
|
}
|
||||||
|
|
||||||
// ParseRS485Data 解析RS485数据
|
// ParseRS485Data 解析RS485数据 - 使用Protocol标准方法
|
||||||
func (p *RS485Protocol) ParseRS485Data() (*RS485WeatherData, error) {
|
func (p *RS485Protocol) ParseRS485Data() (*RS485WeatherData, error) {
|
||||||
if !ValidateRS485Data(p.RawData) {
|
if !ValidateRS485Data(p.RawData) {
|
||||||
return nil, fmt.Errorf("无效的RS485数据格式")
|
return nil, fmt.Errorf("无效的RS485数据格式")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 创建标准Protocol来解析数据
|
||||||
|
protocol := NewProtocol(p.RawData)
|
||||||
data := &RS485WeatherData{}
|
data := &RS485WeatherData{}
|
||||||
|
|
||||||
// 解析温度 (索引5-6)
|
// 使用Protocol标准方法解析温度
|
||||||
tempRaw := int16(p.RawData[5])<<8 | int16(p.RawData[6])
|
if temp, err := protocol.GetTemperature(); err == nil {
|
||||||
data.Temperature = float64(tempRaw) / 10.0
|
data.Temperature = temp.Complete.Value
|
||||||
|
}
|
||||||
|
|
||||||
// 解析湿度 (索引7-8)
|
// 使用Protocol标准方法解析湿度
|
||||||
humRaw := int16(p.RawData[7])<<8 | int16(p.RawData[8])
|
if humidity, err := protocol.GetHumidity(); err == nil {
|
||||||
data.Humidity = float64(humRaw) / 10.0
|
data.Humidity = float64(humidity.Complete.Value)
|
||||||
|
}
|
||||||
|
|
||||||
// 解析风速 (索引9-10)
|
// 使用Protocol标准方法解析风速
|
||||||
windSpeedRaw := int16(p.RawData[9])<<8 | int16(p.RawData[10])
|
if windSpeed, err := protocol.GetWindSpeed(); err == nil {
|
||||||
data.WindSpeed = float64(windSpeedRaw) / 10.0
|
data.WindSpeed = windSpeed.Complete.Value
|
||||||
|
}
|
||||||
|
|
||||||
// 解析风向 (索引11-12)
|
// 使用Protocol标准方法解析风向
|
||||||
windDirRaw := int16(p.RawData[11])<<8 | int16(p.RawData[12])
|
if windDir, err := protocol.GetWindDirection(); err == nil {
|
||||||
data.WindDirection = float64(windDirRaw)
|
data.WindDirection = windDir.Complete.Degree
|
||||||
|
}
|
||||||
|
|
||||||
// 解析雨量 (索引13-14)
|
// 使用Protocol标准方法解析降雨量
|
||||||
rainRaw := int16(p.RawData[13])<<8 | int16(p.RawData[14])
|
if rainfall, err := protocol.GetRainfall(); err == nil {
|
||||||
data.Rainfall = float64(rainRaw) / 10.0
|
data.Rainfall = rainfall.Complete.Value
|
||||||
|
}
|
||||||
|
|
||||||
// 解析光照 (索引15-16)
|
// 使用Protocol标准方法解析光照
|
||||||
lightRaw := int16(p.RawData[15])<<8 | int16(p.RawData[16])
|
if light, err := protocol.GetLight(); err == nil {
|
||||||
data.Light = float64(lightRaw)
|
data.Light = light.Complete.Value
|
||||||
|
}
|
||||||
|
|
||||||
// 解析紫外线 (索引17-18)
|
// 使用Protocol标准方法解析UV指数
|
||||||
uvRaw := int16(p.RawData[17])<<8 | int16(p.RawData[18])
|
if uv, err := protocol.GetUVIndex(); err == nil {
|
||||||
data.UV = float64(uvRaw) / 10.0
|
data.UV = uv.Complete.Value
|
||||||
|
}
|
||||||
|
|
||||||
// 解析气压 (索引19-20)
|
// 使用Protocol标准方法解析气压
|
||||||
pressureRaw := int16(p.RawData[19])<<8 | int16(p.RawData[20])
|
if pressure, err := protocol.GetPressure(); err == nil {
|
||||||
data.Pressure = float64(pressureRaw) / 10.0
|
data.Pressure = pressure.Complete.Value
|
||||||
|
}
|
||||||
|
|
||||||
return data, nil
|
return data, nil
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user