diff --git a/internal/database/models.go b/internal/database/models.go
index 3f6c6e8..e949062 100644
--- a/internal/database/models.go
+++ b/internal/database/models.go
@@ -131,7 +131,8 @@ func GetSeriesFrom10Min(db *sql.DB, stationID string, startTime, endTime time.Ti
ROUND(wind_dir_deg::numeric, 2) AS wind_direction,
ROUND(rain_10m_mm_x1000/1000.0, 3) AS rainfall,
ROUND(solar_wm2_x100/100.0, 2) AS light,
- ROUND(uv_index::numeric, 2) AS uv
+ ROUND(uv_index::numeric, 2) AS uv,
+ ROUND(rain_total_mm_x1000/1000.0, 3) AS rain_total
FROM rs485_weather_10min
WHERE station_id = $1 AND bucket_start >= $2 AND bucket_start <= $3
ORDER BY bucket_start`
@@ -156,7 +157,7 @@ func GetSeriesFrom10Min(db *sql.DB, stationID string, startTime, endTime time.Ti
var points []types.WeatherPoint
for rows.Next() {
var p types.WeatherPoint
- if err := rows.Scan(&p.DateTime, &p.Temperature, &p.Humidity, &p.Pressure, &p.WindSpeed, &p.WindDir, &p.Rainfall, &p.Light, &p.UV); err != nil {
+ if err := rows.Scan(&p.DateTime, &p.Temperature, &p.Humidity, &p.Pressure, &p.WindSpeed, &p.WindDir, &p.Rainfall, &p.Light, &p.UV, &p.RainTotal); err != nil {
continue
}
points = append(points, p)
@@ -191,7 +192,8 @@ func buildAggFrom10MinQuery(interval string) string {
SUM(sin(radians(wind_dir_deg)) * sample_count)::double precision AS sin_sum,
SUM(cos(radians(wind_dir_deg)) * sample_count)::double precision AS cos_sum,
SUM(rain_10m_mm_x1000) AS rain_sum,
- SUM(sample_count) AS n_sum
+ SUM(sample_count) AS n_sum,
+ MAX(rain_total_mm_x1000) AS rain_total_max
FROM base
GROUP BY 1
)
@@ -206,7 +208,8 @@ func buildAggFrom10MinQuery(interval string) string {
ELSE degrees(atan2(sin_sum, cos_sum)) END)::numeric, 2) AS wind_direction,
ROUND((rain_sum/1000.0)::numeric, 3) AS rainfall,
ROUND((w_solar/NULLIF(n_sum,0))/100.0, 2) AS light,
- ROUND((w_uv/NULLIF(n_sum,0))::numeric, 2) AS uv
+ ROUND((w_uv/NULLIF(n_sum,0))::numeric, 2) AS uv,
+ ROUND((rain_total_max/1000.0)::numeric, 3) AS rain_total
FROM g
ORDER BY grp`
}
@@ -415,3 +418,37 @@ func GetForecastData(db *sql.DB, stationID string, startTime, endTime time.Time,
return points, nil
}
+
+func GetSeriesRaw(db *sql.DB, stationID string, startTime, endTime time.Time) ([]types.WeatherPoint, error) {
+ query := `
+ SELECT
+ to_char(timestamp, 'YYYY-MM-DD HH24:MI:SS') AS date_time,
+ COALESCE(temperature, 0) AS temperature,
+ COALESCE(humidity, 0) AS humidity,
+ COALESCE(pressure, 0) AS pressure,
+ COALESCE(wind_speed, 0) AS wind_speed,
+ COALESCE(wind_direction, 0) AS wind_direction,
+ COALESCE(rainfall, 0) AS rainfall,
+ COALESCE(light, 0) AS light,
+ COALESCE(uv, 0) AS uv,
+ COALESCE(rainfall, 0) AS rain_total
+ FROM rs485_weather_data
+ WHERE station_id = $1 AND timestamp >= $2 AND timestamp <= $3
+ ORDER BY timestamp`
+
+ rows, err := db.Query(query, stationID, startTime, endTime)
+ if err != nil {
+ return nil, err
+ }
+ defer rows.Close()
+
+ var points []types.WeatherPoint
+ for rows.Next() {
+ var p types.WeatherPoint
+ if err := rows.Scan(&p.DateTime, &p.Temperature, &p.Humidity, &p.Pressure, &p.WindSpeed, &p.WindDir, &p.Rainfall, &p.Light, &p.UV, &p.RainTotal); err != nil {
+ continue
+ }
+ points = append(points, p)
+ }
+ return points, nil
+}
diff --git a/internal/server/gin.go b/internal/server/gin.go
index c97a906..00deb56 100644
--- a/internal/server/gin.go
+++ b/internal/server/gin.go
@@ -126,7 +126,12 @@ func getDataHandler(c *gin.Context) {
}
// 获取数据(改为基于10分钟聚合表的再聚合)
- points, err := database.GetSeriesFrom10Min(database.GetDB(), stationID, start, end, interval)
+ var points []types.WeatherPoint
+ if interval == "raw" {
+ points, err = database.GetSeriesRaw(database.GetDB(), stationID, start, end)
+ } else {
+ points, err = database.GetSeriesFrom10Min(database.GetDB(), stationID, start, end, interval)
+ }
if err != nil {
log.Printf("查询数据失败: %v", err) // 记录具体错误到服务端日志
c.JSON(http.StatusInternalServerError, gin.H{
diff --git a/pkg/types/types.go b/pkg/types/types.go
index b7c8045..0cbaa59 100644
--- a/pkg/types/types.go
+++ b/pkg/types/types.go
@@ -24,6 +24,7 @@ type WeatherPoint struct {
Rainfall float64 `json:"rainfall"`
Light float64 `json:"light"`
UV float64 `json:"uv"`
+ RainTotal float64 `json:"rain_total"`
}
// PageData 页面数据结构
diff --git a/static/js/weather-chart.js b/static/js/weather-chart.js
index 3201943..3c2d07c 100644
--- a/static/js/weather-chart.js
+++ b/static/js/weather-chart.js
@@ -32,12 +32,20 @@ const WeatherChart = {
const item = historyData.find(d => d.date_time === label);
return item ? item.rainfall : null;
});
+ const historyRainTotals = allLabels.map(label => {
+ const item = historyData.find(d => d.date_time === label);
+ return item && item.rain_total !== undefined ? item.rain_total : null;
+ });
// 准备预报数据
const forecastTemperatures = allLabels.map(label => {
const item = forecastData.find(d => d.date_time === label);
return item && item.temperature !== null ? item.temperature : null;
});
+ const forecastHumidities = allLabels.map(label => {
+ const item = forecastData.find(d => d.date_time === label);
+ return item && item.humidity !== null ? item.humidity : null;
+ });
const forecastRainfalls = allLabels.map(label => {
const item = forecastData.find(d => d.date_time === label);
return item && item.rainfall !== null ? item.rainfall : null;
@@ -74,6 +82,17 @@ const WeatherChart = {
backgroundColor: 'rgba(54, 162, 235, 0.6)',
borderColor: 'rgb(54, 162, 235)',
yAxisID: 'y-rainfall'
+ },
+ {
+ label: '累计雨量 (mm) - 实测(10m total)',
+ data: historyRainTotals,
+ borderColor: 'rgb(75, 192, 192)',
+ backgroundColor: 'rgba(75, 192, 192, 0.1)',
+ yAxisID: 'y-rainfall',
+ tension: 0.2,
+ spanGaps: false,
+ pointRadius: 0,
+ hidden: true
}
];
@@ -88,7 +107,19 @@ const WeatherChart = {
borderDash: [5, 5],
yAxisID: 'y-temperature',
tension: 0.4,
- spanGaps: false
+ spanGaps: false,
+ hidden: true
+ },
+ {
+ label: '湿度 (%) - 预报',
+ data: forecastHumidities,
+ borderColor: 'rgba(255, 165, 0, 0.8)',
+ backgroundColor: 'rgba(255, 165, 0, 0.05)',
+ borderDash: [5, 5],
+ yAxisID: 'y-humidity',
+ tension: 0.4,
+ spanGaps: false,
+ hidden: false
},
{
label: '雨量 (mm) - 预报',
diff --git a/templates/index.html b/templates/index.html
index 5fd207d..23397ce 100644
--- a/templates/index.html
+++ b/templates/index.html
@@ -489,6 +489,7 @@
+