# -*- coding: utf-8 -*- """ 内置 Action 处理器实现 ───────────────────────────────────────────────────────────────── 每个处理函数签名: def handler(action: Action, ctx: ActionContext) -> Any 处理函数内部通过 ctx.emit_event() 产生一个或多个 Event 对象 ───────────────────────────────────────────────────────────────── """ import logging import random import time from uas.action.action_context import ActionContext from uas.action.action_model import Action from uas.event.event_model import make_event # 复用 Event 模块 from uas.event.event_type import EventType logger = logging.getLogger(__name__) # ───────────────────────────────────────────────────────────────── # 控制类 Action 处理器 # ───────────────────────────────────────────────────────────────── def handle_pause(action: Action, ctx: ActionContext) -> dict: """ 暂停处理器 产生事件:DEVICE_STATUS_CHANGED """ ctx.report_progress(10, "发送暂停指令...") time.sleep(0.1) # 模拟指令发送延迟 ctx.check_cancel() ctx.report_progress(80, "等待设备响应...") time.sleep(0.1) # 产生状态变更事件 ctx.emit_event(make_event( EventType.DEVICE_STATUS_CHANGED, source = action.source, message = f"设备已暂停", prev_state = "running", curr_state = "paused", action_id = action.action_id, )) ctx.report_progress(100, "暂停完成") logger.info(f"⏸ 暂停完成: {action.source}") return {"status": "paused", "device": action.source} def handle_resume(action: Action, ctx: ActionContext) -> dict: """ 继续处理器 产生事件:DEVICE_STATUS_CHANGED """ ctx.report_progress(20, "发送继续指令...") time.sleep(0.1) ctx.check_cancel() ctx.emit_event(make_event( EventType.DEVICE_STATUS_CHANGED, source = action.source, message = "设备已恢复运行", prev_state = "paused", curr_state = "running", action_id = action.action_id, )) ctx.report_progress(100, "继续完成") logger.info(f"▶️ 继续完成: {action.source}") return {"status": "running", "device": action.source} def handle_stop(action: Action, ctx: ActionContext) -> dict: """ 停止处理器 产生事件:DEVICE_STATUS_CHANGED + SYSTEM_WARNING(若强制停止) """ force = action.params.get("force", False) ctx.report_progress(10, "准备停止...") if force: # 强制停止:产生警告事件 ctx.emit_event(make_event( EventType.SYSTEM_WARNING, source = action.source, message = "强制停止指令已执行", level = "warning", )) ctx.report_progress(60, "执行停止序列...") time.sleep(0.2) ctx.check_cancel() ctx.emit_event(make_event( EventType.DEVICE_STATUS_CHANGED, source = action.source, message = "设备已停止", prev_state = "running", curr_state = "stopped", force = force, )) ctx.report_progress(100, "停止完成") logger.info(f"⏹ 停止完成: {action.source} force={force}") return {"status": "stopped", "force": force} def handle_reset(action: Action, ctx: ActionContext) -> dict: """ 重置处理器 产生事件:DEVICE_RESET + DEVICE_STATUS_CHANGED """ ctx.report_progress(10, "开始重置...") time.sleep(0.1) ctx.emit_event(make_event( EventType.DEVICE_RESET, source = action.source, message = "设备重置开始", )) ctx.report_progress(50, "重置中...") time.sleep(0.2) ctx.check_cancel() ctx.emit_event(make_event( EventType.DEVICE_STATUS_CHANGED, source = action.source, message = "设备重置完成", curr_state = "idle", )) ctx.report_progress(100, "重置完成") logger.info(f"🔄 重置完成: {action.source}") return {"status": "reset_done"} # ───────────────────────────────────────────────────────────────── # 感知类 Action 处理器 # ───────────────────────────────────────────────────────────────── def handle_capture_photo(action: Action, ctx: ActionContext) -> dict: """ 拍照处理器 产生事件:DEVICE_DATA_RECEIVED(含图像元数据) """ resolution = action.params.get("resolution", "1080P") fmt = action.params.get("format", "jpg") camera_id = action.source ctx.report_progress(20, f"初始化相机 {camera_id}...") time.sleep(0.05) ctx.check_cancel() ctx.report_progress(60, "曝光采集...") time.sleep(0.1) # 模拟图像数据 photo_meta = { "camera_id": camera_id, "resolution": resolution, "format": fmt, "file_path": f"/data/photos/{camera_id}_{int(time.time())}.{fmt}", "size_kb": random.randint(500, 5000), "exposure_ms": random.randint(10, 100), } # 产生数据到达事件 ctx.emit_event(make_event( EventType.DEVICE_DATA_RECEIVED, source = camera_id, message = f"拍照完成 [{resolution}]", data_type = "image", **photo_meta, )) ctx.report_progress(100, "拍照完成") logger.info(f"📷 拍照完成: {camera_id} {resolution} -> {photo_meta['file_path']}") return photo_meta def handle_recognize_target(action: Action, ctx: ActionContext) -> dict: """ 目标识别处理器 产生事件: - DEVICE_DATA_RECEIVED(识别结果) - EQUIPMENT_ALARM(若发现威胁目标) """ model = action.params.get("model", "yolov8") confidence = action.params.get("confidence", 0.85) image_path = action.params.get("image_path", "") ctx.report_progress(10, f"加载模型 {model}...") time.sleep(0.1) ctx.check_cancel() ctx.report_progress(40, "推理中...") time.sleep(0.2) ctx.check_cancel() # 模拟识别结果 targets = [ {"id": f"T{i:03d}", "label": random.choice(["aircraft", "vehicle", "person"]), "confidence": round(random.uniform(0.7, 0.99), 3), "bbox": [random.randint(0, 640) for _ in range(4)]} for i in range(random.randint(0, 3)) ] ctx.report_progress(80, f"发现 {len(targets)} 个目标...") # 产生识别结果事件 ctx.emit_event(make_event( EventType.DEVICE_DATA_RECEIVED, source = action.source, message = f"目标识别完成,发现 {len(targets)} 个目标", data_type = "recognition", model = model, targets = targets, image_path = image_path, )) # 若发现高威胁目标,额外产生告警事件 threat_targets = [t for t in targets if t["label"] == "aircraft" and t["confidence"] > 0.9] if threat_targets: ctx.emit_event(make_event( EventType.EQUIPMENT_ALARM, source = action.source, message = f"发现 {len(threat_targets)} 个高威胁目标!", level = "critical", targets = threat_targets, )) logger.warning(f"🚨 发现威胁目标: {threat_targets}") ctx.report_progress(100, "识别完成") logger.info(f"🎯 目标识别完成: {len(targets)} 个目标") return {"targets": targets, "model": model} def handle_scan_environment(action: Action, ctx: ActionContext) -> dict: """ 环境扫描处理器 产生事件:DEVICE_DATA_RECEIVED(扫描数据)+ DEVICE_WARNING(若发现异常) """ scan_range = action.params.get("range_m", 100) sensor = action.source ctx.report_progress(10, "初始化传感器...") time.sleep(0.05) scan_data = [] steps = 5 for i in range(steps): ctx.check_cancel() time.sleep(0.05) ctx.report_progress( int((i + 1) / steps * 80), f"扫描中 {int((i+1)/steps*100)}%..." ) scan_data.append({ "angle": i * (360 // steps), "distance": random.uniform(5, scan_range), "intensity": random.uniform(0.1, 1.0), }) # 产生扫描数据事件 ctx.emit_event(make_event( EventType.DEVICE_DATA_RECEIVED, source = sensor, message = f"环境扫描完成,范围 {scan_range}m", data_type = "lidar_scan", points = len(scan_data), scan_data = scan_data, )) # 检测到近距离障碍物 close_obstacles = [d for d in scan_data if d["distance"] < 10] if close_obstacles: ctx.emit_event(make_event( EventType.DEVICE_WARNING, source = sensor, message = f"检测到 {len(close_obstacles)} 个近距离障碍物", obstacles = close_obstacles, )) ctx.report_progress(100, "扫描完成") return {"scan_points": len(scan_data), "range_m": scan_range} # ───────────────────────────────────────────────────────────────── # 系统类 Action 处理器 # ───────────────────────────────────────────────────────────────── def handle_system_diagnose(action: Action, ctx: ActionContext) -> dict: """ 系统诊断处理器 产生事件:SYSTEM_WARNING(若发现问题)或 DEVICE_STATUS_CHANGED """ checks = ["CPU", "内存", "存储", "网络", "传感器"] results = {} for i, check in enumerate(checks): ctx.check_cancel() time.sleep(0.05) ctx.report_progress(int((i + 1) / len(checks) * 90), f"检查 {check}...") status = random.choice(["normal", "normal", "normal", "warning"]) results[check] = status if status == "warning": ctx.emit_event(make_event( EventType.SYSTEM_WARNING, source = action.source, message = f"诊断发现 {check} 异常", component = check, level = "warning", )) # 产生诊断完成事件 ctx.emit_event(make_event( EventType.DEVICE_STATUS_CHANGED, source = action.source, message = "系统诊断完成", curr_state = "diagnosed", results = results, )) ctx.report_progress(100, "诊断完成") warnings = [k for k, v in results.items() if v == "warning"] logger.info(f"🔧 系统诊断完成: {results} warnings={warnings}") return {"results": results, "warnings": warnings} def handle_system_calibrate(action: Action, ctx: ActionContext) -> dict: """ 设备校准处理器 产生事件:DEVICE_CALIBRATED """ sensor_ids = action.params.get("sensors", ["all"]) ctx.report_progress(10, "开始校准...") for i, sid in enumerate(sensor_ids): ctx.check_cancel() time.sleep(0.1) ctx.report_progress( int((i + 1) / len(sensor_ids) * 90), f"校准传感器 {sid}..." ) ctx.emit_event(make_event( EventType.DEVICE_CALIBRATED, source = action.source, message = f"校准完成,传感器: {sensor_ids}", sensors = sensor_ids, accuracy = round(random.uniform(0.95, 0.999), 4), )) ctx.report_progress(100, "校准完成") logger.info(f"📐 校准完成: {action.source} sensors={sensor_ids}") return {"calibrated": sensor_ids} # ───────────────────────────────────────────────────────────────── # 处理器映射表(供 ActionRegistry 使用) # ───────────────────────────────────────────────────────────────── from uas.action.action_type import ActionType BUILTIN_HANDLERS = { ActionType.PAUSE: handle_pause, ActionType.RESUME: handle_resume, ActionType.STOP: handle_stop, ActionType.RESET: handle_reset, ActionType.CAPTURE_PHOTO: handle_capture_photo, ActionType.RECOGNIZE_TARGET: handle_recognize_target, ActionType.SCAN_ENVIRONMENT: handle_scan_environment, ActionType.SYSTEM_DIAGNOSE: handle_system_diagnose, ActionType.SYSTEM_CALIBRATE: handle_system_calibrate, }