diff --git a/Changelog.md b/Changelog.md index 380079a14..88e4303d8 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,3 +1,19 @@ +## [15.3.0] - 2023-07-22 + +### Changes + +For a full list of changes see [Full list of changes](https://github.com/jomjol/AI-on-the-edge-device/compare/v15.2.1...v15.2.4) + +#### Changed + + - Updated PlatformIO to `6.3.2` + - Updated analog tflite files + - ana-cont_1207_s2_q.tflite + - dig-cont_0620_s3_q.tflite + + + + ## [15.2.4] - 2023-05-02 ### Changes diff --git a/code/components/jomjol_fileserver_ota/server_file.cpp b/code/components/jomjol_fileserver_ota/server_file.cpp index 1bb65e35d..21d4f3cb0 100644 --- a/code/components/jomjol_fileserver_ota/server_file.cpp +++ b/code/components/jomjol_fileserver_ota/server_file.cpp @@ -717,7 +717,8 @@ static esp_err_t upload_post_handler(httpd_req_t *req) /* Close file upon upload completion */ fclose(fd); - ESP_LOGI(TAG, "File reception complete"); + LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "File saved: " + string(filename)); + ESP_LOGI(TAG, "File reception completed"); std::string directory = std::string(filepath); size_t zw = directory.find("/"); @@ -736,21 +737,27 @@ static esp_err_t upload_post_handler(httpd_req_t *req) // ESP_LOGD(TAG, "Directory danach 2: %s", directory.c_str()); /* Redirect onto root to see the updated file list */ - httpd_resp_set_status(req, "303 See Other"); - httpd_resp_set_hdr(req, "Location", directory.c_str()); + if (strcmp(filename, "/config/config.ini") == 0 || + strcmp(filename, "/config/ref0.jpg") == 0 || + strcmp(filename, "/config/ref0_org.jpg") == 0 || + strcmp(filename, "/config/ref1.jpg") == 0 || + strcmp(filename, "/config/ref1_org.jpg") == 0 || + strcmp(filename, "/config/reference.jpg") == 0 || + strcmp(filename, "/img_tmp/ref0.jpg") == 0 || + strcmp(filename, "/img_tmp/ref0_org.jpg") == 0 || + strcmp(filename, "/img_tmp/ref1.jpg") == 0 || + strcmp(filename, "/img_tmp/ref1_org.jpg") == 0 || + strcmp(filename, "/img_tmp/reference.jpg") == 0 ) + { + httpd_resp_set_status(req, HTTPD_200); // Avoid reloading of folder content + } + else { + httpd_resp_set_status(req, "303 See Other"); // Reload folder content after upload + } - /* Redirect onto root to see the updated file list */ - httpd_resp_set_status(req, "303 See Other"); httpd_resp_set_hdr(req, "Location", directory.c_str()); httpd_resp_sendstr(req, "File uploaded successfully"); -/* - if (strcmp(filepath, CONFIG_FILE) == 0) { - ESP_LOGD(TAG, "New config found. Reload handler."); - gpio_handler_deinit(); - MQTTdestroy(); - } -*/ return ESP_OK; } @@ -837,16 +844,15 @@ static esp_err_t delete_post_handler(httpd_req_t *req) return ESP_FAIL; } - if (stat(filepath, &file_stat) == -1) { - LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "File does not exist: " + string(filename)); - /* Respond with 400 Bad Request */ - httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "File does not exist"); - return ESP_FAIL; + if (stat(filepath, &file_stat) == -1) { // File does not exist + /* This is ok, we would delete it anyway */ + LogFile.WriteToFile(ESP_LOG_INFO, TAG, "File does not exist: " + string(filename)); } - LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Deleting file: " + string(filename)); /* Delete file */ unlink(filepath); + LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "File deleted: " + string(filename)); + ESP_LOGI(TAG, "File deletion completed"); directory = std::string(filepath); size_t zw = directory.find("/"); @@ -863,16 +869,30 @@ static esp_err_t delete_post_handler(httpd_req_t *req) directory = directory.substr(start_fn, found - start_fn + 1); directory = "/fileserver" + directory; ESP_LOGD(TAG, "Directory danach 4: %s", directory.c_str()); - } + ////////////////////////////////////////////////////////////// + /* Redirect onto root to see the updated file list */ + if (strcmp(filename, "/config/config.ini") == 0 || + strcmp(filename, "/config/ref0.jpg") == 0 || + strcmp(filename, "/config/ref0_org.jpg") == 0 || + strcmp(filename, "/config/ref1.jpg") == 0 || + strcmp(filename, "/config/ref1_org.jpg") == 0 || + strcmp(filename, "/config/reference.jpg") == 0 || + strcmp(filename, "/img_tmp/ref0.jpg") == 0 || + strcmp(filename, "/img_tmp/ref0_org.jpg") == 0 || + strcmp(filename, "/img_tmp/ref1.jpg") == 0 || + strcmp(filename, "/img_tmp/ref1_org.jpg") == 0 || + strcmp(filename, "/img_tmp/reference.jpg") == 0 ) + { + httpd_resp_set_status(req, HTTPD_200); // Avoid reloading of folder content + } + else { + httpd_resp_set_status(req, "303 See Other"); // Reload folder content after upload + } + } - -////////////////////////////////////////////////////////////// - - /* Redirect onto root to see the updated file list */ - httpd_resp_set_status(req, "303 See Other"); httpd_resp_set_hdr(req, "Location", directory.c_str()); httpd_resp_sendstr(req, "File successfully deleted"); return ESP_OK; @@ -929,7 +949,7 @@ std::string unzip_new(std::string _in_zip_file, std::string _target_zip, std::st // Get and print information about each file in the archive. int numberoffiles = (int)mz_zip_reader_get_num_files(&zip_archive); - LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Numbers of files to be extracted: " + to_string(numberoffiles)); + LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Files to be extracted: " + to_string(numberoffiles)); sort_iter = 0; { @@ -993,7 +1013,7 @@ std::string unzip_new(std::string _in_zip_file, std::string _target_zip, std::st string filename_zw = zw + SUFFIX_ZW; - ESP_LOGI(TAG, "Filename to extract: %s, Zwischenfilename: %s", zw.c_str(), filename_zw.c_str()); + ESP_LOGI(TAG, "File to extract: %s, Temp. Filename: %s", zw.c_str(), filename_zw.c_str()); std::string folder = filename_zw.substr(0, filename_zw.find_last_of('/')); MakeDir(folder); @@ -1097,7 +1117,7 @@ void unzip(std::string _in_zip_file, std::string _target_directory){ // Save to File. zw = std::string(archive_filename); zw = _target_directory + zw; - ESP_LOGD(TAG, "Filename to extract: %s", zw.c_str()); + ESP_LOGD(TAG, "File to extract: %s", zw.c_str()); FILE* fpTargetFile = fopen(zw.c_str(), "wb"); fwrite(p, 1, (uint)uncomp_size, fpTargetFile); fclose(fpTargetFile); diff --git a/code/components/jomjol_fileserver_ota/server_help.cpp b/code/components/jomjol_fileserver_ota/server_help.cpp index 60d3c9c62..c878aa91c 100644 --- a/code/components/jomjol_fileserver_ota/server_help.cpp +++ b/code/components/jomjol_fileserver_ota/server_help.cpp @@ -61,7 +61,13 @@ esp_err_t send_file(httpd_req_t *req, std::string filename) endsWith(filename, ".jpeg") || endsWith(filename, ".ico") || endsWith(filename, ".png")) { - httpd_resp_set_hdr(req, "Cache-Control", "max-age=86400"); + + if (filename == "/sdcard/html/setup.html") { + httpd_resp_set_hdr(req, "Clear-Site-Data", "\"*\""); + } + else { + httpd_resp_set_hdr(req, "Cache-Control", "max-age=86400"); + } } set_content_type_from_file(req, filename.c_str()); diff --git a/code/components/jomjol_flowcontroll/ClassFlowCNNGeneral.cpp b/code/components/jomjol_flowcontroll/ClassFlowCNNGeneral.cpp index 821fc89a7..ac1e6c280 100644 --- a/code/components/jomjol_flowcontroll/ClassFlowCNNGeneral.cpp +++ b/code/components/jomjol_flowcontroll/ClassFlowCNNGeneral.cpp @@ -55,7 +55,7 @@ string ClassFlowCNNGeneral::getReadout(int _analog = 0, bool _extendedResolution // LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "getReadout(analog) number=" + std::to_string(number) + ", result_after_decimal_point=" + std::to_string(result_after_decimal_point) + ", prev=" + std::to_string(prev)); result = std::to_string(prev); - if (_extendedResolution && (CNNType != Digital)) + if (_extendedResolution) result = result + std::to_string(result_after_decimal_point); for (int i = GENERAL[_analog]->ROI.size() - 2; i >= 0; --i) @@ -142,11 +142,10 @@ int ClassFlowCNNGeneral::PointerEvalHybridNew(float number, float number_of_pred int result_before_decimal_point = ((int) floor(number) + 10) % 10; if (eval_predecessors < 0) - { - if ((result_after_decimal_point <= Digital_Uncertainty * 10) || (result_after_decimal_point >= Digital_Uncertainty * 10)) // Band around the digit --> Rounding, as digit reaches inaccuracy in the frame - result = (int) (round(number) + 10) % 10; - else - result = (int) ((int) trunc(number) + 10) % 10; + { + // on first digit is no spezial logic for transition needed + // we use the recognition as given. The result is the int value of the recognition + result = (int) ((int) trunc(number) + 10) % 10; LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "PointerEvalHybridNew - No predecessor - Result = " + std::to_string(result) + " number: " + std::to_string(number) + " number_of_predecessors = " + std::to_string(number_of_predecessors)+ " eval_predecessors = " + std::to_string(eval_predecessors) + " Digital_Uncertainty = " + std::to_string(Digital_Uncertainty)); diff --git a/code/components/jomjol_flowcontroll/ClassFlowControll.h b/code/components/jomjol_flowcontroll/ClassFlowControll.h index dc09555af..e0d5f74e2 100644 --- a/code/components/jomjol_flowcontroll/ClassFlowControll.h +++ b/code/components/jomjol_flowcontroll/ClassFlowControll.h @@ -34,13 +34,14 @@ class ClassFlowControll : bool AutoStart; float AutoInterval; - bool SetupModeActive; void SetInitialParameter(void); std::string aktstatusWithTime; std::string aktstatus; int aktRunNr; public: + bool SetupModeActive; + void InitFlow(std::string config); bool doFlow(string time); void doFlowTakeImageOnly(string time); diff --git a/code/components/jomjol_flowcontroll/ClassFlowPostProcessing.cpp b/code/components/jomjol_flowcontroll/ClassFlowPostProcessing.cpp index ceed7d3a2..351bcc0e9 100644 --- a/code/components/jomjol_flowcontroll/ClassFlowPostProcessing.cpp +++ b/code/components/jomjol_flowcontroll/ClassFlowPostProcessing.cpp @@ -866,12 +866,12 @@ bool ClassFlowPostProcessing::doFlow(string zwtime) LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "handleAllowNegativeRate for device: " + NUMBERS[j]->name); if ((NUMBERS[j]->Value < NUMBERS[j]->PreValue)) { - #ifdef SERIAL_DEBUG - ESP_LOGD(TAG, "Neg: value=%f, preValue=%f, preToll%f", NUMBERS[j]->Value, NUMBERS[j]->PreValue, - NUMBERS[j]->PreValue-(2/pow(10, NUMBERS[j]->Nachkomma)) - ) ; - #endif - + // more debug if extended resolution is on, see #2447 + if (NUMBERS[j]->isExtendedResolution) { + LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Neg: value=" + std::to_string(NUMBERS[j]->Value) + + ", preValue=" + std::to_string(NUMBERS[j]->PreValue) + + ", preToll=" + std::to_string(NUMBERS[j]->PreValue-(2/pow(10, NUMBERS[j]->Nachkomma)))); + } // Include inaccuracy of 0.2 for isExtendedResolution. if (NUMBERS[j]->Value >= (NUMBERS[j]->PreValue-(2/pow(10, NUMBERS[j]->Nachkomma))) && NUMBERS[j]->isExtendedResolution) { NUMBERS[j]->Value = NUMBERS[j]->PreValue; diff --git a/code/components/jomjol_flowcontroll/MainFlowControl.cpp b/code/components/jomjol_flowcontroll/MainFlowControl.cpp index 26084fb29..18f1f723e 100644 --- a/code/components/jomjol_flowcontroll/MainFlowControl.cpp +++ b/code/components/jomjol_flowcontroll/MainFlowControl.cpp @@ -230,7 +230,7 @@ esp_err_t handler_stream(httpd_req_t *req) if (httpd_query_key_value(_query, "flashlight", _value, 10) == ESP_OK) { #ifdef DEBUG_DETAIL_ON - ESP_LOGD(TAG, "flashlight is found%s", _size); + ESP_LOGD(TAG, "flashlight is found%s", _value); #endif if (strlen(_value) > 0) flashlightOn = true; @@ -453,7 +453,7 @@ esp_err_t handler_wasserzaehler(httpd_req_t *req) else { /* Digital ROIs */ txt = ""; - txt += "

Recognized Digit ROIs (previous round)

\n"; + txt += "

Recognized Digit ROIs (previous round)

\n"; txt += "\n"; std::vector htmlinfodig; @@ -488,7 +488,7 @@ esp_err_t handler_wasserzaehler(httpd_req_t *req) /* Analog ROIs */ - txt = "

Recognized Analog ROIs (previous round)

\n"; + txt = "

Recognized Analog ROIs (previous round)

\n"; txt += "
\n"; std::vector htmlinfoana; @@ -510,7 +510,7 @@ esp_err_t handler_wasserzaehler(httpd_req_t *req) /* Full Image * Only show it after the image got taken and aligned */ - txt = "

Aligned Image (current round)

\n"; + txt = "

Aligned Image (current round)

\n"; if ((*status == std::string("Initialization")) || (*status == std::string("Initialization (delayed)")) || (*status == std::string("Take Image"))) { @@ -657,14 +657,7 @@ esp_err_t handler_editflow(httpd_req_t *req) string out2 = out.substr(0, out.length() - 4) + "_org.jpg"; - std::string state = *flowctrl.getActStatus(); - - /* To be able to provide the image, several conditions must be met due to the shared PSRAM usage: - - Ether the round most be completed or not started yet - - Or we must be in Setup Mode - - Additionally, the initialization of the shared PSRAM must be successful */ - if (((state == "Flow finished") || (state == "Initialization") || (state == "Initialization (delayed)") || isSetupModusActive()) && - psram_init_shared_memory_for_take_image_step()) { + if ((flowctrl.SetupModeActive || (*flowctrl.getActStatus() == "Flow finished")) && psram_init_shared_memory_for_take_image_step()) { LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Taking image for Alignment Mark Update..."); CAlignAndCutImage *caic = new CAlignAndCutImage("cutref", in); @@ -687,7 +680,7 @@ esp_err_t handler_editflow(httpd_req_t *req) } else { LogFile.WriteToFile(ESP_LOG_WARN, TAG, std::string("Taking image for Alignment Mark not possible while device") + - " is busy with a round (Current State: '" + state + "')!"); + " is busy with a round (Current State: '" + *flowctrl.getActStatus() + "')!"); zw = "Device Busy"; } @@ -897,7 +890,7 @@ esp_err_t handler_prevalue(httpd_req_t *req) if (httpd_query_key_value(_query, "value", _value, 20) == ESP_OK) { #ifdef DEBUG_DETAIL_ON - ESP_LOGD(TAG, "Value: %s", _size); + ESP_LOGD(TAG, "Value: %s", _value); #endif } } diff --git a/code/components/jomjol_influxdb/interface_influxdb.cpp b/code/components/jomjol_influxdb/interface_influxdb.cpp index e338bf934..1a9ac3088 100644 --- a/code/components/jomjol_influxdb/interface_influxdb.cpp +++ b/code/components/jomjol_influxdb/interface_influxdb.cpp @@ -116,7 +116,7 @@ static esp_err_t http_event_handler(esp_http_client_event_t *evt) LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "HTTP Client Error encountered"); break; case HTTP_EVENT_ON_CONNECTED: - LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "HTTP Client Error encountered"); + LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "HTTP Client connected"); ESP_LOGI(TAG, "HTTP Client Connected"); break; case HTTP_EVENT_HEADERS_SENT: diff --git a/code/components/jomjol_mqtt/interface_mqtt.cpp b/code/components/jomjol_mqtt/interface_mqtt.cpp index 1ab8f03fd..aa21fe7da 100644 --- a/code/components/jomjol_mqtt/interface_mqtt.cpp +++ b/code/components/jomjol_mqtt/interface_mqtt.cpp @@ -9,6 +9,11 @@ #include "cJSON.h" #include "../../include/defines.h" +#if DEBUG_DETAIL_ON +#include "esp_timer.h" +#endif + + static const char *TAG = "MQTT IF"; std::map>* connectFunktionMap = NULL; diff --git a/code/components/jomjol_wlan/read_wlanini.cpp b/code/components/jomjol_wlan/read_wlanini.cpp index 1a9af2276..7ebca23da 100644 --- a/code/components/jomjol_wlan/read_wlanini.cpp +++ b/code/components/jomjol_wlan/read_wlanini.cpp @@ -174,10 +174,12 @@ int LoadWlanFromFile(std::string fn) } /* Check if password is empty (mandatory parameter) */ + /* Disabled see issue #2393 if (wlan_config.password.empty()) { LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Password empty. Device init aborted!"); return -2; } + */ return 0; } diff --git a/code/platformio.ini b/code/platformio.ini index c5a40aca4..ea924fb2f 100644 --- a/code/platformio.ini +++ b/code/platformio.ini @@ -19,7 +19,7 @@ [common:esp32-idf] extends = common:idf - platform = platformio/espressif32 @ 6.2.0 + platform = platformio/espressif32 @ 6.3.2 framework = espidf lib_deps = ${common:idf.lib_deps} diff --git a/code/sdkconfig.defaults b/code/sdkconfig.defaults index e41514a16..8e7fbc64b 100644 --- a/code/sdkconfig.defaults +++ b/code/sdkconfig.defaults @@ -109,6 +109,11 @@ CONFIG_ESP_INT_WDT_TIMEOUT_MS=300 CONFIG_HTTPD_MAX_REQ_HDR_LEN=1024 CONFIG_HTTPD_PURGE_BUF_LEN=16 +<<<<<<< Updated upstream +======= +CONFIG_HTTPD_WS_SUPPORT=y +CONFIG_LWIP_MAX_SOCKETS=12 +>>>>>>> Stashed changes CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=16 CONFIG_ESP32_WIFI_CACHE_TX_BUFFER_NUM=16 diff --git a/images/Flowstate_initialization.xcf b/images/Flowstate_initialization.xcf index 6a54f159a..ddfedf702 100644 Binary files a/images/Flowstate_initialization.xcf and b/images/Flowstate_initialization.xcf differ diff --git a/images/Flowstate_initialization_delayed.xcf b/images/Flowstate_initialization_delayed.xcf index 80e61e5d7..2e465cf42 100644 Binary files a/images/Flowstate_initialization_delayed.xcf and b/images/Flowstate_initialization_delayed.xcf differ diff --git a/images/Flowstate_take_image.xcf b/images/Flowstate_take_image.xcf index 961597d59..1fe747f6e 100644 Binary files a/images/Flowstate_take_image.xcf and b/images/Flowstate_take_image.xcf differ diff --git a/images/icon/logo.png b/images/icon/logo.png new file mode 100644 index 000000000..194cb4afd Binary files /dev/null and b/images/icon/logo.png differ diff --git a/sd-card/config/ana-class100_0157_s1_q.tflite b/sd-card/config/ana-class100_0157_s1_q.tflite deleted file mode 100644 index 0b184b206..000000000 Binary files a/sd-card/config/ana-class100_0157_s1_q.tflite and /dev/null differ diff --git a/sd-card/config/ana-class100_0169_s1_q.tflite b/sd-card/config/ana-class100_0169_s1_q.tflite new file mode 100644 index 000000000..cf52e19bb Binary files /dev/null and b/sd-card/config/ana-class100_0169_s1_q.tflite differ diff --git a/sd-card/config/ana-class100_0170_s1_q.tflite b/sd-card/config/ana-class100_0170_s1_q.tflite new file mode 100644 index 000000000..8ecddda33 Binary files /dev/null and b/sd-card/config/ana-class100_0170_s1_q.tflite differ diff --git a/sd-card/config/ana-cont_1105_s2_q.tflite b/sd-card/config/ana-cont_1105_s2_q.tflite deleted file mode 100644 index e9c2368a4..000000000 Binary files a/sd-card/config/ana-cont_1105_s2_q.tflite and /dev/null differ diff --git a/sd-card/config/ana-cont_1206_s2_q.tflite b/sd-card/config/ana-cont_1206_s2_q.tflite new file mode 100644 index 000000000..e4e5f5faf Binary files /dev/null and b/sd-card/config/ana-cont_1206_s2_q.tflite differ diff --git a/sd-card/config/ana-cont_1207_s2_q.tflite b/sd-card/config/ana-cont_1207_s2_q.tflite new file mode 100644 index 000000000..3ff05babe Binary files /dev/null and b/sd-card/config/ana-cont_1207_s2_q.tflite differ diff --git a/sd-card/config/config.ini b/sd-card/config/config.ini index 08e350460..dc9955566 100644 --- a/sd-card/config/config.ini +++ b/sd-card/config/config.ini @@ -12,7 +12,7 @@ FixedExposure = false Demo = false [Alignment] -InitialRotate = 179 +InitialRotate = 0.0 InitialMirror = false SearchFieldX = 20 SearchFieldY = 20 @@ -22,7 +22,7 @@ FlipImageSize = false /config/ref1.jpg 442 142 [Digits] -Model = /config/dig-cont_0611_s3_q.tflite +Model = /config/dig-cont_0620_s3_q.tflite CNNGoodThreshold = 0.5 ;ROIImagesLocation = /log/digit ;ROIImagesRetention = 3 @@ -31,7 +31,7 @@ main.dig2 343 126 30 54 false main.dig3 391 126 30 54 false [Analog] -Model = /config/ana-cont_1105_s2_q.tflite +Model = /config/ana-cont_1207_s2_q.tflite CNNGoodThreshold = 0.5 ;ROIImagesLocation = /log/analog ;ROIImagesRetention = 3 @@ -106,6 +106,6 @@ LogfilesRetention = 3 TimeZone = CET-1CEST,M3.5.0,M10.5.0/3 ;TimeServer = pool.ntp.org ;Hostname = undefined -;RSSIThreshold = 0 +RSSIThreshold = -75 CPUFrequency = 160 SetupMode = true diff --git a/sd-card/config/dig-class100-0165_s2_q.tflite b/sd-card/config/dig-class100-0165_s2_q.tflite new file mode 100644 index 000000000..4dcc02d1d Binary files /dev/null and b/sd-card/config/dig-class100-0165_s2_q.tflite differ diff --git a/sd-card/config/dig-class100_0160_s2_q.tflite b/sd-card/config/dig-class100_0160_s2_q.tflite deleted file mode 100644 index a1769322b..000000000 Binary files a/sd-card/config/dig-class100_0160_s2_q.tflite and /dev/null differ diff --git a/sd-card/config/dig-cont_0611_s3.tflite b/sd-card/config/dig-cont_0611_s3.tflite deleted file mode 100644 index 0a2314a56..000000000 Binary files a/sd-card/config/dig-cont_0611_s3.tflite and /dev/null differ diff --git a/sd-card/config/dig-cont_0620_s3_q.tflite b/sd-card/config/dig-cont_0620_s3_q.tflite new file mode 100644 index 000000000..95932c748 Binary files /dev/null and b/sd-card/config/dig-cont_0620_s3_q.tflite differ diff --git a/sd-card/html/Flowstate_initialization.jpg b/sd-card/html/Flowstate_initialization.jpg index b490fc47f..54d9ccfd5 100644 Binary files a/sd-card/html/Flowstate_initialization.jpg and b/sd-card/html/Flowstate_initialization.jpg differ diff --git a/sd-card/html/Flowstate_initialization_delayed.jpg b/sd-card/html/Flowstate_initialization_delayed.jpg index 4be8f74f2..bce3d2c5c 100644 Binary files a/sd-card/html/Flowstate_initialization_delayed.jpg and b/sd-card/html/Flowstate_initialization_delayed.jpg differ diff --git a/sd-card/html/Flowstate_take_image.jpg b/sd-card/html/Flowstate_take_image.jpg index dbc4feeed..8ce51e3e3 100644 Binary files a/sd-card/html/Flowstate_take_image.jpg and b/sd-card/html/Flowstate_take_image.jpg differ diff --git a/sd-card/html/backup.html b/sd-card/html/backup.html index 8e04bc5ff..04af87f36 100644 --- a/sd-card/html/backup.html +++ b/sd-card/html/backup.html @@ -1,42 +1,41 @@ - + - -Backup/Restore Configuration - - - + .button { + padding: 5px 10px; + width: 205px; + font-size: 16px; + } + -

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.

+

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 index 66b3992c0..20d010103 100644 --- a/sd-card/html/common.js +++ b/sd-card/html/common.js @@ -1,7 +1,7 @@ /* The UI can also be run locally, but you have to set the IP of your devide accordingly. * And you also might have to disable CORS in your webbrowser! */ -var domainname_for_testing = "192.168.178.23"; +var domainname_for_testing = "192.168.1.151"; /* Returns the domainname with prepended protocol. @@ -13,7 +13,7 @@ function getDomainname(){ ) { - console.log("Using pre-defined domainname for testing: " + domainname_for_testing); + //console.log("Using pre-defined domainname for testing: " + domainname_for_testing); domainname = "http://" + domainname_for_testing } else @@ -139,8 +139,8 @@ function compareVersions() { console.log("FW Hash: " + fWGitHash + ", Web UI Hash: " + webUiHash); if (fWGitHash != webUiHash) { - firework.launch("The Version of the Web Interface (" + webUiHash + - ") does not match the Firmware Version (" + + firework.launch("The version of the web interface (" + webUiHash + + ") does not match the firmware version (" + fWGitHash + ")! It is suggested to keep them on the same version!", 'warning', 30000); } } diff --git a/sd-card/html/data.html b/sd-card/html/data.html index a592241cc..09f9885b0 100644 --- a/sd-card/html/data.html +++ b/sd-card/html/data.html @@ -1,17 +1,26 @@ - + + + Data Viewer + + -

Todays Data

-

Last part of Todays Data

+

Data Viewer

+

Today's latest data

- - - - + + + +
-



Loading Data file, please wait...
+



Loading data file, please wait...
diff --git a/sd-card/html/edit_alignment.html b/sd-card/html/edit_alignment.html index 434f1db79..fe89abc43 100644 --- a/sd-card/html/edit_alignment.html +++ b/sd-card/html/edit_alignment.html @@ -1,101 +1,135 @@ - + - -Alignment Marks - - - - - - + select { + padding: 3px 5px; + display: inline-block; + border: 1px solid #ccc; + font-size: 16px; + margin-right: 10px; + min-width: 100px; + vertical-align: middle; + } + + .button { + padding: 5px 10px; + width: 205px; + font-size: 16px; + } + + th, td { + padding: 5px 5px 5px 0px; + } + + table { + width: 660px; + padding: 5px; + } + + + + -

Alignment Marks

-

On this page you define two Reference Marks. - See https://jomjol.github.io/AI-on-the-edge-device-docs/Alignment/ for explanations.

-

After saving the Reference Marks, you can define the digit resp. analog ROI's.
- Only after those steps a reboot is required.

- -
- - - -
+

Alignment Marker

+
+ CLICK HERE for usage description. More infos in documentation: + Alignment + +

+ Two alignment marker with clear contour and proper contrast are needed to identify unique "fix points" on the image. + The marker area should be not be part of the variable area of ROI evaluation. Please find more information in documenation: + Alignment +

+

+ Select an alignment marker area using drag and dop feature by mouse operation or by manually entering the coordinates and sizes in the fields below the image. + After you selected a suitable first alignment marker area, push the "Update Marker" button. Switch to second alignment marker with "Marker" + and repeat the procedure. +

+

+ After definition of both alignment marker is completed don't forget to save with the "Save New Marker" button!
+ NOTE: There is no need to perform a reboot after every saving or step. It's sufficient to reboot after all configuration steps + (reference image, alignment, ROI configuration) are completed to activate new configuration. +

+
+
+ + + + + - - + - + - - - + + + - - - -
Select Reference: + Marker: Storage Path/Name: Filename:
x: dx:
y: dy:
Original Image:Reference Image:Selected Image Area:Resulting Marker:
- - - - + + -
-

Proceed to update the digit resp. analog ROI's when you are done.

+ + Reference Image: + + + + + + + + + @@ -130,10 +164,15 @@

Alignment Marks

} function SaveToConfig(){ - WriteConfigININew(); - UpdateConfigReference(domainname) - SaveConfigToServer(domainname); - firework.launch('Reference Marks got updated. The change will get applied after the next reboot!', 'success', 5000); + if (confirm("Are you sure you want to save the new alignment marker configuration?")) { + WriteConfigININew(); + UpdateConfigReference(domainname) + SaveConfigToServer(domainname); + document.getElementById("savemarker").disabled = true; + document.getElementById("enhancecontrast").disabled = true; + + firework.launch('Alignment marker saved. They will get applied after next reboot', 'success', 5000); + } } function EnhanceContrast(){ @@ -146,6 +185,7 @@

Alignment Marks

enhanceCon = true; if (MakeContrastImageZW(refInfo[aktindex], enhanceCon, domainname)) { UpdateReference(); + document.getElementById("enhancecontrast").disabled = true; } } @@ -174,7 +214,6 @@

Alignment Marks

document.getElementById("refy").value = refInfo[aktindex]["y"]; rect.startX = document.getElementById("refx").value; rect.startY = document.getElementById("refy").value; - document.getElementById("enhancecontrast").disabled = true; draw(); } @@ -215,14 +254,27 @@

Alignment Marks

return { top: Math.round(top), left: Math.round(left) }; } + + /* hash #description open the details part of the page */ + function openDescription() { + if(window.location.hash) { + var hash = window.location.hash.substring(1); //Puts hash in variable, and removes the # character + if(hash == 'description') + document.getElementById("desc_details").open = true; + } + } + - - function init() { + function init() { + openDescription(); domainname = getDomainname(); loadConfig(domainname); ParseConfig(); param = getConfigParameters(); + document.getElementById("savemarker").disabled = true; + document.getElementById("enhancecontrast").disabled = true; + canvas.addEventListener('mousedown', mouseDown, false); canvas.addEventListener('mouseup', mouseUp, false); canvas.addEventListener('mousemove', mouseMove, false); @@ -235,6 +287,8 @@

Alignment Marks

drawImage(); } + + function drawImage(){ var canvas = document.getElementById('canvas'); var context = canvas.getContext('2d'); @@ -254,6 +308,7 @@

Alignment Marks

if (MakeRefZW(refInfo[aktindex], domainname)) { UpdateReference(); document.getElementById("enhancecontrast").disabled = false; + document.getElementById("savemarker").disabled = false; } } diff --git a/sd-card/html/edit_analog.html b/sd-card/html/edit_analog.html index d16413703..59a36eb62 100644 --- a/sd-card/html/edit_analog.html +++ b/sd-card/html/edit_analog.html @@ -1,142 +1,221 @@ - + - - -Analog ROI's - - + + + + -#div2{ - background-color:#777; - margin-bottom:20px; -} -.disabledDiv { - pointer-events: none; - opacity: 0.4; -} - - - - -

Analog ROI's

-

On this page you define ROI's for the analog counters. - See https://jomjol.github.io/AI-on-the-edge-device-docs/ROI-Configuration/ for explanations.

- -

- +

Analog ROI

+
+ CLICK HERE for usage description. More infos in documentation: + ROI Configuration + +

+ Region Of Interest (ROI) for analog pointer counter can be defined on this page. If no analog pointer counter need to be + processed, disable analog pointer counter processing by deselecting "Analog ROI Processing". +

+

+ By default one number sequence (a number seqence contains of 1-x digit ROIs + 1-x analog counter ROIs which are processed together) is + predefined and already selected in the drop down "Number Sequence". If you need more than one number sequence additional + one's can be added with the buttons next to the drop down. Each number sequence will be processed separately. +

+

+ Using drag and drop by mouse of by manually entering the parameters into the given fields the analog ROIs can be positined to the analog pointer + counters on the reference image. To have proper ROI definition please check the documentation: + ROI Configuration. It's very important to be + really precise to have reliable processing. With the drop down "ROI" you can change between the different ROIs in the selected + number sequence. To create new ROIs use "New ROI". +

+

+ The order of the ROIs defines the position (and therefore the multiplication factor) within the reading sequence. The position + in the number sequence can be changed with the buttons "Move ROI Lower" and "Move ROI Higher". The multiplication factor which is + shown below the ROI drop down is the multiplication factor of pure position/order in number sequence and the factor right-hand side to this is + the additionally corrected by decimal shift setting (configuration, expert parameter, default: 0). +

+

+ After definition of digit ROIs is completed don't forget to save with the "Save Config" button!
+ NOTE: There is no need to perform a reboot after every saving or step. It's sufficient to reboot after all configuration steps + (reference image, alignment, ROI configuration) are completed to activate new configuration. +

+
+
+ +

+ + +

+ +
- - - - -
- -

- - - Number: + +
+ + + + + + + + + + + -
Number Sequence:
- - - -
-

+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + +
ROI:
Multiplier:
+ (only based on order) +
Multiplier:
+ (order + decimal shift: ) +
- - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - -
x: Δx:
y: Δy:
-
- - - - - - - -
-
+ + + + + + + x: + Δx: + + + + y: + Δy: + + + + + + + + + + + + + + + + + + + + + + + + +
Reference Image:
@@ -158,16 +237,15 @@

Analog ROI's

lockSizes = false; domainname = getDomainname(); - -function doReboot() { - if (confirm("Are you sure you want to reboot? Did you save your changes?")) { - var stringota = getDomainname() + "/reboot"; - window.location = stringota; - window.location.href = stringota; - window.location.assign(stringota); - window.location.replace(stringota); + function doReboot() { + if (confirm("Are you sure you want to reboot? Did you save your changes?")) { + var stringota = getDomainname() + "/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; @@ -186,9 +264,9 @@

Analog ROI's

sah1(document.getElementById("div1"), !isEnabled); - cofcat["Analog"]["enabled"] = isEnabled; - + document.getElementById("saveroi").disabled = false; + if (isEnabled) { UpdateROIs(); @@ -212,6 +290,10 @@

Analog ROI's

} function deleteROI(){ + if (!confirm("Delete the selected ROI?")) { + return; //break out of the function early because prompt was aborted + } + ROIInfo.splice(aktindex, 1); if (aktindex > ROIInfo.length - 1){ aktindex = ROIInfo.length - 1; @@ -220,18 +302,21 @@

Analog ROI's

draw(); } -function newROI(){ +function newROI() { var sel = document.getElementById("Numbers_value1"); var _number= sel.options[sel.selectedIndex].text; sel = document.getElementById("index"); var _roialt= sel.options[sel.selectedIndex].text; - var _roinew = prompt("Please enter name of new ROI", "name"); + var _roinew = prompt("Please enter a name for the new ROI", "name"); + if (_roinew === null) { + return; //break out of the function early because prompt was aborted + } if (ROIInfo.length > 0) - erg = CreateROI(_number, "analog", sel.selectedIndex, _roinew, 1, 1, ROIInfo[aktindex]["dx"], ROIInfo[aktindex]["dy"], ROIInfo[aktindex]["CCW"]=="true"); + erg = CreateROI(_number, "analog", sel.selectedIndex, _roinew, 15, 30, ROIInfo[aktindex]["dx"], ROIInfo[aktindex]["dy"], ROIInfo[aktindex]["CCW"]=="true"); else - erg = CreateROI(_number, "analog", sel.selectedIndex, _roinew, 1, 1, 30, 30, false); + erg = CreateROI(_number, "analog", sel.selectedIndex, _roinew, 15, 30, 30, 30, false); if (erg != "") firework.launch(erg, 'danger', 30000); @@ -275,7 +360,9 @@

Analog ROI's

ROIInfo[aktindex]["CCW"] = "true"; else ROIInfo[aktindex]["CCW"] = "false"; - UpdateROIs(); + + UpdateROIs(); + } function ChangeSelection(){ @@ -285,11 +372,68 @@

Analog ROI's

} function SaveToConfig(){ -// _zwcat = getConfigCategory(); - cofcat["Analog"]["enabled"] = document.getElementById("Category_Analog_enabled").checked; - WriteConfigININew(); - SaveConfigToServer(domainname); - firework.launch('Configuration got updated. It will get applied after the next reboot!', 'success', 5000); + if (confirm("Are you sure you want to save the new analog ROI configuration?")) { + //_zwcat = getConfigCategory(); + cofcat["Analog"]["enabled"] = document.getElementById("Category_Analog_enabled").checked; + WriteConfigININew(); + SaveConfigToServer(domainname); + UpdateROIs(); + document.getElementById("saveroi").disabled = true; + + firework.launch('Configuration saved. It will get applied after next reboot', 'success', 5000); + } +} + + +function ShowMultiplier() +{ + var decimalShift = 0; + var multiplier; + var multiplier_decshift; + var fixedDecimals; + var fixedDecimals_decshift; + var NumberInfo = getNUMBERInfo(); + var CategoryInfo = getConfigCategory(); + + var sel = document.getElementById("Numbers_value1"); + var _number= sel.options[sel.selectedIndex].text; + document.getElementById("decimalShift").value = 0; + for (var i = 0; i < NumberInfo.length; ++i) { + if (NumberInfo[i]["name"] == _number) { + if (NumberInfo[i]["PostProcessing"]["DecimalShift"]["enabled"]) { + decimalShift = NumberInfo[i]["PostProcessing"]["DecimalShift"]["value1"]; + document.getElementById("decimalShift").value=decimalShift; + } + } + } + + if (CategoryInfo["Analog"]["enabled"] == true && CategoryInfo["Digits"]["enabled"] == true) { // Digit + Analog + multiplier = fixedDecimals = aktindex + 1; + multiplier_decshift = fixedDecimals_decshift = multiplier - Number(decimalShift); + + if (multiplier < 0) + fixedDecimals = 0; + + if (multiplier_decshift < 0) + fixedDecimals_decshift = 0; + + document.getElementById("multiplier").value="x" + Number(10 ** (-1*multiplier)).toFixed(fixedDecimals); + document.getElementById("multiplier_decshift").value="x" + Number(10 ** (-1*multiplier_decshift)).toFixed(fixedDecimals_decshift); + } + else if (CategoryInfo["Analog"]["enabled"] == true && CategoryInfo["Digits"]["enabled"] == false) { // Only Analog + multiplier = ROIInfo.length - 1 - aktindex; + multiplier_decshift = fixedDecimals_decshift = multiplier + Number(decimalShift); + + if (multiplier_decshift > 0) + fixedDecimals_decshift = 0; + + if (fixedDecimals_decshift < 0) { + fixedDecimals_decshift = -1 * fixedDecimals_decshift; + } + + document.getElementById("multiplier").value="x" + Number(10 ** multiplier).toFixed(0); + document.getElementById("multiplier_decshift").value="x" + Number(10 ** multiplier_decshift).toFixed(fixedDecimals_decshift); + } } @@ -305,19 +449,28 @@

Analog ROI's

{ document.getElementById("Category_Analog_enabled").checked = false; EnDisableAnalog(); - firework.launch('Analog ROIs are disabled - please enable first (Check box top left)', 'warning', 10000); + firework.launch('Analog ROI processing is disabled. Activate with checkbox if needed', 'warning', 10000); return; } if (ROIInfo.length == 0){ - firework.launch('There are no ROIs defined. Please first create a new ROI ("New ROIs ...")', 'danger', 10000); + firework.launch('No analog ROIs defined in selected number sequence', 'warning', 10000); document.getElementById("newROI").disabled = false; document.getElementById("deleteROI").disabled = true; - document.getElementById("index").disabled = true; - document.getElementById("saveroi").disabled = true; document.getElementById("renameROI").disabled = true; + document.getElementById("index").disabled = true; + document.getElementById("multiplier").style.display = "none"; + document.getElementById("multiplier_decshift").style.display = "none"; + document.getElementById("refx").disabled = true; + document.getElementById("refdx").disabled = true; + document.getElementById("refy").disabled = true; + document.getElementById("refdy").disabled = true; + document.getElementById("lockSizes").disabled = true; + document.getElementById("lockAspectRatio").disabled = true; + document.getElementById("CCW").disabled = true; document.getElementById("moveNext").disabled = true; document.getElementById("movePrevious").disabled = true; + document.getElementById("saveroi").disabled = false; return; } else @@ -326,6 +479,15 @@

Analog ROI's

document.getElementById("deleteROI").disabled = false; document.getElementById("renameROI").disabled = false; document.getElementById("index").disabled = false; + document.getElementById("multiplier").style.display = ""; + document.getElementById("multiplier_decshift").style.display = ""; + document.getElementById("refx").disabled = false; + document.getElementById("refdx").disabled = false; + document.getElementById("refy").disabled = false; + document.getElementById("refdy").disabled = false; + document.getElementById("lockSizes").disabled = false; + document.getElementById("lockAspectRatio").disabled = false; + document.getElementById("CCW").disabled = false; document.getElementById("saveroi").disabled = false; } @@ -335,7 +497,7 @@

Analog ROI's

} if (aktindex > ROIInfo.length) - aktindex = ROIInfo.length; + aktindex = ROIInfo.length-1; for (var i = 0; i < ROIInfo.length; ++i){ var option = document.createElement("option"); @@ -358,7 +520,9 @@

Analog ROI's

document.getElementById("moveNext").disabled = false; if (aktindex == (ROIInfo.length-1)){ document.getElementById("moveNext").disabled = true; - } + } + + ShowMultiplier(); document.getElementById("lockAspectRatio").checked = lockAspectRatio; document.getElementById("lockSizes").checked = lockSizes; @@ -373,8 +537,7 @@

Analog ROI's

rect.startY = ROIInfo[aktindex]["y"]; rect.w = ROIInfo[aktindex]["dx"]; rect.h = ROIInfo[aktindex]["dy"]; - draw(); - + draw(); } function loadCanvas(dataURL) { @@ -404,10 +567,20 @@

Analog ROI's

var left = box.left + scrollLeft - clientLeft; return { top: Math.round(top), left: Math.round(left) }; } - - + + + /* hash #description open the details part of the page */ + function openDescription() { + if(window.location.hash) { + var hash = window.location.hash.substring(1); //Puts hash in variable, and removes the # character + if(hash == 'description') + document.getElementById("desc_details").open = true; + } + } + function init() { + openDescription(); domainname = getDomainname(); canvas.addEventListener('mousedown', mouseDown, false); canvas.addEventListener('mouseup', mouseUp, false); @@ -440,11 +613,12 @@

Analog ROI's

console.log("Not all ROI have the same dX and dY, unticking the sync checkbox!"); } + document.getElementById("saveroi").disabled = true; drawImage(); draw(); } - + function drawImage(){ var canvas = document.getElementById('canvas'); var context = canvas.getContext('2d'); @@ -483,10 +657,13 @@

Analog ROI's

function renameNumber(){ var sel = document.getElementById("Numbers_value1"); - var _delte= sel.options[sel.selectedIndex].text; - var _numbernew = prompt("Please enter new name", _delte); + var _delete= sel.options[sel.selectedIndex].text; + var _numbernew = prompt("Please enter a new name for the selected number sequence", _delete); + if (_numbernew === null) { + return; //break out of the function early because prompt was aborted + } - erg = RenameNUMBER(_delte, _numbernew); + erg = RenameNUMBER(_delete, _numbernew); if (erg != "") firework.launch(erg, 'danger', 30000); else @@ -494,7 +671,10 @@

Analog ROI's

} function newNumber(){ - var _numbernew = prompt("Please enter name of new number", "name"); + var _numbernew = prompt("Please enter a name for the new number sequence", "name"); + if (_numbernew === null) { + return; //break out of the function early because prompt was aborted + } erg = CreateNUMBER(_numbernew); if (erg != "") @@ -505,10 +685,13 @@

Analog ROI's

function removeNumber(){ - if (confirm("This will remove the number complete (analog and digital).\nIf you only want to remove the digital ROIs, please use \"Delete ROIs\".\nDo you want to proceed?")) { + if (confirm("The entire number sequence will be removed (digit + analog parts). " + + "To remove single ROI of the number sequence, use \"Delete ROI\" instead.\n" + + "Do you really want to proceed?")) + { var sel = document.getElementById("Numbers_value1"); - var _delte= sel.options[sel.selectedIndex].text; - erg = DeleteNUMBER(_delte); + var _delete= sel.options[sel.selectedIndex].text; + erg = DeleteNUMBER(_delete); if (erg != "") firework.launch(erg, 'danger', 30000); UpdateNUMBERS(); @@ -576,8 +759,12 @@

Analog ROI's

var dx = parseInt(ROIInfo[_nb].dx) + parseInt(lw); var dy = parseInt(ROIInfo[_nb].dy) + parseInt(lw); context.strokeRect(x0, y0, dx, dy); - drawTextBG(context, ROIInfo[_nb]["name"], x0+dx/2-0.5, y0-13, 5); - + + if (ROIInfo[_nb]["CCW"] != "true") + drawTextBG(context, ROIInfo[_nb]["name"], x0+dx/2-0.5, y0-13, 5); + else + drawTextBG(context, ROIInfo[_nb]["name"]+" (CCW)", x0+dx/2-0.5, y0-13, 5); + lw = 1; var x0 = parseInt(ROIInfo[_nb].x) - parseInt(lw/2); var y0 = parseInt(ROIInfo[_nb].y) - parseInt(lw/2); @@ -586,7 +773,8 @@

Analog ROI's

context.strokeRect(x0, y0, dx, dy); context.lineWidth = lw; context.beginPath(); - context.arc(x0+dx/2, y0+dy/2, dx/2, 0, 2 * Math.PI); +// context.arc (x0+dx/2, y0+dy/2, dx/2, 0, 2 * Math.PI); + context.ellipse(x0+dx/2, y0+dy/2, dx/2, dy/2, 0, 0, 2 * Math.PI); context.moveTo(x0+dx/2, y0); context.lineTo(x0+dx/2, y0+dy); context.moveTo(x0, y0+dy/2); @@ -602,11 +790,17 @@

Analog ROI's

var y0 = parseInt(rect.startY) - parseInt(lw/2); var dx = parseInt(rect.w) + parseInt(lw); var dy = parseInt(rect.h) + parseInt(lw); - context.strokeRect(x0, y0, dx, dy); - drawTextBG(context, ROIInfo[aktindex]["name"], x0+dx/2, y0-11, 5); + context.strokeRect(x0, y0, dx, dy); + + if (ROIInfo[aktindex]["CCW"] != "true") + drawTextBG(context, ROIInfo[aktindex]["name"], x0+dx/2, y0-11, 5); + else + drawTextBG(context, ROIInfo[aktindex]["name"] + " (CCW)", x0+dx/2, y0-11, 5); + context.lineWidth = 1; context.beginPath(); - context.arc(x0+dx/2, y0+dy/2, dx/2, 0, 2 * Math.PI); +// context.arc(x0+dx/2, y0+dy/2, dx/2, 0, 2 * Math.PI); + context.ellipse(x0+dx/2, y0+dy/2, dx/2, dy/2, 0, 0, 2 * Math.PI); context.moveTo(x0+dx/2, y0); context.lineTo(x0+dx/2, y0+dy); context.moveTo(x0, y0+dy/2); @@ -706,6 +900,7 @@

Analog ROI's

rect.startY = document.getElementById("refy").value; draw(); } + document.getElementById("saveroi").disabled = false; } function valuemanualchangeddx(){ @@ -721,6 +916,7 @@

Analog ROI's

rect.startY = document.getElementById("refy").value; draw(); } + document.getElementById("saveroi").disabled = false; } @@ -730,8 +926,10 @@

Analog ROI's

sel = document.getElementById("index"); var _roialt= sel.options[sel.selectedIndex].text; - - var _roinew = prompt("Please enter new name", _roialt); + var _roinew = prompt("Please enter a new name for the selected ROI", _roialt); + if (_roinew === null) { + return; //break out of the function early because prompt was aborted + } erg = RenameROI(_number, "analog", _roialt, _roinew); if (erg != "") @@ -742,13 +940,15 @@

Analog ROI's

function numberChanged() { + aktindex = 0; UpdateROIs(); } - init(); + + diff --git a/sd-card/html/edit_check.html b/sd-card/html/edit_check.html deleted file mode 100644 index 27ca50127..000000000 --- a/sd-card/html/edit_check.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - -Check - - - - - - - - - - - - - -
Result:
- - -

- -

-

-
-

-

- Takes up to 2 Minutes! -

- Digits and Analog recognition not yet implemented. -

- -

-

- -

-
- - - - - - - - diff --git a/sd-card/html/edit_config.html b/sd-card/html/edit_config.html index 475b875e5..bbac90472 100644 --- a/sd-card/html/edit_config.html +++ b/sd-card/html/edit_config.html @@ -1,25 +1,24 @@ - + - Edit Config - + @@ -28,59 +27,60 @@ - - - - - - - - - - - -

Config.ini:

- -
+ +

Configuration - "Config.ini" Editor

+ +
+ +
- - - - + + + + function doReboot() { + if (confirm("Are you sure you want to reboot?")) { + var stringota = "/reboot"; + window.location = stringota; + window.location.href = stringota; + window.location.assign(stringota); + window.location.replace(stringota); + } + } + + LoadConfigNeu(); + + diff --git a/sd-card/html/edit_config_param.html b/sd-card/html/edit_config_param.html index 398957462..76d04c678 100644 --- a/sd-card/html/edit_config_param.html +++ b/sd-card/html/edit_config_param.html @@ -1,108 +1,165 @@ - + - -Edit Config - +Configuration + @@ -116,50 +173,85 @@

Configuration

-

The documentation of each parameter can be shown with hovering over the icon.
- The latest version of the documentation is available on jomjol.github.io/AI-on-the-edge-device-docs/Parameters.

- - -

- + + + +

Data Graph

+

Loading...

+ Number sequence: + + Day: + +

+ + + diff --git a/sd-card/html/index.html b/sd-card/html/index.html index b624afffb..c3a172200 100644 --- a/sd-card/html/index.html +++ b/sd-card/html/index.html @@ -1,94 +1,120 @@ - + - -AI on the edge - - - - - - - - - - - - - - + + + + + + + + + function resetMenu() { + [].forEach.call(document.querySelectorAll('.submenu'), function (el) { + el.style.visibility = 'visible'; + }); + } + + function getCookie(cname) { + let name = cname + "="; + let decodedCookie = decodeURIComponent(document.cookie); + let ca = decodedCookie.split(';'); + for(let i = 0; i
- - - +

Digitizer - AI on the edge

-

An ESP32 all inclusive neural network recognition system for meter digitalization

-
+ + + +

Digitizer - AI on the edge

+

An ESP32 all inclusive neural network recognition system for meter digitalization

+
+ - + -Loading version... +Loading version... + } + console.log("Loading page: " + getCookie("page")); + document.getElementById('maincontent').src = getCookie("page"); + + /* + function flow_start() { + var url = getDomainname() + '/flow_start'; + var xhttp = new XMLHttpRequest(); + xhttp.onreadystatechange = function() { + if (this.readyState == 4 && this.status == 200) { + if (xhttp.responseText.substring(0,3) == "001") { + firework.launch('Flow start triggered', 'success', 5000); + window.location.reload(); + } + else if (xhttp.responseText.substring(0,3) == "002") { + firework.launch('Flow start scheduled. Start after round is completed', 'success', 5000); + } + else if (xhttp.responseText.substring(0,3) == "099") { + firework.launch('Flow start triggered, but start not possible (no flow task available)', 'danger', 5000); + } + } + } + xhttp.open("GET", url, true); + xhttp.send(); + } + */ -
+ + function HA_send_discovery_visibility() { + loadConfig(domainname); + ParseConfig(); + category = getConfigCategory(); + param = getConfigParameters(); + if (category["MQTT"]["enabled"] && param["MQTT"]["HomeassistantDiscovery"]["value1"] == "true") { + document.getElementById("ManualControl").style.display=""; + document.getElementById("HASendDiscovery").style.display=""; + } + } + + + function HA_send_discovery() { + console.log("HA Discovery scheduled"); + var url = getDomainname() + '/mqtt_publish_discovery'; + var xhttp = new XMLHttpRequest(); + xhttp.onreadystatechange = function() { + if (this.readyState == 4 && this.status == 200) { + firework.launch('Sending HA discovery topics scheduled. The sending will be processed in state "Publish to MQTT"', 'success', 5000); + } + } + xhttp.open("GET", url, true); + xhttp.send(); + } + + + function start_livestream(streamFlashlight) { + if (streamPopup) + streamPopup.close(); + + if (streamFlashlight) + streamPopup = window.open(getDomainname() + '/stream?flashlight=true','LivestreamWithlight',streamWindowFeatures); + else + streamPopup = window.open(getDomainname() + '/stream','Livestream',streamWindowFeatures); + + streamPopup.focus(); + } + diff --git a/sd-card/html/info.html b/sd-card/html/info.html index 08fd57e6e..9ab7d94ab 100644 --- a/sd-card/html/info.html +++ b/sd-card/html/info.html @@ -1,9 +1,8 @@ - + - Info - + + -

Runtime Information

- - - - - - - - - -
- Last restart: - -
- -
-
- Uptime: - -
- -
-
- -

Build Info

- - - - - - - - - - - - - - -
- Firmware Version: - -
- -
-
- Firmware Build Time: - -
- -
-
- Web Interface Version: - -
- -
-
- - -

Host Info

- - - - - - - - - - - - - -
- Hostname: - -
- -
-
- IP-Address: - -
- -
-
- WLan-SSID: - -
- -
-
- -

SD Card Info

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- SD Card Manufacturer: - -
- -
-
- SD Card Name: - -
- -
-
- SD Card Size [MB]: - -
- -
-
- SD Card Sector Size [byte]: - -
- -
-
- Partition Size [MB]: - -
- -
-
- Partition Free Space [MB]: - -
- -
-
- Partition Allocation Size [byte]: - -
- -
-
+ + + + + + +

Runtime Information

+ + + + + + + + + +
Start time:
Uptime:
+ + + + + + + +

Build Info

+ + + + + + + + + + + + + + +
Firmware version: + +
Firmware build time: + +
Web interface version: + +
+ + + + + + + + +

Host Info

+ + + + + + + + + + + + + +
Hostname: + +
IP Address: + +
WLAN SSID: + +
+ + + + + + + +

SD Card Info

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SD card manufacturer: + +
SD card name: + +
SD card size: + +
SD card sector size: + +
Partition size: + +
Partition free space: + +
Partition allocation size: + +
+ + + + + + + +

Memory Info

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Total Free (Int + Ext): + +
Ext. RAM - Free: + +
Ext. RAM - Largest Free Block: + +
Ext. RAM - Min Free: + +
Int. RAM - Free: + +
Int. RAM - Largest Free Block: + +
Int. RAM - Min Free: + +
+

Copyright

Copyright © 2020 - 2023 by Jomjol and others. + + diff --git a/sd-card/html/log.html b/sd-card/html/log.html index cad504f56..503941f41 100644 --- a/sd-card/html/log.html +++ b/sd-card/html/log.html @@ -1,16 +1,19 @@ - + + + Log Viewer +
- - - + + +
-



Loading Logfile, please wait...
+



Loading logfile, please wait...
diff --git a/sd-card/html/ota_page.html b/sd-card/html/ota_page.html index f97bf753a..adaf4fa75 100644 --- a/sd-card/html/ota_page.html +++ b/sd-card/html/ota_page.html @@ -1,27 +1,25 @@ - + - OTA Update - + @@ -51,11 +49,11 @@

Update



- +

+

Status: Idle

-

Status: idle

@@ -262,10 +260,10 @@

Status: idle

function progressHandler(event) { _("loaded_n_total").innerHTML = "Uploaded " + (event.loaded / 1024 / 1024).toFixed(2) + - " MBytes of " + (event.total / 1024/ 1024).toFixed(2) + " MBytes."; + " MB of " + (event.total / 1024/ 1024).toFixed(2) + " MB"; var percent = (event.loaded / event.total) * 100; _("progressBar").value = Math.round(percent); - _("status").innerHTML = "Status: " + Math.round(percent) + "% uploaded... please wait"; + _("status").innerHTML = "Status: " + Math.round(percent) + "% uploaded. Please wait..."; } diff --git a/sd-card/html/overview.html b/sd-card/html/overview.html index 4ef17bae9..6d22f62c4 100644 --- a/sd-card/html/overview.html +++ b/sd-card/html/overview.html @@ -1,77 +1,89 @@ - + - Overview - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Value:
-
-
Previous Value:
-
-
Raw Value:
-
-
Status:
-
-
-
-
-
-
-
- - -
-
- - - - - - + + + + @@ -104,6 +156,7 @@

Result:

xhttp.send(); response = xhttp.responseText; document.getElementById("result").innerHTML=response; + firework.launch('New \"previous value\" set', 'success', 5000); } catch (error) { @@ -145,11 +198,10 @@

Result:

lines.forEach(function(line) { arr = line.split("\t"); if (_number == arr[0]) { - document.getElementById("myInput").value=arr[1]; + document.getElementById("myInput").value = Number(arr[1]); return; } }); - } catch (error) { @@ -190,7 +242,7 @@

Result:

function init(){ - domainname = getDomainname(); + domainname = getDomainname(); loadConfig(domainname); ParseConfig(); UpdateNUMBERS(); diff --git a/sd-card/html/readconfigcommon.js b/sd-card/html/readconfigcommon.js index ff74c7a68..4871bc17a 100644 --- a/sd-card/html/readconfigcommon.js +++ b/sd-card/html/readconfigcommon.js @@ -85,6 +85,7 @@ function ZerlegeZeile(input, delimiter = " =\t\r") } + function findDelimiterPos(input, delimiter) { var pos = -1; @@ -131,7 +132,8 @@ function getConfig() } -function loadConfig(_domainname) { +function loadConfig(_domainname) +{ var xhttp = new XMLHttpRequest(); try { url = _domainname + '/fileserver/config/config.ini'; @@ -148,17 +150,17 @@ function loadConfig(_domainname) { } - - -function dataURLtoBlob(dataurl) { +function dataURLtoBlob(dataurl) +{ var arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1], bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n); while(n--){ u8arr[n] = bstr.charCodeAt(n); } return new Blob([u8arr], {type:mime}); - } - +} + + function FileCopyOnServer(_source, _target, _domainname = ""){ url = _domainname + "/editflow?task=copy&in=" + _source + "&out=" + _target; var xhttp = new XMLHttpRequest(); @@ -171,6 +173,7 @@ function FileCopyOnServer(_source, _target, _domainname = ""){ } } + function FileDeleteOnServer(_filename, _domainname = ""){ var xhttp = new XMLHttpRequest(); var okay = false; @@ -201,6 +204,7 @@ function FileDeleteOnServer(_filename, _domainname = ""){ return okay; } + function FileSendContent(_content, _filename, _domainname = ""){ var xhttp = new XMLHttpRequest(); var okay = false; @@ -242,6 +246,7 @@ function SaveCanvasToImage(_canvas, _filename, _delete = true, _domainname = "") FileSendContent(rtn, _filename, _domainname); } + function MakeContrastImageZW(zw, _enhance, _domainname){ _filename = zw["name"].replace("/config/", "/img_tmp/"); url = _domainname + "/editflow?task=cutref&in=/config/reference.jpg&out=" + _filename + "&x=" + zw["x"] + "&y=" + zw["y"] + "&dx=" + zw["dx"] + "&dy=" + zw["dy"]; @@ -260,7 +265,7 @@ function MakeContrastImageZW(zw, _enhance, _domainname){ } if (xhttp.responseText == "CutImage Done") { - firework.launch('Reference Image Contrast got enhanced.', 'success', 5000); + firework.launch('Image Contrast got enhanced', 'success', 5000); return true; } else { @@ -270,7 +275,6 @@ function MakeContrastImageZW(zw, _enhance, _domainname){ } - function MakeRefZW(zw, _domainname){ _filetarget = zw["name"].replace("/config/", "/img_tmp/"); _filetarget = _filetarget.replace(".jpg", "_org.jpg"); @@ -289,7 +293,7 @@ function MakeRefZW(zw, _domainname){ _filetarget2 = zw["name"].replace("/config/", "/img_tmp/"); // _filetarget2 = _filetarget2.replace(".jpg", "_org.jpg"); FileCopyOnServer(_filetarget, _filetarget2, _domainname); - firework.launch('Reference Image got updated.', 'success', 5000); + firework.launch('Marker got updated', 'success', 5000); return true; } else { diff --git a/sd-card/html/readconfigparam.js b/sd-card/html/readconfigparam.js index a2138143d..c31c0b4df 100644 --- a/sd-card/html/readconfigparam.js +++ b/sd-card/html/readconfigparam.js @@ -710,9 +710,10 @@ function getNUMBERInfo(){ } function RenameNUMBER(_alt, _neu){ - if ((_neu.indexOf(".") >= 0) || (_neu.indexOf(",") >= 0) || (_neu.indexOf(" ") >= 0) || (_neu.indexOf("\"") >= 0)) + if ((_neu.indexOf(".") >= 0) || (_neu.indexOf(",") >= 0) || + (_neu.indexOf(" ") >= 0) || (_neu.indexOf("\"") >= 0)) { - return "Name must not contain ',', '.', ' ' or '\"' - please change name"; + return "Number sequence name must not contain , . \" or a space"; } index = -1; @@ -725,21 +726,21 @@ function RenameNUMBER(_alt, _neu){ } if (found) - return "Name is already existing - please use another name"; + return "Number sequence name is already existing, please choose another name"; NUMBERS[index]["name"] = _neu; return ""; } -function DeleteNUMBER(_delte){ +function DeleteNUMBER(_delete){ if (NUMBERS.length == 1) - return "The last number cannot be deleted." + return "One number sequence is mandatory. Therefore this cannot be deleted" index = -1; for (i = 0; i < NUMBERS.length; ++i) { - if (NUMBERS[i]["name"] == _delte) + if (NUMBERS[i]["name"] == _delete) index = i; } @@ -758,7 +759,7 @@ function CreateNUMBER(_numbernew){ } if (found) - return "Name does already exist, please choose another one!"; + return "Number sequence name is already existing, please choose another name"; _ret = new Object(); _ret["name"] = _numbernew; @@ -796,24 +797,26 @@ function CreateNUMBER(_numbernew){ function getROIInfo(_typeROI, _number){ - index = 0; + index = -1; for (var i = 0; i < NUMBERS.length; ++i) if (NUMBERS[i]["name"] == _number) index = i; - return NUMBERS[index][_typeROI]; + if (index != -1) + return NUMBERS[index][_typeROI]; + else + return ""; } function RenameROI(_number, _type, _alt, _neu){ if ((_neu.includes("=")) || (_neu.includes(".")) || (_neu.includes(":")) || (_neu.includes(",")) || (_neu.includes(";")) || (_neu.includes(" ")) || - (_neu.includes("\""))) { - return "Name must not contain any of the following characters: . : , ; = \" ' '"; + (_neu.includes("\""))) + { + return "ROI name must not contain . : , ; = \" or space"; } - - index = -1; found = false; _indexnumber = -1; @@ -821,6 +824,9 @@ function RenameROI(_number, _type, _alt, _neu){ if (NUMBERS[j]["name"] == _number) _indexnumber = j; + if (_indexnumber == -1) + return "Number sequence not existing. ROI cannot be renamed" + for (i = 0; i < NUMBERS[_indexnumber][_type].length; ++i) { if (NUMBERS[_indexnumber][_type][i]["name"] == _alt) index = i; @@ -829,18 +835,18 @@ function RenameROI(_number, _type, _alt, _neu){ } if (found) - return "Name is already existing - please use another name"; + return "ROI name is already existing, please choose another name"; NUMBERS[_indexnumber][_type][index]["name"] = _neu; return ""; } + function DeleteNUMBER(_delte){ if (NUMBERS.length == 1) - return "The last number cannot be deleted." + return "The last number cannot be deleted" - index = -1; for (i = 0; i < NUMBERS.length; ++i) { if (NUMBERS[i]["name"] == _delte) @@ -854,21 +860,24 @@ function DeleteNUMBER(_delte){ return ""; } + function CreateROI(_number, _type, _pos, _roinew, _x, _y, _dx, _dy, _CCW){ _indexnumber = -1; for (j = 0; j < NUMBERS.length; ++j) if (NUMBERS[j]["name"] == _number) _indexnumber = j; + if (_indexnumber == -1) + return "Number sequence not existing. ROI cannot be created" found = false; - for (i = 0; i < NUMBERS.length; ++i) { - if (NUMBERS[_indexnumber][_type]["name"] == _roinew) + for (i = 0; i < NUMBERS[_indexnumber][_type].length; ++i) { + if (NUMBERS[_indexnumber][_type][i]["name"] == _roinew) found = true; } if (found) - return "ROI does already exist, please choose another name!"; + return "ROI name is already existing, please choose another name"; _ret = new Object(); _ret["name"] = _roinew; diff --git a/sd-card/html/reboot_page.html b/sd-card/html/reboot_page.html index 3795296f7..f58440b71 100644 --- a/sd-card/html/reboot_page.html +++ b/sd-card/html/reboot_page.html @@ -1,9 +1,8 @@ - + - Reboot - + @@ -22,13 +21,13 @@ - -

Do you really want to reboot your ESP32 now?

+ +

Do you really want to reboot now?

- +
diff --git a/sd-card/html/setup.html b/sd-card/html/setup.html index c33837943..3196908a2 100644 --- a/sd-card/html/setup.html +++ b/sd-card/html/setup.html @@ -1,17 +1,25 @@ - + - AI on the edge - + + + - - - -

Digitizer - Initial Setup

-

An ESP32 all inclusive neural network recognition system for meter digitalization

-
- - - - - -
- - - If you need support, have a look to the documentation or the discussion pages. -
- + + + + + +
+

Digitizer - AI on the edge - Initial setup

+

An ESP32 all inclusive neural network recognition system for meter digitalization

+
-
- -
+ + + + + + + + + + + +
+ + + + + Setup Progress:
+ +
-
- -
+
+ +
+
+ + +
- - diff --git a/sd-card/html/style.css b/sd-card/html/style.css index c2b6c3e83..60da015e3 100644 --- a/sd-card/html/style.css +++ b/sd-card/html/style.css @@ -1,26 +1,39 @@ body, html { - width: 100%; - height: 100%; - min-height: 800px; + max-width: 1022px; + min-width: 688px; + height: 100vh; + min-height: 100vh; + margin: 0px 0px 0px 2px; + padding: 0; + font-family: arial; +} + +@media screen and (max-width:687px) { + body, html { + max-width: 687px; + height: 150vh; + min-height: 100vh; margin: 0px 0px 0px 2px; padding: 0; font-family: arial; - width: fit-content; + } } .main { display: flex; width: 100%; height: 100%; - flex-direction: column; + flex-direction: column; overflow: hidden; + font-family: arial; } .iframe { - flex-grow: 1; - margin: 5px 0px 4px 0px; + flex: 1 1 auto; + margin: 5px 0px 8px 0px; padding: 0; - border: 2px solid #333; /* black */ + border: 0px solid #333; /* black */ + font-family: arial; } h1 { @@ -41,20 +54,13 @@ p { font-size: 1em; } - - - - - - - .menu { margin: 0px; padding: 0px; font-family: "Arial"; font-size: 18px; font-weight: bold; - width: 1008px; + width: 100%; background: #333; /* black */ } @@ -171,13 +177,6 @@ p { color: white; } - - - - - - - .arrow { border: solid #333; /* black */ border-width: 0 3px 3px 0; @@ -187,9 +186,8 @@ p { } .right { - transform: rotate(-45deg); -webkit-transform: rotate(-45deg); - + transform: rotate(-45deg); position: absolute; right: 10px; top: 20px; @@ -198,8 +196,8 @@ p { } .down { - transform: rotate(45deg); -webkit-transform: rotate(45deg); + transform: rotate(45deg); border-bottom: solid white; border-right: solid white; margin: 0px 0px 2px 5px; diff --git a/sd-card/html/test.html b/sd-card/html/test.html deleted file mode 100644 index 8657156d5..000000000 --- a/sd-card/html/test.html +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - - - - testschrift -
- - - - - - diff --git a/sd-card/html/testcnn.html b/sd-card/html/testcnn.html deleted file mode 100644 index ab2b44c2a..000000000 --- a/sd-card/html/testcnn.html +++ /dev/null @@ -1 +0,0 @@ -

Not-a-Number

\ No newline at end of file diff --git a/sd-card/html/timezones.html b/sd-card/html/timezones.html index 90cd52494..410c84ced 100644 --- a/sd-card/html/timezones.html +++ b/sd-card/html/timezones.html @@ -1,5 +1,5 @@ - +