mirror of
https://github.com/Laxilef/OTGateway.git
synced 2025-12-11 02:34:29 +05:00
feat: fault state gpio setting replaced with cascade control
This commit is contained in:
165
src/MainTask.h
165
src/MainTask.h
@@ -119,6 +119,7 @@ protected:
|
||||
|
||||
this->emergency();
|
||||
this->ledStatus();
|
||||
this->cascadeControl();
|
||||
this->externalPump();
|
||||
this->yield();
|
||||
|
||||
@@ -336,6 +337,170 @@ protected:
|
||||
this->blinker->tick();
|
||||
}
|
||||
|
||||
void cascadeControl() {
|
||||
static uint8_t configuredInputGpio = GPIO_IS_NOT_CONFIGURED;
|
||||
static uint8_t configuredOutputGpio = GPIO_IS_NOT_CONFIGURED;
|
||||
static bool inputTempValue = false;
|
||||
static unsigned long inputChangedTs = 0;
|
||||
static bool outputTempValue = false;
|
||||
static unsigned long outputChangedTs = 0;
|
||||
|
||||
// input
|
||||
if (settings.cascadeControl.input.enable) {
|
||||
if (settings.cascadeControl.input.gpio != configuredInputGpio) {
|
||||
if (configuredInputGpio != GPIO_IS_NOT_CONFIGURED) {
|
||||
pinMode(configuredInputGpio, OUTPUT);
|
||||
digitalWrite(configuredInputGpio, LOW);
|
||||
|
||||
Log.sinfoln(FPSTR(L_CASCADE_INPUT), F("Deinitialized on GPIO %hhu"), configuredInputGpio);
|
||||
}
|
||||
|
||||
if (GPIO_IS_VALID(settings.cascadeControl.input.gpio)) {
|
||||
configuredInputGpio = settings.cascadeControl.input.gpio;
|
||||
pinMode(configuredInputGpio, INPUT);
|
||||
|
||||
Log.sinfoln(FPSTR(L_CASCADE_INPUT), F("Initialized on GPIO %hhu"), configuredInputGpio);
|
||||
|
||||
} else if (configuredInputGpio != GPIO_IS_NOT_CONFIGURED) {
|
||||
configuredInputGpio = GPIO_IS_NOT_CONFIGURED;
|
||||
|
||||
Log.swarningln(FPSTR(L_CASCADE_INPUT), F("Failed initialize: GPIO %hhu is not valid!"), configuredInputGpio);
|
||||
}
|
||||
}
|
||||
|
||||
if (configuredInputGpio != GPIO_IS_NOT_CONFIGURED) {
|
||||
bool value;
|
||||
if (digitalRead(configuredInputGpio) == HIGH) {
|
||||
value = true ^ settings.cascadeControl.input.invertState;
|
||||
} else {
|
||||
value = false ^ settings.cascadeControl.input.invertState;
|
||||
}
|
||||
|
||||
if (value != vars.cascadeControl.input) {
|
||||
if (value != inputTempValue) {
|
||||
inputTempValue = value;
|
||||
inputChangedTs = millis();
|
||||
|
||||
} else if (millis() - inputChangedTs >= settings.cascadeControl.input.thresholdTime * 1000u) {
|
||||
vars.cascadeControl.input = value;
|
||||
|
||||
Log.sinfoln(
|
||||
FPSTR(L_CASCADE_INPUT),
|
||||
F("State changed to %s"),
|
||||
value ? F("TRUE") : F("FALSE")
|
||||
);
|
||||
}
|
||||
|
||||
} else if (value != inputTempValue) {
|
||||
inputTempValue = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!settings.cascadeControl.input.enable || configuredInputGpio == GPIO_IS_NOT_CONFIGURED) {
|
||||
if (!vars.cascadeControl.input) {
|
||||
vars.cascadeControl.input = true;
|
||||
|
||||
Log.sinfoln(
|
||||
FPSTR(L_CASCADE_INPUT),
|
||||
F("Disabled, state changed to %s"),
|
||||
vars.cascadeControl.input ? F("TRUE") : F("FALSE")
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// output
|
||||
if (settings.cascadeControl.output.enable) {
|
||||
if (settings.cascadeControl.output.gpio != configuredOutputGpio) {
|
||||
if (configuredOutputGpio != GPIO_IS_NOT_CONFIGURED) {
|
||||
pinMode(configuredOutputGpio, OUTPUT);
|
||||
digitalWrite(configuredOutputGpio, LOW);
|
||||
|
||||
Log.sinfoln(FPSTR(L_CASCADE_OUTPUT), F("Deinitialized on GPIO %hhu"), configuredOutputGpio);
|
||||
}
|
||||
|
||||
if (GPIO_IS_VALID(settings.cascadeControl.output.gpio)) {
|
||||
configuredOutputGpio = settings.cascadeControl.output.gpio;
|
||||
pinMode(configuredOutputGpio, OUTPUT);
|
||||
digitalWrite(
|
||||
configuredOutputGpio,
|
||||
settings.cascadeControl.output.invertState
|
||||
? HIGH
|
||||
: LOW
|
||||
);
|
||||
|
||||
Log.sinfoln(FPSTR(L_CASCADE_OUTPUT), F("Initialized on GPIO %hhu"), configuredOutputGpio);
|
||||
|
||||
} else if (configuredOutputGpio != GPIO_IS_NOT_CONFIGURED) {
|
||||
configuredOutputGpio = GPIO_IS_NOT_CONFIGURED;
|
||||
|
||||
Log.swarningln(FPSTR(L_CASCADE_OUTPUT), F("Failed initialize: GPIO %hhu is not valid!"), configuredOutputGpio);
|
||||
}
|
||||
}
|
||||
|
||||
if (configuredOutputGpio != GPIO_IS_NOT_CONFIGURED) {
|
||||
bool value = false;
|
||||
if (settings.cascadeControl.output.onFault && vars.states.fault) {
|
||||
value = true;
|
||||
|
||||
} else if (settings.cascadeControl.output.onLossConnection && !vars.states.otStatus) {
|
||||
value = true;
|
||||
|
||||
} else if (settings.cascadeControl.output.onEnabledHeating && settings.heating.enable && vars.cascadeControl.input) {
|
||||
value = true;
|
||||
}
|
||||
|
||||
if (value != vars.cascadeControl.output) {
|
||||
if (value != outputTempValue) {
|
||||
outputTempValue = value;
|
||||
outputChangedTs = millis();
|
||||
|
||||
} else if (millis() - outputChangedTs >= settings.cascadeControl.output.thresholdTime * 1000u) {
|
||||
vars.cascadeControl.output = value;
|
||||
|
||||
digitalWrite(
|
||||
configuredOutputGpio,
|
||||
vars.cascadeControl.output ^ settings.cascadeControl.output.invertState
|
||||
? HIGH
|
||||
: LOW
|
||||
);
|
||||
|
||||
Log.sinfoln(
|
||||
FPSTR(L_CASCADE_OUTPUT),
|
||||
F("State changed to %s"),
|
||||
value ? F("TRUE") : F("FALSE")
|
||||
);
|
||||
}
|
||||
|
||||
} else if (value != outputTempValue) {
|
||||
outputTempValue = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!settings.cascadeControl.output.enable || configuredOutputGpio == GPIO_IS_NOT_CONFIGURED) {
|
||||
if (vars.cascadeControl.output) {
|
||||
vars.cascadeControl.output = false;
|
||||
|
||||
if (configuredOutputGpio != GPIO_IS_NOT_CONFIGURED) {
|
||||
digitalWrite(
|
||||
configuredOutputGpio,
|
||||
vars.cascadeControl.output ^ settings.cascadeControl.output.invertState
|
||||
? HIGH
|
||||
: LOW
|
||||
);
|
||||
}
|
||||
|
||||
Log.sinfoln(
|
||||
FPSTR(L_CASCADE_OUTPUT),
|
||||
F("Disabled, state changed to %s"),
|
||||
vars.cascadeControl.output ? F("TRUE") : F("FALSE")
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void externalPump() {
|
||||
static uint8_t configuredGpio = GPIO_IS_NOT_CONFIGURED;
|
||||
|
||||
|
||||
@@ -28,8 +28,6 @@ protected:
|
||||
unsigned long dhwSetTempTime = 0;
|
||||
unsigned long heatingSetTempTime = 0;
|
||||
byte configuredRxLedGpio = GPIO_IS_NOT_CONFIGURED;
|
||||
byte configuredFaultStateGpio = GPIO_IS_NOT_CONFIGURED;
|
||||
bool faultState = false;
|
||||
|
||||
#if defined(ARDUINO_ARCH_ESP32)
|
||||
const char* getTaskName() override {
|
||||
@@ -133,28 +131,7 @@ 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 && vars.cascadeControl.input && this->isReady();
|
||||
bool heatingCh2Enabled = settings.opentherm.heatingCh2Enabled;
|
||||
if (settings.opentherm.heatingCh1ToCh2) {
|
||||
heatingCh2Enabled = heatingEnabled;
|
||||
@@ -212,16 +189,6 @@ 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;
|
||||
}
|
||||
|
||||
@@ -251,16 +218,6 @@ protected:
|
||||
vars.states.heating, vars.states.dhw, vars.states.flame, vars.states.fault, vars.states.diagnostic
|
||||
);
|
||||
|
||||
// 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 (this->updateMinModulationLevel()) {
|
||||
|
||||
@@ -51,8 +51,6 @@ 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;
|
||||
uint8_t maxModulation = 100;
|
||||
float pressureFactor = 1.0f;
|
||||
@@ -156,6 +154,25 @@ struct Settings {
|
||||
unsigned short antiStuckTime = 300;
|
||||
} externalPump;
|
||||
|
||||
struct {
|
||||
struct {
|
||||
bool enable = false;
|
||||
byte gpio = GPIO_IS_NOT_CONFIGURED;
|
||||
byte invertState = false;
|
||||
unsigned short thresholdTime = 60;
|
||||
} input;
|
||||
|
||||
struct {
|
||||
bool enable = false;
|
||||
byte gpio = GPIO_IS_NOT_CONFIGURED;
|
||||
byte invertState = false;
|
||||
unsigned short thresholdTime = 60;
|
||||
bool onFault = true;
|
||||
bool onLossConnection = true;
|
||||
bool onEnabledHeating = false;
|
||||
} output;
|
||||
} cascadeControl;
|
||||
|
||||
char validationValue[8] = SETTINGS_VALID_VALUE;
|
||||
} settings;
|
||||
|
||||
@@ -205,6 +222,11 @@ struct Variables {
|
||||
float exhaust = 0.0f;
|
||||
} temperatures;
|
||||
|
||||
struct {
|
||||
bool input = false;
|
||||
bool output = false;
|
||||
} cascadeControl;
|
||||
|
||||
struct {
|
||||
bool heatingEnabled = false;
|
||||
byte heatingMinTemp = DEFAULT_HEATING_MIN_TEMP;
|
||||
|
||||
@@ -24,4 +24,6 @@ const char L_SENSORS_INDOOR[] PROGMEM = "SENSORS.INDOOR";
|
||||
const char L_SENSORS_BLE[] PROGMEM = "SENSORS.BLE";
|
||||
const char L_REGULATOR[] PROGMEM = "REGULATOR";
|
||||
const char L_REGULATOR_PID[] PROGMEM = "REGULATOR.PID";
|
||||
const char L_REGULATOR_EQUITHERM[] PROGMEM = "REGULATOR.EQUITHERM";
|
||||
const char L_REGULATOR_EQUITHERM[] PROGMEM = "REGULATOR.EQUITHERM";
|
||||
const char L_CASCADE_INPUT[] PROGMEM = "CASCADE.INPUT";
|
||||
const char L_CASCADE_OUTPUT[] PROGMEM = "CASCADE.OUTPUT";
|
||||
165
src/utils.h
165
src/utils.h
@@ -342,8 +342,6 @@ 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"]["maxModulation"] = src.opentherm.maxModulation;
|
||||
dst["opentherm"]["pressureFactor"] = roundd(src.opentherm.pressureFactor, 2);
|
||||
@@ -447,6 +445,19 @@ void settingsToJson(const Settings& src, JsonVariant dst, bool safe = false) {
|
||||
dst["externalPump"]["postCirculationTime"] = roundd(src.externalPump.postCirculationTime / 60, 0);
|
||||
dst["externalPump"]["antiStuckInterval"] = roundd(src.externalPump.antiStuckInterval / 86400, 0);
|
||||
dst["externalPump"]["antiStuckTime"] = roundd(src.externalPump.antiStuckTime / 60, 0);
|
||||
|
||||
dst["cascadeControl"]["input"]["enable"] = src.cascadeControl.input.enable;
|
||||
dst["cascadeControl"]["input"]["gpio"] = src.cascadeControl.input.gpio;
|
||||
dst["cascadeControl"]["input"]["invertState"] = src.cascadeControl.input.invertState;
|
||||
dst["cascadeControl"]["input"]["thresholdTime"] = src.cascadeControl.input.thresholdTime;
|
||||
|
||||
dst["cascadeControl"]["output"]["enable"] = src.cascadeControl.output.enable;
|
||||
dst["cascadeControl"]["output"]["gpio"] = src.cascadeControl.output.gpio;
|
||||
dst["cascadeControl"]["output"]["invertState"] = src.cascadeControl.output.invertState;
|
||||
dst["cascadeControl"]["output"]["thresholdTime"] = src.cascadeControl.output.thresholdTime;
|
||||
dst["cascadeControl"]["output"]["onFault"] = src.cascadeControl.output.onFault;
|
||||
dst["cascadeControl"]["output"]["onLossConnection"] = src.cascadeControl.output.onLossConnection;
|
||||
dst["cascadeControl"]["output"]["onEnabledHeating"] = src.cascadeControl.output.onEnabledHeating;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -665,32 +676,6 @@ 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>();
|
||||
|
||||
@@ -1470,6 +1455,127 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// cascade control
|
||||
if (src["cascadeControl"]["input"]["enable"].is<bool>()) {
|
||||
bool value = src["cascadeControl"]["input"]["enable"].as<bool>();
|
||||
|
||||
if (value != dst.cascadeControl.input.enable) {
|
||||
dst.cascadeControl.input.enable = value;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!src["cascadeControl"]["input"]["gpio"].isNull()) {
|
||||
if (src["cascadeControl"]["input"]["gpio"].is<JsonString>() && src["cascadeControl"]["input"]["gpio"].as<JsonString>().size() == 0) {
|
||||
if (dst.cascadeControl.input.gpio != GPIO_IS_NOT_CONFIGURED) {
|
||||
dst.cascadeControl.input.gpio = GPIO_IS_NOT_CONFIGURED;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
} else {
|
||||
unsigned char value = src["cascadeControl"]["input"]["gpio"].as<unsigned char>();
|
||||
|
||||
if (GPIO_IS_VALID(value) && value != dst.cascadeControl.input.gpio) {
|
||||
dst.cascadeControl.input.gpio = value;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (src["cascadeControl"]["input"]["invertState"].is<bool>()) {
|
||||
bool value = src["cascadeControl"]["input"]["invertState"].as<bool>();
|
||||
|
||||
if (value != dst.cascadeControl.input.invertState) {
|
||||
dst.cascadeControl.input.invertState = value;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!src["cascadeControl"]["input"]["thresholdTime"].isNull()) {
|
||||
unsigned short value = src["cascadeControl"]["input"]["thresholdTime"].as<unsigned short>();
|
||||
|
||||
if (value >= 5 && value <= 600) {
|
||||
if (value != dst.cascadeControl.input.thresholdTime) {
|
||||
dst.cascadeControl.input.thresholdTime = value;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (src["cascadeControl"]["output"]["enable"].is<bool>()) {
|
||||
bool value = src["cascadeControl"]["output"]["enable"].as<bool>();
|
||||
|
||||
if (value != dst.cascadeControl.output.enable) {
|
||||
dst.cascadeControl.output.enable = value;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!src["cascadeControl"]["output"]["gpio"].isNull()) {
|
||||
if (src["cascadeControl"]["output"]["gpio"].is<JsonString>() && src["cascadeControl"]["output"]["gpio"].as<JsonString>().size() == 0) {
|
||||
if (dst.cascadeControl.output.gpio != GPIO_IS_NOT_CONFIGURED) {
|
||||
dst.cascadeControl.output.gpio = GPIO_IS_NOT_CONFIGURED;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
} else {
|
||||
unsigned char value = src["cascadeControl"]["output"]["gpio"].as<unsigned char>();
|
||||
|
||||
if (GPIO_IS_VALID(value) && value != dst.cascadeControl.output.gpio) {
|
||||
dst.cascadeControl.output.gpio = value;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (src["cascadeControl"]["output"]["invertState"].is<bool>()) {
|
||||
bool value = src["cascadeControl"]["output"]["invertState"].as<bool>();
|
||||
|
||||
if (value != dst.cascadeControl.output.invertState) {
|
||||
dst.cascadeControl.output.invertState = value;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!src["cascadeControl"]["output"]["thresholdTime"].isNull()) {
|
||||
unsigned short value = src["cascadeControl"]["output"]["thresholdTime"].as<unsigned short>();
|
||||
|
||||
if (value >= 5 && value <= 600) {
|
||||
if (value != dst.cascadeControl.output.thresholdTime) {
|
||||
dst.cascadeControl.output.thresholdTime = value;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (src["cascadeControl"]["output"]["onFault"].is<bool>()) {
|
||||
bool value = src["cascadeControl"]["output"]["onFault"].as<bool>();
|
||||
|
||||
if (value != dst.cascadeControl.output.onFault) {
|
||||
dst.cascadeControl.output.onFault = value;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (src["cascadeControl"]["output"]["onLossConnection"].is<bool>()) {
|
||||
bool value = src["cascadeControl"]["output"]["onLossConnection"].as<bool>();
|
||||
|
||||
if (value != dst.cascadeControl.output.onLossConnection) {
|
||||
dst.cascadeControl.output.onLossConnection = value;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (src["cascadeControl"]["output"]["onEnabledHeating"].is<bool>()) {
|
||||
bool value = src["cascadeControl"]["output"]["onEnabledHeating"].as<bool>();
|
||||
|
||||
if (value != dst.cascadeControl.output.onEnabledHeating) {
|
||||
dst.cascadeControl.output.onEnabledHeating = value;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// force check emergency target
|
||||
@@ -1587,6 +1693,9 @@ void varsToJson(const Variables& src, JsonVariant dst) {
|
||||
dst["temperatures"]["dhw"] = roundd(src.temperatures.dhw, 2);
|
||||
dst["temperatures"]["exhaust"] = roundd(src.temperatures.exhaust, 2);
|
||||
|
||||
dst["cascadeControl"]["input"] = src.cascadeControl.input;
|
||||
dst["cascadeControl"]["output"] = src.cascadeControl.output;
|
||||
|
||||
dst["parameters"]["heatingEnabled"] = src.parameters.heatingEnabled;
|
||||
dst["parameters"]["heatingMinTemp"] = src.parameters.heatingMinTemp;
|
||||
dst["parameters"]["heatingMaxTemp"] = src.parameters.heatingMaxTemp;
|
||||
|
||||
Reference in New Issue
Block a user