**MicroPython BLE Library**

Проект представляет собой библиотеку классов, созданную на основе знаний о Micropython BLE. Библиотека предназначена для упрощения использования соответствующих кодов в будущем.

### Проект

На основе ранее полученных знаний о MicroPython BLE была создана библиотека классов. Это сделано для того, чтобы облегчить дальнейшее использование соответствующих кодов.

### BLE-связанные термины

Для облегчения понимания и во избежание неправильного перевода, некоторые термины были объяснены автором. Если есть ошибки, автор просит исправить их.

#### Profile

Можно понимать как документ, описывающий устройство BLE как конкретное устройство с определённой целью, например, как HID-устройство (обычно клавиатура, мышь или джойстик). Для этого необходимо реализовать следующие три услуги:
* Battery Service;
* Device Information;
* Human Interface Device.

Эти три услуги описывают профиль.

#### Services

Предоставленные в проекте услуги, а также последующие характеристики и дескрипторы определяются веб-сайтом Bluetooth® Technology Website. Все люди разрабатывают устройства Bluetooth в соответствии со стандартами. Без дополнительной разработки программного обеспечения наши аппаратные устройства могут быть распознаны и использованы такими устройствами, как ПК и мобильные телефоны.

Роль услуг заключается в информировании центрального устройства о том, какие услуги будет предоставлять наше оборудование. Например, HID-профиль содержит три службы, и центральное устройство распознает его как периферийное устройство клавиатуры.

#### Characteristics

Характеристики можно понимать как атрибуты или параметры услуг. Как и профиль может содержать несколько служб, так и служба может содержать несколько характеристик. Они используются для описания конкретных значений характеристик определённых услуг.

Например, Battery Service включает характеристику Battery Level. Записав значение от 0 до 100, можно сообщить центральному устройству текущий уровень заряда батареи нашего устройства.

#### Descriptors

Как и услуги, каждая характеристика может включать несколько дескрипторов. Роль дескриптора заключается в настройке дополнительных параметров характеристики. Например, некоторые центральные устройства будут отправлять уведомления определённым характеристикам наших периферийных устройств. Дескриптор может настроить, следует ли принимать уведомление.

### Использование

Далее на примере main.py объясняется, как использовать библиотеку классов для создания профиля.

> Предполагается, что вы уже знакомы с основами использования модуля ubluetooth.

#### Импорт файлов библиотеки классов

```python
import ubluetooth as bt
from ble.const import BLEConst
from ble.tools import BLETools
from ble.profile.manager import ProfileManager
from ble.services import *
from ble.characteristics import *
from ble.descriptors import *
```

#### Создание профиля

```python
profile = ProfileManager()

profile.add_services(
    BatteryService().add_characteristics(
        Characteristics(BLEConst.Characteristics.BATTERY_LEVEL, BLEConst.CharacteristicFlags.BATTERY_LEVEL_)
    ),
    HumanInterfaceDevice().add_characteristics(
        Characteristics(BLEConst.Characteristics.REPORT, BLEConst.CharacteristicFlags.REPORT_).add_descriptors(
            ClientCharacteristicConfiguration(),
        )
    ),
)
```
Здесь в профиль добавлены две службы, каждая из которых имеет одну характеристику и один дополнительный дескриптор.
* Батарейная служба (услуга)
    * Уровень заряда батареи (характеристика)
* Устройство интерфейса человека (услуга)
    * Отчёт (характеристика)
        * Конфигурация клиентской характеристики (дескриптор)

Первоначально планировалось использовать более понятный способ создания профиля, например:

```python
# Определение трёх обязательных услуг для HID-устройств
profile.add_services(
    HumanInterfaceDevice().add_characteristics(
        ReportMap(),
        Report(),
        ProtocolMode(),
        HIDInformation(),
        HIDControlPoint(),
        BootMouseInputReport(),
    ),
    DeviceInformation().add_characteristics(
        PNPID(),
    ),
    BatteryService().add_characteristics(
        BatteryLevel(),
    ),
)
```
Однако, учитывая большое количество официальных характеристик, было решено использовать более сложный метод. Однако, поскольку услуг и дескрипторов относительно немного, используется упрощённый метод.

#### Регистрация услуг

Зарегистрируйте услуги, получите дескрипторы и характеристики для взаимодействия с центральным устройством.

> Порядок определения профиля должен соответствовать порядку определения услуг.

```python
ble = bt.BLE()
services = profile.get_services()

(
    (
        handle_battery_level,
    ),
    (
        handle_report,
        handle_handle_report_desc,
    ),
) = ble.gatts_register_services(services)
```

#### Генерация широковещательной информации

Чтобы избежать переполнения широковещательных данных, рекомендуется включить имя устройства в ответ сканирования.

```python
uuids = profile.get_services_uuid()
appearance = BLEConst.Appearance.GENERIC_HEART_RATE_SENSOR

adv_payload = BLETools.advertising_generic_payload(
    services=uuids,
    appearance=appearance
)
resp_payload = BLETools.advertising_resp_payload(
    name="BLELibTest"
)
```

#### Широковещательная информация

Широковещательные данные профиля включают информацию об услугах, которые могут быть проанализированы и отображены для пользователя после получения центральным устройством.

```python
ble.gap_advertise(None)
ble.gap_advertise(interval_us=100000, adv_data=adv_payload, resp_data=resp_payload)
```

#### Передача сообщений на центральное устройство

Сначала запишите значение уровня заряда батареи на устройстве, а затем используйте метод Notify, чтобы уведомить центральное устройство.

```python
import struct

ble.gatts_write(handle_battery_level, struct.pack("<B", int(100)))
ble.gatts_notify(conn_handle, handle_battery_level)
```

handle_battery_level — это дескриптор, полученный при регистрации услуг. conn_handle — это дескриптор соединения, когда центральное устройство подключено.

Это основной метод использования. Давайте посмотрим на эффект.

### Просмотр эффекта

Поскольку пример профиля представляет собой случайный набор данных, его нельзя найти непосредственно на компьютере или мобильном телефоне. Необходимо использовать стороннее приложение, такое как nRF Connect.

![Screenshot01](images/screenshot_01.png)

![Screenshot02](images/screenshot_02.png)

Полный вывод в REPL выглядит следующим образом:

```docs
activating ble...
I (57150) BTDM_INIT: BT controller