feat: added fault state GPIO setting

This commit is contained in:
Yurii
2024-05-25 02:51:10 +03:00
parent 935f8bd0a8
commit a825412f37
5 changed files with 103 additions and 2 deletions

View File

@@ -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();

View File

@@ -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;

View File

@@ -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

View File

@@ -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<JsonString>() && src["opentherm"]["faultStateGpio"].as<JsonString>().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<unsigned char>();
if (GPIO_IS_VALID(value) && value != dst.opentherm.faultStateGpio) {
dst.opentherm.faultStateGpio = value;
changed = true;
}
}
}
if (src["opentherm"]["invertFaultState"].is<bool>()) {
bool value = src["opentherm"]["invertFaultState"].as<bool>();
if (value != dst.opentherm.invertFaultState) {
dst.opentherm.invertFaultState = value;
changed = true;
}
}
if (!src["opentherm"]["memberIdCode"].isNull()) {
unsigned int value = src["opentherm"]["memberIdCode"].as<unsigned int>();
@@ -652,8 +680,12 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false
}
if (src["opentherm"]["dhwPresent"].is<bool>()) {
dst.opentherm.dhwPresent = src["opentherm"]["dhwPresent"].as<bool>();
changed = true;
bool value = src["opentherm"]["dhwPresent"].as<bool>();
if (value != dst.opentherm.dhwPresent) {
dst.opentherm.dhwPresent = value;
changed = true;
}
}
if (src["opentherm"]["summerWinterMode"].is<bool>()) {

View File

@@ -435,6 +435,20 @@
<input type="checkbox" id="opentherm-get-min-max-temp" name="opentherm[getMinMaxTemp]" value="true">
Get min/max temp from boiler
</label>
<hr />
<fieldset>
<label for="opentherm-fault-state-gpio">
Fault state GPIO
<input type="number" inputmode="numeric" id="opentherm-fault-state-gpio" name="opentherm[faultStateGpio]" min="0" max="254" step="1">
<small>Can be useful to switch on another boiler <u>via relay</u>. Blank - not use.</small>
</label>
<label for="opentherm-invert-fault-state">
<input type="checkbox" id="opentherm-invert-fault-state" name="opentherm[invertFaultState]" value="true">
Invert fault state
</label>
</fieldset>
<hr />
<label for="opentherm-native-heating-control">
@@ -680,6 +694,8 @@
setInputValue('#opentherm-in-gpio', data.opentherm.inGpio < 255 ? data.opentherm.inGpio : '');
setInputValue('#opentherm-out-gpio', data.opentherm.outGpio < 255 ? data.opentherm.outGpio : '');
setInputValue('#opentherm-rx-led-gpio', data.opentherm.rxLedGpio < 255 ? data.opentherm.rxLedGpio : '');
setInputValue('#opentherm-fault-state-gpio', data.opentherm.faultStateGpio < 255 ? data.opentherm.faultStateGpio : '');
setCheckboxValue('#opentherm-invert-fault-state', data.opentherm.invertFaultState);
setInputValue('#opentherm-member-id-code', data.opentherm.memberIdCode);
setCheckboxValue('#opentherm-dhw-present', data.opentherm.dhwPresent);
setCheckboxValue('#opentherm-sw-mode', data.opentherm.summerWinterMode);