Compare commits

...

327 Commits

Author SHA1 Message Date
CaCO3
37086987d0 update pipeline (#3296)
* Create dig-cont_0640_s3_q.tflite

* Update edit_reference.html (#2924)

Zoom-Einstellungen ausblenden, wenn zoom deaktiviert ist

* Update edit_config_template.html (#2925)

Zoom-Einstellungen ausblenden, wenn zoom deaktiviert ist +
Kameraeinstellungen nicht nur in der config.ini speichern, sondern auch setzen

* The parameter "negative" is processed on the MCU

* Renamed menu entry Alignment -> References

* renamed model file to make naming consistent

* Fix test (#2933)

* always reset change absolute (#2956)

* Create dig-class11_1701_s2.tflite

* Update tflite

* Update tflite

* 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

* Fix minor typo and harmonize spaces (#3030)

* Update edit_digits.html

* Update edit_analog.html

* Update overview.html

* Update edit_reference.html

---------

Co-authored-by: jomjol <30766535+jomjol@users.noreply.github.com>

* Source code formatting, ClassFlowPostProcessing.cpp

* fix edit_config_template.html

Unfortunately, I didn't take out some entries from other experiments because I overlooked/forgot them^^

* fix readconfigparam.js

Unfortunately, I didn't take out some entries from other experiments because I overlooked/forgot them^^

* fix edit_config_template.html

TakeImage_CamZoomMode_value1 was replaced by TakeImage_CamZoomSize_value1, but not deleted.
This caused problems when saving the camera settings.

* Update info.html

function loadWLANSSID() was present three times

* Update overview.html

CamFrameSize is no longer needed/used for zoom

* Update reply-bot.yaml

* homeassistant service discovery: derive node_id when using nested topics (#3088)

* derive correct node_id for homeassistant service discovery in nested topics (fixes #1792)

* explicit use of std::string

* move nodeId creation to separate function
add unit-tests

* add documentation about node_id generation for Home Assistant MQTT Service Discovery

* add Prometheus/OpenMetrics exporter (#3081)

* add prometheus endpoint

* refine metrics implementation

* move metrics generator to ClassFlowControll

* add more metrics
align prefix

* add more metrics
clean up

* refine documentation

* revert dependencies change

* sanitize labels

* create separate module for openmetrics

* move openmetrics to separate folder

* clean up

* add basic unit-tests

* work with const numbers
add replaceAll for string replacement
avoid opening std namespace
adapt unit-tests

* Update code/main/server_main.cpp

---------

Co-authored-by: CaCO3 <caco3@ruinelli.ch>

* Typo

* update platformIO to 6.7.0 (ESP IDF 5.2.1) (#3098)

* update to platformio/espressif32 @ 6.7.0

* remove unused getReadout() as it throws errors (error: 'virtual std::string ClassFlow::getReadout()' was hidden).

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* Update reply-bot.yaml (#3107)

* Fix actions-label-commenter

* Update Helper.cpp

* Update Helper.h

* Update Helper.cpp

* Update readconfigparam.js

fix for:
In the selected field the value '1' in the section 'TakeImage' in the field 'CamGainceiling' is invalid. PLEASE CHECK BEFORE SAVING!

* proposal for renaming and documentation (#3115)

* Update server_camera.cpp

 Fix building with -D DEBUG_DETAIL_ON 

better alternative to:
https://github.com/jomjol/AI-on-the-edge-device/pull/3160

* Update ClassFlowPostProcessing.cpp

* Update ClassFlowAlignment.cpp

* Fix building with `-D DEBUG_DETAIL_ON` (#3160)

Building with `-D DEBUG_DETAIL_ON` has been broken since #3029.

Co-authored-by: CaCO3 <caco3@ruinelli.ch>

* Handle empty prevalue.ini gracefully (#3162)

Fixes #2149.

* Bugfix for boot loop (#3175)

* Add files via upload

* Add files via upload

* Add files via upload

* Delete param-docs/parameter-pages/TakeImage/Aec2.md

has been replaced by CamAec2.md

* Delete param-docs/parameter-pages/TakeImage/AutoExposureLevel.md

has been replaced by CamAeLevel.md

* Delete param-docs/parameter-pages/TakeImage/Brightness.md

has been replaced by CamBrightness.md

* Delete param-docs/parameter-pages/TakeImage/Contrast.md

has been replaced by CamContrast.md

* Delete param-docs/parameter-pages/TakeImage/Grayscale.md

has been replaced by CamSpecialEffect.md

* Delete param-docs/parameter-pages/TakeImage/Negative.md

has been replaced by CamSpecialEffect.md

* Delete param-docs/parameter-pages/TakeImage/Saturation.md

has been replaced by CamSaturation.md

* Delete param-docs/parameter-pages/TakeImage/Sharpness.md

has been replaced by CamSharpness.md

* Delete param-docs/parameter-pages/TakeImage/ImageQuality.md

has been replaced by CamQuality.md

* Delete param-docs/parameter-pages/TakeImage/Zoom.md

has been replaced by CamZoom.md

* Delete param-docs/parameter-pages/TakeImage/ZoomMode.md

has been replaced by CamZoomSize.md

* Delete param-docs/parameter-pages/TakeImage/ZoomOffsetX.md

has been replaced by CamZoomOffsetX.md

* Delete param-docs/parameter-pages/TakeImage/ZoomOffsetY.md

has been replaced by CamZoomOffsetY.md

* Delete param-docs/parameter-pages/TakeImage/ImageSize.md

has been replaced by CamZoomSize.md

* Delete param-docs/parameter-pages/TakeImage/FixedExposure.md

has been replaced by CamAec.md

* Delete param-docs/parameter-pages/Alignment/FlipImageSize.md

has been replaced by CamVflip.md

* Delete param-docs/parameter-pages/Alignment/InitialMirror.md

has been replaced by CamHmirror.md

* CamParameter documentation update

https://github.com/jomjol/AI-on-the-edge-device/issues/3185

* typo

* add Webhook #3148 (#3163)

* WIP add Webhook

* fix config html for webhook
add tooltips for webhook

* webhook: fix not enabling webhook

* send webhook as json

* Update ApiKey.md

* webhook: fix only sending last "Number"

* webhook JSON is now closer to the data log in CSV format

* webhook: drop timeStampTimeUTC and switch from timeStamp to lastvalue like lokal csv to fix no timestamp on error

---------

Co-authored-by: CaCO3 <caco3@ruinelli.ch>

* Bugfix for time stamp (#3180)

* Update ClassFlowPostProcessing.cpp

* Update ClassFlowDefineTypes.h

* Update ClassFlowPostProcessing.cpp

* Update ClassFlowPostProcessing.cpp

* Update ClassFlowPostProcessing.cpp

* Update ClassFlowPostProcessing.cpp

* Update interface_webhook.cpp

* Update readconfigcommon.js

fix for: The same message("Image Contrast got enhanced") came up with "Update Marker" and "Enhance Image Contrast".

* fix svg favicon 

The svg one got added in 33893eb566 but does not work on Firefox

* Update platformIO to 6.8.1 (Contains ESP IDF 5.3) (#3196)

* Update platformIO to 6.8.1 (ESP IDF 5.3)

* removed now redundant typedef

* updated IDF manifest hash

* Add files via upload

so it should work now

* Update server_main.cpp

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>
Co-authored-by: michael <Heinrich-Tuning@web.de>

* Update MainFlowControl.cpp

* Add support for OV5640 camera (#3063)

* Add support for OV5640 camera

* clean up sharpness handling

* limit sharpness range to -2 and +2

* refactor

* Fix OV3660 sharpness handling

* refactor sharpness handling

* fix OV3660 zoom mode

* reinstate aspect ratio via imageSize

* Changed OV5640 full frame size to match datasheet

* various fixes

* add denoise config and general clean up

* fix line endings to LF

* Support enabling red blue swap via web interface

* update jpeg quality limits

* remove color swap config; color swap workaround dependent on vflip

* fix missing commit

* fix gain ceiling

* Update cam vflip param page

* fix typo: camdenoise, not camsdenoise

* fix compile errors

* Update MainFlowControl.cpp

* Add rate threshold parameter (#3195)

* still needs to be tested

https://github.com/jomjol/AI-on-the-edge-device/issues/3143

* Update ClassFlowPostProcessing.cpp

code formatting

* Update ClassFlowDefineTypes.h

code formatting

* Update ClassFlowPostProcessing.h

code formatting

* Update edit_config_template.html

* fix

* Update config.ini

* Update edit_config_template.html

* Updated param doc

* Rename parameters

* Update edit_config_template.html

* Update NUMBER.ChangeRateThreshold.md

* Update NUMBER.ChangeRateThreshold.md

---------

Co-authored-by: CaCO3 <caco3@ruinelli.ch>

* Update main.cpp

* Update config.ini

Adjusted camera settings to make the image brighter.

* Update readconfigparam.js

Adjusted camera settings to make the image brighter.

* add optional ImageUpload for Webhook (#3174)

* WIP add Webhook

* fix config html for webhook
add tooltips for webhook

* webhook: fix not enabling webhook

* send webhook as json

* Update ApiKey.md

* webhook: fix only sending last "Number"

* webhook JSON is now closer to the data log in CSV format

* webhook: add img upload

* webhoop added config for imgupload

* webhook html fixes

* webhook: drop timeStampTimeUTC and switch from timeStamp to lastvalue like lokal csv to fix no timestamp on error

* add checkbox for Webhook_UploadImg

* Update sd-card/html/edit_config_template.html

* Update edit_config_template.html

* Update edit_config_template.html

* Update edit_config_template.html

* added a long timestamp to both webhook requests

---------

Co-authored-by: CaCO3 <caco3@ruinelli.ch>

* Add files via upload (#3207)

* Update ClassFlowPostProcessing.cpp

deleted some unnecessary double entries
RateType renamed to MaxRateType

* Update ClassFlowDefineTypes.h

RateType renamed to MaxRateType

* Update text on recognition page

* Update digital CNN

* add a Delay between the WiFi reconnections (#3068)

* add a Delay between the WiFi reconnections

* log the delay between the WiFi reconnections

move the delay after the log

* cleanup

* cleanup

* cleanup

* Update edit_alignment.html

* cleanup

* cleanup

* Update platformIO to 6.9.0 (Contains ESP IDF 5.3.1)

* Handle crash on corrupted model (#3220)

* Upgrade esp-tflite-micro to 1.3.1

* Added log message to hint in case it crashes on loading a corrupted model

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* new dig-class100-173-s2-q on 23.800 images (#3257)

* new dig-class100-173-s2-q on 23.800 images

* platformio/espressif32 @ 6.8.1 for esp32cam-dev

* Revert "platformio/espressif32 @ 6.8.1 for esp32cam-dev"

This reverts commit cc9297d483.

* not using platformio 6.1.16

* Revert "not using platformio 6.1.16"

This reverts commit ef18e4fae7.

* moved number edit box styles into new file edit_style.css (#3262)

changed input[type=number] from 60px to 3em, to show 3 digits with current font size.

* added note about only TLS 1.2 is supported (#3213)

* Renamed digital to digit (#3219)

* renamed Digital to Digit

* added param migration

* Update .github/label-commenter-config.yaml

* renamed AnalogDigitTransition* to AnalogToDigitTransition*

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* Update Changelog.md

* Update Changelog.md

* Prepare next release (#3267) (#3270)

* Create dig-cont_0640_s3_q.tflite

* Update edit_reference.html (#2924)

Zoom-Einstellungen ausblenden, wenn zoom deaktiviert ist

* Update edit_config_template.html (#2925)

Zoom-Einstellungen ausblenden, wenn zoom deaktiviert ist +
Kameraeinstellungen nicht nur in der config.ini speichern, sondern auch setzen

* The parameter "negative" is processed on the MCU

* Renamed menu entry Alignment -> References

* renamed model file to make naming consistent

* Fix test (#2933)

* always reset change absolute (#2956)

* Create dig-class11_1701_s2.tflite

* Update tflite

* Update tflite

* 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

* Fix minor typo and harmonize spaces (#3030)

* Update edit_digits.html

* Update edit_analog.html

* Update overview.html

* Update edit_reference.html

---------



* Source code formatting, ClassFlowPostProcessing.cpp

* fix edit_config_template.html

Unfortunately, I didn't take out some entries from other experiments because I overlooked/forgot them^^

* fix readconfigparam.js

Unfortunately, I didn't take out some entries from other experiments because I overlooked/forgot them^^

* fix edit_config_template.html

TakeImage_CamZoomMode_value1 was replaced by TakeImage_CamZoomSize_value1, but not deleted.
This caused problems when saving the camera settings.

* Update info.html

function loadWLANSSID() was present three times

* Update overview.html

CamFrameSize is no longer needed/used for zoom

* Update reply-bot.yaml

* homeassistant service discovery: derive node_id when using nested topics (#3088)

* derive correct node_id for homeassistant service discovery in nested topics (fixes #1792)

* explicit use of std::string

* move nodeId creation to separate function
add unit-tests

* add documentation about node_id generation for Home Assistant MQTT Service Discovery

* add Prometheus/OpenMetrics exporter (#3081)

* add prometheus endpoint

* refine metrics implementation

* move metrics generator to ClassFlowControll

* add more metrics
align prefix

* add more metrics
clean up

* refine documentation

* revert dependencies change

* sanitize labels

* create separate module for openmetrics

* move openmetrics to separate folder

* clean up

* add basic unit-tests

* work with const numbers
add replaceAll for string replacement
avoid opening std namespace
adapt unit-tests

* Update code/main/server_main.cpp

---------



* Typo

* update platformIO to 6.7.0 (ESP IDF 5.2.1) (#3098)

* update to platformio/espressif32 @ 6.7.0

* remove unused getReadout() as it throws errors (error: 'virtual std::string ClassFlow::getReadout()' was hidden).

---------



* Update reply-bot.yaml (#3107)

* Fix actions-label-commenter

* Update Helper.cpp

* Update Helper.h

* Update Helper.cpp

* Update readconfigparam.js

fix for:
In the selected field the value '1' in the section 'TakeImage' in the field 'CamGainceiling' is invalid. PLEASE CHECK BEFORE SAVING!

* proposal for renaming and documentation (#3115)

* Update server_camera.cpp

 Fix building with -D DEBUG_DETAIL_ON 

better alternative to:
https://github.com/jomjol/AI-on-the-edge-device/pull/3160

* Update ClassFlowPostProcessing.cpp

* Update ClassFlowAlignment.cpp

* Fix building with `-D DEBUG_DETAIL_ON` (#3160)

Building with `-D DEBUG_DETAIL_ON` has been broken since #3029.



* Handle empty prevalue.ini gracefully (#3162)

Fixes #2149.

* Bugfix for boot loop (#3175)

* Add files via upload

* Add files via upload

* Add files via upload

* Delete param-docs/parameter-pages/TakeImage/Aec2.md

has been replaced by CamAec2.md

* Delete param-docs/parameter-pages/TakeImage/AutoExposureLevel.md

has been replaced by CamAeLevel.md

* Delete param-docs/parameter-pages/TakeImage/Brightness.md

has been replaced by CamBrightness.md

* Delete param-docs/parameter-pages/TakeImage/Contrast.md

has been replaced by CamContrast.md

* Delete param-docs/parameter-pages/TakeImage/Grayscale.md

has been replaced by CamSpecialEffect.md

* Delete param-docs/parameter-pages/TakeImage/Negative.md

has been replaced by CamSpecialEffect.md

* Delete param-docs/parameter-pages/TakeImage/Saturation.md

has been replaced by CamSaturation.md

* Delete param-docs/parameter-pages/TakeImage/Sharpness.md

has been replaced by CamSharpness.md

* Delete param-docs/parameter-pages/TakeImage/ImageQuality.md

has been replaced by CamQuality.md

* Delete param-docs/parameter-pages/TakeImage/Zoom.md

has been replaced by CamZoom.md

* Delete param-docs/parameter-pages/TakeImage/ZoomMode.md

has been replaced by CamZoomSize.md

* Delete param-docs/parameter-pages/TakeImage/ZoomOffsetX.md

has been replaced by CamZoomOffsetX.md

* Delete param-docs/parameter-pages/TakeImage/ZoomOffsetY.md

has been replaced by CamZoomOffsetY.md

* Delete param-docs/parameter-pages/TakeImage/ImageSize.md

has been replaced by CamZoomSize.md

* Delete param-docs/parameter-pages/TakeImage/FixedExposure.md

has been replaced by CamAec.md

* Delete param-docs/parameter-pages/Alignment/FlipImageSize.md

has been replaced by CamVflip.md

* Delete param-docs/parameter-pages/Alignment/InitialMirror.md

has been replaced by CamHmirror.md

* CamParameter documentation update

https://github.com/jomjol/AI-on-the-edge-device/issues/3185

* typo

* add Webhook #3148 (#3163)

* WIP add Webhook

* fix config html for webhook
add tooltips for webhook

* webhook: fix not enabling webhook

* send webhook as json

* Update ApiKey.md

* webhook: fix only sending last "Number"

* webhook JSON is now closer to the data log in CSV format

* webhook: drop timeStampTimeUTC and switch from timeStamp to lastvalue like lokal csv to fix no timestamp on error

---------



* Bugfix for time stamp (#3180)

* Update ClassFlowPostProcessing.cpp

* Update ClassFlowDefineTypes.h

* Update ClassFlowPostProcessing.cpp

* Update ClassFlowPostProcessing.cpp

* Update ClassFlowPostProcessing.cpp

* Update ClassFlowPostProcessing.cpp

* Update interface_webhook.cpp

* Update readconfigcommon.js

fix for: The same message("Image Contrast got enhanced") came up with "Update Marker" and "Enhance Image Contrast".

* fix svg favicon 

The svg one got added in 33893eb566 but does not work on Firefox

* Update platformIO to 6.8.1 (Contains ESP IDF 5.3) (#3196)

* Update platformIO to 6.8.1 (ESP IDF 5.3)

* removed now redundant typedef

* updated IDF manifest hash

* Add files via upload

so it should work now

* Update server_main.cpp

---------




* Update MainFlowControl.cpp

* Add support for OV5640 camera (#3063)

* Add support for OV5640 camera

* clean up sharpness handling

* limit sharpness range to -2 and +2

* refactor

* Fix OV3660 sharpness handling

* refactor sharpness handling

* fix OV3660 zoom mode

* reinstate aspect ratio via imageSize

* Changed OV5640 full frame size to match datasheet

* various fixes

* add denoise config and general clean up

* fix line endings to LF

* Support enabling red blue swap via web interface

* update jpeg quality limits

* remove color swap config; color swap workaround dependent on vflip

* fix missing commit

* fix gain ceiling

* Update cam vflip param page

* fix typo: camdenoise, not camsdenoise

* fix compile errors

* Update MainFlowControl.cpp

* Add rate threshold parameter (#3195)

* still needs to be tested

https://github.com/jomjol/AI-on-the-edge-device/issues/3143

* Update ClassFlowPostProcessing.cpp

code formatting

* Update ClassFlowDefineTypes.h

code formatting

* Update ClassFlowPostProcessing.h

code formatting

* Update edit_config_template.html

* fix

* Update config.ini

* Update edit_config_template.html

* Updated param doc

* Rename parameters

* Update edit_config_template.html

* Update NUMBER.ChangeRateThreshold.md

* Update NUMBER.ChangeRateThreshold.md

---------



* Update main.cpp

* Update config.ini

Adjusted camera settings to make the image brighter.

* Update readconfigparam.js

Adjusted camera settings to make the image brighter.

* add optional ImageUpload for Webhook (#3174)

* WIP add Webhook

* fix config html for webhook
add tooltips for webhook

* webhook: fix not enabling webhook

* send webhook as json

* Update ApiKey.md

* webhook: fix only sending last "Number"

* webhook JSON is now closer to the data log in CSV format

* webhook: add img upload

* webhoop added config for imgupload

* webhook html fixes

* webhook: drop timeStampTimeUTC and switch from timeStamp to lastvalue like lokal csv to fix no timestamp on error

* add checkbox for Webhook_UploadImg

* Update sd-card/html/edit_config_template.html

* Update edit_config_template.html

* Update edit_config_template.html

* Update edit_config_template.html

* added a long timestamp to both webhook requests

---------



* Add files via upload (#3207)

* Update ClassFlowPostProcessing.cpp

deleted some unnecessary double entries
RateType renamed to MaxRateType

* Update ClassFlowDefineTypes.h

RateType renamed to MaxRateType

* Update text on recognition page

* Update digital CNN

* add a Delay between the WiFi reconnections (#3068)

* add a Delay between the WiFi reconnections

* log the delay between the WiFi reconnections

move the delay after the log

* cleanup

* cleanup

* cleanup

* Update edit_alignment.html

* cleanup

* cleanup

* Update platformIO to 6.9.0 (Contains ESP IDF 5.3.1)

* Handle crash on corrupted model (#3220)

* Upgrade esp-tflite-micro to 1.3.1

* Added log message to hint in case it crashes on loading a corrupted model

---------



* new dig-class100-173-s2-q on 23.800 images (#3257)

* new dig-class100-173-s2-q on 23.800 images

* platformio/espressif32 @ 6.8.1 for esp32cam-dev

* Revert "platformio/espressif32 @ 6.8.1 for esp32cam-dev"

This reverts commit cc9297d483.

* not using platformio 6.1.16

* Revert "not using platformio 6.1.16"

This reverts commit ef18e4fae7.

* moved number edit box styles into new file edit_style.css (#3262)

changed input[type=number] from 60px to 3em, to show 3 digits with current font size.

* added note about only TLS 1.2 is supported (#3213)

* Renamed digital to digit (#3219)

* renamed Digital to Digit

* added param migration

* Update .github/label-commenter-config.yaml

* renamed AnalogDigitTransition* to AnalogToDigitTransition*

---------



* Update Changelog.md

* Update Changelog.md

---------

Co-authored-by: jomjol <30766535+jomjol@users.noreply.github.com>
Co-authored-by: michael <Heinrich-Tuning@web.de>
Co-authored-by: Frank Haverland <fspapaping@googlemail.com>
Co-authored-by: kub3let <95883234+kub3let@users.noreply.github.com>
Co-authored-by: Marco H <myxor@users.noreply.github.com>
Co-authored-by: Henry Thasler <henrythasler@users.noreply.github.com>
Co-authored-by: CaCO3 <caco@ruinelli.ch>
Co-authored-by: Sebastian Lövdahl <slovdahl@hibox.fi>
Co-authored-by: Raphael Hehl <raphael@rhehl.de>
Co-authored-by: jasaw <jasaw@dius.com.au>
Co-authored-by: Francesco Carnielli <hex7c0@gmail.com>
Co-authored-by: kalwados <kalwados@gmx.de>

* revert TFlite submodule update as certain modules crash with it, see https://github.com/jomjol/AI-on-the-edge-device/issues/3269

* Rename NUMBER.AnalogDigitTransitionStart.md to NUMBER.AnalogToDigitTransitionStart.md

* Update NUMBER.AnalogToDigitTransitionStart.md

* Update edit_config_template.html

* changed the webhook UploadImg to false

* changed the webhook UploadImg to false (#3279)

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* Show boolean option in settings page (#3285)

* changed the webhook UploadImg to false

* show boolean value on boolean drop down boxes

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* changed default value from boolean to numeric value in parameter camDenoise documentation

* Update edit_explain_7.html

https://github.com/jomjol/AI-on-the-edge-device/issues/3284?notification_referrer_id=NT_kwDOAAj1wbIxMjY3MDI1Njk3MDo1ODcyMDE#issuecomment-2387102786

* docs: update README.md (#3290)

prefered -> preferred

* rename/remove unused parameters (#3291)

* migrate-cam-parameters (#3288)

* Update main.cpp

* remove commented out code

---------

Co-authored-by: CaCO3 <caco3@ruinelli.ch>

* Update Changelog.md

* cleanup

* Skip release jobs on non-release changes

* Update build.yaml

* Update build.yaml

* Update build.yaml

* Update build.yaml

* Update build.yaml

* fix pipeline

* Update build.yaml

---------

Co-authored-by: jomjol <30766535+jomjol@users.noreply.github.com>
Co-authored-by: michael <Heinrich-Tuning@web.de>
Co-authored-by: Frank Haverland <fspapaping@googlemail.com>
Co-authored-by: kub3let <95883234+kub3let@users.noreply.github.com>
Co-authored-by: Marco H <myxor@users.noreply.github.com>
Co-authored-by: Henry Thasler <henrythasler@users.noreply.github.com>
Co-authored-by: CaCO3 <caco@ruinelli.ch>
Co-authored-by: Sebastian Lövdahl <slovdahl@hibox.fi>
Co-authored-by: Raphael Hehl <raphael@rhehl.de>
Co-authored-by: jasaw <jasaw@dius.com.au>
Co-authored-by: Francesco Carnielli <hex7c0@gmail.com>
Co-authored-by: kalwados <kalwados@gmx.de>
Co-authored-by: Ikko Eltociear Ashimine <eltociear@gmail.com>
2024-10-04 23:21:33 +02:00
CaCO3
a75035e9ed fix pipeline (#3294)
* Create dig-cont_0640_s3_q.tflite

* Update edit_reference.html (#2924)

Zoom-Einstellungen ausblenden, wenn zoom deaktiviert ist

* Update edit_config_template.html (#2925)

Zoom-Einstellungen ausblenden, wenn zoom deaktiviert ist +
Kameraeinstellungen nicht nur in der config.ini speichern, sondern auch setzen

* The parameter "negative" is processed on the MCU

* Renamed menu entry Alignment -> References

* renamed model file to make naming consistent

* Fix test (#2933)

* always reset change absolute (#2956)

* Create dig-class11_1701_s2.tflite

* Update tflite

* Update tflite

* 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

* Fix minor typo and harmonize spaces (#3030)

* Update edit_digits.html

* Update edit_analog.html

* Update overview.html

* Update edit_reference.html

---------

Co-authored-by: jomjol <30766535+jomjol@users.noreply.github.com>

* Source code formatting, ClassFlowPostProcessing.cpp

* fix edit_config_template.html

Unfortunately, I didn't take out some entries from other experiments because I overlooked/forgot them^^

* fix readconfigparam.js

Unfortunately, I didn't take out some entries from other experiments because I overlooked/forgot them^^

* fix edit_config_template.html

TakeImage_CamZoomMode_value1 was replaced by TakeImage_CamZoomSize_value1, but not deleted.
This caused problems when saving the camera settings.

* Update info.html

function loadWLANSSID() was present three times

* Update overview.html

CamFrameSize is no longer needed/used for zoom

* Update reply-bot.yaml

* homeassistant service discovery: derive node_id when using nested topics (#3088)

* derive correct node_id for homeassistant service discovery in nested topics (fixes #1792)

* explicit use of std::string

* move nodeId creation to separate function
add unit-tests

* add documentation about node_id generation for Home Assistant MQTT Service Discovery

* add Prometheus/OpenMetrics exporter (#3081)

* add prometheus endpoint

* refine metrics implementation

* move metrics generator to ClassFlowControll

* add more metrics
align prefix

* add more metrics
clean up

* refine documentation

* revert dependencies change

* sanitize labels

* create separate module for openmetrics

* move openmetrics to separate folder

* clean up

* add basic unit-tests

* work with const numbers
add replaceAll for string replacement
avoid opening std namespace
adapt unit-tests

* Update code/main/server_main.cpp

---------

Co-authored-by: CaCO3 <caco3@ruinelli.ch>

* Typo

* update platformIO to 6.7.0 (ESP IDF 5.2.1) (#3098)

* update to platformio/espressif32 @ 6.7.0

* remove unused getReadout() as it throws errors (error: 'virtual std::string ClassFlow::getReadout()' was hidden).

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* Update reply-bot.yaml (#3107)

* Fix actions-label-commenter

* Update Helper.cpp

* Update Helper.h

* Update Helper.cpp

* Update readconfigparam.js

fix for:
In the selected field the value '1' in the section 'TakeImage' in the field 'CamGainceiling' is invalid. PLEASE CHECK BEFORE SAVING!

* proposal for renaming and documentation (#3115)

* Update server_camera.cpp

 Fix building with -D DEBUG_DETAIL_ON 

better alternative to:
https://github.com/jomjol/AI-on-the-edge-device/pull/3160

* Update ClassFlowPostProcessing.cpp

* Update ClassFlowAlignment.cpp

* Fix building with `-D DEBUG_DETAIL_ON` (#3160)

Building with `-D DEBUG_DETAIL_ON` has been broken since #3029.

Co-authored-by: CaCO3 <caco3@ruinelli.ch>

* Handle empty prevalue.ini gracefully (#3162)

Fixes #2149.

* Bugfix for boot loop (#3175)

* Add files via upload

* Add files via upload

* Add files via upload

* Delete param-docs/parameter-pages/TakeImage/Aec2.md

has been replaced by CamAec2.md

* Delete param-docs/parameter-pages/TakeImage/AutoExposureLevel.md

has been replaced by CamAeLevel.md

* Delete param-docs/parameter-pages/TakeImage/Brightness.md

has been replaced by CamBrightness.md

* Delete param-docs/parameter-pages/TakeImage/Contrast.md

has been replaced by CamContrast.md

* Delete param-docs/parameter-pages/TakeImage/Grayscale.md

has been replaced by CamSpecialEffect.md

* Delete param-docs/parameter-pages/TakeImage/Negative.md

has been replaced by CamSpecialEffect.md

* Delete param-docs/parameter-pages/TakeImage/Saturation.md

has been replaced by CamSaturation.md

* Delete param-docs/parameter-pages/TakeImage/Sharpness.md

has been replaced by CamSharpness.md

* Delete param-docs/parameter-pages/TakeImage/ImageQuality.md

has been replaced by CamQuality.md

* Delete param-docs/parameter-pages/TakeImage/Zoom.md

has been replaced by CamZoom.md

* Delete param-docs/parameter-pages/TakeImage/ZoomMode.md

has been replaced by CamZoomSize.md

* Delete param-docs/parameter-pages/TakeImage/ZoomOffsetX.md

has been replaced by CamZoomOffsetX.md

* Delete param-docs/parameter-pages/TakeImage/ZoomOffsetY.md

has been replaced by CamZoomOffsetY.md

* Delete param-docs/parameter-pages/TakeImage/ImageSize.md

has been replaced by CamZoomSize.md

* Delete param-docs/parameter-pages/TakeImage/FixedExposure.md

has been replaced by CamAec.md

* Delete param-docs/parameter-pages/Alignment/FlipImageSize.md

has been replaced by CamVflip.md

* Delete param-docs/parameter-pages/Alignment/InitialMirror.md

has been replaced by CamHmirror.md

* CamParameter documentation update

https://github.com/jomjol/AI-on-the-edge-device/issues/3185

* typo

* add Webhook #3148 (#3163)

* WIP add Webhook

* fix config html for webhook
add tooltips for webhook

* webhook: fix not enabling webhook

* send webhook as json

* Update ApiKey.md

* webhook: fix only sending last "Number"

* webhook JSON is now closer to the data log in CSV format

* webhook: drop timeStampTimeUTC and switch from timeStamp to lastvalue like lokal csv to fix no timestamp on error

---------

Co-authored-by: CaCO3 <caco3@ruinelli.ch>

* Bugfix for time stamp (#3180)

* Update ClassFlowPostProcessing.cpp

* Update ClassFlowDefineTypes.h

* Update ClassFlowPostProcessing.cpp

* Update ClassFlowPostProcessing.cpp

* Update ClassFlowPostProcessing.cpp

* Update ClassFlowPostProcessing.cpp

* Update interface_webhook.cpp

* Update readconfigcommon.js

fix for: The same message("Image Contrast got enhanced") came up with "Update Marker" and "Enhance Image Contrast".

* fix svg favicon 

The svg one got added in 33893eb566 but does not work on Firefox

* Update platformIO to 6.8.1 (Contains ESP IDF 5.3) (#3196)

* Update platformIO to 6.8.1 (ESP IDF 5.3)

* removed now redundant typedef

* updated IDF manifest hash

* Add files via upload

so it should work now

* Update server_main.cpp

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>
Co-authored-by: michael <Heinrich-Tuning@web.de>

* Update MainFlowControl.cpp

* Add support for OV5640 camera (#3063)

* Add support for OV5640 camera

* clean up sharpness handling

* limit sharpness range to -2 and +2

* refactor

* Fix OV3660 sharpness handling

* refactor sharpness handling

* fix OV3660 zoom mode

* reinstate aspect ratio via imageSize

* Changed OV5640 full frame size to match datasheet

* various fixes

* add denoise config and general clean up

* fix line endings to LF

* Support enabling red blue swap via web interface

* update jpeg quality limits

* remove color swap config; color swap workaround dependent on vflip

* fix missing commit

* fix gain ceiling

* Update cam vflip param page

* fix typo: camdenoise, not camsdenoise

* fix compile errors

* Update MainFlowControl.cpp

* Add rate threshold parameter (#3195)

* still needs to be tested

https://github.com/jomjol/AI-on-the-edge-device/issues/3143

* Update ClassFlowPostProcessing.cpp

code formatting

* Update ClassFlowDefineTypes.h

code formatting

* Update ClassFlowPostProcessing.h

code formatting

* Update edit_config_template.html

* fix

* Update config.ini

* Update edit_config_template.html

* Updated param doc

* Rename parameters

* Update edit_config_template.html

* Update NUMBER.ChangeRateThreshold.md

* Update NUMBER.ChangeRateThreshold.md

---------

Co-authored-by: CaCO3 <caco3@ruinelli.ch>

* Update main.cpp

* Update config.ini

Adjusted camera settings to make the image brighter.

* Update readconfigparam.js

Adjusted camera settings to make the image brighter.

* add optional ImageUpload for Webhook (#3174)

* WIP add Webhook

* fix config html for webhook
add tooltips for webhook

* webhook: fix not enabling webhook

* send webhook as json

* Update ApiKey.md

* webhook: fix only sending last "Number"

* webhook JSON is now closer to the data log in CSV format

* webhook: add img upload

* webhoop added config for imgupload

* webhook html fixes

* webhook: drop timeStampTimeUTC and switch from timeStamp to lastvalue like lokal csv to fix no timestamp on error

* add checkbox for Webhook_UploadImg

* Update sd-card/html/edit_config_template.html

* Update edit_config_template.html

* Update edit_config_template.html

* Update edit_config_template.html

* added a long timestamp to both webhook requests

---------

Co-authored-by: CaCO3 <caco3@ruinelli.ch>

* Add files via upload (#3207)

* Update ClassFlowPostProcessing.cpp

deleted some unnecessary double entries
RateType renamed to MaxRateType

* Update ClassFlowDefineTypes.h

RateType renamed to MaxRateType

* Update text on recognition page

* Update digital CNN

* add a Delay between the WiFi reconnections (#3068)

* add a Delay between the WiFi reconnections

* log the delay between the WiFi reconnections

move the delay after the log

* cleanup

* cleanup

* cleanup

* Update edit_alignment.html

* cleanup

* cleanup

* Update platformIO to 6.9.0 (Contains ESP IDF 5.3.1)

* Handle crash on corrupted model (#3220)

* Upgrade esp-tflite-micro to 1.3.1

* Added log message to hint in case it crashes on loading a corrupted model

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* new dig-class100-173-s2-q on 23.800 images (#3257)

* new dig-class100-173-s2-q on 23.800 images

* platformio/espressif32 @ 6.8.1 for esp32cam-dev

* Revert "platformio/espressif32 @ 6.8.1 for esp32cam-dev"

This reverts commit cc9297d483.

* not using platformio 6.1.16

* Revert "not using platformio 6.1.16"

This reverts commit ef18e4fae7.

* moved number edit box styles into new file edit_style.css (#3262)

changed input[type=number] from 60px to 3em, to show 3 digits with current font size.

* added note about only TLS 1.2 is supported (#3213)

* Renamed digital to digit (#3219)

* renamed Digital to Digit

* added param migration

* Update .github/label-commenter-config.yaml

* renamed AnalogDigitTransition* to AnalogToDigitTransition*

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* Update Changelog.md

* Update Changelog.md

* Prepare next release (#3267) (#3270)

* Create dig-cont_0640_s3_q.tflite

* Update edit_reference.html (#2924)

Zoom-Einstellungen ausblenden, wenn zoom deaktiviert ist

* Update edit_config_template.html (#2925)

Zoom-Einstellungen ausblenden, wenn zoom deaktiviert ist +
Kameraeinstellungen nicht nur in der config.ini speichern, sondern auch setzen

* The parameter "negative" is processed on the MCU

* Renamed menu entry Alignment -> References

* renamed model file to make naming consistent

* Fix test (#2933)

* always reset change absolute (#2956)

* Create dig-class11_1701_s2.tflite

* Update tflite

* Update tflite

* 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

* Fix minor typo and harmonize spaces (#3030)

* Update edit_digits.html

* Update edit_analog.html

* Update overview.html

* Update edit_reference.html

---------



* Source code formatting, ClassFlowPostProcessing.cpp

* fix edit_config_template.html

Unfortunately, I didn't take out some entries from other experiments because I overlooked/forgot them^^

* fix readconfigparam.js

Unfortunately, I didn't take out some entries from other experiments because I overlooked/forgot them^^

* fix edit_config_template.html

TakeImage_CamZoomMode_value1 was replaced by TakeImage_CamZoomSize_value1, but not deleted.
This caused problems when saving the camera settings.

* Update info.html

function loadWLANSSID() was present three times

* Update overview.html

CamFrameSize is no longer needed/used for zoom

* Update reply-bot.yaml

* homeassistant service discovery: derive node_id when using nested topics (#3088)

* derive correct node_id for homeassistant service discovery in nested topics (fixes #1792)

* explicit use of std::string

* move nodeId creation to separate function
add unit-tests

* add documentation about node_id generation for Home Assistant MQTT Service Discovery

* add Prometheus/OpenMetrics exporter (#3081)

* add prometheus endpoint

* refine metrics implementation

* move metrics generator to ClassFlowControll

* add more metrics
align prefix

* add more metrics
clean up

* refine documentation

* revert dependencies change

* sanitize labels

* create separate module for openmetrics

* move openmetrics to separate folder

* clean up

* add basic unit-tests

* work with const numbers
add replaceAll for string replacement
avoid opening std namespace
adapt unit-tests

* Update code/main/server_main.cpp

---------



* Typo

* update platformIO to 6.7.0 (ESP IDF 5.2.1) (#3098)

* update to platformio/espressif32 @ 6.7.0

* remove unused getReadout() as it throws errors (error: 'virtual std::string ClassFlow::getReadout()' was hidden).

---------



* Update reply-bot.yaml (#3107)

* Fix actions-label-commenter

* Update Helper.cpp

* Update Helper.h

* Update Helper.cpp

* Update readconfigparam.js

fix for:
In the selected field the value '1' in the section 'TakeImage' in the field 'CamGainceiling' is invalid. PLEASE CHECK BEFORE SAVING!

* proposal for renaming and documentation (#3115)

* Update server_camera.cpp

 Fix building with -D DEBUG_DETAIL_ON 

better alternative to:
https://github.com/jomjol/AI-on-the-edge-device/pull/3160

* Update ClassFlowPostProcessing.cpp

* Update ClassFlowAlignment.cpp

* Fix building with `-D DEBUG_DETAIL_ON` (#3160)

Building with `-D DEBUG_DETAIL_ON` has been broken since #3029.



* Handle empty prevalue.ini gracefully (#3162)

Fixes #2149.

* Bugfix for boot loop (#3175)

* Add files via upload

* Add files via upload

* Add files via upload

* Delete param-docs/parameter-pages/TakeImage/Aec2.md

has been replaced by CamAec2.md

* Delete param-docs/parameter-pages/TakeImage/AutoExposureLevel.md

has been replaced by CamAeLevel.md

* Delete param-docs/parameter-pages/TakeImage/Brightness.md

has been replaced by CamBrightness.md

* Delete param-docs/parameter-pages/TakeImage/Contrast.md

has been replaced by CamContrast.md

* Delete param-docs/parameter-pages/TakeImage/Grayscale.md

has been replaced by CamSpecialEffect.md

* Delete param-docs/parameter-pages/TakeImage/Negative.md

has been replaced by CamSpecialEffect.md

* Delete param-docs/parameter-pages/TakeImage/Saturation.md

has been replaced by CamSaturation.md

* Delete param-docs/parameter-pages/TakeImage/Sharpness.md

has been replaced by CamSharpness.md

* Delete param-docs/parameter-pages/TakeImage/ImageQuality.md

has been replaced by CamQuality.md

* Delete param-docs/parameter-pages/TakeImage/Zoom.md

has been replaced by CamZoom.md

* Delete param-docs/parameter-pages/TakeImage/ZoomMode.md

has been replaced by CamZoomSize.md

* Delete param-docs/parameter-pages/TakeImage/ZoomOffsetX.md

has been replaced by CamZoomOffsetX.md

* Delete param-docs/parameter-pages/TakeImage/ZoomOffsetY.md

has been replaced by CamZoomOffsetY.md

* Delete param-docs/parameter-pages/TakeImage/ImageSize.md

has been replaced by CamZoomSize.md

* Delete param-docs/parameter-pages/TakeImage/FixedExposure.md

has been replaced by CamAec.md

* Delete param-docs/parameter-pages/Alignment/FlipImageSize.md

has been replaced by CamVflip.md

* Delete param-docs/parameter-pages/Alignment/InitialMirror.md

has been replaced by CamHmirror.md

* CamParameter documentation update

https://github.com/jomjol/AI-on-the-edge-device/issues/3185

* typo

* add Webhook #3148 (#3163)

* WIP add Webhook

* fix config html for webhook
add tooltips for webhook

* webhook: fix not enabling webhook

* send webhook as json

* Update ApiKey.md

* webhook: fix only sending last "Number"

* webhook JSON is now closer to the data log in CSV format

* webhook: drop timeStampTimeUTC and switch from timeStamp to lastvalue like lokal csv to fix no timestamp on error

---------



* Bugfix for time stamp (#3180)

* Update ClassFlowPostProcessing.cpp

* Update ClassFlowDefineTypes.h

* Update ClassFlowPostProcessing.cpp

* Update ClassFlowPostProcessing.cpp

* Update ClassFlowPostProcessing.cpp

* Update ClassFlowPostProcessing.cpp

* Update interface_webhook.cpp

* Update readconfigcommon.js

fix for: The same message("Image Contrast got enhanced") came up with "Update Marker" and "Enhance Image Contrast".

* fix svg favicon 

The svg one got added in 33893eb566 but does not work on Firefox

* Update platformIO to 6.8.1 (Contains ESP IDF 5.3) (#3196)

* Update platformIO to 6.8.1 (ESP IDF 5.3)

* removed now redundant typedef

* updated IDF manifest hash

* Add files via upload

so it should work now

* Update server_main.cpp

---------




* Update MainFlowControl.cpp

* Add support for OV5640 camera (#3063)

* Add support for OV5640 camera

* clean up sharpness handling

* limit sharpness range to -2 and +2

* refactor

* Fix OV3660 sharpness handling

* refactor sharpness handling

* fix OV3660 zoom mode

* reinstate aspect ratio via imageSize

* Changed OV5640 full frame size to match datasheet

* various fixes

* add denoise config and general clean up

* fix line endings to LF

* Support enabling red blue swap via web interface

* update jpeg quality limits

* remove color swap config; color swap workaround dependent on vflip

* fix missing commit

* fix gain ceiling

* Update cam vflip param page

* fix typo: camdenoise, not camsdenoise

* fix compile errors

* Update MainFlowControl.cpp

* Add rate threshold parameter (#3195)

* still needs to be tested

https://github.com/jomjol/AI-on-the-edge-device/issues/3143

* Update ClassFlowPostProcessing.cpp

code formatting

* Update ClassFlowDefineTypes.h

code formatting

* Update ClassFlowPostProcessing.h

code formatting

* Update edit_config_template.html

* fix

* Update config.ini

* Update edit_config_template.html

* Updated param doc

* Rename parameters

* Update edit_config_template.html

* Update NUMBER.ChangeRateThreshold.md

* Update NUMBER.ChangeRateThreshold.md

---------



* Update main.cpp

* Update config.ini

Adjusted camera settings to make the image brighter.

* Update readconfigparam.js

Adjusted camera settings to make the image brighter.

* add optional ImageUpload for Webhook (#3174)

* WIP add Webhook

* fix config html for webhook
add tooltips for webhook

* webhook: fix not enabling webhook

* send webhook as json

* Update ApiKey.md

* webhook: fix only sending last "Number"

* webhook JSON is now closer to the data log in CSV format

* webhook: add img upload

* webhoop added config for imgupload

* webhook html fixes

* webhook: drop timeStampTimeUTC and switch from timeStamp to lastvalue like lokal csv to fix no timestamp on error

* add checkbox for Webhook_UploadImg

* Update sd-card/html/edit_config_template.html

* Update edit_config_template.html

* Update edit_config_template.html

* Update edit_config_template.html

* added a long timestamp to both webhook requests

---------



* Add files via upload (#3207)

* Update ClassFlowPostProcessing.cpp

deleted some unnecessary double entries
RateType renamed to MaxRateType

* Update ClassFlowDefineTypes.h

RateType renamed to MaxRateType

* Update text on recognition page

* Update digital CNN

* add a Delay between the WiFi reconnections (#3068)

* add a Delay between the WiFi reconnections

* log the delay between the WiFi reconnections

move the delay after the log

* cleanup

* cleanup

* cleanup

* Update edit_alignment.html

* cleanup

* cleanup

* Update platformIO to 6.9.0 (Contains ESP IDF 5.3.1)

* Handle crash on corrupted model (#3220)

* Upgrade esp-tflite-micro to 1.3.1

* Added log message to hint in case it crashes on loading a corrupted model

---------



* new dig-class100-173-s2-q on 23.800 images (#3257)

* new dig-class100-173-s2-q on 23.800 images

* platformio/espressif32 @ 6.8.1 for esp32cam-dev

* Revert "platformio/espressif32 @ 6.8.1 for esp32cam-dev"

This reverts commit cc9297d483.

* not using platformio 6.1.16

* Revert "not using platformio 6.1.16"

This reverts commit ef18e4fae7.

* moved number edit box styles into new file edit_style.css (#3262)

changed input[type=number] from 60px to 3em, to show 3 digits with current font size.

* added note about only TLS 1.2 is supported (#3213)

* Renamed digital to digit (#3219)

* renamed Digital to Digit

* added param migration

* Update .github/label-commenter-config.yaml

* renamed AnalogDigitTransition* to AnalogToDigitTransition*

---------



* Update Changelog.md

* Update Changelog.md

---------

Co-authored-by: jomjol <30766535+jomjol@users.noreply.github.com>
Co-authored-by: michael <Heinrich-Tuning@web.de>
Co-authored-by: Frank Haverland <fspapaping@googlemail.com>
Co-authored-by: kub3let <95883234+kub3let@users.noreply.github.com>
Co-authored-by: Marco H <myxor@users.noreply.github.com>
Co-authored-by: Henry Thasler <henrythasler@users.noreply.github.com>
Co-authored-by: CaCO3 <caco@ruinelli.ch>
Co-authored-by: Sebastian Lövdahl <slovdahl@hibox.fi>
Co-authored-by: Raphael Hehl <raphael@rhehl.de>
Co-authored-by: jasaw <jasaw@dius.com.au>
Co-authored-by: Francesco Carnielli <hex7c0@gmail.com>
Co-authored-by: kalwados <kalwados@gmx.de>

* revert TFlite submodule update as certain modules crash with it, see https://github.com/jomjol/AI-on-the-edge-device/issues/3269

* Rename NUMBER.AnalogDigitTransitionStart.md to NUMBER.AnalogToDigitTransitionStart.md

* Update NUMBER.AnalogToDigitTransitionStart.md

* Update edit_config_template.html

* changed the webhook UploadImg to false

* changed the webhook UploadImg to false (#3279)

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* Show boolean option in settings page (#3285)

* changed the webhook UploadImg to false

* show boolean value on boolean drop down boxes

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* changed default value from boolean to numeric value in parameter camDenoise documentation

* Update edit_explain_7.html

https://github.com/jomjol/AI-on-the-edge-device/issues/3284?notification_referrer_id=NT_kwDOAAj1wbIxMjY3MDI1Njk3MDo1ODcyMDE#issuecomment-2387102786

* docs: update README.md (#3290)

prefered -> preferred

* rename/remove unused parameters (#3291)

* migrate-cam-parameters (#3288)

* Update main.cpp

* remove commented out code

---------

Co-authored-by: CaCO3 <caco3@ruinelli.ch>

* Update Changelog.md

* cleanup

* Skip release jobs on non-release changes

* Update build.yaml

* Update build.yaml

* Update build.yaml

* Update build.yaml

* Update build.yaml

---------

Co-authored-by: jomjol <30766535+jomjol@users.noreply.github.com>
Co-authored-by: michael <Heinrich-Tuning@web.de>
Co-authored-by: Frank Haverland <fspapaping@googlemail.com>
Co-authored-by: kub3let <95883234+kub3let@users.noreply.github.com>
Co-authored-by: Marco H <myxor@users.noreply.github.com>
Co-authored-by: Henry Thasler <henrythasler@users.noreply.github.com>
Co-authored-by: CaCO3 <caco@ruinelli.ch>
Co-authored-by: Sebastian Lövdahl <slovdahl@hibox.fi>
Co-authored-by: Raphael Hehl <raphael@rhehl.de>
Co-authored-by: jasaw <jasaw@dius.com.au>
Co-authored-by: Francesco Carnielli <hex7c0@gmail.com>
Co-authored-by: kalwados <kalwados@gmx.de>
Co-authored-by: Ikko Eltociear Ashimine <eltociear@gmail.com>
2024-10-04 23:07:03 +02:00
CaCO3
2f1d7e577c updated pipeline (#3293)
* Create dig-cont_0640_s3_q.tflite

* Update edit_reference.html (#2924)

Zoom-Einstellungen ausblenden, wenn zoom deaktiviert ist

* Update edit_config_template.html (#2925)

Zoom-Einstellungen ausblenden, wenn zoom deaktiviert ist +
Kameraeinstellungen nicht nur in der config.ini speichern, sondern auch setzen

* The parameter "negative" is processed on the MCU

* Renamed menu entry Alignment -> References

* renamed model file to make naming consistent

* Fix test (#2933)

* always reset change absolute (#2956)

* Create dig-class11_1701_s2.tflite

* Update tflite

* Update tflite

* 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

* Fix minor typo and harmonize spaces (#3030)

* Update edit_digits.html

* Update edit_analog.html

* Update overview.html

* Update edit_reference.html

---------

Co-authored-by: jomjol <30766535+jomjol@users.noreply.github.com>

* Source code formatting, ClassFlowPostProcessing.cpp

* fix edit_config_template.html

Unfortunately, I didn't take out some entries from other experiments because I overlooked/forgot them^^

* fix readconfigparam.js

Unfortunately, I didn't take out some entries from other experiments because I overlooked/forgot them^^

* fix edit_config_template.html

TakeImage_CamZoomMode_value1 was replaced by TakeImage_CamZoomSize_value1, but not deleted.
This caused problems when saving the camera settings.

* Update info.html

function loadWLANSSID() was present three times

* Update overview.html

CamFrameSize is no longer needed/used for zoom

* Update reply-bot.yaml

* homeassistant service discovery: derive node_id when using nested topics (#3088)

* derive correct node_id for homeassistant service discovery in nested topics (fixes #1792)

* explicit use of std::string

* move nodeId creation to separate function
add unit-tests

* add documentation about node_id generation for Home Assistant MQTT Service Discovery

* add Prometheus/OpenMetrics exporter (#3081)

* add prometheus endpoint

* refine metrics implementation

* move metrics generator to ClassFlowControll

* add more metrics
align prefix

* add more metrics
clean up

* refine documentation

* revert dependencies change

* sanitize labels

* create separate module for openmetrics

* move openmetrics to separate folder

* clean up

* add basic unit-tests

* work with const numbers
add replaceAll for string replacement
avoid opening std namespace
adapt unit-tests

* Update code/main/server_main.cpp

---------

Co-authored-by: CaCO3 <caco3@ruinelli.ch>

* Typo

* update platformIO to 6.7.0 (ESP IDF 5.2.1) (#3098)

* update to platformio/espressif32 @ 6.7.0

* remove unused getReadout() as it throws errors (error: 'virtual std::string ClassFlow::getReadout()' was hidden).

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* Update reply-bot.yaml (#3107)

* Fix actions-label-commenter

* Update Helper.cpp

* Update Helper.h

* Update Helper.cpp

* Update readconfigparam.js

fix for:
In the selected field the value '1' in the section 'TakeImage' in the field 'CamGainceiling' is invalid. PLEASE CHECK BEFORE SAVING!

* proposal for renaming and documentation (#3115)

* Update server_camera.cpp

 Fix building with -D DEBUG_DETAIL_ON 

better alternative to:
https://github.com/jomjol/AI-on-the-edge-device/pull/3160

* Update ClassFlowPostProcessing.cpp

* Update ClassFlowAlignment.cpp

* Fix building with `-D DEBUG_DETAIL_ON` (#3160)

Building with `-D DEBUG_DETAIL_ON` has been broken since #3029.

Co-authored-by: CaCO3 <caco3@ruinelli.ch>

* Handle empty prevalue.ini gracefully (#3162)

Fixes #2149.

* Bugfix for boot loop (#3175)

* Add files via upload

* Add files via upload

* Add files via upload

* Delete param-docs/parameter-pages/TakeImage/Aec2.md

has been replaced by CamAec2.md

* Delete param-docs/parameter-pages/TakeImage/AutoExposureLevel.md

has been replaced by CamAeLevel.md

* Delete param-docs/parameter-pages/TakeImage/Brightness.md

has been replaced by CamBrightness.md

* Delete param-docs/parameter-pages/TakeImage/Contrast.md

has been replaced by CamContrast.md

* Delete param-docs/parameter-pages/TakeImage/Grayscale.md

has been replaced by CamSpecialEffect.md

* Delete param-docs/parameter-pages/TakeImage/Negative.md

has been replaced by CamSpecialEffect.md

* Delete param-docs/parameter-pages/TakeImage/Saturation.md

has been replaced by CamSaturation.md

* Delete param-docs/parameter-pages/TakeImage/Sharpness.md

has been replaced by CamSharpness.md

* Delete param-docs/parameter-pages/TakeImage/ImageQuality.md

has been replaced by CamQuality.md

* Delete param-docs/parameter-pages/TakeImage/Zoom.md

has been replaced by CamZoom.md

* Delete param-docs/parameter-pages/TakeImage/ZoomMode.md

has been replaced by CamZoomSize.md

* Delete param-docs/parameter-pages/TakeImage/ZoomOffsetX.md

has been replaced by CamZoomOffsetX.md

* Delete param-docs/parameter-pages/TakeImage/ZoomOffsetY.md

has been replaced by CamZoomOffsetY.md

* Delete param-docs/parameter-pages/TakeImage/ImageSize.md

has been replaced by CamZoomSize.md

* Delete param-docs/parameter-pages/TakeImage/FixedExposure.md

has been replaced by CamAec.md

* Delete param-docs/parameter-pages/Alignment/FlipImageSize.md

has been replaced by CamVflip.md

* Delete param-docs/parameter-pages/Alignment/InitialMirror.md

has been replaced by CamHmirror.md

* CamParameter documentation update

https://github.com/jomjol/AI-on-the-edge-device/issues/3185

* typo

* add Webhook #3148 (#3163)

* WIP add Webhook

* fix config html for webhook
add tooltips for webhook

* webhook: fix not enabling webhook

* send webhook as json

* Update ApiKey.md

* webhook: fix only sending last "Number"

* webhook JSON is now closer to the data log in CSV format

* webhook: drop timeStampTimeUTC and switch from timeStamp to lastvalue like lokal csv to fix no timestamp on error

---------

Co-authored-by: CaCO3 <caco3@ruinelli.ch>

* Bugfix for time stamp (#3180)

* Update ClassFlowPostProcessing.cpp

* Update ClassFlowDefineTypes.h

* Update ClassFlowPostProcessing.cpp

* Update ClassFlowPostProcessing.cpp

* Update ClassFlowPostProcessing.cpp

* Update ClassFlowPostProcessing.cpp

* Update interface_webhook.cpp

* Update readconfigcommon.js

fix for: The same message("Image Contrast got enhanced") came up with "Update Marker" and "Enhance Image Contrast".

* fix svg favicon 

The svg one got added in 33893eb566 but does not work on Firefox

* Update platformIO to 6.8.1 (Contains ESP IDF 5.3) (#3196)

* Update platformIO to 6.8.1 (ESP IDF 5.3)

* removed now redundant typedef

* updated IDF manifest hash

* Add files via upload

so it should work now

* Update server_main.cpp

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>
Co-authored-by: michael <Heinrich-Tuning@web.de>

* Update MainFlowControl.cpp

* Add support for OV5640 camera (#3063)

* Add support for OV5640 camera

* clean up sharpness handling

* limit sharpness range to -2 and +2

* refactor

* Fix OV3660 sharpness handling

* refactor sharpness handling

* fix OV3660 zoom mode

* reinstate aspect ratio via imageSize

* Changed OV5640 full frame size to match datasheet

* various fixes

* add denoise config and general clean up

* fix line endings to LF

* Support enabling red blue swap via web interface

* update jpeg quality limits

* remove color swap config; color swap workaround dependent on vflip

* fix missing commit

* fix gain ceiling

* Update cam vflip param page

* fix typo: camdenoise, not camsdenoise

* fix compile errors

* Update MainFlowControl.cpp

* Add rate threshold parameter (#3195)

* still needs to be tested

https://github.com/jomjol/AI-on-the-edge-device/issues/3143

* Update ClassFlowPostProcessing.cpp

code formatting

* Update ClassFlowDefineTypes.h

code formatting

* Update ClassFlowPostProcessing.h

code formatting

* Update edit_config_template.html

* fix

* Update config.ini

* Update edit_config_template.html

* Updated param doc

* Rename parameters

* Update edit_config_template.html

* Update NUMBER.ChangeRateThreshold.md

* Update NUMBER.ChangeRateThreshold.md

---------

Co-authored-by: CaCO3 <caco3@ruinelli.ch>

* Update main.cpp

* Update config.ini

Adjusted camera settings to make the image brighter.

* Update readconfigparam.js

Adjusted camera settings to make the image brighter.

* add optional ImageUpload for Webhook (#3174)

* WIP add Webhook

* fix config html for webhook
add tooltips for webhook

* webhook: fix not enabling webhook

* send webhook as json

* Update ApiKey.md

* webhook: fix only sending last "Number"

* webhook JSON is now closer to the data log in CSV format

* webhook: add img upload

* webhoop added config for imgupload

* webhook html fixes

* webhook: drop timeStampTimeUTC and switch from timeStamp to lastvalue like lokal csv to fix no timestamp on error

* add checkbox for Webhook_UploadImg

* Update sd-card/html/edit_config_template.html

* Update edit_config_template.html

* Update edit_config_template.html

* Update edit_config_template.html

* added a long timestamp to both webhook requests

---------

Co-authored-by: CaCO3 <caco3@ruinelli.ch>

* Add files via upload (#3207)

* Update ClassFlowPostProcessing.cpp

deleted some unnecessary double entries
RateType renamed to MaxRateType

* Update ClassFlowDefineTypes.h

RateType renamed to MaxRateType

* Update text on recognition page

* Update digital CNN

* add a Delay between the WiFi reconnections (#3068)

* add a Delay between the WiFi reconnections

* log the delay between the WiFi reconnections

move the delay after the log

* cleanup

* cleanup

* cleanup

* Update edit_alignment.html

* cleanup

* cleanup

* Update platformIO to 6.9.0 (Contains ESP IDF 5.3.1)

* Handle crash on corrupted model (#3220)

* Upgrade esp-tflite-micro to 1.3.1

* Added log message to hint in case it crashes on loading a corrupted model

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* new dig-class100-173-s2-q on 23.800 images (#3257)

* new dig-class100-173-s2-q on 23.800 images

* platformio/espressif32 @ 6.8.1 for esp32cam-dev

* Revert "platformio/espressif32 @ 6.8.1 for esp32cam-dev"

This reverts commit cc9297d483.

* not using platformio 6.1.16

* Revert "not using platformio 6.1.16"

This reverts commit ef18e4fae7.

* moved number edit box styles into new file edit_style.css (#3262)

changed input[type=number] from 60px to 3em, to show 3 digits with current font size.

* added note about only TLS 1.2 is supported (#3213)

* Renamed digital to digit (#3219)

* renamed Digital to Digit

* added param migration

* Update .github/label-commenter-config.yaml

* renamed AnalogDigitTransition* to AnalogToDigitTransition*

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* Update Changelog.md

* Update Changelog.md

* Prepare next release (#3267) (#3270)

* Create dig-cont_0640_s3_q.tflite

* Update edit_reference.html (#2924)

Zoom-Einstellungen ausblenden, wenn zoom deaktiviert ist

* Update edit_config_template.html (#2925)

Zoom-Einstellungen ausblenden, wenn zoom deaktiviert ist +
Kameraeinstellungen nicht nur in der config.ini speichern, sondern auch setzen

* The parameter "negative" is processed on the MCU

* Renamed menu entry Alignment -> References

* renamed model file to make naming consistent

* Fix test (#2933)

* always reset change absolute (#2956)

* Create dig-class11_1701_s2.tflite

* Update tflite

* Update tflite

* 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

* Fix minor typo and harmonize spaces (#3030)

* Update edit_digits.html

* Update edit_analog.html

* Update overview.html

* Update edit_reference.html

---------



* Source code formatting, ClassFlowPostProcessing.cpp

* fix edit_config_template.html

Unfortunately, I didn't take out some entries from other experiments because I overlooked/forgot them^^

* fix readconfigparam.js

Unfortunately, I didn't take out some entries from other experiments because I overlooked/forgot them^^

* fix edit_config_template.html

TakeImage_CamZoomMode_value1 was replaced by TakeImage_CamZoomSize_value1, but not deleted.
This caused problems when saving the camera settings.

* Update info.html

function loadWLANSSID() was present three times

* Update overview.html

CamFrameSize is no longer needed/used for zoom

* Update reply-bot.yaml

* homeassistant service discovery: derive node_id when using nested topics (#3088)

* derive correct node_id for homeassistant service discovery in nested topics (fixes #1792)

* explicit use of std::string

* move nodeId creation to separate function
add unit-tests

* add documentation about node_id generation for Home Assistant MQTT Service Discovery

* add Prometheus/OpenMetrics exporter (#3081)

* add prometheus endpoint

* refine metrics implementation

* move metrics generator to ClassFlowControll

* add more metrics
align prefix

* add more metrics
clean up

* refine documentation

* revert dependencies change

* sanitize labels

* create separate module for openmetrics

* move openmetrics to separate folder

* clean up

* add basic unit-tests

* work with const numbers
add replaceAll for string replacement
avoid opening std namespace
adapt unit-tests

* Update code/main/server_main.cpp

---------



* Typo

* update platformIO to 6.7.0 (ESP IDF 5.2.1) (#3098)

* update to platformio/espressif32 @ 6.7.0

* remove unused getReadout() as it throws errors (error: 'virtual std::string ClassFlow::getReadout()' was hidden).

---------



* Update reply-bot.yaml (#3107)

* Fix actions-label-commenter

* Update Helper.cpp

* Update Helper.h

* Update Helper.cpp

* Update readconfigparam.js

fix for:
In the selected field the value '1' in the section 'TakeImage' in the field 'CamGainceiling' is invalid. PLEASE CHECK BEFORE SAVING!

* proposal for renaming and documentation (#3115)

* Update server_camera.cpp

 Fix building with -D DEBUG_DETAIL_ON 

better alternative to:
https://github.com/jomjol/AI-on-the-edge-device/pull/3160

* Update ClassFlowPostProcessing.cpp

* Update ClassFlowAlignment.cpp

* Fix building with `-D DEBUG_DETAIL_ON` (#3160)

Building with `-D DEBUG_DETAIL_ON` has been broken since #3029.



* Handle empty prevalue.ini gracefully (#3162)

Fixes #2149.

* Bugfix for boot loop (#3175)

* Add files via upload

* Add files via upload

* Add files via upload

* Delete param-docs/parameter-pages/TakeImage/Aec2.md

has been replaced by CamAec2.md

* Delete param-docs/parameter-pages/TakeImage/AutoExposureLevel.md

has been replaced by CamAeLevel.md

* Delete param-docs/parameter-pages/TakeImage/Brightness.md

has been replaced by CamBrightness.md

* Delete param-docs/parameter-pages/TakeImage/Contrast.md

has been replaced by CamContrast.md

* Delete param-docs/parameter-pages/TakeImage/Grayscale.md

has been replaced by CamSpecialEffect.md

* Delete param-docs/parameter-pages/TakeImage/Negative.md

has been replaced by CamSpecialEffect.md

* Delete param-docs/parameter-pages/TakeImage/Saturation.md

has been replaced by CamSaturation.md

* Delete param-docs/parameter-pages/TakeImage/Sharpness.md

has been replaced by CamSharpness.md

* Delete param-docs/parameter-pages/TakeImage/ImageQuality.md

has been replaced by CamQuality.md

* Delete param-docs/parameter-pages/TakeImage/Zoom.md

has been replaced by CamZoom.md

* Delete param-docs/parameter-pages/TakeImage/ZoomMode.md

has been replaced by CamZoomSize.md

* Delete param-docs/parameter-pages/TakeImage/ZoomOffsetX.md

has been replaced by CamZoomOffsetX.md

* Delete param-docs/parameter-pages/TakeImage/ZoomOffsetY.md

has been replaced by CamZoomOffsetY.md

* Delete param-docs/parameter-pages/TakeImage/ImageSize.md

has been replaced by CamZoomSize.md

* Delete param-docs/parameter-pages/TakeImage/FixedExposure.md

has been replaced by CamAec.md

* Delete param-docs/parameter-pages/Alignment/FlipImageSize.md

has been replaced by CamVflip.md

* Delete param-docs/parameter-pages/Alignment/InitialMirror.md

has been replaced by CamHmirror.md

* CamParameter documentation update

https://github.com/jomjol/AI-on-the-edge-device/issues/3185

* typo

* add Webhook #3148 (#3163)

* WIP add Webhook

* fix config html for webhook
add tooltips for webhook

* webhook: fix not enabling webhook

* send webhook as json

* Update ApiKey.md

* webhook: fix only sending last "Number"

* webhook JSON is now closer to the data log in CSV format

* webhook: drop timeStampTimeUTC and switch from timeStamp to lastvalue like lokal csv to fix no timestamp on error

---------



* Bugfix for time stamp (#3180)

* Update ClassFlowPostProcessing.cpp

* Update ClassFlowDefineTypes.h

* Update ClassFlowPostProcessing.cpp

* Update ClassFlowPostProcessing.cpp

* Update ClassFlowPostProcessing.cpp

* Update ClassFlowPostProcessing.cpp

* Update interface_webhook.cpp

* Update readconfigcommon.js

fix for: The same message("Image Contrast got enhanced") came up with "Update Marker" and "Enhance Image Contrast".

* fix svg favicon 

The svg one got added in 33893eb566 but does not work on Firefox

* Update platformIO to 6.8.1 (Contains ESP IDF 5.3) (#3196)

* Update platformIO to 6.8.1 (ESP IDF 5.3)

* removed now redundant typedef

* updated IDF manifest hash

* Add files via upload

so it should work now

* Update server_main.cpp

---------




* Update MainFlowControl.cpp

* Add support for OV5640 camera (#3063)

* Add support for OV5640 camera

* clean up sharpness handling

* limit sharpness range to -2 and +2

* refactor

* Fix OV3660 sharpness handling

* refactor sharpness handling

* fix OV3660 zoom mode

* reinstate aspect ratio via imageSize

* Changed OV5640 full frame size to match datasheet

* various fixes

* add denoise config and general clean up

* fix line endings to LF

* Support enabling red blue swap via web interface

* update jpeg quality limits

* remove color swap config; color swap workaround dependent on vflip

* fix missing commit

* fix gain ceiling

* Update cam vflip param page

* fix typo: camdenoise, not camsdenoise

* fix compile errors

* Update MainFlowControl.cpp

* Add rate threshold parameter (#3195)

* still needs to be tested

https://github.com/jomjol/AI-on-the-edge-device/issues/3143

* Update ClassFlowPostProcessing.cpp

code formatting

* Update ClassFlowDefineTypes.h

code formatting

* Update ClassFlowPostProcessing.h

code formatting

* Update edit_config_template.html

* fix

* Update config.ini

* Update edit_config_template.html

* Updated param doc

* Rename parameters

* Update edit_config_template.html

* Update NUMBER.ChangeRateThreshold.md

* Update NUMBER.ChangeRateThreshold.md

---------



* Update main.cpp

* Update config.ini

Adjusted camera settings to make the image brighter.

* Update readconfigparam.js

Adjusted camera settings to make the image brighter.

* add optional ImageUpload for Webhook (#3174)

* WIP add Webhook

* fix config html for webhook
add tooltips for webhook

* webhook: fix not enabling webhook

* send webhook as json

* Update ApiKey.md

* webhook: fix only sending last "Number"

* webhook JSON is now closer to the data log in CSV format

* webhook: add img upload

* webhoop added config for imgupload

* webhook html fixes

* webhook: drop timeStampTimeUTC and switch from timeStamp to lastvalue like lokal csv to fix no timestamp on error

* add checkbox for Webhook_UploadImg

* Update sd-card/html/edit_config_template.html

* Update edit_config_template.html

* Update edit_config_template.html

* Update edit_config_template.html

* added a long timestamp to both webhook requests

---------



* Add files via upload (#3207)

* Update ClassFlowPostProcessing.cpp

deleted some unnecessary double entries
RateType renamed to MaxRateType

* Update ClassFlowDefineTypes.h

RateType renamed to MaxRateType

* Update text on recognition page

* Update digital CNN

* add a Delay between the WiFi reconnections (#3068)

* add a Delay between the WiFi reconnections

* log the delay between the WiFi reconnections

move the delay after the log

* cleanup

* cleanup

* cleanup

* Update edit_alignment.html

* cleanup

* cleanup

* Update platformIO to 6.9.0 (Contains ESP IDF 5.3.1)

* Handle crash on corrupted model (#3220)

* Upgrade esp-tflite-micro to 1.3.1

* Added log message to hint in case it crashes on loading a corrupted model

---------



* new dig-class100-173-s2-q on 23.800 images (#3257)

* new dig-class100-173-s2-q on 23.800 images

* platformio/espressif32 @ 6.8.1 for esp32cam-dev

* Revert "platformio/espressif32 @ 6.8.1 for esp32cam-dev"

This reverts commit cc9297d483.

* not using platformio 6.1.16

* Revert "not using platformio 6.1.16"

This reverts commit ef18e4fae7.

* moved number edit box styles into new file edit_style.css (#3262)

changed input[type=number] from 60px to 3em, to show 3 digits with current font size.

* added note about only TLS 1.2 is supported (#3213)

* Renamed digital to digit (#3219)

* renamed Digital to Digit

* added param migration

* Update .github/label-commenter-config.yaml

* renamed AnalogDigitTransition* to AnalogToDigitTransition*

---------



* Update Changelog.md

* Update Changelog.md

---------

Co-authored-by: jomjol <30766535+jomjol@users.noreply.github.com>
Co-authored-by: michael <Heinrich-Tuning@web.de>
Co-authored-by: Frank Haverland <fspapaping@googlemail.com>
Co-authored-by: kub3let <95883234+kub3let@users.noreply.github.com>
Co-authored-by: Marco H <myxor@users.noreply.github.com>
Co-authored-by: Henry Thasler <henrythasler@users.noreply.github.com>
Co-authored-by: CaCO3 <caco@ruinelli.ch>
Co-authored-by: Sebastian Lövdahl <slovdahl@hibox.fi>
Co-authored-by: Raphael Hehl <raphael@rhehl.de>
Co-authored-by: jasaw <jasaw@dius.com.au>
Co-authored-by: Francesco Carnielli <hex7c0@gmail.com>
Co-authored-by: kalwados <kalwados@gmx.de>

* revert TFlite submodule update as certain modules crash with it, see https://github.com/jomjol/AI-on-the-edge-device/issues/3269

* Rename NUMBER.AnalogDigitTransitionStart.md to NUMBER.AnalogToDigitTransitionStart.md

* Update NUMBER.AnalogToDigitTransitionStart.md

* Update edit_config_template.html

* changed the webhook UploadImg to false

* changed the webhook UploadImg to false (#3279)

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* Show boolean option in settings page (#3285)

* changed the webhook UploadImg to false

* show boolean value on boolean drop down boxes

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* changed default value from boolean to numeric value in parameter camDenoise documentation

* Update edit_explain_7.html

https://github.com/jomjol/AI-on-the-edge-device/issues/3284?notification_referrer_id=NT_kwDOAAj1wbIxMjY3MDI1Njk3MDo1ODcyMDE#issuecomment-2387102786

* docs: update README.md (#3290)

prefered -> preferred

* rename/remove unused parameters (#3291)

* migrate-cam-parameters (#3288)

* Update main.cpp

* remove commented out code

---------

Co-authored-by: CaCO3 <caco3@ruinelli.ch>

* Update Changelog.md

* cleanup

* Skip release jobs on non-release changes

* Update build.yaml

* Update build.yaml

* Update build.yaml

* Update build.yaml

---------

Co-authored-by: jomjol <30766535+jomjol@users.noreply.github.com>
Co-authored-by: michael <Heinrich-Tuning@web.de>
Co-authored-by: Frank Haverland <fspapaping@googlemail.com>
Co-authored-by: kub3let <95883234+kub3let@users.noreply.github.com>
Co-authored-by: Marco H <myxor@users.noreply.github.com>
Co-authored-by: Henry Thasler <henrythasler@users.noreply.github.com>
Co-authored-by: CaCO3 <caco@ruinelli.ch>
Co-authored-by: Sebastian Lövdahl <slovdahl@hibox.fi>
Co-authored-by: Raphael Hehl <raphael@rhehl.de>
Co-authored-by: jasaw <jasaw@dius.com.au>
Co-authored-by: Francesco Carnielli <hex7c0@gmail.com>
Co-authored-by: kalwados <kalwados@gmx.de>
Co-authored-by: Ikko Eltociear Ashimine <eltociear@gmail.com>
2024-10-04 22:59:44 +02:00
CaCO3
89c36374b3 RC2 preparations (#3292)
* Create dig-cont_0640_s3_q.tflite

* Update edit_reference.html (#2924)

Zoom-Einstellungen ausblenden, wenn zoom deaktiviert ist

* Update edit_config_template.html (#2925)

Zoom-Einstellungen ausblenden, wenn zoom deaktiviert ist +
Kameraeinstellungen nicht nur in der config.ini speichern, sondern auch setzen

* The parameter "negative" is processed on the MCU

* Renamed menu entry Alignment -> References

* renamed model file to make naming consistent

* Fix test (#2933)

* always reset change absolute (#2956)

* Create dig-class11_1701_s2.tflite

* Update tflite

* Update tflite

* 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

* Fix minor typo and harmonize spaces (#3030)

* Update edit_digits.html

* Update edit_analog.html

* Update overview.html

* Update edit_reference.html

---------

Co-authored-by: jomjol <30766535+jomjol@users.noreply.github.com>

* Source code formatting, ClassFlowPostProcessing.cpp

* fix edit_config_template.html

Unfortunately, I didn't take out some entries from other experiments because I overlooked/forgot them^^

* fix readconfigparam.js

Unfortunately, I didn't take out some entries from other experiments because I overlooked/forgot them^^

* fix edit_config_template.html

TakeImage_CamZoomMode_value1 was replaced by TakeImage_CamZoomSize_value1, but not deleted.
This caused problems when saving the camera settings.

* Update info.html

function loadWLANSSID() was present three times

* Update overview.html

CamFrameSize is no longer needed/used for zoom

* Update reply-bot.yaml

* homeassistant service discovery: derive node_id when using nested topics (#3088)

* derive correct node_id for homeassistant service discovery in nested topics (fixes #1792)

* explicit use of std::string

* move nodeId creation to separate function
add unit-tests

* add documentation about node_id generation for Home Assistant MQTT Service Discovery

* add Prometheus/OpenMetrics exporter (#3081)

* add prometheus endpoint

* refine metrics implementation

* move metrics generator to ClassFlowControll

* add more metrics
align prefix

* add more metrics
clean up

* refine documentation

* revert dependencies change

* sanitize labels

* create separate module for openmetrics

* move openmetrics to separate folder

* clean up

* add basic unit-tests

* work with const numbers
add replaceAll for string replacement
avoid opening std namespace
adapt unit-tests

* Update code/main/server_main.cpp

---------

Co-authored-by: CaCO3 <caco3@ruinelli.ch>

* Typo

* update platformIO to 6.7.0 (ESP IDF 5.2.1) (#3098)

* update to platformio/espressif32 @ 6.7.0

* remove unused getReadout() as it throws errors (error: 'virtual std::string ClassFlow::getReadout()' was hidden).

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* Update reply-bot.yaml (#3107)

* Fix actions-label-commenter

* Update Helper.cpp

* Update Helper.h

* Update Helper.cpp

* Update readconfigparam.js

fix for:
In the selected field the value '1' in the section 'TakeImage' in the field 'CamGainceiling' is invalid. PLEASE CHECK BEFORE SAVING!

* proposal for renaming and documentation (#3115)

* Update server_camera.cpp

 Fix building with -D DEBUG_DETAIL_ON 

better alternative to:
https://github.com/jomjol/AI-on-the-edge-device/pull/3160

* Update ClassFlowPostProcessing.cpp

* Update ClassFlowAlignment.cpp

* Fix building with `-D DEBUG_DETAIL_ON` (#3160)

Building with `-D DEBUG_DETAIL_ON` has been broken since #3029.

Co-authored-by: CaCO3 <caco3@ruinelli.ch>

* Handle empty prevalue.ini gracefully (#3162)

Fixes #2149.

* Bugfix for boot loop (#3175)

* Add files via upload

* Add files via upload

* Add files via upload

* Delete param-docs/parameter-pages/TakeImage/Aec2.md

has been replaced by CamAec2.md

* Delete param-docs/parameter-pages/TakeImage/AutoExposureLevel.md

has been replaced by CamAeLevel.md

* Delete param-docs/parameter-pages/TakeImage/Brightness.md

has been replaced by CamBrightness.md

* Delete param-docs/parameter-pages/TakeImage/Contrast.md

has been replaced by CamContrast.md

* Delete param-docs/parameter-pages/TakeImage/Grayscale.md

has been replaced by CamSpecialEffect.md

* Delete param-docs/parameter-pages/TakeImage/Negative.md

has been replaced by CamSpecialEffect.md

* Delete param-docs/parameter-pages/TakeImage/Saturation.md

has been replaced by CamSaturation.md

* Delete param-docs/parameter-pages/TakeImage/Sharpness.md

has been replaced by CamSharpness.md

* Delete param-docs/parameter-pages/TakeImage/ImageQuality.md

has been replaced by CamQuality.md

* Delete param-docs/parameter-pages/TakeImage/Zoom.md

has been replaced by CamZoom.md

* Delete param-docs/parameter-pages/TakeImage/ZoomMode.md

has been replaced by CamZoomSize.md

* Delete param-docs/parameter-pages/TakeImage/ZoomOffsetX.md

has been replaced by CamZoomOffsetX.md

* Delete param-docs/parameter-pages/TakeImage/ZoomOffsetY.md

has been replaced by CamZoomOffsetY.md

* Delete param-docs/parameter-pages/TakeImage/ImageSize.md

has been replaced by CamZoomSize.md

* Delete param-docs/parameter-pages/TakeImage/FixedExposure.md

has been replaced by CamAec.md

* Delete param-docs/parameter-pages/Alignment/FlipImageSize.md

has been replaced by CamVflip.md

* Delete param-docs/parameter-pages/Alignment/InitialMirror.md

has been replaced by CamHmirror.md

* CamParameter documentation update

https://github.com/jomjol/AI-on-the-edge-device/issues/3185

* typo

* add Webhook #3148 (#3163)

* WIP add Webhook

* fix config html for webhook
add tooltips for webhook

* webhook: fix not enabling webhook

* send webhook as json

* Update ApiKey.md

* webhook: fix only sending last "Number"

* webhook JSON is now closer to the data log in CSV format

* webhook: drop timeStampTimeUTC and switch from timeStamp to lastvalue like lokal csv to fix no timestamp on error

---------

Co-authored-by: CaCO3 <caco3@ruinelli.ch>

* Bugfix for time stamp (#3180)

* Update ClassFlowPostProcessing.cpp

* Update ClassFlowDefineTypes.h

* Update ClassFlowPostProcessing.cpp

* Update ClassFlowPostProcessing.cpp

* Update ClassFlowPostProcessing.cpp

* Update ClassFlowPostProcessing.cpp

* Update interface_webhook.cpp

* Update readconfigcommon.js

fix for: The same message("Image Contrast got enhanced") came up with "Update Marker" and "Enhance Image Contrast".

* fix svg favicon 

The svg one got added in 33893eb566 but does not work on Firefox

* Update platformIO to 6.8.1 (Contains ESP IDF 5.3) (#3196)

* Update platformIO to 6.8.1 (ESP IDF 5.3)

* removed now redundant typedef

* updated IDF manifest hash

* Add files via upload

so it should work now

* Update server_main.cpp

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>
Co-authored-by: michael <Heinrich-Tuning@web.de>

* Update MainFlowControl.cpp

* Add support for OV5640 camera (#3063)

* Add support for OV5640 camera

* clean up sharpness handling

* limit sharpness range to -2 and +2

* refactor

* Fix OV3660 sharpness handling

* refactor sharpness handling

* fix OV3660 zoom mode

* reinstate aspect ratio via imageSize

* Changed OV5640 full frame size to match datasheet

* various fixes

* add denoise config and general clean up

* fix line endings to LF

* Support enabling red blue swap via web interface

* update jpeg quality limits

* remove color swap config; color swap workaround dependent on vflip

* fix missing commit

* fix gain ceiling

* Update cam vflip param page

* fix typo: camdenoise, not camsdenoise

* fix compile errors

* Update MainFlowControl.cpp

* Add rate threshold parameter (#3195)

* still needs to be tested

https://github.com/jomjol/AI-on-the-edge-device/issues/3143

* Update ClassFlowPostProcessing.cpp

code formatting

* Update ClassFlowDefineTypes.h

code formatting

* Update ClassFlowPostProcessing.h

code formatting

* Update edit_config_template.html

* fix

* Update config.ini

* Update edit_config_template.html

* Updated param doc

* Rename parameters

* Update edit_config_template.html

* Update NUMBER.ChangeRateThreshold.md

* Update NUMBER.ChangeRateThreshold.md

---------

Co-authored-by: CaCO3 <caco3@ruinelli.ch>

* Update main.cpp

* Update config.ini

Adjusted camera settings to make the image brighter.

* Update readconfigparam.js

Adjusted camera settings to make the image brighter.

* add optional ImageUpload for Webhook (#3174)

* WIP add Webhook

* fix config html for webhook
add tooltips for webhook

* webhook: fix not enabling webhook

* send webhook as json

* Update ApiKey.md

* webhook: fix only sending last "Number"

* webhook JSON is now closer to the data log in CSV format

* webhook: add img upload

* webhoop added config for imgupload

* webhook html fixes

* webhook: drop timeStampTimeUTC and switch from timeStamp to lastvalue like lokal csv to fix no timestamp on error

* add checkbox for Webhook_UploadImg

* Update sd-card/html/edit_config_template.html

* Update edit_config_template.html

* Update edit_config_template.html

* Update edit_config_template.html

* added a long timestamp to both webhook requests

---------

Co-authored-by: CaCO3 <caco3@ruinelli.ch>

* Add files via upload (#3207)

* Update ClassFlowPostProcessing.cpp

deleted some unnecessary double entries
RateType renamed to MaxRateType

* Update ClassFlowDefineTypes.h

RateType renamed to MaxRateType

* Update text on recognition page

* Update digital CNN

* add a Delay between the WiFi reconnections (#3068)

* add a Delay between the WiFi reconnections

* log the delay between the WiFi reconnections

move the delay after the log

* cleanup

* cleanup

* cleanup

* Update edit_alignment.html

* cleanup

* cleanup

* Update platformIO to 6.9.0 (Contains ESP IDF 5.3.1)

* Handle crash on corrupted model (#3220)

* Upgrade esp-tflite-micro to 1.3.1

* Added log message to hint in case it crashes on loading a corrupted model

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* new dig-class100-173-s2-q on 23.800 images (#3257)

* new dig-class100-173-s2-q on 23.800 images

* platformio/espressif32 @ 6.8.1 for esp32cam-dev

* Revert "platformio/espressif32 @ 6.8.1 for esp32cam-dev"

This reverts commit cc9297d483.

* not using platformio 6.1.16

* Revert "not using platformio 6.1.16"

This reverts commit ef18e4fae7.

* moved number edit box styles into new file edit_style.css (#3262)

changed input[type=number] from 60px to 3em, to show 3 digits with current font size.

* added note about only TLS 1.2 is supported (#3213)

* Renamed digital to digit (#3219)

* renamed Digital to Digit

* added param migration

* Update .github/label-commenter-config.yaml

* renamed AnalogDigitTransition* to AnalogToDigitTransition*

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* Update Changelog.md

* Update Changelog.md

* Prepare next release (#3267) (#3270)

* Create dig-cont_0640_s3_q.tflite

* Update edit_reference.html (#2924)

Zoom-Einstellungen ausblenden, wenn zoom deaktiviert ist

* Update edit_config_template.html (#2925)

Zoom-Einstellungen ausblenden, wenn zoom deaktiviert ist +
Kameraeinstellungen nicht nur in der config.ini speichern, sondern auch setzen

* The parameter "negative" is processed on the MCU

* Renamed menu entry Alignment -> References

* renamed model file to make naming consistent

* Fix test (#2933)

* always reset change absolute (#2956)

* Create dig-class11_1701_s2.tflite

* Update tflite

* Update tflite

* 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

* Fix minor typo and harmonize spaces (#3030)

* Update edit_digits.html

* Update edit_analog.html

* Update overview.html

* Update edit_reference.html

---------



* Source code formatting, ClassFlowPostProcessing.cpp

* fix edit_config_template.html

Unfortunately, I didn't take out some entries from other experiments because I overlooked/forgot them^^

* fix readconfigparam.js

Unfortunately, I didn't take out some entries from other experiments because I overlooked/forgot them^^

* fix edit_config_template.html

TakeImage_CamZoomMode_value1 was replaced by TakeImage_CamZoomSize_value1, but not deleted.
This caused problems when saving the camera settings.

* Update info.html

function loadWLANSSID() was present three times

* Update overview.html

CamFrameSize is no longer needed/used for zoom

* Update reply-bot.yaml

* homeassistant service discovery: derive node_id when using nested topics (#3088)

* derive correct node_id for homeassistant service discovery in nested topics (fixes #1792)

* explicit use of std::string

* move nodeId creation to separate function
add unit-tests

* add documentation about node_id generation for Home Assistant MQTT Service Discovery

* add Prometheus/OpenMetrics exporter (#3081)

* add prometheus endpoint

* refine metrics implementation

* move metrics generator to ClassFlowControll

* add more metrics
align prefix

* add more metrics
clean up

* refine documentation

* revert dependencies change

* sanitize labels

* create separate module for openmetrics

* move openmetrics to separate folder

* clean up

* add basic unit-tests

* work with const numbers
add replaceAll for string replacement
avoid opening std namespace
adapt unit-tests

* Update code/main/server_main.cpp

---------



* Typo

* update platformIO to 6.7.0 (ESP IDF 5.2.1) (#3098)

* update to platformio/espressif32 @ 6.7.0

* remove unused getReadout() as it throws errors (error: 'virtual std::string ClassFlow::getReadout()' was hidden).

---------



* Update reply-bot.yaml (#3107)

* Fix actions-label-commenter

* Update Helper.cpp

* Update Helper.h

* Update Helper.cpp

* Update readconfigparam.js

fix for:
In the selected field the value '1' in the section 'TakeImage' in the field 'CamGainceiling' is invalid. PLEASE CHECK BEFORE SAVING!

* proposal for renaming and documentation (#3115)

* Update server_camera.cpp

 Fix building with -D DEBUG_DETAIL_ON 

better alternative to:
https://github.com/jomjol/AI-on-the-edge-device/pull/3160

* Update ClassFlowPostProcessing.cpp

* Update ClassFlowAlignment.cpp

* Fix building with `-D DEBUG_DETAIL_ON` (#3160)

Building with `-D DEBUG_DETAIL_ON` has been broken since #3029.



* Handle empty prevalue.ini gracefully (#3162)

Fixes #2149.

* Bugfix for boot loop (#3175)

* Add files via upload

* Add files via upload

* Add files via upload

* Delete param-docs/parameter-pages/TakeImage/Aec2.md

has been replaced by CamAec2.md

* Delete param-docs/parameter-pages/TakeImage/AutoExposureLevel.md

has been replaced by CamAeLevel.md

* Delete param-docs/parameter-pages/TakeImage/Brightness.md

has been replaced by CamBrightness.md

* Delete param-docs/parameter-pages/TakeImage/Contrast.md

has been replaced by CamContrast.md

* Delete param-docs/parameter-pages/TakeImage/Grayscale.md

has been replaced by CamSpecialEffect.md

* Delete param-docs/parameter-pages/TakeImage/Negative.md

has been replaced by CamSpecialEffect.md

* Delete param-docs/parameter-pages/TakeImage/Saturation.md

has been replaced by CamSaturation.md

* Delete param-docs/parameter-pages/TakeImage/Sharpness.md

has been replaced by CamSharpness.md

* Delete param-docs/parameter-pages/TakeImage/ImageQuality.md

has been replaced by CamQuality.md

* Delete param-docs/parameter-pages/TakeImage/Zoom.md

has been replaced by CamZoom.md

* Delete param-docs/parameter-pages/TakeImage/ZoomMode.md

has been replaced by CamZoomSize.md

* Delete param-docs/parameter-pages/TakeImage/ZoomOffsetX.md

has been replaced by CamZoomOffsetX.md

* Delete param-docs/parameter-pages/TakeImage/ZoomOffsetY.md

has been replaced by CamZoomOffsetY.md

* Delete param-docs/parameter-pages/TakeImage/ImageSize.md

has been replaced by CamZoomSize.md

* Delete param-docs/parameter-pages/TakeImage/FixedExposure.md

has been replaced by CamAec.md

* Delete param-docs/parameter-pages/Alignment/FlipImageSize.md

has been replaced by CamVflip.md

* Delete param-docs/parameter-pages/Alignment/InitialMirror.md

has been replaced by CamHmirror.md

* CamParameter documentation update

https://github.com/jomjol/AI-on-the-edge-device/issues/3185

* typo

* add Webhook #3148 (#3163)

* WIP add Webhook

* fix config html for webhook
add tooltips for webhook

* webhook: fix not enabling webhook

* send webhook as json

* Update ApiKey.md

* webhook: fix only sending last "Number"

* webhook JSON is now closer to the data log in CSV format

* webhook: drop timeStampTimeUTC and switch from timeStamp to lastvalue like lokal csv to fix no timestamp on error

---------



* Bugfix for time stamp (#3180)

* Update ClassFlowPostProcessing.cpp

* Update ClassFlowDefineTypes.h

* Update ClassFlowPostProcessing.cpp

* Update ClassFlowPostProcessing.cpp

* Update ClassFlowPostProcessing.cpp

* Update ClassFlowPostProcessing.cpp

* Update interface_webhook.cpp

* Update readconfigcommon.js

fix for: The same message("Image Contrast got enhanced") came up with "Update Marker" and "Enhance Image Contrast".

* fix svg favicon 

The svg one got added in 33893eb566 but does not work on Firefox

* Update platformIO to 6.8.1 (Contains ESP IDF 5.3) (#3196)

* Update platformIO to 6.8.1 (ESP IDF 5.3)

* removed now redundant typedef

* updated IDF manifest hash

* Add files via upload

so it should work now

* Update server_main.cpp

---------




* Update MainFlowControl.cpp

* Add support for OV5640 camera (#3063)

* Add support for OV5640 camera

* clean up sharpness handling

* limit sharpness range to -2 and +2

* refactor

* Fix OV3660 sharpness handling

* refactor sharpness handling

* fix OV3660 zoom mode

* reinstate aspect ratio via imageSize

* Changed OV5640 full frame size to match datasheet

* various fixes

* add denoise config and general clean up

* fix line endings to LF

* Support enabling red blue swap via web interface

* update jpeg quality limits

* remove color swap config; color swap workaround dependent on vflip

* fix missing commit

* fix gain ceiling

* Update cam vflip param page

* fix typo: camdenoise, not camsdenoise

* fix compile errors

* Update MainFlowControl.cpp

* Add rate threshold parameter (#3195)

* still needs to be tested

https://github.com/jomjol/AI-on-the-edge-device/issues/3143

* Update ClassFlowPostProcessing.cpp

code formatting

* Update ClassFlowDefineTypes.h

code formatting

* Update ClassFlowPostProcessing.h

code formatting

* Update edit_config_template.html

* fix

* Update config.ini

* Update edit_config_template.html

* Updated param doc

* Rename parameters

* Update edit_config_template.html

* Update NUMBER.ChangeRateThreshold.md

* Update NUMBER.ChangeRateThreshold.md

---------



* Update main.cpp

* Update config.ini

Adjusted camera settings to make the image brighter.

* Update readconfigparam.js

Adjusted camera settings to make the image brighter.

* add optional ImageUpload for Webhook (#3174)

* WIP add Webhook

* fix config html for webhook
add tooltips for webhook

* webhook: fix not enabling webhook

* send webhook as json

* Update ApiKey.md

* webhook: fix only sending last "Number"

* webhook JSON is now closer to the data log in CSV format

* webhook: add img upload

* webhoop added config for imgupload

* webhook html fixes

* webhook: drop timeStampTimeUTC and switch from timeStamp to lastvalue like lokal csv to fix no timestamp on error

* add checkbox for Webhook_UploadImg

* Update sd-card/html/edit_config_template.html

* Update edit_config_template.html

* Update edit_config_template.html

* Update edit_config_template.html

* added a long timestamp to both webhook requests

---------



* Add files via upload (#3207)

* Update ClassFlowPostProcessing.cpp

deleted some unnecessary double entries
RateType renamed to MaxRateType

* Update ClassFlowDefineTypes.h

RateType renamed to MaxRateType

* Update text on recognition page

* Update digital CNN

* add a Delay between the WiFi reconnections (#3068)

* add a Delay between the WiFi reconnections

* log the delay between the WiFi reconnections

move the delay after the log

* cleanup

* cleanup

* cleanup

* Update edit_alignment.html

* cleanup

* cleanup

* Update platformIO to 6.9.0 (Contains ESP IDF 5.3.1)

* Handle crash on corrupted model (#3220)

* Upgrade esp-tflite-micro to 1.3.1

* Added log message to hint in case it crashes on loading a corrupted model

---------



* new dig-class100-173-s2-q on 23.800 images (#3257)

* new dig-class100-173-s2-q on 23.800 images

* platformio/espressif32 @ 6.8.1 for esp32cam-dev

* Revert "platformio/espressif32 @ 6.8.1 for esp32cam-dev"

This reverts commit cc9297d483.

* not using platformio 6.1.16

* Revert "not using platformio 6.1.16"

This reverts commit ef18e4fae7.

* moved number edit box styles into new file edit_style.css (#3262)

changed input[type=number] from 60px to 3em, to show 3 digits with current font size.

* added note about only TLS 1.2 is supported (#3213)

* Renamed digital to digit (#3219)

* renamed Digital to Digit

* added param migration

* Update .github/label-commenter-config.yaml

* renamed AnalogDigitTransition* to AnalogToDigitTransition*

---------



* Update Changelog.md

* Update Changelog.md

---------

Co-authored-by: jomjol <30766535+jomjol@users.noreply.github.com>
Co-authored-by: michael <Heinrich-Tuning@web.de>
Co-authored-by: Frank Haverland <fspapaping@googlemail.com>
Co-authored-by: kub3let <95883234+kub3let@users.noreply.github.com>
Co-authored-by: Marco H <myxor@users.noreply.github.com>
Co-authored-by: Henry Thasler <henrythasler@users.noreply.github.com>
Co-authored-by: CaCO3 <caco@ruinelli.ch>
Co-authored-by: Sebastian Lövdahl <slovdahl@hibox.fi>
Co-authored-by: Raphael Hehl <raphael@rhehl.de>
Co-authored-by: jasaw <jasaw@dius.com.au>
Co-authored-by: Francesco Carnielli <hex7c0@gmail.com>
Co-authored-by: kalwados <kalwados@gmx.de>

* revert TFlite submodule update as certain modules crash with it, see https://github.com/jomjol/AI-on-the-edge-device/issues/3269

* Rename NUMBER.AnalogDigitTransitionStart.md to NUMBER.AnalogToDigitTransitionStart.md

* Update NUMBER.AnalogToDigitTransitionStart.md

* Update edit_config_template.html

* changed the webhook UploadImg to false

* changed the webhook UploadImg to false (#3279)

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* Show boolean option in settings page (#3285)

* changed the webhook UploadImg to false

* show boolean value on boolean drop down boxes

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* changed default value from boolean to numeric value in parameter camDenoise documentation

* Update edit_explain_7.html

https://github.com/jomjol/AI-on-the-edge-device/issues/3284?notification_referrer_id=NT_kwDOAAj1wbIxMjY3MDI1Njk3MDo1ODcyMDE#issuecomment-2387102786

* docs: update README.md (#3290)

prefered -> preferred

* rename/remove unused parameters (#3291)

* migrate-cam-parameters (#3288)

* Update main.cpp

* remove commented out code

---------

Co-authored-by: CaCO3 <caco3@ruinelli.ch>

* Update Changelog.md

* cleanup

---------

Co-authored-by: jomjol <30766535+jomjol@users.noreply.github.com>
Co-authored-by: michael <Heinrich-Tuning@web.de>
Co-authored-by: Frank Haverland <fspapaping@googlemail.com>
Co-authored-by: kub3let <95883234+kub3let@users.noreply.github.com>
Co-authored-by: Marco H <myxor@users.noreply.github.com>
Co-authored-by: Henry Thasler <henrythasler@users.noreply.github.com>
Co-authored-by: CaCO3 <caco@ruinelli.ch>
Co-authored-by: Sebastian Lövdahl <slovdahl@hibox.fi>
Co-authored-by: Raphael Hehl <raphael@rhehl.de>
Co-authored-by: jasaw <jasaw@dius.com.au>
Co-authored-by: Francesco Carnielli <hex7c0@gmail.com>
Co-authored-by: kalwados <kalwados@gmx.de>
Co-authored-by: Ikko Eltociear Ashimine <eltociear@gmail.com>
2024-10-04 22:05:15 +02:00
CaCO3
ca01f5a38f Prepare next release (#3267)
* Create dig-cont_0640_s3_q.tflite

* Update edit_reference.html (#2924)

Zoom-Einstellungen ausblenden, wenn zoom deaktiviert ist

* Update edit_config_template.html (#2925)

Zoom-Einstellungen ausblenden, wenn zoom deaktiviert ist +
Kameraeinstellungen nicht nur in der config.ini speichern, sondern auch setzen

* The parameter "negative" is processed on the MCU

* Renamed menu entry Alignment -> References

* renamed model file to make naming consistent

* Fix test (#2933)

* always reset change absolute (#2956)

* Create dig-class11_1701_s2.tflite

* Update tflite

* Update tflite

* 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

* Fix minor typo and harmonize spaces (#3030)

* Update edit_digits.html

* Update edit_analog.html

* Update overview.html

* Update edit_reference.html

---------

Co-authored-by: jomjol <30766535+jomjol@users.noreply.github.com>

* Source code formatting, ClassFlowPostProcessing.cpp

* fix edit_config_template.html

Unfortunately, I didn't take out some entries from other experiments because I overlooked/forgot them^^

* fix readconfigparam.js

Unfortunately, I didn't take out some entries from other experiments because I overlooked/forgot them^^

* fix edit_config_template.html

TakeImage_CamZoomMode_value1 was replaced by TakeImage_CamZoomSize_value1, but not deleted.
This caused problems when saving the camera settings.

* Update info.html

function loadWLANSSID() was present three times

* Update overview.html

CamFrameSize is no longer needed/used for zoom

* Update reply-bot.yaml

* homeassistant service discovery: derive node_id when using nested topics (#3088)

* derive correct node_id for homeassistant service discovery in nested topics (fixes #1792)

* explicit use of std::string

* move nodeId creation to separate function
add unit-tests

* add documentation about node_id generation for Home Assistant MQTT Service Discovery

* add Prometheus/OpenMetrics exporter (#3081)

* add prometheus endpoint

* refine metrics implementation

* move metrics generator to ClassFlowControll

* add more metrics
align prefix

* add more metrics
clean up

* refine documentation

* revert dependencies change

* sanitize labels

* create separate module for openmetrics

* move openmetrics to separate folder

* clean up

* add basic unit-tests

* work with const numbers
add replaceAll for string replacement
avoid opening std namespace
adapt unit-tests

* Update code/main/server_main.cpp

---------

Co-authored-by: CaCO3 <caco3@ruinelli.ch>

* Typo

* update platformIO to 6.7.0 (ESP IDF 5.2.1) (#3098)

* update to platformio/espressif32 @ 6.7.0

* remove unused getReadout() as it throws errors (error: 'virtual std::string ClassFlow::getReadout()' was hidden).

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* Update reply-bot.yaml (#3107)

* Fix actions-label-commenter

* Update Helper.cpp

* Update Helper.h

* Update Helper.cpp

* Update readconfigparam.js

fix for:
In the selected field the value '1' in the section 'TakeImage' in the field 'CamGainceiling' is invalid. PLEASE CHECK BEFORE SAVING!

* proposal for renaming and documentation (#3115)

* Update server_camera.cpp

 Fix building with -D DEBUG_DETAIL_ON 

better alternative to:
https://github.com/jomjol/AI-on-the-edge-device/pull/3160

* Update ClassFlowPostProcessing.cpp

* Update ClassFlowAlignment.cpp

* Fix building with `-D DEBUG_DETAIL_ON` (#3160)

Building with `-D DEBUG_DETAIL_ON` has been broken since #3029.

Co-authored-by: CaCO3 <caco3@ruinelli.ch>

* Handle empty prevalue.ini gracefully (#3162)

Fixes #2149.

* Bugfix for boot loop (#3175)

* Add files via upload

* Add files via upload

* Add files via upload

* Delete param-docs/parameter-pages/TakeImage/Aec2.md

has been replaced by CamAec2.md

* Delete param-docs/parameter-pages/TakeImage/AutoExposureLevel.md

has been replaced by CamAeLevel.md

* Delete param-docs/parameter-pages/TakeImage/Brightness.md

has been replaced by CamBrightness.md

* Delete param-docs/parameter-pages/TakeImage/Contrast.md

has been replaced by CamContrast.md

* Delete param-docs/parameter-pages/TakeImage/Grayscale.md

has been replaced by CamSpecialEffect.md

* Delete param-docs/parameter-pages/TakeImage/Negative.md

has been replaced by CamSpecialEffect.md

* Delete param-docs/parameter-pages/TakeImage/Saturation.md

has been replaced by CamSaturation.md

* Delete param-docs/parameter-pages/TakeImage/Sharpness.md

has been replaced by CamSharpness.md

* Delete param-docs/parameter-pages/TakeImage/ImageQuality.md

has been replaced by CamQuality.md

* Delete param-docs/parameter-pages/TakeImage/Zoom.md

has been replaced by CamZoom.md

* Delete param-docs/parameter-pages/TakeImage/ZoomMode.md

has been replaced by CamZoomSize.md

* Delete param-docs/parameter-pages/TakeImage/ZoomOffsetX.md

has been replaced by CamZoomOffsetX.md

* Delete param-docs/parameter-pages/TakeImage/ZoomOffsetY.md

has been replaced by CamZoomOffsetY.md

* Delete param-docs/parameter-pages/TakeImage/ImageSize.md

has been replaced by CamZoomSize.md

* Delete param-docs/parameter-pages/TakeImage/FixedExposure.md

has been replaced by CamAec.md

* Delete param-docs/parameter-pages/Alignment/FlipImageSize.md

has been replaced by CamVflip.md

* Delete param-docs/parameter-pages/Alignment/InitialMirror.md

has been replaced by CamHmirror.md

* CamParameter documentation update

https://github.com/jomjol/AI-on-the-edge-device/issues/3185

* typo

* add Webhook #3148 (#3163)

* WIP add Webhook

* fix config html for webhook
add tooltips for webhook

* webhook: fix not enabling webhook

* send webhook as json

* Update ApiKey.md

* webhook: fix only sending last "Number"

* webhook JSON is now closer to the data log in CSV format

* webhook: drop timeStampTimeUTC and switch from timeStamp to lastvalue like lokal csv to fix no timestamp on error

---------

Co-authored-by: CaCO3 <caco3@ruinelli.ch>

* Bugfix for time stamp (#3180)

* Update ClassFlowPostProcessing.cpp

* Update ClassFlowDefineTypes.h

* Update ClassFlowPostProcessing.cpp

* Update ClassFlowPostProcessing.cpp

* Update ClassFlowPostProcessing.cpp

* Update ClassFlowPostProcessing.cpp

* Update interface_webhook.cpp

* Update readconfigcommon.js

fix for: The same message("Image Contrast got enhanced") came up with "Update Marker" and "Enhance Image Contrast".

* fix svg favicon 

The svg one got added in 33893eb566 but does not work on Firefox

* Update platformIO to 6.8.1 (Contains ESP IDF 5.3) (#3196)

* Update platformIO to 6.8.1 (ESP IDF 5.3)

* removed now redundant typedef

* updated IDF manifest hash

* Add files via upload

so it should work now

* Update server_main.cpp

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>
Co-authored-by: michael <Heinrich-Tuning@web.de>

* Update MainFlowControl.cpp

* Add support for OV5640 camera (#3063)

* Add support for OV5640 camera

* clean up sharpness handling

* limit sharpness range to -2 and +2

* refactor

* Fix OV3660 sharpness handling

* refactor sharpness handling

* fix OV3660 zoom mode

* reinstate aspect ratio via imageSize

* Changed OV5640 full frame size to match datasheet

* various fixes

* add denoise config and general clean up

* fix line endings to LF

* Support enabling red blue swap via web interface

* update jpeg quality limits

* remove color swap config; color swap workaround dependent on vflip

* fix missing commit

* fix gain ceiling

* Update cam vflip param page

* fix typo: camdenoise, not camsdenoise

* fix compile errors

* Update MainFlowControl.cpp

* Add rate threshold parameter (#3195)

* still needs to be tested

https://github.com/jomjol/AI-on-the-edge-device/issues/3143

* Update ClassFlowPostProcessing.cpp

code formatting

* Update ClassFlowDefineTypes.h

code formatting

* Update ClassFlowPostProcessing.h

code formatting

* Update edit_config_template.html

* fix

* Update config.ini

* Update edit_config_template.html

* Updated param doc

* Rename parameters

* Update edit_config_template.html

* Update NUMBER.ChangeRateThreshold.md

* Update NUMBER.ChangeRateThreshold.md

---------

Co-authored-by: CaCO3 <caco3@ruinelli.ch>

* Update main.cpp

* Update config.ini

Adjusted camera settings to make the image brighter.

* Update readconfigparam.js

Adjusted camera settings to make the image brighter.

* add optional ImageUpload for Webhook (#3174)

* WIP add Webhook

* fix config html for webhook
add tooltips for webhook

* webhook: fix not enabling webhook

* send webhook as json

* Update ApiKey.md

* webhook: fix only sending last "Number"

* webhook JSON is now closer to the data log in CSV format

* webhook: add img upload

* webhoop added config for imgupload

* webhook html fixes

* webhook: drop timeStampTimeUTC and switch from timeStamp to lastvalue like lokal csv to fix no timestamp on error

* add checkbox for Webhook_UploadImg

* Update sd-card/html/edit_config_template.html

* Update edit_config_template.html

* Update edit_config_template.html

* Update edit_config_template.html

* added a long timestamp to both webhook requests

---------

Co-authored-by: CaCO3 <caco3@ruinelli.ch>

* Add files via upload (#3207)

* Update ClassFlowPostProcessing.cpp

deleted some unnecessary double entries
RateType renamed to MaxRateType

* Update ClassFlowDefineTypes.h

RateType renamed to MaxRateType

* Update text on recognition page

* Update digital CNN

* add a Delay between the WiFi reconnections (#3068)

* add a Delay between the WiFi reconnections

* log the delay between the WiFi reconnections

move the delay after the log

* cleanup

* cleanup

* cleanup

* Update edit_alignment.html

* cleanup

* cleanup

* Update platformIO to 6.9.0 (Contains ESP IDF 5.3.1)

* Handle crash on corrupted model (#3220)

* Upgrade esp-tflite-micro to 1.3.1

* Added log message to hint in case it crashes on loading a corrupted model

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* new dig-class100-173-s2-q on 23.800 images (#3257)

* new dig-class100-173-s2-q on 23.800 images

* platformio/espressif32 @ 6.8.1 for esp32cam-dev

* Revert "platformio/espressif32 @ 6.8.1 for esp32cam-dev"

This reverts commit cc9297d483.

* not using platformio 6.1.16

* Revert "not using platformio 6.1.16"

This reverts commit ef18e4fae7.

* moved number edit box styles into new file edit_style.css (#3262)

changed input[type=number] from 60px to 3em, to show 3 digits with current font size.

* added note about only TLS 1.2 is supported (#3213)

* Renamed digital to digit (#3219)

* renamed Digital to Digit

* added param migration

* Update .github/label-commenter-config.yaml

* renamed AnalogDigitTransition* to AnalogToDigitTransition*

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* Update Changelog.md

* Update Changelog.md

---------

Co-authored-by: jomjol <30766535+jomjol@users.noreply.github.com>
Co-authored-by: michael <Heinrich-Tuning@web.de>
Co-authored-by: Frank Haverland <fspapaping@googlemail.com>
Co-authored-by: kub3let <95883234+kub3let@users.noreply.github.com>
Co-authored-by: Marco H <myxor@users.noreply.github.com>
Co-authored-by: Henry Thasler <henrythasler@users.noreply.github.com>
Co-authored-by: CaCO3 <caco@ruinelli.ch>
Co-authored-by: Sebastian Lövdahl <slovdahl@hibox.fi>
Co-authored-by: Raphael Hehl <raphael@rhehl.de>
Co-authored-by: jasaw <jasaw@dius.com.au>
Co-authored-by: Francesco Carnielli <hex7c0@gmail.com>
Co-authored-by: kalwados <kalwados@gmx.de>
2024-09-29 23:22:33 +02:00
CaCO3
0d0b0187f4 Update index.html 2024-02-17 01:13:17 +01:00
CaCO3
4cf9ea6c45 updated changelog 2024-02-17 00:51:10 +01:00
CaCO3
1b76e0f449 restructure menu 2024-02-17 00:50:41 +01:00
CaCO3
d4a0ad20ff Restructure menus (#2921)
* renamed config pages
* restructured menu
2024-02-17 00:40:46 +01:00
CaCO3
df72445e79 show note a bit longer 2024-02-16 22:45:32 +01:00
CaCO3
456cb93809 Update reply-bot.yaml 2024-02-16 22:36:16 +01:00
CaCO3
d968a7adc6 Update reply-bot.yaml 2024-02-16 22:33:38 +01:00
CaCO3
9a52b8b2f3 Update reply-bot.yaml 2024-02-16 22:30:15 +01:00
CaCO3
8caa852bbf Update info.html 2024-02-16 22:27:00 +01:00
michael
4faca4c46c Update edit_reference.html (#2914)
On the ref image page, when a cam setting gets changed, disable the save button to enforce creating a new image first
2024-02-16 22:16:38 +01:00
michael
238fc5fae3 Update edit_config_param_template.html (#2915)
Show Warning when changing camera settings in edit config param
2024-02-16 22:13:09 +01:00
CaCO3
c32ca5a23c the yaml files must have the file extention yaml. If they are called yml, they are threated slightly different in the actions section 2024-02-16 00:03:24 +01:00
CaCO3
827d9d1700 updated param doc: added note that the ref image and alignment marks need to be updated as well (#2916)
param-doc: added note that the ref image and alignment marks need to be updated as well
2024-02-15 23:49:14 +01:00
CaCO3
0ea4b3b3ce Update Changelog.md 2024-02-15 23:28:50 +01:00
CaCO3
3e26c6c743 restructured ROI pages 2024-02-15 22:16:18 +01:00
michael
fa5c99b3cb Button to hide other red Digit Frames (#2907)
Button to hide other red Digit Frames for easier setup, implements #2680
2024-02-15 21:55:01 +01:00
CaCO3
6feae4e239 Use valid default values 2024-02-15 00:12:37 +01:00
CaCO3
ef64be3888 Enhance ref image page (#2910)
Enhanced Reference Image page
2024-02-14 23:49:35 +01:00
CaCO3
cc89d625f2 Enhance ref image page2 (#2908)
minor fixes
2024-02-14 21:02:08 +01:00
CaCO3
08ba754b88 Restructure reference image page (#2905) 2024-02-14 16:54:31 +01:00
michael
6b38e44d7f Loading alignment page faster (#2868)
Da es Probleme mit param_temp gab (mal ging es, mal nicht), habe ich extra Parameter angelegt (_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).
Bei den bisherigen Tests, hat alles so funktioniert wie es soll.
2024-02-14 16:24:29 +01:00
CaCO3
141aea7fa7 Revert "Implemented late analog / digital transition (#2778)"
This reverts commit b5a4cfed96.
2024-02-12 22:41:56 +01:00
CaCO3
bcd07761b6 . 2024-02-12 22:37:46 +01:00
CaCO3
fe4d861e15 . 2024-02-12 22:37:46 +01:00
CaCO3
71322c9fbe fixed review findings 2024-02-12 22:37:46 +01:00
CaCO3
f8b4881a50 . 2024-02-12 22:37:46 +01:00
CaCO3
438d5696e4 . 2024-02-12 22:37:46 +01:00
CaCO3
0d391c8780 . 2024-02-12 22:37:46 +01:00
CaCO3
59de6319a1 . 2024-02-12 22:37:46 +01:00
CaCO3
3805687219 . 2024-02-12 22:37:46 +01:00
CaCO3
c6a789dc45 . 2024-02-12 22:37:46 +01:00
CaCO3
246f9cfc31 . 2024-02-12 22:37:46 +01:00
CaCO3
b2d8c60bb1 . 2024-02-12 22:37:46 +01:00
CaCO3
1d573cd18a . 2024-02-12 22:37:46 +01:00
CaCO3
b2e5cdd8a3 . 2024-02-12 22:37:46 +01:00
CaCO3
f7fde7c430 . 2024-02-12 22:37:46 +01:00
CaCO3
2c19080a66 . 2024-02-12 22:37:46 +01:00
CaCO3
35663c5fd4 add tooltip css 2024-02-12 22:37:46 +01:00
CaCO3
5b449d5c45 update param doc 2024-02-12 22:37:46 +01:00
CaCO3
3a5f3496d5 fix typo in variable name 2024-02-12 22:37:46 +01:00
CaCO3
00434d01c3 update action 2024-02-12 22:37:46 +01:00
CaCO3
3e0bb81e32 added tooltips to reference image page 2024-02-12 22:37:46 +01:00
CaCO3
4f57f9eafd add spacing 2024-02-12 22:37:46 +01:00
CaCO3
f24ec581e6 Added FixedExposure to reference image page 2024-02-12 22:37:46 +01:00
CaCO3
0d78bb78ea corrected default 2024-02-12 22:37:46 +01:00
CaCO3
47aea007b3 Added param InitialMirror to config page 2024-02-12 22:37:46 +01:00
CaCO3
284b3f428e on reference image page, hide expert params and add checkbox to unhide them 2024-02-12 22:37:46 +01:00
CaCO3
92d45c7971 Moved 6 Reference Impage Parameters from expert to normal level 2024-02-12 22:37:46 +01:00
CaCO3
ff1d9d3b4f prepare table row IDs to be removed as tehy seem unused 2024-02-12 22:37:46 +01:00
CaCO3
2b57dd0853 . 2024-02-12 22:37:46 +01:00
CaCO3
dd8f5eea22 Added parameters to config page 2024-02-12 22:37:46 +01:00
Joo Aun Saw
60c5305378 Fix up Zoom option documentation 2024-02-12 22:37:46 +01:00
Joo Aun Saw
8b1c65a38a add documentation for new TakeImage options 2024-02-12 22:37:46 +01:00
Joo Aun Saw
4f5933c4f2 add default values for new TakeImage options in config.ini 2024-02-12 22:37:46 +01:00
Joo Aun Saw
06c9bfb0de html: fix negative not applied correctly after saving reference 2024-02-12 22:37:46 +01:00
Joo Aun Saw
69f1a99b55 ov2640: support sharpness control 2024-02-12 22:37:46 +01:00
Joo Aun Saw
a8fb88a35d Support negative photo effect and auto exposure control 2 2024-02-12 22:37:46 +01:00
Joo Aun Saw
d418d22155 removed redundant changes 2024-02-12 22:37:46 +01:00
Joo Aun Saw
53e8cf49f9 limit auto exposure values to range -2 to +2 2024-02-12 22:37:46 +01:00
Joo Aun Saw
ac4f823cbf Support crop image on sensor, grayscale, auto exposure level 2024-02-12 22:37:46 +01:00
CaCO3
444dc0fa39 add missing image 2024-02-11 22:14:57 +01:00
CaCO3
5053a31245 renaming 2024-02-11 22:10:41 +01:00
CaCO3
44cf8933d4 . 2024-02-11 22:10:41 +01:00
CaCO3
35de56be04 Add Firmware Version to MQTT 2024-02-11 22:10:41 +01:00
CaCO3
80a6fc1dc3 Update edit_config_param_template.html (#2881) 2024-02-09 23:02:10 +01:00
CaCO3
d2c47fcde2 Fix pipeline 2024-02-09 14:43:22 +01:00
CaCO3
7b3a493587 v15.6.0 (#2876) (#2877)
* Fix pipeline (#2860)

fix action

* ATA-Trim support (#2864)

Fix issues with the SD-Card initialization

* Update Changelog.md

---------

Co-authored-by: michael <Heinrich-Tuning@web.de>
2024-02-09 14:00:40 +01:00
CaCO3
217f543578 Update Changelog.md 2024-02-09 13:59:23 +01:00
michael
797fc5e764 ATA-Trim support (#2864)
Fix issues with the SD-Card initialization
2024-02-09 13:56:25 +01:00
CaCO3
7a4e82a44e Fix pipeline (#2860)
fix action
2024-02-03 23:16:15 +01:00
CaCO3
019069cd16 v15.5.0 (#2850) (#2851)
* update

* Revert "v15.4.0"

This reverts commit 74d4f20858.

* Revert "prepare v15.4.0 versuch 2"

This reverts commit e790a14caa.

* revert submnodules (#2768)



* Update submodules (#2769)

- Update `esp-nn` to v1.0.2
- Update `esp32-camera` to v2.0.6
- Updated `tflite-micro-esp-examples` (The repo got renamed to `esp-tflite-micro ` and the folder structure got cleaned up).

* fix(unity-test): Run unity tests in dedicated task
Avoid running out of heap

* Add delay

* Update

* Update

* Enhance busy notification (#2774)

* on marker updating, show message and retry until round got completed

* same for contrast enhancement

---------



* Fix negatives on extended resolution false #2744 (#2772)

* not extended resolution allows -1 on the lowest digit

* not extended resolution allows -1 on the lowest number

* negatives on last value digit with -1 will set to prevalue and is not an error  #2744

---------



* Implemented late analog / digital transition (#2778)

* Implemented late transition

Complete rewrite of analog / digital transition

Two tests is still failing, which need to be discussed.

* Allow wider range of transition values to support late transition

* Added documentation

* Fix testings (#2783)

* fix all tests and more description

* The decimal point offset. -3 corresponds to x.yyy

---------



* Bugfix InfluxDB shifting times (#2785)

* Modify time_sntp

* Update time_sntp.cpp

* Update time_sntp.cpp

* update

* Update interface_influxdb.cpp

* Update interface_influxdb.cpp

* Update time_sntp.cpp

* Upload

* Update interface_influxdb.cpp

* Update interface_influxdb.cpp

* Update interface_influxdb.cpp

* Remove Time Convert vom influx Interface

* Update platform-espressif32 to 6.5.0 (#2770)

* Update ESP IDF to 6.5.0

* Migration to new IDF

* Correct smtp vor v5.1

---------




* ATA-Trim support (#2781)

* Add files via upload

* Update main.cpp

* Update main.cpp

* Update main.cpp

* Update Helper.cpp

* Update Helper.h

* Update CMakeLists.txt

* Update CMakeLists.txt

* Update diskio_sdmmc_mh.c

* Update diskio_sdmmc_mh.h

* Update ff_mh.c

* Update vfs_fat_sdmmc_mh.c

* Update sdmmc_common_mh.h

* Update sdmmc_common_mh.c

* Update Helper.cpp

* Update README.md

* Update README.md

* Update README.md

* Update README.md

* Update README.md

* Update README.md

* Update README.md

* Update README.md

* Update README.md

* Update README.md

* Update README.md

* Update README.md

* Update README.md

* Update ff_mh.c

---------



* Update Changelog.md

* Add device info info page (#2789)



* fix chip information REST API

* Update pipelines to fix warnings (#2841)

Update actions

* Move param doc (#2843)

moved param doc from docs repo to here

* fix(tflite): Fix memory leaks in tflite integration (#2842)

* Update Changelog.md (#2849)

---------

Signed-off-by: Florian Grabmeier <flo.grabmeier@gmail.com>
Co-authored-by: jomjol <30766535+jomjol@users.noreply.github.com>
Co-authored-by: CaCO3 <caco@ruinelli.ch>
Co-authored-by: Slider0007 <jobbelle@gmx.net>
Co-authored-by: Frank Haverland <fspapaping@googlemail.com>
Co-authored-by: Martin Siggel <martin.siggel@dlr.de>
Co-authored-by: michael <Heinrich-Tuning@web.de>
Co-authored-by: flox_x <93255373+flooxo@users.noreply.github.com>
Co-authored-by: Slider0007 <115730895+Slider0007@users.noreply.github.com>
2024-02-02 13:52:05 +01:00
CaCO3
4de1152cf3 Update Changelog.md (#2849) 2024-02-02 13:46:42 +01:00
Slider0007
0e0fb459dc fix(tflite): Fix memory leaks in tflite integration (#2842) 2024-02-02 13:23:51 +01:00
CaCO3
8410df6144 Move param doc (#2843)
moved param doc from docs repo to here
2024-01-31 21:53:56 +01:00
CaCO3
4990858101 Update pipelines to fix warnings (#2841)
Update actions
2024-01-31 20:53:41 +01:00
CaCO3
fc1f8ee242 fix chip information REST API 2024-01-08 23:41:48 +01:00
flox_x
252c399a76 Add device info info page (#2789)
Signed-off-by: Florian Grabmeier <flo.grabmeier@gmail.com>
2024-01-08 23:23:57 +01:00
jomjol
eb7f2b3705 Update Changelog.md 2024-01-02 09:04:15 +01:00
michael
2ed6fb0f0d ATA-Trim support (#2781)
* Add files via upload

* Update main.cpp

* Update main.cpp

* Update main.cpp

* Update Helper.cpp

* Update Helper.h

* Update CMakeLists.txt

* Update CMakeLists.txt

* Update diskio_sdmmc_mh.c

* Update diskio_sdmmc_mh.h

* Update ff_mh.c

* Update vfs_fat_sdmmc_mh.c

* Update sdmmc_common_mh.h

* Update sdmmc_common_mh.c

* Update Helper.cpp

* Update README.md

* Update README.md

* Update README.md

* Update README.md

* Update README.md

* Update README.md

* Update README.md

* Update README.md

* Update README.md

* Update README.md

* Update README.md

* Update README.md

* Update README.md

* Update ff_mh.c

---------

Co-authored-by: CaCO3 <caco3@ruinelli.ch>
2024-01-02 08:56:46 +01:00
CaCO3
b5213b01af Update platform-espressif32 to 6.5.0 (#2770)
* Update ESP IDF to 6.5.0

* Migration to new IDF

* Correct smtp vor v5.1

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>
Co-authored-by: jomjol <30766535+jomjol@users.noreply.github.com>
2024-01-01 22:00:23 +01:00
jomjol
473e458b85 Bugfix InfluxDB shifting times (#2785)
* Modify time_sntp

* Update time_sntp.cpp

* Update time_sntp.cpp

* update

* Update interface_influxdb.cpp

* Update interface_influxdb.cpp

* Update time_sntp.cpp

* Upload

* Update interface_influxdb.cpp

* Update interface_influxdb.cpp

* Update interface_influxdb.cpp

* Remove Time Convert vom influx Interface
2024-01-01 10:41:12 +01:00
Frank Haverland
4f3f3d9af2 Fix testings (#2783)
* fix all tests and more description

* The decimal point offset. -3 corresponds to x.yyy

---------

Co-authored-by: jomjol <30766535+jomjol@users.noreply.github.com>
2023-12-31 14:43:08 +01:00
Martin Siggel
b5a4cfed96 Implemented late analog / digital transition (#2778)
* Implemented late transition

Complete rewrite of analog / digital transition

Two tests is still failing, which need to be discussed.

* Allow wider range of transition values to support late transition

* Added documentation
2023-12-31 12:04:09 +01:00
Frank Haverland
6fca4d8d95 Fix negatives on extended resolution false #2744 (#2772)
* not extended resolution allows -1 on the lowest digit

* not extended resolution allows -1 on the lowest number

* negatives on last value digit with -1 will set to prevalue and is not an error  #2744

---------

Co-authored-by: jomjol <30766535+jomjol@users.noreply.github.com>
2023-12-31 12:03:52 +01:00
CaCO3
a11e19fb0c Enhance busy notification (#2774)
* on marker updating, show message and retry until round got completed

* same for contrast enhancement

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>
2023-12-31 11:47:28 +01:00
Frank Haverland
09fa94c95f Merge pull request #2777 from Slider0007/unity-test-rolling
chore(unity-test): Run unity tests in dedicated task
2023-12-30 11:55:22 +01:00
Slider0007
f01b4dbd13 Update 2023-12-29 09:57:59 +01:00
Slider0007
dbf1770016 Update 2023-12-29 09:56:47 +01:00
Slider0007
006f3aa063 Add delay 2023-12-29 09:47:37 +01:00
Slider0007
24c46c38b4 fix(unity-test): Run unity tests in dedicated task
Avoid running out of heap
2023-12-28 21:32:43 +01:00
CaCO3
9ced147d9c Update submodules (#2769)
- Update `esp-nn` to v1.0.2
- Update `esp32-camera` to v2.0.6
- Updated `tflite-micro-esp-examples` (The repo got renamed to `esp-tflite-micro ` and the folder structure got cleaned up).
2023-12-28 12:13:57 +01:00
CaCO3
0808895bd6 revert submnodules (#2768)
Co-authored-by: CaCO3 <caco@ruinelli.ch>
2023-12-28 09:27:42 +01:00
jomjol
d2dec9fa59 Revert "prepare v15.4.0 versuch 2"
This reverts commit e790a14caa.
2023-12-22 23:50:56 +01:00
jomjol
7e7bc3dd68 Revert "v15.4.0"
This reverts commit 74d4f20858.
2023-12-22 23:48:43 +01:00
jomjol
5b09cd0d59 update 2023-12-22 23:47:17 +01:00
jomjol
74d4f20858 v15.4.0 2023-12-22 23:38:31 +01:00
jomjol
e790a14caa prepare v15.4.0 versuch 2 2023-12-22 23:31:13 +01:00
jomjol
f023a6b739 Revert "v15.4.0"
This reverts commit 374462a7d8.
2023-12-22 23:22:57 +01:00
jomjol
1e463188ea Revert "Update Changelog.md"
This reverts commit 9991196961.
2023-12-22 23:22:08 +01:00
jomjol
9991196961 Update Changelog.md 2023-12-22 23:04:52 +01:00
jomjol
ecece0f7fc Update dependencies.lock 2023-12-22 22:55:54 +01:00
jomjol
1b3b7595c1 Merge branch 'rolling' 2023-12-22 22:46:36 +01:00
jomjol
6d10f712d1 Update Changelog.md 2023-12-22 22:46:16 +01:00
jomjol
b84a2db050 Update config.ini 2023-12-22 22:45:32 +01:00
jomjol
374462a7d8 v15.4.0 2023-12-22 22:43:08 +01:00
Frank Haverland
4facd7be05 new images on analog and digits (#2756)
* new images on dig-class100, older ana-class100 removed

* new images on analog and digits
2023-12-22 22:42:33 +01:00
jomjol
3baf5865ad Prepare 15.4.0 2023-12-21 19:21:22 +01:00
CaCO3
02138c44ac rename InfluxDBv2 parameter Database to Bucket (#2704)
* rename InfluxDBv2 parameter Database to Basket

* only enable the field if it is a boolean

* corrected "Basket" to "Bucket"

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>
2023-11-22 23:43:23 +01:00
Slider0007
1094c8a0a8 fix(influxdb): Consider DST setting for UTC time conversion (#2679)
* fix(influxdb): Consider DST setting for UTC time conversion

* Update
2023-11-12 12:04:18 +01:00
LordGuilly
75b15b8e9d added config entries for MQTT TLS (#2651)
3 new entries in the config section, for setting file paths for
        - Root CA
        - Client Certificate
        - Client Private Key
 (all set as expert parameters)

- logging cert filenames

added config entries for MQTT TLS

 3 new entries in the config section, for setting file paths for
        - Root CA
        - Client Certificate
        - Client Private Key

- logging cert filenames

MQTT-TLS: Updates for the PR comments

- config.ini now has default values closer to "real" life filenames
- MQTT cert entries are hidden as Expert parameters
- Fixed debug logging at MQTT interface for unhandled messages
2023-11-07 22:58:16 +01:00
CaCO3
36c12b400b rework test-domain check 2023-11-07 22:42:15 +01:00
CaCO3
35d90cd0ee update readme 2023-10-21 22:39:21 +02:00
CaCO3
999a8d9374 updated readme 2023-10-21 22:35:13 +02:00
CaCO3
8a4269c6a0 Add files via upload 2023-10-21 22:32:25 +02:00
CaCO3
8f5579cca5 updated readme 2023-10-21 22:30:29 +02:00
CaCO3
e58b3a2cf8 update webinstaller 2023-10-21 22:23:08 +02:00
CaCO3
222ee0921c udpate webinstaller 2023-10-21 22:19:07 +02:00
CaCO3
e2bfcd26c9 update web installer 2023-10-21 22:15:47 +02:00
CaCO3
18917b2d82 Delete docs/manifest_template.json 2023-10-21 01:06:52 +02:00
CaCO3
f0dea3abcb Delete docs/binary/firmware.bin 2023-10-21 01:06:42 +02:00
CaCO3
bd2d8b4a15 Update manual-update-webinstaller.yml 2023-10-21 01:06:15 +02:00
CaCO3
80e3f50a5b Update manifest.json 2023-10-21 01:05:19 +02:00
CaCO3
f6ca32d69f Update manual-update-webinstaller.yml 2023-10-21 01:03:00 +02:00
CaCO3
49e919c481 Update manual-update-webinstaller.yml 2023-10-21 01:00:21 +02:00
CaCO3
de768c4f44 Delete releases/download directory 2023-10-21 00:49:24 +02:00
CaCO3
002fc033aa Delete firmware directory 2023-10-21 00:47:05 +02:00
CaCO3
f4af8de699 fix paypal button (#2666)
* Add files via upload

* Update README.md

* Update README.md

* Update README.md

* Update README.md
2023-10-21 00:43:36 +02:00
CaCO3
e4d6707a0b Update README.md 2023-10-21 00:27:52 +02:00
CaCO3
9f03e68690 Update README.md 2023-10-21 00:27:32 +02:00
CaCO3
b1df7df580 added label action 2023-10-20 23:35:07 +02:00
CaCO3
ebc9be4a28 added label action 2023-10-20 23:27:10 +02:00
jomjol
5d0fc73c13 Updated feature request 2023-09-03 15:48:00 +02:00
jomjol
40a1aa0430 Update submodules, include only needed layers of tflite (#2586)
* Initial version

* Working Version

* Update

* Update main.cpp

* Updated Docu
2023-08-20 21:49:28 +02:00
TheDubliner
d7a733512f 📚 Fix minor typos, grammar and formatting issues. (#2575) 2023-08-15 21:37:22 +02:00
Frank Haverland
dc9f1aad27 new images on dig-class100, older ana-class100 removed (#2545) 2023-08-02 21:46:00 +02:00
Frank Haverland
cd3e641bcc #2540 fix trunc of first with imprecise precision (#2543)
* added more debug for #2447

* new model on new images dig-class100-0165_s2

* #2465 fix first digit with extended_Resolution=false

* fix #2491

* #2540 fix trunc of first with imprecise precision
2023-07-30 18:25:56 +02:00
Slider0007
ad72ffa37c mqtt_handler_set_prevalue: fix memory leak (#2544) 2023-07-30 18:25:35 +02:00
Giel van Schijndel
2d45a0ed26 fix: provide proper error messages for invalid /info?type= query parameter (#2533) 2023-07-24 21:44:06 +02:00
Giel van Schijndel
e8065ef414 fix(fileserver): avoid sending *two* "last-chunk" sequences (#2532)
Because a zero-sized chunk indicates the end of a HTTP response sending
another such zero-sized chunk is not interpretable by the HTTP client.

See [RFC2616 3.6.1] "Chunked Transfer Encoding" for details.

[RFC2616 3.6.1]: https://datatracker.ietf.org/doc/html/rfc2616#section-3.6.1
2023-07-24 21:43:56 +02:00
pfeifferch
33893eb566 Shortcut Icon hinzugefügt (#2530)
* Add files via upload

Shortcut icon

* Update index.html

Shortcut icon
2023-07-23 20:33:04 +02:00
jomjol
3fbff0ad33 Merge branch 'rolling' 2023-07-22 11:41:24 +02:00
jomjol
28cabea7f2 Prepare v15.3.0 2023-07-22 09:53:24 +02:00
CaCO3
5d06130a88 enable RSSI roaming by default and set it to -75 dBm (#2504) 2023-07-10 19:50:28 +02:00
LordGuilly
3497a86084 fixed build issues when enabling DEBUG_DETAIL_ON (#2509)
fixed build issues when enabling DEBUG_DETAIL_ON

added missing header when DEBUG_DETAIL_ON is enabled
2023-07-09 22:59:34 +02:00
Frank Haverland
84707fb27a fix #2491 - missing </li> (#2495)
* added more debug for #2447

* new model on new images dig-class100-0165_s2

* #2465 fix first digit with extended_Resolution=false

* fix #2491
2023-07-01 21:16:00 +02:00
CaCO3
0b81af7cb8 Update PlatformIO to 6.3.2 (#2499) 2023-06-30 00:11:56 +02:00
Frank Haverland
61efe1a6ef #2465 Fix first digit on extended_Resolution=false (#2466)
* added more debug for #2447

* new model on new images dig-class100-0165_s2

* #2465 fix first digit with extended_Resolution=false
2023-06-12 20:14:30 +02:00
Frank Haverland
09ecd722cc new model dig-class_0165_s2 on new images (#2455)
* added more debug for #2447

* new model on new images dig-class100-0165_s2
2023-06-06 20:17:27 +02:00
Frank Haverland
5615fd8137 added more debug for #2447 (#2450) 2023-06-03 07:24:14 +02:00
Slider0007
7ebf68411f Analog ROI: Fix wrong multiplier view - only analog ROI, no digit ROI (#2440)
* Fix multiplier view with only analog ROIs

* Refactor multiplier view for digit ROI
2023-06-01 20:46:34 +02:00
Frank Haverland
34835dca84 new version of dig-class100 (#2437) 2023-06-01 20:45:56 +02:00
CaCO3
697ff4c4b6 Update platformio to 6.3.1 2023-05-26 13:31:11 +02:00
CaCO3
0f7c685933 Update PlatformIO to 6.3.0 (#2420)
* Update WebUI

* Initial rotate default to 0.0

* Process related file update: no folder content redirect

* Try to clear cache after intial setup

* Update

* Reference image: remove updatepage

* Update

* Hide "manual flow start"

* Update

* Update

* Update text

* BugFix Make Reference

* Update MainFlowControl.cpp

* Update platformio.ini

* Fix #2393

* Update platformio.ini

---------

Co-authored-by: Slider0007 <jobbelle@gmx.net>
Co-authored-by: jomjol <30766535+jomjol@users.noreply.github.com>
Co-authored-by: CaCO3 <caco@ruinelli.ch>
2023-05-23 21:29:19 +02:00
CaCO3
3ace5aeff1 . 2023-05-23 00:02:18 +02:00
CaCO3
d47ed060b0 Enhance web UI 2023-05-22 23:43:33 +02:00
jomjol
e7dbebffa1 Fix #2393 2023-05-21 13:26:48 +02:00
jomjol
def13d46af Update MainFlowControl.cpp 2023-05-19 22:23:05 +02:00
jomjol
f82a6bf513 Merge branch 'rolling' into update-webui 2023-05-19 22:08:05 +02:00
jomjol
05deecee00 BugFix Make Reference 2023-05-19 21:53:56 +02:00
jomjol
8339b6788f Bug Fix #2403 2023-05-19 21:14:51 +02:00
CaCO3
4e5b084932 SHow correct message in log. Fixes https://github.com/jomjol/AI-on-the-edge-device/issues/2411 2023-05-17 22:16:12 +02:00
jomjol
62fcefee78 Update config.ini 2023-05-09 22:11:07 +02:00
Frank Haverland
14128ca3a7 new models ana-cont, ana-class100, dig-class100 2023-05-09 20:29:33 +02:00
CaCO3
431551fb45 speed up deletion of files (#2389)
* speed up deletion of files

* .

* .

* .

* .

* .

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>
2023-05-05 18:43:46 +02:00
Slider0007
ff52d785cd Update text 2023-05-03 08:50:19 +02:00
Slider0007
f5a7c082d6 Update 2023-05-03 08:46:33 +02:00
Slider0007
f3e90c6293 Update 2023-05-02 23:29:38 +02:00
CaCO3
cbd14a267f v15.2.4 (#2385)
* Testcase for #2145 and debug-log (#2151)

* new models ana-cont-11.0.5, ana-class100-1.5.7, dig-class100-1.6.0

* Testcase for #2145
Added debug log, if allowNegativeRates is handeled

* Fix timezone config parser (#2169)

* make sure to parse the whole config line

* fix crash on empty timezone parameter

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* Enhance ROI pages (#2161)

* Check if the ROIs are equidistant. Only if not, untick the checkbox

* renaming

* Check if the ROIs have same y, dy and dx. If so, tick the sync checkbox

* only allow editing space when box is checked

* fix sync check

* show inner frame on all ROIs

* cleanup

* Check if the ROIs have same dy and dx. If so, tick the sync checkbox

* checkbox position

* renaming

* renaming

* show inner frame and cross hairs on all ROIs

* update ROIs on ticking checkboxes

* show timezone hint

* fix deleting last ROI

* cleanup

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* restart timeout on progress, catch error (#2170)

* restart timeout on progress, catch error

* .

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* BugFix #2167

* Release 15.1 preparations (#2171)

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update changelog

* Fix links to PR

* Formating

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

---------

Co-authored-by: Slider0007 <jobbelle@gmx.net>
Co-authored-by: Slider0007 <115730895+Slider0007@users.noreply.github.com>

* fix typo

* Replace relative documentation links with absolute ones pointing to the external documentation (#2180)

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* Sort model files in configuration combobox (#2189)

* new models ana-cont-11.0.5, ana-class100-1.5.7, dig-class100-1.6.0

* Testcase for #2145
Added debug log, if allowNegativeRates is handeled

* Sort model files in combobox

* reboot task - increase stack size (#2201)

Avoid stack overflow

* Update interface_influxdb.cpp

* Update Changelog.md

* Show PSRAM usage (#2206)

* centralize PSRAM usage (application code only)

* update logging

* update logging

* fix use after free

* initialize buffer

* free rgb_image before ussing it for new allocation

* use wrapper function

* switch log level to debug

* .

* undo adding free() calls

* .

* add names to all CImage instances

* .

* .

* .

* revert changes of stbi_image_free() with free_psram_heap() on the places where is is not in PSRAM

* .

* typos

* typo

* Added MQTT Outbox explanation/warning

* added CONFIG_SPIRAM_USE_MEMMAP explanation

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* Disable custom MQTT Outbox. This also moves the MQTT Publishing memory usage back to the internal RAM!

* log MQTT connection refused reasons (#2216)

* Revert PSRAM usage as it lead to memory fragmentation.
See https://github.com/jomjol/AI-on-the-edge-device/issues/2200 for details

* fix missing value data

* Revert PSRAM usage as it lead to memory fragmentation. (#2224)

See https://github.com/jomjol/AI-on-the-edge-device/issues/2200 for details

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* Fix missing value data in graph (#2230)

* fix missing value data

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* Update Changelog.md (#2231)

* Update interface_influxdb.cpp (#2233)

* update copyright year

* Cleanup

* Set prevalue using MQTT + set prevalue to RAW value (REST+MQTT) (#2252)

* Use double instead of float

* Error handling + set to RAW if newvalue < 0

* REST SetPrevalue: Set to RAW if newvalue < 0

* set prevalue with MQTT

* removed the stb_image files and re-add them as a submodule. (#2223)

- stb_image.h: Version update 2.25 -> 2.28
- stb_resize.h: Version update 0.96 -> 0.97
- stb_write.h: Version update 1.14 -> 1.16

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* Remove obsolete ClassFlowWriteList (#2264)

* Renaming & cleanup of some modules / functions in source code (#2265)

* Rename module tag name

* Rename server_tflite.cpp -> MainFlowControl.cpp

* Remove redundandant MQTTMainTopic function

* Update

* Remove obsolete GetMQTTMainTopic

* Fix last element missing in digit model drop down (#2282)

* Debug influxdb (#2283)

* Fix time offset issues in InfluxDB component. (#2278)

Closes #2273
Closes #2150

* Update interface_influxdb.cpp

* Update interface_influxdb.cpp

* Improve Logging

* Implement TimeSync at beginning

* Update time_sntp.cpp

* Update time_sntp.cpp

* Set Time After WLAN Init

---------

Co-authored-by: Antonin Delpeuch <antonin@delpeuch.eu>

* Implement a camera livestream handler (#2286)

* fix leading NaN (#2310)

* analogROI: Activate save button after ROI creation (#2326)

* Migration of PlatformIO 5.2.0 to 6.1.0 (resp. ESP IDF from 4.4.2 to 5.0.1) (#2305)

* Migration to PlatformIO 6.1.0

* Disable RMTMEM usage as it is no longer allowed -> Smart LEDs not functional!

* moved miniz into subfolder of jomjol_fileserver_ota, else it does not build anymore.

* cleanup

* fix leading NaN (#2310)

* Migration to PlatformIO 6.1.0

* Disable RMTMEM usage as it is no longer allowed -> Smart LEDs not functional!

* moved miniz into subfolder of jomjol_fileserver_ota, else it does not build anymore.

* cleanup

* Task watchdog has new config name

* Fix return value check. It must be something else than ESP_FAIL, but it does not need to be ESP_OK!

* add missing strucures to work around new RMTMEM restriction (untested)

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* Keep MainFlowTask alive to handle reboot (#2325)

* Shared PSRAM memory (#2285)

* enable PSRAM logging

* add extra functions for psram shared memroy handling

* CImageBasis objects still should used dynamic memory (eg. rawImage), haw ever tmpImage must be placed inside the shared memory

* Place all STBI allocs inside the shared memory

* The models are placed in the shared PSRAM reagion and must be allocated through the dedicated functions

* .

* renaming

* fix cast warning

* add flag to switch STBI PSRAM usage

* improve PSRAM shared handling

* reserve shared PSRAM as early as possible

* init logging eralier so we can use it in PSRAM shared alloc

* move Wifi_LWIP, BSS_SEG and MQTT Outbox into PSRAM to ffree internal memory

* Check if model fits into reserved shared memory

* Update code/components/jomjol_tfliteclass/CTfLiteClass.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_flowcontroll/ClassFlowControll.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_image_proc/CImageBasis.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* .

* .

* .

* .

* Korrektur Merge Conflict in main.cpp

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>
Co-authored-by: jomjol <30766535+jomjol@users.noreply.github.com>

* fix PSRAM init return value check

* Extend InfluxDBv1 with individual topic names (#2319)

* Implement individual influx topic

* Update interface_influxdb.cpp

* Update interface_influxdb.cpp

* Update FieldName

* analogROI: Activate save button after ROI creation (#2326)

* Migration of PlatformIO 5.2.0 to 6.1.0 (resp. ESP IDF from 4.4.2 to 5.0.1) (#2305)

* Migration to PlatformIO 6.1.0

* Disable RMTMEM usage as it is no longer allowed -> Smart LEDs not functional!

* moved miniz into subfolder of jomjol_fileserver_ota, else it does not build anymore.

* cleanup

* fix leading NaN (#2310)

* Migration to PlatformIO 6.1.0

* Disable RMTMEM usage as it is no longer allowed -> Smart LEDs not functional!

* moved miniz into subfolder of jomjol_fileserver_ota, else it does not build anymore.

* cleanup

* Task watchdog has new config name

* Fix return value check. It must be something else than ESP_FAIL, but it does not need to be ESP_OK!

* add missing strucures to work around new RMTMEM restriction (untested)

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* Keep MainFlowTask alive to handle reboot (#2325)

* Shared PSRAM memory (#2285)

* enable PSRAM logging

* add extra functions for psram shared memroy handling

* CImageBasis objects still should used dynamic memory (eg. rawImage), haw ever tmpImage must be placed inside the shared memory

* Place all STBI allocs inside the shared memory

* The models are placed in the shared PSRAM reagion and must be allocated through the dedicated functions

* .

* renaming

* fix cast warning

* add flag to switch STBI PSRAM usage

* improve PSRAM shared handling

* reserve shared PSRAM as early as possible

* init logging eralier so we can use it in PSRAM shared alloc

* move Wifi_LWIP, BSS_SEG and MQTT Outbox into PSRAM to ffree internal memory

* Check if model fits into reserved shared memory

* Update code/components/jomjol_tfliteclass/CTfLiteClass.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_flowcontroll/ClassFlowControll.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_image_proc/CImageBasis.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* .

* .

* .

* .

* Korrektur Merge Conflict in main.cpp

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>
Co-authored-by: jomjol <30766535+jomjol@users.noreply.github.com>

* fix PSRAM init return value check

* Extend incl. indiv. Measurement

* Implement UX

* Update ClassFlowInfluxDBv2.cpp

* Implement individual influx topic

* Update interface_influxdb.cpp

* Update interface_influxdb.cpp

* Update FieldName

* Extend incl. indiv. Measurement

* Implement UX

* Update ClassFlowInfluxDBv2.cpp

* Update main.cpp

---------

Co-authored-by: Slider0007 <115730895+Slider0007@users.noreply.github.com>
Co-authored-by: CaCO3 <caco3@ruinelli.ch>
Co-authored-by: CaCO3 <caco@ruinelli.ch>

* Update Changelog.md (#2344)

* Update Changelog.md

* Update Changelog.md

* merge conflicts

* merge conflicts

* update changelog

* Update Changelog.md

* Fix alignment mark PSRAM issue (#2357)

* Add lock for shared PSRAM memory, use it for the relevant round steps and the Alignment Mark Task

* only allow taking a new image for the Alignment Mark while round got completed

* show success/denial of Alignment Mark Update Request

* .

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* Update Changelog.md (#2360)

* Update platformio.ini (#2368)

* Allow the Alignment Mark step while status is "Initializing" or "Initialization (delayed)" or while in setup mode (#2373)

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* Improve logging if Autostart is not enabled. Renamed/splitted functions (#2376)

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* Cleanup web UI (#2378)

* fix wrong index on backup log

* remove no longer used files/functions

* improve logging on Alignment Mark Update

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* Update Changelog.md

* fix broken sysinfo (#2381)

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* Update Changelog.md

* Update Changelog.md

* Update sdcard_check.cpp (#2384)

* Update Changelog.md

---------

Co-authored-by: Frank Haverland <fspapaping@googlemail.com>
Co-authored-by: CaCO3 <caco@ruinelli.ch>
Co-authored-by: jomjol <30766535+jomjol@users.noreply.github.com>
Co-authored-by: Slider0007 <jobbelle@gmx.net>
Co-authored-by: Slider0007 <115730895+Slider0007@users.noreply.github.com>
Co-authored-by: Antonin Delpeuch <antonin@delpeuch.eu>
2023-05-02 07:54:28 +02:00
CaCO3
ba7d6b3621 Merge branch 'master' into rolling 2023-05-02 07:53:10 +02:00
CaCO3
d4a492463b Update Changelog.md 2023-05-02 07:51:25 +02:00
CaCO3
46589288e7 Update sdcard_check.cpp (#2384) 2023-05-02 07:49:44 +02:00
CaCO3
81a57d32a8 v15.2.3 (#2382)
* Testcase for #2145 and debug-log (#2151)

* new models ana-cont-11.0.5, ana-class100-1.5.7, dig-class100-1.6.0

* Testcase for #2145
Added debug log, if allowNegativeRates is handeled

* Fix timezone config parser (#2169)

* make sure to parse the whole config line

* fix crash on empty timezone parameter

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* Enhance ROI pages (#2161)

* Check if the ROIs are equidistant. Only if not, untick the checkbox

* renaming

* Check if the ROIs have same y, dy and dx. If so, tick the sync checkbox

* only allow editing space when box is checked

* fix sync check

* show inner frame on all ROIs

* cleanup

* Check if the ROIs have same dy and dx. If so, tick the sync checkbox

* checkbox position

* renaming

* renaming

* show inner frame and cross hairs on all ROIs

* update ROIs on ticking checkboxes

* show timezone hint

* fix deleting last ROI

* cleanup

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* restart timeout on progress, catch error (#2170)

* restart timeout on progress, catch error

* .

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* BugFix #2167

* Release 15.1 preparations (#2171)

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update changelog

* Fix links to PR

* Formating

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

---------

Co-authored-by: Slider0007 <jobbelle@gmx.net>
Co-authored-by: Slider0007 <115730895+Slider0007@users.noreply.github.com>

* fix typo

* Replace relative documentation links with absolute ones pointing to the external documentation (#2180)

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* Sort model files in configuration combobox (#2189)

* new models ana-cont-11.0.5, ana-class100-1.5.7, dig-class100-1.6.0

* Testcase for #2145
Added debug log, if allowNegativeRates is handeled

* Sort model files in combobox

* reboot task - increase stack size (#2201)

Avoid stack overflow

* Update interface_influxdb.cpp

* Update Changelog.md

* Show PSRAM usage (#2206)

* centralize PSRAM usage (application code only)

* update logging

* update logging

* fix use after free

* initialize buffer

* free rgb_image before ussing it for new allocation

* use wrapper function

* switch log level to debug

* .

* undo adding free() calls

* .

* add names to all CImage instances

* .

* .

* .

* revert changes of stbi_image_free() with free_psram_heap() on the places where is is not in PSRAM

* .

* typos

* typo

* Added MQTT Outbox explanation/warning

* added CONFIG_SPIRAM_USE_MEMMAP explanation

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* Disable custom MQTT Outbox. This also moves the MQTT Publishing memory usage back to the internal RAM!

* log MQTT connection refused reasons (#2216)

* Revert PSRAM usage as it lead to memory fragmentation.
See https://github.com/jomjol/AI-on-the-edge-device/issues/2200 for details

* fix missing value data

* Revert PSRAM usage as it lead to memory fragmentation. (#2224)

See https://github.com/jomjol/AI-on-the-edge-device/issues/2200 for details

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* Fix missing value data in graph (#2230)

* fix missing value data

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* Update Changelog.md (#2231)

* Update interface_influxdb.cpp (#2233)

* update copyright year

* Cleanup

* Set prevalue using MQTT + set prevalue to RAW value (REST+MQTT) (#2252)

* Use double instead of float

* Error handling + set to RAW if newvalue < 0

* REST SetPrevalue: Set to RAW if newvalue < 0

* set prevalue with MQTT

* removed the stb_image files and re-add them as a submodule. (#2223)

- stb_image.h: Version update 2.25 -> 2.28
- stb_resize.h: Version update 0.96 -> 0.97
- stb_write.h: Version update 1.14 -> 1.16

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* Remove obsolete ClassFlowWriteList (#2264)

* Renaming & cleanup of some modules / functions in source code (#2265)

* Rename module tag name

* Rename server_tflite.cpp -> MainFlowControl.cpp

* Remove redundandant MQTTMainTopic function

* Update

* Remove obsolete GetMQTTMainTopic

* Fix last element missing in digit model drop down (#2282)

* Debug influxdb (#2283)

* Fix time offset issues in InfluxDB component. (#2278)

Closes #2273
Closes #2150

* Update interface_influxdb.cpp

* Update interface_influxdb.cpp

* Improve Logging

* Implement TimeSync at beginning

* Update time_sntp.cpp

* Update time_sntp.cpp

* Set Time After WLAN Init

---------

Co-authored-by: Antonin Delpeuch <antonin@delpeuch.eu>

* Implement a camera livestream handler (#2286)

* fix leading NaN (#2310)

* analogROI: Activate save button after ROI creation (#2326)

* Migration of PlatformIO 5.2.0 to 6.1.0 (resp. ESP IDF from 4.4.2 to 5.0.1) (#2305)

* Migration to PlatformIO 6.1.0

* Disable RMTMEM usage as it is no longer allowed -> Smart LEDs not functional!

* moved miniz into subfolder of jomjol_fileserver_ota, else it does not build anymore.

* cleanup

* fix leading NaN (#2310)

* Migration to PlatformIO 6.1.0

* Disable RMTMEM usage as it is no longer allowed -> Smart LEDs not functional!

* moved miniz into subfolder of jomjol_fileserver_ota, else it does not build anymore.

* cleanup

* Task watchdog has new config name

* Fix return value check. It must be something else than ESP_FAIL, but it does not need to be ESP_OK!

* add missing strucures to work around new RMTMEM restriction (untested)

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* Keep MainFlowTask alive to handle reboot (#2325)

* Shared PSRAM memory (#2285)

* enable PSRAM logging

* add extra functions for psram shared memroy handling

* CImageBasis objects still should used dynamic memory (eg. rawImage), haw ever tmpImage must be placed inside the shared memory

* Place all STBI allocs inside the shared memory

* The models are placed in the shared PSRAM reagion and must be allocated through the dedicated functions

* .

* renaming

* fix cast warning

* add flag to switch STBI PSRAM usage

* improve PSRAM shared handling

* reserve shared PSRAM as early as possible

* init logging eralier so we can use it in PSRAM shared alloc

* move Wifi_LWIP, BSS_SEG and MQTT Outbox into PSRAM to ffree internal memory

* Check if model fits into reserved shared memory

* Update code/components/jomjol_tfliteclass/CTfLiteClass.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_flowcontroll/ClassFlowControll.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_image_proc/CImageBasis.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* .

* .

* .

* .

* Korrektur Merge Conflict in main.cpp

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>
Co-authored-by: jomjol <30766535+jomjol@users.noreply.github.com>

* fix PSRAM init return value check

* Extend InfluxDBv1 with individual topic names (#2319)

* Implement individual influx topic

* Update interface_influxdb.cpp

* Update interface_influxdb.cpp

* Update FieldName

* analogROI: Activate save button after ROI creation (#2326)

* Migration of PlatformIO 5.2.0 to 6.1.0 (resp. ESP IDF from 4.4.2 to 5.0.1) (#2305)

* Migration to PlatformIO 6.1.0

* Disable RMTMEM usage as it is no longer allowed -> Smart LEDs not functional!

* moved miniz into subfolder of jomjol_fileserver_ota, else it does not build anymore.

* cleanup

* fix leading NaN (#2310)

* Migration to PlatformIO 6.1.0

* Disable RMTMEM usage as it is no longer allowed -> Smart LEDs not functional!

* moved miniz into subfolder of jomjol_fileserver_ota, else it does not build anymore.

* cleanup

* Task watchdog has new config name

* Fix return value check. It must be something else than ESP_FAIL, but it does not need to be ESP_OK!

* add missing strucures to work around new RMTMEM restriction (untested)

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* Keep MainFlowTask alive to handle reboot (#2325)

* Shared PSRAM memory (#2285)

* enable PSRAM logging

* add extra functions for psram shared memroy handling

* CImageBasis objects still should used dynamic memory (eg. rawImage), haw ever tmpImage must be placed inside the shared memory

* Place all STBI allocs inside the shared memory

* The models are placed in the shared PSRAM reagion and must be allocated through the dedicated functions

* .

* renaming

* fix cast warning

* add flag to switch STBI PSRAM usage

* improve PSRAM shared handling

* reserve shared PSRAM as early as possible

* init logging eralier so we can use it in PSRAM shared alloc

* move Wifi_LWIP, BSS_SEG and MQTT Outbox into PSRAM to ffree internal memory

* Check if model fits into reserved shared memory

* Update code/components/jomjol_tfliteclass/CTfLiteClass.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_flowcontroll/ClassFlowControll.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_image_proc/CImageBasis.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* .

* .

* .

* .

* Korrektur Merge Conflict in main.cpp

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>
Co-authored-by: jomjol <30766535+jomjol@users.noreply.github.com>

* fix PSRAM init return value check

* Extend incl. indiv. Measurement

* Implement UX

* Update ClassFlowInfluxDBv2.cpp

* Implement individual influx topic

* Update interface_influxdb.cpp

* Update interface_influxdb.cpp

* Update FieldName

* Extend incl. indiv. Measurement

* Implement UX

* Update ClassFlowInfluxDBv2.cpp

* Update main.cpp

---------

Co-authored-by: Slider0007 <115730895+Slider0007@users.noreply.github.com>
Co-authored-by: CaCO3 <caco3@ruinelli.ch>
Co-authored-by: CaCO3 <caco@ruinelli.ch>

* Update Changelog.md (#2344)

* Update Changelog.md

* Update Changelog.md

* merge conflicts

* merge conflicts

* update changelog

* Update Changelog.md

* Fix alignment mark PSRAM issue (#2357)

* Add lock for shared PSRAM memory, use it for the relevant round steps and the Alignment Mark Task

* only allow taking a new image for the Alignment Mark while round got completed

* show success/denial of Alignment Mark Update Request

* .

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* Update Changelog.md (#2360)

* Update platformio.ini (#2368)

* Allow the Alignment Mark step while status is "Initializing" or "Initialization (delayed)" or while in setup mode (#2373)

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* Improve logging if Autostart is not enabled. Renamed/splitted functions (#2376)

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* Cleanup web UI (#2378)

* fix wrong index on backup log

* remove no longer used files/functions

* improve logging on Alignment Mark Update

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* Update Changelog.md

* fix broken sysinfo (#2381)

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* Update Changelog.md

* Update Changelog.md

---------

Co-authored-by: Frank Haverland <fspapaping@googlemail.com>
Co-authored-by: CaCO3 <caco@ruinelli.ch>
Co-authored-by: jomjol <30766535+jomjol@users.noreply.github.com>
Co-authored-by: Slider0007 <jobbelle@gmx.net>
Co-authored-by: Slider0007 <115730895+Slider0007@users.noreply.github.com>
Co-authored-by: Antonin Delpeuch <antonin@delpeuch.eu>
2023-05-01 23:39:12 +02:00
CaCO3
17994494c9 Merge branch 'master' into rolling 2023-05-01 23:38:47 +02:00
CaCO3
c581d64a26 Update Changelog.md 2023-05-01 23:37:58 +02:00
CaCO3
70c2b88f8a Update Changelog.md 2023-05-01 23:37:36 +02:00
CaCO3
13d01a6c96 fix broken sysinfo (#2381)
Co-authored-by: CaCO3 <caco@ruinelli.ch>
2023-05-01 23:34:55 +02:00
CaCO3
331e3533cc v15.2.2 (#2379)
* Testcase for #2145 and debug-log (#2151)

* new models ana-cont-11.0.5, ana-class100-1.5.7, dig-class100-1.6.0

* Testcase for #2145
Added debug log, if allowNegativeRates is handeled

* Fix timezone config parser (#2169)

* make sure to parse the whole config line

* fix crash on empty timezone parameter

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* Enhance ROI pages (#2161)

* Check if the ROIs are equidistant. Only if not, untick the checkbox

* renaming

* Check if the ROIs have same y, dy and dx. If so, tick the sync checkbox

* only allow editing space when box is checked

* fix sync check

* show inner frame on all ROIs

* cleanup

* Check if the ROIs have same dy and dx. If so, tick the sync checkbox

* checkbox position

* renaming

* renaming

* show inner frame and cross hairs on all ROIs

* update ROIs on ticking checkboxes

* show timezone hint

* fix deleting last ROI

* cleanup

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* restart timeout on progress, catch error (#2170)

* restart timeout on progress, catch error

* .

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* BugFix #2167

* Release 15.1 preparations (#2171)

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update changelog

* Fix links to PR

* Formating

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

---------

Co-authored-by: Slider0007 <jobbelle@gmx.net>
Co-authored-by: Slider0007 <115730895+Slider0007@users.noreply.github.com>

* fix typo

* Replace relative documentation links with absolute ones pointing to the external documentation (#2180)

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* Sort model files in configuration combobox (#2189)

* new models ana-cont-11.0.5, ana-class100-1.5.7, dig-class100-1.6.0

* Testcase for #2145
Added debug log, if allowNegativeRates is handeled

* Sort model files in combobox

* reboot task - increase stack size (#2201)

Avoid stack overflow

* Update interface_influxdb.cpp

* Update Changelog.md

* Show PSRAM usage (#2206)

* centralize PSRAM usage (application code only)

* update logging

* update logging

* fix use after free

* initialize buffer

* free rgb_image before ussing it for new allocation

* use wrapper function

* switch log level to debug

* .

* undo adding free() calls

* .

* add names to all CImage instances

* .

* .

* .

* revert changes of stbi_image_free() with free_psram_heap() on the places where is is not in PSRAM

* .

* typos

* typo

* Added MQTT Outbox explanation/warning

* added CONFIG_SPIRAM_USE_MEMMAP explanation

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* Disable custom MQTT Outbox. This also moves the MQTT Publishing memory usage back to the internal RAM!

* log MQTT connection refused reasons (#2216)

* Revert PSRAM usage as it lead to memory fragmentation.
See https://github.com/jomjol/AI-on-the-edge-device/issues/2200 for details

* fix missing value data

* Revert PSRAM usage as it lead to memory fragmentation. (#2224)

See https://github.com/jomjol/AI-on-the-edge-device/issues/2200 for details

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* Fix missing value data in graph (#2230)

* fix missing value data

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* Update Changelog.md (#2231)

* Update interface_influxdb.cpp (#2233)

* update copyright year

* Cleanup

* Set prevalue using MQTT + set prevalue to RAW value (REST+MQTT) (#2252)

* Use double instead of float

* Error handling + set to RAW if newvalue < 0

* REST SetPrevalue: Set to RAW if newvalue < 0

* set prevalue with MQTT

* removed the stb_image files and re-add them as a submodule. (#2223)

- stb_image.h: Version update 2.25 -> 2.28
- stb_resize.h: Version update 0.96 -> 0.97
- stb_write.h: Version update 1.14 -> 1.16

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* Remove obsolete ClassFlowWriteList (#2264)

* Renaming & cleanup of some modules / functions in source code (#2265)

* Rename module tag name

* Rename server_tflite.cpp -> MainFlowControl.cpp

* Remove redundandant MQTTMainTopic function

* Update

* Remove obsolete GetMQTTMainTopic

* Fix last element missing in digit model drop down (#2282)

* Debug influxdb (#2283)

* Fix time offset issues in InfluxDB component. (#2278)

Closes #2273
Closes #2150

* Update interface_influxdb.cpp

* Update interface_influxdb.cpp

* Improve Logging

* Implement TimeSync at beginning

* Update time_sntp.cpp

* Update time_sntp.cpp

* Set Time After WLAN Init

---------

Co-authored-by: Antonin Delpeuch <antonin@delpeuch.eu>

* Implement a camera livestream handler (#2286)

* fix leading NaN (#2310)

* analogROI: Activate save button after ROI creation (#2326)

* Migration of PlatformIO 5.2.0 to 6.1.0 (resp. ESP IDF from 4.4.2 to 5.0.1) (#2305)

* Migration to PlatformIO 6.1.0

* Disable RMTMEM usage as it is no longer allowed -> Smart LEDs not functional!

* moved miniz into subfolder of jomjol_fileserver_ota, else it does not build anymore.

* cleanup

* fix leading NaN (#2310)

* Migration to PlatformIO 6.1.0

* Disable RMTMEM usage as it is no longer allowed -> Smart LEDs not functional!

* moved miniz into subfolder of jomjol_fileserver_ota, else it does not build anymore.

* cleanup

* Task watchdog has new config name

* Fix return value check. It must be something else than ESP_FAIL, but it does not need to be ESP_OK!

* add missing strucures to work around new RMTMEM restriction (untested)

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* Keep MainFlowTask alive to handle reboot (#2325)

* Shared PSRAM memory (#2285)

* enable PSRAM logging

* add extra functions for psram shared memroy handling

* CImageBasis objects still should used dynamic memory (eg. rawImage), haw ever tmpImage must be placed inside the shared memory

* Place all STBI allocs inside the shared memory

* The models are placed in the shared PSRAM reagion and must be allocated through the dedicated functions

* .

* renaming

* fix cast warning

* add flag to switch STBI PSRAM usage

* improve PSRAM shared handling

* reserve shared PSRAM as early as possible

* init logging eralier so we can use it in PSRAM shared alloc

* move Wifi_LWIP, BSS_SEG and MQTT Outbox into PSRAM to ffree internal memory

* Check if model fits into reserved shared memory

* Update code/components/jomjol_tfliteclass/CTfLiteClass.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_flowcontroll/ClassFlowControll.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_image_proc/CImageBasis.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* .

* .

* .

* .

* Korrektur Merge Conflict in main.cpp

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>
Co-authored-by: jomjol <30766535+jomjol@users.noreply.github.com>

* fix PSRAM init return value check

* Extend InfluxDBv1 with individual topic names (#2319)

* Implement individual influx topic

* Update interface_influxdb.cpp

* Update interface_influxdb.cpp

* Update FieldName

* analogROI: Activate save button after ROI creation (#2326)

* Migration of PlatformIO 5.2.0 to 6.1.0 (resp. ESP IDF from 4.4.2 to 5.0.1) (#2305)

* Migration to PlatformIO 6.1.0

* Disable RMTMEM usage as it is no longer allowed -> Smart LEDs not functional!

* moved miniz into subfolder of jomjol_fileserver_ota, else it does not build anymore.

* cleanup

* fix leading NaN (#2310)

* Migration to PlatformIO 6.1.0

* Disable RMTMEM usage as it is no longer allowed -> Smart LEDs not functional!

* moved miniz into subfolder of jomjol_fileserver_ota, else it does not build anymore.

* cleanup

* Task watchdog has new config name

* Fix return value check. It must be something else than ESP_FAIL, but it does not need to be ESP_OK!

* add missing strucures to work around new RMTMEM restriction (untested)

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* Keep MainFlowTask alive to handle reboot (#2325)

* Shared PSRAM memory (#2285)

* enable PSRAM logging

* add extra functions for psram shared memroy handling

* CImageBasis objects still should used dynamic memory (eg. rawImage), haw ever tmpImage must be placed inside the shared memory

* Place all STBI allocs inside the shared memory

* The models are placed in the shared PSRAM reagion and must be allocated through the dedicated functions

* .

* renaming

* fix cast warning

* add flag to switch STBI PSRAM usage

* improve PSRAM shared handling

* reserve shared PSRAM as early as possible

* init logging eralier so we can use it in PSRAM shared alloc

* move Wifi_LWIP, BSS_SEG and MQTT Outbox into PSRAM to ffree internal memory

* Check if model fits into reserved shared memory

* Update code/components/jomjol_tfliteclass/CTfLiteClass.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_flowcontroll/ClassFlowControll.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_image_proc/CImageBasis.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* .

* .

* .

* .

* Korrektur Merge Conflict in main.cpp

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>
Co-authored-by: jomjol <30766535+jomjol@users.noreply.github.com>

* fix PSRAM init return value check

* Extend incl. indiv. Measurement

* Implement UX

* Update ClassFlowInfluxDBv2.cpp

* Implement individual influx topic

* Update interface_influxdb.cpp

* Update interface_influxdb.cpp

* Update FieldName

* Extend incl. indiv. Measurement

* Implement UX

* Update ClassFlowInfluxDBv2.cpp

* Update main.cpp

---------

Co-authored-by: Slider0007 <115730895+Slider0007@users.noreply.github.com>
Co-authored-by: CaCO3 <caco3@ruinelli.ch>
Co-authored-by: CaCO3 <caco@ruinelli.ch>

* Update Changelog.md (#2344)

* Update Changelog.md

* Update Changelog.md

* merge conflicts

* merge conflicts

* update changelog

* Update Changelog.md

* Fix alignment mark PSRAM issue (#2357)

* Add lock for shared PSRAM memory, use it for the relevant round steps and the Alignment Mark Task

* only allow taking a new image for the Alignment Mark while round got completed

* show success/denial of Alignment Mark Update Request

* .

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* Update Changelog.md (#2360)

* Update platformio.ini (#2368)

* Allow the Alignment Mark step while status is "Initializing" or "Initialization (delayed)" or while in setup mode (#2373)

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* Improve logging if Autostart is not enabled. Renamed/splitted functions (#2376)

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* Cleanup web UI (#2378)

* fix wrong index on backup log

* remove no longer used files/functions

* improve logging on Alignment Mark Update

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* Update Changelog.md

---------

Co-authored-by: Frank Haverland <fspapaping@googlemail.com>
Co-authored-by: CaCO3 <caco@ruinelli.ch>
Co-authored-by: jomjol <30766535+jomjol@users.noreply.github.com>
Co-authored-by: Slider0007 <jobbelle@gmx.net>
Co-authored-by: Slider0007 <115730895+Slider0007@users.noreply.github.com>
Co-authored-by: Antonin Delpeuch <antonin@delpeuch.eu>
2023-05-01 22:54:10 +02:00
CaCO3
5a00bdd7f6 Update Changelog.md 2023-05-01 22:53:49 +02:00
CaCO3
db7ffb30c4 Merge branch 'master' into rolling 2023-05-01 22:48:39 +02:00
CaCO3
9a07f271ff Cleanup web UI (#2378)
* fix wrong index on backup log

* remove no longer used files/functions

* improve logging on Alignment Mark Update

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>
2023-05-01 22:38:30 +02:00
CaCO3
6a45ab7693 Improve logging if Autostart is not enabled. Renamed/splitted functions (#2376)
Co-authored-by: CaCO3 <caco@ruinelli.ch>
2023-05-01 22:16:48 +02:00
CaCO3
9fc876853b Allow the Alignment Mark step while status is "Initializing" or "Initialization (delayed)" or while in setup mode (#2373)
Co-authored-by: CaCO3 <caco@ruinelli.ch>
2023-05-01 21:28:23 +02:00
Slider0007
c30881f73c Hide "manual flow start" 2023-05-01 20:00:41 +02:00
Slider0007
e75e720869 Update 2023-05-01 19:23:01 +02:00
CaCO3
43aae5a3cd Update platformio.ini (#2368) 2023-05-01 16:19:38 +02:00
Slider0007
54cd7e511a Reference image: remove updatepage 2023-05-01 14:45:47 +02:00
Slider0007
c5a82e839f Update 2023-05-01 14:44:56 +02:00
Slider0007
9f97a2b223 Try to clear cache after intial setup 2023-05-01 14:23:14 +02:00
Slider0007
8d06de5792 Process related file update: no folder content redirect 2023-05-01 14:22:15 +02:00
Slider0007
1326585a33 Initial rotate default to 0.0 2023-05-01 14:20:05 +02:00
Slider0007
d7a507ca05 Update WebUI 2023-05-01 14:19:31 +02:00
CaCO3
b24b7d5ce2 v15.2.1 (#2361)
* Testcase for #2145 and debug-log (#2151)

* new models ana-cont-11.0.5, ana-class100-1.5.7, dig-class100-1.6.0

* Testcase for #2145
Added debug log, if allowNegativeRates is handeled

* Fix timezone config parser (#2169)

* make sure to parse the whole config line

* fix crash on empty timezone parameter

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* Enhance ROI pages (#2161)

* Check if the ROIs are equidistant. Only if not, untick the checkbox

* renaming

* Check if the ROIs have same y, dy and dx. If so, tick the sync checkbox

* only allow editing space when box is checked

* fix sync check

* show inner frame on all ROIs

* cleanup

* Check if the ROIs have same dy and dx. If so, tick the sync checkbox

* checkbox position

* renaming

* renaming

* show inner frame and cross hairs on all ROIs

* update ROIs on ticking checkboxes

* show timezone hint

* fix deleting last ROI

* cleanup

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* restart timeout on progress, catch error (#2170)

* restart timeout on progress, catch error

* .

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* BugFix #2167

* Release 15.1 preparations (#2171)

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update changelog

* Fix links to PR

* Formating

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

---------

Co-authored-by: Slider0007 <jobbelle@gmx.net>
Co-authored-by: Slider0007 <115730895+Slider0007@users.noreply.github.com>

* fix typo

* Replace relative documentation links with absolute ones pointing to the external documentation (#2180)

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* Sort model files in configuration combobox (#2189)

* new models ana-cont-11.0.5, ana-class100-1.5.7, dig-class100-1.6.0

* Testcase for #2145
Added debug log, if allowNegativeRates is handeled

* Sort model files in combobox

* reboot task - increase stack size (#2201)

Avoid stack overflow

* Update interface_influxdb.cpp

* Update Changelog.md

* Show PSRAM usage (#2206)

* centralize PSRAM usage (application code only)

* update logging

* update logging

* fix use after free

* initialize buffer

* free rgb_image before ussing it for new allocation

* use wrapper function

* switch log level to debug

* .

* undo adding free() calls

* .

* add names to all CImage instances

* .

* .

* .

* revert changes of stbi_image_free() with free_psram_heap() on the places where is is not in PSRAM

* .

* typos

* typo

* Added MQTT Outbox explanation/warning

* added CONFIG_SPIRAM_USE_MEMMAP explanation

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* Disable custom MQTT Outbox. This also moves the MQTT Publishing memory usage back to the internal RAM!

* log MQTT connection refused reasons (#2216)

* Revert PSRAM usage as it lead to memory fragmentation.
See https://github.com/jomjol/AI-on-the-edge-device/issues/2200 for details

* fix missing value data

* Revert PSRAM usage as it lead to memory fragmentation. (#2224)

See https://github.com/jomjol/AI-on-the-edge-device/issues/2200 for details

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* Fix missing value data in graph (#2230)

* fix missing value data

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* Update Changelog.md (#2231)

* Update interface_influxdb.cpp (#2233)

* update copyright year

* Cleanup

* Set prevalue using MQTT + set prevalue to RAW value (REST+MQTT) (#2252)

* Use double instead of float

* Error handling + set to RAW if newvalue < 0

* REST SetPrevalue: Set to RAW if newvalue < 0

* set prevalue with MQTT

* removed the stb_image files and re-add them as a submodule. (#2223)

- stb_image.h: Version update 2.25 -> 2.28
- stb_resize.h: Version update 0.96 -> 0.97
- stb_write.h: Version update 1.14 -> 1.16

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* Remove obsolete ClassFlowWriteList (#2264)

* Renaming & cleanup of some modules / functions in source code (#2265)

* Rename module tag name

* Rename server_tflite.cpp -> MainFlowControl.cpp

* Remove redundandant MQTTMainTopic function

* Update

* Remove obsolete GetMQTTMainTopic

* Fix last element missing in digit model drop down (#2282)

* Debug influxdb (#2283)

* Fix time offset issues in InfluxDB component. (#2278)

Closes #2273
Closes #2150

* Update interface_influxdb.cpp

* Update interface_influxdb.cpp

* Improve Logging

* Implement TimeSync at beginning

* Update time_sntp.cpp

* Update time_sntp.cpp

* Set Time After WLAN Init

---------

Co-authored-by: Antonin Delpeuch <antonin@delpeuch.eu>

* Implement a camera livestream handler (#2286)

* fix leading NaN (#2310)

* analogROI: Activate save button after ROI creation (#2326)

* Migration of PlatformIO 5.2.0 to 6.1.0 (resp. ESP IDF from 4.4.2 to 5.0.1) (#2305)

* Migration to PlatformIO 6.1.0

* Disable RMTMEM usage as it is no longer allowed -> Smart LEDs not functional!

* moved miniz into subfolder of jomjol_fileserver_ota, else it does not build anymore.

* cleanup

* fix leading NaN (#2310)

* Migration to PlatformIO 6.1.0

* Disable RMTMEM usage as it is no longer allowed -> Smart LEDs not functional!

* moved miniz into subfolder of jomjol_fileserver_ota, else it does not build anymore.

* cleanup

* Task watchdog has new config name

* Fix return value check. It must be something else than ESP_FAIL, but it does not need to be ESP_OK!

* add missing strucures to work around new RMTMEM restriction (untested)

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* Keep MainFlowTask alive to handle reboot (#2325)

* Shared PSRAM memory (#2285)

* enable PSRAM logging

* add extra functions for psram shared memroy handling

* CImageBasis objects still should used dynamic memory (eg. rawImage), haw ever tmpImage must be placed inside the shared memory

* Place all STBI allocs inside the shared memory

* The models are placed in the shared PSRAM reagion and must be allocated through the dedicated functions

* .

* renaming

* fix cast warning

* add flag to switch STBI PSRAM usage

* improve PSRAM shared handling

* reserve shared PSRAM as early as possible

* init logging eralier so we can use it in PSRAM shared alloc

* move Wifi_LWIP, BSS_SEG and MQTT Outbox into PSRAM to ffree internal memory

* Check if model fits into reserved shared memory

* Update code/components/jomjol_tfliteclass/CTfLiteClass.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_flowcontroll/ClassFlowControll.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_image_proc/CImageBasis.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* .

* .

* .

* .

* Korrektur Merge Conflict in main.cpp

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>
Co-authored-by: jomjol <30766535+jomjol@users.noreply.github.com>

* fix PSRAM init return value check

* Extend InfluxDBv1 with individual topic names (#2319)

* Implement individual influx topic

* Update interface_influxdb.cpp

* Update interface_influxdb.cpp

* Update FieldName

* analogROI: Activate save button after ROI creation (#2326)

* Migration of PlatformIO 5.2.0 to 6.1.0 (resp. ESP IDF from 4.4.2 to 5.0.1) (#2305)

* Migration to PlatformIO 6.1.0

* Disable RMTMEM usage as it is no longer allowed -> Smart LEDs not functional!

* moved miniz into subfolder of jomjol_fileserver_ota, else it does not build anymore.

* cleanup

* fix leading NaN (#2310)

* Migration to PlatformIO 6.1.0

* Disable RMTMEM usage as it is no longer allowed -> Smart LEDs not functional!

* moved miniz into subfolder of jomjol_fileserver_ota, else it does not build anymore.

* cleanup

* Task watchdog has new config name

* Fix return value check. It must be something else than ESP_FAIL, but it does not need to be ESP_OK!

* add missing strucures to work around new RMTMEM restriction (untested)

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* Keep MainFlowTask alive to handle reboot (#2325)

* Shared PSRAM memory (#2285)

* enable PSRAM logging

* add extra functions for psram shared memroy handling

* CImageBasis objects still should used dynamic memory (eg. rawImage), haw ever tmpImage must be placed inside the shared memory

* Place all STBI allocs inside the shared memory

* The models are placed in the shared PSRAM reagion and must be allocated through the dedicated functions

* .

* renaming

* fix cast warning

* add flag to switch STBI PSRAM usage

* improve PSRAM shared handling

* reserve shared PSRAM as early as possible

* init logging eralier so we can use it in PSRAM shared alloc

* move Wifi_LWIP, BSS_SEG and MQTT Outbox into PSRAM to ffree internal memory

* Check if model fits into reserved shared memory

* Update code/components/jomjol_tfliteclass/CTfLiteClass.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_flowcontroll/ClassFlowControll.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_image_proc/CImageBasis.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* .

* .

* .

* .

* Korrektur Merge Conflict in main.cpp

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>
Co-authored-by: jomjol <30766535+jomjol@users.noreply.github.com>

* fix PSRAM init return value check

* Extend incl. indiv. Measurement

* Implement UX

* Update ClassFlowInfluxDBv2.cpp

* Implement individual influx topic

* Update interface_influxdb.cpp

* Update interface_influxdb.cpp

* Update FieldName

* Extend incl. indiv. Measurement

* Implement UX

* Update ClassFlowInfluxDBv2.cpp

* Update main.cpp

---------

Co-authored-by: Slider0007 <115730895+Slider0007@users.noreply.github.com>
Co-authored-by: CaCO3 <caco3@ruinelli.ch>
Co-authored-by: CaCO3 <caco@ruinelli.ch>

* Update Changelog.md (#2344)

* Update Changelog.md

* Update Changelog.md

* merge conflicts

* merge conflicts

* update changelog

* Update Changelog.md

* Fix alignment mark PSRAM issue (#2357)

* Add lock for shared PSRAM memory, use it for the relevant round steps and the Alignment Mark Task

* only allow taking a new image for the Alignment Mark while round got completed

* show success/denial of Alignment Mark Update Request

* .

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* Update Changelog.md (#2360)

---------

Co-authored-by: Frank Haverland <fspapaping@googlemail.com>
Co-authored-by: CaCO3 <caco@ruinelli.ch>
Co-authored-by: jomjol <30766535+jomjol@users.noreply.github.com>
Co-authored-by: Slider0007 <jobbelle@gmx.net>
Co-authored-by: Slider0007 <115730895+Slider0007@users.noreply.github.com>
Co-authored-by: Antonin Delpeuch <antonin@delpeuch.eu>
2023-04-27 22:41:08 +02:00
CaCO3
fc719da0ae Update Changelog.md (#2360) 2023-04-27 22:34:04 +02:00
CaCO3
9b1a83c8b4 Fix alignment mark PSRAM issue (#2357)
* Add lock for shared PSRAM memory, use it for the relevant round steps and the Alignment Mark Task

* only allow taking a new image for the Alignment Mark while round got completed

* show success/denial of Alignment Mark Update Request

* .

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>
2023-04-27 22:30:12 +02:00
CaCO3
6defcf8d4c Update Changelog.md 2023-04-23 17:27:06 +02:00
CaCO3
c2a55e7c86 v15.2.0 (#2345)
* Testcase for #2145 and debug-log (#2151)

* new models ana-cont-11.0.5, ana-class100-1.5.7, dig-class100-1.6.0

* Testcase for #2145
Added debug log, if allowNegativeRates is handeled

* Fix timezone config parser (#2169)

* make sure to parse the whole config line

* fix crash on empty timezone parameter

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* Enhance ROI pages (#2161)

* Check if the ROIs are equidistant. Only if not, untick the checkbox

* renaming

* Check if the ROIs have same y, dy and dx. If so, tick the sync checkbox

* only allow editing space when box is checked

* fix sync check

* show inner frame on all ROIs

* cleanup

* Check if the ROIs have same dy and dx. If so, tick the sync checkbox

* checkbox position

* renaming

* renaming

* show inner frame and cross hairs on all ROIs

* update ROIs on ticking checkboxes

* show timezone hint

* fix deleting last ROI

* cleanup

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* restart timeout on progress, catch error (#2170)

* restart timeout on progress, catch error

* .

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* BugFix #2167

* Release 15.1 preparations (#2171)

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update changelog

* Fix links to PR

* Formating

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

---------

Co-authored-by: Slider0007 <jobbelle@gmx.net>
Co-authored-by: Slider0007 <115730895+Slider0007@users.noreply.github.com>

* fix typo

* Replace relative documentation links with absolute ones pointing to the external documentation (#2180)

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* Sort model files in configuration combobox (#2189)

* new models ana-cont-11.0.5, ana-class100-1.5.7, dig-class100-1.6.0

* Testcase for #2145
Added debug log, if allowNegativeRates is handeled

* Sort model files in combobox

* reboot task - increase stack size (#2201)

Avoid stack overflow

* Update interface_influxdb.cpp

* Update Changelog.md

* Show PSRAM usage (#2206)

* centralize PSRAM usage (application code only)

* update logging

* update logging

* fix use after free

* initialize buffer

* free rgb_image before ussing it for new allocation

* use wrapper function

* switch log level to debug

* .

* undo adding free() calls

* .

* add names to all CImage instances

* .

* .

* .

* revert changes of stbi_image_free() with free_psram_heap() on the places where is is not in PSRAM

* .

* typos

* typo

* Added MQTT Outbox explanation/warning

* added CONFIG_SPIRAM_USE_MEMMAP explanation

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* Disable custom MQTT Outbox. This also moves the MQTT Publishing memory usage back to the internal RAM!

* log MQTT connection refused reasons (#2216)

* Revert PSRAM usage as it lead to memory fragmentation.
See https://github.com/jomjol/AI-on-the-edge-device/issues/2200 for details

* fix missing value data

* Revert PSRAM usage as it lead to memory fragmentation. (#2224)

See https://github.com/jomjol/AI-on-the-edge-device/issues/2200 for details

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* Fix missing value data in graph (#2230)

* fix missing value data

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* Update Changelog.md (#2231)

* Update interface_influxdb.cpp (#2233)

* update copyright year

* Cleanup

* Set prevalue using MQTT + set prevalue to RAW value (REST+MQTT) (#2252)

* Use double instead of float

* Error handling + set to RAW if newvalue < 0

* REST SetPrevalue: Set to RAW if newvalue < 0

* set prevalue with MQTT

* removed the stb_image files and re-add them as a submodule. (#2223)

- stb_image.h: Version update 2.25 -> 2.28
- stb_resize.h: Version update 0.96 -> 0.97
- stb_write.h: Version update 1.14 -> 1.16

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* Remove obsolete ClassFlowWriteList (#2264)

* Renaming & cleanup of some modules / functions in source code (#2265)

* Rename module tag name

* Rename server_tflite.cpp -> MainFlowControl.cpp

* Remove redundandant MQTTMainTopic function

* Update

* Remove obsolete GetMQTTMainTopic

* Fix last element missing in digit model drop down (#2282)

* Debug influxdb (#2283)

* Fix time offset issues in InfluxDB component. (#2278)

Closes #2273
Closes #2150

* Update interface_influxdb.cpp

* Update interface_influxdb.cpp

* Improve Logging

* Implement TimeSync at beginning

* Update time_sntp.cpp

* Update time_sntp.cpp

* Set Time After WLAN Init

---------

Co-authored-by: Antonin Delpeuch <antonin@delpeuch.eu>

* Implement a camera livestream handler (#2286)

* fix leading NaN (#2310)

* analogROI: Activate save button after ROI creation (#2326)

* Migration of PlatformIO 5.2.0 to 6.1.0 (resp. ESP IDF from 4.4.2 to 5.0.1) (#2305)

* Migration to PlatformIO 6.1.0

* Disable RMTMEM usage as it is no longer allowed -> Smart LEDs not functional!

* moved miniz into subfolder of jomjol_fileserver_ota, else it does not build anymore.

* cleanup

* fix leading NaN (#2310)

* Migration to PlatformIO 6.1.0

* Disable RMTMEM usage as it is no longer allowed -> Smart LEDs not functional!

* moved miniz into subfolder of jomjol_fileserver_ota, else it does not build anymore.

* cleanup

* Task watchdog has new config name

* Fix return value check. It must be something else than ESP_FAIL, but it does not need to be ESP_OK!

* add missing strucures to work around new RMTMEM restriction (untested)

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* Keep MainFlowTask alive to handle reboot (#2325)

* Shared PSRAM memory (#2285)

* enable PSRAM logging

* add extra functions for psram shared memroy handling

* CImageBasis objects still should used dynamic memory (eg. rawImage), haw ever tmpImage must be placed inside the shared memory

* Place all STBI allocs inside the shared memory

* The models are placed in the shared PSRAM reagion and must be allocated through the dedicated functions

* .

* renaming

* fix cast warning

* add flag to switch STBI PSRAM usage

* improve PSRAM shared handling

* reserve shared PSRAM as early as possible

* init logging eralier so we can use it in PSRAM shared alloc

* move Wifi_LWIP, BSS_SEG and MQTT Outbox into PSRAM to ffree internal memory

* Check if model fits into reserved shared memory

* Update code/components/jomjol_tfliteclass/CTfLiteClass.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_flowcontroll/ClassFlowControll.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_image_proc/CImageBasis.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* .

* .

* .

* .

* Korrektur Merge Conflict in main.cpp

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>
Co-authored-by: jomjol <30766535+jomjol@users.noreply.github.com>

* fix PSRAM init return value check

* Extend InfluxDBv1 with individual topic names (#2319)

* Implement individual influx topic

* Update interface_influxdb.cpp

* Update interface_influxdb.cpp

* Update FieldName

* analogROI: Activate save button after ROI creation (#2326)

* Migration of PlatformIO 5.2.0 to 6.1.0 (resp. ESP IDF from 4.4.2 to 5.0.1) (#2305)

* Migration to PlatformIO 6.1.0

* Disable RMTMEM usage as it is no longer allowed -> Smart LEDs not functional!

* moved miniz into subfolder of jomjol_fileserver_ota, else it does not build anymore.

* cleanup

* fix leading NaN (#2310)

* Migration to PlatformIO 6.1.0

* Disable RMTMEM usage as it is no longer allowed -> Smart LEDs not functional!

* moved miniz into subfolder of jomjol_fileserver_ota, else it does not build anymore.

* cleanup

* Task watchdog has new config name

* Fix return value check. It must be something else than ESP_FAIL, but it does not need to be ESP_OK!

* add missing strucures to work around new RMTMEM restriction (untested)

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* Keep MainFlowTask alive to handle reboot (#2325)

* Shared PSRAM memory (#2285)

* enable PSRAM logging

* add extra functions for psram shared memroy handling

* CImageBasis objects still should used dynamic memory (eg. rawImage), haw ever tmpImage must be placed inside the shared memory

* Place all STBI allocs inside the shared memory

* The models are placed in the shared PSRAM reagion and must be allocated through the dedicated functions

* .

* renaming

* fix cast warning

* add flag to switch STBI PSRAM usage

* improve PSRAM shared handling

* reserve shared PSRAM as early as possible

* init logging eralier so we can use it in PSRAM shared alloc

* move Wifi_LWIP, BSS_SEG and MQTT Outbox into PSRAM to ffree internal memory

* Check if model fits into reserved shared memory

* Update code/components/jomjol_tfliteclass/CTfLiteClass.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_flowcontroll/ClassFlowControll.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_image_proc/CImageBasis.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* .

* .

* .

* .

* Korrektur Merge Conflict in main.cpp

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>
Co-authored-by: jomjol <30766535+jomjol@users.noreply.github.com>

* fix PSRAM init return value check

* Extend incl. indiv. Measurement

* Implement UX

* Update ClassFlowInfluxDBv2.cpp

* Implement individual influx topic

* Update interface_influxdb.cpp

* Update interface_influxdb.cpp

* Update FieldName

* Extend incl. indiv. Measurement

* Implement UX

* Update ClassFlowInfluxDBv2.cpp

* Update main.cpp

---------

Co-authored-by: Slider0007 <115730895+Slider0007@users.noreply.github.com>
Co-authored-by: CaCO3 <caco3@ruinelli.ch>
Co-authored-by: CaCO3 <caco@ruinelli.ch>

* Update Changelog.md (#2344)

* Update Changelog.md

* Update Changelog.md

* merge conflicts

* merge conflicts

* update changelog

---------

Co-authored-by: Frank Haverland <fspapaping@googlemail.com>
Co-authored-by: CaCO3 <caco@ruinelli.ch>
Co-authored-by: jomjol <30766535+jomjol@users.noreply.github.com>
Co-authored-by: Slider0007 <jobbelle@gmx.net>
Co-authored-by: Slider0007 <115730895+Slider0007@users.noreply.github.com>
Co-authored-by: Antonin Delpeuch <antonin@delpeuch.eu>
2023-04-23 17:13:18 +02:00
CaCO3
a636ce3679 update changelog 2023-04-23 16:58:25 +02:00
CaCO3
a20fec1094 merge conflicts 2023-04-23 16:50:04 +02:00
CaCO3
929796c87f merge conflicts 2023-04-23 16:45:20 +02:00
CaCO3
e40ceb54ce merge conflicts 2023-04-23 16:44:19 +02:00
CaCO3
eebdd7c6eb Update Changelog.md (#2344)
* Update Changelog.md

* Update Changelog.md
2023-04-23 16:37:12 +02:00
jomjol
2a7f3b33a3 Extend InfluxDBv1 with individual topic names (#2319)
* Implement individual influx topic

* Update interface_influxdb.cpp

* Update interface_influxdb.cpp

* Update FieldName

* analogROI: Activate save button after ROI creation (#2326)

* Migration of PlatformIO 5.2.0 to 6.1.0 (resp. ESP IDF from 4.4.2 to 5.0.1) (#2305)

* Migration to PlatformIO 6.1.0

* Disable RMTMEM usage as it is no longer allowed -> Smart LEDs not functional!

* moved miniz into subfolder of jomjol_fileserver_ota, else it does not build anymore.

* cleanup

* fix leading NaN (#2310)

* Migration to PlatformIO 6.1.0

* Disable RMTMEM usage as it is no longer allowed -> Smart LEDs not functional!

* moved miniz into subfolder of jomjol_fileserver_ota, else it does not build anymore.

* cleanup

* Task watchdog has new config name

* Fix return value check. It must be something else than ESP_FAIL, but it does not need to be ESP_OK!

* add missing strucures to work around new RMTMEM restriction (untested)

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* Keep MainFlowTask alive to handle reboot (#2325)

* Shared PSRAM memory (#2285)

* enable PSRAM logging

* add extra functions for psram shared memroy handling

* CImageBasis objects still should used dynamic memory (eg. rawImage), haw ever tmpImage must be placed inside the shared memory

* Place all STBI allocs inside the shared memory

* The models are placed in the shared PSRAM reagion and must be allocated through the dedicated functions

* .

* renaming

* fix cast warning

* add flag to switch STBI PSRAM usage

* improve PSRAM shared handling

* reserve shared PSRAM as early as possible

* init logging eralier so we can use it in PSRAM shared alloc

* move Wifi_LWIP, BSS_SEG and MQTT Outbox into PSRAM to ffree internal memory

* Check if model fits into reserved shared memory

* Update code/components/jomjol_tfliteclass/CTfLiteClass.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_flowcontroll/ClassFlowControll.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_image_proc/CImageBasis.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* .

* .

* .

* .

* Korrektur Merge Conflict in main.cpp

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>
Co-authored-by: jomjol <30766535+jomjol@users.noreply.github.com>

* fix PSRAM init return value check

* Extend incl. indiv. Measurement

* Implement UX

* Update ClassFlowInfluxDBv2.cpp

* Implement individual influx topic

* Update interface_influxdb.cpp

* Update interface_influxdb.cpp

* Update FieldName

* Extend incl. indiv. Measurement

* Implement UX

* Update ClassFlowInfluxDBv2.cpp

* Update main.cpp

---------

Co-authored-by: Slider0007 <115730895+Slider0007@users.noreply.github.com>
Co-authored-by: CaCO3 <caco3@ruinelli.ch>
Co-authored-by: CaCO3 <caco@ruinelli.ch>
2023-04-20 22:00:13 +02:00
CaCO3
262d83ee6f fix PSRAM init return value check 2023-04-19 21:55:01 +02:00
CaCO3
de92c29245 Shared PSRAM memory (#2285)
* enable PSRAM logging

* add extra functions for psram shared memroy handling

* CImageBasis objects still should used dynamic memory (eg. rawImage), haw ever tmpImage must be placed inside the shared memory

* Place all STBI allocs inside the shared memory

* The models are placed in the shared PSRAM reagion and must be allocated through the dedicated functions

* .

* renaming

* fix cast warning

* add flag to switch STBI PSRAM usage

* improve PSRAM shared handling

* reserve shared PSRAM as early as possible

* init logging eralier so we can use it in PSRAM shared alloc

* move Wifi_LWIP, BSS_SEG and MQTT Outbox into PSRAM to ffree internal memory

* Check if model fits into reserved shared memory

* Update code/components/jomjol_tfliteclass/CTfLiteClass.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_flowcontroll/ClassFlowControll.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_image_proc/CImageBasis.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* Update code/components/jomjol_helper/psram.cpp

* .

* .

* .

* .

* Korrektur Merge Conflict in main.cpp

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>
Co-authored-by: jomjol <30766535+jomjol@users.noreply.github.com>
2023-04-19 21:17:41 +02:00
Slider0007
19158c998f Keep MainFlowTask alive to handle reboot (#2325) 2023-04-19 20:50:49 +02:00
CaCO3
17ffd28c05 Migration of PlatformIO 5.2.0 to 6.1.0 (resp. ESP IDF from 4.4.2 to 5.0.1) (#2305)
* Migration to PlatformIO 6.1.0

* Disable RMTMEM usage as it is no longer allowed -> Smart LEDs not functional!

* moved miniz into subfolder of jomjol_fileserver_ota, else it does not build anymore.

* cleanup

* fix leading NaN (#2310)

* Migration to PlatformIO 6.1.0

* Disable RMTMEM usage as it is no longer allowed -> Smart LEDs not functional!

* moved miniz into subfolder of jomjol_fileserver_ota, else it does not build anymore.

* cleanup

* Task watchdog has new config name

* Fix return value check. It must be something else than ESP_FAIL, but it does not need to be ESP_OK!

* add missing strucures to work around new RMTMEM restriction (untested)

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>
2023-04-19 20:44:30 +02:00
Slider0007
9ca02e0a7f analogROI: Activate save button after ROI creation (#2326) 2023-04-17 23:50:03 +02:00
CaCO3
7488d7bf23 fix leading NaN (#2310) 2023-04-14 12:26:25 +02:00
Slider0007
e7bfba4b01 Implement a camera livestream handler (#2286) 2023-04-04 22:06:53 +02:00
jomjol
63ac38a52d Debug influxdb (#2283)
* Fix time offset issues in InfluxDB component. (#2278)

Closes #2273
Closes #2150

* Update interface_influxdb.cpp

* Update interface_influxdb.cpp

* Improve Logging

* Implement TimeSync at beginning

* Update time_sntp.cpp

* Update time_sntp.cpp

* Set Time After WLAN Init

---------

Co-authored-by: Antonin Delpeuch <antonin@delpeuch.eu>
2023-04-02 17:39:36 +02:00
Slider0007
e2cf8337d4 Fix last element missing in digit model drop down (#2282) 2023-04-01 23:27:54 +02:00
Slider0007
e995d6c498 Renaming & cleanup of some modules / functions in source code (#2265)
* Rename module tag name

* Rename server_tflite.cpp -> MainFlowControl.cpp

* Remove redundandant MQTTMainTopic function

* Update

* Remove obsolete GetMQTTMainTopic
2023-03-30 21:56:45 +02:00
Slider0007
0e3a50d0c1 Remove obsolete ClassFlowWriteList (#2264) 2023-03-30 21:55:28 +02:00
CaCO3
df12deae00 removed the stb_image files and re-add them as a submodule. (#2223)
- stb_image.h: Version update 2.25 -> 2.28
- stb_resize.h: Version update 0.96 -> 0.97
- stb_write.h: Version update 1.14 -> 1.16

Co-authored-by: CaCO3 <caco@ruinelli.ch>
2023-03-30 21:54:44 +02:00
Slider0007
b6bfeea936 Set prevalue using MQTT + set prevalue to RAW value (REST+MQTT) (#2252)
* Use double instead of float

* Error handling + set to RAW if newvalue < 0

* REST SetPrevalue: Set to RAW if newvalue < 0

* set prevalue with MQTT
2023-03-28 20:41:25 +02:00
jomjol
f79e03faa2 Cleanup 2023-03-26 11:33:52 +02:00
CaCO3
de1dcc4d06 update copyright year 2023-03-25 21:04:30 +01:00
CaCO3
33bfef0af4 Merge branch 'rolling' of https://github.com/jomjol/AI-on-the-edge-device into rolling 2023-03-25 21:02:34 +01:00
CaCO3
727b871fc5 Update interface_influxdb.cpp (#2233) 2023-03-24 15:49:47 +01:00
CaCO3
03c84a1ff3 Release 15.1.1 (#2232)
* Testcase for #2145 and debug-log (#2151)

* new models ana-cont-11.0.5, ana-class100-1.5.7, dig-class100-1.6.0

* Testcase for #2145
Added debug log, if allowNegativeRates is handeled

* Fix timezone config parser (#2169)

* make sure to parse the whole config line

* fix crash on empty timezone parameter

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* Enhance ROI pages (#2161)

* Check if the ROIs are equidistant. Only if not, untick the checkbox

* renaming

* Check if the ROIs have same y, dy and dx. If so, tick the sync checkbox

* only allow editing space when box is checked

* fix sync check

* show inner frame on all ROIs

* cleanup

* Check if the ROIs have same dy and dx. If so, tick the sync checkbox

* checkbox position

* renaming

* renaming

* show inner frame and cross hairs on all ROIs

* update ROIs on ticking checkboxes

* show timezone hint

* fix deleting last ROI

* cleanup

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* restart timeout on progress, catch error (#2170)

* restart timeout on progress, catch error

* .

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* BugFix #2167

* Release 15.1 preparations (#2171)

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update changelog

* Fix links to PR

* Formating

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

---------

Co-authored-by: Slider0007 <jobbelle@gmx.net>
Co-authored-by: Slider0007 <115730895+Slider0007@users.noreply.github.com>

* fix typo

* Replace relative documentation links with absolute ones pointing to the external documentation (#2180)

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* Sort model files in configuration combobox (#2189)

* new models ana-cont-11.0.5, ana-class100-1.5.7, dig-class100-1.6.0

* Testcase for #2145
Added debug log, if allowNegativeRates is handeled

* Sort model files in combobox

* reboot task - increase stack size (#2201)

Avoid stack overflow

* Update interface_influxdb.cpp

* Update Changelog.md

* Show PSRAM usage (#2206)

* centralize PSRAM usage (application code only)

* update logging

* update logging

* fix use after free

* initialize buffer

* free rgb_image before ussing it for new allocation

* use wrapper function

* switch log level to debug

* .

* undo adding free() calls

* .

* add names to all CImage instances

* .

* .

* .

* revert changes of stbi_image_free() with free_psram_heap() on the places where is is not in PSRAM

* .

* typos

* typo

* Added MQTT Outbox explanation/warning

* added CONFIG_SPIRAM_USE_MEMMAP explanation

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* Disable custom MQTT Outbox. This also moves the MQTT Publishing memory usage back to the internal RAM!

* log MQTT connection refused reasons (#2216)

* Revert PSRAM usage as it lead to memory fragmentation. (#2224)

See https://github.com/jomjol/AI-on-the-edge-device/issues/2200 for details

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* Fix missing value data in graph (#2230)

* fix missing value data

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* Update Changelog.md (#2231)

---------

Co-authored-by: Frank Haverland <fspapaping@googlemail.com>
Co-authored-by: CaCO3 <caco@ruinelli.ch>
Co-authored-by: jomjol <30766535+jomjol@users.noreply.github.com>
Co-authored-by: Slider0007 <jobbelle@gmx.net>
Co-authored-by: Slider0007 <115730895+Slider0007@users.noreply.github.com>
2023-03-23 21:38:43 +01:00
CaCO3
db36fe2522 Merge branch 'master' into rolling 2023-03-23 21:38:37 +01:00
CaCO3
9ffaf6e3f8 Update Changelog.md (#2231) 2023-03-23 21:37:30 +01:00
CaCO3
fa09680711 Fix missing value data in graph (#2230)
* fix missing value data

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>
2023-03-23 21:26:01 +01:00
CaCO3
e2b66aa73a Revert PSRAM usage as it lead to memory fragmentation. (#2224)
See https://github.com/jomjol/AI-on-the-edge-device/issues/2200 for details

Co-authored-by: CaCO3 <caco@ruinelli.ch>
2023-03-23 21:25:14 +01:00
CaCO3
c4b990ada0 fix missing value data 2023-03-23 21:24:15 +01:00
CaCO3
267782d083 Revert PSRAM usage as it lead to memory fragmentation.
See https://github.com/jomjol/AI-on-the-edge-device/issues/2200 for details
2023-03-22 23:27:55 +01:00
Slider0007
e4a6fd33fe log MQTT connection refused reasons (#2216) 2023-03-22 17:52:44 +01:00
CaCO3
5db20d3687 Disable custom MQTT Outbox. This also moves the MQTT Publishing memory usage back to the internal RAM! 2023-03-19 23:39:10 +01:00
CaCO3
58185a0569 Show PSRAM usage (#2206)
* centralize PSRAM usage (application code only)

* update logging

* update logging

* fix use after free

* initialize buffer

* free rgb_image before ussing it for new allocation

* use wrapper function

* switch log level to debug

* .

* undo adding free() calls

* .

* add names to all CImage instances

* .

* .

* .

* revert changes of stbi_image_free() with free_psram_heap() on the places where is is not in PSRAM

* .

* typos

* typo

* Added MQTT Outbox explanation/warning

* added CONFIG_SPIRAM_USE_MEMMAP explanation

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>
2023-03-19 23:28:06 +01:00
jomjol
b5e0d6ee66 Implement InfluxDBv1 and minor changes (#2211)
* Testcase for #2145 and debug-log (#2151)

* new models ana-cont-11.0.5, ana-class100-1.5.7, dig-class100-1.6.0

* Testcase for #2145
Added debug log, if allowNegativeRates is handeled

* Fix timezone config parser (#2169)

* make sure to parse the whole config line

* fix crash on empty timezone parameter

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* Enhance ROI pages (#2161)

* Check if the ROIs are equidistant. Only if not, untick the checkbox

* renaming

* Check if the ROIs have same y, dy and dx. If so, tick the sync checkbox

* only allow editing space when box is checked

* fix sync check

* show inner frame on all ROIs

* cleanup

* Check if the ROIs have same dy and dx. If so, tick the sync checkbox

* checkbox position

* renaming

* renaming

* show inner frame and cross hairs on all ROIs

* update ROIs on ticking checkboxes

* show timezone hint

* fix deleting last ROI

* cleanup

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* restart timeout on progress, catch error (#2170)

* restart timeout on progress, catch error

* .

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* BugFix #2167

* Release 15.1 preparations (#2171)

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update changelog

* Fix links to PR

* Formating

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

---------

Co-authored-by: Slider0007 <jobbelle@gmx.net>
Co-authored-by: Slider0007 <115730895+Slider0007@users.noreply.github.com>

* fix typo

* Replace relative documentation links with absolute ones pointing to the external documentation (#2180)

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* Sort model files in configuration combobox (#2189)

* new models ana-cont-11.0.5, ana-class100-1.5.7, dig-class100-1.6.0

* Testcase for #2145
Added debug log, if allowNegativeRates is handeled

* Sort model files in combobox

* reboot task - increase stack size (#2201)

Avoid stack overflow

* Update interface_influxdb.cpp

* Update Changelog.md

---------

Co-authored-by: Frank Haverland <fspapaping@googlemail.com>
Co-authored-by: CaCO3 <caco3@ruinelli.ch>
Co-authored-by: CaCO3 <caco@ruinelli.ch>
Co-authored-by: Slider0007 <jobbelle@gmx.net>
Co-authored-by: Slider0007 <115730895+Slider0007@users.noreply.github.com>
2023-03-19 18:31:01 +01:00
jomjol
d93c5daf14 Update Changelog.md 2023-03-19 18:26:41 +01:00
jomjol
6ff83445ac Merge branch 'correct-influxdbv1-bug' into rolling 2023-03-19 18:24:12 +01:00
jomjol
d944e8676b Update interface_influxdb.cpp 2023-03-19 17:54:48 +01:00
Slider0007
a8d7b29507 reboot task - increase stack size (#2201)
Avoid stack overflow
2023-03-17 07:46:40 +01:00
Frank Haverland
ab0fc72257 Sort model files in configuration combobox (#2189)
* new models ana-cont-11.0.5, ana-class100-1.5.7, dig-class100-1.6.0

* Testcase for #2145
Added debug log, if allowNegativeRates is handeled

* Sort model files in combobox
2023-03-14 22:57:00 +01:00
CaCO3
933215c116 Replace relative documentation links with absolute ones pointing to the external documentation (#2180)
Co-authored-by: CaCO3 <caco@ruinelli.ch>
2023-03-13 21:45:34 +01:00
CaCO3
e81a7eebe8 fix typo 2023-03-13 21:32:39 +01:00
CaCO3
7d33c3ee5f release 15.1.0 (#2172)
* Testcase for #2145 and debug-log (#2151)

* new models ana-cont-11.0.5, ana-class100-1.5.7, dig-class100-1.6.0

* Testcase for #2145
Added debug log, if allowNegativeRates is handeled

* Fix timezone config parser (#2169)

* make sure to parse the whole config line

* fix crash on empty timezone parameter

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* Enhance ROI pages (#2161)

* Check if the ROIs are equidistant. Only if not, untick the checkbox

* renaming

* Check if the ROIs have same y, dy and dx. If so, tick the sync checkbox

* only allow editing space when box is checked

* fix sync check

* show inner frame on all ROIs

* cleanup

* Check if the ROIs have same dy and dx. If so, tick the sync checkbox

* checkbox position

* renaming

* renaming

* show inner frame and cross hairs on all ROIs

* update ROIs on ticking checkboxes

* show timezone hint

* fix deleting last ROI

* cleanup

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* restart timeout on progress, catch error (#2170)

* restart timeout on progress, catch error

* .

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* BugFix #2167

* Release 15.1 preparations (#2171)

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update changelog

* Fix links to PR

* Formating

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

---------

Co-authored-by: Slider0007 <jobbelle@gmx.net>
Co-authored-by: Slider0007 <115730895+Slider0007@users.noreply.github.com>

---------

Co-authored-by: Frank Haverland <fspapaping@googlemail.com>
Co-authored-by: CaCO3 <caco@ruinelli.ch>
Co-authored-by: jomjol <30766535+jomjol@users.noreply.github.com>
Co-authored-by: Slider0007 <jobbelle@gmx.net>
Co-authored-by: Slider0007 <115730895+Slider0007@users.noreply.github.com>
2023-03-12 22:52:30 +01:00
CaCO3
863856ca5d Merge branch 'master' into rolling 2023-03-12 22:51:08 +01:00
CaCO3
eefc41d6ff Release 15.1 preparations (#2171)
* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update changelog

* Fix links to PR

* Formating

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

* Update Changelog.md

---------

Co-authored-by: Slider0007 <jobbelle@gmx.net>
Co-authored-by: Slider0007 <115730895+Slider0007@users.noreply.github.com>
2023-03-12 22:46:16 +01:00
jomjol
d1807a1b3d Merge branch 'rolling' of https://github.com/jomjol/AI-on-the-edge-device into rolling 2023-03-12 22:20:10 +01:00
jomjol
dfc45772b7 BugFix #2167 2023-03-12 22:19:30 +01:00
CaCO3
4dd41c486f restart timeout on progress, catch error (#2170)
* restart timeout on progress, catch error

* .

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>
2023-03-12 21:30:23 +01:00
CaCO3
ff81fcbd7f Enhance ROI pages (#2161)
* Check if the ROIs are equidistant. Only if not, untick the checkbox

* renaming

* Check if the ROIs have same y, dy and dx. If so, tick the sync checkbox

* only allow editing space when box is checked

* fix sync check

* show inner frame on all ROIs

* cleanup

* Check if the ROIs have same dy and dx. If so, tick the sync checkbox

* checkbox position

* renaming

* renaming

* show inner frame and cross hairs on all ROIs

* update ROIs on ticking checkboxes

* show timezone hint

* fix deleting last ROI

* cleanup

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>
2023-03-12 17:03:03 +01:00
CaCO3
5e5d2e2f72 Fix timezone config parser (#2169)
* make sure to parse the whole config line

* fix crash on empty timezone parameter

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>
2023-03-12 17:01:04 +01:00
jomjol
53cee961f4 Update Changelog.md 2023-03-11 21:32:14 +01:00
jomjol
c81f901a19 Merge branch 'master' of https://github.com/jomjol/AI-on-the-edge-device 2023-03-11 21:21:12 +01:00
Frank Haverland
512d7f95b4 Testcase for #2145 and debug-log (#2151)
* new models ana-cont-11.0.5, ana-class100-1.5.7, dig-class100-1.6.0

* Testcase for #2145
Added debug log, if allowNegativeRates is handeled
2023-03-11 11:19:29 +01:00
CaCO3
6642f6f995 Merge branch 'rolling' into master 2023-03-11 09:03:52 +01:00
Slider0007
431df73e52 Fix mqtt enable (#2144) 2023-03-08 17:42:43 +01:00
jomjol
1f5d4de5f3 Cleanup tflite (#2133)
* Clean & Update

* Update tflite
2023-03-06 07:14:21 +01:00
Slider0007
ce00192684 Print startblock after NTP snyc only once (#2129) 2023-03-05 19:14:45 +01:00
Yveaux
28f3ad0242 Update FeatureRequest.md (#2130)
Added #36 Run demo without camera
2023-03-05 17:37:51 +01:00
CaCO3
2dfd55e1c3 move Wifi, LWIP and BSSI to PSRAm (#2117)
Co-authored-by: CaCO3 <caco@ruinelli.ch>
2023-03-05 08:43:37 +01:00
CaCO3
f84f20b2e8 Set CPU frequency (#2125)
* move Wifi, LWIP and BSSI to PSRAm

* Allow setting the CPU frequency to 240 MHz (default: 160 MHz)

* .

* .

* .

* .

* Update sdkconfig.defaults

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>
2023-03-05 08:31:07 +01:00
CaCO3
806adcb4d0 Use PSRAM for MQTT publishing and make it scheduled (#2113)
* Run the Homeassistant Discovery directly after connecting to the broker. Before it was delayed 10s and happened while the first round alredy was in progress

* schedule sending HA discovery and static topics

* Allow setting QOS for MQTT topics

* .

* .

* change MQTT QOS1 expiration time from (default) 30 to 5s

* add logging of heap change on MQTT topic sendings

* wait for MQTT transmission timeout after publishing

* use QOS0 for Homeassistant Discovery topics. the messages then could possibly get lost but we save a lot of heap

* .

* use PSRAM for the MQTT outbox

* use QOS1 for HA discovery again

* .

* .

* disable delay, not needed with PSRAM

* .

* consolidated scheduledSendingOf_DiscoveryAndStaticTopics into sendingOf_DiscoveryAndStaticTopics_scheduled

* Send Homeasstsiatnt Discovery and static data in MQTT step instead of when the wifi gets connected

* "WIFI roaming" by channel scan (AP switching at low RSSI) (#2120)

* Activate 802.11kv wifi mesh roaming

* Activate roaming by scanning

* Revert stack reducation

* move Wifi, LWIP and BSSI to PSRAm

* added State Class "measurement" to rate_per_time_unit (#2116)

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* use QOS0 for Homeassistant Discovery topics. the messages then could possibly get lost but we save a lot of heap

* use QOS0 for Homeassistant Discovery topics. the messages then could possibly get lost but we save a lot of heap

# Conflicts:
#	code/components/jomjol_mqtt/server_mqtt.cpp

# Conflicts:
#	code/components/jomjol_mqtt/server_mqtt.cpp

* .

* .

* move to next PR

* Update code/components/jomjol_mqtt/server_mqtt.cpp

* Update code/components/jomjol_mqtt/server_mqtt.cpp

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>
Co-authored-by: Slider0007 <115730895+Slider0007@users.noreply.github.com>
2023-03-05 07:57:54 +01:00
Attila Darazs
4dc4752823 Add GJ (gigajoule) as an energy meter unit (#2114)
Some district heating meters are displaying their values in GJ and Home
Assistant is also capable of accepting heating values in this format.
2023-03-04 18:31:32 +01:00
CaCO3
827423023c added State Class "measurement" to rate_per_time_unit (#2116)
Co-authored-by: CaCO3 <caco@ruinelli.ch>
2023-03-04 13:16:23 +01:00
Slider0007
6ca7897fa0 "WIFI roaming" by channel scan (AP switching at low RSSI) (#2120)
* Activate 802.11kv wifi mesh roaming

* Activate roaming by scanning

* Revert stack reducation
2023-03-04 11:49:08 +01:00
CaCO3
39b8b5b07c updated log message 2023-03-02 20:44:21 +01:00
Slider0007
5b98acaa32 ImageQuality: Set low input limit to 8 (#2108) 2023-03-01 21:04:04 +01:00
Slider0007
d3d241c7b9 Logfile: Print start indication block after time sync (#2106)
* logfile: Print start indication after time sync

* No time set at boot -> keep log_1970-01-01.txt
2023-03-01 20:55:12 +01:00
CaCO3
8c7e86fea4 Master (#2104)
* Replace deprecated actions (#2016)

* Update build.yaml

* Update build.yaml

* Update manual-update-webinstaller.yml

* Update manual-update-webinstaller.yml

* Update manual-update-webinstaller.yml

* Update manual-update-webinstaller.yml

* Update build.yaml

* preparations for v15.0 (#2063)

* Migrated parameters, see https://github.com/jomjol/AI-on-the-edge-device/pull/2023

* remove no longer used "topic" parameter. This is a backport from b21e3c6c9d

* Fix wrong url-encoding, see https://github.com/jomjol/AI-on-the-edge-device/issues/2036 resp. https://github.com/jomjol/AI-on-the-edge-device/issues/2036

* Threashold -> Threshold

* updated changelog

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* DataLogActive is true by default

* updated changelog

* Bugfix #1933 (again :-))

* Update Influxdb

* re-add missing dropdownbox filling for Postprocessing Individual Parameters

* stop auto filling the release notes, it causes more confusion than it helps

* Update Changelog.md

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>
Co-authored-by: jomjol <30766535+jomjol@users.noreply.github.com>
2023-03-01 20:54:14 +01:00
CaCO3
98d85b2c6c Merge branch 'rolling' into master 2023-02-28 22:01:05 +01:00
CaCO3
f42e9c71f2 Update Changelog.md 2023-02-28 21:39:50 +01:00
CaCO3
00be21f9e1 stop auto filling the release notes, it causes more confusion than it helps 2023-02-28 21:37:30 +01:00
CaCO3
c694d9f363 re-add missing dropdownbox filling for Postprocessing Individual Parameters 2023-02-28 21:35:54 +01:00
CaCO3
a7dc37761b The raw topic should have no unit and must be State Class "None", so it is handled as a string (#2103)
Co-authored-by: CaCO3 <caco@ruinelli.ch>
2023-02-28 20:57:15 +01:00
Slider0007
2dd2d03f6c SD card basic R/W check + folder/file presence check (#2085)
* SD card basic RW check + folder structure check

* Default LED blink repeat 2x

* Abort booting when SD basic R/W check failed

* SD R/W error+missing folder,file > load reduced UI
2023-02-28 18:25:27 +01:00
jomjol
4c407499d2 Update Influxdb 2023-02-27 22:19:10 +01:00
jomjol
b97d808b54 Merge branch 'bugfix-influxdb-v15.0.1' 2023-02-27 21:55:38 +01:00
jomjol
9f2e91a9df Bugfix #1933 (again :-)) 2023-02-27 21:54:50 +01:00
jomjol
18e96d62a6 Update readconfigparam.js 2023-02-27 19:46:15 +01:00
CaCO3
a1a77ae5d9 Improve MQTT (#2091)
* moved functions

* use hostname as default MQTT maintopic if parameter is not set

* use hostname as default MQTT client ID

* Only send Homassistant Discovery and Static Topics on the first connect. Retry in next round if any topic failed

* .

* add missing return code usage

* send maintopic/connection on every round like the system topics

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>
2023-02-27 18:26:46 +01:00
Frank Haverland
c5b20f3680 new models ana-cont-11.0.5, ana-class100-1.5.7, dig-class100-1.6.0 (#2089) 2023-02-27 18:25:30 +01:00
CaCO3
add6cf5c33 catch empty values (#2096)
Co-authored-by: CaCO3 <caco@ruinelli.ch>
2023-02-27 14:38:46 +01:00
CaCO3
493bd4df2f use a plotly version which only provides the basics, see https://github.com/plotly/plotly.js/blob/master/dist/README.md#plotlyjs-basic (#2095)
Co-authored-by: CaCO3 <caco@ruinelli.ch>
2023-02-27 14:22:47 +01:00
CaCO3
53ff190860 enhance data pages (#2088)
* enhance data pages

* add checkbox to show relative values

* remove static entries, they get overwritten by dynamic oes

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>
2023-02-26 23:08:39 +01:00
CaCO3
9a9aa68a65 do not show value on recognition page (#2083)
* do not show value on recognition page

* .

* .

* .

* .

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>
2023-02-26 18:28:26 +01:00
CaCO3
a92cb69067 Fix missing number list (#2082)
* remove unused label references

* fix missing number list

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>
2023-02-25 22:03:16 +01:00
CaCO3
90fa44380c Migrate some UART logs to Logfile logs (#2079)
* repolaced ESP_LOGE() with LogFile.WriteToFile(ESP_LOG_ERROR()

* converted more UART logs to logfile logs

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>
2023-02-25 21:18:56 +01:00
Slider0007
7a9f61a8d8 Boot phase: Add more error handling + provide verbose output in error cases (#2020)
* WLAN: add error handling

* WLAN: parameter global struct

* WLAN.ini -> more info text

* RSSIThreshold

* Rename logs

* Boot process: error handling

* Update texts

* Comments

* Init sequence

* Prepare for check dir creation

* add check makedir, update logs

* Blink code for OTA+SoftAP

* Blink code for missing time snyc

* Update

* reboot -> switch LED off

* Update log texts

* Update

* Update log texts

* create empty default folders at startup

* Update

* Adapt log level

* Print log level switch

* Update

* Update text

* Add SD free space to log

* WIFI/MQTT disconnect message set to WARN (+ ERROR)
2023-02-25 21:12:52 +01:00
CaCO3
a8f8189543 Keep the html folder on a flast structure (no subfolders). Else the OTA fails until >15.0.x because it does not create the needed subfolders (#2080)
Co-authored-by: CaCO3 <caco@ruinelli.ch>
2023-02-25 18:27:43 +01:00
CaCO3
2c4bda9e66 Restructure webui menu (#2070)
Co-authored-by: CaCO3 <caco@ruinelli.ch>
2023-02-25 14:21:16 +01:00
CaCO3
7b2a80a13d Enhance pages (#2075)
* enhance pages

* .

* .

* .

* .

* .

* .

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>
2023-02-25 14:20:55 +01:00
CaCO3
95d312b920 Update Changelog.md 2023-02-24 20:23:20 +01:00
CaCO3
886cd4ffa5 Master (#2073)
* Replace deprecated actions (#2016)

* Update build.yaml

* Update build.yaml

* Update manual-update-webinstaller.yml

* Update manual-update-webinstaller.yml

* Update manual-update-webinstaller.yml

* Update manual-update-webinstaller.yml

* Update build.yaml

* preparations for v15.0 (#2063)

* Migrated parameters, see https://github.com/jomjol/AI-on-the-edge-device/pull/2023

* remove no longer used "topic" parameter. This is a backport from b21e3c6c9d

* Fix wrong url-encoding, see https://github.com/jomjol/AI-on-the-edge-device/issues/2036 resp. https://github.com/jomjol/AI-on-the-edge-device/issues/2036

* Threashold -> Threshold

* updated changelog

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>

* DataLogActive is true by default

* updated changelog

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>
2023-02-24 20:22:04 +01:00
CaCO3
10e0435383 Merge branch 'rolling'
# Conflicts:
#	Changelog.md
#	code/components/jomjol_helper/Helper.cpp
#	code/components/jomjol_helper/Helper.h
#	sd-card/html/edit_config_param.html
#	sd-card/html/readconfigparam.js
2023-02-24 20:19:45 +01:00
CaCO3
b0de37b762 Move parameter doc to use tooltips generated using the online documentation (#2059)
* prework

* add tooltips

* .

* Update build.yaml

* remove tooltip link and embed it directly

* embedd tooltip directly

* .

* .

* .

* .

* .

* .

* .

* .

* .

* .

* fix disabled tooltips

* fix disabled tooltips

* renamed Parameter in UI, added units, fixed labels

* .

* .

* .

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>
2023-02-24 18:36:26 +01:00
CaCO3
2c1a7f4c9e DataLogActive is true by default 2023-02-23 23:39:02 +01:00
CaCO3
3d711f495e updated save message 2023-02-22 23:20:52 +01:00
jomjol
b21e3c6c9d Remove ";Topic = ", Delete Checkbox "AllowNegativeRate" 2023-02-22 21:38:31 +01:00
CaCO3
23d2ae627d Update config.ini 2023-02-22 11:33:44 +01:00
CaCO3
3f62abf878 add missing config.ini entries for InfluxDBv2 2023-02-22 09:42:25 +01:00
CaCO3
025f4af9f2 V14.1 backport to rolling (#2058)
* Migrate parameters to v14.1 branch (#2023)

* Migrated parameters

* -

* .

* .

* .

* .

* .

* Remove unneeded checkboxes for true/false

* Remove ";"

* Correct MaintTopic

* Added missing parameters to UI: FlipImageSize, InitialMirror
Removed checkbox in UI for ErrorMessage
Added migration of pboolean parameters: enable them if they where disabled, set them to their default value, then enable them
Switch SetRetainFlag internally to a boolean

* .

* CamImages -> RawImages

* CamImages -> RawImages

* catch error on unknown parameter

* fix missing case insensitivity

* fix typo

* fixmissing rename

* fix migration of ExtendedResolution

* Delete ClassFlowMakeImage.cpp

* Delete ClassFlowMakeImage.h

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>
Co-authored-by: jomjol <30766535+jomjol@users.noreply.github.com>

* Update Changelog.md

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>
Co-authored-by: jomjol <30766535+jomjol@users.noreply.github.com>
2023-02-21 23:18:24 +01:00
CaCO3
3d92860c5e Updated web pages (#2055)
* allow longer file paths

* updated web pages

* updated the setup pages

* .

* Update server_file.cpp

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>
2023-02-21 22:35:50 +01:00
CaCO3
2ed9fb8eb5 Create folders as needed (#2056)
* allow longer file paths

* create folders as needed

---------

Co-authored-by: CaCO3 <caco@ruinelli.ch>
2023-02-21 22:14:09 +01:00
jomjol
598db004ae Update Changelog.md 2023-02-20 20:16:39 +01:00
jomjol
70332fe142 Update tflite 2023-02-20 20:03:39 +01:00
Slider0007
10da8c4f94 Support saturation & contrast (#2048)
* reference image: use correct value for contrast

* Update quality, contrast & saturation parameter

* fix for saturation,contrast+error handling
2023-02-19 21:15:16 +01:00
jomjol
5bac1c68d9 Correct BugFix in InfluxDB 2023-02-18 12:46:14 +01:00
jomjol
008dba7e11 fix for #2036 2023-02-18 11:44:56 +01:00
Yonz
7283bfd506 Update FeatureRequest.md (#2033)
Added:  #35 Use the same model, but provide the image from a Smartphone Camera
2023-02-16 21:05:34 +01:00
CaCO3
44e186e65b Update backup.html (#2015) 2023-02-11 21:45:08 +01:00
jomjol
55be652dc1 Update Changelog.md 2023-02-09 20:16:18 +01:00
jomjol
1acd72d33e Implement InfluxDB v2 (#2004)
* Implement InfluxDBv2 Innitial

* Update incl. UI

* Correct UI

* Update UI - Indiv. Param.

* Update edit_config_param.html

* Correct Timeshift

* Update Fieldname
2023-02-09 20:13:08 +01:00
jomjol
795bcd0d21 Merge branch 'InfluxDB-Fix-Timeshift' into rolling 2023-02-08 20:31:17 +01:00
jomjol
0b2e38935b Update Changelog.md 2023-02-08 20:29:01 +01:00
jomjol
a9c5bebb45 Update interface_influxdb.cpp 2023-02-08 19:56:28 +01:00
Joerg Rosenkranz
876adc51af Fix small typo (#1995) 2023-02-08 19:54:10 +01:00
CaCO3
bf090f3762 Update README.md 2023-02-07 23:13:11 +01:00
CaCO3
3fa16c5624 Use the preprocessed Web UI for the manual.zip (#1983)
* Update build.yaml

* Update build.yaml

* Update build.yaml
2023-02-05 15:31:04 +01:00
Slider0007
b9134f923e ota_page: Add missing quotation mark (#1977) 2023-02-05 08:10:59 +01:00
CaCO3
06f4d417b5 Cleanup config (#1972)
* Update config.ini

* Update config.ini

* Update config.ini
2023-02-05 08:10:29 +01:00
Slider0007
55efc3b3f4 wifi disconnect before deinit (#1978) 2023-02-05 08:09:53 +01:00
jomjol
800e231301 Update Changelog.md 2023-02-04 21:45:02 +01:00
jomjol
34a3d6d6e3 Merge branch 'Increase-max-JPG-size' into rolling 2023-02-04 21:38:37 +01:00
CaCO3
4bfe5422c5 fix broken webinstaller update 2023-02-03 21:46:08 +01:00
CaCO3
d63dc08f33 Update manual-update-webinstaller.yml 2023-02-03 21:43:40 +01:00
Slider0007
2ee85001eb Cleanup defines.h (#1967)
* Update defines.h

* Update: Disable USE_HIMEM_IF_AVAILABLE
2023-02-03 21:02:32 +01:00
Nicolas Liaudat
1d2f920819 Option alignment algo off (#1924)
* Update edit_config_param.html

* Update ClassFlowAlignment.cpp
2023-02-03 21:01:43 +01:00
jomjol
69583db99e Correct influx utc (#1964)
* Update interface_influxdb.cpp

* Correct to UTC
2023-02-02 19:14:55 +01:00
367 changed files with 32460 additions and 24295 deletions

View File

@@ -3,7 +3,32 @@
# Make sure to also add the response to .github/workflows/reply-bot.yml!
# Due to the way it works, you have to add each response twice, once for the issue, once for the discussions!
labels:
labels:
#######################################################################
# Bot Response: Documentation
#######################################################################
- name: bot-reply Documentation
labeled:
issue:
body: |
Please have a look on our documentation: https://jomjol.github.io/AI-on-the-edge-device-docs
discussion:
body: |
Please have a look on our documentation: https://jomjol.github.io/AI-on-the-edge-device-docs
#######################################################################
# Bot Response: ROI setup
#######################################################################
- name: bot-reply ROI Setup
labeled:
issue:
body: |
Make sure to setup your ROIs properly. Have a look on our documentation: https://jomjol.github.io/AI-on-the-edge-device-docs/ROI-Configuration/#how-to-setup-the-digit-rois-perfectly
discussion:
body: |
Make sure to setup your ROIs properly. Have a look on our documentation: https://jomjol.github.io/AI-on-the-edge-device-docs/ROI-Configuration/#how-to-setup-the-digit-rois-perfectly
#######################################################################
# Bot Response: Logfile
#######################################################################
@@ -90,9 +115,9 @@
labeled:
issue:
body: |
See [Digital Digits](https://jomjol.github.io/neural-network-digital-counter-readout) resp. [Analogue Pointers](https://jomjol.github.io/neural-network-analog-needle-readout) for an overview of all trained data.
See [Digits](https://jomjol.github.io/neural-network-digital-counter-readout) resp. [Analogue Pointers](https://jomjol.github.io/neural-network-analog-needle-readout) for an overview of all trained data.
If your type is not contained it can be added to our training material, see [here](https://jomjol.github.io/AI-on-the-edge-device-docs/collect-new-images/).
discussion:
body: |
See [Digital Digits](https://jomjol.github.io/neural-network-digital-counter-readout) resp. [Analogue Pointers](https://jomjol.github.io/neural-network-analog-needle-readout) for an overview of all trained data.
See [Digits](https://jomjol.github.io/neural-network-digital-counter-readout) resp. [Analogue Pointers](https://jomjol.github.io/neural-network-analog-needle-readout) for an overview of all trained data.
If your type is not contained it can be added to our training material, see [here](https://jomjol.github.io/AI-on-the-edge-device-docs/collect-new-images/).

View File

@@ -14,8 +14,8 @@ jobs:
uses: fkirc/skip-duplicate-actions@v5
with:
concurrent_skipping: same_content_newer
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
submodules: recursive
@@ -25,28 +25,28 @@ jobs:
echo "sha_short=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT
- name: Update PIP cache on every commit
uses: actions/cache@v3.2.3
uses: actions/cache@v4
with:
path: ~/.cache/pip
key: pip-${{ github.run_id }}
restore-keys: pip # This matches above key as it is only used as a prefix. it the restores the nearest cache, see https://github.com/restore-keys:/blob/main/tips-and-workarounds.md#update-a-cache
- name: Update PlatformIO cache on every commit
uses: actions/cache@v3.2.3
uses: actions/cache@v4
with:
path: ~/.platformio
key: platformio-${{ github.run_id }}
restore-keys: platformio # This matches above key as it is only used as a prefix. it the restores the nearest cache, see https://github.com/restore-keys:/blob/main/tips-and-workarounds.md#update-a-cache
- name: Update Build cache on every commit
uses: actions/cache@v3.2.3
uses: actions/cache@v4
with:
path: ./code/.pio/
key: build-${{ github.run_id }}
restore-keys: build # This matches above key as it is only used as a prefix. it the restores the nearest cache, see https://github.com/restore-keys:/blob/main/tips-and-workarounds.md#update-a-cache
- name: Update generated-files cache on every commit
uses: actions/cache@v3.2.3
uses: actions/cache@v4
with:
path: |
./code/.pio/build/esp32cam/firmware.bin
@@ -57,7 +57,7 @@ jobs:
restore-keys: generated-files # This matches above key as it is only used as a prefix. it the restores the nearest cache, see https://github.com/restore-keys:/blob/main/tips-and-workarounds.md#update-a-cache
- name: Set up Python
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: '3.10'
@@ -70,13 +70,22 @@ jobs:
#run: echo "Testing... ${{ github.ref_name }}, ${{ steps.vars.outputs.sha_short }}" > ./sd-card/html/version.txt; mkdir -p ./code/.pio/build/esp32cam/; cd ./code/.pio/build/esp32cam/; echo "${{ steps.vars.outputs.sha_short }}" > firmware.bin; cp firmware.bin partitions.bin; cp firmware.bin bootloader.bin # Testing
run: cd code; platformio run --environment esp32cam
- name: Prepare Web UI (copy data from repo and update hashes in all files)
- name: Prepare Web UI (generate tooltip pages and update hashes in all files)
run: |
rm -rf ./html
mkdir html
cp ./sd-card/html/* ./html/
cp -r ./sd-card/html/* ./html/
python -m pip install markdown
mkdir html/param-tooltips
cd tools/parameter-tooltip-generator
python generate-param-doc-tooltips.py
cd ../..
cp -r ./sd-card/html/* ./html/
echo "Replacing variables..."
cd html; find . -type f -exec sed -i 's/$COMMIT_HASH/${{ steps.vars.outputs.sha_short }}/g' {} \;
#########################################################################################
@@ -86,16 +95,16 @@ jobs:
# New OTA concept
# update__version.zip file with following content:
# - /firmware.bin
# - (optional) /html/*
# - (optional) /html/* (inkl. subfolders)
# - (optional) /config/*.tfl
runs-on: ubuntu-latest
needs: build
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Update generated-files cache on every commit
uses: actions/cache@v3.2.3
uses: actions/cache@v4
with:
path: |
./code/.pio/build/esp32cam/firmware.bin
@@ -106,12 +115,12 @@ jobs:
restore-keys: generated-files # This matches above key as it is only used as a prefix. it the restores the nearest cache, see https://github.com/restore-keys:/blob/main/tips-and-workarounds.md#update-a-cache
- name: Update update cache on every commit
uses: actions/cache@v3.2.3
uses: actions/cache@v4
with:
path: update
key: update-${{ github.run_id }}
restore-keys: update # This matches above key as it is only used as a prefix. it the restores the nearest cache, see https://github.com/restore-keys:/blob/main/tips-and-workarounds.md#update-a-cache
- name: Set Variables
id: vars
run: |
@@ -135,13 +144,12 @@ jobs:
cp ./sd-card/config/*.tflite ./update/config/ 2>/dev/null || true
- name: Upload update as update.zip artifact (Firmware + Web UI + CNN)
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: "AI-on-the-edge-device__update__${{ steps.vars.outputs.branch }}_(${{ steps.vars.outputs.sha_short }})"
path: ./update/*
#########################################################################################
## Pack for Remote Setup
#########################################################################################
@@ -149,16 +157,16 @@ jobs:
# New Remote Setup concept
# remote_setup__version.zip file with following content:
# - /firmware.bin
# - /html/*
# - /html/* (inkl. subfolders)
# - /config/*
runs-on: ubuntu-latest
needs: build
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Update generated-files cache on every commit
uses: actions/cache@v3.2.3
uses: actions/cache@v4
with:
path: |
./code/.pio/build/esp32cam/firmware.bin
@@ -167,9 +175,9 @@ jobs:
./html/*
key: generated-files-${{ github.run_id }}
restore-keys: generated-files # This matches above key as it is only used as a prefix. it the restores the nearest cache, see https://github.com/restore-keys:/blob/main/tips-and-workarounds.md#update-a-cache
- name: Update remote_setup cache on every commit
uses: actions/cache@v3.2.3
uses: actions/cache@v4
with:
path: remote_setup
key: remote_setup-${{ github.run_id }}
@@ -196,7 +204,7 @@ jobs:
cp ./sd-card/config/* ./remote_setup/config/ 2>/dev/null || true
- name: Upload remote_setup as remote_setup.zip artifact (Firmware + Web UI + Config)
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: "AI-on-the-edge-device__remote-setup__${{ steps.vars.outputs.branch }}_(${{ steps.vars.outputs.sha_short }})"
path: ./remote_setup/*
@@ -211,10 +219,10 @@ jobs:
needs: build
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Update generated-files cache on every commit
uses: actions/cache@v3.2.3
uses: actions/cache@v4
with:
path: |
./code/.pio/build/esp32cam/firmware.bin
@@ -225,7 +233,7 @@ jobs:
restore-keys: generated-files # This matches above key as it is only used as a prefix. it the restores the nearest cache, see https://github.com/restore-keys:/blob/main/tips-and-workarounds.md#update-a-cache
- name: Update manual_setup cache on every commit
uses: actions/cache@v3.2.3
uses: actions/cache@v4
with:
path: manual_setup
key: manual_setup-${{ github.run_id }}
@@ -252,9 +260,9 @@ jobs:
cp -r ./html ./sd-card/ # Overwrite the Web UI with the preprocessed files
cd sd-card; zip -r ../manual_setup/sd-card.zip *; cd ..
cd ./manual_setup
- name: Upload manual_setup.zip artifact (Firmware + Bootloader + Partitions + Web UI)
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: "AI-on-the-edge-device__manual-setup__${{ steps.vars.outputs.branch }}_(${{ steps.vars.outputs.sha_short }})"
path: ./manual_setup
@@ -275,24 +283,24 @@ jobs:
id-token: write
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Update update cache on every commit
uses: actions/cache@v3.2.3
uses: actions/cache@v4
with:
path: update
key: update-${{ github.run_id }}
restore-keys: update # This matches above key as it is only used as a prefix. it the restores the nearest cache, see https://github.com/restore-keys:/blob/main/tips-and-workarounds.md#update-a-cache
- name: Update remote_setup cache on every commit
uses: actions/cache@v3.2.3
uses: actions/cache@v4
with:
path: remote_setup
key: remote_setup-${{ github.run_id }}
restore-keys: remote_setup # This matches above key as it is only used as a prefix. it the restores the nearest cache, see https://github.com/restore-keys:/blob/main/tips-and-workarounds.md#update-a-cache
- name: Update manual_setup cache on every commit
uses: actions/cache@v3.2.3
uses: actions/cache@v4
with:
path: manual_setup
key: manual_setup-${{ github.run_id }}
@@ -323,34 +331,30 @@ jobs:
# extract the version used in next step
- id: get_version
if: startsWith(github.ref, 'refs/tags/')
uses: Simply007/get-version-action@v2
uses: dhkatz/get-version-action@v3.0.0
# # the changelog [unreleased] will now be changed to the release version
# - name: Update changelog
# uses: thomaseizinger/keep-a-changelog-new-release@v1
# if: startsWith(github.ref, 'refs/tags/')
# with:
# changelogPath: Changelog.md
# version: ${{ steps.get_version.outputs.version-without-v }}
# the release notes will be extracted from changelog
- name: Extract release notes
id: extract-release-notes
if: startsWith(github.ref, 'refs/tags/')
uses: ffurrer2/extract-release-notes@v1
with:
changelog_file: Changelog.md
# # the release notes will be extracted from changelog
# - name: Extract release notes
# id: extract-release-notes
# uses: ffurrer2/extract-release-notes@v1
# with:
# changelog_file: Changelog.md
# Releases should only be created on master by tagging the last commit.
# all artifacts in firmware folder pushed to the release
- name: Release
uses: softprops/action-gh-release@v1
uses: softprops/action-gh-release@v2.0.8
# Note:
# If you get the error "Resource not accessible by integration",
# The access rights are not sufficient, see
# https://github.com/softprops/action-gh-release/issues/232#issuecomment-1131379440
if: startsWith(github.ref, 'refs/tags/')
with:
name: ${{ steps.get_version.outputs.version-without-v }}
body: ${{ steps.extract-release-notes.outputs.release_notes }}
@@ -359,7 +363,6 @@ jobs:
# # Commit&Push Changelog to master branch. Must be manually merged back to rolling
# - name: Commit changes and push changes
# if: startsWith(github.ref, 'refs/tags/')
# run: |
# git config user.name github-actions
# git config user.email github-actions@github.com
@@ -371,8 +374,9 @@ jobs:
#########################################################################################
## Update the Web Installer on a release
#########################################################################################
# This is the same as in the update-webinstaller.yml
update-web-installer:
# Make sure to also update update-webinstaller.yml!
update-web-installer:
if: github.event_name == 'release' && github.event.action == 'published' # Only run on release but not on prerelease
needs: [release]
environment:
name: github-pages
@@ -387,8 +391,8 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Get version of last release
id: last_release
uses: mindojo/get-latest-release@0b8ef1434d7468d6bffcc8263baff5c777f72321
@@ -396,23 +400,26 @@ jobs:
myToken: ${{ github.token }}
exclude_types: "draft|prerelease"
view_top: 1
- name: Add binary to Web Installer and update manifest
run: |
echo "Updating Web installer to use firmware from ${{ steps.last_release.outputs.tag_name }}..."
rm -f docs/binary/firmware.bin
wget https://github.com/jomjol/AI-on-the-edge-device/releases/download/${{ steps.last_release.outputs.tag_name }}/AI-on-the-edge-device__update__${{ steps.last_release.outputs.tag_name }}.zip
wget ${{ github.server_url }}/${{ github.repository }}/releases/download/${{ steps.last_release.outputs.tag_name }}/AI-on-the-edge-device__update__${{ steps.last_release.outputs.tag_name }}.zip
unzip AI-on-the-edge-device__update__${{ steps.last_release.outputs.tag_name }}.zip
cp -f firmware.bin docs/binary/firmware.bin
cp -f docs/manifest_template.json docs/manifest.json
sed -i 's/VERSION/${{ steps.last_release.outputs.tag_name }}/g' docs/manifest.json
echo "Updating index and manifest file..."
sed -i 's/$VERSION/${{ steps.last_release.outputs.tag_name }}/g' docs/index.html
sed -i 's/$VERSION/${{ steps.last_release.outputs.tag_name }}/g' docs/manifest.json
- name: Setup Pages
uses: actions/configure-pages@v2
uses: actions/configure-pages@v4
- name: Upload artifact
uses: actions/upload-pages-artifact@v1
uses: actions/upload-pages-artifact@v2
with:
path: 'docs'
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v1
uses: actions/deploy-pages@v3 # Note: v4 does not work!

View File

@@ -1,7 +1,7 @@
# This updates the Web Installer with the files from the docs folder and the binary of the latest release
# it only gets run on:
# - Changes to the docs folder in the `rolling` branch
# - On a release
# - Manually triggered
# Make sure to also update the lower part of build.yml!
name: Manual Web Installer Update
@@ -12,7 +12,7 @@ on:
# - rolling
# paths:
# - docs # The path filter somehow does not work, so lets run it on every change to rolling
jobs:
manually-update-web-installer:
environment:
@@ -29,7 +29,7 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Get version of last release
id: last_release
uses: mindojo/get-latest-release@0b8ef1434d7468d6bffcc8263baff5c777f72321
@@ -37,15 +37,17 @@ jobs:
myToken: ${{ github.token }}
exclude_types: "draft|prerelease"
view_top: 1
- name: Add binary to Web Installer and update manifest
run: |
echo "Updating Web installer to use firmware from ${{ steps.last_release.outputs.tag_name }}..."
rm -f docs/binary/firmware.bin
wget https://github.com/jomjol/AI-on-the-edge-device/releases/download/${{ steps.last_release.outputs.tag_name }}/AI-on-the-edge-device__update__${{ steps.last_release.outputs.tag_name }}.zip
unzip AI-on-the-edge-device__update__${{ steps.last_release.outputs.tag_name }}.zip
cp -f firmware.bin docs/binary/firmware.bin
cp -f docs/manifest_template.json docs/manifest.json
sed -i 's/VERSION/${{ steps.last_release.outputs.tag_name }}/g' docs/manifest.json
echo "Updating index and manifest file..."
sed -i 's/$VERSION/${{ steps.last_release.outputs.tag_name }}/g' docs/index.html
sed -i 's/$VERSION/${{ steps.last_release.outputs.tag_name }}/g' docs/manifest.json
- name: Setup Pages
uses: actions/configure-pages@v2
@@ -58,4 +60,3 @@ jobs:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v1

View File

@@ -1,5 +1,5 @@
# Reply Bot
# It uses the configuration in .github/label-commenter-config.yml
# It uses the configuration in .github/label-commenter-config.yaml
# See https://github.com/peaceiris/actions-label-commenter
name: Reply-Bot
@@ -20,12 +20,11 @@ jobs:
comment:
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
####################################################################
## Remove labels again (issues only)
## Make sure to also add the reply message to .github/label-commenter-config.yml!
## Make sure to also add the reply message to .github/label-commenter-config.yaml!
## This currently seems no longer to work due to changes on the actions-cool/issues-helper!
####################################################################
# - name: Remove 'Logfile' label again (issues only)
@@ -69,11 +68,12 @@ jobs:
# with:
# actions: 'remove-labels'
# labels: 'bot-reply Show Trained Digits/Pointers'
####################################################################
## Write the response
####################################################################
- name: Write Response
uses: peaceiris/actions-label-commenter@c2d00660c86f2b9ed0fb35b372c451558eba85b3
with:
repo-token: "${{ secrets.GITHUB_TOKEN }}"
github_token: "${{ secrets.GITHUB_TOKEN }}"
config_file: .github/label-commenter-config.yaml

2
.gitignore vendored
View File

@@ -23,3 +23,5 @@ CTestTestfile.cmake
_deps
code/edgeAI.code-workspace
.DS_Store
tools/parameter-tooltip-generator/html
tools/parameter-tooltip-generator/AI-on-the-edge-device-docs

9
.gitmodules vendored
View File

@@ -4,6 +4,9 @@
[submodule "code/components/esp-nn"]
path = code/components/esp-nn
url = https://github.com/espressif/esp-nn.git
[submodule "code/components/tflite-micro-esp-examples"]
path = code/components/tflite-micro-esp-examples
url = https://github.com/espressif/tflite-micro-esp-examples.git
[submodule "code/components/esp-tflite-micro"]
path = code/components/esp-tflite-micro
url = https://github.com/espressif/esp-tflite-micro.git
[submodule "code/components/stb"]
path = code/components/stb
url = https://github.com/nothings/stb.git

View File

@@ -1,11 +1,283 @@
## [15.0.1] - 2023-02-23
## [16.0.0-RC2] - 2024-10-04
**Parameter Migration**
For a full list of changes see [Full list of changes](https://github.com/jomjol/AI-on-the-edge-device/compare/v15.7.0...v16.0.0-RC1)
#### Known issues
Please check the [issues](https://github.com/jomjol/AI-on-the-edge-device/issues) and
[discussions](https://github.com/jomjol/AI-on-the-edge-device/discussions) before reporting a new issue.
#### Core Changes
Only changes since RC1 are listed:
- Updated parameter documentation pages
- Rename/remove unused parameters (#3291)
- Migrate-cam-parameters (#3288)
#### Bug Fixes
Only changes since RC1 are listed:
- Reverted TFlite submodule update as certain modules crash with it (#3269)
- Changed the webhook UploadImg to false (#3279)
- Changed default value from boolean to numeric value in parameter camDenoise documentation
- Updated config page
## [16.0.0-RC1] - 2024-09-24
For a full list of changes see [Full list of changes](https://github.com/jomjol/AI-on-the-edge-device/compare/v15.7.0...v16.0.0-RC1)
#### Known issues
Please check the [issues](https://github.com/jomjol/AI-on-the-edge-device/issues) and
[discussions](https://github.com/jomjol/AI-on-the-edge-device/discussions) before reporting a new issue.
#### Core Changes
Those are just the major changes:
- Add support for OV5640 camera (#3063)
- New tflite-Models
- Homeassistant service discovery: derive node_id when using nested topics (#3088)
- Added Prometheus/OpenMetrics exporter (#3081)
- Added Webhook (#3148, #3163, #3174)
- Add rate threshold parameter (#3195)
- Added a Delay between the WiFi reconnections (#3068)
- Web UI improvements
- Various minor changes
- Update platformIO to 6.9.0 (Contains ESP IDF 5.3.1)
#### Bug Fixes
Those are just the major changes:
- Handle crash on corrupted model (#3220)
- Bugfix for boot loop (#3175)
- Bugfix for time stamp (#3180)
- Handle empty prevalue.ini gracefully (#3162)
- Added note about only TLS 1.2 is supported (#3213)
## [15.7.0] - 2024-02-17
For a full list of changes see [Full list of changes](https://github.com/jomjol/AI-on-the-edge-device/compare/v15.6.0...v15.7.0)
#### Core Changes
- Added new camera settings (See `Settings > Alignment > Reference Image and Camera Settings`). You might need to re-create the reference image and alignment marks. Note worthy:
- You can now crop the image
- Support to configure sharpness, grayscale, negatoive and exposure
- Enhanced various WebUI pages with better explanations and usability
- Add Firmware Version to MQTT
#### Bug Fixes
- Reverted "Implemented late analog / digit transition [#2778](https://github.com/jomjol/AI-on-the-edge-device/pull/2778) (introduced in `v15.5`) as is seems to cause issues for many users.
## [15.6.0] - 2024-02-09
For a full list of changes see [Full list of changes](https://github.com/jomjol/AI-on-the-edge-device/compare/v15.5.0...v15.6.0)
#### Fixed
* Fixed issues with the SD-Card initialization
## [15.5.0] - 2024-02-02
For a full list of changes see [Full list of changes](https://github.com/jomjol/AI-on-the-edge-device/compare/v15.4.0...v15.5.0)
#### Changed
- Update PlattformIO to v6.5.0, which means esp-idf to v5.1
- Enhance busy notification
- Implemented late analog / digit transition
#### Fixed
* ATA-TRIM: workaround for old SD-cards with no trim function to work with esp-idf v5.x
* InfluxDB: Modified the time conversions to be more stable (UTC vs. local time shifts)
* Fix negatives on extended resolution false
* Show chip infos on info page
* Fix memory leaks in tflite integration
## [15.4.0] - 2023-12-22
For a full list of changes see [Full list of changes](https://github.com/jomjol/AI-on-the-edge-device/compare/v15.3.0...v15.4.0)
#### Changed
- Updates submodules (esp-nn, tflite-micro-example, esp-camera)
- Explicitly included needed tflite network layers (instead of all) , resulting in much smaller firmware size
- Added shortcut icon
- Rename in InfluxDB 'Database' to 'Bucket'
- Updated analog tflite files
- dig-class100-0167_s2_q.tflite
- dig-class11_1700_s2.tflite
- ana-cont_1208_s2_q.tflite
- Added config entries for MQTT TLS
#### Fixed
* InfluxDB: consider DST setting for UTC time conversion
* Minor html response bugfix
- Memory leakage (MQTT)
## [15.3.0] - 2023-07-22
For a full list of changes see [Full list of changes](https://github.com/jomjol/AI-on-the-edge-device/compare/v15.3.0...v15.2.4)
#### Changed
- Updated PlatformIO to `6.3.2`
- Updated analog tflite files
- ana-cont_1207_s2_q.tflite
- dig-cont_0620_s3_q.tflite
## [15.2.4] - 2023-05-02
For a full list of changes see [Full list of changes](https://github.com/jomjol/AI-on-the-edge-device/compare/v15.2.1...v15.2.4)
#### Changed
- Updated PlatformIO to `6.2.0`
- [#2376](https://github.com/jomjol/AI-on-the-edge-device/pull/2376) Improve logging if Autostart is not enabled
#### Fixed
- [#2373](https://github.com/jomjol/AI-on-the-edge-device/pull/2373) Allow the Alignment Mark step while status is "Initializing" or "Initialization (delayed)" or while in setup mode
- [#2381](https://github.com/jomjol/AI-on-the-edge-device/pull/2381) Fix broken sysinfo REST API
## [15.2.1] - 2023-04-27
### Changes
For a full list of changes see [Full list of changes](https://github.com/jomjol/AI-on-the-edge-device/compare/v15.2.0...v15.2.1)
#### Fixed
- [#2357](https://github.com/jomjol/AI-on-the-edge-device/pull/2357) Fix Alignment Mark issue
## [15.2.0] - 2023-04-23
For a full list of changes see [Full list of changes](https://github.com/jomjol/AI-on-the-edge-device/compare/v15.1.1...v15.2.0)
#### Added
- [#2286](https://github.com/jomjol/AI-on-the-edge-device/pull/2286) Implement a camera livestream handler
- [#2252](https://github.com/jomjol/AI-on-the-edge-device/pull/2252) Set prevalue using MQTT + set prevalue to RAW value (REST+MQTT)
- [#2319](https://github.com/jomjol/AI-on-the-edge-device/pull/2319) Extend InfluxDBv1 with individual topic names
#### Changed
- [#2285](https://github.com/jomjol/AI-on-the-edge-device/pull/2285) Re-implemented PSRAM usage
- [#2325](https://github.com/jomjol/AI-on-the-edge-device/pull/2325) Keep MainFlowTask alive to handle reboot
- [#2233](https://github.com/jomjol/AI-on-the-edge-device/pull/2233) Remove trailing slash in influxDBv1
- [#2305](https://github.com/jomjol/AI-on-the-edge-device/pull/2305) Migration of PlatformIO `5.2.0` to `6.1.0` (resp. ESP IDF from `4.4.2` to `5.0.1`)
- Various cleanup and refactoring
#### Fixed
- [#2326](https://github.com/jomjol/AI-on-the-edge-device/pull/2326) Activate save button after Analogue ROI creationSet prevalue using MQTT + set prevalue to RAW value (REST+MQTT)
- [#2283](https://github.com/jomjol/AI-on-the-edge-device/pull/2283) Fix Timezone issues on InfluxDB
- Various minor fixes
#### Removed
- n.a.
## [15.1.1] - 2023-03-23
For a full list of changes see [Full list of changes](https://github.com/jomjol/AI-on-the-edge-device/compare/v15.1.0...v15.1.1)
#### Added
- [#2206](https://github.com/jomjol/AI-on-the-edge-device/pull/2206) Log PSRAM usage
- [#2216](https://github.com/jomjol/AI-on-the-edge-device/pull/2216) Log MQTT connection refused reasons
#### Changed
- n.a.
#### Fixed
- [#2224](https://github.com/jomjol/AI-on-the-edge-device/pull/2224), [#2213](https://github.com/jomjol/AI-on-the-edge-device/pull/2213) Reverted some of the PSRAM usage changes due to negative sideffects
- [#2203](https://github.com/jomjol/AI-on-the-edge-device/issues/2203) Correct API for pure InfluxDB v1
- [#2180](https://github.com/jomjol/AI-on-the-edge-device/pull/2180) Fixed links in Parameter Documentation
- Various minor fixes
#### Removed
- n.a.
## [15.1.0] - 2023-03-12
### Update Procedure
Update Procedure see [online documentation](https://jomjol.github.io/AI-on-the-edge-device-docs/Installation/#update-ota-over-the-air)
:bangbang: Afterwards you should force-reload the Web Interface (usually Ctrl-F5 will do it)!
:bangbang: Afterwards you should check your configuration for errors!
### Changes
For a full list of changes see [Full list of changes](https://github.com/jomjol/AI-on-the-edge-device/compare/v15.0.3...v15.1.0)
#### Added
- The Configuration page has now tooltips with enhanced documentation
- MQTT:
- Added `GJ` (`gigajoule`) as an energy meter unit
- Removed State Class and unit from `raw` topic
- Various Improvements (Only send Homeassistant Discovery the first time we connect, ...) (https://github.com/jomjol/AI-on-the-edge-device/pull/2091
- Added Expert Parameter to change CPU Clock from `160` to `240 Mhz`
- SD card basic read/write check and a folder/file presence check at boot to indicate SD card issues or missing folders / files ([#2085](https://github.com/jomjol/AI-on-the-edge-device/pull/2085))
- Simplified "WIFI roaming" by client triggered channel scan (AP switching at low RSSI) -> using expert parameter "RSSIThreshold" ([#2120](https://github.com/jomjol/AI-on-the-edge-device/pull/2120))
- Log WLAN disconnect reason codes (see [WLAN disconnect reasons](https://jomjol.github.io/AI-on-the-edge-device-docs/WLAN-disconnect-reason))
- Support of InfluxDB v2 ([#2004](https://github.com/jomjol/AI-on-the-edge-device/pull/2004))
#### Changed
- Updated models (tflite files), removed old versions (https://github.com/jomjol/AI-on-the-edge-device/pull/2089, https://github.com/jomjol/AI-on-the-edge-device/pull/2133)
:bangbang: **Attention:** Update your configuration!
- Hybrid CNN network to `dig-cont_0611_s3`
- Analog CNN network to `ana-cont-11.0.5` and `ana-clas100-1.5.7`
- Digit CNN network to `dig-class100-1.6.0`
- Various Web interface Improvements/Enhancements:
- Restructured Menu (Needs cache clearing to be applied)
- Enhanced `Previous Value` page
- Improved/faster Graph page
- Various minor improvements
- ROI config pages improvements
- Improved Backup Functionality
- Added log file logs for Firmware Update
- Improved memory management (moved various stuff to external PSRAM, https://github.com/jomjol/AI-on-the-edge-device/pull/2117)
- Camera driver update: Support of contrast and saturation ([#2048](https://github.com/jomjol/AI-on-the-edge-device/pull/2048))
:bangbang: **Attention**: This could have impact to old configurations. Please check your configuration and potentially adapt parametrization, if detection is negativly affected.
- Improved error handling and provide more verbose output in error cases during boot phase ([#2020](https://github.com/jomjol/AI-on-the-edge-device/pull/2020))
- Red board LED is indicating more different errors and states (see [Status LED Blink Codes](https://jomjol.github.io/AI-on-the-edge-device-docs/StatusLED-BlinkCodes))
- Logfile: Print start indication block after time is synced to indicate start in logfile after a cold boot
- `Image Quality Index`: Limit lower input range to 8 to avoid system instabilities
#### Fixed
- Various minor fixes
- Added State Class "measurement" to rate_per_time_unit
- GPIO: Avoid MQTT publishing to empty topic when "MQTT enable" flag is not set
- Fix timezone config parser
- Remote Setup truncated long passwords (https://github.com/jomjol/AI-on-the-edge-device/issues/2167)
- Problem with timestamp in InfluxDB interface
#### Removed
- n.a.
## [15.0.3] - 2023-02-28
**Name: Parameter Migration**
### Update Procedure
Update Procedure see [online documentation](https://jomjol.github.io/AI-on-the-edge-device-docs/Installation/#update-ota-over-the-air)
:bangbang: Afterwards you should force-reload the Web Interface (usually Ctrl-F5 will do it).
### Changes
This release only migrates some parameters, see #2023 for details and a list of all parameter changes.
@@ -27,15 +299,18 @@ If you want to revert back to `v14` or earlier, you will have to revert the migr
#### Fixed
- [2036](https://github.com/jomjol/AI-on-the-edge-device/issues/2036) Fix wrong url-encoding
- [#2036](https://github.com/jomjol/AI-on-the-edge-device/issues/2036) Fix wrong url-encoding
- **NEW v15.0.2:** [#1933](https://github.com/jomjol/AI-on-the-edge-device/issues/1933) Bugfix InfluxDB Timestamp
- **NEW v15.0.3:** Re-added lost dropdownbox filling for Postprocessing Individual Parameters
#### Removed
- n.a.
## [14.0.3] - 2023-02-05
**Stabilization and Improved User Experience**
## [14.0.3] -2023-02-05
**Name: Stabilization and Improved User Experience**
Thanks to over 80 Pull Requests from 6 contributors, we can anounce another great release with many many improvements and new features:
@@ -89,7 +364,7 @@ For a full list of changes see [Full list of changes](https://github.com/jomjol/
## [13.0.8] - 2022-12-19
**Home Assistant MQTT Discovery Support**
**Name: Home Assistant MQTT Discovery Support**
### Update Procedure see [online documentation](https://jomjol.github.io/AI-on-the-edge-device-docs/Installation/#update-ota-over-the-air)
@@ -100,7 +375,7 @@ For a full list of changes see [Full list of changes](https://github.com/jomjol/
- Improved OTA Update mechanism (only working after installation for next update)
- Added data logging in `/log/data` - One day per file and each measurement is on one line
- Format: csv - comma separated
- Content: `time`, `name-of-number`, `raw-value`, `return-value`, `pre-value`, `change-rate`, `change-absolute`, `error-text`, `cnn-digital`, `cnn-analog`
- Content: `time`, `name-of-number`, `raw-value`, `return-value`, `pre-value`, `change-rate`, `change-absolute`, `error-text`, `cnn-digit`, `cnn-analog`
- Show graph of values direct in the user interface (thanks to [@rdmueller](https://github.com/rdmueller))
- Using new data logging (see above)
@@ -118,10 +393,10 @@ For a full list of changes see [Full list of changes](https://github.com/jomjol/
- Updated OTA functionality (more robust, but not fully bullet prove yet)
- Updated Espressif library to `espressif32@v5.2.0`
- [#1176](https://github.com/jomjol/AI-on-the-edge-device/discussions/1176) accept minor negative values (-0.2) if extended resolution is enabled
- [#1143](https://github.com/jomjol/AI-on-the-edge-device/issues/1143) added config parameter `AnalogDigitalTransitionStart`. It can setup very early and very late digit transition starts.
- [#1143](https://github.com/jomjol/AI-on-the-edge-device/issues/1143) added config parameter `AnalogDigTransitionStart`. It can setup very early and very late digit transition starts.
- New version of `dig-class100` (v1.4.0): added images of heliowatt powermeter
- NEW v13.0.2: Update Tool "Logfile downloader and combiner" to handle the new csv file format.
- NEW v13.0.2: MQTT: Added MQTT topic `status` (Digitalization Status), Timezone to MQTT topic `timestamp`.#
- NEW v13.0.2: MQTT: Added MQTT topic `status` (Digitization Status), Timezone to MQTT topic `timestamp`.#
- NEW v13.0.2: Logging: Disable heap logs by default, cleanup
- NEW v13.0.7:
- log NTP server name
@@ -169,7 +444,7 @@ For a full list of changes see [Full list of changes](https://github.com/jomjol/
## [12.0.1] 2022-09-29
Improve **u**ser e**x**perience
Name: Improve **u**ser e**x**perience
:bangbang: The release breaks a few things in ota update :bangbang:
@@ -246,7 +521,7 @@ Intermediate Digits
- Updated analog neural network file (`ana-cont_11.3.0_s2.tflite` - default, `ana-class100_0120_s1_q.tflite`)
- Updated digital neural network file (`dig-cont_0570_s3.tflite` - default, `dig-class100_0120_s2_q.tflite`)
- Updated digit neural network file (`dig-cont_0570_s3.tflite` - default, `dig-class100_0120_s2_q.tflite`)
- Added automated filtering of tflite-file in the graphical configuration (thanks to @**[caco3](https://github.com/caco3)**)
@@ -258,8 +533,8 @@ Intermediate Digits
Intermediate Digits
- New and improved consistency check (especially with analog and digital counters mixed)
- Bug Fix: digital counter algorithm
- New and improved consistency check (especially with analog and digit counters mixed)
- Bug Fix: digit counter algorithm
## [11.0.1](https://github.com/jomjol/AI-on-the-edge-device/releases/tag/v11.0.1), 2022-08-18
@@ -299,7 +574,7 @@ Stability Increase
- `config.ini`: removal of modelsize (readout from tflite)
- Updated analog neural network file (`ana1000s2.tflite`) & digital neural network file (`dig1400s2q.tflite`)
- Updated analog neural network file (`ana1000s2.tflite`) & digit neural network file (`dig1400s2q.tflite`)
- TFMicro/Lite: Update (espressif Version 20220716)
@@ -335,7 +610,7 @@ Stability Increase
- In the future the new files will also be copied to the `firmware` directory of the repository
- Added Wifi RSSI to MQTT information
- Updated analog neural network file (`ana-s3-q-20220105.tflite`)
- Updated digital neural network file (`dig-s1-q-20220102.tflite`)
- Updated digit neural network file (`dig-s1-q-20220102.tflite`)
- Updated build environment to `Espressif 3.5.0`
## [10.3.0] - (2022-01-29)
@@ -401,7 +676,7 @@ Stability Increase
- Update analog neural network (ana-s3-q-20220105.tflite)
- Update digital neural network (dig-s1-q-20220102.tflite)
- Update digit neural network (dig-s1-q-20220102.tflite)
- Increased web-server buffers
@@ -438,7 +713,7 @@ External Illumination
- Direct JSON access: `http://IP-ADRESS/json`
- Error message in log file in case camera error during startup
- Upgrade analog CNN to v9.1.0
- Upgrade digital CNN to v13.3.0 (added new images)
- Upgrade digit CNN to v13.3.0 (added new images)
- html: support of different ports
## [9.1.1] - External Illumination (2021-11-16)
@@ -463,7 +738,7 @@ External Illumination
### Changed
- Upgrade digital CNN to v13.1.0 (added new images)
- Upgrade digit CNN to v13.1.0 (added new images)
- bug fix: wlan password with space, double digit output
## [8.4.0] - Multi Meter Support (2021-09-25)
@@ -493,7 +768,7 @@ External Illumination
### Changed
- Upgrade digital CNN to v12.1.0 (added new images)
- Upgrade digit CNN to v12.1.0 (added new images)
- Dedicated NaN handling, internal refactoring (CNN-Handling)
- HTML: confirmation after config.ini update
- Bug fixing
@@ -515,7 +790,7 @@ External Illumination
- GPIO: using the general mqtt main topic for GPIO
- Upgrade digital CNN to v12.0.0 (added new images)
- Upgrade digit CNN to v12.0.0 (added new images)
- Update tfmicro to new master (2021-08-07)
- Bug fix: remove text in mqtt value, remove connect limit in wlan reconnet
@@ -551,7 +826,7 @@ External Illumination
- Update wlan handling to esp-idf 4.1
- Upgrade digital CNN to v8.7.0 (added new images)
- Upgrade digit CNN to v8.7.0 (added new images)
- Bug fix: MQTT, WLAN, LED-Controll, GPIO usage, fixed IP, calculation flow rate
@@ -562,7 +837,7 @@ External Illumination
- NEW: 7.0.1: bug fix wlan password with "="
- Upgrade digital CNN to v8.5.0 (added new images)
- Upgrade digit CNN to v8.5.0 (added new images)
- New MQTT topics: flow rate (units/minute), time stamp (last correct read readout)
@@ -579,7 +854,7 @@ External Illumination
- NEW 6.7.1: Improved stability of camera (back to v6.6.1) - remove black strips and areas
- Upgrade digital CNN to v8.3.0 (added new type of digits)
- Upgrade digit CNN to v8.3.0 (added new type of digits)
- Internal update: TFlite (v2.5), esp32cam, startup sequence
@@ -600,7 +875,7 @@ External Illumination
### Changed
- Upgrade digital CNN to v8.2.0 (added new type of digits)
- Upgrade digit CNN to v8.2.0 (added new type of digits)
- Supporting alignment structures in ROI definition
@@ -636,7 +911,7 @@ External Illumination
- Determination of fixed illumination settings during startup - speed up of 5s in each run
- Update digital CNN to v8.1.1 (additional digital images trained)
- Update digit CNN to v8.1.1 (additional digit images trained)
- Extended error message in MQTT error message
@@ -648,7 +923,7 @@ External Illumination
### Changed
- Disabling of analog / digital counters in configuration
- Disabling of analog / digit counters in configuration
- Improved Alignment Algorithm (`AlignmentAlgo` = `Default`, `Accurate` , `Fast`)
@@ -668,7 +943,7 @@ External Illumination
- MQTT: Last Will Testament (LWT) implemented: "connection lost" in case of connection lost to `TopicError`
- Disabled `CheckDigitIncreaseConsistency` in default configuration - must now be explicit enabled if needed
- Update digital CNN to v7.2.1 (additional digital images trained)
- Update digit CNN to v7.2.1 (additional digit images trained)
- Setting of arbitrary time server in `config.ini`
- Option for fixed IP-, DNS-Settings in `wlan.ini`
- Increased stability (internal image and camera handling)
@@ -702,7 +977,7 @@ External Illumination
- standardized access to current logfile via `http://IP-ADRESS/logfileact`
- Update digital CNN to v7.2.0, analog CNN to 6.3.0
- Update digit CNN to v7.2.0, analog CNN to 6.3.0
- Bug fixing: truncation error, CheckDigitConsistency & PreValue implementation
@@ -721,7 +996,7 @@ External Illumination
### Changed
- Update digital CNN to v6.5.0 and HTML (Info to hostname, IP, ssid)
- Update digit CNN to v6.5.0 and HTML (Info to hostname, IP, ssid)
- New implementation of "checkDigitConsistency" also for digits
@@ -837,7 +1112,12 @@ External Illumination
- Initial Version
[15.0.1]: https://github.com/jomjol/AI-on-the-edge-device/compare/v14.0.3...v15.0.1
[15.2.4]: https://github.com/jomjol/AI-on-the-edge-device/compare/v15.2.1...v15.2.4
[15.2.1]: https://github.com/jomjol/AI-on-the-edge-device/compare/v15.2.0...v15.2.1
[15.2.0]: https://github.com/jomjol/AI-on-the-edge-device/compare/v15.1.1...v15.2.0
[15.1.1]: https://github.com/jomjol/AI-on-the-edge-device/compare/v15.1.0...v15.1.1
[15.1.0]: https://github.com/jomjol/AI-on-the-edge-device/compare/v15.0.3...v15.1.0
[15.0.3]: https://github.com/jomjol/AI-on-the-edge-device/compare/v14.0.3...v15.0.3
[14.0.3]: https://github.com/jomjol/AI-on-the-edge-device/compare/v13.0.8...v14.0.3
[13.0.8]: https://github.com/jomjol/AI-on-the-edge-device/compare/v12.0.1...v13.0.8
[13.0.7]: https://github.com/jomjol/AI-on-the-edge-device/compare/v12.0.1...v13.0.7

View File

@@ -2,14 +2,48 @@
**There are a lot of ideas for further improvements, but only limited capacity on side of the developer.** Therefore I have created this page as a collection of ideas.
1. Who ever has a new idea can put it here, so it that it is not forgotten.
1. Whoever has a new idea can put it here, so that it is not forgotten.
2. Who ever has time, capacity and passion to support, can take any of the ideas and implement them.
I will support and help where ever I can!
2. Whoever has the time, capacity and passion to support the project can take any of the ideas and implement them. I will provide support and help wherever I can!
____
#### #40 Trigger with cron like exact time slot
* https://github.com/jomjol/AI-on-the-edge-device/issues/2470
#### #39 upnp implementation to auto detect the device
* https://github.com/jomjol/AI-on-the-edge-device/issues/2481
#### #38 Energy Saving
* Deep sleep between recognition
* https://github.com/jomjol/AI-on-the-edge-device/issues/2486
#### #37 Auto init SD card
* Fully implement the SD card handling (including formatting) into the firmware
* https://github.com/jomjol/AI-on-the-edge-device/issues/2488Demo
#### #36 Run demo without camera
Demo mode requires a working camera (if not, one receives a 'Cam bad' error). Would be nice to demo or play around on other ESP32 boards (or on ESP32-CAM boards when you broke the camera cable...).
#### #35 Use the same model, but provide the image from a Smartphone Camera
as reading the Electricity or Water meter every few minutues only delivers apparent accuracy (DE: "Scheingenauigkeit") you could just as well take a picture with your Smartphone evey so often (e.g. once a week when you are in the Basement anyway), then with some "semi clever" tricks pass this image to the model developed here, and the values then on to who ever needs them e.g. via MQTT.
IMO: It is not needed to have that many readings (datapoints) as our behaviour (Use of electricity or water) doesn't vary that much, say, over a weeks time. The interpolation between weekly readings will give sufficient information on the power and/or water usage.
#### #34 implement state and Roi for water leak detection
for example see Roi on the next picture..
![grafik](https://user-images.githubusercontent.com/38385805/207858812-2a6ba41d-1a8c-4fa1-9b6a-53cdd113c106.png)
@@ -43,7 +77,7 @@ haveing this state in the mqtt broker can trigger functions like closing the ate
#### ~~#29 Add favicon and use the hostname for the website~~- implemented v11.3.1
~~* https://github.com/jomjol/AI-on-the-edge-device/issues/927~~
* ~~https://github.com/jomjol/AI-on-the-edge-device/issues/927~~
#### #28 Improved error handling for ROIs
@@ -81,7 +115,7 @@ haveing this state in the mqtt broker can trigger functions like closing the ate
#### ~~#22 Direct hint to the different neural network files in the other repositories~~- implemented >v11.3.1
~~* https://github.com/jomjol/AI-on-the-edge-device/issues/644~~
* ~~https://github.com/jomjol/AI-on-the-edge-device/issues/644~~

View File

@@ -1,31 +1,31 @@
# Welcome to the AI-on-the-edge-device
<img src="images/icon/watermeter.svg" width="100px">
Artificial intelligence based systems have been established in our every days live. Just think of speech or image recognition. Most of the systems relay on either powerful processors or a direct connection to the cloud for doing the calculations up there. With the increasing power of modern processors the AI systems are coming closer to the end user - which is usually called **edge computing**.
Here this edge computing is brought into a practical oriented example, where a AI network is implemented on a ESP32 device so: **AI on the edge**.
Artificial intelligence based systems have become established in our everyday lives. Just think of speech or image recognition. Most of the systems rely on either powerful processors or a direct connection to the cloud for doing the calculations there. With the increasing power of modern processors, the AI systems are coming closer to the end user which is usually called **edge computing**.
Here, this edge computing is put into a practically oriented example, where an AI network is implemented on an ESP32 device so: **AI on the edge**.
This projects allows you to digitalize your **analoge** water, gas, power and other meters using cheap and easily available hardware.
This project allows you to digitize your **analog** water, gas, power and other meters using cheap and easily available hardware.
All you need is an [ESP32 board with a supported camera](https://jomjol.github.io/AI-on-the-edge-device-docs/Hardware-Compatibility/) and a bit of a practical hand.
All you need is an [ESP32 board with a supported camera](https://jomjol.github.io/AI-on-the-edge-device-docs/Hardware-Compatibility/) and something of a practical hand.
<img src="images/esp32-cam.png" width="200px">
## Key features
- Tensorflow Lite (TFlite) integration - including easy to use wrapper
- Inline Image processing (feature detection, alignment, ROI extraction)
- **Small** and **cheap** device (3x4.5x2 cm³, < 10 EUR)
- camera and illumination integrated
- Web surface to administrate and control
- OTA-Interface to update directly through the web interface
- Tensorflow Lite (TFlite) integration including easy-to-use wrapper
- Inline image processing (feature detection, alignment, ROI extraction)
- **Small** and **cheap** device (3 x 4.5 x 2 cm³, < 10 EUR)
- Integrated camera and illumination
- Web interface for administration and control
- OTA interface for updating directly via the web interface
- Full integration into Homeassistant
- Support for Influx DB 1
- Support for Influx DB 1 and 2
- MQTT
- REST API
## Workflow
The device takes a photo of your meter at a defined interval. It then extracts the Regions of Interest (ROI's) out of it and runs them through an artificial inteligence. As a result, you get the digitalized value of your meter.
The device takes a photo of your meter at a defined interval. It then extracts the Regions of Interest (ROIs) from the image and runs them through artificial intelligence. As a result, you get the digitized value of your meter.
There are several options what to do with that value. Either send it to a MQTT broker, write it to an InfluxDb or simply provide it throug a REST API.
There are several options for what to do with that value. Either send it to an MQTT broker, write it to an InfluxDb or simply provide access to it via a REST API.
<img src="https://raw.githubusercontent.com/jomjol/AI-on-the-edge-device/master/images/idea.jpg" width="600">
@@ -41,62 +41,68 @@ There are several options what to do with that value. Either send it to a MQTT b
## Setup
There is a growing [documentation](https://jomjol.github.io/AI-on-the-edge-device-docs/) which provides you with a lot of information.
Head there to get a start, set it up and configure it.
There is growing [documentation](https://jomjol.github.io/AI-on-the-edge-device-docs/) which provides you with a lot of information. Head there to get a start, set it up and configure it.
There are also a articles in the German Heise magazine "make:" about the setup and the technical background (behind a paywall) : [DIY - Setup](https://www.heise.de/select/make/2021/2/2103513300897420296)
There are also articles in the German Heise magazine "make:" about the setup and technical background (behind a paywall): [DIY - Setup](https://www.heise.de/select/make/2021/2/2103513300897420296)
For further background information, head to [Neural Networks](https://www.heise.de/select/make/2021/6/2126410443385102621), [Training Neural Networks](https://www.heise.de/select/make/2022/1/2134114065999161585) and [Programming on the ESP32](https://www.heise.de/select/make/2022/2/2204010051597422030)
A lot of people created useful Youtube videos which might help you getting started.
Here a small selection:
- [youtube.com/watch?v=HKBofb1cnNc](https://www.youtube.com/watch?v=HKBofb1cnNc)
- [youtube.com/watch?v=yyf0ORNLCk4](https://www.youtube.com/watch?v=yyf0ORNLCk4)
- [youtube.com/watch?v=XxmTubGek6M](https://www.youtube.com/watch?v=XxmTubGek6M)
- [youtube.com/watch?v=mDIJEyElkAU](https://www.youtube.com/watch?v=mDIJEyElkAU)
- [youtube.com/watch?v=SssiPkyKVVs](https://www.youtube.com/watch?v=SssiPkyKVVs)
- [youtube.com/watch?v=MAHE_QyHZFQ](https://www.youtube.com/watch?v=MAHE_QyHZFQ)
- [youtube.com/watch?v=Uap_6bwtILQ](https://www.youtube.com/watch?v=Uap_6bwtILQ)
For further background information, head to [Neural Networks](https://www.heise.de/select/make/2021/6/2126410443385102621), [Training Neural Networks](https://www.heise.de/select/make/2022/1/2134114065999161585) and [Programming on the ESP32](https://www.heise.de/select/make/2022/2/2204010051597422030).
### Download
The latest available version is available on the [Releases page](https://github.com/jomjol/AI-on-the-edge-device/releases).
The latest available version can be found on the [Releases page](https://github.com/jomjol/AI-on-the-edge-device/releases).
### Flashing of the ESP32
Initially you will have to flash the ESP32 through an USB connection. Later an update is possible directly over the Air (OTA).
### Flashing the ESP32
Initially you will have to flash the ESP32 via a USB connection. Later updates are possible directly over the air (OTA using WIFI).
There are different ways to flash your ESP32:
- [Web Installer and Console](https://jomjol.github.io/AI-on-the-edge-device/index.html) (Webbrowser based tool to flash the ESP32 and extract the Log over USB)
- The preferred way is the [Web Installer and Console](https://jomjol.github.io/AI-on-the-edge-device/index.html) which is a browser-based tool to flash the ESP32 and extract the log over USB:
![](images/web-installer.png)
- Flash Tool from Espressif
- ESPtool (Command Line Tool)
- ESPtool (command-line tool)
See the [Docu](https://jomjol.github.io/AI-on-the-edge-device-docs/Installation/) for more information.
See the [documentation](https://jomjol.github.io/AI-on-the-edge-device-docs/Installation/) for more information.
### Flashing the SD-Card
The SD-Card must be flashed separately, see the [Docu](https://jomjol.github.io/AI-on-the-edge-device-docs/Installation/) for details.
### Flashing the SD Card
The SD card can be setup automatically after the firmware got installed. See the [documentation](https://jomjol.github.io/AI-on-the-edge-device-docs/Installation/#remote-setup-using-the-built-in-access-point) for details. For this to work, the SD card must be FAT formated (which is the default on a new SD card).
Alternatively the SD card still can be setup manually, see the [documentation](https://jomjol.github.io/AI-on-the-edge-device-docs/Installation/#3-sd-card) for details!
## Casing
A 3d-printable housing can be found here:
Various 3D-printable housing can be found here:
- https://www.thingiverse.com/thing:4573481 (Water Meter)
- https://www.thingiverse.com/thing:5028229 (Power Meter)
- https://www.thingiverse.com/thing:5224101 (Gas Meter)
- https://www.thingiverse.com/thing:4571627 (ESP32-Cam housing only)
## Build it yourself
See [Build Instructions](code/README.md).
- https://www.thingiverse.com/thing:4571627 (ESP32-cam housing only)
## Donate
If you would like to support the developer with a cup of coffee you can do that via [Paypal](https://www.paypal.com/donate?hosted_button_id=8TRSVYNYKDSWL).
If you would like to support the developer with a cup of coffee, you can do that via [PayPal](https://www.paypal.com/donate?hosted_button_id=8TRSVYNYKDSWL).
<form action="https://www.paypal.com/donate" method="post" target="_top">
<input type="hidden" name="hosted_button_id" value="8TRSVYNYKDSWL" />
<input type="image" src="https://www.paypalobjects.com/en_US/DK/i/btn/btn_donateCC_LG.gif" border="0" name="submit" title="PayPal - The safer, easier way to pay online!" alt="Donate with PayPal button" />
<img alt="" border="0" src="https://www.paypal.com/en_DE/i/scr/pixel.gif" width="1" height="1" />
</form>
If you have any technical topics, you can create an [Issue](https://github.com/jomjol/AI-on-the-edge-device/issues).
<a href="https://www.paypal.com/donate?hosted_button_id=8TRSVYNYKDSWL"><img border="0" src="images/paypal.png" width="200px" target="_blank"></a>
In other cases you can contact the developer via email: <img src="https://raw.githubusercontent.com/jomjol/AI-on-the-edge-device/master/images/mail.jpg" height="25">
## Support
If you have any technical problems please search the [discussions](https://github.com/jomjol/AI-on-the-edge-device/discussions). In case you found a ug or have a feature request, please open an [issue](https://github.com/jomjol/AI-on-the-edge-device/issues).
In other cases you can contact the developer via email: <img src="https://raw.githubusercontent.com/jomjol/AI-on-the-edge-device/master/images/mail.jpg" height="25">
## Changes and History
See [Changelog](Changelog.md)
See [Changelog](Changelog.md).
## Build It Yourself
See [Build Instructions](code/README.md).
## Tools
* Logfile downloader and combiner (Thx to [reserve85](https://github.com/reserve85))
* Files see ['/tools/logfile-tool'](tbd), How-to see [Docu](https://jomjol.github.io/AI-on-the-edge-device-docs/outdated--Gasmeter-Log-Downloader/)
* Files see ['/tools/logfile-tool'](tbd), how-to see [documentation](https://jomjol.github.io/AI-on-the-edge-device-docs/outdated--Gasmeter-Log-Downloader/)
## Additional Ideas
There are some ideas and feature requests which are not followed currently - mainly due to capacity reasons on side of the developer. They are collected here: [FeatureRequest.md](FeatureRequest.md)
------
There are some ideas and feature requests which are not currently being pursued mainly due to capacity reasons on the part of the developers.
They features are collected in the [issues](https://github.com/jomjol/AI-on-the-edge-device/issues) and in [FeatureRequest.md](FeatureRequest.md).

1
code/.gitignore vendored
View File

@@ -1,4 +1,5 @@
.pio
.idea
.vscode/.browse.c_cpp.db*
.vscode/c_cpp_properties.json
.vscode/launch.json

View File

@@ -1,6 +1,6 @@
cmake_minimum_required(VERSION 3.16.0)
list(APPEND EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/protocol_examples_common components/tflite-micro-esp-examples/components/tflite-lib)
list(APPEND EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/protocol_examples_common components/esp-tflite-micro)
ADD_CUSTOM_COMMAND(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/version.cpp

View File

@@ -8,6 +8,15 @@ git checkout rolling
git submodule update --init
```
## Update Submodules
```
cd /components/submodule-name (e.g. tflite-micro-example)
git checkout VERSION (e.g. HASH of latest tflite-micro-example build)
cd ../../ (auf Ebene von code)
git submodule update --init
```
Evt. muss man vorher noch einige Verzeichnisse in compenents von Hand löschen, da sie beim checkout nicht gelöscht wurden (vor update -- init)
## Build and Flash within terminal
See further down to build it within an IDE.
### Compile
@@ -60,3 +69,6 @@ pio device monitor -p /dev/ttyUSB0
- `pio run --target erase` to erase the flash
- `pio run --target upload` this will upload the `bootloader.bin, partitions.bin,firmware.bin` from the `code/.pio/build/esp32cam/` folder.
- `pio device monitor` to observe the logs via uart
# Update Parameters
If you create or rename a parameter, make sure to update its documentation in `../param-docs/parameter-pages`! Check the `../param-docs/README.md` for more information.

View File

@@ -1,5 +1,32 @@
#include "SmartLeds.h"
/* PlatformIO 6 (ESP IDF 5) does no longer allow access to RMTMEM,
see https://docs.espressif.com/projects/esp-idf/en/latest/esp32/migration-guides/release-5.x/5.0/peripherals.html?highlight=rmtmem#id5
As a dirty workaround, we copy the needed structures from rmt_struct.h
In the long run, this should be replaced! */
typedef struct rmt_item32_s {
union {
struct {
uint32_t duration0 :15;
uint32_t level0 :1;
uint32_t duration1 :15;
uint32_t level1 :1;
};
uint32_t val;
};
} rmt_item32_t;
//Allow access to RMT memory using RMTMEM.chan[0].data32[8]
typedef volatile struct rmt_mem_s {
struct {
rmt_item32_t data32[64];
} chan[8];
} rmt_mem_t;
extern rmt_mem_t RMTMEM;
IsrCore SmartLed::_interruptCore = CoreCurrent;
intr_handle_t SmartLed::_interruptHandle = NULL;

View File

@@ -35,6 +35,20 @@
#include <cassert>
#include <cstring>
#include "esp_idf_version.h"
#if (ESP_IDF_VERSION_MAJOR >= 5)
#include "soc/periph_defs.h"
#include "esp_private/periph_ctrl.h"
#include "soc/gpio_sig_map.h"
#include "soc/gpio_periph.h"
#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 ets_delay_us(a) esp_rom_delay_us(a)
#endif
#if defined ( ARDUINO )
extern "C" { // ...someone forgot to put in the includes...
#include "esp32-hal.h"
@@ -65,6 +79,27 @@
#include <stdio.h>
#endif
#if (ESP_IDF_VERSION_MAJOR >= 4) && (ESP_IDF_VERSION_MINOR > 1)
#include "hal/gpio_ll.h"
#else
#include "soc/gpio_periph.h"
#define esp_rom_delay_us ets_delay_us
static inline int gpio_ll_get_level(gpio_dev_t *hw, int gpio_num)
{
if (gpio_num < 32) {
return (hw->in >> gpio_num) & 0x1;
} else {
return (hw->in1.data >> (gpio_num - 32)) & 0x1;
}
}
#endif
#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0))
#if !(configENABLE_BACKWARD_COMPATIBILITY == 1)
#define xSemaphoreHandle SemaphoreHandle_t
#endif
#endif
#include "Color.h"
namespace detail {

View File

@@ -6,9 +6,6 @@
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "esp_event.h"
#include "server_tflite.h"
#include "esp_log.h"
@@ -22,8 +19,10 @@
#include "ClassLogFile.h"
#include "configFile.h"
#include "Helper.h"
#ifdef ENABLE_MQTT
#include "interface_mqtt.h"
#include "interface_mqtt.h"
#include "server_mqtt.h"
#endif //ENABLE_MQTT
@@ -82,10 +81,10 @@ static void gpioHandlerTask(void *arg) {
void GpioPin::gpioInterrupt(int value) {
#ifdef ENABLE_MQTT
if (_mqttTopic != "") {
if (_mqttTopic.compare("") != 0) {
ESP_LOGD(TAG, "gpioInterrupt %s %d", _mqttTopic.c_str(), value);
MQTTPublish(_mqttTopic, value ? "true" : "false");
MQTTPublish(_mqttTopic, value ? "true" : "false", 1);
}
#endif //ENABLE_MQTT
currentState = value;
@@ -115,7 +114,7 @@ void GpioPin::init()
}
#ifdef ENABLE_MQTT
if ((_mqttTopic != "") && ((_mode == GPIO_PIN_MODE_OUTPUT) || (_mode == GPIO_PIN_MODE_OUTPUT_PWM) || (_mode == GPIO_PIN_MODE_BUILT_IN_FLASH_LED))) {
if ((_mqttTopic.compare("") != 0) && ((_mode == GPIO_PIN_MODE_OUTPUT) || (_mode == GPIO_PIN_MODE_OUTPUT_PWM) || (_mode == GPIO_PIN_MODE_BUILT_IN_FLASH_LED))) {
std::function<bool(std::string, char*, int)> f = std::bind(&GpioPin::handleMQTT, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
MQTTregisterSubscribeFunction(_mqttTopic, f);
}
@@ -141,8 +140,8 @@ void GpioPin::setValue(bool value, gpio_set_source setSource, std::string* error
gpio_set_level(_gpio, value);
#ifdef ENABLE_MQTT
if ((_mqttTopic != "") && (setSource != GPIO_SET_SOURCE_MQTT)) {
MQTTPublish(_mqttTopic, value ? "true" : "false");
if ((_mqttTopic.compare("") != 0) && (setSource != GPIO_SET_SOURCE_MQTT)) {
MQTTPublish(_mqttTopic, value ? "true" : "false", 1);
}
#endif //ENABLE_MQTT
}
@@ -153,7 +152,8 @@ void GpioPin::publishState() {
if (newState != currentState) {
ESP_LOGD(TAG,"publish state of GPIO %d new state %d", _gpio, newState);
#ifdef ENABLE_MQTT
MQTTPublish(_mqttTopic, newState ? "true" : "false");
if (_mqttTopic.compare("") != 0)
MQTTPublish(_mqttTopic, newState ? "true" : "false", 1);
#endif //ENABLE_MQTT
currentState = newState;
}
@@ -330,7 +330,7 @@ bool GpioHandler::readConfig()
#ifdef ENABLE_MQTT
// std::string mainTopicMQTT = "";
std::string mainTopicMQTT = GetMQTTMainTopic();
std::string mainTopicMQTT = mqttServer_getMainTopic();
if (mainTopicMQTT.length() > 0)
{
mainTopicMQTT = mainTopicMQTT + "/GPIO";
@@ -359,9 +359,9 @@ bool GpioHandler::readConfig()
gpio_int_type_t intType = resolveIntType(toLower(splitted[2]));
uint16_t dutyResolution = (uint8_t)atoi(splitted[3].c_str());
#ifdef ENABLE_MQTT
bool mqttEnabled = toLower(splitted[4]) == "true";
bool mqttEnabled = (toLower(splitted[4]) == "true");
#endif // ENABLE_MQTT
bool httpEnabled = toLower(splitted[5]) == "true";
bool httpEnabled = (toLower(splitted[5]) == "true");
char gpioName[100];
if (splitted.size() >= 7) {
strcpy(gpioName, trim(splitted[6]).c_str());

View File

@@ -4,6 +4,6 @@ list(APPEND EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/proto
idf_component_register(SRCS ${app_sources}
INCLUDE_DIRS "."
REQUIRES esp32-camera esp_http_server jomjol_logfile jomjol_image_proc nvs_flash jomjol_fileserver_ota jomjol_controlGPIO)
REQUIRES esp_timer esp32-camera esp_http_server jomjol_logfile jomjol_image_proc nvs_flash jomjol_fileserver_ota jomjol_controlGPIO)

File diff suppressed because it is too large Load Diff

View File

@@ -15,48 +15,99 @@
#include "CImageBasis.h"
#include "../../include/defines.h"
class CCamera {
protected:
int ActualQuality;
framesize_t ActualResolution;
int brightness, contrast, saturation;
bool isFixedExposure;
int waitbeforepicture_org;
int led_intensity = 4095;
typedef struct
{
uint16_t CamSensor_id;
void ledc_init(void);
bool CameraInitSuccessful = false;
bool demoMode = false;
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)
public:
int image_height, image_width;
CCamera();
esp_err_t InitCam();
int ImageDenoiseLevel; // The OV2640 does not support it, OV3660 and OV5640 (0 to 8)
void LightOnOff(bool status);
void LEDOnOff(bool status);
esp_err_t CaptureToHTTP(httpd_req_t *req, int delay = 0);
void SetQualitySize(int qual, framesize_t resol);
bool SetBrightnessContrastSaturation(int _brightness, int _contrast, int _saturation);
void GetCameraParameter(httpd_req_t *req, int &qual, framesize_t &resol);
void SetLEDIntensity(float _intrel);
bool testCamera(void);
void EnableAutoExposure(int flash_duration);
bool getCameraInitSuccessful();
void useDemoMode(void);
int ImageWidth;
int ImageHeight;
framesize_t TextToFramesize(const char * text);
int ImageLedIntensity;
esp_err_t CaptureToFile(std::string nm, int delay = 0);
esp_err_t CaptureToBasisImage(CImageBasis *_Image, int delay = 0);
bool ImageZoomEnabled;
int ImageZoomOffsetX;
int ImageZoomOffsetY;
int ImageZoomSize;
int WaitBeforePicture;
bool isImageSize;
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 frameSizeX, int frameSizeY, int xOffset, int yOffset, int xTotal, int yTotal, int xOutput, int yOutput, int imageVflip);
void SetImageWidthHeightFromResolution(framesize_t resol);
void SanitizeZoomParams(int imageSize, int frameSizeX, int frameSizeY, int &imageWidth, int &imageHeight, int &zoomOffsetX, int &zoomOffsetY);
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);
int ov5640_set_gainceiling(sensor_t *s, gainceiling_t level);
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, int imageVflip);
void SetZoomSize(bool zoomEnabled, int zoomOffsetX, int zoomOffsetY, int imageSize, int imageVflip);
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

View File

@@ -0,0 +1,152 @@
#include <stdint.h>
#include "esp_camera.h"
#include "ov2640_sharpness.h"
const static uint8_t OV2640_SHARPNESS_AUTO[]=
{
//reg, val, mask
0xFF, 0x00, 0xFF,
0x92, 0x01, 0xFF,
0x93, 0x20, 0x20,
0x00, 0x00, 0x00
};
const static uint8_t OV2640_SHARPNESS_MANUAL[]=
{
//reg, val, mask
0xFF, 0x00, 0xFF,
0x92, 0x01, 0xFF,
0x93, 0x00, 0x20,
0x00, 0x00, 0x00
};
const static uint8_t OV2640_SHARPNESS_LEVEL0[]=
{
//reg, val, mask
0xFF, 0x00, 0xFF,
0x92, 0x01, 0xFF,
0x93, 0xC0, 0x1F,
0x00, 0x00, 0x00
};
const static uint8_t OV2640_SHARPNESS_LEVEL1[]=
{
//reg, val, mask
0xFF, 0x00, 0xFF,
0x92, 0x01, 0xFF,
0x93, 0xC1, 0x1F,
0x00, 0x00, 0x00
};
const static uint8_t OV2640_SHARPNESS_LEVEL2[]=
{
//reg, val, mask
0xFF, 0x00, 0xFF,
0x92, 0x01, 0xFF,
0x93, 0xC2, 0x1F,
0x00, 0x00, 0x00
};
const static uint8_t OV2640_SHARPNESS_LEVEL3[]=
{
//reg, val, mask
0xFF, 0x00, 0xFF,
0x92, 0x01, 0xFF,
0x93, 0xC4, 0x1F,
0x00, 0x00, 0x00
};
const static uint8_t OV2640_SHARPNESS_LEVEL4[]=
{
//reg, val, mask
0xFF, 0x00, 0xFF,
0x92, 0x01, 0xFF,
0x93, 0xC8, 0x1F,
0x00, 0x00, 0x00
};
const static uint8_t OV2640_SHARPNESS_LEVEL5[]=
{
//reg, val, mask
0xFF, 0x00, 0xFF,
0x92, 0x01, 0xFF,
0x93, 0xD0, 0x1F,
0x00, 0x00, 0x00
};
const static uint8_t OV2640_SHARPNESS_LEVEL6[]=
{
//reg, val, mask
0xFF, 0x00, 0xFF,
0x92, 0x01, 0xFF,
0x93, 0xDF, 0x1F,
0x00, 0x00, 0x00
};
const static uint8_t *OV2640_SETTING_SHARPNESS[]=
{
OV2640_SHARPNESS_LEVEL0, // -3 sharpness
OV2640_SHARPNESS_LEVEL1,
OV2640_SHARPNESS_LEVEL2,
OV2640_SHARPNESS_LEVEL3,
OV2640_SHARPNESS_LEVEL4,
OV2640_SHARPNESS_LEVEL5,
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;
uint8_t value;
uint8_t orgval;
uint8_t mask;
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)
{
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_temp + 3]);
return 0;
}

View File

@@ -0,0 +1,11 @@
#pragma once
#ifndef OV2640_SHARPNESS_H
#define OV2640_SHARPNESS_H
#include "esp_camera.h"
int ov2640_enable_auto_sharpness(sensor_t *sensor);
int ov2640_set_sharpness(sensor_t *sensor, int sharpness); // -3 to +3, -4 for auto-sharpness
#endif

View File

@@ -5,6 +5,7 @@
#include "esp_camera.h"
#include "ClassControllCamera.h"
#include "MainFlowControl.h"
#include "ClassLogFile.h"
#include "esp_log.h"
@@ -13,183 +14,187 @@
static const char *TAG = "server_cam";
void PowerResetCamera()
{
#if CAM_PIN_PWDN == GPIO_NUM_NC // Use reset only if pin is available
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "No power down pin availbale to reset camera");
#else
ESP_LOGD(TAG, "Resetting camera by power down line");
gpio_config_t conf;
conf.intr_type = GPIO_INTR_DISABLE;
conf.pin_bit_mask = 1LL << CAM_PIN_PWDN;
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(CAM_PIN_PWDN, 1);
vTaskDelay(1000 / portTICK_PERIOD_MS);
gpio_set_level(CAM_PIN_PWDN, 0);
vTaskDelay(1000 / portTICK_PERIOD_MS);
#endif
}
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;
// If the camera settings were changed by creating a new reference image, they must be reset
if (CFstatus.changedCameraSettings)
{
Camera.setSensorDatenFromCCstatus(); // CCstatus >>> Kamera
Camera.SetQualityZoomSize(CCstatus.ImageQuality, CCstatus.ImageFrameSize, CCstatus.ImageZoomEnabled, CCstatus.ImageZoomOffsetX, CCstatus.ImageZoomOffsetY, CCstatus.ImageZoomSize, CCstatus.ImageVflip);
CFstatus.changedCameraSettings = false;
}
Camera.GetCameraParameter(req, quality, res);
#ifdef DEBUG_DETAIL_ON
ESP_LOGD(TAG, "Size: %d, Quality: %d", res, quality);
#endif
Camera.SetQualitySize(quality, res);
#ifdef DEBUG_DETAIL_ON
ESP_LOGD(TAG, "Size: %d, Quality: %d", CCstatus.ImageFrameSize, CCstatus.ImageQuality);
#endif
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;
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);
// If the camera settings were changed by creating a new reference image, they must be reset
if (CFstatus.changedCameraSettings)
{
Camera.setSensorDatenFromCCstatus(); // CCstatus >>> Kamera
Camera.SetQualityZoomSize(CCstatus.ImageQuality, CCstatus.ImageFrameSize, CCstatus.ImageZoomEnabled, CCstatus.ImageZoomOffsetX, CCstatus.ImageZoomOffsetY, CCstatus.ImageZoomSize, CCstatus.ImageVflip);
CFstatus.changedCameraSettings = false;
}
#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", CCstatus.ImageFrameSize, CCstatus.ImageQuality);
#endif
Camera.SetQualitySize(quality, res);
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];
@@ -197,94 +202,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;
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);
#ifdef DEBUG_DETAIL_ON
ESP_LOGD(TAG, "Size: %d, Quality: %d", res, quality);
#endif
Camera.SetQualitySize(quality, res);
// If the camera settings were changed by creating a new reference image, they must be reset
if (CFstatus.changedCameraSettings)
{
Camera.setSensorDatenFromCCstatus(); // CCstatus >>> Kamera
Camera.SetQualityZoomSize(CCstatus.ImageQuality, CCstatus.ImageFrameSize, CCstatus.ImageZoomEnabled, CCstatus.ImageZoomOffsetX, CCstatus.ImageZoomOffsetY, CCstatus.ImageZoomSize, CCstatus.ImageVflip);
CFstatus.changedCameraSettings = false;
}
#ifdef DEBUG_DETAIL_ON
ESP_LOGD(TAG, "Size: %d, Quality: %d", CCstatus.ImageFrameSize, CCstatus.ImageQuality);
#endif
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);
}

View File

@@ -10,7 +10,6 @@
//#include "ClassControllCamera.h"
void register_server_camera_uri(httpd_handle_t server);
void PowerResetCamera();
#endif

View File

@@ -1,7 +1,7 @@
FILE(GLOB_RECURSE app_sources ${CMAKE_CURRENT_SOURCE_DIR}/*.*)
idf_component_register(SRCS ${app_sources}
INCLUDE_DIRS "." "../../include"
REQUIRES tflite-lib esp_http_server app_update esp_http_client nvs_flash jomjol_tfliteclass jomjol_flowcontroll spiffs jomjol_helper jomjol_controlGPIO miniz)
INCLUDE_DIRS "." "../../include" "miniz"
REQUIRES vfs esp_http_server app_update esp_http_client nvs_flash jomjol_tfliteclass jomjol_flowcontroll spiffs jomjol_helper jomjol_controlGPIO)

View File

@@ -153,7 +153,7 @@
/*#define MINIZ_NO_MALLOC */
#ifdef MINIZ_NO_INFLATE_APIS
#define MINIZ_NO_ARCHIVE_APIS
//#define MINIZ_NO_ARCHIVE_APIS
#endif
#ifdef MINIZ_NO_DEFLATE_APIS

View File

@@ -4,5 +4,5 @@ It should be possible to include the repo directly as a submodule, how ever it c
- https://github.com/richgel999/miniz/issues/145
- https://github.com/espressif/esptool/pull/500#issuecomment-574879468
For sumplicity we therefore use the release files as suggested in the readme.
Additionally we added the CMakeLists.txt and this readme.
For simplicity we therefore use the release files as suggested in the readme.
Additionally we added the CMakeLists.txt and this readme.

View File

@@ -36,7 +36,7 @@ extern "C" {
#include "../../include/defines.h"
#include "ClassLogFile.h"
#include "server_tflite.h"
#include "MainFlowControl.h"
#include "server_help.h"
#ifdef ENABLE_MQTT
@@ -47,7 +47,6 @@ extern "C" {
#include "Helper.h"
#include "miniz.h"
static const char *TAG = "OTA FILE";
struct file_server_data {
@@ -74,7 +73,7 @@ static esp_err_t send_datafile(httpd_req_t *req, bool send_full_file);
esp_err_t get_numbers_file_handler(httpd_req_t *req)
{
std::string ret = tfliteflow.getNumbersName();
std::string ret = flowctrl.getNumbersName();
// ESP_LOGI(TAG, "Result get_numbers_file_handler: %s", ret.c_str());
@@ -228,7 +227,7 @@ static esp_err_t http_resp_dir_html(httpd_req_t *req, const char *dirpath, const
if (chunksize > 0){
if (httpd_resp_send_chunk(req, chunk, chunksize) != ESP_OK) {
fclose(fd);
ESP_LOGE(TAG, "File sending failed!");
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "File sending failed!");
return ESP_FAIL;
}
}
@@ -267,7 +266,7 @@ static esp_err_t http_resp_dir_html(httpd_req_t *req, const char *dirpath, const
strlcpy(entrypath + dirpath_len, entry->d_name, sizeof(entrypath) - dirpath_len);
ESP_LOGD(TAG, "Entrypath: %s", entrypath);
if (stat(entrypath, &entry_stat) == -1) {
ESP_LOGE(TAG, "Failed to stat %s: %s", entrytype, entry->d_name);
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Failed to stat " + string(entrytype) + ": " + string(entry->d_name));
continue;
}
@@ -357,7 +356,7 @@ static esp_err_t send_datafile(httpd_req_t *req, bool send_full_file)
fd = fopen(currentfilename.c_str(), "r");
if (!fd) {
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Failed to read file: " + std::string(currentfilename) +"!");
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Failed to read file: " + currentfilename + "!");
/* Respond with 404 Error */
httpd_resp_send_err(req, HTTPD_404_NOT_FOUND, get404());
return ESP_FAIL;
@@ -373,7 +372,7 @@ static esp_err_t send_datafile(httpd_req_t *req, bool send_full_file)
/* Adapted from https://www.geeksforgeeks.org/implement-your-own-tail-read-last-n-lines-of-a-huge-file/ */
if (fseek(fd, 0, SEEK_END)) {
ESP_LOGE(TAG, "Failed to get to end of file!");
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Failed to get to end of file!");
return ESP_FAIL;
}
else {
@@ -381,7 +380,7 @@ static esp_err_t send_datafile(httpd_req_t *req, bool send_full_file)
ESP_LOGI(TAG, "File contains %ld bytes", pos);
if (fseek(fd, pos - std::min((long)LOGFILE_LAST_PART_BYTES, pos), SEEK_SET)) { // Go LOGFILE_LAST_PART_BYTES bytes back from EOF
ESP_LOGE(TAG, "Failed to go back %ld bytes within the file!", std::min((long)LOGFILE_LAST_PART_BYTES, pos));
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Failed to go back " + to_string(std::min((long)LOGFILE_LAST_PART_BYTES, pos)) + " bytes within the file!");
return ESP_FAIL;
}
}
@@ -404,7 +403,7 @@ static esp_err_t send_datafile(httpd_req_t *req, bool send_full_file)
/* Send the buffer contents as HTTP response chunk */
if (httpd_resp_send_chunk(req, chunk, chunksize) != ESP_OK) {
fclose(fd);
ESP_LOGE(TAG, "File sending failed!");
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "File sending failed!");
/* Abort sending file */
httpd_resp_sendstr_chunk(req, NULL);
/* Respond with 500 Internal Server Error */
@@ -443,7 +442,7 @@ static esp_err_t send_logfile(httpd_req_t *req, bool send_full_file)
fd = fopen(currentfilename.c_str(), "r");
if (!fd) {
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Failed to read file: " + std::string(currentfilename.c_str()) +"!");
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Failed to read file: " + currentfilename + "!");
/* Respond with 404 Error */
httpd_resp_send_err(req, HTTPD_404_NOT_FOUND, get404());
return ESP_FAIL;
@@ -459,7 +458,7 @@ static esp_err_t send_logfile(httpd_req_t *req, bool send_full_file)
/* Adapted from https://www.geeksforgeeks.org/implement-your-own-tail-read-last-n-lines-of-a-huge-file/ */
if (fseek(fd, 0, SEEK_END)) {
ESP_LOGE(TAG, "Failed to get to end of file!");
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Failed to get to end of file!");
return ESP_FAIL;
}
else {
@@ -467,7 +466,7 @@ static esp_err_t send_logfile(httpd_req_t *req, bool send_full_file)
ESP_LOGI(TAG, "File contains %ld bytes", pos);
if (fseek(fd, pos - std::min((long)LOGFILE_LAST_PART_BYTES, pos), SEEK_SET)) { // Go LOGFILE_LAST_PART_BYTES bytes back from EOF
ESP_LOGE(TAG, "Failed to go back %ld bytes within the file!", std::min((long)LOGFILE_LAST_PART_BYTES, pos));
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Failed to go back " + to_string(std::min((long)LOGFILE_LAST_PART_BYTES, pos)) + " bytes within the file!");
return ESP_FAIL;
}
}
@@ -490,7 +489,7 @@ static esp_err_t send_logfile(httpd_req_t *req, bool send_full_file)
/* Send the buffer contents as HTTP response chunk */
if (httpd_resp_send_chunk(req, chunk, chunksize) != ESP_OK) {
fclose(fd);
ESP_LOGE(TAG, "File sending failed!");
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "File sending failed!");
/* Abort sending file */
httpd_resp_sendstr_chunk(req, NULL);
/* Respond with 500 Internal Server Error */
@@ -530,7 +529,7 @@ static esp_err_t download_get_handler(httpd_req_t *req)
if (!filename) {
ESP_LOGE(TAG, "Filename is too long");
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Filename is too long");
/* Respond with 414 Error */
httpd_resp_send_err(req, HTTPD_414_URI_TOO_LONG, "Filename too long");
return ESP_FAIL;
@@ -548,7 +547,7 @@ static esp_err_t download_get_handler(httpd_req_t *req)
/* Get value of expected key from query string */
if (httpd_query_key_value(buf, "readonly", param, sizeof(param)) == ESP_OK) {
ESP_LOGI(TAG, "Found URL query parameter => readonly=%s", param);
readonly = param && strcmp(param,"true")==0;
readonly = (strcmp(param,"true") == 0);
}
}
}
@@ -571,7 +570,7 @@ static esp_err_t download_get_handler(httpd_req_t *req)
fd = fopen(filepath, "r");
if (!fd) {
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Failed to read file: " + std::string(filepath) +"!");
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Failed to read file: " + std::string(filepath) + "!");
/* Respond with 404 Error */
httpd_resp_send_err(req, HTTPD_404_NOT_FOUND, get404());
return ESP_FAIL;
@@ -589,10 +588,12 @@ static esp_err_t download_get_handler(httpd_req_t *req)
/* Read file in chunks into the scratch buffer */
chunksize = fread(chunk, 1, SERVER_FILER_SCRATCH_BUFSIZE, fd);
/* Send the buffer contents as HTTP response chunk */
/* Send buffer contents as HTTP chunk. If empty this functions as a
* last-chunk message, signaling end-of-response, to the HTTP client.
* See RFC 2616, section 3.6.1 for details on Chunked Transfer Encoding. */
if (httpd_resp_send_chunk(req, chunk, chunksize) != ESP_OK) {
fclose(fd);
ESP_LOGE(TAG, "File sending failed!");
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "File sending failed!");
/* Abort sending file */
httpd_resp_sendstr_chunk(req, NULL);
/* Respond with 500 Internal Server Error */
@@ -607,8 +608,6 @@ static esp_err_t download_get_handler(httpd_req_t *req)
fclose(fd);
ESP_LOGD(TAG, "File successfully sent");
/* Respond with an empty chunk to signal HTTP response completion */
httpd_resp_send_chunk(req, NULL, 0);
return ESP_OK;
}
@@ -634,14 +633,14 @@ static esp_err_t upload_post_handler(httpd_req_t *req)
/* Filename cannot have a trailing '/' */
if (filename[strlen(filename) - 1] == '/') {
ESP_LOGE(TAG, "Invalid filename: %s", filename);
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Invalid filename: " + string(filename));
/* Respond with 400 Bad Request */
httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "Invalid filename");
return ESP_FAIL;
}
if (stat(filepath, &file_stat) == 0) {
ESP_LOGE(TAG, "File already exists: %s", filepath);
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "File already exists: " + string(filepath));
/* Respond with 400 Bad Request */
httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "File already exists");
return ESP_FAIL;
@@ -649,7 +648,7 @@ static esp_err_t upload_post_handler(httpd_req_t *req)
/* File cannot be larger than a limit */
if (req->content_len > MAX_FILE_SIZE) {
ESP_LOGE(TAG, "File too large: %d bytes", req->content_len);
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "File too large: " + to_string(req->content_len) + " bytes");
/* Respond with 400 Bad Request */
httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST,
"File size must be less than "
@@ -661,7 +660,7 @@ static esp_err_t upload_post_handler(httpd_req_t *req)
fd = fopen(filepath, "w");
if (!fd) {
ESP_LOGE(TAG, "Failed to create file: %s", filepath);
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Failed to create file: " + string(filepath));
/* Respond with 500 Internal Server Error */
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Failed to create file");
return ESP_FAIL;
@@ -692,7 +691,7 @@ static esp_err_t upload_post_handler(httpd_req_t *req)
fclose(fd);
unlink(filepath);
ESP_LOGE(TAG, "File reception failed!");
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "File reception failed!");
/* Respond with 500 Internal Server Error */
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Failed to receive file");
return ESP_FAIL;
@@ -705,7 +704,7 @@ static esp_err_t upload_post_handler(httpd_req_t *req)
fclose(fd);
unlink(filepath);
ESP_LOGE(TAG, "File write failed!");
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "File write failed!");
/* Respond with 500 Internal Server Error */
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Failed to write file to storage");
return ESP_FAIL;
@@ -718,7 +717,8 @@ static esp_err_t upload_post_handler(httpd_req_t *req)
/* Close file upon upload completion */
fclose(fd);
ESP_LOGI(TAG, "File reception complete");
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "File saved: " + string(filename));
ESP_LOGI(TAG, "File reception completed");
std::string directory = std::string(filepath);
size_t zw = directory.find("/");
@@ -737,21 +737,27 @@ static esp_err_t upload_post_handler(httpd_req_t *req)
// ESP_LOGD(TAG, "Directory danach 2: %s", directory.c_str());
/* Redirect onto root to see the updated file list */
httpd_resp_set_status(req, "303 See Other");
httpd_resp_set_hdr(req, "Location", directory.c_str());
if (strcmp(filename, "/config/config.ini") == 0 ||
strcmp(filename, "/config/ref0.jpg") == 0 ||
strcmp(filename, "/config/ref0_org.jpg") == 0 ||
strcmp(filename, "/config/ref1.jpg") == 0 ||
strcmp(filename, "/config/ref1_org.jpg") == 0 ||
strcmp(filename, "/config/reference.jpg") == 0 ||
strcmp(filename, "/img_tmp/ref0.jpg") == 0 ||
strcmp(filename, "/img_tmp/ref0_org.jpg") == 0 ||
strcmp(filename, "/img_tmp/ref1.jpg") == 0 ||
strcmp(filename, "/img_tmp/ref1_org.jpg") == 0 ||
strcmp(filename, "/img_tmp/reference.jpg") == 0 )
{
httpd_resp_set_status(req, HTTPD_200); // Avoid reloading of folder content
}
else {
httpd_resp_set_status(req, "303 See Other"); // Reload folder content after upload
}
/* Redirect onto root to see the updated file list */
httpd_resp_set_status(req, "303 See Other");
httpd_resp_set_hdr(req, "Location", directory.c_str());
httpd_resp_sendstr(req, "File uploaded successfully");
/*
if (strcmp(filepath, CONFIG_FILE) == 0) {
ESP_LOGD(TAG, "New config found. Reload handler.");
gpio_handler_deinit();
MQTTdestroy();
}
*/
return ESP_OK;
}
@@ -780,7 +786,7 @@ static esp_err_t delete_post_handler(httpd_req_t *req)
if (httpd_query_key_value(_query, "task", _valuechar, 30) == ESP_OK)
{
ESP_LOGD(TAG, "task is found: %s", _valuechar);
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "task is found: " + string(_valuechar));
_task = std::string(_valuechar);
}
}
@@ -826,28 +832,27 @@ static esp_err_t delete_post_handler(httpd_req_t *req)
/* Filename cannot have a trailing '/' */
if (filename[strlen(filename) - 1] == '/') {
ESP_LOGE(TAG, "Invalid filename: %s", filename);
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Invalid filename: " + string(filename));
/* Respond with 400 Bad Request */
httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "Invalid filename");
return ESP_FAIL;
}
if (strcmp(filename, "wlan.ini") == 0) {
ESP_LOGE(TAG, "Trying to delete protected file : %s", filename);
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Failed to delete protected file : " + string(filename));
httpd_resp_send_err(req, HTTPD_403_FORBIDDEN, "Not allowed to delete wlan.ini");
return ESP_FAIL;
}
if (stat(filepath, &file_stat) == -1) {
ESP_LOGE(TAG, "File does not exist: %s", filename);
/* Respond with 400 Bad Request */
httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "File does not exist");
return ESP_FAIL;
if (stat(filepath, &file_stat) == -1) { // File does not exist
/* This is ok, we would delete it anyway */
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "File does not exist: " + string(filename));
}
ESP_LOGI(TAG, "Deleting file: %s", filename);
/* Delete file */
unlink(filepath);
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "File deleted: " + string(filename));
ESP_LOGI(TAG, "File deletion completed");
directory = std::string(filepath);
size_t zw = directory.find("/");
@@ -864,16 +869,30 @@ static esp_err_t delete_post_handler(httpd_req_t *req)
directory = directory.substr(start_fn, found - start_fn + 1);
directory = "/fileserver" + directory;
ESP_LOGD(TAG, "Directory danach 4: %s", directory.c_str());
}
//////////////////////////////////////////////////////////////
/* Redirect onto root to see the updated file list */
if (strcmp(filename, "/config/config.ini") == 0 ||
strcmp(filename, "/config/ref0.jpg") == 0 ||
strcmp(filename, "/config/ref0_org.jpg") == 0 ||
strcmp(filename, "/config/ref1.jpg") == 0 ||
strcmp(filename, "/config/ref1_org.jpg") == 0 ||
strcmp(filename, "/config/reference.jpg") == 0 ||
strcmp(filename, "/img_tmp/ref0.jpg") == 0 ||
strcmp(filename, "/img_tmp/ref0_org.jpg") == 0 ||
strcmp(filename, "/img_tmp/ref1.jpg") == 0 ||
strcmp(filename, "/img_tmp/ref1_org.jpg") == 0 ||
strcmp(filename, "/img_tmp/reference.jpg") == 0 )
{
httpd_resp_set_status(req, HTTPD_200); // Avoid reloading of folder content
}
else {
httpd_resp_set_status(req, "303 See Other"); // Reload folder content after upload
}
}
//////////////////////////////////////////////////////////////
/* Redirect onto root to see the updated file list */
httpd_resp_set_status(req, "303 See Other");
httpd_resp_set_hdr(req, "Location", directory.c_str());
httpd_resp_sendstr(req, "File successfully deleted");
return ESP_OK;
@@ -887,7 +906,7 @@ void delete_all_in_directory(std::string _directory)
std::string filename;
if (!dir) {
ESP_LOGE(TAG, "Failed to stat dir: %s", _directory.c_str());
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Failed to stat dir: " + _directory);
return;
}
@@ -896,7 +915,7 @@ void delete_all_in_directory(std::string _directory)
if (!(entry->d_type == DT_DIR)){
if (strcmp("wlan.ini", entry->d_name) != 0){ // auf wlan.ini soll nicht zugegriffen werden !!!
filename = _directory + "/" + std::string(entry->d_name);
ESP_LOGI(TAG, "Deleting file: %s", filename.c_str());
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Deleting file: " + filename);
/* Delete file */
unlink(filename.c_str());
}
@@ -930,7 +949,7 @@ std::string unzip_new(std::string _in_zip_file, std::string _target_zip, std::st
// Get and print information about each file in the archive.
int numberoffiles = (int)mz_zip_reader_get_num_files(&zip_archive);
ESP_LOGI(TAG, "Numbers of files to be extracted: %d", numberoffiles);
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Files to be extracted: " + to_string(numberoffiles));
sort_iter = 0;
{
@@ -953,7 +972,7 @@ std::string unzip_new(std::string _in_zip_file, std::string _target_zip, std::st
p = mz_zip_reader_extract_file_to_heap(&zip_archive, archive_filename, &uncomp_size, 0);
if (!p)
{
ESP_LOGE(TAG, "mz_zip_reader_extract_file_to_heap() failed on file %s", archive_filename);
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "mz_zip_reader_extract_file_to_heap() failed on file " + string(archive_filename));
mz_zip_reader_end(&zip_archive);
return ret;
}
@@ -994,10 +1013,14 @@ std::string unzip_new(std::string _in_zip_file, std::string _target_zip, std::st
string filename_zw = zw + SUFFIX_ZW;
ESP_LOGI(TAG, "Filename to extract: %s, Zwischenfilename: %s", zw.c_str(), filename_zw.c_str());
ESP_LOGI(TAG, "File to extract: %s, Temp. Filename: %s", zw.c_str(), filename_zw.c_str());
std::string folder = filename_zw.substr(0, filename_zw.find_last_of('/'));
MakeDir(folder);
// extrahieren in zwischendatei
DeleteFile(filename_zw);
FILE* fpTargetFile = fopen(filename_zw.c_str(), "wb");
uint writtenbytes = fwrite(p, 1, (uint)uncomp_size, fpTargetFile);
fclose(fpTargetFile);
@@ -1011,21 +1034,22 @@ std::string unzip_new(std::string _in_zip_file, std::string _target_zip, std::st
else
{
isokay = false;
ESP_LOGD(TAG, "ERROR in writting extracted file (function fwrite) extracted file \"%s\", size %u", archive_filename, (uint)uncomp_size);
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "ERROR in writting extracted file (function fwrite) extracted file \"" +
string(archive_filename) + "\", size " + to_string(uncomp_size));
}
DeleteFile(zw);
if (!isokay)
ESP_LOGE(TAG, "ERROR in fwrite \"%s\", size %u", archive_filename, (uint)uncomp_size);
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "ERROR in fwrite \"" + string(archive_filename) + "\", size " + to_string(uncomp_size));
isokay = isokay && RenameFile(filename_zw, zw);
if (!isokay)
ESP_LOGE(TAG, "ERROR in Rename \"%s\" to \"%s\"", filename_zw.c_str(), zw.c_str());
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "ERROR in Rename \"" + filename_zw + "\" to \"" + zw);
if (isokay)
ESP_LOGI(TAG, "Successfully extracted file \"%s\", size %u", archive_filename, (uint)uncomp_size);
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Successfully extracted file \"" + string(archive_filename) + "\", size " + to_string(uncomp_size));
else
{
ESP_LOGE(TAG, "ERROR in extracting file \"%s\", size %u", archive_filename, (uint)uncomp_size);
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "ERROR in extracting file \"" + string(archive_filename) + "\", size " + to_string(uncomp_size));
ret = "ERROR";
}
mz_free(p);
@@ -1059,7 +1083,7 @@ void unzip(std::string _in_zip_file, std::string _target_directory){
status = mz_zip_reader_init_file(&zip_archive, _in_zip_file.c_str(), 0);
if (!status)
{
ESP_LOGD(TAG, "mz_zip_reader_init_file() failed!");
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "mz_zip_reader_init_file() failed!");
return;
}
@@ -1071,7 +1095,7 @@ void unzip(std::string _in_zip_file, std::string _target_directory){
status = mz_zip_reader_init_file(&zip_archive, _in_zip_file.c_str(), sort_iter ? MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY : 0);
if (!status)
{
ESP_LOGD(TAG, "mz_zip_reader_init_file() failed!");
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "mz_zip_reader_init_file() failed!");
return;
}
@@ -1085,7 +1109,7 @@ void unzip(std::string _in_zip_file, std::string _target_directory){
p = mz_zip_reader_extract_file_to_heap(&zip_archive, archive_filename, &uncomp_size, 0);
if (!p)
{
ESP_LOGD(TAG, "mz_zip_reader_extract_file_to_heap() failed!");
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "mz_zip_reader_extract_file_to_heap() failed!");
mz_zip_reader_end(&zip_archive);
return;
}
@@ -1093,7 +1117,7 @@ void unzip(std::string _in_zip_file, std::string _target_directory){
// Save to File.
zw = std::string(archive_filename);
zw = _target_directory + zw;
ESP_LOGD(TAG, "Filename to extract: %s", zw.c_str());
ESP_LOGD(TAG, "File to extract: %s", zw.c_str());
FILE* fpTargetFile = fopen(zw.c_str(), "wb");
fwrite(p, 1, (uint)uncomp_size, fpTargetFile);
fclose(fpTargetFile);
@@ -1121,19 +1145,19 @@ void register_server_file_uri(httpd_handle_t server, const char *base_path)
/* Validate file storage base path */
if (!base_path) {
// if (!base_path || strcmp(base_path, "/spiffs") != 0) {
ESP_LOGE(TAG, "File server base_path not set");
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "File server base_path not set");
// return ESP_ERR_INVALID_ARG;
}
if (server_data) {
ESP_LOGE(TAG, "File server already started");
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "File server already started");
// return ESP_ERR_INVALID_STATE;
}
/* Allocate memory for server data */
server_data = (file_server_data *) calloc(1, sizeof(struct file_server_data));
if (!server_data) {
ESP_LOGE(TAG, "Failed to allocate memory for server data");
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Failed to allocate memory for server data");
// return ESP_ERR_NO_MEM;
}
strlcpy(server_data->base_path, base_path,

View File

@@ -61,7 +61,13 @@ esp_err_t send_file(httpd_req_t *req, std::string filename)
endsWith(filename, ".jpeg") ||
endsWith(filename, ".ico") ||
endsWith(filename, ".png")) {
httpd_resp_set_hdr(req, "Cache-Control", "max-age=86400");
if (filename == "/sdcard/html/setup.html") {
httpd_resp_set_hdr(req, "Clear-Site-Data", "\"*\"");
}
else {
httpd_resp_set_hdr(req, "Cache-Control", "max-age=86400");
}
}
set_content_type_from_file(req, filename.c_str());

View File

@@ -3,7 +3,10 @@
#include <string>
#include "string.h"
#include <esp_int_wdt.h>
/* TODO Rethink the usage of the int watchdog. It is no longer to be used, see
https://docs.espressif.com/projects/esp-idf/en/latest/esp32/migration-guides/release-5.x/5.0/system.html?highlight=esp_int_wdt */
#include "esp_private/esp_int_wdt.h"
#include <esp_task_wdt.h>
@@ -11,14 +14,13 @@
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "esp_event.h"
#include "esp_event.h"
#include "esp_log.h"
#include <esp_ota_ops.h>
#include "esp_http_client.h"
#include "esp_flash_partitions.h"
#include "esp_partition.h"
#include <nvs.h>
#include "esp_app_format.h"
#include "nvs_flash.h"
#include "driver/gpio.h"
// #include "protocol_examples_common.h"
@@ -26,7 +28,7 @@
#include <sys/stat.h>
#include "server_tflite.h"
#include "MainFlowControl.h"
#include "server_file.h"
#include "server_GPIO.h"
#ifdef ENABLE_MQTT
@@ -39,6 +41,7 @@
#include "ClassLogFile.h"
#include "Helper.h"
#include "statusled.h"
#include "../../include/defines.h"
/*an ota data write buffer ready to write to the flash*/
@@ -56,9 +59,9 @@ bool initial_setup = false;
static void infinite_loop(void)
{
int i = 0;
ESP_LOGI(TAG, "When a new firmware is available on the server, press the reset button to download it");
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "When a new firmware is available on the server, press the reset button to download it");
while(1) {
ESP_LOGI(TAG, "Waiting for a new firmware... %d", ++i);
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Waiting for a new firmware... (" + to_string(++i) + ")");
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
}
@@ -66,6 +69,8 @@ static void infinite_loop(void)
void task_do_Update_ZIP(void *pvParameter)
{
StatusLED(AP_OR_OTA, 1, true); // Signaling an OTA update
std::string filetype = toUpper(getFileType(_file_name_update));
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "File: " + _file_name_update + " Filetype: " + filetype);
@@ -87,13 +92,13 @@ void task_do_Update_ZIP(void *pvParameter)
ota_update_task(retfirmware);
}
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Trigger reboot due to firmware update.");
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Trigger reboot due to firmware update");
doRebootOTA();
} else if (filetype == "BIN")
{
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Do firmware update - file: " + _file_name_update);
ota_update_task(_file_name_update);
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Trigger reboot due to firmware update.");
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Trigger reboot due to firmware update");
doRebootOTA();
}
else
@@ -108,7 +113,7 @@ void CheckUpdate()
FILE *pfile;
if ((pfile = fopen("/sdcard/update.txt", "r")) == NULL)
{
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "No update triggered.");
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "No pending update");
return;
}
@@ -120,13 +125,13 @@ void CheckUpdate()
std::string _szw = std::string(zw);
if (_szw == "init")
{
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Inital Setup triggered.");
initial_setup = true; }
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Inital Setup triggered");
}
}
fclose(pfile);
DeleteFile("/sdcard/update.txt"); // Prevent Boot Loop!!!
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Update during boot triggered - Update File: " + _file_name_update);
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Start update process (" + _file_name_update + ")");
xTaskCreate(&task_do_Update_ZIP, "task_do_Update_ZIP", configMINIMAL_STACK_SIZE * 35, NULL, tskIDLE_PRIORITY+1, NULL);
@@ -148,18 +153,18 @@ static bool ota_update_task(std::string fn)
const esp_partition_t *configured = esp_ota_get_boot_partition();
const esp_partition_t *running = esp_ota_get_running_partition();
if (configured != running) {
ESP_LOGW(TAG, "Configured OTA boot partition at offset 0x%08x, but running from offset 0x%08x",
configured->address, running->address);
ESP_LOGW(TAG, "(This can happen if either the OTA boot data or preferred boot image become somehow corrupted.)");
if (configured != running) {
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Configured OTA boot partition at offset " + to_string(configured->address) +
", but running from offset " + to_string(running->address));
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "(This can happen if either the OTA boot data or preferred boot image become somehow corrupted.)");
}
ESP_LOGI(TAG, "Running partition type %d subtype %d (offset 0x%08x)",
running->type, running->subtype, running->address);
running->type, running->subtype, (unsigned int)running->address);
update_partition = esp_ota_get_next_update_partition(NULL);
ESP_LOGI(TAG, "Writing to partition subtype %d at offset 0x%x",
update_partition->subtype, update_partition->address);
update_partition->subtype, (unsigned int)update_partition->address);
// assert(update_partition != NULL);
int binary_file_length = 0;
@@ -179,7 +184,7 @@ static bool ota_update_task(std::string fn)
while (data_read > 0) {
if (data_read < 0) {
ESP_LOGE(TAG, "Error: SSL data read error");
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Error: SSL data read error");
return false;
} else if (data_read > 0) {
if (image_header_was_checked == false) {
@@ -203,16 +208,17 @@ static bool ota_update_task(std::string fn)
// check current version with last invalid partition
if (last_invalid_app != NULL) {
if (memcmp(invalid_app_info.version, new_app_info.version, sizeof(new_app_info.version)) == 0) {
ESP_LOGW(TAG, "New version is the same as invalid version.");
ESP_LOGW(TAG, "Previously, there was an attempt to launch the firmware with %s version, but it failed.", invalid_app_info.version);
ESP_LOGW(TAG, "The firmware has been rolled back to the previous version.");
LogFile.WriteToFile(ESP_LOG_WARN, TAG, "New version is the same as invalid version");
LogFile.WriteToFile(ESP_LOG_WARN, TAG, "Previously, there was an attempt to launch the firmware with " +
string(invalid_app_info.version) + " version, but it failed");
LogFile.WriteToFile(ESP_LOG_WARN, TAG, "The firmware has been rolled back to the previous version");
infinite_loop();
}
}
/*
if (memcmp(new_app_info.version, running_app_info.version, sizeof(new_app_info.version)) == 0) {
ESP_LOGW(TAG, "Current running version is the same as a new. We will not continue the update.");
LogFile.WriteToFile(ESP_LOG_WARN, TAG, "Current running version is the same as a new. We will not continue the update");
infinite_loop();
}
*/
@@ -220,12 +226,12 @@ static bool ota_update_task(std::string fn)
err = esp_ota_begin(update_partition, OTA_SIZE_UNKNOWN, &update_handle);
if (err != ESP_OK) {
ESP_LOGE(TAG, "esp_ota_begin failed (%s)", esp_err_to_name(err));
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "esp_ota_begin failed (" + string(esp_err_to_name(err)) + ")");
return false;
}
ESP_LOGI(TAG, "esp_ota_begin succeeded");
} else {
ESP_LOGE(TAG, "received package is not fit len");
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "received package is not fit len");
return false;
}
}
@@ -241,7 +247,7 @@ static bool ota_update_task(std::string fn)
// * `errno` to check for underlying transport connectivity closure if any
//
if (errno == ECONNRESET || errno == ENOTCONN) {
ESP_LOGE(TAG, "Connection closed, errno = %d", errno);
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Connection closed, errno = " + to_string(errno));
break;
}
}
@@ -254,15 +260,15 @@ static bool ota_update_task(std::string fn)
err = esp_ota_end(update_handle);
if (err != ESP_OK) {
if (err == ESP_ERR_OTA_VALIDATE_FAILED) {
ESP_LOGE(TAG, "Image validation failed, image is corrupted");
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Image validation failed, image is corrupted");
}
ESP_LOGE(TAG, "esp_ota_end failed (%s)!", esp_err_to_name(err));
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "esp_ota_end failed (" + string(esp_err_to_name(err)) + ")!");
return false;
}
err = esp_ota_set_boot_partition(update_partition);
if (err != ESP_OK) {
ESP_LOGE(TAG, "esp_ota_set_boot_partition failed (%s)!", esp_err_to_name(err));
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "esp_ota_set_boot_partition failed (" + string(esp_err_to_name(err)) + ")!");
}
// ESP_LOGI(TAG, "Prepare to restart system!");
@@ -329,7 +335,7 @@ void CheckOTAUpdate(void)
ESP_LOGI(TAG, "Diagnostics completed successfully! Continuing execution...");
esp_ota_mark_app_valid_cancel_rollback();
} else {
ESP_LOGE(TAG, "Diagnostics failed! Start rollback to the previous version...");
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Diagnostics failed! Start rollback to the previous version...");
esp_ota_mark_app_invalid_rollback_and_reboot();
}
}
@@ -353,7 +359,7 @@ void CheckOTAUpdate(void)
ESP_LOGI(TAG, "Diagnostics completed successfully! Continuing execution...");
esp_ota_mark_app_valid_cancel_rollback();
} else {
ESP_LOGE(TAG, "Diagnostics failed! Start rollback to the previous version...");
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Diagnostics failed! Start rollback to the previous version...");
esp_ota_mark_app_invalid_rollback_and_reboot();
}
}
@@ -445,7 +451,7 @@ esp_err_t handler_ota_update(httpd_req_t *req)
if ((filetype == "ZIP") || (filetype == "BIN"))
{
FILE *pfile;
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Update for reboot.");
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Update for reboot");
pfile = fopen("/sdcard/update.txt", "w");
fwrite(fn.c_str(), fn.length(), 1, pfile);
fclose(pfile);
@@ -463,7 +469,7 @@ esp_err_t handler_ota_update(httpd_req_t *req)
{
const char* resp_str;
KillTFliteTasks();
DeleteMainFlowTask();
gpio_handler_deinit();
if (ota_update_task(fn))
{
@@ -522,7 +528,7 @@ esp_err_t handler_ota_update(httpd_req_t *req)
}
else
{
ESP_LOGD(TAG, "File does not exist: %s", fn.c_str());
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "File does not exist: " + fn);
}
/* Respond with an empty chunk to signal HTTP response completion */
std::string zw = "file deleted\n";
@@ -537,12 +543,12 @@ esp_err_t handler_ota_update(httpd_req_t *req)
httpd_resp_send(req, zw.c_str(), strlen(zw.c_str()));
httpd_resp_send_chunk(req, NULL, 0);
ESP_LOGE(TAG, "ota without parameter - should not be the case!");
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "ota without parameter - should not be the case!");
/*
const char* resp_str;
KillTFliteTasks();
DeleteMainFlowTask();
gpio_handler_deinit();
if (ota_update_task(fn))
{
@@ -566,13 +572,19 @@ esp_err_t handler_ota_update(httpd_req_t *req)
void hard_restart()
{
esp_task_wdt_init(1,true);
esp_task_wdt_config_t twdt_config = {
.timeout_ms = 1,
.idle_core_mask = (1 << portNUM_PROCESSORS) - 1, // Bitmask of all cores
.trigger_panic = true,
};
ESP_ERROR_CHECK(esp_task_wdt_init(&twdt_config));
esp_task_wdt_add(NULL);
while(true);
}
void task_reboot(void *KillAutoFlow)
void task_reboot(void *DeleteMainFlow)
{
// write a reboot, to identify a reboot by purpouse
FILE* pfile = fopen("/sdcard/reboot.txt", "w");
@@ -582,10 +594,13 @@ void task_reboot(void *KillAutoFlow)
vTaskDelay(3000 / portTICK_PERIOD_MS);
if ((bool)KillAutoFlow) {
KillTFliteTasks(); // Kill autoflow task if executed in extra task, if not don't kill parent task
if ((bool)DeleteMainFlow) {
DeleteMainFlowTask(); // Kill autoflow task if executed in extra task, if not don't kill parent task
}
Camera.LightOnOff(false);
StatusLEDOff();
/* Stop service tasks */
#ifdef ENABLE_MQTT
MQTTdestroy_client(true);
@@ -600,20 +615,20 @@ void task_reboot(void *KillAutoFlow)
vTaskDelay(5000 / portTICK_PERIOD_MS);
hard_restart(); // Reset type: System reset (Triggered by watchdog), if esp_restart stalls (WDT needs to be activated)
ESP_LOGE(TAG, "Reboot failed!");
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Reboot failed!");
vTaskDelete(NULL); //Delete this task if it comes to this point
}
void doReboot()
{
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Reboot triggered by Software (5s).");
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Reboot triggered by Software (5s)");
LogFile.WriteToFile(ESP_LOG_WARN, TAG, "Reboot in 5sec");
BaseType_t xReturned = xTaskCreate(&task_reboot, "task_reboot", configMINIMAL_STACK_SIZE * 3, (void*) true, 10, NULL);
BaseType_t xReturned = xTaskCreate(&task_reboot, "task_reboot", configMINIMAL_STACK_SIZE * 4, (void*) true, 10, NULL);
if( xReturned != pdPASS )
{
ESP_LOGE(TAG, "task_reboot not created -> force reboot without killing flow");
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "task_reboot not created -> force reboot without killing flow");
task_reboot((void*) false);
}
vTaskDelay(10000 / portTICK_PERIOD_MS); // Prevent serving web client fetch response until system is shuting down
@@ -624,6 +639,8 @@ void doRebootOTA()
{
LogFile.WriteToFile(ESP_LOG_WARN, TAG, "Reboot in 5sec");
Camera.LightOnOff(false);
StatusLEDOff();
esp_camera_deinit();
vTaskDelay(5000 / portTICK_PERIOD_MS);
@@ -641,7 +658,7 @@ esp_err_t handler_reboot(httpd_req_t *req)
#endif
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "handler_reboot");
ESP_LOGI(TAG, "!!! System will restart within 5 sec!!!");
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "!!! System will restart within 5 sec!!!");
std::string response =
"<html><head><script>"

View File

@@ -2,6 +2,6 @@ FILE(GLOB_RECURSE app_sources ${CMAKE_CURRENT_SOURCE_DIR}/*.*)
idf_component_register(SRCS ${app_sources}
INCLUDE_DIRS "."
REQUIRES jomjol_tfliteclass jomjol_helper jomjol_controlcamera jomjol_mqtt jomjol_influxdb jomjol_fileserver_ota jomjol_image_proc jomjol_wlan)
REQUIRES esp_timer esp_wifi jomjol_tfliteclass jomjol_helper jomjol_controlcamera jomjol_mqtt jomjol_influxdb jomjol_webhook jomjol_fileserver_ota jomjol_image_proc jomjol_wlan openmetrics)

View File

@@ -67,11 +67,6 @@ string ClassFlow::getHTMLSingleStep(string host){
return "";
}
string ClassFlow::getReadout()
{
return string();
}
std::string ClassFlow::GetParameterName(std::string _input)
{
string _param;

View File

@@ -46,7 +46,6 @@ public:
virtual bool ReadParameter(FILE* pfile, string &aktparamgraph);
virtual bool doFlow(string time);
virtual string getHTMLSingleStep(string host);
virtual string getReadout();
virtual string name(){return "ClassFlow";};
};

View File

@@ -1,376 +1,374 @@
#include "ClassFlowAlignment.h"
#include "ClassFlowTakeImage.h"
#include "ClassFlow.h"
#include "server_tflite.h"
#include "CRotateImage.h"
#include "esp_log.h"
#include "ClassLogFile.h"
#include "../../include/defines.h"
static const char *TAG = "ALIGN";
// #define DEBUG_DETAIL_ON
void ClassFlowAlignment::SetInitialParameter(void)
{
initalrotate = 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*)heap_caps_malloc(sizeof(ImageData), MALLOC_CAP_8BIT | MALLOC_CAP_SPIRAM);
#endif
previousElement = NULL;
disabled = false;
SAD_criteria = 0.05;
}
ClassFlowAlignment::ClassFlowAlignment(std::vector<ClassFlow*>* 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(namerawimage);
}
}
bool ClassFlowAlignment::ReadParameter(FILE* pfile, string& aktparamgraph)
{
std::vector<string> splitted;
int suchex = 40;
int suchey = 40;
int alg_algo = 0;
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]) == "INITALROTATE") || (toUpper(splitted[0]) == "INITIALROTATE")) && (splitted.size() > 1))
{
this->initalrotate = 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;
}
}
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
}
LoadReferenceAlignmentValues();
return true;
}
string ClassFlowAlignment::getHTMLSingleStep(string host)
{
string result;
result = "<p>Rotated Image: </p> <p><img src=\"" + host + "/img_tmp/rot.jpg\"></p>\n";
result = result + "<p>Found Alignment: </p> <p><img src=\"" + host + "/img_tmp/rot_roi.jpg\"></p>\n";
result = result + "<p>Aligned Image: </p> <p><img src=\"" + host + "/img_tmp/alg.jpg\"></p>\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(ImageBasis);
if (!ImageTMP)
{
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Can't allocate ImageTMP -> Exec this round aborted!");
LogFile.WriteHeapInfo("ClassFlowAlignment-doFlow");
return false;
}
}
delete AlignAndCutImage;
AlignAndCutImage = new CAlignAndCutImage(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(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 ((initalrotate != 0) || initialflip)
{
if (use_antialiasing)
rt.RotateAntiAliasing(initalrotate);
else
rt.Rotate(initalrotate);
if (SaveAllFiles)
AlignAndCutImage->SaveToFile(FormatFileName("/sdcard/img_tmp/rot.jpg"));
}
if (!AlignAndCutImage->Align(&References[0], &References[1]))
{
SaveReferenceAlignmentValues();
}
#ifdef ALGROI_LOAD_FROM_MEM_AS_JPG
if (AlgROI) {
DrawRef(ImageTMP);
tfliteflow.DigitalDrawROI(ImageTMP);
tfliteflow.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;
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<string> 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<ClassFlow *> *lfc)
{
SetInitialParameter();
ListFlowControll = lfc;
for (int i = 0; i < ListFlowControll->size(); ++i) {
if (((*ListFlowControll)[i])->name().compare("ClassFlowTakeImage") == 0) {
ImageBasis = ((ClassFlowTakeImage *)(*ListFlowControll)[i])->rawImage;
}
}
// the function take pictures does not exist --> must be created first ONLY FOR TEST PURPOSES
if (!ImageBasis) {
ESP_LOGD(TAG, "CImageBasis had to be created");
ImageBasis = new CImageBasis("ImageBasis", namerawimage);
}
}
bool ClassFlowAlignment::ReadParameter(FILE *pfile, string &aktparamgraph)
{
std::vector<string> 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)) {
initialflip = alphanumericToBoolean(splitted[1]);
}
else if (((toUpper(splitted[0]) == "initialrotate") || (toUpper(splitted[0]) == "INITIALROTATE")) && (splitted.size() > 1)) {
if (isStringNumeric(splitted[1])) {
this->initialrotate = std::stod(splitted[1]);
}
}
else if ((toUpper(splitted[0]) == "SEARCHFIELDX") && (splitted.size() > 1)) {
if (isStringNumeric(splitted[1])) {
suchex = std::stod(splitted[1]);
}
}
else if ((toUpper(splitted[0]) == "SEARCHFIELDY") && (splitted.size() > 1)) {
if (isStringNumeric(splitted[1])) {
suchey = std::stod(splitted[1]);
}
}
else if ((toUpper(splitted[0]) == "ANTIALIASING") && (splitted.size() > 1)) {
use_antialiasing = alphanumericToBoolean(splitted[1]);
}
else if ((splitted.size() == 3) && (anz_ref < 2)) {
if ((isStringNumeric(splitted[1])) && (isStringNumeric(splitted[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
{
References[anz_ref].image_file = FormatFileName("/sdcard" + splitted[0]);
References[anz_ref].target_x = 10;
References[anz_ref].target_y = 10;
anz_ref++;
}
}
else if ((toUpper(splitted[0]) == "SAVEALLFILES") && (splitted.size() > 1)) {
SaveAllFiles = alphanumericToBoolean(splitted[1]);
}
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) {
return LoadReferenceAlignmentValues();
}
return true;
}
string ClassFlowAlignment::getHTMLSingleStep(string host)
{
string result;
result = "<p>Rotated Image: </p> <p><img src=\"" + host + "/img_tmp/rot.jpg\"></p>\n";
result = result + "<p>Found Alignment: </p> <p><img src=\"" + host + "/img_tmp/rot_roi.jpg\"></p>\n";
result = result + "<p>Aligned Image: </p> <p><img src=\"" + host + "/img_tmp/alg.jpg\"></p>\n";
return result;
}
bool ClassFlowAlignment::doFlow(string time)
{
#ifdef ALGROI_LOAD_FROM_MEM_AS_JPG
// AlgROI needs to be allocated before ImageTMP to avoid heap fragmentation
if (!AlgROI) {
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.DigitDrawROI(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) {
return 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<string> 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);
}
}

View File

@@ -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 <string>
using namespace std;
class ClassFlowAlignment :
public ClassFlow
{
protected:
float initalrotate;
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<ClassFlow*>* 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 <string>
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<ClassFlow *> *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

File diff suppressed because it is too large Load Diff

View File

@@ -11,10 +11,10 @@ enum t_CNNType {
AutoDetect,
Analogue,
Analogue100,
Digital,
DigitalHyprid10,
Digit,
DigitHyprid10,
DoubleHyprid10,
Digital100,
Digit100,
None
};
@@ -26,15 +26,6 @@ protected:
std::vector<general*> GENERAL;
float CNNGoodThreshold;
//moved to define.h
//float Analog_error = 3.0;
//float AnalogToDigtalFehler = 0.8;
//float Digital_Uncertainty = 0.2;
//int DigitalBand = 3;
//float Digital_Transition_Range_Predecessor = 2;
//float Digital_Transition_Area_Predecessor = 0.7; // 9.3 - 0.7
//float Digital_Transition_Area_Forward = 9.7; // Pre-run zero crossing only happens from approx. 9.7 onwards
string cnnmodelfile;
int modelxsize, modelysize, modelchannel;
bool isLogImageSelect;
@@ -44,8 +35,8 @@ protected:
bool SaveAllFiles;
int PointerEvalAnalogNew(float zahl, int numeral_preceder);
int PointerEvalAnalogToDigitNew(float zahl, float numeral_preceder, int eval_predecessors, float analogDigitalTransitionStart);
int PointerEvalHybridNew(float zahl, float number_of_predecessors, int eval_predecessors, bool Analog_Predecessors = false, float analogDigitalTransitionStart=9.2);
int PointerEvalAnalogToDigitNew(float zahl, float numeral_preceder, int eval_predecessors, float AnalogToDigitTransitionStart);
int PointerEvalHybridNew(float zahl, float number_of_predecessors, int eval_predecessors, bool Analog_Predecessors = false, float AnalogToDigitTransitionStart=9.2);
@@ -61,7 +52,7 @@ public:
bool doFlow(string time);
string getHTMLSingleStep(string host);
string getReadout(int _analog, bool _extendedResolution = false, int prev = -1, float _before_narrow_Analog = -1, float analogDigitalTransitionStart=9.2);
string getReadout(int _analog, bool _extendedResolution = false, int prev = -1, float _before_narrow_Analog = -1, float AnalogToDigitTransitionStart=9.2);
string getReadoutRawString(int _analog);

View File

@@ -25,13 +25,13 @@ extern "C" {
#endif //ENABLE_MQTT
#include "server_help.h"
#include "MainFlowControl.h"
#include "../../include/defines.h"
static const char* TAG = "CTRL";
static const char* TAG = "FLOWCTRL";
//#define DEBUG_DETAIL_ON
std::string ClassFlowControll::doSingleStep(std::string _stepname, std::string _host){
std::string _classname = "";
std::string result = "";
@@ -60,12 +60,23 @@ std::string ClassFlowControll::doSingleStep(std::string _stepname, std::string _
if ((_stepname.compare("[InfluxDB]") == 0) || (_stepname.compare(";[InfluxDB]") == 0)){
_classname = "ClassFlowInfluxDB";
}
if ((_stepname.compare("[InfluxDBv2]") == 0) || (_stepname.compare(";[InfluxDBv2]") == 0)){
_classname = "ClassFlowInfluxDBv2";
}
#endif //ENABLE_INFLUXDB
#ifdef ENABLE_WEBHOOK
if ((_stepname.compare("[Webhook]") == 0) || (_stepname.compare(";[Webhook]") == 0)){
_classname = "ClassFlowWebhook";
}
#endif //ENABLE_WEBHOOK
for (int i = 0; i < FlowControll.size(); ++i)
if (FlowControll[i]->name().compare(_classname) == 0){
if (!(FlowControll[i]->name().compare("ClassFlowTakeImage") == 0)) // if it is a TakeImage, the image does not need to be included, this happens automatically with the html query.
if (!(FlowControll[i]->name().compare("ClassFlowTakeImage") == 0)) {
// if it is a TakeImage, the image does not need to be included, this happens automatically with the html query.
FlowControll[i]->doFlow("");
}
result = FlowControll[i]->getHTMLSingleStep(_host);
}
@@ -74,37 +85,51 @@ std::string ClassFlowControll::doSingleStep(std::string _stepname, std::string _
return result;
}
std::string ClassFlowControll::TranslateAktstatus(std::string _input)
{
if (_input.compare("ClassFlowTakeImage") == 0)
if (_input.compare("ClassFlowTakeImage") == 0) {
return ("Take Image");
if (_input.compare("ClassFlowAlignment") == 0)
}
if (_input.compare("ClassFlowAlignment") == 0) {
return ("Aligning");
if (_input.compare("ClassFlowCNNGeneral") == 0)
return ("Digitalization of ROIs");
}
if (_input.compare("ClassFlowCNNGeneral") == 0) {
return ("Digitization of ROIs");
}
#ifdef ENABLE_MQTT
if (_input.compare("ClassFlowMQTT") == 0)
if (_input.compare("ClassFlowMQTT") == 0) {
return ("Sending MQTT");
}
#endif //ENABLE_MQTT
#ifdef ENABLE_INFLUXDB
if (_input.compare("ClassFlowInfluxDB") == 0)
if (_input.compare("ClassFlowInfluxDB") == 0) {
return ("Sending InfluxDB");
}
if (_input.compare("ClassFlowInfluxDBv2") == 0) {
return ("Sending InfluxDBv2");
}
#endif //ENABLE_INFLUXDB
if (_input.compare("ClassFlowPostProcessing") == 0)
#ifdef ENABLE_WEBHOOK
if (_input.compare("ClassFlowWebhook") == 0) {
return ("Sending Webhook");
}
#endif //ENABLE_WEBHOOK
if (_input.compare("ClassFlowPostProcessing") == 0) {
return ("Post-Processing");
if (_input.compare("ClassFlowWriteList") == 0)
return ("Writing List");
}
return "Unkown Status";
}
std::vector<HTMLInfo*> ClassFlowControll::GetAllDigital()
std::vector<HTMLInfo*> ClassFlowControll::GetAllDigit()
{
if (flowdigit)
{
ESP_LOGD(TAG, "ClassFlowControll::GetAllDigital - flowdigit != NULL");
if (flowdigit) {
ESP_LOGD(TAG, "ClassFlowControll::GetAllDigit - flowdigit != NULL");
return flowdigit->GetHTMLInfo();
}
@@ -112,73 +137,63 @@ std::vector<HTMLInfo*> ClassFlowControll::GetAllDigital()
return empty;
}
std::vector<HTMLInfo*> ClassFlowControll::GetAllAnalog()
{
if (flowanalog)
if (flowanalog) {
return flowanalog->GetHTMLInfo();
}
std::vector<HTMLInfo*> empty;
return empty;
}
t_CNNType ClassFlowControll::GetTypeDigital()
t_CNNType ClassFlowControll::GetTypeDigit()
{
if (flowdigit)
if (flowdigit) {
return flowdigit->getCNNType();
}
return t_CNNType::None;
}
t_CNNType ClassFlowControll::GetTypeAnalog()
{
if (flowanalog)
if (flowanalog) {
return flowanalog->getCNNType();
}
return t_CNNType::None;
}
#ifdef ALGROI_LOAD_FROM_MEM_AS_JPG
void ClassFlowControll::DigitalDrawROI(CImageBasis *_zw)
void ClassFlowControll::DigitDrawROI(CImageBasis *_zw)
{
if (flowdigit)
if (flowdigit) {
flowdigit->DrawROI(_zw);
}
}
void ClassFlowControll::AnalogDrawROI(CImageBasis *_zw)
{
if (flowanalog)
if (flowanalog) {
flowanalog->DrawROI(_zw);
}
}
#endif
#ifdef ENABLE_MQTT
string ClassFlowControll::GetMQTTMainTopic()
bool ClassFlowControll::StartMQTTService()
{
for (int i = 0; i < FlowControll.size(); ++i)
if (FlowControll[i]->name().compare("ClassFlowMQTT") == 0)
return ((ClassFlowMQTT*) (FlowControll[i]))->GetMQTTMainTopic();
return "";
}
bool ClassFlowControll::StartMQTTService() {
/* Start the MQTT service */
for (int i = 0; i < FlowControll.size(); ++i) {
if (FlowControll[i]->name().compare("ClassFlowMQTT") == 0) {
return ((ClassFlowMQTT*) (FlowControll[i]))->Start(AutoInterval);
}
}
for (int i = 0; i < FlowControll.size(); ++i) {
if (FlowControll[i]->name().compare("ClassFlowMQTT") == 0) {
return ((ClassFlowMQTT*) (FlowControll[i]))->Start(AutoInterval);
}
}
return false;
}
#endif //ENABLE_MQTT
void ClassFlowControll::SetInitialParameter(void)
{
AutoStart = false;
@@ -190,83 +205,102 @@ void ClassFlowControll::SetInitialParameter(void)
disabled = false;
aktRunNr = 0;
aktstatus = "Flow task not yet created";
aktstatusWithTime = aktstatus;
}
bool ClassFlowControll::isAutoStart(long &_interval)
bool ClassFlowControll::getIsAutoStart(void)
{
_interval = AutoInterval * 60 * 1000; // AutoInterval: minutes -> ms
return AutoStart;
}
void ClassFlowControll::setAutoStartInterval(long &_interval)
{
_interval = AutoInterval * 60 * 1000; // AutoInterval: minutes -> ms
}
ClassFlow* ClassFlowControll::CreateClassFlow(std::string _type)
{
ClassFlow* cfc = NULL;
_type = trim(_type);
if (toUpper(_type).compare("[TAKEIMAGE]") == 0)
{
if (toUpper(_type).compare("[TAKEIMAGE]") == 0) {
cfc = new ClassFlowTakeImage(&FlowControll);
flowtakeimage = (ClassFlowTakeImage*) cfc;
}
if (toUpper(_type).compare("[ALIGNMENT]") == 0)
{
if (toUpper(_type).compare("[ALIGNMENT]") == 0) {
cfc = new ClassFlowAlignment(&FlowControll);
flowalignment = (ClassFlowAlignment*) cfc;
}
if (toUpper(_type).compare("[ANALOG]") == 0)
{
if (toUpper(_type).compare("[ANALOG]") == 0) {
cfc = new ClassFlowCNNGeneral(flowalignment);
flowanalog = (ClassFlowCNNGeneral*) cfc;
}
if (toUpper(_type).compare(0, 7, "[DIGITS") == 0)
{
if (toUpper(_type).compare(0, 7, "[DIGITS") == 0) {
cfc = new ClassFlowCNNGeneral(flowalignment);
flowdigit = (ClassFlowCNNGeneral*) cfc;
}
#ifdef ENABLE_MQTT
if (toUpper(_type).compare("[MQTT]") == 0)
if (toUpper(_type).compare("[MQTT]") == 0) {
cfc = new ClassFlowMQTT(&FlowControll);
}
#endif //ENABLE_MQTT
#ifdef ENABLE_INFLUXDB
if (toUpper(_type).compare("[INFLUXDB]") == 0)
if (toUpper(_type).compare("[INFLUXDB]") == 0) {
cfc = new ClassFlowInfluxDB(&FlowControll);
#endif //ENABLE_INFLUXDB
if (toUpper(_type).compare("[WRITELIST]") == 0)
cfc = new ClassFlowWriteList(&FlowControll);
}
if (toUpper(_type).compare("[POSTPROCESSING]") == 0)
{
if (toUpper(_type).compare("[INFLUXDBV2]") == 0) {
cfc = new ClassFlowInfluxDBv2(&FlowControll);
}
#endif //ENABLE_INFLUXDB
#ifdef ENABLE_WEBHOOK
if (toUpper(_type).compare("[WEBHOOK]") == 0)
cfc = new ClassFlowWebhook(&FlowControll);
#endif //ENABLE_WEBHOOK
if (toUpper(_type).compare("[POSTPROCESSING]") == 0) {
cfc = new ClassFlowPostProcessing(&FlowControll, flowanalog, flowdigit);
flowpostprocessing = (ClassFlowPostProcessing*) cfc;
}
if (cfc) // Attached only if it is not [AutoTimer], because this is for FlowControll
if (cfc) {
// Attached only if it is not [AutoTimer], because this is for FlowControll
FlowControll.push_back(cfc);
}
if (toUpper(_type).compare("[AUTOTIMER]") == 0)
cfc = this;
if (toUpper(_type).compare("[AUTOTIMER]") == 0) {
cfc = this;
}
if (toUpper(_type).compare("[DATALOGGING]") == 0)
cfc = this;
if (toUpper(_type).compare("[DATALOGGING]") == 0) {
cfc = this;
}
if (toUpper(_type).compare("[DEBUG]") == 0)
cfc = this;
if (toUpper(_type).compare("[DEBUG]") == 0) {
cfc = this;
}
if (toUpper(_type).compare("[SYSTEM]") == 0)
cfc = this;
if (toUpper(_type).compare("[SYSTEM]") == 0) {
cfc = this;
}
return cfc;
}
void ClassFlowControll::InitFlow(std::string config)
{
aktstatus = "Initialization";
aktstatusWithTime = aktstatus;
//#ifdef ENABLE_MQTT
//MQTTPublish(mqttServer_getMainTopic() + "/" + "status", "Initialization", false); // Right now, not possible -> MQTT Service is going to be started later
//MQTTPublish(mqttServer_getMainTopic() + "/" + "status", "Initialization", 1, false); // Right now, not possible -> MQTT Service is going to be started later
//#endif //ENABLE_MQTT
string line;
@@ -280,60 +314,61 @@ void ClassFlowControll::InitFlow(std::string config)
line = "";
char zw[1024];
if (pFile != NULL)
{
if (pFile != NULL) {
fgets(zw, 1024, pFile);
ESP_LOGD(TAG, "%s", zw);
line = std::string(zw);
}
while ((line.size() > 0) && !(feof(pFile)))
{
while ((line.size() > 0) && !(feof(pFile))) {
cfc = CreateClassFlow(line);
if (cfc)
{
ESP_LOGD(TAG, "Start ReadParameter (%s)", line.c_str());
// printf("Name: %s\n", cfc->name().c_str());
if (cfc) {
ESP_LOGE(TAG, "Start ReadParameter (%s)", line.c_str());
cfc->ReadParameter(pFile, line);
}
else
{
else {
line = "";
if (fgets(zw, 1024, pFile) && !feof(pFile))
{
ESP_LOGD(TAG, "Read: %s", zw);
line = std::string(zw);
}
if (fgets(zw, 1024, pFile) && !feof(pFile)) {
ESP_LOGD(TAG, "Read: %s", zw);
line = std::string(zw);
}
}
}
fclose(pFile);
}
std::string* ClassFlowControll::getActStatusWithTime()
{
return &aktstatusWithTime;
}
std::string* ClassFlowControll::getActStatus()
{
return &aktstatus;
}
void ClassFlowControll::setActStatus(std::string _aktstatus)
{
aktstatus = _aktstatus;
aktstatusWithTime = aktstatus;
}
void ClassFlowControll::doFlowTakeImageOnly(string time)
{
std::string zw_time;
for (int i = 0; i < FlowControll.size(); ++i)
{
for (int i = 0; i < FlowControll.size(); ++i) {
if (FlowControll[i]->name() == "ClassFlowTakeImage") {
zw_time = getCurrentTimeString("%H:%M:%S");
std::string flowStatus = TranslateAktstatus(FlowControll[i]->name());
aktstatus = flowStatus + " (" + zw_time + ")";
aktstatus = TranslateAktstatus(FlowControll[i]->name());
aktstatusWithTime = aktstatus + " (" + zw_time + ")";
#ifdef ENABLE_MQTT
MQTTPublish(mqttServer_getMainTopic() + "/" + "status", flowStatus, false);
MQTTPublish(mqttServer_getMainTopic() + "/" + "status", aktstatus, 1, false);
#endif //ENABLE_MQTT
FlowControll[i]->doFlow(time);
@@ -341,12 +376,12 @@ void ClassFlowControll::doFlowTakeImageOnly(string time)
}
}
bool ClassFlowControll::doFlow(string time)
{
bool result = true;
std::string zw_time;
int repeat = 0;
int qos = 1;
#ifdef DEBUG_DETAIL_ON
LogFile.WriteHeapInfo("ClassFlowControll::doFlow - Start");
@@ -360,14 +395,13 @@ bool ClassFlowControll::doFlow(string time)
//checkNtpStatus(0);
for (int i = 0; i < FlowControll.size(); ++i)
{
for (int i = 0; i < FlowControll.size(); ++i) {
zw_time = getCurrentTimeString("%H:%M:%S");
std::string flowStatus = TranslateAktstatus(FlowControll[i]->name());
aktstatus = flowStatus + " (" + zw_time + ")";
//LogFile.WriteToFile(ESP_LOG_INFO, TAG, aktstatus);
aktstatus = TranslateAktstatus(FlowControll[i]->name());
aktstatusWithTime = aktstatus + " (" + zw_time + ")";
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Status: " + aktstatusWithTime);
#ifdef ENABLE_MQTT
MQTTPublish(mqttServer_getMainTopic() + "/" + "status", flowStatus, false);
MQTTPublish(mqttServer_getMainTopic() + "/" + "status", aktstatus, qos, false);
#endif //ENABLE_MQTT
#ifdef DEBUG_DETAIL_ON
@@ -378,7 +412,7 @@ bool ClassFlowControll::doFlow(string time)
if (!FlowControll[i]->doFlow(time)){
repeat++;
LogFile.WriteToFile(ESP_LOG_WARN, TAG, "Fehler im vorheriger Schritt - wird zum " + to_string(repeat) + ". Mal wiederholt");
if (i) i -= 1; // vPrevious step must be repeated (probably take pictures)
if (i) { i -= 1; } // vPrevious step must be repeated (probably take pictures)
result = false;
if (repeat > 5) {
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Wiederholung 5x nicht erfolgreich --> reboot");
@@ -386,8 +420,7 @@ bool ClassFlowControll::doFlow(string time)
//Step was repeated 5x --> reboot
}
}
else
{
else {
result = true;
}
@@ -397,11 +430,11 @@ bool ClassFlowControll::doFlow(string time)
}
zw_time = getCurrentTimeString("%H:%M:%S");
std::string flowStatus = "Flow finished";
aktstatus = flowStatus + " (" + zw_time + ")";
//LogFile.WriteToFile(ESP_LOG_INFO, TAG, aktstatus);
aktstatus = "Flow finished";
aktstatusWithTime = aktstatus + " (" + zw_time + ")";
//LogFile.WriteToFile(ESP_LOG_INFO, TAG, aktstatusWithTime);
#ifdef ENABLE_MQTT
MQTTPublish(mqttServer_getMainTopic() + "/" + "status", flowStatus, false);
MQTTPublish(mqttServer_getMainTopic() + "/" + "status", aktstatus, qos, false);
#endif //ENABLE_MQTT
return result;
@@ -411,27 +444,29 @@ bool ClassFlowControll::doFlow(string time)
string ClassFlowControll::getReadoutAll(int _type)
{
std::string out = "";
if (flowpostprocessing)
{
if (flowpostprocessing) {
std::vector<NumberPost*> *numbers = flowpostprocessing->GetNumbers();
for (int i = 0; i < (*numbers).size(); ++i)
{
for (int i = 0; i < (*numbers).size(); ++i) {
out = out + (*numbers)[i]->name + "\t";
switch (_type) {
case READOUT_TYPE_VALUE:
out = out + (*numbers)[i]->ReturnValue;
break;
case READOUT_TYPE_PREVALUE:
if (flowpostprocessing->PreValueUse)
{
if ((*numbers)[i]->PreValueOkay)
if (flowpostprocessing->PreValueUse) {
if ((*numbers)[i]->PreValueOkay) {
out = out + (*numbers)[i]->ReturnPreValue;
else
out = out + "PreValue too old";
}
else {
out = out + "PreValue too old";
}
}
else
else {
out = out + "PreValue deactivated";
}
break;
case READOUT_TYPE_RAWVALUE:
out = out + (*numbers)[i]->ReturnRawValue;
@@ -440,8 +475,10 @@ string ClassFlowControll::getReadoutAll(int _type)
out = out + (*numbers)[i]->ErrorMessageText;
break;
}
if (i < (*numbers).size()-1)
if (i < (*numbers).size()-1) {
out = out + "\r\n";
}
}
// ESP_LOGD(TAG, "OUT: %s", out.c_str());
}
@@ -449,189 +486,166 @@ string ClassFlowControll::getReadoutAll(int _type)
return out;
}
string ClassFlowControll::getReadout(bool _rawvalue = false, bool _noerror = false)
string ClassFlowControll::getReadout(bool _rawvalue = false, bool _noerror = false, int _number = 0)
{
if (flowpostprocessing)
return flowpostprocessing->getReadoutParam(_rawvalue, _noerror);
string zw = "";
string result = "";
for (int i = 0; i < FlowControll.size(); ++i)
{
zw = FlowControll[i]->getReadout();
if (zw.length() > 0)
{
if (result.length() == 0)
result = zw;
else
result = result + "\t" + zw;
}
if (flowpostprocessing) {
return flowpostprocessing->getReadoutParam(_rawvalue, _noerror, _number);
}
return result;
return std::string("");
}
string ClassFlowControll::GetPrevalue(std::string _number)
{
if (flowpostprocessing)
{
if (flowpostprocessing) {
return flowpostprocessing->GetPreValue(_number);
}
return std::string("");
}
std::string ClassFlowControll::UpdatePrevalue(std::string _newvalue, std::string _numbers, bool _extern)
bool ClassFlowControll::UpdatePrevalue(std::string _newvalue, std::string _numbers, bool _extern)
{
float zw;
double newvalueAsDouble;
char* p;
_newvalue = trim(_newvalue);
// ESP_LOGD(TAG, "Input UpdatePreValue: %s", _newvalue.c_str());
//ESP_LOGD(TAG, "Input UpdatePreValue: %s", _newvalue.c_str());
if (_newvalue.compare("0.0") == 0)
{
zw = 0;
if (_newvalue.substr(0,8).compare("0.000000") == 0 || _newvalue.compare("0.0") == 0 || _newvalue.compare("0") == 0) {
newvalueAsDouble = 0; // preset to value = 0
}
else
{
zw = strtof(_newvalue.c_str(), &p);
if (zw == 0)
return "- Error in String to Value Conversion!!! Must be of format value=123.456";
else {
newvalueAsDouble = strtod(_newvalue.c_str(), &p);
if (newvalueAsDouble == 0) {
LogFile.WriteToFile(ESP_LOG_WARN, TAG, "UpdatePrevalue: No valid value for processing: " + _newvalue);
return false;
}
}
if (flowpostprocessing)
{
flowpostprocessing->SetPreValue(zw, _numbers, _extern);
return _newvalue;
if (flowpostprocessing) {
if (flowpostprocessing->SetPreValue(newvalueAsDouble, _numbers, _extern)) {
return true;
}
else {
return false;
}
}
else {
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "UpdatePrevalue: ERROR - Class Post-Processing not initialized");
return false;
}
return std::string();
}
bool ClassFlowControll::ReadParameter(FILE* pfile, string& aktparamgraph)
{
std::vector<string> splitted;
aktparamgraph = trim(aktparamgraph);
if (aktparamgraph.size() == 0)
if (!this->GetNextParagraph(pfile, aktparamgraph))
if (aktparamgraph.size() == 0) {
if (!this->GetNextParagraph(pfile, aktparamgraph)) {
return false;
}
}
if ((toUpper(aktparamgraph).compare("[AUTOTIMER]") != 0) && (toUpper(aktparamgraph).compare("[DEBUG]") != 0) &&
(toUpper(aktparamgraph).compare("[SYSTEM]") != 0 && (toUpper(aktparamgraph).compare("[DATALOGGING]") != 0))) // Paragraph passt nicht zu Debug oder DataLogging
(toUpper(aktparamgraph).compare("[SYSTEM]") != 0 && (toUpper(aktparamgraph).compare("[DATALOGGING]") != 0))) {
// Paragraph passt nicht zu Debug oder DataLogging
return false;
}
while (this->getNextLine(pfile, &aktparamgraph) && !this->isNewParagraph(aktparamgraph))
{
while (this->getNextLine(pfile, &aktparamgraph) && !this->isNewParagraph(aktparamgraph)) {
splitted = ZerlegeZeile(aktparamgraph, " =");
if ((toUpper(splitted[0]) == "AUTOSTART") && (splitted.size() > 1))
{
if (toUpper(splitted[1]) == "TRUE")
if ((toUpper(splitted[0]) == "AUTOSTART") && (splitted.size() > 1)) {
AutoStart = alphanumericToBoolean(splitted[1]);
}
if ((toUpper(splitted[0]) == "INTERVAL") && (splitted.size() > 1)) {
if (isStringNumeric(splitted[1]))
{
AutoStart = true;
AutoInterval = std::stof(splitted[1]);
}
}
if ((toUpper(splitted[0]) == "INTERVAL") && (splitted.size() > 1))
{
AutoInterval = std::stof(splitted[1]);
if ((toUpper(splitted[0]) == "DATALOGACTIVE") && (splitted.size() > 1)) {
LogFile.SetDataLogToSD(alphanumericToBoolean(splitted[1]));
}
if ((toUpper(splitted[0]) == "DATALOGACTIVE") && (splitted.size() > 1))
{
if (toUpper(splitted[1]) == "TRUE")
if ((toUpper(splitted[0]) == "DATAFILESRETENTION") && (splitted.size() > 1)) {
if (isStringNumeric(splitted[1]))
{
LogFile.SetDataLogToSD(true);
}
else {
LogFile.SetDataLogToSD(false);
LogFile.SetDataLogRetention(std::stoi(splitted[1]));
}
}
if ((toUpper(splitted[0]) == "DATAFILESRETENTION") && (splitted.size() > 1))
{
LogFile.SetDataLogRetention(std::stoi(splitted[1]));
}
if ((toUpper(splitted[0]) == "LOGLEVEL") && (splitted.size() > 1))
{
if ((toUpper(splitted[0]) == "LOGLEVEL") && (splitted.size() > 1)) {
/* matches esp_log_level_t */
if ((toUpper(splitted[1]) == "TRUE") || (toUpper(splitted[1]) == "2"))
{
if ((toUpper(splitted[1]) == "TRUE") || (toUpper(splitted[1]) == "2")) {
LogFile.setLogLevel(ESP_LOG_WARN);
}
else if ((toUpper(splitted[1]) == "FALSE") || (toUpper(splitted[1]) == "0") || (toUpper(splitted[1]) == "1"))
{
else if ((toUpper(splitted[1]) == "FALSE") || (toUpper(splitted[1]) == "0") || (toUpper(splitted[1]) == "1")) {
LogFile.setLogLevel(ESP_LOG_ERROR);
}
else if (toUpper(splitted[1]) == "3")
{
else if (toUpper(splitted[1]) == "3") {
LogFile.setLogLevel(ESP_LOG_INFO);
}
else if (toUpper(splitted[1]) == "4")
{
else if (toUpper(splitted[1]) == "4") {
LogFile.setLogLevel(ESP_LOG_DEBUG);
}
/* If system reboot was not triggered by user and reboot was caused by execption -> keep log level to DEBUG */
if (!getIsPlannedReboot() && (esp_reset_reason() == ESP_RST_PANIC)) {
LogFile.setLogLevel(ESP_LOG_DEBUG);
}
}
if ((toUpper(splitted[0]) == "LOGFILESRETENTION") && (splitted.size() > 1))
{
LogFile.SetLogFileRetention(std::stoi(splitted[1]));
if ((toUpper(splitted[0]) == "LOGFILESRETENTION") && (splitted.size() > 1)) {
if (isStringNumeric(splitted[1]))
{
LogFile.SetLogFileRetention(std::stoi(splitted[1]));
}
}
/* TimeServer and TimeZone got already read from the config, see setupTime () */
if ((toUpper(splitted[0]) == "RSSITHRESHOLD") && (splitted.size() > 1))
{
if (ChangeRSSIThreshold(WLAN_CONFIG_FILE, atoi(splitted[1].c_str())))
{
#if (defined WLAN_USE_ROAMING_BY_SCANNING || (defined WLAN_USE_MESH_ROAMING && defined WLAN_USE_MESH_ROAMING_ACTIVATE_CLIENT_TRIGGERED_QUERIES))
if ((toUpper(splitted[0]) == "RSSITHRESHOLD") && (splitted.size() > 1)) {
int RSSIThresholdTMP = atoi(splitted[1].c_str());
RSSIThresholdTMP = min(0, max(-100, RSSIThresholdTMP)); // Verify input limits (-100 - 0)
if (ChangeRSSIThreshold(WLAN_CONFIG_FILE, RSSIThresholdTMP)) {
// reboot necessary so that the new wlan.ini is also used !!!
fclose(pfile);
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Rebooting to activate new RSSITHRESHOLD ...");
esp_restart();
hard_restart();
LogFile.WriteToFile(ESP_LOG_WARN, TAG, "Rebooting to activate new RSSITHRESHOLD ...");
doReboot();
}
}
#endif
if ((toUpper(splitted[0]) == "HOSTNAME") && (splitted.size() > 1)) {
if (ChangeHostName(WLAN_CONFIG_FILE, splitted[1])) {
// reboot necessary so that the new wlan.ini is also used !!!
fclose(pfile);
LogFile.WriteToFile(ESP_LOG_WARN, TAG, "Rebooting to activate new HOSTNAME...");
doReboot();
}
}
if ((toUpper(splitted[0]) == "HOSTNAME") && (splitted.size() > 1))
{
if (ChangeHostName(WLAN_CONFIG_FILE, splitted[1]))
{
// reboot necessary so that the new wlan.ini is also used !!!
fclose(pfile);
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Rebooting to activate new HOSTNAME...");
esp_restart();
hard_restart();
doReboot();
}
}
if ((toUpper(splitted[0]) == "SETUPMODE") && (splitted.size() > 1))
{
if (toUpper(splitted[1]) == "TRUE")
{
SetupModeActive = true;
}
if ((toUpper(splitted[0]) == "SETUPMODE") && (splitted.size() > 1)) {
SetupModeActive = alphanumericToBoolean(splitted[1]);
}
}
return true;
}
int ClassFlowControll::CleanTempFolder() {
const char* folderPath = "/sdcard/img_tmp";
ESP_LOGD(TAG, "Clean up temporary folder to avoid damage of sdcard sectors: %s", folderPath);
DIR *dir = opendir(folderPath);
if (!dir) {
ESP_LOGE(TAG, "Failed to stat dir: %s", folderPath);
return -1;
@@ -639,31 +653,33 @@ int ClassFlowControll::CleanTempFolder() {
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) {
if (unlink(path.c_str()) == 0) {
deleted ++;
} else {
ESP_LOGE(TAG, "can't delete file: %s", path.c_str());
}
} else if (entry->d_type == DT_DIR) {
deleted += removeFolder(path.c_str(), TAG);
}
if (entry->d_type == DT_REG) {
if (unlink(path.c_str()) == 0) {
deleted ++;
}
else {
ESP_LOGE(TAG, "can't delete file: %s", path.c_str());
}
}
else if (entry->d_type == DT_DIR) {
deleted += removeFolder(path.c_str(), TAG);
}
}
closedir(dir);
ESP_LOGD(TAG, "%d files deleted", deleted);
return 0;
}
esp_err_t ClassFlowControll::SendRawJPG(httpd_req_t *req)
{
return flowtakeimage != NULL ? flowtakeimage->SendRawJPG(req) : ESP_FAIL;
}
esp_err_t ClassFlowControll::GetJPGStream(std::string _fn, httpd_req_t *req)
{
ESP_LOGD(TAG, "ClassFlowControll::GetJPGStream %s", _fn.c_str());
@@ -712,7 +728,7 @@ esp_err_t ClassFlowControll::GetJPGStream(std::string _fn, httpd_req_t *req)
httpd_resp_set_type(req, "image/jpeg");
result = httpd_resp_send(req, (const char *)fileBuffer, fileSize);
delete fileBuffer;
free(fileBuffer);
}
else if (aktstatus.find("Initialization") != -1) {
FILE* file = fopen("/sdcard/html/Flowstate_initialization.jpg", "rb");
@@ -739,7 +755,7 @@ esp_err_t ClassFlowControll::GetJPGStream(std::string _fn, httpd_req_t *req)
httpd_resp_set_type(req, "image/jpeg");
result = httpd_resp_send(req, (const char *)fileBuffer, fileSize);
delete fileBuffer;
free(fileBuffer);
}
else if (aktstatus.find("Take Image") != -1) {
if (flowalignment && flowalignment->AlgROI) {
@@ -801,7 +817,7 @@ esp_err_t ClassFlowControll::GetJPGStream(std::string _fn, httpd_req_t *req)
return ESP_FAIL;
}
_send = new CImageBasis(flowalignment->ImageBasis);
_send = new CImageBasis("alg_roi", flowalignment->ImageBasis);
if (_send->ImageOkay()) {
if (flowalignment) flowalignment->DrawRef(_send);
@@ -825,8 +841,8 @@ esp_err_t ClassFlowControll::GetJPGStream(std::string _fn, httpd_req_t *req)
else {
std::vector<HTMLInfo*> htmlinfo;
htmlinfo = GetAllDigital();
ESP_LOGD(TAG, "After getClassFlowControll::GetAllDigital");
htmlinfo = GetAllDigit();
ESP_LOGD(TAG, "After getClassFlowControll::GetAllDigit");
for (int i = 0; i < htmlinfo.size(); ++i)
{
@@ -895,14 +911,20 @@ esp_err_t ClassFlowControll::GetJPGStream(std::string _fn, httpd_req_t *req)
return result;
}
string ClassFlowControll::getNumbersName()
{
return flowpostprocessing->getNumbersName();
}
string ClassFlowControll::getJSON()
{
return flowpostprocessing->GetJSON();
}
/**
* @returns a vector of all current sequences
**/
const std::vector<NumberPost*> &ClassFlowControll::getNumbers()
{
return *flowpostprocessing->GetNumbers();
}

View File

@@ -15,9 +15,12 @@
#endif //ENABLE_MQTT
#ifdef ENABLE_INFLUXDB
#include "ClassFlowInfluxDB.h"
#include "ClassFlowInfluxDBv2.h"
#endif //ENABLE_INFLUXDB
#ifdef ENABLE_WEBHOOK
#include "ClassFlowWebhook.h"
#endif //ENABLE_WEBHOOK
#include "ClassFlowCNNGeneral.h"
#include "ClassFlowWriteList.h"
class ClassFlowControll :
public ClassFlow
@@ -34,32 +37,31 @@ protected:
bool AutoStart;
float AutoInterval;
bool SetupModeActive;
void SetInitialParameter(void);
std::string aktstatusWithTime;
std::string aktstatus;
int aktRunNr;
public:
bool SetupModeActive;
void InitFlow(std::string config);
bool doFlow(string time);
void doFlowTakeImageOnly(string time);
bool getStatusSetupModus(){return SetupModeActive;};
string getReadout(bool _rawvalue, bool _noerror);
string getReadout(bool _rawvalue, bool _noerror, int _number);
string getReadoutAll(int _type);
string UpdatePrevalue(std::string _newvalue, std::string _numbers, bool _extern);
bool UpdatePrevalue(std::string _newvalue, std::string _numbers, bool _extern);
string GetPrevalue(std::string _number = "");
bool ReadParameter(FILE* pfile, string& aktparamgraph);
string getJSON();
const std::vector<NumberPost*> &getNumbers();
string getNumbersName();
string TranslateAktstatus(std::string _input);
#ifdef ENABLE_MQTT
string GetMQTTMainTopic();
#endif //ENABLE_MQTT
#ifdef ALGROI_LOAD_FROM_MEM_AS_JPG
void DigitalDrawROI(CImageBasis *_zw);
void DigitDrawROI(CImageBasis *_zw);
void AnalogDrawROI(CImageBasis *_zw);
#endif
@@ -68,15 +70,17 @@ public:
std::string doSingleStep(std::string _stepname, std::string _host);
bool isAutoStart(long &_interval);
bool getIsAutoStart();
void setAutoStartInterval(long &_interval);
std::string* getActStatusWithTime();
std::string* getActStatus();
void setActStatus(std::string _aktstatus);
std::vector<HTMLInfo*> GetAllDigital();
std::vector<HTMLInfo*> GetAllDigit();
std::vector<HTMLInfo*> GetAllAnalog();
t_CNNType GetTypeDigital();
t_CNNType GetTypeDigit();
t_CNNType GetTypeAnalog();
#ifdef ENABLE_MQTT

View File

@@ -5,6 +5,10 @@
#include "ClassFlowImage.h"
/**
* Properties of one ROI
* FIXME: naming of members could use some refactoring to comply with common C++ coding style guidelines
*/
struct roi {
int posx, posy, deltax, deltay;
float result_float;
@@ -14,49 +18,66 @@ struct roi {
CImageBasis *image, *image_org;
};
/**
* FIXME: Why is this additional layer needed?
*/
struct general {
string name;
std::vector<roi*> ROI;
};
enum t_RateType {
AbsoluteChange,
RateChange
AbsoluteChange, // ignores the time difference; only the value difference is used comparison with NumberPost.maxRate
RateChange // time difference is considered and a normalized rate is used for comparison with NumberPost.maxRate
};
/**
* Holds all properties and settings of a sequence. A sequence is a set of digit and/or analog ROIs that are combined to
* provide one meter reading (value).
* FIXME: can be renamed to `Sequence`
*/
struct NumberPost {
float MaxRateValue;
bool useMaxRateValue;
t_RateType RateType;
bool ErrorMessage;
bool PreValueOkay;
bool AllowNegativeRates;
bool checkDigitIncreaseConsistency;
time_t lastvalue;
string timeStamp;
double FlowRateAct; // m3 / min
double PreValue; // last value that was read out well
double Value; // last value read out, incl. corrections
string ReturnRateValue; // return value rate
string ReturnChangeAbsolute; // return value rate
string ReturnRawValue; // Raw value (with N & leading 0)
string ReturnValue; // corrected return value, if necessary with error message
string ReturnPreValue; // corrected return value without error message
string ErrorMessageText; // Error message for consistency check
int AnzahlAnalog;
int AnzahlDigital;
int DecimalShift;
int DecimalShiftInitial;
float AnalogDigitalTransitionStart; // When is the digit > x.1, i.e. when does it start to tilt?
int Nachkomma;
float MaxRateValue; // maxRate; upper bound for the difference between two consecutive readings; affected by maxRateType;
bool useMaxRateValue; // consistencyChecksEnabled; enables consistency checks; uses maxRate and maxRateType
t_RateType MaxRateType; // maxRateType; affects how the value of maxRate is used for comparing the current and previous value
bool ErrorMessage; // FIXME: not used; can be removed
int ChangeRateThreshold; // threshold parameter for negative rate detection
bool PreValueOkay; // previousValueValid; indicates that the reading of the previous round has no errors
bool AllowNegativeRates; // allowNegativeRate; defines if the consistency checks allow negative rates between consecutive meter readings.
bool checkDigitIncreaseConsistency; // extendedConsistencyCheck; performs an additional consistency check to avoid wrong readings
time_t timeStampLastValue; // Timestamp for the last read value; is used for the log
time_t timeStampLastPreValue; // Timestamp for the last PreValue set; is used for useMaxRateValue
time_t timeStampTimeUTC; // FIXME: not used; can be removed.
string timeStamp; // localTimeStr; timestamp of last valid reading formatted as local time
double FlowRateAct; // currentRate; ΔValue/min; since usage is not limited to water meters, the physical unit is not known.
double PreValue; // lastValidValue; most recent value that could be read w/o any errors
double Value; // value; most recent readout; may include corrections
string ReturnRateValue; // currentRateStr; current normalized rate; ΔValue/min
string ReturnChangeAbsolute; // currentChangeStr; absolute difference between current and previous measurement
string ReturnRawValue; // rawValueStr; Raw value (with N & leading 0)
string ReturnValue; // valueStr; corrected return value, if necessary with error message
string ReturnPreValue; // lastValidValueStr; corrected return value without error message
string ErrorMessageText; // errorMessage; Error message for consistency checks
int AnzahlAnalog; // numAnalogRoi; number of analog ROIs used in this sequence
int AnzahlDigit; // numDigitRoi; number of digit ROIs used in this sequence
int DecimalShift; // decimalShift; each increment shifts the decimal separator by one digit; value=value*10^decimalShift; pos. value shifts to the right
int DecimalShiftInitial; // decimalShiftInitial; same as decimalShift but is a const to reset decimalShift after calculations
float AnalogToDigitTransitionStart; // AnalogToDigitTransitionStartValue; FIXME: need a better description; When is the digit > x.1, i.e. when does it start to tilt?
int Nachkomma; // decimalPlaces; usually defined by the number of analog ROIs; affected by DecimalShift
bool isExtendedResolution;
string FieldV1; // influxdbFieldName_v1; Name of the Field in InfluxDBv1
string MeasurementV1; // influxdbMeasurementName_v1; Name of the Measurement in InfluxDBv1
general *digit_roi;
general *analog_roi;
string FieldV2; // influxdbFieldName_v2; Name of the Field in InfluxDBv2
string MeasurementV2; // influxdbMeasurementName_v2; Name of the Measurement in InfluxDBv2
string name;
bool isExtendedResolution; // extendResolution; Adds the decimal place of the least significant analog ROI to the value
general *digit_roi; // digitRoi; set of digit ROIs for the sequence
general *analog_roi; // analogRoi; set of analog ROIs for the sequence
string name; // name; Designation for the sequence
};
#endif

View File

@@ -17,7 +17,8 @@ extern "C" {
#include "esp_log.h"
#include "../../include/defines.h"
static const char* TAG = "IMG";
static const char* TAG = "FLOWIMAGE";
ClassFlowImage::ClassFlowImage(const char* logTag)
{

View File

@@ -15,13 +15,12 @@
#include <time.h>
static const char* TAG = "class_flow_influxDb";
static const char* TAG = "INFLUXDB";
void ClassFlowInfluxDB::SetInitialParameter(void)
{
uri = "";
database = "";
measurement = "";
OldValue = "";
flowpostprocessing = NULL;
@@ -86,33 +85,39 @@ bool ClassFlowInfluxDB::ReadParameter(FILE* pfile, string& aktparamgraph)
{
ESP_LOGD(TAG, "while loop reading line: %s", aktparamgraph.c_str());
splitted = ZerlegeZeile(aktparamgraph);
if ((toUpper(splitted[0]) == "USER") && (splitted.size() > 1))
std::string _param = GetParameterName(splitted[0]);
if ((toUpper(_param) == "USER") && (splitted.size() > 1))
{
this->user = splitted[1];
}
if ((toUpper(splitted[0]) == "PASSWORD") && (splitted.size() > 1))
if ((toUpper(_param) == "PASSWORD") && (splitted.size() > 1))
{
this->password = splitted[1];
}
if ((toUpper(splitted[0]) == "URI") && (splitted.size() > 1))
if ((toUpper(_param) == "URI") && (splitted.size() > 1))
{
this->uri = splitted[1];
}
if (((toUpper(splitted[0]) == "MEASUREMENT")) && (splitted.size() > 1))
{
this->measurement = splitted[1];
}
if (((toUpper(splitted[0]) == "DATABASE")) && (splitted.size() > 1))
if (((toUpper(_param) == "DATABASE")) && (splitted.size() > 1))
{
this->database = splitted[1];
}
if (((toUpper(_param) == "MEASUREMENT")) && (splitted.size() > 1))
{
handleMeasurement(splitted[0], splitted[1]);
}
if (((toUpper(_param) == "FIELD")) && (splitted.size() > 1))
{
handleFieldname(splitted[0], splitted[1]);
}
}
if ((uri.length() > 0) && (database.length() > 0) && (measurement.length() > 0))
if ((uri.length() > 0) && (database.length() > 0))
{
// ESP_LOGD(TAG, "Init InfluxDB with uri: %s, measurement: %s, user: %s, password: %s", uri.c_str(), measurement.c_str(), user.c_str(), password.c_str());
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Init InfluxDB with uri: " + uri + ", measurement: " + measurement + ", user: " + user + ", password: " + password);
InfluxDBInit(uri, database, measurement, user, password);
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Init InfluxDB with uri: " + uri + ", user: " + user + ", password: " + password);
InfluxDBInit(uri, database, user, password);
InfluxDBenable = true;
} else {
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "InfluxDB init skipped as we are missing some parameters");
@@ -121,23 +126,18 @@ bool ClassFlowInfluxDB::ReadParameter(FILE* pfile, string& aktparamgraph)
return true;
}
string ClassFlowInfluxDB::GetInfluxDBMeasurement()
{
return measurement;
}
bool ClassFlowInfluxDB::doFlow(string zwtime)
{
if (!InfluxDBenable)
return true;
std::string result;
std::string measurement;
std::string resulterror = "";
std::string resultraw = "";
std::string resultrate = "";
std::string resulttimestamp = "";
long int timeutc;
string zw = "";
string namenumber = "";
@@ -147,20 +147,29 @@ bool ClassFlowInfluxDB::doFlow(string zwtime)
for (int i = 0; i < (*NUMBERS).size(); ++i)
{
measurement = (*NUMBERS)[i]->MeasurementV1;
result = (*NUMBERS)[i]->ReturnValue;
resultraw = (*NUMBERS)[i]->ReturnRawValue;
resulterror = (*NUMBERS)[i]->ErrorMessageText;
resultrate = (*NUMBERS)[i]->ReturnRateValue;
resulttimestamp = (*NUMBERS)[i]->timeStamp;
timeutc = (*NUMBERS)[i]->timeStampTimeUTC;
namenumber = (*NUMBERS)[i]->name;
if (namenumber == "default")
namenumber = "value";
if ((*NUMBERS)[i]->FieldV1.length() > 0)
{
namenumber = (*NUMBERS)[i]->FieldV1;
}
else
namenumber = namenumber + "/value";
{
namenumber = (*NUMBERS)[i]->name;
if (namenumber == "default")
namenumber = "value";
else
namenumber = namenumber + "/value";
}
if (result.length() > 0 && resulttimestamp.length() > 0)
InfluxDBPublish(namenumber, result, resulttimestamp);
if (result.length() > 0)
InfluxDBPublish(measurement, namenumber, result, timeutc);
}
}
@@ -169,4 +178,50 @@ bool ClassFlowInfluxDB::doFlow(string zwtime)
return true;
}
void ClassFlowInfluxDB::handleMeasurement(string _decsep, string _value)
{
string _digit, _decpos;
int _pospunkt = _decsep.find_first_of(".");
// ESP_LOGD(TAG, "Name: %s, Pospunkt: %d", _decsep.c_str(), _pospunkt);
if (_pospunkt > -1)
_digit = _decsep.substr(0, _pospunkt);
else
_digit = "default";
for (int j = 0; j < flowpostprocessing->NUMBERS.size(); ++j)
{
if (_digit == "default") // Set to default first (if nothing else is set)
{
flowpostprocessing->NUMBERS[j]->MeasurementV1 = _value;
}
if (flowpostprocessing->NUMBERS[j]->name == _digit)
{
flowpostprocessing->NUMBERS[j]->MeasurementV1 = _value;
}
}
}
void ClassFlowInfluxDB::handleFieldname(string _decsep, string _value)
{
string _digit, _decpos;
int _pospunkt = _decsep.find_first_of(".");
// ESP_LOGD(TAG, "Name: %s, Pospunkt: %d", _decsep.c_str(), _pospunkt);
if (_pospunkt > -1)
_digit = _decsep.substr(0, _pospunkt);
else
_digit = "default";
for (int j = 0; j < flowpostprocessing->NUMBERS.size(); ++j)
{
if (_digit == "default") // Set to default first (if nothing else is set)
{
flowpostprocessing->NUMBERS[j]->FieldV1 = _value;
}
if (flowpostprocessing->NUMBERS[j]->name == _digit)
{
flowpostprocessing->NUMBERS[j]->FieldV1 = _value;
}
}
}
#endif //ENABLE_INFLUXDB

View File

@@ -21,14 +21,19 @@ protected:
std::string user, password;
bool InfluxDBenable;
void SetInitialParameter(void);
void SetInitialParameter(void);
void handleFieldname(string _decsep, string _value);
void handleMeasurement(string _decsep, string _value);
public:
ClassFlowInfluxDB();
ClassFlowInfluxDB(std::vector<ClassFlow*>* lfc);
ClassFlowInfluxDB(std::vector<ClassFlow*>* lfc, ClassFlow *_prev);
string GetInfluxDBMeasurement();
// string GetInfluxDBMeasurement();
bool ReadParameter(FILE* pfile, string& aktparamgraph);
bool doFlow(string time);

View File

@@ -0,0 +1,244 @@
#ifdef ENABLE_INFLUXDB
#include <sstream>
#include "ClassFlowInfluxDBv2.h"
#include "Helper.h"
#include "connect_wlan.h"
#include "time_sntp.h"
#include "interface_influxdb.h"
#include "ClassFlowPostProcessing.h"
#include "esp_log.h"
#include "../../include/defines.h"
#include "ClassLogFile.h"
#include <time.h>
static const char* TAG = "INFLUXDBV2";
void ClassFlowInfluxDBv2::SetInitialParameter(void)
{
uri = "";
bucket = "";
dborg = "";
dbtoken = "";
// dbfield = "";
OldValue = "";
flowpostprocessing = NULL;
previousElement = NULL;
ListFlowControll = NULL;
disabled = false;
InfluxDBenable = false;
}
ClassFlowInfluxDBv2::ClassFlowInfluxDBv2()
{
SetInitialParameter();
}
ClassFlowInfluxDBv2::ClassFlowInfluxDBv2(std::vector<ClassFlow*>* lfc)
{
SetInitialParameter();
ListFlowControll = lfc;
for (int i = 0; i < ListFlowControll->size(); ++i)
{
if (((*ListFlowControll)[i])->name().compare("ClassFlowPostProcessing") == 0)
{
flowpostprocessing = (ClassFlowPostProcessing*) (*ListFlowControll)[i];
}
}
}
ClassFlowInfluxDBv2::ClassFlowInfluxDBv2(std::vector<ClassFlow*>* lfc, ClassFlow *_prev)
{
SetInitialParameter();
previousElement = _prev;
ListFlowControll = lfc;
for (int i = 0; i < ListFlowControll->size(); ++i)
{
if (((*ListFlowControll)[i])->name().compare("ClassFlowPostProcessing") == 0)
{
flowpostprocessing = (ClassFlowPostProcessing*) (*ListFlowControll)[i];
}
}
}
bool ClassFlowInfluxDBv2::ReadParameter(FILE* pfile, string& aktparamgraph)
{
std::vector<string> splitted;
aktparamgraph = trim(aktparamgraph);
printf("akt param: %s\n", aktparamgraph.c_str());
if (aktparamgraph.size() == 0)
if (!this->GetNextParagraph(pfile, aktparamgraph))
return false;
if (toUpper(aktparamgraph).compare("[INFLUXDBV2]") != 0)
return false;
while (this->getNextLine(pfile, &aktparamgraph) && !this->isNewParagraph(aktparamgraph))
{
// ESP_LOGD(TAG, "while loop reading line: %s", aktparamgraph.c_str());
splitted = ZerlegeZeile(aktparamgraph);
std::string _param = GetParameterName(splitted[0]);
if ((toUpper(_param) == "ORG") && (splitted.size() > 1))
{
this->dborg = splitted[1];
}
if ((toUpper(_param) == "TOKEN") && (splitted.size() > 1))
{
this->dbtoken = splitted[1];
}
if ((toUpper(_param) == "URI") && (splitted.size() > 1))
{
this->uri = splitted[1];
}
if (((toUpper(_param) == "FIELD")) && (splitted.size() > 1))
{
handleFieldname(splitted[0], splitted[1]);
}
if (((toUpper(_param) == "MEASUREMENT")) && (splitted.size() > 1))
{
handleMeasurement(splitted[0], splitted[1]);
}
if (((toUpper(splitted[0]) == "BUCKET")) && (splitted.size() > 1))
{
this->bucket = splitted[1];
}
}
printf("uri: %s\n", uri.c_str());
printf("org: %s\n", dborg.c_str());
printf("token: %s\n", dbtoken.c_str());
if ((uri.length() > 0) && (bucket.length() > 0) && (dbtoken.length() > 0) && (dborg.length() > 0))
{
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Init InfluxDB with uri: " + uri + ", org: " + dborg + ", token: *****");
// printf("vor V2 Init\n");
InfluxDB_V2_Init(uri, bucket, dborg, dbtoken);
// printf("nach V2 Init\n");
InfluxDBenable = true;
} else {
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "InfluxDBv2 (Verion2 !!!) init skipped as we are missing some parameters");
}
return true;
}
/*
string ClassFlowInfluxDBv2::GetInfluxDBMeasurement()
{
return measurement;
}
*/
void ClassFlowInfluxDBv2::handleFieldname(string _decsep, string _value)
{
string _digit, _decpos;
int _pospunkt = _decsep.find_first_of(".");
// ESP_LOGD(TAG, "Name: %s, Pospunkt: %d", _decsep.c_str(), _pospunkt);
if (_pospunkt > -1)
_digit = _decsep.substr(0, _pospunkt);
else
_digit = "default";
for (int j = 0; j < flowpostprocessing->NUMBERS.size(); ++j)
{
if (_digit == "default") // Set to default first (if nothing else is set)
{
flowpostprocessing->NUMBERS[j]->FieldV2 = _value;
}
if (flowpostprocessing->NUMBERS[j]->name == _digit)
{
flowpostprocessing->NUMBERS[j]->FieldV2 = _value;
}
}
}
void ClassFlowInfluxDBv2::handleMeasurement(string _decsep, string _value)
{
string _digit, _decpos;
int _pospunkt = _decsep.find_first_of(".");
// ESP_LOGD(TAG, "Name: %s, Pospunkt: %d", _decsep.c_str(), _pospunkt);
if (_pospunkt > -1)
_digit = _decsep.substr(0, _pospunkt);
else
_digit = "default";
for (int j = 0; j < flowpostprocessing->NUMBERS.size(); ++j)
{
if (_digit == "default") // Set to default first (if nothing else is set)
{
flowpostprocessing->NUMBERS[j]->MeasurementV2 = _value;
}
if (flowpostprocessing->NUMBERS[j]->name == _digit)
{
flowpostprocessing->NUMBERS[j]->MeasurementV2 = _value;
}
}
}
bool ClassFlowInfluxDBv2::doFlow(string zwtime)
{
if (!InfluxDBenable)
return true;
std::string measurement;
std::string result;
std::string resulterror = "";
std::string resultraw = "";
std::string resultrate = "";
std::string resulttimestamp = "";
long int resulttimeutc = 0;
string zw = "";
string namenumber = "";
if (flowpostprocessing)
{
std::vector<NumberPost*>* NUMBERS = flowpostprocessing->GetNumbers();
for (int i = 0; i < (*NUMBERS).size(); ++i)
{
measurement = (*NUMBERS)[i]->MeasurementV2;
result = (*NUMBERS)[i]->ReturnValue;
resultraw = (*NUMBERS)[i]->ReturnRawValue;
resulterror = (*NUMBERS)[i]->ErrorMessageText;
resultrate = (*NUMBERS)[i]->ReturnRateValue;
resulttimestamp = (*NUMBERS)[i]->timeStamp;
resulttimeutc = (*NUMBERS)[i]->timeStampTimeUTC;
if ((*NUMBERS)[i]->FieldV2.length() > 0)
{
namenumber = (*NUMBERS)[i]->FieldV2;
}
else
{
namenumber = (*NUMBERS)[i]->name;
if (namenumber == "default")
namenumber = "value";
else
namenumber = namenumber + "/value";
}
printf("vor sende Influx_DB_V2 - namenumber. %s, result: %s, timestampt: %s", namenumber.c_str(), result.c_str(), resulttimestamp.c_str());
if (result.length() > 0)
InfluxDB_V2_Publish(measurement, namenumber, result, resulttimeutc);
}
}
OldValue = result;
return true;
}
#endif //ENABLE_INFLUXDB

View File

@@ -0,0 +1,43 @@
#ifdef ENABLE_INFLUXDB
#pragma once
#ifndef CLASSFINFLUXDBv2_H
#define CLASSFINFLUXDBv2_H
#include "ClassFlow.h"
#include "ClassFlowPostProcessing.h"
#include <string>
class ClassFlowInfluxDBv2 :
public ClassFlow
{
protected:
std::string uri, bucket;
std::string dborg, dbtoken, dbfield;
std::string OldValue;
ClassFlowPostProcessing* flowpostprocessing;
bool InfluxDBenable;
void SetInitialParameter(void);
void handleFieldname(string _decsep, string _value);
void handleMeasurement(string _decsep, string _value);
public:
ClassFlowInfluxDBv2();
ClassFlowInfluxDBv2(std::vector<ClassFlow*>* lfc);
ClassFlowInfluxDBv2(std::vector<ClassFlow*>* lfc, ClassFlow *_prev);
// string GetInfluxDBMeasurement();
bool ReadParameter(FILE* pfile, string& aktparamgraph);
bool doFlow(string time);
string name(){return "ClassFlowInfluxDBv2";};
};
#endif //CLASSFINFLUXDBv2_H
#endif //ENABLE_INFLUXDB

View File

@@ -5,6 +5,7 @@
#include "ClassFlowMQTT.h"
#include "Helper.h"
#include "connect_wlan.h"
#include "read_wlanini.h"
#include "ClassLogFile.h"
#include "time_sntp.h"
@@ -31,12 +32,15 @@ void ClassFlowMQTT::SetInitialParameter(void)
topicError = "";
topicRate = "";
topicTimeStamp = "";
maintopic = hostname;
maintopic = wlan_config.hostname;
topicUptime = "";
topicFreeMem = "";
clientname = "AIOTED-" + getMac();
caCertFilename = "";
clientCertFilename = "";
clientKeyFilename = "";
clientname = wlan_config.hostname;
OldValue = "";
flowpostprocessing = NULL;
@@ -101,6 +105,18 @@ bool ClassFlowMQTT::ReadParameter(FILE* pfile, string& aktparamgraph)
while (this->getNextLine(pfile, &aktparamgraph) && !this->isNewParagraph(aktparamgraph))
{
splitted = ZerlegeZeile(aktparamgraph);
if ((toUpper(splitted[0]) == "CACERT") && (splitted.size() > 1))
{
this->caCertFilename = splitted[1];
}
if ((toUpper(splitted[0]) == "CLIENTCERT") && (splitted.size() > 1))
{
this->clientCertFilename = splitted[1];
}
if ((toUpper(splitted[0]) == "CLIENTKEY") && (splitted.size() > 1))
{
this->clientKeyFilename = splitted[1];
}
if ((toUpper(splitted[0]) == "USER") && (splitted.size() > 1))
{
this->user = splitted[1];
@@ -155,6 +171,9 @@ bool ClassFlowMQTT::ReadParameter(FILE* pfile, string& aktparamgraph)
else if (toUpper(splitted[1]) == "ENERGY_MWH") {
mqttServer_setMeterType("energy", "MWh", "h", "MW");
}
else if (toUpper(splitted[1]) == "ENERGY_GJ") {
mqttServer_setMeterType("energy", "GJ", "h", "GJ/h");
}
}
if ((toUpper(splitted[0]) == "CLIENTID") && (splitted.size() > 1))
@@ -165,7 +184,6 @@ bool ClassFlowMQTT::ReadParameter(FILE* pfile, string& aktparamgraph)
if (((toUpper(splitted[0]) == "TOPIC") || (toUpper(splitted[0]) == "MAINTOPIC")) && (splitted.size() > 1))
{
maintopic = splitted[1];
mqttServer_setMainTopic(maintopic);
}
}
@@ -174,16 +192,12 @@ bool ClassFlowMQTT::ReadParameter(FILE* pfile, string& aktparamgraph)
* How ever we need the interval parameter from the ClassFlowControll, but that only gets started later.
* To work around this, we delay the start and trigger it from ClassFlowControll::ReadParameter() */
mqttServer_setMainTopic(maintopic);
return true;
}
string ClassFlowMQTT::GetMQTTMainTopic()
{
return maintopic;
}
bool ClassFlowMQTT::Start(float AutoInterval)
{
roundInterval = AutoInterval; // Minutes
@@ -197,7 +211,8 @@ bool ClassFlowMQTT::Start(float AutoInterval)
mqttServer_setParameter(flowpostprocessing->GetNumbers(), keepAlive, roundInterval);
bool MQTTConfigCheck = MQTT_Configure(uri, clientname, user, password, maintopic, LWT_TOPIC, LWT_CONNECTED,
LWT_DISCONNECTED, keepAlive, SetRetainFlag, (void *)&GotConnected);
LWT_DISCONNECTED, caCertFilename, clientCertFilename, clientKeyFilename,
keepAlive, SetRetainFlag, (void *)&GotConnected);
if (!MQTTConfigCheck) {
return false;
@@ -209,6 +224,7 @@ bool ClassFlowMQTT::Start(float AutoInterval)
bool ClassFlowMQTT::doFlow(string zwtime)
{
bool success;
std::string result;
std::string resulterror = "";
std::string resultraw = "";
@@ -219,8 +235,12 @@ bool ClassFlowMQTT::doFlow(string zwtime)
std::string resultchangabs = "";
string zw = "";
string namenumber = "";
int qos = 1;
publishSystemData();
/* Send the the Homeassistant Discovery and the Static Topics in case they where scheduled */
sendDiscovery_and_static_Topics();
success = publishSystemData(qos);
if (flowpostprocessing && getMQTTisConnected())
{
@@ -246,13 +266,13 @@ bool ClassFlowMQTT::doFlow(string zwtime)
if (result.length() > 0)
MQTTPublish(namenumber + "value", result, SetRetainFlag);
success |= MQTTPublish(namenumber + "value", result, qos, SetRetainFlag);
if (resulterror.length() > 0)
MQTTPublish(namenumber + "error", resulterror, SetRetainFlag);
success |= MQTTPublish(namenumber + "error", resulterror, qos, SetRetainFlag);
if (resultrate.length() > 0) {
MQTTPublish(namenumber + "rate", resultrate, SetRetainFlag);
success |= MQTTPublish(namenumber + "rate", resultrate, qos, SetRetainFlag);
std::string resultRatePerTimeUnit;
if (getTimeUnit() == "h") { // Need conversion to be per hour
@@ -261,22 +281,22 @@ bool ClassFlowMQTT::doFlow(string zwtime)
else { // Keep per minute
resultRatePerTimeUnit = resultrate;
}
MQTTPublish(namenumber + "rate_per_time_unit", resultRatePerTimeUnit, SetRetainFlag);
success |= MQTTPublish(namenumber + "rate_per_time_unit", resultRatePerTimeUnit, qos, SetRetainFlag);
}
if (resultchangabs.length() > 0) {
MQTTPublish(namenumber + "changeabsolut", resultchangabs, SetRetainFlag); // Legacy API
MQTTPublish(namenumber + "rate_per_digitalization_round", resultchangabs, SetRetainFlag);
success |= MQTTPublish(namenumber + "changeabsolut", resultchangabs, qos, SetRetainFlag); // Legacy API
success |= MQTTPublish(namenumber + "rate_per_Digitization_round", resultchangabs, qos, SetRetainFlag);
}
if (resultraw.length() > 0)
MQTTPublish(namenumber + "raw", resultraw, SetRetainFlag);
success |= MQTTPublish(namenumber + "raw", resultraw, qos, SetRetainFlag);
if (resulttimestamp.length() > 0)
MQTTPublish(namenumber + "timestamp", resulttimestamp, SetRetainFlag);
success |= MQTTPublish(namenumber + "timestamp", resulttimestamp, qos, SetRetainFlag);
std::string json = flowpostprocessing->getJsonFromNumber(i, "\n");
MQTTPublish(namenumber + "json", json, SetRetainFlag);
success |= MQTTPublish(namenumber + "json", json, qos, SetRetainFlag);
}
}
@@ -294,10 +314,14 @@ bool ClassFlowMQTT::doFlow(string zwtime)
// result = result + "\t" + zw;
// }
// }
// MQTTPublish(topic, result, SetRetainFlag);
// success |= MQTTPublish(topic, result, qos, SetRetainFlag);
// }
OldValue = result;
if (!success) {
LogFile.WriteToFile(ESP_LOG_WARN, TAG, "One or more MQTT topics failed to be published!");
}
return true;
}

View File

@@ -19,6 +19,7 @@ protected:
std::string OldValue;
ClassFlowPostProcessing* flowpostprocessing;
std::string user, password;
std::string caCertFilename, clientCertFilename, clientKeyFilename;
bool SetRetainFlag;
int keepAlive; // Seconds
float roundInterval; // Minutes
@@ -31,7 +32,6 @@ public:
ClassFlowMQTT(std::vector<ClassFlow*>* lfc);
ClassFlowMQTT(std::vector<ClassFlow*>* lfc, ClassFlow *_prev);
string GetMQTTMainTopic();
bool Start(float AutoInterval);
bool ReadParameter(FILE* pfile, string& aktparamgraph);

View File

@@ -15,18 +15,15 @@ class ClassFlowPostProcessing :
public ClassFlow
{
protected:
std::vector<NumberPost*> NUMBERS;
bool UpdatePreValueINI;
int PreValueAgeStartup;
bool ErrorMessage;
bool IgnoreLeadingNaN; // SPECIAL CASE for User Gustl ???
ClassFlowCNNGeneral* flowAnalog;
ClassFlowCNNGeneral* flowDigit;
string FilePreValue;
ClassFlowTakeImage *flowTakeImage;
@@ -42,18 +39,17 @@ protected:
void handleMaxRateValue(string _decsep, string _value);
void handleDecimalExtendedResolution(string _decsep, string _value);
void handleMaxRateType(string _decsep, string _value);
void handleAnalogDigitalTransitionStart(string _decsep, string _value);
void handleAnalogToDigitTransitionStart(string _decsep, string _value);
void handleAllowNegativeRate(string _decsep, string _value);
void handleChangeRateThreshold(string _decsep, string _value);
std::string GetStringReadouts(general);
void WriteDataLog(int _index);
public:
bool PreValueUse;
std::vector<NumberPost*> NUMBERS;
ClassFlowPostProcessing(std::vector<ClassFlow*>* lfc, ClassFlowCNNGeneral *_analog, ClassFlowCNNGeneral *_digit);
virtual ~ClassFlowPostProcessing(){};
@@ -67,7 +63,7 @@ public:
void SavePreValue();
string getJsonFromNumber(int i, std::string _lineend);
string GetPreValue(std::string _number = "");
void SetPreValue(double zw, string _numbers, bool _extern = false);
bool SetPreValue(double zw, string _numbers, bool _extern = false);
std::string GetJSON(std::string _lineend = "\n");
std::string getNumbersName();

View File

@@ -1,24 +1,31 @@
#include <iostream>
#include <string>
#include <vector>
#include <regex>
#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"
#include "../../include/defines.h"
#include "psram.h"
#include <time.h>
// #define DEBUG_DETAIL_ON
// #define DEBUG_DETAIL_ON
// #define WIFITURNOFF
static const char* TAG = "flow_make_image";
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);
@@ -29,150 +36,500 @@ 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;
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<ClassFlow*>* lfc) : ClassFlowImage(lfc, TAG)
std::vector<string> 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))
{
if (isStringNumeric(splitted[1]))
{
this->imagesRetention = std::stod(splitted[1]);
}
}
else if ((toUpper(splitted[0]) == "SAVEALLFILES") && (splitted.size() > 1))
{
CCstatus.SaveAllFiles = alphanumericToBoolean(splitted[1]);
}
else if ((toUpper(splitted[0]) == "WAITBEFORETAKINGPICTURE") && (splitted.size() > 1))
{
if (isStringNumeric(splitted[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 (isStringNumeric(_ImageGainceiling))
{
int _ImageGainceiling_ = std::stoi(_ImageGainceiling);
switch (_ImageGainceiling_)
{
case 1:
CFstatus.ImageGainceiling = GAINCEILING_4X;
break;
case 2:
CFstatus.ImageGainceiling = GAINCEILING_8X;
break;
case 3:
CFstatus.ImageGainceiling = GAINCEILING_16X;
break;
case 4:
CFstatus.ImageGainceiling = GAINCEILING_32X;
break;
case 5:
CFstatus.ImageGainceiling = GAINCEILING_64X;
break;
case 6:
CFstatus.ImageGainceiling = GAINCEILING_128X;
break;
default:
CFstatus.ImageGainceiling = GAINCEILING_2X;
}
}
else
{
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))
{
if (isStringNumeric(splitted[1]))
{
int _ImageQuality = std::stoi(splitted[1]);
CCstatus.ImageQuality = clipInt(_ImageQuality, 63, 6);
}
}
else if ((toUpper(splitted[0]) == "CAMBRIGHTNESS") && (splitted.size() > 1))
{
if (isStringNumeric(splitted[1]))
{
int _ImageBrightness = std::stoi(splitted[1]);
CCstatus.ImageBrightness = clipInt(_ImageBrightness, 2, -2);
}
}
else if ((toUpper(splitted[0]) == "CAMCONTRAST") && (splitted.size() > 1))
{
if (isStringNumeric(splitted[1]))
{
int _ImageContrast = std::stoi(splitted[1]);
CCstatus.ImageContrast = clipInt(_ImageContrast, 2, -2);
}
}
else if ((toUpper(splitted[0]) == "CAMSATURATION") && (splitted.size() > 1))
{
if (isStringNumeric(splitted[1]))
{
int _ImageSaturation = std::stoi(splitted[1]);
CCstatus.ImageSaturation = clipInt(_ImageSaturation, 2, -2);
}
}
else if ((toUpper(splitted[0]) == "CAMSHARPNESS") && (splitted.size() > 1))
{
if (isStringNumeric(splitted[1]))
{
int _ImageSharpness = std::stoi(splitted[1]);
if (CCstatus.CamSensor_id == OV2640_PID)
{
CCstatus.ImageSharpness = clipInt(_ImageSharpness, 2, -2);
}
else
{
CCstatus.ImageSharpness = clipInt(_ImageSharpness, 3, -3);
}
}
}
else if ((toUpper(splitted[0]) == "CAMAUTOSHARPNESS") && (splitted.size() > 1))
{
CCstatus.ImageAutoSharpness = alphanumericToBoolean(splitted[1]);
}
else if ((toUpper(splitted[0]) == "CAMSPECIALEFFECT") && (splitted.size() > 1))
{
std::string _ImageSpecialEffect = toUpper(splitted[1]);
if (isStringNumeric(_ImageSpecialEffect))
{
int _ImageSpecialEffect_ = std::stoi(_ImageSpecialEffect);
CFstatus.ImageSpecialEffect = clipInt(_ImageSpecialEffect_, 6, 0);
}
else
{
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 (isStringNumeric(_ImageWbMode))
{
int _ImageWbMode_ = std::stoi(_ImageWbMode);
CFstatus.ImageWbMode = clipInt(_ImageWbMode_, 4, 0);
}
else
{
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))
{
CCstatus.ImageAwb = alphanumericToBoolean(splitted[1]);
}
else if ((toUpper(splitted[0]) == "CAMAWBGAIN") && (splitted.size() > 1))
{
CCstatus.ImageAwbGain = alphanumericToBoolean(splitted[1]);
}
else if ((toUpper(splitted[0]) == "CAMAEC") && (splitted.size() > 1))
{
CCstatus.ImageAec = alphanumericToBoolean(splitted[1]);
}
else if ((toUpper(splitted[0]) == "CAMAEC2") && (splitted.size() > 1))
{
CCstatus.ImageAec2 = alphanumericToBoolean(splitted[1]);
}
else if ((toUpper(splitted[0]) == "CAMAELEVEL") && (splitted.size() > 1))
{
if (isStringNumeric(splitted[1]))
{
int _ImageAeLevel = std::stoi(splitted[1]);
if (CCstatus.CamSensor_id == OV2640_PID)
{
CCstatus.ImageAeLevel = clipInt(_ImageAeLevel, 2, -2);
}
else
{
CCstatus.ImageAeLevel = clipInt(_ImageAeLevel, 5, -5);
}
}
}
else if ((toUpper(splitted[0]) == "CAMAECVALUE") && (splitted.size() > 1))
{
if (isStringNumeric(splitted[1]))
{
int _ImageAecValue = std::stoi(splitted[1]);
CCstatus.ImageAecValue = clipInt(_ImageAecValue, 1200, 0);
}
}
else if ((toUpper(splitted[0]) == "CAMAGC") && (splitted.size() > 1))
{
CCstatus.ImageAgc = alphanumericToBoolean(splitted[1]);
}
else if ((toUpper(splitted[0]) == "CAMAGCGAIN") && (splitted.size() > 1))
{
if (isStringNumeric(splitted[1]))
{
int _ImageAgcGain = std::stoi(splitted[1]);
CCstatus.ImageAgcGain = clipInt(_ImageAgcGain, 30, 0);
}
}
else if ((toUpper(splitted[0]) == "CAMBPC") && (splitted.size() > 1))
{
CCstatus.ImageBpc = alphanumericToBoolean(splitted[1]);
}
else if ((toUpper(splitted[0]) == "CAMWPC") && (splitted.size() > 1))
{
CCstatus.ImageWpc = alphanumericToBoolean(splitted[1]);
}
else if ((toUpper(splitted[0]) == "CAMRAWGMA") && (splitted.size() > 1))
{
CCstatus.ImageRawGma = alphanumericToBoolean(splitted[1]);
}
else if ((toUpper(splitted[0]) == "CAMLENC") && (splitted.size() > 1))
{
CCstatus.ImageLenc = alphanumericToBoolean(splitted[1]);
}
else if ((toUpper(splitted[0]) == "CAMHMIRROR") && (splitted.size() > 1))
{
CCstatus.ImageHmirror = alphanumericToBoolean(splitted[1]);
}
else if ((toUpper(splitted[0]) == "CAMVFLIP") && (splitted.size() > 1))
{
CCstatus.ImageVflip = alphanumericToBoolean(splitted[1]);
}
else if ((toUpper(splitted[0]) == "CAMDCW") && (splitted.size() > 1))
{
CCstatus.ImageDcw = alphanumericToBoolean(splitted[1]);
}
else if ((toUpper(splitted[0]) == "CAMDENOISE") && (splitted.size() > 1))
{
if (isStringNumeric(splitted[1]))
{
int _ImageDenoiseLevel = std::stoi(splitted[1]);
if (CCstatus.CamSensor_id == OV2640_PID)
{
CCstatus.ImageDenoiseLevel = 0;
}
else
{
CCstatus.ImageDenoiseLevel = clipInt(_ImageDenoiseLevel, 8, 0);
}
}
}
else if ((toUpper(splitted[0]) == "CAMZOOM") && (splitted.size() > 1))
{
CCstatus.ImageZoomEnabled = alphanumericToBoolean(splitted[1]);
}
else if ((toUpper(splitted[0]) == "CAMZOOMOFFSETX") && (splitted.size() > 1))
{
if (isStringNumeric(splitted[1]))
{
int _ImageZoomOffsetX = std::stoi(splitted[1]);
if (CCstatus.CamSensor_id == OV2640_PID)
{
CCstatus.ImageZoomOffsetX = clipInt(_ImageZoomOffsetX, 480, -480);
}
else if (CCstatus.CamSensor_id == OV3660_PID)
{
CCstatus.ImageZoomOffsetX = clipInt(_ImageZoomOffsetX, 704, -704);
}
else if (CCstatus.CamSensor_id == OV5640_PID)
{
CCstatus.ImageZoomOffsetX = clipInt(_ImageZoomOffsetX, 960, -960);
}
}
}
else if ((toUpper(splitted[0]) == "CAMZOOMOFFSETY") && (splitted.size() > 1))
{
if (isStringNumeric(splitted[1]))
{
int _ImageZoomOffsetY = std::stoi(splitted[1]);
if (CCstatus.CamSensor_id == OV2640_PID)
{
CCstatus.ImageZoomOffsetY = clipInt(_ImageZoomOffsetY, 360, -360);
}
else if (CCstatus.CamSensor_id == OV3660_PID)
{
CCstatus.ImageZoomOffsetY = clipInt(_ImageZoomOffsetY, 528, -528);
}
else if (CCstatus.CamSensor_id == OV5640_PID)
{
CCstatus.ImageZoomOffsetY = clipInt(_ImageZoomOffsetY, 720, -720);
}
}
}
else if ((toUpper(splitted[0]) == "CAMZOOMSIZE") && (splitted.size() > 1))
{
if (isStringNumeric(splitted[1]))
{
int _ImageZoomSize = std::stoi(splitted[1]);
if (CCstatus.CamSensor_id == OV2640_PID)
{
CCstatus.ImageZoomSize = clipInt(_ImageZoomSize, 29, 0);
}
else if (CCstatus.CamSensor_id == OV3660_PID)
{
CCstatus.ImageZoomSize = clipInt(_ImageZoomSize, 43, 0);
}
else if (CCstatus.CamSensor_id == OV5640_PID)
{
CCstatus.ImageZoomSize = clipInt(_ImageZoomSize, 59, 0);
}
}
}
else if ((toUpper(splitted[0]) == "LEDINTENSITY") && (splitted.size() > 1))
{
if (isStringNumeric(splitted[1]))
{
float ledintensity = std::stof(splitted[1]);
Camera.SetLEDIntensity(ledintensity);
}
}
else if ((toUpper(splitted[0]) == "DEMO") && (splitted.size() > 1))
{
CCstatus.DemoMode = alphanumericToBoolean(splitted[1]);
if (CCstatus.DemoMode == true)
{
Camera.useDemoMode();
}
}
}
Camera.setSensorDatenFromCCstatus(); // CCstatus >>> Kamera
Camera.SetQualityZoomSize(CCstatus.ImageQuality, CCstatus.ImageFrameSize, CCstatus.ImageZoomEnabled, CCstatus.ImageZoomOffsetX, CCstatus.ImageZoomOffsetY, CCstatus.ImageZoomSize, CCstatus.ImageVflip);
rawImage = new CImageBasis("rawImage");
rawImage->CreateEmptyImage(CCstatus.ImageWidth, CCstatus.ImageHeight, 3);
return true;
}
ClassFlowTakeImage::ClassFlowTakeImage(std::vector<ClassFlow *> *lfc) : ClassFlowImage(lfc, TAG)
{
imagesLocation = "/log/source";
imagesRetention = 5;
SetInitialParameter();
}
bool ClassFlowTakeImage::ReadParameter(FILE* pfile, string& aktparamgraph)
{
std::vector<string> splitted;
aktparamgraph = trim(aktparamgraph);
int _brightness = -100;
int _contrast = -100;
int _saturation = -100;
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]) == "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]) == "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);
Camera.SetQualitySize(ImageQuality, ImageSize);
image_width = Camera.image_width;
image_height = Camera.image_height;
rawImage = new CImageBasis();
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;
@@ -180,70 +537,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, CCstatus.ImageVflip);
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(rawImage);
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;
}
@@ -252,4 +617,3 @@ ClassFlowTakeImage::~ClassFlowTakeImage(void)
{
delete rawImage;
}

View File

@@ -9,47 +9,32 @@
#include <string>
class ClassFlowTakeImage :
public ClassFlowImage
class ClassFlowTakeImage : public ClassFlowImage
{
protected:
float waitbeforepicture;
float waitbeforepicture_store;
framesize_t ImageSize;
bool isImageSize;
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<ClassFlow*>* lfc);
ClassFlowTakeImage(std::vector<ClassFlow *> *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
#endif // CLASSFFLOWTAKEIMAGE_H

View File

@@ -0,0 +1,171 @@
#ifdef ENABLE_WEBHOOK
#include <sstream>
#include "ClassFlowWebhook.h"
#include "Helper.h"
#include "connect_wlan.h"
#include "time_sntp.h"
#include "interface_webhook.h"
#include "ClassFlowPostProcessing.h"
#include "ClassFlowAlignment.h"
#include "esp_log.h"
#include "../../include/defines.h"
#include "ClassLogFile.h"
#include <time.h>
static const char* TAG = "WEBHOOK";
void ClassFlowWebhook::SetInitialParameter(void)
{
uri = "";
flowpostprocessing = NULL;
flowAlignment = NULL;
previousElement = NULL;
ListFlowControll = NULL;
disabled = false;
WebhookEnable = false;
WebhookUploadImg = 0;
}
ClassFlowWebhook::ClassFlowWebhook()
{
SetInitialParameter();
}
ClassFlowWebhook::ClassFlowWebhook(std::vector<ClassFlow*>* lfc)
{
SetInitialParameter();
ListFlowControll = lfc;
for (int i = 0; i < ListFlowControll->size(); ++i)
{
if (((*ListFlowControll)[i])->name().compare("ClassFlowPostProcessing") == 0)
{
flowpostprocessing = (ClassFlowPostProcessing*) (*ListFlowControll)[i];
}
if (((*ListFlowControll)[i])->name().compare("ClassFlowAlignment") == 0)
{
flowAlignment = (ClassFlowAlignment*) (*ListFlowControll)[i];
}
}
}
ClassFlowWebhook::ClassFlowWebhook(std::vector<ClassFlow*>* lfc, ClassFlow *_prev)
{
SetInitialParameter();
previousElement = _prev;
ListFlowControll = lfc;
for (int i = 0; i < ListFlowControll->size(); ++i)
{
if (((*ListFlowControll)[i])->name().compare("ClassFlowPostProcessing") == 0)
{
flowpostprocessing = (ClassFlowPostProcessing*) (*ListFlowControll)[i];
}
if (((*ListFlowControll)[i])->name().compare("ClassFlowAlignment") == 0)
{
flowAlignment = (ClassFlowAlignment*) (*ListFlowControll)[i];
}
}
}
bool ClassFlowWebhook::ReadParameter(FILE* pfile, string& aktparamgraph)
{
std::vector<string> splitted;
aktparamgraph = trim(aktparamgraph);
printf("akt param: %s\n", aktparamgraph.c_str());
if (aktparamgraph.size() == 0)
if (!this->GetNextParagraph(pfile, aktparamgraph))
return false;
if (toUpper(aktparamgraph).compare("[WEBHOOK]") != 0)
return false;
while (this->getNextLine(pfile, &aktparamgraph) && !this->isNewParagraph(aktparamgraph))
{
ESP_LOGD(TAG, "while loop reading line: %s", aktparamgraph.c_str());
splitted = ZerlegeZeile(aktparamgraph);
std::string _param = GetParameterName(splitted[0]);
if ((toUpper(_param) == "URI") && (splitted.size() > 1))
{
this->uri = splitted[1];
}
if (((toUpper(_param) == "APIKEY")) && (splitted.size() > 1))
{
this->apikey = splitted[1];
}
if (((toUpper(_param) == "UPLOADIMG")) && (splitted.size() > 1))
{
if (toUpper(splitted[1]) == "1")
{
this->WebhookUploadImg = 1;
} else if (toUpper(splitted[1]) == "2")
{
this->WebhookUploadImg = 2;
}
}
}
WebhookInit(uri,apikey);
WebhookEnable = true;
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Webhook Enabled for Uri " + uri);
printf("uri: %s\n", uri.c_str());
return true;
}
void ClassFlowWebhook::handleMeasurement(string _decsep, string _value)
{
string _digit, _decpos;
int _pospunkt = _decsep.find_first_of(".");
// ESP_LOGD(TAG, "Name: %s, Pospunkt: %d", _decsep.c_str(), _pospunkt);
if (_pospunkt > -1)
_digit = _decsep.substr(0, _pospunkt);
else
_digit = "default";
for (int j = 0; j < flowpostprocessing->NUMBERS.size(); ++j)
{
if (_digit == "default") // Set to default first (if nothing else is set)
{
flowpostprocessing->NUMBERS[j]->MeasurementV2 = _value;
}
if (flowpostprocessing->NUMBERS[j]->name == _digit)
{
flowpostprocessing->NUMBERS[j]->MeasurementV2 = _value;
}
}
}
bool ClassFlowWebhook::doFlow(string zwtime)
{
if (!WebhookEnable)
return true;
if (flowpostprocessing)
{
printf("vor sende WebHook");
bool numbersWithError = WebhookPublish(flowpostprocessing->GetNumbers());
#ifdef ALGROI_LOAD_FROM_MEM_AS_JPG
if ((WebhookUploadImg == 1 || (WebhookUploadImg != 0 && numbersWithError)) && flowAlignment && flowAlignment->AlgROI) {
WebhookUploadPic(flowAlignment->AlgROI);
}
#endif
}
return true;
}
#endif //ENABLE_WEBHOOK

View File

@@ -0,0 +1,43 @@
#ifdef ENABLE_WEBHOOK
#pragma once
#ifndef CLASSFWEBHOOK_H
#define CLASSFWEBHOOK_H
#include "ClassFlow.h"
#include "ClassFlowPostProcessing.h"
#include "ClassFlowAlignment.h"
#include <string>
class ClassFlowWebhook :
public ClassFlow
{
protected:
std::string uri, apikey;
ClassFlowPostProcessing* flowpostprocessing;
ClassFlowAlignment* flowAlignment;
bool WebhookEnable;
int WebhookUploadImg;
void SetInitialParameter(void);
void handleFieldname(string _decsep, string _value);
void handleMeasurement(string _decsep, string _value);
public:
ClassFlowWebhook();
ClassFlowWebhook(std::vector<ClassFlow*>* lfc);
ClassFlowWebhook(std::vector<ClassFlow*>* lfc, ClassFlow *_prev);
bool ReadParameter(FILE* pfile, string& aktparamgraph);
bool doFlow(string time);
string name(){return "ClassFlowWebhook";};
};
#endif //CLASSFWEBHOOK_H
#endif //ENABLE_WEBHOOK

View File

@@ -1,91 +0,0 @@
#include <sstream>
#include "ClassFlowWriteList.h"
#include "Helper.h"
#include "time_sntp.h"
#include "../../include/defines.h"
#include <time.h>
void ClassFlowWriteList::SetInitialParameter(void)
{
flowpostprocessing = NULL;
previousElement = NULL;
ListFlowControll = NULL;
disabled = false;
}
ClassFlowWriteList::ClassFlowWriteList()
{
SetInitialParameter();
}
ClassFlowWriteList::ClassFlowWriteList(std::vector<ClassFlow*>* lfc)
{
SetInitialParameter();
ListFlowControll = lfc;
for (int i = 0; i < ListFlowControll->size(); ++i)
{
if (((*ListFlowControll)[i])->name().compare("ClassFlowPostProcessing") == 0)
{
flowpostprocessing = (ClassFlowPostProcessing*) (*ListFlowControll)[i];
}
}
}
bool ClassFlowWriteList::ReadParameter(FILE* pfile, string& aktparamgraph)
{
std::vector<string> splitted;
aktparamgraph = trim(aktparamgraph);
if (aktparamgraph.size() == 0)
if (!this->GetNextParagraph(pfile, aktparamgraph))
return false;
if (toUpper(aktparamgraph).compare("[MQTT]") != 0)
return false;
while (this->getNextLine(pfile, &aktparamgraph) && !this->isNewParagraph(aktparamgraph))
{
splitted = ZerlegeZeile(aktparamgraph);
}
return true;
}
bool ClassFlowWriteList::doFlow(string zwtime)
{
std::string line = "";
std::string result;
std::string resulterror = "";
std::string resultraw = "";
std::string resultrate = "";
std::string resulttimestamp = "";
string zw = "";
string namenumber = "";
if (flowpostprocessing)
{
std::vector<NumberPost*>* NUMBERS = flowpostprocessing->GetNumbers();
for (int i = 0; i < (*NUMBERS).size(); ++i)
{
result = (*NUMBERS)[i]->ReturnValue;
resultraw = (*NUMBERS)[i]->ReturnRawValue;
resulterror = (*NUMBERS)[i]->ErrorMessageText;
resultrate = (*NUMBERS)[i]->ReturnRateValue;
resulttimestamp = (*NUMBERS)[i]->timeStamp;
line = line + resulttimestamp + "\t" + resultraw + "\t" + result + "\t" + resultraw + "\t" + resultrate + "\t" + resulttimestamp + "\t";
}
}
return true;
}

View File

@@ -1,27 +0,0 @@
#pragma once
#ifndef CLASSFFLOWPWRITELIST_H
#define CLASSFFLOWPWRITELIST_H
#include "ClassFlow.h"
#include "ClassFlowPostProcessing.h"
#include <string>
class ClassFlowWriteList :
public ClassFlow
{
protected:
ClassFlowPostProcessing* flowpostprocessing;
void SetInitialParameter(void);
public:
ClassFlowWriteList();
ClassFlowWriteList(std::vector<ClassFlow*>* lfc);
bool ReadParameter(FILE* pfile, string& aktparamgraph);
bool doFlow(string time);
string name(){return "ClassFlowWriteList";};
};
#endif //CLASSFFLOWPWRITELIST_H

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,91 @@
#pragma once
#ifndef MAINFLOWCONTROL_H
#define MAINFLOWCONTROL_H
#include <esp_log.h>
#include <string>
#include <esp_http_server.h>
#include "CImageBasis.h"
#include "ClassFlowControll.h"
#include "openmetrics.h"
typedef struct
{
uint16_t CamSensor_id;
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 ImageDenoiseLevel; // The OV2640 does not support it, OV3660 and OV5640 (0 to 8)
int ImageWidth;
int ImageHeight;
int ImageLedIntensity;
bool ImageZoomEnabled;
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(void);
bool getIsPlannedReboot(void);
void InitializeFlowTask(void);
void DeleteMainFlowTask(void);
bool isSetupModusActive(void);
int getCountFlowRounds(void);
#ifdef ENABLE_MQTT
esp_err_t MQTTCtrlFlowStart(std::string _topic);
#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

View File

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

File diff suppressed because it is too large Load Diff

View File

@@ -6,6 +6,7 @@
#include <string>
#include <fstream>
#include <vector>
#include "sdmmc_cmd.h"
using namespace std;
@@ -20,7 +21,6 @@ bool RenameFile(string from, string to);
bool MakeDir(std::string _what);
bool FileExists(string filename);
string RundeOutput(double _in, int _anzNachkomma);
size_t findDelimiterPos(string input, string delimiter);
@@ -32,7 +32,6 @@ string getFileType(string filename);
string getFileFullFileName(string filename);
string getDirectory(string filename);
int mkdir_r(const char *dir, const mode_t mode);
int removeFolder(const char* folderPath, const char* logTag);
@@ -67,7 +66,6 @@ string getSDCardSectorSize();
string getMac(void);
/* Error bit fields
One bit per error
Make sure it matches https://jomjol.github.io/AI-on-the-edge-device-docs/Error-Codes */
@@ -76,6 +74,8 @@ enum SystemStatusFlag_t { // One bit per error
SYSTEM_STATUS_PSRAM_BAD = 1 << 0, // 1, Critical Error
SYSTEM_STATUS_HEAP_TOO_SMALL = 1 << 1, // 2, Critical Error
SYSTEM_STATUS_CAM_BAD = 1 << 2, // 4, Critical Error
SYSTEM_STATUS_SDCARD_CHECK_BAD = 1 << 3, // 8, Critical Error
SYSTEM_STATUS_FOLDER_CHECK_BAD = 1 << 4, // 16, Critical Error
// Second Byte
SYSTEM_STATUS_CAM_FB_BAD = 1 << (0+8), // 8, Flow still might work
@@ -95,4 +95,18 @@ const char* get404(void);
std::string UrlDecode(const std::string& value);
void replaceAll(std::string& s, const std::string& toReplace, const std::string& replaceWith);
bool replaceString(std::string& s, std::string const& toReplace, std::string const& replaceWith);
bool replaceString(std::string& s, std::string const& toReplace, std::string const& replaceWith, bool logIt);
bool isInString(std::string& s, std::string const& toFind);
bool isStringNumeric(std::string &input);
bool isStringAlphabetic(std::string &input);
bool isStringAlphanumeric(std::string &input);
bool alphanumericToBoolean(std::string &input);
int clipInt(int input, int high, int low);
bool numericStrToBool(std::string input);
bool stringToBoolean(std::string input);
#endif //HELPER_H

View File

@@ -3,6 +3,7 @@
#ifdef DEBUG_ENABLE_SYSINFO
#include "esp_sys.h"
#include "esp_chip_info.h"
#include <string>
@@ -121,7 +122,7 @@ std::string get_device_info()
}
#ifdef USE_HIMEM_IF_AVAILABLE
sprintf(aMsgBuf,"spiram size %u\n", esp_spiram_get_size());
sprintf(aMsgBuf,"spiram size %u\n", esp_psram_get_size());
espInfoResultStr += std::string(aMsgBuf);
sprintf(aMsgBuf,"himem free %u\n", esp_himem_get_free_size());
espInfoResultStr += std::string(aMsgBuf);

View File

@@ -16,9 +16,9 @@
#include <esp_spi_flash.h>
#include <esp_heap_caps.h>
// for esp_spiram_get_size
// for esp_psram_get_size
extern "C" {
#include <esp32/spiram.h>
#include "esp_psram.h"
#ifdef USE_HIMEM_IF_AVAILABLE
#include <esp32/himem.h>
#endif

View File

@@ -0,0 +1,211 @@
#include "ClassLogFile.h"
#include "../../include/defines.h"
#include "psram.h"
static const char* TAG = "PSRAM";
using namespace std;
void *shared_region = NULL;
uint32_t allocatedBytesForSTBI = 0;
std::string sharedMemoryInUseFor = "";
/** Reserve a large block in the PSRAM which will be shared between the different steps.
* Each step uses it differently but only wiuthin itself. */
bool reserve_psram_shared_region(void) {
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Allocating shared PSRAM region (" +
std::to_string(TENSOR_ARENA_SIZE + MAX_MODEL_SIZE) + " bytes)...");
shared_region = malloc_psram_heap("Shared PSRAM region", TENSOR_ARENA_SIZE + MAX_MODEL_SIZE,
MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT);
if (shared_region == NULL) {
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Failed to allocating shared PSRAM region!");
return false;
}
else {
return true;
}
}
/*******************************************************************
* Memory used in Take Image (STBI)
*******************************************************************/
bool psram_init_shared_memory_for_take_image_step(void) {
if (sharedMemoryInUseFor != "") {
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Shared memory in PSRAM already in use for " + sharedMemoryInUseFor + "!");
return false;
}
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Init shared memory for step 'Take Image' (STBI buffers)");
allocatedBytesForSTBI = 0;
sharedMemoryInUseFor = "TakeImage";
return true;
}
void psram_deinit_shared_memory_for_take_image_step(void) {
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Deinit shared memory for step 'Take Image' (STBI buffers)");
allocatedBytesForSTBI = 0;
sharedMemoryInUseFor = "";
}
void *psram_reserve_shared_stbi_memory(size_t size) {
/* Only large buffers should be placed in the shared PSRAM
* If we also place all smaller STBI buffers here, we get artefacts for some reasons. */
if (size >= 100000) {
if ((allocatedBytesForSTBI + size) > TENSOR_ARENA_SIZE + MAX_MODEL_SIZE) { // Check if it still fits in the shared region
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Shared memory in PSRAM too small (STBI) to fit additional " +
std::to_string(size) + " bytes! Available: " + std::to_string(TENSOR_ARENA_SIZE + MAX_MODEL_SIZE - allocatedBytesForSTBI) + " bytes!");
return NULL;
}
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Allocating memory (" + std::to_string(size) + " bytes) for STBI (use shared memory in PSRAM)...");
allocatedBytesForSTBI += size;
return (uint8_t *)shared_region + allocatedBytesForSTBI - size;
}
else { // Normal PSRAM
return malloc_psram_heap("STBI", size, MALLOC_CAP_SPIRAM);
}
}
void *psram_reallocate_shared_stbi_memory(void *ptr, size_t newsize) {
char buf[20];
sprintf(buf, "%p", ptr);
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "STBI requested realloc for " + std::string(buf) + " but this is currently unsupported!");
return NULL;
}
void psram_free_shared_stbi_memory(void *p) {
if ((p >= shared_region) && (p <= ((uint8_t *)shared_region + allocatedBytesForSTBI))) { // was allocated inside the shared memory
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Part of shared memory used for STBI (PSRAM, part of shared memory) is free again");
}
else { // Normal PSRAM
free_psram_heap("STBI", p);
}
}
/*******************************************************************
* Memory used in Aligning Step
* During this step we only use the shared part of the PSRAM
* for the tmpImage.
*******************************************************************/
void *psram_reserve_shared_tmp_image_memory(void) {
if (sharedMemoryInUseFor != "") {
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Shared memory in PSRAM already in use for " + sharedMemoryInUseFor + "!");
return NULL;
}
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Allocating tmpImage (" + std::to_string(IMAGE_SIZE) + " bytes, use shared memory in PSRAM)...");
sharedMemoryInUseFor = "Aligning";
return shared_region; // Use 1th part of the shared memory for the tmpImage (only user)
}
void psram_free_shared_temp_image_memory(void) {
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Shared memory used for tmpImage (PSRAM, part of shared memory) is free again");
sharedMemoryInUseFor = "";
}
/*******************************************************************
* Memory used in Digitization Steps
* During this step we only use the shared part of the PSRAM for the
* Tensor Arena and one of the Models.
* The shared memory is large enough for the largest model and the
* Tensor Arena. Therefore we do not need to monitor the usage.
*******************************************************************/
void *psram_get_shared_tensor_arena_memory(void) {
if ((sharedMemoryInUseFor == "") || (sharedMemoryInUseFor == "Digitization_Model")) {
sharedMemoryInUseFor = "Digitization_Tensor";
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Allocating Tensor Arena (" + std::to_string(TENSOR_ARENA_SIZE) + " bytes, use shared memory in PSRAM)...");
return shared_region; // Use 1th part of the shared memory for Tensor
}
else {
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Shared memory in PSRAM already in use for " + sharedMemoryInUseFor + "!");
return NULL;
}
}
void *psram_get_shared_model_memory(void) {
if ((sharedMemoryInUseFor == "") || (sharedMemoryInUseFor == "Digitization_Tensor")) {
sharedMemoryInUseFor = "Digitization_Model";
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Allocating Model memory (" + std::to_string(MAX_MODEL_SIZE) + " bytes, use shared memory in PSRAM)...");
return (uint8_t *)shared_region + TENSOR_ARENA_SIZE; // Use 2nd part of the shared memory (after Tensor Arena) for the model
}
else {
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Shared memory in PSRAM already in use for " + sharedMemoryInUseFor + "!");
return NULL;
}
}
void psram_free_shared_tensor_arena_and_model_memory(void) {
sharedMemoryInUseFor = "";
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Shared memory used for Tensor Arena and model (PSRAM, part of shared memory) is free again");
}
/*******************************************************************
* General
*******************************************************************/
void *malloc_psram_heap(std::string name, size_t size, uint32_t caps) {
void *ptr;
ptr = heap_caps_malloc(size, caps);
if (ptr != NULL) {
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Allocated " + to_string(size) + " bytes in PSRAM for '" + name + "'");
}
else {
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Failed to allocate " + to_string(size) + " bytes in PSRAM for '" + name + "'!");
}
return ptr;
}
void *realloc_psram_heap(std::string name, void *ptr, size_t size, uint32_t caps) {
ptr = heap_caps_realloc(ptr, size, caps);
if (ptr != NULL) {
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Reallocated " + to_string(size) + " bytes in PSRAM for '" + name + "'");
}
else {
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Failed to reallocate " + to_string(size) + " bytes in PSRAM for '" + name + "'!");
}
return ptr;
}
void *calloc_psram_heap(std::string name, size_t n, size_t size, uint32_t caps) {
void *ptr;
ptr = heap_caps_calloc(n, size, caps);
if (ptr != NULL) {
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Allocated " + to_string(size) + " bytes in PSRAM for '" + name + "'");
}
else {
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Failed to allocate " + to_string(size) + " bytes in PSRAM for '" + name + "'!");
}
return ptr;
}
void free_psram_heap(std::string name, void *ptr) {
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Freeing memory in PSRAM used for '" + name + "'...");
heap_caps_free(ptr);
}

View File

@@ -0,0 +1,35 @@
#pragma once
#ifndef PSRAM_h
#define PSRAM_h
#include "esp_heap_caps.h"
bool reserve_psram_shared_region(void);
/* Memory used in Take Image Step */
bool psram_init_shared_memory_for_take_image_step(void);
void psram_deinit_shared_memory_for_take_image_step(void);
void *psram_reserve_shared_stbi_memory(size_t size);
void *psram_reallocate_shared_stbi_memory(void *ptr, size_t newsize);
void psram_free_shared_stbi_memory(void *p);
/* Memory used in Aligning Step */
void *psram_reserve_shared_tmp_image_memory(void);
void psram_free_shared_temp_image_memory(void);
/* Memory used in Digitization Steps */
void *psram_get_shared_tensor_arena_memory(void);
void *psram_get_shared_model_memory(void);
void psram_free_shared_tensor_arena_and_model_memory(void);
/* General */
void *malloc_psram_heap(std::string name, size_t size, uint32_t caps);
void *realloc_psram_heap(std::string name, void *ptr, size_t size, uint32_t caps);
void *calloc_psram_heap(std::string name, size_t n, size_t size, uint32_t caps);
void free_psram_heap(std::string name, void *ptr);
#endif // PSRAM_h

View File

@@ -0,0 +1,161 @@
#include "sdcard_check.h"
#include <string.h>
#include <stdio.h>
#include <stdbool.h>
#include <stdint.h>
#include <unistd.h>
#include <inttypes.h>
#include <sys/stat.h>
#include "esp_rom_crc.h"
#include "ClassLogFile.h"
static const char *TAG = "SDCARD";
int SDCardCheckRW(void)
{
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Basic R/W check started...");
FILE* pFile = NULL;
int iCRCMessage = 0;
pFile = fopen("/sdcard/sdcheck.txt","w");
if (pFile == NULL) {
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Basic R/W check: (E1) No able to open file to write");
return -1;
}
else {
std::string sMessage = "This message is used for a SD-Card basic check!";
iCRCMessage = esp_rom_crc16_le(0, (uint8_t*)sMessage.c_str(), sMessage.length());
if (fwrite(sMessage.c_str(), sMessage.length(), 1, pFile) == 0 ) {
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Basic R/W check: (E2) Not able to write file");
fclose(pFile);
unlink("/sdcard/sdcheck.txt");
return -2;
}
fclose(pFile);
}
pFile = fopen("/sdcard/sdcheck.txt","r");
if (pFile == NULL) {
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Basic R/W check: (E3) Not able to open file to read back");
unlink("/sdcard/sdcheck.txt");
return -3;
}
else {
char cReadBuf[50];
if (fgets(cReadBuf, sizeof(cReadBuf), pFile) == 0) {
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Basic R/W check: (E4) Not able to read file back");
fclose(pFile);
unlink("/sdcard/sdcheck.txt");
return -4;
}
else {
if (esp_rom_crc16_le(0, (uint8_t*)cReadBuf, strlen(cReadBuf)) != iCRCMessage) {
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Basic R/W check: (E5) Read back, but wrong CRC");
fclose(pFile);
unlink("/sdcard/sdcheck.txt");
return -5;
}
}
fclose(pFile);
}
if (unlink("/sdcard/sdcheck.txt") != 0) {
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Basic R/W check: (E6) Unable to delete the file");
return -6;
}
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Basic R/W check successful");
return 0;
}
bool SDCardCheckFolderFilePresence()
{
struct stat sb;
bool bRetval = true;
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Folder/file presence check started...");
/* check if folder exists: config */
if (stat("/sdcard/config", &sb) != 0) {
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Folder/file check: Folder /config not found");
bRetval = false;
}
/* check if folder exists: html */
if (stat("/sdcard/html", &sb) != 0) {
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Folder/file check: Folder /html not found");
bRetval = false;
}
/* check if folder exists: firmware */
if (stat("/sdcard/firmware", &sb) != 0) {
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Folder/file check: Folder /firmware not found");
bRetval = false;
}
/* check if folder exists: img_tmp */
if (stat("/sdcard/img_tmp", &sb) != 0) {
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Folder/file check: Folder /img_tmp not found");
bRetval = false;
}
/* check if folder exists: log */
if (stat("/sdcard/log", &sb) != 0) {
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Folder/file check: Folder /log not found");
bRetval = false;
}
/* check if folder exists: demo */
if (stat("/sdcard/demo", &sb) != 0) {
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Folder/file check: Folder /demo not found");
bRetval = false;
}
/* check if file exists: wlan.ini */
if (stat("/sdcard/wlan.ini", &sb) != 0) {
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Folder/file check: File /wlan.ini not found");
bRetval = false;
}
/* check if file exists: config.ini */
if (stat("/sdcard/config/config.ini", &sb) != 0) {
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Folder/file check: File /config/config.ini not found");
bRetval = false;
}
/* check if file exists: index.html */
if (stat("/sdcard/html/index.html", &sb) != 0) {
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Folder/file check: File /html/index.html not found");
bRetval = false;
}
/* check if file exists: ota.html */
if (stat("/sdcard/html/ota_page.html", &sb) != 0) {
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Folder/file check: File /html/ota.html not found");
bRetval = false;
}
/* check if file exists: log.html */
if (stat("/sdcard/html/log.html", &sb) != 0) {
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Folder/file check: File /html/log.html not found");
bRetval = false;
}
/* check if file exists: common.js */
if (stat("/sdcard/html/common.js", &sb) != 0) {
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Folder/file check: File /html/common.js not found");
bRetval = false;
}
/* check if file exists: version.txt */
if (stat("/sdcard/html/version.txt", &sb) != 0) {
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Folder/file check: File /html/version.txt not found");
bRetval = false;
}
if (bRetval)
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Folder/file presence check successful");
return bRetval;
}

View File

@@ -0,0 +1,11 @@
#pragma once
#ifndef COMPONENTS_HELPER_SDCARD_CHECK_H
#define COMPONENTS_HELPER_SDCARD_CHECK_H
#include "../../include/defines.h"
int SDCardCheckRW(void);
bool SDCardCheckFolderFilePresence(void);
#endif /* COMPONENTS_HELPER_SDCARD_CHECK_H */

View File

@@ -0,0 +1,646 @@
/*
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdlib.h>
#include <string.h>
#include "sdcard_init.h"
#include "esp_log.h"
#include "ffconf.h"
#include "esp_compiler.h"
#include "esp_vfs.h"
#include "vfs_fat_internal.h"
#include "diskio_impl.h"
#include "diskio_sdmmc.h"
#include "soc/soc_caps.h"
#include "driver/sdmmc_defs.h"
#if SOC_SDMMC_HOST_SUPPORTED
#include "driver/sdmmc_host.h"
#endif
static sdmmc_card_t* s_cards[FF_VOLUMES] = { NULL };
static bool s_disk_status_check_en[FF_VOLUMES] = { };
static const char* TAG = "sdcard_init";
#define CHECK_EXECUTE_RESULT(err, str) do { \
if ((err) !=ESP_OK) { \
ESP_LOGE(TAG, str" (0x%x).", err); \
goto cleanup; \
} \
} while(0)
typedef struct mh_vfs_fat_sd_ctx_t {
BYTE pdrv; //Drive number that is mounted
esp_vfs_fat_mount_config_t mount_config; //Mount configuration
FATFS *fs; //FAT structure pointer that is registered
sdmmc_card_t *card; //Card info
char *base_path; //Path where partition is registered
} mh_vfs_fat_sd_ctx_t;
static mh_vfs_fat_sd_ctx_t *s_ctx[FF_VOLUMES] = {};
/**
* This `s_saved_ctx_id` is only used by `esp_vfs_fat_sdmmc_unmount`, which is deprecated.
* This variable together with `esp_vfs_fat_sdmmc_unmount` should be removed in next major version
*/
static uint32_t s_saved_ctx_id = FF_VOLUMES;
static void call_host_deinit_mh(const sdmmc_host_t *host_config);
static esp_err_t partition_card_mh(const esp_vfs_fat_mount_config_t *mount_config, const char *drv, sdmmc_card_t *card, BYTE pdrv);
//Check if SD/MMC card is present
static DSTATUS ff_sdmmc_card_available_mh(BYTE pdrv)
{
sdmmc_card_t* card = s_cards[pdrv];
assert(card);
esp_err_t err = sdmmc_get_status(card);
if (unlikely(err != ESP_OK)) {
ESP_LOGE(TAG, "Check status failed (0x%x)", err);
return STA_NOINIT;
}
return 0;
}
/**
* ff_sdmmc_status() and ff_sdmmc_initialize() return STA_NOINIT when sdmmc_get_status()
* fails. This error value is checked throughout the FATFS code.
* Both functions return 0 on success.
*/
DSTATUS ff_sdmmc_initialize_mh (BYTE pdrv)
{
return ff_sdmmc_card_available_mh(pdrv);
}
DSTATUS ff_sdmmc_status_mh(BYTE pdrv)
{
if (s_disk_status_check_en[pdrv]) {
return ff_sdmmc_card_available_mh(pdrv);
}
return 0;
}
DRESULT ff_sdmmc_read_mh (BYTE pdrv, BYTE* buff, DWORD sector, UINT count)
{
sdmmc_card_t* card = s_cards[pdrv];
assert(card);
esp_err_t err = sdmmc_read_sectors(card, buff, sector, count);
if (unlikely(err != ESP_OK)) {
ESP_LOGE(TAG, "sdmmc_read_blocks failed (%d)", err);
return RES_ERROR;
}
return RES_OK;
}
DRESULT ff_sdmmc_write_mh (BYTE pdrv, const BYTE* buff, DWORD sector, UINT count)
{
sdmmc_card_t* card = s_cards[pdrv];
assert(card);
esp_err_t err = sdmmc_write_sectors(card, buff, sector, count);
if (unlikely(err != ESP_OK)) {
ESP_LOGE(TAG, "sdmmc_write_blocks failed (%d)", err);
return RES_ERROR;
}
return RES_OK;
}
#if FF_USE_TRIM
DRESULT ff_sdmmc_trim_mh (BYTE pdrv, DWORD start_sector, DWORD sector_count)
{
sdmmc_card_t* card = s_cards[pdrv];
assert(card);
sdmmc_erase_arg_t arg;
arg = sdmmc_can_discard(card) == ESP_OK ? SDMMC_DISCARD_ARG : SDMMC_ERASE_ARG;
esp_err_t err = sdmmc_erase_sectors(card, start_sector, sector_count, arg);
if (unlikely(err != ESP_OK)) {
ESP_LOGE(TAG, "sdmmc_erase_sectors failed (%d)", err);
return RES_ERROR;
}
return RES_OK;
}
#endif //FF_USE_TRIM
DRESULT ff_sdmmc_ioctl_mh (BYTE pdrv, BYTE cmd, void* buff)
{
sdmmc_card_t* card = s_cards[pdrv];
assert(card);
switch(cmd) {
case CTRL_SYNC:
return RES_OK;
case GET_SECTOR_COUNT:
*((DWORD*) buff) = card->csd.capacity;
return RES_OK;
case GET_SECTOR_SIZE:
*((WORD*) buff) = card->csd.sector_size;
return RES_OK;
case GET_BLOCK_SIZE:
return RES_ERROR;
#if FF_USE_TRIM
case CTRL_TRIM:
if (sdmmc_can_trim(card) != ESP_OK) {
return RES_PARERR;
}
return ff_sdmmc_trim_mh (pdrv, *((DWORD*)buff), //start_sector
(*((DWORD*)buff + 1) - *((DWORD*)buff) + 1)); //sector_count
#endif //FF_USE_TRIM
}
return RES_ERROR;
}
void ff_sdmmc_set_disk_status_check_mh(BYTE pdrv, bool enable)
{
s_disk_status_check_en[pdrv] = enable;
}
void ff_diskio_register_sdmmc_mh(BYTE pdrv, sdmmc_card_t* card)
{
static const ff_diskio_impl_t sdmmc_impl = {
.init = &ff_sdmmc_initialize_mh,
.status = &ff_sdmmc_status_mh,
.read = &ff_sdmmc_read_mh,
.write = &ff_sdmmc_write_mh,
.ioctl = &ff_sdmmc_ioctl_mh
};
s_cards[pdrv] = card;
s_disk_status_check_en[pdrv] = false;
ff_diskio_register(pdrv, &sdmmc_impl);
}
BYTE ff_diskio_get_pdrv_card_mh(const sdmmc_card_t* card)
{
for (int i = 0; i < FF_VOLUMES; i++) {
if (card == s_cards[i]) {
return i;
}
}
return 0xff;
}
static bool s_get_context_id_by_card_mh(const sdmmc_card_t *card, uint32_t *out_id)
{
mh_vfs_fat_sd_ctx_t *p_ctx = NULL;
for (int i = 0; i < FF_VOLUMES; i++) {
p_ctx = s_ctx[i];
if (p_ctx) {
if (p_ctx->card == card) {
*out_id = i;
return true;
}
}
}
return false;
}
static uint32_t s_get_unused_context_id_mh(void)
{
for (uint32_t i = 0; i < FF_VOLUMES; i++) {
if (!s_ctx[i]) {
return i;
}
}
return FF_VOLUMES;
}
static esp_err_t mount_prepare_mem_mh(const char *base_path, BYTE *out_pdrv, char **out_dup_path, sdmmc_card_t** out_card)
{
esp_err_t err = ESP_OK;
char* dup_path = NULL;
sdmmc_card_t* card = NULL;
// connect SDMMC driver to FATFS
BYTE pdrv = FF_DRV_NOT_USED;
if (ff_diskio_get_drive(&pdrv) != ESP_OK || pdrv == FF_DRV_NOT_USED) {
ESP_LOGD(TAG, "the maximum count of volumes is already mounted");
return ESP_ERR_NO_MEM;
}
// not using ff_memalloc here, as allocation in internal RAM is preferred
card = (sdmmc_card_t*)malloc(sizeof(sdmmc_card_t));
if (card == NULL) {
ESP_LOGD(TAG, "could not locate new sdmmc_card_t");
err = ESP_ERR_NO_MEM;
goto cleanup;
}
dup_path = strdup(base_path);
if(!dup_path){
ESP_LOGD(TAG, "could not copy base_path");
err = ESP_ERR_NO_MEM;
goto cleanup;
}
*out_card = card;
*out_pdrv = pdrv;
*out_dup_path = dup_path;
return ESP_OK;
cleanup:
free(card);
free(dup_path);
return err;
}
static esp_err_t s_f_mount_mh(sdmmc_card_t *card, FATFS *fs, const char *drv, uint8_t pdrv, const esp_vfs_fat_mount_config_t *mount_config)
{
esp_err_t err = ESP_OK;
FRESULT res = f_mount(fs, drv, 1);
if (res != FR_OK) {
err = ESP_FAIL;
ESP_LOGW(TAG, "failed to mount card (%d)", res);
bool need_mount_again = (res == FR_NO_FILESYSTEM || res == FR_INT_ERR) && mount_config->format_if_mount_failed;
if (!need_mount_again) {
return ESP_FAIL;
}
err = partition_card_mh(mount_config, drv, card, pdrv);
if (err != ESP_OK) {
return err;
}
ESP_LOGW(TAG, "mounting again");
res = f_mount(fs, drv, 0);
if (res != FR_OK) {
err = ESP_FAIL;
ESP_LOGD(TAG, "f_mount failed after formatting (%d)", res);
return err;
}
}
return ESP_OK;
}
static esp_err_t mount_to_vfs_fat_mh(const esp_vfs_fat_mount_config_t *mount_config, sdmmc_card_t *card, uint8_t pdrv, const char *base_path, FATFS **out_fs)
{
FATFS *fs = NULL;
esp_err_t err;
ff_diskio_register_sdmmc_mh(pdrv, card);
ff_sdmmc_set_disk_status_check_mh(pdrv, mount_config->disk_status_check_enable);
ESP_LOGD(TAG, "using pdrv=%i", pdrv);
char drv[3] = {(char)('0' + pdrv), ':', 0};
// connect FATFS to VFS
err = esp_vfs_fat_register(base_path, drv, mount_config->max_files, &fs);
*out_fs = fs;
if (err == ESP_ERR_INVALID_STATE) {
// it's okay, already registered with VFS
} else if (err != ESP_OK) {
ESP_LOGD(TAG, "esp_vfs_fat_register failed 0x(%x)", err);
goto fail;
}
// Try to mount partition
err = s_f_mount_mh(card, fs, drv, pdrv, mount_config);
if (err != ESP_OK) {
goto fail;
}
return ESP_OK;
fail:
if (fs) {
f_mount(NULL, drv, 0);
}
esp_vfs_fat_unregister_path(base_path);
ff_diskio_unregister(pdrv);
return err;
}
static esp_err_t partition_card_mh(const esp_vfs_fat_mount_config_t *mount_config, const char *drv, sdmmc_card_t *card, BYTE pdrv)
{
FRESULT res = FR_OK;
esp_err_t err;
const size_t workbuf_size = 4096;
void* workbuf = NULL;
ESP_LOGW(TAG, "partitioning card");
workbuf = ff_memalloc(workbuf_size);
if (workbuf == NULL) {
return ESP_ERR_NO_MEM;
}
LBA_t plist[] = {100, 0, 0, 0};
res = f_fdisk(pdrv, plist, workbuf);
if (res != FR_OK) {
err = ESP_FAIL;
ESP_LOGD(TAG, "f_fdisk failed (%d)", res);
goto fail;
}
size_t alloc_unit_size = esp_vfs_fat_get_allocation_unit_size(card->csd.sector_size, mount_config->allocation_unit_size);
ESP_LOGW(TAG, "formatting card, allocation unit size=%d", alloc_unit_size);
const MKFS_PARM opt = {(BYTE)FM_ANY, 0, 0, 0, alloc_unit_size};
res = f_mkfs(drv, &opt, workbuf, workbuf_size);
if (res != FR_OK) {
err = ESP_FAIL;
ESP_LOGD(TAG, "f_mkfs failed (%d)", res);
goto fail;
}
free(workbuf);
return ESP_OK;
fail:
free(workbuf);
return err;
}
#if SOC_SDMMC_HOST_SUPPORTED
static esp_err_t init_sdmmc_host_mh(int slot, const void *slot_config, int *out_slot)
{
*out_slot = slot;
return sdmmc_host_init_slot(slot, (const sdmmc_slot_config_t*) slot_config);
}
esp_err_t esp_vfs_fat_sdmmc_mount_mh(const char* base_path, const sdmmc_host_t* host_config, const void* slot_config, const esp_vfs_fat_mount_config_t* mount_config, sdmmc_card_t** out_card)
{
esp_err_t err;
mh_vfs_fat_sd_ctx_t *ctx = NULL;
uint32_t ctx_id = FF_VOLUMES;
FATFS *fs = NULL;
int card_handle = -1; //uninitialized
sdmmc_card_t* card = NULL;
BYTE pdrv = FF_DRV_NOT_USED;
char* dup_path = NULL;
bool host_inited = false;
err = mount_prepare_mem_mh(base_path, &pdrv, &dup_path, &card);
if (err != ESP_OK) {
ESP_LOGE(TAG, "mount_prepare failed");
return err;
}
err = (*host_config->init)();
CHECK_EXECUTE_RESULT(err, "host init failed");
//deinit() needs to be called to revert the init
host_inited = true;
//If this failed (indicated by card_handle != -1), slot deinit needs to called()
//leave card_handle as is to indicate that (though slot deinit not implemented yet.
err = init_sdmmc_host_mh(host_config->slot, slot_config, &card_handle);
CHECK_EXECUTE_RESULT(err, "slot init failed");
// probe and initialize card
err = sdmmc_card_init(host_config, card);
CHECK_EXECUTE_RESULT(err, "sdmmc_card_init failed");
err = mount_to_vfs_fat_mh(mount_config, card, pdrv, dup_path, &fs);
CHECK_EXECUTE_RESULT(err, "mount_to_vfs failed");
if (out_card != NULL) {
*out_card = card;
}
//For deprecation backward compatibility
if (s_saved_ctx_id == FF_VOLUMES) {
s_saved_ctx_id = 0;
}
ctx = calloc(sizeof(mh_vfs_fat_sd_ctx_t), 1);
if (!ctx) {
CHECK_EXECUTE_RESULT(ESP_ERR_NO_MEM, "no mem");
}
ctx->pdrv = pdrv;
memcpy(&ctx->mount_config, mount_config, sizeof(esp_vfs_fat_mount_config_t));
ctx->card = card;
ctx->base_path = dup_path;
ctx->fs = fs;
ctx_id = s_get_unused_context_id_mh();
assert(ctx_id != FF_VOLUMES);
s_ctx[ctx_id] = ctx;
return ESP_OK;
cleanup:
if (host_inited) {
call_host_deinit_mh(host_config);
}
free(card);
free(dup_path);
return err;
}
#endif
static esp_err_t init_sdspi_host_mh(int slot, const void *slot_config, int *out_slot)
{
esp_err_t err = sdspi_host_init_device((const sdspi_device_config_t*)slot_config, out_slot);
if (err != ESP_OK) {
ESP_LOGE(TAG,
"Failed to attach sdspi device onto an SPI bus (rc=0x%x), please initialize the \
bus first and check the device parameters."
, err);
}
return err;
}
esp_err_t esp_vfs_fat_sdspi_mount_mh(const char* base_path, const sdmmc_host_t* host_config_input, const sdspi_device_config_t* slot_config, const esp_vfs_fat_mount_config_t* mount_config, sdmmc_card_t** out_card)
{
const sdmmc_host_t* host_config = host_config_input;
esp_err_t err;
mh_vfs_fat_sd_ctx_t *ctx = NULL;
uint32_t ctx_id = FF_VOLUMES;
FATFS *fs = NULL;
int card_handle = -1; //uninitialized
bool host_inited = false;
BYTE pdrv = FF_DRV_NOT_USED;
sdmmc_card_t* card = NULL;
char* dup_path = NULL;
err = mount_prepare_mem_mh(base_path, &pdrv, &dup_path, &card);
if (err != ESP_OK) {
ESP_LOGE(TAG, "mount_prepare failed");
return err;
}
//the init() function is usually empty, doesn't require any deinit to revert it
err = (*host_config->init)();
CHECK_EXECUTE_RESULT(err, "host init failed");
err = init_sdspi_host_mh(host_config->slot, slot_config, &card_handle);
CHECK_EXECUTE_RESULT(err, "slot init failed");
//Set `host_inited` to true to indicate that host_config->deinit() needs
//to be called to revert `init_sdspi_host`
host_inited = true;
//The `slot` argument inside host_config should be replaced by the SD SPI handled returned
//above. But the input pointer is const, so create a new variable.
sdmmc_host_t new_config;
if (card_handle != host_config->slot) {
new_config = *host_config_input;
host_config = &new_config;
new_config.slot = card_handle;
}
// probe and initialize card
err = sdmmc_card_init(host_config, card);
CHECK_EXECUTE_RESULT(err, "sdmmc_card_init failed");
err = mount_to_vfs_fat_mh(mount_config, card, pdrv, dup_path, &fs);
CHECK_EXECUTE_RESULT(err, "mount_to_vfs failed");
if (out_card != NULL) {
*out_card = card;
}
//For deprecation backward compatibility
if (s_saved_ctx_id == FF_VOLUMES) {
s_saved_ctx_id = 0;
}
ctx = calloc(sizeof(mh_vfs_fat_sd_ctx_t), 1);
if (!ctx) {
CHECK_EXECUTE_RESULT(ESP_ERR_NO_MEM, "no mem");
}
ctx->pdrv = pdrv;
memcpy(&ctx->mount_config, mount_config, sizeof(esp_vfs_fat_mount_config_t));
ctx->card = card;
ctx->base_path = dup_path;
ctx->fs = fs;
ctx_id = s_get_unused_context_id_mh();
assert(ctx_id != FF_VOLUMES);
s_ctx[ctx_id] = ctx;
return ESP_OK;
cleanup:
if (host_inited) {
call_host_deinit_mh(host_config);
}
free(card);
free(dup_path);
return err;
}
static void call_host_deinit_mh(const sdmmc_host_t *host_config)
{
if (host_config->flags & SDMMC_HOST_FLAG_DEINIT_ARG) {
host_config->deinit_p(host_config->slot);
} else {
host_config->deinit();
}
}
static esp_err_t unmount_card_core_mh(const char *base_path, sdmmc_card_t *card)
{
BYTE pdrv = ff_diskio_get_pdrv_card_mh(card);
if (pdrv == 0xff) {
return ESP_ERR_INVALID_ARG;
}
// unmount
char drv[3] = {(char)('0' + pdrv), ':', 0};
f_mount(0, drv, 0);
// release SD driver
ff_diskio_unregister(pdrv);
call_host_deinit_mh(&card->host);
free(card);
esp_err_t err = esp_vfs_fat_unregister_path(base_path);
return err;
}
esp_err_t esp_vfs_fat_sdmmc_unmount_mh(void)
{
esp_err_t err = unmount_card_core_mh(s_ctx[s_saved_ctx_id]->base_path, s_ctx[s_saved_ctx_id]->card);
free(s_ctx[s_saved_ctx_id]);
s_ctx[s_saved_ctx_id] = NULL;
s_saved_ctx_id = FF_VOLUMES;
return err;
}
esp_err_t esp_vfs_fat_sdcard_unmount_mh(const char *base_path, sdmmc_card_t *card)
{
uint32_t id = FF_VOLUMES;
bool found = s_get_context_id_by_card_mh(card, &id);
if (!found) {
return ESP_ERR_INVALID_ARG;
}
free(s_ctx[id]);
s_ctx[id] = NULL;
esp_err_t err = unmount_card_core_mh(base_path, card);
return err;
}
esp_err_t esp_vfs_fat_sdcard_format_mh(const char *base_path, sdmmc_card_t *card)
{
esp_err_t ret = ESP_OK;
if (!card) {
ESP_LOGE(TAG, "card not initialized");
return ESP_ERR_INVALID_STATE;
}
BYTE pdrv = ff_diskio_get_pdrv_card_mh(card);
if (pdrv == 0xff) {
ESP_LOGE(TAG, "card driver not registered");
return ESP_ERR_INVALID_STATE;
}
const size_t workbuf_size = 4096;
void *workbuf = ff_memalloc(workbuf_size);
if (workbuf == NULL) {
return ESP_ERR_NO_MEM;
}
//unmount
char drv[3] = {(char)('0' + pdrv), ':', 0};
f_mount(0, drv, 0);
//format
uint32_t id = FF_VOLUMES;
bool found = s_get_context_id_by_card_mh(card, &id);
assert(found);
size_t alloc_unit_size = esp_vfs_fat_get_allocation_unit_size(card->csd.sector_size, s_ctx[id]->mount_config.allocation_unit_size);
ESP_LOGI(TAG, "Formatting card, allocation unit size=%d", alloc_unit_size);
const MKFS_PARM opt = {(BYTE)FM_ANY, 0, 0, 0, alloc_unit_size};
FRESULT res = f_mkfs(drv, &opt, workbuf, workbuf_size);
free(workbuf);
if (res != FR_OK) {
ret = ESP_FAIL;
ESP_LOGD(TAG, "f_mkfs failed (%d)", res);
}
//mount back
esp_err_t err = s_f_mount_mh(card, s_ctx[id]->fs, drv, pdrv, &s_ctx[id]->mount_config);
if (err != ESP_OK) {
unmount_card_core_mh(base_path, card);
ESP_LOGE(TAG, "failed to format, resources recycled, please mount again");
}
return ret;
}

View File

@@ -0,0 +1,111 @@
/*
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stddef.h>
#include "esp_err.h"
#include "driver/gpio.h"
#include "sdmmc_cmd.h"
#include "driver/sdmmc_types.h"
#include "driver/sdspi_host.h"
#include "ff.h"
#include "esp_vfs_fat.h"
#include "wear_levelling.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Convenience function to get FAT filesystem on SD card registered in VFS
*
* This is an all-in-one function which does the following:
* - initializes SDMMC driver or SPI driver with configuration in host_config
* - initializes SD card with configuration in slot_config
* - mounts FAT partition on SD card using FATFS library, with configuration in mount_config
* - registers FATFS library with VFS, with prefix given by base_prefix variable
*
* This function is intended to make example code more compact.
* For real world applications, developers should implement the logic of
* probing SD card, locating and mounting partition, and registering FATFS in VFS,
* with proper error checking and handling of exceptional conditions.
*
* @note Use this API to mount a card through SDSPI is deprecated. Please call
* `esp_vfs_fat_sdspi_mount()` instead for that case.
*
* @param base_path path where partition should be registered (e.g. "/sdcard")
* @param host_config Pointer to structure describing SDMMC host. When using
* SDMMC peripheral, this structure can be initialized using
* SDMMC_HOST_DEFAULT() macro. When using SPI peripheral,
* this structure can be initialized using SDSPI_HOST_DEFAULT()
* macro.
* @param slot_config Pointer to structure with slot configuration.
* For SDMMC peripheral, pass a pointer to sdmmc_slot_config_t
* structure initialized using SDMMC_SLOT_CONFIG_DEFAULT.
* @param mount_config pointer to structure with extra parameters for mounting FATFS
* @param[out] out_card if not NULL, pointer to the card information structure will be returned via this argument
* @return
* - ESP_OK on success
* - ESP_ERR_INVALID_STATE if esp_vfs_fat_sdmmc_mount was already called
* - ESP_ERR_NO_MEM if memory can not be allocated
* - ESP_FAIL if partition can not be mounted
* - other error codes from SDMMC or SPI drivers, SDMMC protocol, or FATFS drivers
*/
esp_err_t esp_vfs_fat_sdmmc_mount_mh(const char* base_path, const sdmmc_host_t* host_config, const void* slot_config, const esp_vfs_fat_mount_config_t* mount_config, sdmmc_card_t** out_card);
/**
* @brief Convenience function to get FAT filesystem on SD card registered in VFS
*
* This is an all-in-one function which does the following:
* - initializes an SPI Master device based on the SPI Master driver with configuration in
* slot_config, and attach it to an initialized SPI bus.
* - initializes SD card with configuration in host_config_input
* - mounts FAT partition on SD card using FATFS library, with configuration in mount_config
* - registers FATFS library with VFS, with prefix given by base_prefix variable
*
* This function is intended to make example code more compact.
* For real world applications, developers should implement the logic of
* probing SD card, locating and mounting partition, and registering FATFS in VFS,
* with proper error checking and handling of exceptional conditions.
*
* @note This function try to attach the new SD SPI device to the bus specified in host_config.
* Make sure the SPI bus specified in `host_config->slot` have been initialized by
* `spi_bus_initialize()` before.
*
* @param base_path path where partition should be registered (e.g. "/sdcard")
* @param host_config_input Pointer to structure describing SDMMC host. This structure can be
* initialized using SDSPI_HOST_DEFAULT() macro.
* @param slot_config Pointer to structure with slot configuration.
* For SPI peripheral, pass a pointer to sdspi_device_config_t
* structure initialized using SDSPI_DEVICE_CONFIG_DEFAULT().
* @param mount_config pointer to structure with extra parameters for mounting FATFS
* @param[out] out_card If not NULL, pointer to the card information structure will be returned via
* this argument. It is suggested to hold this handle and use it to unmount the card later if
* needed. Otherwise it's not suggested to use more than one card at the same time and unmount one
* of them in your application.
* @return
* - ESP_OK on success
* - ESP_ERR_INVALID_STATE if esp_vfs_fat_sdmmc_mount was already called
* - ESP_ERR_NO_MEM if memory can not be allocated
* - ESP_FAIL if partition can not be mounted
* - other error codes from SDMMC or SPI drivers, SDMMC protocol, or FATFS drivers
*/
esp_err_t esp_vfs_fat_sdspi_mount_mh(const char* base_path, const sdmmc_host_t* host_config_input, const sdspi_device_config_t* slot_config, const esp_vfs_fat_mount_config_t* mount_config, sdmmc_card_t** out_card);
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,153 @@
#include "statusled.h"
#include <sys/types.h>
#include <sys/stat.h>
#include "driver/gpio.h"
#include "ClassLogFile.h"
#include "../../include/defines.h"
// define `gpio_pad_select_gpip` for newer versions of IDF
#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 3, 0))
#include "esp_rom_gpio.h"
#define gpio_pad_select_gpio esp_rom_gpio_pad_select_gpio
#endif
static const char* TAG = "STATUSLED";
TaskHandle_t xHandle_task_StatusLED = NULL;
struct StatusLEDData StatusLEDData = {};
void task_StatusLED(void *pvParameter)
{
//ESP_LOGD(TAG, "task_StatusLED - create");
while (StatusLEDData.bProcessingRequest)
{
//ESP_LOGD(TAG, "task_StatusLED - start");
struct StatusLEDData StatusLEDDataInt = StatusLEDData;
gpio_pad_select_gpio(BLINK_GPIO); // Init the GPIO
gpio_set_direction(BLINK_GPIO, GPIO_MODE_OUTPUT); // Set the GPIO as a push/pull output
gpio_set_level(BLINK_GPIO, 1);// LED off
for (int i=0; i<2; ) // Default: repeat 2 times
{
if (!StatusLEDDataInt.bInfinite)
++i;
for (int j = 0; j < StatusLEDDataInt.iSourceBlinkCnt; ++j)
{
gpio_set_level(BLINK_GPIO, 0);
vTaskDelay(StatusLEDDataInt.iBlinkTime / portTICK_PERIOD_MS);
gpio_set_level(BLINK_GPIO, 1);
vTaskDelay(StatusLEDDataInt.iBlinkTime / portTICK_PERIOD_MS);
}
vTaskDelay(500 / portTICK_PERIOD_MS); // Delay between module code and error code
for (int j = 0; j < StatusLEDDataInt.iCodeBlinkCnt; ++j)
{
gpio_set_level(BLINK_GPIO, 0);
vTaskDelay(StatusLEDDataInt.iBlinkTime / portTICK_PERIOD_MS);
gpio_set_level(BLINK_GPIO, 1);
vTaskDelay(StatusLEDDataInt.iBlinkTime / portTICK_PERIOD_MS);
}
vTaskDelay(1500 / portTICK_PERIOD_MS); // Delay to signal new round
}
StatusLEDData.bProcessingRequest = false;
//ESP_LOGD(TAG, "task_StatusLED - done/wait");
vTaskDelay(10000 / portTICK_PERIOD_MS); // Wait for an upcoming request otherwise continue and delete task to save memory
}
//ESP_LOGD(TAG, "task_StatusLED - delete");
xHandle_task_StatusLED = NULL;
vTaskDelete(NULL); // Delete this task due to no request
}
void StatusLED(StatusLedSource _eSource, int _iCode, bool _bInfinite)
{
//ESP_LOGD(TAG, "StatusLED - start");
if (_eSource == WLAN_CONN) {
StatusLEDData.iSourceBlinkCnt = WLAN_CONN;
StatusLEDData.iCodeBlinkCnt = _iCode;
StatusLEDData.iBlinkTime = 250;
StatusLEDData.bInfinite = _bInfinite;
}
else if (_eSource == WLAN_INIT) {
StatusLEDData.iSourceBlinkCnt = WLAN_INIT;
StatusLEDData.iCodeBlinkCnt = _iCode;
StatusLEDData.iBlinkTime = 250;
StatusLEDData.bInfinite = _bInfinite;
}
else if (_eSource == SDCARD_INIT) {
StatusLEDData.iSourceBlinkCnt = SDCARD_INIT;
StatusLEDData.iCodeBlinkCnt = _iCode;
StatusLEDData.iBlinkTime = 250;
StatusLEDData.bInfinite = _bInfinite;
}
else if (_eSource == SDCARD_CHECK) {
StatusLEDData.iSourceBlinkCnt = SDCARD_CHECK;
StatusLEDData.iCodeBlinkCnt = _iCode;
StatusLEDData.iBlinkTime = 250;
StatusLEDData.bInfinite = _bInfinite;
}
else if (_eSource == CAM_INIT) {
StatusLEDData.iSourceBlinkCnt = CAM_INIT;
StatusLEDData.iCodeBlinkCnt = _iCode;
StatusLEDData.iBlinkTime = 250;
StatusLEDData.bInfinite = _bInfinite;
}
else if (_eSource == PSRAM_INIT) {
StatusLEDData.iSourceBlinkCnt = PSRAM_INIT;
StatusLEDData.iCodeBlinkCnt = _iCode;
StatusLEDData.iBlinkTime = 250;
StatusLEDData.bInfinite = _bInfinite;
}
else if (_eSource == TIME_CHECK) {
StatusLEDData.iSourceBlinkCnt = TIME_CHECK;
StatusLEDData.iCodeBlinkCnt = _iCode;
StatusLEDData.iBlinkTime = 250;
StatusLEDData.bInfinite = _bInfinite;
}
else if (_eSource == AP_OR_OTA) {
StatusLEDData.iSourceBlinkCnt = AP_OR_OTA;
StatusLEDData.iCodeBlinkCnt = _iCode;
StatusLEDData.iBlinkTime = 350;
StatusLEDData.bInfinite = _bInfinite;
}
if (xHandle_task_StatusLED && !StatusLEDData.bProcessingRequest) {
StatusLEDData.bProcessingRequest = true;
BaseType_t xReturned = xTaskAbortDelay(xHandle_task_StatusLED); // Reuse still running status LED task
/*if (xReturned == pdPASS)
ESP_LOGD(TAG, "task_StatusLED - abort waiting delay");*/
}
else if (xHandle_task_StatusLED == NULL) {
StatusLEDData.bProcessingRequest = true;
BaseType_t xReturned = xTaskCreate(&task_StatusLED, "task_StatusLED", 1280, NULL, tskIDLE_PRIORITY+1, &xHandle_task_StatusLED);
if(xReturned != pdPASS)
{
xHandle_task_StatusLED = NULL;
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "task_StatusLED failed to create");
LogFile.WriteHeapInfo("task_StatusLED failed");
}
}
else {
ESP_LOGD(TAG, "task_StatusLED still processing, request skipped"); // Requests with high frequency could be skipped, but LED is only helpful for static states
}
//ESP_LOGD(TAG, "StatusLED - done");
}
void StatusLEDOff(void)
{
if (xHandle_task_StatusLED)
vTaskDelete(xHandle_task_StatusLED); // Delete task for StatusLED to force stop of blinking
gpio_pad_select_gpio(BLINK_GPIO); // Init the GPIO
gpio_set_direction(BLINK_GPIO, GPIO_MODE_OUTPUT); // Set the GPIO as a push/pull output
gpio_set_level(BLINK_GPIO, 1);// LED off
}

View File

@@ -0,0 +1,34 @@
#pragma once
#ifndef STATUSLED_H
#define STATUSLED_H
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
extern TaskHandle_t xHandle_task_StatusLED;
enum StatusLedSource {
WLAN_CONN = 1,
WLAN_INIT = 2,
SDCARD_INIT = 3,
SDCARD_CHECK = 4,
CAM_INIT = 5,
PSRAM_INIT = 6,
TIME_CHECK = 7,
AP_OR_OTA = 8
};
struct StatusLEDData {
int iSourceBlinkCnt = 1;
int iCodeBlinkCnt = 1;
int iBlinkTime = 250;
bool bInfinite = false;
bool bProcessingRequest = false;
};
void StatusLED(StatusLedSource _eSource, int _iCode, bool _bInfinite);
void StatusLEDOff(void);
#endif //STATUSLED_H

View File

@@ -5,12 +5,14 @@
#include <math.h>
#include <algorithm>
#include <esp_log.h>
#include "psram.h"
#include "../../include/defines.h"
static const char* TAG = "c_align_and_cut_image";
CAlignAndCutImage::CAlignAndCutImage(CImageBasis *_org, CImageBasis *_temp)
CAlignAndCutImage::CAlignAndCutImage(std::string _name, CImageBasis *_org, CImageBasis *_temp) : CImageBasis(_name)
{
name = _name;
rgb_image = _org->rgb_image;
channels = _org->channels;
width = _org->width;
@@ -37,7 +39,7 @@ bool CAlignAndCutImage::Align(RefInfo *_temp1, RefInfo *_temp2)
int r0_x, r0_y, r1_x, r1_y;
bool isSimilar1, isSimilar2;
CFindTemplate* ft = new CFindTemplate(rgb_image, channels, width, height, bpp);
CFindTemplate* ft = new CFindTemplate("align", rgb_image, channels, width, height, bpp);
r0_x = _temp1->target_x;
r0_y = _temp1->target_y;
@@ -81,7 +83,7 @@ bool CAlignAndCutImage::Align(RefInfo *_temp1, RefInfo *_temp2)
LogFile.WriteToDedicatedFile("/sdcard/alignment.txt", zw);
#endif*/
CRotateImage rt(this, ImageTMP);
CRotateImage rt("Align", this, ImageTMP);
rt.Translate(dx, dy);
rt.Rotate(d_winkel, _temp1->target_x, _temp1->target_y);
ESP_LOGD(TAG, "Alignment: dx %d - dy %d - rot %f", dx, dy, d_winkel);
@@ -107,7 +109,7 @@ void CAlignAndCutImage::CutAndSave(std::string _template1, int x1, int y1, int d
dy = y2 - y1;
int memsize = dx * dy * channels;
uint8_t* odata = (unsigned char*) GET_MEMORY(memsize);
uint8_t* odata = (unsigned char*) malloc_psram_heap(std::string(TAG) + "->odata", memsize, MALLOC_CAP_SPIRAM);
stbi_uc* p_target;
stbi_uc* p_source;
@@ -186,7 +188,7 @@ CImageBasis* CAlignAndCutImage::CutAndSave(int x1, int y1, int dx, int dy)
dy = y2 - y1;
int memsize = dx * dy * channels;
uint8_t* odata = (unsigned char*)GET_MEMORY(memsize);
uint8_t* odata = (unsigned char*)malloc_psram_heap(std::string(TAG) + "->odata", memsize, MALLOC_CAP_SPIRAM);
stbi_uc* p_target;
stbi_uc* p_source;
@@ -202,7 +204,7 @@ CImageBasis* CAlignAndCutImage::CutAndSave(int x1, int y1, int dx, int dy)
p_target[_channels] = p_source[_channels];
}
CImageBasis* rs = new CImageBasis(odata, channels, dx, dy, bpp);
CImageBasis* rs = new CImageBasis("CutAndSave", odata, channels, dx, dy, bpp);
RGBImageRelease();
rs->SetIndepended();
return rs;

View File

@@ -12,9 +12,9 @@ class CAlignAndCutImage : public CImageBasis
public:
int t0_dx, t0_dy, t1_dx, t1_dy;
CImageBasis *ImageTMP;
CAlignAndCutImage(std::string _image) : CImageBasis(_image) {ImageTMP = NULL;};
CAlignAndCutImage(uint8_t* _rgb_image, int _channels, int _width, int _height, int _bpp) : CImageBasis(_rgb_image, _channels, _width, _height, _bpp) {ImageTMP = NULL;};
CAlignAndCutImage(CImageBasis *_org, CImageBasis *_temp);
CAlignAndCutImage(std::string name, std::string _image) : CImageBasis(name, _image) {ImageTMP = NULL;};
CAlignAndCutImage(std::string name, uint8_t* _rgb_image, int _channels, int _width, int _height, int _bpp) : CImageBasis(name, _rgb_image, _channels, _width, _height, _bpp) {ImageTMP = NULL;};
CAlignAndCutImage(std::string name, CImageBasis *_org, CImageBasis *_temp);
bool Align(RefInfo *_temp1, RefInfo *_temp2);
// void Align(std::string _template1, int x1, int y1, std::string _template2, int x2, int y2, int deltax = 40, int deltay = 40, std::string imageROI = "");

View File

@@ -32,7 +32,7 @@ class CFindTemplate : public CImageBasis
{
public:
int tpl_width, tpl_height, tpl_bpp;
CFindTemplate(uint8_t* _rgb_image, int _channels, int _width, int _height, int _bpp) : CImageBasis(_rgb_image, _channels, _width, _height, _bpp) {};
CFindTemplate(std::string name, uint8_t* _rgb_image, int _channels, int _width, int _height, int _bpp) : CImageBasis(name, _rgb_image, _channels, _width, _height, _bpp) {};
bool FindTemplate(RefInfo *_ref);

View File

@@ -1,5 +1,6 @@
#include "CImageBasis.h"
#include "Helper.h"
#include "psram.h"
#include "ClassLogFile.h"
#include "server_ota.h"
@@ -360,8 +361,9 @@ void CImageBasis::drawCircle(int x1, int y1, int rad, int r, int g, int b, int t
}
CImageBasis::CImageBasis()
CImageBasis::CImageBasis(string _name)
{
name = _name;
externalImage = false;
rgb_image = NULL;
width = 0;
@@ -384,8 +386,9 @@ void CImageBasis::CreateEmptyImage(int _width, int _height, int _channels)
LogFile.WriteHeapInfo("CreateEmptyImage");
#endif
int memsize = width * height * channels;
rgb_image = (unsigned char*)GET_MEMORY(memsize);
memsize = width * height * channels;
rgb_image = (unsigned char*)malloc_psram_heap(std::string(TAG) + "->CImageBasis (" + name + ")", memsize, MALLOC_CAP_SPIRAM);
if (rgb_image == NULL)
{
@@ -435,10 +438,12 @@ void CImageBasis::LoadFromMemory(stbi_uc *_buffer, int len)
{
RGBImageLock();
if (rgb_image)
if (rgb_image != NULL) {
stbi_image_free(rgb_image);
//free_psram_heap(std::string(TAG) + "->rgb_image (LoadFromMemory)", rgb_image);
}
rgb_image = stbi_load_from_memory(_buffer, len, &width, &height, &channels, 3);
rgb_image = stbi_load_from_memory(_buffer, len, &width, &height, &channels, STBI_rgb);
bpp = channels;
ESP_LOGD(TAG, "Image loaded from memory: %d, %d, %d", width, height, channels);
@@ -454,8 +459,47 @@ void CImageBasis::LoadFromMemory(stbi_uc *_buffer, int len)
}
CImageBasis::CImageBasis(CImageBasis *_copyfrom)
void CImageBasis::crop_image(unsigned short cropLeft, unsigned short cropRight, unsigned short cropTop, unsigned short cropBottom)
{
unsigned int maxTopIndex = cropTop * width * channels;
unsigned int minBottomIndex = ((width*height) - (cropBottom * width)) * channels;
unsigned short maxX = width - cropRight; // In pixels
unsigned short newWidth = width - cropLeft - cropRight;
unsigned short newHeight = height - cropTop - cropBottom;
unsigned int writeIndex = 0;
// Loop over all bytes
for (int i = 0; i < width * height * channels; i += channels) {
// Calculate current X, Y pixel position
int x = (i/channels) % width;
// Crop from the top
if (i < maxTopIndex) { continue; }
// Crop from the bottom
if (i > minBottomIndex) { continue; }
// Crop from the left
if (x <= cropLeft) { continue; }
// Crop from the right
if (x > maxX) { continue; }
// If we get here, keep the pixels
for (int c = 0; c < channels; c++) {
rgb_image[writeIndex++] = rgb_image[i+c];
}
}
// Set the new dimensions of the framebuffer for further use.
width = newWidth;
height = newHeight;
}
CImageBasis::CImageBasis(string _name, CImageBasis *_copyfrom)
{
name = _name;
islocked = false;
externalImage = false;
channels = _copyfrom->channels;
@@ -469,8 +513,15 @@ CImageBasis::CImageBasis(CImageBasis *_copyfrom)
LogFile.WriteHeapInfo("CImageBasis_copyfrom - Start");
#endif
int memsize = width * height * channels;
rgb_image = (unsigned char*)GET_MEMORY(memsize);
memsize = width * height * channels;
if (name == "tmpImage") {
rgb_image = (unsigned char*)psram_reserve_shared_tmp_image_memory();
}
else {
rgb_image = (unsigned char*)malloc_psram_heap(std::string(TAG) + "->CImageBasis (" + name + ")", memsize, MALLOC_CAP_SPIRAM);
}
if (rgb_image == NULL)
{
@@ -489,8 +540,9 @@ CImageBasis::CImageBasis(CImageBasis *_copyfrom)
}
CImageBasis::CImageBasis(int _width, int _height, int _channels)
CImageBasis::CImageBasis(string _name, int _width, int _height, int _channels)
{
name = _name;
islocked = false;
externalImage = false;
channels = _channels;
@@ -504,8 +556,9 @@ CImageBasis::CImageBasis(int _width, int _height, int _channels)
LogFile.WriteHeapInfo("CImageBasis_width,height,ch - Start");
#endif
int memsize = width * height * channels;
rgb_image = (unsigned char*)GET_MEMORY(memsize);
memsize = width * height * channels;
rgb_image = (unsigned char*)malloc_psram_heap(std::string(TAG) + "->CImageBasis (" + name + ")", memsize, MALLOC_CAP_SPIRAM);
if (rgb_image == NULL)
{
@@ -523,8 +576,9 @@ CImageBasis::CImageBasis(int _width, int _height, int _channels)
}
CImageBasis::CImageBasis(std::string _image)
CImageBasis::CImageBasis(string _name, std::string _image)
{
name = _name;
islocked = false;
channels = 3;
externalImage = false;
@@ -569,8 +623,9 @@ bool CImageBasis::ImageOkay(){
}
CImageBasis::CImageBasis(uint8_t* _rgb_image, int _channels, int _width, int _height, int _bpp)
CImageBasis::CImageBasis(string _name, uint8_t* _rgb_image, int _channels, int _width, int _height, int _bpp)
{
name = _name;
islocked = false;
rgb_image = _rgb_image;
channels = _channels;
@@ -581,6 +636,20 @@ CImageBasis::CImageBasis(uint8_t* _rgb_image, int _channels, int _width, int _he
}
void CImageBasis::Negative(void)
{
RGBImageLock();
for (int i = 0; i < width * height * channels; i += channels) {
for (int c = 0; c < channels; c++) {
rgb_image[i+c] = 255 - rgb_image[i+c];
}
}
RGBImageRelease();
}
void CImageBasis::Contrast(float _contrast) //input range [-100..100]
{
stbi_uc* p_source;
@@ -607,8 +676,21 @@ CImageBasis::~CImageBasis()
{
RGBImageLock();
if (!externalImage)
stbi_image_free(rgb_image);
if (!externalImage) {
if (name == "tmpImage") { // This image should be placed in the shared part of PSRAM
psram_free_shared_temp_image_memory();
}
else { // All other images are much smaller and can go into the normal PSRAM region
//stbi_image_free(rgb_image);
if (memsize == 0) {
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Not freeing (" + name + " as there was never PSRAM allocated for it)");
}
else {
free_psram_heap(std::string(TAG) + "->CImageBasis (" + name + ", " + to_string(memsize) + ")", rgb_image);
}
}
}
RGBImageRelease();
}
@@ -637,19 +719,19 @@ void CImageBasis::SaveToFile(std::string _imageout)
void CImageBasis::Resize(int _new_dx, int _new_dy)
{
int memsize = _new_dx * _new_dy * channels;
uint8_t* odata = (unsigned char*)GET_MEMORY(memsize);
memsize = _new_dx * _new_dy * channels;
uint8_t* odata = (unsigned char*)malloc_psram_heap(std::string(TAG) + "->odata", memsize, MALLOC_CAP_SPIRAM);
RGBImageLock();
stbir_resize_uint8(rgb_image, width, height, 0, odata, _new_dx, _new_dy, 0, channels);
stbi_image_free(rgb_image);
rgb_image = (unsigned char*)GET_MEMORY(memsize);
rgb_image = (unsigned char*)malloc_psram_heap(std::string(TAG) + "->CImageBasis Resize (" + name + ")", memsize, MALLOC_CAP_SPIRAM);
memCopy(odata, rgb_image, memsize);
width = _new_dx;
height = _new_dy;
stbi_image_free(odata);
free_psram_heap(std::string(TAG) + "->odata", odata);
RGBImageRelease();
}

View File

@@ -11,9 +11,9 @@
#include <math.h>
#include "stb_image.h"
#include "stb_image_write.h"
#include "stb_image_resize.h"
#include "../stb/stb_image.h"
#include "../stb/stb_image_write.h"
#include "../stb/stb_image_resize.h"
#include "esp_heap_caps.h"
@@ -30,6 +30,8 @@ class CImageBasis
protected:
bool externalImage;
std::string filename;
std::string name; // Just used for diagnostics
int memsize = 0;
void memCopy(uint8_t* _source, uint8_t* _target, int _size);
bool isInImage(int x, int y);
@@ -37,7 +39,7 @@ class CImageBasis
bool islocked;
public:
uint8_t* rgb_image;
uint8_t* rgb_image = NULL;
int channels;
int width, height, bpp;
@@ -54,6 +56,7 @@ class CImageBasis
void drawEllipse(int x1, int y1, int radx, int rady, int r, int g, int b, int thickness = 1);
void setPixelColor(int x, int y, int r, int g, int b);
void Negative(void);
void Contrast(float _contrast);
bool ImageOkay();
bool CopyFromMemory(uint8_t* _source, int _size);
@@ -64,14 +67,15 @@ class CImageBasis
void EmptyImage();
CImageBasis();
CImageBasis(std::string _image);
CImageBasis(uint8_t* _rgb_image, int _channels, int _width, int _height, int _bpp);
CImageBasis(int _width, int _height, int _channels);
CImageBasis(CImageBasis *_copyfrom);
CImageBasis(std::string name);
CImageBasis(std::string name, std::string _image);
CImageBasis(std::string name, uint8_t* _rgb_image, int _channels, int _width, int _height, int _bpp);
CImageBasis(std::string name, int _width, int _height, int _channels);
CImageBasis(std::string name, CImageBasis *_copyfrom);
void Resize(int _new_dx, int _new_dy);
void Resize(int _new_dx, int _new_dy, CImageBasis *_target);
void crop_image(unsigned short cropLeft, unsigned short cropRight, unsigned short cropTop, unsigned short cropBottom);
void LoadFromMemory(stbi_uc *_buffer, int len);

View File

@@ -1,349 +1,309 @@
#include "CRotateImage.h"
CRotateImage::CRotateImage(CImageBasis *_org, CImageBasis *_temp, bool _flip)
{
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*)GET_MEMORY(memsize);
}
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)
stbi_image_free(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*)GET_MEMORY(memsize);
}
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)
{
stbi_image_free(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*)GET_MEMORY(memsize);
}
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)
{
stbi_image_free(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*)GET_MEMORY(memsize);
}
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)
{
stbi_image_free(odata);
}
if (ImageTMP)
{
ImageTMP->RGBImageRelease();
}
RGBImageRelease();
}
#include <string>
#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();
}

View File

@@ -1,28 +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 _image, bool _flip = false) : CImageBasis(_image) {ImageTMP = NULL; ImageOrg = NULL; doflip = _flip;};
CRotateImage(uint8_t* _rgb_image, int _channels, int _width, int _height, int _bpp, bool _flip = false) : CImageBasis(_rgb_image, _channels, _width, _height, _bpp) {ImageTMP = NULL; ImageOrg = NULL; doflip = _flip;};
CRotateImage(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

View File

@@ -1,13 +1,28 @@
#include <stdint.h>
#include <string>
#include "psram.h"
#include "../../include/defines.h"
#define USE_SHARED_PSRAM_FOR_STBI
#ifdef USE_SHARED_PSRAM_FOR_STBI
#define STBI_MALLOC(sz) psram_reserve_shared_stbi_memory(sz)
#define STBI_REALLOC(p,newsz) psram_reallocate_shared_stbi_memory(p, newsz)
#define STBI_FREE(p) psram_free_shared_stbi_memory(p)
#else // Use normal PSRAM
#define STBI_MALLOC(sz) malloc_psram_heap("STBI", sz, MALLOC_CAP_SPIRAM)
#define STBI_REALLOC(p,newsz) realloc_psram_heap("STBI", p, newsz, MALLOC_CAP_SPIRAM)
#define STBI_FREE(p) free_psram_heap("STBI", p)
#endif
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"
#include "../stb/stb_image.h"
#define STB_IMAGE_WRITE_IMPLEMENTATION
#include "stb_image_write.h"
#include "../stb/stb_image_write.h"
#define STB_IMAGE_RESIZE_IMPLEMENTATION
#include "stb_image_resize.h"
#include "../stb/stb_image_resize.h"

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

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

View File

@@ -5,6 +5,7 @@
#include <time.h>
#include "ClassLogFile.h"
#include "esp_http_client.h"
#include "time_sntp.h"
#include "../../include/defines.h"
@@ -12,10 +13,90 @@ static const char *TAG = "INFLUXDB";
std::string _influxDBURI;
std::string _influxDBDatabase;
std::string _influxDBMeasurement;
std::string _influxDBUser;
std::string _influxDBPassword;
std::string _influxDB_V2_URI;
std::string _influxDB_V2_Bucket;
std::string _influxDB_V2_Token;
std::string _influxDB_V2_Org;
static esp_err_t http_event_handler(esp_http_client_event_t *evt);
void InfluxDB_V2_Init(std::string _uri, std::string _bucket, std::string _org, std::string _token)
{
_influxDB_V2_URI = _uri;
_influxDB_V2_Bucket = _bucket;
_influxDB_V2_Org = _org;
_influxDB_V2_Token = _token;
}
void InfluxDB_V2_Publish(std::string _measurement, std::string _key, std::string _content, long int _timeUTC)
{
char response_buffer[MAX_HTTP_OUTPUT_BUFFER] = {0};
esp_http_client_config_t http_config = {
.user_agent = "ESP32 Meter reader",
.method = HTTP_METHOD_POST,
.event_handler = http_event_handler,
.buffer_size = MAX_HTTP_OUTPUT_BUFFER,
.user_data = response_buffer
};
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "InfluxDB_V2_Publish - Key: " + _key + ", Content: " + _content + ", timeUTC: " + std::to_string(_timeUTC));
std::string payload;
char nowTimestamp[21];
if (_timeUTC > 0)
{
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Timestamp (UTC): " + std::to_string(_timeUTC));
sprintf(nowTimestamp,"%ld000000000", _timeUTC); // UTC
payload = _measurement + " " + _key + "=" + _content + " " + nowTimestamp;
}
else
{
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "no timestamp given");
payload = _measurement + " " + _key + "=" + _content;
}
payload.shrink_to_fit();
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "sending line to influxdb:" + payload);
std::string apiURI = _influxDB_V2_URI + "/api/v2/write?org=" + _influxDB_V2_Org + "&bucket=" + _influxDB_V2_Bucket;
apiURI.shrink_to_fit();
http_config.url = apiURI.c_str();
ESP_LOGI(TAG, "http_config: %s", http_config.url); // Add mark on log to see when it restarted
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "API URI: " + apiURI);
esp_http_client_handle_t http_client = esp_http_client_init(&http_config);
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "client is initialized");
esp_http_client_set_header(http_client, "Content-Type", "text/plain");
std::string _zw = "Token " + _influxDB_V2_Token;
// LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Tokenheader: %s\n", _zw.c_str());
esp_http_client_set_header(http_client, "Authorization", _zw.c_str());
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "header is set");
ESP_ERROR_CHECK(esp_http_client_set_post_field(http_client, payload.c_str(), payload.length()));
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "post payload is set");
esp_err_t err = ESP_ERROR_CHECK_WITHOUT_ABORT(esp_http_client_perform(http_client));
if( err == ESP_OK ) {
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "HTTP request was performed");
int status_code = esp_http_client_get_status_code(http_client);
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "HTTP status code" + std::to_string(status_code));
} else {
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "HTTP request failed");
}
esp_http_client_cleanup(http_client);
}
static esp_err_t http_event_handler(esp_http_client_event_t *evt)
{
switch(evt->event_id)
@@ -24,7 +105,7 @@ static esp_err_t http_event_handler(esp_http_client_event_t *evt)
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "HTTP Client Error encountered");
break;
case HTTP_EVENT_ON_CONNECTED:
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "HTTP Client Error encountered");
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "HTTP Client connected");
ESP_LOGI(TAG, "HTTP Client Connected");
break;
case HTTP_EVENT_HEADERS_SENT:
@@ -42,11 +123,14 @@ static esp_err_t http_event_handler(esp_http_client_event_t *evt)
case HTTP_EVENT_DISCONNECTED:
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "HTTP Client Disconnected");
break;
case HTTP_EVENT_REDIRECT:
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "HTTP Redirect");
break;
}
return ESP_OK;
}
void InfluxDBPublish(std::string _key, std::string _content, std::string _timestamp) {
void InfluxDBPublish(std::string _measurement, std::string _key, std::string _content, long int _timeUTC) {
char response_buffer[MAX_HTTP_OUTPUT_BUFFER] = {0};
esp_http_client_config_t http_config = {
.user_agent = "ESP32 Meter reader",
@@ -62,37 +146,32 @@ void InfluxDBPublish(std::string _key, std::string _content, std::string _timest
http_config.auth_type = HTTP_AUTH_TYPE_BASIC;
}
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "InfluxDBPublish - Key: " + _key + ", Content: " + _content + ", Timestamp: " + _timestamp);
// Format: #define PREVALUE_TIME_FORMAT_OUTPUT "%Y-%m-%dT%H:%M:%S%z"
struct tm tm;
strptime(_timestamp.c_str(), PREVALUE_TIME_FORMAT_OUTPUT, &tm);
time_t t = mktime(&tm); // t is now your desired time_t
struct tm * ptm;
ptm = gmtime ( &t );
time_t utc = mktime(ptm);
// time_t now;
// time(&now);
std::string payload;
char nowTimestamp[21];
// pad with zeroes to get nanoseconds
// sprintf(nowTimestamp,"%ld000000000", (long) now);
// sprintf(nowTimestamp,"%ld000000000", (long) t); // Localtime
sprintf(nowTimestamp,"%ld000000000", (long) utc); // UTC
// LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Test Time Conversion - t: " + std::to_string(t) + ", utc: " + std::to_string(utc));
// LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Test Time Conversion - now: " + std::to_string(now) + ", timestamp: " + std::to_string(t) + "(correct time not used yet)");
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "InfluxDBPublish - Key: " + _key + ", Content: " + _content + ", timeUTC: " + std::to_string(_timeUTC));
if (_timeUTC > 0)
{
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Timestamp (UTC): " + std::to_string(_timeUTC));
sprintf(nowTimestamp,"%ld000000000", _timeUTC); // UTC
payload = _measurement + " " + _key + "=" + _content + " " + nowTimestamp;
}
else
{
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "no timestamp given");
payload = _measurement + " " + _key + "=" + _content;
}
std::string payload = _influxDBMeasurement + " " + _key + "=" + _content + " " + nowTimestamp;
payload.shrink_to_fit();
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "sending line to influxdb:" + payload);
// use the default retention policy of the database
std::string apiURI = _influxDBURI + "/api/v2/write?bucket=" + _influxDBDatabase + "/";
// use the default retention policy of the bucket
std::string apiURI = _influxDBURI + "/write?db=" + _influxDBDatabase;
// std::string apiURI = _influxDBURI + "/api/v2/write?bucket=" + _influxDBDatabase + "/";
apiURI.shrink_to_fit();
http_config.url = apiURI.c_str();
@@ -120,10 +199,9 @@ void InfluxDBPublish(std::string _key, std::string _content, std::string _timest
}
void InfluxDBInit(std::string _uri, std::string _database, std::string _measurement, std::string _user, std::string _password){
void InfluxDBInit(std::string _uri, std::string _database, std::string _user, std::string _password){
_influxDBURI = _uri;
_influxDBDatabase = _database;
_influxDBMeasurement = _measurement;
_influxDBUser = _user;
_influxDBPassword = _password;

View File

@@ -8,10 +8,17 @@
#include <map>
#include <functional>
void InfluxDBInit(std::string _influxDBURI, std::string _database, std::string _measurement, std::string _user, std::string _password);
void InfluxDBdestroy();
// Interface to InfluxDB v1.x
void InfluxDBInit(std::string _influxDBURI, std::string _database, std::string _user, std::string _password);
void InfluxDBPublish(std::string _measurement, std::string _key, std::string _content, long int _timeUTC);
void InfluxDBPublish(std::string _key, std::string _content, std::string _timestamp);
// Interface to InfluxDB v2.x
void InfluxDB_V2_Init(std::string _uri, std::string _bucket, std::string _org, std::string _token);
void InfluxDB_V2_Publish(std::string _measurement, std::string _key, std::string _content, long int _timeUTC);
void InfluxDBdestroy();
#endif //INTERFACE_INFLUXDB_H
#endif //ENABLE_INFLUXDB

Some files were not shown because too many files have changed in this diff Show More