Bluetooth Low Energy (BLE) library written with pure Node.js (no bindings) - baked by Bluez via DBus
This library works on many architectures supported by Linux. However Windows and Mac OS are not supported.
It leverages the bluez driver, a component supported by the following platforms and distributions https://www.bluez.org/about.
node-ble has been tested on the following operating systems: - Raspbian - Ubuntu - Debian
npm install node-ble
In order to allow a connection with the DBus daemon, you have to set up right permissions.
Execute the following command, in order to create the file /etc/dbus-1/system.d/node-ble.conf, configured with the current user id (Note: You may need to manually change the user id).
echo '<!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>' | sed "s/__USERID__/$(id -un)/" | sudo tee /etc/dbus-1/system.d/node-ble.conf > /dev/null
To start a Bluetooth Low Energy (BLE) connection you need a Bluetooth adapter instance.
const {createBluetooth} = require('node-ble')
const {bluetooth, destroy} = createBluetooth()
const adapter = await bluetooth.defaultAdapter()
In order to find a Bluetooth Low Energy device out, you have to start a discovery operation.
if (! await adapter.isDiscovering())
await adapter.startDiscovery()
Use the adapter instance in order to get a remote Bluetooth device, then connect and interact with 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()
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)
const service2 = await gattServer.getPrimaryService('uuid')
const characteristic2 = await service2.getCharacteristic('uuid')
characteristic2.on('valuechanged', buffer => {
console.log(buffer)
})
await characteristic2.startNotifications()
When you have done you can stop notifications, disconnect and destroy the session.
await characteristic2.stopNotifications()
await device.disconnect()
destroy()
async writeValue (value, optionsOrOffset = {}) #20; Upgrades depsBluetooth.activeAdapters() func #45; writeValueWithoutResponse() and writeValueWithResponse methods #47; Improves typescript definition #48 getManufacturerData and getAdvertisingData functions on Device #67; Adds getServiceData functions on Device; Improves pre-requisite doc section #68| 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 |
| inxi --bluetooth -z | Bluetooth device info |
$ claude mcp add node-ble \
-- python -m otcore.mcp_server <graph>