cron.go 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314
  1. package service
  2. import (
  3. "fmt"
  4. "server/logger"
  5. "server/modbus"
  6. "server/model"
  7. "server/utils"
  8. "sort"
  9. "time"
  10. )
  11. type Cron struct {
  12. }
  13. // RelayOnOffTimeTask 定时开关 前提是 设备在线 否则失效
  14. func (c Cron) RelayOnOffTimeTask() {
  15. current := time.Now().Format("15:04")
  16. devices, err := utils.GetOnlineDevices()
  17. if err != nil {
  18. logger.Get().Errorf("LoadData err = %s", err.Error())
  19. return
  20. }
  21. relayMap := make(map[string]map[int]int)
  22. for _, d := range devices {
  23. //if d.State == 0 {
  24. // continue
  25. //}
  26. tmp, isExist := relayMap[d.Sn]
  27. if !isExist { // 回路id 回路状态
  28. tmp = make(map[int]int)
  29. }
  30. relays := d.DeviceLoops
  31. rcTime, rlTime, err := utils.SunriseSunsetForChina(28.23, 113.05)
  32. if err != nil {
  33. logger.Get().Errorf("SunriseSunsetForChina err = %s", err.Error())
  34. rcTime = "06:00"
  35. rlTime = "18:00"
  36. }
  37. for _, r := range relays {
  38. //日出日落时间
  39. if r.TimeCondition1OnTime == "日出" {
  40. r.TimeCondition1OnTime = rcTime
  41. } else if r.TimeCondition1OnTime == "日落" {
  42. r.TimeCondition1OnTime = rlTime
  43. }
  44. if r.TimeCondition1OffTime == "日出" {
  45. r.TimeCondition1OffTime = rcTime
  46. } else if r.TimeCondition1OffTime == "日落" {
  47. r.TimeCondition1OffTime = rlTime
  48. }
  49. if r.TimeCondition2OnTime == "日出" {
  50. r.TimeCondition2OnTime = rcTime
  51. } else if r.TimeCondition2OnTime == "日落" {
  52. r.TimeCondition2OnTime = rlTime
  53. }
  54. if r.TimeCondition2OffTime == "日出" {
  55. r.TimeCondition2OffTime = rcTime
  56. } else if r.TimeCondition2OffTime == "日落" {
  57. r.TimeCondition2OffTime = rlTime
  58. }
  59. isTiming := 0 // 用来判断该设备的回路 是否定时
  60. //控制回路 时间判断 是否关闭 当前时间是否等与规定时间 规定时间到规定时间+10分钟
  61. //因为1分钟执行一次,所以会多次执行,则新加判断 如果数据库中状态和回路状态相同则不执行下去
  62. layout := "15:04"
  63. rTimeCondition1OnTime, _ := time.Parse(layout, r.TimeCondition1OnTime)
  64. rTimeCondition1OffTime, _ := time.Parse(layout, r.TimeCondition1OffTime)
  65. rTimeCondition2OnTime, _ := time.Parse(layout, r.TimeCondition2OnTime)
  66. rTimeCondition2OffTime, _ := time.Parse(layout, r.TimeCondition2OffTime)
  67. rCurrent, _ := time.Parse(layout, current)
  68. if r.TimeCondition1OnTime != "关闭" &&
  69. (r.TimeCondition1OnTime == current ||
  70. (rCurrent.Before(rTimeCondition1OnTime.Add(11*time.Minute)) && rCurrent.After(rTimeCondition1OnTime))) {
  71. tmp[r.ID] = 1
  72. isTiming = 1
  73. }
  74. if r.TimeCondition1OffTime != "关闭" && (r.TimeCondition1OffTime == current ||
  75. (rCurrent.Before(rTimeCondition1OffTime.Add(11*time.Minute)) && rCurrent.After(rTimeCondition1OffTime))) {
  76. tmp[r.ID] = 0
  77. isTiming = 1
  78. }
  79. if r.TimeCondition2OnTime != "关闭" && (r.TimeCondition2OnTime == current ||
  80. (rCurrent.Before(rTimeCondition2OnTime.Add(11*time.Minute)) && rCurrent.After(rTimeCondition2OnTime))) {
  81. tmp[r.ID] = 1
  82. isTiming = 1
  83. }
  84. if r.TimeCondition2OffTime != "关闭" && (r.TimeCondition2OffTime == current ||
  85. (rCurrent.Before(rTimeCondition2OffTime.Add(11*time.Minute)) && rCurrent.After(rTimeCondition2OffTime))) {
  86. tmp[r.ID] = 0
  87. isTiming = 1
  88. }
  89. if isTiming == 1 {
  90. relayMap[d.Sn] = tmp
  91. }
  92. }
  93. }
  94. for key, value := range relayMap {
  95. reg, dev, err := utils.GetDataByDeviceId(key)
  96. if err != nil {
  97. logger.Get().Errorf("GetDataByDeviceId err = %s\n", err.Error())
  98. }
  99. for i, i2 := range value {
  100. data := modbus.DeviceLoopSwitch(i, i2)
  101. if model.ConnectionMap[key] == nil {
  102. logger.Get().Errorf("设备连接丢失")
  103. }
  104. err := utils.WriteDevice(data, model.ConnectionMap[key])
  105. time.Sleep(100 * time.Millisecond)
  106. if err != nil {
  107. logger.Get().Errorf("WriteDevice err = %s\n", err.Error())
  108. }
  109. for j, loop := range dev.DeviceLoops {
  110. if loop.ID == i {
  111. dev.DeviceLoops[j].State = i2
  112. }
  113. }
  114. }
  115. for i, device := range reg.Devices {
  116. if device.Sn == dev.Sn {
  117. reg.Devices[i] = dev
  118. }
  119. }
  120. data, err := utils.SaveRegionOnData(reg)
  121. if err != nil {
  122. logger.Get().Errorf("SaveRegionOnData err = %s\n", err.Error())
  123. }
  124. err = SaveData(data)
  125. if err != nil {
  126. logger.Get().Errorf("SaveData err = %s\n", err.Error())
  127. }
  128. }
  129. }
  130. func (c Cron) RelayOnOffTimeTaskSn(sn string) {
  131. _, dev, err := utils.GetDataByDeviceId(sn)
  132. if err != nil {
  133. logger.Get().Errorf("LoadData err = %s", err.Error())
  134. return
  135. }
  136. relays := dev.DeviceLoops
  137. rcTime, rlTime, err := utils.SunriseSunsetForChina(28.23, 113.05)
  138. tmp := make(map[int]int)
  139. for _, relay := range relays {
  140. //日出日落时间
  141. if relay.TimeCondition1OnTime == "日出" {
  142. relay.TimeCondition1OnTime = rcTime
  143. } else if relay.TimeCondition1OnTime == "日落" {
  144. relay.TimeCondition1OnTime = rlTime
  145. }
  146. if relay.TimeCondition1OffTime == "日出" {
  147. relay.TimeCondition1OffTime = rcTime
  148. } else if relay.TimeCondition1OffTime == "日落" {
  149. relay.TimeCondition1OffTime = rlTime
  150. }
  151. if relay.TimeCondition2OnTime == "日出" {
  152. relay.TimeCondition2OnTime = rcTime
  153. } else if relay.TimeCondition2OnTime == "日落" {
  154. relay.TimeCondition2OnTime = rlTime
  155. }
  156. if relay.TimeCondition2OffTime == "日出" {
  157. relay.TimeCondition2OffTime = rcTime
  158. } else if relay.TimeCondition2OffTime == "日落" {
  159. relay.TimeCondition2OffTime = rlTime
  160. }
  161. if relay.TimeCondition1OffTime == "关闭" && relay.TimeCondition1OnTime == "关闭" && relay.TimeCondition2OffTime == "关闭" && relay.TimeCondition2OnTime == "关闭" {
  162. continue
  163. }
  164. state, _ := ss(relay.TimeCondition1OnTime, relay.TimeCondition1OffTime, relay.TimeCondition2OnTime, relay.TimeCondition2OffTime)
  165. tmp[relay.ID] = state
  166. }
  167. for loop1, state := range tmp {
  168. reg, dev, err := utils.GetDataByDeviceId(sn)
  169. if err != nil {
  170. logger.Get().Errorf("GetDataByDeviceId err = %s\n", err.Error())
  171. }
  172. data := modbus.DeviceLoopSwitch(loop1, state)
  173. if model.ConnectionMap[sn] == nil {
  174. logger.Get().Errorf("设备连接丢失")
  175. }
  176. err = utils.WriteDevice(data, model.ConnectionMap[sn])
  177. time.Sleep(100 * time.Millisecond)
  178. if err != nil {
  179. logger.Get().Errorf("WriteDevice err = %s\n", err.Error())
  180. }
  181. for j, loop := range dev.DeviceLoops {
  182. if loop.ID == loop1 {
  183. dev.DeviceLoops[j].State = state
  184. }
  185. }
  186. for i, device := range reg.Devices {
  187. if device.Sn == dev.Sn {
  188. reg.Devices[i] = dev
  189. }
  190. }
  191. data1, err := utils.SaveRegionOnData(reg)
  192. if err != nil {
  193. logger.Get().Errorf("SaveRegionOnData err = %s\n", err.Error())
  194. }
  195. err = SaveData(data1)
  196. if err != nil {
  197. logger.Get().Errorf("SaveData err = %s\n", err.Error())
  198. }
  199. }
  200. }
  201. const (
  202. Off = iota
  203. On
  204. )
  205. type TimeControl struct {
  206. start time.Time
  207. end time.Time
  208. state int
  209. }
  210. func getDeviceState(schedules []TimeControl, currentTime time.Time) int {
  211. for _, period := range schedules {
  212. now := time.Date(0, time.January, 1, currentTime.Hour(), currentTime.Minute(), currentTime.Second(), currentTime.Nanosecond(), time.UTC)
  213. if period.start.After(period.end) {
  214. if now.After(period.start) || now.Before(period.end) {
  215. return period.state
  216. }
  217. } else {
  218. if now.After(period.start) && now.Before(period.end) {
  219. return period.state
  220. }
  221. }
  222. }
  223. return Off
  224. }
  225. func stateTransition(str string) int {
  226. if str == "on1" || str == "on2" {
  227. return On
  228. } else {
  229. return Off
  230. }
  231. }
  232. func ss(on1, off1, on2, off2 string) (int, error) {
  233. deviceRecoveryTime := time.Now()
  234. // 定义时间映射
  235. deviceTime := map[string]string{
  236. "on1": on1,
  237. "off1": off1,
  238. "on2": on2,
  239. "off2": off2,
  240. }
  241. // 创建一个切片存储时间
  242. var times []struct {
  243. key string
  244. value time.Time
  245. }
  246. // 将时间字符串解析为 time.Time 对象,并存入切片
  247. for key, value := range deviceTime {
  248. if value == "关闭" {
  249. continue
  250. }
  251. t, err := time.Parse("15:04", value)
  252. if err != nil {
  253. logger.Get().Error("时间转换失败!" + err.Error())
  254. return 0, err
  255. }
  256. times = append(times, struct {
  257. key string
  258. value time.Time
  259. }{key, t})
  260. }
  261. // 对时间进行排序
  262. sort.Slice(times, func(i, j int) bool {
  263. return times[i].value.Before(times[j].value)
  264. })
  265. var timeControls []TimeControl
  266. for i, _ := range times {
  267. if len(times) == i+1 {
  268. timeControls = append(timeControls, TimeControl{start: times[i].value, end: times[0].value.Add(24 * time.Hour), state: stateTransition(times[i].key)})
  269. continue
  270. }
  271. timeControls = append(timeControls, TimeControl{start: times[i].value, end: times[i+1].value, state: stateTransition(times[i].key)})
  272. }
  273. for _, control := range timeControls {
  274. fmt.Printf("%s : %s : %d\n", control.start, control.end, control.state)
  275. }
  276. // 在恢复时检查状态
  277. state := getDeviceState(timeControls, deviceRecoveryTime)
  278. return state, nil
  279. }