Просмотр исходного кода

Merge branch 'rolling' of https://github.com/haverland/AI-on-the-edge-device into rolling

Frank Haverland 3 лет назад
Родитель
Сommit
9de573c15e
49 измененных файлов с 1434 добавлено и 490 удалено
  1. 24 11
      .github/workflows/build.yaml
  2. 7 0
      Changelog.md
  3. 6 0
      FeatureRequest.md
  4. 4 3
      code/components/jomjol_configfile/configFile.cpp
  5. 7 7
      code/components/jomjol_controlGPIO/server_GPIO.cpp
  6. 13 13
      code/components/jomjol_controlcamera/ClassControllCamera.cpp
  7. 13 10
      code/components/jomjol_controlcamera/server_camera.cpp
  8. 49 47
      code/components/jomjol_fileserver_ota/server_file.cpp
  9. 21 27
      code/components/jomjol_fileserver_ota/server_ota.cpp
  10. 6 4
      code/components/jomjol_flowcontroll/ClassFlow.cpp
  11. 5 3
      code/components/jomjol_flowcontroll/ClassFlowAlignment.cpp
  12. 95 72
      code/components/jomjol_flowcontroll/ClassFlowCNNGeneral.cpp
  13. 6 4
      code/components/jomjol_flowcontroll/ClassFlowCNNGeneral.h
  14. 11 12
      code/components/jomjol_flowcontroll/ClassFlowControll.cpp
  15. 1 0
      code/components/jomjol_flowcontroll/ClassFlowDefineTypes.h
  16. 8 6
      code/components/jomjol_flowcontroll/ClassFlowImage.cpp
  17. 6 3
      code/components/jomjol_flowcontroll/ClassFlowInfluxDB.cpp
  18. 7 5
      code/components/jomjol_flowcontroll/ClassFlowMQTT.cpp
  19. 3 2
      code/components/jomjol_flowcontroll/ClassFlowMakeImage.cpp
  20. 109 43
      code/components/jomjol_flowcontroll/ClassFlowPostProcessing.cpp
  21. 4 1
      code/components/jomjol_flowcontroll/ClassFlowPostProcessing.h
  22. 1 1
      code/components/jomjol_helper/CMakeLists.txt
  23. 259 16
      code/components/jomjol_helper/Helper.cpp
  24. 15 1
      code/components/jomjol_helper/Helper.h
  25. 7 4
      code/components/jomjol_image_proc/CAlignAndCutImage.cpp
  26. 13 9
      code/components/jomjol_image_proc/CFindTemplate.cpp
  27. 16 16
      code/components/jomjol_image_proc/CImageBasis.cpp
  28. 2 2
      code/components/jomjol_image_proc/CRotateImage.cpp
  29. 104 5
      code/components/jomjol_logfile/ClassLogFile.cpp
  30. 9 1
      code/components/jomjol_logfile/ClassLogFile.h
  31. 0 2
      code/components/jomjol_mqtt/interface_mqtt.cpp
  32. 19 15
      code/components/jomjol_tfliteclass/CTfLiteClass.cpp
  33. 51 53
      code/components/jomjol_tfliteclass/server_tflite.cpp
  34. 3 4
      code/components/jomjol_time_sntp/time_sntp.cpp
  35. 8 6
      code/components/jomjol_wlan/read_wlanini.cpp
  36. 31 24
      code/main/main.cpp
  37. 81 13
      code/main/server_main.cpp
  38. 104 0
      code/test/components/jomjol-flowcontroll/test_ZeigerEvalAnalogToDigitNeu.cpp
  39. 22 8
      code/test/components/jomjol-flowcontroll/test_flow_postrocess_helper.cpp
  40. 8 0
      code/test/components/jomjol-flowcontroll/test_flow_postrocess_helper.h
  41. 1 1
      code/test/components/jomjol-flowcontroll/test_flow_pp_negative.cpp
  42. 80 23
      code/test/components/jomjol-flowcontroll/test_flowpostprocessing.cpp
  43. 8 4
      code/test/test_suite_flowcontroll.cpp
  44. 1 0
      sd-card/config/config.ini
  45. 16 0
      sd-card/html/edit_config_param.html
  46. 9 9
      sd-card/html/graph.html
  47. 82 0
      sd-card/html/graph_data.html
  48. 78 0
      sd-card/html/info.html
  49. 1 0
      sd-card/html/readconfigparam.js

+ 24 - 11
.github/workflows/build.yaml

@@ -17,7 +17,7 @@ jobs:
     - name: Set Variables
       id: vars
       run: |
-        echo "sha_short=$(git rev-parse --short HEAD)" >> $GITHUB_ENV
+        echo "sha_short=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT
 
     - name: Cache PlatformIO
       uses: actions/cache@v3
@@ -28,7 +28,7 @@ jobs:
     - name: Set up Python
       uses: actions/setup-python@v4
       with:
-        python-version: '3.10' 
+        python-version: '3.10'
     - name: Install PlatformIO
       run: |
         python -m pip install --upgrade pip
@@ -76,23 +76,24 @@ jobs:
     - name: Set Variables
       id: vars
       run: |
-        echo "sha_short=$(git rev-parse --short HEAD)" >> $GITHUB_ENV
+        echo "sha_short=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT
 
     - name: Rename firmware file to contain versioning (old ota)
       run: |
         mkdir -p ./dist_old_ota
-        cp "./code/.pio/build/esp32cam/firmware.bin" "./dist_old_ota/firmware__${{ github.ref_name }}_(${{ env.sha_short }}).bin"
+        cp "./code/.pio/build/esp32cam/firmware.bin" "./dist_old_ota/firmware__${{ github.ref_name }}_(${{ steps.vars.outputs.sha_short }}).bin"
 
     - name: Upload Firmware artifact (old OTA concept)
       uses: actions/upload-artifact@v3
       with:
-        name: "firmware__(extract_before_upload)__${{ github.ref_name }}__(${{ env.sha_short }})"
+#        name: "firmware__${{ github.ref_name }}__(${{ steps.vars.outputs.sha_short }})__(extract_before_upload__only_needed_for_migration_from_11.3.1)"
+        name: "firmware__(extract_before_upload)__${{ github.ref_name }}__(${{ steps.vars.outputs.sha_short }})"
         path: ./dist_old_ota/*
 
     - name: Upload Web interface artifact (old OTA concept)
       uses: actions/upload-artifact@v3
       with:
-        name: "html__${{ github.ref_name }}__(${{ env.sha_short }})"
+        name: "html__${{ github.ref_name }}__(${{ steps.vars.outputs.sha_short }})"
         path: ./sd-card/html/*
 
 
@@ -125,15 +126,27 @@ jobs:
     - name: Set Variables
       id: vars
       run: |
-        echo "sha_short=$(git rev-parse --short HEAD)" >> $GITHUB_ENV
+        echo "sha_short=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT
 
     - name: Prepare update.zip artifact
       run: |
         mkdir -p ./dist
         cp "./code/.pio/build/esp32cam/firmware.bin" "dist/firmware.bin"
+
+#    - name: Upload update.zip Artifact (Firmware only)
+#      uses: actions/upload-artifact@v3
+#      with:
+#        name: "update_firmware_only__${{ github.ref_name }}_(${{ steps.vars.outputs.sha_short }})"
+#        path: ./dist/*
         
     - name: Add Web UI to dist
       run: cp -r ./sd-card/html ./dist/
+
+#    - name: Upload update.zip artifact (Firmware + Web UI)
+#      uses: actions/upload-artifact@v3
+#      with:
+#        name: "update_firmware+webinterface__${{ github.ref_name }}_(${{ steps.vars.outputs.sha_short }})"
+#        path: ./dist/*
         
     - name: Add CNN to dist
       run: |
@@ -144,7 +157,7 @@ jobs:
     - name: Upload dist as update.zip artifact (Firmware + Web UI + CNN)
       uses: actions/upload-artifact@v3
       with:
-        name: "update__${{ github.ref_name }}_(${{ env.sha_short }})"
+        name: "update__${{ github.ref_name }}_(${{ steps.vars.outputs.sha_short }})"
         path: ./dist/*
 
     - name: Store generated files in cache
@@ -181,7 +194,7 @@ jobs:
     - name: Set Variables
       id: vars
       run: |
-        echo "sha_short=$(git rev-parse --short HEAD)" >> $GITHUB_ENV
+        echo "sha_short=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT
 
     - name: Prepare artifacts for release
       run: |
@@ -198,7 +211,7 @@ jobs:
     - name: Upload initial_esp32_setup.zip artifact (Firmware + Bootloader + Partitions + Web UI)
       uses: actions/upload-artifact@v3
       with:
-        name: "initial_esp32_setup__${{ github.ref_name }}_(${{ env.sha_short }})"
+        name: "initial_esp32_setup__${{ github.ref_name }}_(${{ steps.vars.outputs.sha_short }})"
         path: ./firmware
 
     - name: Store generated files in cache
@@ -251,7 +264,7 @@ jobs:
     - name: Set Variables
       id: vars
       run: |
-        echo "sha_short=$(git rev-parse --short HEAD)" >> $GITHUB_ENV
+        echo "sha_short=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT
 
 
     - name: Prepare artifacts for release

+ 7 - 0
Changelog.md

@@ -7,11 +7,18 @@
 -   added `/graph.html` to fetch measurements from the debug log and display them as a graph. Activate debug logging for this feature to work.
 -   Added PreValue to `/json` ([#1154](https://github.com/jomjol/AI-on-the-edge-device/issues/1154))
 -   Show graph of values direct in the user interface (thanks to [@rdmueller](https://github.com/rdmueller))
+-   SD card info into the "Info" Menue (thanks to [@Slider007]( https://github.com/Slider0007))
+-   Added a logging of the values in a text table in `/log/data` - each measurement is one line
+    -   Format: tabulator separated
+    -   Content: time, name-of-number, raw-value, return-value, pre-value, change-rate, change-absolute, error-text, cnn-digital, cnn-analog
+    -   ATTENTION: format not fully fixed yet!
+
 
 ### Changed
 
 -   Updated built environment to `espressif32@v5.2.0`
 -   [#1176](https://github.com/jomjol/AI-on-the-edge-device/discussions/1176) accept minor negative values (-0.2) if extended resolution is enabled
+-   [#1143](https://github.com/jomjol/AI-on-the-edge-device/issues/1143) added config parameter AnalogDigitalTransitionStart. It can setup very early and very late digit transition starts.
 ### Fixed
 
 -   [#1116](https://github.com/jomjol/AI-on-the-edge-device/issues/1116) precision problem at setting prevalue

+ 6 - 0
FeatureRequest.md

@@ -11,6 +11,12 @@
 
 ____
 
+#### #32 Add feature to correct misinterpreted value
+
+* If a value is misinterpreted, the user can manually correct the value.
+* The misinterpreted ROIs would be saved in a "training data" -folder on the SD-card
+* Stretch goal: make sending of saved training data as easy as pushing a button =)
+
 #### #31 Implement InfluxDB v2.x interface
 
 * Currently only InfluxDB v1.x is supportet, extend to v2.x

+ 4 - 3
code/components/jomjol_configfile/configFile.cpp

@@ -4,8 +4,9 @@
 
 #include "Helper.h"
 #include "configFile.h"
+#include <esp_log.h>
 
-//static const char *TAGCONFIGFILE = "configFile";
+static const char *TAG = "configFile";
 
 ConfigFile::ConfigFile(std::string filePath)
 {
@@ -48,7 +49,7 @@ bool ConfigFile::getNextLine(std::string *rt, bool &disabled, bool &eof)
 
 	if (fgets(zw, 1024, pFile))
 	{
-		printf("%s", zw);
+		ESP_LOGD(TAG, "%s", zw);
 		if ((strlen(zw) == 0) && feof(pFile))
 		{
 			*rt = "";
@@ -67,7 +68,7 @@ bool ConfigFile::getNextLine(std::string *rt, bool &disabled, bool &eof)
 	while ((zw[0] == ';' || zw[0] == '#' || (rt->size() == 0)) && !(zw[1] == '['))			// Kommentarzeilen (; oder #) und Leerzeilen überspringen, es sei denn es ist ein neuer auskommentierter Paragraph
 	{
 		fgets(zw, 1024, pFile);
-		printf("%s", zw);		
+		ESP_LOGD(TAG, "%s", zw);
 		if (feof(pFile))
 		{
 			*rt = "";

+ 7 - 7
code/components/jomjol_controlGPIO/server_GPIO.cpp

@@ -210,10 +210,10 @@ GpioHandler::~GpioHandler()  {
 void GpioHandler::init()
 {
     // TickType_t xDelay = 60000 / portTICK_PERIOD_MS;
-    // printf("wait before start %ldms\r\n", (long) xDelay);
+    // ESP_LOGD(TAG_SERVERGPIO, "wait before start %ldms", (long) xDelay);
     // vTaskDelay( xDelay );
 
-    printf("*************** Start GPIOHandler_Init *****************\n");
+    ESP_LOGD(TAG_SERVERGPIO, "*************** Start GPIOHandler_Init *****************");
 
     if (gpioMap == NULL) {
         gpioMap = new std::map<gpio_num_t, GpioPin*>();
@@ -300,13 +300,13 @@ bool GpioHandler::readConfig()
     bool eof = false;
     gpio_num_t gpioExtLED = (gpio_num_t) 0;
     
-//    printf("readConfig - Start 1\n");
+//    ESP_LOGD(TAG_SERVERGPIO, "readConfig - Start 1");
         
     while ((!configFile.GetNextParagraph(line, disabledLine, eof) || (line.compare("[GPIO]") != 0)) && !eof) {}
     if (eof)
         return false;
 
-//    printf("readConfig - Start 2 line: %s, disabbledLine: %d\n", line.c_str(), (int) disabledLine);
+//    ESP_LOGD(TAG_SERVERGPIO, "readConfig - Start 2 line: %s, disabbledLine: %d", line.c_str(), (int) disabledLine);
 
 
     _isEnabled = !disabledLine;
@@ -314,7 +314,7 @@ bool GpioHandler::readConfig()
     if (!_isEnabled)
         return false;
 
-//    printf("readConfig - Start 3\n");
+//    ESP_LOGD(TAG_SERVERGPIO, "readConfig - Start 3");
 
 //    std::string mainTopicMQTT = "";
     std::string mainTopicMQTT = GetMQTTMainTopic();
@@ -359,7 +359,7 @@ bool GpioHandler::readConfig()
 
             if (pinMode == GPIO_PIN_MODE_EXTERNAL_FLASH_WS281X)
             {
-                printf("Set WS2812 to GPIO %d\n", gpioNr);
+                ESP_LOGD(TAG_SERVERGPIO, "Set WS2812 to GPIO %d", gpioNr);
                 gpioExtLED = gpioNr;
             }
 
@@ -403,7 +403,7 @@ bool GpioHandler::readConfig()
     //     LogFile.WriteToFile("Startsequence 06");      // Nremove
 //        vTaskDelay( xDelay );   
 //        xDelay = 5000 / portTICK_PERIOD_MS;
-//        printf("main: sleep for : %ldms\n", (long) xDelay);
+//        ESP_LOGD(TAG_SERVERGPIO, "main: sleep for: %ldms", (long) xDelay);
 
 //        SmartLed leds( LED_WS2812, 2, GPIO_NUM_12, 0, DoubleBuffer );
 

+ 13 - 13
code/components/jomjol_controlcamera/ClassControllCamera.cpp

@@ -249,7 +249,7 @@ void CCamera::SetQualitySize(int qual, framesize_t resol)
 
 void CCamera::EnableAutoExposure(int flashdauer)
 {
-    printf("EnableAutoExposure");
+    ESP_LOGD(TAGCAMERACLASS, "EnableAutoExposure");
     LEDOnOff(true);
     if (flashdauer > 0)
         LightOnOff(true);
@@ -423,19 +423,19 @@ esp_err_t CCamera::CaptureToFile(std::string nm, int delay)
     LEDOnOff(false);    
 
 #ifdef DEBUG_DETAIL_ON    
-    printf("w %d, h %d, size %d\n", fb->width, fb->height, fb->len);
+    ESP_LOGD(TAGCAMERACLASS, "w %d, h %d, size %d", fb->width, fb->height, fb->len);
 #endif
 
     nm = FormatFileName(nm);
 
 #ifdef DEBUG_DETAIL_ON
-    printf("Save Camera to : %s\n", nm.c_str());
+    ESP_LOGD(TAGCAMERACLASS, "Save Camera to : %s", nm.c_str());
 #endif
 
     ftype = toUpper(getFileType(nm));
 
 #ifdef DEBUG_DETAIL_ON
-    printf("Filetype: %s\n", ftype.c_str());
+    ESP_LOGD(TAGCAMERACLASS, "Filetype: %s", ftype.c_str());
 #endif
 
     uint8_t * buf = NULL;
@@ -551,20 +551,20 @@ void CCamera::LightOnOff(bool status)
 {
     GpioHandler* gpioHandler = gpio_handler_get();
     if ((gpioHandler != NULL) && (gpioHandler->isEnabled())) {
-        printf("Use gpioHandler flashLigh\n");
+        ESP_LOGD(TAGCAMERACLASS, "Use gpioHandler flashLigh");
         gpioHandler->flashLightEnable(status);
     }  else {
     #ifdef USE_PWM_LEDFLASH
         if (status)
         {
-            printf("Internal Flash-LED turn on with PWM %d\n", led_intensity);
+            ESP_LOGD(TAGCAMERACLASS, "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
         {
-            printf("Internal Flash-LED turn off PWM\n");
+            ESP_LOGD(TAGCAMERACLASS, "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));
         }
@@ -608,11 +608,11 @@ void CCamera::GetCameraParameter(httpd_req_t *req, int &qual, framesize_t &resol
 
     if (httpd_req_get_url_query_str(req, _query, 100) == ESP_OK)
     {
-        printf("Query: "); printf(_query); printf("\n");
+        ESP_LOGD(TAGCAMERACLASS, "Query: %s", _query);
         if (httpd_query_key_value(_query, "size", _size, 10) == ESP_OK)
         {
 #ifdef DEBUG_DETAIL_ON   
-            printf("Size: "); printf(_size); printf("\n");            
+            ESP_LOGD(TAGCAMERACLASS, "Size: %s", _size);
 #endif
             if (strcmp(_size, "QVGA") == 0)
                 resol = FRAMESIZE_QVGA;       // 320x240
@@ -630,7 +630,7 @@ void CCamera::GetCameraParameter(httpd_req_t *req, int &qual, framesize_t &resol
         if (httpd_query_key_value(_query, "quality", _qual, 10) == ESP_OK)
         {
 #ifdef DEBUG_DETAIL_ON   
-            printf("Quality: "); printf(_qual); printf("\n");
+            ESP_LOGD(TAGCAMERACLASS, "Quality: %s", _qual);
 #endif
             qual = atoi(_qual);
                 
@@ -663,7 +663,7 @@ framesize_t CCamera::TextToFramesize(const char * _size)
 CCamera::CCamera()
 {
 #ifdef DEBUG_DETAIL_ON    
-    printf("CreateClassCamera\n");
+    ESP_LOGD(TAGCAMERACLASS, "CreateClassCamera");
 #endif
     brightness = -5;
     contrast = -5;
@@ -675,7 +675,7 @@ CCamera::CCamera()
 
 esp_err_t CCamera::InitCam()
 {
-    printf("Init Camera\n");
+    ESP_LOGD(TAGCAMERACLASS, "Init Camera");
     ActualQuality = camera_config.jpeg_quality;
     ActualResolution = camera_config.frame_size;
     //initialize the camera
@@ -694,6 +694,6 @@ void CCamera::SetLEDIntensity(float _intrel)
     _intrel = max(_intrel, (float) 0);
     _intrel = _intrel / 100;
     led_intensity = (int) (_intrel * 8191);
-    printf("Set led_intensity to %d of 8191\n", led_intensity);
+    ESP_LOGD(TAGCAMERACLASS, "Set led_intensity to %d of 8191", led_intensity);
 
 }

+ 13 - 10
code/components/jomjol_controlcamera/server_camera.cpp

@@ -7,6 +7,9 @@
 #include "ClassControllCamera.h"
 
 #include "ClassLogFile.h"
+#include "esp_log.h"
+
+static const char *TAG = "server_cam";
 
 #define SCRATCH_BUFSIZE2  8192 
 char scratch2[SCRATCH_BUFSIZE2];
@@ -37,7 +40,7 @@ esp_err_t handler_lightOn(httpd_req_t *req)
 {
 #ifdef DEBUG_DETAIL_ON   
     LogFile.WriteHeapInfo("handler_lightOn - Start");
-    printf("handler_lightOn uri:\n"); printf(req->uri); printf("\n");
+    ESP_LOGD(TAG, "handler_lightOn uri: %s", req->uri);
 #endif
 
     Camera.LightOnOff(true);
@@ -55,7 +58,7 @@ esp_err_t handler_lightOff(httpd_req_t *req)
 {
 #ifdef DEBUG_DETAIL_ON   
     LogFile.WriteHeapInfo("handler_lightOff - Start");
-    printf("handler_lightOff uri:\n"); printf(req->uri); printf("\n");
+    ESP_LOGD(TAG, "handler_lightOff uri: %s", req->uri);
 #endif
     Camera.LightOnOff(false);
     const char* resp_str = (const char*) req->user_ctx;
@@ -80,7 +83,7 @@ esp_err_t handler_capture(httpd_req_t *req)
     Camera.GetCameraParameter(req, quality, res);
 
 #ifdef DEBUG_DETAIL_ON   
-    printf("Size: %d", res); printf(" Quality: %d\n", quality);
+    ESP_LOGD(TAG, "Size: %d, Quality: %d", res, quality);
 #endif
 
     Camera.SetQualitySize(quality, res);
@@ -110,11 +113,11 @@ esp_err_t handler_capture_with_ligth(httpd_req_t *req)
 
     if (httpd_req_get_url_query_str(req, _query, 100) == ESP_OK)
     {
-        printf("Query: "); printf(_query); printf("\n");
+        ESP_LOGD(TAG, "Query: %s", _query);
         if (httpd_query_key_value(_query, "delay", _delay, 10) == ESP_OK)
         {
 #ifdef DEBUG_DETAIL_ON   
-            printf("Delay: "); printf(_delay); printf("\n");    
+            ESP_LOGD(TAG, "Delay: %s", _delay);
 #endif        
             delay = atoi(_delay);
 
@@ -126,7 +129,7 @@ esp_err_t handler_capture_with_ligth(httpd_req_t *req)
     Camera.GetCameraParameter(req, quality, res);
 
 #ifdef DEBUG_DETAIL_ON   
-    printf("Size: %d", res); printf(" Quality: %d\n", quality);
+    ESP_LOGD(TAG, "Size: %d, Quality: %d", res, quality);
 #endif
 
     Camera.SetQualitySize(quality, res);
@@ -166,12 +169,12 @@ esp_err_t handler_capture_save_to_file(httpd_req_t *req)
 
     if (httpd_req_get_url_query_str(req, _query, 100) == ESP_OK)
     {
-        printf("Query: "); printf(_query); printf("\n");
+        ESP_LOGD(TAG, "Query: %s", _query);
         if (httpd_query_key_value(_query, "filename", filename, 100) == ESP_OK)
         {
             fn.append(filename);
 #ifdef DEBUG_DETAIL_ON   
-            printf("Filename: "); printf(fn.c_str()); printf("\n");            
+            ESP_LOGD(TAG, "Filename: %s", fn.c_str());
 #endif
         }
         else
@@ -180,7 +183,7 @@ esp_err_t handler_capture_save_to_file(httpd_req_t *req)
         if (httpd_query_key_value(_query, "delay", _delay, 10) == ESP_OK)
         {
 #ifdef DEBUG_DETAIL_ON   
-            printf("Delay: "); printf(_delay); printf("\n");            
+            ESP_LOGD(TAG, "Delay: %s", _delay);
 #endif
             delay = atoi(_delay);
 
@@ -194,7 +197,7 @@ esp_err_t handler_capture_save_to_file(httpd_req_t *req)
 
     Camera.GetCameraParameter(req, quality, res);
 #ifdef DEBUG_DETAIL_ON   
-    printf("Size: %d", res); printf(" Quality: %d\n", quality);
+    ESP_LOGD(TAG, "Size: %d, Quality: %d", res, quality);
 #endif
     Camera.SetQualitySize(quality, res);
 

+ 49 - 47
code/components/jomjol_fileserver_ota/server_file.cpp

@@ -43,6 +43,8 @@ extern "C" {
 #include "Helper.h"
 #include "miniz.h"
 
+static const char *TAG = "server_file";
+
 /* Max length a file path can have on storage */
 // #define FILE_PATH_MAX (ESP_VFS_PATH_MAX + CONFIG_SPIFFS_OBJ_NAME_LEN)
 #define FILE_PATH_MAX (255)
@@ -88,7 +90,7 @@ esp_err_t get_tflite_file_handler(httpd_req_t *req)
     size_t pos = 0;
     
     const char verz_name[] = "/sdcard/config";
-    printf("Suche TFLITE in /sdcard/config/\n");
+    ESP_LOGD(TAG, "Suche TFLITE in /sdcard/config/");
 
     httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");
     httpd_resp_set_type(req, "text/plain");
@@ -97,7 +99,7 @@ esp_err_t get_tflite_file_handler(httpd_req_t *req)
     while ((entry = readdir(dir)) != NULL) 
     {
         _filename = std::string(entry->d_name);
-        printf("File: %s\t", _filename.c_str());
+        ESP_LOGD(TAG, "File: %s", _filename.c_str());
 
         // ignore all files with starting dot (hidden files)
         if (_filename.rfind(".", 0) == 0) {
@@ -109,7 +111,7 @@ esp_err_t get_tflite_file_handler(httpd_req_t *req)
         if (pos != std::string::npos)
             _fileext = _fileext.erase(0, pos + 1);
 
-        printf(" Extension: %s\n", _fileext.c_str());
+        ESP_LOGD(TAG, " Extension: %s", _fileext.c_str());
 
         if ((_fileext == "tfl") || (_fileext == "tflite"))
         {
@@ -147,11 +149,11 @@ static esp_err_t http_resp_dir_html(httpd_req_t *req, const char *dirpath, const
     DIR *dir = opendir(dirpath_corrected);
 
     const size_t dirpath_len = strlen(dirpath);
-    printf("Dirpath: <%s>, Pathlength: %d\n", dirpath, dirpath_len);    
+    ESP_LOGD(TAG, "Dirpath: <%s>, Pathlength: %d", dirpath, dirpath_len);
 
     /* Retrieve the base path of file storage to construct the full path */
     strlcpy(entrypath, dirpath, sizeof(entrypath));
-    printf("entrypath: <%s>\n", entrypath);    
+    ESP_LOGD(TAG, "entrypath: <%s>", entrypath);
 
     if (!dir) {
         ESP_LOGE(TAG_FILESERVER, "Failed to stat dir : %s", dirpath);
@@ -170,7 +172,7 @@ static esp_err_t http_resp_dir_html(httpd_req_t *req, const char *dirpath, const
         size_t chunksize;
         do {
             chunksize = fread(chunk, 1, SCRATCH_BUFSIZE, fd);
-            //        printf("Chunksize %d\n", chunksize);
+            //        ESP_LOGD(TAG, "Chunksize %d", chunksize);
             if (chunksize > 0){
                 if (httpd_resp_send_chunk(req, chunk, chunksize) != ESP_OK) {
                 fclose(fd);
@@ -211,7 +213,7 @@ static esp_err_t http_resp_dir_html(httpd_req_t *req, const char *dirpath, const
             entrytype = (entry->d_type == DT_DIR ? "directory" : "file");
 
             strlcpy(entrypath + dirpath_len, entry->d_name, sizeof(entrypath) - dirpath_len);
-            printf("Entrypath: %s\n", entrypath);
+            ESP_LOGD(TAG, "Entrypath: %s", entrypath);
             if (stat(entrypath, &entry_stat) == -1) {
                 ESP_LOGE(TAG_FILESERVER, "Failed to stat %s : %s", entrytype, entry->d_name);
                 continue;
@@ -266,11 +268,11 @@ static esp_err_t logfileact_get_handler(httpd_req_t *req)
     char filepath[FILE_PATH_MAX];
     FILE *fd = NULL;
     //struct stat file_stat;
-    printf("uri: %s\n", req->uri);
+    ESP_LOGD(TAG, "uri: %s", req->uri);
 
     const char* filename = "log_current.txt"; 
 
-    printf("uri: %s, filename: %s, filepath: %s\n", req->uri, filename, filepath);
+    ESP_LOGD(TAG, "uri: %s, filename: %s, filepath: %s", req->uri, filename, filepath);
 
     std::string currentfilename = LogFile.GetCurrentFileName();
 
@@ -331,12 +333,12 @@ static esp_err_t download_get_handler(httpd_req_t *req)
     char filepath[FILE_PATH_MAX];
     FILE *fd = NULL;
     struct stat file_stat;
-    printf("uri: %s\n", req->uri);
+    ESP_LOGD(TAG, "uri: %s", req->uri);
 
     const char *filename = get_path_from_uri(filepath, ((struct file_server_data *)req->user_ctx)->base_path,
                                              req->uri  + sizeof("/fileserver") - 1, sizeof(filepath));    
 
-    printf("uri: %s, filename: %s, filepath: %s\n", req->uri, filename, filepath);
+    ESP_LOGD(TAG, "uri: %s, filename: %s, filepath: %s", req->uri, filename, filepath);
 
 //    filename = get_path_from_uri(filepath, ((struct file_server_data *)req->user_ctx)->base_path,
 //                                             req->uri, sizeof(filepath));
@@ -366,7 +368,7 @@ static esp_err_t download_get_handler(httpd_req_t *req)
             }
         }
 
-        printf("uri: %s, filename: %s, filepath: %s\n", req->uri, filename, filepath);
+        ESP_LOGD(TAG, "uri: %s, filename: %s, filepath: %s", req->uri, filename, filepath);
         return http_resp_dir_html(req, filepath, filename, readonly);
     }
 
@@ -541,12 +543,12 @@ static esp_err_t upload_post_handler(httpd_req_t *req)
 	}
 
     int start_fn = strlen(((struct file_server_data *)req->user_ctx)->base_path);
-    printf("Directory: %s, start_fn: %d, found: %d\n", directory.c_str(), start_fn, found);
+    ESP_LOGD(TAG, "Directory: %s, start_fn: %d, found: %d", directory.c_str(), start_fn, found);
 	directory = directory.substr(start_fn, found - start_fn + 1);
-    printf("Directory danach 1: %s\n", directory.c_str());    
+    ESP_LOGD(TAG, "Directory danach 1: %s", directory.c_str());
 
     directory = "/fileserver" + directory;
-    printf("Directory danach 2: %s\n", directory.c_str());   
+    ESP_LOGD(TAG, "Directory danach 2: %s", directory.c_str());
 
     /* Redirect onto root to see the updated file list */
     httpd_resp_set_status(req, "303 See Other");
@@ -559,7 +561,7 @@ static esp_err_t upload_post_handler(httpd_req_t *req)
 
 /*
     if (strcmp(filepath, CONFIG_FILE) == 0) {
-        printf("New config found. Reload handler.");
+        ESP_LOGD(TAG, "New config found. Reload handler.");
         gpio_handler_deinit();
         MQTTdestroy();
     }
@@ -586,11 +588,11 @@ static esp_err_t delete_post_handler(httpd_req_t *req)
 
     if (httpd_req_get_url_query_str(req, _query, 200) == ESP_OK)
     {
-        printf("Query: "); printf(_query); printf("\n");
+        ESP_LOGD(TAG, "Query: %s", _query);
         
         if (httpd_query_key_value(_query, "task", _valuechar, 30) == ESP_OK)
         {
-            printf("task is found: "); printf(_valuechar); printf("\n"); 
+            ESP_LOGD(TAG, "task is found: %s", _valuechar);
             _task = std::string(_valuechar);
         }
     }
@@ -610,12 +612,12 @@ static esp_err_t delete_post_handler(httpd_req_t *req)
         zw = zw.substr(0, zw.length()-1);
         directory = "/fileserver" + zw + "/";
         zw = "/sdcard" + zw;
-        printf("Directory to delete: %s\n", zw.c_str());
+        ESP_LOGD(TAG, "Directory to delete: %s", zw.c_str());
 
         delete_all_in_directory(zw);
 //        directory = std::string(filepath);
 //        directory = "/fileserver" + directory;
-        printf("Location after delete directory content: %s\n", directory.c_str());
+        ESP_LOGD(TAG, "Location after delete directory content: %s", directory.c_str());
         /* Redirect onto root to see the updated file list */
 //        httpd_resp_set_status(req, "303 See Other");
 //        httpd_resp_set_hdr(req, "Location", directory.c_str());
@@ -663,12 +665,12 @@ static esp_err_t delete_post_handler(httpd_req_t *req)
         }
 
         int start_fn = strlen(((struct file_server_data *)req->user_ctx)->base_path);
-        printf("Directory: %s, start_fn: %d, found: %d\n", directory.c_str(), start_fn, found);
+        ESP_LOGD(TAG, "Directory: %s, start_fn: %d, found: %d", directory.c_str(), start_fn, found);
         directory = directory.substr(start_fn, found - start_fn + 1);
-        printf("Directory danach 3: %s\n", directory.c_str());    
+        ESP_LOGD(TAG, "Directory danach 3: %s", directory.c_str());
 
         directory = "/fileserver" + directory;
-        printf("Directory danach 4: %s\n", directory.c_str());   
+        ESP_LOGD(TAG, "Directory danach 4: %s", directory.c_str());
     }
     
 
@@ -722,18 +724,18 @@ std::string unzip_new(std::string _in_zip_file, std::string _target_zip, std::st
     std::string directory = "";
 //    static const char* s_Test_archive_filename = "testhtml.zip";
 
-    printf("miniz.c version: %s\n", MZ_VERSION);
-    printf("Zipfile: %s\n", _in_zip_file.c_str());
-    printf("Target Dir ZIP: %s\n", _target_zip.c_str());
-    printf("Target Dir BIN: %s\n", _target_bin.c_str());
-    printf("Target Dir main: %s\n", _main.c_str());
+    ESP_LOGD(TAG, "miniz.c version: %s", MZ_VERSION);
+    ESP_LOGD(TAG, "Zipfile: %s", _in_zip_file.c_str());
+    ESP_LOGD(TAG, "Target Dir ZIP: %s", _target_zip.c_str());
+    ESP_LOGD(TAG, "Target Dir BIN: %s", _target_bin.c_str());
+    ESP_LOGD(TAG, "Target Dir main: %s", _main.c_str());
 
     // Now try to open the archive.
     memset(&zip_archive, 0, sizeof(zip_archive));
     status = mz_zip_reader_init_file(&zip_archive, _in_zip_file.c_str(), 0);
     if (!status)
     {
-        printf("mz_zip_reader_init_file() failed!\n");
+        ESP_LOGD(TAG, "mz_zip_reader_init_file() failed!");
         return ret;
     }
 
@@ -745,7 +747,7 @@ std::string unzip_new(std::string _in_zip_file, std::string _target_zip, std::st
         status = mz_zip_reader_init_file(&zip_archive, _in_zip_file.c_str(), sort_iter ? MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY : 0);
         if (!status)
         {
-            printf("mz_zip_reader_init_file() failed!\n");
+            ESP_LOGD(TAG, "mz_zip_reader_init_file() failed!");
             return ret;
         }
 
@@ -760,14 +762,14 @@ std::string unzip_new(std::string _in_zip_file, std::string _target_zip, std::st
             p = mz_zip_reader_extract_file_to_heap(&zip_archive, archive_filename, &uncomp_size, 0);
                 if (!p)
                 {
-                    printf("mz_zip_reader_extract_file_to_heap() failed on file %s\n", archive_filename);
+                    ESP_LOGD(TAG, "mz_zip_reader_extract_file_to_heap() failed on file %s", archive_filename);
                     mz_zip_reader_end(&zip_archive);
                     return ret;
                 }
             
                 // Save to File.
                 zw = std::string(archive_filename);
-                printf("Rohfilename: %s\n", zw.c_str());
+                ESP_LOGD(TAG, "Rohfilename: %s", zw.c_str());
 
                 if (getFileType(zw) == "BIN")
                 {
@@ -791,7 +793,7 @@ std::string unzip_new(std::string _in_zip_file, std::string _target_zip, std::st
             
                 string filename_zw = zw + SUFFIX_ZW;
 
-                printf("Filename to extract: %s, Zwischenfilename: %s", zw.c_str(), filename_zw.c_str());
+                ESP_LOGD(TAG, "Filename to extract: %s, Zwischenfilename: %s", zw.c_str(), filename_zw.c_str());
 
                 // extrahieren in zwischendatei
                 DeleteFile(filename_zw);
@@ -803,8 +805,8 @@ std::string unzip_new(std::string _in_zip_file, std::string _target_zip, std::st
                 RenameFile(filename_zw, zw);
                 DeleteFile(filename_zw);
 
-                printf("Successfully extracted file \"%s\", size %u\n", archive_filename, (uint)uncomp_size);
-                //            printf("File data: \"%s\"\n", (const char*)p);
+                ESP_LOGD(TAG, "Successfully extracted file \"%s\", size %u", archive_filename, (uint)uncomp_size);
+                //            ESP_LOGD(TAG, "File data: \"%s\"", (const char*)p);
 
                 // We're done.
                 mz_free(p);
@@ -815,7 +817,7 @@ std::string unzip_new(std::string _in_zip_file, std::string _target_zip, std::st
         mz_zip_reader_end(&zip_archive);
     }
 
-    printf("Success.\n");
+    ESP_LOGD(TAG, "Success.");
     return ret;
 }
 
@@ -829,16 +831,16 @@ void unzip(std::string _in_zip_file, std::string _target_directory){
     std::string zw;
 //    static const char* s_Test_archive_filename = "testhtml.zip";
 
-    printf("miniz.c version: %s\n", MZ_VERSION);
-    printf("Zipfile: %s\n", _in_zip_file.c_str());
-    printf("Target Dir: %s\n", _target_directory.c_str());
+    ESP_LOGD(TAG, "miniz.c version: %s", MZ_VERSION);
+    ESP_LOGD(TAG, "Zipfile: %s", _in_zip_file.c_str());
+    ESP_LOGD(TAG, "Target Dir: %s", _target_directory.c_str());
 
     // Now try to open the archive.
     memset(&zip_archive, 0, sizeof(zip_archive));
     status = mz_zip_reader_init_file(&zip_archive, _in_zip_file.c_str(), 0);
     if (!status)
     {
-        printf("mz_zip_reader_init_file() failed!\n");
+        ESP_LOGD(TAG, "mz_zip_reader_init_file() failed!");
         return;
     }
 
@@ -850,7 +852,7 @@ void unzip(std::string _in_zip_file, std::string _target_directory){
         status = mz_zip_reader_init_file(&zip_archive, _in_zip_file.c_str(), sort_iter ? MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY : 0);
         if (!status)
         {
-            printf("mz_zip_reader_init_file() failed!\n");
+            ESP_LOGD(TAG, "mz_zip_reader_init_file() failed!");
             return;
         }
 
@@ -864,7 +866,7 @@ void unzip(std::string _in_zip_file, std::string _target_directory){
             p = mz_zip_reader_extract_file_to_heap(&zip_archive, archive_filename, &uncomp_size, 0);
             if (!p)
             {
-                printf("mz_zip_reader_extract_file_to_heap() failed!\n");
+                ESP_LOGD(TAG, "mz_zip_reader_extract_file_to_heap() failed!");
                 mz_zip_reader_end(&zip_archive);
                 return;
             }
@@ -872,13 +874,13 @@ void unzip(std::string _in_zip_file, std::string _target_directory){
             // Save to File.
             zw = std::string(archive_filename);
             zw = _target_directory + zw;
-            printf("Filename to extract: %s", zw.c_str());
+            ESP_LOGD(TAG, "Filename to extract: %s", zw.c_str());
             FILE* fpTargetFile = OpenFileAndWait(zw.c_str(), "wb");
             fwrite(p, 1, (uint)uncomp_size, fpTargetFile);
             fclose(fpTargetFile);
 
-            printf("Successfully extracted file \"%s\", size %u\n", archive_filename, (uint)uncomp_size);
-            //            printf("File data: \"%s\"\n", (const char*)p);
+            ESP_LOGD(TAG, "Successfully extracted file \"%s\", size %u", archive_filename, (uint)uncomp_size);
+            //            ESP_LOGD(TAG, "File data: \"%s\"", (const char*)p);
 
             // We're done.
             mz_free(p);
@@ -888,7 +890,7 @@ void unzip(std::string _in_zip_file, std::string _target_directory){
         mz_zip_reader_end(&zip_archive);
     }
 
-    printf("Success.\n");
+    ESP_LOGD(TAG, "Success.");
 }
 
 
@@ -925,7 +927,7 @@ void register_server_file_uri(httpd_handle_t server, const char *base_path)
 //    strcpy(zw, serverprefix);
 //    zw[strlen(serverprefix)] = '*';
 //    zw[strlen(serverprefix)+1] = '\0';    
-//    printf("zw: %s\n", zw);
+//    ESP_LOGD(TAG, "zw: %s", zw);
     httpd_uri_t file_download = {
         .uri       = "/fileserver*",  // Match all URIs of type /path/to/file
         .method    = HTTP_GET,

+ 21 - 27
code/components/jomjol_fileserver_ota/server_ota.cpp

@@ -58,7 +58,7 @@ static void infinite_loop(void)
     int i = 0;
     ESP_LOGI(TAGPARTOTA, "When a new firmware is available on the server, press the reset button to download it");
     while(1) {
-        ESP_LOGI(TAGPARTOTA, "Waiting for a new firmware ... %d", ++i);
+        ESP_LOGI(TAGPARTOTA, "Waiting for a new firmware... %d", ++i);
         vTaskDelay(2000 / portTICK_PERIOD_MS);
     }
 }
@@ -219,8 +219,7 @@ static bool diagnostic(void)
 
 void CheckOTAUpdate(void)
 {
-    ESP_LOGI(TAGPARTOTA, "Start CheckOTAUpdateCheck ...");
-    printf("Start CheckOTAUpdateCheck ...\n");
+    ESP_LOGI(TAGPARTOTA, "Start CheckOTAUpdateCheck...");
 
     uint8_t sha_256[HASH_LEN] = { 0 };
     esp_partition_t partition;
@@ -249,31 +248,29 @@ void CheckOTAUpdate(void)
     switch (res_stat_partition)
     {
         case ESP_OK:
-            printf("CheckOTAUpdate Partition: ESP_OK\n");
+            ESP_LOGD(TAGPARTOTA, "CheckOTAUpdate Partition: ESP_OK");
             if (esp_ota_get_state_partition(running, &ota_state) == ESP_OK) {
                 if (ota_state == ESP_OTA_IMG_PENDING_VERIFY) {
                     // run diagnostic function ...
                     bool diagnostic_is_ok = diagnostic();
                     if (diagnostic_is_ok) {
-                        ESP_LOGI(TAGPARTOTA, "Diagnostics completed successfully! Continuing execution ...");
-                        printf("Diagnostics completed successfully! Continuing execution ...\n");
+                        ESP_LOGI(TAGPARTOTA, "Diagnostics completed successfully! Continuing execution...");
                         esp_ota_mark_app_valid_cancel_rollback();
                     } else {
-                        ESP_LOGE(TAGPARTOTA, "Diagnostics failed! Start rollback to the previous version ...");
-                        printf("Diagnostics failed! Start rollback to the previous version ...\n");
+                        ESP_LOGE(TAGPARTOTA, "Diagnostics failed! Start rollback to the previous version...");
                         esp_ota_mark_app_invalid_rollback_and_reboot();
                     }
                 }
             }            
             break;
         case ESP_ERR_INVALID_ARG:
-            printf("CheckOTAUpdate Partition: ESP_ERR_INVALID_ARG\n");
+            ESP_LOGD(TAGPARTOTA, "CheckOTAUpdate Partition: ESP_ERR_INVALID_ARG");
             break;
         case ESP_ERR_NOT_SUPPORTED:
-            printf("CheckOTAUpdate Partition: ESP_ERR_NOT_SUPPORTED\n");
+            ESP_LOGD(TAGPARTOTA, "CheckOTAUpdate Partition: ESP_ERR_NOT_SUPPORTED");
             break;
         case ESP_ERR_NOT_FOUND:
-            printf("CheckOTAUpdate Partition: ESP_ERR_NOT_FOUND\n");
+            ESP_LOGD(TAGPARTOTA, "CheckOTAUpdate Partition: ESP_ERR_NOT_FOUND");
             break;
     }
     if (esp_ota_get_state_partition(running, &ota_state) == ESP_OK) {
@@ -281,12 +278,10 @@ void CheckOTAUpdate(void)
             // run diagnostic function ...
             bool diagnostic_is_ok = diagnostic();
             if (diagnostic_is_ok) {
-                ESP_LOGI(TAGPARTOTA, "Diagnostics completed successfully! Continuing execution ...");
-                printf("Diagnostics completed successfully! Continuing execution ...\n");
+                ESP_LOGI(TAGPARTOTA, "Diagnostics completed successfully! Continuing execution...");
                 esp_ota_mark_app_valid_cancel_rollback();
             } else {
-                ESP_LOGE(TAGPARTOTA, "Diagnostics failed! Start rollback to the previous version ...");
-                printf("Diagnostics failed! Start rollback to the previous version ...\n");
+                ESP_LOGE(TAGPARTOTA, "Diagnostics failed! Start rollback to the previous version...");
                 esp_ota_mark_app_invalid_rollback_and_reboot();
             }
         }
@@ -311,24 +306,24 @@ esp_err_t handler_ota_update(httpd_req_t *req)
 
     if (httpd_req_get_url_query_str(req, _query, 200) == ESP_OK)
     {
-        printf("Query: "); printf(_query); printf("\n");
+        ESP_LOGD(TAGPARTOTA, "Query: %s", _query);
         
         if (httpd_query_key_value(_query, "task", _valuechar, 30) == ESP_OK)
         {
-            printf("task is found: "); printf(_valuechar); printf("\n"); 
+            ESP_LOGD(TAGPARTOTA, "task is found: %s", _valuechar);
             _task = std::string(_valuechar);
         }
 
         if (httpd_query_key_value(_query, "file", _filename, 100) == ESP_OK)
         {
             fn.append(_filename);
-            printf("File: "); printf(fn.c_str()); printf("\n");            
+            ESP_LOGD(TAGPARTOTA, "File: %s", fn.c_str());
         }
         if (httpd_query_key_value(_query, "delete", _filename, 100) == ESP_OK)
         {
             fn.append(_filename);
             _file_del = true;
-            printf("Delete Default File: "); printf(fn.c_str()); printf("\n");            
+            ESP_LOGD(TAGPARTOTA, "Delete Default File: %s", fn.c_str());
         }
 
     };
@@ -394,7 +389,7 @@ esp_err_t handler_ota_update(httpd_req_t *req)
                 std::string zw = "reboot\n";
                 httpd_resp_sendstr_chunk(req, zw.c_str());
                 httpd_resp_sendstr_chunk(req, NULL);  
-                printf("Send reboot\n");
+                ESP_LOGD(TAGPARTOTA, "Send reboot");
                 return ESP_OK;                
             }
 
@@ -418,7 +413,7 @@ esp_err_t handler_ota_update(httpd_req_t *req)
 
     if (_task.compare("unziphtml") == 0)
     {
-        printf("Task unziphmtl\n");
+        ESP_LOGD(TAGPARTOTA, "Task unziphtml");
         std::string in, out, zw;
 
         in = "/sdcard/firmware/html.zip";
@@ -435,22 +430,22 @@ esp_err_t handler_ota_update(httpd_req_t *req)
 
     if (_file_del)
     {
-        printf("Delete !! _file_del: %s\n", fn.c_str());
+        ESP_LOGD(TAGPARTOTA, "Delete !! _file_del: %s", fn.c_str());
         struct stat file_stat;
         int _result = stat(fn.c_str(), &file_stat);
-        printf("Ergebnis %d\n", _result);
+        ESP_LOGD(TAGPARTOTA, "Ergebnis %d\n", _result);
         if (_result == 0) {
-            printf("Deleting file : %s\n", fn.c_str());
+            ESP_LOGD(TAGPARTOTA, "Deleting file : %s", fn.c_str());
             /* Delete file */
             unlink(fn.c_str());
         }
         else
         {
-            printf("File does not exist: %s\n", fn.c_str());
+            ESP_LOGD(TAGPARTOTA, "File does not exist: %s", fn.c_str());
         }
         /* Respond with an empty chunk to signal HTTP response completion */
         std::string zw = "file deleted\n";
-        printf((zw + "\n").c_str());
+        ESP_LOGD(TAGPARTOTA, "%s", zw.c_str());
         httpd_resp_send(req, zw.c_str(), strlen(zw.c_str()));
         httpd_resp_send_chunk(req, NULL, 0);
         return ESP_OK;
@@ -499,7 +494,6 @@ void task_reboot(void *pvParameter)
 void doReboot(){
     LogFile.SwitchOnOff(true);
     LogFile.WriteToFile("Reboot triggered by Software (5s).");
-    ESP_LOGI(TAGPARTOTA, "Reboot in 5sec");
     LogFile.WriteToFile("Reboot in 5sec");
     xTaskCreate(&task_reboot, "reboot", configMINIMAL_STACK_SIZE * 64, NULL, 10, NULL);
     // KillTFliteTasks(); // kills itself 

+ 6 - 4
code/components/jomjol_flowcontroll/ClassFlow.cpp

@@ -3,7 +3,9 @@
 #include <string>
 #include <iostream>
 #include <string.h>
+#include "esp_log.h"
 
+static const char *TAG = "class_flow";
 
 
 void ClassFlow::SetInitialParameter(void)
@@ -105,7 +107,7 @@ std::string ClassFlow::GetParameterName(std::string _input)
     {
         _param = _input;
     }
-//    printf("Parameter: %s, Pospunkt: %d\n", _param.c_str(), _pospunkt);
+//    ESP_LOGD(TAG, "Parameter: %s, Pospunkt: %d", _param.c_str(), _pospunkt);
 	return _param;
 }
 
@@ -121,10 +123,10 @@ bool ClassFlow::getNextLine(FILE* pfile, string *rt)
 	if (!fgets(zw, 1024, pfile))
 	{
 		*rt = "";
-		printf("END OF FILE\n");
+		ESP_LOGD(TAG, "END OF FILE");
 		return false;
 	}
-	printf("%s", zw);
+	ESP_LOGD(TAG, "%s", zw);
 	*rt = zw;
 	*rt = trim(*rt);
 	while ((zw[0] == ';' || zw[0] == '#' || (rt->size() == 0)) && !(zw[1] == '['))			// Kommentarzeilen (; oder #) und Leerzeilen überspringen, es sei denn es ist ein neuer auskommentierter Paragraph
@@ -132,7 +134,7 @@ bool ClassFlow::getNextLine(FILE* pfile, string *rt)
 		*rt = "";
 		if (!fgets(zw, 1024, pfile))
 			return false;
-		printf("%s", zw);		
+		ESP_LOGD(TAG, "%s", zw);
 		*rt = zw;
 		*rt = trim(*rt);
 	}

+ 5 - 3
code/components/jomjol_flowcontroll/ClassFlowAlignment.cpp

@@ -3,11 +3,13 @@
 #include "ClassFlow.h"
 
 #include "CRotateImage.h"
+#include "esp_log.h"
 
 
 #include "ClassLogFile.h"
 
 
+static const char *TAG = "class_flow_alignment";
 
 bool AlignmentExtendedDebugging = true;
 
@@ -48,7 +50,7 @@ ClassFlowAlignment::ClassFlowAlignment(std::vector<ClassFlow*>* lfc)
 
     if (!ImageBasis)            // die Funktion Bilder aufnehmen existiert nicht --> muss erst erzeugt werden NUR ZU TESTZWECKEN
     {
-        if (AlignmentExtendedDebugging) printf("CImageBasis had to be created\n");
+        if (AlignmentExtendedDebugging) ESP_LOGD(TAG, "CImageBasis had to be created");
         ImageBasis = new CImageBasis(namerawimage);
     }
 }
@@ -174,7 +176,7 @@ bool ClassFlowAlignment::doFlow(string time)
     }
 
     if (initialmirror){
-        printf("do mirror\n");
+        ESP_LOGD(TAG, "do mirror");
         rt.Mirror();
         if (SaveAllFiles) AlignAndCutImage->SaveToFile(FormatFileName("/sdcard/img_tmp/mirror.jpg"));
     }
@@ -279,7 +281,7 @@ bool ClassFlowAlignment::LoadReferenceAlignmentValues(void)
 //    LogFile.WriteToDedicatedFile("/sdcard/alignment.txt", "LoadReferenceAlignmentValues01");      
 
     fgets(zw, 1024, pFile);
-    printf("%s", zw);
+    ESP_LOGD(TAG, "%s", zw);
 
 //    zwvalue = "LoadReferenceAlignmentValues Time: " + std::string(zw);
 

+ 95 - 72
code/components/jomjol_flowcontroll/ClassFlowCNNGeneral.cpp

@@ -7,10 +7,11 @@
 
 #include "CTfLiteClass.h"
 #include "ClassLogFile.h"
+#include "esp_log.h"
 
 static const char* TAG = "flow_analog";
 
-bool debugdetailgeneral = false;
+
 
 ClassFlowCNNGeneral::ClassFlowCNNGeneral(ClassFlowAlignment *_flowalign, t_CNNType _cnntype) : ClassFlowImage(NULL, TAG)
 {
@@ -28,7 +29,7 @@ ClassFlowCNNGeneral::ClassFlowCNNGeneral(ClassFlowAlignment *_flowalign, t_CNNTy
     flowpostalignment = _flowalign;
 }
 
-string ClassFlowCNNGeneral::getReadout(int _analog = 0, bool _extendedResolution, int prev, float _vorgaengerAnalog)
+string ClassFlowCNNGeneral::getReadout(int _analog = 0, bool _extendedResolution, int prev, float _vorgaengerAnalog, float analogDigitalTransitionStart)
 {
     string result = "";    
 
@@ -87,7 +88,7 @@ string ClassFlowCNNGeneral::getReadout(int _analog = 0, bool _extendedResolution
             {
 //                prev = ZeigerEval(GENERAL[_analog]->ROI[GENERAL[_analog]->ROI.size() - 1]->result_float, prev);
                 if (_vorgaengerAnalog >= 0)
-                    prev = ZeigerEvalHybridNeu(GENERAL[_analog]->ROI[GENERAL[_analog]->ROI.size() - 1]->result_float, _vorgaengerAnalog, prev, true);
+                    prev = ZeigerEvalHybridNeu(GENERAL[_analog]->ROI[GENERAL[_analog]->ROI.size() - 1]->result_float, _vorgaengerAnalog, prev, true, analogDigitalTransitionStart);
                 else
                     prev = ZeigerEvalHybridNeu(GENERAL[_analog]->ROI[GENERAL[_analog]->ROI.size() - 1]->result_float, prev, prev);
                 result = std::to_string(prev);
@@ -127,7 +128,7 @@ string ClassFlowCNNGeneral::getReadout(int _analog = 0, bool _extendedResolution
     return result;
 }
 
-int ClassFlowCNNGeneral::ZeigerEvalHybridNeu(float zahl, float zahl_vorgaenger, int eval_vorgaenger, bool AnalogerVorgaenger)
+int ClassFlowCNNGeneral::ZeigerEvalHybridNeu(float zahl, float zahl_vorgaenger, int eval_vorgaenger, bool AnalogerVorgaenger, float digitalAnalogTransitionStart)
 {
     int result;
     int ergebnis_nachkomma = ((int) floor(zahl * 10)) % 10;
@@ -147,7 +148,7 @@ int ClassFlowCNNGeneral::ZeigerEvalHybridNeu(float zahl, float zahl_vorgaenger,
 
     if (AnalogerVorgaenger)
     {
-        result = ZeigerEvalAnalogToDigitNeu(zahl, zahl_vorgaenger, eval_vorgaenger);
+        result = ZeigerEvalAnalogToDigitNeu(zahl, zahl_vorgaenger, eval_vorgaenger, digitalAnalogTransitionStart);
         if (debugdetailgeneral) LogFile.WriteToFile("ClassFlowCNNGeneral::ZeigerEvalHybridNeu - Analoger Vorgänger, Bewertung über ZeigerEvalAnalogNeu = " + std::to_string(result) +
                                                     " zahl: " + std::to_string(zahl) + " zahl_vorgaenger = " + std::to_string(zahl_vorgaenger)+ " eval_vorgaenger = " + std::to_string(eval_vorgaenger) + " DigitalUnschaerfe = " +  std::to_string(DigitalUnschaerfe));
         return result;
@@ -201,55 +202,49 @@ int ClassFlowCNNGeneral::ZeigerEvalHybridNeu(float zahl, float zahl_vorgaenger,
 }
 
 
-int ClassFlowCNNGeneral::ZeigerEvalAnalogToDigitNeu(float zahl, float ziffer_vorgaenger,  int eval_vorgaenger)
+int ClassFlowCNNGeneral::ZeigerEvalAnalogToDigitNeu(float zahl, float ziffer_vorgaenger,  int eval_vorgaenger, float analogDigitalTransitionStart)
 {
     int result;
     int ergebnis_nachkomma = ((int) floor(zahl * 10)) % 10;
     int ergebnis_vorkomma = ((int) floor(zahl) + 10) % 10;
-
-    if (ziffer_vorgaenger < 0)
-    {
-        result = (int) floor(zahl);
-        if (debugdetailgeneral) LogFile.WriteToFile("ClassFlowCNNGeneral::ZeigerEvalAnalogToDigitNeu - kein Vorgänger - Ergebnis = " + std::to_string(result) +
-                                                    " zahl: " + std::to_string(zahl) + " ziffer_vorgaenger = " + std::to_string(ziffer_vorgaenger) + " AnalogFehler = " +  std::to_string(AnalogFehler));
-        return result;
-    }
-
-    if (ziffer_vorgaenger <= 3 && eval_vorgaenger<9)  // Nulldurchgang hat stattgefunden (!Bewertung über Prev_value und nicht Zahl!) --> hier aufrunden (2.8 --> 3, aber auch 3.1 --> 3)
-        // aber Sonderfall ziffer_vorgaeger = 0.1 vor_vorgaenger 9.9 => eval_vorgaenger ist 9, damit hat Nulldurchgang nicht stattgefunden.
-    {
-        if (ergebnis_nachkomma > 5)
-            result =  (ergebnis_vorkomma + 1) % 10;
-        else
-            result =  ergebnis_vorkomma;
-        if (debugdetailgeneral) LogFile.WriteToFile("ClassFlowCNNGeneral::ZeigerEvalAnalogToDigitNeu - Nulldurchgang hat stattgefunden = " + std::to_string(result) +
-                                                    " zahl: " + std::to_string(zahl) + " ziffer_vorgaenger = " + std::to_string(ziffer_vorgaenger) + " DigitalUnschaerfe = " +  std::to_string(DigitalUnschaerfe));
-        return result;
+    bool roundedUp = false;
+
+    // Innerhalb der digitalen Unschaefe 
+    if (ergebnis_nachkomma >= (10-DigitalUnschaerfe * 10))  {   // Band um die Ziffer --> Runden, da Ziffer im Rahmen Ungenauigkeit erreicht
+        result = (int) (round(zahl) + 10) % 10;
+        roundedUp = true;
+        // vor/nachkomma neu berechnen, da wir anhand der Unschaefe die Zahl anpassen.
+        ergebnis_nachkomma = ((int) floor(result * 10)) % 10;
+        ergebnis_vorkomma = ((int) floor(result) + 10) % 10;
+        if (debugdetailgeneral) LogFile.WriteToFile("ClassFlowCNNGeneral::ZeigerEvalAnalogToDigitNeu - digitaleUnschaerfe - Ergebnis = " + std::to_string(result) +
+                                                    " zahl: " + std::to_string(zahl) + " ziffer_vorgaenger: " + std::to_string(ziffer_vorgaenger) +
+                                                    " erg_vorkomma: " + std::to_string(ergebnis_vorkomma) + 
+                                                    " erg_nachkomma: " + std::to_string(ergebnis_nachkomma));
+    } else {
+        result = (int) ((int) trunc(zahl) + 10) % 10;
+        if (debugdetailgeneral) LogFile.WriteToFile("ClassFlowCNNGeneral::ZeigerEvalAnalogToDigitNeu - KEINE digitaleUnschaerfe - Ergebnis = " + std::to_string(result) +
+                                                    " zahl: " + std::to_string(zahl) + " ziffer_vorgaenger = " + std::to_string(ziffer_vorgaenger));
     }
 
-    // Vorlauf ziffer_vorgaenger <=9.9 und ergebnis_nachkomma >=0..1 (digits drehen nach umschalten nicht gleich weiter)
-    // Beispiel dig=4.0, ana=9.1 ==> dig=3
+    // Kein Nulldurchgang hat stattgefunden.
+    // Nur eval_vorgaenger verwendet, da ziffer_vorgaenger hier falsch sein könnte.
+    // ziffer_vorgaenger<=0.1 & eval_vorgaenger=9 entspricht analog wurde zurückgesetzt wegen vorhergehender analog, die noch nicht auf 0 sind.
+    if ((eval_vorgaenger>=6 && (ziffer_vorgaenger>analogDigitalTransitionStart || ziffer_vorgaenger<=0.2) && roundedUp)
+        // digit läuft dem Analog vor. Darf aber erst passieren, wenn 
+        // digit wirklich schnon los läuft, deshalb 9
+        || (eval_vorgaenger>9 && ziffer_vorgaenger>analogDigitalTransitionStart && ergebnis_nachkomma<=1))
 
-    // Nachlauf ziffer_vorgaenger 0..2 und ergebnis_nachkomma 8..9
-    // Beispiel dig=6.8, ana=2.2 ==> dig=7
-    // dig=4.8, ana=5.5 => dig=4
+    {
+        result =  ((ergebnis_vorkomma+10) - 1) % 10;
+        if (debugdetailgeneral) LogFile.WriteToFile("ClassFlowCNNGeneral::ZeigerEvalAnalogToDigitNeu - Nulldurchgang noch nicht stattgefunden = " + std::to_string(result) +
+                                    " zahl: " + std::to_string(zahl) + 
+                                    " ziffer_vorgaenger = " + std::to_string(ziffer_vorgaenger) + 
+                                    " erg_nachkomma = " +  std::to_string(ergebnis_nachkomma));
 
-    // Vorlauf bei ergebnis_nachkomma >=0..1 und ziffer_vorgaenger 8..9
-    if (ergebnis_nachkomma <= 1 &&  ziffer_vorgaenger>=8)  {
-        result =  (ergebnis_vorkomma - 1 + 10) % 10;
-    } else {
-        // Ziffer bleibt bei x.8 oder x.9 "hängen", kommt also nicht richtig auf x.0
-        // muss eine Rundung erfolgen
-        // jedoch nicht im während der Transition (ziffer_vorgaenger>=8)
-         if (eval_vorgaenger<9 && ziffer_vorgaenger<8 && ergebnis_nachkomma >= 8)   
-            result = ((int) round(zahl) + 10) % 10;
-        else
-            result = ergebnis_vorkomma;
     }
-    
-    if (debugdetailgeneral) LogFile.WriteToFile("ClassFlowCNNGeneral::ZeigerEvalAnalogToDigitNeu - 9.0 --> noch kein Nulldurchgang = " + std::to_string(result) +
-                                                    " zahl: " + std::to_string(zahl) + " ziffer_vorgaenger = " + std::to_string(ziffer_vorgaenger) + " DigitalUnschaerfe = " +  std::to_string(DigitalUnschaerfe));
+
     return result;
+
 }
 
 int ClassFlowCNNGeneral::ZeigerEvalAnalogNeu(float zahl, int ziffer_vorgaenger)
@@ -317,7 +312,7 @@ bool ClassFlowCNNGeneral::ReadParameter(FILE* pfile, string& aktparamgraph)
     {
         disabled = true;
         while (getNextLine(pfile, &aktparamgraph) && !isNewParagraph(aktparamgraph));
-        printf("[Analog/Digit] is disabled !!!\n");
+        ESP_LOGD(TAG, "[Analog/Digit] is disabled!");
         return true;
     }
 
@@ -435,7 +430,7 @@ general* ClassFlowCNNGeneral::GetGENERAL(string _name, bool _create = true)
 
     _ret->ROI.push_back(neuroi);
 
-    printf("GetGENERAL - GENERAL %s - roi %s - CCW: %d\n", _analog.c_str(), _roi.c_str(), neuroi->CCW);
+    ESP_LOGD(TAG, "GetGENERAL - GENERAL %s - roi %s - CCW: %d", _analog.c_str(), _roi.c_str(), neuroi->CCW);
 
     return _ret;
 }
@@ -494,7 +489,7 @@ bool ClassFlowCNNGeneral::doAlignAndCut(string time)
     for (int _ana = 0; _ana < GENERAL.size(); ++_ana)
         for (int i = 0; i < GENERAL[_ana]->ROI.size(); ++i)
         {
-            printf("General %d - Align&Cut\n", i);
+            ESP_LOGD(TAG, "General %d - Align&Cut", i);
             
             caic->CutAndSave(GENERAL[_ana]->ROI[i]->posx, GENERAL[_ana]->ROI[i]->posy, GENERAL[_ana]->ROI[i]->deltax, GENERAL[_ana]->ROI[i]->deltay, GENERAL[_ana]->ROI[i]->image_org);
             if (SaveAllFiles)
@@ -551,10 +546,9 @@ bool ClassFlowCNNGeneral::getNetworkParameter()
     CTfLiteClass *tflite = new CTfLiteClass;  
     string zwcnn = "/sdcard" + cnnmodelfile;
     zwcnn = FormatFileName(zwcnn);
-    printf(zwcnn.c_str());printf("\n");
+    ESP_LOGD(TAG, "%s", zwcnn.c_str());
     if (!tflite->LoadModel(zwcnn)) {
-        printf("Can't read model file /sdcard%s\n", cnnmodelfile.c_str());
-        LogFile.WriteToFile("Cannot load model");
+        LogFile.WriteToFile("Can't read model file /sdcard%s", cnnmodelfile.c_str());
         delete tflite;
         return false;
     } 
@@ -572,37 +566,37 @@ bool ClassFlowCNNGeneral::getNetworkParameter()
         {
             case 2:
                 CNNType = Analogue;
-                printf("TFlite-Type set to Analogue\n");
+                ESP_LOGD(TAG, "TFlite-Type set to Analogue");
                 break;
             case 10:
                 CNNType = DoubleHyprid10;
-                printf("TFlite-Type set to DoubleHyprid10\n");
+                ESP_LOGD(TAG, "TFlite-Type set to DoubleHyprid10");
                 break;
             case 11:
                 CNNType = Digital;
-                printf("TFlite-Type set to Digital\n");
+                ESP_LOGD(TAG, "TFlite-Type set to Digital");
                 break;
 /*            case 20:
                 CNNType = DigitalHyprid10;
-                printf("TFlite-Type set to DigitalHyprid10\n");
+                ESP_LOGD(TAG, "TFlite-Type set to DigitalHyprid10");
                 break;
 */
 //            case 22:
 //                CNNType = DigitalHyprid;
-//                printf("TFlite-Type set to DigitalHyprid\n");
+//                ESP_LOGD(TAG, "TFlite-Type set to DigitalHyprid");
 //                break;
              case 100:
                 if (modelxsize==32 && modelysize == 32) {
                     CNNType = Analogue100;
-                    printf("TFlite-Type set to Analogue100\n");
+                    ESP_LOGD(TAG, "TFlite-Type set to Analogue100");
                 } else {
                     CNNType = Digital100;
-                    printf("TFlite-Type set to Digital\n");
+                    ESP_LOGD(TAG, "TFlite-Type set to Digital");
                 }
                 break;
             default:
                 LogFile.WriteToFile("ERROR ERROR ERROR - tflite passt nicht zur Firmware - ERROR ERROR ERROR (outout_dimension=" + std::to_string(_anzoutputdimensions) + ")");
-                printf("ERROR ERROR ERROR - tflite passt nicht zur Firmware - ERROR ERROR ERROR\n");
+                ESP_LOGD(TAG, "ERROR ERROR ERROR - tflite passt nicht zur Firmware - ERROR ERROR ERROR");
         }
     }
 
@@ -620,10 +614,9 @@ bool ClassFlowCNNGeneral::doNeuralNetwork(string time)
     CTfLiteClass *tflite = new CTfLiteClass;  
     string zwcnn = "/sdcard" + cnnmodelfile;
     zwcnn = FormatFileName(zwcnn);
-    printf(zwcnn.c_str());printf("\n");
+    ESP_LOGD(TAG, "%s", zwcnn.c_str());
     if (!tflite->LoadModel(zwcnn)) {
-        printf("Can't read model file /sdcard%s\n", cnnmodelfile.c_str());
-        LogFile.WriteToFile("Cannot load model");
+        LogFile.WriteToFile("Can't read model file /sdcard%s", cnnmodelfile.c_str());
 
         delete tflite;
         return false;
@@ -634,7 +627,7 @@ bool ClassFlowCNNGeneral::doNeuralNetwork(string time)
     {
         for (int i = 0; i < GENERAL[_ana]->ROI.size(); ++i)
         {
-            printf("General %d - TfLite\n", i);
+            ESP_LOGD(TAG, "General %d - TfLite", i);
 
             switch (CNNType) {
                 case Analogue:
@@ -655,7 +648,7 @@ bool ClassFlowCNNGeneral::doNeuralNetwork(string time)
                         else
                             GENERAL[_ana]->ROI[i]->result_float = result * 10;
                               
-                        printf("Result General(Analog)%i - CCW: %d -  %f\n", i, GENERAL[_ana]->ROI[i]->CCW, GENERAL[_ana]->ROI[i]->result_float); 
+                        ESP_LOGD(TAG, "Result General(Analog)%i - CCW: %d -  %f", i, GENERAL[_ana]->ROI[i]->CCW, GENERAL[_ana]->ROI[i]->result_float);
                         if (isLogImage)
                             LogImage(logPath, GENERAL[_ana]->ROI[i]->name, &GENERAL[_ana]->ROI[i]->result_float, NULL, time, GENERAL[_ana]->ROI[i]->image_org);
                     } break;
@@ -664,7 +657,7 @@ bool ClassFlowCNNGeneral::doNeuralNetwork(string time)
                     {
                         GENERAL[_ana]->ROI[i]->result_klasse = 0;
                         GENERAL[_ana]->ROI[i]->result_klasse = tflite->GetClassFromImageBasis(GENERAL[_ana]->ROI[i]->image);
-                        printf("Result General(Digit)%i: %d\n", i, GENERAL[_ana]->ROI[i]->result_klasse);
+                        ESP_LOGD(TAG, "Result General(Digit)%i: %d", i, GENERAL[_ana]->ROI[i]->result_klasse);
 
                         if (isLogImage)
                         {
@@ -701,7 +694,7 @@ bool ClassFlowCNNGeneral::doNeuralNetwork(string time)
                         else
                             GENERAL[_ana]->ROI[i]->result_float = fmod((double) _num + (((double)_nachkomma)-5)/10 + (double) 10, 10);
 
-                        printf("Result General(DigitalHyprid)%i: %f\n", i, GENERAL[_ana]->ROI[i]->result_float); 
+                        ESP_LOGD(TAG, "Result General(DigitalHyprid)%i: %f\n", i, GENERAL[_ana]->ROI[i]->result_float);
                         _zwres = "Result General(DigitalHyprid)" + to_string(i) + ": " + to_string(GENERAL[_ana]->ROI[i]->result_float);
                         if (debugdetailgeneral) LogFile.WriteToFile(_zwres);
 
@@ -738,7 +731,7 @@ bool ClassFlowCNNGeneral::doNeuralNetwork(string time)
 
                         GENERAL[_ana]->ROI[i]->result_float = fmod((double) _num + (((double)_nachkomma)-5)/10 + (double) 10, 10);
 
-                        printf("Result General(DigitalHyprid)%i: %f\n", i, GENERAL[_ana]->ROI[i]->result_float); 
+                        ESP_LOGD(TAG, "Result General(DigitalHyprid)%i: %f\n", i, GENERAL[_ana]->ROI[i]->result_float);
                         _zwres = "Result General(DigitalHyprid)" + to_string(i) + ": " + to_string(GENERAL[_ana]->ROI[i]->result_float);
                         if (debugdetailgeneral) LogFile.WriteToFile(_zwres);
 
@@ -798,7 +791,7 @@ bool ClassFlowCNNGeneral::doNeuralNetwork(string time)
                         string zw = "_num (p, m): " + to_string(_num) + " " + to_string(_numplus) + " " + to_string(_numminus);
                         zw = zw + " _val (p, m): " + to_string(_val) + " " + to_string(_valplus) + " " + to_string(_valminus);
                         zw = zw + " result: " + to_string(result) + " _fit: " + to_string(_fit);
-                        printf("details cnn: %s\n", zw.c_str());
+                        ESP_LOGD(TAG, "details cnn: %s", zw.c_str());
                         LogFile.WriteToFile(zw);
 
 
@@ -809,8 +802,7 @@ bool ClassFlowCNNGeneral::doNeuralNetwork(string time)
                             GENERAL[_ana]->ROI[i]->isReject = true;
                             result = -1;
                             _result_save_file+= 100;     // Für den Fall, dass fit nicht ausreichend, soll trotzdem das Ergebnis mit "-10x.y" abgespeichert werden.
-                            string zw = "Value Rejected due to Threshold (Fit: " + to_string(_fit) + "Threshold: " + to_string(CNNGoodThreshold);
-                            printf("Value Rejected due to Threshold (Fit: %f, Threshold: %f\n", _fit, CNNGoodThreshold);
+                            string zw = "Value Rejected due to Threshold (Fit: " + to_string(_fit) + "Threshold: " + to_string(CNNGoodThreshold) + ")";
                             LogFile.WriteToFile(zw);
                         }
                         else
@@ -820,7 +812,7 @@ bool ClassFlowCNNGeneral::doNeuralNetwork(string time)
 
 
                         GENERAL[_ana]->ROI[i]->result_float = result;
-                        printf("Result General(Analog)%i: %f\n", i, GENERAL[_ana]->ROI[i]->result_float); 
+                        ESP_LOGD(TAG, "Result General(Analog)%i: %f", i, GENERAL[_ana]->ROI[i]->result_float);
 
                         if (isLogImage)
                         {
@@ -858,7 +850,7 @@ bool ClassFlowCNNGeneral::doNeuralNetwork(string time)
                         
                         GENERAL[_ana]->ROI[i]->isReject = false;
                         
-                        printf("Result General(Analog)%i - CCW: %d -  %f\n", i, GENERAL[_ana]->ROI[i]->CCW, GENERAL[_ana]->ROI[i]->result_float); 
+                        ESP_LOGD(TAG, "Result General(Analog)%i - CCW: %d -  %f", i, GENERAL[_ana]->ROI[i]->CCW, GENERAL[_ana]->ROI[i]->result_float);
 
                         if (isLogImage)
                         {
@@ -904,7 +896,7 @@ std::vector<HTMLInfo*> ClassFlowCNNGeneral::GetHTMLInfo()
     for (int _ana = 0; _ana < GENERAL.size(); ++_ana)
         for (int i = 0; i < GENERAL[_ana]->ROI.size(); ++i)
         {
-            printf("Image: %d\n", (int) GENERAL[_ana]->ROI[i]->image);
+            ESP_LOGD(TAG, "Image: %d", (int) GENERAL[_ana]->ROI[i]->image);
             if (GENERAL[_ana]->ROI[i]->image)
             {
                 if (GENERAL[_ana]->name == "default")
@@ -976,3 +968,34 @@ void ClassFlowCNNGeneral::UpdateNameNumbers(std::vector<std::string> *_name_numb
             (*_name_numbers).push_back(_name);
     }
 }
+
+string ClassFlowCNNGeneral::getReadoutRawString(int _analog) 
+{
+    string rt = "";
+
+    if (GENERAL[_analog]->ROI.size() == 0)
+        return rt;
+ 
+    for (int i = 0; i < GENERAL[_analog]->ROI.size(); ++i)
+    {
+        if (CNNType == Analogue || CNNType == Analogue100)
+        {
+            rt = rt + "\t" + RundeOutput(GENERAL[_analog]->ROI[i]->result_float, 1);
+        }
+
+        if (CNNType == Digital)
+        {
+            if (GENERAL[_analog]->ROI[i]->result_klasse == 10)
+                rt = rt + "\tN";
+            else
+                rt = rt + "\t" + RundeOutput(GENERAL[_analog]->ROI[i]->result_klasse, 0);
+        }
+
+        if ((CNNType == DoubleHyprid10) || (CNNType == Digital100))
+        {
+            rt = rt + "\t" + RundeOutput(GENERAL[_analog]->ROI[i]->result_float, 1);
+        }
+    }
+    return rt;
+}
+

+ 6 - 4
code/components/jomjol_flowcontroll/ClassFlowCNNGeneral.h

@@ -20,6 +20,7 @@ class ClassFlowCNNGeneral :
     public ClassFlowImage
 {
 protected:
+    bool debugdetailgeneral = true;
     t_CNNType CNNType;
     std::vector<general*> GENERAL;
     float CNNGoodThreshold;
@@ -28,7 +29,6 @@ protected:
     float DigitalUnschaerfe = 0.2;
     int DigitalBand = 3;
     float DigitalAnalogerVorgaengerUebergangsbereich = 2;
-    // nicht mehr benötigt float DigitalUebergangsbereichVorgaengerAnalogToDigit = 1; // war vorher 2
     float DigitalUebergangsbereichVorgaenger = 0.7; // 9.3 - 0.7
     float DigitalUebergangsbereichVorlauf = 9.7; // Vorlauf-Nulldurchgang passiert erst ab ca. 9.7
 
@@ -41,8 +41,8 @@ protected:
     bool SaveAllFiles;   
 
     int ZeigerEvalAnalogNeu(float zahl, int ziffer_vorgaenger);
-    int ZeigerEvalAnalogToDigitNeu(float zahl, float ziffer_vorgaenger,  int eval_vorgaenger);
-    int ZeigerEvalHybridNeu(float zahl, float zahl_vorgaenger, int eval_vorgaenger, bool AnalogerVorgaenger = false);
+    int ZeigerEvalAnalogToDigitNeu(float zahl, float ziffer_vorgaenger,  int eval_vorgaenger, float analogDigitalTransitionStart);
+    int ZeigerEvalHybridNeu(float zahl, float zahl_vorgaenger, int eval_vorgaenger, bool AnalogerVorgaenger = false, float analogDigitalTransitionStart=9.2);
 
 
 
@@ -58,7 +58,9 @@ public:
     bool doFlow(string time);
 
     string getHTMLSingleStep(string host);
-    string getReadout(int _analog, bool _extendedResolution = false, int prev = -1, float _vorgaengerAnalog = -1);   
+    string getReadout(int _analog, bool _extendedResolution = false, int prev = -1, float _vorgaengerAnalog = -1, float analogDigitalTransitionStart=9.2); 
+
+    string getReadoutRawString(int _analog);  
 
     void DrawROI(CImageBasis *_zw); 
 

+ 11 - 12
code/components/jomjol_flowcontroll/ClassFlowControll.cpp

@@ -33,7 +33,7 @@ static const char* TAG = "flow_controll";
 std::string ClassFlowControll::doSingleStep(std::string _stepname, std::string _host){
     std::string _classname = "";
     std::string result = "";
-//    printf("_stepname: %s\n", _stepname.c_str());
+//    ESP_LOGD(TAG, "_stepname: %s", _stepname.c_str());
     if ((_stepname.compare("[MakeImage]") == 0) || (_stepname.compare(";[MakeImage]") == 0)){
         _classname = "ClassFlowMakeImage";
     }
@@ -89,7 +89,7 @@ std::vector<HTMLInfo*> ClassFlowControll::GetAllDigital()
 {
     if (flowdigit)
     {
-        printf("ClassFlowControll::GetAllDigital - flowdigit != NULL\n");
+        ESP_LOGD(TAG, "ClassFlowControll::GetAllDigital - flowdigit != NULL");
         return flowdigit->GetHTMLInfo();
     }
 
@@ -230,7 +230,7 @@ void ClassFlowControll::InitFlow(std::string config)
     if (pFile != NULL)
     {
         fgets(zw, 1024, pFile);
-        printf("%s", zw);
+        ESP_LOGD(TAG, "%s", zw);
         line = std::string(zw);
     }
 
@@ -239,7 +239,7 @@ void ClassFlowControll::InitFlow(std::string config)
         cfc = CreateClassFlow(line);
         if (cfc)
         {
-            printf("Start ReadParameter (%s)\n", line.c_str());
+            ESP_LOGD(TAG, "Start ReadParameter (%s)", line.c_str());
             cfc->ReadParameter(pFile, line);
         }
         else
@@ -247,7 +247,7 @@ void ClassFlowControll::InitFlow(std::string config)
             line = "";
             if (fgets(zw, 1024, pFile) && !feof(pFile))
                 {
-                    printf("Read: %s", zw);
+                    ESP_LOGD(TAG, "Read: %s", zw);
                     line = std::string(zw);
                 }
         }
@@ -362,7 +362,7 @@ string ClassFlowControll::getReadoutAll(int _type)
             if (i < (*numbers).size()-1)
                 out = out + "\r\n";
         }
-    //    printf("OUT: %s", out.c_str());
+    //    ESP_LOGD(TAG, "OUT: %s", out.c_str());
     }
 
     return out;
@@ -408,7 +408,7 @@ std::string ClassFlowControll::UpdatePrevalue(std::string _newvalue, std::string
     char* p;
 
     _newvalue = trim(_newvalue);
-//    printf("Input UpdatePreValue: %s\n", _newvalue.c_str());
+//    ESP_LOGD(TAG, "Input UpdatePreValue: %s", _newvalue.c_str());
 
     if (_newvalue.compare("0.0") == 0)
     {
@@ -493,9 +493,8 @@ bool ClassFlowControll::ReadParameter(FILE* pfile, string& aktparamgraph)
             {
                 // reboot notwendig damit die neue wlan.ini auch benutzt wird !!!
                 fclose(pfile);
-                printf("do reboot\n");
                 LogFile.SwitchOnOff(true);
-                LogFile.WriteToFile("Reboot to activate new HOSTNAME.");
+                LogFile.WriteToFile("Rebooting to activate new HOSTNAME...");
                 esp_restart();
                 hard_restart();                   
                 doReboot();
@@ -558,7 +557,7 @@ esp_err_t ClassFlowControll::SendRawJPG(httpd_req_t *req)
 
 esp_err_t ClassFlowControll::GetJPGStream(std::string _fn, httpd_req_t *req)
 {
-    printf("ClassFlowControll::GetJPGStream %s\n", _fn.c_str());
+    ESP_LOGD(TAG, "ClassFlowControll::GetJPGStream %s", _fn.c_str());
 
     CImageBasis *_send = NULL;
     esp_err_t result = ESP_FAIL;
@@ -566,7 +565,7 @@ esp_err_t ClassFlowControll::GetJPGStream(std::string _fn, httpd_req_t *req)
 
     if (flowalignment == NULL)
     {
-        printf("Can't continue, flowalignment is NULL\n");
+        ESP_LOGD(TAG, "Can't continue, flowalignment is NULL");
         return ESP_FAIL;
     }
 
@@ -589,7 +588,7 @@ esp_err_t ClassFlowControll::GetJPGStream(std::string _fn, httpd_req_t *req)
         {
             std::vector<HTMLInfo*> htmlinfo;
             htmlinfo = GetAllDigital();
-            printf("After getClassFlowControll::GetAllDigital\n");
+            ESP_LOGD(TAG, "After getClassFlowControll::GetAllDigital");
 
             for (int i = 0; i < htmlinfo.size(); ++i)
             {

+ 1 - 0
code/components/jomjol_flowcontroll/ClassFlowDefineTypes.h

@@ -46,6 +46,7 @@ struct NumberPost {
     int AnzahlDigital;
     int DecimalShift;
     int DecimalShiftInitial;
+    float AnalogDigitalTransitionStart; // Wann ist das digit > x.1, also wann fängt es an zu kippen
     int Nachkomma;
 
     bool isExtendedResolution;

+ 8 - 6
code/components/jomjol_flowcontroll/ClassFlowImage.cpp

@@ -14,6 +14,8 @@ extern "C" {
 #include "time_sntp.h"
 #include "ClassLogFile.h"
 #include "CImageBasis.h"
+#include "esp_log.h"
+
 
 ClassFlowImage::ClassFlowImage(const char* logTag)
 {
@@ -45,7 +47,6 @@ string ClassFlowImage::CreateLogFolder(string time) {
 	string logPath = LogImageLocation + "/" + time.LOGFILE_TIME_FORMAT_DATE_EXTR + "/" + time.LOGFILE_TIME_FORMAT_HOUR_EXTR;
     isLogImage = mkdir_r(logPath.c_str(), S_IRWXU) == 0;
     if (!isLogImage) {
-        ESP_LOGW(logTag, "Can't create log folder for analog images. Path %s", logPath.c_str());
         LogFile.WriteToFile("Can't create log folder for analog images. Path " + logPath);
     }
 
@@ -65,7 +66,7 @@ void ClassFlowImage::LogImage(string logPath, string name, float *resultFloat, i
         else
         {
             sprintf(buf, "%.1f_", *resultFloat);
-            if (strcmp(buf, "10.0_"))
+            if (strcmp(buf, "10.0_") == 0)
                 sprintf(buf, "0.0_");
         }
             
@@ -79,7 +80,7 @@ void ClassFlowImage::LogImage(string logPath, string name, float *resultFloat, i
 	nm = FormatFileName(nm);
 	string output = "/sdcard/img_tmp/" + name + ".jpg";
 	output = FormatFileName(output);
-	printf("save to file: %s\n", nm.c_str());
+	ESP_LOGD(logTag, "save to file: %s", nm.c_str());
 	_img->SaveToFile(nm);
 //	CopyFile(output, nm);
 }
@@ -119,14 +120,15 @@ void ClassFlowImage::RemoveOldLogs()
         string folderPath = LogImageLocation + "/" + entry->d_name;
 		if (entry->d_type == DT_DIR) {
 			//ESP_LOGI(logTag, "Compare %s %s", entry->d_name, folderName.c_str());	
-			if ((strlen(entry->d_name) == folderName.length()) && (strcmp(entry->d_name, folderName.c_str()) < 0)) {
-                deleted += removeFolder(folderPath.c_str(), logTag);
+			if ((strlen(entry->d_name) == folderName.length()) && (strcmp(entry->d_name, folderName.c_str()) == 0)) {
+                removeFolder(folderPath.c_str(), logTag);
+                deleted++;
 			} else {
                 notDeleted ++;
             }
 		}
     }
-    ESP_LOGI(logTag, "%d older log files deleted. %d current log files not deleted.", deleted, notDeleted);
+    LogFile.WriteToFile("Image folder deleted: " + std::to_string(deleted) + ". Image folder not deleted: " + std::to_string(notDeleted));	
     closedir(dir);
 }
 

+ 6 - 3
code/components/jomjol_flowcontroll/ClassFlowInfluxDB.cpp

@@ -6,9 +6,12 @@
 #include "time_sntp.h"
 #include "interface_influxdb.h"
 #include "ClassFlowPostProcessing.h"
+#include "esp_log.h"
 
 #include <time.h>
 
+static const char* TAG = "class_flow_influxDb";
+
 void ClassFlowInfluxDB::SetInitialParameter(void)
 {
     uri = "";
@@ -76,7 +79,7 @@ bool ClassFlowInfluxDB::ReadParameter(FILE* pfile, string& aktparamgraph)
 
     while (this->getNextLine(pfile, &aktparamgraph) && !this->isNewParagraph(aktparamgraph))
     {
-        printf("while loop reading line: %s\n", aktparamgraph.c_str());
+        ESP_LOGD(TAG, "while loop reading line: %s", aktparamgraph.c_str());
         zerlegt = this->ZerlegeZeile(aktparamgraph);
         if ((toUpper(zerlegt[0]) == "USER") && (zerlegt.size() > 1))
         {
@@ -102,11 +105,11 @@ bool ClassFlowInfluxDB::ReadParameter(FILE* pfile, string& aktparamgraph)
 
     if ((uri.length() > 0) && (database.length() > 0) && (measurement.length() > 0)) 
     { 
-        printf("Init InfluxDB with uri: %s, measurement: %s, user: %s, password: %s\n", uri.c_str(), measurement.c_str(), user.c_str(), password.c_str());
+        ESP_LOGD(TAG, "Init InfluxDB with uri: %s, measurement: %s, user: %s, password: %s", uri.c_str(), measurement.c_str(), user.c_str(), password.c_str());
         InfluxDBInit(uri, database, measurement, user, password); 
         InfluxDBenable = true;
     } else {
-        printf("InfluxDB init skipped as we are missing some parameters");
+        ESP_LOGD(TAG, "InfluxDB init skipped as we are missing some parameters");
     }
    
     return true;

+ 7 - 5
code/components/jomjol_flowcontroll/ClassFlowMQTT.cpp

@@ -12,6 +12,8 @@
 
 #define __HIDE_PASSWORD
 
+static const char *TAG = "class_flow_MQTT";
+
 void ClassFlowMQTT::SetInitialParameter(void)
 {
     uri = "";
@@ -120,19 +122,19 @@ bool ClassFlowMQTT::ReadParameter(FILE* pfile, string& aktparamgraph)
     }
 
 #ifdef __HIDE_PASSWORD
-    printf("Init Read with uri: %s, clientname: %s, user: %s, password: XXXXXX, maintopic: %s\n", uri.c_str(), clientname.c_str(), user.c_str(), mainerrortopic.c_str());
+    ESP_LOGD(TAG, "Init Read with uri: %s, clientname: %s, user: %s, password: XXXXXX, maintopic: %s", uri.c_str(), clientname.c_str(), user.c_str(), mainerrortopic.c_str());
 #else
-    printf("Init Read with uri: %s, clientname: %s, user: %s, password: %s, maintopic: %s\n", uri.c_str(), clientname.c_str(), user.c_str(), password.c_str(), mainerrortopic.c_str());
+    ESP_LOGD(TAG, "Init Read with uri: %s, clientname: %s, user: %s, password: %s, maintopic: %s", uri.c_str(), clientname.c_str(), user.c_str(), password.c_str(), mainerrortopic.c_str());
 #endif
 
     if (!MQTTisConnected() && (uri.length() > 0) && (maintopic.length() > 0)) 
     { 
-        printf("InitMQTTInit\n");
+        ESP_LOGD(TAG, "InitMQTTInit");
         mainerrortopic = maintopic + "/connection";
 #ifdef __HIDE_PASSWORD
-        printf("Init MQTT with uri: %s, clientname: %s, user: %s, password: XXXXXXXX, maintopic: %s\n", uri.c_str(), clientname.c_str(), user.c_str(), mainerrortopic.c_str());
+        ESP_LOGD(TAG, "Init MQTT with uri: %s, clientname: %s, user: %s, password: XXXXXXXX, maintopic: %s", uri.c_str(), clientname.c_str(), user.c_str(), mainerrortopic.c_str());
 #else
-        printf("Init MQTT with uri: %s, clientname: %s, user: %s, password: %s, maintopic: %s\n", uri.c_str(), clientname.c_str(), user.c_str(), password.c_str(), mainerrortopic.c_str());
+        ESP_LOGD(TAG, "Init MQTT with uri: %s, clientname: %s, user: %s, password: %s, maintopic: %s", uri.c_str(), clientname.c_str(), user.c_str(), password.c_str(), mainerrortopic.c_str());
 #endif
         if (!MQTTInit(uri, clientname, user, password, mainerrortopic, keepAlive))
         { // Failed

+ 3 - 2
code/components/jomjol_flowcontroll/ClassFlowMakeImage.cpp

@@ -6,6 +6,7 @@
 #include "ClassControllCamera.h"
 
 #include "esp_wifi.h"
+#include "esp_log.h"
 
 #include <time.h>
 
@@ -30,7 +31,7 @@ void ClassFlowMakeImage::takePictureWithFlash(int flashdauer)
     rawImage->width = image_width;          
     rawImage->height = image_height;
     /////////////////////////////////////////////////////////////////////////////////////
-    printf("Flashdauer: %d\n", flashdauer);
+    ESP_LOGD(TAG, "Flashdauer: %d", flashdauer);
     Camera.CaptureToBasisImage(rawImage, flashdauer);
     time(&TimeImageTaken);
     localtime(&TimeImageTaken);
@@ -145,7 +146,7 @@ bool ClassFlowMakeImage::ReadParameter(FILE* pfile, string& aktparamgraph)
     waitbeforepicture_store = waitbeforepicture;
     if (FixedExposure && (waitbeforepicture > 0))
     {
-//        printf("Fixed Exposure enabled!\n");
+//        ESP_LOGD(TAG, "Fixed Exposure enabled!");
         int flashdauer = (int) (waitbeforepicture * 1000);
         Camera.EnableAutoExposure(flashdauer);
         waitbeforepicture = 0.2;

+ 109 - 43
code/components/jomjol_flowcontroll/ClassFlowPostProcessing.cpp

@@ -9,6 +9,11 @@
 #include <time.h>
 
 #include "time_sntp.h"
+
+#include "esp_log.h"
+
+static const char* TAG = "class_flow_postproc";
+
 //#define SERIAL_DEBUG // testing debug on serial enabled
 
 
@@ -72,10 +77,10 @@ string ClassFlowPostProcessing::GetPreValue(std::string _number)
 
 void ClassFlowPostProcessing::SetPreValue(double zw, string _numbers, bool _extern)
 {
-    printf("SetPrevalue: %f, %s\n", zw, _numbers.c_str());
+    ESP_LOGD(TAG, "SetPrevalue: %f, %s", zw, _numbers.c_str());
     for (int j = 0; j < NUMBERS.size(); ++j)
     {
-//        printf("Number %d, %s\n", j, NUMBERS[j]->name.c_str());
+//        ESP_LOGD(TAG, "Number %d, %s", j, NUMBERS[j]->name.c_str());
         if (NUMBERS[j]->name == _numbers)
         {
             NUMBERS[j]->PreValue = zw;
@@ -86,7 +91,7 @@ void ClassFlowPostProcessing::SetPreValue(double zw, string _numbers, bool _exte
                 time(&(NUMBERS[j]->lastvalue));
                 localtime(&(NUMBERS[j]->lastvalue));
             }
-//            printf("Found %d! - set to %f\n", j,  NUMBERS[j]->PreValue);
+//            ESP_LOGD(TAG, "Found %d! - set to %f", j,  NUMBERS[j]->PreValue);
         }
     }
     UpdatePreValueINI = true;
@@ -110,7 +115,7 @@ bool ClassFlowPostProcessing::LoadPreValue(void)
         return false;
 
     fgets(zw, 1024, pFile);
-    printf("Read line Prevalue.ini: %s", zw);
+    ESP_LOGD(TAG, "Read line Prevalue.ini: %s", zw);
     zwtime = trim(std::string(zw));
     if (zwtime.length() == 0)
         return false;
@@ -161,7 +166,7 @@ bool ClassFlowPostProcessing::LoadPreValue(void)
                 _done = true;
             else
             {
-                printf("Read line Prevalue.ini: %s", zw);
+                ESP_LOGD(TAG, "Read line Prevalue.ini: %s", zw);
                 zerlegt = HelperZerlegeZeile(trim(std::string(zw)), "\t");
                 if (zerlegt.size() > 1)
                 {
@@ -177,7 +182,7 @@ bool ClassFlowPostProcessing::LoadPreValue(void)
     {
         fgets(zw, 1024, pFile);
         fclose(pFile);
-        printf("%s", zw);
+        ESP_LOGD(TAG, "%s", zw);
         zwvalue = trim(std::string(zw));
         NUMBERS[0]->PreValue = stod(zwvalue.c_str());
 
@@ -194,7 +199,7 @@ bool ClassFlowPostProcessing::LoadPreValue(void)
         whenStart.tm_sec = ss;
         whenStart.tm_isdst = -1;
 
-        printf("TIME: %d, %d, %d, %d, %d, %d\n", whenStart.tm_year, whenStart.tm_mon, whenStart.tm_wday, whenStart.tm_hour, whenStart.tm_min, whenStart.tm_sec);
+        ESP_LOGD(TAG, "TIME: %d, %d, %d, %d, %d, %d", whenStart.tm_year, whenStart.tm_mon, whenStart.tm_wday, whenStart.tm_hour, whenStart.tm_min, whenStart.tm_sec);
 
         NUMBERS[0]->lastvalue = mktime(&whenStart);
 
@@ -236,10 +241,10 @@ void ClassFlowPostProcessing::SavePreValue()
         struct tm* timeinfo = localtime(&NUMBERS[j]->lastvalue);
         strftime(buffer, 80, PREVALUE_TIME_FORMAT_OUTPUT, timeinfo);
         NUMBERS[j]->timeStamp = std::string(buffer);
-//        printf("SaverPreValue %d, Value: %f, Nachkomma %d\n", j, NUMBERS[j]->PreValue, NUMBERS[j]->Nachkomma);
+//        ESP_LOGD(TAG, "SaverPreValue %d, Value: %f, Nachkomma %d", j, NUMBERS[j]->PreValue, NUMBERS[j]->Nachkomma);
 
         _zw = NUMBERS[j]->name + "\t" + NUMBERS[j]->timeStamp + "\t" + RundeOutput(NUMBERS[j]->PreValue, NUMBERS[j]->Nachkomma) + "\n";
-        printf("Write PreValue Zeile: %s\n", _zw.c_str());
+        ESP_LOGD(TAG, "Write PreValue Zeile: %s", _zw.c_str());
         if (pFile) {
             fputs(_zw.c_str(), pFile);
         }
@@ -278,7 +283,7 @@ void ClassFlowPostProcessing::handleDecimalExtendedResolution(string _decsep, st
 {
     string _digit, _decpos;
     int _pospunkt = _decsep.find_first_of(".");
-//    printf("Name: %s, Pospunkt: %d\n", _decsep.c_str(), _pospunkt);
+//    ESP_LOGD(TAG, "Name: %s, Pospunkt: %d", _decsep.c_str(), _pospunkt);
     if (_pospunkt > -1)
         _digit = _decsep.substr(0, _pospunkt);
     else
@@ -308,7 +313,7 @@ void ClassFlowPostProcessing::handleDecimalSeparator(string _decsep, string _val
 {
     string _digit, _decpos;
     int _pospunkt = _decsep.find_first_of(".");
-//    printf("Name: %s, Pospunkt: %d\n", _decsep.c_str(), _pospunkt);
+//    ESP_LOGD(TAG, "Name: %s, Pospunkt: %d", _decsep.c_str(), _pospunkt);
     if (_pospunkt > -1)
         _digit = _decsep.substr(0, _pospunkt);
     else
@@ -324,7 +329,7 @@ void ClassFlowPostProcessing::handleDecimalSeparator(string _decsep, string _val
         }
 /*        catch(const std::exception& e)
         {
-            printf("ERROR - Decimalshift is not a number: %s\n", _value.c_str());
+            ESP_LOGD(TAG, "ERROR - Decimalshift is not a number: %s", _value.c_str());
         }
 */        
         if (_digit == "default")                        // erstmal auf default setzen (falls sonst nichts gesetzt)
@@ -343,13 +348,36 @@ void ClassFlowPostProcessing::handleDecimalSeparator(string _decsep, string _val
     }
 }
 
+void ClassFlowPostProcessing::handleAnalogDigitalTransitionStart(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 < NUMBERS.size(); ++j)
+    {
+        float _zwdc = 9.2;
+        {
+            _zwdc = stof(_value);
+        }
+        if (_digit == "default" || NUMBERS[j]->name == _digit)  // erstmal auf default setzen (falls sonst nichts gesetzt)
+        {
+            NUMBERS[j]->AnalogDigitalTransitionStart = _zwdc;
+
+        }
+    }
+}
 
 
 void ClassFlowPostProcessing::handleMaxRateType(string _decsep, string _value)
 {
     string _digit, _decpos;
     int _pospunkt = _decsep.find_first_of(".");
-//    printf("Name: %s, Pospunkt: %d\n", _decsep.c_str(), _pospunkt);
+//    ESP_LOGD(TAG, "Name: %s, Pospunkt: %d", _decsep.c_str(), _pospunkt);
     if (_pospunkt > -1)
         _digit = _decsep.substr(0, _pospunkt);
     else
@@ -376,36 +404,33 @@ void ClassFlowPostProcessing::handleMaxRateType(string _decsep, string _value)
 
 
 
+
 void ClassFlowPostProcessing::handleMaxRateValue(string _decsep, string _value)
 {
     string _digit, _decpos;
     int _pospunkt = _decsep.find_first_of(".");
-//    printf("Name: %s, Pospunkt: %d\n", _decsep.c_str(), _pospunkt);
+//    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 < NUMBERS.size(); ++j)
     {
         float _zwdc = 1;
-
 //        try
         {
             _zwdc = stof(_value);
         }
 /*        catch(const std::exception& e)
         {
-            printf("ERROR - MaxRateValue is not a number: %s\n", _value.c_str());
+            ESP_LOGD(TAG, "ERROR - MaxRateValue is not a number: %s", _value.c_str());
         }
 */
-
         if (_digit == "default")                        // erstmal auf default setzen (falls sonst nichts gesetzt)
         {
             NUMBERS[j]->useMaxRateValue = true;
             NUMBERS[j]->MaxRateValue = _zwdc;
         }
-
         if (NUMBERS[j]->name == _digit)
         {
             NUMBERS[j]->useMaxRateValue = true;
@@ -447,6 +472,10 @@ bool ClassFlowPostProcessing::ReadParameter(FILE* pfile, string& aktparamgraph)
         {
             handleDecimalSeparator(zerlegt[0], zerlegt[1]);
         }
+        if ((toUpper(_param) == "ANALOGDIGITALTRANSITIONSTART") && (zerlegt.size() > 1))
+        {
+            handleAnalogDigitalTransitionStart(zerlegt[0], zerlegt[1]);
+        }
         if ((toUpper(_param) == "MAXRATEVALUE") && (zerlegt.size() > 1))
         {
             handleMaxRateValue(zerlegt[0], zerlegt[1]);
@@ -517,7 +546,7 @@ void ClassFlowPostProcessing::InitNUMBERS()
         flowAnalog->UpdateNameNumbers(&name_numbers);
     }
 
-    printf("Anzahl NUMBERS: %d - DIGITS: %d, ANALOG: %d\n", name_numbers.size(), anzDIGIT, anzANALOG);
+    ESP_LOGD(TAG, "Anzahl NUMBERS: %d - DIGITS: %d, ANALOG: %d", name_numbers.size(), anzDIGIT, anzANALOG);
 
     for (int _num = 0; _num < name_numbers.size(); ++_num)
     {
@@ -557,6 +586,7 @@ void ClassFlowPostProcessing::InitNUMBERS()
         _number->DecimalShift = 0;
         _number->DecimalShiftInitial = 0;
         _number->isExtendedResolution = false;
+        _number->AnalogDigitalTransitionStart=9.2;
 
 
         _number->FlowRateAct = 0;          // m3 / min
@@ -572,7 +602,7 @@ void ClassFlowPostProcessing::InitNUMBERS()
     }
 
     for (int i = 0; i < NUMBERS.size(); ++i) {
-        printf("Number %s, Anz DIG: %d, Anz ANA %d\n", NUMBERS[i]->name.c_str(), NUMBERS[i]->AnzahlDigital, NUMBERS[i]->AnzahlAnalog);
+        ESP_LOGD(TAG, "Number %s, Anz DIG: %d, Anz ANA %d", NUMBERS[i]->name.c_str(), NUMBERS[i]->AnzahlDigital, NUMBERS[i]->AnzahlAnalog);
     }
 
 }
@@ -641,7 +671,7 @@ bool ClassFlowPostProcessing::doFlow(string zwtime)
     strftime(strftime_buf, sizeof(strftime_buf), "%Y-%m-%dT%H:%M:%S", timeinfo);
     zwtime = std::string(strftime_buf);
 
-    printf("Anzahl NUMBERS: %d\n", NUMBERS.size());
+    ESP_LOGD(TAG, "Anzahl NUMBERS: %d", NUMBERS.size());
 
     for (int j = 0; j < NUMBERS.size(); ++j)
     {
@@ -666,7 +696,7 @@ bool ClassFlowPostProcessing::doFlow(string zwtime)
             }
         }
         #ifdef SERIAL_DEBUG
-            printf("After analog->getReadout: ReturnRaw %s\n", NUMBERS[j]->ReturnRawValue.c_str());  
+            ESP_LOGD(TAG, "After analog->getReadout: ReturnRaw %s", NUMBERS[j]->ReturnRawValue.c_str());
         #endif
         if (NUMBERS[j]->digit_roi && NUMBERS[j]->analog_roi)
             NUMBERS[j]->ReturnRawValue = "." + NUMBERS[j]->ReturnRawValue;
@@ -674,17 +704,17 @@ bool ClassFlowPostProcessing::doFlow(string zwtime)
         if (NUMBERS[j]->digit_roi)
         {
             if (NUMBERS[j]->analog_roi) 
-                NUMBERS[j]->ReturnRawValue = flowDigit->getReadout(j, false, previous_value, NUMBERS[j]->analog_roi->ROI[0]->result_float) + NUMBERS[j]->ReturnRawValue;
+                NUMBERS[j]->ReturnRawValue = flowDigit->getReadout(j, false, previous_value, NUMBERS[j]->analog_roi->ROI[0]->result_float, NUMBERS[j]->AnalogDigitalTransitionStart) + NUMBERS[j]->ReturnRawValue;
             else
                 NUMBERS[j]->ReturnRawValue = flowDigit->getReadout(j, NUMBERS[j]->isExtendedResolution, previous_value);        // Extended Resolution nur falls es keine analogen Ziffern gibt
         }
         #ifdef SERIAL_DEBUG
-            printf("After digital->getReadout: ReturnRaw %s\n", NUMBERS[j]->ReturnRawValue.c_str());  
+            ESP_LOGD(TAG, "After digital->getReadout: ReturnRaw %s", NUMBERS[j]->ReturnRawValue.c_str());
         #endif
         NUMBERS[j]->ReturnRawValue = ShiftDecimal(NUMBERS[j]->ReturnRawValue, NUMBERS[j]->DecimalShift);
 
         #ifdef SERIAL_DEBUG
-            printf("After ShiftDecimal: ReturnRaw %s\n", NUMBERS[j]->ReturnRawValue.c_str());  
+            ESP_LOGD(TAG, "After ShiftDecimal: ReturnRaw %s", NUMBERS[j]->ReturnRawValue.c_str());
         #endif
 
         if (IgnoreLeadingNaN)               
@@ -692,29 +722,34 @@ bool ClassFlowPostProcessing::doFlow(string zwtime)
                 NUMBERS[j]->ReturnRawValue.erase(0, 1);
 
         #ifdef SERIAL_DEBUG
-            printf("After IgnoreLeadingNaN: ReturnRaw %s\n", NUMBERS[j]->ReturnRawValue.c_str());  
+            ESP_LOGD(TAG, "After IgnoreLeadingNaN: ReturnRaw %s", NUMBERS[j]->ReturnRawValue.c_str());
         #endif
         NUMBERS[j]->ReturnValue = NUMBERS[j]->ReturnRawValue;
 
         if (findDelimiterPos(NUMBERS[j]->ReturnValue, "N") != std::string::npos)
         {
             if (PreValueUse && NUMBERS[j]->PreValueOkay)
+            {
                 NUMBERS[j]->ReturnValue = ErsetzteN(NUMBERS[j]->ReturnValue, NUMBERS[j]->PreValue); 
+            }
             else
+            {
+                WriteDataLog(j);
                 continue; // es gibt keinen Zahl, da noch ein N vorhanden ist.
+            }
         }
         #ifdef SERIAL_DEBUG
-            printf("After findDelimiterPos: ReturnValue %s\n", NUMBERS[j]->ReturnRawValue.c_str());  
+            ESP_LOGD(TAG, "After findDelimiterPos: ReturnValue %s", NUMBERS[j]->ReturnRawValue.c_str());
         #endif
         // Lösche führende Nullen (außer es ist nur noch einen 0)
         while ((NUMBERS[j]->ReturnValue.length() > 1) && (NUMBERS[j]->ReturnValue[0] == '0'))
             NUMBERS[j]->ReturnValue.erase(0, 1);
         #ifdef SERIAL_DEBUG
-            printf("After removeLeadingZeros: ReturnValue %s\n", NUMBERS[j]->ReturnRawValue.c_str());  
+            ESP_LOGD(TAG, "After removeLeadingZeros: ReturnValue %s", NUMBERS[j]->ReturnRawValue.c_str());
         #endif
         NUMBERS[j]->Value = std::stod(NUMBERS[j]->ReturnValue);
         #ifdef SERIAL_DEBUG
-            printf("After setting the Value: Value %f and as double is %f\n", NUMBERS[j]->Value, std::stod(NUMBERS[j]->ReturnValue));  
+            ESP_LOGD(TAG, "After setting the Value: Value %f and as double is %f", NUMBERS[j]->Value, std::stod(NUMBERS[j]->ReturnValue));
         #endif
 
         if (NUMBERS[j]->checkDigitIncreaseConsistency)
@@ -722,20 +757,20 @@ bool ClassFlowPostProcessing::doFlow(string zwtime)
             if (flowDigit)
             {
                 if (flowDigit->getCNNType() != Digital)
-                    printf("checkDigitIncreaseConsistency = true - ignored due to wrong CNN-Type (not Digital Classification)\n"); 
+                    ESP_LOGD(TAG, "checkDigitIncreaseConsistency = true - ignored due to wrong CNN-Type (not Digital Classification)");
                 else 
                     NUMBERS[j]->Value = checkDigitConsistency(NUMBERS[j]->Value, NUMBERS[j]->DecimalShift, NUMBERS[j]->analog_roi != NULL, NUMBERS[j]->PreValue);
             }
             else
             {
                 #ifdef SERIAL_DEBUG
-                    printf("checkDigitIncreaseConsistency = true - no digital numbers defined!\n"); 
+                    ESP_LOGD(TAG, "checkDigitIncreaseConsistency = true - no digital numbers defined!");
                 #endif
             }
         }
 
         #ifdef SERIAL_DEBUG
-            printf("After checkDigitIncreaseConsistency: Value %f\n", NUMBERS[j]->Value);  
+            ESP_LOGD(TAG, "After checkDigitIncreaseConsistency: Value %f", NUMBERS[j]->Value);
         #endif
                
 
@@ -744,7 +779,7 @@ bool ClassFlowPostProcessing::doFlow(string zwtime)
             if ((NUMBERS[j]->Value < NUMBERS[j]->PreValue))
             {
                 #ifdef SERIAL_DEBUG
-                    printf("Neg: value=%f, preValue=%f, preToll%f\n", NUMBERS[j]->Value, NUMBERS[j]->PreValue,
+                    ESP_LOGD(TAG, "Neg: value=%f, preValue=%f, preToll%f", NUMBERS[j]->Value, NUMBERS[j]->PreValue,
                      NUMBERS[j]->PreValue-(2/pow(10, NUMBERS[j]->Nachkomma))
                       ) ;
                 #endif
@@ -756,13 +791,14 @@ bool ClassFlowPostProcessing::doFlow(string zwtime)
                     NUMBERS[j]->ErrorMessageText = NUMBERS[j]->ErrorMessageText + "Neg. Rate - Read: " + zwvalue + " - Raw: " + NUMBERS[j]->ReturnRawValue + " - Pre: " + RundeOutput(NUMBERS[j]->PreValue, NUMBERS[j]->Nachkomma) + " "; 
                     NUMBERS[j]->Value = NUMBERS[j]->PreValue;
                     NUMBERS[j]->ReturnValue = "";
+                    WriteDataLog(j);
                     continue;
                 }
                 
             }
         }
         #ifdef SERIAL_DEBUG
-            printf("After AllowNegativeRates: Value %f\n", NUMBERS[j]->Value);  
+            ESP_LOGD(TAG, "After AllowNegativeRates: Value %f", NUMBERS[j]->Value);
         #endif
         double difference = difftime(imagetime, NUMBERS[j]->lastvalue);      // in Sekunden
         difference /= 60;  
@@ -783,11 +819,12 @@ bool ClassFlowPostProcessing::doFlow(string zwtime)
                 NUMBERS[j]->Value = NUMBERS[j]->PreValue;
                 NUMBERS[j]->ReturnValue = "";
                 NUMBERS[j]->ReturnRateValue = "";
+                WriteDataLog(j);
                 continue;
             }
         }
         #ifdef SERIAL_DEBUG
-           printf("After MaxRateCheck: Value %f\n", NUMBERS[j]->Value);  
+           ESP_LOGD(TAG, "After MaxRateCheck: Value %f", NUMBERS[j]->Value);
         #endif
         NUMBERS[j]->ReturnChangeAbsolute = RundeOutput(NUMBERS[j]->Value - NUMBERS[j]->PreValue, NUMBERS[j]->Nachkomma);                                                
         NUMBERS[j]->lastvalue = imagetime;
@@ -802,13 +839,37 @@ bool ClassFlowPostProcessing::doFlow(string zwtime)
         UpdatePreValueINI = true;
 
         string _zw = "PostProcessing - Raw: " + NUMBERS[j]->ReturnRawValue + " Value: " + NUMBERS[j]->ReturnValue + " Error: " + NUMBERS[j]->ErrorMessageText;
+        ESP_LOGD(TAG, "%s", zw.c_str());
         LogFile.WriteToFile(_zw);
+        WriteDataLog(j);
     }
 
     SavePreValue();
     return true;
 }
 
+void ClassFlowPostProcessing::WriteDataLog(int _index)
+{
+    string analog = "";
+    string digital = "";
+    string timezw = "";
+    char buffer[80];
+    struct tm* timeinfo = localtime(&NUMBERS[_index]->lastvalue);
+    strftime(buffer, 80, PREVALUE_TIME_FORMAT_OUTPUT, timeinfo);
+    timezw = std::string(buffer);
+
+    if (flowAnalog)
+        analog = flowAnalog->getReadoutRawString(_index);
+    if (flowDigit)
+        digital = flowDigit->getReadoutRawString(_index);
+    LogFile.WriteToData(timezw, NUMBERS[_index]->name, 
+                        NUMBERS[_index]->ReturnRawValue, NUMBERS[_index]->ReturnValue, NUMBERS[_index]->ReturnPreValue, 
+                        NUMBERS[_index]->ReturnRateValue, NUMBERS[_index]->ReturnChangeAbsolute,
+                        NUMBERS[_index]->ErrorMessageText, 
+                        digital, analog);
+    ESP_LOGD(TAG, "WriteDataLog: %s, %s, %s, %s, %s", NUMBERS[_index]->ReturnRawValue.c_str(), NUMBERS[_index]->ReturnValue.c_str(), NUMBERS[_index]->ErrorMessageText.c_str(), digital.c_str(), analog.c_str());
+}
+
 
 void ClassFlowPostProcessing::UpdateNachkommaDecimalShift()
 {
@@ -816,7 +877,7 @@ void ClassFlowPostProcessing::UpdateNachkommaDecimalShift()
     {
         if (NUMBERS[j]->digit_roi && !NUMBERS[j]->analog_roi)            // es gibt nur digitale ziffern
         {
-//            printf("Nurdigital\n");
+//            ESP_LOGD(TAG, "Nurdigital");
             NUMBERS[j]->DecimalShift = NUMBERS[j]->DecimalShiftInitial;
 
             if (NUMBERS[j]->isExtendedResolution && flowDigit->isExtendedResolution())  // extended resolution ist an und soll auch bei dieser Ziffer verwendet werden
@@ -827,7 +888,7 @@ void ClassFlowPostProcessing::UpdateNachkommaDecimalShift()
 
         if (!NUMBERS[j]->digit_roi && NUMBERS[j]->analog_roi)            // es gibt nur analoge ziffern
         {
-//            printf("Nur analog\n");
+//            ESP_LOGD(TAG, "Nur analog");
             NUMBERS[j]->DecimalShift = NUMBERS[j]->DecimalShiftInitial;
             if (NUMBERS[j]->isExtendedResolution && flowAnalog->isExtendedResolution())  // extended resolution ist an und soll auch bei dieser Ziffer verwendet werden
                 NUMBERS[j]->DecimalShift = NUMBERS[j]->DecimalShift-1;
@@ -837,7 +898,7 @@ void ClassFlowPostProcessing::UpdateNachkommaDecimalShift()
 
         if (NUMBERS[j]->digit_roi && NUMBERS[j]->analog_roi)            // digital + analog
         {
-//            printf("Nur digital + analog\n");
+//            ESP_LOGD(TAG, "Nur digital + analog");
 
             NUMBERS[j]->DecimalShift = NUMBERS[j]->DecimalShiftInitial;
             NUMBERS[j]->Nachkomma = NUMBERS[j]->analog_roi->ROI.size() - NUMBERS[j]->DecimalShift;
@@ -847,7 +908,7 @@ void ClassFlowPostProcessing::UpdateNachkommaDecimalShift()
 
         }
 
-        printf("UpdateNachkommaDecShift NUMBER%i: Nachkomma %i, DecShift %i\n", j, NUMBERS[j]->Nachkomma,NUMBERS[j]->DecimalShift);
+        ESP_LOGD(TAG, "UpdateNachkommaDecShift NUMBER%i: Nachkomma %i, DecShift %i", j, NUMBERS[j]->Nachkomma,NUMBERS[j]->DecimalShift);
     }
 }
 
@@ -866,10 +927,12 @@ string ClassFlowPostProcessing::getReadoutParam(bool _rawValue, bool _noerror, i
     return NUMBERS[_number]->ReturnValue;
 }
 
+/*  Jetzt als globale Funktion in Helper.h
+
 string ClassFlowPostProcessing::RundeOutput(double _in, int _anzNachkomma){
     std::stringstream stream;
     int _zw = _in;    
-//    printf("AnzNachkomma: %d\n", _anzNachkomma);
+//    ESP_LOGD(TAG, "AnzNachkomma: %d", _anzNachkomma);
 
     if (_anzNachkomma < 0) {
         _anzNachkomma = 0;
@@ -888,6 +951,7 @@ string ClassFlowPostProcessing::RundeOutput(double _in, int _anzNachkomma){
 
     return stream.str();  
 }
+*/
 
 
 string ClassFlowPostProcessing::ErsetzteN(string input, double _prevalue)
@@ -934,7 +998,7 @@ float ClassFlowPostProcessing::checkDigitConsistency(double input, int _decilams
         pot++;
     }
     #ifdef SERIAL_DEBUG
-        printf("checkDigitConsistency: pot=%d, decimalshift=%d\n", pot, _decilamshift);
+        ESP_LOGD(TAG, "checkDigitConsistency: pot=%d, decimalshift=%d", pot, _decilamshift);
     #endif
     pot_max = ((int) log10(input)) + 1;
     while (pot <= pot_max)
@@ -966,7 +1030,7 @@ float ClassFlowPostProcessing::checkDigitConsistency(double input, int _decilams
             }
         }
         #ifdef SERIAL_DEBUG
-            printf("checkDigitConsistency: input=%f", input);
+            ESP_LOGD(TAG, "checkDigitConsistency: input=%f", input);
         #endif
         pot++;
     }
@@ -989,3 +1053,5 @@ string ClassFlowPostProcessing::getReadoutError(int _number)
 {
     return NUMBERS[_number]->ErrorMessageText;
 }
+
+

+ 4 - 1
code/components/jomjol_flowcontroll/ClassFlowPostProcessing.h

@@ -34,13 +34,16 @@ protected:
 
     string ErsetzteN(string, double _prevalue);
     float checkDigitConsistency(double input, int _decilamshift, bool _isanalog, double _preValue);
-    string RundeOutput(double _in, int _anzNachkomma);
 
     void InitNUMBERS();
     void handleDecimalSeparator(string _decsep, string _value);
     void handleMaxRateValue(string _decsep, string _value);
     void handleDecimalExtendedResolution(string _decsep, string _value); 
     void handleMaxRateType(string _decsep, string _value);
+    void handleAnalogDigitalTransitionStart(string _decsep, string _value);
+    std::string GetStringReadouts(general);
+
+    void WriteDataLog(int _index);
 
 
 

+ 1 - 1
code/components/jomjol_helper/CMakeLists.txt

@@ -2,6 +2,6 @@ FILE(GLOB_RECURSE app_sources ${CMAKE_CURRENT_SOURCE_DIR}/*.*)
 
 idf_component_register(SRCS ${app_sources}
                     INCLUDE_DIRS "."
-                    REQUIRES tflite-lib jomjol_logfile)
+                    REQUIRES tflite-lib jomjol_logfile fatfs sdmmc)
 
 

+ 259 - 16
code/components/jomjol_helper/Helper.cpp

@@ -7,6 +7,9 @@
 #include <sys/types.h>
 #include <sys/stat.h>
 
+#include <iomanip>
+#include <sstream>
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -20,13 +23,19 @@ extern "C" {
 
 
 #include "ClassLogFile.h"
-//#include "ClassLogFile.h"
+
+#include "esp_vfs_fat.h"
+
+static const char* TAG = "helper";
 
 //#define ISWINDOWS_TRUE
 #define PATH_MAX_STRING_SIZE 256
 
 using namespace std;
 
+sdmmc_cid_t SDCardCid;
+sdmmc_csd_t SDCardCsd;
+
 /////////////////////////////////////////////////////////////////////////////////////////////
 string getESPHeapInfo(){
 	string espInfoResultStr = "";
@@ -73,8 +82,78 @@ size_t getInternalESPHeapSize() {
 	return aFreeInternalHeapSize;
 }
 
+string getSDCardPartitionSize(){
+	FATFS *fs;
+    uint32_t fre_clust, tot_sect;
+
+    /* Get volume information and free clusters of drive 0 */
+    f_getfree("0:", (DWORD *)&fre_clust, &fs);
+    tot_sect = ((fs->n_fatent - 2) * fs->csize) /1024 /(1024/SDCardCsd.sector_size);	//corrected by SD Card sector size (usually 512 bytes) and convert to MB
+
+    printf("%d MB total drive space (Sector size [bytes]: %d)\n", (int)tot_sect, (int)fs->csize*512);
+
+	return std::to_string(tot_sect);
+}
+
+string getSDCardFreePartitionSpace(){
+	FATFS *fs;
+    uint32_t fre_clust, fre_sect;
+  
+    /* Get volume information and free clusters of drive 0 */
+    f_getfree("0:", (DWORD *)&fre_clust, &fs);
+    fre_sect = (fre_clust * fs->csize) / 1024 /(1024/SDCardCsd.sector_size);	//corrected by SD Card sector size (usually 512 bytes) and convert to MB
+
+    printf("%d MB free drive space (Sector size [bytes]: %d)\n", (int)fre_sect, (int)fs->ssize);
+
+	return std::to_string(fre_sect);
+}
+
+string getSDCardPartitionAllocationSize(){
+	FATFS *fs;
+    uint32_t fre_clust, allocation_size;
+  
+    /* Get volume information and free clusters of drive 0 */
+    f_getfree("0:", (DWORD *)&fre_clust, &fs);
+    allocation_size = fs->ssize;
+
+    printf("SD Card Partition Allocation Size (bytes): %d)\n", allocation_size);
+
+	return std::to_string(allocation_size);
+}
+
+
+void SaveSDCardInfo(sdmmc_card_t* card) {
+	SDCardCid = card->cid;
+    SDCardCsd = card->csd;
+}
+
+string getSDCardManufacturer(){
+	string SDCardManufacturer = SDCardParseManufacturerIDs(SDCardCid.mfg_id);
+	printf("SD Card Manufactuer: %s\n", SDCardManufacturer.c_str());
+	
+	return (SDCardManufacturer + " (ID: " + std::to_string(SDCardCid.mfg_id) + ")");
+}
+
+string getSDCardName(){
+	char *SDCardName = SDCardCid.name;
+	printf("SD Card Name: %s\n", SDCardName); 
+
+	return std::string(SDCardName);
+}
+
+string getSDCardCapacity(){
+	int SDCardCapacity = SDCardCsd.capacity / (1024/SDCardCsd.sector_size) / 1024;  // total sectors * sector size  --> Byte to MB (1024*1024)
+	printf("SD Card Capacity: %s\n", std::to_string(SDCardCapacity).c_str()); 
 
+	return std::to_string(SDCardCapacity);
+}
 
+string getSDCardSectorSize(){
+	int SDCardSectorSize = SDCardCsd.sector_size;
+	printf("SD Card Sector Size: %s\n", std::to_string(SDCardSectorSize).c_str()); 
+
+	return std::to_string(SDCardSectorSize);
+}
 
 ///////////////////////////////////////////////////////////////////////////////////////////////
 
@@ -90,13 +169,13 @@ FILE* OpenFileAndWait(const char* nm, const char* _mode, int _waitsec)
 {
 	FILE *pfile;
 
-	printf("open file %s in mode %s\n", nm, _mode);
+	ESP_LOGD(TAG, "open file %s in mode %s", nm, _mode);
 
 	if ((pfile = fopen(nm, _mode)) != NULL) {
-		printf("File %s successfully opened\n", nm);
+		ESP_LOGD(TAG, "File %s successfully opened", nm);
 	}
 	else {
-		printf("Error: file %s does not exist!\n", nm);
+		ESP_LOGD(TAG, "Error: file %s does not exist!", nm);
 		return NULL;
 	}
 
@@ -106,9 +185,7 @@ FILE* OpenFileAndWait(const char* nm, const char* _mode, int _waitsec)
 		TickType_t xDelay;
 		xDelay = _waitsec * 1000 / portTICK_PERIOD_MS;
 		std::string zw = "File is locked: " + std::string(nm) + " - wait for " + std::to_string(_waitsec) + " seconds";
-	    printf(zw.c_str());
-		printf("\n");
-		LogFile.WriteToFile(zw);      
+	    LogFile.WriteToFile(zw);
 		vTaskDelay( xDelay );
 		pfile = fopen(nm, _mode);
 	}
@@ -154,6 +231,12 @@ void FindReplace(std::string& line, std::string& oldString, std::string& newStri
     }
 }
 
+void MakeDir(std::string _what)
+{
+int mk_ret = mkdir(_what.c_str(), 0775);
+if (mk_ret)
+	ESP_LOGD(TAG, "error with mkdir %s ret %d", _what.c_str(), mk_ret);
+}
 
 
 
@@ -226,7 +309,7 @@ void RenameFile(string from, string to)
 	FILE* fpSourceFile = OpenFileAndWait(from.c_str(), "rb");
 	if (!fpSourceFile)	// Sourcefile existiert nicht sonst gibt es einen Fehler beim Kopierversuch!
 	{
-		printf("DeleteFile: File %s existiert nicht!\n", from.c_str());
+		ESP_LOGD(TAG, "DeleteFile: File %s existiert nicht!", from.c_str());
 		return;
 	}
 	fclose(fpSourceFile);
@@ -242,7 +325,7 @@ void DeleteFile(string fn)
 	FILE* fpSourceFile = OpenFileAndWait(fn.c_str(), "rb");
 	if (!fpSourceFile)	// Sourcefile existiert nicht sonst gibt es einen Fehler beim Kopierversuch!
 	{
-		printf("DeleteFile: File %s existiert nicht!\n", fn.c_str());
+		ESP_LOGD(TAG, "DeleteFile: File %s existiert nicht!", fn.c_str());
 		return;
 	}
 	fclose(fpSourceFile);
@@ -258,7 +341,7 @@ void CopyFile(string input, string output)
 
 	if (toUpper(input).compare("/SDCARD/WLAN.INI") == 0)
 	{
-		printf("wlan.ini kann nicht kopiert werden!\n");
+		ESP_LOGD(TAG, "wlan.ini kann nicht kopiert werden!");
 		return;
 	}
 
@@ -266,7 +349,7 @@ void CopyFile(string input, string output)
 	FILE* fpSourceFile = OpenFileAndWait(input.c_str(), "rb");
 	if (!fpSourceFile)	// Sourcefile existiert nicht sonst gibt es einen Fehler beim Kopierversuch!
 	{
-		printf("File %s existiert nicht!\n", input.c_str());
+		ESP_LOGD(TAG, "File %s existiert nicht!", input.c_str());
 		return;
 	}
 
@@ -284,7 +367,7 @@ void CopyFile(string input, string output)
 	// Close The Files
 	fclose(fpSourceFile);
 	fclose(fpTargetFile);
-	printf("File copied: %s to %s", input.c_str(), output.c_str());
+	ESP_LOGD(TAG, "File copied: %s to %s", input.c_str(), output.c_str());
 }
 
 string getFileFullFileName(string filename)
@@ -294,7 +377,7 @@ string getFileFullFileName(string filename)
 	if (lastpos == string::npos)
 		return "";
 
-//	printf("Last position: %d\n", lastpos);
+//	ESP_LOGD(TAG, "Last position: %d", lastpos);
 
 	string zw = filename.substr(lastpos + 1, filename.size() - lastpos);
 
@@ -311,7 +394,7 @@ string getDirectory(string filename)
 	if (lastpos == string::npos)
 		return "";
 
-//	printf("Directory: %d\n", lastpos);
+//	ESP_LOGD(TAG, "Directory: %d", lastpos);
 
 	string zw = filename.substr(0, lastpos - 1);
 	return zw;
@@ -319,7 +402,7 @@ string getDirectory(string filename)
 
 string getFileType(string filename)
 {
-	size_t lastpos = filename.find(".", 0);
+	size_t lastpos = filename.rfind(".", filename.length());
 	size_t neu_pos;
 	while ((neu_pos = filename.find(".", lastpos + 1)) > -1)
 	{
@@ -455,7 +538,6 @@ int removeFolder(const char* folderPath, const char* logTag) {
 }
 
 
-
 std::vector<string> HelperZerlegeZeile(std::string input, std::string _delimiter = "")
 {
 	std::vector<string> Output;
@@ -480,3 +562,164 @@ std::vector<string> HelperZerlegeZeile(std::string input, std::string _delimiter
 	return Output;
 }
 
+
+/* Source: https://git.kernel.org/pub/scm/utils/mmc/mmc-utils.git/tree/lsmmc.c */
+/* SD Card Manufacturer Database */
+struct SDCard_Manufacturer_database {
+	string type;
+	int id;
+	string manufacturer;
+};
+
+/* Source: https://git.kernel.org/pub/scm/utils/mmc/mmc-utils.git/tree/lsmmc.c */
+/* SD Card Manufacturer Database */
+struct SDCard_Manufacturer_database database[] = {
+	{
+		.type = "sd",
+		.id = 0x01,
+		.manufacturer = "Panasonic",
+	},
+	{
+		.type = "sd",
+		.id = 0x02,
+		.manufacturer = "Toshiba/Kingston/Viking",
+	},
+	{
+		.type = "sd",
+		.id = 0x03,
+		.manufacturer = "SanDisk",
+	},
+	{
+		.type = "sd",
+		.id = 0x08,
+		.manufacturer = "Silicon Power",
+	},
+	{
+		.type = "sd",
+		.id = 0x18,
+		.manufacturer = "Infineon",
+	},
+	{
+		.type = "sd",
+		.id = 0x1b,
+		.manufacturer = "Transcend/Samsung",
+	},
+	{
+		.type = "sd",
+		.id = 0x1c,
+		.manufacturer = "Transcend",
+	},
+	{
+		.type = "sd",
+		.id = 0x1d,
+		.manufacturer = "Corsair/AData",
+	},
+	{
+		.type = "sd",
+		.id = 0x1e,
+		.manufacturer = "Transcend",
+	},
+	{
+		.type = "sd",
+		.id = 0x1f,
+		.manufacturer = "Kingston",
+	},
+	{
+		.type = "sd",
+		.id = 0x27,
+		.manufacturer = "Delkin/Phison",
+	},
+	{
+		.type = "sd",
+		.id = 0x28,
+		.manufacturer = "Lexar",
+	},
+	{
+		.type = "sd",
+		.id = 0x30,
+		.manufacturer = "SanDisk",
+	},
+	{
+		.type = "sd",
+		.id = 0x31,
+		.manufacturer = "Silicon Power",
+	},
+	{
+		.type = "sd",
+		.id = 0x33,
+		.manufacturer = "STMicroelectronics",
+	},
+	{
+		.type = "sd",
+		.id = 0x41,
+		.manufacturer = "Kingston",
+	},
+	{
+		.type = "sd",
+		.id = 0x6f,
+		.manufacturer = "STMicroelectronics",
+	},
+	{
+		.type = "sd",
+		.id = 0x74,
+		.manufacturer = "Transcend",
+	},
+	{
+		.type = "sd",
+		.id = 0x76,
+		.manufacturer = "Patriot",
+	},
+	{
+		.type = "sd",
+		.id = 0x82,
+		.manufacturer = "Gobe/Sony",
+	},
+	{
+		.type = "sd",
+		.id = 0x89,
+		.manufacturer = "Unknown",
+	}
+};
+
+/* Parse SD Card Manufacturer Database */
+string SDCardParseManufacturerIDs(int id) 
+{
+	unsigned int id_cnt = sizeof(database) / sizeof(struct SDCard_Manufacturer_database);
+	string ret_val = "";
+
+	for (int i = 0; i < id_cnt; i++) {
+		if (database[i].id == id) {
+			return database[i].manufacturer;
+		}
+		else {
+			ret_val = "ID unknown (not in DB)";
+		}
+	}
+	return ret_val;
+}
+
+
+string RundeOutput(double _in, int _anzNachkomma)
+{
+    std::stringstream stream;
+    int _zw = _in;    
+//    ESP_LOGD(TAG, "AnzNachkomma: %d", _anzNachkomma);
+
+    if (_anzNachkomma < 0) {
+        _anzNachkomma = 0;
+    }
+
+    if (_anzNachkomma > 0)
+    {
+        stream << std::fixed << std::setprecision(_anzNachkomma) << _in;
+        return stream.str();          
+    }
+    else
+    {
+        stream << _zw;
+    }
+
+
+    return stream.str();  
+}
+

+ 15 - 1
code/components/jomjol_helper/Helper.h

@@ -2,7 +2,7 @@
 #include <string>
 #include <fstream>
 #include <vector>
-
+#include "sdmmc_cmd.h"
 
 using namespace std;
 
@@ -12,6 +12,10 @@ void FindReplace(std::string& line, std::string& oldString, std::string& newStri
 void CopyFile(string input, string output);
 void DeleteFile(string fn);
 void RenameFile(string from, string to);
+void MakeDir(std::string _what);
+
+
+string RundeOutput(double _in, int _anzNachkomma);
 
 
 FILE* OpenFileAndWait(const char* nm, const char* _mode, int _waitsec = 1);
@@ -45,3 +49,13 @@ size_t getESPHeapSize();
 string getESPHeapInfo();
 
 /////////////////////////////
+string getSDCardPartitionSize();
+string getSDCardFreePartitionSpace();
+string getSDCardPartitionAllocationSize();
+
+void SaveSDCardInfo(sdmmc_card_t* card);
+string SDCardParseManufacturerIDs(int);
+string getSDCardManufacturer();
+string getSDCardName();
+string getSDCardCapacity();
+string getSDCardSectorSize();

+ 7 - 4
code/components/jomjol_image_proc/CAlignAndCutImage.cpp

@@ -5,6 +5,9 @@
 #define _USE_MATH_DEFINES
 #include <math.h>
 #include <algorithm>
+#include <esp_log.h>
+
+static const char* TAG = "c_align_and_cut_image";
 
 //#define GET_MEMORY malloc
 #define GET_MEMORY(X) heap_caps_malloc(X, MALLOC_CAP_SPIRAM)
@@ -43,14 +46,14 @@ bool CAlignAndCutImage::Align(RefInfo *_temp1, RefInfo *_temp2)
 
     r0_x = _temp1->target_x;
     r0_y = _temp1->target_y;
-    printf("Vor ft->FindTemplate(_temp1);  %s\n", _temp1->image_file.c_str());
+    ESP_LOGD(TAG, "Vor ft->FindTemplate(_temp1); %s", _temp1->image_file.c_str());
     isSimilar1 = ft->FindTemplate(_temp1);
     _temp1->width = ft->tpl_width;
     _temp1->height = ft->tpl_height; 
 
     r1_x = _temp2->target_x;
     r1_y = _temp2->target_y;
-    printf("Vor ft->FindTemplate(_temp2);  %s\n", _temp2->image_file.c_str());
+    ESP_LOGD(TAG, "Vor ft->FindTemplate(_temp2); %s", _temp2->image_file.c_str());
     isSimilar2 = ft->FindTemplate(_temp2);
     _temp2->width = ft->tpl_width;
     _temp2->height = ft->tpl_height; 
@@ -86,7 +89,7 @@ bool CAlignAndCutImage::Align(RefInfo *_temp1, RefInfo *_temp2)
     CRotateImage rt(this, ImageTMP);
     rt.Translate(dx, dy);
     rt.Rotate(d_winkel, _temp1->target_x, _temp1->target_y);
-    printf("Alignment: dx %d - dy %d - rot %f\n", dx, dy, d_winkel);
+    ESP_LOGD(TAG, "Alignment: dx %d - dy %d - rot %f", dx, dy, d_winkel);
 
     return (isSimilar1 && isSimilar2);
 }
@@ -147,7 +150,7 @@ void CAlignAndCutImage::CutAndSave(int x1, int y1, int dx, int dy, CImageBasis *
 
     if ((_target->height != dy) || (_target->width != dx) || (_target->channels != channels))
     {
-        printf("CAlignAndCutImage::CutAndSave - Image size does not match !!");
+        ESP_LOGD(TAG, "CAlignAndCutImage::CutAndSave - Image size does not match!");
         return;
     }
 

+ 13 - 9
code/components/jomjol_image_proc/CFindTemplate.cpp

@@ -2,6 +2,10 @@
 
 #include "ClassLogFile.h"
 
+#include <esp_log.h>
+
+static const char* TAG = "c_find_template";
+
 // #define DEBUG_DETAIL_ON  
 
 
@@ -9,7 +13,7 @@ bool CFindTemplate::FindTemplate(RefInfo *_ref)
 {
     uint8_t* rgb_template = stbi_load(_ref->image_file.c_str(), &tpl_width, &tpl_height, &tpl_bpp, channels);
 
-//    printf("FindTemplate 01\n");
+//    ESP_LOGD(TAG, "FindTemplate 01");
 
     int ow, ow_start, ow_stop;
     int oh, oh_start, oh_stop;
@@ -45,7 +49,7 @@ bool CFindTemplate::FindTemplate(RefInfo *_ref)
     int min, max;
     bool isSimilar = false;
 
-//    printf("FindTemplate 02\n");
+//    ESP_LOGD(TAG, "FindTemplate 02");
 
     if ((_ref->alignment_algo == 2) && (_ref->fastalg_x > -1) && (_ref->fastalg_y > -1))     // für Testzwecke immer Berechnen
     {
@@ -57,7 +61,7 @@ bool CFindTemplate::FindTemplate(RefInfo *_ref)
 #endif
     }
 
-//    printf("FindTemplate 03\n");
+//    ESP_LOGD(TAG, "FindTemplate 03");
 
 
     if (isSimilar)
@@ -70,7 +74,7 @@ bool CFindTemplate::FindTemplate(RefInfo *_ref)
         return true;
     }
 
-//    printf("FindTemplate 04\n");
+//    ESP_LOGD(TAG, "FindTemplate 04");
 
 
     double aktSAD;
@@ -78,7 +82,7 @@ bool CFindTemplate::FindTemplate(RefInfo *_ref)
 
     RGBImageLock();
 
-//    printf("FindTemplate 05\n");
+//    ESP_LOGD(TAG, "FindTemplate 05");
     int xouter, youter, tpl_x, tpl_y, _ch;
     int _anzchannels = channels;
     if (_ref->alignment_algo == 0)  // 0 = "Default" (nur R-Kanal)
@@ -106,14 +110,14 @@ bool CFindTemplate::FindTemplate(RefInfo *_ref)
             }
         }
 
-//    printf("FindTemplate 06\n");
+//    ESP_LOGD(TAG, "FindTemplate 06");
 
 
     if (_ref->alignment_algo == 2)
         CalculateSimularities(rgb_template, _ref->found_x, _ref->found_y, ow, oh, min, avg, max, SAD, _ref->fastalg_SAD, _ref->fastalg_SAD_criteria);
 
 
-//    printf("FindTemplate 07\n");
+//    ESP_LOGD(TAG, "FindTemplate 07");
 
     _ref->fastalg_x = _ref->found_x;
     _ref->fastalg_y = _ref->found_y;
@@ -132,7 +136,7 @@ bool CFindTemplate::FindTemplate(RefInfo *_ref)
     RGBImageRelease();
     stbi_image_free(rgb_template);
     
-//    printf("FindTemplate 08\n");
+//    ESP_LOGD(TAG, "FindTemplate 08");
 
     return false;
 }
@@ -173,7 +177,7 @@ bool CFindTemplate::CalculateSimularities(uint8_t* _rgb_tmpl, int _startx, int _
 
     float _SADdif = abs(SAD - _SADold);
 
-    printf("Anzahl %ld, avgDifSum %fd, avg %f, SAD_neu: %fd, _SAD_old: %f, _SAD_crit:%f\n", anz, avgDifSum, avg, SAD, _SADold, _SADdif);
+    ESP_LOGD(TAG, "Anzahl %ld, avgDifSum %fd, avg %f, SAD_neu: %fd, _SAD_old: %f, _SAD_crit:%f", anz, avgDifSum, avg, SAD, _SADold, _SADdif);
 
     if (_SADdif <= _SADcrit)
         return true;

+ 16 - 16
code/components/jomjol_image_proc/CImageBasis.cpp

@@ -29,7 +29,7 @@ uint8_t * CImageBasis::RGBImageLock(int _waitmaxsec)
     if (islocked)
     {
 #ifdef DEBUG_DETAIL_ON   
-        printf("Image is locked: sleep for : %ds\n", _waitmaxsec);
+        ESP_LOGD(TAG, "Image is locked: sleep for: %ds", _waitmaxsec);
 #endif
         TickType_t xDelay;
         xDelay = 1000 / portTICK_PERIOD_MS;
@@ -61,7 +61,7 @@ uint8_t * CImageBasis::RGBImageGet()
 
 void writejpghelp(void *context, void *data, int size)
 {
-//    printf("Size all: %d, size %d\n", ((ImageData*)context)->size, size);
+//    ESP_LOGD(TAG, "Size all: %d, size %d", ((ImageData*)context)->size, size);
     ImageData* _zw = (ImageData*) context;
     uint8_t *voidstart = _zw->data;
     uint8_t *datastart = (uint8_t*) data;
@@ -146,7 +146,7 @@ bool CImageBasis::CopyFromMemory(uint8_t* _source, int _size)
     int gr = height * width * channels;
     if (gr != _size)            // Größe passt nicht
     {
-        printf("Cannot copy image from memory - sizes do not match: should be %d, but is %d\n", _size, gr);
+        ESP_LOGD(TAG, "Cannot copy image from memory - sizes do not match: should be %d, but is %d", _size, gr);
         return false;
     }
 
@@ -359,7 +359,7 @@ void CImageBasis::LoadFromMemory(stbi_uc *_buffer, int len)
         stbi_image_free(rgb_image);
     rgb_image = stbi_load_from_memory(_buffer, len, &width, &height, &channels, 3);
     bpp = channels;
-    printf("Image loaded from memory: %d, %d, %d\n", width, height, channels);
+    ESP_LOGD(TAG, "Image loaded from memory: %d, %d, %d", width, height, channels);
     if ((width * height * channels) == 0)
     {
         ESP_LOGE(TAG, "Image with size 0 loaded --> reboot to be done! "
@@ -392,7 +392,7 @@ CImageBasis::CImageBasis(CImageBasis *_copyfrom, int _anzrepeat)
     int anz = 1;
     while (!rgb_image && (anz < _anzrepeat))    
     {
-	    printf("Create Image from Copy - Memory is full - try again: %d.\n", anz);
+	    ESP_LOGD(TAG, "Create Image from Copy - Memory is full - try again: %d", anz);
         rgb_image = (unsigned char*) malloc(memsize);
         anz++;
     }
@@ -400,8 +400,8 @@ CImageBasis::CImageBasis(CImageBasis *_copyfrom, int _anzrepeat)
     
     if (!rgb_image)
     {
-        printf(getESPHeapInfo().c_str());
-        printf("\nNo more free memory!! Needed: %d %d %d %d\n", width, height, channels, memsize);
+        ESP_LOGD(TAG, "%s", getESPHeapInfo().c_str());
+        ESP_LOGD(TAG, "No more free memory!! Needed: %d %d %d %d", width, height, channels, memsize);
         RGBImageRelease();
         return;
     }
@@ -424,8 +424,8 @@ CImageBasis::CImageBasis(int _width, int _height, int _channels)
     rgb_image = (unsigned char*)GET_MEMORY(memsize);
     if (!rgb_image)
     {
-        printf(getESPHeapInfo().c_str());
-        printf("\nNo more free memory!! Needed: %d %d %d %d\n", width, height, channels, memsize);
+        ESP_LOGD(TAG, "%s", getESPHeapInfo().c_str());
+        ESP_LOGD(TAG, "No more free memory!! Needed: %d %d %d %d", width, height, channels, memsize);
         return;
     }
 }
@@ -438,21 +438,21 @@ CImageBasis::CImageBasis(std::string _image)
     externalImage = false;
     filename = _image;
     long zwld = esp_get_free_heap_size();
-    printf("freeheapsize before: %ld\n", zwld);
+    ESP_LOGD(TAG, "freeheapsize before: %ld", zwld);
 
     RGBImageLock();
     rgb_image = stbi_load(_image.c_str(), &width, &height, &bpp, channels);
     RGBImageRelease();
 
     zwld = esp_get_free_heap_size();
-    printf("freeheapsize after : %ld\n", zwld);
+    ESP_LOGD(TAG, "freeheapsize after : %ld", zwld);
 
-    std::string zw = "Image Load failed:" + _image + "\n";
+    std::string zw = "Image Load failed:" + _image;
     if (rgb_image == NULL)
-        printf(zw.c_str());
+        ESP_LOGD(TAG, "%s", zw.c_str());
     zw = "CImageBasis after load " + _image + "\n";
-    printf(zw.c_str());
-    printf("w %d, h %d, b %d, c %d\n", width, height, bpp, channels);
+    ESP_LOGD(TAG, "%s", zw.c_str());
+    ESP_LOGD(TAG, "w %d, h %d, b %d, c %d", width, height, bpp, channels);
 
 }
 
@@ -543,7 +543,7 @@ void CImageBasis::Resize(int _new_dx, int _new_dy, CImageBasis *_target)
 {
     if ((_target->height != _new_dy) || (_target->width != _new_dx) || (_target->channels != channels))
     {
-        printf("CImageBasis::Resize - Target image size does not fit !!");
+        ESP_LOGD(TAG, "CImageBasis::Resize - Target image size does not fit!");
         return;
     }
 

+ 2 - 2
code/components/jomjol_image_proc/CRotateImage.cpp

@@ -280,13 +280,13 @@ void CRotateImage::RotateAntiAliasing(float _angle, int _centerx, int _centery)
 
 void CRotateImage::Rotate(float _angle)
 {
-//    printf("width %d, height %d\n", width, height);
+//    ESP_LOGD(TAG, "width %d, height %d", width, height);
     Rotate(_angle, width / 2, height / 2);
 }
 
 void CRotateImage::RotateAntiAliasing(float _angle)
 {
-//    printf("width %d, height %d\n", width, height);
+//    ESP_LOGD(TAG, "width %d, height %d", width, height);
     RotateAntiAliasing(_angle, width / 2, height / 2);
 }
 

+ 104 - 5
code/components/jomjol_logfile/ClassLogFile.cpp

@@ -16,7 +16,7 @@ extern "C" {
 
 static const char *TAG = "log";
 
-ClassLogFile LogFile("/sdcard/log/message", "log_%Y-%m-%d.txt");
+ClassLogFile LogFile("/sdcard/log/message", "log_%Y-%m-%d.txt", "/sdcard/log/data", "data_%Y-%m-%d.txt");
 
 void ClassLogFile::WriteHeapInfo(std::string _id)
 {
@@ -62,6 +62,57 @@ std::string ClassLogFile::getESPHeapInfo(){
 	return 	espInfoResultStr;
 }
 
+void ClassLogFile::WriteToData(std::string _timestamp, std::string _name, std::string  _ReturnRawValue, std::string  _ReturnValue, std::string  _ReturnPreValue, std::string  _ReturnRateValue, std::string  _ReturnChangeAbsolute, std::string  _ErrorMessageText, std::string  _digital, std::string  _analog)
+{
+    ESP_LOGD(TAG, "Start WriteToData\n");
+    time_t rawtime;
+    struct tm* timeinfo;
+    char buffer[30];
+
+    time(&rawtime);
+    timeinfo = localtime(&rawtime);
+
+    strftime(buffer, 30, datafile.c_str(), timeinfo);
+    std::string logpath = dataroot + "/" + buffer; 
+    
+    FILE* pFile;
+    std::string zwtime;
+
+    if (!doLogFile){
+        return;
+    }
+
+    ESP_LOGD(TAG, "Datalogfile: %s", logpath.c_str());
+    pFile = fopen(logpath.c_str(), "a+");
+
+    if (pFile!=NULL) {
+        fputs(_timestamp.c_str(), pFile);
+        fputs("\t", pFile);
+        fputs(_name.c_str(), pFile);
+        fputs("\t", pFile);
+        fputs(_ReturnRawValue.c_str(), pFile);
+        fputs("\t", pFile);
+        fputs(_ReturnValue.c_str(), pFile);
+        fputs("\t", pFile);
+        fputs(_ReturnPreValue.c_str(), pFile);
+        fputs("\t", pFile);
+        fputs(_ReturnRateValue.c_str(), pFile);
+        fputs("\t", pFile);
+        fputs(_ReturnChangeAbsolute.c_str(), pFile);
+        fputs("\t", pFile);
+        fputs(_ErrorMessageText.c_str(), pFile);
+        fputs(_digital.c_str(), pFile);
+        fputs(_analog.c_str(), pFile);
+        fputs("\n", pFile);
+
+        fclose(pFile);    
+    } else {
+        ESP_LOGI(TAG, "Can't open data file %s", logpath.c_str());
+    }
+
+}
+
+
 void ClassLogFile::WriteToDedicatedFile(std::string _fn, std::string info, bool _time)
 {
     FILE* pFile;
@@ -73,7 +124,7 @@ void ClassLogFile::WriteToDedicatedFile(std::string _fn, std::string info, bool
 
 //    pFile = OpenFileAndWait(_fn.c_str(), "a"); 
     pFile = fopen(_fn.c_str(), "a+");
-//    printf("Logfile opened: %s\n", _fn.c_str());
+//    ESP_LOGD(TAG, "Logfile opened: %s", _fn.c_str());
 
     if (pFile!=NULL) {
         if (_time)
@@ -129,7 +180,7 @@ void ClassLogFile::WriteToFile(std::string info, bool _time)
     std::string logpath = logroot + "/" + buffer; 
     
     WriteToDedicatedFile(logpath, info, _time);
-    printf((info + "\n").c_str());
+    ESP_LOGD(TAG, "%s", info.c_str());
 }
 
 std::string ClassLogFile::GetCurrentFileName()
@@ -161,6 +212,8 @@ void ClassLogFile::RemoveOld()
     rawtime = addDays(rawtime, -retentionInDays);
     timeinfo = localtime(&rawtime);
     
+
+//////////////////////  message /////////////////////////////////////////
     strftime(cmpfilename, 30, logfile.c_str(), timeinfo);
     //ESP_LOGE(TAG, "log file name to compare: %s", cmpfilename);
 
@@ -176,7 +229,7 @@ void ClassLogFile::RemoveOld()
     while ((entry = readdir(dir)) != NULL) {
         if (entry->d_type == DT_REG) {
             //ESP_LOGI(TAG, "list log file : %s %s", entry->d_name, cmpfilename);
-            if ((strlen(entry->d_name) == strlen(cmpfilename)) && (strcmp(entry->d_name, cmpfilename) < 0)) {
+            if ((strlen(entry->d_name) == strlen(cmpfilename)) && (strcmp(entry->d_name, cmpfilename) == 0)) {
                 ESP_LOGI(TAG, "delete log file : %s", entry->d_name);
                 std::string filepath = logroot + "/" + entry->d_name; 
                 if (unlink(filepath.c_str()) == 0) {
@@ -189,15 +242,61 @@ void ClassLogFile::RemoveOld()
             }
         }
     }
+    LogFile.WriteToFile("logfiles deleted: " + std::to_string(deleted) + " files not deleted (incl. leer.txt): " + std::to_string(notDeleted));	
+    closedir(dir);
+
+
+//////////////////////  data /////////////////////////////////////////
+    strftime(cmpfilename, 30, datafile.c_str(), timeinfo);
+    //ESP_LOGE(TAG, "log file name to compare: %s", cmpfilename);
+
+    dir = opendir(dataroot.c_str());
+    if (!dir) {
+        ESP_LOGI(TAG, "Failed to stat dir : %s", dataroot.c_str());
+        return;
+    }
+
+    deleted = 0;
+    notDeleted = 0;
+    while ((entry = readdir(dir)) != NULL) {
+        if (entry->d_type == DT_REG) {
+            //ESP_LOGI(TAG, "list log file : %s %s", entry->d_name, cmpfilename);
+            if ((strlen(entry->d_name) == strlen(cmpfilename)) && (strcmp(entry->d_name, cmpfilename) < 0)) {
+                ESP_LOGI(TAG, "delete data file : %s", entry->d_name);
+                std::string filepath = logroot + "/" + entry->d_name; 
+                if (unlink(filepath.c_str()) == 0) {
+                    deleted ++;
+                } else {
+                    ESP_LOGE(TAG, "can't delete file : %s", entry->d_name);
+                }
+            } else {
+                notDeleted ++;
+            }
+        }
+    }
     ESP_LOGI(TAG, "%d older log files deleted. %d current log files not deleted.", deleted, notDeleted);
     closedir(dir);
 }
 
-ClassLogFile::ClassLogFile(std::string _logroot, std::string _logfile)
+void ClassLogFile::CreateLogDirectories()
+{
+    MakeDir("/sdcard/log");
+    MakeDir("/sdcard/log/data");
+    MakeDir("/sdcard/log/analog");
+    MakeDir("/sdcard/log/digit");
+    MakeDir("/sdcard/log/message");
+    MakeDir("/sdcard/log/source");
+}
+
+
+ClassLogFile::ClassLogFile(std::string _logroot, std::string _logfile, std::string _logdatapath, std::string _datafile)
 {
     logroot = _logroot;
     logfile =  _logfile;
+    datafile = _datafile;
+    dataroot = _logdatapath;
     doLogFile = true;
     retentionInDays = 10;
     loglevel = 0;
+    MakeDir("/sdcard/log/data");
 }

+ 9 - 1
code/components/jomjol_logfile/ClassLogFile.h

@@ -7,11 +7,13 @@ class ClassLogFile
 private:
     std::string logroot;
     std::string logfile;
+    std::string dataroot;
+    std::string datafile;
     bool doLogFile;
     unsigned short retentionInDays;
     int loglevel;
 public:
-    ClassLogFile(std::string _logpath, std::string _logfile);
+    ClassLogFile(std::string _logpath, std::string _logfile, std::string _logdatapath, std::string _datafile);
 
     std::string getESPHeapInfo();
 
@@ -22,10 +24,16 @@ public:
     void SwitchOnOff(bool _doLogFile);
     void SetRetention(unsigned short _retentionInDays);
 
+    void CreateLogDirectories();
+
     void WriteToFile(std::string info, bool _time = true);
     void WriteToDedicatedFile(std::string _fn, std::string info, bool _time = true);
     void RemoveOld();
 
+//    void WriteToData(std::string _ReturnRawValue, std::string _ReturnValue, std::string _ReturnPreValue, std::string _ErrorMessageText, std::string _digital, std::string _analog);
+    void WriteToData(std::string _timestamp, std::string _name, std::string  _ReturnRawValue, std::string  _ReturnValue, std::string  _ReturnPreValue, std::string  _ReturnRateValue, std::string  _ReturnChangeAbsolute, std::string  _ErrorMessageText, std::string  _digital, std::string  _analog);
+
+
     std::string GetCurrentFileName();
 };
 

+ 0 - 2
code/components/jomjol_mqtt/interface_mqtt.cpp

@@ -32,7 +32,6 @@ bool MQTTPublish(std::string _key, std::string _content, int retained_flag){
     }
     zw = "MQTT - sent publish successful in MQTTPublish, msg_id=" + std::to_string(msg_id) + ", " + _key + ", " + _content;
     if (debugdetail) LogFile.WriteToFile(zw);
-    ESP_LOGD(TAG_INTERFACEMQTT, "sent publish successful in MQTTPublish, msg_id=%d, %s, %s", msg_id, _key.c_str(), _content.c_str());
     return true;
 }
 
@@ -223,7 +222,6 @@ void MQTTconnected(){
        if (subscribeFunktionMap != NULL) {
             for(std::map<std::string, std::function<bool(std::string, char*, int)>>::iterator it = subscribeFunktionMap->begin(); it != subscribeFunktionMap->end(); ++it) {
                 int msg_id = esp_mqtt_client_subscribe(client, it->first.c_str(), 0);
-                ESP_LOGD(TAG_INTERFACEMQTT, "topic %s subscribe successful, msg_id=%d", it->first.c_str(), msg_id);
                 LogFile.WriteToFile("MQTT - topic " + it->first + " subscribe successful, msg_id=" + std::to_string(msg_id));
             }
         }

+ 19 - 15
code/components/jomjol_tfliteclass/CTfLiteClass.cpp

@@ -1,11 +1,15 @@
 #include "CTfLiteClass.h"
 #include "ClassLogFile.h"
 #include "Helper.h"
+#include "esp_log.h"
 
 #include <sys/stat.h>
 
 // #define DEBUG_DETAIL_ON
 
+
+static const char *TAG = "ctflite_class";
+
 float CTfLiteClass::GetOutputValue(int nr)
 {
     TfLiteTensor* output2 = this->interpreter->output(0);
@@ -41,7 +45,7 @@ int CTfLiteClass::GetOutClassification(int _von, int _bis)
     return -1;
 
   int numeroutput = output2->dims->data[1];
-  //printf("\n number output neurons: %d\n\n", numeroutput);
+  //ESP_LOGD(TAG, "number output neurons: %d", numeroutput);
 
   if (_bis == -1)
     _bis = numeroutput -1;
@@ -51,7 +55,7 @@ int CTfLiteClass::GetOutClassification(int _von, int _bis)
 
   if (_bis >= numeroutput)
   {
-    printf("ANZAHL OUTPUT NEURONS passt nicht zu geforderter Classifizierung!");
+    ESP_LOGD(TAG, "ANZAHL OUTPUT NEURONS passt nicht zu geforderter Classifizierung!");
     return -1;
   }
 
@@ -74,13 +78,13 @@ void CTfLiteClass::GetInputDimension(bool silent = false)
   TfLiteTensor* input2 = this->interpreter->input(0);
 
   int numdim = input2->dims->size;
-  if (!silent)  printf("NumDimension: %d\n", numdim);  
+  if (!silent)  ESP_LOGD(TAG, "NumDimension: %d", numdim);
 
   int sizeofdim;
   for (int j = 0; j < numdim; ++j)
   {
     sizeofdim = input2->dims->data[j];
-    if (!silent) printf("SizeOfDimension %d: %d\n", j, sizeofdim);  
+    if (!silent) ESP_LOGD(TAG, "SizeOfDimension %d: %d", j, sizeofdim);
     if (j == 1) im_height = sizeofdim;
     if (j == 2) im_width = sizeofdim;
     if (j == 3) im_channel = sizeofdim;
@@ -106,13 +110,13 @@ int CTfLiteClass::GetAnzOutPut(bool silent)
   TfLiteTensor* output2 = this->interpreter->output(0);
 
   int numdim = output2->dims->size;
-  if (!silent) printf("NumDimension: %d\n", numdim);  
+  if (!silent) ESP_LOGD(TAG, "NumDimension: %d", numdim);
 
   int sizeofdim;
   for (int j = 0; j < numdim; ++j)
   {
     sizeofdim = output2->dims->data[j];
-    if (!silent) printf("SizeOfDimension %d: %d\n", j, sizeofdim);  
+    if (!silent) ESP_LOGD(TAG, "SizeOfDimension %d: %d", j, sizeofdim);
   }
 
 
@@ -123,7 +127,7 @@ int CTfLiteClass::GetAnzOutPut(bool silent)
   for (int i = 0; i < numeroutput; ++i)
   {
    fo = output2->data.f[i];
-    if (!silent) printf("Result %d: %f\n", i, fo);  
+    if (!silent) ESP_LOGD(TAG, "Result %d: %f", i, fo);
   }
   return numeroutput;
 }
@@ -143,7 +147,7 @@ bool CTfLiteClass::LoadInputImageBasis(CImageBasis *rs)
     unsigned int w = rs->width;
     unsigned int h = rs->height;
     unsigned char red, green, blue;
-//    printf("Image: %s size: %d x %d\n", _fn.c_str(), w, h);
+//    ESP_LOGD(TAG, "Image: %s size: %d x %d\n", _fn.c_str(), w, h);
 
     input_i = 0;
     float* input_data_ptr = (interpreter->input(0))->data.f;
@@ -174,9 +178,9 @@ void CTfLiteClass::MakeAllocate()
 {
     static tflite::AllOpsResolver resolver;
 
-//    printf(LogFile.getESPHeapInfo().c_str()); printf("\n");
+//    ESP_LOGD(TAG, "%s", LogFile.getESPHeapInfo().c_str());
     this->interpreter = new tflite::MicroInterpreter(this->model, resolver, this->tensor_arena, this->kTensorArenaSize, this->error_reporter);
-//    printf(LogFile.getESPHeapInfo().c_str()); printf("\n");
+//    ESP_LOGD(TAG, "%s", LogFile.getESPHeapInfo().c_str());
 
     TfLiteStatus allocate_status = this->interpreter->AllocateTensors();
     if (allocate_status != kTfLiteOk) {
@@ -186,14 +190,14 @@ void CTfLiteClass::MakeAllocate()
     this->GetInputDimension();   
     return;
   }
-//    printf("Allocate Done.\n");
+//    ESP_LOGD(TAG, "Allocate Done");
 }
 
 void CTfLiteClass::GetInputTensorSize(){
 #ifdef DEBUG_DETAIL_ON    
     float *zw = this->input;
     int test = sizeof(zw);
-    printf("Input Tensor Dimension: %d\n", test);       
+    ESP_LOGD(TAG, "Input Tensor Dimension: %d", test);
 #endif
 }
 
@@ -213,7 +217,7 @@ unsigned char* CTfLiteClass::ReadFileToCharArray(std::string _fn)
 
     if (size == -1)
     {
-  		printf("\nFile doesn't exist.\n");
+      ESP_LOGD(TAG, "File doesn't exist");
       return NULL;
     }
 
@@ -222,7 +226,7 @@ unsigned char* CTfLiteClass::ReadFileToCharArray(std::string _fn)
     while (!result && (anz < 6))    // maximal 5x versuchen (= 5s)
     {
 #ifdef DEBUG_DETAIL_ON      
-		    printf("Speicher ist voll - Versuche es erneut: %d.\n", anz);
+		    ESP_LOGD(TAG, "Speicher ist voll - Versuche es erneut: %d", anz);
 #endif
         result = (unsigned char*) malloc(size);
         anz++;
@@ -234,7 +238,7 @@ unsigned char* CTfLiteClass::ReadFileToCharArray(std::string _fn)
         fread(result, 1, size, f);
         fclose(f);        
 	  }else {
-		  printf("\nNo free memory available.\n");
+		  ESP_LOGD(TAG, "No free memory available");
 	}    
 
 

+ 51 - 53
code/components/jomjol_tfliteclass/server_tflite.cpp

@@ -67,7 +67,7 @@ bool isSetupModusActive() {
 void KillTFliteTasks()
 {
 #ifdef DEBUG_DETAIL_ON          
-    printf("Handle: xHandleblink_task_doFlow: %ld\n", (long) xHandleblink_task_doFlow);  
+    ESP_LOGD(TAGTFLITE, "Handle: xHandleblink_task_doFlow: %ld", (long) xHandleblink_task_doFlow);
 #endif  
     if (xHandleblink_task_doFlow != NULL)
     {
@@ -75,12 +75,12 @@ void KillTFliteTasks()
         xHandleblink_task_doFlow = NULL;
         vTaskDelete(xHandleblink_task_doFlowTmp);
 #ifdef DEBUG_DETAIL_ON      
-        printf("Killed: xHandleblink_task_doFlow\n");
+        ESP_LOGD(TAGTFLITE, "Killed: xHandleblink_task_doFlow");
 #endif
     }
 
 #ifdef DEBUG_DETAIL_ON      
-    printf("Handle: xHandletask_autodoFlow: %ld\n", (long) xHandletask_autodoFlow);  
+    ESP_LOGD(TAGTFLITE, "Handle: xHandletask_autodoFlow: %ld", (long) xHandletask_autodoFlow);
 #endif
     if (xHandletask_autodoFlow != NULL)
     {
@@ -88,7 +88,7 @@ void KillTFliteTasks()
         xHandletask_autodoFlow = NULL;
         vTaskDelete(xHandletask_autodoFlowTmp);
 #ifdef DEBUG_DETAIL_ON      
-        printf("Killed: xHandletask_autodoFlow\n");
+        ESP_LOGD(TAGTFLITE, "Killed: xHandletask_autodoFlow");
 #endif
     }
 
@@ -97,11 +97,11 @@ void KillTFliteTasks()
 void doInit(void)
 {
 #ifdef DEBUG_DETAIL_ON             
-    printf("Start tfliteflow.InitFlow(config);\n");
+    ESP_LOGD(TAGTFLITE, "Start tfliteflow.InitFlow(config);");
 #endif
     tfliteflow.InitFlow(CONFIG_FILE);
 #ifdef DEBUG_DETAIL_ON      
-    printf("Finished tfliteflow.InitFlow(config);\n");
+    ESP_LOGD(TAGTFLITE, "Finished tfliteflow.InitFlow(config);");
 #endif
 }
 
@@ -110,13 +110,13 @@ bool doflow(void)
 {
     
     std::string zw_time = gettimestring(LOGFILE_TIME_FORMAT);
-    printf("doflow - start %s\n", zw_time.c_str());
+    ESP_LOGD(TAGTFLITE, "doflow - start %s", zw_time.c_str());
     flowisrunning = true;
     tfliteflow.doFlow(zw_time);
     flowisrunning = false;
 
 #ifdef DEBUG_DETAIL_ON      
-    printf("doflow - end %s\n", zw_time.c_str());
+    ESP_LOGD(TAGTFLITE, "doflow - end %s", zw_time.c_str());
 #endif    
     return true;
 }
@@ -124,7 +124,7 @@ bool doflow(void)
 void blink_task_doFlow(void *pvParameter)
 {
 #ifdef DEBUG_DETAIL_ON          
-    printf("blink_task_doFlow\n");
+    ESP_LOGD(TAGTFLITE, "blink_task_doFlow");
 #endif
     if (!flowisrunning)
     {
@@ -141,7 +141,7 @@ esp_err_t handler_init(httpd_req_t *req)
 {
 #ifdef DEBUG_DETAIL_ON      
     LogFile.WriteHeapInfo("handler_init - Start");       
-    printf("handler_doinit uri:\n"); printf(req->uri); printf("\n");
+    ESP_LOGD(TAGTFLITE, "handler_doinit uri: %s", req->uri);
 #endif
 
     const char* resp_str = "Init started<br>";
@@ -167,7 +167,7 @@ esp_err_t handler_doflow(httpd_req_t *req)
     LogFile.WriteHeapInfo("handler_doflow - Start");       
 #endif
 
-    printf("handler_doFlow uri: "); printf(req->uri); printf("\n");
+    ESP_LOGD(TAGTFLITE, "handler_doFlow uri: %s", req->uri);
 
     if (flowisrunning)
     {
@@ -199,7 +199,7 @@ esp_err_t handler_json(httpd_req_t *req)
 #endif
 
 
-    printf("handler_JSON uri:\n"); printf(req->uri); printf("\n");
+    ESP_LOGD(TAGTFLITE, "handler_JSON uri: %s", req->uri);
 
     char _query[100];
 //    char _size[10];
@@ -236,18 +236,18 @@ esp_err_t handler_wasserzaehler(httpd_req_t *req)
     std::string _type = "value";
     string zw;
 
-    printf("handler_wasserzaehler uri:\n"); printf(req->uri); printf("\n");
+    ESP_LOGD(TAGTFLITE, "handler_wasserzaehler uri: %s", req->uri);
 
     char _query[100];
     char _size[10];
 
     if (httpd_req_get_url_query_str(req, _query, 100) == ESP_OK)
     {
-//        printf("Query: "); printf(_query); printf("\n");
+//        ESP_LOGD(TAGTFLITE, "Query: %s", _query);
         if (httpd_query_key_value(_query, "all", _size, 10) == ESP_OK)
         {
 #ifdef DEBUG_DETAIL_ON       
-            printf("all is found"); printf(_size); printf("\n"); 
+            ESP_LOGD(TAGTFLITE, "all is found%s", _size);
 #endif
             _all = true;
         }
@@ -255,7 +255,7 @@ esp_err_t handler_wasserzaehler(httpd_req_t *req)
         if (httpd_query_key_value(_query, "type", _size, 10) == ESP_OK)
         {
 #ifdef DEBUG_DETAIL_ON       
-            printf("all is found"); printf(_size); printf("\n"); 
+            ESP_LOGD(TAGTFLITE, "all is found: %s", _size);
 #endif
             _type = std::string(_size);
         }
@@ -263,14 +263,14 @@ esp_err_t handler_wasserzaehler(httpd_req_t *req)
         if (httpd_query_key_value(_query, "rawvalue", _size, 10) == ESP_OK)
         {
 #ifdef DEBUG_DETAIL_ON       
-            printf("rawvalue is found"); printf(_size); printf("\n"); 
+            ESP_LOGD(TAGTFLITE, "rawvalue is found: %s", _size);
 #endif
             _rawValue = true;
         }
         if (httpd_query_key_value(_query, "noerror", _size, 10) == ESP_OK)
         {
 #ifdef DEBUG_DETAIL_ON       
-            printf("noerror is found"); printf(_size); printf("\n"); 
+            ESP_LOGD(TAGTFLITE, "noerror is found: %s", _size);
 #endif
             _noerror = true;
         }        
@@ -281,7 +281,7 @@ esp_err_t handler_wasserzaehler(httpd_req_t *req)
     if (_all)
     {
         httpd_resp_set_type(req, "text/plain");
-        printf("TYPE: %s\n", _type.c_str());
+        ESP_LOGD(TAGTFLITE, "TYPE: %s", _type.c_str());
         int _intype = READOUT_TYPE_VALUE;
         if (_type == "prevalue")
             _intype = READOUT_TYPE_PREVALUE;
@@ -292,7 +292,7 @@ esp_err_t handler_wasserzaehler(httpd_req_t *req)
 
 
         zw = tfliteflow.getReadoutAll(_intype);
-        printf("ZW: %s\n", zw.c_str());
+        ESP_LOGD(TAGTFLITE, "ZW: %s", zw.c_str());
         if (zw.length() > 0)
             httpd_resp_sendstr_chunk(req, zw.c_str()); 
         httpd_resp_sendstr_chunk(req, NULL);   
@@ -304,7 +304,7 @@ esp_err_t handler_wasserzaehler(httpd_req_t *req)
         httpd_resp_sendstr_chunk(req, zw.c_str()); 
 
     string query = std::string(_query);
-//    printf("Query: %s\n", query.c_str());
+//    ESP_LOGD(TAGTFLITE, "Query: %s, query.c_str());
     if (query.find("full") != std::string::npos)
     {
         string txt, zw;
@@ -380,7 +380,7 @@ esp_err_t handler_editflow(httpd_req_t *req)
     LogFile.WriteHeapInfo("handler_editflow - Start");       
 #endif
 
-    printf("handler_editflow uri: "); printf(req->uri); printf("\n");
+    ESP_LOGD(TAGTFLITE, "handler_editflow uri: %s", req->uri);
 
     char _query[200];
     char _valuechar[30];
@@ -391,7 +391,7 @@ esp_err_t handler_editflow(httpd_req_t *req)
         if (httpd_query_key_value(_query, "task", _valuechar, 30) == ESP_OK)
         {
 #ifdef DEBUG_DETAIL_ON       
-            printf("task is found: %s\n", _valuechar); 
+            ESP_LOGD(TAGTFLITE, "task is found: %s", _valuechar);
 #endif
             _task = string(_valuechar);
         }
@@ -399,7 +399,7 @@ esp_err_t handler_editflow(httpd_req_t *req)
 
     if (_task.compare("tflite") == 0)
     {
-        printf("Get tflite list\n");
+        ESP_LOGD(TAGTFLITE, "Get tflite list");
         return get_tflite_file_handler(req);
     }
 
@@ -414,8 +414,8 @@ esp_err_t handler_editflow(httpd_req_t *req)
         out = string(_valuechar);  
 
 #ifdef DEBUG_DETAIL_ON       
-        printf("in: "); printf(in.c_str()); printf("\n"); 
-        printf("out: "); printf(out.c_str()); printf("\n"); 
+        ESP_LOGD(TAGTFLITE, "in: %s", in.c_str());
+        ESP_LOGD(TAGTFLITE, "out: %s", out.c_str());
 #endif
 
         in = "/sdcard" + in;
@@ -456,12 +456,12 @@ esp_err_t handler_editflow(httpd_req_t *req)
         dy = stoi(zw);          
 
 #ifdef DEBUG_DETAIL_ON       
-        printf("in: "); printf(in.c_str()); printf("\n"); 
-        printf("out: "); printf(out.c_str()); printf("\n"); 
-        printf("x: "); printf(zw.c_str()); printf("\n"); 
-        printf("y: "); printf(zw.c_str()); printf("\n"); 
-        printf("dx: "); printf(zw.c_str()); printf("\n"); 
-        printf("dy: "); printf(zw.c_str()); printf("\n"); 
+        ESP_LOGD(TAGTFLITE, "in: %s", in.c_str());
+        ESP_LOGD(TAGTFLITE, "out: %s", out.c_str());
+        ESP_LOGD(TAGTFLITE, "x: %s", zw.c_str());
+        ESP_LOGD(TAGTFLITE, "y: %s", zw.c_str());
+        ESP_LOGD(TAGTFLITE, "dx: %s", zw.c_str());
+        ESP_LOGD(TAGTFLITE, "dy: %s", zw.c_str());
 #endif
 
         if (httpd_query_key_value(_query, "enhance", _valuechar, 10) == ESP_OK)
@@ -529,11 +529,11 @@ esp_err_t handler_editflow(httpd_req_t *req)
         }
 
 
-//        printf("Parameter host: "); printf(_host.c_str()); printf("\n"); 
-//        string zwzw = "Do " + _task + " start\n"; printf(zwzw.c_str());
+//        ESP_LOGD(TAGTFLITE, "Parameter host: %s", _host.c_str());
+//        string zwzw = "Do " + _task + " start\n"; ESP_LOGD(TAGTFLITE, zwzw.c_str());
         Camera.SetBrightnessContrastSaturation(bri, con, sat);
         Camera.SetLEDIntensity(intens);
-        printf("test_take - vor MakeImage");
+        ESP_LOGD(TAGTFLITE, "test_take - vor MakeImage");
         std::string zw = tfliteflow.doSingleStep("[MakeImage]", _host);
         httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");
         httpd_resp_sendstr_chunk(req, zw.c_str()); 
@@ -546,9 +546,9 @@ esp_err_t handler_editflow(httpd_req_t *req)
         if (httpd_query_key_value(_query, "host", _valuechar, 30) == ESP_OK) {
             _host = std::string(_valuechar);
         }
-//        printf("Parameter host: "); printf(_host.c_str()); printf("\n"); 
+//        ESP_LOGD(TAGTFLITE, "Parameter host: %s", _host.c_str());
 
-//        string zwzw = "Do " + _task + " start\n"; printf(zwzw.c_str());
+//        string zwzw = "Do " + _task + " start\n"; ESP_LOGD(TAGTFLITE, zwzw.c_str());
         std::string zw = tfliteflow.doSingleStep("[Alignment]", _host);
         httpd_resp_sendstr_chunk(req, zw.c_str()); 
     }
@@ -573,7 +573,7 @@ esp_err_t handler_statusflow(httpd_req_t *req)
     const char* resp_str;
 
 #ifdef DEBUG_DETAIL_ON       
-    printf("handler_prevalue:\n"); printf(req->uri); printf("\n");
+    ESP_LOGD(TAGTFLITE, "handler_prevalue: %s", req->uri);
 #endif
 
     string* zw = tfliteflow.getActStatus();
@@ -651,7 +651,7 @@ esp_err_t handler_prevalue(httpd_req_t *req)
     string zw;
 
 #ifdef DEBUG_DETAIL_ON       
-    printf("handler_prevalue:\n"); printf(req->uri); printf("\n");
+    ESP_LOGD(TAGTFLITE, "handler_prevalue: %s", req->uri);
 #endif
 
     char _query[100];
@@ -661,13 +661,13 @@ esp_err_t handler_prevalue(httpd_req_t *req)
     if (httpd_req_get_url_query_str(req, _query, 100) == ESP_OK)
     {
 #ifdef DEBUG_DETAIL_ON       
-        printf("Query: "); printf(_query); printf("\n");
+        ESP_LOGD(TAGTFLITE, "Query: %s", _query);
 #endif
 
         if (httpd_query_key_value(_query, "value", _size, 10) == ESP_OK)
         {
 #ifdef DEBUG_DETAIL_ON       
-            printf("Value: "); printf(_size); printf("\n"); 
+            ESP_LOGD(TAGTFLITE, "Value: %s", _size);
 #endif
         }
 
@@ -703,7 +703,7 @@ void task_autodoFlow(void *pvParameter)
 {
     int64_t fr_start, fr_delta_ms;
 
-    printf("task_autodoFlow: start\r\n");
+    ESP_LOGD(TAGTFLITE, "task_autodoFlow: start");
     doInit();
     gpio_handler_init();
 
@@ -718,24 +718,23 @@ void task_autodoFlow(void *pvParameter)
     {
         std::string _zw = "task_autodoFlow - next round - Round #" + std::to_string(++countRounds);
         LogFile.WriteToFile(_zw); 
-        printf("Autoflow: start\n");
         fr_start = esp_timer_get_time();
 
         if (flowisrunning)
         {
 #ifdef DEBUG_DETAIL_ON       
-            printf("Autoflow: doFlow is already running!\n");
+            ESP_LOGD(TAGTFLITE, "Autoflow: doFlow is already running!");
 #endif
         }
         else
         {
 #ifdef DEBUG_DETAIL_ON       
-            printf("Autoflow: doFlow is started\n");
+            ESP_LOGD(TAGTFLITE, "Autoflow: doFlow is started");
 #endif
             flowisrunning = true;
             doflow();
 #ifdef DEBUG_DETAIL_ON       
-            printf("Remove older log files\n");
+            ESP_LOGD(TAGTFLITE, "Remove older log files");
 #endif
             LogFile.RemoveOld();
         }
@@ -747,18 +746,17 @@ void task_autodoFlow(void *pvParameter)
         stream << std::fixed << std::setprecision(1) << cputmp;
         string zwtemp = "CPU Temperature: " + stream.str();
         LogFile.WriteToFile(zwtemp); 
-        printf("CPU Temperature: %.2f\n", cputmp);
         fr_delta_ms = (esp_timer_get_time() - fr_start) / 1000;
         if (auto_intervall > fr_delta_ms)
         {
             const TickType_t xDelay = (auto_intervall - fr_delta_ms)  / portTICK_PERIOD_MS;
-            printf("Autoflow: sleep for : %ldms\n", (long) xDelay);
+            ESP_LOGD(TAGTFLITE, "Autoflow: sleep for: %ldms", (long) xDelay);
             vTaskDelay( xDelay );        
         }
     }
     vTaskDelete(NULL); //Delete this task if it exits from the loop above
     xHandletask_autodoFlow = NULL;
-    printf("task_autodoFlow: end\r\n");
+    ESP_LOGD(TAGTFLITE, "task_autodoFlow: end");
 }
 
 void TFliteDoAutoStart()
@@ -767,17 +765,17 @@ void TFliteDoAutoStart()
 
     int _i = configMINIMAL_STACK_SIZE;
 
-    printf("task_autodoFlow configMINIMAL_STACK_SIZE: %d\n", _i);
-    printf("getESPHeapInfo: %s\n", getESPHeapInfo().c_str());
+    ESP_LOGD(TAGTFLITE, "task_autodoFlow configMINIMAL_STACK_SIZE: %d", _i);
+    ESP_LOGD(TAGTFLITE, "getESPHeapInfo: %s", getESPHeapInfo().c_str());
 
     xReturned = xTaskCreate(&task_autodoFlow, "task_autodoFlow", configMINIMAL_STACK_SIZE * 35, NULL, tskIDLE_PRIORITY+1, &xHandletask_autodoFlow);
     if( xReturned != pdPASS )
     {
 
        //Memory: 64 --> 48 --> 35 --> 25
-       printf("ERROR task_autodoFlow konnte nicht erzeugt werden !!\r\n");
+       ESP_LOGD(TAGTFLITE, "ERROR task_autodoFlow konnte nicht erzeugt werden!");
     }
-    printf("getESPHeapInfo: %s\n", getESPHeapInfo().c_str());
+    ESP_LOGD(TAGTFLITE, "getESPHeapInfo: %s", getESPHeapInfo().c_str());
 
 
 }

+ 3 - 4
code/components/jomjol_time_sntp/time_sntp.cpp

@@ -78,14 +78,13 @@ void setup_time()
     ESP_LOGI(TAG, "The current date/time in Berlin is: %s", strftime_buf);
 
     std::string zw = gettimestring("%Y%m%d-%H%M%S");
-    printf("timeist %s\n", zw.c_str());
+    ESP_LOGD(TAG, "timeist %s", zw.c_str());
 }
 
 void setTimeZone(std::string _tzstring)
 {
     setenv("TZ", _tzstring.c_str(), 1);
     tzset();    
-    printf("TimeZone set to %s\n", _tzstring.c_str());
     _tzstring = "Time zone set to " + _tzstring;
     LogFile.WriteToFile(_tzstring);
 }
@@ -109,14 +108,14 @@ static void obtain_time(void)
 
 void reset_servername(std::string _servername)
 {
-    printf("Set SNTP-Server: %s\n", _servername.c_str());
+    ESP_LOGD(TAG, "Set SNTP-Server: %s", _servername.c_str());
     sntp_stop();
     sntp_setoperatingmode(SNTP_OPMODE_POLL);
     sntp_setservername(0, _servername.c_str());
     sntp_init();
     obtain_time();
     std::string zw = gettimestring("%Y%m%d-%H%M%S");
-    printf("Time ist %s\n", zw.c_str());
+    ESP_LOGD(TAG, "Time ist %s", zw.c_str());
 }
 
 static void initialize_sntp(void)

+ 8 - 6
code/components/jomjol_wlan/read_wlanini.cpp

@@ -10,7 +10,9 @@
 #include <sstream>
 #include <iostream>
 #include <string.h>
+#include "esp_log.h"
 
+static const char *TAG = "read_wlanini";
 
 std::vector<string> ZerlegeZeileWLAN(std::string input, std::string _delimiter = "")
 {
@@ -55,7 +57,7 @@ void LoadWlanFromFile(std::string fn, char *&_ssid, char *&_password, char *&_ho
     fn = FormatFileName(fn);
 
     pFile = OpenFileAndWait(fn.c_str(), "r");
-    printf("file loaded\n");
+    ESP_LOGD(TAG, "file loaded");
 
     if (pFile == NULL)
         return;
@@ -66,7 +68,7 @@ void LoadWlanFromFile(std::string fn, char *&_ssid, char *&_password, char *&_ho
 
     while ((line.size() > 0) || !(feof(pFile)))
     {
-//        printf("%s", line.c_str());
+//        ESP_LOGD(TAG, "%s", line.c_str());
         zerlegt = ZerlegeZeileWLAN(line, "=");
         zerlegt[0] = trim(zerlegt[0], " ");
 
@@ -198,7 +200,7 @@ bool ChangeHostName(std::string fn, std::string _newhostname)
     fn = FormatFileName(fn);
     pFile = OpenFileAndWait(fn.c_str(), "r");
 
-    printf("file loaded\n");
+    ESP_LOGD(TAG, "file loaded\n");
 
     if (pFile == NULL)
         return false;
@@ -209,7 +211,7 @@ bool ChangeHostName(std::string fn, std::string _newhostname)
 
     while ((line.size() > 0) || !(feof(pFile)))
     {
-        printf("%s", line.c_str());
+        ESP_LOGD(TAG, "%s", line.c_str());
         zerlegt = ZerlegeZeileWLAN(line, "=");
         zerlegt[0] = trim(zerlegt[0], " ");
 
@@ -242,13 +244,13 @@ bool ChangeHostName(std::string fn, std::string _newhostname)
 
     for (int i = 0; i < neuesfile.size(); ++i)
     {
-        printf(neuesfile[i].c_str());
+        ESP_LOGD(TAG, "%s", neuesfile[i].c_str());
         fputs(neuesfile[i].c_str(), pFile);
     }
 
     fclose(pFile);
 
-    printf("*** Hostname update done ***\n");
+    ESP_LOGD(TAG, "*** Hostname update done ***");
 
     return true;
 }

+ 31 - 24
code/main/main.cpp

@@ -111,8 +111,9 @@ bool Init_NVS_SDCard()
         }
         return false;
     }
-    sdmmc_card_print_info(stdout, card);
 
+    sdmmc_card_print_info(stdout, card);
+    SaveSDCardInfo(card);
     return true;
 }
 
@@ -126,7 +127,7 @@ void task_NoSDBlink(void *pvParameter)
     
     TickType_t xDelay;
     xDelay = 100 / portTICK_PERIOD_MS;
-    printf("SD-Card could not be inialized - STOP THE PROGRAMM HERE\n");
+    ESP_LOGD(TAGMAIN, "SD-Card could not be inialized - STOP THE PROGRAMM HERE");
 
     while (1)
     {
@@ -146,15 +147,15 @@ extern "C" void app_main(void)
     string versionFormated = "Branch: '" + std::string(GIT_BRANCH) + "', Tag: '" + std::string(GIT_TAG) + \
             "', Revision: " + std::string(GIT_REV) +", Date/Time: " + std::string(BUILD_TIME);
 
-    printf("=============================================================================================\n");
-    printf("%s\n", versionFormated.c_str());
-    printf("=============================================================================================\n");
+    ESP_LOGD(TAGMAIN, "=============================================================================================");
+    ESP_LOGD(TAGMAIN, "%s", versionFormated.c_str());
+    ESP_LOGD(TAGMAIN, "=============================================================================================");
 
     PowerResetCamera();
     esp_err_t cam = Camera.InitCam();
     Camera.LightOnOff(false);
     xDelay = 2000 / portTICK_PERIOD_MS;
-    printf("After camera initialization: sleep for : %ldms\n", (long) xDelay);
+    ESP_LOGD(TAGMAIN, "After camera initialization: sleep for: %ldms", (long) xDelay);
     vTaskDelay( xDelay );   
 
 
@@ -166,35 +167,46 @@ extern "C" void app_main(void)
 
     CheckOTAUpdate();
 
+    LogFile.CreateLogDirectories();
+/*
+    int mk_ret = mkdir("/sdcard/new_fd_mkdir", 0775);
+    ESP_LOGI(TAGMAIN, "mkdir ret %d", mk_ret);
+    mk_ret = mkdir("/sdcard/new_fd_mkdir/test", 0775);
+    ESP_LOGI(TAGMAIN, "mkdir ret %d", mk_ret);
+    MakeDir("/sdcard/test2");
+    MakeDir("/sdcard/test2/intern");
+*/
+
+
     char *ssid = NULL, *passwd = NULL, *hostname = NULL, *ip = NULL, *gateway = NULL, *netmask = NULL, *dns = NULL;
     LoadWlanFromFile("/sdcard/wlan.ini", ssid, passwd, hostname, ip, gateway, netmask, dns);
 
     if (ssid != NULL && passwd != NULL)
 #ifdef __HIDE_PASSWORD
-        printf("\nWLan: %s, XXXXXX\n", ssid);
+        ESP_LOGD(TAGMAIN, "WLan: %s, XXXXXX", ssid);
 #else
-        printf("\nWLan: %s, %s\n", ssid, passwd);
+        ESP_LOGD(TAGMAIN, "WLan: %s, %s", ssid, passwd);
 #endif        
 
     else
-        printf("No SSID and PASSWORD set!!!");
+        ESP_LOGD(TAGMAIN, "No SSID and PASSWORD set!!!");
 
     if (hostname != NULL)
-        printf("Hostename: %s\n", hostname);
+        ESP_LOGD(TAGMAIN, "Hostename: %s", hostname);
     else
-        printf("Hostname not set.\n");
+        ESP_LOGD(TAGMAIN, "Hostname not set");
 
     if (ip != NULL && gateway != NULL && netmask != NULL)
-       printf("Fixed IP: %s, Gateway %s, Netmask %s\n", ip, gateway, netmask);
+       ESP_LOGD(TAGMAIN, "Fixed IP: %s, Gateway %s, Netmask %s", ip, gateway, netmask);
     if (dns != NULL)
-       printf("DNS IP: %s\n", dns);
+       ESP_LOGD(TAGMAIN, "DNS IP: %s", dns);
 
 
     wifi_init_sta(ssid, passwd, hostname, ip, gateway, netmask, dns);   
 
 
     xDelay = 2000 / portTICK_PERIOD_MS;
-    printf("main: sleep for : %ldms\n", (long) xDelay);
+    ESP_LOGD(TAGMAIN, "main: sleep for: %ldms", (long) xDelay);
     vTaskDelay( xDelay );   
     setup_time();
     setBootTime();
@@ -205,22 +217,18 @@ extern "C" void app_main(void)
     LogFile.SwitchOnOff(false);
 
     std::string zw = gettimestring("%Y%m%d-%H%M%S");
-    printf("time %s\n", zw.c_str());    
+    ESP_LOGD(TAGMAIN, "time %s", zw.c_str());
 
     size_t _hsize = getESPHeapSize();
     if (_hsize < 4000000)
     {
         std::string _zws = "Not enough PSRAM available. Expected 4.194.304 MByte - available: " + std::to_string(_hsize);
         _zws = _zws + "\nEither not initialzed, too small (2MByte only) or not present at all. Firmware cannot start!!";
-        printf(_zws.c_str());
         LogFile.SwitchOnOff(true);
         LogFile.WriteToFile(_zws);
         LogFile.SwitchOnOff(false);
     } else {
         if (cam != ESP_OK) {
-                ESP_LOGE(TAGMAIN, "Failed to initialize camera module. "
-                    "Check that your camera module is working and connected properly.");
-
                 LogFile.SwitchOnOff(true);
                 LogFile.WriteToFile("Failed to initialize camera module. "
                         "Check that your camera module is working and connected properly.");
@@ -229,7 +237,6 @@ extern "C" void app_main(void)
 // Test Camera            
             camera_fb_t * fb = esp_camera_fb_get();
             if (!fb) {
-                ESP_LOGE(TAGMAIN, "esp_camera_fb_get: Camera Capture Failed");
                 LogFile.SwitchOnOff(true);
                 LogFile.WriteToFile("Camera cannot be initialzed. "
                         "System will reboot.");
@@ -243,10 +250,10 @@ extern "C" void app_main(void)
 
 
     xDelay = 2000 / portTICK_PERIOD_MS;
-    printf("main: sleep for : %ldms\n", (long) xDelay*10);
+    ESP_LOGD(TAGMAIN, "main: sleep for: %ldms", (long) xDelay*10);
     vTaskDelay( xDelay ); 
 
-    printf("starting server\n");
+    ESP_LOGD(TAGMAIN, "starting server");
 
     server = start_webserver();   
     register_server_camera_uri(server); 
@@ -256,10 +263,10 @@ extern "C" void app_main(void)
 
     gpio_handler_create(server);
 
-    printf("vor reg server main\n");
+    ESP_LOGD(TAGMAIN, "vor reg server main");
     register_server_main_uri(server, "/sdcard");
 
-    printf("vor dotautostart\n");
+    ESP_LOGD(TAGMAIN, "vor dotautostart");
     TFliteDoAutoStart();
 
 }

+ 81 - 13
code/main/server_main.cpp

@@ -14,6 +14,9 @@
 #include "esp_wifi.h"
 
 #include "server_tflite.h"
+#include "esp_log.h"
+
+#include "Helper.h"
 
 //#define DEBUG_DETAIL_ON      
 
@@ -38,11 +41,11 @@ esp_err_t info_get_handler(httpd_req_t *req)
 
     if (httpd_req_get_url_query_str(req, _query, 200) == ESP_OK)
     {
-        printf("Query: "); printf(_query); printf("\n");
+        ESP_LOGD(TAG_SERVERMAIN, "Query: %s", _query);
         
         if (httpd_query_key_value(_query, "type", _valuechar, 30) == ESP_OK)
         {
-            printf("type is found"); printf(_valuechar); printf("\n"); 
+            ESP_LOGD(TAG_SERVERMAIN, "type is found: %s", _valuechar);
             _task = std::string(_valuechar);
         }
     };
@@ -134,6 +137,71 @@ esp_err_t info_get_handler(httpd_req_t *req)
         return ESP_OK;        
     }
 
+    if (_task.compare("SDCardPartitionSize") == 0)
+    {
+        std::string zw;
+        zw = getSDCardPartitionSize();
+        httpd_resp_sendstr_chunk(req, zw.c_str());
+        httpd_resp_sendstr_chunk(req, NULL);  
+        return ESP_OK;        
+    }
+
+    if (_task.compare("SDCardFreePartitionSpace") == 0)
+    {
+        std::string zw;
+        zw = getSDCardFreePartitionSpace();
+        httpd_resp_sendstr_chunk(req, zw.c_str());
+        httpd_resp_sendstr_chunk(req, NULL);  
+        return ESP_OK;        
+    }
+
+    if (_task.compare("SDCardPartitionAllocationSize") == 0)
+    {
+        std::string zw;
+        zw = getSDCardPartitionAllocationSize();
+        httpd_resp_sendstr_chunk(req, zw.c_str());
+        httpd_resp_sendstr_chunk(req, NULL);  
+        return ESP_OK;        
+    }
+
+    if (_task.compare("SDCardManufacturer") == 0)
+    {
+        std::string zw;
+        zw = getSDCardManufacturer(); 
+        httpd_resp_sendstr_chunk(req, zw.c_str());
+        httpd_resp_sendstr_chunk(req, NULL);  
+        return ESP_OK;        
+    }
+
+    if (_task.compare("SDCardName") == 0)
+    {
+        std::string zw;
+        zw = getSDCardName(); 
+        httpd_resp_sendstr_chunk(req, zw.c_str());
+        httpd_resp_sendstr_chunk(req, NULL);  
+        return ESP_OK;        
+    }
+
+    if (_task.compare("SDCardCapacity") == 0)
+    {
+        std::string zw;
+        zw = getSDCardCapacity();
+        httpd_resp_sendstr_chunk(req, zw.c_str());
+        httpd_resp_sendstr_chunk(req, NULL);  
+        return ESP_OK;        
+    }
+
+    if (_task.compare("SDCardSectorSize") == 0)
+    {
+        std::string zw;
+        zw = getSDCardSectorSize();
+        httpd_resp_sendstr_chunk(req, zw.c_str());
+        httpd_resp_sendstr_chunk(req, NULL);  
+        return ESP_OK;        
+    }
+
+
+
     return ESP_OK;
 }
 
@@ -153,7 +221,7 @@ esp_err_t hello_main_handler(httpd_req_t *req)
 #endif
 
     char filepath[50];
-    printf("uri: %s\n", req->uri);
+    ESP_LOGD(TAG_SERVERMAIN, "uri: %s\n", req->uri);
     int _pos;
     esp_err_t res;
 
@@ -162,7 +230,7 @@ esp_err_t hello_main_handler(httpd_req_t *req)
 
     const char *filename = get_path_from_uri(filepath, base_path,
                                              req->uri - 1, sizeof(filepath));    
-    printf("1 uri: %s, filename: %s, filepath: %s\n", req->uri, filename, filepath);
+    ESP_LOGD(TAG_SERVERMAIN, "1 uri: %s, filename: %s, filepath: %s", req->uri, filename, filepath);
 
     if ((strcmp(req->uri, "/") == 0))
     {
@@ -180,13 +248,13 @@ esp_err_t hello_main_handler(httpd_req_t *req)
     }
 
     if (filetosend == "/sdcard/html/index.html" && isSetupModusActive()) {
-        printf("System is in setup mode --> index.html --> setup.html");
+        ESP_LOGD(TAG_SERVERMAIN, "System is in setup mode --> index.html --> setup.html");
         filetosend = "/sdcard/html/setup.html";
     }
 
-    printf("Filename: %s\n", filename);
+    ESP_LOGD(TAG_SERVERMAIN, "Filename: %s", filename);
     
-    printf("File requested: %s\n", filetosend.c_str());    
+    ESP_LOGD(TAG_SERVERMAIN, "File requested: %s", filetosend.c_str());
 
     if (!filename) {
         ESP_LOGE(TAG_SERVERMAIN, "Filename is too long");
@@ -216,17 +284,17 @@ esp_err_t hello_main_handler(httpd_req_t *req)
 esp_err_t img_tmp_handler(httpd_req_t *req)
 {
     char filepath[50];
-    printf("uri: %s\n", req->uri);
+    ESP_LOGD(TAG_SERVERMAIN, "uri: %s", req->uri);
 
     char *base_path = (char*) req->user_ctx;
     std::string filetosend(base_path);
 
     const char *filename = get_path_from_uri(filepath, base_path,
                                              req->uri  + sizeof("/img_tmp/") - 1, sizeof(filepath));    
-    printf("1 uri: %s, filename: %s, filepath: %s\n", req->uri, filename, filepath);
+    ESP_LOGD(TAG_SERVERMAIN, "1 uri: %s, filename: %s, filepath: %s", req->uri, filename, filepath);
 
     filetosend = filetosend + "/img_tmp/" + std::string(filename);
-    printf("File to upload: %s\n", filetosend.c_str());    
+    ESP_LOGD(TAG_SERVERMAIN, "File to upload: %s", filetosend.c_str());
 
     esp_err_t res = send_file(req, filetosend); 
     if (res != ESP_OK)
@@ -245,17 +313,17 @@ esp_err_t img_tmp_virtual_handler(httpd_req_t *req)
 
     char filepath[50];
 
-    printf("uri: %s\n", req->uri);
+    ESP_LOGD(TAG_SERVERMAIN, "uri: %s", req->uri);
 
     char *base_path = (char*) req->user_ctx;
     std::string filetosend(base_path);
 
     const char *filename = get_path_from_uri(filepath, base_path,
                                              req->uri  + sizeof("/img_tmp/") - 1, sizeof(filepath));    
-    printf("1 uri: %s, filename: %s, filepath: %s\n", req->uri, filename, filepath);
+    ESP_LOGD(TAG_SERVERMAIN, "1 uri: %s, filename: %s, filepath: %s", req->uri, filename, filepath);
 
     filetosend = std::string(filename);
-    printf("File to upload: %s\n", filetosend.c_str()); 
+    ESP_LOGD(TAG_SERVERMAIN, "File to upload: %s", filetosend.c_str());
 
     if (filetosend == "raw.jpg")
     {

+ 104 - 0
code/test/components/jomjol-flowcontroll/test_ZeigerEvalAnalogToDigitNeu.cpp

@@ -0,0 +1,104 @@
+#include <unity.h>
+#include <ClassFlowCNNGeneral.h>
+
+class UnderTestCNNGeneral : public ClassFlowCNNGeneral {
+    public:
+        UnderTestCNNGeneral( ClassFlowAlignment *_flowalign, t_CNNType _cnntype) :
+            ClassFlowCNNGeneral(_flowalign, _cnntype) {};
+        
+        using ClassFlowCNNGeneral::ZeigerEvalAnalogToDigitNeu;
+       
+
+};
+
+
+/**
+ * @brief 
+ * 
+ * Transition = x.8 - x.2 hier keine Transition in den Testfaellen
+ * Versatz = dig=x.n, ana= n.y: kein Versatz, da beide "n" gleich
+ */
+void test_analogToDigit_Standard() {
+
+    UnderTestCNNGeneral* undertest = new UnderTestCNNGeneral(nullptr, Digital100);
+
+    // 4.8 ist eine "hängende" 5. Heißt sie ist nicht bis auf 5.0 umgesprungen.
+    // ab Transition sollte trotzdem ein "hängendes Digit" gerundet werden.
+    // Transition = ja
+    // Versatz = nein
+    TEST_ASSERT_EQUAL_INT(5,  undertest->ZeigerEvalAnalogToDigitNeu(4.8, 8.0, 8, 9.2));
+
+    // https://github.com/jomjol/AI-on-the-edge-device/issues/921#issue-1344032217
+    // Standard: dig=9.6, ana=6.8 => erg=9
+    // Transition = nein
+    // Versatz = nein
+    TEST_ASSERT_EQUAL_INT(9,  undertest->ZeigerEvalAnalogToDigitNeu( 9.6, 6.8, 6, 9.2));
+
+
+    // https://github.com/jomjol/AI-on-the-edge-device/issues/921#issuecomment-1220365920
+    // Standard: dig=4.6, ana=6.2 => erg=4
+    // Transition = nein
+    // Versatz = nein
+    TEST_ASSERT_EQUAL_INT(4,  undertest->ZeigerEvalAnalogToDigitNeu( 4.6, 6.2, 6, 9.2));
+
+    // https://github.com/jomjol/AI-on-the-edge-device/issues/1143#issuecomment-1274434805
+    // Hängendes digit ()
+    // Standard: dig=6.8, ana=8.6 => erg=7
+    // Transition = nein
+    // Versatz = nein
+    TEST_ASSERT_EQUAL_INT(7,  undertest->ZeigerEvalAnalogToDigitNeu( 6.8, 8.6, 6, 9.2));
+
+    // https://github.com/jomjol/AI-on-the-edge-device/issues/1143#issuecomment-1274434805
+    // Ebenfalls Hängendes digit () bei kleinem Zeiger nach 0-Durchlauf
+    // Standard: dig=6.8, ana=1.0 => erg=7
+    // Transition = nein
+    // Versatz = nein
+    TEST_ASSERT_EQUAL_INT(7,  undertest->ZeigerEvalAnalogToDigitNeu( 6.8, 1.0, 1, 9.2));
+
+
+}
+
+void test_analogToDigit_Transition() {
+    UnderTestCNNGeneral* undertest = new UnderTestCNNGeneral(nullptr, Digital100);
+    
+    // https://github.com/jomjol/AI-on-the-edge-device/issues/921#issuecomment-1222672175
+    // Standard: dig=3.9, ana=9.7 => erg=3
+    // Transition = ja
+    // Nulldurchgang = nein
+    // Versatz = nein
+    TEST_ASSERT_EQUAL_INT(3,  undertest->ZeigerEvalAnalogToDigitNeu( 3.9, 9.7, 9, 9.2));
+  
+    // ohne Referenz
+    // Standard: dig=4.0, ana=9.1 => erg=4
+    // Transition = ja
+    // Nulldurchgang = nein
+    // Versatz = nein
+    // Besonderheit: Digit ist bei analog 9.1 noch nicht losgelaufen
+    TEST_ASSERT_EQUAL_INT(4,  undertest->ZeigerEvalAnalogToDigitNeu( 4.0, 9.1, 9, 9.2));
+
+    // ohne Referenz
+    // Standard: dig=9.8, ana=0.1, ana_2=9.9 => erg=9
+    // Transition = ja
+    // Nulldurchgang = nein
+    // Versatz = nein
+    // Besonderheit: analog wird durch vorherigen analog wieder auf 9 gesetzt
+    TEST_ASSERT_EQUAL_INT(9,  undertest->ZeigerEvalAnalogToDigitNeu( 9.8, 0.1, 9, 9.2));
+
+
+    // https://github.com/jomjol/AI-on-the-edge-device/issues/1110#issuecomment-1277425333
+    // Standard: dig=5.9, ana=9.4 => erg=9
+    // Transition = ja
+    // Nulldurchgang = nein
+    // Versatz = nein
+    // Besonderheit: 
+    TEST_ASSERT_EQUAL_INT(5,  undertest->ZeigerEvalAnalogToDigitNeu( 5.9, 9.4, 9, 9.2));
+
+    // https://github.com/jomjol/AI-on-the-edge-device/issues/1110#issuecomment-1282168030
+    // Standard: dig=1.8, ana=7.8 => erg=9
+    // Transition = ja
+    // Nulldurchgang = nein
+    // Versatz = nein
+    // Besonderheit: Digit läuft mit Analog mit. Deshalb 1.8 (vs. 7.8)
+    TEST_ASSERT_EQUAL_INT(1,  undertest->ZeigerEvalAnalogToDigitNeu( 1.8, 7.8, 7, 7.7));
+
+}

+ 22 - 8
code/test/components/jomjol-flowcontroll/test_flow.cpp → code/test/components/jomjol-flowcontroll/test_flow_postrocess_helper.cpp

@@ -1,5 +1,7 @@
-#include "test_flow.h"
+#include "test_flow_postrocess_helper.h"
+#include "esp_log.h"
 
+static const char *TAG = "test_flow_postproc_helper";
 
 UnderTestPost* setUpClassFlowPostprocessing(t_CNNType digType, t_CNNType anaType)
 {
@@ -36,13 +38,15 @@ std::string process_doFlow(std::vector<float> analog, std::vector<float> digits,
             bool checkConsistency, bool extendedResolution, int decimal_shift) {
     // setup the classundertest
     UnderTestPost* _undertestPost = init_do_flow(analog, digits, digType, checkConsistency, extendedResolution, decimal_shift);
-    printf("SetupClassFlowPostprocessing completed.\n");
+    ESP_LOGD(TAG, "SetupClassFlowPostprocessing completed.");
 
     string time;
     // run test
     TEST_ASSERT_TRUE(_undertestPost->doFlow(time));
 
-    return _undertestPost->getReadout(0);
+    std::string result =  _undertestPost->getReadout(0);
+    delete _undertestPost;
+    return result;
 
 }
 
@@ -79,7 +83,7 @@ UnderTestPost* init_do_flow(std::vector<float> analog, std::vector<float> digits
             gen_analog->ROI.push_back(anaROI);
         }
     }
-    printf("Setting up of ROIs completed.\n");
+    ESP_LOGD(TAG, "Setting up of ROIs completed.");
 
     _undertestPost->InitNUMBERS();
    
@@ -93,7 +97,7 @@ UnderTestPost* init_do_flow(std::vector<float> analog, std::vector<float> digits
 
 void setPreValue(UnderTestPost* _underTestPost, double _preValue) {
         if (_preValue>0) {
-        printf("preValue=%f", _preValue);
+        ESP_LOGD(TAG, "preValue=%f", _preValue);
         std::vector<NumberPost*>* NUMBERS = _underTestPost->GetNumbers();    
         for (int _n = 0; _n < (*NUMBERS).size(); ++_n) {
             (*NUMBERS)[_n]->PreValue = _preValue;
@@ -102,7 +106,7 @@ void setPreValue(UnderTestPost* _underTestPost, double _preValue) {
 }
 
 void setAllowNegatives(UnderTestPost* _underTestPost, bool _allowNegatives) {
-        printf("checkConsistency=true\n");
+        ESP_LOGD(TAG, "checkConsistency=true");
         std::vector<NumberPost*>* NUMBERS = _underTestPost->GetNumbers();    
         for (int _n = 0; _n < (*NUMBERS).size(); ++_n) {
             (*NUMBERS)[_n]->AllowNegativeRates = _allowNegatives;
@@ -112,7 +116,7 @@ void setAllowNegatives(UnderTestPost* _underTestPost, bool _allowNegatives) {
 
 void setConsitencyCheck(UnderTestPost* _underTestPost, bool _checkConsistency) {
         if (_checkConsistency) {
-        printf("checkConsistency=true\n");
+        ESP_LOGD(TAG, "checkConsistency=true");
         std::vector<NumberPost*>* NUMBERS = _underTestPost->GetNumbers();    
         for (int _n = 0; _n < (*NUMBERS).size(); ++_n) {
             (*NUMBERS)[_n]->checkDigitIncreaseConsistency = true;
@@ -134,9 +138,19 @@ void setDecimalShift(UnderTestPost* _underTestPost, int _decimal_shift) {
     if (_decimal_shift!=0) {
         std::vector<NumberPost*>* NUMBERS = _underTestPost->GetNumbers();    
         for (int _n = 0; _n < (*NUMBERS).size(); ++_n) {
-            printf("Setting decimal shift on number: %d to %d\n", _n, _decimal_shift);
+            ESP_LOGD(TAG, "Setting decimal shift on number: %d to %d", _n, _decimal_shift);
             (*NUMBERS)[_n]->DecimalShift = _decimal_shift;
             (*NUMBERS)[_n]->DecimalShiftInitial = _decimal_shift;   
         }       
     }
 }
+
+void setAnalogdigitTransistionStart(UnderTestPost* _underTestPost, float _analogdigitTransistionStart) {
+    if (_analogdigitTransistionStart!=0) {
+        std::vector<NumberPost*>* NUMBERS = _underTestPost->GetNumbers();    
+        for (int _n = 0; _n < (*NUMBERS).size(); ++_n) {
+            ESP_LOGD(TAG, "Setting decimal shift on number: %d to %f", _n, _analogdigitTransistionStart);
+            (*NUMBERS)[_n]->AnalogDigitalTransitionStart = _analogdigitTransistionStart; 
+        }       
+    }
+}

+ 8 - 0
code/test/components/jomjol-flowcontroll/test_flow.h → code/test/components/jomjol-flowcontroll/test_flow_postrocess_helper.h

@@ -99,4 +99,12 @@ void setExtendedResolution(UnderTestPost* _UnderTestPost, bool _extendedResoluti
  */
 void setDecimalShift(UnderTestPost* _UnderTestPost, int decimal_shift);
 
+/**
+ * @brief Set the Analogdigit Transistion Start 
+ * 
+ * @param _underTestPost the testobject  
+ * @param _analogdigitTransistionStart the analog to digit transition start
+ */
+void setAnalogdigitTransistionStart(UnderTestPost* _underTestPost, float _analogdigitTransistionStart);
+
 #endif // TEST_FLOW_H

+ 1 - 1
code/test/components/jomjol-flowcontroll/test_flow_pp_negative.cpp

@@ -1,4 +1,4 @@
-#include "test_flow.h"
+#include "test_flow_postrocess_helper.h"
 
 
 

+ 80 - 23
code/test/components/jomjol-flowcontroll/test_flowpostprocessing.cpp

@@ -1,9 +1,12 @@
-#include "test_flow.h"
+#include "test_flow_postrocess_helper.h"
 
 
 
 
 /**
+ * ACHTUNG! Die Test laufen aktuell nur mit ausgeschaltetem Debug in ClassFlowCNNGeneral 
+ * 
+ *
  * @brief Testet die doFlow-Methode von ClassFlowPostprocessing
  * digits[] - enthält die liste der vom Model zurückgegebenen Ergebnisse (class100/cont) in der Reihenfolge von links nach rechts
  * analog[] - enthält die Liste der Zeiger vom Model, wie bei den digits
@@ -29,7 +32,7 @@ void test_doFlow() {
         TEST_ASSERT_EQUAL_STRING(expected, result.c_str());
 
         /*
-         * https://github.com/jomjol/AI-on-the-edge-device/issues/921
+         * https://github.com/jomjol/AI-on-the-edge-device/issues/921#issue-1344032217
          * 
          * Das Ergebnis sollte "376529.6" sein. 
          */
@@ -40,7 +43,7 @@ void test_doFlow() {
         TEST_ASSERT_EQUAL_STRING(expected, result.c_str());
 
         /*
-         * https://github.com/jomjol/AI-on-the-edge-device/issues/921
+         * https://github.com/jomjol/AI-on-the-edge-device/issues/921#issuecomment-1220365920
          * 
          * Das Ergebnis sollte "167734.6" sein. Bzw. 16.98 ohne Extended true
          */
@@ -81,13 +84,13 @@ void test_doFlow() {
 
         digits = { 1.1, 9.0, 4.0};
         analogs = { 8.1, 2.6, 6.25, 9.7};
-        expected = "193.8259";
+        expected = "194.8259";
         result = process_doFlow(analogs, digits);
         TEST_ASSERT_EQUAL_STRING(expected, result.c_str());
 
         digits = { 1.1, 9.0, 4.0};
         analogs = { 9.1, 2.6, 6.25, 9.7};
-        expected = "193.9259";
+        expected = "194.9259";
         result = process_doFlow(analogs, digits);
         TEST_ASSERT_EQUAL_STRING(expected, result.c_str());
 
@@ -346,10 +349,10 @@ void test_doFlow() {
         
         // Fehler bei V12.0.1 
         // https://github.com/jomjol/AI-on-the-edge-device/issues/1110#issue-1391153343
-        digits = { 1.0, 4.0, 2.0};  // 142.9269 als falsches Ergebnis
+        digits = { 1.0, 4.0, 2.0};  // 141.9269 als falsches Ergebnis
         analogs = { 9.2, 2.5, 6.8, 9.0};
-        expected = "141.9269";
-        expected_extended= "141.92690";
+        expected = "142.9269";
+        expected_extended= "142.92690";
         
         // extendResolution=false
         result = process_doFlow(analogs, digits, Digital100, false, false, 0);
@@ -363,25 +366,31 @@ void test_doFlow() {
        // Fehler bei V12.0.1 
         // https://github.com/jomjol/AI-on-the-edge-device/issues/1110#issuecomment-1262626388
         digits = { 1.2, 6.8, 0.0, 0.0, 5.0, 2.8};  //170.05387 als falsches Ergebnis
+        // letztes digit läuft mit analog zeiger mit. Hier nur lösbar mit setAnalogdigitTransistionStart=7.7
         analogs = { 8.7};
         expected = "170.0528";
         expected_extended= "170.05287";
         
         // extendResolution=false
-        result = process_doFlow(analogs, digits, Digital100, false, false, -3);
+        UnderTestPost* undertestPost = init_do_flow(analogs, digits, Digital100, false, false, -3);
+        setAnalogdigitTransistionStart(undertestPost, 7.7);
+        result = process_doFlow(undertestPost);
         TEST_ASSERT_EQUAL_STRING(expected, result.c_str());
+        delete undertestPost;
 
         // checkConsistency=false und extendResolution=true
-        result = process_doFlow(analogs, digits, Digital100, false, true, -3);
+        undertestPost = init_do_flow(analogs, digits, Digital100, false, true, -3);
+        setAnalogdigitTransistionStart(undertestPost, 7.7);
+        result = process_doFlow(undertestPost);
         TEST_ASSERT_EQUAL_STRING(expected_extended, result.c_str());
-
+        delete undertestPost;
 
         // Fehler bei rolling post V12.0.1 
         // lokal watermeter1
-        digits = { 0.0, 0.0, 9.0, 1.0};  //91.88174 als falsches Ergebnis
+        digits = { 0.0, 0.0, 9.0, 1.0};  //90.88174 als falsches Ergebnis
         analogs = {9.0,  8.0, 1.8, 7.4};
-        expected = "90.8817";
-        expected_extended= "90.88174";
+        expected = "91.8817";
+        expected_extended= "91.88174";
         
         // extendResolution=false
         result = process_doFlow(analogs, digits, Digital100, false, false, 0);
@@ -426,9 +435,8 @@ void test_doFlow() {
         // https://github.com/jomjol/AI-on-the-edge-device/issues/1143#issuecomment-1274434805
         digits = { 4.9, 6.9, 6.8};  // 576.8649 als falsches Ergebnis
         analogs = {8.6, 6.2, 5.0, 9.0};
-        // fall unklar ob wirklich 577 oder 576, erst mal 577
-        expected = "576.8649";
-        expected_extended= "576.86490";
+        expected = "577.8649";
+        expected_extended= "577.86490";
         
         // extendResolution=false
         result = process_doFlow(analogs, digits, Digital100, false, false, 0);
@@ -440,12 +448,26 @@ void test_doFlow() {
 
 
         // Fehler  V12.0.1 "TODO 00211.03480 vs 00211.03580"
-        // Lokal
-        digits = { 4.9, 6.9, 6.8};  // 576.8649 als falsches Ergebnis
-        analogs = {8.6, 6.2, 5.0, 9.0};
-        // fall unklar ob wirklich 577 oder 576, erst mal 577
-        expected = "576.8649";
-        expected_extended= "576.86490";
+        // Lokal "Hängendes Digit"
+        digits = { 2.0, 1.0, 1.0, 0.0, 3.0, 4.8};  // 00211.03480 als falsches Ergebnis
+        analogs = {8.0};
+        expected = "211.0358";
+        expected_extended= "211.03580";
+        
+        // extendResolution=false
+        result = process_doFlow(analogs, digits, Digital100, false, false, -3);
+        TEST_ASSERT_EQUAL_STRING(expected, result.c_str());
+
+        // checkConsistency=false und extendResolution=true
+        result = process_doFlow(analogs, digits, Digital100, false, true, -3);
+        TEST_ASSERT_EQUAL_STRING(expected_extended, result.c_str());
+
+       // Fehler  V12.0.1 
+        // https://github.com/jomjol/AI-on-the-edge-device/issues/1143#issuecomment-1281231468
+        digits = {  1.0, 1.9, 6.0};  // 125.923 als falsches Ergebnis
+        analogs = {9.3, 2.3, 3.1};
+        expected = "126.923";
+        expected_extended= "126.9231";
         
         // extendResolution=false
         result = process_doFlow(analogs, digits, Digital100, false, false, 0);
@@ -455,7 +477,42 @@ void test_doFlow() {
         result = process_doFlow(analogs, digits, Digital100, false, true, 0);
         TEST_ASSERT_EQUAL_STRING(expected_extended, result.c_str());
 
+       // Fehler  V12.0.1 
+        // https://github.com/jomjol/AI-on-the-edge-device/issues/1110#issuecomment-1282168030
+        digits = {  3.0, 8.1, 5.9, 0.0, 5.0, 6.7};  // 386.05672 als richtiges Ergebnis. Letztes digit schein mit dem Analogzeiger mitzulaufen
+        analogs = {7.2};
+        expected = "386.0567";
+        expected_extended= "386.05672";
+        
+        // extendResolution=false
+        result = process_doFlow(analogs, digits, Digital100, false, false, -3);
+        TEST_ASSERT_EQUAL_STRING(expected, result.c_str());
+
+        // checkConsistency=false und extendResolution=true
+        result = process_doFlow(analogs, digits, Digital100, false, true, -3);
+        TEST_ASSERT_EQUAL_STRING(expected_extended, result.c_str());
 
+        // Fehler  V12.0.1 
+        // https://github.com/jomjol/AI-on-the-edge-device/issues/1110#issuecomment-1282168030
+        digits = {  1.2, 7.0, 1.2, 2.0, 4.0, 1.8};  // 171.24278 als falsches Ergebnis. 
+        // Test ist nur erfolgreich mit Veränderung des AnalogdigitTransistionStart
+        analogs = {7.8};
+        expected = "171.2417";
+        expected_extended= "171.24178";
+        
+        // extendResolution=false
+        undertestPost = init_do_flow(analogs, digits, Digital100, false, false, -3);
+        setAnalogdigitTransistionStart(undertestPost, 7.7);
+        result = process_doFlow(undertestPost);
+        TEST_ASSERT_EQUAL_STRING(expected, result.c_str());
+        delete undertestPost;
+
+        // checkConsistency=false und extendResolution=true
+        undertestPost = init_do_flow(analogs, digits, Digital100, false, true, -3);
+        setAnalogdigitTransistionStart(undertestPost, 7.7);
+        result = process_doFlow(undertestPost);
+        TEST_ASSERT_EQUAL_STRING(expected_extended, result.c_str());
+        delete undertestPost;
 }
 
 

+ 8 - 4
code/test/test_suite_flowcontroll.cpp

@@ -1,8 +1,9 @@
 #include <unity.h>
 
-#include "components/jomjol-flowcontroll/test_flow.cpp"
+#include "components/jomjol-flowcontroll/test_flow_postrocess_helper.cpp"
 #include "components/jomjol-flowcontroll/test_flowpostprocessing.cpp"
 #include "components/jomjol-flowcontroll/test_flow_pp_negative.cpp"
+#include "components/jomjol-flowcontroll/test_ZeigerEvalAnalogToDigitNeu.cpp"
 // SD-Card ////////////////////
 #include "nvs_flash.h"
 #include "esp_vfs_fat.h"
@@ -103,9 +104,12 @@ extern "C" void app_main()
   initGPIO();
   Init_NVS_SDCard();
   UNITY_BEGIN();
-
-  RUN_TEST(testNegative);
-  RUN_TEST(test_doFlow);
+  
+    RUN_TEST(testNegative);
+  
+    RUN_TEST(test_analogToDigit_Standard);
+    RUN_TEST(test_analogToDigit_Transition);
+    RUN_TEST(test_doFlow);
   
   UNITY_END();
 }

+ 1 - 0
sd-card/config/config.ini

@@ -42,6 +42,7 @@ main.ana4 155 328 92 92 false
 
 [PostProcessing]
 main.DecimalShift = 0
+main.AnalogDigitalTransitionStart = 9.2
 PreValueUse = true
 PreValueAgeStartup = 720
 AllowNegativeRates = false

+ 16 - 0
sd-card/html/edit_config_param.html

@@ -489,6 +489,20 @@ textarea {
 				Shift the digit separator within the digital digits (positiv and negativ)
 			</td>
 		</tr>
+		<tr>
+			<td class="indent1">
+				<input type="checkbox" id="PostProcessing_AnalogDigitalTransitionStart_enabled" value="1"  onclick = 'InvertEnableItem("PostProcessing", "AnalogDigitalTransitionStart")' unchecked >
+				<label for=PostProcessing_AnalogDigitalTransitionStart_enabled><class id="PostProcessing_AnalogDigitalTransitionStart_text" style="color:black;">AnalogDigitalTransitionStart</class></label>
+			</td>
+			<td>
+				<input type="number" id="PostProcessing_AnalogDigitalTransitionStart_value1" step="0.1" min="6.0" max="9.9" value="9.2">
+			</td>
+			<td style="font-size: 80%;">
+				If you have false Values, but the recognition is correct. Look for the start of changing of the first digit and note the analog pointer value behind. Set it here.
+				Only used on combination of digits and analog pointers. Default=9.2
+			</td>
+		</tr>
+
 		<tr>
 			<td class="indent1">
 				<input type="checkbox" id="PostProcessing_MaxRateValue_enabled" value="1"  onclick = 'InvertEnableItem("PostProcessing", "MaxRateValue")' unchecked >
@@ -1670,6 +1684,7 @@ function UpdateInputIndividual()
 	if (NUNBERSAkt != -1)
 	{
 		ReadParameter(param, "PostProcessing", "DecimalShift", true, NUNBERSAkt)		
+		ReadParameter(param, "PostProcessing", "AnalogDigitalTransitionStart", true, NUNBERSAkt)		
 		ReadParameter(param, "PostProcessing", "MaxRateValue", true, NUNBERSAkt)		
 		ReadParameter(param, "PostProcessing", "MaxRateType", true, NUNBERSAkt)		
 		ReadParameter(param, "PostProcessing", "ExtendedResolution", true, NUNBERSAkt)		
@@ -1679,6 +1694,7 @@ function UpdateInputIndividual()
 	var sel = document.getElementById("Numbers_value1");
 	NUNBERSAkt = sel.selectedIndex;
 	WriteParameter(param, category, "PostProcessing", "DecimalShift", true, NUNBERSAkt);
+	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);

+ 9 - 9
sd-card/html/graph.html

@@ -26,21 +26,21 @@ console.log (hash);
 var d = new Date();
 var options="<option>Please Select...</option>";
 for (var i=0;  i<27; i++) {
-  var currentDate = new Date(d-i*60*60*24*1000);
-  var option = currentDate.getFullYear()+"-"+(currentDate.getMonth()+1)+"-"+currentDate.getDate()
-  options += "<option>"+option+"</option>\n";
+    var currentDate = new Date(d-i*60*60*24*1000);
+    var option = currentDate.getFullYear()+"-"+(currentDate.getMonth()+1)+"-"+currentDate.getDate()
+    options += "<option>"+option+"</option>\n";
 }
 document.getElementById("selector").innerHTML = options;
 
 var dateString = d.getFullYear() + "-" + (d.getMonth()+1) + "-" + d.getDate();    
 if (hash!="") {
-  dateString = hash.substring(1);
+    dateString = hash.substring(1);
 }
-fetch('/fileserver/log/message/log_'+dateString+'.txt')
+fetch('/fileserver/log/data/data_'+dateString+'.txt')
 .then(response => {
     // handle the response
     if (response.status == 404) {
-      alert("no log data available for "+dateString);
+        alert("no log data available for "+dateString);
     }
     response.text()
     .then( result => {
@@ -53,10 +53,10 @@ fetch('/fileserver/log/message/log_'+dateString+'.txt')
 
         var timex = 1;
         for (let line of lines) {
-            if (line.includes("PostProcessing - Raw")) {
+            {
                 console.log(line);
-                var value = line.split(" ")[6];
-                var time  = line.split(" ")[0];
+                var value = line.split("\t")[3];
+                var time  = line.split("\t")[0];
                 console.log("> "+time+" "+value+"\n");
                 if (value<1000) {
                     trace.x.push(timex);

+ 82 - 0
sd-card/html/graph_data.html

@@ -0,0 +1,82 @@
+
+<html>
+    <head>
+    <script src='https://cdn.plot.ly/plotly-2.14.0.min.js'></script>
+    <style>
+        textarea {
+            width: 600px;
+            height: 300px;
+        }
+    </style>
+    <script>
+    function run() {
+      var el = document.getElementById('cnsl');
+      el && eval(el.value);
+    }
+    </script>
+    </head>
+    <body>
+    <div id='chart'></div>
+    <select id="selector" onchange="document.location.href=document.location.href.split('#')[0]+'#'+this.value;run();"></select>
+    <button onclick="document.getElementById('editor').hidden = false; this.hidden = true;" >Editor</button>
+    <div id='editor' hidden='true'>
+    <textarea id="cnsl">
+var hash = window.location.hash;
+console.log (hash);
+var d = new Date();
+var options="<option>Please Select...</option>";
+for (var i=0;  i<27; i++) {
+  var currentDate = new Date(d-i*60*60*24*1000);
+  var option = currentDate.getFullYear()+"-"+(currentDate.getMonth()+1)+"-"+currentDate.getDate()
+  options += "<option>"+option+"</option>\n";
+}
+document.getElementById("selector").innerHTML = options;
+
+var dateString = d.getFullYear() + "-" + (d.getMonth()+1) + "-" + d.getDate();    
+if (hash!="") {
+  dateString = hash.substring(1);
+}
+fetch('/fileserver/log/message/log_'+dateString+'.txt')
+.then(response => {
+    // handle the response
+    if (response.status == 404) {
+      alert("no log data available for "+dateString);
+    }
+    response.text()
+    .then( result => {
+        var lines = result.split("\n");
+        var trace = {
+        x: [],
+        y: [],
+        type: 'scatter'
+        };
+
+        var timex = 1;
+        for (let line of lines) {
+            if (line.includes("PostProcessing - Raw")) {
+                console.log(line);
+                var value = line.split(" ")[6];
+                var time  = line.split(" ")[0];
+                console.log("> "+time+" "+value+"\n");
+                if (value<1000) {
+                    trace.x.push(timex);
+                    timex += 1;
+                    trace.y.push(value);
+                }
+            }
+        }
+        console.log(trace);
+        var data = [trace];
+        Plotly.newPlot('chart', data);
+    });
+}).catch((error) => {
+    // handle the error
+    console.log(error);
+alert("test");
+});        
+</textarea><br />
+<button onclick="run();">run</button>
+</div>
+<script>run();</script>
+</body>
+</html>

+ 78 - 0
sd-card/html/info.html

@@ -77,6 +77,84 @@ div {
 	</tr>
 </table>
 
+
+<table style="font-family: arial">
+<h3>SD Card Info</h3>
+<table style="font-family: arial">
+	<tr>
+		<td>
+			SD Card Manufacturer:
+		</td>
+		<td>
+			<div id="SDCardManufacturer">
+				<object data="/version?type=SDCardManufacturer"></object>
+			</div>
+		</td>
+	</tr>
+	<tr>
+		<td>
+			SD Card Name:
+		</td>
+		<td>
+			<div id="SDCardName">
+				<object data="/version?type=SDCardName"></object>
+			</div>
+		</td>
+	</tr>
+	<tr>
+		<td>
+			SD Card Size [MB]:
+		</td>
+		<td>
+			<div id="SDCardCapacity">
+				<object data="/version?type=SDCardCapacity"></object>
+			</div>
+		</td>
+	</tr>
+	<tr>
+		<td>
+			SD Card Sector Size [byte]:
+		</td>
+		<td>
+			<div id="SDCardSectorSize">
+				<object data="/version?type=SDCardSectorSize"></object>
+			</div>
+		</td>
+	</tr>
+	<tr>
+		<td>
+			Partition Size [MB]:
+		</td>
+		<td>
+			<div id="SDPartitionSize">
+				<object data="/version?type=SDCardPartitionSize"></object>
+			</div>
+		</td>
+	</tr>
+	<tr>
+		<td>
+			Partition Free Space [MB]:
+		</td>	
+		<td>
+			<div id="SDFreePartitionSpace">
+				<object data="/version?type=SDCardFreePartitionSpace"></object>
+			</div>
+		</td>
+	</tr>
+	<tr>
+		<td>
+			Partition Allocation Size [byte]:
+		</td>	
+		<td>
+			<div id="SDCardPartitionAllocationSize">
+				<object data="/version?type=SDCardPartitionAllocationSize"></object>
+			</div>
+		</td>
+	</tr>
+</table>
+
+
+<table style="font-family: arial">
 <h3>Version Info</h3>
 
 <table style="font-family: arial">

+ 1 - 0
sd-card/html/readconfigparam.js

@@ -102,6 +102,7 @@ function ParseConfig() {
      category[catname]["found"] = false;
      param[catname] = new Object();
      ParamAddValue(param, catname, "DecimalShift", 1, true);
+     ParamAddValue(param, catname, "AnalogDigitalTransitionStart", 1, true);
      ParamAddValue(param, catname, "PreValueUse");
      ParamAddValue(param, catname, "PreValueAgeStartup");
      ParamAddValue(param, catname, "AllowNegativeRates");