|
@@ -1,10 +1,12 @@
|
|
|
package service
|
|
|
|
|
|
import (
|
|
|
+ "fmt"
|
|
|
"server/logger"
|
|
|
"server/modbus"
|
|
|
"server/model"
|
|
|
"server/utils"
|
|
|
+ "sort"
|
|
|
"time"
|
|
|
)
|
|
|
|
|
@@ -138,3 +140,175 @@ func (c Cron) RelayOnOffTimeTask() {
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+func (c Cron) RelayOnOffTimeTaskSn(sn string) {
|
|
|
+ _, dev, err := utils.GetDataByDeviceId(sn)
|
|
|
+ if err != nil {
|
|
|
+ logger.Get().Errorf("LoadData err = %s", err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ relays := dev.DeviceLoops
|
|
|
+ rcTime, rlTime, err := utils.SunriseSunsetForChina(28.23, 113.05)
|
|
|
+ tmp := make(map[int]int)
|
|
|
+ for _, relay := range relays {
|
|
|
+ //日出日落时间
|
|
|
+ if relay.TimeCondition1OnTime == "日出" {
|
|
|
+ relay.TimeCondition1OnTime = rcTime
|
|
|
+ } else if relay.TimeCondition1OnTime == "日落" {
|
|
|
+ relay.TimeCondition1OnTime = rlTime
|
|
|
+ }
|
|
|
+ if relay.TimeCondition1OffTime == "日出" {
|
|
|
+ relay.TimeCondition1OffTime = rcTime
|
|
|
+ } else if relay.TimeCondition1OffTime == "日落" {
|
|
|
+ relay.TimeCondition1OffTime = rlTime
|
|
|
+ }
|
|
|
+ if relay.TimeCondition2OnTime == "日出" {
|
|
|
+ relay.TimeCondition2OnTime = rcTime
|
|
|
+ } else if relay.TimeCondition2OnTime == "日落" {
|
|
|
+ relay.TimeCondition2OnTime = rlTime
|
|
|
+ }
|
|
|
+ if relay.TimeCondition2OffTime == "日出" {
|
|
|
+ relay.TimeCondition2OffTime = rcTime
|
|
|
+ } else if relay.TimeCondition2OffTime == "日落" {
|
|
|
+ relay.TimeCondition2OffTime = rlTime
|
|
|
+ }
|
|
|
+
|
|
|
+ if relay.TimeCondition1OffTime == "关闭" && relay.TimeCondition1OnTime == "关闭" && relay.TimeCondition2OffTime == "关闭" && relay.TimeCondition2OnTime == "关闭" {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ state, _ := ss(relay.TimeCondition1OnTime, relay.TimeCondition1OffTime, relay.TimeCondition2OnTime, relay.TimeCondition2OffTime)
|
|
|
+ tmp[relay.ID] = state
|
|
|
+ }
|
|
|
+
|
|
|
+ for loop1, state := range tmp {
|
|
|
+
|
|
|
+ reg, dev, err := utils.GetDataByDeviceId(sn)
|
|
|
+ if err != nil {
|
|
|
+ logger.Get().Errorf("GetDataByDeviceId err = %s\n", err.Error())
|
|
|
+ }
|
|
|
+
|
|
|
+ data := modbus.DeviceLoopSwitch(loop1, state)
|
|
|
+ if model.ConnectionMap[sn] == nil {
|
|
|
+ logger.Get().Errorf("设备连接丢失")
|
|
|
+ }
|
|
|
+ err = utils.WriteDevice(data, model.ConnectionMap[sn])
|
|
|
+ time.Sleep(100 * time.Millisecond)
|
|
|
+ if err != nil {
|
|
|
+ logger.Get().Errorf("WriteDevice err = %s\n", err.Error())
|
|
|
+ }
|
|
|
+
|
|
|
+ for j, loop := range dev.DeviceLoops {
|
|
|
+ if loop.ID == loop1 {
|
|
|
+ dev.DeviceLoops[j].State = state
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ for i, device := range reg.Devices {
|
|
|
+ if device.Sn == dev.Sn {
|
|
|
+ reg.Devices[i] = dev
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ data1, err := utils.SaveRegionOnData(reg)
|
|
|
+ if err != nil {
|
|
|
+ logger.Get().Errorf("SaveRegionOnData err = %s\n", err.Error())
|
|
|
+ }
|
|
|
+ err = SaveData(data1)
|
|
|
+ if err != nil {
|
|
|
+ logger.Get().Errorf("SaveData err = %s\n", err.Error())
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+const (
|
|
|
+ Off = iota
|
|
|
+ On
|
|
|
+)
|
|
|
+
|
|
|
+type TimeControl struct {
|
|
|
+ start time.Time
|
|
|
+ end time.Time
|
|
|
+ state int
|
|
|
+}
|
|
|
+
|
|
|
+func getDeviceState(schedules []TimeControl, currentTime time.Time) int {
|
|
|
+ for _, period := range schedules {
|
|
|
+ now := time.Date(0, time.January, 1, currentTime.Hour(), currentTime.Minute(), currentTime.Second(), currentTime.Nanosecond(), time.UTC)
|
|
|
+ if period.start.After(period.end) {
|
|
|
+ if now.After(period.start) || now.Before(period.end) {
|
|
|
+ return period.state
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ if now.After(period.start) && now.Before(period.end) {
|
|
|
+ return period.state
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return Off
|
|
|
+}
|
|
|
+
|
|
|
+func stateTransition(str string) int {
|
|
|
+ if str == "on1" || str == "on2" {
|
|
|
+ return On
|
|
|
+ } else {
|
|
|
+ return Off
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+func ss(on1, off1, on2, off2 string) (int, error) {
|
|
|
+ deviceRecoveryTime := time.Now()
|
|
|
+
|
|
|
+ // 定义时间映射
|
|
|
+ deviceTime := map[string]string{
|
|
|
+ "on1": on1,
|
|
|
+ "off1": off1,
|
|
|
+ "on2": on2,
|
|
|
+ "off2": off2,
|
|
|
+ }
|
|
|
+
|
|
|
+ // 创建一个切片存储时间
|
|
|
+ var times []struct {
|
|
|
+ key string
|
|
|
+ value time.Time
|
|
|
+ }
|
|
|
+
|
|
|
+ // 将时间字符串解析为 time.Time 对象,并存入切片
|
|
|
+ for key, value := range deviceTime {
|
|
|
+ if value == "关闭" {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+
|
|
|
+ t, err := time.Parse("15:04", value)
|
|
|
+ if err != nil {
|
|
|
+ logger.Get().Error("时间转换失败!" + err.Error())
|
|
|
+ return 0, err
|
|
|
+ }
|
|
|
+ times = append(times, struct {
|
|
|
+ key string
|
|
|
+ value time.Time
|
|
|
+ }{key, t})
|
|
|
+ }
|
|
|
+
|
|
|
+ // 对时间进行排序
|
|
|
+ sort.Slice(times, func(i, j int) bool {
|
|
|
+ return times[i].value.Before(times[j].value)
|
|
|
+ })
|
|
|
+
|
|
|
+ var timeControls []TimeControl
|
|
|
+
|
|
|
+ for i, _ := range times {
|
|
|
+ if len(times) == i+1 {
|
|
|
+ timeControls = append(timeControls, TimeControl{start: times[i].value, end: times[0].value.Add(24 * time.Hour), state: stateTransition(times[i].key)})
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ timeControls = append(timeControls, TimeControl{start: times[i].value, end: times[i+1].value, state: stateTransition(times[i].key)})
|
|
|
+ }
|
|
|
+
|
|
|
+ for _, control := range timeControls {
|
|
|
+ fmt.Printf("%s : %s : %d\n", control.start, control.end, control.state)
|
|
|
+ }
|
|
|
+
|
|
|
+ // 在恢复时检查状态
|
|
|
+ state := getDeviceState(timeControls, deviceRecoveryTime)
|
|
|
+ return state, nil
|
|
|
+}
|