diff --git a/components/ble_client.rst b/components/ble_client.rst new file mode 100644 index 000000000..452342c8c --- /dev/null +++ b/components/ble_client.rst @@ -0,0 +1,214 @@ +BLE Client +========== + +.. seo:: + :description: Configuration of the BLE client on ESP32. + :image: bluetooth.svg + +The ``ble_client`` component enables connections to Bluetooth +Low Energy devices in order to query and control them. This +component does not expose any sensors or output components itself, +but merely manages connections to them for use by other components. + +.. note:: + + The BLE software stack on the ESP32 consumes a significant + amount of RAM on the device. As such, you may experience + frequent crashes due to out-of-memory if you enable many + other components. + + A maximum of three devices is supported due to limitations in the + ESP32 BLE stack. If you wish to connect more devices, use additional + ESP32 boards. + + This component does not (yet) support devices that require + security settings (eg connecting with a PIN). + + Currently, devices connected with the client cannot be + supported by other components based on :doc:`/components/esp32_ble_tracker` + as they listen to advertisements which are only sent by devices + without an active connection. + +Despite the last point above, the ``ble_client`` component requires +the ``esp32_ble_tracker`` component in order to discover available +client devices. + +.. code-block:: yaml + + esp32_ble_tracker: + + ble_client: + - mac_address: FF:FF:20:00:0F:15 + id: itag_black + +Configuration variables: +------------------------ + +- **mac_address** (*Required*, MAC Address): The MAC address of the BLE device to connect to. +- **id** (*Required*, :ref:`config-id`): The ID to use for code generation, and for reference by dependent components. + +Automations: + +- **on_connect** (*Optional*, :ref:`Automation `): An automation to perform + when the client connects to a device. See :ref:`ble_client-on_connect`. +- **on_disconnect** (*Optional*, :ref:`Automation `): An automation to perform + when the client disconnects from a device. See :ref:`ble_client-on_disconnect`. + +BLE Client Automation +--------------------- + +.. _ble_client-on_connect: + +``on_connect`` +************** + +This automation is triggered when the client connects to the BLE device. + +.. code-block:: yaml + + ble_client: + - mac_address: 11:22:33:44:55:66 + id: ble_itag + on_connect: + then: + - lambda: |- + ESP_LOGD("ble_client_lambda", "Connected to BLE device"); + +.. _ble_client-on_disconnect: + +``on_disconnect`` +***************** + +This automation is triggered when the client disconnects from a BLE device. + +.. code-block:: yaml + + ble_client: + - mac_address: 11:22:33:44:55:66 + id: ble_itag + on_disconnect: + then: + - lambda: |- + ESP_LOGD("ble_client_lambda", "Disconnected from BLE device"); + +BLE Overview +------------ +This section gives a brief overview of the Bluetooth LE architecture +to help with understanding this and the related components. There are +plenty of more detailed references online. + +BLE uses the concept of a *server* and a *client*. In simple terms, +the server is implemented on the device providing services, usually +these are the devices such as heart monitors, tags, weather stations, +etc. The client connects to the server and makes use of its services. +The client will often be an app on a phone, or in the case of ESPHome, +it's the ESP32 device. + +When a client connects to a server, the client queries for *services* +provided by the server. Services expose categories of functionality +on the server. These might be well defined and supported services, +such as the Battery Level service, Device Information or Heart Rate. +Or they might be custom services designed just for that device. For +example the button on cheap iTags uses a custom service. + +Each service then defines one or more *characteristics* which are +typically the discrete values of that service. For example for the +Environmental Sensor service characteristics exposed include the +Wind Speed, Humidity and Rainfall. Each of these may be read-only +or read-write, depending on their functionality. + +A characteristic may also expose one or more *descriptors*, which carry +further information about the characteristic. This could be things +like the units, the valid ranges, and whether notifications (see below) +are enabled. + +BLE also supports *notifications*. A client continuously polling for +updates could consume a lot of power, which is undesirable for a +protocol that's designed to be low energy. Instead, a server can push +updates to the client only when they change. Depending on their purpose +and design, a characteristic may allow for notifications to be sent. The +client can then enable notifications by setting the configuration +descriptor for the characteristic. + +Each service, characteristic, and descriptor is identified by a +unique identifier (UUID) that may be between 16 and 128 bits long. +A client will typically identify a device's capabilities based on +the UUIDs. + +Once the connection is established, referencing each +service/characteristic/descriptor by the full UUID would take a +considerable portion of the small (~23 byte) packet. So the +characteristics and descriptors also provide a small 2-byte +*handle* (alias) to maximise available data space. + +Setting Up Devices +------------------ + +Whilst the component can connect to most BLE devices (that do not +require authentication/pin), useful functionality is only obtained +through dependent components, such as :doc:`/components/sensor/ble_sensor`. +See the documentation for these components for details on setting up +specific devices. + +In order to use the ``ble_client`` component, you need to enable the +:doc:`/components/esp32_ble_tracker` component. This will also allow you to discover +the MAC address of the device. + +When you have discovered the MAC address of the device, you can add it +to the ``ble_client`` stanza. + +If you then build and upload this configuration, the ESP will listen for +the device and attempt to connect to it when it is discovered. The component +will then query the device for all available services and characteristics and +display them in the log: + +.. code-block:: text + + [18:24:56][D][ble_client:043]: Found device at MAC address [FC:58:FA:B1:F8:93] + [18:24:56][I][ble_client:072]: Attempting BLE connection to fc:58:fa:b1:f8:93 + [18:24:56][I][ble_client:097]: [fc:58:fa:b1:f8:93] ESP_GATTC_OPEN_EVT + [18:24:57][I][ble_client:143]: Service UUID: 0x1800 + [18:24:57][I][ble_client:144]: start_handle: 0x1 end_handle: 0x5 + [18:24:57][I][ble_client:305]: characteristic 0x2A00, handle 0x3, properties 0x2 + [18:24:57][I][ble_client:305]: characteristic 0x2A01, handle 0x5, properties 0x2 + [18:24:57][I][ble_client:143]: Service UUID: 0x1801 + [18:24:57][I][ble_client:144]: start_handle: 0x6 end_handle: 0x6 + [18:24:57][I][ble_client:143]: Service UUID: 0x180A + [18:24:57][I][ble_client:144]: start_handle: 0x7 end_handle: 0x19 + [18:24:57][I][ble_client:305]: characteristic 0x2A29, handle 0x9, properties 0x2 + [18:24:57][I][ble_client:305]: characteristic 0x2A24, handle 0xb, properties 0x2 + [18:24:57][I][ble_client:305]: characteristic 0x2A25, handle 0xd, properties 0x2 + [18:24:57][I][ble_client:305]: characteristic 0x2A27, handle 0xf, properties 0x2 + [18:24:57][I][ble_client:305]: characteristic 0x2A26, handle 0x11, properties 0x2 + [18:24:57][I][ble_client:305]: characteristic 0x2A28, handle 0x13, properties 0x2 + [18:24:57][I][ble_client:305]: characteristic 0x2A23, handle 0x15, properties 0x2 + [18:24:57][I][ble_client:305]: characteristic 0x2A2A, handle 0x17, properties 0x2 + [18:24:57][I][ble_client:305]: characteristic 0x2A50, handle 0x19, properties 0x2 + [18:24:57][I][ble_client:143]: Service UUID: F000FFC0045140-00B0-0000-0000-000000 + [18:24:57][I][ble_client:144]: start_handle: 0x1a end_handle: 0x22 + [18:24:57][I][ble_client:305]: characteristic F000FFC1045140-00B0-0000-0000-000000, handle 0x1c, properties 0x1c + [18:24:57][I][ble_client:343]: descriptor 0x2902, handle 0x1d + [18:24:57][I][ble_client:343]: descriptor 0x2901, handle 0x1e + [18:24:57][I][ble_client:305]: characteristic F000FFC2045140-00B0-0000-0000-000000, handle 0x20, properties 0x1c + [18:24:57][I][ble_client:343]: descriptor 0x2902, handle 0x21 + [18:24:57][I][ble_client:343]: descriptor 0x2901, handle 0x22 + [18:24:57][I][ble_client:143]: Service UUID: 0xFFE0 + [18:24:57][I][ble_client:144]: start_handle: 0x23 end_handle: 0x26 + [18:24:57][I][ble_client:305]: characteristic 0xFFE1, handle 0x25, properties 0x10 + [18:24:57][I][ble_client:343]: descriptor 0x2902, handle 0x26 + [18:24:57][I][ble_client:143]: Service UUID: 0x1802 + [18:24:57][I][ble_client:144]: start_handle: 0x27 end_handle: 0x29 + [18:24:57][I][ble_client:305]: characteristic 0x2A06, handle 0x29, properties 0x4 + + +The discovered services can then be used to enable and configure other +ESPHome components, for example Service UUID 0xFFE0 is used for iTag style +keychain button events, used by the :doc:`/components/sensor/ble_sensor` component. + +See Also +-------- + +- :doc:`/components/sensor/ble_sensor` +- :ref:`Automation ` +- :apiref:`ble_client/ble_client.h` +- :ghedit:`Edit` diff --git a/components/sensor/ble_sensor.rst b/components/sensor/ble_sensor.rst new file mode 100644 index 000000000..bc57cbb92 --- /dev/null +++ b/components/sensor/ble_sensor.rst @@ -0,0 +1,85 @@ +BLE Sensor +========== + +.. seo:: + :description: Fetch numeric values from BLE devices. + :image: bluetooth.svg + +The ``ble_sensor`` component is a sensor platform that can +query BLE devices for specific values of service characteristics. + +For more information on BLE services and characteristics, see +:doc:`/components/ble_client`. + +.. code-block:: yaml + + esp32_ble_tracker: + + ble_client: + - mac_address: FF:FF:20:00:0F:15 + id: itag_black + + sensor: + - platform: ble_client + ble_client_id: itag_black + name: "iTag battery level" + service_uuid: '180f' + characteristic_uuid: '2a19' + icon: 'mdi:battery' + unit_of_measurement: '%' + +Configuration variables: +------------------------ + +- **ble_client_id** (**Required**, :ref:`config-id`): ID of the associated BLE client. +- **service_uuid** (**Required**, UUID): UUID of the service on the device. +- **characteristic_uuid** (**Required**, UUID): UUID of the service's characteristic to query. +- **descriptor_uuid** (*Optional*, UUID): UUID of the characteristic's descriptor to query. +- **id** (*Optional*, :ref:`config-id`): The ID to use for code generation, and for reference by dependent components. +- **notify** (*Optional*, boolean): Instruct the server to send notifications for this + characteristic. +- **update_interval** (*Optional*, :ref:`config-time`): The interval to poll the device. +- All other options from :ref:`Sensor `. + +Automations: + +- **on_notify** (*Optional*, :ref:`Automation `): An automation to + perform when a notify message is received from the device. See :ref:`ble_sensor-on_notify`. + +BLE Sensor Automation +--------------------- + +.. _ble_sensor-on_notify: + +``on_notify`` +************* + +This automation is triggered when the device/server sends a notify message for +a characteristic. The config variable *notify* must be true or this will have +no effect. +A variable ``x`` of type ``float`` is passed to the automation for use in lambdas. + +Example UUIDs +------------- +The UUIDs available on a device are dependent on the type of +device and the functionality made available. Check the ESPHome +device logs for those that are found on the device. + +Some common ones: + ++----------+------------------+-----------------------+ +| Service | Characteristic | Description | ++==========+==================+=======================+ +| 180F | 2A19 | Battery level | ++----------+------------------+-----------------------+ +| 181A | 2A6F | Humidity | ++----------+------------------+-----------------------+ + + +See Also +-------- + +- :doc:`/components/ble_client` +- :ref:`sensor-filters` +- :apiref:`ble_sensor/ble_sensor.h` +- :ghedit:`Edit` diff --git a/components/switch/ble.rst b/components/switch/ble.rst new file mode 100644 index 000000000..eaf225736 --- /dev/null +++ b/components/switch/ble.rst @@ -0,0 +1,41 @@ +BLE Switch +========== + +.. seo:: + :description: Control the state of BLE clients. + :image: bluetooth.svg + +The ``ble_switch`` component is a switch platform that is used to enable +and disable a ``ble_client``. This has several uses, such as minimising +battery usage or for allowing other clients (Eg phone apps) to connect to +the device. + +For more information on BLE services and characteristics, see +:doc:`/components/ble_client`. + +.. code-block:: yaml + + esp32_ble_tracker: + + ble_client: + - mac_address: FF:FF:20:00:0F:15 + id: itag_black + + switch: + - platform: ble_client + ble_client_id: itag_black + name: "Enable iTag" + +Configuration variables: +------------------------ + +- **ble_client_id** (**Required**, :ref:`config-id`): ID of the associated BLE client. +- **id** (**Optional**, :ref:`config-id`): The ID to use for code generation, and for reference by dependent components. +- All other options from :ref:`Switch `. + +See Also +-------- + +- :doc:`/components/ble_client` +- :apiref:`ble_client/switch/ble_switch.h` +- :ghedit:`Edit` diff --git a/cookbook/ble_itag.rst b/cookbook/ble_itag.rst new file mode 100644 index 000000000..463dc0483 --- /dev/null +++ b/cookbook/ble_itag.rst @@ -0,0 +1,114 @@ +BLE iTag Button +=============== + +.. seo:: + :description: Receive events from a cheap BLE keyring button. + :image: bluetooth.svg + +This example shows how to use a cheap BLE keyring tag to trigger arbitrary +events. An ESP32 is used, which provides a BLE peripheral. + +.. figure:: images/esp32_ble_itag.png + :align: center + :width: 40% + +These tags can be had for a couple of dollars each and run for several months +on a coin cell. Using the BLE features of ESPHome, you can use these as small +and cheap remotes to control any automation. + +Quickstart +---------- + +Use the configuration block below for a basic setup which will provide a +binary_sensor that is momentarily turned on when the button is pressed. + +You will need to find the MAC address of your tag. See the documentation +for :doc:`/components/ble_client` for how to find this out. You may also +wish to change the name and id fields where appropriate to suit your +device(s). + +Note that a maximum of three devices are supported due to limitations in +the ESP32's BLE stack. + +Configuration example: +------------------------ + +.. code-block:: yaml + + esp32_ble_tracker: + + ble_client: + # Replace with the MAC address of your device. + - mac_address: FF:FF:20:00:0F:15 + id: itag_black + + binary_sensor: + - platform: template + id: black_button + name: "Black iTag Button" + filters: + delayed_off: 200ms + + sensor: + # This entry registers and awaits notifications for the + # characteristic that signals button presses. Each time + # a notification is received, the corresponding binary_sensor + # is briefly toggled. + - platform: ble_client + ble_client_id: itag_black + name: "Black iTag btn" + service_uuid: 'ffe0' + char_uuid: 'ffe1' + notify: true + update_interval: never + on_notify: + then: + - binary_sensor.template.publish: + id: black_button + state: ON + - binary_sensor.template.publish: + id: black_button + state: OFF + # This entry queries the battery level. Some tags may not + # support this characteristic, you will see 'Unknown' in the + # HA frontent. + - platform: ble_client + ble_client_id: itag_black + name: "Black iTag Battery" + service_uuid: '180f' + char_uuid: '2a19' + icon: 'mdi:battery' + unit_of_measurement: '%' + +Explanation +----------- + +The first thing enabled is the ``esp32_ble_tracker`` component. This sets up +the BLE stack on the device and listens for available devices. + +Next, the ``ble_client`` component will listen to devices discovered by +the tracker, and establish a connection to the given device when it is +available. + +The ``binary_sensor`` provides a template sensor which will export to the +HA frontend the sensor that's switched by the BLE tag's button. + +The first entry in the ``sensor`` component is used to configure the specific +Service and Characteristic UUIDs for an iTag's button. It also enables BLE +notifications and sets up an automation to toggle the ``binary_sensor`` when +a notification is received from the tag. Automatic updates are disabled, there +is no point querying the tag for the device state, as we will be immediately +notified when the button is pressed. + +The next ``sensor`` entry listens for a well-known Service and Chacteristic +that is used by many BLE devices to give battery level information. This sensor +will be exposed in the HA frontend to determine the state of the tag's battery. +Note that many tags will not provide this service, so you will not see a valid +value. If not, you can remove this from the config. + +See Also +-------- + +- :doc:`/components/ble_client` +- :doc:`/components/sensor/ble_sensor` +- :ghedit:`Edit` diff --git a/cookbook/images/esp32_ble_itag.png b/cookbook/images/esp32_ble_itag.png new file mode 100644 index 000000000..cb3051f0e Binary files /dev/null and b/cookbook/images/esp32_ble_itag.png differ diff --git a/guides/contributing.rst b/guides/contributing.rst index fd285671b..8b9c1d79d 100644 --- a/guides/contributing.rst +++ b/guides/contributing.rst @@ -543,7 +543,8 @@ loader. These are: - ``DEPENDENCIES``: Mark the component to depend on other components. If the user hasn't explicitly added these components in their configuration, a validation error will be generated. - ``AUTO_LOAD``: Automatically load an integration if the user hasn't added it manually. -- ``MULTI_CONF``: Mark this component to accept an array of configurations. +- ``MULTI_CONF``: Mark this component to accept an array of configurations. If this is an + integer instead of a boolean, validation will only permit the given number of entries. - ``CONFLICTS_WITH``: Mark a list of components as conflicting with this integration. If the user has one of them in the config, a validation error will be generated. diff --git a/images/esp32_ble_itag.jpg b/images/esp32_ble_itag.jpg new file mode 100644 index 000000000..34ece0dc0 Binary files /dev/null and b/images/esp32_ble_itag.jpg differ diff --git a/index.rst b/index.rst index 31995209b..4ef6e196b 100644 --- a/index.rst +++ b/index.rst @@ -104,6 +104,7 @@ Sensor Components BH1750, components/sensor/bh1750, bh1750.jpg Binary Sensor Map, components/sensor/binary_sensor_map, binary_sensor_map.jpg BLE RSSI, components/sensor/ble_rssi, bluetooth.svg + BLE Sensor, components/sensor/ble_sensor, bluetooth.svg BME280, components/sensor/bme280, bme280.jpg BME680, components/sensor/bme680, bme680.jpg BME680 via BSEC, components/sensor/bme680_bsec, bme680.jpg @@ -270,6 +271,7 @@ Switch Components UART Switch, components/switch/uart, uart.svg Custom Switch, components/switch/custom, language-cpp.svg Tuya Switch, components/switch/tuya, tuya.png + BLE Switch, components/switch/ble, bluetooth.svg Fan Components -------------- @@ -359,6 +361,7 @@ Misc Components Sun, components/sun, weather-sunny.svg GPS, components/gps, crosshairs-gps.svg + ESP32 BLE Client, components/ble_client, bluetooth.svg ESP32 BLE Tracker, components/esp32_ble_tracker, bluetooth.svg ESP32 BLE Beacon, components/esp32_ble_beacon, bluetooth.svg ESP32 Ethernet, components/ethernet, ethernet.svg @@ -423,6 +426,7 @@ Cookbook Teckin SB50, cookbook/teckin_sb50, teckin_sb50.jpg Sonoff light switch options, cookbook/sonoff-light-switch, light_switch.png ESP32 Water Leak Detector, cookbook/leak-detector-m5stickC, leak-detector-m5stickC_main_index.jpg + ESP32 BLE iTag Button, cookbook/ble_itag, esp32_ble_itag.jpg IAQ (Indoor Air Quality) Board, cookbook/iaq_board, iaq_board2.jpg Custom UART Text Sensor, cookbook/uart_text_sensor, language-cpp.svg