From 9a0117f84f450d00fb7c9e77e19b24bb92134f01 Mon Sep 17 00:00:00 2001 From: yarnom Date: Sat, 2 Aug 2025 01:00:31 +0800 Subject: [PATCH] feat: add a new 485 type weather station --- model/weather_data.go | 56 ++++++++++++++++++++++++++++--------------- 1 file changed, 37 insertions(+), 19 deletions(-) diff --git a/model/weather_data.go b/model/weather_data.go index 9674091..ec4f36a 100644 --- a/model/weather_data.go +++ b/model/weather_data.go @@ -233,51 +233,71 @@ type WH65LPData struct { WSPFlag bool // 风速标志位 } +// 辅助函数:将byte转换为二进制字符串 +func byteToBinary(b byte) string { + return fmt.Sprintf("%08b", b) +} + // ParseWH65LPData 解析WH65LP设备的25字节数据 func ParseWH65LPData(data []byte) (*WH65LPData, error) { if len(data) != 25 { return nil, fmt.Errorf("数据长度错误:期望25字节,实际%d字节", len(data)) } + fmt.Printf("\n=== 数据包解析详情 ===\n") + fmt.Printf("原始数据(25字节):\n") + for i, b := range data { + fmt.Printf("字节[%2d]: 0x%02X (二进制: %s)\n", i, b, byteToBinary(b)) + } + fmt.Printf("\n") + wd := &WH65LPData{ Timestamp: time.Now(), } // 1. 家族码 (第1字节,bits 0-7) wd.FamilyCode = data[0] - if wd.FamilyCode != 0x24 { - return nil, fmt.Errorf("无效的家族码:0x%02X", wd.FamilyCode) - } + fmt.Printf("1. 家族码: 0x%02X\n", wd.FamilyCode) // 2. 设备ID (第2字节 + 第22-23字节) - id := (uint32(data[22])<<8|uint32(data[21]))<<8 | uint32(data[1]) + idLSB := uint32(data[1]) + idMSB := uint32(data[22])<<8 | uint32(data[21]) + id := (idMSB << 8) | idLSB wd.StationID = fmt.Sprintf("%06X", id) + fmt.Printf("2. 设备ID: LSB=0x%02X, MSB=0x%04X, 完整ID=0x%06X\n", idLSB, idMSB, id) // 3. 风向 (bits 16-24) - windDir := uint16(data[2]) | ((uint16(data[3]) & 0x01) << 8) + windDirLow := uint16(data[2]) + windDirHigh := uint16(data[3] & 0x01) + windDir := windDirLow | (windDirHigh << 8) wd.WindDirection = int(windDir) % 360 + fmt.Printf("3. 风向: Low=0x%02X (%s), High=%d, 角度=%d°\n", + data[2], byteToBinary(data[2]), windDirHigh, wd.WindDirection) // 4. WSP_FLAG (bit 25) wd.WSPFlag = (data[3]>>1)&0x01 == 1 + fmt.Printf("4. WSP_FLAG: %v (字节3=%s)\n", wd.WSPFlag, byteToBinary(data[3])) // 5. 风速高2位 (bits 26-27) wspHigh := (data[3] >> 2) & 0x03 + fmt.Printf("5. 风速高2位: 0x%X (字节3位6-7=%s)\n", wspHigh, byteToBinary(data[3])[2:4]) // 6. 低电量标志 (bit 28) wd.LowBattery = (data[3]>>4)&0x01 == 1 + fmt.Printf("6. 低电量: %v (字节3位4=%d)\n", wd.LowBattery, (data[3]>>4)&0x01) - // 7. 温度 (bits 29-39) - 11位数据 - // 根据示例数据分析,温度应该是: - // - 第4字节的全部8位 (0xB3) - // - 第5字节的低3位 (0x4A & 0x07 = 0x02) + // 7. 温度 (bits 29-39) tempLow := uint16(data[4]) tempHigh := uint16(data[5] & 0x07) tempRaw := tempLow | (tempHigh << 8) wd.Temperature = float64(tempRaw-400) / 10.0 + fmt.Printf("7. 温度: Low=0x%02X (%s), High=0x%X, Raw=0x%X, 温度=%.1f°C\n", + data[4], byteToBinary(data[4]), tempHigh, tempRaw, wd.Temperature) // 8. 湿度 (bits 40-47) - // 湿度应该是第5字节的高5位 wd.Humidity = int(data[5] >> 3) + fmt.Printf("8. 湿度: 字节5=0x%02X (%s), 湿度=%d%%\n", + data[5], byteToBinary(data[5]), wd.Humidity) // 9. 风速 (bits 48-55 + WSP_9,WSP_8) windSpeedRaw := uint16(data[6]) @@ -285,39 +305,37 @@ func ParseWH65LPData(data []byte) (*WH65LPData, error) { windSpeedRaw |= uint16(wspHigh) << 8 } wd.WindSpeed = float64(windSpeedRaw) / 8.0 * 0.51 + fmt.Printf("9. 风速: Raw=0x%X, 风速=%.2f m/s\n", windSpeedRaw, wd.WindSpeed) // 10. 阵风 (bits 56-63) wd.WindGust = float64(data[7]) * 0.51 + fmt.Printf("10. 阵风: Raw=0x%02X, 阵风=%.2f m/s\n", data[7], wd.WindGust) // 11. 降雨量 (bits 64-79) rainRaw := uint16(data[8]) | uint16(data[9])<<8 wd.Rain = float64(rainRaw) * 0.254 + fmt.Printf("11. 降雨量: Raw=0x%04X, 降雨量=%.3f mm\n", rainRaw, wd.Rain) // 12. 紫外线 (bits 80-95) uvRaw := uint16(data[10]) | uint16(data[11])<<8 wd.UV = getUVIndex(uvRaw) + fmt.Printf("12. 紫外线: Raw=0x%04X, UV指数=%d\n", uvRaw, wd.UV) // 13. 光照 (bits 96-119) lightRaw := uint32(data[12]) | uint32(data[13])<<8 | uint32(data[14])<<16 wd.Light = float64(lightRaw) / 10.0 + fmt.Printf("13. 光照: Raw=0x%06X, 光照=%.1f lux\n", lightRaw, wd.Light) // 14. 气压 (bits 136-159) - // 根据示例数据分析,气压应该是: - // - 第18字节 (0x01) - // - 第19字节 (0x83) - // - 第20字节的低1位 (0x30 & 0x01 = 0x00) pressureRaw := uint32(data[17]) | uint32(data[18])<<8 | (uint32(data[19])&0x01)<<16 if pressureRaw == 0x1FFFF { wd.Pressure = 0 // 无效值 } else { wd.Pressure = float64(pressureRaw) / 100.0 } + fmt.Printf("14. 气压: Raw=0x%05X, 气压=%.2f hPa\n", pressureRaw, wd.Pressure) - // 添加调试信息,帮助分析 - fmt.Printf("调试信息:\n") - fmt.Printf("温度原始值: 0x%X (%d), 计算温度: %.1f°C\n", tempRaw, tempRaw, wd.Temperature) - fmt.Printf("湿度原始值: 0x%X (%d)\n", data[5]>>3, data[5]>>3) - fmt.Printf("气压原始值: 0x%X (%d), 计算气压: %.2f hPa\n", pressureRaw, pressureRaw, wd.Pressure) + fmt.Printf("\n=== 解析结果 ===\n%s\n", wd.String()) return wd, nil }