diff --git a/lib/VeDirectFrameHandler/VeDirectData.cpp b/lib/VeDirectFrameHandler/VeDirectData.cpp index d28f9f783..c0deb5faa 100644 --- a/lib/VeDirectFrameHandler/VeDirectData.cpp +++ b/lib/VeDirectFrameHandler/VeDirectData.cpp @@ -137,6 +137,44 @@ frozen::string const& veStruct::getPidAsString() const return getAsString(values, productID_PID); } +/* + * This function returns the firmware version as an integer, disregarding + * release candidate marks. + */ +uint32_t veStruct::getFwVersionAsInteger() const +{ + char const* strVersion = firmwareVer_FW; + + // VE.Direct protocol manual states that the first char can be a non-digit, + // in which case that char represents a release candidate version + if (strVersion[0] < '0' || strVersion[0] > '9') { ++strVersion; } + + return static_cast(strtoul(strVersion, nullptr, 10)); +} + +/* + * This function returns the firmware version as readable text. + */ +String veStruct::getFwVersionFormatted() const +{ + char const* strVersion = firmwareVer_FW; + + // VE.Direct protocol manual states that the first char can be a non-digit, + // in which case that char represents a release candidate version + if (strVersion[0] < '0' || strVersion[0] > '9') { ++strVersion; } + + String res(strVersion[0]); + res += "."; + res += strVersion + 1; + + if (strVersion > firmwareVer_FW) { + res += "-rc-"; + res += firmwareVer_FW[0]; + } + + return res; +} + /* * This function returns the state of operations (CS) as readable text. */ diff --git a/lib/VeDirectFrameHandler/VeDirectData.h b/lib/VeDirectFrameHandler/VeDirectData.h index 86be497ff..22c17a7a3 100644 --- a/lib/VeDirectFrameHandler/VeDirectData.h +++ b/lib/VeDirectFrameHandler/VeDirectData.h @@ -2,6 +2,7 @@ #include #include +#include #define VE_MAX_VALUE_LEN 33 // VE.Direct Protocol: max value size is 33 including /0 #define VE_MAX_HEX_LEN 100 // Maximum size of hex frame - max payload 34 byte (=68 char) + safe buffer @@ -9,12 +10,14 @@ typedef struct { uint16_t productID_PID = 0; // product id char serialNr_SER[VE_MAX_VALUE_LEN]; // serial number - char firmwareNr_FW[VE_MAX_VALUE_LEN]; // firmware release number + char firmwareVer_FW[VE_MAX_VALUE_LEN]; // firmware release number uint32_t batteryVoltage_V_mV = 0; // battery voltage in mV int32_t batteryCurrent_I_mA = 0; // battery current in mA (can be negative) float mpptEfficiency_Percent = 0; // efficiency in percent (calculated, moving average) frozen::string const& getPidAsString() const; // product ID as string + uint32_t getFwVersionAsInteger() const; + String getFwVersionFormatted() const; } veStruct; struct veMpptStruct : veStruct { diff --git a/lib/VeDirectFrameHandler/VeDirectFrameHandler.cpp b/lib/VeDirectFrameHandler/VeDirectFrameHandler.cpp index 44435dacf..d299268df 100644 --- a/lib/VeDirectFrameHandler/VeDirectFrameHandler.cpp +++ b/lib/VeDirectFrameHandler/VeDirectFrameHandler.cpp @@ -247,7 +247,7 @@ void VeDirectFrameHandler::processTextData(std::string const& name, std::stri } if (name == "FW") { - strcpy(_tmpFrame.firmwareNr_FW, value.c_str()); + strcpy(_tmpFrame.firmwareVer_FW, value.c_str()); return; } diff --git a/lib/VeDirectFrameHandler/VeDirectMpptController.cpp b/lib/VeDirectFrameHandler/VeDirectMpptController.cpp index f1bd00dec..368cac1d0 100644 --- a/lib/VeDirectFrameHandler/VeDirectMpptController.cpp +++ b/lib/VeDirectFrameHandler/VeDirectMpptController.cpp @@ -110,7 +110,7 @@ void VeDirectMpptController::frameValidEvent() { // charger periodically sends human readable (TEXT) data to the serial port. For firmware // versions v1.53 and above, the charger always periodically sends TEXT data to the serial port. // --> We just use hex commandes for firmware >= 1.53 to keep text messages alive - if (atoi(_tmpFrame.firmwareNr_FW) < 153) { return; } + if (_tmpFrame.getFwVersionAsInteger() < 153) { return; } using Command = VeDirectHexCommand; using Register = VeDirectHexRegister; diff --git a/src/MqttHandleVedirect.cpp b/src/MqttHandleVedirect.cpp index 0ed47e87a..c244afc68 100644 --- a/src/MqttHandleVedirect.cpp +++ b/src/MqttHandleVedirect.cpp @@ -110,7 +110,7 @@ void MqttHandleVedirectClass::publish_mppt_data(const VeDirectMpptController::da PUBLISH(productID_PID, "PID", currentData.getPidAsString().data()); PUBLISH(serialNr_SER, "SER", currentData.serialNr_SER); - PUBLISH(firmwareNr_FW, "FW", currentData.firmwareNr_FW); + PUBLISH(firmwareVer_FW, "FW", currentData.firmwareVer_FW); PUBLISH(loadOutputState_LOAD, "LOAD", (currentData.loadOutputState_LOAD ? "ON" : "OFF")); PUBLISH(currentState_CS, "CS", currentData.getCsAsString().data()); PUBLISH(errorCode_ERR, "ERR", currentData.getErrAsString().data()); diff --git a/src/WebApi_ws_vedirect_live.cpp b/src/WebApi_ws_vedirect_live.cpp index 9a92b363d..abf3376eb 100644 --- a/src/WebApi_ws_vedirect_live.cpp +++ b/src/WebApi_ws_vedirect_live.cpp @@ -139,7 +139,7 @@ void WebApiWsVedirectLiveClass::generateCommonJsonResponse(JsonVariant& root, bo void WebApiWsVedirectLiveClass::populateJson(const JsonObject &root, const VeDirectMpptController::data_t &mpptData) { root["product_id"] = mpptData.getPidAsString(); - root["firmware_version"] = String(mpptData.firmwareNr_FW); + root["firmware_version"] = mpptData.getFwVersionFormatted(); const JsonObject values = root["values"].to(); diff --git a/webapp/src/components/VedirectView.vue b/webapp/src/components/VedirectView.vue index a1ed9bc3c..052a2be36 100644 --- a/webapp/src/components/VedirectView.vue +++ b/webapp/src/components/VedirectView.vue @@ -21,13 +21,13 @@ {{ item.product_id }}
- {{ $t('vedirecthome.SerialNumber') }} {{ serial }} + {{ $t('vedirecthome.SerialNumber') }}: {{ serial }}
- {{ $t('vedirecthome.FirmwareNumber') }} {{ item.firmware_version }} + {{ $t('vedirecthome.FirmwareVersion') }}: {{ item.firmware_version }}
- {{ $t('vedirecthome.DataAge') }} {{ $t('vedirecthome.Seconds', {'val': Math.floor(item.data_age_ms / 1000)}) }} + {{ $t('vedirecthome.DataAge') }}: {{ $t('vedirecthome.Seconds', {'val': Math.floor(item.data_age_ms / 1000)}) }}
diff --git a/webapp/src/locales/de.json b/webapp/src/locales/de.json index 615bbc840..4ef2e5897 100644 --- a/webapp/src/locales/de.json +++ b/webapp/src/locales/de.json @@ -152,9 +152,9 @@ "LoadingInverter": "Warte auf Daten... (kann bis zu 10 Sekunden dauern)" }, "vedirecthome": { - "SerialNumber": "Seriennummer: ", - "FirmwareNumber": "Firmware Version: ", - "DataAge": "letzte Aktualisierung: ", + "SerialNumber": "Seriennummer", + "FirmwareVersion": "Firmware-Version", + "DataAge": "letzte Aktualisierung", "Seconds": "vor {val} Sekunden", "Property": "Eigenschaft", "Value": "Wert", diff --git a/webapp/src/locales/en.json b/webapp/src/locales/en.json index bde25c127..ef2448c9c 100644 --- a/webapp/src/locales/en.json +++ b/webapp/src/locales/en.json @@ -152,9 +152,9 @@ "LoadingInverter": "Waiting for data... (can take up to 10 seconds)" }, "vedirecthome": { - "SerialNumber": "Serial Number: ", - "FirmwareNumber": "Firmware Number: ", - "DataAge": "Data Age: ", + "SerialNumber": "Serial Number", + "FirmwareVersion": "Firmware Version", + "DataAge": "Data Age", "Seconds": "{val} seconds", "Property": "Property", "Value": "Value", diff --git a/webapp/src/locales/fr.json b/webapp/src/locales/fr.json index 5e4bbca1b..59f6e3aa7 100644 --- a/webapp/src/locales/fr.json +++ b/webapp/src/locales/fr.json @@ -152,10 +152,10 @@ "LoadingInverter": "Waiting for data... (can take up to 10 seconds)" }, "vedirecthome": { - "SerialNumber": "Serial Number: ", - "FirmwareNumber": "Firmware Number: ", - "DataAge": "Data Age: ", - "Seconds": "{val} seconds", + "SerialNumber": "Numéro de série", + "FirmwareVersion": "Version du Firmware", + "DataAge": "Âge des données", + "Seconds": "{val} secondes", "Property": "Property", "Value": "Value", "Unit": "Unit",