279 lines
7.6 KiB
TypeScript
279 lines
7.6 KiB
TypeScript
// device_manager.ts - 动态设备管理工具
|
||
|
||
interface DeviceConfig {
|
||
manufacturer: string;
|
||
serialNumber: string;
|
||
}
|
||
|
||
export class DeviceManager {
|
||
private devicesFilePath: string;
|
||
private devices: DeviceConfig[] = [];
|
||
|
||
constructor(devicesFilePath = "./devices.json") {
|
||
this.devicesFilePath = devicesFilePath;
|
||
}
|
||
|
||
/**
|
||
* 加载现有设备列表
|
||
*/
|
||
async loadDevices(): Promise<DeviceConfig[]> {
|
||
try {
|
||
const text = await Deno.readTextFile(this.devicesFilePath);
|
||
this.devices = JSON.parse(text);
|
||
console.log(`📱 已加载 ${this.devices.length} 个设备`);
|
||
return this.devices;
|
||
} catch (error) {
|
||
if (error instanceof Deno.errors.NotFound) {
|
||
console.log("📄 devices.json 不存在,创建新文件");
|
||
this.devices = [];
|
||
await this.saveDevices();
|
||
return this.devices;
|
||
}
|
||
throw error;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 保存设备列表到文件
|
||
*/
|
||
async saveDevices(): Promise<void> {
|
||
const json = JSON.stringify(this.devices, null, 2);
|
||
await Deno.writeTextFile(this.devicesFilePath, json);
|
||
console.log(`💾 已保存 ${this.devices.length} 个设备到 ${this.devicesFilePath}`);
|
||
}
|
||
|
||
/**
|
||
* 添加新设备
|
||
*/
|
||
async addDevice(manufacturer: string, serialNumber: string): Promise<boolean> {
|
||
const deviceKey = `${manufacturer}-${serialNumber}`;
|
||
const exists = this.devices.some(d =>
|
||
d.manufacturer === manufacturer && d.serialNumber === serialNumber
|
||
);
|
||
|
||
if (exists) {
|
||
console.log(`⚠️ 设备 ${deviceKey} 已存在`);
|
||
return false;
|
||
}
|
||
|
||
this.devices.push({ manufacturer, serialNumber });
|
||
await this.saveDevices();
|
||
console.log(`➕ 已添加设备: ${deviceKey}`);
|
||
return true;
|
||
}
|
||
|
||
/**
|
||
* 批量添加设备
|
||
*/
|
||
async addDevices(newDevices: DeviceConfig[]): Promise<number> {
|
||
let addedCount = 0;
|
||
|
||
for (const device of newDevices) {
|
||
const exists = this.devices.some(d =>
|
||
d.manufacturer === device.manufacturer && d.serialNumber === device.serialNumber
|
||
);
|
||
|
||
if (!exists) {
|
||
this.devices.push(device);
|
||
addedCount++;
|
||
console.log(`➕ 已添加设备: ${device.manufacturer}-${device.serialNumber}`);
|
||
} else {
|
||
console.log(`⚠️ 设备 ${device.manufacturer}-${device.serialNumber} 已存在,跳过`);
|
||
}
|
||
}
|
||
|
||
if (addedCount > 0) {
|
||
await this.saveDevices();
|
||
}
|
||
|
||
console.log(`✅ 批量添加完成: 新增 ${addedCount} 个设备`);
|
||
return addedCount;
|
||
}
|
||
|
||
/**
|
||
* 删除设备
|
||
*/
|
||
async removeDevice(manufacturer: string, serialNumber: string): Promise<boolean> {
|
||
const deviceKey = `${manufacturer}-${serialNumber}`;
|
||
const initialLength = this.devices.length;
|
||
|
||
this.devices = this.devices.filter(d =>
|
||
!(d.manufacturer === manufacturer && d.serialNumber === serialNumber)
|
||
);
|
||
|
||
if (this.devices.length < initialLength) {
|
||
await this.saveDevices();
|
||
console.log(`➖ 已删除设备: ${deviceKey}`);
|
||
return true;
|
||
} else {
|
||
console.log(`⚠️ 设备 ${deviceKey} 不存在`);
|
||
return false;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 强制删除设备(即使配置文件中不存在)
|
||
*/
|
||
async forceRemoveDevice(manufacturer: string, serialNumber: string): Promise<boolean> {
|
||
const deviceKey = `${manufacturer}-${serialNumber}`;
|
||
const initialLength = this.devices.length;
|
||
|
||
// 从内存中移除
|
||
this.devices = this.devices.filter(d =>
|
||
!(d.manufacturer === manufacturer && d.serialNumber === serialNumber)
|
||
);
|
||
|
||
// 总是保存文件,确保一致性
|
||
await this.saveDevices();
|
||
|
||
if (this.devices.length < initialLength) {
|
||
console.log(`🗑️ 已强制删除设备: ${deviceKey}`);
|
||
} else {
|
||
console.log(`🗑️ 强制删除设备: ${deviceKey} (配置文件中不存在,但已清理运行时状态)`);
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
/**
|
||
* 列出所有设备
|
||
*/
|
||
listDevices(): DeviceConfig[] {
|
||
console.log(`📋 当前设备列表 (${this.devices.length} 个):`);
|
||
this.devices.forEach((device, index) => {
|
||
console.log(` ${index + 1}. ${device.manufacturer}/${device.serialNumber}`);
|
||
});
|
||
return this.devices;
|
||
}
|
||
|
||
/**
|
||
* 清空所有设备
|
||
*/
|
||
async clearDevices(): Promise<void> {
|
||
this.devices = [];
|
||
await this.saveDevices();
|
||
console.log("🗑️ 已清空所有设备");
|
||
}
|
||
|
||
/**
|
||
* 生成测试设备
|
||
*/
|
||
async generateTestDevices(count: number, prefix = "TEST"): Promise<void> {
|
||
const testDevices: DeviceConfig[] = [];
|
||
|
||
for (let i = 0; i < count; i++) {
|
||
testDevices.push({
|
||
manufacturer: "SEER",
|
||
serialNumber: `${prefix}-${i}`
|
||
});
|
||
}
|
||
|
||
await this.addDevices(testDevices);
|
||
console.log(`🧪 已生成 ${count} 个测试设备`);
|
||
}
|
||
|
||
/**
|
||
* 检查设备是否存在
|
||
*/
|
||
deviceExists(manufacturer: string, serialNumber: string): boolean {
|
||
return this.devices.some(d =>
|
||
d.manufacturer === manufacturer && d.serialNumber === serialNumber
|
||
);
|
||
}
|
||
|
||
/**
|
||
* 获取设备数量
|
||
*/
|
||
getDeviceCount(): number {
|
||
return this.devices.length;
|
||
}
|
||
}
|
||
|
||
// 导出便捷函数
|
||
export async function addDeviceToConfig(manufacturer: string, serialNumber: string): Promise<boolean> {
|
||
const manager = new DeviceManager();
|
||
await manager.loadDevices();
|
||
return await manager.addDevice(manufacturer, serialNumber);
|
||
}
|
||
|
||
export async function removeDeviceFromConfig(manufacturer: string, serialNumber: string): Promise<boolean> {
|
||
const manager = new DeviceManager();
|
||
await manager.loadDevices();
|
||
return await manager.removeDevice(manufacturer, serialNumber);
|
||
}
|
||
|
||
export async function listConfigDevices(): Promise<DeviceConfig[]> {
|
||
const manager = new DeviceManager();
|
||
await manager.loadDevices();
|
||
return manager.listDevices();
|
||
}
|
||
|
||
// CLI 使用示例
|
||
if (import.meta.main) {
|
||
const manager = new DeviceManager();
|
||
await manager.loadDevices();
|
||
|
||
const args = Deno.args;
|
||
const command = args[0];
|
||
|
||
switch (command) {
|
||
case "add":
|
||
if (args.length >= 3) {
|
||
await manager.addDevice(args[1], args[2]);
|
||
} else {
|
||
console.log("用法: deno run device_manager.ts add <manufacturer> <serialNumber>");
|
||
}
|
||
break;
|
||
|
||
case "remove":
|
||
if (args.length >= 3) {
|
||
await manager.removeDevice(args[1], args[2]);
|
||
} else {
|
||
console.log("用法: deno run device_manager.ts remove <manufacturer> <serialNumber>");
|
||
}
|
||
break;
|
||
|
||
case "force-remove":
|
||
if (args.length >= 3) {
|
||
await manager.forceRemoveDevice(args[1], args[2]);
|
||
} else {
|
||
console.log("用法: deno run device_manager.ts force-remove <manufacturer> <serialNumber>");
|
||
}
|
||
break;
|
||
|
||
case "list":
|
||
manager.listDevices();
|
||
break;
|
||
|
||
case "clear":
|
||
await manager.clearDevices();
|
||
break;
|
||
|
||
case "generate":
|
||
const count = parseInt(args[1]) || 10;
|
||
const prefix = args[2] || "TEST";
|
||
await manager.generateTestDevices(count, prefix);
|
||
break;
|
||
|
||
default:
|
||
console.log(`
|
||
🔧 设备管理工具
|
||
|
||
用法:
|
||
deno run --allow-read --allow-write device_manager.ts <command> [args]
|
||
|
||
命令:
|
||
add <manufacturer> <serialNumber> - 添加设备
|
||
remove <manufacturer> <serialNumber> - 删除设备
|
||
force-remove <manufacturer> <serialNumber> - 强制删除设备
|
||
list - 列出所有设备
|
||
clear - 清空所有设备
|
||
generate <count> [prefix] - 生成测试设备
|
||
|
||
示例:
|
||
deno run --allow-read --allow-write device_manager.ts add SEER AGV-001
|
||
deno run --allow-read --allow-write device_manager.ts list
|
||
deno run --allow-read --allow-write device_manager.ts generate 5 TEST
|
||
`);
|
||
}
|
||
}
|