154 lines
3.0 KiB
Go
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)
|
|
}
|