npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

bluetoothle-explorer

v1.1.0

Published

Command line explorer for Bluetooth Low Energy (BLE) devices

Downloads

11

Readme

BluetoothLE-Explorer

latest version published to npm

bluetoothle-explorer is a Node.js package for logging information about available Bluetooth Low Energy (BLE) devices, and the data they generate, at the command line.

It is a tool for debugging / exploration, building on top of the noble library, and not intended for consumption from other applications.

Instructions

git clone https://github.com/chbrown/BluetoothLE-Explorer
cd BluetoothLE-Explorer
npm install
node server.js

By default, that will limit discovery to devices advertising recognized service UUIDs (those listed in services.js). To specify a different filter, set the BLE_SERVICES environment variable to a :-separated list of UUIDs. E.g., BLE_SERVICES=180a:1821 node server.js will only connect to devices that advertise the "Device Information" or "Indoor Positioning" services. Use an empty value, e.g., BLE_SERVICES= node server.js, to discover all BLE devices.

Notes on Bluetooth LE / the interface provided by noble

Root level noble object

const noble = require('noble')

That's the noble controller you start with.

You can't do anything with it until it's "powered on", which happens automatically, so you have to listen for its stateChange event, check that noble.state is poweredOn, and then do stuff.

noble.startScanning(serviceUUIDs, allowDuplicates) is the main entry point.

  • This triggers the noble object's discover event, once (assuming allowDuplicates is set to false) for each new device
  • When you provide an non-empty list of serviceUUIDs (a list of hexadecimal strings), it will only trigger discover events for devices ("peripherals") that advertise having that serviceUUID.

peripheral objects

Peripherals are Bluetooth LE devices acting as servers that your machine, the client, is connecting to.

  • A peripheral always has an id attribute (duplicated as uuid), and sometimes an address and addressType, as identifying features.
  • The advertisement is a descriptive object with more information about the peripheral. It has some handy attributes, like:
    • localName: a high-level name for the device
    • serviceUuids: which lists the the service UUIDs it will match
  • The rssi indicates the strength of signal from the peripheral; it's negative, and maxes out at 0. So, the closer to 0 it is, the stronger the signal is.

Besides that chunk of information, you can't do much with the peripheral until you "connect" to it. Assuming the connectable attribute is true, and the current state is "disconnected", you "connect" to the peripheral with peripheral.connect(error => { ... }).

At this point you can call peripheral.discoverServices(serviceUUIDs, (error, services) => { ... }), which as with the noble global's startScanning method, can supply an array of serviceUUIDs to filter, or [] to discover all services.

These are all returned in a single batch, via the callback's services argument.

The discoverServices method will likely return many more services than the device directly advertises (though it includes those), but these are probably metadata, like battery level -- not as integral to the function of the device as what it advertises.

service objects

A service object represents a service as conceptualized by the Bluetooth LE standard.

These are mostly just data; using them is negotiated via the peripheral, though the noble package's interface has the relevant methods attached to the service objects.

Calling service.discoverCharacteristics(characteristicUUIDs, (error, characteristics) => { ... }) triggers discovery of the peripherals characteristics for that service, filtered by characteristicUUIDs, or returning all characteristics if characteristicUUIDs is [].

These are all returned in a single batch, via the callback's characteristics argument.

characteristic objects

Characteristic objects represent various sources of data that the device can produce, which are specified in the Bluetooth LE standard.

Again, these are mostly data, but the noble interface provides helper methods on the characteristic objects.

Most of the information you'll need to parse/interpret characteristics comes from the corresponding Bluetooth LE specification, but it provides one handy attribute that determines what you can do with it via noble: properties, which is an array of strings.

  • If properties contains the string "notify", you can "subscribe" to the characteristic, which will start triggering data events on the characteristic object, as sent by the device.

  • If properties contains the string "read", you can "read" from the characteristic to get the current value.

    You cannot "subscribe" to characteristics with a "read" property hoping to get continual updates whenever it changes; instead, you'd have to set up an interval of your own and poll the characteristic as often as you suspect it might change.

The data structures returned by characteristic.read or emitted as the characteristic's data events are Buffer instances.

  • To parse these, you must consult the Bluetooth LE specification for that characteristic.
  • Several parsers for characteristics of interest (to me) are provided in characteristics.js; when a characteristic defined in that file matches a characteristic received from a device, the command line tool will use that definition's parse(data: Buffer) function to process the data structure. Otherwise, the command line tool will display the raw Buffer.

License

Copyright 2018 Christopher Brown. MIT Licensed.