Skip to content
Hsiang Chou edited this page Jun 18, 2020 · 24 revisions

What you need

  • A BLE equipped computer
  • A BLE peripheral (see here for a list of tested devices)

Setup Prerequisites

node.js

Linux Specific

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

Installing

npm install noble

Usage

See Readme and examples for more info.

Include/import

var noble = require('noble');

Waiting for adapter state

noble.on('stateChange', function(state) {
  // possible state values: "unknown", "resetting", "unsupported", "unauthorized", "poweredOff", "poweredOn"

  // ...
});

Starting/stopping scanning on adapter state change, and discover event

noble.on('stateChange', function(state) {
  if (state === 'poweredOn') {
    noble.startScanning();
  } else {
    noble.stopScanning();
  }
});

noble.on('discover', function(peripheral) {
    console.log('Found device with local name: ' + peripheral.advertisement.localName);
    console.log('advertising the following service uuid\'s: ' + peripheral.advertisement.serviceUuids);
    console.log();
});

Options on startScanning

// only scan for devices advertising these service UUID's (default or empty array => any peripherals
var serviceUuids = ['<service uuid>', ...]; 

// allow duplicate peripheral to be returned (default false) on discovery event
var allowDuplicates = true; 

noble.startScanning(serviceUuids, allowDuplicates);

Note that in order to get advertising information in BLE scan responses, you must set allowDuplicates to true.

Connecting to a peripheral

noble.on('discover', function(peripheral) {
  peripheral.connect(function(error) {
    console.log('connected to peripheral: ' + peripheral.uuid);
  });
});

Disconnecting a peripheral

noble.on('discover', function(peripheral) {
  peripheral.connect(function(error) {
    console.log('connected to peripheral: ' + peripheral.uuid);
    
    peripheral.disconnect(function(error) {
       console.log('disconnected from peripheral: ' + peripheral.uuid);
    });
  });
});

Discovering a peripheral's services

Discovering all services

noble.on('discover', function(peripheral) {
  peripheral.connect(function(error) {
    console.log('connected to peripheral: ' + peripheral.uuid);
    peripheral.discoverServices(null, function(error, services) {
      console.log('discovered the following services:');
      for (var i in services) {
        console.log('  ' + i + ' uuid: ' + services[i].uuid);
      }
    });
  });
});

Discovering a particular service UUID

Example of only discovering device information service

noble.on('discover', function(peripheral) {
  peripheral.connect(function(error) {
    console.log('connected to peripheral: ' + peripheral.uuid);
    peripheral.discoverServices(['180a'], function(error, services) {
      var deviceInformationService = services[0];

      ...
    });
  });
});

Discovering service characteristics

Discovering all service characteristics

noble.on('discover', function(peripheral) {
  peripheral.connect(function(error) {
    console.log('connected to peripheral: ' + peripheral.uuid);
    peripheral.discoverServices(['180a'], function(error, services) {
      var deviceInformationService = services[0];
      console.log('discovered device information service');

      deviceInformationService.discoverCharacteristics(null, function(error, characteristics) {
        console.log('discovered the following characteristics:');
        for (var i in characteristics) {
          console.log('  ' + i + ' uuid: ' + characteristics[i].uuid);
        }
      });
    });
  });
});

Discovering a particular service characteristics

Example of only discovering manufacturer name string characteristic

noble.on('discover', function(peripheral) {
  peripheral.connect(function(error) {
    console.log('connected to peripheral: ' + peripheral.uuid);
    peripheral.discoverServices(['180a'], function(error, services) {
      var deviceInformationService = services[0];
      console.log('discovered device information service');

      deviceInformationService.discoverCharacteristics(['2a29'], function(error, characteristics) {
        var manufacturerNameCharacteristic = characteristics[0];

        ...
      });
    });
  });
});

Reading a characteristic

noble.on('discover', function(peripheral) {
  peripheral.connect(function(error) {
    console.log('connected to peripheral: ' + peripheral.uuid);
    peripheral.discoverServices(['180a'], function(error, services) {
      var deviceInformationService = services[0];
      console.log('discovered device information service');

      deviceInformationService.discoverCharacteristics(['2a29'], function(error, characteristics) {
        var manufacturerNameCharacteristic = characteristics[0];
        console.log('discovered manufacturer name characteristic');

        manufacturerNameCharacteristic.read(function(error, data) {
          // data is a buffer
          console.log('manufacture name is: ' + data.toString('utf8'));
        });
      });
    });
  });
});

Writing a characteristic

Example of writing 0x01 to Alert Level

noble.on('discover', function(peripheral) {
  peripheral.connect(function(error) {
    console.log('connected to peripheral: ' + peripheral.uuid);
    peripheral.discoverServices(['1802'], function(error, services) {
      var immediateAlertService = services[0];
      console.log('discovered Immediate Alert service');

      immediateAlertService.discoverCharacteristics(['2a06'], function(error, characteristics) {
        var alertLevelCharacteristic = characteristics[0];
        console.log('discovered Alert Level characteristic');

        // true if for write without response
        alertLevelCharacteristic.write(new Buffer([0x01]), true, function(error) {
          console.log('set alert level to mid (1)');
        });
      });
    });
  });
});

Getting notified on characteristic value change

Example of getting notified of Battery Level change

noble.on('discover', function(peripheral) {
  peripheral.connect(function(error) {
    console.log('connected to peripheral: ' + peripheral.uuid);
    peripheral.discoverServices(['180f'], function(error, services) {
      var batteryService = services[0];
      console.log('discoveredBatter service');

      batteryService.discoverCharacteristics(['2a19'], function(error, characteristics) {
        var batteryLevelCharacteristic = characteristics[0];
        console.log('discovered Battery Level characteristic');

        batteryLevelCharacteristic.on('data', function(data, isNotification) {
          console.log('battery level is now: ', data.readUInt8(0) + '%');
        });

        // to enable notify
        batteryLevelCharacteristic.subscribe(function(error) {
          console.log('battery level notification on');
        });
      });
    });
  });
});