2025-05-15 16:44:38 +08:00

116 lines
3.3 KiB
Go

package dao
import (
"database/sql"
"time"
"go_rain_dtu/internal/model"
"go_rain_dtu/pkg/logger"
)
type SensorDAO struct {
db *sql.DB
}
func NewSensorDAO(db *sql.DB) *SensorDAO {
return &SensorDAO{db: db}
}
// 插入传感器数据
func (dao *SensorDAO) Insert(data *model.SensorData) error {
query := `
INSERT INTO sensor_data (
timestamp, wind_speed, wind_force, wind_direction_8,
wind_direction_360, humidity, temperature, atm_pressure,
solar_radiation, rainfall
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
`
_, err := dao.db.Exec(query,
data.Timestamp, data.WindSpeed, data.WindForce, data.WindDirection8,
data.WindDirection360, data.Humidity, data.Temperature, data.AtmPressure,
data.SolarRadiation, data.Rainfall,
)
if err != nil {
logger.Logger.Printf("插入传感器数据失败: %v", err)
return err
}
return nil
}
// 获取聚合数据
func (dao *SensorDAO) GetAggregatedData(start, end time.Time, interval string) ([]model.AggregatedData, error) {
var query string
switch interval {
case "5min":
query = `
SELECT
DATE_FORMAT(timestamp, '%Y-%m-%dT%H:%i:%s') as ts,
ROUND(AVG(temperature)/10, 1) as avg_temp,
MAX(rainfall) - MIN(rainfall) as rainfall,
ROUND(AVG(humidity)/10, 1) as avg_humidity,
ROUND(AVG(wind_speed)/10, 1) as avg_wind_speed
FROM sensor_data
WHERE timestamp BETWEEN ? AND ?
GROUP BY FLOOR(UNIX_TIMESTAMP(timestamp)/(5*60))
ORDER BY ts DESC
`
case "30min":
query = `
SELECT
DATE_FORMAT(timestamp, '%Y-%m-%dT%H:%i:%s') as ts,
ROUND(AVG(temperature)/10, 1) as avg_temp,
MAX(rainfall) - MIN(rainfall) as rainfall,
ROUND(AVG(humidity)/10, 1) as avg_humidity,
ROUND(AVG(wind_speed)/10, 1) as avg_wind_speed
FROM sensor_data
WHERE timestamp BETWEEN ? AND ?
GROUP BY FLOOR(UNIX_TIMESTAMP(timestamp)/(30*60))
ORDER BY ts DESC
`
default: // 1hour
query = `
SELECT
DATE_FORMAT(timestamp, '%Y-%m-%dT%H:%i:%s') as ts,
ROUND(AVG(temperature)/10, 1) as avg_temp,
MAX(rainfall) - MIN(rainfall) as rainfall,
ROUND(AVG(humidity)/10, 1) as avg_humidity,
ROUND(AVG(wind_speed)/10, 1) as avg_wind_speed
FROM sensor_data
WHERE timestamp BETWEEN ? AND ?
GROUP BY FLOOR(UNIX_TIMESTAMP(timestamp)/3600)
ORDER BY ts DESC
`
}
rows, err := dao.db.Query(query, start, end)
if err != nil {
logger.Logger.Printf("查询聚合数据失败: %v", err)
return nil, err
}
defer rows.Close()
var result []model.AggregatedData
for rows.Next() {
var data model.AggregatedData
var tsStr string
err := rows.Scan(&tsStr, &data.AvgTemperature, &data.Rainfall,
&data.AvgHumidity, &data.AvgWindSpeed)
if err != nil {
logger.Logger.Printf("扫描数据行失败: %v", err)
continue
}
// 解析ISO格式的时间字符串
data.Timestamp, err = time.Parse("2006-01-02T15:04:05", tsStr)
if err != nil {
logger.Logger.Printf("解析时间失败: %v", err)
continue
}
result = append(result, data)
}
return result, nil
}