api-amr/cli.ts
2025-06-04 19:15:02 +08:00

188 lines
7.4 KiB
TypeScript

import { DeviceManager } from "./device_manager.ts";
import { updateDeviceListFromConfig, removeDeviceFromWorker } from "./master_manager.ts";
// 处理设备管理命令
async function handleDeviceCommand(args: string[], masterWorker: Worker, instanceId: string) {
const deviceManager = new DeviceManager();
const subCommand = args[0];
try {
switch (subCommand) {
case "add":
if (args.length >= 3) {
await deviceManager.loadDevices();
const success = await deviceManager.addDevice(args[1], args[2]);
if (success) {
console.log("🔄 正在重新加载设备配置...");
// 读取配置文件并获取config对象
const configText = await Deno.readTextFile("./config.json");
const config = JSON.parse(configText);
await updateDeviceListFromConfig(masterWorker, config, instanceId);
}
} else {
console.log("用法: device add <manufacturer> <serialNumber>");
}
break;
case "remove":
if (args.length >= 3) {
await deviceManager.loadDevices();
const success = await deviceManager.removeDevice(args[1], args[2]);
if (success) {
console.log("🔄 正在重新加载设备配置...");
const configText = await Deno.readTextFile("./config.json");
const config = JSON.parse(configText);
await updateDeviceListFromConfig(masterWorker, config, instanceId);
}
} else {
console.log("用法: device remove <manufacturer> <serialNumber>");
}
break;
case "force-remove":
if (args.length >= 3) {
await deviceManager.loadDevices();
// 强制从配置文件中删除
await deviceManager.forceRemoveDevice(args[1], args[2]);
// 立即从Worker中移除
await removeDeviceFromWorker(masterWorker, args[1], args[2]);
console.log("✅ 设备已完全移除(配置文件 + 运行时状态)");
} else {
console.log("用法: device force-remove <manufacturer> <serialNumber>");
}
break;
case "instant-remove":
if (args.length >= 3) {
// 仅从运行时移除,不修改配置文件
await removeDeviceFromWorker(masterWorker, args[1], args[2]);
console.log("✅ 设备已从运行时移除(配置文件保持不变)");
} else {
console.log("用法: device instant-remove <manufacturer> <serialNumber>");
}
break;
case "list":
await deviceManager.loadDevices();
deviceManager.listDevices();
break;
case "status":
// 查询运行时设备状态
console.log("🔍 查询运行时设备状态...");
masterWorker.postMessage({ type: "discoverDevices" });
break;
case "reload":{
console.log("🔄 正在重新加载设备配置...");
const configText = await Deno.readTextFile("./config.json");
const config = JSON.parse(configText);
await updateDeviceListFromConfig(masterWorker, config, instanceId);
break;
}
case "generate":{
const count = parseInt(args[1]) || 10;
const prefix = args[2] || "TEST";
await deviceManager.loadDevices();
await deviceManager.generateTestDevices(count, prefix);
console.log("🔄 正在重新加载设备配置...");
const configText2 = await Deno.readTextFile("./config.json");
const config2 = JSON.parse(configText2);
await updateDeviceListFromConfig(masterWorker, config2, instanceId);
break;
}
default:
console.log(`
🔧 设备管理命令:
device add <manufacturer> <serialNumber> - 添加新设备
device remove <manufacturer> <serialNumber> - 删除设备(配置文件+重新加载)
device force-remove <manufacturer> <serialNumber> - 强制删除设备(配置文件+运行时)
device instant-remove <manufacturer> <serialNumber> - 即时删除设备(仅运行时)
device list - 列出所有设备
device status - 查询运行时设备状态
device reload - 重新加载设备配置
device generate <count> [prefix] - 生成测试设备
`);
}
} catch (error) {
console.error("❌ 设备命令执行失败:", error);
}
}
export function startCli(
masterWorker: Worker,
agvWorker: Worker,
sendNavigationOrder: () => void,
cancelOrder: (orderId: string) => void,
sendCustomCommand: (cmd: string) => void,
instanceId: string
) {
const decoder = new TextDecoder();
const reader = Deno.stdin.readable.getReader();
console.log("\n可用命令:");
console.log(" send - 发送新的导航订单");
console.log(" cancel <orderId> - 取消指定的订单");
console.log(" discover - 请求当前所有发现的设备信息");
console.log(" setcmd <command> - 发送自定义命令设置到 Worker");
console.log(" requestKV - 请求从 KV 中获取设备数据,并发送给 agvWorker");
console.log(" device add <manufacturer> <serialNumber> - 动态添加设备");
console.log(" device remove <manufacturer> <serialNumber> - 删除设备(配置+重载)");
console.log(" device force-remove <manufacturer> <serialNumber> - 强制删除设备");
console.log(" device instant-remove <manufacturer> <serialNumber> - 即时删除设备");
console.log(" device list - 列出所有配置的设备");
console.log(" device reload - 重新加载设备配置");
console.log(" device generate <count> [prefix] - 生成测试设备");
console.log(" exit - 退出程序");
(async () => {
let buffer = "";
while (true) {
const { value, done } = await reader.read();
if (done) break;
buffer += decoder.decode(value);
const lines = buffer.split("\n");
buffer = lines.pop() || "";
for (const line of lines) {
const trimmed = line.trim();
const [cmd, ...args] = trimmed.split(/\s+/);
switch (cmd) {
case "send":
sendNavigationOrder();
break;
case "cancel":
if (args[0]) cancelOrder(args[0]);
else console.log("请提供订单ID");
break;
case "discover":
masterWorker.postMessage({ type: "discoverDevices" });
break;
case "setcmd":
if (args.length) sendCustomCommand(args.join(" "));
else console.log("请提供自定义命令内容");
break;
case "requestKV":
agvWorker.postMessage({ type: "requestKVData" });
break;
case "device":
await handleDeviceCommand(args, masterWorker, instanceId);
break;
case "exit":
masterWorker.postMessage({ type: "shutdown" });
agvWorker.postMessage("shutdown");
setTimeout(() => {
agvWorker.terminate();
masterWorker.terminate();
console.log("所有 Worker 已终止,程序退出");
Deno.exit(0);
}, 2000);
return;
default:
if (trimmed) console.log(`未知命令: ${trimmed}`);
console.log("可用命令: send, cancel <orderId>, discover, setcmd <command>, requestKV, device <subcommand>, exit");
break;
}
}
}
})();
}