1.2.0 • Published 4 years ago

@sunookitsune/node-ble v1.2.0

Weekly downloads
1
License
MIT
Repository
github
Last release
4 years ago

node-ble

Bluetooth Low Energy (BLE) library written with pure Node.js (no bindings) - baked by Bluez via DBus

chrvadala Test Coverage Status npm Downloads Donate

Setup

yarn add node-ble

Example

Provide permissions

In order to allow a connection with the DBus daemon, you have to set up right permissions.

Create the file /etc/dbus-1/system.d/node-ble.conf with the following content (customize with userid)

<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
  "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
<busconfig>
  <policy user="%userid%">
   <allow own="org.bluez"/>
    <allow send_destination="org.bluez"/>
    <allow send_interface="org.bluez.GattCharacteristic1"/>
    <allow send_interface="org.bluez.GattDescriptor1"/>
    <allow send_interface="org.freedesktop.DBus.ObjectManager"/>
    <allow send_interface="org.freedesktop.DBus.Properties"/>
  </policy>
</busconfig>

STEP 1: Get Adapter

To start a Bluetooth Low Energy (BLE) connection you need a Bluetooth adapter.

const {createBluetooth} = require('node-ble')
const {bluetooth, destroy} = createBluetooth()
const adapter = await bluetooth.defaultAdapter()

STEP 2: Start discovering

In order to find a Bluetooth Low Energy device out, you have to start a discovery operation.

if (! await adapter.isDiscovering())
  await adapter.startDiscovery()

STEP 3: Get a device, Connect and Get GATT Server

Use an adapter to get a remote Bluetooth device, then connect to it and bind to the GATT (Generic Attribute Profile) server.

const device = await adapter.waitDevice('00:00:00:00:00:00')
await device.connect()
const gattServer = await device.gatt()

STEP 4a: Read and write a characteristic.

const service1 = await gattServer.getPrimaryService('uuid')
const characteristic1 = await service1.getCharacteristic('uuid')
await characteristic1.writeValue(Buffer.from("Hello world"))
const buffer = await characteristic1.readValue()
console.log(buffer)

STEP 4b: Subscribe to a characteristic.

const service2 = await gattServer.getPrimaryService('uuid')
const characteristic2 = await service2.getCharacteristic('uuid')
await characteristic2.startNotifications()
characteristic2.on('valuechanged', buffer => {
  console.log(buffer)
})
await characteristic2.stopNotifications()

STEP 5: Disconnect

When you have done you can disconnect and destroy the session.

await device.disconnect()
destroy()

Reference

const {createBluetooth} = require('node-ble')
const {bluetooth, destroy} = createBluetooth()
MethodDescription
Bluetooth bluetooth
void destroy()

Bluetooth

MethodDescription
Promise<String[]> adapters()List of available adapters
Promise<Adapter> defaultAdapter()Get an available adapter
Promise<Adapter> getAdapter(String adapter)Get a specific adapter (one of available in adapters())

Adapter

MethodDescription
Promise<String> getAddress()The Bluetooth device address.
Promise<String> getAddressType()The Bluetooth Address Type. One of public or random.
Promise<String> getName()The Bluetooth system name (pretty hostname).
Promise<String> getAlias()The Bluetooth friendly name.
Promise<bool> isPowered()Adapter power status.
Promise<bool> isDiscovering()Indicates that a device discovery procedure is active.
Promise<void> startDiscovery()Starts the device discovery session.
Promise<void> stopDiscovery()Cancel any previous StartDiscovery transaction.
Promise<String[]> devices()List of discovered Bluetooth Low Energy devices
Promise<Device> getDevice(String uuid)Returns an available Bluetooth Low Energy (waitDevice is preferred)
Promise<Device> waitDevice(String uuid)Returns a Bluetooth Low Energy device as soon as it is available
Promise<String> toString()User friendly adapter name

Device extends EventEmitter

MethodDescription
Promise<String> getName()The Bluetooth remote name.
Promise<String> getAddress()The Bluetooth device address of the remote device.
Promise<String> getAddressType()The Bluetooth Address Type. One of public or random.
Promise<String> getAlias()The name alias for the remote device.
Promise<String> getRSSI()Received Signal Strength Indicator of the remote device.
Promise<String> isPaired()Indicates if the remote device is paired.
Promise<String> isConnected()Indicates if the remote device is currently connected.
Promise<void> pair()Connects to the remote device, initiate pairing and then retrieve GATT primary services (needs a default agent to handle wizard).
Promise<void> cancelPair()This method can be used to cancel a pairing operation initiated by the Pair method.
Promise<void> connect()This is a generic method to connect any profiles the remote device supports that can be connected to and have been flagged as auto-connectable on our side.
Promise<void> disconnect()This method gracefully disconnects all connected profiles and then terminates low-level ACL connection.
Promise<GattServer> gatt()Waits services resolving, then returns a connection to the remote Gatt Server
Promise<String> toString()User friendly device name.
EventDescription
connectConnected to device
disconnectDisconnected from device

GattServer

MethodDescription
Promise<String[]> services()List of available services
Promise<GattService> getPrimaryService(String uuid)Returns a specific Primary Service

GattService

MethodDescription
Promise<bool> isPrimary()Indicates whether or not this GATT service is a primary service.
Promise<String> getUUID()128-bit service UUID.
Promise<String[]> characteristics()List of available characteristic UUIDs.
Promise<GattCharacteristic> getCharacteristic(String uuid)Returns a specific characteristic.
Promise<String> toString()User friendly service name.

GattCharacteristic extends EventEmitter

MethodDescription
Promise<String> getUUID()128-bit characteristic UUID.
Promise<String[]> getFlags()Defines how the characteristic value can be used.
Promise<bool> isNotifying()True, if notifications or indications on this characteristic are currently enabled.
Promise<Buffer> readValue(Number offset = 0)Issues a request to read the value of the characteristic and returns the value if the operation was successful.
Promise<void> writeValue(Buffer buffer, Number offset = 0)Issues a request to write the value of the characteristic.
Promise<void> startNotifications()Starts a notification session from this characteristic if it supports value notifications or indications.
Promise<void> stopNotifications()This method will cancel any previous StartNotify transaction.
Promise<String> toString()User friendly characteristic name.
EventDescription
valuechangedNew value is notified. (invoke startNotifications() to enable notifications)

Compatibility

This library works on many architectures supported by Linux. It leverages on Bluez driver, a component supported by the following platforms and distributions https://www.bluez.org/about

Node-ble has been tested on the following environment:

  • Raspbian GNU/Linux 10 (buster)
  • Ubuntu 18.04.4 LTS

Changelog

  • 0.x - Beta version
  • 1.0 - First official version
  • 1.1 - Migrates to gh-workflows
  • 1.2 - Upgrades deps

Contributors

Run tests

In order to run test suite you have to set up right DBus permissions.

Create the file /etc/dbus-1/system.d/node-ble-test.conf with the following content (customize with userid)

<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
  "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
<busconfig>
  <policy user="%userid%">
    <allow own="org.test"/>
    <allow send_destination="org.test"/>
    <allow send_interface="org.test.iface"/>
  </policy>
</busconfig>

Unit tests

yarn test

End to end (e2e) tests

The end to end test will try to connect to a real bluetooth device and read some characteristics. To do that, you need two different devices.

Device 1

wget https://git.kernel.org/pub/scm/bluetooth/bluez.git/plain/test/example-advertisement
wget https://git.kernel.org/pub/scm/bluetooth/bluez.git/plain/test/example-gatt-server
python example-advertisement
python example-gatt-server
hcitool dev #this command shows bluetooth mac address

Device 2

# .env
TEST_DEVICE=00:00:00:00:00:00
TEST_SERVICE=12345678-1234-5678-1234-56789abcdef0
TEST_CHARACTERISTIC=12345678-1234-5678-1234-56789abcdef1
TEST_NOTIFY_SERVICE=0000180d-0000-1000-8000-00805f9b34fb
TEST_NOTIFY_CHARACTERISTIC=00002a37-0000-1000-8000-00805f9b34fb
yarn test:e2e

References

Similar libraries

Useful commands

CommandDescription
rm -r /var/lib/bluetooth/*Clean Bluetooth cache
hciconfig -aAdapter info
hcitool devAdapter info (through Bluez)
d-feetDBus debugging tool
nvram bluetoothHostControllerSwitchBehavior=neverOnly on Parallels