# -*- coding: utf-8 -*- import base64 import copy import json import re import shutil import threading from copy import deepcopy from typing import List import requests from flask import jsonify, request, Response, send_from_directory, send_file import concurrent.futures import queue import LSZXBackend.base_driver from Backend.consensus import * # from Database.manager_database import * from DeviceDefine.consensus import UNKNOWN, MASTER, SLAVER from Exercise3.base_exercise import base_detect_image from Exercise3.overhang import Overhang from Exercise3.tricep_dip import Tricep_dip_1 from Exercise3.pull_up_1 import PullUp_1 from Exercise3.pull_up_2 import PullUp_2 from Exercise3.pull_up_3 import PullUp_3 from Exercise3.push_up_1 import PushUp_1 from Exercise3.push_up_2 import PushUp_2 from Exercise3.push_up_3 import PushUp_3 from Exercise3.run_around import Runaround # 调试 # from Exercise3.running_muwb import Running from Exercise3.running_muwb_with_rssi import Running import Exercise3.running_muwb_pure_detection from Exercise3.sit_up_new import SitUp_New from Exercise3.sit_up_old_1 import SitUp_Old_1 from Exercise3.sit_up_old_2 import SitUp_Old_2 from Exercise3.sit_up_old_3 import SitUp_Old_3 from LSZXBackend.eng_code import FUNC_TABLE, FACTORY_MODE from LSZXBackend.general import * from LSZXVideo.video_recording import VideoRecording from LSZXVideo.video_sender import VideoSending from Other.np_encoder import NpEncoder from Speaker.fake_speak_base import beep from Database.database_mgr import * # 难度值 DIFFICULT_HARD = 1 DIFFICULT_EASY = 2 STANDARDS_NEW = 3 STANDARDS_OLD = 4 COMMON_EASY = 5 # 训练难度 difficulty_lookup = { DIFFICULT_HARD: "比武难度", DIFFICULT_EASY: "考核难度", COMMON_EASY: "普通难度" } # 动作标准 standards_lookup = { STANDARDS_NEW: "新式动作标准", STANDARDS_OLD: "旧式动作标准" } DIFFICULT_FILE = "./train_info.json" SUMMARY_FILE = "./summary_info.json" DIFFICULTY_MES = "difficulty_mes" DIFFICULTY_DIS = "difficulty_display" DIFFICULTY = "difficulty" STANDARDS_DIS = "standards_display" STANDARDS = "standards" # 状态值 MAX_HR = "max_hr" MIN_BO = "min_bo" HR = "hr" BO = "bo" # 缓存路径 CACHE_DIR = "./Cache/" STARTING = 1 STOP = 0 # 准备录屏 video_path = os.path.join(GLOBAL_DIR, "LSZXVideo", "Video") output_video_path = os.path.join(GLOBAL_DIR, "LSZXVideo", "Output_Video") video_recorder = VideoRecording() video_recorder.start() # 视频发送 video_sending = VideoSending() # 用于在线程池中发送POST请求 def send_post_request(q, url_target): try: while not q.empty(): seg_data = q.get() _response = requests.post(url=url_target, json=seg_data, timeout=3) if _response.status_code != 200: print(f"请求网络:{url_target} 响应不成功") q.task_done() except requests.RequestException: print('转发失败!!!') print(traceback.format_exc()) class ExerciseBackend(LSZXBackend.base_driver.BaseDriver): def __init__( self, name, domain="0.0.0.0", port=0, master_mode=True, positioning=True, camera=True, speaker=True, multi_positioning_mode=True, device_type=UNKNOWN, **kwargs ): super().__init__( name, domain, port, master_mode, positioning=positioning, camera=camera, speaker=speaker, multi_positioning_mode=multi_positioning_mode, device_type=device_type, **kwargs ) # 管理难度 # 生成初始化动作难度与标准json文件 if not os.path.exists(DIFFICULT_FILE): self.train_info = { DIFFICULTY_DIS: difficulty_lookup[DIFFICULT_HARD], DIFFICULTY: DIFFICULT_HARD, STANDARDS_DIS: standards_lookup[STANDARDS_OLD], STANDARDS: STANDARDS_OLD, } try: with open(DIFFICULT_FILE, "w+", encoding='utf-8_sig') as f: json.dump(self.train_info, f, ensure_ascii=False) except: pass else: try: with open(DIFFICULT_FILE, "r", encoding='utf-8_sig') as f: self.train_info = json.load(f) except: pass # 手环状态监控 self.hr_bo_record = {MAX_HR: 0, MIN_BO: 100, HR: 0, BO: 100} # 同步状态监控 self.synchronization_kill_sign = True self.synchronization_message = { TASK_HAD_DONE: 0, STATUS: STOP, TASK_NUMBER: 0 } # 当前作训工程 self.project = None self.exercise_tag = "" self.running = None self.running_mes = {} # 数据同步缓存 self.synchronization_cache = [] # 实时展示 # 初始化传送管理端的成绩 self.synchronization_info = {} self.statistics_score = {SITUP: [], RUNAROUND: [], PUSHUP: [], PULLUP: [], RUNNING: [], 'total': [], 'top': {'total': {}, SITUP: {}, RUNAROUND: {}, PULLUP: {}, PUSHUP: {}, RUNNING: {}}} self._statistics_score = {} self._statistics_sql_score = {} self._sql_score = {} self.hrbo_info = {} self._hrbo_info = {} self.closed_chamber = {} self.HrBo_info = {} self.tag_mes = {HR: None, BO: None} if device_type == MASTER or device_type == SLAVER: self.send_score_signal = threading.Event() self.send_score_signal.set() self.send_sql_score_signal = threading.Event() # self.send_sql_score_signal.set() threading.Thread(target=self.send_score).start() threading.Thread(target=self.send_sql_score).start() else: self.manager.delete_orphan_batches() self.manager.delete_empty_score_type() self.sql_data = self.manager.select_all_score() for i in self.sql_data: i.update({'hr': {'hr': '', 'color': 'W'}, 'bo': {'bo': '', 'color': 'W'}}) self._sql_score.update({i['id']: copy.deepcopy(i)}) for key in i.keys(): if '_count' in key: if i[key]: score = str(i[key]) else: score = '' i[key] = {'count': score, 'is_changed': False} threading.Thread(target=self.processing_sql).start() self.processing_score_signal = threading.Event() threading.Thread(target=self.processing_score).start() # 汇总分析 if not os.path.exists(SUMMARY_FILE): batch = self.manager.get_this_batch() if not batch: this_time = int(time.time()) batch = time.strftime("%Y年%m月%d日%H时", time.localtime(this_time)) self.summary_info = { 'batch': batch, 'default_projects': {SITUP: '仰卧起坐', RUNAROUND: '30*2蛇形跑', PULLUP: '引体向上', RUNNING: '长跑'}, 'default_batch': batch, 'default_class_projects': {RUNNING: '长跑'}, 'default_class_batch': batch, 'default_group_projects': {RUNNING: '长跑'}, 'default_team_project': {RUNNING: '长跑'}, 'default_team_batch': batch, 'default_team_class': ['1班'], 'default_personal_projects': {SITUP: '仰卧起坐', RUNAROUND: '30*2蛇形跑', PULLUP: '引体向上', RUNNING: '长跑'}, 'default_personal_batch': [batch], 'default_personal_personal': {'id': 1, 'name': '人员1'} } try: with open(SUMMARY_FILE, "w+", encoding='utf-8_sig') as f: json.dump(self.summary_info, f, ensure_ascii=False) except: pass else: try: with open(SUMMARY_FILE, "r", encoding='utf-8_sig') as f: self.summary_info = json.load(f) batch = self.manager.get_this_batch() if batch: self.summary_info['batch'] = self.manager.get_this_batch() except: batch = self.manager.get_this_batch() if not batch: this_time = int(time.time()) batch = time.strftime("%Y年%m月%d日%H时", time.localtime(this_time)) self.summary_info = { 'batch': batch, 'default_projects': {SITUP: '仰卧起坐', RUNAROUND: '30*2蛇形跑', PULLUP: '引体向上', RUNNING: '长跑'}, 'default_batch': batch, 'default_class_projects': {RUNNING: '长跑'}, 'default_class_batch': batch, 'default_group_projects': {RUNNING: '长跑'}, 'default_team_project': {RUNNING: '长跑'}, 'default_team_batch': batch, 'default_team_class': ['1班'], 'default_personal_projects': {SITUP: '仰卧起坐', RUNAROUND: '30*2蛇形跑', PULLUP: '引体向上', RUNNING: '长跑'}, 'default_personal_batch': [batch], 'default_personal_personal': {'id': 1, 'name': '人员1'} } # 更新汇总信息json def _update_summary_info(self): try: with open(SUMMARY_FILE, "w", encoding='utf-8_sig') as f: json.dump(self.summary_info, f, ensure_ascii=False) except: print(traceback.format_exc()) def reset_hr_bo_record(self): self.hr_bo_record = {MAX_HR: 0, MIN_BO: 100, HR: 0, BO: 100} def update_hr_bo_record(self, tag_mes): if tag_mes[HR] != 0: self.hr_bo_record[HR] = tag_mes[HR] if self.hr_bo_record[MAX_HR] < tag_mes[HR]: self.hr_bo_record[MAX_HR] = tag_mes[HR] if tag_mes[BO] != 0: self.hr_bo_record[BO] = tag_mes[BO] if self.hr_bo_record[MIN_BO] > tag_mes[BO]: self.hr_bo_record[MIN_BO] = tag_mes[BO] def _get_train_info(self): try: with open(DIFFICULT_FILE, 'r', encoding='utf-8_sig') as read_json: self.train_info = json.load(read_json) difficulty = self.train_info[DIFFICULTY] standards = self.train_info[STANDARDS] return difficulty, standards except: if os.path.exists(DIFFICULT_FILE): os.remove(DIFFICULT_FILE) self.train_info = { DIFFICULTY_DIS: difficulty_lookup[DIFFICULT_HARD], DIFFICULTY: DIFFICULT_HARD, STANDARDS_DIS: standards_lookup[STANDARDS_OLD], STANDARDS: STANDARDS_OLD, } with open(DIFFICULT_FILE, "w+", encoding='utf-8_sig') as f: json.dump(self.train_info, f, ensure_ascii=False) difficulty = self.train_info[DIFFICULTY] standards = self.train_info[STANDARDS] return difficulty, standards def _set_train_info(self, train_info): try: difficulty = train_info.get(DIFFICULTY) standards = train_info.get(STANDARDS) if not difficulty or not standards: return self.train_info = { DIFFICULTY_DIS: difficulty_lookup[difficulty], DIFFICULTY: difficulty, STANDARDS_DIS: standards_lookup[standards], STANDARDS: standards } with open(DIFFICULT_FILE, "w+", encoding='utf-8_sig') as f: json.dump(self.train_info, f, ensure_ascii=False) except: print(traceback.format_exc()) def get_band_mes(self): data = request.json try: band_id = data.get(BAND_ID) if band_id: raw_info = self.manager.select_a_person_from_band(band_id) if not raw_info: return jsonify({STATUS: ID_ERROR, MSG: "该手环没有匹配的人员"}) info = raw_info[0] return jsonify({STATUS: STATUS_OK, DATA: info}) else: return jsonify({STATUS: ILLEGAL_CONFIG, MSG: "参数缺失"}) except Exception as e: return jsonify({STATUS: ACTION_FAIL, MSG: str(e)}) # 准备进行俯卧撑 def active_push_up(self): if self.project: self.project.kill() data = request.json person_id = data.get(ID) band_id = data.get(BAND_ID) if person_id: info = self.manager.select_a_person(person_id)[0] else: if band_id: raw_info = self.manager.select_a_person_from_band(band_id) if not raw_info: return jsonify({STATUS: ID_ERROR, MSG: "该手环没有匹配的人员"}) info = raw_info[0] else: return jsonify({STATUS: ILLEGAL_CONFIG, MSG: "参数缺失"}) try: difficulty, standards = self._get_train_info() if difficulty == DIFFICULT_HARD: self.project = PushUp_1(info, camera=self.camera) elif difficulty == DIFFICULT_EASY: self.project = PushUp_2(info, camera=self.camera) elif difficulty == COMMON_EASY: self.project = PushUp_3(info, camera=self.camera) self.exercise_tag = PUSHUP return jsonify({STATUS: STATUS_OK}) except Exception as e: return jsonify({STATUS: ACTION_FAIL, MSG: str(e)}) # 准备进行引体向上 def active_pull_up(self): if self.project: self.project.kill() data = request.json person_id = data.get(ID) band_id = data.get(BAND_ID) if person_id: info = self.manager.select_a_person(person_id)[0] else: if band_id: raw_info = self.manager.select_a_person_from_band(band_id) if not raw_info: return jsonify({STATUS: ID_ERROR, MSG: "该手环没有匹配的人员"}) info = raw_info[0] else: return jsonify({STATUS: ILLEGAL_CONFIG, MSG: "参数缺失"}) try: difficulty, standards = self._get_train_info() if difficulty == DIFFICULT_HARD: self.project = PullUp_1(info, camera=self.camera) elif difficulty == DIFFICULT_EASY: self.project = PullUp_2(info, camera=self.camera) elif difficulty == COMMON_EASY: self.project = PullUp_3(info, camera=self.camera) self.exercise_tag = PULLUP return jsonify({STATUS: STATUS_OK}) except Exception as e: return jsonify({STATUS: ACTION_FAIL, MSG: str(e)}) # 准备进行曲臂悬垂 def active_overhang(self): if self.project: self.project.kill() data = request.json person_id = data.get(ID) band_id = data.get(BAND_ID) if person_id: info = self.manager.select_a_person(person_id)[0] else: if band_id: raw_info = self.manager.select_a_person_from_band(band_id) if not raw_info: return jsonify({STATUS: ID_ERROR, MSG: "该手环没有匹配的人员"}) info = raw_info[0] else: return jsonify({STATUS: ILLEGAL_CONFIG, MSG: "参数缺失"}) try: self.project = Overhang(info, camera=self.camera) self.exercise_tag = OVERHANG return jsonify({STATUS: STATUS_OK}) except Exception as e: return jsonify({STATUS: ACTION_FAIL, MSG: str(e)}) # 准备进行双杠臂屈伸 def active_tricep_dip(self): if self.project: self.project.kill() data = request.json person_id = data.get(ID) band_id = data.get(BAND_ID) if person_id: info = self.manager.select_a_person(person_id)[0] else: if band_id: raw_info = self.manager.select_a_person_from_band(band_id) if not raw_info: return jsonify({STATUS: ID_ERROR, MSG: "该手环没有匹配的人员"}) info = raw_info[0] else: return jsonify({STATUS: ILLEGAL_CONFIG, MSG: "参数缺失"}) try: self.project = Tricep_dip_1(info, camera=self.camera) self.exercise_tag = TRICEDIP return jsonify({STATUS: STATUS_OK}) except Exception as e: return jsonify({STATUS: ACTION_FAIL, MSG: str(e)}) # 准备进行仰卧起坐 def active_sit_up(self): if self.project: self.project.kill() data = request.json person_id = data.get(ID) band_id = data.get(BAND_ID) if person_id: info = self.manager.select_a_person(person_id)[0] else: if band_id: raw_info = self.manager.select_a_person_from_band(band_id) if not raw_info: return jsonify({STATUS: ID_ERROR, MSG: "该手环没有匹配的人员"}) info = raw_info[0] else: return jsonify({STATUS: ILLEGAL_CONFIG, MSG: "参数缺失"}) try: difficulty, standards = self._get_train_info() if standards == STANDARDS_NEW: self.project = SitUp_New(info, camera=self.camera) elif standards == STANDARDS_OLD and difficulty == DIFFICULT_HARD: self.project = SitUp_Old_1(info, camera=self.camera) elif standards == STANDARDS_OLD and difficulty == DIFFICULT_EASY: self.project = SitUp_Old_2(info, camera=self.camera) elif standards == STANDARDS_OLD and difficulty == COMMON_EASY: self.project = SitUp_Old_3(info, camera=self.camera) self.exercise_tag = SITUP return jsonify({STATUS: STATUS_OK}) except Exception as e: return jsonify({STATUS: ACTION_FAIL, MSG: str(e)}) # 准备进行蛇形跑 def active_run_around(self): if self.project: self.project.kill() data = request.json person_id = data.get(ID) band_id = data.get(BAND_ID) if person_id: info = self.manager.select_a_person(person_id)[0] else: if band_id: raw_info = self.manager.select_a_person_from_band(band_id) if not raw_info: return jsonify({STATUS: ID_ERROR, MSG: "该手环没有匹配的人员"}) info = raw_info[0] else: return jsonify({STATUS: ILLEGAL_CONFIG, MSG: "参数缺失"}) try: self.project = Runaround(info, camera=self.camera) self.exercise_tag = RUNAROUND return jsonify({STATUS: STATUS_OK}) except Exception as e: return jsonify({STATUS: ACTION_FAIL, MSG: str(e)}) # 开始进行作训 def start_exercise(self): try: self.reset_hr_bo_record() # self.positioning.pause() self.camera.start_record() video_name = self.project.info[ID] + '_' + self.project.info[ "name"] + '_' + self.project.exercise_type + '_' + 'unknow' # 开始屏幕录制 video_recorder.write_start(video_name) self.project.start() self.project.waiting_for_start() # 清空传送管理端的成绩 self.synchronization_info = {} self.tag_mes = {HR: None, BO: None} return jsonify({STATUS: STATUS_OK, "valid": self.project.is_valid(), "mes": self.project.valid_mes()}) except Exception as e: print(traceback.format_exc()) error_msg = { STATUS: STATUS_UNKNOWN_ERROR, ERROR_MESSAGE: "出现错误,请联系后端开发人员!错误原因:{}".format(e) } return jsonify(error_msg) # 强制结束作训测试 def stop_exercise(self): try: if self.project: info = self.project.get_info() else: info = None self.camera.stop_record() self.camera.clear_cache() self.project.kill() result = self.project.get_result() score = result["score"] if score == '不合格': real_score = 0 else: real_score = float(score) video_name = self.project.info[ID] + '_' + self.project.info[ "name"] + '_' + self.project.exercise_type + '_' + str(real_score) # 结束屏幕录制 # video_recorder.write_stop(video_name) self.synchronization_info[self.exercise_tag] = {} self.send_score_signal.set() # self.send_sql_score_signal.set() return jsonify({STATUS: STATUS_OK, "info": info}) except Exception as e: print(traceback.format_exc()) error_msg = { STATUS: STATUS_UNKNOWN_ERROR, ERROR_MESSAGE: "出现错误,请联系后端开发人员!错误原因:{}".format(e) } return jsonify(error_msg) # 直接获取骨架信息 def video_directly(self): video_response = Response(base_detect_image(self.camera), mimetype='multipart/x-mixed-replace; boundary=frame') return video_response # 获得作训摄像头流 def exercise_video(self): if self.project is None: video_response = Response(base_detect_image(self.camera), mimetype='multipart/x-mixed-replace; boundary=frame') elif self.project and not self.project.is_start: video_response = Response(self.project.video_gen(), mimetype='multipart/x-mixed-replace; boundary=frame') else: video_response = Response(self.project.streaming_gen(), mimetype='multipart/x-mixed-replace; boundary=frame') return video_response # 录入作训成绩 def update_score(self): try: person_id = self.project.info[ID] name = self.project.info[NAME] person_class = self.project.info['class'] result = self.project.get_result() score = result["score"] had_done = result['had_done'] if score == '不合格': real_score = 0 else: real_score = float(score) count = result["count"] response_code = OK self.synchronization_info[self.exercise_tag] = {} self.send_score_signal.set() self._statistics_sql_score = { self.exercise_tag: {person_id: {'record': count, 'score': real_score}}} if had_done: self.send_sql_score_signal.set() _count = count _score = real_score elif self.exercise_tag in {PULLUP, TRICEDIP} and had_done == False: # 结束屏幕录制 video_name = self.project.info[ID] + '_' + self.project.info[ "name"] + '_' + self.project.exercise_type + '_' + str(real_score) video_recorder.write_stop(video_name) _count = count _score = real_score else: _count = -1 _score = 0 _result = self.manager.select_a_score(person_id=person_id, score_type=self.exercise_tag) if _result is None: response_code = self.manager.insert_a_score(record=_count, score=_score, person_id=person_id, score_type=self.exercise_tag, person_class=person_class, name=name) elif _count != -1: _record = float(_result[0]['record']) _score = float(_result[0]['score']) if self.exercise_tag in {PUSHUP, PULLUP, SITUP, OVERHANG, TRICEDIP}: if float(count) > _record or real_score > _score: response_code = self.manager.update_counting_score(record=count, score=real_score, person_id=person_id, score_type=self.exercise_tag) print(response_code) elif self.exercise_tag == RUNAROUND: if count != -1 and (float(count) < _record or real_score > _score): response_code = self.manager.update_timekeeping_score(record=_count, score=real_score, person_id=person_id, score_type=self.exercise_tag, ) else: response_code = STATUS_UNKNOWN_ERROR return_mes = "" except Exception as e: return_mes = str(e) response_code = STATUS_UNKNOWN_ERROR print(traceback.format_exc()) return jsonify({STATUS: response_code, "mes": return_mes}) # 获取作训成绩Websocket接口 def get_score(self, ws): while True: try: # 每隔0.3秒发送一次当前成绩 time.sleep(0.3) score_result = self.project.get_result() band_id = self.project.info.get("band_id") tag_mes = self.positioning.get_tag_mes(band_id) temp = {} if tag_mes: self.update_hr_bo_record(tag_mes) temp['hr'] = tag_mes[HR] temp['bo'] = "{:.2%}".format(tag_mes[BO] / 100) if tag_mes[HR] >= 190 or tag_mes[BO] <= 80: temp['normal'] = False else: temp['normal'] = True self.tag_mes = {HR: temp['hr'], BO: temp['bo']} else: if self.tag_mes[HR] and self.tag_mes[BO]: tag_mes = self.tag_mes else: tag_mes = {HR: '-', BO: '-'} temp['hr'] = tag_mes[HR] temp['bo'] = tag_mes[BO] temp['normal'] = True score_result.update(self.hr_bo_record) format_data = json.dumps(score_result, cls=NpEncoder) ws.send(format_data) temp['name'] = self.project.info[NAME] temp['id'] = self.project.info[ID] temp['count'] = score_result['count'] self.synchronization_info[self.exercise_tag] = temp self.send_score_signal.set() except Exception as e: # print(traceback.format_exc()) continue # 获得指定班级的数据 def get_class_data(self): try: data = request.json response_data = self.manager.get_a_class(data.get(CLASS)) return jsonify(response_data) except Exception as e: error_msg = {STATUS: UNKNOWN_ERROR, ERROR_MESSAGE: "出现错误,请联系后端开发人员!错误原因:{}".format(e)} return jsonify(error_msg) # 获得所有班级列表 def get_all_class(self): try: response_data = self.manager.get_all_class() return jsonify(response_data) except Exception as e: error_msg = {STATUS: UNKNOWN_ERROR, ERROR_MESSAGE: "出现错误,请联系后端开发人员!错误原因:{}".format(e)} return jsonify(error_msg) # 获得所有人员信息 def get_all_person(self): try: response_data = self.manager.select_all_person() return jsonify(response_data) except Exception as e: error_msg = {STATUS: UNKNOWN_ERROR, ERROR_MESSAGE: "出现错误,请联系后端开发人员!错误原因:{}".format(e)} return jsonify(error_msg) # 获得指定班级成绩 def get_a_class_score(self): try: data = request.json response_data = self.manager.get_a_class_score(data.get(CLASS)) return jsonify(response_data) except Exception as e: error_msg = {STATUS: UNKNOWN_ERROR, ERROR_MESSAGE: "出现错误,请联系后端开发人员!错误原因:{}".format(e)} return jsonify(error_msg) # 获得所有人员信息成绩 def get_all_score(self): try: response_data = self.manager.select_all_score() return jsonify(response_data) except Exception as e: error_msg = {STATUS: UNKNOWN_ERROR, ERROR_MESSAGE: "出现错误,请联系后端开发人员!错误原因:{}".format(e)} return jsonify(error_msg) # 開啓多基站長跑模式 def running_master_multi(self): self.running_mes.clear() try: self.running = Running(positioning=self.positioning) coordinates_data = { "master": [ [0, 0, "主机"] for _ in range(len(self.positioning.multi_uwb.uwb_driver_table)) ], "slaver": [] } self.speak_driver.add_speak("基站识别成功,请检查基站数量!") return jsonify({"status": OK, "coordinates": coordinates_data}) except Exception as e: print(traceback.format_exc()) error_msg = {"status": UNKNOWN_ERROR, "error_message": "出现错误,请联系后端开发人员!错误原因:{}".format(e)} return jsonify(error_msg) # 開啓多基站長跑模式 def running_master_pd_mode(self): self.running_mes.clear() try: self.running = Exercise3.running_muwb_pure_detection.Running(positioning=self.positioning) coordinates_data = { "master": [ [0, 0, "主机"] for _ in range(len(self.positioning.multi_uwb.uwb_driver_table)) ], "slaver": [] } self.speak_driver.add_speak("基站识别成功,请检查基站数量!") return jsonify({"status": OK, "coordinates": coordinates_data}) except Exception as e: print(traceback.format_exc()) error_msg = {"status": UNKNOWN_ERROR, "error_message": "出现错误,请联系后端开发人员!错误原因:{}".format(e)} return jsonify(error_msg) # 开启长跑主机模式 def running_master(self): self.running_mes.clear() # 检查网络链接 try: if not self.connection.get_connected_wifi() and not self.connection.master_mode: self.speak_driver.add_speak("网络未连接!") error_msg = {STATUS: CONNECTION_ERROR, ERROR_MESSAGE: "网络未链接!"} return jsonify(error_msg) except Exception as e: print(traceback.format_exc()) error_msg = { STATUS: CONNECTION_ERROR, ERROR_MESSAGE: "网络错误!", MSG: f"{e.args}" } self.speak_driver.add_speak("网络错误!请重新链接WiFi!") return jsonify(error_msg) if self.running: self.running.kill() # 重启驱动 self.positioning.resume() self.positioning.stop_positioning_mode() ip_list = [self.connection.get_self_ip()] + self.connection.get_other() if ip_list[0] is None: self.connection.wifi_ap.reboot() time.sleep(5) try: self.positioning.set_2_positioning_mode(10, ip_list) self.running = Running(positioning=self.positioning) anchor_coordinates = self.positioning.get_anchor_coordinates() if not anchor_coordinates: self.speak_driver.add_speak("定位出错,请重试或检查设备网络链接!") return jsonify({STATUS: ACTION_FAIL, ERROR_MESSAGE: "基站定位出错,请重试!"}) coordinates_data = { "master": [], "slaver": [] } master_anchor = self.running.get_master_anchor() for anchor, coordinate in anchor_coordinates.items(): if anchor == master_anchor: coordinates_data["master"].append([*coordinate, "主机"]) else: coordinates_data["slaver"].append([*coordinate, "从机"]) self.speak_driver.add_speak("基站识别成功,请检查基站数量!") return jsonify({STATUS: OK, "coordinates": coordinates_data}) except Exception as e: # self.positioning.pause() error_msg = {STATUS: UNKNOWN_ERROR, ERROR_MESSAGE: "出现错误,请联系后端开发人员!错误原因:{}".format(e)} return jsonify(error_msg) # 设置长跑的圈时圈数 def set_running_config(self): data = request.json round_num = data.get("round") min_round_time = data.get("min_round_time") try: self.running.set_config(round_num, min_round_time) return jsonify({STATUS: OK}) except Exception as e: error_msg = {STATUS: UNKNOWN_ERROR, ERROR_MESSAGE: "出现错误,请联系后端开发人员!错误原因:{}".format(e)} return jsonify(error_msg) # 重设长跑数据 def running_reset(self): try: # self.positioning.pause() self.running_mes = {} self.running.reset() return jsonify({STATUS: OK}) except Exception as e: error_msg = {STATUS: UNKNOWN_ERROR, ERROR_MESSAGE: "出现错误,请联系后端开发人员!错误原因:{}".format(e)} return jsonify(error_msg) # 长跑增加一个手环 def running_add_band(self): data = request.json ids = data.get("id") try: self.running_mes = {} self.running.reset() test_person_name = [] for person_id in ids: person_mes = self.manager.select_a_person(person_id) band_id = person_mes[0]["band_id"] if not band_id: if person_mes: return jsonify({STATUS: ID_ERROR, ERROR_MESSAGE: f"{person_mes[0]['name']}未链接到人员信息!"}) else: return jsonify({STATUS: ID_ERROR, ERROR_MESSAGE: f"找不到人员编号为<{person_id}>的信息!"}) self.running_mes[band_id] = person_mes[0] self.running.add_tag(band_id) self.running.add_tag_mes(band_id, person_mes[0]) test_person_name.append(person_mes[0]["name"]) return jsonify({STATUS: OK}) except Exception as e: error_msg = {STATUS: UNKNOWN_ERROR, ERROR_MESSAGE: "出现错误,请联系后端开发人员!错误原因:{}".format(e)} return jsonify(error_msg) # 长跑删除一个手环 def running_del_band(self): data = request.json band_id = data.get("band_id") try: del self.running_mes[band_id] self.running.del_tag(band_id) self.speak_driver.add_speak("删除成功!") return jsonify({STATUS: OK}) except Exception as e: error_msg = {STATUS: UNKNOWN_ERROR, ERROR_MESSAGE: "出现错误,请联系后端开发人员!错误原因:{}".format(e)} return jsonify(error_msg) # 查看当前指定人员的圈时 def get_round_time(self): data = request.json person_id = data.get("id") try: data = self.running.get_person_round_time(person_id) result = [] time_counting = 0 if data: for key, value in data.items(): time_counting += value round_time = str(time.strftime("%H:%M:%S", time.gmtime(value))) counting_round_time = str(time.strftime("%H:%M:%S", time.gmtime(time_counting))) result.append({ "name": f"第{key}圈用时", "time": f"{round_time}({counting_round_time})", "no": key }) else: result = [] result = sorted(result, key=lambda x: x["no"]) return jsonify({STATUS: OK, DATA: result}) except Exception as e: error_msg = {STATUS: UNKNOWN_ERROR, ERROR_MESSAGE: "出现错误,请联系后端开发人员!错误原因:{}".format(e)} return jsonify(error_msg) # 获得所有考生详情 def get_running_all_score(self): try: data = {STATUS: OK, DATA: self.running.get_all_score()} return jsonify(data) except Exception as e: error_msg = {STATUS: UNKNOWN_ERROR, ERROR_MESSAGE: "出现错误,请联系后端开发人员!错误原因:{}".format(e)} return jsonify(error_msg) # 修正指定考生成绩 def fix_score(self): data = request.json person_id = data.get("id") try: self.running.fix_score(person_id) return jsonify({STATUS: OK}) except Exception as e: error_msg = {STATUS: UNKNOWN_ERROR, ERROR_MESSAGE: "出现错误,请联系后端开发人员!错误原因:{}".format(e)} return jsonify(error_msg) # 撤销修正指定考生成绩 def fix_withdraw(self): data = request.json person_id = data.get("id") try: self.running.fix_withdraw(person_id) return jsonify({STATUS: OK}) except Exception as e: error_msg = {STATUS: UNKNOWN_ERROR, ERROR_MESSAGE: "出现错误,请联系后端开发人员!错误原因:{}".format(e)} return jsonify(error_msg) # 长跑手环列表 def running_list(self): try: return jsonify(list(self.running_mes.values())) except Exception as e: error_msg = {STATUS: UNKNOWN_ERROR, ERROR_MESSAGE: "出现错误,请联系后端开发人员!错误原因:{}".format(e)} return jsonify(error_msg) # 开始长跑 def start_running(self): try: self.running.start() return jsonify({STATUS: OK}) except Exception as e: error_msg = {STATUS: UNKNOWN_ERROR, ERROR_MESSAGE: "出现错误,请联系后端开发人员!错误原因:{}".format(e)} return jsonify(error_msg) # 设置是否进行语音播报 def voice_play(self): _data = request.json is_play = _data.get("data") try: self.running.set_play(is_play) return jsonify({STATUS: OK, MSG: "设置成功"}) except Exception as e: error_msg = {STATUS: UNKNOWN_ERROR, MSG: "出现错误,请联系后端开发人员!错误原因:{}".format(e)} return jsonify(error_msg) # 结束长跑 def stop_running(self): try: # self.positioning.pause() self.synchronization_info[RUNNING] = [] self.send_score_signal.set() # self.send_sql_score_signal.set() if self.running: self.running.stop() return jsonify({STATUS: OK}) except Exception as e: error_msg = {STATUS: UNKNOWN_ERROR, ERROR_MESSAGE: "出现错误,请联系后端开发人员!错误原因:{}".format(e)} return jsonify(error_msg) # 结束长跑 def stop_running_auto_clear(self): try: # self.positioning.pause() if self.running: self.running.stop() for person_mes in self.running_mes.values(): person_id = person_mes["id"] self.running.fix_score(person_id) return jsonify({STATUS: OK}) except Exception as e: print(traceback.format_exc()) error_msg = {STATUS: UNKNOWN_ERROR, ERROR_MESSAGE: "出现错误,请联系后端开发人员!错误原因:{}".format(e)} return jsonify(error_msg) # 获得当前成绩 # 获取跑步成绩Websocket接口 def running_score(self, ws): while True: # 每隔0.2秒发送一次当前成绩 time.sleep(0.5) raw_score = self.running.get_score() final_score = [] # 对初始成绩进行排序 if raw_score: raw_score = sorted(raw_score, key=lambda x: (-x["score"], -x["round"], x["band_id"], ["total_time"])) rank = 0 last_total_time = -1 for score in raw_score: if score["total_time"] != last_total_time: rank += 1 last_total_time = score["total_time"] full_mes = deepcopy(score) band_id = score["band_id"] tag_mes = self.positioning.get_tag_status(band_id) person_mes = self.running_mes[band_id] full_mes.update(person_mes) full_mes.update({ "rank": rank }) full_mes.update(tag_mes) final_score.append(full_mes) temp = [] for row in final_score: if row[HR] != 0 and row[BO] != 0: hr = row[HR] bo = "{:.2%}".format(row[BO] / 100) if row[HR] >= 220 or row[BO] < 80: normal = False else: normal = True else: hr = '-' bo = '-' normal = True temp.append( {'id': row['id'], 'name': row['name'], 'hr': hr, 'bo': bo, 'rank': row['rank'], 'finish': row['finish'], 'round': row['round'], 'count': row['total_time'], 'normal': normal}) self.synchronization_info[RUNNING] = temp self.send_score_signal.set() format_data = json.dumps(final_score) ws.send(format_data) # 确认长跑成绩有效 def update_running_score(self): try: final_score = self.running.get_valid_score() self.synchronization_info[RUNNING] = [] self.send_score_signal.set() self._statistics_sql_score = {RUNNING: {}} for score in final_score: result = self.manager.select_a_score(person_id=score[ID], score_type=RUNNING) if result is None: self.manager.insert_a_score(record=score["total_time"], score=score['score'], person_id=score[ID], score_type=RUNNING, person_class=score['class'], name=score[NAME]) else: _record = float(result[0]['record']) _score = float(result[0]['score']) if float(score["total_time"]) < _record or float(score['score']) > _score: self.manager.update_timekeeping_score(record=score["total_time"], score=score['score'], person_id=score[ID], score_type=RUNNING, ) self._statistics_sql_score[RUNNING][score[ID]] = {'record': score["total_time"], 'score': score['score']} if final_score: self.send_sql_score_signal.set() return jsonify({STATUS: OK}) except Exception as e: print(traceback.format_exc()) error_msg = {STATUS: UNKNOWN_ERROR, ERROR_MESSAGE: "出现错误,请联系后端开发人员!错误原因:{}".format(e)} return jsonify(error_msg) # 修改考核难度和动作标准信息并保存 def set_train_info(self): try: data = request.json self._set_train_info(data) return jsonify({STATUS: OK}) except Exception as e: error_msg = {STATUS: UNKNOWN_ERROR, ERROR_MESSAGE: "出现错误,请联系后端开发人员!错误原因:{}".format(e.args)} return jsonify(error_msg) # 查看考核难度和动作标准信息 def view_train_info(self): try: result = copy.copy(self.train_info) result.update({STATUS: OK}) return jsonify(result) except Exception as e: error_msg = {STATUS: UNKNOWN_ERROR, ERROR_MESSAGE: "出现错误,请联系后端开发人员!错误原因:{}".format(e)} return jsonify(error_msg) # 开启长跑从机模式 def running_slaver(self): error_msg = {STATUS: CONNECTION_ERROR, ERROR_MESSAGE: "从机未开放长跑功能!"} self.speak_driver.add_speak("从机未开放长跑功能!") return jsonify(error_msg) # # 检查网络链接 # try: # if not self.connection.wifi.wifi_connect_status(): # error_msg = {STATUS: CONNECTION_ERROR, ERROR_MESSAGE: "网络未链接!"} # return jsonify(error_msg) # except Exception as e: # error_msg = {STATUS: CONNECTION_ERROR, ERROR_MESSAGE: "网络错误!", MSG: f"{e.args}"} # return jsonify(error_msg) # try: # return jsonify({STATUS: OK}) # except Exception as e: # error_msg = {STATUS: UNKNOWN_ERROR, ERROR_MESSAGE: "出现错误,请联系后端开发人员!错误原因:{}".format(e)} # return jsonify(error_msg) # 开始长跑 def start_running_slaver(self): try: self.positioning.resume() self.positioning.stop_positioning_mode() return jsonify({STATUS: OK}) except Exception as e: # self.positioning.pause() error_msg = {STATUS: UNKNOWN_ERROR, ERROR_MESSAGE: "出现错误,请联系后端开发人员!错误原因:{}".format(e)} return jsonify(error_msg) # 结束长跑 def stop_running_slaver(self): try: # self.positioning.pause() self.positioning.stop_positioning_mode() return jsonify({STATUS: OK}) except Exception as e: error_msg = {STATUS: UNKNOWN_ERROR, ERROR_MESSAGE: "出现错误,请联系后端开发人员!错误原因:{}".format(e)} return jsonify(error_msg) # 增加一个人员 def add_person(self): try: data = request.json response_code = self.manager.insert_a_info(data) # if response_code == OK: # self.manager.insert_a_score(data) return jsonify({STATUS: response_code}) except Exception as e: error_msg = {STATUS: UNKNOWN_ERROR, ERROR_MESSAGE: "出现错误,请联系后端开发人员!错误原因:{}".format(e)} return jsonify(error_msg) # 导入excel def load_xlsx(self): try: data = request.files if not os.path.exists(CACHE_DIR): os.makedirs(CACHE_DIR) file = data.get("file") save_file_dir = CACHE_DIR + "person.xlsx" file.save(CACHE_DIR + "person.xlsx") response_code = self.manager.insert_many_person_from_xlsx(save_file_dir) return jsonify({STATUS: response_code}) except Exception as e: error_msg = {STATUS: UNKNOWN_ERROR, ERROR_MESSAGE: "出现错误,请联系后端开发人员!错误原因:{}".format(e)} return jsonify(error_msg) # 更新某个人的数据 def update_person(self): try: data = request.json response_code = self.manager.update_a_person(data) return jsonify({STATUS: response_code}) except Exception as e: error_msg = {STATUS: UNKNOWN_ERROR, ERROR_MESSAGE: "出现错误,请联系后端开发人员!错误原因:{}".format(e)} return jsonify(error_msg) # 删除某个人的数据 def delete_person(self): try: data = request.json person_to_be_del = data.get(ID) if isinstance(person_to_be_del, List): for person in person_to_be_del: response_code = self.manager.delete_a_person(person) if response_code == OK: self.manager.delete_a_score(person) else: response_code = self.manager.delete_a_person(data.get(ID)) if response_code == OK: self.manager.delete_a_score(data.get(ID)) return jsonify({STATUS: OK}) except Exception as e: error_msg = {STATUS: UNKNOWN_ERROR, ERROR_MESSAGE: "出现错误,请联系后端开发人员!错误原因:{}".format(e)} return jsonify(error_msg) # 删除所有人员信息 def delete_all_person(self): try: response_code = self.manager.delete_all_person() return jsonify({STATUS: response_code}) except Exception as e: error_msg = {STATUS: UNKNOWN_ERROR, ERROR_MESSAGE: "出现错误,请联系后端开发人员!错误原因:{}".format(e)} return jsonify(error_msg) # 导入成绩excel def load_score_xlsx(self): try: data = request.files if not os.path.exists(CACHE_DIR): os.makedirs(CACHE_DIR) file = data.get("file") save_file_dir = CACHE_DIR + "score.xlsx" file.save(CACHE_DIR + "score.xlsx") response_code = self.manager.insert_many_score_from_xlsx(save_file_dir) return jsonify({STATUS: response_code}) except Exception as e: error_msg = {STATUS: UNKNOWN_ERROR, ERROR_MESSAGE: "出现错误,请联系后端开发人员!错误原因:{}".format(e)} return jsonify(error_msg) # 搜索人员成绩信息 def get_a_name_score(self): try: data = request.json response_data = self.manager.select_a_score_from_name(data.get(NAME)) return jsonify(response_data) except Exception as e: error_msg = {STATUS: UNKNOWN_ERROR, ERROR_MESSAGE: "出现错误,请联系后端开发人员!错误原因:{}".format(e)} return jsonify(error_msg) # 搜索人员基本信息 def get_a_name_person(self): try: data = request.json response_data = self.manager.select_a_person_from_name(data.get(NAME)) return jsonify(response_data) except Exception as e: error_msg = {STATUS: UNKNOWN_ERROR, ERROR_MESSAGE: "出现错误,请联系后端开发人员!错误原因:{}".format(e)} return jsonify(error_msg) # 导出所有人员信息成绩 def get_score_xlsx(self): try: self.manager.dump_score(CACHE_DIR + "score.xlsx") return send_from_directory(CACHE_DIR, "score.xlsx") except Exception as e: error_msg = {STATUS: UNKNOWN_ERROR, ERROR_MESSAGE: "出现错误,请联系后端开发人员!错误原因:{}".format(e)} return jsonify(error_msg) # 导出所有人员信息 def get_person_xlsx(self): try: self.manager.dump_person(CACHE_DIR + "person.xlsx") return send_from_directory(CACHE_DIR, "person.xlsx") except Exception as e: error_msg = {STATUS: UNKNOWN_ERROR, ERROR_MESSAGE: "出现错误,请联系后端开发人员!错误原因:{}".format(e)} return jsonify(error_msg) # 删除所有人员信息 def delete_all_score(self): try: response_code = self.manager.clear_all_score() return jsonify({STATUS: response_code}) except Exception as e: error_msg = {STATUS: UNKNOWN_ERROR, ERROR_MESSAGE: "出现错误,请联系后端开发人员!错误原因:{}".format(e)} return jsonify(error_msg) # 重置同步信息 def reset_synchronization_status(self): self.synchronization_message = { TASK_HAD_DONE: 0, STATUS: 0, TASK_NUMBER: 0 } def synchronization_server(self): try: cmd = request.json # print(cmd) 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] = STOP else: self.synchronization_cache = [] # 清空录制屏幕视频 video_recorder.delete_video() return jsonify({STATUS: STATUS_OK}) except Exception as e: error_msg = {STATUS: UNKNOWN_ERROR, ERROR_MESSAGE: "出现错误,请联系后端开发人员!错误原因:{}".format(e)} print(traceback.format_exc()) return jsonify(error_msg) def score_synchronization_server(self): try: cmd = request.json 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 ] # container_dir = {} # for con in format_container: # container_dir[con["id"]] = con # format_container = container_dir.values() # 逐条成绩更新 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] = STOP else: self.synchronization_cache = [] return jsonify({STATUS: STATUS_OK}) except Exception as e: error_msg = {STATUS: UNKNOWN_ERROR, ERROR_MESSAGE: "出现错误,请联系后端开发人员!错误原因:{}".format(e)} print(traceback.format_exc()) return jsonify(error_msg) def video_synchronization_server(self): try: cmd = request.json if self.synchronization_message[STATUS] == STARTING: if cmd[MSG] == OK: name = cmd["name"] v = base64.b64decode(cmd[DATA]) v_dir = os.path.join(GLOBAL_DIR, "LSZXVideo", "Video", name) with open(v_dir, 'wb') as f: f.write(v) self.synchronization_message[TASK_HAD_DONE] += 1 return jsonify({STATUS: STATUS_OK}) except Exception as e: error_msg = {STATUS: UNKNOWN_ERROR, ERROR_MESSAGE: "出现错误,请联系后端开发人员!错误原因:{}".format(e)} print(traceback.format_exc()) return jsonify(error_msg) # 广播服务,用于转发设备间的信息 @staticmethod def broadcast(): try: json_mes = request.json targets = json_mes[TARGET] data = json_mes[DATA] # 创建一个最大并发量为16的线程池 executor = concurrent.futures.ThreadPoolExecutor(max_workers=16) futures = [] for url_target in targets: q = queue.Queue() # 创建队列,用于维护数据顺序 # 为每个URL创建的队列按顺序添加数据项 for seg_data in data: q.put(seg_data) # 将数据放入队列中 # 为每个URL创建一个任务 future = executor.submit(send_post_request, q, url_target) futures.append(future) concurrent.futures.wait(futures) # 等待所有任务完成 return jsonify({STATUS: OK}) except Exception as e: error_msg = {STATUS: UNKNOWN_ERROR, ERROR_MESSAGE: "出现错误,请联系后端开发人员!错误原因:{}".format(e)} return jsonify(error_msg) # 开启成绩同步 def waiting_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: error_msg = {STATUS: CONNECTION_ERROR, ERROR_MESSAGE: "网络未链接!"} return jsonify(error_msg) except Exception as e: error_msg = {STATUS: CONNECTION_ERROR, ERROR_MESSAGE: "网络错误!", MSG: f"{e.args}"} return jsonify(error_msg) self_ip = self.connection.get_self_ip() if not self_ip: error_msg = {STATUS: CONNECTION_ERROR, ERROR_MESSAGE: "无法加入主机网络,请等待网络初始化,或重新链接WiFi!"} return jsonify(error_msg) 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 self.speak_driver.add_speak("同步完成!") return jsonify({STATUS: OK}) except Exception as e: error_msg = {STATUS: UNKNOWN_ERROR, ERROR_MESSAGE: "出现错误,请联系后端开发人员!错误原因:{}".format(e)} return jsonify(error_msg) # 发送同步数据 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: error_msg = {STATUS: CONNECTION_ERROR, ERROR_MESSAGE: "网络未链接!"} return jsonify(error_msg) except Exception as e: error_msg = {STATUS: CONNECTION_ERROR, ERROR_MESSAGE: "网络错误!", MSG: f"{e.args}"} return jsonify(error_msg) self.synchronization_message[STATUS] = STARTING # 获得所有设备ip ip_list = self.connection.get_other() 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 counting = 0 # 发送起始包 start_pkg = {MSG: "start", TASK_NUMBER: len(format_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) targets = [ f"http://{ip}:{TERMINAL}/synchronization_server" for ip in ip_list ] master_ip = self.connection.get_master_ip() broadcast_pkg = { TARGET: targets, DATA: pkg } requests.post(url=f"http://{master_ip}:{TERMINAL}/broadcast", json=broadcast_pkg, timeout=30) # 更新同步状态包 self.synchronization_message[STATUS] = STOP self.speak_driver.add_speak("同步完成!") return jsonify({STATUS: OK}) except Exception as e: error_msg = {STATUS: UNKNOWN_ERROR, ERROR_MESSAGE: "出现错误,请联系后端开发人员!错误原因:{}".format(e)} return jsonify(error_msg) # 获取数据同步进度 def get_synchronization_processing(self): mes_got = copy.deepcopy(self.synchronization_message) try: return jsonify({STATUS: OK, DATA: mes_got}) except Exception as e: error_msg = {STATUS: UNKNOWN_ERROR, ERROR_MESSAGE: "出现错误,请联系后端开发人员!错误原因:{}".format(e)} return jsonify(error_msg) # 结束数据同步 def stop_data_synchronization(self): try: self.synchronization_kill_sign = True self.reset_synchronization_status() return jsonify({STATUS: OK}) except Exception as e: error_msg = {STATUS: UNKNOWN_ERROR, ERROR_MESSAGE: "出现错误,请联系后端开发人员!错误原因:{}".format(e)} return jsonify(error_msg) # 发送同步成绩 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("网络未连接!") error_msg = {STATUS: CONNECTION_ERROR, ERROR_MESSAGE: "网络未链接!"} return jsonify(error_msg) except Exception as e: error_msg = {STATUS: CONNECTION_ERROR, ERROR_MESSAGE: "网络错误!", MSG: f"{e.args}"} self.speak_driver.add_speak("网络错误!请重新链接WiFi!") return jsonify(error_msg) # 获得所有设备ip ip_list = self.connection.get_other() try: self.speak_driver.add_speak("准备开始同步数据!") # 更新同步状态包 self.synchronization_message[STATUS] = 1 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)) self.synchronization_message[TASK_NUMBER] = len(format_data) + video_num * 2 step = 100 counting = 0 # 发送起始包 start_pkg = {MSG: "start", TASK_NUMBER: len(format_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: video_sending.convert_video(vide_path) self.synchronization_message[TASK_HAD_DONE] += 1 else: break targets = [ f"http://{ip}:{MANAGER}/video_synchronization_server" for ip in self.connection.get_manager() ] master_ip = self.connection.get_master_ip() for filename in os.listdir(output_video_path): if not self.synchronization_kill_sign: v_name = os.path.join(output_video_path, filename) with open(v_name, 'rb') as file: v = base64.b64encode(file.read()).decode('utf-8') file = [{"name": filename, DATA: v, MSG: OK}] broadcast_pkg = { TARGET: targets, DATA: file } requests.post(url=f"http://{master_ip}:{TERMINAL}/broadcast", json=broadcast_pkg, timeout=30) self.synchronization_message[TASK_HAD_DONE] += 1 else: break except: print(traceback.format_exc()) print("发送压缩视频失败!!!") # 发送结束包 stop_pkg = {MSG: "stop"} pkg.append(stop_pkg) targets = [ f"http://{ip}:{MANAGER}/score_synchronization_server" for ip in self.connection.get_manager() ] master_ip = self.connection.get_master_ip() broadcast_pkg = { TARGET: targets, DATA: pkg } requests.post(url=f"http://{master_ip}:{TERMINAL}/broadcast", json=broadcast_pkg, timeout=3 * len(ip_list) + 1) # 清空录制屏幕视频 # video_recorder.delete_video() # 更新同步状态包 self.synchronization_message[STATUS] = STOP self.speak_driver.add_speak("同步完成!") return jsonify({STATUS: OK}) except Exception as e: self.speak_driver.add_speak("同步时发生错误,同步结束!") print(traceback.format_exc()) error_msg = {STATUS: UNKNOWN_ERROR, ERROR_MESSAGE: "出现错误,请联系后端开发人员!错误原因:{}".format(e)} return jsonify(error_msg) # 开启数据同步 def waiting_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: self.speak_driver.add_speak("网络未连接!") error_msg = {STATUS: CONNECTION_ERROR, ERROR_MESSAGE: "网络未链接!"} return jsonify(error_msg) except Exception as e: error_msg = {STATUS: CONNECTION_ERROR, ERROR_MESSAGE: "网络错误!", MSG: f"{e.args}"} self.speak_driver.add_speak("网络错误!请重新链接WiFi!") return jsonify(error_msg) self_ip = self.connection.get_self_ip() if not self_ip: self.speak_driver.add_speak("无法加入主机网络,请等待网络初始化,或重新链接WiFi!") error_msg = {STATUS: CONNECTION_ERROR, ERROR_MESSAGE: "无法加入主机网络,请等待网络初始化,或重新链接WiFi!"} return jsonify(error_msg) 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 self.speak_driver.add_speak("同步完成!") # 清空录制屏幕视频 video_recorder.delete_video() return jsonify({STATUS: OK}) except Exception as e: print(traceback.format_exc()) error_msg = {STATUS: UNKNOWN_ERROR, ERROR_MESSAGE: "出现错误,请联系后端开发人员!错误原因:{}".format(e)} return jsonify(error_msg) # 获取视频列表 def video_list(self): try: cmd = request.json person_id = cmd['id'] project = cmd['project'] response_data = [] for i in os.listdir(video_path): v_name = i.rsplit('.', 1)[0] data = v_name.split('_') if data[0] == person_id and data[2] == project: t = data[4].split('-') date = "{}年{}月{}日{}时{}分".format(t[0], t[1], t[2], t[3], t[4]) response_data.append({'name': i, 'date': date, 'project': data[2], 'score': data[3]}) response_data = sorted(response_data, key=lambda item: (item['date'], item['score']), reverse=True) return jsonify({STATUS: OK, DATA: response_data}) except Exception as e: print(traceback.format_exc()) error_msg = {STATUS: UNKNOWN_ERROR, ERROR_MESSAGE: "出现错误,请联系后端开发人员!错误原因:{}".format(e)} return jsonify(error_msg) # 获取视频 def video_server(self): try: cmd = request.json file_name = cmd['file_name'] video_dir = os.path.join(video_path, file_name) return send_file(video_dir) except Exception as e: error_msg = {STATUS: UNKNOWN_ERROR, ERROR_MESSAGE: "出现错误,请联系后端开发人员!错误原因:{}".format(e)} return jsonify(error_msg) # 向管理端发送成绩 def send_score(self): while True: try: self.send_score_signal.wait() self.send_score_signal.clear() manager_ip_list = self.connection.get_manager() ip = self.connection.get_self_ip() _ip = ip.split('.')[2] if manager_ip_list and _ip == '138': self.synchronization_info['time'] = time.time() broadcast_pkg = { DATA: self.synchronization_info, 'ip': ip } for manage_ip in manager_ip_list: try: requests.post(url=f"http://{manage_ip}:{MANAGER}/totals_synchronization_server", json=broadcast_pkg, timeout=3) except: continue except Exception: # print(traceback.format_exc()) continue # 向管理端发送数据库成绩 def send_sql_score(self): while True: try: self.send_sql_score_signal.wait() self.send_sql_score_signal.clear() manager_ip_list = self.connection.get_manager() ip = self.connection.get_self_ip() _ip = ip.split('.')[2] if manager_ip_list and _ip == "138": broadcast_pkg = { DATA: self._statistics_sql_score, 'ip': ip } for manager_ip in manager_ip_list: try: requests.post(url=f"http://{manager_ip}:{MANAGER}/totals_sql_synchronization_server", json=broadcast_pkg, timeout=3) except: continue self._statistics_sql_score = {} except Exception as e: # print(traceback.format_exc()) continue # 汇总成绩 def totals_synchronization_server(self): try: cmd = request.json ip = cmd['ip'] cmd['data']['time'] = time.time() if ip not in self._statistics_score: self._statistics_score.update({ip: {}}) self._statistics_score[ip] = cmd['data'] self.processing_score_signal.set() return jsonify({STATUS: OK}) except Exception as e: print(traceback.format_exc()) error_msg = {STATUS: UNKNOWN_ERROR, ERROR_MESSAGE: "出现错误,请联系后端开发人员!错误原因:{}".format(e)} return jsonify(error_msg) # 处理大屏实时成绩 def processing_score(self): while True: try: self.processing_score_signal.wait() self.processing_score_signal.clear() new_statistics_score = {SITUP: [], RUNAROUND: [], PUSHUP: [], PULLUP: [], RUNNING: []} for k, v in self._statistics_score.items(): for key, value in v.items(): if key == RUNNING: new_statistics_score.setdefault(key, []) new_statistics_score[key] = value new_statistics_score[key].sort(key=lambda x: (1 if x['normal'] else 0, x['rank'])) elif key != 'time': new_statistics_score.setdefault(key, []) if value: new_statistics_score[key].append(value) else: pass if key == 'runaround': new_statistics_score[key].sort(key=lambda x: (1 if x['normal'] else 0, x['count'])) else: new_statistics_score[key].sort(key=lambda x: (1 if x['normal'] else 0, -x['count'])) if key != 'time': for i in new_statistics_score[key]: if not i['normal'] and int(i['id']) not in self.closed_chamber: self.hrbo_info.update({int(i['id']): i}) self.statistics_score.update(new_statistics_score) # 5分钟后移出小黑屋 temp = self.closed_chamber.copy() for key, value in temp.items(): this_time = time.time() if this_time - int(value) > 300: del self.closed_chamber[key] except Exception as e: print(traceback.format_exc()) error_msg = {STATUS: UNKNOWN_ERROR, ERROR_MESSAGE: "出现错误,请联系后端开发人员!错误原因:{}".format(e)} return jsonify(error_msg) # 汇总数据库成绩 def totals_sql_synchronization_server(self): try: cmd = request.json exercise_tag = next(iter(cmd['data'])) if exercise_tag != RUNAROUND: record = str(exercise_tag) + '_' + 'count' score = str(exercise_tag) + '_' + 'score' else: record = 'run_bf_count' score = 'run_bf_score' for o in self.sql_data: for key, value in cmd['data'][exercise_tag].items(): if o['id'] == key: _record = self._sql_score[key][record] o[score] = value['score'] s = str(round(value['record'], 2)) if _record: o[record]['count'] = s + '(' + str(_record) + ')' else: o[record]['count'] = s o[record]['is_changed'] = True # if k in ('pullup_count', 'pullup_score', 'pushup_count', 'pushup_score', 'situp_count', # 'situp_score', 'running_score', 'run_bf_score'): # if n[k]: # if not o[k] or n[k] > o[k]: # o[k] = n[k] # elif k in ('run_bf_count', 'running_count'): # if n[k] and n[k] > 0: # if not o[k] or float(n[k]) < float(o[k]): # o[k] = format(float(n[k]), '.2f') # break threading.Thread(target=self.processing_sql).start() return jsonify({STATUS: OK}) except Exception as e: print(traceback.format_exc()) error_msg = {STATUS: UNKNOWN_ERROR, ERROR_MESSAGE: "出现错误,请联系后端开发人员!错误原因:{}".format(e)} return jsonify(error_msg) # 处理数据库成绩 def processing_sql(self): try: response_data = self.sql_data total = [ {'hr': row['hr'], 'bo': row['bo'], 'id': row['id'], 'name': row['name'], SITUP: row['situp_count'], RUNAROUND: row['run_bf_count'], PUSHUP: row['pushup_count'], PULLUP: row['pullup_count'], RUNNING: row['running_count']} for row in response_data] top_score = 0 top_situp = 0 top_pushup = 0 top_pullup = 0 top_runround = 40 top_running = 1800 for i in response_data: if i['pullup_score'] and i['situp_score'] and i['running_score'] and \ i['run_bf_score']: total_score = (float(i['pullup_score']) + float(i['situp_score']) + float(i['running_score']) + float(i['run_bf_score'])) / 4 if total_score > top_score: top_score = total_score self.statistics_score['top']['total'] = {'name': i['name'], 'score': top_score} if i['pullup_count']['count']: if '(' in str(i['pullup_count']['count']): count = float(i['pullup_count']['count'].split('(')[0]) if count > top_pullup: top_pullup = count self.statistics_score['top'][PULLUP] = {'name': i['name'], 'score': top_pullup} else: if float(i['pullup_count']['count']) > top_pullup: top_pullup = float(i['pullup_count']['count']) self.statistics_score['top'][PULLUP] = {'name': i['name'], 'score': top_pullup} if i['pushup_count']['count']: if '(' in str(i['pushup_count']['count']): count = float(i['pushup_count']['count'].split('(')[0]) if count > top_pushup: top_pushup = count self.statistics_score['top'][PUSHUP] = {'name': i['name'], 'score': top_pushup} else: if float(i['pushup_count']['count']) > top_pushup: top_pushup = float(i['pushup_count']['count']) self.statistics_score['top'][PUSHUP] = {'name': i['name'], 'score': top_pushup} if i['situp_count']['count']: if '(' in str(i['pushup_count']['count']): count = float(i['situp_count']['count'].split('(')[0]) if count > top_situp: top_situp = count self.statistics_score['top'][SITUP] = {'name': i['name'], 'score': top_situp} else: if float(i['situp_count']['count']) > top_situp: top_situp = float(i['situp_count']['count']) self.statistics_score['top'][SITUP] = {'name': i['name'], 'score': top_situp} if i['run_bf_count']['count']: if '(' in str(i['run_bf_count']['count']): count = float(i['run_bf_count']['count'].split('(')[0]) if top_runround > count > 0: top_runround = count self.statistics_score['top'][RUNAROUND] = {'name': i['name'], 'score': top_runround} else: if top_runround > float(i['run_bf_count']['count']) > 0: top_runround = float(i['run_bf_count']['count']) self.statistics_score['top'][RUNAROUND] = {'name': i['name'], 'score': top_runround} if i['running_count']['count']: if '(' in str(i['running_count']['count']): count = float(i['running_count']['count'].split('(')[0]) if count < top_running: top_running = count self.statistics_score['top'][RUNNING] = {'name': i['name'], 'score': top_running} else: if float(i['running_count']['count']) < top_running: top_running = float(i['running_count']['count']) self.statistics_score['top'][RUNNING] = {'name': i['name'], 'score': top_running} self.statistics_score['total'] = total except Exception as e: print(traceback.format_exc()) error_msg = {STATUS: UNKNOWN_ERROR, ERROR_MESSAGE: "出现错误,请联系后端开发人员!错误原因:{}".format(e)} return jsonify(error_msg) def statistics(self, ws): while True: try: time.sleep(0.5) self.statistics_score.update({STATUS: OK}) ws.send(json.dumps(self.statistics_score)) temp = self._statistics_score.copy() for k, v in temp.items(): this_time = time.time() if this_time - v['time'] > 60: del self._statistics_score[k] self.processing_score_signal.set() except Exception as e: print(traceback.format_exc()) error_msg = {STATUS: UNKNOWN_ERROR, ERROR_MESSAGE: "出现错误,请联系后端开发人员!错误原因:{}".format(e)} return jsonify(error_msg) # 接收心率血氧信息 def totals_HrBoInfo_server(self): try: cmd = request.json data = cmd["data"] # 5分钟后移出小黑屋 temp = self.closed_chamber.copy() for key, value in temp.items(): this_time = time.time() if this_time - int(value) > 300: del self.closed_chamber[key] # 汇总所有人hrbo信息 for k, v in data.items(): self._hrbo_info[k] = v # 筛选出警告人员 temp = self._hrbo_info.copy() for key, value in temp.items(): this_time = time.time() if this_time - value['record_time'] > 120: del self._hrbo_info[key] p_data = self.manager.select_a_person_from_band(key) if p_data: p_id = int(p_data[0]["id"]) p_name = p_data[0]["name"] for i in self.statistics_score['total']: if p_id == int(i[ID]): i['hr'] = value['hr'] i['bo'] = value['bo'] break if not value["normal"] and p_id not in self.closed_chamber: self.hrbo_info.update({p_id: value}) self.hrbo_info[p_id]["name"] = p_name return jsonify({STATUS: OK}) except Exception as e: print(traceback.format_exc()) error_msg = {STATUS: UNKNOWN_ERROR, ERROR_MESSAGE: "出现错误,请联系后端开发人员!错误原因:{}".format(e)} return jsonify(error_msg) # 心率血氧有误 def abnormal(self, ws): report_tag = "" while True: try: time.sleep(0.5) if self.hrbo_info: data = [] for key, value in self.hrbo_info.items(): data.append({"name": value["name"], "id": key, HR: value[HR], BO: value[BO]}) # # 演示版 # if int(key) == 34: # data.append({"name": value["name"], "id": key, HR: value[HR]['hr'], BO: value[BO]['bo']}) data = sorted(data, key=lambda item: item['id']) new_report_tag = "@".join([str(item['id']) for item in data]) ws.send(json.dumps({STATUS: OK, "data": data})) if report_tag != new_report_tag: report_tag = new_report_tag beep(duration=1500, freq=640) self.speak_driver.add_speak("体征监测系统警报!") for d in data: self.speak_driver.add_speak(f"{d['name']}体征异常!请尽快救护!") else: report_tag = "" ws.send(json.dumps({STATUS: OK, "data": []})) except Exception as e: print(traceback.format_exc()) error_msg = {STATUS: UNKNOWN_ERROR, ERROR_MESSAGE: "出现错误,请联系后端开发人员!错误原因:{}".format(e)} return jsonify(error_msg) # 心率血氧有误回传信号给后端 def receive(self): try: cmd = request.json self.hrbo_info = {} # 关入小黑屋 for i in cmd["data"]: this_time = time.time() p_id = int(i["id"]) self.closed_chamber.update({p_id: this_time}) return jsonify({STATUS: OK, "msg": "成功"}) except Exception as e: print(traceback.format_exc()) error_msg = {STATUS: UNKNOWN_ERROR, ERROR_MESSAGE: "出现错误,请联系后端开发人员!错误原因:{}".format(e)} return jsonify(error_msg) # 发送工程代码 def send_code(self): try: if FACTORY_MODE.is_set(): mes = "正在进行其他指令,请稍候!" self.speak_driver.add_speak(mes) return jsonify({STATUS: UNKNOWN_ERROR, "msg": mes}) else: FACTORY_MODE.set() cmd = request.json data = cmd["data"] code_re = re.search("[a-zA-Z0-9]+(?=@)", data) value_re = re.search("[0-9]+", data) code = code_re.group() if code_re else None value = value_re.group() if value_re else None mes = "指令不存在!" if code in FUNC_TABLE: mes = FUNC_TABLE[code](value=value, eb=self) else: self.speak_driver.add_speak(mes) return jsonify({STATUS: OK, "msg": mes}) except Exception as e: print(traceback.format_exc()) error_msg = {STATUS: UNKNOWN_ERROR, ERROR_MESSAGE: "出现错误,请联系后端开发人员!错误原因:{}".format(e)} return jsonify(error_msg) # 退出工程模式 def stop_code(self): try: FACTORY_MODE.clear() return jsonify({STATUS: OK, "msg": "成功"}) except Exception as e: print(traceback.format_exc()) error_msg = {STATUS: UNKNOWN_ERROR, ERROR_MESSAGE: "出现错误,请联系后端开发人员!错误原因:{}".format(e)} return jsonify(error_msg) # 演示视频1 def display_video1(self): try: video_dir = ".//display_video//1.mp4" return send_file(video_dir) except Exception as e: print(traceback.format_exc()) error_msg = {STATUS: UNKNOWN_ERROR, ERROR_MESSAGE: "出现错误,请联系后端开发人员!错误原因:{}".format(e)} return jsonify(error_msg) # 演示视频2 def display_video2(self): try: video_dir = ".//display_video//2.mp4" return send_file(video_dir) except Exception as e: print(traceback.format_exc()) error_msg = {STATUS: UNKNOWN_ERROR, ERROR_MESSAGE: "出现错误,请联系后端开发人员!错误原因:{}".format(e)} return jsonify(error_msg) # 演示视频3 def display_video3(self): try: video_dir = ".//display_video//3.mp4" return send_file(video_dir) except Exception as e: print(traceback.format_exc()) error_msg = {STATUS: UNKNOWN_ERROR, ERROR_MESSAGE: "出现错误,请联系后端开发人员!错误原因:{}".format(e)} return jsonify(error_msg) # 演示视频4 def display_video4(self): try: video_dir = ".//display_video//4.mp4" return send_file(video_dir) except Exception as e: print(traceback.format_exc()) error_msg = {STATUS: UNKNOWN_ERROR, ERROR_MESSAGE: "出现错误,请联系后端开发人员!错误原因:{}".format(e)} return jsonify(error_msg) # 读取当前考核批次GET def get_batch(self): try: batch = self.summary_info['batch'] return jsonify({STATUS: OK, DATA: batch}) except Exception as e: print(traceback.format_exc()) error_msg = {STATUS: UNKNOWN_ERROR, ERROR_MESSAGE: "出现错误,请联系后端开发人员!错误原因:{}".format(e)} return jsonify(error_msg) # 生成新的考核批次GET def set_batch(self): try: batch = self.manager.generate_batch() if batch: self.summary_info['batch'] = batch return jsonify({STATUS: OK}) except Exception as e: print(traceback.format_exc()) error_msg = {STATUS: UNKNOWN_ERROR, ERROR_MESSAGE: "出现错误,请联系后端开发人员!错误原因:{}".format(e)} return jsonify(error_msg) # 获取所有的课目GET def get_all_projects(self): try: projects = [] for k, v in EXERCISE_NAME_LIST.items(): projects.append({'value': k, 'label': v}) return jsonify({STATUS: OK, 'projects': projects}) except Exception as e: print(traceback.format_exc()) error_msg = {STATUS: UNKNOWN_ERROR, ERROR_MESSAGE: "出现错误,请联系后端开发人员!错误原因:{}".format(e)} return jsonify(error_msg) # 获取所有的批次GET def get_all_batch(self): try: all_batch = self.manager.get_all_batch() return jsonify({STATUS: OK, 'batch': all_batch}) except Exception as e: print(traceback.format_exc()) error_msg = {STATUS: UNKNOWN_ERROR, ERROR_MESSAGE: "出现错误,请联系后端开发人员!错误原因:{}".format(e)} return jsonify(error_msg) # 获取所有的人员GET def get_all_people(self): try: all_name = [] for k, v in self.manager.get_all_name().items(): all_name.append({'id': k, 'name': v}) return jsonify({STATUS: OK, 'people': all_name}) except Exception as e: print(traceback.format_exc()) error_msg = {STATUS: UNKNOWN_ERROR, ERROR_MESSAGE: "出现错误,请联系后端开发人员!错误原因:{}".format(e)} return jsonify(error_msg) # 获取所有的班级GET def get_all_classes(self): try: all_class = self.manager.get_all_class() return jsonify({STATUS: OK, 'class': all_class}) except Exception as e: print(traceback.format_exc()) error_msg = {STATUS: UNKNOWN_ERROR, ERROR_MESSAGE: "出现错误,请联系后端开发人员!错误原因:{}".format(e)} return jsonify(error_msg) # 汇总分析总览界面 # 获得课目训练汇总默认的课目和批次GET def get_projects_batch(self): try: projects = [] for k, v in self.summary_info['default_projects'].items(): projects.append(v) batch = self.summary_info['default_batch'] return jsonify({STATUS: OK, 'projects': projects, 'batch': batch}) except Exception as e: print(traceback.format_exc()) error_msg = {STATUS: UNKNOWN_ERROR, ERROR_MESSAGE: "出现错误,请联系后端开发人员!错误原因:{}".format(e)} return jsonify(error_msg) # 设置课目训练汇总课目和批次POST def set_projects_batch(self): try: cmd = request.json self.summary_info['default_projects'] = cmd['projects'] self.summary_info['default_batch'] = cmd['batch'] self._update_summary_info() return jsonify({STATUS: OK}) except Exception as e: print(traceback.format_exc()) error_msg = {STATUS: UNKNOWN_ERROR, ERROR_MESSAGE: "出现错误,请联系后端开发人员!错误原因:{}".format(e)} return jsonify(error_msg) # 环形图--总览 def circular_diagram(self): try: cmd = request.json projects = [] categorize = [] response_data = {} for k, v in cmd['projects'].items(): projects.append(k) response_data.update({k: []}) categorize.append({'name': v, 'keyname': k}) batch = cmd['batch'] data = self.manager.get_exercise_statistic( type_list=projects, batch=batch) for k, v in data.items(): for j in categorize: if k == j['keyname']: for i in GRADE_RANK: percentage = round(v[i]['percentage'] * 100, 2) response_data[k].append(percentage) return jsonify({STATUS: OK, 'categorize': categorize, DATA: response_data}) except Exception as e: print(traceback.format_exc()) error_msg = {STATUS: UNKNOWN_ERROR, ERROR_MESSAGE: "出现错误,请联系后端开发人员!错误原因:{}".format(e)} return jsonify(error_msg) # 详细成绩分布--总览环形图 def detailed_grade_info_1(self): try: cmd = request.json project = None for k, v in cmd['projects'].items(): project = k batch = cmd['batch'] grade = cmd['grade'] data = self.manager.get_exercise_statistic( type_list=[project], batch=batch ) response_data = [ { "id": person_data[ID], "name": person_data[NAME], "score": person_data[SCORE], "count": person_data[RECORD] } for person_data in data[project][grade][DATA] ] return jsonify({STATUS: OK, DATA: response_data}) except Exception as e: print(traceback.format_exc()) error_msg = {STATUS: UNKNOWN_ERROR, ERROR_MESSAGE: "出现错误,请联系后端开发人员!错误原因:{}".format(e)} return jsonify(error_msg) # 获得各班课目训练汇总默认的课目和批次GET def get_class_projects_batch(self): try: projects = [] for k, v in self.summary_info['default_class_projects'].items(): projects.append(v) batch = self.summary_info['default_class_batch'] return jsonify({STATUS: OK, 'projects': projects, 'batch': batch}) except Exception as e: print(traceback.format_exc()) error_msg = {STATUS: UNKNOWN_ERROR, ERROR_MESSAGE: "出现错误,请联系后端开发人员!错误原因:{}".format(e)} return jsonify(error_msg) # 设置各班课目训练汇总课目和批次POST def set_class_projects_batch(self): try: cmd = request.json self.summary_info['default_class_projects'] = cmd['projects'] self.summary_info['default_class_batch'] = cmd['batch'] self._update_summary_info() return jsonify({STATUS: OK}) except Exception as e: print(traceback.format_exc()) error_msg = {STATUS: UNKNOWN_ERROR, ERROR_MESSAGE: "出现错误,请联系后端开发人员!错误原因:{}".format(e)} return jsonify(error_msg) # 班级条形图--总览 def class_bar_chart(self): try: cmd = request.json project = None for k, v in cmd['projects'].items(): project = k batch = cmd['batch'] data = self.manager.get_class_statistic( batch=batch, _type=project ) team = [] for k, v in data.items(): team.append(k) team = sorted(team) response_data = [[] for _ in GRADE_RANK] for index, item in enumerate(GRADE_RANK): for _index, _item in enumerate(team): percentage = round(data[_item][item]['percentage'] * 100, 2) response_data[index].append(percentage) return jsonify({STATUS: OK, 'class': team, DATA: response_data}) except Exception as e: print(traceback.format_exc()) error_msg = {STATUS: UNKNOWN_ERROR, ERROR_MESSAGE: "出现错误,请联系后端开发人员!错误原因:{}".format(e)} return jsonify(error_msg) # 详细成绩分布--总览班级条形图 def detailed_grade_info_2(self): try: cmd = request.json project = None for k, v in cmd['projects'].items(): project = k batch = cmd['batch'] grade = cmd['grade'] _class = cmd['class'] data = self.manager.get_class_statistic( batch=batch, _type=project ) response_data = [ { "id": person_data[ID], "name": person_data[NAME], "score": person_data[SCORE], "count": person_data[RECORD] } for person_data in data[_class][grade][DATA] ] return jsonify({STATUS: OK, DATA: response_data}) except Exception as e: print(traceback.format_exc()) error_msg = {STATUS: UNKNOWN_ERROR, ERROR_MESSAGE: "出现错误,请联系后端开发人员!错误原因:{}".format(e)} return jsonify(error_msg) # 获得集体课目训练汇总默认的课目GET def get_group_projects(self): try: projects = [] for k, v in self.summary_info['default_group_projects'].items(): projects.append(v) return jsonify({STATUS: OK, 'projects': projects}) except Exception as e: print(traceback.format_exc()) error_msg = {STATUS: UNKNOWN_ERROR, ERROR_MESSAGE: "出现错误,请联系后端开发人员!错误原因:{}".format(e)} return jsonify(error_msg) # 设置集体课目训练汇总课目POST def set_group_projects(self): try: cmd = request.json self.summary_info['default_group_projects'] = cmd['projects'] self._update_summary_info() return jsonify({STATUS: OK}) except Exception as e: print(traceback.format_exc()) error_msg = {STATUS: UNKNOWN_ERROR, ERROR_MESSAGE: "出现错误,请联系后端开发人员!错误原因:{}".format(e)} return jsonify(error_msg) # 批次条形图--总览 def batch_bar_chart(self): try: cmd = request.json project = None for k, v in cmd['projects'].items(): project = k data = self.manager.get_group_statistic( _type=project ) all_batch = self.manager.get_all_batch() response_data = [[] for _ in GRADE_RANK] for index, item in enumerate(GRADE_RANK): for _index, _item in enumerate(all_batch): percentage = round(data[_item][item]['percentage'] * 100, 2) response_data[index].append(percentage) return jsonify({STATUS: OK, 'batch': all_batch, DATA: response_data}) except Exception as e: print(traceback.format_exc()) error_msg = {STATUS: UNKNOWN_ERROR, ERROR_MESSAGE: "出现错误,请联系后端开发人员!错误原因:{}".format(e)} return jsonify(error_msg) # 详细成绩分布--总览批次条形图 def detailed_grade_info_3(self): try: cmd = request.json project = None for k, v in cmd['projects'].items(): project = k batch = cmd['batch'] grade = cmd['grade'] data = self.manager.get_group_statistic( _type=project ) response_data = [ { "id": person_data[ID], "name": person_data[NAME], "score": person_data[SCORE], "count": person_data[RECORD] } for person_data in data[batch][grade][DATA] ] return jsonify({STATUS: OK, DATA: response_data}) except Exception as e: print(traceback.format_exc()) error_msg = {STATUS: UNKNOWN_ERROR, ERROR_MESSAGE: "出现错误,请联系后端开发人员!错误原因:{}".format(e)} return jsonify(error_msg) # 汇总分析集体界面 # 获得集体汇总默认的课目、班级、批次 def get_team_projects_batch_class(self): try: projects = None for k, v in self.summary_info['default_team_project'].items(): projects = v batch = self.summary_info['default_team_batch'] team = self.summary_info['default_team_class'] return jsonify({STATUS: OK, 'projects': projects, 'batch': batch, 'class': team}) except Exception as e: print(traceback.format_exc()) error_msg = {STATUS: UNKNOWN_ERROR, ERROR_MESSAGE: "出现错误,请联系后端开发人员!错误原因:{}".format(e)} return jsonify(error_msg) # 设置集体汇总默认的课目、班级、批次 def set_team_projects_batch_class(self): try: cmd = request.json self.summary_info['default_team_project'] = cmd['projects'] self.summary_info['default_team_batch'] = cmd['batch'] self.summary_info['default_team_class'] = cmd['class'] self._update_summary_info() return jsonify({STATUS: OK}) except Exception as e: print(traceback.format_exc()) error_msg = {STATUS: UNKNOWN_ERROR, ERROR_MESSAGE: "出现错误,请联系后端开发人员!错误原因:{}".format(e)} return jsonify(error_msg) # 集体比例分布图 def scale_drawing(self): try: cmd = request.json project = None for k, v in cmd['projects'].items(): project = k team = cmd['class'] batch = cmd['batch'] group_data = self.manager.get_group_multiple_statistic( _type=project, class_list=team, batch=batch ) response_data = [ { "name": grade, "value": len(group_data[grade][DATA]), "children": [ { "id": data[ID], "name": data[NAME], "score": data[SCORE], "count": data[RECORD] if data[RECORD] else "无", "cn_name": GRADE_LIST[grade], "value": 1 } for data in group_data[grade][DATA] ] } for grade in GRADE_LIST ] return jsonify({STATUS: OK, DATA: response_data}) except Exception as e: print(traceback.format_exc()) error_msg = {STATUS: UNKNOWN_ERROR, ERROR_MESSAGE: "出现错误,请联系后端开发人员!错误原因:{}".format(e)} return jsonify(error_msg) ## 汇总分析个人界面 # 获得个人汇总默认的课目、人员、批次 def get_personal_projects_batch_person(self): try: projects = [] for k, v in self.summary_info['default_personal_projects'].items(): projects.append(v) batch = self.summary_info['default_personal_batch'] personal = self.summary_info['default_personal_personal'] return jsonify({STATUS: OK, 'projects': projects, 'batch': batch, 'personal': personal}) except Exception as e: print(traceback.format_exc()) error_msg = {STATUS: UNKNOWN_ERROR, ERROR_MESSAGE: "出现错误,请联系后端开发人员!错误原因:{}".format(e)} return jsonify(error_msg) # 设置个人汇总默认的课目、人员、批次 def set_personal_projects_batch_person(self): try: cmd = request.json self.summary_info['default_personal_projects'] = cmd['projects'] self.summary_info['default_personal_batch'] = cmd['batch'] self.summary_info['default_personal_personal'] = cmd['person'] self._update_summary_info() return jsonify({STATUS: OK}) except Exception as e: print(traceback.format_exc()) error_msg = {STATUS: UNKNOWN_ERROR, ERROR_MESSAGE: "出现错误,请联系后端开发人员!错误原因:{}".format(e)} return jsonify(error_msg) # 雷达图 def radar_chart(self): try: cmd = request.json person = cmd['person'] projects = [] for k, v in cmd['projects'].items(): projects.append(k) batch = cmd['batch'] data = self.manager.get_individual_statistic( _id=str(person['id']), _type_list=projects, batch_list=batch ) response_data = data['type_avg'] return jsonify({STATUS: OK, DATA: response_data}) except Exception as e: print(traceback.format_exc()) error_msg = {STATUS: UNKNOWN_ERROR, ERROR_MESSAGE: "出现错误,请联系后端开发人员!错误原因:{}".format(e)} return jsonify(error_msg) # 折线图 def line_chart(self): try: cmd = request.json person = cmd['person'] projects = [] categorize = [] valueDdata = {} for k, v in cmd['projects'].items(): projects.append(k) valueDdata.update({k: []}) categorize.append({'name': v, 'keyname': k}) batch = cmd['batch'] data = self.manager.get_individual_statistic( _id=str(person['id']), _type_list=projects, batch_list=batch ) batch_data = data['batch'] batch_avg = data['batch_avg'] maxScode = 0 minScore = 0 average = [] for i in batch_data.values(): for k, v in valueDdata.items(): valueDdata[k].append(i[k]['score']) if i[k]['score'] > maxScode: maxScode = i[k]['score'] remainder = maxScode % 10 maxScode = maxScode + (10 - remainder) if maxScode < 100: maxScode = 100 interval = maxScode / 5 for k, v in batch_avg.items(): average.append(v) response_data = { 'minScore': minScore, 'maxScore': maxScode, 'interval': interval, 'average': average, 'barData': { 'categorize': categorize, 'valueDdata': valueDdata } } return jsonify({STATUS: OK, DATA: response_data}) except Exception as e: print(traceback.format_exc()) error_msg = {STATUS: UNKNOWN_ERROR, ERROR_MESSAGE: "出现错误,请联系后端开发人员!错误原因:{}".format(e)} return jsonify(error_msg)