2025-08-22 12:16:43 +08:00

128 lines
3.5 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package main
import (
"context"
"flag"
"log"
"sync"
"time"
"weatherstation/internal/database"
"weatherstation/internal/forecast"
"weatherstation/internal/selftest"
"weatherstation/internal/server"
"weatherstation/internal/tools"
)
func main() {
// 命令行参数
var webOnly = flag.Bool("web", false, "只启动Web服务器Gin")
var udpOnly = flag.Bool("udp", false, "只启动UDP服务器")
// 调试回填10分钟表
var doBackfill = flag.Bool("backfill", false, "将16s原始数据聚合写入10分钟表调试用途")
var bfStation = flag.String("station", "", "指定站点ID为空则全站回填")
var bfFrom = flag.String("from", "", "回填起始时间格式YYYY-MM-DD HH:MM:SS")
var bfTo = flag.String("to", "", "回填结束时间格式YYYY-MM-DD HH:MM:SS")
var bfWrap = flag.Float64("wrap", 0, "回绕一圈对应毫米值mm<=0 则降级为仅计当前值")
// 自检控制
var noSelftest = flag.Bool("no-selftest", false, "跳过启动自检")
var selftestOnly = flag.Bool("selftest_only", false, "仅执行自检后退出")
// 预报抓取
var forecastOnly = flag.Bool("forecast_only", false, "仅执行一次open-meteo拉取并退出")
flag.Parse()
// 设置日志
server.SetupLogger()
// 初始化数据库连接
_ = database.GetDB() // 确保数据库连接已初始化
defer database.Close()
// 启动前自检
if !*noSelftest {
if err := selftest.Run(context.Background()); err != nil {
log.Fatalf("启动自检失败: %v", err)
}
if *selftestOnly {
log.Println("自检完成,按 --selftest_only 要求退出")
return
}
}
// 单次 open-meteo 拉取
if *forecastOnly {
if err := forecast.RunOpenMeteoFetch(context.Background()); err != nil {
log.Fatalf("open-meteo 拉取失败: %v", err)
}
log.Println("open-meteo 拉取完成")
return
}
// Backfill 调试路径
if *doBackfill {
if *bfFrom == "" || *bfTo == "" {
log.Fatalln("backfill 需要提供 --from 与 --to 时间")
}
fromT, err := time.Parse("2006-01-02 15:04:05", *bfFrom)
if err != nil {
log.Fatalf("解析from失败: %v", err)
}
toT, err := time.Parse("2006-01-02 15:04:05", *bfTo)
if err != nil {
log.Fatalf("解析to失败: %v", err)
}
ctx := context.Background()
if err := tools.RunBackfill10Min(ctx, tools.BackfillOptions{
StationID: *bfStation,
FromTime: fromT,
ToTime: toT,
WrapCycleMM: *bfWrap,
BucketMinutes: 10,
}); err != nil {
log.Fatalf("回填失败: %v", err)
}
log.Println("回填完成")
return
}
// 根据命令行参数启动服务
if *webOnly {
// 只启动Web服务器
log.Println("启动Web服务器模式...")
if err := server.StartGinServer(); err != nil {
log.Fatalf("启动Web服务器失败: %v", err)
}
} else if *udpOnly {
// 只启动UDP服务器
log.Println("启动UDP服务器模式...")
if err := server.StartUDPServer(); err != nil {
log.Fatalf("启动UDP服务器失败: %v", err)
}
} else {
// 同时启动UDP和Web服务器
log.Println("启动完整模式UDP + Web服务器...")
var wg sync.WaitGroup
wg.Add(2)
// 启动UDP服务器
go func() {
defer wg.Done()
log.Println("正在启动UDP服务器...")
if err := server.StartUDPServer(); err != nil {
log.Printf("UDP服务器异常退出: %v", err)
}
}()
// 启动Web服务器
go func() {
defer wg.Done()
log.Println("正在启动Web服务器...")
if err := server.StartGinServer(); err != nil {
log.Printf("Web服务器异常退出: %v", err)
}
}()
wg.Wait()
}
}