From a825412f37b53f03029a482e40eb0c261cafd601 Mon Sep 17 00:00:00 2001 From: Yurii Date: Sat, 25 May 2024 02:51:10 +0300 Subject: [PATCH] feat: added fault state GPIO setting --- src/OpenThermTask.h | 47 ++++++++++++++++++++++++++++++++++++++++++ src/Settings.h | 2 ++ src/defines.h | 4 ++++ src/utils.h | 36 ++++++++++++++++++++++++++++++-- src_data/settings.html | 16 ++++++++++++++ 5 files changed, 103 insertions(+), 2 deletions(-) diff --git a/src/OpenThermTask.h b/src/OpenThermTask.h index a283d8b..e3ba2d9 100644 --- a/src/OpenThermTask.h +++ b/src/OpenThermTask.h @@ -30,6 +30,8 @@ protected: unsigned long dhwSetTempTime = 0; unsigned long heatingSetTempTime = 0; byte configuredRxLedGpio = GPIO_IS_NOT_CONFIGURED; + byte configuredFaultStateGpio = GPIO_IS_NOT_CONFIGURED; + bool faultState = false; const char* getTaskName() { @@ -116,6 +118,7 @@ protected: return; } + // RX LED GPIO setup if (settings.opentherm.rxLedGpio != this->configuredRxLedGpio) { if (this->configuredRxLedGpio != GPIO_IS_NOT_CONFIGURED) { digitalWrite(this->configuredRxLedGpio, LOW); @@ -131,6 +134,27 @@ protected: } } + // Fault state setup + if (settings.opentherm.faultStateGpio != this->configuredFaultStateGpio) { + if (this->configuredFaultStateGpio != GPIO_IS_NOT_CONFIGURED) { + digitalWrite(this->configuredFaultStateGpio, LOW); + } + + if (GPIO_IS_VALID(settings.opentherm.faultStateGpio)) { + this->configuredFaultStateGpio = settings.opentherm.faultStateGpio; + this->faultState = false ^ settings.opentherm.invertFaultState ? HIGH : LOW; + + pinMode(this->configuredFaultStateGpio, OUTPUT); + digitalWrite( + this->configuredFaultStateGpio, + this->faultState + ); + + } else if (this->configuredFaultStateGpio != GPIO_IS_NOT_CONFIGURED) { + this->configuredFaultStateGpio = GPIO_IS_NOT_CONFIGURED; + } + } + bool heatingEnabled = (vars.states.emergency || settings.heating.enable) && this->pump && this->isReady(); bool heatingCh2Enabled = settings.opentherm.heatingCh2Enabled; if (settings.opentherm.heatingCh1ToCh2) { @@ -174,6 +198,16 @@ protected: vars.states.fault = false; vars.states.diagnostic = false; + // Force fault state = on + if (this->configuredFaultStateGpio != GPIO_IS_NOT_CONFIGURED) { + bool fState = true ^ settings.opentherm.invertFaultState ? HIGH : LOW; + + if (fState != this->faultState) { + this->faultState = fState; + digitalWrite(this->configuredFaultStateGpio, this->faultState); + } + } + return; } @@ -199,6 +233,16 @@ protected: vars.states.fault = CustomOpenTherm::isFault(response); vars.states.diagnostic = CustomOpenTherm::isDiagnostic(response); + // Fault state + if (this->configuredFaultStateGpio != GPIO_IS_NOT_CONFIGURED) { + bool fState = vars.states.fault ^ settings.opentherm.invertFaultState ? HIGH : LOW; + + if (fState != this->faultState) { + this->faultState = fState; + digitalWrite(this->configuredFaultStateGpio, this->faultState); + } + } + // These parameters will be updated every minute if (millis() - this->prevUpdateNonEssentialVars > 60000) { if (!heatingEnabled && settings.opentherm.modulationSyncWithHeating) { @@ -286,6 +330,9 @@ protected: // Get fault code (if necessary) if (vars.states.fault) { updateFaultCode(); + + } else if (vars.sensors.faultCode != 0) { + vars.sensors.faultCode = 0; } updatePressure(); diff --git a/src/Settings.h b/src/Settings.h index e968845..f2046d6 100644 --- a/src/Settings.h +++ b/src/Settings.h @@ -51,6 +51,8 @@ struct Settings { byte inGpio = DEFAULT_OT_IN_GPIO; byte outGpio = DEFAULT_OT_OUT_GPIO; byte rxLedGpio = DEFAULT_OT_RX_LED_GPIO; + byte faultStateGpio = DEFAULT_OT_FAULT_STATE_GPIO; + byte invertFaultState = false; unsigned int memberIdCode = 0; bool dhwPresent = true; bool summerWinterMode = false; diff --git a/src/defines.h b/src/defines.h index 7b7172f..ba2af9a 100644 --- a/src/defines.h +++ b/src/defines.h @@ -103,6 +103,10 @@ #define DEFAULT_OT_RX_LED_GPIO GPIO_IS_NOT_CONFIGURED #endif +#ifndef DEFAULT_OT_FAULT_STATE_GPIO + #define DEFAULT_OT_FAULT_STATE_GPIO GPIO_IS_NOT_CONFIGURED +#endif + #ifndef DEFAULT_SENSOR_OUTDOOR_GPIO #define DEFAULT_SENSOR_OUTDOOR_GPIO GPIO_IS_NOT_CONFIGURED #endif diff --git a/src/utils.h b/src/utils.h index 637dea1..4876fcc 100644 --- a/src/utils.h +++ b/src/utils.h @@ -342,6 +342,8 @@ void settingsToJson(const Settings& src, JsonVariant dst, bool safe = false) { dst["opentherm"]["inGpio"] = src.opentherm.inGpio; dst["opentherm"]["outGpio"] = src.opentherm.outGpio; dst["opentherm"]["rxLedGpio"] = src.opentherm.rxLedGpio; + dst["opentherm"]["faultStateGpio"] = src.opentherm.faultStateGpio; + dst["opentherm"]["invertFaultState"] = src.opentherm.invertFaultState; dst["opentherm"]["memberIdCode"] = src.opentherm.memberIdCode; dst["opentherm"]["dhwPresent"] = src.opentherm.dhwPresent; dst["opentherm"]["summerWinterMode"] = src.opentherm.summerWinterMode; @@ -642,6 +644,32 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false } } + if (!src["opentherm"]["faultStateGpio"].isNull()) { + if (src["opentherm"]["faultStateGpio"].is() && src["opentherm"]["faultStateGpio"].as().size() == 0) { + if (dst.opentherm.faultStateGpio != GPIO_IS_NOT_CONFIGURED) { + dst.opentherm.faultStateGpio = GPIO_IS_NOT_CONFIGURED; + changed = true; + } + + } else { + unsigned char value = src["opentherm"]["faultStateGpio"].as(); + + if (GPIO_IS_VALID(value) && value != dst.opentherm.faultStateGpio) { + dst.opentherm.faultStateGpio = value; + changed = true; + } + } + } + + if (src["opentherm"]["invertFaultState"].is()) { + bool value = src["opentherm"]["invertFaultState"].as(); + + if (value != dst.opentherm.invertFaultState) { + dst.opentherm.invertFaultState = value; + changed = true; + } + } + if (!src["opentherm"]["memberIdCode"].isNull()) { unsigned int value = src["opentherm"]["memberIdCode"].as(); @@ -652,8 +680,12 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false } if (src["opentherm"]["dhwPresent"].is()) { - dst.opentherm.dhwPresent = src["opentherm"]["dhwPresent"].as(); - changed = true; + bool value = src["opentherm"]["dhwPresent"].as(); + + if (value != dst.opentherm.dhwPresent) { + dst.opentherm.dhwPresent = value; + changed = true; + } } if (src["opentherm"]["summerWinterMode"].is()) { diff --git a/src_data/settings.html b/src_data/settings.html index e270292..2fb9b9e 100644 --- a/src_data/settings.html +++ b/src_data/settings.html @@ -435,6 +435,20 @@ Get min/max temp from boiler + +
+
+ + + +