package main import ( "flag" "io/ioutil" "log" "rain_monitor/api" "rain_monitor/db" "rain_monitor/em3395ty" "rain_monitor/modbus" "rain_monitor/scheduler" "time" "gopkg.in/yaml.v2" ) // 配置结构体 type Config struct { Database struct { Host string `yaml:"host"` Port int `yaml:"port"` User string `yaml:"user"` Password string `yaml:"password"` DBName string `yaml:"dbname"` } `yaml:"database"` Web struct { Port int `yaml:"port"` } `yaml:"web"` TCP struct { Port int `yaml:"port"` } `yaml:"tcp"` Scheduler struct { Enabled bool `yaml:"enabled"` WeatherStationInterval string `yaml:"weather_station_interval"` } `yaml:"scheduler"` EM3395TY struct { ClientID string `yaml:"client_id"` Secret string `yaml:"secret"` BaseURL string `yaml:"base_url"` Devices []string `yaml:"devices"` QueryInterval string `yaml:"query_interval"` // 查询间隔 } `yaml:"em3395ty"` } var ( configFile = flag.String("config", "config.yaml", "配置文件路径") config Config ) func main() { flag.Parse() // 加载配置文件 err := loadConfig(*configFile) if err != nil { log.Fatalf("加载配置文件失败: %v", err) } dbConfig := db.DBConfig{ Host: config.Database.Host, Port: config.Database.Port, User: config.Database.User, Password: config.Database.Password, DBName: config.Database.DBName, } log.Println("正在连接数据库...") err = db.InitDB(dbConfig) if err != nil { log.Fatalf("数据库初始化失败: %v", err) } defer db.CloseDB() log.Println("数据库连接成功") // 初始化EM3395TY配置 em3395ty.InitConfig(config.EM3395TY.ClientID, config.EM3395TY.Secret, config.EM3395TY.BaseURL) log.Println("正在启动TCP服务器...") go modbus.StartTCPServer() // 配置并启动ModBus设备调度器 if config.Scheduler.Enabled { log.Println("正在启动ModBus设备定时任务调度器...") // 解析气象站查询间隔 weatherStationInterval := 15 * time.Minute // 默认值 if config.Scheduler.WeatherStationInterval != "" { if duration, err := time.ParseDuration(config.Scheduler.WeatherStationInterval); err == nil { weatherStationInterval = duration } else { log.Printf("无法解析气象站查询间隔 '%s',使用默认值 15m", config.Scheduler.WeatherStationInterval) } } // 设置调度器配置 schedulerConfig := scheduler.TaskConfig{ WeatherStationInterval: weatherStationInterval, RainGaugeInterval: time.Hour, // 雨量计固定为整点查询 Enabled: true, } scheduler.SetTaskConfig(schedulerConfig) // 启动调度器 go scheduler.StartScheduler() } else { log.Println("ModBus设备定时任务调度器已禁用") } // 启动EM3395TY设备调度器 if len(config.EM3395TY.Devices) > 0 { log.Printf("检测到 %d 个EM3395TY设备,正在启动调度器...", len(config.EM3395TY.Devices)) em3395tyScheduler := em3395ty.NewScheduler(db.GetDB(), config.EM3395TY.Devices) // 设置查询间隔 if config.EM3395TY.QueryInterval != "" { switch config.EM3395TY.QueryInterval { case "hourly": em3395tyScheduler.SetQueryInterval(em3395ty.IntervalHourly) case "30min": em3395tyScheduler.SetQueryInterval(em3395ty.IntervalThirtyMin) case "10min": em3395tyScheduler.SetQueryInterval(em3395ty.IntervalTenMin) case "30sec": em3395tyScheduler.SetQueryInterval(em3395ty.IntervalThirtySec) case "10sec": em3395tyScheduler.SetQueryInterval(em3395ty.IntervalTenSec) default: // 尝试解析为自定义时间间隔 if duration, err := time.ParseDuration(config.EM3395TY.QueryInterval); err == nil { em3395tyScheduler.SetCustomInterval(duration) } else { log.Printf("无法解析查询间隔 '%s',使用默认值", config.EM3395TY.QueryInterval) } } } go em3395tyScheduler.Start() } log.Println("正在启动Web服务器...") api.StartWebServer() } // 加载配置文件 func loadConfig(path string) error { data, err := ioutil.ReadFile(path) if err != nil { return err } err = yaml.Unmarshal(data, &config) if err != nil { return err } log.Printf("配置文件加载成功: %s", path) return nil }