# 这是一个示例 Python 脚本。 import json import os # 按 Shift+F10 执行或将其替换为您的代码。 # 按 双击 Shift 在所有地方搜索类、文件、工具窗口、操作和设置。 import SimpleView_SaveImage as simple import config import image import time # 在文件顶部导入 time 模块 from flask import Flask, jsonify, request from logConfig import get_logger app = Flask(__name__) import concurrent.futures from functools import partial # 使用示例 logger = get_logger() # 示例接口:GET 请求 @app.route("/config/update") def home(): logger.info("配置更新请求") config.load_configs() logger.info("配置更新完成") return {"message": "Hello, this service config update!", "status": "OK"} @app.route("/api/addTemplate", methods=["POST"]) def save_template(): logger.info("接收到添加模板请求") data = request.get_json() # 验证必要字段 if not data: logger.error("添加模板失败:未提供数据") return jsonify({"status": "ERROR", "message": "No data provided"}), 400 template_type = data.get("type") if not template_type: logger.error("添加模板失败:缺少'type'字段") return jsonify({"status": "ERROR", "message": "Missing 'type' field"}), 400 CONFIG_DIR = "./config/template" # 构造文件路径 filename = f"{template_type}.json" file_path = os.path.join(CONFIG_DIR, filename) # 写入文件 try: with open(file_path, "w", encoding="utf-8") as f: json.dump(data, f, ensure_ascii=False, indent=4) config.load_configs() logger.info(f"模板 '{template_type}' 保存成功") return jsonify({"status": "OK", "message": f"Template '{template_type}' saved successfully."}), 200 except Exception as e: logger.error(f"保存模板失败: {str(e)}") return jsonify({"status": "ERROR", "message": f"Failed to save template: {str(e)}"}), 500 @app.route("/api/initDevice", methods=['POST']) def initDevice(): logger.info("设备初始化请求") simple.initialize_devices() logger.info("设备初始化完成") # # @app.route("/api/picComputeAll", methods=['POST']) # def picComputeAll(): # logger.info("接收到全设备图片计算请求") # start_time_total = time.time() # # # 输入参数 # # sn:设备编号 # # type:类型 # # # 获取 JSON 数据 # data = request.get_json() # type = data['type'] # template = config.TEMPLATE_CONFIG_MAP.get(type) # if not template: # logger.error("缺少模板配置: 'type'") # return jsonify({ # "message": "", # "status": "ERROR", # "error": "Missing required parameter: 'type'" # }), 400 # all_sn_list = list(config.CAMERA_CONFIG_MAP.keys()) # # # 遍历每个 sn 并判断是否都有 hole # all_have_holes = False # color_list = [] # 新增:用于保存所有 sn 的 color # # count_assemble = 0 # for sn in all_sn_list: # start_time = time.time() # 开始计时 # logger.info(f"开始处理设备 {sn} 的图片计算") # pic_info = simple.enhanced_pic(sn, type) # points = pic_info.get("point") # if points is None: # logger.warning(f"设备 {sn} 未返回点云数据") # all_have_holes = True # break # # # 提取 color 并加入列表 # color = pic_info.get("color") # if color is not None: # color_list.append(color) # # try: # real_holes, count = image.detect_large_holes(points, sn, type) # # count_assemble += count # # if len(real_holes) != 0: # all_have_holes = True # # 计算耗时 # elapsed_time = round(time.time() - start_time, 3) # # 输出日志 # logger.info(f"[INFO] picComputeAll executed in {elapsed_time} seconds {sn}") # break # 判断到空洞就直接退出 # except Exception as e: # all_have_holes = True # logger.error(f"Failed to process request: {str(e)} sn:{sn}") # # # 计算总耗时 # total_elapsed_time = round(time.time() - start_time_total, 3) # logger.info(f"全设备图片计算完成,总耗时 {total_elapsed_time} 秒,结果: {all_have_holes}") # # # 返回结果中包含 color 列表 # return jsonify({ # "message": all_have_holes, # "lack": all_have_holes, # "type": type, # "count": count_assemble, # "colors": color_list, # 添加 color 列表 # "status": "OK" # }) # @app.route("/api/picComputeAll", methods=['POST']) def picComputeAll(): logger.info("接收到全设备图片计算请求") start_time_total = time.time() # 获取 JSON 数据 data = request.get_json() type = data['type'] template = config.TEMPLATE_CONFIG_MAP.get(type) if not template: logger.error("缺少模板配置: 'type'") return jsonify({ "message": "", "status": "ERROR", "error": "Missing required parameter: 'type'" }), 400 all_sn_list = list(config.CAMERA_CONFIG_MAP.keys()) # 同步处理每个设备 all_have_holes = False color_list = [] count_assemble = 0 # 逐个同步处理设备 for sn in all_sn_list: try: start_time = time.time() logger.info(f"开始处理设备 {sn} 的图片计算") # 同步采集图片信息 pic_info = simple.enhanced_pic(sn, type) points = pic_info.get("point") if points is None: logger.warning(f"设备 {sn} 未返回点云数据") all_have_holes = True break # 提取 color 并加入列表 if pic_info.get("color") is not None: color_list.append(pic_info["color"]) # 检测空洞 real_holes, count = image.detect_large_holes(points, sn, type) elapsed_time = round(time.time() - start_time, 3) logger.info(f"设备 {sn} 处理完成,耗时 {elapsed_time} 秒,发现空洞: {len(real_holes) != 0}") # 检查是否发现空洞 if len(real_holes) != 0: all_have_holes = True count_assemble += count logger.info(f"设备 {sn} 发现空洞,停止其他任务") break # 发现空洞就直接退出 except Exception as e: logger.error(f"处理设备 {sn} 时发生异常: {str(e)}") all_have_holes = True break # 计算总耗时 total_elapsed_time = round(time.time() - start_time_total, 3) logger.info(f"全设备图片计算完成,总耗时 {total_elapsed_time} 秒,结果: {all_have_holes}") # 返回结果中包含 color 列表 return jsonify({ "message": all_have_holes, "lack": all_have_holes, "type": type, "count": count_assemble, "colors": color_list, "status": "OK" }) @app.route("/api/picBitCloudy", methods=['POST']) def picBitCloudy(): logger.info("接收到picBitCloudy请求") # 输入参数 # sn:设备编号 # type:类型 # 获取 JSON 数据 data = request.get_json() direction = data.get('direction') type = data.get('type') all_sn_list = list(config.CAMERA_CONFIG_MAP.keys()) # 遍历每个 sn 并判断是否都有 hole all_have_holes = False color_list = [] # 新增:用于保存所有 sn 的 color count_assemble = 0 for sn in all_sn_list: if direction and config.CAMERA_CONFIG_MAP[sn].get("direction") != direction: logger.debug(f"设备 {sn} 方向不匹配,跳过") continue start_time = time.time() # 开始计时 logger.info(f"开始处理设备 {sn} 的图片计算") pic_info = simple.enhanced_pic(sn, type) points = pic_info.get("point") if points is None or len(points) < 300: logger.warning(f"设备 {sn} 点云数据不足") all_have_holes = True break # 提取 color 并加入列表 color = pic_info.get("color") if color is not None: color_list.append(color) logger.info(f"picBitCloudy处理完成,结果: {all_have_holes}") # 返回结果中包含 color 列表 return jsonify({ "message": all_have_holes, "lack": all_have_holes, "colors": color_list, # 添加 color 列表 "status": "OK" }) @app.route("/api/picCompute", methods=['POST']) def picCompute(): logger.info("接收到单设备图片计算请求") # 输入参数 # sn:设备编号 # type:类型 try: # 获取 JSON 数据 data = request.get_json() if not data or 'sn' not in data: logger.error("缺少必需参数: 'sn'") return jsonify({ "message": "", "status": "ERROR", "error": "Missing required parameter: 'sn'" }), 400 sn = data['sn'] type = data['type'] logger.info(f"开始处理设备 {sn} 类型 {type} 的图片计算") template = config.TEMPLATE_CONFIG_MAP.get(type) if not template: logger.error(f"缺少模板配置: {type}") return jsonify({ "message": "", "status": "ERROR", "error": "Missing required parameter: 'type'" }), 400 pic_info = simple.enhanced_pic(sn, type) real_holes, count = image.detect_large_holes(pic_info["point"], sn, type) result = len(real_holes) != 0 logger.info(f"设备 {sn} 图片计算完成,检测到空洞: {result}") return jsonify({"message": result, "lack": result, "status": "OK"}) except Exception as e: logger.error(f"图片计算失败: {str(e)}") return jsonify({"message": "", "status": "ERROR", "error": f"Failed to get TIFF paths: {str(e)}"}), 500 return jsonify({"message": True, "lack": True, "status": "OK"}) @app.errorhandler(Exception) def handle_exception(e): # 处理所有未被捕获的异常 logger.error(f"未捕获的异常: {str(e)}") return jsonify({ "message": "", "status": "ERROR", "error": str(e) }), 500 if __name__ == "__main__": from waitress import serve logger.info("服务启动中...") print("Serving on http://0.0.0.0:5000") logger.info("服务启动成功,监听地址: http://0.0.0.0:5000") serve(app, host='0.0.0.0', port=5000)