Скачивание файлов и OTA обновление #
Скачивание на микроконтроллер отправленного в чат файла происходит в несколько этапов:
- Получение апдейта, который содержит сообщение с файлом
- Отправка запроса на получение файла с указанием id файла
- Получение ссылки на скачивание файла из ответа сервера
- Скачивание файла по ссылке
В библиотеке все эти этапы обёрнуты в одну функцию downloadFile
, внутри неё происходят все необходимые запросы и проверки. В результате получается объект Fetcher
, содержащий Stream с бинарными данными файла. Пример:
void update(fb::Update& u) {
// проверяем, что в сообщении есть файл и это документ
if (u.isMessage() && u.message().hasDocument()) {
// передаём id документа из сообщения
fb::Fetcher fetch = bot.downloadFile(u.message().document().id());
// если скачивание удалось и файл валидный
if (fetch) {
// вывести содержимое в сериал
fetch.writeTo(Serial);
// Serial.println(fetch); // или так
// также можно записать в файл
File file = LittleFS.open("file.txt", "w");
fetch.writeTo(file);
// file.print(fetch); // или так
}
}
}
На esp8266/esp32 объект Fetcher
также умеет делать OTA обновление прошивки и файловой системы, для этого достаточно вызвать updateFlash()
или updateFS()
. Но сначала нужно убедиться, что это нужный файл:
void update(fb::Update& u) {
// проверяем, что сообщение содержит файл с расширением .bin
// или другой сценарий, например отправка файла + текстовая команда
// или проверка ID юзера-админа
if (u.isMessage() &&
u.message().hasDocument() &&
u.message().document().name().endsWith(".bin")
) {
// качаем файл
fb::Fetcher fetch = bot.downloadFile(u.message().document().id());
// OTA
bool ok = fetch.updateFlash();
// отправляем сообщение с результатом
bot.sendMessage(fb::Message(ok ? "OTA done" : "OTA error", u.message().chat().id()));
}
}
После успешного OTA обновления МК дождётся следующего Update обновления от сервера, принудительно пропустит сообщение с файлом прошивки и сам перезагрузится!
OTA обновление #
Есть второй способ OTA обновления, менее требовательный к памяти. Описанный выше способ вызывает обновление из обработчика, а лучше делать это из loop. При получении файла с обновлением нужно вызвать updateFlash
или updateFS
(для файловой системы), передав файл из сообщения и по желанию ID юзера, которому будет отправлено уведомление об окончании обновления. Это может быть тот же юзер, который отправил файл, например:
void updateh(fb::Update& u) {
if (u.message().hasDocument() && u.message().document().name().endsWith(".bin")) {
bot.updateFlash(u.message().document(), u.message().chat().id());
}
}
Библиотека запомнит файл и запустит обновление из следующего вызова tick, указанный юзер получит сообщение, а после успешного обновления esp автоматически перезагрузится.
Отправка файлов #
Файл можно отправить 4-мя способами:
- Из файла файловой системы (esp8266/esp32)
- Из байтового буфера (например кадр с камеры или текст), в том числе из PROGMEM
- По ссылке из Интернета
- Существующий файл в Телеграм по id файла
Для отправки файла нужно создать объект класса fb::File
, который наследует возможности класса Message
- таким образом к файлу можно добавить подпись (caption
), меню и прочее.
// отправка файла из файла
File file = LittleFS.open("/image.jpg", "r");
fb::File f("file.txt", fb::File::Type::photo, file);
f.chatID = 123123123213;
f.caption = "подпись к файлу";
bot.sendFile(f);
// отправка файла из буфера
char str[] = "hello text";
fb::File f("file.txt", fb::File::Type::document, (uint8_t*)str, strlen(str)); // указать длину данных!
f.chatID = 13231231234;
bot.sendFile(f);
// отправка файла из Интернет
fb::File f("file.txt", fb::File::Type::document, "https://compote.slate.com/images/697b023b-64a5-49a0-8059-27b963453fb1.gif");
f.chatID = 132453234;
bot.sendFile(f);
Редактирование файлов #
Для редактирования файла достаточно создать объект класса FileEdit
, указать файл таким же образом как при отправке, указать необходимые параметры и отправить редакцию:
char str[] = "hello text v2";
fb::FileEdit f("file.txt", fb::File::Type::document, (uint8_t*)str, strlen(str));
f.messageID = 123123123; // id сообщения с прошлым файлом
f.chatID = 3231321321;
bot.editFile(f);
Для изменения подписи или меню нужно использовать CaptionEdit
и MenuEdit
соответственно.