mirror of
https://github.com/Laxilef/OTGateway.git
synced 2026-11-11 08:54:51 +05:00
feat: configure OpenTherm channel disabling actions
This commit is contained in:
1 parent
4581ca49cb
commit
c63b8d44a1
11 files changed
+229
-94
No files matched your search
+47
-32
@@ -182,7 +182,8 @@ protected:
|
|||||||
&& !vars.master.heating.overheat;
|
&& !vars.master.heating.overheat;
|
||||||
|
|
||||||
// DHW settings
|
// DHW settings
|
||||||
vars.master.dhw.enabled = settings.opentherm.options.dhwSupport
|
vars.master.dhw.enabled = this->isReady()
|
||||||
|
&& settings.opentherm.options.dhwSupport
|
||||||
&& settings.dhw.enabled
|
&& settings.dhw.enabled
|
||||||
&& !vars.master.dhw.overheat;
|
&& !vars.master.dhw.overheat;
|
||||||
vars.master.dhw.targetTemp = settings.dhw.target;
|
vars.master.dhw.targetTemp = settings.dhw.target;
|
||||||
@@ -190,7 +191,7 @@ protected:
|
|||||||
// CH2 settings
|
// CH2 settings
|
||||||
vars.master.ch2.enabled = settings.opentherm.options.ch2AlwaysEnabled
|
vars.master.ch2.enabled = settings.opentherm.options.ch2AlwaysEnabled
|
||||||
|| (settings.opentherm.options.heatingToCh2 && vars.master.heating.enabled)
|
|| (settings.opentherm.options.heatingToCh2 && vars.master.heating.enabled)
|
||||||
|| (settings.opentherm.options.dhwToCh2 && settings.opentherm.options.dhwSupport && settings.dhw.enabled);
|
|| (settings.opentherm.options.dhwToCh2 && vars.master.dhw.enabled);
|
||||||
|
|
||||||
if (settings.opentherm.options.heatingToCh2) {
|
if (settings.opentherm.options.heatingToCh2) {
|
||||||
vars.master.ch2.targetTemp = !settings.opentherm.options.nativeOTC
|
vars.master.ch2.targetTemp = !settings.opentherm.options.nativeOTC
|
||||||
@@ -211,6 +212,7 @@ protected:
|
|||||||
statusLb = 0xCA;
|
statusLb = 0xCA;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Mode flags follow the channel request, before applying its disabling action.
|
||||||
// Summer/winter mode
|
// Summer/winter mode
|
||||||
bool summerWinterMode = settings.opentherm.options.summerWinterMode;
|
bool summerWinterMode = settings.opentherm.options.summerWinterMode;
|
||||||
if (settings.opentherm.options.heatingStateToSummerWinterMode) {
|
if (settings.opentherm.options.heatingStateToSummerWinterMode) {
|
||||||
@@ -224,11 +226,11 @@ protected:
|
|||||||
}
|
}
|
||||||
|
|
||||||
unsigned long response = this->instance->setBoilerStatus(
|
unsigned long response = this->instance->setBoilerStatus(
|
||||||
vars.master.heating.enabled,
|
this->getSlaveChannelEnabled(vars.master.heating.enabled, settings.opentherm.heatingDisablingAction),
|
||||||
vars.master.dhw.enabled,
|
settings.opentherm.options.dhwSupport && this->getSlaveChannelEnabled(vars.master.dhw.enabled, settings.opentherm.dhwDisablingAction),
|
||||||
settings.opentherm.options.coolingSupport,
|
settings.opentherm.options.coolingSupport,
|
||||||
settings.opentherm.options.nativeOTC,
|
settings.opentherm.options.nativeOTC,
|
||||||
vars.master.ch2.enabled,
|
this->getSlaveChannelEnabled(vars.master.ch2.enabled, settings.opentherm.ch2DisablingAction),
|
||||||
summerWinterMode,
|
summerWinterMode,
|
||||||
dhwBlocking,
|
dhwBlocking,
|
||||||
statusLb
|
statusLb
|
||||||
@@ -1222,16 +1224,14 @@ protected:
|
|||||||
|
|
||||||
|
|
||||||
// Update DHW temp
|
// Update DHW temp
|
||||||
if (vars.master.dhw.enabled) {
|
if (settings.opentherm.options.dhwSupport) {
|
||||||
// Target dhw temp
|
// Target dhw temp
|
||||||
const float& targetTemp = vars.master.dhw.targetTemp;
|
const float targetTemp = this->getSlaveChannelSetpoint(
|
||||||
|
vars.master.dhw.enabled, vars.master.dhw.targetTemp, settings.opentherm.dhwDisablingAction
|
||||||
|
);
|
||||||
|
|
||||||
// Converted target dhw temp
|
// Converted target dhw temp
|
||||||
const float convertedTemp = convertTemp(
|
const float convertedTemp = this->convertSetpointTemp(targetTemp);
|
||||||
targetTemp,
|
|
||||||
settings.system.unitSystem,
|
|
||||||
settings.opentherm.unitSystem
|
|
||||||
);
|
|
||||||
|
|
||||||
// Set DHW temp
|
// Set DHW temp
|
||||||
if (this->needSetDhwTemp(convertedTemp)) {
|
if (this->needSetDhwTemp(convertedTemp)) {
|
||||||
@@ -1328,19 +1328,16 @@ protected:
|
|||||||
// Set heating temp
|
// Set heating temp
|
||||||
{
|
{
|
||||||
// Target heating temp
|
// Target heating temp
|
||||||
float targetTemp = 0.0f;
|
const float targetTemp = this->getSlaveChannelSetpoint(
|
||||||
if (vars.master.heating.enabled) {
|
vars.master.heating.enabled,
|
||||||
targetTemp = !settings.opentherm.options.nativeOTC
|
settings.opentherm.options.nativeOTC
|
||||||
? vars.master.heating.setpointTemp
|
? vars.master.heating.targetTemp
|
||||||
: vars.master.heating.targetTemp;
|
: vars.master.heating.setpointTemp,
|
||||||
}
|
settings.opentherm.heatingDisablingAction
|
||||||
|
);
|
||||||
|
|
||||||
// Converted target heating temp
|
// Converted target heating temp
|
||||||
const float convertedTemp = convertTemp(
|
const float convertedTemp = this->convertSetpointTemp(targetTemp);
|
||||||
targetTemp,
|
|
||||||
settings.system.unitSystem,
|
|
||||||
settings.opentherm.unitSystem
|
|
||||||
);
|
|
||||||
|
|
||||||
if (this->needSetHeatingTemp(convertedTemp)) {
|
if (this->needSetHeatingTemp(convertedTemp)) {
|
||||||
// Set max heating temp
|
// Set max heating temp
|
||||||
@@ -1375,18 +1372,15 @@ protected:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Set CH2 temp
|
// Set CH2 temp
|
||||||
if (settings.opentherm.options.heatingToCh2 || settings.opentherm.options.dhwToCh2) {
|
if (settings.opentherm.options.heatingToCh2 || settings.opentherm.options.dhwToCh2
|
||||||
|
|| (!vars.master.ch2.enabled && settings.opentherm.ch2DisablingAction != ChannelDisablingAction::OFF)) {
|
||||||
// Target CH2 heating temp
|
// Target CH2 heating temp
|
||||||
const float targetTemp = vars.master.ch2.enabled
|
const float targetTemp = this->getSlaveChannelSetpoint(
|
||||||
? vars.master.ch2.targetTemp
|
vars.master.ch2.enabled, vars.master.ch2.targetTemp, settings.opentherm.ch2DisablingAction
|
||||||
: 0.0f;
|
);
|
||||||
|
|
||||||
// Converted target CH2 temp
|
// Converted target CH2 temp
|
||||||
const float convertedTemp = convertTemp(
|
const float convertedTemp = this->convertSetpointTemp(targetTemp);
|
||||||
targetTemp,
|
|
||||||
settings.system.unitSystem,
|
|
||||||
settings.opentherm.unitSystem
|
|
||||||
);
|
|
||||||
|
|
||||||
if (this->needSetCh2Temp(convertedTemp)) {
|
if (this->needSetCh2Temp(convertedTemp)) {
|
||||||
if (this->setCh2Temp(convertedTemp)) {
|
if (this->setCh2Temp(convertedTemp)) {
|
||||||
@@ -1556,6 +1550,27 @@ protected:
|
|||||||
return millis() - this->instanceCreatedTime > this->readyTime;
|
return millis() - this->instanceCreatedTime > this->readyTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool getSlaveChannelEnabled(const bool enabled, const ChannelDisablingAction action) {
|
||||||
|
return enabled || action == ChannelDisablingAction::ZERO_SETPOINT;
|
||||||
|
}
|
||||||
|
|
||||||
|
float getSlaveChannelSetpoint(const bool enabled, const float temperature, const ChannelDisablingAction action) {
|
||||||
|
if (!enabled && action != ChannelDisablingAction::OFF) {
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
return temperature;
|
||||||
|
}
|
||||||
|
|
||||||
|
float convertSetpointTemp(const float temperature) {
|
||||||
|
// Preserve the no-demand zero for TSet/TsetCH2 when converting units.
|
||||||
|
if (temperature == 0.0f) {
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
return convertTemp(temperature, settings.system.unitSystem, settings.opentherm.unitSystem);
|
||||||
|
}
|
||||||
|
|
||||||
bool needSetRoomSetpoint(const float target) {
|
bool needSetRoomSetpoint(const float target) {
|
||||||
return !this->roomSetTempTime
|
return !this->roomSetTempTime
|
||||||
|| millis() - this->roomSetTempTime > this->heatingSetTempInterval
|
|| millis() - this->roomSetTempTime > this->heatingSetTempInterval
|
||||||
|
|||||||
+3
-1
@@ -58,6 +58,9 @@ struct Settings {
|
|||||||
uint8_t rxLedGpio = DEFAULT_OT_RX_LED_GPIO;
|
uint8_t rxLedGpio = DEFAULT_OT_RX_LED_GPIO;
|
||||||
uint8_t memberId = 0;
|
uint8_t memberId = 0;
|
||||||
uint8_t flags = 0;
|
uint8_t flags = 0;
|
||||||
|
ChannelDisablingAction heatingDisablingAction = ChannelDisablingAction::OFF_AND_ZERO_SETPOINT;
|
||||||
|
ChannelDisablingAction dhwDisablingAction = ChannelDisablingAction::OFF_AND_ZERO_SETPOINT;
|
||||||
|
ChannelDisablingAction ch2DisablingAction = ChannelDisablingAction::OFF_AND_ZERO_SETPOINT;
|
||||||
float minPower = 0.0f;
|
float minPower = 0.0f;
|
||||||
float maxPower = 0.0f;
|
float maxPower = 0.0f;
|
||||||
|
|
||||||
@@ -113,7 +116,6 @@ struct Settings {
|
|||||||
struct {
|
struct {
|
||||||
bool enabled = true;
|
bool enabled = true;
|
||||||
float value = 0.5f;
|
float value = 0.5f;
|
||||||
HysteresisAction action = HysteresisAction::DISABLE_HEATING;
|
|
||||||
} hysteresis;
|
} hysteresis;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
|
|||||||
+4
-3
@@ -163,9 +163,10 @@ enum class UnitSystem : uint8_t {
|
|||||||
IMPERIAL = 1
|
IMPERIAL = 1
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class HysteresisAction : uint8_t {
|
enum class ChannelDisablingAction : uint8_t {
|
||||||
DISABLE_HEATING = 0,
|
OFF = 0,
|
||||||
SET_ZERO_TARGET = 1
|
ZERO_SETPOINT = 1,
|
||||||
|
OFF_AND_ZERO_SETPOINT = 2
|
||||||
};
|
};
|
||||||
|
|
||||||
char buffer[255];
|
char buffer[255];
|
||||||
+3
-1
@@ -35,7 +35,6 @@ const char L_CASCADE_OUTPUT[] PROGMEM = "CASCADE.OUTPUT";
|
|||||||
const char L_EXTPUMP[] PROGMEM = "EXTPUMP";
|
const char L_EXTPUMP[] PROGMEM = "EXTPUMP";
|
||||||
|
|
||||||
|
|
||||||
const char S_ACTION[] PROGMEM = "action";
|
|
||||||
const char S_ACTIONS[] PROGMEM = "actions";
|
const char S_ACTIONS[] PROGMEM = "actions";
|
||||||
const char S_ACTIVE[] PROGMEM = "active";
|
const char S_ACTIVE[] PROGMEM = "active";
|
||||||
const char S_ADDRESS[] PROGMEM = "address";
|
const char S_ADDRESS[] PROGMEM = "address";
|
||||||
@@ -55,6 +54,7 @@ const char S_BUILD[] PROGMEM = "build";
|
|||||||
const char S_CASCADE_CONTROL[] PROGMEM = "cascadeControl";
|
const char S_CASCADE_CONTROL[] PROGMEM = "cascadeControl";
|
||||||
const char S_CHANNEL[] PROGMEM = "channel";
|
const char S_CHANNEL[] PROGMEM = "channel";
|
||||||
const char S_CH2_ALWAYS_ENABLED[] PROGMEM = "ch2AlwaysEnabled";
|
const char S_CH2_ALWAYS_ENABLED[] PROGMEM = "ch2AlwaysEnabled";
|
||||||
|
const char S_CH2_DISABLING_ACTION[] PROGMEM = "ch2DisablingAction";
|
||||||
const char S_CHIP[] PROGMEM = "chip";
|
const char S_CHIP[] PROGMEM = "chip";
|
||||||
const char S_CODE[] PROGMEM = "code";
|
const char S_CODE[] PROGMEM = "code";
|
||||||
const char S_COMMIT[] PROGMEM = "commit";
|
const char S_COMMIT[] PROGMEM = "commit";
|
||||||
@@ -71,6 +71,7 @@ const char S_DATE[] PROGMEM = "date";
|
|||||||
const char S_DEADBAND[] PROGMEM = "deadband";
|
const char S_DEADBAND[] PROGMEM = "deadband";
|
||||||
const char S_DHW[] PROGMEM = "dhw";
|
const char S_DHW[] PROGMEM = "dhw";
|
||||||
const char S_DHW_BLOCKING[] PROGMEM = "dhwBlocking";
|
const char S_DHW_BLOCKING[] PROGMEM = "dhwBlocking";
|
||||||
|
const char S_DHW_DISABLING_ACTION[] PROGMEM = "dhwDisablingAction";
|
||||||
const char S_DHW_STATE_AS_DHW_BLOCKING[] PROGMEM = "dhwStateAsDhwBlocking";
|
const char S_DHW_STATE_AS_DHW_BLOCKING[] PROGMEM = "dhwStateAsDhwBlocking";
|
||||||
const char S_DHW_SUPPORT[] PROGMEM = "dhwSupport";
|
const char S_DHW_SUPPORT[] PROGMEM = "dhwSupport";
|
||||||
const char S_DHW_TO_CH2[] PROGMEM = "dhwToCh2";
|
const char S_DHW_TO_CH2[] PROGMEM = "dhwToCh2";
|
||||||
@@ -102,6 +103,7 @@ const char S_GET_MIN_MAX_TEMP[] PROGMEM = "getMinMaxTemp";
|
|||||||
const char S_GPIO[] PROGMEM = "gpio";
|
const char S_GPIO[] PROGMEM = "gpio";
|
||||||
const char S_HEAP[] PROGMEM = "heap";
|
const char S_HEAP[] PROGMEM = "heap";
|
||||||
const char S_HEATING[] PROGMEM = "heating";
|
const char S_HEATING[] PROGMEM = "heating";
|
||||||
|
const char S_HEATING_DISABLING_ACTION[] PROGMEM = "heatingDisablingAction";
|
||||||
const char S_HEATING_TO_CH2[] PROGMEM = "heatingToCh2";
|
const char S_HEATING_TO_CH2[] PROGMEM = "heatingToCh2";
|
||||||
const char S_HEATING_STATE_TO_SUMMER_WINTER_MODE[] PROGMEM = "heatingStateToSummerWinterMode";
|
const char S_HEATING_STATE_TO_SUMMER_WINTER_MODE[] PROGMEM = "heatingStateToSummerWinterMode";
|
||||||
const char S_HIDDEN[] PROGMEM = "hidden";
|
const char S_HIDDEN[] PROGMEM = "hidden";
|
||||||
|
|||||||
+38
-18
@@ -444,6 +444,9 @@ void settingsToJson(const Settings& src, JsonVariant dst, bool safe = false) {
|
|||||||
opentherm[FPSTR(S_RX_LED_GPIO)] = src.opentherm.rxLedGpio;
|
opentherm[FPSTR(S_RX_LED_GPIO)] = src.opentherm.rxLedGpio;
|
||||||
opentherm[FPSTR(S_MEMBER_ID)] = src.opentherm.memberId;
|
opentherm[FPSTR(S_MEMBER_ID)] = src.opentherm.memberId;
|
||||||
opentherm[FPSTR(S_FLAGS)] = src.opentherm.flags;
|
opentherm[FPSTR(S_FLAGS)] = src.opentherm.flags;
|
||||||
|
opentherm[FPSTR(S_HEATING_DISABLING_ACTION)] = static_cast<uint8_t>(src.opentherm.heatingDisablingAction);
|
||||||
|
opentherm[FPSTR(S_DHW_DISABLING_ACTION)] = static_cast<uint8_t>(src.opentherm.dhwDisablingAction);
|
||||||
|
opentherm[FPSTR(S_CH2_DISABLING_ACTION)] = static_cast<uint8_t>(src.opentherm.ch2DisablingAction);
|
||||||
opentherm[FPSTR(S_MIN_POWER)] = roundf(src.opentherm.minPower, 2);
|
opentherm[FPSTR(S_MIN_POWER)] = roundf(src.opentherm.minPower, 2);
|
||||||
opentherm[FPSTR(S_MAX_POWER)] = roundf(src.opentherm.maxPower, 2);
|
opentherm[FPSTR(S_MAX_POWER)] = roundf(src.opentherm.maxPower, 2);
|
||||||
|
|
||||||
@@ -489,7 +492,6 @@ void settingsToJson(const Settings& src, JsonVariant dst, bool safe = false) {
|
|||||||
heating[FPSTR(S_TARGET)] = roundf(src.heating.target, 2);
|
heating[FPSTR(S_TARGET)] = roundf(src.heating.target, 2);
|
||||||
heating[FPSTR(S_HYSTERESIS)][FPSTR(S_ENABLED)] = src.heating.hysteresis.enabled;
|
heating[FPSTR(S_HYSTERESIS)][FPSTR(S_ENABLED)] = src.heating.hysteresis.enabled;
|
||||||
heating[FPSTR(S_HYSTERESIS)][FPSTR(S_VALUE)] = roundf(src.heating.hysteresis.value, 3);
|
heating[FPSTR(S_HYSTERESIS)][FPSTR(S_VALUE)] = roundf(src.heating.hysteresis.value, 3);
|
||||||
heating[FPSTR(S_HYSTERESIS)][FPSTR(S_ACTION)] = static_cast<uint8_t>(src.heating.hysteresis.action);
|
|
||||||
heating[FPSTR(S_TURBO_FACTOR)] = roundf(src.heating.turboFactor, 3);
|
heating[FPSTR(S_TURBO_FACTOR)] = roundf(src.heating.turboFactor, 3);
|
||||||
heating[FPSTR(S_MIN_TEMP)] = src.heating.minTemp;
|
heating[FPSTR(S_MIN_TEMP)] = src.heating.minTemp;
|
||||||
heating[FPSTR(S_MAX_TEMP)] = src.heating.maxTemp;
|
heating[FPSTR(S_MAX_TEMP)] = src.heating.maxTemp;
|
||||||
@@ -570,6 +572,29 @@ inline void safeSettingsToJson(const Settings& src, JsonVariant dst) {
|
|||||||
settingsToJson(src, dst, true);
|
settingsToJson(src, dst, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool jsonToChannelDisablingAction(const JsonVariantConst src, ChannelDisablingAction& dst) {
|
||||||
|
if (!src.is<uint8_t>()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const uint8_t value = src.as<uint8_t>();
|
||||||
|
switch (value) {
|
||||||
|
case static_cast<uint8_t>(ChannelDisablingAction::OFF):
|
||||||
|
case static_cast<uint8_t>(ChannelDisablingAction::ZERO_SETPOINT):
|
||||||
|
case static_cast<uint8_t>(ChannelDisablingAction::OFF_AND_ZERO_SETPOINT):
|
||||||
|
if (static_cast<uint8_t>(dst) != value) {
|
||||||
|
dst = static_cast<ChannelDisablingAction>(value);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false) {
|
bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false) {
|
||||||
bool changed = false;
|
bool changed = false;
|
||||||
|
|
||||||
@@ -822,6 +847,18 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (jsonToChannelDisablingAction(src[FPSTR(S_OPENTHERM)][FPSTR(S_HEATING_DISABLING_ACTION)], dst.opentherm.heatingDisablingAction)) {
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (jsonToChannelDisablingAction(src[FPSTR(S_OPENTHERM)][FPSTR(S_DHW_DISABLING_ACTION)], dst.opentherm.dhwDisablingAction)) {
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (jsonToChannelDisablingAction(src[FPSTR(S_OPENTHERM)][FPSTR(S_CH2_DISABLING_ACTION)], dst.opentherm.ch2DisablingAction)) {
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (!src[FPSTR(S_OPENTHERM)][FPSTR(S_MIN_POWER)].isNull()) {
|
if (!src[FPSTR(S_OPENTHERM)][FPSTR(S_MIN_POWER)].isNull()) {
|
||||||
float value = src[FPSTR(S_OPENTHERM)][FPSTR(S_MIN_POWER)].as<float>();
|
float value = src[FPSTR(S_OPENTHERM)][FPSTR(S_MIN_POWER)].as<float>();
|
||||||
|
|
||||||
@@ -1332,23 +1369,6 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!src[FPSTR(S_HEATING)][FPSTR(S_HYSTERESIS)][FPSTR(S_ACTION)].isNull()) {
|
|
||||||
uint8_t value = src[FPSTR(S_HEATING)][FPSTR(S_HYSTERESIS)][FPSTR(S_ACTION)].as<uint8_t>();
|
|
||||||
|
|
||||||
switch (value) {
|
|
||||||
case static_cast<uint8_t>(HysteresisAction::DISABLE_HEATING):
|
|
||||||
case static_cast<uint8_t>(HysteresisAction::SET_ZERO_TARGET):
|
|
||||||
if (static_cast<uint8_t>(dst.heating.hysteresis.action) != value) {
|
|
||||||
dst.heating.hysteresis.action = static_cast<HysteresisAction>(value);
|
|
||||||
changed = true;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!src[FPSTR(S_HEATING)][FPSTR(S_TURBO_FACTOR)].isNull()) {
|
if (!src[FPSTR(S_HEATING)][FPSTR(S_TURBO_FACTOR)].isNull()) {
|
||||||
float value = src[FPSTR(S_HEATING)][FPSTR(S_TURBO_FACTOR)].as<float>();
|
float value = src[FPSTR(S_HEATING)][FPSTR(S_TURBO_FACTOR)].as<float>();
|
||||||
|
|
||||||
|
|||||||
@@ -352,12 +352,7 @@
|
|||||||
"hyst": {
|
"hyst": {
|
||||||
"title": "滞回",
|
"title": "滞回",
|
||||||
"desc": "滞回有助于维持设定的室内温度(在使用«Equitherm»和/或«PID»时)。强制禁用加热当<code>current indoor > target + value</code>,启用加热当<code>current indoor < (target - value)</code>。",
|
"desc": "滞回有助于维持设定的室内温度(在使用«Equitherm»和/或«PID»时)。强制禁用加热当<code>current indoor > target + value</code>,启用加热当<code>current indoor < (target - value)</code>。",
|
||||||
"value": "值 <small>(以度为单位)</small>",
|
"value": "值 <small>(以度为单位)</small>"
|
||||||
"action": {
|
|
||||||
"title": "行动",
|
|
||||||
"disableHeating": "禁用加热",
|
|
||||||
"set0target": "设置空目标"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"turboFactor": "Turbo 模式系数",
|
"turboFactor": "Turbo 模式系数",
|
||||||
"indoorTempAvgType": {
|
"indoorTempAvgType": {
|
||||||
@@ -420,6 +415,16 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"ot": {
|
"ot": {
|
||||||
|
"disablingAction": {
|
||||||
|
"title": "回路关闭方式",
|
||||||
|
"desc": "无论因何原因关闭回路,包括过热,均采用所选的关闭方式。<br />某些锅炉会在关闭回路时停止循环泵,此时可尝试将目标温度设为 <b>0</b>,以使循环泵的延时运转功能正常工作。",
|
||||||
|
"heating": "采暖回路",
|
||||||
|
"dhw": "生活热水回路",
|
||||||
|
"ch2": "回路 2",
|
||||||
|
"off": "仅关闭回路",
|
||||||
|
"zeroSetpoint": "将目标温度设为 <b>0</b>",
|
||||||
|
"offAndZeroSetpoint": "关闭回路并将目标温度设为 <b>0</b>"
|
||||||
|
},
|
||||||
"advanced": "高级设置",
|
"advanced": "高级设置",
|
||||||
"inGpio": "In GPIO",
|
"inGpio": "In GPIO",
|
||||||
"outGpio": "Out GPIO",
|
"outGpio": "Out GPIO",
|
||||||
|
|||||||
@@ -352,12 +352,7 @@
|
|||||||
"hyst": {
|
"hyst": {
|
||||||
"title": "Hysteresis",
|
"title": "Hysteresis",
|
||||||
"desc": "Hysteresis is useful for maintaining a set indoor temp (when using «Equitherm» and/or «PID»). Forces disable heating when <code>current indoor > target + value</code> and enable heating when <code>current indoor < (target - value)</code>.",
|
"desc": "Hysteresis is useful for maintaining a set indoor temp (when using «Equitherm» and/or «PID»). Forces disable heating when <code>current indoor > target + value</code> and enable heating when <code>current indoor < (target - value)</code>.",
|
||||||
"value": "Value <small>(in degrees)</small>",
|
"value": "Value <small>(in degrees)</small>"
|
||||||
"action": {
|
|
||||||
"title": "Action",
|
|
||||||
"disableHeating": "Disable heating",
|
|
||||||
"set0target": "Set null target"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"turboFactor": "Turbo mode coeff.",
|
"turboFactor": "Turbo mode coeff.",
|
||||||
"indoorTempAvgType": {
|
"indoorTempAvgType": {
|
||||||
@@ -420,6 +415,16 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"ot": {
|
"ot": {
|
||||||
|
"disablingAction": {
|
||||||
|
"title": "Circuit disabling action",
|
||||||
|
"desc": "The selected action applies whenever the circuit is disabled, including overheating.<br />Some boilers stop the circulation pump when the circuit is disabled. In this case, you can try setting the target temperature to <b>0</b> so that the pump overrun works correctly.",
|
||||||
|
"heating": "Heating circuit",
|
||||||
|
"dhw": "DHW circuit",
|
||||||
|
"ch2": "Circuit 2",
|
||||||
|
"off": "Disable circuit only",
|
||||||
|
"zeroSetpoint": "Set the target temperature to <b>0</b>",
|
||||||
|
"offAndZeroSetpoint": "Disable circuit and set the target temperature to <b>0</b>"
|
||||||
|
},
|
||||||
"advanced": "Advanced Settings",
|
"advanced": "Advanced Settings",
|
||||||
"inGpio": "In GPIO",
|
"inGpio": "In GPIO",
|
||||||
"outGpio": "Out GPIO",
|
"outGpio": "Out GPIO",
|
||||||
|
|||||||
@@ -352,12 +352,7 @@
|
|||||||
"hyst": {
|
"hyst": {
|
||||||
"title": "Isteresi",
|
"title": "Isteresi",
|
||||||
"desc": "L'isteresi è utile per mantenere una temperatura interna impostata (quando si utilizza «Equitherm» e/o «PID»). Forza la disabilitazione del riscaldamento quando <code>current indoor > target + value</code> e abilita il riscaldamento quando <code>current indoor < (target - value)</code>.",
|
"desc": "L'isteresi è utile per mantenere una temperatura interna impostata (quando si utilizza «Equitherm» e/o «PID»). Forza la disabilitazione del riscaldamento quando <code>current indoor > target + value</code> e abilita il riscaldamento quando <code>current indoor < (target - value)</code>.",
|
||||||
"value": "Valore <small>(in gradi)</small>",
|
"value": "Valore <small>(in gradi)</small>"
|
||||||
"action": {
|
|
||||||
"title": "Azione",
|
|
||||||
"disableHeating": "Disabilita riscaldamento",
|
|
||||||
"set0target": "Imposta target nullo"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"turboFactor": "Turbo mode coeff.",
|
"turboFactor": "Turbo mode coeff.",
|
||||||
"indoorTempAvgType": {
|
"indoorTempAvgType": {
|
||||||
@@ -420,6 +415,16 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"ot": {
|
"ot": {
|
||||||
|
"disablingAction": {
|
||||||
|
"title": "Azione di disattivazione dei circuiti",
|
||||||
|
"desc": "L'azione selezionata si applica a ogni disattivazione del circuito, anche in caso di surriscaldamento.<br />Alcune caldaie arrestano la pompa di circolazione quando il circuito viene disattivato; in questo caso si può provare a impostare la temperatura desiderata a <b>0</b>, affinché la post-circolazione della pompa funzioni correttamente.",
|
||||||
|
"heating": "Circuito di riscaldamento",
|
||||||
|
"dhw": "Circuito ACS",
|
||||||
|
"ch2": "Circuito 2",
|
||||||
|
"off": "Disattiva solo il circuito",
|
||||||
|
"zeroSetpoint": "Imposta la temperatura desiderata a <b>0</b>",
|
||||||
|
"offAndZeroSetpoint": "Disattiva il circuito e imposta la temperatura desiderata a <b>0</b>"
|
||||||
|
},
|
||||||
"advanced": "Impostazioni avanzate",
|
"advanced": "Impostazioni avanzate",
|
||||||
"inGpio": "In GPIO",
|
"inGpio": "In GPIO",
|
||||||
"outGpio": "Out GPIO",
|
"outGpio": "Out GPIO",
|
||||||
|
|||||||
@@ -352,12 +352,7 @@
|
|||||||
"hyst": {
|
"hyst": {
|
||||||
"title": "Hysterese",
|
"title": "Hysterese",
|
||||||
"desc": "Hysterese is nuttig voor het handhaven van een ingestelde binnentemperatuur (bij gebruik van «Equitherm» en/of «PID»). Forceert uitschakelen van verwarming wanneer <code>current indoor > target + value</code> en inschakelen van verwarming wanneer <code>current indoor < (target - value)</code>.",
|
"desc": "Hysterese is nuttig voor het handhaven van een ingestelde binnentemperatuur (bij gebruik van «Equitherm» en/of «PID»). Forceert uitschakelen van verwarming wanneer <code>current indoor > target + value</code> en inschakelen van verwarming wanneer <code>current indoor < (target - value)</code>.",
|
||||||
"value": "Waarde <small>(in graden)</small>",
|
"value": "Waarde <small>(in graden)</small>"
|
||||||
"action": {
|
|
||||||
"title": "Actie",
|
|
||||||
"disableHeating": "Verwarming uitschakelen",
|
|
||||||
"set0target": "Stel null target in"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"turboFactor": "Turbomodus coëff.",
|
"turboFactor": "Turbomodus coëff.",
|
||||||
"indoorTempAvgType": {
|
"indoorTempAvgType": {
|
||||||
@@ -420,6 +415,16 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"ot": {
|
"ot": {
|
||||||
|
"disablingAction": {
|
||||||
|
"title": "Actie bij uitschakelen van circuits",
|
||||||
|
"desc": "De gekozen actie geldt bij elke uitschakeling van het circuit, ook bij oververhitting.<br />Sommige ketels schakelen de circulatiepomp uit wanneer het circuit wordt uitgeschakeld. In dat geval kunt u proberen de doeltemperatuur op <b>0</b> in te stellen, zodat de pompnaloop correct werkt.",
|
||||||
|
"heating": "Verwarmingscircuit",
|
||||||
|
"dhw": "Warmtapwatercircuit",
|
||||||
|
"ch2": "Circuit 2",
|
||||||
|
"off": "Alleen het circuit uitschakelen",
|
||||||
|
"zeroSetpoint": "Doeltemperatuur op <b>0</b> instellen",
|
||||||
|
"offAndZeroSetpoint": "Circuit uitschakelen en doeltemperatuur op <b>0</b> instellen"
|
||||||
|
},
|
||||||
"advanced": "Geavanceerde instellingen",
|
"advanced": "Geavanceerde instellingen",
|
||||||
"inGpio": "In GPIO",
|
"inGpio": "In GPIO",
|
||||||
"outGpio": "Uit GPIO",
|
"outGpio": "Uit GPIO",
|
||||||
|
|||||||
@@ -352,12 +352,7 @@
|
|||||||
"hyst": {
|
"hyst": {
|
||||||
"title": "Гистерезис",
|
"title": "Гистерезис",
|
||||||
"desc": "Гистерезис полезен для поддержания заданной внутр. темп. (при использовании «ПЗА» и/или «ПИД»). Принудительно откл. отопление, когда <code>current indoor > target + value</code>, и вкл. отопление, когда <code>current indoor < (target - value)</code>.",
|
"desc": "Гистерезис полезен для поддержания заданной внутр. темп. (при использовании «ПЗА» и/или «ПИД»). Принудительно откл. отопление, когда <code>current indoor > target + value</code>, и вкл. отопление, когда <code>current indoor < (target - value)</code>.",
|
||||||
"value": "Значение <small>(в градусах)</small>",
|
"value": "Значение <small>(в градусах)</small>"
|
||||||
"action": {
|
|
||||||
"title": "Действие",
|
|
||||||
"disableHeating": "Отключить отопление",
|
|
||||||
"set0target": "Установить 0 в качестве целевой темп."
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"turboFactor": "Коэфф. турбо режима",
|
"turboFactor": "Коэфф. турбо режима",
|
||||||
"indoorTempAvgType": {
|
"indoorTempAvgType": {
|
||||||
@@ -420,6 +415,16 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"ot": {
|
"ot": {
|
||||||
|
"disablingAction": {
|
||||||
|
"title": "Действие отключения контуров",
|
||||||
|
"desc": "Выбранное действие применяется при любой причине отключения, включая перегрев.<br />Некоторые котлы отключают циркуляционный насос при отключении контура, в этом случае можно попробовать установить <b>0</b> в качестве целевой температуры, чтобы выбег насоса работал корректно.",
|
||||||
|
"heating": "Контур отопления",
|
||||||
|
"dhw": "Контур ГВС",
|
||||||
|
"ch2": "Контур 2",
|
||||||
|
"off": "Только отключить контур",
|
||||||
|
"zeroSetpoint": "Установить <b>0</b> в качестве целевой температуры",
|
||||||
|
"offAndZeroSetpoint": "Отключить контур и установить <b>0</b> в качестве целевой температуры"
|
||||||
|
},
|
||||||
"advanced": "Дополнительные настройки",
|
"advanced": "Дополнительные настройки",
|
||||||
"inGpio": "Вход GPIO",
|
"inGpio": "Вход GPIO",
|
||||||
"outGpio": "Выход GPIO",
|
"outGpio": "Выход GPIO",
|
||||||
|
|||||||
@@ -239,13 +239,6 @@
|
|||||||
<input type="number" inputmode="decimal" name="heating[hysteresis][value]" min="0" max="5" step="0.05" required>
|
<input type="number" inputmode="decimal" name="heating[hysteresis][value]" min="0" max="5" step="0.05" required>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<label>
|
|
||||||
<span data-i18n>settings.heating.hyst.action.title</span>
|
|
||||||
<select name="heating[hysteresis][action]">
|
|
||||||
<option value="0" data-i18n>settings.heating.hyst.action.disableHeating</option>
|
|
||||||
<option value="1" data-i18n>settings.heating.hyst.action.set0target</option>
|
|
||||||
</select>
|
|
||||||
</label>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -621,6 +614,81 @@
|
|||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<hr />
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary><b data-i18n>settings.ot.disablingAction.title</b></summary>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<fieldset>
|
||||||
|
<small data-i18n>settings.ot.disablingAction.desc</small>
|
||||||
|
</fieldset>
|
||||||
|
|
||||||
|
<fieldset>
|
||||||
|
<legend><b data-i18n>settings.ot.disablingAction.heating</b></legend>
|
||||||
|
|
||||||
|
<label>
|
||||||
|
<input type="radio" name="opentherm[heatingDisablingAction]" value="0" />
|
||||||
|
<span data-i18n>settings.ot.disablingAction.off</span>
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<label>
|
||||||
|
<input type="radio" name="opentherm[heatingDisablingAction]" value="1" />
|
||||||
|
<span data-i18n>settings.ot.disablingAction.zeroSetpoint</span>
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<label>
|
||||||
|
<input type="radio" name="opentherm[heatingDisablingAction]" value="2" />
|
||||||
|
<span data-i18n>settings.ot.disablingAction.offAndZeroSetpoint</span>
|
||||||
|
</label>
|
||||||
|
</fieldset>
|
||||||
|
|
||||||
|
<hr />
|
||||||
|
|
||||||
|
<fieldset>
|
||||||
|
<legend><b data-i18n>settings.ot.disablingAction.dhw</b></legend>
|
||||||
|
|
||||||
|
<label>
|
||||||
|
<input type="radio" name="opentherm[dhwDisablingAction]" value="0" />
|
||||||
|
<span data-i18n>settings.ot.disablingAction.off</span>
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<label>
|
||||||
|
<input type="radio" name="opentherm[dhwDisablingAction]" value="1" />
|
||||||
|
<span data-i18n>settings.ot.disablingAction.zeroSetpoint</span>
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<label>
|
||||||
|
<input type="radio" name="opentherm[dhwDisablingAction]" value="2" />
|
||||||
|
<span data-i18n>settings.ot.disablingAction.offAndZeroSetpoint</span>
|
||||||
|
</label>
|
||||||
|
</fieldset>
|
||||||
|
|
||||||
|
<hr />
|
||||||
|
|
||||||
|
<fieldset>
|
||||||
|
<legend><b data-i18n>settings.ot.disablingAction.ch2</b></legend>
|
||||||
|
|
||||||
|
<label>
|
||||||
|
<input type="radio" name="opentherm[ch2DisablingAction]" value="0" />
|
||||||
|
<span data-i18n>settings.ot.disablingAction.off</span>
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<label>
|
||||||
|
<input type="radio" name="opentherm[ch2DisablingAction]" value="1" />
|
||||||
|
<span data-i18n>settings.ot.disablingAction.zeroSetpoint</span>
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<label>
|
||||||
|
<input type="radio" name="opentherm[ch2DisablingAction]" value="2" />
|
||||||
|
<span data-i18n>settings.ot.disablingAction.offAndZeroSetpoint</span>
|
||||||
|
</label>
|
||||||
|
</fieldset>
|
||||||
|
</div>
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<hr />
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
<summary><b data-i18n>settings.ot.options.title</b></summary>
|
<summary><b data-i18n>settings.ot.options.title</b></summary>
|
||||||
|
|
||||||
@@ -1124,6 +1192,9 @@
|
|||||||
setInputValue("[name='opentherm[flags]']", data.opentherm.flags);
|
setInputValue("[name='opentherm[flags]']", data.opentherm.flags);
|
||||||
setInputValue("[name='opentherm[minPower]']", data.opentherm.minPower);
|
setInputValue("[name='opentherm[minPower]']", data.opentherm.minPower);
|
||||||
setInputValue("[name='opentherm[maxPower]']", data.opentherm.maxPower);
|
setInputValue("[name='opentherm[maxPower]']", data.opentherm.maxPower);
|
||||||
|
setRadioValue("[name='opentherm[heatingDisablingAction]']", data.opentherm.heatingDisablingAction);
|
||||||
|
setRadioValue("[name='opentherm[dhwDisablingAction]']", data.opentherm.dhwDisablingAction);
|
||||||
|
setRadioValue("[name='opentherm[ch2DisablingAction]']", data.opentherm.ch2DisablingAction);
|
||||||
setCheckboxValue("[name='opentherm[options][dhwSupport]']", data.opentherm.options.dhwSupport);
|
setCheckboxValue("[name='opentherm[options][dhwSupport]']", data.opentherm.options.dhwSupport);
|
||||||
setCheckboxValue("[name='opentherm[options][coolingSupport]']", data.opentherm.options.coolingSupport);
|
setCheckboxValue("[name='opentherm[options][coolingSupport]']", data.opentherm.options.coolingSupport);
|
||||||
setCheckboxValue("[name='opentherm[options][summerWinterMode]']", data.opentherm.options.summerWinterMode);
|
setCheckboxValue("[name='opentherm[options][summerWinterMode]']", data.opentherm.options.summerWinterMode);
|
||||||
@@ -1190,7 +1261,6 @@
|
|||||||
});
|
});
|
||||||
setCheckboxValue("[name='heating[hysteresis][enabled]']", data.heating.hysteresis.enabled);
|
setCheckboxValue("[name='heating[hysteresis][enabled]']", data.heating.hysteresis.enabled);
|
||||||
setInputValue("[name='heating[hysteresis][value]']", data.heating.hysteresis.value);
|
setInputValue("[name='heating[hysteresis][value]']", data.heating.hysteresis.value);
|
||||||
setSelectValue("[name='heating[hysteresis][action]']", data.heating.hysteresis.action);
|
|
||||||
setInputValue("[name='heating[turboFactor]']", data.heating.turboFactor);
|
setInputValue("[name='heating[turboFactor]']", data.heating.turboFactor);
|
||||||
setInputValue("[name='heating[maxModulation]']", data.heating.maxModulation);
|
setInputValue("[name='heating[maxModulation]']", data.heating.maxModulation);
|
||||||
setSelectValue("[name='heating[indoorTempAvgType]']", data.heating.indoorTempAvgType);
|
setSelectValue("[name='heating[indoorTempAvgType]']", data.heating.indoorTempAvgType);
|
||||||
@@ -1402,4 +1472,4 @@
|
|||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
Reference in new issue
Block a user