Bluez

BlueZ-over-D-Bus client library for Elixir: BLE scanning (passive and active), active GATT connections, pairing, and bluez-alsa A2DP audio — the pieces an ESPHome-style Bluetooth proxy or any BLE-consuming Elixir application needs on embedded Linux.

Built for Nerves devices (read-only rootfs, MuonTrap-supervised daemons) but has no Nerves dependency: it runs on any Linux host where your application may own the system D-Bus instance.

Status

Early extraction from universal_proxy, where this code shipped and was hardware-validated as an ESPHome Bluetooth proxy on Raspberry Pis (passive/active scanning into Home Assistant, GATT connect/read/write/notify/pair against real peripherals, BT-headphone audio). Still being iterated on; not a final API.

Documentation

Start here once you're ready to go beyond the quickstart below:

The core modules carry the reference detail:

Features

Installation

def deps do
[
{:bluez, "~> 0.1"}
]
end

A note on the D-Bus layer: exporting objects (which BlueZ's passive scanning requires) needs a service-side API that isn't in any released D-Bus client, so this library ships a vendored, namespaced copy of rebus as Bluez.Rebus.* (MIT, with the service-side additions proposed upstream in ausimian/rebus#9 — see lib/bluez/rebus/VENDORED.md). The namespacing means this can never collide with a rebus dependency of your own.

Usage

children = [
{Bluez,
client: [on_advertisement: &MyApp.Scanner.on_advertisement/1],
gatt: [on_gatt_event: &MyApp.BLEProxy.gatt_event/2],
desired_adapter: nil, # nil = auto (lowest-index adapter)
audio: true} # bluealsad + Bluez.BlueAlsa
]

Adverts then arrive at your scanner fun as maps (%{address:, rss:, address_type:, raw_data:}), and GATT requests are cast-style with results delivered as events:

Bluez.Gatt.connect(0xAABBCCDDEEFF, [], self())
receive do
{:gatt_connection, addr, {:ok, mtu}} -> Bluez.Gatt.get_services(addr)
{:gatt_connection, _addr, {:error, code}} -> {:error, code}
end

See the host integration guide for the full option surface and event contract.

Runtime requirements

On Nerves none of this is in the official systems — see the Nerves system guide for the full customization list (buildroot packages, kernel fragment, firmware blobs, overlay).

License

Apache-2.0 — see the LICENSE file in the repository.