shmuelzon / esp32-ble2mqtt

A BLE to MQTT bridge running on an ESP32
MIT License
682 stars 108 forks source link
ble bluetooth esp32 gatt mqtt

ESP32-BLE2MQTT

This project is a BLE to MQTT bridge, i.e. it exposes BLE GATT characteristics as MQTT topics for bidirectional communication. It's developed for the ESP32 SoC and is based on ESP-IDF release v5.2.1. Note that using any other ESP-IDF version might not be stable or even compile.

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.

Characteristics supporting notifications will automatically be registered on and new values will be published once available. It's also possible to proactively issue a read request by publishing any value to the topic using the above format suffixed with '/Get'. Note that values are strings representing the characteristic values based on their definitions grabbed from http://bluetooth.org. For example, a battery level of 100% (0x64) will be sent as a string '100'.

In order to set a GATT value, publish a message to a writable characteristic using the above format suffixed with /Set. Payload should be of the same format described above and will be converted, when needed, before sending to the BLE peripheral.

In addition to the characteristic values, the BLE2MQTT devices also publish additional topics to help book-keeping:

Broadcasters

Broadcasters are non-connectable BLE devices that only send advertisements. This application supports publishing these advertisements over MQTT. For each broadcaster, at-least two topics are published:

In addition, depending on the broadcaster type and payload, additional meta-data is published.

Note: Broadcaster topics are published without the retained flag regardless of what's defined in the configuration file.

Compiling

  1. Install ESP-IDF

You will first need to install the Espressif IoT Development Framework. The Installation Instructions have all of the details. Make sure to follow ALL the steps, up to and including step 4 where you set up the tools and the get_idf alias.

  1. Download the repository and its dependencies:
git clone --recursive https://github.com/shmuelzon/esp32-ble2mqtt
  1. Modify the config.json and flash

Modify the configuration file to fit your environment, build and flash (make sure to modify the serial device your ESP32 is connected to):

idf.py build flash

Remote Logging

If configured, the application can send the logs remotely via UDP to another host to allow receiving logs from remote devices without a serial connection. To receive these logs on your host, execute idf.py remote-monitor.

Configuration

The configuration file provided in located at data/config.json in the repository. It contains all of the different configuration options.

The network section should contain either a wifi section or an eth section. If case there are both, the eth section has preference over the wifi section.

Optionally, the network section can contain a hostname which, if set, is used in MQTT subscriptions as well. In such case, relace BLE2MQTT-XXX in this documentation with the hostname you have set.

The wifi section below includes the following entries:

{
  "network": {
    "hostname": "MY_HOSTNAME",
    "wifi": {
      "ssid": "MY_SSID",
      "password": "MY_PASSWORD",
      "eap": {
        "method": null,
        "identity": null,
        "client_cert": null,
        "client_key": null,
        "server_cert": null,
        "username": null,
        "password": null
      }
    }
  }
}

The eth section below includes the following entries:

{
  "network": {
    "eth": {
      "phy": "MY_ETH_PHY",
      "phy_power_pin": -1
    }
  }
}

Note: Defining the eth section will disable WiFi

The mqtt section below includes the following entries:

{
  "mqtt": {
    "server": {
      "host": "192.168.1.1",
      "port": 1883,
      "ssl": false,
      "client_cert": null,
      "client_key": null,
      "server_cert": null,
      "username": null,
      "password": null,
      "client_id": null
    },
    "publish": {
      "qos": 0,
      "retain": true
    },
    "topics" :{
      "prefix": "",
      "get_suffix": "/Get",
      "set_suffix": "/Set"
    }
  }
}

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

{
  "ble": {
    "//Optional: 'whitelist' or 'blacklist'": [],
    "services": {
      "definitions": {},
      "//Optional: 'whitelist' or 'blacklist'": []
    },
    "characteristics": {
      "definitions": {},
      "//Optional: 'whitelist' or 'blacklist'": []
    },
    "passkeys": {},
    "mikeys": {}
  }
}

The optional log section below includes the following entries:

{
  "log": {
    "host": "224.0.0.200",
    "port": 5000
  }
}

OTA

It is possible to upgrade both firmware and configuration file over-the-air once an initial version was flashed via serial interface. To do so, execute: idf.py upload or idf.py upload-config accordingly. The above will upgrade all BLE2MQTT devices connected to the MQTT broker defined in the configuration file. It is also possible to upgrade a specific device by adding the OTA_TARGET variable to the above command set to the host name of the requested device, e.g.:

OTA_TARGET=BLE2MQTT-470C idf.py upload

Note: In order to avoid unneeded upgrades, there is a mechanism in place to compare the new version with the one that resides on the flash. For the firmware image it's based on the git tag and for the configuration file it's an MD5 hash of its contents. In order to force an upgrade regardless of the currently installed version, run idf.py force-upload or idf.py force-upload-config respectively.

Board Compatibility

The sdkconfig.defaults included in this project covers common configurations.

Olimex ESP32-POE

A number of minor changes are required to support this board: