feat: 新增 485 的解析

This commit is contained in:
yarnom 2025-08-03 11:25:54 +08:00
parent 523f489e11
commit cb1728ef00
4 changed files with 56 additions and 71 deletions

View File

@ -143,11 +143,7 @@ func startUDP() {
case *model.WeatherData: case *model.WeatherData:
stationID = v.StationID stationID = v.StationID
case *model.RS485WeatherData: case *model.RS485WeatherData:
// 设备ID格式: HSB(21) MSB(22) LSB(1) stationID = fmt.Sprintf("RS485-%s", v.DeviceID)
hsb := rawData[21] // HSB: bit 168-175 (索引21)
msb := rawData[22] // MSB: bit 176-183 (索引22)
lsb := rawData[1] // LSB: bit 8-15 (索引1)
stationID = fmt.Sprintf("RS485-%02X%02X%02X", hsb, msb, lsb)
} }
if stationID != "" { if stationID != "" {

View File

@ -136,7 +136,8 @@ func saveWIFIWeatherData(data *WeatherData, rawData string) error {
} }
func saveRS485WeatherData(data *RS485WeatherData) error { func saveRS485WeatherData(data *RS485WeatherData) error {
err := ensureStationExists(data.StationID, "") stationID := fmt.Sprintf("RS485-%s", data.DeviceID)
err := ensureStationExists(stationID, "")
if err != nil { if err != nil {
return err return err
} }
@ -146,10 +147,10 @@ func saveRS485WeatherData(data *RS485WeatherData) error {
station_id, timestamp, temperature, humidity, wind_speed, station_id, timestamp, temperature, humidity, wind_speed,
wind_direction, rainfall, light, uv, pressure, raw_data wind_direction, rainfall, light, uv, pressure, raw_data
) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)`, ) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)`,
data.StationID, data.Timestamp, stationID, data.ReceivedAt,
data.Temperature, data.Humidity, data.WindSpeed, data.Temperature, data.Humidity, data.WindSpeed,
data.WindDirection, data.Rainfall, data.Light, data.WindDirection, data.Rainfall, data.Light,
data.UV, data.Pressure, data.RawData) data.UV, data.Pressure, data.RawDataHex)
if err != nil { if err != nil {
return fmt.Errorf("保存RS485气象数据失败: %v", err) return fmt.Errorf("保存RS485气象数据失败: %v", err)

View File

@ -2,6 +2,7 @@ package model
import ( import (
"fmt" "fmt"
"time"
) )
// Protocol 定义协议结构 // Protocol 定义协议结构
@ -768,6 +769,9 @@ type RS485WeatherData struct {
Light float64 // 光照 Light float64 // 光照
UV float64 // 紫外线 UV float64 // 紫外线
Pressure float64 // 气压 Pressure float64 // 气压
DeviceID string // 设备ID
ReceivedAt time.Time // 接收时间
RawDataHex string // 原始数据十六进制
} }
// ParseRS485Data 解析RS485数据 // ParseRS485Data 解析RS485数据
@ -812,3 +816,29 @@ func (p *RS485Protocol) ParseRS485Data() (*RS485WeatherData, error) {
return data, nil return data, nil
} }
// String 返回RS485WeatherData的字符串表示
func (w *RS485WeatherData) String() string {
return fmt.Sprintf(`
设备ID: RS485-%s
温度: %.1f°C
湿度: %.1f%%
风向: %.1f°
风速: %.2f m/s
降雨量: %.2f mm
光照: %.2f lux
紫外线: %.2f
气压: %.2f hPa
时间: %s`,
w.DeviceID,
w.Temperature,
w.Humidity,
w.WindDirection,
w.WindSpeed,
w.Rainfall,
w.Light,
w.UV,
w.Pressure,
w.ReceivedAt.Format("2006-01-02 15:04:05"),
)
}

View File

@ -47,47 +47,30 @@ type WeatherData struct {
RTFreq int RTFreq int
} }
// RS485WeatherData 存储RS485设备的气象数据
type RS485WeatherData struct {
StationID string // 站点ID
Timestamp time.Time // 时间戳
Temperature float64 // 温度
Humidity float64 // 湿度
WindSpeed float64 // 风速
WindDirection float64 // 风向
Rainfall float64 // 雨量
Light float64 // 光照
UV float64 // 紫外线
Pressure float64 // 气压
RawData string // 原始数据
}
var urlRegex = regexp.MustCompile(`/weatherstation/updateweatherstation\.php\?([^&\s]+(&[^&\s]+)*)`) var urlRegex = regexp.MustCompile(`/weatherstation/updateweatherstation\.php\?([^&\s]+(&[^&\s]+)*)`)
// ParseData 根据数据类型解析气象数据 // ParseData 根据数据类型解析气象数据
func ParseData(data []byte) (interface{}, DeviceType, error) { func ParseData(data []byte) (interface{}, DeviceType, error) {
// 检查是否为RS485数据 // 检查是否为RS485数据
if len(data) == 25 && data[0] == 0x24 { if len(data) == 25 && data[0] == 0x24 {
protocol := NewRS485Protocol(data) protocol := NewProtocol(data)
rs485Data, err := protocol.ParseRS485Data() rs485Protocol := NewRS485Protocol(data)
rs485Data, err := rs485Protocol.ParseRS485Data()
if err != nil { if err != nil {
return nil, DeviceTypeRS485, err return nil, DeviceTypeRS485, err
} }
weatherData := &RS485WeatherData{ // 获取设备ID
StationID: fmt.Sprintf("RS485-%02X%02X", data[1], data[2]), idParts, err := protocol.GetCompleteID()
Timestamp: time.Now(), if err != nil {
Temperature: rs485Data.Temperature, return nil, DeviceTypeRS485, fmt.Errorf("获取设备ID失败: %v", err)
Humidity: rs485Data.Humidity,
WindSpeed: rs485Data.WindSpeed,
WindDirection: rs485Data.WindDirection,
Rainfall: rs485Data.Rainfall,
Light: rs485Data.Light,
UV: rs485Data.UV,
Pressure: rs485Data.Pressure,
RawData: fmt.Sprintf("%X", data),
} }
return weatherData, DeviceTypeRS485, nil
rs485Data.DeviceID = idParts.Complete.Hex
rs485Data.ReceivedAt = time.Now()
rs485Data.RawDataHex = fmt.Sprintf("%X", data)
return rs485Data, DeviceTypeRS485, nil
} }
// 尝试解析为WIFI数据 // 尝试解析为WIFI数据
@ -256,28 +239,3 @@ func (w *WeatherData) String() string {
w.DateUTC, w.DateUTC,
) )
} }
func (w *RS485WeatherData) String() string {
return fmt.Sprintf(`
站点ID: %s
温度: %.1f°C
湿度: %.1f%%
风向: %.1f°
风速: %.2f m/s
降雨量: %.2f mm
光照: %.2f lux
紫外线: %.2f
气压: %.2f hPa
时间: %s`,
w.StationID,
w.Temperature,
w.Humidity,
w.WindDirection,
w.WindSpeed,
w.Rainfall,
w.Light,
w.UV,
w.Pressure,
w.Timestamp.Format("2006-01-02 15:04:05"),
)
}