@abandonware/noble 中文文档教程

发布于 3年前 浏览 387 项目主页 更新于 3年前

noble

构建状态 Gitter  OpenCollective”></a> 
  <a href=OpenCollective

Node.js BLE(低功耗蓝牙)中央模块。

想要实现外设? 查看 bleno

注意:ma​​cOS / Mac OS X、Linux、FreeBSD 和 Windows 是目前唯一受支持的操作系统。

Documentation

Quick Start Example

// 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);
});

Installation

Prerequisites

OS X

  • Install Xcode
  • On newer versions of OSX, allow bluetooth access on the terminal app: "System Preferences" —> "Security & Privacy" —> "Bluetooth" -> Add terminal app (see Sandboxed terminal)

Linux

  • Kernel version 3.6 or above
  • libbluetooth-dev needs to be installed. For instructions for specific distributions, see below.
  • To set the necessary privileges to run without sudo, see this section. This is required for all distributions (Raspbian, Ubuntu, Fedora, etc). You will not get any errors if running without sudo, but nothing will happen.
Ubuntu, Debian, Raspbian

请先查看上面的通用 Linux 注释

sudo apt-get install bluetooth bluez libbluetooth-dev libudev-dev

确保 node 在您的 PATH 上。 如果不是,一些选项:

Fedora and other RPM-based distributions

首先查看上面的通用 Linux 注释

sudo yum install bluez bluez-libs bluez-libs-devel
Intel Edison

请先查看上面的通用 Linux 注释

请参阅为蓝牙 LE(智能)开发配置英特尔 Edison

FreeBSD

确保你有 GNU Make:

sudo pkg install gmake

通过将 no-ubt.conf 放入 来禁用默认蓝牙堆栈的自动加载/usr/local/etc/devd/no-ubt.conf 并重新启动 devd(sudo service devd restart)。

卸载 ng_ubt 内核模块(如果已加载):

sudo kldunload ng_ubt

确保您对与蓝牙适配器对应的 /dev/usb/* 设备具有读写权限。

Windows

Windows 的 node-gyp 要求

使用 Microsoft 的 windows-build-tools 来自提升的 PowerShell 或 cmd.exe(以管理员身份运行)。

npm install --global --production windows-build-tools

node-bluetooth-hci-socket 先决条件

  • Compatible Bluetooth 4.0 USB adapter
  • WinUSB driver setup for Bluetooth 4.0 USB adapter, using Zadig tool

请参阅 @don 在 < a href="https://www.youtube.com/watch?v=mL9B8wuEdms&feature=youtu.be&t=1m46s">Bluetooth LE with Node.js and Noble on Windows

Docker

确保您的容器运行使用 --network=host 选项并验证所有特定环境先决条件。

Installing and using the package

npm install @abandonware/noble
const noble = require('@abandonware/noble');

API docs

所有操作都有两种 API 变体——一种期望回调,一种返回 Promise(由 Async 后缀表示)。

此外,还有与每个操作对应的事件(以及一些全局事件)。

例如,在 Peripheral 的“发现服务”操作的情况下:

  • There's a discoverServices method expecting a callback:
   peripheral.discoverServices((error, services) => {
     // callback - handle error and services
   });
  • There's a discoverServicesAsync method returning a Promise:
  try {
    const services = await peripheral.discoverServicesAsync();
    // handle services
  } catch (e) {
    // handle error
  }
  • There's a servicesDiscover event emitted after services are discovered:
  peripheral.once('servicesDiscover', (services) => {
    // handle services
  });

API 结构:

Scanning and discovery

Event: Adapter state changed

noble.on('stateChange', callback(state));

state 可以是以下之一:

  • unknown
  • resetting
  • unsupported
  • unauthorized
  • poweredOff
  • poweredOn

Start scanning

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必须在扫描开始前 poweredOnnoble.on('stateChange', callback(state)); 可用于监听状态变化事件。

Event: Scanning started

noble.on('scanStart', callback);

事件触发时间:

  • Scanning is started
  • Another application enables scanning
  • Another application changes scanning settings

Stop scanning

noble.stopScanning();

Event: Scanning stopped

noble.on('scanStop', callback);

事件触发时间:

  • Scanning is stopped
  • Another application stops scanning

Event: Peripheral discovered

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 上,如果之前未连接设备,地址将设置为 ''。

Event: Warning raised

noble.on('warning', callback(message));

Reset device

noble.reset()

Peripheral

Connect

peripheral.connect([callback(error)]);

某些蓝牙设备无法无缝连接,可能是因为蓝牙设备固件或内核。 请在连接 API 之前使用 noble.reset() API 重置设备。

Event: Connected

peripheral.once('connect', callback);

Cancel a pending connection

peripheral.cancelConnect();
// Will emit a 'connect' event with error

Disconnect

peripheral.disconnect([callback(error)]);

Event: Disconnected

peripheral.once('disconnect', callback);

Update RSSI

peripheral.updateRssi([callback(error, rssi)]);

Event: RSSI updated

peripheral.once('rssiUpdate', callback(rssi));

Discover services

peripheral.discoverServices(); // any service UUID

var serviceUUIDs = ['<service UUID 1>', ...];
peripheral.discoverServices(serviceUUIDs[, callback(error, services)]); // particular UUIDs

Discover all services and characteristics

peripheral.discoverAllServicesAndCharacteristics([callback(error, services, characteristics)]);

Discover some services and characteristics

var serviceUUIDs = ['<service UUID 1>', ...];
var characteristicUUIDs = ['<characteristic UUID 1>', ...];
peripheral.discoverSomeServicesAndCharacteristics(serviceUUIDs, characteristicUUIDs, [callback(error, services, characteristics));

Event: Services discovered

peripheral.once('servicesDiscover', callback(services));

Read handle

peripheral.readHandle(handle, callback(error, data));

Event: Handle read

peripheral.once('handleRead<handle>', callback(data)); // data is a Buffer

是句柄标识符。

Write handle

peripheral.writeHandle(handle, data, withoutResponse, callback(error));

Event: Handle written

peripheral.once('handleWrite<handle>', callback());

是句柄标识符。

Service

Discover included services

service.discoverIncludedServices(); // any service UUID

var serviceUUIDs = ['<service UUID 1>', ...];
service.discoverIncludedServices(serviceUUIDs[, callback(error, includedServiceUuids)]); // particular UUIDs

Event: Included services discovered

service.once('includedServicesDiscover', callback(includedServiceUuids));

Discover characteristics

service.discoverCharacteristics() // any characteristic UUID

var characteristicUUIDs = ['<characteristic UUID 1>', ...];
service.discoverCharacteristics(characteristicUUIDs[, callback(error, characteristics)]); // particular UUIDs

Event: Characteristics discovered

service.once('characteristicsDiscover', callback(characteristics));
  • characteristics
  {
    uuid: '<uuid>',
    properties: ['...'] // 'broadcast', 'read', 'writeWithoutResponse', 'write', 'notify', 'indicate', 'authenticatedSignedWrites', 'extendedProperties'
  };

Characteristic

Read

characteristic.read([callback(error, data)]);

Event: Data read

characteristic.on('data', callback(data, isNotification));

characteristic.once('read', callback(data, isNotification)); // legacy

发出时间:

  • Characteristic read has completed, result of characteristic.read(...)
  • Characteristic value has been updated by peripheral via notification or indication, after having been enabled with characteristic.notify(true[, callback(error)])

注意 isNotification 事件参数值可以未定义,具体取决于平台。 该参数在 1.8.1 版本后被弃用,并且在 macOS High Sierra 及更高版本上不受支持。

Write

characteristic.write(data, withoutResponse[, callback(error)]); // data is a Buffer, withoutResponse is true|false
  • withoutResponse:
  • false: send a write request, used with "write" characteristic property
  • true: send a write command, used with "write without response" characteristic property

Event: Data written

characteristic.once('write', withoutResponse, callback());

当特征写入完成时发出,characteristic.write(...) 的结果。

Broadcast

characteristic.broadcast(broadcast[, callback(error)]); // broadcast is true|false

Event: Broadcast sent

characteristic.once('broadcast', callback(state));

当特征广播状态改变时发出,characteristic.broadcast(...) 的结果。

Subscribe

characteristic.subscribe([callback(error)]);

订阅一个特征。

当外设发送通知或指示时触发 data 事件。 用于具有“通知”或“指示”属性的特性。

Event: Notification received

characteristic.once('notify', callback(state));

当特征通知状态改变时发出,characteristic.notify(...) 的结果。

Unsubscribe

characteristic.unsubscribe([callback(error)]);

取消订阅特征。

用于具有“notify”或“indicate”属性的特性

Discover descriptors

characteristic.discoverDescriptors([callback(error, descriptors)]);

Event: Descriptors discovered

characteristic.once('descriptorsDiscover', callback(descriptors));
  • descriptors:
  [
    {
      uuid: '<uuid>'
    },
    // ...
  ]

Descriptor

Read value

descriptor.readValue([callback(error, data)]);

Event: Value read

descriptor.once('valueRead', data); // data is a Buffer

Write value

descriptor.writeValue(data[, callback(error)]); // data is a Buffer

Event: Value written

descriptor.once('valueWrite');

Advanced usage

Override default bindings

默认情况下,noble 将根据您的平台选择合适的蓝牙设备绑定。 您可以使用 with-bindings 模块提供自定义绑定。

var noble = require('@abandonware/noble/with-bindings')(require('./my-custom-bindings'));

Running without root/sudo (Linux-specific)

运行以下命令:

sudo setcap cap_net_raw+eip $(eval readlink -f `which node`)

这将授予 node 二进制 cap_net_raw 权限,因此它可以启动/停止 BLE 广播。

注意:以上命令需要安装setcap。 它可以通过以下方式安装:

  • apt: sudo apt-get install libcap2-bin
  • yum: su -c \'yum install libcap2-bin\'

Multiple Adapters (Linux-specific)

默认使用hci0

要覆盖,请将 NOBLE_HCI_DEVICE_ID 环境变量设置为接口编号。

例如,要指定 hci1

sudo NOBLE_HCI_DEVICE_ID=1 node <your file>.js

如果您在一个设置中使用多个 HCI 设备,您可以运行两个具有不同绑定配置的 noble 实例,方法是在代码中分别初始化它们:

const HCIBindings = require('@abandonware/noble/lib/hci-socket/bindings');
const Noble = require('@abandonware/noble/lib/noble');

const params = {
  deviceId: 0,
  userChannel: true
};

const noble = new Noble(new HCIBindings(params));

Reporting all HCI events (Linux-specific)

默认情况下,noble 等待两个每个蓝牙地址的广告数据和扫描响应数据。 如果您的设备不使用扫描响应,则可以使用 NOBLE_REPORT_ALL_HCI_EVENTS 环境变量来绕过它。

sudo NOBLE_REPORT_ALL_HCI_EVENTS=1 node <your file>.js

bleno compatibility (Linux-specific)

默认情况下,每当收到 GATT 请求消息时,noble 都会以错误响应。 如果您打算将 bleno 与 noble 一起使用,则可以使用 NOBLE_MULTI_ROLE 环境变量来绕过此行为。

注意:这需要蓝牙 4.1 适配器。

sudo NOBLE_MULTI_ROLE=1 node <your file>.js

Common problems

Maximum simultaneous connections

此限制由蓝牙适配器硬件及其固件强加。

Platform
OS X 10.11 (El Capitan) 6
Linux/Windows - Adapter-dependent 5 (CSR based adapter)

Sandboxed terminal

在较新版本的 OSX 上,终端应用程序被沙盒化以默认不允许蓝牙连接。 如果您运行试图访问它的脚本,您将收到 Abort trap: 6 错误。

要启用蓝牙,请转到“系统偏好设置”—> “安全与隐私”——> “蓝牙”-> 将您的终端添加到允许的应用程序中。

Adapter-specific known issues

某些 BLE 适配器在扫描时无法连接到外围设备(以下示例)。 尝试连接时您将收到以下消息:

Sena UD-100(Cambridge Silicon Radio, Ltd Bluetooth Dongle(HCI 模式)):Error: Command disallowed

Intel Dual Band Wireless-AC 7260 (Intel Corporation Wireless 7260 (rev 73): Error: Connection Rejected due to Limited Resources (0xd)

为了解决这个问题,您需要在尝试连接之前停止扫描。

Backers

支持我们每月捐款并帮助我们继续我们的活动。 [成为支持者]

Sponsors

成为赞助商并在 Github 上的自述文件中获取您的徽标以及指向您网站的链接。 [成为赞助商]

License

版权所有 (C) 2015 Sandeep Mistry sandeep.mistry@gmail.com

特此免费授予任何权限获得本软件和相关文档文件(“软件”)副本的人,可以不受限制地处理本软件,包括但不限于使用、复制、修改、合并、发布、分发、再许可和/或出售的权利软件的副本,并允许获得软件的人这样做,但须满足以下条件:

上述版权声明和本许可声明应包含在软件的所有副本或重要部分中。

本软件“按原样”提供,不提供任何明示或暗示的保证,包括但不限于对适销性、特定用途的适用性和非侵权的保证。 在任何情况下,作者或版权持有人均不对任何索赔、损害或其他责任负责,无论是在合同诉讼、侵权行为还是其他方面,由软件或软件的使用或其他交易引起、由软件引起或与之相关软件。

分析

noble

Build Status Gitter OpenCollective OpenCollective

A Node.js BLE (Bluetooth Low Energy) central module.

Want to implement a peripheral? Check out bleno.

Note: macOS / Mac OS X, Linux, FreeBSD and Windows are currently the only supported OSes.

Documentation

Quick Start Example

// 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);
});

Installation

Prerequisites

OS X

  • Install Xcode
  • On newer versions of OSX, allow bluetooth access on the terminal app: "System Preferences" —> "Security & Privacy" —> "Bluetooth" -> Add terminal app (see Sandboxed terminal)

Linux

  • Kernel version 3.6 or above
  • libbluetooth-dev needs to be installed. For instructions for specific distributions, see below.
  • To set the necessary privileges to run without sudo, see this section. This is required for all distributions (Raspbian, Ubuntu, Fedora, etc). You will not get any errors if running without sudo, but nothing will happen.
Ubuntu, Debian, Raspbian

See the generic Linux notes above first.

sudo apt-get install bluetooth bluez libbluetooth-dev libudev-dev

Make sure node is on your PATH. If it's not, some options:

Fedora and other RPM-based distributions

See the generic Linux notes above first.

sudo yum install bluez bluez-libs bluez-libs-devel
Intel Edison

See the generic Linux notes above first.

See Configure Intel Edison for Bluetooth LE (Smart) Development.

FreeBSD

Make sure you have GNU Make:

sudo pkg install gmake

Disable automatic loading of the default Bluetooth stack by putting no-ubt.conf into /usr/local/etc/devd/no-ubt.conf and restarting devd (sudo service devd restart).

Unload ng_ubt kernel module if already loaded:

sudo kldunload ng_ubt

Make sure you have read and write permissions on the /dev/usb/* device that corresponds to your Bluetooth adapter.

Windows

node-gyp requirements for Windows

Install the required tools and configurations using Microsoft's windows-build-tools from an elevated PowerShell or cmd.exe (run as Administrator).

npm install --global --production windows-build-tools

node-bluetooth-hci-socket prerequisites

  • Compatible Bluetooth 4.0 USB adapter
  • WinUSB driver setup for Bluetooth 4.0 USB adapter, using Zadig tool

See @don's setup guide on Bluetooth LE with Node.js and Noble on Windows

Docker

Make sur your container runs with --network=host options and all specific environment preriquisites are verified.

Installing and using the package

npm install @abandonware/noble
const noble = require('@abandonware/noble');

API docs

All operations have two API variants – one expecting a callback, one returning a Promise (denoted by Async suffix).

Additionally, there are events corresponding to each operation (and a few global events).

For example, in case of the "discover services" operation of Peripheral:

  • There's a discoverServices method expecting a callback:
   peripheral.discoverServices((error, services) => {
     // callback - handle error and services
   });
  • There's a discoverServicesAsync method returning a Promise:
  try {
    const services = await peripheral.discoverServicesAsync();
    // handle services
  } catch (e) {
    // handle error
  }
  • There's a servicesDiscover event emitted after services are discovered:
  peripheral.once('servicesDiscover', (services) => {
    // handle services
  });

API structure:

Scanning and discovery

Event: Adapter state changed

noble.on('stateChange', callback(state));

state can be one of:

  • unknown
  • resetting
  • unsupported
  • unauthorized
  • poweredOff
  • poweredOn

Start scanning

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

NOTE: noble.state must be poweredOn before scanning is started. noble.on('stateChange', callback(state)); can be used to listen for state change events.

Event: Scanning started

noble.on('scanStart', callback);

The event is emitted when:

  • Scanning is started
  • Another application enables scanning
  • Another application changes scanning settings

Stop scanning

noble.stopScanning();

Event: Scanning stopped

noble.on('scanStop', callback);

The event is emitted when:

  • Scanning is stopped
  • Another application stops scanning

Event: Peripheral discovered

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
  };

Note: On macOS, the address will be set to '' if the device has not been connected previously.

Event: Warning raised

noble.on('warning', callback(message));

Reset device

noble.reset()

Peripheral

Connect

peripheral.connect([callback(error)]);

Some of the bluetooth devices doesn't connect seamlessly, may be because of bluetooth device firmware or kernel. Do reset the device with noble.reset() API before connect API.

Event: Connected

peripheral.once('connect', callback);

Cancel a pending connection

peripheral.cancelConnect();
// Will emit a 'connect' event with error

Disconnect

peripheral.disconnect([callback(error)]);

Event: Disconnected

peripheral.once('disconnect', callback);

Update RSSI

peripheral.updateRssi([callback(error, rssi)]);

Event: RSSI updated

peripheral.once('rssiUpdate', callback(rssi));

Discover services

peripheral.discoverServices(); // any service UUID

var serviceUUIDs = ['<service UUID 1>', ...];
peripheral.discoverServices(serviceUUIDs[, callback(error, services)]); // particular UUIDs

Discover all services and characteristics

peripheral.discoverAllServicesAndCharacteristics([callback(error, services, characteristics)]);

Discover some services and characteristics

var serviceUUIDs = ['<service UUID 1>', ...];
var characteristicUUIDs = ['<characteristic UUID 1>', ...];
peripheral.discoverSomeServicesAndCharacteristics(serviceUUIDs, characteristicUUIDs, [callback(error, services, characteristics));

Event: Services discovered

peripheral.once('servicesDiscover', callback(services));

Read handle

peripheral.readHandle(handle, callback(error, data));

Event: Handle read

peripheral.once('handleRead<handle>', callback(data)); // data is a Buffer

<handle> is the handle identifier.

Write handle

peripheral.writeHandle(handle, data, withoutResponse, callback(error));

Event: Handle written

peripheral.once('handleWrite<handle>', callback());

<handle> is the handle identifier.

Service

Discover included services

service.discoverIncludedServices(); // any service UUID

var serviceUUIDs = ['<service UUID 1>', ...];
service.discoverIncludedServices(serviceUUIDs[, callback(error, includedServiceUuids)]); // particular UUIDs

Event: Included services discovered

service.once('includedServicesDiscover', callback(includedServiceUuids));

Discover characteristics

service.discoverCharacteristics() // any characteristic UUID

var characteristicUUIDs = ['<characteristic UUID 1>', ...];
service.discoverCharacteristics(characteristicUUIDs[, callback(error, characteristics)]); // particular UUIDs

Event: Characteristics discovered

service.once('characteristicsDiscover', callback(characteristics));
  • characteristics
  {
    uuid: '<uuid>',
    properties: ['...'] // 'broadcast', 'read', 'writeWithoutResponse', 'write', 'notify', 'indicate', 'authenticatedSignedWrites', 'extendedProperties'
  };

Characteristic

Read

characteristic.read([callback(error, data)]);

Event: Data read

characteristic.on('data', callback(data, isNotification));

characteristic.once('read', callback(data, isNotification)); // legacy

Emitted when:

  • Characteristic read has completed, result of characteristic.read(...)
  • Characteristic value has been updated by peripheral via notification or indication, after having been enabled with characteristic.notify(true[, callback(error)])

Note: isNotification event parameter value MAY be undefined depending on platform. The parameter is deprecated after version 1.8.1, and not supported on macOS High Sierra and later.

Write

characteristic.write(data, withoutResponse[, callback(error)]); // data is a Buffer, withoutResponse is true|false
  • withoutResponse:
  • false: send a write request, used with "write" characteristic property
  • true: send a write command, used with "write without response" characteristic property

Event: Data written

characteristic.once('write', withoutResponse, callback());

Emitted when characteristic write has completed, result of characteristic.write(...).

Broadcast

characteristic.broadcast(broadcast[, callback(error)]); // broadcast is true|false

Event: Broadcast sent

characteristic.once('broadcast', callback(state));

Emitted when characteristic broadcast state changes, result of characteristic.broadcast(...).

Subscribe

characteristic.subscribe([callback(error)]);

Subscribe to a characteristic.

Triggers data events when peripheral sends a notification or indication. Use for characteristics with "notify" or "indicate" properties.

Event: Notification received

characteristic.once('notify', callback(state));

Emitted when characteristic notification state changes, result of characteristic.notify(...).

Unsubscribe

characteristic.unsubscribe([callback(error)]);

Unsubscribe from a characteristic.

Use for characteristics with "notify" or "indicate" properties

Discover descriptors

characteristic.discoverDescriptors([callback(error, descriptors)]);

Event: Descriptors discovered

characteristic.once('descriptorsDiscover', callback(descriptors));
  • descriptors:
  [
    {
      uuid: '<uuid>'
    },
    // ...
  ]

Descriptor

Read value

descriptor.readValue([callback(error, data)]);

Event: Value read

descriptor.once('valueRead', data); // data is a Buffer

Write value

descriptor.writeValue(data[, callback(error)]); // data is a Buffer

Event: Value written

descriptor.once('valueWrite');

Advanced usage

Override default bindings

By default, noble will select appropriate Bluetooth device bindings based on your platform. You can provide custom bindings using the with-bindings module.

var noble = require('@abandonware/noble/with-bindings')(require('./my-custom-bindings'));

Running without root/sudo (Linux-specific)

Run the following command:

sudo setcap cap_net_raw+eip $(eval readlink -f `which node`)

This grants the node binary cap_net_raw privileges, so it can start/stop BLE advertising.

Note: The above command requires setcap to be installed. It can be installed the following way:

  • apt: sudo apt-get install libcap2-bin
  • yum: su -c \'yum install libcap2-bin\'

Multiple Adapters (Linux-specific)

hci0 is used by default.

To override, set the NOBLE_HCI_DEVICE_ID environment variable to the interface number.

For example, to specify hci1:

sudo NOBLE_HCI_DEVICE_ID=1 node <your file>.js

If you are using multiple HCI devices in one setup you can run two instances of noble with different binding configurations by initializing them seperatly in code:

const HCIBindings = require('@abandonware/noble/lib/hci-socket/bindings');
const Noble = require('@abandonware/noble/lib/noble');

const params = {
  deviceId: 0,
  userChannel: true
};

const noble = new Noble(new HCIBindings(params));

Reporting all HCI events (Linux-specific)

By default, noble waits for both the advertisement data and scan response data for each Bluetooth address. If your device does not use scan response, the NOBLE_REPORT_ALL_HCI_EVENTS environment variable can be used to bypass it.

sudo NOBLE_REPORT_ALL_HCI_EVENTS=1 node <your file>.js

bleno compatibility (Linux-specific)

By default, noble will respond with an error whenever a GATT request message is received. If your intention is to use bleno in tandem with noble, the NOBLE_MULTI_ROLE environment variable can be used to bypass this behaviour.

Note: this requires a Bluetooth 4.1 adapter.

sudo NOBLE_MULTI_ROLE=1 node <your file>.js

Common problems

Maximum simultaneous connections

This limit is imposed by the Bluetooth adapter hardware as well as its firmware.

Platform
OS X 10.11 (El Capitan) 6
Linux/Windows - Adapter-dependent 5 (CSR based adapter)

Sandboxed terminal

On newer versions of OSX, the terminal app is sandboxed to not allow bluetooth connections by default. If you run a script that tries to access it, you will get an Abort trap: 6 error.

To enable bluetooth, go to "System Preferences" —> "Security & Privacy" —> "Bluetooth" -> Add your terminal into allowed apps.

Adapter-specific known issues

Some BLE adapters cannot connect to a peripheral while they are scanning (examples below). You will get the following messages when trying to connect:

Sena UD-100 (Cambridge Silicon Radio, Ltd Bluetooth Dongle (HCI mode)): Error: Command disallowed

Intel Dual Band Wireless-AC 7260 (Intel Corporation Wireless 7260 (rev 73)): Error: Connection Rejected due to Limited Resources (0xd)

You need to stop scanning before trying to connect in order to solve this issue.

Backers

Support us with a monthly donation and help us continue our activities. [Become a backer]

Sponsors

Become a sponsor and get your logo on our README on Github with a link to your site. [Become a sponsor]

License

Copyright (C) 2015 Sandeep Mistry sandeep.mistry@gmail.com

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Analytics

更多

友情链接

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文