Giter Club home page Giter Club logo

modum-io / modblue Goto Github PK

View Code? Open in Web Editor NEW
13.0 4.0 1.0 2.67 MB

BLE library for nodejs that supports central and peripheral mode using hci, dbus, windows native via WinRT/UWP and macos native

Home Page: https://modum-io.github.io/modblue/

License: MIT License

TypeScript 9.54% JavaScript 0.64% Python 0.19% Objective-C 0.14% Objective-C++ 1.43% C++ 88.07%
nodejs noble bluetooth bluetooth-low-energy dbus hci gatt gatt-server gatt-client characteristics

modblue's Introduction

ModBlue

Trying to make the world better place by improving the bluetooth experience one library at a time.

Getting started

Prerequisites

OS X

Linux

  • Give net_cap_raw to node

    This command may not work if you're using NVM or asdf!
    Make sure to give the actual node binary the permission

    sudo setcap cap_net_raw+eip $(eval readlink -f $(which node))
  • Stop/Disable the bluetooth service if you're planning to advertise with the hci bindings:

    Please note that this stops the dbus bindings from working properly!

    sudo systemctl stop bluetooth

    You can also disable it permanently:

    sudo systemctl disable bluetooth
Debian flavours
  •  sudo apt-get install bluetooth bluez libbluetooth-dev libudev-dev
Fedora and other RPM-based distros
  •  sudo yum install bluez bluez-libs bluez-libs-devel

Installation

Install the module from npm:

npm i -E @modum-io/modblue

Then install the peer depencies depending on which one(s) you want to use:

Usage

Create a new MODblue object to get started (all bindings have the same interface)

import { HciMODblue } from '@modum-io/modblue/hci'; // for hci bindings
// import { DbusMODblue } from '@modum-io/modblue/dbus'; // for dbus bindings

const modblue = new HciMODblue();    // or: new DbusMODblue()

Now you can scan & use one or multiple of the adapters:

const adapters = await modblue.getAdapters();
const adapter = adapters[0];

Scanning

Use an adapter to scan for devices in proximity:

const serviceUUIDs: string[] = [];        // Optional: Advertised service UUIDs, without dashes (-)
const allowDuplicates: boolean = true;    // Optional: Allow duplicate 'discover' events for the same device

await adapter.startScanning(serviceUUIDs, allowDuplicates);

Now you can either wait for a few seconds to scan and then get all the scanned peripherals

const peripherals = await adapter.getScannedPeripherals();

or you can attach an event to trigger each time a new peripheral is discovered (or more often if allowDuplicates is true):

adapter.on('discover', (peripheral) => console.log('Discovered', peripheral.address));

Once discovered you can connect to a peripheral and grab it's GATT to discover services and characteristics:

await peripheral.connect();

// Setup GATT
const requestMtu = 517;    // Optional: Request a specific MTU
const gatt = await peripheral.setupGatt(requestMtu);

// Discover services
const services = await gatt.discoverServices();
const service = services[0];

// Discover characteristics
const characteristics = await service.discoverCharacteristics();
const characteristic = characteristics[0];

// Discover descriptors
const descriptors = await characteristic.discoverDescriptors();
const descriptor = descriptors[0];

// Read value
const buffer = await characteristic.read();
// or
const buffer = await descriptor.readValue();

// Write value
const withoutResponse: boolean = true;    // Tell the peripheral we don't need a response for this write

await characteristic.write(buffer, withoutResponse);
// or
await descriptor.writeValue(buffer);

Advertising

First you have to setup the local GATT and the services and characteristics you want to advertise:

import { GattServiceInput } from '@modum-io/modblue';

const maxMtu: number = 517;                             // Optional: Specify the maximum MTU that should be negotiated with connecting devices.
const gatt = await adapter.setupGatt(maxMtu);           // Setup our local GATT server

const deviceName: string = 'MODblue Testing';
const services: GattServiceInput[] = [
   {
      uuid: '48ee0000bf49460ca3d77ec7a512a4ce',          // UUID of the service (without dashes [-])
      characteristics: [
         {
            uuid: '48ee0001bf49460ca3d77ec7a512a4ce',    // UUID of the characteristic
            properties: ['read'],                        // Supported properties on the characteristic
            secure: [],                                  // Which of the supported properties are secured
            descriptors: [],                             // Descriptors on this characteristic
            value: Buffer.from('test', 'utf-8')          // The (constant) data that is returned for this characteristic
         },
      {
         uuid: '48ee0002bf49460ca3d77ec7a512a4ce',
         properties: ['read'],
         secure: [],
         descriptors: [],
         onRead: async (offset) => {
            // This function receives the offset at which to start reading
            if (offset === 0) {
               // Only do your computation when the first bytes are requested.
               // In case of subsequent reads (because of long data / small MTU) we want to return the same data as before, starting at the offset
               }

               // Returns a tuple containing: [error: number, data: Buffer] - Use 0 for the error on success.
               return [0, Buffer.from('other', 'utf-8').slice(offset)];
            }
         },
         {
            uuid: '48ee0003bf49460ca3d77ec7a512a4cd',
            properties: ['write', 'write-without-response'],
            secure: [],
            descriptors: [],
            onWrite: (offset, data, withoutResponse) => {
               // This function handles writing data to the characteristic
               console.log('writing', offset, data, withoutResponse);
            }
         }
      ]
   }
];
gatt.setData(deviceName, services);

To advertise services and characteristics use:

const deviceName: string = 'MODblue Testing';    // You can use a different advertising name then the name in the GATT
const advertisedServiceUUIDs: string[] = [];     // Optional: Advertise specific service UUIDs (without dashes [-])

await adapter.startAdvertising(deviceName, advertisedServiceUUIDs);

Tests

Adapters

This test will list all available adapters for all available bindings.

  1. Run test using

    node tests/adapters.js

Connect

This test will connect, discover services and characteristics, read a single characteristic value and disconnect. The test runs indefinitely and rotates between all specified devices.

  1. Run test using

    export BINDINGS="hci";
    export LOGGER_IDS="AA:AA:AA:AA:AA:AA|BB:BB:BB:BB:BB:BB";
    export SERVICE_ID="48ee0000bf49460ca3d77ec7a512a4cd";
    export CHARACTERISTIC_ID = "48ee000bbf49460ca3d77ec7a512a4cd";
    node tests/connect.js $BINDINGS $LOGGER_IDS $SERVICE_ID $CHARACTERISTIC_ID

Advertise

This test will advertise some services and characteristics under a specified name. The test runs indefinitely and waits for connections.

  1. Run test using

    export BINDINGS="hci";
    export ADVERTISE_NAME="MODblue Testing";
    node tests/advertise.js $BINDINGS "$ADVERTISE_NAME"

modblue's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

Forkers

casear

modblue's Issues

Apology in advance

I know this is a separate issue and i apologize in advanced. In invitemanager discord support server, the moderator pinged everyone that the bot is officially dead and says its being discontinued.

Due to the bot being dead for many months now with no response from you or andy regarding bringing the bot back up.

I can completely understand that dev wish to discontinue after a time but shouldnt you at least inform the moderators about it so they can notify the users about it. As far as i recall there are active patreons who are waiting fortheir bot to be online again..

Again sorry for creating this issue but this was the only way to get your atttention.

(great app you have on this repo by theway=

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.