188 lines
7.4 KiB
TypeScript
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;
|
|
}
|
|
}
|
|
}
|
|
})();
|
|
}
|