© Excellent backgrounds/Shutterstock.com
Bluetooth Low Energy in JavaScript und Node.js

Wir müssen reden


Bluetooth Low Energy wird im Bereich des Internet of Things immer interessanter. Sei es, um vom Smartphone den Fitness-Tracker auszulesen oder um von einem Raspberry Pi auf die Messwerte von verschiedenen Sensoren zuzugreifen. Über die Node.js-Module bleno und noble lässt sich die Kommunikation zwischen BLE-Geräten auch unter JavaScript nutzen.

Zunächst sollen ein paar grundlegende Begriffe geklärt werden, die im Zusammenhang mit BLE verwendet werden. Nehmen wir dazu das Beispiel einer Smartphone-App, die sich mit verschiedenen E-Health-Geräten, wie Blutdruckmessgeräten oder Pulsmessgeräten, verbinden kann. Diese E-Health-Geräte werden im Zusammenhang mit BLE als Peripheral-Devices bezeichnet (kurz: Peripherals), die Smartphone-App dagegen als Central-Device (kurz: Central). Beide Rollen sind im so genannten GAP-Protokoll (Generic Access Profile) festgelegt, über das entschieden wird, ob zwei BLE-Geräte miteinander kommunizieren dürfen oder nicht.

Um auf sich aufmerksam zu machen, senden Peripherals kontinuierlich oder in einer bestimmten Frequenz per Broadcast ein so genanntes Advertising-Signal (Abb. 1). Die Informationen, die dabei mitgesendet werden, enthalten in der Regel den Namen des Peripherals, eine ID und einige weitere Eigenschaften. Anhand dieser Informationen kann ein Central dann entscheiden, ob es sich mit dem Peripheral verbinden möchte. Dabei kann ein Central durchaus zu mehreren Peripherals eine Verbindung herstellen. Ein Smartphone kann sich also mit mehreren E-Health-Geräten verbinden. Ein Peripheral dagegen kann immer nur mit einem einzigen Central verbunden sein, ein E-Health-Gerät beispielsweise also nicht gleichzeitig mit mehreren Smartphones. Das ist übrigens auch einer der Gründe, warum Sie mit Ihrer Bluetoothtastatur nicht gleichzeitig zwei Rechner steuern können.

ackermann_ble_1.tif_fmt1.jpgAbb. 1: Das Prinzip des Generic Access Profile

Wie zwei Geräte via BLE miteinander kommunizieren, wird über das so genannte Generic Attribute Pro­file (GATT) definiert (Abb. 2). Auf den Peripherals läuft dazu jeweils ein GATT-Server, auf dem Central ein entsprechender GATT-Client, sprich: Wenn sich ein Smartphone mit mehreren E-Health-Geräten verbindet, läuft auf jedem dieser Peripherals ein GATT-Server, auf dem Smartphone dagegen jeweils ein GATT-Client.

ackermann_ble_2.tif_fmt1.jpgAbb. 2: Das Prinzip des Generic Attribute Profile

Welche Daten von einem GATT-Server bereitgestellt werden, wird über so genannte Profile definiert. Dabei handelt es sich um eine Zusammenstellung verschiedener Services, die von dem jeweiligen Peripheral zur Verfügung gestellt werden (Abb. 3). Die Bluetooth Special Interest Group (SIG) hat diesbezüglich bereits einige Profile und Services definiert, beispielsweise für Blutdruck- oder Herzfrequenzmessgeräte [1], [2]. Prinzipiell kann man Profile und Services aber auch selbst definieren und implementieren.

Services wiederum enthalten eine oder mehrere Characteristics, auf die lesend und/oder schreibend zugegriffen werden kann, beispielsweise um Messwerte auszulesen oder das Peripheral in einen bestimmten Zustand zu versetzen. Auch hierfür gibt es unter [3] bereits einige vordefinierte Characteristics. Aber auch hier kann man als Entwickler wieder seinen Fantasien quasi freien Lauf lassen. Jede Characteristic wiederum enthält einen Wert sowie optional einen oder mehrere so genannter Descriptors, sprich textuelle Beschreibungen der Characteristic. Darüber hinaus besteht die Möglichkeit, ähnlich dem Observer- oder Publish-/Subscribe-Entwurfsmuster, vom Central über Änderungen einer Characteristic auf einem Peripheral benachrichtigt zu werden.

ackermann_ble_3.tif_fmt1.jpgAbb. 3: Der Zusammenhang von Profiles, Services und Characteristics

„bleno“ und „noble“: die Node.js-Module im Einsatz

Im folgenden Tutorial sollen nun ein Peripheral und ein Central mit Node.js und mit den Modulen bleno und noble implementiert werden. Das Peripheral wird dabei einen Service mit drei Characteristics bereitstellen, auf die dann vom Central in bestimmter Reihenfolge lesend und schreibend zugegriffen wird. Außerdem wird sich das Central an einer der Characteristics als Listener registrieren.

Benötigt werden für das Tutorial zwei Rechner: Einer, der die Rolle des Centrals einnimmt und einer, der die Rolle des Peripherals einnimmt. Hier bieten sich beispielsweise zwei Raspberry Pis an, die praktischerweise seit Version 3 BLE direkt mit an Bord haben. Steht die Hardware, muss anschließend auf den beteiligten Raspberry Pis die JavaScript-Plattform Node.js installiert werden. Dies geschieht relativ einfach über folgende Befehle, die nacheinander die Packages von www.nodesource.com zum Package Repository hinzufügen und anschließend die Installation von Node.js übernehmen:

sudo curl –sL https://deb.nodesource.com/setup_4.x | sudo -E bash - sudo apt-get install -y nodejs

Die erfolgreiche Installation von Node.js können Sie anschließend überprüfen, indem Sie sich beispielsweise über den Befehl node -v die Versionsnummer ausgeben lassen. Mehr Details zu der Installation auf verschiedenen Betriebssystemen finden sich unter [4]. Für die Implementierung von Peripherals steht für Node.js das Modul bleno zur Verfügung [5], für die Implementierung von Centrals das Modul noble vom gleichen Entwickler [6].

Sowohl bleno als auch noble setzen beim Einsatz auf einem Raspberry Pi verschiedene Pakete voraus, die zunächst über folgenden Befehl für jeden der beiden Rechner installiert werden müssen:

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

Die beiden Node.js-Module werden anschließend wie für Node.js-Module gewohnt über den Node.js Package Manager (npm) installiert und gegebenenfalls über den Parameter --save als Abhängigkeit in die Konfigurationsdatei package.json des jeweiligen Projekts geschrieben. Auf dem Rechner, der als Peripheral dienen soll, führt man also den Befehl npm install bleno --save aus, auf dem Rechner, der als Central dienen soll, dagegen den Befehl npm install noble --save.

Als Basis für das Tutorial dient das Hello-World-Pizza-Beispiel von der Entwicklerseite [7], wobei dieses aber deutlich abgeändert wurde: Zum einen wurde der dortige ES5-Code vollständig in ES2015-Code migriert, zum anderen wurde das Beispiel aber auch – fast schon wichtiger – in eine der Jahreszeit entsprechenden Domäne verfrachtet: Statt eines Pizzaservic...

Neugierig geworden?

Angebote für Teams

Für Firmen haben wir individuelle Teamlizenzen. Wir erstellen Ihnen gerne ein passendes Angebot.

Das Library-Modell:
IP-Zugang

Das Company-Modell:
Domain-Zugang