Nextion, VerifyOTA? RollBackConfig

This commit is contained in:
Mit4el
2024-09-20 12:05:34 +03:00
parent 3919e5a0ab
commit d6a24b1837
13 changed files with 386 additions and 232 deletions

View File

@@ -21,6 +21,7 @@
"pinSDA": 0, "pinSDA": 0,
"i2cFreq": 100000, "i2cFreq": 100000,
"wg": "group1", "wg": "group1",
"debugTrace": 1,
"udps": 1, "udps": 1,
"settings_": "" "settings_": ""
} }

View File

@@ -18,3 +18,6 @@ extern "C" void __real_esp_panic_handler(void*);
void printDebugTrace(); void printDebugTrace();
void sendDebugTraceAndFreeMemory(bool); void sendDebugTraceAndFreeMemory(bool);
void IRAM_ATTR debugUpdate(); void IRAM_ATTR debugUpdate();
extern "C" bool verifyRollbackLater();
void verifyFirmware();

View File

@@ -20,12 +20,13 @@
"pinSCL": 0, "pinSCL": 0,
"pinSDA": 0, "pinSDA": 0,
"i2cFreq": 100000, "i2cFreq": 100000,
"wg": "group1" "wg": "group1",
"debugTrace": 1
}, },
"projectProp": { "projectProp": {
"platformio": { "platformio": {
"default_envs": "esp8266_4mb", "default_envs": "esp32_4mb3f",
"comments_default_envs": "choose from: esp8266_4mb or esp32_4mb or esp32cam_4mb or esp32s2_4mb or esp32_4mb3f or esp32s3_16mb or esp32c3m_4mb or esp8266_1mb or esp8266_1mb_ota or esp8285_1mb or esp8285_1mb_ota", "comments_default_envs": "choose from: esp8266_4mb, esp32_4mb, esp32_4mb3f, esp8266_16mb, esp32_16mb, esp32cam_4mb, esp32s2_4mb, esp32s3_16mb, esp32c3m_4mb, esp8266_1mb, esp8266_1mb_ota, esp8266_2mb, esp8266_2mb_ota, esp8285_1mb, esp8285_1mb_ota",
"envs": [ "envs": [
{ {
"name": "esp8266_4mb", "name": "esp8266_4mb",
@@ -134,7 +135,7 @@
}, },
{ {
"path": "src/modules/virtual/Cron", "path": "src/modules/virtual/Cron",
"active": true "active": false
}, },
{ {
"path": "src/modules/virtual/GoogleSheet", "path": "src/modules/virtual/GoogleSheet",
@@ -142,23 +143,23 @@
}, },
{ {
"path": "src/modules/virtual/Loging", "path": "src/modules/virtual/Loging",
"active": true "active": false
}, },
{ {
"path": "src/modules/virtual/LogingDaily", "path": "src/modules/virtual/LogingDaily",
"active": true "active": false
}, },
{ {
"path": "src/modules/virtual/Math", "path": "src/modules/virtual/Math",
"active": true "active": false
}, },
{ {
"path": "src/modules/virtual/owmWeather", "path": "src/modules/virtual/owmWeather",
"active": true "active": false
}, },
{ {
"path": "src/modules/virtual/Ping", "path": "src/modules/virtual/Ping",
"active": true "active": false
}, },
{ {
"path": "src/modules/virtual/Timer", "path": "src/modules/virtual/Timer",
@@ -166,7 +167,7 @@
}, },
{ {
"path": "src/modules/virtual/Variable", "path": "src/modules/virtual/Variable",
"active": true "active": false
}, },
{ {
"path": "src/modules/virtual/VButton", "path": "src/modules/virtual/VButton",
@@ -184,11 +185,11 @@
}, },
{ {
"path": "src/modules/sensors/A02Distance", "path": "src/modules/sensors/A02Distance",
"active": true "active": false
}, },
{ {
"path": "src/modules/sensors/Acs712", "path": "src/modules/sensors/Acs712",
"active": true "active": false
}, },
{ {
"path": "src/modules/sensors/Ads1115", "path": "src/modules/sensors/Ads1115",
@@ -196,11 +197,11 @@
}, },
{ {
"path": "src/modules/sensors/AhtXX", "path": "src/modules/sensors/AhtXX",
"active": true "active": false
}, },
{ {
"path": "src/modules/sensors/AnalogAdc", "path": "src/modules/sensors/AnalogAdc",
"active": true "active": false
}, },
{ {
"path": "src/modules/sensors/BH_1750", "path": "src/modules/sensors/BH_1750",
@@ -208,7 +209,7 @@
}, },
{ {
"path": "src/modules/sensors/BL0937", "path": "src/modules/sensors/BL0937",
"active": true "active": false
}, },
{ {
"path": "src/modules/sensors/Ble", "path": "src/modules/sensors/Ble",
@@ -224,19 +225,19 @@
}, },
{ {
"path": "src/modules/sensors/Bme280", "path": "src/modules/sensors/Bme280",
"active": true "active": false
}, },
{ {
"path": "src/modules/sensors/Bmp280", "path": "src/modules/sensors/Bmp280",
"active": true "active": false
}, },
{ {
"path": "src/modules/sensors/Dht1122", "path": "src/modules/sensors/Dht1122",
"active": true "active": false
}, },
{ {
"path": "src/modules/sensors/Ds18b20", "path": "src/modules/sensors/Ds18b20",
"active": true "active": false
}, },
{ {
"path": "src/modules/sensors/DS2401", "path": "src/modules/sensors/DS2401",
@@ -280,7 +281,7 @@
}, },
{ {
"path": "src/modules/sensors/Impulse", "path": "src/modules/sensors/Impulse",
"active": true "active": false
}, },
{ {
"path": "src/modules/sensors/Ina219", "path": "src/modules/sensors/Ina219",
@@ -308,7 +309,7 @@
}, },
{ {
"path": "src/modules/sensors/MQgas", "path": "src/modules/sensors/MQgas",
"active": true "active": false
}, },
{ {
"path": "src/modules/sensors/Ntc", "path": "src/modules/sensors/Ntc",
@@ -320,7 +321,7 @@
}, },
{ {
"path": "src/modules/sensors/Pzem004t_v2", "path": "src/modules/sensors/Pzem004t_v2",
"active": true "active": false
}, },
{ {
"path": "src/modules/sensors/RCswitch", "path": "src/modules/sensors/RCswitch",
@@ -328,11 +329,11 @@
}, },
{ {
"path": "src/modules/sensors/RTC", "path": "src/modules/sensors/RTC",
"active": true "active": false
}, },
{ {
"path": "src/modules/sensors/S8", "path": "src/modules/sensors/S8",
"active": true "active": false
}, },
{ {
"path": "src/modules/sensors/Scd40", "path": "src/modules/sensors/Scd40",
@@ -348,25 +349,25 @@
}, },
{ {
"path": "src/modules/sensors/Sht20", "path": "src/modules/sensors/Sht20",
"active": true "active": false
}, },
{ {
"path": "src/modules/sensors/Sht30", "path": "src/modules/sensors/Sht30",
"active": true "active": false
}, },
{ {
"path": "src/modules/sensors/Sonar", "path": "src/modules/sensors/Sonar",
"active": true "active": false
}, },
{ {
"path": "src/modules/sensors/UART", "path": "src/modules/sensors/UART",
"active": true "active": false
} }
], ],
"executive_devices": [ "executive_devices": [
{ {
"path": "src/modules/exec/AnalogBtn", "path": "src/modules/exec/AnalogBtn",
"active": true "active": false
}, },
{ {
"path": "src/modules/exec/BrokerMQTT", "path": "src/modules/exec/BrokerMQTT",
@@ -374,19 +375,23 @@
}, },
{ {
"path": "src/modules/exec/ButtonIn", "path": "src/modules/exec/ButtonIn",
"active": true "active": false
}, },
{ {
"path": "src/modules/exec/ButtonOut", "path": "src/modules/exec/ButtonOut",
"active": true "active": false
}, },
{ {
"path": "src/modules/exec/Buzzer", "path": "src/modules/exec/Buzzer",
"active": false
},
{
"path": "src/modules/exec/EctoControlAdapter",
"active": true "active": true
}, },
{ {
"path": "src/modules/exec/Enconder", "path": "src/modules/exec/Enconder",
"active": true "active": false
}, },
{ {
"path": "src/modules/exec/EspCam", "path": "src/modules/exec/EspCam",
@@ -402,7 +407,7 @@
}, },
{ {
"path": "src/modules/exec/IoTServo", "path": "src/modules/exec/IoTServo",
"active": true "active": false
}, },
{ {
"path": "src/modules/exec/Mcp23008", "path": "src/modules/exec/Mcp23008",
@@ -410,15 +415,15 @@
}, },
{ {
"path": "src/modules/exec/Mcp23017", "path": "src/modules/exec/Mcp23017",
"active": true "active": false
}, },
{ {
"path": "src/modules/exec/Mp3", "path": "src/modules/exec/Mp3",
"active": true "active": false
}, },
{ {
"path": "src/modules/exec/Multitouch", "path": "src/modules/exec/Multitouch",
"active": true "active": false
}, },
{ {
"path": "src/modules/exec/MySensors", "path": "src/modules/exec/MySensors",
@@ -426,15 +431,15 @@
}, },
{ {
"path": "src/modules/exec/Pcf8574", "path": "src/modules/exec/Pcf8574",
"active": true "active": false
}, },
{ {
"path": "src/modules/exec/Pwm32", "path": "src/modules/exec/Pwm32",
"active": true "active": false
}, },
{ {
"path": "src/modules/exec/Pwm8266", "path": "src/modules/exec/Pwm8266",
"active": true "active": false
}, },
{ {
"path": "src/modules/exec/SDcard", "path": "src/modules/exec/SDcard",
@@ -442,7 +447,7 @@
}, },
{ {
"path": "src/modules/exec/SIM800", "path": "src/modules/exec/SIM800",
"active": false "active": true
}, },
{ {
"path": "src/modules/exec/SmartBoiler", "path": "src/modules/exec/SmartBoiler",
@@ -458,11 +463,11 @@
}, },
{ {
"path": "src/modules/exec/TelegramLT", "path": "src/modules/exec/TelegramLT",
"active": true "active": false
}, },
{ {
"path": "src/modules/exec/Telegram_v2", "path": "src/modules/exec/Telegram_v2",
"active": false "active": true
}, },
{ {
"path": "src/modules/exec/Thermostat", "path": "src/modules/exec/Thermostat",
@@ -476,11 +481,11 @@
"screens": [ "screens": [
{ {
"path": "src/modules/display/DwinI", "path": "src/modules/display/DwinI",
"active": true "active": false
}, },
{ {
"path": "src/modules/display/Lcd2004", "path": "src/modules/display/Lcd2004",
"active": true "active": false
}, },
{ {
"path": "src/modules/display/Nextion", "path": "src/modules/display/Nextion",
@@ -496,11 +501,11 @@
}, },
{ {
"path": "src/modules/display/Oled64", "path": "src/modules/display/Oled64",
"active": true "active": false
}, },
{ {
"path": "src/modules/display/Smi2_m", "path": "src/modules/display/Smi2_m",
"active": true "active": false
}, },
{ {
"path": "src/modules/display/TM16XX", "path": "src/modules/display/TM16XX",

View File

@@ -62,6 +62,7 @@ extern "C" void __wrap_esp_panic_handler(void *info)
debugHeapUpdate(); debugHeapUpdate();
debugBacktraceUpdate(); debugBacktraceUpdate();
bootloop_panic_count += 1;
// Call the original panic handler function to finish processing this error (creating a core dump for example...) // Call the original panic handler function to finish processing this error (creating a core dump for example...)
__real_esp_panic_handler(info); __real_esp_panic_handler(info);
} }
@@ -273,6 +274,7 @@ void sendDebugTraceAndFreeMemory( bool postMsg)
free(msg); free(msg);
} }
};*/ };*/
} }
#else #else
@@ -285,3 +287,34 @@ extern "C" void __wrap_esp_panic_handler(void *info)
__real_esp_panic_handler(info); __real_esp_panic_handler(info);
} }
#endif // RESTART_DEBUG_INFO #endif // RESTART_DEBUG_INFO
extern "C" bool verifyRollbackLater(){
Serial.printf("verifyRollbackLater OVERRIDDEN FUNCTION!");
return true;
}
void verifyFirmware(){
Serial.printf("[SYSTEM] - Checking firmware...\n");
const esp_partition_t *running = esp_ota_get_running_partition();
esp_ota_img_states_t ota_state;
if (esp_ota_get_state_partition(running, &ota_state) == ESP_OK) {
const char* otaState = ota_state == ESP_OTA_IMG_NEW ? "ESP_OTA_IMG_NEW"
: ota_state == ESP_OTA_IMG_PENDING_VERIFY ? "ESP_OTA_IMG_PENDING_VERIFY"
: ota_state == ESP_OTA_IMG_VALID ? "ESP_OTA_IMG_VALID"
: ota_state == ESP_OTA_IMG_INVALID ? "ESP_OTA_IMG_INVALID"
: ota_state == ESP_OTA_IMG_ABORTED ? "ESP_OTA_IMG_ABORTED"
: "ESP_OTA_IMG_UNDEFINED";
Serial.printf( "[System] - Ota state: %s\n",otaState);
if (ota_state == ESP_OTA_IMG_PENDING_VERIFY) {
if (esp_ota_mark_app_valid_cancel_rollback() == ESP_OK) {
Serial.printf( "[System] - App is valid, rollback cancelled successfully\n");
} else {
Serial.printf("[System] - Failed to cancel rollback\n");
}
}
}else{
Serial.printf("[System] - OTA partition has no record in OTA data\n");
}
}

View File

@@ -35,6 +35,26 @@ void syncSettingsFlashJson()
writeFile(F("settings.json"), settingsFlashJson); writeFile(F("settings.json"), settingsFlashJson);
} }
void resetSettingsFlashByPanic()
{
FileFS.rename("/config.json", "/config_bak.json");
/*
update.configJson = readFile("config.json", 4096 * 4);
update.layoutJson = readFile("layout.json", 4096 * 4);
update.scenarioTxt = readFile("scenario.txt", 4096 * 4);
writeFile(F("/config_bak.json"), update.configJson);
writeFile(F("/scenario_bak.txt"), update.scenarioTxt);
writeFile(F("/layout_bak.json"), update.layoutJson);
*/
update.configJson = "[]";
update.scenarioTxt = "";
update.layoutJson = "[]";
writeFile(F("/config.json"), update.configJson);
writeFile(F("/scenario.txt"), update.scenarioTxt);
writeFile(F("/layout.json"), update.layoutJson);
ESP.reset();
}
void syncValuesFlashJson() void syncValuesFlashJson()
{ {
writeFile(F("values.json"), valuesFlashJson); writeFile(F("values.json"), valuesFlashJson);

View File

@@ -124,6 +124,8 @@ void setup() {
// получение chip id // получение chip id
setChipId(); setChipId();
verifyFirmware();
// синхронизация глобальных переменных с flash // синхронизация глобальных переменных с flash
globalVarsSync(); globalVarsSync();
@@ -148,6 +150,14 @@ void setup() {
SerialPrint("i", "i2c", F("i2c pins overriding done")); SerialPrint("i", "i2c", F("i2c pins overriding done"));
} }
if (bootloop_panic_count >= 3)
{
resetSettingsFlashByPanic();
bootloop_panic_count = -1;
}
if (bootloop_panic_count == -1)
SerialPrint("E", "CORE", F("CONFIG and SCENARIO reset !!!"));
// настраиваем микроконтроллер // настраиваем микроконтроллер
configure("/config.json"); configure("/config.json");
@@ -232,6 +242,7 @@ void setup() {
Serial.println("--------test end---------"); Serial.println("--------test end---------");
stopErrorMarker(SETUPLAST_ERRORMARKER); stopErrorMarker(SETUPLAST_ERRORMARKER);
bootloop_panic_count = 0;
} }
void loop() { void loop() {

View File

@@ -22,12 +22,14 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
* *
*/ */
/*
#ifdef CORE_DEBUG_LEVEL #ifdef CORE_DEBUG_LEVEL
#undef CORE_DEBUG_LEVEL #undef CORE_DEBUG_LEVEL
#endif #endif
#define CORE_DEBUG_LEVEL 3 #define CORE_DEBUG_LEVEL 3
#define LOG_LOCAL_LEVEL ESP_LOG_DEBUG #define LOG_LOCAL_LEVEL ESP_LOG_DEBUG
*/
#include "ESPNexUpload.h" #include "ESPNexUpload.h"
@@ -77,9 +79,9 @@ bool ESPNexUpload::connect()
return true; return true;
} }
bool ESPNexUpload::prepareUpload(uint32_t file_size, bool prot) bool ESPNexUpload::prepareUpload(uint32_t file_size, bool oldProt)
{ {
protv2 = prot; _oldProtv11 = oldProt;
_undownloadByte = file_size; _undownloadByte = file_size;
ESP_LOGD(TAG, "prepareUpload: %" PRIu32, file_size); ESP_LOGD(TAG, "prepareUpload: %" PRIu32, file_size);
vTaskDelay(5 / portTICK_PERIOD_MS); vTaskDelay(5 / portTICK_PERIOD_MS);
@@ -206,7 +208,7 @@ uint16_t ESPNexUpload::recvRetString(std::string &response, uint32_t timeout, bo
bool exit_flag = false; bool exit_flag = false;
bool ff_flag = false; bool ff_flag = false;
response = ""; response = "";
if (timeout != 500) // if (timeout != 500)
ESP_LOGD(TAG, "timeout setting serial read: %" PRIu32, timeout); ESP_LOGD(TAG, "timeout setting serial read: %" PRIu32, timeout);
start = (unsigned long)(esp_timer_get_time() / 1000ULL); start = (unsigned long)(esp_timer_get_time() / 1000ULL);
@@ -238,7 +240,11 @@ uint16_t ESPNexUpload::recvRetString(std::string &response, uint32_t timeout, bo
if (recv_flag) if (recv_flag)
{ {
if (response.find(0x05) != -1) if (response.find(0x05) != -1 && response.length() == 1)
{
exit_flag = true;
}
else if (response.find(0x08) != -1 && response.length() == 5)
{ {
exit_flag = true; exit_flag = true;
} }
@@ -273,10 +279,10 @@ bool ESPNexUpload::_setPrepareForFirmwareUpdate(uint32_t upload_baudrate)
vTaskDelay(10 / portTICK_PERIOD_MS); vTaskDelay(10 / portTICK_PERIOD_MS);
this->recvRetString(response, 800, true); // normal response time is 400ms this->recvRetString(response, 800, true); // normal response time is 400ms
ESP_LOGD(TAG, "response (00): %s", response.c_str()); ESP_LOGD(TAG, "response (00): %s", response.c_str());
if (protv2) if (_oldProtv11)
cmd = "whmi-wris " + std::to_string(_undownloadByte) + "," + std::to_string(upload_baudrate) + ",1";
else
cmd = "whmi-wri " + std::to_string(_undownloadByte) + "," + std::to_string(upload_baudrate) + ",0"; cmd = "whmi-wri " + std::to_string(_undownloadByte) + "," + std::to_string(upload_baudrate) + ",0";
else
cmd = "whmi-wris " + std::to_string(_undownloadByte) + "," + std::to_string(upload_baudrate) + ",1";
ESP_LOGI(TAG, "cmd: %s", cmd.c_str()); ESP_LOGI(TAG, "cmd: %s", cmd.c_str());
this->sendCommand(cmd.c_str()); this->sendCommand(cmd.c_str());
@@ -305,6 +311,7 @@ bool ESPNexUpload::_setPrepareForFirmwareUpdate(uint32_t upload_baudrate)
} }
} }
// НЕ ПРОВЕРЯЛОСЬ !!!!!!!!!!!!!!!!!!
bool ESPNexUpload::upload(const uint8_t *file_buf, size_t file_size) bool ESPNexUpload::upload(const uint8_t *file_buf, size_t file_size)
{ {
@@ -327,10 +334,13 @@ bool ESPNexUpload::upload(const uint8_t *file_buf, size_t file_size)
{ {
blockSize = file_size - offset; blockSize = file_size - offset;
} }
uartWriteBuf((char*)file_buf[offset], blockSize); uartWriteBuf((char *)file_buf[offset], blockSize);
// wait for the Nextion to return its 0x05 byte confirming reception and readiness to receive the next packets // wait for the Nextion to return its 0x05 byte confirming reception and readiness to receive the next packets
this->recvRetString(response, 2000, true); this->recvRetString(response, 2000, true);
ESP_LOGE(TAG, "response [%s]",
format_hex_pretty(reinterpret_cast<const uint8_t *>(response.data()), response.size()).c_str());
if (response[0] == 0x08 && response.size() == 5) if (response[0] == 0x08 && response.size() == 5)
{ // handle partial upload request { // handle partial upload request
remainingBlocks -= 1; remainingBlocks -= 1;
@@ -341,8 +351,8 @@ bool ESPNexUpload::upload(const uint8_t *file_buf, size_t file_size)
ESP_LOGI(TAG, "bulk: %i, total bytes %" PRIu32 ", response: %s", sent_bulk_counter, _sent_packets_total, response.c_str()); ESP_LOGI(TAG, "bulk: %i, total bytes %" PRIu32 ", response: %s", sent_bulk_counter, _sent_packets_total, response.c_str());
} }
ESP_LOGE(TAG, "response [%s]", // ESP_LOGE(TAG, "response [%s]",
format_hex_pretty(reinterpret_cast<const uint8_t *>(response.data()), response.size()).c_str()); // format_hex_pretty(reinterpret_cast<const uint8_t *>(response.data()), response.size()).c_str());
for (int j = 0; j < 4; ++j) for (int j = 0; j < 4; ++j)
{ {
@@ -362,8 +372,8 @@ bool ESPNexUpload::upload(const uint8_t *file_buf, size_t file_size)
ESP_LOGI(TAG, "bulk: %i, total bytes %" PRIu32 ", response: %s", sent_bulk_counter, _sent_packets_total, response.c_str()); ESP_LOGI(TAG, "bulk: %i, total bytes %" PRIu32 ", response: %s", sent_bulk_counter, _sent_packets_total, response.c_str());
} }
ESP_LOGE(TAG, "response [%s]", // ESP_LOGE(TAG, "response [%s]",
format_hex_pretty(reinterpret_cast<const uint8_t *>(response.data()), response.size()).c_str()); // format_hex_pretty(reinterpret_cast<const uint8_t *>(response.data()), response.size()).c_str());
offset += 4096; offset += 4096;
} }
@@ -399,22 +409,23 @@ bool ESPNexUpload::upload(Stream &myFile)
uint32_t _seekByte = 0; uint32_t _seekByte = 0;
uint32_t _packets_total_byte = 0; uint32_t _packets_total_byte = 0;
// get available data size // get available data size
size_t file_size = myFile.available(); size_t file_size = _undownloadByte; // myFile.available();
if (file_size) if (file_size)
{ {
int remainingBlocks = ceil(file_size / 4096); int remainingBlocks = ceil(file_size / 4096.);
int blockSize = 4096; int blockSize = 4096;
ESP_LOGI(TAG, "Remaining Blocks ALL: %" PRIu32, remainingBlocks);
while (remainingBlocks > 0) while (remainingBlocks > 0)
{ {
file_size = myFile.available(); // myFile.available();
// read up to 4096 byte into the buffer // read up to 4096 byte into the buffer
if (_seekByte > 0) if (_seekByte > 0)
{ {
if (file_size > _seekByte) if (file_size > _seekByte)
{ {
blockSize = myFile.readBytes(file_buf, _seekByte); blockSize = myFile.readBytes(file_buf, _seekByte);
file_size = myFile.available(); // file_size = myFile.available();
file_size -= _seekByte;
ESP_LOGI(TAG, "Seek file: %" PRIu32 ", left bytes %" PRIu32, _seekByte, file_size); ESP_LOGI(TAG, "Seek file: %" PRIu32 ", left bytes %" PRIu32, _seekByte, file_size);
} }
else else
@@ -423,59 +434,71 @@ bool ESPNexUpload::upload(Stream &myFile)
return false; return false;
} }
blockSize = myFile.readBytes(file_buf, ((file_size > sizeof(file_buf)) ? sizeof(file_buf) : file_size)); blockSize = myFile.readBytes(file_buf, ((file_size > sizeof(file_buf)) ? sizeof(file_buf) : file_size));
file_size -= blockSize; // осталось байт
} }
else else
{
blockSize = myFile.readBytes(file_buf, ((file_size > sizeof(file_buf)) ? sizeof(file_buf) : file_size)); blockSize = myFile.readBytes(file_buf, ((file_size > sizeof(file_buf)) ? sizeof(file_buf) : file_size));
file_size -= blockSize; // осталось байт
uartWriteBuf((char*)file_buf, blockSize); }
uartWriteBuf((char *)file_buf, blockSize);
// wait for the Nextion to return its 0x05 byte confirming reception and readiness to receive the next packets // wait for the Nextion to return its 0x05 byte confirming reception and readiness to receive the next packets
if (response[0] == 0x08 || timeout >= 4)
this->recvRetString(response, 2000, true); this->recvRetString(response, 2000, true);
else
this->recvRetString(response, 500, true);
ESP_LOGE(TAG, "upload response byte [%s]",
format_hex_pretty(reinterpret_cast<const uint8_t *>(response.data()), response.size()).c_str());
ESP_LOG_BUFFER_HEX(TAG, response.data(), response.size());
if (response[0] == 0x08 && response.size() == 5) if (response[0] == 0x08 && response.size() == 5)
{ // handle partial upload request { // handle partial upload request
remainingBlocks -= 1; remainingBlocks -= 1;
_sent_packets_total += blockSize; _sent_packets_total += blockSize; // отправлено байт
_packets_total_byte += blockSize; _packets_total_byte += blockSize; // всего байт отправлено или пропущено
sent_bulk_counter++; sent_bulk_counter++;
if (sent_bulk_counter % 10 == 0) if (sent_bulk_counter % 10 == 0)
{ {
ESP_LOGI(TAG, "bulk: %i, total bytes %" PRIu32 ", response: %s", sent_bulk_counter, _sent_packets_total, response.c_str()); // ESP_LOGI(TAG, "bulk: %i, total bytes %" PRIu32 ", response: %s", sent_bulk_counter, _sent_packets_total, response.c_str());
} }
ESP_LOGE(TAG, "upload response [%s]",
ESP_LOGE(TAG, "response [%s]",
format_hex_pretty(reinterpret_cast<const uint8_t *>(response.data()), response.size()).c_str()); format_hex_pretty(reinterpret_cast<const uint8_t *>(response.data()), response.size()).c_str());
for (int j = 0; j < 4; ++j) for (int j = 0; j < 4; ++j)
{ {
offset += static_cast<uint8_t>(response[j + 1]) << (8 * j); offset += static_cast<uint8_t>(response[j + 1]) << (8 * j);
ESP_LOGI(TAG, "Offset : %" PRIu32, offset);
} }
ESP_LOGI(TAG, "Offset : %" PRIu32, offset);
if (offset) if (offset)
{ {
remainingBlocks = ceil((file_size - offset) / blockSize); remainingBlocks = ceil((file_size - offset) / blockSize);
_seekByte = offset - _packets_total_byte; _seekByte = offset - _packets_total_byte;
_packets_total_byte += _seekByte; _packets_total_byte += _seekByte;
ESP_LOGI(TAG, "Seek Byte : %" PRIu32, _seekByte);
ESP_LOGI(TAG, "Remaining Blocks : %" PRIu32, remainingBlocks);
} }
} }
else if (response[0] == 0x05) else if ((response[0] == 0x08 || response[0] == 0x05) && response.size() == 1)
{ {
remainingBlocks -= 1; remainingBlocks -= 1;
_sent_packets_total += blockSize; _sent_packets_total += blockSize;
_packets_total_byte += blockSize; _packets_total_byte += blockSize;
file_size -= blockSize;
sent_bulk_counter++; sent_bulk_counter++;
if (sent_bulk_counter % 10 == 0) if (sent_bulk_counter % 10 == 0)
{ {
ESP_LOGI(TAG, "bulk: %i, total bytes %" PRIu32 ", response: %s", sent_bulk_counter, _sent_packets_total, response.c_str()); // ESP_LOGI(TAG, "bulk: %i, total bytes %" PRIu32 ", response: %s", sent_bulk_counter, _sent_packets_total, response.c_str());
} }
ESP_LOGE(TAG, "response [%s]", ESP_LOGE(TAG, "upload response [%s]",
format_hex_pretty(reinterpret_cast<const uint8_t *>(response.data()), response.size()).c_str()); format_hex_pretty(reinterpret_cast<const uint8_t *>(response.data()), response.size()).c_str());
offset += 4096; offset += 4096;
} }
else else
{ {
if (timeout >= 2) ESP_LOGE(TAG, "Fail response [%s]",
format_hex_pretty(reinterpret_cast<const uint8_t *>(response.data()), response.size()).c_str());
if (timeout >= 9)
{ {
ESP_LOGE(TAG, "upload failed, no valid response from display, total bytes send : %" PRIu32, _sent_packets_total); ESP_LOGE(TAG, "upload failed, no valid response from display, total bytes send : %" PRIu32, _sent_packets_total);
sent_bulk_counter = 0; sent_bulk_counter = 0;
@@ -483,8 +506,22 @@ bool ESPNexUpload::upload(Stream &myFile)
} }
timeout++; timeout++;
} }
ESP_LOGI(TAG, "bulk: %i, total bytes %" PRIu32 ", response: %s", sent_bulk_counter, _sent_packets_total, response.c_str());
} }
ESP_LOGI(TAG, "upload send last bytes %" PRIu32 ", response: %s", _sent_packets_total, response.c_str()); this->recvRetString(response, 3000, true);
if (response[0] == 0x88)
{
ESP_LOGI(TAG, "upload finished (Response 0x88), total bytes send : %" PRIu32, _sent_packets_total);
this->end();
}
else
{
ESP_LOGE(TAG, "upload response [%s]",
format_hex_pretty(reinterpret_cast<const uint8_t *>(response.data()), response.size()).c_str());
ESP_LOGI(TAG, "upload finished (TimeOut 0x88), total bytes send : %" PRIu32, _sent_packets_total);
this->end();
}
// ESP_LOGI(TAG, "upload send last bytes %" PRIu32 ", response: %s", _sent_packets_total, response.c_str());
// ESP_LOGI(TAG,"upload finished, total bytes send : %"PRIu32, _sent_packets_total); // ESP_LOGI(TAG,"upload finished, total bytes send : %"PRIu32, _sent_packets_total);
sent_bulk_counter = 0; sent_bulk_counter = 0;
return true; return true;
@@ -511,15 +548,15 @@ void ESPNexUpload::end()
} }
// wait for the nextion to finish internal processes // wait for the nextion to finish internal processes
vTaskDelay(1600 / portTICK_PERIOD_MS); // vTaskDelay(1600 / portTICK_PERIOD_MS);
// soft reset the nextion // soft reset the nextion
this->softReset(); this->softReset();
// end Serial connection // end Serial connection
uart_mutex_lock(); // uart_mutex_lock();
ESP_ERROR_CHECK(uart_driver_delete(_upload_uart_num)); // ESP_ERROR_CHECK(uart_driver_delete(_upload_uart_num));
uart_mutex_unlock(); // uart_mutex_unlock();
// reset sent packets counter // reset sent packets counter
//_sent_packets = 0; //_sent_packets = 0;
@@ -779,17 +816,20 @@ void ESPNexUpload::setBaudrate(uart_port_t uart_num, uint32_t baud_rate, gpio_nu
} }
ESP_ERROR_CHECK(uart_set_pin(uart_num, tx_io_num, rx_io_num, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE)); ESP_ERROR_CHECK(uart_set_pin(uart_num, tx_io_num, rx_io_num, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE));
/*
ESP_ERROR_CHECK(uart_driver_install(uart_num, ESP_ERROR_CHECK(uart_driver_install(uart_num,
CONFIG_NEX_UART_RECV_BUFFER_SIZE, // Receive buffer size. CONFIG_NEX_UART_RECV_BUFFER_SIZE, // Receive buffer size.
0, // Transmit buffer size. 0, // Transmit buffer size.
10, // Queue size. 10, // Queue size.
NULL, // Queue pointer. NULL, // Queue pointer.
0)); // Allocation flags. 0)); // Allocation flags.
*/
ESP_LOGD(TAG, "driver installed"); ESP_LOGD(TAG, "driver installed");
_uart_diver_installed = true; _uart_diver_installed = true;
} }
std::string ESPNexUpload::str_snprintf(const char *fmt, size_t len, ...) { std::string ESPNexUpload::str_snprintf(const char *fmt, size_t len, ...)
{
std::string str; std::string str;
va_list args; va_list args;
@@ -804,12 +844,14 @@ std::string ESPNexUpload::str_snprintf(const char *fmt, size_t len, ...) {
return str; return str;
} }
char ESPNexUpload::format_hex_pretty_char(uint8_t v) { return v >= 10 ? 'A' + (v - 10) : '0' + v; } char ESPNexUpload::format_hex_pretty_char(uint8_t v) { return v >= 10 ? 'A' + (v - 10) : '0' + v; }
std::string ESPNexUpload::format_hex_pretty(const uint8_t *data, size_t length) { std::string ESPNexUpload::format_hex_pretty(const uint8_t *data, size_t length)
{
if (length == 0) if (length == 0)
return ""; return "";
std::string ret; std::string ret;
ret.resize(3 * length - 1); ret.resize(3 * length - 1);
for (size_t i = 0; i < length; i++) { for (size_t i = 0; i < length; i++)
{
ret[3 * i] = format_hex_pretty_char((data[i] & 0xF0) >> 4); ret[3 * i] = format_hex_pretty_char((data[i] & 0xF0) >> 4);
ret[3 * i + 1] = format_hex_pretty_char(data[i] & 0x0F); ret[3 * i + 1] = format_hex_pretty_char(data[i] & 0x0F);
if (i != length - 1) if (i != length - 1)

View File

@@ -114,7 +114,7 @@ public: /* methods */
* *
* @return true if success, false for failure. * @return true if success, false for failure.
*/ */
bool prepareUpload(uint32_t file_size, bool prot); bool prepareUpload(uint32_t file_size, bool oldProt);
/** /**
* start update tft file to nextion. * start update tft file to nextion.
@@ -300,7 +300,7 @@ private: /* methods */
void uartFlushTxOnly(); void uartFlushTxOnly();
private: /* data */ private: /* data */
bool protv2; bool _oldProtv11;
uint32_t _baudrate; /* nextion serail baudrate */ uint32_t _baudrate; /* nextion serail baudrate */
uint32_t _undownloadByte; /* undownload byte of tft file */ uint32_t _undownloadByte; /* undownload byte of tft file */
uart_port_t _upload_uart_num; /* upload uart port number */ uart_port_t _upload_uart_num; /* upload uart port number */

View File

@@ -14,7 +14,7 @@ private:
bool _UpTelegram; bool _UpTelegram;
char _inc; char _inc;
String _inStr = ""; // буфер приема строк в режимах 0, 1, 2 String _inStr = ""; // буфер приема строк в режимах 0, 1, 2
bool _protv2; bool _oldProt;
// Выводим русские буквы на экран Nextion (преобразуем в кодировку ISO-8859-5) // Выводим русские буквы на экран Nextion (преобразуем в кодировку ISO-8859-5)
String convertRUS(String text) String convertRUS(String text)
@@ -66,7 +66,8 @@ public:
jsonRead(parameters, "speed", _speed); jsonRead(parameters, "speed", _speed);
jsonRead(parameters, "line", _line); jsonRead(parameters, "line", _line);
jsonRead(parameters, "uploadTelegram", _UpTelegram); jsonRead(parameters, "uploadTelegram", _UpTelegram);
jsonRead(parameters, "protv2", _protv2); if (!jsonRead(parameters, "oldProt_v11", _oldProt))
_oldProt = false;
} }
IoTValue execute(String command, std::vector<IoTValue> &param) IoTValue execute(String command, std::vector<IoTValue> &param)
@@ -79,7 +80,7 @@ public:
else if (command == "printFFF") else if (command == "printFFF")
{ {
if (param.size() == 2) if (param.size() == 2)
//UART.printFFF("auto.val=1",0) // UART.printFFF("auto.val=1",0)
{ {
String strToUart = ""; String strToUart = "";
strToUart = param[0].valS; strToUart = param[0].valS;
@@ -125,43 +126,54 @@ public:
else else
uartPrintFFF(convertRUS(strToUart + param[1].valS)); uartPrintFFF(convertRUS(strToUart + param[1].valS));
} }
}// else { // не забываем, что переопределяем execute и нужно проверить что в базовом классе проверяется } // else { // не забываем, что переопределяем execute и нужно проверить что в базовом классе проверяется
// return IoTUart::execute(command, param); // return IoTUart::execute(command, param);
// } // }
return {}; return {};
} }
void onModuleOrder(String &key, String &value) { void onModuleOrder(String &key, String &value)
if (key == "uploadServer") { {
if (key == "uploadServer")
{
updateServer(); updateServer();
} }
} }
void uartPrintFFF(const String& msg) { void uartPrintFFF(const String &msg)
if (_myUART) { {
SerialPrint("I", F("Nextion"), "uartPrintFFF -> "+msg+" +FFFFFF"); if (_myUART)
{
SerialPrint("I", F("Nextion"), "uartPrintFFF -> " + msg + " +FFFFFF");
_myUART->print(msg); _myUART->print(msg);
_myUART->write(0xff); _myUART->write(0xff);
_myUART->write(0xff); _myUART->write(0xff);
_myUART->write(0xff); _myUART->write(0xff);
} }
} }
//---------------------NEXTION-UART---START------------------------ //---------------------NEXTION-UART---START------------------------
void uartHandle() { void uartHandle()
if (!_myUART) return; {
if (_myUART->available()) { if (!_myUART)
return;
if (_myUART->available())
{
_inc = _myUART->read(); _inc = _myUART->read();
if (_inc == 0xFF) { if (_inc == 0xFF)
{
_inc = _myUART->read(); _inc = _myUART->read();
_inc = _myUART->read(); _inc = _myUART->read();
_inStr = ""; _inStr = "";
return; return;
} }
if (_inc == '\r') return; if (_inc == '\r')
return;
if (_inc == '\n') { if (_inc == '\n')
if (_inStr.indexOf("=") == -1) { // если входящее сообщение не по формату, то работаем как в режиме 0 {
if (_inStr.indexOf("=") == -1)
{ // если входящее сообщение не по формату, то работаем как в режиме 0
setValue(_inStr); setValue(_inStr);
return; return;
} }
@@ -172,30 +184,42 @@ public:
id.replace(".txt", "_txt"); id.replace(".txt", "_txt");
generateOrder(id, valStr); generateOrder(id, valStr);
_inStr = ""; _inStr = "";
} else _inStr += _inc; }
else
_inStr += _inc;
} }
} }
void onRegEvent(IoTItem* eventItem) { void onRegEvent(IoTItem *eventItem)
if (!_myUART || !eventItem) return; {
if (!_myUART || !eventItem)
return;
int indexOf_; int indexOf_;
String printStr = ""; String printStr = "";
printStr += eventItem->getID(); printStr += eventItem->getID();
indexOf_ = printStr.indexOf("_"); indexOf_ = printStr.indexOf("_");
if (indexOf_ == -1) return; // пропускаем событие, если нет используемого признака типа данных - _txt или _vol if (indexOf_ == -1)
return; // пропускаем событие, если нет используемого признака типа данных - _txt или _vol
if (printStr.indexOf("_txt") > 0) { if (printStr.indexOf("_txt") > 0)
{
printStr.replace("_txt", ".txt=\""); printStr.replace("_txt", ".txt=\"");
printStr += eventItem->getValue(); printStr += eventItem->getValue();
printStr += "\""; printStr += "\"";
} else if (printStr.indexOf("_val") > 0) { }
else if (printStr.indexOf("_val") > 0)
{
printStr += eventItem->getValue(); printStr += eventItem->getValue();
printStr.replace(".", ""); printStr.replace(".", "");
printStr.replace("_val", ".val="); printStr.replace("_val", ".val=");
} else { }
if (indexOf_ == printStr.length()-1) printStr.replace("_", ""); else
else printStr.replace("_", "."); {
if (indexOf_ == printStr.length() - 1)
printStr.replace("_", "");
else
printStr.replace("_", ".");
printStr += "="; printStr += "=";
printStr += eventItem->getValue(); printStr += eventItem->getValue();
} }
@@ -203,9 +227,9 @@ public:
uartPrintFFF(convertRUS(printStr)); uartPrintFFF(convertRUS(printStr));
} }
//---------------------NEXTION-UART---END------------------------ //---------------------NEXTION-UART---END------------------------
//---------------------NEXTION-UPDATE---START------------------------ //---------------------NEXTION-UPDATE---START------------------------
void updateServer() void updateServer()
{ {
SerialPrint("I", F("NextionUpdate"), "Update .... "); SerialPrint("I", F("NextionUpdate"), "Update .... ");
@@ -252,7 +276,7 @@ public:
if (!http.begin(url)) // пингуем файл if (!http.begin(url)) // пингуем файл
SerialPrint("I", F("NextionUpdate"), "connection failed "); SerialPrint("I", F("NextionUpdate"), "connection failed ");
#endif #endif
SerialPrint("I", F("NextionUpdate"), "Requesting file: OK" ); SerialPrint("I", F("NextionUpdate"), "Requesting file: OK");
int code = http.GET(); int code = http.GET();
// Update the nextion display // Update the nextion display
if (code == 200) if (code == 200)
@@ -260,7 +284,7 @@ public:
else else
SerialPrint("I", F("NextionUpdate"), "HTTP error: " + (String)http.errorToString(code).c_str()); SerialPrint("I", F("NextionUpdate"), "HTTP error: " + (String)http.errorToString(code).c_str());
http.end(); //http.end();
SerialPrint("I", F("NextionUpdate"), "Closing connection "); SerialPrint("I", F("NextionUpdate"), "Closing connection ");
} }
} }
@@ -274,7 +298,7 @@ public:
// nexUp.setUpdateProgressCallback([]() // nexUp.setUpdateProgressCallback([]()
// { SerialPrint("I", F("NextionUpdate"), "... "); }); // { SerialPrint("I", F("NextionUpdate"), "... "); });
result = nexUp.prepareUpload(contentLength, _protv2); result = nexUp.prepareUpload(contentLength, _oldProt);
if (!result) if (!result)
{ {
SerialPrint("I", F("NextionUpdate"), "Error Connect in prepare upload"); SerialPrint("I", F("NextionUpdate"), "Error Connect in prepare upload");
@@ -288,19 +312,39 @@ public:
{ {
SerialPrint("I", F("NextionUpdate"), "Succesfully updated Nextion! "); SerialPrint("I", F("NextionUpdate"), "Succesfully updated Nextion! ");
if (tlgrmItem)
tlgrmItem->sendTelegramMsg(false, String("NextionUpdate: Succesfully updated Nextion!"));
} }
else else
{ {
SerialPrint("I", F("NextionUpdate"), "Error updating Nextion" ); SerialPrint("I", F("NextionUpdate"), "Error updating Nextion!");
if (tlgrmItem)
tlgrmItem->sendTelegramMsg(false, String("NextionUpdate: Error updating Nextion!"));
} }
nexUp.end(); nexUp.end();
#ifdef ESP8266
_myUART->begin(_speed);
#endif
#ifdef ESP32
if (_line >= 0)
{
//_myUART = new HardwareSerial(_line);
((HardwareSerial *)_myUART)->updateBaudRate(_speed);
}
else
{
//_myUART = new SoftwareSerial(_rx, _tx);
((SoftwareSerial *)_myUART)->begin(_speed);
}
#endif
updated = false; updated = false;
} }
} }
//---------------------NEXTION-UPDATE---END------------------------ //---------------------NEXTION-UPDATE---END------------------------
~Nextion(){}; ~Nextion(){};
}; };
void *getAPI_Nextion(String subtype, String param) void *getAPI_Nextion(String subtype, String param)

View File

@@ -17,8 +17,8 @@
"rx": 16, "rx": 16,
"line": 2, "line": 2,
"speed": 9600, "speed": 9600,
"protv2": 1, "uploadTelegram": 1,
"uploadTelegram": 1 "oldProt_v11": 0
} }
], ],
"about": { "about": {
@@ -41,8 +41,8 @@
"line": "Актуально только для ESP32: номер линии hardUART. =2 rx=16 tx=17, для SoftwarwSerial в ESP32 line = -1", "line": "Актуально только для ESP32: номер линии hardUART. =2 rx=16 tx=17, для SoftwarwSerial в ESP32 line = -1",
"host": "Сервер обновления. Можно использовать LiveServer из VisualCode, указывать ip адрес", "host": "Сервер обновления. Можно использовать LiveServer из VisualCode, указывать ip адрес",
"url": "файл прошивки экрана, указывать с расширением, например nextion.tft или iotm/test.tft", "url": "файл прошивки экрана, указывать с расширением, например nextion.tft или iotm/test.tft",
"protv2": "1-использует быстрый протоколо прошивки v1.2, 0-использует оффициальный протокол прошивки",
"uploadTelegram": "1 - разрешает прошивать экран через модуль Telegram_v2", "uploadTelegram": "1 - разрешает прошивать экран через модуль Telegram_v2",
"oldProt_v11": "0 - По умолчанию используется более быстрый протокол версии 1.2 (не официальный), 1 - Использовать старый протокол версии 1.1 для прошивки экрана.",
"btn-uploadServer": "Кнопка загрузки прошивки с сервера LiveServer или другого по ip" "btn-uploadServer": "Кнопка загрузки прошивки с сервера LiveServer или другого по ip"
}, },
"funcInfo": [ "funcInfo": [

View File

@@ -42,8 +42,7 @@ public:
HTTPClient http; HTTPClient http;
#if defined ESP8266 #if defined ESP8266
WiFiClient client; if (!http.begin(_host, 80, _url))
if (!http.begin(client, _host, 80, _url))
{ {
// Serial.println("connection failed"); // Serial.println("connection failed");
SerialPrint("I", F("NextionUpdate"), "connection failed "); SerialPrint("I", F("NextionUpdate"), "connection failed ");
@@ -119,13 +118,7 @@ public:
int contentLength = http.getSize(); int contentLength = http.getSize();
SerialPrint("I", F("NextionUpdate"), "File received. Update Nextion... "); SerialPrint("I", F("NextionUpdate"), "File received. Update Nextion... ");
bool result; bool result;
#ifdef ESP8266 ESPNexUpload nextion(115200, _NEXT_RX, _NEXT_TX);
ESPNexUpload nextion(115200, -1, _NEXT_RX, _NEXT_TX);
#elif defined(esp32c3m_4mb) || defined(esp32s2_4mb)
ESPNexUpload nextion(115200, 1, _NEXT_RX, _NEXT_TX);
#else
ESPNexUpload nextion(115200, 2, _NEXT_RX, _NEXT_TX);
#endif
nextion.setUpdateProgressCallback([]() nextion.setUpdateProgressCallback([]()
{ SerialPrint("I", F("NextionUpdate"), "... "); }); { SerialPrint("I", F("NextionUpdate"), "... "); });

View File

@@ -125,8 +125,6 @@ namespace _Broker
} }
} }
bool _debug;
class BrokerMQTT : public IoTItem class BrokerMQTT : public IoTItem
{ {
private: private:
@@ -134,7 +132,7 @@ namespace _Broker
int _port = 0; int _port = 0;
String _user; String _user;
String _pass; String _pass;
//bool _debug; bool _debug;
bool _brige; bool _brige;
String _server; String _server;
String _srvUser; String _srvUser;

View File

@@ -11,6 +11,7 @@
#ifdef ESP8266 #ifdef ESP8266
#define FB_DYNAMIC #define FB_DYNAMIC
#endif #endif
#include <FastBot.h> #include <FastBot.h>
#include <map> #include <map>
@@ -94,8 +95,8 @@ public:
_myBot->tick(); _myBot->tick();
if (fl_rollback) if (fl_rollback)
{ {
_myBot->tickManual(); // Чтобы отметить сообщение прочитанным
#ifdef ESP32 #ifdef ESP32
_myBot->tickManual(); // Чтобы отметить сообщение прочитанным
if (Update.rollBack()) if (Update.rollBack())
{ {
SerialPrint("I", F("Update"), F("Откат OTA успешно выполнен")); SerialPrint("I", F("Update"), F("Откат OTA успешно выполнен"));
@@ -107,6 +108,9 @@ public:
SerialPrint("E", F("Update"), F("Откат OTA не выполнен!")); SerialPrint("E", F("Update"), F("Откат OTA не выполнен!"));
_myBot->sendMessage("Откат OTA не выполнен!", _chatID); _myBot->sendMessage("Откат OTA не выполнен!", _chatID);
} }
#else
SerialPrint("I", F("Update"), F("Откат OTA только в ESP32"));
_myBot->sendMessage("Откат OTA поддерживается только в ESP32", _chatID);
#endif #endif
} }
// была попытка OTA обновления. Обновляемся после ответа серверу! // была попытка OTA обновления. Обновляемся после ответа серверу!