|
|
# Дополнительные фичи
|
|
|
## Время приложения
|
|
|
При открытии ПУ приложение отправляет точное время (время операционной системы, на которой запущено приложение) в unix-формате. Это время можно использовать для синхронизации часов устройства и так далее. Для получения времени нужно подключить обработчик `onUnix`:
|
|
|
```cpp
|
|
|
void onunix(uint32_t stamp) {
|
|
|
Serial.println(stamp);
|
|
|
}
|
|
|
|
|
|
void setup() {
|
|
|
hub.onUnix(onunix);
|
|
|
}
|
|
|
```
|
|
|
|
|
|
## Веб-консоль
|
|
|
В настройках ПУ можно включить текстовую консоль. Сообщения, которые в неё отправляются, можно принять в обработчике `onCLI`:
|
|
|
```cpp
|
|
|
void cli(String str) {
|
|
|
Serial.println(str);
|
|
|
}
|
|
|
|
|
|
void setup() {
|
|
|
hub.onCLI(cli);
|
|
|
}
|
|
|
```
|
|
|
Для отправки сообщений обратно используется `void sendCLI(AnyText str)`
|
|
|
|
|
|
## Информация о билде
|
|
|
Внутри билдера можно узнать, кто и с какой целью вызвал билдер:
|
|
|
```cpp
|
|
|
void build(gh::Builder& b) {
|
|
|
// это запрос виджетов
|
|
|
if (b.build.isUI()) {
|
|
|
Serial.println("=== UI BUILD ===");
|
|
|
}
|
|
|
|
|
|
// это действие с виджетом
|
|
|
if (b.build.isSet()) {
|
|
|
Serial.println("=== SET ===");
|
|
|
|
|
|
// можно напрямую получить имя и значение виджета
|
|
|
Serial.print("name: ");
|
|
|
Serial.println(b.build.name);
|
|
|
Serial.print("value: ");
|
|
|
Serial.println(b.build.value);
|
|
|
}
|
|
|
|
|
|
// инфо о клиенте
|
|
|
Serial.print("client from: ");
|
|
|
Serial.println(gh::readConnection(b.build.client.connection()));
|
|
|
Serial.print("ID: ");
|
|
|
Serial.println(b.build.client.id);
|
|
|
Serial.println();
|
|
|
}
|
|
|
```
|
|
|
|
|
|
Так как билдер динамический, это даёт возможность например показывать некоторые виджеты только определённому клиенту или только по конкретному способу связи:
|
|
|
```cpp
|
|
|
if (b.build.client.id == "abc123") b.Input();
|
|
|
```
|
|
|
|
|
|
А также перехватывать входящие значения без подключения переменной:
|
|
|
```cpp
|
|
|
if (b.Input().click()) Serial.println(b.build.value);
|
|
|
```
|
|
|
|
|
|
## Обработка запроса
|
|
|
Библиотека позволяет получить всю информацию о запросе до того, как он будет применён, и разрешить или запретить его. Это относится ко всем запросам с приложения, что позволяет очень гибко настроить систему. Например разрешить или какие то действия только определённым клиентам или по определённым способам связи, что может быть полезно для "общественных" проектов: у юзеров одни права, а у админа - другие. Длня начала нужно подключить обработчик запроса:
|
|
|
```cpp
|
|
|
bool req(gh::Request& r) {
|
|
|
Serial.print("Request: ");
|
|
|
Serial.print(gh::readConnection(r.client.connection())); // подключение
|
|
|
Serial.print(',');
|
|
|
Serial.print(r.client.id); // id клиента
|
|
|
Serial.print(',');
|
|
|
Serial.print(gh::readCMD(r.cmd)); // команда (см. доку)
|
|
|
Serial.print(',');
|
|
|
Serial.print(r.name); // имя виджета
|
|
|
Serial.print(',');
|
|
|
Serial.print(r.value); // значение виджета
|
|
|
Serial.println();
|
|
|
return 1;
|
|
|
}
|
|
|
|
|
|
void setup() {
|
|
|
hub.onRequest(req);
|
|
|
}
|
|
|
|
|
|
```
|
|
|
Из функции нужно вернуть `true`, чтобы разрешить запрос!
|
|
|
|
|
|
## Модули
|
|
|
Доступ к устройству из приложения можно контролировать при помощи системы модулей: их можно включать и отключать. По умолчанию все модули **включены**. Список модулей:
|
|
|
```cpp
|
|
|
gh::Module::ModUI // разрешить ПУ
|
|
|
gh::Module::ModInfo // разрешить вкладку инфо
|
|
|
gh::Module::ModSet // разрешить установку виджетов
|
|
|
gh::Module::ModRead // разрешить чтение виджетов
|
|
|
gh::Module::ModGet // разрешить чтение из билдера
|
|
|
gh::Module::ModData
|
|
|
gh::Module::ModReboot // разрешить перезагрузку из инфо
|
|
|
gh::Module::ModFiles // разрешить вкладку менеджера файлов
|
|
|
gh::Module::ModFormat // разрешить форматирование FS
|
|
|
gh::Module::ModDelete // разрешить удаление файлов
|
|
|
gh::Module::ModRename // разрешить переименование файлов
|
|
|
gh::Module::ModCreate // разрешить создание файлов
|
|
|
gh::Module::ModFetch // разрешить скачивание
|
|
|
gh::Module::ModUpload // разрешить скачивание
|
|
|
gh::Module::ModOta // разрешить ОТА
|
|
|
gh::Module::ModOtaUrl // разрешить ОТА по URL
|
|
|
```
|
|
|
Для включения нужно вызвать `hub.modules.set()`, для выключения - `hub.modules.clear()` и передать одну или несколько констант через `|`, например:
|
|
|
|
|
|
```cpp
|
|
|
// выключить менеджер файлов и кнопку переименования файлов
|
|
|
hub.modules.clear(gh::Module::ModFiles | gh::Module::ModRename);
|
|
|
|
|
|
// запретить все
|
|
|
hub.modules.clearAll();
|
|
|
|
|
|
// разрешить Info
|
|
|
hub.modules.set(gh::Module::ModInfo);
|
|
|
```
|
|
|
|
|
|
## Перехват скачивания
|
|
|
По умолчанию менеджер файлов и все виджеты с указанием пути к файлу работают с flash-памятью и файл автоматически открывается по указанному пути. Открытие файла можно перехватить в обработчике `onFetch`:
|
|
|
```cpp
|
|
|
const char* fetch_bytes = "fetch bytes";
|
|
|
const char fetch_pgm[] PROGMEM = "fetch pgm";
|
|
|
|
|
|
void fetch(gh::Fetcher& f) {
|
|
|
// например по имени файла можно отправить данные из памяти программы или из PROGMEM
|
|
|
if (f.path == "/fetch_bytes.txt") f.fetchBytes((uint8_t*)fetch_bytes, strlen(fetch_bytes));
|
|
|
if (f.path == "/fetch_pgm.txt") f.fetchBytes_P((uint8_t*)fetch_pgm, strlen_P(fetch_pgm));
|
|
|
|
|
|
// или отправить другой файл
|
|
|
if (f.path == "/fetch_file.txt") f.fetchFile("/fetch_file123.txt");
|
|
|
|
|
|
// также можно отправить например кадр с камеры:
|
|
|
if (f.path == "frame.jpg") {
|
|
|
// start == true - начало загрузки
|
|
|
if (f.start) {
|
|
|
frame = esp_camera_fb_get(); // получить кадр
|
|
|
if (frame) f.fetchBytes((uint8_t*)frame->buf, frame->len); // начать отправку
|
|
|
|
|
|
// start == true - конец загрузки
|
|
|
} else {
|
|
|
esp_camera_fb_return(frame); // освободить кадр
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
void setup() {
|
|
|
hub.onFetch(fetch);
|
|
|
}
|
|
|
```
|
|
|
|
|
|
## Окончание загрузки
|
|
|
Также можно отловить момент окончания загрузки файла с приложения в память устройства:
|
|
|
```cpp
|
|
|
void upl(String& path) {
|
|
|
Serial.print("Uploaded: ");
|
|
|
Serial.println(path);
|
|
|
}
|
|
|
|
|
|
void setup() {
|
|
|
hub.onUpload(upl);
|
|
|
}
|
|
|
```
|
|
|
|
|
|
## Свои поля в Info
|
|
|
Во вкладку Info в любой из 4-х блоков можно добавить свои поля:
|
|
|
```cpp
|
|
|
void info(gh::Info& info) {
|
|
|
switch (info.type) {
|
|
|
case gh::Info::Type::Version:
|
|
|
info.add("Module", "v123");
|
|
|
break;
|
|
|
|
|
|
case gh::Info::Type::Network:
|
|
|
info.add(F("5G"), "50%");
|
|
|
break;
|
|
|
|
|
|
case gh::Info::Type::Memory:
|
|
|
info.add(F("SD"), "10 GB");
|
|
|
break;
|
|
|
|
|
|
case gh::Info::Type::System:
|
|
|
info.add(F("Battery"), 3.63, 2);
|
|
|
info.add("ur mom", "120kg");
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
void setup() {
|
|
|
hub.onInfo(info);
|
|
|
}
|
|
|
``` |