|
@@ -1,11 +1,13 @@
|
|
|
package service
|
|
|
|
|
|
import (
|
|
|
+ "fmt"
|
|
|
"net"
|
|
|
"server/logger"
|
|
|
"server/modbus"
|
|
|
"server/model"
|
|
|
"server/utils"
|
|
|
+ "sort"
|
|
|
"time"
|
|
|
)
|
|
|
|
|
@@ -22,10 +24,7 @@ func (c Cron) RelayOnOffTimeTask() {
|
|
|
}
|
|
|
relayMap := make(map[string]map[int]int)
|
|
|
for _, d := range devices {
|
|
|
- //if d.State == 0 {
|
|
|
- // continue
|
|
|
- //}
|
|
|
- tmp, isExist := relayMap[d.Sn]
|
|
|
+ tmp, isExist := relayMap[d.Ip]
|
|
|
if !isExist { // 回路id 回路状态
|
|
|
tmp = make(map[int]int)
|
|
|
}
|
|
@@ -94,13 +93,13 @@ func (c Cron) RelayOnOffTimeTask() {
|
|
|
isTiming = 1
|
|
|
}
|
|
|
if isTiming == 1 {
|
|
|
- relayMap[d.Sn] = tmp
|
|
|
+ relayMap[d.Ip] = tmp
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
for key, value := range relayMap {
|
|
|
|
|
|
- reg, dev, err := utils.GetDataByDeviceId(key)
|
|
|
+ reg, dev, err := utils.GetDataByDeviceIP(key)
|
|
|
if err != nil {
|
|
|
logger.Get().Errorf("GetDataByDeviceId err = %s\n", err.Error())
|
|
|
}
|
|
@@ -111,11 +110,11 @@ func (c Cron) RelayOnOffTimeTask() {
|
|
|
// 成功找到连接
|
|
|
netConn := conn1.(net.Conn)
|
|
|
err := utils.WriteDevice(data, netConn)
|
|
|
- time.Sleep(1 * time.Second)
|
|
|
if err != nil {
|
|
|
- logger.Get().Errorf("WriteDevice err = %s\n", err.Error())
|
|
|
+ logger.Get().Errorf("定时控制 写命令错误: %s -- conn: %v", err, netConn.RemoteAddr().String())
|
|
|
+ return
|
|
|
}
|
|
|
-
|
|
|
+ time.Sleep(1 * time.Second)
|
|
|
for j, loop := range dev.DeviceLoops {
|
|
|
if loop.ID == i {
|
|
|
dev.DeviceLoops[j].State = i2
|
|
@@ -123,7 +122,7 @@ func (c Cron) RelayOnOffTimeTask() {
|
|
|
}
|
|
|
} else {
|
|
|
// 没有找到对应的连接
|
|
|
- logger.Get().Printf("Connection for key %s not found", key)
|
|
|
+ logger.Get().Printf("定时Connection for key %s not found", key)
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -143,3 +142,178 @@ func (c Cron) RelayOnOffTimeTask() {
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+// DeviceAdjustment 设备调正
|
|
|
+func DeviceAdjustment(ip string) {
|
|
|
+ reg, dev, _ := utils.GetDataByDeviceIP(ip)
|
|
|
+
|
|
|
+ rcTime, rlTime, err := utils.SunriseSunsetForChina(28.23, 113.05)
|
|
|
+ tmp := make(map[int]int)
|
|
|
+ for _, relay := range dev.DeviceLoops {
|
|
|
+ //日出日落时间
|
|
|
+ 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, err := ss(relay.TimeCondition1OnTime, relay.TimeCondition1OffTime, relay.TimeCondition2OnTime, relay.TimeCondition2OffTime)
|
|
|
+ if err != nil {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ tmp[relay.ID] = state
|
|
|
+ }
|
|
|
+ logger.Get().Printf("[DEBUG] %v", tmp)
|
|
|
+ for i, i2 := range tmp {
|
|
|
+ data := modbus.DeviceLoopSwitch(i, i2)
|
|
|
+ if conn1, ok := model.ConnectionMap1.Load(ip); ok {
|
|
|
+ // 成功找到连接
|
|
|
+ netConn := conn1.(net.Conn)
|
|
|
+ err := utils.WriteDevice(data, netConn)
|
|
|
+ if err != nil {
|
|
|
+ logger.Get().Errorf("定时控制 写命令错误: %s -- conn: %v", err, netConn.RemoteAddr().String())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ time.Sleep(2 * time.Second)
|
|
|
+ for j, loop := range dev.DeviceLoops {
|
|
|
+ if loop.ID == i {
|
|
|
+ dev.DeviceLoops[j].State = i2
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ // 没有找到对应的连接
|
|
|
+ logger.Get().Printf("重连Connection for key %s not found", ip)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ for i, device := range reg.Devices {
|
|
|
+ if device.Sn == dev.Sn {
|
|
|
+ reg.Devices[i] = dev
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ data, err := utils.SaveRegionOnData(reg)
|
|
|
+ if err != nil {
|
|
|
+ logger.Get().Errorf("重连SaveRegionOnData err = %s\n", err.Error())
|
|
|
+ }
|
|
|
+ err = SaveData(data)
|
|
|
+ if err != nil {
|
|
|
+ logger.Get().Errorf("SaveData err = %s\n", err.Error())
|
|
|
+ }
|
|
|
+ return
|
|
|
+}
|
|
|
+
|
|
|
+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)
|
|
|
+ start := time.Date(0, time.January, 1, period.start.Hour(), period.start.Minute(), period.start.Second(), period.start.Nanosecond(), time.UTC)
|
|
|
+ end := time.Date(0, time.January, 1, period.end.Hour(), period.end.Minute(), period.end.Second(), period.end.Nanosecond(), time.UTC)
|
|
|
+
|
|
|
+ if start.After(end) { // 跨越午夜
|
|
|
+ if now.After(start) || now.Before(end) {
|
|
|
+ return period.state
|
|
|
+ }
|
|
|
+ } else { // 不跨越午夜
|
|
|
+ if now.After(start) && now.Before(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)
|
|
|
+ fmt.Printf("%s %d\n", timeControls, state)
|
|
|
+ return state, nil
|
|
|
+}
|