diff --git a/src/OpenThermTask.h b/src/OpenThermTask.h index fd5e1d8..1dbb93b 100644 --- a/src/OpenThermTask.h +++ b/src/OpenThermTask.h @@ -236,7 +236,7 @@ protected: vars.slave.heating.active = CustomOpenTherm::isCentralHeatingActive(response); vars.slave.dhw.active = settings.opentherm.options.dhwSupport ? CustomOpenTherm::isHotWaterActive(response) : false; vars.slave.flame = CustomOpenTherm::isFlameOn(response); - vars.slave.cooling = CustomOpenTherm::isCoolingActive(response); + vars.slave.cooling.active = CustomOpenTherm::isCoolingActive(response); vars.slave.ch2.active = CustomOpenTherm::isCh2Active(response); vars.slave.fault.active = CustomOpenTherm::isFault(response); @@ -250,7 +250,7 @@ protected: Log.snoticeln( FPSTR(L_OT), F("Received boiler status. Heating: %hhu; DHW: %hhu; flame: %hhu; cooling: %hhu; channel 2: %hhu; fault: %hhu; diag: %hhu"), vars.slave.heating.active, vars.slave.dhw.active, - vars.slave.flame, vars.slave.cooling, vars.slave.ch2.active, vars.slave.fault.active, vars.slave.diag.active + vars.slave.flame, vars.slave.cooling.active, vars.slave.ch2.active, vars.slave.fault.active, vars.slave.diag.active ); } @@ -318,6 +318,8 @@ protected: vars.slave.dhw.enabled = false; vars.slave.dhw.active = false; vars.slave.flame = false; + vars.slave.cooling.active = false; + vars.slave.cooling.setpoint = 0; vars.slave.fault.active = false; vars.slave.fault.code = 0; vars.slave.diag.active = false; @@ -688,6 +690,22 @@ protected: this->prevUpdateNonEssentialVars = millis(); } + // Set cooling setpoint = heating max modulation + if (settings.opentherm.options.coolingSupport) { + if (this->setCoolingSetpoint(settings.heating.maxModulation)) { + Log.snoticeln( + FPSTR(L_OT), F("Set cooling setpoint: %hhu%% (response: %hhu%%)"), + settings.heating.maxModulation, vars.slave.cooling.setpoint + ); + + } else { + Log.swarningln( + FPSTR(L_OT), F("Failed set cooling setpoint: %hhu%% (response: %hhu%%)"), + settings.heating.maxModulation, vars.slave.cooling.setpoint + ); + } + } + // Set max modulation level uint8_t targetMaxModulation = vars.slave.modulation.max; if (vars.slave.heating.active) { @@ -1568,6 +1586,26 @@ protected: return CustomOpenTherm::getUInt(response) == request; } + bool setCoolingSetpoint(const uint8_t value) { + const unsigned int request = CustomOpenTherm::toFloat(value); + const unsigned long response = this->instance->sendRequest(CustomOpenTherm::buildRequest( + OpenThermRequestType::WRITE_DATA, + OpenThermMessageID::CoolingControl, + request + )); + + if (!CustomOpenTherm::isValidResponse(response)) { + return false; + + } else if (!CustomOpenTherm::isValidResponseId(response, OpenThermMessageID::CoolingControl)) { + return false; + } + + vars.slave.cooling.setpoint = CustomOpenTherm::getFloat(response); + + return CustomOpenTherm::getUInt(response) == request; + } + bool setMaxModulationLevel(const uint8_t value) { const unsigned int request = CustomOpenTherm::toFloat(value); const unsigned long response = this->instance->sendRequest(CustomOpenTherm::buildRequest( diff --git a/src/Settings.h b/src/Settings.h index 1fded9f..80ab827 100644 --- a/src/Settings.h +++ b/src/Settings.h @@ -329,10 +329,14 @@ struct Variables { bool connected = false; bool flame = false; - bool cooling = false; float pressure = 0.0f; float heatExchangerTemp = 0.0f; + struct { + bool active = false; + uint8_t setpoint = 0; + } cooling; + struct { bool active = false; uint8_t code = 0; diff --git a/src/strings.h b/src/strings.h index 74e2eaf..268d73e 100644 --- a/src/strings.h +++ b/src/strings.h @@ -190,6 +190,7 @@ const char S_STA[] PROGMEM = "sta"; const char S_STATE[] PROGMEM = "state"; const char S_STATIC_CONFIG[] PROGMEM = "staticConfig"; const char S_STATUS_LED_GPIO[] PROGMEM = "statusLedGpio"; +const char S_SETPOINT[] PROGMEM = "setpoint"; const char S_SETPOINT_TEMP[] PROGMEM = "setpointTemp"; const char S_SUBNET[] PROGMEM = "subnet"; const char S_SUMMER_WINTER_MODE[] PROGMEM = "summerWinterMode"; diff --git a/src/utils.h b/src/utils.h index ac4ffa2..85db0cc 100644 --- a/src/utils.h +++ b/src/utils.h @@ -2060,7 +2060,10 @@ void varsToJson(const Variables& src, JsonVariant dst) { slave[FPSTR(S_PROTOCOL_VERSION)] = src.slave.appVersion; slave[FPSTR(S_CONNECTED)] = src.slave.connected; slave[FPSTR(S_FLAME)] = src.slave.flame; - slave[FPSTR(S_COOLING)] = src.slave.cooling; + + auto sCooling = slave[FPSTR(S_COOLING)].to(); + sCooling[FPSTR(S_ACTIVE)] = src.slave.cooling.active; + sCooling[FPSTR(S_SETPOINT)] = src.slave.cooling.setpoint; auto sModulation = slave[FPSTR(S_MODULATION)].to(); sModulation[FPSTR(S_MIN)] = src.slave.modulation.min; diff --git a/src_data/locales/cn.json b/src_data/locales/cn.json index 51ffb01..abf02f8 100644 --- a/src_data/locales/cn.json +++ b/src_data/locales/cn.json @@ -109,7 +109,8 @@ "sConnected": "OpenTherm 通讯状态", "sFlame": "火焰", - "sCooling": "制冷", + "sCoolingActive": "制冷", + "sCoolingSetpoint": "冷却设定点", "sFaultActive": "报警状态", "sFaultCode": "报警代码", "sDiagActive": "诊断状态", diff --git a/src_data/locales/en.json b/src_data/locales/en.json index c801561..c3f880d 100644 --- a/src_data/locales/en.json +++ b/src_data/locales/en.json @@ -109,7 +109,8 @@ "sConnected": "OpenTherm connection", "sFlame": "Flame", - "sCooling": "Cooling", + "sCoolingActive": "Cooling", + "sCoolingSetpoint": "Cooling setpoint", "sFaultActive": "Fault", "sFaultCode": "Fault code", "sDiagActive": "Diagnostic", diff --git a/src_data/locales/it.json b/src_data/locales/it.json index 9a13be8..454fb8e 100644 --- a/src_data/locales/it.json +++ b/src_data/locales/it.json @@ -109,7 +109,8 @@ "sConnected": "Connessione OpenTherm", "sFlame": "Fiamma", - "sCooling": "Raffrescamento", + "sCoolingActive": "Raffrescamento", + "sCoolingSetpoint": "Raffrescamento setpoint", "sFaultActive": "Anomalia", "sFaultCode": "Codice anomalia", "sDiagActive": "Diagnostica", diff --git a/src_data/locales/nl.json b/src_data/locales/nl.json index 9464def..70cacd3 100644 --- a/src_data/locales/nl.json +++ b/src_data/locales/nl.json @@ -99,7 +99,8 @@ "mCascadeControlOutput": "Cascaderegeling (uitgang)", "sConnected": "OpenTherm-verbinding", "sFlame": "Vlam", - "sCooling": "Koeling", + "sCoolingActive": "Koeling", + "sCoolingSetpoint": "Koelinstelpunt", "sFaultActive": "Storing", "sFaultCode": "Storingscode", "sDiagActive": "Diagnose", diff --git a/src_data/locales/ru.json b/src_data/locales/ru.json index 28055f7..b712c3c 100644 --- a/src_data/locales/ru.json +++ b/src_data/locales/ru.json @@ -109,7 +109,8 @@ "sConnected": "Подключение к OpenTherm", "sFlame": "Пламя", - "sCooling": "Охлаждение", + "sCoolingActive": "Охлаждение", + "sCoolingSetpoint": "Охлаждение, уставка", "sFaultActive": "Ошибка", "sFaultCode": "Код ошибки", "sDiagActive": "Диагностика", diff --git a/src_data/pages/dashboard.html b/src_data/pages/dashboard.html index 1d446f9..f01b72b 100644 --- a/src_data/pages/dashboard.html +++ b/src_data/pages/dashboard.html @@ -154,9 +154,14 @@ dashboard.states.sFlame + - dashboard.states.sCooling - + dashboard.states.sCoolingActive + + + + dashboard.states.sCoolingSetpoint + % @@ -558,7 +563,9 @@ result.slave.connected ? "green" : "red" ); setState('.sFlame', result.slave.flame); - setState('.sCooling', result.slave.cooling); + + setState('.sCoolingActive', result.slave.cooling.active); + setValue('.sCoolingSetpoint', result.slave.cooling.setpoint); setValue('.sModMin', result.slave.modulation.min); setValue('.sModMax', result.slave.modulation.max);