Fix: properly format Victron MPPT firmware version
This commit is contained in:
parent
90eb25f503
commit
88314f93c2
@ -137,6 +137,44 @@ frozen::string const& veStruct::getPidAsString() const
|
|||||||
return getAsString(values, productID_PID);
|
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<uint32_t>(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.
|
* This function returns the state of operations (CS) as readable text.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include <frozen/string.h>
|
#include <frozen/string.h>
|
||||||
#include <frozen/map.h>
|
#include <frozen/map.h>
|
||||||
|
#include <Arduino.h>
|
||||||
|
|
||||||
#define VE_MAX_VALUE_LEN 33 // VE.Direct Protocol: max value size is 33 including /0
|
#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
|
#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 {
|
typedef struct {
|
||||||
uint16_t productID_PID = 0; // product id
|
uint16_t productID_PID = 0; // product id
|
||||||
char serialNr_SER[VE_MAX_VALUE_LEN]; // serial number
|
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
|
uint32_t batteryVoltage_V_mV = 0; // battery voltage in mV
|
||||||
int32_t batteryCurrent_I_mA = 0; // battery current in mA (can be negative)
|
int32_t batteryCurrent_I_mA = 0; // battery current in mA (can be negative)
|
||||||
float mpptEfficiency_Percent = 0; // efficiency in percent (calculated, moving average)
|
float mpptEfficiency_Percent = 0; // efficiency in percent (calculated, moving average)
|
||||||
|
|
||||||
frozen::string const& getPidAsString() const; // product ID as string
|
frozen::string const& getPidAsString() const; // product ID as string
|
||||||
|
uint32_t getFwVersionAsInteger() const;
|
||||||
|
String getFwVersionFormatted() const;
|
||||||
} veStruct;
|
} veStruct;
|
||||||
|
|
||||||
struct veMpptStruct : veStruct {
|
struct veMpptStruct : veStruct {
|
||||||
|
|||||||
@ -247,7 +247,7 @@ void VeDirectFrameHandler<T>::processTextData(std::string const& name, std::stri
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (name == "FW") {
|
if (name == "FW") {
|
||||||
strcpy(_tmpFrame.firmwareNr_FW, value.c_str());
|
strcpy(_tmpFrame.firmwareVer_FW, value.c_str());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -110,7 +110,7 @@ void VeDirectMpptController::frameValidEvent() {
|
|||||||
// charger periodically sends human readable (TEXT) data to the serial port. For firmware
|
// 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.
|
// 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
|
// --> 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 Command = VeDirectHexCommand;
|
||||||
using Register = VeDirectHexRegister;
|
using Register = VeDirectHexRegister;
|
||||||
|
|||||||
@ -110,7 +110,7 @@ void MqttHandleVedirectClass::publish_mppt_data(const VeDirectMpptController::da
|
|||||||
|
|
||||||
PUBLISH(productID_PID, "PID", currentData.getPidAsString().data());
|
PUBLISH(productID_PID, "PID", currentData.getPidAsString().data());
|
||||||
PUBLISH(serialNr_SER, "SER", currentData.serialNr_SER);
|
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(loadOutputState_LOAD, "LOAD", (currentData.loadOutputState_LOAD ? "ON" : "OFF"));
|
||||||
PUBLISH(currentState_CS, "CS", currentData.getCsAsString().data());
|
PUBLISH(currentState_CS, "CS", currentData.getCsAsString().data());
|
||||||
PUBLISH(errorCode_ERR, "ERR", currentData.getErrAsString().data());
|
PUBLISH(errorCode_ERR, "ERR", currentData.getErrAsString().data());
|
||||||
|
|||||||
@ -139,7 +139,7 @@ void WebApiWsVedirectLiveClass::generateCommonJsonResponse(JsonVariant& root, bo
|
|||||||
|
|
||||||
void WebApiWsVedirectLiveClass::populateJson(const JsonObject &root, const VeDirectMpptController::data_t &mpptData) {
|
void WebApiWsVedirectLiveClass::populateJson(const JsonObject &root, const VeDirectMpptController::data_t &mpptData) {
|
||||||
root["product_id"] = mpptData.getPidAsString();
|
root["product_id"] = mpptData.getPidAsString();
|
||||||
root["firmware_version"] = String(mpptData.firmwareNr_FW);
|
root["firmware_version"] = mpptData.getFwVersionFormatted();
|
||||||
|
|
||||||
const JsonObject values = root["values"].to<JsonObject>();
|
const JsonObject values = root["values"].to<JsonObject>();
|
||||||
|
|
||||||
|
|||||||
@ -21,13 +21,13 @@
|
|||||||
{{ item.product_id }}
|
{{ item.product_id }}
|
||||||
</div>
|
</div>
|
||||||
<div style="padding-right: 2em;">
|
<div style="padding-right: 2em;">
|
||||||
{{ $t('vedirecthome.SerialNumber') }} {{ serial }}
|
{{ $t('vedirecthome.SerialNumber') }}: {{ serial }}
|
||||||
</div>
|
</div>
|
||||||
<div style="padding-right: 2em;">
|
<div style="padding-right: 2em;">
|
||||||
{{ $t('vedirecthome.FirmwareNumber') }} {{ item.firmware_version }}
|
{{ $t('vedirecthome.FirmwareVersion') }}: {{ item.firmware_version }}
|
||||||
</div>
|
</div>
|
||||||
<div style="padding-right: 2em;">
|
<div style="padding-right: 2em;">
|
||||||
{{ $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)}) }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -152,9 +152,9 @@
|
|||||||
"LoadingInverter": "Warte auf Daten... (kann bis zu 10 Sekunden dauern)"
|
"LoadingInverter": "Warte auf Daten... (kann bis zu 10 Sekunden dauern)"
|
||||||
},
|
},
|
||||||
"vedirecthome": {
|
"vedirecthome": {
|
||||||
"SerialNumber": "Seriennummer: ",
|
"SerialNumber": "Seriennummer",
|
||||||
"FirmwareNumber": "Firmware Version: ",
|
"FirmwareVersion": "Firmware-Version",
|
||||||
"DataAge": "letzte Aktualisierung: ",
|
"DataAge": "letzte Aktualisierung",
|
||||||
"Seconds": "vor {val} Sekunden",
|
"Seconds": "vor {val} Sekunden",
|
||||||
"Property": "Eigenschaft",
|
"Property": "Eigenschaft",
|
||||||
"Value": "Wert",
|
"Value": "Wert",
|
||||||
|
|||||||
@ -152,9 +152,9 @@
|
|||||||
"LoadingInverter": "Waiting for data... (can take up to 10 seconds)"
|
"LoadingInverter": "Waiting for data... (can take up to 10 seconds)"
|
||||||
},
|
},
|
||||||
"vedirecthome": {
|
"vedirecthome": {
|
||||||
"SerialNumber": "Serial Number: ",
|
"SerialNumber": "Serial Number",
|
||||||
"FirmwareNumber": "Firmware Number: ",
|
"FirmwareVersion": "Firmware Version",
|
||||||
"DataAge": "Data Age: ",
|
"DataAge": "Data Age",
|
||||||
"Seconds": "{val} seconds",
|
"Seconds": "{val} seconds",
|
||||||
"Property": "Property",
|
"Property": "Property",
|
||||||
"Value": "Value",
|
"Value": "Value",
|
||||||
|
|||||||
@ -152,10 +152,10 @@
|
|||||||
"LoadingInverter": "Waiting for data... (can take up to 10 seconds)"
|
"LoadingInverter": "Waiting for data... (can take up to 10 seconds)"
|
||||||
},
|
},
|
||||||
"vedirecthome": {
|
"vedirecthome": {
|
||||||
"SerialNumber": "Serial Number: ",
|
"SerialNumber": "Numéro de série",
|
||||||
"FirmwareNumber": "Firmware Number: ",
|
"FirmwareVersion": "Version du Firmware",
|
||||||
"DataAge": "Data Age: ",
|
"DataAge": "Âge des données",
|
||||||
"Seconds": "{val} seconds",
|
"Seconds": "{val} secondes",
|
||||||
"Property": "Property",
|
"Property": "Property",
|
||||||
"Value": "Value",
|
"Value": "Value",
|
||||||
"Unit": "Unit",
|
"Unit": "Unit",
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user