feat: 新增 485 的解析
This commit is contained in:
parent
bc3290c501
commit
6e643497a1
146
main.go
146
main.go
@ -128,45 +128,43 @@ func startUDP() {
|
||||
asciiDump := asciiDump(rawData)
|
||||
log.Printf("ASCII码:\n%s", asciiDump)
|
||||
|
||||
data, deviceType, err := model.ParseData(rawData)
|
||||
if err != nil {
|
||||
log.Printf("解析数据失败: %v", err)
|
||||
continue
|
||||
}
|
||||
// 检查数据是否为RS485格式
|
||||
if len(rawData) == 25 && rawData[0] == 0x24 {
|
||||
// 解析RS485数据
|
||||
hexStr := strings.ReplaceAll(hexDump, "\n", " ")
|
||||
parseHexData(hexStr)
|
||||
|
||||
log.Println("成功解析气象站数据:")
|
||||
log.Printf("设备类型: %s", getDeviceTypeString(deviceType))
|
||||
log.Println(data)
|
||||
|
||||
// 如果是RS485数据,打印更详细的信息
|
||||
if deviceType == model.DeviceTypeRS485 {
|
||||
if rs485Data, ok := data.(*model.RS485WeatherData); ok {
|
||||
log.Println("RS485数据详情:")
|
||||
log.Printf("设备ID: %s", rs485Data.DeviceID)
|
||||
log.Printf("温度: %.2f°C", rs485Data.Temperature)
|
||||
log.Printf("湿度: %.2f%%", rs485Data.Humidity)
|
||||
log.Printf("风向: %.2f°", rs485Data.WindDirection)
|
||||
log.Printf("风速: %.2f m/s", rs485Data.WindSpeed)
|
||||
log.Printf("降雨量: %.2f mm", rs485Data.Rainfall)
|
||||
log.Printf("光照: %.2f lux", rs485Data.Light)
|
||||
log.Printf("紫外线: %.2f", rs485Data.UV)
|
||||
log.Printf("气压: %.2f hPa", rs485Data.Pressure)
|
||||
// 注册设备
|
||||
protocol := model.NewProtocol(rawData)
|
||||
idParts, err := protocol.GetCompleteID()
|
||||
if err == nil {
|
||||
stationID := fmt.Sprintf("RS485-%s", idParts.Complete.Hex)
|
||||
model.RegisterDevice(stationID, addr)
|
||||
log.Printf("设备 %s 已注册,IP: %s", stationID, addr.String())
|
||||
}
|
||||
}
|
||||
|
||||
var stationID string
|
||||
switch v := data.(type) {
|
||||
case *model.WeatherData:
|
||||
stationID = v.StationID
|
||||
case *model.RS485WeatherData:
|
||||
stationID = fmt.Sprintf("RS485-%s", v.DeviceID)
|
||||
}
|
||||
|
||||
if stationID != "" {
|
||||
model.RegisterDevice(stationID, addr)
|
||||
log.Printf("设备 %s 已注册,IP: %s", stationID, addr.String())
|
||||
} else {
|
||||
log.Printf("警告: 收到的数据没有站点ID")
|
||||
// 尝试解析WIFI数据
|
||||
data, deviceType, err := model.ParseData(rawData)
|
||||
if err != nil {
|
||||
log.Printf("解析数据失败: %v", err)
|
||||
continue
|
||||
}
|
||||
|
||||
log.Println("成功解析气象站数据:")
|
||||
log.Printf("设备类型: %s", getDeviceTypeString(deviceType))
|
||||
log.Println(data)
|
||||
|
||||
if deviceType == model.DeviceTypeWIFI {
|
||||
if wifiData, ok := data.(*model.WeatherData); ok {
|
||||
stationID := wifiData.StationID
|
||||
if stationID != "" {
|
||||
model.RegisterDevice(stationID, addr)
|
||||
log.Printf("设备 %s 已注册,IP: %s", stationID, addr.String())
|
||||
} else {
|
||||
log.Printf("警告: 收到的数据没有站点ID")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 暂时不保存到数据库
|
||||
@ -191,8 +189,21 @@ func getDeviceTypeString(deviceType model.DeviceType) string {
|
||||
}
|
||||
|
||||
func main() {
|
||||
setupLogger()
|
||||
startUDP()
|
||||
// 检查是否有命令行参数
|
||||
if len(os.Args) > 1 && os.Args[1] == "parse" {
|
||||
if len(os.Args) > 2 {
|
||||
// 解析指定的十六进制数据
|
||||
hexData := os.Args[2]
|
||||
parseHexData(hexData)
|
||||
} else {
|
||||
fmt.Println("用法: ./weatherstation parse <十六进制数据>")
|
||||
fmt.Println("示例: ./weatherstation parse \"24 F2 10 02 C7 48 10 03 00 6A 03 E8 05 F5 96 10 3F 01 83 2D B1 00 29 9B A4\"")
|
||||
}
|
||||
} else {
|
||||
// 正常启动服务器
|
||||
setupLogger()
|
||||
startUDP()
|
||||
}
|
||||
}
|
||||
|
||||
func hexDump(data []byte) string {
|
||||
@ -234,3 +245,62 @@ func asciiDump(data []byte) string {
|
||||
}
|
||||
return result.String()
|
||||
}
|
||||
|
||||
// parseHexData 解析十六进制字符串数据
|
||||
func parseHexData(hexStr string) {
|
||||
// 移除所有空格
|
||||
hexStr = strings.ReplaceAll(hexStr, " ", "")
|
||||
|
||||
// 将十六进制字符串转换为字节数组
|
||||
data, err := hex.DecodeString(hexStr)
|
||||
if err != nil {
|
||||
log.Printf("解析十六进制字符串失败: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
// 检查数据有效性
|
||||
if !model.ValidateRS485Data(data) {
|
||||
log.Printf("无效的RS485数据格式: 长度=%d, 起始字节=%02X", len(data), data[0])
|
||||
return
|
||||
}
|
||||
|
||||
// 创建协议解析器
|
||||
protocol := model.NewProtocol(data)
|
||||
rs485Protocol := model.NewRS485Protocol(data)
|
||||
|
||||
// 获取设备ID
|
||||
idParts, err := protocol.GetCompleteID()
|
||||
if err != nil {
|
||||
log.Printf("获取设备ID失败: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
// 解析RS485数据
|
||||
rs485Data, err := rs485Protocol.ParseRS485Data()
|
||||
if err != nil {
|
||||
log.Printf("解析RS485数据失败: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
// 添加设备ID和时间戳
|
||||
rs485Data.DeviceID = idParts.Complete.Hex
|
||||
rs485Data.ReceivedAt = time.Now()
|
||||
rs485Data.RawDataHex = fmt.Sprintf("%X", data)
|
||||
|
||||
// 打印解析结果
|
||||
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("湿度: %.1f%%", rs485Data.Humidity)
|
||||
log.Printf("风向: %.1f°", rs485Data.WindDirection)
|
||||
log.Printf("风速: %.2f m/s", rs485Data.WindSpeed)
|
||||
log.Printf("降雨量: %.2f mm", rs485Data.Rainfall)
|
||||
log.Printf("光照: %.2f lux", rs485Data.Light)
|
||||
log.Printf("紫外线: %.2f", rs485Data.UV)
|
||||
log.Printf("气压: %.2f hPa", rs485Data.Pressure)
|
||||
}
|
||||
|
||||
@ -549,8 +549,8 @@ func TestGetPressure(t *testing.T) {
|
||||
|
||||
func TestParseNewData(t *testing.T) {
|
||||
// 新的测试数据:24 F2 30 02 AF 51 03 01 00 08 00 00 00 00 00 6E C2 01 82 D8 5B 00 29 87 EA
|
||||
data := []byte{0x24, 0xF2, 0x30, 0x02, 0xAF, 0x51, 0x03, 0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6E, 0xC2, 0x01, 0x82, 0xD8, 0x5B, 0x00, 0x29, 0x87, 0xEA}
|
||||
|
||||
//data := []byte{0x24, 0xF2, 0x30, 0x02, 0xAF, 0x51, 0x03, 0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6E, 0xC2, 0x01, 0x82, 0xD8, 0x5B, 0x00, 0x29, 0x87, 0xEA}
|
||||
data := []byte{0x24, 0xF2, 0x10, 0x02, 0xC7, 0x48, 0x10, 0x03, 0x00, 0x6A, 0x03, 0xE8, 0x05, 0xF5, 0x96, 0x10, 0x3F, 0x01, 0x83, 0x2D, 0xB1, 0x00, 0x29, 0x9B, 0xA4}
|
||||
protocol := NewProtocol(data)
|
||||
|
||||
// 1. 解析风速
|
||||
@ -686,3 +686,130 @@ func TestParseNewDataWithDetails(t *testing.T) {
|
||||
t.Logf("设备ID: %02X %02X %02X", id.HSB.Dec, id.MSB.Dec, id.LSB.Dec)
|
||||
t.Logf("原始字节: HSB=%02X, MSB=%02X, LSB=%02X", data[21], data[22], data[1])
|
||||
}
|
||||
|
||||
func TestParseSpecificData(t *testing.T) {
|
||||
// 测试数据:24 F2 10 02 C7 48 10 03 00 6A 03 E8 05 F5 96 10 3F 01 83 2D B1 00 29 9B A4
|
||||
data := []byte{0x24, 0xF2, 0x10, 0x02, 0xC7, 0x48, 0x10, 0x03, 0x00, 0x6A, 0x03, 0xE8, 0x05, 0xF5, 0x96, 0x10, 0x3F, 0x01, 0x83, 0x2D, 0xB1, 0x00, 0x29, 0x9B, 0xA4}
|
||||
|
||||
protocol := NewProtocol(data)
|
||||
|
||||
t.Log("\n=== 特定数据解析测试 ===")
|
||||
|
||||
// 1. 设备ID解析
|
||||
t.Log("\n=== 设备ID解析 ===")
|
||||
id, err := protocol.GetCompleteID()
|
||||
if err != nil {
|
||||
t.Fatalf("获取设备ID失败: %v", err)
|
||||
}
|
||||
t.Logf("设备ID: %s", id.Complete.Hex)
|
||||
t.Logf("原始字节: HSB=%02X, MSB=%02X, LSB=%02X", data[21], data[22], data[1])
|
||||
|
||||
// 2. 温度解析
|
||||
t.Log("\n=== 温度解析 ===")
|
||||
temp, err := protocol.GetTemperature()
|
||||
if err != nil {
|
||||
t.Fatalf("获取温度失败: %v", err)
|
||||
}
|
||||
t.Logf("温度: %.2f °C (raw: 0x%X)", temp.Complete.Value, temp.Complete.RawValue)
|
||||
t.Logf("TMP_H: %s (0x%X), TMP_M: %s (0x%X), TMP_L: %s (0x%X)",
|
||||
temp.TmpH.Binary, temp.TmpH.Value,
|
||||
temp.TmpM.Binary, temp.TmpM.Value,
|
||||
temp.TmpL.Binary, temp.TmpL.Value)
|
||||
|
||||
// 3. 湿度解析
|
||||
t.Log("\n=== 湿度解析 ===")
|
||||
humidity, err := protocol.GetHumidity()
|
||||
if err != nil {
|
||||
t.Fatalf("获取湿度失败: %v", err)
|
||||
}
|
||||
t.Logf("湿度: %d%% (raw: 0x%X)", humidity.Complete.Value, humidity.Complete.RawValue)
|
||||
t.Logf("HM_H: %s (0x%X), HM_L: %s (0x%X)",
|
||||
humidity.HmH.Binary, humidity.HmH.Value,
|
||||
humidity.HmL.Binary, humidity.HmL.Value)
|
||||
|
||||
// 4. 风速解析
|
||||
t.Log("\n=== 风速解析 ===")
|
||||
windSpeed, err := protocol.GetWindSpeed()
|
||||
if err != nil {
|
||||
t.Fatalf("获取风速失败: %v", err)
|
||||
}
|
||||
t.Logf("风速: %.5f m/s (raw: 0x%X)", windSpeed.Complete.Value, windSpeed.Complete.RawValue)
|
||||
t.Logf("WSP_FLAG: %v", windSpeed.WspFlag.Value)
|
||||
t.Logf("WSP_H: %s (0x%X), WSP_L: %s (0x%X)",
|
||||
windSpeed.WspH.Binary, windSpeed.WspH.Value,
|
||||
windSpeed.WspL.Binary, windSpeed.WspL.Value)
|
||||
|
||||
// 5. 风向解析
|
||||
t.Log("\n=== 风向解析 ===")
|
||||
windDir, err := protocol.GetWindDirection()
|
||||
if err != nil {
|
||||
t.Fatalf("获取风向失败: %v", err)
|
||||
}
|
||||
t.Logf("风向: %.1f° (raw: 0x%X)", windDir.Complete.Degree, windDir.Complete.Value)
|
||||
t.Logf("DirH: %s (0x%X), DirM: %s (0x%X), DirL: %s (0x%X)",
|
||||
windDir.DirH.Binary, windDir.DirH.Value,
|
||||
windDir.DirM.Binary, windDir.DirM.Value,
|
||||
windDir.DirL.Binary, windDir.DirL.Value)
|
||||
|
||||
// 6. 降雨量解析
|
||||
t.Log("\n=== 降雨量解析 ===")
|
||||
rainfall, err := protocol.GetRainfall()
|
||||
if err != nil {
|
||||
t.Fatalf("获取降雨量失败: %v", err)
|
||||
}
|
||||
t.Logf("降雨量: %.3f mm (raw: 0x%X)", rainfall.Complete.Value, rainfall.Complete.RawValue)
|
||||
t.Logf("原始字节: %02X %02X", data[8], data[9])
|
||||
|
||||
// 7. 光照解析
|
||||
t.Log("\n=== 光照解析 ===")
|
||||
light, err := protocol.GetLight()
|
||||
if err != nil {
|
||||
t.Fatalf("获取光照失败: %v", err)
|
||||
}
|
||||
t.Logf("光照: %.1f lux (raw: 0x%X)", light.Complete.Value, light.Complete.RawValue)
|
||||
t.Logf("原始字节: %02X %02X %02X", data[12], data[13], data[14])
|
||||
|
||||
// 8. UV指数解析
|
||||
t.Log("\n=== UV指数解析 ===")
|
||||
uv, err := protocol.GetUVIndex()
|
||||
if err != nil {
|
||||
t.Fatalf("获取UV指数失败: %v", err)
|
||||
}
|
||||
t.Logf("UV指数: %.1f uW/c㎡ (raw: 0x%X)", uv.Complete.Value, uv.Complete.RawValue)
|
||||
t.Logf("原始字节: %02X %02X", data[10], data[11])
|
||||
|
||||
// 9. 气压解析
|
||||
t.Log("\n=== 气压解析 ===")
|
||||
pressure, err := protocol.GetPressure()
|
||||
if err != nil {
|
||||
t.Fatalf("获取气压失败: %v", err)
|
||||
}
|
||||
t.Logf("气压: %.2f hPa (raw: 0x%X)", pressure.Complete.Value, pressure.Complete.RawValue)
|
||||
t.Logf("原始字节: %02X %02X %02X", data[17], data[18], data[19])
|
||||
|
||||
// 10. 阵风速度解析
|
||||
t.Log("\n=== 阵风速度解析 ===")
|
||||
gust, err := protocol.GetGustSpeed()
|
||||
if err != nil {
|
||||
t.Fatalf("获取阵风速度失败: %v", err)
|
||||
}
|
||||
t.Logf("阵风速度: %.2f m/s (raw: 0x%X)", gust.Complete.Value, gust.Complete.RawValue)
|
||||
t.Logf("原始字节: %02X", data[7])
|
||||
|
||||
// 11. 创建RS485协议解析器并解析数据
|
||||
t.Log("\n=== RS485协议解析 ===")
|
||||
rs485Protocol := NewRS485Protocol(data)
|
||||
rs485Data, err := rs485Protocol.ParseRS485Data()
|
||||
if err != nil {
|
||||
t.Fatalf("RS485数据解析失败: %v", err)
|
||||
}
|
||||
|
||||
t.Logf("温度: %.2f°C", rs485Data.Temperature)
|
||||
t.Logf("湿度: %.1f%%", rs485Data.Humidity)
|
||||
t.Logf("风速: %.2f m/s", rs485Data.WindSpeed)
|
||||
t.Logf("风向: %.1f°", rs485Data.WindDirection)
|
||||
t.Logf("降雨量: %.3f mm", rs485Data.Rainfall)
|
||||
t.Logf("光照: %.1f lux", rs485Data.Light)
|
||||
t.Logf("紫外线: %.1f", rs485Data.UV)
|
||||
t.Logf("气压: %.2f hPa", rs485Data.Pressure)
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user