прошивка через telegram

This commit is contained in:
Mit4el
2024-05-08 00:37:21 +03:00
parent fcfcc27863
commit ac20905220
2 changed files with 174 additions and 11 deletions

View File

@@ -1,5 +1,6 @@
#include "Global.h" #include "Global.h"
#include "classes/IoTItem.h" #include "classes/IoTItem.h"
#include "UpgradeFirm.h"
// #define FB_NO_UNICODE // #define FB_NO_UNICODE
// #define FB_NO_URLENCODE // #define FB_NO_URLENCODE
// #define FB_NO_OTA // #define FB_NO_OTA
@@ -27,7 +28,9 @@ String _token;
String _chatID; String _chatID;
bool _autos; bool _autos;
bool _initSD; bool _initSD;
bool _resolveOTA;
bool fl_rollback;
int8_t _OTAstate = -1;
struct ButtonMenu struct ButtonMenu
{ {
String message = ""; String message = "";
@@ -35,7 +38,15 @@ struct ButtonMenu
String setId = ""; String setId = "";
String value = ""; String value = "";
}; };
/*
struct updateFirm {
String settingsFlashJson;
String configJson;
String layoutJson;
String scenarioTxt;
String chartsData;
};
*/
std::map<String, ButtonMenu *> mapBtnMenu; // <btnName, ID> std::map<String, ButtonMenu *> mapBtnMenu; // <btnName, ID>
std::map<String, ButtonMenu *> mapBtnInline; // <btnName, ID> std::map<String, ButtonMenu *> mapBtnInline; // <btnName, ID>
@@ -51,8 +62,11 @@ public:
{ {
jsonRead(parameters, "token", _token); jsonRead(parameters, "token", _token);
jsonRead(parameters, "autos", _autos); jsonRead(parameters, "autos", _autos);
if (!jsonRead(parameters, "OTA", _resolveOTA))
_resolveOTA = 0;
jsonRead(parameters, "receiveMsg", _receiveMsg); jsonRead(parameters, "receiveMsg", _receiveMsg);
jsonRead(parameters, "chatID", _chatID); jsonRead(parameters, "chatID", _chatID);
fl_rollback = false;
instanceBot(); instanceBot();
// _myBot->setTextMode(FB_MARKDOWN); // _myBot->setTextMode(FB_MARKDOWN);
_myBot->attach(telegramMsgParse); _myBot->attach(telegramMsgParse);
@@ -72,6 +86,37 @@ public:
if (_receiveMsg && isNetworkActive()) if (_receiveMsg && isNetworkActive())
{ {
_myBot->tick(); _myBot->tick();
if (fl_rollback)
{
_myBot->tickManual(); // Чтобы отметить сообщение прочитанным
if (Update.rollBack())
{
SerialPrint("I", F("Update"), F("Откат OTA успешно выполнен"));
_myBot->sendMessage("Откат OTA запущен, плата будет перезагружена", _chatID);
ESP.restart();
}
else
{
SerialPrint("E", F("Update"), F("Откат OTA не выполнен!"));
_myBot->sendMessage("Откат OTA не выполнен!", _chatID);
}
}
// была попытка OTA обновления. Обновляемся после ответа серверу!
if (_OTAstate >= 0)
{
_myBot->tickManual(); // Чтобы отметить сообщение прочитанным
String ota;
if (_OTAstate == 0)
ota = F("Error");
else if (_OTAstate == 1)
ota = F("No updates");
else if (_OTAstate == 2)
ota = F("OK");
_myBot->sendMessage(ota, _chatID);
if (_OTAstate == 2)
ESP.restart();
_OTAstate = -1;
}
} }
// Далее вызов doByInterval для обработки комманд // Далее вызов doByInterval для обработки комманд
IoTItem::loop(); IoTItem::loop();
@@ -302,6 +347,8 @@ public:
//============================================================================= //=============================================================================
void static telegramMsgParse(FB_msg &msg) void static telegramMsgParse(FB_msg &msg)
{ {
static String OTAfilepath = "";
static uint8_t typeOTA = 0;
// FB_msg msg; // FB_msg msg;
SerialPrint("i", F("Telegram"), "chat ID: " + msg.chatID + ", msg: " + msg.text); SerialPrint("i", F("Telegram"), "chat ID: " + msg.chatID + ", msg: " + msg.text);
// _myBot->setChatID(_chatID); // _myBot->setChatID(_chatID);
@@ -309,9 +356,84 @@ public:
{ {
_chatID = msg.chatID; _chatID = msg.chatID;
} }
// -------------- Обработка сообщения об откате --------------
// -------------------------------------------------------------------------
if (msg.text.indexOf("rollback") != -1 && msg.chatID == _chatID)
{
_myBot->inlineMenu("Вы уверены, что хотите откатить прошивку? " + jsonReadStr(settingsFlashJson, F("name")) + " \n OTA_roll", F("Rollback \t Cancel"));
}
else if (msg.text.indexOf("OTA_roll") != -1)
{
// удаляем последнее сообщение от бота
_myBot->deleteMessage(_myBot->lastBotMsg());
if (msg.data.indexOf("Rollback") != -1)
{
if (Update.canRollBack())
{
fl_rollback = true;
}
else
{
SerialPrint("E", F("Update"), F("Откат OTA не возможен!"));
_myBot->sendMessage("Откат OTA не возможен!", _chatID);
}
}
}
// -------------- Обработка файлов *.bin для прошивки по OTA --------------
// -------------------------------------------------------------------------
else if (msg.OTA && _resolveOTA && msg.chatID == _chatID)
{
// _myBot->editMessage(_myBot->lastUsrMsg(), "firmware...", _chatID);
OTAfilepath = msg.fileUrl;
if (msg.fileName.indexOf("littlefs") != -1)
typeOTA = FB_SPIFFS;
else if (msg.fileName.indexOf("firmware") != -1)
typeOTA = FB_FIRMWARE;
else
SerialPrint("E", F("Update"), "Unknown file: " + msg.fileName);
_myBot->inlineMenu("Вы уверены, что хотите прошить плату? " + jsonReadStr(settingsFlashJson, F("name")) + "\n OTA_firmware", F("Firmware \t Cancel"));
}
else if (msg.text.indexOf("OTA_firmware") != -1)
{
// удаляем последнее сообщение от бота
_myBot->deleteMessage(_myBot->lastBotMsg());
if (msg.data.indexOf("Firmware") != -1)
{
putUserDataToRam();
if (typeOTA == FB_SPIFFS)
{
if (_updateFS((String *)&OTAfilepath) == 1)
{
saveUserDataToFlash();
SerialPrint("!!!", F("Update"), "Start upgrade FS... ");
}
else
{
SerialPrint("E", F("Update"), F("FS Path error"));
_myBot->sendMessage("FS Path error!", _chatID);
}
}
else if (typeOTA == FB_FIRMWARE)
{
if (_update((String *)&OTAfilepath) == 1)
{
saveUserDataToFlash();
SerialPrint("!!!", F("Update"), "Start upgrade BUILD... ");
}
else
{
SerialPrint("E", F("Update"), F("Build Path error"));
_myBot->sendMessage("Build Path error!", _chatID);
}
}
}
OTAfilepath = "";
typeOTA = 0;
}
// -------------- Обработка кнопок меню созданного в сценарии -------------- // -------------- Обработка кнопок меню созданного в сценарии --------------
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
if (auto search = mapBtnMenu.find(msg.text); search != mapBtnMenu.end()) else if (auto search = mapBtnMenu.find(msg.text); search != mapBtnMenu.end())
{ {
String outMsg; String outMsg;
outMsg = mapBtnMenu[msg.text]->message; outMsg = mapBtnMenu[msg.text]->message;
@@ -325,7 +447,7 @@ public:
} }
if (mapBtnMenu[msg.text]->setId != "") if (mapBtnMenu[msg.text]->setId != "")
{ {
//outMsg += ", " + mapBtnMenu[msg.text]->setId + "=" + mapBtnMenu[msg.text]->value; // outMsg += ", " + mapBtnMenu[msg.text]->setId + "=" + mapBtnMenu[msg.text]->value;
generateOrder(mapBtnMenu[msg.text]->setId, mapBtnMenu[msg.text]->value); generateOrder(mapBtnMenu[msg.text]->setId, mapBtnMenu[msg.text]->value);
} }
SerialPrint("i", F("Telegram"), "chat ID: " + _chatID + ", msg: " + String(outMsg)); SerialPrint("i", F("Telegram"), "chat ID: " + _chatID + ", msg: " + String(outMsg));
@@ -348,12 +470,12 @@ public:
if (item) if (item)
{ {
outMsg += ": " + item->getValue(); outMsg += ": " + item->getValue();
//SerialPrint("i", F("Telegram"), "chat ID: " + _chatID + ", msg: " + String(msg.data)); // SerialPrint("i", F("Telegram"), "chat ID: " + _chatID + ", msg: " + String(msg.data));
} }
} }
if (mapBtnInline[msg.data]->setId != "") if (mapBtnInline[msg.data]->setId != "")
{ {
//outMsg += ", " + mapBtnInline[msg.data]->setId + "=" + mapBtnInline[msg.data]->value; // outMsg += ", " + mapBtnInline[msg.data]->setId + "=" + mapBtnInline[msg.data]->value;
generateOrder(mapBtnInline[msg.data]->setId, mapBtnInline[msg.data]->value); generateOrder(mapBtnInline[msg.data]->setId, mapBtnInline[msg.data]->value);
} }
SerialPrint("i", F("Telegram"), "chat ID: " + _chatID + ", msg: " + String(outMsg)); SerialPrint("i", F("Telegram"), "chat ID: " + _chatID + ", msg: " + String(outMsg));
@@ -638,6 +760,46 @@ public:
} }
mapBtnInline.clear(); mapBtnInline.clear();
} }
// ===================== OTA =====================
// ОТА обновление, вызывать внутри обработчика сообщения по флагу OTA
uint8_t static _update(String *_file_ptr, __attribute__((unused)) uint8_t type = FB_FIRMWARE)
{
#ifndef FB_NO_OTA
if (!_file_ptr)
return 8;
uint8_t OTAflag = type;
_myBot->sendMessage((type == FB_FIRMWARE) ? F("OTA firmware...") : F("OTA spiffs..."), _chatID);
#ifdef ESP8266
ESPhttpUpdate.rebootOnUpdate(false);
#ifdef FB_DYNAMIC
BearSSL::WiFiClientSecure client;
client.setInsecure();
#endif
if (OTAflag == FB_FIRMWARE)
_OTAstate = ESPhttpUpdate.update(client, *_file_ptr);
else if (OTAflag == FB_SPIFFS)
_OTAstate = ESPhttpUpdate.updateFS(client, *_file_ptr);
#else
WiFiClientSecure client;
client.setInsecure();
httpUpdate.rebootOnUpdate(false);
if (OTAflag == FB_FIRMWARE)
_OTAstate = httpUpdate.update(client, *_file_ptr);
else if (OTAflag == FB_SPIFFS)
_OTAstate = httpUpdate.updateSpiffs(client, *_file_ptr);
#endif
#endif
return 1;
}
// ОТА обновление SPIFFS, вызывать внутри обработчика сообщения по флагу OTA
uint8_t static _updateFS(String *_file_ptr)
{
return _update(_file_ptr, FB_SPIFFS);
}
~Telegram_v2() ~Telegram_v2()
{ {
clearMapMenu(); clearMapMenu();

View File

@@ -11,11 +11,11 @@
"page": "", "page": "",
"descr": "", "descr": "",
"int": 10, "int": 10,
"token": "", "token": "",
"autos": 1, "autos": 1,
"receiveMsg": 1, "receiveMsg": 1,
"chatID": "" "chatID": "",
"OTA": 0
}], }],
"about": { "about": {
@@ -24,18 +24,19 @@
"authorGit": "https://github.com/Mit4el", "authorGit": "https://github.com/Mit4el",
"specialThanks": "", "specialThanks": "",
"moduleName": "Telegram_v2", "moduleName": "Telegram_v2",
"moduleVersion": "3.0", "moduleVersion": "3.1",
"usedRam": { "usedRam": {
"esp32_4mb": 37, "esp32_4mb": 37,
"esp8266_4mb": 37 "esp8266_4mb": 37
}, },
"title": "Телеграм-Бот v2", "title": "Телеграм-Бот v2",
"moduleDesc": "Добавляет возможность отправлять сообщения от имени бота контакту в Телеграм-чате и получать команды.", "moduleDesc": "Добавляет возможность отправлять сообщения от имени бота контакту в Телеграм-чате и получать команды. Можно использовать для обновление ОТА, для этого отправить файл firmware.bin или littlefs.bin в чат боту",
"propInfo": { "propInfo": {
"token": "Токен для авторизации бота в системе Telegram", "token": "Токен для авторизации бота в системе Telegram",
"autos": "Автоматически(1) или нет(0) запоминать ChatID по входящим сообщениям. Т.е. бот будет информировать тех, кто последний прислал сообщение.", "autos": "Автоматически(1) или нет(0) запоминать ChatID по входящим сообщениям. Т.е. бот будет информировать тех, кто последний прислал сообщение.",
"receiveMsg": "Обрабатывать(1) или нет(0) входящие сообщения.", "receiveMsg": "Обрабатывать(1) или нет(0) входящие сообщения.",
"chatID": "ИД диалога с контактом. Необходим для отправки сообщений именно вам." "chatID": "ИД диалога с контактом. Необходим для отправки сообщений именно вам.",
"OTA": "Разрешена(1) или запрещена(0) прошивка через чат бота. Если разрешена, то файл принимается только от пользователя прописанного в chatID или от всех если autos=1"
}, },
"funcInfo": [ "funcInfo": [
{ {