From e39718a21a71cbaeafc0b4f6fb4b92eaa11b20e6 Mon Sep 17 00:00:00 2001 From: michael Date: Sun, 18 Jan 2026 01:02:02 +0100 Subject: [PATCH] test2 --- .../ClassFlowDefineTypes.h | 4 +- .../ClassFlowPostProcessing.cpp | 153 ++++++++++-------- param-docs/expert-params.txt | 3 +- .../{ErrorMessage.md => SkipErrorMessage.md} | 4 +- sd-card/config/config.ini | 5 +- sd-card/html/edit_config_template.html | 10 +- sd-card/html/readconfigparam.js | 2 +- 7 files changed, 103 insertions(+), 78 deletions(-) rename param-docs/parameter-pages/PostProcessing/{ErrorMessage.md => SkipErrorMessage.md} (82%) diff --git a/code/components/jomjol_flowcontroll/ClassFlowDefineTypes.h b/code/components/jomjol_flowcontroll/ClassFlowDefineTypes.h index 517dd491..8d9d3cd5 100644 --- a/code/components/jomjol_flowcontroll/ClassFlowDefineTypes.h +++ b/code/components/jomjol_flowcontroll/ClassFlowDefineTypes.h @@ -41,9 +41,8 @@ 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 PreValueValid; // 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 @@ -58,6 +57,7 @@ struct NumberPost 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 + bool ErrorMessage; // 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 diff --git a/code/components/jomjol_flowcontroll/ClassFlowPostProcessing.cpp b/code/components/jomjol_flowcontroll/ClassFlowPostProcessing.cpp index 85ccf984..4fab3aad 100644 --- a/code/components/jomjol_flowcontroll/ClassFlowPostProcessing.cpp +++ b/code/components/jomjol_flowcontroll/ClassFlowPostProcessing.cpp @@ -13,7 +13,7 @@ #include "Helper.h" #include "time_sntp.h" -static const char *TAG = "POSTPROCESS"; +static const char *TAG = "POSTPROC"; std::string ClassFlowPostProcessing::getNumbersName() { @@ -141,7 +141,7 @@ bool ClassFlowPostProcessing::SetPreValue(double _newvalue, std::string _numbers } NUMBERS[j]->ReturnPreValue = std::to_string(NUMBERS[j]->PreValue); - NUMBERS[j]->PreValueOkay = true; + NUMBERS[j]->PreValueValid = true; if (_extern) { @@ -149,8 +149,6 @@ bool ClassFlowPostProcessing::SetPreValue(double _newvalue, std::string _numbers localtime(&(NUMBERS[j]->timeStampLastPreValue)); } - // ESP_LOGD(TAG, "Found %d! - set to %.8f", j, NUMBERS[j]->PreValue); - UpdatePreValueINI = true; // Only update prevalue file if a new value is set SavePreValue(); @@ -228,11 +226,11 @@ bool ClassFlowPostProcessing::LoadPreValue(void) if (difference > PreValueAgeStartup) { - NUMBERS[j]->PreValueOkay = false; + NUMBERS[j]->PreValueValid = false; } else { - NUMBERS[j]->PreValueOkay = true; + NUMBERS[j]->PreValueValid = true; } } } @@ -344,7 +342,7 @@ ClassFlowPostProcessing::ClassFlowPostProcessing(std::vector *lfc, { PreValueUse = false; PreValueAgeStartup = 30; - ErrorMessage = false; + SkipErrorMessage = false; ListFlowControll = NULL; FilePreValue = format_filename("/sdcard/config/prevalue.ini"); ListFlowControll = lfc; @@ -670,9 +668,9 @@ bool ClassFlowPostProcessing::ReadParameter(FILE *pFile, std::string &aktparamgr PreValueAgeStartup = std::stoi(splitted[1]); } } - else if (_param == "ERRORMESSAGE") + else if (_param == "SKIPERRORMESSAGE") { - ErrorMessage = alphanumeric_to_boolean(splitted[1]); + SkipErrorMessage = alphanumeric_to_boolean(splitted[1]); } else if (_param == "ALLOWNEGATIVERATES") { @@ -776,27 +774,28 @@ void ClassFlowPostProcessing::InitNUMBERS() _number->AnzahlAnalog = 0; } - _number->PreValue = 0; // last value read out well + _number->PreValue = 0.0f; // last value read out well _number->ReturnPreValue = ""; - _number->PreValueOkay = false; + _number->PreValueValid = false; + _number->ErrorMessage = false; _number->ErrorMessageText = ""; // Error message for consistency check _number->AllowNegativeRates = false; _number->DecimalShift = 0; _number->DecimalShiftInitial = 0; - _number->AnalogToDigitTransitionStart = 9.2; - _number->MaxFlowRate = 4.0; + _number->AnalogToDigitTransitionStart = 9.2f; + _number->MaxFlowRate = 4.0f; _number->useMaxFlowRate = false; - _number->MaxRateValue = 0.1; + _number->MaxRateValue = 0.1f; _number->MaxRateType = AbsoluteChange; _number->useMaxRateValue = false; _number->ChangeRateThreshold = 2; _number->isExtendedResolution = false; _number->IgnoreLeadingNaN = false; - _number->Value = 0; // last value read out, incl. corrections + _number->Value = 0.0f; // last value read out, incl. corrections _number->ReturnValue = ""; // corrected return value, possibly with error message _number->ReturnRawValue = ""; // raw value (with N & leading 0) - _number->FlowRateAct = 0; // m3 / min + _number->FlowRateAct = 0.0f; // m3 / min _number->Nachkomma = _number->AnzahlAnalog; @@ -871,22 +870,42 @@ bool ClassFlowPostProcessing::doFlow(std::string temp_time) for (int j = 0; j < NUMBERS.size(); ++j) { - NUMBERS[j]->ReturnRawValue = ""; - NUMBERS[j]->ReturnRateValue = ""; - NUMBERS[j]->ReturnValue = ""; - NUMBERS[j]->ReturnChangeAbsolute = round_output(0.0, NUMBERS[j]->Nachkomma); // always reset change absolute + NUMBERS[j]->ErrorMessage = false; NUMBERS[j]->ErrorMessageText = ""; + NUMBERS[j]->Value = -1; + if (SkipErrorMessage) + { + NUMBERS[j]->ReturnValue = std::to_string(NUMBERS[j]->PreValue); + NUMBERS[j]->ReturnRawValue = NUMBERS[j]->ReturnValue; + } + else + { + NUMBERS[j]->ReturnValue = ""; + NUMBERS[j]->ReturnRawValue = ""; + } + + NUMBERS[j]->FlowRateAct = 0.0f; + NUMBERS[j]->ReturnRateValue = round_output(0.0f, NUMBERS[j]->Nachkomma); + NUMBERS[j]->ReturnChangeAbsolute = NUMBERS[j]->ReturnRateValue; + // calculate time difference - double LastValueTimeDifference = difftime(imagetime, NUMBERS[j]->timeStampLastValue) / 60; // in minutes + double LastValueTimeDifference = difftime(imagetime, NUMBERS[j]->timeStampLastValue) / 60; // in minutes double LastPreValueTimeDifference = difftime(imagetime, NUMBERS[j]->timeStampLastPreValue) / 60; // in minutes if (!flowctrl.AlignmentOk) { - NUMBERS[j]->ErrorMessageText = "alignment failed"; - LogFile.WriteToFile(ESP_LOG_ERROR, TAG, NUMBERS[j]->ErrorMessageText); + NUMBERS[j]->Value = NUMBERS[j]->PreValue; + NUMBERS[j]->timeStampLastValue = imagetime; + + NUMBERS[j]->ErrorMessage = true; + NUMBERS[j]->ErrorMessageText = NUMBERS[j]->ErrorMessageText + "Alignment failed - Read: " + round_output(NUMBERS[j]->Value, NUMBERS[j]->Nachkomma) + " - Raw: " + NUMBERS[j]->ReturnRawValue + " - Pre: " + round_output(NUMBERS[j]->PreValue, NUMBERS[j]->Nachkomma) + " - Rate: " + NUMBERS[j]->ReturnRateValue; + + std::string temp_string = NUMBERS[j]->name + ": Raw: " + NUMBERS[j]->ReturnRawValue + ", Value: " + NUMBERS[j]->ReturnValue + ", Status: " + NUMBERS[j]->ErrorMessageText; + LogFile.WriteToFile(ESP_LOG_ERROR, TAG, temp_string); WriteDataLog(j); + continue; } @@ -934,34 +953,52 @@ bool ClassFlowPostProcessing::doFlow(std::string temp_time) } } - NUMBERS[j]->ReturnValue = NUMBERS[j]->ReturnRawValue; + std::string TempValue = NUMBERS[j]->ReturnRawValue; - if (find_delimiter_pos(NUMBERS[j]->ReturnValue, "N") != std::string::npos) + if (find_delimiter_pos(TempValue, "N") != std::string::npos) { - if (PreValueUse && NUMBERS[j]->PreValueOkay) + if (PreValueUse && NUMBERS[j]->PreValueValid) { - NUMBERS[j]->ReturnValue = ErsetzteN(NUMBERS[j]->ReturnValue, NUMBERS[j]->PreValue); + TempValue = ErsetzteN(TempValue, NUMBERS[j]->PreValue); } else { + NUMBERS[j]->Value = NUMBERS[j]->PreValue; + NUMBERS[j]->timeStampLastValue = imagetime; + + NUMBERS[j]->ErrorMessage = true; + NUMBERS[j]->ErrorMessageText = NUMBERS[j]->ErrorMessageText + "PreValue not valid - Read: " + round_output(NUMBERS[j]->Value, NUMBERS[j]->Nachkomma) + " - Raw: " + NUMBERS[j]->ReturnRawValue + " - Pre: " + round_output(NUMBERS[j]->PreValue, NUMBERS[j]->Nachkomma) + " - Rate: " + NUMBERS[j]->ReturnRateValue; + std::string temp_string = NUMBERS[j]->name + ": Raw: " + NUMBERS[j]->ReturnRawValue + ", Value: " + NUMBERS[j]->ReturnValue + ", Status: " + NUMBERS[j]->ErrorMessageText; LogFile.WriteToFile(ESP_LOG_INFO, TAG, temp_string); - NUMBERS[j]->ReturnValue = ""; - NUMBERS[j]->timeStampLastValue = imagetime; WriteDataLog(j); + continue; // there is no number because there is still an N. } } // Delete leading zeros (unless there is only one 0 left) - while ((NUMBERS[j]->ReturnValue.length() > 1) && (NUMBERS[j]->ReturnValue[0] == '0')) + while ((TempValue.length() > 1) && (TempValue[0] == '0')) { - NUMBERS[j]->ReturnValue.erase(0, 1); + TempValue.erase(0, 1); } - NUMBERS[j]->Value = std::stod(NUMBERS[j]->ReturnValue); + NUMBERS[j]->Value = std::stod(TempValue); - if (PreValueUse && NUMBERS[j]->PreValueOkay) + NUMBERS[j]->ReturnChangeAbsolute = round_output(NUMBERS[j]->Value - NUMBERS[j]->PreValue, NUMBERS[j]->Nachkomma); + NUMBERS[j]->FlowRateAct = std::stod(round_output(((NUMBERS[j]->Value - NUMBERS[j]->PreValue) / LastPreValueTimeDifference), NUMBERS[j]->Nachkomma)); + + if (NUMBERS[j]->MaxRateType == RateChange) + { + NUMBERS[j]->ReturnRateValue = std::to_string(NUMBERS[j]->FlowRateAct); + } + else + { + // Difference per round, as a safeguard in case a reading error(Neg. Rate - Read: or Rate too high - Read:) occurs in the meantime + NUMBERS[j]->ReturnRateValue = round_output((NUMBERS[j]->Value - NUMBERS[j]->PreValue) / ((int)(round(LastPreValueTimeDifference / LastValueTimeDifference))), NUMBERS[j]->Nachkomma); + } + + if (PreValueUse && NUMBERS[j]->PreValueValid) { if ((NUMBERS[j]->Nachkomma > 0) && (NUMBERS[j]->ChangeRateThreshold > 0)) { @@ -971,7 +1008,6 @@ bool ClassFlowPostProcessing::doFlow(std::string temp_time) if ((NUMBERS[j]->Value >= _difference1) && (NUMBERS[j]->Value <= _difference2)) { NUMBERS[j]->Value = NUMBERS[j]->PreValue; - NUMBERS[j]->ReturnValue = std::to_string(NUMBERS[j]->PreValue); } } @@ -981,63 +1017,53 @@ bool ClassFlowPostProcessing::doFlow(std::string temp_time) if ((NUMBERS[j]->Value < NUMBERS[j]->PreValue)) { - NUMBERS[j]->ErrorMessageText = NUMBERS[j]->ErrorMessageText + "Neg. Rate - Read: " + round_output(NUMBERS[j]->Value, NUMBERS[j]->Nachkomma) + " - Raw: " + NUMBERS[j]->ReturnRawValue + " - Pre: " + round_output(NUMBERS[j]->PreValue, NUMBERS[j]->Nachkomma) + " "; NUMBERS[j]->Value = NUMBERS[j]->PreValue; - NUMBERS[j]->ReturnValue = ""; NUMBERS[j]->timeStampLastValue = imagetime; + NUMBERS[j]->ErrorMessage = true; + NUMBERS[j]->ErrorMessageText = NUMBERS[j]->ErrorMessageText + "Neg. Rate - Read: " + round_output(NUMBERS[j]->Value, NUMBERS[j]->Nachkomma) + " - Raw: " + NUMBERS[j]->ReturnRawValue + " - Pre: " + round_output(NUMBERS[j]->PreValue, NUMBERS[j]->Nachkomma) + " - Rate: " + NUMBERS[j]->ReturnRateValue; + std::string temp_string = NUMBERS[j]->name + ": Raw: " + NUMBERS[j]->ReturnRawValue + ", Value: " + NUMBERS[j]->ReturnValue + ", Status: " + NUMBERS[j]->ErrorMessageText; LogFile.WriteToFile(ESP_LOG_ERROR, TAG, temp_string); WriteDataLog(j); + continue; } } - NUMBERS[j]->FlowRateAct = (NUMBERS[j]->Value - NUMBERS[j]->PreValue) / LastPreValueTimeDifference; - NUMBERS[j]->ReturnRateValue = std::to_string(NUMBERS[j]->FlowRateAct); - if ((NUMBERS[j]->useMaxRateValue) && (NUMBERS[j]->Value != NUMBERS[j]->PreValue)) { - double _ratedifference; - - if (NUMBERS[j]->MaxRateType == RateChange) + if (abs(std::stod(NUMBERS[j]->ReturnRateValue)) > abs(NUMBERS[j]->MaxRateValue)) { - _ratedifference = NUMBERS[j]->FlowRateAct; - } - else - { - // Difference per round, as a safeguard in case a reading error(Neg. Rate - Read: or Rate too high - Read:) occurs in the meantime - _ratedifference = ((NUMBERS[j]->Value - NUMBERS[j]->PreValue) / ((int)(round(LastPreValueTimeDifference / LastValueTimeDifference)))); - } - - if (abs(_ratedifference) > abs(NUMBERS[j]->MaxRateValue)) - { - NUMBERS[j]->ErrorMessageText = NUMBERS[j]->ErrorMessageText + "Rate too high - Read: " + round_output(NUMBERS[j]->Value, NUMBERS[j]->Nachkomma) + " - Pre: " + round_output(NUMBERS[j]->PreValue, NUMBERS[j]->Nachkomma) + " - Rate: " + round_output(_ratedifference, NUMBERS[j]->Nachkomma); NUMBERS[j]->Value = NUMBERS[j]->PreValue; - NUMBERS[j]->ReturnValue = ""; - NUMBERS[j]->ReturnRateValue = ""; NUMBERS[j]->timeStampLastValue = imagetime; + NUMBERS[j]->ErrorMessage = true; + NUMBERS[j]->ErrorMessageText = NUMBERS[j]->ErrorMessageText + "Rate too high - Read: " + round_output(NUMBERS[j]->Value, NUMBERS[j]->Nachkomma) + " - Raw: " + NUMBERS[j]->ReturnRawValue + " - Pre: " + round_output(NUMBERS[j]->PreValue, NUMBERS[j]->Nachkomma) + " - Rate: " + NUMBERS[j]->ReturnRateValue; + std::string temp_string = NUMBERS[j]->name + ": Raw: " + NUMBERS[j]->ReturnRawValue + ", Value: " + NUMBERS[j]->ReturnValue + ", Status: " + NUMBERS[j]->ErrorMessageText; LogFile.WriteToFile(ESP_LOG_ERROR, TAG, temp_string); WriteDataLog(j); + continue; } } } NUMBERS[j]->ReturnChangeAbsolute = round_output(NUMBERS[j]->Value - NUMBERS[j]->PreValue, NUMBERS[j]->Nachkomma); - NUMBERS[j]->PreValue = NUMBERS[j]->Value; - NUMBERS[j]->PreValueOkay = true; - NUMBERS[j]->timeStampLastValue = imagetime; - NUMBERS[j]->timeStampLastPreValue = imagetime; + NUMBERS[j]->PreValue = NUMBERS[j]->Value; + NUMBERS[j]->PreValueValid = true; + UpdatePreValueINI = true; NUMBERS[j]->ReturnValue = round_output(NUMBERS[j]->Value, NUMBERS[j]->Nachkomma); NUMBERS[j]->ReturnPreValue = round_output(NUMBERS[j]->PreValue, NUMBERS[j]->Nachkomma); - NUMBERS[j]->ErrorMessageText = "no error"; - UpdatePreValueINI = true; + NUMBERS[j]->timeStampLastValue = imagetime; + NUMBERS[j]->timeStampLastPreValue = imagetime; + + NUMBERS[j]->ErrorMessage = false; + NUMBERS[j]->ErrorMessageText = NUMBERS[j]->ErrorMessageText + "no error - Read: " + round_output(NUMBERS[j]->Value, NUMBERS[j]->Nachkomma) + " - Raw: " + NUMBERS[j]->ReturnRawValue + " - Pre: " + round_output(NUMBERS[j]->PreValue, NUMBERS[j]->Nachkomma) + " - Rate: " + NUMBERS[j]->ReturnRateValue; std::string temp_string = NUMBERS[j]->name + ": Raw: " + NUMBERS[j]->ReturnRawValue + ", Value: " + NUMBERS[j]->ReturnValue + ", Status: " + NUMBERS[j]->ErrorMessageText; LogFile.WriteToFile(ESP_LOG_INFO, TAG, temp_string); @@ -1045,6 +1071,7 @@ bool ClassFlowPostProcessing::doFlow(std::string temp_time) } SavePreValue(); + return true; } @@ -1074,11 +1101,11 @@ void ClassFlowPostProcessing::WriteDataLog(int _index) std::string analog = ""; std::string digit = ""; - std::string temp_time = ""; + char buffer[80]; struct tm *timeinfo = localtime(&NUMBERS[_index]->timeStampLastValue); strftime(buffer, 80, PREVALUE_TIME_FORMAT_OUTPUT, timeinfo); - temp_time = std::string(buffer); + std::string temp_time = std::string(buffer); if (flowAnalog) { diff --git a/param-docs/expert-params.txt b/param-docs/expert-params.txt index 88d8bd78..1537c7b2 100644 --- a/param-docs/expert-params.txt +++ b/param-docs/expert-params.txt @@ -33,9 +33,8 @@ Antialiasing AlignmentAlgo CNNGoodThreshold PreValueAgeStartup -ErrorMessage +SkipErrorMessage MaxFlowRate -ProcessAlgoNew CACert ClientCert ClientKey diff --git a/param-docs/parameter-pages/PostProcessing/ErrorMessage.md b/param-docs/parameter-pages/PostProcessing/SkipErrorMessage.md similarity index 82% rename from param-docs/parameter-pages/PostProcessing/ErrorMessage.md rename to param-docs/parameter-pages/PostProcessing/SkipErrorMessage.md index 2213efb4..b5aa708c 100644 --- a/param-docs/parameter-pages/PostProcessing/ErrorMessage.md +++ b/param-docs/parameter-pages/PostProcessing/SkipErrorMessage.md @@ -1,5 +1,5 @@ -# Parameter `ErrorMessage` -Default Value: `true` +# Parameter `SkipErrorMessage` +Default Value: `false` !!! Warning This is an **Expert Parameter**! Only change it if you understand what it does! diff --git a/sd-card/config/config.ini b/sd-card/config/config.ini index 62604657..0ec82291 100644 --- a/sd-card/config/config.ini +++ b/sd-card/config/config.ini @@ -67,17 +67,16 @@ main.ana4 155 328 92 92 false [PostProcessing] PreValueUse = true PreValueAgeStartup = 720 -ErrorMessage = true +SkipErrorMessage = false main.AllowNegativeRates = false main.DecimalShift = 0 main.AnalogToDigitTransitionStart = 9.8 -;main.MaxFlowRate = 4.0 +main.MaxFlowRate = 4.0 main.MaxRateValue = 0.05 main.MaxRateType = AbsoluteChange main.ChangeRateThreshold = 2 main.ExtendedResolution = false main.IgnoreLeadingNaN = false -main.ProcessAlgoNew = false ;[MQTT] ;Uri = mqtt://IP-ADRESS:1883 diff --git a/sd-card/html/edit_config_template.html b/sd-card/html/edit_config_template.html index 6fac3ddc..19924c31 100644 --- a/sd-card/html/edit_config_template.html +++ b/sd-card/html/edit_config_template.html @@ -930,15 +930,15 @@ - Skip Messages on Error + Skip Messages on Error - - $TOOLTIP_PostProcessing_ErrorMessage + $TOOLTIP_PostProcessing_SkipErrorMessage @@ -2405,7 +2405,7 @@ function UpdateInput() { WriteParameter(param, category, "PostProcessing", "PreValueUse", false); WriteParameter(param, category, "PostProcessing", "PreValueAgeStartup", true); - WriteParameter(param, category, "PostProcessing", "ErrorMessage", false); + WriteParameter(param, category, "PostProcessing", "SkipErrorMessage", false); WriteParameter(param, category, "MQTT", "Uri", true); WriteParameter(param, category, "MQTT", "MainTopic", true); @@ -2579,7 +2579,7 @@ function ReadParameterAll() { ReadParameter(param, "PostProcessing", "PreValueUse", false); ReadParameter(param, "PostProcessing", "PreValueAgeStartup", true); - ReadParameter(param, "PostProcessing", "ErrorMessage", false); + ReadParameter(param, "PostProcessing", "SkipErrorMessage", false); ReadParameter(param, "MQTT", "Uri", true); ReadParameter(param, "MQTT", "MainTopic", true); diff --git a/sd-card/html/readconfigparam.js b/sd-card/html/readconfigparam.js index d69c0fba..02107707 100644 --- a/sd-card/html/readconfigparam.js +++ b/sd-card/html/readconfigparam.js @@ -253,7 +253,7 @@ function ParseConfig() { // ParamAddValue(param, catname, "PreValueUse", 1, true, "true"); ParamAddValue(param, catname, "PreValueUse", 1, false, "true"); ParamAddValue(param, catname, "PreValueAgeStartup", 1, false, "720"); - ParamAddValue(param, catname, "ErrorMessage", 1, false, "true"); + ParamAddValue(param, catname, "SkipErrorMessage", 1, false, "false"); ParamAddValue(param, catname, "AllowNegativeRates", 1, true, "false"); ParamAddValue(param, catname, "DecimalShift", 1, true, "0"); ParamAddValue(param, catname, "AnalogToDigitTransitionStart", 1, true, "9.2");