package scheduler import ( "log" "rain_monitor/db" "rain_monitor/modbus" "time" ) type TaskConfig struct { WeatherStationInterval time.Duration RainGaugeInterval time.Duration Enabled bool } var ( config TaskConfig weatherTick *time.Ticker stopChan chan struct{} ) func init() { config = TaskConfig{ WeatherStationInterval: 15 * time.Minute, RainGaugeInterval: time.Hour, Enabled: true, } stopChan = make(chan struct{}) } func StartScheduler() { if !config.Enabled { log.Println("定时查询任务已禁用") return } log.Printf("启动定时查询任务,气象站间隔: %v, 雨量计整点查询", config.WeatherStationInterval) weatherTick = time.NewTicker(config.WeatherStationInterval) go func() { for { select { case <-weatherTick.C: queryWeatherStation() case <-stopChan: return } } }() go scheduleHourlyRainGaugeQuery() } func durationUntilNextHour() time.Duration { now := time.Now() nextHour := time.Date(now.Year(), now.Month(), now.Day(), now.Hour()+1, 0, 0, 0, now.Location()) return nextHour.Sub(now) } func scheduleHourlyRainGaugeQuery() { for { select { case <-stopChan: return default: waitTime := durationUntilNextHour() log.Printf("下一次雨量计查询将在 %s 后进行 (整点: %s)", waitTime.String(), time.Now().Add(waitTime).Format("15:04:05")) timer := time.NewTimer(waitTime) select { case <-timer.C: queryRainGauge() case <-stopChan: timer.Stop() return } } } } func StopScheduler() { if weatherTick != nil { weatherTick.Stop() } close(stopChan) log.Println("定时查询任务已停止") } func SetTaskConfig(newConfig TaskConfig) { StopScheduler() config = newConfig if config.Enabled { StartScheduler() } } func queryWeatherStation() { log.Println("执行气象站查询任务") err := modbus.QueryDevice(modbus.DeviceWeatherStation) if err != nil { log.Printf("气象站查询失败: %v", err) return } time.Sleep(2 * time.Second) weatherData := modbus.GetLatestWeatherData() if weatherData == nil { log.Println("未获取到气象站数据") return } _, err = db.SaveWeatherData(weatherData) if err != nil { log.Printf("保存气象站数据失败: %v", err) return } log.Printf("气象站数据已保存,温度: %.1f℃, 湿度: %.1f%%", weatherData.Temperature, weatherData.Humidity) } func queryRainGauge() { log.Println("执行雨量计查询任务 (整点)") err := modbus.QueryDevice(modbus.DeviceRainGauge) if err != nil { log.Printf("雨量计查询失败: %v", err) return } time.Sleep(2 * time.Second) rainData := modbus.GetLatestRainData() if rainData == nil { log.Println("未获取到雨量计数据") return } _, err = db.SaveRainGaugeData(rainData) if err != nil { log.Printf("保存雨量计数据失败: %v", err) return } log.Printf("雨量计数据已保存,当天降雨量: %.1fmm, 总降雨量: %.1fmm", rainData.DailyRainfall, rainData.TotalRainfall) }