104 lines
2.8 KiB
Go

package model
import (
"database/sql"
"fmt"
"time"
"weatherstation/config"
_ "github.com/lib/pq"
)
var db *sql.DB
func InitDB() error {
cfg := config.GetConfig()
connStr := fmt.Sprintf("host=%s port=%d user=%s password=%s dbname=%s sslmode=%s",
cfg.Database.Host, cfg.Database.Port, cfg.Database.User,
cfg.Database.Password, cfg.Database.DBName, cfg.Database.SSLMode)
var err error
db, err = sql.Open("postgres", connStr)
if err != nil {
return fmt.Errorf("无法连接到数据库: %v", err)
}
err = db.Ping()
if err != nil {
return fmt.Errorf("数据库连接测试失败: %v", err)
}
return nil
}
func CloseDB() {
if db != nil {
db.Close()
}
}
func ensureStationExists(stationID, password string) error {
if db == nil {
return fmt.Errorf("数据库未初始化")
}
var count int
err := db.QueryRow("SELECT COUNT(*) FROM stations WHERE station_id = $1", stationID).Scan(&count)
if err != nil {
return fmt.Errorf("查询站点失败: %v", err)
}
if count == 0 {
_, err = db.Exec("INSERT INTO stations (station_id, password) VALUES ($1, $2)", stationID, password)
if err != nil {
return fmt.Errorf("添加站点失败: %v", err)
}
} else {
_, err = db.Exec("UPDATE stations SET password = $1, last_update = $2 WHERE station_id = $3",
password, time.Now(), stationID)
if err != nil {
return fmt.Errorf("更新站点失败: %v", err)
}
}
return nil
}
func SaveWeatherData(data *WeatherData, rawData string) error {
if db == nil {
return fmt.Errorf("数据库未初始化")
}
err := ensureStationExists(data.StationID, data.Password)
if err != nil {
return err
}
cst := time.FixedZone("CST", 8*60*60)
timestamp := time.Now().In(cst)
_, err = db.Exec(`
INSERT INTO weather_data (
station_id, timestamp, temp_f, humidity, dewpoint_f, windchill_f,
wind_dir, wind_speed_mph, wind_gust_mph, rain_in, daily_rain_in,
weekly_rain_in, monthly_rain_in, yearly_rain_in, total_rain_in,
solar_radiation, uv, indoor_temp_f, indoor_humidity,
abs_barometer_in, barometer_in, low_battery, raw_data
) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22, $23)`,
data.StationID, timestamp,
int(data.TempF*10), data.Humidity, int(data.DewpointF*10), int(data.WindchillF*10),
data.WindDir, int(data.WindSpeedMph*100), int(data.WindGustMph*100),
int(data.RainIn*1000), int(data.DailyRainIn*1000), int(data.WeeklyRainIn*1000),
int(data.MonthlyRainIn*1000), int(data.YearlyRainIn*1000), int(data.TotalRainIn*1000),
int(data.SolarRadiation*100), data.UV, int(data.IndoorTempF*10), data.IndoorHumidity,
int(data.AbsBarometerIn*1000), int(data.BarometerIn*1000), data.LowBattery, rawData)
if err != nil {
return fmt.Errorf("保存气象数据失败: %v", err)
}
return nil
}