问题描述
我希望通过NodeJS定期向bluetoothctl
运行命令,并能够读取这些命令的输出。
例如,我想运行scan on
,并获取输出。以及运行devices
并阅读列表。可以解析它,但这不是字符串,但是我需要能够与bluetoothctl
程序进行交互。
问题在于,当您在终端中键入命令bluetoothctl
时,它会带您进入类似“管理器”的视图,我想Node无法从中读取数据?我错了吗?
我有点迷茫,找不到任何有用的东西。我找到了一些NodeJS蓝牙包装器,但是它们都比较旧,并且需要不推荐使用的node版本。
编辑
这是我到目前为止的代码。但是问题是我没有从运行的命令中获得预期的输出,而是得到了我调用过的命令的名称...
import * as cp from 'child_process';
async function sleep(ms) {
await new Promise(r => setTimeout(() => r(),ms));
return;
}
function log(m: string) {
console.log(`[${ShellyBluetoothScanner.name}] ${m}`);
}
export class ShellyBluetoothScanner {
bluetoothctl: cp.ChildProcessWithoutNullStreams;
constructor() {
this.setup();
}
async run() {
log('Running scan and devices list in 2s...');
await sleep(2000);
log('Enabling bluetooth');
this.bluetoothctl.stdin.write('power on');
await sleep(2000);
log('Claering devices');
this.bluetoothctl.stdin.write('remove *');
log('Scan devices for 3s');
this.bluetoothctl.stdin.write('scan on');
await sleep(3000);
log('Print devices');
this.bluetoothctl.stdin.write('devices');
}
private setup() {
log('INFO: Setting up bluetooth');
this.bluetoothctl = cp.spawn('bluetoothctl');
this.bluetoothctl.stdout.on('data',m => console.log('STDOUT Data - ',m.toString()));
this.bluetoothctl.stdout.on('error',error => console.log('STDOUT Error - ',error.message));
log('INFO: Bluetooth setup completed');
}
}
const SBTS = new ShellyBluetoothScanner();
SBTS.run();
解决方法
我不认为曾经打算以这种方式运行bluetoothctl
。它当然没有文档化的API,并且我已经看到该命令中的命令随着时间的推移巧妙地改变了,这会破坏您的脚本。
一种更好的方法是使用已记录并打算用于此用途的D-Bus API。
https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/doc/adapter-api.txt
https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/doc/device-api.txt
https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/doc/gatt-api.txt
在https://www.npmjs.com/package/dbus
有可用的绑定我确信也有可能有用的库。也许https://www.npmjs.com/package/node-ble