mirror of
https://github.com/Laxilef/OTGateway.git
synced 2025-12-10 18:24:27 +05:00
feat: added polling of min modulation and max boiler power; added sensor for current boiler power
This commit is contained in:
@@ -872,6 +872,52 @@ public:
|
|||||||
return this->publish(this->getTopic(FPSTR(HA_ENTITY_BINARY_SENSOR), F("diagnostic")).c_str(), doc);
|
return this->publish(this->getTopic(FPSTR(HA_ENTITY_BINARY_SENSOR), F("diagnostic")).c_str(), doc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool publishSensorMaxPower(bool enabledByDefault = true) {
|
||||||
|
JsonDocument doc;
|
||||||
|
doc[FPSTR(HA_AVAILABILITY)][0][FPSTR(HA_TOPIC)] = this->getDeviceTopic(F("status"));
|
||||||
|
doc[FPSTR(HA_AVAILABILITY)][1][FPSTR(HA_TOPIC)] = this->getDeviceTopic(F("state"));
|
||||||
|
doc[FPSTR(HA_AVAILABILITY)][1][FPSTR(HA_VALUE_TEMPLATE)] = F("{{ iif(value_json.states.otStatus, 'online', 'offline') }}");
|
||||||
|
doc[FPSTR(HA_AVAILABILITY_MODE)] = F("all");
|
||||||
|
doc[FPSTR(HA_ENABLED_BY_DEFAULT)] = enabledByDefault;
|
||||||
|
doc[FPSTR(HA_UNIQUE_ID)] = this->getObjectId(F("max_power"));
|
||||||
|
doc[FPSTR(HA_OBJECT_ID)] = this->getObjectId(F("max_power"));
|
||||||
|
doc[FPSTR(HA_ENTITY_CATEGORY)] = F("diagnostic");
|
||||||
|
doc[FPSTR(HA_DEVICE_CLASS)] = F("power");
|
||||||
|
doc[FPSTR(HA_STATE_CLASS)] = F("measurement");
|
||||||
|
doc[FPSTR(HA_UNIT_OF_MEASUREMENT)] = F("kW");
|
||||||
|
doc[FPSTR(HA_NAME)] = F("Max power");
|
||||||
|
doc[FPSTR(HA_ICON)] = F("mdi:chart-bar");
|
||||||
|
doc[FPSTR(HA_STATE_TOPIC)] = this->getDeviceTopic(F("state"));
|
||||||
|
doc[FPSTR(HA_VALUE_TEMPLATE)] = F("{{ value_json.sensors.maxPower|float(0)|round(2) }}");
|
||||||
|
doc[FPSTR(HA_EXPIRE_AFTER)] = 120;
|
||||||
|
doc.shrinkToFit();
|
||||||
|
|
||||||
|
return this->publish(this->getTopic(FPSTR(HA_ENTITY_SENSOR), F("max_power")).c_str(), doc);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool publishSensorCurrentPower(bool enabledByDefault = true) {
|
||||||
|
JsonDocument doc;
|
||||||
|
doc[FPSTR(HA_AVAILABILITY)][0][FPSTR(HA_TOPIC)] = this->getDeviceTopic(F("status"));
|
||||||
|
doc[FPSTR(HA_AVAILABILITY)][1][FPSTR(HA_TOPIC)] = this->getDeviceTopic(F("state"));
|
||||||
|
doc[FPSTR(HA_AVAILABILITY)][1][FPSTR(HA_VALUE_TEMPLATE)] = F("{{ iif(value_json.states.otStatus, 'online', 'offline') }}");
|
||||||
|
doc[FPSTR(HA_AVAILABILITY_MODE)] = F("all");
|
||||||
|
doc[FPSTR(HA_ENABLED_BY_DEFAULT)] = enabledByDefault;
|
||||||
|
doc[FPSTR(HA_UNIQUE_ID)] = this->getObjectId(F("current_power"));
|
||||||
|
doc[FPSTR(HA_OBJECT_ID)] = this->getObjectId(F("current_power"));
|
||||||
|
doc[FPSTR(HA_ENTITY_CATEGORY)] = F("diagnostic");
|
||||||
|
doc[FPSTR(HA_DEVICE_CLASS)] = F("power");
|
||||||
|
doc[FPSTR(HA_STATE_CLASS)] = F("measurement");
|
||||||
|
doc[FPSTR(HA_UNIT_OF_MEASUREMENT)] = F("kW");
|
||||||
|
doc[FPSTR(HA_NAME)] = F("Current power");
|
||||||
|
doc[FPSTR(HA_ICON)] = F("mdi:chart-bar");
|
||||||
|
doc[FPSTR(HA_STATE_TOPIC)] = this->getDeviceTopic(F("state"));
|
||||||
|
doc[FPSTR(HA_VALUE_TEMPLATE)] = F("{{ value_json.sensors.currentPower|float(0)|round(2) }}");
|
||||||
|
doc[FPSTR(HA_EXPIRE_AFTER)] = 120;
|
||||||
|
doc.shrinkToFit();
|
||||||
|
|
||||||
|
return this->publish(this->getTopic(FPSTR(HA_ENTITY_SENSOR), F("current_power")).c_str(), doc);
|
||||||
|
}
|
||||||
|
|
||||||
bool publishSensorFaultCode(bool enabledByDefault = true) {
|
bool publishSensorFaultCode(bool enabledByDefault = true) {
|
||||||
JsonDocument doc;
|
JsonDocument doc;
|
||||||
doc[FPSTR(HA_AVAILABILITY)][0][FPSTR(HA_TOPIC)] = this->getDeviceTopic(F("status"));
|
doc[FPSTR(HA_AVAILABILITY)][0][FPSTR(HA_TOPIC)] = this->getDeviceTopic(F("status"));
|
||||||
|
|||||||
@@ -357,6 +357,8 @@ protected:
|
|||||||
// sensors
|
// sensors
|
||||||
this->haHelper->publishSensorModulation(false);
|
this->haHelper->publishSensorModulation(false);
|
||||||
this->haHelper->publishSensorPressure(settings.system.unitSystem, false);
|
this->haHelper->publishSensorPressure(settings.system.unitSystem, false);
|
||||||
|
this->haHelper->publishSensorMaxPower(false);
|
||||||
|
this->haHelper->publishSensorCurrentPower();
|
||||||
this->haHelper->publishSensorFaultCode();
|
this->haHelper->publishSensorFaultCode();
|
||||||
this->haHelper->publishSensorDiagnosticCode();
|
this->haHelper->publishSensorDiagnosticCode();
|
||||||
this->haHelper->publishSensorRssi(false);
|
this->haHelper->publishSensorRssi(false);
|
||||||
|
|||||||
@@ -253,6 +253,19 @@ 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 (this->updateMinModulationLevel()) {
|
||||||
|
Log.straceln(FPSTR(L_OT), F("Min modulation: %u%%, boiler max power: %u kW"), vars.parameters.minModulation, vars.sensors.maxPower);
|
||||||
|
|
||||||
|
if (vars.parameters.minModulation > settings.heating.maxModulation) {
|
||||||
|
settings.heating.maxModulation = vars.parameters.minModulation;
|
||||||
|
fsSettings.update();
|
||||||
|
Log.snoticeln(FPSTR(L_OT_DHW), F("Updated min modulation: %hhu"), settings.heating.maxModulation);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
Log.swarningln(FPSTR(L_OT), F("Failed get min modulation & max power"));
|
||||||
|
}
|
||||||
|
|
||||||
if (!heatingEnabled && settings.opentherm.modulationSyncWithHeating) {
|
if (!heatingEnabled && settings.opentherm.modulationSyncWithHeating) {
|
||||||
if (this->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)"));
|
||||||
@@ -363,11 +376,22 @@ protected:
|
|||||||
|
|
||||||
|
|
||||||
// Get current modulation level (if necessary)
|
// Get current modulation level (if necessary)
|
||||||
if (vars.states.flame) {
|
if (vars.states.flame && this->updateModulationLevel()) {
|
||||||
this->updateModulationLevel();
|
vars.sensors.currentPower = vars.sensors.maxPower > 0
|
||||||
|
? vars.sensors.maxPower * (vars.sensors.modulation / 100)
|
||||||
|
: 0;
|
||||||
|
|
||||||
|
Log.sverboseln(
|
||||||
|
FPSTR(L_OT_DHW),
|
||||||
|
F("Current modulation level: %.2f%%, power: %.2f of %hhu kW"),
|
||||||
|
vars.sensors.modulation,
|
||||||
|
vars.sensors.currentPower,
|
||||||
|
vars.sensors.maxPower
|
||||||
|
);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
vars.sensors.modulation = 0;
|
vars.sensors.modulation = 0;
|
||||||
|
vars.sensors.currentPower = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update DHW sensors (if necessary)
|
// Update DHW sensors (if necessary)
|
||||||
@@ -1045,6 +1069,26 @@ protected:
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool updateMinModulationLevel() {
|
||||||
|
unsigned long response = this->instance->sendRequest(CustomOpenTherm::buildRequest(
|
||||||
|
OpenThermRequestType::READ_DATA,
|
||||||
|
OpenThermMessageID::MaxCapacityMinModLevel,
|
||||||
|
0
|
||||||
|
));
|
||||||
|
|
||||||
|
if (!CustomOpenTherm::isValidResponse(response)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
byte minModulation = response & 0xFF;
|
||||||
|
byte maxPower = (response & 0xFFFF) >> 8;
|
||||||
|
|
||||||
|
vars.parameters.minModulation = minModulation;
|
||||||
|
vars.sensors.maxPower = maxPower;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool updatePressure() {
|
bool updatePressure() {
|
||||||
unsigned long response = this->instance->sendRequest(CustomOpenTherm::buildRequest(
|
unsigned long response = this->instance->sendRequest(CustomOpenTherm::buildRequest(
|
||||||
OpenThermRequestType::READ_DATA,
|
OpenThermRequestType::READ_DATA,
|
||||||
|
|||||||
@@ -174,6 +174,8 @@ struct Variables {
|
|||||||
float modulation = 0.0f;
|
float modulation = 0.0f;
|
||||||
float pressure = 0.0f;
|
float pressure = 0.0f;
|
||||||
float dhwFlowRate = 0.0f;
|
float dhwFlowRate = 0.0f;
|
||||||
|
byte maxPower = 0;
|
||||||
|
float currentPower = 0.0f;
|
||||||
byte faultCode = 0;
|
byte faultCode = 0;
|
||||||
unsigned short diagnosticCode = 0;
|
unsigned short diagnosticCode = 0;
|
||||||
int8_t rssi = 0;
|
int8_t rssi = 0;
|
||||||
@@ -210,6 +212,7 @@ struct Variables {
|
|||||||
unsigned long extPumpLastEnableTime = 0;
|
unsigned long extPumpLastEnableTime = 0;
|
||||||
byte dhwMinTemp = DEFAULT_DHW_MIN_TEMP;
|
byte dhwMinTemp = DEFAULT_DHW_MIN_TEMP;
|
||||||
byte dhwMaxTemp = DEFAULT_DHW_MAX_TEMP;
|
byte dhwMaxTemp = DEFAULT_DHW_MAX_TEMP;
|
||||||
|
byte minModulation = 0;
|
||||||
byte maxModulation = 0;
|
byte maxModulation = 0;
|
||||||
uint8_t slaveMemberId = 0;
|
uint8_t slaveMemberId = 0;
|
||||||
uint8_t slaveFlags = 0;
|
uint8_t slaveFlags = 0;
|
||||||
|
|||||||
@@ -1546,6 +1546,8 @@ void varsToJson(const Variables& src, JsonVariant dst) {
|
|||||||
dst["sensors"]["modulation"] = roundd(src.sensors.modulation, 2);
|
dst["sensors"]["modulation"] = roundd(src.sensors.modulation, 2);
|
||||||
dst["sensors"]["pressure"] = roundd(src.sensors.pressure, 2);
|
dst["sensors"]["pressure"] = roundd(src.sensors.pressure, 2);
|
||||||
dst["sensors"]["dhwFlowRate"] = roundd(src.sensors.dhwFlowRate, 2);
|
dst["sensors"]["dhwFlowRate"] = roundd(src.sensors.dhwFlowRate, 2);
|
||||||
|
dst["sensors"]["maxPower"] = src.sensors.maxPower;
|
||||||
|
dst["sensors"]["currentPower"] = roundd(src.sensors.currentPower, 2);
|
||||||
dst["sensors"]["faultCode"] = src.sensors.faultCode;
|
dst["sensors"]["faultCode"] = src.sensors.faultCode;
|
||||||
dst["sensors"]["diagnosticCode"] = src.sensors.diagnosticCode;
|
dst["sensors"]["diagnosticCode"] = src.sensors.diagnosticCode;
|
||||||
dst["sensors"]["rssi"] = src.sensors.rssi;
|
dst["sensors"]["rssi"] = src.sensors.rssi;
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
"releases": "Releases"
|
"releases": "Releases"
|
||||||
},
|
},
|
||||||
"dbm": "dBm",
|
"dbm": "dBm",
|
||||||
|
"kw": "kW",
|
||||||
|
|
||||||
"button": {
|
"button": {
|
||||||
"upgrade": "Upgrade",
|
"upgrade": "Upgrade",
|
||||||
@@ -99,6 +100,8 @@
|
|||||||
"modulation": "Modulation",
|
"modulation": "Modulation",
|
||||||
"pressure": "Pressure",
|
"pressure": "Pressure",
|
||||||
"dhwFlowRate": "DHW flow rate",
|
"dhwFlowRate": "DHW flow rate",
|
||||||
|
"maxPower": "Max power",
|
||||||
|
"currentPower": "Current power",
|
||||||
"faultCode": "Fault code",
|
"faultCode": "Fault code",
|
||||||
"diagCode": "Diagnostic code",
|
"diagCode": "Diagnostic code",
|
||||||
"indoorTemp": "Indoor temp",
|
"indoorTemp": "Indoor temp",
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
"releases": "Релизы"
|
"releases": "Релизы"
|
||||||
},
|
},
|
||||||
"dbm": "дБм",
|
"dbm": "дБм",
|
||||||
|
"kw": "кВт",
|
||||||
|
|
||||||
"button": {
|
"button": {
|
||||||
"upgrade": "Обновить",
|
"upgrade": "Обновить",
|
||||||
@@ -99,6 +100,8 @@
|
|||||||
"modulation": "Уровень модуляции",
|
"modulation": "Уровень модуляции",
|
||||||
"pressure": "Давление",
|
"pressure": "Давление",
|
||||||
"dhwFlowRate": "Расход ГВС",
|
"dhwFlowRate": "Расход ГВС",
|
||||||
|
"maxPower": "Макс. мощность",
|
||||||
|
"currentPower": "Текущая мощность",
|
||||||
"faultCode": "Код ошибки",
|
"faultCode": "Код ошибки",
|
||||||
"diagCode": "Диагностический код",
|
"diagCode": "Диагностический код",
|
||||||
"indoorTemp": "Внутренняя темп.",
|
"indoorTemp": "Внутренняя темп.",
|
||||||
|
|||||||
@@ -158,6 +158,14 @@
|
|||||||
<th scope="row" data-i18n>dashboard.state.dhwFlowRate</th>
|
<th scope="row" data-i18n>dashboard.state.dhwFlowRate</th>
|
||||||
<td><b id="ot-dhw-flow-rate"></b> <span class="volume-unit"></span>/min</td>
|
<td><b id="ot-dhw-flow-rate"></b> <span class="volume-unit"></span>/min</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row" data-i18n>dashboard.state.maxPower</th>
|
||||||
|
<td><b id="ot-max-power"></b> <span data-i18n>kw</span></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row" data-i18n>dashboard.state.currentPower</th>
|
||||||
|
<td><b id="ot-current-power"></b> <span data-i18n>kw</span></td>
|
||||||
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="row" data-i18n>dashboard.state.faultCode</th>
|
<th scope="row" data-i18n>dashboard.state.faultCode</th>
|
||||||
<td><b id="ot-fault-code"></b></td>
|
<td><b id="ot-fault-code"></b></td>
|
||||||
@@ -434,6 +442,8 @@
|
|||||||
setValue('#ot-modulation', result.sensors.modulation);
|
setValue('#ot-modulation', result.sensors.modulation);
|
||||||
setValue('#ot-pressure', result.sensors.pressure);
|
setValue('#ot-pressure', result.sensors.pressure);
|
||||||
setValue('#ot-dhw-flow-rate', result.sensors.dhwFlowRate);
|
setValue('#ot-dhw-flow-rate', result.sensors.dhwFlowRate);
|
||||||
|
setValue('#ot-max-power', result.sensors.maxPower);
|
||||||
|
setValue('#ot-current-power', result.sensors.currentPower);
|
||||||
setValue(
|
setValue(
|
||||||
'#ot-fault-code',
|
'#ot-fault-code',
|
||||||
result.sensors.faultCode
|
result.sensors.faultCode
|
||||||
|
|||||||
Reference in New Issue
Block a user