Skip to content

Commit b1b855e

Browse files
[esp32_ble_server] Create custom BLE services, characteristics and descriptors (#4002)
Co-authored-by: Clyde Stubbs <[email protected]>
1 parent 88d2adb commit b1b855e

File tree

1 file changed

+243
-6
lines changed

1 file changed

+243
-6
lines changed

components/esp32_ble_server.rst

+243-6
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,8 @@ BLE Server
55
:description: Instructions for setting up Bluetooth LE GATT Server in ESPHome.
66
:image: bluetooth.svg
77

8-
The ``esp32_ble_server`` component in ESPHome sets up a simple BLE GATT server that exposes the device name,
9-
manufacturer and board. This component allows other components to create their own services to expose
10-
data and control.
8+
The ``esp32_ble_server`` component in ESPHome sets up a BLE GATT server that exposes the device name,
9+
manufacturer and board. BLE GATT services and characteristics can be added to the server to expose data and control.
1110

1211
.. warning::
1312

@@ -24,17 +23,255 @@ data and control.
2423
esp32_ble_server:
2524
manufacturer: "Orange"
2625
manufacturer_data: [0x4C, 0, 0x23, 77, 0xF0 ]
26+
on_connect:
27+
- lambda: |-
28+
ESP_LOGD("BLE", "Connection from %d", id);
29+
on_disconnect:
30+
- lambda: |-
31+
ESP_LOGD("BLE", "Disconnection from %d", id);
2732
2833
2934
Configuration variables:
3035
------------------------
3136

32-
- **manufacturer** (*Optional*, string): The name of the manufacturer/firmware creator. Defaults to ``ESPHome``.
33-
- **model** (*Optional*, string): The model name of the device. Defaults to the friendly name of the ``board`` chosen
34-
in the :ref:`core configuration <esphome-configuration_variables>`.
37+
- **manufacturer** (*Optional*, :ref:`esp32_ble_server-value`): The name of the manufacturer/firmware creator. Defaults to ``ESPHome``.
38+
- **model** (*Optional*, :ref:`esp32_ble_server-value`): The model name of the device. Defaults to the project's name defined in the :ref:`core configuration <esphome-creators_project>` if present, otherwise to the friendly name of the ``board`` chosen in the :ref:`core configuration <esphome-configuration_variables>`.
39+
- **firmware_version** (*Optional*, :ref:`esp32_ble_server-value`): The firmware version of the device. Defaults to the project's version defined in the :ref:`core configuration <esphome-creators_project>` if present, otherwise to the ESPHome version.
3540
- **manufacturer_data** (*Optional*, list of bytes): The manufacturer-specific data to include in the advertising
3641
packet. Should be a list of bytes, where the first two are the little-endian representation of the 16-bit
3742
manufacturer ID as assigned by the Bluetooth SIG.
43+
- **on_connect** (*Optional*, :ref:`Automation <automation>`): An action to be performed when a client connects to the BLE server. It provides the ``id`` variable which contains the ID of the client that connected.
44+
- **on_disconnect** (*Optional*, :ref:`Automation <automation>`): An action to be performed when a client disconnects from the BLE server. It provides the ``id`` variable which contains the ID of the client that disconnected.
45+
- **services** (*Optional*, list of :ref:`esp32_ble_server-service`): A list of services to expose on the BLE GATT server.
46+
47+
48+
.. _esp32_ble_server-service:
49+
50+
Service Configuration
51+
---------------------
52+
53+
Services are the main way to expose data and control over BLE. Services communicate with the client through characteristics. Each service can have multiple characteristics.
54+
55+
.. code-block:: yaml
56+
57+
esp32_ble_server:
58+
services:
59+
- uuid: 2a24b789-7aab-4535-af3e-ee76a35cc42d
60+
advertise: false
61+
characteristics:
62+
- uuid: cad48e28-7fbe-41cf-bae9-d77a6c233423
63+
read: true
64+
value:
65+
value: "Hello, World!"
66+
67+
68+
Configuration variables:
69+
70+
- **uuid** (*Required*, string, int): The UUID of the service.
71+
- **advertise** (*Optional*, boolean): If the service should be advertised. Defaults to ``false``.
72+
- **characteristics** (*Optional*, list of :ref:`esp32_ble_server-characteristic`): A list of characteristics to expose in this service.
73+
74+
75+
.. _esp32_ble_server-characteristic:
76+
77+
Characteristic Configuration
78+
----------------------------
79+
80+
Characteristics expose data and control for a BLE service. Each characteristic has a value that may be readable and or writable, and may permit a client to subscribe to notifications.
81+
Characteristics can also have multiple descriptors to provide additional information about the characteristic.
82+
83+
.. code-block:: yaml
84+
85+
esp32_ble_server:
86+
services:
87+
# ...
88+
characteristics:
89+
- id: test_characteristic
90+
uuid: cad48e28-7fbe-41cf-bae9-d77a6c233423
91+
advertise: true
92+
description: "Sample description"
93+
read: true
94+
value:
95+
data: "123.1"
96+
type: float
97+
endianness: BIG
98+
descriptors:
99+
- uuid: cad48e28-7fbe-41cf-bae9-d77a6c211423
100+
value: "Hello, World Descriptor!"
101+
102+
103+
Configuration variables:
104+
105+
- **id** (*Optional*, string): An ID to refer to this characteristic in automations.
106+
- **uuid** (*Required*, string, int): The UUID of the characteristic.
107+
- **description** (*Optional*, :ref:`esp32_ble_server-value`): The description of the characteristic - not templatable. It will add a ``CUD`` descriptor (0x2901) to the characteristic with the value of the description.
108+
- **read** (*Optional*, boolean): If the characteristic should be readable. Defaults to ``false``.
109+
- **write** (*Optional*, boolean): If the characteristic should be writable. Defaults to ``false``.
110+
- **broadcast** (*Optional*, boolean): If the characteristic should be broadcast. Defaults to ``false``.
111+
- **notify** (*Optional*, boolean): If the characteristic supports notifications. If ``true``, a ``CCCD`` descriptor will be automatically added to the characteristic. Defaults to ``false``.
112+
- **indicate** (*Optional*, boolean): If the characteristic supports indications. If ``true``, a ``CCCD`` descriptor will be automatically added to the characteristic. Defaults to ``false``.
113+
- **write_no_response** (*Optional*, boolean): If the characteristic should be writable without a response. Defaults to ``false``.
114+
- **value** (*Optional*, :ref:`esp32_ble_server-value`): The value of the characteristic.
115+
- **descriptors** (*Optional*, list of :ref:`esp32_ble_server-descriptor`): A list of descriptors to expose in this characteristic.
116+
- **on_write** (*Optional*, :ref:`Automation <automation>`): An action to be performed when the characteristic is written to. The characteristic must have the ``write`` property. See :ref:`esp32_ble_server-characteristic-on_write`.
117+
118+
119+
.. _esp32_ble_server-descriptor:
120+
121+
Descriptor Configuration
122+
------------------------
123+
124+
Descriptors are optional and are used to provide additional information (metadata) about a characteristic.
125+
126+
.. code-block:: yaml
127+
128+
esp32_ble_server:
129+
services:
130+
- uuid: # ...
131+
characteristics:
132+
- uuid: # ...
133+
descriptors:
134+
- uuid: 2901
135+
value:
136+
value: "Hello, World Descriptor!"
137+
138+
139+
Configuration variables:
140+
141+
- **id** (*Optional*, string): An ID to refer to this descriptor in automations.
142+
- **uuid** (*Required*, string, int): The UUID of the descriptor.
143+
- **value** (*Required*, :ref:`esp32_ble_server-value`): The value of the descriptor. :ref:`templatable <config-templatable>` values are not allowed. In order to set the value of a descriptor dynamically, use the :ref:`esp32_ble_server-descriptor-set_value` action.
144+
145+
146+
.. _esp32_ble_server-value:
147+
148+
Value Configuration
149+
-------------------
150+
151+
Values can be of different types and are used to define the value of a characteristic or descriptor.
152+
The value of a characteristic is templatable. If the value is templated, the template will be evaluated each time the characteristic is read, or a notification is triggered. The value of a descriptor is not templatable as it is expected to be static.
153+
154+
155+
.. code-block:: yaml
156+
157+
esp32_ble_server:
158+
services:
159+
- uuid: # ...
160+
characteristics:
161+
- uuid: # ...
162+
# Simple value (auto-detect type)
163+
value: "Hello, World!"
164+
- uuid: # ...
165+
# String value
166+
value:
167+
data: "Hello, World!"
168+
type: string
169+
string_encoding: utf-8
170+
- uuid: # ...
171+
# Integer value
172+
value:
173+
data: "123"
174+
type: uint16_t
175+
endianness: LITTLE
176+
- uuid: # ...
177+
# Array of bytes value
178+
value:
179+
data: [9, 9, 9]
180+
- uuid: # ...
181+
# Lambda value
182+
value:
183+
data: !lambda 'return std::vector<uint8_t>({9, 9, 9});'
184+
- uuid: # ...
185+
# Lambda value using ByteBuffer
186+
value:
187+
data: !lambda 'return bytebuffer::ByteBuffer::wrap(0.182).get_data();'
188+
189+
Configuration variables:
190+
191+
- **data** (*Required*, string, int, float, boolean, list of bytes, :ref:`templatable <config-templatable>`): The value of the characteristic or descriptor. For :ref:`templatable <config-templatable>` values, the lambda function must return a ``std::vector<uint8_t>`` (you may use the ``bytebuffer::ByteBuffer`` helper class to transform different data types into a byte array). The value is computed each time the characteristic is read.
192+
- **type** (*Optional*, string): The C++ type of the value. The available values are ``uint8_t``, ``uint16_t``, ``uint32_t``, ``uint64_t``, ``int8_t``, ``int16_t``, ``int32_t``, ``int64_t``, ``float``, ``double`` and ``string``. It must be defined if the value is not :ref:`templatable <config-templatable>`.
193+
- **endianness** (*Optional*, string): The endianness of the value. Can be ``BIG`` or ``LITTLE``. Defaults to ``LITTLE``.
194+
- **string_encoding** (*Optional*, string): The encoding of the string. Only applicable if the type is ``string``. The conversion is done in Python before compilation, so the encoding must be a valid [Python encoding](https://docs.python.org/3/library/codecs.html#standard-encodings). Defaults to ``utf-8``.
195+
196+
197+
.. _esp32_ble_server-characteristic-on_write:
198+
199+
``on_write`` Trigger
200+
--------------------
201+
202+
With this configuration option you can write complex automations that are triggered when a characteristic is written to. It provides the ``x`` variable which contains the new value of the characteristic as a ``std::vector<uint8_t>`` and the ``id`` variable which contains the ID of the client that wrote to the characteristic.
203+
204+
.. code-block:: yaml
205+
206+
esp32_ble_server:
207+
services:
208+
- uuid: # ...
209+
characteristics:
210+
# ...
211+
write: true
212+
on_write:
213+
then:
214+
- lambda: |-
215+
ESP_LOGD("BLE", "Descriptor received: %s from %d", std::string(x.begin(), x.end()).c_str(), id);
216+
217+
218+
``ble_server.characteristic.set_value`` Action
219+
----------------------------------------------
220+
221+
This action sets the value of a characteristic. A characteristic may not have a set_value action if it also has a templated value in its configuration.
222+
223+
.. code-block:: yaml
224+
225+
on_...:
226+
then:
227+
- ble_server.characteristic_set_value:
228+
id: test_write_characteristic
229+
value: [0, 1, 2]
230+
231+
232+
Configuration variables:
233+
234+
- **id** (*Required*, string): The ID of the characteristic to set the value of.
235+
- **value** (*Required*, :ref:`esp32_ble_server-value`): The new value of the characteristic.
236+
237+
238+
``ble_server.characteristic.notify`` Action
239+
-------------------------------------------
240+
241+
This action triggers a notification to the client. The value sent will be the current value of the characteristic, or the value from evaluation of the template, if present.
242+
243+
.. code-block:: yaml
244+
245+
on_...:
246+
then:
247+
- ble_server.characteristic_notify:
248+
id: test_notify_characteristic
249+
250+
Configuration variables:
251+
- **id** (*Required*, string): The ID of the characteristic to notify the client about (must have the ``notify`` property).
252+
253+
254+
.. _esp32_ble_server-descriptor-set_value:
255+
256+
``ble_server.descriptor.set_value`` Action
257+
----------------------------------------------
258+
259+
This action sets the value of a descriptor.
260+
261+
.. code-block:: yaml
262+
263+
on_...:
264+
then:
265+
- ble_server.descriptor:
266+
id: test_write_descriptor
267+
value: [0, 1, 2]
268+
269+
270+
Configuration variables:
271+
272+
- **id** (*Required*, string): The ID of the descriptor to set the value of.
273+
- **value** (*Required*, :ref:`esp32_ble_server-value`): The new value of the descriptor.
274+
38275

39276
See Also
40277
--------

0 commit comments

Comments
 (0)