mirror of
https://github.com/jomjol/AI-on-the-edge-device.git
synced 2025-12-08 04:26:58 +03:00
Compare commits
1 Commits
16.0.0-RC2
...
v15.6.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8d6f731d5a |
@@ -115,9 +115,9 @@
|
||||
labeled:
|
||||
issue:
|
||||
body: |
|
||||
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.
|
||||
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.
|
||||
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 [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 [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.
|
||||
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/).
|
||||
@@ -150,6 +150,7 @@ jobs:
|
||||
path: ./update/*
|
||||
|
||||
|
||||
|
||||
#########################################################################################
|
||||
## Pack for Remote Setup
|
||||
#########################################################################################
|
||||
@@ -331,11 +332,13 @@ jobs:
|
||||
|
||||
# extract the version used in next step
|
||||
- id: get_version
|
||||
uses: dhkatz/get-version-action@v3.0.0
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
uses: Simply007/get-version-action@v2
|
||||
|
||||
# # 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 }}
|
||||
@@ -343,6 +346,7 @@ jobs:
|
||||
# # 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
|
||||
@@ -350,11 +354,12 @@ jobs:
|
||||
# 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@v2.0.8
|
||||
uses: softprops/action-gh-release@v1
|
||||
# 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 }}
|
||||
@@ -363,6 +368,7 @@ 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
|
||||
@@ -376,7 +382,6 @@ jobs:
|
||||
#########################################################################################
|
||||
# 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
|
||||
@@ -405,7 +410,7 @@ jobs:
|
||||
run: |
|
||||
echo "Updating Web installer to use firmware from ${{ steps.last_release.outputs.tag_name }}..."
|
||||
rm -f docs/binary/firmware.bin
|
||||
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
|
||||
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
|
||||
echo "Updating index and manifest file..."
|
||||
@@ -60,3 +60,4 @@ jobs:
|
||||
- name: Deploy to GitHub Pages
|
||||
id: deployment
|
||||
uses: actions/deploy-pages@v1
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Reply Bot
|
||||
# It uses the configuration in .github/label-commenter-config.yaml
|
||||
# It uses the configuration in .github/label-commenter-config.yml
|
||||
# See https://github.com/peaceiris/actions-label-commenter
|
||||
|
||||
name: Reply-Bot
|
||||
@@ -20,11 +20,12 @@ jobs:
|
||||
comment:
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
|
||||
####################################################################
|
||||
## Remove labels again (issues only)
|
||||
## Make sure to also add the reply message to .github/label-commenter-config.yaml!
|
||||
## Make sure to also add the reply message to .github/label-commenter-config.yml!
|
||||
## This currently seems no longer to work due to changes on the actions-cool/issues-helper!
|
||||
####################################################################
|
||||
# - name: Remove 'Logfile' label again (issues only)
|
||||
@@ -75,5 +76,4 @@ jobs:
|
||||
- name: Write Response
|
||||
uses: peaceiris/actions-label-commenter@c2d00660c86f2b9ed0fb35b372c451558eba85b3
|
||||
with:
|
||||
github_token: "${{ secrets.GITHUB_TOKEN }}"
|
||||
config_file: .github/label-commenter-config.yaml
|
||||
repo-token: "${{ secrets.GITHUB_TOKEN }}"
|
||||
115
Changelog.md
115
Changelog.md
@@ -1,68 +1,3 @@
|
||||
## [16.0.0-RC2] - 2024-10-04
|
||||
|
||||
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)
|
||||
@@ -79,7 +14,7 @@ For a full list of changes see [Full list of changes](https://github.com/jomjol/
|
||||
|
||||
- Update PlattformIO to v6.5.0, which means esp-idf to v5.1
|
||||
- Enhance busy notification
|
||||
- Implemented late analog / digit transition
|
||||
- Implemented late analog / digital transition
|
||||
|
||||
#### Fixed
|
||||
|
||||
@@ -108,8 +43,6 @@ For a full list of changes see [Full list of changes](https://github.com/jomjol/
|
||||
- dig-class11_1700_s2.tflite
|
||||
- ana-cont_1208_s2_q.tflite
|
||||
|
||||
- Added config entries for MQTT TLS
|
||||
|
||||
|
||||
#### Fixed
|
||||
|
||||
@@ -239,7 +172,7 @@ For a full list of changes see [Full list of changes](https://github.com/jomjol/
|
||||
: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`
|
||||
- Digital 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
|
||||
@@ -375,7 +308,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-digit`, `cnn-analog`
|
||||
- Content: `time`, `name-of-number`, `raw-value`, `return-value`, `pre-value`, `change-rate`, `change-absolute`, `error-text`, `cnn-digital`, `cnn-analog`
|
||||
- Show graph of values direct in the user interface (thanks to [@rdmueller](https://github.com/rdmueller))
|
||||
|
||||
- Using new data logging (see above)
|
||||
@@ -393,10 +326,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 `AnalogDigTransitionStart`. 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 `AnalogDigitalTransitionStart`. 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` (Digitization Status), Timezone to MQTT topic `timestamp`.#
|
||||
- NEW v13.0.2: MQTT: Added MQTT topic `status` (Digitalization 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
|
||||
@@ -521,7 +454,7 @@ Intermediate Digits
|
||||
|
||||
- Updated analog neural network file (`ana-cont_11.3.0_s2.tflite` - default, `ana-class100_0120_s1_q.tflite`)
|
||||
|
||||
- Updated digit neural network file (`dig-cont_0570_s3.tflite` - default, `dig-class100_0120_s2_q.tflite`)
|
||||
- Updated digital 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)**)
|
||||
|
||||
@@ -533,8 +466,8 @@ Intermediate Digits
|
||||
|
||||
Intermediate Digits
|
||||
|
||||
- New and improved consistency check (especially with analog and digit counters mixed)
|
||||
- Bug Fix: digit counter algorithm
|
||||
- New and improved consistency check (especially with analog and digital counters mixed)
|
||||
- Bug Fix: digital counter algorithm
|
||||
|
||||
## [11.0.1](https://github.com/jomjol/AI-on-the-edge-device/releases/tag/v11.0.1), 2022-08-18
|
||||
|
||||
@@ -574,7 +507,7 @@ Stability Increase
|
||||
|
||||
- `config.ini`: removal of modelsize (readout from tflite)
|
||||
|
||||
- Updated analog neural network file (`ana1000s2.tflite`) & digit neural network file (`dig1400s2q.tflite`)
|
||||
- Updated analog neural network file (`ana1000s2.tflite`) & digital neural network file (`dig1400s2q.tflite`)
|
||||
|
||||
- TFMicro/Lite: Update (espressif Version 20220716)
|
||||
|
||||
@@ -610,7 +543,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 digit neural network file (`dig-s1-q-20220102.tflite`)
|
||||
- Updated digital neural network file (`dig-s1-q-20220102.tflite`)
|
||||
- Updated build environment to `Espressif 3.5.0`
|
||||
|
||||
## [10.3.0] - (2022-01-29)
|
||||
@@ -676,7 +609,7 @@ Stability Increase
|
||||
|
||||
- Update analog neural network (ana-s3-q-20220105.tflite)
|
||||
|
||||
- Update digit neural network (dig-s1-q-20220102.tflite)
|
||||
- Update digital neural network (dig-s1-q-20220102.tflite)
|
||||
|
||||
- Increased web-server buffers
|
||||
|
||||
@@ -713,7 +646,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 digit CNN to v13.3.0 (added new images)
|
||||
- Upgrade digital CNN to v13.3.0 (added new images)
|
||||
- html: support of different ports
|
||||
|
||||
## [9.1.1] - External Illumination (2021-11-16)
|
||||
@@ -738,7 +671,7 @@ External Illumination
|
||||
|
||||
### Changed
|
||||
|
||||
- Upgrade digit CNN to v13.1.0 (added new images)
|
||||
- Upgrade digital 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)
|
||||
@@ -768,7 +701,7 @@ External Illumination
|
||||
|
||||
### Changed
|
||||
|
||||
- Upgrade digit CNN to v12.1.0 (added new images)
|
||||
- Upgrade digital CNN to v12.1.0 (added new images)
|
||||
- Dedicated NaN handling, internal refactoring (CNN-Handling)
|
||||
- HTML: confirmation after config.ini update
|
||||
- Bug fixing
|
||||
@@ -790,7 +723,7 @@ External Illumination
|
||||
- GPIO: using the general mqtt main topic for GPIO
|
||||
|
||||
|
||||
- Upgrade digit CNN to v12.0.0 (added new images)
|
||||
- Upgrade digital 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
|
||||
|
||||
@@ -826,7 +759,7 @@ External Illumination
|
||||
|
||||
- Update wlan handling to esp-idf 4.1
|
||||
|
||||
- Upgrade digit CNN to v8.7.0 (added new images)
|
||||
- Upgrade digital CNN to v8.7.0 (added new images)
|
||||
|
||||
- Bug fix: MQTT, WLAN, LED-Controll, GPIO usage, fixed IP, calculation flow rate
|
||||
|
||||
@@ -837,7 +770,7 @@ External Illumination
|
||||
- NEW: 7.0.1: bug fix wlan password with "="
|
||||
|
||||
|
||||
- Upgrade digit CNN to v8.5.0 (added new images)
|
||||
- Upgrade digital CNN to v8.5.0 (added new images)
|
||||
|
||||
- New MQTT topics: flow rate (units/minute), time stamp (last correct read readout)
|
||||
|
||||
@@ -854,7 +787,7 @@ External Illumination
|
||||
|
||||
- NEW 6.7.1: Improved stability of camera (back to v6.6.1) - remove black strips and areas
|
||||
|
||||
- Upgrade digit CNN to v8.3.0 (added new type of digits)
|
||||
- Upgrade digital CNN to v8.3.0 (added new type of digits)
|
||||
|
||||
- Internal update: TFlite (v2.5), esp32cam, startup sequence
|
||||
|
||||
@@ -875,7 +808,7 @@ External Illumination
|
||||
|
||||
### Changed
|
||||
|
||||
- Upgrade digit CNN to v8.2.0 (added new type of digits)
|
||||
- Upgrade digital CNN to v8.2.0 (added new type of digits)
|
||||
|
||||
|
||||
- Supporting alignment structures in ROI definition
|
||||
@@ -911,7 +844,7 @@ External Illumination
|
||||
|
||||
- Determination of fixed illumination settings during startup - speed up of 5s in each run
|
||||
|
||||
- Update digit CNN to v8.1.1 (additional digit images trained)
|
||||
- Update digital CNN to v8.1.1 (additional digital images trained)
|
||||
|
||||
- Extended error message in MQTT error message
|
||||
|
||||
@@ -923,7 +856,7 @@ External Illumination
|
||||
|
||||
### Changed
|
||||
|
||||
- Disabling of analog / digit counters in configuration
|
||||
- Disabling of analog / digital counters in configuration
|
||||
|
||||
|
||||
- Improved Alignment Algorithm (`AlignmentAlgo` = `Default`, `Accurate` , `Fast`)
|
||||
@@ -943,7 +876,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 digit CNN to v7.2.1 (additional digit images trained)
|
||||
- Update digital CNN to v7.2.1 (additional digital 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)
|
||||
@@ -977,7 +910,7 @@ External Illumination
|
||||
|
||||
- standardized access to current logfile via `http://IP-ADRESS/logfileact`
|
||||
|
||||
- Update digit CNN to v7.2.0, analog CNN to 6.3.0
|
||||
- Update digital CNN to v7.2.0, analog CNN to 6.3.0
|
||||
|
||||
- Bug fixing: truncation error, CheckDigitConsistency & PreValue implementation
|
||||
|
||||
@@ -996,7 +929,7 @@ External Illumination
|
||||
|
||||
### Changed
|
||||
|
||||
- Update digit CNN to v6.5.0 and HTML (Info to hostname, IP, ssid)
|
||||
- Update digital CNN to v6.5.0 and HTML (Info to hostname, IP, ssid)
|
||||
|
||||
- New implementation of "checkDigitConsistency" also for digits
|
||||
|
||||
|
||||
@@ -65,7 +65,7 @@ The latest available version can be found on the [Releases page](https://github.
|
||||
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:
|
||||
- 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:
|
||||
- The prefered 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:
|
||||

|
||||
- Flash Tool from Espressif
|
||||
- ESPtool (command-line tool)
|
||||
|
||||
Submodule code/components/esp-tflite-micro updated: 0032f1734e...13f26b8294
File diff suppressed because it is too large
Load Diff
@@ -15,99 +15,49 @@
|
||||
#include "CImageBasis.h"
|
||||
#include "../../include/defines.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16_t CamSensor_id;
|
||||
class CCamera {
|
||||
protected:
|
||||
int ActualQuality;
|
||||
framesize_t ActualResolution;
|
||||
int brightness, contrast, saturation;
|
||||
bool isFixedExposure;
|
||||
int waitbeforepicture_org;
|
||||
int led_intensity = 4095;
|
||||
|
||||
framesize_t ImageFrameSize = FRAMESIZE_VGA; // 0 - 10
|
||||
gainceiling_t ImageGainceiling; // Image gain (GAINCEILING_x2, x4, x8, x16, x32, x64 or x128)
|
||||
void ledc_init(void);
|
||||
bool CameraInitSuccessful = false;
|
||||
bool demoMode = false;
|
||||
|
||||
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)
|
||||
bool loadNextDemoImage(camera_fb_t *fb);
|
||||
long GetFileSize(std::string filename);
|
||||
|
||||
int ImageDenoiseLevel; // The OV2640 does not support it, OV3660 and OV5640 (0 to 8)
|
||||
public:
|
||||
int image_height, image_width;
|
||||
|
||||
int ImageWidth;
|
||||
int ImageHeight;
|
||||
CCamera();
|
||||
esp_err_t InitCam();
|
||||
|
||||
int ImageLedIntensity;
|
||||
void LightOnOff(bool status);
|
||||
void LEDOnOff(bool status);
|
||||
esp_err_t CaptureToHTTP(httpd_req_t *req, int delay = 0);
|
||||
esp_err_t CaptureToStream(httpd_req_t *req, bool FlashlightOn);
|
||||
void SetQualitySize(int qual, framesize_t resol);
|
||||
bool 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);
|
||||
|
||||
bool ImageZoomEnabled;
|
||||
int ImageZoomOffsetX;
|
||||
int ImageZoomOffsetY;
|
||||
int ImageZoomSize;
|
||||
|
||||
int WaitBeforePicture;
|
||||
bool isImageSize;
|
||||
framesize_t TextToFramesize(const char * text);
|
||||
|
||||
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);
|
||||
esp_err_t CaptureToFile(std::string nm, int delay = 0);
|
||||
esp_err_t CaptureToBasisImage(CImageBasis *_Image, int delay = 0);
|
||||
};
|
||||
|
||||
|
||||
extern CCamera Camera;
|
||||
|
||||
#endif
|
||||
@@ -1,152 +0,0 @@
|
||||
#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;
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
#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
|
||||
@@ -5,7 +5,6 @@
|
||||
|
||||
#include "esp_camera.h"
|
||||
#include "ClassControllCamera.h"
|
||||
#include "MainFlowControl.h"
|
||||
|
||||
#include "ClassLogFile.h"
|
||||
#include "esp_log.h"
|
||||
@@ -14,39 +13,37 @@
|
||||
|
||||
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);
|
||||
|
||||
// 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
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
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())
|
||||
{
|
||||
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
|
||||
@@ -55,24 +52,25 @@ esp_err_t handler_lightOn(httpd_req_t *req)
|
||||
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())
|
||||
{
|
||||
Camera.LightOnOff(false);
|
||||
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
|
||||
@@ -81,118 +79,115 @@ esp_err_t handler_lightOff(httpd_req_t *req)
|
||||
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 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;
|
||||
}
|
||||
int quality;
|
||||
framesize_t res;
|
||||
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "Size: %d, Quality: %d", CCstatus.ImageFrameSize, CCstatus.ImageQuality);
|
||||
#endif
|
||||
Camera.GetCameraParameter(req, quality, res);
|
||||
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "Size: %d, Quality: %d", res, quality);
|
||||
#endif
|
||||
|
||||
Camera.SetQualitySize(quality, res);
|
||||
|
||||
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
|
||||
#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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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", CCstatus.ImageFrameSize, CCstatus.ImageQuality);
|
||||
#endif
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "Size: %d, Quality: %d", res, quality);
|
||||
#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);
|
||||
|
||||
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())
|
||||
{
|
||||
@@ -202,61 +197,52 @@ 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");
|
||||
}
|
||||
|
||||
// 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
|
||||
Camera.GetCameraParameter(req, quality, res);
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
ESP_LOGD(TAG, "Size: %d, Quality: %d", res, quality);
|
||||
#endif
|
||||
Camera.SetQualitySize(quality, res);
|
||||
|
||||
esp_err_t result;
|
||||
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;
|
||||
}
|
||||
@@ -267,37 +253,38 @@ esp_err_t handler_capture_save_to_file(httpd_req_t *req)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void register_server_camera_uri(httpd_handle_t server)
|
||||
{
|
||||
#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";
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
camuri.uri = "/save";
|
||||
camuri.handler = handler_capture_save_to_file;
|
||||
camuri.user_ctx = NULL;
|
||||
httpd_register_uri_handler(server, &camuri);
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
//#include "ClassControllCamera.h"
|
||||
|
||||
void register_server_camera_uri(httpd_handle_t server);
|
||||
|
||||
void PowerResetCamera();
|
||||
|
||||
#endif
|
||||
@@ -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 simplicity we therefore use the release files as suggested in the readme.
|
||||
For sumplicity we therefore use the release files as suggested in the readme.
|
||||
Additionally we added the CMakeLists.txt and this readme.
|
||||
@@ -2,6 +2,6 @@ FILE(GLOB_RECURSE app_sources ${CMAKE_CURRENT_SOURCE_DIR}/*.*)
|
||||
|
||||
idf_component_register(SRCS ${app_sources}
|
||||
INCLUDE_DIRS "."
|
||||
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)
|
||||
REQUIRES esp_timer esp_wifi jomjol_tfliteclass jomjol_helper jomjol_controlcamera jomjol_mqtt jomjol_influxdb jomjol_fileserver_ota jomjol_image_proc jomjol_wlan)
|
||||
|
||||
|
||||
|
||||
@@ -67,6 +67,11 @@ string ClassFlow::getHTMLSingleStep(string host){
|
||||
return "";
|
||||
}
|
||||
|
||||
string ClassFlow::getReadout()
|
||||
{
|
||||
return string();
|
||||
}
|
||||
|
||||
std::string ClassFlow::GetParameterName(std::string _input)
|
||||
{
|
||||
string _param;
|
||||
|
||||
@@ -46,6 +46,7 @@ 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";};
|
||||
|
||||
};
|
||||
|
||||
@@ -6,189 +6,193 @@
|
||||
#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;
|
||||
initalrotate = 0;
|
||||
anz_ref = 0;
|
||||
initialmirror = false;
|
||||
use_antialiasing = false;
|
||||
initialflip = false;
|
||||
SaveAllFiles = false;
|
||||
namerawimage = "/sdcard/img_tmp/raw.jpg";
|
||||
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
|
||||
#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)
|
||||
|
||||
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;
|
||||
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) {
|
||||
if (!ImageBasis) // the function take pictures does not exist --> must be created first ONLY FOR TEST PURPOSES
|
||||
{
|
||||
ESP_LOGD(TAG, "CImageBasis had to be created");
|
||||
ImageBasis = new CImageBasis("ImageBasis", namerawimage);
|
||||
}
|
||||
}
|
||||
|
||||
bool ClassFlowAlignment::ReadParameter(FILE *pfile, string &aktparamgraph)
|
||||
|
||||
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
|
||||
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)) {
|
||||
if (!this->GetNextParagraph(pfile, aktparamgraph))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (aktparamgraph.compare("[Alignment]") != 0)
|
||||
{
|
||||
// Paragraph does not fit Alignment
|
||||
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]);
|
||||
if ((toUpper(splitted[0]) == "FLIPIMAGESIZE") && (splitted.size() > 1))
|
||||
{
|
||||
if (toUpper(splitted[1]) == "TRUE")
|
||||
initialflip = true;
|
||||
}
|
||||
else if (((toUpper(splitted[0]) == "initialrotate") || (toUpper(splitted[0]) == "INITIALROTATE")) && (splitted.size() > 1)) {
|
||||
if (isStringNumeric(splitted[1])) {
|
||||
this->initialrotate = std::stod(splitted[1]);
|
||||
}
|
||||
if ((toUpper(splitted[0]) == "INITIALMIRROR") && (splitted.size() > 1))
|
||||
{
|
||||
if (toUpper(splitted[1]) == "TRUE")
|
||||
initialmirror = true;
|
||||
}
|
||||
else if ((toUpper(splitted[0]) == "SEARCHFIELDX") && (splitted.size() > 1)) {
|
||||
if (isStringNumeric(splitted[1])) {
|
||||
suchex = std::stod(splitted[1]);
|
||||
}
|
||||
if (((toUpper(splitted[0]) == "INITALROTATE") || (toUpper(splitted[0]) == "INITIALROTATE")) && (splitted.size() > 1))
|
||||
{
|
||||
this->initalrotate = std::stod(splitted[1]);
|
||||
}
|
||||
else if ((toUpper(splitted[0]) == "SEARCHFIELDY") && (splitted.size() > 1)) {
|
||||
if (isStringNumeric(splitted[1])) {
|
||||
suchey = std::stod(splitted[1]);
|
||||
}
|
||||
if ((toUpper(splitted[0]) == "SEARCHFIELDX") && (splitted.size() > 1))
|
||||
{
|
||||
suchex = std::stod(splitted[1]);
|
||||
}
|
||||
else if ((toUpper(splitted[0]) == "ANTIALIASING") && (splitted.size() > 1)) {
|
||||
use_antialiasing = alphanumericToBoolean(splitted[1]);
|
||||
if ((toUpper(splitted[0]) == "SEARCHFIELDY") && (splitted.size() > 1))
|
||||
{
|
||||
suchey = std::stod(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++;
|
||||
}
|
||||
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++;
|
||||
}
|
||||
|
||||
else if ((toUpper(splitted[0]) == "SAVEALLFILES") && (splitted.size() > 1)) {
|
||||
SaveAllFiles = alphanumericToBoolean(splitted[1]);
|
||||
if ((toUpper(splitted[0]) == "SAVEALLFILES") && (splitted.size() > 1))
|
||||
{
|
||||
if (toUpper(splitted[1]) == "TRUE")
|
||||
SaveAllFiles = true;
|
||||
}
|
||||
else if ((toUpper(splitted[0]) == "ALIGNMENTALGO") && (splitted.size() > 1)) {
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
std::string zw2 = "Alignment mode selected: " + splitted[1];
|
||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, zw2);
|
||||
#endif
|
||||
if (toUpper(splitted[1]) == "HIGHACCURACY") {
|
||||
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") {
|
||||
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
|
||||
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) {
|
||||
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
|
||||
#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();
|
||||
//no align algo if set to 3 = off => no draw ref //add disable aligment algo |01.2023
|
||||
if(References[0].alignment_algo != 3){
|
||||
LoadReferenceAlignmentValues();
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
|
||||
string ClassFlowAlignment::getHTMLSingleStep(string host)
|
||||
{
|
||||
string result;
|
||||
|
||||
result = "<p>Rotated Image: </p> <p><img src=\"" + host + "/img_tmp/rot.jpg\"></p>\n";
|
||||
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");
|
||||
#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 (AlgROI)
|
||||
{
|
||||
ImageBasis->writeToMemoryAsJPG((ImageData*)AlgROI, 90);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!ImageTMP) {
|
||||
if (!ImageTMP)
|
||||
{
|
||||
ImageTMP = new CImageBasis("tmpImage", ImageBasis); // Make sure the name does not get change, it is relevant for the PSRAM allocation!
|
||||
|
||||
if (!ImageTMP) {
|
||||
if (!ImageTMP)
|
||||
{
|
||||
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Can't allocate tmpImage -> Exec this round aborted!");
|
||||
LogFile.WriteHeapInfo("ClassFlowAlignment-doFlow");
|
||||
return false;
|
||||
@@ -197,16 +201,16 @@ bool ClassFlowAlignment::doFlow(string time)
|
||||
|
||||
delete AlignAndCutImage;
|
||||
AlignAndCutImage = new CAlignAndCutImage("AlignAndCutImage", ImageBasis, ImageTMP);
|
||||
|
||||
if (!AlignAndCutImage) {
|
||||
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) {
|
||||
if (initialflip)
|
||||
{
|
||||
int _zw = ImageBasis->height;
|
||||
ImageBasis->height = ImageBasis->width;
|
||||
ImageBasis->width = _zw;
|
||||
@@ -216,40 +220,50 @@ bool ClassFlowAlignment::doFlow(string time)
|
||||
ImageTMP->height = _zw;
|
||||
}
|
||||
|
||||
if ((initialrotate != 0) || initialflip) {
|
||||
if (use_antialiasing) {
|
||||
rt.RotateAntiAliasing(initialrotate);
|
||||
}
|
||||
else {
|
||||
rt.Rotate(initialrotate);
|
||||
}
|
||||
if (initialmirror)
|
||||
{
|
||||
ESP_LOGD(TAG, "do mirror");
|
||||
rt.Mirror();
|
||||
|
||||
if (SaveAllFiles) {
|
||||
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"));
|
||||
}
|
||||
}
|
||||
|
||||
// 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 algo if set to 3 = off //add disable aligment algo |01.2023
|
||||
if(References[0].alignment_algo != 3){
|
||||
if (!AlignAndCutImage->Align(&References[0], &References[1]))
|
||||
{
|
||||
SaveReferenceAlignmentValues();
|
||||
}
|
||||
}// no align
|
||||
|
||||
|
||||
#ifdef ALGROI_LOAD_FROM_MEM_AS_JPG
|
||||
if (AlgROI) {
|
||||
//no align algo if set to 3 = off => no draw ref //add disable aligment algo |01.2023
|
||||
if(References[0].alignment_algo != 3){
|
||||
DrawRef(ImageTMP);
|
||||
}
|
||||
flowctrl.DigitalDrawROI(ImageTMP);
|
||||
flowctrl.AnalogDrawROI(ImageTMP);
|
||||
ImageTMP->writeToMemoryAsJPG((ImageData*)AlgROI, 90);
|
||||
}
|
||||
} // no align
|
||||
#endif
|
||||
|
||||
#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) {
|
||||
if (SaveAllFiles)
|
||||
{
|
||||
AlignAndCutImage->SaveToFile(FormatFileName("/sdcard/img_tmp/alg.jpg"));
|
||||
ImageTMP->SaveToFile(FormatFileName("/sdcard/img_tmp/alg_roi.jpg"));
|
||||
}
|
||||
@@ -258,24 +272,26 @@ bool ClassFlowAlignment::doFlow(string time)
|
||||
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();
|
||||
//no align algo if set to 3 = off => no draw ref //add disable aligment algo |01.2023
|
||||
if(References[0].alignment_algo != 3){
|
||||
LoadReferenceAlignmentValues();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void ClassFlowAlignment::SaveReferenceAlignmentValues()
|
||||
{
|
||||
FILE *pFile;
|
||||
FILE* pFile;
|
||||
std::string zwtime, zwvalue;
|
||||
|
||||
pFile = fopen(FileStoreRefAlignment.c_str(), "w");
|
||||
|
||||
if (strlen(zwtime.c_str()) == 0) {
|
||||
if (strlen(zwtime.c_str()) == 0)
|
||||
{
|
||||
time_t rawtime;
|
||||
struct tm *timeinfo;
|
||||
struct tm* timeinfo;
|
||||
char buffer[80];
|
||||
|
||||
time(&rawtime);
|
||||
@@ -289,40 +305,40 @@ void ClassFlowAlignment::SaveReferenceAlignmentValues()
|
||||
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);
|
||||
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);
|
||||
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;
|
||||
FILE* pFile;
|
||||
char zw[1024];
|
||||
string zwvalue;
|
||||
std::vector<string> splitted;
|
||||
|
||||
pFile = fopen(FileStoreRefAlignment.c_str(), "r");
|
||||
|
||||
if (pFile == NULL) {
|
||||
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) {
|
||||
if (splitted.size() < 6)
|
||||
{
|
||||
fclose(pFile);
|
||||
return false;
|
||||
}
|
||||
@@ -336,8 +352,8 @@ bool ClassFlowAlignment::LoadReferenceAlignmentValues(void)
|
||||
|
||||
fgets(zw, 1024, pFile);
|
||||
splitted = ZerlegeZeile(std::string(zw));
|
||||
|
||||
if (splitted.size() < 6) {
|
||||
if (splitted.size() < 6)
|
||||
{
|
||||
fclose(pFile);
|
||||
return false;
|
||||
}
|
||||
@@ -351,6 +367,7 @@ bool ClassFlowAlignment::LoadReferenceAlignmentValues(void)
|
||||
|
||||
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);
|
||||
@@ -365,9 +382,11 @@ bool ClassFlowAlignment::LoadReferenceAlignmentValues(void)
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void ClassFlowAlignment::DrawRef(CImageBasis *_zw)
|
||||
{
|
||||
if (_zw->ImageOkay()) {
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -12,10 +12,12 @@
|
||||
|
||||
using namespace std;
|
||||
|
||||
class ClassFlowAlignment : public ClassFlow
|
||||
class ClassFlowAlignment :
|
||||
public ClassFlow
|
||||
{
|
||||
protected:
|
||||
float initialrotate;
|
||||
float initalrotate;
|
||||
bool initialmirror;
|
||||
bool initialflip;
|
||||
bool use_antialiasing;
|
||||
RefInfo References[2];
|
||||
@@ -32,20 +34,21 @@ protected:
|
||||
|
||||
public:
|
||||
CImageBasis *ImageBasis, *ImageTMP;
|
||||
#ifdef ALGROI_LOAD_FROM_MEM_AS_JPG
|
||||
#ifdef ALGROI_LOAD_FROM_MEM_AS_JPG
|
||||
ImageData *AlgROI;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
ClassFlowAlignment(std::vector<ClassFlow *> *lfc);
|
||||
ClassFlowAlignment(std::vector<ClassFlow*>* lfc);
|
||||
|
||||
CAlignAndCutImage *GetAlignAndCutImage() { return AlignAndCutImage; };
|
||||
CAlignAndCutImage* GetAlignAndCutImage(){return AlignAndCutImage;};
|
||||
|
||||
void DrawRef(CImageBasis *_zw);
|
||||
|
||||
bool ReadParameter(FILE *pfile, string &aktparamgraph);
|
||||
bool ReadParameter(FILE* pfile, string& aktparamgraph);
|
||||
bool doFlow(string time);
|
||||
string getHTMLSingleStep(string host);
|
||||
string name() { return "ClassFlowAlignment"; };
|
||||
string name(){return "ClassFlowAlignment";};
|
||||
};
|
||||
|
||||
#endif // CLASSFLOWALIGNMENT_H
|
||||
|
||||
#endif //CLASSFLOWALIGNMENT_H
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -11,10 +11,10 @@ enum t_CNNType {
|
||||
AutoDetect,
|
||||
Analogue,
|
||||
Analogue100,
|
||||
Digit,
|
||||
DigitHyprid10,
|
||||
Digital,
|
||||
DigitalHyprid10,
|
||||
DoubleHyprid10,
|
||||
Digit100,
|
||||
Digital100,
|
||||
None
|
||||
};
|
||||
|
||||
@@ -26,6 +26,15 @@ 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;
|
||||
@@ -35,8 +44,8 @@ protected:
|
||||
bool SaveAllFiles;
|
||||
|
||||
int PointerEvalAnalogNew(float zahl, int numeral_preceder);
|
||||
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);
|
||||
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);
|
||||
|
||||
|
||||
|
||||
@@ -52,7 +61,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 AnalogToDigitTransitionStart=9.2);
|
||||
string getReadout(int _analog, bool _extendedResolution = false, int prev = -1, float _before_narrow_Analog = -1, float analogDigitalTransitionStart=9.2);
|
||||
|
||||
string getReadoutRawString(int _analog);
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@ 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 = "";
|
||||
@@ -64,19 +65,11 @@ std::string ClassFlowControll::doSingleStep(std::string _stepname, std::string _
|
||||
_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);
|
||||
}
|
||||
|
||||
@@ -85,51 +78,37 @@ 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 ("Digitization of ROIs");
|
||||
}
|
||||
|
||||
if (_input.compare("ClassFlowCNNGeneral") == 0)
|
||||
return ("Digitalization 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) {
|
||||
if (_input.compare("ClassFlowInfluxDBv2") == 0)
|
||||
return ("Sending InfluxDBv2");
|
||||
}
|
||||
#endif //ENABLE_INFLUXDB
|
||||
#ifdef ENABLE_WEBHOOK
|
||||
if (_input.compare("ClassFlowWebhook") == 0) {
|
||||
return ("Sending Webhook");
|
||||
}
|
||||
#endif //ENABLE_WEBHOOK
|
||||
if (_input.compare("ClassFlowPostProcessing") == 0) {
|
||||
if (_input.compare("ClassFlowPostProcessing") == 0)
|
||||
return ("Post-Processing");
|
||||
}
|
||||
|
||||
return "Unkown Status";
|
||||
}
|
||||
|
||||
std::vector<HTMLInfo*> ClassFlowControll::GetAllDigit()
|
||||
|
||||
std::vector<HTMLInfo*> ClassFlowControll::GetAllDigital()
|
||||
{
|
||||
if (flowdigit) {
|
||||
ESP_LOGD(TAG, "ClassFlowControll::GetAllDigit - flowdigit != NULL");
|
||||
if (flowdigit)
|
||||
{
|
||||
ESP_LOGD(TAG, "ClassFlowControll::GetAllDigital - flowdigit != NULL");
|
||||
return flowdigit->GetHTMLInfo();
|
||||
}
|
||||
|
||||
@@ -137,63 +116,65 @@ std::vector<HTMLInfo*> ClassFlowControll::GetAllDigit()
|
||||
return empty;
|
||||
}
|
||||
|
||||
|
||||
std::vector<HTMLInfo*> ClassFlowControll::GetAllAnalog()
|
||||
{
|
||||
if (flowanalog) {
|
||||
if (flowanalog)
|
||||
return flowanalog->GetHTMLInfo();
|
||||
}
|
||||
|
||||
std::vector<HTMLInfo*> empty;
|
||||
return empty;
|
||||
}
|
||||
|
||||
t_CNNType ClassFlowControll::GetTypeDigit()
|
||||
|
||||
t_CNNType ClassFlowControll::GetTypeDigital()
|
||||
{
|
||||
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::DigitDrawROI(CImageBasis *_zw)
|
||||
void ClassFlowControll::DigitalDrawROI(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
|
||||
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;
|
||||
@@ -208,6 +189,7 @@ void ClassFlowControll::SetInitialParameter(void)
|
||||
aktstatusWithTime = aktstatus;
|
||||
}
|
||||
|
||||
|
||||
bool ClassFlowControll::getIsAutoStart(void)
|
||||
{
|
||||
return AutoStart;
|
||||
@@ -219,81 +201,69 @@ 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);
|
||||
}
|
||||
|
||||
if (toUpper(_type).compare("[INFLUXDBV2]") == 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) {
|
||||
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) {
|
||||
if (toUpper(_type).compare("[AUTOTIMER]") == 0)
|
||||
cfc = this;
|
||||
}
|
||||
|
||||
if (toUpper(_type).compare("[DATALOGGING]") == 0) {
|
||||
if (toUpper(_type).compare("[DATALOGGING]") == 0)
|
||||
cfc = this;
|
||||
}
|
||||
|
||||
if (toUpper(_type).compare("[DEBUG]") == 0) {
|
||||
if (toUpper(_type).compare("[DEBUG]") == 0)
|
||||
cfc = this;
|
||||
}
|
||||
|
||||
if (toUpper(_type).compare("[SYSTEM]") == 0) {
|
||||
if (toUpper(_type).compare("[SYSTEM]") == 0)
|
||||
cfc = this;
|
||||
}
|
||||
|
||||
return cfc;
|
||||
}
|
||||
|
||||
|
||||
void ClassFlowControll::InitFlow(std::string config)
|
||||
{
|
||||
aktstatus = "Initialization";
|
||||
@@ -314,55 +284,62 @@ 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);
|
||||
// printf("Name: %s\n", cfc->name().c_str());
|
||||
|
||||
if (cfc) {
|
||||
ESP_LOGE(TAG, "Start ReadParameter (%s)", line.c_str());
|
||||
// printf("Name: %s\n", cfc->name().c_str());
|
||||
if (cfc)
|
||||
{
|
||||
ESP_LOGD(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");
|
||||
aktstatus = TranslateAktstatus(FlowControll[i]->name());
|
||||
@@ -376,6 +353,7 @@ void ClassFlowControll::doFlowTakeImageOnly(string time)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool ClassFlowControll::doFlow(string time)
|
||||
{
|
||||
bool result = true;
|
||||
@@ -395,7 +373,8 @@ 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");
|
||||
aktstatus = TranslateAktstatus(FlowControll[i]->name());
|
||||
aktstatusWithTime = aktstatus + " (" + zw_time + ")";
|
||||
@@ -412,7 +391,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");
|
||||
@@ -420,7 +399,8 @@ bool ClassFlowControll::doFlow(string time)
|
||||
//Step was repeated 5x --> reboot
|
||||
}
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
|
||||
@@ -444,29 +424,27 @@ 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 {
|
||||
else
|
||||
out = out + "PreValue too old";
|
||||
}
|
||||
}
|
||||
else {
|
||||
else
|
||||
out = out + "PreValue deactivated";
|
||||
}
|
||||
break;
|
||||
case READOUT_TYPE_RAWVALUE:
|
||||
out = out + (*numbers)[i]->ReturnRawValue;
|
||||
@@ -475,10 +453,8 @@ 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());
|
||||
}
|
||||
@@ -486,24 +462,43 @@ string ClassFlowControll::getReadoutAll(int _type)
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
string ClassFlowControll::getReadout(bool _rawvalue = false, bool _noerror = false, int _number = 0)
|
||||
{
|
||||
if (flowpostprocessing) {
|
||||
if (flowpostprocessing)
|
||||
return flowpostprocessing->getReadoutParam(_rawvalue, _noerror, _number);
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
return std::string("");
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
string ClassFlowControll::GetPrevalue(std::string _number)
|
||||
{
|
||||
if (flowpostprocessing) {
|
||||
if (flowpostprocessing)
|
||||
{
|
||||
return flowpostprocessing->GetPreValue(_number);
|
||||
}
|
||||
|
||||
|
||||
return std::string("");
|
||||
}
|
||||
|
||||
|
||||
bool ClassFlowControll::UpdatePrevalue(std::string _newvalue, std::string _numbers, bool _extern)
|
||||
{
|
||||
double newvalueAsDouble;
|
||||
@@ -524,12 +519,10 @@ bool ClassFlowControll::UpdatePrevalue(std::string _newvalue, std::string _numbe
|
||||
}
|
||||
|
||||
if (flowpostprocessing) {
|
||||
if (flowpostprocessing->SetPreValue(newvalueAsDouble, _numbers, _extern)) {
|
||||
if (flowpostprocessing->SetPreValue(newvalueAsDouble, _numbers, _extern))
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
else
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "UpdatePrevalue: ERROR - Class Post-Processing not initialized");
|
||||
@@ -537,85 +530,93 @@ bool ClassFlowControll::UpdatePrevalue(std::string _newvalue, std::string _numbe
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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)) {
|
||||
AutoStart = alphanumericToBoolean(splitted[1]);
|
||||
}
|
||||
|
||||
if ((toUpper(splitted[0]) == "INTERVAL") && (splitted.size() > 1)) {
|
||||
if (isStringNumeric(splitted[1]))
|
||||
if ((toUpper(splitted[0]) == "AUTOSTART") && (splitted.size() > 1))
|
||||
{
|
||||
if (toUpper(splitted[1]) == "TRUE")
|
||||
{
|
||||
AutoInterval = std::stof(splitted[1]);
|
||||
AutoStart = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ((toUpper(splitted[0]) == "DATALOGACTIVE") && (splitted.size() > 1)) {
|
||||
LogFile.SetDataLogToSD(alphanumericToBoolean(splitted[1]));
|
||||
if ((toUpper(splitted[0]) == "INTERVAL") && (splitted.size() > 1))
|
||||
{
|
||||
AutoInterval = std::stof(splitted[1]);
|
||||
}
|
||||
|
||||
if ((toUpper(splitted[0]) == "DATAFILESRETENTION") && (splitted.size() > 1)) {
|
||||
if (isStringNumeric(splitted[1]))
|
||||
if ((toUpper(splitted[0]) == "DATALOGACTIVE") && (splitted.size() > 1))
|
||||
{
|
||||
if (toUpper(splitted[1]) == "TRUE")
|
||||
{
|
||||
LogFile.SetDataLogRetention(std::stoi(splitted[1]));
|
||||
LogFile.SetDataLogToSD(true);
|
||||
}
|
||||
else {
|
||||
LogFile.SetDataLogToSD(false);
|
||||
}
|
||||
}
|
||||
|
||||
if ((toUpper(splitted[0]) == "LOGLEVEL") && (splitted.size() > 1)) {
|
||||
if ((toUpper(splitted[0]) == "DATAFILESRETENTION") && (splitted.size() > 1))
|
||||
{
|
||||
LogFile.SetDataLogRetention(std::stoi(splitted[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)) {
|
||||
if (!getIsPlannedReboot() && (esp_reset_reason() == ESP_RST_PANIC))
|
||||
LogFile.setLogLevel(ESP_LOG_DEBUG);
|
||||
}
|
||||
}
|
||||
|
||||
if ((toUpper(splitted[0]) == "LOGFILESRETENTION") && (splitted.size() > 1)) {
|
||||
if (isStringNumeric(splitted[1]))
|
||||
{
|
||||
LogFile.SetLogFileRetention(std::stoi(splitted[1]));
|
||||
}
|
||||
if ((toUpper(splitted[0]) == "LOGFILESRETENTION") && (splitted.size() > 1))
|
||||
{
|
||||
LogFile.SetLogFileRetention(std::stoi(splitted[1]));
|
||||
}
|
||||
|
||||
/* TimeServer and TimeZone got already read from the config, see setupTime () */
|
||||
|
||||
#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)) {
|
||||
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)) {
|
||||
if (ChangeRSSIThreshold(WLAN_CONFIG_FILE, RSSIThresholdTMP))
|
||||
{
|
||||
// reboot necessary so that the new wlan.ini is also used !!!
|
||||
fclose(pfile);
|
||||
LogFile.WriteToFile(ESP_LOG_WARN, TAG, "Rebooting to activate new RSSITHRESHOLD ...");
|
||||
@@ -624,8 +625,10 @@ bool ClassFlowControll::ReadParameter(FILE* pfile, string& aktparamgraph)
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((toUpper(splitted[0]) == "HOSTNAME") && (splitted.size() > 1)) {
|
||||
if (ChangeHostName(WLAN_CONFIG_FILE, splitted[1])) {
|
||||
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...");
|
||||
@@ -633,19 +636,23 @@ bool ClassFlowControll::ReadParameter(FILE* pfile, string& aktparamgraph)
|
||||
}
|
||||
}
|
||||
|
||||
if ((toUpper(splitted[0]) == "SETUPMODE") && (splitted.size() > 1)) {
|
||||
SetupModeActive = alphanumericToBoolean(splitted[1]);
|
||||
if ((toUpper(splitted[0]) == "SETUPMODE") && (splitted.size() > 1))
|
||||
{
|
||||
if (toUpper(splitted[1]) == "TRUE")
|
||||
{
|
||||
SetupModeActive = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
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;
|
||||
@@ -653,33 +660,31 @@ 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());
|
||||
@@ -841,8 +846,8 @@ esp_err_t ClassFlowControll::GetJPGStream(std::string _fn, httpd_req_t *req)
|
||||
else {
|
||||
std::vector<HTMLInfo*> htmlinfo;
|
||||
|
||||
htmlinfo = GetAllDigit();
|
||||
ESP_LOGD(TAG, "After getClassFlowControll::GetAllDigit");
|
||||
htmlinfo = GetAllDigital();
|
||||
ESP_LOGD(TAG, "After getClassFlowControll::GetAllDigital");
|
||||
|
||||
for (int i = 0; i < htmlinfo.size(); ++i)
|
||||
{
|
||||
@@ -911,20 +916,14 @@ 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();
|
||||
}
|
||||
|
||||
@@ -17,9 +17,6 @@
|
||||
#include "ClassFlowInfluxDB.h"
|
||||
#include "ClassFlowInfluxDBv2.h"
|
||||
#endif //ENABLE_INFLUXDB
|
||||
#ifdef ENABLE_WEBHOOK
|
||||
#include "ClassFlowWebhook.h"
|
||||
#endif //ENABLE_WEBHOOK
|
||||
#include "ClassFlowCNNGeneral.h"
|
||||
|
||||
class ClassFlowControll :
|
||||
@@ -55,13 +52,12 @@ public:
|
||||
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 ALGROI_LOAD_FROM_MEM_AS_JPG
|
||||
void DigitDrawROI(CImageBasis *_zw);
|
||||
void DigitalDrawROI(CImageBasis *_zw);
|
||||
void AnalogDrawROI(CImageBasis *_zw);
|
||||
#endif
|
||||
|
||||
@@ -77,10 +73,10 @@ public:
|
||||
std::string* getActStatus();
|
||||
void setActStatus(std::string _aktstatus);
|
||||
|
||||
std::vector<HTMLInfo*> GetAllDigit();
|
||||
std::vector<HTMLInfo*> GetAllDigital();
|
||||
std::vector<HTMLInfo*> GetAllAnalog();
|
||||
|
||||
t_CNNType GetTypeDigit();
|
||||
t_CNNType GetTypeDigital();
|
||||
t_CNNType GetTypeAnalog();
|
||||
|
||||
#ifdef ENABLE_MQTT
|
||||
|
||||
@@ -5,10 +5,6 @@
|
||||
|
||||
#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;
|
||||
@@ -18,66 +14,56 @@ 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, // 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
|
||||
AbsoluteChange,
|
||||
RateChange
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* 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; // 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
|
||||
float MaxRateValue;
|
||||
bool useMaxRateValue;
|
||||
t_RateType RateType;
|
||||
bool ErrorMessage;
|
||||
bool PreValueOkay;
|
||||
bool AllowNegativeRates;
|
||||
bool checkDigitIncreaseConsistency;
|
||||
time_t lastvalue;
|
||||
time_t timeStampTimeUTC;
|
||||
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;
|
||||
|
||||
string FieldV1; // influxdbFieldName_v1; Name of the Field in InfluxDBv1
|
||||
string MeasurementV1; // influxdbMeasurementName_v1; Name of the Measurement in InfluxDBv1
|
||||
string FieldV1; // Fieldname in InfluxDBv1
|
||||
string MeasurementV1; // Measurement in InfluxDBv1
|
||||
|
||||
string FieldV2; // influxdbFieldName_v2; Name of the Field in InfluxDBv2
|
||||
string MeasurementV2; // influxdbMeasurementName_v2; Name of the Measurement in InfluxDBv2
|
||||
string FieldV2; // Fieldname in InfluxDBv2
|
||||
string MeasurementV2; // Measurement in InfluxDBv2
|
||||
|
||||
bool isExtendedResolution; // extendResolution; Adds the decimal place of the least significant analog ROI to the value
|
||||
bool isExtendedResolution;
|
||||
|
||||
general *digit_roi; // digitRoi; set of digit ROIs for the sequence
|
||||
general *analog_roi; // analogRoi; set of analog ROIs for the sequence
|
||||
general *digit_roi;
|
||||
general *analog_roi;
|
||||
|
||||
string name; // name; Designation for the sequence
|
||||
string name;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -286,7 +286,7 @@ bool ClassFlowMQTT::doFlow(string zwtime)
|
||||
|
||||
if (resultchangabs.length() > 0) {
|
||||
success |= MQTTPublish(namenumber + "changeabsolut", resultchangabs, qos, SetRetainFlag); // Legacy API
|
||||
success |= MQTTPublish(namenumber + "rate_per_Digitization_round", resultchangabs, qos, SetRetainFlag);
|
||||
success |= MQTTPublish(namenumber + "rate_per_digitalization_round", resultchangabs, qos, SetRetainFlag);
|
||||
}
|
||||
|
||||
if (resultraw.length() > 0)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -21,9 +21,11 @@ protected:
|
||||
bool ErrorMessage;
|
||||
bool IgnoreLeadingNaN; // SPECIAL CASE for User Gustl ???
|
||||
|
||||
|
||||
ClassFlowCNNGeneral* flowAnalog;
|
||||
ClassFlowCNNGeneral* flowDigit;
|
||||
|
||||
|
||||
string FilePreValue;
|
||||
|
||||
ClassFlowTakeImage *flowTakeImage;
|
||||
@@ -39,18 +41,21 @@ protected:
|
||||
void handleMaxRateValue(string _decsep, string _value);
|
||||
void handleDecimalExtendedResolution(string _decsep, string _value);
|
||||
void handleMaxRateType(string _decsep, string _value);
|
||||
void handleAnalogToDigitTransitionStart(string _decsep, string _value);
|
||||
void handleAnalogDigitalTransitionStart(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(){};
|
||||
bool ReadParameter(FILE* pfile, string& aktparamgraph);
|
||||
|
||||
@@ -1,15 +1,9 @@
|
||||
#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"
|
||||
@@ -19,13 +13,13 @@
|
||||
#include <time.h>
|
||||
|
||||
// #define DEBUG_DETAIL_ON
|
||||
|
||||
// #define WIFITURNOFF
|
||||
|
||||
static const char *TAG = "TAKEIMAGE";
|
||||
static const char* TAG = "TAKEIMAGE";
|
||||
|
||||
esp_err_t ClassFlowTakeImage::camera_capture(void)
|
||||
{
|
||||
string nm = namerawimage;
|
||||
esp_err_t ClassFlowTakeImage::camera_capture(){
|
||||
string nm = namerawimage;
|
||||
Camera.CaptureToFile(nm);
|
||||
time(&TimeImageTaken);
|
||||
localtime(&TimeImageTaken);
|
||||
@@ -36,500 +30,150 @@ esp_err_t ClassFlowTakeImage::camera_capture(void)
|
||||
void ClassFlowTakeImage::takePictureWithFlash(int flash_duration)
|
||||
{
|
||||
// in case the image is flipped, it must be reset here //
|
||||
rawImage->width = CCstatus.ImageWidth;
|
||||
rawImage->height = CCstatus.ImageHeight;
|
||||
|
||||
rawImage->width = image_width;
|
||||
rawImage->height = image_height;
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
ESP_LOGD(TAG, "flash_duration: %d", flash_duration);
|
||||
|
||||
Camera.CaptureToBasisImage(rawImage, flash_duration);
|
||||
|
||||
time(&TimeImageTaken);
|
||||
localtime(&TimeImageTaken);
|
||||
|
||||
if (CCstatus.SaveAllFiles)
|
||||
{
|
||||
rawImage->SaveToFile(namerawimage);
|
||||
}
|
||||
if (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
|
||||
|
||||
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)
|
||||
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");
|
||||
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;
|
||||
@@ -537,68 +181,64 @@ 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)(CCstatus.WaitBeforePicture * 1000);
|
||||
int flash_duration = (int) (waitbeforepicture * 1000);
|
||||
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("ClassFlowTakeImage::doFlow - Before takePictureWithFlash");
|
||||
#endif
|
||||
#ifdef DEBUG_DETAIL_ON
|
||||
LogFile.WriteHeapInfo("ClassFlowTakeImage::doFlow - Before takePictureWithFlash");
|
||||
#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;
|
||||
}
|
||||
#ifdef WIFITURNOFF
|
||||
esp_wifi_stop(); // to save power usage and
|
||||
#endif
|
||||
|
||||
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)(CCstatus.WaitBeforePicture * 1000);
|
||||
int flash_duration = (int) (waitbeforepicture * 1000);
|
||||
time(&TimeImageTaken);
|
||||
localtime(&TimeImageTaken);
|
||||
|
||||
return Camera.CaptureToHTTP(req, flash_duration);
|
||||
}
|
||||
|
||||
ImageData *ClassFlowTakeImage::SendRawImage(void)
|
||||
|
||||
ImageData* ClassFlowTakeImage::SendRawImage()
|
||||
{
|
||||
CImageBasis *zw = new CImageBasis("SendRawImage", rawImage);
|
||||
ImageData *id;
|
||||
int flash_duration = (int)(CCstatus.WaitBeforePicture * 1000);
|
||||
int flash_duration = (int) (waitbeforepicture * 1000);
|
||||
Camera.CaptureToBasisImage(zw, flash_duration);
|
||||
time(&TimeImageTaken);
|
||||
localtime(&TimeImageTaken);
|
||||
@@ -608,7 +248,7 @@ ImageData *ClassFlowTakeImage::SendRawImage(void)
|
||||
return id;
|
||||
}
|
||||
|
||||
time_t ClassFlowTakeImage::getTimeImageTaken(void)
|
||||
time_t ClassFlowTakeImage::getTimeImageTaken()
|
||||
{
|
||||
return TimeImageTaken;
|
||||
}
|
||||
@@ -617,3 +257,4 @@ ClassFlowTakeImage::~ClassFlowTakeImage(void)
|
||||
{
|
||||
delete rawImage;
|
||||
}
|
||||
|
||||
|
||||
@@ -9,32 +9,47 @@
|
||||
|
||||
#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;
|
||||
|
||||
esp_err_t camera_capture(void);
|
||||
|
||||
|
||||
void CopyFile(string input, string output);
|
||||
|
||||
esp_err_t camera_capture();
|
||||
void takePictureWithFlash(int flash_duration);
|
||||
|
||||
|
||||
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(void);
|
||||
string name() { return "ClassFlowTakeImage"; };
|
||||
time_t getTimeImageTaken();
|
||||
string name(){return "ClassFlowTakeImage";};
|
||||
|
||||
ImageData *SendRawImage(void);
|
||||
ImageData* SendRawImage();
|
||||
esp_err_t SendRawJPG(httpd_req_t *req);
|
||||
|
||||
~ClassFlowTakeImage(void);
|
||||
};
|
||||
|
||||
#endif // CLASSFFLOWTAKEIMAGE_H
|
||||
|
||||
#endif //CLASSFFLOWTAKEIMAGE_H
|
||||
@@ -1,171 +0,0 @@
|
||||
#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
|
||||
@@ -1,43 +0,0 @@
|
||||
#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
|
||||
File diff suppressed because it is too large
Load Diff
@@ -9,83 +9,26 @@
|
||||
#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 CheckIsPlannedReboot();
|
||||
bool getIsPlannedReboot();
|
||||
|
||||
void InitializeFlowTask(void);
|
||||
void DeleteMainFlowTask(void);
|
||||
bool isSetupModusActive(void);
|
||||
void InitializeFlowTask();
|
||||
void DeleteMainFlowTask();
|
||||
bool isSetupModusActive();
|
||||
|
||||
int getCountFlowRounds(void);
|
||||
int getCountFlowRounds();
|
||||
|
||||
#ifdef ENABLE_MQTT
|
||||
esp_err_t MQTTCtrlFlowStart(std::string _topic);
|
||||
#endif // ENABLE_MQTT
|
||||
#endif //ENABLE_MQTT
|
||||
|
||||
esp_err_t GetRawJPG(httpd_req_t *req);
|
||||
esp_err_t GetJPG(std::string _filename, httpd_req_t *req);
|
||||
|
||||
#endif // MAINFLOWCONTROL_H
|
||||
#endif //MAINFLOWCONTROL_H
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -21,6 +21,7 @@ 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,6 +33,7 @@ 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);
|
||||
|
||||
@@ -66,6 +68,7 @@ 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 */
|
||||
@@ -95,18 +98,8 @@ 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
|
||||
|
||||
@@ -120,15 +120,15 @@ void psram_free_shared_temp_image_memory(void) {
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
* Memory used in Digitization Steps
|
||||
* Memory used in Digitalization 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";
|
||||
if ((sharedMemoryInUseFor == "") || (sharedMemoryInUseFor == "Digitalization_Model")) {
|
||||
sharedMemoryInUseFor = "Digitalization_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
|
||||
}
|
||||
@@ -140,8 +140,8 @@ void *psram_get_shared_tensor_arena_memory(void) {
|
||||
|
||||
|
||||
void *psram_get_shared_model_memory(void) {
|
||||
if ((sharedMemoryInUseFor == "") || (sharedMemoryInUseFor == "Digitization_Tensor")) {
|
||||
sharedMemoryInUseFor = "Digitization_Model";
|
||||
if ((sharedMemoryInUseFor == "") || (sharedMemoryInUseFor == "Digitalization_Tensor")) {
|
||||
sharedMemoryInUseFor = "Digitalization_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
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ void psram_free_shared_stbi_memory(void *p);
|
||||
void *psram_reserve_shared_tmp_image_memory(void);
|
||||
void psram_free_shared_temp_image_memory(void);
|
||||
|
||||
/* Memory used in Digitization Steps */
|
||||
/* Memory used in Digitalization 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);
|
||||
|
||||
@@ -35,15 +35,15 @@ static const char* TAG = "sdcard_init";
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
typedef struct mh_vfs_fat_sd_ctx_t {
|
||||
typedef struct 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;
|
||||
} vfs_fat_sd_ctx_t;
|
||||
|
||||
static mh_vfs_fat_sd_ctx_t *s_ctx[FF_VOLUMES] = {};
|
||||
static 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.
|
||||
@@ -185,9 +185,14 @@ BYTE ff_diskio_get_pdrv_card_mh(const sdmmc_card_t* card)
|
||||
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;
|
||||
vfs_fat_sd_ctx_t *p_ctx = NULL;
|
||||
for (int i = 0; i < FF_VOLUMES; i++) {
|
||||
p_ctx = s_ctx[i];
|
||||
if (p_ctx) {
|
||||
@@ -373,7 +378,7 @@ static esp_err_t init_sdmmc_host_mh(int slot, const void *slot_config, int *out_
|
||||
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;
|
||||
vfs_fat_sd_ctx_t *ctx = NULL;
|
||||
uint32_t ctx_id = FF_VOLUMES;
|
||||
FATFS *fs = NULL;
|
||||
int card_handle = -1; //uninitialized
|
||||
@@ -414,7 +419,7 @@ esp_err_t esp_vfs_fat_sdmmc_mount_mh(const char* base_path, const sdmmc_host_t*
|
||||
s_saved_ctx_id = 0;
|
||||
}
|
||||
|
||||
ctx = calloc(sizeof(mh_vfs_fat_sd_ctx_t), 1);
|
||||
ctx = calloc(sizeof(vfs_fat_sd_ctx_t), 1);
|
||||
|
||||
if (!ctx) {
|
||||
CHECK_EXECUTE_RESULT(ESP_ERR_NO_MEM, "no mem");
|
||||
@@ -457,7 +462,7 @@ esp_err_t esp_vfs_fat_sdspi_mount_mh(const char* base_path, const sdmmc_host_t*
|
||||
{
|
||||
const sdmmc_host_t* host_config = host_config_input;
|
||||
esp_err_t err;
|
||||
mh_vfs_fat_sd_ctx_t *ctx = NULL;
|
||||
vfs_fat_sd_ctx_t *ctx = NULL;
|
||||
uint32_t ctx_id = FF_VOLUMES;
|
||||
FATFS *fs = NULL;
|
||||
int card_handle = -1; //uninitialized
|
||||
@@ -509,7 +514,7 @@ esp_err_t esp_vfs_fat_sdspi_mount_mh(const char* base_path, const sdmmc_host_t*
|
||||
s_saved_ctx_id = 0;
|
||||
}
|
||||
|
||||
ctx = calloc(sizeof(mh_vfs_fat_sd_ctx_t), 1);
|
||||
ctx = calloc(sizeof(vfs_fat_sd_ctx_t), 1);
|
||||
|
||||
if (!ctx) {
|
||||
CHECK_EXECUTE_RESULT(ESP_ERR_NO_MEM, "no mem");
|
||||
|
||||
@@ -443,7 +443,7 @@ void CImageBasis::LoadFromMemory(stbi_uc *_buffer, int len)
|
||||
//free_psram_heap(std::string(TAG) + "->rgb_image (LoadFromMemory)", rgb_image);
|
||||
}
|
||||
|
||||
rgb_image = stbi_load_from_memory(_buffer, len, &width, &height, &channels, STBI_rgb);
|
||||
rgb_image = stbi_load_from_memory(_buffer, len, &width, &height, &channels, 3);
|
||||
bpp = channels;
|
||||
ESP_LOGD(TAG, "Image loaded from memory: %d, %d, %d", width, height, channels);
|
||||
|
||||
@@ -459,44 +459,6 @@ void CImageBasis::LoadFromMemory(stbi_uc *_buffer, int len)
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
@@ -636,20 +598,6 @@ CImageBasis::CImageBasis(string _name, uint8_t* _rgb_image, int _channels, int _
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
|
||||
@@ -56,7 +56,6 @@ 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);
|
||||
@@ -75,7 +74,6 @@ class CImageBasis
|
||||
|
||||
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);
|
||||
|
||||
|
||||
@@ -18,6 +18,50 @@ CRotateImage::CRotateImage(std::string _name, CImageBasis *_org, CImageBasis *_t
|
||||
doflip = _flip;
|
||||
}
|
||||
|
||||
|
||||
void CRotateImage::Mirror(){
|
||||
int memsize = width * height * channels;
|
||||
uint8_t* odata;
|
||||
if (ImageTMP)
|
||||
{
|
||||
odata = ImageTMP->RGBImageLock();
|
||||
}
|
||||
else
|
||||
{
|
||||
odata = (unsigned char*)malloc_psram_heap(std::string(TAG) + "->odata", memsize, MALLOC_CAP_SPIRAM);
|
||||
}
|
||||
|
||||
|
||||
int x_source, y_source;
|
||||
stbi_uc* p_target;
|
||||
stbi_uc* p_source;
|
||||
|
||||
RGBImageLock();
|
||||
|
||||
for (int x = 0; x < width; ++x)
|
||||
for (int y = 0; y < height; ++y)
|
||||
{
|
||||
p_target = odata + (channels * (y * width + x));
|
||||
|
||||
x_source = width - x;
|
||||
y_source = y;
|
||||
|
||||
p_source = rgb_image + (channels * (y_source * width + x_source));
|
||||
for (int _channels = 0; _channels < channels; ++_channels)
|
||||
p_target[_channels] = p_source[_channels];
|
||||
}
|
||||
|
||||
// memcpy(rgb_image, odata, memsize);
|
||||
memCopy(odata, rgb_image, memsize);
|
||||
if (!ImageTMP)
|
||||
free_psram_heap(std::string(TAG) + "->odata", odata);
|
||||
|
||||
if (ImageTMP)
|
||||
ImageTMP->RGBImageRelease();
|
||||
|
||||
RGBImageRelease();
|
||||
}
|
||||
|
||||
void CRotateImage::Rotate(float _angle, int _centerx, int _centery)
|
||||
{
|
||||
int org_width, org_height;
|
||||
|
||||
@@ -23,6 +23,7 @@ class CRotateImage: public CImageBasis
|
||||
void RotateAntiAliasing(float _angle, int _centerx, int _centery);
|
||||
|
||||
void Translate(int _dx, int _dy);
|
||||
void Mirror();
|
||||
};
|
||||
|
||||
#endif //CROTATEIMAGE_H
|
||||
@@ -32,7 +32,7 @@ void ClassLogFile::WriteHeapInfo(std::string _id)
|
||||
}
|
||||
|
||||
|
||||
void ClassLogFile::WriteToData(std::string _timestamp, std::string _name, std::string _ReturnRawValue, std::string _ReturnValue, std::string _ReturnPreValue, std::string _ReturnRateValue, std::string _ReturnChangeAbsolute, std::string _ErrorMessageText, std::string _digit, std::string _analog)
|
||||
void ClassLogFile::WriteToData(std::string _timestamp, std::string _name, std::string _ReturnRawValue, std::string _ReturnValue, std::string _ReturnPreValue, std::string _ReturnRateValue, std::string _ReturnChangeAbsolute, std::string _ErrorMessageText, std::string _digital, std::string _analog)
|
||||
{
|
||||
ESP_LOGD(TAG, "Start WriteToData");
|
||||
time_t rawtime;
|
||||
@@ -67,7 +67,7 @@ void ClassLogFile::WriteToData(std::string _timestamp, std::string _name, std::s
|
||||
fputs(_ReturnChangeAbsolute.c_str(), pFile);
|
||||
fputs(",", pFile);
|
||||
fputs(_ErrorMessageText.c_str(), pFile);
|
||||
fputs(_digit.c_str(), pFile);
|
||||
fputs(_digital.c_str(), pFile);
|
||||
fputs(_analog.c_str(), pFile);
|
||||
fputs("\n", pFile);
|
||||
|
||||
|
||||
@@ -39,8 +39,8 @@ public:
|
||||
void RemoveOldLogFile();
|
||||
void RemoveOldDataLog();
|
||||
|
||||
// void WriteToData(std::string _ReturnRawValue, std::string _ReturnValue, std::string _ReturnPreValue, std::string _ErrorMessageText, std::string _digit, std::string _analog);
|
||||
void WriteToData(std::string _timestamp, std::string _name, std::string _ReturnRawValue, std::string _ReturnValue, std::string _ReturnPreValue, std::string _ReturnRateValue, std::string _ReturnChangeAbsolute, std::string _ErrorMessageText, std::string _digit, std::string _analog);
|
||||
// void WriteToData(std::string _ReturnRawValue, std::string _ReturnValue, std::string _ReturnPreValue, std::string _ErrorMessageText, std::string _digital, std::string _analog);
|
||||
void WriteToData(std::string _timestamp, std::string _name, std::string _ReturnRawValue, std::string _ReturnValue, std::string _ReturnPreValue, std::string _ReturnRateValue, std::string _ReturnChangeAbsolute, std::string _ErrorMessageText, std::string _digital, std::string _analog);
|
||||
|
||||
|
||||
std::string GetCurrentFileName();
|
||||
|
||||
@@ -21,7 +21,6 @@ static const char *TAG = "MQTT SERVER";
|
||||
extern const char* libfive_git_version(void);
|
||||
extern const char* libfive_git_revision(void);
|
||||
extern const char* libfive_git_branch(void);
|
||||
extern std::string getFwVersion(void);
|
||||
|
||||
std::vector<NumberPost*>* NUMBERS;
|
||||
bool HomeassistantDiscovery = false;
|
||||
@@ -49,15 +48,6 @@ void mqttServer_setMeterType(std::string _meterType, std::string _valueUnit, std
|
||||
rateUnit = _rateUnit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes any multi-level MQTT-topic and returns the last topic level as nodeId
|
||||
* see https://www.hivemq.com/blog/mqtt-essentials-part-5-mqtt-topics-best-practices/ for details about MQTT topics
|
||||
*/
|
||||
std::string createNodeId(std::string &topic) {
|
||||
auto splitPos = topic.find_last_of('/');
|
||||
return (splitPos == std::string::npos) ? topic : topic.substr(splitPos + 1);
|
||||
}
|
||||
|
||||
bool sendHomeAssistantDiscoveryTopic(std::string group, std::string field,
|
||||
std::string name, std::string icon, std::string unit, std::string deviceClass, std::string stateClass, std::string entityCategory,
|
||||
int qos) {
|
||||
@@ -78,18 +68,11 @@ bool sendHomeAssistantDiscoveryTopic(std::string group, std::string field,
|
||||
name = group + " " + name;
|
||||
}
|
||||
|
||||
/**
|
||||
* homeassistant needs the MQTT discovery topic according to the following structure:
|
||||
* <discovery_prefix>/<component>/[<node_id>/]<object_id>/config
|
||||
* if the main topic is embedded in a nested structure, we just use the last part as node_id
|
||||
* This means a maintopic "home/test/watermeter" is transformed to the discovery topic "homeassistant/sensor/watermeter/..."
|
||||
*/
|
||||
std::string node_id = createNodeId(maintopic);
|
||||
if (field == "problem") { // Special binary sensor which is based on error topic
|
||||
topicFull = "homeassistant/binary_sensor/" + node_id + "/" + configTopic + "/config";
|
||||
topicFull = "homeassistant/binary_sensor/" + maintopic + "/" + configTopic + "/config";
|
||||
}
|
||||
else {
|
||||
topicFull = "homeassistant/sensor/" + node_id + "/" + configTopic + "/config";
|
||||
topicFull = "homeassistant/sensor/" + maintopic + "/" + configTopic + "/config";
|
||||
}
|
||||
|
||||
/* See https://www.home-assistant.io/docs/mqtt/discovery/ */
|
||||
@@ -168,7 +151,6 @@ bool MQTThomeassistantDiscovery(int qos) {
|
||||
// Group | Field | User Friendly Name | Icon | Unit | Device Class | State Class | Entity Category
|
||||
allSendsSuccessed |= sendHomeAssistantDiscoveryTopic("", "uptime", "Uptime", "clock-time-eight-outline", "s", "", "", "diagnostic", qos);
|
||||
allSendsSuccessed |= sendHomeAssistantDiscoveryTopic("", "MAC", "MAC Address", "network-outline", "", "", "", "diagnostic", qos);
|
||||
allSendsSuccessed |= sendHomeAssistantDiscoveryTopic("", "fwVersion", "Firmware Version", "application-outline", "", "", "", "diagnostic", qos);
|
||||
allSendsSuccessed |= sendHomeAssistantDiscoveryTopic("", "hostname", "Hostname", "network-outline", "", "", "", "diagnostic", qos);
|
||||
allSendsSuccessed |= sendHomeAssistantDiscoveryTopic("", "freeMem", "Free Memory", "memory", "B", "", "measurement", "diagnostic", qos);
|
||||
allSendsSuccessed |= sendHomeAssistantDiscoveryTopic("", "wifiRSSI", "Wi-Fi RSSI", "wifi", "dBm", "signal_strength", "", "diagnostic", qos);
|
||||
@@ -188,10 +170,10 @@ bool MQTThomeassistantDiscovery(int qos) {
|
||||
allSendsSuccessed |= sendHomeAssistantDiscoveryTopic(group, "value", "Value", "gauge", valueUnit, meterType, "total_increasing", "", qos);
|
||||
allSendsSuccessed |= sendHomeAssistantDiscoveryTopic(group, "raw", "Raw Value", "raw", "", "", "", "diagnostic", qos);
|
||||
allSendsSuccessed |= sendHomeAssistantDiscoveryTopic(group, "error", "Error", "alert-circle-outline", "", "", "", "diagnostic", qos);
|
||||
/* Not announcing "rate" as it is better to use rate_per_time_unit resp. rate_per_Digitization_round */
|
||||
/* Not announcing "rate" as it is better to use rate_per_time_unit resp. rate_per_digitalization_round */
|
||||
// allSendsSuccessed |= sendHomeAssistantDiscoveryTopic(group, "rate", "Rate (Unit/Minute)", "swap-vertical", "", "", "", ""); // Legacy, always Unit per Minute
|
||||
allSendsSuccessed |= sendHomeAssistantDiscoveryTopic(group, "rate_per_time_unit", "Rate (" + rateUnit + ")", "swap-vertical", rateUnit, "", "measurement", "", qos);
|
||||
allSendsSuccessed |= sendHomeAssistantDiscoveryTopic(group, "rate_per_Digitization_round", "Change since last Digitization round", "arrow-expand-vertical", valueUnit, "", "measurement", "", qos); // correctly the Unit is Unit/Interval!
|
||||
allSendsSuccessed |= sendHomeAssistantDiscoveryTopic(group, "rate_per_digitalization_round", "Change since last digitalization round", "arrow-expand-vertical", valueUnit, "", "measurement", "", qos); // correctly the Unit is Unit/Interval!
|
||||
allSendsSuccessed |= sendHomeAssistantDiscoveryTopic(group, "timestamp", "Timestamp", "clock-time-eight-outline", "", "timestamp", "", "diagnostic", qos);
|
||||
allSendsSuccessed |= sendHomeAssistantDiscoveryTopic(group, "json", "JSON", "code-json", "", "", "", "diagnostic", qos);
|
||||
allSendsSuccessed |= sendHomeAssistantDiscoveryTopic(group, "problem", "Problem", "alert-outline", "", "problem", "", "", qos); // Special binary sensor which is based on error topic
|
||||
@@ -262,7 +244,6 @@ bool publishStaticData(int qos) {
|
||||
|
||||
int aFreeInternalHeapSizeBefore = heap_caps_get_free_size(MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL);
|
||||
|
||||
allSendsSuccessed |= MQTTPublish(maintopic + "/" + "fwVersion", getFwVersion().c_str(), qos, retainFlag);
|
||||
allSendsSuccessed |= MQTTPublish(maintopic + "/" + "MAC", getMac(), qos, retainFlag);
|
||||
allSendsSuccessed |= MQTTPublish(maintopic + "/" + "IP", *getIPAddress(), qos, retainFlag);
|
||||
allSendsSuccessed |= MQTTPublish(maintopic + "/" + "hostname", wlan_config.hostname, qos, retainFlag);
|
||||
|
||||
@@ -22,7 +22,6 @@ std::string getTimeUnit(void);
|
||||
void GotConnected(std::string maintopic, bool SetRetainFlag);
|
||||
esp_err_t sendDiscovery_and_static_Topics(void);
|
||||
|
||||
std::string createNodeId(std::string &topic);
|
||||
|
||||
#endif //SERVERMQTT_H
|
||||
#endif //ENABLE_MQTT
|
||||
@@ -206,7 +206,6 @@ bool CTfLiteClass::MakeAllocate()
|
||||
|
||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "CTfLiteClass::MakeAllocate");
|
||||
this->interpreter = new tflite::MicroInterpreter(this->model, resolver, this->tensor_arena, this->kTensorArenaSize);
|
||||
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Trying to load the model. If it crashes here, it ist most likely due to a corrupted model!");
|
||||
|
||||
if (this->interpreter)
|
||||
{
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
FILE(GLOB_RECURSE app_sources ${CMAKE_CURRENT_SOURCE_DIR}/*.*)
|
||||
|
||||
idf_component_register(SRCS ${app_sources}
|
||||
INCLUDE_DIRS "."
|
||||
REQUIRES esp_http_client jomjol_logfile jomjol_flowcontroll json)
|
||||
|
||||
|
||||
@@ -1,170 +0,0 @@
|
||||
#ifdef ENABLE_WEBHOOK
|
||||
#include "interface_webhook.h"
|
||||
|
||||
#include "esp_log.h"
|
||||
#include <time.h>
|
||||
#include "ClassLogFile.h"
|
||||
#include "esp_http_client.h"
|
||||
#include "time_sntp.h"
|
||||
#include "../../include/defines.h"
|
||||
#include <cJSON.h>
|
||||
#include <ClassFlowDefineTypes.h>
|
||||
|
||||
|
||||
static const char *TAG = "WEBHOOK";
|
||||
|
||||
std::string _webhookURI;
|
||||
std::string _webhookApiKey;
|
||||
long _lastTimestamp;
|
||||
|
||||
static esp_err_t http_event_handler(esp_http_client_event_t *evt);
|
||||
|
||||
void WebhookInit(std::string _uri, std::string _apiKey)
|
||||
{
|
||||
_webhookURI = _uri;
|
||||
_webhookApiKey = _apiKey;
|
||||
_lastTimestamp = 0L;
|
||||
}
|
||||
|
||||
bool WebhookPublish(std::vector<NumberPost*>* numbers)
|
||||
{
|
||||
bool numbersWithError = false;
|
||||
cJSON *jsonArray = cJSON_CreateArray();
|
||||
|
||||
for (int i = 0; i < (*numbers).size(); ++i)
|
||||
{
|
||||
string timezw = "";
|
||||
char buffer[80];
|
||||
time_t &lastPreValue = (*numbers)[i]->timeStampLastPreValue;
|
||||
struct tm* timeinfo = localtime(&lastPreValue);
|
||||
_lastTimestamp = static_cast<long>(lastPreValue);
|
||||
strftime(buffer, 80, PREVALUE_TIME_FORMAT_OUTPUT, timeinfo);
|
||||
timezw = std::string(buffer);
|
||||
|
||||
cJSON *json = cJSON_CreateObject();
|
||||
cJSON_AddStringToObject(json, "timestamp", timezw.c_str());
|
||||
cJSON_AddStringToObject(json, "timestampLong", std::to_string(_lastTimestamp).c_str());
|
||||
cJSON_AddStringToObject(json, "name", (*numbers)[i]->name.c_str());
|
||||
cJSON_AddStringToObject(json, "rawValue", (*numbers)[i]->ReturnRawValue.c_str());
|
||||
cJSON_AddStringToObject(json, "value", (*numbers)[i]->ReturnValue.c_str());
|
||||
cJSON_AddStringToObject(json, "preValue", (*numbers)[i]->ReturnPreValue.c_str());
|
||||
cJSON_AddStringToObject(json, "rate", (*numbers)[i]->ReturnRateValue.c_str());
|
||||
cJSON_AddStringToObject(json, "changeAbsolute", (*numbers)[i]->ReturnChangeAbsolute.c_str());
|
||||
cJSON_AddStringToObject(json, "error", (*numbers)[i]->ErrorMessageText.c_str());
|
||||
|
||||
cJSON_AddItemToArray(jsonArray, json);
|
||||
|
||||
if ((*numbers)[i]->ErrorMessage) {
|
||||
numbersWithError = true;
|
||||
}
|
||||
}
|
||||
|
||||
char *jsonString = cJSON_PrintUnformatted(jsonArray);
|
||||
|
||||
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "sending webhook");
|
||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "sending JSON: " + std::string(jsonString));
|
||||
|
||||
char response_buffer[MAX_HTTP_OUTPUT_BUFFER] = {0};
|
||||
esp_http_client_config_t http_config = {
|
||||
.url = _webhookURI.c_str(),
|
||||
.user_agent = "ESP32 Meter reader",
|
||||
.method = HTTP_METHOD_POST,
|
||||
.event_handler = http_event_handler,
|
||||
.buffer_size = MAX_HTTP_OUTPUT_BUFFER,
|
||||
.user_data = response_buffer
|
||||
};
|
||||
|
||||
esp_http_client_handle_t http_client = esp_http_client_init(&http_config);
|
||||
|
||||
esp_http_client_set_header(http_client, "Content-Type", "application/json");
|
||||
esp_http_client_set_header(http_client, "APIKEY", _webhookApiKey.c_str());
|
||||
|
||||
ESP_ERROR_CHECK(esp_http_client_set_post_field(http_client, jsonString, strlen(jsonString)));
|
||||
|
||||
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_ERROR, TAG, "HTTP request failed");
|
||||
}
|
||||
|
||||
esp_http_client_cleanup(http_client);
|
||||
cJSON_Delete(jsonArray);
|
||||
free(jsonString);
|
||||
return numbersWithError;
|
||||
}
|
||||
|
||||
void WebhookUploadPic(ImageData *Img) {
|
||||
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Starting WebhookUploadPic");
|
||||
|
||||
std::string fullURI = _webhookURI + "?timestamp=" + std::to_string(_lastTimestamp);
|
||||
char response_buffer[MAX_HTTP_OUTPUT_BUFFER] = {0};
|
||||
esp_http_client_config_t http_config = {
|
||||
.url = fullURI.c_str(),
|
||||
.user_agent = "ESP32 Meter reader",
|
||||
.method = HTTP_METHOD_PUT,
|
||||
.event_handler = http_event_handler,
|
||||
.buffer_size = MAX_HTTP_OUTPUT_BUFFER,
|
||||
.user_data = response_buffer
|
||||
};
|
||||
|
||||
esp_http_client_handle_t http_client = esp_http_client_init(&http_config);
|
||||
|
||||
esp_http_client_set_header(http_client, "Content-Type", "image/jpeg");
|
||||
esp_http_client_set_header(http_client, "APIKEY", _webhookApiKey.c_str());
|
||||
|
||||
esp_err_t err = ESP_ERROR_CHECK_WITHOUT_ABORT(esp_http_client_set_post_field(http_client, (const char *)Img->data, Img->size));
|
||||
|
||||
err = ESP_ERROR_CHECK_WITHOUT_ABORT(esp_http_client_perform(http_client));
|
||||
|
||||
if (err == ESP_OK) {
|
||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "HTTP PUT request was performed successfully");
|
||||
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_ERROR, TAG, "HTTP PUT request failed");
|
||||
}
|
||||
|
||||
esp_http_client_cleanup(http_client);
|
||||
|
||||
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "WebhookUploadPic finished");
|
||||
}
|
||||
|
||||
|
||||
static esp_err_t http_event_handler(esp_http_client_event_t *evt)
|
||||
{
|
||||
switch(evt->event_id)
|
||||
{
|
||||
case HTTP_EVENT_ERROR:
|
||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "HTTP Client Error encountered");
|
||||
break;
|
||||
case HTTP_EVENT_ON_CONNECTED:
|
||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "HTTP Client connected");
|
||||
ESP_LOGI(TAG, "HTTP Client Connected");
|
||||
break;
|
||||
case HTTP_EVENT_HEADERS_SENT:
|
||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "HTTP Client sent all request headers");
|
||||
break;
|
||||
case HTTP_EVENT_ON_HEADER:
|
||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Header: key=" + std::string(evt->header_key) + ", value=" + std::string(evt->header_value));
|
||||
break;
|
||||
case HTTP_EVENT_ON_DATA:
|
||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "HTTP Client data recevied: len=" + std::to_string(evt->data_len));
|
||||
break;
|
||||
case HTTP_EVENT_ON_FINISH:
|
||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "HTTP Client finished");
|
||||
break;
|
||||
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;
|
||||
}
|
||||
|
||||
#endif //ENABLE_WEBHOOK
|
||||
@@ -1,17 +0,0 @@
|
||||
#ifdef ENABLE_WEBHOOK
|
||||
|
||||
#pragma once
|
||||
#ifndef INTERFACE_WEBHOOK_H
|
||||
#define INTERFACE_WEBHOOK_H
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <functional>
|
||||
#include <ClassFlowDefineTypes.h>
|
||||
|
||||
void WebhookInit(std::string _webhookURI, std::string _apiKey);
|
||||
bool WebhookPublish(std::vector<NumberPost*>* numbers);
|
||||
void WebhookUploadPic(ImageData *Img);
|
||||
|
||||
#endif //INTERFACE_WEBHOOK_H
|
||||
#endif //ENABLE_WEBHOOK
|
||||
@@ -480,8 +480,7 @@ static void event_handler(void* arg, esp_event_base_t event_base, int32_t event_
|
||||
if (WIFIReconnectCnt >= 10) {
|
||||
WIFIReconnectCnt = 0;
|
||||
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Disconnected, multiple reconnect attempts failed (" +
|
||||
std::to_string(disconn->reason) + "), retrying after 5s");
|
||||
vTaskDelay(5000 / portTICK_PERIOD_MS); // Delay between the reconnections
|
||||
std::to_string(disconn->reason) + "), still retrying...");
|
||||
}
|
||||
}
|
||||
else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_CONNECTED)
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
FILE(GLOB_RECURSE app_sources ${CMAKE_CURRENT_SOURCE_DIR}/*.*)
|
||||
|
||||
idf_component_register(SRCS ${app_sources}
|
||||
INCLUDE_DIRS "."
|
||||
REQUIRES jomjol_image_proc)
|
||||
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
#include "openmetrics.h"
|
||||
|
||||
/**
|
||||
* create a singe metric from the given input
|
||||
**/
|
||||
std::string createMetric(const std::string &metricName, const std::string &help, const std::string &type, const std::string &value)
|
||||
{
|
||||
return "# HELP " + metricName + " " + help + "\n" +
|
||||
"# TYPE " + metricName + " " + type + "\n" +
|
||||
metricName + " " + value + "\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate the MetricFamily from all available sequences
|
||||
* @returns the string containing the text wire format of the MetricFamily
|
||||
**/
|
||||
std::string createSequenceMetrics(std::string prefix, const std::vector<NumberPost *> &numbers)
|
||||
{
|
||||
std::string res;
|
||||
|
||||
for (const auto &number : numbers)
|
||||
{
|
||||
// only valid data is reported (https://github.com/OpenObservability/OpenMetrics/blob/main/specification/OpenMetrics.md#missing-data)
|
||||
if (number->ReturnValue.length() > 0)
|
||||
{
|
||||
auto label = number->name;
|
||||
|
||||
// except newline, double quote, and backslash (https://github.com/OpenObservability/OpenMetrics/blob/main/specification/OpenMetrics.md#abnf)
|
||||
// to keep it simple, these characters are just removed from the label
|
||||
replaceAll(label, "\\", "");
|
||||
replaceAll(label, "\"", "");
|
||||
replaceAll(label, "\n", "");
|
||||
res += prefix + "_flow_value{sequence=\"" + label + "\"} " + number->ReturnValue + "\n";
|
||||
}
|
||||
}
|
||||
|
||||
// prepend metadata if a valid metric was created
|
||||
if (res.length() > 0)
|
||||
{
|
||||
res = "# HELP " + prefix + "_flow_value current value of meter readout\n# TYPE " + prefix + "_flow_value gauge\n" + res;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef OPENMETRICS_H
|
||||
#define OPENMETRICS_H
|
||||
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
#include <vector>
|
||||
|
||||
#include "ClassFlowDefineTypes.h"
|
||||
|
||||
std::string createMetric(const std::string &metricName, const std::string &help, const std::string &type, const std::string &value);
|
||||
std::string createSequenceMetrics(std::string prefix, const std::vector<NumberPost *> &numbers);
|
||||
|
||||
#endif // OPENMETRICS_H
|
||||
@@ -1,16 +1,3 @@
|
||||
dependencies:
|
||||
espressif/esp-nn:
|
||||
component_hash: b32869798bdb40dec6bc99caca48cd65d42f8a9f506b9ab9c598a076f891ede9
|
||||
source:
|
||||
pre_release: true
|
||||
service_url: https://api.components.espressif.com/
|
||||
type: service
|
||||
version: 1.0.2
|
||||
idf:
|
||||
component_hash: null
|
||||
source:
|
||||
type: idf
|
||||
version: 5.3.0
|
||||
manifest_hash: 6995555b9b41e897235448c868ca92c0c3401fd2ff90df084be9bb8629958f2c
|
||||
manifest_hash: 63f5c6c9f0bcebc7b9ca12d2aa8b26b2c5f5218d377dc4b2375d9b9ca1df7815
|
||||
target: esp32
|
||||
version: 1.0.0
|
||||
@@ -58,9 +58,19 @@
|
||||
//#define CONFIG_IDF_TARGET_ARCH_XTENSA //not needed with platformio/espressif32 @ 5.2.0
|
||||
|
||||
|
||||
//Statusled + ClassControllCamera
|
||||
#define BLINK_GPIO GPIO_NUM_33 // PIN for red board LED
|
||||
|
||||
|
||||
//ClassControllCamera
|
||||
#define FLASH_GPIO GPIO_NUM_4 // PIN for flashlight LED
|
||||
#define USE_PWM_LEDFLASH // if __LEDGLOBAL is defined, a global variable is used for LED control, otherwise locally and each time a new
|
||||
#define CAM_LIVESTREAM_REFRESHRATE 500 // Camera livestream feature: Waiting time in milliseconds to refresh image
|
||||
// #define GRAYSCALE_AS_DEFAULT
|
||||
|
||||
|
||||
//ClassControllCamera + ClassFlowTakeImage
|
||||
#define CAMERA_MODEL_AI_THINKER
|
||||
#define BOARD_ESP32CAM_AITHINKER
|
||||
|
||||
|
||||
//server_GPIO
|
||||
@@ -94,7 +104,7 @@
|
||||
#define LOGFILE_LAST_PART_BYTES 80 * 1024 // 80 kBytes // Size of partial log file to return
|
||||
|
||||
#define SERVER_FILER_SCRATCH_BUFSIZE 4096
|
||||
#define SERVER_HELPER_SCRATCH_BUFSIZE 4096
|
||||
#define SERVER_HELPER_SCRATCH_BUFSIZE 8192
|
||||
#define SERVER_OTA_SCRATCH_BUFSIZE 1024
|
||||
|
||||
|
||||
@@ -176,13 +186,15 @@
|
||||
|
||||
//ClassFlowCNNGeneral
|
||||
#define Analog_error 3
|
||||
|
||||
#define AnalogToDigtalFehler 0.8
|
||||
#define Digit_Uncertainty 0.2
|
||||
#define DigitBand 3
|
||||
#define Digit_Transition_Range_Predecessor 2
|
||||
#define Digit_Transition_Area_Predecessor 0.7 // 9.3 - 0.7
|
||||
#define Digit_Transition_Area_Forward 9.7 // Pre-run zero crossing only happens from approx. 9.7 onwards
|
||||
#define Digital_Uncertainty 0.2
|
||||
#define DigitalBand 3
|
||||
#define Digital_Transition_Range_Predecessor 2
|
||||
#define Digital_Transition_Area_Predecessor 0.7 // 9.3 - 0.7
|
||||
#define Digital_Transition_Area_Forward 9.7 // Pre-run zero crossing only happens from approx. 9.7 onwards
|
||||
|
||||
|
||||
|
||||
|
||||
//#define DEBUG_DETAIL_ON
|
||||
|
||||
@@ -197,124 +209,117 @@
|
||||
//// Conditionnal definitions ////
|
||||
/////////////////////////////////////////////
|
||||
|
||||
//******* camera model
|
||||
#if defined(CAMERA_MODEL_WROVER_KIT)
|
||||
#define PWDN_GPIO_NUM -1
|
||||
#define RESET_GPIO_NUM -1
|
||||
#define XCLK_GPIO_NUM 21
|
||||
#define SIOD_GPIO_NUM 26
|
||||
#define SIOC_GPIO_NUM 27
|
||||
|
||||
// ******* Board type
|
||||
#if defined(BOARD_WROVER_KIT) // WROVER-KIT PIN Map
|
||||
// SD card (operated with SDMMC peripheral)
|
||||
//-------------------------------------------------
|
||||
#define GPIO_SDCARD_CLK GPIO_NUM_14
|
||||
#define GPIO_SDCARD_CMD GPIO_NUM_15
|
||||
#define GPIO_SDCARD_D0 GPIO_NUM_2
|
||||
#ifndef __SD_USE_ONE_LINE_MODE__
|
||||
#define GPIO_SDCARD_D1 GPIO_NUM_4
|
||||
#define GPIO_SDCARD_D2 GPIO_NUM_12
|
||||
#define GPIO_SDCARD_D3 GPIO_NUM_13
|
||||
#else
|
||||
#define GPIO_SDCARD_D1 GPIO_NUM_NC
|
||||
#define GPIO_SDCARD_D2 GPIO_NUM_NC
|
||||
#define GPIO_SDCARD_D3 GPIO_NUM_13
|
||||
#endif
|
||||
#define Y9_GPIO_NUM 35
|
||||
#define Y8_GPIO_NUM 34
|
||||
#define Y7_GPIO_NUM 39
|
||||
#define Y6_GPIO_NUM 36
|
||||
#define Y5_GPIO_NUM 19
|
||||
#define Y4_GPIO_NUM 18
|
||||
#define Y3_GPIO_NUM 5
|
||||
#define Y2_GPIO_NUM 4
|
||||
#define VSYNC_GPIO_NUM 25
|
||||
#define HREF_GPIO_NUM 23
|
||||
#define PCLK_GPIO_NUM 22
|
||||
|
||||
#define CAM_PIN_PWDN GPIO_NUM_NC //power down is not used
|
||||
#define CAM_PIN_RESET GPIO_NUM_NC //software reset will be performed
|
||||
#define CAM_PIN_XCLK GPIO_NUM_21
|
||||
#define CAM_PIN_SIOD GPIO_NUM_26
|
||||
#define CAM_PIN_SIOC GPIO_NUM_27
|
||||
#elif defined(CAMERA_MODEL_M5STACK_PSRAM)
|
||||
#define PWDN_GPIO_NUM -1
|
||||
#define RESET_GPIO_NUM 15
|
||||
#define XCLK_GPIO_NUM 27
|
||||
#define SIOD_GPIO_NUM 25
|
||||
#define SIOC_GPIO_NUM 23
|
||||
|
||||
#define CAM_PIN_D7 GPIO_NUM_35
|
||||
#define CAM_PIN_D6 GPIO_NUM_34
|
||||
#define CAM_PIN_D5 GPIO_NUM_39
|
||||
#define CAM_PIN_D4 GPIO_NUM_36
|
||||
#define CAM_PIN_D3 GPIO_NUM_19
|
||||
#define CAM_PIN_D2 GPIO_NUM_18
|
||||
#define CAM_PIN_D1 GPIO_NUM_5
|
||||
#define CAM_PIN_D0 GPIO_NUM_4
|
||||
#define CAM_PIN_VSYNC GPIO_NUM_25
|
||||
#define CAM_PIN_HREF GPIO_NUM_23
|
||||
#define CAM_PIN_PCLK GPIO_NUM_22
|
||||
#define Y9_GPIO_NUM 19
|
||||
#define Y8_GPIO_NUM 36
|
||||
#define Y7_GPIO_NUM 18
|
||||
#define Y6_GPIO_NUM 39
|
||||
#define Y5_GPIO_NUM 5
|
||||
#define Y4_GPIO_NUM 34
|
||||
#define Y3_GPIO_NUM 35
|
||||
#define Y2_GPIO_NUM 32
|
||||
#define VSYNC_GPIO_NUM 22
|
||||
#define HREF_GPIO_NUM 26
|
||||
#define PCLK_GPIO_NUM 21
|
||||
|
||||
//Statusled + ClassControllCamera
|
||||
#define BLINK_GPIO GPIO_NUM_33 // PIN for red board LED, On the board the LED is on the IO2, but it is used for the SD
|
||||
#elif defined(CAMERA_MODEL_AI_THINKER)
|
||||
#define PWDN_GPIO_NUM GPIO_NUM_32
|
||||
#define RESET_GPIO_NUM -1
|
||||
#define XCLK_GPIO_NUM GPIO_NUM_0
|
||||
#define SIOD_GPIO_NUM GPIO_NUM_26
|
||||
#define SIOC_GPIO_NUM GPIO_NUM_27
|
||||
|
||||
//ClassControllCamera
|
||||
#define FLASH_GPIO GPIO_NUM_12 // PIN for flashlight LED
|
||||
#define USE_PWM_LEDFLASH // if __LEDGLOBAL is defined, a global variable is used for LED control, otherwise locally and each time a new
|
||||
|
||||
#elif defined(BOARD_M5STACK_PSRAM) // M5STACK PSRAM PIN Map
|
||||
#define CAM_PIN_PWDN GPIO_NUM_NC
|
||||
#define CAM_PIN_RESET GPIO_NUM_15
|
||||
#define CAM_PIN_XCLK GPIO_NUM_27
|
||||
#define CAM_PIN_SIOD GPIO_NUM_25
|
||||
#define CAM_PIN_SIOC GPIO_NUM_23
|
||||
|
||||
#define CAM_PIN_D7 GPIO_NUM_19
|
||||
#define CAM_PIN_D6 GPIO_NUM_36
|
||||
#define CAM_PIN_D5 GPIO_NUM_18
|
||||
#define CAM_PIN_D4 GPIO_NUM_39
|
||||
#define CAM_PIN_D3 GPIO_NUM_5
|
||||
#define CAM_PIN_D2 GPIO_NUM_34
|
||||
#define CAM_PIN_D1 GPIO_NUM_35
|
||||
#define CAM_PIN_D0 GPIO_NUM_32
|
||||
#define CAM_PIN_VSYNC GPIO_NUM_22
|
||||
#define CAM_PIN_HREF GPIO_NUM_26
|
||||
#define CAM_PIN_PCLK GPIO_NUM_21
|
||||
|
||||
//Statusled + ClassControllCamera
|
||||
#define BLINK_GPIO GPIO_NUM_33 // PIN for red board LED
|
||||
|
||||
//ClassControllCamera
|
||||
#define FLASH_GPIO GPIO_NUM_4 // PIN for flashlight LED
|
||||
#define USE_PWM_LEDFLASH // if __LEDGLOBAL is defined, a global variable is used for LED control, otherwise locally and each time a new
|
||||
|
||||
|
||||
#elif defined(BOARD_ESP32CAM_AITHINKER) // ESP32Cam (AiThinker) PIN Map
|
||||
// SD card (operated with SDMMC peripheral)
|
||||
//-------------------------------------------------
|
||||
#define GPIO_SDCARD_CLK GPIO_NUM_14
|
||||
#define GPIO_SDCARD_CMD GPIO_NUM_15
|
||||
#define GPIO_SDCARD_D0 GPIO_NUM_2
|
||||
#ifndef __SD_USE_ONE_LINE_MODE__
|
||||
#define GPIO_SDCARD_D1 GPIO_NUM_4
|
||||
#define GPIO_SDCARD_D2 GPIO_NUM_12
|
||||
#define GPIO_SDCARD_D3 GPIO_NUM_13
|
||||
#else
|
||||
#define GPIO_SDCARD_D1 GPIO_NUM_NC
|
||||
#define GPIO_SDCARD_D2 GPIO_NUM_NC
|
||||
#define GPIO_SDCARD_D3 GPIO_NUM_13
|
||||
#endif
|
||||
|
||||
#define CAM_PIN_PWDN GPIO_NUM_32
|
||||
#define CAM_PIN_RESET GPIO_NUM_NC //software reset will be performed
|
||||
#define CAM_PIN_XCLK GPIO_NUM_0
|
||||
#define CAM_PIN_SIOD GPIO_NUM_26
|
||||
#define CAM_PIN_SIOC GPIO_NUM_27
|
||||
|
||||
#define CAM_PIN_D7 GPIO_NUM_35
|
||||
#define CAM_PIN_D6 GPIO_NUM_34
|
||||
#define CAM_PIN_D5 GPIO_NUM_39
|
||||
#define CAM_PIN_D4 GPIO_NUM_36
|
||||
#define CAM_PIN_D3 GPIO_NUM_21
|
||||
#define CAM_PIN_D2 GPIO_NUM_19
|
||||
#define CAM_PIN_D1 GPIO_NUM_18
|
||||
#define CAM_PIN_D0 GPIO_NUM_5
|
||||
#define CAM_PIN_VSYNC GPIO_NUM_25
|
||||
#define CAM_PIN_HREF GPIO_NUM_23
|
||||
#define CAM_PIN_PCLK GPIO_NUM_22
|
||||
|
||||
//Statusled + ClassControllCamera
|
||||
#define BLINK_GPIO GPIO_NUM_33 // PIN for red board LED
|
||||
|
||||
//ClassControllCamera
|
||||
#define FLASH_GPIO GPIO_NUM_4 // PIN for flashlight LED
|
||||
#define USE_PWM_LEDFLASH // if __LEDGLOBAL is defined, a global variable is used for LED control, otherwise locally and each time a new
|
||||
#define Y9_GPIO_NUM GPIO_NUM_35
|
||||
#define Y8_GPIO_NUM GPIO_NUM_34
|
||||
#define Y7_GPIO_NUM GPIO_NUM_39
|
||||
#define Y6_GPIO_NUM GPIO_NUM_36
|
||||
#define Y5_GPIO_NUM GPIO_NUM_21
|
||||
#define Y4_GPIO_NUM GPIO_NUM_19
|
||||
#define Y3_GPIO_NUM GPIO_NUM_18
|
||||
#define Y2_GPIO_NUM GPIO_NUM_5
|
||||
#define VSYNC_GPIO_NUM GPIO_NUM_25
|
||||
#define HREF_GPIO_NUM GPIO_NUM_23
|
||||
#define PCLK_GPIO_NUM GPIO_NUM_22
|
||||
|
||||
#else
|
||||
#error "Board not selected"
|
||||
#endif //Board PIN Map
|
||||
#error "Camera model not selected"
|
||||
#endif //camera model
|
||||
|
||||
// ******* Board type
|
||||
#ifdef BOARD_WROVER_KIT // WROVER-KIT PIN Map
|
||||
|
||||
#define CAM_PIN_PWDN -1 //power down is not used
|
||||
#define CAM_PIN_RESET -1 //software reset will be performed
|
||||
#define CAM_PIN_XCLK 21
|
||||
#define CAM_PIN_SIOD 26
|
||||
#define CAM_PIN_SIOC 27
|
||||
|
||||
#define CAM_PIN_D7 35
|
||||
#define CAM_PIN_D6 34
|
||||
#define CAM_PIN_D5 39
|
||||
#define CAM_PIN_D4 36
|
||||
#define CAM_PIN_D3 19
|
||||
#define CAM_PIN_D2 18
|
||||
#define CAM_PIN_D1 5
|
||||
#define CAM_PIN_D0 4
|
||||
#define CAM_PIN_VSYNC 25
|
||||
#define CAM_PIN_HREF 23
|
||||
#define CAM_PIN_PCLK 22
|
||||
|
||||
#endif //// WROVER-KIT PIN Map
|
||||
|
||||
|
||||
#ifdef BOARD_ESP32CAM_AITHINKER // ESP32Cam (AiThinker) PIN Map
|
||||
|
||||
#define CAM_PIN_PWDN 32
|
||||
#define CAM_PIN_RESET -1 //software reset will be performed
|
||||
#define CAM_PIN_XCLK 0
|
||||
#define CAM_PIN_SIOD 26
|
||||
#define CAM_PIN_SIOC 27
|
||||
|
||||
#define CAM_PIN_D7 35
|
||||
#define CAM_PIN_D6 34
|
||||
#define CAM_PIN_D5 39
|
||||
#define CAM_PIN_D4 36
|
||||
#define CAM_PIN_D3 21
|
||||
#define CAM_PIN_D2 19
|
||||
#define CAM_PIN_D1 18
|
||||
#define CAM_PIN_D0 5
|
||||
#define CAM_PIN_VSYNC 25
|
||||
#define CAM_PIN_HREF 23
|
||||
#define CAM_PIN_PCLK 22
|
||||
|
||||
#endif // ESP32Cam (AiThinker) PIN Map
|
||||
|
||||
// ******* LED definition
|
||||
#ifdef USE_PWM_LEDFLASH
|
||||
|
||||
//// PWM für Flash-LED
|
||||
#define LEDC_TIMER LEDC_TIMER_1 // LEDC_TIMER_0
|
||||
#define LEDC_MODE LEDC_LOW_SPEED_MODE
|
||||
@@ -326,7 +331,6 @@
|
||||
|
||||
#endif //USE_PWM_LEDFLASH
|
||||
|
||||
|
||||
//softAP
|
||||
#ifdef ENABLE_SOFTAP
|
||||
#define EXAMPLE_ESP_WIFI_SSID "AI-on-the-Edge"
|
||||
|
||||
@@ -11,13 +11,10 @@
|
||||
#include "esp_chip_info.h"
|
||||
|
||||
// SD-Card ////////////////////
|
||||
#include "sdcard_init.h"
|
||||
#include "esp_vfs_fat.h"
|
||||
#include "ffconf.h"
|
||||
#include "driver/sdmmc_host.h"
|
||||
|
||||
#if (ESP_IDF_VERSION <= ESP_IDF_VERSION_VAL(5, 1, 2))
|
||||
#include "sdcard_init.h"
|
||||
#endif
|
||||
///////////////////////////////
|
||||
|
||||
#include "ClassLogFile.h"
|
||||
@@ -94,10 +91,10 @@ static const char *TAG = "MAIN";
|
||||
|
||||
#define MOUNT_POINT "/sdcard"
|
||||
|
||||
|
||||
bool Init_NVS_SDCard()
|
||||
{
|
||||
esp_err_t ret = nvs_flash_init();
|
||||
|
||||
if (ret == ESP_ERR_NVS_NO_FREE_PAGES) {
|
||||
ESP_ERROR_CHECK(nvs_flash_erase());
|
||||
ret = nvs_flash_init();
|
||||
@@ -111,23 +108,12 @@ bool Init_NVS_SDCard()
|
||||
// Modify slot_config.gpio_cd and slot_config.gpio_wp if your board has these signals.
|
||||
sdmmc_slot_config_t slot_config = SDMMC_SLOT_CONFIG_DEFAULT();
|
||||
|
||||
// Set bus width to use:
|
||||
#ifdef __SD_USE_ONE_LINE_MODE__
|
||||
slot_config.width = 1;
|
||||
#ifdef SOC_SDMMC_USE_GPIO_MATRIX
|
||||
slot_config.clk = GPIO_SDCARD_CLK;
|
||||
slot_config.cmd = GPIO_SDCARD_CMD;
|
||||
slot_config.d0 = GPIO_SDCARD_D0;
|
||||
#endif
|
||||
|
||||
#else
|
||||
slot_config.width = 4;
|
||||
#ifdef SOC_SDMMC_USE_GPIO_MATRIX
|
||||
slot_config.d1 = GPIO_SDCARD_D1;
|
||||
slot_config.d2 = GPIO_SDCARD_D2;
|
||||
slot_config.d3 = GPIO_SDCARD_D3;
|
||||
#endif
|
||||
#endif
|
||||
// Set bus width to use:
|
||||
#ifdef __SD_USE_ONE_LINE_MODE__
|
||||
slot_config.width = 1;
|
||||
#else
|
||||
slot_config.width = 4;
|
||||
#endif
|
||||
|
||||
// Enable internal pullups on enabled pins. The internal pullups
|
||||
// are insufficient however, please make sure 10k external pullups are
|
||||
@@ -139,7 +125,7 @@ bool Init_NVS_SDCard()
|
||||
// dies führt jedoch bei schlechten Kopien des AI_THINKER Boards
|
||||
// zu Problemen mit der SD Initialisierung und eventuell sogar zur reboot-loops.
|
||||
// Um diese Probleme zu kompensieren, wird der PullUp manuel gesetzt.
|
||||
gpio_set_pull_mode(GPIO_SDCARD_D3, GPIO_PULLUP_ONLY); // HS2_D3
|
||||
gpio_set_pull_mode(GPIO_NUM_13, GPIO_PULLUP_ONLY); // HS2_D3
|
||||
|
||||
// Options for mounting the filesystem.
|
||||
// If format_if_mount_failed is set to true, SD card will be partitioned and
|
||||
@@ -158,11 +144,7 @@ bool Init_NVS_SDCard()
|
||||
// Note: esp_vfs_fat_sdmmc_mount is an all-in-one convenience function.
|
||||
// Please check its source code and implement error recovery when developing
|
||||
// production applications.
|
||||
#if (ESP_IDF_VERSION <= ESP_IDF_VERSION_VAL(5, 1, 2))
|
||||
ret = esp_vfs_fat_sdmmc_mount_mh(mount_point, &host, &slot_config, &mount_config, &card);
|
||||
#else
|
||||
ret = esp_vfs_fat_sdmmc_mount(mount_point, &host, &slot_config, &mount_config, &card);
|
||||
#endif
|
||||
|
||||
if (ret != ESP_OK) {
|
||||
if (ret == ESP_FAIL) {
|
||||
@@ -185,6 +167,7 @@ bool Init_NVS_SDCard()
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
extern "C" void app_main(void)
|
||||
{
|
||||
//#ifdef CONFIG_HEAP_TRACING_STANDALONE
|
||||
@@ -208,6 +191,7 @@ extern "C" void app_main(void)
|
||||
// ********************************************
|
||||
ESP_LOGI(TAG, "\n\n\n\n================ Start app_main =================");
|
||||
|
||||
|
||||
// Init SD card
|
||||
// ********************************************
|
||||
if (!Init_NVS_SDCard())
|
||||
@@ -228,6 +212,7 @@ extern "C" void app_main(void)
|
||||
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "==================== Start ======================");
|
||||
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "=================================================");
|
||||
|
||||
|
||||
// Init external PSRAM
|
||||
// ********************************************
|
||||
esp_err_t PSRAMStatus = esp_psram_init();
|
||||
@@ -276,6 +261,7 @@ extern "C" void app_main(void)
|
||||
ESP_LOGD(TAG, "After camera initialization: sleep for: %ldms", (long) xDelay * CONFIG_FREERTOS_HZ/portTICK_PERIOD_MS);
|
||||
vTaskDelay( xDelay );
|
||||
|
||||
|
||||
// Check camera init
|
||||
// ********************************************
|
||||
if (camStatus != ESP_OK) { // Camera init failed, retry to init
|
||||
@@ -324,6 +310,7 @@ extern "C" void app_main(void)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// SD card: basic R/W check
|
||||
// ********************************************
|
||||
int iSDCardStatus = SDCardCheckRW();
|
||||
@@ -348,10 +335,12 @@ extern "C" void app_main(void)
|
||||
// ********************************************
|
||||
setupTime(); // NTP time service: Status of time synchronization will be checked after every round (server_tflite.cpp)
|
||||
|
||||
|
||||
// Set CPU Frequency
|
||||
// ********************************************
|
||||
setCpuFrequency();
|
||||
|
||||
|
||||
// SD card: Create further mandatory directories (if not already existing)
|
||||
// Correct creation of these folders will be checked with function "SDCardCheckFolderFilePresence"
|
||||
// ********************************************
|
||||
@@ -443,6 +432,7 @@ extern "C" void app_main(void)
|
||||
ESP_LOGD(TAG, "main: sleep for: %ldms", (long) xDelay * CONFIG_FREERTOS_HZ/portTICK_PERIOD_MS);
|
||||
vTaskDelay( xDelay );
|
||||
|
||||
|
||||
// manual reset the time
|
||||
// ********************************************
|
||||
if (!time_manual_reset_sync())
|
||||
@@ -450,6 +440,8 @@ extern "C" void app_main(void)
|
||||
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Manual Time Sync failed during startup" );
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Set log level for wifi component to WARN level (default: INFO; only relevant for serial console)
|
||||
// ********************************************
|
||||
esp_log_level_set("wifi", ESP_LOG_WARN);
|
||||
@@ -473,6 +465,8 @@ extern "C" void app_main(void)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
// Print Device info
|
||||
// ********************************************
|
||||
esp_chip_info_t chipInfo;
|
||||
@@ -528,19 +522,9 @@ extern "C" void app_main(void)
|
||||
}
|
||||
}
|
||||
|
||||
void migrateConfiguration(void) {
|
||||
std::vector<string> splitted;
|
||||
bool migrated = false;
|
||||
|
||||
bool CamZoom_found = false;
|
||||
int CamZoom_lines = 0;
|
||||
bool CamZoom_value = false;
|
||||
int CamZoomSize_lines = 0;
|
||||
int CamZoomSize_value = 0;
|
||||
int CamZoomOffsetX_lines = 0;
|
||||
int CamZoomOffsetX_value = 0;
|
||||
int CamZoomOffsetY_lines = 0;
|
||||
int CamZoomOffsetY_value = 0;
|
||||
void migrateConfiguration(void) {
|
||||
bool migrated = false;
|
||||
|
||||
if (!FileExists(CONFIG_FILE)) {
|
||||
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Config file seems to be missing!");
|
||||
@@ -548,24 +532,20 @@ void migrateConfiguration(void) {
|
||||
}
|
||||
|
||||
std::string section = "";
|
||||
std::ifstream ifs(CONFIG_FILE);
|
||||
std::string content((std::istreambuf_iterator<char>(ifs)), (std::istreambuf_iterator<char>()));
|
||||
std::ifstream ifs(CONFIG_FILE);
|
||||
std::string content((std::istreambuf_iterator<char>(ifs)), (std::istreambuf_iterator<char>()));
|
||||
|
||||
/* Split config file it array of lines */
|
||||
std::vector<std::string> configLines = splitString(content);
|
||||
|
||||
/* Process each line */
|
||||
for (int i = 0; i < configLines.size(); i++) {
|
||||
// ESP_LOGI(TAG, "Line %d: %s", i, configLines[i].c_str());
|
||||
//ESP_LOGI(TAG, "Line %d: %s", i, configLines[i].c_str());
|
||||
|
||||
if (configLines[i].find("[") != std::string::npos) {
|
||||
// Start of new section
|
||||
if (configLines[i].find("[") != std::string::npos) { // Start of new section
|
||||
section = configLines[i];
|
||||
replaceString(section, ";", "", false); // Remove possible semicolon (just for the string comparison)
|
||||
// ESP_LOGI(TAG, "New section: %s", section.c_str());
|
||||
}
|
||||
else {
|
||||
splitted = ZerlegeZeile(configLines[i]);
|
||||
//ESP_LOGI(TAG, "New section: %s", section.c_str());
|
||||
}
|
||||
|
||||
/* Migrate parameters as needed
|
||||
@@ -583,154 +563,115 @@ void migrateConfiguration(void) {
|
||||
}
|
||||
|
||||
if (section == "[MakeImage]" || section == "[TakeImage]") {
|
||||
if ((isInString(configLines[i], "Brightness")) && (!isInString(configLines[i], "CamBrightness"))) {
|
||||
migrated = migrated | replaceString(configLines[i], "Brightness", "CamBrightness");
|
||||
}
|
||||
else if ((isInString(configLines[i], "Contrast")) && (!isInString(configLines[i], "CamContrast"))) {
|
||||
migrated = migrated | replaceString(configLines[i], "Contrast", "CamContrast");
|
||||
}
|
||||
else if ((isInString(configLines[i], "Saturation")) && (!isInString(configLines[i], "CamSaturation"))) {
|
||||
migrated = migrated | replaceString(configLines[i], "Saturation", "CamSaturation");
|
||||
}
|
||||
else if ((isInString(configLines[i], "Sharpness")) && (!isInString(configLines[i], "CamSharpness")) && (!isInString(configLines[i], "CamAutoSharpness"))) {
|
||||
migrated = migrated | replaceString(configLines[i], "Sharpness", "CamSharpness");
|
||||
}
|
||||
else if ((isInString(configLines[i], "Aec2")) && (!isInString(configLines[i], "CamAec")) && (!isInString(configLines[i], "CamAec2"))) {
|
||||
migrated = migrated | replaceString(configLines[i], "Aec2", "CamAec2");
|
||||
}
|
||||
else if ((isInString(configLines[i], "Zoom")) && (!isInString(configLines[i], "CamZoom")) && (!isInString(configLines[i], "ZoomMode")) && (!isInString(configLines[i], "ZoomOffsetX")) && (!isInString(configLines[i], "ZoomOffsetY"))) {
|
||||
CamZoom_lines = i;
|
||||
CamZoom_value = alphanumericToBoolean(splitted[1]);
|
||||
CamZoom_found = true;
|
||||
}
|
||||
else if ((isInString(configLines[i], "ZoomMode")) && (!isInString(configLines[i], "CamZoom"))) {
|
||||
CamZoomSize_lines = i;
|
||||
if (isStringNumeric(splitted[1])) {
|
||||
CamZoomSize_value = std::stof(splitted[1]);
|
||||
}
|
||||
CamZoom_found = true;
|
||||
}
|
||||
else if ((isInString(configLines[i], "ZoomOffsetX")) && (!isInString(configLines[i], "CamZoom")) && (!isInString(configLines[i], "ZoomOffsetY"))) {
|
||||
CamZoomOffsetX_lines = i;
|
||||
if (isStringNumeric(splitted[1])) {
|
||||
CamZoomOffsetX_value = std::stof(splitted[1]);
|
||||
}
|
||||
CamZoom_found = true;
|
||||
}
|
||||
else if ((isInString(configLines[i], "ZoomOffsetY")) && (!isInString(configLines[i], "CamZoom")) && (!isInString(configLines[i], "ZoomOffsetX"))) {
|
||||
CamZoomOffsetY_lines = i;
|
||||
if (isStringNumeric(splitted[1])) {
|
||||
CamZoomOffsetY_value = std::stof(splitted[1]);
|
||||
}
|
||||
CamZoom_found = true;
|
||||
}
|
||||
else {
|
||||
migrated = migrated | replaceString(configLines[i], "LogImageLocation", "RawImagesLocation");
|
||||
migrated = migrated | replaceString(configLines[i], "LogfileRetentionInDays", "RawImagesRetention");
|
||||
migrated = migrated | replaceString(configLines[i], "LogImageLocation", "RawImagesLocation");
|
||||
migrated = migrated | replaceString(configLines[i], "LogfileRetentionInDays", "RawImagesRetention");
|
||||
|
||||
migrated = migrated | replaceString(configLines[i], ";Demo = true", ";Demo = false"); // Set it to its default value
|
||||
migrated = migrated | replaceString(configLines[i], ";Demo", "Demo"); // Enable it
|
||||
migrated = migrated | replaceString(configLines[i], ";Demo = true", ";Demo = false"); // Set it to its default value
|
||||
migrated = migrated | replaceString(configLines[i], ";Demo", "Demo"); // Enable it
|
||||
|
||||
migrated = migrated | replaceString(configLines[i], "ImageQuality", "CamQuality");
|
||||
migrated = migrated | replaceString(configLines[i], "AutoExposureLevel", "CamAeLevel");
|
||||
migrated = migrated | replaceString(configLines[i], "FixedExposure", "CamAec");
|
||||
|
||||
migrated = migrated | replaceString(configLines[i], "ImageSize", ";UNUSED_PARAMETER"); // This parameter is no longer used
|
||||
migrated = migrated | replaceString(configLines[i], "Grayscale", ";UNUSED_PARAMETER"); // This parameter is no longer used
|
||||
migrated = migrated | replaceString(configLines[i], "Negative", ";UNUSED_PARAMETER"); // This parameter is no longer used
|
||||
}
|
||||
migrated = migrated | replaceString(configLines[i], ";FixedExposure = true", ";FixedExposure = false"); // Set it to its default value
|
||||
migrated = migrated | replaceString(configLines[i], ";FixedExposure", "FixedExposure"); // Enable it
|
||||
}
|
||||
else if (section == "[Alignment]") {
|
||||
migrated = migrated | replaceString(configLines[i], "InitialMirror", ";UNUSED_PARAMETER"); // This parameter is no longer used
|
||||
migrated = migrated | replaceString(configLines[i], ";InitialMirror", ";UNUSED_PARAMETER"); // This parameter is no longer used
|
||||
migrated = migrated | replaceString(configLines[i], "FlipImageSize", ";UNUSED_PARAMETER"); // This parameter is no longer used
|
||||
migrated = migrated | replaceString(configLines[i], ";FlipImageSize", ";UNUSED_PARAMETER"); // This parameter is no longer used
|
||||
|
||||
if (section == "[Alignment]") {
|
||||
migrated = migrated | replaceString(configLines[i], ";InitialMirror = true", ";InitialMirror = false"); // Set it to its default value
|
||||
migrated = migrated | replaceString(configLines[i], ";InitialMirror", "InitialMirror"); // Enable it
|
||||
|
||||
migrated = migrated | replaceString(configLines[i], ";FlipImageSize = true", ";FlipImageSize = false"); // Set it to its default value
|
||||
migrated = migrated | replaceString(configLines[i], ";FlipImageSize", "FlipImageSize"); // Enable it
|
||||
}
|
||||
else if (section == "[Digits]") {
|
||||
|
||||
if (section == "[Digits]") {
|
||||
migrated = migrated | replaceString(configLines[i], "LogImageLocation", "ROIImagesLocation");
|
||||
migrated = migrated | replaceString(configLines[i], "LogfileRetentionInDays", "ROIImagesRetention");
|
||||
}
|
||||
else if (section == "[Analog]") {
|
||||
|
||||
if (section == "[Analog]") {
|
||||
migrated = migrated | replaceString(configLines[i], "LogImageLocation", "ROIImagesLocation");
|
||||
migrated = migrated | replaceString(configLines[i], "LogfileRetentionInDays", "ROIImagesRetention");
|
||||
migrated = migrated | replaceString(configLines[i], "ExtendedResolution", ";UNUSED_PARAMETER"); // This parameter is no longer used
|
||||
}
|
||||
else if (section == "[PostProcessing]") {
|
||||
|
||||
if (section == "[PostProcessing]") {
|
||||
migrated = migrated | replaceString(configLines[i], ";PreValueUse = true", ";PreValueUse = false"); // Set it to its default value
|
||||
migrated = migrated | replaceString(configLines[i], ";PreValueUse", "PreValueUse"); // Enable it
|
||||
|
||||
/* AllowNegativeRates has a <NUMBER> as prefix! */
|
||||
if (isInString(configLines[i], "AllowNegativeRates") && isInString(configLines[i], ";")) {
|
||||
// It is the parameter "AllowNegativeRates" and it is commented out
|
||||
if (isInString(configLines[i], "AllowNegativeRates") && isInString(configLines[i], ";")) { // It is the parameter "AllowNegativeRates" and it is commented out
|
||||
migrated = migrated | replaceString(configLines[i], "true", "false"); // Set it to its default value
|
||||
migrated = migrated | replaceString(configLines[i], ";", ""); // Enable it
|
||||
migrated = migrated | replaceString(configLines[i], ";", ""); // Enable it
|
||||
}
|
||||
|
||||
/* IgnoreLeadingNaN has a <NUMBER> as prefix! */
|
||||
else if (isInString(configLines[i], "IgnoreLeadingNaN") && isInString(configLines[i], ";")) {
|
||||
// It is the parameter "IgnoreLeadingNaN" and it is commented out
|
||||
if (isInString(configLines[i], "IgnoreLeadingNaN") && isInString(configLines[i], ";")) { // It is the parameter "IgnoreLeadingNaN" and it is commented out
|
||||
migrated = migrated | replaceString(configLines[i], "true", "false"); // Set it to its default value
|
||||
migrated = migrated | replaceString(configLines[i], ";", ""); // Enable it
|
||||
migrated = migrated | replaceString(configLines[i], ";", ""); // Enable it
|
||||
}
|
||||
|
||||
/* ExtendedResolution has a <NUMBER> as prefix! */
|
||||
else if (isInString(configLines[i], "ExtendedResolution") && isInString(configLines[i], ";")) {
|
||||
// It is the parameter "ExtendedResolution" and it is commented out
|
||||
if (isInString(configLines[i], "ExtendedResolution") && isInString(configLines[i], ";")) { // It is the parameter "ExtendedResolution" and it is commented out
|
||||
migrated = migrated | replaceString(configLines[i], "true", "false"); // Set it to its default value
|
||||
migrated = migrated | replaceString(configLines[i], ";", ""); // Enable it
|
||||
migrated = migrated | replaceString(configLines[i], ";", ""); // Enable it
|
||||
}
|
||||
else {
|
||||
migrated = migrated | replaceString(configLines[i], ";PreValueUse = true", ";PreValueUse = false"); // Set it to its default value
|
||||
migrated = migrated | replaceString(configLines[i], ";PreValueUse", "PreValueUse"); // Enable it
|
||||
|
||||
migrated = migrated | replaceString(configLines[i], ";ErrorMessage = true", ";ErrorMessage = false"); // Set it to its default value
|
||||
migrated = migrated | replaceString(configLines[i], ";ErrorMessage", "ErrorMessage"); // Enable it
|
||||
migrated = migrated | replaceString(configLines[i], ";ErrorMessage = true", ";ErrorMessage = false"); // Set it to its default value
|
||||
migrated = migrated | replaceString(configLines[i], ";ErrorMessage", "ErrorMessage"); // Enable it
|
||||
|
||||
migrated = migrated | replaceString(configLines[i], ";CheckDigitIncreaseConsistency = true", ";CheckDigitIncreaseConsistency = false"); // Set it to its default value
|
||||
migrated = migrated | replaceString(configLines[i], ";CheckDigitIncreaseConsistency", "CheckDigitIncreaseConsistency"); // Enable it
|
||||
}
|
||||
migrated = migrated | replaceString(configLines[i], ";CheckDigitIncreaseConsistency = true", ";CheckDigitIncreaseConsistency = false"); // Set it to its default value
|
||||
migrated = migrated | replaceString(configLines[i], ";CheckDigitIncreaseConsistency", "CheckDigitIncreaseConsistency"); // Enable it
|
||||
}
|
||||
else if (section == "[MQTT]") {
|
||||
migrated = migrated | replaceString(configLines[i], "SetRetainFlag", "RetainMessages"); // First rename it, enable it with its default value
|
||||
|
||||
if (section == "[MQTT]") {
|
||||
migrated = migrated | replaceString(configLines[i], "SetRetainFlag", "RetainMessages"); // First rename it, enable it with its default value
|
||||
migrated = migrated | replaceString(configLines[i], ";RetainMessages = true", ";RetainMessages = false"); // Set it to its default value
|
||||
migrated = migrated | replaceString(configLines[i], ";RetainMessages", "RetainMessages"); // Enable it
|
||||
migrated = migrated | replaceString(configLines[i], ";RetainMessages", "RetainMessages"); // Enable it
|
||||
|
||||
migrated = migrated | replaceString(configLines[i], ";HomeassistantDiscovery = true", ";HomeassistantDiscovery = false"); // Set it to its default value
|
||||
migrated = migrated | replaceString(configLines[i], ";HomeassistantDiscovery", "HomeassistantDiscovery"); // Enable it
|
||||
migrated = migrated | replaceString(configLines[i], ";HomeassistantDiscovery", "HomeassistantDiscovery"); // Enable it
|
||||
|
||||
// only if string starts with "Topic" (Was the naming in very old version)
|
||||
if (configLines[i].rfind("Topic", 0) != std::string::npos) {
|
||||
if (configLines[i].rfind("Topic", 0) != std::string::npos) // only if string starts with "Topic" (Was the naming in very old version)
|
||||
{
|
||||
migrated = migrated | replaceString(configLines[i], "Topic", "MainTopic");
|
||||
}
|
||||
}
|
||||
else if (section == "[InfluxDB]") {
|
||||
|
||||
if (section == "[InfluxDB]") {
|
||||
/* Fieldname has a <NUMBER> as prefix! */
|
||||
if (isInString(configLines[i], "Fieldname")) {
|
||||
// It is the parameter "Fieldname"
|
||||
if (isInString(configLines[i], "Fieldname")) { // It is the parameter "Fieldname"
|
||||
migrated = migrated | replaceString(configLines[i], "Fieldname", "Field"); // Rename it to Field
|
||||
}
|
||||
}
|
||||
else if (section == "[InfluxDBv2]") {
|
||||
|
||||
if (section == "[InfluxDBv2]") {
|
||||
/* Fieldname has a <NUMBER> as prefix! */
|
||||
if (isInString(configLines[i], "Fieldname")) {
|
||||
// It is the parameter "Fieldname"
|
||||
if (isInString(configLines[i], "Fieldname")) { // It is the parameter "Fieldname"
|
||||
migrated = migrated | replaceString(configLines[i], "Fieldname", "Field"); // Rename it to Field
|
||||
}
|
||||
/* Database got renamed to Bucket! */
|
||||
else if (isInString(configLines[i], "Database")) {
|
||||
// It is the parameter "Database"
|
||||
if (isInString(configLines[i], "Database")) { // It is the parameter "Database"
|
||||
migrated = migrated | replaceString(configLines[i], "Database", "Bucket"); // Rename it to Bucket
|
||||
}
|
||||
}
|
||||
else if (section == "[GPIO]") {
|
||||
|
||||
if (section == "[GPIO]") {
|
||||
|
||||
}
|
||||
else if (section == "[DataLogging]") {
|
||||
|
||||
if (section == "[DataLogging]") {
|
||||
migrated = migrated | replaceString(configLines[i], "DataLogRetentionInDays", "DataFilesRetention");
|
||||
/* DataLogActive is true by default! */
|
||||
migrated = migrated | replaceString(configLines[i], ";DataLogActive = false", ";DataLogActive = true"); // Set it to its default value
|
||||
migrated = migrated | replaceString(configLines[i], ";DataLogActive", "DataLogActive"); // Enable it
|
||||
migrated = migrated | replaceString(configLines[i], ";DataLogActive", "DataLogActive"); // Enable it
|
||||
}
|
||||
else if (section == "[AutoTimer]") {
|
||||
|
||||
if (section == "[AutoTimer]") {
|
||||
migrated = migrated | replaceString(configLines[i], "Intervall", "Interval");
|
||||
migrated = migrated | replaceString(configLines[i], ";AutoStart = true", ";AutoStart = false"); // Set it to its default value
|
||||
migrated = migrated | replaceString(configLines[i], ";AutoStart", "AutoStart"); // Enable it
|
||||
migrated = migrated | replaceString(configLines[i], ";AutoStart", "AutoStart"); // Enable it
|
||||
|
||||
}
|
||||
else if (section == "[Debug]") {
|
||||
|
||||
if (section == "[Debug]") {
|
||||
migrated = migrated | replaceString(configLines[i], "Logfile ", "LogLevel "); // Whitespace needed so it does not match `LogfileRetentionInDays`
|
||||
/* LogLevel (resp. LogFile) was originally a boolean, but we switched it to an int
|
||||
* For both cases (true/false), we set it to level 2 (WARNING) */
|
||||
@@ -738,107 +679,33 @@ void migrateConfiguration(void) {
|
||||
migrated = migrated | replaceString(configLines[i], "LogLevel = false", "LogLevel = 2");
|
||||
migrated = migrated | replaceString(configLines[i], "LogfileRetentionInDays", "LogfilesRetention");
|
||||
}
|
||||
else if (section == "[System]") {
|
||||
|
||||
if (section == "[System]") {
|
||||
migrated = migrated | replaceString(configLines[i], "RSSIThreashold", "RSSIThreshold");
|
||||
migrated = migrated | replaceString(configLines[i], "AutoAdjustSummertime", ";UNUSED_PARAMETER"); // This parameter is no longer used
|
||||
|
||||
migrated = migrated | replaceString(configLines[i], ";SetupMode = true", ";SetupMode = false"); // Set it to its default value
|
||||
migrated = migrated | replaceString(configLines[i], ";SetupMode", "SetupMode"); // Enable it
|
||||
migrated = migrated | replaceString(configLines[i], ";SetupMode", "SetupMode"); // Enable it
|
||||
}
|
||||
}
|
||||
|
||||
if (CamZoom_found == true) {
|
||||
if (CamZoomSize_value == 0) {
|
||||
// mode0
|
||||
// 1600 - 640 = 960 / 2 = max-Offset (+/-) 480
|
||||
// 1200 - 480 = 720 / 2 = max-Offset (+/-) 360
|
||||
|
||||
if (CamZoomOffsetX_value > 960) {
|
||||
CamZoomOffsetX_value = 960;
|
||||
}
|
||||
else {
|
||||
CamZoomOffsetX_value = (floor((CamZoomOffsetX_value - 480) / 8) * 8);
|
||||
}
|
||||
|
||||
if (CamZoomOffsetY_value > 720) {
|
||||
CamZoomOffsetY_value = 720;
|
||||
}
|
||||
else {
|
||||
CamZoomOffsetY_value = (floor((CamZoomOffsetY_value - 360) / 8) * 8);
|
||||
}
|
||||
|
||||
CamZoomSize_value = 29;
|
||||
}
|
||||
else {
|
||||
// mode1
|
||||
// 800 - 640 = 160 / 2 = max-Offset (+/-) 80
|
||||
// 600 - 480 = 120 / 2 = max-Offset (+/-) 60
|
||||
|
||||
if (CamZoomOffsetX_value > 160) {
|
||||
CamZoomOffsetX_value = 160;
|
||||
}
|
||||
else {
|
||||
CamZoomOffsetX_value = (floor(((CamZoomOffsetX_value - 80) * 2) / 8) * 8);
|
||||
}
|
||||
|
||||
if (CamZoomOffsetY_value > 120) {
|
||||
CamZoomOffsetY_value = 120;
|
||||
}
|
||||
else {
|
||||
CamZoomOffsetY_value = (floor(((CamZoomOffsetY_value - 60) * 2) / 8) * 8);
|
||||
}
|
||||
|
||||
CamZoomSize_value = 9;
|
||||
}
|
||||
|
||||
if (CamZoom_lines > 0) {
|
||||
if (CamZoom_value) {
|
||||
configLines[CamZoom_lines] = ("CamZoom = true");
|
||||
}
|
||||
else {
|
||||
configLines[CamZoom_lines] = ("CamZoom = false");
|
||||
}
|
||||
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Migrated Configfile line 'Zoom' to 'CamZoom'");
|
||||
migrated = true;
|
||||
}
|
||||
if (CamZoomSize_lines > 0) {
|
||||
configLines[CamZoomSize_lines] = ("CamZoomSize = " + std::to_string(CamZoomSize_value));
|
||||
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Migrated Configfile line 'ZoomMode' to 'CamZoomSize'");
|
||||
migrated = true;
|
||||
}
|
||||
if (CamZoomOffsetX_lines > 0) {
|
||||
configLines[CamZoomOffsetX_lines] = ("CamZoomOffsetX = " + std::to_string(CamZoomOffsetX_value));
|
||||
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Migrated Configfile line 'ZoomOffsetX' to 'CamZoomOffsetX'");
|
||||
migrated = true;
|
||||
}
|
||||
if (CamZoomOffsetY_lines > 0) {
|
||||
configLines[CamZoomOffsetY_lines] = ("CamZoomOffsetY = " + std::to_string(CamZoomOffsetY_value));
|
||||
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Migrated Configfile line 'ZoomOffsetY' to 'CamZoomOffsetY'");
|
||||
migrated = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (migrated) {
|
||||
// At least one replacement happened
|
||||
if (!RenameFile(CONFIG_FILE, CONFIG_FILE_BACKUP)) {
|
||||
if (migrated) { // At least one replacement happened
|
||||
if (! RenameFile(CONFIG_FILE, CONFIG_FILE_BACKUP)) {
|
||||
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Failed to create backup of Config file!");
|
||||
return;
|
||||
}
|
||||
|
||||
FILE *pfile = fopen(CONFIG_FILE, "w");
|
||||
|
||||
FILE* pfile = fopen(CONFIG_FILE, "w");
|
||||
for (int i = 0; i < configLines.size(); i++) {
|
||||
if (!isInString(configLines[i], ";UNUSED_PARAMETER")) {
|
||||
fwrite(configLines[i].c_str(), configLines[i].length(), 1, pfile);
|
||||
fwrite("\n", 1, 1, pfile);
|
||||
}
|
||||
fwrite(configLines[i].c_str() , configLines[i].length(), 1, pfile);
|
||||
fwrite("\n" , 1, 1, pfile);
|
||||
}
|
||||
|
||||
fclose(pfile);
|
||||
LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Config file migrated. Saved backup to " + string(CONFIG_FILE_BACKUP));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::vector<std::string> splitString(const std::string& str) {
|
||||
std::vector<std::string> tokens;
|
||||
|
||||
@@ -852,6 +719,8 @@ std::vector<std::string> splitString(const std::string& str) {
|
||||
return tokens;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*bool replace_all(std::string& s, std::string const& toReplace, std::string const& replaceWith) {
|
||||
std::string buf;
|
||||
std::size_t pos = 0;
|
||||
@@ -879,10 +748,11 @@ std::vector<std::string> splitString(const std::string& str) {
|
||||
return found;
|
||||
}*/
|
||||
|
||||
|
||||
bool setCpuFrequency(void) {
|
||||
ConfigFile configFile = ConfigFile(CONFIG_FILE);
|
||||
string cpuFrequency = "160";
|
||||
esp_pm_config_t pm_config;
|
||||
esp_pm_config_esp32_t pm_config;
|
||||
|
||||
if (!configFile.ConfigFileExists()){
|
||||
LogFile.WriteToFile(ESP_LOG_WARN, TAG, "No ConfigFile defined - exit setCpuFrequency()!");
|
||||
@@ -894,6 +764,7 @@ bool setCpuFrequency(void) {
|
||||
bool disabledLine = false;
|
||||
bool eof = false;
|
||||
|
||||
|
||||
/* Load config from config file */
|
||||
while ((!configFile.GetNextParagraph(line, disabledLine, eof) ||
|
||||
(line.compare("[System]") != 0)) && !eof) {}
|
||||
|
||||
@@ -357,7 +357,7 @@ esp_err_t img_tmp_virtual_handler(httpd_req_t *req)
|
||||
if (filetosend == "raw.jpg")
|
||||
return GetRawJPG(req);
|
||||
|
||||
// Serve alg.jpg, alg_roi.jpg or digit and analog ROIs
|
||||
// Serve alg.jpg, alg_roi.jpg or digital and analog ROIs
|
||||
if (ESP_OK == GetJPG(filetosend, req))
|
||||
return ESP_OK;
|
||||
|
||||
@@ -451,7 +451,7 @@ void register_server_main_uri(httpd_handle_t server, const char *base_path)
|
||||
httpd_handle_t start_webserver(void)
|
||||
{
|
||||
httpd_handle_t server = NULL;
|
||||
httpd_config_t config = HTTPD_DEFAULT_CONFIG();
|
||||
httpd_config_t config = { };
|
||||
|
||||
config.task_priority = tskIDLE_PRIORITY+3; // previously -> 2022-12-11: tskIDLE_PRIORITY+1; 2021-09-24: tskIDLE_PRIORITY+5
|
||||
config.stack_size = 12288; // previously -> 2023-01-02: 32768
|
||||
@@ -459,7 +459,7 @@ httpd_handle_t start_webserver(void)
|
||||
config.server_port = 80;
|
||||
config.ctrl_port = 32768;
|
||||
config.max_open_sockets = 5; //20210921 --> previously 7
|
||||
config.max_uri_handlers = 40; // Make sure this fits all URI handlers. Memory usage in bytes: 6*max_uri_handlers
|
||||
config.max_uri_handlers = 39; // previously 24, 20220511: 35, 20221220: 37, 2023-01-02:38
|
||||
config.max_resp_headers = 8;
|
||||
config.backlog_conn = 5;
|
||||
config.lru_purge_enable = true; // this cuts old connections if new ones are needed.
|
||||
|
||||
@@ -19,8 +19,7 @@
|
||||
|
||||
[common:esp32-idf]
|
||||
extends = common:idf
|
||||
; PlatformIO releases, see https://github.com/platformio/platform-espressif32/releases
|
||||
platform = platformio/espressif32 @ 6.9.0
|
||||
platform = platformio/espressif32 @ 6.5.0
|
||||
framework = espidf
|
||||
lib_deps =
|
||||
${common:idf.lib_deps}
|
||||
@@ -30,6 +29,7 @@
|
||||
-DUSE_ESP32
|
||||
-DUSE_ESP32_FRAMEWORK_ESP_IDF
|
||||
|
||||
|
||||
[flags:runtime]
|
||||
build_flags =
|
||||
-Wno-nonnull-compare
|
||||
@@ -46,7 +46,6 @@
|
||||
;-Wshadow-compatible-local
|
||||
-fno-exceptions
|
||||
|
||||
|
||||
; The main env - default
|
||||
[env:esp32cam]
|
||||
extends = common:esp32-idf
|
||||
@@ -57,14 +56,13 @@ build_flags =
|
||||
${common:esp32-idf.build_flags}
|
||||
${flags:runtime.build_flags}
|
||||
; ### Sofware options : (can be set in defines.h)
|
||||
-D BOARD_ESP32CAM_AITHINKER
|
||||
-D ENABLE_MQTT
|
||||
-D ENABLE_INFLUXDB
|
||||
-D ENABLE_WEBHOOK
|
||||
-D ENABLE_SOFTAP
|
||||
board_build.partitions = partitions.csv
|
||||
monitor_speed = 115200
|
||||
|
||||
monitor_rts = 0
|
||||
monitor_dtr = 0
|
||||
|
||||
; full standalone dev mode
|
||||
; As sample, the board is nod32s instead of esp32cam (do not change nothing in fact :)
|
||||
@@ -79,10 +77,8 @@ build_flags =
|
||||
${common:esp32-idf.build_flags}
|
||||
${flags:clangtidy.build_flags}
|
||||
; ### Sofware options : (can be set in defines.h)
|
||||
-D BOARD_ESP32CAM_AITHINKER
|
||||
-D ENABLE_MQTT
|
||||
-D ENABLE_INFLUXDB
|
||||
-D ENABLE_WEBHOOK
|
||||
;-D ENABLE_SOFTAP
|
||||
; ### Debug options :
|
||||
;-D DEBUG_DETAIL_ON
|
||||
@@ -125,6 +121,8 @@ platform_packages =
|
||||
;;;;espressif/toolchain-xtensa-esp32 @ 8.4.0+2021r2-patch5
|
||||
board_build.partitions = partitions.csv
|
||||
monitor_speed = 115200
|
||||
monitor_rts = 0
|
||||
monitor_dtr = 0
|
||||
|
||||
|
||||
; Activate all debug mode
|
||||
@@ -213,5 +211,4 @@ build_flags =
|
||||
; ### Sofware options :
|
||||
-D ENABLE_MQTT
|
||||
-D ENABLE_INFLUXDB
|
||||
-D ENABLE_WEBHOOK
|
||||
;-D ENABLE_SOFTAP ; disabled
|
||||
|
||||
@@ -109,6 +109,11 @@ CONFIG_ESP_INT_WDT_TIMEOUT_MS=300
|
||||
|
||||
CONFIG_HTTPD_MAX_REQ_HDR_LEN=1024
|
||||
CONFIG_HTTPD_PURGE_BUF_LEN=16
|
||||
<<<<<<< Updated upstream
|
||||
=======
|
||||
CONFIG_HTTPD_WS_SUPPORT=y
|
||||
CONFIG_LWIP_MAX_SOCKETS=12
|
||||
>>>>>>> Stashed changes
|
||||
|
||||
CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=16
|
||||
CONFIG_ESP32_WIFI_CACHE_TX_BUFFER_NUM=16
|
||||
@@ -135,8 +140,7 @@ CONFIG_OV7670_SUPPORT=n
|
||||
CONFIG_OV7725_SUPPORT=n
|
||||
CONFIG_NT99141_SUPPORT=n
|
||||
CONFIG_OV3660_SUPPORT=n
|
||||
CONFIG_OV2640_SUPPORT=y
|
||||
CONFIG_OV5640_SUPPORT=y
|
||||
CONFIG_OV5640_SUPPORT=n
|
||||
CONFIG_GC2145_SUPPORT=n
|
||||
CONFIG_GC032A_SUPPORT=n
|
||||
CONFIG_GC0308_SUPPORT=n
|
||||
|
||||
@@ -20,7 +20,7 @@ class UnderTestCNNGeneral : public ClassFlowCNNGeneral {
|
||||
*/
|
||||
void test_analogToDigit_Standard() {
|
||||
|
||||
UnderTestCNNGeneral* undertest = new UnderTestCNNGeneral(nullptr, Digit100);
|
||||
UnderTestCNNGeneral* undertest = new UnderTestCNNGeneral(nullptr, Digital100);
|
||||
|
||||
// 4.8 is a "hanging" 5, i.e. it has not jumped over to 5.0.
|
||||
// A "hanging digit" should still be rounded from Transition.
|
||||
@@ -59,7 +59,7 @@ void test_analogToDigit_Standard() {
|
||||
}
|
||||
|
||||
void test_analogToDigit_Transition() {
|
||||
UnderTestCNNGeneral* undertest = new UnderTestCNNGeneral(nullptr, Digit100);
|
||||
UnderTestCNNGeneral* undertest = new UnderTestCNNGeneral(nullptr, Digital100);
|
||||
|
||||
// https://github.com/jomjol/AI-on-the-edge-device/issues/921#issuecomment-1222672175
|
||||
// Default: dig=3.9, ana=9.7 => erg=3
|
||||
|
||||
@@ -16,7 +16,7 @@ class UnderTestCNN : public ClassFlowCNNGeneral {
|
||||
*/
|
||||
void test_ZeigerEval()
|
||||
{
|
||||
UnderTestCNN undertest = UnderTestCNN(nullptr, Digit100);
|
||||
UnderTestCNN undertest = UnderTestCNN(nullptr, Digital100);
|
||||
|
||||
// the 5.2 is already above 5.0 and the previous digit too (3)
|
||||
printf("Test 5.2, 3\n");
|
||||
@@ -29,11 +29,11 @@ void test_ZeigerEval()
|
||||
TEST_ASSERT_EQUAL(4, undertest.PointerEvalAnalogNew(5.2, 9));
|
||||
|
||||
printf("Test 4.4, 9\n");
|
||||
// the 4.4 (Digit100) is not above 5 and the previous digit (analog) too (9.3)
|
||||
// the 4.4 (digital100) is not above 5 and the previous digit (analog) too (9.3)
|
||||
TEST_ASSERT_EQUAL(4, undertest.PointerEvalAnalogNew(4.4, 9));
|
||||
|
||||
printf("Test 4.5, 0\n");
|
||||
// the 4.5 (Digit100) is not above 5 and the previous digit (analog) too (9.6)
|
||||
// the 4.5 (digital100) is not above 5 and the previous digit (analog) too (9.6)
|
||||
TEST_ASSERT_EQUAL(4, undertest.PointerEvalAnalogNew(4.5, 0));
|
||||
|
||||
}
|
||||
@@ -42,7 +42,7 @@ void test_ZeigerEval()
|
||||
* @brief test if all combinations of digit
|
||||
* evaluation are running correctly
|
||||
*
|
||||
* Desciption on call undertest.PointerEvalHybridNew(float number, float number_of_predecessors, int eval_predecessors, bool Analog_Predecessors, float digitAnalogTransitionStart)
|
||||
* Desciption on call undertest.PointerEvalHybridNew(float number, float number_of_predecessors, int eval_predecessors, bool Analog_Predecessors, float digitalAnalogTransitionStart)
|
||||
* @param number: is the current ROI as float value from recognition
|
||||
* @param number_of_predecessors: is the last (lower) ROI as float from recognition
|
||||
* @param eval_predecessors: is the evaluated number. Sometimes a much lower value can change higer values
|
||||
@@ -50,16 +50,16 @@ void test_ZeigerEval()
|
||||
* 0.1 => 0 (eval_predecessors)
|
||||
* The 0 makes a 9.9 to 0 (eval_predecessors)
|
||||
* The 0 makes a 9.8 to 0
|
||||
* @param Analog_Predecessors false/true if the last ROI is an analog or digit ROI (default=false)
|
||||
* @param Analog_Predecessors false/true if the last ROI is an analog or digital ROI (default=false)
|
||||
* runs in special handling because analog is much less precise
|
||||
* @param digitAnalogTransitionStart start of the transitionlogic begins on number_of_predecessor (default=9.2)
|
||||
* @param digitalAnalogTransitionStart start of the transitionlogic begins on number_of_predecessor (default=9.2)
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
void test_ZeigerEvalHybrid() {
|
||||
UnderTestCNN undertest = UnderTestCNN(nullptr, Digit100);
|
||||
UnderTestCNN undertest = UnderTestCNN(nullptr, Digital100);
|
||||
|
||||
// the 5.2 and no previous should round down
|
||||
printf("PointerEvalHybridNew(5.2, 0, -1)\n");
|
||||
@@ -93,17 +93,17 @@ void test_ZeigerEvalHybrid() {
|
||||
// the 5.7 with previous and the previous >=9.5 should trunc to 5
|
||||
TEST_ASSERT_EQUAL(5, undertest.PointerEvalHybridNew(5.7, 9.6, 9));
|
||||
|
||||
// the 4.5 (Digit100) is not above 5 and the previous digit (analog) not over Zero (9.6)
|
||||
// the 4.5 (digital100) is not above 5 and the previous digit (analog) not over Zero (9.6)
|
||||
TEST_ASSERT_EQUAL(4, undertest.PointerEvalHybridNew(4.5, 9.6, 0));
|
||||
|
||||
// the 4.5 (Digit100) is not above 5 and the previous digit (analog) not over Zero (9.6)
|
||||
// the 4.5 (digital100) is not above 5 and the previous digit (analog) not over Zero (9.6)
|
||||
TEST_ASSERT_EQUAL(4, undertest.PointerEvalHybridNew(4.5, 9.6, 9));
|
||||
// the 4.5 (Digit100) is not above 5 and the previous digit (analog) not over Zero (9.5)
|
||||
// the 4.5 (digital100) is not above 5 and the previous digit (analog) not over Zero (9.5)
|
||||
TEST_ASSERT_EQUAL(4, undertest.PointerEvalHybridNew(4.5, 9.5, 9));
|
||||
|
||||
// 59.96889 - Pre: 58.94888
|
||||
// 8.6 : 9.8 : 6.7
|
||||
// the 4.4 (Digit100) is not above 5 and the previous digit (analog) not over Zero (9.5)
|
||||
// the 4.4 (digital100) is not above 5 and the previous digit (analog) not over Zero (9.5)
|
||||
TEST_ASSERT_EQUAL(8, undertest.PointerEvalHybridNew(8.6, 9.8, 9));
|
||||
|
||||
// pre = 9.9 (0.0 raw)
|
||||
@@ -111,7 +111,7 @@ void test_ZeigerEvalHybrid() {
|
||||
TEST_ASSERT_EQUAL(2, undertest.PointerEvalHybridNew(1.8, 9.0, 9));
|
||||
|
||||
// if a digit have an early transition and the pointer is < 9.0
|
||||
// prev (pointer) = 6.2, but on digit readout = 6.0 (prev is int parameter)
|
||||
// prev (pointer) = 6.2, but on digital readout = 6.0 (prev is int parameter)
|
||||
// zahl = 4.6
|
||||
TEST_ASSERT_EQUAL(4, undertest.PointerEvalHybridNew(4.6, 6.0, 6));
|
||||
|
||||
|
||||
@@ -37,9 +37,9 @@ std::string process_doFlow(UnderTestPost* _underTestPost) {
|
||||
* @brief setup flow like it runs after recognition.
|
||||
*
|
||||
* @param analog the analog recognitions as array begins with the highest ROI
|
||||
* @param digits the digit regocnitions as array begins with the highest ROI
|
||||
* @param digType type of the model defaults do Digit100
|
||||
* @param checkConsistency for Digit type only. Not relvant for newer models
|
||||
* @param digits the digital regocnitions as array begins with the highest ROI
|
||||
* @param digType type of the model defaults do Digital100
|
||||
* @param checkConsistency for Digital type only. Not relvant for newer models
|
||||
* @param extendedResolution the lowest ROI will directly used (9.7 => 9.7) if false 9.7 => 9
|
||||
* @param decimal_shift the decimal point offset. -3 corresponds to x.yyy
|
||||
* @return std::string the value result
|
||||
@@ -162,7 +162,7 @@ void setAnalogdigitTransistionStart(UnderTestPost* _underTestPost, float _analog
|
||||
std::vector<NumberPost*>* NUMBERS = _underTestPost->GetNumbers();
|
||||
for (int _n = 0; _n < (*NUMBERS).size(); ++_n) {
|
||||
ESP_LOGD(TAG, "Setting decimal shift on number: %d to %f", _n, _analogdigitTransistionStart);
|
||||
(*NUMBERS)[_n]->AnalogToDigitTransitionStart = _analogdigitTransistionStart;
|
||||
(*NUMBERS)[_n]->AnalogDigitalTransitionStart = _analogdigitTransistionStart;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,13 +33,13 @@ UnderTestPost* setUpClassFlowPostprocessing(t_CNNType digType, t_CNNType anaType
|
||||
*
|
||||
* @param analog the analog recognitions
|
||||
* @param digits the digit recognitions
|
||||
* @param digType the digit model type (default Digit100)
|
||||
* @param digType the digit model type (default Digital100)
|
||||
* @param checkConsistency sets property checkConsistency (default = false)
|
||||
* @param extendedResolution sets property extendedResolution (default = false)
|
||||
* @param decimal_shift set property decimal_shift (Nachkommastellen, default = 0)
|
||||
* @return UnderTestPost* the created testobject
|
||||
*/
|
||||
UnderTestPost* init_do_flow(std::vector<float> analog, std::vector<float> digits, t_CNNType digType = Digit100,
|
||||
UnderTestPost* init_do_flow(std::vector<float> analog, std::vector<float> digits, t_CNNType digType = Digital100,
|
||||
bool checkConsistency=false, bool extendedResolution=false, int decimal_shift=0);
|
||||
|
||||
/**
|
||||
@@ -47,13 +47,13 @@ UnderTestPost* init_do_flow(std::vector<float> analog, std::vector<float> digits
|
||||
*
|
||||
* @param analog the analog recognitions
|
||||
* @param digits the digit recognitions
|
||||
* @param digType the digit model type (default Digit100)
|
||||
* @param digType the digit model type (default Digital100)
|
||||
* @param checkConsistency sets property checkConsistency (default = false)
|
||||
* @param extendedResolution sets property extendedResolution (default = false)
|
||||
* @param decimal_shift set property decimal_shift (Nachkommastellen, default = 0)
|
||||
* @return std::string the return value of do_Flow is the Value as string
|
||||
*/
|
||||
std::string process_doFlow(std::vector<float> analog, std::vector<float> digits, t_CNNType digType = Digit100,
|
||||
std::string process_doFlow(std::vector<float> analog, std::vector<float> digits, t_CNNType digType = Digital100,
|
||||
bool checkConsistency=false, bool extendedResolution=false, int decimal_shift=0);
|
||||
|
||||
/**
|
||||
|
||||
@@ -20,7 +20,7 @@ void testNegative() {
|
||||
|
||||
// extendResolution=false
|
||||
// da kein negativ, sollte kein Error auftreten
|
||||
UnderTestPost* underTestPost = init_do_flow(analogs, digits, Digit100, false, false, 0);
|
||||
UnderTestPost* underTestPost = init_do_flow(analogs, digits, Digital100, false, false, 0);
|
||||
setAllowNegatives(underTestPost, false);
|
||||
setPreValue(underTestPost, preValue);
|
||||
std::string result = process_doFlow(underTestPost);
|
||||
@@ -31,7 +31,7 @@ void testNegative() {
|
||||
// extendResolution=true
|
||||
// da negativ im Rahmen (letzte Stelle -0.2 > ergebnis), kein Error
|
||||
// Aber der PreValue wird gesetzt
|
||||
underTestPost = init_do_flow(analogs, digits, Digit100, false, true, 0);
|
||||
underTestPost = init_do_flow(analogs, digits, Digital100, false, true, 0);
|
||||
setAllowNegatives(underTestPost, false);
|
||||
setPreValue(underTestPost, preValue_extended);
|
||||
result = process_doFlow(underTestPost);
|
||||
@@ -42,7 +42,7 @@ void testNegative() {
|
||||
// extendResolution=true
|
||||
// Tolleranz überschritten, Error wird gesetzt, kein ReturnValue
|
||||
preValue_extended = 16.988; // zu groß
|
||||
underTestPost = init_do_flow(analogs, digits, Digit100, false, true, 0);
|
||||
underTestPost = init_do_flow(analogs, digits, Digital100, false, true, 0);
|
||||
setAllowNegatives(underTestPost, false);
|
||||
setPreValue(underTestPost, preValue_extended);
|
||||
result = process_doFlow(underTestPost);
|
||||
@@ -53,7 +53,7 @@ void testNegative() {
|
||||
// extendResolution=false
|
||||
// value < (preValue -.01)
|
||||
preValue = 17.00; // zu groß
|
||||
underTestPost = init_do_flow(analogs, digits, Digit100, false, false, 0);
|
||||
underTestPost = init_do_flow(analogs, digits, Digital100, false, false, 0);
|
||||
setAllowNegatives(underTestPost, false);
|
||||
setPreValue(underTestPost, preValue);
|
||||
result = process_doFlow(underTestPost);
|
||||
@@ -65,7 +65,7 @@ void testNegative() {
|
||||
// value > (preValue -.01)
|
||||
// ist im Rahmen der Ungenauigkeit (-1 auf letzter Stelle)
|
||||
preValue = 16.99; // zu groß
|
||||
underTestPost = init_do_flow(analogs, digits, Digit100, false, false, 0);
|
||||
underTestPost = init_do_flow(analogs, digits, Digital100, false, false, 0);
|
||||
setAllowNegatives(underTestPost, false);
|
||||
setPreValue(underTestPost, preValue);
|
||||
result = process_doFlow(underTestPost);
|
||||
@@ -77,7 +77,7 @@ void testNegative() {
|
||||
// value < preValue
|
||||
// Aber Prüfung abgeschaltet => kein Fehler
|
||||
preValue = 17.99; // zu groß
|
||||
underTestPost = init_do_flow(analogs, digits, Digit100, false, false, 0);
|
||||
underTestPost = init_do_flow(analogs, digits, Digital100, false, false, 0);
|
||||
setAllowNegatives(underTestPost, true);
|
||||
setPreValue(underTestPost, preValue_extended);
|
||||
result = process_doFlow(underTestPost);
|
||||
@@ -105,11 +105,11 @@ void testNegative_Issues() {
|
||||
// value < preValue
|
||||
// Prüfung eingeschaltet => Fehler
|
||||
preValue = 22018.09; // zu groß
|
||||
UnderTestPost* underTestPost = init_do_flow(analogs, digits, Digit100, false, false, -2);
|
||||
UnderTestPost* underTestPost = init_do_flow(analogs, digits, Digital100, false, false, -2);
|
||||
setAllowNegatives(underTestPost, false);
|
||||
setPreValue(underTestPost, preValue_extended);
|
||||
std::string result = process_doFlow(underTestPost);
|
||||
TEST_ASSERT_EQUAL_STRING("Neg. Rate - Read: - Raw: 22017.98 - Pre: 22018.09 ", underTestPost->getReadoutError().c_str());
|
||||
TEST_ASSERT_EQUAL_STRING("Neg. Rate - Read: - Raw: 22017.98 - Pre: 22018.08 ", underTestPost->getReadoutError().c_str());
|
||||
// if negativ no result any more
|
||||
|
||||
TEST_ASSERT_EQUAL_STRING("", result.c_str());
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#include "test_flow_postrocess_helper.h"
|
||||
|
||||
|
||||
|
||||
#include <memory>
|
||||
|
||||
/**
|
||||
* ACHTUNG! Die Test laufen aktuell nur mit ausgeschaltetem Debug in ClassFlowCNNGeneral
|
||||
@@ -178,7 +177,7 @@ void test_doFlowPP2() {
|
||||
std::vector<float> digits = { 1.0, 9.0, 9.0}; // Übergang wurde um 1 erhöht (200, statt 199)
|
||||
std::vector<float> analogs = { 7.1, 4.8, 8.3};
|
||||
const char* expected = "199.748";
|
||||
std::string result = process_doFlow(analogs, digits, Digit);
|
||||
std::string result = process_doFlow(analogs, digits, Digital);
|
||||
TEST_ASSERT_EQUAL_STRING(expected, result.c_str());
|
||||
|
||||
// Fehler bei Rolling (2002-09-09)
|
||||
@@ -191,15 +190,15 @@ void test_doFlowPP2() {
|
||||
// expected_extended= "32289.4198";
|
||||
|
||||
// extendResolution=false, checkConsistency=false
|
||||
result = process_doFlow(analogs, digits, Digit100, false, false, -3);
|
||||
result = process_doFlow(analogs, digits, Digital100, false, false, -3);
|
||||
TEST_ASSERT_EQUAL_STRING(expected, result.c_str());
|
||||
|
||||
// extendResolution=true
|
||||
result = process_doFlow(analogs, digits, Digit100, false, true, -3);
|
||||
result = process_doFlow(analogs, digits, Digital100, false, true, -3);
|
||||
TEST_ASSERT_EQUAL_STRING(expected_extended, result.c_str());
|
||||
|
||||
// checkConsistency=true und extendResolution=true
|
||||
result = process_doFlow(analogs, digits, Digit100, false, true, -3);
|
||||
result = process_doFlow(analogs, digits, Digital100, false, true, -3);
|
||||
TEST_ASSERT_EQUAL_STRING(expected_extended, result.c_str());
|
||||
|
||||
// Fehler Rolling (2022-09-10)
|
||||
@@ -210,20 +209,20 @@ void test_doFlowPP2() {
|
||||
expected_extended= "83.99401";
|
||||
|
||||
// checkConsistency=false
|
||||
result = process_doFlow(analogs, digits, Digit100, false);
|
||||
result = process_doFlow(analogs, digits, Digital100, false);
|
||||
TEST_ASSERT_EQUAL_STRING(expected, result.c_str());
|
||||
|
||||
|
||||
// checkConsistency=true
|
||||
result = process_doFlow(analogs, digits, Digit100, true);
|
||||
result = process_doFlow(analogs, digits, Digital100, true);
|
||||
TEST_ASSERT_EQUAL_STRING(expected, result.c_str());
|
||||
|
||||
// extendResolution=true
|
||||
result = process_doFlow(analogs, digits, Digit100, false, true);
|
||||
result = process_doFlow(analogs, digits, Digital100, false, true);
|
||||
TEST_ASSERT_EQUAL_STRING(expected_extended, result.c_str());
|
||||
|
||||
// checkConsistency=true und extendResolution=true
|
||||
result = process_doFlow(analogs, digits, Digit100, false, true);
|
||||
result = process_doFlow(analogs, digits, Digital100, false, true);
|
||||
TEST_ASSERT_EQUAL_STRING(expected_extended, result.c_str());
|
||||
|
||||
// Fehler Rolling (2022-09-10)
|
||||
@@ -234,16 +233,16 @@ void test_doFlowPP2() {
|
||||
expected_extended= "123235.6";
|
||||
|
||||
// checkConsistency=true
|
||||
result = process_doFlow(analogs, digits, Digit100, false, false);
|
||||
result = process_doFlow(analogs, digits, Digital100, false, false);
|
||||
TEST_ASSERT_EQUAL_STRING(expected, result.c_str());
|
||||
|
||||
|
||||
// checkConsistency=true
|
||||
result = process_doFlow(analogs, digits, Digit100, true, false);
|
||||
result = process_doFlow(analogs, digits, Digital100, true, false);
|
||||
TEST_ASSERT_EQUAL_STRING(expected, result.c_str());
|
||||
|
||||
// extendResolution=true
|
||||
result = process_doFlow(analogs, digits, Digit100, false, true);
|
||||
result = process_doFlow(analogs, digits, Digital100, false, true);
|
||||
TEST_ASSERT_EQUAL_STRING(expected_extended, result.c_str());
|
||||
|
||||
// Fehler bei V11.2.0
|
||||
@@ -254,11 +253,11 @@ void test_doFlowPP2() {
|
||||
expected_extended= "3249.4692";
|
||||
|
||||
// checkConsistency=true
|
||||
result = process_doFlow(analogs, digits, Digit100, false, false, -3);
|
||||
result = process_doFlow(analogs, digits, Digital100, false, false, -3);
|
||||
TEST_ASSERT_EQUAL_STRING(expected, result.c_str());
|
||||
|
||||
// extendResolution=true
|
||||
result = process_doFlow(analogs, digits, Digit100, false, true, -3);
|
||||
result = process_doFlow(analogs, digits, Digital100, false, true, -3);
|
||||
TEST_ASSERT_EQUAL_STRING(expected_extended, result.c_str());
|
||||
|
||||
// Fehler bei V11.2.0
|
||||
@@ -269,11 +268,11 @@ void test_doFlowPP2() {
|
||||
expected_extended= "269.92272";
|
||||
|
||||
// extendResolution=true
|
||||
result = process_doFlow(analogs, digits, Digit100, false, false);
|
||||
result = process_doFlow(analogs, digits, Digital100, false, false);
|
||||
TEST_ASSERT_EQUAL_STRING(expected, result.c_str());
|
||||
|
||||
// checkConsistency=false und extendResolution=true
|
||||
result = process_doFlow(analogs, digits, Digit100, false, true);
|
||||
result = process_doFlow(analogs, digits, Digital100, false, true);
|
||||
TEST_ASSERT_EQUAL_STRING(expected_extended, result.c_str());
|
||||
|
||||
// Fehler bei V11.3.1
|
||||
@@ -284,11 +283,11 @@ void test_doFlowPP2() {
|
||||
expected_extended= "169.35935";
|
||||
|
||||
// extendResolution=false
|
||||
result = process_doFlow(analogs, digits, Digit100, false, false, -3);
|
||||
result = process_doFlow(analogs, digits, Digital100, false, false, -3);
|
||||
TEST_ASSERT_EQUAL_STRING(expected, result.c_str());
|
||||
|
||||
// checkConsistency=false und extendResolution=true
|
||||
result = process_doFlow(analogs, digits, Digit100, false, true, -3);
|
||||
result = process_doFlow(analogs, digits, Digital100, false, true, -3);
|
||||
TEST_ASSERT_EQUAL_STRING(expected_extended, result.c_str());
|
||||
|
||||
// Fehler bei V12.0.1
|
||||
@@ -299,11 +298,11 @@ void test_doFlowPP2() {
|
||||
expected_extended= "211.03555";
|
||||
|
||||
// extendResolution=false
|
||||
result = process_doFlow(analogs, digits, Digit100, false, false, -3);
|
||||
result = process_doFlow(analogs, digits, Digital100, false, false, -3);
|
||||
TEST_ASSERT_EQUAL_STRING(expected, result.c_str());
|
||||
|
||||
// checkConsistency=false und extendResolution=true
|
||||
result = process_doFlow(analogs, digits, Digit100, false, true, -3);
|
||||
result = process_doFlow(analogs, digits, Digital100, false, true, -3);
|
||||
TEST_ASSERT_EQUAL_STRING(expected_extended, result.c_str());
|
||||
|
||||
// Fehler bei V12.0.1
|
||||
@@ -314,11 +313,11 @@ void test_doFlowPP2() {
|
||||
expected_extended= "245.9386";
|
||||
|
||||
// extendResolution=false
|
||||
result = process_doFlow(analogs, digits, Digit100, false, false, 0);
|
||||
result = process_doFlow(analogs, digits, Digital100, false, false, 0);
|
||||
TEST_ASSERT_EQUAL_STRING(expected, result.c_str());
|
||||
|
||||
// checkConsistency=false und extendResolution=true
|
||||
result = process_doFlow(analogs, digits, Digit100, false, true, 0);
|
||||
result = process_doFlow(analogs, digits, Digital100, false, true, 0);
|
||||
TEST_ASSERT_EQUAL_STRING(expected_extended, result.c_str());
|
||||
|
||||
// Fehler bei V12.0.1
|
||||
@@ -329,11 +328,11 @@ void test_doFlowPP2() {
|
||||
expected_extended= "245.9386";
|
||||
|
||||
// extendResolution=false
|
||||
result = process_doFlow(analogs, digits, Digit100, false, false, 0);
|
||||
result = process_doFlow(analogs, digits, Digital100, false, false, 0);
|
||||
TEST_ASSERT_EQUAL_STRING(expected, result.c_str());
|
||||
|
||||
// checkConsistency=false und extendResolution=true
|
||||
result = process_doFlow(analogs, digits, Digit100, false, true, 0);
|
||||
result = process_doFlow(analogs, digits, Digital100, false, true, 0);
|
||||
TEST_ASSERT_EQUAL_STRING(expected_extended, result.c_str());
|
||||
}
|
||||
|
||||
@@ -346,11 +345,11 @@ void test_doFlowPP3() {
|
||||
const char* expected_extended= "247.2045";
|
||||
|
||||
// extendResolution=false
|
||||
std::string result = process_doFlow(analogs, digits, Digit100, false, false, 0);
|
||||
std::string result = process_doFlow(analogs, digits, Digital100, false, false, 0);
|
||||
TEST_ASSERT_EQUAL_STRING(expected, result.c_str());
|
||||
|
||||
// checkConsistency=false und extendResolution=true
|
||||
result = process_doFlow(analogs, digits, Digit100, false, true, 0);
|
||||
result = process_doFlow(analogs, digits, Digital100, false, true, 0);
|
||||
TEST_ASSERT_EQUAL_STRING(expected_extended, result.c_str());
|
||||
|
||||
|
||||
@@ -362,11 +361,11 @@ void test_doFlowPP3() {
|
||||
expected_extended= "142.92690";
|
||||
|
||||
// extendResolution=false
|
||||
result = process_doFlow(analogs, digits, Digit100, false, false, 0);
|
||||
result = process_doFlow(analogs, digits, Digital100, false, false, 0);
|
||||
TEST_ASSERT_EQUAL_STRING(expected, result.c_str());
|
||||
|
||||
// checkConsistency=false und extendResolution=true
|
||||
result = process_doFlow(analogs, digits, Digit100, false, true, 0);
|
||||
result = process_doFlow(analogs, digits, Digital100, false, true, 0);
|
||||
TEST_ASSERT_EQUAL_STRING(expected_extended, result.c_str());
|
||||
|
||||
|
||||
@@ -379,14 +378,14 @@ void test_doFlowPP3() {
|
||||
expected_extended= "170.05287";
|
||||
|
||||
// extendResolution=false
|
||||
UnderTestPost* undertestPost = init_do_flow(analogs, digits, Digit100, false, false, -3);
|
||||
UnderTestPost* undertestPost = init_do_flow(analogs, digits, Digital100, false, false, -3);
|
||||
setAnalogdigitTransistionStart(undertestPost, 7.7);
|
||||
result = process_doFlow(undertestPost);
|
||||
TEST_ASSERT_EQUAL_STRING(expected, result.c_str());
|
||||
delete undertestPost;
|
||||
|
||||
// checkConsistency=false und extendResolution=true
|
||||
undertestPost = init_do_flow(analogs, digits, Digit100, false, true, -3);
|
||||
undertestPost = init_do_flow(analogs, digits, Digital100, false, true, -3);
|
||||
setAnalogdigitTransistionStart(undertestPost, 7.7);
|
||||
result = process_doFlow(undertestPost);
|
||||
TEST_ASSERT_EQUAL_STRING(expected_extended, result.c_str());
|
||||
@@ -400,11 +399,11 @@ void test_doFlowPP3() {
|
||||
expected_extended= "91.88174";
|
||||
|
||||
// extendResolution=false
|
||||
result = process_doFlow(analogs, digits, Digit100, false, false, 0);
|
||||
result = process_doFlow(analogs, digits, Digital100, false, false, 0);
|
||||
TEST_ASSERT_EQUAL_STRING(expected, result.c_str());
|
||||
|
||||
// checkConsistency=false und extendResolution=true
|
||||
result = process_doFlow(analogs, digits, Digit100, false, true, 0);
|
||||
result = process_doFlow(analogs, digits, Digital100, false, true, 0);
|
||||
TEST_ASSERT_EQUAL_STRING(expected_extended, result.c_str());
|
||||
|
||||
|
||||
@@ -416,11 +415,11 @@ void test_doFlowPP3() {
|
||||
expected_extended= "92.38320";
|
||||
|
||||
// extendResolution=false
|
||||
result = process_doFlow(analogs, digits, Digit100, false, false, 0);
|
||||
result = process_doFlow(analogs, digits, Digital100, false, false, 0);
|
||||
TEST_ASSERT_EQUAL_STRING(expected, result.c_str());
|
||||
|
||||
// checkConsistency=false und extendResolution=true
|
||||
result = process_doFlow(analogs, digits, Digit100, false, true, 0);
|
||||
result = process_doFlow(analogs, digits, Digital100, false, true, 0);
|
||||
TEST_ASSERT_EQUAL_STRING(expected_extended, result.c_str());
|
||||
|
||||
// Fehler V11.3.0
|
||||
@@ -431,11 +430,11 @@ void test_doFlowPP3() {
|
||||
expected_extended= "7472.7594";
|
||||
|
||||
// extendResolution=false
|
||||
result = process_doFlow(analogs, digits, Digit100, false, false, -3);
|
||||
result = process_doFlow(analogs, digits, Digital100, false, false, -3);
|
||||
TEST_ASSERT_EQUAL_STRING(expected, result.c_str());
|
||||
|
||||
// checkConsistency=false und extendResolution=true
|
||||
result = process_doFlow(analogs, digits, Digit100, false, true, -3);
|
||||
result = process_doFlow(analogs, digits, Digital100, false, true, -3);
|
||||
TEST_ASSERT_EQUAL_STRING(expected_extended, result.c_str());
|
||||
|
||||
// Fehler V12.0.1
|
||||
@@ -446,11 +445,11 @@ void test_doFlowPP3() {
|
||||
expected_extended= "577.86490";
|
||||
|
||||
// extendResolution=false
|
||||
result = process_doFlow(analogs, digits, Digit100, false, false, 0);
|
||||
result = process_doFlow(analogs, digits, Digital100, false, false, 0);
|
||||
TEST_ASSERT_EQUAL_STRING(expected, result.c_str());
|
||||
|
||||
// checkConsistency=false und extendResolution=true
|
||||
result = process_doFlow(analogs, digits, Digit100, false, true, 0);
|
||||
result = process_doFlow(analogs, digits, Digital100, false, true, 0);
|
||||
TEST_ASSERT_EQUAL_STRING(expected_extended, result.c_str());
|
||||
|
||||
|
||||
@@ -462,11 +461,11 @@ void test_doFlowPP3() {
|
||||
expected_extended= "211.03580";
|
||||
|
||||
// extendResolution=false
|
||||
result = process_doFlow(analogs, digits, Digit100, false, false, -3);
|
||||
result = process_doFlow(analogs, digits, Digital100, false, false, -3);
|
||||
TEST_ASSERT_EQUAL_STRING(expected, result.c_str());
|
||||
|
||||
// checkConsistency=false und extendResolution=true
|
||||
result = process_doFlow(analogs, digits, Digit100, false, true, -3);
|
||||
result = process_doFlow(analogs, digits, Digital100, false, true, -3);
|
||||
TEST_ASSERT_EQUAL_STRING(expected_extended, result.c_str());
|
||||
|
||||
// Fehler V12.0.1
|
||||
@@ -477,11 +476,11 @@ void test_doFlowPP3() {
|
||||
expected_extended= "126.9231";
|
||||
|
||||
// extendResolution=false
|
||||
result = process_doFlow(analogs, digits, Digit100, false, false, 0);
|
||||
result = process_doFlow(analogs, digits, Digital100, false, false, 0);
|
||||
TEST_ASSERT_EQUAL_STRING(expected, result.c_str());
|
||||
|
||||
// checkConsistency=false und extendResolution=true
|
||||
result = process_doFlow(analogs, digits, Digit100, false, true, 0);
|
||||
result = process_doFlow(analogs, digits, Digital100, false, true, 0);
|
||||
TEST_ASSERT_EQUAL_STRING(expected_extended, result.c_str());
|
||||
|
||||
// Fehler V12.0.1
|
||||
@@ -492,11 +491,11 @@ void test_doFlowPP3() {
|
||||
expected_extended= "386.05672";
|
||||
|
||||
// extendResolution=false
|
||||
result = process_doFlow(analogs, digits, Digit100, false, false, -3);
|
||||
result = process_doFlow(analogs, digits, Digital100, false, false, -3);
|
||||
TEST_ASSERT_EQUAL_STRING(expected, result.c_str());
|
||||
|
||||
// checkConsistency=false und extendResolution=true
|
||||
result = process_doFlow(analogs, digits, Digit100, false, true, -3);
|
||||
result = process_doFlow(analogs, digits, Digital100, false, true, -3);
|
||||
TEST_ASSERT_EQUAL_STRING(expected_extended, result.c_str());
|
||||
|
||||
// Fehler V12.0.1
|
||||
@@ -508,14 +507,14 @@ void test_doFlowPP3() {
|
||||
expected_extended= "171.24178";
|
||||
|
||||
// extendResolution=false
|
||||
undertestPost = init_do_flow(analogs, digits, Digit100, false, false, -3);
|
||||
undertestPost = init_do_flow(analogs, digits, Digital100, false, false, -3);
|
||||
setAnalogdigitTransistionStart(undertestPost, 7.7);
|
||||
result = process_doFlow(undertestPost);
|
||||
TEST_ASSERT_EQUAL_STRING(expected, result.c_str());
|
||||
delete undertestPost;
|
||||
|
||||
// checkConsistency=false und extendResolution=true
|
||||
undertestPost = init_do_flow(analogs, digits, Digit100, false, true, -3);
|
||||
undertestPost = init_do_flow(analogs, digits, Digital100, false, true, -3);
|
||||
setAnalogdigitTransistionStart(undertestPost, 7.7);
|
||||
result = process_doFlow(undertestPost);
|
||||
TEST_ASSERT_EQUAL_STRING(expected_extended, result.c_str());
|
||||
@@ -533,13 +532,73 @@ void test_doFlowPP4() {
|
||||
const char* expected_extended= "717.01658";
|
||||
|
||||
// extendResolution=false
|
||||
std::string result = process_doFlow(analogs, digits, Digit100, false, false);
|
||||
std::string result = process_doFlow(analogs, digits, Digital100, false, false);
|
||||
TEST_ASSERT_EQUAL_STRING(expected, result.c_str());
|
||||
|
||||
// checkConsistency=false und extendResolution=true
|
||||
result = process_doFlow(analogs, digits, Digit100, false, true);
|
||||
result = process_doFlow(analogs, digits, Digital100, false, true);
|
||||
TEST_ASSERT_EQUAL_STRING(expected_extended, result.c_str());
|
||||
|
||||
}
|
||||
|
||||
std::string postProcess(std::vector<float> digits,
|
||||
std::vector<float> analogs,
|
||||
float analog2DigitalTransition=0.0)
|
||||
{
|
||||
std::unique_ptr<UnderTestPost> undertestPost(init_do_flow(std::move(analogs),
|
||||
std::move(digits),
|
||||
Digital100,
|
||||
false, false));
|
||||
|
||||
setAnalogdigitTransistionStart(undertestPost.get(), analog2DigitalTransition);
|
||||
return process_doFlow(undertestPost.get());
|
||||
}
|
||||
|
||||
void test_doFlowLateTransition()
|
||||
{
|
||||
// in these test cases, the last digit before comma turns 3.6 too late
|
||||
float a2dt = 3.6;
|
||||
|
||||
// meter shows 011.0210 but it already needs to be 012.0210, before transition
|
||||
TEST_ASSERT_EQUAL_STRING("12.0210", postProcess({0.0, 1.0, 1.0}, {0.2, 2.2, 1.0, 0.0}, a2dt).c_str());
|
||||
|
||||
// meter shows 011.3210 but it already needs to be 012.3210, just before transition
|
||||
TEST_ASSERT_EQUAL_STRING("12.3210", postProcess({0.0, 1.0, 1.2}, {3.3, 2.2, 1.0, 0.0}, a2dt).c_str());
|
||||
|
||||
// meter shows 012.4210 , this is after transition
|
||||
TEST_ASSERT_EQUAL_STRING("12.4210", postProcess({0.0, 1.0, 2.0}, {4.3, 2.2, 1.0, 0.0}, a2dt).c_str());
|
||||
|
||||
// meter shows 012.987
|
||||
TEST_ASSERT_EQUAL_STRING("12.9870", postProcess({0.0, 1.0, 2.0}, {9.8, 8.7, 7.0, 0.0}, a2dt).c_str());
|
||||
|
||||
// meter shows 0012.003
|
||||
TEST_ASSERT_EQUAL_STRING("13.003", postProcess({0.0, 0.0, 1.0, 2.0}, {0.1, 0.3, 3.1}, a2dt).c_str());
|
||||
|
||||
// meter shows 0012.351
|
||||
TEST_ASSERT_EQUAL_STRING("13.351", postProcess({0.0, 0.0, 1.0, 2.8}, {3.5, 5.2, 1.1}, a2dt).c_str());
|
||||
|
||||
// meter shows 0013.421
|
||||
TEST_ASSERT_EQUAL_STRING("13.421", postProcess({0.0, 0.0, 1.0, 3.0}, {4.1, 2.2, 1.1}, a2dt).c_str());
|
||||
}
|
||||
|
||||
void test_doFlowEarlyTransition()
|
||||
{
|
||||
// in these test cases, the last digit before comma turns at around 7.5
|
||||
// start transition 7.0 end transition 8.0
|
||||
float a2dt = 7.5;
|
||||
|
||||
// meter shows 011.0210 but it already needs to be 012.0210, before transition
|
||||
TEST_ASSERT_EQUAL_STRING("12.6789", postProcess({0.0, 1.0, 2.0}, {6.7, 7.8, 8.9, 9.0}, a2dt).c_str());
|
||||
|
||||
TEST_ASSERT_EQUAL_STRING("12.7234", postProcess({0.0, 1.0, 2.4}, {7.2, 2.3, 3.4, 4.0}, a2dt).c_str());
|
||||
|
||||
TEST_ASSERT_EQUAL_STRING("12.7789", postProcess({0.0, 1.0, 2.7}, {7.7, 7.8, 8.9, 9.0}, a2dt).c_str());
|
||||
|
||||
TEST_ASSERT_EQUAL_STRING("12.8123", postProcess({0.0, 1.0, 3.0}, {8.1, 1.2, 2.3, 3.0}, a2dt).c_str());
|
||||
|
||||
TEST_ASSERT_EQUAL_STRING("13.1234", postProcess({0.0, 1.0, 3.0}, {1.2, 2.3, 3.4, 4.0}, a2dt).c_str());
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
void test_getReadoutRawString() {
|
||||
|
||||
// no ROIs setted up
|
||||
UnderTestPost* _undertestPost = setUpClassFlowPostprocessing(Digit100, Analogue100);
|
||||
UnderTestPost* _undertestPost = setUpClassFlowPostprocessing(Digital100, Analogue100);
|
||||
|
||||
string result = _undertestPost->flowAnalog->getReadoutRawString(0);
|
||||
TEST_ASSERT_EQUAL_STRING("", result.c_str());
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
#include <unity.h>
|
||||
#include <server_mqtt.h>
|
||||
|
||||
void test_createNodeId()
|
||||
{
|
||||
std::string topic = "watermeter";
|
||||
TEST_ASSERT_EQUAL_STRING("watermeter", createNodeId(topic).c_str());
|
||||
|
||||
topic = "/watermeter";
|
||||
TEST_ASSERT_EQUAL_STRING("watermeter", createNodeId(topic).c_str());
|
||||
|
||||
topic = "home/test/watermeter";
|
||||
TEST_ASSERT_EQUAL_STRING("watermeter", createNodeId(topic).c_str());
|
||||
|
||||
topic = "home/test/subtopic/something/test/watermeter";
|
||||
TEST_ASSERT_EQUAL_STRING("watermeter", createNodeId(topic).c_str());
|
||||
}
|
||||
|
||||
void test_mqtt()
|
||||
{
|
||||
test_createNodeId();
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
#include <unity.h>
|
||||
#include <openmetrics.h>
|
||||
|
||||
void test_createMetric()
|
||||
{
|
||||
// simple happy path
|
||||
const char *expected = "# HELP metric_name short description\n# TYPE metric_name gauge\nmetric_name 123.456\n";
|
||||
std::string result = createMetric("metric_name", "short description", "gauge", "123.456");
|
||||
TEST_ASSERT_EQUAL_STRING(expected, result.c_str());
|
||||
}
|
||||
|
||||
/**
|
||||
* test the replaceString function as it's a dependency to sanitize sequence names
|
||||
*/
|
||||
void test_replaceString()
|
||||
{
|
||||
std::string sample = "hello\\world\\";
|
||||
replaceAll(sample, "\\", "");
|
||||
TEST_ASSERT_EQUAL_STRING("helloworld", sample.c_str());
|
||||
|
||||
sample = "hello\"world\"";
|
||||
replaceAll(sample, "\"", "");
|
||||
TEST_ASSERT_EQUAL_STRING("helloworld", sample.c_str());
|
||||
|
||||
sample = "hello\nworld\n";
|
||||
replaceAll(sample, "\n", "");
|
||||
TEST_ASSERT_EQUAL_STRING("helloworld", sample.c_str());
|
||||
|
||||
sample = "\\\\\\\\\\\\\\\\\\hello\\world\\\\\\\\\\\\\\\\\\\\";
|
||||
replaceAll(sample, "\\", "");
|
||||
TEST_ASSERT_EQUAL_STRING("helloworld", sample.c_str());
|
||||
}
|
||||
|
||||
void test_createSequenceMetrics()
|
||||
{
|
||||
std::vector<NumberPost *> NUMBERS;
|
||||
NumberPost *number_1 = new NumberPost;
|
||||
number_1->name = "main";
|
||||
number_1->ReturnValue = "123.456";
|
||||
NUMBERS.push_back(number_1);
|
||||
|
||||
const std::string metricNamePrefix = "ai_on_the_edge_device";
|
||||
const std::string metricName = metricNamePrefix + "_flow_value";
|
||||
|
||||
std::string expected1 = "# HELP " + metricName + " current value of meter readout\n# TYPE " + metricName + " gauge\n" +
|
||||
metricName + "{sequence=\"" + number_1->name + "\"} " + number_1->ReturnValue + "\n";
|
||||
TEST_ASSERT_EQUAL_STRING(expected1.c_str(), createSequenceMetrics(metricNamePrefix, NUMBERS).c_str());
|
||||
|
||||
NumberPost *number_2 = new NumberPost;
|
||||
number_2->name = "secondary";
|
||||
number_2->ReturnValue = "1.0";
|
||||
NUMBERS.push_back(number_2);
|
||||
|
||||
std::string expected2 = "# HELP " + metricName + " current value of meter readout\n# TYPE " + metricName + " gauge\n" +
|
||||
metricName + "{sequence=\"" + number_1->name + "\"} " + number_1->ReturnValue + "\n" +
|
||||
metricName + "{sequence=\"" + number_2->name + "\"} " + number_2->ReturnValue + "\n";
|
||||
TEST_ASSERT_EQUAL_STRING(expected2.c_str(), createSequenceMetrics(metricNamePrefix, NUMBERS).c_str());
|
||||
}
|
||||
|
||||
void test_openmetrics()
|
||||
{
|
||||
test_createMetric();
|
||||
test_replaceString();
|
||||
test_createSequenceMetrics();
|
||||
}
|
||||
@@ -20,8 +20,7 @@
|
||||
#include "components/jomjol-flowcontroll/test_PointerEvalAnalogToDigitNew.cpp"
|
||||
#include "components/jomjol-flowcontroll/test_getReadoutRawString.cpp"
|
||||
#include "components/jomjol-flowcontroll/test_cnnflowcontroll.cpp"
|
||||
#include "components/openmetrics/test_openmetrics.cpp"
|
||||
#include "components/jomjol_mqtt/test_server_mqtt.cpp"
|
||||
|
||||
|
||||
bool Init_NVS_SDCard()
|
||||
{
|
||||
@@ -152,12 +151,12 @@ extern "C" void app_main()
|
||||
{
|
||||
initGPIO();
|
||||
Init_NVS_SDCard();
|
||||
esp_log_level_set("*", ESP_LOG_ERROR); // set all components to ERROR level
|
||||
esp_log_level_set("*", ESP_LOG_DEBUG); // set all components to ERROR level
|
||||
|
||||
UNITY_BEGIN();
|
||||
RUN_TEST(testNegative_Issues);
|
||||
RUN_TEST(testNegative);
|
||||
|
||||
/*
|
||||
RUN_TEST(test_analogToDigit_Standard);
|
||||
RUN_TEST(test_analogToDigit_Transition);
|
||||
RUN_TEST(test_doFlowPP);
|
||||
@@ -165,11 +164,11 @@ extern "C" void app_main()
|
||||
RUN_TEST(test_doFlowPP2);
|
||||
RUN_TEST(test_doFlowPP3);
|
||||
RUN_TEST(test_doFlowPP4);
|
||||
RUN_TEST(test_doFlowLateTransition);
|
||||
RUN_TEST(test_doFlowEarlyTransition);
|
||||
|
||||
// getReadoutRawString test
|
||||
RUN_TEST(test_getReadoutRawString);
|
||||
RUN_TEST(test_openmetrics);
|
||||
RUN_TEST(test_mqtt);
|
||||
|
||||
*/
|
||||
UNITY_END();
|
||||
}
|
||||
|
||||
@@ -1,33 +1,17 @@
|
||||
WaitBeforeTakingPicture
|
||||
CamFrameSize
|
||||
CamGainceiling
|
||||
CamQuality
|
||||
CamAutoSharpness
|
||||
CamSharpness
|
||||
CamSpecialEffect
|
||||
CamWbMode
|
||||
CamAwb
|
||||
CamAwbGain
|
||||
CamAec
|
||||
CamAec2
|
||||
CamAeLevel
|
||||
CamAecValue
|
||||
CamAgc
|
||||
CamAgcGain
|
||||
CamBpc
|
||||
CamWpc
|
||||
CamRawGma
|
||||
CamLenc
|
||||
CamDcw
|
||||
CamDenoise
|
||||
CamZoom
|
||||
CamZoomSize
|
||||
CamZoomOffsetX
|
||||
CamZoomOffsetY
|
||||
demo
|
||||
WaitBeforeTakingPicture
|
||||
ImageQuality
|
||||
ImageSize
|
||||
LEDIntensity
|
||||
Brightness
|
||||
Contrast
|
||||
Saturation
|
||||
FixedExposure
|
||||
SearchFieldX
|
||||
SearchFieldY
|
||||
AlignmentAlgo
|
||||
InitialMirror
|
||||
FlipImageSize
|
||||
CNNGoodThreshold
|
||||
PreValueAgeStartup
|
||||
ErrorMessage
|
||||
|
||||
11
param-docs/parameter-pages/Alignment/FlipImageSize.md
Normal file
11
param-docs/parameter-pages/Alignment/FlipImageSize.md
Normal file
@@ -0,0 +1,11 @@
|
||||
# Parameter `FlipImageSize`
|
||||
Default Value: `false`
|
||||
|
||||
!!! Warning
|
||||
This is an **Expert Parameter**! Only change it if you understand what it does!
|
||||
|
||||
!!! Note
|
||||
This parameter can also be set on the Reference Image configuration.
|
||||
|
||||
This parameter can be used to rotate the viewport together with the alignment rotation:
|
||||

|
||||
10
param-docs/parameter-pages/Alignment/InitialMirror.md
Normal file
10
param-docs/parameter-pages/Alignment/InitialMirror.md
Normal file
@@ -0,0 +1,10 @@
|
||||
# Parameter `InitialMirror`
|
||||
Default Value: `false`
|
||||
|
||||
!!! Warning
|
||||
This is an **Expert Parameter**! Only change it if you understand what it does!
|
||||
|
||||
!!! Note
|
||||
This parameter can also be set on the Reference Image configuration.
|
||||
|
||||
Option for initially mirroring the image on the original x-axis.
|
||||
@@ -1,12 +1,9 @@
|
||||
# Parameter `InitialRotate`
|
||||
Default Value: `0`
|
||||
Default Value: `179`
|
||||
|
||||
Unit: Degrees
|
||||
|
||||
!!! Note
|
||||
This parameter can also be set on the Reference Image configuration page!
|
||||
Initial rotation of image before alignment in degree (0 .. 359)
|
||||
|
||||
!!! Note
|
||||
After changing this parameter you need to update your reference image and alignment markers!
|
||||
|
||||
Initial rotation of image before alignment in degree (`-360` .. `+360`)
|
||||
This parameter is accessible on the Reference Image Page but not on the Config page!
|
||||
|
||||
@@ -16,6 +16,3 @@ Usually there is a common RootCA certificate for the MQTT broker
|
||||
|
||||
!!! Note
|
||||
This also means that you might have to change the protocol and port in [uri](https://jomjol.github.io/AI-on-the-edge-device-docs/Parameters/#parameter-uri) to `mqtts://example.com:8883`!
|
||||
|
||||
!!! Note
|
||||
Only TLS 1.2 is supported!
|
||||
|
||||
@@ -17,6 +17,3 @@ Usually there is a one pair of Client Certificate/Key for each client that conne
|
||||
!!! Note
|
||||
If set, `ClientKey` must be set too
|
||||
This also means that you might have to change the protocol and port in [uri](https://jomjol.github.io/AI-on-the-edge-device-docs/Parameters/#parameter-uri) to `mqtts://example.com:8883`!
|
||||
|
||||
!!! Note
|
||||
Only TLS 1.2 is supported!
|
||||
|
||||
@@ -17,6 +17,3 @@ Usually there is a one pair of Client Certificate/Key for each client that conne
|
||||
!!! Note
|
||||
If set, `ClientCert` must be set too
|
||||
This also means that you might have to change the protocol and port in [uri](https://jomjol.github.io/AI-on-the-edge-device-docs/Parameters/#parameter-uri) to `mqtts://example.com:8883`!
|
||||
|
||||
!!! Note
|
||||
Only TLS 1.2 is supported!
|
||||
|
||||
@@ -8,7 +8,7 @@ The single value will be published with the following key: `MAINTOPIC/NUMBER/RES
|
||||
With:
|
||||
|
||||
- `NUMBER`: The name of the value (a meter might have more than one value).
|
||||
The names get defined in the analog and digit ROI configuration (defaults to `main`).
|
||||
The names get defined in the analog and digital ROI configuration (defaults to `main`).
|
||||
- `RESULT_TOPIC`: Automatically filled with the right name, eg. `value`, `rate`, `timestamp`, `error`, ....
|
||||
|
||||
The general connection status can be found in `MAINTOPIC/CONNECTION`.
|
||||
@@ -16,5 +16,3 @@ See [MQTT Result Topics](../MQTT-API#result) for a full list of topics.
|
||||
|
||||
!!! Note
|
||||
The main topic is allowed to contain `/` which can be used to split it into multiple levels, eg. `/basement/meters/watermeter/1/` if you have multiple water meters in your basement.
|
||||
|
||||
The nodeId for the Home Assistant MQTT Service Discovery must follow the schema `<discovery_prefix>/<component>/[<node_id>/]<object_id>/config`. The node_id is not configurable but derived from the `MainTopic` by stripping any but the last topic level. A `MainTopic` with the value `home/basement/watermeter` is transformed into the node_id `watermeter`, resulting in the discovery topic `homeassistant/sensor/watermeter/value/config` for the current value.
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
# Parameter `<NUMBER>.AnalogToDigitTransitionStart`
|
||||
# Parameter `<NUMBER>.AnalogDigitalTransitionStart`
|
||||
Default Value: `9.2`
|
||||
|
||||
This can be used if you have wrong values, but the recognition of the individual ROIs are correct.
|
||||
Look for the start of changing of the first digit and note the analog pointer value behind.
|
||||
Set it here. Only used on combination of digits and analog pointers.
|
||||
See [here](../Watermeter-specific-analog---digit-transition) for details.
|
||||
See [here](../Watermeter-specific-analog---digital-transition) for details.
|
||||
|
||||
Range: `6.0` .. `9.9`.
|
||||
@@ -1,25 +0,0 @@
|
||||
# Parameter `<NUMBER>.ChangeRateThreshold`
|
||||
Default Value: `2`
|
||||
|
||||
Range: `1` .. `9`.
|
||||
|
||||
Threshold parameter for change rate detection.<br>
|
||||
This parameter is intended to compensate for small reading fluctuations that occur when the meter does not change its value for a long time (e.g. at night) or slightly turns backwards. This can eg. happen on watermeters.
|
||||
|
||||
It is only applied to the last digit of the read value (See example below).
|
||||
If the read value is within PreValue +/- Threshold, no further calculation is carried out and the Value/Prevalue remains at the old value.
|
||||
|
||||
Example:
|
||||
|
||||
Smallest ROI provides value for 0.000x
|
||||
ChangeRateThreshold = 2
|
||||
|
||||
Extended Resolution disabled:
|
||||
PreValue: 123.456'7 >>> Threshold = +/- 0.000'2
|
||||
Comparative value >>> max = 123.456'9 and min = 123.456'5
|
||||
|
||||
Extended Resolution enabled:
|
||||
PreValue: 123.456'78 >>> Threshold = +/- 0.000'02
|
||||
Comparative value >>> max = 123.456'80 and min = 123.456'76
|
||||
|
||||

|
||||
10
param-docs/parameter-pages/TakeImage/Brightness.md
Normal file
10
param-docs/parameter-pages/TakeImage/Brightness.md
Normal file
@@ -0,0 +1,10 @@
|
||||
# Parameter `Brightness`
|
||||
Default Value: `0`
|
||||
|
||||
!!! Warning
|
||||
This is an **Expert Parameter**! Only change it if you understand what it does!
|
||||
|
||||
!!! Note
|
||||
This parameter can also be set on the Reference Image configuration.
|
||||
|
||||
Image Brightness (`-2` .. `2`)
|
||||
@@ -1,22 +0,0 @@
|
||||
# Parameter `CamAeLevel`
|
||||
|
||||
**Auto-Exposure-Level**
|
||||
|
||||
range on OV2640 (`-2` .. `2`)<br>
|
||||
range on OV3660 and OV5640 (`-5` .. `5`)
|
||||
|
||||
Default Value: `0`
|
||||
|
||||
See [here](../datasheets/Camera.ov2640_ds_1.8_.pdf) for the ov2640 camera datasheet.<br>
|
||||
See [here](../datasheets/OV5640_datasheet.pdf) for the ov5640 camera datasheet.
|
||||
|
||||
!!! Warning
|
||||
This is an **Expert Parameter**! Only change it if you understand what it does!
|
||||
|
||||
After changing this parameter you need to update your reference image and alignment markers!
|
||||
|
||||
!!! Note
|
||||
The exposure offset for automatic exposure, lower values produce darker image.
|
||||
|
||||
!!! Note
|
||||
This parameter can also be set on the Reference Image configuration page!
|
||||
@@ -1,19 +0,0 @@
|
||||
# Parameter `CamAec`
|
||||
|
||||
**Auto-Exposure-Control**
|
||||
|
||||
- When **true**, the camera attempts to automatically control the exposure.
|
||||
- When **false**, the **CamAecValue** setting is used instead.
|
||||
|
||||
Default Value: `true`
|
||||
|
||||
See [here](../datasheets/Camera.ov2640_ds_1.8_.pdf) for the ov2640 camera datasheet.<br>
|
||||
See [here](../datasheets/OV5640_datasheet.pdf) for the ov5640 camera datasheet.
|
||||
|
||||
!!! Warning
|
||||
This is an **Expert Parameter**! Only change it if you understand what it does!
|
||||
|
||||
After changing this parameter you need to update your reference image and alignment markers!
|
||||
|
||||
!!! Note
|
||||
This parameter can also be set on the Reference Image configuration page!
|
||||
@@ -1,22 +0,0 @@
|
||||
# Parameter `CamAec2`
|
||||
|
||||
**Auto-Exposure-Control2**
|
||||
|
||||
- When **true**, the sensor’s "night mode" is enabled, extending the range of automatic gain control.
|
||||
- When **false**, the sensor’s "night mode" is disabled.
|
||||
|
||||
Default Value: `true`
|
||||
|
||||
See [here](../datasheets/Camera.ov2640_ds_1.8_.pdf) for the ov2640 camera datasheet.<br>
|
||||
See [here](../datasheets/OV5640_datasheet.pdf) for the ov5640 camera datasheet.
|
||||
|
||||
!!! Warning
|
||||
This is an **Expert Parameter**! Only change it if you understand what it does!
|
||||
|
||||
After changing this parameter you need to update your reference image and alignment markers!
|
||||
|
||||
!!! Note
|
||||
This may resolve some over-exposure and under-exposure issues.
|
||||
|
||||
!!! Note
|
||||
This parameter can also be set on the Reference Image configuration page!
|
||||
@@ -1,21 +0,0 @@
|
||||
# Parameter `CamAecValue`
|
||||
|
||||
**Auto-Exposure-Value**
|
||||
|
||||
Range (`0` .. `1200`)
|
||||
|
||||
Default Value: `160`
|
||||
|
||||
See [here](../datasheets/Camera.ov2640_ds_1.8_.pdf) for the ov2640 camera datasheet.<br>
|
||||
See [here](../datasheets/OV5640_datasheet.pdf) for the ov5640 camera datasheet.
|
||||
|
||||
!!! Warning
|
||||
This is an **Expert Parameter**! Only change it if you understand what it does!
|
||||
|
||||
After changing this parameter you need to update your reference image and alignment markers!
|
||||
|
||||
!!! Note
|
||||
Access the exposure value of the camera, higher values produce brighter images.
|
||||
|
||||
!!! Note
|
||||
This parameter can also be set on the Reference Image configuration page!
|
||||
@@ -1,16 +0,0 @@
|
||||
# Parameter `CamAgc`
|
||||
|
||||
**Auto-Gain-Control**
|
||||
|
||||
- When **true**, the camera attempts to automatically control the sensor gain, up to the value in the **CamGainceiling** property.
|
||||
- When **false**, the **CamAgcGain** setting is used instead.
|
||||
|
||||
Default Value: `true`
|
||||
|
||||
See [here](../datasheets/Camera.ov2640_ds_1.8_.pdf) for the ov2640 camera datasheet.<br>
|
||||
See [here](../datasheets/OV5640_datasheet.pdf) for the ov5640 camera datasheet.
|
||||
|
||||
!!! Warning
|
||||
This is an **Expert Parameter**! Only change it if you understand what it does!
|
||||
|
||||
After changing this parameter you need to update your reference image and alignment markers!
|
||||
@@ -1,21 +0,0 @@
|
||||
# Parameter `CamAgcGain`
|
||||
|
||||
**Auto-Gain-Control-Value**
|
||||
|
||||
Range (`0` .. `30`)
|
||||
|
||||
Default Value: `15`
|
||||
|
||||
See [here](../datasheets/Camera.ov2640_ds_1.8_.pdf) for the ov2640 camera datasheet.<br>
|
||||
See [here](../datasheets/OV5640_datasheet.pdf) for the ov5640 camera datasheet.
|
||||
|
||||
!!! Warning
|
||||
This is an **Expert Parameter**! Only change it if you understand what it does!
|
||||
|
||||
After changing this parameter you need to update your reference image and alignment markers!
|
||||
|
||||
!!! Note
|
||||
This is used when **CamAgc** is off.
|
||||
|
||||
!!! Note
|
||||
Access the gain level of the sensor, higher values produce brighter images.
|
||||
@@ -1,22 +0,0 @@
|
||||
# Parameter `CamAutoSharpness`
|
||||
|
||||
**Auto-Sharpness**
|
||||
|
||||
- When **true**, the camera attempts to automatically adjusts the sharpness.
|
||||
- When **false**, the **CamSharpness** setting is used instead.
|
||||
|
||||
Default Value: `false`
|
||||
|
||||
See [here](../datasheets/Camera.ov2640_ds_1.8_.pdf) for the ov2640 camera datasheet.<br>
|
||||
See [here](../datasheets/OV5640_datasheet.pdf) for the ov5640 camera datasheet.
|
||||
|
||||
!!! Warning
|
||||
This is an **Expert Parameter**! Only change it if you understand what it does!
|
||||
|
||||
After changing this parameter you need to update your reference image and alignment markers!
|
||||
|
||||
!!! Note
|
||||
The OV2640 does not officially support auto sharpness, this is an experimental parameter!
|
||||
|
||||
!!! Note
|
||||
This parameter can also be set on the Reference Image configuration page!
|
||||
@@ -1,16 +0,0 @@
|
||||
# Parameter `CamAwb`
|
||||
|
||||
**Auto-White-Balance**
|
||||
|
||||
- When **true**, the camera attempts to automatically control white balance.
|
||||
- When **false**, the **CamWbMode** setting is used instead.
|
||||
|
||||
Default Value: `true`
|
||||
|
||||
See [here](../datasheets/Camera.ov2640_ds_1.8_.pdf) for the ov2640 camera datasheet.<br>
|
||||
See [here](../datasheets/OV5640_datasheet.pdf) for the ov5640 camera datasheet.
|
||||
|
||||
!!! Warning
|
||||
This is an **Expert Parameter**! Only change it if you understand what it does!
|
||||
|
||||
After changing this parameter you need to update your reference image and alignment markers!
|
||||
@@ -1,15 +0,0 @@
|
||||
# Parameter `CamAwbGain`
|
||||
|
||||
**Auto-White-Balance-Gain**
|
||||
|
||||
- Enable/Disable **CamAwbGain** control.
|
||||
|
||||
Default Value: `true`
|
||||
|
||||
See [here](../datasheets/Camera.ov2640_ds_1.8_.pdf) for the ov2640 camera datasheet.<br>
|
||||
See [here](../datasheets/OV5640_datasheet.pdf) for the ov5640 camera datasheet.
|
||||
|
||||
!!! Warning
|
||||
This is an **Expert Parameter**! Only change it if you understand what it does!
|
||||
|
||||
After changing this parameter you need to update your reference image and alignment markers!
|
||||
@@ -1,15 +0,0 @@
|
||||
# Parameter `CamBpc`
|
||||
|
||||
**Black-Pixel-Correction**
|
||||
|
||||
- Enable/Disable **black point compensation**, this can make black parts of the image darker.
|
||||
|
||||
Default Value: `true`
|
||||
|
||||
See [here](../datasheets/Camera.ov2640_ds_1.8_.pdf) for the ov2640 camera datasheet.<br>
|
||||
See [here](../datasheets/OV5640_datasheet.pdf) for the ov5640 camera datasheet.
|
||||
|
||||
!!! Warning
|
||||
This is an **Expert Parameter**! Only change it if you understand what it does!
|
||||
|
||||
After changing this parameter you need to update your reference image and alignment markers!
|
||||
@@ -1,16 +0,0 @@
|
||||
# Parameter `CamBrightness`
|
||||
|
||||
**Image-Brightness**
|
||||
|
||||
Range (`-2` .. `2`)
|
||||
|
||||
Default Value: `0`
|
||||
|
||||
See [here](../datasheets/Camera.ov2640_ds_1.8_.pdf) for the ov2640 camera datasheet.<br>
|
||||
See [here](../datasheets/OV5640_datasheet.pdf) for the ov5640 camera datasheet.
|
||||
|
||||
!!! Warning
|
||||
After changing this parameter you need to update your reference image and alignment markers!
|
||||
|
||||
!!! Note
|
||||
This parameter can also be set on the Reference Image configuration page!
|
||||
@@ -1,13 +0,0 @@
|
||||
# Parameter `CamColorbar`
|
||||
|
||||
**Colorbar**
|
||||
|
||||
currently not implemented.
|
||||
|
||||
Default Value: `false`
|
||||
|
||||
See [here](../datasheets/Camera.ov2640_ds_1.8_.pdf) for the ov2640 camera datasheet.<br>
|
||||
See [here](../datasheets/OV5640_datasheet.pdf) for the ov5640 camera datasheet.
|
||||
|
||||
!!! Warning
|
||||
This is an **Expert Parameter**! Only change it if you understand what it does!
|
||||
@@ -1,16 +0,0 @@
|
||||
# Parameter `CamContrast`
|
||||
|
||||
**Image-Contrast**
|
||||
|
||||
Range (`-2` .. `2`)
|
||||
|
||||
Default Value: `0`
|
||||
|
||||
See [here](../datasheets/Camera.ov2640_ds_1.8_.pdf) for the ov2640 camera datasheet.<br>
|
||||
See [here](../datasheets/OV5640_datasheet.pdf) for the ov5640 camera datasheet.
|
||||
|
||||
!!! Warning
|
||||
After changing this parameter you need to update your reference image and alignment markers!
|
||||
|
||||
!!! Note
|
||||
This parameter can also be set on the Reference Image configuration page!
|
||||
@@ -1,21 +0,0 @@
|
||||
# Parameter `CamDcw`
|
||||
|
||||
**Image-Downsize**
|
||||
|
||||
- When **CamDcw** is on, the image that you receive will be the size that you requested (VGA, QQVGA, etc).
|
||||
- When **CamDcw** is off, the image that you receive will be one of UXGA, SVGA, or CIF.
|
||||
|
||||
Default Value: `true`
|
||||
|
||||
See [here](../datasheets/Camera.ov2640_ds_1.8_.pdf) for the ov2640 camera datasheet.<br>
|
||||
See [here](../datasheets/OV5640_datasheet.pdf) for the ov5640 camera datasheet.
|
||||
|
||||
!!! Warning
|
||||
This is an **Expert Parameter**! Only change it if you understand what it does!
|
||||
|
||||
After changing this parameter you need to update your reference image and alignment markers!
|
||||
|
||||
If **CamZoom** is used, this must be activated.
|
||||
|
||||
!!! Note
|
||||
If **CamDcw** is off, and you pick a different image size, this implicitly turns **CamDcw** back on again.
|
||||
@@ -1,15 +0,0 @@
|
||||
# Parameter `CamDenoise`
|
||||
|
||||
**Image-Denoise**
|
||||
|
||||
- Denoise Image, is only supported by OV3660 and OV5640
|
||||
|
||||
range on OV3660 and OV5640 (0 .. 8)
|
||||
|
||||
Default Value: `0`
|
||||
|
||||
See [here](../datasheets/Camera.ov2640_ds_1.8_.pdf) for the ov2640 camera datasheet.<br>
|
||||
See [here](../datasheets/OV5640_datasheet.pdf) for the ov5640 camera datasheet.
|
||||
|
||||
!!! Warning
|
||||
This is an **Expert Parameter**! Only change it if you understand what it does!
|
||||
@@ -1,33 +0,0 @@
|
||||
# Parameter `CamGainceiling`
|
||||
|
||||
**Gain-Ceiling**
|
||||
|
||||
Available options:
|
||||
|
||||
- `x2`
|
||||
- `x4`
|
||||
- `x8`
|
||||
- `x16`
|
||||
- `x32`
|
||||
- `x64`
|
||||
- `x128`
|
||||
|
||||
Default Value for ov2640: `x4`<br>
|
||||
Default Value for ov5640: `x8`
|
||||
|
||||
See [here](../datasheets/Camera.ov2640_ds_1.8_.pdf) for the ov2640 camera datasheet.<br>
|
||||
See [here](../datasheets/OV5640_datasheet.pdf) for the ov5640 camera datasheet.
|
||||
|
||||
!!! Warning
|
||||
This is an **Expert Parameter**! Only change it if you understand what it does!
|
||||
|
||||
After changing this parameter you need to update your reference image and alignment markers!
|
||||
|
||||
!!! Note
|
||||
A higher gain means that the sensor has a greater response to light, but also makes sensor noise more visible.
|
||||
|
||||
This is used when **CamAgc** is on.
|
||||
|
||||
!!! Note
|
||||
The **Gain** is an analog multiplier applied to the raw sensor data.<br>
|
||||
The **Ceiling** is the maximum gain value that the sensor will use.
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user