## Размер буфера
При помощи `.setBufferSize(uint16_t size)` можно установить размер буфера отправки пакета с компонентами панели управления в ручном режиме. 
- При размере `0` пакет будет собран полностью и строка займет столько, сколько весит пакет компонентов
- При другом указанном размере буфера обработчик `.onManual()` будет вызываться с частями пакета для отправки, а строка не будет превышать указанную длину!

## Stream режим
Библиотека сама может обрабатывать один `Stream`-канал связи, который передаёт данные с любого источника. Например `Serial` для связи по Serial (тип `GH_SERIAL`), `SoftwareSerial` или `BluetoothSerial` для работы с Bluetooth и прочими uart-штуками. Для включения перехвата сообщений нужно подключить объект класса `Stream` и указать тип связи, например для аппаратного Serial:

```cpp
void setup() {
  Serial.begin(115200);
  hub.setupStream(&Serial, GH_SERIAL);
  // ...
}
```

> Примечание: библиотека GyverHub берёт на себя только опрос (available, read) и отправку (print) по указанному Stream. Запуск, настройка и остановка потока делается программистом в основной программе!

## Ручной режим
Библиотека позволяет работать с микроконтроллером в ручном режиме, то есть без встроенных способов связи (WebSocket/MQTT), либо со своей реализацией этих способов. Для работы в ручном режиме нужно реализовать в программа прием и передачу по любому из способов связи, которые поддерживает приложение GyverHub (WebSocket, MQTT, Serial, Bluetooth) при помощи любых сторонних библиотек и аппаратных модулей.

### Своя реализация MQTT/WS для ESPxx
Если необходимо сделать свою реализацию этих протоколов в скетче, то рекомендуется отключить встроенные:
```cpp
// перед подключением GyverHub
#define GH_NO_WS    // убрать WebSocket
#define GH_NO_MQTT  // убрать MQTT

#include <GyverHub.h>
```

### Парсинг запроса
Полученный из приложения запрос (см. [API](https://github.com/GyverLibs/GyverHub/wiki#api)) нужно передать в функцию `parse`:
- `parse(char* url, GHconn_t from)` - парсить команду вида `PREFIX/ID/HUB_ID/CMD/NAME=VALUE`
- `parse(char* url, char* value, GHconn_t from)` - парсить команду вида `PREFIX/ID/HUB_ID/CMD/NAME`, `VALUE` отдельной строкой

> Если запрос приходит в виде `String`, то передать как `(char*)str.c_str()`

> `GHconn_t` - тип соединения (`GH_SERIAL`, `GH_BT`, `GH_WS`, `GH_MQTT`). Он же будет передан в обработчик ответа на запрос для ответа по тому же протоколу.

Пример для Serial:
```cpp
void loop() {
  if (Serial.available()) {
    String str = Serial.readStringUntil('\0');
    hub.parse((char*)str.c_str(), GH_SERIAL);
  }
}
```

### Ответ на запрос
Библиотека разберёт запрос и сформирует ответ в виде `String` строки. Получить ответ для отправки в приложение можно в подключенной функции вида `f(String& s, GHconn_t from, bool broadcast)`, например так:

```cpp
void manual(String& s, GHconn_t from, bool br) {
  switch(from) {
    case GH_SERIAL:
      //Serial.print(s);
      break;

    case GH_WS:
      //if (br) broadcastWS(s);
      //else sendWS(s);
      break;
  }
}

void setup() {
  hub.onManual(manual);
}
```

> Обработчик `onManual()` по сути вызывается внутри функции `parse()`

#### Флаг broadcast
Этот флаг указывает на то, что ответ должен быть отправлен всем клиентам. При `false` нужно отправить ответ только клиенту, от которого пришел запрос. При `true` - в том числе всем остальным клиентам, если это возможно (например при MQTT и WebSocket соединении).