# node-ble
**Repository Path**: zh041/node-ble
## Basic Information
- **Project Name**: node-ble
- **Description**: No description available
- **Primary Language**: Unknown
- **License**: MIT
- **Default Branch**: main
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2021-06-20
- **Last Updated**: 2021-06-21
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# node-ble
Bluetooth Low Energy (BLE) library written with pure Node.js (no bindings) - baked by Bluez via DBus
[](https://chrvadala.github.io)
[](https://github.com/chrvadala/node-ble/actions)
[](https://coveralls.io/github/chrvadala/node-ble?branch=master)
[](https://www.npmjs.com/package/node-ble)
[](https://www.npmjs.com/package/node-ble)
[](https://www.paypal.me/chrvadala/25)
# Setup
```sh
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)
```xml
```
## STEP 1: Get Adapter
To start a Bluetooth Low Energy (BLE) connection you need a Bluetooth adapter.
```javascript
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.
```javascript
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.
```javascript
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.
```javascript
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.
```javascript
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.
```javascript
await device.disconnect()
destroy()
```
# Reference
```javascript
const {createBluetooth} = require('node-ble')
const {bluetooth, destroy} = createBluetooth()
```
| Method | Description |
| --- | --- |
|`Bluetooth bluetooth` |
|`void destroy()` |
## `Bluetooth`
| Method | Description |
| --- | --- |
| `Promise adapters()` | List of available adapters |
| `Promise defaultAdapter()` | Get an available adapter |
| `Promise getAdapter(String adapter)` | Get a specific adapter (one of available in `adapters()`)|
## `Adapter`
| Method | Description |
| --- | --- |
| `Promise getAddress()` | The Bluetooth device address. |
| `Promise getAddressType()`| The Bluetooth Address Type. One of `public` or `random`. |
| `Promise getName()`| The Bluetooth system name (pretty hostname). |
| `Promise getAlias()`| The Bluetooth friendly name. |
| `Promise isPowered()`| Adapter power status. |
| `Promise isDiscovering()`| Indicates that a device discovery procedure is active. |
| `Promise startDiscovery()`| Starts the device discovery session. |
| `Promise stopDiscovery()`| Cancel any previous StartDiscovery transaction. |
| `Promise devices()`| List of discovered Bluetooth Low Energy devices |
| `Promise getDevice(String uuid)`| Returns an available Bluetooth Low Energy (`waitDevice` is preferred)|
| `Promise waitDevice(String uuid)`| Returns a Bluetooth Low Energy device as soon as it is available |
| `Promise toString()`| User friendly adapter name |
## `Device` extends `EventEmitter`
| Method | Description |
| --- | --- |
| `Promise getName()` | The Bluetooth remote name. |
| `Promise getAddress()` | The Bluetooth device address of the remote device. |
| `Promise getAddressType()` | The Bluetooth Address Type. One of `public` or `random`. |
| `Promise getAlias()` | The name alias for the remote device. |
| `Promise getRSSI()` | Received Signal Strength Indicator of the remote device. |
| `Promise isPaired()` | Indicates if the remote device is paired. |
| `Promise isConnected()` | Indicates if the remote device is currently connected. |
| `Promise pair()` | Connects to the remote device, initiate pairing and then retrieve GATT primary services (needs a default agent to handle wizard).|
| `Promise cancelPair()` | This method can be used to cancel a pairing operation initiated by the Pair method. |
| `Promise 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 disconnect()` | This method gracefully disconnects all connected profiles and then terminates low-level ACL connection. |
| `Promise gatt()` | Waits services resolving, then returns a connection to the remote Gatt Server
| `Promise toString()` | User friendly device name. |
| Event | Description |
| --- | --- |
| `connect` | Connected to device |
| `disconnect` | Disconnected from device |
## `GattServer`
| Method | Description |
| --- | --- |
| `Promise services()` | List of available services |
| `Promise getPrimaryService(String uuid)` | Returns a specific Primary Service |
## `GattService`
| Method | Description |
| --- | --- |
| `Promise isPrimary()` | Indicates whether or not this GATT service is a primary service. |
| `Promise getUUID()` | 128-bit service UUID. |
| `Promise characteristics()` | List of available characteristic UUIDs. |
| `Promise getCharacteristic(String uuid)` | Returns a specific characteristic. |
| `Promise toString()` | User friendly service name. |
## `GattCharacteristic` extends `EventEmitter`
| Method | Description |
| --- | --- |
| `Promise getUUID()` | 128-bit characteristic UUID. |
| `Promise getFlags()` | Defines how the characteristic value can be used. |
| `Promise isNotifying()` | True, if notifications or indications on this characteristic are currently enabled. |
| `Promise readValue(Number offset = 0)` | Issues a request to read the value of the characteristic and returns the value if the operation was successful. |
| `Promise writeValue(Buffer buffer, Number | WriteValueOptions options = {})` | Issues a request to write the value of the characteristic. Default options `{ offset: 0, type: 'reliable' }`. |
| `Promise startNotifications()` | Starts a notification session from this characteristic if it supports value notifications or indications. |
| `Promise stopNotifications()` | This method will cancel any previous StartNotify transaction. |
| `Promise toString()` | User friendly characteristic name. |
| Event | Description |
| --- | --- |
| valuechanged | New 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
- Ubuntu 20.04 LTS
## Changelog
- **0.x** - Beta version
- **1.0** - First official version
- **1.1** - Migrates to gh-workflows
- **1.2** - Upgrades deps
- **1.3** - Adds typescript definitions [#10](https://github.com/chrvadala/node-ble/pull/10)
- **1.4** - Upgrades deps
- **1.5** - Adds write options configuration `async writeValue (value, optionsOrOffset = {})` [#20](https://github.com/chrvadala/node-ble/pull/20); Upgrades deps
## Contributors
- [chrvadala](https://github.com/chrvadala) (author)
- [pascalopitz](https://github.com/pascalopitz)
- [lupol](https://github.com/lupol)
## 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)
```xml
```
### 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
```shell script
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
```shell script
# .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
```
```shell script
yarn test:e2e
```
## References
- 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://webbluetoothcg.github.io/web-bluetooth - method signatures follow, when possible, WebBluetooth standards
- https://developers.google.com/web/updates/2015/07/interact-with-ble-devices-on-the-web - method signatures follow, when possible, WebBluetooth standards
## Similar libraries
- https://github.com/noble/noble
- https://github.com/abandonware/noble (noble fork)
- https://www.npmjs.com/package/node-web-bluetooth
## Useful commands
| Command | Description |
| --- | --- |
| rm -r /var/lib/bluetooth/* | Clean Bluetooth cache |
| hciconfig -a | Adapter info |
| hcitool dev | Adapter info (through Bluez) |
| d-feet | DBus debugging tool |
| nvram bluetoothHostControllerSwitchBehavior=never | Only on Parallels |