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->heating();
|
||||
this->emergency();
|
||||
this->ledStatus();
|
||||
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() {
|
||||
// flags
|
||||
uint8_t emergencyFlags = 0b00000000;
|
||||
|
||||
@@ -169,7 +169,7 @@ protected:
|
||||
|
||||
// Heating settings
|
||||
vars.master.heating.enabled = this->isReady()
|
||||
&& (settings.heating.enabled || vars.emergency.state)
|
||||
&& settings.heating.enabled
|
||||
&& vars.cascadeControl.input
|
||||
&& !vars.master.heating.blocking
|
||||
&& !vars.master.heating.overheat;
|
||||
|
||||
@@ -110,6 +110,7 @@ struct Settings {
|
||||
uint8_t maxModulation = 100;
|
||||
uint8_t overheatHighTemp = 95;
|
||||
uint8_t overheatLowTemp = 90;
|
||||
uint8_t antiFreezeTemp = 10;
|
||||
} heating;
|
||||
|
||||
struct {
|
||||
|
||||
@@ -44,6 +44,7 @@ const char S_APP_VERSION[] PROGMEM = "appVersion";
|
||||
const char S_AUTH[] PROGMEM = "auth";
|
||||
const char S_AUTO_DIAG_RESET[] PROGMEM = "autoDiagReset";
|
||||
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_BATTERY[] PROGMEM = "battery";
|
||||
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_OVERHEAT_HIGH_TEMP)] = src.heating.overheatHighTemp;
|
||||
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>();
|
||||
dhw[FPSTR(S_ENABLED)] = src.dhw.enabled;
|
||||
@@ -1369,6 +1370,15 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false
|
||||
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
|
||||
if (src[FPSTR(S_DHW)][FPSTR(S_ENABLED)].is<bool>()) {
|
||||
|
||||
@@ -350,7 +350,11 @@
|
||||
|
||||
"heating": {
|
||||
"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": {
|
||||
|
||||
@@ -350,7 +350,11 @@
|
||||
|
||||
"heating": {
|
||||
"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": {
|
||||
|
||||
@@ -350,7 +350,11 @@
|
||||
|
||||
"heating": {
|
||||
"hyst": "Гистерезис <small>(в градусах)</small>",
|
||||
"turboFactor": "Коэфф. турбо режима"
|
||||
"turboFactor": "Коэфф. турбо режима",
|
||||
"antiFreezeTemp": {
|
||||
"title": "Температура защиты от замерзания",
|
||||
"note": "Отопление будет принудительно включено, если температура теплоносителя или внутренняя температура опустится ниже этого значения"
|
||||
}
|
||||
},
|
||||
|
||||
"emergency": {
|
||||
|
||||
@@ -207,6 +207,12 @@
|
||||
<input type="number" inputmode="numeric" name="heating[maxModulation]" min="1" max="100" step="1" required>
|
||||
</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>
|
||||
<summary><b data-i18n>settings.overheat.title</b></summary>
|
||||
|
||||
@@ -926,6 +932,10 @@
|
||||
setInputValue("[name='heating[maxModulation]']", data.heating.maxModulation);
|
||||
setInputValue("[name='heating[overheatHighTemp]']", data.heating.overheatHighTemp);
|
||||
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);
|
||||
|
||||
// DHW
|
||||
@@ -943,11 +953,10 @@
|
||||
setBusy('#dhw-settings-busy', '#dhw-settings', false);
|
||||
|
||||
// Emergency mode
|
||||
setInputValue("[name='emergency[tresholdTime]']", data.emergency.tresholdTime);
|
||||
if (data.opentherm.options.nativeHeatingControl) {
|
||||
setInputValue("[name='emergency[target]']", data.emergency.target, {
|
||||
"min": data.system.unitSystem == 0 ? 5 : 41,
|
||||
"max": data.system.unitSystem == 0 ? 40 : 86
|
||||
"max": data.system.unitSystem == 0 ? 40 : 104
|
||||
});
|
||||
|
||||
} else {
|
||||
@@ -956,7 +965,7 @@
|
||||
"max": data.heating.maxTemp,
|
||||
});
|
||||
}
|
||||
|
||||
setInputValue("[name='emergency[tresholdTime]']", data.emergency.tresholdTime);
|
||||
setBusy('#emergency-settings-busy', '#emergency-settings', false);
|
||||
|
||||
// Equitherm
|
||||
|
||||
Reference in New Issue
Block a user