diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 30586889..7da907c1 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -253,7 +253,7 @@ jobs: ./code/.pio/build/esp32cam/partitions.bin ./code/.pio/build/esp32cam/bootloader.bin ./sd-card/html/version.txt - key: ${{ github.run_number }} + key: ${{ steps.vars.outputs.branch }} # import the changes from - name: Get generated files from cache diff --git a/Changelog.md b/Changelog.md index 41a2b3e2..15af6862 100644 --- a/Changelog.md +++ b/Changelog.md @@ -2,43 +2,56 @@ ## [Unreleased] -Home Assistant Discovery Support +**Home Assistant MQTT Discovery Support** + +### Update Procedure +:bangbang: **Make sure to read the instructions below carfully!**. -**Make sure to read the instructions below carfully!**. - 1. Backup your configuration (use the `System -> Backup/Restore` page)! -1. You should update to `12.0.1` before you update to this release. All other migrations are not tested. +1. You should update to `12.0.1` before you update to this release. All other migrations are untested. 1. Upload and update the `update-*.zip` file from this release. 1. Let it restart and check on the `System -> Info` page that the Firmware as well as the Web UI got updated. If only one got updated, redo the update. If it fails several times, you also can update the Firmware and the Web UI separately. -1. Please go to `Settings -> Configuration` and address the changed parameters. +1. Safe way: + 1. Update first the `firmware.bin` (extract from zip file) and do the Reboot + 1. Update with the full zip file (`update-*.zip`, ignore the version warning after the reboot) + +1. Please go to `Settings -> Configuration` and address the changed parameters: * DataLogging (storing the values for data graph) * Debug (extended by different debug reporting levels) -If anything breaks you can try to -- Call `http:///ota?task=update&file=firmware.bin` resp. `http:///ota?task=update&file=update-*.zip` if the upload successed but the extraction failed (`update-*.zip` is the name of the uploaded file). -- Use the initial_esp32_setup.zip ( ) as alternative to have a clean install. +If anything breaks you can try to enforce manual update as following: + +**OTA:** + 1. Make sure the last run of the update completed the **Uploading** step. + 1. Call `http:///ota?task=update&file=` to enforce the extraction/flashing. + +**Initial Setup:** + 1. Use the initial_esp32_setup.zip ( ) as alternative to have a clean install. + ### Added - Implementation of [Home Assistant MQTT Discovery](https://www.home-assistant.io/integrations/mqtt/#mqtt-discovery) - Improved ROIs configuration: locked ROI geometry, equidistant delta x -- `/graph.html` to fetch measurements from the debug log and display them as a graph. Activate debug logging for this feature to work. -- PreValue is now contained in `/json` ([#1154](https://github.com/jomjol/AI-on-the-edge-device/issues/1154)) -- Show graph of values direct in the user interface (thanks to [@rdmueller](https://github.com/rdmueller)) - - Using new data logging (see below) - - Possibility to choose different values and switch between different numbers (if present) - -- SD card info into the `System>Info` menu (thanks to [@Slider007]( https://github.com/Slider0007)) -- Added a logging of the values in a text table in `/log/data` - each measurement is on one line +- Improved OTA Update mechanism (only working after installation for next update) +- Added data logging in `/log/data` - One day per file and each measurement is on one line - Format: csv - comma separated - Content: `time`, `name-of-number`, `raw-value`, `return-value`, `pre-value`, `change-rate`, `change-absolute`, `error-text`, `cnn-digital`, `cnn-analog` +- Show graph of values direct in the user interface (thanks to [@rdmueller](https://github.com/rdmueller)) + - Using new data logging (see above) + - Possibility to choose different values and switch between different numbers (if present) + + Note: You need to activate data logging for this feature to work, see above! +- PreValue is now contained in `/json` ([#1154](https://github.com/jomjol/AI-on-the-edge-device/issues/1154)) +- SD card info into the `System>Info` menu (thanks to [@Slider007]( https://github.com/Slider0007)) - Version check (Firmware vs. Web UI) +- Various minor new features ### Changed - Updated tflite (`dig-cont_0600_s3.tflite`) -- Update mode (more robust, not fully bullet prove yet) +- Updated OTA functionality (more robust, but not fully bullet prove yet) - Updated Espressif library to `espressif32@v5.2.0` - [#1176](https://github.com/jomjol/AI-on-the-edge-device/discussions/1176) accept minor negative values (-0.2) if extended resolution is enabled - [#1143](https://github.com/jomjol/AI-on-the-edge-device/issues/1143) added config parameter `AnalogDigitalTransitionStart`. It can setup very early and very late digit transition starts. @@ -58,7 +71,8 @@ If anything breaks you can try to - n.a. -## [12.0.1] 2022-09-29 + +## [12.0.1](https://github.com/jomjol/AI-on-the-edge-device/releases/tag/v12.0.1), 2022-09-29 Improve **u**ser e**x**perience @@ -97,7 +111,7 @@ If anything breaks you can try to ### Fixed - [#1092](https://github.com/jomjol/AI-on-the-edge-device/issues/1092) censor passwords in log outputs -- [#1029](https://github.com/jomjol/AI-on-the-edge-device/issues/1029) wrong change of `checkDigitConsistency` now working like releases before `11.3.1` +- [#1029](https://github.com/jomjol/AI-on-the-edge-device/issues/1029) wrong change of `checkDigitConsistency` now working like releases before `11.3.1` - Spelling corrections (**[cristianmitran](https://github.com/cristianmitran)**) ### Removed diff --git a/code/components/jomjol_fileserver_ota/server_ota.cpp b/code/components/jomjol_fileserver_ota/server_ota.cpp index 30e4449b..f04f6fc3 100644 --- a/code/components/jomjol_fileserver_ota/server_ota.cpp +++ b/code/components/jomjol_fileserver_ota/server_ota.cpp @@ -52,6 +52,68 @@ static const char *TAG = "OTA"; esp_err_t handler_reboot(httpd_req_t *req); +std::string _file_name_update; + + +void task_do_Update_ZIP(void *pvParameter) +{ + std::string filetype = toUpper(getFileType(_file_name_update)); + + LogFile.WriteToFile(ESP_LOG_INFO, TAG, "File: " + _file_name_update + " Filetype: " + filetype); + + + if (filetype == "ZIP") + { + std::string in, out, outbin, zw, retfirmware; + + out = "/sdcard/html"; + outbin = "/sdcard/firmware"; + + retfirmware = unzip_new(_file_name_update, out+"/", outbin+"/"); + LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Files unzipped."); + + if (retfirmware.length() > 0) + { + LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Found firmware.bin"); + ota_update_task(retfirmware); + } + LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Trigger reboot due to firmware update."); + doReboot(); + } + else + { + LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Only ZIP-Files support for update during startup!"); + } +} + + +void CheckUpdate() +{ + FILE *pfile; + if ((pfile = fopen("/sdcard/update.txt", "r")) == NULL) + { + LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "No update triggered."); + return; + } + + char zw[1024] = ""; + fgets(zw, 1024, pfile); + _file_name_update = std::string(zw); + fclose(pfile); + DeleteFile("/sdcard/update.txt"); // Prevent Boot Loop!!! + LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Update during boot triggered - Update File: " + _file_name_update); + + + BaseType_t xReturned; + int _i = configMINIMAL_STACK_SIZE; + xReturned = xTaskCreate(&task_do_Update_ZIP, "task_do_Update_ZIP", configMINIMAL_STACK_SIZE * 35, NULL, tskIDLE_PRIORITY+1, NULL); + TickType_t xDelay; + xDelay = 2000000 / portTICK_PERIOD_MS; + ESP_LOGD(TAG, "Wait for Update to be finished: sleep for: %ldms", (long) xDelay); + vTaskDelay( xDelay ); +} + + static void infinite_loop(void) { @@ -373,6 +435,21 @@ esp_err_t handler_ota_update(httpd_req_t *req) if (filetype == "ZIP") { + FILE *pfile; + LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Update for reboot."); + pfile = fopen("/sdcard/update.txt", "w"); + fwrite(fn.c_str(), fn.length(), 1, pfile); + fclose(pfile); + + std::string zw = "reboot\n"; + httpd_resp_sendstr_chunk(req, zw.c_str()); + httpd_resp_sendstr_chunk(req, NULL); + ESP_LOGD(TAG, "Send reboot"); + return ESP_OK; + + + +/* std::string in, out, outbin, zw, retfirmware; out = "/sdcard/html"; @@ -392,6 +469,7 @@ esp_err_t handler_ota_update(httpd_req_t *req) httpd_resp_sendstr_chunk(req, NULL); return ESP_OK; } +*/ } @@ -537,7 +615,7 @@ esp_err_t handler_reboot(httpd_req_t *req) LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "handler_reboot"); ESP_LOGI(TAG, "!!! System will restart within 5 sec!!!"); - const char* resp_str = "

"; + const char* resp_str = "

"; httpd_resp_send(req, resp_str, strlen(resp_str)); doReboot(); diff --git a/code/components/jomjol_fileserver_ota/server_ota.h b/code/components/jomjol_fileserver_ota/server_ota.h index 415e5fd9..db9093e6 100644 --- a/code/components/jomjol_fileserver_ota/server_ota.h +++ b/code/components/jomjol_fileserver_ota/server_ota.h @@ -2,10 +2,12 @@ #include -//#include "ClassControllCamera.h" +#include + void register_server_ota_sdcard_uri(httpd_handle_t server); void CheckOTAUpdate(); void doReboot(); void hard_restart(); - +void CheckUpdate(); +static bool ota_update_task(std::string fn); \ No newline at end of file diff --git a/code/main/CMakeLists.txt b/code/main/CMakeLists.txt index e244b881..5ab3ebd9 100644 --- a/code/main/CMakeLists.txt +++ b/code/main/CMakeLists.txt @@ -39,7 +39,12 @@ set(VERSION "const char* GIT_REV=\"${GIT_REV}${GIT_DIFF}\"; const char* GIT_TAG=\"${GIT_TAG}\"; const char* GIT_BRANCH=\"${GIT_BRANCH}\"; const char* BUILD_TIME=\"${BUILD_TIME}\";") -set(VERSION_HTML "${GIT_BRANCH}, ${GIT_TAG}, ${GIT_REV}${GIT_DIFF}") + +if ("${GIT_TAG}" STREQUAL "") # Tag not set, show branch + set(VERSION_HTML "Development-Branch: ${GIT_BRANCH} (Commit: ${GIT_REV}${GIT_DIFF})") +else() # Tag is set, ignore branch + set(VERSION_HTML "Release: ${GIT_TAG} (Commit: ${GIT_REV}${GIT_DIFF})") +endif() if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/version.cpp) file(READ ${CMAKE_CURRENT_SOURCE_DIR}/version.cpp VERSION_) diff --git a/code/main/main.cpp b/code/main/main.cpp index f1665a2e..1ca173ae 100644 --- a/code/main/main.cpp +++ b/code/main/main.cpp @@ -174,9 +174,12 @@ extern "C" void app_main(void) ESP_LOGD(TAG, "============================================================================================="); ESP_LOGD(TAG, "Reset reason: %s", getResetReason().c_str()); + + CheckOTAUpdate(); LogFile.CreateLogDirectories(); + CheckUpdate(); /* int mk_ret = mkdir("/sdcard/new_fd_mkdir", 0775); ESP_LOGI(TAG, "mkdir ret %d", mk_ret); diff --git a/code/main/server_main.cpp b/code/main/server_main.cpp index 1fdec51e..7bbfa5e7 100644 --- a/code/main/server_main.cpp +++ b/code/main/server_main.cpp @@ -58,50 +58,45 @@ esp_err_t info_get_handler(httpd_req_t *req) httpd_resp_sendstr_chunk(req, NULL); return ESP_OK; } - - - if (_task.compare("GitTag") == 0) + else if (_task.compare("GitTag") == 0) { httpd_resp_sendstr_chunk(req, libfive_git_version()); httpd_resp_sendstr_chunk(req, NULL); return ESP_OK; } - - - - if (_task.compare("GitRevision") == 0) + else if (_task.compare("GitRevision") == 0) { httpd_resp_sendstr_chunk(req, libfive_git_revision()); httpd_resp_sendstr_chunk(req, NULL); return ESP_OK; } - - if (_task.compare("BuildTime") == 0) + else if (_task.compare("BuildTime") == 0) { httpd_resp_sendstr_chunk(req, build_time()); httpd_resp_sendstr_chunk(req, NULL); return ESP_OK; } - - if (_task.compare("GitBaseBranch") == 0) + else if (_task.compare("FirmwareVersion") == 0) { - string buf = "Branch: '" + std::string(GIT_BRANCH) + "', Tag: '" + std::string(GIT_TAG) + \ - "', Revision: " + std::string(GIT_REV); + string buf; + if (std::string(GIT_TAG) == "") { // Tag not set, show branch + buf = "Development-Branch: " + std::string(GIT_BRANCH); + } + else { // Tag is set, ignore branch + buf = "Release: " + std::string(GIT_TAG); + } + buf = buf + " (Commit: " + std::string(GIT_REV) + ")"; httpd_resp_sendstr_chunk(req, buf.c_str()); httpd_resp_sendstr_chunk(req, NULL); return ESP_OK; } - - if (_task.compare("HTMLVersion") == 0) + else if (_task.compare("HTMLVersion") == 0) { -// std::string zw; -// zw = std::string(getHTMLversion()); httpd_resp_sendstr_chunk(req, getHTMLversion()); httpd_resp_sendstr_chunk(req, NULL); return ESP_OK; } - - if (_task.compare("Hostname") == 0) + else if (_task.compare("Hostname") == 0) { std::string zw; zw = std::string(hostname); @@ -109,8 +104,7 @@ esp_err_t info_get_handler(httpd_req_t *req) httpd_resp_sendstr_chunk(req, NULL); return ESP_OK; } - - if (_task.compare("IP") == 0) + else if (_task.compare("IP") == 0) { std::string *zw; zw = getIPAddress(); @@ -118,8 +112,7 @@ esp_err_t info_get_handler(httpd_req_t *req) httpd_resp_sendstr_chunk(req, NULL); return ESP_OK; } - - if (_task.compare("SSID") == 0) + else if (_task.compare("SSID") == 0) { std::string *zw; zw = getSSID(); @@ -127,8 +120,7 @@ esp_err_t info_get_handler(httpd_req_t *req) httpd_resp_sendstr_chunk(req, NULL); return ESP_OK; } - - if (_task.compare("FlowStatus") == 0) + else if (_task.compare("FlowStatus") == 0) { std::string zw; zw = std::string("FlowStatus"); @@ -136,8 +128,7 @@ esp_err_t info_get_handler(httpd_req_t *req) httpd_resp_sendstr_chunk(req, NULL); return ESP_OK; } - - if (_task.compare("SDCardPartitionSize") == 0) + else if (_task.compare("SDCardPartitionSize") == 0) { std::string zw; zw = getSDCardPartitionSize(); @@ -145,8 +136,7 @@ esp_err_t info_get_handler(httpd_req_t *req) httpd_resp_sendstr_chunk(req, NULL); return ESP_OK; } - - if (_task.compare("SDCardFreePartitionSpace") == 0) + else if (_task.compare("SDCardFreePartitionSpace") == 0) { std::string zw; zw = getSDCardFreePartitionSpace(); @@ -154,8 +144,7 @@ esp_err_t info_get_handler(httpd_req_t *req) httpd_resp_sendstr_chunk(req, NULL); return ESP_OK; } - - if (_task.compare("SDCardPartitionAllocationSize") == 0) + else if (_task.compare("SDCardPartitionAllocationSize") == 0) { std::string zw; zw = getSDCardPartitionAllocationSize(); @@ -163,8 +152,7 @@ esp_err_t info_get_handler(httpd_req_t *req) httpd_resp_sendstr_chunk(req, NULL); return ESP_OK; } - - if (_task.compare("SDCardManufacturer") == 0) + else if (_task.compare("SDCardManufacturer") == 0) { std::string zw; zw = getSDCardManufacturer(); @@ -172,8 +160,7 @@ esp_err_t info_get_handler(httpd_req_t *req) httpd_resp_sendstr_chunk(req, NULL); return ESP_OK; } - - if (_task.compare("SDCardName") == 0) + else if (_task.compare("SDCardName") == 0) { std::string zw; zw = getSDCardName(); @@ -181,8 +168,7 @@ esp_err_t info_get_handler(httpd_req_t *req) httpd_resp_sendstr_chunk(req, NULL); return ESP_OK; } - - if (_task.compare("SDCardCapacity") == 0) + else if (_task.compare("SDCardCapacity") == 0) { std::string zw; zw = getSDCardCapacity(); @@ -190,8 +176,7 @@ esp_err_t info_get_handler(httpd_req_t *req) httpd_resp_sendstr_chunk(req, NULL); return ESP_OK; } - - if (_task.compare("SDCardSectorSize") == 0) + else if (_task.compare("SDCardSectorSize") == 0) { std::string zw; zw = getSDCardSectorSize(); @@ -200,8 +185,6 @@ esp_err_t info_get_handler(httpd_req_t *req) return ESP_OK; } - - return ESP_OK; } @@ -394,7 +377,7 @@ esp_err_t sysinfo_handler(httpd_req_t *req) void register_server_main_uri(httpd_handle_t server, const char *base_path) { httpd_uri_t info_get_handle = { - .uri = "/version", // Match all URIs of type /path/to/file + .uri = "/info", // Match all URIs of type /path/to/file .method = HTTP_GET, .handler = info_get_handler, .user_ctx = (void*) base_path // Pass server data as context diff --git a/code/main/version.h b/code/main/version.h index 0456cd9e..a3acd61f 100644 --- a/code/main/version.h +++ b/code/main/version.h @@ -38,7 +38,7 @@ const char* libfive_git_branch(void) } -char _char_getHTMLversion[50]="NaN\0"; +char _char_getHTMLversion[100]="?\0"; const char* getHTMLversion(void){ FILE* pFile; diff --git a/sd-card/html/backup.html b/sd-card/html/backup.html index 52c93557..7030c511 100644 --- a/sd-card/html/backup.html +++ b/sd-card/html/backup.html @@ -58,7 +58,7 @@ function doBackup() { // Get hostname try { var xhttp = new XMLHttpRequest(); - xhttp.open("GET", "/version?type=Hostname", false); + xhttp.open("GET", "/info?type=Hostname", false); xhttp.send(); hostname = xhttp.responseText; } diff --git a/sd-card/html/common.js b/sd-card/html/common.js index 500bc22f..a6cea459 100644 --- a/sd-card/html/common.js +++ b/sd-card/html/common.js @@ -19,7 +19,7 @@ function LoadHostname() { // var xhttp = new XMLHttpRequest(); try { - url = _basepath + '/version?type=Hostname'; + url = _basepath + '/info?type=Hostname'; xhttp.open("GET", url, true); xhttp.send(); @@ -52,7 +52,7 @@ function LoadFwVersion() { }); try { - url = _basepath + '/version?type=GitBaseBranch'; + url = _basepath + '/info?type=FirmwareVersion'; xhttp.open("GET", url, true); xhttp.send(); } @@ -78,7 +78,7 @@ function LoadWebUiVersion() { }); try { - url = _basepath + '/version?type=HTMLVersion'; + url = _basepath + '/info?type=HTMLVersion'; xhttp.open("GET", url, true); xhttp.send(); } diff --git a/sd-card/html/info.html b/sd-card/html/info.html index e2167f12..257abb8e 100644 --- a/sd-card/html/info.html +++ b/sd-card/html/info.html @@ -25,20 +25,55 @@ div { -

Current

+

Runtime Information

Last restart: -
+
+

Build Info

+ + + + + + + + + + + + + + +
+ Firmware Version: + +
+ +
+
+ Firmware Build Time: + +
+ +
+
+ Web Interface Version: + +
+ +
+
+

Host Info

@@ -47,8 +82,8 @@ div { Hostname: @@ -57,8 +92,8 @@ div { IP-Address: @@ -67,71 +102,13 @@ div { WLan-SSID:
-
- +
+
-
- +
+
-
- +
+
-

Version Info

- - - - - - - - - - - - - - - - - - - - - - - - - -
- Git-Branch: - -
- -
-
- Git-Tag: - -
- -
-
- Git-Revision: - -
- -
-
- Build Time: - -
- -
-
- HTML Version: - -
- -
-
-

SD Card Info

@@ -140,7 +117,7 @@ div { @@ -150,7 +127,7 @@ div { @@ -160,7 +137,7 @@ div { @@ -170,7 +147,7 @@ div { @@ -180,7 +157,7 @@ div { @@ -190,7 +167,7 @@ div { @@ -200,7 +177,7 @@ div { diff --git a/sd-card/html/ota_page.html b/sd-card/html/ota_page.html index 03d6acfb..5a87d44e 100644 --- a/sd-card/html/ota_page.html +++ b/sd-card/html/ota_page.html @@ -89,7 +89,7 @@ function init(){ function doRebootAfterUpdate() { - if (confirm("Update completed!\nThe ESP32 will reboot now!")) { + if (confirm("Upload completed!\nThe device will reboot now and complete the update.\nThis will take up to 180s!")) { var stringota = "/reboot"; window.location = stringota; window.location.href = stringota; @@ -132,7 +132,7 @@ function prepareOnServer() { return; } - document.getElementById("status").innerText = "Status: Preparations on ESP32"; + document.getElementById("status").innerText = "Status: Preparations on device"; document.getElementById("doUpdate").disabled = true; var xhttp = new XMLHttpRequest(); @@ -199,7 +199,7 @@ function upload() { function extract() { - document.getElementById("status").innerText = "Status: Processing on ESP32 (takes up to 3 minutes)..."; + document.getElementById("status").innerText = "Status: Processing on device (takes up to 3 minutes)..."; var xhttp = new XMLHttpRequest(); /* first delete the old firmware */ @@ -210,6 +210,7 @@ function extract() { document.getElementById("status").innerText = "Status: Update completed!"; document.getElementById("doUpdate").disabled = true; document.getElementById("newfile").disabled = false; + document.cookie = "overview.html"; // Make sure after the reboot we go to the overview page if (xhttp.responseText.startsWith("reboot")) {
- +
- +
- +
- +
- +
- +
- +