rain_monitor/scheduler/scheduler.go
yarnom f6f70a561e Revert "feat:新增EM3395TY设备"
This reverts commit b8819d6a5e3590b145a8c785d16c44b113365e42.
2025-07-21 11:24:52 +08:00

178 lines
3.9 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, // 默认15分钟查询一次气象站
RainGaugeInterval: time.Hour, // 默认每小时查询一次雨量计
Enabled: true, // 默认启用
}
stopChan = make(chan struct{})
}
// StartScheduler 启动定时任务调度器
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
}
}
}
}
// StopScheduler 停止定时任务调度器
func StopScheduler() {
if weatherTick != nil {
weatherTick.Stop()
}
close(stopChan)
log.Println("定时查询任务已停止")
}
// SetTaskConfig 设置任务配置
func SetTaskConfig(newConfig TaskConfig) {
// 先停止现有任务
StopScheduler()
// 更新配置
config = newConfig
// 重新启动任务
if config.Enabled {
StartScheduler()
}
}
// queryWeatherStation 查询气象站并保存数据
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)
}
// queryRainGauge 查询雨量计并保存数据
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)
}