mirror of
https://github.com/esphome/esphome-docs.git
synced 2025-01-25 22:11:29 +01:00
Ble client docs (#702)
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
This commit is contained in:
parent
31b91a6b0d
commit
27d19d4207
214
components/ble_client.rst
Normal file
214
components/ble_client.rst
Normal file
@ -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 <automation>`): An automation to perform
|
||||
when the client connects to a device. See :ref:`ble_client-on_connect`.
|
||||
- **on_disconnect** (*Optional*, :ref:`Automation <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 <automation>`
|
||||
- :apiref:`ble_client/ble_client.h`
|
||||
- :ghedit:`Edit`
|
85
components/sensor/ble_sensor.rst
Normal file
85
components/sensor/ble_sensor.rst
Normal file
@ -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 <config-sensor>`.
|
||||
|
||||
Automations:
|
||||
|
||||
- **on_notify** (*Optional*, :ref:`Automation <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`
|
41
components/switch/ble.rst
Normal file
41
components/switch/ble.rst
Normal file
@ -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 <config-switch>`.
|
||||
|
||||
See Also
|
||||
--------
|
||||
|
||||
- :doc:`/components/ble_client`
|
||||
- :apiref:`ble_client/switch/ble_switch.h`
|
||||
- :ghedit:`Edit`
|
114
cookbook/ble_itag.rst
Normal file
114
cookbook/ble_itag.rst
Normal file
@ -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`
|
BIN
cookbook/images/esp32_ble_itag.png
Normal file
BIN
cookbook/images/esp32_ble_itag.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 373 KiB |
@ -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.
|
||||
|
||||
|
BIN
images/esp32_ble_itag.jpg
Normal file
BIN
images/esp32_ble_itag.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 16 KiB |
@ -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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user