// main.ts /// // 导入 UUID 库(请根据实际情况调整URL) import { v4 as uuidv4 } from "npm:uuid"; import { setupAgvWorker, initAgvWorker } from "./agv_manager.ts"; import { reconnectAllWorker, setupMasterWorker, updateDeviceListFromConfig } from "./master_manager.ts"; import { globalEventManager } from "./event_manager.ts"; // Load config and mappings from JSON files at runtime const configText = await Deno.readTextFile("./config.json"); const config = JSON.parse(configText); const mappingFile = config.mappingFile || "mapping.json"; const mappingsText = await Deno.readTextFile(`./${mappingFile}`); const mappings = JSON.parse(mappingsText); // Generate a unique instance ID from manufacturer and UUID const instanceId = uuidv4(); // 添加全局事件监听器 globalEventManager.addEventListener("reconnect-all", (event: Event) => { const customEvent = event as CustomEvent; console.log("🎯 主线程收到全局重连事件:", customEvent.detail); handleReconnectAll(); }); globalEventManager.addEventListener("grpc-connection-lost", (event: Event) => { const customEvent = event as CustomEvent; console.log("🎯 主线程收到 gRPC 连接丢失事件:", customEvent.detail); // 可以添加特殊的 gRPC 重连逻辑 }); globalEventManager.addEventListener("device-status-update", (event: Event) => { const customEvent = event as CustomEvent; console.log("🎯 主线程收到设备状态更新事件:", customEvent.detail.data); }); // 重连处理函数 function handleReconnectAll() { console.log("agv_main: 执行全局重连"); reconnectAllWorker(kv, webWorker, masterWorker, agvWorker, config, mappings, instanceId); } // 初始化 downWorker 并支持自身重启 let downWorker: Worker; function startDownWorker() { console.log("agv_main: 启动 downWorker"); downWorker = new Worker( new URL("./vda5050_transformer_worker.ts", import.meta.url).href, { type: "module" } ); // 注册到全局事件管理器 globalEventManager.registerWorker("downWorker", downWorker); // 初始化 downWorker downWorker.postMessage({ type: "init", mqtt: config.mqtt, mappings, instanceId }); // 监听重启请求 downWorker.onmessage = (event: MessageEvent) => { const message = event.data; // 只处理非全局事件相关的消息 if (message.type === "reconnect-all" && message.type !== "dispatchGlobalEvent") { console.log("agv_main: 收到 downWorker reconnect-all,重启所有 Workers"); handleReconnectAll(); } else if (message.type === "reconnect-down") { console.log("agv_main: 收到 downWorker reconnect-down,重启 downWorker"); downWorker.postMessage({ type: "stop" }); downWorker.terminate(); startDownWorker(); } }; } startDownWorker(); // 打开 Deno KV 数据库(Deno KV 在最新版本中为内置特性) const kv = await Deno.openKv(); // // 启动 Web Worker 用于可视化界面 const webWorker = new Worker( new URL("./web_worker.ts", import.meta.url).href, { type: "module" } ); console.log("Web Worker 已启动"); const masterWorker = new Worker( new URL("./vda_worker.ts", import.meta.url).href, { type: "module" } ); const agvWorker = new Worker( new URL("./agv_worker.ts", import.meta.url).href, { type: "module" } ); // 注册所有 Worker 到全局事件管理器 globalEventManager.registerWorker("webWorker", webWorker); globalEventManager.registerWorker("masterWorker", masterWorker); globalEventManager.registerWorker("agvWorker", agvWorker); reconnectAllWorker(kv, webWorker, masterWorker, agvWorker, config, mappings, instanceId); // 监听配置文件变化,动态更新设备列表 const watcher = Deno.watchFs("./devices.json"); (async () => { console.log("开始监控配置文件变化..."); for await (const event of watcher) { if (event.paths.some((p) => p.endsWith("devices.json"))) { console.log("检测到设备配置文件变化,更新设备列表..."); await updateDeviceListFromConfig(masterWorker, config, instanceId); } } })(); // 处理 Ctrl+C(SIGINT)退出 Deno.addSignalListener("SIGINT", () => { console.log("接收到 Ctrl+C,主程序通知 Worker 退出..."); // 向所有 Worker 发送 shutdown 消息 agvWorker.postMessage("shutdown"); masterWorker.postMessage({ type: "shutdown" }); webWorker.postMessage({ type: "shutdown" }); // 通知 downWorker 关闭 downWorker.postMessage({ type: "shutdown" }); // 延时后终止 Worker 并退出主程序 setTimeout(() => { agvWorker.terminate(); masterWorker.terminate(); webWorker.terminate(); downWorker.terminate(); console.log("所有 Worker 已终止,程序退出"); Deno.exit(0); }, 2000); }); // Web Worker 错误处理 webWorker.onerror = (error) => { console.error("Web Worker 执行错误:", error); }; // 发送导航订单的函数(示例订单) function sendNavigationOrder() { // 使用 UUID v4 生成订单号 const orderId = uuidv4(); console.log(`创建新的导航订单 ${orderId}`); masterWorker.postMessage({ type: "sendOrder", orderId: orderId, nodes: [ { nodeId: "start", nodePosition: { x: 0.0, y: 0.0, mapId: "warehouse", theta: 0, }, actions: [], }, { nodeId: "waypoint1", nodePosition: { x: 5.0, y: 0.0, mapId: "warehouse", theta: 0, }, actions: [], }, { nodeId: "destination", nodePosition: { x: 10.0, y: 5.0, mapId: "warehouse", theta: 0, }, actions: [], }, ], }); } // 取消订单的函数 function cancelOrder(orderId: string) { console.log(`取消订单 ${orderId}`); masterWorker.postMessage({ type: "cancelOrder", orderId: orderId, }); } // 发送自定义命令设置给 Worker 的函数 function sendCustomCommand(cmd: string) { console.log(`发送自定义命令设置: ${cmd}`); masterWorker.postMessage({ type: "setCommand", command: cmd, }); } // CLI moved to cli.ts import { startCli } from "./cli.ts"; startCli(masterWorker, agvWorker, sendNavigationOrder, cancelOrder, sendCustomCommand, instanceId); console.log("VDA 5050 控制程序已启动,输入命令或按 Ctrl+C 退出程序");