All Projects → shmuelzon → ble2mqtt

shmuelzon / ble2mqtt

Licence: MIT license
A BLE to MQTT bridge

Programming Languages

javascript
184084 projects - #8 most used programming language

Projects that are alternatives of or similar to ble2mqtt

bluetooth-gatt-parser
Bluetooth GATT service and characteristic parser
Stars: ✭ 61 (+1.67%)
Mutual labels:  bluetooth, ble, gatt
py-bluetooth-utils
Python module containing bluetooth utility functions, in particular for easy BLE scanning and advertising
Stars: ✭ 60 (+0%)
Mutual labels:  bluetooth, ble, bluez
bluetooth-manager
Java Bluetooth Manager. A library/framework for managing bluetooth adapters, bluetooth devices, GATT services and characteristics
Stars: ✭ 75 (+25%)
Mutual labels:  bluetooth, ble, gatt
bluetooth-iot-service-python
This application connects two devices over Bluetooth and allows one to send messages to the other using json. Raspberry Pi Bluetooth interfacing with Linux via RFCOMM BT network
Stars: ✭ 23 (-61.67%)
Mutual labels:  bluetooth, ble, bluez
coBlue
Use Bluetooth Low Energy for remote commands, file transfer, Based on bluez Bluetooth protocol stack (BLE Terminal)
Stars: ✭ 41 (-31.67%)
Mutual labels:  bluetooth, ble, gatt
BTLinker
🔥空祖家的蓝牙连接封装库,适用于智能硬件蓝牙通讯
Stars: ✭ 64 (+6.67%)
Mutual labels:  bluetooth, ble
theheraldproject.github.io
Herald - Proximity Detection Protocol and research documentation, including the Fair Efficacy Formula
Stars: ✭ 17 (-71.67%)
Mutual labels:  bluetooth, ble
sblendid
A JavaScript Bluetooth Low Energy (BLE) Library
Stars: ✭ 60 (+0%)
Mutual labels:  bluetooth, ble
Gormsson
Harald "Bluetooth" Gormsson was a king of Denmark and Norway.
Stars: ✭ 25 (-58.33%)
Mutual labels:  bluetooth, ble
bluetooth-terminal
ES6 class for serial communication with your own Bluetooth Low Energy (Smart) devices
Stars: ✭ 43 (-28.33%)
Mutual labels:  bluetooth, ble
ganglion-ble
Web Bluetooth client for the Ganglion brain-computer interface by OpenBCI
Stars: ✭ 27 (-55%)
Mutual labels:  bluetooth, ble
ble
Bluetooth Low Energy for Linux / macOS
Stars: ✭ 264 (+340%)
Mutual labels:  bluetooth, ble
RejsaRubberTrac
RejsaRubberTrac - A wireless thermal camera for monitoring tire temperatures
Stars: ✭ 77 (+28.33%)
Mutual labels:  bluetooth, ble
daydream-node
Quick Node.js module to connect to the Daydream controller and receive all the data
Stars: ✭ 17 (-71.67%)
Mutual labels:  bluetooth, ble
onewheel-bluetooth
A python bluetooth data reader for the Onewheel (supporting Gemini firmware, and later).
Stars: ✭ 28 (-53.33%)
Mutual labels:  bluetooth, gatt
contact-tracer
A prototype contact tracer app for COVID-19 pandemic response
Stars: ✭ 50 (-16.67%)
Mutual labels:  bluetooth, ble
ioBroker.ble
Monitor Bluetooth Low Energy beacons
Stars: ✭ 39 (-35%)
Mutual labels:  bluetooth, ble
app-xyo-nodejs
XYO Archivist/Diviner CLI
Stars: ✭ 41 (-31.67%)
Mutual labels:  bluetooth, ble
spherov2.py
Unofficial Python API for all Sphero toys
Stars: ✭ 36 (-40%)
Mutual labels:  bluetooth, ble
Golden Gate
Framework to connect wearables and other IoT devices to mobile phones, tablets and PCs with an IP-based protocol stack over Bluetooth Low Energy
Stars: ✭ 223 (+271.67%)
Mutual labels:  bluetooth, ble

BLE2MQTT

Depreciation Notice - This project is no longer maintained in favor of the ESP32 variant. Pull requests and questions are still welcome.

This project aims to be a BLE to MQTT bridge, i.e. expose BLE GATT characteristics as MQTT topics for bidirectional communication. It relies on the BlueZ DBus API and as such is supported on Linux only.

For example, if a device with a MAC address of A0:E6:F8:50:72:53 exposes the 0000180f-0000-1000-8000-00805f9b34fb service (Battery Service) which includes the 00002a19-0000-1000-8000-00805f9b34fb characteristic (Battery Level), the A0:E6:F8:50:72:53/BatteryService/BatteryLevel MQTT topic is published with a value representing the battery level.

In order to set a GATT value, publish a message to a writable characteristic using the above format suffixed with /Set. Note that values are byte arrays so writing a 64-bit value would look like 10,231,32,24.

Configuration

While the basic configuration file provided in the repository (config.json) should be enough for most users, it is possible to tweak it a bit to fit one's specific needs.

The mqtt section below includes the following entries:

{
  "mqtt": {
    "server": {
      "host": "127.0.0.1",
      "port": 1883
    },
    "publish": {
      "retain": true
    },
    "topics" :{
      "device_name": "Address",
      "set_suffix": "/Set"
    }
  }
}
  • server - define which MQTT broker the application should connect to
  • publish - configuration for publishing topics. This object is passed as-is to the mqtt.publish() method
  • topics
    • device name - define which attribute of a device (as exposed by Bluez) should be used to identify it in the MQTT topic
    • set_suffix - Which suffix should be added to the MQTT value topic in order to write a new value to the characteristic. Set this to an empty string if you wish to use the same topic for reading and writing

The ble section of the configuration file includes the following default configuration:

{
  "ble": {
    "services": { },
    "characteristics": { }
  }
}
  • services - add an additional service or override an existing definition to the ones grabbed automatically on first run from http://www.bluetooth.org. Each service can include a name field which will be used in the MQTT topic instead of its UUID. For example:

    "services": {
      "00002f00-0000-1000-8000-00805f9b34fb": {
        "name": "Relay Service"
      },
    }
  • characteristics - add an additional characteristic or override an existing definition to the ones grabbed automatically on first run from http://www.bluetooth.org. Each characteristic can include a name field which will be used in the MQTT topic instead of its UUID, a types array defining how to parse the byte array reflecting the characteristic's value and a poll value (in seconds) for the application to poll the BLE device for a new value. For example:

    "characteristics": {
      "00002a19-0000-1000-8000-00805f9b34fb": {
        "//": "Poll the battery level characteristic every day",
        "poll": 86400
      },
      "00002f01-0000-1000-8000-00805f9b34fb": {
        "name": "Relay State",
        "types": [
          "boolean"
        ]
      }
    }
  • whitelist/blacklist - An array of strings or regular expressions used to match MAC addresses of devices. If whitelist is used, only devices with a MAC address matching one of the entries will be connected while if blacklist is used, only devices that do not match any entry will be connected to.

    "whitelist": [
      "A0:E6:F8:.*"
    ]
  • passkeys - An object containing the passkey (number 000000~999999) used for out-of-band authorization. Each entry is the MAC address of the BLE device and the value is the passkey to use.

    "passkeys": {
      "B0:B4:48:D3:63:98": 123456
    }

Installation

This app requires node version >= 4.3.2 (need support for arrow functions) as well as a fairly recent version of Bluez (>= 5.40).

Note that you can probably point your apt sources to stretch/testing to get newer versions of these packages. I, personally, haven't tried that yet

Bluez

My personal setup is a Raspberry Pi 3 utilizing its built-in Bluetooth radio. I needed to build a newer version of Bluez and needed it to be a Debian package since a different package (pi-bluetooth, which creates the HCI device) depends on it. To overcome this, I ran the following:

# Get dependencies
sudo apt-get update
sudo apt-get install -y libusb-dev libdbus-1-dev libglib2.0-dev libudev-dev \
  libical-dev libreadline-dev checkinstall 

# Compile + Install Bluez 5.45
mkdir -p ~/Downloads
wget -O ~/Downloads/bluez-5.45.tar.xz http://www.kernel.org/pub/linux/bluetooth/bluez-5.45.tar.xz
mkdir -p ~/code
cd ~/code
tar -xvf ~/Downloads/bluez-5.45.tar.xz
cd bluez-5.45

# Allow tabs to be tabs (for patches)
bind '\C-i:self-insert'
 
patch -p1 << EOF
--- a/tools/hciattach.c
+++ b/tools/hciattach.c
@@ -1236,7 +1236,7 @@
 {
 	struct uart_t *u = NULL;
 	int detach, printpid, raw, opt, i, n, ld, err;
-	int to = 10;
+	int to = 30;
 	int init_speed = 0;
 	int send_break = 0;
 	pid_t pid;
--- a/tools/hciattach_bcm43xx.c
+++ b/tools/hciattach_bcm43xx.c
@@ -43,7 +43,7 @@
 #include "hciattach.h"
 
 #ifndef FIRMWARE_DIR
-#define FIRMWARE_DIR "/etc/firmware"
+#define FIRMWARE_DIR "/lib/firmware"
 #endif
 
 #define FW_EXT ".hcd"
@@ -366,11 +366,8 @@
 		return -1;
 
 	if (bcm43xx_locate_patch(FIRMWARE_DIR, chip_name, fw_path)) {
-		fprintf(stderr, "Patch not found, continue anyway\n");
+		fprintf(stderr, "Patch not found for %s, continue anyway\n", chip_name);
 	} else {
-		if (bcm43xx_set_speed(fd, ti, speed))
-			return -1;
-
 		if (bcm43xx_load_firmware(fd, fw_path))
 			return -1;
 
@@ -380,6 +377,7 @@
 			return -1;
 		}
 
+		sleep(1);
 		if (bcm43xx_reset(fd))
 			return -1;
 	}
--- a/src/bluetooth.conf
+++ b/src/bluetooth.conf
@@ -34,6 +34,10 @@
     <allow send_destination="org.bluez"/>
   </policy>
 
+  <policy group="bluetooth">
+    <allow send_destination="org.bluez"/>
+  </policy>
+
   <policy context="default">
     <deny send_destination="org.bluez"/>
   </policy>
--- a/src/bluetooth.service.in
+++ b/src/bluetooth.service.in
@@ -6,7 +6,7 @@
 [Service]
 Type=dbus
 BusName=org.bluez
-ExecStart=@libexecdir@/bluetoothd
+ExecStart=@libexecdir@/bluetoothd -E
 NotifyAccess=main
 #WatchdogSec=10
 #Restart=on-failure
EOF

# Re-enable tabs
bind '\C-i:complete'

./configure --disable-cups --disable-obex --enable-deprecated --prefix=/usr --libexecdir=/usr/lib --localstatedir=/var/lib/bluetooth/
make -j 4
sudo checkinstall -y --nodoc [email protected]

Node

To install Node, I used the following:

# Install Node
curl -sL https://deb.nodesource.com/setup_6.x | sudo -E bash -
sudo apt-get install -y nodejs

Startup on boot

Raspbian Jesse uses systemd as its init process, so I created a service file for it. Make sure to add your user to the bluetooth group so you can run this application without running as root.

cat << EOF > ble2mqtt@$USER.service
[Unit]
Description=BLE2MQTT Bridge for %i
After=network.target bluetooth.service

[Service]
Type=simple
WorkingDirectory=/home/%i/code/ble2mqtt
ExecStart=/usr/bin/npm start
User=%i
SendSIGKILL=no
Restart=on-failure

[Install]
WantedBy=multi-user.target
EOF

sudo mv ble2mqtt@$USER.service /lib/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable ble2mqtt@$USER.service
sudo systemctl start ble2mqtt@$USER.service

To Do

  • Add configuration file:
    • MQTT settings
    • Single/Split topic for get/set
    • MQTT topic prefix (to distinguish between different instances of the app)
  • Error handling:
    • What happens when an adapter/device is disconnected? Do we need to cleanup anything? What happens to events on removed devices?
  • Pretty names (should be configurable):
    • Allow using different properties as device name
      • Listen on changes in the property used for the device name as if it changes, topic names (both published and subscribed) need to be updated
    • Use service/characteristic name instead of UUID
      • Extendable via configuration file
  • Pretty values (convert byte array to Boolean, String, etc.):
    • Configuration file can define custom characteristics
  • Refactoring
    • Create a separate NPM module out of the BlueZ code
    • Lots of similar code copy-pasted, we can do better
  • Security
    • Support pairing via AgentManager1 API
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].