一个Node.js BLE(蓝牙低能)中央模块.
想要执行一个外围? 检查出来 布尔诺。 。 。 .
说明: macOS / Mac OS X,Linux,FreeBSD和Windows是目前唯一被支持的OS.
文档
快速启动示例
// Read the battery level of the first found peripheral exposing the Battery Level characteristic
const noble = require('@abandonware/noble');
noble.on('stateChange', async (state) => {
if (state === 'poweredOn') {
await noble.startScanningAsync(['180f'], false);
}
});
noble.on('discover', async (peripheral) => {
await noble.stopScanningAsync();
await peripheral.connectAsync();
const {characteristics} = await peripheral.discoverSomeServicesAndCharacteristicsAsync(['180f'], ['2a19']);
const batteryLevel = (await characteristics[0].readAsync())[0];
console.log(`${peripheral.address} (${peripheral.advertisement.localName}): ${batteryLevel}%`);
await peripheral.disconnectAsync();
process.exit(0);
});
使用高贵的 BLE5 扩展特性
const noble = require('@abandonware/noble/with-custom-binding')({extended: true});
安装
先决条件
操作系统X
链接
- 3.6或以上内核版本
libbluetooth-dev需要安装。 关于具体分发的指示,见下文.- 设置必要的权限 运行没有sudo, 参见本节。所有分销(Raspbian、Ubuntu、Fedora等)都需要这样做。 如果运行时没有sudo, 就不会出任何错误, 但不会发生任何事 .
乌本图、德比安、拉斯比安
见 以上通用 Linux 注释 先说.
sudo apt-get install bluetooth bluez libbluetooth-dev libudev-dev
确保 node 交给你了 PATH如果不是,一些选项:
- 共线
nodejs改为node数字 :sudo ln -s /usr/bin/nodejs /usr/bin/node - 使用节点源码包安装节点.js
如果你在Raspberry Pi上无法连接到 BLE 设备,你应该禁用 pnat 插件 。 在底部添加下行 /etc/bluetooth/main.conf数字 :
DisablePlugins=pnat
然后重新启动系统.
见 · OpenWonderLabs/家用桥接接接器。 。 。 .
Fedora 和其他基于 RPM 的分布
见 以上通用 Linux 注释 先说.
sudo yum install bluez bluez-libs bluez-libs-devel
爱迪生情报
见 以上通用 Linux 注释 先说.
见 为 Bluetooth LE (Smart) 开发配置信息爱迪生。 。 。 .
免费BSD
确保您有 GNU Make :
sudo pkg install gmake
禁用默认蓝牙堆栈的自动加载 无怀疑.conf 输入 /usr/local/etc/devd/no-ubt.conf 并重新启动devd(sudo service devd restart) (中文(简体) ).
卸载 ng_ubt 如果已装入内核模块 :
sudo kldunload ng_ubt
请确认您已读取和写入权限 /dev/usb/* 与您的蓝牙适配器对应的设备.
窗口
使用 Microsoft 安装所需的工具和配置 窗口建设工具 从高级的 PowerShell 或 cmd.exe (以管理员身份运行) .
npm install --global --production windows-build-tools
- 相容蓝牙 5.0 Zephyr HCI-USB适配器(需要将 BLUETOOTH HCI SOCKET USB VID 和 BLUETOOTH HCI SOCKET USB PID 添加到进程内)
- 兼容蓝牙 4.0 USB 适配器
- 温USB 蓝牙 4. 0 USB 适配器的驱动程序设置,使用 Zadig 工具
见 @don (英语)设置指南 蓝牙 LE 有节点.js和Windows上的Noble
夹克
确保你的容器运行 --network=host 选项和所有特定环境的前提都经过核查.
安装和使用软件包
npm install @abandonware/noble
在 Windows OS 中,将您的自定义 hci- usb dongle 添加到进程内
set BLUETOOTH_HCI_SOCKET_USB_VID=xxx
set BLUETOOTH_HCI_SOCKET_USB_PID=xxx
const noble = require('@abandonware/noble');
API 文件
所有操作都有两种API的变体,一种是等待回调,一种是返回承诺(注意: Async 后缀).
此外,还有与每项行动相适应的事件(以及一些全球事件).
例如,对于周边的"发现服务"操作:
- 有一个
discoverServices需要召回的方法 :peripheral.discoverServices((error, services) => { // callback - handle error and services }); - 有一个
discoverServicesAsync返回承诺的方法 :try { const services = await peripheral.discoverServicesAsync(); // handle services } catch (e) { // handle error } - 有一个
servicesDiscover发现服务后释放出的事件 :peripheral.once('servicesDiscover', (services) => { // handle services });
API 结构 :
扫描和发现
事件: 适应器状态已更改
noble.on('stateChange', callback(state));
state 可以是:
unknownresettingunsupportedunauthorizedpoweredOffpoweredOn
开始扫描
noble.startScanning(); // any service UUID, no duplicates
noble.startScanning([], true); // any service UUID, allow duplicates
var serviceUUIDs = ['<service UUID 1>', ...]; // default: [] => all
var allowDuplicates = falseOrTrue; // default: false
noble.startScanning(serviceUUIDs, allowDuplicates[, callback(error)]); // particular UUIDs
注: noble.state 必须是 poweredOn 在扫描开始前. noble.on('stateChange', callback(state)); 可用于收听州变事件.
事件: 开始扫描
noble.on('scanStart', callback);
活动于下列时间发布:
- 扫描开始
- 另一个应用程序允许扫描
- 另一个应用程序更改了扫描设置
停止扫描
noble.stopScanning();
事件: 扫描已停止
noble.on('scanStop', callback);
活动于下列时间发布:
- 扫描已停止
- 另一个应用程序停止扫描
事件:发现地外
noble.on('discover', callback(peripheral));
peripheral数字 :{ id: '<id>', address: '<BT address'>, // Bluetooth Address of device, or 'unknown' if not known addressType: '<BT address type>', // Bluetooth Address type (public, random), or 'unknown' if not known connectable: trueOrFalseOrUndefined, // true or false, or undefined if not known advertisement: { localName: '<name>', txPowerLevel: someInteger, serviceUuids: ['<service UUID>', ...], serviceSolicitationUuid: ['<service solicitation UUID>', ...], manufacturerData: someBuffer, // a Buffer serviceData: [ { uuid: '<service UUID>', data: someBuffer // a Buffer }, // ... ] }, rssi: integerValue, mtu: integerValue // MTU will be null, until device is connected and hci-socket is used };
说明: 在 macOS 上, 如果设备之前没有连接, 地址将被设置为 “ ” .
事件:提出警告
noble.on('warning', callback(message));
重置设备
noble.reset()
周边
连接
peripheral.connect([callback(error)]);
有的蓝牙设备没有无缝连接,可能是因为蓝牙设备固件或内核. 在连接 API 之前, 请用 al. reset () API 重置设备 .
事件:已连接
peripheral.once('connect', callback);
取消待定的连接
peripheral.cancelConnect();
// Will emit a 'connect' event with error
断开连接
peripheral.disconnect([callback(error)]);
事件: 断开
peripheral.once('disconnect', callback);
更新 RSSI
peripheral.updateRssi([callback(error, rssi)]);
活动:更新RSSI
peripheral.once('rssiUpdate', callback(rssi));
发现服务
peripheral.discoverServices(); // any service UUID
var serviceUUIDs = ['<service UUID 1>', ...];
peripheral.discoverServices(serviceUUIDs[, callback(error, services)]); // particular UUIDs
发现所有服务和特点
peripheral.discoverAllServicesAndCharacteristics([callback(error, services, characteristics)]);
发现一些服务和特点
var serviceUUIDs = ['<service UUID 1>', ...];
var characteristicUUIDs = ['<characteristic UUID 1>', ...];
peripheral.discoverSomeServicesAndCharacteristics(serviceUUIDs, characteristicUUIDs, [callback(error, services, characteristics));
事件:发现的服务
peripheral.once('servicesDiscover', callback(services));
读取手柄
peripheral.readHandle(handle, callback(error, data));
事件: 处理已读
peripheral.once('handleRead<handle>', callback(data)); // data is a Buffer
<handle> 是手柄标识符.
写手柄
peripheral.writeHandle(handle, data, withoutResponse, callback(error));
事件: 处理已写入
peripheral.once('handleWrite<handle>', callback());
<handle> 是手柄标识符.
服务
发现包括的服务
service.discoverIncludedServices(); // any service UUID
var serviceUUIDs = ['<service UUID 1>', ...];
service.discoverIncludedServices(serviceUUIDs[, callback(error, includedServiceUuids)]); // particular UUIDs
事件:发现的服务包含在内
service.once('includedServicesDiscover', callback(includedServiceUuids));
发现特性
service.discoverCharacteristics() // any characteristic UUID
var characteristicUUIDs = ['<characteristic UUID 1>', ...];
service.discoverCharacteristics(characteristicUUIDs[, callback(error, characteristics)]); // particular UUIDs
事件: 发现的特征
service.once('characteristicsDiscover', callback(characteristics));
characteristics{ uuid: '<uuid>', properties: ['...'] // 'broadcast', 'read', 'writeWithoutResponse', 'write', 'notify', 'indicate', 'authenticatedSignedWrites', 'extendedProperties' };
特征
读取
characteristic.read([callback(error, data)]);
事件: 数据已读取
characteristic.on('data', callback(data, isNotification));
characteristic.once('read', callback(data, isNotification)); // legacy
当:
- 特征读取完成,结果
characteristic.read(...) - 特征值在启用之后,通过通知或提示通过外围更新
characteristic.notify(true[, callback(error)])
说明: isNotification 事件参数值 undefined 取决于平台。 参数是 已贬值 在1.8.1版本之后,在macOS High Sierra上和后来不支持.
写入
characteristic.write(data, withoutResponse[, callback(error)]); // data is a Buffer, withoutResponse is true|false
withoutResponse数字 :false: 发送一个带有“ 写” 特性属性的写请求true: 发送写入命令, 使用“ 写入无回复” 特性属性
事件: 数据已写入
characteristic.once('write', withoutResponse, callback());
特性书写完成后即予公布,结果 characteristic.write(...)。 。 。 .
广播
characteristic.broadcast(broadcast[, callback(error)]); // broadcast is true|false
事件:发送广播
characteristic.once('broadcast', callback(state));
特性广播状态发生变化时,因 characteristic.broadcast(...)。 。 。 .
订阅
characteristic.subscribe([callback(error)]);
订阅于一特征.
触发器 data 当外围发送通知或指示时的事件。 用于具有"通知"或"暗示"属性的特性.
事件:收到通知
characteristic.once('notify', callback(state));
特性通知状态发生变化时,因 characteristic.notify(...)。 。 。 .
取消订阅
characteristic.unsubscribe([callback(error)]);
不订阅从特征.
用于具有“ 通知” 或“ 输入” 属性的特性
发现描述符
characteristic.discoverDescriptors([callback(error, descriptors)]);
事件:发现描述符
characteristic.once('descriptorsDiscover', callback(descriptors));
descriptors数字 :[ { uuid: '<uuid>' }, // ... ]
说明
读取值
descriptor.readValue([callback(error, data)]);
事件: 数值已读
descriptor.once('valueRead', data); // data is a Buffer
写入值
descriptor.writeValue(data[, callback(error)]); // data is a Buffer
事件: 写入值
descriptor.once('valueWrite');
高级用途
覆盖默认绑定
默认情况下,贵族会根据您的平台选择合适的蓝牙设备绑定. 您可以使用 with-bindings 模块.
var noble = require('@abandonware/noble/with-bindings')(require('./my-custom-bindings'));
无 root/ sudo 运行( 特定 Linux)
运行以下命令 :
sudo setcap cap_net_raw+eip $(eval readlink -f `which node`)
这允许 node 二进制 cap_net_raw 权限,因此可以开始/停止BLE广告.
说明: 上述命令要求 setcap 将安装.
其安装方式如下:
- 时间:
sudo apt-get install libcap2-bin - y:
su -c \'yum install libcap2-bin\'
多个适配器( Linux 特定)
hci0 默认使用.
要覆盖,请设置 NOBLE_HCI_DEVICE_ID 环境变量到接口编号.
例如,指明 hci1数字 :
sudo NOBLE_HCI_DEVICE_ID=1 node <your file>.js
如果您在一个设置中使用了多个 SCI 设备, 您可以通过在代码中自行初始化来运行两种具有不同绑定配置的 高贵 :
const HCIBindings = require('@abandonware/noble/lib/hci-socket/bindings');
const Noble = require('@abandonware/noble/lib/noble');
const params = {
deviceId: 0,
userChannel: true,
extended: false //ble5 extended features
};
const noble = new Noble(new HCIBindings(params));
报告所有HCI事件(具体为Linux)
默认情况下,贵族既会等待广告数据,也会为每个蓝牙地址扫描响应数据. 如果设备不使用扫描响应,则 NOBLE_REPORT_ALL_HCI_EVENTS 环境变量可用于绕过.
sudo NOBLE_REPORT_ALL_HCI_EVENTS=1 node <your file>.js
bleno 兼容性( 特定 Linux )
默认情况下,只要收到关贸总协定请求的电文,贵族就会以出错回应. 如果你打算和贵族一起使用布尔诺语 NOBLE_MULTI_ROLE 环境变量可用于绕过此行为.
说明: 这需要蓝牙4.1适配器.
sudo NOBLE_MULTI_ROLE=1 node <your file>.js
常见问题
最大同时连接
此限制由蓝牙适配器硬件及其固件所强制.
| 平台 | |
|---|---|
| OS X 10.11 (El Capitan) (法语) | 6个 |
| Linux/ Windows - 适应器依赖 | 5 (基于CSR的适配器) |
沙箱终端
在较新版本的OSX上,终端应用被沙盒所设置,默认不允许蓝牙连接. 如果你运行一个尝试访问它的脚本, 你会得到一个 Abort trap: 6 错误.
要启用蓝牙, 请访问“ 系统首选项 ” QQ“ 安全和隐私 ” “ 蓝牙 ” - > 将终端添加到允许的应用程序中 .
特定适应者的已知问题
一些BLE适配器在扫描时无法连接到外围(下面的例子). 您在尝试连接时会收到以下信息 :
Sena UD-100(剑桥硅电台,Ltd Bluetooth Dongle(HCI模式)): Error: Command disallowed
Intel Dual Band Wireless-AC 7260 (Intel Corporation Wireless 7260 (rev 73)): 互联网档案馆的存檔,存档日期2013-12-20 Error: Connection Rejected due to Limited Resources (0xd)
在试图连接之前你必须停止扫描,以便解决这个问题.
备份
支持我们每月捐款,帮助我们继续活动。 [成为后卫[ . ]
发起人
成为赞助商,在Github上的我们读取的README上获得你的标志,并链接到你的网站。 [成为提案国[ . ]
有用链接
许可证
版权(C)2015 Sandep Mistry [email protected] (英语)
特此准许任何人免费获得本软件和相关文件文件("软件")的副本,不受限制地在软件中进行交易,包括不受限制地享有软件的使用、复制、修改、合并、出版、分发、分版和(或)销售的权利,并允许软件获得者这样做,但须符合下列条件: 1
上述版权通知和许可通知应载入软件的所有副本或大部分.
软件是提供的"AS IS", 没有任何种类的恐惧, 释放或被卷入, 包括但不限制在 危机的保障, 证明一个特定的目的和无关。 任何索赔、索赔或其他负债,无论是合同、交易或其他行为,产生于、产生于或涉及软件或软件的使用或其他交易的行为,都不得作为担保.
