LISHUZUOXUN_yangjiang/PureBackend/synchronization.py

563 lines
26 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 代码编写人:曾忠和
# 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