# 代码编写人:曾忠和 # coding: gb2312 import copy from PureBackend.base_driver import MODEL_MEDIAPIPE from PureBackend.manage_driver import ManagerDriver from LSZXNetWork.lszx_network import * from LSZXNetWork.data_transit import * from PureBackend.general import * from LSZXBackend.tag_control import * import shutil video_path = os.path.join(GLOBAL_DIR, "LSZXVideo", "Video") output_video_path = os.path.join(GLOBAL_DIR, "LSZXVideo", "Output_Video") class Synchronization(ManagerDriver): def __init__(self, master_mode=True, positioning=True, camera=True, model=MODEL_MEDIAPIPE, speaker=True, multi_positioning_mode=True, device_type=UNKNOWN, pure_mode=False): super().__init__(master_mode, positioning, camera, model, speaker, multi_positioning_mode, device_type, pure_mode) # 同步状态监控 self.synchronization_kill_sign = True self.synchronization_message = { TASK_HAD_DONE: 0, STATUS: STOP, TASK_NUMBER: 0 } # 定义接收端和发送端 self.server = Server(ip="0.0.0.0", port=server_port, file_port=server_file_port, cache_path=video_path) self.client = Client(ip="0.0.0.0") self.transit_server = Transit_Server(ip="0.0.0.0", transit_port=transit_server_port) self.transit_client = Transit_Client(ip="0.0.0.0") threading.Thread(target=self.receive_threads).start() # 接收线程 def receive_threads(self): while True: try: data = self.server.get_data() if data[0]['data_type'] == 'person_data': self.synchronization_server(data) elif data[0]['data_type'] == 'score_data': self.score_synchronization_server(data) elif data[0]['data_type'] == 'totals_data': self.totals_synchronization_server(data[0]['data']) elif data[0]['data_type'] == 'totals_sql_data': self.totals_sql_synchronization_server(data[0]['data']) elif data[0]['data_type'] == 'hrbo_data': self.totals_HrBoInfo_server(data[0]) elif data[0]['data_type'] == 'broadcast': self.broadcast(address_list=data[0]['address_list'], pkg_list=data[0]['pkg_list']) elif data[0]['data_type'] == 'tag_control_data': self.tag_control_server(data[0]) elif data[0]['data_type'] == 'get_band_id_response': self.get_band_id_response(data[0]) except Exception as e: GLOBAL_LOG.write(f"数据传输接收线程发生错误,{str(e)},错误来源:{traceback.format_exc()}") # 广播服务,用于转发设备间的信息 def broadcast(self, address_list, pkg_list): try: self.client.distributed_send(address_list, pkg_list) return True except Exception as e: GLOBAL_LOG.write(f"广播服务发生错误,{str(e)},错误来源:{traceback.format_exc()}") return False # 重置同步信息 def reset_synchronization_status(self): self.synchronization_message = { TASK_HAD_DONE: 0, STATUS: STOP, TASK_NUMBER: 0 } # 终端处理接收人员信息 def synchronization_server(self, cmd_data): try: for cmd in cmd_data: if self.synchronization_message[STATUS] == STARTING: if cmd[MSG] == "start": self.synchronization_message[TASK_HAD_DONE] = 0 self.synchronization_message[TASK_NUMBER] = cmd[TASK_NUMBER] self.synchronization_cache = [] elif cmd[MSG] == DATA: data = cmd[DATA] self.synchronization_cache.extend(data) self.synchronization_message[TASK_HAD_DONE] += cmd[TASK_NUMBER] elif cmd[MSG] == "stop": if self.synchronization_message[TASK_HAD_DONE] == self.synchronization_message[TASK_NUMBER]: # 更新标准 train_info = cmd[DIFFICULTY_MES] self.set_train_info(train_info) # 删除所有人员信息 self.manager.delete_all_person() # 更新人员信息 format_container = [ { PERSON_FEATURE_LIST[key_index]: row[key_index] for key_index in range(0, len(PERSON_FEATURE_LIST)) } for row in self.synchronization_cache ] container_dir = {} for con in format_container: container_dir[con["id"]] = con format_container = container_dir.values() self.manager.insert_many_person_from_json(format_container) self.synchronization_message[STATUS] = SUCCESS else: self.synchronization_cache = [] return True except Exception as e: GLOBAL_LOG.write(f"处理接收人员信息发生错误,{str(e)},错误来源:{traceback.format_exc()}") return False # 管理端处理接收成绩信息 def score_synchronization_server(self, cmd_data): try: for cmd in cmd_data: if self.synchronization_message[STATUS] == STARTING: if cmd[MSG] == "start": self.synchronization_message[TASK_HAD_DONE] = 0 self.synchronization_message[TASK_NUMBER] = cmd[TASK_NUMBER] self.synchronization_cache = [] elif cmd[MSG] == DATA: data = cmd[DATA] self.synchronization_cache.extend(data) self.synchronization_message[TASK_HAD_DONE] = cmd[TASK_NUMBER] elif cmd[MSG] == "stop": if self.synchronization_message[TASK_HAD_DONE] == self.synchronization_message[TASK_NUMBER]: self.synchronization_cache.copy() format_container = [ { SCORE_FEATURE_LIST[key_index]: row[key_index] for key_index in range(0, len(SCORE_FEATURE_LIST)) } for row in self.synchronization_cache ] # 逐条成绩更新 for con in format_container: result = self.manager.select_a_score(person_id=con[ID], score_type=con['score_type'], batch=self.summary_info['batch']) if result is None: self.manager.insert_a_score(record=con["record"], score=con['score'], person_id=con[ID], score_type=con['score_type'], batch=self.summary_info['batch'], person_class=con['class'], name=con[NAME]) else: _record = float(result[0]['record']) _score = float(result[0]['score']) if con['score_type'] in {RUNAROUND, RUNNING} and con["record"] != -1 \ and (float(con["record"]) < _record or float(con['score']) > _score): self.manager.update_timekeeping_score(record=con["record"], score=con['score'], person_id=con[ID], score_type=con['score_type'], batch=self.summary_info['batch']) elif float(con["record"]) > _record or float(con['score']) > _score: self.manager.update_counting_score(record=con["record"], score=con['score'], person_id=con[ID], score_type=con['score_type'], batch=self.summary_info['batch']) self.synchronization_message[STATUS] = SUCCESS else: self.synchronization_cache = [] return True except Exception as e: GLOBAL_LOG.write(f"处理接收成绩信息发生错误,{str(e)},错误来源:{traceback.format_exc()}") return False def data_synchronization(self): # 检查网络链接 try: if not self.connection.get_connected_wifi() and not self.connection.master_mode: self.speak_driver.add_speak("网络未连接!") GLOBAL_LOG.write(f"开启数据同步发生错误:网络未连接", need_print=True) return False except Exception as e: GLOBAL_LOG.write(f"开启数据同步发生错误:网络错误!请重新链接WiFi!", need_print=True) self.speak_driver.add_speak("网络错误!请重新链接WiFi!") return False self_ip = self.connection.get_self_ip() if not self_ip: self.speak_driver.add_speak("无法加入主机网络,请等待网络初始化,或重新链接WiFi!") GLOBAL_LOG.write(f"开启数据同步发生错误:无法加入主机网络,请等待网络初始化,或重新链接WiFi!", need_print=True) return False try: self.synchronization_message[STATUS] = STARTING self.speak_driver.add_speak("准备开始同步数据!") while not self.synchronization_kill_sign: time.sleep(0.1) # 等待更新结束 if self.synchronization_message[STATUS] == STOP: break elif self.synchronization_message[STATUS] == SUCCESS: self.reset_synchronization_status() # 清空录制屏幕视频 self.video_recorder.delete_video() self.speak_driver.add_speak("同步完成!") break return True except Exception as e: GLOBAL_LOG.write(f"开启数据同步发生错误,{str(e)},错误来源:{traceback.format_exc()}", need_print=True) return False # 终端开启数据同步 def waiting_data_synchronization(self): self.synchronization_kill_sign = False self.reset_synchronization_status() synchronization_thread = threading.Thread(target=self.data_synchronization) synchronization_thread.start() def score_synchronization(self): # 检查网络链接 try: if not self.connection.get_connected_wifi() and not self.connection.master_mode: GLOBAL_LOG.write(f"开启成绩同步发生错误:网络未连接", need_print=True) return False except Exception as e: GLOBAL_LOG.write(f"开启成绩同步发生错误:网络错误", need_print=True) return False self_ip = self.connection.get_self_ip() if not self_ip: GLOBAL_LOG.write(f"开启成绩同步发生错误:无法加入主机网络,请等待网络初始化,或重新链接WiFi!", need_print=True) return False try: self.synchronization_message[STATUS] = STARTING self.speak_driver.add_speak("准备开始同步数据!") while not self.synchronization_kill_sign: time.sleep(0.1) # 等待更新结束 if self.synchronization_message[STATUS] == STOP: break elif self.synchronization_message[STATUS] == SUCCESS: self.reset_synchronization_status() self.speak_driver.add_speak("同步完成!") break return True except Exception as e: GLOBAL_LOG.write(f"开启成绩同步发生错误,{str(e)},错误来源:{traceback.format_exc()}") return False # 管理端开启成绩同步 def waiting_score_synchronization(self): self.synchronization_kill_sign = False self.reset_synchronization_status() synchronization_thread = threading.Thread(target=self.score_synchronization) synchronization_thread.start() # 管理端发送同步数据 def send_data_synchronization(self): self.synchronization_kill_sign = False self.reset_synchronization_status() # 检查网络链接 try: if not self.connection.get_connected_wifi() and not self.connection.master_mode: GLOBAL_LOG.write(f"发送同步数据发生错误:网络未连接", need_print=True) return False except Exception as e: GLOBAL_LOG.write(f"发送同步数据发生错误:网络错误", need_print=True) return False self.synchronization_message[STATUS] = STARTING # 获得所有设备ip ip_list = self.connection.get_other() if not ip_list: self.speak_driver.add_speak("未检测到同步网络,同步结束!") self.reset_synchronization_status() return False try: # 获得所有人员信息 data = self.manager.select_all_person() format_data = [[row.get(key) for key in PERSON_FEATURE_LIST] for row in data] self.synchronization_message[TASK_NUMBER] = len(format_data) step = 100 # 发送起始包 start_pkg = {MSG: "start", TASK_NUMBER: len(format_data), 'data_type': 'person_data'} pkg = [start_pkg] # 发送所有数据 for segment_data in [format_data[i: i + step] for i in range(0, len(format_data), step)]: counting = len(segment_data) data_pkg = {MSG: DATA, DATA: segment_data, TASK_NUMBER: counting} pkg.append(data_pkg) self.synchronization_message[TASK_HAD_DONE] += len(segment_data) # 发送结束包 stop_pkg = {MSG: "stop", DIFFICULTY_MES: self.train_info} pkg.append(stop_pkg) # 打包人员信息 address_list = [] pkg_list = [] for ip in ip_list: address_list.append((ip, server_port)) pkg_list.append(pkg) # 发送到主机,再由主机转发 broadcast_pkg = [{'address_list': address_list, 'pkg_list': pkg_list, 'data_type': 'broadcast'}] master_ip = self.connection.get_master_ip() print(pkg) self.client.connect2(ip=master_ip, port=server_port) self.client.send(broadcast_pkg) # 更新同步状态包 self.synchronization_message[STATUS] = SUCCESS self.speak_driver.add_speak("同步完成!") return True except Exception as e: GLOBAL_LOG.write(f"发送同步数据发生错误,{str(e)},错误来源:{traceback.format_exc()}") return False def send_score_synchronization_thread(self): synchronization_thread = threading.Thread(target=self.send_score_synchronization) synchronization_thread.start() # 终端发送同步成绩 def send_score_synchronization(self): self.synchronization_kill_sign = False self.reset_synchronization_status() # 检查网络链接 try: if (not self.connection.get_connected_wifi() and not self.connection.master_mode): self.speak_driver.add_speak("网络未连接!") return False except Exception as e: self.speak_driver.add_speak("网络错误!请重新链接WiFi!") GLOBAL_LOG.write(f"发送同步数据发生错误:网络错误", need_print=True) return False if not self.connection.get_manager(): self.speak_driver.add_speak("未检测到管理端网络!") self.reset_synchronization_status() return False try: self.speak_driver.add_speak("准备开始同步数据!") # 更新同步状态包 self.synchronization_message[STATUS] = STARTING self.synchronization_message[TASK_HAD_DONE] = 0 self.synchronization_message[TASK_NUMBER] = 0 # 获得所有成绩信息 data = self.manager.select_score() format_data = [[row.get(key) for key in SCORE_FEATURE_LIST] for row in data] video_num = len(os.listdir(video_path)) manager_num = len(self.connection.get_manager()) self.synchronization_message[TASK_NUMBER] = len(format_data) + video_num + video_num * manager_num step = 100 counting = 0 # 发送起始包 master_ip = self.connection.get_master_ip() start_pkg = {MSG: "start", TASK_NUMBER: len(format_data), 'data_type': 'score_data'} pkg = [start_pkg] for segment_data in [ format_data[i: i + step] for i in range(0, len(format_data), step) ]: counting += len(segment_data) data_pkg = {MSG: DATA, DATA: segment_data, TASK_NUMBER: counting} pkg.append(data_pkg) self.synchronization_message[TASK_HAD_DONE] += len(segment_data) # 压缩视频 try: if not os.path.exists(output_video_path): os.mkdir(output_video_path) else: shutil.rmtree(output_video_path) os.mkdir(output_video_path) input_video_list = os.listdir(video_path) for vide_path in input_video_list: if not self.synchronization_kill_sign: self.video_sending.convert_video(vide_path) self.synchronization_message[TASK_HAD_DONE] += 1 else: break for _ip in self.connection.get_manager(): self.transit_client.connect_transit(ip=master_ip, port=transit_server_port) for filename in os.listdir(output_video_path): if not self.synchronization_kill_sign: v_name = os.path.join(output_video_path, filename) # 发送视频 self.transit_client.transit_file(file_path=v_name, file_name=filename, final_target_ip=_ip) self.synchronization_message[TASK_HAD_DONE] += 1 else: break except: print(traceback.format_exc()) print("发送压缩视频失败!!!") # 发送结束包 stop_pkg = {MSG: "stop"} pkg.append(stop_pkg) # 发送成绩信息 address_list = [] pkg_list = [] for ip in self.connection.get_manager(): address_list.append((ip, server_port)) pkg_list.append(pkg) broadcast_pkg = [{'address_list': address_list, 'pkg_list': pkg_list, 'data_type': 'broadcast'}] # self.client.distributed_send(address_list, pkg_list) self.client.connect2(ip=master_ip, port=server_port) self.client.send(broadcast_pkg) # 更新同步状态包 self.synchronization_message[STATUS] = SUCCESS self.speak_driver.add_speak("同步完成!") return True except Exception as e: self.speak_driver.add_speak("同步时发生错误,同步结束!") GLOBAL_LOG.write(f"发送同步成绩发生错误,{str(e)},错误来源:{traceback.format_exc()}") return False # 获取数据同步进度 def get_synchronization_processing(self): mes_got = copy.deepcopy(self.synchronization_message) try: return mes_got except Exception as e: GLOBAL_LOG.write(f"获取数据同步进度发生错误,{str(e)},错误来源:{traceback.format_exc()}") return None # 结束数据同步 def stop_data_synchronization(self): try: self.synchronization_kill_sign = True self.speak_driver.add_speak("同步结束!") self.reset_synchronization_status() return True except Exception as e: GLOBAL_LOG.write(f"结束数据同步发生错误,{str(e)},错误来源:{traceback.format_exc()}") return False # 手环操作 def tag_control_server(self, data): try: detected_tag = None # 获取当前手环服务 if data[CMD] == CMD_GET_BAND_ID: detected_tag = get_tag_func( speak_driver=self.speak_driver, positioning=self.positioning ) if detected_tag: master_ip = self.connection.get_master_ip() pkg = [{'data': detected_tag, 'data_type': 'get_band_id_response'}] self.client.connect2(ip=master_ip, port=server_port) self.client.send(pkg) # 关闭所有手环服务 elif data[CMD] == CMD_CLOSE_BAND: close_all_band( speak_driver=self.speak_driver, positioning=self.positioning ) # 关闭所有手环的警报 elif data[CMD] == CMD_STOP_ALARM_ALL: close_all_band_alarm( speak_driver=self.speak_driver, positioning=self.positioning ) # 关闭指定手环的警报 elif data[CMD] == CMD_STOP_ALARM: tag_id = data[TAG] stop_assign_alarm( speak_driver=self.speak_driver, positioning=self.positioning, tag_id=tag_id ) return detected_tag except Exception as e: GLOBAL_LOG.write(f"发生错误,{str(e)},错误来源:{traceback.format_exc()}") # 获得当前检测的手环 def get_band_id_passive(self): try: if self.connection.get_connected_wifi_name(): master_ip = self.connection.get_master_ip() else: self.speak_driver.add_speak("网络未连接") return True except Exception as e: GLOBAL_LOG.write(f"发生错误,{str(e)},错误来源:{traceback.format_exc()}") return False try: pkg = [{CMD: CMD_GET_BAND_ID, 'data_type': 'tag_control_data'}] self.client.connect2(ip=master_ip, port=server_port) self.client.send(pkg) return None except Exception as e: GLOBAL_LOG.write(f"发生错误,{str(e)},错误来源:{traceback.format_exc()}") return None # 获得当前检测手环回应 def get_band_id_response(self, data): try: response = data['data'] detected_tag = response.json()[DETECTED_TAG] return detected_tag except Exception as e: GLOBAL_LOG.write(f"发生错误,{str(e)},错误来源:{traceback.format_exc()}") return None # 关闭所有手环 def close_all_band(self): try: if self.connection.get_connected_wifi_name(): master_ip = self.connection.get_master_ip() else: self.speak_driver.add_speak("网络未连接") return True except Exception as e: GLOBAL_LOG.write(f"发生错误,{str(e)},错误来源:{traceback.format_exc()}") return False try: pkg = [{CMD: CMD_CLOSE_BAND, 'data_type': 'tag_control_data'}] self.client.connect2(ip=master_ip, port=server_port) self.client.send(pkg) return True except Exception as e: GLOBAL_LOG.write(f"发生错误,{str(e)},错误来源:{traceback.format_exc()}", need_print=True) return False # 关闭所有手环警报 def stop_all_band_alarm(self): try: if self.connection.get_connected_wifi_name(): master_ip = self.connection.get_master_ip() else: self.speak_driver.add_speak("网络未连接") return True except Exception as e: GLOBAL_LOG.write(f"发生错误,{str(e)},错误来源:{traceback.format_exc()}") return False try: pkg = [{CMD: CMD_STOP_ALARM_ALL, 'data_type': 'tag_control_data'}] self.client.connect2(ip=master_ip, port=server_port) self.client.send(pkg) return True except Exception as e: GLOBAL_LOG.write(f"发生错误,{str(e)},错误来源:{traceback.format_exc()}", need_print=True) return False # 关闭手环警报 def stop_band_alarm(self, data): band_id = data.get(BAND_ID) try: if self.connection.get_connected_wifi_name(): master_ip = self.connection.get_master_ip() else: self.speak_driver.add_speak("网络未连接") return True except Exception as e: GLOBAL_LOG.write(f"发生错误,{str(e)},错误来源:{traceback.format_exc()}") return False try: pkg = [{CMD: CMD_STOP_ALARM_ALL, TAG: band_id, 'data_type': 'tag_control_data'}] self.client.connect2(ip=master_ip, port=server_port) self.client.send(pkg) return True except Exception as e: GLOBAL_LOG.write(f"发生错误,{str(e)},错误来源:{traceback.format_exc()}", need_print=True) return False