From 69583db99e9f9cc9747d27836bba4fe1e7f73b41 Mon Sep 17 00:00:00 2001 From: jomjol <30766535+jomjol@users.noreply.github.com> Date: Thu, 2 Feb 2023 19:14:55 +0100 Subject: [PATCH 01/31] Correct influx utc (#1964) * Update interface_influxdb.cpp * Correct to UTC --- code/components/jomjol_influxdb/interface_influxdb.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/code/components/jomjol_influxdb/interface_influxdb.cpp b/code/components/jomjol_influxdb/interface_influxdb.cpp index 1c95a2bd..f311085e 100644 --- a/code/components/jomjol_influxdb/interface_influxdb.cpp +++ b/code/components/jomjol_influxdb/interface_influxdb.cpp @@ -69,15 +69,20 @@ void InfluxDBPublish(std::string _key, std::string _content, std::string _timest strptime(_timestamp.c_str(), PREVALUE_TIME_FORMAT_OUTPUT, &tm); time_t t = mktime(&tm); // t is now your desired time_t + struct tm * ptm; + ptm = gmtime ( &t ); + time_t utc = mktime(ptm); // time_t now; // time(&now); char nowTimestamp[21]; // pad with zeroes to get nanoseconds // sprintf(nowTimestamp,"%ld000000000", (long) now); - sprintf(nowTimestamp,"%ld000000000", (long) t); +// sprintf(nowTimestamp,"%ld000000000", (long) t); // Localtime + sprintf(nowTimestamp,"%ld000000000", (long) utc); // UTC +// LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Test Time Conversion - t: " + std::to_string(t) + ", utc: " + std::to_string(utc)); // LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Test Time Conversion - now: " + std::to_string(now) + ", timestamp: " + std::to_string(t) + "(correct time not used yet)"); std::string payload = _influxDBMeasurement + " " + _key + "=" + _content + " " + nowTimestamp; From 1d2f9208191b21d9d9bac9207cf4638b06aac159 Mon Sep 17 00:00:00 2001 From: Nicolas Liaudat Date: Fri, 3 Feb 2023 21:01:43 +0100 Subject: [PATCH 02/31] Option alignment algo off (#1924) * Update edit_config_param.html * Update ClassFlowAlignment.cpp --- .../ClassFlowAlignment.cpp | 32 ++++++++++++++----- sd-card/html/edit_config_param.html | 1 + 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/code/components/jomjol_flowcontroll/ClassFlowAlignment.cpp b/code/components/jomjol_flowcontroll/ClassFlowAlignment.cpp index 4d4038b8..2cb8580a 100644 --- a/code/components/jomjol_flowcontroll/ClassFlowAlignment.cpp +++ b/code/components/jomjol_flowcontroll/ClassFlowAlignment.cpp @@ -65,7 +65,7 @@ bool ClassFlowAlignment::ReadParameter(FILE* pfile, string& aktparamgraph) std::vector splitted; int suchex = 40; int suchey = 40; - int alg_algo = 0; + int alg_algo = 0; //default=0; 1 =HIGHACCURACY; 2= FAST; 3= OFF //add disable aligment algo |01.2023 aktparamgraph = trim(aktparamgraph); @@ -130,6 +130,8 @@ bool ClassFlowAlignment::ReadParameter(FILE* pfile, string& aktparamgraph) alg_algo = 1; if (toUpper(splitted[1]) == "FAST") alg_algo = 2; + if (toUpper(splitted[1]) == "OFF") //no align algo if set to 3 = off => no draw ref //add disable aligment algo |01.2023 + alg_algo = 3; } } @@ -145,7 +147,10 @@ bool ClassFlowAlignment::ReadParameter(FILE* pfile, string& aktparamgraph) #endif } - LoadReferenceAlignmentValues(); + //no align algo if set to 3 = off => no draw ref //add disable aligment algo |01.2023 + if(References[0].alignment_algo != 3){ + LoadReferenceAlignmentValues(); + } return true; @@ -230,14 +235,22 @@ bool ClassFlowAlignment::doFlow(string time) AlignAndCutImage->SaveToFile(FormatFileName("/sdcard/img_tmp/rot.jpg")); } - if (!AlignAndCutImage->Align(&References[0], &References[1])) - { - SaveReferenceAlignmentValues(); - } + + //no align algo if set to 3 = off //add disable aligment algo |01.2023 + if(References[0].alignment_algo != 3){ + if (!AlignAndCutImage->Align(&References[0], &References[1])) + { + SaveReferenceAlignmentValues(); + } + }// no align + #ifdef ALGROI_LOAD_FROM_MEM_AS_JPG if (AlgROI) { - DrawRef(ImageTMP); + //no align algo if set to 3 = off => no draw ref //add disable aligment algo |01.2023 + if(References[0].alignment_algo != 3){ + DrawRef(ImageTMP); + } tfliteflow.DigitalDrawROI(ImageTMP); tfliteflow.AnalogDrawROI(ImageTMP); ImageTMP->writeToMemoryAsJPG((ImageData*)AlgROI, 90); @@ -261,7 +274,10 @@ bool ClassFlowAlignment::doFlow(string time) delete ImageTMP; ImageTMP = NULL; - LoadReferenceAlignmentValues(); + //no align algo if set to 3 = off => no draw ref //add disable aligment algo |01.2023 + if(References[0].alignment_algo != 3){ + LoadReferenceAlignmentValues(); + } return true; } diff --git a/sd-card/html/edit_config_param.html b/sd-card/html/edit_config_param.html index d78a6dd1..370f9d05 100644 --- a/sd-card/html/edit_config_param.html +++ b/sd-card/html/edit_config_param.html @@ -282,6 +282,7 @@ textarea { + From 2ee85001ebad9352bb41d36a41e6cbabeec5f34d Mon Sep 17 00:00:00 2001 From: Slider0007 <115730895+Slider0007@users.noreply.github.com> Date: Fri, 3 Feb 2023 21:02:32 +0100 Subject: [PATCH 03/31] Cleanup defines.h (#1967) * Update defines.h * Update: Disable USE_HIMEM_IF_AVAILABLE --- code/include/defines.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/code/include/defines.h b/code/include/defines.h index c5a13d1d..78a3eb41 100644 --- a/code/include/defines.h +++ b/code/include/defines.h @@ -21,7 +21,9 @@ // use himem //https://github.com/jomjol/AI-on-the-edge-device/issues/1842 - #define USE_HIMEM_IF_AVAILABLE + #if (CONFIG_SPIRAM_BANKSWITCH_ENABLE) + #define USE_HIMEM_IF_AVAILABLE 1 + #endif /* Uncomment this to generate task list with stack sizes using the /heap handler PLEASE BE AWARE: The following CONFIG parameters have to to be set in @@ -116,7 +118,6 @@ //ClassFlowControll: Serve alg_roi.jpg from memory as JPG #define ALGROI_LOAD_FROM_MEM_AS_JPG // Load ALG_ROI.JPG as rendered JPG from RAM - #define ALGROI_LOAD_FROM_MEM_AS_JPG__SHOW_TAKE_IMAGE_PROCESS // Show take image image processing on webinterface (overview.html) //ClassFlowMQTT #define LWT_TOPIC "connection" From d63dc08f339565f9e8438c6fbb2462c6b46c0a2b Mon Sep 17 00:00:00 2001 From: CaCO3 Date: Fri, 3 Feb 2023 21:43:40 +0100 Subject: [PATCH 04/31] Update manual-update-webinstaller.yml --- .github/workflows/manual-update-webinstaller.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/manual-update-webinstaller.yml b/.github/workflows/manual-update-webinstaller.yml index 1b8bf455..7c36cdc0 100644 --- a/.github/workflows/manual-update-webinstaller.yml +++ b/.github/workflows/manual-update-webinstaller.yml @@ -35,7 +35,7 @@ jobs: uses: InsonusK/get-latest-release@v1.0.1 with: myToken: ${{ github.token }} - exclude_types: "release" + exclude_types: "draft|prerelease" view_top: 1 - name: Add binary to Web Installer and update manifest From 4bfe5422c5b337889a0bd2c6b5808c245cab425a Mon Sep 17 00:00:00 2001 From: CaCO3 Date: Fri, 3 Feb 2023 21:46:08 +0100 Subject: [PATCH 05/31] fix broken webinstaller update --- .github/workflows/build.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index ecfae65b..d6488d56 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -393,7 +393,7 @@ jobs: uses: InsonusK/get-latest-release@v1.0.1 with: myToken: ${{ github.token }} - exclude_types: "release" + exclude_types: "draft|prerelease" view_top: 1 - name: Add binary to Web Installer and update manifest From 800e231301e76a03d11a002c61af25141c1d635a Mon Sep 17 00:00:00 2001 From: jomjol <30766535+jomjol@users.noreply.github.com> Date: Sat, 4 Feb 2023 21:45:02 +0100 Subject: [PATCH 06/31] Update Changelog.md --- Changelog.md | 34 +++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/Changelog.md b/Changelog.md index 05391a7e..5ec4c1e1 100644 --- a/Changelog.md +++ b/Changelog.md @@ -2,6 +2,32 @@ ## [Unreleased] +### Update Procedure + +Update Procedure see [online documentation](https://jomjol.github.io/AI-on-the-edge-device-docs/Installation/#update-ota-over-the-air) + +### Changes + +For a full list of changes see [Full list of changes](https://github.com/jomjol/AI-on-the-edge-device/compare/rolling...v14.0.0) + +#### Added + +- n.a. + +#### Changed + +- n.a. + +#### Fixed + +- [#1961](https://github.com/jomjol/AI-on-the-edge-device/issues/1961) Weird ROI Image with `FlipImageSize = true` + +#### Removed + +- n.a. + +## [14.0.0] - 2023-02-02 + **Stabilization and Improved User Experience** Thanks to over 80 Pull Requests from 6 contributors, we can anounce another great release with many many improvements and new features: @@ -150,8 +176,8 @@ Improve **u**ser e**x**perience 5. Now you can reboot. If anything breaks you can try to -1. Call `http:///ota?task=update&file=firmware.bin` resp. `http:///ota?task=update&file=html.zip` if the upload successed but the extraction failed. -1. Use the initial_esp32_setup.zip ( ) as alternative. +1\. Call `http:///ota?task=update&file=firmware.bin` resp. `http:///ota?task=update&file=html.zip` if the upload successed but the extraction failed. +1\. Use the initial_esp32_setup.zip ( ) as alternative. ### Added @@ -821,4 +847,6 @@ External Illumination [11.3.9]: https://github.com/haverland/AI-on-the-edge-device/compare/v10.6.2...v11.3.9 -[Unreleased]: https://github.com/jomjol/AI-on-the-edge-device/compare/v14.0.0-RC8...HEAD \ No newline at end of file +[Unreleased]: https://github.com/jomjol/AI-on-the-edge-device/compare/14.0.0...HEAD + +[14.0.0]: https://github.com/jomjol/AI-on-the-edge-device/compare/13.0.8...14.0.0 From 55efc3b3f48f926e3f7353bec28468eaf0602016 Mon Sep 17 00:00:00 2001 From: Slider0007 <115730895+Slider0007@users.noreply.github.com> Date: Sun, 5 Feb 2023 08:09:53 +0100 Subject: [PATCH 07/31] wifi disconnect before deinit (#1978) --- code/components/jomjol_wlan/connect_wlan.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/code/components/jomjol_wlan/connect_wlan.cpp b/code/components/jomjol_wlan/connect_wlan.cpp index 59c42976..1d5b80bf 100644 --- a/code/components/jomjol_wlan/connect_wlan.cpp +++ b/code/components/jomjol_wlan/connect_wlan.cpp @@ -556,7 +556,9 @@ bool getWIFIisConnected() void WIFIDestroy() { - esp_event_handler_unregister(IP_EVENT, IP_EVENT_STA_GOT_IP, event_handler); + esp_wifi_disconnect(); + + esp_event_handler_unregister(IP_EVENT, IP_EVENT_STA_GOT_IP, event_handler); esp_event_handler_unregister(WIFI_EVENT, ESP_EVENT_ANY_ID, event_handler); #ifdef WLAN_USE_MESH_ROAMING esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_STA_BSS_RSSI_LOW, esp_bss_rssi_low_handler); From 06f4d417b505bec37ec5a2224c9bed48990c4664 Mon Sep 17 00:00:00 2001 From: CaCO3 Date: Sun, 5 Feb 2023 08:10:29 +0100 Subject: [PATCH 08/31] Cleanup config (#1972) * Update config.ini * Update config.ini * Update config.ini --- sd-card/config/config.ini | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sd-card/config/config.ini b/sd-card/config/config.ini index 9f516bd3..58c9d0d9 100644 --- a/sd-card/config/config.ini +++ b/sd-card/config/config.ini @@ -9,7 +9,7 @@ LEDIntensity = 50 ImageQuality = 12 ImageSize = VGA FixedExposure = false -;Demo = true +Demo = false [Alignment] InitialRotate = 179 @@ -46,7 +46,7 @@ main.DecimalShift = 0 main.AnalogDigitalTransitionStart = 9.2 PreValueUse = true PreValueAgeStartup = 720 -AllowNegativeRates = false +main.AllowNegativeRates = false main.MaxRateValue = 0.05 ;main.MaxRateType = AbsoluteChange ;main.ExtendedResolution = false @@ -100,4 +100,5 @@ TimeZone = CET-1CEST,M3.5.0,M10.5.0/3 ;TimeServer = pool.ntp.org ;AutoAdjustSummertime = false ;Hostname = undefined +;RSSIThreashold = 0 SetupMode = true From b9134f923efd14e50e29cadfc3273f277ac9b865 Mon Sep 17 00:00:00 2001 From: Slider0007 <115730895+Slider0007@users.noreply.github.com> Date: Sun, 5 Feb 2023 08:10:59 +0100 Subject: [PATCH 09/31] ota_page: Add missing quotation mark (#1977) --- sd-card/html/ota_page.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sd-card/html/ota_page.html b/sd-card/html/ota_page.html index ddee596d..f97bf753 100644 --- a/sd-card/html/ota_page.html +++ b/sd-card/html/ota_page.html @@ -118,7 +118,7 @@ * - *.bin * - *.zip */ else if (filename.endsWith(".zip") || filename.endsWith(".bin")) { // Warning but still accepted - firework.launch('The filename does not match the suggested filename pattern, but is nevertheless accepted. You can now press "Upload and install', 'warning', 10000); + firework.launch('The filename does not match the suggested filename pattern, but is nevertheless accepted. You can now press "Upload and install".', 'warning', 10000); } /* Any other file name format is not accepted */ else { // invalid From 3fa16c5624e1a77b5012eda91f4804cdd0be6ccc Mon Sep 17 00:00:00 2001 From: CaCO3 Date: Sun, 5 Feb 2023 15:31:04 +0100 Subject: [PATCH 10/31] Use the preprocessed Web UI for the manual.zip (#1983) * Update build.yaml * Update build.yaml * Update build.yaml --- .github/workflows/build.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index d6488d56..d620dc00 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -248,6 +248,8 @@ jobs: cp -f "./code/.pio/build/esp32cam/firmware.bin" "manual_setup/firmware.bin" cp -f "./code/.pio/build/esp32cam/bootloader.bin" "manual_setup/bootloader.bin" cp -f "./code/.pio/build/esp32cam/partitions.bin" "manual_setup/partitions.bin" + rm -rf ./sd-card/html + cp -r ./html ./sd-card/ # Overwrite the Web UI with the preprocessed files cd sd-card; zip -r ../manual_setup/sd-card.zip *; cd .. cd ./manual_setup From bf090f3762dfac0c106337d0ec66e02a49ff2b68 Mon Sep 17 00:00:00 2001 From: CaCO3 Date: Tue, 7 Feb 2023 23:13:11 +0100 Subject: [PATCH 11/31] Update README.md --- firmware/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/firmware/README.md b/firmware/README.md index bf3f5130..79e006a9 100644 --- a/firmware/README.md +++ b/firmware/README.md @@ -3,4 +3,4 @@ The firmware got moved to the [Release page](https://github.com/jomjol/AI-on-the # Installation Guide -You find the complete installation guide at +You find the complete installation guide at https://jomjol.github.io/AI-on-the-edge-device-docs/Installation/ From 876adc51af255d5cf9a56103220af94a8d853b1d Mon Sep 17 00:00:00 2001 From: Joerg Rosenkranz Date: Wed, 8 Feb 2023 19:54:10 +0100 Subject: [PATCH 12/31] Fix small typo (#1995) --- sd-card/html/edit_explain_0.html | 2 +- sd-card/html/setup.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sd-card/html/edit_explain_0.html b/sd-card/html/edit_explain_0.html index 9935906e..2083fd88 100644 --- a/sd-card/html/edit_explain_0.html +++ b/sd-card/html/edit_explain_0.html @@ -57,7 +57,7 @@ p {font-size: 1em;} After step 5 setup mode is completed, it then reboots and starts into the normal mode.

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

Have fun with the digitizer!

diff --git a/sd-card/html/setup.html b/sd-card/html/setup.html index c0a22219..176fe9bb 100644 --- a/sd-card/html/setup.html +++ b/sd-card/html/setup.html @@ -40,7 +40,7 @@ p {font-size: 1em;} - If you need support, have a look to the documenation or the discussion pages. + If you need support, have a look to the documentation or the discussion pages. From a9c5bebb45298ca6a697285141bfd510d5f45f9e Mon Sep 17 00:00:00 2001 From: jomjol <30766535+jomjol@users.noreply.github.com> Date: Wed, 8 Feb 2023 19:56:28 +0100 Subject: [PATCH 13/31] Update interface_influxdb.cpp --- .../jomjol_influxdb/interface_influxdb.cpp | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/code/components/jomjol_influxdb/interface_influxdb.cpp b/code/components/jomjol_influxdb/interface_influxdb.cpp index f311085e..8d8fbd0a 100644 --- a/code/components/jomjol_influxdb/interface_influxdb.cpp +++ b/code/components/jomjol_influxdb/interface_influxdb.cpp @@ -67,23 +67,21 @@ void InfluxDBPublish(std::string _key, std::string _content, std::string _timest // Format: #define PREVALUE_TIME_FORMAT_OUTPUT "%Y-%m-%dT%H:%M:%S%z" struct tm tm; strptime(_timestamp.c_str(), PREVALUE_TIME_FORMAT_OUTPUT, &tm); - time_t t = mktime(&tm); // t is now your desired time_t + + time_t t = mktime(&tm); // Time in Localtime (looks like timezone is not used by strptime) struct tm * ptm; ptm = gmtime ( &t ); + time_t utc = mktime(ptm); + utc = 2*t - utc; -// time_t now; -// time(&now); char nowTimestamp[21]; - // pad with zeroes to get nanoseconds -// sprintf(nowTimestamp,"%ld000000000", (long) now); -// sprintf(nowTimestamp,"%ld000000000", (long) t); // Localtime - sprintf(nowTimestamp,"%ld000000000", (long) utc); // UTC - -// LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Test Time Conversion - t: " + std::to_string(t) + ", utc: " + std::to_string(utc)); -// LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Test Time Conversion - now: " + std::to_string(now) + ", timestamp: " + std::to_string(t) + "(correct time not used yet)"); + sprintf(nowTimestamp,"%ld000000000", (long) utc); // UTC + + +// LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Test Time Conversion - t: " + std::to_string(t) + ", utc: " + std::to_string(utc) + ", now: " + std::to_string(now) + ", utc_local: " + std::to_string(utc_local)); std::string payload = _influxDBMeasurement + " " + _key + "=" + _content + " " + nowTimestamp; payload.shrink_to_fit(); From 0b2e38935bea28b536c3f2fd36b534e32e6d9d55 Mon Sep 17 00:00:00 2001 From: jomjol <30766535+jomjol@users.noreply.github.com> Date: Wed, 8 Feb 2023 20:29:01 +0100 Subject: [PATCH 14/31] Update Changelog.md --- Changelog.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Changelog.md b/Changelog.md index 5632ab7a..f1a37030 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,4 +1,4 @@ -## [14.0.2] - 2023-02-05 +## [Unreleased] **Stabilization and Improved User Experience** @@ -47,6 +47,7 @@ For a full list of changes see [Full list of changes](https://github.com/jomjol/ - [1530](https://github.com/jomjol/AI-on-the-edge-device/pull/1530) Homeassistant `Problem Sensor` - [1518](https://github.com/jomjol/AI-on-the-edge-device/pull/1518) JSON Strings - [1817](https://github.com/jomjol/AI-on-the-edge-device/pull/1817) DataGraph: datafiles sorted -> newest on top +- **New 14.0.4:** Fix for InfluxDB timeshift problem [#1991](https://github.com/jomjol/AI-on-the-edge-device/issues/1991) #### Removed From 1acd72d33e74b697b552876d287d835f503734fd Mon Sep 17 00:00:00 2001 From: jomjol <30766535+jomjol@users.noreply.github.com> Date: Thu, 9 Feb 2023 20:13:08 +0100 Subject: [PATCH 15/31] Implement InfluxDB v2 (#2004) * Implement InfluxDBv2 Innitial * Update incl. UI * Correct UI * Update UI - Indiv. Param. * Update edit_config_param.html * Correct Timeshift * Update Fieldname --- .../jomjol_flowcontroll/ClassFlowControll.cpp | 8 + .../jomjol_flowcontroll/ClassFlowControll.h | 1 + .../ClassFlowDefineTypes.h | 1 + .../ClassFlowInfluxDBv2.cpp | 219 ++++++++++++++++++ .../jomjol_flowcontroll/ClassFlowInfluxDBv2.h | 41 ++++ .../ClassFlowPostProcessing.h | 3 +- code/components/jomjol_helper/Helper.cpp | 6 +- .../jomjol_influxdb/interface_influxdb.cpp | 129 +++++++++-- .../jomjol_influxdb/interface_influxdb.h | 11 +- sd-card/html/edit_config_param.html | 180 ++++++++++++-- sd-card/html/gethost.js | 2 +- sd-card/html/readconfigcommon.js | 5 +- sd-card/html/readconfigparam.js | 12 + 13 files changed, 578 insertions(+), 40 deletions(-) create mode 100644 code/components/jomjol_flowcontroll/ClassFlowInfluxDBv2.cpp create mode 100644 code/components/jomjol_flowcontroll/ClassFlowInfluxDBv2.h diff --git a/code/components/jomjol_flowcontroll/ClassFlowControll.cpp b/code/components/jomjol_flowcontroll/ClassFlowControll.cpp index 667ab683..4de11c02 100644 --- a/code/components/jomjol_flowcontroll/ClassFlowControll.cpp +++ b/code/components/jomjol_flowcontroll/ClassFlowControll.cpp @@ -60,6 +60,9 @@ std::string ClassFlowControll::doSingleStep(std::string _stepname, std::string _ if ((_stepname.compare("[InfluxDB]") == 0) || (_stepname.compare(";[InfluxDB]") == 0)){ _classname = "ClassFlowInfluxDB"; } + if ((_stepname.compare("[InfluxDBv2]") == 0) || (_stepname.compare(";[InfluxDBv2]") == 0)){ + _classname = "ClassFlowInfluxDBv2"; + } #endif //ENABLE_INFLUXDB for (int i = 0; i < FlowControll.size(); ++i) @@ -90,6 +93,8 @@ std::string ClassFlowControll::TranslateAktstatus(std::string _input) #ifdef ENABLE_INFLUXDB if (_input.compare("ClassFlowInfluxDB") == 0) return ("Sending InfluxDB"); + if (_input.compare("ClassFlowInfluxDBv2") == 0) + return ("Sending InfluxDBv2"); #endif //ENABLE_INFLUXDB if (_input.compare("ClassFlowPostProcessing") == 0) return ("Post-Processing"); @@ -233,6 +238,8 @@ ClassFlow* ClassFlowControll::CreateClassFlow(std::string _type) #ifdef ENABLE_INFLUXDB if (toUpper(_type).compare("[INFLUXDB]") == 0) cfc = new ClassFlowInfluxDB(&FlowControll); + if (toUpper(_type).compare("[INFLUXDBV2]") == 0) + cfc = new ClassFlowInfluxDBv2(&FlowControll); #endif //ENABLE_INFLUXDB if (toUpper(_type).compare("[WRITELIST]") == 0) cfc = new ClassFlowWriteList(&FlowControll); @@ -290,6 +297,7 @@ void ClassFlowControll::InitFlow(std::string config) while ((line.size() > 0) && !(feof(pFile))) { cfc = CreateClassFlow(line); +// printf("Name: %s\n", cfc->name().c_str()); if (cfc) { ESP_LOGD(TAG, "Start ReadParameter (%s)", line.c_str()); diff --git a/code/components/jomjol_flowcontroll/ClassFlowControll.h b/code/components/jomjol_flowcontroll/ClassFlowControll.h index fdcad311..22ac6898 100644 --- a/code/components/jomjol_flowcontroll/ClassFlowControll.h +++ b/code/components/jomjol_flowcontroll/ClassFlowControll.h @@ -15,6 +15,7 @@ #endif //ENABLE_MQTT #ifdef ENABLE_INFLUXDB #include "ClassFlowInfluxDB.h" + #include "ClassFlowInfluxDBv2.h" #endif //ENABLE_INFLUXDB #include "ClassFlowCNNGeneral.h" #include "ClassFlowWriteList.h" diff --git a/code/components/jomjol_flowcontroll/ClassFlowDefineTypes.h b/code/components/jomjol_flowcontroll/ClassFlowDefineTypes.h index 4890d94f..4a35773f 100644 --- a/code/components/jomjol_flowcontroll/ClassFlowDefineTypes.h +++ b/code/components/jomjol_flowcontroll/ClassFlowDefineTypes.h @@ -50,6 +50,7 @@ struct NumberPost { int DecimalShiftInitial; float AnalogDigitalTransitionStart; // When is the digit > x.1, i.e. when does it start to tilt? int Nachkomma; + string Fieldname; // Fieldname in InfluxDB2 bool isExtendedResolution; diff --git a/code/components/jomjol_flowcontroll/ClassFlowInfluxDBv2.cpp b/code/components/jomjol_flowcontroll/ClassFlowInfluxDBv2.cpp new file mode 100644 index 00000000..d88ec25b --- /dev/null +++ b/code/components/jomjol_flowcontroll/ClassFlowInfluxDBv2.cpp @@ -0,0 +1,219 @@ +#ifdef ENABLE_INFLUXDB +#include +#include "ClassFlowInfluxDBv2.h" +#include "Helper.h" +#include "connect_wlan.h" + +#include "time_sntp.h" +#include "interface_influxdb.h" + +#include "ClassFlowPostProcessing.h" +#include "esp_log.h" +#include "../../include/defines.h" + +#include "ClassLogFile.h" + +#include + +static const char* TAG = "class_flow_influxDbv2"; + +void ClassFlowInfluxDBv2::SetInitialParameter(void) +{ + uri = ""; + database = ""; + measurement = ""; + dborg = ""; + dbtoken = ""; +// dbfield = ""; + + OldValue = ""; + flowpostprocessing = NULL; + previousElement = NULL; + ListFlowControll = NULL; + disabled = false; + InfluxDBenable = false; +} + +ClassFlowInfluxDBv2::ClassFlowInfluxDBv2() +{ + SetInitialParameter(); +} + +ClassFlowInfluxDBv2::ClassFlowInfluxDBv2(std::vector* lfc) +{ + SetInitialParameter(); + + ListFlowControll = lfc; + for (int i = 0; i < ListFlowControll->size(); ++i) + { + if (((*ListFlowControll)[i])->name().compare("ClassFlowPostProcessing") == 0) + { + flowpostprocessing = (ClassFlowPostProcessing*) (*ListFlowControll)[i]; + } + } +} + +ClassFlowInfluxDBv2::ClassFlowInfluxDBv2(std::vector* lfc, ClassFlow *_prev) +{ + SetInitialParameter(); + + previousElement = _prev; + ListFlowControll = lfc; + + for (int i = 0; i < ListFlowControll->size(); ++i) + { + if (((*ListFlowControll)[i])->name().compare("ClassFlowPostProcessing") == 0) + { + flowpostprocessing = (ClassFlowPostProcessing*) (*ListFlowControll)[i]; + } + } +} + + +bool ClassFlowInfluxDBv2::ReadParameter(FILE* pfile, string& aktparamgraph) +{ + std::vector splitted; + + aktparamgraph = trim(aktparamgraph); + printf("akt param: %s\n", aktparamgraph.c_str()); + + if (aktparamgraph.size() == 0) + if (!this->GetNextParagraph(pfile, aktparamgraph)) + return false; + + if (toUpper(aktparamgraph).compare("[INFLUXDBV2]") != 0) + return false; + + while (this->getNextLine(pfile, &aktparamgraph) && !this->isNewParagraph(aktparamgraph)) + { +// ESP_LOGD(TAG, "while loop reading line: %s", aktparamgraph.c_str()); + splitted = ZerlegeZeile(aktparamgraph); + std::string _param = GetParameterName(splitted[0]); + + if ((toUpper(_param) == "ORG") && (splitted.size() > 1)) + { + this->dborg = splitted[1]; + } + if ((toUpper(_param) == "TOKEN") && (splitted.size() > 1)) + { + this->dbtoken = splitted[1]; + } + if ((toUpper(_param) == "URI") && (splitted.size() > 1)) + { + this->uri = splitted[1]; + } + if (((toUpper(_param) == "MEASUREMENT")) && (splitted.size() > 1)) + { + this->measurement = splitted[1]; + } + if (((toUpper(_param) == "FIELDNAME")) && (splitted.size() > 1)) + { + handleFieldname(splitted[0], splitted[1]); + } + if (((toUpper(splitted[0]) == "DATABASE")) && (splitted.size() > 1)) + { + this->database = splitted[1]; + } + } + + printf("uri: %s\n", uri.c_str()); + printf("measurement: %s\n", measurement.c_str()); + printf("org: %s\n", dborg.c_str()); + printf("token: %s\n", dbtoken.c_str()); + + if ((uri.length() > 0) && (database.length() > 0) && (measurement.length() > 0) && (dbtoken.length() > 0) && (dborg.length() > 0)) + { + LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Init InfluxDB with uri: " + uri + ", measurement: " + measurement + ", org: " + dborg + ", token: *****"); +// printf("vor V2 Init\n"); + InfluxDB_V2_Init(uri, database, measurement, dborg, dbtoken); +// printf("nach V2 Init\n"); + InfluxDBenable = true; + } else { + LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "InfluxDBv2 (Verion2 !!!) init skipped as we are missing some parameters"); + } + + return true; +} + + +string ClassFlowInfluxDBv2::GetInfluxDBMeasurement() +{ + return measurement; +} + +void ClassFlowInfluxDBv2::handleFieldname(string _decsep, string _value) +{ + string _digit, _decpos; + int _pospunkt = _decsep.find_first_of("."); +// ESP_LOGD(TAG, "Name: %s, Pospunkt: %d", _decsep.c_str(), _pospunkt); + if (_pospunkt > -1) + _digit = _decsep.substr(0, _pospunkt); + else + _digit = "default"; + for (int j = 0; j < flowpostprocessing->NUMBERS.size(); ++j) + { + if (_digit == "default") // Set to default first (if nothing else is set) + { + flowpostprocessing->NUMBERS[j]->Fieldname = _value; + } + if (flowpostprocessing->NUMBERS[j]->name == _digit) + { + flowpostprocessing->NUMBERS[j]->Fieldname = _value; + } + } +} + + + +bool ClassFlowInfluxDBv2::doFlow(string zwtime) +{ + if (!InfluxDBenable) + return true; + + std::string result; + std::string resulterror = ""; + std::string resultraw = ""; + std::string resultrate = ""; + std::string resulttimestamp = ""; + string zw = ""; + string namenumber = ""; + + if (flowpostprocessing) + { + std::vector* NUMBERS = flowpostprocessing->GetNumbers(); + + for (int i = 0; i < (*NUMBERS).size(); ++i) + { + result = (*NUMBERS)[i]->ReturnValue; + resultraw = (*NUMBERS)[i]->ReturnRawValue; + resulterror = (*NUMBERS)[i]->ErrorMessageText; + resultrate = (*NUMBERS)[i]->ReturnRateValue; + resulttimestamp = (*NUMBERS)[i]->timeStamp; + + if ((*NUMBERS)[i]->Fieldname.length() > 0) + { + namenumber = (*NUMBERS)[i]->Fieldname; + } + else + { + namenumber = (*NUMBERS)[i]->name; + if (namenumber == "default") + namenumber = "value"; + else + namenumber = namenumber + "/value"; + } + + printf("vor sende Influx_DB_V2 - namenumber. %s, result: %s, timestampt: %s", namenumber.c_str(), result.c_str(), resulttimestamp.c_str()); + + if (result.length() > 0) + InfluxDB_V2_Publish(namenumber, result, resulttimestamp); +// InfluxDB_V2_Publish(namenumber, result, resulttimestamp); + } + } + + OldValue = result; + + return true; +} + +#endif //ENABLE_INFLUXDB \ No newline at end of file diff --git a/code/components/jomjol_flowcontroll/ClassFlowInfluxDBv2.h b/code/components/jomjol_flowcontroll/ClassFlowInfluxDBv2.h new file mode 100644 index 00000000..a1832025 --- /dev/null +++ b/code/components/jomjol_flowcontroll/ClassFlowInfluxDBv2.h @@ -0,0 +1,41 @@ +#ifdef ENABLE_INFLUXDB + +#pragma once + +#ifndef CLASSFINFLUXDBv2_H +#define CLASSFINFLUXDBv2_H + +#include "ClassFlow.h" + +#include "ClassFlowPostProcessing.h" + +#include + +class ClassFlowInfluxDBv2 : + public ClassFlow +{ +protected: + std::string uri, database, measurement; + std::string dborg, dbtoken, dbfield; + std::string OldValue; + ClassFlowPostProcessing* flowpostprocessing; + bool InfluxDBenable; + + void SetInitialParameter(void); + + void handleFieldname(string _decsep, string _value); + +public: + ClassFlowInfluxDBv2(); + ClassFlowInfluxDBv2(std::vector* lfc); + ClassFlowInfluxDBv2(std::vector* lfc, ClassFlow *_prev); + + string GetInfluxDBMeasurement(); + + bool ReadParameter(FILE* pfile, string& aktparamgraph); + bool doFlow(string time); + string name(){return "ClassFlowInfluxDBv2";}; +}; + +#endif //CLASSFINFLUXDBv2_H +#endif //ENABLE_INFLUXDB \ No newline at end of file diff --git a/code/components/jomjol_flowcontroll/ClassFlowPostProcessing.h b/code/components/jomjol_flowcontroll/ClassFlowPostProcessing.h index b2fbc4b8..69a455c9 100644 --- a/code/components/jomjol_flowcontroll/ClassFlowPostProcessing.h +++ b/code/components/jomjol_flowcontroll/ClassFlowPostProcessing.h @@ -15,7 +15,6 @@ class ClassFlowPostProcessing : public ClassFlow { protected: - std::vector NUMBERS; bool UpdatePreValueINI; int PreValueAgeStartup; @@ -54,6 +53,8 @@ protected: public: bool PreValueUse; + std::vector NUMBERS; + ClassFlowPostProcessing(std::vector* lfc, ClassFlowCNNGeneral *_analog, ClassFlowCNNGeneral *_digit); virtual ~ClassFlowPostProcessing(){}; diff --git a/code/components/jomjol_helper/Helper.cpp b/code/components/jomjol_helper/Helper.cpp index a137d97d..0b8989ca 100644 --- a/code/components/jomjol_helper/Helper.cpp +++ b/code/components/jomjol_helper/Helper.cpp @@ -576,9 +576,6 @@ std::vector HelperZerlegeZeile(std::string input, std::string _delimiter std::vector ZerlegeZeile(std::string input, std::string delimiter) { std::vector Output; - - input = trim(input, delimiter); - /* The input can have multiple formats: * - key = value * - key = value1 value2 value3 ... @@ -593,12 +590,13 @@ std::vector ZerlegeZeile(std::string input, std::string delimiter) * As a workaround and to not break any legacy usage, we enforce to only use the * equal sign, if the key is "password" */ - if (input.find("password") != string::npos) { // Line contains a password, use the equal sign as the only delimiter and only split on first occurrence + if ((input.find("password") != string::npos) || (input.find("Token") != string::npos)) { // Line contains a password, use the equal sign as the only delimiter and only split on first occurrence size_t pos = input.find("="); Output.push_back(trim(input.substr(0, pos), "")); Output.push_back(trim(input.substr(pos +1, string::npos), "")); } else { // Legacy Mode + input = trim(input, delimiter); // sonst werden delimiter am Ende (z.B. == im Token) gelöscht) size_t pos = findDelimiterPos(input, delimiter); std::string token; while (pos != std::string::npos) { diff --git a/code/components/jomjol_influxdb/interface_influxdb.cpp b/code/components/jomjol_influxdb/interface_influxdb.cpp index 8d8fbd0a..e07c30e5 100644 --- a/code/components/jomjol_influxdb/interface_influxdb.cpp +++ b/code/components/jomjol_influxdb/interface_influxdb.cpp @@ -16,6 +16,101 @@ std::string _influxDBMeasurement; std::string _influxDBUser; std::string _influxDBPassword; +std::string _influxDB_V2_URI; +std::string _influxDB_V2_Database; +std::string _influxDB_V2_Measurement; +std::string _influxDB_V2_Token; +std::string _influxDB_V2_Org; + +static esp_err_t http_event_handler(esp_http_client_event_t *evt); + +void InfluxDB_V2_Init(std::string _uri, std::string _database, std::string _measurement, std::string _org, std::string _token) +{ + _influxDB_V2_URI = _uri; + _influxDB_V2_Database = _database; + _influxDB_V2_Measurement = _measurement; + _influxDB_V2_Org = _org; + _influxDB_V2_Token = _token; +} + +void InfluxDB_V2_Publish(std::string _key, std::string _content, std::string _timestamp) +{ + char response_buffer[MAX_HTTP_OUTPUT_BUFFER] = {0}; + esp_http_client_config_t http_config = { + .user_agent = "ESP32 Meter reader", + .method = HTTP_METHOD_POST, + .event_handler = http_event_handler, + .buffer_size = MAX_HTTP_OUTPUT_BUFFER, + .user_data = response_buffer + }; + + LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "InfluxDB_V2_Publish - Key: " + _key + ", Content: " + _content + ", Timestamp: " + _timestamp); + + // Format: #define PREVALUE_TIME_FORMAT_OUTPUT "%Y-%m-%dT%H:%M:%S%z" + + char nowTimestamp[21]; + std::string payload; + + if (_timestamp.length() > 0) + { + struct tm tm; + strptime(_timestamp.c_str(), PREVALUE_TIME_FORMAT_OUTPUT, &tm); + time_t t = mktime(&tm); // Time in Localtime (looks like timezone is not used by strptime) + + struct tm * ptm; + ptm = gmtime ( &t ); + time_t utc = mktime(ptm); + utc = 2*t - utc; // Take care of timezone (looks difficult, but is easy: t = t + (t - utc), weil t-utc = timezone) + + sprintf(nowTimestamp,"%ld000000000", (long) utc); // UTC + + payload = _influxDB_V2_Measurement + " " + _key + "=" + _content + " " + nowTimestamp; +// payload = _influxDB_V2_Measurement + " " + _key + "=774 " + nowTimestamp; + } + else + { + payload = _influxDB_V2_Measurement + " " + _key + "=" + _content; +// payload = _influxDB_V2_Measurement + " " + _key + "=774"; + } + + payload.shrink_to_fit(); + + LogFile.WriteToFile(ESP_LOG_INFO, TAG, "sending line to influxdb:" + payload); + + std::string apiURI = _influxDB_V2_URI + "/api/v2/write?org=" + _influxDB_V2_Org + "&bucket=" + _influxDB_V2_Database; + apiURI.shrink_to_fit(); + http_config.url = apiURI.c_str(); + ESP_LOGI(TAG, "http_config: %s", http_config.url); // Add mark on log to see when it restarted + + LogFile.WriteToFile(ESP_LOG_INFO, TAG, "API URI: " + apiURI); + + esp_http_client_handle_t http_client = esp_http_client_init(&http_config); + LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "client is initialized"); + + esp_http_client_set_header(http_client, "Content-Type", "text/plain"); + std::string _zw = "Token " + _influxDB_V2_Token; + // LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Tokenheader: %s\n", _zw.c_str()); + esp_http_client_set_header(http_client, "Authorization", _zw.c_str()); + + LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "header is set"); + + ESP_ERROR_CHECK(esp_http_client_set_post_field(http_client, payload.c_str(), payload.length())); + LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "post payload is set"); + + esp_err_t err = ESP_ERROR_CHECK_WITHOUT_ABORT(esp_http_client_perform(http_client)); + + if( err == ESP_OK ) { + LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "HTTP request was performed"); + int status_code = esp_http_client_get_status_code(http_client); + LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "HTTP status code" + std::to_string(status_code)); + } else { + LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "HTTP request failed"); + } + esp_http_client_cleanup(http_client); +} + + + static esp_err_t http_event_handler(esp_http_client_event_t *evt) { switch(evt->event_id) @@ -64,26 +159,30 @@ void InfluxDBPublish(std::string _key, std::string _content, std::string _timest LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "InfluxDBPublish - Key: " + _key + ", Content: " + _content + ", Timestamp: " + _timestamp); - // Format: #define PREVALUE_TIME_FORMAT_OUTPUT "%Y-%m-%dT%H:%M:%S%z" - struct tm tm; - strptime(_timestamp.c_str(), PREVALUE_TIME_FORMAT_OUTPUT, &tm); - - time_t t = mktime(&tm); // Time in Localtime (looks like timezone is not used by strptime) - - struct tm * ptm; - ptm = gmtime ( &t ); - - time_t utc = mktime(ptm); - utc = 2*t - utc; - char nowTimestamp[21]; + std::string payload; - sprintf(nowTimestamp,"%ld000000000", (long) utc); // UTC + if (_timestamp.length() > 0) + { + struct tm tm; + strptime(_timestamp.c_str(), PREVALUE_TIME_FORMAT_OUTPUT, &tm); + time_t t = mktime(&tm); // Time in Localtime (looks like timezone is not used by strptime) + struct tm * ptm; + ptm = gmtime ( &t ); + time_t utc = mktime(ptm); + utc = 2*t - utc; // Take care of timezone (looks difficult, but is easy: t = t + (t - utc), weil t-utc = timezone) -// LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Test Time Conversion - t: " + std::to_string(t) + ", utc: " + std::to_string(utc) + ", now: " + std::to_string(now) + ", utc_local: " + std::to_string(utc_local)); + sprintf(nowTimestamp,"%ld000000000", (long) utc); // UTC + + payload = _influxDB_V2_Measurement + " " + _key + "=" + _content + " " + nowTimestamp; +// payload = _influxDB_V2_Measurement + " " + _key + "=774 " + nowTimestamp; + } + else + { + payload = _influxDBMeasurement + " " + _key + "=" + _content; + } - std::string payload = _influxDBMeasurement + " " + _key + "=" + _content + " " + nowTimestamp; payload.shrink_to_fit(); LogFile.WriteToFile(ESP_LOG_INFO, TAG, "sending line to influxdb:" + payload); diff --git a/code/components/jomjol_influxdb/interface_influxdb.h b/code/components/jomjol_influxdb/interface_influxdb.h index ab179577..919e4a3d 100644 --- a/code/components/jomjol_influxdb/interface_influxdb.h +++ b/code/components/jomjol_influxdb/interface_influxdb.h @@ -8,10 +8,17 @@ #include #include +// Interface to InfluxDB v1.x void InfluxDBInit(std::string _influxDBURI, std::string _database, std::string _measurement, std::string _user, std::string _password); -void InfluxDBdestroy(); - void InfluxDBPublish(std::string _key, std::string _content, std::string _timestamp); +// Interface to InfluxDB v2.x +void InfluxDB_V2_Init(std::string _uri, std::string _database, std::string _measurement, std::string _org, std::string _token); +void InfluxDB_V2_Publish(std::string _key, std::string _content, std::string _timestamp); + + + +void InfluxDBdestroy(); + #endif //INTERFACE_INFLUXDB_H #endif //ENABLE_INFLUXDB \ No newline at end of file diff --git a/sd-card/html/edit_config_param.html b/sd-card/html/edit_config_param.html index 370f9d05..be7c347a 100644 --- a/sd-card/html/edit_config_param.html +++ b/sd-card/html/edit_config_param.html @@ -456,7 +456,7 @@ textarea { - + @@ -471,7 +471,7 @@ textarea { - + @@ -484,7 +484,7 @@ textarea { - + @@ -498,7 +498,7 @@ textarea { - + @@ -510,7 +510,7 @@ textarea { - + @@ -525,7 +525,7 @@ textarea { - + @@ -541,7 +541,7 @@ textarea { - + @@ -701,7 +701,7 @@ textarea {

-

Only InfluxDB v1.x is supported, v2.x has a changed interface
+ @@ -765,6 +765,109 @@ textarea { + + + + +

+ +

Only InfluxDB v2.x is configured here, v1.x see above [InfluxDB]
+ + + + + + + + + + + + URI of the HTTP interface to InfluxDB (Version2), without traililing slash, e.g. http://IP-Address:Port + + + + + + + + + + + + Database name in which to publish the read value. + + + + + + + + + + + + Measurement name to use to publish the read value. + + + + + + + + + + + + Organisation (Org) for InfluxDBv2 authentication + + + + + + + + + + + + Token for InfluxDB authentication + + + + +
+ Postprocessing Individual Parameters: + + + + + + + + + + + + + Fieldname to use for saving. + + + + + + + + + + + + +

@@ -1464,7 +1567,8 @@ function LoadConfigNeu() { InitIndivParameter(); UpdateInput(); - UpdateInputIndividual(); + var sel = document.getElementById("Numbers_value1"); + UpdateInputIndividual(sel); UpdateExpertModus(); document.getElementById("divall").style.display = ''; } @@ -1476,14 +1580,23 @@ function InitIndivParameter() var _index = document.getElementById("Numbers_value1"); while (_index.length) _index.remove(0); + var _indexInflux = document.getElementById("NumbersInfluxDB_value1"); + while (_indexInflux.length) + _indexInflux.remove(0); for (var i = 0; i < NUMBERS.length; ++i){ var option = document.createElement("option"); option.text = NUMBERS[i]["name"]; option.value = i; _index.add(option); + + var optionInflux = document.createElement("option"); + optionInflux.text = NUMBERS[i]["name"]; + optionInflux.value = i; + _indexInflux.add(optionInflux); } _index.selectedIndex = 0; + _indexInflux.selectedIndex = 0; } @@ -1768,7 +1881,7 @@ function ReadParameter(_param, _cat, _name, _optional, _number = -1){ } } -function UpdateInputIndividual() +function UpdateInputIndividual(sel) { if (NUNBERSAkt != -1) { @@ -1779,9 +1892,10 @@ function UpdateInputIndividual() ReadParameter(param, "PostProcessing", "ExtendedResolution", true, NUNBERSAkt) ReadParameter(param, "PostProcessing", "IgnoreLeadingNaN", true, NUNBERSAkt) ReadParameter(param, "PostProcessing", "AllowNegativeRates", true, NUNBERSAkt) + ReadParameter(param, "InfluxDBv2", "Fieldname", true, NUNBERSAkt) } - var sel = document.getElementById("Numbers_value1"); +// var sel = document.getElementById("Numbers_value1"); NUNBERSAkt = sel.selectedIndex; WriteParameter(param, category, "PostProcessing", "DecimalShift", true, NUNBERSAkt); WriteParameter(param, category, "PostProcessing", "AnalogDigitalTransitionStart", true, NUNBERSAkt); @@ -1790,6 +1904,7 @@ function UpdateInputIndividual() WriteParameter(param, category, "PostProcessing", "ExtendedResolution", true, NUNBERSAkt); WriteParameter(param, category, "PostProcessing", "IgnoreLeadingNaN", true, NUNBERSAkt); WriteParameter(param, category, "PostProcessing", "AllowNegativeRates", true, NUNBERSAkt); + WriteParameter(param, category, "InfluxDBv2", "Fieldname", true, NUNBERSAkt); } function UpdateInput() { @@ -1798,6 +1913,7 @@ function UpdateInput() { document.getElementById("Category_MQTT_enabled").checked = category["MQTT"]["enabled"]; document.getElementById("Category_GPIO_enabled").checked = category["GPIO"]["enabled"]; document.getElementById("Category_InfluxDB_enabled").checked = category["InfluxDB"]["enabled"]; + document.getElementById("Category_InfluxDBv2_enabled").checked = category["InfluxDBv2"]["enabled"]; setVisible("GPIO_item", category["GPIO"]["enabled"]); WriteParameter(param, category, "MakeImage", "LogImageLocation", true); @@ -1844,6 +1960,13 @@ function UpdateInput() { WriteParameter(param, category, "InfluxDB", "user", true); WriteParameter(param, category, "InfluxDB", "password", true); + WriteParameter(param, category, "InfluxDBv2", "Uri", true); + WriteParameter(param, category, "InfluxDBv2", "Database", true); + WriteParameter(param, category, "InfluxDBv2", "Measurement", true); + WriteParameter(param, category, "InfluxDBv2", "Org", true); + WriteParameter(param, category, "InfluxDBv2", "Token", true); + WriteParameter(param, category, "InfluxDBv2", "Fieldname", true); + WriteParameter(param, category, "GPIO", "IO0", true); WriteParameter(param, category, "GPIO", "IO1", true); WriteParameter(param, category, "GPIO", "IO3", true); @@ -1919,6 +2042,7 @@ function ReadParameterAll() category["Digits"]["enabled"] = document.getElementById("Category_Digits_enabled").checked; category["MQTT"]["enabled"] = document.getElementById("Category_MQTT_enabled").checked; category["InfluxDB"]["enabled"] = document.getElementById("Category_InfluxDB_enabled").checked; + category["InfluxDBv2"]["enabled"] = document.getElementById("Category_InfluxDBv2_enabled").checked; category["GPIO"]["enabled"] = document.getElementById("Category_GPIO_enabled").checked; ReadParameter(param, "MakeImage", "LogImageLocation", true); @@ -1948,7 +2072,6 @@ function ReadParameterAll() ReadParameter(param, "PostProcessing", "PreValueUse", true); ReadParameter(param, "PostProcessing", "PreValueAgeStartup", true); -// ReadParameter(param, "PostProcessing", "AllowNegativeRates", true); ReadParameter(param, "PostProcessing", "ErrorMessage", true); ReadParameter(param, "PostProcessing", "CheckDigitIncreaseConsistency", true); @@ -1967,6 +2090,13 @@ function ReadParameterAll() ReadParameter(param, "InfluxDB", "user", true); ReadParameter(param, "InfluxDB", "password", true); + ReadParameter(param, "InfluxDBv2", "Uri", true); + ReadParameter(param, "InfluxDBv2", "Database", true); + ReadParameter(param, "InfluxDBv2", "Measurement", true); + ReadParameter(param, "InfluxDBv2", "Org", true); + ReadParameter(param, "InfluxDBv2", "Token", true); +// ReadParameter(param, "InfluxDB", "Fieldname", true); + ReadParameter(param, "GPIO", "IO0", true); ReadParameter(param, "GPIO", "IO1", true); ReadParameter(param, "GPIO", "IO3", true); @@ -1998,7 +2128,8 @@ function ReadParameterAll() ReadParameter(param, "System", "TimeServer", true); ReadParameter(param, "System", "RSSIThreashold", true); - UpdateInputIndividual(); + var sel = document.getElementById("Numbers_value1"); + UpdateInputIndividual(sel); // FormatDecimalValue(param, "PostProcessing", "MaxRateValue"); } @@ -2018,10 +2149,12 @@ function UpdateAfterCategoryCheck() { category["Digits"]["enabled"] = document.getElementById("Category_Digits_enabled").checked; category["MQTT"]["enabled"] = document.getElementById("Category_MQTT_enabled").checked; category["InfluxDB"]["enabled"] = document.getElementById("Category_InfluxDB_enabled").checked; + category["InfluxDBv2"]["enabled"] = document.getElementById("Category_InfluxDBv2_enabled").checked; category["GPIO"]["enabled"] = document.getElementById("Category_GPIO_enabled").checked; UpdateInput(); - UpdateInputIndividual(); + var sel = document.getElementById("Numbers_value1"); + UpdateInputIndividual(sel); } function UpdateExpertModus() @@ -2098,9 +2231,26 @@ function editConfigDirect() { function numberChanged() { - UpdateInputIndividual(); + var sel = document.getElementById("Numbers_value1"); + _neu = sel.selectedIndex; + UpdateInputIndividual(sel); + + var _selInflux = document.getElementById("NumbersInfluxDB_value1"); + if (_selInflux.selectedIndex != _neu) + _selInflux.selectedIndex = _neu } +function numberInfluxDBChanged() +{ + var sel = document.getElementById("NumbersInfluxDB_value1"); + _neu = sel.selectedIndex; + UpdateInputIndividual(sel); + + var _sel2 = document.getElementById("Numbers_value1"); + if (_sel2.selectedIndex != _neu) + _sel2.selectedIndex = _neu +} + LoadConfigNeu(); diff --git a/sd-card/html/gethost.js b/sd-card/html/gethost.js index dc84410f..d838b629 100644 --- a/sd-card/html/gethost.js +++ b/sd-card/html/gethost.js @@ -13,7 +13,7 @@ function getbasepath(){ { // host = "http://192.168.2.219"; // jomjol interner test // host = "http://192.168.178.46"; // jomjol interner test - host = "http://192.168.178.62"; // jomjol interner Real + host = "http://192.168.178.44"; // jomjol interner Real // host = "http://192.168.43.191"; // host = "."; // jomjol interner localhost diff --git a/sd-card/html/readconfigcommon.js b/sd-card/html/readconfigcommon.js index f4cf862a..0f9c83fe 100644 --- a/sd-card/html/readconfigcommon.js +++ b/sd-card/html/readconfigcommon.js @@ -45,7 +45,6 @@ function ZerlegeZeile(input, delimiter = " =\t\r") var Output = Array(0); // delimiter = " =,\t"; - input = trim(input, delimiter); /* The input can have multiple formats: * - key = value @@ -61,12 +60,14 @@ function ZerlegeZeile(input, delimiter = " =\t\r") * As a workaround and to not break any legacy usage, we enforce to only use the * equal sign, if the key is "password" */ - if (input.includes("password")) { // Line contains a password, use the equal sign as the only delimiter and only split on first occurrence + if (input.includes("password") || input.includes("Token")) { // Line contains a password, use the equal sign as the only delimiter and only split on first occurrence var pos = input.indexOf("="); + delimiter = " \t\r" Output.push(trim(input.substr(0, pos), delimiter)); Output.push(trim(input.substr(pos +1, input.length), delimiter)); } else { // Legacy Mode + input = trim(input, delimiter); var pos = findDelimiterPos(input, delimiter); var token; while (pos > -1) { diff --git a/sd-card/html/readconfigparam.js b/sd-card/html/readconfigparam.js index b92b2611..b764a282 100644 --- a/sd-card/html/readconfigparam.js +++ b/sd-card/html/readconfigparam.js @@ -196,6 +196,18 @@ function ParseConfig() { ParamAddValue(param, catname, "user"); ParamAddValue(param, catname, "password"); + var catname = "InfluxDBv2"; + category[catname] = new Object(); + category[catname]["enabled"] = false; + category[catname]["found"] = false; + param[catname] = new Object(); + ParamAddValue(param, catname, "Uri"); + ParamAddValue(param, catname, "Database"); + ParamAddValue(param, catname, "Measurement"); + ParamAddValue(param, catname, "Org"); + ParamAddValue(param, catname, "Token"); + ParamAddValue(param, catname, "Fieldname", 1, true); + var catname = "GPIO"; category[catname] = new Object(); category[catname]["enabled"] = false; From 55be652dc1737cb021c8422fd8f5641e65bf81f4 Mon Sep 17 00:00:00 2001 From: jomjol <30766535+jomjol@users.noreply.github.com> Date: Thu, 9 Feb 2023 20:16:18 +0100 Subject: [PATCH 16/31] Update Changelog.md --- Changelog.md | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/Changelog.md b/Changelog.md index f1a37030..7a22e5c7 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,5 +1,29 @@ ## [Unreleased] +**Rolling** + + + +#### Added + +- Additional interface to InfluxDB Version 2 upwards + +#### Changed + +- n.a. + +#### Fixed + +- n.a. + +#### Removed + +- n.a. + + + +## [14.0.3] -2023-02-05 + **Stabilization and Improved User Experience** Thanks to over 80 Pull Requests from 6 contributors, we can anounce another great release with many many improvements and new features: From 44e186e65ba7fa093a4b787728ebc0778c3398ea Mon Sep 17 00:00:00 2001 From: CaCO3 Date: Sat, 11 Feb 2023 21:45:08 +0100 Subject: [PATCH 17/31] Update backup.html (#2015) --- sd-card/html/backup.html | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/sd-card/html/backup.html b/sd-card/html/backup.html index b5622027..260354d9 100644 --- a/sd-card/html/backup.html +++ b/sd-card/html/backup.html @@ -121,9 +121,15 @@ function fetchFiles(urls, filesData, index, retry, zipFilename) { else if (retry == 1) { // longer timeout xhr.timeout = 5000; // time in milliseconds } - else { // very long timeout + else if (retry == 2) { // longer timeout xhr.timeout = 20000; // time in milliseconds } + else if (retry == 3) { // longer timeout + xhr.timeout = 30000; // time in milliseconds + } + else { // very long timeout + xhr.timeout = 60000; // time in milliseconds + } xhr.onload = () => { // Request finished //console.log(url + " done"); From 7283bfd50648eacf350fc27c10cadfab37ca46c9 Mon Sep 17 00:00:00 2001 From: Yonz Date: Thu, 16 Feb 2023 21:05:34 +0100 Subject: [PATCH 18/31] Update FeatureRequest.md (#2033) Added: #35 Use the same model, but provide the image from a Smartphone Camera --- FeatureRequest.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/FeatureRequest.md b/FeatureRequest.md index 56677ba5..41315738 100644 --- a/FeatureRequest.md +++ b/FeatureRequest.md @@ -10,6 +10,11 @@ ____ +#### #35 Use the same model, but provide the image from a Smartphone Camera +as reading the Electricity or Water meter every few minutues only delivers apparent accuracy (DE: "Scheingenauigkeit") you could just as well take a picture with your Smartphone evey so often (e.g. once a week when you are in the Basement anyway), then with some "semi clever" tricks pass this image to the model developed here, and the values then on to who ever needs them e.g. via MQTT. +IMO: It is not needed to have that many readings (datapoints) as our behaviour (Use of electricity or water) doesn't vary that much, say, over a weeks time. The interpolation between weekly readings will give sufficient information on the power and/or water usage. + + #### #34 implement state and Roi for water leak detection for example see Roi on the next picture.. ![grafik](https://user-images.githubusercontent.com/38385805/207858812-2a6ba41d-1a8c-4fa1-9b6a-53cdd113c106.png) From 008dba7e11a467be0f1a9742b8c041a9e9211fd0 Mon Sep 17 00:00:00 2001 From: jomjol <30766535+jomjol@users.noreply.github.com> Date: Sat, 18 Feb 2023 11:44:56 +0100 Subject: [PATCH 19/31] fix for #2036 --- Changelog.md | 2 +- code/components/jomjol_helper/Helper.cpp | 30 ++++++++++++++++++++++++ code/components/jomjol_helper/Helper.h | 3 +++ code/main/softAP.cpp | 18 +++++++------- 4 files changed, 43 insertions(+), 10 deletions(-) diff --git a/Changelog.md b/Changelog.md index 7a22e5c7..775533f8 100644 --- a/Changelog.md +++ b/Changelog.md @@ -14,7 +14,7 @@ #### Fixed -- n.a. +- [2036](https://github.com/jomjol/AI-on-the-edge-device/issues/2036) Initial AP-Mode now decodes the parameters correctly #### Removed diff --git a/code/components/jomjol_helper/Helper.cpp b/code/components/jomjol_helper/Helper.cpp index 0b8989ca..23fad5cb 100644 --- a/code/components/jomjol_helper/Helper.cpp +++ b/code/components/jomjol_helper/Helper.cpp @@ -898,3 +898,33 @@ const char* get404(void) { " You could try your luck here!\n" ""; // Make sure we load the overview page } + + +std::string UrlDecode(const std::string& value) +{ + std::string result; + result.reserve(value.size()); + + for (std::size_t i = 0; i < value.size(); ++i) + { + auto ch = value[i]; + + if (ch == '%' && (i + 2) < value.size()) + { + auto hex = value.substr(i + 1, 2); + auto dec = static_cast(std::strtol(hex.c_str(), nullptr, 16)); + result.push_back(dec); + i += 2; + } + else if (ch == '+') + { + result.push_back(' '); + } + else + { + result.push_back(ch); + } + } + + return result; +} diff --git a/code/components/jomjol_helper/Helper.h b/code/components/jomjol_helper/Helper.h index 84171b86..6aac032f 100644 --- a/code/components/jomjol_helper/Helper.h +++ b/code/components/jomjol_helper/Helper.h @@ -93,4 +93,7 @@ std::string getFormatedUptime(bool compact); const char* get404(void); + +std::string UrlDecode(const std::string& value); + #endif //HELPER_H diff --git a/code/main/softAP.cpp b/code/main/softAP.cpp index 517ec1b8..5fb716a8 100644 --- a/code/main/softAP.cpp +++ b/code/main/softAP.cpp @@ -213,55 +213,55 @@ esp_err_t config_ini_handler(httpd_req_t *req) if (httpd_query_key_value(_query, "ssid", _valuechar, 30) == ESP_OK) { ESP_LOGD(TAG, "ssid is found: %s", _valuechar); - ssid = std::string(_valuechar); + ssid = UrlDecode(std::string(_valuechar)); } if (httpd_query_key_value(_query, "pwd", _valuechar, 30) == ESP_OK) { ESP_LOGD(TAG, "pwd is found: %s", _valuechar); - pwd = std::string(_valuechar); + pwd = UrlDecode(std::string(_valuechar)); } if (httpd_query_key_value(_query, "ssid", _valuechar, 30) == ESP_OK) { ESP_LOGD(TAG, "ssid is found: %s", _valuechar); - ssid = std::string(_valuechar); + ssid = UrlDecode(std::string(_valuechar)); } if (httpd_query_key_value(_query, "hn", _valuechar, 30) == ESP_OK) { ESP_LOGD(TAG, "hostname is found: %s", _valuechar); - hn = std::string(_valuechar); + hn = UrlDecode(std::string(_valuechar)); } if (httpd_query_key_value(_query, "ip", _valuechar, 30) == ESP_OK) { ESP_LOGD(TAG, "ip is found: %s", _valuechar); - ip = std::string(_valuechar); + ip = UrlDecode(std::string(_valuechar)); } if (httpd_query_key_value(_query, "gw", _valuechar, 30) == ESP_OK) { ESP_LOGD(TAG, "gateway is found: %s", _valuechar); - gw = std::string(_valuechar); + gw = UrlDecode(std::string(_valuechar)); } if (httpd_query_key_value(_query, "nm", _valuechar, 30) == ESP_OK) { ESP_LOGD(TAG, "netmask is found: %s", _valuechar); - nm = std::string(_valuechar); + nm = UrlDecode(std::string(_valuechar)); } if (httpd_query_key_value(_query, "dns", _valuechar, 30) == ESP_OK) { ESP_LOGD(TAG, "dns is found: %s", _valuechar); - dns = std::string(_valuechar); + dns = UrlDecode(std::string(_valuechar)); } if (httpd_query_key_value(_query, "rssi", _valuechar, 30) == ESP_OK) { ESP_LOGD(TAG, "rssi is found: %s", _valuechar); - rssi = std::string(_valuechar); + rssi = UrlDecode(std::string(_valuechar)); } }; From 5bac1c68d9981828601bc037763f06f13ba1f143 Mon Sep 17 00:00:00 2001 From: jomjol <30766535+jomjol@users.noreply.github.com> Date: Sat, 18 Feb 2023 12:46:14 +0100 Subject: [PATCH 20/31] Correct BugFix in InfluxDB --- code/components/jomjol_influxdb/interface_influxdb.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/components/jomjol_influxdb/interface_influxdb.cpp b/code/components/jomjol_influxdb/interface_influxdb.cpp index e07c30e5..bc878e84 100644 --- a/code/components/jomjol_influxdb/interface_influxdb.cpp +++ b/code/components/jomjol_influxdb/interface_influxdb.cpp @@ -175,8 +175,8 @@ void InfluxDBPublish(std::string _key, std::string _content, std::string _timest sprintf(nowTimestamp,"%ld000000000", (long) utc); // UTC - payload = _influxDB_V2_Measurement + " " + _key + "=" + _content + " " + nowTimestamp; -// payload = _influxDB_V2_Measurement + " " + _key + "=774 " + nowTimestamp; + payload = _influxDBMeasurement + " " + _key + "=" + _content + " " + nowTimestamp; +// payload = _influxDBMeasurement + " " + _key + "=774 " + nowTimestamp; } else { From 10da8c4f94512bc4615884f1a266ccb1b193b94d Mon Sep 17 00:00:00 2001 From: Slider0007 <115730895+Slider0007@users.noreply.github.com> Date: Sun, 19 Feb 2023 21:15:16 +0100 Subject: [PATCH 21/31] Support saturation & contrast (#2048) * reference image: use correct value for contrast * Update quality, contrast & saturation parameter * fix for saturation,contrast+error handling --- .../ClassControllCamera.cpp | 244 ++++++++++-------- sd-card/html/edit_config_param.html | 18 +- sd-card/html/edit_reference.html | 2 +- 3 files changed, 148 insertions(+), 116 deletions(-) diff --git a/code/components/jomjol_controlcamera/ClassControllCamera.cpp b/code/components/jomjol_controlcamera/ClassControllCamera.cpp index 71637951..e1f04091 100644 --- a/code/components/jomjol_controlcamera/ClassControllCamera.cpp +++ b/code/components/jomjol_controlcamera/ClassControllCamera.cpp @@ -63,7 +63,6 @@ static camera_config_t camera_config = { .fb_count = 1, //if more than one, i2s runs in continuous mode. Use only with JPEG .fb_location = CAMERA_FB_IN_PSRAM, /*!< The location where the frame buffer will be allocated */ .grab_mode = CAMERA_GRAB_LATEST, // only from new esp32cam version - }; @@ -126,63 +125,97 @@ void CCamera::ledc_init(void) } -static size_t jpg_encode_stream(void * arg, size_t index, const void* data, size_t len){ +static size_t jpg_encode_stream(void * arg, size_t index, const void* data, size_t len) +{ jpg_chunking_t *j = (jpg_chunking_t *)arg; - if(!index){ + + if(!index) { j->len = 0; } - if(httpd_resp_send_chunk(j->req, (const char *)data, len) != ESP_OK){ + + if(httpd_resp_send_chunk(j->req, (const char *)data, len) != ESP_OK) { return 0; } + j->len += len; + return len; } bool CCamera::SetBrightnessContrastSaturation(int _brightness, int _contrast, int _saturation) { - bool result = false; - sensor_t * s = esp_camera_sensor_get(); - if (_brightness > -100) - _brightness = min(2, max(-2, _brightness)); - if (_contrast > -100) - _contrast = min(2, max(-2, _contrast)); - if (_saturation > -100) - _saturation = min(2, max(-2, _saturation)); + _brightness = min(2, max(-2, _brightness)); + _contrast = min(2, max(-2, _contrast)); + _saturation = min(2, max(-2, _saturation)); - if (_saturation > -100) + sensor_t * s = esp_camera_sensor_get(); + if (s) { s->set_saturation(s, _saturation); - if (_contrast > -100) s->set_contrast(s, _contrast); - if (_brightness > -100) s->set_brightness(s, _brightness); - if ((_brightness != brightness) && (_brightness > -100)) - result = true; - if ((_contrast != contrast) && (_contrast > -100)) - result = true; - if ((_saturation != saturation) && (_saturation > -100)) - result = true; - - if (_brightness > -100) - brightness = _brightness; - if (_contrast > -100) - contrast = _contrast; - if (_saturation > -100) - saturation = _saturation; + /* Workaround - bug in cam library - enable bits are set without using bitwise OR logic -> only latest enable setting is used */ + /* Library version: https://github.com/espressif/esp32-camera/commit/5c8349f4cf169c8a61283e0da9b8cff10994d3f3 */ + /* Reference: https://esp32.com/viewtopic.php?f=19&t=14376#p93178 */ + /* The memory structure is as follows for + byte_0 = enable_bits + byte_0->bit0 = enable saturation and hue --> OK + byte_0->bit1 = enable saturation --> OK + byte_0->bit2 = enable brightness and contrast --> OK + byte_0->bit3 = enable green -> blue spitial effect (Antique and blunish and greenish and readdish and b&w) enable + byte_0->bit4 = anable gray -> read spitial effect (Antique and blunish and greenish and readdish and b&w) enable + byte_0->bit5 = remove (UV) in YUV color system + byte_0->bit6 = enable negative + byte_0->bit7 = remove (Y) in YUV color system + byte_1 = saturation1 0-255 --> ? + byte_2 = hue 0-255 --> OK + byte_3 = saturation2 0-255 --> OK + byte_4 = reenter saturation2 in documents --> ? + byte_5 = spital effect green -> blue 0-255 --> ? + byte_6 = spital effect gray -> read 0-255 --> ? + byte_7 = contrast lower byte 0-255 --> OK + byte_8 = contrast higher byte 0-255 --> OK + byte_9 = brightness 0-255 --> OK + byte_10= if byte_10==4 contrast effective --> ? + */ - if (result && isFixedExposure) + //s->set_reg(s, 0x7C, 0xFF, 2); // Optional feature - hue setting: Select byte 2 in register 0x7C to set hue value + //s->set_reg(s, 0x7D, 0xFF, 0); // Optional feature - hue setting: Hue value 0 - 255 + s->set_reg(s, 0xFF, 0x01, 0); // Select DSP bank + s->set_reg(s, 0x7C, 0xFF, 0); // Select byte 0 in register 0x7C + s->set_reg(s, 0x7D, 7, 7); // Set bit 0, 1, 2 in register 0x7D to enable saturation, contrast, brightness and hue control + } + else { + LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "SetBrightnessContrastSaturation: Failed to get control structure"); + } + + if (((_brightness != brightness) || (_contrast != contrast) || (_saturation != saturation)) && isFixedExposure) EnableAutoExposure(waitbeforepicture_org); - return result; + brightness = _brightness; + contrast = _contrast; + saturation = _saturation; + + ESP_LOGD(TAG, "brightness %d, contrast: %d, saturation %d", brightness, contrast, saturation); + + return true; } void CCamera::SetQualitySize(int qual, framesize_t resol) { - sensor_t * s = esp_camera_sensor_get(); - s->set_quality(s, qual); - s->set_framesize(s, resol); + qual = min(63, max(8, qual)); // Limit quality from 8..63 (values lower than 8 tent to be unstable) + + sensor_t * s = esp_camera_sensor_get(); + if (s) { + s->set_quality(s, qual); + s->set_framesize(s, resol); + } + else { + LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "SetQualitySize: Failed to get control structure"); + } + ActualResolution = resol; ActualQuality = qual; @@ -191,41 +224,45 @@ void CCamera::SetQualitySize(int qual, framesize_t resol) image_height = 240; image_width = 320; } - if (resol == FRAMESIZE_VGA) + else if (resol == FRAMESIZE_VGA) { image_height = 480; image_width = 640; } - } void CCamera::EnableAutoExposure(int flash_duration) { ESP_LOGD(TAG, "EnableAutoExposure"); + LEDOnOff(true); - if (flash_duration > 0) + if (flash_duration > 0) { LightOnOff(true); - const TickType_t xDelay = flash_duration / portTICK_PERIOD_MS; - vTaskDelay( xDelay ); + const TickType_t xDelay = flash_duration / portTICK_PERIOD_MS; + vTaskDelay( xDelay ); + } camera_fb_t * fb = esp_camera_fb_get(); esp_camera_fb_return(fb); fb = esp_camera_fb_get(); if (!fb) { - ESP_LOGE(TAG, "Camera Capture Failed"); LEDOnOff(false); LightOnOff(false); - LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Capture Failed (Procedure 'EnableAutoExposure') --> Reboot! " - "Check that your camera module is working and connected properly."); + LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "EnableAutoExposure: Capture Failed. " + "Check camera module and/or proper electrical connection"); //doReboot(); } esp_camera_fb_return(fb); sensor_t * s = esp_camera_sensor_get(); - s->set_gain_ctrl(s, 0); - s->set_exposure_ctrl(s, 0); - + if (s) { + s->set_gain_ctrl(s, 0); + s->set_exposure_ctrl(s, 0); + } + else { + LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "EnableAutoExposure: Failed to get control structure to set gain+exposure"); + } LEDOnOff(false); LightOnOff(false); @@ -237,22 +274,21 @@ void CCamera::EnableAutoExposure(int flash_duration) esp_err_t CCamera::CaptureToBasisImage(CImageBasis *_Image, int delay) { #ifdef DEBUG_DETAIL_ON - LogFile.WriteHeapInfo("CCamera::CaptureToBasisImage - Start"); + LogFile.WriteHeapInfo("CaptureToBasisImage - Start"); #endif _Image->EmptyImage(); //Delete previous stored raw image -> black image LEDOnOff(true); - if (delay > 0) - { + if (delay > 0) { LightOnOff(true); const TickType_t xDelay = delay / portTICK_PERIOD_MS; vTaskDelay( xDelay ); } #ifdef DEBUG_DETAIL_ON - LogFile.WriteHeapInfo("CCamera::CaptureToBasisImage - After LightOn"); + LogFile.WriteHeapInfo("CaptureToBasisImage - After LightOn"); #endif camera_fb_t * fb = esp_camera_fb_get(); @@ -262,9 +298,8 @@ esp_err_t CCamera::CaptureToBasisImage(CImageBasis *_Image, int delay) LEDOnOff(false); LightOnOff(false); - ESP_LOGE(TAG, "CaptureToBasisImage: Capture Failed"); - LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "is not working anymore (CCamera::CaptureToBasisImage) - most probably caused by a hardware problem (instablility, ...). " - "System will reboot."); + LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "is not working anymore (CaptureToBasisImage) - most probably caused " + "by a hardware problem (instablility, ...). System will reboot."); doReboot(); return ESP_FAIL; @@ -276,11 +311,16 @@ esp_err_t CCamera::CaptureToBasisImage(CImageBasis *_Image, int delay) } CImageBasis* _zwImage = new CImageBasis(); - _zwImage->LoadFromMemory(fb->buf, fb->len); + if (_zwImage) { + _zwImage->LoadFromMemory(fb->buf, fb->len); + } + else { + LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "CaptureToBasisImage: Can't allocate _zwImage"); + } esp_camera_fb_return(fb); #ifdef DEBUG_DETAIL_ON - LogFile.WriteHeapInfo("CCamera::CaptureToBasisImage - After fb_get"); + LogFile.WriteHeapInfo("CaptureToBasisImage - After fb_get"); #endif LEDOnOff(false); @@ -292,7 +332,7 @@ esp_err_t CCamera::CaptureToBasisImage(CImageBasis *_Image, int delay) // vTaskDelay( xDelay ); // wait for power to recover #ifdef DEBUG_DETAIL_ON - LogFile.WriteHeapInfo("CCamera::CaptureToBasisImage - After LoadFromMemory"); + LogFile.WriteHeapInfo("CaptureToBasisImage - After LoadFromMemory"); #endif stbi_uc* p_target; @@ -320,7 +360,7 @@ esp_err_t CCamera::CaptureToBasisImage(CImageBasis *_Image, int delay) delete _zwImage; #ifdef DEBUG_DETAIL_ON - LogFile.WriteHeapInfo("CCamera::CaptureToBasisImage - Done"); + LogFile.WriteHeapInfo("CaptureToBasisImage - Done"); #endif return ESP_OK; @@ -333,8 +373,7 @@ esp_err_t CCamera::CaptureToFile(std::string nm, int delay) LEDOnOff(true); // Switched off to save power ! - if (delay > 0) - { + if (delay > 0) { LightOnOff(true); const TickType_t xDelay = delay / portTICK_PERIOD_MS; vTaskDelay( xDelay ); @@ -344,11 +383,10 @@ esp_err_t CCamera::CaptureToFile(std::string nm, int delay) esp_camera_fb_return(fb); fb = esp_camera_fb_get(); if (!fb) { - ESP_LOGE(TAG, "CaptureToFile: Camera Capture Failed"); LEDOnOff(false); LightOnOff(false); - LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Capture Failed (CCamera::CaptureToFile) --> Reboot! " - "Check that your camera module is working and connected properly."); + LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "CaptureToFile: Capture Failed. " + "Check camera module and/or proper electrical connection"); //doReboot(); return ESP_FAIL; @@ -395,24 +433,21 @@ esp_err_t CCamera::CaptureToFile(std::string nm, int delay) } FILE * fp = fopen(nm.c_str(), "wb"); - if (fp == NULL) /* If an error occurs during the file creation */ - { - fprintf(stderr, "fopen() failed for '%s'\n", nm.c_str()); + if (fp == NULL) { // If an error occurs during the file creation + LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "CaptureToFile: Failed to open file " + nm); } - else - { + else { fwrite(buf, sizeof(uint8_t), buf_len, fp); fclose(fp); - } + } + if (converted) free(buf); esp_camera_fb_return(fb); if (delay > 0) - { LightOnOff(false); - } return ESP_OK; } @@ -420,29 +455,26 @@ esp_err_t CCamera::CaptureToFile(std::string nm, int delay) esp_err_t CCamera::CaptureToHTTP(httpd_req_t *req, int delay) { - camera_fb_t * fb = NULL; esp_err_t res = ESP_OK; size_t fb_len = 0; int64_t fr_start = esp_timer_get_time(); - LEDOnOff(true); - if (delay > 0) - { + if (delay > 0) { LightOnOff(true); const TickType_t xDelay = delay / portTICK_PERIOD_MS; vTaskDelay( xDelay ); } - - fb = esp_camera_fb_get(); + camera_fb_t *fb = esp_camera_fb_get(); esp_camera_fb_return(fb); fb = esp_camera_fb_get(); if (!fb) { - ESP_LOGE(TAG, "Camera capture failed"); LEDOnOff(false); LightOnOff(false); + LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "CaptureToFile: Capture Failed. " + "Check camera module and/or proper electrical connection"); httpd_resp_send_500(req); // doReboot(); @@ -482,9 +514,7 @@ esp_err_t CCamera::CaptureToHTTP(httpd_req_t *req, int delay) ESP_LOGI(TAG, "JPG: %uKB %ums", (uint32_t)(fb_len/1024), (uint32_t)((fr_end - fr_start)/1000)); if (delay > 0) - { LightOnOff(false); - } return res; } @@ -494,19 +524,18 @@ void CCamera::LightOnOff(bool status) { GpioHandler* gpioHandler = gpio_handler_get(); if ((gpioHandler != NULL) && (gpioHandler->isEnabled())) { - ESP_LOGD(TAG, "Use gpioHandler flashLigh"); + ESP_LOGD(TAG, "Use gpioHandler to trigger flashlight"); gpioHandler->flashLightEnable(status); - } else { + } + else { #ifdef USE_PWM_LEDFLASH - if (status) - { + if (status) { ESP_LOGD(TAG, "Internal Flash-LED turn on with PWM %d", led_intensity); ESP_ERROR_CHECK(ledc_set_duty(LEDC_MODE, LEDC_CHANNEL, led_intensity)); // Update duty to apply the new value ESP_ERROR_CHECK(ledc_update_duty(LEDC_MODE, LEDC_CHANNEL)); } - else - { + else { ESP_LOGD(TAG, "Internal Flash-LED turn off PWM"); ESP_ERROR_CHECK(ledc_set_duty(LEDC_MODE, LEDC_CHANNEL, 0)); ESP_ERROR_CHECK(ledc_update_duty(LEDC_MODE, LEDC_CHANNEL)); @@ -555,33 +584,33 @@ void CCamera::GetCameraParameter(httpd_req_t *req, int &qual, framesize_t &resol ESP_LOGD(TAG, "Query: %s", _query); if (httpd_query_key_value(_query, "size", _size, 10) == ESP_OK) { -#ifdef DEBUG_DETAIL_ON + #ifdef DEBUG_DETAIL_ON ESP_LOGD(TAG, "Size: %s", _size); -#endif + #endif if (strcmp(_size, "QVGA") == 0) resol = FRAMESIZE_QVGA; // 320x240 - if (strcmp(_size, "VGA") == 0) + else if (strcmp(_size, "VGA") == 0) resol = FRAMESIZE_VGA; // 640x480 - if (strcmp(_size, "SVGA") == 0) + else if (strcmp(_size, "SVGA") == 0) resol = FRAMESIZE_SVGA; // 800x600 - if (strcmp(_size, "XGA") == 0) + else if (strcmp(_size, "XGA") == 0) resol = FRAMESIZE_XGA; // 1024x768 - if (strcmp(_size, "SXGA") == 0) + else if (strcmp(_size, "SXGA") == 0) resol = FRAMESIZE_SXGA; // 1280x1024 - if (strcmp(_size, "UXGA") == 0) + else if (strcmp(_size, "UXGA") == 0) resol = FRAMESIZE_UXGA; // 1600x1200 } if (httpd_query_key_value(_query, "quality", _qual, 10) == ESP_OK) { -#ifdef DEBUG_DETAIL_ON + #ifdef DEBUG_DETAIL_ON ESP_LOGD(TAG, "Quality: %s", _qual); -#endif + #endif qual = atoi(_qual); - if (qual > 63) + if (qual > 63) // Limit to max. 63 qual = 63; - if (qual < 0) - qual = 0; + else if (qual < 8) // Limit to min. 8 + qual = 8; } } } @@ -591,28 +620,29 @@ framesize_t CCamera::TextToFramesize(const char * _size) { if (strcmp(_size, "QVGA") == 0) return FRAMESIZE_QVGA; // 320x240 - if (strcmp(_size, "VGA") == 0) + else if (strcmp(_size, "VGA") == 0) return FRAMESIZE_VGA; // 640x480 - if (strcmp(_size, "SVGA") == 0) + else if (strcmp(_size, "SVGA") == 0) return FRAMESIZE_SVGA; // 800x600 - if (strcmp(_size, "XGA") == 0) + else if (strcmp(_size, "XGA") == 0) return FRAMESIZE_XGA; // 1024x768 - if (strcmp(_size, "SXGA") == 0) + else if (strcmp(_size, "SXGA") == 0) return FRAMESIZE_SXGA; // 1280x1024 - if (strcmp(_size, "UXGA") == 0) - return FRAMESIZE_UXGA; // 1600x1200 + else if (strcmp(_size, "UXGA") == 0) + return FRAMESIZE_UXGA; // 1600x1200 + return ActualResolution; } CCamera::CCamera() { -#ifdef DEBUG_DETAIL_ON - ESP_LOGD(TAG, "CreateClassCamera"); -#endif - brightness = -5; - contrast = -5; - saturation = -5; + #ifdef DEBUG_DETAIL_ON + ESP_LOGD(TAG, "CreateClassCamera"); + #endif + brightness = 0; + contrast = 0; + saturation = 0; isFixedExposure = false; ledc_init(); diff --git a/sd-card/html/edit_config_param.html b/sd-card/html/edit_config_param.html index be7c347a..3158f816 100644 --- a/sd-card/html/edit_config_param.html +++ b/sd-card/html/edit_config_param.html @@ -158,11 +158,12 @@ textarea { ImageQuality - + - Quality index for picture (default = "12" - "0" high ... "63" low)
- Remark: values smaller than 12 can result in a reboot, as the bigger sized JPEG might not fit in the available RAM! + Image quality index (default = 12)
+ Input range: 8 [highest quality] ... 63 [lowest quality]
+ Remark: Value < 12 could result in system instabilities! @@ -201,7 +202,8 @@ textarea { - Image Brightness (-2 .. 2 - default = "0") + Image brightness (default = 0)
+ Input range: -2 ... 2 @@ -213,8 +215,8 @@ textarea { - Image Contrast (-2 .. 2 - default = "0")
- Remark: camera driver is not fully supporting this setting yet (no impact on image) + Image contrast (default = 0)
+ Input range: -2 ... 2 @@ -226,8 +228,8 @@ textarea { - Image Saturation (-2 .. 2 - default = "0")
- Remark: camera driver is not fully supporting this setting yet (no impact on image) + Image saturation (default = 0)
+ Input range: -2 ... 2 diff --git a/sd-card/html/edit_reference.html b/sd-card/html/edit_reference.html index 951ffa12..c5d0cbbc 100644 --- a/sd-card/html/edit_reference.html +++ b/sd-card/html/edit_reference.html @@ -129,7 +129,7 @@ table { _contrast = document.getElementById("MakeImage_Contrast_value1").value; _saturation = document.getElementById("MakeImage_Saturation_value1").value; url = getDomainname() + "/editflow?task=test_take&bri=" + _brightness; - url = url + "&con=" + _saturation + "&sat=" + _saturation + "&int=" + _intensity; + url = url + "&con=" + _contrast + "&sat=" + _saturation + "&int=" + _intensity; } else { From 70332fe142a20f29fc1bf34902b20375f2a937e3 Mon Sep 17 00:00:00 2001 From: jomjol <30766535+jomjol@users.noreply.github.com> Date: Mon, 20 Feb 2023 20:03:39 +0100 Subject: [PATCH 22/31] Update tflite --- Changelog.md | 1 + sd-card/config/dig-cont_0610_s3.tflite | Bin 0 -> 1200904 bytes sd-card/config/dig-cont_0610_s3_q.tflite | Bin 0 -> 315504 bytes 3 files changed, 1 insertion(+) create mode 100644 sd-card/config/dig-cont_0610_s3.tflite create mode 100644 sd-card/config/dig-cont_0610_s3_q.tflite diff --git a/Changelog.md b/Changelog.md index 775533f8..227fc5a2 100644 --- a/Changelog.md +++ b/Changelog.md @@ -7,6 +7,7 @@ #### Added - Additional interface to InfluxDB Version 2 upwards +- Updated the Hybrid CNN network to `dig-cont_0610_s3` #### Changed diff --git a/sd-card/config/dig-cont_0610_s3.tflite b/sd-card/config/dig-cont_0610_s3.tflite new file mode 100644 index 0000000000000000000000000000000000000000..ecc71a882fe5d6c33981f919edfe87f3e0e708d3 GIT binary patch literal 1200904 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ⅇYSxX{tEdkb3 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

Only InfluxDB v1.x is supported as of now
@@ -767,8 +789,6 @@ textarea { - -

@@ -860,16 +880,6 @@ textarea { - - - - - - - - - -

@@ -1392,10 +1402,10 @@ textarea { - Interval + Interval - + Interval in which the number(s) are read (in minutes). If a digitalization round takes longer than this interval, the next run gets postponed until the current run completes. @@ -1422,10 +1432,10 @@ textarea { - DataLogRetentionInDays + DataFilesRetention - + Time to keep the data files (in days - "0" = forever) @@ -1437,10 +1447,10 @@ textarea { - Logfile Log Level + Logfile Log Level - @@ -1453,10 +1463,10 @@ textarea { - LogfileRetentionInDays + LogfilesRetention - + Time to keep the log files (in days - "0" = forever) @@ -1506,15 +1516,15 @@ textarea { Hostname for server - will be transfered to wlan.ini at next startup) - + - - + + - + - WLAN Mesh Parameter: Threashold for RSSI value to check for start switching access point in a mesh system. + WLAN Mesh Parameter: Threshold for RSSI value to check for start switching access point in a mesh system. Possible values: -100 to 0, 0 = disabled - Value will be transfered to wlan.ini at next startup) @@ -1613,8 +1623,14 @@ function getParameterByName(name, url = window.location.href) { } function WriteParameter(_param, _category, _cat, _name, _optional, _number = -1){ - - let anzpara = _param[_cat][_name].anzParam; + let anzpara; + try { + anzpara = _param[_cat][_name].anzParam; + } + catch (error) { + firework.launch("Parameter '" + _name + "' in category '" + _cat + "' is unknown!", 'danger', 30000); + return; + } if (_number > -1) { if ((NUMBERS[_number] == undefined) || (NUMBERS[_number][_cat] == undefined) || (NUMBERS[_number][_cat][_name] == undefined)) @@ -1891,9 +1907,9 @@ function UpdateInputIndividual(sel) ReadParameter(param, "PostProcessing", "AnalogDigitalTransitionStart", true, NUNBERSAkt) ReadParameter(param, "PostProcessing", "MaxRateValue", true, NUNBERSAkt) ReadParameter(param, "PostProcessing", "MaxRateType", true, NUNBERSAkt) - ReadParameter(param, "PostProcessing", "ExtendedResolution", true, NUNBERSAkt) - ReadParameter(param, "PostProcessing", "IgnoreLeadingNaN", true, NUNBERSAkt) - ReadParameter(param, "PostProcessing", "AllowNegativeRates", true, NUNBERSAkt) + ReadParameter(param, "PostProcessing", "ExtendedResolution", false, NUNBERSAkt) + ReadParameter(param, "PostProcessing", "IgnoreLeadingNaN", false, NUNBERSAkt) + ReadParameter(param, "PostProcessing", "AllowNegativeRates", false, NUNBERSAkt) ReadParameter(param, "InfluxDBv2", "Fieldname", true, NUNBERSAkt) } @@ -1903,9 +1919,9 @@ function UpdateInputIndividual(sel) WriteParameter(param, category, "PostProcessing", "AnalogDigitalTransitionStart", true, NUNBERSAkt); WriteParameter(param, category, "PostProcessing", "MaxRateValue", true, NUNBERSAkt); WriteParameter(param, category, "PostProcessing", "MaxRateType", true, NUNBERSAkt); - WriteParameter(param, category, "PostProcessing", "ExtendedResolution", true, NUNBERSAkt); - WriteParameter(param, category, "PostProcessing", "IgnoreLeadingNaN", true, NUNBERSAkt); - WriteParameter(param, category, "PostProcessing", "AllowNegativeRates", true, NUNBERSAkt); + WriteParameter(param, category, "PostProcessing", "ExtendedResolution", false, NUNBERSAkt); + WriteParameter(param, category, "PostProcessing", "IgnoreLeadingNaN", false, NUNBERSAkt); + WriteParameter(param, category, "PostProcessing", "AllowNegativeRates", false, NUNBERSAkt); WriteParameter(param, category, "InfluxDBv2", "Fieldname", true, NUNBERSAkt); } @@ -1918,42 +1934,42 @@ function UpdateInput() { document.getElementById("Category_InfluxDBv2_enabled").checked = category["InfluxDBv2"]["enabled"]; setVisible("GPIO_item", category["GPIO"]["enabled"]); - WriteParameter(param, category, "MakeImage", "LogImageLocation", true); - WriteParameter(param, category, "MakeImage", "LogfileRetentionInDays", true); - WriteParameter(param, category, "MakeImage", "Demo", true); - WriteParameter(param, category, "MakeImage", "WaitBeforeTakingPicture", false); - WriteParameter(param, category, "MakeImage", "ImageQuality", false); - WriteParameter(param, category, "MakeImage", "Brightness", false); - WriteParameter(param, category, "MakeImage", "Contrast", false); - WriteParameter(param, category, "MakeImage", "Saturation", false); - WriteParameter(param, category, "MakeImage", "LEDIntensity", false); - WriteParameter(param, category, "MakeImage", "ImageSize", false); - WriteParameter(param, category, "MakeImage", "FixedExposure", false); + WriteParameter(param, category, "TakeImage", "RawImagesLocation", true); + WriteParameter(param, category, "TakeImage", "RawImagesRetention", true); + WriteParameter(param, category, "TakeImage", "Demo", false); + WriteParameter(param, category, "TakeImage", "WaitBeforeTakingPicture", false); + WriteParameter(param, category, "TakeImage", "ImageQuality", false); + WriteParameter(param, category, "TakeImage", "Brightness", false); + WriteParameter(param, category, "TakeImage", "Contrast", false); + WriteParameter(param, category, "TakeImage", "Saturation", false); + WriteParameter(param, category, "TakeImage", "LEDIntensity", false); + WriteParameter(param, category, "TakeImage", "ImageSize", false); + WriteParameter(param, category, "TakeImage", "FixedExposure", false); WriteParameter(param, category, "Alignment", "SearchFieldX", false); WriteParameter(param, category, "Alignment", "SearchFieldY", false); WriteParameter(param, category, "Alignment", "AlignmentAlgo", true); WriteParameter(param, category, "Digits", "CNNGoodThreshold", true); - WriteParameter(param, category, "Digits", "LogImageLocation", true); - WriteParameter(param, category, "Digits", "LogfileRetentionInDays", true); + WriteParameter(param, category, "Digits", "ROIImagesLocation", true); + WriteParameter(param, category, "Digits", "ROIImagesRetention", true); - WriteParameter(param, category, "Analog", "LogImageLocation", true); - WriteParameter(param, category, "Analog", "LogfileRetentionInDays", true); + WriteParameter(param, category, "Analog", "ROIImagesLocation", true); + WriteParameter(param, category, "Analog", "ROIImagesRetention", true); - WriteParameter(param, category, "PostProcessing", "PreValueUse", true); + WriteParameter(param, category, "PostProcessing", "PreValueUse", false); WriteParameter(param, category, "PostProcessing", "PreValueAgeStartup", true); // WriteParameter(param, category, "PostProcessing", "AllowNegativeRates", true); - WriteParameter(param, category, "PostProcessing", "ErrorMessage", true); - WriteParameter(param, category, "PostProcessing", "CheckDigitIncreaseConsistency", true); + WriteParameter(param, category, "PostProcessing", "ErrorMessage", false); + WriteParameter(param, category, "PostProcessing", "CheckDigitIncreaseConsistency", false); WriteParameter(param, category, "MQTT", "Uri", true); WriteParameter(param, category, "MQTT", "MainTopic", true); WriteParameter(param, category, "MQTT", "ClientID", true); WriteParameter(param, category, "MQTT", "user", true); WriteParameter(param, category, "MQTT", "password", true); - WriteParameter(param, category, "MQTT", "SetRetainFlag", true); - WriteParameter(param, category, "MQTT", "HomeassistantDiscovery", true); + WriteParameter(param, category, "MQTT", "RetainMessages", false); + WriteParameter(param, category, "MQTT", "HomeassistantDiscovery", false); WriteParameter(param, category, "MQTT", "MeterType", true); WriteParameter(param, category, "InfluxDB", "Uri", true); @@ -1980,18 +1996,18 @@ function UpdateInput() { WriteParameter(param, category, "GPIO", "LEDColor", false); WriteParameter(param, category, "AutoTimer", "AutoStart", false); - WriteParameter(param, category, "AutoTimer", "Intervall", false); + WriteParameter(param, category, "AutoTimer", "Interval", false); WriteParameter(param, category, "DataLogging", "DataLogActive", false); - WriteParameter(param, category, "DataLogging", "DataLogRetentionInDays", false); + WriteParameter(param, category, "DataLogging", "DataFilesRetention", false); - WriteParameter(param, category, "Debug", "Logfile", false); - WriteParameter(param, category, "Debug", "LogfileRetentionInDays", false); + WriteParameter(param, category, "Debug", "LogLevel", false); + WriteParameter(param, category, "Debug", "LogfilesRetention", false); WriteParameter(param, category, "System", "TimeZone", true); WriteParameter(param, category, "System", "Hostname", true); WriteParameter(param, category, "System", "TimeServer", true); - WriteParameter(param, category, "System", "RSSIThreashold", true); + WriteParameter(param, category, "System", "RSSIThreshold", true); WriteModelFiles(); } @@ -2047,17 +2063,17 @@ function ReadParameterAll() category["InfluxDBv2"]["enabled"] = document.getElementById("Category_InfluxDBv2_enabled").checked; category["GPIO"]["enabled"] = document.getElementById("Category_GPIO_enabled").checked; - ReadParameter(param, "MakeImage", "LogImageLocation", true); - ReadParameter(param, "MakeImage", "LogfileRetentionInDays", true); - ReadParameter(param, "MakeImage", "Demo", true); - ReadParameter(param, "MakeImage", "WaitBeforeTakingPicture", false); - ReadParameter(param, "MakeImage", "ImageQuality", false); - ReadParameter(param, "MakeImage", "Brightness", false); - ReadParameter(param, "MakeImage", "Contrast", false); - ReadParameter(param, "MakeImage", "Saturation", false); - ReadParameter(param, "MakeImage", "LEDIntensity", false); - ReadParameter(param, "MakeImage", "ImageSize", false); - ReadParameter(param, "MakeImage", "FixedExposure", false); + ReadParameter(param, "TakeImage", "RawImagesLocation", true); + ReadParameter(param, "TakeImage", "RawImagesRetention", true); + ReadParameter(param, "TakeImage", "Demo", false); + ReadParameter(param, "TakeImage", "WaitBeforeTakingPicture", false); + ReadParameter(param, "TakeImage", "ImageQuality", false); + ReadParameter(param, "TakeImage", "Brightness", false); + ReadParameter(param, "TakeImage", "Contrast", false); + ReadParameter(param, "TakeImage", "Saturation", false); + ReadParameter(param, "TakeImage", "LEDIntensity", false); + ReadParameter(param, "TakeImage", "ImageSize", false); + ReadParameter(param, "TakeImage", "FixedExposure", false); ReadParameter(param, "Alignment", "SearchFieldX", false); ReadParameter(param, "Alignment", "SearchFieldY", false); @@ -2065,25 +2081,25 @@ function ReadParameterAll() ReadParameter(param, "Digits", "Model", false); ReadParameter(param, "Digits", "CNNGoodThreshold", true); - ReadParameter(param, "Digits", "LogImageLocation", true); - ReadParameter(param, "Digits", "LogfileRetentionInDays", true); + ReadParameter(param, "Digits", "ROIImagesLocation", true); + ReadParameter(param, "Digits", "ROIImagesRetention", true); ReadParameter(param, "Analog", "Model", false); - ReadParameter(param, "Analog", "LogImageLocation", true); - ReadParameter(param, "Analog", "LogfileRetentionInDays", true); + ReadParameter(param, "Analog", "ROIImagesLocation", true); + ReadParameter(param, "Analog", "ROIImagesRetention", true); - ReadParameter(param, "PostProcessing", "PreValueUse", true); - ReadParameter(param, "PostProcessing", "PreValueAgeStartup", true); - ReadParameter(param, "PostProcessing", "ErrorMessage", true); - ReadParameter(param, "PostProcessing", "CheckDigitIncreaseConsistency", true); + ReadParameter(param, "PostProcessing", "PreValueUse", false); + ReadParameter(param, "PostProcessing", "PreValueAgeStartup", true); + ReadParameter(param, "PostProcessing", "ErrorMessage", false); + ReadParameter(param, "PostProcessing", "CheckDigitIncreaseConsistency", false); ReadParameter(param, "MQTT", "Uri", true); ReadParameter(param, "MQTT", "MainTopic", true); ReadParameter(param, "MQTT", "ClientID", true); ReadParameter(param, "MQTT", "user", true); ReadParameter(param, "MQTT", "password", true); - ReadParameter(param, "MQTT", "SetRetainFlag", true); - ReadParameter(param, "MQTT", "HomeassistantDiscovery", true); + ReadParameter(param, "MQTT", "RetainMessages", false); + ReadParameter(param, "MQTT", "HomeassistantDiscovery", false); ReadParameter(param, "MQTT", "MeterType", true); ReadParameter(param, "InfluxDB", "Uri", true); @@ -2117,18 +2133,18 @@ function ReadParameterAll() param["GPIO"]["LEDColor"]["found"] = true; ReadParameter(param, "AutoTimer", "AutoStart", false); - ReadParameter(param, "AutoTimer", "Intervall", false); + ReadParameter(param, "AutoTimer", "Interval", false); ReadParameter(param, "DataLogging", "DataLogActive", false); - ReadParameter(param, "DataLogging", "DataLogRetentionInDays", false); + ReadParameter(param, "DataLogging", "DataFilesRetention", false); - ReadParameter(param, "Debug", "Logfile", false); - ReadParameter(param, "Debug", "LogfileRetentionInDays", false); + ReadParameter(param, "Debug", "LogLevel", false); + ReadParameter(param, "Debug", "LogfilesRetention", false); ReadParameter(param, "System", "TimeZone", true); ReadParameter(param, "System", "Hostname", true); ReadParameter(param, "System", "TimeServer", true); - ReadParameter(param, "System", "RSSIThreashold", true); + ReadParameter(param, "System", "RSSIThreshold", true); var sel = document.getElementById("Numbers_value1"); UpdateInputIndividual(sel); diff --git a/sd-card/html/edit_reference.html b/sd-card/html/edit_reference.html index 9a31b606..2835614f 100644 --- a/sd-card/html/edit_reference.html +++ b/sd-card/html/edit_reference.html @@ -53,8 +53,8 @@ table { - LEDIntensity: - + LEDIntensity: + @@ -62,8 +62,8 @@ table { - Brightness: - + Brightness: + @@ -71,16 +71,16 @@ table { Degrees - Contrast - + Contrast + Degrees - Saturation - + Saturation + @@ -123,13 +123,13 @@ table { function doTake(){ var xhttp = new XMLHttpRequest(); - if (param["MakeImage"]["Brightness"].found && param["MakeImage"]["Brightness"].enabled) + if (param["TakeImage"]["Brightness"].found && param["TakeImage"]["Brightness"].enabled) { - _intensity = document.getElementById("MakeImage_LEDIntensity_value1").value; + _intensity = document.getElementById("TakeImage_LEDIntensity_value1").value; if (_intensity == "") _intensity = "50"; - _brightness = document.getElementById("MakeImage_Brightness_value1").value; - _contrast = document.getElementById("MakeImage_Contrast_value1").value; - _saturation = document.getElementById("MakeImage_Saturation_value1").value; + _brightness = document.getElementById("TakeImage_Brightness_value1").value; + _contrast = document.getElementById("TakeImage_Contrast_value1").value; + _saturation = document.getElementById("TakeImage_Saturation_value1").value; url = getDomainname() + "/editflow?task=test_take&bri=" + _brightness; url = url + "&con=" + _contrast + "&sat=" + _saturation + "&int=" + _intensity; } @@ -168,24 +168,24 @@ table { document.getElementById("labelflip").style = "color:lightgrey;"; } - if (param["MakeImage"]["Brightness"].found && param["MakeImage"]["Brightness"].enabled) + if (param["TakeImage"]["Brightness"].found && param["TakeImage"]["Brightness"].enabled) { - document.getElementById("MakeImage_Brightness_value1").disabled = false; - document.getElementById("MakeImage_Contrast_value1").disabled = false; - document.getElementById("MakeImage_Saturation_value1").disabled = false; - document.getElementById("MakeImage_LEDIntensity_value1").disabled = false; + document.getElementById("TakeImage_Brightness_value1").disabled = false; + document.getElementById("TakeImage_Contrast_value1").disabled = false; + document.getElementById("TakeImage_Saturation_value1").disabled = false; + document.getElementById("TakeImage_LEDIntensity_value1").disabled = false; } else { - document.getElementById("MakeImage_Brightness_value1").type = "hidden"; - document.getElementById("MakeImage_Brightness_text").style.visibility = "hidden"; + document.getElementById("TakeImage_Brightness_value1").type = "hidden"; + document.getElementById("TakeImage_Brightness_text").style.visibility = "hidden"; } -// if (param["MakeImage"]["Saturation"].found) -// document.getElementById("MakeImage_Saturation_value1").disabled = false; -// if (param["MakeImage"]["Contrast"].found) -// document.getElementById("MakeImage_Contrast_value1").disabled = false; +// if (param["TakeImage"]["Saturation"].found) +// document.getElementById("TakeImage_Saturation_value1").disabled = false; +// if (param["TakeImage"]["Contrast"].found) +// document.getElementById("TakeImage_Contrast_value1").disabled = false; isActReference = false; loadCanvas(url); @@ -207,16 +207,16 @@ table { document.getElementById("prerotateangle").disabled = true; document.getElementById("updatereferenceimage").disabled = true; document.getElementById("take").disabled = true; - document.getElementById("MakeImage_Brightness_value1").disabled = true; - document.getElementById("MakeImage_Saturation_value1").disabled = true; - document.getElementById("MakeImage_Contrast_value1").disabled = true; - document.getElementById("MakeImage_LEDIntensity_value1").disabled = true; + document.getElementById("TakeImage_Brightness_value1").disabled = true; + document.getElementById("TakeImage_Saturation_value1").disabled = true; + document.getElementById("TakeImage_Contrast_value1").disabled = true; + document.getElementById("TakeImage_LEDIntensity_value1").disabled = true; document.getElementById("mirror").disabled = false; document.getElementById("flip").disabled = false; - if (!(param["MakeImage"]["Brightness"].found)) + if (!(param["TakeImage"]["Brightness"].found)) { - document.getElementById("MakeImage_Brightness_value1").type = "hidden"; - document.getElementById("MakeImage_Brightness_text").style.visibility = "hidden"; + document.getElementById("TakeImage_Brightness_value1").type = "hidden"; + document.getElementById("TakeImage_Brightness_text").style.visibility = "hidden"; } @@ -255,12 +255,12 @@ table { else param["Alignment"]["FlipImageSize"].value1 = "false"; - if (param["MakeImage"]["Brightness"].found && param["MakeImage"]["Brightness"].enabled) + if (param["TakeImage"]["Brightness"].found && param["TakeImage"]["Brightness"].enabled) { - ReadParameter(param, "MakeImage", "Brightness", false); - ReadParameter(param, "MakeImage", "Contrast", false); - ReadParameter(param, "MakeImage", "Saturation", false); - ReadParameter(param, "MakeImage", "LEDIntensity", false); + ReadParameter(param, "TakeImage", "Brightness", false); + ReadParameter(param, "TakeImage", "Contrast", false); + ReadParameter(param, "TakeImage", "Saturation", false); + ReadParameter(param, "TakeImage", "LEDIntensity", false); } var canvas = document.getElementById("canvas"); @@ -309,30 +309,30 @@ table { ParseConfig(); param = getConfigParameters(); - param["MakeImage"]["LEDIntensity"]["enabled"] = true; - param["MakeImage"]["Brightness"]["enabled"] = true; - param["MakeImage"]["Contrast"]["enabled"] = true; - param["MakeImage"]["Saturation"]["enabled"] = true; + param["TakeImage"]["LEDIntensity"]["enabled"] = true; + param["TakeImage"]["Brightness"]["enabled"] = true; + param["TakeImage"]["Contrast"]["enabled"] = true; + param["TakeImage"]["Saturation"]["enabled"] = true; - if (!param["MakeImage"]["LEDIntensity"]["found"]) + if (!param["TakeImage"]["LEDIntensity"]["found"]) { - param["MakeImage"]["LEDIntensity"]["found"] = true; - param["MakeImage"]["LEDIntensity"]["value1"] = "50"; + param["TakeImage"]["LEDIntensity"]["found"] = true; + param["TakeImage"]["LEDIntensity"]["value1"] = "50"; } - if (!param["MakeImage"]["Brightness"]["found"]) + if (!param["TakeImage"]["Brightness"]["found"]) { - param["MakeImage"]["Brightness"]["found"] = true; - param["MakeImage"]["Brightness"]["value1"] = "0"; + param["TakeImage"]["Brightness"]["found"] = true; + param["TakeImage"]["Brightness"]["value1"] = "0"; } - if (!param["MakeImage"]["Contrast"]["found"]) + if (!param["TakeImage"]["Contrast"]["found"]) { - param["MakeImage"]["Contrast"]["found"] = true; - param["MakeImage"]["Contrast"]["value1"] = "0"; + param["TakeImage"]["Contrast"]["found"] = true; + param["TakeImage"]["Contrast"]["value1"] = "0"; } - if (!param["MakeImage"]["Saturation"]["found"]) + if (!param["TakeImage"]["Saturation"]["found"]) { - param["MakeImage"]["Saturation"]["found"] = true; - param["MakeImage"]["Saturation"]["value1"] = "0"; + param["TakeImage"]["Saturation"]["found"] = true; + param["TakeImage"]["Saturation"]["value1"] = "0"; } UpdateInput(); @@ -340,10 +340,10 @@ table { } function UpdateInput() { - WriteParameter(param, category, "MakeImage", "Brightness", false); - WriteParameter(param, category, "MakeImage", "Contrast", false); - WriteParameter(param, category, "MakeImage", "Saturation", false); - WriteParameter(param, category, "MakeImage", "LEDIntensity", false); + WriteParameter(param, category, "TakeImage", "Brightness", false); + WriteParameter(param, category, "TakeImage", "Contrast", false); + WriteParameter(param, category, "TakeImage", "Saturation", false); + WriteParameter(param, category, "TakeImage", "LEDIntensity", false); } diff --git a/sd-card/html/readconfigparam.js b/sd-card/html/readconfigparam.js index b764a282..4990c944 100644 --- a/sd-card/html/readconfigparam.js +++ b/sd-card/html/readconfigparam.js @@ -105,14 +105,14 @@ function ParseConfig() { param = new Object(); category = new Object(); - var catname = "MakeImage"; + var catname = "TakeImage"; category[catname] = new Object(); category[catname]["enabled"] = false; category[catname]["found"] = false; param[catname] = new Object(); - ParamAddValue(param, catname, "LogImageLocation"); + ParamAddValue(param, catname, "RawImagesLocation"); ParamAddValue(param, catname, "WaitBeforeTakingPicture"); - ParamAddValue(param, catname, "LogfileRetentionInDays"); + ParamAddValue(param, catname, "RawImagesRetention"); ParamAddValue(param, catname, "Demo"); ParamAddValue(param, catname, "Brightness"); ParamAddValue(param, catname, "Contrast"); @@ -141,8 +141,8 @@ function ParseConfig() { param[catname] = new Object(); ParamAddValue(param, catname, "Model"); ParamAddValue(param, catname, "CNNGoodThreshold", 1); - ParamAddValue(param, catname, "LogImageLocation"); - ParamAddValue(param, catname, "LogfileRetentionInDays"); + ParamAddValue(param, catname, "ROIImagesLocation"); + ParamAddValue(param, catname, "ROIImagesRetention"); var catname = "Analog"; category[catname] = new Object(); @@ -150,8 +150,8 @@ function ParseConfig() { category[catname]["found"] = false; param[catname] = new Object(); ParamAddValue(param, catname, "Model"); - ParamAddValue(param, catname, "LogImageLocation"); - ParamAddValue(param, catname, "LogfileRetentionInDays"); + ParamAddValue(param, catname, "ROIImagesLocation"); + ParamAddValue(param, catname, "ROIImagesRetention"); var catname = "PostProcessing"; category[catname] = new Object(); @@ -181,7 +181,7 @@ function ParseConfig() { ParamAddValue(param, catname, "ClientID"); ParamAddValue(param, catname, "user"); ParamAddValue(param, catname, "password"); - ParamAddValue(param, catname, "SetRetainFlag"); + ParamAddValue(param, catname, "RetainMessages"); ParamAddValue(param, catname, "HomeassistantDiscovery"); ParamAddValue(param, catname, "MeterType"); @@ -236,7 +236,7 @@ function ParseConfig() { category[catname]["found"] = false; param[catname] = new Object(); ParamAddValue(param, catname, "AutoStart"); - ParamAddValue(param, catname, "Intervall"); + ParamAddValue(param, catname, "Interval"); var catname = "DataLogging"; category[catname] = new Object(); @@ -244,15 +244,15 @@ function ParseConfig() { category[catname]["found"] = false; param[catname] = new Object(); ParamAddValue(param, catname, "DataLogActive"); - ParamAddValue(param, catname, "DataLogRetentionInDays"); + ParamAddValue(param, catname, "DataFilesRetention"); var catname = "Debug"; category[catname] = new Object(); category[catname]["enabled"] = false; category[catname]["found"] = false; param[catname] = new Object(); - ParamAddValue(param, catname, "Logfile"); - ParamAddValue(param, catname, "LogfileRetentionInDays"); + ParamAddValue(param, catname, "LogLevel"); + ParamAddValue(param, catname, "LogfilesRetention"); var catname = "System"; category[catname] = new Object(); @@ -261,9 +261,8 @@ function ParseConfig() { param[catname] = new Object(); ParamAddValue(param, catname, "TimeZone"); ParamAddValue(param, catname, "TimeServer"); - ParamAddValue(param, catname, "AutoAdjustSummertime"); ParamAddValue(param, catname, "Hostname"); - ParamAddValue(param, catname, "RSSIThreashold"); + ParamAddValue(param, catname, "RSSIThreshold"); ParamAddValue(param, catname, "SetupMode"); @@ -285,22 +284,7 @@ function ParseConfig() { aktline++; } - - // Make the downward compatiblity with MQTT (Maintopic --> topic) - if (param["MQTT"]["Topic"]["found"] == true && param["MQTT"]["MainTopic"]["found"] == false) - { - param["MQTT"]["MainTopic"] = param["MQTT"]["Topic"] - } - delete param["MQTT"]["Topic"] // Dient nur der Downwardskompatibilität - - - if (param["Debug"]["Logfile"]["value1"] == "false" || param["Debug"]["Logfile"]["value1"] == "true") - { - param["Debug"]["Logfile"]["value1"] = "2"; - } - - - // Make the downward compatiblity with MQTT (Maintopic --> topic) + // Make the downward compatiblity if (category["DataLogging"]["found"] == false) { category["DataLogging"]["found"] = true; @@ -310,9 +294,9 @@ function ParseConfig() { param["DataLogging"]["DataLogActive"]["enabled"] = true; param["DataLogging"]["DataLogActive"]["value1"] = "true"; - param["DataLogging"]["DataLogRetentionInDays"]["found"] = true; - param["DataLogging"]["DataLogRetentionInDays"]["enabled"] = true; - param["DataLogging"]["DataLogRetentionInDays"]["value1"] = "3"; + param["DataLogging"]["DataFilesRetention"]["found"] = true; + param["DataLogging"]["DataFilesRetention"]["enabled"] = true; + param["DataLogging"]["DataFilesRetention"]["value1"] = "3"; } if (category["DataLogging"]["enabled"] == false) @@ -325,11 +309,11 @@ function ParseConfig() { param["DataLogging"]["DataLogActive"]["value1"] = "true"; } - if (param["DataLogging"]["DataLogRetentionInDays"]["enabled"] == false && param["DataLogging"]["DataLogRetentionInDays"]["value1"] == "") + if (param["DataLogging"]["DataFilesRetention"]["enabled"] == false && param["DataLogging"]["DataFilesRetention"]["value1"] == "") { - param["DataLogging"]["DataLogRetentionInDays"]["found"] = true; - param["DataLogging"]["DataLogRetentionInDays"]["enabled"] = true; - param["DataLogging"]["DataLogRetentionInDays"]["value1"] = "3"; + param["DataLogging"]["DataFilesRetention"]["found"] = true; + param["DataLogging"]["DataFilesRetention"]["enabled"] = true; + param["DataLogging"]["DataFilesRetention"]["value1"] = "3"; } } From 3f62abf87895a0488f76eeec6068e7410c8d9320 Mon Sep 17 00:00:00 2001 From: CaCO3 Date: Wed, 22 Feb 2023 09:42:25 +0100 Subject: [PATCH 27/31] add missing config.ini entries for InfluxDBv2 --- sd-card/config/config.ini | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/sd-card/config/config.ini b/sd-card/config/config.ini index 5c7368b1..ec013c60 100644 --- a/sd-card/config/config.ini +++ b/sd-card/config/config.ini @@ -70,6 +70,14 @@ HomeassistantDiscovery = false ;user = undefined ;password = undefined +;[InfluxDBv2] +;Uri = undefined +;Database = +;Measurement = undefined +;Org = undefined +;token = undefined +;main.fieldname = undefined + ;[GPIO] ;MainTopicMQTT = wasserzaehler/GPIO ;IO0 = input disabled 10 false false From 23d2ae627d14843e5cc40ea0642c2905fdb2363e Mon Sep 17 00:00:00 2001 From: CaCO3 Date: Wed, 22 Feb 2023 11:33:44 +0100 Subject: [PATCH 28/31] Update config.ini --- sd-card/config/config.ini | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sd-card/config/config.ini b/sd-card/config/config.ini index ec013c60..f703dd60 100644 --- a/sd-card/config/config.ini +++ b/sd-card/config/config.ini @@ -65,18 +65,18 @@ HomeassistantDiscovery = false ;[InfluxDB] ;Uri = undefined -;Database = +;Database = undefined ;Measurement = undefined ;user = undefined ;password = undefined ;[InfluxDBv2] ;Uri = undefined -;Database = +;Database = undefined ;Measurement = undefined ;Org = undefined -;token = undefined -;main.fieldname = undefined +;Token = undefined +;main.Fieldname = undefined ;[GPIO] ;MainTopicMQTT = wasserzaehler/GPIO From b21e3c6c9d56555457e632bac9c5880e78c78eaf Mon Sep 17 00:00:00 2001 From: jomjol <30766535+jomjol@users.noreply.github.com> Date: Wed, 22 Feb 2023 21:38:31 +0100 Subject: [PATCH 29/31] Remove ";Topic = ", Delete Checkbox "AllowNegativeRate" --- sd-card/html/edit_config_param.html | 1 - sd-card/html/readconfigparam.js | 1 - 2 files changed, 2 deletions(-) diff --git a/sd-card/html/edit_config_param.html b/sd-card/html/edit_config_param.html index ab4e58b3..278f1a17 100644 --- a/sd-card/html/edit_config_param.html +++ b/sd-card/html/edit_config_param.html @@ -486,7 +486,6 @@ textarea { - diff --git a/sd-card/html/readconfigparam.js b/sd-card/html/readconfigparam.js index 4990c944..fddc0f06 100644 --- a/sd-card/html/readconfigparam.js +++ b/sd-card/html/readconfigparam.js @@ -177,7 +177,6 @@ function ParseConfig() { param[catname] = new Object(); ParamAddValue(param, catname, "Uri"); ParamAddValue(param, catname, "MainTopic", 1, false); - ParamAddValue(param, catname, "Topic", 1, false); ParamAddValue(param, catname, "ClientID"); ParamAddValue(param, catname, "user"); ParamAddValue(param, catname, "password"); From 3d711f495eb6f2e47788ed8dfd5e0c0d47e55dfd Mon Sep 17 00:00:00 2001 From: CaCO3 Date: Wed, 22 Feb 2023 23:20:52 +0100 Subject: [PATCH 30/31] updated save message --- sd-card/html/edit_alignment.html | 2 +- sd-card/html/edit_analog.html | 2 +- sd-card/html/edit_config.html | 2 +- sd-card/html/edit_config_param.html | 2 +- sd-card/html/edit_digits.html | 2 +- sd-card/html/edit_reference.html | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/sd-card/html/edit_alignment.html b/sd-card/html/edit_alignment.html index ff50a028..f827992f 100644 --- a/sd-card/html/edit_alignment.html +++ b/sd-card/html/edit_alignment.html @@ -133,7 +133,7 @@ function SaveToConfig(){ WriteConfigININew(); UpdateConfigReference(domainname) SaveConfigToServer(domainname); - firework.launch('Configuration got updated. Please reboot to activate changes!', 'success', 5000); + firework.launch('Configuration got updated. It will get applied after the next reboot!', 'success', 5000); } function EnhanceContrast(){ diff --git a/sd-card/html/edit_analog.html b/sd-card/html/edit_analog.html index 53ba41d3..162f0364 100644 --- a/sd-card/html/edit_analog.html +++ b/sd-card/html/edit_analog.html @@ -292,7 +292,7 @@ function SaveToConfig(){ cofcat["Analog"]["enabled"] = document.getElementById("Category_Analog_enabled").checked; WriteConfigININew(); SaveConfigToServer(domainname); - firework.launch('Configuration got updated. Please reboot to activate changes!', 'success', 5000); + firework.launch('Configuration got updated. It will get applied after the next reboot!', 'success', 5000); } diff --git a/sd-card/html/edit_config.html b/sd-card/html/edit_config.html index 2d5f55d3..475b875e 100644 --- a/sd-card/html/edit_config.html +++ b/sd-card/html/edit_config.html @@ -63,7 +63,7 @@ function saveTextAsFile() FileDeleteOnServer("/config/config.ini", domainname); var textToSave = document.getElementById("inputTextToSave").value; FileSendContent(textToSave, "/config/config.ini", domainname); - firework.launch('Configuration got updated. Please reboot to activate changes!', 'success', 5000); + firework.launch('Configuration got updated. It will get applied after the next reboot!', 'success', 5000); } } diff --git a/sd-card/html/edit_config_param.html b/sd-card/html/edit_config_param.html index 278f1a17..154a1274 100644 --- a/sd-card/html/edit_config_param.html +++ b/sd-card/html/edit_config_param.html @@ -2222,7 +2222,7 @@ function saveTextAsFile() ReadParameterAll(); WriteConfigININew(); SaveConfigToServer(domainname); - firework.launch('Configuration got updated. Please reboot to activate changes!', 'success', 5000); + firework.launch('Configuration got updated. It will get applied after the next reboot!', 'success', 5000); } } diff --git a/sd-card/html/edit_digits.html b/sd-card/html/edit_digits.html index 6a617492..60736c4f 100644 --- a/sd-card/html/edit_digits.html +++ b/sd-card/html/edit_digits.html @@ -296,7 +296,7 @@ function SaveToConfig(){ cofcat["Digits"]["enabled"] = document.getElementById("Category_Digits_enabled").checked; WriteConfigININew(); SaveConfigToServer(domainname); - firework.launch('Configuration got updated. Please reboot to activate changes!', 'success', 5000); + firework.launch('Configuration got updated. It will get applied after the next reboot!', 'success', 5000); } diff --git a/sd-card/html/edit_reference.html b/sd-card/html/edit_reference.html index 2835614f..4254ba60 100644 --- a/sd-card/html/edit_reference.html +++ b/sd-card/html/edit_reference.html @@ -272,7 +272,7 @@ table { SaveCanvasToImage(canvas, "/config/reference.jpg", true, getDomainname()); showReference(param); UpdatePage(); - firework.launch('Reference got updated. Please reboot to activate changes!', 'success', 5000); + firework.launch('Reference got updated. It will get applied after the next reboot!', 'success', 5000); } } From 2c1a7f4c9e7fb676241306fdb82ea1b7adf0fbf8 Mon Sep 17 00:00:00 2001 From: CaCO3 Date: Thu, 23 Feb 2023 23:39:02 +0100 Subject: [PATCH 31/31] DataLogActive is true by default --- code/main/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/main/main.cpp b/code/main/main.cpp index e5e5f5cc..a5794ba6 100644 --- a/code/main/main.cpp +++ b/code/main/main.cpp @@ -537,7 +537,7 @@ void migrateConfiguration(void) { if (section == "[DataLogging]") { migrated = migrated | replace(configLines[i], "DataLogRetentionInDays", "DataFilesRetention"); /* DataLogActive is true by default! */ - migrated = migrated | replace(configLines[i], ";DataLogActive = true", ";DataLogActive = true"); // Set it to its default value + migrated = migrated | replace(configLines[i], ";DataLogActive = false", ";DataLogActive = true"); // Set it to its default value migrated = migrated | replace(configLines[i], ";DataLogActive", "DataLogActive"); // Enable it }