auto_switch_juyudeng.py 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  1. #!/usr/bin/env python
  2. # encoding: utf-8
  3. """
  4. @CreateTime: 2022/06/28 18:53
  5. @Author: lxc
  6. @LastEditTime:
  7. @Desctiption: 聚鱼灯
  8. """
  9. from event_storage import EventStorage
  10. from log import OutPutLog
  11. import time
  12. from datetime import datetime
  13. from utility import Utility
  14. import json
  15. class AutoSwitchJuyudeng:
  16. def __init__(self):
  17. self._storage = EventStorage()
  18. self._log = OutPutLog()
  19. def run(self):
  20. self._log.info("[AutoSwitchDevice] - AutoSwitchDevice module is running!")
  21. run_time = 0
  22. while True:
  23. this_time = time.time()
  24. self.now = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
  25. if this_time - run_time > 60:
  26. run_time = this_time
  27. self.check_status()
  28. self.update_juyudeng_status()
  29. def get_light_real_status(self):
  30. """
  31. 获取聚鱼灯的实时状态:光敏模式的状态、灯的开关状态
  32. :return: {'juyudeng_1#_guangmin': 0, 'juyudeng_2#_guangmin': 1, 'juyudeng_3#_guangmin': 0,
  33. 'juyudeng_4#_guangmin': 0, 'juyudeng_5#_guangmin': 0, 'juyudeng_6#_guangmin': 1, 'juyudeng_7#_guangmin': 1,
  34. 'juyudeng_8#_guangmin': 1, 'juyudeng_1#_status': 1, 'juyudeng_2#_status': 1, 'juyudeng_3#_status': 0,
  35. 'juyudeng_4#_status': 0, 'juyudeng_5#_status': 1, 'juyudeng_6#_status': 1, 'juyudeng_7#_status': 0,
  36. 'juyudeng_8#_status': 0}
  37. """
  38. sql_point_info = "SELECT serial_number,io_point_name " \
  39. "FROM `data_point_tbl` " \
  40. "WHERE `io_point_name` LIKE 'juyudeng_%_%';"
  41. point_info = self._storage.execute_sql(sql_point_info)
  42. read_real_list = []
  43. point_name_dict = {}
  44. for each in point_info:
  45. serial_number = "c"+str(each["serial_number"])
  46. read_real_list.append(serial_number)
  47. point_name_dict[serial_number] = each["io_point_name"]
  48. real_data_dict = self._storage.get_real_data(read_real_list)
  49. light_real_status = {}
  50. for k, v in real_data_dict.items():
  51. light_real_status[point_name_dict[k]] = v
  52. return light_real_status
  53. def get_light_his_status(self):
  54. """
  55. 获取聚鱼灯的历史状态信息
  56. :return: [{'location': '1#', 'control_mode': 1, 'status': 1, 'definite_time': '[]',
  57. 'commands': '{"open_light": [{"res": 65280, "device_id": 1, "start_addr": 0, "output_value": 65280, "function_code": 5},
  58. {"res": 65280, "device_id": 1, "start_addr": 1, "output_value": 65280, "function_code": 5}],
  59. "close_light": [{"res": 0, "device_id": 1, "start_addr": 0, "output_value": 0, "function_code": 5},
  60. {"res": 0, "device_id": 1, "start_addr": 1, "output_value": 0, "function_code": 5}],
  61. "open_photosense": [{"res": 0, "device_id": 1, "start_addr": 2, "output_value": 0, "function_code": 5}],
  62. "close_photosense": [{"res": 65280, "device_id": 1, "start_addr": 2, "output_value": 65280, "function_code": 5}]}',
  63. 'conn_status': 1}, ...]
  64. """
  65. sql_his_info = "SELECT location,control_mode,status,definite_time,commands,conn_status " \
  66. "FROM `gather_fish_light_control`;"
  67. his_info = self._storage.execute_sql(sql_his_info)
  68. return his_info
  69. def check_status(self):
  70. # 获取聚鱼灯的实时状态:光敏模式的状态、灯的开关状态
  71. light_real_status = self.get_light_real_status()
  72. print("light_real_status=", light_real_status)
  73. # 获取聚鱼灯的历史状态信息
  74. light_his_status = self.get_light_his_status()
  75. for each in light_his_status:
  76. # {'location': '2#', 'control_mode': 1, 'status': 1, 'definite_time': '[["00:00:00,23:59:59"]]', 'commands': '{}', 'conn_status': 0}
  77. location = each['location'] # 聚鱼灯的位置
  78. his_control_mode = each['control_mode'] # 历史控制模式(0=光敏控制 1=手动控制 2=定时控制)
  79. his_status = each['status'] # 历史状态(0=关 1=开,模式1需要获取该参数的值)
  80. his_conn_status = each['conn_status'] # 历史通讯状态(0=在线,1=不在线)
  81. command = json.loads(each['commands']) # 控制开关的指令
  82. guangmin_status = light_real_status[f"juyudeng_{location}_guangmin"] # 此刻光敏模式的状态(0=开 1=关)
  83. light_status = light_real_status[f"juyudeng_{location}_status"] # 此刻灯的状态(0=关 1=开)
  84. sql_update = False
  85. all_command = []
  86. # 对比现在的状态和断电之前的状态
  87. try:
  88. if light_status is not None and his_conn_status == 1:
  89. # 现在能读到聚鱼灯的状态且上一次读不到:将聚鱼灯的状态恢复至断电之前的状态,更新conn_status的状态
  90. print(f"{self.now}-[check_status]-{location}聚鱼灯 ({light_status},{light_status},{guangmin_status},0) 1、2路表示灯开关(0关 1开) 3路表示光敏模式开关(0开 1关)")
  91. if his_control_mode == 0:
  92. # 恢复至光敏模式
  93. if int(guangmin_status) == 1:
  94. # 当前是非光敏模式,需要改为光敏模式
  95. if light_status == 1:
  96. # 先关灯
  97. all_command.extend(command['close_light'])
  98. print(f"{self.now}-[check_status]-{location}聚鱼灯 先关灯,再设为光敏模式")
  99. # 再开光敏
  100. all_command.extend(command['open_photosense'])
  101. print(f"{self.now}-[check_status]-{location}聚鱼灯 设为光敏模式")
  102. else:
  103. # 当前是光敏模式,不需要处理
  104. # print(f"{self.now}-[check_status]-{location}聚鱼灯 当前是光敏模式,不需要处理")
  105. pass
  106. elif his_control_mode == 1:
  107. # 恢复至手动模式
  108. if int(guangmin_status) == 0:
  109. # 先关闭光敏模式
  110. all_command.extend(command['close_photosense'])
  111. print(f"{self.now}-[check_status]-{location}聚鱼灯 先关闭光敏模式,再修改灯的状态为{his_status}")
  112. if light_status != his_status:
  113. # 聚鱼灯改为his_status的状态(0=关 1=开)
  114. if his_status == 0:
  115. all_command.extend(command['close_light'])
  116. elif his_status == 1:
  117. all_command.extend(command['open_light'])
  118. print(f"{self.now}-[check_status]-{location}聚鱼灯 修改灯的状态为{his_status}")
  119. else:
  120. # print(f"{self.now}-[check_status]-{location}聚鱼灯 状态相同{his_status},不需要处理")
  121. pass
  122. elif his_control_mode == 2:
  123. # 恢复至定时模式
  124. if int(guangmin_status) == 0:
  125. # 先关闭光敏模式
  126. all_command.extend(command['close_photosense'])
  127. print(f"{self.now}-[check_status]-{location}聚鱼灯 定时模式:先关闭光敏模式")
  128. # 判断开关灯在 command_polling 方法中
  129. # 更新conn_status的状态
  130. sql_update = f"UPDATE `gather_fish_light_control` SET conn_status=0 WHERE `location`='{location}';"
  131. elif light_status is None and his_conn_status == 0:
  132. # 现在读不到聚鱼灯的状态且上一次能读到:更新conn_status的状态
  133. sql_update = f"UPDATE `gather_fish_light_control` SET conn_status=1 WHERE location='{location}';"
  134. elif light_status is None and his_conn_status == 1:
  135. # print(f"{self.now}-[check_status]-{location}聚鱼灯一直处于离线状态,不做处理")
  136. pass
  137. elif light_status is not None and his_conn_status == 0:
  138. # 聚鱼灯一直处于在线状态
  139. if int(his_status) == int(light_status):
  140. # print(f"{self.now}-[check_status]-{location}聚鱼灯一直处于在线状态,status与当前状态一致!")
  141. pass
  142. else:
  143. # 更新status字段的状态(control_mode字段的状态由前端调接口修改)
  144. sql_update = f"UPDATE `gather_fish_light_control` SET status={light_status} WHERE `location`='{location}';"
  145. print(f"{self.now}-[check_status]-{location}聚鱼灯一直处于在线状态,保存当前模式status={light_status}")
  146. # 执行修改状态的指令
  147. if len(all_command) > 0:
  148. jyd_connectors = Utility.available_connectors[f"juyudeng_{location}"]
  149. for each_command in all_command:
  150. print(f"{self.now}-[check_status]-{location}聚鱼灯 {each_command}")
  151. jyd_connectors.send_command(each_command)
  152. if sql_update:
  153. print(f"{self.now}-[check_status]-{location}聚鱼灯 {sql_update}")
  154. self._storage.execute_update_sql(sql_update)
  155. except Exception as e:
  156. print(f"{self.now}-[check_status]-{location}聚鱼灯 ERROR:{e}")
  157. self._log.error(e)
  158. def get_real_status(self):
  159. """
  160. 获取聚鱼灯的实时状态
  161. return:{'juyudeng_1#': '1', 'juyudeng_2#': None, 'juyudeng_3#': None,...}
  162. """
  163. juyudeng_point_sql = "SELECT serial_number,io_point_name FROM `data_point_tbl` WHERE `io_point_name` LIKE 'juyudeng_%_status';"
  164. juyudeng_point = self._storage.execute_sql(juyudeng_point_sql)
  165. read_real_list = []
  166. point_name_dict = {}
  167. for each in juyudeng_point:
  168. serial_number = "c"+str(each["serial_number"])
  169. read_real_list.append(serial_number)
  170. juyudeng_name = each["io_point_name"].replace("_status", "")
  171. point_name_dict[serial_number] = juyudeng_name
  172. real_data_dict = self._storage.get_real_data(read_real_list)
  173. light_real_status = {}
  174. for k,v in real_data_dict.items():
  175. light_real_status[point_name_dict[k]] = v
  176. return light_real_status
  177. def update_juyudeng_status(self):
  178. """判断聚鱼灯的状态是否需要修改"""
  179. # 获取聚鱼灯的实时状态
  180. all_light_real_status = self.get_real_status() # {'juyudeng_1#': '1', 'juyudeng_2#': None,...}
  181. # print(all_light_real_status)
  182. # 判断聚鱼灯的状态是否需要修改
  183. juyudeng_info_sql = "SELECT location,control_mode,definite_time,commands FROM `gather_fish_light_control`;"
  184. get_juyudeng_info = self._storage.execute_sql(juyudeng_info_sql)
  185. for juyudeng_info in get_juyudeng_info:
  186. # {'location': '1#', 'control_mode': 0, 'definite_time': '[["06:00:00,10:59:59"], ["00:03:00,03:50:59"]]', 'commands': None}
  187. control_mode = juyudeng_info["control_mode"] # 0:光敏控制,1:手动控制,2:定时控制
  188. if control_mode == 0:
  189. '''光敏模式:前端发送控制指令'''
  190. pass
  191. elif control_mode == 1:
  192. '''手动模式:前端发送控制指令'''
  193. pass
  194. elif control_mode == 2:
  195. '''定时模式'''
  196. light_status = 0 # 默认聚鱼灯处于关闭状态
  197. now_time = datetime.now().strftime("%H:%M:%S")
  198. definite_time = json.loads(juyudeng_info["definite_time"])
  199. # 依次判断每个时间段
  200. for time_list in definite_time:
  201. each_time = time_list[0].split(",")
  202. time1 = each_time[0]
  203. time2 = each_time[1]
  204. if time1 < time2:
  205. if time1 <= now_time <= time2:
  206. light_status = 1
  207. else:
  208. if time2 <= now_time <= time1:
  209. light_status = 1
  210. # 判断是否需要修改当前状态
  211. light_name = f"juyudeng_{juyudeng_info['location']}"
  212. light_real_status = all_light_real_status[light_name]
  213. # print("///////////////////////",light_name, light_real_status, light_status)
  214. if light_real_status is None or int(light_status) != int(light_real_status):
  215. commands = json.loads(juyudeng_info["commands"])
  216. if int(light_status) == 0:
  217. # 关灯
  218. command = commands["close_light"]
  219. elif int(light_status) == 1:
  220. # 开灯
  221. command = commands["open_light"]
  222. # print(light_name, light_real_status. light_status, command)
  223. try:
  224. Utility.available_connectors[light_name].send_command(command)
  225. except Exception as e:
  226. self._log.error(e)