rain_monitor/scheduler/scheduler.go
2025-07-12 17:41:49 +08:00

154 lines
3.0 KiB
Go

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)
}