diff --git a/code/lib/jomjol_fileserver_ota/server_file.cpp b/code/lib/jomjol_fileserver_ota/server_file.cpp
index 633542bc..78f45a74 100644
--- a/code/lib/jomjol_fileserver_ota/server_file.cpp
+++ b/code/lib/jomjol_fileserver_ota/server_file.cpp
@@ -84,7 +84,7 @@ static esp_err_t favicon_get_handler(httpd_req_t *req)
* a list of all files and folders under the requested path.
* In case of SPIFFS this returns empty list when path is any
* string other than '/', since SPIFFS doesn't support directories */
-static esp_err_t http_resp_dir_html(httpd_req_t *req, const char *dirpath)
+static esp_err_t http_resp_dir_html(httpd_req_t *req, const char *dirpath, const char* uripath, bool readonly)
{
char entrypath[FILE_PATH_MAX];
char entrysize[16];
@@ -120,24 +120,24 @@ static esp_err_t http_resp_dir_html(httpd_req_t *req, const char *dirpath)
httpd_resp_sendstr_chunk(req, "
");
/////////////////////////////////////////////////
-
- FILE *fd = fopen("/sdcard/html/upload_script.html", "r");
- char *chunk = ((struct file_server_data *)req->user_ctx)->scratch;
- size_t chunksize;
- do {
- chunksize = fread(chunk, 1, SCRATCH_BUFSIZE, fd);
-// printf("Chunksize %d\n", chunksize);
- if (chunksize > 0){
- if (httpd_resp_send_chunk(req, chunk, chunksize) != ESP_OK) {
- fclose(fd);
- ESP_LOGE(TAG, "File sending failed!");
- return ESP_FAIL;
+ if (!readonly) {
+ FILE *fd = fopen("/sdcard/html/upload_script.html", "r");
+ char *chunk = ((struct file_server_data *)req->user_ctx)->scratch;
+ size_t chunksize;
+ do {
+ chunksize = fread(chunk, 1, SCRATCH_BUFSIZE, fd);
+ // printf("Chunksize %d\n", chunksize);
+ if (chunksize > 0){
+ if (httpd_resp_send_chunk(req, chunk, chunksize) != ESP_OK) {
+ fclose(fd);
+ ESP_LOGE(TAG, "File sending failed!");
+ return ESP_FAIL;
+ }
}
- }
- } while (chunksize != 0);
- fclose(fd);
-// ESP_LOGI(TAG, "File sending complete");
-
+ } while (chunksize != 0);
+ fclose(fd);
+ // ESP_LOGI(TAG, "File sending complete");
+ }
///////////////////////////////
std::string _zw = std::string(dirpath);
@@ -149,12 +149,16 @@ static esp_err_t http_resp_dir_html(httpd_req_t *req, const char *dirpath)
httpd_resp_sendstr_chunk(req,
""
""
- "| Name | Type | Size (Bytes) | Delete "
- ""
- " |
\n");
+ "| Name | Type | Size (Bytes) | ");
+ if (!readonly) {
+ httpd_resp_sendstr_chunk(req, "Delete "
+ ""
+ " |
");
+ }
+ httpd_resp_sendstr_chunk(req, "\n");
/* Iterate over all files / folders and fetch their names and sizes */
while ((entry = readdir(dir)) != NULL) {
@@ -173,7 +177,8 @@ static esp_err_t http_resp_dir_html(httpd_req_t *req, const char *dirpath)
/* Send chunk of HTML file containing table entries with file name and size */
httpd_resp_sendstr_chunk(req, "| uri);
+ httpd_resp_sendstr_chunk(req, "/fileserver");
+ httpd_resp_sendstr_chunk(req, uripath);
httpd_resp_sendstr_chunk(req, entry->d_name);
if (entry->d_type == DT_DIR) {
httpd_resp_sendstr_chunk(req, "/");
@@ -184,11 +189,13 @@ static esp_err_t http_resp_dir_html(httpd_req_t *req, const char *dirpath)
httpd_resp_sendstr_chunk(req, entrytype);
httpd_resp_sendstr_chunk(req, " | ");
httpd_resp_sendstr_chunk(req, entrysize);
- httpd_resp_sendstr_chunk(req, " | ");
- httpd_resp_sendstr_chunk(req, "");
+ if (!readonly) {
+ httpd_resp_sendstr_chunk(req, " | ");
+ httpd_resp_sendstr_chunk(req, "");
+ }
httpd_resp_sendstr_chunk(req, " |
\n");
}
}
@@ -226,6 +233,7 @@ static esp_err_t download_get_handler(httpd_req_t *req)
// filename = get_path_from_uri(filepath, ((struct file_server_data *)req->user_ctx)->base_path,
// req->uri, sizeof(filepath));
+
if (!filename) {
ESP_LOGE(TAG, "Filename is too long");
/* Respond with 500 Internal Server Error */
@@ -235,7 +243,22 @@ static esp_err_t download_get_handler(httpd_req_t *req)
/* If name has trailing '/', respond with directory contents */
if (filename[strlen(filename) - 1] == '/') {
- return http_resp_dir_html(req, filepath);
+ bool readonly = false;
+ size_t buf_len = httpd_req_get_url_query_len(req) + 1;
+ if (buf_len > 1) {
+ char buf[buf_len];
+ if (httpd_req_get_url_query_str(req, buf, buf_len) == ESP_OK) {
+ ESP_LOGI(TAG, "Found URL query => %s", buf);
+ char param[32];
+ /* Get value of expected key from query string */
+ if (httpd_query_key_value(buf, "readonly", param, sizeof(param)) == ESP_OK) {
+ ESP_LOGI(TAG, "Found URL query parameter => readonly=%s", param);
+ readonly = param && strcmp(param,"true")==0;
+ }
+ }
+ }
+
+ return http_resp_dir_html(req, filepath, filename, readonly);
}
std::string testwlan = toUpper(std::string(filename));
diff --git a/code/lib/jomjol_flowcontroll/ClassFlow.h b/code/lib/jomjol_flowcontroll/ClassFlow.h
index 35928d91..18260229 100644
--- a/code/lib/jomjol_flowcontroll/ClassFlow.h
+++ b/code/lib/jomjol_flowcontroll/ClassFlow.h
@@ -9,6 +9,10 @@
using namespace std;
+#define LOGFILE_TIME_FORMAT "%Y%m%d-%H%M%S"
+#define LOGFILE_TIME_FORMAT_DATE_EXTR substr(0, 8)
+#define LOGFILE_TIME_FORMAT_HOUR_EXTR substr(9, 2)
+
struct HTMLInfo
{
float val;
diff --git a/code/lib/jomjol_flowcontroll/ClassFlowAnalog.cpp b/code/lib/jomjol_flowcontroll/ClassFlowAnalog.cpp
index fa6085e7..d0dea860 100644
--- a/code/lib/jomjol_flowcontroll/ClassFlowAnalog.cpp
+++ b/code/lib/jomjol_flowcontroll/ClassFlowAnalog.cpp
@@ -2,7 +2,7 @@
#include
#include
-#include
+#include
// #define OHNETFLITE
@@ -12,25 +12,23 @@
#include "ClassLogFile.h"
+static const char* TAG = "flow_analog";
+
bool debugdetailanalog = false;
-ClassFlowAnalog::ClassFlowAnalog()
+ClassFlowAnalog::ClassFlowAnalog() : ClassFlowImage(TAG)
{
- isLogImage = false;
string cnnmodelfile = "";
modelxsize = 1;
modelysize = 1;
ListFlowControll = NULL;
}
-ClassFlowAnalog::ClassFlowAnalog(std::vector* lfc)
+ClassFlowAnalog::ClassFlowAnalog(std::vector* lfc) : ClassFlowImage(lfc, TAG)
{
- isLogImage = false;
string cnnmodelfile = "";
modelxsize = 1;
modelysize = 1;
- ListFlowControll = NULL;
- ListFlowControll = lfc;
}
@@ -90,8 +88,12 @@ bool ClassFlowAnalog::ReadParameter(FILE* pfile, string& aktparamgraph)
zerlegt = this->ZerlegeZeile(aktparamgraph);
if ((zerlegt[0] == "LogImageLocation") && (zerlegt.size() > 1))
{
+ this->LogImageLocation = "/sdcard" + zerlegt[1];
this->isLogImage = true;
- this->LogImageLocation = zerlegt[1];
+ }
+ if ((toUpper(zerlegt[0]) == "LOGFILERETENTIONINDAYS") && (zerlegt.size() > 1))
+ {
+ this->logfileRetentionInDays = std::stoi(zerlegt[1]);
}
if ((zerlegt[0] == "Model") && (zerlegt.size() > 1))
{
@@ -153,6 +155,8 @@ bool ClassFlowAnalog::doFlow(string time)
doNeuralNetwork(time);
+ RemoveOldLogs();
+
return true;
}
@@ -233,10 +237,11 @@ bool ClassFlowAnalog::doAlignAndCut(string time)
bool ClassFlowAnalog::doNeuralNetwork(string time)
{
+ string logPath = CreateLogFolder(time);
+
string input = "/sdcard/img_tmp/alg.jpg";
string ioresize = "/sdcard/img_tmp/resize.bmp";
string output;
- string nm;
input = FormatFileName(input);
#ifndef OHNETFLITE
@@ -275,19 +280,7 @@ bool ClassFlowAnalog::doNeuralNetwork(string time)
printf("Result Analog%i: %f\n", i, ROI[i]->result);
- if (isLogImage)
- {
- std::stringstream stream;
- stream << std::fixed << std::setprecision(1) << ROI[i]->result;
- std::string s = stream.str();
-// std::snprintf(&s[0], s.size(), "%.2f", pi);
- nm = "/sdcard" + LogImageLocation + "/" + s + "_" + ROI[i]->name + "_" + time + ".jpg";
- nm = FormatFileName(nm);
- output = "/sdcard/img_tmp/" + ROI[i]->name + ".jpg";
- output = FormatFileName(output);
- printf("Analog - save to file: %s\n", nm.c_str());
- CopyFile(output, nm);
- }
+ LogImage(logPath, ROI[i]->name, &ROI[i]->result, NULL, time);
}
#ifndef OHNETFLITE
delete tflite;
diff --git a/code/lib/jomjol_flowcontroll/ClassFlowAnalog.h b/code/lib/jomjol_flowcontroll/ClassFlowAnalog.h
index ce41f17f..89f2f6e2 100644
--- a/code/lib/jomjol_flowcontroll/ClassFlowAnalog.h
+++ b/code/lib/jomjol_flowcontroll/ClassFlowAnalog.h
@@ -1,5 +1,5 @@
#pragma once
-#include "ClassFlow.h"
+#include "ClassFlowImage.h"
// #include "CTfLiteClass.h"
struct roianalog {
@@ -10,11 +10,9 @@ struct roianalog {
class ClassFlowAnalog :
- public ClassFlow
+ public ClassFlowImage
{
protected:
- string LogImageLocation;
- bool isLogImage;
std::vector ROI;
string cnnmodelfile;
int modelxsize, modelysize;
diff --git a/code/lib/jomjol_flowcontroll/ClassFlowControll.cpp b/code/lib/jomjol_flowcontroll/ClassFlowControll.cpp
index 50ea08c7..3307f5eb 100644
--- a/code/lib/jomjol_flowcontroll/ClassFlowControll.cpp
+++ b/code/lib/jomjol_flowcontroll/ClassFlowControll.cpp
@@ -1,10 +1,14 @@
#include "ClassFlowControll.h"
+#include
+#include
#include "ClassLogFile.h"
#include "time_sntp.h"
#include "Helper.h"
#include "server_ota.h"
+static const char* TAG = "flow_controll";
+
std::string ClassFlowControll::doSingleStep(std::string _stepname, std::string _host){
std::string _classname = "";
std::string result = "";
@@ -149,6 +153,8 @@ std::string ClassFlowControll::getActStatus(){
bool ClassFlowControll::doFlow(string time)
{
+ CleanTempFolder();
+
bool result = true;
std::string zw_time;
int repeat = 0;
@@ -280,8 +286,41 @@ bool ClassFlowControll::ReadParameter(FILE* pfile, string& aktparamgraph)
{
LogFile.SwitchOnOff(false);
}
+ }
+ if ((toUpper(zerlegt[0]) == "LOGFILERETENTIONINDAYS") && (zerlegt.size() > 1))
+ {
+ LogFile.SetRetention(std::stoi(zerlegt[1]));
}
}
return true;
}
+int ClassFlowControll::CleanTempFolder() {
+ const char* folderPath = "/sdcard/img_tmp";
+
+ ESP_LOGI(TAG, "Clean up temporary folder to avoid damage of sdcard sectors : %s", folderPath);
+ DIR *dir = opendir(folderPath);
+ if (!dir) {
+ ESP_LOGE(TAG, "Failed to stat dir : %s", folderPath);
+ return -1;
+ }
+
+ struct dirent *entry;
+ int deleted = 0;
+ while ((entry = readdir(dir)) != NULL) {
+ std::string path = string(folderPath) + "/" + entry->d_name;
+ if (entry->d_type == DT_REG) {
+ if (unlink(path.c_str()) == 0) {
+ deleted ++;
+ } else {
+ ESP_LOGE(TAG, "can't delete file : %s", path.c_str());
+ }
+ } else if (entry->d_type == DT_DIR) {
+ deleted += removeFolder(path.c_str(), TAG);
+ }
+ }
+ closedir(dir);
+ ESP_LOGI(TAG, "%d files deleted", deleted);
+
+ return 0;
+}
\ No newline at end of file
diff --git a/code/lib/jomjol_flowcontroll/ClassFlowControll.h b/code/lib/jomjol_flowcontroll/ClassFlowControll.h
index d3d9de9a..91eac5fa 100644
--- a/code/lib/jomjol_flowcontroll/ClassFlowControll.h
+++ b/code/lib/jomjol_flowcontroll/ClassFlowControll.h
@@ -42,6 +42,8 @@ public:
std::vector GetAllDigital();
std::vector GetAllAnalog();
+ int CleanTempFolder();
+
string name(){return "ClassFlowControll";};
};
diff --git a/code/lib/jomjol_flowcontroll/ClassFlowDigit.cpp b/code/lib/jomjol_flowcontroll/ClassFlowDigit.cpp
index 70f1132b..90f02254 100644
--- a/code/lib/jomjol_flowcontroll/ClassFlowDigit.cpp
+++ b/code/lib/jomjol_flowcontroll/ClassFlowDigit.cpp
@@ -13,23 +13,21 @@
#include "ClassLogFile.h"
-ClassFlowDigit::ClassFlowDigit()
+static const char* TAG = "flow_digital";
+
+ClassFlowDigit::ClassFlowDigit() : ClassFlowImage(TAG)
{
- isLogImage = false;
string cnnmodelfile = "";
modelxsize = 1;
modelysize = 1;
ListFlowControll = NULL;
}
-ClassFlowDigit::ClassFlowDigit(std::vector* lfc)
+ClassFlowDigit::ClassFlowDigit(std::vector* lfc) : ClassFlowImage(lfc, TAG)
{
- isLogImage = false;
string cnnmodelfile = "";
modelxsize = 1;
modelysize = 1;
- ListFlowControll = NULL;
- ListFlowControll = lfc;
}
string ClassFlowDigit::getReadout()
@@ -66,8 +64,8 @@ bool ClassFlowDigit::ReadParameter(FILE* pfile, string& aktparamgraph)
zerlegt = this->ZerlegeZeile(aktparamgraph);
if ((zerlegt[0] == "LogImageLocation") && (zerlegt.size() > 1))
{
- isLogImage = true;
- LogImageLocation = zerlegt[1];
+ LogImageLocation = "/sdcard" + zerlegt[1];
+ isLogImage = true;
}
if ((zerlegt[0] == "Model") && (zerlegt.size() > 1))
{
@@ -128,6 +126,8 @@ bool ClassFlowDigit::doFlow(string time)
doNeuralNetwork(time);
+ RemoveOldLogs();
+
return true;
}
@@ -194,6 +194,8 @@ bool ClassFlowDigit::doAlignAndCut(string time)
bool ClassFlowDigit::doNeuralNetwork(string time)
{
+ string logPath = CreateLogFolder(time);
+
string input = "/sdcard/img_tmp/alg.jpg";
string ioresize = "/sdcard/img_tmp/resize.bmp";
string output;
@@ -221,16 +223,9 @@ bool ClassFlowDigit::doNeuralNetwork(string time)
#ifndef OHNETFLITE
ROI[i]->resultklasse = tflite->GetClassFromImage(ioresize);
#endif
- printf("Result Digit%i: %d\n", i, ROI[i]->resultklasse);
+ printf("Result Digit%i: %d\n", i, ROI[i]->resultklasse);
- if (isLogImage)
- {
- nm = "/sdcard" + LogImageLocation + "/" + std::to_string(ROI[i]->resultklasse) + "/" + time + "_" + ROI[i]->name + ".jpg";
- output = "/sdcard/img_tmp/" + ROI[i]->name + ".jpg";
- output = FormatFileName(output);
- nm = FormatFileName(nm);
- CopyFile(output, nm);
- }
+ LogImage(logPath, ROI[i]->name, NULL, &ROI[i]->resultklasse, time);
}
#ifndef OHNETFLITE
delete tflite;
diff --git a/code/lib/jomjol_flowcontroll/ClassFlowDigit.h b/code/lib/jomjol_flowcontroll/ClassFlowDigit.h
index b84c7f37..3546bb36 100644
--- a/code/lib/jomjol_flowcontroll/ClassFlowDigit.h
+++ b/code/lib/jomjol_flowcontroll/ClassFlowDigit.h
@@ -1,5 +1,5 @@
#pragma once
-#include "ClassFlow.h"
+#include "ClassFlowImage.h"
#include "Helper.h"
#include
@@ -12,11 +12,9 @@ struct roi {
};
class ClassFlowDigit :
- public ClassFlow
+ public ClassFlowImage
{
protected:
- string LogImageLocation;
- bool isLogImage;
std::vector ROI;
string cnnmodelfile;
int modelxsize, modelysize;
diff --git a/code/lib/jomjol_flowcontroll/ClassFlowImage.cpp b/code/lib/jomjol_flowcontroll/ClassFlowImage.cpp
new file mode 100644
index 00000000..5c09160e
--- /dev/null
+++ b/code/lib/jomjol_flowcontroll/ClassFlowImage.cpp
@@ -0,0 +1,101 @@
+#include "ClassFlowImage.h"
+#include
+#include
+#include
+#include
+#include "time_sntp.h"
+#include "ClassLogFile.h"
+
+ClassFlowImage::ClassFlowImage(const char* logTag)
+{
+ this->logTag = logTag;
+ isLogImage = false;
+}
+
+ClassFlowImage::ClassFlowImage(std::vector * lfc, const char* logTag) : ClassFlow((std::vector*)lfc)
+{
+ this->logTag = logTag;
+ isLogImage = false;
+}
+
+string ClassFlowImage::CreateLogFolder(string time) {
+ if (!isLogImage)
+ return "";
+
+ string logPath = LogImageLocation + "/" + time.LOGFILE_TIME_FORMAT_DATE_EXTR + "/" + time.LOGFILE_TIME_FORMAT_HOUR_EXTR;
+ isLogImage = mkdir_r(logPath.c_str(), S_IRWXU) == 0;
+ if (!isLogImage) {
+ ESP_LOGW(logTag, "Can't create log foolder for analog images. Path %s", logPath.c_str());
+ LogFile.WriteToFile("Can't create log foolder for analog images. Path " + logPath);
+ }
+
+ return logPath;
+}
+
+void ClassFlowImage::LogImage(string logPath, string name, float *resultFloat, int *resultInt, string time) {
+ if (!isLogImage)
+ return;
+
+ char buf[10];
+ if (resultFloat != NULL) {
+ sprintf(buf, "%.1f_", *resultFloat);
+ } 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);
+ printf("save to file: %s\n", nm.c_str());
+ CopyFile(output, nm);
+}
+
+void ClassFlowImage::RemoveOldLogs()
+{
+ if (!isLogImage)
+ return;
+
+ ESP_LOGI(logTag, "remove old log images");
+ if (logfileRetentionInDays == 0) {
+ return;
+ }
+
+ time_t rawtime;
+ struct tm* timeinfo;
+ char cmpfilename[30];
+
+ time(&rawtime);
+ rawtime = addDays(rawtime, -logfileRetentionInDays);
+ timeinfo = localtime(&rawtime);
+
+ strftime(cmpfilename, 30, LOGFILE_TIME_FORMAT, timeinfo);
+ //ESP_LOGE(TAG, "log file name to compare: %s", cmpfilename);
+ string folderName = string(cmpfilename).LOGFILE_TIME_FORMAT_DATE_EXTR;
+
+ DIR *dir = opendir(LogImageLocation.c_str());
+ if (!dir) {
+ ESP_LOGI(logTag, "Failed to stat dir : %s", LogImageLocation.c_str());
+ return;
+ }
+
+ struct dirent *entry;
+ int deleted = 0;
+ int notDeleted = 0;
+ while ((entry = readdir(dir)) != NULL) {
+ string folderPath = LogImageLocation + "/" + entry->d_name;
+ if (entry->d_type == DT_DIR) {
+ //ESP_LOGI(logTag, "Compare %s %s", entry->d_name, folderName.c_str());
+ if ((strlen(entry->d_name) == folderName.length()) && (strcmp(entry->d_name, folderName.c_str()) < 0)) {
+ deleted += removeFolder(folderPath.c_str(), logTag);
+ } else {
+ notDeleted ++;
+ }
+ }
+ }
+ ESP_LOGI(logTag, "%d older log files deleted. %d current log files not deleted.", deleted, notDeleted);
+ closedir(dir);
+}
+
diff --git a/code/lib/jomjol_flowcontroll/ClassFlowImage.h b/code/lib/jomjol_flowcontroll/ClassFlowImage.h
new file mode 100644
index 00000000..23154c64
--- /dev/null
+++ b/code/lib/jomjol_flowcontroll/ClassFlowImage.h
@@ -0,0 +1,22 @@
+#pragma once
+#include "ClassFlow.h"
+
+using namespace std;
+
+class ClassFlowImage : public ClassFlow
+{
+protected:
+ string LogImageLocation;
+ bool isLogImage;
+ unsigned short logfileRetentionInDays;
+ const char* logTag;
+
+ string CreateLogFolder(string time);
+ void LogImage(string logPath, string name, float *resultFloat, int *resultInt, string time);
+
+public:
+ ClassFlowImage(const char* logTag);
+ ClassFlowImage(std::vector * lfc, const char* logTag);
+
+ void RemoveOldLogs();
+};
diff --git a/code/lib/jomjol_flowcontroll/ClassFlowMQTT.cpp b/code/lib/jomjol_flowcontroll/ClassFlowMQTT.cpp
index c1d66426..92396e2b 100644
--- a/code/lib/jomjol_flowcontroll/ClassFlowMQTT.cpp
+++ b/code/lib/jomjol_flowcontroll/ClassFlowMQTT.cpp
@@ -6,8 +6,6 @@
#include
-static const char* TAG2 = "example";
-
ClassFlowMQTT::ClassFlowMQTT()
{
uri = "";
diff --git a/code/lib/jomjol_flowcontroll/ClassFlowMakeImage.cpp b/code/lib/jomjol_flowcontroll/ClassFlowMakeImage.cpp
index d7f3d201..d1f4d78c 100644
--- a/code/lib/jomjol_flowcontroll/ClassFlowMakeImage.cpp
+++ b/code/lib/jomjol_flowcontroll/ClassFlowMakeImage.cpp
@@ -1,12 +1,12 @@
#include "ClassFlowMakeImage.h"
#include "Helper.h"
-
#include "CFindTemplate.h"
#include "ClassControllCamera.h"
#include
+static const char* TAG = "flow_make_image";
esp_err_t ClassFlowMakeImage::camera_capture(){
string nm = namerawimage;
@@ -24,11 +24,8 @@ void ClassFlowMakeImage::takePictureWithFlash(int flashdauer)
}
-
-
-ClassFlowMakeImage::ClassFlowMakeImage()
+ClassFlowMakeImage::ClassFlowMakeImage() : ClassFlowImage(TAG)
{
- isLogImage = false;
waitbeforepicture = 5;
isImageSize = false;
ImageQuality = -1;
@@ -36,16 +33,13 @@ ClassFlowMakeImage::ClassFlowMakeImage()
namerawimage = "/sdcard/img_tmp/raw.jpg";
}
-ClassFlowMakeImage::ClassFlowMakeImage(std::vector* lfc)
+ClassFlowMakeImage::ClassFlowMakeImage(std::vector* lfc) : ClassFlowImage(lfc, TAG)
{
- isLogImage = false;
waitbeforepicture = 5;
isImageSize = false;
ImageQuality = -1;
TimeImageTaken = 0;
namerawimage = "/sdcard/img_tmp/raw.jpg";
-
- ListFlowControll = lfc;
}
bool ClassFlowMakeImage::ReadParameter(FILE* pfile, string& aktparamgraph)
@@ -66,8 +60,8 @@ bool ClassFlowMakeImage::ReadParameter(FILE* pfile, string& aktparamgraph)
zerlegt = this->ZerlegeZeile(aktparamgraph);
if ((zerlegt[0] == "LogImageLocation") && (zerlegt.size() > 1))
{
- this->isLogImage = true;
- this->LogImageLocation = zerlegt[1];
+ LogImageLocation = "/sdcard" + zerlegt[1];
+ isLogImage = true;
}
if ((zerlegt[0] == "ImageQuality") && (zerlegt.size() > 1))
this->ImageQuality = std::stod(zerlegt[1]);
@@ -81,45 +75,6 @@ bool ClassFlowMakeImage::ReadParameter(FILE* pfile, string& aktparamgraph)
return true;
}
-
-void ClassFlowMakeImage::CopyFile(string input, string output)
-{
- input = FormatFileName(input);
- output = FormatFileName(output);
- input = namerawimage;
-
-
- printf("Copy Input : %s\n", input.c_str());
- printf("Copy Output: %s\n", output.c_str());
-
- char cTemp;
- FILE* fpSourceFile = fopen(input.c_str(), "rb");
- FILE* fpTargetFile = fopen(output.c_str(), "wb");
-
- if (fpSourceFile == NULL)
- {
- printf("fpSourceFile == NULL\n");
- perror("Error");
- }
-
- if (fpTargetFile == NULL)
- {
- printf("fpTargetFile == NULL\n");
- perror("Error");
- }
-
-
- while (fread(&cTemp, 1, 1, fpSourceFile) == 1)
- {
- fwrite(&cTemp, 1, 1, fpTargetFile);
- }
-
- // Close The Files
- fclose(fpSourceFile);
- fclose(fpTargetFile);
- printf("Copy done\n");
-}
-
string ClassFlowMakeImage::getHTMLSingleStep(string host)
{
string result;
@@ -133,6 +88,8 @@ bool ClassFlowMakeImage::doFlow(string zwtime)
// TakeImage and Store into /image_tmp/raw.jpg TO BE DONE
////////////////////////////////////////////////////////////////////
+ string logPath = CreateLogFolder(zwtime);
+
int flashdauer = (int) waitbeforepicture * 1000;
@@ -140,16 +97,9 @@ bool ClassFlowMakeImage::doFlow(string zwtime)
time(&TimeImageTaken);
localtime(&TimeImageTaken);
+ LogImage(logPath, "raw", NULL, NULL, zwtime);
- if (this->isLogImage)
- {
- string nm = "/sdcard" + this->LogImageLocation + "/" + zwtime + ".jpg";
- string input = "/sdcard/image_tmp/raw.jgp";
- printf("loginput from: %s to: %s\n", input.c_str(), nm.c_str());
- nm = FormatFileName(nm);
- input = FormatFileName(input);
- CopyFile(input, nm);
- }
+ RemoveOldLogs();
return true;
}
diff --git a/code/lib/jomjol_flowcontroll/ClassFlowMakeImage.h b/code/lib/jomjol_flowcontroll/ClassFlowMakeImage.h
index f19eef94..febb2ab3 100644
--- a/code/lib/jomjol_flowcontroll/ClassFlowMakeImage.h
+++ b/code/lib/jomjol_flowcontroll/ClassFlowMakeImage.h
@@ -1,11 +1,9 @@
#pragma once
-#include "ClassFlow.h"
+#include "ClassFlowImage.h"
#include "ClassControllCamera.h"
#include
-static const char* TAG2 = "example";
-
#define BLINK_GPIO GPIO_NUM_4
#define CAMERA_MODEL_AI_THINKER
@@ -13,11 +11,9 @@ static const char* TAG2 = "example";
class ClassFlowMakeImage :
- public ClassFlow
+ public ClassFlowImage
{
protected:
- string LogImageLocation;
- bool isLogImage;
float waitbeforepicture;
framesize_t ImageSize;
bool isImageSize;
diff --git a/code/lib/jomjol_helper/Helper.cpp b/code/lib/jomjol_helper/Helper.cpp
index 4e7797ec..5ffd73e0 100644
--- a/code/lib/jomjol_helper/Helper.cpp
+++ b/code/lib/jomjol_helper/Helper.cpp
@@ -1,8 +1,14 @@
//#pragma warning(disable : 4996)
#include "Helper.h"
+#include
+#include
+#include
+#include
+#include
//#define ISWINDOWS_TRUE
+#define PATH_MAX_STRING_SIZE 256
using namespace std;
@@ -159,6 +165,63 @@ string getFileType(string filename)
return zw;
}
+/* recursive mkdir */
+int mkdir_r(const char *dir, const mode_t mode) {
+ char tmp[PATH_MAX_STRING_SIZE];
+ char *p = NULL;
+ struct stat sb;
+ size_t len;
+
+ /* copy path */
+ len = strnlen (dir, PATH_MAX_STRING_SIZE);
+ if (len == 0 || len == PATH_MAX_STRING_SIZE) {
+ return -1;
+ }
+ memcpy (tmp, dir, len);
+ tmp[len] = '\0';
+
+ /* remove trailing slash */
+ if(tmp[len - 1] == '/') {
+ tmp[len - 1] = '\0';
+ }
+
+ /* check if path exists and is a directory */
+ if (stat (tmp, &sb) == 0) {
+ if (S_ISDIR (sb.st_mode)) {
+ return 0;
+ }
+ }
+
+ /* recursive mkdir */
+ for(p = tmp + 1; *p; p++) {
+ if(*p == '/') {
+ *p = 0;
+ /* test path */
+ if (stat(tmp, &sb) != 0) {
+ /* path does not exist - create directory */
+ if (mkdir(tmp, mode) < 0) {
+ return -1;
+ }
+ } else if (!S_ISDIR(sb.st_mode)) {
+ /* not a directory */
+ return -1;
+ }
+ *p = '/';
+ }
+ }
+ /* test path */
+ if (stat(tmp, &sb) != 0) {
+ /* path does not exist - create directory */
+ if (mkdir(tmp, mode) < 0) {
+ return -1;
+ }
+ } else if (!S_ISDIR(sb.st_mode)) {
+ /* not a directory */
+ return -1;
+ }
+ return 0;
+}
+
string toUpper(string in)
{
for (int i = 0; i < in.length(); ++i)
@@ -173,3 +236,42 @@ float temperatureRead()
{
return (temprature_sens_read() - 32) / 1.8;
}
+
+time_t addDays(time_t startTime, int days) {
+ struct tm* tm = localtime(&startTime);
+ tm->tm_mday += days;
+ return mktime(tm);
+}
+
+int removeFolder(const char* folderPath, const char* logTag) {
+ ESP_LOGI(logTag, "Delete folder %s", folderPath);
+
+ DIR *dir = opendir(folderPath);
+ if (!dir) {
+ ESP_LOGI(logTag, "Failed to stat dir : %s", folderPath);
+ return -1;
+ }
+
+ struct dirent *entry;
+ int deleted = 0;
+ while ((entry = readdir(dir)) != NULL) {
+ std::string path = string(folderPath) + "/" + entry->d_name;
+ if (entry->d_type == DT_REG) {
+ if (unlink(path.c_str()) == 0) {
+ deleted ++;
+ } else {
+ ESP_LOGE(logTag, "can't delete file : %s", path.c_str());
+ }
+ } else if (entry->d_type == DT_DIR) {
+ deleted += removeFolder(path.c_str(), logTag);
+ }
+ }
+
+ closedir(dir);
+ if (rmdir(folderPath) != 0) {
+ ESP_LOGE(logTag, "can't delete file : %s", folderPath);
+ }
+ ESP_LOGI(logTag, "%d older log files in folder %s deleted.", deleted, folderPath);
+
+ return deleted;
+}
diff --git a/code/lib/jomjol_helper/Helper.h b/code/lib/jomjol_helper/Helper.h
index ce2f4e32..7891263c 100644
--- a/code/lib/jomjol_helper/Helper.h
+++ b/code/lib/jomjol_helper/Helper.h
@@ -17,6 +17,11 @@ bool ctype_space(const char c, string adddelimiter);
string getFileType(string filename);
+int mkdir_r(const char *dir, const mode_t mode);
+int removeFolder(const char* folderPath, const char* logTag);
+
string toUpper(string in);
float temperatureRead();
+
+time_t addDays(time_t startTime, int days);
diff --git a/code/lib/jomjol_logfile/ClassLogFile.cpp b/code/lib/jomjol_logfile/ClassLogFile.cpp
index 11a168a6..ccb75cf0 100644
--- a/code/lib/jomjol_logfile/ClassLogFile.cpp
+++ b/code/lib/jomjol_logfile/ClassLogFile.cpp
@@ -1,7 +1,14 @@
#include "ClassLogFile.h"
#include "time_sntp.h"
+#include
+#include
+#include
+#include
+#include "Helper.h"
-ClassLogFile LogFile("/sdcard/log.txt");
+static const char *TAG = "log";
+
+ClassLogFile LogFile("/sdcard/log/message", "log_%Y-%m-%d.txt");
void ClassLogFile::WriteToDedicatedFile(std::string _fn, std::string info, bool _time)
{
@@ -13,39 +20,111 @@ void ClassLogFile::WriteToDedicatedFile(std::string _fn, std::string info, bool
}
pFile = fopen(_fn.c_str(), "a+");
+ if (pFile!=NULL) {
+ if (_time)
+ {
+ time_t rawtime;
+ struct tm* timeinfo;
+ char buffer[80];
- if (_time)
- {
- time_t rawtime;
- struct tm* timeinfo;
- char buffer[80];
+ time(&rawtime);
+ timeinfo = localtime(&rawtime);
- time(&rawtime);
- timeinfo = localtime(&rawtime);
+ strftime(buffer, 80, "%Y-%m-%d_%H-%M-%S", timeinfo);
- strftime(buffer, 80, "%Y-%m-%d_%H-%M-%S", timeinfo);
+ zwtime = std::string(buffer);
+ info = zwtime + ": " + info;
+ }
+ fputs(info.c_str(), pFile);
+ fputs("\n", pFile);
- zwtime = std::string(buffer);
- info = zwtime + ": " + info;
+ fclose(pFile);
+ } else {
+ ESP_LOGI(TAG, "Can't open log file %s", _fn.c_str());
}
- fputs(info.c_str(), pFile);
- fputs("\n", pFile);
-
- fclose(pFile);
}
void ClassLogFile::SwitchOnOff(bool _doLogFile){
doLogFile = _doLogFile;
};
+void ClassLogFile::SetRetention(unsigned short _retentionInDays){
+ retentionInDays = _retentionInDays;
+};
void ClassLogFile::WriteToFile(std::string info, bool _time)
{
- WriteToDedicatedFile(logfile, info, _time);
+ struct stat path_stat;
+ if (stat(logroot.c_str(), &path_stat) != 0) {
+ ESP_LOGI(TAG, "Create log folder: %s", logroot.c_str());
+ if (mkdir_r(logroot.c_str(), S_IRWXU) == -1) {
+ ESP_LOGI(TAG, "Can't create log foolder");
+ }
+ }
+
+ time_t rawtime;
+ struct tm* timeinfo;
+ char buffer[30];
+
+ time(&rawtime);
+ timeinfo = localtime(&rawtime);
+
+ strftime(buffer, 30, logfile.c_str(), timeinfo);
+ std::string logpath = logroot + "/" + buffer;
+
+ WriteToDedicatedFile(logpath, info, _time);
}
-ClassLogFile::ClassLogFile(std::string _logfile)
+void ClassLogFile::RemoveOld()
{
- logfile = _logfile;
+ if (retentionInDays == 0) {
+ return;
+ }
+
+ time_t rawtime;
+ struct tm* timeinfo;
+ char cmpfilename[30];
+
+ time(&rawtime);
+ rawtime = addDays(rawtime, -retentionInDays);
+ timeinfo = localtime(&rawtime);
+
+ strftime(cmpfilename, 30, logfile.c_str(), timeinfo);
+ //ESP_LOGE(TAG, "log file name to compare: %s", cmpfilename);
+
+ DIR *dir = opendir(logroot.c_str());
+ if (!dir) {
+ ESP_LOGI(TAG, "Failed to stat dir : %s", logroot.c_str());
+ return;
+ }
+
+ struct dirent *entry;
+ int deleted = 0;
+ int notDeleted = 0;
+ while ((entry = readdir(dir)) != NULL) {
+ if (entry->d_type == DT_REG) {
+ //ESP_LOGI(TAG, "list log file : %s %s", entry->d_name, cmpfilename);
+ if ((strlen(entry->d_name) == strlen(cmpfilename)) && (strcmp(entry->d_name, cmpfilename) < 0)) {
+ ESP_LOGI(TAG, "delete log file : %s", entry->d_name);
+ std::string filepath = logroot + "/" + entry->d_name;
+ if (unlink(filepath.c_str()) == 0) {
+ deleted ++;
+ } else {
+ ESP_LOGE(TAG, "can't delete file : %s", entry->d_name);
+ }
+ } else {
+ notDeleted ++;
+ }
+ }
+ }
+ ESP_LOGI(TAG, "%d older log files deleted. %d current log files not deleted.", deleted, notDeleted);
+ closedir(dir);
+}
+
+ClassLogFile::ClassLogFile(std::string _logroot, std::string _logfile)
+{
+ logroot = _logroot;
+ logfile = _logfile;
doLogFile = true;
-}
\ No newline at end of file
+ retentionInDays = 10;
+}
diff --git a/code/lib/jomjol_logfile/ClassLogFile.h b/code/lib/jomjol_logfile/ClassLogFile.h
index fcb37ea1..5915c329 100644
--- a/code/lib/jomjol_logfile/ClassLogFile.h
+++ b/code/lib/jomjol_logfile/ClassLogFile.h
@@ -5,15 +5,19 @@
class ClassLogFile
{
private:
+ std::string logroot;
std::string logfile;
bool doLogFile;
+ unsigned short retentionInDays;
public:
- ClassLogFile(std::string _logfile);
+ ClassLogFile(std::string _logpath, std::string _logfile);
void SwitchOnOff(bool _doLogFile);
+ void SetRetention(unsigned short _retentionInDays);
void WriteToFile(std::string info, bool _time = true);
void WriteToDedicatedFile(std::string _fn, std::string info, bool _time = true);
+ void RemoveOld();
};
extern ClassLogFile LogFile;
\ No newline at end of file
diff --git a/code/lib/jomjol_time_sntp/time_sntp.cpp b/code/lib/jomjol_time_sntp/time_sntp.cpp
index 92dd1876..6c8b9047 100644
--- a/code/lib/jomjol_time_sntp/time_sntp.cpp
+++ b/code/lib/jomjol_time_sntp/time_sntp.cpp
@@ -124,4 +124,4 @@ static void initialize_sntp(void)
sntp_setservername(0, "pool.ntp.org");
sntp_set_time_sync_notification_cb(time_sync_notification_cb);
sntp_init();
-}
\ No newline at end of file
+}
diff --git a/code/src/server_main.h b/code/src/server_main.h
index 83471970..16a851ed 100644
--- a/code/src/server_main.h
+++ b/code/src/server_main.h
@@ -14,7 +14,7 @@
#include
-static const char *TAG = "example";
+static const char *TAG = "server-main";
extern httpd_handle_t server;
diff --git a/code/src/server_tflite.cpp b/code/src/server_tflite.cpp
index f5e2d5e0..b579ac59 100644
--- a/code/src/server_tflite.cpp
+++ b/code/src/server_tflite.cpp
@@ -58,7 +58,8 @@ void doInit(void)
bool doflow(void)
{
- std::string zw_time = gettimestring("%Y%m%d-%H%M%S");
+
+ std::string zw_time = gettimestring(LOGFILE_TIME_FORMAT);
printf("doflow - start %s\n", zw_time.c_str());
flowisrunning = true;
tfliteflow.doFlow(zw_time);
@@ -433,6 +434,8 @@ void task_autodoFlow(void *pvParameter)
printf("Autoflow: doFLow wird gestartet\n");
flowisrunning = true;
doflow();
+ printf("Remove older log files\n");
+ LogFile.RemoveOld();
}
LogFile.WriteToFile("task_autodoFlow - round done");
diff --git a/code/src/version.cpp b/code/src/version.cpp
index b8bd5180..5cea5ac3 100644
--- a/code/src/version.cpp
+++ b/code/src/version.cpp
@@ -1,4 +1,4 @@
const char* GIT_REV="05a0f6f";
const char* GIT_TAG="";
const char* GIT_BRANCH="update_tflite";
-const char* BUILD_TIME="2020-11-08 03:06";
\ No newline at end of file
+const char* BUILD_TIME="2020-11-08 03:06";
diff --git a/code/version.cpp b/code/version.cpp
index b8bd5180..5cea5ac3 100644
--- a/code/version.cpp
+++ b/code/version.cpp
@@ -1,4 +1,4 @@
const char* GIT_REV="05a0f6f";
const char* GIT_TAG="";
const char* GIT_BRANCH="update_tflite";
-const char* BUILD_TIME="2020-11-08 03:06";
\ No newline at end of file
+const char* BUILD_TIME="2020-11-08 03:06";
diff --git a/sd-card/config/config.ini b/sd-card/config/config.ini
index 64219ec0..df9ba8a8 100644
--- a/sd-card/config/config.ini
+++ b/sd-card/config/config.ini
@@ -1,5 +1,6 @@
[MakeImage]
;LogImageLocation = /log/source
+;LogfileRetentionInDays = 15
WaitBeforeTakingPicture=5
ImageQuality = 5
ImageSize = VGA
@@ -15,6 +16,7 @@ SearchFieldY = 20
[Digits]
Model=/config/dig0650s3.tflite
LogImageLocation = /log/digit
+LogfileRetentionInDays = 15
ModelInputSize 20, 32
digit1, 306, 120, 37, 67
digit2, 355, 120, 37, 67
@@ -23,6 +25,7 @@ digit3, 404, 120, 37, 67
[Analog]
Model=/config/ana0630s2.tflite
LogImageLocation = /log/analog
+LogfileRetentionInDays = 15
ModelInputSize 32, 32
analog1, 444, 225, 92, 92
analog2, 391, 329, 92, 92
@@ -51,5 +54,7 @@ Intervall = 4.85
[Debug]
Logfile = False
+; Number of days before a log file is deleted. 0 = disabled. 10 is default value (if not defined)
+;LogfileRetentionInDays = 10
[Ende]
\ No newline at end of file
diff --git a/sd-card/html/index.html b/sd-card/html/index.html
index 36e2fa78..78e55a9d 100644
--- a/sd-card/html/index.html
+++ b/sd-card/html/index.html
@@ -91,7 +91,7 @@ li.dropdown {
System