diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml new file mode 100644 index 00000000..f9f7216a --- /dev/null +++ b/.github/workflows/build.yaml @@ -0,0 +1,106 @@ +name: Build and Pack + +on: [push] + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + + - name: Cache PlatformIO + uses: actions/cache@v2 + with: + path: ~/.platformio + key: ${{ runner.os }}-${{ hashFiles('**/lockfiles') }} + + - name: Set up Python + uses: actions/setup-python@v2 + - name: Install PlatformIO + run: | + python -m pip install --upgrade pip + pip install --upgrade platformio + + - name: Set Variables + id: vars + run: | + echo "::set-output name=sha_short::$(git rev-parse --short HEAD)" + echo "::set-output name=date_time::$(git log -1 --format="%at" | xargs -I{} date -d @{} '+%Y-%m-%d %H:%M:%S')" + echo "::set-output name=date_time_filename::$(git log -1 --format="%at" | xargs -I{} date -d @{} '+%Y-%m-%d_%H-%M-%S')" + #echo "::set-output name=version_string::${{ steps.vars.outputs.date_time_filename }}__${{ github.ref_name }}_(${{ steps.vars.outputs.sha_short }})" + #echo "Version String: ${{ steps.vars.outputs.version_string }}" + + + - name: Set Version used in HTML Info page + run: echo "${{ steps.vars.outputs.date_time }}, ${{ github.ref_name }} (${{ steps.vars.outputs.sha_short }})" > "sd-card/html/version.txt" + + + - name: Build Firmware +# run: mkdir -p ./code/.pio/build/esp32cam/; touch ./code/.pio/build/esp32cam/firmware.bin # Testing + run: cd code; platformio run --environment esp32cam + + + + # Old OTA concept + # firmware__*.zip needs to be unpacked before attaching to the release! + # The bin filename can contain versioning. + - name: Rename firmware file to contain versioning (old ota) + run: | + mkdir -p ./dist_old_ota + cp "./code/.pio/build/esp32cam/firmware.bin" "./dist_old_ota/firmware__${{ steps.vars.outputs.date_time_filename }}__${{ github.ref_name }}_(${{ steps.vars.outputs.sha_short }}).bin" + ls -l ./dist_old_ota + + - name: Upload Firmware artifact (old OTA concept) + uses: actions/upload-artifact@v3 + with: + name: "firmware__extract_before_upload__only_needed_for_migration_from_11.2.0" + path: ./dist_old_ota/* + + - name: Upload Web interface artifact (old OTA concept) + uses: actions/upload-artifact@v3 + with: + name: "html__only_needed_for_migration_from_11.2.0__${{ steps.vars.outputs.date_time_filename }}__${{ github.ref_name }}_(${{ steps.vars.outputs.sha_short }})" + path: ./sd-card/html/* + + + + # New OTA concept + # update__version.zip file with following content: + # - /firmware.bin + # - (optional) /html/* + # - (optional) /config/*.tfl + - name: Prepare update.zip artifact + run: | + mkdir -p ./dist + cp "./code/.pio/build/esp32cam/firmware.bin" "dist/firmware.bin" + + - name: Upload update.zip Artifact (Firmware only) + uses: actions/upload-artifact@v3 + with: + name: "update_firmware_only__${{ steps.vars.outputs.date_time_filename }}__${{ github.ref_name }}_(${{ steps.vars.outputs.sha_short }})" + path: ./dist/* + + + - name: Prepare update.zip artifact (Firmware + Web UI) + run: cp -r ./sd-card/html ./dist/ + + - name: Upload update.zip artifact (Firmware + Web UI) + uses: actions/upload-artifact@v3 + with: + name: "update_firmware+web_ui__${{ steps.vars.outputs.date_time_filename }}__${{ github.ref_name }}_(${{ steps.vars.outputs.sha_short }})" + path: ./dist/* + + + - name: Prepare update.zip artifact (Firmware + Web UI + CNN) + run: | + mkdir ./dist/config/ + cp ./sd-card/config/*.tfl ./dist/config/ 2>/dev/null || true + cp ./sd-card/config/*.tflite ./dist/config/ 2>/dev/null || true + + - name: Upload update.zip artifact (Firmware + Web UI + CNN) + uses: actions/upload-artifact@v3 + with: + name: "update_firmware+web_ui+cnn__${{ steps.vars.outputs.date_time_filename }}__${{ github.ref_name }}_(${{ steps.vars.outputs.sha_short }})" + path: ./dist/* diff --git a/README.md b/README.md index c6561a19..2ed672a2 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,27 @@ In other cases you can contact the developer via email: 0) + { + zw = _main + zw; + } + else + { + zw = _target_zip + zw; + } + + } + + printf("Filename to extract: %s", zw.c_str()); + DeleteFile(zw); + FILE* fpTargetFile = OpenFileAndWait(zw.c_str(), "wb"); + fwrite(p, 1, (uint)uncomp_size, fpTargetFile); + fclose(fpTargetFile); + + printf("Successfully extracted file \"%s\", size %u\n", archive_filename, (uint)uncomp_size); + // printf("File data: \"%s\"\n", (const char*)p); + + // We're done. + mz_free(p); + } + + // Close the archive, freeing any resources it was using + mz_zip_reader_end(&zip_archive); + } + + printf("Success.\n"); + return ret; +} + void unzip(std::string _in_zip_file, std::string _target_directory){ int i, sort_iter; mz_bool status; @@ -860,15 +945,4 @@ void register_server_file_uri(httpd_handle_t server, const char *base_path) }; httpd_register_uri_handler(server, &file_delete); - - /* URI handler for getting tflite files from server */ -/* - httpd_uri_t file_tflite = { - .uri = "/tflite", // Match all URIs of type /delete/path/to/file - .method = HTTP_GET, - .handler = get_tflite_file_handler, - .user_ctx = server_data // Pass server data as context - }; - httpd_register_uri_handler(server, &file_tflite); -*/ } diff --git a/code/components/jomjol_fileserver_ota/server_file.h b/code/components/jomjol_fileserver_ota/server_file.h index c179e36e..9dbcc88f 100644 --- a/code/components/jomjol_fileserver_ota/server_file.h +++ b/code/components/jomjol_fileserver_ota/server_file.h @@ -4,6 +4,8 @@ void register_server_file_uri(httpd_handle_t server, const char *base_path); void unzip(std::string _in_zip_file, std::string _target_directory); +std::string unzip_new(std::string _in_zip_file, std::string _target_zip, std::string _target_bin, std::string _main = "/sdcard/"); + void delete_all_in_directory(std::string _directory); diff --git a/code/components/jomjol_fileserver_ota/server_help.cpp b/code/components/jomjol_fileserver_ota/server_help.cpp index 4bb06ffa..e8238b84 100644 --- a/code/components/jomjol_fileserver_ota/server_help.cpp +++ b/code/components/jomjol_fileserver_ota/server_help.cpp @@ -43,6 +43,7 @@ esp_err_t send_file(httpd_req_t *req, std::string filename) } ESP_LOGI(TAG, "Sending file : %s ...", filename.c_str()); +// httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*"); set_content_type_from_file(req, filename.c_str()); /* Retrieve the pointer to scratch buffer for temporary storage */ @@ -120,6 +121,8 @@ esp_err_t set_content_type_from_file(httpd_req_t *req, const char *filename) return httpd_resp_set_type(req, "image/x-icon"); } else if (IS_FILE_EXT(filename, ".js")) { return httpd_resp_set_type(req, "text/javascript"); + } else if (IS_FILE_EXT(filename, ".css")) { + return httpd_resp_set_type(req, "text/css"); } /* This is a limited set only */ /* For any other type always set as plain text */ diff --git a/code/components/jomjol_fileserver_ota/server_ota.cpp b/code/components/jomjol_fileserver_ota/server_ota.cpp index c9b11b08..3d41b78f 100644 --- a/code/components/jomjol_fileserver_ota/server_ota.cpp +++ b/code/components/jomjol_fileserver_ota/server_ota.cpp @@ -50,6 +50,8 @@ static char ota_write_data[BUFFSIZE + 1] = { 0 }; #define OTA_URL_SIZE 256 static const char *TAGPARTOTA = "server_ota"; +esp_err_t handler_reboot(httpd_req_t *req); + static void infinite_loop(void) { @@ -207,24 +209,6 @@ static void print_sha256 (const uint8_t *image_hash, const char *label) static bool diagnostic(void) { -/* - gpio_config_t io_conf; - io_conf.intr_type = (gpio_int_type_t) GPIO_PIN_INTR_DISABLE; - io_conf.mode = GPIO_MODE_INPUT; - io_conf.pin_bit_mask = (1ULL << CONFIG_EXAMPLE_GPIO_DIAGNOSTIC); - io_conf.pull_down_en = GPIO_PULLDOWN_DISABLE; - io_conf.pull_up_en = GPIO_PULLUP_ENABLE; - gpio_config(&io_conf); - - ESP_LOGI(TAGPARTOTA, "Diagnostics (5 sec)..."); - vTaskDelay(5000 / portTICK_PERIOD_MS); - - bool diagnostic_is_ok = gpio_get_level(CONFIG_EXAMPLE_GPIO_DIAGNOSTIC); - - gpio_reset_pin(CONFIG_EXAMPLE_GPIO_DIAGNOSTIC); - - return diagnostic_is_ok; -*/ return true; } @@ -326,7 +310,7 @@ esp_err_t handler_ota_update(httpd_req_t *req) if (httpd_query_key_value(_query, "task", _valuechar, 30) == ESP_OK) { - printf("task is found"); printf(_valuechar); printf("\n"); + printf("task is found: "); printf(_valuechar); printf("\n"); _task = std::string(_valuechar); } @@ -344,16 +328,105 @@ esp_err_t handler_ota_update(httpd_req_t *req) }; + if (_task.compare("update") == 0) + { + std::string filetype = toUpper(getFileType(fn)); + if (filetype.length() == 0) + { + std::string zw = "Update failed - no file specified (zip, bin, tfl, tlite)"; + httpd_resp_sendstr_chunk(req, zw.c_str()); + httpd_resp_sendstr_chunk(req, NULL); + return ESP_OK; + } + + + if ((filetype == "TFLITE") || (filetype == "TFL")) + { + std::string out = "/sdcard/config/" + getFileFullFileName(fn); + DeleteFile(out); + CopyFile(fn, out); + DeleteFile(fn); + + const char* resp_str = "Neural Network File copied."; + httpd_resp_sendstr_chunk(req, resp_str); + httpd_resp_sendstr_chunk(req, NULL); + return ESP_OK; + } + + + if (filetype == "ZIP") + { + std::string in, out, outbin, zw, retfirmware; + +// in = "/sdcard/firmware/html.zip"; + out = "/sdcard/html"; + outbin = "/sdcard/firmware"; + +// delete_all_in_directory(out); + + retfirmware = unzip_new(fn, out+"/", outbin+"/"); + + if (retfirmware.length() > 0) + { + filetype = "BIN"; + fn = retfirmware; + zw = "HTML Update Successfull!

Additioal firmware found in ZIP file.\n"; + httpd_resp_sendstr_chunk(req, zw.c_str()); + } + else + { + zw = "HTML Update Successfull!

No reboot necessary.\n"; + httpd_resp_sendstr_chunk(req, zw.c_str()); + httpd_resp_sendstr_chunk(req, NULL); + return ESP_OK; + } + } + + + if (filetype == "BIN") + { + const char* resp_str; + KillTFliteTasks(); + gpio_handler_deinit(); + if (ota_update_task(fn)) + { +// resp_str = "rebooting - Firmware Update Successfull!

You can restart now."; +// httpd_resp_send(req, resp_str, strlen(resp_str)); +// httpd_resp_sendstr_chunk(req, NULL); + return handler_reboot(req); + } + else + { + resp_str = "Error during Firmware Update!!!

Please check output of console."; + } + + httpd_resp_send(req, resp_str, strlen(resp_str)); + + #ifdef DEBUG_DETAIL_ON + LogFile.WriteHeapInfo("handler_ota_update - Done"); + #endif + + return ESP_OK; + } + + + std::string zw = "Update failed - no valid file specified (zip, bin, tfl, tlite)"; + httpd_resp_sendstr_chunk(req, zw.c_str()); + httpd_resp_sendstr_chunk(req, NULL); + return ESP_OK; + } + + if (_task.compare("unziphtml") == 0) { std::string in, out, zw; in = "/sdcard/firmware/html.zip"; - out = "/sdcard/html/"; + out = "/sdcard/html"; delete_all_in_directory(out); - unzip(in, out); + unzip(in, out+"/"); zw = "HTML Update Successfull!

No reboot necessary"; httpd_resp_sendstr_chunk(req, zw.c_str()); httpd_resp_sendstr_chunk(req, NULL); @@ -371,6 +444,8 @@ esp_err_t handler_ota_update(httpd_req_t *req) unlink(fn.c_str()); } /* Respond with an empty chunk to signal HTTP response completion */ + std::string zw = "file deleted!\n"; + httpd_resp_sendstr_chunk(req, zw.c_str()); httpd_resp_send_chunk(req, NULL, 0); return ESP_OK; } @@ -437,7 +512,7 @@ esp_err_t handler_reboot(httpd_req_t *req) LogFile.WriteToFile("handler_reboot"); ESP_LOGI(TAGPARTOTA, "!!! 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_flowcontroll/ClassFlowCNNGeneral.cpp b/code/components/jomjol_flowcontroll/ClassFlowCNNGeneral.cpp index da6ddfd5..a60735f6 100644 --- a/code/components/jomjol_flowcontroll/ClassFlowCNNGeneral.cpp +++ b/code/components/jomjol_flowcontroll/ClassFlowCNNGeneral.cpp @@ -10,7 +10,7 @@ static const char* TAG = "flow_analog"; -bool debugdetailgeneral = false; +bool debugdetailgeneral = true; ClassFlowCNNGeneral::ClassFlowCNNGeneral(ClassFlowAlignment *_flowalign, t_CNNType _cnntype) : ClassFlowImage(NULL, TAG) { @@ -201,7 +201,7 @@ int ClassFlowCNNGeneral::ZeigerEvalHybridNeu(float zahl, float zahl_vorgaenger, if (AnalogerVorgaenger) { // result = ZeigerEvalAnalogToDigitNeu(zahl, eval_vorgaenger); - result = ZeigerEvalAnalogToDigitNeu(zahl, zahl_vorgaenger); + result = ZeigerEvalAnalogToDigitNeu(zahl, zahl_vorgaenger, eval_vorgaenger); if (debugdetailgeneral) LogFile.WriteToFile("ClassFlowCNNGeneral::ZeigerEvalHybridNeu - Analoger Vorgänger, Bewertung über ZeigerEvalAnalogNeu = " + std::to_string(result) + " zahl: " + std::to_string(zahl) + " zahl_vorgaenger = " + std::to_string(zahl_vorgaenger)+ " eval_vorgaenger = " + std::to_string(eval_vorgaenger) + " DigitalUnschaerfe = " + std::to_string(DigitalUnschaerfe)); return result; @@ -232,20 +232,20 @@ int ClassFlowCNNGeneral::ZeigerEvalHybridNeu(float zahl, float zahl_vorgaenger, } // bleibt nur >= 9.5 --> noch kein Nulldurchgang --> 2.8 --> 2, und 3.1 --> 2 - // hier auf 4 reduziert, da erst ab Vorgänder 9 anfängt umzustellen. Bei 9.5 Vorgänger kann die aktuelle - // Zahl noch x.4 - x.5 sein. + // alles >=x.4 kann als aktuelle Zahl gelten im Übergang. Bei 9.5 Vorgänger kann die aktuelle + // Zahl noch x.6 - x.7 sein. if (ergebnis_nachkomma >= 4) result = ergebnis_vorkomma; else result = (ergebnis_vorkomma - 1 + 10) % 10; if (debugdetailgeneral) LogFile.WriteToFile("ClassFlowCNNGeneral::ZeigerEvalHybridNeu - KEIN Analoger Vorgänger, >= 9.5 --> noch kein Nulldurchgang = " + std::to_string(result) + - " zahl: " + std::to_string(zahl) + " zahl_vorgaenger = " + std::to_string(zahl_vorgaenger)+ " eval_vorgaenger = " + std::to_string(eval_vorgaenger) + " DigitalUnschaerfe = " + std::to_string(DigitalUnschaerfe)); + " zahl: " + std::to_string(zahl) + " zahl_vorgaenger = " + std::to_string(zahl_vorgaenger)+ " eval_vorgaenger = " + std::to_string(eval_vorgaenger) + " DigitalUnschaerfe = " + std::to_string(DigitalUnschaerfe) + " ergebnis_nachkomma = " + std::to_string(ergebnis_nachkomma)); return result; } -int ClassFlowCNNGeneral::ZeigerEvalAnalogToDigitNeu(float zahl, float ziffer_vorgaenger) +int ClassFlowCNNGeneral::ZeigerEvalAnalogToDigitNeu(float zahl, float ziffer_vorgaenger, int eval_vorgaenger) { int result; int ergebnis_nachkomma = ((int) floor(zahl * 10)) % 10; @@ -272,7 +272,8 @@ int ClassFlowCNNGeneral::ZeigerEvalAnalogToDigitNeu(float zahl, float ziffer_vor return result; } - if (ziffer_vorgaenger <= 1) // Nulldurchgang hat stattgefunden (!Bewertung über Prev_value und nicht Zahl!) --> hier aufrunden (2.8 --> 3, aber auch 3.1 --> 3) + if (ziffer_vorgaenger <= 1 && eval_vorgaenger<9) // Nulldurchgang hat stattgefunden (!Bewertung über Prev_value und nicht Zahl!) --> hier aufrunden (2.8 --> 3, aber auch 3.1 --> 3) + // aber Sonderfall ziffer_vorgaeger = 0.1 vor_vorgaenger 9.9 => eval_vorgaenger ist 9, damit hat Nulldurchgang nicht stattgefunden. { if (ergebnis_nachkomma > 5) result = (ergebnis_vorkomma + 1) % 10; @@ -339,38 +340,6 @@ int ClassFlowCNNGeneral::ZeigerEvalAnalogNeu(float zahl, int ziffer_vorgaenger) } -/* -int ClassFlowCNNGeneral::ZeigerEval(float zahl, int ziffer_vorgaenger) -{ - int ergebnis_nachkomma = ((int) floor(zahl * 10) + 10) % 10; - int ergebnis_vorkomma = ((int) floor(zahl) + 10) % 10; - int ergebnis; - float ergebnis_rating; - if (debugdetailgeneral) LogFile.WriteToFile("ClassFlowCNNGeneral::ZeigerEval erg_v=" + std::to_string(ergebnis_vorkomma) + ", erg_n=" + std::to_string(ergebnis_nachkomma) + ", ziff_v=" + std::to_string(ziffer_vorgaenger)); - - if (ziffer_vorgaenger == -1) - return ergebnis_vorkomma % 10; - - // Ist die aktuelle Stelle schon umgesprungen und die Vorstelle noch nicht? - // Akt.: 2.1, Vorstelle = 0.9 => 1.9 - // Problem sind mehrere Rundungen - // Bsp. zahl=4.5, Vorgänger= 9.6 (ziffer_vorgaenger=0) - // Tritt nur auf bei Übergang von analog auf digit - ergebnis_rating = ergebnis_nachkomma - ziffer_vorgaenger; - if (ergebnis_nachkomma >= 5) - ergebnis_rating-=5.1; - else - ergebnis_rating+=5; - ergebnis = (int) round(zahl); - if (ergebnis_rating < 0) - ergebnis-=1; - if (ergebnis == -1) - ergebnis+=10; - - ergebnis = (ergebnis + 10) % 10; - return ergebnis; -} -*/ bool ClassFlowCNNGeneral::ReadParameter(FILE* pfile, string& aktparamgraph) { @@ -416,11 +385,6 @@ bool ClassFlowCNNGeneral::ReadParameter(FILE* pfile, string& aktparamgraph) { this->logfileRetentionInDays = std::stoi(zerlegt[1]); } -// if ((toUpper(zerlegt[0]) == "MODELTYPE") && (zerlegt.size() > 1)) -// { -// if (toUpper(zerlegt[1]) == "DIGITHYPRID") -// CNNType = DigitalHyprid; -// } if ((toUpper(zerlegt[0]) == "MODEL") && (zerlegt.size() > 1)) { @@ -439,6 +403,11 @@ bool ClassFlowCNNGeneral::ReadParameter(FILE* pfile, string& aktparamgraph) neuroi->posy = std::stoi(zerlegt[2]); neuroi->deltax = std::stoi(zerlegt[3]); neuroi->deltay = std::stoi(zerlegt[4]); + neuroi->CCW = false; + if (zerlegt.size() >= 6) + { + neuroi->CCW = toUpper(zerlegt[5]) == "TRUE"; + } neuroi->result_float = -1; neuroi->image = NULL; neuroi->image_org = NULL; @@ -511,7 +480,7 @@ general* ClassFlowCNNGeneral::GetGENERAL(string _name, bool _create = true) _ret->ROI.push_back(neuroi); - printf("GetGENERAL - GENERAL %s - roi %s\n", _analog.c_str(), _roi.c_str()); + printf("GetGENERAL - GENERAL %s - roi %s - CCW: %d\n", _analog.c_str(), _roi.c_str(), neuroi->CCW); return _ret; } @@ -658,10 +627,11 @@ bool ClassFlowCNNGeneral::getNetworkParameter() CNNType = Digital; printf("TFlite-Type set to Digital\n"); break; - case 20: +/* case 20: CNNType = DigitalHyprid10; printf("TFlite-Type set to DigitalHyprid10\n"); break; +*/ // case 22: // CNNType = DigitalHyprid; // printf("TFlite-Type set to DigitalHyprid\n"); @@ -724,8 +694,13 @@ bool ClassFlowCNNGeneral::doNeuralNetwork(string time) f1 = tflite->GetOutputValue(0); f2 = tflite->GetOutputValue(1); float result = fmod(atan2(f1, f2) / (M_PI * 2) + 2, 1); - GENERAL[_ana]->ROI[i]->result_float = result * 10; - printf("Result General(Analog)%i: %f\n", i, GENERAL[_ana]->ROI[i]->result_float); + + if(GENERAL[_ana]->ROI[i]->CCW) + GENERAL[_ana]->ROI[i]->result_float = 10 - (result * 10); + else + GENERAL[_ana]->ROI[i]->result_float = result * 10; + + printf("Result General(Analog)%i - CCW: %d - %f\n", i, GENERAL[_ana]->ROI[i]->CCW, GENERAL[_ana]->ROI[i]->result_float); if (isLogImage) LogImage(logPath, GENERAL[_ana]->ROI[i]->name, &GENERAL[_ana]->ROI[i]->result_float, NULL, time, GENERAL[_ana]->ROI[i]->image_org); } break; @@ -790,6 +765,7 @@ bool ClassFlowCNNGeneral::doNeuralNetwork(string time) } } break; */ +/* case DigitalHyprid10: { int _num, _nachkomma; @@ -825,6 +801,7 @@ bool ClassFlowCNNGeneral::doNeuralNetwork(string time) } } } break; +*/ case DoubleHyprid10: { @@ -858,7 +835,7 @@ bool ClassFlowCNNGeneral::doNeuralNetwork(string time) _fit = _val + _valminus; } - if (result > 10) + if (result >= 10) result = result - 10; if (result < 0) result = result + 10; @@ -916,15 +893,17 @@ bool ClassFlowCNNGeneral::doNeuralNetwork(string time) _num = tflite->GetOutClassification(); - GENERAL[_ana]->ROI[i]->result_float = (float)_num / 10.0; + if(GENERAL[_ana]->ROI[i]->CCW) + GENERAL[_ana]->ROI[i]->result_float = 10 - ((float)_num / 10.0); + else + GENERAL[_ana]->ROI[i]->result_float = (float)_num / 10.0; - _result_save_file = GENERAL[_ana]->ROI[i]->result_float; GENERAL[_ana]->ROI[i]->isReject = false; - printf("Result General(Analog)%i: %f\n", i, GENERAL[_ana]->ROI[i]->result_float); + printf("Result General(Analog)%i - CCW: %d - %f\n", i, GENERAL[_ana]->ROI[i]->CCW, GENERAL[_ana]->ROI[i]->result_float); if (isLogImage) { diff --git a/code/components/jomjol_flowcontroll/ClassFlowCNNGeneral.h b/code/components/jomjol_flowcontroll/ClassFlowCNNGeneral.h index fd58153c..06444ba7 100644 --- a/code/components/jomjol_flowcontroll/ClassFlowCNNGeneral.h +++ b/code/components/jomjol_flowcontroll/ClassFlowCNNGeneral.h @@ -10,7 +10,6 @@ enum t_CNNType { Analogue, Analogue100, Digital, -// DigitalHyprid, DigitalHyprid10, DoubleHyprid10, Digital100, @@ -30,21 +29,18 @@ protected: int DigitalBand = 3; float DigitalAnalogerVorgaengerUebergangsbereich = 2; float DigitalUebergangsbereichVorgaengerAnalogToDigit = 1; // war vorher 2 - float DigitalUebergangsbereichVorgaenger = 0.9; + float DigitalUebergangsbereichVorgaenger = 0.7; // 9.3 - 0.7 string cnnmodelfile; int modelxsize, modelysize, modelchannel; bool isLogImageSelect; string LogImageSelect; ClassFlowAlignment* flowpostalignment; -// ClassFlowPostProcessing *flowpostprocessing = NULL; - bool SaveAllFiles; -// bool extendedResolution; -// int ZeigerEval(float zahl, int ziffer_vorgaenger); -// int ZeigerEvalHybrid(float zahl, float zahl_vorgaenger, int eval_vorgaenger); + bool SaveAllFiles; + int ZeigerEvalAnalogNeu(float zahl, int ziffer_vorgaenger); - int ZeigerEvalAnalogToDigitNeu(float zahl, float ziffer_vorgaenger); + int ZeigerEvalAnalogToDigitNeu(float zahl, float ziffer_vorgaenger, int eval_vorgaenger); int ZeigerEvalHybridNeu(float zahl, float zahl_vorgaenger, int eval_vorgaenger, bool AnalogerVorgaenger = false); diff --git a/code/components/jomjol_flowcontroll/ClassFlowDefineTypes.h b/code/components/jomjol_flowcontroll/ClassFlowDefineTypes.h index 98432886..c296ca27 100644 --- a/code/components/jomjol_flowcontroll/ClassFlowDefineTypes.h +++ b/code/components/jomjol_flowcontroll/ClassFlowDefineTypes.h @@ -7,7 +7,7 @@ struct roi { int posx, posy, deltax, deltay; float result_float; int result_klasse; - bool isReject; + bool isReject, CCW; string name; CImageBasis *image, *image_org; }; @@ -33,9 +33,9 @@ struct NumberPost { bool checkDigitIncreaseConsistency; time_t lastvalue; string timeStamp; - float FlowRateAct; // m3 / min - float PreValue; // letzter Wert, der gut ausgelesen wurde - float Value; // letzer ausgelesener Wert, inkl. Korrekturen + double FlowRateAct; // m3 / min + double PreValue; // letzter Wert, der gut ausgelesen wurde + double Value; // letzer ausgelesener Wert, inkl. Korrekturen string ReturnRateValue; // RückgabewertRate string ReturnChangeAbsolute; // RückgabewertRate string ReturnRawValue; // Rohwert (mit N & führenden 0) diff --git a/code/components/jomjol_flowcontroll/ClassFlowImage.cpp b/code/components/jomjol_flowcontroll/ClassFlowImage.cpp index c50b8cda..4053b5dc 100644 --- a/code/components/jomjol_flowcontroll/ClassFlowImage.cpp +++ b/code/components/jomjol_flowcontroll/ClassFlowImage.cpp @@ -63,7 +63,12 @@ void ClassFlowImage::LogImage(string logPath, string name, float *resultFloat, i if (*resultFloat < 0) sprintf(buf, "N.N_"); else + { sprintf(buf, "%.1f_", *resultFloat); + if (strcmp(buf, "10.0_")) + sprintf(buf, "0.0_"); + } + } else if (resultInt != NULL) { sprintf(buf, "%d_", *resultInt); } else { diff --git a/code/components/jomjol_flowcontroll/ClassFlowMQTT.cpp b/code/components/jomjol_flowcontroll/ClassFlowMQTT.cpp index f4e014e9..b82f7afe 100644 --- a/code/components/jomjol_flowcontroll/ClassFlowMQTT.cpp +++ b/code/components/jomjol_flowcontroll/ClassFlowMQTT.cpp @@ -6,6 +6,7 @@ #include "time_sntp.h" #include "interface_mqtt.h" #include "ClassFlowPostProcessing.h" +#include "ClassLogFile.h" #include @@ -31,9 +32,7 @@ void ClassFlowMQTT::SetInitialParameter(void) ListFlowControll = NULL; disabled = false; MQTTenable = false; - - - + keepAlive = 600; // TODO This must be greater than the Flow Interval! } ClassFlowMQTT::ClassFlowMQTT() @@ -124,11 +123,50 @@ bool ClassFlowMQTT::ReadParameter(FILE* pfile, string& aktparamgraph) printf("InitMQTTInit\n"); mainerrortopic = maintopic + "/connection"; printf("Init MQTT with uri: %s, clientname: %s, user: %s, password: %s, maintopic: %s\n", uri.c_str(), clientname.c_str(), user.c_str(), password.c_str(), mainerrortopic.c_str()); - MQTTInit(uri, clientname, user, password, mainerrortopic, 60); - MQTTPublish(mainerrortopic, "connected", SetRetainFlag); - MQTTenable = true; + if (!MQTTInit(uri, clientname, user, password, mainerrortopic, keepAlive)) + { // Failed + MQTTenable = false; + return true; // We need to return true despite we failed, else it will retry 5x and then reboot! + } } + + // Try sending mainerrortopic. If it fails, re-run init + if (!MQTTPublish(mainerrortopic, "connected", SetRetainFlag)) + { // Failed + LogFile.WriteToFile("MQTT - Re-running init...!"); + if (!MQTTInit(this->uri, this->clientname, this->user, this->password, this->mainerrortopic, keepAlive)) + { // Failed + MQTTenable = false; + return false; + } + } + + // Try again and quit if it fails + if (!MQTTPublish(mainerrortopic, "connected", SetRetainFlag)) + { // Failed + MQTTenable = false; + return false; + } + + + + /* if (!MQTTPublish(mainerrortopic, "connected", SetRetainFlag)) + { // Failed + LogFile.WriteToFile("MQTT - Could not publish connection status!"); + MQTTenable = false; + return true; // We need to return true despite we failed, else it will retry 5x and then reboot! + }*/ + + /* if(!MQTTPublish(_LWTContext, "", 1)) + { + LogFile.WriteToFile("MQTT - Could not publish LWT!"); + MQTTenable = false; + return true; // We need to return true despite we failed, else it will retry 5x and then reboot! + }*/ + + + MQTTenable = true; return true; } @@ -141,8 +179,44 @@ string ClassFlowMQTT::GetMQTTMainTopic() bool ClassFlowMQTT::doFlow(string zwtime) { - if (!MQTTenable) - return true; + // if (!MQTTenable) { + // LogFile.WriteToFile("MQTT not enabled!"); + // + // // Try again to init it + // if (!MQTTInit(this->uri, this->clientname, this->user, this->password, this->mainerrortopic, keepAlive)) + // { // Failed + // MQTTenable = false; + // return true; // We need to return true despite we failed, else it will retry 5x and then reboot! + // } + // + // if (!MQTTPublish(mainerrortopic, "connected", SetRetainFlag)) + // { // Failed + // MQTTenable = false; + // return true; // We need to return true despite we failed, else it will retry 5x and then reboot! + // } + // + // LogFile.WriteToFile("MQTT is now enabled"); + // MQTTenable = true; + // } + + + // Try sending mainerrortopic. If it fails, re-run init + if (!MQTTPublish(mainerrortopic, "connected", SetRetainFlag)) + { // Failed + LogFile.WriteToFile("MQTT - Re-running init...!"); + if (!MQTTInit(this->uri, this->clientname, this->user, this->password, this->mainerrortopic, keepAlive)) + { // Failed + MQTTenable = false; + return true; // We need to return true despite we failed, else it will retry 5x and then reboot! + } + } + + // Try again and quit if it fails + if (!MQTTPublish(mainerrortopic, "connected", SetRetainFlag)) + { // Failed + MQTTenable = false; + return true; // We need to return true despite we failed, else it will retry 5x and then reboot! + } std::string result; std::string resulterror = ""; @@ -153,7 +227,10 @@ bool ClassFlowMQTT::doFlow(string zwtime) string zw = ""; string namenumber = ""; - MQTTPublish(mainerrortopic, "connected"); + // if (!MQTTPublish(mainerrortopic, "connected", SetRetainFlag)) + //{ // Failed, skip other topics + // return true; // We need to return true despite we failed, else it will retry 5x and then reboot! + //} zw = maintopic + "/" + "uptime"; char uptimeStr[11]; @@ -163,13 +240,19 @@ bool ClassFlowMQTT::doFlow(string zwtime) zw = maintopic + "/" + "freeMem"; char freeheapmem[11]; sprintf(freeheapmem, "%zu", esp_get_free_heap_size()); - MQTTPublish(zw, freeheapmem, SetRetainFlag); + if (!MQTTPublish(zw, freeheapmem, SetRetainFlag)) + { // Failed, skip other topics + return true; // We need to return true despite we failed, else it will retry 5x and then reboot! + } zw = maintopic + "/" + "wifiRSSI"; char rssi[11]; sprintf(rssi, "%d", get_WIFI_RSSI()); MQTTPublish(zw, rssi, SetRetainFlag); + zw = maintopic + "/" + "CPUtemp"; + std::string cputemp = std::to_string(temperatureRead()); + MQTTPublish(zw, cputemp, SetRetainFlag); if (flowpostprocessing) { diff --git a/code/components/jomjol_flowcontroll/ClassFlowMQTT.h b/code/components/jomjol_flowcontroll/ClassFlowMQTT.h index 816389b1..3a990c7d 100644 --- a/code/components/jomjol_flowcontroll/ClassFlowMQTT.h +++ b/code/components/jomjol_flowcontroll/ClassFlowMQTT.h @@ -15,6 +15,7 @@ protected: std::string user, password; int SetRetainFlag; bool MQTTenable; + int keepAlive; std::string maintopic, mainerrortopic; void SetInitialParameter(void); diff --git a/code/components/jomjol_flowcontroll/ClassFlowPostProcessing.cpp b/code/components/jomjol_flowcontroll/ClassFlowPostProcessing.cpp index 9d0f85c5..73feef3e 100644 --- a/code/components/jomjol_flowcontroll/ClassFlowPostProcessing.cpp +++ b/code/components/jomjol_flowcontroll/ClassFlowPostProcessing.cpp @@ -9,6 +9,7 @@ #include #include "time_sntp.h" +//#define SERIAL_DEBUG // testing debug on serial enabled #define PREVALUE_TIME_FORMAT_OUTPUT "%Y-%m-%dT%H:%M:%S" @@ -68,7 +69,7 @@ string ClassFlowPostProcessing::GetPreValue(std::string _number) return result; } -void ClassFlowPostProcessing::SetPreValue(float zw, string _numbers, bool _extern) +void ClassFlowPostProcessing::SetPreValue(double zw, string _numbers, bool _extern) { printf("SetPrevalue: %f, %s\n", zw, _numbers.c_str()); for (int j = 0; j < NUMBERS.size(); ++j) @@ -126,7 +127,7 @@ bool ClassFlowPostProcessing::LoadPreValue(void) { if (NUMBERS[j]->name == name) { - NUMBERS[j]->PreValue = stof(zwvalue.c_str()); + NUMBERS[j]->PreValue = stod(zwvalue.c_str()); NUMBERS[j]->ReturnPreValue = RundeOutput(NUMBERS[j]->PreValue, NUMBERS[j]->Nachkomma + 1); // SIcherheitshalber 1 Stelle mehr, da ggf. Exgtended Resolution an ist (wird erst beim ersten Durchlauf gesetzt) time_t tStart; @@ -177,7 +178,7 @@ bool ClassFlowPostProcessing::LoadPreValue(void) fclose(pFile); printf("%s", zw); zwvalue = trim(std::string(zw)); - NUMBERS[0]->PreValue = stof(zwvalue.c_str()); + NUMBERS[0]->PreValue = stod(zwvalue.c_str()); time_t tStart; int yy, month, dd, hh, mm, ss; @@ -663,7 +664,9 @@ bool ClassFlowPostProcessing::doFlow(string zwtime) previous_value = zw - 48; } } - + #ifdef SERIAL_DEBUG + printf("After analog->getReadout: ReturnRaw %s\n", NUMBERS[j]->ReturnRawValue.c_str()); + #endif if (NUMBERS[j]->digit_roi && NUMBERS[j]->analog_roi) NUMBERS[j]->ReturnRawValue = "." + NUMBERS[j]->ReturnRawValue; @@ -674,16 +677,22 @@ bool ClassFlowPostProcessing::doFlow(string zwtime) else NUMBERS[j]->ReturnRawValue = flowDigit->getReadout(j, NUMBERS[j]->isExtendedResolution, previous_value); // Extended Resolution nur falls es keine analogen Ziffern gibt } - + #ifdef SERIAL_DEBUG + printf("After digital->getReadout: ReturnRaw %s\n", NUMBERS[j]->ReturnRawValue.c_str()); + #endif NUMBERS[j]->ReturnRawValue = ShiftDecimal(NUMBERS[j]->ReturnRawValue, NUMBERS[j]->DecimalShift); - printf("ReturnRaw %s", NUMBERS[j]->ReturnRawValue.c_str()); - + #ifdef SERIAL_DEBUG + printf("After ShiftDecimal: ReturnRaw %s\n", NUMBERS[j]->ReturnRawValue.c_str()); + #endif if (IgnoreLeadingNaN) while ((NUMBERS[j]->ReturnRawValue.length() > 1) && (NUMBERS[j]->ReturnRawValue[0] == 'N')) NUMBERS[j]->ReturnRawValue.erase(0, 1); + #ifdef SERIAL_DEBUG + printf("After IgnoreLeadingNaN: ReturnRaw %s\n", NUMBERS[j]->ReturnRawValue.c_str()); + #endif NUMBERS[j]->ReturnValue = NUMBERS[j]->ReturnRawValue; if (findDelimiterPos(NUMBERS[j]->ReturnValue, "N") != std::string::npos) @@ -693,18 +702,38 @@ bool ClassFlowPostProcessing::doFlow(string zwtime) else continue; // es gibt keinen Zahl, da noch ein N vorhanden ist. } - + #ifdef SERIAL_DEBUG + printf("After findDelimiterPos: ReturnValue %s\n", NUMBERS[j]->ReturnRawValue.c_str()); + #endif // Lösche führende Nullen (außer es ist nur noch einen 0) while ((NUMBERS[j]->ReturnValue.length() > 1) && (NUMBERS[j]->ReturnValue[0] == '0')) NUMBERS[j]->ReturnValue.erase(0, 1); - - NUMBERS[j]->Value = std::stof(NUMBERS[j]->ReturnValue); + #ifdef SERIAL_DEBUG + printf("After removeLeadingZeros: ReturnValue %s\n", NUMBERS[j]->ReturnRawValue.c_str()); + #endif + NUMBERS[j]->Value = std::stod(NUMBERS[j]->ReturnValue); + #ifdef SERIAL_DEBUG + printf("After setting the Value: Value %f and as double is %f\n", NUMBERS[j]->Value, std::stod(NUMBERS[j]->ReturnValue)); + #endif if (NUMBERS[j]->checkDigitIncreaseConsistency) { - NUMBERS[j]->Value = checkDigitConsistency(NUMBERS[j]->Value, NUMBERS[j]->DecimalShift, NUMBERS[j]->analog_roi != NULL, NUMBERS[j]->PreValue); + if (flowDigit) + { + if (flowDigit->getCNNType() != Digital) + printf("checkDigitIncreaseConsistency = true - ignored due to wrong CNN-Type (not Digital Classification)\n"); + else + NUMBERS[j]->Value = checkDigitConsistency(NUMBERS[j]->Value, NUMBERS[j]->DecimalShift, NUMBERS[j]->analog_roi != NULL, NUMBERS[j]->PreValue); + } + else + { + printf("checkDigitIncreaseConsistency = true - no digital numbers defined!\n"); + } } + #ifdef SERIAL_DEBUG + printf("After checkDigitIncreaseConsistency: Value %f\n", NUMBERS[j]->Value); + #endif if (!NUMBERS[j]->AllowNegativeRates) @@ -717,7 +746,9 @@ bool ClassFlowPostProcessing::doFlow(string zwtime) continue; } } - + #ifdef SERIAL_DEBUG + printf("After AllowNegativeRates: Value %f\n", NUMBERS[j]->Value); + #endif double difference = difftime(imagetime, NUMBERS[j]->lastvalue); // in Sekunden difference /= 60; NUMBERS[j]->FlowRateAct = (NUMBERS[j]->Value - NUMBERS[j]->PreValue) / difference; @@ -725,7 +756,7 @@ bool ClassFlowPostProcessing::doFlow(string zwtime) if (NUMBERS[j]->useMaxRateValue && PreValueUse && NUMBERS[j]->PreValueOkay) { - float _ratedifference; + double _ratedifference; if (NUMBERS[j]->RateType == RateChange) _ratedifference = NUMBERS[j]->FlowRateAct; else @@ -740,7 +771,9 @@ bool ClassFlowPostProcessing::doFlow(string zwtime) continue; } } - + #ifdef SERIAL_DEBUG + printf("After MaxRateCheck: Value %f\n", NUMBERS[j]->Value); + #endif NUMBERS[j]->ReturnChangeAbsolute = RundeOutput(NUMBERS[j]->Value - NUMBERS[j]->PreValue, NUMBERS[j]->Nachkomma); NUMBERS[j]->lastvalue = imagetime; NUMBERS[j]->PreValue = NUMBERS[j]->Value; @@ -818,7 +851,7 @@ string ClassFlowPostProcessing::getReadoutParam(bool _rawValue, bool _noerror, i return NUMBERS[_number]->ReturnValue; } -string ClassFlowPostProcessing::RundeOutput(float _in, int _anzNachkomma){ +string ClassFlowPostProcessing::RundeOutput(double _in, int _anzNachkomma){ std::stringstream stream; int _zw = _in; // printf("AnzNachkomma: %d\n", _anzNachkomma); @@ -842,7 +875,7 @@ string ClassFlowPostProcessing::RundeOutput(float _in, int _anzNachkomma){ } -string ClassFlowPostProcessing::ErsetzteN(string input, float _prevalue) +string ClassFlowPostProcessing::ErsetzteN(string input, double _prevalue) { int posN, posPunkt; int pot, ziffer; @@ -873,7 +906,7 @@ string ClassFlowPostProcessing::ErsetzteN(string input, float _prevalue) return input; } -float ClassFlowPostProcessing::checkDigitConsistency(float input, int _decilamshift, bool _isanalog, float _preValue){ +float ClassFlowPostProcessing::checkDigitConsistency(double input, int _decilamshift, bool _isanalog, double _preValue){ int aktdigit, olddigit; int aktdigit_before, olddigit_before; int pot, pot_max; @@ -885,8 +918,14 @@ float ClassFlowPostProcessing::checkDigitConsistency(float input, int _decilamsh { pot++; } + #ifdef SERIAL_DEBUG + printf("checkDigitConsistency: pot=%d, decimalshift=%d\n", pot, _decilamshift); + #endif pot_max = ((int) log10(input)) + 1; - + float not_checked_input = floorf(input * pow(10, pot)) / pow(10, pot); + #ifdef SERIAL_DEBUG + printf("checkDigitConsistency: not_checked_input=%f\n", not_checked_input); + #endif while (pot <= pot_max) { zw = input / pow(10, pot-1); @@ -915,11 +954,13 @@ float ClassFlowPostProcessing::checkDigitConsistency(float input, int _decilamsh input = input + ((float) (1)) * pow(10, pot); // addiere 1 an der Stelle } } - + #ifdef SERIAL_DEBUG + printf("checkDigitConsistency: input=%f", input); + #endif pot++; } - return input; + return not_checked_input + input; } string ClassFlowPostProcessing::getReadoutRate(int _number) diff --git a/code/components/jomjol_flowcontroll/ClassFlowPostProcessing.h b/code/components/jomjol_flowcontroll/ClassFlowPostProcessing.h index 34b2309c..0d99958d 100644 --- a/code/components/jomjol_flowcontroll/ClassFlowPostProcessing.h +++ b/code/components/jomjol_flowcontroll/ClassFlowPostProcessing.h @@ -32,9 +32,9 @@ protected: bool LoadPreValue(void); string ShiftDecimal(string in, int _decShift); - string ErsetzteN(string, float _prevalue); - float checkDigitConsistency(float input, int _decilamshift, bool _isanalog, float _preValue); - string RundeOutput(float _in, int _anzNachkomma); + string ErsetzteN(string, double _prevalue); + float checkDigitConsistency(double input, int _decilamshift, bool _isanalog, double _preValue); + string RundeOutput(double _in, int _anzNachkomma); void InitNUMBERS(); void handleDecimalSeparator(string _decsep, string _value); @@ -58,7 +58,7 @@ public: string getReadoutTimeStamp(int _number = 0); void SavePreValue(); string GetPreValue(std::string _number = ""); - void SetPreValue(float zw, string _numbers, bool _extern = false); + void SetPreValue(double zw, string _numbers, bool _extern = false); std::string GetJSON(std::string _id = "", std::string _mac = "", std::string _lineend = "\n"); diff --git a/code/components/jomjol_helper/Helper.cpp b/code/components/jomjol_helper/Helper.cpp index fe299f54..411553b0 100644 --- a/code/components/jomjol_helper/Helper.cpp +++ b/code/components/jomjol_helper/Helper.cpp @@ -209,6 +209,21 @@ size_t findDelimiterPos(string input, string delimiter) return pos; } +void DeleteFile(string fn) +{ +// ESP_LOGI(logTag, "Deleting file : %s", fn.c_str()); + /* Delete file */ + FILE* fpSourceFile = OpenFileAndWait(fn.c_str(), "rb"); + if (!fpSourceFile) // Sourcefile existiert nicht sonst gibt es einen Fehler beim Kopierversuch! + { + printf("DeleteFile: File %s existiert nicht!\n", fn.c_str()); + return; + } + fclose(fpSourceFile); + + unlink(fn.c_str()); +} + void CopyFile(string input, string output) { @@ -243,18 +258,48 @@ void CopyFile(string input, string output) // Close The Files fclose(fpSourceFile); fclose(fpTargetFile); + printf("File copied: %s to %s", input.c_str(), output.c_str()); } +string getFileFullFileName(string filename) +{ + size_t lastpos = filename.find_last_of('/'); + + if (lastpos == string::npos) + return ""; + +// printf("Last position: %d\n", lastpos); + + string zw = filename.substr(lastpos + 1, filename.size() - lastpos); + + return zw; +} + +string getDirectory(string filename) +{ + size_t lastpos = filename.find('/'); + + if (lastpos == string::npos) + return ""; + +// printf("Directory: %d\n", lastpos); + + string zw = filename.substr(0, lastpos - 1); + return zw; +} string getFileType(string filename) { - int lastpos = filename.find(".", 0); - int neu_pos; + size_t lastpos = filename.find(".", 0); + size_t neu_pos; while ((neu_pos = filename.find(".", lastpos + 1)) > -1) { lastpos = neu_pos; } + if (lastpos == string::npos) + return ""; + string zw = filename.substr(lastpos + 1, filename.size() - lastpos); zw = toUpper(zw); diff --git a/code/components/jomjol_helper/Helper.h b/code/components/jomjol_helper/Helper.h index 46fbf8d6..ab263cf2 100644 --- a/code/components/jomjol_helper/Helper.h +++ b/code/components/jomjol_helper/Helper.h @@ -10,6 +10,7 @@ std::string FormatFileName(std::string input); void FindReplace(std::string& line, std::string& oldString, std::string& newString); void CopyFile(string input, string output); +void DeleteFile(string fn); FILE* OpenFileAndWait(const char* nm, const char* _mode, int _waitsec = 1); @@ -19,6 +20,8 @@ string trim(string istring, string adddelimiter = ""); bool ctype_space(const char c, string adddelimiter); string getFileType(string filename); +string getFileFullFileName(string filename); +string getDirectory(string filename); int mkdir_r(const char *dir, const mode_t mode); int removeFolder(const char* folderPath, const char* logTag); diff --git a/code/components/jomjol_logfile/ClassLogFile.cpp b/code/components/jomjol_logfile/ClassLogFile.cpp index f9a790fe..f462e7a4 100644 --- a/code/components/jomjol_logfile/ClassLogFile.cpp +++ b/code/components/jomjol_logfile/ClassLogFile.cpp @@ -129,6 +129,7 @@ void ClassLogFile::WriteToFile(std::string info, bool _time) std::string logpath = logroot + "/" + buffer; WriteToDedicatedFile(logpath, info, _time); + printf((info + "\n").c_str()); } std::string ClassLogFile::GetCurrentFileName() diff --git a/code/components/jomjol_mqtt/interface_mqtt.cpp b/code/components/jomjol_mqtt/interface_mqtt.cpp index ef98aff4..556a50d8 100644 --- a/code/components/jomjol_mqtt/interface_mqtt.cpp +++ b/code/components/jomjol_mqtt/interface_mqtt.cpp @@ -19,18 +19,43 @@ esp_mqtt_event_id_t esp_mmqtt_ID = MQTT_EVENT_ANY; bool mqtt_connected = false; esp_mqtt_client_handle_t client = NULL; -void MQTTPublish(std::string _key, std::string _content, int retained_flag){ - if (client && mqtt_connected) { - int msg_id; - std::string zw; - msg_id = esp_mqtt_client_publish(client, _key.c_str(), _content.c_str(), 0, 1, retained_flag); - zw = "sent publish successful in MQTTPublish, msg_id=" + std::to_string(msg_id) + ", " + _key + ", " + _content; - if (debugdetail) LogFile.WriteToFile(zw); - ESP_LOGD(TAG_INTERFACEMQTT, "sent publish successful in MQTTPublish, msg_id=%d, %s, %s", msg_id, _key.c_str(), _content.c_str()); +bool MQTTPublish(std::string _key, std::string _content, int retained_flag){ + + // if (!client) { + // LogFile.WriteToFile("MQTT - client not initialized!"); + // return false; + // } + // LogFile.WriteToFile("MQTT - client initialized!"); // Debug + // + // if (!mqtt_connected) { + // LogFile.WriteToFile("MQTT - Can not publish, not connected!"); + // ESP_LOGW(TAG_INTERFACEMQTT, "Problem with Publish, client=%d, mqtt_connected %d", (int) client, (int) mqtt_connected); + // return false; + // } + // LogFile.WriteToFile("MQTT - connected!"); // Debug + + /* if (client && mqtt_connected) { + LogFile.WriteToFile("MQTT - connected!"); // Debug } - else { - ESP_LOGW(TAG_INTERFACEMQTT, "Problem with Publish, client=%d, mqtt_connected %d", (int) client, (int) mqtt_connected); + else { // init needed + if (!MQTTInit(this->uri, this->clientname, this->user, password, mainerrortopic, keepAlive)) // validate{ + { // Failed + return false; + } + }*/ + + + int msg_id; + std::string zw; + msg_id = esp_mqtt_client_publish(client, _key.c_str(), _content.c_str(), 0, 1, retained_flag); + if (msg_id < 0) { + LogFile.WriteToFile("MQTT - Failed to publish '" + _key + "'!"); + return false; } + zw = "MQTT - sent publish successful in MQTTPublish, msg_id=" + std::to_string(msg_id) + ", " + _key + ", " + _content; + if (debugdetail) LogFile.WriteToFile(zw); + ESP_LOGD(TAG_INTERFACEMQTT, "sent publish successful in MQTTPublish, msg_id=%d, %s, %s", msg_id, _key.c_str(), _content.c_str()); + return true; } @@ -90,11 +115,23 @@ static void mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_ mqtt_event_handler_cb((esp_mqtt_event_handle_t) event_data); } -void MQTTInit(std::string _mqttURI, std::string _clientid, std::string _user, std::string _password, std::string _LWTContext, int _keepalive){ + +bool MQTTInit(std::string _mqttURI, std::string _clientid, std::string _user, std::string _password, std::string _LWTContext, int _keepalive){ std::string _zwmessage = "connection lost"; int _lzw = _zwmessage.length(); +/* LWTContext = _LWTContext; + + mqtt_cfg.uri = _mqttURI.c_str(); + mqtt_cfg.client_id = _clientid.c_str(); + mqtt_cfg.lwt_topic = _LWTContext.c_str(); + mqtt_cfg.lwt_msg = _zwmessage.c_str(); + mqtt_cfg.lwt_retain = 1; + mqtt_cfg.lwt_msg_len = _lzw; + mqtt_cfg.keepalive = _keepalive; +*/ + esp_mqtt_client_config_t mqtt_cfg = { .uri = _mqttURI.c_str(), .client_id = _clientid.c_str(), @@ -105,12 +142,51 @@ void MQTTInit(std::string _mqttURI, std::string _clientid, std::string _user, st .keepalive = _keepalive }; + LogFile.WriteToFile("MQTT - Init"); + if (_user.length() && _password.length()){ mqtt_cfg.username = _user.c_str(); mqtt_cfg.password = _password.c_str(); ESP_LOGI(TAG_INTERFACEMQTT, "Connect to MQTT: %s, %s", mqtt_cfg.username, mqtt_cfg.password); }; + MQTTdestroy(); + client = esp_mqtt_client_init(&mqtt_cfg); + if (client) + { + if (esp_mqtt_client_register_event(client, esp_mmqtt_ID, mqtt_event_handler, client) != ESP_OK) + { + LogFile.WriteToFile("MQTT - Could not register event!"); + return false; + } + if (esp_mqtt_client_start(client) != ESP_OK) + { + LogFile.WriteToFile("MQTT - Could not start client!"); + return false; + } + + /* if(!MQTTPublish(_LWTContext, "", 1)) + { + LogFile.WriteToFile("MQTT - Could not publish LWT!"); + return false; + }*/ + } + else + { + LogFile.WriteToFile("MQTT - Could not Init client!"); + return false; + } + + LogFile.WriteToFile("MQTT - Init successful"); + return true; +} + +/* +void MQTTReConnect(){ + std::string _zwmessage = "connection lost"; + int _lzw = _zwmessage.length(); + +>>>>>>> Stashed changes client = esp_mqtt_client_init(&mqtt_cfg); if (client) { @@ -119,14 +195,25 @@ void MQTTInit(std::string _mqttURI, std::string _clientid, std::string _user, st if (esp_mqtt_client_start(client) != ESP_OK) LogFile.WriteToFile("MQTT - Could not start client!"); - MQTTPublish(_LWTContext, "", 1); +<<<<<<< Updated upstream + if(MQTTPublish(_LWTContext, "", 1)) { + LogFile.WriteToFile("MQTT - Client init successful"); + } +======= + if (mqtt_connected) + MQTTPublish(LWTContext, "", 1); + else + LogFile.WriteToFile("Problem with (Re)Connection not successful!"); + +>>>>>>> Stashed changes } else { - LogFile.WriteToFile("MQTT - Could not Init MQTT Client!"); + LogFile.WriteToFile("MQTT - Could not Init client!"); } } +*/ void MQTTdestroy() { if (client != NULL) { @@ -185,6 +272,7 @@ void MQTTregisterSubscribeFunction(std::string topic, std::function>::iterator it = connectFunktionMap->begin(); it != connectFunktionMap->end(); ++it) { it->second(); @@ -192,10 +280,11 @@ void MQTTconnected(){ } } - if (subscribeFunktionMap != NULL) { + if (subscribeFunktionMap != NULL) { for(std::map>::iterator it = subscribeFunktionMap->begin(); it != subscribeFunktionMap->end(); ++it) { int msg_id = esp_mqtt_client_subscribe(client, it->first.c_str(), 0); ESP_LOGD(TAG_INTERFACEMQTT, "topic %s subscribe successful, msg_id=%d", it->first.c_str(), msg_id); + LogFile.WriteToFile("MQTT - topic " + it->first + " subscribe successful, msg_id=" + std::to_string(msg_id)); } } } diff --git a/code/components/jomjol_mqtt/interface_mqtt.h b/code/components/jomjol_mqtt/interface_mqtt.h index 397d1787..06210782 100644 --- a/code/components/jomjol_mqtt/interface_mqtt.h +++ b/code/components/jomjol_mqtt/interface_mqtt.h @@ -5,12 +5,12 @@ #include #include -void MQTTInit(std::string _mqttURI, std::string _clientid, std::string _user, std::string _password, std::string _LWTContext, int _keepalive); +bool MQTTInit(std::string _mqttURI, std::string _clientid, std::string _user, std::string _password, std::string _LWTContext, int _keepalive); void MQTTdestroy(); //void MQTTInit(std::string _mqttURI, std::string _clientid, std::string _user = "", std::string _password = ""); -void MQTTPublish(std::string _key, std::string _content, int retained_flag = 1); // retained Flag as Standart +bool MQTTPublish(std::string _key, std::string _content, int retained_flag = 1); // retained Flag as Standart bool MQTTisConnected(); diff --git a/code/components/jomjol_tfliteclass/server_tflite.cpp b/code/components/jomjol_tfliteclass/server_tflite.cpp index 28619fcf..903cc6f4 100644 --- a/code/components/jomjol_tfliteclass/server_tflite.cpp +++ b/code/components/jomjol_tfliteclass/server_tflite.cpp @@ -21,6 +21,7 @@ #include "server_GPIO.h" #include "server_file.h" +#include "connect_wlan.h" #define DEBUG_DETAIL_ON @@ -590,6 +591,55 @@ esp_err_t handler_statusflow(httpd_req_t *req) return ESP_OK; }; +esp_err_t handler_cputemp(httpd_req_t *req) +{ +#ifdef DEBUG_DETAIL_ON + LogFile.WriteHeapInfo("handler_cputemp - Start"); +#endif + + const char* resp_str; + char cputemp[20]; + + sprintf(cputemp, "CPU Temp: %4.1f°C", temperatureRead()); + + resp_str = cputemp; + + httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*"); + httpd_resp_send(req, resp_str, strlen(resp_str)); + /* Respond with an empty chunk to signal HTTP response completion */ + httpd_resp_send_chunk(req, NULL, 0); + +#ifdef DEBUG_DETAIL_ON + LogFile.WriteHeapInfo("handler_cputemp - End"); +#endif + + return ESP_OK; +}; + +esp_err_t handler_rssi(httpd_req_t *req) +{ +#ifdef DEBUG_DETAIL_ON + LogFile.WriteHeapInfo("handler_rssi - Start"); +#endif + + const char* resp_str; + char rssi[20]; + + sprintf(rssi, "RSSI: %idBm", get_WIFI_RSSI()); + + resp_str = rssi; + + httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*"); + httpd_resp_send(req, resp_str, strlen(resp_str)); + /* Respond with an empty chunk to signal HTTP response completion */ + httpd_resp_send_chunk(req, NULL, 0); + +#ifdef DEBUG_DETAIL_ON + LogFile.WriteHeapInfo("handler_rssi - End"); +#endif + + return ESP_OK; +}; esp_err_t handler_prevalue(httpd_req_t *req) { @@ -643,7 +693,7 @@ esp_err_t handler_prevalue(httpd_req_t *req) httpd_resp_send_chunk(req, NULL, 0); #ifdef DEBUG_DETAIL_ON - LogFile.WriteHeapInfo("handler_prevalue - Start"); + LogFile.WriteHeapInfo("handler_prevalue - End"); #endif return ESP_OK; @@ -766,11 +816,26 @@ void register_server_tflite_uri(httpd_handle_t server) camuri.user_ctx = (void*) "Light Off"; httpd_register_uri_handler(server, &camuri); + camuri.uri = "/cputemp.html"; + camuri.handler = handler_cputemp; + camuri.user_ctx = (void*) "Light Off"; + httpd_register_uri_handler(server, &camuri); + + camuri.uri = "/rssi.html"; + camuri.handler = handler_rssi; + camuri.user_ctx = (void*) "Light Off"; + httpd_register_uri_handler(server, &camuri); + camuri.uri = "/editflow.html"; camuri.handler = handler_editflow; camuri.user_ctx = (void*) "EditFlow"; httpd_register_uri_handler(server, &camuri); + camuri.uri = "/value.html"; + camuri.handler = handler_wasserzaehler; + camuri.user_ctx = (void*) "Value"; + httpd_register_uri_handler(server, &camuri); + camuri.uri = "/wasserzaehler.html"; camuri.handler = handler_wasserzaehler; camuri.user_ctx = (void*) "Wasserzaehler"; diff --git a/code/main/version.cpp b/code/main/version.cpp index 7ac6d41c..faa24be9 100644 --- a/code/main/version.cpp +++ b/code/main/version.cpp @@ -1,4 +1,4 @@ -const char* GIT_REV="234925c"; -const char* GIT_TAG=""; -const char* GIT_BRANCH="master"; -const char* BUILD_TIME="2022-08-28 19:59"; \ No newline at end of file +const char* GIT_REV="N/A"; +const char* GIT_TAG="N/A"; +const char* GIT_BRANCH="N/A"; +const char* BUILD_TIME="2022-09-17 09:00"; \ No newline at end of file diff --git a/code/main/version.h b/code/main/version.h index eac09720..5b1ee98f 100644 --- a/code/main/version.h +++ b/code/main/version.h @@ -13,7 +13,7 @@ extern "C" #include "Helper.h" #include -const char* GIT_BASE_BRANCH = "master - v11.2.0 - 2022-08-28"; +const char* GIT_BASE_BRANCH = "master - v11.3.0 - 2022-09-16"; const char* git_base_branch(void) diff --git a/code/platformio.ini b/code/platformio.ini index 987e58e5..39b6032c 100644 --- a/code/platformio.ini +++ b/code/platformio.ini @@ -12,12 +12,12 @@ [platformio] src_dir = main - [env:esp32cam] platform = espressif32@4.4.0 ;platform = espressif32@5.1.0 ;platform = espressif32 board = esp32cam +;board = m5stack-core-esp32 framework = espidf ;board_build.partitions = partitions_singleapp.csv @@ -45,3 +45,6 @@ monitor_rts = 0 monitor_dtr = 0 debug_tool = esp-prog + +; Enable and adapt for logging over USB +;upload_port = /dev/ttyUSB0 \ No newline at end of file diff --git a/code/sdkconfig b/code/sdkconfig index 225d3a06..9b8daa3b 100644 --- a/code/sdkconfig +++ b/code/sdkconfig @@ -1028,7 +1028,7 @@ CONFIG_MQTT_TRANSPORT_SSL=y CONFIG_MQTT_TRANSPORT_WEBSOCKET=y CONFIG_MQTT_TRANSPORT_WEBSOCKET_SECURE=y # CONFIG_MQTT_MSG_ID_INCREMENTAL is not set -# CONFIG_MQTT_SKIP_PUBLISH_IF_DISCONNECTED is not set +CONFIG_MQTT_SKIP_PUBLISH_IF_DISCONNECTED is not set # CONFIG_MQTT_REPORT_DELETED_MESSAGES is not set # CONFIG_MQTT_USE_CUSTOM_CONFIG is not set # CONFIG_MQTT_TASK_CORE_SELECTION_ENABLED is not set diff --git a/code/sdkconfig.esp32cam b/code/sdkconfig.esp32cam index 5437b6a8..5510ad43 100644 --- a/code/sdkconfig.esp32cam +++ b/code/sdkconfig.esp32cam @@ -1036,7 +1036,7 @@ CONFIG_MQTT_TRANSPORT_SSL=y CONFIG_MQTT_TRANSPORT_WEBSOCKET=y CONFIG_MQTT_TRANSPORT_WEBSOCKET_SECURE=y # CONFIG_MQTT_MSG_ID_INCREMENTAL is not set -# CONFIG_MQTT_SKIP_PUBLISH_IF_DISCONNECTED is not set +CONFIG_MQTT_SKIP_PUBLISH_IF_DISCONNECTED=y # CONFIG_MQTT_REPORT_DELETED_MESSAGES is not set # CONFIG_MQTT_USE_CUSTOM_CONFIG is not set # CONFIG_MQTT_TASK_CORE_SELECTION_ENABLED is not set diff --git a/code/test/components/jomjol-flowcontroll/test_flowpostprocessing.cpp b/code/test/components/jomjol-flowcontroll/test_flowpostprocessing.cpp index 01b68800..ae4c360f 100644 --- a/code/test/components/jomjol-flowcontroll/test_flowpostprocessing.cpp +++ b/code/test/components/jomjol-flowcontroll/test_flowpostprocessing.cpp @@ -5,7 +5,8 @@ #include void setUpClassFlowPostprocessing(void); -string process_doFlow(std::vector analog, std::vector digits); +string process_doFlow(std::vector analog, std::vector digits, t_CNNType digType = Digital100, + bool checkConsistency=false, bool extendedResolution=false, int decimal_shift=0); ClassFlowCNNGeneral* _analog; ClassFlowCNNGeneral* _digit; @@ -43,13 +44,14 @@ void test_doFlow() { std::vector digits = { 1.2, 6.7}; std::vector analogs = { 9.5, 8.4}; const char* expected = "16.98"; + const char* expected_extended = "16.984"; std::string result = process_doFlow(analogs, digits); TEST_ASSERT_EQUAL_STRING(expected, result.c_str()); /* * https://github.com/jomjol/AI-on-the-edge-device/issues/921 * - * Das Ergebnis sollte "376529.6" sein. Bzw. 16.98 ohne Extended true + * Das Ergebnis sollte "376529.6" sein. */ digits = { 3.0, 7.0, 6.0, 5.0, 2.5, 9.6}; analogs = { 6.4}; @@ -158,11 +160,154 @@ void test_doFlow() { expected = "194.9089"; result = process_doFlow(analogs, digits); TEST_ASSERT_EQUAL_STRING(expected, result.c_str()); + + // Fehler bei V11.2.0 + // https://github.com/jomjol/AI-on-the-edge-device/issues/921#issuecomment-1229552041 + digits = { 2.9, 7.0, 7.0, 9.1, 8.1, 8.5}; // 376.9884(1) als falsches Ergebnis + analogs = { 4.1 }; + expected = "377988.4"; + result = process_doFlow(analogs, digits); + TEST_ASSERT_EQUAL_STRING(expected, result.c_str()); + + // Fehler bei V11.2.0 + // https://github.com/jomjol/AI-on-the-edge-device/issues/921#issuecomment-1233149877 + digits = { 0.0, 0.0, 7.0, 8.9}; // 79.9999(6) als falsches Ergebnis + analogs = { 0.1, 0.1, 0.1, 9.6}; + expected = "78.9999"; + result = process_doFlow(analogs, digits); + TEST_ASSERT_EQUAL_STRING(expected, result.c_str()); + + // Fehler bei V11.2.0 + // https://github.com/jomjol/AI-on-the-edge-device/issues/921#issuecomment-1236119370 + digits = { 3.1, 9.1, 5.7}; // 9.1 führt zu falscher Erkennung eines unvollständigen Übergangs + analogs = { 8.8, 6.1, 3.0, 2.0}; + expected = "395.8632"; + result = process_doFlow(analogs, digits); + TEST_ASSERT_EQUAL_STRING(expected, result.c_str()); + + // Fehler bei V11.2.0 + // https://github.com/jomjol/AI-on-the-edge-device/discussions/950#discussion-4338615 + digits = { 1.0, 9.0, 9.0}; // Übergang wurde um 1 erhöht (200, statt 199) + analogs = { 7.1, 4.8, 8.3}; + expected = "199.748"; + result = process_doFlow(analogs, digits, Digital); + TEST_ASSERT_EQUAL_STRING(expected, result.c_str()); + + // Fehler bei Rolling (2002-09-09) + // https://github.com/jomjol/AI-on-the-edge-device/issues/921#issuecomment-1242730397 + digits = { 3.0, 2.0, 2.0, 8.0, 9.0, 4.0, 1.7, 9.8}; // falscher Wert 32290.420 + analogs = { }; + expected = "32289.420"; + expected_extended= "32289.4198"; + // FALSCH! wegen ungenügender Präzision von NUMBERS->Value + // expected_extended= "32289.4198"; + + // extendResolution=false, checkConsistency=false + result = process_doFlow(analogs, digits, Digital100, false, false, -3); + TEST_ASSERT_EQUAL_STRING(expected, result.c_str()); + + // extendResolution=true + result = process_doFlow(analogs, digits, Digital100, false, true, -3); + TEST_ASSERT_EQUAL_STRING(expected_extended, result.c_str()); + + // checkConsistency=true und extendResolution=true + result = process_doFlow(analogs, digits, Digital100, false, true, -3); + TEST_ASSERT_EQUAL_STRING(expected_extended, result.c_str()); + + // Fehler Rolling (2022-09-10) + // not documented as issue + digits = { 0.0, 0.0, 7.9, 3.8}; // 84.99401 als falsches Ergebnis + analogs = { 0.0, 9.4, 4.1, 0.1}; + expected = "83.9940"; + expected_extended= "83.99401"; + + // checkConsistency=false + result = process_doFlow(analogs, digits, Digital100, false); + TEST_ASSERT_EQUAL_STRING(expected, result.c_str()); + + + // checkConsistency=true + result = process_doFlow(analogs, digits, Digital100, true); + TEST_ASSERT_EQUAL_STRING(expected, result.c_str()); + + // extendResolution=true + result = process_doFlow(analogs, digits, Digital100, false, true); + TEST_ASSERT_EQUAL_STRING(expected_extended, result.c_str()); + + // checkConsistency=true und extendResolution=true + result = process_doFlow(analogs, digits, Digital100, false, true); + TEST_ASSERT_EQUAL_STRING(expected_extended, result.c_str()); + + // Fehler Rolling (2022-09-10) + // https://github.com/jomjol/AI-on-the-edge-device/issues/994#issue-1368570945 + digits = { 0.0, 0.0, 1.0, 2.0, 2.8, 1.9, 2.8, 5.6}; // 123245.6 als falsches Ergebnis + analogs = { }; + expected = "123236"; + expected_extended= "123235.6"; + + // checkConsistency=true + result = process_doFlow(analogs, digits, Digital100, false, false); + TEST_ASSERT_EQUAL_STRING(expected, result.c_str()); + + + // checkConsistency=true + result = process_doFlow(analogs, digits, Digital100, true, false); + TEST_ASSERT_EQUAL_STRING(expected, result.c_str()); + + // extendResolution=true + result = process_doFlow(analogs, digits, Digital100, false, true); + TEST_ASSERT_EQUAL_STRING(expected_extended, result.c_str()); + + // Fehler bei V11.2.0 + // https://github.com/jomjol/AI-on-the-edge-device/discussions/950#discussioncomment-3661982 + digits = { 3.0, 2.0, 4.1, 9.0, 4.0, 6.3, 9.2}; // 3249.459 als falsches Ergebnis + analogs = { }; + expected = "3249.469"; + expected_extended= "3249.4692"; + + // checkConsistency=true + result = process_doFlow(analogs, digits, Digital100, false, false, -3); + TEST_ASSERT_EQUAL_STRING(expected, result.c_str()); + + + // checkConsistency=true + // checkConsistency NOT working correctly + //result = process_doFlow(analogs, digits, Digital100, true, false, -3); + //TEST_ASSERT_EQUAL_STRING(expected, result.c_str()); + + // extendResolution=true + result = process_doFlow(analogs, digits, Digital100, false, true, -3); + TEST_ASSERT_EQUAL_STRING(expected_extended, result.c_str()); + + // Fehler bei V11.2.0 + // https://github.com/jomjol/AI-on-the-edge-device/issues/1020#issue-1375648891 + digits = { 0.0, 2.0, 6.1, 9.2}; // 259.9227 als falsches Ergebnis + analogs = { 9.0, 2.5, 2.9, 7.2}; + expected = "269.9227"; + expected_extended= "269.92272"; + // Float Value reduziert die Genauigkeit hier. Korrekt wäre + // expected_extended= "269.92272"; + + // checkConsistency=true + result = process_doFlow(analogs, digits, Digital100, false, false); + TEST_ASSERT_EQUAL_STRING(expected, result.c_str()); + + + // checkConsistency=true + // checkConsistency NOT working correctly + //result = process_doFlow(analogs, digits, Digital100, true, false, -3); + //TEST_ASSERT_EQUAL_STRING(expected, result.c_str()); + + + // checkConsistency=true und extendResolution=true + result = process_doFlow(analogs, digits, Digital100, false, true); + TEST_ASSERT_EQUAL_STRING(expected_extended, result.c_str()); + } -void setUpClassFlowPostprocessing(void) +void setUpClassFlowPostprocessing(t_CNNType digType, t_CNNType anaType) { // wird im doFlow verwendet @@ -170,18 +315,19 @@ void setUpClassFlowPostprocessing(void) FlowControll.push_back(flowmakeimage); // Die Modeltypen werden gesetzt, da keine Modelle verwendet werden. - _analog = new ClassFlowCNNGeneral(nullptr, Analogue100); + _analog = new ClassFlowCNNGeneral(nullptr, anaType); - _digit = new ClassFlowCNNGeneral(nullptr, Digital100); + _digit = new ClassFlowCNNGeneral(nullptr, digType); undertestPost = new UnderTestPost(&FlowControll, _analog, _digit); } -std::string process_doFlow(std::vector analog, std::vector digits) { +std::string process_doFlow(std::vector analog, std::vector digits, t_CNNType digType, + bool checkConsistency, bool extendedResolution, int decimal_shift) { // setup the classundertest - setUpClassFlowPostprocessing(); + setUpClassFlowPostprocessing(digType, Analogue100); printf("SetupClassFlowPostprocessing completed.\n"); @@ -189,11 +335,11 @@ std::string process_doFlow(std::vector analog, std::vector digits) if (digits.size()>0) { general* gen_digit = _digit->GetGENERAL("default", true); gen_digit->ROI.clear(); - for (int i = 0; iname = name; + digitROI->result_klasse = (int) digits[i]; digitROI->result_float = digits[i]; gen_digit->ROI.push_back(digitROI); } @@ -215,6 +361,30 @@ std::string process_doFlow(std::vector analog, std::vector digits) printf("Setup ROIs completed.\n"); undertestPost->InitNUMBERS(); + if (checkConsistency) { + printf("checkConsistency=true\n"); + std::vector* NUMBERS = undertestPost->GetNumbers(); + for (int _n = 0; _n < (*NUMBERS).size(); ++_n) { + printf("Set checkConsistency on number: %d\n", _n); + (*NUMBERS)[_n]->checkDigitIncreaseConsistency = true; + } + } + if (extendedResolution ) { + std::vector* NUMBERS = undertestPost->GetNumbers(); + for (int _n = 0; _n < (*NUMBERS).size(); ++_n) { + printf("Set extendedResolution on number: %d\n", _n); + (*NUMBERS)[_n]->isExtendedResolution = true; + } + + } + if (decimal_shift!=0) { + std::vector* NUMBERS = undertestPost->GetNumbers(); + for (int _n = 0; _n < (*NUMBERS).size(); ++_n) { + printf("Set decimalshif on number: %d to %d\n", _n, decimal_shift); + (*NUMBERS)[_n]->DecimalShift = decimal_shift; + (*NUMBERS)[_n]->DecimalShiftInitial = decimal_shift; + } + } string time; // run test diff --git a/code/version.cpp b/code/version.cpp index 7ac6d41c..faa24be9 100644 --- a/code/version.cpp +++ b/code/version.cpp @@ -1,4 +1,4 @@ -const char* GIT_REV="234925c"; -const char* GIT_TAG=""; -const char* GIT_BRANCH="master"; -const char* BUILD_TIME="2022-08-28 19:59"; \ No newline at end of file +const char* GIT_REV="N/A"; +const char* GIT_TAG="N/A"; +const char* GIT_BRANCH="N/A"; +const char* BUILD_TIME="2022-09-17 09:00"; \ No newline at end of file diff --git a/firmware/bootloader.bin b/firmware/bootloader.bin index 07a73f5f..3046c597 100644 Binary files a/firmware/bootloader.bin and b/firmware/bootloader.bin differ diff --git a/firmware/firmware.bin b/firmware/firmware.bin index e4cadadd..699b481f 100644 Binary files a/firmware/firmware.bin and b/firmware/firmware.bin differ diff --git a/firmware/html.zip b/firmware/html.zip index 402fc1f2..8e335240 100644 Binary files a/firmware/html.zip and b/firmware/html.zip differ diff --git a/sd-card/config/ana-class100_0120_s1_q.tflite b/sd-card/config/ana-class100_0120_s1_q.tflite deleted file mode 100644 index d8f7ea58..00000000 Binary files a/sd-card/config/ana-class100_0120_s1_q.tflite and /dev/null differ diff --git a/sd-card/config/ana-class100_0130_s1_q.tflite b/sd-card/config/ana-class100_0130_s1_q.tflite new file mode 100644 index 00000000..338add82 Binary files /dev/null and b/sd-card/config/ana-class100_0130_s1_q.tflite differ diff --git a/sd-card/config/config.ini b/sd-card/config/config.ini index 5b657b46..ee7c75fc 100644 --- a/sd-card/config/config.ini +++ b/sd-card/config/config.ini @@ -25,9 +25,9 @@ Model = /config/dig-cont_0570_s3.tflite CNNGoodThreshold = 0.5 ;LogImageLocation = /log/digit ;LogfileRetentionInDays = 3 -main.dig1 294 126 30 54 -main.dig2 343 126 30 54 -main.dig3 391 126 30 54 +main.dig1 294 126 30 54 false +main.dig2 343 126 30 54 false +main.dig3 391 126 30 54 false [Analog] Model = /config/ana-cont_11.3.0_s2.tflite @@ -35,10 +35,10 @@ CNNGoodThreshold = 0.5 ;LogImageLocation = /log/analog ;LogfileRetentionInDays = 3 ExtendedResolution = true -main.ana1 432 230 92 92 -main.ana2 379 332 92 92 -main.ana3 283 374 92 92 -main.ana4 155 328 92 92 +main.ana1 432 230 92 92 false +main.ana2 379 332 92 92 false +main.ana3 283 374 92 92 false +main.ana4 155 328 92 92 false [PostProcessing] main.DecimalShift = 0 diff --git a/sd-card/config/dig-class100-0130_s2_q.tflite b/sd-card/config/dig-class100-0130_s2_q.tflite new file mode 100644 index 00000000..5134e3b2 Binary files /dev/null and b/sd-card/config/dig-class100-0130_s2_q.tflite differ diff --git a/sd-card/config/dig-class100_0120_s2_q.tflite b/sd-card/config/dig-class100_0120_s2_q.tflite deleted file mode 100644 index 5a32d59a..00000000 Binary files a/sd-card/config/dig-class100_0120_s2_q.tflite and /dev/null differ diff --git a/sd-card/html/FileSaver.min.js b/sd-card/html/FileSaver.min.js new file mode 100644 index 00000000..6d493b29 --- /dev/null +++ b/sd-card/html/FileSaver.min.js @@ -0,0 +1,3 @@ +(function(a,b){if("function"==typeof define&&define.amd)define([],b);else if("undefined"!=typeof exports)b();else{b(),a.FileSaver={exports:{}}.exports}})(this,function(){"use strict";function b(a,b){return"undefined"==typeof b?b={autoBom:!1}:"object"!=typeof b&&(console.warn("Deprecated: Expected third argument to be a object"),b={autoBom:!b}),b.autoBom&&/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(a.type)?new Blob(["\uFEFF",a],{type:a.type}):a}function c(a,b,c){var d=new XMLHttpRequest;d.open("GET",a),d.responseType="blob",d.onload=function(){g(d.response,b,c)},d.onerror=function(){console.error("could not download file")},d.send()}function d(a){var b=new XMLHttpRequest;b.open("HEAD",a,!1);try{b.send()}catch(a){}return 200<=b.status&&299>=b.status}function e(a){try{a.dispatchEvent(new MouseEvent("click"))}catch(c){var b=document.createEvent("MouseEvents");b.initMouseEvent("click",!0,!0,window,0,0,0,80,20,!1,!1,!1,!1,0,null),a.dispatchEvent(b)}}var f="object"==typeof window&&window.window===window?window:"object"==typeof self&&self.self===self?self:"object"==typeof global&&global.global===global?global:void 0,a=/Macintosh/.test(navigator.userAgent)&&/AppleWebKit/.test(navigator.userAgent)&&!/Safari/.test(navigator.userAgent),g=f.saveAs||("object"!=typeof window||window!==f?function(){}:"download"in HTMLAnchorElement.prototype&&!a?function(b,g,h){var i=f.URL||f.webkitURL,j=document.createElement("a");g=g||b.name||"download",j.download=g,j.rel="noopener","string"==typeof b?(j.href=b,j.origin===location.origin?e(j):d(j.href)?c(b,g,h):e(j,j.target="_blank")):(j.href=i.createObjectURL(b),setTimeout(function(){i.revokeObjectURL(j.href)},4E4),setTimeout(function(){e(j)},0))}:"msSaveOrOpenBlob"in navigator?function(f,g,h){if(g=g||f.name||"download","string"!=typeof f)navigator.msSaveOrOpenBlob(b(f,h),g);else if(d(f))c(f,g,h);else{var i=document.createElement("a");i.href=f,i.target="_blank",setTimeout(function(){e(i)})}}:function(b,d,e,g){if(g=g||open("","_blank"),g&&(g.document.title=g.document.body.innerText="downloading..."),"string"==typeof b)return c(b,d,e);var h="application/octet-stream"===b.type,i=/constructor/i.test(f.HTMLElement)||f.safari,j=/CriOS\/[\d]+/.test(navigator.userAgent);if((j||h&&i||a)&&"undefined"!=typeof FileReader){var k=new FileReader;k.onloadend=function(){var a=k.result;a=j?a:a.replace(/^data:[^;]*;/,"data:attachment/file;"),g?g.location.href=a:location=a,g=null},k.readAsDataURL(b)}else{var l=f.URL||f.webkitURL,m=l.createObjectURL(b);g?g.location=m:location.href=m,g=null,setTimeout(function(){l.revokeObjectURL(m)},4E4)}});f.saveAs=g.saveAs=g,"undefined"!=typeof module&&(module.exports=g)}); + +//# sourceMappingURL=FileSaver.min.js.map \ No newline at end of file diff --git a/sd-card/html/FileSaver.min.js.map b/sd-card/html/FileSaver.min.js.map new file mode 100644 index 00000000..7d5da054 --- /dev/null +++ b/sd-card/html/FileSaver.min.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["../src/FileSaver.js"],"names":[],"mappings":"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","file":"FileSaver.min.js","sourcesContent":["/*\n* FileSaver.js\n* A saveAs() FileSaver implementation.\n*\n* By Eli Grey, http://eligrey.com\n*\n* License : https://github.com/eligrey/FileSaver.js/blob/master/LICENSE.md (MIT)\n* source : http://purl.eligrey.com/github/FileSaver.js\n*/\n\n// The one and only way of getting global scope in all environments\n// https://stackoverflow.com/q/3277182/1008999\nvar _global = typeof window === 'object' && window.window === window\n ? window : typeof self === 'object' && self.self === self\n ? self : typeof global === 'object' && global.global === global\n ? global\n : this\n\nfunction bom (blob, opts) {\n if (typeof opts === 'undefined') opts = { autoBom: false }\n else if (typeof opts !== 'object') {\n console.warn('Deprecated: Expected third argument to be a object')\n opts = { autoBom: !opts }\n }\n\n // prepend BOM for UTF-8 XML and text/* types (including HTML)\n // note: your browser will automatically convert UTF-16 U+FEFF to EF BB BF\n if (opts.autoBom && /^\\s*(?:text\\/\\S*|application\\/xml|\\S*\\/\\S*\\+xml)\\s*;.*charset\\s*=\\s*utf-8/i.test(blob.type)) {\n return new Blob([String.fromCharCode(0xFEFF), blob], { type: blob.type })\n }\n return blob\n}\n\nfunction download (url, name, opts) {\n var xhr = new XMLHttpRequest()\n xhr.open('GET', url)\n xhr.responseType = 'blob'\n xhr.onload = function () {\n saveAs(xhr.response, name, opts)\n }\n xhr.onerror = function () {\n console.error('could not download file')\n }\n xhr.send()\n}\n\nfunction corsEnabled (url) {\n var xhr = new XMLHttpRequest()\n // use sync to avoid popup blocker\n xhr.open('HEAD', url, false)\n try {\n xhr.send()\n } catch (e) {}\n return xhr.status >= 200 && xhr.status <= 299\n}\n\n// `a.click()` doesn't work for all browsers (#465)\nfunction click (node) {\n try {\n node.dispatchEvent(new MouseEvent('click'))\n } catch (e) {\n var evt = document.createEvent('MouseEvents')\n evt.initMouseEvent('click', true, true, window, 0, 0, 0, 80,\n 20, false, false, false, false, 0, null)\n node.dispatchEvent(evt)\n }\n}\n\n// Detect WebView inside a native macOS app by ruling out all browsers\n// We just need to check for 'Safari' because all other browsers (besides Firefox) include that too\n// https://www.whatismybrowser.com/guides/the-latest-user-agent/macos\nvar isMacOSWebView = /Macintosh/.test(navigator.userAgent) && /AppleWebKit/.test(navigator.userAgent) && !/Safari/.test(navigator.userAgent)\n\nvar saveAs = _global.saveAs || (\n // probably in some web worker\n (typeof window !== 'object' || window !== _global)\n ? function saveAs () { /* noop */ }\n\n // Use download attribute first if possible (#193 Lumia mobile) unless this is a macOS WebView\n : ('download' in HTMLAnchorElement.prototype && !isMacOSWebView)\n ? function saveAs (blob, name, opts) {\n var URL = _global.URL || _global.webkitURL\n var a = document.createElement('a')\n name = name || blob.name || 'download'\n\n a.download = name\n a.rel = 'noopener' // tabnabbing\n\n // TODO: detect chrome extensions & packaged apps\n // a.target = '_blank'\n\n if (typeof blob === 'string') {\n // Support regular links\n a.href = blob\n if (a.origin !== location.origin) {\n corsEnabled(a.href)\n ? download(blob, name, opts)\n : click(a, a.target = '_blank')\n } else {\n click(a)\n }\n } else {\n // Support blobs\n a.href = URL.createObjectURL(blob)\n setTimeout(function () { URL.revokeObjectURL(a.href) }, 4E4) // 40s\n setTimeout(function () { click(a) }, 0)\n }\n }\n\n // Use msSaveOrOpenBlob as a second approach\n : 'msSaveOrOpenBlob' in navigator\n ? function saveAs (blob, name, opts) {\n name = name || blob.name || 'download'\n\n if (typeof blob === 'string') {\n if (corsEnabled(blob)) {\n download(blob, name, opts)\n } else {\n var a = document.createElement('a')\n a.href = blob\n a.target = '_blank'\n setTimeout(function () { click(a) })\n }\n } else {\n navigator.msSaveOrOpenBlob(bom(blob, opts), name)\n }\n }\n\n // Fallback to using FileReader and a popup\n : function saveAs (blob, name, opts, popup) {\n // Open a popup immediately do go around popup blocker\n // Mostly only available on user interaction and the fileReader is async so...\n popup = popup || open('', '_blank')\n if (popup) {\n popup.document.title =\n popup.document.body.innerText = 'downloading...'\n }\n\n if (typeof blob === 'string') return download(blob, name, opts)\n\n var force = blob.type === 'application/octet-stream'\n var isSafari = /constructor/i.test(_global.HTMLElement) || _global.safari\n var isChromeIOS = /CriOS\\/[\\d]+/.test(navigator.userAgent)\n\n if ((isChromeIOS || (force && isSafari) || isMacOSWebView) && typeof FileReader !== 'undefined') {\n // Safari doesn't allow downloading of blob URLs\n var reader = new FileReader()\n reader.onloadend = function () {\n var url = reader.result\n url = isChromeIOS ? url : url.replace(/^data:[^;]*;/, 'data:attachment/file;')\n if (popup) popup.location.href = url\n else location = url\n popup = null // reverse-tabnabbing #460\n }\n reader.readAsDataURL(blob)\n } else {\n var URL = _global.URL || _global.webkitURL\n var url = URL.createObjectURL(blob)\n if (popup) popup.location = url\n else location.href = url\n popup = null // reverse-tabnabbing #460\n setTimeout(function () { URL.revokeObjectURL(url) }, 4E4) // 40s\n }\n }\n)\n\n_global.saveAs = saveAs.saveAs = saveAs\n\nif (typeof module !== 'undefined') {\n module.exports = saveAs;\n}\n"]} \ No newline at end of file diff --git a/sd-card/html/backup.html b/sd-card/html/backup.html new file mode 100644 index 00000000..52c93557 --- /dev/null +++ b/sd-card/html/backup.html @@ -0,0 +1,140 @@ + + + + +Backup/Restore Configuration + + + + + + + +

Backup Configuration

+

With the following action the config folder on the SD-card gets zipped and provided as a download.

+ + + + + + +
+ + +

+
+
+

Restore Configuration

+

Use the File Server to upload individual files.

+ + + + + + + + diff --git a/sd-card/html/common.js b/sd-card/html/common.js new file mode 100644 index 00000000..130bda20 --- /dev/null +++ b/sd-card/html/common.js @@ -0,0 +1,31 @@ + +var basepath = "http://192.168.178.22"; + +function LoadHostname() { + _basepath = getbasepath(); + + + var xhttp = new XMLHttpRequest(); + xhttp.addEventListener('load', function(event) { + if (xhttp.status >= 200 && xhttp.status < 300) { + hostname = xhttp.responseText; + document.title = hostname + " - AI on the edge"; + document.getElementById("id_title").innerHTML = "Digitizer - AI on the edge - " + hostname; + } + else { + console.warn(request.statusText, request.responseText); + } + }); + +// var xhttp = new XMLHttpRequest(); + try { + url = _basepath + '/version?type=Hostname'; + xhttp.open("GET", url, true); + xhttp.send(); + + } + catch (error) + { +// alert("Loading Hostname failed"); + } +} diff --git a/sd-card/html/edit_alignment.html b/sd-card/html/edit_alignment.html index 166231b1..f0488261 100644 --- a/sd-card/html/edit_alignment.html +++ b/sd-card/html/edit_alignment.html @@ -86,7 +86,10 @@ select { - + + + +
@@ -107,7 +110,17 @@ select { basepath = "http://192.168.178.26"; basepath = "", param; - + +function doReboot() { + if (confirm("Are you sure you want to reboot? Did you save the config?")) { + var stringota = "/reboot"; + window.location = stringota; + window.location.href = stringota; + window.location.assign(stringota); + window.location.replace(stringota); + } +} + function ChangeSelection(){ aktindex = parseInt(document.getElementById("index").value); UpdateReference(); diff --git a/sd-card/html/edit_analog.html b/sd-card/html/edit_analog.html index 61d4237c..0d8eed40 100644 --- a/sd-card/html/edit_analog.html +++ b/sd-card/html/edit_analog.html @@ -116,18 +116,22 @@ th, td { x: dx: - + y: dy: + - + + + +
@@ -147,8 +151,17 @@ th, td { enhanceCon = false; lockAR = true; basepath = "http://192.168.178.26"; - - + +function doReboot() { + if (confirm("Are you sure you want to reboot? Did you save the config?")) { + var stringota = "/reboot"; + window.location = stringota; + window.location.href = stringota; + window.location.assign(stringota); + window.location.replace(stringota); + } +} + function EnDisableAnalog() { isEnabled = document.getElementById("Category_Analog_enabled").checked; @@ -204,9 +217,9 @@ function newROI(){ var _roinew = prompt("Please enter name of new ROI", "name"); if (ROIInfo.length > 0) - erg = CreateROI(_number, "analog", sel.selectedIndex, _roinew, 1, 1, ROIInfo[aktindex]["dx"], ROIInfo[aktindex]["dy"]); + erg = CreateROI(_number, "analog", sel.selectedIndex, _roinew, 1, 1, ROIInfo[aktindex]["dx"], ROIInfo[aktindex]["dy"], ROIInfo[aktindex]["CCW"]=="true"); else - erg = CreateROI(_number, "analog", sel.selectedIndex, _roinew, 1, 1, 30, 30); + erg = CreateROI(_number, "analog", sel.selectedIndex, _roinew, 1, 1, 30, 30, false); if (erg != "") alert(erg); @@ -234,6 +247,20 @@ function changelockAR(){ lockAR = document.getElementById("lockAR").checked; } +function changeCCW(){ + var sel = document.getElementById("Numbers_value1"); + var _number = sel.options[sel.selectedIndex].text; + + ROIInfo = getROIInfo("analog", _number); + aktindex = parseInt(document.getElementById("index").value); + + if (document.getElementById("CCW").checked) + ROIInfo[aktindex]["CCW"] = "true"; + else + ROIInfo[aktindex]["CCW"] = "false"; + UpdateROIs(); +} + function ChangeSelection(){ aktindex = parseInt(document.getElementById("index").value); // lockAR = true; @@ -249,7 +276,7 @@ function SaveToConfig(){ } -function UpdateROIs(){ +function UpdateROIs(_sel){ document.getElementById("Category_Analog_enabled").checked = true; var sel = document.getElementById("Numbers_value1"); var _number = sel.options[sel.selectedIndex].text; @@ -320,6 +347,8 @@ function UpdateROIs(){ document.getElementById("refy").value = ROIInfo[aktindex]["y"]; document.getElementById("refdx").value = ROIInfo[aktindex]["dx"]; document.getElementById("refdy").value = ROIInfo[aktindex]["dy"]; + document.getElementById("CCW").checked = ROIInfo[aktindex]["CCW"] == "true"; + rect.startX = ROIInfo[aktindex]["x"]; rect.startY = ROIInfo[aktindex]["y"]; rect.w = ROIInfo[aktindex]["dx"]; diff --git a/sd-card/html/edit_config_param.html b/sd-card/html/edit_config_param.html index aacac873..a3ffcb12 100644 --- a/sd-card/html/edit_config_param.html +++ b/sd-card/html/edit_config_param.html @@ -611,8 +611,12 @@ textarea { - MQTT main topic, under which the counters are published. The single value will be published with the following key: MAINTOPIC/VALUE_NAME/PARAMETER
- where parameters are: value, rate, timestamp, error
+ MQTT main topic, under which the counters are published.
+ The single value will be published with the following key: MAINTOPIC/VALUE_NAME/PARAMETER where +
    +
  • VALUE_NAME is the name of the value (a meter might have more than one value) as defined during analog and digital ROI configuration (defaults to "main")
  • +
  • and PARAMETERS are: value, rate, timestamp, error
  • +
The general connection status can be found in MAINTOPIC/CONNECTION diff --git a/sd-card/html/edit_digits.html b/sd-card/html/edit_digits.html index 711db2f1..c0685acb 100644 --- a/sd-card/html/edit_digits.html +++ b/sd-card/html/edit_digits.html @@ -119,6 +119,9 @@ th, td { + + +
@@ -140,6 +143,15 @@ th, td { lockAR = true; basepath = "http://192.168.178.26"; + function doReboot() { + if (confirm("Are you sure you want to reboot? Did you save the config?")) { + var stringota = "/reboot"; + window.location = stringota; + window.location.href = stringota; + window.location.assign(stringota); + window.location.replace(stringota); + } + } function EnDisableDigits() { isEnabled = document.getElementById("Category_Digits_enabled").checked; @@ -197,9 +209,9 @@ function newROI() { var _roinew = prompt("Please enter name of new ROI", "name"); if (ROIInfo.length > 0) - erg = CreateROI(_number, "digit", sel.selectedIndex, _roinew, 1, 1, ROIInfo[aktindex]["dx"], ROIInfo[aktindex]["dy"]); + erg = CreateROI(_number, "digit", sel.selectedIndex, _roinew, 1, 1, ROIInfo[aktindex]["dx"], ROIInfo[aktindex]["dy"], 0); else - erg = CreateROI(_number, "digit", sel.selectedIndex, _roinew, 1, 1, 30, 51); + erg = CreateROI(_number, "digit", sel.selectedIndex, _roinew, 1, 1, 30, 51, 0); if (erg != "") alert(erg); diff --git a/sd-card/html/edit_explain_0.html b/sd-card/html/edit_explain_0.html index 338797b9..d3bb9310 100644 --- a/sd-card/html/edit_explain_0.html +++ b/sd-card/html/edit_explain_0.html @@ -2,14 +2,11 @@ -jomjol - AI on the edge +AI on the edge + + + + + - + +
@@ -82,71 +127,35 @@ li.dropdown {
-

- -

- -
- - - - + +
+ diff --git a/sd-card/html/index_configure.html b/sd-card/html/index_configure.html index 19afc3b9..9fee5888 100644 --- a/sd-card/html/index_configure.html +++ b/sd-card/html/index_configure.html @@ -2,76 +2,117 @@ -jomjol - AI on the edge +AI on the edge - + + - + +
@@ -81,62 +122,44 @@ li.dropdown {
-

-

- -
- + + + + + + +
+ diff --git a/sd-card/html/info.html b/sd-card/html/info.html index 8434cd28..2324a114 100644 --- a/sd-card/html/info.html +++ b/sd-card/html/info.html @@ -2,7 +2,7 @@ -Set PreValue +Info + + + + +Check at https://github.com/jomjol/AI-on-the-edge-device/releases to see if there is an update available. +

It is strongly recommended to update firmware and web interface (stored separately in the html directory on SD-card) at the same time!

+
+

Update

+ + + + +
+ + + + + + + + + + + +
+ + + + + +
+ + + + + +
+
+

Reboot

+ +
+ + + + + + + diff --git a/sd-card/html/ota_page_v2.html b/sd-card/html/ota_page_v2.html index 9c8cfb0b..dfc0f126 100644 --- a/sd-card/html/ota_page_v2.html +++ b/sd-card/html/ota_page_v2.html @@ -1,7 +1,7 @@ - jomjol - AI on the edge + AI on the edge