From 88b531ae8b89caaff6606a6ae68b8811d8eaac07 Mon Sep 17 00:00:00 2001 From: michael Date: Thu, 11 Apr 2024 21:12:40 +0200 Subject: [PATCH] Camera settings (#3029) * Add files via upload * Add files via upload * Add files via upload * Add files via upload * Add files via upload * Add files via upload * Add files via upload * Add files via upload --- .../ClassControllCamera.cpp | 1357 ++++++------ .../ClassControllCamera.h | 138 +- .../jomjol_controlcamera/ov2640_sharpness.cpp | 88 +- .../jomjol_controlcamera/server_camera.cpp | 279 ++- .../jomjol_controlcamera/server_camera.h | 1 - .../ClassFlowAlignment.cpp | 795 +++---- .../jomjol_flowcontroll/ClassFlowAlignment.h | 105 +- .../ClassFlowTakeImage.cpp | 706 +++++-- .../jomjol_flowcontroll/ClassFlowTakeImage.h | 40 +- .../jomjol_flowcontroll/MainFlowControl.cpp | 1659 +++++++++------ .../jomjol_flowcontroll/MainFlowControl.h | 69 +- code/components/jomjol_helper/Helper.cpp | 990 +++++---- .../jomjol_image_proc/CRotateImage.cpp | 662 +++--- .../jomjol_image_proc/CRotateImage.h | 55 +- param-docs/expert-params.txt | 29 +- .../parameter-pages/TakeImage/CamAeLevel.md | 15 + .../parameter-pages/TakeImage/CamAec.md | 13 + .../parameter-pages/TakeImage/CamAec2.md | 13 + .../parameter-pages/TakeImage/CamAecValue.md | 15 + .../parameter-pages/TakeImage/CamAgc.md | 10 + .../parameter-pages/TakeImage/CamAgcGain.md | 13 + .../TakeImage/CamAutoSharpness.md | 13 + .../parameter-pages/TakeImage/CamAwb.md | 10 + .../parameter-pages/TakeImage/CamAwbGain.md | 10 + .../parameter-pages/TakeImage/CamBpc.md | 10 + .../TakeImage/CamBrightness.md | 10 + .../parameter-pages/TakeImage/CamColorbar.md | 5 + .../parameter-pages/TakeImage/CamContrast.md | 11 + .../parameter-pages/TakeImage/CamDcw.md | 13 + .../parameter-pages/TakeImage/CamDenoise.md | 10 + .../TakeImage/CamGainceiling.md | 21 + .../parameter-pages/TakeImage/CamHmirror.md | 10 + .../parameter-pages/TakeImage/CamLenc.md | 10 + .../parameter-pages/TakeImage/CamQuality.md | 10 + .../parameter-pages/TakeImage/CamRawGma.md | 10 + .../TakeImage/CamSaturation.md | 11 + .../parameter-pages/TakeImage/CamSharpness.md | 13 + .../TakeImage/CamSpecialEffect.md | 21 + .../parameter-pages/TakeImage/CamVflip.md | 10 + .../parameter-pages/TakeImage/CamWbMode.md | 18 + .../parameter-pages/TakeImage/CamWpc.md | 10 + .../parameter-pages/TakeImage/CamZoom.md | 13 + .../TakeImage/CamZoomOffsetX.md | 14 + .../TakeImage/CamZoomOffsetY.md | 14 + .../parameter-pages/TakeImage/CamZoomSize.md | 13 + sd-card/config/config.ini | 259 +-- sd-card/html/edit_alignment.html | 114 +- sd-card/html/edit_analog.html | 41 +- sd-card/html/edit_config_template.html | 1823 +++++++++++------ sd-card/html/edit_digits.html | 97 +- sd-card/html/edit_reference.html | 1499 +++++++++----- sd-card/html/index.html | 58 +- sd-card/html/overview.html | 420 ++-- sd-card/html/readconfigcommon.js | 340 ++- sd-card/html/readconfigparam.js | 1642 ++++++++------- 55 files changed, 8096 insertions(+), 5539 deletions(-) create mode 100644 param-docs/parameter-pages/TakeImage/CamAeLevel.md create mode 100644 param-docs/parameter-pages/TakeImage/CamAec.md create mode 100644 param-docs/parameter-pages/TakeImage/CamAec2.md create mode 100644 param-docs/parameter-pages/TakeImage/CamAecValue.md create mode 100644 param-docs/parameter-pages/TakeImage/CamAgc.md create mode 100644 param-docs/parameter-pages/TakeImage/CamAgcGain.md create mode 100644 param-docs/parameter-pages/TakeImage/CamAutoSharpness.md create mode 100644 param-docs/parameter-pages/TakeImage/CamAwb.md create mode 100644 param-docs/parameter-pages/TakeImage/CamAwbGain.md create mode 100644 param-docs/parameter-pages/TakeImage/CamBpc.md create mode 100644 param-docs/parameter-pages/TakeImage/CamBrightness.md create mode 100644 param-docs/parameter-pages/TakeImage/CamColorbar.md create mode 100644 param-docs/parameter-pages/TakeImage/CamContrast.md create mode 100644 param-docs/parameter-pages/TakeImage/CamDcw.md create mode 100644 param-docs/parameter-pages/TakeImage/CamDenoise.md create mode 100644 param-docs/parameter-pages/TakeImage/CamGainceiling.md create mode 100644 param-docs/parameter-pages/TakeImage/CamHmirror.md create mode 100644 param-docs/parameter-pages/TakeImage/CamLenc.md create mode 100644 param-docs/parameter-pages/TakeImage/CamQuality.md create mode 100644 param-docs/parameter-pages/TakeImage/CamRawGma.md create mode 100644 param-docs/parameter-pages/TakeImage/CamSaturation.md create mode 100644 param-docs/parameter-pages/TakeImage/CamSharpness.md create mode 100644 param-docs/parameter-pages/TakeImage/CamSpecialEffect.md create mode 100644 param-docs/parameter-pages/TakeImage/CamVflip.md create mode 100644 param-docs/parameter-pages/TakeImage/CamWbMode.md create mode 100644 param-docs/parameter-pages/TakeImage/CamWpc.md create mode 100644 param-docs/parameter-pages/TakeImage/CamZoom.md create mode 100644 param-docs/parameter-pages/TakeImage/CamZoomOffsetX.md create mode 100644 param-docs/parameter-pages/TakeImage/CamZoomOffsetY.md create mode 100644 param-docs/parameter-pages/TakeImage/CamZoomSize.md diff --git a/code/components/jomjol_controlcamera/ClassControllCamera.cpp b/code/components/jomjol_controlcamera/ClassControllCamera.cpp index 33b00bc8..5095cb16 100644 --- a/code/components/jomjol_controlcamera/ClassControllCamera.cpp +++ b/code/components/jomjol_controlcamera/ClassControllCamera.cpp @@ -41,24 +41,34 @@ #include "soc/io_mux_reg.h" #include "esp_rom_gpio.h" #define gpio_pad_select_gpio esp_rom_gpio_pad_select_gpio -#define gpio_matrix_in(a,b,c) esp_rom_gpio_connect_in_signal(a,b,c) -#define gpio_matrix_out(a,b,c,d) esp_rom_gpio_connect_out_signal(a,b,c,d) +#define gpio_matrix_in(a, b, c) esp_rom_gpio_connect_in_signal(a, b, c) +#define gpio_matrix_out(a, b, c, d) esp_rom_gpio_connect_out_signal(a, b, c, d) #define ets_delay_us(a) esp_rom_delay_us(a) #endif -static const char *TAG = "CAM"; +CCamera Camera; +camera_controll_config_temp_t CCstatus; +static const char *TAG = "CAM"; /* Camera live stream */ #define PART_BOUNDARY "123456789000000000000987654321" -static const char* _STREAM_CONTENT_TYPE = "multipart/x-mixed-replace;boundary=" PART_BOUNDARY; -static const char* _STREAM_BOUNDARY = "\r\n--" PART_BOUNDARY "\r\n"; -static const char* _STREAM_PART = "Content-Type: image/jpeg\r\nContent-Length: %u\r\n\r\n"; +static const char *_STREAM_CONTENT_TYPE = "multipart/x-mixed-replace;boundary=" PART_BOUNDARY; +static const char *_STREAM_BOUNDARY = "\r\n--" PART_BOUNDARY "\r\n"; +static const char *_STREAM_PART = "Content-Type: image/jpeg\r\nContent-Length: %u\r\n\r\n"; -// OV2640 Camera SDE Indirect Register Access -#define OV2640_IRA_BPADDR 0x7C -#define OV2640_IRA_BPDATA 0x7D +uint8_t *demoImage = NULL; // Buffer holding the demo image in bytes +#define DEMO_IMAGE_SIZE 30000 // Max size of demo image in bytes +// Camera module bus communications frequency. +// Originally: config.xclk_freq_mhz = 20000000, but this lead to visual artifacts on many modules. +// See https://github.com/espressif/esp32-camera/issues/150#issuecomment-726473652 et al. +#if !defined(XCLK_FREQ_MHZ) +// int xclk = 8; +int xclk = 20; // Orginal value +#else +int xclk = XCLK_FREQ_MHZ; +#endif static camera_config_t camera_config = { .pin_pwdn = CAM_PIN_PWDN, @@ -79,90 +89,439 @@ static camera_config_t camera_config = { .pin_href = CAM_PIN_HREF, .pin_pclk = CAM_PIN_PCLK, - //XCLK 20MHz or 10MHz for OV2640 double FPS (Experimental) - .xclk_freq_hz = 20000000, // Orginal value -// .xclk_freq_hz = 5000000, // Test to get rid of the image errors !!!! Hangs in version 9.2 !!!! - .ledc_timer = LEDC_TIMER_0, - .ledc_channel = LEDC_CHANNEL_0, + .xclk_freq_hz = (xclk * 1000000), + .ledc_timer = LEDC_TIMER_0, // LEDC timer to be used for generating XCLK + .ledc_channel = LEDC_CHANNEL_0, // LEDC channel to be used for generating XCLK - .pixel_format = PIXFORMAT_JPEG, //YUV422,GRAYSCALE,RGB565,JPEG - .frame_size = FRAMESIZE_VGA, //QQVGA-UXGA Do not use sizes above QVGA when not JPEG -// .frame_size = FRAMESIZE_UXGA, //QQVGA-UXGA Do not use sizes above QVGA when not JPEG - .jpeg_quality = 12, //0-63 lower number means higher quality - .fb_count = 1, //if more than one, i2s runs in continuous mode. Use only with JPEG + .pixel_format = PIXFORMAT_JPEG, // YUV422,GRAYSCALE,RGB565,JPEG + .frame_size = FRAMESIZE_VGA, // QQVGA-UXGA Do not use sizes above QVGA when not JPEG + // .frame_size = FRAMESIZE_UXGA, //QQVGA-UXGA Do not use sizes above QVGA when not JPEG + .jpeg_quality = 6, // 0-63 lower number means higher quality + .fb_count = 1, // if more than one, i2s runs in continuous mode. Use only with JPEG .fb_location = CAMERA_FB_IN_PSRAM, /*!< The location where the frame buffer will be allocated */ - .grab_mode = CAMERA_GRAB_LATEST, // only from new esp32cam version + .grab_mode = CAMERA_GRAB_LATEST, // only from new esp32cam version }; - -CCamera Camera; - -uint8_t *demoImage = NULL; // Buffer holding the demo image in bytes - -#define DEMO_IMAGE_SIZE 30000 // Max size of demo image in bytes - -typedef struct { - httpd_req_t *req; - size_t len; +typedef struct +{ + httpd_req_t *req; + size_t len; } jpg_chunking_t; +CCamera::CCamera(void) +{ +#ifdef DEBUG_DETAIL_ON + ESP_LOGD(TAG, "CreateClassCamera"); +#endif + CCstatus.WaitBeforePicture = 2; -bool CCamera::testCamera(void) { - bool success; - camera_fb_t *fb = esp_camera_fb_get(); - if (fb) { - success = true; - } - else { - success = false; - } - - esp_camera_fb_return(fb); - return success; + ledc_init(); } +esp_err_t CCamera::InitCam(void) +{ + ESP_LOGD(TAG, "Init Camera"); + + CCstatus.ImageQuality = camera_config.jpeg_quality; + CCstatus.ImageFrameSize = camera_config.frame_size; + + // initialize the camera + esp_camera_deinit(); // De-init in case it was already initialized + esp_err_t err = esp_camera_init(&camera_config); + + if (err != ESP_OK) + { + ESP_LOGE(TAG, "Camera Init Failed"); + return err; + } + + CCstatus.CameraInitSuccessful = true; + + // Get a reference to the sensor + sensor_t *s = esp_camera_sensor_get(); + + if (s != NULL) + { + // Dump camera module, warn for unsupported modules. + switch (s->id.PID) + { + case OV2640_PID: + ESP_LOGI(TAG, "OV2640 camera module detected"); + break; + case OV3660_PID: + ESP_LOGI(TAG, "OV3660 camera module detected"); + break; + default: + ESP_LOGE(TAG, "Camera module is unknown and not properly supported!"); + CCstatus.CameraInitSuccessful = false; + } + } + + if (CCstatus.CameraInitSuccessful) + { + return ESP_OK; + } + else + { + return ESP_FAIL; + } +} + +bool CCamera::testCamera(void) +{ + bool success; + camera_fb_t *fb = esp_camera_fb_get(); + + if (fb) + { + success = true; + } + else + { + success = false; + } + + esp_camera_fb_return(fb); + + return success; +} void CCamera::ledc_init(void) { #ifdef USE_PWM_LEDFLASH - // Prepare and then apply the LEDC PWM timer configuration - ledc_timer_config_t ledc_timer = { }; + ledc_timer_config_t ledc_timer = {}; - ledc_timer.speed_mode = LEDC_MODE; - ledc_timer.timer_num = LEDC_TIMER; - ledc_timer.duty_resolution = LEDC_DUTY_RES; - ledc_timer.freq_hz = LEDC_FREQUENCY; // Set output frequency at 5 kHz - ledc_timer.clk_cfg = LEDC_AUTO_CLK; + ledc_timer.speed_mode = LEDC_MODE; + ledc_timer.timer_num = LEDC_TIMER; + ledc_timer.duty_resolution = LEDC_DUTY_RES; + ledc_timer.freq_hz = LEDC_FREQUENCY; // Set output frequency at 5 kHz + ledc_timer.clk_cfg = LEDC_AUTO_CLK; ESP_ERROR_CHECK(ledc_timer_config(&ledc_timer)); // Prepare and then apply the LEDC PWM channel configuration - ledc_channel_config_t ledc_channel = { }; + ledc_channel_config_t ledc_channel = {}; - ledc_channel.speed_mode = LEDC_MODE; - ledc_channel.channel = LEDC_CHANNEL; - ledc_channel.timer_sel = LEDC_TIMER; - ledc_channel.intr_type = LEDC_INTR_DISABLE; - ledc_channel.gpio_num = LEDC_OUTPUT_IO; - ledc_channel.duty = 0; // Set duty to 0% - ledc_channel.hpoint = 0; + ledc_channel.speed_mode = LEDC_MODE; + ledc_channel.channel = LEDC_CHANNEL; + ledc_channel.timer_sel = LEDC_TIMER; + ledc_channel.intr_type = LEDC_INTR_DISABLE; + ledc_channel.gpio_num = LEDC_OUTPUT_IO; + ledc_channel.duty = 0; // Set duty to 0% + ledc_channel.hpoint = 0; + // ledc_channel.flags.output_invert = LEDC_OUTPUT_INVERT; ESP_ERROR_CHECK(ledc_channel_config(&ledc_channel)); - #endif } +void CCamera::SetLEDIntensity(float _intrel) +{ + _intrel = min(_intrel, (float)100); + _intrel = max(_intrel, (float)0); + _intrel = _intrel / 100; + CCstatus.ImageLedIntensity = (int)(_intrel * 8191); + ESP_LOGD(TAG, "Set led_intensity to %d of 8191", CCstatus.ImageLedIntensity); +} -static size_t jpg_encode_stream(void * arg, size_t index, const void* data, size_t len) +bool CCamera::getCameraInitSuccessful(void) +{ + return CCstatus.CameraInitSuccessful; +} + +esp_err_t CCamera::setSensorDatenFromCCstatus(void) +{ + sensor_t *s = esp_camera_sensor_get(); + + if (s != NULL) + { + s->set_framesize(s, CCstatus.ImageFrameSize); + s->set_gainceiling(s, CCstatus.ImageGainceiling); // Image gain (GAINCEILING_x2, x4, x8, x16, x32, x64 or x128) + + s->set_quality(s, CCstatus.ImageQuality); // 0 - 63 + + s->set_brightness(s, CCstatus.ImageBrightness); // -2 to 2 + s->set_contrast(s, CCstatus.ImageContrast); // -2 to 2 + s->set_saturation(s, CCstatus.ImageSaturation); // -2 to 2 + // s->set_sharpness(s, CCstatus.ImageSharpness); // auto-sharpness is not officially supported, default to 0 + SetCamSharpness(CCstatus.ImageAutoSharpness, CCstatus.ImageSharpness); + + s->set_exposure_ctrl(s, CCstatus.ImageAec); // 0 = disable , 1 = enable + s->set_ae_level(s, CCstatus.ImageAeLevel); // -2 to 2 + s->set_aec_value(s, CCstatus.ImageAecValue); // 0 to 1200 + + s->set_aec2(s, CCstatus.ImageAec2); // 0 = disable , 1 = enable + + s->set_gain_ctrl(s, CCstatus.ImageAgc); // 0 = disable , 1 = enable + s->set_agc_gain(s, CCstatus.ImageAgcGain); // 0 to 30 + + s->set_bpc(s, CCstatus.ImageBpc); // 0 = disable , 1 = enable + s->set_wpc(s, CCstatus.ImageWpc); // 0 = disable , 1 = enable + + s->set_raw_gma(s, CCstatus.ImageRawGma); // 0 = disable , 1 = enable + s->set_lenc(s, CCstatus.ImageLenc); // 0 = disable , 1 = enable + + s->set_hmirror(s, CCstatus.ImageHmirror); // 0 = disable , 1 = enable + s->set_vflip(s, CCstatus.ImageVflip); // 0 = disable , 1 = enable + + s->set_dcw(s, CCstatus.ImageDcw); // 0 = disable , 1 = enable + + s->set_wb_mode(s, CCstatus.ImageWbMode); // 0 to 4 - if awb_gain enabled (0 - Auto, 1 - Sunny, 2 - Cloudy, 3 - Office, 4 - Home) + s->set_awb_gain(s, CCstatus.ImageAwbGain); // 0 = disable , 1 = enable + s->set_whitebal(s, CCstatus.ImageAwb); // 0 = disable , 1 = enable + + // special_effect muß als Letztes gesetzt werden, sonst geht es nicht + s->set_special_effect(s, CCstatus.ImageSpecialEffect); // 0 to 6 (0 - No Effect, 1 - Negative, 2 - Grayscale, 3 - Red Tint, 4 - Green Tint, 5 - Blue Tint, 6 - Sepia) + + TickType_t xDelay2 = 1000 / portTICK_PERIOD_MS; + vTaskDelay(xDelay2); + + return ESP_OK; + } + else + { + return ESP_FAIL; + } +} + +esp_err_t CCamera::getSensorDatenToCCstatus(void) +{ + sensor_t *s = esp_camera_sensor_get(); + + if (s != NULL) + { + CCstatus.ImageFrameSize = (framesize_t)s->status.framesize; + CCstatus.ImageGainceiling = (gainceiling_t)s->status.gainceiling; + + CCstatus.ImageQuality = s->status.quality; + CCstatus.ImageBrightness = s->status.brightness; + CCstatus.ImageContrast = s->status.contrast; + CCstatus.ImageSaturation = s->status.saturation; + // CCstatus.ImageSharpness = s->status.sharpness; // gibt -1 zurück, da es nicht unterstützt wird + CCstatus.ImageWbMode = s->status.wb_mode; + CCstatus.ImageAwb = s->status.awb; + CCstatus.ImageAwbGain = s->status.awb_gain; + CCstatus.ImageAec = s->status.aec; + CCstatus.ImageAec2 = s->status.aec2; + CCstatus.ImageAeLevel = s->status.ae_level; + CCstatus.ImageAecValue = s->status.aec_value; + CCstatus.ImageAgc = s->status.agc; + CCstatus.ImageAgcGain = s->status.agc_gain; + CCstatus.ImageBpc = s->status.bpc; + CCstatus.ImageWpc = s->status.wpc; + CCstatus.ImageRawGma = s->status.raw_gma; + CCstatus.ImageLenc = s->status.lenc; + CCstatus.ImageSpecialEffect = s->status.special_effect; + CCstatus.ImageHmirror = s->status.hmirror; + CCstatus.ImageVflip = s->status.vflip; + CCstatus.ImageDcw = s->status.dcw; + + return ESP_OK; + } + else + { + return ESP_FAIL; + } +} + +void CCamera::SetZoomSize(bool zoomEnabled, int zoomOffsetX, int zoomOffsetY, int imageSize) +{ + sensor_t *s = esp_camera_sensor_get(); + + if (s != NULL) + { + if (zoomEnabled) + { + // ov2640_sensor_mode_t _mode = OV2640_MODE_UXGA; // 1600x1200 + // ov2640_sensor_mode_t _mode = OV2640_MODE_SVGA; // 800x600 + // ov2640_sensor_mode_t _mode = OV2640_MODE_CIF; // 400x296 + int _mode = 0; + + int _offsetx = zoomOffsetX; + int _offsety = zoomOffsetY; + int _imageSize_temp = 0; + int _maxX = 0; + int _maxY = 0; + + if (imageSize < 29) + { + _imageSize_temp = (29 - imageSize); + } + + // This works only if the aspect ratio of 4:3 is preserved in the window size. + // use values divisible by 8 without remainder + int _imageWidth = CCstatus.ImageWidth + (_imageSize_temp * 4 * 8); + int _imageHeight = CCstatus.ImageHeight + (_imageSize_temp * 3 * 8); + + _maxX = 1600 - _imageWidth; + _maxY = 1200 - _imageHeight; + + if ((abs(_offsetx) * 2) > _maxX) + { + if (_offsetx > 0) + { + _offsetx = _maxX; + } + else + { + _offsetx = 0; + } + } + else + { + if (_offsetx > 0) + { + // wenn der Wert von _offsetx nicht durch 8 teilbar ist, + // werden die Farben sehr oft vertauscht(insbesondere Rot mit Blau) + _offsetx = ((_maxX / 2) + _offsetx); + } + else + { + // wenn der Wert von _offsetx nicht durch 8 teilbar ist, + // werden die Farben sehr oft vertauscht(insbesondere Rot mit Blau) + _offsetx = ((_maxX / 2) + _offsetx); + } + } + + if ((abs(_offsety) * 2) > _maxY) + { + if (_offsety > 0) + { + _offsety = _maxY; + } + else + { + _offsety = 0; + } + } + else + { + if (_offsety > 0) + { + // wenn der Wert von _offsety nicht durch 8 teilbar ist, + // werden die Farben sehr oft vertauscht(insbesondere Rot mit Blau) + _offsety = ((_maxY / 2) + _offsety); + } + else + { + // wenn der Wert von _offsety nicht durch 8 teilbar ist, + // werden die Farben sehr oft vertauscht(insbesondere Rot mit Blau) + _offsety = ((_maxY / 2) + _offsety); + } + } + + // _mode sets the sensor resolution (3 options available), + // _offsetx and _offsety set the start of the ROI, + // _imageWidth and _imageHeight set the size of the ROI, + // CCstatus.ImageWidth and CCstatus.ImageHeight set the output window size. + SetCamWindow(s, _mode, _offsetx, _offsety, _imageWidth, _imageHeight, CCstatus.ImageWidth, CCstatus.ImageHeight); + } + else + { + s->set_framesize(s, CCstatus.ImageFrameSize); + } + } +} + +void CCamera::SetQualityZoomSize(int qual, framesize_t resol, bool zoomEnabled, int zoomOffsetX, int zoomOffsetY, int imageSize) +{ + qual = min(63, max(8, qual)); // Limit quality from 8..63 (values lower than 8 tent to be unstable) + + SetImageWidthHeightFromResolution(resol); + + sensor_t *s = esp_camera_sensor_get(); + + if (s != NULL) + { + s->set_quality(s, qual); + SetZoomSize(zoomEnabled, zoomOffsetX, zoomOffsetY, imageSize); + } + else + { + LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "SetQualityZoomSize, Failed to get Cam control structure"); + } +} + +void CCamera::SetCamSharpness(bool _autoSharpnessEnabled, int _sharpnessLevel) +{ + _sharpnessLevel = min(2, max(-2, _sharpnessLevel)); + + sensor_t *s = esp_camera_sensor_get(); + + if (s != NULL) + { + // post processing + if (_autoSharpnessEnabled) + { + s->set_sharpness(s, 0); + ov2640_enable_auto_sharpness(s); + } + else + { + ov2640_set_sharpness(s, _sharpnessLevel); + } + } + else + { + LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "SetCamSharpness, Failed to get Cam control structure"); + } +} + +/* + * resolution = 0 \\ OV2640_MODE_UXGA -> 1600 x 1200 + * resolution = 1 \\ OV2640_MODE_SVGA -> 800 x 600 + * resolution = 2 \\ OV2640_MODE_CIF -> 400 x 296 + * resolution = 3 \\ OV2640_MODE_MAX + */ +void CCamera::SetCamWindow(sensor_t *s, int resolution, int xOffset, int yOffset, int xTotal, int yTotal, int xOutput, int yOutput) +{ + // - (xOffset,yOffset) is the origin of the window in pixels and (xLength,yLength) is the size of the window in pixels. + // - (xOffset,yOffset) ist der Ursprung des Fensters in Pixel und (xLength,yLength) ist die Größe des Fensters in Pixel. + + // - Be aware that changing the resolution will effectively overwrite these settings. + // - Beachten Sie, dass eine Änderung der Auflösung diese Einstellungen effektiv überschreibt. + + // - This works only if the aspect ratio of 4:3 is preserved in the window size. + // - Dies funktioniert nur, wenn das Seitenverhältnis von 4:3 in der Fenstergröße beibehalten wird. + + // - total_x and total_y defines the size on the sensor + // - total_x und total_y definieren die Größe des Sensors + + // - width and height defines the resulting image(may be smaller than the size on the sensor) + // - width und height definieren das resultierende Bild (kann kleiner sein als die Größe des Sensor) + + // - keep the aspect total_x : total_y == width : height + // - Behalten Sie den Aspekt total_x : total_y == width : height bei + + // - use values divisible by 8 without remainder + // - Verwenden Sie Werte, die ohne Rest durch 8 teilbar sind + + // - start with total_x = width and total_y = height, reduce both values by eg.32 pixels + // - Beginnen Sie mit total_x = width und total_y = height und reduzieren Sie beide Werte um z.B.32 Pixel + + // - next try moving with offset_x or offset_y by 8 pixels + // - Versuchen Sie als Nächstes, mit offset_x oder offset_y um 8 Pixel zu verschieben + + // set_res_raw(sensor_t *sensor, int startX, int startY, int endX, int endY, int offsetX, int offsetY, int totalX, int totalY, int outputX, int outputY, bool scale, bool binning) + // set_window(sensor, (ov2640_sensor_mode_t)startX, offsetX, offsetY, totalX, totalY, outputX, outputY); + // set_window(sensor, mode, offset_x, offset_y, max_x, max_y, w, h); + + int unused = 0; + s->set_res_raw(s, resolution, unused, unused, unused, xOffset, yOffset, xTotal, yTotal, xOutput, yOutput, unused, unused); +} + +static size_t jpg_encode_stream(void *arg, size_t index, const void *data, size_t len) { jpg_chunking_t *j = (jpg_chunking_t *)arg; - if(!index) { + if (!index) + { j->len = 0; } - if(httpd_resp_send_chunk(j->req, (const char *)data, len) != ESP_OK) { + if (httpd_resp_send_chunk(j->req, (const char *)data, len) != ESP_OK) + { return 0; } @@ -171,295 +530,35 @@ static size_t jpg_encode_stream(void * arg, size_t index, const void* data, size return len; } - -bool CCamera::SetBrightnessContrastSaturation(int _brightness, int _contrast, int _saturation, int _autoExposureLevel, bool _grayscale, bool _negative, bool _aec2, int _sharpnessLevel) -{ - _brightness = min(2, max(-2, _brightness)); - _contrast = min(2, max(-2, _contrast)); - _saturation = min(2, max(-2, _saturation)); - _autoExposureLevel = min(2, max(-2, _autoExposureLevel)); - bool _autoSharpness = false; - if (_sharpnessLevel <= -4) - _autoSharpness = true; - _sharpnessLevel = min(3, max(-3, _sharpnessLevel)); - - sensor_t * s = esp_camera_sensor_get(); - if (s) { - // camera gives precedence to negative over grayscale, so it's easier to do negative ourselves. - // if (_negative) { - // s->set_special_effect(s, 1); // 0 - no effect, 1 - negative, 2 - grayscale, 3 - reddish, 4 - greenish, 5 - blue, 6 - retro - // } - if (_grayscale) { - s->set_special_effect(s, 2); // 0 - no effect, 1 - negative, 2 - grayscale, 3 - reddish, 4 - greenish, 5 - blue, 6 - retro - } - - // auto exposure controls - s->set_aec2(s, _aec2 ? 1 : 0); - s->set_ae_level(s, _autoExposureLevel); // -2 to 2 - s->set_gainceiling(s, GAINCEILING_2X); // GAINCEILING_2X 4X 8X 16X 32X 64X 128X - - // post processing - if (_autoSharpness) { - s->set_sharpness(s, 0); // auto-sharpness is not officially supported, default to 0 - } - s->set_saturation(s, _saturation); - s->set_contrast(s, _contrast); - s->set_brightness(s, _brightness); - - camera_sensor_info_t *sensor_info = esp_camera_sensor_get_info(&(s->id)); - if (sensor_info != NULL) { - if (sensor_info->model == CAMERA_OV2640) { - if (_autoSharpness) { - ov2640_enable_auto_sharpness(s); - } else { - ov2640_set_sharpness(s, _sharpnessLevel); - } - - /* Workaround - bug in cam library - enable bits are set without using bitwise OR logic -> only latest enable setting is used */ - /* Library version: https://github.com/espressif/esp32-camera/commit/5c8349f4cf169c8a61283e0da9b8cff10994d3f3 */ - /* Reference: https://esp32.com/viewtopic.php?f=19&t=14376#p93178 */ - /* The memory structure is as follows for - byte_0 = enable_bits - byte_0->bit0 = enable saturation and hue --> OK - byte_0->bit1 = enable saturation --> OK - byte_0->bit2 = enable brightness and contrast --> OK - byte_0->bit3 = enable green -> blue spitial effect (Antique and blunish and greenish and readdish and b&w) enable - byte_0->bit4 = anable gray -> read spitial effect (Antique and blunish and greenish and readdish and b&w) enable - byte_0->bit5 = remove (UV) in YUV color system - byte_0->bit6 = enable negative - byte_0->bit7 = remove (Y) in YUV color system - byte_1 = saturation1 0-255 --> ? - byte_2 = hue 0-255 --> OK - byte_3 = saturation2 0-255 --> OK - byte_4 = reenter saturation2 in documents --> ? - byte_5 = spital effect green -> blue 0-255 --> ? - byte_6 = spital effect gray -> read 0-255 --> ? - byte_7 = contrast lower byte 0-255 --> OK - byte_8 = contrast higher byte 0-255 --> OK - byte_9 = brightness 0-255 --> OK - byte_10= if byte_10==4 contrast effective --> ? - */ - - //s->set_reg(s, 0x7C, 0xFF, 2); // Optional feature - hue setting: Select byte 2 in register 0x7C to set hue value - //s->set_reg(s, 0x7D, 0xFF, 0); // Optional feature - hue setting: Hue value 0 - 255 - int indirectReg0 = 0x07; // Set bit 0, 1, 2 to enable saturation, contrast, brightness and hue control - if (_grayscale) { - indirectReg0 |= 0x18; - } - // camera gives precedence to negative over grayscale, so it's easier to do negative ourselves. - // if (_negative) { - // indirectReg0 |= 0x40; - // } - // Indirect register access - s->set_reg(s, 0xFF, 0x01, 0); // Select DSP bank - s->set_reg(s, OV2640_IRA_BPADDR, 0xFF, 0x00); // Address 0x00 - s->set_reg(s, OV2640_IRA_BPDATA, 0xFF, indirectReg0); - s->set_reg(s, OV2640_IRA_BPADDR, 0xFF, 0x05); // Address 0x05 - s->set_reg(s, OV2640_IRA_BPDATA, 0xFF, 0x80); - s->set_reg(s, OV2640_IRA_BPDATA, 0xFF, 0x80); - } - } - } - else { - LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "SetBrightnessContrastSaturation: Failed to get control structure"); - } - - if (((_brightness != brightness) || (_contrast != contrast) || (_saturation != saturation)) && isFixedExposure) - EnableAutoExposure(waitbeforepicture_org); - - brightness = _brightness; - contrast = _contrast; - saturation = _saturation; - autoExposureLevel = _autoExposureLevel; - imageGrayscale = _grayscale; - imageNegative = _negative; - imageAec2 = _aec2; - imageAutoSharpness = _autoSharpness; - imageSharpnessLevel = _sharpnessLevel; - - ESP_LOGD(TAG, "brightness %d, contrast: %d, saturation %d, autoExposureLevel %d, grayscale %d", brightness, contrast, saturation, autoExposureLevel, (int)imageGrayscale); - - return true; -} - - -/* -* resolution = 0 \\ 1600 x 1200 -* resolution = 1 \\ 800 x 600 -* resolution = 2 \\ 400 x 296 -*/ -void CCamera::SetCamWindow(sensor_t *s, int resolution, int xOffset, int yOffset, int xLength, int yLength) -{ - s->set_res_raw(s, resolution, 0, 0, 0, xOffset, yOffset, xLength, yLength, xLength, yLength, false, false); -} - - -void CCamera::SetImageWidthHeightFromResolution(framesize_t resol) -{ - if (resol == FRAMESIZE_QVGA) - { - image_height = 240; - image_width = 320; - } - else if (resol == FRAMESIZE_VGA) - { - image_height = 480; - image_width = 640; - } - else if (resol == FRAMESIZE_SVGA) - { - image_height = 600; - image_width = 800; - } - else if (resol == FRAMESIZE_XGA) - { - image_height = 768; - image_width = 1024; - } - else if (resol == FRAMESIZE_HD) - { - image_height = 720; - image_width = 1280; - } - else if (resol == FRAMESIZE_SXGA) - { - image_height = 1024; - image_width = 1280; - } - else if (resol == FRAMESIZE_UXGA) - { - image_height = 1200; - image_width = 1600; - } -} - - -void CCamera::SetZoom(bool zoomEnabled, int zoomMode, int zoomOffsetX, int zoomOffsetY) -{ - imageZoomEnabled = zoomEnabled; - imageZoomMode = zoomMode; - imageZoomOffsetX = zoomOffsetX; - imageZoomOffsetY = zoomOffsetY; - - sensor_t *s = esp_camera_sensor_get(); - if (s) { - if (imageZoomEnabled) { - int z = imageZoomMode; - int x = imageZoomOffsetX; - int y = imageZoomOffsetY; - if (z > 1) - z = 1; - if (image_width >= 800 || image_height >= 600) { - z = 0; - } - int maxX = 1600 - image_width; - int maxY = 1200 - image_height; - if (z == 1) { - maxX = 800 - image_width; - maxY = 600 - image_height; - } - if (x > maxX) - x = maxX; - if (y > maxY) - y = maxY; - SetCamWindow(s, z, x, y, image_width, image_height); - } else { - s->set_framesize(s, ActualResolution); - } - } -} - - -void CCamera::SetQualitySize(int qual, framesize_t resol, bool zoomEnabled, int zoomMode, int zoomOffsetX, int zoomOffsetY) -{ - qual = min(63, max(8, qual)); // Limit quality from 8..63 (values lower than 8 tent to be unstable) - - ActualResolution = resol; - ActualQuality = qual; - - imageZoomEnabled = zoomEnabled; - imageZoomMode = zoomMode; - imageZoomOffsetX = zoomOffsetX; - imageZoomOffsetY = zoomOffsetY; - - SetImageWidthHeightFromResolution(resol); - - sensor_t * s = esp_camera_sensor_get(); - if (s) { - s->set_quality(s, qual); - SetZoom(zoomEnabled, zoomMode, zoomOffsetX, zoomOffsetY); - } - else { - LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "SetQualitySize: Failed to get control structure"); - } -} - - -void CCamera::EnableAutoExposure(int flash_duration) -{ - ESP_LOGD(TAG, "EnableAutoExposure"); - - LEDOnOff(true); - if (flash_duration > 0) { - LightOnOff(true); - const TickType_t xDelay = flash_duration / portTICK_PERIOD_MS; - vTaskDelay( xDelay ); - } - - camera_fb_t * fb = esp_camera_fb_get(); - esp_camera_fb_return(fb); - fb = esp_camera_fb_get(); - if (!fb) { - LEDOnOff(false); - LightOnOff(false); - LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "EnableAutoExposure: Capture Failed. " - "Check camera module and/or proper electrical connection"); - //doReboot(); - } - esp_camera_fb_return(fb); - - sensor_t * s = esp_camera_sensor_get(); - if (s) { - s->set_gain_ctrl(s, 0); - s->set_exposure_ctrl(s, 0); - } - else { - LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "EnableAutoExposure: Failed to get control structure to set gain+exposure"); - } - - LEDOnOff(false); - LightOnOff(false); - isFixedExposure = true; - waitbeforepicture_org = flash_duration; -} - - esp_err_t CCamera::CaptureToBasisImage(CImageBasis *_Image, int delay) { - #ifdef DEBUG_DETAIL_ON - LogFile.WriteHeapInfo("CaptureToBasisImage - Start"); - #endif +#ifdef DEBUG_DETAIL_ON + LogFile.WriteHeapInfo("CaptureToBasisImage - Start"); +#endif - _Image->EmptyImage(); //Delete previous stored raw image -> black image - - LEDOnOff(true); + _Image->EmptyImage(); // Delete previous stored raw image -> black image - if (delay > 0) { - LightOnOff(true); + LEDOnOff(true); // Status-LED on + + if (delay > 0) + { + LightOnOff(true); // Flash-LED on const TickType_t xDelay = delay / portTICK_PERIOD_MS; - vTaskDelay( xDelay ); + vTaskDelay(xDelay); } - #ifdef DEBUG_DETAIL_ON - LogFile.WriteHeapInfo("CaptureToBasisImage - After LightOn"); - #endif +#ifdef DEBUG_DETAIL_ON + LogFile.WriteHeapInfo("CaptureToBasisImage - After LightOn"); +#endif - camera_fb_t * fb = esp_camera_fb_get(); + camera_fb_t *fb = esp_camera_fb_get(); esp_camera_fb_return(fb); fb = esp_camera_fb_get(); - if (!fb) { - LEDOnOff(false); - LightOnOff(false); + + if (!fb) + { + LEDOnOff(false); // Status-LED off + LightOnOff(false); // Flash-LED off LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "is not working anymore (CaptureToBasisImage) - most probably caused " "by a hardware problem (instablility, ...). System will reboot."); @@ -468,540 +567,532 @@ esp_err_t CCamera::CaptureToBasisImage(CImageBasis *_Image, int delay) return ESP_FAIL; } - if (demoMode) { // Use images stored on SD-Card instead of camera image + if (CCstatus.DemoMode) + { + // Use images stored on SD-Card instead of camera image /* Replace Framebuffer with image from SD-Card */ loadNextDemoImage(fb); } - CImageBasis* _zwImage = new CImageBasis("zwImage"); - if (_zwImage) { + CImageBasis *_zwImage = new CImageBasis("zwImage"); + + if (_zwImage) + { _zwImage->LoadFromMemory(fb->buf, fb->len); } - else { + else + { LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "CaptureToBasisImage: Can't allocate _zwImage"); } + esp_camera_fb_return(fb); - #ifdef DEBUG_DETAIL_ON - LogFile.WriteHeapInfo("CaptureToBasisImage - After fb_get"); - #endif +#ifdef DEBUG_DETAIL_ON + LogFile.WriteHeapInfo("CaptureToBasisImage - After fb_get"); +#endif - LEDOnOff(false); + LEDOnOff(false); // Status-LED off - if (delay > 0) - LightOnOff(false); - -// TickType_t xDelay = 1000 / portTICK_PERIOD_MS; -// vTaskDelay( xDelay ); // wait for power to recover - - #ifdef DEBUG_DETAIL_ON - LogFile.WriteHeapInfo("CaptureToBasisImage - After LoadFromMemory"); - #endif + if (delay > 0) + { + LightOnOff(false); // Flash-LED off + } - if (_zwImage == NULL) { + // TickType_t xDelay = 1000 / portTICK_PERIOD_MS; + // vTaskDelay( xDelay ); // wait for power to recover + +#ifdef DEBUG_DETAIL_ON + LogFile.WriteHeapInfo("CaptureToBasisImage - After LoadFromMemory"); +#endif + + if (_zwImage == NULL) + { return ESP_OK; } - if (imageNegative) { - _zwImage->Negative(); - } - - stbi_uc* p_target; - stbi_uc* p_source; + stbi_uc *p_target; + stbi_uc *p_source; int channels = 3; - int width = image_width; - int height = image_height; + int width = CCstatus.ImageWidth; + int height = CCstatus.ImageHeight; - #ifdef DEBUG_DETAIL_ON - std::string _zw = "Targetimage: " + std::to_string((int) _Image->rgb_image) + " Size: " + std::to_string(_Image->width) + ", " + std::to_string(_Image->height); - _zw = _zw + " _zwImage: " + std::to_string((int) _zwImage->rgb_image) + " Size: " + std::to_string(_zwImage->width) + ", " + std::to_string(_zwImage->height); - LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, _zw); - #endif +#ifdef DEBUG_DETAIL_ON + std::string _zw = "Targetimage: " + std::to_string((int)_Image->rgb_image) + " Size: " + std::to_string(_Image->width) + ", " + std::to_string(_Image->height); + _zw = _zw + " _zwImage: " + std::to_string((int)_zwImage->rgb_image) + " Size: " + std::to_string(_zwImage->width) + ", " + std::to_string(_zwImage->height); + LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, _zw); +#endif for (int x = 0; x < width; ++x) + { for (int y = 0; y < height; ++y) { p_target = _Image->rgb_image + (channels * (y * width + x)); p_source = _zwImage->rgb_image + (channels * (y * width + x)); - for (int c = 0; c < channels; c++) { + + for (int c = 0; c < channels; c++) + { p_target[c] = p_source[c]; } } + } delete _zwImage; - #ifdef DEBUG_DETAIL_ON - LogFile.WriteHeapInfo("CaptureToBasisImage - Done"); - #endif +#ifdef DEBUG_DETAIL_ON + LogFile.WriteHeapInfo("CaptureToBasisImage - Done"); +#endif return ESP_OK; } - esp_err_t CCamera::CaptureToFile(std::string nm, int delay) { string ftype; - LEDOnOff(true); // Switched off to save power ! + LEDOnOff(true); // Status-LED on - if (delay > 0) { - LightOnOff(true); + if (delay > 0) + { + LightOnOff(true); // Flash-LED on const TickType_t xDelay = delay / portTICK_PERIOD_MS; - vTaskDelay( xDelay ); + vTaskDelay(xDelay); } - camera_fb_t * fb = esp_camera_fb_get(); + camera_fb_t *fb = esp_camera_fb_get(); esp_camera_fb_return(fb); fb = esp_camera_fb_get(); - if (!fb) { - LEDOnOff(false); - LightOnOff(false); + + if (!fb) + { + LEDOnOff(false); // Status-LED off + LightOnOff(false); // Flash-LED off LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "CaptureToFile: Capture Failed. " "Check camera module and/or proper electrical connection"); - //doReboot(); + // doReboot(); return ESP_FAIL; } - LEDOnOff(false); - #ifdef DEBUG_DETAIL_ON - ESP_LOGD(TAG, "w %d, h %d, size %d", fb->width, fb->height, fb->len); - #endif + LEDOnOff(false); // Status-LED off + +#ifdef DEBUG_DETAIL_ON + ESP_LOGD(TAG, "w %d, h %d, size %d", fb->width, fb->height, fb->len); +#endif nm = FormatFileName(nm); - #ifdef DEBUG_DETAIL_ON - ESP_LOGD(TAG, "Save Camera to: %s", nm.c_str()); - #endif +#ifdef DEBUG_DETAIL_ON + ESP_LOGD(TAG, "Save Camera to: %s", nm.c_str()); +#endif ftype = toUpper(getFileType(nm)); - #ifdef DEBUG_DETAIL_ON - ESP_LOGD(TAG, "Filetype: %s", ftype.c_str()); - #endif +#ifdef DEBUG_DETAIL_ON + ESP_LOGD(TAG, "Filetype: %s", ftype.c_str()); +#endif - uint8_t * buf = NULL; - size_t buf_len = 0; - bool converted = false; + uint8_t *buf = NULL; + size_t buf_len = 0; + bool converted = false; if (ftype.compare("BMP") == 0) { frame2bmp(fb, &buf, &buf_len); converted = true; } + if (ftype.compare("JPG") == 0) { - if(fb->format != PIXFORMAT_JPEG){ - bool jpeg_converted = frame2jpg(fb, ActualQuality, &buf, &buf_len); + if (fb->format != PIXFORMAT_JPEG) + { + bool jpeg_converted = frame2jpg(fb, CCstatus.ImageQuality, &buf, &buf_len); converted = true; - if(!jpeg_converted){ + + if (!jpeg_converted) + { ESP_LOGE(TAG, "JPEG compression failed"); } - } else { + } + else + { buf_len = fb->len; buf = fb->buf; } } - FILE * fp = fopen(nm.c_str(), "wb"); - if (fp == NULL) { // If an error occurs during the file creation + FILE *fp = fopen(nm.c_str(), "wb"); + + if (fp == NULL) + { + // If an error occurs during the file creation LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "CaptureToFile: Failed to open file " + nm); } - else { - fwrite(buf, sizeof(uint8_t), buf_len, fp); + else + { + fwrite(buf, sizeof(uint8_t), buf_len, fp); fclose(fp); - } + } if (converted) + { free(buf); + } esp_camera_fb_return(fb); - if (delay > 0) - LightOnOff(false); + if (delay > 0) + { + LightOnOff(false); // Flash-LED off + } - return ESP_OK; + return ESP_OK; } - esp_err_t CCamera::CaptureToHTTP(httpd_req_t *req, int delay) { esp_err_t res = ESP_OK; size_t fb_len = 0; int64_t fr_start = esp_timer_get_time(); - LEDOnOff(true); + LEDOnOff(true); // Status-LED on - if (delay > 0) { - LightOnOff(true); + if (delay > 0) + { + LightOnOff(true); // Flash-LED on const TickType_t xDelay = delay / portTICK_PERIOD_MS; - vTaskDelay( xDelay ); + vTaskDelay(xDelay); } camera_fb_t *fb = esp_camera_fb_get(); esp_camera_fb_return(fb); fb = esp_camera_fb_get(); - if (!fb) { - LEDOnOff(false); - LightOnOff(false); + + if (!fb) + { + LEDOnOff(false); // Status-LED off + LightOnOff(false); // Flash-LED off LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "CaptureToFile: Capture Failed. " - "Check camera module and/or proper electrical connection"); + "Check camera module and/or proper electrical connection"); httpd_resp_send_500(req); -// doReboot(); + // doReboot(); return ESP_FAIL; } - LEDOnOff(false); + LEDOnOff(false); // Status-LED off res = httpd_resp_set_type(req, "image/jpeg"); - if(res == ESP_OK){ + + if (res == ESP_OK) + { res = httpd_resp_set_hdr(req, "Content-Disposition", "inline; filename=raw.jpg"); } - if(res == ESP_OK){ - if (demoMode) { // Use images stored on SD-Card instead of camera image + if (res == ESP_OK) + { + if (CCstatus.DemoMode) + { + // Use images stored on SD-Card instead of camera image LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Using Demo image!"); /* Replace Framebuffer with image from SD-Card */ loadNextDemoImage(fb); res = httpd_resp_send(req, (const char *)fb->buf, fb->len); } - else { - if(fb->format == PIXFORMAT_JPEG){ + else + { + if (fb->format == PIXFORMAT_JPEG) + { fb_len = fb->len; res = httpd_resp_send(req, (const char *)fb->buf, fb->len); - } else { + } + else + { jpg_chunking_t jchunk = {req, 0}; - res = frame2jpg_cb(fb, 80, jpg_encode_stream, &jchunk)?ESP_OK:ESP_FAIL; + res = frame2jpg_cb(fb, 80, jpg_encode_stream, &jchunk) ? ESP_OK : ESP_FAIL; httpd_resp_send_chunk(req, NULL, 0); fb_len = jchunk.len; } } } + esp_camera_fb_return(fb); int64_t fr_end = esp_timer_get_time(); - - ESP_LOGI(TAG, "JPG: %dKB %dms", (int)(fb_len/1024), (int)((fr_end - fr_start)/1000)); - if (delay > 0) - LightOnOff(false); + ESP_LOGI(TAG, "JPG: %dKB %dms", (int)(fb_len / 1024), (int)((fr_end - fr_start) / 1000)); + + if (delay > 0) + { + LightOnOff(false); // Flash-LED off + } return res; } - esp_err_t CCamera::CaptureToStream(httpd_req_t *req, bool FlashlightOn) { esp_err_t res = ESP_OK; size_t fb_len = 0; int64_t fr_start; - char * part_buf[64]; + char *part_buf[64]; + + // wenn die Kameraeinstellungen durch Erstellen eines neuen Referenzbildes verändert wurden, müssen sie neu gesetzt werden + if (CFstatus.changedCameraSettings) + { + Camera.setSensorDatenFromCCstatus(); // CCstatus >>> Kamera + Camera.SetQualityZoomSize(CCstatus.ImageQuality, CCstatus.ImageFrameSize, CCstatus.ImageZoomEnabled, CCstatus.ImageZoomOffsetX, CCstatus.ImageZoomOffsetY, CCstatus.ImageZoomSize); + CFstatus.changedCameraSettings = false; + } LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Live stream started"); - if (FlashlightOn) { - LEDOnOff(true); - LightOnOff(true); + if (FlashlightOn) + { + LEDOnOff(true); // Status-LED on + LightOnOff(true); // Flash-LED on } - //httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*"); //stream is blocking web interface, only serving to local + // httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*"); //stream is blocking web interface, only serving to local httpd_resp_set_type(req, _STREAM_CONTENT_TYPE); httpd_resp_send_chunk(req, _STREAM_BOUNDARY, strlen(_STREAM_BOUNDARY)); - while(1) + while (1) { fr_start = esp_timer_get_time(); camera_fb_t *fb = esp_camera_fb_get(); esp_camera_fb_return(fb); fb = esp_camera_fb_get(); - if (!fb) { + + if (!fb) + { LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "CaptureToStream: Camera framebuffer not available"); break; } + fb_len = fb->len; - - if (res == ESP_OK){ + + if (res == ESP_OK) + { size_t hlen = snprintf((char *)part_buf, sizeof(part_buf), _STREAM_PART, fb_len); res = httpd_resp_send_chunk(req, (const char *)part_buf, hlen); } - if (res == ESP_OK){ + + if (res == ESP_OK) + { res = httpd_resp_send_chunk(req, (const char *)fb->buf, fb_len); } - if (res == ESP_OK){ + + if (res == ESP_OK) + { res = httpd_resp_send_chunk(req, _STREAM_BOUNDARY, strlen(_STREAM_BOUNDARY)); } - + esp_camera_fb_return(fb); int64_t fr_end = esp_timer_get_time(); - ESP_LOGD(TAG, "JPG: %dKB %dms", (int)(fb_len/1024), (int)((fr_end - fr_start)/1000)); + ESP_LOGD(TAG, "JPG: %dKB %dms", (int)(fb_len / 1024), (int)((fr_end - fr_start) / 1000)); - if (res != ESP_OK){ // Exit loop, e.g. also when closing the webpage + if (res != ESP_OK) + { + // Exit loop, e.g. also when closing the webpage break; } int64_t fr_delta_ms = (fr_end - fr_start) / 1000; - if (CAM_LIVESTREAM_REFRESHRATE > fr_delta_ms) { - const TickType_t xDelay = (CAM_LIVESTREAM_REFRESHRATE - fr_delta_ms) / portTICK_PERIOD_MS; - ESP_LOGD(TAG, "Stream: sleep for: %ldms", (long) xDelay*10); - vTaskDelay(xDelay); + + if (CAM_LIVESTREAM_REFRESHRATE > fr_delta_ms) + { + const TickType_t xDelay = (CAM_LIVESTREAM_REFRESHRATE - fr_delta_ms) / portTICK_PERIOD_MS; + ESP_LOGD(TAG, "Stream: sleep for: %ldms", (long)xDelay * 10); + vTaskDelay(xDelay); } } - LEDOnOff(false); - LightOnOff(false); + LEDOnOff(false); // Status-LED off + LightOnOff(false); // Flash-LED off LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Live stream stopped"); return res; } - void CCamera::LightOnOff(bool status) { - GpioHandler* gpioHandler = gpio_handler_get(); - if ((gpioHandler != NULL) && (gpioHandler->isEnabled())) { + GpioHandler *gpioHandler = gpio_handler_get(); + + if ((gpioHandler != NULL) && (gpioHandler->isEnabled())) + { ESP_LOGD(TAG, "Use gpioHandler to trigger flashlight"); gpioHandler->flashLightEnable(status); - } - else { - #ifdef USE_PWM_LEDFLASH - if (status) { - ESP_LOGD(TAG, "Internal Flash-LED turn on with PWM %d", led_intensity); - ESP_ERROR_CHECK(ledc_set_duty(LEDC_MODE, LEDC_CHANNEL, led_intensity)); + } + else + { +#ifdef USE_PWM_LEDFLASH + if (status) + { + ESP_LOGD(TAG, "Internal Flash-LED turn on with PWM %d", CCstatus.ImageLedIntensity); + ESP_ERROR_CHECK(ledc_set_duty(LEDC_MODE, LEDC_CHANNEL, CCstatus.ImageLedIntensity)); // Update duty to apply the new value ESP_ERROR_CHECK(ledc_update_duty(LEDC_MODE, LEDC_CHANNEL)); } - else { + else + { ESP_LOGD(TAG, "Internal Flash-LED turn off PWM"); ESP_ERROR_CHECK(ledc_set_duty(LEDC_MODE, LEDC_CHANNEL, 0)); ESP_ERROR_CHECK(ledc_update_duty(LEDC_MODE, LEDC_CHANNEL)); } - #else +#else // Init the GPIO gpio_pad_select_gpio(FLASH_GPIO); - // Set the GPIO as a push/pull output - gpio_set_direction(FLASH_GPIO, GPIO_MODE_OUTPUT); - if (status) + // Set the GPIO as a push/pull output + gpio_set_direction(FLASH_GPIO, GPIO_MODE_OUTPUT); + + if (status) + { gpio_set_level(FLASH_GPIO, 1); + } else + { gpio_set_level(FLASH_GPIO, 0); - #endif + } +#endif } } - void CCamera::LEDOnOff(bool status) { - if (xHandle_task_StatusLED == NULL) { + if (xHandle_task_StatusLED == NULL) + { // Init the GPIO gpio_pad_select_gpio(BLINK_GPIO); + /* Set the GPIO as a push/pull output */ - gpio_set_direction(BLINK_GPIO, GPIO_MODE_OUTPUT); + gpio_set_direction(BLINK_GPIO, GPIO_MODE_OUTPUT); - if (!status) + if (!status) + { gpio_set_level(BLINK_GPIO, 1); + } else - gpio_set_level(BLINK_GPIO, 0); + { + gpio_set_level(BLINK_GPIO, 0); + } } } - -void CCamera::GetCameraParameter(httpd_req_t *req, int &qual, framesize_t &resol, bool &zoomEnabled, int &zoomMode, int &zoomOffsetX, int &zoomOffsetY) +void CCamera::SetImageWidthHeightFromResolution(framesize_t resol) { - char _query[100]; - char _value[10]; - - resol = ActualResolution; - qual = ActualQuality; - zoomEnabled = imageZoomEnabled; - zoomMode = imageZoomMode; - zoomOffsetX = imageZoomOffsetX; - zoomOffsetY = imageZoomOffsetY; - - if (httpd_req_get_url_query_str(req, _query, 100) == ESP_OK) + if (resol == FRAMESIZE_QVGA) { - ESP_LOGD(TAG, "Query: %s", _query); - if (httpd_query_key_value(_query, "size", _value, sizeof(_value)) == ESP_OK) - { - #ifdef DEBUG_DETAIL_ON - ESP_LOGD(TAG, "Size: %s", _size); - #endif - if (strcmp(_value, "QVGA") == 0) - resol = FRAMESIZE_QVGA; // 320x240 - else if (strcmp(_value, "VGA") == 0) - resol = FRAMESIZE_VGA; // 640x480 - else if (strcmp(_value, "SVGA") == 0) - resol = FRAMESIZE_SVGA; // 800x600 - else if (strcmp(_value, "XGA") == 0) - resol = FRAMESIZE_XGA; // 1024x768 - else if (strcmp(_value, "SXGA") == 0) - resol = FRAMESIZE_SXGA; // 1280x1024 - else if (strcmp(_value, "UXGA") == 0) - resol = FRAMESIZE_UXGA; // 1600x1200 - } - if (httpd_query_key_value(_query, "quality", _value, sizeof(_value)) == ESP_OK) - { - #ifdef DEBUG_DETAIL_ON - ESP_LOGD(TAG, "Quality: %s", _qual); - #endif - qual = atoi(_value); - if (qual > 63) // Limit to max. 63 - qual = 63; - else if (qual < 8) // Limit to min. 8 - qual = 8; - } - if (httpd_query_key_value(_query, "z", _value, sizeof(_value)) == ESP_OK) - { - #ifdef DEBUG_DETAIL_ON - ESP_LOGD(TAG, "Zoom: %s", _value); - #endif - if (atoi(_value) != 0) - zoomEnabled = true; - else - zoomEnabled = false; - } - if (httpd_query_key_value(_query, "zm", _value, sizeof(_value)) == ESP_OK) - { - #ifdef DEBUG_DETAIL_ON - ESP_LOGD(TAG, "Zoom mode: %s", _value); - #endif - zoomMode = atoi(_value); - if (zoomMode > 2) - zoomMode = 2; - else if (zoomMode < 0) - zoomMode = 0; - } - if (httpd_query_key_value(_query, "x", _value, sizeof(_value)) == ESP_OK) - { - #ifdef DEBUG_DETAIL_ON - ESP_LOGD(TAG, "X offset: %s", _value); - #endif - zoomOffsetX = atoi(_value); - if (zoomOffsetX < 0) - zoomOffsetX = 0; - } - if (httpd_query_key_value(_query, "y", _value, sizeof(_value)) == ESP_OK) - { - #ifdef DEBUG_DETAIL_ON - ESP_LOGD(TAG, "Y offset: %s", _value); - #endif - zoomOffsetY = atoi(_value); - if (zoomOffsetY < 0) - zoomOffsetY = 0; - } + CCstatus.ImageHeight = 240; + CCstatus.ImageWidth = 320; + } + else if (resol == FRAMESIZE_VGA) + { + CCstatus.ImageHeight = 480; + CCstatus.ImageWidth = 640; + } + else if (resol == FRAMESIZE_SVGA) + { + CCstatus.ImageHeight = 600; + CCstatus.ImageWidth = 800; + } + else if (resol == FRAMESIZE_XGA) + { + CCstatus.ImageHeight = 768; + CCstatus.ImageWidth = 1024; + } + else if (resol == FRAMESIZE_HD) + { + CCstatus.ImageHeight = 720; + CCstatus.ImageWidth = 1280; + } + else if (resol == FRAMESIZE_SXGA) + { + CCstatus.ImageHeight = 1024; + CCstatus.ImageWidth = 1280; + } + else if (resol == FRAMESIZE_UXGA) + { + CCstatus.ImageHeight = 1200; + CCstatus.ImageWidth = 1600; } } - -framesize_t CCamera::TextToFramesize(const char * _size) +framesize_t CCamera::TextToFramesize(const char *_size) { if (strcmp(_size, "QVGA") == 0) - return FRAMESIZE_QVGA; // 320x240 + { + return FRAMESIZE_QVGA; // 320x240 + } else if (strcmp(_size, "VGA") == 0) - return FRAMESIZE_VGA; // 640x480 + { + return FRAMESIZE_VGA; // 640x480 + } else if (strcmp(_size, "SVGA") == 0) - return FRAMESIZE_SVGA; // 800x600 + { + return FRAMESIZE_SVGA; // 800x600 + } else if (strcmp(_size, "XGA") == 0) - return FRAMESIZE_XGA; // 1024x768 + { + return FRAMESIZE_XGA; // 1024x768 + } else if (strcmp(_size, "SXGA") == 0) - return FRAMESIZE_SXGA; // 1280x1024 + { + return FRAMESIZE_SXGA; // 1280x1024 + } else if (strcmp(_size, "UXGA") == 0) - return FRAMESIZE_UXGA; // 1600x1200 - - return ActualResolution; -} - - -CCamera::CCamera() -{ - #ifdef DEBUG_DETAIL_ON - ESP_LOGD(TAG, "CreateClassCamera"); - #endif - brightness = 0; - contrast = 0; - saturation = 0; - isFixedExposure = false; - - ledc_init(); -} - - -esp_err_t CCamera::InitCam() -{ - ESP_LOGD(TAG, "Init Camera"); - ActualQuality = camera_config.jpeg_quality; - ActualResolution = camera_config.frame_size; - //initialize the camera - esp_camera_deinit(); // De-init in case it was already initialized - esp_err_t err = esp_camera_init(&camera_config); - if (err != ESP_OK) { - ESP_LOGE(TAG, "Camera Init Failed"); - return err; + { + return FRAMESIZE_UXGA; // 1600x1200 } - CameraInitSuccessful = true; - return ESP_OK; + return CCstatus.ImageFrameSize; } - -void CCamera::SetLEDIntensity(float _intrel) -{ - _intrel = min(_intrel, (float) 100); - _intrel = max(_intrel, (float) 0); - _intrel = _intrel / 100; - led_intensity = (int) (_intrel * 8191); - ESP_LOGD(TAG, "Set led_intensity to %d of 8191", led_intensity); - -} - - -bool CCamera::getCameraInitSuccessful() -{ - return CameraInitSuccessful; -} - - std::vector demoFiles; -void CCamera::useDemoMode() +void CCamera::useDemoMode(void) { char line[50]; FILE *fd = fopen("/sdcard/demo/files.txt", "r"); - if (!fd) { + + if (!fd) + { LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Can not start Demo mode, the folder '/sdcard/demo/' does not contain the needed files!"); LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "See Details on https://jomjol.github.io/AI-on-the-edge-device-docs/Demo-Mode!"); return; } - demoImage = (uint8_t*)malloc(DEMO_IMAGE_SIZE); - if (demoImage == NULL) { + demoImage = (uint8_t *)malloc(DEMO_IMAGE_SIZE); + + if (demoImage == NULL) + { LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Unable to acquire required memory for demo image!"); return; } - while (fgets(line, sizeof(line), fd) != NULL) { + while (fgets(line, sizeof(line), fd) != NULL) + { line[strlen(line) - 1] = '\0'; demoFiles.push_back(line); } - + fclose(fd); - LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Using Demo mode (" + std::to_string(demoFiles.size()) + - " files) instead of real camera image!"); + LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Using Demo mode (" + std::to_string(demoFiles.size()) + " files) instead of real camera image!"); - for (auto file : demoFiles) { + for (auto file : demoFiles) + { LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, file); } - demoMode = true; + CCstatus.DemoMode = true; } - -bool CCamera::loadNextDemoImage(camera_fb_t *fb) { +bool CCamera::loadNextDemoImage(camera_fb_t *fb) +{ char filename[50]; int readBytes; long fileSize; @@ -1012,17 +1103,20 @@ bool CCamera::loadNextDemoImage(camera_fb_t *fb) { /* Inject saved image */ - FILE * fp = fopen(filename, "rb"); - if (!fp) { - LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Failed to read file: " + std::string(filename) +"!"); + FILE *fp = fopen(filename, "rb"); + + if (!fp) + { + LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Failed to read file: " + std::string(filename) + "!"); return false; } fileSize = GetFileSize(filename); - if (fileSize > DEMO_IMAGE_SIZE) { + + if (fileSize > DEMO_IMAGE_SIZE) + { char buf[100]; - snprintf(buf, sizeof(buf), "Demo Image (%d bytes) is larger than provided buffer (%d bytes)!", - (int)fileSize, DEMO_IMAGE_SIZE); + snprintf(buf, sizeof(buf), "Demo Image (%d bytes) is larger than provided buffer (%d bytes)!", (int)fileSize, DEMO_IMAGE_SIZE); LogFile.WriteToFile(ESP_LOG_ERROR, TAG, std::string(buf)); return false; } @@ -1038,7 +1132,6 @@ bool CCamera::loadNextDemoImage(camera_fb_t *fb) { return true; } - long CCamera::GetFileSize(std::string filename) { struct stat stat_buf; diff --git a/code/components/jomjol_controlcamera/ClassControllCamera.h b/code/components/jomjol_controlcamera/ClassControllCamera.h index 064eefb9..b674ead3 100644 --- a/code/components/jomjol_controlcamera/ClassControllCamera.h +++ b/code/components/jomjol_controlcamera/ClassControllCamera.h @@ -15,66 +15,100 @@ #include "CImageBasis.h" #include "../../include/defines.h" -class CCamera { - protected: - int ActualQuality; - framesize_t ActualResolution; - int brightness, contrast, saturation, autoExposureLevel; - bool isFixedExposure; - int waitbeforepicture_org; - int led_intensity = 4095; +typedef enum +{ + OV2640_MODE_UXGA, + OV2640_MODE_SVGA, + OV2640_MODE_CIF +} ov2640_sensor_mode_t; - void ledc_init(void); - bool CameraInitSuccessful = false; - bool demoMode = false; +typedef struct +{ + framesize_t ImageFrameSize = FRAMESIZE_VGA; // 0 - 10 + gainceiling_t ImageGainceiling; // Image gain (GAINCEILING_x2, x4, x8, x16, x32, x64 or x128) - bool loadNextDemoImage(camera_fb_t *fb); - long GetFileSize(std::string filename); + int ImageQuality; // 0 - 63 + int ImageBrightness; // (-2 to 2) - set brightness + int ImageContrast; //-2 - 2 + int ImageSaturation; //-2 - 2 + int ImageSharpness; //-2 - 2 + bool ImageAutoSharpness; + int ImageSpecialEffect; // 0 - 6 + int ImageWbMode; // 0 to 4 - if awb_gain enabled (0 - Auto, 1 - Sunny, 2 - Cloudy, 3 - Office, 4 - Home) + int ImageAwb; // white balance enable (0 or 1) + int ImageAwbGain; // Auto White Balance enable (0 or 1) + int ImageAec; // auto exposure off (1 or 0) + int ImageAec2; // automatic exposure sensor (0 or 1) + int ImageAeLevel; // auto exposure levels (-2 to 2) + int ImageAecValue; // set exposure manually (0-1200) + int ImageAgc; // auto gain off (1 or 0) + int ImageAgcGain; // set gain manually (0 - 30) + int ImageBpc; // black pixel correction + int ImageWpc; // white pixel correction + int ImageRawGma; // (1 or 0) + int ImageLenc; // lens correction (1 or 0) + int ImageHmirror; // (0 or 1) flip horizontally + int ImageVflip; // Invert image (0 or 1) + int ImageDcw; // downsize enable (1 or 0) - void SetCamWindow(sensor_t *s, int resolution, int xOffset, int yOffset, int xLength, int yLength); - void SetImageWidthHeightFromResolution(framesize_t resol); + int ImageWidth; + int ImageHeight; - public: - int image_height, image_width; - bool imageZoomEnabled = false; - int imageZoomMode = 0; - int imageZoomOffsetX = 0; - int imageZoomOffsetY = 0; - bool imageNegative = false; - bool imageAec2 = false; - bool imageAutoSharpness = false; - int imageSharpnessLevel = 0; - #ifdef GRAYSCALE_AS_DEFAULT - bool imageGrayscale = true; - #else - bool imageGrayscale = false; - #endif - - CCamera(); - esp_err_t InitCam(); + int ImageLedIntensity; - void LightOnOff(bool status); - void LEDOnOff(bool status); - esp_err_t CaptureToHTTP(httpd_req_t *req, int delay = 0); - esp_err_t CaptureToStream(httpd_req_t *req, bool FlashlightOn); - void SetQualitySize(int qual, framesize_t resol, bool zoomEnabled, int zoomMode, int zoomOffsetX, int zoomOffsetY); - bool SetBrightnessContrastSaturation(int _brightness, int _contrast, int _saturation, int _autoExposureLevel, bool _grayscale, bool _negative, bool _aec2, int _sharpnessLevel); - void SetZoom(bool zoomEnabled, int zoomMode, int zoomOffsetX, int zoomOffsetY); - void GetCameraParameter(httpd_req_t *req, int &qual, framesize_t &resol, bool &zoomEnabled, int &zoomMode, int &zoomOffsetX, int &zoomOffsetY); - void SetLEDIntensity(float _intrel); - bool testCamera(void); - void EnableAutoExposure(int flash_duration); - bool getCameraInitSuccessful(); - void useDemoMode(void); - + bool ImageZoomEnabled; + int ImageZoomMode; + int ImageZoomOffsetX; + int ImageZoomOffsetY; + int ImageZoomSize; - framesize_t TextToFramesize(const char * text); + int WaitBeforePicture; + bool isImageSize; - esp_err_t CaptureToFile(std::string nm, int delay = 0); - esp_err_t CaptureToBasisImage(CImageBasis *_Image, int delay = 0); + bool CameraInitSuccessful; + bool changedCameraSettings; + bool DemoMode; + bool SaveAllFiles; +} camera_controll_config_temp_t; + +extern camera_controll_config_temp_t CCstatus; + +class CCamera +{ +protected: + void ledc_init(void); + bool loadNextDemoImage(camera_fb_t *fb); + long GetFileSize(std::string filename); + void SetCamWindow(sensor_t *s, int resolution, int xOffset, int yOffset, int xTotal, int yTotal, int xOutput, int yOutput); + void SetImageWidthHeightFromResolution(framesize_t resol); + +public: + CCamera(void); + esp_err_t InitCam(void); + + void LightOnOff(bool status); + void LEDOnOff(bool status); + + esp_err_t setSensorDatenFromCCstatus(void); + esp_err_t getSensorDatenToCCstatus(void); + + esp_err_t CaptureToHTTP(httpd_req_t *req, int delay = 0); + esp_err_t CaptureToStream(httpd_req_t *req, bool FlashlightOn); + + void SetQualityZoomSize(int qual, framesize_t resol, bool zoomEnabled, int zoomOffsetX, int zoomOffsetY, int imageSize); + void SetZoomSize(bool zoomEnabled, int zoomOffsetX, int zoomOffsetY, int imageSize); + void SetCamSharpness(bool _autoSharpnessEnabled, int _sharpnessLevel); + + void SetLEDIntensity(float _intrel); + bool testCamera(void); + bool getCameraInitSuccessful(void); + void useDemoMode(void); + + framesize_t TextToFramesize(const char *text); + + esp_err_t CaptureToFile(std::string nm, int delay = 0); + esp_err_t CaptureToBasisImage(CImageBasis *_Image, int delay = 0); }; - extern CCamera Camera; - #endif \ No newline at end of file diff --git a/code/components/jomjol_controlcamera/ov2640_sharpness.cpp b/code/components/jomjol_controlcamera/ov2640_sharpness.cpp index 6970b27c..8e67bc78 100644 --- a/code/components/jomjol_controlcamera/ov2640_sharpness.cpp +++ b/code/components/jomjol_controlcamera/ov2640_sharpness.cpp @@ -3,71 +3,78 @@ #include "ov2640_sharpness.h" -#define OV2640_MAXLEVEL_SHARPNESS 6 - const static uint8_t OV2640_SHARPNESS_AUTO[]= { - 0xFF, 0x00, 0xff, - 0x92, 0x01, 0xff, + //reg, val, mask + 0xFF, 0x00, 0xFF, + 0x92, 0x01, 0xFF, 0x93, 0x20, 0x20, 0x00, 0x00, 0x00 }; const static uint8_t OV2640_SHARPNESS_MANUAL[]= { - 0xFF, 0x00, 0xff, - 0x92, 0x01, 0xff, + //reg, val, mask + 0xFF, 0x00, 0xFF, + 0x92, 0x01, 0xFF, 0x93, 0x00, 0x20, 0x00, 0x00, 0x00 }; const static uint8_t OV2640_SHARPNESS_LEVEL0[]= { - 0xFF, 0x00, 0xff, - 0x92, 0x01, 0xff, - 0x93, 0xc0, 0x1f, + //reg, val, mask + 0xFF, 0x00, 0xFF, + 0x92, 0x01, 0xFF, + 0x93, 0xC0, 0x1F, 0x00, 0x00, 0x00 }; const static uint8_t OV2640_SHARPNESS_LEVEL1[]= { - 0xFF, 0x00, 0xff, - 0x92, 0x01, 0xff, - 0x93, 0xc1, 0x1f, + //reg, val, mask + 0xFF, 0x00, 0xFF, + 0x92, 0x01, 0xFF, + 0x93, 0xC1, 0x1F, 0x00, 0x00, 0x00 }; const static uint8_t OV2640_SHARPNESS_LEVEL2[]= { - 0xFF, 0x00, 0xff, - 0x92, 0x01, 0xff, - 0x93, 0xc2, 0x1f, + //reg, val, mask + 0xFF, 0x00, 0xFF, + 0x92, 0x01, 0xFF, + 0x93, 0xC2, 0x1F, 0x00, 0x00, 0x00 }; const static uint8_t OV2640_SHARPNESS_LEVEL3[]= { - 0xFF, 0x00, 0xff, - 0x92, 0x01, 0xff, - 0x93, 0xc4, 0x1f, + //reg, val, mask + 0xFF, 0x00, 0xFF, + 0x92, 0x01, 0xFF, + 0x93, 0xC4, 0x1F, 0x00, 0x00, 0x00 }; const static uint8_t OV2640_SHARPNESS_LEVEL4[]= { - 0xFF, 0x00, 0xff, - 0x92, 0x01, 0xff, - 0x93, 0xc8, 0x1f, + //reg, val, mask + 0xFF, 0x00, 0xFF, + 0x92, 0x01, 0xFF, + 0x93, 0xC8, 0x1F, 0x00, 0x00, 0x00 }; const static uint8_t OV2640_SHARPNESS_LEVEL5[]= { - 0xFF, 0x00, 0xff, - 0x92, 0x01, 0xff, - 0x93, 0xd0, 0x1f, + //reg, val, mask + 0xFF, 0x00, 0xFF, + 0x92, 0x01, 0xFF, + 0x93, 0xD0, 0x1F, 0x00, 0x00, 0x00 }; const static uint8_t OV2640_SHARPNESS_LEVEL6[]= { - 0xFF, 0x00, 0xff, - 0x92, 0x01, 0xff, - 0x93, 0xdf, 0x1f, + //reg, val, mask + 0xFF, 0x00, 0xFF, + 0x92, 0x01, 0xFF, + 0x93, 0xDF, 0x1F, 0x00, 0x00, 0x00 }; @@ -82,6 +89,9 @@ const static uint8_t *OV2640_SETTING_SHARPNESS[]= OV2640_SHARPNESS_LEVEL6 // +3 sharpness }; +#define OV2640_MAXLEVEL_SHARPNESS 6 + + static int table_mask_write(sensor_t *sensor, const uint8_t* ptab) { uint8_t address; @@ -91,34 +101,52 @@ static int table_mask_write(sensor_t *sensor, const uint8_t* ptab) const uint8_t *pdata = ptab; if (pdata == NULL) + { return -1; + } while (1) { address = *pdata++; value = *pdata++; mask = *pdata++; + if ((address == 0) && (value == 0) && (mask == 0)) + { break; + } + sensor->set_reg(sensor, address, mask, value); } return 0; } + int ov2640_enable_auto_sharpness(sensor_t *sensor) { table_mask_write(sensor, OV2640_SHARPNESS_AUTO); + return 0; } int ov2640_set_sharpness(sensor_t *sensor, int sharpness) { - if ((sharpness < -3) || (sharpness > OV2640_MAXLEVEL_SHARPNESS - 3)) - return -1; + int sharpness_temp = 0; + + if (sharpness < -3) + { + sharpness_temp = -3; + } + + if (sharpness > OV2640_MAXLEVEL_SHARPNESS - 3) + { + sharpness_temp = OV2640_MAXLEVEL_SHARPNESS - 3; + } table_mask_write(sensor, OV2640_SHARPNESS_MANUAL); - table_mask_write(sensor, OV2640_SETTING_SHARPNESS[sharpness + 3]); + table_mask_write(sensor, OV2640_SETTING_SHARPNESS[sharpness_temp + 3]); + return 0; } diff --git a/code/components/jomjol_controlcamera/server_camera.cpp b/code/components/jomjol_controlcamera/server_camera.cpp index dc37e2ab..ed6d0d12 100644 --- a/code/components/jomjol_controlcamera/server_camera.cpp +++ b/code/components/jomjol_controlcamera/server_camera.cpp @@ -5,6 +5,7 @@ #include "esp_camera.h" #include "ClassControllCamera.h" +#include "MainFlowControl.h" #include "ClassLogFile.h" #include "esp_log.h" @@ -13,191 +14,183 @@ static const char *TAG = "server_cam"; +void PowerResetCamera() +{ + ESP_LOGD(TAG, "Resetting camera by power down line"); + gpio_config_t conf; + conf.intr_type = GPIO_INTR_DISABLE; + conf.pin_bit_mask = 1LL << GPIO_NUM_32; + conf.mode = GPIO_MODE_OUTPUT; + conf.pull_down_en = GPIO_PULLDOWN_DISABLE; + conf.pull_up_en = GPIO_PULLUP_DISABLE; + gpio_config(&conf); -void PowerResetCamera(){ - - ESP_LOGD(TAG, "Resetting camera by power down line"); - gpio_config_t conf; - conf.intr_type = GPIO_INTR_DISABLE; - conf.pin_bit_mask = 1LL << GPIO_NUM_32; - conf.mode = GPIO_MODE_OUTPUT; - conf.pull_down_en = GPIO_PULLDOWN_DISABLE; - conf.pull_up_en = GPIO_PULLUP_DISABLE; - gpio_config(&conf); - - // carefull, logic is inverted compared to reset pin - gpio_set_level(GPIO_NUM_32, 1); - vTaskDelay(1000 / portTICK_PERIOD_MS); - gpio_set_level(GPIO_NUM_32, 0); - vTaskDelay(1000 / portTICK_PERIOD_MS); + // carefull, logic is inverted compared to reset pin + gpio_set_level(GPIO_NUM_32, 1); + vTaskDelay(1000 / portTICK_PERIOD_MS); + gpio_set_level(GPIO_NUM_32, 0); + vTaskDelay(1000 / portTICK_PERIOD_MS); } - esp_err_t handler_lightOn(httpd_req_t *req) { - #ifdef DEBUG_DETAIL_ON - LogFile.WriteHeapInfo("handler_lightOn - Start"); - ESP_LOGD(TAG, "handler_lightOn uri: %s", req->uri); - #endif +#ifdef DEBUG_DETAIL_ON + LogFile.WriteHeapInfo("handler_lightOn - Start"); + ESP_LOGD(TAG, "handler_lightOn uri: %s", req->uri); +#endif - if (Camera.getCameraInitSuccessful()) + if (Camera.getCameraInitSuccessful()) { Camera.LightOnOff(true); - const char* resp_str = (const char*) req->user_ctx; + const char *resp_str = (const char *)req->user_ctx; httpd_resp_send(req, resp_str, strlen(resp_str)); } - else + else { httpd_resp_send_err(req, HTTPD_403_FORBIDDEN, "Camera not initialized: REST API /lighton not available!"); return ESP_ERR_NOT_FOUND; } - #ifdef DEBUG_DETAIL_ON - LogFile.WriteHeapInfo("handler_lightOn - Done"); - #endif +#ifdef DEBUG_DETAIL_ON + LogFile.WriteHeapInfo("handler_lightOn - Done"); +#endif return ESP_OK; } - esp_err_t handler_lightOff(httpd_req_t *req) { - #ifdef DEBUG_DETAIL_ON - LogFile.WriteHeapInfo("handler_lightOff - Start"); - ESP_LOGD(TAG, "handler_lightOff uri: %s", req->uri); - #endif +#ifdef DEBUG_DETAIL_ON + LogFile.WriteHeapInfo("handler_lightOff - Start"); + ESP_LOGD(TAG, "handler_lightOff uri: %s", req->uri); +#endif - if (Camera.getCameraInitSuccessful()) + if (Camera.getCameraInitSuccessful()) { Camera.LightOnOff(false); - const char* resp_str = (const char*) req->user_ctx; - httpd_resp_send(req, resp_str, strlen(resp_str)); + const char *resp_str = (const char *)req->user_ctx; + httpd_resp_send(req, resp_str, strlen(resp_str)); } - else + else { httpd_resp_send_err(req, HTTPD_403_FORBIDDEN, "Camera not initialized: REST API /lightoff not available!"); return ESP_ERR_NOT_FOUND; } - #ifdef DEBUG_DETAIL_ON - LogFile.WriteHeapInfo("handler_lightOff - Done"); - #endif +#ifdef DEBUG_DETAIL_ON + LogFile.WriteHeapInfo("handler_lightOff - Done"); +#endif return ESP_OK; } - esp_err_t handler_capture(httpd_req_t *req) { - #ifdef DEBUG_DETAIL_ON - LogFile.WriteHeapInfo("handler_capture - Start"); - #endif +#ifdef DEBUG_DETAIL_ON + LogFile.WriteHeapInfo("handler_capture - Start"); +#endif - if (Camera.getCameraInitSuccessful()) + if (Camera.getCameraInitSuccessful()) { - int quality; - framesize_t res; - bool zoomEnabled; - int zoomMode; - int zoomOffsetX; - int zoomOffsetY; +#ifdef DEBUG_DETAIL_ON + ESP_LOGD(TAG, "Size: %d, Quality: %d", res, quality); +#endif - Camera.GetCameraParameter(req, quality, res, zoomEnabled, zoomMode, zoomOffsetX, zoomOffsetY); - - #ifdef DEBUG_DETAIL_ON - ESP_LOGD(TAG, "Size: %d, Quality: %d", res, quality); - #endif - - Camera.SetQualitySize(quality, res, zoomEnabled, zoomMode, zoomOffsetX, zoomOffsetY); + // wenn die Kameraeinstellungen durch Erstellen eines neuen Referenzbildes verändert wurden, müssen sie neu gesetzt werden + if (CFstatus.changedCameraSettings) + { + Camera.setSensorDatenFromCCstatus(); // CCstatus >>> Kamera + Camera.SetQualityZoomSize(CCstatus.ImageQuality, CCstatus.ImageFrameSize, CCstatus.ImageZoomEnabled, CCstatus.ImageZoomOffsetX, CCstatus.ImageZoomOffsetY, CCstatus.ImageZoomSize); + CFstatus.changedCameraSettings = false; + } esp_err_t result; result = Camera.CaptureToHTTP(req); - #ifdef DEBUG_DETAIL_ON - LogFile.WriteHeapInfo("handler_capture - Done"); - #endif +#ifdef DEBUG_DETAIL_ON + LogFile.WriteHeapInfo("handler_capture - Done"); +#endif return result; } - else + else { httpd_resp_send_err(req, HTTPD_403_FORBIDDEN, "Camera not initialized: REST API /capture not available!"); return ESP_ERR_NOT_FOUND; } } - esp_err_t handler_capture_with_light(httpd_req_t *req) { - #ifdef DEBUG_DETAIL_ON - LogFile.WriteHeapInfo("handler_capture_with_light - Start"); - #endif - - if (Camera.getCameraInitSuccessful()) +#ifdef DEBUG_DETAIL_ON + LogFile.WriteHeapInfo("handler_capture_with_light - Start"); +#endif + + if (Camera.getCameraInitSuccessful()) { char _query[100]; char _delay[10]; - - int quality; - framesize_t res; - bool zoomEnabled; - int zoomMode; - int zoomOffsetX; - int zoomOffsetY; int delay = 2500; if (httpd_req_get_url_query_str(req, _query, 100) == ESP_OK) { ESP_LOGD(TAG, "Query: %s", _query); + if (httpd_query_key_value(_query, "delay", _delay, 10) == ESP_OK) { - #ifdef DEBUG_DETAIL_ON - ESP_LOGD(TAG, "Delay: %s", _delay); - #endif +#ifdef DEBUG_DETAIL_ON + ESP_LOGD(TAG, "Delay: %s", _delay); +#endif delay = atoi(_delay); if (delay < 0) + { delay = 0; + } } } - Camera.GetCameraParameter(req, quality, res, zoomEnabled, zoomMode, zoomOffsetX, zoomOffsetY); +#ifdef DEBUG_DETAIL_ON + ESP_LOGD(TAG, "Size: %d, Quality: %d", res, quality); +#endif - #ifdef DEBUG_DETAIL_ON - ESP_LOGD(TAG, "Size: %d, Quality: %d", res, quality); - #endif + // wenn die Kameraeinstellungen durch Erstellen eines neuen Referenzbildes verändert wurden, müssen sie neu gesetzt werden + if (CFstatus.changedCameraSettings) + { + Camera.setSensorDatenFromCCstatus(); // CCstatus >>> Kamera + Camera.SetQualityZoomSize(CCstatus.ImageQuality, CCstatus.ImageFrameSize, CCstatus.ImageZoomEnabled, CCstatus.ImageZoomOffsetX, CCstatus.ImageZoomOffsetY, CCstatus.ImageZoomSize); + CFstatus.changedCameraSettings = false; + } - Camera.SetQualitySize(quality, res, zoomEnabled, zoomMode, zoomOffsetX, zoomOffsetY); Camera.LightOnOff(true); const TickType_t xDelay = delay / portTICK_PERIOD_MS; - vTaskDelay( xDelay ); + vTaskDelay(xDelay); esp_err_t result; - result = Camera.CaptureToHTTP(req); + result = Camera.CaptureToHTTP(req); Camera.LightOnOff(false); - #ifdef DEBUG_DETAIL_ON - LogFile.WriteHeapInfo("handler_capture_with_light - Done"); - #endif +#ifdef DEBUG_DETAIL_ON + LogFile.WriteHeapInfo("handler_capture_with_light - Done"); +#endif return result; } - else + else { httpd_resp_send_err(req, HTTPD_403_FORBIDDEN, "Camera not initialized: REST API /capture_with_flashlight not available!"); return ESP_ERR_NOT_FOUND; } } - esp_err_t handler_capture_save_to_file(httpd_req_t *req) { - #ifdef DEBUG_DETAIL_ON - LogFile.WriteHeapInfo("handler_capture_save_to_file - Start"); - #endif +#ifdef DEBUG_DETAIL_ON + LogFile.WriteHeapInfo("handler_capture_save_to_file - Start"); +#endif - if (Camera.getCameraInitSuccessful()) + if (Camera.getCameraInitSuccessful()) { char _query[100]; char _delay[10]; @@ -205,98 +198,102 @@ esp_err_t handler_capture_save_to_file(httpd_req_t *req) char filename[100]; std::string fn = "/sdcard/"; - - int quality; - framesize_t res; - bool zoomEnabled; - int zoomMode; - int zoomOffsetX; - int zoomOffsetY; - if (httpd_req_get_url_query_str(req, _query, 100) == ESP_OK) { ESP_LOGD(TAG, "Query: %s", _query); + if (httpd_query_key_value(_query, "filename", filename, 100) == ESP_OK) { fn.append(filename); - #ifdef DEBUG_DETAIL_ON - ESP_LOGD(TAG, "Filename: %s", fn.c_str()); - #endif +#ifdef DEBUG_DETAIL_ON + ESP_LOGD(TAG, "Filename: %s", fn.c_str()); +#endif } else + { fn.append("noname.jpg"); + } if (httpd_query_key_value(_query, "delay", _delay, 10) == ESP_OK) { - #ifdef DEBUG_DETAIL_ON - ESP_LOGD(TAG, "Delay: %s", _delay); - #endif +#ifdef DEBUG_DETAIL_ON + ESP_LOGD(TAG, "Delay: %s", _delay); +#endif delay = atoi(_delay); if (delay < 0) + { delay = 0; + } } } else + { fn.append("noname.jpg"); + } - Camera.GetCameraParameter(req, quality, res, zoomEnabled, zoomMode, zoomOffsetX, zoomOffsetY); - #ifdef DEBUG_DETAIL_ON - ESP_LOGD(TAG, "Size: %d, Quality: %d", res, quality); - #endif - Camera.SetQualitySize(quality, res, zoomEnabled, zoomMode, zoomOffsetX, zoomOffsetY); +#ifdef DEBUG_DETAIL_ON + ESP_LOGD(TAG, "Size: %d, Quality: %d", res, quality); +#endif + + // wenn die Kameraeinstellungen durch Erstellen eines neuen Referenzbildes verändert wurden, müssen sie neu gesetzt werden + if (CFstatus.changedCameraSettings) + { + Camera.setSensorDatenFromCCstatus(); // CCstatus >>> Kamera + Camera.SetQualityZoomSize(CCstatus.ImageQuality, CCstatus.ImageFrameSize, CCstatus.ImageZoomEnabled, CCstatus.ImageZoomOffsetX, CCstatus.ImageZoomOffsetY, CCstatus.ImageZoomSize); + CFstatus.changedCameraSettings = false; + } esp_err_t result; - result = Camera.CaptureToFile(fn, delay); + result = Camera.CaptureToFile(fn, delay); - const char* resp_str = (const char*) fn.c_str(); + const char *resp_str = (const char *)fn.c_str(); httpd_resp_send(req, resp_str, strlen(resp_str)); - #ifdef DEBUG_DETAIL_ON - LogFile.WriteHeapInfo("handler_capture_save_to_file - Done"); - #endif +#ifdef DEBUG_DETAIL_ON + LogFile.WriteHeapInfo("handler_capture_save_to_file - Done"); +#endif return result; } - else + else { httpd_resp_send_err(req, HTTPD_403_FORBIDDEN, "Camera not initialized: REST API /save not available!"); return ESP_ERR_NOT_FOUND; } } - void register_server_camera_uri(httpd_handle_t server) { -#ifdef DEBUG_DETAIL_ON +#ifdef DEBUG_DETAIL_ON ESP_LOGI(TAG, "server_part_camera - Registering URI handlers"); #endif - httpd_uri_t camuri = { }; - camuri.method = HTTP_GET; + httpd_uri_t camuri = {}; + camuri.method = HTTP_GET; - camuri.uri = "/lighton"; - camuri.handler = handler_lightOn; - camuri.user_ctx = (void*) "Light On"; + camuri.uri = "/lighton"; + camuri.handler = handler_lightOn; + camuri.user_ctx = (void *)"Light On"; httpd_register_uri_handler(server, &camuri); - camuri.uri = "/lightoff"; - camuri.handler = handler_lightOff; - camuri.user_ctx = (void*) "Light Off"; - httpd_register_uri_handler(server, &camuri); + camuri.uri = "/lightoff"; + camuri.handler = handler_lightOff; + camuri.user_ctx = (void *)"Light Off"; + httpd_register_uri_handler(server, &camuri); - camuri.uri = "/capture"; - camuri.handler = handler_capture; - camuri.user_ctx = NULL; - httpd_register_uri_handler(server, &camuri); + camuri.uri = "/capture"; + camuri.handler = handler_capture; + camuri.user_ctx = NULL; + httpd_register_uri_handler(server, &camuri); - camuri.uri = "/capture_with_flashlight"; - camuri.handler = handler_capture_with_light; - camuri.user_ctx = NULL; - httpd_register_uri_handler(server, &camuri); + camuri.uri = "/capture_with_flashlight"; + camuri.handler = handler_capture_with_light; + camuri.user_ctx = NULL; + httpd_register_uri_handler(server, &camuri); - camuri.uri = "/save"; - camuri.handler = handler_capture_save_to_file; - camuri.user_ctx = NULL; - httpd_register_uri_handler(server, &camuri); + camuri.uri = "/save"; + camuri.handler = handler_capture_save_to_file; + camuri.user_ctx = NULL; + httpd_register_uri_handler(server, &camuri); } diff --git a/code/components/jomjol_controlcamera/server_camera.h b/code/components/jomjol_controlcamera/server_camera.h index 7bd79b89..656b99eb 100644 --- a/code/components/jomjol_controlcamera/server_camera.h +++ b/code/components/jomjol_controlcamera/server_camera.h @@ -10,7 +10,6 @@ //#include "ClassControllCamera.h" void register_server_camera_uri(httpd_handle_t server); - void PowerResetCamera(); #endif \ No newline at end of file diff --git a/code/components/jomjol_flowcontroll/ClassFlowAlignment.cpp b/code/components/jomjol_flowcontroll/ClassFlowAlignment.cpp index 235e3df5..c3ab6967 100644 --- a/code/components/jomjol_flowcontroll/ClassFlowAlignment.cpp +++ b/code/components/jomjol_flowcontroll/ClassFlowAlignment.cpp @@ -1,393 +1,402 @@ -#include "ClassFlowAlignment.h" -#include "ClassFlowTakeImage.h" -#include "ClassFlow.h" -#include "MainFlowControl.h" - -#include "CRotateImage.h" -#include "esp_log.h" - - -#include "ClassLogFile.h" -#include "psram.h" -#include "../../include/defines.h" - - -static const char *TAG = "ALIGN"; - -// #define DEBUG_DETAIL_ON - - -void ClassFlowAlignment::SetInitialParameter(void) -{ - initialrotate = 0; - anz_ref = 0; - initialmirror = false; - use_antialiasing = false; - initialflip = false; - SaveAllFiles = false; - namerawimage = "/sdcard/img_tmp/raw.jpg"; - FileStoreRefAlignment = "/sdcard/config/align.txt"; - ListFlowControll = NULL; - AlignAndCutImage = NULL; - ImageBasis = NULL; - ImageTMP = NULL; - #ifdef ALGROI_LOAD_FROM_MEM_AS_JPG - AlgROI = (ImageData*)malloc_psram_heap(std::string(TAG) + "->AlgROI", sizeof(ImageData), MALLOC_CAP_8BIT | MALLOC_CAP_SPIRAM); - #endif - previousElement = NULL; - disabled = false; - SAD_criteria = 0.05; -} - - -ClassFlowAlignment::ClassFlowAlignment(std::vector* lfc) -{ - SetInitialParameter(); - ListFlowControll = lfc; - - for (int i = 0; i < ListFlowControll->size(); ++i) - { - if (((*ListFlowControll)[i])->name().compare("ClassFlowTakeImage") == 0) - { - ImageBasis = ((ClassFlowTakeImage*) (*ListFlowControll)[i])->rawImage; - } - } - - if (!ImageBasis) // the function take pictures does not exist --> must be created first ONLY FOR TEST PURPOSES - { - ESP_LOGD(TAG, "CImageBasis had to be created"); - ImageBasis = new CImageBasis("ImageBasis", namerawimage); - } -} - - -bool ClassFlowAlignment::ReadParameter(FILE* pfile, string& aktparamgraph) -{ - std::vector splitted; - int suchex = 40; - int suchey = 40; - int alg_algo = 0; //default=0; 1 =HIGHACCURACY; 2= FAST; 3= OFF //add disable aligment algo |01.2023 - - - aktparamgraph = trim(aktparamgraph); - - if (aktparamgraph.size() == 0) - if (!this->GetNextParagraph(pfile, aktparamgraph)) - return false; - - if (aktparamgraph.compare("[Alignment]") != 0) //Paragraph does not fit Alignment - return false; - - while (this->getNextLine(pfile, &aktparamgraph) && !this->isNewParagraph(aktparamgraph)) - { - splitted = ZerlegeZeile(aktparamgraph); - if ((toUpper(splitted[0]) == "FLIPIMAGESIZE") && (splitted.size() > 1)) - { - if (toUpper(splitted[1]) == "TRUE") - initialflip = true; - } - if ((toUpper(splitted[0]) == "INITIALMIRROR") && (splitted.size() > 1)) - { - if (toUpper(splitted[1]) == "TRUE") - initialmirror = true; - } - if (((toUpper(splitted[0]) == "initialrotate") || (toUpper(splitted[0]) == "INITIALROTATE")) && (splitted.size() > 1)) - { - this->initialrotate = std::stod(splitted[1]); - } - if ((toUpper(splitted[0]) == "SEARCHFIELDX") && (splitted.size() > 1)) - { - suchex = std::stod(splitted[1]); - } - if ((toUpper(splitted[0]) == "SEARCHFIELDY") && (splitted.size() > 1)) - { - suchey = std::stod(splitted[1]); - } - if ((toUpper(splitted[0]) == "ANTIALIASING") && (splitted.size() > 1)) - { - if (toUpper(splitted[1]) == "TRUE") - use_antialiasing = true; - } - if ((splitted.size() == 3) && (anz_ref < 2)) - { - References[anz_ref].image_file = FormatFileName("/sdcard" + splitted[0]); - References[anz_ref].target_x = std::stod(splitted[1]); - References[anz_ref].target_y = std::stod(splitted[2]); - anz_ref++; - } - - if ((toUpper(splitted[0]) == "SAVEALLFILES") && (splitted.size() > 1)) - { - if (toUpper(splitted[1]) == "TRUE") - SaveAllFiles = true; - } - if ((toUpper(splitted[0]) == "ALIGNMENTALGO") && (splitted.size() > 1)) - { - #ifdef DEBUG_DETAIL_ON - std::string zw2 = "Alignment mode selected: " + splitted[1]; - LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, zw2); - #endif - if (toUpper(splitted[1]) == "HIGHACCURACY") - alg_algo = 1; - if (toUpper(splitted[1]) == "FAST") - alg_algo = 2; - if (toUpper(splitted[1]) == "OFF") //no align algo if set to 3 = off => no draw ref //add disable aligment algo |01.2023 - alg_algo = 3; - } - } - - for (int i = 0; i < anz_ref; ++i) - { - References[i].search_x = suchex; - References[i].search_y = suchey; - References[i].fastalg_SAD_criteria = SAD_criteria; - References[i].alignment_algo = alg_algo; - #ifdef DEBUG_DETAIL_ON - std::string zw2 = "Alignment mode written: " + std::to_string(alg_algo); - LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, zw2); - #endif - } - - //no align algo if set to 3 = off => no draw ref //add disable aligment algo |01.2023 - if(References[0].alignment_algo != 3){ - LoadReferenceAlignmentValues(); - } - - return true; - -} - - -string ClassFlowAlignment::getHTMLSingleStep(string host) -{ - string result; - - result = "

Rotated Image:

\n"; - result = result + "

Found Alignment:

\n"; - result = result + "

Aligned Image:

\n"; - return result; -} - - -bool ClassFlowAlignment::doFlow(string time) -{ - #ifdef ALGROI_LOAD_FROM_MEM_AS_JPG - if (!AlgROI) // AlgROI needs to be allocated before ImageTMP to avoid heap fragmentation - { - AlgROI = (ImageData*)heap_caps_realloc(AlgROI, sizeof(ImageData), MALLOC_CAP_8BIT | MALLOC_CAP_SPIRAM); - if (!AlgROI) - { - LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Can't allocate AlgROI"); - LogFile.WriteHeapInfo("ClassFlowAlignment-doFlow"); - } - } - - if (AlgROI) - { - ImageBasis->writeToMemoryAsJPG((ImageData*)AlgROI, 90); - } - #endif - - if (!ImageTMP) - { - ImageTMP = new CImageBasis("tmpImage", ImageBasis); // Make sure the name does not get change, it is relevant for the PSRAM allocation! - if (!ImageTMP) - { - LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Can't allocate tmpImage -> Exec this round aborted!"); - LogFile.WriteHeapInfo("ClassFlowAlignment-doFlow"); - return false; - } - } - - delete AlignAndCutImage; - AlignAndCutImage = new CAlignAndCutImage("AlignAndCutImage", ImageBasis, ImageTMP); - if (!AlignAndCutImage) - { - LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Can't allocate AlignAndCutImage -> Exec this round aborted!"); - LogFile.WriteHeapInfo("ClassFlowAlignment-doFlow"); - return false; - } - - CRotateImage rt("rawImage", AlignAndCutImage, ImageTMP, initialflip); - if (initialflip) - { - int _zw = ImageBasis->height; - ImageBasis->height = ImageBasis->width; - ImageBasis->width = _zw; - - _zw = ImageTMP->width; - ImageTMP->width = ImageTMP->height; - ImageTMP->height = _zw; - } - - if (initialmirror) - { - ESP_LOGD(TAG, "do mirror"); - rt.Mirror(); - - if (SaveAllFiles) - AlignAndCutImage->SaveToFile(FormatFileName("/sdcard/img_tmp/mirror.jpg")); - } - - if ((initialrotate != 0) || initialflip) - { - if (use_antialiasing) - rt.RotateAntiAliasing(initialrotate); - else - rt.Rotate(initialrotate); - - if (SaveAllFiles) - AlignAndCutImage->SaveToFile(FormatFileName("/sdcard/img_tmp/rot.jpg")); - } - - - //no align algo if set to 3 = off //add disable aligment algo |01.2023 - if(References[0].alignment_algo != 3){ - if (!AlignAndCutImage->Align(&References[0], &References[1])) - { - SaveReferenceAlignmentValues(); - } - }// no align - - - #ifdef ALGROI_LOAD_FROM_MEM_AS_JPG - if (AlgROI) { - //no align algo if set to 3 = off => no draw ref //add disable aligment algo |01.2023 - if(References[0].alignment_algo != 3){ - DrawRef(ImageTMP); - } - flowctrl.DigitalDrawROI(ImageTMP); - flowctrl.AnalogDrawROI(ImageTMP); - ImageTMP->writeToMemoryAsJPG((ImageData*)AlgROI, 90); - } - #endif - - if (SaveAllFiles) - { - AlignAndCutImage->SaveToFile(FormatFileName("/sdcard/img_tmp/alg.jpg")); - ImageTMP->SaveToFile(FormatFileName("/sdcard/img_tmp/alg_roi.jpg")); - } - - // must be deleted to have memory space for loading tflite - delete ImageTMP; - ImageTMP = NULL; - - //no align algo if set to 3 = off => no draw ref //add disable aligment algo |01.2023 - if(References[0].alignment_algo != 3){ - LoadReferenceAlignmentValues(); - } - - return true; -} - - -void ClassFlowAlignment::SaveReferenceAlignmentValues() -{ - FILE* pFile; - std::string zwtime, zwvalue; - - pFile = fopen(FileStoreRefAlignment.c_str(), "w"); - - if (strlen(zwtime.c_str()) == 0) - { - time_t rawtime; - struct tm* timeinfo; - char buffer[80]; - - time(&rawtime); - timeinfo = localtime(&rawtime); - - strftime(buffer, 80, "%Y-%m-%dT%H:%M:%S", timeinfo); - zwtime = std::string(buffer); - } - - fputs(zwtime.c_str(), pFile); - fputs("\n", pFile); - - zwvalue = std::to_string(References[0].fastalg_x) + "\t" + std::to_string(References[0].fastalg_y); - zwvalue = zwvalue + "\t" +std::to_string(References[0].fastalg_SAD)+ "\t" +std::to_string(References[0].fastalg_min); - zwvalue = zwvalue + "\t" +std::to_string(References[0].fastalg_max)+ "\t" +std::to_string(References[0].fastalg_avg); - fputs(zwvalue.c_str(), pFile); - fputs("\n", pFile); - - zwvalue = std::to_string(References[1].fastalg_x) + "\t" + std::to_string(References[1].fastalg_y); - zwvalue = zwvalue + "\t" +std::to_string(References[1].fastalg_SAD)+ "\t" +std::to_string(References[1].fastalg_min); - zwvalue = zwvalue + "\t" +std::to_string(References[1].fastalg_max)+ "\t" +std::to_string(References[1].fastalg_avg); - fputs(zwvalue.c_str(), pFile); - fputs("\n", pFile); - - fclose(pFile); -} - - -bool ClassFlowAlignment::LoadReferenceAlignmentValues(void) -{ - FILE* pFile; - char zw[1024]; - string zwvalue; - std::vector splitted; - - - pFile = fopen(FileStoreRefAlignment.c_str(), "r"); - if (pFile == NULL) - return false; - - fgets(zw, 1024, pFile); - ESP_LOGD(TAG, "%s", zw); - - fgets(zw, 1024, pFile); - splitted = ZerlegeZeile(std::string(zw), " \t"); - if (splitted.size() < 6) - { - fclose(pFile); - return false; - } - - References[0].fastalg_x = stoi(splitted[0]); - References[0].fastalg_y = stoi(splitted[1]); - References[0].fastalg_SAD = stof(splitted[2]); - References[0].fastalg_min = stoi(splitted[3]); - References[0].fastalg_max = stoi(splitted[4]); - References[0].fastalg_avg = stof(splitted[5]); - - fgets(zw, 1024, pFile); - splitted = ZerlegeZeile(std::string(zw)); - if (splitted.size() < 6) - { - fclose(pFile); - return false; - } - - References[1].fastalg_x = stoi(splitted[0]); - References[1].fastalg_y = stoi(splitted[1]); - References[1].fastalg_SAD = stof(splitted[2]); - References[1].fastalg_min = stoi(splitted[3]); - References[1].fastalg_max = stoi(splitted[4]); - References[1].fastalg_avg = stof(splitted[5]); - - fclose(pFile); - - - /*#ifdef DEBUG_DETAIL_ON - std::string _zw = "\tLoadReferences[0]\tx,y:\t" + std::to_string(References[0].fastalg_x) + "\t" + std::to_string(References[0].fastalg_x); - _zw = _zw + "\tSAD, min, max, avg:\t" + std::to_string(References[0].fastalg_SAD) + "\t" + std::to_string(References[0].fastalg_min); - _zw = _zw + "\t" + std::to_string(References[0].fastalg_max) + "\t" + std::to_string(References[0].fastalg_avg); - LogFile.WriteToDedicatedFile("/sdcard/alignment.txt", _zw); - _zw = "\tLoadReferences[1]\tx,y:\t" + std::to_string(References[1].fastalg_x) + "\t" + std::to_string(References[1].fastalg_x); - _zw = _zw + "\tSAD, min, max, avg:\t" + std::to_string(References[1].fastalg_SAD) + "\t" + std::to_string(References[1].fastalg_min); - _zw = _zw + "\t" + std::to_string(References[1].fastalg_max) + "\t" + std::to_string(References[1].fastalg_avg); - LogFile.WriteToDedicatedFile("/sdcard/alignment.txt", _zw); - #endif*/ - - return true; -} - - -void ClassFlowAlignment::DrawRef(CImageBasis *_zw) -{ - if (_zw->ImageOkay()) - { - _zw->drawRect(References[0].target_x, References[0].target_y, References[0].width, References[0].height, 255, 0, 0, 2); - _zw->drawRect(References[1].target_x, References[1].target_y, References[1].width, References[1].height, 255, 0, 0, 2); - } -} +#include "ClassFlowAlignment.h" +#include "ClassFlowTakeImage.h" +#include "ClassFlow.h" +#include "MainFlowControl.h" + +#include "CRotateImage.h" +#include "esp_log.h" + +#include "ClassLogFile.h" +#include "psram.h" +#include "../../include/defines.h" + +static const char *TAG = "ALIGN"; + +// #define DEBUG_DETAIL_ON + +void ClassFlowAlignment::SetInitialParameter(void) +{ + initialrotate = 0; + anz_ref = 0; + use_antialiasing = false; + initialflip = false; + SaveAllFiles = false; + namerawimage = "/sdcard/img_tmp/raw.jpg"; + FileStoreRefAlignment = "/sdcard/config/align.txt"; + ListFlowControll = NULL; + AlignAndCutImage = NULL; + ImageBasis = NULL; + ImageTMP = NULL; +#ifdef ALGROI_LOAD_FROM_MEM_AS_JPG + AlgROI = (ImageData *)malloc_psram_heap(std::string(TAG) + "->AlgROI", sizeof(ImageData), MALLOC_CAP_8BIT | MALLOC_CAP_SPIRAM); +#endif + previousElement = NULL; + disabled = false; + SAD_criteria = 0.05; +} + +ClassFlowAlignment::ClassFlowAlignment(std::vector *lfc) +{ + SetInitialParameter(); + ListFlowControll = lfc; + + for (int i = 0; i < ListFlowControll->size(); ++i) + { + if (((*ListFlowControll)[i])->name().compare("ClassFlowTakeImage") == 0) + { + ImageBasis = ((ClassFlowTakeImage *)(*ListFlowControll)[i])->rawImage; + } + } + + if (!ImageBasis) // the function take pictures does not exist --> must be created first ONLY FOR TEST PURPOSES + { + ESP_LOGD(TAG, "CImageBasis had to be created"); + ImageBasis = new CImageBasis("ImageBasis", namerawimage); + } +} + +bool ClassFlowAlignment::ReadParameter(FILE *pfile, string &aktparamgraph) +{ + std::vector splitted; + int suchex = 40; + int suchey = 40; + int alg_algo = 0; // default=0; 1 =HIGHACCURACY; 2= FAST; 3= OFF //add disable aligment algo |01.2023 + + aktparamgraph = trim(aktparamgraph); + + if (aktparamgraph.size() == 0) + { + if (!this->GetNextParagraph(pfile, aktparamgraph)) + { + return false; + } + } + + if (aktparamgraph.compare("[Alignment]") != 0) + { + // Paragraph does not fit Alignment + return false; + } + + while (this->getNextLine(pfile, &aktparamgraph) && !this->isNewParagraph(aktparamgraph)) + { + splitted = ZerlegeZeile(aktparamgraph); + + if ((toUpper(splitted[0]) == "FLIPIMAGESIZE") && (splitted.size() > 1)) + { + if (toUpper(splitted[1]) == "TRUE") + { + initialflip = true; + } + } + else if (((toUpper(splitted[0]) == "initialrotate") || (toUpper(splitted[0]) == "INITIALROTATE")) && (splitted.size() > 1)) + { + this->initialrotate = std::stod(splitted[1]); + } + else if ((toUpper(splitted[0]) == "SEARCHFIELDX") && (splitted.size() > 1)) + { + suchex = std::stod(splitted[1]); + } + else if ((toUpper(splitted[0]) == "SEARCHFIELDY") && (splitted.size() > 1)) + { + suchey = std::stod(splitted[1]); + } + else if ((toUpper(splitted[0]) == "ANTIALIASING") && (splitted.size() > 1)) + { + if (toUpper(splitted[1]) == "TRUE") + { + use_antialiasing = true; + } + } + else if ((splitted.size() == 3) && (anz_ref < 2)) + { + References[anz_ref].image_file = FormatFileName("/sdcard" + splitted[0]); + References[anz_ref].target_x = std::stod(splitted[1]); + References[anz_ref].target_y = std::stod(splitted[2]); + anz_ref++; + } + + else if ((toUpper(splitted[0]) == "SAVEALLFILES") && (splitted.size() > 1)) + { + if (toUpper(splitted[1]) == "TRUE") + { + SaveAllFiles = true; + } + } + else if ((toUpper(splitted[0]) == "ALIGNMENTALGO") && (splitted.size() > 1)) + { +#ifdef DEBUG_DETAIL_ON + std::string zw2 = "Alignment mode selected: " + splitted[1]; + LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, zw2); +#endif + if (toUpper(splitted[1]) == "HIGHACCURACY") + { + alg_algo = 1; + } + if (toUpper(splitted[1]) == "FAST") + { + alg_algo = 2; + } + if (toUpper(splitted[1]) == "OFF") + { + // no align algo if set to 3 = off => no draw ref //add disable aligment algo |01.2023 + alg_algo = 3; + } + } + } + + for (int i = 0; i < anz_ref; ++i) + { + References[i].search_x = suchex; + References[i].search_y = suchey; + References[i].fastalg_SAD_criteria = SAD_criteria; + References[i].alignment_algo = alg_algo; +#ifdef DEBUG_DETAIL_ON + std::string zw2 = "Alignment mode written: " + std::to_string(alg_algo); + LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, zw2); +#endif + } + + // no align algo if set to 3 = off => no draw ref //add disable aligment algo |01.2023 + if (References[0].alignment_algo != 3) + { + LoadReferenceAlignmentValues(); + } + + return true; +} + +string ClassFlowAlignment::getHTMLSingleStep(string host) +{ + string result; + + result = "

Rotated Image:

\n"; + result = result + "

Found Alignment:

\n"; + result = result + "

Aligned Image:

\n"; + return result; +} + +bool ClassFlowAlignment::doFlow(string time) +{ +#ifdef ALGROI_LOAD_FROM_MEM_AS_JPG + if (!AlgROI) // AlgROI needs to be allocated before ImageTMP to avoid heap fragmentation + { + AlgROI = (ImageData *)heap_caps_realloc(AlgROI, sizeof(ImageData), MALLOC_CAP_8BIT | MALLOC_CAP_SPIRAM); + + if (!AlgROI) + { + LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Can't allocate AlgROI"); + LogFile.WriteHeapInfo("ClassFlowAlignment-doFlow"); + } + } + + if (AlgROI) + { + ImageBasis->writeToMemoryAsJPG((ImageData *)AlgROI, 90); + } +#endif + + if (!ImageTMP) + { + ImageTMP = new CImageBasis("tmpImage", ImageBasis); // Make sure the name does not get change, it is relevant for the PSRAM allocation! + + if (!ImageTMP) + { + LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Can't allocate tmpImage -> Exec this round aborted!"); + LogFile.WriteHeapInfo("ClassFlowAlignment-doFlow"); + return false; + } + } + + delete AlignAndCutImage; + AlignAndCutImage = new CAlignAndCutImage("AlignAndCutImage", ImageBasis, ImageTMP); + + if (!AlignAndCutImage) + { + LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Can't allocate AlignAndCutImage -> Exec this round aborted!"); + LogFile.WriteHeapInfo("ClassFlowAlignment-doFlow"); + return false; + } + + CRotateImage rt("rawImage", AlignAndCutImage, ImageTMP, initialflip); + + if (initialflip) + { + int _zw = ImageBasis->height; + ImageBasis->height = ImageBasis->width; + ImageBasis->width = _zw; + + _zw = ImageTMP->width; + ImageTMP->width = ImageTMP->height; + ImageTMP->height = _zw; + } + + if ((initialrotate != 0) || initialflip) + { + if (use_antialiasing) + { + rt.RotateAntiAliasing(initialrotate); + } + else + { + rt.Rotate(initialrotate); + } + + if (SaveAllFiles) + { + AlignAndCutImage->SaveToFile(FormatFileName("/sdcard/img_tmp/rot.jpg")); + } + } + + // no align algo if set to 3 = off //add disable aligment algo |01.2023 + if (References[0].alignment_algo != 3) + { + if (!AlignAndCutImage->Align(&References[0], &References[1])) + { + SaveReferenceAlignmentValues(); + } + } // no align + +#ifdef ALGROI_LOAD_FROM_MEM_AS_JPG + if (AlgROI) + { + // no align algo if set to 3 = off => no draw ref //add disable aligment algo |01.2023 + if (References[0].alignment_algo != 3) + { + DrawRef(ImageTMP); + } + + flowctrl.DigitalDrawROI(ImageTMP); + flowctrl.AnalogDrawROI(ImageTMP); + ImageTMP->writeToMemoryAsJPG((ImageData *)AlgROI, 90); + } +#endif + + if (SaveAllFiles) + { + AlignAndCutImage->SaveToFile(FormatFileName("/sdcard/img_tmp/alg.jpg")); + ImageTMP->SaveToFile(FormatFileName("/sdcard/img_tmp/alg_roi.jpg")); + } + + // must be deleted to have memory space for loading tflite + delete ImageTMP; + ImageTMP = NULL; + + // no align algo if set to 3 = off => no draw ref //add disable aligment algo |01.2023 + if (References[0].alignment_algo != 3) + { + LoadReferenceAlignmentValues(); + } + + return true; +} + +void ClassFlowAlignment::SaveReferenceAlignmentValues() +{ + FILE *pFile; + std::string zwtime, zwvalue; + + pFile = fopen(FileStoreRefAlignment.c_str(), "w"); + + if (strlen(zwtime.c_str()) == 0) + { + time_t rawtime; + struct tm *timeinfo; + char buffer[80]; + + time(&rawtime); + timeinfo = localtime(&rawtime); + + strftime(buffer, 80, "%Y-%m-%dT%H:%M:%S", timeinfo); + zwtime = std::string(buffer); + } + + fputs(zwtime.c_str(), pFile); + fputs("\n", pFile); + + zwvalue = std::to_string(References[0].fastalg_x) + "\t" + std::to_string(References[0].fastalg_y); + zwvalue = zwvalue + "\t" + std::to_string(References[0].fastalg_SAD) + "\t" + std::to_string(References[0].fastalg_min); + zwvalue = zwvalue + "\t" + std::to_string(References[0].fastalg_max) + "\t" + std::to_string(References[0].fastalg_avg); + fputs(zwvalue.c_str(), pFile); + fputs("\n", pFile); + + zwvalue = std::to_string(References[1].fastalg_x) + "\t" + std::to_string(References[1].fastalg_y); + zwvalue = zwvalue + "\t" + std::to_string(References[1].fastalg_SAD) + "\t" + std::to_string(References[1].fastalg_min); + zwvalue = zwvalue + "\t" + std::to_string(References[1].fastalg_max) + "\t" + std::to_string(References[1].fastalg_avg); + fputs(zwvalue.c_str(), pFile); + fputs("\n", pFile); + + fclose(pFile); +} + +bool ClassFlowAlignment::LoadReferenceAlignmentValues(void) +{ + FILE *pFile; + char zw[1024]; + string zwvalue; + std::vector splitted; + + pFile = fopen(FileStoreRefAlignment.c_str(), "r"); + + if (pFile == NULL) + return false; + + fgets(zw, 1024, pFile); + ESP_LOGD(TAG, "%s", zw); + + fgets(zw, 1024, pFile); + splitted = ZerlegeZeile(std::string(zw), " \t"); + + if (splitted.size() < 6) + { + fclose(pFile); + return false; + } + + References[0].fastalg_x = stoi(splitted[0]); + References[0].fastalg_y = stoi(splitted[1]); + References[0].fastalg_SAD = stof(splitted[2]); + References[0].fastalg_min = stoi(splitted[3]); + References[0].fastalg_max = stoi(splitted[4]); + References[0].fastalg_avg = stof(splitted[5]); + + fgets(zw, 1024, pFile); + splitted = ZerlegeZeile(std::string(zw)); + + if (splitted.size() < 6) + { + fclose(pFile); + return false; + } + + References[1].fastalg_x = stoi(splitted[0]); + References[1].fastalg_y = stoi(splitted[1]); + References[1].fastalg_SAD = stof(splitted[2]); + References[1].fastalg_min = stoi(splitted[3]); + References[1].fastalg_max = stoi(splitted[4]); + References[1].fastalg_avg = stof(splitted[5]); + + fclose(pFile); + + /*#ifdef DEBUG_DETAIL_ON + std::string _zw = "\tLoadReferences[0]\tx,y:\t" + std::to_string(References[0].fastalg_x) + "\t" + std::to_string(References[0].fastalg_x); + _zw = _zw + "\tSAD, min, max, avg:\t" + std::to_string(References[0].fastalg_SAD) + "\t" + std::to_string(References[0].fastalg_min); + _zw = _zw + "\t" + std::to_string(References[0].fastalg_max) + "\t" + std::to_string(References[0].fastalg_avg); + LogFile.WriteToDedicatedFile("/sdcard/alignment.txt", _zw); + _zw = "\tLoadReferences[1]\tx,y:\t" + std::to_string(References[1].fastalg_x) + "\t" + std::to_string(References[1].fastalg_x); + _zw = _zw + "\tSAD, min, max, avg:\t" + std::to_string(References[1].fastalg_SAD) + "\t" + std::to_string(References[1].fastalg_min); + _zw = _zw + "\t" + std::to_string(References[1].fastalg_max) + "\t" + std::to_string(References[1].fastalg_avg); + LogFile.WriteToDedicatedFile("/sdcard/alignment.txt", _zw); + #endif*/ + + return true; +} + +void ClassFlowAlignment::DrawRef(CImageBasis *_zw) +{ + if (_zw->ImageOkay()) + { + _zw->drawRect(References[0].target_x, References[0].target_y, References[0].width, References[0].height, 255, 0, 0, 2); + _zw->drawRect(References[1].target_x, References[1].target_y, References[1].width, References[1].height, 255, 0, 0, 2); + } +} diff --git a/code/components/jomjol_flowcontroll/ClassFlowAlignment.h b/code/components/jomjol_flowcontroll/ClassFlowAlignment.h index e7a1591f..2d0944cb 100644 --- a/code/components/jomjol_flowcontroll/ClassFlowAlignment.h +++ b/code/components/jomjol_flowcontroll/ClassFlowAlignment.h @@ -1,54 +1,51 @@ -#pragma once - -#ifndef CLASSFLOWALIGNMENT_H -#define CLASSFLOWALIGNMENT_H - -#include "ClassFlow.h" -#include "Helper.h" -#include "CAlignAndCutImage.h" -#include "CFindTemplate.h" - -#include - -using namespace std; - -class ClassFlowAlignment : - public ClassFlow -{ -protected: - float initialrotate; - bool initialmirror; - bool initialflip; - bool use_antialiasing; - RefInfo References[2]; - int anz_ref; - string namerawimage; - bool SaveAllFiles; - CAlignAndCutImage *AlignAndCutImage; - std::string FileStoreRefAlignment; - float SAD_criteria; - - void SetInitialParameter(void); - bool LoadReferenceAlignmentValues(void); - void SaveReferenceAlignmentValues(); - -public: - CImageBasis *ImageBasis, *ImageTMP; - #ifdef ALGROI_LOAD_FROM_MEM_AS_JPG - ImageData *AlgROI; - #endif - - ClassFlowAlignment(std::vector* lfc); - - CAlignAndCutImage* GetAlignAndCutImage(){return AlignAndCutImage;}; - - void DrawRef(CImageBasis *_zw); - - bool ReadParameter(FILE* pfile, string& aktparamgraph); - bool doFlow(string time); - string getHTMLSingleStep(string host); - string name(){return "ClassFlowAlignment";}; -}; - - -#endif //CLASSFLOWALIGNMENT_H +#pragma once + +#ifndef CLASSFLOWALIGNMENT_H +#define CLASSFLOWALIGNMENT_H + +#include "ClassFlow.h" +#include "Helper.h" +#include "CAlignAndCutImage.h" +#include "CFindTemplate.h" + +#include + +using namespace std; + +class ClassFlowAlignment : public ClassFlow +{ +protected: + float initialrotate; + bool initialflip; + bool use_antialiasing; + RefInfo References[2]; + int anz_ref; + string namerawimage; + bool SaveAllFiles; + CAlignAndCutImage *AlignAndCutImage; + std::string FileStoreRefAlignment; + float SAD_criteria; + + void SetInitialParameter(void); + bool LoadReferenceAlignmentValues(void); + void SaveReferenceAlignmentValues(); + +public: + CImageBasis *ImageBasis, *ImageTMP; +#ifdef ALGROI_LOAD_FROM_MEM_AS_JPG + ImageData *AlgROI; +#endif + + ClassFlowAlignment(std::vector *lfc); + + CAlignAndCutImage *GetAlignAndCutImage() { return AlignAndCutImage; }; + + void DrawRef(CImageBasis *_zw); + + bool ReadParameter(FILE *pfile, string &aktparamgraph); + bool doFlow(string time); + string getHTMLSingleStep(string host); + string name() { return "ClassFlowAlignment"; }; +}; + +#endif // CLASSFLOWALIGNMENT_H diff --git a/code/components/jomjol_flowcontroll/ClassFlowTakeImage.cpp b/code/components/jomjol_flowcontroll/ClassFlowTakeImage.cpp index 5d6d9ed7..999296b1 100644 --- a/code/components/jomjol_flowcontroll/ClassFlowTakeImage.cpp +++ b/code/components/jomjol_flowcontroll/ClassFlowTakeImage.cpp @@ -1,9 +1,15 @@ +#include +#include +#include +#include + #include "ClassFlowTakeImage.h" #include "Helper.h" #include "ClassLogFile.h" #include "CImageBasis.h" #include "ClassControllCamera.h" +#include "MainFlowControl.h" #include "esp_wifi.h" #include "esp_log.h" @@ -12,14 +18,14 @@ #include -// #define DEBUG_DETAIL_ON - +// #define DEBUG_DETAIL_ON // #define WIFITURNOFF -static const char* TAG = "TAKEIMAGE"; +static const char *TAG = "TAKEIMAGE"; -esp_err_t ClassFlowTakeImage::camera_capture(){ - string nm = namerawimage; +esp_err_t ClassFlowTakeImage::camera_capture(void) +{ + string nm = namerawimage; Camera.CaptureToFile(nm); time(&TimeImageTaken); localtime(&TimeImageTaken); @@ -30,205 +36,480 @@ esp_err_t ClassFlowTakeImage::camera_capture(){ void ClassFlowTakeImage::takePictureWithFlash(int flash_duration) { // in case the image is flipped, it must be reset here // - rawImage->width = image_width; - rawImage->height = image_height; - ///////////////////////////////////////////////////////////////////////////////////// + rawImage->width = CCstatus.ImageWidth; + rawImage->height = CCstatus.ImageHeight; + ESP_LOGD(TAG, "flash_duration: %d", flash_duration); + Camera.CaptureToBasisImage(rawImage, flash_duration); + time(&TimeImageTaken); localtime(&TimeImageTaken); - if (SaveAllFiles) rawImage->SaveToFile(namerawimage); + if (CCstatus.SaveAllFiles) + { + rawImage->SaveToFile(namerawimage); + } } void ClassFlowTakeImage::SetInitialParameter(void) { - waitbeforepicture = 5; - isImageSize = false; - ImageQuality = -1; TimeImageTaken = 0; - ImageQuality = 5; rawImage = NULL; - ImageSize = FRAMESIZE_VGA; - ZoomEnabled = false; - ZoomMode = 0; - zoomOffsetX = 0; - zoomOffsetY = 0; - ImageNegative = false; - ImageAec2 = false; -#ifdef GRAYSCALE_AS_DEFAULT - ImageGrayscale = true; -#else - ImageGrayscale = false; -#endif - SaveAllFiles = false; disabled = false; - FixedExposure = false; namerawimage = "/sdcard/img_tmp/raw.jpg"; -} +} +// auslesen der Kameraeinstellungen aus der config.ini +// wird beim Start aufgerufen +bool ClassFlowTakeImage::ReadParameter(FILE *pfile, string &aktparamgraph) +{ + Camera.getSensorDatenToCCstatus(); // Kamera >>> CCstatus -ClassFlowTakeImage::ClassFlowTakeImage(std::vector* lfc) : ClassFlowImage(lfc, TAG) + std::vector splitted; + + aktparamgraph = trim(aktparamgraph); + + if (aktparamgraph.size() == 0) + { + if (!this->GetNextParagraph(pfile, aktparamgraph)) + { + return false; + } + } + + if (aktparamgraph.compare("[TakeImage]") != 0) + { + // Paragraph does not fit TakeImage + return false; + } + + while (this->getNextLine(pfile, &aktparamgraph) && !this->isNewParagraph(aktparamgraph)) + { + splitted = ZerlegeZeile(aktparamgraph); + + if ((toUpper(splitted[0]) == "RAWIMAGESLOCATION") && (splitted.size() > 1)) + { + imagesLocation = "/sdcard" + splitted[1]; + isLogImage = true; + } + + else if ((toUpper(splitted[0]) == "RAWIMAGESRETENTION") && (splitted.size() > 1)) + { + this->imagesRetention = std::stod(splitted[1]); + } + + else if ((toUpper(splitted[0]) == "SAVEALLFILES") && (splitted.size() > 1)) + { + if (toUpper(splitted[1]) == "TRUE") + { + CCstatus.SaveAllFiles = 1; + } + else + { + CCstatus.SaveAllFiles = 0; + } + } + + else if ((toUpper(splitted[0]) == "WAITBEFORETAKINGPICTURE") && (splitted.size() > 1)) + { + int _WaitBeforePicture = std::stoi(splitted[1]); + if (_WaitBeforePicture != 0) + { + CCstatus.WaitBeforePicture = _WaitBeforePicture; + } + else + { + CCstatus.WaitBeforePicture = 2; + } + } + + else if ((toUpper(splitted[0]) == "CAMGAINCEILING") && (splitted.size() > 1)) + { + std::string _ImageGainceiling = toUpper(splitted[1]); + if (_ImageGainceiling == "X4") + { + CCstatus.ImageGainceiling = GAINCEILING_4X; + } + else if (_ImageGainceiling == "X8") + { + CCstatus.ImageGainceiling = GAINCEILING_8X; + } + else if (_ImageGainceiling == "X16") + { + CCstatus.ImageGainceiling = GAINCEILING_16X; + } + else if (_ImageGainceiling == "X32") + { + CCstatus.ImageGainceiling = GAINCEILING_32X; + } + else if (_ImageGainceiling == "X64") + { + CCstatus.ImageGainceiling = GAINCEILING_64X; + } + else if (_ImageGainceiling == "X128") + { + CCstatus.ImageGainceiling = GAINCEILING_128X; + } + else + { + CCstatus.ImageGainceiling = GAINCEILING_2X; + } + } + + else if ((toUpper(splitted[0]) == "CAMQUALITY") && (splitted.size() > 1)) + { + int _ImageQuality = std::stoi(splitted[1]); + if ((_ImageQuality >= 0) && (_ImageQuality <= 63)) + { + CCstatus.ImageQuality = _ImageQuality; + } + } + + else if ((toUpper(splitted[0]) == "CAMBRIGHTNESS") && (splitted.size() > 1)) + { + int _ImageBrightness = std::stoi(splitted[1]); + if ((_ImageBrightness >= -2) && (_ImageBrightness <= 2)) + { + CCstatus.ImageBrightness = _ImageBrightness; + } + } + + else if ((toUpper(splitted[0]) == "CAMCONTRAST") && (splitted.size() > 1)) + { + int _ImageContrast = std::stoi(splitted[1]); + if ((_ImageContrast >= -2) && (_ImageContrast <= 2)) + { + CCstatus.ImageContrast = _ImageContrast; + } + } + + else if ((toUpper(splitted[0]) == "CAMSATURATION") && (splitted.size() > 1)) + { + int _ImageSaturation = std::stoi(splitted[1]); + if ((_ImageSaturation >= -2) && (_ImageSaturation <= 2)) + { + CCstatus.ImageSaturation = _ImageSaturation; + } + } + + else if ((toUpper(splitted[0]) == "CAMSHARPNESS") && (splitted.size() > 1)) + { + int _ImageSharpness = std::stoi(splitted[1]); + if ((_ImageSharpness >= -2) && (_ImageSharpness <= 2)) + { + CCstatus.ImageSharpness = _ImageSharpness; + } + } + + else if ((toUpper(splitted[0]) == "CAMAUTOSHARPNESS") && (splitted.size() > 1)) + { + if (toUpper(splitted[1]) == "TRUE") + { + CCstatus.ImageAutoSharpness = 1; + } + else + { + CCstatus.ImageAutoSharpness = 0; + } + } + + else if ((toUpper(splitted[0]) == "CAMSPECIALEFFECT") && (splitted.size() > 1)) + { + std::string _ImageSpecialEffect = toUpper(splitted[1]); + if (_ImageSpecialEffect == "NEGATIVE") + { + CCstatus.ImageSpecialEffect = 1; + } + else if (_ImageSpecialEffect == "GRAYSCALE") + { + CCstatus.ImageSpecialEffect = 2; + } + else if (_ImageSpecialEffect == "RED") + { + CCstatus.ImageSpecialEffect = 3; + } + else if (_ImageSpecialEffect == "GREEN") + { + CCstatus.ImageSpecialEffect = 4; + } + else if (_ImageSpecialEffect == "BLUE") + { + CCstatus.ImageSpecialEffect = 5; + } + else if (_ImageSpecialEffect == "RETRO") + { + CCstatus.ImageSpecialEffect = 6; + } + else + { + CCstatus.ImageSpecialEffect = 0; + } + } + + else if ((toUpper(splitted[0]) == "CAMWBMODE") && (splitted.size() > 1)) + { + std::string _ImageWbMode = toUpper(splitted[1]); + if (_ImageWbMode == "SUNNY") + { + CCstatus.ImageWbMode = 1; + } + else if (_ImageWbMode == "CLOUDY") + { + CCstatus.ImageWbMode = 2; + } + else if (_ImageWbMode == "OFFICE") + { + CCstatus.ImageWbMode = 3; + } + else if (_ImageWbMode == "HOME") + { + CCstatus.ImageWbMode = 4; + } + else + { + CCstatus.ImageWbMode = 0; + } + } + + else if ((toUpper(splitted[0]) == "CAMAWB") && (splitted.size() > 1)) + { + if (toUpper(splitted[1]) == "TRUE") + { + CCstatus.ImageAwb = 1; + } + else + { + CCstatus.ImageAwb = 0; + } + } + + else if ((toUpper(splitted[0]) == "CAMAWBGAIN") && (splitted.size() > 1)) + { + if (toUpper(splitted[1]) == "TRUE") + { + CCstatus.ImageAwbGain = 1; + } + else + { + CCstatus.ImageAwbGain = 0; + } + } + + else if ((toUpper(splitted[0]) == "CAMAEC") && (splitted.size() > 1)) + { + if (toUpper(splitted[1]) == "TRUE") + { + CCstatus.ImageAec = 1; + } + else + { + CCstatus.ImageAec = 0; + } + } + + else if ((toUpper(splitted[0]) == "CAMAEC2") && (splitted.size() > 1)) + { + if (toUpper(splitted[1]) == "TRUE") + { + CCstatus.ImageAec2 = 1; + } + else + { + CCstatus.ImageAec2 = 0; + } + } + + else if ((toUpper(splitted[0]) == "CAMAELEVEL") && (splitted.size() > 1)) + { + int _ImageAeLevel = std::stoi(splitted[1]); + if ((_ImageAeLevel >= -2) && (_ImageAeLevel <= 2)) + { + CCstatus.ImageAeLevel = _ImageAeLevel; + } + } + + else if ((toUpper(splitted[0]) == "CAMAECVALUE") && (splitted.size() > 1)) + { + int _ImageAecValue = std::stoi(splitted[1]); + if ((_ImageAecValue >= 0) && (_ImageAecValue <= 1200)) + { + CCstatus.ImageAecValue = _ImageAecValue; + } + } + + else if ((toUpper(splitted[0]) == "CAMAGC") && (splitted.size() > 1)) + { + if (toUpper(splitted[1]) == "TRUE") + { + CCstatus.ImageAgc = 1; + } + else + { + CCstatus.ImageAgc = 0; + } + } + + else if ((toUpper(splitted[0]) == "CAMAGCGAIN") && (splitted.size() > 1)) + { + int _ImageAgcGain = std::stoi(splitted[1]); + if ((_ImageAgcGain >= 0) && (_ImageAgcGain <= 30)) + { + CCstatus.ImageAgcGain = _ImageAgcGain; + } + } + + else if ((toUpper(splitted[0]) == "CAMBPC") && (splitted.size() > 1)) + { + if (toUpper(splitted[1]) == "TRUE") + { + CCstatus.ImageBpc = 1; + } + else + { + CCstatus.ImageBpc = 0; + } + } + + else if ((toUpper(splitted[0]) == "CAMWPC") && (splitted.size() > 1)) + { + if (toUpper(splitted[1]) == "TRUE") + { + CCstatus.ImageWpc = 1; + } + else + { + CCstatus.ImageWpc = 0; + } + } + + else if ((toUpper(splitted[0]) == "CAMRAWGMA") && (splitted.size() > 1)) + { + if (toUpper(splitted[1]) == "TRUE") + { + CCstatus.ImageRawGma = 1; + } + else + { + CCstatus.ImageRawGma = 0; + } + } + + else if ((toUpper(splitted[0]) == "CAMLENC") && (splitted.size() > 1)) + { + if (toUpper(splitted[1]) == "TRUE") + { + CCstatus.ImageLenc = 1; + } + else + { + CCstatus.ImageLenc = 0; + } + } + + else if ((toUpper(splitted[0]) == "CAMHMIRROR") && (splitted.size() > 1)) + { + if (toUpper(splitted[1]) == "TRUE") + { + CCstatus.ImageHmirror = 1; + } + else + { + CCstatus.ImageHmirror = 0; + } + } + + else if ((toUpper(splitted[0]) == "CAMVFLIP") && (splitted.size() > 1)) + { + if (toUpper(splitted[1]) == "TRUE") + { + CCstatus.ImageVflip = 1; + } + else + { + CCstatus.ImageVflip = 0; + } + } + + else if ((toUpper(splitted[0]) == "CAMDCW") && (splitted.size() > 1)) + { + if (toUpper(splitted[1]) == "TRUE") + { + CCstatus.ImageDcw = 1; + } + else + { + CCstatus.ImageDcw = 0; + } + } + + else if ((toUpper(splitted[0]) == "CAMZOOM") && (splitted.size() > 1)) + { + if (toUpper(splitted[1]) == "TRUE") + { + CCstatus.ImageZoomEnabled = 1; + } + else + { + CCstatus.ImageZoomEnabled = 0; + } + } + + else if ((toUpper(splitted[0]) == "CAMZOOMOFFSETX") && (splitted.size() > 1)) + { + CCstatus.ImageZoomOffsetX = std::stoi(splitted[1]); + } + + else if ((toUpper(splitted[0]) == "CAMZOOMOFFSETY") && (splitted.size() > 1)) + { + CCstatus.ImageZoomOffsetY = std::stoi(splitted[1]); + } + + else if ((toUpper(splitted[0]) == "CAMZOOMSIZE") && (splitted.size() > 1)) + { + int _ImageZoomSize = std::stoi(splitted[1]); + if (_ImageZoomSize >= 0) + { + CCstatus.ImageZoomSize = _ImageZoomSize; + } + } + + else if ((toUpper(splitted[0]) == "LEDINTENSITY") && (splitted.size() > 1)) + { + float ledintensity = std::stof(splitted[1]); + Camera.SetLEDIntensity(ledintensity); + } + + else if ((toUpper(splitted[0]) == "DEMO") && (splitted.size() > 1)) + { + if (toUpper(splitted[1]) == "TRUE") + { + CCstatus.DemoMode = true; + Camera.useDemoMode(); + } + else + { + CCstatus.DemoMode = false; + } + } + } + + Camera.setSensorDatenFromCCstatus(); // CCstatus >>> Kamera + Camera.SetQualityZoomSize(CCstatus.ImageQuality, CCstatus.ImageFrameSize, CCstatus.ImageZoomEnabled, CCstatus.ImageZoomOffsetX, CCstatus.ImageZoomOffsetY, CCstatus.ImageZoomSize); + + rawImage = new CImageBasis("rawImage"); + rawImage->CreateEmptyImage(CCstatus.ImageWidth, CCstatus.ImageHeight, 3); + + return true; +} + +ClassFlowTakeImage::ClassFlowTakeImage(std::vector *lfc) : ClassFlowImage(lfc, TAG) { imagesLocation = "/log/source"; imagesRetention = 5; SetInitialParameter(); } - -bool ClassFlowTakeImage::ReadParameter(FILE* pfile, string& aktparamgraph) -{ - std::vector splitted; - - aktparamgraph = trim(aktparamgraph); - int _brightness = 0; - int _contrast = 0; - int _saturation = 0; - int _sharpness = 0; - int _autoExposureLevel = 0; - - if (aktparamgraph.size() == 0) - if (!this->GetNextParagraph(pfile, aktparamgraph)) - return false; - - if (aktparamgraph.compare("[TakeImage]") != 0) // Paragraph does not fit TakeImage - return false; - - while (this->getNextLine(pfile, &aktparamgraph) && !this->isNewParagraph(aktparamgraph)) - { - splitted = ZerlegeZeile(aktparamgraph); - if ((toUpper(splitted[0]) == "RAWIMAGESLOCATION") && (splitted.size() > 1)) - { - imagesLocation = "/sdcard" + splitted[1]; - isLogImage = true; - } - if ((toUpper(splitted[0]) == "IMAGEQUALITY") && (splitted.size() > 1)) - ImageQuality = std::stod(splitted[1]); - - if ((toUpper(splitted[0]) == "ZOOM") && (splitted.size() > 1)) - { - if (toUpper(splitted[1]) == "TRUE") - ZoomEnabled = true; - else if (toUpper(splitted[1]) == "FALSE") - ZoomEnabled = false; - } - if ((toUpper(splitted[0]) == "ZOOMMODE") && (splitted.size() > 1)) - ZoomMode = std::stod(splitted[1]); - if ((toUpper(splitted[0]) == "ZOOMOFFSETX") && (splitted.size() > 1)) - zoomOffsetX = std::stod(splitted[1]); - if ((toUpper(splitted[0]) == "ZOOMOFFSETY") && (splitted.size() > 1)) - zoomOffsetY = std::stod(splitted[1]); - if ((toUpper(splitted[0]) == "GRAYSCALE") && (splitted.size() > 1)) - { - if (toUpper(splitted[1]) == "TRUE") - ImageGrayscale = true; - else if (toUpper(splitted[1]) == "FALSE") - ImageGrayscale = false; - } - if ((toUpper(splitted[0]) == "NEGATIVE") && (splitted.size() > 1)) - { - if (toUpper(splitted[1]) == "TRUE") - ImageNegative = true; - else if (toUpper(splitted[1]) == "FALSE") - ImageNegative = false; - } - if ((toUpper(splitted[0]) == "AEC2") && (splitted.size() > 1)) - { - if (toUpper(splitted[1]) == "TRUE") - ImageAec2 = true; - else if (toUpper(splitted[1]) == "FALSE") - ImageAec2 = false; - } - if ((toUpper(splitted[0]) == "AUTOEXPOSURELEVEL") && (splitted.size() > 1)) - _autoExposureLevel = std::stod(splitted[1]); - - if ((toUpper(splitted[0]) == "IMAGESIZE") && (splitted.size() > 1)) - { - ImageSize = Camera.TextToFramesize(splitted[1].c_str()); - isImageSize = true; - } - - if ((toUpper(splitted[0]) == "SAVEALLFILES") && (splitted.size() > 1)) - { - if (toUpper(splitted[1]) == "TRUE") - SaveAllFiles = true; - } - - if ((toUpper(splitted[0]) == "WAITBEFORETAKINGPICTURE") && (splitted.size() > 1)) - { - waitbeforepicture = stoi(splitted[1]); - } - - if ((toUpper(splitted[0]) == "RAWIMAGESRETENTION") && (splitted.size() > 1)) - { - this->imagesRetention = std::stoi(splitted[1]); - } - - if ((toUpper(splitted[0]) == "BRIGHTNESS") && (splitted.size() > 1)) - { - _brightness = stoi(splitted[1]); - } - - if ((toUpper(splitted[0]) == "CONTRAST") && (splitted.size() > 1)) - { - _contrast = stoi(splitted[1]); - } - - if ((toUpper(splitted[0]) == "SATURATION") && (splitted.size() > 1)) - { - _saturation = stoi(splitted[1]); - } - - if ((toUpper(splitted[0]) == "SHARPNESS") && (splitted.size() > 1)) - { - _sharpness = stoi(splitted[1]); - } - - if ((toUpper(splitted[0]) == "FIXEDEXPOSURE") && (splitted.size() > 1)) - { - if (toUpper(splitted[1]) == "TRUE") - FixedExposure = true; - } - - if ((toUpper(splitted[0]) == "LEDINTENSITY") && (splitted.size() > 1)) - { - float ledintensity = stof(splitted[1]); - ledintensity = min((float) 100, ledintensity); - ledintensity = max((float) 0, ledintensity); - Camera.SetLEDIntensity(ledintensity); - } - - if ((toUpper(splitted[0]) == "DEMO") && (splitted.size() > 1)) - { - if (toUpper(splitted[1]) == "TRUE") - Camera.useDemoMode(); - } - } - - Camera.SetBrightnessContrastSaturation(_brightness, _contrast, _saturation, _autoExposureLevel, ImageGrayscale, ImageNegative, ImageAec2, _sharpness); - Camera.SetQualitySize(ImageQuality, ImageSize, ZoomEnabled, ZoomMode, zoomOffsetX, zoomOffsetY); - - image_width = Camera.image_width; - image_height = Camera.image_height; - rawImage = new CImageBasis("rawImage"); - rawImage->CreateEmptyImage(image_width, image_height, 3); - - waitbeforepicture_store = waitbeforepicture; - if (FixedExposure && (waitbeforepicture > 0)) - { -// ESP_LOGD(TAG, "Fixed Exposure enabled!"); - int flash_duration = (int) (waitbeforepicture * 1000); - Camera.EnableAutoExposure(flash_duration); - waitbeforepicture = 0.2; -// flash_duration = (int) (waitbeforepicture * 1000); -// takePictureWithFlash(flash_duration); -// rawImage->SaveToFile("/sdcard/init2.jpg"); - } - - return true; -} - - string ClassFlowTakeImage::getHTMLSingleStep(string host) { string result; @@ -236,74 +517,78 @@ string ClassFlowTakeImage::getHTMLSingleStep(string host) return result; } - +// wird bei jeder Auswertrunde aufgerufen bool ClassFlowTakeImage::doFlow(string zwtime) { psram_init_shared_memory_for_take_image_step(); string logPath = CreateLogFolder(zwtime); - int flash_duration = (int) (waitbeforepicture * 1000); - - #ifdef DEBUG_DETAIL_ON - LogFile.WriteHeapInfo("ClassFlowTakeImage::doFlow - Before takePictureWithFlash"); - #endif + int flash_duration = (int)(CCstatus.WaitBeforePicture * 1000); +#ifdef DEBUG_DETAIL_ON + LogFile.WriteHeapInfo("ClassFlowTakeImage::doFlow - Before takePictureWithFlash"); +#endif - #ifdef WIFITURNOFF - esp_wifi_stop(); // to save power usage and - #endif +#ifdef WIFITURNOFF + esp_wifi_stop(); // to save power usage and +#endif + + // wenn die Kameraeinstellungen durch Erstellen eines neuen Referenzbildes verändert wurden, müssen sie neu gesetzt werden + if (CFstatus.changedCameraSettings) + { + Camera.setSensorDatenFromCCstatus(); // CCstatus >>> Kamera + Camera.SetQualityZoomSize(CCstatus.ImageQuality, CCstatus.ImageFrameSize, CCstatus.ImageZoomEnabled, CCstatus.ImageZoomOffsetX, CCstatus.ImageZoomOffsetY, CCstatus.ImageZoomSize); + CFstatus.changedCameraSettings = false; + } takePictureWithFlash(flash_duration); - #ifdef WIFITURNOFF - esp_wifi_start(); - #endif +#ifdef WIFITURNOFF + esp_wifi_start(); +#endif - - #ifdef DEBUG_DETAIL_ON - LogFile.WriteHeapInfo("ClassFlowTakeImage::doFlow - After takePictureWithFlash"); - #endif +#ifdef DEBUG_DETAIL_ON + LogFile.WriteHeapInfo("ClassFlowTakeImage::doFlow - After takePictureWithFlash"); +#endif LogImage(logPath, "raw", NULL, NULL, zwtime, rawImage); RemoveOldLogs(); - #ifdef DEBUG_DETAIL_ON - LogFile.WriteHeapInfo("ClassFlowTakeImage::doFlow - After RemoveOldLogs"); - #endif +#ifdef DEBUG_DETAIL_ON + LogFile.WriteHeapInfo("ClassFlowTakeImage::doFlow - After RemoveOldLogs"); +#endif psram_deinit_shared_memory_for_take_image_step(); return true; } - esp_err_t ClassFlowTakeImage::SendRawJPG(httpd_req_t *req) { - int flash_duration = (int) (waitbeforepicture * 1000); + int flash_duration = (int)(CCstatus.WaitBeforePicture * 1000); time(&TimeImageTaken); localtime(&TimeImageTaken); return Camera.CaptureToHTTP(req, flash_duration); } - -ImageData* ClassFlowTakeImage::SendRawImage() +ImageData *ClassFlowTakeImage::SendRawImage(void) { CImageBasis *zw = new CImageBasis("SendRawImage", rawImage); ImageData *id; - int flash_duration = (int) (waitbeforepicture * 1000); + int flash_duration = (int)(CCstatus.WaitBeforePicture * 1000); Camera.CaptureToBasisImage(zw, flash_duration); time(&TimeImageTaken); localtime(&TimeImageTaken); - id = zw->writeToMemoryAsJPG(); + id = zw->writeToMemoryAsJPG(); delete zw; - return id; + return id; } -time_t ClassFlowTakeImage::getTimeImageTaken() +time_t ClassFlowTakeImage::getTimeImageTaken(void) { return TimeImageTaken; } @@ -312,4 +597,3 @@ ClassFlowTakeImage::~ClassFlowTakeImage(void) { delete rawImage; } - diff --git a/code/components/jomjol_flowcontroll/ClassFlowTakeImage.h b/code/components/jomjol_flowcontroll/ClassFlowTakeImage.h index d83f393e..0be4f3af 100644 --- a/code/components/jomjol_flowcontroll/ClassFlowTakeImage.h +++ b/code/components/jomjol_flowcontroll/ClassFlowTakeImage.h @@ -9,54 +9,32 @@ #include -class ClassFlowTakeImage : - public ClassFlowImage +class ClassFlowTakeImage : public ClassFlowImage { protected: - float waitbeforepicture; - float waitbeforepicture_store; - framesize_t ImageSize; - bool isImageSize; - bool ZoomEnabled = false; - int ZoomMode = 0; - int zoomOffsetX = 0; - int zoomOffsetY = 0; - bool ImageGrayscale; - bool ImageNegative; - bool ImageAec2; - int ImageQuality; time_t TimeImageTaken; string namerawimage; - int image_height, image_width; - bool SaveAllFiles; - bool FixedExposure; - - - void CopyFile(string input, string output); - - esp_err_t camera_capture(); + esp_err_t camera_capture(void); void takePictureWithFlash(int flash_duration); - - void SetInitialParameter(void); + void SetInitialParameter(void); public: CImageBasis *rawImage; - ClassFlowTakeImage(std::vector* lfc); + ClassFlowTakeImage(std::vector *lfc); - bool ReadParameter(FILE* pfile, string& aktparamgraph); + bool ReadParameter(FILE *pfile, string &aktparamgraph); bool doFlow(string time); string getHTMLSingleStep(string host); - time_t getTimeImageTaken(); - string name(){return "ClassFlowTakeImage";}; + time_t getTimeImageTaken(void); + string name() { return "ClassFlowTakeImage"; }; - ImageData* SendRawImage(); + ImageData *SendRawImage(void); esp_err_t SendRawJPG(httpd_req_t *req); ~ClassFlowTakeImage(void); }; - -#endif //CLASSFFLOWTAKEIMAGE_H \ No newline at end of file +#endif // CLASSFFLOWTAKEIMAGE_H \ No newline at end of file diff --git a/code/components/jomjol_flowcontroll/MainFlowControl.cpp b/code/components/jomjol_flowcontroll/MainFlowControl.cpp index 85ed3067..63eadac1 100644 --- a/code/components/jomjol_flowcontroll/MainFlowControl.cpp +++ b/code/components/jomjol_flowcontroll/MainFlowControl.cpp @@ -34,6 +34,7 @@ #endif ClassFlowControll flowctrl; +camera_flow_config_temp_t CFstatus; TaskHandle_t xHandletask_autodoFlow = NULL; @@ -48,177 +49,323 @@ bool isPlannedReboot = false; static const char *TAG = "MAINCTRL"; -//#define DEBUG_DETAIL_ON +// #define DEBUG_DETAIL_ON - -void CheckIsPlannedReboot() { +void CheckIsPlannedReboot(void) +{ FILE *pfile; - - if ((pfile = fopen("/sdcard/reboot.txt", "r")) == NULL) { - //LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Initial boot or not a planned reboot"); + + if ((pfile = fopen("/sdcard/reboot.txt", "r")) == NULL) + { + // LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Initial boot or not a planned reboot"); isPlannedReboot = false; } - else { + else + { LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Planned reboot"); - DeleteFile("/sdcard/reboot.txt"); // Prevent Boot Loop!!! + DeleteFile("/sdcard/reboot.txt"); // Prevent Boot Loop!!! isPlannedReboot = true; } } - -bool getIsPlannedReboot() { +bool getIsPlannedReboot(void) +{ return isPlannedReboot; } - -int getCountFlowRounds() { +int getCountFlowRounds(void) +{ return countRounds; } - -esp_err_t GetJPG(std::string _filename, httpd_req_t *req) { +esp_err_t GetJPG(std::string _filename, httpd_req_t *req) +{ return flowctrl.GetJPGStream(_filename, req); } - -esp_err_t GetRawJPG(httpd_req_t *req) { +esp_err_t GetRawJPG(httpd_req_t *req) +{ return flowctrl.SendRawJPG(req); } - -bool isSetupModusActive() { +bool isSetupModusActive(void) +{ return flowctrl.getStatusSetupModus(); } - -void DeleteMainFlowTask() +void DeleteMainFlowTask(void) { - #ifdef DEBUG_DETAIL_ON - ESP_LOGD(TAG, "DeleteMainFlowTask: xHandletask_autodoFlow: %ld", (long) xHandletask_autodoFlow); - #endif - - if( xHandletask_autodoFlow != NULL ) { +#ifdef DEBUG_DETAIL_ON + ESP_LOGD(TAG, "DeleteMainFlowTask: xHandletask_autodoFlow: %ld", (long)xHandletask_autodoFlow); +#endif + + if (xHandletask_autodoFlow != NULL) + { vTaskDelete(xHandletask_autodoFlow); xHandletask_autodoFlow = NULL; } - - #ifdef DEBUG_DETAIL_ON - ESP_LOGD(TAG, "Killed: xHandletask_autodoFlow"); - #endif + +#ifdef DEBUG_DETAIL_ON + ESP_LOGD(TAG, "Killed: xHandletask_autodoFlow"); +#endif } - -void doInit() { - #ifdef DEBUG_DETAIL_ON - ESP_LOGD(TAG, "Start flowctrl.InitFlow(config);"); - #endif +void doInit(void) +{ +#ifdef DEBUG_DETAIL_ON + ESP_LOGD(TAG, "Start flowctrl.InitFlow(config);"); +#endif flowctrl.InitFlow(CONFIG_FILE); - #ifdef DEBUG_DETAIL_ON - ESP_LOGD(TAG, "Finished flowctrl.InitFlow(config);"); - #endif - +#ifdef DEBUG_DETAIL_ON + ESP_LOGD(TAG, "Finished flowctrl.InitFlow(config);"); +#endif + /* GPIO handler has to be initialized before MQTT init to ensure proper topic subscription */ gpio_handler_init(); - #ifdef ENABLE_MQTT - flowctrl.StartMQTTService(); - #endif //ENABLE_MQTT +#ifdef ENABLE_MQTT + flowctrl.StartMQTTService(); +#endif // ENABLE_MQTT } - -bool doflow() { +bool doflow(void) +{ std::string zw_time = getCurrentTimeString(LOGFILE_TIME_FORMAT); ESP_LOGD(TAG, "doflow - start %s", zw_time.c_str()); flowisrunning = true; flowctrl.doFlow(zw_time); flowisrunning = false; - #ifdef DEBUG_DETAIL_ON - ESP_LOGD(TAG, "doflow - end %s", zw_time.c_str()); - #endif +#ifdef DEBUG_DETAIL_ON + ESP_LOGD(TAG, "doflow - end %s", zw_time.c_str()); +#endif return true; } +esp_err_t setCCstatusToCFstatus(void) +{ + CFstatus.ImageFrameSize = CCstatus.ImageFrameSize; + CFstatus.ImageGainceiling = CCstatus.ImageGainceiling; -esp_err_t handler_get_heap(httpd_req_t *req) { - #ifdef DEBUG_DETAIL_ON - LogFile.WriteHeapInfo("handler_get_heap - Start"); - ESP_LOGD(TAG, "handler_get_heap uri: %s", req->uri); - #endif + CFstatus.ImageQuality = CCstatus.ImageQuality; + CFstatus.ImageBrightness = CCstatus.ImageBrightness; + CFstatus.ImageContrast = CCstatus.ImageContrast; + CFstatus.ImageSaturation = CCstatus.ImageSaturation; + CFstatus.ImageSharpness = CCstatus.ImageSharpness; + CFstatus.ImageAutoSharpness = CCstatus.ImageAutoSharpness; + CFstatus.ImageWbMode = CCstatus.ImageWbMode; + CFstatus.ImageAwb = CCstatus.ImageAwb; + CFstatus.ImageAwbGain = CCstatus.ImageAwbGain; + CFstatus.ImageAec = CCstatus.ImageAec; + CFstatus.ImageAec2 = CCstatus.ImageAec2; + CFstatus.ImageAeLevel = CCstatus.ImageAeLevel; + CFstatus.ImageAecValue = CCstatus.ImageAecValue; + CFstatus.ImageAgc = CCstatus.ImageAgc; + CFstatus.ImageAgcGain = CCstatus.ImageAgcGain; + CFstatus.ImageBpc = CCstatus.ImageBpc; + CFstatus.ImageWpc = CCstatus.ImageWpc; + CFstatus.ImageRawGma = CCstatus.ImageRawGma; + CFstatus.ImageLenc = CCstatus.ImageLenc; + CFstatus.ImageSpecialEffect = CCstatus.ImageSpecialEffect; + CFstatus.ImageHmirror = CCstatus.ImageHmirror; + CFstatus.ImageVflip = CCstatus.ImageVflip; + CFstatus.ImageDcw = CCstatus.ImageDcw; - std::string zw = "Heap info:
" + getESPHeapInfo(); + CFstatus.ImageLedIntensity = CCstatus.ImageLedIntensity; - #ifdef TASK_ANALYSIS_ON - char* pcTaskList = (char*) calloc_psram_heap(std::string(TAG) + "->pcTaskList", 1, sizeof(char) * 768, MALLOC_CAP_8BIT | MALLOC_CAP_SPIRAM); - if (pcTaskList) { - vTaskList(pcTaskList); - zw = zw + "

Task info:
Name | State | Prio | Lowest stacksize | Creation order | CPU (-1=NoAffinity)
" - + std::string(pcTaskList) + "
"; - free_psram_heap(std::string(TAG) + "->pcTaskList", pcTaskList); - } - else { - zw = zw + "

Task info:
ERROR - Allocation of TaskList buffer in PSRAM failed"; - } - #endif + CFstatus.ImageZoomEnabled = CCstatus.ImageZoomEnabled; + CFstatus.ImageZoomMode = CCstatus.ImageZoomMode; + CFstatus.ImageZoomOffsetX = CCstatus.ImageZoomOffsetX; + CFstatus.ImageZoomOffsetY = CCstatus.ImageZoomOffsetY; + CFstatus.ImageZoomSize = CCstatus.ImageZoomSize; - httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*"); - - if (zw.length() > 0) { - httpd_resp_send(req, zw.c_str(), zw.length()); - } - else { - httpd_resp_send(req, NULL, 0); - } - - #ifdef DEBUG_DETAIL_ON - LogFile.WriteHeapInfo("handler_get_heap - Done"); - #endif + CFstatus.WaitBeforePicture = CCstatus.WaitBeforePicture; return ESP_OK; } +esp_err_t setCFstatusToCCstatus(void) +{ + CCstatus.ImageFrameSize = CFstatus.ImageFrameSize; + CCstatus.ImageGainceiling = CFstatus.ImageGainceiling; -esp_err_t handler_init(httpd_req_t *req) { - #ifdef DEBUG_DETAIL_ON - LogFile.WriteHeapInfo("handler_init - Start"); - ESP_LOGD(TAG, "handler_doinit uri: %s", req->uri); - #endif + CCstatus.ImageQuality = CFstatus.ImageQuality; + CCstatus.ImageBrightness = CFstatus.ImageBrightness; + CCstatus.ImageContrast = CFstatus.ImageContrast; + CCstatus.ImageSaturation = CFstatus.ImageSaturation; + CCstatus.ImageSharpness = CFstatus.ImageSharpness; + CCstatus.ImageAutoSharpness = CFstatus.ImageAutoSharpness; + CCstatus.ImageWbMode = CFstatus.ImageWbMode; + CCstatus.ImageAwb = CFstatus.ImageAwb; + CCstatus.ImageAwbGain = CFstatus.ImageAwbGain; + CCstatus.ImageAec = CFstatus.ImageAec; + CCstatus.ImageAec2 = CFstatus.ImageAec2; + CCstatus.ImageAeLevel = CFstatus.ImageAeLevel; + CCstatus.ImageAecValue = CFstatus.ImageAecValue; + CCstatus.ImageAgc = CFstatus.ImageAgc; + CCstatus.ImageAgcGain = CFstatus.ImageAgcGain; + CCstatus.ImageBpc = CFstatus.ImageBpc; + CCstatus.ImageWpc = CFstatus.ImageWpc; + CCstatus.ImageRawGma = CFstatus.ImageRawGma; + CCstatus.ImageLenc = CFstatus.ImageLenc; + CCstatus.ImageSpecialEffect = CFstatus.ImageSpecialEffect; + CCstatus.ImageHmirror = CFstatus.ImageHmirror; + CCstatus.ImageVflip = CFstatus.ImageVflip; + CCstatus.ImageDcw = CFstatus.ImageDcw; + + CCstatus.ImageLedIntensity = CFstatus.ImageLedIntensity; + + CCstatus.ImageZoomEnabled = CFstatus.ImageZoomEnabled; + CCstatus.ImageZoomMode = CFstatus.ImageZoomMode; + CCstatus.ImageZoomOffsetX = CFstatus.ImageZoomOffsetX; + CCstatus.ImageZoomOffsetY = CFstatus.ImageZoomOffsetY; + CCstatus.ImageZoomSize = CFstatus.ImageZoomSize; + + CCstatus.WaitBeforePicture = CFstatus.WaitBeforePicture; + + return ESP_OK; +} + +esp_err_t setCFstatusToCam(void) +{ + sensor_t *s = esp_camera_sensor_get(); + + if (s != NULL) + { + s->set_framesize(s, CFstatus.ImageFrameSize); + s->set_gainceiling(s, CFstatus.ImageGainceiling); + + s->set_quality(s, CFstatus.ImageQuality); // 0 - 63 + + s->set_brightness(s, CFstatus.ImageBrightness); // -2 to 2 + s->set_contrast(s, CFstatus.ImageContrast); // -2 to 2 + s->set_saturation(s, CFstatus.ImageSaturation); // -2 to 2 + // s->set_sharpness(s, CFstatus.ImageSharpness); // auto-sharpness is not officially supported, default to 0 + Camera.SetCamSharpness(CFstatus.ImageAutoSharpness, CFstatus.ImageSharpness); + + s->set_exposure_ctrl(s, CFstatus.ImageAec); // 0 = disable , 1 = enable + s->set_ae_level(s, CFstatus.ImageAeLevel); // -2 to 2 + s->set_aec_value(s, CFstatus.ImageAecValue); // 0 to 1200 + s->set_aec2(s, CFstatus.ImageAec2); // 0 = disable , 1 = enable + + s->set_gain_ctrl(s, CFstatus.ImageAgc); // 0 = disable , 1 = enable + s->set_agc_gain(s, CFstatus.ImageAgcGain); // 0 to 30 + + s->set_bpc(s, CFstatus.ImageBpc); // 0 = disable , 1 = enable + s->set_wpc(s, CFstatus.ImageWpc); // 0 = disable , 1 = enable + + s->set_raw_gma(s, CFstatus.ImageRawGma); // 0 = disable , 1 = enable + s->set_lenc(s, CFstatus.ImageLenc); // 0 = disable , 1 = enable + + s->set_hmirror(s, CFstatus.ImageHmirror); // 0 = disable , 1 = enable + s->set_vflip(s, CFstatus.ImageVflip); // 0 = disable , 1 = enable + + s->set_dcw(s, CFstatus.ImageDcw); // 0 = disable , 1 = enable + + s->set_wb_mode(s, CFstatus.ImageWbMode); // 0 to 4 - if awb_gain enabled (0 - Auto, 1 - Sunny, 2 - Cloudy, 3 - Office, 4 - Home) + s->set_awb_gain(s, CFstatus.ImageAwbGain); // 0 = disable , 1 = enable + s->set_whitebal(s, CFstatus.ImageAwb); // 0 = disable , 1 = enable + + // special_effect muß als Letztes gesetzt werden, sonst geht es nicht + s->set_special_effect(s, CFstatus.ImageSpecialEffect); // 0 to 6 (0 - No Effect, 1 - Negative, 2 - Grayscale, 3 - Red Tint, 4 - Green Tint, 5 - Blue Tint, 6 - Sepia) + + TickType_t xDelay2 = 1000 / portTICK_PERIOD_MS; + vTaskDelay(xDelay2); + + return ESP_OK; + } + else + { + return ESP_FAIL; + } +} + +esp_err_t handler_get_heap(httpd_req_t *req) +{ +#ifdef DEBUG_DETAIL_ON + LogFile.WriteHeapInfo("handler_get_heap - Start"); + ESP_LOGD(TAG, "handler_get_heap uri: %s", req->uri); +#endif + + std::string zw = "Heap info:
" + getESPHeapInfo(); + +#ifdef TASK_ANALYSIS_ON + char *pcTaskList = (char *)calloc_psram_heap(std::string(TAG) + "->pcTaskList", 1, sizeof(char) * 768, MALLOC_CAP_8BIT | MALLOC_CAP_SPIRAM); + if (pcTaskList) + { + vTaskList(pcTaskList); + zw = zw + "

Task info:
Name | State | Prio | Lowest stacksize | Creation order | CPU (-1=NoAffinity)
" + std::string(pcTaskList) + "
"; + free_psram_heap(std::string(TAG) + "->pcTaskList", pcTaskList); + } + else + { + zw = zw + "

Task info:
ERROR - Allocation of TaskList buffer in PSRAM failed"; + } +#endif httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*"); - const char* resp_str = "Init started
"; - httpd_resp_send(req, resp_str, HTTPD_RESP_USE_STRLEN); + + if (zw.length() > 0) + { + httpd_resp_send(req, zw.c_str(), zw.length()); + } + else + { + httpd_resp_send(req, NULL, 0); + } + +#ifdef DEBUG_DETAIL_ON + LogFile.WriteHeapInfo("handler_get_heap - Done"); +#endif + + return ESP_OK; +} + +esp_err_t handler_init(httpd_req_t *req) +{ +#ifdef DEBUG_DETAIL_ON + LogFile.WriteHeapInfo("handler_init - Start"); + ESP_LOGD(TAG, "handler_doinit uri: %s", req->uri); +#endif + + httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*"); + const char *resp_str = "Init started
"; + httpd_resp_send(req, resp_str, HTTPD_RESP_USE_STRLEN); doInit(); resp_str = "Init done
"; - httpd_resp_send(req, resp_str, HTTPD_RESP_USE_STRLEN); + httpd_resp_send(req, resp_str, HTTPD_RESP_USE_STRLEN); - #ifdef DEBUG_DETAIL_ON - LogFile.WriteHeapInfo("handler_init - Done"); - #endif +#ifdef DEBUG_DETAIL_ON + LogFile.WriteHeapInfo("handler_init - Done"); +#endif return ESP_OK; } - -esp_err_t handler_stream(httpd_req_t *req) { - #ifdef DEBUG_DETAIL_ON - LogFile.WriteHeapInfo("handler_stream - Start"); - ESP_LOGD(TAG, "handler_stream uri: %s", req->uri); - #endif +esp_err_t handler_stream(httpd_req_t *req) +{ +#ifdef DEBUG_DETAIL_ON + LogFile.WriteHeapInfo("handler_stream - Start"); + ESP_LOGD(TAG, "handler_stream uri: %s", req->uri); +#endif char _query[50]; char _value[10]; bool flashlightOn = false; - if (httpd_req_get_url_query_str(req, _query, 50) == ESP_OK) { -// ESP_LOGD(TAG, "Query: %s", _query); - if (httpd_query_key_value(_query, "flashlight", _value, 10) == ESP_OK) { - #ifdef DEBUG_DETAIL_ON - ESP_LOGD(TAG, "flashlight is found%s", _value); - #endif - if (strlen(_value) > 0) { + if (httpd_req_get_url_query_str(req, _query, 50) == ESP_OK) + { + // ESP_LOGD(TAG, "Query: %s", _query); + if (httpd_query_key_value(_query, "flashlight", _value, 10) == ESP_OK) + { +#ifdef DEBUG_DETAIL_ON + ESP_LOGD(TAG, "flashlight is found%s", _value); +#endif + if (strlen(_value) > 0) + { flashlightOn = true; } } @@ -226,190 +373,212 @@ esp_err_t handler_stream(httpd_req_t *req) { Camera.CaptureToStream(req, flashlightOn); - #ifdef DEBUG_DETAIL_ON - LogFile.WriteHeapInfo("handler_stream - Done"); - #endif +#ifdef DEBUG_DETAIL_ON + LogFile.WriteHeapInfo("handler_stream - Done"); +#endif return ESP_OK; } - -esp_err_t handler_flow_start(httpd_req_t *req) { - - #ifdef DEBUG_DETAIL_ON - LogFile.WriteHeapInfo("handler_flow_start - Start"); - #endif +esp_err_t handler_flow_start(httpd_req_t *req) +{ +#ifdef DEBUG_DETAIL_ON + LogFile.WriteHeapInfo("handler_flow_start - Start"); +#endif ESP_LOGD(TAG, "handler_flow_start uri: %s", req->uri); httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*"); - if (autostartIsEnabled) { + if (autostartIsEnabled) + { xTaskAbortDelay(xHandletask_autodoFlow); // Delay will be aborted if task is in blocked (waiting) state. If task is already running, no action LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Flow start triggered by REST API /flow_start"); - const char* resp_str = "The flow is going to be started immediately or is already running"; - httpd_resp_send(req, resp_str, HTTPD_RESP_USE_STRLEN); + const char *resp_str = "The flow is going to be started immediately or is already running"; + httpd_resp_send(req, resp_str, HTTPD_RESP_USE_STRLEN); } - else { + else + { LogFile.WriteToFile(ESP_LOG_WARN, TAG, "Flow start triggered by REST API, but flow is not active!"); - const char* resp_str = "WARNING: Flow start triggered by REST API, but flow is not active"; - httpd_resp_send(req, resp_str, HTTPD_RESP_USE_STRLEN); + const char *resp_str = "WARNING: Flow start triggered by REST API, but flow is not active"; + httpd_resp_send(req, resp_str, HTTPD_RESP_USE_STRLEN); } - #ifdef DEBUG_DETAIL_ON - LogFile.WriteHeapInfo("handler_flow_start - Done"); - #endif +#ifdef DEBUG_DETAIL_ON + LogFile.WriteHeapInfo("handler_flow_start - Done"); +#endif return ESP_OK; } - #ifdef ENABLE_MQTT -esp_err_t MQTTCtrlFlowStart(std::string _topic) { - #ifdef DEBUG_DETAIL_ON - LogFile.WriteHeapInfo("MQTTCtrlFlowStart - Start"); - #endif +esp_err_t MQTTCtrlFlowStart(std::string _topic) +{ +#ifdef DEBUG_DETAIL_ON + LogFile.WriteHeapInfo("MQTTCtrlFlowStart - Start"); +#endif ESP_LOGD(TAG, "MQTTCtrlFlowStart: topic %s", _topic.c_str()); - if (autostartIsEnabled) { + if (autostartIsEnabled) + { xTaskAbortDelay(xHandletask_autodoFlow); // Delay will be aborted if task is in blocked (waiting) state. If task is already running, no action LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Flow start triggered by MQTT topic " + _topic); } - else { + else + { LogFile.WriteToFile(ESP_LOG_WARN, TAG, "Flow start triggered by MQTT topic " + _topic + ", but flow is not active!"); - } + } - #ifdef DEBUG_DETAIL_ON - LogFile.WriteHeapInfo("MQTTCtrlFlowStart - Done"); - #endif +#ifdef DEBUG_DETAIL_ON + LogFile.WriteHeapInfo("MQTTCtrlFlowStart - Done"); +#endif return ESP_OK; } -#endif //ENABLE_MQTT +#endif // ENABLE_MQTT - -esp_err_t handler_json(httpd_req_t *req) { - #ifdef DEBUG_DETAIL_ON - LogFile.WriteHeapInfo("handler_json - Start"); - #endif +esp_err_t handler_json(httpd_req_t *req) +{ +#ifdef DEBUG_DETAIL_ON + LogFile.WriteHeapInfo("handler_json - Start"); +#endif ESP_LOGD(TAG, "handler_JSON uri: %s", req->uri); - - if (bTaskAutoFlowCreated) { + + if (bTaskAutoFlowCreated) + { httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*"); httpd_resp_set_type(req, "application/json"); std::string zw = flowctrl.getJSON(); - if (zw.length() > 0) { + if (zw.length() > 0) + { httpd_resp_send(req, zw.c_str(), zw.length()); } - else { + else + { httpd_resp_send(req, NULL, 0); } } - else { + else + { httpd_resp_send_err(req, HTTPD_403_FORBIDDEN, "Flow not (yet) started: REST API /json not yet available!"); return ESP_ERR_NOT_FOUND; } - #ifdef DEBUG_DETAIL_ON - LogFile.WriteHeapInfo("handler_JSON - Done"); - #endif +#ifdef DEBUG_DETAIL_ON + LogFile.WriteHeapInfo("handler_JSON - Done"); +#endif return ESP_OK; } +esp_err_t handler_wasserzaehler(httpd_req_t *req) +{ +#ifdef DEBUG_DETAIL_ON + LogFile.WriteHeapInfo("handler water counter - Start"); +#endif -esp_err_t handler_wasserzaehler(httpd_req_t *req) { - #ifdef DEBUG_DETAIL_ON - LogFile.WriteHeapInfo("handler water counter - Start"); - #endif - - if (bTaskAutoFlowCreated) { + if (bTaskAutoFlowCreated) + { bool _rawValue = false; bool _noerror = false; bool _all = false; std::string _type = "value"; string zw; - ESP_LOGD(TAG, "handler water counter uri: %s", req->uri); + ESP_LOGD(TAG, "handler water counter uri: %s", req->uri); char _query[100]; char _size[10]; - if (httpd_req_get_url_query_str(req, _query, 100) == ESP_OK) { - // ESP_LOGD(TAG, "Query: %s", _query); - if (httpd_query_key_value(_query, "all", _size, 10) == ESP_OK) { - #ifdef DEBUG_DETAIL_ON - ESP_LOGD(TAG, "all is found%s", _size); - #endif + if (httpd_req_get_url_query_str(req, _query, 100) == ESP_OK) + { + // ESP_LOGD(TAG, "Query: %s", _query); + if (httpd_query_key_value(_query, "all", _size, 10) == ESP_OK) + { +#ifdef DEBUG_DETAIL_ON + ESP_LOGD(TAG, "all is found%s", _size); +#endif _all = true; } - if (httpd_query_key_value(_query, "type", _size, 10) == ESP_OK) { - #ifdef DEBUG_DETAIL_ON - ESP_LOGD(TAG, "all is found: %s", _size); - #endif + if (httpd_query_key_value(_query, "type", _size, 10) == ESP_OK) + { +#ifdef DEBUG_DETAIL_ON + ESP_LOGD(TAG, "all is found: %s", _size); +#endif _type = std::string(_size); } - if (httpd_query_key_value(_query, "rawvalue", _size, 10) == ESP_OK) { - #ifdef DEBUG_DETAIL_ON - ESP_LOGD(TAG, "rawvalue is found: %s", _size); - #endif + if (httpd_query_key_value(_query, "rawvalue", _size, 10) == ESP_OK) + { +#ifdef DEBUG_DETAIL_ON + ESP_LOGD(TAG, "rawvalue is found: %s", _size); +#endif _rawValue = true; } - - if (httpd_query_key_value(_query, "noerror", _size, 10) == ESP_OK) { - #ifdef DEBUG_DETAIL_ON - ESP_LOGD(TAG, "noerror is found: %s", _size); - #endif + + if (httpd_query_key_value(_query, "noerror", _size, 10) == ESP_OK) + { +#ifdef DEBUG_DETAIL_ON + ESP_LOGD(TAG, "noerror is found: %s", _size); +#endif _noerror = true; - } - } + } + } httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*"); - if (_all) { + if (_all) + { httpd_resp_set_type(req, "text/plain"); ESP_LOGD(TAG, "TYPE: %s", _type.c_str()); int _intype = READOUT_TYPE_VALUE; - - if (_type == "prevalue") { + + if (_type == "prevalue") + { _intype = READOUT_TYPE_PREVALUE; } - - if (_type == "raw") { + + if (_type == "raw") + { _intype = READOUT_TYPE_RAWVALUE; } - - if (_type == "error") { + + if (_type == "error") + { _intype = READOUT_TYPE_ERROR; } zw = flowctrl.getReadoutAll(_intype); ESP_LOGD(TAG, "ZW: %s", zw.c_str()); - - if (zw.length() > 0) { + + if (zw.length() > 0) + { httpd_resp_send(req, zw.c_str(), zw.length()); } - + return ESP_OK; } std::string *status = flowctrl.getActStatus(); string query = std::string(_query); - // ESP_LOGD(TAG, "Query: %s, query.c_str()); - if (query.find("full") != std::string::npos) { + // ESP_LOGD(TAG, "Query: %s, query.c_str()); + + if (query.find("full") != std::string::npos) + { string txt; txt = ""; - if ((countRounds <= 1) && (*status != std::string("Flow finished"))) { + if ((countRounds <= 1) && (*status != std::string("Flow finished"))) + { // First round not completed yet txt += "

Please wait for the first round to complete!

Current state: " + *status + "

\n"; } - else { + else + { txt += "

Value

"; } @@ -417,118 +586,133 @@ esp_err_t handler_wasserzaehler(httpd_req_t *req) { } zw = flowctrl.getReadout(_rawValue, _noerror, 0); - - if (zw.length() > 0) { - httpd_resp_sendstr_chunk(req, zw.c_str()); + + if (zw.length() > 0) + { + httpd_resp_sendstr_chunk(req, zw.c_str()); } - if (query.find("full") != std::string::npos) { + if (query.find("full") != std::string::npos) + { string txt, zw; - if ((countRounds <= 1) && (*status != std::string("Flow finished"))) { + if ((countRounds <= 1) && (*status != std::string("Flow finished"))) + { // First round not completed yet // Nothing to do } - else { + else + { /* Digital ROIs */ txt = ""; txt += "

Recognized Digit ROIs (previous round)

\n"; txt += "\n"; - std::vector htmlinfodig; - htmlinfodig = flowctrl.GetAllDigital(); + std::vector htmlinfodig; + htmlinfodig = flowctrl.GetAllDigital(); - for (int i = 0; i < htmlinfodig.size(); ++i) { - if (flowctrl.GetTypeDigital() == Digital) { - if (htmlinfodig[i]->val >= 10) { + for (int i = 0; i < htmlinfodig.size(); ++i) + { + if (flowctrl.GetTypeDigital() == Digital) + { + if (htmlinfodig[i]->val >= 10) + { zw = "NaN"; } - else { - zw = to_string((int) htmlinfodig[i]->val); + else + { + zw = to_string((int)htmlinfodig[i]->val); } - txt += "\n"; + txt += "\n"; } - else { + else + { std::stringstream stream; stream << std::fixed << std::setprecision(1) << htmlinfodig[i]->val; zw = stream.str(); - if (std::stod(zw) >= 10) { + if (std::stod(zw) >= 10) + { zw = "NaN"; } - txt += "\n"; + txt += "\n"; } delete htmlinfodig[i]; } htmlinfodig.clear(); - + txt += "

" + zw + "

filename + "\">

" + zw + "

filename + "\">

" + zw + "

filename + "\">

" + zw + "

filename + "\">

\n"; - httpd_resp_sendstr_chunk(req, txt.c_str()); + httpd_resp_sendstr_chunk(req, txt.c_str()); /* Analog ROIs */ txt = "

Recognized Analog ROIs (previous round)

\n"; txt += "\n"; - - std::vector htmlinfoana; + + std::vector htmlinfoana; htmlinfoana = flowctrl.GetAllAnalog(); - - for (int i = 0; i < htmlinfoana.size(); ++i) { + + for (int i = 0; i < htmlinfoana.size(); ++i) + { std::stringstream stream; stream << std::fixed << std::setprecision(1) << htmlinfoana[i]->val; zw = stream.str(); - if (std::stod(zw) >= 10) { + if (std::stod(zw) >= 10) + { zw = "NaN"; - } + } - txt += "\n"; + txt += "\n"; delete htmlinfoana[i]; } - - htmlinfoana.clear(); + + htmlinfoana.clear(); txt += "\n

" + zw + "

filename + "\">

" + zw + "

filename + "\">

\n"; - httpd_resp_sendstr_chunk(req, txt.c_str()); + httpd_resp_sendstr_chunk(req, txt.c_str()); - /* Full Image + /* Full Image * Only show it after the image got taken and aligned */ txt = "

Aligned Image (current round)

\n"; - - if ((*status == std::string("Initialization")) || - (*status == std::string("Initialization (delayed)")) || - (*status == std::string("Take Image"))) { + + if ((*status == std::string("Initialization")) || + (*status == std::string("Initialization (delayed)")) || + (*status == std::string("Take Image"))) + { txt += "

Current state: " + *status + "

\n"; } - else { + else + { txt += "\n"; } - httpd_resp_sendstr_chunk(req, txt.c_str()); + httpd_resp_sendstr_chunk(req, txt.c_str()); } - } + } /* Respond with an empty chunk to signal HTTP response completion */ - httpd_resp_sendstr_chunk(req, NULL); + httpd_resp_sendstr_chunk(req, NULL); } - else { + else + { httpd_resp_send_err(req, HTTPD_403_FORBIDDEN, "Flow not (yet) started: REST API /value not available!"); return ESP_ERR_NOT_FOUND; } - #ifdef DEBUG_DETAIL_ON - LogFile.WriteHeapInfo("handler_wasserzaehler - Done"); - #endif +#ifdef DEBUG_DETAIL_ON + LogFile.WriteHeapInfo("handler_wasserzaehler - Done"); +#endif return ESP_OK; } - -esp_err_t handler_editflow(httpd_req_t *req) { - #ifdef DEBUG_DETAIL_ON - LogFile.WriteHeapInfo("handler_editflow - Start"); - #endif +esp_err_t handler_editflow(httpd_req_t *req) +{ +#ifdef DEBUG_DETAIL_ON + LogFile.WriteHeapInfo("handler_editflow - Start"); +#endif ESP_LOGD(TAG, "handler_editflow uri: %s", req->uri); @@ -536,42 +720,48 @@ esp_err_t handler_editflow(httpd_req_t *req) { char _valuechar[30]; string _task; - if (httpd_req_get_url_query_str(req, _query, 200) == ESP_OK) { - if (httpd_query_key_value(_query, "task", _valuechar, 30) == ESP_OK) { - #ifdef DEBUG_DETAIL_ON - ESP_LOGD(TAG, "task is found: %s", _valuechar); - #endif + if (httpd_req_get_url_query_str(req, _query, 200) == ESP_OK) + { + if (httpd_query_key_value(_query, "task", _valuechar, 30) == ESP_OK) + { +#ifdef DEBUG_DETAIL_ON + ESP_LOGD(TAG, "task is found: %s", _valuechar); +#endif _task = string(_valuechar); } - } + } - if (_task.compare("namenumbers") == 0) { + if (_task.compare("namenumbers") == 0) + { ESP_LOGD(TAG, "Get NUMBER list"); return get_numbers_file_handler(req); } - if (_task.compare("data") == 0) { + if (_task.compare("data") == 0) + { ESP_LOGD(TAG, "Get data list"); return get_data_file_handler(req); } - if (_task.compare("tflite") == 0) { + if (_task.compare("tflite") == 0) + { ESP_LOGD(TAG, "Get tflite list"); return get_tflite_file_handler(req); } - if (_task.compare("copy") == 0) { + if (_task.compare("copy") == 0) + { string in, out, zw; httpd_query_key_value(_query, "in", _valuechar, 30); in = string(_valuechar); - httpd_query_key_value(_query, "out", _valuechar, 30); - out = string(_valuechar); + httpd_query_key_value(_query, "out", _valuechar, 30); + out = string(_valuechar); - #ifdef DEBUG_DETAIL_ON - ESP_LOGD(TAG, "in: %s", in.c_str()); - ESP_LOGD(TAG, "out: %s", out.c_str()); - #endif +#ifdef DEBUG_DETAIL_ON + ESP_LOGD(TAG, "in: %s", in.c_str()); + ESP_LOGD(TAG, "out: %s", out.c_str()); +#endif in = "/sdcard" + in; out = "/sdcard" + out; @@ -579,10 +769,11 @@ esp_err_t handler_editflow(httpd_req_t *req) { CopyFile(in, out); zw = "Copy Done"; httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*"); - httpd_resp_send(req, zw.c_str(), zw.length()); + httpd_resp_send(req, zw.c_str(), zw.length()); } - if (_task.compare("cutref") == 0) { + if (_task.compare("cutref") == 0) + { string in, out, zw; int x, y, dx, dy; bool enhance = false; @@ -590,37 +781,40 @@ esp_err_t handler_editflow(httpd_req_t *req) { httpd_query_key_value(_query, "in", _valuechar, 30); in = string(_valuechar); - httpd_query_key_value(_query, "out", _valuechar, 30); - out = string(_valuechar); + httpd_query_key_value(_query, "out", _valuechar, 30); + out = string(_valuechar); httpd_query_key_value(_query, "x", _valuechar, 30); - zw = string(_valuechar); - x = stoi(zw); + string _x = string(_valuechar); + x = stoi(_x); httpd_query_key_value(_query, "y", _valuechar, 30); - zw = string(_valuechar); - y = stoi(zw); + string _y = string(_valuechar); + y = stoi(_y); httpd_query_key_value(_query, "dx", _valuechar, 30); - zw = string(_valuechar); - dx = stoi(zw); + string _dx = string(_valuechar); + dx = stoi(_dx); httpd_query_key_value(_query, "dy", _valuechar, 30); - zw = string(_valuechar); - dy = stoi(zw); + string _dy = string(_valuechar); + dy = stoi(_dy); - #ifdef DEBUG_DETAIL_ON - ESP_LOGD(TAG, "in: %s", in.c_str()); - ESP_LOGD(TAG, "out: %s", out.c_str()); - ESP_LOGD(TAG, "x: %s", zw.c_str()); - ESP_LOGD(TAG, "y: %s", zw.c_str()); - ESP_LOGD(TAG, "dx: %s", zw.c_str()); - ESP_LOGD(TAG, "dy: %s", zw.c_str()); - #endif +#ifdef DEBUG_DETAIL_ON + ESP_LOGD(TAG, "in: %s", in.c_str()); + ESP_LOGD(TAG, "out: %s", out.c_str()); + ESP_LOGD(TAG, "x: %s", _x.c_str()); + ESP_LOGD(TAG, "y: %s", _y.c_str()); + ESP_LOGD(TAG, "dx: %s", _dx.c_str()); + ESP_LOGD(TAG, "dy: %s", _dy.c_str()); +#endif - if (httpd_query_key_value(_query, "enhance", _valuechar, 10) == ESP_OK) { - zw = string(_valuechar); - if (zw.compare("true") == 0) { + if (httpd_query_key_value(_query, "enhance", _valuechar, 10) == ESP_OK) + { + string _enhance = string(_valuechar); + + if (_enhance.compare("true") == 0) + { enhance = true; } } @@ -630,269 +824,507 @@ esp_err_t handler_editflow(httpd_req_t *req) { string out2 = out.substr(0, out.length() - 4) + "_org.jpg"; - if ((flowctrl.SetupModeActive || (*flowctrl.getActStatus() == "Flow finished")) && psram_init_shared_memory_for_take_image_step()) { + if ((flowctrl.SetupModeActive || (*flowctrl.getActStatus() == std::string("Flow finished"))) && psram_init_shared_memory_for_take_image_step()) + { LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Taking image for Alignment Mark Update..."); CAlignAndCutImage *caic = new CAlignAndCutImage("cutref", in); caic->CutAndSave(out2, x, y, dx, dy); - delete caic; + delete caic; CImageBasis *cim = new CImageBasis("cutref", out2); - if (enhance) { + + if (enhance) + { cim->Contrast(90); } cim->SaveToFile(out); - delete cim; + delete cim; psram_deinit_shared_memory_for_take_image_step(); zw = "CutImage Done"; } - else { - LogFile.WriteToFile(ESP_LOG_WARN, TAG, std::string("Taking image for Alignment Mark not possible while device") + - " is busy with a round (Current State: '" + *flowctrl.getActStatus() + "')!"); + else + { + LogFile.WriteToFile(ESP_LOG_WARN, TAG, std::string("Taking image for Alignment Mark not possible while device") + " is busy with a round (Current State: '" + *flowctrl.getActStatus() + "')!"); zw = "Device Busy"; } httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*"); - httpd_resp_send(req, zw.c_str(), zw.length()); + httpd_resp_send(req, zw.c_str(), zw.length()); } - if ((_task.compare("test_take") == 0) || (_task.compare("cam_settings") == 0)) { - std::string _zw = ""; - std::string _host = ""; - int bri = -100; - int sat = -100; - int con = -100; - int intens = -100; - int aelevel = 0; - int zoommode = 0; - int zoomoffsetx = 0; - int zoomoffsety = 0; - bool zoom = false; - bool negative = false; - bool aec2 = false; - int sharpnessLevel = 0; - #ifdef GRAYSCALE_AS_DEFAULT - bool grayscale = true; - #else - bool grayscale = false; - #endif + // wird beim Erstellen eines neuen Referenzbildes aufgerufen + std::string *sys_status = flowctrl.getActStatus(); - if (httpd_query_key_value(_query, "host", _valuechar, 30) == ESP_OK) { - _host = std::string(_valuechar); - } - if (httpd_query_key_value(_query, "int", _valuechar, 30) == ESP_OK) { - std::string _int = std::string(_valuechar); - intens = stoi(_int); - } - if (httpd_query_key_value(_query, "bri", _valuechar, 30) == ESP_OK) { - std::string _bri = std::string(_valuechar); - bri = stoi(_bri); - } - if (httpd_query_key_value(_query, "con", _valuechar, 30) == ESP_OK) { - std::string _con = std::string(_valuechar); - con = stoi(_con); - } - if (httpd_query_key_value(_query, "sat", _valuechar, 30) == ESP_OK) { - std::string _sat = std::string(_valuechar); - sat = stoi(_sat); - } - if (httpd_query_key_value(_query, "ae", _valuechar, 30) == ESP_OK) { - std::string _ae = std::string(_valuechar); - aelevel = stoi(_ae); - } - if (httpd_query_key_value(_query, "sh", _valuechar, 30) == ESP_OK) { - std::string _sh = std::string(_valuechar); - sharpnessLevel = stoi(_sh); - } - if (httpd_query_key_value(_query, "gs", _valuechar, 30) == ESP_OK) { - std::string _gr = std::string(_valuechar); - if (stoi(_gr) != 0) { - grayscale = true; - } - else { - grayscale = false; - } - } - if (httpd_query_key_value(_query, "ne", _valuechar, 30) == ESP_OK) { - std::string _ne = std::string(_valuechar); - if (stoi(_ne) != 0) { - negative = true; - } - else { - negative = false; - } - } - if (httpd_query_key_value(_query, "a2", _valuechar, 30) == ESP_OK) { - std::string _a2 = std::string(_valuechar); - if (stoi(_a2) != 0) { - aec2 = true; - } - else { - aec2 = false; - } - } - if (httpd_query_key_value(_query, "z", _valuechar, 30) == ESP_OK) { - std::string _zoom = std::string(_valuechar); - if (stoi(_zoom) != 0) { - zoom = true; - } - else { - zoom = false; - } - } - if (httpd_query_key_value(_query, "zm", _valuechar, 30) == ESP_OK) { - std::string _zm = std::string(_valuechar); - zoommode = stoi(_zm); - } - if (httpd_query_key_value(_query, "x", _valuechar, 30) == ESP_OK) { - std::string _x = std::string(_valuechar); - zoomoffsetx = stoi(_x); - } - if (httpd_query_key_value(_query, "y", _valuechar, 30) == ESP_OK) { - std::string _y = std::string(_valuechar); - zoomoffsety = stoi(_y); - } - -// ESP_LOGD(TAG, "Parameter host: %s", _host.c_str()); -// string zwzw = "Do " + _task + " start\n"; ESP_LOGD(TAG, zwzw.c_str()); - Camera.SetZoom(zoom, zoommode, zoomoffsetx, zoomoffsety); - Camera.SetBrightnessContrastSaturation(bri, con, sat, aelevel, grayscale, negative, aec2, sharpnessLevel); - Camera.SetLEDIntensity(intens); - - if (_task.compare("cam_settings") == 0) + if ((sys_status->c_str() != std::string("Take Image")) && (sys_status->c_str() != std::string("Aligning"))) + { + if ((_task.compare("test_take") == 0) || (_task.compare("cam_settings") == 0)) { - ESP_LOGD(TAG, "Cam Settings set"); - _zw = "Cam Settings set"; + std::string _host = ""; + + // laden der aktuellen Kameraeinstellungen(CCstatus) in den Zwischenspeicher(CFstatus) + setCCstatusToCFstatus(); // CCstatus >>> CFstatus + + if (httpd_query_key_value(_query, "host", _valuechar, 30) == ESP_OK) + { + _host = std::string(_valuechar); + } + + if (httpd_query_key_value(_query, "waitb", _valuechar, 30) == ESP_OK) + { + int _waitb = std::stoi(_valuechar); + if (_waitb != 0) + { + CFstatus.WaitBeforePicture = _waitb; + } + } + + if (httpd_query_key_value(_query, "qual", _valuechar, 30) == ESP_OK) + { + int _qual = std::stoi(_valuechar); + if ((_qual >= 0) && (_qual <= 63)) + { + CFstatus.ImageQuality = _qual; + } + } + + if (httpd_query_key_value(_query, "bri", _valuechar, 30) == ESP_OK) + { + int _bri = std::stoi(_valuechar); + if ((_bri >= -2) && (_bri <= 2)) + { + CFstatus.ImageBrightness = _bri; + } + } + + if (httpd_query_key_value(_query, "con", _valuechar, 30) == ESP_OK) + { + int _con = std::stoi(_valuechar); + if ((_con >= -2) && (_con <= 2)) + { + CFstatus.ImageContrast = _con; + } + } + + if (httpd_query_key_value(_query, "sat", _valuechar, 30) == ESP_OK) + { + int _sat = std::stoi(_valuechar); + if ((_sat >= -2) && (_sat <= 2)) + { + CFstatus.ImageSaturation = _sat; + } + } + + if (httpd_query_key_value(_query, "shp", _valuechar, 30) == ESP_OK) + { + int _shp = std::stoi(_valuechar); + if ((_shp >= -2) && (_shp <= 2)) + { + CFstatus.ImageSharpness = _shp; + } + } + + if (httpd_query_key_value(_query, "ashp", _valuechar, 30) == ESP_OK) + { + if (std::stoi(_valuechar) != 0) + { + CFstatus.ImageAutoSharpness = 1; + } + else + { + CFstatus.ImageAutoSharpness = 0; + } + } + + if (httpd_query_key_value(_query, "spe", _valuechar, 30) == ESP_OK) + { + int _spe = std::stoi(_valuechar); + if ((_spe >= 0) && (_spe <= 6)) + { + CFstatus.ImageSpecialEffect = _spe; + } + } + + if (httpd_query_key_value(_query, "wbm", _valuechar, 30) == ESP_OK) + { + int _wbm = std::stoi(_valuechar); + if ((_wbm >= 0) && (_wbm <= 4)) + { + CFstatus.ImageWbMode = _wbm; + } + } + + if (httpd_query_key_value(_query, "awb", _valuechar, 30) == ESP_OK) + { + if (std::stoi(_valuechar) != 0) + { + CFstatus.ImageAwb = 1; + } + else + { + CFstatus.ImageAwb = 0; + } + } + + if (httpd_query_key_value(_query, "awbg", _valuechar, 30) == ESP_OK) + { + if (std::stoi(_valuechar) != 0) + { + CFstatus.ImageAwbGain = 1; + } + else + { + CFstatus.ImageAwbGain = 0; + } + } + + if (httpd_query_key_value(_query, "aec", _valuechar, 30) == ESP_OK) + { + if (std::stoi(_valuechar) != 0) + { + CFstatus.ImageAec = 1; + } + else + { + CFstatus.ImageAec = 0; + } + } + + if (httpd_query_key_value(_query, "aec2", _valuechar, 30) == ESP_OK) + { + if (std::stoi(_valuechar) != 0) + { + CFstatus.ImageAec2 = 1; + } + else + { + CFstatus.ImageAec2 = 0; + } + } + + if (httpd_query_key_value(_query, "ael", _valuechar, 30) == ESP_OK) + { + int _ael = std::stoi(_valuechar); + if ((_ael >= -2) && (_ael <= 2)) + { + CFstatus.ImageAeLevel = _ael; + } + } + + if (httpd_query_key_value(_query, "aecv", _valuechar, 30) == ESP_OK) + { + int _aecv = std::stoi(_valuechar); + if ((_aecv >= 0) && (_aecv <= 1200)) + { + CFstatus.ImageAecValue = _aecv; + } + } + + if (httpd_query_key_value(_query, "agc", _valuechar, 30) == ESP_OK) + { + if (std::stoi(_valuechar) != 0) + { + CFstatus.ImageAgc = 1; + } + else + { + CFstatus.ImageAgc = 0; + } + } + + if (httpd_query_key_value(_query, "agcg", _valuechar, 30) == ESP_OK) + { + int _agcg = std::stoi(_valuechar); + if ((_agcg >= 0) && (_agcg <= 30)) + { + CFstatus.ImageAgcGain = _agcg; + } + } + + if (httpd_query_key_value(_query, "bpc", _valuechar, 30) == ESP_OK) + { + if (std::stoi(_valuechar) != 0) + { + CFstatus.ImageBpc = 1; + } + else + { + CFstatus.ImageBpc = 0; + } + } + + if (httpd_query_key_value(_query, "wpc", _valuechar, 30) == ESP_OK) + { + if (std::stoi(_valuechar) != 0) + { + CFstatus.ImageWpc = 1; + } + else + { + CFstatus.ImageWpc = 0; + } + } + + if (httpd_query_key_value(_query, "rgma", _valuechar, 30) == ESP_OK) + { + if (std::stoi(_valuechar) != 0) + { + CFstatus.ImageRawGma = 1; + } + else + { + CFstatus.ImageRawGma = 0; + } + } + + if (httpd_query_key_value(_query, "lenc", _valuechar, 30) == ESP_OK) + { + if (std::stoi(_valuechar) != 0) + { + CFstatus.ImageLenc = 1; + } + else + { + CFstatus.ImageLenc = 0; + } + } + + if (httpd_query_key_value(_query, "mirror", _valuechar, 30) == ESP_OK) + { + if (std::stoi(_valuechar) != 0) + { + CFstatus.ImageHmirror = 1; + } + else + { + CFstatus.ImageHmirror = 0; + } + } + + if (httpd_query_key_value(_query, "flip", _valuechar, 30) == ESP_OK) + { + if (std::stoi(_valuechar) != 0) + { + CFstatus.ImageVflip = 1; + } + else + { + CFstatus.ImageVflip = 0; + } + } + + if (httpd_query_key_value(_query, "dcw", _valuechar, 30) == ESP_OK) + { + if (std::stoi(_valuechar) != 0) + { + CFstatus.ImageDcw = 1; + } + else + { + CFstatus.ImageDcw = 0; + } + } + + if (httpd_query_key_value(_query, "zoom", _valuechar, 30) == ESP_OK) + { + if (std::stoi(_valuechar) != 0) + { + CFstatus.ImageZoomEnabled = 1; + } + else + { + CFstatus.ImageZoomEnabled = 0; + } + } + + if (httpd_query_key_value(_query, "zoomx", _valuechar, 30) == ESP_OK) + { + CFstatus.ImageZoomOffsetX = std::stoi(_valuechar); + } + + if (httpd_query_key_value(_query, "zoomy", _valuechar, 30) == ESP_OK) + { + CFstatus.ImageZoomOffsetY = std::stoi(_valuechar); + } + + if (httpd_query_key_value(_query, "zooms", _valuechar, 30) == ESP_OK) + { + int _ImageZoomSize = std::stoi(_valuechar); + if (_ImageZoomSize >= 0) + { + CFstatus.ImageZoomSize = _ImageZoomSize; + } + } + + if (httpd_query_key_value(_query, "ledi", _valuechar, 30) == ESP_OK) + { + float _ImageLedIntensity = std::stof(_valuechar); + Camera.SetLEDIntensity(_ImageLedIntensity); + CFstatus.ImageLedIntensity = CCstatus.ImageLedIntensity; + } + + if (_task.compare("cam_settings") == 0) + { + // wird aufgerufen, wenn das Referenzbild + Kameraeinstellungen gespeichert wurden + setCFstatusToCCstatus(); // CFstatus >>> CCstatus + + // Kameraeinstellungen wurden verädert + CFstatus.changedCameraSettings = true; + + ESP_LOGD(TAG, "Cam Settings set"); + std::string _zw = "CamSettingsSet"; + httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*"); + httpd_resp_send(req, _zw.c_str(), _zw.length()); + } + else + { + // wird aufgerufen, wenn ein neues Referenzbild erstellt oder aktualisiert wurde + // CFstatus >>> Kamera + setCFstatusToCam(); + + Camera.SetQualityZoomSize(CFstatus.ImageQuality, CFstatus.ImageFrameSize, CFstatus.ImageZoomEnabled, CFstatus.ImageZoomOffsetX, CFstatus.ImageZoomOffsetY, CFstatus.ImageZoomSize); + // Camera.SetZoomSize(CFstatus.ImageZoomEnabled, CFstatus.ImageZoomOffsetX, CFstatus.ImageZoomOffsetY, CFstatus.ImageZoomSize); + + // Kameraeinstellungen wurden verädert + CFstatus.changedCameraSettings = true; + + ESP_LOGD(TAG, "test_take - vor TakeImage"); + std::string image_temp = flowctrl.doSingleStep("[TakeImage]", _host); + httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*"); + httpd_resp_send(req, image_temp.c_str(), image_temp.length()); + } } - else + if (_task.compare("test_align") == 0) { - ESP_LOGD(TAG, "test_take - vor TakeImage"); - _zw = flowctrl.doSingleStep("[TakeImage]", _host); - } - - httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*"); - httpd_resp_send(req, _zw.c_str(), _zw.length()); - } - - if (_task.compare("test_align") == 0) { - std::string _host = ""; - if (httpd_query_key_value(_query, "host", _valuechar, 30) == ESP_OK) { - _host = std::string(_valuechar); - } -// ESP_LOGD(TAG, "Parameter host: %s", _host.c_str()); + std::string _host = ""; -// string zwzw = "Do " + _task + " start\n"; ESP_LOGD(TAG, zwzw.c_str()); - std::string zw = flowctrl.doSingleStep("[Alignment]", _host); + if (httpd_query_key_value(_query, "host", _valuechar, 30) == ESP_OK) + { + _host = std::string(_valuechar); + } + + std::string zw = flowctrl.doSingleStep("[Alignment]", _host); + httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*"); + httpd_resp_send(req, zw.c_str(), zw.length()); + } + } + else + { + std::string _zw = "DeviceIsBusy"; httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*"); - httpd_resp_send(req, zw.c_str(), zw.length()); + httpd_resp_send(req, _zw.c_str(), _zw.length()); } - #ifdef DEBUG_DETAIL_ON - LogFile.WriteHeapInfo("handler_editflow - Done"); - #endif +#ifdef DEBUG_DETAIL_ON + LogFile.WriteHeapInfo("handler_editflow - Done"); +#endif return ESP_OK; } +esp_err_t handler_statusflow(httpd_req_t *req) +{ +#ifdef DEBUG_DETAIL_ON + LogFile.WriteHeapInfo("handler_statusflow - Start"); +#endif -esp_err_t handler_statusflow(httpd_req_t *req) { - #ifdef DEBUG_DETAIL_ON - LogFile.WriteHeapInfo("handler_statusflow - Start"); - #endif - - const char* resp_str; + const char *resp_str; httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*"); - if (bTaskAutoFlowCreated) { - #ifdef DEBUG_DETAIL_ON - ESP_LOGD(TAG, "handler_statusflow: %s", req->uri); - #endif + if (bTaskAutoFlowCreated) + { +#ifdef DEBUG_DETAIL_ON + ESP_LOGD(TAG, "handler_statusflow: %s", req->uri); +#endif - string* zw = flowctrl.getActStatusWithTime(); + string *zw = flowctrl.getActStatusWithTime(); resp_str = zw->c_str(); - httpd_resp_send(req, resp_str, HTTPD_RESP_USE_STRLEN); + httpd_resp_send(req, resp_str, HTTPD_RESP_USE_STRLEN); } - else { + else + { resp_str = "Flow task not yet created"; - httpd_resp_send(req, resp_str, HTTPD_RESP_USE_STRLEN); + httpd_resp_send(req, resp_str, HTTPD_RESP_USE_STRLEN); } - #ifdef DEBUG_DETAIL_ON - LogFile.WriteHeapInfo("handler_statusflow - Done"); - #endif +#ifdef DEBUG_DETAIL_ON + LogFile.WriteHeapInfo("handler_statusflow - Done"); +#endif return ESP_OK; } - -esp_err_t handler_cputemp(httpd_req_t *req) { - #ifdef DEBUG_DETAIL_ON - LogFile.WriteHeapInfo("handler_cputemp - Start"); - #endif +esp_err_t handler_cputemp(httpd_req_t *req) +{ +#ifdef DEBUG_DETAIL_ON + LogFile.WriteHeapInfo("handler_cputemp - Start"); +#endif httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*"); httpd_resp_send(req, std::to_string((int)temperatureRead()).c_str(), HTTPD_RESP_USE_STRLEN); - #ifdef DEBUG_DETAIL_ON - LogFile.WriteHeapInfo("handler_cputemp - End"); - #endif +#ifdef DEBUG_DETAIL_ON + LogFile.WriteHeapInfo("handler_cputemp - End"); +#endif return ESP_OK; } +esp_err_t handler_rssi(httpd_req_t *req) +{ +#ifdef DEBUG_DETAIL_ON + LogFile.WriteHeapInfo("handler_rssi - Start"); +#endif -esp_err_t handler_rssi(httpd_req_t *req) { - #ifdef DEBUG_DETAIL_ON - LogFile.WriteHeapInfo("handler_rssi - Start"); - #endif - - if (getWIFIisConnected()) { + if (getWIFIisConnected()) + { httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*"); httpd_resp_send(req, std::to_string(get_WIFI_RSSI()).c_str(), HTTPD_RESP_USE_STRLEN); } - else { + else + { httpd_resp_send_err(req, HTTPD_403_FORBIDDEN, "WIFI not (yet) connected: REST API /rssi not available!"); return ESP_ERR_NOT_FOUND; - } + } - #ifdef DEBUG_DETAIL_ON - LogFile.WriteHeapInfo("handler_rssi - End"); - #endif +#ifdef DEBUG_DETAIL_ON + LogFile.WriteHeapInfo("handler_rssi - End"); +#endif return ESP_OK; } +esp_err_t handler_uptime(httpd_req_t *req) +{ +#ifdef DEBUG_DETAIL_ON + LogFile.WriteHeapInfo("handler_uptime - Start"); +#endif -esp_err_t handler_uptime(httpd_req_t *req) { - #ifdef DEBUG_DETAIL_ON - LogFile.WriteHeapInfo("handler_uptime - Start"); - #endif - std::string formatedUptime = getFormatedUptime(false); httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*"); - httpd_resp_send(req, formatedUptime.c_str(), formatedUptime.length()); + httpd_resp_send(req, formatedUptime.c_str(), formatedUptime.length()); - #ifdef DEBUG_DETAIL_ON - LogFile.WriteHeapInfo("handler_uptime - End"); - #endif +#ifdef DEBUG_DETAIL_ON + LogFile.WriteHeapInfo("handler_uptime - End"); +#endif return ESP_OK; } - -esp_err_t handler_prevalue(httpd_req_t *req) { - #ifdef DEBUG_DETAIL_ON - LogFile.WriteHeapInfo("handler_prevalue - Start"); - ESP_LOGD(TAG, "handler_prevalue: %s", req->uri); - #endif +esp_err_t handler_prevalue(httpd_req_t *req) +{ +#ifdef DEBUG_DETAIL_ON + LogFile.WriteHeapInfo("handler_prevalue - Start"); + ESP_LOGD(TAG, "handler_prevalue: %s", req->uri); +#endif // Default usage message when handler gets called without any parameter - const std::string RESTUsageInfo = + const std::string RESTUsageInfo = "00: Handler usage:
" "- To retrieve actual PreValue, please provide only a numbersname, e.g. /setPreValue?numbers=main
" "- To set PreValue to a new value, please provide a numbersname and a value, e.g. /setPreValue?numbers=main&value=1234.5678
" @@ -909,82 +1341,92 @@ esp_err_t handler_prevalue(httpd_req_t *req) { httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*"); - if (httpd_req_get_url_query_str(req, _query, 100) == ESP_OK) { - #ifdef DEBUG_DETAIL_ON - ESP_LOGD(TAG, "Query: %s", _query); - #endif + if (httpd_req_get_url_query_str(req, _query, 100) == ESP_OK) + { +#ifdef DEBUG_DETAIL_ON + ESP_LOGD(TAG, "Query: %s", _query); +#endif - if (httpd_query_key_value(_query, "numbers", _numbersname, 50) != ESP_OK) { + if (httpd_query_key_value(_query, "numbers", _numbersname, 50) != ESP_OK) + { // If request is incomplete sReturnMessage = "E91: Query parameter incomplete or not valid!
" "Call /setPreValue to show REST API usage info and/or check documentation"; httpd_resp_send(req, sReturnMessage.c_str(), sReturnMessage.length()); - return ESP_FAIL; + return ESP_FAIL; } - if (httpd_query_key_value(_query, "value", _value, 20) == ESP_OK) { - #ifdef DEBUG_DETAIL_ON - ESP_LOGD(TAG, "Value: %s", _value); - #endif + if (httpd_query_key_value(_query, "value", _value, 20) == ESP_OK) + { +#ifdef DEBUG_DETAIL_ON + ESP_LOGD(TAG, "Value: %s", _value); +#endif } } - else { + else + { // if no parameter is provided, print handler usage httpd_resp_send(req, RESTUsageInfo.c_str(), RESTUsageInfo.length()); - return ESP_OK; - } + return ESP_OK; + } - if (strlen(_value) == 0) { + if (strlen(_value) == 0) + { // If no value is povided --> return actual PreValue sReturnMessage = flowctrl.GetPrevalue(std::string(_numbersname)); - if (sReturnMessage.empty()) { + if (sReturnMessage.empty()) + { sReturnMessage = "E92: Numbers name not found"; httpd_resp_send(req, sReturnMessage.c_str(), sReturnMessage.length()); return ESP_FAIL; } } - else { + else + { // New value is positive: Set PreValue to provided value and return value // New value is negative and actual RAW value is a valid number: Set PreValue to RAW value and return value - LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "REST API handler_prevalue called: numbersname: " + std::string(_numbersname) + - ", value: " + std::string(_value)); - if (!flowctrl.UpdatePrevalue(_value, _numbersname, true)) { + LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "REST API handler_prevalue called: numbersname: " + std::string(_numbersname) + ", value: " + std::string(_value)); + + if (!flowctrl.UpdatePrevalue(_value, _numbersname, true)) + { sReturnMessage = "E93: Update request rejected. Please check device logs for more details"; - httpd_resp_send(req, sReturnMessage.c_str(), sReturnMessage.length()); + httpd_resp_send(req, sReturnMessage.c_str(), sReturnMessage.length()); return ESP_FAIL; } sReturnMessage = flowctrl.GetPrevalue(std::string(_numbersname)); - if (sReturnMessage.empty()) { + if (sReturnMessage.empty()) + { sReturnMessage = "E94: Numbers name not found"; httpd_resp_send(req, sReturnMessage.c_str(), sReturnMessage.length()); return ESP_FAIL; } } - httpd_resp_send(req, sReturnMessage.c_str(), sReturnMessage.length()); + httpd_resp_send(req, sReturnMessage.c_str(), sReturnMessage.length()); - #ifdef DEBUG_DETAIL_ON - LogFile.WriteHeapInfo("handler_prevalue - End"); - #endif +#ifdef DEBUG_DETAIL_ON + LogFile.WriteHeapInfo("handler_prevalue - End"); +#endif return ESP_OK; } - -void task_autodoFlow(void *pvParameter) { +void task_autodoFlow(void *pvParameter) +{ int64_t fr_start, fr_delta_ms; bTaskAutoFlowCreated = true; - if (!isPlannedReboot && (esp_reset_reason() == ESP_RST_PANIC)) { + if (!isPlannedReboot && (esp_reset_reason() == ESP_RST_PANIC)) + { flowctrl.setActStatus("Initialization (delayed)"); - //#ifdef ENABLE_MQTT - //MQTTPublish(mqttServer_getMainTopic() + "/" + "status", "Initialization (delayed)", false); // Right now, not possible -> MQTT Service is going to be started later - //#endif //ENABLE_MQTT - vTaskDelay(60*5000 / portTICK_PERIOD_MS); // Wait 5 minutes to give time to do an OTA update or fetch the log + // #ifdef ENABLE_MQTT + // MQTTPublish(mqttServer_getMainTopic() + "/" + "status", "Initialization (delayed)", false); // Right now, not possible -> MQTT Service is going to be started later + // #endif //ENABLE_MQTT + vTaskDelay(60 * 5000 / portTICK_PERIOD_MS); // Wait 5 minutes to give time to do an OTA update or fetch the log } ESP_LOGD(TAG, "task_autodoFlow: start"); @@ -993,206 +1435,219 @@ void task_autodoFlow(void *pvParameter) { flowctrl.setAutoStartInterval(auto_interval); autostartIsEnabled = flowctrl.getIsAutoStart(); - if (isSetupModusActive()) { + if (isSetupModusActive()) + { LogFile.WriteToFile(ESP_LOG_INFO, TAG, "We are in Setup Mode -> Not starting Auto Flow!"); autostartIsEnabled = false; - std::string zw_time = getCurrentTimeString(LOGFILE_TIME_FORMAT); - flowctrl.doFlowTakeImageOnly(zw_time); + // 15.7.0 Setup Wizard cannot take a Reference Picture #2953 + // std::string zw_time = getCurrentTimeString(LOGFILE_TIME_FORMAT); + // flowctrl.doFlowTakeImageOnly(zw_time); } - if (autostartIsEnabled) { + if (autostartIsEnabled) + { LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Starting Flow..."); } - else { + else + { LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Autostart is not enabled -> Not starting Flow"); } - - while (autostartIsEnabled) { + + while (autostartIsEnabled) + { LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "----------------------------------------------------------------"); // Clear separation between runs - std::string _zw = "Round #" + std::to_string(++countRounds) + " started"; time_t roundStartTime = getUpTime(); - LogFile.WriteToFile(ESP_LOG_INFO, TAG, _zw); + + std::string _zw = "Round #" + std::to_string(++countRounds) + " started"; + LogFile.WriteToFile(ESP_LOG_INFO, TAG, _zw); + fr_start = esp_timer_get_time(); - if (flowisrunning) { - #ifdef DEBUG_DETAIL_ON - ESP_LOGD(TAG, "Autoflow: doFlow is already running!"); - #endif + if (flowisrunning) + { +#ifdef DEBUG_DETAIL_ON + ESP_LOGD(TAG, "Autoflow: doFlow is already running!"); +#endif } - else { - #ifdef DEBUG_DETAIL_ON - ESP_LOGD(TAG, "Autoflow: doFlow is started"); - #endif + else + { +#ifdef DEBUG_DETAIL_ON + ESP_LOGD(TAG, "Autoflow: doFlow is started"); +#endif flowisrunning = true; doflow(); - #ifdef DEBUG_DETAIL_ON - ESP_LOGD(TAG, "Remove older log files"); - #endif +#ifdef DEBUG_DETAIL_ON + ESP_LOGD(TAG, "Remove older log files"); +#endif LogFile.RemoveOldLogFile(); LogFile.RemoveOldDataLog(); } // Round finished -> Logfile - LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Round #" + std::to_string(countRounds) + - " completed (" + std::to_string(getUpTime() - roundStartTime) + " seconds)"); - + LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Round #" + std::to_string(countRounds) + " completed (" + std::to_string(getUpTime() - roundStartTime) + " seconds)"); + // CPU Temp -> Logfile LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "CPU Temperature: " + std::to_string((int)temperatureRead()) + "°C"); - + // WIFI Signal Strength (RSSI) -> Logfile LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "WIFI Signal (RSSI): " + std::to_string(get_WIFI_RSSI()) + "dBm"); // Check if time is synchronized (if NTP is configured) - if (getUseNtp() && !getTimeIsSet()) { + if (getUseNtp() && !getTimeIsSet()) + { LogFile.WriteToFile(ESP_LOG_WARN, TAG, "Time server is configured, but time is not yet set!"); StatusLED(TIME_CHECK, 1, false); } - #if (defined WLAN_USE_MESH_ROAMING && defined WLAN_USE_MESH_ROAMING_ACTIVATE_CLIENT_TRIGGERED_QUERIES) - wifiRoamingQuery(); - #endif - - // Scan channels and check if an AP with better RSSI is available, then disconnect and try to reconnect to AP with better RSSI - // NOTE: Keep this direct before the following task delay, because scan is done in blocking mode and this takes ca. 1,5 - 2s. - #ifdef WLAN_USE_ROAMING_BY_SCANNING - wifiRoamByScanning(); - #endif - +#if (defined WLAN_USE_MESH_ROAMING && defined WLAN_USE_MESH_ROAMING_ACTIVATE_CLIENT_TRIGGERED_QUERIES) + wifiRoamingQuery(); +#endif + +// Scan channels and check if an AP with better RSSI is available, then disconnect and try to reconnect to AP with better RSSI +// NOTE: Keep this direct before the following task delay, because scan is done in blocking mode and this takes ca. 1,5 - 2s. +#ifdef WLAN_USE_ROAMING_BY_SCANNING + wifiRoamByScanning(); +#endif + fr_delta_ms = (esp_timer_get_time() - fr_start) / 1000; - - if (auto_interval > fr_delta_ms) { - const TickType_t xDelay = (auto_interval - fr_delta_ms) / portTICK_PERIOD_MS; - ESP_LOGD(TAG, "Autoflow: sleep for: %ldms", (long) xDelay); - vTaskDelay( xDelay ); + + if (auto_interval > fr_delta_ms) + { + const TickType_t xDelay = (auto_interval - fr_delta_ms) / portTICK_PERIOD_MS; + ESP_LOGD(TAG, "Autoflow: sleep for: %ldms", (long)xDelay); + vTaskDelay(xDelay); } } - while(1) { + while (1) + { // Keep flow task running to handle necessary sub tasks like reboot handler, etc.. - vTaskDelay(2000 / portTICK_PERIOD_MS); + vTaskDelay(2000 / portTICK_PERIOD_MS); } - vTaskDelete(NULL); //Delete this task if it exits from the loop above + vTaskDelete(NULL); // Delete this task if it exits from the loop above xHandletask_autodoFlow = NULL; + ESP_LOGD(TAG, "task_autodoFlow: end"); } - -void InitializeFlowTask() { +void InitializeFlowTask(void) +{ BaseType_t xReturned; ESP_LOGD(TAG, "getESPHeapInfo: %s", getESPHeapInfo().c_str()); uint32_t stackSize = 16 * 1024; - xReturned = xTaskCreatePinnedToCore(&task_autodoFlow, "task_autodoFlow", stackSize, NULL, tskIDLE_PRIORITY+2, &xHandletask_autodoFlow, 0); - - if( xReturned != pdPASS ) { + xReturned = xTaskCreatePinnedToCore(&task_autodoFlow, "task_autodoFlow", stackSize, NULL, tskIDLE_PRIORITY + 2, &xHandletask_autodoFlow, 0); + + if (xReturned != pdPASS) + { LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Creation task_autodoFlow failed. Requested stack size:" + std::to_string(stackSize)); LogFile.WriteHeapInfo("Creation task_autodoFlow failed"); } - + ESP_LOGD(TAG, "getESPHeapInfo: %s", getESPHeapInfo().c_str()); } - -void register_server_main_flow_task_uri(httpd_handle_t server) { +void register_server_main_flow_task_uri(httpd_handle_t server) +{ ESP_LOGI(TAG, "server_main_flow_task - Registering URI handlers"); - - httpd_uri_t camuri = { }; - camuri.method = HTTP_GET; - camuri.uri = "/doinit"; - camuri.handler = handler_init; - camuri.user_ctx = (void*) "Light On"; + httpd_uri_t camuri = {}; + camuri.method = HTTP_GET; + + camuri.uri = "/doinit"; + camuri.handler = handler_init; + camuri.user_ctx = (void *)"Light On"; httpd_register_uri_handler(server, &camuri); // Legacy API => New: "/setPreValue" - camuri.uri = "/setPreValue.html"; - camuri.handler = handler_prevalue; - camuri.user_ctx = (void*) "Prevalue"; + camuri.uri = "/setPreValue.html"; + camuri.handler = handler_prevalue; + camuri.user_ctx = (void *)"Prevalue"; httpd_register_uri_handler(server, &camuri); - camuri.uri = "/setPreValue"; - camuri.handler = handler_prevalue; - camuri.user_ctx = (void*) "Prevalue"; + camuri.uri = "/setPreValue"; + camuri.handler = handler_prevalue; + camuri.user_ctx = (void *)"Prevalue"; httpd_register_uri_handler(server, &camuri); - camuri.uri = "/flow_start"; - camuri.handler = handler_flow_start; - camuri.user_ctx = (void*) "Flow Start"; + camuri.uri = "/flow_start"; + camuri.handler = handler_flow_start; + camuri.user_ctx = (void *)"Flow Start"; httpd_register_uri_handler(server, &camuri); - camuri.uri = "/statusflow.html"; - camuri.handler = handler_statusflow; - camuri.user_ctx = (void*) "Light Off"; + camuri.uri = "/statusflow.html"; + camuri.handler = handler_statusflow; + camuri.user_ctx = (void *)"Light Off"; httpd_register_uri_handler(server, &camuri); - camuri.uri = "/statusflow"; - camuri.handler = handler_statusflow; - camuri.user_ctx = (void*) "Light Off"; + camuri.uri = "/statusflow"; + camuri.handler = handler_statusflow; + camuri.user_ctx = (void *)"Light Off"; httpd_register_uri_handler(server, &camuri); // Legacy API => New: "/cpu_temperature" - camuri.uri = "/cputemp.html"; - camuri.handler = handler_cputemp; - camuri.user_ctx = (void*) "Light Off"; + camuri.uri = "/cputemp.html"; + camuri.handler = handler_cputemp; + camuri.user_ctx = (void *)"Light Off"; httpd_register_uri_handler(server, &camuri); - camuri.uri = "/cpu_temperature"; - camuri.handler = handler_cputemp; - camuri.user_ctx = (void*) "Light Off"; + camuri.uri = "/cpu_temperature"; + camuri.handler = handler_cputemp; + camuri.user_ctx = (void *)"Light Off"; httpd_register_uri_handler(server, &camuri); // Legacy API => New: "/rssi" - camuri.uri = "/rssi.html"; - camuri.handler = handler_rssi; - camuri.user_ctx = (void*) "Light Off"; + camuri.uri = "/rssi.html"; + camuri.handler = handler_rssi; + camuri.user_ctx = (void *)"Light Off"; httpd_register_uri_handler(server, &camuri); - camuri.uri = "/rssi"; - camuri.handler = handler_rssi; - camuri.user_ctx = (void*) "Light Off"; + camuri.uri = "/rssi"; + camuri.handler = handler_rssi; + camuri.user_ctx = (void *)"Light Off"; httpd_register_uri_handler(server, &camuri); - camuri.uri = "/uptime"; - camuri.handler = handler_uptime; - camuri.user_ctx = (void*) "Light Off"; + camuri.uri = "/uptime"; + camuri.handler = handler_uptime; + camuri.user_ctx = (void *)"Light Off"; httpd_register_uri_handler(server, &camuri); - camuri.uri = "/editflow"; - camuri.handler = handler_editflow; - camuri.user_ctx = (void*) "EditFlow"; - httpd_register_uri_handler(server, &camuri); - - // Legacy API => New: "/value" - camuri.uri = "/value.html"; - camuri.handler = handler_wasserzaehler; - camuri.user_ctx = (void*) "Value"; - httpd_register_uri_handler(server, &camuri); - - camuri.uri = "/value"; - camuri.handler = handler_wasserzaehler; - camuri.user_ctx = (void*) "Value"; + camuri.uri = "/editflow"; + camuri.handler = handler_editflow; + camuri.user_ctx = (void *)"EditFlow"; httpd_register_uri_handler(server, &camuri); // Legacy API => New: "/value" - camuri.uri = "/wasserzaehler.html"; - camuri.handler = handler_wasserzaehler; - camuri.user_ctx = (void*) "Wasserzaehler"; + camuri.uri = "/value.html"; + camuri.handler = handler_wasserzaehler; + camuri.user_ctx = (void *)"Value"; httpd_register_uri_handler(server, &camuri); - camuri.uri = "/json"; - camuri.handler = handler_json; - camuri.user_ctx = (void*) "JSON"; + camuri.uri = "/value"; + camuri.handler = handler_wasserzaehler; + camuri.user_ctx = (void *)"Value"; httpd_register_uri_handler(server, &camuri); - camuri.uri = "/heap"; - camuri.handler = handler_get_heap; - camuri.user_ctx = (void*) "Heap"; + // Legacy API => New: "/value" + camuri.uri = "/wasserzaehler.html"; + camuri.handler = handler_wasserzaehler; + camuri.user_ctx = (void *)"Wasserzaehler"; httpd_register_uri_handler(server, &camuri); - camuri.uri = "/stream"; - camuri.handler = handler_stream; - camuri.user_ctx = (void*) "stream"; + camuri.uri = "/json"; + camuri.handler = handler_json; + camuri.user_ctx = (void *)"JSON"; + httpd_register_uri_handler(server, &camuri); + + camuri.uri = "/heap"; + camuri.handler = handler_get_heap; + camuri.user_ctx = (void *)"Heap"; + httpd_register_uri_handler(server, &camuri); + + camuri.uri = "/stream"; + camuri.handler = handler_stream; + camuri.user_ctx = (void *)"stream"; httpd_register_uri_handler(server, &camuri); } diff --git a/code/components/jomjol_flowcontroll/MainFlowControl.h b/code/components/jomjol_flowcontroll/MainFlowControl.h index 8ede3be0..8a2d1c41 100644 --- a/code/components/jomjol_flowcontroll/MainFlowControl.h +++ b/code/components/jomjol_flowcontroll/MainFlowControl.h @@ -10,25 +10,78 @@ #include "CImageBasis.h" #include "ClassFlowControll.h" +typedef struct +{ + framesize_t ImageFrameSize = FRAMESIZE_VGA; // 0 - 10 + gainceiling_t ImageGainceiling; // Image gain (GAINCEILING_x2, x4, x8, x16, x32, x64 or x128) + + int ImageQuality; // 0 - 63 + int ImageBrightness; // (-2 to 2) - set brightness + int ImageContrast; //-2 - 2 + int ImageSaturation; //-2 - 2 + int ImageSharpness; //-2 - 2 + bool ImageAutoSharpness; + int ImageSpecialEffect; // 0 - 6 + int ImageWbMode; // 0 to 4 - if awb_gain enabled (0 - Auto, 1 - Sunny, 2 - Cloudy, 3 - Office, 4 - Home) + int ImageAwb; // white balance enable (0 or 1) + int ImageAwbGain; // Auto White Balance enable (0 or 1) + int ImageAec; // auto exposure off (1 or 0) + int ImageAec2; // automatic exposure sensor (0 or 1) + int ImageAeLevel; // auto exposure levels (-2 to 2) + int ImageAecValue; // set exposure manually (0-1200) + int ImageAgc; // auto gain off (1 or 0) + int ImageAgcGain; // set gain manually (0 - 30) + int ImageBpc; // black pixel correction + int ImageWpc; // white pixel correction + int ImageRawGma; // (1 or 0) + int ImageLenc; // lens correction (1 or 0) + int ImageHmirror; // (0 or 1) flip horizontally + int ImageVflip; // Invert image (0 or 1) + int ImageDcw; // downsize enable (1 or 0) + + int ImageWidth; + int ImageHeight; + + int ImageLedIntensity; + + bool ImageZoomEnabled; + int ImageZoomMode; + int ImageZoomOffsetX; + int ImageZoomOffsetY; + int ImageZoomSize; + + int WaitBeforePicture; + bool isImageSize; + + bool CameraInitSuccessful; + bool changedCameraSettings; + bool DemoMode; + bool SaveAllFiles; +} camera_flow_config_temp_t; + +extern camera_flow_config_temp_t CFstatus; extern ClassFlowControll flowctrl; +esp_err_t setCCstatusToCFstatus(void); // CCstatus >>> CFstatus +esp_err_t setCFstatusToCCstatus(void); // CFstatus >>> CCstatus +esp_err_t setCFstatusToCam(void); // CFstatus >>> Kamera void register_server_main_flow_task_uri(httpd_handle_t server); -void CheckIsPlannedReboot(); -bool getIsPlannedReboot(); +void CheckIsPlannedReboot(void); +bool getIsPlannedReboot(void); -void InitializeFlowTask(); -void DeleteMainFlowTask(); -bool isSetupModusActive(); +void InitializeFlowTask(void); +void DeleteMainFlowTask(void); +bool isSetupModusActive(void); -int getCountFlowRounds(); +int getCountFlowRounds(void); #ifdef ENABLE_MQTT esp_err_t MQTTCtrlFlowStart(std::string _topic); -#endif //ENABLE_MQTT +#endif // ENABLE_MQTT esp_err_t GetRawJPG(httpd_req_t *req); esp_err_t GetJPG(std::string _filename, httpd_req_t *req); -#endif //MAINFLOWCONTROL_H +#endif // MAINFLOWCONTROL_H diff --git a/code/components/jomjol_helper/Helper.cpp b/code/components/jomjol_helper/Helper.cpp index ed2c9524..c794646a 100644 --- a/code/components/jomjol_helper/Helper.cpp +++ b/code/components/jomjol_helper/Helper.cpp @@ -1,4 +1,4 @@ -//#pragma warning(disable : 4996) +// #pragma warning(disable : 4996) #include "freertos/FreeRTOS.h" #include "freertos/task.h" @@ -14,7 +14,8 @@ #include #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif #include #ifdef __cplusplus @@ -32,7 +33,7 @@ extern "C" { #include "esp_vfs_fat.h" #include "../sdmmc_common.h" -static const char* TAG = "HELPER"; +static const char *TAG = "HELPER"; using namespace std; @@ -42,191 +43,206 @@ sdmmc_cid_t SDCardCid; sdmmc_csd_t SDCardCsd; bool SDCardIsMMC; -// #define DEBUG_DETAIL_ON +// #define DEBUG_DETAIL_ON ///////////////////////////////////////////////////////////////////////////////////////////// -string getESPHeapInfo(){ +string getESPHeapInfo() +{ string espInfoResultStr = ""; char aMsgBuf[80]; - size_t aFreeHeapSize = heap_caps_get_free_size(MALLOC_CAP_8BIT); + size_t aFreeHeapSize = heap_caps_get_free_size(MALLOC_CAP_8BIT); - size_t aFreeSPIHeapSize = heap_caps_get_free_size(MALLOC_CAP_8BIT | MALLOC_CAP_SPIRAM); - size_t aFreeInternalHeapSize = heap_caps_get_free_size(MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL); + size_t aFreeSPIHeapSize = heap_caps_get_free_size(MALLOC_CAP_8BIT | MALLOC_CAP_SPIRAM); + size_t aFreeInternalHeapSize = heap_caps_get_free_size(MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL); size_t aHeapLargestFreeBlockSize = heap_caps_get_largest_free_block(MALLOC_CAP_8BIT | MALLOC_CAP_SPIRAM); size_t aHeapIntLargestFreeBlockSize = heap_caps_get_largest_free_block(MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL); - size_t aMinFreeHeapSize = heap_caps_get_minimum_free_size(MALLOC_CAP_8BIT | MALLOC_CAP_SPIRAM); - size_t aMinFreeInternalHeapSize = heap_caps_get_minimum_free_size(MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL); + size_t aMinFreeHeapSize = heap_caps_get_minimum_free_size(MALLOC_CAP_8BIT | MALLOC_CAP_SPIRAM); + size_t aMinFreeInternalHeapSize = heap_caps_get_minimum_free_size(MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL); - - sprintf(aMsgBuf,"Heap Total: %ld", (long) aFreeHeapSize); + sprintf(aMsgBuf, "Heap Total: %ld", (long)aFreeHeapSize); espInfoResultStr += string(aMsgBuf); - sprintf(aMsgBuf," | SPI Free: %ld", (long) aFreeSPIHeapSize); + sprintf(aMsgBuf, " | SPI Free: %ld", (long)aFreeSPIHeapSize); espInfoResultStr += string(aMsgBuf); - sprintf(aMsgBuf," | SPI Large Block: %ld", (long) aHeapLargestFreeBlockSize); + sprintf(aMsgBuf, " | SPI Large Block: %ld", (long)aHeapLargestFreeBlockSize); espInfoResultStr += string(aMsgBuf); - sprintf(aMsgBuf," | SPI Min Free: %ld", (long) aMinFreeHeapSize); + sprintf(aMsgBuf, " | SPI Min Free: %ld", (long)aMinFreeHeapSize); espInfoResultStr += string(aMsgBuf); - sprintf(aMsgBuf," | Int Free: %ld", (long) (aFreeInternalHeapSize)); + sprintf(aMsgBuf, " | Int Free: %ld", (long)(aFreeInternalHeapSize)); espInfoResultStr += string(aMsgBuf); - sprintf(aMsgBuf," | Int Large Block: %ld", (long) aHeapIntLargestFreeBlockSize); + sprintf(aMsgBuf, " | Int Large Block: %ld", (long)aHeapIntLargestFreeBlockSize); espInfoResultStr += string(aMsgBuf); - sprintf(aMsgBuf," | Int Min Free: %ld", (long) (aMinFreeInternalHeapSize)); + sprintf(aMsgBuf, " | Int Min Free: %ld", (long)(aMinFreeInternalHeapSize)); espInfoResultStr += string(aMsgBuf); - - return espInfoResultStr; + + return espInfoResultStr; } - size_t getESPHeapSize() { - return heap_caps_get_free_size(MALLOC_CAP_8BIT); + return heap_caps_get_free_size(MALLOC_CAP_8BIT); } - -size_t getInternalESPHeapSize() +size_t getInternalESPHeapSize() { - return heap_caps_get_free_size(MALLOC_CAP_8BIT| MALLOC_CAP_INTERNAL); + return heap_caps_get_free_size(MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL); } - -string getSDCardPartitionSize(){ +string getSDCardPartitionSize() +{ FATFS *fs; - uint32_t fre_clust, tot_sect; + 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 + /* 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 - //ESP_LOGD(TAG, "%d MB total drive space (Sector size [bytes]: %d)", (int)tot_sect, (int)fs->ssize); + // ESP_LOGD(TAG, "%d MB total drive space (Sector size [bytes]: %d)", (int)tot_sect, (int)fs->ssize); return std::to_string(tot_sect); } - -string getSDCardFreePartitionSpace(){ +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 + uint32_t fre_clust, fre_sect; - //ESP_LOGD(TAG, "%d MB free drive space (Sector size [bytes]: %d)", (int)fre_sect, (int)fs->ssize); + /* 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 + + // ESP_LOGD(TAG, "%d MB free drive space (Sector size [bytes]: %d)", (int)fre_sect, (int)fs->ssize); return std::to_string(fre_sect); } - -string getSDCardPartitionAllocationSize(){ +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; + uint32_t fre_clust, allocation_size; - //ESP_LOGD(TAG, "SD Card Partition Allocation Size: %d bytes", allocation_size); + /* Get volume information and free clusters of drive 0 */ + f_getfree("0:", (DWORD *)&fre_clust, &fs); + allocation_size = fs->ssize; + + // ESP_LOGD(TAG, "SD Card Partition Allocation Size: %d bytes", allocation_size); return std::to_string(allocation_size); } - -void SaveSDCardInfo(sdmmc_card_t* card) { +void SaveSDCardInfo(sdmmc_card_t *card) +{ SDCardCid = card->cid; - SDCardCsd = card->csd; + SDCardCsd = card->csd; SDCardIsMMC = card->is_mmc; } - -string getSDCardManufacturer(){ +string getSDCardManufacturer() +{ string SDCardManufacturer = SDCardParseManufacturerIDs(SDCardCid.mfg_id); - //ESP_LOGD(TAG, "SD Card Manufacturer: %s", SDCardManufacturer.c_str()); - + // ESP_LOGD(TAG, "SD Card Manufacturer: %s", SDCardManufacturer.c_str()); + return (SDCardManufacturer + " (ID: " + std::to_string(SDCardCid.mfg_id) + ")"); } - -string getSDCardName(){ +string getSDCardName() +{ char *SDCardName = SDCardCid.name; - //ESP_LOGD(TAG, "SD Card Name: %s", SDCardName); + // ESP_LOGD(TAG, "SD Card Name: %s", 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) - //ESP_LOGD(TAG, "SD Card Capacity: %s", std::to_string(SDCardCapacity).c_str()); +string getSDCardCapacity() +{ + int SDCardCapacity = SDCardCsd.capacity / (1024 / SDCardCsd.sector_size) / 1024; // total sectors * sector size --> Byte to MB (1024*1024) + // ESP_LOGD(TAG, "SD Card Capacity: %s", std::to_string(SDCardCapacity).c_str()); return std::to_string(SDCardCapacity); } - -string getSDCardSectorSize(){ +string getSDCardSectorSize() +{ int SDCardSectorSize = SDCardCsd.sector_size; - //ESP_LOGD(TAG, "SD Card Sector Size: %s bytes", std::to_string(SDCardSectorSize).c_str()); + // ESP_LOGD(TAG, "SD Card Sector Size: %s bytes", std::to_string(SDCardSectorSize).c_str()); return std::to_string(SDCardSectorSize); } /////////////////////////////////////////////////////////////////////////////////////////////// -void memCopyGen(uint8_t* _source, uint8_t* _target, int _size) +void memCopyGen(uint8_t *_source, uint8_t *_target, int _size) { - for (int i = 0; i < _size; ++i) - *(_target + i) = *(_source + i); + for (int i = 0; i < _size; ++i) + { + *(_target + i) = *(_source + i); + } } - std::string FormatFileName(std::string input) { #ifdef ISWINDOWS_TRUE - input.erase(0, 1); - std::string os = "/"; - std::string ns = "\\"; - FindReplace(input, os, ns); + input.erase(0, 1); + std::string os = "/"; + std::string ns = "\\"; + FindReplace(input, os, ns); #endif - return input; + return input; } +std::size_t file_size(const std::string &file_name) +{ + std::ifstream file(file_name.c_str(), std::ios::in | std::ios::binary); -std::size_t file_size(const std::string& file_name) { - std::ifstream file(file_name.c_str(),std::ios::in | std::ios::binary); - if (!file) return 0; - file.seekg (0, std::ios::end); - return static_cast(file.tellg()); + if (!file) + { + return 0; + } + + file.seekg(0, std::ios::end); + return static_cast(file.tellg()); } +void FindReplace(std::string &line, std::string &oldString, std::string &newString) +{ + const size_t oldSize = oldString.length(); -void FindReplace(std::string& line, std::string& oldString, std::string& newString) { - const size_t oldSize = oldString.length(); + // do nothing if line is shorter than the string to find + if (oldSize > line.length()) + { + return; + } - // do nothing if line is shorter than the string to find - if (oldSize > line.length()) return; + const size_t newSize = newString.length(); - const size_t newSize = newString.length(); - for (size_t pos = 0; ; pos += newSize) { - // Locate the substring to replace - pos = line.find(oldString, pos); - if (pos == std::string::npos) return; - if (oldSize == newSize) { - // if they're same size, use std::string::replace - line.replace(pos, oldSize, newString); - } - else { - // if not same size, replace by erasing and inserting - line.erase(pos, oldSize); - line.insert(pos, newString); - } - } + for (size_t pos = 0;; pos += newSize) + { + // Locate the substring to replace + pos = line.find(oldString, pos); + + if (pos == std::string::npos) + { + return; + } + + if (oldSize == newSize) + { + // if they're same size, use std::string::replace + line.replace(pos, oldSize, newString); + } + else + { + // if not same size, replace by erasing and inserting + line.erase(pos, oldSize); + line.insert(pos, newString); + } + } } - /** * Create a folder and its parent folders as needed */ @@ -237,56 +253,63 @@ bool MakeDir(std::string path) LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Creating folder " + path + "..."); bool bSuccess = false; - int nRC = ::mkdir( path.c_str(), 0775 ); - if( nRC == -1 ) - { - switch( errno ) { - case ENOENT: - //parent didn't exist, try to create it - parent = path.substr(0, path.find_last_of('/')); - LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Need to create parent folder first: " + parent); - if(MakeDir(parent)) { - //Now, try to create again. - bSuccess = 0 == ::mkdir( path.c_str(), 0775 ); - } - else { - LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Failed to create parent folder: " + parent); - bSuccess = false; - } - break; + int nRC = ::mkdir(path.c_str(), 0775); - case EEXIST: - //Done! - bSuccess = true; - break; - - default: - LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Failed to create folder: " + path + " (errno: " + std::to_string(errno) + ")"); - bSuccess = false; - break; - } - } - else { - bSuccess = true; + if (nRC == -1) + { + switch (errno) + { + case ENOENT: + // parent didn't exist, try to create it + parent = path.substr(0, path.find_last_of('/')); + LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Need to create parent folder first: " + parent); + + if (MakeDir(parent)) + { + // Now, try to create again. + bSuccess = 0 == ::mkdir(path.c_str(), 0775); + } + else + { + LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Failed to create parent folder: " + parent); + bSuccess = false; + } + break; + + case EEXIST: + // Done! + bSuccess = true; + break; + + default: + LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Failed to create folder: " + path + " (errno: " + std::to_string(errno) + ")"); + bSuccess = false; + break; + } + } + else + { + bSuccess = true; } - return bSuccess; + return bSuccess; } - bool ctype_space(const char c, string adddelimiter) { if (c == ' ' || c == '\t' || c == '\r' || c == '\n' || c == 11) { return true; } + if (adddelimiter.find(c) != string::npos) + { return true; + } return false; } - string trim(string istring, string adddelimiter) { bool trimmed = false; @@ -313,76 +336,87 @@ string trim(string istring, string adddelimiter) } } - size_t findDelimiterPos(string input, string delimiter) { size_t pos = std::string::npos; - size_t zw; + // size_t zw; string akt_del; for (int anz = 0; anz < delimiter.length(); ++anz) { akt_del = delimiter[anz]; - if ((zw = input.find(akt_del)) != std::string::npos) + size_t zw = input.find(akt_del); + + if (zw != std::string::npos) { - if (pos != std::string::npos) + if ((pos != std::string::npos) && (zw < pos)) { - if (zw < pos) - pos = zw; + pos = zw; } else + { pos = zw; + } } } + return pos; } - bool RenameFile(string from, string to) { -// ESP_LOGI(logTag, "Deleting file: %s", fn.c_str()); + // ESP_LOGI(logTag, "Deleting file: %s", fn.c_str()); /* Delete file */ - FILE* fpSourceFile = fopen(from.c_str(), "rb"); - if (!fpSourceFile) // Sourcefile existiert nicht sonst gibt es einen Fehler beim Kopierversuch! + FILE *fpSourceFile = fopen(from.c_str(), "rb"); + + // Sourcefile existiert nicht sonst gibt es einen Fehler beim Kopierversuch! + if (!fpSourceFile) { ESP_LOGE(TAG, "DeleteFile: File %s existiert nicht!", from.c_str()); return false; } + fclose(fpSourceFile); rename(from.c_str(), to.c_str()); + return true; } - bool FileExists(string filename) { - FILE* fpSourceFile = fopen(filename.c_str(), "rb"); - if (!fpSourceFile) // Sourcefile existiert nicht sonst gibt es einen Fehler beim Kopierversuch! + FILE *fpSourceFile = fopen(filename.c_str(), "rb"); + + // Sourcefile existiert nicht sonst gibt es einen Fehler beim Kopierversuch! + if (!fpSourceFile) { return false; } - fclose(fpSourceFile); - return true; -} + fclose(fpSourceFile); + + return true; +} bool DeleteFile(string fn) { -// ESP_LOGI(logTag, "Deleting file: %s", fn.c_str()); + // ESP_LOGI(logTag, "Deleting file: %s", fn.c_str()); /* Delete file */ - FILE* fpSourceFile = fopen(fn.c_str(), "rb"); - if (!fpSourceFile) // Sourcefile existiert nicht sonst gibt es einen Fehler beim Kopierversuch! + FILE *fpSourceFile = fopen(fn.c_str(), "rb"); + + // Sourcefile existiert nicht sonst gibt es einen Fehler beim Kopierversuch! + if (!fpSourceFile) { ESP_LOGD(TAG, "DeleteFile: File %s existiert nicht!", fn.c_str()); return false; } + fclose(fpSourceFile); unlink(fn.c_str()); - return true; -} + return true; +} bool CopyFile(string input, string output) { @@ -396,14 +430,16 @@ bool CopyFile(string input, string output) } char cTemp; - FILE* fpSourceFile = fopen(input.c_str(), "rb"); - if (!fpSourceFile) // Sourcefile existiert nicht sonst gibt es einen Fehler beim Kopierversuch! + FILE *fpSourceFile = fopen(input.c_str(), "rb"); + + // Sourcefile existiert nicht sonst gibt es einen Fehler beim Kopierversuch! + if (!fpSourceFile) { ESP_LOGD(TAG, "File %s existiert nicht!", input.c_str()); return false; } - FILE* fpTargetFile = fopen(output.c_str(), "wb"); + FILE *fpTargetFile = fopen(output.c_str(), "wb"); // Code Section @@ -418,53 +454,60 @@ bool CopyFile(string input, string output) fclose(fpSourceFile); fclose(fpTargetFile); ESP_LOGD(TAG, "File copied: %s to %s", input.c_str(), output.c_str()); + return true; } - string getFileFullFileName(string filename) { size_t lastpos = filename.find_last_of('/'); if (lastpos == string::npos) + { return ""; + } -// ESP_LOGD(TAG, "Last position: %d", lastpos); + // ESP_LOGD(TAG, "Last position: %d", lastpos); string zw = filename.substr(lastpos + 1, filename.size() - lastpos); return zw; } - string getDirectory(string filename) { size_t lastpos = filename.find('/'); if (lastpos == string::npos) + { lastpos = filename.find('\\'); + } if (lastpos == string::npos) + { return ""; + } -// ESP_LOGD(TAG, "Directory: %d", lastpos); + // ESP_LOGD(TAG, "Directory: %d", lastpos); string zw = filename.substr(0, lastpos - 1); return zw; } - string getFileType(string filename) { size_t lastpos = filename.rfind(".", filename.length()); size_t neu_pos; + while ((neu_pos = filename.find(".", lastpos + 1)) > -1) { lastpos = neu_pos; } if (lastpos == string::npos) + { return ""; + } string zw = filename.substr(lastpos + 1, filename.size() - lastpos); zw = toUpper(zw); @@ -472,172 +515,213 @@ string getFileType(string filename) return zw; } - /* recursive mkdir */ -int mkdir_r(const char *dir, const mode_t mode) { - char tmp[FILE_PATH_MAX]; - char *p = NULL; - struct stat sb; - size_t len; - - /* copy path */ - len = strnlen (dir, FILE_PATH_MAX); - if (len == 0 || len == FILE_PATH_MAX) { - return -1; - } - memcpy (tmp, dir, len); - tmp[len] = '\0'; +int mkdir_r(const char *dir, const mode_t mode) +{ + char tmp[FILE_PATH_MAX]; + char *p = NULL; + struct stat sb; + size_t len; - /* remove trailing slash */ - if(tmp[len - 1] == '/') { - tmp[len - 1] = '\0'; - } + /* copy path */ + len = strnlen(dir, FILE_PATH_MAX); - /* check if path exists and is a directory */ - if (stat (tmp, &sb) == 0) { - if (S_ISDIR (sb.st_mode)) { - return 0; - } - } - - /* recursive mkdir */ - for(p = tmp + 1; *p; p++) { - if(*p == '/') { - *p = 0; - /* test path */ - if (stat(tmp, &sb) != 0) { - /* path does not exist - create directory */ - if (mkdir(tmp, mode) < 0) { - return -1; - } - } else if (!S_ISDIR(sb.st_mode)) { - /* not a directory */ - return -1; - } - *p = '/'; - } - } - /* test path */ - if (stat(tmp, &sb) != 0) { - /* path does not exist - create directory */ - if (mkdir(tmp, mode) < 0) { - return -1; - } - } else if (!S_ISDIR(sb.st_mode)) { - /* not a directory */ - return -1; - } - return 0; + if (len == 0 || len == FILE_PATH_MAX) + { + return -1; + } + + memcpy(tmp, dir, len); + tmp[len] = '\0'; + + /* remove trailing slash */ + if (tmp[len - 1] == '/') + { + tmp[len - 1] = '\0'; + } + + /* check if path exists and is a directory */ + if (stat(tmp, &sb) == 0) + { + if (S_ISDIR(sb.st_mode)) + { + return 0; + } + } + + /* recursive mkdir */ + for (p = tmp + 1; *p; p++) + { + if (*p == '/') + { + *p = 0; + + /* test path */ + if (stat(tmp, &sb) != 0) + { + /* path does not exist - create directory */ + if (mkdir(tmp, mode) < 0) + { + return -1; + } + } + else if (!S_ISDIR(sb.st_mode)) + { + /* not a directory */ + return -1; + } + + *p = '/'; + } + } + + /* test path */ + if (stat(tmp, &sb) != 0) + { + /* path does not exist - create directory */ + if (mkdir(tmp, mode) < 0) + { + return -1; + } + } + else if (!S_ISDIR(sb.st_mode)) + { + /* not a directory */ + return -1; + } + + return 0; } - string toUpper(string in) { for (int i = 0; i < in.length(); ++i) + { in[i] = toupper(in[i]); - + } + return in; } - string toLower(string in) { for (int i = 0; i < in.length(); ++i) + { in[i] = tolower(in[i]); - + } + return in; } - // CPU Temp extern "C" uint8_t temprature_sens_read(); float temperatureRead() { - return (temprature_sens_read() - 32) / 1.8; + return (temprature_sens_read() - 32) / 1.8; } - -time_t addDays(time_t startTime, int days) { - struct tm* tm = localtime(&startTime); +time_t addDays(time_t startTime, int days) +{ + struct tm *tm = localtime(&startTime); tm->tm_mday += days; return mktime(tm); } - -int removeFolder(const char* folderPath, const char* logTag) { - //ESP_LOGD(logTag, "Delete content in path %s", folderPath); +int removeFolder(const char *folderPath, const char *logTag) +{ + // ESP_LOGD(logTag, "Delete content in path %s", folderPath); DIR *dir = opendir(folderPath); - if (!dir) { - ESP_LOGE(logTag, "Failed to stat dir: %s", folderPath); - return -1; - } - struct dirent *entry; - int deleted = 0; - while ((entry = readdir(dir)) != NULL) { - std::string path = string(folderPath) + "/" + entry->d_name; - if (entry->d_type == DT_REG) { - //ESP_LOGD(logTag, "Delete file %s", path.c_str()); - if (unlink(path.c_str()) == 0) { - deleted ++; - } else { + if (!dir) + { + ESP_LOGE(logTag, "Failed to stat dir: %s", folderPath); + return -1; + } + + struct dirent *entry; + int deleted = 0; + + while ((entry = readdir(dir)) != NULL) + { + std::string path = string(folderPath) + "/" + entry->d_name; + + if (entry->d_type == DT_REG) + { + // ESP_LOGD(logTag, "Delete file %s", path.c_str()); + if (unlink(path.c_str()) == 0) + { + deleted++; + } + else + { ESP_LOGE(logTag, "can't delete file: %s", path.c_str()); } - } else if (entry->d_type == DT_DIR) { + } + else if (entry->d_type == DT_DIR) + { deleted += removeFolder(path.c_str(), logTag); } - } - - closedir(dir); - if (rmdir(folderPath) != 0) { + } + + closedir(dir); + + if (rmdir(folderPath) != 0) + { ESP_LOGE(logTag, "can't delete folder: %s", folderPath); } + ESP_LOGD(logTag, "%d files in folder %s deleted.", deleted, folderPath); return deleted; } - std::vector HelperZerlegeZeile(std::string input, std::string _delimiter = "") { std::vector Output; std::string delimiter = " =,"; - if (_delimiter.length() > 0){ - delimiter = _delimiter; - } + + if (_delimiter.length() > 0) + { + delimiter = _delimiter; + } return ZerlegeZeile(input, delimiter); } - std::vector ZerlegeZeile(std::string input, std::string delimiter) { std::vector Output; - /* The input can have multiple formats: + /* The input can have multiple formats: * - key = value - * - key = value1 value2 value3 ... - * - key value1 value2 value3 ... - * + * - key = value1 value2 value3 ... + * - key value1 value2 value3 ... + * * Examples: * - ImageSize = VGA - * - IO0 = input disabled 10 false false + * - IO0 = input disabled 10 false false * - main.dig1 28 144 55 100 false - * + * * This causes issues eg. if a password key has a whitespace or equal sign in its value. * As a workaround and to not break any legacy usage, we enforce to only use the * equal sign, if the key is "password" - */ - if ((input.find("password") != string::npos) || (input.find("Token") != string::npos)) { // Line contains a password, use the equal sign as the only delimiter and only split on first occurrence + */ + if ((input.find("password") != string::npos) || (input.find("Token") != string::npos)) + { + // Line contains a password, use the equal sign as the only delimiter and only split on first occurrence size_t pos = input.find("="); Output.push_back(trim(input.substr(0, pos), "")); - Output.push_back(trim(input.substr(pos +1, string::npos), "")); + Output.push_back(trim(input.substr(pos + 1, string::npos), "")); } - else { // Legacy Mode - input = trim(input, delimiter); // sonst werden delimiter am Ende (z.B. == im Token) gelöscht) + else + { + // Legacy Mode + input = trim(input, delimiter); // sonst werden delimiter am Ende (z.B. == im Token) gelöscht) size_t pos = findDelimiterPos(input, delimiter); std::string token; - while (pos != std::string::npos) { + + while (pos != std::string::npos) + { token = input.substr(0, pos); token = trim(token, delimiter); Output.push_back(token); @@ -645,34 +729,35 @@ std::vector ZerlegeZeile(std::string input, std::string delimiter) input = trim(input, delimiter); pos = findDelimiterPos(input, delimiter); } + Output.push_back(input); } return Output; - } +std::string ReplaceString(std::string subject, const std::string &search, const std::string &replace) +{ + size_t pos = 0; -std::string ReplaceString(std::string subject, const std::string& search, - const std::string& replace) { - size_t pos = 0; - while ((pos = subject.find(search, pos)) != std::string::npos) { - subject.replace(pos, search.length(), replace); - pos += replace.length(); - } - return subject; + while ((pos = subject.find(search, pos)) != std::string::npos) + { + subject.replace(pos, search.length(), replace); + pos += replace.length(); + } + + return subject; } - /* Source: https://git.kernel.org/pub/scm/utils/mmc/mmc-utils.git/tree/lsmmc.c */ /* SD Card Manufacturer Database */ -struct SDCard_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 sd_database[] = { @@ -857,242 +942,267 @@ struct SDCard_Manufacturer_database mmc_database[] = { }; /* Parse SD Card Manufacturer Database */ -string SDCardParseManufacturerIDs(int id) +string SDCardParseManufacturerIDs(int id) { - if (SDCardIsMMC) - { - unsigned int id_cnt = sizeof(mmc_database) / sizeof(struct SDCard_Manufacturer_database); - string ret_val = ""; - - for (int i = 0; i < id_cnt; i++) + if (SDCardIsMMC) { - if (mmc_database[i].id == id) - { - return mmc_database[i].manufacturer; - } - else - { - ret_val = "ID unknown (not in DB)"; - } + unsigned int id_cnt = sizeof(mmc_database) / sizeof(struct SDCard_Manufacturer_database); + string ret_val = ""; + + for (int i = 0; i < id_cnt; i++) + { + if (mmc_database[i].id == id) + { + return mmc_database[i].manufacturer; + } + else + { + ret_val = "ID unknown (not in DB)"; + } + } + + return ret_val; } - return ret_val; - } - - else - { - unsigned int id_cnt = sizeof(sd_database) / sizeof(struct SDCard_Manufacturer_database); - string ret_val = ""; - - for (int i = 0; i < id_cnt; i++) + else { - if (sd_database[i].id == id) - { - return sd_database[i].manufacturer; - } - else - { - ret_val = "ID unknown (not in DB)"; - } - } + unsigned int id_cnt = sizeof(sd_database) / sizeof(struct SDCard_Manufacturer_database); + string ret_val = ""; - return ret_val; - } + for (int i = 0; i < id_cnt; i++) + { + if (sd_database[i].id == id) + { + return sd_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); + 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; + } + else + { + stream << _zw; + } - if (_anzNachkomma > 0) - { - stream << std::fixed << std::setprecision(_anzNachkomma) << _in; - return stream.str(); - } - else - { - stream << _zw; - } - - - return stream.str(); + return stream.str(); } +string getMac(void) +{ + uint8_t macInt[6]; + char macFormated[6 * 2 + 5 + 1]; // AA:BB:CC:DD:EE:FF -string getMac(void) { - uint8_t macInt[6]; - char macFormated[6*2 + 5 + 1]; // AA:BB:CC:DD:EE:FF + esp_read_mac(macInt, ESP_MAC_WIFI_STA); + sprintf(macFormated, "%02X:%02X:%02X:%02X:%02X:%02X", macInt[0], macInt[1], macInt[2], macInt[3], macInt[4], macInt[5]); - esp_read_mac(macInt, ESP_MAC_WIFI_STA); - sprintf(macFormated, "%02X:%02X:%02X:%02X:%02X:%02X", macInt[0], macInt[1], macInt[2], macInt[3], macInt[4], macInt[5]); - - return macFormated; + return macFormated; } - -void setSystemStatusFlag(SystemStatusFlag_t flag) { +void setSystemStatusFlag(SystemStatusFlag_t flag) +{ systemStatus = systemStatus | flag; // set bit char buf[20]; snprintf(buf, sizeof(buf), "0x%08X", getSystemStatus()); - LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "New System Status: " + std::string(buf)); + LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "New System Status: " + std::string(buf)); } - -void clearSystemStatusFlag(SystemStatusFlag_t flag) { +void clearSystemStatusFlag(SystemStatusFlag_t flag) +{ systemStatus = systemStatus | ~flag; // clear bit char buf[20]; snprintf(buf, sizeof(buf), "0x%08X", getSystemStatus()); - LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "New System Status: " + std::string(buf)); + LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "New System Status: " + std::string(buf)); } - -int getSystemStatus(void) { - return systemStatus; +int getSystemStatus(void) +{ + return systemStatus; } +bool isSetSystemStatusFlag(SystemStatusFlag_t flag) +{ + // ESP_LOGE(TAG, "Flag (0x%08X) is set (0x%08X): %d", flag, systemStatus , ((systemStatus & flag) == flag)); -bool isSetSystemStatusFlag(SystemStatusFlag_t flag) { - //ESP_LOGE(TAG, "Flag (0x%08X) is set (0x%08X): %d", flag, systemStatus , ((systemStatus & flag) == flag)); - - if ((systemStatus & flag) == flag) { + if ((systemStatus & flag) == flag) + { return true; } - else { + else + { return false; } } - -time_t getUpTime(void) { - return (uint32_t)(esp_timer_get_time()/1000/1000); // in seconds +time_t getUpTime(void) +{ + return (uint32_t)(esp_timer_get_time() / 1000 / 1000); // in seconds } - -string getResetReason(void) { +string getResetReason(void) +{ std::string reasonText; - switch(esp_reset_reason()) { - case ESP_RST_POWERON: reasonText = "Power-on event (or reset button)"; break; //!< Reset due to power-on event - case ESP_RST_EXT: reasonText = "External pin"; break; //!< Reset by external pin (not applicable for ESP32) - case ESP_RST_SW: reasonText = "Via esp_restart"; break; //!< Software reset via esp_restart - case ESP_RST_PANIC: reasonText = "Exception/panic"; break; //!< Software reset due to exception/panic - case ESP_RST_INT_WDT: reasonText = "Interrupt watchdog"; break; //!< Reset (software or hardware) due to interrupt watchdog - case ESP_RST_TASK_WDT: reasonText = "Task watchdog"; break; //!< Reset due to task watchdog - case ESP_RST_WDT: reasonText = "Other watchdogs"; break; //!< Reset due to other watchdogs - case ESP_RST_DEEPSLEEP: reasonText = "Exiting deep sleep mode"; break; //!< Reset after exiting deep sleep mode - case ESP_RST_BROWNOUT: reasonText = "Brownout"; break; //!< Brownout reset (software or hardware) - case ESP_RST_SDIO: reasonText = "SDIO"; break; //!< Reset over SDIO + switch (esp_reset_reason()) + { + case ESP_RST_POWERON: + reasonText = "Power-on event (or reset button)"; + break; //!< Reset due to power-on event + case ESP_RST_EXT: + reasonText = "External pin"; + break; //!< Reset by external pin (not applicable for ESP32) + case ESP_RST_SW: + reasonText = "Via esp_restart"; + break; //!< Software reset via esp_restart + case ESP_RST_PANIC: + reasonText = "Exception/panic"; + break; //!< Software reset due to exception/panic + case ESP_RST_INT_WDT: + reasonText = "Interrupt watchdog"; + break; //!< Reset (software or hardware) due to interrupt watchdog + case ESP_RST_TASK_WDT: + reasonText = "Task watchdog"; + break; //!< Reset due to task watchdog + case ESP_RST_WDT: + reasonText = "Other watchdogs"; + break; //!< Reset due to other watchdogs + case ESP_RST_DEEPSLEEP: + reasonText = "Exiting deep sleep mode"; + break; //!< Reset after exiting deep sleep mode + case ESP_RST_BROWNOUT: + reasonText = "Brownout"; + break; //!< Brownout reset (software or hardware) + case ESP_RST_SDIO: + reasonText = "SDIO"; + break; //!< Reset over SDIO - case ESP_RST_UNKNOWN: //!< Reset reason can not be determined - default: - reasonText = "Unknown"; + case ESP_RST_UNKNOWN: //!< Reset reason can not be determined + default: + reasonText = "Unknown"; } - return reasonText; -} + return reasonText; +} /** * Returns the current uptime formated ad xxf xxh xxm [xxs] */ -std::string getFormatedUptime(bool compact) { +std::string getFormatedUptime(bool compact) +{ char buf[20]; - #pragma GCC diagnostic ignored "-Wformat-truncation" +#pragma GCC diagnostic ignored "-Wformat-truncation" - int uptime = getUpTime(); // in seconds + int uptime = getUpTime(); // in seconds - int days = int(floor(uptime / (3600*24))); - int hours = int(floor((uptime - days * 3600*24) / (3600))); - int minutes = int(floor((uptime - days * 3600*24 - hours * 3600) / (60))); - int seconds = uptime - days * 3600*24 - hours * 3600 - minutes * 60; - - if (compact) { + int days = int(floor(uptime / (3600 * 24))); + int hours = int(floor((uptime - days * 3600 * 24) / (3600))); + int minutes = int(floor((uptime - days * 3600 * 24 - hours * 3600) / (60))); + int seconds = uptime - days * 3600 * 24 - hours * 3600 - minutes * 60; + + if (compact) + { snprintf(buf, sizeof(buf), "%dd%02dh%02dm%02ds", days, hours, minutes, seconds); } - else { + else + { snprintf(buf, sizeof(buf), "%3dd %02dh %02dm %02ds", days, hours, minutes, seconds); } return std::string(buf); } - -const char* get404(void) { - return -"
\n\n\n\n"
-"        _\n"
-"    .__(.)< ( oh oh! This page does not exist! )\n"
-"    \\___)\n"
-"\n\n"
-"                You could try your luck here!
\n" -""; // Make sure we load the overview page -} - - -std::string UrlDecode(const std::string& value) +const char *get404(void) { - std::string result; - result.reserve(value.size()); - - for (std::size_t i = 0; i < value.size(); ++i) - { - auto ch = value[i]; - - if (ch == '%' && (i + 2) < value.size()) - { - auto hex = value.substr(i + 1, 2); - auto dec = static_cast(std::strtol(hex.c_str(), nullptr, 16)); - result.push_back(dec); - i += 2; - } - else if (ch == '+') - { - result.push_back(' '); - } - else - { - result.push_back(ch); - } - } - - return result; + return "
\n\n\n\n"
+		   "        _\n"
+		   "    .__(.)< ( oh oh! This page does not exist! )\n"
+		   "    \\___)\n"
+		   "\n\n"
+		   "                You could try your luck here!
\n" + ""; // Make sure we load the overview page } +std::string UrlDecode(const std::string &value) +{ + std::string result; + result.reserve(value.size()); -bool replaceString(std::string& s, std::string const& toReplace, std::string const& replaceWith) { - return replaceString(s, toReplace, replaceWith, true); + for (std::size_t i = 0; i < value.size(); ++i) + { + auto ch = value[i]; + + if (ch == '%' && (i + 2) < value.size()) + { + auto hex = value.substr(i + 1, 2); + auto dec = static_cast(std::strtol(hex.c_str(), nullptr, 16)); + result.push_back(dec); + i += 2; + } + else if (ch == '+') + { + result.push_back(' '); + } + else + { + result.push_back(ch); + } + } + + return result; } - -bool replaceString(std::string& s, std::string const& toReplace, std::string const& replaceWith, bool logIt) { - std::size_t pos = s.find(toReplace); - - if (pos == std::string::npos) { // Not found - return false; - } - - std::string old = s; - s.replace(pos, toReplace.length(), replaceWith); - if (logIt) { - LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Migrated Configfile line '" + old + "' to '" + s + "'"); - } - return true; +bool replaceString(std::string &s, std::string const &toReplace, std::string const &replaceWith) +{ + return replaceString(s, toReplace, replaceWith, true); } +bool replaceString(std::string &s, std::string const &toReplace, std::string const &replaceWith, bool logIt) +{ + std::size_t pos = s.find(toReplace); -bool isInString(std::string& s, std::string const& toFind) { - std::size_t pos = s.find(toFind); + if (pos == std::string::npos) + { + // Not found + return false; + } - if (pos == std::string::npos) { // Not found - return false; - } - return true; + std::string old = s; + s.replace(pos, toReplace.length(), replaceWith); + + if (logIt) + { + LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Migrated Configfile line '" + old + "' to '" + s + "'"); + } + + return true; +} + +bool isInString(std::string &s, std::string const &toFind) +{ + std::size_t pos = s.find(toFind); + + if (pos == std::string::npos) + { + // Not found + return false; + } + + return true; } diff --git a/code/components/jomjol_image_proc/CRotateImage.cpp b/code/components/jomjol_image_proc/CRotateImage.cpp index 12d44154..bd1c91e7 100644 --- a/code/components/jomjol_image_proc/CRotateImage.cpp +++ b/code/components/jomjol_image_proc/CRotateImage.cpp @@ -1,353 +1,309 @@ -#include -#include "CRotateImage.h" -#include "psram.h" - -static const char *TAG = "C ROTATE IMG"; - -CRotateImage::CRotateImage(std::string _name, CImageBasis *_org, CImageBasis *_temp, bool _flip) : CImageBasis(_name) -{ - rgb_image = _org->rgb_image; - channels = _org->channels; - width = _org->width; - height = _org->height; - bpp = _org->bpp; - externalImage = true; - ImageTMP = _temp; - ImageOrg = _org; - islocked = false; - doflip = _flip; -} - - -void CRotateImage::Mirror(){ - int memsize = width * height * channels; - uint8_t* odata; - if (ImageTMP) - { - odata = ImageTMP->RGBImageLock(); - } - else - { - odata = (unsigned char*)malloc_psram_heap(std::string(TAG) + "->odata", memsize, MALLOC_CAP_SPIRAM); - } - - - int x_source, y_source; - stbi_uc* p_target; - stbi_uc* p_source; - - RGBImageLock(); - - for (int x = 0; x < width; ++x) - for (int y = 0; y < height; ++y) - { - p_target = odata + (channels * (y * width + x)); - - x_source = width - x; - y_source = y; - - p_source = rgb_image + (channels * (y_source * width + x_source)); - for (int _channels = 0; _channels < channels; ++_channels) - p_target[_channels] = p_source[_channels]; - } - - // memcpy(rgb_image, odata, memsize); - memCopy(odata, rgb_image, memsize); - if (!ImageTMP) - free_psram_heap(std::string(TAG) + "->odata", odata); - - if (ImageTMP) - ImageTMP->RGBImageRelease(); - - RGBImageRelease(); -} - -void CRotateImage::Rotate(float _angle, int _centerx, int _centery) -{ - int org_width, org_height; - float m[2][3]; - - float x_center = _centerx; - float y_center = _centery; - _angle = _angle / 180 * M_PI; - - if (doflip) - { - org_width = width; - org_height = height; - height = org_width; - width = org_height; - x_center = x_center - (org_width/2) + (org_height/2); - y_center = y_center + (org_width/2) - (org_height/2); - if (ImageOrg) - { - ImageOrg->height = height; - ImageOrg->width = width; - } - } - else - { - org_width = width; - org_height = height; - } - - m[0][0] = cos(_angle); - m[0][1] = sin(_angle); - m[0][2] = (1 - m[0][0]) * x_center - m[0][1] * y_center; - - m[1][0] = -m[0][1]; - m[1][1] = m[0][0]; - m[1][2] = m[0][1] * x_center + (1 - m[0][0]) * y_center; - - if (doflip) - { - m[0][2] = m[0][2] + (org_width/2) - (org_height/2); - m[1][2] = m[1][2] - (org_width/2) + (org_height/2); - } - - int memsize = width * height * channels; - uint8_t* odata; - if (ImageTMP) - { - odata = ImageTMP->RGBImageLock(); - } - else - { - odata = (unsigned char*)malloc_psram_heap(std::string(TAG) + "->odata", memsize, MALLOC_CAP_SPIRAM); - } - - - int x_source, y_source; - stbi_uc* p_target; - stbi_uc* p_source; - - RGBImageLock(); - - for (int x = 0; x < width; ++x) - for (int y = 0; y < height; ++y) - { - p_target = odata + (channels * (y * width + x)); - - x_source = int(m[0][0] * x + m[0][1] * y); - y_source = int(m[1][0] * x + m[1][1] * y); - - x_source += int(m[0][2]); - y_source += int(m[1][2]); - - if ((x_source >= 0) && (x_source < org_width) && (y_source >= 0) && (y_source < org_height)) - { - p_source = rgb_image + (channels * (y_source * org_width + x_source)); - for (int _channels = 0; _channels < channels; ++_channels) - p_target[_channels] = p_source[_channels]; - } - else - { - for (int _channels = 0; _channels < channels; ++_channels) - p_target[_channels] = 255; - } - } - - // memcpy(rgb_image, odata, memsize); - memCopy(odata, rgb_image, memsize); - - if (!ImageTMP) - { - free_psram_heap(std::string(TAG) + "->odata", odata); - } - if (ImageTMP) - ImageTMP->RGBImageRelease(); - - RGBImageRelease(); -} - - - -void CRotateImage::RotateAntiAliasing(float _angle, int _centerx, int _centery) -{ - int org_width, org_height; - float m[2][3]; - - float x_center = _centerx; - float y_center = _centery; - _angle = _angle / 180 * M_PI; - - if (doflip) - { - org_width = width; - org_height = height; - height = org_width; - width = org_height; - x_center = x_center - (org_width/2) + (org_height/2); - y_center = y_center + (org_width/2) - (org_height/2); - if (ImageOrg) - { - ImageOrg->height = height; - ImageOrg->width = width; - } - } - else - { - org_width = width; - org_height = height; - } - - m[0][0] = cos(_angle); - m[0][1] = sin(_angle); - m[0][2] = (1 - m[0][0]) * x_center - m[0][1] * y_center; - - m[1][0] = -m[0][1]; - m[1][1] = m[0][0]; - m[1][2] = m[0][1] * x_center + (1 - m[0][0]) * y_center; - - if (doflip) - { - m[0][2] = m[0][2] + (org_width/2) - (org_height/2); - m[1][2] = m[1][2] - (org_width/2) + (org_height/2); - } - - int memsize = width * height * channels; - uint8_t* odata; - if (ImageTMP) - { - odata = ImageTMP->RGBImageLock(); - } - else - { - odata = (unsigned char*)malloc_psram_heap(std::string(TAG) + "->odata", memsize, MALLOC_CAP_SPIRAM); - } - - - int x_source_1, y_source_1, x_source_2, y_source_2; - float x_source, y_source; - float quad_ul, quad_ur, quad_ol, quad_or; - stbi_uc* p_target; - stbi_uc *p_source_ul, *p_source_ur, *p_source_ol, *p_source_or; - - RGBImageLock(); - - for (int x = 0; x < width; ++x) - for (int y = 0; y < height; ++y) - { - p_target = odata + (channels * (y * width + x)); - - x_source = (m[0][0] * x + m[0][1] * y); - y_source = (m[1][0] * x + m[1][1] * y); - - x_source += (m[0][2]); - y_source += (m[1][2]); - - x_source_1 = (int)x_source; - x_source_2 = x_source_1 + 1; - y_source_1 = (int)y_source; - y_source_2 = y_source_1 + 1; - - quad_ul = (x_source_2 - x_source) * (y_source_2 - y_source); - quad_ur = (1- (x_source_2 - x_source)) * (y_source_2 - y_source); - quad_or = (x_source_2 - x_source) * (1-(y_source_2 - y_source)); - quad_ol = (1- (x_source_2 - x_source)) * (1-(y_source_2 - y_source)); - - - if ((x_source_1 >= 0) && (x_source_2 < org_width) && (y_source_1 >= 0) && (y_source_2 < org_height)) - { - p_source_ul = rgb_image + (channels * (y_source_1 * org_width + x_source_1)); - p_source_ur = rgb_image + (channels * (y_source_1 * org_width + x_source_2)); - p_source_or = rgb_image + (channels * (y_source_2 * org_width + x_source_1)); - p_source_ol = rgb_image + (channels * (y_source_2 * org_width + x_source_2)); - for (int _channels = 0; _channels < channels; ++_channels) - { - p_target[_channels] = (int)((float)p_source_ul[_channels] * quad_ul - + (float)p_source_ur[_channels] * quad_ur - + (float)p_source_or[_channels] * quad_or - + (float)p_source_ol[_channels] * quad_ol); - } - } - else - { - for (int _channels = 0; _channels < channels; ++_channels) - p_target[_channels] = 255; - } - } - - // memcpy(rgb_image, odata, memsize); - memCopy(odata, rgb_image, memsize); - - if (!ImageTMP) - { - free_psram_heap(std::string(TAG) + "->odata", odata); - } - if (ImageTMP) - ImageTMP->RGBImageRelease(); - - RGBImageRelease(); -} - - -void CRotateImage::Rotate(float _angle) -{ -// ESP_LOGD(TAG, "width %d, height %d", width, height); - Rotate(_angle, width / 2, height / 2); -} - -void CRotateImage::RotateAntiAliasing(float _angle) -{ -// ESP_LOGD(TAG, "width %d, height %d", width, height); - RotateAntiAliasing(_angle, width / 2, height / 2); -} - -void CRotateImage::Translate(int _dx, int _dy) -{ - int memsize = width * height * channels; - uint8_t* odata; - if (ImageTMP) - { - odata = ImageTMP->RGBImageLock(); - } - else - { - odata = (unsigned char*)malloc_psram_heap(std::string(TAG) + "->odata", memsize, MALLOC_CAP_SPIRAM); - } - - - - int x_source, y_source; - stbi_uc* p_target; - stbi_uc* p_source; - - RGBImageLock(); - - for (int x = 0; x < width; ++x) - for (int y = 0; y < height; ++y) - { - p_target = odata + (channels * (y * width + x)); - - x_source = x - _dx; - y_source = y - _dy; - - if ((x_source >= 0) && (x_source < width) && (y_source >= 0) && (y_source < height)) - { - p_source = rgb_image + (channels * (y_source * width + x_source)); - for (int _channels = 0; _channels < channels; ++_channels) - p_target[_channels] = p_source[_channels]; - } - else - { - for (int _channels = 0; _channels < channels; ++_channels) - p_target[_channels] = 255; - } - } - - // memcpy(rgb_image, odata, memsize); - memCopy(odata, rgb_image, memsize); - if (!ImageTMP) - { - free_psram_heap(std::string(TAG) + "->odata", odata); - } - - if (ImageTMP) - { - ImageTMP->RGBImageRelease(); - } - RGBImageRelease(); - -} - +#include +#include "CRotateImage.h" +#include "psram.h" + +static const char *TAG = "C ROTATE IMG"; + +CRotateImage::CRotateImage(std::string _name, CImageBasis *_org, CImageBasis *_temp, bool _flip) : CImageBasis(_name) +{ + rgb_image = _org->rgb_image; + channels = _org->channels; + width = _org->width; + height = _org->height; + bpp = _org->bpp; + externalImage = true; + ImageTMP = _temp; + ImageOrg = _org; + islocked = false; + doflip = _flip; +} + +void CRotateImage::Rotate(float _angle, int _centerx, int _centery) +{ + int org_width, org_height; + float m[2][3]; + + float x_center = _centerx; + float y_center = _centery; + _angle = _angle / 180 * M_PI; + + if (doflip) + { + org_width = width; + org_height = height; + height = org_width; + width = org_height; + x_center = x_center - (org_width/2) + (org_height/2); + y_center = y_center + (org_width/2) - (org_height/2); + if (ImageOrg) + { + ImageOrg->height = height; + ImageOrg->width = width; + } + } + else + { + org_width = width; + org_height = height; + } + + m[0][0] = cos(_angle); + m[0][1] = sin(_angle); + m[0][2] = (1 - m[0][0]) * x_center - m[0][1] * y_center; + + m[1][0] = -m[0][1]; + m[1][1] = m[0][0]; + m[1][2] = m[0][1] * x_center + (1 - m[0][0]) * y_center; + + if (doflip) + { + m[0][2] = m[0][2] + (org_width/2) - (org_height/2); + m[1][2] = m[1][2] - (org_width/2) + (org_height/2); + } + + int memsize = width * height * channels; + uint8_t* odata; + if (ImageTMP) + { + odata = ImageTMP->RGBImageLock(); + } + else + { + odata = (unsigned char*)malloc_psram_heap(std::string(TAG) + "->odata", memsize, MALLOC_CAP_SPIRAM); + } + + + int x_source, y_source; + stbi_uc* p_target; + stbi_uc* p_source; + + RGBImageLock(); + + for (int x = 0; x < width; ++x) + for (int y = 0; y < height; ++y) + { + p_target = odata + (channels * (y * width + x)); + + x_source = int(m[0][0] * x + m[0][1] * y); + y_source = int(m[1][0] * x + m[1][1] * y); + + x_source += int(m[0][2]); + y_source += int(m[1][2]); + + if ((x_source >= 0) && (x_source < org_width) && (y_source >= 0) && (y_source < org_height)) + { + p_source = rgb_image + (channels * (y_source * org_width + x_source)); + for (int _channels = 0; _channels < channels; ++_channels) + p_target[_channels] = p_source[_channels]; + } + else + { + for (int _channels = 0; _channels < channels; ++_channels) + p_target[_channels] = 255; + } + } + + // memcpy(rgb_image, odata, memsize); + memCopy(odata, rgb_image, memsize); + + if (!ImageTMP) + { + free_psram_heap(std::string(TAG) + "->odata", odata); + } + if (ImageTMP) + ImageTMP->RGBImageRelease(); + + RGBImageRelease(); +} + + + +void CRotateImage::RotateAntiAliasing(float _angle, int _centerx, int _centery) +{ + int org_width, org_height; + float m[2][3]; + + float x_center = _centerx; + float y_center = _centery; + _angle = _angle / 180 * M_PI; + + if (doflip) + { + org_width = width; + org_height = height; + height = org_width; + width = org_height; + x_center = x_center - (org_width/2) + (org_height/2); + y_center = y_center + (org_width/2) - (org_height/2); + if (ImageOrg) + { + ImageOrg->height = height; + ImageOrg->width = width; + } + } + else + { + org_width = width; + org_height = height; + } + + m[0][0] = cos(_angle); + m[0][1] = sin(_angle); + m[0][2] = (1 - m[0][0]) * x_center - m[0][1] * y_center; + + m[1][0] = -m[0][1]; + m[1][1] = m[0][0]; + m[1][2] = m[0][1] * x_center + (1 - m[0][0]) * y_center; + + if (doflip) + { + m[0][2] = m[0][2] + (org_width/2) - (org_height/2); + m[1][2] = m[1][2] - (org_width/2) + (org_height/2); + } + + int memsize = width * height * channels; + uint8_t* odata; + if (ImageTMP) + { + odata = ImageTMP->RGBImageLock(); + } + else + { + odata = (unsigned char*)malloc_psram_heap(std::string(TAG) + "->odata", memsize, MALLOC_CAP_SPIRAM); + } + + + int x_source_1, y_source_1, x_source_2, y_source_2; + float x_source, y_source; + float quad_ul, quad_ur, quad_ol, quad_or; + stbi_uc* p_target; + stbi_uc *p_source_ul, *p_source_ur, *p_source_ol, *p_source_or; + + RGBImageLock(); + + for (int x = 0; x < width; ++x) + for (int y = 0; y < height; ++y) + { + p_target = odata + (channels * (y * width + x)); + + x_source = (m[0][0] * x + m[0][1] * y); + y_source = (m[1][0] * x + m[1][1] * y); + + x_source += (m[0][2]); + y_source += (m[1][2]); + + x_source_1 = (int)x_source; + x_source_2 = x_source_1 + 1; + y_source_1 = (int)y_source; + y_source_2 = y_source_1 + 1; + + quad_ul = (x_source_2 - x_source) * (y_source_2 - y_source); + quad_ur = (1- (x_source_2 - x_source)) * (y_source_2 - y_source); + quad_or = (x_source_2 - x_source) * (1-(y_source_2 - y_source)); + quad_ol = (1- (x_source_2 - x_source)) * (1-(y_source_2 - y_source)); + + + if ((x_source_1 >= 0) && (x_source_2 < org_width) && (y_source_1 >= 0) && (y_source_2 < org_height)) + { + p_source_ul = rgb_image + (channels * (y_source_1 * org_width + x_source_1)); + p_source_ur = rgb_image + (channels * (y_source_1 * org_width + x_source_2)); + p_source_or = rgb_image + (channels * (y_source_2 * org_width + x_source_1)); + p_source_ol = rgb_image + (channels * (y_source_2 * org_width + x_source_2)); + for (int _channels = 0; _channels < channels; ++_channels) + { + p_target[_channels] = (int)((float)p_source_ul[_channels] * quad_ul + + (float)p_source_ur[_channels] * quad_ur + + (float)p_source_or[_channels] * quad_or + + (float)p_source_ol[_channels] * quad_ol); + } + } + else + { + for (int _channels = 0; _channels < channels; ++_channels) + p_target[_channels] = 255; + } + } + + // memcpy(rgb_image, odata, memsize); + memCopy(odata, rgb_image, memsize); + + if (!ImageTMP) + { + free_psram_heap(std::string(TAG) + "->odata", odata); + } + if (ImageTMP) + ImageTMP->RGBImageRelease(); + + RGBImageRelease(); +} + + +void CRotateImage::Rotate(float _angle) +{ +// ESP_LOGD(TAG, "width %d, height %d", width, height); + Rotate(_angle, width / 2, height / 2); +} + +void CRotateImage::RotateAntiAliasing(float _angle) +{ +// ESP_LOGD(TAG, "width %d, height %d", width, height); + RotateAntiAliasing(_angle, width / 2, height / 2); +} + +void CRotateImage::Translate(int _dx, int _dy) +{ + int memsize = width * height * channels; + uint8_t* odata; + if (ImageTMP) + { + odata = ImageTMP->RGBImageLock(); + } + else + { + odata = (unsigned char*)malloc_psram_heap(std::string(TAG) + "->odata", memsize, MALLOC_CAP_SPIRAM); + } + + + + int x_source, y_source; + stbi_uc* p_target; + stbi_uc* p_source; + + RGBImageLock(); + + for (int x = 0; x < width; ++x) + for (int y = 0; y < height; ++y) + { + p_target = odata + (channels * (y * width + x)); + + x_source = x - _dx; + y_source = y - _dy; + + if ((x_source >= 0) && (x_source < width) && (y_source >= 0) && (y_source < height)) + { + p_source = rgb_image + (channels * (y_source * width + x_source)); + for (int _channels = 0; _channels < channels; ++_channels) + p_target[_channels] = p_source[_channels]; + } + else + { + for (int _channels = 0; _channels < channels; ++_channels) + p_target[_channels] = 255; + } + } + + // memcpy(rgb_image, odata, memsize); + memCopy(odata, rgb_image, memsize); + if (!ImageTMP) + { + free_psram_heap(std::string(TAG) + "->odata", odata); + } + + if (ImageTMP) + { + ImageTMP->RGBImageRelease(); + } + RGBImageRelease(); + +} + diff --git a/code/components/jomjol_image_proc/CRotateImage.h b/code/components/jomjol_image_proc/CRotateImage.h index 30c758d3..6b7b542e 100644 --- a/code/components/jomjol_image_proc/CRotateImage.h +++ b/code/components/jomjol_image_proc/CRotateImage.h @@ -1,29 +1,28 @@ -#pragma once - -#ifndef CROTATEIMAGE_H -#define CROTATEIMAGE_H - -#include "CImageBasis.h" - - -class CRotateImage: public CImageBasis -{ - - public: - CImageBasis *ImageTMP, *ImageOrg; - bool doflip; - CRotateImage(std::string name, std::string _image, bool _flip = false) : CImageBasis(name, _image) {ImageTMP = NULL; ImageOrg = NULL; doflip = _flip;}; - CRotateImage(std::string name, uint8_t* _rgb_image, int _channels, int _width, int _height, int _bpp, bool _flip = false) : CImageBasis(name, _rgb_image, _channels, _width, _height, _bpp) {ImageTMP = NULL; ImageOrg = NULL; doflip = _flip;}; - CRotateImage(std::string name, CImageBasis *_org, CImageBasis *_temp, bool _flip = false); - - void Rotate(float _angle); - void RotateAntiAliasing(float _angle); - - void Rotate(float _angle, int _centerx, int _centery); - void RotateAntiAliasing(float _angle, int _centerx, int _centery); - - void Translate(int _dx, int _dy); - void Mirror(); -}; - +#pragma once + +#ifndef CROTATEIMAGE_H +#define CROTATEIMAGE_H + +#include "CImageBasis.h" + + +class CRotateImage: public CImageBasis +{ + + public: + CImageBasis *ImageTMP, *ImageOrg; + bool doflip; + CRotateImage(std::string name, std::string _image, bool _flip = false) : CImageBasis(name, _image) {ImageTMP = NULL; ImageOrg = NULL; doflip = _flip;}; + CRotateImage(std::string name, uint8_t* _rgb_image, int _channels, int _width, int _height, int _bpp, bool _flip = false) : CImageBasis(name, _rgb_image, _channels, _width, _height, _bpp) {ImageTMP = NULL; ImageOrg = NULL; doflip = _flip;}; + CRotateImage(std::string name, CImageBasis *_org, CImageBasis *_temp, bool _flip = false); + + void Rotate(float _angle); + void RotateAntiAliasing(float _angle); + + void Rotate(float _angle, int _centerx, int _centery); + void RotateAntiAliasing(float _angle, int _centerx, int _centery); + + void Translate(int _dx, int _dy); +}; + #endif //CROTATEIMAGE_H \ No newline at end of file diff --git a/param-docs/expert-params.txt b/param-docs/expert-params.txt index c2fe85c7..db38cc92 100644 --- a/param-docs/expert-params.txt +++ b/param-docs/expert-params.txt @@ -1,8 +1,29 @@ -demo WaitBeforeTakingPicture -ImageQuality -ImageSize -FixedExposure +CamFrameSize +CamGainceiling +CamQuality +CamAutoSharpness +CamSharpness +CamSpecialEffect +CamWbMode +CamAwb +CamAwbGain +CamAec +CamAec2 +CamAeLevel +CamAecValue +CamAgc +CamAgcGain +CamBpc +CamWpc +CamRawGma +CamLenc +CamDcw +CamZoom +CamZoomSize +CamZoomOffsetX +CamZoomOffsetY +demo SearchFieldX SearchFieldY AlignmentAlgo diff --git a/param-docs/parameter-pages/TakeImage/CamAeLevel.md b/param-docs/parameter-pages/TakeImage/CamAeLevel.md new file mode 100644 index 00000000..8f562828 --- /dev/null +++ b/param-docs/parameter-pages/TakeImage/CamAeLevel.md @@ -0,0 +1,15 @@ +# Parameter `CamAeLevel` +Default Value: `0` + +!!! Warning + This is an **Expert Parameter**! Only change it if you understand what it does! + +!!! Note + This parameter can also be set on the Reference Image configuration page! + +!!! Note + After changing this parameter you need to update your reference image and alignment markers! + +Auto-Exposure Compensation. Lower values produce darker image. + +Range (`-2` .. `2`) diff --git a/param-docs/parameter-pages/TakeImage/CamAec.md b/param-docs/parameter-pages/TakeImage/CamAec.md new file mode 100644 index 00000000..b6e4712b --- /dev/null +++ b/param-docs/parameter-pages/TakeImage/CamAec.md @@ -0,0 +1,13 @@ +# Parameter `CamAec` +Default Value: `true` + +!!! Warning + This is an **Expert Parameter**! Only change it if you understand what it does! + +!!! Note + This parameter can also be set on the Reference Image configuration page! + +!!! Note + After changing this parameter you need to update your reference image and alignment markers! + +Auto-Exposure Control Algorithm diff --git a/param-docs/parameter-pages/TakeImage/CamAec2.md b/param-docs/parameter-pages/TakeImage/CamAec2.md new file mode 100644 index 00000000..c6b402fb --- /dev/null +++ b/param-docs/parameter-pages/TakeImage/CamAec2.md @@ -0,0 +1,13 @@ +# Parameter `CamAec2` +Default Value: `false` + +!!! Warning + This is an **Expert Parameter**! Only change it if you understand what it does! + +!!! Note + This parameter can also be set on the Reference Image configuration page! + +!!! Note + After changing this parameter you need to update your reference image and alignment markers! + +Switch to "Auto-Exposure Control 2" Algorithm. This may resolve some over-exposure and under-exposure issues. diff --git a/param-docs/parameter-pages/TakeImage/CamAecValue.md b/param-docs/parameter-pages/TakeImage/CamAecValue.md new file mode 100644 index 00000000..e03c3b65 --- /dev/null +++ b/param-docs/parameter-pages/TakeImage/CamAecValue.md @@ -0,0 +1,15 @@ +# Parameter `CamAecValue` +Default Value: `0` + +!!! Warning + This is an **Expert Parameter**! Only change it if you understand what it does! + +!!! Note + This parameter can also be set on the Reference Image configuration page! + +!!! Note + After changing this parameter you need to update your reference image and alignment markers! + +set Manuall-Exposure Control Value + +Range (`0` .. `1200`) diff --git a/param-docs/parameter-pages/TakeImage/CamAgc.md b/param-docs/parameter-pages/TakeImage/CamAgc.md new file mode 100644 index 00000000..e6c48769 --- /dev/null +++ b/param-docs/parameter-pages/TakeImage/CamAgc.md @@ -0,0 +1,10 @@ +# Parameter `CamAgc` +Default Value: `true` + +!!! Warning + This is an **Expert Parameter**! Only change it if you understand what it does! + +!!! Note + After changing this parameter you need to update your reference image and alignment markers! + +This sets the Automatic Gain Control, how the camera responds to the overall level of light in the image. diff --git a/param-docs/parameter-pages/TakeImage/CamAgcGain.md b/param-docs/parameter-pages/TakeImage/CamAgcGain.md new file mode 100644 index 00000000..b383dc1e --- /dev/null +++ b/param-docs/parameter-pages/TakeImage/CamAgcGain.md @@ -0,0 +1,13 @@ +# Parameter `CamAgcGain` +Default Value: ` ` + +!!! Warning + This is an **Expert Parameter**! Only change it if you understand what it does! + +!!! Note + After changing this parameter you need to update your reference image and alignment markers! + +!!! Note + This is visible when AGC is off. Gain is an amplification of the values read from the image sensor. + +Range (`0` .. `30`) diff --git a/param-docs/parameter-pages/TakeImage/CamAutoSharpness.md b/param-docs/parameter-pages/TakeImage/CamAutoSharpness.md new file mode 100644 index 00000000..48ebfd7b --- /dev/null +++ b/param-docs/parameter-pages/TakeImage/CamAutoSharpness.md @@ -0,0 +1,13 @@ +# Parameter `CamAutoSharpness` +Default Value: `false` + +!!! Warning + This is an **Expert Parameter**! Only change it if you understand what it does! + +!!! Note + This parameter can also be set on the Reference Image configuration page! + +!!! Note + After changing this parameter you need to update your reference image and alignment markers! + +AutoSharpness diff --git a/param-docs/parameter-pages/TakeImage/CamAwb.md b/param-docs/parameter-pages/TakeImage/CamAwb.md new file mode 100644 index 00000000..9a5a4143 --- /dev/null +++ b/param-docs/parameter-pages/TakeImage/CamAwb.md @@ -0,0 +1,10 @@ +# Parameter `CamAwb` +Default Value: ` ` + +!!! Warning + This is an **Expert Parameter**! Only change it if you understand what it does! + +!!! Note + After changing this parameter you need to update your reference image and alignment markers! + +Auto White Balance diff --git a/param-docs/parameter-pages/TakeImage/CamAwbGain.md b/param-docs/parameter-pages/TakeImage/CamAwbGain.md new file mode 100644 index 00000000..86e9bb83 --- /dev/null +++ b/param-docs/parameter-pages/TakeImage/CamAwbGain.md @@ -0,0 +1,10 @@ +# Parameter `CamAwbGain` +Default Value: ` ` + +!!! Warning + This is an **Expert Parameter**! Only change it if you understand what it does! + +!!! Note + After changing this parameter you need to update your reference image and alignment markers! + +Auto White Balance Gain diff --git a/param-docs/parameter-pages/TakeImage/CamBpc.md b/param-docs/parameter-pages/TakeImage/CamBpc.md new file mode 100644 index 00000000..1cef3c07 --- /dev/null +++ b/param-docs/parameter-pages/TakeImage/CamBpc.md @@ -0,0 +1,10 @@ +# Parameter `CamBpc` +Default Value: `true` + +!!! Warning + This is an **Expert Parameter**! Only change it if you understand what it does! + +!!! Note + After changing this parameter you need to update your reference image and alignment markers! + +Black Pixel Correction diff --git a/param-docs/parameter-pages/TakeImage/CamBrightness.md b/param-docs/parameter-pages/TakeImage/CamBrightness.md new file mode 100644 index 00000000..41e6a9d9 --- /dev/null +++ b/param-docs/parameter-pages/TakeImage/CamBrightness.md @@ -0,0 +1,10 @@ +# Parameter `CamBrightness` +Default Value: `0` + +!!! Note + This parameter can also be set on the Reference Image configuration page! + +!!! Note + After changing this parameter you need to update your reference image and alignment markers! + +Image Brightness (`-2` .. `2`) diff --git a/param-docs/parameter-pages/TakeImage/CamColorbar.md b/param-docs/parameter-pages/TakeImage/CamColorbar.md new file mode 100644 index 00000000..619e3f70 --- /dev/null +++ b/param-docs/parameter-pages/TakeImage/CamColorbar.md @@ -0,0 +1,5 @@ +# Parameter `CamColorbar` +Default Value: `false` + +!!! Note + This parameter can also be set on the Reference Image configuration page! diff --git a/param-docs/parameter-pages/TakeImage/CamContrast.md b/param-docs/parameter-pages/TakeImage/CamContrast.md new file mode 100644 index 00000000..941be46a --- /dev/null +++ b/param-docs/parameter-pages/TakeImage/CamContrast.md @@ -0,0 +1,11 @@ +# Parameter `CamContrast` +Default Value: `0` + +!!! Note + This parameter can also be set on the Reference Image configuration page! + +!!! Note + After changing this parameter you need to update your reference image and alignment markers! + +Image Contrast (`-2` .. `2`) + diff --git a/param-docs/parameter-pages/TakeImage/CamDcw.md b/param-docs/parameter-pages/TakeImage/CamDcw.md new file mode 100644 index 00000000..550380c7 --- /dev/null +++ b/param-docs/parameter-pages/TakeImage/CamDcw.md @@ -0,0 +1,13 @@ +# Parameter `CamDcw` +Default Value: `true` + +!!! Warning + This is an **Expert Parameter**! Only change it if you understand what it does! + +!!! Note + After changing this parameter you need to update your reference image and alignment markers! + +!!! Note + When DCW is on, the image that you receive will be the size that you requested (VGA, QQVGA, etc). + When DCW is off, the image that you receive will be one of UXGA, SVGA, or CIF. In other words, literally the actual image size as read from the sensor without any scaling. + Note that if DCW is off, and you pick a different image size, this implicitly turns DCW back on again (although this isn't reflected in the options). diff --git a/param-docs/parameter-pages/TakeImage/CamDenoise.md b/param-docs/parameter-pages/TakeImage/CamDenoise.md new file mode 100644 index 00000000..36c0a573 --- /dev/null +++ b/param-docs/parameter-pages/TakeImage/CamDenoise.md @@ -0,0 +1,10 @@ +# Parameter `CamDenoise` +Default Value: ` ` + +!!! Warning + This is an **Expert Parameter**! Only change it if you understand what it does! + +!!! Note + After changing this parameter you need to update your reference image and alignment markers! + +Denoise Image (not supported) diff --git a/param-docs/parameter-pages/TakeImage/CamGainceiling.md b/param-docs/parameter-pages/TakeImage/CamGainceiling.md new file mode 100644 index 00000000..479f746f --- /dev/null +++ b/param-docs/parameter-pages/TakeImage/CamGainceiling.md @@ -0,0 +1,21 @@ +# Parameter `CamGainceiling` +Default Value: `x2` + +!!! Warning + This is an **Expert Parameter**! Only change it if you understand what it does! + +!!! Note + After changing this parameter you need to update your reference image and alignment markers! + +!!! Note + This is visible when AGC is on. + +Available options: + +- `x2` +- `x4` +- `x8` +- `x16` +- `x32` +- `x64` +- `x128` diff --git a/param-docs/parameter-pages/TakeImage/CamHmirror.md b/param-docs/parameter-pages/TakeImage/CamHmirror.md new file mode 100644 index 00000000..f8001678 --- /dev/null +++ b/param-docs/parameter-pages/TakeImage/CamHmirror.md @@ -0,0 +1,10 @@ +# Parameter `CamHmirror` +Default Value: `false` + +!!! Note + This parameter can also be set on the Reference Image configuration page! + +!!! Note + After changing this parameter you need to update your reference image and alignment markers! + +Option for initially mirroring the image on the original x-axis. diff --git a/param-docs/parameter-pages/TakeImage/CamLenc.md b/param-docs/parameter-pages/TakeImage/CamLenc.md new file mode 100644 index 00000000..c1f32db5 --- /dev/null +++ b/param-docs/parameter-pages/TakeImage/CamLenc.md @@ -0,0 +1,10 @@ +# Parameter `CamLenc` +Default Value: `true` + +!!! Warning + This is an **Expert Parameter**! Only change it if you understand what it does! + +!!! Note + After changing this parameter you need to update your reference image and alignment markers! + +Lens Correction diff --git a/param-docs/parameter-pages/TakeImage/CamQuality.md b/param-docs/parameter-pages/TakeImage/CamQuality.md new file mode 100644 index 00000000..757800ad --- /dev/null +++ b/param-docs/parameter-pages/TakeImage/CamQuality.md @@ -0,0 +1,10 @@ +# Parameter `CamQuality` +Default Value: `12` + +!!! Warning + This is an **Expert Parameter**! Only change it if you understand what it does! + +Quality index for pictures: `8` (highest quality) ... `63` (lowest quality) + +!!! Warning + Value below 12 could result in system instabilities! diff --git a/param-docs/parameter-pages/TakeImage/CamRawGma.md b/param-docs/parameter-pages/TakeImage/CamRawGma.md new file mode 100644 index 00000000..f98d1ff9 --- /dev/null +++ b/param-docs/parameter-pages/TakeImage/CamRawGma.md @@ -0,0 +1,10 @@ +# Parameter `CamRawGma` +Default Value: ` ` + +!!! Warning + This is an **Expert Parameter**! Only change it if you understand what it does! + +!!! Note + After changing this parameter you need to update your reference image and alignment markers! + +RawGma diff --git a/param-docs/parameter-pages/TakeImage/CamSaturation.md b/param-docs/parameter-pages/TakeImage/CamSaturation.md new file mode 100644 index 00000000..ac8511c9 --- /dev/null +++ b/param-docs/parameter-pages/TakeImage/CamSaturation.md @@ -0,0 +1,11 @@ +# Parameter `CamSaturation` +Default Value: `0` + +!!! Note + This parameter can also be set on the Reference Image configuration page! + +!!! Note + After changing this parameter you need to update your reference image and alignment markers! + +Image Saturation (`-2` .. `2`) + diff --git a/param-docs/parameter-pages/TakeImage/CamSharpness.md b/param-docs/parameter-pages/TakeImage/CamSharpness.md new file mode 100644 index 00000000..290d931b --- /dev/null +++ b/param-docs/parameter-pages/TakeImage/CamSharpness.md @@ -0,0 +1,13 @@ +# Parameter `CamSharpness` +Default Value: `0` + +!!! Warning + This is an **Expert Parameter**! Only change it if you understand what it does! + +!!! Note + This parameter can also be set on the Reference Image configuration page! + +!!! Note + After changing this parameter you need to update your reference image and alignment markers! + +Range (`-2` .. `2`) diff --git a/param-docs/parameter-pages/TakeImage/CamSpecialEffect.md b/param-docs/parameter-pages/TakeImage/CamSpecialEffect.md new file mode 100644 index 00000000..2e48fb02 --- /dev/null +++ b/param-docs/parameter-pages/TakeImage/CamSpecialEffect.md @@ -0,0 +1,21 @@ +# Parameter `CamSpecialEffect` +Default Value: `no_effect` + +!!! Warning + This is an **Expert Parameter**! Only change it if you understand what it does! + +!!! Note + This parameter can also be set on the Reference Image configuration page! + +!!! Note + After changing this parameter you need to update your reference image and alignment markers! + +Available options: + +- `no_effect` +- `negative` +- `grayscale` +- `red` +- `green` +- `blue` +- `retro` diff --git a/param-docs/parameter-pages/TakeImage/CamVflip.md b/param-docs/parameter-pages/TakeImage/CamVflip.md new file mode 100644 index 00000000..fccb3022 --- /dev/null +++ b/param-docs/parameter-pages/TakeImage/CamVflip.md @@ -0,0 +1,10 @@ +# Parameter `CamVflip` +Default Value: `false` + +!!! Note + This parameter can also be set on the Reference Image configuration page! + +!!! Note + After changing this parameter you need to update your reference image and alignment markers! + +Option for initially flip the image on the original y-axis. diff --git a/param-docs/parameter-pages/TakeImage/CamWbMode.md b/param-docs/parameter-pages/TakeImage/CamWbMode.md new file mode 100644 index 00000000..a29eae44 --- /dev/null +++ b/param-docs/parameter-pages/TakeImage/CamWbMode.md @@ -0,0 +1,18 @@ +# Parameter `CamWbMode` +Default Value: `auto` + +!!! Note + This parameter can also be set on the Reference Image configuration page! + +!!! Note + After changing this parameter you need to update your reference image and alignment markers! + +White Balance Mode + +Available options: + +- `auto` +- `sunny` +- `cloudy` +- `office` +- `home` diff --git a/param-docs/parameter-pages/TakeImage/CamWpc.md b/param-docs/parameter-pages/TakeImage/CamWpc.md new file mode 100644 index 00000000..bf1d5741 --- /dev/null +++ b/param-docs/parameter-pages/TakeImage/CamWpc.md @@ -0,0 +1,10 @@ +# Parameter `CamWpc` +Default Value: `true` + +!!! Note + This parameter can also be set on the Reference Image configuration page! + +!!! Note + After changing this parameter you need to update your reference image and alignment markers! + +White Pixel Correction diff --git a/param-docs/parameter-pages/TakeImage/CamZoom.md b/param-docs/parameter-pages/TakeImage/CamZoom.md new file mode 100644 index 00000000..4f41f4a0 --- /dev/null +++ b/param-docs/parameter-pages/TakeImage/CamZoom.md @@ -0,0 +1,13 @@ +# Parameter `CamZoom` +Default Value: `false` + +!!! Warning + This is an **Expert Parameter**! Only change it if you understand what it does! + +!!! Note + This parameter can also be set on the Reference Image configuration page! + +!!! Note + After changing this parameter you need to update your reference image and alignment markers! + +Crop the camera sensor frame to `ImageSize` resolution instead of scaling it down. diff --git a/param-docs/parameter-pages/TakeImage/CamZoomOffsetX.md b/param-docs/parameter-pages/TakeImage/CamZoomOffsetX.md new file mode 100644 index 00000000..1d8d4605 --- /dev/null +++ b/param-docs/parameter-pages/TakeImage/CamZoomOffsetX.md @@ -0,0 +1,14 @@ +# Parameter `CamZoomOffsetX` +Default Value: `0` + +!!! Warning + This is an **Expert Parameter**! Only change it if you understand what it does! + +!!! Note + This parameter can also be set on the Reference Image configuration page! + +!!! Note + After changing this parameter you need to update your reference image and alignment markers! + +`ZoomOffsetX` only applies when `Zoom` is enabled. +X coordinate of the crop location within the camera sensor frame. diff --git a/param-docs/parameter-pages/TakeImage/CamZoomOffsetY.md b/param-docs/parameter-pages/TakeImage/CamZoomOffsetY.md new file mode 100644 index 00000000..6ea68809 --- /dev/null +++ b/param-docs/parameter-pages/TakeImage/CamZoomOffsetY.md @@ -0,0 +1,14 @@ +# Parameter `CamZoomOffsetY` +Default Value: `0` + +!!! Warning + This is an **Expert Parameter**! Only change it if you understand what it does! + +!!! Note + This parameter can also be set on the Reference Image configuration page! + +!!! Note + After changing this parameter you need to update your reference image and alignment markers! + +`ZoomOffsetY` only applies when `Zoom` is enabled. +Y coordinate of the crop location within the camera sensor frame. diff --git a/param-docs/parameter-pages/TakeImage/CamZoomSize.md b/param-docs/parameter-pages/TakeImage/CamZoomSize.md new file mode 100644 index 00000000..809e59b2 --- /dev/null +++ b/param-docs/parameter-pages/TakeImage/CamZoomSize.md @@ -0,0 +1,13 @@ +# Parameter `CamZoomSize` +Default Value: `0` + +!!! Warning + This is an **Expert Parameter**! Only change it if you understand what it does! + +!!! Note + This parameter can also be set on the Reference Image configuration page! + +!!! Note + After changing this parameter you need to update your reference image and alignment markers! + +`CamZoomSize` only applies when `Zoom` is enabled. diff --git a/sd-card/config/config.ini b/sd-card/config/config.ini index 518eedc5..2b133857 100644 --- a/sd-card/config/config.ini +++ b/sd-card/config/config.ini @@ -1,123 +1,136 @@ -[TakeImage] -;RawImagesLocation = /log/source -WaitBeforeTakingPicture = 5 -;RawImagesRetention = 15 -Brightness = 0 -Contrast = 0 -Saturation = 0 -Sharpness = 0 -LEDIntensity = 50 -ImageQuality = 12 -ImageSize = VGA -Zoom = false -ZoomMode = 0 -ZoomOffsetX = 0 -ZoomOffsetY = 0 -Grayscale = false -Negative = false -Aec2 = false -AutoExposureLevel = 0 -FixedExposure = false -Demo = false - -[Alignment] -InitialRotate = 0.0 -InitialMirror = false -SearchFieldX = 20 -SearchFieldY = 20 -AlignmentAlgo = Default -FlipImageSize = false -/config/ref0.jpg 103 271 -/config/ref1.jpg 442 142 - -[Digits] -Model = /config/dig-cont_0700_s3_q.tflite -CNNGoodThreshold = 0.5 -;ROIImagesLocation = /log/digit -;ROIImagesRetention = 3 -main.dig1 294 126 30 54 false -main.dig2 343 126 30 54 false -main.dig3 391 126 30 54 false - -[Analog] -Model = /config/ana-cont_1300_s2.tflite -CNNGoodThreshold = 0.5 -;ROIImagesLocation = /log/analog -;ROIImagesRetention = 3 -main.ana1 432 230 92 92 false -main.ana2 379 332 92 92 false -main.ana3 283 374 92 92 false -main.ana4 155 328 92 92 false - -[PostProcessing] -main.DecimalShift = 0 -main.AnalogDigitalTransitionStart = 9.2 -PreValueUse = true -PreValueAgeStartup = 720 -main.AllowNegativeRates = false -main.MaxRateValue = 0.05 -;main.MaxRateType = AbsoluteChange -main.ExtendedResolution = false -main.IgnoreLeadingNaN = false -ErrorMessage = true -CheckDigitIncreaseConsistency = false - -;[MQTT] -;Uri = mqtt://IP-ADRESS:1883 -;MainTopic = watermeter -;ClientID = watermeter -;user = USERNAME -;password = PASSWORD -RetainMessages = false -HomeassistantDiscovery = false -;MeterType = other -;CACert = /config/certs/RootCA.pem -;ClientCert = /config/certs/client.pem.crt -;ClientKey = /config/certs/client.pem.key - -;[InfluxDB] -;Uri = undefined -;Database = undefined -;Measurement = undefined -;user = undefined -;password = undefined - -;[InfluxDBv2] -;Uri = undefined -;Bucket = undefined -;Measurement = undefined -;Org = undefined -;Token = undefined -;main.Fieldname = undefined - -;[GPIO] -;MainTopicMQTT = wasserzaehler/GPIO -;IO0 = input disabled 10 false false -;IO1 = input disabled 10 false false -;IO3 = input disabled 10 false false -;IO4 = built-in-led disabled 10 false false -;IO12 = input-pullup disabled 10 false false -;IO13 = input-pullup disabled 10 false false -LEDType = WS2812 -LEDNumbers = 2 -LEDColor = 150 150 150 - -[AutoTimer] -AutoStart = true -Interval = 5 - -[DataLogging] -DataLogActive = true -DataFilesRetention = 3 - -[Debug] -LogLevel = 1 -LogfilesRetention = 3 - -[System] -TimeZone = CET-1CEST,M3.5.0,M10.5.0/3 -;TimeServer = pool.ntp.org -;Hostname = undefined -RSSIThreshold = -75 -CPUFrequency = 160 -SetupMode = true +[TakeImage] +;RawImagesLocation = /log/source +;RawImagesRetention = 15 +WaitBeforeTakingPicture = 2 +CamGainceiling = x4 +CamQuality = 8 +CamBrightness = 0 +CamContrast = 0 +CamSaturation = 0 +CamSharpness = 1 +CamAutoSharpness = false +CamSpecialEffect = no_effect +CamWbMode = auto +CamAwb = true +CamAwbGain = true +CamAec = true +CamAec2 = true +CamAeLevel = 2 +CamAecValue = 500 +CamAgc = true +CamAgcGain = 0 +CamBpc = true +CamWpc = true +CamRawGma = true +CamLenc = true +CamHmirror = false +CamVflip = false +CamDcw = true +CamZoom = false +CamZoomOffsetX = 0 +CamZoomOffsetY = 0 +CamZoomSize = 0 +LEDIntensity = 50 +Demo = false + +[Alignment] +InitialRotate = 0.0 +InitialMirror = false +SearchFieldX = 20 +SearchFieldY = 20 +AlignmentAlgo = Default +FlipImageSize = false +/config/ref0.jpg 103 271 +/config/ref1.jpg 442 142 + +[Digits] +Model = /config/dig-cont_0700_s3_q.tflite +CNNGoodThreshold = 0.5 +;ROIImagesLocation = /log/digit +;ROIImagesRetention = 3 +main.dig1 294 126 30 54 false +main.dig2 343 126 30 54 false +main.dig3 391 126 30 54 false + +[Analog] +Model = /config/ana-cont_1300_s2.tflite +CNNGoodThreshold = 0.5 +;ROIImagesLocation = /log/analog +;ROIImagesRetention = 3 +main.ana1 432 230 92 92 false +main.ana2 379 332 92 92 false +main.ana3 283 374 92 92 false +main.ana4 155 328 92 92 false + +[PostProcessing] +main.DecimalShift = 0 +main.AnalogDigitalTransitionStart = 9.2 +PreValueUse = true +PreValueAgeStartup = 720 +main.AllowNegativeRates = false +main.MaxRateValue = 0.05 +;main.MaxRateType = AbsoluteChange +main.ExtendedResolution = false +main.IgnoreLeadingNaN = false +ErrorMessage = true +CheckDigitIncreaseConsistency = false + +;[MQTT] +;Uri = mqtt://IP-ADRESS:1883 +;MainTopic = watermeter +;ClientID = watermeter +;user = USERNAME +;password = PASSWORD +RetainMessages = false +HomeassistantDiscovery = false +;MeterType = other +;CACert = /config/certs/RootCA.pem +;ClientCert = /config/certs/client.pem.crt +;ClientKey = /config/certs/client.pem.key + +;[InfluxDB] +;Uri = undefined +;Database = undefined +;Measurement = undefined +;user = undefined +;password = undefined + +;[InfluxDBv2] +;Uri = undefined +;Bucket = undefined +;Measurement = undefined +;Org = undefined +;Token = undefined +;main.Fieldname = undefined + +;[GPIO] +;MainTopicMQTT = wasserzaehler/GPIO +;IO0 = input disabled 10 false false +;IO1 = input disabled 10 false false +;IO3 = input disabled 10 false false +;IO4 = built-in-led disabled 10 false false +;IO12 = input-pullup disabled 10 false false +;IO13 = input-pullup disabled 10 false false +LEDType = WS2812 +LEDNumbers = 2 +LEDColor = 150 150 150 + +[AutoTimer] +AutoStart = true +Interval = 5 + +[DataLogging] +DataLogActive = true +DataFilesRetention = 3 + +[Debug] +LogLevel = 1 +LogfilesRetention = 3 + +[System] +TimeZone = CET-1CEST,M3.5.0,M10.5.0/3 +;TimeServer = pool.ntp.org +;Hostname = undefined +RSSIThreshold = -75 +CPUFrequency = 160 +SetupMode = true diff --git a/sd-card/html/edit_alignment.html b/sd-card/html/edit_alignment.html index 944803c7..a515a0ff 100644 --- a/sd-card/html/edit_alignment.html +++ b/sd-card/html/edit_alignment.html @@ -113,49 +113,56 @@
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Marker: - - Filename:
x: dx:
y: dy:
Selected Image Area:Resulting Marker:
Reference Image: -
- + + + + + + + + Marker: + + + Filename: + + + + x: + dx: + + + + + y: + dy: + + + + Selected Image Area: + Resulting Marker: + + + + + + + + + + Reference Image: + + + + + + + + + + @@ -173,6 +180,7 @@ var canvas = document.getElementById('canvas'), domainname = getDomainname(), neueref1, neueref2, + cofcat, param; function doReboot() { @@ -290,8 +298,7 @@ function UpdateReference(){ draw(); } - _filenameurl = refInfo[aktindex]["name"].replace("/config/", "/img_tmp/"); - + var _filenameurl = refInfo[aktindex]["name"].replace("/config/", "/img_tmp/"); var url = domainname + "/fileserver" + _filenameurl + "?" + Date.now(); document.getElementById("img_ref").src = url; @@ -352,7 +359,7 @@ function openDescription() { if(window.location.hash) { var hash = window.location.hash.substring(1); //Puts hash in variable, and removes the # character if(hash == 'description') { - document.getElementById("desc_details").open = true; + document.getElementById("desc_details").open = false; } } } @@ -368,7 +375,7 @@ function LoadReference(){ draw(); } - _filenameurl = refInfo[aktindex]["name"]; + var _filenameurl = refInfo[aktindex]["name"]; var url = domainname + "/fileserver" + _filenameurl + "?" + Date.now(); document.getElementById("img_ref").src = url; @@ -387,17 +394,23 @@ function LoadReference(){ function init() { openDescription(); domainname = getDomainname(); - loadConfig(domainname); + + if (!loadConfig(domainname)) { + firework.launch('Configuration could not be loaded! Please reload the page!', 'danger', 30000); + return; + } + ParseConfig(); param = getConfigParameters(); + cofcat = getConfigCategory(); document.getElementById("savemarker").disabled = true; document.getElementById("enhancecontrast").disabled = true; - + canvas.addEventListener('mousedown', mouseDown, false); canvas.addEventListener('mouseup', mouseUp, false); canvas.addEventListener('mousemove', mouseMove, false); - loadCanvas(domainname + "/fileserver/config/reference.jpg"); + loadCanvas(domainname + "/fileserver/config/reference.jpg"); //CopyReferenceToImgTmp(domainname); refInfo = GetReferencesInfo(); @@ -405,6 +418,7 @@ function init() { //UpdateReference(); LoadReference(); drawImage(); + draw(); } function drawImage(){ diff --git a/sd-card/html/edit_analog.html b/sd-card/html/edit_analog.html index 8f7dfcfe..7acbe016 100644 --- a/sd-card/html/edit_analog.html +++ b/sd-card/html/edit_analog.html @@ -125,7 +125,6 @@
- @@ -133,9 +132,11 @@ + + + + + + + @@ -202,7 +209,6 @@ The following settings are only used for easier setup, they are not persi


-
Number Sequence:
ROI:
Multiplier:
(only based on order) @@ -183,14 +187,17 @@
x: Δx:
y: Δy:
@@ -212,20 +218,23 @@ The following settings are only used for easier setup, they are not persi + - - + +
Reference Image: + +
- - + + + + + + +
+
+
+

Configuration

@@ -252,227 +283,398 @@ $TOOLTIP_TakeImage_RawImagesRetention - - - - - - - - $TOOLTIP_TakeImage_Demo - - - + Wait Before Taking Picture - Seconds $TOOLTIP_TakeImage_WaitBeforeTakingPicture - + - Brightness + CamGainceiling - + - $TOOLTIP_TakeImage_Brightness - - - + $TOOLTIP_TakeImage_CamGainceiling + + + - Contrast + Image Quality - - $TOOLTIP_TakeImage_Contrast + $TOOLTIP_TakeImage_CamQuality - + - Saturation + Brightness - + - $TOOLTIP_TakeImage_Saturation + $TOOLTIP_TakeImage_CamBrightness - + - Sharpness + Contrast - + - $TOOLTIP_TakeImage_Sharpness + $TOOLTIP_TakeImage_CamContrast - + + + Saturation + + + + + $TOOLTIP_TakeImage_CamSaturation + + + + + AutoSharpness + + + + + $TOOLTIP_TakeImage_CamAutoSharpness + + + + + Sharpness + + + + + $TOOLTIP_TakeImage_CamSharpness + + + + + SpecialEffect + + + + + $TOOLTIP_TakeImage_CamSpecialEffect + + + + + White Balance Mode + + + + + $TOOLTIP_TakeImage_CamWbMode + + + + + White Balance + + + + + $TOOLTIP_TakeImage_CamAwb + + + + + Auto White Balance + + + + + $TOOLTIP_TakeImage_CamAwbGain + + + + + Auto-Exposure Control + + + + + $TOOLTIP_TakeImage_CamAec + + + + + Auto-Exposure Control 2 + + + + + $TOOLTIP_TakeImage_CamAec2 + + + + + Auto Exposure Level + + + + + $TOOLTIP_TakeImage_CamAeLevel + + + + + Auto Exposure Value + + + + + $TOOLTIP_TakeImage_CamAecValue + + + + + Auto Gain + + + + + $TOOLTIP_TakeImage_CamAgc + + + + + Gain Manuall Value + + + + + $TOOLTIP_TakeImage_CamAgcGain + + + + + Black Pixel Correction + + + + + $TOOLTIP_TakeImage_CamBpc + + + + + White Pixel Correction + + + + + $TOOLTIP_TakeImage_CamWpc + + + + + CamRawGma + + + + + $TOOLTIP_TakeImage_CamRawGma + + + + + Lens Correction + + + + + $TOOLTIP_TakeImage_CamLenc + + + + + Mirror Image + + + + + $TOOLTIP_TakeImage_CamHmirror + + + + + Flip Image + + + + + $TOOLTIP_TakeImage_CamVflip + + + + + Downsize + + + + + $TOOLTIP_TakeImage_CamDcw + + + + + Zoom + + + + + $TOOLTIP_TakeImage_CamZoom + + + + + Zoom Size + + + + + $TOOLTIP_TakeImage_CamZoomSize + + + + + Zoom Offset X + + + Pixel + + $TOOLTIP_TakeImage_CamZoomOffsetX + + + + + Zoom Offset Y + + + Pixel + + $TOOLTIP_TakeImage_CamZoomOffsetY + + + LED Intensity + oninput="(!validity.rangeUnderflow||(value=0)) && (!validity.rangeOverflow||(value=100)) && (!validity.stepMismatch||(value=parseInt(this.value)));"> $TOOLTIP_TakeImage_LEDIntensity - - + + - Image Quality + - - - $TOOLTIP_TakeImage_ImageQuality - - - - - Image Size - - - + + - $TOOLTIP_TakeImage_ImageSize - - - - - Zoom - - - - - $TOOLTIP_TakeImage_Zoom - - - - - Zoom Mode - - - - - $TOOLTIP_TakeImage_ZoomMode - - - - - - Zoom Offset X - - - Pixel - - $TOOLTIP_TakeImage_ZoomOffsetX - - - - - - Zoom Offset Y - - - Pixel - - $TOOLTIP_TakeImage_ZoomOffsetY - - - - - Grayscale - - - - - $TOOLTIP_TakeImage_Grayscale - - - - - Negative - - - - - $TOOLTIP_TakeImage_Negative - - - - - Auto-exposure Control 2 - - - - - $TOOLTIP_TakeImage_Aec2 - - - - - Auto Exposure Level - - - - - $TOOLTIP_TakeImage_AutoExposureLevel - - - - - Fixed Exposure - - - - - $TOOLTIP_TakeImage_FixedExposure + $TOOLTIP_TakeImage_Demo @@ -480,7 +682,7 @@

Alignment

- + Search Field X @@ -491,7 +693,7 @@ $TOOLTIP_Alignment_SearchFieldX - + Search Field Y @@ -502,7 +704,7 @@ $TOOLTIP_Alignment_SearchFieldY - + @@ -518,39 +720,13 @@ $TOOLTIP_Alignment_AlignmentAlgo - - - Flip Image Size - - - - - $TOOLTIP_Alignment_FlipImageSize - - - - - Initial Mirror - - - - - $TOOLTIP_Alignment_InitialMirror - - - + Rotation angle - degree + degree $TOOLTIP_Alignment_InitialRotate @@ -657,19 +833,6 @@

Post-Processing

- - - - - - - - $TOOLTIP_PostProcessing_PreValueUse - - @@ -688,8 +851,8 @@ $TOOLTIP_PostProcessing_ErrorMessage @@ -701,8 +864,8 @@ $TOOLTIP_PostProcessing_CheckDigitIncreaseConsistency @@ -719,12 +882,25 @@ - + - + + + + + $TOOLTIP_PostProcessing_PreValueUse + + + + + + + + $TOOLTIP_PostProcessing_NUMBER.AllowNegativeRates @@ -749,8 +925,8 @@ - $TOOLTIP_PostProcessing_NUMBER.AnalogDigitalTransitionStart @@ -788,25 +964,38 @@ $TOOLTIP_PostProcessing_NUMBER.ExtendedResolution - + $TOOLTIP_PostProcessing_NUMBER.IgnoreLeadingNaN + + + + + + + + + $TOOLTIP_PostProcessing_NUMBER.IgnoreAllNaN + @@ -913,8 +1102,8 @@ $TOOLTIP_MQTT_RetainMessages @@ -935,8 +1124,8 @@ $TOOLTIP_MQTT_HomeassistantDiscovery @@ -1445,6 +1634,8 @@ + + @@ -1533,18 +1724,28 @@ LED Color - - R - G - B $TOOLTIP_GPIO_LEDColor + + + + + G + + + + + + B + @@ -1629,8 +1830,8 @@ $TOOLTIP_AutoTimer_AutoStart @@ -1659,8 +1860,8 @@ $TOOLTIP_DataLogging_DataLogActive @@ -1776,6 +1977,18 @@ $TOOLTIP_System_CPUFrequency + + + Tooltip + + + + + + @@ -1801,31 +2014,38 @@ var canvas = document.getElementById('canvas'), NUNBERSAkt = -1, NUMBERS; - function cameraParameterChanged() { changeCamValue = 1; - if (document.getElementById("TakeImage_Zoom_value1").value == "false") { - document.getElementById("TakeImage_ZoomMode_value1").disabled = true; - document.getElementById("TakeImage_ZoomOffsetX_value1").disabled = true; - document.getElementById("TakeImage_ZoomOffsetY_value1").disabled = true; + if(!document.getElementById("TakeImage_CamZoom_value1").selectedIndex) { + // EnDisableItem(_status, _param, _category, _cat, _name, _optional, _number = -1) + EnDisableItem(true, param, category, "TakeImage", "CamZoomOffsetX", false); + EnDisableItem(true, param, category, "TakeImage", "CamZoomOffsetY", false); + EnDisableItem(true, param, category, "TakeImage", "CamZoomSize", false); } else { - document.getElementById("TakeImage_ZoomMode_value1").disabled = false; - document.getElementById("TakeImage_ZoomOffsetX_value1").disabled = false; - document.getElementById("TakeImage_ZoomOffsetY_value1").disabled = false; - } + EnDisableItem(false, param, category, "TakeImage", "CamZoomOffsetX", false); + EnDisableItem(false, param, category, "TakeImage", "CamZoomOffsetY", false); + EnDisableItem(false, param, category, "TakeImage", "CamZoomSize", false); + } + + if(!document.getElementById("TakeImage_CamAutoSharpness_value1").selectedIndex) { + EnDisableItem(true, param, category, "TakeImage", "CamSharpness", false); + } + else { + EnDisableItem(false, param, category, "TakeImage", "CamSharpness", false); + } } - function LoadConfigNeu() { - domainname = getDomainname(); + domainname = getDomainname(); + if (!loadConfig(domainname)) { firework.launch('Configuration could not be loaded! Please reload the page!', 'danger', 30000); return; - } - ParseConfig(); - param = getConfigParameters(); + } + + param = getCamConfig(); category = getConfigCategory(); InitIndivParameter(); @@ -1833,21 +2053,29 @@ function LoadConfigNeu() { var sel = document.getElementById("Numbers_value1"); UpdateInputIndividual(sel); UpdateExpertModus(); + UpdateTooltipModus(); document.getElementById("divall").style.display = ''; - if (document.getElementById("TakeImage_Zoom_value1").value == "false") { - document.getElementById("TakeImage_ZoomMode_value1").disabled = true; - document.getElementById("TakeImage_ZoomOffsetX_value1").disabled = true; - document.getElementById("TakeImage_ZoomOffsetY_value1").disabled = true; + if(!document.getElementById("TakeImage_CamZoom_value1").selectedIndex) { + // EnDisableItem(_status, _param, _category, _cat, _name, _optional, _number = -1) + EnDisableItem(true, param, category, "TakeImage", "CamZoomOffsetX", false); + EnDisableItem(true, param, category, "TakeImage", "CamZoomOffsetY", false); + EnDisableItem(true, param, category, "TakeImage", "CamZoomSize", false); } else { - document.getElementById("TakeImage_ZoomMode_value1").disabled = false; - document.getElementById("TakeImage_ZoomOffsetX_value1").disabled = false; - document.getElementById("TakeImage_ZoomOffsetY_value1").disabled = false; + EnDisableItem(false, param, category, "TakeImage", "CamZoomOffsetX", false); + EnDisableItem(false, param, category, "TakeImage", "CamZoomOffsetY", false); + EnDisableItem(false, param, category, "TakeImage", "CamZoomSize", false); + } + + if(!document.getElementById("TakeImage_CamAutoSharpness_value1").selectedIndex) { + EnDisableItem(true, param, category, "TakeImage", "CamSharpness", false); + } + else { + EnDisableItem(false, param, category, "TakeImage", "CamSharpness", false); } } - function InitIndivParameter() { NUMBERS = getNUMBERInfo(); @@ -1888,319 +2116,17 @@ function InitIndivParameter() { _indexInfluxv1.selectedIndex = 0; } - -function getParameterByName(name, url = window.location.href) { - name = name.replace(/[\[\]]/g, '\\$&'); - var regex = new RegExp('[?&]' + name + '(=([^&#]*)|&|#|$)'), - results = regex.exec(url); - - if (!results) {return null;} - if (!results[2]) {return '';} - - return decodeURIComponent(results[2].replace(/\+/g, ' ')); -} - - -function WriteParameter(_param, _category, _cat, _name, _optional, _number = -1) { - let anzpara; - try { - anzpara = _param[_cat][_name].anzParam; - } - catch (error) { - firework.launch("Parameter '" + _name + "' in category '" + _cat + "' is unknown!", 'danger', 30000); - return; - } - - if (_number > -1) { - if ((NUMBERS[_number] == undefined) || (NUMBERS[_number][_cat] == undefined) || (NUMBERS[_number][_cat][_name] == undefined)) { - return; - } - - if (_optional) { - document.getElementById(_cat+"_"+_name+"_enabled").checked = NUMBERS[_number][_cat][_name]["enabled"]; - for (var j = 1; j <= anzpara; ++j) { - document.getElementById(_cat+"_"+_name+"_value"+j).disabled = !NUMBERS[_number][_cat][_name]["enabled"]; - } - } - - document.getElementById(_cat+"_"+_name+"_text").style.color = "black" - setEnabled(_cat+"_"+_name, true); - - for (var j = 1; j <= anzpara; ++j) { - let element = document.getElementById(_cat+"_"+_name+"_value"+j); - if (element.tagName.toLowerCase() == "select") { - var textToFind = NUMBERS[_number][_cat][_name]["value"+j]; - if (textToFind == undefined) { - continue; - } - - _isFound = false; - element.selectedIndex = -1; - for (var i = 0; i < element.options.length; i++) { - if (element.options[i].value.toLowerCase() === textToFind.toLowerCase()) { - element.selectedIndex = i; - _isFound = true; - break; - } - } - if (!_isFound) { - _zw_txt = "In the selected field the value '" + textToFind + "' in the parameter '"; - _zw_txt = _zw_txt + _cat + "' in the field '" + _name + "' is invalid. PLEASE CHECK BEFORE SAVING!"; - firework.launch(_zw_txt, 'warning', 10000); - } - } - else if ((element.getAttribute("type") != null) && (element.getAttribute("type").toLowerCase() == "checkbox")) { - element.checked = NUMBERS[_number][_cat][_name]["value"+j] == "true"; - } - else { - element.value = NUMBERS[_number][_cat][_name]["value"+j]; - } - } - } - else { - if (_optional) { - document.getElementById(_cat+"_"+_name+"_enabled").checked = _param[_cat][_name]["enabled"]; - for (var j = 1; j <= anzpara; ++j) { - document.getElementById(_cat+"_"+_name+"_value"+j).disabled = !_param[_cat][_name]["enabled"]; - } - } - document.getElementById(_cat+"_"+_name+"_text").style.color = "black" - setEnabled(_cat+"_"+_name, true); - - for (var j = 1; j <= anzpara; ++j) { - let element = document.getElementById(_cat+"_"+_name+"_value"+j); - if (element.tagName.toLowerCase() == "select") { - var textToFind = _param[_cat][_name]["value"+j]; - if (textToFind == undefined) { - continue; - } - - _isFound = false; - element.selectedIndex = -1; - for (var i = 0; i < element.options.length; i++) { - if (element.options[i].value.toLowerCase() === textToFind.toLowerCase()) { - element.selectedIndex = i; - _isFound = true; - break; - } - } - if (!_isFound) { - _zw_txt = "In the selected field the value '" + textToFind + "' in the section '"; - _zw_txt = _zw_txt + _cat + "' in the field '" + _name + "' is invalid. PLEASE CHECK BEFORE SAVING!"; - firework.launch(_zw_txt, 'warning', 10000); - } - - } - else if ((element.getAttribute("type") != null) && (element.getAttribute("type").toLowerCase() == "checkbox")) { - element.checked = _param[_cat][_name]["value"+j] == "true"; - } - else { - element.value = _param[_cat][_name]["value"+j]; - } - } - } - - ///////////////// am Ende, falls Kategorie als gesamtes nicht ausgewählt --> deaktivieren - if (_category[_cat]["enabled"] == false) { - if (_optional) { - document.getElementById(_cat+"_"+_name+"_enabled").disabled = true; - for (var j = 1; j <= anzpara; ++j) { - document.getElementById(_cat+"_"+_name+"_value"+j).disabled = true; - } - } - document.getElementById(_cat+"_"+_name+"_text").style="color: gray;" - setEnabled(_cat+"_"+_name, false); - } - - EnDisableItem(_category[_cat]["enabled"], _param, _category, _cat, _name, _optional, _number); -} - - -function InvertEnableItem(_cat, _param) { - _zw = _cat + "_" + _param + "_enabled"; - _isOn = document.getElementById(_zw).checked; - - _color = "rgb(122, 122, 122)"; - - if (_isOn) { - _color = "black"; - } - - _zw = _cat + "_" + _param + "_text"; - document.getElementById(_zw).disabled = !_isOn; - document.getElementById(_zw).style.color = _color; - - setEnabled(_cat + "_" + _param, _isOn); - - for (var j = 1; j <= param[_cat][_param]["anzParam"]; ++j) { - document.getElementById(_cat+"_"+_param+"_value"+j).disabled = !_isOn; - document.getElementById(_cat+"_"+_param+"_value"+j).style.color = _color; - } -} - - -function setEnabled(className, enabled) { - _color = "rgb(122, 122, 122)"; - if (enabled) { - _color = "black"; - } - - let elements = document.getElementsByClassName(className); - for (i = 0; i < elements.length; i++) { - if (enabled) { - elements[i].classList.remove("disabled"); - } - else { - elements[i].classList.add("disabled"); - } - - let inputs = elements[i].getElementsByTagName("input"); - for (j = 0; j < inputs.length; j++) { - if (inputs[j].id.endsWith("_enabled")) { - continue; - } - - inputs[j].style.color = _color; - if (enabled) { - inputs[j].removeAttribute("disabled"); - } - else { - inputs[j].setAttribute("disabled", "disabled"); - } - } - } -} - - -function setVisible(className, visible) { - let elements = document.getElementsByClassName(className); - for (i = 0; i < elements.length; i++) { - if (visible) { - elements[i].classList.remove("hidden"); - } - else { - elements[i].classList.add("hidden"); - } - } -} - - -function EnDisableItem(_status, _param, _category, _cat, _name, _optional, _number = -1) { - _status = _category[_cat]["enabled"]; - - _color = "rgb(122, 122, 122)"; - if (_status) { - _color = "black"; - } - - if (_optional) { - document.getElementById(_cat+"_"+_name+"_enabled").disabled = !_status; - document.getElementById(_cat+"_"+_name+"_enabled").style.color = _color; - } - - if (_number == -1) { - if (!_param[_cat][_name]["enabled"]) { - _status = false; - _color = "rgb(122, 122, 122)"; - } - } - else { - if (!NUMBERS[_number][_cat][_name]["enabled"]) { - _status = false; - _color = "rgb(122, 122, 122)"; - } - } - - document.getElementById(_cat+"_"+_name+"_text").disabled = !_status; - document.getElementById(_cat+"_"+_name+"_text").style.color = _color; - - setEnabled(_cat+"_"+_name, _status); - - for (var j = 1; j <= _param[_cat][_name]["anzParam"]; ++j) { - document.getElementById(_cat+"_"+_name+"_value"+j).disabled = !_status; - document.getElementById(_cat+"_"+_name+"_value"+j).style.color = _color; - } -} - - -function ReadParameter(_param, _cat, _name, _optional, _number = -1) { - if (_number > -1) { - if (_cat == "Digits") { - _cat = "digit"; - } - - if (_cat == "Analog") { - _cat = "analog"; - } - - if ((NUMBERS[_number] == undefined) || (NUMBERS[_number][_cat] == undefined) || (NUMBERS[_number][_cat][_name] == undefined)) { - return; - } - - if (_optional) { - NUMBERS[_number][_cat][_name]["enabled"] = document.getElementById(_cat+"_"+_name+"_enabled").checked; - } - - for (var j = 1; j <= _param[_cat][_name]["anzParam"]; ++j) { - let element = document.getElementById(_cat+"_"+_name+"_value"+j); - if (element.tagName.toLowerCase() == "select") { - NUMBERS[_number][_cat][_name]["value"+j] = element.selectedIndex > -1 ? element.options[element.selectedIndex].value : ""; - } - else if ((element.getAttribute("type") != null) && (element.getAttribute("type").toLowerCase() == "checkbox")) { - NUMBERS[_number][_cat][_name]["value"+j] = element.checked; - } - else { - if ((NUMBERS[_number][_cat][_name].checkRegExList != null) && (NUMBERS[_number][_cat][_name].checkRegExList[j-1] != null)) { - if (!element.value.match(NUMBERS[_cat][_name].checkRegExList[j-1])) { - element.classList.add("invalid-input"); - } - else { - element.classList.remove("invalid-input"); - } - } - NUMBERS[_number][_cat][_name]["value"+j] = element.value; - } - } - } - else - { - if (_optional) { - _param[_cat][_name]["enabled"] = document.getElementById(_cat+"_"+_name+"_enabled").checked; - } - - for (var j = 1; j <= _param[_cat][_name]["anzParam"]; ++j) { - let element = document.getElementById(_cat+"_"+_name+"_value"+j); - if (element.tagName.toLowerCase() == "select") { - _param[_cat][_name]["value"+j] = element.selectedIndex > -1 ? element.options[element.selectedIndex].value : ""; - } - else if ((element.getAttribute("type") != null) && (element.getAttribute("type").toLowerCase() == "checkbox")) { - _param[_cat][_name]["value"+j] = element.checked; - } - else { - if ((_param[_cat][_name].checkRegExList != null) && (_param[_cat][_name].checkRegExList[j-1] != null)) { - if (!element.value.match(_param[_cat][_name].checkRegExList[j-1])) { - element.classList.add("invalid-input"); - } - else { - element.classList.remove("invalid-input"); - } - } - _param[_cat][_name]["value"+j] = element.value; - } - } - } -} - - function UpdateInputIndividual(sel) { if (NUNBERSAkt != -1) { + ReadParameter(param, "PostProcessing", "PreValueUse", false, NUNBERSAkt); 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", false, NUNBERSAkt); ReadParameter(param, "PostProcessing", "IgnoreLeadingNaN", false, NUNBERSAkt); - ReadParameter(param, "PostProcessing", "AllowNegativeRates", false, NUNBERSAkt); + ReadParameter(param, "PostProcessing", "IgnoreAllNaN", false, NUNBERSAkt); + ReadParameter(param, "PostProcessing", "AllowNegativeRate", false, NUNBERSAkt); ReadParameter(param, "InfluxDB", "Field", true, NUNBERSAkt); ReadParameter(param, "InfluxDBv2", "Field", true, NUNBERSAkt); ReadParameter(param, "InfluxDB", "Measurement", true, NUNBERSAkt); @@ -2209,20 +2135,21 @@ function UpdateInputIndividual(sel) { // var sel = document.getElementById("Numbers_value1"); NUNBERSAkt = sel.selectedIndex; + WriteParameter(param, category, "PostProcessing", "PreValueUse", false, NUNBERSAkt); 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", false, NUNBERSAkt); WriteParameter(param, category, "PostProcessing", "IgnoreLeadingNaN", false, NUNBERSAkt); - WriteParameter(param, category, "PostProcessing", "AllowNegativeRates", false, NUNBERSAkt); + WriteParameter(param, category, "PostProcessing", "IgnoreAllNaN", false, NUNBERSAkt); + WriteParameter(param, category, "PostProcessing", "AllowNegativeRate", false, NUNBERSAkt); WriteParameter(param, category, "InfluxDB", "Field", true, NUNBERSAkt); WriteParameter(param, category, "InfluxDBv2", "Field", true, NUNBERSAkt); WriteParameter(param, category, "InfluxDB", "Measurement", true, NUNBERSAkt); WriteParameter(param, category, "InfluxDBv2", "Measurement", true, NUNBERSAkt); } - function UpdateInput() { document.getElementById("Category_Digits_enabled").checked = category["Digits"]["enabled"]; setVisible("DigitItem", category["Digits"]["enabled"]); @@ -2244,30 +2171,42 @@ function UpdateInput() { WriteParameter(param, category, "TakeImage", "RawImagesLocation", true); WriteParameter(param, category, "TakeImage", "RawImagesRetention", true); - WriteParameter(param, category, "TakeImage", "Demo", false); - WriteParameter(param, category, "TakeImage", "WaitBeforeTakingPicture", false); - WriteParameter(param, category, "TakeImage", "ImageQuality", false); - WriteParameter(param, category, "TakeImage", "Brightness", false); - WriteParameter(param, category, "TakeImage", "Contrast", false); - WriteParameter(param, category, "TakeImage", "Saturation", false); - WriteParameter(param, category, "TakeImage", "Sharpness", false); - WriteParameter(param, category, "TakeImage", "LEDIntensity", false); - WriteParameter(param, category, "TakeImage", "ImageSize", false); - WriteParameter(param, category, "TakeImage", "Zoom", false); - WriteParameter(param, category, "TakeImage", "ZoomMode", false); - WriteParameter(param, category, "TakeImage", "ZoomOffsetX", false); - WriteParameter(param, category, "TakeImage", "ZoomOffsetY", false); - WriteParameter(param, category, "TakeImage", "Grayscale", false); - WriteParameter(param, category, "TakeImage", "Negative", false); - WriteParameter(param, category, "TakeImage", "Aec2", false); - WriteParameter(param, category, "TakeImage", "AutoExposureLevel", false); - WriteParameter(param, category, "TakeImage", "FixedExposure", false); + WriteParameter(param, category, "TakeImage", "WaitBeforeTakingPicture", false); + WriteParameter(param, category, "TakeImage", "CamGainceiling", false); + WriteParameter(param, category, "TakeImage", "CamQuality", false); + WriteParameter(param, category, "TakeImage", "CamBrightness", false); + WriteParameter(param, category, "TakeImage", "CamContrast", false); + WriteParameter(param, category, "TakeImage", "CamSaturation", false); + WriteParameter(param, category, "TakeImage", "CamSharpness", false); + WriteParameter(param, category, "TakeImage", "CamAutoSharpness", false); + WriteParameter(param, category, "TakeImage", "CamSpecialEffect", false); + WriteParameter(param, category, "TakeImage", "CamWbMode", false); + WriteParameter(param, category, "TakeImage", "CamAwb", false); + WriteParameter(param, category, "TakeImage", "CamAwbGain", false); + WriteParameter(param, category, "TakeImage", "CamAec", false); + WriteParameter(param, category, "TakeImage", "CamAec2", false); + WriteParameter(param, category, "TakeImage", "CamAeLevel", false); + WriteParameter(param, category, "TakeImage", "CamAecValue", false); + WriteParameter(param, category, "TakeImage", "CamAgc", false); + WriteParameter(param, category, "TakeImage", "CamAgcGain", false); + WriteParameter(param, category, "TakeImage", "CamBpc", false); + WriteParameter(param, category, "TakeImage", "CamWpc", false); + WriteParameter(param, category, "TakeImage", "CamRawGma", false); + WriteParameter(param, category, "TakeImage", "CamLenc", false); + WriteParameter(param, category, "TakeImage", "CamHmirror", false); + WriteParameter(param, category, "TakeImage", "CamVflip", false); + WriteParameter(param, category, "TakeImage", "CamDcw", false); + WriteParameter(param, category, "TakeImage", "CamZoom", false); + WriteParameter(param, category, "TakeImage", "CamZoomOffsetX", false); + WriteParameter(param, category, "TakeImage", "CamZoomOffsetY", false); + WriteParameter(param, category, "TakeImage", "CamZoomSize", false); + WriteParameter(param, category, "TakeImage", "LEDIntensity", false); + WriteParameter(param, category, "TakeImage", "Demo", false); + WriteParameter(param, category, "Alignment", "SearchFieldX", false); WriteParameter(param, category, "Alignment", "SearchFieldY", false); - WriteParameter(param, category, "Alignment", "AlignmentAlgo", true); - WriteParameter(param, category, "Alignment", "FlipImageSize", false); - WriteParameter(param, category, "Alignment", "InitialMirror", false); + WriteParameter(param, category, "Alignment", "AlignmentAlgo", true); WriteParameter(param, category, "Alignment", "InitialRotate", false); WriteParameter(param, category, "Digits", "CNNGoodThreshold", true); @@ -2277,11 +2216,15 @@ function UpdateInput() { WriteParameter(param, category, "Analog", "ROIImagesLocation", true); WriteParameter(param, category, "Analog", "ROIImagesRetention", true); - WriteParameter(param, category, "PostProcessing", "PreValueUse", false); + // WriteParameter(param, category, "PostProcessing", "PreValueUse", false); WriteParameter(param, category, "PostProcessing", "PreValueAgeStartup", true); - // WriteParameter(param, category, "PostProcessing", "AllowNegativeRates", true); WriteParameter(param, category, "PostProcessing", "ErrorMessage", false); WriteParameter(param, category, "PostProcessing", "CheckDigitIncreaseConsistency", false); + + // WriteParameter(param, category, "PostProcessing", "ExtendedResolution", false); + // WriteParameter(param, category, "PostProcessing", "IgnoreLeadingNaN", false); + // WriteParameter(param, category, "PostProcessing", "IgnoreAllNaN", false); + // WriteParameter(param, category, "PostProcessing", "AllowNegativeRate", false); WriteParameter(param, category, "MQTT", "Uri", true); WriteParameter(param, category, "MQTT", "MainTopic", true); @@ -2328,6 +2271,7 @@ function UpdateInput() { WriteParameter(param, category, "Debug", "LogLevel", false); WriteParameter(param, category, "Debug", "LogfilesRetention", false); + WriteParameter(param, category, "System", "Tooltip", false); WriteParameter(param, category, "System", "TimeZone", true); WriteParameter(param, category, "System", "Hostname", true); WriteParameter(param, category, "System", "TimeServer", true); @@ -2337,7 +2281,6 @@ function UpdateInput() { WriteModelFiles(); } - function WriteModelFiles() { list_tflite = getTFLITEList(); @@ -2383,7 +2326,6 @@ function WriteModelFiles() { WriteParameter(param, category, "Digits", "Model", false); } - function ReadParameterAll() { category["Analog"]["enabled"] = document.getElementById("Category_Analog_enabled").checked; category["Digits"]["enabled"] = document.getElementById("Category_Digits_enabled").checked; @@ -2391,33 +2333,44 @@ function ReadParameterAll() { category["InfluxDB"]["enabled"] = document.getElementById("Category_InfluxDB_enabled").checked; category["InfluxDBv2"]["enabled"] = document.getElementById("Category_InfluxDBv2_enabled").checked; category["GPIO"]["enabled"] = document.getElementById("Category_GPIO_enabled").checked; - + ReadParameter(param, "TakeImage", "RawImagesLocation", true); ReadParameter(param, "TakeImage", "RawImagesRetention", true); - ReadParameter(param, "TakeImage", "Demo", false); - ReadParameter(param, "TakeImage", "WaitBeforeTakingPicture", false); - ReadParameter(param, "TakeImage", "ImageQuality", false); - ReadParameter(param, "TakeImage", "Brightness", false); - ReadParameter(param, "TakeImage", "Contrast", false); - ReadParameter(param, "TakeImage", "Saturation", false); - ReadParameter(param, "TakeImage", "Sharpness", false); - ReadParameter(param, "TakeImage", "LEDIntensity", false); - ReadParameter(param, "TakeImage", "ImageSize", false); - ReadParameter(param, "TakeImage", "Zoom", false); - ReadParameter(param, "TakeImage", "ZoomMode", false); - ReadParameter(param, "TakeImage", "ZoomOffsetX", false); - ReadParameter(param, "TakeImage", "ZoomOffsetY", false); - ReadParameter(param, "TakeImage", "Grayscale", false); - ReadParameter(param, "TakeImage", "Negative", false); - ReadParameter(param, "TakeImage", "Aec2", false); - ReadParameter(param, "TakeImage", "AutoExposureLevel", false); - ReadParameter(param, "TakeImage", "FixedExposure", false); + ReadParameter(param, "TakeImage", "WaitBeforeTakingPicture", false); + ReadParameter(param, "TakeImage", "CamGainceiling", false); + ReadParameter(param, "TakeImage", "CamQuality", false); + ReadParameter(param, "TakeImage", "CamBrightness", false); + ReadParameter(param, "TakeImage", "CamContrast", false); + ReadParameter(param, "TakeImage", "CamSaturation", false); + ReadParameter(param, "TakeImage", "CamSharpness", false); + ReadParameter(param, "TakeImage", "CamAutoSharpness", false); + ReadParameter(param, "TakeImage", "CamSpecialEffect", false); + ReadParameter(param, "TakeImage", "CamWbMode", false); + ReadParameter(param, "TakeImage", "CamAwb", false); + ReadParameter(param, "TakeImage", "CamAwbGain", false); + ReadParameter(param, "TakeImage", "CamAec", false); + ReadParameter(param, "TakeImage", "CamAec2", false); + ReadParameter(param, "TakeImage", "CamAeLevel", false); + ReadParameter(param, "TakeImage", "CamAecValue", false); + ReadParameter(param, "TakeImage", "CamAgc", false); + ReadParameter(param, "TakeImage", "CamAgcGain", false); + ReadParameter(param, "TakeImage", "CamBpc", false); + ReadParameter(param, "TakeImage", "CamWpc", false); + ReadParameter(param, "TakeImage", "CamRawGma", false); + ReadParameter(param, "TakeImage", "CamLenc", false); + ReadParameter(param, "TakeImage", "CamHmirror", false); + ReadParameter(param, "TakeImage", "CamVflip", false); + ReadParameter(param, "TakeImage", "CamDcw", false); + ReadParameter(param, "TakeImage", "CamZoom", false); + ReadParameter(param, "TakeImage", "CamZoomOffsetX", false); + ReadParameter(param, "TakeImage", "CamZoomOffsetY", false); + ReadParameter(param, "TakeImage", "CamZoomSize", false); + ReadParameter(param, "TakeImage", "LEDIntensity", false); + ReadParameter(param, "TakeImage", "Demo", false); ReadParameter(param, "Alignment", "SearchFieldX", false); ReadParameter(param, "Alignment", "SearchFieldY", false); ReadParameter(param, "Alignment", "AlignmentAlgo", true); - ReadParameter(param, "Alignment", "FlipImageSize", false); - ReadParameter(param, "Alignment", "InitialMirror", false); ReadParameter(param, "Alignment", "InitialRotate", false); ReadParameter(param, "Digits", "Model", false); @@ -2429,10 +2382,15 @@ function ReadParameterAll() { ReadParameter(param, "Analog", "ROIImagesLocation", true); ReadParameter(param, "Analog", "ROIImagesRetention", true); - ReadParameter(param, "PostProcessing", "PreValueUse", false); + // ReadParameter(param, "PostProcessing", "PreValueUse", false); ReadParameter(param, "PostProcessing", "PreValueAgeStartup", true); ReadParameter(param, "PostProcessing", "ErrorMessage", false); ReadParameter(param, "PostProcessing", "CheckDigitIncreaseConsistency", false); + + // ReadParameter(param, "PostProcessing", "ExtendedResolution", false); + // ReadParameter(param, "PostProcessing", "IgnoreLeadingNaN", false); + // ReadParameter(param, "PostProcessing", "IgnoreAllNaN", false); + // ReadParameter(param, "PostProcessing", "AllowNegativeRate", false); ReadParameter(param, "MQTT", "Uri", true); ReadParameter(param, "MQTT", "MainTopic", true); @@ -2468,6 +2426,7 @@ function ReadParameterAll() { ReadParameter(param, "GPIO", "LEDType", false); ReadParameter(param, "GPIO", "LEDNumbers", false); ReadParameter(param, "GPIO", "LEDColor", false); + // Folgende Zeilen sind für Abwärtskompatibität < v9.0.0 notwendig (manchmal parameter auskommentiert) param["GPIO"]["LEDType"]["enabled"] = true; param["GPIO"]["LEDNumbers"]["enabled"] = true; @@ -2485,6 +2444,7 @@ function ReadParameterAll() { ReadParameter(param, "Debug", "LogLevel", false); ReadParameter(param, "Debug", "LogfilesRetention", false); + ReadParameter(param, "System", "Tooltip", false); ReadParameter(param, "System", "TimeZone", true); ReadParameter(param, "System", "Hostname", true); ReadParameter(param, "System", "TimeServer", true); @@ -2497,16 +2457,6 @@ function ReadParameterAll() { // FormatDecimalValue(param, "PostProcessing", "MaxRateValue"); } - -function FormatDecimalValue(_param, _cat, _name) { - for (var j = 1; j <= _param[_cat][_name]["anzParam"]; ++j) { - var _val = _param[_cat][_name]["value"+j]; - _val = _val.replace(",", "."); - _param[_cat][_name]["value"+j] = _val; - } -} - - function UpdateAfterCategoryCheck() { ReadParameterAll(); category["Analog"]["enabled"] = document.getElementById("Category_Analog_enabled").checked; @@ -2521,7 +2471,6 @@ function UpdateAfterCategoryCheck() { UpdateInputIndividual(sel); } - function UpdateExpertModus() { // var _style = 'display:none;'; var _style_pur = 'none'; @@ -2557,6 +2506,22 @@ function UpdateExpertModus() { }); } +function UpdateTooltipModus() { + var _style_pur = 'none'; + var _hidden = true; + + if (!document.getElementById("System_Tooltip_value1").selectedIndex) { + _style_pur = ''; + _hidden = false; + //firework.launch("Tooltip view activated.", 'warning', 5000); + } + + const tooltip = document.querySelectorAll(".tooltip"); + + for (var i = 0; i < tooltip.length; i++) { + tooltip[i].style.display = _style_pur; + } +} function saveTextAsFile() { ReadParameterAll(); @@ -2573,55 +2538,236 @@ function saveTextAsFile() { firework.launch('Configuration saved. It will get applied after the next reboot!', 'success', 5000); if (changeCamValue == 1) { - camSettingsSet(param); + camSettingsSet(); firework.launch('You have changed the camera settings, so creating a new reference image and updating the alignment marks is mandatory!', 'success', 10000); } } } - -function camSettingsSet(_param) { +function camSettingsSet(){ var domainname = getDomainname(); - var xhttp = new XMLHttpRequest(); - var _grayscale = _param["TakeImage"]["Grayscale"].value1; - var _negative = _param["TakeImage"]["Negative"].value1; - var _aec2 = _param["TakeImage"]["Aec2"].value1; - var _FixedExposure = _param["TakeImage"]["FixedExposure"].value1; - var _zoom = _param["TakeImage"]["Zoom"].value1; - - var _zm = _param["TakeImage"]["ZoomMode"].value1; - var _x = _param["TakeImage"]["ZoomOffsetX"].value1; - var _y = _param["TakeImage"]["ZoomOffsetY"].value1; - var _intensity = _param["TakeImage"]["LEDIntensity"].value1; - var _brightness = _param["TakeImage"]["Brightness"].value1; - var _contrast = _param["TakeImage"]["Contrast"].value1; - var _saturation = _param["TakeImage"]["Saturation"].value1; - var _sharpness = _param["TakeImage"]["Sharpness"].value1; - var _ae = _param["TakeImage"]["AutoExposureLevel"].value1; - - var url = domainname + "/editflow?task=cam_settings"; - url = url + "&bri=" + _brightness + "&con=" + _contrast + "&sat=" + _saturation + "&sh=" + _sharpness; - url = url + "&int=" + _intensity + "&gs=" + _grayscale + "&ne=" + _negative + "&z=" + _zoom; - - if (_zoom != '0') { - url = url + "&zm=" + _zm + "&x=" + _x + "&y=" + _y; + document.getElementById("overlay").style.display = "block"; + document.getElementById("overlaytext").innerHTML = "Save Cam Settings..."; + + var _waitb_temp = document.getElementById("TakeImage_WaitBeforeTakingPicture_value1").value; + var _qual_temp = document.getElementById("TakeImage_CamQuality_value1").value; + + var _bri_temp = document.getElementById("TakeImage_CamBrightness_value1").value; + var _con_temp = document.getElementById("TakeImage_CamContrast_value1").value; + var _sat_temp = document.getElementById("TakeImage_CamSaturation_value1").value; + var _shp_temp = document.getElementById("TakeImage_CamSharpness_value1").value; + + var _ashp_temp = document.getElementById("TakeImage_CamAutoSharpness_value1").value; + if (_ashp_temp == '0') { + _ashp_temp = '1'; } else { - url = url + "&zm=0" + "&x=0" + "&y=0"; + _ashp_temp = '0'; } - - url = url + "&ae=" + _ae + "&a2=" + _aec2; - - if (domainname.length > 0){ - url = url + "&host=" + domainname; + + var _spe_temp = document.getElementById("TakeImage_CamSpecialEffect_value1").selectedIndex; + var _wbm_temp = document.getElementById("TakeImage_CamWbMode_value1").selectedIndex; + + var _awb_temp = document.getElementById("TakeImage_CamAwb_value1").selectedIndex; + if (_awb_temp == '0') { + _awb_temp = '1'; + } + else { + _awb_temp = '0'; } - xhttp.open("GET", url, true); - xhttp.send(); + var _awbg_temp = document.getElementById("TakeImage_CamAwbGain_value1").selectedIndex; + if (_awbg_temp == '0') { + _awbg_temp = '1'; + } + else { + _awbg_temp = '0'; + } + + var _aec_temp = document.getElementById("TakeImage_CamAec_value1").selectedIndex; + if (_aec_temp == '0') { + _aec_temp = '1'; + } + else { + _aec_temp = '0'; + } + + var _aec2_temp = document.getElementById("TakeImage_CamAec2_value1").selectedIndex; + if (_aec2_temp == '0') { + _aec2_temp = '1'; + } + else { + _aec2_temp = '0'; + } + + var _ael_temp = document.getElementById("TakeImage_CamAeLevel_value1").value; + var _aecv_temp = document.getElementById("TakeImage_CamAecValue_value1").value; + + var _agc_temp = document.getElementById("TakeImage_CamAgc_value1").selectedIndex; + if (_agc_temp == '0') { + _agc_temp = '1'; + } + else { + _agc_temp = '0'; + } + + var _agcg_temp = document.getElementById("TakeImage_CamAgcGain_value1").value; + + var _bpc_temp = document.getElementById("TakeImage_CamBpc_value1").selectedIndex; + if (_bpc_temp == '0') { + _bpc_temp = '1'; + } + else { + _bpc_temp = '0'; + } + + var _wpc_temp = document.getElementById("TakeImage_CamWpc_value1").selectedIndex; + if (_wpc_temp == '0') { + _wpc_temp = '1'; + } + else { + _wpc_temp = '0'; + } + + var _rgma_temp = document.getElementById("TakeImage_CamRawGma_value1").selectedIndex; + if (_rgma_temp == '0') { + _rgma_temp = '1'; + } + else { + _rgma_temp = '0'; + } + + var _lenc_temp = document.getElementById("TakeImage_CamLenc_value1").selectedIndex; + if (_lenc_temp == '0') { + _lenc_temp = '1'; + } + else { + _lenc_temp = '0'; + } + + var _mirror_temp = document.getElementById("TakeImage_CamHmirror_value1").selectedIndex; + if (_mirror_temp == '0') { + _mirror_temp = '1'; + } + else { + _mirror_temp = '0'; + } + + var _flip_temp = document.getElementById("TakeImage_CamVflip_value1").selectedIndex; + if (_flip_temp == '0') { + _flip_temp = '1'; + } + else { + _flip_temp = '0'; + } + + var _dcw_temp = document.getElementById("TakeImage_CamDcw_value1").selectedIndex; + if (_dcw_temp == '0') { + _dcw_temp = '1'; + } + else { + _dcw_temp = '0'; + } + + var _ledi_temp = document.getElementById("TakeImage_LEDIntensity_value1").value; + + var _zoom_temp = document.getElementById("TakeImage_CamZoom_value1").selectedIndex; + if (_zoom_temp == '0') { + _zoom_temp = '1'; + } + else { + _zoom_temp = '0'; + } + + var _zmode_temp = document.getElementById("TakeImage_CamZoomMode_value1").selectedIndex; + if (_zmode_temp == '0') { + _zmode_temp = '1'; + } + else { + _zmode_temp = '0'; + } + + var _zoomx_temp = document.getElementById("TakeImage_CamZoomOffsetX_value1").value; + var _zoomy_temp = document.getElementById("TakeImage_CamZoomOffsetY_value1").value; + var _zooms_temp = document.getElementById("TakeImage_CamZoomSize_value1").value; + + // bei einmal Alles senden kommt es zu problemen!!!!!!!!!!!!!!!!!!!! + var url_1 = domainname + "/editflow?task=cam_settings"; + url_1 = url_1 + "&waitb=" + _waitb_temp + "&qual=" + _qual_temp; + url_1 = url_1 + "&bri=" + _bri_temp + "&con=" + _con_temp + "&sat=" + _sat_temp + "&shp=" + _shp_temp + "&ashp=" + _ashp_temp; + url_1 = url_1 + "&spe=" + _spe_temp + "&wbm=" + _wbm_temp + "&awb=" + _awb_temp + "&awbg=" + _awbg_temp; + url_1 = url_1 + "&aec=" + _aec_temp + "&aec2=" + _aec2_temp + "&ael=" + _ael_temp + "&aecv=" + _aecv_temp; + + var url_2 = domainname + "/editflow?task=cam_settings"; + url_2 = url_2 + "&agc=" + _agc_temp + "&agcg=" + _agcg_temp + "&bpc=" + _bpc_temp + "&wpc=" + _wpc_temp; + url_2 = url_2 + "&rgma=" + _rgma_temp + "&lenc=" + _lenc_temp + "&mirror=" + _mirror_temp + "&flip=" + _flip_temp; + url_2 = url_2 + "&dcw=" + _dcw_temp + "&ledi=" + _ledi_temp; + + if (_zoom_temp != '0') { + url_2 = url_2 + "&zoom=" + _zoom_temp + "&zooms=" + _zooms_temp; + url_2 = url_2 + "&zoomx=" + _zoomx_temp + "&zoomy=" + _zoomy_temp; + } + else { + url_2 = url_2 + "&zoom=0" + "&zooms=0" + "&zoomx=0" + "&zoomy=0"; + } + + if (domainname.length > 0){ + url_1 = url_1 + "&host=" + domainname; + url_2 = url_2 + "&host=" + domainname; + } + + var durchlaufe = 0; + + function sleep(ms) { + return new Promise(resolve => setTimeout(resolve, ms)); + } + + async function task() { + while (true) { + var xhttp1 = new XMLHttpRequest(); + var xhttp2 = new XMLHttpRequest(); + + if (durchlaufe > 10) { + document.getElementById("overlay").style.display = "none"; + firework.launch('Save Cam Settings aborted, timeout!', 'success', 5000); + return; + } + + try { + xhttp1.open("GET", url_1, false); + xhttp1.send(); + xhttp2.open("GET", url_2, false); + xhttp2.send(); + } catch (error){} + + if ((xhttp1.responseText == "CamSettingsSet") && (xhttp2.responseText == "CamSettingsSet")) { + document.getElementById("overlay").style.display = "none"; + return; + } + else { + // Get status + var _xhttp = new XMLHttpRequest(); + durchlaufe = durchlaufe + 1; + + try { + _xhttp.open("GET", domainname + "/statusflow", false); + _xhttp.send(); + } + catch (error){} + + document.getElementById("overlaytext").innerHTML = "Device is busy, plase waiting...

Current step: " + _xhttp.responseText; + console.log("Device is busy, waiting 2s then checking again..."); + await sleep(2000); + } + } + } + + setTimeout(function() { // Delay so the overlay gets shown + task(); + }, 1); } - function doReboot() { if (confirm("Are you sure you want to reboot?")) { var stringota = getDomainname() + "/reboot"; @@ -2632,6 +2778,13 @@ function doReboot() { } } +function FormatDecimalValue(_param, _cat, _name) { + for (var j = 1; j <= _param[_cat][_name]["anzParam"]; ++j) { + var _val = _param[_cat][_name]["value"+j]; + _val = _val.replace(",", "."); + _param[_cat][_name]["value"+j] = _val; + } +} function editConfigRaw() { if (confirm("Proceed to switch to raw edit mode? Unsaved changes will get lost")) { @@ -2643,7 +2796,6 @@ function editConfigRaw() { } } - function numberChanged() { var sel = document.getElementById("Numbers_value1"); _neu = sel.selectedIndex; @@ -2654,7 +2806,6 @@ function numberChanged() { _selInflux.selectedIndex = _neu } } - function numberInfluxDBv2Changed() { var sel = document.getElementById("NumbersInfluxDBv2_value1"); @@ -2672,7 +2823,6 @@ function numberInfluxDBv2Changed() { } } - function numberInfluxDBChanged() { var sel = document.getElementById("NumbersInfluxDB_value1"); _neu = sel.selectedIndex; @@ -2689,11 +2839,327 @@ function numberInfluxDBChanged() { } } +function getParameterByName(name, url = window.location.href) { + name = name.replace(/[\[\]]/g, '\\$&'); + var regex = new RegExp('[?&]' + name + '(=([^&#]*)|&|#|$)'), + results = regex.exec(url); + + if (!results) {return null;} + if (!results[2]) {return '';} + + return decodeURIComponent(results[2].replace(/\+/g, ' ')); +} + +function InvertEnableItem(_cat, _param) { + _zw = _cat + "_" + _param + "_enabled"; + _isOn = document.getElementById(_zw).checked; + + _color = "rgb(122, 122, 122)"; + + if (_isOn) { + _color = "black"; + } + + _zw = _cat + "_" + _param + "_text"; + document.getElementById(_zw).disabled = !_isOn; + document.getElementById(_zw).style.color = _color; + + setEnabled(_cat + "_" + _param, _isOn); + + for (var j = 1; j <= param[_cat][_param]["anzParam"]; ++j) { + document.getElementById(_cat+"_"+_param+"_value"+j).disabled = !_isOn; + document.getElementById(_cat+"_"+_param+"_value"+j).style.color = _color; + } +} + +function setEnabled(className, enabled) { + _color = "rgb(122, 122, 122)"; + + if (enabled) { + _color = "black"; + } + + let elements = document.getElementsByClassName(className); + for (i = 0; i < elements.length; i++) { + if (enabled) { + elements[i].classList.remove("disabled"); + } + else { + elements[i].classList.add("disabled"); + } + + let inputs = elements[i].getElementsByTagName("input"); + for (j = 0; j < inputs.length; j++) { + if (inputs[j].id.endsWith("_enabled")) { + continue; + } + + inputs[j].style.color = _color; + if (enabled) { + inputs[j].removeAttribute("disabled"); + } + else { + inputs[j].setAttribute("disabled", "disabled"); + } + } + } +} + +function setVisible(className, visible) { + let elements = document.getElementsByClassName(className); + + for (i = 0; i < elements.length; i++) { + if (visible) { + elements[i].classList.remove("hidden"); + } + else { + elements[i].classList.add("hidden"); + } + } +} + +function EnDisableItem(_status, _param, _category, _cat, _name, _optional, _number = -1) { + // _status = _category[_cat]["enabled"]; + + _color = "rgb(122, 122, 122)"; + + if (_status) { + _color = "black"; + } + + if (_optional) { + document.getElementById(_cat+"_"+_name+"_enabled").disabled = !_status; + document.getElementById(_cat+"_"+_name+"_enabled").style.color = _color; + } + + if (_number == -1) { + if (!_param[_cat][_name]["enabled"]) { + _status = false; + _color = "rgb(122, 122, 122)"; + } + } + else { + if (!NUMBERS[_number][_cat][_name]["enabled"]) { + _status = false; + _color = "rgb(122, 122, 122)"; + } + } + + document.getElementById(_cat+"_"+_name+"_text").disabled = !_status; + document.getElementById(_cat+"_"+_name+"_text").style.color = _color; + + setEnabled(_cat+"_"+_name, _status); + + for (var j = 1; j <= _param[_cat][_name]["anzParam"]; ++j) { + document.getElementById(_cat+"_"+_name+"_value"+j).disabled = !_status; + document.getElementById(_cat+"_"+_name+"_value"+j).style.color = _color; + } +} + +function ReadParameter(_param, _cat, _name, _optional, _number = -1) { + if (_number > -1) { + if (_cat == "Digits") { + _cat = "digit"; + } + + if (_cat == "Analog") { + _cat = "analog"; + } + + if ((NUMBERS[_number] == undefined) || (NUMBERS[_number][_cat] == undefined) || (NUMBERS[_number][_cat][_name] == undefined)) { + return; + } + + if (_optional) { + NUMBERS[_number][_cat][_name]["enabled"] = document.getElementById(_cat+"_"+_name+"_enabled").checked; + } + + for (var j = 1; j <= _param[_cat][_name]["anzParam"]; ++j) { + let element = document.getElementById(_cat+"_"+_name+"_value"+j); + + if (element.tagName.toLowerCase() == "select") { + NUMBERS[_number][_cat][_name]["value"+j] = element.selectedIndex > -1 ? element.options[element.selectedIndex].value : ""; + } + else if ((element.getAttribute("type") != null) && (element.getAttribute("type").toLowerCase() == "checkbox")) { + NUMBERS[_number][_cat][_name]["value"+j] = element.checked; + } + else { + if ((NUMBERS[_number][_cat][_name].checkRegExList != null) && (NUMBERS[_number][_cat][_name].checkRegExList[j-1] != null)) { + if (!element.value.match(NUMBERS[_cat][_name].checkRegExList[j-1])) { + element.classList.add("invalid-input"); + } + else { + element.classList.remove("invalid-input"); + } + } + + NUMBERS[_number][_cat][_name]["value"+j] = element.value; + } + } + } + else + { + if (_optional) { + _param[_cat][_name]["enabled"] = document.getElementById(_cat+"_"+_name+"_enabled").checked; + } + + for (var j = 1; j <= _param[_cat][_name]["anzParam"]; ++j) { + let element = document.getElementById(_cat+"_"+_name+"_value"+j); + + if (element.tagName.toLowerCase() == "select") { + _param[_cat][_name]["value"+j] = element.selectedIndex > -1 ? element.options[element.selectedIndex].value : ""; + } + else if ((element.getAttribute("type") != null) && (element.getAttribute("type").toLowerCase() == "checkbox")) { + _param[_cat][_name]["value"+j] = element.checked; + } + else { + if ((_param[_cat][_name].checkRegExList != null) && (_param[_cat][_name].checkRegExList[j-1] != null)) { + if (!element.value.match(_param[_cat][_name].checkRegExList[j-1])) { + element.classList.add("invalid-input"); + } + else { + element.classList.remove("invalid-input"); + } + } + + _param[_cat][_name]["value"+j] = element.value; + } + } + } +} + +function WriteParameter(_param, _category, _cat, _name, _optional, _number = -1) { + let anzpara; + try { + anzpara = _param[_cat][_name].anzParam; + } + catch (error) { + firework.launch("Parameter '" + _name + "' in category '" + _cat + "' is unknown!", 'danger', 30000); + return; + } + + if (_number > -1) { + if ((NUMBERS[_number] == undefined) || (NUMBERS[_number][_cat] == undefined) || (NUMBERS[_number][_cat][_name] == undefined)) { + return; + } + + if (_optional) { + document.getElementById(_cat+"_"+_name+"_enabled").checked = NUMBERS[_number][_cat][_name]["enabled"]; + + for (var j = 1; j <= anzpara; ++j) { + document.getElementById(_cat+"_"+_name+"_value"+j).disabled = !NUMBERS[_number][_cat][_name]["enabled"]; + } + } + + document.getElementById(_cat+"_"+_name+"_text").style.color = "black" + setEnabled(_cat+"_"+_name, true); + + for (var j = 1; j <= anzpara; ++j) { + let element = document.getElementById(_cat+"_"+_name+"_value"+j); + + if (element.tagName.toLowerCase() == "select") { + var textToFind = NUMBERS[_number][_cat][_name]["value"+j]; + + if (textToFind == undefined) { + continue; + } + + _isFound = false; + element.selectedIndex = -1; + + for (var i = 0; i < element.options.length; i++) { + if (element.options[i].value.toLowerCase() === textToFind.toLowerCase()) { + element.selectedIndex = i; + _isFound = true; + break; + } + } + + if (!_isFound) { + _zw_txt = "In the selected field the value '" + textToFind + "' in the parameter '"; + _zw_txt = _zw_txt + _cat + "' in the field '" + _name + "' is invalid. PLEASE CHECK BEFORE SAVING!"; + firework.launch(_zw_txt, 'warning', 10000); + } + } + else if ((element.getAttribute("type") != null) && (element.getAttribute("type").toLowerCase() == "checkbox")) { + element.checked = NUMBERS[_number][_cat][_name]["value"+j] == "true"; + } + else { + element.value = NUMBERS[_number][_cat][_name]["value"+j]; + } + } + } + else { + if (_optional) { + document.getElementById(_cat+"_"+_name+"_enabled").checked = _param[_cat][_name]["enabled"]; + + for (var j = 1; j <= anzpara; ++j) { + document.getElementById(_cat+"_"+_name+"_value"+j).disabled = !_param[_cat][_name]["enabled"]; + } + } + + document.getElementById(_cat+"_"+_name+"_text").style.color = "black" + setEnabled(_cat+"_"+_name, true); + + for (var j = 1; j <= anzpara; ++j) { + let element = document.getElementById(_cat+"_"+_name+"_value"+j); + + if (element.tagName.toLowerCase() == "select") { + var textToFind = _param[_cat][_name]["value"+j]; + + if (textToFind == undefined) { + continue; + } + + _isFound = false; + element.selectedIndex = -1; + + for (var i = 0; i < element.options.length; i++) { + if (element.options[i].value.toLowerCase() === textToFind.toLowerCase()) { + element.selectedIndex = i; + _isFound = true; + break; + } + } + + if (!_isFound) { + _zw_txt = "In the selected field the value '" + textToFind + "' in the section '"; + _zw_txt = _zw_txt + _cat + "' in the field '" + _name + "' is invalid. PLEASE CHECK BEFORE SAVING!"; + firework.launch(_zw_txt, 'warning', 10000); + } + + } + else if ((element.getAttribute("type") != null) && (element.getAttribute("type").toLowerCase() == "checkbox")) { + element.checked = _param[_cat][_name]["value"+j] == "true"; + } + else { + element.value = _param[_cat][_name]["value"+j]; + } + } + } + + ///////////////// am Ende, falls Kategorie als gesamtes nicht ausgewählt --> deaktivieren + if (_category[_cat]["enabled"] == false) { + if (_optional) { + document.getElementById(_cat+"_"+_name+"_enabled").disabled = true; + + for (var j = 1; j <= anzpara; ++j) { + document.getElementById(_cat+"_"+_name+"_value"+j).disabled = true; + } + } + + document.getElementById(_cat+"_"+_name+"_text").style="color: gray;" + setEnabled(_cat+"_"+_name, false); + } + + EnDisableItem(_category[_cat]["enabled"], _param, _category, _cat, _name, _optional, _number); +} /* hash #description open the details part of the page */ function openDescription() { if(window.location.hash) { var hash = window.location.hash.substring(1); //Puts hash in variable, and removes the # character + if(hash == 'description') { document.getElementById("desc_details").open = true; document.getElementById("reboot").style.display = "none"; @@ -2706,6 +3172,5 @@ openDescription(); LoadConfigNeu(); - diff --git a/sd-card/html/edit_digits.html b/sd-card/html/edit_digits.html index fbe06f51..2510c669 100644 --- a/sd-card/html/edit_digits.html +++ b/sd-card/html/edit_digits.html @@ -11,7 +11,7 @@ p {font-size: 1em;} input[type=number] { - width: 40px; + width: 60px; margin-right: 10px; padding: 3px 5px; display: inline-block; @@ -123,17 +123,25 @@ + + - - - + + +
Number Sequence:
+ + + + + +
@@ -146,15 +154,26 @@ + ROI: + - - - - + + + + + + + + + + + + + Multiplier:
(only based on order) @@ -162,8 +181,12 @@ Multiplier:
(order + decimal shift: ) - - + + + + + + @@ -173,10 +196,12 @@ + x: Δx: - + + y: Δy: @@ -186,11 +211,11 @@
-The following settings are only used for easier setup, they are not persisted on the device:
-
-
-
- + The following settings are only used for easier setup, they are not persisted on the device:
+
+
+
+

@@ -201,10 +226,14 @@ The following settings are only used for easier setup, they are not persi + Reference Image: - - + + + + + @@ -491,6 +520,7 @@ The following settings are only used for easier setup, they are not persi } var _index = document.getElementById("index"); + while (_index.length){ _index.remove(0); } @@ -582,7 +612,7 @@ The following settings are only used for easier setup, they are not persi if(window.location.hash) { var hash = window.location.hash.substring(1); //Puts hash in variable, and removes the # character if(hash == 'description') { - document.getElementById("desc_details").open = true; + document.getElementById("desc_details").open = false; } } } @@ -590,14 +620,21 @@ The following settings are only used for easier setup, they are not persi function init() { openDescription(); domainname = getDomainname(); - canvas.addEventListener('mousedown', mouseDown, false); - canvas.addEventListener('mouseup', mouseUp, false); - canvas.addEventListener('mousemove', mouseMove, false); - loadCanvas(domainname + "/fileserver/config/reference.jpg"); - loadConfig(domainname); + + if (!loadConfig(domainname)) { + firework.launch('Configuration could not be loaded! Please reload the page!', 'danger', 30000); + return; + } + ParseConfig(); param = getConfigParameters(); cofcat = getConfigCategory(); + + canvas.addEventListener('mousedown', mouseDown, false); + canvas.addEventListener('mouseup', mouseUp, false); + canvas.addEventListener('mousemove', mouseMove, false); + loadCanvas(domainname + "/fileserver/config/reference.jpg"); + UpdateNUMBERS(); /* Check if the ROIs are equidistant. Only if not, untick the checkbox */ @@ -717,6 +754,7 @@ The following settings are only used for easier setup, they are not persi } erg = CreateNUMBER(_numbernew); + if (erg != "") { firework.launch(erg, 'danger', 30000); } @@ -844,14 +882,17 @@ The following settings are only used for easier setup, they are not persi function mouseUp() { drag = false; + if (rect.w < 0) { rect.w = -rect.w rect.startX-=rect.w } + if (rect.h < 0) { rect.h = -rect.h rect.startY-=rect.h } + document.getElementById("refdx").value = rect.w; document.getElementById("refdy").value = rect.h; document.getElementById("refx").value = rect.startX; @@ -876,10 +917,12 @@ The following settings are only used for easier setup, they are not persi } document.getElementById("refdx").value = rect.w; document.getElementById("refdy").value = rect.h; + draw(); } else { draw(); + var canvas = document.getElementById('canvas'); var context = canvas.getContext('2d'); @@ -915,10 +958,10 @@ The following settings are only used for easier setup, they are not persi rect.startX = document.getElementById("refx").value; rect.startY = document.getElementById("refy").value; - draw(); if (lockSpaceEquidistant) { makeX_SpaceEquidistant(); - } + } + draw(); } document.getElementById("saveroi").disabled = false; @@ -990,11 +1033,13 @@ The following settings are only used for easier setup, they are not persi _roialt= sel.options[sel.selectedIndex].text; var _roinew = prompt("Please enter a new name for the selected ROI", _roialt); + if (_roinew === null) { return; //break out of the function early because prompt was aborted } erg = RenameROI(_number, "digit", _roialt, _roinew); + if (erg != "") { firework.launch(erg, 'danger', 30000); } diff --git a/sd-card/html/edit_reference.html b/sd-card/html/edit_reference.html index e9fc087b..d6359bd4 100644 --- a/sd-card/html/edit_reference.html +++ b/sd-card/html/edit_reference.html @@ -155,12 +155,9 @@
- + -

- *) A change of this parameter only is applied on the next update of the Refrence Image. - @@ -170,157 +167,221 @@ + + + + + + - - - - - + + + - - + + + - - + + + + + + + + + + + + - - - - + + + + - + + - - - - + + + + - + + - + - - + + + - + + - + - - + + - + + - + + + + + - - - - + + 0 + + + - - - - + + + + - - - - - - - - - +
+ Zoom + + + $TOOLTIP_TakeImage_CamZoom + + - - $TOOLTIP_TakeImage_Zoom - - + $TOOLTIP_TakeImage_ZoomOffsetX$TOOLTIP_TakeImage_CamZoomOffsetX
+ + - - + $TOOLTIP_TakeImage_ZoomMode$TOOLTIP_TakeImage_CamZoomSize + + - - + $TOOLTIP_TakeImage_ZoomOffsetY$TOOLTIP_TakeImage_CamZoomOffsetY
+ SpecialEffect: + + + $TOOLTIP_TakeImage_CamSpecialEffect + Auto-exposure Control 2 + + + $TOOLTIP_TakeImage_CamAec2
- - $TOOLTIP_Alignment_InitialMirror - LED intensity: *) + + Mirror Image + + + $TOOLTIP_TakeImage_CamHmirror + LED intensity: + oninput="(!validity.rangeOverflow||(value=100)) && (!validity.rangeUnderflow||(value=0)) && (!validity.stepMismatch||(value=parseInt(this.value)));"> $TOOLTIP_TakeImage_LEDIntensity$TOOLTIP_TakeImage_LEDIntensity
- - $TOOLTIP_Alignment_FlipImageSize - Brightness: *) + + Flip Image + + + $TOOLTIP_TakeImage_CamVflip + Brightness: - - 0 + + 0 $TOOLTIP_TakeImage_Brightness$TOOLTIP_TakeImage_CamBrightness
+ + - degree - $TOOLTIP_Alignment_InitialRotate - Contrast: *) + degree + $TOOLTIP_Alignment_InitialRotate + Contrast: - - 0 + + 0 $TOOLTIP_TakeImage_Contrast$TOOLTIP_TakeImage_CamContrast
+ + - degree + degree - Saturation: *) + + Saturation: - - 0 + + 0 $TOOLTIP_TakeImage_Saturation$TOOLTIP_TakeImage_CamSaturation
- + Auto-exposure Control + + + $TOOLTIP_TakeImage_CamAec + Auto Exposure Level: + - $TOOLTIP_TakeImage_Negative - - $TOOLTIP_TakeImage_Aec2$TOOLTIP_TakeImage_CamAeLevel
- - $TOOLTIP_TakeImage_Grayscale - Auto Exposure Level: *) + + AutoSharpness + + + $TOOLTIP_TakeImage_CamAutoSharpness + Sharpness: - - 0 + + 0 $TOOLTIP_TakeImage_AutoExposureLevel
- - $TOOLTIP_TakeImage_FixedExposure - Sharpness: *) - - - 0 - $TOOLTIP_TakeImage_Sharpness$TOOLTIP_TakeImage_CamSharpness
- - - + + + +
+ + + +
@@ -334,23 +395,7 @@ imageObj = new Image(), isActReference = false, param, - _rotate_temp, - _mirror_temp, - _isize_temp, - _grayscale_temp, - _negative_temp, - _aec2_temp, - _FixedExposure_temp, - _zoom_temp, - _zm_temp, - _x_temp, - _y_temp, - _intensity_temp, - _brightness_temp, - _contrast_temp, - _saturation_temp, - _sharpness_temp, - _ae_temp; + category; function doReboot() { if (confirm("Are you sure you want to reboot? Did you save the config?")) { @@ -365,386 +410,487 @@ function cameraParameterChanged() { document.getElementById("savereferenceimage").disabled = true; - if(document.getElementById("zoom").checked) { - document.getElementById("zoommode").disabled = false; - document.getElementById("zoomoffsetx").disabled = false; - document.getElementById("zoomoffsety").disabled = false; + if(!document.getElementById("TakeImage_CamZoom_value1").selectedIndex) { + // EnDisableItem(_status, _param, _category, _cat, _name, _optional, _number = -1) + EnDisableItem(true, param, category, "TakeImage", "CamZoomOffsetX", false); + EnDisableItem(true, param, category, "TakeImage", "CamZoomOffsetY", false); + EnDisableItem(true, param, category, "TakeImage", "CamZoomSize", false); } else { - document.getElementById("zoommode").disabled = true; - document.getElementById("zoomoffsetx").disabled = true; - document.getElementById("zoomoffsety").disabled = true; - } + EnDisableItem(false, param, category, "TakeImage", "CamZoomOffsetX", false); + EnDisableItem(false, param, category, "TakeImage", "CamZoomOffsetY", false); + EnDisableItem(false, param, category, "TakeImage", "CamZoomSize", false); + } + + if(!document.getElementById("TakeImage_CamAutoSharpness_value1").selectedIndex) { + EnDisableItem(false, param, category, "TakeImage", "CamSharpness", false); + } + else { + EnDisableItem(true, param, category, "TakeImage", "CamSharpness", false); + } } function cameraParameterChangedDR() { - document.getElementById("savereferenceimage").disabled = true; + //document.getElementById("savereferenceimage").disabled = true; drawRotated(); } // Create New Reference, Update Image - function doTakeReference(){ + function doTakeReference(){ + var domainname = getDomainname(); + document.getElementById("overlay").style.display = "block"; document.getElementById("overlaytext").innerHTML = "Taking new image..."; + + EnDisableItem(true, param, category, "TakeImage", "CamBrightness", false); + EnDisableItem(true, param, category, "TakeImage", "CamSaturation", false); + EnDisableItem(true, param, category, "TakeImage", "CamContrast", false); - document.getElementById("grayscale").disabled = false; - document.getElementById("negative").disabled = false; - document.getElementById("aec2").disabled = false; - document.getElementById("FixedExposure").disabled = false; - - document.getElementById("zoom").disabled = false; - - if(document.getElementById("zoom").checked) { - document.getElementById("zoommode").disabled = false; - document.getElementById("zoomoffsetx").disabled = false; - document.getElementById("zoomoffsety").disabled = false; + EnDisableItem(true, param, category, "TakeImage", "CamAutoSharpness", false); + + if(!document.getElementById("TakeImage_CamAutoSharpness_value1").selectedIndex) { + EnDisableItem(false, param, category, "TakeImage", "CamSharpness", false); } else { - document.getElementById("zoommode").disabled = true; - document.getElementById("zoomoffsetx").disabled = true; - document.getElementById("zoomoffsety").disabled = true; + EnDisableItem(true, param, category, "TakeImage", "CamSharpness", false); + } + + EnDisableItem(true, param, category, "TakeImage", "CamZoom", false); + + if(!document.getElementById("TakeImage_CamZoom_value1").selectedIndex) { + EnDisableItem(true, param, category, "TakeImage", "CamZoomOffsetX", false); + EnDisableItem(true, param, category, "TakeImage", "CamZoomOffsetY", false); + EnDisableItem(true, param, category, "TakeImage", "CamZoomSize", false); } - - document.getElementById("TakeImage_AutoExposureLevel_value1").disabled = false; - document.getElementById("finerotate").disabled = false; - document.getElementById("prerotateangle").disabled = false; + else { + EnDisableItem(false, param, category, "TakeImage", "CamZoomOffsetX", false); + EnDisableItem(false, param, category, "TakeImage", "CamZoomOffsetY", false); + EnDisableItem(false, param, category, "TakeImage", "CamZoomSize", false); + } + + EnDisableItem(true, param, category, "TakeImage", "CamAec", false); + EnDisableItem(true, param, category, "TakeImage", "CamAec2", false); + EnDisableItem(true, param, category, "TakeImage", "CamAeLevel", false); + + EnDisableItem(true, param, category, "TakeImage", "CamHmirror", false); + EnDisableItem(true, param, category, "TakeImage", "CamVflip", false); + + EnDisableItem(true, param, category, "TakeImage", "CamSpecialEffect", false); + + EnDisableItem(true, param, category, "TakeImage", "LEDIntensity", false); + + document.getElementById("ExpertModus_enabled").disabled = false; + + document.getElementById("FineRotate_value1").disabled = false; + document.getElementById("FineRotate_text").style.color = "black"; + document.getElementById("PreRotateAngle_value1").disabled = false; + document.getElementById("PreRotateAngle_text").style.color = "black"; document.getElementById("showcurrentreference").disabled = false; document.getElementById("startreference").disabled = true; document.getElementById("updatereferenceimage").disabled = false; document.getElementById("savereferenceimage").disabled = false; + + var _aec_temp = document.getElementById("TakeImage_CamAec_value1").selectedIndex; + if (_aec_temp == '0') { + _aec_temp = '1'; + } + else { + _aec_temp = '0'; + } + + var _aec2_temp = document.getElementById("TakeImage_CamAec2_value1").selectedIndex; + if (_aec2_temp == '0') { + _aec2_temp = '1'; + } + else { + _aec2_temp = '0'; + } - if (param["Alignment"]["InitialMirror"].found) { - document.getElementById("mirror").disabled = false; + var _mirror_temp = document.getElementById("TakeImage_CamHmirror_value1").selectedIndex; + if (_mirror_temp == '0') { + _mirror_temp = '1'; } else { - document.getElementById("labelmirror").style = "color:lightgrey;"; + _mirror_temp = '0'; } - - if (param["Alignment"]["FlipImageSize"].found) { - document.getElementById("flip").disabled = false; + + var _flip_temp = document.getElementById("TakeImage_CamVflip_value1").selectedIndex; + if (_flip_temp == '0') { + _flip_temp = '1'; } else { - document.getElementById("labelflip").style = "color:lightgrey;"; + _flip_temp = '0'; + } + + var _zoom_temp = document.getElementById("TakeImage_CamZoom_value1").selectedIndex; + if (_zoom_temp == '0') { + _zoom_temp = '1'; } + else { + _zoom_temp = '0'; + } + + var _ashp_temp = document.getElementById("TakeImage_CamAutoSharpness_value1").value; + if (_ashp_temp == '0') { + _ashp_temp = '1'; + } + else { + _ashp_temp = '0'; + } + + var _zoomx_temp = document.getElementById("TakeImage_CamZoomOffsetX_value1").value; + var _zoomy_temp = document.getElementById("TakeImage_CamZoomOffsetY_value1").value; + var _zooms_temp = document.getElementById("TakeImage_CamZoomSize_value1").value; + + var _ledi_temp = document.getElementById("TakeImage_LEDIntensity_value1").value; + + var _bri_temp = document.getElementById("TakeImage_CamBrightness_value1").value; + var _con_temp = document.getElementById("TakeImage_CamContrast_value1").value; + var _sat_temp = document.getElementById("TakeImage_CamSaturation_value1").value; + var _shp_temp = document.getElementById("TakeImage_CamSharpness_value1").value; - document.getElementById("TakeImage_Brightness_value1").disabled = false; - document.getElementById("TakeImage_Contrast_value1").disabled = false; - document.getElementById("TakeImage_Saturation_value1").disabled = false; - document.getElementById("TakeImage_Sharpness_value1").disabled = false; - document.getElementById("TakeImage_LEDIntensity_value1").disabled = false; - - setTimeout(function() { - var xhttp = new XMLHttpRequest(); - var domainname = getDomainname(); - - var _grayscale = document.getElementById("grayscale").checked ? '1' : '0'; - var _negative = document.getElementById("negative").checked ? '1' : '0'; - var _aec2 = document.getElementById("aec2").checked ? '1' : '0'; - var _FixedExposure = document.getElementById("FixedExposure").checked ? '1' : '0'; - var _zoom = document.getElementById("zoom").checked ? '1' : '0'; + var _ael_temp = document.getElementById("TakeImage_CamAeLevel_value1").value; + var _effect_temp = document.getElementById("TakeImage_CamSpecialEffect_value1").selectedIndex; + + var url = domainname + "/editflow?task=test_take"; + url = url + "&bri=" + _bri_temp + "&con=" + _con_temp + "&sat=" + _sat_temp + "&shp=" + _shp_temp; + url = url + "&ashp=" + _ashp_temp + "&ledi=" + _ledi_temp + "&spe=" + _effect_temp + "&zoom=" + _zoom_temp; - var _zm = document.getElementById("zoommode").value; - if (_zm == '') { - _zm = '0'; - } - - var _x = document.getElementById("zoomoffsetx").value; - if (_x == '') { - _x = '0'; - } - - var _y = document.getElementById("zoomoffsety").value; - if (_y == '') { - _y = '0'; - } - - var _intensity = document.getElementById("TakeImage_LEDIntensity_value1").value; - if (_intensity == '') { - _intensity = '50'; - } - - var _brightness = document.getElementById("TakeImage_Brightness_value1").value; - var _contrast = document.getElementById("TakeImage_Contrast_value1").value; - var _saturation = document.getElementById("TakeImage_Saturation_value1").value; - var _sharpness = document.getElementById("TakeImage_Sharpness_value1").value; - - var _ae = document.getElementById("TakeImage_AutoExposureLevel_value1").value; - - if (_grayscale == '1') { - param["TakeImage"]["Grayscale"].value1 = "true"; - } else { - param["TakeImage"]["Grayscale"].value1 = "false"; - } - if (_negative == '1') { - param["TakeImage"]["Negative"].value1 = "true"; - } else { - param["TakeImage"]["Negative"].value1 = "false"; - } - if (_aec2 == '1') { - param["TakeImage"]["Aec2"].value1 = "true"; - } else { - param["TakeImage"]["Aec2"].value1 = "false"; - } - if (_FixedExposure == '1') { - param["TakeImage"]["FixedExposure"].value1 = "true"; - } else { - param["TakeImage"]["FixedExposure"].value1 = "false"; - } - if (_zoom == '1') { - param["TakeImage"]["Zoom"].value1 = "true"; - } else { - param["TakeImage"]["Zoom"].value1 = "false"; - } - - param["TakeImage"]["ZoomMode"].value1 = _zm; - param["TakeImage"]["ZoomOffsetX"].value1 = _x; - param["TakeImage"]["ZoomOffsetY"].value1 = _y; - param["TakeImage"]["LEDIntensity"].value1 = _intensity; - param["TakeImage"]["Brightness"].value1 = _brightness; - param["TakeImage"]["Contrast"].value1 = _contrast; - param["TakeImage"]["Saturation"].value1 = _saturation; - param["TakeImage"]["Sharpness"].value1 = _sharpness; - param["TakeImage"]["AutoExposureLevel"].value1 = _ae; - - var url = domainname + "/editflow?task=test_take"; - url = url + "&bri=" + _brightness + "&con=" + _contrast + "&sat=" + _saturation + "&sh=" + _sharpness; - url = url + "&int=" + _intensity + "&gs=" + _grayscale + "&ne=" + _negative + "&z=" + _zoom; - - if (_zoom != '0') { - url = url + "&zm=" + _zm + "&x=" + _x + "&y=" + _y; - } - else { - url = url + "&zm=0" + "&x=0" + "&y=0"; - } + if (_zoom_temp != '0') { + url = url + "&zooms=" + _zooms_temp + "&zoomx=" + _zoomx_temp + "&zoomy=" + _zoomy_temp; + } + else { + url = url + "&zooms=0" + "&zoomx=0" + "&zoomy=0"; + } - url = url + "&ae=" + _ae + "&a2=" + _aec2; + url = url + "&aec=" + _aec_temp + "&ael=" + _ael_temp + "&aec2=" + _aec2_temp; + url = url + "&mirror=" + _mirror_temp + "&flip=" + _flip_temp; - if (domainname.length > 0){ - url = url + "&host=" + domainname; - } + if (domainname.length > 0){ + url = url + "&host=" + domainname; + } - xhttp.open("GET", url, true); - xhttp.send(); + var durchlaufe = 0; + + function sleep(ms) { + return new Promise(resolve => setTimeout(resolve, ms)); + } + + async function task() { + while (true) { + var xhttp = new XMLHttpRequest(); + + if (durchlaufe > 15) { + document.getElementById("overlay").style.display = "none"; + firework.launch('Image capture aborted, timeout!', 'warning', 5000); + return; + } + + try { + xhttp.open("GET", url, false); + xhttp.send(); + } catch (error){} - var _url = domainname + "/img_tmp/raw.jpg" + "?session=" + Math.floor((Math.random() * 1000000) + 1); - - isActReference = false; - loadCanvas(_url, true); - camSettingsSet(); - - }, 1); // Delay so the overlay gets shown - } + if (xhttp.responseText != "DeviceIsBusy") { + var _url = domainname + "/img_tmp/raw.jpg" + "?session=" + Math.floor((Math.random() * 1000000) + 1); + loadCanvas(_url, true); + isActReference = false; + return; + } + else { + // Get status + var _xhttp = new XMLHttpRequest(); + durchlaufe = durchlaufe + 1; + + try { + _xhttp.open("GET", domainname + "/statusflow", false); + _xhttp.send(); + } + catch (error){} + + document.getElementById("overlaytext").innerHTML = "Device is busy, plase waiting...

Current step: " + _xhttp.responseText; + console.log("Device is busy, waiting 5s then checking again..."); + await sleep(2000); + } + } + } + + setTimeout(function() { // Delay so the overlay gets shown + task(); + }, 1); + } function camSettingsSet(){ var domainname = getDomainname(); - var xhttp = new XMLHttpRequest(); - var _grayscale = '0'; - var _negative = '0'; - var _aec2 = '0'; - var _FixedExposure = '0'; - var _zoom = '0'; + document.getElementById("overlay").style.display = "block"; + document.getElementById("overlaytext").innerHTML = "Save Cam Settings..."; - if (_grayscale_temp == "true") { - _grayscale = '1'; + var _aec_temp = document.getElementById("TakeImage_CamAec_value1").selectedIndex; + if (_aec_temp == '0') { + _aec_temp = '1'; } - if (_negative_temp == "true") { - _negative = '1'; + else { + _aec_temp = '0'; + } + + var _aec2_temp = document.getElementById("TakeImage_CamAec2_value1").selectedIndex; + if (_aec2_temp == '0') { + _aec2_temp = '1'; + } + else { + _aec2_temp = '0'; + } + + var _mirror_temp = document.getElementById("TakeImage_CamHmirror_value1").selectedIndex; + if (_mirror_temp == '0') { + _mirror_temp = '1'; + } + else { + _mirror_temp = '0'; + } + + var _flip_temp = document.getElementById("TakeImage_CamVflip_value1").selectedIndex; + if (_flip_temp == '0') { + _flip_temp = '1'; + } + else { + _flip_temp = '0'; + } + + var _zoom_temp = document.getElementById("TakeImage_CamZoom_value1").selectedIndex; + if (_zoom_temp == '0') { + _zoom_temp = '1'; + } + else { + _zoom_temp = '0'; } - if (_aec2_temp == "true") { - _aec2 = '1'; + + var _ashp_temp = document.getElementById("TakeImage_CamAutoSharpness_value1").value; + if (_ashp_temp == '0') { + _ashp_temp = '1'; } - if (_FixedExposure_temp == "true") { - _FixedExposure = '1'; - } - if (_zoom_temp == "true") { - _zoom = '1'; + else { + _ashp_temp = '0'; } - var url = domainname + "/editflow?task=cam_settings"; - url = url + "&bri=" + _brightness_temp + "&con=" + _contrast_temp + "&sat=" + _saturation_temp + "&sh=" + _sharpness_temp; - url = url + "&int=" + _intensity_temp + "&gs=" + _grayscale + "&ne=" + _negative + "&z=" + _zoom; + var _zoomx_temp = document.getElementById("TakeImage_CamZoomOffsetX_value1").value; + var _zoomy_temp = document.getElementById("TakeImage_CamZoomOffsetY_value1").value; + var _zooms_temp = document.getElementById("TakeImage_CamZoomSize_value1").value; - if (_zoom != '0') { - url = url + "&zm=" + _zm_temp + "&x=" + _x_temp + "&y=" + _y_temp; + var _ledi_temp = document.getElementById("TakeImage_LEDIntensity_value1").value; + + var _bri_temp = document.getElementById("TakeImage_CamBrightness_value1").value; + var _con_temp = document.getElementById("TakeImage_CamContrast_value1").value; + var _sat_temp = document.getElementById("TakeImage_CamSaturation_value1").value; + var _shp_temp = document.getElementById("TakeImage_CamSharpness_value1").value; + + var _ael_temp = document.getElementById("TakeImage_CamAeLevel_value1").value; + var _effect_temp = document.getElementById("TakeImage_CamSpecialEffect_value1").selectedIndex; + + var url = domainname + "/editflow?task=cam_settings"; + url = url + "&bri=" + _bri_temp + "&con=" + _con_temp + "&sat=" + _sat_temp + "&shp=" + _shp_temp; + url = url + "&ashp=" + _ashp_temp + "&ledi=" + _ledi_temp + "&spe=" + _effect_temp + "&zoom=" + _zoom_temp; + + if (_zoom_temp != '0') { + url = url + "&zooms=" + _zooms_temp + "&zoomx=" + _zoomx_temp + "&zoomy=" + _zoomy_temp; } - - url = url + "&ae=" + _ae_temp + "&a2=" + _aec2; + else { + url = url + "&zooms=0" + "&zoomx=0" + "&zoomy=0"; + } + + url = url + "&aec=" + _aec_temp + "&ael=" + _ael_temp + "&aec2=" + _aec2_temp; + url = url + "&mirror=" + _mirror_temp + "&flip=" + _flip_temp; if (domainname.length > 0){ url = url + "&host=" + domainname; } - xhttp.open("GET", url, true); - xhttp.send(); + var durchlaufe = 0; + + function sleep(ms) { + return new Promise(resolve => setTimeout(resolve, ms)); + } + + async function task() { + while (true) { + var xhttp = new XMLHttpRequest(); + + if (durchlaufe > 15) { + document.getElementById("overlay").style.display = "none"; + firework.launch('Save Cam Settings aborted, timeout!', 'warning', 5000); + return; + } + + try { + xhttp.open("GET", url, false); + xhttp.send(); + } catch (error){} + + if (xhttp.responseText == "CamSettingsSet") { + document.getElementById("overlay").style.display = "none"; + return; + } + else { + // Get status + var _xhttp = new XMLHttpRequest(); + durchlaufe = durchlaufe + 1; + + try { + _xhttp.open("GET", domainname + "/statusflow", false); + _xhttp.send(); + } + catch (error){} + + document.getElementById("overlaytext").innerHTML = "Device is busy, plase waiting...

Current step: " + _xhttp.responseText; + console.log("Device is busy, waiting 5s then checking again..."); + await sleep(2000); + } + } + } + + setTimeout(function() { // Delay so the overlay gets shown + task(); + }, 1); } - function showReference(){ - var domainname = getDomainname(); + url = getDomainname() + "/fileserver/config/reference.jpg" + "?session=" + Math.floor((Math.random() * 1000000) + 1); + loadCanvas(url, false); + isActReference = true; - url = domainname + "/fileserver/config/reference.jpg" + "?session=" + Math.floor((Math.random() * 1000000) + 1); + var _rotate_temp = param["Alignment"]["InitialRotate"].value1; if (_rotate_temp < 0) { - document.getElementById("prerotateangle").value = Math.ceil(_rotate_temp); + document.getElementById("PreRotateAngle_value1").value = Math.ceil(_rotate_temp); } else { - document.getElementById("prerotateangle").value = Math.floor(_rotate_temp); + document.getElementById("PreRotateAngle_value1").value = Math.floor(_rotate_temp); } - document.getElementById("finerotate").value = (Number(_rotate_temp) - Number(document.getElementById("prerotateangle").value)).toFixed(1); + document.getElementById("FineRotate_value1").value = (Number(_rotate_temp) - Number(document.getElementById("PreRotateAngle_value1").value)).toFixed(1); - if (_mirror_temp == "true") { - document.getElementById("mirror").checked = true; - } - else { - document.getElementById("mirror").checked = false; - } + WriteParameter(param, category, "TakeImage", "CamBrightness", false, true); + WriteParameter(param, category, "TakeImage", "CamContrast", false, true); + WriteParameter(param, category, "TakeImage", "CamSaturation", false, true); + WriteParameter(param, category, "TakeImage", "CamSharpness", false, true); + WriteParameter(param, category, "TakeImage", "CamAutoSharpness", false); - if (_isize_temp == "true") { - document.getElementById("flip").checked = true; - } - else { - document.getElementById("flip").checked = false; - } + WriteParameter(param, category, "TakeImage", "CamZoom", false); + WriteParameter(param, category, "TakeImage", "CamZoomOffsetX", false); + WriteParameter(param, category, "TakeImage", "CamZoomOffsetY", false); + WriteParameter(param, category, "TakeImage", "CamZoomSize", false); - if (_grayscale_temp == "true") { - document.getElementById("grayscale").checked = true; - } - else { - document.getElementById("grayscale").checked = false; - } + WriteParameter(param, category, "TakeImage", "CamAec", false); + WriteParameter(param, category, "TakeImage", "CamAec2", false); + WriteParameter(param, category, "TakeImage", "CamAeLevel", false, true); + + WriteParameter(param, category, "TakeImage", "CamHmirror", false); + WriteParameter(param, category, "TakeImage", "CamVflip", false); + + WriteParameter(param, category, "TakeImage", "CamSpecialEffect", false); + + WriteParameter(param, category, "TakeImage", "LEDIntensity", false); - if (_negative_temp == "true") { - document.getElementById("negative").checked = true; - } - else { - document.getElementById("negative").checked = false; - } + EnDisableItem(false, param, category, "TakeImage", "CamBrightness", false); + EnDisableItem(false, param, category, "TakeImage", "CamSaturation", false); + EnDisableItem(false, param, category, "TakeImage", "CamContrast", false); + EnDisableItem(false, param, category, "TakeImage", "CamSharpness", false); + EnDisableItem(false, param, category, "TakeImage", "CamAutoSharpness", false); - if (_aec2_temp == "true") { - document.getElementById("aec2").checked = true; - } - else { - document.getElementById("aec2").checked = false; - } - - if (_FixedExposure_temp == "true") { - document.getElementById("FixedExposure").checked = true; - } - else { - document.getElementById("FixedExposure").checked = false; - } + EnDisableItem(false, param, category, "TakeImage", "CamZoom", false); + EnDisableItem(false, param, category, "TakeImage", "CamZoomOffsetX", false); + EnDisableItem(false, param, category, "TakeImage", "CamZoomOffsetY", false); + EnDisableItem(false, param, category, "TakeImage", "CamZoomSize", false); - if (_zoom_temp == "true") { - document.getElementById("zoom").checked = true; - } - else { - document.getElementById("zoom").checked = false; - } + EnDisableItem(false, param, category, "TakeImage", "CamAec", false); + EnDisableItem(false, param, category, "TakeImage", "CamAec2", false); + EnDisableItem(false, param, category, "TakeImage", "CamAeLevel", false); + + EnDisableItem(false, param, category, "TakeImage", "CamHmirror", false); + EnDisableItem(false, param, category, "TakeImage", "CamVflip", false); + + EnDisableItem(false, param, category, "TakeImage", "CamSpecialEffect", false); + + EnDisableItem(false, param, category, "TakeImage", "LEDIntensity", false); - document.getElementById("zoommode").value = _zm_temp; - document.getElementById("zoomoffsetx").value = _x_temp; - document.getElementById("zoomoffsety").value = _y_temp; + document.getElementById("ExpertModus_enabled").disabled = true; - document.getElementById("TakeImage_LEDIntensity_value1").value = _intensity_temp; + document.getElementById("FineRotate_value1").disabled = true; + document.getElementById("FineRotate_text").style.color = "rgb(122, 122, 122)"; + document.getElementById("PreRotateAngle_value1").disabled = true; + document.getElementById("PreRotateAngle_text").style.color = "rgb(122, 122, 122)"; - document.getElementById("TakeImage_Brightness_value1").value = _brightness_temp; - document.getElementById("TakeImage_Brightness_value1_output").value = _brightness_temp; - - document.getElementById("TakeImage_Contrast_value1").value = _contrast_temp; - document.getElementById("TakeImage_Contrast_value1_output").value = _contrast_temp; - - document.getElementById("TakeImage_Saturation_value1").value = _saturation_temp; - document.getElementById("TakeImage_Saturation_value1_output").value = _saturation_temp; - - document.getElementById("TakeImage_Sharpness_value1").value = _sharpness_temp; - document.getElementById("TakeImage_Sharpness_value1_output").value = _sharpness_temp; - - document.getElementById("TakeImage_AutoExposureLevel_value1").value = _ae_temp; - document.getElementById("TakeImage_AutoExposureLevel_value1_output").value = _ae_temp; - - document.getElementById("grayscale").disabled = true; - document.getElementById("negative").disabled = true; - document.getElementById("aec2").disabled = true; - document.getElementById("FixedExposure").disabled = true; - document.getElementById("zoom").disabled = true; - document.getElementById("zoommode").disabled = true; - document.getElementById("zoomoffsetx").disabled = true; - document.getElementById("zoomoffsety").disabled = true; - document.getElementById("TakeImage_AutoExposureLevel_value1").disabled = true; - document.getElementById("finerotate").disabled = true; - document.getElementById("prerotateangle").disabled = true; document.getElementById("savereferenceimage").disabled = true; document.getElementById("updatereferenceimage").disabled = true; document.getElementById("showcurrentreference").disabled = true; - document.getElementById("startreference").disabled = false; - document.getElementById("TakeImage_Brightness_value1").disabled = true; - document.getElementById("TakeImage_Saturation_value1").disabled = true; - document.getElementById("TakeImage_Contrast_value1").disabled = true; - document.getElementById("TakeImage_Sharpness_value1").disabled = true; - document.getElementById("TakeImage_LEDIntensity_value1").disabled = true; - document.getElementById("mirror").disabled = true; - document.getElementById("flip").disabled = true; - - isActReference = true; - loadCanvas(url, false); + document.getElementById("startreference").disabled = false; } - - function dataURLtoBlob(dataurl) { - var arr = dataurl.split(','); - var mime = arr[0].match(/:(.*?);/)[1]; - var bstr = atob(arr[1]); - var n = bstr.length; - var u8arr = new Uint8Array(n); - - while(n--){ - u8arr[n] = bstr.charCodeAt(n); - } - - return new Blob([u8arr], {type:mime}); - } - + function SaveReference(){ var domainname = getDomainname(); - param["Alignment"]["InitialRotate"].value1 = (Number(document.getElementById("prerotateangle").value) + - Number(document.getElementById("finerotate").value)).toFixed(1); + param["Alignment"]["InitialRotate"].value1 = (Number(document.getElementById("PreRotateAngle_value1").value) + + Number(document.getElementById("FineRotate_value1").value)).toFixed(1); - if (document.getElementById("mirror").checked) { - param["Alignment"]["InitialMirror"].value1 = "true"; - } - else { - param["Alignment"]["InitialMirror"].value1 = "false"; - } + ReadParameter(param, "TakeImage", "CamBrightness", false); + ReadParameter(param, "TakeImage", "CamContrast", false); + ReadParameter(param, "TakeImage", "CamSaturation", false); + ReadParameter(param, "TakeImage", "CamSharpness", false); + ReadParameter(param, "TakeImage", "CamAutoSharpness", false); - if (document.getElementById("flip").checked) { - param["Alignment"]["FlipImageSize"].value1 = "true"; - } - else { - param["Alignment"]["FlipImageSize"].value1 = "false"; - } + ReadParameter(param, "TakeImage", "CamZoom", false); + ReadParameter(param, "TakeImage", "CamZoomOffsetX", false); + ReadParameter(param, "TakeImage", "CamZoomOffsetY", false); + ReadParameter(param, "TakeImage", "CamZoomSize", false); + + ReadParameter(param, "TakeImage", "CamAec", false); + ReadParameter(param, "TakeImage", "CamAec2", false); + ReadParameter(param, "TakeImage", "CamAeLevel", false); + + ReadParameter(param, "TakeImage", "CamHmirror", false); + ReadParameter(param, "TakeImage", "CamVflip", false); + + ReadParameter(param, "TakeImage", "CamSpecialEffect", false); + + ReadParameter(param, "TakeImage", "LEDIntensity", false); var canvas = document.getElementById("canvas"); drawRotated(false); WriteConfigININew(); SaveConfigToServer(domainname); - //document.getElementById("savereferenceimage").disabled = true; - //document.getElementById("updatereferenceimage").disabled = true; SaveCanvasToImage(canvas, "/config/reference.jpg", true, domainname); - - LoadParamTemp(); + camSettingsSet(); showReference(); firework.launch('Reference image configuration saved', 'success', 5000); } - function loadCanvas(dataURL, grid) { + function init() { + openDescription(); + domainname = getDomainname(); + + if (!loadConfig(domainname)) { + firework.launch('Configuration could not be loaded! Please reload the page!', 'danger', 30000); + return; + } + + param = getCamConfig(); + category = getConfigCategory(); + + canvas.addEventListener('mousemove', mouseMove, false); + + UpdateExpertModus(); + UpdateTooltipModus(); + showReference(); + } + + function loadCanvas(dataURL, grid = false) { var canvas = document.getElementById('canvas'); var context = canvas.getContext('2d'); @@ -781,151 +927,27 @@ FileSendContent(rtn, _filename, _domainname); } - function getCoords(elem) { - // crossbrowser version - var box = elem.getBoundingClientRect(); - var body = document.body; - var docEl = document.documentElement; - var scrollTop = window.pageYOffset || docEl.scrollTop || body.scrollTop; - var scrollLeft = window.pageXOffset || docEl.scrollLeft || body.scrollLeft; - var clientTop = docEl.clientTop || body.clientTop || 0; - var clientLeft = docEl.clientLeft || body.clientLeft || 0; - var top = box.top + scrollTop - clientTop; - var left = box.left + scrollLeft - clientLeft; - - return { top: Math.round(top), left: Math.round(left) }; - } - - function openDescription() { - if(window.location.hash) { - var hash = window.location.hash.substring(1); + function dataURLtoBlob(dataurl) { + var arr = dataurl.split(','); + var mime = arr[0].match(/:(.*?);/)[1]; + var bstr = atob(arr[1]); + var n = bstr.length; + var u8arr = new Uint8Array(n); - if(hash == 'description') { - document.getElementById("desc_details").open = true; - } - } - } - - function init() { - openDescription(); - canvas.addEventListener('mousemove', mouseMove, false); - - loadConfig(getDomainname()); - ParseConfig(); - param = getConfigParameters(); - - param["TakeImage"]["AutoExposureLevel"]["enabled"] = true; - param["TakeImage"]["LEDIntensity"]["enabled"] = true; - param["TakeImage"]["Brightness"]["enabled"] = true; - param["TakeImage"]["Contrast"]["enabled"] = true; - param["TakeImage"]["Saturation"]["enabled"] = true; - param["TakeImage"]["Sharpness"]["enabled"] = true; - - param["TakeImage"]["Grayscale"]["enabled"] = true; - param["TakeImage"]["Negative"]["enabled"] = true; - param["TakeImage"]["Aec2"]["enabled"] = true; - param["TakeImage"]["FixedExposure"]["enabled"] = true; - param["TakeImage"]["Zoom"]["enabled"] = true; - param["TakeImage"]["ZoomMode"]["enabled"] = true; - param["TakeImage"]["ZoomOffsetX"]["enabled"] = true; - param["TakeImage"]["ZoomOffsetY"]["enabled"] = true; - - if (!param["TakeImage"]["Grayscale"]["found"]) { - param["TakeImage"]["Grayscale"]["found"] = true; - param["TakeImage"]["Grayscale"].value1 = 'false'; - } - if (!param["TakeImage"]["Negative"]["found"]) { - param["TakeImage"]["Negative"]["found"] = true; - param["TakeImage"]["Negative"].value1 = 'false'; - } - if (!param["TakeImage"]["Aec2"]["found"]) { - param["TakeImage"]["Aec2"]["found"] = true; - param["TakeImage"]["Aec2"].value1 = 'false'; - } - if (!param["TakeImage"]["FixedExposure"]["found"]) { - param["TakeImage"]["FixedExposure"]["found"] = true; - param["TakeImage"]["FixedExposure"].value1 = 'false'; - } - if (!param["TakeImage"]["Zoom"]["found"]) { - param["TakeImage"]["Zoom"]["found"] = true; - param["TakeImage"]["Zoom"].value1 = 'false'; - } - if (!param["TakeImage"]["ZoomMode"]["found"]) { - param["TakeImage"]["ZoomMode"]["found"] = true; - param["TakeImage"]["ZoomMode"].value1 = '0'; - } - if (!param["TakeImage"]["ZoomOffsetX"]["found"]) { - param["TakeImage"]["ZoomOffsetX"]["found"] = true; - param["TakeImage"]["ZoomOffsetX"].value1 = '0'; - } - if (!param["TakeImage"]["ZoomOffsetY"]["found"]) { - param["TakeImage"]["ZoomOffsetY"]["found"] = true; - param["TakeImage"]["ZoomOffsetY"].value1 = '0'; - } - if (!param["TakeImage"]["AutoExposureLevel"]["found"]) { - param["TakeImage"]["AutoExposureLevel"]["found"] = true; - param["TakeImage"]["AutoExposureLevel"]["value1"] = '0'; - } - if (!param["TakeImage"]["LEDIntensity"]["found"]) { - param["TakeImage"]["LEDIntensity"]["found"] = true; - param["TakeImage"]["LEDIntensity"]["value1"] = '50'; - } - if (!param["TakeImage"]["Brightness"]["found"]) { - param["TakeImage"]["Brightness"]["found"] = true; - param["TakeImage"]["Brightness"]["value1"] = '0'; - } - if (!param["TakeImage"]["Contrast"]["found"]) { - param["TakeImage"]["Contrast"]["found"] = true; - param["TakeImage"]["Contrast"]["value1"] = '0'; - } - if (!param["TakeImage"]["Saturation"]["found"]) { - param["TakeImage"]["Saturation"]["found"] = true; - param["TakeImage"]["Saturation"]["value1"] = '0'; - } - if (!param["TakeImage"]["Sharpness"]["found"]) { - param["TakeImage"]["Sharpness"]["found"] = true; - param["TakeImage"]["Sharpness"]["value1"] = '0'; + while(n--){ + u8arr[n] = bstr.charCodeAt(n); } - UpdateExpertModus(); - LoadParamTemp(); - showReference(); + return new Blob([u8arr], {type:mime}); } - - function LoadParamTemp() { - _rotate_temp = param["Alignment"]["InitialRotate"].value1; - _mirror_temp = param["Alignment"]["InitialMirror"].value1; - _isize_temp = param["Alignment"]["FlipImageSize"].value1; - - _grayscale_temp = param["TakeImage"]["Grayscale"].value1; - _negative_temp = param["TakeImage"]["Negative"].value1; - _aec2_temp = param["TakeImage"]["Aec2"].value1; - _FixedExposure_temp = param["TakeImage"]["FixedExposure"].value1; - _zoom_temp = param["TakeImage"]["Zoom"].value1; - _zm_temp = param["TakeImage"]["ZoomMode"].value1; - _x_temp = param["TakeImage"]["ZoomOffsetX"].value1; - _y_temp = param["TakeImage"]["ZoomOffsetY"].value1; - _intensity_temp = param["TakeImage"]["LEDIntensity"]["value1"]; - _brightness_temp = param["TakeImage"]["Brightness"]["value1"]; - _contrast_temp = param["TakeImage"]["Contrast"]["value1"]; - _saturation_temp = param["TakeImage"]["Saturation"]["value1"]; - _sharpness_temp = param["TakeImage"]["Sharpness"]["value1"]; - _ae_temp = param["TakeImage"]["AutoExposureLevel"]["value1"]; - } - - function drawRotated(_grid = true) { var canvas = document.getElementById('canvas'); var context = canvas.getContext('2d'); - var _finerot = parseFloat(document.getElementById("finerotate").value); - var _prerot = parseFloat(document.getElementById("prerotateangle").value); + var _finerot = parseFloat(document.getElementById("FineRotate_value1").value); + var _prerot = parseFloat(document.getElementById("PreRotateAngle_value1").value); - var _mirror = document.getElementById("mirror").checked ? '1' : '0'; - var _flip = document.getElementById("flip").checked ? '1' : '0'; - var _negative = document.getElementById("negative").checked ? '1' : '0'; - if (_finerot == 1) { _prerot+=1 _finerot = 0 @@ -937,17 +959,11 @@ } degrees = _finerot + _prerot; - document.getElementById("finerotate").value = _finerot; - document.getElementById("prerotateangle").value = _prerot; + document.getElementById("FineRotate_value1").value = _finerot; + document.getElementById("PreRotateAngle_value1").value = _prerot; - if (_flip == '1') { - canvas.width = imageObj.height; - canvas.height = imageObj.width; - } - else { - canvas.width = imageObj.width; - canvas.height = imageObj.height; - } + canvas.width = imageObj.width; + canvas.height = imageObj.height; context.clearRect(0,0,canvas.width,canvas.height); context.save(); @@ -956,17 +972,9 @@ context.drawImage(imageObj,0,0); } else { - if (_negative == '1') { - context.filter = 'invert(1)'; - } - context.translate(canvas.width/2,canvas.height/2); context.rotate(degrees*Math.PI/180); - if (_mirror == '1') { - context.scale(-1, 1); - } - context.drawImage(imageObj,-imageObj.width/2,-imageObj.height/2); } @@ -1048,6 +1056,363 @@ expert[i].style.display = _style_pur; } } + + function UpdateTooltipModus() { + var _style_pur = 'none'; + var _hidden = true; + + if (param["System"]["Tooltip"].value1 == 'true') { + _style_pur = ''; + _hidden = false; + } + + const tooltip = document.querySelectorAll(".tooltip"); + + for (var i = 0; i < tooltip.length; i++) { + tooltip[i].style.display = _style_pur; + } + } + + function getCoords(elem) { + // crossbrowser version + var box = elem.getBoundingClientRect(); + var body = document.body; + var docEl = document.documentElement; + var scrollTop = window.pageYOffset || docEl.scrollTop || body.scrollTop; + var scrollLeft = window.pageXOffset || docEl.scrollLeft || body.scrollLeft; + var clientTop = docEl.clientTop || body.clientTop || 0; + var clientLeft = docEl.clientLeft || body.clientLeft || 0; + var top = box.top + scrollTop - clientTop; + var left = box.left + scrollLeft - clientLeft; + + return { top: Math.round(top), left: Math.round(left) }; + } + + function InvertEnableItem(_cat, _param) { + _zw = _cat + "_" + _param + "_enabled"; + _isOn = document.getElementById(_zw).checked; + + _color = "rgb(122, 122, 122)"; + + if (_isOn) { + _color = "black"; + } + + _zw = _cat + "_" + _param + "_text"; + document.getElementById(_zw).disabled = !_isOn; + document.getElementById(_zw).style.color = _color; + + setEnabled(_cat + "_" + _param, _isOn); + + for (var j = 1; j <= param[_cat][_param]["anzParam"]; ++j) { + document.getElementById(_cat+"_"+_param+"_value"+j).disabled = !_isOn; + document.getElementById(_cat+"_"+_param+"_value"+j).style.color = _color; + } + } + + function setEnabled(className, enabled) { + _color = "rgb(122, 122, 122)"; + + if (enabled) { + _color = "black"; + } + + let elements = document.getElementsByClassName(className); + + for (i = 0; i < elements.length; i++) { + if (enabled) { + elements[i].classList.remove("disabled"); + } + else { + elements[i].classList.add("disabled"); + } + + let inputs = elements[i].getElementsByTagName("input"); + + for (j = 0; j < inputs.length; j++) { + if (inputs[j].id.endsWith("_enabled")) { + continue; + } + + inputs[j].style.color = _color; + + if (enabled) { + inputs[j].removeAttribute("disabled"); + } + else { + inputs[j].setAttribute("disabled", "disabled"); + } + } + } + } + + function setVisible(className, visible) { + let elements = document.getElementsByClassName(className); + + for (i = 0; i < elements.length; i++) { + if (visible) { + elements[i].classList.remove("hidden"); + } + else { + elements[i].classList.add("hidden"); + } + } + } + + function EnDisableItem(_status, _param, _category, _cat, _name, _optional, _number = -1) { + //_status = _category[_cat]["enabled"]; + + _color = "rgb(122, 122, 122)"; + + if (_status) { + _color = "black"; + } + + if (_optional) { + document.getElementById(_cat+"_"+_name+"_enabled").disabled = !_status; + document.getElementById(_cat+"_"+_name+"_enabled").style.color = _color; + } + + if (_number == -1) { + if (!_param[_cat][_name]["enabled"]) { + _status = false; + _color = "rgb(122, 122, 122)"; + } + } + else { + if (!NUMBERS[_number][_cat][_name]["enabled"]) { + _status = false; + _color = "rgb(122, 122, 122)"; + } + } + + document.getElementById(_cat+"_"+_name+"_text").disabled = !_status; + document.getElementById(_cat+"_"+_name+"_text").style.color = _color; + + setEnabled(_cat+"_"+_name, _status); + + for (var j = 1; j <= _param[_cat][_name]["anzParam"]; ++j) { + document.getElementById(_cat+"_"+_name+"_value"+j).disabled = !_status; + document.getElementById(_cat+"_"+_name+"_value"+j).style.color = _color; + } + } + + function ReadParameter(_param, _cat, _name, _optional, _number = -1) { + if (_number > -1) { + if (_cat == "Digits") { + _cat = "digit"; + } + + if (_cat == "Analog") { + _cat = "analog"; + } + + if ((NUMBERS[_number] == undefined) || (NUMBERS[_number][_cat] == undefined) || (NUMBERS[_number][_cat][_name] == undefined)) { + return; + } + + if (_optional) { + NUMBERS[_number][_cat][_name]["enabled"] = document.getElementById(_cat+"_"+_name+"_enabled").checked; + } + + for (var j = 1; j <= _param[_cat][_name]["anzParam"]; ++j) { + let element = document.getElementById(_cat+"_"+_name+"_value"+j); + + if (element.tagName.toLowerCase() == "select") { + NUMBERS[_number][_cat][_name]["value"+j] = element.selectedIndex > -1 ? element.options[element.selectedIndex].value : ""; + } + else if ((element.getAttribute("type") != null) && (element.getAttribute("type").toLowerCase() == "checkbox")) { + NUMBERS[_number][_cat][_name]["value"+j] = element.checked; + } + else { + if ((NUMBERS[_number][_cat][_name].checkRegExList != null) && (NUMBERS[_number][_cat][_name].checkRegExList[j-1] != null)) { + if (!element.value.match(NUMBERS[_cat][_name].checkRegExList[j-1])) { + element.classList.add("invalid-input"); + } + else { + element.classList.remove("invalid-input"); + } + } + NUMBERS[_number][_cat][_name]["value"+j] = element.value; + } + } + } + else { + if (_optional) { + _param[_cat][_name]["enabled"] = document.getElementById(_cat+"_"+_name+"_enabled").checked; + } + + for (var j = 1; j <= _param[_cat][_name]["anzParam"]; ++j) { + let element = document.getElementById(_cat+"_"+_name+"_value"+j); + + if (element.tagName.toLowerCase() == "select") { + _param[_cat][_name]["value"+j] = element.selectedIndex > -1 ? element.options[element.selectedIndex].value : ""; + } + else if ((element.getAttribute("type") != null) && (element.getAttribute("type").toLowerCase() == "checkbox")) { + _param[_cat][_name]["value"+j] = element.checked; + } + else { + if ((_param[_cat][_name].checkRegExList != null) && (_param[_cat][_name].checkRegExList[j-1] != null)) { + if (!element.value.match(_param[_cat][_name].checkRegExList[j-1])) { + element.classList.add("invalid-input"); + } + else { + element.classList.remove("invalid-input"); + } + } + _param[_cat][_name]["value"+j] = element.value; + } + } + } + } + + function WriteParameter(_param, _category, _cat, _name, _optional, _outval = false, _number = -1) { + let anzpara; + try { + anzpara = _param[_cat][_name].anzParam; + } + catch (error) { + firework.launch("Parameter '" + _name + "' in der Kategorie '" + _cat + "' ist unbekannt!", 'danger', 30000); + return; + } + + if (_number > -1) { + if ((NUMBERS[_number] == undefined) || (NUMBERS[_number][_cat] == undefined) || (NUMBERS[_number][_cat][_name] == undefined)) { + return; + } + + if (_optional) { + document.getElementById(_cat+"_"+_name+"_enabled").checked = NUMBERS[_number][_cat][_name]["enabled"]; + + for (var j = 1; j <= anzpara; ++j) { + document.getElementById(_cat+"_"+_name+"_value"+j).disabled = !NUMBERS[_number][_cat][_name]["enabled"]; + } + } + + document.getElementById(_cat+"_"+_name+"_text").style.color = "black" + setEnabled(_cat+"_"+_name, true); + + for (var j = 1; j <= anzpara; ++j) { + let element = document.getElementById(_cat+"_"+_name+"_value"+j); + + if (element.tagName.toLowerCase() == "select") { + var textToFind = NUMBERS[_number][_cat][_name]["value"+j]; + + if (textToFind == undefined) { + continue; + } + + _isFound = false; + element.selectedIndex = -1; + + for (var i = 0; i < element.options.length; i++) { + if (element.options[i].value.toLowerCase() === textToFind.toLowerCase()) { + element.selectedIndex = i; + _isFound = true; + break; + } + } + + if (!_isFound) { + _zw_txt = "Der Wert '" + textToFind + "' des Parameters '" + _name; + _zw_txt = _zw_txt + "' im Bereich '" + _cat + "' ist ungültig. BITTE VOR DEM SPEICHERN PRÜFEN!"; + firework.launch(_zw_txt, 'warning', 10000); + } + } + else if ((element.getAttribute("type") != null) && (element.getAttribute("type").toLowerCase() == "checkbox")) { + element.checked = NUMBERS[_number][_cat][_name]["value"+j] == "true"; + } + else { + element.value = NUMBERS[_number][_cat][_name]["value"+j]; + } + } + + if (_outval) { + for (var j = 1; j <= anzpara; ++j) { + document.getElementById(_cat+"_"+_name+"_value"+j+"_output").value = document.getElementById(_cat+"_"+_name+"_value"+j).value; + } + } + } + else { + if (_optional) { + document.getElementById(_cat+"_"+_name+"_enabled").checked = _param[_cat][_name]["enabled"]; + + for (var j = 1; j <= anzpara; ++j) { + document.getElementById(_cat+"_"+_name+"_value"+j).disabled = !_param[_cat][_name]["enabled"]; + } + } + + document.getElementById(_cat+"_"+_name+"_text").style.color = "black" + setEnabled(_cat+"_"+_name, true); + + for (var j = 1; j <= anzpara; ++j) { + let element = document.getElementById(_cat+"_"+_name+"_value"+j); + + if (element.tagName.toLowerCase() == "select") { + var textToFind = _param[_cat][_name]["value"+j]; + + if (textToFind == undefined) { + continue; + } + + _isFound = false; + element.selectedIndex = -1; + + for (var i = 0; i < element.options.length; i++) { + if (element.options[i].value.toLowerCase() === textToFind.toLowerCase()) { + element.selectedIndex = i; + _isFound = true; + break; + } + } + + if (!_isFound) { + _zw_txt = "Der Wert '" + textToFind + "' des Parameters '" + _name; + _zw_txt = _zw_txt + "' im Bereich '" + _cat + "' ist ungültig. BITTE VOR DEM SPEICHERN PRÜFEN!"; + firework.launch(_zw_txt, 'warning', 10000); + } + + } + else if ((element.getAttribute("type") != null) && (element.getAttribute("type").toLowerCase() == "checkbox")) { + element.checked = _param[_cat][_name]["value"+j] == "true"; + } + else { + element.value = _param[_cat][_name]["value"+j]; + } + } + + if (_outval) { + document.getElementById(_cat+"_"+_name+"_value1_output").value = document.getElementById(_cat+"_"+_name+"_value1").value; + } + } + + ///////////////// am Ende, falls Kategorie als gesamtes nicht ausgewählt --> deaktivieren + if (_category[_cat]["enabled"] == false) { + if (_optional) { + document.getElementById(_cat+"_"+_name+"_enabled").disabled = true; + + for (var j = 1; j <= anzpara; ++j) { + document.getElementById(_cat+"_"+_name+"_value"+j).disabled = true; + } + } + + document.getElementById(_cat+"_"+_name+"_text").style="color: gray;" + setEnabled(_cat+"_"+_name, false); + } + + EnDisableItem(_category[_cat]["enabled"], _param, _category, _cat, _name, _optional, _number); + } + + /* hash #description open the details part of the page */ + function openDescription() { + if(window.location.hash) { + var hash = window.location.hash.substring(1); + + if(hash == 'description') { + document.getElementById("desc_details").open = true; + } + } + } init(); diff --git a/sd-card/html/index.html b/sd-card/html/index.html index 05fe9daf..12a580cb 100644 --- a/sd-card/html/index.html +++ b/sd-card/html/index.html @@ -21,21 +21,21 @@ var streamPopup; var streamFlashlight = false; var streamWindowFeatures = - 'channelmode=no,directories=no,fullscreen=no,' + - 'location=no,dependent=yes,menubar=no,resizable=no,scrollbars=no,' + - 'status=no,toolbar=no,titlebar=no,' + - 'left=10,top=260,width=640px,height=480px'; + 'channelmode=no,directories=no,fullscreen=no,' + + 'location=no,dependent=yes,menubar=no,resizable=no,scrollbars=no,' + + 'status=no,toolbar=no,titlebar=no,' + + 'left=10,top=260,width=640px,height=480px'; - function loadPage(page) { + function loadPage(page) { console.log("loadPage( " + page + " )"); - if (streamPopup) // Ensure that stream popup is closed because it's blocking web interface + if (streamPopup) { // Ensure that stream popup is closed because it's blocking web interface streamPopup.close(); + } asyncPageLoad(page); } - async function asyncPageLoad(page ) { console.log(" loading " + page + " ..."); document.cookie = "page="+page + "; path=/"; @@ -46,7 +46,6 @@ }); } - function resetMenu() { [].forEach.call(document.querySelectorAll('.submenu'), function (el) { el.style.visibility = 'visible'; @@ -54,18 +53,20 @@ } function getCookie(cname) { - let name = cname + "="; - let decodedCookie = decodeURIComponent(document.cookie); - let ca = decodedCookie.split(';'); - for(let i = 0; i @@ -153,7 +154,7 @@ HA_send_discovery_visibility(); if (getCookie("page") == "" || getCookie("page") == "reboot_page.html?v=$COMMIT_HASH") { - document.cookie = "page=overview.html?v=$COMMIT_HASH" + "; path=/"; + document.cookie = "page=overview.html?v=$COMMIT_HASH" + "; path=/"; } console.log("Loading page: " + getCookie("page")); document.getElementById('maincontent').src = getCookie("page"); @@ -181,19 +182,18 @@ } */ - function HA_send_discovery_visibility() { loadConfig(domainname); ParseConfig(); category = getConfigCategory(); param = getConfigParameters(); - if (category["MQTT"]["enabled"] && param["MQTT"]["HomeassistantDiscovery"]["value1"] == "true") { + + if (category["MQTT"]["enabled"] && param["MQTT"]["HomeassistantDiscovery"].value == "true") { document.getElementById("ManualControl").style.display=""; document.getElementById("HASendDiscovery").style.display=""; } } - function HA_send_discovery() { console.log("HA Discovery scheduled"); var url = getDomainname() + '/mqtt_publish_discovery'; @@ -207,15 +207,17 @@ xhttp.send(); } - function start_livestream(streamFlashlight) { - if (streamPopup) + if (streamPopup) { streamPopup.close(); + } - if (streamFlashlight) + if (streamFlashlight) { streamPopup = window.open(getDomainname() + '/stream?flashlight=true','LivestreamWithlight',streamWindowFeatures); - else + } + else { streamPopup = window.open(getDomainname() + '/stream','Livestream',streamWindowFeatures); + } streamPopup.focus(); } diff --git a/sd-card/html/overview.html b/sd-card/html/overview.html index 6d22f62c..ed5ab4c2 100644 --- a/sd-card/html/overview.html +++ b/sd-card/html/overview.html @@ -5,13 +5,64 @@ @@ -78,221 +129,208 @@ - + + diff --git a/sd-card/html/readconfigcommon.js b/sd-card/html/readconfigcommon.js index 9be51c5c..b113a361 100644 --- a/sd-card/html/readconfigcommon.js +++ b/sd-card/html/readconfigcommon.js @@ -1,11 +1,13 @@ function SaveConfigToServer(_domainname){ // leere Zeilen am Ende löschen var zw = config_split.length - 1; + while (config_split[zw] == "") { config_split.pop(); } var config_gesamt = ""; + for (var i = 0; i < config_split.length; ++i) { config_gesamt = config_gesamt + config_split[i] + "\n"; @@ -26,231 +28,227 @@ function UpdateConfig(zw, _index, _enhance, _domainname){ function createReader(file) { var image = new Image(); + reader.onload = function(evt) { var image = new Image(); + image.onload = function(evt) { var width = this.width; var height = this.height; - //alert (width); // will produce something like 198 }; + image.src = evt.target.result; }; + reader.readAsDataURL(file); } -function ZerlegeZeile(input, delimiter = " =\t\r") - { - var Output = Array(0); +function ZerlegeZeile(input, delimiter = " =\t\r") { + var Output = Array(0); // delimiter = " =,\t"; - /* The input can have multiple formats: - * - key = value - * - key = value1 value2 value3 ... - * - key value1 value2 value3 ... - * - * Examples: - * - ImageSize = VGA - * - IO0 = input disabled 10 false false - * - main.dig1 28 144 55 100 false - * - * This causes issues eg. if a password key has a whitespace or equal sign in its value. - * As a workaround and to not break any legacy usage, we enforce to only use the - * equal sign, if the key is "password" - */ - if (input.includes("password") || input.includes("Token")) { // Line contains a password, use the equal sign as the only delimiter and only split on first occurrence - var pos = input.indexOf("="); - delimiter = " \t\r" - Output.push(trim(input.substr(0, pos), delimiter)); - Output.push(trim(input.substr(pos +1, input.length), delimiter)); - } - else { // Legacy Mode - input = trim(input, delimiter); - var pos = findDelimiterPos(input, delimiter); - var token; - while (pos > -1) { - token = input.substr(0, pos); - token = trim(token, delimiter); - Output.push(token); - input = input.substr(pos+1, input.length); - input = trim(input, delimiter); - pos = findDelimiterPos(input, delimiter); - } - Output.push(input); - } + /* The input can have multiple formats: + * - key = value + * - key = value1 value2 value3 ... + * - key value1 value2 value3 ... + * + * Examples: + * - ImageSize = VGA + * - IO0 = input disabled 10 false false + * - main.dig1 28 144 55 100 false + * + * This causes issues eg. if a password key has a whitespace or equal sign in its value. + * As a workaround and to not break any legacy usage, we enforce to only use the + * equal sign, if the key is "password" + */ + if (input.includes("password") || input.includes("Token")) { // Line contains a password, use the equal sign as the only delimiter and only split on first occurrence + var pos = input.indexOf("="); + delimiter = " \t\r" + Output.push(trim(input.substr(0, pos), delimiter)); + Output.push(trim(input.substr(pos +1, input.length), delimiter)); + } + else { // Legacy Mode + input = trim(input, delimiter); + var pos = findDelimiterPos(input, delimiter); + var token; + + while (pos > -1) { + token = input.substr(0, pos); + token = trim(token, delimiter); + Output.push(token); + input = input.substr(pos+1, input.length); + input = trim(input, delimiter); + pos = findDelimiterPos(input, delimiter); + } + + Output.push(input); + } - return Output; - } + return Output; +} -function findDelimiterPos(input, delimiter) - { - var pos = -1; - var zw; - var akt_del; +function findDelimiterPos(input, delimiter) { + var pos = -1; + var zw; + var akt_del; - for (var anz = 0; anz < delimiter.length; ++anz) - { - akt_del = delimiter[anz]; - zw = input.indexOf(akt_del); - if (zw > -1) - { - if (pos > -1) - { - if (zw < pos) - pos = zw; - } - else - pos = zw; - } - } - return pos; - } + for (var anz = 0; anz < delimiter.length; ++anz) { + akt_del = delimiter[anz]; + zw = input.indexOf(akt_del); + + if (zw > -1) { + if (pos > -1) { + if (zw < pos) { + pos = zw; + } + } + else { + pos = zw; + } + } + } + + return pos; +} -function trim(istring, adddelimiter) - { - while ((istring.length > 0) && (adddelimiter.indexOf(istring[0]) >= 0)){ - istring = istring.substr(1, istring.length-1); - } +function trim(istring, adddelimiter) { + while ((istring.length > 0) && (adddelimiter.indexOf(istring[0]) >= 0)) { + istring = istring.substr(1, istring.length-1); + } - while ((istring.length > 0) && (adddelimiter.indexOf(istring[istring.length-1]) >= 0)){ - istring = istring.substr(0, istring.length-1); - } + while ((istring.length > 0) && (adddelimiter.indexOf(istring[istring.length-1]) >= 0)) { + istring = istring.substr(0, istring.length-1); + } - return istring; - } + return istring; +} -function getConfig() -{ - return config_gesamt; +function getConfig() { + return config_gesamt; } -function loadConfig(_domainname) -{ - var xhttp = new XMLHttpRequest(); - try { - url = _domainname + '/fileserver/config/config.ini'; - xhttp.open("GET", url, false); - xhttp.send(); - config_gesamt = xhttp.responseText; - config_gesamt = config_gesamt.replace("InitalRotate", "InitialRotate"); // Korrigiere Schreibfehler in config.ini !!!!! - } - catch (error) - { -// firework.launch('Deleting Config.ini failed!', 'danger', 30000); - } - return true; +function loadConfig(_domainname) { + var xhttp = new XMLHttpRequest(); + + try { + url = _domainname + '/fileserver/config/config.ini'; + xhttp.open("GET", url, false); + xhttp.send(); + config_gesamt = xhttp.responseText; + config_gesamt = config_gesamt.replace("InitalRotate", "InitialRotate"); // Korrigiere Schreibfehler in config.ini !!!!! + } catch (error) {} + + return true; } -function dataURLtoBlob(dataurl) -{ - var arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1], +function dataURLtoBlob(dataurl) { + var arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1], bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n); - while(n--){ - u8arr[n] = bstr.charCodeAt(n); - } - return new Blob([u8arr], {type:mime}); + + while(n--){ + u8arr[n] = bstr.charCodeAt(n); + } + + return new Blob([u8arr], {type:mime}); } -function FileCopyOnServer(_source, _target, _domainname = ""){ - url = _domainname + "/editflow?task=copy&in=" + _source + "&out=" + _target; - var xhttp = new XMLHttpRequest(); - try { - xhttp.open("GET", url, false); - xhttp.send(); } - catch (error) - { -// firework.launch('Deleting Config.ini failed!', 'danger', 30000); - } +function FileCopyOnServer(_source, _target, _domainname = "") { + url = _domainname + "/editflow?task=copy&in=" + _source + "&out=" + _target; + var xhttp = new XMLHttpRequest(); + + try { + xhttp.open("GET", url, false); + xhttp.send(); + } catch (error) {} } -function FileDeleteOnServer(_filename, _domainname = ""){ - var xhttp = new XMLHttpRequest(); - var okay = false; +function FileDeleteOnServer(_filename, _domainname = "") { + var xhttp = new XMLHttpRequest(); + var okay = false; - xhttp.onreadystatechange = function() { - if (xhttp.readyState == 4) { - if (xhttp.status == 200) { - okay = true; - } else if (xhttp.status == 0) { -// firework.launch('Server closed the connection abruptly!', 'danger', 30000); -// location.reload() - } else { -// firework.launch('An error occured: ' + xhttp.responseText, 'danger', 30000); -// location.reload() - } - } - }; - try { - var url = _domainname + "/delete" + _filename; - xhttp.open("POST", url, false); - xhttp.send(); - } - catch (error) - { -// firework.launch('Deleting Config.ini failed!', 'danger', 30000); - } + xhttp.onreadystatechange = function() { + if (xhttp.readyState == 4) { + if (xhttp.status == 200) { + okay = true; + } + else if (xhttp.status == 0) { + // firework.launch('Server closed the connection abruptly!', 'danger', 30000); + // location.reload() + } + else { + // firework.launch('An error occured: ' + xhttp.responseText, 'danger', 30000); + // location.reload() + } + } + }; + + try { + var url = _domainname + "/delete" + _filename; + xhttp.open("POST", url, false); + xhttp.send(); + } catch (error) {} - return okay; + return okay; } -function FileSendContent(_content, _filename, _domainname = ""){ - var xhttp = new XMLHttpRequest(); - var okay = false; +function FileSendContent(_content, _filename, _domainname = "") { + var xhttp = new XMLHttpRequest(); + var okay = false; - xhttp.onreadystatechange = function() { - if (xhttp.readyState == 4) { - if (xhttp.status == 200) { - okay = true; - } else if (xhttp.status == 0) { + xhttp.onreadystatechange = function() { + if (xhttp.readyState == 4) { + if (xhttp.status == 200) { + okay = true; + } + else if (xhttp.status == 0) { firework.launch('Server closed the connection abruptly!', 'danger', 30000); - } else { + } + else { firework.launch('An error occured: ' + xhttp.responseText, 'danger', 30000); - } - } - }; + } + } + }; - try { - upload_path = _domainname + "/upload" + _filename; - xhttp.open("POST", upload_path, false); - xhttp.send(_content); - } - catch (error) - { -// firework.launch('Deleting Config.ini failed!', 'danger', 30000); - } + try { + upload_path = _domainname + "/upload" + _filename; + xhttp.open("POST", upload_path, false); + xhttp.send(_content); + } catch (error) {} + return okay; } function MakeRefImageZW(zw, _enhance, _domainname){ - var _filename = zw["name"].replace("/config/", "/img_tmp/"); + var _filename = zw["name"].replace("/config/", "/img_tmp/"); - var url = _domainname + "/editflow?task=cutref&in=/config/reference.jpg&out=" + _filename + "&x=" + zw["x"] + "&y=" + zw["y"] + "&dx=" + zw["dx"] + "&dy=" + zw["dy"]; + var url = _domainname + "/editflow?task=cutref&in=/config/reference.jpg&out=" + _filename + "&x=" + zw["x"] + "&y=" + zw["y"] + "&dx=" + zw["dx"] + "&dy=" + zw["dy"]; - if (_enhance == true){ - url = url + "&enhance=true"; - } + if (_enhance == true){ + url = url + "&enhance=true"; + } - var xhttp = new XMLHttpRequest(); + var xhttp = new XMLHttpRequest(); - try { - xhttp.open("GET", url, false); - xhttp.send(); - } catch (error){} + try { + xhttp.open("GET", url, false); + xhttp.send(); + } catch (error){} - if (xhttp.responseText == "CutImage Done") { - firework.launch('Image Contrast got enhanced', 'success', 5000); - return true; - } - else { - return false; - } + if (xhttp.responseText == "CutImage Done") { + firework.launch('Image Contrast got enhanced', 'success', 5000); + return true; + } + else { + return false; + } } diff --git a/sd-card/html/readconfigparam.js b/sd-card/html/readconfigparam.js index 641b94ec..d40a248a 100644 --- a/sd-card/html/readconfigparam.js +++ b/sd-card/html/readconfigparam.js @@ -8,706 +8,893 @@ var REFERENCES = new Array(0); function getNUMBERSList() { - _domainname = getDomainname(); - var namenumberslist = ""; + _domainname = getDomainname(); + var namenumberslist = ""; - var xhttp = new XMLHttpRequest(); - xhttp.addEventListener('load', function(event) { - if (xhttp.status >= 200 && xhttp.status < 300) { - namenumberslist = xhttp.responseText; - } else { - console.warn(request.statusText, request.responseText); - } - }); + var xhttp = new XMLHttpRequest(); + + xhttp.addEventListener('load', function(event) { + if (xhttp.status >= 200 && xhttp.status < 300) { + namenumberslist = xhttp.responseText; + } + else { + console.warn(request.statusText, request.responseText); + } + }); - try { - url = _domainname + '/editflow?task=namenumbers'; - xhttp.open("GET", url, false); - xhttp.send(); - } - catch (error) - { -// alert("Loading Hostname failed"); - } + try { + url = _domainname + '/editflow?task=namenumbers'; + xhttp.open("GET", url, false); + xhttp.send(); + } catch (error) {} - namenumberslist = namenumberslist.split("\t"); -// namenumberslist.pop(); + namenumberslist = namenumberslist.split("\t"); - return namenumberslist; + return namenumberslist; } function getDATAList() { - _domainname = getDomainname(); - datalist = ""; + _domainname = getDomainname(); + datalist = ""; - var xhttp = new XMLHttpRequest(); - xhttp.addEventListener('load', function(event) { - if (xhttp.status >= 200 && xhttp.status < 300) { - datalist = xhttp.responseText; - } else { - console.warn(request.statusText, request.responseText); - } - }); + var xhttp = new XMLHttpRequest(); + + xhttp.addEventListener('load', function(event) { + if (xhttp.status >= 200 && xhttp.status < 300) { + datalist = xhttp.responseText; + } + else { + console.warn(request.statusText, request.responseText); + } + }); - try { - url = _domainname + '/editflow?task=data'; - xhttp.open("GET", url, false); - xhttp.send(); - } - catch (error) - { -// alert("Loading Hostname failed"); - } + try { + url = _domainname + '/editflow?task=data'; + xhttp.open("GET", url, false); + xhttp.send(); + } catch (error) {} - datalist = datalist.split("\t"); - datalist.pop(); - datalist.sort(); + datalist = datalist.split("\t"); + datalist.pop(); + datalist.sort(); - return datalist; + return datalist; } function getTFLITEList() { - _domainname = getDomainname(); - tflitelist = ""; + _domainname = getDomainname(); + tflitelist = ""; - var xhttp = new XMLHttpRequest(); - xhttp.addEventListener('load', function(event) { - if (xhttp.status >= 200 && xhttp.status < 300) { - tflitelist = xhttp.responseText; - } else { - console.warn(request.statusText, request.responseText); - } - }); + var xhttp = new XMLHttpRequest(); + + xhttp.addEventListener('load', function(event) { + if (xhttp.status >= 200 && xhttp.status < 300) { + tflitelist = xhttp.responseText; + } + else { + console.warn(request.statusText, request.responseText); + } + }); - try { - url = _domainname + '/editflow?task=tflite'; - xhttp.open("GET", url, false); - xhttp.send(); - } - catch (error) - { -// alert("Loading Hostname failed"); - } + try { + url = _domainname + '/editflow?task=tflite'; + xhttp.open("GET", url, false); + xhttp.send(); + } catch (error) {} - tflitelist = tflitelist.split("\t"); - tflitelist.sort(); + tflitelist = tflitelist.split("\t"); + tflitelist.sort(); - return tflitelist; + return tflitelist; } function ParseConfig() { - config_split = config_gesamt.split("\n"); - var aktline = 0; + config_split = config_gesamt.split("\n"); + var aktline = 0; - param = new Object(); - category = new Object(); + param = new Object(); + category = new Object(); - var catname = "TakeImage"; - category[catname] = new Object(); - category[catname]["enabled"] = false; - category[catname]["found"] = false; - param[catname] = new Object(); - ParamAddValue(param, catname, "RawImagesLocation"); - ParamAddValue(param, catname, "WaitBeforeTakingPicture"); - ParamAddValue(param, catname, "RawImagesRetention"); - ParamAddValue(param, catname, "Demo"); - ParamAddValue(param, catname, "Brightness"); - ParamAddValue(param, catname, "Contrast"); - ParamAddValue(param, catname, "Saturation"); - ParamAddValue(param, catname, "Sharpness"); - ParamAddValue(param, catname, "LEDIntensity"); - ParamAddValue(param, catname, "ImageQuality"); - ParamAddValue(param, catname, "ImageSize"); - ParamAddValue(param, catname, "Zoom"); - ParamAddValue(param, catname, "ZoomMode"); - ParamAddValue(param, catname, "ZoomOffsetX"); - ParamAddValue(param, catname, "ZoomOffsetY"); - ParamAddValue(param, catname, "Grayscale"); - ParamAddValue(param, catname, "Negative"); - ParamAddValue(param, catname, "Aec2"); - ParamAddValue(param, catname, "AutoExposureLevel"); - ParamAddValue(param, catname, "FixedExposure"); + var catname = "TakeImage"; + category[catname] = new Object(); + category[catname]["enabled"] = false; + category[catname]["found"] = false; + param[catname] = new Object(); + ParamAddValue(param, catname, "RawImagesLocation"); + ParamAddValue(param, catname, "RawImagesRetention"); + ParamAddValue(param, catname, "WaitBeforeTakingPicture"); + ParamAddValue(param, catname, "CamGainceiling"); // Image gain (GAINCEILING_x2, x4, x8, x16, x32, x64 or x128) + ParamAddValue(param, catname, "CamQuality"); // 0 - 63 + ParamAddValue(param, catname, "CamBrightness"); // (-2 to 2) - set brightness + ParamAddValue(param, catname, "CamContrast"); //-2 - 2 + ParamAddValue(param, catname, "CamSaturation"); //-2 - 2 + ParamAddValue(param, catname, "CamSharpness"); //-2 - 2 + ParamAddValue(param, catname, "CamAutoSharpness"); // (1 or 0) + ParamAddValue(param, catname, "CamSpecialEffect"); // 0 - 6 + ParamAddValue(param, catname, "CamWbMode"); // 0 to 4 - if awb_gain enabled (0 - Auto, 1 - Sunny, 2 - Cloudy, 3 - Office, 4 - Home) + ParamAddValue(param, catname, "CamAwb"); // white balance enable (0 or 1) + ParamAddValue(param, catname, "CamAwbGain"); // Auto White Balance enable (0 or 1) + ParamAddValue(param, catname, "CamAec"); // auto exposure off (1 or 0) + ParamAddValue(param, catname, "CamAec2"); // automatic exposure sensor (0 or 1) + ParamAddValue(param, catname, "CamAeLevel"); // auto exposure levels (-2 to 2) + ParamAddValue(param, catname, "CamAecValue"); // set exposure manually (0-1200) + ParamAddValue(param, catname, "CamAgc"); // auto gain off (1 or 0) + ParamAddValue(param, catname, "CamAgcGain"); // set gain manually (0 - 30) + ParamAddValue(param, catname, "CamBpc"); // black pixel correction + ParamAddValue(param, catname, "CamWpc"); // white pixel correction + ParamAddValue(param, catname, "CamRawGma"); // (1 or 0) + ParamAddValue(param, catname, "CamLenc"); // lens correction (1 or 0) + ParamAddValue(param, catname, "CamHmirror"); // (0 or 1) flip horizontally + ParamAddValue(param, catname, "CamVflip"); // Invert image (0 or 1) + ParamAddValue(param, catname, "CamDcw"); // downsize enable (1 or 0) + ParamAddValue(param, catname, "CamZoom"); + ParamAddValue(param, catname, "CamZoomOffsetX"); + ParamAddValue(param, catname, "CamZoomOffsetY"); + ParamAddValue(param, catname, "CamZoomSize"); + ParamAddValue(param, catname, "LEDIntensity"); + ParamAddValue(param, catname, "Demo"); - var catname = "Alignment"; - category[catname] = new Object(); - category[catname]["enabled"] = false; - category[catname]["found"] = false; - param[catname] = new Object(); - ParamAddValue(param, catname, "InitialRotate"); - ParamAddValue(param, catname, "InitialMirror"); - ParamAddValue(param, catname, "SearchFieldX"); - ParamAddValue(param, catname, "SearchFieldY"); - ParamAddValue(param, catname, "AlignmentAlgo"); - ParamAddValue(param, catname, "FlipImageSize"); + var catname = "Alignment"; + category[catname] = new Object(); + category[catname]["enabled"] = false; + category[catname]["found"] = false; + param[catname] = new Object(); + ParamAddValue(param, catname, "InitialRotate"); + ParamAddValue(param, catname, "SearchFieldX"); + ParamAddValue(param, catname, "SearchFieldY"); + ParamAddValue(param, catname, "AlignmentAlgo"); - var catname = "Digits"; - category[catname] = new Object(); - category[catname]["enabled"] = false; - category[catname]["found"] = false; - param[catname] = new Object(); - ParamAddValue(param, catname, "Model"); - ParamAddValue(param, catname, "CNNGoodThreshold", 1); - ParamAddValue(param, catname, "ROIImagesLocation"); - ParamAddValue(param, catname, "ROIImagesRetention"); + var catname = "Digits"; + category[catname] = new Object(); + category[catname]["enabled"] = false; + category[catname]["found"] = false; + param[catname] = new Object(); + ParamAddValue(param, catname, "Model"); + ParamAddValue(param, catname, "CNNGoodThreshold", 1); + ParamAddValue(param, catname, "ROIImagesLocation"); + ParamAddValue(param, catname, "ROIImagesRetention"); - var catname = "Analog"; - category[catname] = new Object(); - category[catname]["enabled"] = false; - category[catname]["found"] = false; - param[catname] = new Object(); - ParamAddValue(param, catname, "Model"); - ParamAddValue(param, catname, "ROIImagesLocation"); - ParamAddValue(param, catname, "ROIImagesRetention"); + var catname = "Analog"; + category[catname] = new Object(); + category[catname]["enabled"] = false; + category[catname]["found"] = false; + param[catname] = new Object(); + ParamAddValue(param, catname, "Model"); + ParamAddValue(param, catname, "ROIImagesLocation"); + ParamAddValue(param, catname, "ROIImagesRetention"); - var catname = "PostProcessing"; - category[catname] = new Object(); - category[catname]["enabled"] = false; - 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", 1, true, "true"); - ParamAddValue(param, catname, "MaxRateValue", 1, true); - ParamAddValue(param, catname, "MaxRateType", 1, true); - ParamAddValue(param, catname, "ExtendedResolution", 1, true, "false"); - ParamAddValue(param, catname, "IgnoreLeadingNaN", 1, true, "false"); - ParamAddValue(param, catname, "ErrorMessage"); - ParamAddValue(param, catname, "CheckDigitIncreaseConsistency"); + var catname = "PostProcessing"; + category[catname] = new Object(); + category[catname]["enabled"] = false; + category[catname]["found"] = false; + param[catname] = new Object(); + ParamAddValue(param, catname, "DecimalShift", 1, true); + ParamAddValue(param, catname, "AnalogDigitalTransitionStart", 1, true); + ParamAddValue(param, catname, "PreValueUse", 1, true, "true"); + ParamAddValue(param, catname, "PreValueAgeStartup"); + ParamAddValue(param, catname, "AllowNegativeRate", 1, true, "false"); + // ParamAddValue(param, catname, "AllowNegativeRate"); + ParamAddValue(param, catname, "MaxRateValue", 1, true); + ParamAddValue(param, catname, "MaxRateType", 1, true); + ParamAddValue(param, catname, "ExtendedResolution", 1, true, "false"); + // ParamAddValue(param, catname, "ExtendedResolution"); + ParamAddValue(param, catname, "IgnoreLeadingNaN", 1, true, "false"); + // ParamAddValue(param, catname, "IgnoreLeadingNaN"); + ParamAddValue(param, catname, "IgnoreAllNaN", 1, true, "false"); + // ParamAddValue(param, catname, "IgnoreAllNaN"); + ParamAddValue(param, catname, "ErrorMessage"); + ParamAddValue(param, catname, "CheckDigitIncreaseConsistency"); - var catname = "MQTT"; - category[catname] = new Object(); - category[catname]["enabled"] = false; - category[catname]["found"] = false; - param[catname] = new Object(); - ParamAddValue(param, catname, "Uri"); - ParamAddValue(param, catname, "MainTopic", 1, false); - ParamAddValue(param, catname, "ClientID"); - ParamAddValue(param, catname, "user"); - ParamAddValue(param, catname, "password"); - ParamAddValue(param, catname, "RetainMessages"); - ParamAddValue(param, catname, "HomeassistantDiscovery"); - ParamAddValue(param, catname, "MeterType"); - ParamAddValue(param, catname, "CACert"); - ParamAddValue(param, catname, "ClientCert"); - ParamAddValue(param, catname, "ClientKey"); + var catname = "MQTT"; + category[catname] = new Object(); + category[catname]["enabled"] = false; + category[catname]["found"] = false; + param[catname] = new Object(); + ParamAddValue(param, catname, "Uri"); + ParamAddValue(param, catname, "MainTopic", 1, false); + ParamAddValue(param, catname, "ClientID"); + ParamAddValue(param, catname, "user"); + ParamAddValue(param, catname, "password"); + ParamAddValue(param, catname, "RetainMessages"); + ParamAddValue(param, catname, "HomeassistantDiscovery"); + ParamAddValue(param, catname, "MeterType"); + ParamAddValue(param, catname, "CACert"); + ParamAddValue(param, catname, "ClientCert"); + ParamAddValue(param, catname, "ClientKey"); - var catname = "InfluxDB"; - category[catname] = new Object(); - category[catname]["enabled"] = false; - category[catname]["found"] = false; - param[catname] = new Object(); - ParamAddValue(param, catname, "Uri"); - ParamAddValue(param, catname, "Database"); + var catname = "InfluxDB"; + category[catname] = new Object(); + category[catname]["enabled"] = false; + category[catname]["found"] = false; + param[catname] = new Object(); + ParamAddValue(param, catname, "Uri"); + ParamAddValue(param, catname, "Database"); // ParamAddValue(param, catname, "Measurement"); - ParamAddValue(param, catname, "user"); - ParamAddValue(param, catname, "password"); - ParamAddValue(param, catname, "Measurement", 1, true); - ParamAddValue(param, catname, "Field", 1, true); + ParamAddValue(param, catname, "user"); + ParamAddValue(param, catname, "password"); + ParamAddValue(param, catname, "Measurement", 1, true); + ParamAddValue(param, catname, "Field", 1, true); - var catname = "InfluxDBv2"; - category[catname] = new Object(); - category[catname]["enabled"] = false; - category[catname]["found"] = false; - param[catname] = new Object(); - ParamAddValue(param, catname, "Uri"); - ParamAddValue(param, catname, "Bucket"); + var catname = "InfluxDBv2"; + category[catname] = new Object(); + category[catname]["enabled"] = false; + category[catname]["found"] = false; + param[catname] = new Object(); + ParamAddValue(param, catname, "Uri"); + ParamAddValue(param, catname, "Bucket"); // ParamAddValue(param, catname, "Measurement"); - ParamAddValue(param, catname, "Org"); - ParamAddValue(param, catname, "Token"); - ParamAddValue(param, catname, "Measurement", 1, true); - ParamAddValue(param, catname, "Field", 1, true); + ParamAddValue(param, catname, "Org"); + ParamAddValue(param, catname, "Token"); + ParamAddValue(param, catname, "Measurement", 1, true); + ParamAddValue(param, catname, "Field", 1, true); - var catname = "GPIO"; - category[catname] = new Object(); - category[catname]["enabled"] = false; - category[catname]["found"] = false; - param[catname] = new Object(); - ParamAddValue(param, catname, "IO0", 6, false, "", [null, null, /^[0-9]*$/, null, null, /^[a-zA-Z0-9_-]*$/]); - ParamAddValue(param, catname, "IO1", 6, false, "", [null, null, /^[0-9]*$/, null, null, /^[a-zA-Z0-9_-]*$/]); - ParamAddValue(param, catname, "IO3", 6, false, "", [null, null, /^[0-9]*$/, null, null, /^[a-zA-Z0-9_-]*$/]); - ParamAddValue(param, catname, "IO4", 6, false, "", [null, null, /^[0-9]*$/, null, null, /^[a-zA-Z0-9_-]*$/]); - ParamAddValue(param, catname, "IO12", 6, false, "", [null, null, /^[0-9]*$/, null, null, /^[a-zA-Z0-9_-]*$/]); - ParamAddValue(param, catname, "IO13", 6, false, "", [null, null, /^[0-9]*$/, null, null, /^[a-zA-Z0-9_-]*$/]); - ParamAddValue(param, catname, "LEDType"); - ParamAddValue(param, catname, "LEDNumbers"); - ParamAddValue(param, catname, "LEDColor", 3); + var catname = "GPIO"; + category[catname] = new Object(); + category[catname]["enabled"] = false; + category[catname]["found"] = false; + param[catname] = new Object(); + ParamAddValue(param, catname, "IO0", 6, false, "", [null, null, /^[0-9]*$/, null, null, /^[a-zA-Z0-9_-]*$/]); + ParamAddValue(param, catname, "IO1", 6, false, "", [null, null, /^[0-9]*$/, null, null, /^[a-zA-Z0-9_-]*$/]); + ParamAddValue(param, catname, "IO3", 6, false, "", [null, null, /^[0-9]*$/, null, null, /^[a-zA-Z0-9_-]*$/]); + ParamAddValue(param, catname, "IO4", 6, false, "", [null, null, /^[0-9]*$/, null, null, /^[a-zA-Z0-9_-]*$/]); + ParamAddValue(param, catname, "IO12", 6, false, "", [null, null, /^[0-9]*$/, null, null, /^[a-zA-Z0-9_-]*$/]); + ParamAddValue(param, catname, "IO13", 6, false, "", [null, null, /^[0-9]*$/, null, null, /^[a-zA-Z0-9_-]*$/]); + ParamAddValue(param, catname, "LEDType"); + ParamAddValue(param, catname, "LEDNumbers"); + ParamAddValue(param, catname, "LEDColor", 3); // Default Values, um abwärtskompatiblität zu gewährleisten - param[catname]["LEDType"]["value1"] = "WS2812"; - param[catname]["LEDNumbers"]["value1"] = "2"; - param[catname]["LEDColor"]["value1"] = "50"; - param[catname]["LEDColor"]["value2"] = "50"; - param[catname]["LEDColor"]["value3"] = "50"; + param[catname]["LEDType"]["value1"] = "WS2812"; + param[catname]["LEDNumbers"]["value1"] = "2"; + param[catname]["LEDColor"]["value1"] = "50"; + param[catname]["LEDColor"]["value2"] = "50"; + param[catname]["LEDColor"]["value3"] = "50"; + var catname = "AutoTimer"; + category[catname] = new Object(); + category[catname]["enabled"] = false; + category[catname]["found"] = false; + param[catname] = new Object(); + ParamAddValue(param, catname, "AutoStart"); + ParamAddValue(param, catname, "Interval"); - var catname = "AutoTimer"; - category[catname] = new Object(); - category[catname]["enabled"] = false; - category[catname]["found"] = false; - param[catname] = new Object(); - ParamAddValue(param, catname, "AutoStart"); - ParamAddValue(param, catname, "Interval"); + var catname = "DataLogging"; + category[catname] = new Object(); + category[catname]["enabled"] = false; + category[catname]["found"] = false; + param[catname] = new Object(); + ParamAddValue(param, catname, "DataLogActive"); + ParamAddValue(param, catname, "DataFilesRetention"); - var catname = "DataLogging"; - category[catname] = new Object(); - category[catname]["enabled"] = false; - category[catname]["found"] = false; - param[catname] = new Object(); - ParamAddValue(param, catname, "DataLogActive"); - ParamAddValue(param, catname, "DataFilesRetention"); + var catname = "Debug"; + category[catname] = new Object(); + category[catname]["enabled"] = false; + category[catname]["found"] = false; + param[catname] = new Object(); + ParamAddValue(param, catname, "LogLevel"); + ParamAddValue(param, catname, "LogfilesRetention"); - var catname = "Debug"; - category[catname] = new Object(); - category[catname]["enabled"] = false; - category[catname]["found"] = false; - param[catname] = new Object(); - ParamAddValue(param, catname, "LogLevel"); - ParamAddValue(param, catname, "LogfilesRetention"); - - var catname = "System"; - category[catname] = new Object(); - category[catname]["enabled"] = false; - category[catname]["found"] = false; - param[catname] = new Object(); - ParamAddValue(param, catname, "TimeZone"); - ParamAddValue(param, catname, "TimeServer"); - ParamAddValue(param, catname, "Hostname"); - ParamAddValue(param, catname, "RSSIThreshold"); - ParamAddValue(param, catname, "CPUFrequency"); - ParamAddValue(param, catname, "SetupMode"); + var catname = "System"; + category[catname] = new Object(); + category[catname]["enabled"] = false; + category[catname]["found"] = false; + param[catname] = new Object(); + ParamAddValue(param, catname, "Tooltip"); + ParamAddValue(param, catname, "TimeZone"); + ParamAddValue(param, catname, "TimeServer"); + ParamAddValue(param, catname, "Hostname"); + ParamAddValue(param, catname, "RSSIThreshold"); + ParamAddValue(param, catname, "CPUFrequency"); + ParamAddValue(param, catname, "SetupMode"); - - while (aktline < config_split.length){ - for (var cat in category) { - zw = cat.toUpperCase(); - zw1 = "[" + zw + "]"; - zw2 = ";[" + zw + "]"; - if ((config_split[aktline].trim().toUpperCase() == zw1) || (config_split[aktline].trim().toUpperCase() == zw2)) { - if (config_split[aktline].trim().toUpperCase() == zw1) { - category[cat]["enabled"] = true; - } - category[cat]["found"] = true; - category[cat]["line"] = aktline; - aktline = ParseConfigParamAll(aktline, cat); - continue; - } - } - aktline++; - } + while (aktline < config_split.length){ + for (var cat in category) { + zw = cat.toUpperCase(); + zw1 = "[" + zw + "]"; + zw2 = ";[" + zw + "]"; + + if ((config_split[aktline].trim().toUpperCase() == zw1) || (config_split[aktline].trim().toUpperCase() == zw2)) { + if (config_split[aktline].trim().toUpperCase() == zw1) { + category[cat]["enabled"] = true; + } + + category[cat]["found"] = true; + category[cat]["line"] = aktline; + aktline = ParseConfigParamAll(aktline, cat); + continue; + } + } + + aktline++; + } - // Make the downward compatiblity with DataLogging - if (category["DataLogging"]["found"] == false) - { - category["DataLogging"]["found"] = true; - category["DataLogging"]["enabled"] = true; + // Make the downward compatiblity with DataLogging + if (category["DataLogging"]["found"] == false) { + category["DataLogging"]["found"] = true; + category["DataLogging"]["enabled"] = true; - param["DataLogging"]["DataLogActive"]["found"] = true; - param["DataLogging"]["DataLogActive"]["enabled"] = true; - param["DataLogging"]["DataLogActive"]["value1"] = "true"; + param["DataLogging"]["DataLogActive"]["found"] = true; + param["DataLogging"]["DataLogActive"]["enabled"] = true; + param["DataLogging"]["DataLogActive"]["value1"] = "true"; - param["DataLogging"]["DataFilesRetention"]["found"] = true; - param["DataLogging"]["DataFilesRetention"]["enabled"] = true; - param["DataLogging"]["DataFilesRetention"]["value1"] = "3"; - } + param["DataLogging"]["DataFilesRetention"]["found"] = true; + param["DataLogging"]["DataFilesRetention"]["enabled"] = true; + param["DataLogging"]["DataFilesRetention"]["value1"] = "3"; + } - if (category["DataLogging"]["enabled"] == false) - category["DataLogging"]["enabled"] = true + if (category["DataLogging"]["enabled"] == false) { + category["DataLogging"]["enabled"] = true + } - if (param["DataLogging"]["DataLogActive"]["enabled"] == false && param["DataLogging"]["DataLogActive"]["value1"] == "") - { - param["DataLogging"]["DataLogActive"]["found"] = true; - param["DataLogging"]["DataLogActive"]["enabled"] = true; - param["DataLogging"]["DataLogActive"]["value1"] = "true"; - } + if (param["DataLogging"]["DataLogActive"]["enabled"] == false && param["DataLogging"]["DataLogActive"]["value1"] == "") { + param["DataLogging"]["DataLogActive"]["found"] = true; + param["DataLogging"]["DataLogActive"]["enabled"] = true; + param["DataLogging"]["DataLogActive"]["value1"] = "true"; + } - if (param["DataLogging"]["DataFilesRetention"]["enabled"] == false && param["DataLogging"]["DataFilesRetention"]["value1"] == "") - { - param["DataLogging"]["DataFilesRetention"]["found"] = true; - param["DataLogging"]["DataFilesRetention"]["enabled"] = true; - param["DataLogging"]["DataFilesRetention"]["value1"] = "3"; - } + if (param["DataLogging"]["DataFilesRetention"]["enabled"] == false && param["DataLogging"]["DataFilesRetention"]["value1"] == "") { + param["DataLogging"]["DataFilesRetention"]["found"] = true; + param["DataLogging"]["DataFilesRetention"]["enabled"] = true; + param["DataLogging"]["DataFilesRetention"]["value1"] = "3"; + } - // Downward compatibility: Create RSSIThreshold if not available - if (param["System"]["RSSIThreshold"]["found"] == false) - { - param["System"]["RSSIThreshold"]["found"] = true; - param["System"]["RSSIThreshold"]["enabled"] = false; - param["System"]["RSSIThreshold"]["value1"] = "0"; - } + // Downward compatibility: Create RSSIThreshold if not available + if (param["System"]["RSSIThreshold"]["found"] == false) { + param["System"]["RSSIThreshold"]["found"] = true; + param["System"]["RSSIThreshold"]["enabled"] = false; + param["System"]["RSSIThreshold"]["value1"] = "0"; + } } -function ParamAddValue(param, _cat, _param, _anzParam = 1, _isNUMBER = false, _defaultValue = "", _checkRegExList = null){ - param[_cat][_param] = new Object(); - param[_cat][_param]["found"] = false; - param[_cat][_param]["enabled"] = false; - param[_cat][_param]["line"] = -1; - param[_cat][_param]["anzParam"] = _anzParam; - param[_cat][_param]["defaultValue"] = _defaultValue; - param[_cat][_param]["Numbers"] = _isNUMBER; - param[_cat][_param].checkRegExList = _checkRegExList; +function ParamAddValue(param, _cat, _param, _anzParam = 1, _isNUMBER = false, _defaultValue = "", _checkRegExList = null) { + param[_cat][_param] = new Object(); + param[_cat][_param]["found"] = false; + param[_cat][_param]["enabled"] = false; + param[_cat][_param]["line"] = -1; + param[_cat][_param]["anzParam"] = _anzParam; + param[_cat][_param]["defaultValue"] = _defaultValue; + param[_cat][_param]["Numbers"] = _isNUMBER; + param[_cat][_param].checkRegExList = _checkRegExList; }; -function ParseConfigParamAll(_aktline, _catname){ - ++_aktline; - while ((_aktline < config_split.length) - && !(config_split[_aktline][0] == "[") - && !((config_split[_aktline][0] == ";") && (config_split[_aktline][1] == "["))) { - var _input = config_split[_aktline]; - let [isCom, input] = isCommented(_input); - var linesplit = ZerlegeZeile(input); - ParamExtractValueAll(param, linesplit, _catname, _aktline, isCom); - if (!isCom && (linesplit.length >= 5) && (_catname == 'Digits')) - ExtractROIs(input, "digit"); - if (!isCom && (linesplit.length >= 5) && (_catname == 'Analog')) - ExtractROIs(input, "analog"); - if (!isCom && (linesplit.length == 3) && (_catname == 'Alignment')) - { - _newref = new Object(); - _newref["name"] = linesplit[0]; - _newref["x"] = linesplit[1]; - _newref["y"] = linesplit[2]; - REFERENCES.push(_newref); - } +function ParseConfigParamAll(_aktline, _catname) { + ++_aktline; - ++_aktline; - } - return _aktline; + while ((_aktline < config_split.length) && !(config_split[_aktline][0] == "[") && !((config_split[_aktline][0] == ";") && (config_split[_aktline][1] == "["))) { + var _input = config_split[_aktline]; + let [isCom, input] = isCommented(_input); + var linesplit = ZerlegeZeile(input); + ParamExtractValueAll(param, linesplit, _catname, _aktline, isCom); + + if (!isCom && (linesplit.length >= 5) && (_catname == 'Digits')) { + ExtractROIs(input, "digit"); + } + + if (!isCom && (linesplit.length >= 5) && (_catname == 'Analog')) { + ExtractROIs(input, "analog"); + } + + if (!isCom && (linesplit.length == 3) && (_catname == 'Alignment')) { + _newref = new Object(); + _newref["name"] = linesplit[0]; + _newref["x"] = linesplit[1]; + _newref["y"] = linesplit[2]; + REFERENCES.push(_newref); + } + + ++_aktline; + } + + return _aktline; } -function ParamExtractValue(_param, _linesplit, _catname, _paramname, _aktline, _iscom, _anzvalue = 1){ - if ((_linesplit[0].toUpperCase() == _paramname.toUpperCase()) && (_linesplit.length > _anzvalue)) - { - _param[_catname][_paramname]["found"] = true; - _param[_catname][_paramname]["enabled"] = !_iscom; - _param[_catname][_paramname]["line"] = _aktline; - _param[_catname][_paramname]["anzpara"] = _anzvalue; - for (var j = 1; j <= _anzvalue; ++j) { - _param[_catname][_paramname]["value"+j] = _linesplit[j]; - } - } + +function ParamExtractValue(_param, _linesplit, _catname, _paramname, _aktline, _iscom, _anzvalue = 1) { + if ((_linesplit[0].toUpperCase() == _paramname.toUpperCase()) && (_linesplit.length > _anzvalue)) { + _param[_catname][_paramname]["found"] = true; + _param[_catname][_paramname]["enabled"] = !_iscom; + _param[_catname][_paramname]["line"] = _aktline; + _param[_catname][_paramname]["anzpara"] = _anzvalue; + + for (var j = 1; j <= _anzvalue; ++j) { + _param[_catname][_paramname]["value"+j] = _linesplit[j]; + } + } } -function ParamExtractValueAll(_param, _linesplit, _catname, _aktline, _iscom){ - for (var paramname in _param[_catname]) { - _AktROI = "default"; - _AktPara = _linesplit[0]; - _pospunkt = _AktPara.indexOf ("."); - if (_pospunkt > -1) - { - _AktROI = _AktPara.substring(0, _pospunkt); - _AktPara = _AktPara.substring(_pospunkt+1); - } - if (_AktPara.toUpperCase() == paramname.toUpperCase()) - { - while (_linesplit.length <= _param[_catname][paramname]["anzParam"]) { - _linesplit.push(""); - } - _param[_catname][paramname]["found"] = true; - _param[_catname][paramname]["enabled"] = !_iscom; - _param[_catname][paramname]["line"] = _aktline; - if (_param[_catname][paramname]["Numbers"] == true) // möglicher Multiusage - { - abc = getNUMBERS(_linesplit[0]); - abc[_catname][paramname] = new Object; - abc[_catname][paramname]["found"] = true; - abc[_catname][paramname]["enabled"] = !_iscom; +function ParamExtractValueAll(_param, _linesplit, _catname, _aktline, _iscom) { + for (var paramname in _param[_catname]) { + _AktROI = "default"; + _AktPara = _linesplit[0]; + _pospunkt = _AktPara.indexOf ("."); + + if (_pospunkt > -1) { + _AktROI = _AktPara.substring(0, _pospunkt); + _AktPara = _AktPara.substring(_pospunkt+1); + } + + if (_AktPara.toUpperCase() == paramname.toUpperCase()) { + while (_linesplit.length <= _param[_catname][paramname]["anzParam"]) { + _linesplit.push(""); + } + + _param[_catname][paramname]["found"] = true; + _param[_catname][paramname]["enabled"] = !_iscom; + _param[_catname][paramname]["line"] = _aktline; + + if (_param[_catname][paramname]["Numbers"] == true) { // möglicher Multiusage + abc = getNUMBERS(_linesplit[0]); + abc[_catname][paramname] = new Object; + abc[_catname][paramname]["found"] = true; + abc[_catname][paramname]["enabled"] = !_iscom; - for (var j = 1; j <= _param[_catname][paramname]["anzParam"]; ++j) { - abc[_catname][paramname]["value"+j] = _linesplit[j]; - } - if (abc["name"] == "default") - { - for (_num in NUMBERS) // wert mit Default belegen - { - if (NUMBERS[_num][_catname][paramname]["found"] == false) - { - NUMBERS[_num][_catname][paramname]["found"] = true; - NUMBERS[_num][_catname][paramname]["enabled"] = !_iscom; - NUMBERS[_num][_catname][paramname]["line"] = _aktline; - for (var j = 1; j <= _param[_catname][paramname]["anzParam"]; ++j) { - NUMBERS[_num][_catname][paramname]["value"+j] = _linesplit[j]; - } - - } - } + for (var j = 1; j <= _param[_catname][paramname]["anzParam"]; ++j) { + abc[_catname][paramname]["value"+j] = _linesplit[j]; + } + + if (abc["name"] == "default") { + for (_num in NUMBERS) { // wert mit Default belegen + if (NUMBERS[_num][_catname][paramname]["found"] == false) { + NUMBERS[_num][_catname][paramname]["found"] = true; + NUMBERS[_num][_catname][paramname]["enabled"] = !_iscom; + NUMBERS[_num][_catname][paramname]["line"] = _aktline; + + for (var j = 1; j <= _param[_catname][paramname]["anzParam"]; ++j) { + NUMBERS[_num][_catname][paramname]["value"+j] = _linesplit[j]; + } + } } - } - else - { - _param[_catname][paramname]["found"] = true; - _param[_catname][paramname]["enabled"] = !_iscom; - _param[_catname][paramname]["line"] = _aktline; - for (var j = 1; j <= _param[_catname][paramname]["anzParam"]; ++j) { - _param[_catname][paramname]["value"+j] = _linesplit[j]; - } - } - } - } + } + } + else { + _param[_catname][paramname]["found"] = true; + _param[_catname][paramname]["enabled"] = !_iscom; + _param[_catname][paramname]["line"] = _aktline; + + for (var j = 1; j <= _param[_catname][paramname]["anzParam"]; ++j) { + _param[_catname][paramname]["value"+j] = _linesplit[j]; + } + } + } + } } + +function getCamConfig() { + ParseConfig(); + + param["System"]["Tooltip"]["enabled"] = true; + param["Alignment"]["InitialRotate"]["enabled"] = true; + + param["TakeImage"]["WaitBeforeTakingPicture"]["enabled"] = true; + param["TakeImage"]["CamGainceiling"]["enabled"] = true; // Image gain (GAINCEILING_x2, x4, x8, x16, x32, x64 or x128) + param["TakeImage"]["CamQuality"]["enabled"] = true; // 0 - 63 + param["TakeImage"]["CamBrightness"]["enabled"] = true; // (-2 to 2) - set brightness + param["TakeImage"]["CamContrast"]["enabled"] = true; //-2 - 2 + param["TakeImage"]["CamSaturation"]["enabled"] = true; //-2 - 2 + param["TakeImage"]["CamSharpness"]["enabled"] = true; //-2 - 2 + param["TakeImage"]["CamAutoSharpness"]["enabled"] = true; //(1 or 0) + param["TakeImage"]["CamSpecialEffect"]["enabled"] = true; // 0 - 6 + param["TakeImage"]["CamWbMode"]["enabled"] = true; // 0 to 4 - if awb_gain enabled (0 - Auto, 1 - Sunny, 2 - Cloudy, 3 - Office, 4 - Home) + param["TakeImage"]["CamAwb"]["enabled"] = true; // white balance enable (0 or 1) + param["TakeImage"]["CamAwbGain"]["enabled"] = true; // Auto White Balance enable (0 or 1) + param["TakeImage"]["CamAec"]["enabled"] = true; // auto exposure off (1 or 0) + param["TakeImage"]["CamAec2"]["enabled"] = true; // automatic exposure sensor (0 or 1) + param["TakeImage"]["CamAeLevel"]["enabled"] = true; // auto exposure levels (-2 to 2) + param["TakeImage"]["CamAecValue"]["enabled"] = true; // set exposure manually (0-1200) + param["TakeImage"]["CamAgc"]["enabled"] = true; // auto gain off (1 or 0) + param["TakeImage"]["CamAgcGain"]["enabled"] = true; // set gain manually (0 - 30) + param["TakeImage"]["CamBpc"]["enabled"] = true; // black pixel correction + param["TakeImage"]["CamWpc"]["enabled"] = true; // white pixel correction + param["TakeImage"]["CamRawGma"]["enabled"] = true; // (1 or 0) + param["TakeImage"]["CamLenc"]["enabled"] = true; // lens correction (1 or 0) + param["TakeImage"]["CamHmirror"]["enabled"] = true; // (0 or 1) flip horizontally + param["TakeImage"]["CamVflip"]["enabled"] = true; // Invert image (0 or 1) + param["TakeImage"]["CamDcw"]["enabled"] = true; // downsize enable (1 or 0) + param["TakeImage"]["CamZoom"]["enabled"] = true; + param["TakeImage"]["CamZoomOffsetX"]["enabled"] = true; + param["TakeImage"]["CamZoomOffsetY"]["enabled"] = true; + param["TakeImage"]["CamZoomSize"]["enabled"] = true; + param["TakeImage"]["LEDIntensity"]["enabled"] = true; + + if (!param["System"]["Tooltip"]["found"]) { + param["System"]["Tooltip"]["found"] = true; + param["System"]["Tooltip"].value1 = 'true'; + } + + if (!param["Alignment"]["InitialRotate"]["found"]) { + param["Alignment"]["InitialRotate"]["found"] = true; + param["Alignment"]["InitialRotate"].value1 = 'false'; + } + + if (!param["TakeImage"]["WaitBeforeTakingPicture"]["found"]) { + param["TakeImage"]["WaitBeforeTakingPicture"]["found"] = true; + param["TakeImage"]["WaitBeforeTakingPicture"].value1 = '5'; + } + if (!param["TakeImage"]["CamGainceiling"]["found"]) { + param["TakeImage"]["CamGainceiling"]["found"] = true; + param["TakeImage"]["CamGainceiling"].value1 = '1'; + } + if (!param["TakeImage"]["CamQuality"]["found"]) { + param["TakeImage"]["CamQuality"]["found"] = true; + param["TakeImage"]["CamQuality"].value1 = '10'; + } + if (!param["TakeImage"]["CamBrightness"]["found"]) { + param["TakeImage"]["CamBrightness"]["found"] = true; + param["TakeImage"]["CamBrightness"].value1 = '0'; + } + if (!param["TakeImage"]["CamContrast"]["found"]) { + param["TakeImage"]["CamContrast"]["found"] = true; + param["TakeImage"]["CamContrast"].value1 = '0'; + } + if (!param["TakeImage"]["CamSaturation"]["found"]) { + param["TakeImage"]["CamSaturation"]["found"] = true; + param["TakeImage"]["CamSaturation"].value1 = '0'; + } + if (!param["TakeImage"]["CamSharpness"]["found"]) { + param["TakeImage"]["CamSharpness"]["found"] = true; + param["TakeImage"]["CamSharpness"].value1 = '0'; + } + if (!param["TakeImage"]["CamAutoSharpness"]["found"]) { + param["TakeImage"]["CamAutoSharpness"]["found"] = true; + param["TakeImage"]["CamAutoSharpness"].value1 = 'false'; + } + if (!param["TakeImage"]["CamSpecialEffect"]["found"]) { + param["TakeImage"]["CamSpecialEffect"]["found"] = true; + param["TakeImage"]["CamSpecialEffect"].value1 = 'no_effect'; + } + if (!param["TakeImage"]["CamWbMode"]["found"]) { + param["TakeImage"]["CamWbMode"]["found"] = true; + param["TakeImage"]["CamWbMode"].value1 = 'auto'; + } + if (!param["TakeImage"]["CamAwb"]["found"]) { + param["TakeImage"]["CamAwb"]["found"] = true; + param["TakeImage"]["CamAwb"].value1 = 'true'; + } + if (!param["TakeImage"]["CamAwbGain"]["found"]) { + param["TakeImage"]["CamAwbGain"]["found"] = true; + param["TakeImage"]["CamAwbGain"].value1 = 'true'; + } + if (!param["TakeImage"]["CamAec"]["found"]) { + param["TakeImage"]["CamAec"]["found"] = true; + param["TakeImage"]["CamAec"].value1 = 'true'; + } + if (!param["TakeImage"]["CamAec2"]["found"]) { + param["TakeImage"]["CamAec2"]["found"] = true; + param["TakeImage"]["CamAec2"].value1 = 'false'; + } + if (!param["TakeImage"]["CamAeLevel"]["found"]) { + param["TakeImage"]["CamAeLevel"]["found"] = true; + param["TakeImage"]["CamAeLevel"].value1 = '0'; + } + if (!param["TakeImage"]["CamAecValue"]["found"]) { + param["TakeImage"]["CamAecValue"]["found"] = true; + param["TakeImage"]["CamAecValue"].value1 = '168'; + } + if (!param["TakeImage"]["CamAgc"]["found"]) { + param["TakeImage"]["CamAgc"]["found"] = true; + param["TakeImage"]["CamAgc"].value1 = 'true'; + } + if (!param["TakeImage"]["CamAgcGain"]["found"]) { + param["TakeImage"]["CamAgcGain"]["found"] = true; + param["TakeImage"]["CamAgcGain"].value1 = '0'; + } + if (!param["TakeImage"]["CamBpc"]["found"]) { + param["TakeImage"]["CamBpc"]["found"] = true; + param["TakeImage"]["CamBpc"].value1 = 'false'; + } + if (!param["TakeImage"]["CamWpc"]["found"]) { + param["TakeImage"]["CamWpc"]["found"] = true; + param["TakeImage"]["CamWpc"].value1 = 'true'; + } + if (!param["TakeImage"]["CamRawGma"]["found"]) { + param["TakeImage"]["CamRawGma"]["found"] = true; + param["TakeImage"]["CamRawGma"].value1 = 'true'; + } + if (!param["TakeImage"]["CamLenc"]["found"]) { + param["TakeImage"]["CamLenc"]["found"] = true; + param["TakeImage"]["CamLenc"].value1 = 'true'; + } + if (!param["TakeImage"]["CamHmirror"]["found"]) { + param["TakeImage"]["CamHmirror"]["found"] = true; + param["TakeImage"]["CamHmirror"].value1 = 'false'; + } + if (!param["TakeImage"]["CamVflip"]["found"]) { + param["TakeImage"]["CamVflip"]["found"] = true; + param["TakeImage"]["CamVflip"].value1 = 'false'; + } + if (!param["TakeImage"]["CamDcw"]["found"]) { + param["TakeImage"]["CamDcw"]["found"] = true; + param["TakeImage"]["CamDcw"].value1 = 'true'; + } + if (!param["TakeImage"]["CamZoom"]["found"]) { + param["TakeImage"]["CamZoom"]["found"] = true; + param["TakeImage"]["CamZoom"].value1 = 'false'; + } + if (!param["TakeImage"]["CamZoomOffsetX"]["found"]) { + param["TakeImage"]["CamZoomOffsetX"]["found"] = true; + param["TakeImage"]["CamZoomOffsetX"].value1 = '0'; + } + if (!param["TakeImage"]["CamZoomOffsetY"]["found"]) { + param["TakeImage"]["CamZoomOffsetY"]["found"] = true; + param["TakeImage"]["CamZoomOffsetY"].value1 = '0'; + } + if (!param["TakeImage"]["CamZoomSize"]["found"]) { + param["TakeImage"]["CamZoomSize"]["found"] = true; + param["TakeImage"]["CamZoomSize"].value1 = '0'; + } + if (!param["TakeImage"]["LEDIntensity"]["found"]) { + param["TakeImage"]["LEDIntensity"]["found"] = true; + param["TakeImage"]["LEDIntensity"].value1 = '50'; + } + + return param; +} + + function getConfigParameters() { - return param; + return param; } -function WriteConfigININew() -{ - // Cleanup empty NUMBERS - for (var j = 0; j < NUMBERS.length; ++j) - { - if ((NUMBERS[j]["digit"].length + NUMBERS[j]["analog"].length) == 0) - { - NUMBERS.splice(j, 1); - } - } - config_split = new Array(0); +function WriteConfigININew() { + // Cleanup empty NUMBERS + for (var j = 0; j < NUMBERS.length; ++j) { + if ((NUMBERS[j]["digit"].length + NUMBERS[j]["analog"].length) == 0) { + NUMBERS.splice(j, 1); + } + } - for (var cat in param) { - text = "[" + cat + "]"; - if (!category[cat]["enabled"]) { - text = ";" + text; - } - config_split.push(text); + config_split = new Array(0); - for (var name in param[cat]) { - if (param[cat][name]["Numbers"]) - { - for (_num in NUMBERS) - { - text = NUMBERS[_num]["name"] + "." + name; + for (var cat in param) { + text = "[" + cat + "]"; + + if (!category[cat]["enabled"]) { + text = ";" + text; + } + + config_split.push(text); - var text = text + " =" + for (var name in param[cat]) { + if (param[cat][name]["Numbers"]) { + for (_num in NUMBERS) { + text = NUMBERS[_num]["name"] + "." + name; + + var text = text + " =" - for (var j = 1; j <= param[cat][name]["anzParam"]; ++j) { - if (!(typeof NUMBERS[_num][cat][name]["value"+j] == 'undefined')) - text = text + " " + NUMBERS[_num][cat][name]["value"+j]; - } - if (!NUMBERS[_num][cat][name]["enabled"]) { - text = ";" + text; - } - config_split.push(text); - } - } - else - { - var text = name + " =" - for (var j = 1; j <= param[cat][name]["anzParam"]; ++j) { - if (!(typeof param[cat][name]["value"+j] == 'undefined')) - text = text + " " + param[cat][name]["value"+j]; - } - if (!param[cat][name]["enabled"]) { - text = ";" + text; + if (!(typeof NUMBERS[_num][cat][name]["value"+j] == 'undefined')) { + text = text + " " + NUMBERS[_num][cat][name]["value"+j]; + } } + + if (!NUMBERS[_num][cat][name]["enabled"]) { + text = ";" + text; + } + config_split.push(text); - } - } - if (cat == "Digits") - { - for (var _roi in NUMBERS) - { - if (NUMBERS[_roi]["digit"].length > 0) - { - for (var _roiddet in NUMBERS[_roi]["digit"]) - { - text = NUMBERS[_roi]["name"] + "." + NUMBERS[_roi]["digit"][_roiddet]["name"]; - text = text + " " + NUMBERS[_roi]["digit"][_roiddet]["x"]; - text = text + " " + NUMBERS[_roi]["digit"][_roiddet]["y"]; - text = text + " " + NUMBERS[_roi]["digit"][_roiddet]["dx"]; - text = text + " " + NUMBERS[_roi]["digit"][_roiddet]["dy"]; - text = text + " " + NUMBERS[_roi]["digit"][_roiddet]["CCW"]; - config_split.push(text); - } + } + } + else { + var text = name + " =" + + for (var j = 1; j <= param[cat][name]["anzParam"]; ++j) { + if (!(typeof param[cat][name]["value"+j] == 'undefined')) { + text = text + " " + param[cat][name]["value"+j]; } - } - } - if (cat == "Analog") - { - for (var _roi in NUMBERS) - { - if (NUMBERS[_roi]["analog"].length > 0) - { - for (var _roiddet in NUMBERS[_roi]["analog"]) - { - text = NUMBERS[_roi]["name"] + "." + NUMBERS[_roi]["analog"][_roiddet]["name"]; - text = text + " " + NUMBERS[_roi]["analog"][_roiddet]["x"]; - text = text + " " + NUMBERS[_roi]["analog"][_roiddet]["y"]; - text = text + " " + NUMBERS[_roi]["analog"][_roiddet]["dx"]; - text = text + " " + NUMBERS[_roi]["analog"][_roiddet]["dy"]; - text = text + " " + NUMBERS[_roi]["analog"][_roiddet]["CCW"]; - config_split.push(text); - } + } + + if (!param[cat][name]["enabled"]) { + text = ";" + text; + } + + config_split.push(text); + } + } + + if (cat == "Digits") { + for (var _roi in NUMBERS) { + if (NUMBERS[_roi]["digit"].length > 0) { + for (var _roiddet in NUMBERS[_roi]["digit"]) { + text = NUMBERS[_roi]["name"] + "." + NUMBERS[_roi]["digit"][_roiddet]["name"]; + text = text + " " + NUMBERS[_roi]["digit"][_roiddet]["x"]; + text = text + " " + NUMBERS[_roi]["digit"][_roiddet]["y"]; + text = text + " " + NUMBERS[_roi]["digit"][_roiddet]["dx"]; + text = text + " " + NUMBERS[_roi]["digit"][_roiddet]["dy"]; + text = text + " " + NUMBERS[_roi]["digit"][_roiddet]["CCW"]; + config_split.push(text); } - } - } - if (cat == "Alignment") - { - for (var _roi in REFERENCES) - { - text = REFERENCES[_roi]["name"]; - text = text + " " + REFERENCES[_roi]["x"]; - text = text + " " + REFERENCES[_roi]["y"]; - config_split.push(text); - } - } + } + } + } + + if (cat == "Analog") { + for (var _roi in NUMBERS) { + if (NUMBERS[_roi]["analog"].length > 0) { + for (var _roiddet in NUMBERS[_roi]["analog"]) { + text = NUMBERS[_roi]["name"] + "." + NUMBERS[_roi]["analog"][_roiddet]["name"]; + text = text + " " + NUMBERS[_roi]["analog"][_roiddet]["x"]; + text = text + " " + NUMBERS[_roi]["analog"][_roiddet]["y"]; + text = text + " " + NUMBERS[_roi]["analog"][_roiddet]["dx"]; + text = text + " " + NUMBERS[_roi]["analog"][_roiddet]["dy"]; + text = text + " " + NUMBERS[_roi]["analog"][_roiddet]["CCW"]; + config_split.push(text); + } + } + } + } + + if (cat == "Alignment") { + for (var _roi in REFERENCES) { + text = REFERENCES[_roi]["name"]; + text = text + " " + REFERENCES[_roi]["x"]; + text = text + " " + REFERENCES[_roi]["y"]; + config_split.push(text); + } + } - config_split.push(""); - } + config_split.push(""); + } } -function isCommented(input) - { - let isComment = false; - if (input.charAt(0) == ';') { - isComment = true; - input = input.substr(1, input.length-1); - }; - return [isComment, input]; - } +function isCommented(input) { + let isComment = false; + + if (input.charAt(0) == ';') { + isComment = true; + input = input.substr(1, input.length-1); + } + + return [isComment, input]; +} + function SaveConfigToServer(_domainname){ - // leere Zeilen am Ende löschen - var zw = config_split.length - 1; - while (config_split[zw] == "") { - config_split.pop(); - } + // leere Zeilen am Ende löschen + var zw = config_split.length - 1; + + while (config_split[zw] == "") { + config_split.pop(); + } - var config_gesamt = ""; - for (var i = 0; i < config_split.length; ++i) - { - config_gesamt = config_gesamt + config_split[i] + "\n"; - } + var config_gesamt = ""; + + for (var i = 0; i < config_split.length; ++i) + { + config_gesamt = config_gesamt + config_split[i] + "\n"; + } - FileDeleteOnServer("/config/config.ini", _domainname); - FileSendContent(config_gesamt, "/config/config.ini", _domainname); + FileDeleteOnServer("/config/config.ini", _domainname); + FileSendContent(config_gesamt, "/config/config.ini", _domainname); } + function getConfig() { - return config_gesamt; - } + return config_gesamt; +} + function getConfigCategory() { - return category; + return category; } function ExtractROIs(_aktline, _type){ - var linesplit = ZerlegeZeile(_aktline); - abc = getNUMBERS(linesplit[0], _type); - abc["pos_ref"] = _aktline; - abc["x"] = linesplit[1]; - abc["y"] = linesplit[2]; - abc["dx"] = linesplit[3]; - abc["dy"] = linesplit[4]; - abc["ar"] = parseFloat(linesplit[3]) / parseFloat(linesplit[4]); - abc["CCW"] = "false"; - if (linesplit.length >= 6) - abc["CCW"] = linesplit[5]; + var linesplit = ZerlegeZeile(_aktline); + abc = getNUMBERS(linesplit[0], _type); + abc["pos_ref"] = _aktline; + abc["x"] = linesplit[1]; + abc["y"] = linesplit[2]; + abc["dx"] = linesplit[3]; + abc["dy"] = linesplit[4]; + abc["ar"] = parseFloat(linesplit[3]) / parseFloat(linesplit[4]); + abc["CCW"] = "false"; + + if (linesplit.length >= 6) { + abc["CCW"] = linesplit[5]; + } } -function getNUMBERS(_name, _type, _create = true) -{ - _pospunkt = _name.indexOf ("."); - if (_pospunkt > -1) - { - _digit = _name.substring(0, _pospunkt); - _roi = _name.substring(_pospunkt+1); - } - else - { - _digit = "default"; - _roi = _name; - } +function getNUMBERS(_name, _type, _create = true) { + _pospunkt = _name.indexOf ("."); + + if (_pospunkt > -1) { + _digit = _name.substring(0, _pospunkt); + _roi = _name.substring(_pospunkt+1); + } + else { + _digit = "default"; + _roi = _name; + } - _ret = -1; + _ret = -1; - for (i = 0; i < NUMBERS.length; ++i) - { - if (NUMBERS[i]["name"] == _digit) - _ret = NUMBERS[i]; - } + for (i = 0; i < NUMBERS.length; ++i) { + if (NUMBERS[i]["name"] == _digit) { + _ret = NUMBERS[i]; + } + } - if (!_create) // nicht gefunden und soll auch nicht erzeugt werden, ggf. geht eine NULL zurück + if (!_create) { // nicht gefunden und soll auch nicht erzeugt werden, ggf. geht eine NULL zurück return _ret; + } - if (_ret == -1) - { - _ret = new Object(); - _ret["name"] = _digit; - _ret['digit'] = new Array(); - _ret['analog'] = new Array(); - - for (_cat in param) - for (_param in param[_cat]) - if (param[_cat][_param]["Numbers"] == true){ - if (typeof _ret[_cat] == 'undefined') - _ret[_cat] = new Object(); - _ret[_cat][_param] = new Object(); - _ret[_cat][_param]["found"] = false; - _ret[_cat][_param]["enabled"] = false; - _ret[_cat][_param]["anzParam"] = param[_cat][_param]["anzParam"]; + if (_ret == -1) { + _ret = new Object(); + _ret["name"] = _digit; + _ret['digit'] = new Array(); + _ret['analog'] = new Array(); + for (_cat in param) { + for (_param in param[_cat]) { + if (param[_cat][_param]["Numbers"] == true){ + if (typeof _ret[_cat] == 'undefined') { + _ret[_cat] = new Object(); } + + _ret[_cat][_param] = new Object(); + _ret[_cat][_param]["found"] = false; + _ret[_cat][_param]["enabled"] = false; + _ret[_cat][_param]["anzParam"] = param[_cat][_param]["anzParam"]; + } + } + } - NUMBERS.push(_ret); - } + NUMBERS.push(_ret); + } - if (typeof _type == 'undefined') // muss schon existieren !!! - also erst nach Digits / Analog aufrufen - return _ret; + if (typeof _type == 'undefined') { // muss schon existieren !!! - also erst nach Digits / Analog aufrufen + return _ret; + } - neuroi = new Object(); - neuroi["name"] = _roi; - _ret[_type].push(neuroi); - - - return neuroi; + neuroi = new Object(); + neuroi["name"] = _roi; + _ret[_type].push(neuroi); + return neuroi; } -function CopyReferenceToImgTmp(_domainname) -{ - for (index = 0; index < 2; ++index) - { - _filenamevon = REFERENCES[index]["name"]; - _filenamenach = _filenamevon.replace("/config/", "/img_tmp/"); - FileDeleteOnServer(_filenamenach, _domainname); - FileCopyOnServer(_filenamevon, _filenamenach, _domainname); +function CopyReferenceToImgTmp(_domainname) { + for (index = 0; index < 2; ++index) { + _filenamevon = REFERENCES[index]["name"]; + _filenamenach = _filenamevon.replace("/config/", "/img_tmp/"); + FileDeleteOnServer(_filenamenach, _domainname); + FileCopyOnServer(_filenamevon, _filenamenach, _domainname); - _filenamevon = _filenamevon.replace(".jpg", "_org.jpg"); - _filenamenach = _filenamenach.replace(".jpg", "_org.jpg"); - FileDeleteOnServer(_filenamenach, _domainname); - FileCopyOnServer(_filenamevon, _filenamenach, _domainname); - } + _filenamevon = _filenamevon.replace(".jpg", "_org.jpg"); + _filenamenach = _filenamenach.replace(".jpg", "_org.jpg"); + FileDeleteOnServer(_filenamenach, _domainname); + FileCopyOnServer(_filenamevon, _filenamenach, _domainname); + } } + function GetReferencesInfo(){ - return REFERENCES; + return REFERENCES; } function UpdateConfigReferences(_domainname){ - for (var index = 0; index < 2; ++index) - { - _filenamenach = REFERENCES[index]["name"]; - _filenamevon = _filenamenach.replace("/config/", "/img_tmp/"); - FileDeleteOnServer(_filenamenach, _domainname); - FileCopyOnServer(_filenamevon, _filenamenach, _domainname); + for (var index = 0; index < 2; ++index) { + _filenamenach = REFERENCES[index]["name"]; + _filenamevon = _filenamenach.replace("/config/", "/img_tmp/"); + FileDeleteOnServer(_filenamenach, _domainname); + FileCopyOnServer(_filenamevon, _filenamenach, _domainname); - _filenamenach = _filenamenach.replace(".jpg", "_org.jpg"); - _filenamevon = _filenamevon.replace(".jpg", "_org.jpg"); - FileDeleteOnServer(_filenamenach, _domainname); - FileCopyOnServer(_filenamevon, _filenamenach, _domainname); - } + _filenamenach = _filenamenach.replace(".jpg", "_org.jpg"); + _filenamevon = _filenamevon.replace(".jpg", "_org.jpg"); + FileDeleteOnServer(_filenamenach, _domainname); + FileCopyOnServer(_filenamevon, _filenamenach, _domainname); + } } @@ -740,186 +927,217 @@ function getNUMBERInfo(){ return NUMBERS; } + function RenameNUMBER(_alt, _neu){ - if ((_neu.indexOf(".") >= 0) || (_neu.indexOf(",") >= 0) || - (_neu.indexOf(" ") >= 0) || (_neu.indexOf("\"") >= 0)) - { - return "Number sequence name must not contain , . \" or a space"; - } + if ((_neu.indexOf(".") >= 0) || (_neu.indexOf(",") >= 0) || (_neu.indexOf(" ") >= 0) || (_neu.indexOf("\"") >= 0)) { + return "Number sequence name must not contain , . \" or a space"; + } - index = -1; - found = false; - for (i = 0; i < NUMBERS.length; ++i) { - if (NUMBERS[i]["name"] == _alt) - index = i; - if (NUMBERS[i]["name"] == _neu) - found = true; - } + index = -1; + found = false; + + for (i = 0; i < NUMBERS.length; ++i) { + if (NUMBERS[i]["name"] == _alt) { + index = i; + } + + if (NUMBERS[i]["name"] == _neu) { + found = true; + } + } - if (found) - return "Number sequence name is already existing, please choose another name"; + if (found) { + return "Number sequence name is already existing, please choose another name"; + } - NUMBERS[index]["name"] = _neu; + NUMBERS[index]["name"] = _neu; - return ""; + return ""; } + function DeleteNUMBER(_delete){ - if (NUMBERS.length == 1) - return "One number sequence is mandatory. Therefore this cannot be deleted" + if (NUMBERS.length == 1) { + return "One number sequence is mandatory. Therefore this cannot be deleted" + } + index = -1; + + for (i = 0; i < NUMBERS.length; ++i) { + if (NUMBERS[i]["name"] == _delete) { + index = i; + } + } - index = -1; - for (i = 0; i < NUMBERS.length; ++i) { - if (NUMBERS[i]["name"] == _delete) - index = i; - } + if (index > -1) { + NUMBERS.splice(index, 1); + } - if (index > -1) { - NUMBERS.splice(index, 1); - } - - return ""; + return ""; } + function CreateNUMBER(_numbernew){ - found = false; - for (i = 0; i < NUMBERS.length; ++i) { - if (NUMBERS[i]["name"] == _numbernew) - found = true; - } + found = false; + + for (i = 0; i < NUMBERS.length; ++i) { + if (NUMBERS[i]["name"] == _numbernew) { + found = true; + } + } - if (found) - return "Number sequence name is already existing, please choose another name"; + if (found) { + return "Number sequence name is already existing, please choose another name"; + } - _ret = new Object(); - _ret["name"] = _numbernew; - _ret['digit'] = new Array(); - _ret['analog'] = new Array(); + _ret = new Object(); + _ret["name"] = _numbernew; + _ret['digit'] = new Array(); + _ret['analog'] = new Array(); - for (_cat in param) - for (_param in param[_cat]) - if (param[_cat][_param]["Numbers"] == true) - { - if (typeof (_ret[_cat]) === "undefined") - { - _ret[_cat] = new Object(); - } - _ret[_cat][_param] = new Object(); - if (param[_cat][_param]["defaultValue"] === "") - { - _ret[_cat][_param]["found"] = false; - _ret[_cat][_param]["enabled"] = false; - } - else - { - _ret[_cat][_param]["found"] = true; - _ret[_cat][_param]["enabled"] = true; - _ret[_cat][_param]["value1"] = param[_cat][_param]["defaultValue"]; + for (_cat in param) { + for (_param in param[_cat]) { + if (param[_cat][_param]["Numbers"] == true) { + if (typeof (_ret[_cat]) === "undefined") { + _ret[_cat] = new Object(); + } + + _ret[_cat][_param] = new Object(); + + if (param[_cat][_param]["defaultValue"] === "") { + _ret[_cat][_param]["found"] = false; + _ret[_cat][_param]["enabled"] = false; + } + else { + _ret[_cat][_param]["found"] = true; + _ret[_cat][_param]["enabled"] = true; + _ret[_cat][_param]["value1"] = param[_cat][_param]["defaultValue"]; - } - _ret[_cat][_param]["anzParam"] = param[_cat][_param]["anzParam"]; + } + + _ret[_cat][_param]["anzParam"] = param[_cat][_param]["anzParam"]; + } + } + } - } - - NUMBERS.push(_ret); - return ""; + NUMBERS.push(_ret); + return ""; } function getROIInfo(_typeROI, _number){ - index = -1; - for (var i = 0; i < NUMBERS.length; ++i) - if (NUMBERS[i]["name"] == _number) - index = i; + index = -1; + + for (var i = 0; i < NUMBERS.length; ++i) { + if (NUMBERS[i]["name"] == _number) { + index = i; + } + } - if (index != -1) - return NUMBERS[index][_typeROI]; - else - return ""; + if (index != -1) { + return NUMBERS[index][_typeROI]; + } + else { + return ""; + } } function RenameROI(_number, _type, _alt, _neu){ - if ((_neu.includes("=")) || (_neu.includes(".")) || (_neu.includes(":")) || - (_neu.includes(",")) || (_neu.includes(";")) || (_neu.includes(" ")) || - (_neu.includes("\""))) - { - return "ROI name must not contain . : , ; = \" or space"; - } + if ((_neu.includes("=")) || (_neu.includes(".")) || (_neu.includes(":")) || (_neu.includes(",")) || (_neu.includes(";")) || (_neu.includes(" ")) || (_neu.includes("\""))) { + return "ROI name must not contain . : , ; = \" or space"; + } - index = -1; - found = false; - _indexnumber = -1; - for (j = 0; j < NUMBERS.length; ++j) - if (NUMBERS[j]["name"] == _number) - _indexnumber = j; + index = -1; + found = false; + _indexnumber = -1; + + for (j = 0; j < NUMBERS.length; ++j) { + if (NUMBERS[j]["name"] == _number) { + _indexnumber = j; + } + } - if (_indexnumber == -1) - return "Number sequence not existing. ROI cannot be renamed" + if (_indexnumber == -1) { + return "Number sequence not existing. ROI cannot be renamed" + } - for (i = 0; i < NUMBERS[_indexnumber][_type].length; ++i) { - if (NUMBERS[_indexnumber][_type][i]["name"] == _alt) - index = i; - if (NUMBERS[_indexnumber][_type][i]["name"] == _neu) - found = true; - } + for (i = 0; i < NUMBERS[_indexnumber][_type].length; ++i) { + if (NUMBERS[_indexnumber][_type][i]["name"] == _alt) { + index = i; + } + + if (NUMBERS[_indexnumber][_type][i]["name"] == _neu) { + found = true; + } + } - if (found) - return "ROI name is already existing, please choose another name"; + if (found) { + return "ROI name is already existing, please choose another name"; + } - NUMBERS[_indexnumber][_type][index]["name"] = _neu; + NUMBERS[_indexnumber][_type][index]["name"] = _neu; - return ""; + return ""; } -function DeleteNUMBER(_delte){ - if (NUMBERS.length == 1) - return "The last number cannot be deleted" - - index = -1; - for (i = 0; i < NUMBERS.length; ++i) { - if (NUMBERS[i]["name"] == _delte) - index = i; - } +function DeleteNUMBER(_delte) { + if (NUMBERS.length == 1) { + return "The last number cannot be deleted" + } + + index = -1; + + for (i = 0; i < NUMBERS.length; ++i) { + if (NUMBERS[i]["name"] == _delte) { + index = i; + } + } - if (index > -1) { - NUMBERS.splice(index, 1); - } + if (index > -1) { + NUMBERS.splice(index, 1); + } - return ""; + return ""; } function CreateROI(_number, _type, _pos, _roinew, _x, _y, _dx, _dy, _CCW){ - _indexnumber = -1; - for (j = 0; j < NUMBERS.length; ++j) - if (NUMBERS[j]["name"] == _number) - _indexnumber = j; + _indexnumber = -1; + + for (j = 0; j < NUMBERS.length; ++j) { + if (NUMBERS[j]["name"] == _number) { + _indexnumber = j; + } + } - if (_indexnumber == -1) - return "Number sequence not existing. ROI cannot be created" + if (_indexnumber == -1) { + return "Number sequence not existing. ROI cannot be created" + } - found = false; - for (i = 0; i < NUMBERS[_indexnumber][_type].length; ++i) { - if (NUMBERS[_indexnumber][_type][i]["name"] == _roinew) - found = true; - } + found = false; + + for (i = 0; i < NUMBERS[_indexnumber][_type].length; ++i) { + if (NUMBERS[_indexnumber][_type][i]["name"] == _roinew) { + found = true; + } + } - if (found) - return "ROI name is already existing, please choose another name"; + if (found) { + return "ROI name is already existing, please choose another name"; + } - _ret = new Object(); - _ret["name"] = _roinew; - _ret["x"] = _x; - _ret["y"] = _y; - _ret["dx"] = _dx; - _ret["dy"] = _dy; - _ret["ar"] = _dx / _dy; - _ret["CCW"] = _CCW; + _ret = new Object(); + _ret["name"] = _roinew; + _ret["x"] = _x; + _ret["y"] = _y; + _ret["dx"] = _dx; + _ret["dy"] = _dy; + _ret["ar"] = _dx / _dy; + _ret["CCW"] = _CCW; - NUMBERS[_indexnumber][_type].splice(_pos+1, 0, _ret); + NUMBERS[_indexnumber][_type].splice(_pos+1, 0, _ret); - return ""; + return ""; }