mirror of
https://github.com/Laxilef/OTGateway.git
synced 2025-12-10 18:24:27 +05:00
feat: added freeze protection parameter for heating, removed forced start of heating in emergency mode #157
This commit is contained in:
@@ -152,6 +152,7 @@ protected:
|
|||||||
}
|
}
|
||||||
this->yield();
|
this->yield();
|
||||||
|
|
||||||
|
this->heating();
|
||||||
this->emergency();
|
this->emergency();
|
||||||
this->ledStatus();
|
this->ledStatus();
|
||||||
this->cascadeControl();
|
this->cascadeControl();
|
||||||
@@ -228,6 +229,52 @@ protected:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void heating() {
|
||||||
|
// anti freeze protection
|
||||||
|
if (!settings.heating.enabled) {
|
||||||
|
float minTemp = 255.0f;
|
||||||
|
uint8_t availableSensors = 0;
|
||||||
|
|
||||||
|
if (Sensors::existsConnectedSensorsByPurpose(Sensors::Purpose::INDOOR_TEMP)) {
|
||||||
|
auto value = Sensors::getMeanValueByPurpose(Sensors::Purpose::INDOOR_TEMP, Sensors::ValueType::PRIMARY);
|
||||||
|
if (value < minTemp) {
|
||||||
|
minTemp = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
availableSensors++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Sensors::existsConnectedSensorsByPurpose(Sensors::Purpose::HEATING_TEMP)) {
|
||||||
|
auto value = Sensors::getMeanValueByPurpose(Sensors::Purpose::HEATING_TEMP, Sensors::ValueType::PRIMARY);
|
||||||
|
if (value < minTemp) {
|
||||||
|
minTemp = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
availableSensors++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Sensors::existsConnectedSensorsByPurpose(Sensors::Purpose::HEATING_RETURN_TEMP)) {
|
||||||
|
auto value = Sensors::getMeanValueByPurpose(Sensors::Purpose::HEATING_RETURN_TEMP, Sensors::ValueType::PRIMARY);
|
||||||
|
if (value < minTemp) {
|
||||||
|
minTemp = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
availableSensors++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (availableSensors && minTemp <= settings.heating.antiFreezeTemp) {
|
||||||
|
settings.heating.enabled = true;
|
||||||
|
fsSettings.update();
|
||||||
|
|
||||||
|
Log.sinfoln(
|
||||||
|
FPSTR(L_MAIN),
|
||||||
|
F("Heating turned on by anti freeze protection, current min temp: %.2f, threshold: %hhu"),
|
||||||
|
minTemp, settings.heating.antiFreezeTemp
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void emergency() {
|
void emergency() {
|
||||||
// flags
|
// flags
|
||||||
uint8_t emergencyFlags = 0b00000000;
|
uint8_t emergencyFlags = 0b00000000;
|
||||||
|
|||||||
@@ -169,7 +169,7 @@ protected:
|
|||||||
|
|
||||||
// Heating settings
|
// Heating settings
|
||||||
vars.master.heating.enabled = this->isReady()
|
vars.master.heating.enabled = this->isReady()
|
||||||
&& (settings.heating.enabled || vars.emergency.state)
|
&& settings.heating.enabled
|
||||||
&& vars.cascadeControl.input
|
&& vars.cascadeControl.input
|
||||||
&& !vars.master.heating.blocking
|
&& !vars.master.heating.blocking
|
||||||
&& !vars.master.heating.overheat;
|
&& !vars.master.heating.overheat;
|
||||||
|
|||||||
@@ -110,6 +110,7 @@ struct Settings {
|
|||||||
uint8_t maxModulation = 100;
|
uint8_t maxModulation = 100;
|
||||||
uint8_t overheatHighTemp = 95;
|
uint8_t overheatHighTemp = 95;
|
||||||
uint8_t overheatLowTemp = 90;
|
uint8_t overheatLowTemp = 90;
|
||||||
|
uint8_t antiFreezeTemp = 10;
|
||||||
} heating;
|
} heating;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ const char S_APP_VERSION[] PROGMEM = "appVersion";
|
|||||||
const char S_AUTH[] PROGMEM = "auth";
|
const char S_AUTH[] PROGMEM = "auth";
|
||||||
const char S_AUTO_DIAG_RESET[] PROGMEM = "autoDiagReset";
|
const char S_AUTO_DIAG_RESET[] PROGMEM = "autoDiagReset";
|
||||||
const char S_AUTO_FAULT_RESET[] PROGMEM = "autoFaultReset";
|
const char S_AUTO_FAULT_RESET[] PROGMEM = "autoFaultReset";
|
||||||
|
const char S_ANTI_FREEZE_TEMP[] PROGMEM = "antiFreezeTemp";
|
||||||
const char S_BACKTRACE[] PROGMEM = "backtrace";
|
const char S_BACKTRACE[] PROGMEM = "backtrace";
|
||||||
const char S_BATTERY[] PROGMEM = "battery";
|
const char S_BATTERY[] PROGMEM = "battery";
|
||||||
const char S_BAUDRATE[] PROGMEM = "baudrate";
|
const char S_BAUDRATE[] PROGMEM = "baudrate";
|
||||||
|
|||||||
10
src/utils.h
10
src/utils.h
@@ -497,6 +497,7 @@ void settingsToJson(const Settings& src, JsonVariant dst, bool safe = false) {
|
|||||||
heating[FPSTR(S_MAX_MODULATION)] = src.heating.maxModulation;
|
heating[FPSTR(S_MAX_MODULATION)] = src.heating.maxModulation;
|
||||||
heating[FPSTR(S_OVERHEAT_HIGH_TEMP)] = src.heating.overheatHighTemp;
|
heating[FPSTR(S_OVERHEAT_HIGH_TEMP)] = src.heating.overheatHighTemp;
|
||||||
heating[FPSTR(S_OVERHEAT_LOW_TEMP)] = src.heating.overheatLowTemp;
|
heating[FPSTR(S_OVERHEAT_LOW_TEMP)] = src.heating.overheatLowTemp;
|
||||||
|
heating[FPSTR(S_ANTI_FREEZE_TEMP)] = src.heating.antiFreezeTemp;
|
||||||
|
|
||||||
auto dhw = dst[FPSTR(S_DHW)].to<JsonObject>();
|
auto dhw = dst[FPSTR(S_DHW)].to<JsonObject>();
|
||||||
dhw[FPSTR(S_ENABLED)] = src.dhw.enabled;
|
dhw[FPSTR(S_ENABLED)] = src.dhw.enabled;
|
||||||
@@ -1369,6 +1370,15 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false
|
|||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!src[FPSTR(S_HEATING)][FPSTR(S_ANTI_FREEZE_TEMP)].isNull()) {
|
||||||
|
unsigned short value = src[FPSTR(S_HEATING)][FPSTR(S_ANTI_FREEZE_TEMP)].as<unsigned short>();
|
||||||
|
|
||||||
|
if (isValidTemp(value, dst.system.unitSystem, 1, 30) && value != dst.heating.antiFreezeTemp) {
|
||||||
|
dst.heating.antiFreezeTemp = value;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// dhw
|
// dhw
|
||||||
if (src[FPSTR(S_DHW)][FPSTR(S_ENABLED)].is<bool>()) {
|
if (src[FPSTR(S_DHW)][FPSTR(S_ENABLED)].is<bool>()) {
|
||||||
|
|||||||
@@ -350,7 +350,11 @@
|
|||||||
|
|
||||||
"heating": {
|
"heating": {
|
||||||
"hyst": "Hysteresis <small>(in degrees)</small>",
|
"hyst": "Hysteresis <small>(in degrees)</small>",
|
||||||
"turboFactor": "Turbo mode coeff."
|
"turboFactor": "Turbo mode coeff.",
|
||||||
|
"antiFreezeTemp": {
|
||||||
|
"title": "Freeze protection temperature",
|
||||||
|
"note": "If the heat carrier or indoor temperature drops below this value, the heating will be forced to turn on"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
"emergency": {
|
"emergency": {
|
||||||
|
|||||||
@@ -350,7 +350,11 @@
|
|||||||
|
|
||||||
"heating": {
|
"heating": {
|
||||||
"hyst": "Isteresi <small>(in gradi)</small>",
|
"hyst": "Isteresi <small>(in gradi)</small>",
|
||||||
"turboFactor": "Turbo mode coeff."
|
"turboFactor": "Turbo mode coeff.",
|
||||||
|
"antiFreezeTemp": {
|
||||||
|
"title": "Temperatura di protezione antigelo",
|
||||||
|
"note": "Se la temperatura del fluido termovettore o interna scende al di sotto di questo valore, il riscaldamento verrà forzato ad accendersi"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
"emergency": {
|
"emergency": {
|
||||||
|
|||||||
@@ -350,7 +350,11 @@
|
|||||||
|
|
||||||
"heating": {
|
"heating": {
|
||||||
"hyst": "Гистерезис <small>(в градусах)</small>",
|
"hyst": "Гистерезис <small>(в градусах)</small>",
|
||||||
"turboFactor": "Коэфф. турбо режима"
|
"turboFactor": "Коэфф. турбо режима",
|
||||||
|
"antiFreezeTemp": {
|
||||||
|
"title": "Температура защиты от замерзания",
|
||||||
|
"note": "Отопление будет принудительно включено, если температура теплоносителя или внутренняя температура опустится ниже этого значения"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
"emergency": {
|
"emergency": {
|
||||||
|
|||||||
@@ -207,6 +207,12 @@
|
|||||||
<input type="number" inputmode="numeric" name="heating[maxModulation]" min="1" max="100" step="1" required>
|
<input type="number" inputmode="numeric" name="heating[maxModulation]" min="1" max="100" step="1" required>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
|
<label>
|
||||||
|
<span data-i18n>settings.heating.antiFreezeTemp.title</span>
|
||||||
|
<input type="number" inputmode="numeric" name="heating[antiFreezeTemp]" min="0" max="0" step="1" required>
|
||||||
|
<small data-i18n>settings.heating.antiFreezeTemp.note</small>
|
||||||
|
</label>
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
<summary><b data-i18n>settings.overheat.title</b></summary>
|
<summary><b data-i18n>settings.overheat.title</b></summary>
|
||||||
|
|
||||||
@@ -926,6 +932,10 @@
|
|||||||
setInputValue("[name='heating[maxModulation]']", data.heating.maxModulation);
|
setInputValue("[name='heating[maxModulation]']", data.heating.maxModulation);
|
||||||
setInputValue("[name='heating[overheatHighTemp]']", data.heating.overheatHighTemp);
|
setInputValue("[name='heating[overheatHighTemp]']", data.heating.overheatHighTemp);
|
||||||
setInputValue("[name='heating[overheatLowTemp]']", data.heating.overheatLowTemp);
|
setInputValue("[name='heating[overheatLowTemp]']", data.heating.overheatLowTemp);
|
||||||
|
setInputValue("[name='heating[antiFreezeTemp]']", data.heating.antiFreezeTemp, {
|
||||||
|
"min": data.system.unitSystem == 0 ? 1 : 34,
|
||||||
|
"max": data.system.unitSystem == 0 ? 30 : 86
|
||||||
|
});
|
||||||
setBusy('#heating-settings-busy', '#heating-settings', false);
|
setBusy('#heating-settings-busy', '#heating-settings', false);
|
||||||
|
|
||||||
// DHW
|
// DHW
|
||||||
@@ -943,11 +953,10 @@
|
|||||||
setBusy('#dhw-settings-busy', '#dhw-settings', false);
|
setBusy('#dhw-settings-busy', '#dhw-settings', false);
|
||||||
|
|
||||||
// Emergency mode
|
// Emergency mode
|
||||||
setInputValue("[name='emergency[tresholdTime]']", data.emergency.tresholdTime);
|
|
||||||
if (data.opentherm.options.nativeHeatingControl) {
|
if (data.opentherm.options.nativeHeatingControl) {
|
||||||
setInputValue("[name='emergency[target]']", data.emergency.target, {
|
setInputValue("[name='emergency[target]']", data.emergency.target, {
|
||||||
"min": data.system.unitSystem == 0 ? 5 : 41,
|
"min": data.system.unitSystem == 0 ? 5 : 41,
|
||||||
"max": data.system.unitSystem == 0 ? 40 : 86
|
"max": data.system.unitSystem == 0 ? 40 : 104
|
||||||
});
|
});
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@@ -956,7 +965,7 @@
|
|||||||
"max": data.heating.maxTemp,
|
"max": data.heating.maxTemp,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
setInputValue("[name='emergency[tresholdTime]']", data.emergency.tresholdTime);
|
||||||
setBusy('#emergency-settings-busy', '#emergency-settings', false);
|
setBusy('#emergency-settings-busy', '#emergency-settings', false);
|
||||||
|
|
||||||
// Equitherm
|
// Equitherm
|
||||||
|
|||||||
Reference in New Issue
Block a user