feat: add a new 485 type weather station

This commit is contained in:
yarnom 2025-08-01 21:34:35 +08:00
parent 53cea255ee
commit 67fe281c0a

View File

@ -255,49 +255,59 @@ func ParseWH65LPData(data []byte) (*WH65LPData, error) {
wd.StationID = fmt.Sprintf("%06X", (idMSB<<8)|uint32(idLSB))
// 3. 解析风向 (bits 16-24)
windDir := uint16(data[2]) | (uint16(data[3]&0x01) << 8)
wd.WindDirection = int(windDir)
// 第3字节完整8位 + 第4字节的最低位
windDir := uint16(data[2]) | ((uint16(data[3]) & 0x01) << 8)
wd.WindDirection = int(windDir) % 360
// 4. 解析风速标志和温度
// 4. 风速标志和温度
// WSP_FLAG 在第4字节的第2位 (bit 25)
wd.WSPFlag = (data[3]>>1)&0x01 == 1
// 低电量标志在第4字节的第4位 (bit 28)
wd.LowBattery = (data[3]>>3)&0x01 == 1
// 温度 (11位bits 28-39)
tempRaw := uint16(data[4]) | (uint16(data[5]&0x07) << 8)
// 5. 温度 (bits 28-39)
// 从第4字节的高4位和第5字节的低3位组合出11位温度数据
tempRaw := ((uint16(data[3]) >> 4) & 0x07) | (uint16(data[4]) << 3)
wd.Temperature = float64(tempRaw-400) / 10.0
// 5. 湿度 (bits 40-47)
wd.Humidity = int(data[5] >> 3)
// 6. 湿度 (bits 40-47)
// 第5字节的高5位
wd.Humidity = int(data[4] >> 3)
// 6. 风速 (bits 48-55 + WSP_9,WSP_8)
// 7. 风速 (bits 48-55 + WSP_9,WSP_8)
windSpeedRaw := uint16(data[6])
if !wd.WSPFlag {
// 10位风速
// 10位风速从第4字节的bits 6-7获取高2位
windSpeedRaw |= uint16((data[3]>>6)&0x03) << 8
}
wd.WindSpeed = float64(windSpeedRaw) / 8.0 * 0.51
// 7. 阵风 (bits 56-63)
// 8. 阵风 (bits 56-63)
wd.WindGust = float64(data[7]) * 0.51
// 8. 降雨量 (bits 64-79)
// 9. 降雨量 (bits 64-79)
rainRaw := uint16(data[8]) | uint16(data[9])<<8
wd.Rain = float64(rainRaw) * 0.254
// 9. 紫外线 (bits 80-95)
// 10. 紫外线 (bits 80-95)
uvRaw := uint16(data[10]) | uint16(data[11])<<8
wd.UV = getUVIndex(uvRaw)
// 10. 光照 (bits 96-119)
// 11. 光照 (bits 96-119)
lightRaw := uint32(data[12]) | uint32(data[13])<<8 | uint32(data[14])<<16
wd.Light = float64(lightRaw) / 10.0
// 11. 气压 (bits 136-159)
// 12. 气压 (bits 136-159)
// 从第18-20字节提取17位气压数据
pressureRaw := uint32(data[17]) | uint32(data[18])<<8 | uint32(data[19])<<16
pressureRaw &= 0x1FFFF // 只取17位
pressureRaw &= 0x1FFFF
if pressureRaw == 0x1FFFF {
wd.Pressure = 0 // 无效值
} else {
wd.Pressure = float64(pressureRaw) / 100.0
}
// 验证校验和
// 13. 验证校验和
if !IsWH65LPData(data) {
return nil, fmt.Errorf("数据校验失败")
}
@ -305,6 +315,29 @@ func ParseWH65LPData(data []byte) (*WH65LPData, error) {
return wd, nil
}
// 调试辅助函数
func getBits(data []byte, startBit, length int) uint32 {
var result uint32
startByte := startBit / 8
startBitInByte := startBit % 8
// 从起始字节开始读取
result = uint32(data[startByte]) >> startBitInByte
bitsGot := 8 - startBitInByte
// 如果需要更多位,继续读取后续字节
for bitsGot < length {
startByte++
result |= uint32(data[startByte]) << bitsGot
bitsGot += 8
}
// 只保留需要的位数
result &= (1 << length) - 1
return result
}
// getUVIndex 根据UV原始值获取UV指数
func getUVIndex(uvRaw uint16) int {
switch {