From a226ffcedefaefc23c9984d509d1ee94a1b17357 Mon Sep 17 00:00:00 2001 From: Zefek <32429493+Zefek@users.noreply.github.com> Date: Tue, 26 May 2026 17:16:53 +0200 Subject: [PATCH 1/6] Remove convert_to_utf8 function and update publish --- HeatingTemperatureRegulator.ino | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/HeatingTemperatureRegulator.ino b/HeatingTemperatureRegulator.ino index 34c034d..ba0f44c 100644 --- a/HeatingTemperatureRegulator.ino +++ b/HeatingTemperatureRegulator.ino @@ -41,19 +41,6 @@ void convertToHalfByte(int value, uint8_t* result, uint8_t length) } } -void convert_to_utf8(const uint8_t* input, uint8_t length, char* output) { - int j = 0; - for(int i = 0; i < length; i++) - { - uint8_t first = input[i] >> 4; - uint8_t second = input[i] & 0x0F; - output[j++] = first<10? (char)('0'+first):(char)('7'+first); - output[j++] = second<10? (char)('0'+second):(char)('7'+second); - } - - output[j] = '\0'; // Null-terminate the UTF-8 string -} - /* 0 - currentTemperature 1 - inputTemperature @@ -434,8 +421,7 @@ void OutsideTemperatureChanged(double temperature, uint8_t channel, uint8_t sens outsideTemperature = temperature; if (memcmp(rawData, temperatureDataToCompare, 5) != 0) { - convert_to_utf8(rawData, 5, utf8Buffer); - client.Publish(TOPIC_OUTSIDETEMPERATURE, (const char*) utf8Buffer, true); + client.Publish(TOPIC_OUTSIDETEMPERATURE, rawData, 5); memcpy(temperatureDataToCompare, rawData, 5); } if(!outsideTemperatureWasSet) From 3bfdec755340f58f440dfc1a3dc0d6b2bc955f09 Mon Sep 17 00:00:00 2001 From: Zefek <32429493+Zefek@users.noreply.github.com> Date: Tue, 26 May 2026 17:20:46 +0200 Subject: [PATCH 2/6] Update pull_request_build.yml --- .github/workflows/pull_request_build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pull_request_build.yml b/.github/workflows/pull_request_build.yml index dc6ccce..6cec932 100644 --- a/.github/workflows/pull_request_build.yml +++ b/.github/workflows/pull_request_build.yml @@ -35,7 +35,7 @@ jobs: - name: Static analysis run: | sudo apt-get install -y cppcheck - cppcheck --enable=all --language=c++ --suppress=missingIncludeSystem --suppress=unusedFunction --suppress=unusedStructMember --suppress=noExplicitConstructor --suppress=noCopyConstructor --suppress=noOperatorEq --suppress=cstyleCast --suppress=constParameterCallback --suppress=constParameterPointer --suppress=constVariablePointer --suppress=unsignedLessThanZero --suppress=unsignedPositive --suppress=checkersReport --error-exitcode=1 *.ino *.cpp *.h + cppcheck --enable=all --language=c++ --suppress=missingIncludeSystem --suppress=unusedFunction --suppress=unusedStructMember --suppress=noExplicitConstructor --suppress=noCopyConstructor --suppress=noOperatorEq --suppress=cstyleCast --suppress=constParameterPointer --suppress=constVariablePointer --suppress=unsignedLessThanZero --suppress=unsignedPositive --suppress=checkersReport --error-exitcode=1 *.ino *.cpp *.h - name: Compile Arduino project run: | From 6252cd20decd423cdd6e316508b357c9b225d976 Mon Sep 17 00:00:00 2001 From: Zefek <32429493+Zefek@users.noreply.github.com> Date: Tue, 26 May 2026 17:22:41 +0200 Subject: [PATCH 3/6] Update HeatingTemperatureRegulator.ino --- HeatingTemperatureRegulator.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HeatingTemperatureRegulator.ino b/HeatingTemperatureRegulator.ino index ba0f44c..82a632f 100644 --- a/HeatingTemperatureRegulator.ino +++ b/HeatingTemperatureRegulator.ino @@ -421,7 +421,7 @@ void OutsideTemperatureChanged(double temperature, uint8_t channel, uint8_t sens outsideTemperature = temperature; if (memcmp(rawData, temperatureDataToCompare, 5) != 0) { - client.Publish(TOPIC_OUTSIDETEMPERATURE, rawData, 5); + client.Publish(TOPIC_OUTSIDETEMPERATURE, rawData, 5, true); memcpy(temperatureDataToCompare, rawData, 5); } if(!outsideTemperatureWasSet) From 3777d8d2b77e958daaa51ca1ecc9a4ee262ed8ee Mon Sep 17 00:00:00 2001 From: Zefek <32429493+Zefek@users.noreply.github.com> Date: Tue, 26 May 2026 17:25:11 +0200 Subject: [PATCH 4/6] Remove retain flag from outside temperature publish --- HeatingTemperatureRegulator.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HeatingTemperatureRegulator.ino b/HeatingTemperatureRegulator.ino index 82a632f..ba0f44c 100644 --- a/HeatingTemperatureRegulator.ino +++ b/HeatingTemperatureRegulator.ino @@ -421,7 +421,7 @@ void OutsideTemperatureChanged(double temperature, uint8_t channel, uint8_t sens outsideTemperature = temperature; if (memcmp(rawData, temperatureDataToCompare, 5) != 0) { - client.Publish(TOPIC_OUTSIDETEMPERATURE, rawData, 5, true); + client.Publish(TOPIC_OUTSIDETEMPERATURE, rawData, 5); memcpy(temperatureDataToCompare, rawData, 5); } if(!outsideTemperatureWasSet) From 83e12c1232e9943f1bdc2121c502ca4eaa811087 Mon Sep 17 00:00:00 2001 From: Zefek <32429493+Zefek@users.noreply.github.com> Date: Wed, 27 May 2026 15:20:10 +0200 Subject: [PATCH 5/6] Update HeatingTemperatureRegulator.ino --- HeatingTemperatureRegulator.ino | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/HeatingTemperatureRegulator.ino b/HeatingTemperatureRegulator.ino index ba0f44c..abf7ebe 100644 --- a/HeatingTemperatureRegulator.ino +++ b/HeatingTemperatureRegulator.ino @@ -112,7 +112,6 @@ FVEData currentFveData; DiagData currentDiagData; BelData belData; -uint8_t temperatureDataToCompare[5]; Display lcd(I2C_ADDR, LCD_COLUMNS, LCD_LINES); Ds1302 rtc(4, 5, 6); TX07KTXC outsideTemperatureSensor(2, 3, OutsideTemperatureChanged); @@ -419,11 +418,7 @@ void OutsideTemperatureChanged(double temperature, uint8_t channel, uint8_t sens if(channel == 1 && sensrId == sensorId) { outsideTemperature = temperature; - if (memcmp(rawData, temperatureDataToCompare, 5) != 0) - { - client.Publish(TOPIC_OUTSIDETEMPERATURE, rawData, 5); - memcpy(temperatureDataToCompare, rawData, 5); - } + client.Publish(TOPIC_OUTSIDETEMPERATURE, rawData, 5); if(!outsideTemperatureWasSet) { outsideTemperatureAverage = temperature; From 434dad30a8d2871ec00d794c78eca6803a0f37d6 Mon Sep 17 00:00:00 2001 From: Zefek Date: Fri, 29 May 2026 15:07:46 +0200 Subject: [PATCH 6/6] =?UTF-8?q?=C3=9Apravy=20zobrazen=C3=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- HeatingTemperatureRegulator.ino | 52 ++++++++++++++++++--------------- config_default.h | 6 ++++ display.cpp | 32 +++++++++++--------- display.h | 3 +- docs/PARAMETERS.md | 2 +- 5 files changed, 56 insertions(+), 39 deletions(-) diff --git a/HeatingTemperatureRegulator.ino b/HeatingTemperatureRegulator.ino index abf7ebe..33613f9 100644 --- a/HeatingTemperatureRegulator.ino +++ b/HeatingTemperatureRegulator.ino @@ -18,10 +18,6 @@ #define HEATINGPUMPRELAYPIN 10 #define HEATERWASTEGASTHERMOSTATPIN 11 #define ONEWIREBUSPIN 7 -#define SERVOMAXRANGE 70000 //Časový interval pohybu serva mezi krajními hodnotami -#define SERVO1PC 700L //Jedno procento z intervalu serva -#define MINSERVOINTERVAL 700 //Minimální interval pro aktivaci serva -#define AVGOUTTEMPVALUES 180 //Počet hodnot pro výpočet průměrné venkovní teploty (počet minut) #define FASTAVGALPHA 0.3 #define SLOWAVGALPHA 0.035 @@ -64,6 +60,7 @@ void convertToHalfByte(int value, uint8_t* result, uint8_t length) 19 - averageOutsideTemperature B2 20 - averageOutsideTemperature B3 (MSB) 21 - heatermode +22 - flame */ #pragma pack(push, 1) struct HeaterState { @@ -141,7 +138,6 @@ bool relayOn = false; int8_t direction = 0; double outsideTemperature = 14; double outsideTemperatureAverage = 0; -int sensor = 1; bool thermostat = false; uint8_t sensrId = 0; int lastCurrentTemp = 0; @@ -155,6 +151,7 @@ unsigned long mqttConnectionTimeout = 0; unsigned long mqttLastConnectionTry = 0; bool shouldHeatingBeOnByTemperature = false; bool outsideTemperatureWasSet = false; +unsigned long lastOutsideTemperatureMillis = 0; bool fveOnlineSent = false; bool fveOfflineSent = false; unsigned long fastReadMillis = 0; @@ -212,7 +209,6 @@ void setup() { ComputeWasteGasTemperature(); ComputeSlowWasteGasTemperature(); lcd.SetWasteGasTemperature(averageWasteGasTemperature); - ComputeOutsideTemperatureAverage(); lcd.EndInitialize(); convertToHalfByte(999, currentState.outsideAvgTemp, 4); resetServo = true; @@ -419,11 +415,32 @@ void OutsideTemperatureChanged(double temperature, uint8_t channel, uint8_t sens { outsideTemperature = temperature; client.Publish(TOPIC_OUTSIDETEMPERATURE, rawData, 5); + + //Časově vážený průměr pro ekviterm. Váha čerstvého čtení roste s dobou od + //posledního příjmu => krátké nepravidelné mezery i výpadek se zohlední samy. + double oldAverage = outsideTemperatureAverage; if(!outsideTemperatureWasSet) { - outsideTemperatureAverage = temperature; + outsideTemperatureAverage = temperature; //první čtení = nasazení + } + else + { + double elapsedMin = (currentMillis - lastOutsideTemperatureMillis) / 60000.0; + if(elapsedMin > 0) + { + double alpha = 1.0 - exp(-elapsedMin / OUTSIDEAVGTAU); + outsideTemperatureAverage = constrain(alpha * temperature + (1 - alpha) * outsideTemperatureAverage, -50, 50); + } } + if(oldAverage != outsideTemperatureAverage) + { + int T = (int)(outsideTemperatureAverage * 10); + convertToHalfByte(T, currentState.outsideAvgTemp, 4); + } + + lastOutsideTemperatureMillis = currentMillis; outsideTemperatureWasSet = true; + lcd.SetOutTemperature(temperature); } } @@ -458,22 +475,6 @@ void computeRequiredTemperature() } } -void ComputeOutsideTemperatureAverage() -{ - if(!outsideTemperatureWasSet) - { - return; - } - double oldAverage = outsideTemperatureAverage; - double alpha = 1.0 / 180.0; - outsideTemperatureAverage = constrain(alpha * outsideTemperature + (1 - alpha) * outsideTemperatureAverage, -50, 50); - if(oldAverage != outsideTemperatureAverage) - { - int T = (int)(outsideTemperatureAverage * 10); - convertToHalfByte(T, currentState.outsideAvgTemp, 4); - } -} - void ComputeSlowWasteGasTemperature() { int previousWasteGasTemperature = (int)slowAverageWasteGasTemperature; @@ -710,7 +711,6 @@ void sendToHomeAssistant() { if(sendIndex == 0) { - ComputeOutsideTemperatureAverage(); computeRequiredTemperature(); sendHeaterToHomeAssistant(); sendIndex = 1; @@ -861,6 +861,10 @@ void loop() { resetServo = false; } outsideTemperatureSensor.CheckTemperature(); + if(outsideTemperatureWasSet && currentMillis - lastOutsideTemperatureMillis > OUTSIDETEMPERATURETIMEOUT) + { + lcd.SetOutTemperatureNotSet(); + } belWattmeter.Loop(); if(currentMillis - fastReadMillis > 50) { diff --git a/config_default.h b/config_default.h index b262fbc..cc55c7b 100644 --- a/config_default.h +++ b/config_default.h @@ -19,6 +19,12 @@ #define OVERHEATINGTEMPERATURE 0 #define MININPUTTEMPERATURE 0 #define MAXIMALSERVOSTEP 3 +#define SERVOMAXRANGE 70000 //Časový interval pohybu serva mezi krajními hodnotami +#define SERVO1PC 700L //Jedno procento z intervalu serva +#define MINSERVOINTERVAL 700 //Minimální interval pro aktivaci serva +#define OUTSIDEAVGTAU 180.0 //Časová konstanta průměru venkovní teploty [min] (≈ původní 1/180) +#define OUTSIDETEMPERATURETIMEOUT 600000UL //Po této době bez dat ze snímače [ms] => na displeji --.- + #define HeaterOn(ht, wgt) false #define HeaterOff(ht, wgt) false diff --git a/display.cpp b/display.cpp index 2307eb0..6865f66 100644 --- a/display.cpp +++ b/display.cpp @@ -33,12 +33,12 @@ } } - void Display::printOutTemperature(bool blink) + void Display::printOutTemperature() { - if(blink) + lcd->setCursor(10, 1); + if(!outsideTemperatureWasSet) { - lcd->setCursor(10, 1); - lcd->print(" "); + lcd->print(" --.-"); } else { @@ -58,8 +58,8 @@ lcd->print(" "); } lcd->print(outTemperature, 1); - lcd->write((byte)1); } + lcd->write((byte)1); } Display::Display(uint8_t lcd_Addr,uint8_t lcd_cols,uint8_t lcd_rows) @@ -102,15 +102,25 @@ void Display::SetOutTemperature(double outTemperature) { + outsideTemperatureWasSet = true; if(this->outTemperature != outTemperature || forcePrint) { this->outTemperature = outTemperature; if(!initializing) { - printOutTemperature(false); + printOutTemperature(); } } - outsideTemperatureWasSet = true; + } + + void Display::SetOutTemperatureNotSet() + { + if(!outsideTemperatureWasSet) + { + return; + } + outsideTemperatureWasSet = false; + printOutTemperature(); } void Display::SetWasteGasTemperature(int wasteGasTemperature) @@ -246,10 +256,6 @@ lcd->write((byte)3); } } - if(!outsideTemperatureWasSet) - { - printOutTemperature(shouldBlink); - } if(mode == 2 && !thermostat) { PrintMode(mode, shouldBlink); @@ -282,7 +288,7 @@ forcePrint = true; lcd->clear(); SetRequiredTemperature(this->requiredTemperature); - SetOutTemperature(this->outTemperature); + printOutTemperature(); SetWasteGasTemperature(this->wasteGasTemperature); SetInputTemperature(this->inputTemperature); SetCurrentHeatingTemperature(this->currentHeatingTemperature); @@ -307,4 +313,4 @@ } } } - } \ No newline at end of file + } diff --git a/display.h b/display.h index a6e4660..4dfdf10 100644 --- a/display.h +++ b/display.h @@ -51,7 +51,7 @@ class Display void print2digits(uint8_t number); void printTime(); - void printOutTemperature(bool blink); + void printOutTemperature(); void Blink(); void PrintMode(uint8_t mode, bool blink); @@ -69,4 +69,5 @@ class Display void SetThermostat(bool thermostat); void EndInitialize(); void SetHeater(bool heaterOn); + void SetOutTemperatureNotSet(); }; \ No newline at end of file diff --git a/docs/PARAMETERS.md b/docs/PARAMETERS.md index c385d3d..a5c54a2 100644 --- a/docs/PARAMETERS.md +++ b/docs/PARAMETERS.md @@ -20,7 +20,7 @@ | `TOPIC_CURRENTDATETIEM` | IN | Synchronizace času ve formátu `YYYY-MM-DD HH:MM:SS` | | `TOPIC_THERMOSTATSETCHANGED` | IN | Požadovaná vnitřní teplota z termostatu (float) | | `TOPIC_OUTSIDETEMPERATURE` | OUT | Surová data z venkovního čidla (hex-encoded 5 bajtů) | -| `TOPIC_HEATERSTATE` | OUT | Binární paket `HeaterState` (22 bajtů) se stavem regulátoru | +| `TOPIC_HEATERSTATE` | OUT | Binární paket `HeaterState` (23 bajtů) se stavem regulátoru | | `TOPIC_FVE` | OUT | **Volitelný** — binární paket `FVEData` (16 bajtů) s daty z wattmetru | | `TOPIC_FVE_STATE` | OUT | **Volitelný** — stav FVE (`Online` / `Offline`) |