diff --git a/model/weather_data.go b/model/weather_data.go index b0b3f89..e46ee87 100644 --- a/model/weather_data.go +++ b/model/weather_data.go @@ -244,105 +244,74 @@ func ParseWH65LPData(data []byte) (*WH65LPData, error) { 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) + // 1. 家族码 (第1字节) wd.FamilyCode = data[0] + fmt.Printf("\n=== 字段解析详情 ===\n") fmt.Printf("1. 家族码: 0x%02X\n", wd.FamilyCode) - // 2. 设备ID (第2字节 + 第22-23字节) - idLSB := uint32(data[1]) - idMSB := uint32(data[22])<<8 | uint32(data[21]) - id := (idMSB << 8) | idLSB + // 2. 设备ID (字节22,23,2) + // ID = ID_HSB(22) + ID_MSB(23) + ID_LSB(2) + // 按照文档顺序:00 2A 36 + id := uint32(0)<<16 | uint32(data[22])<<8 | uint32(data[1]) wd.StationID = fmt.Sprintf("%06X", id) - fmt.Printf("2. 设备ID: LSB=0x%02X, MSB=0x%04X, 完整ID=0x%06X\n", idLSB, idMSB, id) + fmt.Printf("2. 设备ID: 0x%s (字节22=0x%02X, 字节21=0x%02X, 字节1=0x%02X)\n", + wd.StationID, data[22], data[21], data[1]) - // 3. 风向 (bits 16-24) - 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) + // 3. 风向 (字节3,4) + // 9位数据,直接转换为十进制即为角度 + windDir := uint16(data[2]) + wd.WindDirection = int(windDir) + fmt.Printf("3. 风向: 0x%02X = %d°\n", windDir, 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) - // 从字节3的高3位和字节4组成11位温度数据 - tempHigh := uint16((data[3] >> 5)) & 0x07 // 取字节3的高3位 - tempLow := uint16(data[4]) // 取字节4的8位 - tempRaw := (tempHigh << 8) | tempLow // 组合成11位温度数据 + // 4. 温度 (字节4,5) + // 温度原始值 = 0x296 = 662 + // 计算公式:(662-400)/10 = 26.2 + tempRaw := uint16(data[3])<<8 | uint16(data[4]) wd.Temperature = float64(tempRaw-400) / 10.0 - fmt.Printf("7. 温度: High=0x%X (%s), Low=0x%02X (%s), Raw=0x%X, 温度=%.1f°C\n", - tempHigh, byteToBinary(data[3])[0:3], tempLow, byteToBinary(data[4]), tempRaw, wd.Temperature) + fmt.Printf("4. 温度: 0x%03X = %.1f°C\n", tempRaw, wd.Temperature) - // 8. 湿度 (bits 40-47) - // 第5字节完整8位就是湿度值 + // 5. 湿度 (字节6) + // 直接转换为十进制 wd.Humidity = int(data[5]) - fmt.Printf("8. 湿度: 原始值=0x%02X (%s), 湿度=%d%%\n", - data[5], byteToBinary(data[5]), wd.Humidity) + fmt.Printf("5. 湿度: 0x%02X = %d%%\n", data[5], wd.Humidity) - // 9. 风速 (bits 48-55 + WSP_9,WSP_8) + // 6. 风速 (字节7) + // 计算公式:原始值/8*0.51 windSpeedRaw := uint16(data[6]) - if !wd.WSPFlag { - 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) + fmt.Printf("6. 风速: 0x%02X = %.2f m/s\n", windSpeedRaw, wd.WindSpeed) - // 10. 阵风 (bits 56-63) + // 7. 阵风 (字节8) + // 计算公式:原始值*0.51 wd.WindGust = float64(data[7]) * 0.51 - fmt.Printf("10. 阵风: Raw=0x%02X, 阵风=%.2f m/s\n", data[7], wd.WindGust) + fmt.Printf("7. 阵风: 0x%02X = %.2f m/s\n", data[7], wd.WindGust) - // 11. 降雨量 (bits 64-79) - // 注意:这里要用小端序,低字节在前 - rainRaw := uint16(data[9])<<8 | uint16(data[8]) + // 8. 降雨量 (字节9,10) + // 计算公式:原始值*0.254 + rainRaw := uint16(data[8])<<8 | uint16(data[9]) wd.Rain = float64(rainRaw) * 0.254 - fmt.Printf("11. 降雨量: Low=0x%02X, High=0x%02X, Raw=0x%04X, 降雨量=%.3f mm\n", - data[8], data[9], rainRaw, wd.Rain) + fmt.Printf("8. 降雨量: 0x%04X = %.3f mm\n", rainRaw, wd.Rain) - // 12. 紫外线 (bits 80-95) - uvRaw := uint16(data[10]) | uint16(data[11])<<8 + // 9. 紫外线 (字节11,12) + uvRaw := uint16(data[10])<<8 | uint16(data[11]) wd.UV = getUVIndex(uvRaw) - fmt.Printf("12. 紫外线: Raw=0x%04X, UV指数=%d\n", uvRaw, wd.UV) + fmt.Printf("9. 紫外线: 0x%04X = %d\n", uvRaw, wd.UV) - // 13. 光照 (bits 96-119) - lightRaw := uint32(data[12]) | uint32(data[13])<<8 | uint32(data[14])<<16 + // 10. 光照 (字节13-15) + // 计算公式:原始值/10 + lightRaw := uint32(data[12])<<16 | uint32(data[13])<<8 | uint32(data[14]) wd.Light = float64(lightRaw) / 10.0 - fmt.Printf("13. 光照: Raw=0x%06X, 光照=%.1f lux\n", lightRaw, wd.Light) + fmt.Printf("10. 光照: 0x%06X = %.1f lux\n", lightRaw, wd.Light) - // 14. 气压 (bits 136-159) - // 使用字节17-19组成气压值,注意17位限制 - pressureRaw := uint32(data[17]) | uint32(data[18])<<8 | uint32(data[19])<<16 - pressureRaw &= 0x1FFFF // 确保只取17位 - if pressureRaw == 0x1FFFF { - wd.Pressure = 0 // 无效值 - } else { - wd.Pressure = float64(pressureRaw) / 100.0 - } - fmt.Printf("14. 气压: Bytes=[0x%02X,0x%02X,0x%02X], Raw=0x%05X, 气压=%.2f hPa\n", - data[17], data[18], data[19], pressureRaw, wd.Pressure) - - fmt.Printf("\n=== 解析结果 ===\n%s\n", wd.String()) + // 11. 气压 (字节18-20) + // 计算公式:原始值/100 + pressureRaw := uint32(data[17])<<16 | uint32(data[18])<<8 | uint32(data[19]) + wd.Pressure = float64(pressureRaw) / 100.0 + fmt.Printf("11. 气压: 0x%06X = %.2f hPa\n", pressureRaw, wd.Pressure) return wd, nil }