mirror of
https://github.com/Laxilef/OTGateway.git
synced 2025-12-11 10:44:29 +05:00
feat: added fault state GPIO setting
This commit is contained in:
@@ -30,6 +30,8 @@ protected:
|
|||||||
unsigned long dhwSetTempTime = 0;
|
unsigned long dhwSetTempTime = 0;
|
||||||
unsigned long heatingSetTempTime = 0;
|
unsigned long heatingSetTempTime = 0;
|
||||||
byte configuredRxLedGpio = GPIO_IS_NOT_CONFIGURED;
|
byte configuredRxLedGpio = GPIO_IS_NOT_CONFIGURED;
|
||||||
|
byte configuredFaultStateGpio = GPIO_IS_NOT_CONFIGURED;
|
||||||
|
bool faultState = false;
|
||||||
|
|
||||||
|
|
||||||
const char* getTaskName() {
|
const char* getTaskName() {
|
||||||
@@ -116,6 +118,7 @@ protected:
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RX LED GPIO setup
|
||||||
if (settings.opentherm.rxLedGpio != this->configuredRxLedGpio) {
|
if (settings.opentherm.rxLedGpio != this->configuredRxLedGpio) {
|
||||||
if (this->configuredRxLedGpio != GPIO_IS_NOT_CONFIGURED) {
|
if (this->configuredRxLedGpio != GPIO_IS_NOT_CONFIGURED) {
|
||||||
digitalWrite(this->configuredRxLedGpio, LOW);
|
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 heatingEnabled = (vars.states.emergency || settings.heating.enable) && this->pump && this->isReady();
|
||||||
bool heatingCh2Enabled = settings.opentherm.heatingCh2Enabled;
|
bool heatingCh2Enabled = settings.opentherm.heatingCh2Enabled;
|
||||||
if (settings.opentherm.heatingCh1ToCh2) {
|
if (settings.opentherm.heatingCh1ToCh2) {
|
||||||
@@ -174,6 +198,16 @@ protected:
|
|||||||
vars.states.fault = false;
|
vars.states.fault = false;
|
||||||
vars.states.diagnostic = 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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -199,6 +233,16 @@ protected:
|
|||||||
vars.states.fault = CustomOpenTherm::isFault(response);
|
vars.states.fault = CustomOpenTherm::isFault(response);
|
||||||
vars.states.diagnostic = CustomOpenTherm::isDiagnostic(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
|
// These parameters will be updated every minute
|
||||||
if (millis() - this->prevUpdateNonEssentialVars > 60000) {
|
if (millis() - this->prevUpdateNonEssentialVars > 60000) {
|
||||||
if (!heatingEnabled && settings.opentherm.modulationSyncWithHeating) {
|
if (!heatingEnabled && settings.opentherm.modulationSyncWithHeating) {
|
||||||
@@ -286,6 +330,9 @@ protected:
|
|||||||
// Get fault code (if necessary)
|
// Get fault code (if necessary)
|
||||||
if (vars.states.fault) {
|
if (vars.states.fault) {
|
||||||
updateFaultCode();
|
updateFaultCode();
|
||||||
|
|
||||||
|
} else if (vars.sensors.faultCode != 0) {
|
||||||
|
vars.sensors.faultCode = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
updatePressure();
|
updatePressure();
|
||||||
|
|||||||
@@ -51,6 +51,8 @@ struct Settings {
|
|||||||
byte inGpio = DEFAULT_OT_IN_GPIO;
|
byte inGpio = DEFAULT_OT_IN_GPIO;
|
||||||
byte outGpio = DEFAULT_OT_OUT_GPIO;
|
byte outGpio = DEFAULT_OT_OUT_GPIO;
|
||||||
byte rxLedGpio = DEFAULT_OT_RX_LED_GPIO;
|
byte rxLedGpio = DEFAULT_OT_RX_LED_GPIO;
|
||||||
|
byte faultStateGpio = DEFAULT_OT_FAULT_STATE_GPIO;
|
||||||
|
byte invertFaultState = false;
|
||||||
unsigned int memberIdCode = 0;
|
unsigned int memberIdCode = 0;
|
||||||
bool dhwPresent = true;
|
bool dhwPresent = true;
|
||||||
bool summerWinterMode = false;
|
bool summerWinterMode = false;
|
||||||
|
|||||||
@@ -103,6 +103,10 @@
|
|||||||
#define DEFAULT_OT_RX_LED_GPIO GPIO_IS_NOT_CONFIGURED
|
#define DEFAULT_OT_RX_LED_GPIO GPIO_IS_NOT_CONFIGURED
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef DEFAULT_OT_FAULT_STATE_GPIO
|
||||||
|
#define DEFAULT_OT_FAULT_STATE_GPIO GPIO_IS_NOT_CONFIGURED
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef DEFAULT_SENSOR_OUTDOOR_GPIO
|
#ifndef DEFAULT_SENSOR_OUTDOOR_GPIO
|
||||||
#define DEFAULT_SENSOR_OUTDOOR_GPIO GPIO_IS_NOT_CONFIGURED
|
#define DEFAULT_SENSOR_OUTDOOR_GPIO GPIO_IS_NOT_CONFIGURED
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
36
src/utils.h
36
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"]["inGpio"] = src.opentherm.inGpio;
|
||||||
dst["opentherm"]["outGpio"] = src.opentherm.outGpio;
|
dst["opentherm"]["outGpio"] = src.opentherm.outGpio;
|
||||||
dst["opentherm"]["rxLedGpio"] = src.opentherm.rxLedGpio;
|
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"]["memberIdCode"] = src.opentherm.memberIdCode;
|
||||||
dst["opentherm"]["dhwPresent"] = src.opentherm.dhwPresent;
|
dst["opentherm"]["dhwPresent"] = src.opentherm.dhwPresent;
|
||||||
dst["opentherm"]["summerWinterMode"] = src.opentherm.summerWinterMode;
|
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()) {
|
if (!src["opentherm"]["memberIdCode"].isNull()) {
|
||||||
unsigned int value = src["opentherm"]["memberIdCode"].as<unsigned int>();
|
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>()) {
|
if (src["opentherm"]["dhwPresent"].is<bool>()) {
|
||||||
dst.opentherm.dhwPresent = src["opentherm"]["dhwPresent"].as<bool>();
|
bool value = src["opentherm"]["dhwPresent"].as<bool>();
|
||||||
changed = true;
|
|
||||||
|
if (value != dst.opentherm.dhwPresent) {
|
||||||
|
dst.opentherm.dhwPresent = value;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (src["opentherm"]["summerWinterMode"].is<bool>()) {
|
if (src["opentherm"]["summerWinterMode"].is<bool>()) {
|
||||||
|
|||||||
@@ -435,6 +435,20 @@
|
|||||||
<input type="checkbox" id="opentherm-get-min-max-temp" name="opentherm[getMinMaxTemp]" value="true">
|
<input type="checkbox" id="opentherm-get-min-max-temp" name="opentherm[getMinMaxTemp]" value="true">
|
||||||
Get min/max temp from boiler
|
Get min/max temp from boiler
|
||||||
</label>
|
</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 />
|
<hr />
|
||||||
<label for="opentherm-native-heating-control">
|
<label for="opentherm-native-heating-control">
|
||||||
@@ -680,6 +694,8 @@
|
|||||||
setInputValue('#opentherm-in-gpio', data.opentherm.inGpio < 255 ? data.opentherm.inGpio : '');
|
setInputValue('#opentherm-in-gpio', data.opentherm.inGpio < 255 ? data.opentherm.inGpio : '');
|
||||||
setInputValue('#opentherm-out-gpio', data.opentherm.outGpio < 255 ? data.opentherm.outGpio : '');
|
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-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);
|
setInputValue('#opentherm-member-id-code', data.opentherm.memberIdCode);
|
||||||
setCheckboxValue('#opentherm-dhw-present', data.opentherm.dhwPresent);
|
setCheckboxValue('#opentherm-dhw-present', data.opentherm.dhwPresent);
|
||||||
setCheckboxValue('#opentherm-sw-mode', data.opentherm.summerWinterMode);
|
setCheckboxValue('#opentherm-sw-mode', data.opentherm.summerWinterMode);
|
||||||
|
|||||||
Reference in New Issue
Block a user