refactor: cosmetic changes; added coeff. setting for filtering numeric values

This commit is contained in:
Yurii
2024-10-13 21:42:33 +03:00
parent 8aab541afa
commit 45af7a30d8
8 changed files with 157 additions and 90 deletions

View File

@@ -254,7 +254,7 @@ protected:
// 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) {
if (setMaxModulationLevel(0)) { if (this->setMaxModulationLevel(0)) {
Log.snoticeln(FPSTR(L_OT_HEATING), F("Set max modulation 0% (off)")); Log.snoticeln(FPSTR(L_OT_HEATING), F("Set max modulation 0% (off)"));
} else { } else {
@@ -262,7 +262,7 @@ protected:
} }
} else { } else {
if (setMaxModulationLevel(settings.heating.maxModulation)) { if (this->setMaxModulationLevel(settings.heating.maxModulation)) {
Log.snoticeln(FPSTR(L_OT_HEATING), F("Set max modulation %hhu%%"), settings.heating.maxModulation); Log.snoticeln(FPSTR(L_OT_HEATING), F("Set max modulation %hhu%%"), settings.heating.maxModulation);
} else { } else {
@@ -273,7 +273,7 @@ protected:
// Get DHW min/max temp (if necessary) // Get DHW min/max temp (if necessary)
if (settings.opentherm.dhwPresent && settings.opentherm.getMinMaxTemp) { if (settings.opentherm.dhwPresent && settings.opentherm.getMinMaxTemp) {
if (updateMinMaxDhwTemp()) { if (this->updateMinMaxDhwTemp()) {
if (settings.dhw.minTemp < vars.parameters.dhwMinTemp) { if (settings.dhw.minTemp < vars.parameters.dhwMinTemp) {
settings.dhw.minTemp = vars.parameters.dhwMinTemp; settings.dhw.minTemp = vars.parameters.dhwMinTemp;
fsSettings.update(); fsSettings.update();
@@ -303,7 +303,7 @@ protected:
// Get heating min/max temp // Get heating min/max temp
if (settings.opentherm.getMinMaxTemp) { if (settings.opentherm.getMinMaxTemp) {
if (updateMinMaxHeatingTemp()) { if (this->updateMinMaxHeatingTemp()) {
if (settings.heating.minTemp < vars.parameters.heatingMinTemp) { if (settings.heating.minTemp < vars.parameters.heatingMinTemp) {
settings.heating.minTemp = vars.parameters.heatingMinTemp; settings.heating.minTemp = vars.parameters.heatingMinTemp;
fsSettings.update(); fsSettings.update();
@@ -330,14 +330,9 @@ protected:
fsSettings.update(); fsSettings.update();
} }
// Get outdoor temp (if necessary)
if (settings.sensors.outdoor.type == SensorType::BOILER) {
updateOutsideTemp();
}
// Get fault code (if necessary) // Get fault code (if necessary)
if (vars.states.fault) { if (vars.states.fault) {
updateFaultCode(); this->updateFaultCode();
} else if (vars.sensors.faultCode != 0) { } else if (vars.sensors.faultCode != 0) {
vars.sensors.faultCode = 0; vars.sensors.faultCode = 0;
@@ -345,13 +340,23 @@ protected:
// Get diagnostic code (if necessary) // Get diagnostic code (if necessary)
if (vars.states.fault || vars.states.diagnostic) { if (vars.states.fault || vars.states.diagnostic) {
updateDiagCode(); this->updateDiagCode();
} else if (vars.sensors.diagnosticCode != 0) { } else if (vars.sensors.diagnosticCode != 0) {
vars.sensors.diagnosticCode = 0; vars.sensors.diagnosticCode = 0;
} }
updatePressure(); // If filtering is disabled, then it is enough to
// update these parameters once a minute
if (!settings.opentherm.filterNumValues.enable) {
// Get outdoor temp (if necessary)
if (settings.sensors.outdoor.type == SensorType::BOILER) {
this->updateOutdoorTemp();
}
// Get pressure
this->updatePressure();
}
this->prevUpdateNonEssentialVars = millis(); this->prevUpdateNonEssentialVars = millis();
} }
@@ -359,7 +364,7 @@ protected:
// Get current modulation level (if necessary) // Get current modulation level (if necessary)
if (vars.states.flame) { if (vars.states.flame) {
updateModulationLevel(); this->updateModulationLevel();
} else { } else {
vars.sensors.modulation = 0; vars.sensors.modulation = 0;
@@ -367,8 +372,8 @@ protected:
// Update DHW sensors (if necessary) // Update DHW sensors (if necessary)
if (settings.opentherm.dhwPresent) { if (settings.opentherm.dhwPresent) {
updateDhwTemp(); this->updateDhwTemp();
updateDhwFlowRate(); this->updateDhwFlowRate();
} else { } else {
vars.temperatures.dhw = 0.0f; vars.temperatures.dhw = 0.0f;
@@ -376,13 +381,25 @@ protected:
} }
// Get current heating temp // Get current heating temp
updateHeatingTemp(); this->updateHeatingTemp();
// Get heating return temp // Get heating return temp
updateHeatingReturnTemp(); this->updateHeatingReturnTemp();
// Get exhaust temp // Get exhaust temp
updateExhaustTemp(); this->updateExhaustTemp();
// If filtering is enabled, these parameters
// must be updated every time.
if (settings.opentherm.filterNumValues.enable) {
// Get outdoor temp (if necessary)
if (settings.sensors.outdoor.type == SensorType::BOILER) {
this->updateOutdoorTemp();
}
// Get pressure
this->updatePressure();
}
// Fault reset action // Fault reset action
@@ -795,7 +812,7 @@ protected:
return CustomOpenTherm::isValidResponse(response); return CustomOpenTherm::isValidResponse(response);
} }
bool updateOutsideTemp() { bool updateOutdoorTemp() {
unsigned long response = this->instance->sendRequest(CustomOpenTherm::buildRequest( unsigned long response = this->instance->sendRequest(CustomOpenTherm::buildRequest(
OpenThermRequestType::READ_DATA, OpenThermRequestType::READ_DATA,
OpenThermMessageID::Toutside, OpenThermMessageID::Toutside,
@@ -812,8 +829,8 @@ protected:
settings.system.unitSystem settings.system.unitSystem
); );
if (settings.opentherm.filteringNumValues && fabs(vars.temperatures.outdoor) >= 0.1f) { if (settings.opentherm.filterNumValues.enable && fabs(vars.temperatures.outdoor) >= 0.1f) {
vars.temperatures.outdoor += (value - vars.temperatures.outdoor) * OT_NUM_VALUES_FILTER_K; vars.temperatures.outdoor += (value - vars.temperatures.outdoor) * settings.opentherm.filterNumValues.factor;
} else { } else {
vars.temperatures.outdoor = value; vars.temperatures.outdoor = value;
@@ -844,8 +861,8 @@ protected:
settings.system.unitSystem settings.system.unitSystem
); );
if (settings.opentherm.filteringNumValues && fabs(vars.temperatures.exhaust) >= 0.1f) { if (settings.opentherm.filterNumValues.enable && fabs(vars.temperatures.exhaust) >= 0.1f) {
vars.temperatures.exhaust += (value - vars.temperatures.exhaust) * OT_NUM_VALUES_FILTER_K; vars.temperatures.exhaust += (value - vars.temperatures.exhaust) * settings.opentherm.filterNumValues.factor;
} else { } else {
vars.temperatures.exhaust = value; vars.temperatures.exhaust = value;
@@ -876,8 +893,8 @@ protected:
settings.system.unitSystem settings.system.unitSystem
); );
if (settings.opentherm.filteringNumValues && fabs(vars.temperatures.heating) >= 0.1f) { if (settings.opentherm.filterNumValues.enable && fabs(vars.temperatures.heating) >= 0.1f) {
vars.temperatures.heating += (value - vars.temperatures.heating) * OT_NUM_VALUES_FILTER_K; vars.temperatures.heating += (value - vars.temperatures.heating) * settings.opentherm.filterNumValues.factor;
} else { } else {
vars.temperatures.heating = value; vars.temperatures.heating = value;
@@ -903,8 +920,8 @@ protected:
settings.system.unitSystem settings.system.unitSystem
); );
if (settings.opentherm.filteringNumValues && fabs(vars.temperatures.heatingReturn) >= 0.1f) { if (settings.opentherm.filterNumValues.enable && fabs(vars.temperatures.heatingReturn) >= 0.1f) {
vars.temperatures.heatingReturn += (value - vars.temperatures.heatingReturn) * OT_NUM_VALUES_FILTER_K; vars.temperatures.heatingReturn += (value - vars.temperatures.heatingReturn) * settings.opentherm.filterNumValues.factor;
} else { } else {
vars.temperatures.heatingReturn = value; vars.temperatures.heatingReturn = value;
@@ -937,8 +954,8 @@ protected:
settings.system.unitSystem settings.system.unitSystem
); );
if (settings.opentherm.filteringNumValues && fabs(vars.temperatures.dhw) >= 0.1f) { if (settings.opentherm.filterNumValues.enable && fabs(vars.temperatures.dhw) >= 0.1f) {
vars.temperatures.dhw += (value - vars.temperatures.dhw) * OT_NUM_VALUES_FILTER_K; vars.temperatures.dhw += (value - vars.temperatures.dhw) * settings.opentherm.filterNumValues.factor;
} else { } else {
vars.temperatures.dhw = value; vars.temperatures.dhw = value;
@@ -964,7 +981,7 @@ protected:
} }
value = convertVolume( value = convertVolume(
value / settings.opentherm.dhwFlowRateMultiplier, value * settings.opentherm.dhwFlowRateFactor,
settings.opentherm.unitSystem, settings.opentherm.unitSystem,
settings.system.unitSystem settings.system.unitSystem
); );
@@ -1018,8 +1035,8 @@ protected:
} }
float value = CustomOpenTherm::getFloat(response); float value = CustomOpenTherm::getFloat(response);
if (settings.opentherm.filteringNumValues && fabs(vars.sensors.modulation) >= 0.1f) { if (settings.opentherm.filterNumValues.enable && fabs(vars.sensors.modulation) >= 0.1f) {
vars.sensors.modulation += (value - vars.sensors.modulation) * OT_NUM_VALUES_FILTER_K; vars.sensors.modulation += (value - vars.sensors.modulation) * settings.opentherm.filterNumValues.factor;
} else { } else {
vars.sensors.modulation = value; vars.sensors.modulation = value;
@@ -1045,13 +1062,13 @@ protected:
} }
value = convertPressure( value = convertPressure(
value / settings.opentherm.pressureMultiplier, value * settings.opentherm.pressureFactor,
settings.opentherm.unitSystem, settings.opentherm.unitSystem,
settings.system.unitSystem settings.system.unitSystem
); );
if (settings.opentherm.filteringNumValues && fabs(vars.sensors.pressure) >= 0.1f) { if (settings.opentherm.filterNumValues.enable && fabs(vars.sensors.pressure) >= 0.1f) {
vars.sensors.pressure += (value - vars.sensors.pressure) * OT_NUM_VALUES_FILTER_K; vars.sensors.pressure += (value - vars.sensors.pressure) * settings.opentherm.filterNumValues.factor;
} else { } else {
vars.sensors.pressure = value; vars.sensors.pressure = value;

View File

@@ -139,7 +139,8 @@ protected:
// if use pid // if use pid
if (settings.pid.enable) { if (settings.pid.enable) {
if (vars.parameters.heatingEnabled) { //if (vars.parameters.heatingEnabled) {
if (settings.heating.enable) {
float pidResult = getPidTemp( float pidResult = getPidTemp(
settings.equitherm.enable ? (settings.pid.maxTemp * -1) : settings.pid.minTemp, settings.equitherm.enable ? (settings.pid.maxTemp * -1) : settings.pid.minTemp,
settings.pid.maxTemp settings.pid.maxTemp
@@ -160,8 +161,8 @@ protected:
} }
} else if (fabs(pidRegulator.integral) > 0.0001f) { } else if (fabs(pidRegulator.integral) > 0.0001f) {
pidRegulator.integral = 0; pidRegulator.integral = 0;
Log.sinfoln(FPSTR(L_REGULATOR_PID), F("Integral sum has been reset")); Log.sinfoln(FPSTR(L_REGULATOR_PID), F("Integral sum has been reset"));
} }
// default temp, manual mode // default temp, manual mode
@@ -259,7 +260,7 @@ protected:
pidRegulator.setLimits(minTemp, maxTemp); pidRegulator.setLimits(minTemp, maxTemp);
pidRegulator.setDt(settings.pid.dt * 1000u); pidRegulator.setDt(settings.pid.dt * 1000u);
pidRegulator.input = vars.temperatures.indoor; pidRegulator.input = vars.temperatures.indoor;
pidRegulator.setpoint = settings.heating.target; pidRegulator.setpoint = vars.states.emergency ? settings.emergency.target : settings.heating.target;
return pidRegulator.getResultTimer(); return pidRegulator.getResultTimer();
} }

View File

@@ -54,8 +54,8 @@ struct Settings {
byte faultStateGpio = DEFAULT_OT_FAULT_STATE_GPIO; byte faultStateGpio = DEFAULT_OT_FAULT_STATE_GPIO;
byte invertFaultState = false; byte invertFaultState = false;
unsigned int memberIdCode = 0; unsigned int memberIdCode = 0;
float pressureMultiplier = 1.0f; float pressureFactor = 1.0f;
float dhwFlowRateMultiplier = 1.0f; float dhwFlowRateFactor = 1.0f;
bool dhwPresent = true; bool dhwPresent = true;
bool summerWinterMode = false; bool summerWinterMode = false;
bool heatingCh2Enabled = true; bool heatingCh2Enabled = true;
@@ -66,7 +66,11 @@ struct Settings {
bool getMinMaxTemp = true; bool getMinMaxTemp = true;
bool nativeHeatingControl = false; bool nativeHeatingControl = false;
bool immergasFix = false; bool immergasFix = false;
bool filteringNumValues = false;
struct {
bool enable = false;
float factor = 0.1f;
} filterNumValues;
} opentherm; } opentherm;
struct { struct {

View File

@@ -5,7 +5,6 @@
#define EXT_SENSORS_INTERVAL 5000 #define EXT_SENSORS_INTERVAL 5000
#define EXT_SENSORS_FILTER_K 0.15 #define EXT_SENSORS_FILTER_K 0.15
#define OT_NUM_VALUES_FILTER_K 0.1
#define CONFIG_URL "http://%s/" #define CONFIG_URL "http://%s/"
#define SETTINGS_VALID_VALUE "stvalid" // only 8 chars! #define SETTINGS_VALID_VALUE "stvalid" // only 8 chars!

View File

@@ -345,8 +345,8 @@ void settingsToJson(const Settings& src, JsonVariant dst, bool safe = false) {
dst["opentherm"]["faultStateGpio"] = src.opentherm.faultStateGpio; dst["opentherm"]["faultStateGpio"] = src.opentherm.faultStateGpio;
dst["opentherm"]["invertFaultState"] = src.opentherm.invertFaultState; dst["opentherm"]["invertFaultState"] = src.opentherm.invertFaultState;
dst["opentherm"]["memberIdCode"] = src.opentherm.memberIdCode; dst["opentherm"]["memberIdCode"] = src.opentherm.memberIdCode;
dst["opentherm"]["pressureMultiplier"] = roundd(src.opentherm.pressureMultiplier, 2); dst["opentherm"]["pressureFactor"] = roundd(src.opentherm.pressureFactor, 2);
dst["opentherm"]["dhwFlowRateMultiplier"] = roundd(src.opentherm.dhwFlowRateMultiplier, 2); dst["opentherm"]["dhwFlowRateFactor"] = roundd(src.opentherm.dhwFlowRateFactor, 2);
dst["opentherm"]["dhwPresent"] = src.opentherm.dhwPresent; dst["opentherm"]["dhwPresent"] = src.opentherm.dhwPresent;
dst["opentherm"]["summerWinterMode"] = src.opentherm.summerWinterMode; dst["opentherm"]["summerWinterMode"] = src.opentherm.summerWinterMode;
dst["opentherm"]["heatingCh2Enabled"] = src.opentherm.heatingCh2Enabled; dst["opentherm"]["heatingCh2Enabled"] = src.opentherm.heatingCh2Enabled;
@@ -357,7 +357,8 @@ void settingsToJson(const Settings& src, JsonVariant dst, bool safe = false) {
dst["opentherm"]["getMinMaxTemp"] = src.opentherm.getMinMaxTemp; dst["opentherm"]["getMinMaxTemp"] = src.opentherm.getMinMaxTemp;
dst["opentherm"]["nativeHeatingControl"] = src.opentherm.nativeHeatingControl; dst["opentherm"]["nativeHeatingControl"] = src.opentherm.nativeHeatingControl;
dst["opentherm"]["immergasFix"] = src.opentherm.immergasFix; dst["opentherm"]["immergasFix"] = src.opentherm.immergasFix;
dst["opentherm"]["filteringNumValues"] = src.opentherm.filteringNumValues; dst["opentherm"]["filterNumValues"]["enable"] = src.opentherm.filterNumValues.enable;
dst["opentherm"]["filterNumValues"]["factor"] = roundd(src.opentherm.filterNumValues.factor, 2);
dst["mqtt"]["enable"] = src.mqtt.enable; dst["mqtt"]["enable"] = src.mqtt.enable;
dst["mqtt"]["server"] = src.mqtt.server; dst["mqtt"]["server"] = src.mqtt.server;
@@ -697,20 +698,38 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false
} }
} }
if (!src["opentherm"]["pressureMultiplier"].isNull()) { if (!src["opentherm"]["pressureFactor"].isNull()) {
float value = src["opentherm"]["pressureMultiplier"].as<float>(); float value = src["opentherm"]["pressureFactor"].as<float>();
if (value > 0 && value <= 100 && fabs(value - dst.opentherm.pressureMultiplier) > 0.0001f) { if (value > 0 && value <= 100 && fabs(value - dst.opentherm.pressureFactor) > 0.0001f) {
dst.opentherm.pressureMultiplier = roundd(value, 2); dst.opentherm.pressureFactor = roundd(value, 2);
changed = true; changed = true;
} }
} }
if (!src["opentherm"]["dhwFlowRateMultiplier"].isNull()) { if (!src["opentherm"]["dhwFlowRateFactor"].isNull()) {
float value = src["opentherm"]["dhwFlowRateMultiplier"].as<float>(); float value = src["opentherm"]["dhwFlowRateFactor"].as<float>();
if (value > 0 && value <= 100 && fabs(value - dst.opentherm.dhwFlowRateMultiplier) > 0.0001f) { if (value > 0 && value <= 100 && fabs(value - dst.opentherm.dhwFlowRateFactor) > 0.0001f) {
dst.opentherm.dhwFlowRateMultiplier = roundd(value, 2); dst.opentherm.dhwFlowRateFactor = roundd(value, 2);
changed = true;
}
}
if (src["opentherm"]["filterNumValues"]["enable"].is<bool>()) {
bool value = src["opentherm"]["filterNumValues"]["enable"].as<bool>();
if (value != dst.opentherm.filterNumValues.enable) {
dst.opentherm.filterNumValues.enable = value;
changed = true;
}
}
if (!src["opentherm"]["filterNumValues"]["factor"].isNull()) {
float value = src["opentherm"]["filterNumValues"]["factor"].as<float>();
if (value > 0 && value <= 1 && fabs(value - dst.opentherm.filterNumValues.factor) > 0.0001f) {
dst.opentherm.filterNumValues.factor = roundd(value, 2);
changed = true; changed = true;
} }
} }
@@ -831,15 +850,6 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false
} }
} }
if (src["opentherm"]["filteringNumValues"].is<bool>()) {
bool value = src["opentherm"]["filteringNumValues"].as<bool>();
if (value != dst.opentherm.filteringNumValues) {
dst.opentherm.filteringNumValues = value;
changed = true;
}
}
// mqtt // mqtt
if (src["mqtt"]["enable"].is<bool>()) { if (src["mqtt"]["enable"].is<bool>()) {

View File

@@ -261,13 +261,24 @@
"outGpio": "Out GPIO", "outGpio": "Out GPIO",
"ledGpio": "RX LED GPIO", "ledGpio": "RX LED GPIO",
"memberIdCode": "Master MemberID code", "memberIdCode": "Master MemberID code",
"pressureMultiplier": { "pressureFactor": {
"title": "Coeff. pressure correction", "title": "Coeff. pressure correction",
"note": "If the pressure displayed is <b>X10</b> from the real one, set the <b>10</b>." "note": "If the pressure displayed is <b>X10</b> from the real one, set the <b>0.1</b>."
}, },
"dhwFlowRateMultiplier": { "dhwFlowRateFactor": {
"title": "Coeff. DHW flow rate correction", "title": "Coeff. DHW flow rate correction",
"note": "If the DHW flow rate displayed is <b>X10</b> from the real one, set the <b>10</b>." "note": "If the DHW flow rate displayed is <b>X10</b> from the real one, set the <b>0.1</b>."
},
"fnv": {
"title": "Filtering numeric values",
"enable": {
"title": "Enable filtering",
"note": "It can be useful if there is a lot of sharp noise on the charts. The filter used is \"Running Average\"."
},
"factor": {
"title": "Filtration coeff.",
"note": "The lower the value, the smoother and <u>longer</u> the change in numeric values."
}
}, },
"options": { "options": {
@@ -279,8 +290,7 @@
"dhwBlocking": "DHW blocking", "dhwBlocking": "DHW blocking",
"modulationSyncWithHeating": "Sync modulation with heating", "modulationSyncWithHeating": "Sync modulation with heating",
"getMinMaxTemp": "Get min/max temp from boiler", "getMinMaxTemp": "Get min/max temp from boiler",
"immergasFix": "Fix for Immergas boilers", "immergasFix": "Fix for Immergas boilers"
"filteringNumValues": "Use filtering for numeric values"
}, },
"faultState": { "faultState": {

View File

@@ -261,13 +261,24 @@
"outGpio": "Выход GPIO", "outGpio": "Выход GPIO",
"ledGpio": "RX LED GPIO", "ledGpio": "RX LED GPIO",
"memberIdCode": "Master MemberID код", "memberIdCode": "Master MemberID код",
"pressureMultiplier": { "pressureFactor": {
"title": "Коэфф. коррекции давления", "title": "Коэфф. коррекции давления",
"note": "Если давление отображается <b>Х10</b> от реального, установите значение <b>10</b>." "note": "Если давление отображается <b>Х10</b> от реального, установите значение <b>0.1</b>."
}, },
"dhwFlowRateMultiplier": { "dhwFlowRateFactor": {
"title": "Коэфф. коррекции потока ГВС", "title": "Коэфф. коррекции потока ГВС",
"note": "Если поток ГВС отображается <b>Х10</b> от реального, установите значение <b>10</b>." "note": "Если поток ГВС отображается <b>Х10</b> от реального, установите значение <b>0.1</b>."
},
"fnv": {
"title": "Фильтрация числовых значений",
"enable": {
"title": "Включить фильтрацию",
"note": "Может быть полезно, если на графиках много резкого шума. В качестве фильтра используется \"бегущее среднее\"."
},
"factor": {
"title": "Коэфф. фильтрации",
"note": "Чем меньше коэф., тем плавнее и <u>дольше</u> изменение числовых значений."
}
}, },
"options": { "options": {
@@ -279,8 +290,7 @@
"dhwBlocking": "DHW blocking", "dhwBlocking": "DHW blocking",
"modulationSyncWithHeating": "Синхронизировать модуляцию с отоплением", "modulationSyncWithHeating": "Синхронизировать модуляцию с отоплением",
"getMinMaxTemp": "Получать мин. и макс. температуру от котла", "getMinMaxTemp": "Получать мин. и макс. температуру от котла",
"immergasFix": "Фикс для котлов Immergas", "immergasFix": "Фикс для котлов Immergas"
"filteringNumValues": "Использовать фильтрацию для числовых значений"
}, },
"faultState": { "faultState": {

View File

@@ -402,16 +402,16 @@
</div> </div>
<div class="grid"> <div class="grid">
<label for="opentherm-pressure-multiplier"> <label for="opentherm-pressure-factor">
<span data-i18n>settings.ot.pressureMultiplier.title</span> <span data-i18n>settings.ot.pressureFactor.title</span>
<input type="number" inputmode="numeric" id="opentherm-pressure-multiplier" name="opentherm[pressureMultiplier]" min="0.1" max="100" step="0.01"> <input type="number" inputmode="numeric" id="opentherm-pressure-factor" name="opentherm[pressureFactor]" min="0.1" max="100" step="0.01">
<small data-i18n>settings.ot.pressureMultiplier.note</small> <small data-i18n>settings.ot.pressureFactor.note</small>
</label> </label>
<label for="opentherm-dhw-fr-multiplier"> <label for="opentherm-dhw-fr-factor">
<span data-i18n>settings.ot.dhwFlowRateMultiplier.title</span> <span data-i18n>settings.ot.dhwFlowRateFactor.title</span>
<input type="number" inputmode="numeric" id="opentherm-dhw-fr-multiplier" name="opentherm[dhwFlowRateMultiplier]" min="0.1" max="100" step="0.01"> <input type="number" inputmode="numeric" id="opentherm-dhw-fr-factor" name="opentherm[dhwFlowRateFactor]" min="0.1" max="100" step="0.01">
<small data-i18n>settings.ot.dhwFlowRateMultiplier.note</small> <small data-i18n>settings.ot.dhwFlowRateFactor.note</small>
</label> </label>
</div> </div>
@@ -462,10 +462,25 @@
<span data-i18n>settings.ot.options.immergasFix</span> <span data-i18n>settings.ot.options.immergasFix</span>
</label> </label>
<label for="opentherm-filtering-num-values"> <hr />
<input type="checkbox" id="opentherm-filtering-num-values" name="opentherm[filteringNumValues]" value="true"> <fieldset>
<span data-i18n>settings.ot.options.filteringNumValues</span> <legend>
</label> <span data-i18n>settings.ot.fnv.title</span>
</legend>
<label for="opentherm-fnv-enable">
<input type="checkbox" id="opentherm-fnv-enable" name="opentherm[filterNumValues][enable]" value="true">
<span data-i18n>settings.ot.fnv.enable.title</span>
<br>
<small data-i18n>settings.ot.fnv.enable.note</small>
</label>
<label for="opentherm-fnv-factor">
<span data-i18n>settings.ot.fnv.factor.title</span>
<input type="number" inputmode="numeric" id="opentherm-fnv-factor" name="opentherm[filterNumValues][factor]" min="0.01" max="1" step="0.01">
<small data-i18n>settings.ot.fnv.factor.note</small>
</label>
</fieldset>
<hr /> <hr />
<fieldset> <fieldset>
@@ -751,8 +766,8 @@
setInputValue('#opentherm-fault-state-gpio', data.opentherm.faultStateGpio < 255 ? data.opentherm.faultStateGpio : ''); setInputValue('#opentherm-fault-state-gpio', data.opentherm.faultStateGpio < 255 ? data.opentherm.faultStateGpio : '');
setCheckboxValue('#opentherm-invert-fault-state', data.opentherm.invertFaultState); setCheckboxValue('#opentherm-invert-fault-state', data.opentherm.invertFaultState);
setInputValue('#opentherm-member-id-code', data.opentherm.memberIdCode); setInputValue('#opentherm-member-id-code', data.opentherm.memberIdCode);
setInputValue('#opentherm-pressure-multiplier', data.opentherm.pressureMultiplier); setInputValue('#opentherm-pressure-factor', data.opentherm.pressureFactor);
setInputValue('#opentherm-dhw-fr-multiplier', data.opentherm.dhwFlowRateMultiplier); setInputValue('#opentherm-dhw-fr-factor', data.opentherm.dhwFlowRateFactor);
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);
setCheckboxValue('#opentherm-heating-ch2-enabled', data.opentherm.heatingCh2Enabled); setCheckboxValue('#opentherm-heating-ch2-enabled', data.opentherm.heatingCh2Enabled);
@@ -763,7 +778,8 @@
setCheckboxValue('#opentherm-get-min-max-temp', data.opentherm.getMinMaxTemp); setCheckboxValue('#opentherm-get-min-max-temp', data.opentherm.getMinMaxTemp);
setCheckboxValue('#opentherm-native-heating-control', data.opentherm.nativeHeatingControl); setCheckboxValue('#opentherm-native-heating-control', data.opentherm.nativeHeatingControl);
setCheckboxValue('#opentherm-immergas-fix', data.opentherm.immergasFix); setCheckboxValue('#opentherm-immergas-fix', data.opentherm.immergasFix);
setCheckboxValue('#opentherm-filtering-num-values', data.opentherm.filteringNumValues); setCheckboxValue('#opentherm-fnv-enable', data.opentherm.filterNumValues.enable);
setInputValue('#opentherm-fnv-factor', data.opentherm.filterNumValues.factor);
setBusy('#opentherm-settings-busy', '#opentherm-settings', false); setBusy('#opentherm-settings-busy', '#opentherm-settings', false);
// MQTT // MQTT