mirror of
https://github.com/IoTManagerProject/IoTManager.git
synced 2026-03-27 06:32:19 +03:00
@@ -74,10 +74,10 @@
|
||||
"defActive": false,
|
||||
"usedLibs": {
|
||||
"esp32*": [
|
||||
"gyverlibs/GyverOLED @ 1.4"
|
||||
"gyverlibs/GyverOLED @ 1.6.3"
|
||||
],
|
||||
"esp82*": [
|
||||
"gyverlibs/GyverOLED @ 1.4"
|
||||
"gyverlibs/GyverOLED @ 1.6.3"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -15,7 +15,7 @@
|
||||
"port": 1883,
|
||||
"user": "root",
|
||||
"pass": "4321",
|
||||
"brige":1,
|
||||
"brige": 1,
|
||||
"server":"http://iotmanager.org",
|
||||
"srvUser": "rise",
|
||||
"srvPass": "3hostel3",
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "Global.h"
|
||||
#include "classes/IoTItem.h"
|
||||
#include "UpgradeFirm.h"
|
||||
// #define FB_NO_UNICODE
|
||||
// #define FB_NO_URLENCODE
|
||||
// #define FB_NO_OTA
|
||||
@@ -27,7 +28,9 @@ String _token;
|
||||
String _chatID;
|
||||
bool _autos;
|
||||
bool _initSD;
|
||||
|
||||
bool _resolveOTA;
|
||||
bool fl_rollback;
|
||||
int8_t _OTAstate = -1;
|
||||
struct ButtonMenu
|
||||
{
|
||||
String message = "";
|
||||
@@ -35,7 +38,15 @@ struct ButtonMenu
|
||||
String setId = "";
|
||||
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 *> mapBtnInline; // <btnName, ID>
|
||||
|
||||
@@ -45,16 +56,21 @@ private:
|
||||
bool _receiveMsg;
|
||||
String _prevMsg = "";
|
||||
bool _useLed = false;
|
||||
uint8_t _textMode = 0;
|
||||
|
||||
public:
|
||||
Telegram_v2(String parameters) : IoTItem(parameters)
|
||||
{
|
||||
jsonRead(parameters, "token", _token);
|
||||
jsonRead(parameters, "autos", _autos);
|
||||
if (!jsonRead(parameters, "OTA", _resolveOTA))
|
||||
_resolveOTA = 0;
|
||||
jsonRead(parameters, "receiveMsg", _receiveMsg);
|
||||
jsonRead(parameters, "chatID", _chatID);
|
||||
_textMode = jsonReadInt(parameters, "textMode");
|
||||
fl_rollback = false;
|
||||
instanceBot();
|
||||
// _myBot->setTextMode(FB_MARKDOWN);
|
||||
_myBot->setTextMode(_textMode);
|
||||
_myBot->attach(telegramMsgParse);
|
||||
|
||||
#ifdef ESP32
|
||||
@@ -72,6 +88,37 @@ public:
|
||||
if (_receiveMsg && isNetworkActive())
|
||||
{
|
||||
_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 для обработки комманд
|
||||
IoTItem::loop();
|
||||
@@ -302,6 +349,8 @@ public:
|
||||
//=============================================================================
|
||||
void static telegramMsgParse(FB_msg &msg)
|
||||
{
|
||||
static String OTAfilepath = "";
|
||||
static uint8_t typeOTA = 0;
|
||||
// FB_msg msg;
|
||||
SerialPrint("i", F("Telegram"), "chat ID: " + msg.chatID + ", msg: " + msg.text);
|
||||
// _myBot->setChatID(_chatID);
|
||||
@@ -309,9 +358,114 @@ public:
|
||||
{
|
||||
_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;
|
||||
}
|
||||
// -------------- обработка файлов загруженных пользователем --------------
|
||||
// -------------------------------------------------------------------------
|
||||
else if (msg.isFile)
|
||||
{
|
||||
if (msg.fileName.endsWith(F(".tft")) && msg.chatID == _chatID)
|
||||
{
|
||||
OTAfilepath = msg.fileUrl;
|
||||
_myBot->inlineMenu("Хотите прошить экран Nextion? На esp " + jsonReadStr(settingsFlashJson, F("name")) + "\n Next_firmware", F("Firmware \t Cancel"));
|
||||
}
|
||||
else if (msg.text.indexOf("download") != -1 && msg.chatID == _chatID)
|
||||
{
|
||||
downloadFile(msg);
|
||||
}
|
||||
else if (msg.text.indexOf("Next_firmware") != -1)
|
||||
{
|
||||
// удаляем последнее сообщение от бота
|
||||
_myBot->deleteMessage(_myBot->lastBotMsg());
|
||||
if (msg.data.indexOf("Firmware") != -1)
|
||||
{
|
||||
for (std::list<IoTItem *>::iterator it = IoTItems.begin(); it != IoTItems.end(); ++it)
|
||||
{
|
||||
if ((*it)->getSubtype() == "NextionUpload" || (*it)->getSubtype() == "Nextion")
|
||||
{
|
||||
_myBot->sendMessage("Nextion firmware ...", _chatID);
|
||||
(*it)->uploadNextionTlgrm(OTAfilepath);
|
||||
}
|
||||
}
|
||||
OTAfilepath = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
// -------------- Обработка кнопок меню созданного в сценарии --------------
|
||||
// -------------------------------------------------------------------------
|
||||
if (auto search = mapBtnMenu.find(msg.text); search != mapBtnMenu.end())
|
||||
else if (auto search = mapBtnMenu.find(msg.text); search != mapBtnMenu.end())
|
||||
{
|
||||
String outMsg;
|
||||
outMsg = mapBtnMenu[msg.text]->message;
|
||||
@@ -325,7 +479,7 @@ public:
|
||||
}
|
||||
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);
|
||||
}
|
||||
SerialPrint("i", F("Telegram"), "chat ID: " + _chatID + ", msg: " + String(outMsg));
|
||||
@@ -348,12 +502,12 @@ public:
|
||||
if (item)
|
||||
{
|
||||
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 != "")
|
||||
{
|
||||
//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);
|
||||
}
|
||||
SerialPrint("i", F("Telegram"), "chat ID: " + _chatID + ", msg: " + String(outMsg));
|
||||
@@ -431,7 +585,7 @@ public:
|
||||
}
|
||||
// -------------- вывод инлайн меню всех юнитов --------------
|
||||
// -------------------------------------------------------------------------
|
||||
else if (msg.text.indexOf("all") != -1)
|
||||
else if (msg.text.indexOf("/all") != -1)
|
||||
{
|
||||
// String list = returnListOfParams();
|
||||
String out;
|
||||
@@ -460,7 +614,7 @@ public:
|
||||
}
|
||||
// -------------- обработка команды /set_ID_VALUE --------------
|
||||
// -------------------------------------------------------------------------
|
||||
else if (msg.text.indexOf("set") != -1)
|
||||
else if (msg.text.indexOf("/set") != -1)
|
||||
{
|
||||
msg.text = deleteBeforeDelimiter(msg.text, "_");
|
||||
generateOrder(selectToMarker(msg.text, "_"), selectToMarkerLast(msg.text, "_"));
|
||||
@@ -469,7 +623,7 @@ public:
|
||||
}
|
||||
// -------------- обработка команды /get_ID --------------
|
||||
// -------------------------------------------------------------------------
|
||||
else if (msg.text.indexOf("get") != -1)
|
||||
else if (msg.text.indexOf("/get") != -1)
|
||||
{
|
||||
msg.text = deleteBeforeDelimiter(msg.text, "_");
|
||||
IoTItem *item = findIoTItem(msg.text);
|
||||
@@ -481,52 +635,43 @@ public:
|
||||
}
|
||||
// -------------- обработка запроса пользователя на скачивание файла --------------
|
||||
// -------------------------------------------------------------------------
|
||||
else if (msg.text.indexOf("file") != -1 && msg.chatID == _chatID)
|
||||
else if (msg.text.indexOf("/file") != -1 && msg.chatID == _chatID)
|
||||
{
|
||||
msg.text = deleteBeforeDelimiter(msg.text, "_");
|
||||
SerialPrint("i", F("Telegram"), "chat ID: " + _chatID + ", get file: " + String(msg.text));
|
||||
auto file = FileFS.open(selectToMarker(msg.text, "_"), FILE_READ); // /test.png
|
||||
if (!file)
|
||||
if (msg.text.indexOf("file_type") != -1)
|
||||
{
|
||||
SerialPrint("E", F("Telegram"), "Fail send file: " + selectToMarker(msg.text, "_"));
|
||||
return;
|
||||
_myBot->sendMessage("Support file type download: \n 0-foto \n 1-audio \n 2-doc \n 3-video \n 4-gif \n 5-voice", _chatID);
|
||||
}
|
||||
int type = atoi(selectToMarkerLast(msg.text, "_").c_str());
|
||||
_myBot->sendFile(file, (FB_FileType)type, selectToMarker(msg.text, "_"), _chatID);
|
||||
file.close();
|
||||
}
|
||||
// -------------- обработка файлов загруженных пользователем --------------
|
||||
// -------------------------------------------------------------------------
|
||||
else if (msg.isFile)
|
||||
{
|
||||
if (msg.text.indexOf("download") != -1 && msg.chatID == _chatID)
|
||||
else
|
||||
{
|
||||
downloadFile(msg);
|
||||
}
|
||||
else if (msg.text.indexOf("nextion") != -1 && msg.chatID == _chatID)
|
||||
{
|
||||
for (std::list<IoTItem *>::iterator it = IoTItems.begin(); it != IoTItems.end(); ++it)
|
||||
msg.text = deleteBeforeDelimiter(msg.text, "_");
|
||||
SerialPrint("i", F("Telegram"), "chat ID: " + _chatID + ", get file: " + String(msg.text));
|
||||
auto file = FileFS.open(selectToMarker(msg.text, "_"), FILE_READ); // /test.png
|
||||
if (!file)
|
||||
{
|
||||
if ((*it)->getSubtype() == "NextionUpload" || (*it)->getSubtype() == "Nextion")
|
||||
{
|
||||
(*it)->uploadNextionTlgrm(msg.fileUrl);
|
||||
}
|
||||
SerialPrint("E", F("Telegram"), "Fail send file: " + selectToMarker(msg.text, "_"));
|
||||
return;
|
||||
}
|
||||
int type = atoi(selectToMarkerLast(msg.text, "_").c_str());
|
||||
_myBot->sendFile(file, (FB_FileType)type, selectToMarker(msg.text, "_"), _chatID);
|
||||
file.close();
|
||||
}
|
||||
}
|
||||
// -------------- обработка остальных команд --------------
|
||||
// -------------------------------------------------------------------------
|
||||
else if (msg.text.indexOf("help") != -1)
|
||||
else if (msg.text.indexOf("/help") != -1)
|
||||
{
|
||||
_myBot->sendMessage("ID: " + chipId, _chatID);
|
||||
_myBot->sendMessage("chatID: " + _chatID, _chatID);
|
||||
_myBot->sendMessage("Command: /help - this text \n /all - inline menu get all values \n /allMenu - bottom menu get all values \n /menu - bottom USER menu from scenario \n /get_id - get value by ID \n /set_id_value - set value in ID \n /file_name_type - take file from esp \n /file_type - support file type \n send file and write download - \"download\" file to esp \n send tft file and write \"nextion\" - flash file.tft to Nextion", _chatID);
|
||||
if (msg.text.indexOf("/helpDebug") != -1)
|
||||
{
|
||||
_myBot->sendMessage("В папке toolchchain с которым собирались (Для esp32 например %%USERPROFILE%/.platformio/packages/toolchain-xtensa-esp32@8.4.0+2021r2-patch5/bin) из командной строки Windows (cmd) запустить файл xtensa-esp32-elf-addr2line.exe \nС параметрами -pfiaC -e Путь_к_файлу/firmware.elf Стэк_адресов", _chatID);
|
||||
}
|
||||
else
|
||||
{
|
||||
_myBot->sendMessage("ID: " + chipId, _chatID);
|
||||
_myBot->sendMessage("chatID: " + _chatID, _chatID);
|
||||
_myBot->sendMessage("Command: /help - this text \n /all - inline menu get all values \n /allMenu - bottom menu get all values \n /menu - bottom USER menu from scenario \n /get_id - get value by ID \n /set_id_value - set value in ID \n /file_name_type - take file from esp \n /file_type - support file type \n send file and write download - \"download\" file to esp \n send tft file and write \"nextion\" - flash file.tft to Nextion", _chatID);
|
||||
}
|
||||
}
|
||||
else if (msg.text.indexOf("file_type") != -1)
|
||||
{
|
||||
_myBot->sendMessage("Support file type download: \n 0-foto \n 1-audio \n 2-doc \n 3-video \n 4-gif \n 5-voice", _chatID);
|
||||
}
|
||||
else
|
||||
else if (msg.text.indexOf("/") != -1)
|
||||
{
|
||||
_myBot->sendMessage("Wrong order, use /help", _chatID);
|
||||
}
|
||||
@@ -638,6 +783,46 @@ public:
|
||||
}
|
||||
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()
|
||||
{
|
||||
clearMapMenu();
|
||||
|
||||
@@ -11,11 +11,12 @@
|
||||
"page": "",
|
||||
"descr": "",
|
||||
"int": 10,
|
||||
|
||||
"token": "",
|
||||
"chatID": "",
|
||||
"autos": 1,
|
||||
"receiveMsg": 1,
|
||||
"chatID": ""
|
||||
"textMode":"0",
|
||||
"OTA": 0
|
||||
}],
|
||||
|
||||
"about": {
|
||||
@@ -24,18 +25,20 @@
|
||||
"authorGit": "https://github.com/Mit4el",
|
||||
"specialThanks": "",
|
||||
"moduleName": "Telegram_v2",
|
||||
"moduleVersion": "3.0",
|
||||
"moduleVersion": "3.1",
|
||||
"usedRam": {
|
||||
"esp32_4mb": 37,
|
||||
"esp8266_4mb": 37
|
||||
},
|
||||
"title": "Телеграм-Бот v2",
|
||||
"moduleDesc": "Добавляет возможность отправлять сообщения от имени бота контакту в Телеграм-чате и получать команды.",
|
||||
"moduleDesc": "Добавляет возможность отправлять сообщения от имени бота контакту в Телеграм-чате и получать команды. Можно использовать для обновление ОТА, для этого отправить файл firmware.bin или littlefs.bin в чат боту",
|
||||
"propInfo": {
|
||||
"token": "Токен для авторизации бота в системе Telegram",
|
||||
"autos": "Автоматически(1) или нет(0) запоминать ChatID по входящим сообщениям. Т.е. бот будет информировать тех, кто последний прислал сообщение.",
|
||||
"receiveMsg": "Обрабатывать(1) или нет(0) входящие сообщения.",
|
||||
"chatID": "ИД диалога с контактом. Необходим для отправки сообщений именно вам."
|
||||
"chatID": "ИД диалога с контактом. Необходим для отправки сообщений именно вам.",
|
||||
"OTA": "Разрешена(1) или запрещена(0) прошивка через чат бота. Если разрешена, то файл принимается только от пользователя прописанного в chatID или от всех если autos=1",
|
||||
"textMode": "Разметка оформления сообщения в сообщениях. 0-без оформления, 1-разметка Markdown v2, 2-разметка HTML"
|
||||
},
|
||||
"funcInfo": [
|
||||
{
|
||||
@@ -75,12 +78,12 @@
|
||||
},
|
||||
{
|
||||
"name": "btnMenu",
|
||||
"descr": "Описание кнопки меню выводит запросит значение ID и выведит сообщение => Произвольное сообщение(message): значение. Пример: btnMenu(Темп.Дома, Текущая температура, IDbme280)",
|
||||
"descr": "Описание кнопки меню. По нажатию запросит значение ID и отправит сообщение. ID УКАЗЫВАТЬ В КАВЫЧКАХ! Пример: btnMenu(Темп.Дома, Текущая температура, IDbme280)",
|
||||
"params": ["Name - название кнопки отображается ботом", "message - Произвольное сообщения присылается в ответ на кнопку", "Id - Вернет значение элемента"]
|
||||
},
|
||||
{
|
||||
"name": "btnMenu",
|
||||
"descr": "Описание кнопки меню выводит запросит значение getID,установит значение value в setID и выведит сообщение => Произвольное сообщение(message): значение, IDrele=1. ВСЁ УКАЗЫВАТЬ В КАВЫЧКАХ, значение не обязательно! Пример: btnMenu(\"Обогрев\", \"Текущая температура\", \"IDbme280\", \"IDrele\", 1), btnMenu(Свет, Вклбчил свет, \"\", IDrele, 1)",
|
||||
"descr": "Описание кнопки меню. Установит значение value в setID. При необходимости запросит значение getID и отправит сообщение. ID УКАЗЫВАТЬ В КАВЫЧКАХ! Пример: btnMenu(\"Обогрев\", \"Текущая температура\", \"IDbme280\", \"IDrele\", 1), btnMenu(Свет, Вклбчил свет, \"\", IDrele, 1)",
|
||||
"params": ["Name - название кнопки отображается ботом", "message - Произвольное сообщения присылается в ответ на кнопку", "getId - Вернет значение элемента", "setId - Установит значение элементу", "value - Устанавливаемое значение"]
|
||||
},
|
||||
{
|
||||
@@ -95,12 +98,12 @@
|
||||
},
|
||||
{
|
||||
"name": "btnInline",
|
||||
"descr": "Описание кнопки встроенного (inline) меню выводит запросит значение ID и выведит сообщение => Произвольное сообщение(message): значение. Пример: btnMenu(Темп.Дома, Текущая температура, IDbme280)",
|
||||
"descr": "Описание кнопки встроенного (inline) меню. Запросит значение ID и отправит сообщение. ID УКАЗЫВАТЬ В КАВЫЧКАХ! Пример: btnInline(Темп.Дома, Текущая температура, IDbme280)",
|
||||
"params": ["Name - название кнопки отображается ботом", "message - Произвольное сообщения присылается в ответ на кнопку", "Id - Вернет значение элемента"]
|
||||
},
|
||||
{
|
||||
"name": "btnInline",
|
||||
"descr": "Описание кнопки встроенного (inline) меню выводит запросит значение getID,установит значение value в setID и выведит сообщение => Произвольное сообщение(message): значение, IDrele=1. ВСЁ УКАЗЫВАТЬ В КАВЫЧКАХ, значение не обязательно! Пример: btnMenu(\"Обогрев\", \"Текущая температура\", \"IDbme280\", \"IDrele\", 1), btnMenu(Свет, Вклбчил свет, \"\", IDrele, 1)",
|
||||
"descr": "Описание кнопки встроенного (inline) меню выводит. Установит значение value в setID. Запросит значение getID (если указан) и отправит сообщение. ID УКАЗЫВАТЬ В КАВЫЧКАХ! Пример: btnInline(\"Обогрев\", \"Текущая температура\", \"IDbme280\", \"IDrele\", 1), btnMenu(Свет, Вклбчил свет, \"\", IDrele, 1)",
|
||||
"params": ["Name - название кнопки отображается ботом", "message - Произвольное сообщения присылается в ответ на кнопку", "getId - Вернет значение элемента", "setId - Установит значение элементу", "value - Устанавливаемое значение"]
|
||||
},
|
||||
{
|
||||
@@ -110,12 +113,12 @@
|
||||
},
|
||||
{
|
||||
"name": "clearInline",
|
||||
"descr": "Очистить встроенное (inline) меню, вызвать перед для язменения, перед созданием новых кнопок",
|
||||
"descr": "Очистить встроенное (inline) меню, вызвать для изменения, перед созданием новых кнопок",
|
||||
"params": []
|
||||
},
|
||||
{
|
||||
"name": "clearMenu",
|
||||
"descr": "Очистить меню, вызвать перед для язменения, перед созданием новых кнопок",
|
||||
"descr": "Очистить меню, вызвать для изменения, перед созданием новых кнопок",
|
||||
"params": []
|
||||
}
|
||||
]
|
||||
|
||||
@@ -157,9 +157,12 @@ private:
|
||||
int BL0937_CF_GPIO = 4; // 8266 12 //Нужна возможность задавать пин из веб, это по умолчанию
|
||||
int BL0937_CF1_GPIO = 5; // 8266 13 //Нужна возможность задавать пин из веб, это по умолчанию
|
||||
int BL0937_SEL_GPIO_INV = 12; // 8266 15 // inverted //Нужна возможность задавать пин из веб, это по умолчанию
|
||||
float _expV = 0;
|
||||
float _expA = 0;
|
||||
float _expW = 0;
|
||||
float _kfV = 0;
|
||||
float _kfA = 0;
|
||||
float _kfW = 0;
|
||||
float expV = 0;
|
||||
float expA = 0;
|
||||
float expW = 0;
|
||||
|
||||
public:
|
||||
BL0937cmd(String parameters) : IoTItem(parameters)
|
||||
@@ -170,24 +173,64 @@ public:
|
||||
jsonRead(parameters, "CF_GPIO", BL0937_CF_GPIO);
|
||||
jsonRead(parameters, "CF1_GPIO", BL0937_CF1_GPIO);
|
||||
jsonRead(parameters, "SEL_GPIO", BL0937_SEL_GPIO_INV);
|
||||
jsonRead(parameters, "expV", _expV);
|
||||
jsonRead(parameters, "expA", _expA);
|
||||
jsonRead(parameters, "expW", _expW);
|
||||
jsonRead(parameters, "kfV", _kfV);
|
||||
jsonRead(parameters, "kfA", _kfA);
|
||||
jsonRead(parameters, "kfW", _kfW);
|
||||
bl0937 = new BL0937;
|
||||
bl0937->begin(BL0937_CF_GPIO, BL0937_CF1_GPIO, BL0937_SEL_GPIO_INV, LOW, true);
|
||||
bl0937->setResistors(CURRENT_RESISTOR, VOLTAGE_RESISTOR_UPSTREAM, VOLTAGE_RESISTOR_DOWNSTREAM);
|
||||
attachInterrupt(BL0937_CF1_GPIO, bl0937_cf1_interrupt, FALLING);
|
||||
attachInterrupt(BL0937_CF_GPIO, bl0937_cf_interrupt, FALLING);
|
||||
if (_expV)
|
||||
bl0937->expectedVoltage(_expV); // для калибровки вольтаж нужно вводить из веб интерфейса
|
||||
if (_expV)
|
||||
bl0937->expectedCurrent(_expA); // для калибровки можно так, а лучше ток вводить из веб интерфейса
|
||||
if (_expV)
|
||||
bl0937->expectedActivePower(_expW); // для калибровки потребляемую мощность нужно вводить из веб интерфейса
|
||||
if (_kfV)
|
||||
bl0937->setVoltageMultiplier(_kfV);
|
||||
if (_kfA)
|
||||
bl0937->setCurrentMultiplier(_kfA);
|
||||
if (_kfW)
|
||||
bl0937->setPowerMultiplier(_kfW);
|
||||
}
|
||||
|
||||
void doByInterval()
|
||||
{
|
||||
static bool startCalbr = false;
|
||||
if (expV && expA && expW)
|
||||
{
|
||||
startCalbr = true;
|
||||
SerialPrint("i", "BL0937", "Start calibration ...");
|
||||
}
|
||||
|
||||
if (startCalbr)
|
||||
{
|
||||
if (expV && bl0937->getVoltage())
|
||||
{
|
||||
bl0937->expectedVoltage(expV); // для калибровки вольтаж нужно вводить из веб интерфейса
|
||||
_kfV = bl0937->getVoltageMultiplier();
|
||||
expV = 0;
|
||||
}
|
||||
if (expA && bl0937->getCurrent())
|
||||
{
|
||||
bl0937->expectedCurrent(expA); // для калибровки можно так, а лучше ток вводить из веб интерфейса
|
||||
_kfA = bl0937->getCurrentMultiplier();
|
||||
expA = 0;
|
||||
}
|
||||
if (expW && bl0937->getActivePower())
|
||||
{
|
||||
bl0937->expectedActivePower(expW); // для калибровки потребляемую мощность нужно вводить из веб интерфейса
|
||||
_kfW = bl0937->getPowerMultiplier();
|
||||
expW = 0;
|
||||
}
|
||||
if (!expV && !expA && !expW)
|
||||
{
|
||||
String str = "Calibration done: kfV=";
|
||||
str += _kfV;
|
||||
str += ", kfA=";
|
||||
str += _kfA;
|
||||
str += ", kfW=";
|
||||
str += _kfW;
|
||||
SerialPrint("i", "BL0937", str);
|
||||
SerialPrint("i", "BL0937", "Enter multiplier to configuration!");
|
||||
startCalbr = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void onModuleOrder(String &key, String &value)
|
||||
@@ -201,27 +244,24 @@ public:
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
IoTValue execute(String command, std::vector<IoTValue> ¶m)
|
||||
{
|
||||
if (!bl0937)
|
||||
return {};
|
||||
if (command == "calibration")
|
||||
{
|
||||
if (param.size() == 3)
|
||||
{
|
||||
float v = param[0].valD;
|
||||
float a = param[1].valD;
|
||||
float p = param[2].valD;
|
||||
bl0937->expectedVoltage(v); // для калибровки вольтаж нужно вводить из веб интерфейса
|
||||
bl0937->expectedCurrent(a); // для калибровки можно так, а лучше ток вводить из веб интерфейса
|
||||
bl0937->expectedActivePower(p); // для калибровки потребляемую мощность нужно вводить из веб интерфейса
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
IoTValue execute(String command, std::vector<IoTValue> ¶m)
|
||||
{
|
||||
if (!bl0937)
|
||||
return {};
|
||||
if (command == "calibration")
|
||||
{
|
||||
if (param.size() == 3)
|
||||
{
|
||||
expV = param[0].valD;
|
||||
expA = param[1].valD;
|
||||
expW = param[2].valD;
|
||||
return {};
|
||||
}
|
||||
}
|
||||
*/
|
||||
return {};
|
||||
}
|
||||
|
||||
~BL0937cmd()
|
||||
{
|
||||
if (bl0937)
|
||||
|
||||
@@ -74,6 +74,7 @@ double BL0937::getCurrent() {
|
||||
// so we first check if power is 0 to set _current to 0 too
|
||||
if (_power == 0) {
|
||||
_current_pulse_width = 0;
|
||||
getActivePower();
|
||||
|
||||
} else if (_use_interrupts) {
|
||||
_checkCF1Signal();
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
"name": "BL0937 Реакт.Мощность",
|
||||
"type": "Reading",
|
||||
"subtype": "BL0937reactw",
|
||||
"id": "bl_w",
|
||||
"id": "bl_reactw",
|
||||
"widget": "anydataWt",
|
||||
"page": "BL0937",
|
||||
"descr": "Реакт.Мощность",
|
||||
@@ -83,15 +83,16 @@
|
||||
"page": "",
|
||||
"descr": "",
|
||||
"btn-reset": "",
|
||||
"int": "5",
|
||||
"R_current": 0.001,
|
||||
"R_upstream": 1000000,
|
||||
"R_downstream": 1000,
|
||||
"CF_GPIO": 4,
|
||||
"CF1_GPIO": 5,
|
||||
"SEL_GPIO": 12,
|
||||
"expV": 0,
|
||||
"expA": 0,
|
||||
"expW": 0
|
||||
"kfV": 0,
|
||||
"kfA": 0,
|
||||
"kfW": 0
|
||||
}
|
||||
],
|
||||
"about": {
|
||||
@@ -108,7 +109,7 @@
|
||||
"title": "Счетчик электроэнергии BL0937",
|
||||
"moduleDesc": "Считает потраченную электроэнергию, измеряет напряжение, силу тока и прочие параметры.",
|
||||
"propInfo": {
|
||||
"int": "Количество секунд между опросами датчика.",
|
||||
"int": "Количество секунд между опросами датчика. В bl_set интервал между попытками калибровки (т.к. нужны сначала данные от датчика)",
|
||||
"btn-reset": "Энергия BL0937 будет сброшена к нулю.",
|
||||
"R_current": "Резистор подключенный последовательно к основной линии",
|
||||
"R_upstream": "это 5 резисторов по 470 Ком в делителе напряжения, который питает вывод V2P",
|
||||
@@ -116,10 +117,17 @@
|
||||
"CF_GPIO": "пин CF",
|
||||
"CF1_GPIO": "пин CF1",
|
||||
"SEL_GPIO": "пин SEL",
|
||||
"expV": "реальное напряжение, указать для калибровки",
|
||||
"expA": "реальный ток, указать для калибровки",
|
||||
"expW": "реальная мощность, указать для калибровки"
|
||||
}
|
||||
"kfV": "Коэффициент корректировки напряжение, указать после калибровки",
|
||||
"kfA": "Коэффициент корректировки тока, указать после калибровки",
|
||||
"kfW": "Коэффициент корректировки мощности, указать после калибровки"
|
||||
},
|
||||
"funcInfo": [
|
||||
{
|
||||
"name": "calibration",
|
||||
"descr": "Расчет коэффициентов калибровки. Вызывать от имени BL0937 настройка. bl_set.calibration(220, 16, 3.5). Полученный коэффициенты искать в логе и ввести в конфигурацию kfV, kfA и kfW",
|
||||
"params": ["Напряжение, Ток, Мощность"]
|
||||
}
|
||||
]
|
||||
},
|
||||
"defActive": true,
|
||||
"usedLibs": {
|
||||
|
||||
@@ -11,11 +11,12 @@ class HX710b : public IoTItem {
|
||||
|
||||
public:
|
||||
HX710b(String parameters) : IoTItem(parameters) {
|
||||
int data, clock;
|
||||
int data, clock, gain;
|
||||
jsonRead(parameters, "data", data);
|
||||
jsonRead(parameters, "clock", clock);
|
||||
jsonRead(parameters, "gain", gain);
|
||||
|
||||
pressure_sensor.begin(data, clock);
|
||||
pressure_sensor.begin(data, clock, gain);
|
||||
pressure_sensor.tare();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user