weather-station/model/weather_data.go
2025-07-25 18:39:59 +08:00

204 lines
5.2 KiB
Go

package model
import (
"fmt"
"net/url"
"regexp"
"strconv"
)
type WeatherData struct {
StationID string
Password string
TempF float64
Humidity int
DewpointF float64
WindchillF float64
WindDir int
WindSpeedMph float64
WindGustMph float64
RainIn float64
DailyRainIn float64
WeeklyRainIn float64
MonthlyRainIn float64
YearlyRainIn float64
TotalRainIn float64
SolarRadiation float64
UV int
IndoorTempF float64
IndoorHumidity int
AbsBarometerIn float64
BarometerIn float64
LowBattery bool
SoftwareType string
DateUTC string
Action string
RealTime int
RTFreq int
}
var urlRegex = regexp.MustCompile(`/weatherstation/updateweatherstation\.php\?([^&\s]+(&[^&\s]+)*)`)
func ParseWeatherData(data string) (*WeatherData, error) {
matches := urlRegex.FindStringSubmatch(data)
if len(matches) < 2 {
return nil, fmt.Errorf("无法找到有效的气象站数据URL")
}
queryString := matches[1]
values, err := url.ParseQuery(queryString)
if err != nil {
return nil, fmt.Errorf("解析查询参数失败: %v", err)
}
wd := &WeatherData{}
wd.StationID = values.Get("ID")
wd.Password = values.Get("PASSWORD")
wd.DateUTC = values.Get("dateutc")
wd.SoftwareType = values.Get("softwaretype")
wd.Action = values.Get("action")
if tempF, err := strconv.ParseFloat(values.Get("tempf"), 64); err == nil {
wd.TempF = tempF
}
if humidity, err := strconv.Atoi(values.Get("humidity")); err == nil {
wd.Humidity = humidity
}
if dewpointF, err := strconv.ParseFloat(values.Get("dewptf"), 64); err == nil {
wd.DewpointF = dewpointF
}
if windchillF, err := strconv.ParseFloat(values.Get("windchillf"), 64); err == nil {
wd.WindchillF = windchillF
}
if windDir, err := strconv.Atoi(values.Get("winddir")); err == nil {
wd.WindDir = windDir
}
if windSpeedMph, err := strconv.ParseFloat(values.Get("windspeedmph"), 64); err == nil {
wd.WindSpeedMph = windSpeedMph
}
if windGustMph, err := strconv.ParseFloat(values.Get("windgustmph"), 64); err == nil {
wd.WindGustMph = windGustMph
}
if rainIn, err := strconv.ParseFloat(values.Get("rainin"), 64); err == nil {
wd.RainIn = rainIn
}
if dailyRainIn, err := strconv.ParseFloat(values.Get("dailyrainin"), 64); err == nil {
wd.DailyRainIn = dailyRainIn
}
if weeklyRainIn, err := strconv.ParseFloat(values.Get("weeklyrainin"), 64); err == nil {
wd.WeeklyRainIn = weeklyRainIn
}
if monthlyRainIn, err := strconv.ParseFloat(values.Get("monthlyrainin"), 64); err == nil {
wd.MonthlyRainIn = monthlyRainIn
}
if yearlyRainIn, err := strconv.ParseFloat(values.Get("yearlyrainin"), 64); err == nil {
wd.YearlyRainIn = yearlyRainIn
}
if totalRainIn, err := strconv.ParseFloat(values.Get("totalrainin"), 64); err == nil {
wd.TotalRainIn = totalRainIn
}
if solarRadiation, err := strconv.ParseFloat(values.Get("solarradiation"), 64); err == nil {
wd.SolarRadiation = solarRadiation
}
if uv, err := strconv.Atoi(values.Get("UV")); err == nil {
wd.UV = uv
}
if indoorTempF, err := strconv.ParseFloat(values.Get("indoortempf"), 64); err == nil {
wd.IndoorTempF = indoorTempF
}
if indoorHumidity, err := strconv.Atoi(values.Get("indoorhumidity")); err == nil {
wd.IndoorHumidity = indoorHumidity
}
if absBarometerIn, err := strconv.ParseFloat(values.Get("absbaromin"), 64); err == nil {
wd.AbsBarometerIn = absBarometerIn
}
if barometerIn, err := strconv.ParseFloat(values.Get("baromin"), 64); err == nil {
wd.BarometerIn = barometerIn
}
if lowBatt, err := strconv.Atoi(values.Get("lowbatt")); err == nil {
wd.LowBattery = lowBatt != 0
}
if realTime, err := strconv.Atoi(values.Get("realtime")); err == nil {
wd.RealTime = realTime
}
if rtFreq, err := strconv.Atoi(values.Get("rtfreq")); err == nil {
wd.RTFreq = rtFreq
}
return wd, nil
}
func (w *WeatherData) String() string {
return fmt.Sprintf(`
站点ID: %s
温度: %.1f°F (%.1f°C)
湿度: %d%%
露点: %.1f°F (%.1f°C)
风寒指数: %.1f°F (%.1f°C)
风向: %d°
风速: %.2f mph (%.2f km/h)
阵风: %.2f mph (%.2f km/h)
降雨量: %.3f 英寸 (%.2f mm)
日降雨量: %.3f 英寸 (%.2f mm)
周降雨量: %.3f 英寸 (%.2f mm)
月降雨量: %.3f 英寸 (%.2f mm)
年降雨量: %.3f 英寸 (%.2f mm)
总降雨量: %.3f 英寸 (%.2f mm)
太阳辐射: %.2f W/m²
紫外线指数: %d
室内温度: %.1f°F (%.1f°C)
室内湿度: %d%%
绝对气压: %.3f 英寸汞柱 (%.2f hPa)
相对气压: %.3f 英寸汞柱 (%.2f hPa)
低电量: %v
软件类型: %s
日期UTC: %s`,
w.StationID,
w.TempF, (w.TempF-32)*5/9,
w.Humidity,
w.DewpointF, (w.DewpointF-32)*5/9,
w.WindchillF, (w.WindchillF-32)*5/9,
w.WindDir,
w.WindSpeedMph, w.WindSpeedMph*1.60934,
w.WindGustMph, w.WindGustMph*1.60934,
w.RainIn, w.RainIn*25.4,
w.DailyRainIn, w.DailyRainIn*25.4,
w.WeeklyRainIn, w.WeeklyRainIn*25.4,
w.MonthlyRainIn, w.MonthlyRainIn*25.4,
w.YearlyRainIn, w.YearlyRainIn*25.4,
w.TotalRainIn, w.TotalRainIn*25.4,
w.SolarRadiation,
w.UV,
w.IndoorTempF, (w.IndoorTempF-32)*5/9,
w.IndoorHumidity,
w.AbsBarometerIn, w.AbsBarometerIn*33.8639,
w.BarometerIn, w.BarometerIn*33.8639,
w.LowBattery,
w.SoftwareType,
w.DateUTC,
)
}