This commit is contained in:
michael
2026-01-17 02:49:32 +01:00
parent a1ccda2e88
commit 4905663933
283 changed files with 32074 additions and 15759 deletions

View File

@@ -1,7 +1,7 @@
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)
INCLUDE_DIRS "." "../../include"
REQUIRES esp_timer esp_wifi jomjol_tfliteclass jomjol_helper jomjol_controlcamera jomjol_mqtt jomjol_influxdb jomjol_webhook jomjol_fileserver_ota jomjol_image_proc jomjol_network openmetrics)

View File

@@ -1,114 +1,192 @@
#include "defines.h"
#include "ClassFlow.h"
#include <fstream>
#include <string>
#include <iostream>
#include <string.h>
#include "esp_log.h"
#include "../../include/defines.h"
static const char *TAG = "CLASS";
void ClassFlow::SetInitialParameter(void)
{
ListFlowControll = NULL;
previousElement = NULL;
previousElement = NULL;
disabled = false;
}
bool ClassFlow::isNewParagraph(string input)
{
if ((input[0] == '[') || ((input[0] == ';') && (input[1] == '[')))
{
return true;
}
return false;
}
bool ClassFlow::GetNextParagraph(FILE* pfile, string& aktparamgraph)
{
while (getNextLine(pfile, &aktparamgraph) && !isNewParagraph(aktparamgraph));
if (isNewParagraph(aktparamgraph))
return true;
return false;
}
ClassFlow::ClassFlow(void)
{
SetInitialParameter();
}
ClassFlow::ClassFlow(std::vector<ClassFlow*> * lfc)
ClassFlow::ClassFlow(std::vector<ClassFlow *> *lfc)
{
SetInitialParameter();
SetInitialParameter();
ListFlowControll = lfc;
}
ClassFlow::ClassFlow(std::vector<ClassFlow*> * lfc, ClassFlow *_prev)
ClassFlow::ClassFlow(std::vector<ClassFlow *> *lfc, ClassFlow *_prev)
{
SetInitialParameter();
SetInitialParameter();
ListFlowControll = lfc;
previousElement = _prev;
}
}
bool ClassFlow::ReadParameter(FILE* pfile, string &aktparamgraph)
bool ClassFlow::ReadParameter(FILE *pFile, std::string &aktparamgraph)
{
return false;
}
bool ClassFlow::doFlow(string time)
bool ClassFlow::doFlow(std::string time)
{
return false;
}
string ClassFlow::getHTMLSingleStep(string host){
std::string ClassFlow::getHTMLSingleStep(std::string host)
{
return "";
}
std::string ClassFlow::GetParameterName(std::string _input)
{
string _param;
int _pospunkt = _input.find_first_of(".");
if (_pospunkt > -1)
{
_param = _input.substr(_pospunkt+1, _input.length() - _pospunkt - 1);
}
else
{
_param = _input;
}
// ESP_LOGD(TAG, "Parameter: %s, Pospunkt: %d", _param.c_str(), _pospunkt);
std::string _param;
int _pospunkt = _input.find_first_of(".");
if (_pospunkt > -1)
{
_param = _input.substr(_pospunkt + 1, _input.length() - _pospunkt - 1);
}
else
{
_param = _input;
}
return _param;
}
bool ClassFlow::getNextLine(FILE* pfile, string *rt)
bool ClassFlow::isNewParagraph(std::string input)
{
char zw[1024];
if (pfile == NULL)
if ((input[0] == '[') || ((input[0] == ';') && (input[1] == '[')))
{
return true;
}
return false;
}
bool ClassFlow::GetNextParagraph(FILE *pFile, std::string &aktparamgraph)
{
while (getNextLine(pFile, &aktparamgraph) && !isNewParagraph(aktparamgraph));
if (isNewParagraph(aktparamgraph))
{
return true;
}
return false;
}
/*
bool ClassFlow::GetNextParagraph(FILE *pFile, std::string &aktparamgraph, bool &disabled, bool &eof)
{
while (getNextLine_new(pFile, &aktparamgraph, disabled, eof) && !isNewParagraph(aktparamgraph));
if (isNewParagraph(aktparamgraph))
{
return true;
}
return false;
}
*/
bool ClassFlow::getNextLine(FILE *pFile, std::string *rt)
{
char temp_char[1024];
if (pFile == NULL)
{
*rt = "";
return false;
}
if (!fgets(zw, 1024, pfile))
if (!fgets(temp_char, 1024, pFile))
{
*rt = "";
ESP_LOGD(TAG, "END OF FILE");
return false;
}
ESP_LOGD(TAG, "%s", zw);
*rt = zw;
*rt = trim(*rt);
while ((zw[0] == ';' || zw[0] == '#' || (rt->size() == 0)) && !(zw[1] == '['))
ESP_LOGD(TAG, "%s", temp_char);
*rt = temp_char;
*rt = trim_string_left_right(*rt);
while ((temp_char[0] == ';' || temp_char[0] == '#' || (rt->size() == 0)) && !(temp_char[1] == '['))
{
*rt = "";
if (!fgets(zw, 1024, pfile))
if (!fgets(temp_char, 1024, pFile))
{
return false;
ESP_LOGD(TAG, "%s", zw);
*rt = zw;
*rt = trim(*rt);
}
ESP_LOGD(TAG, "%s", temp_char);
*rt = temp_char;
*rt = trim_string_left_right(*rt);
}
return true;
}
/*
bool ClassFlow::getNextLine(FILE *pFile, std::string *rt, bool &disabled, bool &eof)
{
eof = false;
char zw[1024] = "";
if (pFile == NULL)
{
*rt = "";
return false;
}
if (fgets(zw, 1024, pFile))
{
ESP_LOGD(TAG, "%s", zw);
if ((strlen(zw) == 0) && feof(pFile))
{
*rt = "";
eof = true;
return false;
}
}
else
{
*rt = "";
eof = true;
return false;
}
*rt = zw;
*rt = trim_string_left_right(*rt);
while ((zw[0] == ';' || zw[0] == '#' || (rt->size() == 0)) && !(zw[1] == '['))
{
fgets(zw, 1024, pFile);
ESP_LOGD(TAG, "%s", zw);
if (feof(pFile))
{
*rt = "";
eof = true;
return false;
}
*rt = zw;
*rt = trim_string_left_right(*rt);
}
disabled = ((*rt)[0] == ';');
return true;
}
*/

View File

@@ -18,36 +18,35 @@ struct HTMLInfo
CImageBasis *image = NULL;
CImageBasis *image_org = NULL;
std::string filename;
std::string filename_org;
std::string filename_org;
};
class ClassFlow
{
protected:
bool isNewParagraph(string input);
bool GetNextParagraph(FILE* pfile, string& aktparamgraph);
bool getNextLine(FILE* pfile, string* rt);
std::vector<ClassFlow*>* ListFlowControll;
std::vector<ClassFlow *> *ListFlowControll;
ClassFlow *previousElement;
virtual void SetInitialParameter(void);
std::string GetParameterName(std::string _input);
bool disabled;
public:
ClassFlow(void);
ClassFlow(std::vector<ClassFlow*> * lfc);
ClassFlow(std::vector<ClassFlow*> * lfc, ClassFlow *_prev);
virtual bool ReadParameter(FILE* pfile, string &aktparamgraph);
virtual bool doFlow(string time);
virtual string getHTMLSingleStep(string host);
virtual string name(){return "ClassFlow";};
ClassFlow(std::vector<ClassFlow *> *lfc);
ClassFlow(std::vector<ClassFlow *> *lfc, ClassFlow *_prev);
bool isNewParagraph(std::string input);
bool GetNextParagraph(FILE *pFile, std::string &aktparamgraph);
// bool GetNextParagraph(FILE *pFile, std::string &aktparamgraph, bool &disabled, bool &eof);
bool getNextLine(FILE *pFile, std::string *rt);
// bool getNextLine(FILE *pFile, std::string *rt, bool &disabled, bool &eof);
virtual bool ReadParameter(FILE *pFile, std::string &aktparamgraph);
virtual bool doFlow(std::string time);
virtual std::string getHTMLSingleStep(std::string host);
virtual std::string name() { return "ClassFlow"; };
};
#endif //CLASSFLOW_H
#endif // CLASSFLOW_H

View File

@@ -1,4 +1,7 @@
#include "defines.h"
#include "ClassFlowAlignment.h"
#include "ClassControllCamera.h"
#include "ClassFlowTakeImage.h"
#include "ClassFlow.h"
#include "MainFlowControl.h"
@@ -8,19 +11,15 @@
#include "ClassLogFile.h"
#include "psram.h"
#include "../../include/defines.h"
static const char *TAG = "ALIGN";
// #define DEBUG_DETAIL_ON
void ClassFlowAlignment::SetInitialParameter(void)
{
initialrotate = 0;
anz_ref = 0;
use_antialiasing = false;
initialflip = false;
SaveAllFiles = false;
Camera.ImageInitialRotate = 0;
Camera.ImageAntialiasing = false;
Camera.ImageInitialFlip = false;
namerawimage = "/sdcard/img_tmp/raw.jpg";
FileStoreRefAlignment = "/sdcard/config/align.txt";
ListFlowControll = NULL;
@@ -40,126 +39,147 @@ ClassFlowAlignment::ClassFlowAlignment(std::vector<ClassFlow *> *lfc)
SetInitialParameter();
ListFlowControll = lfc;
for (int i = 0; i < ListFlowControll->size(); ++i) {
if (((*ListFlowControll)[i])->name().compare("ClassFlowTakeImage") == 0) {
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)
{
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, std::string &aktparamgraph)
{
std::vector<string> splitted;
int suchex = 40;
int suchey = 40;
int alg_algo = 0; // default=0; 1 =HIGHACCURACY; 2= FAST; 3= OFF //add disable aligment algo |01.2023
aktparamgraph = trim(aktparamgraph);
aktparamgraph = trim_string_left_right(aktparamgraph);
if (aktparamgraph.size() == 0)
{
if (!this->GetNextParagraph(pfile, aktparamgraph)) {
if (!GetNextParagraph(pfile, aktparamgraph))
{
return false;
}
}
if (aktparamgraph.compare("[Alignment]") != 0)
if ((to_upper(aktparamgraph).compare("[ALIGNMENT]") != 0) && (to_upper(aktparamgraph).compare(";[ALIGNMENT]") != 0))
{
// Paragraph does not fit Alignment
return false;
}
while (this->getNextLine(pfile, &aktparamgraph) && !this->isNewParagraph(aktparamgraph))
int suchex = 20;
int suchey = 20;
int maxangle = 45;
int alg_algo = 0; // default=0; 1 =HIGHACCURACY; 2= FAST; 3= OFF //add disable aligment algo |01.2023
std::vector<std::string> splitted;
while (getNextLine(pfile, &aktparamgraph) && !isNewParagraph(aktparamgraph))
{
splitted = ZerlegeZeile(aktparamgraph);
splitted = split_line(aktparamgraph);
if ((toUpper(splitted[0]) == "FLIPIMAGESIZE") && (splitted.size() > 1)) {
initialflip = alphanumericToBoolean(splitted[1]);
}
else if (((toUpper(splitted[0]) == "initialrotate") || (toUpper(splitted[0]) == "INITIALROTATE")) && (splitted.size() > 1)) {
if (isStringNumeric(splitted[1])) {
this->initialrotate = std::stod(splitted[1]);
}
}
else if ((toUpper(splitted[0]) == "SEARCHFIELDX") && (splitted.size() > 1)) {
if (isStringNumeric(splitted[1])) {
suchex = std::stod(splitted[1]);
}
}
else if ((toUpper(splitted[0]) == "SEARCHFIELDY") && (splitted.size() > 1)) {
if (isStringNumeric(splitted[1])) {
suchey = std::stod(splitted[1]);
}
}
else if ((toUpper(splitted[0]) == "ANTIALIASING") && (splitted.size() > 1)) {
use_antialiasing = alphanumericToBoolean(splitted[1]);
}
else if ((splitted.size() == 3) && (anz_ref < 2)) {
if ((isStringNumeric(splitted[1])) && (isStringNumeric(splitted[2])))
{
References[anz_ref].image_file = FormatFileName("/sdcard" + splitted[0]);
References[anz_ref].target_x = std::stod(splitted[1]);
References[anz_ref].target_y = std::stod(splitted[2]);
anz_ref++;
}
else
{
References[anz_ref].image_file = FormatFileName("/sdcard" + splitted[0]);
References[anz_ref].target_x = 10;
References[anz_ref].target_y = 10;
anz_ref++;
}
}
if (splitted.size() > 1)
{
std::string _param = to_upper(splitted[0]);
else if ((toUpper(splitted[0]) == "SAVEALLFILES") && (splitted.size() > 1)) {
SaveAllFiles = alphanumericToBoolean(splitted[1]);
}
else if ((toUpper(splitted[0]) == "ALIGNMENTALGO") && (splitted.size() > 1)) {
#ifdef DEBUG_DETAIL_ON
std::string zw2 = "Alignment mode selected: " + splitted[1];
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, zw2);
#endif
if (toUpper(splitted[1]) == "HIGHACCURACY") {
alg_algo = 1;
if (_param == "FLIPIMAGESIZE")
{
Camera.ImageInitialFlip = alphanumeric_to_boolean(splitted[1]);
}
if (toUpper(splitted[1]) == "FAST") {
alg_algo = 2;
else if (_param == "INITIALROTATE")
{
if (is_string_numeric(splitted[1]))
{
Camera.ImageInitialRotate = std::stod(splitted[1]);
}
}
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;
else if (_param == "SEARCHFIELDX")
{
if (is_string_numeric(splitted[1]))
{
suchex = clip_int(std::stoi(splitted[1]), 320, 0);
}
}
else if (_param == "SEARCHFIELDY")
{
if (is_string_numeric(splitted[1]))
{
suchey = clip_int(std::stoi(splitted[1]), 240, 0);
}
}
else if (_param == "SEARCHMAXANGLE")
{
if (is_string_numeric(splitted[1]))
{
maxangle = clip_int(std::stoi(splitted[1]), 180, 0);
}
}
else if (_param == "ANTIALIASING")
{
Camera.ImageAntialiasing = alphanumeric_to_boolean(splitted[1]);
}
else if (_param == "ALIGNMENTALGO")
{
if (to_upper(splitted[1]) == "HIGHACCURACY")
{
alg_algo = 1;
}
else if (to_upper(splitted[1]) == "FAST")
{
alg_algo = 2;
}
else if (to_upper(splitted[1]) == "OFF")
{
// no align algo if set to 3 = off => no draw ref //add disable aligment algo |01.2023
alg_algo = 3;
}
}
else if ((splitted.size() == 3) && (anz_ref < 2))
{
if (is_string_numeric(splitted[1]) && is_string_numeric(splitted[2]))
{
References[anz_ref].image_file = format_filename("/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 = format_filename("/sdcard" + splitted[0]);
References[anz_ref].target_x = 10;
References[anz_ref].target_y = 10;
anz_ref++;
}
}
}
}
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].search_max_angle = (float)maxangle;
References[i].fastalg_SAD_criteria = SAD_criteria;
References[i].alignment_algo = alg_algo;
#ifdef DEBUG_DETAIL_ON
std::string zw2 = "Alignment mode written: " + std::to_string(alg_algo);
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, zw2);
#endif
}
// no align algo if set to 3 = off => no draw ref //add disable aligment algo |01.2023
if (References[0].alignment_algo != 3) {
if (References[0].alignment_algo != 3)
{
return LoadReferenceAlignmentValues();
}
return true;
}
string ClassFlowAlignment::getHTMLSingleStep(string host)
std::string ClassFlowAlignment::getHTMLSingleStep(std::string host)
{
string result;
std::string result;
result = "<p>Rotated Image: </p> <p><img src=\"" + host + "/img_tmp/rot.jpg\"></p>\n";
result = result + "<p>Found Alignment: </p> <p><img src=\"" + host + "/img_tmp/rot_roi.jpg\"></p>\n";
@@ -167,29 +187,34 @@ string ClassFlowAlignment::getHTMLSingleStep(string host)
return result;
}
bool ClassFlowAlignment::doFlow(string time)
bool ClassFlowAlignment::doFlow(std::string time)
{
#ifdef ALGROI_LOAD_FROM_MEM_AS_JPG
// AlgROI needs to be allocated before ImageTMP to avoid heap fragmentation
if (!AlgROI) {
if (!AlgROI)
{
AlgROI = (ImageData *)heap_caps_realloc(AlgROI, sizeof(ImageData), MALLOC_CAP_8BIT | MALLOC_CAP_SPIRAM);
if (!AlgROI) {
if (!AlgROI)
{
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Can't allocate AlgROI");
LogFile.WriteHeapInfo("ClassFlowAlignment-doFlow");
}
}
if (AlgROI) {
if (AlgROI)
{
ImageBasis->writeToMemoryAsJPG((ImageData *)AlgROI, 90);
}
#endif
if (!ImageTMP) {
ImageTMP = new CImageBasis("tmpImage", ImageBasis); // Make sure the name does not get change, it is relevant for the PSRAM allocation!
if (!ImageTMP)
{
ImageTMP = new CImageBasis("TempImage", ImageBasis); // Make sure the name does not get change, it is relevant for the PSRAM allocation!
if (!ImageTMP) {
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Can't allocate tmpImage -> Exec this round aborted!");
if (!ImageTMP)
{
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Can't allocate TempImage -> Exec this round aborted!");
LogFile.WriteHeapInfo("ClassFlowAlignment-doFlow");
return false;
}
@@ -198,48 +223,74 @@ 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);
CRotateImage rt("rawImage", AlignAndCutImage, ImageTMP, Camera.ImageInitialFlip);
if (initialflip) {
int _zw = ImageBasis->height;
if (Camera.ImageInitialFlip)
{
int temp_value = ImageBasis->height;
ImageBasis->height = ImageBasis->width;
ImageBasis->width = _zw;
ImageBasis->width = temp_value;
_zw = ImageTMP->width;
temp_value = ImageTMP->width;
ImageTMP->width = ImageTMP->height;
ImageTMP->height = _zw;
ImageTMP->height = temp_value;
}
if ((initialrotate != 0) || initialflip) {
if (use_antialiasing) {
rt.RotateAntiAliasing(initialrotate);
if (((Camera.ImageInitialRotate > 0) && (Camera.ImageInitialRotate < 360)) || Camera.ImageInitialFlip)
{
if (Camera.ImageAntialiasing)
{
rt.RotateAntiAliasing(Camera.ImageInitialRotate);
}
else {
rt.Rotate(initialrotate);
else
{
rt.Rotate(Camera.ImageInitialRotate);
}
if (SaveAllFiles) {
AlignAndCutImage->SaveToFile(FormatFileName("/sdcard/img_tmp/rot.jpg"));
if (Camera.SaveAllFiles)
{
AlignAndCutImage->SaveToFile(format_filename("/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();
if (References[0].alignment_algo != 3)
{
int res = AlignAndCutImage->Align(&References[0], &References[1]);
if (res >= Alignment_OK)
{
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Alignment OK");
if (res == Fast_Alignment_OK)
{
SaveReferenceAlignmentValues();
}
flowctrl.AlignmentOk = true;
}
} // no align
else
{
// Alignment failed
LogFile.WriteToFile(ESP_LOG_WARN, TAG, "Alignment failed");
flowctrl.AlignmentOk = false;
}
}
else
{
flowctrl.AlignmentOk = true;
}
#ifdef ALGROI_LOAD_FROM_MEM_AS_JPG
if (AlgROI) {
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) {
if (References[0].alignment_algo != 3)
{
DrawRef(ImageTMP);
}
@@ -249,31 +300,26 @@ bool ClassFlowAlignment::doFlow(string time)
}
#endif
if (SaveAllFiles) {
AlignAndCutImage->SaveToFile(FormatFileName("/sdcard/img_tmp/alg.jpg"));
ImageTMP->SaveToFile(FormatFileName("/sdcard/img_tmp/alg_roi.jpg"));
if (Camera.SaveAllFiles)
{
AlignAndCutImage->SaveToFile(format_filename("/sdcard/img_tmp/alg.jpg"));
ImageTMP->SaveToFile(format_filename("/sdcard/img_tmp/alg_roi.jpg"));
}
// must be deleted to have memory space for loading tflite
delete ImageTMP;
ImageTMP = NULL;
// no align algo if set to 3 = off => no draw ref //add disable aligment algo |01.2023
if (References[0].alignment_algo != 3) {
return LoadReferenceAlignmentValues();
}
return true;
}
void ClassFlowAlignment::SaveReferenceAlignmentValues()
void ClassFlowAlignment::SaveReferenceAlignmentValues(void)
{
FILE *pFile;
std::string zwtime, zwvalue;
FILE *pFile = fopen(FileStoreRefAlignment.c_str(), "w");
pFile = fopen(FileStoreRefAlignment.c_str(), "w");
if (strlen(zwtime.c_str()) == 0) {
std::string temp_time;
if (strlen(temp_time.c_str()) == 0)
{
time_t rawtime;
struct tm *timeinfo;
char buffer[80];
@@ -282,22 +328,22 @@ void ClassFlowAlignment::SaveReferenceAlignmentValues()
timeinfo = localtime(&rawtime);
strftime(buffer, 80, "%Y-%m-%dT%H:%M:%S", timeinfo);
zwtime = std::string(buffer);
temp_time = std::string(buffer);
}
fputs(zwtime.c_str(), pFile);
fputs(temp_time.c_str(), pFile);
fputs("\n", pFile);
zwvalue = std::to_string(References[0].fastalg_x) + "\t" + std::to_string(References[0].fastalg_y);
zwvalue = zwvalue + "\t" + std::to_string(References[0].fastalg_SAD) + "\t" + std::to_string(References[0].fastalg_min);
zwvalue = zwvalue + "\t" + std::to_string(References[0].fastalg_max) + "\t" + std::to_string(References[0].fastalg_avg);
fputs(zwvalue.c_str(), pFile);
std::string temp_value = std::to_string(References[0].fastalg_x) + "\t" + std::to_string(References[0].fastalg_y);
temp_value = temp_value + "\t" + std::to_string(References[0].fastalg_SAD) + "\t" + std::to_string(References[0].fastalg_min);
temp_value = temp_value + "\t" + std::to_string(References[0].fastalg_max) + "\t" + std::to_string(References[0].fastalg_avg);
fputs(temp_value.c_str(), pFile);
fputs("\n", pFile);
zwvalue = std::to_string(References[1].fastalg_x) + "\t" + std::to_string(References[1].fastalg_y);
zwvalue = zwvalue + "\t" + std::to_string(References[1].fastalg_SAD) + "\t" + std::to_string(References[1].fastalg_min);
zwvalue = zwvalue + "\t" + std::to_string(References[1].fastalg_max) + "\t" + std::to_string(References[1].fastalg_avg);
fputs(zwvalue.c_str(), pFile);
temp_value = std::to_string(References[1].fastalg_x) + "\t" + std::to_string(References[1].fastalg_y);
temp_value = temp_value + "\t" + std::to_string(References[1].fastalg_SAD) + "\t" + std::to_string(References[1].fastalg_min);
temp_value = temp_value + "\t" + std::to_string(References[1].fastalg_max) + "\t" + std::to_string(References[1].fastalg_avg);
fputs(temp_value.c_str(), pFile);
fputs("\n", pFile);
fclose(pFile);
@@ -305,70 +351,100 @@ void ClassFlowAlignment::SaveReferenceAlignmentValues()
bool ClassFlowAlignment::LoadReferenceAlignmentValues(void)
{
FILE *pFile;
char zw[1024];
string zwvalue;
std::vector<string> splitted;
pFile = fopen(FileStoreRefAlignment.c_str(), "r");
if (pFile == NULL) {
FILE *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) {
char temp_bufer[1024];
// erste Zeile: 2025-03-16T18:50:22
if (!fgets(temp_bufer, 1024, pFile))
{
fclose(pFile);
ESP_LOGE(TAG, "/sdcard/config/align.txt empty!");
return false;
}
References[0].fastalg_x = stoi(splitted[0]);
References[0].fastalg_y = stoi(splitted[1]);
References[0].fastalg_SAD = stof(splitted[2]);
References[0].fastalg_min = stoi(splitted[3]);
References[0].fastalg_max = stoi(splitted[4]);
References[0].fastalg_avg = stof(splitted[5]);
fgets(zw, 1024, pFile);
splitted = ZerlegeZeile(std::string(zw));
if (splitted.size() < 6) {
// zweite Zeile: 177 342 -0.000000 6144 1611659784 0.000000
if (!fgets(temp_bufer, 1024, pFile))
{
fclose(pFile);
ESP_LOGE(TAG, "/sdcard/config/align.txt empty!");
return false;
}
References[1].fastalg_x = stoi(splitted[0]);
References[1].fastalg_y = stoi(splitted[1]);
References[1].fastalg_SAD = stof(splitted[2]);
References[1].fastalg_min = stoi(splitted[3]);
References[1].fastalg_max = stoi(splitted[4]);
References[1].fastalg_avg = stof(splitted[5]);
std::vector<std::string> splitted;
splitted = split_line(temp_bufer, "\t");
if (splitted.size() < 6)
{
fclose(pFile);
ESP_LOGE(TAG, "/sdcard/config/align.txt wrong format!");
return false;
}
if (is_string_numeric(splitted[0]) && is_string_numeric(splitted[1]) && is_string_numeric(splitted[2]) &&
is_string_numeric(splitted[3]) && is_string_numeric(splitted[4]) && is_string_numeric(splitted[5]))
{
References[0].fastalg_x = stoi(splitted[0]);
References[0].fastalg_y = stoi(splitted[1]);
References[0].fastalg_SAD = stof(splitted[2]);
References[0].fastalg_min = stoi(splitted[3]);
References[0].fastalg_max = stoi(splitted[4]);
References[0].fastalg_avg = stof(splitted[5]);
}
else
{
fclose(pFile);
ESP_LOGE(TAG, "/sdcard/config/align.txt wrong format!");
return false;
}
// dritte Zeile: 398 145 -0.000000 6144 1611659784 0.000000
if (!fgets(temp_bufer, 1024, pFile))
{
fclose(pFile);
ESP_LOGE(TAG, "/sdcard/config/align.txt empty!");
return false;
}
splitted = split_line(temp_bufer, "\t");
if (splitted.size() < 6)
{
fclose(pFile);
ESP_LOGE(TAG, "/sdcard/config/align.txt wrong format!");
return false;
}
if (is_string_numeric(splitted[0]) && is_string_numeric(splitted[1]) && is_string_numeric(splitted[2]) &&
is_string_numeric(splitted[3]) && is_string_numeric(splitted[4]) && is_string_numeric(splitted[5]))
{
References[1].fastalg_x = stoi(splitted[0]);
References[1].fastalg_y = stoi(splitted[1]);
References[1].fastalg_SAD = stof(splitted[2]);
References[1].fastalg_min = stoi(splitted[3]);
References[1].fastalg_max = stoi(splitted[4]);
References[1].fastalg_avg = stof(splitted[5]);
}
else
{
fclose(pFile);
ESP_LOGE(TAG, "/sdcard/config/align.txt wrong format!");
return false;
}
fclose(pFile);
/*#ifdef DEBUG_DETAIL_ON
std::string _zw = "\tLoadReferences[0]\tx,y:\t" + std::to_string(References[0].fastalg_x) + "\t" + std::to_string(References[0].fastalg_x);
_zw = _zw + "\tSAD, min, max, avg:\t" + std::to_string(References[0].fastalg_SAD) + "\t" + std::to_string(References[0].fastalg_min);
_zw = _zw + "\t" + std::to_string(References[0].fastalg_max) + "\t" + std::to_string(References[0].fastalg_avg);
LogFile.WriteToDedicatedFile("/sdcard/alignment.txt", _zw);
_zw = "\tLoadReferences[1]\tx,y:\t" + std::to_string(References[1].fastalg_x) + "\t" + std::to_string(References[1].fastalg_x);
_zw = _zw + "\tSAD, min, max, avg:\t" + std::to_string(References[1].fastalg_SAD) + "\t" + std::to_string(References[1].fastalg_min);
_zw = _zw + "\t" + std::to_string(References[1].fastalg_max) + "\t" + std::to_string(References[1].fastalg_avg);
LogFile.WriteToDedicatedFile("/sdcard/alignment.txt", _zw);
#endif*/
return true;
}
void ClassFlowAlignment::DrawRef(CImageBasis *_zw)
void ClassFlowAlignment::DrawRef(CImageBasis *Image)
{
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);
if (Image->ImageOkay())
{
Image->drawRect(References[0].target_x, References[0].target_y, References[0].width, References[0].height, 255, 0, 0, 2);
Image->drawRect(References[1].target_x, References[1].target_y, References[1].width, References[1].height, 255, 0, 0, 2);
}
}

View File

@@ -3,25 +3,21 @@
#ifndef CLASSFLOWALIGNMENT_H
#define CLASSFLOWALIGNMENT_H
#include <string>
#include "ClassFlow.h"
#include "Helper.h"
#include "CAlignAndCutImage.h"
#include "CFindTemplate.h"
#include <string>
using namespace std;
class ClassFlowAlignment : public ClassFlow
{
protected:
float initialrotate;
bool initialflip;
bool use_antialiasing;
RefInfo References[2];
int anz_ref;
string namerawimage;
bool SaveAllFiles;
std::string namerawimage;
CAlignAndCutImage *AlignAndCutImage;
std::string FileStoreRefAlignment;
float SAD_criteria;
@@ -40,12 +36,12 @@ public:
CAlignAndCutImage *GetAlignAndCutImage() { return AlignAndCutImage; };
void DrawRef(CImageBasis *_zw);
void DrawRef(CImageBasis *Image);
bool ReadParameter(FILE *pfile, string &aktparamgraph);
bool doFlow(string time);
string getHTMLSingleStep(string host);
string name() { return "ClassFlowAlignment"; };
bool ReadParameter(FILE *pfile, std::string &aktparamgraph);
bool doFlow(std::string time);
std::string getHTMLSingleStep(std::string host);
std::string name() { return "ClassFlowAlignment"; };
};
#endif // CLASSFLOWALIGNMENT_H

File diff suppressed because it is too large Load Diff

View File

@@ -3,11 +3,11 @@
#ifndef CLASSFLOWCNNGENERAL_H
#define CLASSFLOWCNNGENERAL_H
#include"ClassFlowDefineTypes.h"
#include "ClassFlowDefineTypes.h"
#include "ClassFlowAlignment.h"
enum t_CNNType {
enum t_CNNType
{
AutoDetect,
Analogue,
Analogue100,
@@ -16,64 +16,68 @@ enum t_CNNType {
DoubleHyprid10,
Digit100,
None
};
};
class ClassFlowCNNGeneral :
public ClassFlowImage
class ClassFlowCNNGeneral : public ClassFlowImage
{
protected:
t_CNNType CNNType;
std::vector<general*> GENERAL;
std::vector<general *> GENERAL;
float CNNGoodThreshold;
string cnnmodelfile;
int modelxsize, modelysize, modelchannel;
std::string cnn_model_file;
int model_x_size;
int model_y_size;
int model_channel;
bool isLogImageSelect;
string LogImageSelect;
ClassFlowAlignment* flowpostalignment;
std::string LogImageSelect;
bool SaveAllFiles;
ClassFlowAlignment *flowpostalignment;
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 PointerEvalAnalog(float number, int numeral_preceder);
int PointerEvalAnalogToDigit(float number, float numeral_preceder, int eval_predecessors, float AnalogToDigitTransitionStart);
int PointerEvalHybrid(float number, float number_of_predecessors, int eval_predecessors, bool Analog_Predecessors = false, float AnalogToDigitTransitionStart = 9.2);
bool doNeuralNetwork(std::string time_value);
bool doNeuralNetwork(string time);
bool doAlignAndCut(string time);
bool doAlignAndCut(std::string time_value);
bool getNetworkParameter();
public:
ClassFlowCNNGeneral(ClassFlowAlignment *_flowalign, t_CNNType _cnntype = AutoDetect);
bool ReadParameter(FILE* pfile, string& aktparamgraph);
bool doFlow(string time);
bool ReadParameter(FILE *pfile, std::string &aktparamgraph);
bool doFlow(std::string time_value);
string getHTMLSingleStep(string host);
string getReadout(int _analog, bool _extendedResolution = false, int prev = -1, float _before_narrow_Analog = -1, float AnalogToDigitTransitionStart=9.2);
std::string getHTMLSingleStep(std::string host);
string getReadoutRawString(int _analog);
std::vector<double> getMeterValues(int _number);
void DrawROI(CImageBasis *_zw);
std::string getReadout(int _number, bool _extendedResolution = false, int prev = -1, float _before_narrow_Analog = -1, float AnalogToDigitTransitionStart = 9.2);
std::vector<HTMLInfo*> GetHTMLInfo();
std::string getReadoutRawString(int _number);
int getNumberGENERAL();
general* GetGENERAL(int _analog);
general* GetGENERAL(string _name, bool _create);
general* FindGENERAL(string _name_number);
string getNameGENERAL(int _analog);
void DrawROI(CImageBasis *Image);
std::vector<HTMLInfo *> GetHTMLInfo(void);
int getNumberGENERAL(void);
general *GetGENERAL(int _number);
general *GetGENERAL(std::string _name, bool _create);
general *FindGENERAL(std::string _name_number);
std::string getNameGENERAL(int _number);
bool isExtendedResolution(int _number = 0);
void UpdateNameNumbers(std::vector<std::string> *_name_numbers);
t_CNNType getCNNType(){return CNNType;};
t_CNNType getCNNType() { return CNNType; };
string name(){return "ClassFlowCNNGeneral";};
std::string name() { return "ClassFlowCNNGeneral"; };
};
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -10,62 +10,57 @@
#include "ClassFlowAlignment.h"
#include "ClassFlowCNNGeneral.h"
#include "ClassFlowPostProcessing.h"
#ifdef ENABLE_MQTT
#include "ClassFlowMQTT.h"
#endif //ENABLE_MQTT
#ifdef ENABLE_INFLUXDB
#include "ClassFlowInfluxDB.h"
#include "ClassFlowInfluxDBv2.h"
#endif //ENABLE_INFLUXDB
#ifdef ENABLE_WEBHOOK
#include "ClassFlowWebhook.h"
#endif //ENABLE_WEBHOOK
#include "ClassFlowMQTT.h"
#include "ClassFlowInfluxDB.h"
#include "ClassFlowInfluxDBv2.h"
#include "ClassFlowWebhook.h"
#include "ClassFlowCNNGeneral.h"
class ClassFlowControll :
public ClassFlow
class ClassFlowControll : public ClassFlow
{
protected:
std::vector<ClassFlow*> FlowControll;
ClassFlowPostProcessing* flowpostprocessing;
ClassFlowAlignment* flowalignment;
ClassFlowCNNGeneral* flowanalog;
ClassFlowCNNGeneral* flowdigit;
// ClassFlowDigit* flowdigit;
ClassFlowTakeImage* flowtakeimage;
ClassFlow* CreateClassFlow(std::string _type);
std::vector<ClassFlow *> FlowControll;
ClassFlowPostProcessing *flowpostprocessing;
ClassFlowAlignment *flowalignment;
ClassFlowCNNGeneral *flowanalog;
ClassFlowCNNGeneral *flowdigit;
// ClassFlowDigit* flowdigit;
ClassFlowTakeImage *flowtakeimage;
ClassFlow *CreateClassFlow(std::string _type);
bool AutoStart;
float AutoInterval;
void SetInitialParameter(void);
void SetInitialParameter(void);
std::string aktstatusWithTime;
std::string aktstatus;
int aktRunNr;
public:
bool SetupModeActive;
bool AutoStart = false;
float AutoInterval = 5;
bool SetupModeActive = false;
bool AlignmentOk = false;
void InitFlow(std::string config);
bool doFlow(string time);
void doFlowTakeImageOnly(string time);
bool getStatusSetupModus(){return SetupModeActive;};
string getReadout(bool _rawvalue, bool _noerror, int _number);
string getReadoutAll(int _type);
bool doFlow(std::string time);
void doFlowTakeImageOnly(std::string time);
bool getStatusSetupModus() { return SetupModeActive; };
std::string getReadout(bool _rawvalue, bool _noerror, int _number);
std::string getReadoutAll(int _type);
bool UpdatePrevalue(std::string _newvalue, std::string _numbers, bool _extern);
string GetPrevalue(std::string _number = "");
bool ReadParameter(FILE* pfile, string& aktparamgraph);
string getJSON();
const std::vector<NumberPost*> &getNumbers();
string getNumbersName();
std::string GetPrevalue(std::string _number = "");
bool ReadParameter(FILE *pFile, string &aktparamgraph);
std::string getJSON();
const std::vector<NumberPost *> &getNumbers();
std::string getNumbersName();
string TranslateAktstatus(std::string _input);
std::string TranslateAktstatus(std::string _input);
#ifdef ALGROI_LOAD_FROM_MEM_AS_JPG
void DigitDrawROI(CImageBasis *_zw);
void AnalogDrawROI(CImageBasis *_zw);
#endif
#ifdef ALGROI_LOAD_FROM_MEM_AS_JPG
void DigitDrawROI(CImageBasis *TempImage);
void AnalogDrawROI(CImageBasis *TempImage);
#endif
esp_err_t GetJPGStream(std::string _fn, httpd_req_t *req);
esp_err_t GetJPGStream(std::string file_name, httpd_req_t *req);
esp_err_t SendRawJPG(httpd_req_t *req);
std::string doSingleStep(std::string _stepname, std::string _host);
@@ -73,26 +68,21 @@ public:
bool getIsAutoStart();
void setAutoStartInterval(long &_interval);
std::string* getActStatusWithTime();
std::string* getActStatus();
std::string *getActStatusWithTime();
std::string *getActStatus();
void setActStatus(std::string _aktstatus);
std::vector<HTMLInfo*> GetAllDigit();
std::vector<HTMLInfo*> GetAllAnalog();
std::vector<HTMLInfo *> GetAllDigit();
std::vector<HTMLInfo *> GetAllAnalog();
t_CNNType GetTypeDigit();
t_CNNType GetTypeAnalog();
#ifdef ENABLE_MQTT
bool StartMQTTService();
#endif //ENABLE_MQTT
int CleanTempFolder();
string name(){return "ClassFlowControll";};
std::string name() { return "ClassFlowControll"; };
};
#endif

View File

@@ -5,81 +5,81 @@
#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;
struct roi
{
int pos_x;
int pos_y;
int delta_x;
int delta_y;
float raw_result_float;
int raw_result_klasse;
float result_float;
int result_klasse;
bool isReject, CCW;
bool isReject;
bool ccw;
string name;
CImageBasis *image, *image_org;
CImageBasis *image;
CImageBasis *image_org;
};
/**
* FIXME: Why is this additional layer needed?
*/
struct general {
struct general
{
string name;
std::vector<roi*> ROI;
std::vector<roi *> ROI;
};
enum t_RateType {
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
};
};
/**
* 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 IgnoreLeadingNaN;
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
struct NumberPost
{
float MaxFlowRate;
bool useMaxFlowRate;
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 IgnoreLeadingNaN; //
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; //
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
int Nachkomma; // decimalPlaces; usually defined by the number of analog ROIs; affected by DecimalShift
string DomoticzIdx; // Domoticz counter Idx
string FieldV1; // influxdbFieldName_v1; Name of the Field in InfluxDBv1
string MeasurementV1; // influxdbMeasurementName_v1; Name of the Measurement in InfluxDBv1
string DomoticzIdx; // Domoticz counter Idx
string FieldV2; // influxdbFieldName_v2; Name of the Field in InfluxDBv2
string MeasurementV2; // influxdbMeasurementName_v2; Name of the Measurement in InfluxDBv2
string FieldV1; // influxdbFieldName_v1; Name of the Field in InfluxDBv1
string MeasurementV1; // influxdbMeasurementName_v1; Name of the Measurement in InfluxDBv1
bool isExtendedResolution; // extendResolution; Adds the decimal place of the least significant analog ROI to the value
string FieldV2; // influxdbFieldName_v2; Name of the Field in InfluxDBv2
string MeasurementV2; // influxdbMeasurementName_v2; Name of the Measurement in InfluxDBv2
general *digit_roi; // digitRoi; set of digit ROIs for the sequence
general *analog_roi; // analogRoi; set of analog ROIs for the sequence
bool isExtendedResolution; // extendResolution; Adds the decimal place of the least significant analog ROI to the value
string name; // name; Designation for the sequence
general *digit_roi; // digitRoi; set of digit ROIs for the sequence
general *analog_roi; // analogRoi; set of analog ROIs for the sequence
string name; // name; Designation for the sequence
};
#endif

View File

@@ -1,71 +1,66 @@
#include "defines.h"
#include "ClassFlowImage.h"
#include <string>
#include <string.h>
#include <sys/stat.h>
#ifdef __cplusplus
extern "C" {
#endif
#include <dirent.h>
#ifdef __cplusplus
}
#endif
#include "time_sntp.h"
#include "ClassLogFile.h"
#include "CImageBasis.h"
#include "esp_log.h"
#include "../../include/defines.h"
static const char* TAG = "FLOWIMAGE";
static const char *TAG = "FLOWIMAGE";
ClassFlowImage::ClassFlowImage(const char* logTag)
ClassFlowImage::ClassFlowImage(const char *logTag)
{
this->logTag = logTag;
isLogImage = false;
this->logTag = logTag;
isLogImage = false;
disabled = false;
this->imagesRetention = 5;
}
ClassFlowImage::ClassFlowImage(std::vector<ClassFlow*> * lfc, const char* logTag) : ClassFlow(lfc)
ClassFlowImage::ClassFlowImage(std::vector<ClassFlow *> *lfc, const char *logTag) : ClassFlow(lfc)
{
this->logTag = logTag;
isLogImage = false;
this->logTag = logTag;
isLogImage = false;
disabled = false;
this->imagesRetention = 5;
}
ClassFlowImage::ClassFlowImage(std::vector<ClassFlow*> * lfc, ClassFlow *_prev, const char* logTag) : ClassFlow(lfc, _prev)
ClassFlowImage::ClassFlowImage(std::vector<ClassFlow *> *lfc, ClassFlow *_prev, const char *logTag) : ClassFlow(lfc, _prev)
{
this->logTag = logTag;
isLogImage = false;
this->logTag = logTag;
isLogImage = false;
disabled = false;
this->imagesRetention = 5;
}
string ClassFlowImage::CreateLogFolder(string time)
{
if (!isLogImage)
return "";
string ClassFlowImage::CreateLogFolder(string time) {
if (!isLogImage)
return "";
string logPath = imagesLocation + "/" + time.LOGFILE_TIME_FORMAT_DATE_EXTR + "/" + time.LOGFILE_TIME_FORMAT_HOUR_EXTR;
string logPath = imagesLocation + "/" + time.LOGFILE_TIME_FORMAT_DATE_EXTR + "/" + time.LOGFILE_TIME_FORMAT_HOUR_EXTR;
isLogImage = mkdir_r(logPath.c_str(), S_IRWXU) == 0;
if (!isLogImage) {
if (!isLogImage)
{
LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Can't create log folder for analog images. Path " + logPath);
}
return logPath;
return logPath;
}
void ClassFlowImage::LogImage(string logPath, string name, float *resultFloat, int *resultInt, string time, CImageBasis *_img) {
if (!isLogImage)
return;
char buf[10];
void ClassFlowImage::LogImage(string logPath, string name, float *resultFloat, int *resultInt, string time, CImageBasis *_img)
{
if (!isLogImage)
return;
if (resultFloat != NULL) {
char buf[10];
if (resultFloat != NULL)
{
if (*resultFloat < 0)
sprintf(buf, "N.N_");
else
@@ -74,47 +69,51 @@ void ClassFlowImage::LogImage(string logPath, string name, float *resultFloat, i
if (strcmp(buf, "10.0_") == 0)
sprintf(buf, "0.0_");
}
} else if (resultInt != NULL) {
sprintf(buf, "%d_", *resultInt);
} else {
buf[0] = '\0';
}
}
else if (resultInt != NULL)
{
sprintf(buf, "%d_", *resultInt);
}
else
{
buf[0] = '\0';
}
string nm = logPath + "/" + buf + name + "_" + time + ".jpg";
nm = FormatFileName(nm);
string output = "/sdcard/img_tmp/" + name + ".jpg";
output = FormatFileName(output);
ESP_LOGD(logTag, "save to file: %s", nm.c_str());
_img->SaveToFile(nm);
// CopyFile(output, nm);
string nm = logPath + "/" + buf + name + "_" + time + ".jpg";
nm = format_filename(nm);
string output = "/sdcard/img_tmp/" + name + ".jpg";
output = format_filename(output);
ESP_LOGD(logTag, "save to file: %s", nm.c_str());
_img->SaveToFile(nm);
}
void ClassFlowImage::RemoveOldLogs()
{
if (!isLogImage)
return;
ESP_LOGD(TAG, "remove old images");
if (imagesRetention == 0) {
if (!isLogImage)
{
return;
}
ESP_LOGD(TAG, "remove old images");
if (imagesRetention == 0)
{
return;
}
time_t rawtime;
struct tm* timeinfo;
struct tm *timeinfo;
char cmpfilename[30];
time(&rawtime);
rawtime = addDays(rawtime, -1 * imagesRetention + 1);
rawtime = add_days(rawtime, -1 * imagesRetention + 1);
timeinfo = localtime(&rawtime);
//ESP_LOGD(TAG, "ImagefileRetentionInDays: %d", imagesRetention);
strftime(cmpfilename, 30, LOGFILE_TIME_FORMAT, timeinfo);
//ESP_LOGD(TAG, "file name to compare: %s", cmpfilename);
string folderName = string(cmpfilename).LOGFILE_TIME_FORMAT_DATE_EXTR;
string folderName = string(cmpfilename).LOGFILE_TIME_FORMAT_DATE_EXTR;
DIR *dir = opendir(imagesLocation.c_str());
if (!dir) {
if (!dir)
{
ESP_LOGE(TAG, "Failed to stat dir: %s", imagesLocation.c_str());
return;
}
@@ -122,19 +121,22 @@ void ClassFlowImage::RemoveOldLogs()
struct dirent *entry;
int deleted = 0;
int notDeleted = 0;
while ((entry = readdir(dir)) != NULL) {
while ((entry = readdir(dir)) != NULL)
{
string folderPath = imagesLocation + "/" + entry->d_name;
if (entry->d_type == DT_DIR) {
//ESP_LOGD(TAG, "Compare %s to %s", entry->d_name, folderName.c_str());
if ((strlen(entry->d_name) == folderName.length()) && (strcmp(entry->d_name, folderName.c_str()) < 0)) {
removeFolder(folderPath.c_str(), logTag);
if (entry->d_type == DT_DIR)
{
if ((strlen(entry->d_name) == folderName.length()) && (strcmp(entry->d_name, folderName.c_str()) < 0))
{
remove_folder(folderPath.c_str(), logTag);
deleted++;
} else {
notDeleted ++;
}
}
else
{
notDeleted++;
}
}
}
ESP_LOGD(TAG, "Image folder deleted: %d | Image folder not deleted: %d", deleted, notDeleted);
ESP_LOGD(TAG, "Image folder deleted: %d | Image folder not deleted: %d", deleted, notDeleted);
closedir(dir);
}

View File

@@ -11,20 +11,19 @@ class ClassFlowImage : public ClassFlow
{
protected:
string imagesLocation;
bool isLogImage;
unsigned short imagesRetention;
const char* logTag;
bool isLogImage;
unsigned short imagesRetention;
const char *logTag;
string CreateLogFolder(string time);
void LogImage(string logPath, string name, float *resultFloat, int *resultInt, string time, CImageBasis *_img);
public:
ClassFlowImage(const char* logTag);
ClassFlowImage(std::vector<ClassFlow*> * lfc, const char* logTag);
ClassFlowImage(std::vector<ClassFlow*> * lfc, ClassFlow *_prev, const char* logTag);
ClassFlowImage(const char *logTag);
ClassFlowImage(std::vector<ClassFlow *> *lfc, const char *logTag);
ClassFlowImage(std::vector<ClassFlow *> *lfc, ClassFlow *_prev, const char *logTag);
void RemoveOldLogs();
};
#endif //CLASSFLOWIMAGE_H
#endif // CLASSFLOWIMAGE_H

View File

@@ -1,60 +1,62 @@
#ifdef ENABLE_INFLUXDB
#include "defines.h"
#include <sstream>
#include <time.h>
#include "ClassFlowInfluxDB.h"
#include "Helper.h"
#include "connect_wlan.h"
#include "connect_wifi_sta.h"
#include "time_sntp.h"
#include "interface_influxdb.h"
#include "ClassFlowPostProcessing.h"
#include "esp_log.h"
#include "../../include/defines.h"
#include "ClassLogFile.h"
#include <time.h>
static const char *TAG = "INFLUXDB";
static const char* TAG = "INFLUXDB";
influxDBv1_controll_config_t influxDBv1_controll_config;
void ClassFlowInfluxDB::SetInitialParameter(void)
{
uri = "";
database = "";
influxDBv1_controll_config.enabled = false;
influxDBv1_controll_config.uri = "";
influxDBv1_controll_config.database = "";
influxDBv1_controll_config.user = "";
influxDBv1_controll_config.password = "";
influxDBv1_controll_config.oldValue = "";
OldValue = "";
flowpostprocessing = NULL;
user = "";
password = "";
flowpostprocessing = NULL;
previousElement = NULL;
ListFlowControll = NULL;
ListFlowControll = NULL;
disabled = false;
InfluxDBenable = false;
}
}
ClassFlowInfluxDB::ClassFlowInfluxDB()
{
SetInitialParameter();
}
ClassFlowInfluxDB::ClassFlowInfluxDB(std::vector<ClassFlow*>* lfc)
ClassFlowInfluxDB::ClassFlowInfluxDB(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];
flowpostprocessing = (ClassFlowPostProcessing *)(*ListFlowControll)[i];
}
}
}
ClassFlowInfluxDB::ClassFlowInfluxDB(std::vector<ClassFlow*>* lfc, ClassFlow *_prev)
ClassFlowInfluxDB::ClassFlowInfluxDB(std::vector<ClassFlow *> *lfc, ClassFlow *_prev)
{
SetInitialParameter();
previousElement = _prev;
ListFlowControll = lfc;
@@ -62,176 +64,182 @@ ClassFlowInfluxDB::ClassFlowInfluxDB(std::vector<ClassFlow*>* lfc, ClassFlow *_p
{
if (((*ListFlowControll)[i])->name().compare("ClassFlowPostProcessing") == 0)
{
flowpostprocessing = (ClassFlowPostProcessing*) (*ListFlowControll)[i];
flowpostprocessing = (ClassFlowPostProcessing *)(*ListFlowControll)[i];
}
}
}
bool ClassFlowInfluxDB::ReadParameter(FILE* pfile, string& aktparamgraph)
bool ClassFlowInfluxDB::ReadParameter(FILE *pFile, std::string &aktparamgraph)
{
std::vector<string> splitted;
aktparamgraph = trim(aktparamgraph);
aktparamgraph = trim_string_left_right(aktparamgraph);
if (aktparamgraph.size() == 0)
if (!this->GetNextParagraph(pfile, aktparamgraph))
return false;
if (toUpper(aktparamgraph).compare("[INFLUXDB]") != 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) == "USER") && (splitted.size() > 1))
if (!GetNextParagraph(pFile, aktparamgraph))
{
this->user = splitted[1];
}
if ((toUpper(_param) == "PASSWORD") && (splitted.size() > 1))
{
this->password = splitted[1];
}
if ((toUpper(_param) == "URI") && (splitted.size() > 1))
{
this->uri = splitted[1];
}
if (((toUpper(_param) == "DATABASE")) && (splitted.size() > 1))
{
this->database = splitted[1];
}
if (((toUpper(_param) == "MEASUREMENT")) && (splitted.size() > 1))
{
handleMeasurement(splitted[0], splitted[1]);
}
if (((toUpper(_param) == "FIELD")) && (splitted.size() > 1))
{
handleFieldname(splitted[0], splitted[1]);
return false;
}
}
if ((uri.length() > 0) && (database.length() > 0))
{
// ESP_LOGD(TAG, "Init InfluxDB with uri: %s, measurement: %s, user: %s, password: %s", uri.c_str(), measurement.c_str(), user.c_str(), password.c_str());
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Init InfluxDB with uri: " + uri + ", user: " + user + ", password: " + password);
/////////////////////// NEW //////////////////////////
// InfluxDBInit(uri, database, user, password);
influxDB.InfluxDBInitV1(uri, database, user, password);
/////////////////////// NEW //////////////////////////
InfluxDBenable = true;
} else {
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "InfluxDB init skipped as we are missing some parameters");
if ((to_upper(aktparamgraph).compare("[INFLUXDB]") != 0) && (to_upper(aktparamgraph).compare(";[INFLUXDB]") != 0))
{
return false;
}
if (aktparamgraph[0] == ';')
{
influxDBv1_controll_config.enabled = false;
while (getNextLine(pFile, &aktparamgraph) && !isNewParagraph(aktparamgraph));
ESP_LOGD(TAG, "InfluxDBv1 is disabled!");
return true;
}
std::vector<std::string> splitted;
while (getNextLine(pFile, &aktparamgraph) && !isNewParagraph(aktparamgraph))
{
splitted = split_line(aktparamgraph);
if (splitted.size() > 1)
{
std::string _param = to_upper(GetParameterName(splitted[0]));
if (_param == "USER")
{
influxDBv1_controll_config.user = splitted[1];
}
else if (_param == "PASSWORD")
{
influxDBv1_controll_config.password = splitted[1];
}
else if (_param == "URI")
{
influxDBv1_controll_config.uri = splitted[1];
}
else if (_param == "DATABASE")
{
influxDBv1_controll_config.database = splitted[1];
}
else if (_param == "MEASUREMENT")
{
handleMeasurement(splitted[0], splitted[1]);
}
else if (_param == "FIELD")
{
handleFieldname(splitted[0], splitted[1]);
}
}
}
if ((influxDBv1_controll_config.uri.length() > 0) && (influxDBv1_controll_config.database.length() > 0))
{
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Init InfluxDBv1 with uri: " + influxDBv1_controll_config.uri + ", user: " + influxDBv1_controll_config.user + ", password: " + influxDBv1_controll_config.password);
influxDB.InfluxDBInitV1(influxDBv1_controll_config.uri, influxDBv1_controll_config.database, influxDBv1_controll_config.user, influxDBv1_controll_config.password);
influxDBv1_controll_config.enabled = true;
}
else
{
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "InfluxDBv1 init skipped as we are missing some parameters");
}
return true;
}
bool ClassFlowInfluxDB::doFlow(string zwtime)
bool ClassFlowInfluxDB::doFlow(std::string temp_time)
{
if (!InfluxDBenable)
if (!influxDBv1_controll_config.enabled)
{
return true;
}
std::string result;
std::string measurement;
std::string resulterror = "";
std::string resultraw = "";
std::string resultrate = "";
std::string resulttimestamp = "";
long int timeutc;
string zw = "";
string namenumber = "";
std::string result = "";
std::string measurement = "";
long int result_timeutc = 0;
std::string name_number = "";
if (flowpostprocessing)
{
std::vector<NumberPost*>* NUMBERS = flowpostprocessing->GetNumbers();
std::vector<NumberPost *> *NUMBERS = flowpostprocessing->GetNumbers();
for (int i = 0; i < (*NUMBERS).size(); ++i)
{
measurement = (*NUMBERS)[i]->MeasurementV1;
result = (*NUMBERS)[i]->ReturnValue;
resultraw = (*NUMBERS)[i]->ReturnRawValue;
resulterror = (*NUMBERS)[i]->ErrorMessageText;
resultrate = (*NUMBERS)[i]->ReturnRateValue;
resulttimestamp = (*NUMBERS)[i]->timeStamp;
timeutc = (*NUMBERS)[i]->timeStampTimeUTC;
result = (*NUMBERS)[i]->ReturnValue;
result_timeutc = (*NUMBERS)[i]->timeStampTimeUTC;
if ((*NUMBERS)[i]->FieldV1.length() > 0)
{
namenumber = (*NUMBERS)[i]->FieldV1;
name_number = (*NUMBERS)[i]->FieldV1;
}
else
{
namenumber = (*NUMBERS)[i]->name;
if (namenumber == "default")
namenumber = "value";
name_number = (*NUMBERS)[i]->name;
if (name_number == "default")
{
name_number = "value";
}
else
namenumber = namenumber + "/value";
{
name_number = name_number + "/value";
}
}
if (result.length() > 0)
//////////////////////// NEW //////////////////////////
// InfluxDBPublish(measurement, namenumber, result, timeutc);
influxDB.InfluxDBPublish(measurement, namenumber, result, timeutc);
//////////////////////// NEW //////////////////////////
if (result.length() > 0)
{
influxDB.InfluxDBPublish(measurement, name_number, result, result_timeutc);
}
}
}
OldValue = result;
influxDBv1_controll_config.oldValue = result;
return true;
}
void ClassFlowInfluxDB::handleMeasurement(string _decsep, string _value)
void ClassFlowInfluxDB::handleMeasurement(std::string _decsep, std::string _value)
{
string _digit, _decpos;
std::string _digit;
int _pospunkt = _decsep.find_first_of(".");
// ESP_LOGD(TAG, "Name: %s, Pospunkt: %d", _decsep.c_str(), _pospunkt);
if (_pospunkt > -1)
{
_digit = _decsep.substr(0, _pospunkt);
}
else
{
_digit = "default";
}
for (int j = 0; j < flowpostprocessing->NUMBERS.size(); ++j)
{
if (_digit == "default") // Set to default first (if nothing else is set)
{
flowpostprocessing->NUMBERS[j]->MeasurementV1 = _value;
}
if (flowpostprocessing->NUMBERS[j]->name == _digit)
// Set to default first (if nothing else is set)
if ((_digit == "default") || (flowpostprocessing->NUMBERS[j]->name == _digit))
{
flowpostprocessing->NUMBERS[j]->MeasurementV1 = _value;
}
}
}
void ClassFlowInfluxDB::handleFieldname(string _decsep, string _value)
void ClassFlowInfluxDB::handleFieldname(std::string _decsep, std::string _value)
{
string _digit, _decpos;
std::string _digit;
int _pospunkt = _decsep.find_first_of(".");
// ESP_LOGD(TAG, "Name: %s, Pospunkt: %d", _decsep.c_str(), _pospunkt);
if (_pospunkt > -1)
{
_digit = _decsep.substr(0, _pospunkt);
}
else
{
_digit = "default";
}
for (int j = 0; j < flowpostprocessing->NUMBERS.size(); ++j)
{
if (_digit == "default") // Set to default first (if nothing else is set)
{
flowpostprocessing->NUMBERS[j]->FieldV1 = _value;
}
if (flowpostprocessing->NUMBERS[j]->name == _digit)
// Set to default first (if nothing else is set)
if ((_digit == "default") || (flowpostprocessing->NUMBERS[j]->name == _digit))
{
flowpostprocessing->NUMBERS[j]->FieldV1 = _value;
}
}
}
#endif //ENABLE_INFLUXDB

View File

@@ -1,47 +1,47 @@
#ifdef ENABLE_INFLUXDB
#pragma once
#ifndef CLASSFINFLUXDB_H
#define CLASSFINFLUXDB_H
#include "ClassFlow.h"
#include <string>
#include "ClassFlow.h"
#include "ClassFlowPostProcessing.h"
#include "interface_influxdb.h"
#include <string>
typedef struct
{
bool enabled;
std::string uri;
std::string database;
std::string measurement;
std::string user;
std::string password;
std::string oldValue;
class ClassFlowInfluxDB :
public ClassFlow
} influxDBv1_controll_config_t;
extern influxDBv1_controll_config_t influxDBv1_controll_config;
class ClassFlowInfluxDB : public ClassFlow
{
protected:
std::string uri, database, measurement;
std::string OldValue;
ClassFlowPostProcessing* flowpostprocessing;
std::string user, password;
bool InfluxDBenable;
InfluxDB influxDB;
void SetInitialParameter(void);
void handleFieldname(string _decsep, string _value);
void handleMeasurement(string _decsep, string _value);
ClassFlowPostProcessing *flowpostprocessing;
void SetInitialParameter(void);
void handleFieldname(std::string _decsep, std::string _value);
void handleMeasurement(std::string _decsep, std::string _value);
public:
ClassFlowInfluxDB();
ClassFlowInfluxDB(std::vector<ClassFlow*>* lfc);
ClassFlowInfluxDB(std::vector<ClassFlow*>* lfc, ClassFlow *_prev);
ClassFlowInfluxDB(std::vector<ClassFlow *> *lfc);
ClassFlowInfluxDB(std::vector<ClassFlow *> *lfc, ClassFlow *_prev);
// string GetInfluxDBMeasurement();
bool ReadParameter(FILE* pfile, string& aktparamgraph);
bool doFlow(string time);
string name(){return "ClassFlowInfluxDB";};
bool ReadParameter(FILE *pfile, std::string &aktparamgraph);
bool doFlow(std::string temp_time);
std::string name() { return "ClassFlowInfluxDB"; };
};
#endif //CLASSFINFLUXDB_H
#endif //ENABLE_INFLUXDB
#endif // CLASSFINFLUXDB_H

View File

@@ -1,61 +1,62 @@
#ifdef ENABLE_INFLUXDB
#include "defines.h"
#include <sstream>
#include <time.h>
#include "ClassFlowInfluxDBv2.h"
#include "Helper.h"
#include "connect_wlan.h"
#include "connect_wifi_sta.h"
#include "time_sntp.h"
#include "interface_influxdb.h"
#include "ClassFlowPostProcessing.h"
#include "esp_log.h"
#include "../../include/defines.h"
#include "ClassLogFile.h"
#include <time.h>
static const char *TAG = "INFLUXDBV2";
static const char* TAG = "INFLUXDBV2";
influxDBv2_controll_config_t influxDBv2_controll_config;
void ClassFlowInfluxDBv2::SetInitialParameter(void)
{
uri = "";
bucket = "";
dborg = "";
dbtoken = "";
// dbfield = "";
influxDBv2_controll_config.enabled = false;
influxDBv2_controll_config.uri = "";
influxDBv2_controll_config.bucket = "";
influxDBv2_controll_config.dborg = "";
influxDBv2_controll_config.dbtoken = "";
influxDBv2_controll_config.oldValue = "";
OldValue = "";
flowpostprocessing = NULL;
flowpostprocessing = NULL;
previousElement = NULL;
ListFlowControll = NULL;
ListFlowControll = NULL;
disabled = false;
InfluxDBenable = false;
}
}
ClassFlowInfluxDBv2::ClassFlowInfluxDBv2()
{
SetInitialParameter();
}
ClassFlowInfluxDBv2::ClassFlowInfluxDBv2(std::vector<ClassFlow*>* lfc)
ClassFlowInfluxDBv2::ClassFlowInfluxDBv2(std::vector<ClassFlow *> *lfc)
{
SetInitialParameter();
ListFlowControll = lfc;
for (int i = 0; i < ListFlowControll->size(); ++i)
{
if (((*ListFlowControll)[i])->name().compare("ClassFlowPostProcessing") == 0)
{
flowpostprocessing = (ClassFlowPostProcessing*) (*ListFlowControll)[i];
flowpostprocessing = (ClassFlowPostProcessing *)(*ListFlowControll)[i];
}
}
}
ClassFlowInfluxDBv2::ClassFlowInfluxDBv2(std::vector<ClassFlow*>* lfc, ClassFlow *_prev)
ClassFlowInfluxDBv2::ClassFlowInfluxDBv2(std::vector<ClassFlow *> *lfc, ClassFlow *_prev)
{
SetInitialParameter();
previousElement = _prev;
ListFlowControll = lfc;
@@ -63,190 +64,182 @@ ClassFlowInfluxDBv2::ClassFlowInfluxDBv2(std::vector<ClassFlow*>* lfc, ClassFlow
{
if (((*ListFlowControll)[i])->name().compare("ClassFlowPostProcessing") == 0)
{
flowpostprocessing = (ClassFlowPostProcessing*) (*ListFlowControll)[i];
flowpostprocessing = (ClassFlowPostProcessing *)(*ListFlowControll)[i];
}
}
}
bool ClassFlowInfluxDBv2::ReadParameter(FILE* pfile, string& aktparamgraph)
bool ClassFlowInfluxDBv2::ReadParameter(FILE *pFile, std::string &aktparamgraph)
{
std::vector<string> splitted;
aktparamgraph = trim(aktparamgraph);
printf("akt param: %s\n", aktparamgraph.c_str());
aktparamgraph = trim_string_left_right(aktparamgraph);
if (aktparamgraph.size() == 0)
if (!this->GetNextParagraph(pfile, aktparamgraph))
return false;
if (toUpper(aktparamgraph).compare("[INFLUXDBV2]") != 0)
return false;
while (this->getNextLine(pfile, &aktparamgraph) && !this->isNewParagraph(aktparamgraph))
{
// ESP_LOGD(TAG, "while loop reading line: %s", aktparamgraph.c_str());
splitted = ZerlegeZeile(aktparamgraph);
std::string _param = GetParameterName(splitted[0]);
if ((toUpper(_param) == "ORG") && (splitted.size() > 1))
if (!GetNextParagraph(pFile, aktparamgraph))
{
this->dborg = splitted[1];
}
if ((toUpper(_param) == "TOKEN") && (splitted.size() > 1))
{
this->dbtoken = splitted[1];
}
if ((toUpper(_param) == "URI") && (splitted.size() > 1))
{
this->uri = splitted[1];
}
if (((toUpper(_param) == "FIELD")) && (splitted.size() > 1))
{
handleFieldname(splitted[0], splitted[1]);
}
if (((toUpper(_param) == "MEASUREMENT")) && (splitted.size() > 1))
{
handleMeasurement(splitted[0], splitted[1]);
}
if (((toUpper(splitted[0]) == "BUCKET")) && (splitted.size() > 1))
{
this->bucket = splitted[1];
return false;
}
}
printf("uri: %s\n", uri.c_str());
printf("org: %s\n", dborg.c_str());
printf("token: %s\n", dbtoken.c_str());
if ((uri.length() > 0) && (bucket.length() > 0) && (dbtoken.length() > 0) && (dborg.length() > 0))
{
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Init InfluxDB with uri: " + uri + ", org: " + dborg + ", token: *****");
// printf("vor V2 Init\n");
////////////////////////////////////////// NEW ////////////////////////////////////////////
// InfluxDB_V2_Init(uri, bucket, dborg, dbtoken);
// InfluxDB_V2_Init(uri, bucket, dborg, dbtoken);
influxdb.InfluxDBInitV2(uri, bucket, dborg, dbtoken);
////////////////////////////////////////// NEW ////////////////////////////////////////////
// printf("nach V2 Init\n");
InfluxDBenable = true;
} else {
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "InfluxDBv2 (Verion2 !!!) init skipped as we are missing some parameters");
if ((to_upper(aktparamgraph).compare("[INFLUXDBV2]") != 0) && (to_upper(aktparamgraph).compare(";[INFLUXDBV2]") != 0))
{
return false;
}
if (aktparamgraph[0] == ';')
{
influxDBv2_controll_config.enabled = false;
while (getNextLine(pFile, &aktparamgraph) && !isNewParagraph(aktparamgraph));
ESP_LOGD(TAG, "InfluxDBv2 is disabled!");
return true;
}
std::vector<std::string> splitted;
while (getNextLine(pFile, &aktparamgraph) && !isNewParagraph(aktparamgraph))
{
splitted = split_line(aktparamgraph);
if (splitted.size() > 1)
{
std::string _param = to_upper(GetParameterName(splitted[0]));
if (_param == "ORG")
{
influxDBv2_controll_config.dborg = splitted[1];
}
else if (_param == "TOKEN")
{
influxDBv2_controll_config.dbtoken = splitted[1];
}
else if (_param == "URI")
{
influxDBv2_controll_config.uri = splitted[1];
}
else if (_param == "FIELD")
{
handleFieldname(splitted[0], splitted[1]);
}
else if (_param == "MEASUREMENT")
{
handleMeasurement(splitted[0], splitted[1]);
}
else if (_param == "BUCKET")
{
influxDBv2_controll_config.bucket = splitted[1];
}
}
}
if ((influxDBv2_controll_config.uri.length() > 0) && (influxDBv2_controll_config.bucket.length() > 0) && (influxDBv2_controll_config.dbtoken.length() > 0) && (influxDBv2_controll_config.dborg.length() > 0))
{
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Init InfluxDBv2 with uri: " + influxDBv2_controll_config.uri + ", org: " + influxDBv2_controll_config.dborg + ", token: *****");
influxDB.InfluxDBInitV2(influxDBv2_controll_config.uri, influxDBv2_controll_config.bucket, influxDBv2_controll_config.dborg, influxDBv2_controll_config.dbtoken);
influxDBv2_controll_config.enabled = true;
}
else
{
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "InfluxDBv2 init skipped as we are missing some parameters");
}
return true;
}
/*
string ClassFlowInfluxDBv2::GetInfluxDBMeasurement()
bool ClassFlowInfluxDBv2::doFlow(std::string temp_time)
{
return measurement;
}
*/
void ClassFlowInfluxDBv2::handleFieldname(string _decsep, string _value)
{
string _digit, _decpos;
int _pospunkt = _decsep.find_first_of(".");
// ESP_LOGD(TAG, "Name: %s, Pospunkt: %d", _decsep.c_str(), _pospunkt);
if (_pospunkt > -1)
_digit = _decsep.substr(0, _pospunkt);
else
_digit = "default";
for (int j = 0; j < flowpostprocessing->NUMBERS.size(); ++j)
if (!influxDBv2_controll_config.enabled)
{
if (_digit == "default") // Set to default first (if nothing else is set)
{
flowpostprocessing->NUMBERS[j]->FieldV2 = _value;
}
if (flowpostprocessing->NUMBERS[j]->name == _digit)
{
flowpostprocessing->NUMBERS[j]->FieldV2 = _value;
}
}
}
void ClassFlowInfluxDBv2::handleMeasurement(string _decsep, string _value)
{
string _digit, _decpos;
int _pospunkt = _decsep.find_first_of(".");
// ESP_LOGD(TAG, "Name: %s, Pospunkt: %d", _decsep.c_str(), _pospunkt);
if (_pospunkt > -1)
_digit = _decsep.substr(0, _pospunkt);
else
_digit = "default";
for (int j = 0; j < flowpostprocessing->NUMBERS.size(); ++j)
{
if (_digit == "default") // Set to default first (if nothing else is set)
{
flowpostprocessing->NUMBERS[j]->MeasurementV2 = _value;
}
if (flowpostprocessing->NUMBERS[j]->name == _digit)
{
flowpostprocessing->NUMBERS[j]->MeasurementV2 = _value;
}
}
}
bool ClassFlowInfluxDBv2::doFlow(string zwtime)
{
if (!InfluxDBenable)
return true;
}
std::string measurement;
std::string result;
std::string resulterror = "";
std::string resultraw = "";
std::string resultrate = "";
std::string resulttimestamp = "";
long int resulttimeutc = 0;
string zw = "";
string namenumber = "";
std::string measurement = "";
std::string result = "";
long int result_timeutc = 0;
std::string name_number = "";
if (flowpostprocessing)
{
std::vector<NumberPost*>* NUMBERS = flowpostprocessing->GetNumbers();
std::vector<NumberPost *> *NUMBERS = flowpostprocessing->GetNumbers();
for (int i = 0; i < (*NUMBERS).size(); ++i)
{
measurement = (*NUMBERS)[i]->MeasurementV2;
result = (*NUMBERS)[i]->ReturnValue;
resultraw = (*NUMBERS)[i]->ReturnRawValue;
resulterror = (*NUMBERS)[i]->ErrorMessageText;
resultrate = (*NUMBERS)[i]->ReturnRateValue;
resulttimestamp = (*NUMBERS)[i]->timeStamp;
resulttimeutc = (*NUMBERS)[i]->timeStampTimeUTC;
result = (*NUMBERS)[i]->ReturnValue;
result_timeutc = (*NUMBERS)[i]->timeStampTimeUTC;
if ((*NUMBERS)[i]->FieldV2.length() > 0)
{
namenumber = (*NUMBERS)[i]->FieldV2;
name_number = (*NUMBERS)[i]->FieldV2;
}
else
{
namenumber = (*NUMBERS)[i]->name;
if (namenumber == "default")
namenumber = "value";
name_number = (*NUMBERS)[i]->name;
if (name_number == "default")
{
name_number = "value";
}
else
namenumber = namenumber + "/value";
{
name_number = name_number + "/value";
}
}
printf("vor sende Influx_DB_V2 - namenumber. %s, result: %s, timestampt: %s", namenumber.c_str(), result.c_str(), resulttimestamp.c_str());
if (result.length() > 0)
influxdb.InfluxDBPublish(measurement, namenumber, result, resulttimeutc);
// InfluxDB_V2_Publish(measurement, namenumber, result, resulttimeutc);
if (result.length() > 0)
{
influxDB.InfluxDBPublish(measurement, name_number, result, result_timeutc);
}
}
}
OldValue = result;
influxDBv2_controll_config.oldValue = result;
return true;
}
#endif //ENABLE_INFLUXDB
void ClassFlowInfluxDBv2::handleFieldname(std::string _decsep, std::string _value)
{
std::string _digit;
int _pospunkt = _decsep.find_first_of(".");
if (_pospunkt > -1)
{
_digit = _decsep.substr(0, _pospunkt);
}
else
{
_digit = "default";
}
for (int j = 0; j < flowpostprocessing->NUMBERS.size(); ++j)
{
// Set to default first (if nothing else is set)
if ((_digit == "default") || (flowpostprocessing->NUMBERS[j]->name == _digit))
{
flowpostprocessing->NUMBERS[j]->FieldV2 = _value;
}
}
}
void ClassFlowInfluxDBv2::handleMeasurement(std::string _decsep, std::string _value)
{
std::string _digit;
int _pospunkt = _decsep.find_first_of(".");
if (_pospunkt > -1)
{
_digit = _decsep.substr(0, _pospunkt);
}
else
{
_digit = "default";
}
for (int j = 0; j < flowpostprocessing->NUMBERS.size(); ++j)
{
// Set to default first (if nothing else is set)
if ((_digit == "default") || (flowpostprocessing->NUMBERS[j]->name == _digit))
{
flowpostprocessing->NUMBERS[j]->MeasurementV2 = _value;
}
}
}

View File

@@ -1,47 +1,46 @@
#ifdef ENABLE_INFLUXDB
#pragma once
#ifndef CLASSFINFLUXDBv2_H
#define CLASSFINFLUXDBv2_H
#include "ClassFlow.h"
#include "ClassFlowPostProcessing.h"
#include "interface_influxdb.h"
#include <string>
class ClassFlowInfluxDBv2 :
public ClassFlow
#include "ClassFlow.h"
#include "ClassFlowPostProcessing.h"
#include "interface_influxdb.h"
typedef struct
{
bool enabled;
std::string uri;
std::string bucket;
std::string dborg;
std::string dbtoken;
std::string dbfield;
std::string oldValue;
} influxDBv2_controll_config_t;
extern influxDBv2_controll_config_t influxDBv2_controll_config;
class ClassFlowInfluxDBv2 : public ClassFlow
{
protected:
std::string uri, bucket;
std::string dborg, dbtoken, dbfield;
std::string OldValue;
ClassFlowPostProcessing* flowpostprocessing;
bool InfluxDBenable;
InfluxDB influxdb;
void SetInitialParameter(void);
void handleFieldname(string _decsep, string _value);
void handleMeasurement(string _decsep, string _value);
InfluxDB influxDB;
ClassFlowPostProcessing *flowpostprocessing;
void SetInitialParameter(void);
void handleFieldname(std::string _decsep, std::string _value);
void handleMeasurement(std::string _decsep, std::string _value);
public:
ClassFlowInfluxDBv2();
ClassFlowInfluxDBv2(std::vector<ClassFlow*>* lfc);
ClassFlowInfluxDBv2(std::vector<ClassFlow*>* lfc, ClassFlow *_prev);
ClassFlowInfluxDBv2(std::vector<ClassFlow *> *lfc);
ClassFlowInfluxDBv2(std::vector<ClassFlow *> *lfc, ClassFlow *_prev);
// string GetInfluxDBMeasurement();
bool ReadParameter(FILE* pfile, string& aktparamgraph);
bool doFlow(string time);
string name(){return "ClassFlowInfluxDBv2";};
bool ReadParameter(FILE *pFile, std::string &aktparamgraph);
bool doFlow(std::string temp_time);
std::string name() { return "ClassFlowInfluxDBv2"; };
};
#endif //CLASSFINFLUXDBv2_H
#endif //ENABLE_INFLUXDB
#endif // CLASSFINFLUXDBv2_H

View File

@@ -1,11 +1,16 @@
#ifdef ENABLE_MQTT
#include "defines.h"
#include "ClassFlowMQTT.h"
#include <sstream>
#include <iomanip>
#include "ClassFlowMQTT.h"
#include <time.h>
#include "Helper.h"
#include "connect_wlan.h"
#include "read_wlanini.h"
#include "connect_wifi_sta.h"
#include "read_network_config.h"
#include "ClassLogFile.h"
#include "time_sntp.h"
@@ -15,52 +20,73 @@
#include "server_mqtt.h"
#include <time.h>
#include "../../include/defines.h"
static const char *TAG = "MQTT";
extern const char* libfive_git_version(void);
extern const char* libfive_git_revision(void);
extern const char* libfive_git_branch(void);
mqtt_controll_config_t mqtt_controll_config;
extern const char *libfive_git_version(void);
extern const char *libfive_git_revision(void);
extern const char *libfive_git_branch(void);
void ClassFlowMQTT::SetInitialParameter(void)
{
uri = "";
topic = "";
topicError = "";
topicRate = "";
topicTimeStamp = "";
maintopic = wlan_config.hostname;
mqtt_controll_config.mqtt_enabled = false;
mqtt_controll_config.mqtt_configOK = false;
mqtt_controll_config.mqtt_initialized = false;
mqtt_controll_config.mqtt_connected = false;
topicUptime = "";
topicFreeMem = "";
mqtt_controll_config.HomeAssistantDiscovery = false;
caCertFilename = "";
clientCertFilename = "";
clientKeyFilename = "";
validateServerCert = true;
clientname = wlan_config.hostname;
mqtt_controll_config.esp_mqtt_ID = MQTT_EVENT_ANY;
OldValue = "";
flowpostprocessing = NULL;
user = "";
password = "";
SetRetainFlag = false;
mqtt_controll_config.uri = "";
mqtt_controll_config.topic = "";
mqtt_controll_config.topicError = "";
mqtt_controll_config.topicRate = "";
mqtt_controll_config.topicTimeStamp = "";
mqtt_controll_config.maintopic = network_config.hostname;
mqtt_controll_config.discoveryprefix = "homeassistant";
mqtt_controll_config.topicUptime = "";
mqtt_controll_config.topicFreeMem = "";
mqtt_controll_config.caCertFilename = "";
mqtt_controll_config.clientCertFilename = "";
mqtt_controll_config.clientKeyFilename = "";
mqtt_controll_config.validateServerCert = true;
mqtt_controll_config.clientname = network_config.hostname;
mqtt_controll_config.OldValue = "";
mqtt_controll_config.user = "";
mqtt_controll_config.password = "";
mqtt_controll_config.lwt_topic = mqtt_controll_config.maintopic + "/" + LWT_TOPIC;
mqtt_controll_config.lwt_connected = LWT_CONNECTED;
mqtt_controll_config.lwt_disconnected = LWT_DISCONNECTED;
mqtt_controll_config.meterType = "";
mqtt_controll_config.valueUnit = "";
mqtt_controll_config.timeUnit = "";
mqtt_controll_config.rateUnit = "Unit/Minute";
mqtt_controll_config.retainFlag = false;
mqtt_controll_config.keepAlive = 25 * 60;
mqtt_controll_config.domoticzintopic = "";
flowpostprocessing = NULL;
previousElement = NULL;
ListFlowControll = NULL;
disabled = false;
keepAlive = 25*60;
domoticzintopic = "";
}
ListFlowControll = NULL;
ClassFlowMQTT::ClassFlowMQTT()
disabled = false;
}
ClassFlowMQTT::ClassFlowMQTT(void)
{
SetInitialParameter();
}
ClassFlowMQTT::ClassFlowMQTT(std::vector<ClassFlow*>* lfc)
ClassFlowMQTT::ClassFlowMQTT(std::vector<ClassFlow *> *lfc)
{
SetInitialParameter();
@@ -69,12 +95,12 @@ ClassFlowMQTT::ClassFlowMQTT(std::vector<ClassFlow*>* lfc)
{
if (((*ListFlowControll)[i])->name().compare("ClassFlowPostProcessing") == 0)
{
flowpostprocessing = (ClassFlowPostProcessing*) (*ListFlowControll)[i];
flowpostprocessing = (ClassFlowPostProcessing *)(*ListFlowControll)[i];
}
}
}
ClassFlowMQTT::ClassFlowMQTT(std::vector<ClassFlow*>* lfc, ClassFlow *_prev)
ClassFlowMQTT::ClassFlowMQTT(std::vector<ClassFlow *> *lfc, ClassFlow *_prev)
{
SetInitialParameter();
@@ -85,301 +111,348 @@ ClassFlowMQTT::ClassFlowMQTT(std::vector<ClassFlow*>* lfc, ClassFlow *_prev)
{
if (((*ListFlowControll)[i])->name().compare("ClassFlowPostProcessing") == 0)
{
flowpostprocessing = (ClassFlowPostProcessing*) (*ListFlowControll)[i];
flowpostprocessing = (ClassFlowPostProcessing *)(*ListFlowControll)[i];
}
}
}
bool ClassFlowMQTT::ReadParameter(FILE* pfile, string& aktparamgraph)
bool ClassFlowMQTT::ReadParameter(FILE *pFile, std::string &aktparamgraph)
{
std::vector<string> splitted;
aktparamgraph = trim(aktparamgraph);
aktparamgraph = trim_string_left_right(aktparamgraph);
if (aktparamgraph.size() == 0)
if (!this->GetNextParagraph(pfile, aktparamgraph))
return false;
if (toUpper(aktparamgraph).compare("[MQTT]") != 0) // Paragraph does not fit MQTT
return false;
while (this->getNextLine(pfile, &aktparamgraph) && !this->isNewParagraph(aktparamgraph))
{
splitted = ZerlegeZeile(aktparamgraph);
std::string _param = GetParameterName(splitted[0]);
if ((toUpper(_param) == "CACERT") && (splitted.size() > 1))
if (!GetNextParagraph(pFile, aktparamgraph))
{
this->caCertFilename = "/sdcard" + splitted[1];
return false;
}
if ((toUpper(_param) == "VALIDATESERVERCERT") && (splitted.size() > 1))
{
validateServerCert = alphanumericToBoolean(splitted[1]);
}
if ((toUpper(_param) == "CLIENTCERT") && (splitted.size() > 1))
{
this->clientCertFilename = "/sdcard" + splitted[1];
}
if ((toUpper(_param) == "CLIENTKEY") && (splitted.size() > 1))
{
this->clientKeyFilename = "/sdcard" + splitted[1];
}
if ((toUpper(_param) == "USER") && (splitted.size() > 1))
{
this->user = splitted[1];
}
if ((toUpper(_param) == "PASSWORD") && (splitted.size() > 1))
{
this->password = splitted[1];
}
if ((toUpper(_param) == "URI") && (splitted.size() > 1))
{
this->uri = splitted[1];
}
if ((toUpper(_param) == "RETAINMESSAGES") && (splitted.size() > 1))
{
SetRetainFlag = alphanumericToBoolean(splitted[1]);
setMqtt_Server_Retain(SetRetainFlag);
}
if ((toUpper(_param) == "HOMEASSISTANTDISCOVERY") && (splitted.size() > 1))
{
if (toUpper(splitted[1]) == "TRUE")
SetHomeassistantDiscoveryEnabled(true);
}
if ((toUpper(_param) == "METERTYPE") && (splitted.size() > 1)) {
/* Use meter type for the device class
Make sure it is a listed one on https://developers.home-assistant.io/docs/core/entity/sensor/#available-device-classes */
if (toUpper(splitted[1]) == "WATER_M3") {
mqttServer_setMeterType("water", "", "h", "m³/h");
}
else if (toUpper(splitted[1]) == "WATER_L") {
mqttServer_setMeterType("water", "L", "h", "L/h");
}
else if (toUpper(splitted[1]) == "WATER_FT3") {
mqttServer_setMeterType("water", "ft³", "min", "ft³/min"); // min = Minutes
}
else if (toUpper(splitted[1]) == "WATER_GAL") {
mqttServer_setMeterType("water", "gal", "h", "gal/h");
}
else if (toUpper(splitted[1]) == "WATER_GAL_MIN") {
mqttServer_setMeterType("water", "gal", "min", "gal/min"); // min = Minutes
}
else if (toUpper(splitted[1]) == "GAS_M3") {
mqttServer_setMeterType("gas", "", "h", "m³/h");
}
else if (toUpper(splitted[1]) == "GAS_FT3") {
mqttServer_setMeterType("gas", "ft³", "min", "ft³/min"); // min = Minutes
}
else if (toUpper(splitted[1]) == "ENERGY_WH") {
mqttServer_setMeterType("energy", "Wh", "h", "W");
}
else if (toUpper(splitted[1]) == "ENERGY_KWH") {
mqttServer_setMeterType("energy", "kWh", "h", "kW");
}
else if (toUpper(splitted[1]) == "ENERGY_MWH") {
mqttServer_setMeterType("energy", "MWh", "h", "MW");
}
else if (toUpper(splitted[1]) == "ENERGY_GJ") {
mqttServer_setMeterType("energy", "GJ", "h", "GJ/h");
}
else if (toUpper(splitted[1]) == "TEMPERATURE_C") {
mqttServer_setMeterType("temperature", "°C", "min", "°C/min"); // min = Minutes
}
else if (toUpper(splitted[1]) == "TEMPERATURE_F") {
mqttServer_setMeterType("temperature", "°F", "min", "°F/min"); // min = Minutes
}
else if (toUpper(splitted[1]) == "TEMPERATURE_K") {
mqttServer_setMeterType("temperature", "K", "min", "K/m"); // min = Minutes
}
}
if ((toUpper(_param) == "CLIENTID") && (splitted.size() > 1))
{
this->clientname = splitted[1];
}
if (((toUpper(_param) == "TOPIC") || (toUpper(splitted[0]) == "MAINTOPIC")) && (splitted.size() > 1))
{
maintopic = splitted[1];
}
if (((toUpper(_param) == "DOMOTICZTOPICIN")) && (splitted.size() > 1))
{
this->domoticzintopic = splitted[1];
}
if (((toUpper(_param) == "DOMOTICZIDX")) && (splitted.size() > 1))
{
handleIdx(splitted[0], splitted[1]);
}
}
/* Note:
* Originally, we started the MQTT client here.
* How ever we need the interval parameter from the ClassFlowControll, but that only gets started later.
* To work around this, we delay the start and trigger it from ClassFlowControll::ReadParameter() */
if ((to_upper(aktparamgraph).compare("[MQTT]") != 0) && (to_upper(aktparamgraph).compare(";[MQTT]") != 0))
{
// Paragraph does not fit MQTT
return false;
}
mqttServer_setMainTopic(maintopic);
mqttServer_setDmoticzInTopic(domoticzintopic);
if (aktparamgraph[0] == ';')
{
mqtt_controll_config.mqtt_enabled = false;
while (getNextLine(pFile, &aktparamgraph) && !isNewParagraph(aktparamgraph));
ESP_LOGD(TAG, "mqtt is disabled!");
return true;
}
std::vector<std::string> splitted;
while (getNextLine(pFile, &aktparamgraph) && !isNewParagraph(aktparamgraph))
{
splitted = split_line(aktparamgraph);
if (splitted.size() > 1)
{
std::string _param = to_upper(GetParameterName(splitted[0]));
if (_param == "CACERT")
{
mqtt_controll_config.caCertFilename = "/sdcard" + splitted[1];
}
else if (_param == "VALIDATESERVERCERT")
{
mqtt_controll_config.validateServerCert = alphanumeric_to_boolean(splitted[1]);
}
else if (_param == "CLIENTCERT")
{
mqtt_controll_config.clientCertFilename = "/sdcard" + splitted[1];
}
else if (_param == "CLIENTKEY")
{
mqtt_controll_config.clientKeyFilename = "/sdcard" + splitted[1];
}
else if (_param == "USER")
{
mqtt_controll_config.user = splitted[1];
}
else if (_param == "PASSWORD")
{
mqtt_controll_config.password = splitted[1];
}
else if (_param == "URI")
{
mqtt_controll_config.uri = splitted[1];
}
else if (_param == "RETAINMESSAGES")
{
mqtt_controll_config.retainFlag = alphanumeric_to_boolean(splitted[1]);
}
else if (_param == "HOMEASSISTANTDISCOVERY")
{
if (to_upper(splitted[1]) == "TRUE")
{
mqtt_controll_config.HomeAssistantDiscovery = true;
}
}
else if (_param == "METERTYPE")
{
std::string _value = to_upper(splitted[1]);
/* Use meter type for the device class
Make sure it is a listed one on https://developers.home-assistant.io/docs/core/entity/sensor/#available-device-classes */
if (_value == "WATER_M3")
{
SetMeterType("water", "", "h", "m³/h");
}
else if (_value == "WATER_L")
{
SetMeterType("water", "L", "h", "L/h");
}
else if (_value == "WATER_FT3")
{
SetMeterType("water", "ft³", "min", "ft³/min"); // min = Minutes
}
else if (_value == "WATER_GAL")
{
SetMeterType("water", "gal", "h", "gal/h");
}
else if (_value == "WATER_GAL_MIN")
{
SetMeterType("water", "gal", "min", "gal/min"); // min = Minutes
}
else if (_value == "GAS_M3")
{
SetMeterType("gas", "", "h", "m³/h");
}
else if (_value == "GAS_FT3")
{
SetMeterType("gas", "ft³", "min", "ft³/min"); // min = Minutes
}
else if (_value == "ENERGY_WH")
{
SetMeterType("energy", "Wh", "h", "W");
}
else if (_value == "ENERGY_KWH")
{
SetMeterType("energy", "kWh", "h", "kW");
}
else if (_value == "ENERGY_MWH")
{
SetMeterType("energy", "MWh", "h", "MW");
}
else if (_value == "ENERGY_GJ")
{
SetMeterType("energy", "GJ", "h", "GJ/h");
}
else if (_value == "TEMPERATURE_C")
{
SetMeterType("temperature", "°C", "min", "°C/min"); // min = Minutes
}
else if (_value == "TEMPERATURE_F")
{
SetMeterType("temperature", "°F", "min", "°F/min"); // min = Minutes
}
else if (_value == "TEMPERATURE_K")
{
SetMeterType("temperature", "K", "min", "K/m"); // min = Minutes
}
}
else if (_param == "CLIENTID")
{
mqtt_controll_config.clientname = splitted[1];
}
else if ((_param == "TOPIC") || (_param == "MAINTOPIC"))
{
mqtt_controll_config.maintopic = splitted[1];
}
else if (_param == "DISCOVERYPREFIX")
{
mqtt_controll_config.discoveryprefix = splitted[1];
}
else if (_param == "DOMOTICZTOPICIN")
{
mqtt_controll_config.domoticzintopic = splitted[1];
}
else if (_param == "DOMOTICZIDX")
{
handleIdx(splitted[0], splitted[1]);
}
}
}
if ((mqtt_controll_config.uri.length() > 0) && (mqtt_controll_config.user.length() > 0))
{
/* Note:
* Originally, we started the MQTT client here.
* How ever we need the interval parameter from the ClassFlowControl, but that only gets started later.
* To work around this, we delay the start and trigger it from ClassFlowControl::ReadParameter() */
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Init MQTT with uri: " + mqtt_controll_config.uri + ", user: " + mqtt_controll_config.user);
if (mqtt_controll_config.domoticzintopic.length() > 0)
{
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Init MQTT with domoticzintopic: " + mqtt_controll_config.domoticzintopic);
}
mqtt_controll_config.mqtt_enabled = true;
}
else
{
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "MQTT init skipped as we are missing some parameters");
}
return true;
}
bool ClassFlowMQTT::Start(float AutoInterval)
void ClassFlowMQTT::SetMeterType(std::string _meterType, std::string _valueUnit, std::string _timeUnit, std::string _rateUnit)
{
roundInterval = AutoInterval; // Minutes
keepAlive = roundInterval * 60 * 2.5; // Seconds, make sure it is greater thatn 2 rounds!
mqtt_controll_config.meterType = _meterType;
mqtt_controll_config.valueUnit = _valueUnit;
mqtt_controll_config.timeUnit = _timeUnit;
mqtt_controll_config.rateUnit = _rateUnit;
}
std::stringstream stream;
stream << std::fixed << std::setprecision(1) << "Digitizer interval is " << roundInterval <<
" minutes => setting MQTT LWT timeout to " << ((float)keepAlive/60) << " minutes.";
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, stream.str());
bool ClassFlowMQTT::Start(float AutoInterval)
{
mqtt_controll_config.roundInterval = AutoInterval; // Minutes
mqtt_controll_config.keepAlive = mqtt_controll_config.roundInterval * 60 * 2.5; // Seconds, make sure it is greater thatn 2 rounds!
mqttServer_setParameter(flowpostprocessing->GetNumbers(), keepAlive, roundInterval);
mqttServer_setParameter(flowpostprocessing->GetNumbers());
bool MQTTConfigCheck = MQTT_Configure(uri, clientname, user, password, maintopic, domoticzintopic, LWT_TOPIC, LWT_CONNECTED,
LWT_DISCONNECTED, caCertFilename, validateServerCert, clientCertFilename, clientKeyFilename,
keepAlive, SetRetainFlag, (void *)&GotConnected);
if (!MQTTConfigCheck) {
if (!MQTT_Configure((void *)&GotConnected))
{
return false;
}
return (MQTT_Init() == 1);
}
bool ClassFlowMQTT::doFlow(string zwtime)
bool ClassFlowMQTT::doFlow(std::string time)
{
bool success;
std::string result;
std::string resulterror = "";
std::string resultraw = "";
std::string resultpre = "";
std::string resultrate = ""; // Always Unit / Minute
std::string resultRatePerTimeUnit = ""; // According to selection
std::string resulttimestamp = "";
std::string resultchangabs = "";
string zw = "";
string namenumber = "";
string domoticzpayload = "";
string DomoticzIdx = "";
int qos = 1;
std::string value_temp = "";
std::string error_message_text_temp = "";
std::string raw_value_temp = "";
// std::string pre_value_temp = "";
std::string rate_value_temp = ""; // Always Unit / Minute
std::string time_stamp_temp = "";
std::string change_absolute_temp = "";
/* Send the the Homeassistant Discovery and the Static Topics in case they where scheduled */
sendDiscovery_and_static_Topics();
success = publishSystemData(qos);
bool success = publishSystemData(qos);
if (flowpostprocessing && getMQTTisConnected())
{
std::vector<NumberPost*>* NUMBERS = flowpostprocessing->GetNumbers();
std::vector<NumberPost *> *NUMBERS = flowpostprocessing->GetNumbers();
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Publishing MQTT topics...");
for (int i = 0; i < (*NUMBERS).size(); ++i)
{
result = (*NUMBERS)[i]->ReturnValue;
resultraw = (*NUMBERS)[i]->ReturnRawValue;
resultpre = (*NUMBERS)[i]->ReturnPreValue;
resulterror = (*NUMBERS)[i]->ErrorMessageText;
resultrate = (*NUMBERS)[i]->ReturnRateValue; // Unit per minutes
resultchangabs = (*NUMBERS)[i]->ReturnChangeAbsolute; // Units per round
resulttimestamp = (*NUMBERS)[i]->timeStamp;
value_temp = (*NUMBERS)[i]->ReturnValue;
raw_value_temp = (*NUMBERS)[i]->ReturnRawValue;
// pre_value_temp = (*NUMBERS)[i]->ReturnPreValue;
error_message_text_temp = (*NUMBERS)[i]->ErrorMessageText;
rate_value_temp = (*NUMBERS)[i]->ReturnRateValue; // Unit per minutes
change_absolute_temp = (*NUMBERS)[i]->ReturnChangeAbsolute; // Units per round
time_stamp_temp = (*NUMBERS)[i]->timeStamp;
DomoticzIdx = (*NUMBERS)[i]->DomoticzIdx;
domoticzpayload = "{\"command\":\"udevice\",\"idx\":" + DomoticzIdx + ",\"svalue\":\""+ result + "\"}";
std::string DomoticzIdx = (*NUMBERS)[i]->DomoticzIdx;
std::string domoticzpayload = "{\"command\":\"udevice\",\"idx\":" + DomoticzIdx + ",\"svalue\":\"" + value_temp + "\"}";
namenumber = (*NUMBERS)[i]->name;
if (namenumber == "default")
namenumber = maintopic + "/";
std::string name_temp = (*NUMBERS)[i]->name;
if (name_temp == "default")
{
name_temp = mqtt_controll_config.maintopic + "/";
}
else
namenumber = maintopic + "/" + namenumber + "/";
{
name_temp = mqtt_controll_config.maintopic + "/" + name_temp + "/";
}
if ((domoticzintopic.length() > 0) && (result.length() > 0))
success |= MQTTPublish(domoticzintopic, domoticzpayload, qos, SetRetainFlag);
if ((mqtt_controll_config.domoticzintopic.length() > 0) && (value_temp.length() > 0))
{
success |= MQTTPublish(mqtt_controll_config.domoticzintopic, domoticzpayload, qos, mqtt_controll_config.retainFlag);
}
if (result.length() > 0)
success |= MQTTPublish(namenumber + "value", result, qos, SetRetainFlag);
if (resulterror.length() > 0)
success |= MQTTPublish(namenumber + "error", resulterror, qos, SetRetainFlag);
if (value_temp.length() > 0)
{
success |= MQTTPublish(name_temp + "value", value_temp, qos, mqtt_controll_config.retainFlag);
}
if (error_message_text_temp.length() > 0)
{
success |= MQTTPublish(name_temp + "error", error_message_text_temp, qos, mqtt_controll_config.retainFlag);
}
if (rate_value_temp.length() > 0)
{
success |= MQTTPublish(name_temp + "rate", rate_value_temp, qos, mqtt_controll_config.retainFlag);
if (resultrate.length() > 0) {
success |= MQTTPublish(namenumber + "rate", resultrate, qos, SetRetainFlag);
std::string resultRatePerTimeUnit;
if (getTimeUnit() == "h") { // Need conversion to be per hour
if (mqtt_controll_config.timeUnit == "h")
{
// Need conversion to be per hour
resultRatePerTimeUnit = resultRatePerTimeUnit = to_string((*NUMBERS)[i]->FlowRateAct * 60); // per minutes => per hour
}
else { // Keep per minute
resultRatePerTimeUnit = resultrate;
else
{
// Keep per minute
resultRatePerTimeUnit = rate_value_temp;
}
success |= MQTTPublish(namenumber + "rate_per_time_unit", resultRatePerTimeUnit, qos, SetRetainFlag);
success |= MQTTPublish(name_temp + "rate_per_time_unit", resultRatePerTimeUnit, qos, mqtt_controll_config.retainFlag);
}
if (resultchangabs.length() > 0) {
success |= MQTTPublish(namenumber + "changeabsolut", resultchangabs, qos, SetRetainFlag); // Legacy API
success |= MQTTPublish(namenumber + "rate_per_digitization_round", resultchangabs, qos, SetRetainFlag);
if (change_absolute_temp.length() > 0)
{
success |= MQTTPublish(name_temp + "changeabsolut", change_absolute_temp, qos, mqtt_controll_config.retainFlag); // Legacy API
success |= MQTTPublish(name_temp + "rate_per_digitization_round", change_absolute_temp, qos, mqtt_controll_config.retainFlag);
}
if (resultraw.length() > 0)
success |= MQTTPublish(namenumber + "raw", resultraw, qos, SetRetainFlag);
if (raw_value_temp.length() > 0)
{
success |= MQTTPublish(name_temp + "raw", raw_value_temp, qos, mqtt_controll_config.retainFlag);
}
if (resulttimestamp.length() > 0)
success |= MQTTPublish(namenumber + "timestamp", resulttimestamp, qos, SetRetainFlag);
if (time_stamp_temp.length() > 0)
{
success |= MQTTPublish(name_temp + "timestamp", time_stamp_temp, qos, mqtt_controll_config.retainFlag);
}
std::string json = flowpostprocessing->getJsonFromNumber(i, "\n");
success |= MQTTPublish(namenumber + "json", json, qos, SetRetainFlag);
success |= MQTTPublish(name_temp + "json", json, qos, mqtt_controll_config.retainFlag);
}
}
/* Disabled because this is no longer a use case */
// else
// {
// for (int i = 0; i < ListFlowControll->size(); ++i)
// {
// zw = (*ListFlowControll)[i]->getReadout();
// if (zw.length() > 0)
// {
// if (result.length() == 0)
// result = zw;
// else
// result = result + "\t" + zw;
// }
// }
// success |= MQTTPublish(topic, result, qos, SetRetainFlag);
// }
OldValue = result;
if (!success) {
mqtt_controll_config.OldValue = value_temp;
if (!success)
{
LogFile.WriteToFile(ESP_LOG_WARN, TAG, "One or more MQTT topics failed to be published!");
}
return true;
}
void ClassFlowMQTT::handleIdx(string _decsep, string _value)
void ClassFlowMQTT::handleIdx(std::string _decsep, std::string _value)
{
string _digit, _decpos;
std::string _digit;
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]->DomoticzIdx = _value;
}
if (flowpostprocessing->NUMBERS[j]->name == _digit)
// Set to default first (if nothing else is set)
if ((_digit == "default") || (flowpostprocessing->NUMBERS[j]->name == _digit))
{
flowpostprocessing->NUMBERS[j]->DomoticzIdx = _value;
}
}
}
#endif //ENABLE_MQTT

View File

@@ -1,43 +1,80 @@
#ifdef ENABLE_MQTT
#pragma once
#ifndef CLASSFFLOWMQTT_H
#define CLASSFFLOWMQTT_H
#include "ClassFlow.h"
#include <string>
#include <mqtt_client.h>
#include "ClassFlow.h"
#include "ClassFlowPostProcessing.h"
#include <string>
typedef struct
{
bool mqtt_enabled;
bool mqtt_configOK;
bool mqtt_initialized;
bool mqtt_connected;
class ClassFlowMQTT :
public ClassFlow
bool HomeAssistantDiscovery;
esp_mqtt_event_id_t esp_mqtt_ID;
std::string uri;
std::string topic;
std::string topicError;
std::string clientname;
std::string topicRate;
std::string topicTimeStamp;
std::string topicUptime;
std::string topicFreeMem;
std::string OldValue;
std::string user;
std::string password;
std::string caCertFilename;
std::string clientCertFilename;
std::string clientKeyFilename;
bool validateServerCert;
std::string maintopic;
std::string discoveryprefix;
std::string domoticzintopic;
std::string lwt_topic;
std::string lwt_connected;
std::string lwt_disconnected;
std::string meterType;
std::string valueUnit;
std::string timeUnit;
std::string rateUnit;
float roundInterval; // in Minutes
bool retainFlag;
int keepAlive; // in Seconds
} mqtt_controll_config_t;
extern mqtt_controll_config_t mqtt_controll_config;
class ClassFlowMQTT : public ClassFlow
{
protected:
std::string uri, topic, topicError, clientname, topicRate, topicTimeStamp, topicUptime, topicFreeMem;
std::string OldValue;
ClassFlowPostProcessing* flowpostprocessing;
std::string user, password;
std::string caCertFilename, clientCertFilename, clientKeyFilename;
bool validateServerCert;
bool SetRetainFlag;
int keepAlive; // Seconds
float roundInterval; // Minutes
std::string maintopic, domoticzintopic;
void SetInitialParameter(void);
void handleIdx(string _decsep, string _value);
ClassFlowPostProcessing *flowpostprocessing;
void SetInitialParameter(void);
void SetMeterType(std::string _meterType, std::string _valueUnit, std::string _timeUnit, std::string _rateUnit);
void handleIdx(std::string _decsep, std::string _value);
public:
ClassFlowMQTT();
ClassFlowMQTT(std::vector<ClassFlow*>* lfc);
ClassFlowMQTT(std::vector<ClassFlow*>* lfc, ClassFlow *_prev);
ClassFlowMQTT(void);
ClassFlowMQTT(std::vector<ClassFlow *> *lfc);
ClassFlowMQTT(std::vector<ClassFlow *> *lfc, ClassFlow *_prev);
bool Start(float AutoInterval);
bool ReadParameter(FILE* pfile, string& aktparamgraph);
bool doFlow(string time);
string name(){return "ClassFlowMQTT";};
bool ReadParameter(FILE *pFile, std::string &aktparamgraph);
bool doFlow(std::string time);
std::string name(void) { return "ClassFlowMQTT"; };
};
#endif //CLASSFFLOWMQTT_H
#endif //ENABLE_MQTT
#endif // CLASSFFLOWMQTT_H

File diff suppressed because it is too large Load Diff

View File

@@ -3,75 +3,75 @@
#ifndef CLASSFFLOWPOSTPROCESSING_H
#define CLASSFFLOWPOSTPROCESSING_H
#include <string>
#include "ClassFlow.h"
#include "ClassFlowTakeImage.h"
#include "ClassFlowCNNGeneral.h"
#include "ClassFlowDefineTypes.h"
#include <string>
class ClassFlowPostProcessing :
public ClassFlow
class ClassFlowPostProcessing : public ClassFlow
{
protected:
bool UpdatePreValueINI;
int PreValueAgeStartup;
int PreValueAgeStartup;
bool ErrorMessage;
ClassFlowCNNGeneral* flowAnalog;
ClassFlowCNNGeneral* flowDigit;
string FilePreValue;
ClassFlowCNNGeneral *flowAnalog;
ClassFlowCNNGeneral *flowDigit;
std::string FilePreValue;
ClassFlowTakeImage *flowTakeImage;
bool LoadPreValue(void);
string ShiftDecimal(string in, int _decShift);
std::string ShiftDecimal(std::string in, int _decShift);
string ErsetzteN(string, double _prevalue);
float checkDigitConsistency(double input, int _decilamshift, bool _isanalog, double _preValue);
std::string ErsetzteN(std::string, double _prevalue);
void InitNUMBERS();
void handleDecimalSeparator(string _decsep, string _value);
void handleMaxRateValue(string _decsep, string _value);
void handleDecimalExtendedResolution(string _decsep, string _value);
void handleMaxRateType(string _decsep, string _value);
void handleAnalogToDigitTransitionStart(string _decsep, string _value);
void handleAllowNegativeRate(string _decsep, string _value);
void handleIgnoreLeadingNaN(string _decsep, string _value);
void handleChangeRateThreshold(string _decsep, string _value);
void handlecheckDigitIncreaseConsistency(std::string _decsep, std::string _value);
void handleDecimalSeparator(std::string _decsep, std::string _value);
void handleMaxRateValue(std::string _decsep, std::string _value);
void handleDecimalExtendedResolution(std::string _decsep, std::string _value);
void handleMaxRateType(std::string _decsep, std::string _value);
void handleAnalogToDigitTransitionStart(std::string _decsep, std::string _value);
void handleAllowNegativeRate(std::string _decsep, std::string _value);
void handleIgnoreLeadingNaN(std::string _decsep, std::string _value);
void handleChangeRateThreshold(std::string _decsep, std::string _value);
void handleMaxFlowRate(std::string _decsep, std::string _value);
std::vector<double> addNumbersTogether(std::vector<double> DigitValues, std::vector<double> AnalogValues);
void WriteDataLog(int _index);
public:
bool PreValueUse;
std::vector<NumberPost*> NUMBERS;
std::vector<NumberPost *> NUMBERS;
ClassFlowPostProcessing(std::vector<ClassFlow*>* lfc, ClassFlowCNNGeneral *_analog, ClassFlowCNNGeneral *_digit);
virtual ~ClassFlowPostProcessing(){};
bool ReadParameter(FILE* pfile, string& aktparamgraph);
bool doFlow(string time);
string getReadout(int _number);
string getReadoutParam(bool _rawValue, bool _noerror, int _number = 0);
string getReadoutError(int _number = 0);
string getReadoutRate(int _number = 0);
string getReadoutTimeStamp(int _number = 0);
ClassFlowPostProcessing(std::vector<ClassFlow *> *lfc, ClassFlowCNNGeneral *_analog, ClassFlowCNNGeneral *_digit);
virtual ~ClassFlowPostProcessing() {};
bool ReadParameter(FILE *pFile, std::string &aktparamgraph);
bool doFlow(std::string time);
std::string getReadout(int _number);
std::string getReadoutParam(bool _rawValue, bool _noerror, int _number = 0);
std::string getReadoutError(int _number = 0);
std::string getReadoutRate(int _number = 0);
std::string getReadoutTimeStamp(int _number = 0);
void SavePreValue();
string getJsonFromNumber(int i, std::string _lineend);
string GetPreValue(std::string _number = "");
bool SetPreValue(double zw, string _numbers, bool _extern = false);
std::string getJsonFromNumber(int i, std::string _lineend);
std::string GetPreValue(std::string _number = "");
bool SetPreValue(double _newvalue, string _numbers, bool _extern = false);
std::string GetJSON(std::string _lineend = "\n");
std::string getNumbersName();
void UpdateNachkommaDecimalShift();
std::vector<NumberPost*>* GetNumbers(){return &NUMBERS;};
std::vector<NumberPost *> *GetNumbers() { return &NUMBERS; };
string name(){return "ClassFlowPostProcessing";};
std::string name() { return "ClassFlowPostProcessing"; };
};
#endif //CLASSFFLOWPOSTPROCESSING_H
#endif // CLASSFFLOWPOSTPROCESSING_H

View File

@@ -1,3 +1,5 @@
#include "defines.h"
#include <iostream>
#include <string>
#include <vector>
@@ -13,20 +15,16 @@
#include "esp_wifi.h"
#include "esp_log.h"
#include "../../include/defines.h"
#include "psram.h"
#include <time.h>
// #define DEBUG_DETAIL_ON
// #define WIFITURNOFF
static const char *TAG = "TAKEIMAGE";
esp_err_t ClassFlowTakeImage::camera_capture(void)
{
string nm = namerawimage;
Camera.CaptureToFile(nm);
std::string file_name = NameRawImage;
Camera.capture_to_file(file_name);
time(&TimeImageTaken);
localtime(&TimeImageTaken);
@@ -38,17 +36,22 @@ 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;
if (Camera.CamTempImage)
{
rawImage->width = CFstatus.ImageWidth;
rawImage->height = CFstatus.ImageHeight;
}
ESP_LOGD(TAG, "flash_duration: %d", flash_duration);
Camera.CaptureToBasisImage(rawImage, flash_duration);
Camera.capture_to_basis_image(rawImage, flash_duration);
time(&TimeImageTaken);
localtime(&TimeImageTaken);
if (CCstatus.SaveAllFiles)
if (Camera.SaveAllFiles)
{
rawImage->SaveToFile(namerawimage);
rawImage->SaveToFile(NameRawImage);
}
}
@@ -56,466 +59,447 @@ void ClassFlowTakeImage::SetInitialParameter(void)
{
TimeImageTaken = 0;
rawImage = NULL;
NameRawImage = "/sdcard/img_tmp/raw.jpg";
disabled = 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)
bool ClassFlowTakeImage::ReadParameter(FILE *pFile, std::string &aktparamgraph)
{
Camera.getSensorDatenToCCstatus(); // Kamera >>> CCstatus
std::vector<string> splitted;
aktparamgraph = trim(aktparamgraph);
aktparamgraph = trim_string_left_right(aktparamgraph);
if (aktparamgraph.size() == 0)
{
if (!this->GetNextParagraph(pfile, aktparamgraph))
if (!GetNextParagraph(pFile, aktparamgraph))
{
return false;
}
}
if (aktparamgraph.compare("[TakeImage]") != 0)
if ((to_upper(aktparamgraph).compare("[TAKEIMAGE]") != 0) && (to_upper(aktparamgraph).compare(";[TAKEIMAGE]") != 0))
{
// Paragraph does not fit TakeImage
return false;
}
while (this->getNextLine(pfile, &aktparamgraph) && !this->isNewParagraph(aktparamgraph))
Camera.get_sensor_controll_config(&CCstatus); // Kamera >>> CCstatus
std::vector<std::string> splitted;
while (getNextLine(pFile, &aktparamgraph) && !isNewParagraph(aktparamgraph))
{
splitted = ZerlegeZeile(aktparamgraph);
splitted = split_line(aktparamgraph);
if ((toUpper(splitted[0]) == "RAWIMAGESLOCATION") && (splitted.size() > 1))
if (splitted.size() > 1)
{
imagesLocation = "/sdcard" + splitted[1];
isLogImage = true;
}
std::string _param = to_upper(splitted[0]);
else if ((toUpper(splitted[0]) == "RAWIMAGESRETENTION") && (splitted.size() > 1))
{
if (isStringNumeric(splitted[1]))
if (_param == "RAWIMAGESLOCATION")
{
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]))
imagesLocation = "/sdcard" + splitted[1];
isLogImage = true;
}
else if (_param == "RAWIMAGESRETENTION")
{
int _WaitBeforePicture = std::stoi(splitted[1]);
if (_WaitBeforePicture != 0)
if (is_string_numeric(splitted[1]))
{
CCstatus.WaitBeforePicture = _WaitBeforePicture;
imagesRetention = std::stod(splitted[1]);
}
}
else if (_param == "SAVEALLFILES")
{
Camera.SaveAllFiles = alphanumeric_to_boolean(splitted[1]);
}
else if (_param == "WAITBEFORETAKINGPICTURE")
{
if (is_string_numeric(splitted[1]))
{
int _WaitBeforePicture = std::stoi(splitted[1]);
if (_WaitBeforePicture != 0)
{
CCstatus.WaitBeforePicture = _WaitBeforePicture;
}
else
{
CCstatus.WaitBeforePicture = 2;
}
}
}
else if (_param == "CAMXCLKFREQMHZ")
{
if (is_string_numeric(splitted[1]))
{
int _CamXclkFreqMhz = std::stoi(splitted[1]);
CCstatus.CamXclkFreqMhz = clip_int(_CamXclkFreqMhz, 20, 1);
}
}
else if (_param == "CAMGAINCEILING")
{
std::string _ImageGainceiling = to_upper(splitted[1]);
if (is_string_numeric(_ImageGainceiling))
{
int _ImageGainceiling_ = std::stoi(_ImageGainceiling);
switch (_ImageGainceiling_)
{
case 1:
CCstatus.ImageGainceiling = GAINCEILING_4X;
break;
case 2:
CCstatus.ImageGainceiling = GAINCEILING_8X;
break;
case 3:
CCstatus.ImageGainceiling = GAINCEILING_16X;
break;
case 4:
CCstatus.ImageGainceiling = GAINCEILING_32X;
break;
case 5:
CCstatus.ImageGainceiling = GAINCEILING_64X;
break;
case 6:
CCstatus.ImageGainceiling = GAINCEILING_128X;
break;
default:
CCstatus.ImageGainceiling = GAINCEILING_2X;
}
}
else
{
CCstatus.WaitBeforePicture = 2;
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]) == "CAMGAINCEILING") && (splitted.size() > 1))
{
std::string _ImageGainceiling = toUpper(splitted[1]);
if (isStringNumeric(_ImageGainceiling))
else if (_param == "CAMQUALITY")
{
int _ImageGainceiling_ = std::stoi(_ImageGainceiling);
switch (_ImageGainceiling_)
if (is_string_numeric(splitted[1]))
{
case 1:
CCstatus.ImageGainceiling = GAINCEILING_4X;
break;
case 2:
CCstatus.ImageGainceiling = GAINCEILING_8X;
break;
case 3:
CCstatus.ImageGainceiling = GAINCEILING_16X;
break;
case 4:
CCstatus.ImageGainceiling = GAINCEILING_32X;
break;
case 5:
CCstatus.ImageGainceiling = GAINCEILING_64X;
break;
case 6:
CCstatus.ImageGainceiling = GAINCEILING_128X;
break;
default:
CCstatus.ImageGainceiling = GAINCEILING_2X;
int _ImageQuality = std::stoi(splitted[1]);
CCstatus.ImageQuality = clip_int(_ImageQuality, 63, 6);
}
}
else
else if (_param == "CAMBRIGHTNESS")
{
if (_ImageGainceiling == "X4")
if (is_string_numeric(splitted[1]))
{
CCstatus.ImageGainceiling = GAINCEILING_4X;
int _ImageBrightness = std::stoi(splitted[1]);
CCstatus.ImageBrightness = clip_int(_ImageBrightness, 2, -2);
}
else if (_ImageGainceiling == "X8")
}
else if (_param == "CAMCONTRAST")
{
if (is_string_numeric(splitted[1]))
{
CCstatus.ImageGainceiling = GAINCEILING_8X;
int _ImageContrast = std::stoi(splitted[1]);
CCstatus.ImageContrast = clip_int(_ImageContrast, 2, -2);
}
else if (_ImageGainceiling == "X16")
}
else if (_param == "CAMSATURATION")
{
if (is_string_numeric(splitted[1]))
{
CCstatus.ImageGainceiling = GAINCEILING_16X;
int _ImageSaturation = std::stoi(splitted[1]);
CCstatus.ImageSaturation = clip_int(_ImageSaturation, 2, -2);
}
else if (_ImageGainceiling == "X32")
}
else if (_param == "CAMSHARPNESS")
{
if (is_string_numeric(splitted[1]))
{
CCstatus.ImageGainceiling = GAINCEILING_32X;
int _ImageSharpness = std::stoi(splitted[1]);
if (Camera.CamSensorId == OV2640_PID)
{
CCstatus.ImageSharpness = clip_int(_ImageSharpness, 2, -2);
}
else
{
CCstatus.ImageSharpness = clip_int(_ImageSharpness, 3, -3);
}
}
else if (_ImageGainceiling == "X64")
}
else if (_param == "CAMAUTOSHARPNESS")
{
CCstatus.ImageAutoSharpness = alphanumeric_to_boolean(splitted[1]);
}
else if (_param == "CAMSPECIALEFFECT")
{
std::string _ImageSpecialEffect = to_upper(splitted[1]);
if (is_string_numeric(_ImageSpecialEffect))
{
CCstatus.ImageGainceiling = GAINCEILING_64X;
}
else if (_ImageGainceiling == "X128")
{
CCstatus.ImageGainceiling = GAINCEILING_128X;
int _ImageSpecialEffect_ = std::stoi(_ImageSpecialEffect);
CCstatus.ImageSpecialEffect = clip_int(_ImageSpecialEffect_, 6, 0);
}
else
{
CCstatus.ImageGainceiling = GAINCEILING_2X;
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]) == "CAMQUALITY") && (splitted.size() > 1))
{
if (isStringNumeric(splitted[1]))
else if (_param == "CAMWBMODE")
{
int _ImageQuality = std::stoi(splitted[1]);
CCstatus.ImageQuality = clipInt(_ImageQuality, 63, 6);
}
}
std::string _ImageWbMode = to_upper(splitted[1]);
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)
if (is_string_numeric(_ImageWbMode))
{
CCstatus.ImageSharpness = clipInt(_ImageSharpness, 2, -2);
int _ImageWbMode_ = std::stoi(_ImageWbMode);
CCstatus.ImageWbMode = clip_int(_ImageWbMode_, 4, 0);
}
else
{
CCstatus.ImageSharpness = clipInt(_ImageSharpness, 3, -3);
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]) == "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))
else if (_param == "CAMAWB")
{
int _ImageSpecialEffect_ = std::stoi(_ImageSpecialEffect);
CCstatus.ImageSpecialEffect = clipInt(_ImageSpecialEffect_, 6, 0);
CCstatus.ImageAwb = alphanumeric_to_boolean(splitted[1]);
}
else
else if (_param == "CAMAWBGAIN")
{
if (_ImageSpecialEffect == "NEGATIVE")
CCstatus.ImageAwbGain = alphanumeric_to_boolean(splitted[1]);
}
else if (_param == "CAMAEC")
{
CCstatus.ImageAec = alphanumeric_to_boolean(splitted[1]);
}
else if (_param == "CAMAEC2")
{
CCstatus.ImageAec2 = alphanumeric_to_boolean(splitted[1]);
}
else if (_param == "CAMAELEVEL")
{
if (is_string_numeric(splitted[1]))
{
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;
int _ImageAeLevel = std::stoi(splitted[1]);
if (Camera.CamSensorId == OV2640_PID)
{
CCstatus.ImageAeLevel = clip_int(_ImageAeLevel, 2, -2);
}
else
{
CCstatus.ImageAeLevel = clip_int(_ImageAeLevel, 5, -5);
}
}
}
}
else if ((toUpper(splitted[0]) == "CAMWBMODE") && (splitted.size() > 1))
{
std::string _ImageWbMode = toUpper(splitted[1]);
if (isStringNumeric(_ImageWbMode))
else if (_param == "CAMAECVALUE")
{
int _ImageWbMode_ = std::stoi(_ImageWbMode);
CCstatus.ImageWbMode = clipInt(_ImageWbMode_, 4, 0);
}
else
{
if (_ImageWbMode == "SUNNY")
if (is_string_numeric(splitted[1]))
{
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;
int _ImageAecValue = std::stoi(splitted[1]);
CCstatus.ImageAecValue = clip_int(_ImageAecValue, 1200, 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]))
else if (_param == "CAMAGC")
{
int _ImageAeLevel = std::stoi(splitted[1]);
if (CCstatus.CamSensor_id == OV2640_PID)
CCstatus.ImageAgc = alphanumeric_to_boolean(splitted[1]);
}
else if (_param == "CAMAGCGAIN")
{
if (is_string_numeric(splitted[1]))
{
CCstatus.ImageAeLevel = clipInt(_ImageAeLevel, 2, -2);
}
else
{
CCstatus.ImageAeLevel = clipInt(_ImageAeLevel, 5, -5);
int _ImageAgcGain = std::stoi(splitted[1]);
CCstatus.ImageAgcGain = clip_int(_ImageAgcGain, 30, 0);
}
}
}
else if ((toUpper(splitted[0]) == "CAMAECVALUE") && (splitted.size() > 1))
{
if (isStringNumeric(splitted[1]))
else if (_param == "CAMBPC")
{
int _ImageAecValue = std::stoi(splitted[1]);
CCstatus.ImageAecValue = clipInt(_ImageAecValue, 1200, 0);
CCstatus.ImageBpc = alphanumeric_to_boolean(splitted[1]);
}
}
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]))
else if (_param == "CAMWPC")
{
int _ImageAgcGain = std::stoi(splitted[1]);
CCstatus.ImageAgcGain = clipInt(_ImageAgcGain, 30, 0);
CCstatus.ImageWpc = alphanumeric_to_boolean(splitted[1]);
}
}
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]))
else if (_param == "CAMRAWGMA")
{
int _ImageDenoiseLevel = std::stoi(splitted[1]);
if (CCstatus.CamSensor_id == OV2640_PID)
CCstatus.ImageRawGma = alphanumeric_to_boolean(splitted[1]);
}
else if (_param == "CAMLENC")
{
CCstatus.ImageLenc = alphanumeric_to_boolean(splitted[1]);
}
else if (_param == "CAMHMIRROR")
{
CCstatus.ImageHmirror = alphanumeric_to_boolean(splitted[1]);
}
else if (_param == "CAMVFLIP")
{
CCstatus.ImageVflip = alphanumeric_to_boolean(splitted[1]);
}
else if (_param == "CAMDCW")
{
CCstatus.ImageDcw = alphanumeric_to_boolean(splitted[1]);
}
else if (_param == "CAMDENOISE")
{
if (is_string_numeric(splitted[1]))
{
CCstatus.ImageDenoiseLevel = 0;
}
else
{
CCstatus.ImageDenoiseLevel = clipInt(_ImageDenoiseLevel, 8, 0);
int _ImageDenoiseLevel = std::stoi(splitted[1]);
if (Camera.CamSensorId == OV2640_PID)
{
CCstatus.ImageDenoiseLevel = 0;
}
else
{
CCstatus.ImageDenoiseLevel = clip_int(_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]))
else if (_param == "CAMZOOM")
{
int _ImageZoomOffsetX = std::stoi(splitted[1]);
if (CCstatus.CamSensor_id == OV2640_PID)
CCstatus.ImageZoomEnabled = alphanumeric_to_boolean(splitted[1]);
}
else if (_param == "CAMZOOMOFFSETX")
{
if (is_string_numeric(splitted[1]))
{
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);
int _ImageZoomOffsetX = std::stoi(splitted[1]);
if (Camera.CamSensorId == OV2640_PID)
{
CCstatus.ImageZoomOffsetX = clip_int(_ImageZoomOffsetX, 480, -480);
}
else if (Camera.CamSensorId == OV3660_PID)
{
CCstatus.ImageZoomOffsetX = clip_int(_ImageZoomOffsetX, 704, -704);
}
else if (Camera.CamSensorId == OV5640_PID)
{
CCstatus.ImageZoomOffsetX = clip_int(_ImageZoomOffsetX, 960, -960);
}
}
}
}
else if ((toUpper(splitted[0]) == "CAMZOOMOFFSETY") && (splitted.size() > 1))
{
if (isStringNumeric(splitted[1]))
else if (_param == "CAMZOOMOFFSETY")
{
int _ImageZoomOffsetY = std::stoi(splitted[1]);
if (CCstatus.CamSensor_id == OV2640_PID)
if (is_string_numeric(splitted[1]))
{
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);
int _ImageZoomOffsetY = std::stoi(splitted[1]);
if (Camera.CamSensorId == OV2640_PID)
{
CCstatus.ImageZoomOffsetY = clip_int(_ImageZoomOffsetY, 360, -360);
}
else if (Camera.CamSensorId == OV3660_PID)
{
CCstatus.ImageZoomOffsetY = clip_int(_ImageZoomOffsetY, 528, -528);
}
else if (Camera.CamSensorId == OV5640_PID)
{
CCstatus.ImageZoomOffsetY = clip_int(_ImageZoomOffsetY, 720, -720);
}
}
}
}
else if ((toUpper(splitted[0]) == "CAMZOOMSIZE") && (splitted.size() > 1))
{
if (isStringNumeric(splitted[1]))
else if (_param == "CAMZOOMSIZE")
{
int _ImageZoomSize = std::stoi(splitted[1]);
if (CCstatus.CamSensor_id == OV2640_PID)
if (is_string_numeric(splitted[1]))
{
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);
int _ImageZoomSize = std::stoi(splitted[1]);
if (Camera.CamSensorId == OV2640_PID)
{
CCstatus.ImageZoomSize = clip_int(_ImageZoomSize, 29, 0);
}
else if (Camera.CamSensorId == OV3660_PID)
{
CCstatus.ImageZoomSize = clip_int(_ImageZoomSize, 43, 0);
}
else if (Camera.CamSensorId == OV5640_PID)
{
CCstatus.ImageZoomSize = clip_int(_ImageZoomSize, 59, 0);
}
}
}
}
else if ((toUpper(splitted[0]) == "LEDINTENSITY") && (splitted.size() > 1))
{
if (isStringNumeric(splitted[1]))
else if (_param == "LEDINTENSITY")
{
int ledintensity = std::stoi(splitted[1]);
CCstatus.ImageLedIntensity = Camera.SetLEDIntensity(ledintensity);
if (is_string_numeric(splitted[1]))
{
int ledintensity = std::stoi(splitted[1]);
CCstatus.ImageLedIntensity = Camera.set_led_intensity(ledintensity);
}
}
}
else if ((toUpper(splitted[0]) == "DEMO") && (splitted.size() > 1))
{
CCstatus.DemoMode = alphanumericToBoolean(splitted[1]);
if (CCstatus.DemoMode == true)
else if (_param == "DEMO")
{
Camera.useDemoMode();
Camera.DemoMode = alphanumeric_to_boolean(splitted[1]);
if (Camera.DemoMode == true)
{
Camera.use_demo_mode();
}
}
}
}
Camera.setSensorDatenFromCCstatus(); // CCstatus >>> Kamera
Camera.SetQualityZoomSize(CCstatus.ImageQuality, CCstatus.ImageFrameSize, CCstatus.ImageZoomEnabled, CCstatus.ImageZoomOffsetX, CCstatus.ImageZoomOffsetY, CCstatus.ImageZoomSize, CCstatus.ImageVflip);
Camera.set_sensor_controll_config(&CCstatus); // CCstatus >>> Kamera
Camera.set_quality_zoom_size(&CCstatus);
Camera.changedCameraSettings = false;
Camera.CamTempImage = false;
rawImage = new CImageBasis("rawImage");
rawImage->CreateEmptyImage(CCstatus.ImageWidth, CCstatus.ImageHeight, 3);
@@ -530,57 +514,39 @@ ClassFlowTakeImage::ClassFlowTakeImage(std::vector<ClassFlow *> *lfc) : ClassFlo
SetInitialParameter();
}
string ClassFlowTakeImage::getHTMLSingleStep(string host)
std::string ClassFlowTakeImage::getHTMLSingleStep(std::string host)
{
string result;
std::string result;
result = "Raw Image: <br>\n<img src=\"" + host + "/img_tmp/raw.jpg\">\n";
return result;
}
// wird bei jeder Auswertrunde aufgerufen
bool ClassFlowTakeImage::doFlow(string zwtime)
bool ClassFlowTakeImage::doFlow(std::string zwtime)
{
psram_init_shared_memory_for_take_image_step();
string logPath = CreateLogFolder(zwtime);
std::string logPath = CreateLogFolder(zwtime);
int flash_duration = (int)(CCstatus.WaitBeforePicture * 1000);
#ifdef DEBUG_DETAIL_ON
LogFile.WriteHeapInfo("ClassFlowTakeImage::doFlow - Before takePictureWithFlash");
#endif
if (Camera.CamTempImage)
{
flash_duration = (int)(CFstatus.WaitBeforePicture * 1000);
}
#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);
Camera.LedIntensity = CCstatus.ImageLedIntensity;
CFstatus.changedCameraSettings = false;
}
takePictureWithFlash(flash_duration);
#ifdef WIFITURNOFF
esp_wifi_start();
#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
psram_deinit_shared_memory_for_take_image_step();
return true;
@@ -589,18 +555,29 @@ bool ClassFlowTakeImage::doFlow(string zwtime)
esp_err_t ClassFlowTakeImage::SendRawJPG(httpd_req_t *req)
{
int flash_duration = (int)(CCstatus.WaitBeforePicture * 1000);
if (Camera.CamTempImage)
{
flash_duration = (int)(CFstatus.WaitBeforePicture * 1000);
}
time(&TimeImageTaken);
localtime(&TimeImageTaken);
return Camera.CaptureToHTTP(req, flash_duration);
return Camera.capture_to_http(req, flash_duration);
}
ImageData *ClassFlowTakeImage::SendRawImage(void)
{
CImageBasis *zw = new CImageBasis("SendRawImage", rawImage);
ImageData *id;
int flash_duration = (int)(CCstatus.WaitBeforePicture * 1000);
Camera.CaptureToBasisImage(zw, flash_duration);
if (Camera.CamTempImage)
{
flash_duration = (int)(CFstatus.WaitBeforePicture * 1000);
}
Camera.capture_to_basis_image(zw, flash_duration);
time(&TimeImageTaken);
localtime(&TimeImageTaken);

View File

@@ -3,17 +3,17 @@
#ifndef CLASSFFLOWTAKEIMAGE_H
#define CLASSFFLOWTAKEIMAGE_H
#include <string>
#include "defines.h"
#include "ClassFlowImage.h"
#include "ClassControllCamera.h"
#include "../../include/defines.h"
#include <string>
class ClassFlowTakeImage : public ClassFlowImage
{
protected:
time_t TimeImageTaken;
string namerawimage;
std::string NameRawImage;
esp_err_t camera_capture(void);
void takePictureWithFlash(int flash_duration);
@@ -25,11 +25,11 @@ public:
ClassFlowTakeImage(std::vector<ClassFlow *> *lfc);
bool ReadParameter(FILE *pfile, string &aktparamgraph);
bool doFlow(string time);
string getHTMLSingleStep(string host);
bool ReadParameter(FILE *pFile, std::string &aktparamgraph);
bool doFlow(std::string time);
std::string getHTMLSingleStep(std::string host);
time_t getTimeImageTaken(void);
string name() { return "ClassFlowTakeImage"; };
std::string name() { return "ClassFlowTakeImage"; };
ImageData *SendRawImage(void);
esp_err_t SendRawJPG(httpd_req_t *req);
@@ -37,4 +37,4 @@ public:
~ClassFlowTakeImage(void);
};
#endif // CLASSFFLOWTAKEIMAGE_H
#endif // CLASSFFLOWTAKEIMAGE_H

View File

@@ -1,8 +1,11 @@
#ifdef ENABLE_WEBHOOK
#include <sstream>
#include "ClassFlowWebhook.h"
#include "defines.h"
#include "Helper.h"
#include "connect_wlan.h"
#include <time.h>
#include <sstream>
#include "ClassFlowWebhook.h"
#include "connect_wifi_sta.h"
#include "time_sntp.h"
#include "interface_webhook.h"
@@ -10,32 +13,35 @@
#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";
static const char* TAG = "WEBHOOK";
Webhook_controll_config_t Webhook_controll_config;
void ClassFlowWebhook::SetInitialParameter(void)
{
uri = "";
Webhook_controll_config.enabled = false;
Webhook_controll_config.uri = "";
Webhook_controll_config.apikey = "";
Webhook_controll_config.uploadImg = 0;
Webhook_controll_config.oldValue = "";
flowpostprocessing = NULL;
flowAlignment = NULL;
previousElement = NULL;
ListFlowControll = NULL;
ListFlowControll = NULL;
disabled = false;
WebhookEnable = false;
WebhookUploadImg = 0;
}
}
ClassFlowWebhook::ClassFlowWebhook()
{
SetInitialParameter();
}
ClassFlowWebhook::ClassFlowWebhook(std::vector<ClassFlow*>* lfc)
ClassFlowWebhook::ClassFlowWebhook(std::vector<ClassFlow *> *lfc)
{
SetInitialParameter();
@@ -44,17 +50,17 @@ ClassFlowWebhook::ClassFlowWebhook(std::vector<ClassFlow*>* lfc)
{
if (((*ListFlowControll)[i])->name().compare("ClassFlowPostProcessing") == 0)
{
flowpostprocessing = (ClassFlowPostProcessing*) (*ListFlowControll)[i];
}
if (((*ListFlowControll)[i])->name().compare("ClassFlowAlignment") == 0)
{
flowAlignment = (ClassFlowAlignment*) (*ListFlowControll)[i];
flowpostprocessing = (ClassFlowPostProcessing *)(*ListFlowControll)[i];
}
if (((*ListFlowControll)[i])->name().compare("ClassFlowAlignment") == 0)
{
flowAlignment = (ClassFlowAlignment *)(*ListFlowControll)[i];
}
}
}
ClassFlowWebhook::ClassFlowWebhook(std::vector<ClassFlow*>* lfc, ClassFlow *_prev)
ClassFlowWebhook::ClassFlowWebhook(std::vector<ClassFlow *> *lfc, ClassFlow *_prev)
{
SetInitialParameter();
@@ -65,107 +71,131 @@ ClassFlowWebhook::ClassFlowWebhook(std::vector<ClassFlow*>* lfc, ClassFlow *_pre
{
if (((*ListFlowControll)[i])->name().compare("ClassFlowPostProcessing") == 0)
{
flowpostprocessing = (ClassFlowPostProcessing*) (*ListFlowControll)[i];
flowpostprocessing = (ClassFlowPostProcessing *)(*ListFlowControll)[i];
}
if (((*ListFlowControll)[i])->name().compare("ClassFlowAlignment") == 0)
{
flowAlignment = (ClassFlowAlignment*) (*ListFlowControll)[i];
flowAlignment = (ClassFlowAlignment *)(*ListFlowControll)[i];
}
}
}
bool ClassFlowWebhook::ReadParameter(FILE* pfile, string& aktparamgraph)
bool ClassFlowWebhook::ReadParameter(FILE *pFile, std::string &aktparamgraph)
{
std::vector<string> splitted;
aktparamgraph = trim(aktparamgraph);
printf("akt param: %s\n", aktparamgraph.c_str());
aktparamgraph = trim_string_left_right(aktparamgraph);
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))
if (!GetNextParagraph(pFile, aktparamgraph))
{
this->uri = splitted[1];
return false;
}
if (((toUpper(_param) == "APIKEY")) && (splitted.size() > 1))
}
if ((to_upper(aktparamgraph).compare("[WEBHOOK]") != 0) && (to_upper(aktparamgraph).compare(";[WEBHOOK]") != 0))
{
return false;
}
if (aktparamgraph[0] == ';')
{
Webhook_controll_config.enabled = false;
while (getNextLine(pFile, &aktparamgraph) && !isNewParagraph(aktparamgraph));
ESP_LOGD(TAG, "Webhook is disabled!");
return true;
}
std::vector<std::string> splitted;
while (getNextLine(pFile, &aktparamgraph) && !isNewParagraph(aktparamgraph))
{
splitted = split_line(aktparamgraph);
if (splitted.size() > 1)
{
this->apikey = splitted[1];
}
if (((toUpper(_param) == "UPLOADIMG")) && (splitted.size() > 1))
{
if (toUpper(splitted[1]) == "1")
std::string _param = to_upper(GetParameterName(splitted[0]));
if (_param == "URI")
{
this->WebhookUploadImg = 1;
} else if (toUpper(splitted[1]) == "2")
Webhook_controll_config.uri = splitted[1];
}
else if (_param == "APIKEY")
{
this->WebhookUploadImg = 2;
Webhook_controll_config.apikey = splitted[1];
}
else if (_param == "UPLOADIMG")
{
if (to_upper(splitted[1]) == "1")
{
Webhook_controll_config.uploadImg = 1;
}
else if (to_upper(splitted[1]) == "2")
{
Webhook_controll_config.uploadImg = 2;
}
}
}
}
WebhookInit(uri,apikey);
WebhookEnable = true;
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Webhook Enabled for Uri " + uri);
printf("uri: %s\n", uri.c_str());
if ((Webhook_controll_config.uri.length() > 0) && (Webhook_controll_config.apikey.length() > 0))
{
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Init Webhook with uri: " + Webhook_controll_config.uri + ", apikey: *****");
WebhookInit(Webhook_controll_config.uri, Webhook_controll_config.apikey);
Webhook_controll_config.enabled = true;
}
else
{
LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Webhook init skipped as we are missing some parameters");
Webhook_controll_config.enabled = false;
}
return true;
}
void ClassFlowWebhook::handleMeasurement(string _decsep, string _value)
void ClassFlowWebhook::handleMeasurement(std::string _decsep, std::string _value)
{
string _digit, _decpos;
std::string _digit;
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)
// Set to default first (if nothing else is set)
if ((_digit == "default") || (flowpostprocessing->NUMBERS[j]->name == _digit))
{
flowpostprocessing->NUMBERS[j]->MeasurementV2 = _value;
}
}
}
bool ClassFlowWebhook::doFlow(string zwtime)
bool ClassFlowWebhook::doFlow(std::string temp_time)
{
if (!WebhookEnable)
if (!Webhook_controll_config.enabled)
{
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
#ifdef ALGROI_LOAD_FROM_MEM_AS_JPG
if ((Webhook_controll_config.uploadImg == 1 || (Webhook_controll_config.uploadImg != 0 && numbersWithError)) && flowAlignment && flowAlignment->AlgROI)
{
WebhookUploadPic(flowAlignment->AlgROI);
}
#endif
}
return true;
}
#endif //ENABLE_WEBHOOK

View File

@@ -1,43 +1,42 @@
#ifdef ENABLE_WEBHOOK
#pragma once
#ifndef CLASSFWEBHOOK_H
#define CLASSFWEBHOOK_H
#include "ClassFlow.h"
#include <string>
#include "ClassFlow.h"
#include "ClassFlowPostProcessing.h"
#include "ClassFlowAlignment.h"
#include <string>
typedef struct
{
bool enabled;
std::string uri;
std::string apikey;
int uploadImg;
std::string oldValue;
} Webhook_controll_config_t;
class ClassFlowWebhook :
public ClassFlow
extern Webhook_controll_config_t Webhook_controll_config;
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);
ClassFlowPostProcessing *flowpostprocessing;
ClassFlowAlignment *flowAlignment;
void SetInitialParameter(void);
void handleMeasurement(std::string _decsep, std::string _value);
public:
ClassFlowWebhook();
ClassFlowWebhook(std::vector<ClassFlow*>* lfc);
ClassFlowWebhook(std::vector<ClassFlow*>* lfc, ClassFlow *_prev);
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";};
bool ReadParameter(FILE *pFile, std::string &aktparamgraph);
bool doFlow(std::string temp_time);
std::string name() { return "ClassFlowWebhook"; };
};
#endif //CLASSFWEBHOOK_H
#endif //ENABLE_WEBHOOK
#endif // CLASSFWEBHOOK_H

File diff suppressed because it is too large Load Diff

View File

@@ -3,75 +3,16 @@
#ifndef MAINFLOWCONTROL_H
#define MAINFLOWCONTROL_H
#include <esp_log.h>
#include <string>
#include <esp_log.h>
#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);
@@ -81,11 +22,11 @@ bool isSetupModusActive(void);
int getCountFlowRounds(void);
#ifdef ENABLE_MQTT
esp_err_t MQTTCtrlFlowStart(std::string _topic);
#endif // ENABLE_MQTT
esp_err_t GetRawJPG(httpd_req_t *req);
esp_err_t GetJPG(std::string _filename, httpd_req_t *req);
void main_flow_register_uri(httpd_handle_t server);
#endif // MAINFLOWCONTROL_H