diff --git a/src/HaHelper.h b/src/HaHelper.h index 3258f0e..8583d40 100644 --- a/src/HaHelper.h +++ b/src/HaHelper.h @@ -885,13 +885,33 @@ public: doc[FPSTR(HA_NAME)] = F("Fault code"); doc[FPSTR(HA_ICON)] = F("mdi:chat-alert-outline"); doc[FPSTR(HA_STATE_TOPIC)] = this->getDeviceTopic(F("state")); - doc[FPSTR(HA_VALUE_TEMPLATE)] = F("{{ \"E%02d\"|format(value_json.sensors.faultCode) }}"); + doc[FPSTR(HA_VALUE_TEMPLATE)] = F("{{ \"%02d (0x%02X)\"|format(value_json.sensors.faultCode, value_json.sensors.faultCode) }}"); doc[FPSTR(HA_EXPIRE_AFTER)] = 120; doc.shrinkToFit(); return this->publish(this->getTopic(FPSTR(HA_ENTITY_SENSOR), F("fault_code")).c_str(), doc); } + bool publishSensorDiagnosticCode(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 and value_json.states.fault or value_json.states.diagnostic, 'online', 'offline') }}"); + doc[FPSTR(HA_AVAILABILITY_MODE)] = F("all"); + doc[FPSTR(HA_ENABLED_BY_DEFAULT)] = enabledByDefault; + doc[FPSTR(HA_UNIQUE_ID)] = this->getObjectId(F("diagnostic_code")); + doc[FPSTR(HA_OBJECT_ID)] = this->getObjectId(F("diagnostic_code")); + doc[FPSTR(HA_ENTITY_CATEGORY)] = F("diagnostic"); + doc[FPSTR(HA_NAME)] = F("Diagnostic code"); + doc[FPSTR(HA_ICON)] = F("mdi:chat-alert-outline"); + doc[FPSTR(HA_STATE_TOPIC)] = this->getDeviceTopic(F("state")); + doc[FPSTR(HA_VALUE_TEMPLATE)] = F("{{ \"%02d (0x%02X)\"|format(value_json.sensors.diagnosticCode, value_json.sensors.diagnosticCode) }}"); + doc[FPSTR(HA_EXPIRE_AFTER)] = 120; + doc.shrinkToFit(); + + return this->publish(this->getTopic(FPSTR(HA_ENTITY_SENSOR), F("diagnostic_code")).c_str(), doc); + } + bool publishSensorRssi(bool enabledByDefault = true) { JsonDocument doc; doc[FPSTR(HA_AVAILABILITY)][FPSTR(HA_TOPIC)] = this->getDeviceTopic(F("status")); diff --git a/src/MqttTask.h b/src/MqttTask.h index 479d800..49e3761 100644 --- a/src/MqttTask.h +++ b/src/MqttTask.h @@ -358,6 +358,7 @@ protected: this->haHelper->publishSensorModulation(false); this->haHelper->publishSensorPressure(settings.system.unitSystem, false); this->haHelper->publishSensorFaultCode(); + this->haHelper->publishSensorDiagnosticCode(); this->haHelper->publishSensorRssi(false); this->haHelper->publishSensorUptime(false); diff --git a/src/OpenThermTask.h b/src/OpenThermTask.h index 3c58da9..3e77713 100644 --- a/src/OpenThermTask.h +++ b/src/OpenThermTask.h @@ -347,6 +347,14 @@ protected: vars.sensors.faultCode = 0; } + // Get diagnostic code (if necessary) + if (vars.states.fault || vars.states.diagnostic) { + updateDiagCode(); + + } else if (vars.sensors.diagnosticCode != 0) { + vars.sensors.diagnosticCode = 0; + } + updatePressure(); this->prevUpdateNonEssentialVars = millis(); @@ -933,6 +941,7 @@ protected: )); if (!CustomOpenTherm::isValidResponse(response)) { + vars.sensors.faultCode = 0; return false; } @@ -940,6 +949,22 @@ protected: return true; } + bool updateDiagCode() { + unsigned long response = this->instance->sendRequest(CustomOpenTherm::buildRequest( + OpenThermRequestType::READ_DATA, + OpenThermMessageID::OEMDiagnosticCode, + 0 + )); + + if (!CustomOpenTherm::isValidResponse(response)) { + vars.sensors.diagnosticCode = 0; + return false; + } + + vars.sensors.diagnosticCode = CustomOpenTherm::getUInt(response); + return true; + } + bool updateModulationLevel() { unsigned long response = this->instance->sendRequest(CustomOpenTherm::buildRequest( OpenThermRequestType::READ_DATA, diff --git a/src/Settings.h b/src/Settings.h index dba3e78..333ff02 100644 --- a/src/Settings.h +++ b/src/Settings.h @@ -168,6 +168,7 @@ struct Variables { float pressure = 0.0f; float dhwFlowRate = 0.0f; byte faultCode = 0; + unsigned short diagnosticCode = 0; int8_t rssi = 0; struct { diff --git a/src/utils.h b/src/utils.h index b966f94..4a77629 100644 --- a/src/utils.h +++ b/src/utils.h @@ -1507,6 +1507,7 @@ void varsToJson(const Variables& src, JsonVariant dst) { dst["sensors"]["pressure"] = roundd(src.sensors.pressure, 2); dst["sensors"]["dhwFlowRate"] = roundd(src.sensors.dhwFlowRate, 2); dst["sensors"]["faultCode"] = src.sensors.faultCode; + dst["sensors"]["diagnosticCode"] = src.sensors.diagnosticCode; dst["sensors"]["rssi"] = src.sensors.rssi; dst["sensors"]["uptime"] = millis() / 1000ul; dst["sensors"]["outdoor"]["connected"] = src.sensors.outdoor.connected; diff --git a/src_data/locales/en.json b/src_data/locales/en.json index d4595fc..d3df819 100644 --- a/src_data/locales/en.json +++ b/src_data/locales/en.json @@ -100,6 +100,7 @@ "pressure": "Pressure", "dhwFlowRate": "DHW flow rate", "faultCode": "Fault code", + "diagCode": "Diagnostic code", "indoorTemp": "Indoor temp", "outdoorTemp": "Outdoor temp", "heatingTemp": "Heating temp", diff --git a/src_data/locales/ru.json b/src_data/locales/ru.json index 0637077..2e22763 100644 --- a/src_data/locales/ru.json +++ b/src_data/locales/ru.json @@ -100,6 +100,7 @@ "pressure": "Давление", "dhwFlowRate": "Расход ГВС", "faultCode": "Код ошибки", + "diagCode": "Диагностический код", "indoorTemp": "Внутренняя темп.", "outdoorTemp": "Наружная темп.", "heatingTemp": "Темп. отопления", diff --git a/src_data/pages/dashboard.html b/src_data/pages/dashboard.html index 4f05b15..d2f48c8 100644 --- a/src_data/pages/dashboard.html +++ b/src_data/pages/dashboard.html @@ -162,6 +162,10 @@ dashboard.state.faultCode + + dashboard.state.diagCode + + dashboard.state.indoorTemp @@ -430,7 +434,18 @@ setValue('#ot-modulation', result.sensors.modulation); setValue('#ot-pressure', result.sensors.pressure); setValue('#ot-dhw-flow-rate', result.sensors.dhwFlowRate); - setValue('#ot-fault-code', result.sensors.faultCode ? ("E" + result.sensors.faultCode) : "-"); + setValue( + '#ot-fault-code', + result.sensors.faultCode + ? (result.sensors.faultCode + " (0x" + dec2hex(result.sensors.faultCode) + ")") + : "-" + ); + setValue( + '#ot-diag-code', + result.sensors.diagnosticCode + ? (result.sensors.diagnosticCode + " (0x" + dec2hex(result.sensors.diagnosticCode) + ")") + : "-" + ); setValue('#indoor-temp', result.temperatures.indoor); setValue('#outdoor-temp', result.temperatures.outdoor); diff --git a/src_data/scripts/utils.js b/src_data/scripts/utils.js index c7944ec..d89358a 100644 --- a/src_data/scripts/utils.js +++ b/src_data/scripts/utils.js @@ -665,4 +665,13 @@ function form2json(data, noCastItems = []) { let object = Array.from(data).reduce(method, {}); return JSON.stringify(object); +} + +function dec2hex(i) { + let hex = parseInt(i).toString(16); + if (hex.length % 2 != 0) { + hex = "0" + hex; + } + + return hex.toUpperCase(); } \ No newline at end of file