diff --git a/README.md b/README.md index 6f7edf21..0a0006c5 100644 --- a/README.md +++ b/README.md @@ -27,9 +27,15 @@ A 3d-printable housing can be found here: https://www.thingiverse.com/thing:4571 -##### Rolling - (2020-11-29) +##### Rolling - (2020-11-30) +* New feature: time zone can be specified, regular time synchronization possible (see new section `[System]` in configuration) + +2020-11-29 + +* New feature: errors message can be reported in a separate tag in the MQTT Adapter (parameter: `TopicError`) * New html interface for modification of configuration parameters (access to direct edit of `config.ini` moved to new expert mode) +* Bug fixing: wrong truncation of checked value, in case no analog counter present * Preparation for feature implementation 2020-11-26 diff --git a/code/components/jomjol_flowcontroll/ClassFlow.cpp b/code/components/jomjol_flowcontroll/ClassFlow.cpp index a378c2fb..5913d304 100644 --- a/code/components/jomjol_flowcontroll/ClassFlow.cpp +++ b/code/components/jomjol_flowcontroll/ClassFlow.cpp @@ -11,10 +11,12 @@ void ClassFlow::SetInitialParameter(void) ListFlowControll = NULL; } -std::vector ClassFlow::ZerlegeZeile(std::string input) +//std::vector ClassFlow::ZerlegeZeile(std::string input, std::string delimiter); + +std::vector ClassFlow::ZerlegeZeile(std::string input, std::string delimiter) { std::vector Output; - std::string delimiter = " =,"; +// std::string delimiter = " =,"; input = trim(input, delimiter); size_t pos = findDelimiterPos(input, delimiter); diff --git a/code/components/jomjol_flowcontroll/ClassFlow.h b/code/components/jomjol_flowcontroll/ClassFlow.h index 18260229..11a5b25d 100644 --- a/code/components/jomjol_flowcontroll/ClassFlow.h +++ b/code/components/jomjol_flowcontroll/ClassFlow.h @@ -23,7 +23,8 @@ struct HTMLInfo class ClassFlow { protected: - std::vector ZerlegeZeile(string input); +// std::vector ZerlegeZeile(string input); + std::vector ZerlegeZeile(string input, string delimiter = " =, "); bool isNewParagraph(string input); bool GetNextParagraph(FILE* pfile, string& aktparamgraph); bool getNextLine(FILE* pfile, string* rt); diff --git a/code/components/jomjol_flowcontroll/ClassFlowControll.cpp b/code/components/jomjol_flowcontroll/ClassFlowControll.cpp index a50de987..68f3dce6 100644 --- a/code/components/jomjol_flowcontroll/ClassFlowControll.cpp +++ b/code/components/jomjol_flowcontroll/ClassFlowControll.cpp @@ -1,5 +1,7 @@ #include "ClassFlowControll.h" +#include "freertos/task.h" + #include #include #include "ClassLogFile.h" @@ -104,6 +106,9 @@ ClassFlow* ClassFlowControll::CreateClassFlow(std::string _type) if (toUpper(_type).compare("[DEBUG]") == 0) cfc = this; + if (toUpper(_type).compare("[SYSTEM]") == 0) + cfc = this; + return cfc; } @@ -259,12 +264,12 @@ bool ClassFlowControll::ReadParameter(FILE* pfile, string& aktparamgraph) return false; - if ((toUpper(aktparamgraph).compare("[AUTOTIMER]") != 0) && (toUpper(aktparamgraph).compare("[DEBUG]") != 0)) // Paragraph passt nicht zu MakeImage + if ((toUpper(aktparamgraph).compare("[AUTOTIMER]") != 0) && (toUpper(aktparamgraph).compare("[DEBUG]") != 0) && (toUpper(aktparamgraph).compare("[SYSTEM]") != 0)) // Paragraph passt nicht zu MakeImage return false; while (this->getNextLine(pfile, &aktparamgraph) && !this->isNewParagraph(aktparamgraph)) { - zerlegt = this->ZerlegeZeile(aktparamgraph); + zerlegt = this->ZerlegeZeile(aktparamgraph, " ="); if ((toUpper(zerlegt[0]) == "AUTOSTART") && (zerlegt.size() > 1)) { if (toUpper(zerlegt[1]) == "TRUE") @@ -291,6 +296,19 @@ bool ClassFlowControll::ReadParameter(FILE* pfile, string& aktparamgraph) { LogFile.SetRetention(std::stoi(zerlegt[1])); } + + if ((toUpper(zerlegt[0]) == "TIMEZONE") && (zerlegt.size() > 1)) + { + string zw = "Set TimeZone: " + zerlegt[1]; + setTimeZone(zerlegt[1]); + } + + if ((toUpper(zerlegt[0]) == "TIMEUPDATEINTERVALL") && (zerlegt.size() > 1)) + { + TimeUpdateIntervall = stof(zerlegt[1]); + xTaskCreate(&task_doTimeSync, "update_time", configMINIMAL_STACK_SIZE * 16, &TimeUpdateIntervall, tskIDLE_PRIORITY, NULL); + } + } return true; } diff --git a/code/components/jomjol_flowcontroll/ClassFlowControll.h b/code/components/jomjol_flowcontroll/ClassFlowControll.h index 91eac5fa..aceb79cc 100644 --- a/code/components/jomjol_flowcontroll/ClassFlowControll.h +++ b/code/components/jomjol_flowcontroll/ClassFlowControll.h @@ -23,6 +23,7 @@ protected: float AutoIntervall; void SetInitialParameter(void); std::string aktstatus; + int TimeUpdateIntervall; public: diff --git a/code/components/jomjol_flowcontroll/ClassFlowMQTT.cpp b/code/components/jomjol_flowcontroll/ClassFlowMQTT.cpp index 92396e2b..4d6a9fb1 100644 --- a/code/components/jomjol_flowcontroll/ClassFlowMQTT.cpp +++ b/code/components/jomjol_flowcontroll/ClassFlowMQTT.cpp @@ -10,6 +10,7 @@ ClassFlowMQTT::ClassFlowMQTT() { uri = ""; topic = ""; + topicError = ""; clientname = "watermeter"; OldValue = ""; flowpostprocessing = NULL; @@ -21,6 +22,7 @@ ClassFlowMQTT::ClassFlowMQTT(std::vector* lfc) { uri = ""; topic = ""; + topicError = ""; clientname = "watermeter"; OldValue = ""; flowpostprocessing = NULL; @@ -71,6 +73,10 @@ bool ClassFlowMQTT::ReadParameter(FILE* pfile, string& aktparamgraph) { this->topic = zerlegt[1]; } + if ((toUpper(zerlegt[0]) == "TOPICERROR") && (zerlegt.size() > 1)) + { + this->topicError = zerlegt[1]; + } if ((toUpper(zerlegt[0]) == "CLIENTID") && (zerlegt.size() > 1)) { this->clientname = zerlegt[1]; @@ -90,11 +96,13 @@ bool ClassFlowMQTT::ReadParameter(FILE* pfile, string& aktparamgraph) bool ClassFlowMQTT::doFlow(string zwtime) { std::string result; + std::string resulterror = ""; string zw = ""; if (flowpostprocessing) { result = flowpostprocessing->getReadoutParam(false, true); + resulterror = flowpostprocessing->getReadoutError(); } else { @@ -110,9 +118,13 @@ bool ClassFlowMQTT::doFlow(string zwtime) } } } - + MQTTPublish(topic, result); + if (topicError.length() > 0) { + MQTTPublish(topicError, resulterror); + } + OldValue = result; diff --git a/code/components/jomjol_flowcontroll/ClassFlowMQTT.h b/code/components/jomjol_flowcontroll/ClassFlowMQTT.h index a22173ef..48e93f0f 100644 --- a/code/components/jomjol_flowcontroll/ClassFlowMQTT.h +++ b/code/components/jomjol_flowcontroll/ClassFlowMQTT.h @@ -9,7 +9,7 @@ class ClassFlowMQTT : public ClassFlow { protected: - std::string uri, topic, clientname; + std::string uri, topic, topicError, clientname; std::string OldValue; ClassFlowPostProcessing* flowpostprocessing; std::string user, password; diff --git a/code/components/jomjol_flowcontroll/ClassFlowPostProcessing.cpp b/code/components/jomjol_flowcontroll/ClassFlowPostProcessing.cpp index 0c4dc37f..a19f0fe5 100644 --- a/code/components/jomjol_flowcontroll/ClassFlowPostProcessing.cpp +++ b/code/components/jomjol_flowcontroll/ClassFlowPostProcessing.cpp @@ -13,7 +13,7 @@ string ClassFlowPostProcessing::GetPreValue() { std::string result; - result = to_string(PreValue); + result = RundeOutput(PreValue, -DecimalShift); for (int i = 0; i < ListFlowControll->size(); ++i) { @@ -130,6 +130,7 @@ ClassFlowPostProcessing::ClassFlowPostProcessing() useMaxRateValue = false; checkDigitIncreaseConsistency = false; DecimalShift = 0; + ErrorMessageText = ""; FilePreValue = FormatFileName("/sdcard/config/prevalue.ini"); } @@ -145,6 +146,7 @@ ClassFlowPostProcessing::ClassFlowPostProcessing(std::vector* lfc) useMaxRateValue = false; checkDigitIncreaseConsistency = false; DecimalShift = 0; + ErrorMessageText = ""; FilePreValue = FormatFileName("/sdcard/config/prevalue.ini"); ListFlowControll = lfc; } @@ -263,9 +265,10 @@ bool ClassFlowPostProcessing::doFlow(string zwtime) bool isanalog = false; int AnzahlAnalog = 0; string zw; - string error = ""; time_t imagetime = 0; + ErrorMessageText = ""; + for (int i = 0; i < ListFlowControll->size(); ++i) { if (((*ListFlowControll)[i])->name().compare("ClassFlowMakeImage") == 0) @@ -344,24 +347,24 @@ bool ClassFlowPostProcessing::doFlow(string zwtime) if ((!AllowNegativeRates) && (Value < PreValue)) { - error = error + "Negative Rate - Returned old value - read value: " + zwvalue + " "; + ErrorMessageText = ErrorMessageText + "Negative Rate - Returned old value - read value: " + zwvalue + " "; Value = PreValue; zwvalue = RundeOutput(Value, AnzahlAnalog - DecimalShift); } if (useMaxRateValue && (abs(Value - PreValue) > MaxRateValue)) { - error = error + "Rate too high - Returned old value - read value: " + zwvalue + " "; + ErrorMessageText = ErrorMessageText + "Rate too high - Returned old value - read value: " + zwvalue + " "; Value = PreValue; zwvalue = RundeOutput(Value, AnzahlAnalog - DecimalShift); } ReturnValueNoError = zwvalue; ReturnValue = zwvalue; - if (ErrorMessage && (error.length() > 0)) - ReturnValue = ReturnValue + "\t" + error; + if (ErrorMessage && (ErrorMessageText.length() > 0)) + ReturnValue = ReturnValue + "\t" + ErrorMessageText; - if (error.length() == 0) + if (ErrorMessageText.length() == 0) { PreValue = Value; SavePreValue(Value, zwtime); @@ -471,3 +474,9 @@ float ClassFlowPostProcessing::checkDigitConsistency(float input, int _decilamsh return input; } + + +string ClassFlowPostProcessing::getReadoutError() +{ + return ErrorMessageText; +} diff --git a/code/components/jomjol_flowcontroll/ClassFlowPostProcessing.h b/code/components/jomjol_flowcontroll/ClassFlowPostProcessing.h index b9e74b9e..c9251350 100644 --- a/code/components/jomjol_flowcontroll/ClassFlowPostProcessing.h +++ b/code/components/jomjol_flowcontroll/ClassFlowPostProcessing.h @@ -24,6 +24,7 @@ protected: string ReturnRawValue; // Rohwert (mit N & führenden 0) string ReturnValue; // korrigierter Rückgabewert, ggf. mit Fehlermeldung string ReturnValueNoError; // korrigierter Rückgabewert ohne Fehlermeldung + string ErrorMessageText; // Fehlermeldung bei Consistency Check bool LoadPreValue(void); string ShiftDecimal(string in, int _decShift); @@ -39,6 +40,7 @@ public: bool doFlow(string time); string getReadout(); string getReadoutParam(bool _rawValue, bool _noerror); + string getReadoutError(); void SavePreValue(float value, string time = ""); string GetPreValue(); diff --git a/code/components/jomjol_time_sntp/CMakeLists.txt b/code/components/jomjol_time_sntp/CMakeLists.txt index bd92d82d..948e3829 100644 --- a/code/components/jomjol_time_sntp/CMakeLists.txt +++ b/code/components/jomjol_time_sntp/CMakeLists.txt @@ -2,6 +2,6 @@ FILE(GLOB_RECURSE app_sources ${CMAKE_CURRENT_SOURCE_DIR}/*.*) idf_component_register(SRCS ${app_sources} INCLUDE_DIRS "." - REQUIRES tfmicro) + REQUIRES tfmicro jomjol_logfile) diff --git a/code/components/jomjol_time_sntp/time_sntp.cpp b/code/components/jomjol_time_sntp/time_sntp.cpp index dddfe680..4ea55dfe 100644 --- a/code/components/jomjol_time_sntp/time_sntp.cpp +++ b/code/components/jomjol_time_sntp/time_sntp.cpp @@ -21,6 +21,8 @@ // #include "protocol_examples_common.h" #include "esp_sntp.h" +#include "ClassLogFile.h" + static const char *TAG = "sntp"; RTC_DATA_ATTR int boot_count = 0; @@ -56,8 +58,8 @@ std::string gettimestring(const char * frm) } char strftime_buf[64]; - setenv("TZ", "UTC-2", 1); - tzset(); +// setenv("TZ", "UTC-2", 1); +// tzset(); localtime_r(&now, &timeinfo); strftime(strftime_buf, sizeof(strftime_buf), frm, &timeinfo); @@ -65,7 +67,7 @@ std::string gettimestring(const char * frm) return result; } -void setup_time(void) +void setup_time() { ++boot_count; ESP_LOGI(TAG, "Boot count: %d", boot_count); @@ -84,10 +86,10 @@ void setup_time(void) } char strftime_buf[64]; - // Set timezone to Berlin Standard Time - setenv("TZ", "UTC+9", 1); -// setenv("TZ", "Europe/Berlin", 1); - tzset(); + setTimeZone("CET-1CEST,M3.5.0,M10.5.0/3"); +// setTimeZone("Europe/Berlin"); +// setTimeZone("Asia/Tokyo"); + localtime_r(&now, &timeinfo); strftime(strftime_buf, sizeof(strftime_buf), "%c", &timeinfo); ESP_LOGI(TAG, "The current date/time in Berlin is: %s", strftime_buf); @@ -96,14 +98,22 @@ void setup_time(void) ESP_LOGI(TAG, "The current date/time in Berlin is: %s", strftime_buf); std::string zw = gettimestring("%Y%m%d-%H%M%S"); - printf("time %s\n", zw.c_str()); + printf("timeist %s\n", zw.c_str()); } +void setTimeZone(std::string _tzstring) +{ + setenv("TZ", _tzstring.c_str(), 1); + tzset(); + printf("TimeZone set to %s\n", _tzstring.c_str()); + _tzstring = "Time zone set to " + _tzstring; + LogFile.WriteToFile(_tzstring); +} static void obtain_time(void) { // initialize_sntp(); - + // wait for time to be set time_t now = 0; struct tm timeinfo = {}; @@ -113,6 +123,14 @@ static void obtain_time(void) ESP_LOGI(TAG, "Waiting for system time to be set... (%d/%d)", retry, retry_count); vTaskDelay(2000 / portTICK_PERIOD_MS); } + if (retry == retry_count) { + LogFile.WriteToFile("Time Synchzronisation nicht erfolgreich ..."); + } + else + { + LogFile.WriteToFile("Time erfolgreich ..."); + } + time(&now); localtime_r(&now, &timeinfo); } @@ -125,3 +143,32 @@ static void initialize_sntp(void) sntp_set_time_sync_notification_cb(time_sync_notification_cb); sntp_init(); } + + +void task_doTimeSync(void *pvParameter) +{ + time_t now; + struct tm timeinfo; + char strftime_buf[64]; + int *zw_int = (int*) pvParameter; + + printf("Start Autoupdate Time every: %d Stunden\n", *zw_int ); + TickType_t xDelay = ((*zw_int) * 60 * 60 * 1000) / portTICK_PERIOD_MS; + + while (1) + { + obtain_time(); + localtime_r(&now, &timeinfo); + strftime(strftime_buf, sizeof(strftime_buf), "%c", &timeinfo); + ESP_LOGI(TAG, "The current date/time in Berlin is: %s", strftime_buf); + + strftime(strftime_buf, sizeof(strftime_buf), "%Y-%m-%d_%H:%M", &timeinfo); + ESP_LOGI(TAG, "The current date/time in Berlin is: %s", strftime_buf); + + std::string zw = gettimestring("%Y%m%d-%H%M%S"); + printf("time %s\n", zw.c_str()); + + vTaskDelay( xDelay ); + } + vTaskDelete(NULL); //Delete this task if it exits from the loop above +} \ No newline at end of file diff --git a/code/components/jomjol_time_sntp/time_sntp.h b/code/components/jomjol_time_sntp/time_sntp.h index 978f3917..62847c97 100644 --- a/code/components/jomjol_time_sntp/time_sntp.h +++ b/code/components/jomjol_time_sntp/time_sntp.h @@ -17,4 +17,6 @@ extern int boot_count; void setup_time(void); -std::string gettimestring(const char * frm); \ No newline at end of file +std::string gettimestring(const char * frm); +void task_doTimeSync(void *pvParameter); +void setTimeZone(std::string _tzstring); \ No newline at end of file diff --git a/code/src/version.cpp b/code/src/version.cpp index d8d8b6aa..b1b2a8eb 100644 --- a/code/src/version.cpp +++ b/code/src/version.cpp @@ -1,4 +1,4 @@ -const char* GIT_REV="891adf3"; +const char* GIT_REV="1b5f6b4"; const char* GIT_TAG=""; const char* GIT_BRANCH="rolling"; -const char* BUILD_TIME="2020-11-29 15:14"; \ No newline at end of file +const char* BUILD_TIME="2020-11-30 12:06"; \ No newline at end of file diff --git a/code/version.cpp b/code/version.cpp index d8d8b6aa..b1b2a8eb 100644 --- a/code/version.cpp +++ b/code/version.cpp @@ -1,4 +1,4 @@ -const char* GIT_REV="891adf3"; +const char* GIT_REV="1b5f6b4"; const char* GIT_TAG=""; const char* GIT_BRANCH="rolling"; -const char* BUILD_TIME="2020-11-29 15:14"; \ No newline at end of file +const char* BUILD_TIME="2020-11-30 12:06"; \ No newline at end of file diff --git a/firmware/bootloader.bin b/firmware/bootloader.bin index 0b2913ea..219eae7c 100644 Binary files a/firmware/bootloader.bin and b/firmware/bootloader.bin differ diff --git a/firmware/firmware.bin b/firmware/firmware.bin index e04e2071..ce12ccce 100644 Binary files a/firmware/firmware.bin and b/firmware/firmware.bin differ diff --git a/firmware/html.zip b/firmware/html.zip index 126ae829..8e2ee694 100644 Binary files a/firmware/html.zip and b/firmware/html.zip differ diff --git a/sd-card/config/config.ini b/sd-card/config/config.ini index 3c8c5bf3..7df6ec31 100644 --- a/sd-card/config/config.ini +++ b/sd-card/config/config.ini @@ -1,7 +1,7 @@ [MakeImage] ;LogImageLocation = /log/source ;LogfileRetentionInDays = 15 -WaitBeforeTakingPicture=5 +WaitBeforeTakingPicture = 5 ImageQuality = 5 ImageSize = VGA @@ -14,19 +14,19 @@ SearchFieldY = 20 [Digits] -Model=/config/dig0710s3.tflite -LogImageLocation = /log/digit -LogfileRetentionInDays = 15 -ModelInputSize 20, 32 +Model = /config/dig0720s1.tflite +;LogImageLocation = /log/digit +;LogfileRetentionInDays = 3 +ModelInputSize = 20 32 digit1, 306, 120, 37, 67 digit2, 355, 120, 37, 67 digit3, 404, 120, 37, 67 [Analog] -Model=/config/ana0630s2.tflite -LogImageLocation = /log/analog -LogfileRetentionInDays = 15 -ModelInputSize 32, 32 +Model = /config/ana0630s2.tflite +;LogImageLocation = /log/analog +;LogfileRetentionInDays = 3 +ModelInputSize = 32 32 analog1, 444, 225, 92, 92 analog2, 391, 329, 92, 92 analog3, 294, 369, 92, 92 @@ -39,22 +39,25 @@ PreValueAgeStartup = 720 AllowNegativeRates = False MaxRateValue = 0.1 ErrorMessage = True -CheckDigitIncreaseConsistency = False +CheckDigitIncreaseConsistency = True -;[MQTT] -;Uri = mqtt://IP-MQTT-SERVER:1883 -;Topic = watermeter/readout +[MQTT] +;Uri = mqtt://IP-ADRESS:1883 +;Topic = wasserzaehler/zaehlerstand +;TopicError = wasserzaehler/error ;ClientID = wasser ;user = USERNAME ;password = PASSWORD [AutoTimer] -AutoStart= True +AutoStart = True 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 +LogfileRetentionInDays = 3 + +[System] +TimeZone = CET-1CEST,M3.5.0,M10.5.0/3 [Ende] \ No newline at end of file diff --git a/sd-card/config/prevalue.ini b/sd-card/config/prevalue.ini new file mode 100644 index 00000000..0e7aedf5 --- /dev/null +++ b/sd-card/config/prevalue.ini @@ -0,0 +1,2 @@ +2020-11-30_12-02-22 +42.013401 diff --git a/sd-card/html/edit_config_param.html b/sd-card/html/edit_config_param.html index fa90c8f5..b07c82d0 100644 --- a/sd-card/html/edit_config_param.html +++ b/sd-card/html/edit_config_param.html @@ -561,27 +561,10 @@ textarea { TimeZone - + - Adjustment of time zone relative to UTC (in hours) - - - - - - - - AutoAdjustSummertime - - - - - - Autoadjust the summertime + Time zone in POSIX syntax (Europe/Berlin = "CET-1CEST,M3.5.0,M10.5.0/3" - incl. daylight saving) @@ -726,10 +709,7 @@ function UpdateInput() { WriteParameter(param, "Debug", "LogfileRetentionInDays", true); WriteParameter(param, "System", "TimeZone", true); - WriteParameter(param, "System", "AutoAdjustSummertime", true, true); WriteParameter(param, "System", "TimeUpdateIntervall", true); - - } function WriteConfig(){ @@ -774,10 +754,7 @@ function WriteConfig(){ ReadParameter(param, "Debug", "LogfileRetentionInDays", true); ReadParameter(param, "System", "TimeZone", true); - ReadParameter(param, "System", "AutoAdjustSummertime", true, true); ReadParameter(param, "System", "TimeUpdateIntervall", true); - - FormatDecimalValue(param, "PostProcessing", "MaxRateValue"); diff --git a/sd-card/html/readconfigparam.js b/sd-card/html/readconfigparam.js index 6092b9c8..e853443e 100644 --- a/sd-card/html/readconfigparam.js +++ b/sd-card/html/readconfigparam.js @@ -145,7 +145,7 @@ function ParseConfigParamSystem(_aktline){ while ((akt_ref < 2) && (_aktline < config_split.length) && (config_split[_aktline][0] != "[")) { var _input = config_split[_aktline]; let [isCom, input] = isCommented(_input); - var linesplit = ZerlegeZeile(input); + var linesplit = ZerlegeZeile(input, " ="); ParamExtractValue(param, linesplit, catname, "TimeZone", _aktline, isCom); ParamExtractValue(param, linesplit, catname, "AutoAdjustSummertime", _aktline, isCom); @@ -412,10 +412,10 @@ function createReader(file) { reader.readAsDataURL(file); } -function ZerlegeZeile(input) +function ZerlegeZeile(input, delimiter = " =,") { var Output = Array(0); - delimiter = " =,"; +// delimiter = " =,"; input = trim(input, delimiter); var pos = findDelimiterPos(input, delimiter);