diff --git a/Changelog.md b/Changelog.md index bf580b89..0e490c0b 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,5 +1,83 @@ # Versions + + +##### 6.7.2 Image Processing in Memory - (2021-05-01) + +* NEW 6.7.2: Updated html for setup modus - remove reboot on edit configuration) + +* NEW 6.7.1: Improved stability of camera (back to v6.6.1) - remove black strips and areas + +* Upgrade digital CNN to v8.3.0 (added new type of digits) + +* Internal update: TFlite (v2.5), esp32cam, startup sequence + +* Rollback to espressif v2.1.0, as v3.2.0 shows unstable reboot + +* Bugfix: WLan-passwords, reset of hostname + + +##### 6.6.1 Image Processing in Memory - (2021-04-05) + +* NEW 6.6.1: failed SD card initialization indicated by fast blinking LED at startup +* Improved SD-card handling (increase compatibility with more type of cards) + +##### 6.5.0 Image Processing in Memory - (2021-03-25) + +* Upgrade digital CNN to v8.2.0 (added new type of digits) +* Supporting alignment structures in ROI definition +* Bug fixing: definition of hostname in `config.ini` + +##### 6.4.0 Image Processing in Memory - (2021-03-20) + +* Additional alignment marks for settings the ROIs (analog and digit) +* Upgrade analog CNN to v7.0.0 (added new type of pointer) + +##### 6.3.1 Image Processing in Memory - (2021-03-16) + +* NEW: 6.3.1: bug fixing in initial edit reference image and `config.ini` (Spelling error in `InitialRotate`) +* Initial setup mode: bug fixing, error correction +* Bug-fixing + +##### 6.2.2 Image Processing in Memory - (2021-03-10) + +* NEW 6.2.2: bug fixing +* NEW 6.2.1: Changed brightness and contrast to default if not enabled (resolves to bright images) +* Determination of fixed illumination settings during startup - speed up of 5s in each run +* Update digital CNN to v8.1.1 (additional digital images trained) +* Extended error message in MQTT error message + + +* Image brightness is now adjustable + + +* Bug fixing: minor topics + + +##### 6.1.0 Image Processing in Memory - (2021-01-20) + +* Disabling of analog / digital counters in configuration +* Improved Alignment Algorithm (`AlignmentAlgo` = `Default`, `Accurate` , `Fast`) +* Analog counters: `ExtendedResolution` (last digit is extended by sub comma value of CNN) +* `config.ini`: additional parameter `hostname` (additional to wlan.ini) +* Switching of GPIO12/13 via http-interface: `/GPIO?GPIO=12&Status=high/low` +* Bug fixing: html configuration page, wlan password ("=" now possible) + +##### 6.0.0 Image Processing in Memory - (2021-01-02) + +* **Major change**: image processing fully in memory - no need of SD card buffer anymore + + * Need to limit camera resolution to VGA (due to memory limits) +* MQTT: Last Will Testament (LWT) implemented: "connection lost" in case of connection lost to `TopicError` +* Disabled `CheckDigitIncreaseConsistency` in default configuration - must now be explicit enabled if needed +* Update digital CNN to v7.2.1 (additional digital images trained) +* Setting of arbitrary time server in `config.ini` +* Option for fixed IP-, DNS-Settings in `wlan.ini` +* Increased stability (internal image and camera handling) +* Bug fixing: edit digits, handling PreValue, html-bugs + + + ##### 5.0.0 Setup Modus - (2020-12-06) * Implementation of initial setup modus for fresh installation @@ -127,4 +205,4 @@ ##### 0.1.0 (2020-08-07) -* Initial Version +* Initial Version \ No newline at end of file diff --git a/README.md b/README.md index ae83536a..d00aaf23 100644 --- a/README.md +++ b/README.md @@ -45,83 +45,17 @@ In other cases you can contact the developer via email: getNextLine(pfile, &aktparamgraph) && !this->isNewParagraph(aktparamgraph)) { zerlegt = ZerlegeZeile(aktparamgraph); + if ((toUpper(zerlegt[0]) == "FLIPIMAGESIZE") && (zerlegt.size() > 1)) + { + if (toUpper(zerlegt[1]) == "TRUE") + initialflip = true; + } if ((toUpper(zerlegt[0]) == "INITIALMIRROR") && (zerlegt.size() > 1)) { if (toUpper(zerlegt[1]) == "TRUE") @@ -153,7 +159,13 @@ bool ClassFlowAlignment::doFlow(string time) delete AlignAndCutImage; AlignAndCutImage = new CAlignAndCutImage(ImageBasis, ImageTMP); - CRotateImage rt(AlignAndCutImage, ImageTMP); + CRotateImage rt(AlignAndCutImage, ImageTMP, initialflip); + if (initialflip) + { + int _zw = ImageBasis->height; + ImageBasis->height = ImageBasis->width; + ImageBasis->width = _zw; + } if (initialmirror){ printf("do mirror\n"); @@ -161,7 +173,7 @@ bool ClassFlowAlignment::doFlow(string time) if (SaveAllFiles) AlignAndCutImage->SaveToFile(FormatFileName("/sdcard/img_tmp/mirror.jpg")); } - if (initalrotate != 0) + if ((initalrotate != 0) || initialflip) { rt.Rotate(initalrotate); if (SaveAllFiles) AlignAndCutImage->SaveToFile(FormatFileName("/sdcard/img_tmp/rot.jpg")); @@ -176,6 +188,12 @@ bool ClassFlowAlignment::doFlow(string time) if (SaveAllFiles) { + if (initialflip) + { + int _zw = ImageTMP->width; + ImageTMP->width = ImageTMP->height; + ImageTMP->height = _zw; + } DrawRef(ImageTMP); ImageTMP->SaveToFile(FormatFileName("/sdcard/img_tmp/alg_roi.jpg")); } @@ -209,7 +227,7 @@ void ClassFlowAlignment::SaveReferenceAlignmentValues() time(&rawtime); timeinfo = localtime(&rawtime); - strftime(buffer, 80, "%Y-%m-%d_%H-%M-%S", timeinfo); + strftime(buffer, 80, "%Y-%m-%dT%H:%M:%S", timeinfo); zwtime = std::string(buffer); } diff --git a/code/components/jomjol_flowcontroll/ClassFlowAlignment.h b/code/components/jomjol_flowcontroll/ClassFlowAlignment.h index 8c0e07ce..180dc7f6 100644 --- a/code/components/jomjol_flowcontroll/ClassFlowAlignment.h +++ b/code/components/jomjol_flowcontroll/ClassFlowAlignment.h @@ -15,6 +15,7 @@ class ClassFlowAlignment : protected: float initalrotate; bool initialmirror; + bool initialflip; RefInfo References[2]; int anz_ref; string namerawimage; diff --git a/code/components/jomjol_flowcontroll/ClassFlowMQTT.cpp b/code/components/jomjol_flowcontroll/ClassFlowMQTT.cpp index 273222a8..3e75827a 100644 --- a/code/components/jomjol_flowcontroll/ClassFlowMQTT.cpp +++ b/code/components/jomjol_flowcontroll/ClassFlowMQTT.cpp @@ -11,6 +11,8 @@ void ClassFlowMQTT::SetInitialParameter(void) uri = ""; topic = ""; topicError = ""; + topicRate = ""; + topicTimeStamp = ""; clientname = "watermeter"; OldValue = ""; flowpostprocessing = NULL; @@ -94,6 +96,15 @@ bool ClassFlowMQTT::ReadParameter(FILE* pfile, string& aktparamgraph) { this->topicError = zerlegt[1]; } + if ((toUpper(zerlegt[0]) == "TOPICRATE") && (zerlegt.size() > 1)) + { + this->topicRate = zerlegt[1]; + } + if ((toUpper(zerlegt[0]) == "TOPICTIMESTAMP") && (zerlegt.size() > 1)) + { + this->topicTimeStamp = zerlegt[1]; + } + if ((toUpper(zerlegt[0]) == "CLIENTID") && (zerlegt.size() > 1)) { this->clientname = zerlegt[1]; @@ -114,12 +125,16 @@ bool ClassFlowMQTT::doFlow(string zwtime) { std::string result; std::string resulterror = ""; + std::string resultrate = ""; + std::string resulttimestamp = ""; string zw = ""; if (flowpostprocessing) { result = flowpostprocessing->getReadoutParam(false, true); resulterror = flowpostprocessing->getReadoutError(); + resultrate = flowpostprocessing->getReadoutRate(); + resulttimestamp = flowpostprocessing->getReadoutTimeStamp(); } else { @@ -139,9 +154,21 @@ bool ClassFlowMQTT::doFlow(string zwtime) MQTTPublish(topic, result); if (topicError.length() > 0) { + if (resulterror.length() == 0) + { + resulterror = " "; + } MQTTPublish(topicError, resulterror); } + if (topicRate.length() > 0) { + MQTTPublish(topicRate, resultrate); + } + + if (topicRate.length() > 0) { + MQTTPublish(topicTimeStamp, resulttimestamp); + } + OldValue = result; return true; diff --git a/code/components/jomjol_flowcontroll/ClassFlowMQTT.h b/code/components/jomjol_flowcontroll/ClassFlowMQTT.h index 2ac29135..99035659 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, topicError, clientname; + std::string uri, topic, topicError, clientname, topicRate, topicTimeStamp; std::string OldValue; ClassFlowPostProcessing* flowpostprocessing; std::string user, password; diff --git a/code/components/jomjol_flowcontroll/ClassFlowMakeImage.cpp b/code/components/jomjol_flowcontroll/ClassFlowMakeImage.cpp index 2b9a9f50..0d69a31a 100644 --- a/code/components/jomjol_flowcontroll/ClassFlowMakeImage.cpp +++ b/code/components/jomjol_flowcontroll/ClassFlowMakeImage.cpp @@ -19,6 +19,10 @@ esp_err_t ClassFlowMakeImage::camera_capture(){ void ClassFlowMakeImage::takePictureWithFlash(int flashdauer) { + // für den Fall, dass das Bild geflippt wird, muss es hier zurück gesetzt werden //// + rawImage->width = image_width; + rawImage->height = image_height; + ///////////////////////////////////////////////////////////////////////////////////// Camera.CaptureToBasisImage(rawImage, flashdauer); if (SaveAllFiles) rawImage->SaveToFile(namerawimage); } diff --git a/code/components/jomjol_flowcontroll/ClassFlowPostProcessing.cpp b/code/components/jomjol_flowcontroll/ClassFlowPostProcessing.cpp index acbf565f..e9119239 100644 --- a/code/components/jomjol_flowcontroll/ClassFlowPostProcessing.cpp +++ b/code/components/jomjol_flowcontroll/ClassFlowPostProcessing.cpp @@ -63,7 +63,7 @@ bool ClassFlowPostProcessing::LoadPreValue(void) int yy, month, dd, hh, mm, ss; struct tm whenStart; - sscanf(zwtime.c_str(), "%d-%d-%d_%d-%d-%d", &yy, &month, &dd, &hh, &mm, &ss); + sscanf(zwtime.c_str(), "%d-%d-%dT%d:%d:%d", &yy, &month, &dd, &hh, &mm, &ss); whenStart.tm_year = yy - 1900; whenStart.tm_mon = month - 1; whenStart.tm_mday = dd; @@ -74,10 +74,9 @@ bool ClassFlowPostProcessing::LoadPreValue(void) tStart = mktime(&whenStart); - time_t now; - time(&now); - localtime(&now); - double difference = difftime(now, tStart); + time(&lastvalue); + localtime(&lastvalue); + double difference = difftime(lastvalue, tStart); difference /= 60; if (difference > PreValueAgeStartup) return false; @@ -122,13 +121,17 @@ void ClassFlowPostProcessing::SavePreValue(float value, string zwtime) time(&rawtime); timeinfo = localtime(&rawtime); - strftime(buffer, 80, "%Y-%m-%d_%H-%M-%S", timeinfo); - zwtime = std::string(buffer); + strftime(buffer, 80, "%Y-%m-%dT%H:%M:%S", timeinfo); + timeStamp = std::string(buffer); + } + else + { + timeStamp = zwtime; } PreValue = value; - fputs(zwtime.c_str(), pFile); + fputs(timeStamp.c_str(), pFile); fputs("\n", pFile); fputs(to_string(value).c_str(), pFile); fputs("\n", pFile); @@ -139,6 +142,7 @@ void ClassFlowPostProcessing::SavePreValue(float value, string zwtime) ClassFlowPostProcessing::ClassFlowPostProcessing(std::vector* lfc) { + FlowRateAct = 0; PreValueUse = false; PreValueAgeStartup = 30; AllowNegativeRates = false; @@ -150,6 +154,7 @@ ClassFlowPostProcessing::ClassFlowPostProcessing(std::vector* lfc) checkDigitIncreaseConsistency = false; DecimalShift = 0; ErrorMessageText = ""; + timeStamp = ""; FilePreValue = FormatFileName("/sdcard/config/prevalue.ini"); ListFlowControll = lfc; } @@ -300,7 +305,7 @@ bool ClassFlowPostProcessing::doFlow(string zwtime) timeinfo = localtime(&imagetime); char strftime_buf[64]; - strftime(strftime_buf, sizeof(strftime_buf), "%Y-%m-%d_%H-%M-%S", timeinfo); + strftime(strftime_buf, sizeof(strftime_buf), "%Y-%m-%dT%H:%M:%S", timeinfo); zwtime = std::string(strftime_buf); @@ -343,12 +348,15 @@ bool ClassFlowPostProcessing::doFlow(string zwtime) PreValueOkay = true; PreValue = Value; - + time(&lastvalue); + localtime(&lastvalue); + SavePreValue(Value, zwtime); } return true; } + zw = ErsetzteN(ReturnRawValue); Value = std::stof(zw); @@ -373,6 +381,7 @@ bool ClassFlowPostProcessing::doFlow(string zwtime) zwvalue = RundeOutput(Value, AnzahlAnalog - DecimalShift); } + ReturnValueNoError = zwvalue; ReturnValue = zwvalue; if (ErrorMessage && (ErrorMessageText.length() > 0)) @@ -380,10 +389,15 @@ bool ClassFlowPostProcessing::doFlow(string zwtime) if (ErrorMessageText.length() == 0) { + time_t currenttime; + time(¤ttime); + localtime(¤ttime); + double difference = difftime(currenttime, lastvalue); // in Sekunden + difference /= 60; // in Minuten + FlowRateAct = (Value - PreValue) / difference; + PreValue = Value; - SavePreValue(Value, zwtime); - } return true; } @@ -506,6 +520,16 @@ float ClassFlowPostProcessing::checkDigitConsistency(float input, int _decilamsh return input; } +string ClassFlowPostProcessing::getReadoutRate() +{ + return std::to_string(FlowRateAct); +} + +string ClassFlowPostProcessing::getReadoutTimeStamp() +{ + return timeStamp; +} + string ClassFlowPostProcessing::getReadoutError() { diff --git a/code/components/jomjol_flowcontroll/ClassFlowPostProcessing.h b/code/components/jomjol_flowcontroll/ClassFlowPostProcessing.h index 435c6d48..3c8df529 100644 --- a/code/components/jomjol_flowcontroll/ClassFlowPostProcessing.h +++ b/code/components/jomjol_flowcontroll/ClassFlowPostProcessing.h @@ -17,6 +17,9 @@ protected: bool PreValueOkay; bool checkDigitIncreaseConsistency; int DecimalShift; + time_t lastvalue; + float FlowRateAct; // m3 / min + string FilePreValue; float PreValue; // letzter Wert, der gut ausgelesen wurde @@ -25,6 +28,7 @@ protected: string ReturnValue; // korrigierter Rückgabewert, ggf. mit Fehlermeldung string ReturnValueNoError; // korrigierter Rückgabewert ohne Fehlermeldung string ErrorMessageText; // Fehlermeldung bei Consistency Check + string timeStamp; bool LoadPreValue(void); string ShiftDecimal(string in, int _decShift); @@ -40,6 +44,8 @@ public: string getReadout(); string getReadoutParam(bool _rawValue, bool _noerror); string getReadoutError(); + string getReadoutRate(); + string getReadoutTimeStamp(); void SavePreValue(float value, string time = ""); string GetPreValue(); diff --git a/code/components/jomjol_image_proc/CRotateImage.cpp b/code/components/jomjol_image_proc/CRotateImage.cpp index e40efda5..b6b2321b 100644 --- a/code/components/jomjol_image_proc/CRotateImage.cpp +++ b/code/components/jomjol_image_proc/CRotateImage.cpp @@ -1,7 +1,7 @@ #include "CRotateImage.h" -CRotateImage::CRotateImage(CImageBasis *_org, CImageBasis *_temp) +CRotateImage::CRotateImage(CImageBasis *_org, CImageBasis *_temp, bool _flip) { rgb_image = _org->rgb_image; channels = _org->channels; @@ -9,8 +9,10 @@ CRotateImage::CRotateImage(CImageBasis *_org, CImageBasis *_temp) height = _org->height; bpp = _org->bpp; externalImage = true; - ImageTMP = _temp; + ImageTMP = _temp; + ImageOrg = _org; islocked = false; + doflip = _flip; } void CRotateImage::Mirror(){ @@ -58,12 +60,33 @@ void CRotateImage::Mirror(){ void CRotateImage::Rotate(float _angle, int _centerx, int _centery) { + int org_width, org_height; float m[2][3]; float x_center = _centerx; float y_center = _centery; _angle = _angle / 180 * M_PI; + if (doflip) + { + org_width = width; + org_height = height; + height = org_width; + width = org_height; + x_center = x_center - (org_width/2) + (org_height/2); + y_center = y_center + (org_width/2) - (org_height/2); + if (ImageOrg) + { + ImageOrg->height = height; + ImageOrg->width = width; + } + } + else + { + org_width = width; + org_height = height; + } + m[0][0] = cos(_angle); m[0][1] = sin(_angle); m[0][2] = (1 - m[0][0]) * x_center - m[0][1] * y_center; @@ -72,6 +95,12 @@ void CRotateImage::Rotate(float _angle, int _centerx, int _centery) m[1][1] = m[0][0]; m[1][2] = m[0][1] * x_center + (1 - m[0][0]) * y_center; + if (doflip) + { + m[0][2] = m[0][2] + (org_width/2) - (org_height/2); + m[1][2] = m[1][2] - (org_width/2) + (org_height/2); + } + int memsize = width * height * channels; uint8_t* odata; if (ImageTMP) @@ -101,9 +130,9 @@ void CRotateImage::Rotate(float _angle, int _centerx, int _centery) x_source += int(m[0][2]); y_source += int(m[1][2]); - if ((x_source >= 0) && (x_source < width) && (y_source >= 0) && (y_source < height)) + if ((x_source >= 0) && (x_source < org_width) && (y_source >= 0) && (y_source < org_height)) { - p_source = rgb_image + (channels * (y_source * width + x_source)); + p_source = rgb_image + (channels * (y_source * org_width + x_source)); for (int _channels = 0; _channels < channels; ++_channels) p_target[_channels] = p_source[_channels]; } diff --git a/code/components/jomjol_image_proc/CRotateImage.h b/code/components/jomjol_image_proc/CRotateImage.h index ccd362b4..90ad7d71 100644 --- a/code/components/jomjol_image_proc/CRotateImage.h +++ b/code/components/jomjol_image_proc/CRotateImage.h @@ -4,10 +4,11 @@ class CRotateImage: public CImageBasis { public: - CImageBasis *ImageTMP; - CRotateImage(std::string _image) : CImageBasis(_image) {ImageTMP = NULL;}; - CRotateImage(uint8_t* _rgb_image, int _channels, int _width, int _height, int _bpp) : CImageBasis(_rgb_image, _channels, _width, _height, _bpp) {ImageTMP = NULL;}; - CRotateImage(CImageBasis *_org, CImageBasis *_temp); + CImageBasis *ImageTMP, *ImageOrg; + bool doflip; + CRotateImage(std::string _image, bool _flip = false) : CImageBasis(_image) {ImageTMP = NULL; ImageOrg = NULL; doflip = _flip;}; + CRotateImage(uint8_t* _rgb_image, int _channels, int _width, int _height, int _bpp, bool _flip = false) : CImageBasis(_rgb_image, _channels, _width, _height, _bpp) {ImageTMP = NULL; ImageOrg = NULL; doflip = _flip;}; + CRotateImage(CImageBasis *_org, CImageBasis *_temp, bool _flip = false); void Rotate(float _angle); void Rotate(float _angle, int _centerx, int _centery); diff --git a/code/components/jomjol_logfile/ClassLogFile.cpp b/code/components/jomjol_logfile/ClassLogFile.cpp index f8fbb3fc..71825ca7 100644 --- a/code/components/jomjol_logfile/ClassLogFile.cpp +++ b/code/components/jomjol_logfile/ClassLogFile.cpp @@ -77,7 +77,7 @@ void ClassLogFile::WriteToDedicatedFile(std::string _fn, std::string info, bool time(&rawtime); timeinfo = localtime(&rawtime); - strftime(buffer, 80, "%Y-%m-%d_%H-%M-%S", timeinfo); + strftime(buffer, 80, "%Y-%m-%dT%H:%M:%S", timeinfo); zwtime = std::string(buffer); info = zwtime + ": " + info; diff --git a/code/main/server_main.cpp b/code/main/server_main.cpp index 719e8d7a..fb5df4ee 100644 --- a/code/main/server_main.cpp +++ b/code/main/server_main.cpp @@ -387,7 +387,7 @@ httpd_handle_t start_webserver(void) httpd_config_t config = { }; config.task_priority = tskIDLE_PRIORITY+5; - config.stack_size = 16384; // bei 32k stürzt das Programm beim Bilderaufnehmen ab + config.stack_size = 32384; // bei 32k stürzt das Programm beim Bilderaufnehmen ab config.core_id = tskNO_AFFINITY; config.server_port = 80; config.ctrl_port = 32768; diff --git a/code/main/version.cpp b/code/main/version.cpp index 60c6a4b2..a834e999 100644 --- a/code/main/version.cpp +++ b/code/main/version.cpp @@ -1,4 +1,4 @@ -const char* GIT_REV="a45a529"; +const char* GIT_REV="10d49b5"; const char* GIT_TAG=""; -const char* GIT_BRANCH="master"; -const char* BUILD_TIME="2021-05-01 17:42"; \ No newline at end of file +const char* GIT_BRANCH="rolling"; +const char* BUILD_TIME="2021-05-08 18:03"; \ No newline at end of file diff --git a/code/main/version.h b/code/main/version.h index 130b1a62..33a5aeb6 100644 --- a/code/main/version.h +++ b/code/main/version.h @@ -13,7 +13,7 @@ extern "C" #include "Helper.h" #include -const char* GIT_BASE_BRANCH = "master - v6.7.1 - 2020-01-05"; +const char* GIT_BASE_BRANCH = "master - v7.0.0 - 2020-05-08"; const char* git_base_branch(void) diff --git a/code/version.cpp b/code/version.cpp index 60c6a4b2..a834e999 100644 --- a/code/version.cpp +++ b/code/version.cpp @@ -1,4 +1,4 @@ -const char* GIT_REV="a45a529"; +const char* GIT_REV="10d49b5"; const char* GIT_TAG=""; -const char* GIT_BRANCH="master"; -const char* BUILD_TIME="2021-05-01 17:42"; \ No newline at end of file +const char* GIT_BRANCH="rolling"; +const char* BUILD_TIME="2021-05-08 18:03"; \ No newline at end of file diff --git a/firmware/bootloader.bin b/firmware/bootloader.bin index 3358d19c..ea9086bc 100644 Binary files a/firmware/bootloader.bin and b/firmware/bootloader.bin differ diff --git a/firmware/firmware.bin b/firmware/firmware.bin index 9405f80c..f51c5a23 100644 Binary files a/firmware/firmware.bin and b/firmware/firmware.bin differ diff --git a/firmware/html.zip b/firmware/html.zip index 0fb191bd..d5078f8b 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 716e0aeb..66b30810 100644 --- a/sd-card/config/config.ini +++ b/sd-card/config/config.ini @@ -9,6 +9,7 @@ FixedExposure = false [Alignment] InitialRotate=180 +FlipImageSize = false /config/ref0.jpg 119 273 /config/ref1.jpg 456 138 SearchFieldX = 20 @@ -17,7 +18,7 @@ InitialMirror= false AlignmentAlgo = Default [Digits] -Model = /config/dig0840s1q.tflite +Model = /config/dig0850s1q.tflite ;LogImageLocation = /log/digit ;LogfileRetentionInDays = 3 ModelInputSize = 20 32 @@ -49,6 +50,8 @@ CheckDigitIncreaseConsistency = false ;Uri = mqtt://IP-ADRESS:1883 ;Topic = wasserzaehler/zaehlerstand ;TopicError = wasserzaehler/error +;TopicRate = wasserzaehler/rate +;TopicTimeStamp = wasserzaehler/timestamp ;ClientID = wasser ;user = USERNAME ;password = PASSWORD diff --git a/sd-card/config/dig0850s1q.tflite b/sd-card/config/dig0850s1q.tflite new file mode 100644 index 00000000..aab43750 Binary files /dev/null and b/sd-card/config/dig0850s1q.tflite differ diff --git a/sd-card/html/edit_config_param.html b/sd-card/html/edit_config_param.html index 491cfa94..867ba103 100644 --- a/sd-card/html/edit_config_param.html +++ b/sd-card/html/edit_config_param.html @@ -518,6 +518,34 @@ textarea { MQTT topic, in which the error status is reported (empty = no error) + + + + + + TopicRate + + + + + + MQTT topic, in which the flow rate [units / minute] is reported + + + + + + + + TopicTimeStamp + + + + + + MQTT topic, reporting the last correct readout + + @@ -907,6 +935,8 @@ function UpdateInput() { WriteParameter(param, category, "MQTT", "Uri", true); WriteParameter(param, category, "MQTT", "Topic", true); WriteParameter(param, category, "MQTT", "TopicError", true); + WriteParameter(param, category, "MQTT", "TopicRate", true); + WriteParameter(param, category, "MQTT", "TopicTimeStamp", true); WriteParameter(param, category, "MQTT", "ClientID", true); WriteParameter(param, category, "MQTT", "user", true); WriteParameter(param, category, "MQTT", "password", true); @@ -964,6 +994,8 @@ function ReadParameterAll() ReadParameter(param, "MQTT", "Uri", true); ReadParameter(param, "MQTT", "Topic", true); ReadParameter(param, "MQTT", "TopicError", true); + ReadParameter(param, "MQTT", "TopicRate", true); + ReadParameter(param, "MQTT", "TopicTimeStamp", true); ReadParameter(param, "MQTT", "ClientID", true); ReadParameter(param, "MQTT", "user", true); ReadParameter(param, "MQTT", "password", true); diff --git a/sd-card/html/edit_reference.html b/sd-card/html/edit_reference.html index beb334b9..e937db5b 100644 --- a/sd-card/html/edit_reference.html +++ b/sd-card/html/edit_reference.html @@ -44,6 +44,11 @@ table { + + + + + @@ -129,6 +134,13 @@ table { document.getElementById("labelmirror").style = "color:lightgrey;"; } + if (param["Alignment"]["FlipImageSize"].found) + document.getElementById("flip").disabled = false; + else + { + document.getElementById("labelflip").style = "color:lightgrey;"; + } + if (param["MakeImage"]["Brightness"].found && param["MakeImage"]["Brightness"].enabled) document.getElementById("MakeImage_Brightness_value1").disabled = false; else @@ -156,6 +168,9 @@ table { if (_param["Alignment"]["InitialMirror"].found && (_param["Alignment"]["InitialMirror"].value1 == "true")) document.getElementById("mirror").checked = true; + if (_param["Alignment"]["FlipImageSize"].found && (_param["Alignment"]["FlipImageSize"].value1 == "true")) + document.getElementById("flip").checked = true; + document.getElementById("finerotate").disabled = true; document.getElementById("prerotateangle").disabled = true; document.getElementById("updatereferenceimage").disabled = true; @@ -164,6 +179,7 @@ table { // document.getElementById("MakeImage_Saturation_value1").disabled = true; // document.getElementById("MakeImage_Contrast_value1").disabled = true; document.getElementById("mirror").disabled = false; + document.getElementById("flip").disabled = false; if (!(param["MakeImage"]["Brightness"].found)) { document.getElementById("MakeImage_Brightness_value1").type = "hidden"; @@ -172,6 +188,7 @@ table { document.getElementById("mirror").disabled = true; + document.getElementById("flip").disabled = true; isActReference = true; loadCanvas(url); @@ -190,11 +207,17 @@ table { function SaveReference(){ if (confirm("Are you sure you want to update the reference image?")) { param["Alignment"]["InitialRotate"].value1 = document.getElementById("prerotateangle").value; + if ((param["Alignment"]["InitialMirror"].found == true) && (document.getElementById("mirror").checked)) param["Alignment"]["InitialMirror"].value1 = "true"; else param["Alignment"]["InitialMirror"].value1 = "false"; + if ((param["Alignment"]["FlipImageSize"].found == true) && (document.getElementById("flip").checked)) + param["Alignment"]["FlipImageSize"].value1 = "true"; + else + param["Alignment"]["FlipImageSize"].value1 = "false"; + if (param["MakeImage"]["Brightness"].found && param["MakeImage"]["Brightness"].enabled) { ReadParameter(param, "MakeImage", "Brightness", false); @@ -319,6 +342,7 @@ table { finerot= parseFloat(document.getElementById("finerotate").value); prerot = parseFloat(document.getElementById("prerotateangle").value); mirror = document.getElementById("mirror").checked; + flip = document.getElementById("flip").checked; if (finerot == 1) { prerot+=1 @@ -332,10 +356,22 @@ table { document.getElementById("finerotate").value = finerot; document.getElementById("prerotateangle").value = prerot; + var canvas = document.getElementById('canvas'); + if (flip == 1) + { + canvas.width = imageObj.height; + canvas.height = imageObj.width; + } + else + { + canvas.width = imageObj.width; + canvas.height = imageObj.height; + } + var canvas = document.getElementById('canvas'); var context = canvas.getContext('2d'); - context.clearRect(0,0,imageObj.width,imageObj.height); + context.clearRect(0,0,canvas.width,canvas.height); context.save(); if (isActReference) @@ -344,17 +380,12 @@ table { } else { + context.translate(canvas.width/2,canvas.height/2); + context.rotate(degrees*Math.PI/180); if (mirror) { context.scale(-1, 1); - context.translate(-imageObj.width/2,imageObj.height/2); - context.rotate(-degrees*Math.PI/180); - context.drawImage(imageObj, imageObj.width/2,-imageObj.height/2, -imageObj.width, imageObj.height); - } - else { - context.translate(imageObj.width/2,imageObj.height/2); - context.rotate(degrees*Math.PI/180); - context.drawImage(imageObj,-imageObj.width/2,-imageObj.height/2); } + context.drawImage(imageObj,-imageObj.width/2,-imageObj.height/2); } diff --git a/sd-card/html/readconfigparam.js b/sd-card/html/readconfigparam.js index 960bcc0b..af7a0d00 100644 --- a/sd-card/html/readconfigparam.js +++ b/sd-card/html/readconfigparam.js @@ -39,7 +39,8 @@ function ParseConfig() { ParamAddValue(param, catname, "InitialMirror"); ParamAddValue(param, catname, "SearchFieldX"); ParamAddValue(param, catname, "SearchFieldY"); - ParamAddValue(param, catname, "AlignmentAlgo"); + ParamAddValue(param, catname, "AlignmentAlgo"); + ParamAddValue(param, catname, "FlipImageSize"); var catname = "Digits"; category[catname] = new Object(); @@ -83,6 +84,8 @@ function ParseConfig() { ParamAddValue(param, catname, "Uri"); ParamAddValue(param, catname, "Topic"); ParamAddValue(param, catname, "TopicError"); + ParamAddValue(param, catname, "TopicRate"); + ParamAddValue(param, catname, "TopicTimeStamp"); ParamAddValue(param, catname, "ClientID"); ParamAddValue(param, catname, "user"); ParamAddValue(param, catname, "password"); diff --git a/sd-card/html/sd-card - Verknüpfung.lnk b/sd-card/html/sd-card - Verknüpfung.lnk new file mode 100644 index 00000000..4c6bfce3 Binary files /dev/null and b/sd-card/html/sd-card - Verknüpfung.lnk differ diff --git a/sd-card/html/version.txt b/sd-card/html/version.txt index f22d756d..e029aa99 100644 --- a/sd-card/html/version.txt +++ b/sd-card/html/version.txt @@ -1 +1 @@ -6.5.0 +6.8.0 diff --git a/sd-card/html/wasserzaehler_roi.html b/sd-card/html/wasserzaehler_roi.html index e4e47f9e..d12cbe64 100644 --- a/sd-card/html/wasserzaehler_roi.html +++ b/sd-card/html/wasserzaehler_roi.html @@ -31,7 +31,7 @@ var m = addZero(d.getMinutes()); var s = addZero(d.getSeconds()); - $('#img').html(''); + $('#img').html(''); $("#raw").load("/wasserzaehler.html?rawvalue=true"); $("#corrected").load("/wasserzaehler.html"); $("#checked").load("/setPreValue.html"); @@ -49,7 +49,7 @@ var m = addZero(d.getMinutes()); var s = addZero(d.getSeconds()); // reassign the url to be like alg_roi.jpg?timestamp=456784512 based on timestamp - $('#img').html(''); + $('#img').html(''); $("#raw").load("/wasserzaehler.html?rawvalue=true"); $("#corrected").load("/wasserzaehler.html"); $("#checked").load("/setPreValue.html");