#!/usr/bin/env python # encoding: utf-8 """ @CreateTime: 2022/06/28 18:53 @Author: lxc @LastEditTime: @Desctiption: 聚鱼灯 """ from event_storage import EventStorage from log import OutPutLog import time from datetime import datetime from utility import Utility import json class AutoSwitchJuyudeng: def __init__(self): self._storage = EventStorage() self._log = OutPutLog() def run(self): self._log.info("[AutoSwitchDevice] - AutoSwitchDevice module is running!") run_time = 0 while True: this_time = time.time() self.now = datetime.now().strftime('%Y-%m-%d %H:%M:%S') if this_time - run_time > 60: run_time = this_time self.check_status() self.update_juyudeng_status() def get_light_real_status(self): """ 获取聚鱼灯的实时状态:光敏模式的状态、灯的开关状态 :return: {'juyudeng_1#_guangmin': 0, 'juyudeng_2#_guangmin': 1, 'juyudeng_3#_guangmin': 0, 'juyudeng_4#_guangmin': 0, 'juyudeng_5#_guangmin': 0, 'juyudeng_6#_guangmin': 1, 'juyudeng_7#_guangmin': 1, 'juyudeng_8#_guangmin': 1, 'juyudeng_1#_status': 1, 'juyudeng_2#_status': 1, 'juyudeng_3#_status': 0, 'juyudeng_4#_status': 0, 'juyudeng_5#_status': 1, 'juyudeng_6#_status': 1, 'juyudeng_7#_status': 0, 'juyudeng_8#_status': 0} """ sql_point_info = "SELECT serial_number,io_point_name " \ "FROM `data_point_tbl` " \ "WHERE `io_point_name` LIKE 'juyudeng_%_%';" point_info = self._storage.execute_sql(sql_point_info) read_real_list = [] point_name_dict = {} for each in point_info: serial_number = "c"+str(each["serial_number"]) read_real_list.append(serial_number) point_name_dict[serial_number] = each["io_point_name"] real_data_dict = self._storage.get_real_data(read_real_list) light_real_status = {} for k, v in real_data_dict.items(): light_real_status[point_name_dict[k]] = v return light_real_status def get_light_his_status(self): """ 获取聚鱼灯的历史状态信息 :return: [{'station_name': 'juyudeng_12#', 'location': '1#', 'control_mode': 0, 'status': 0, 'definite_time': '[]', 'commands': '{"open_light": [{"res": 65280, "device_id": 1, "start_addr": 0, "output_value": 65280, "function_code": 5}], "close_light": [{"res": 0, "device_id": 1, "start_addr": 0, "output_value": 0, "function_code": 5}], "open_photosense": [{"res": 0, "device_id": 1, "start_addr": 2, "output_value": 0, "function_code": 5}], "close_photosense": [{"res": 65280, "device_id": 1, "start_addr": 2, "output_value": 65280, "function_code": 5}]}', 'conn_status': 1}, ...] """ sql_his_info = "SELECT station_name,location,control_mode,status,definite_time,commands,conn_status " \ "FROM `gather_fish_light_control`;" his_info = self._storage.execute_sql(sql_his_info) return his_info def check_status(self): # 获取聚鱼灯的实时状态:光敏模式的状态、灯的开关状态 light_real_status = self.get_light_real_status() # print("light_real_status=", light_real_status) # 获取聚鱼灯的历史状态信息 light_his_status = self.get_light_his_status() for each in light_his_status: # {'station_name': 'juyudeng_12#', 'location': '2#', 'control_mode': 1, 'status': 1, 'definite_time': '[["00:00:00,23:59:59"]]', 'commands': '{}', 'conn_status': 0} station_name = each['station_name'] # 聚鱼灯的站名 location = each['location'] # 聚鱼灯的位置 his_control_mode = each['control_mode'] # 历史控制模式(0=光敏控制 1=手动控制 2=定时控制) his_status = each['status'] # 历史状态(0=关 1=开,模式1需要获取该参数的值) his_conn_status = each['conn_status'] # 历史通讯状态(0=在线,1=不在线) command = json.loads(each['commands']) # 控制开关的指令 guangmin_status = light_real_status[f"{station_name}_guangmin"] # 此刻光敏模式的状态(0=开 1=关) light_status = light_real_status[f"juyudeng_{location}_status"] # 此刻灯的状态(0=关 1=开) sql_update = False all_command = [] # 对比现在的状态和断电之前的状态 try: if light_status is not None and his_conn_status == 1: # 现在能读到聚鱼灯的状态且上一次读不到:将聚鱼灯的状态恢复至断电之前的状态,更新conn_status的状态 print(f"{self.now}-[check_status]-{location}聚鱼灯 ({light_status},{guangmin_status}) 1路表示灯开关(0关 1开) 2路表示光敏模式开关(0开 1关)") if his_control_mode == 0: # 恢复至光敏模式 if int(guangmin_status) == 1: # 当前是非光敏模式,需要改为光敏模式 if light_status == 1: # 先关灯 ??????????关两个灯????????? all_command.extend(command['close_light']) print(f"{self.now}-[check_status]-{location}聚鱼灯 先关灯,再设为光敏模式") # 再开光敏 all_command.extend(command['open_photosense']) print(f"{self.now}-[check_status]-{location}聚鱼灯 设为光敏模式") else: # 当前是光敏模式,不需要处理 # print(f"{self.now}-[check_status]-{location}聚鱼灯 当前是光敏模式,不需要处理") pass elif his_control_mode == 1: # 恢复至手动模式 if int(guangmin_status) == 0: # 先关闭光敏模式 all_command.extend(command['close_photosense']) print(f"{self.now}-[check_status]-{location}聚鱼灯 先关闭光敏模式,再修改灯的状态为{his_status}") if light_status != his_status: # 聚鱼灯改为his_status的状态(0=关 1=开) if his_status == 0: all_command.extend(command['close_light']) elif his_status == 1: all_command.extend(command['open_light']) print(f"{self.now}-[check_status]-{location}聚鱼灯 修改灯的状态为{his_status}") else: # print(f"{self.now}-[check_status]-{location}聚鱼灯 状态相同{his_status},不需要处理") pass elif his_control_mode == 2: # 恢复至定时模式 if int(guangmin_status) == 0: # 先关闭光敏模式 all_command.extend(command['close_photosense']) print(f"{self.now}-[check_status]-{location}聚鱼灯 定时模式:先关闭光敏模式") # 判断开关灯在 command_polling 方法中 # 更新conn_status的状态 sql_update = f"UPDATE `gather_fish_light_control` SET conn_status=0 WHERE `location`='{location}';" elif light_status is None and his_conn_status == 0: # 现在读不到聚鱼灯的状态且上一次能读到:更新conn_status的状态 sql_update = f"UPDATE `gather_fish_light_control` SET conn_status=1 WHERE location='{location}';" elif light_status is None and his_conn_status == 1: # print(f"{self.now}-[check_status]-{location}聚鱼灯一直处于离线状态,不做处理") pass elif light_status is not None and his_conn_status == 0: # 聚鱼灯一直处于在线状态 if int(his_status) == int(light_status): # print(f"{self.now}-[check_status]-{location}聚鱼灯一直处于在线状态,status与当前状态一致!") pass else: # 更新status字段的状态(control_mode字段的状态由前端调接口修改) sql_update = f"UPDATE `gather_fish_light_control` SET status={light_status} WHERE `location`='{location}';" print(f"{self.now}-[check_status]-{location}聚鱼灯一直处于在线状态,保存当前模式status={light_status}") # 执行修改状态的指令 if len(all_command) > 0: # jyd_connectors = Utility.available_connectors[f"juyudeng_{location}"] jyd_connectors = Utility.available_connectors[station_name] for each_command in all_command: print(f"{self.now}-[check_status]-{location}聚鱼灯 {each_command}") jyd_connectors.send_command(each_command) if sql_update: print(f"{self.now}-[check_status]-{location}聚鱼灯 {sql_update}") self._storage.execute_update_sql(sql_update) except Exception as e: print(f"{self.now}-[check_status]-{location}聚鱼灯 ERROR:{e}") self._log.error(e) def get_real_status(self): """ 获取聚鱼灯的实时状态 return:{'juyudeng_1#': '1', 'juyudeng_2#': None, 'juyudeng_3#': None,...} """ juyudeng_point_sql = "SELECT serial_number,io_point_name FROM `data_point_tbl` WHERE `io_point_name` LIKE 'juyudeng_%_status';" juyudeng_point = self._storage.execute_sql(juyudeng_point_sql) read_real_list = [] point_name_dict = {} for each in juyudeng_point: serial_number = "c"+str(each["serial_number"]) read_real_list.append(serial_number) juyudeng_name = each["io_point_name"].replace("_status", "") point_name_dict[serial_number] = juyudeng_name real_data_dict = self._storage.get_real_data(read_real_list) light_real_status = {} for k,v in real_data_dict.items(): light_real_status[point_name_dict[k]] = v return light_real_status def update_juyudeng_status(self): """判断聚鱼灯的状态是否需要修改""" # 获取聚鱼灯的实时状态 all_light_real_status = self.get_real_status() # {'juyudeng_1#': '1', 'juyudeng_2#': None,...} # print(all_light_real_status) # 判断聚鱼灯的状态是否需要修改 juyudeng_info_sql = "SELECT station_name,location,control_mode,definite_time,commands FROM `gather_fish_light_control`;" get_juyudeng_info = self._storage.execute_sql(juyudeng_info_sql) for juyudeng_info in get_juyudeng_info: # {'location': '1#', 'control_mode': 0, 'definite_time': '[["06:00:00,10:59:59"], ["00:03:00,03:50:59"]]', 'commands': None} control_mode = juyudeng_info["control_mode"] # 0:光敏控制,1:手动控制,2:定时控制 if control_mode == 0: '''光敏模式:前端发送控制指令''' pass elif control_mode == 1: '''手动模式:前端发送控制指令''' pass elif control_mode == 2: '''定时模式''' light_status = 0 # 默认聚鱼灯处于关闭状态 now_time = datetime.now().strftime("%H:%M:%S") definite_time = json.loads(juyudeng_info["definite_time"]) # 依次判断每个时间段 for time_list in definite_time: each_time = time_list[0].split(",") time1 = each_time[0] time2 = each_time[1] if time1 < time2: if time1 <= now_time <= time2: light_status = 1 else: if time2 <= now_time <= time1: light_status = 1 # 判断是否需要修改当前状态 light_name = f"juyudeng_{juyudeng_info['location']}" station_name = juyudeng_info['station_name'] # 聚鱼灯的站名 light_real_status = all_light_real_status[light_name] # print("///////////////////////",light_name, light_real_status, light_status) if light_real_status is None or int(light_status) != int(light_real_status): commands = json.loads(juyudeng_info["commands"]) if int(light_status) == 0: # 关灯 command = commands["close_light"] elif int(light_status) == 1: # 开灯 command = commands["open_light"] # print(light_name, light_real_status. light_status, command) try: Utility.available_connectors[station_name].send_command(command) except Exception as e: self._log.error(e) """ station_name: juyudeng_12# juyudeng_34# juyudeng_56# juyudeng_78# 开灯1/3/5/7:[{"res": 65280, "device_id": 1, "start_addr": 0, "output_value": 65280, "function_code": 5}] 关灯1/3/5/7:[{"res": 0, "device_id": 1, "start_addr": 0, "output_value": 0, "function_code": 5}] 开灯2/4/6/8:[{"res": 65280, "device_id": 1, "start_addr": 1, "output_value": 65280, "function_code": 5}] 关灯2/4/6/8:[{"res": 0, "device_id": 1, "start_addr": 1, "output_value": 0, "function_code": 5}] 开光敏1-8:[{"res": 0, "device_id": 1, "start_addr": 2, "output_value": 0, "function_code": 5}] 关光敏1-8:[{"res": 65280, "device_id": 1, "start_addr": 2, "output_value": 65280, "function_code": 5}] 1/3/5/7 {"open_light": [{"res": 65280, "device_id": 1, "start_addr": 0, "output_value": 65280, "function_code": 5}], "close_light": [{"res": 0, "device_id": 1, "start_addr": 0, "output_value": 0, "function_code": 5}], "open_photosense": [{"res": 0, "device_id": 1, "start_addr": 2, "output_value": 0, "function_code": 5}], "close_photosense": [{"res": 65280, "device_id": 1, "start_addr": 2, "output_value": 65280, "function_code": 5}]} 2/4/6/8 {"open_light": [{"res": 65280, "device_id": 1, "start_addr": 1, "output_value": 65280, "function_code": 5}], "close_light": [{"res": 0, "device_id": 1, "start_addr": 1, "output_value": 0, "function_code": 5}], "open_photosense": [{"res": 0, "device_id": 1, "start_addr": 2, "output_value": 0, "function_code": 5}], "close_photosense": [{"res": 65280, "device_id": 1, "start_addr": 2, "output_value": 65280, "function_code": 5}]} """