Skip to content

Commit

Permalink
Feature: process VE.Direct "FWE" text data
Browse files Browse the repository at this point in the history
  • Loading branch information
schlimmchen committed Nov 20, 2024
1 parent 4beea35 commit bfa55a8
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 1 deletion.
39 changes: 39 additions & 0 deletions lib/VeDirectFrameHandler/VeDirectData.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,17 @@ frozen::string const& veStruct::getPidAsString() const
*/
uint32_t veStruct::getFwVersionAsInteger() const
{
if (strlen(firmwareVer_FW) == 0) {
if (strlen(firmwareVer_FWE) == 0) { return 0; }

// the firmware version from the FWE field may be preceeded by a zero
// for padding as per VE.Direct protocol, which is fine for strtoul()
// when we use a fixed base. however, the postfix (2 chars) might be
// numeric as well to indicate a beta release, which we must not parse.
std::string strVer(firmwareVer_FWE, strlen(firmwareVer_FWE) - 2);
return static_cast<uint32_t>(strtoul(strVer.c_str(), nullptr, 10));
}

char const* strVersion = firmwareVer_FW;

// VE.Direct protocol manual states that the first char can be a non-digit,
Expand All @@ -157,6 +168,34 @@ uint32_t veStruct::getFwVersionAsInteger() const
*/
String veStruct::getFwVersionFormatted() const
{
if (strlen(firmwareVer_FW) == 0 && strlen(firmwareVer_FWE) == 0) {
return "n/a";
}

if (strlen(firmwareVer_FWE) > 0) {
char const* strVersion = firmwareVer_FWE;

// the firmware version from the FWE field may be preceeded by a zero
// for padding as per VE.Direct protocol.
while (strVersion[0] == '0') { ++strVersion; }

String res(strVersion[0]);
strVersion++;
res += ".";
res += strVersion[0];
strVersion++;
res += strVersion[0];
strVersion++;

String suffix(strVersion);
suffix.toUpperCase();
if (suffix == "FF") { return res; }

res += "-beta-";
res += suffix;
return res;
}

char const* strVersion = firmwareVer_FW;
char rc = 0;

Expand Down
2 changes: 2 additions & 0 deletions lib/VeDirectFrameHandler/VeDirectData.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ typedef struct {
uint16_t productID_PID = 0; // product id
char serialNr_SER[VE_MAX_VALUE_LEN]; // serial number
char firmwareVer_FW[VE_MAX_VALUE_LEN]; // firmware release number
// some devices use "FWE" instead of "FW" for the firmware version.
char firmwareVer_FWE[VE_MAX_VALUE_LEN]; // firmware release number (alternative field)
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)
Expand Down
8 changes: 8 additions & 0 deletions lib/VeDirectFrameHandler/VeDirectFrameHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -249,10 +249,18 @@ void VeDirectFrameHandler<T>::processTextData(std::string const& name, std::stri
}

if (name == "FW") {
_tmpFrame.firmwareVer_FWE[0] = '\0';
strncpy(_tmpFrame.firmwareVer_FW, value.c_str(), sizeof(_tmpFrame.firmwareVer_FW));
return;
}

// some devices use "FWE" instead of "FW" for the firmware version.
if (name == "FWE") {
_tmpFrame.firmwareVer_FW[0] = '\0';
strncpy(_tmpFrame.firmwareVer_FWE, value.c_str(), sizeof(_tmpFrame.firmwareVer_FWE));
return;
}

if (name == "V") {
_tmpFrame.batteryVoltage_V_mV = atol(value.c_str());
return;
Expand Down
3 changes: 3 additions & 0 deletions src/MqttHandleVedirect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,10 @@ void MqttHandleVedirectClass::publish_mppt_data(const VeDirectMpptController::da

PUBLISH(productID_PID, "PID", currentData.getPidAsString().data());
PUBLISH(serialNr_SER, "SER", currentData.serialNr_SER);
PUBLISH(firmwareVer_FW, "FWI", currentData.getFwVersionAsInteger());
PUBLISH(firmwareVer_FW, "FWF", currentData.getFwVersionFormatted());
PUBLISH(firmwareVer_FW, "FW", currentData.firmwareVer_FW);
PUBLISH(firmwareVer_FWE, "FWE", currentData.firmwareVer_FWE);
PUBLISH(currentState_CS, "CS", currentData.getCsAsString().data());
PUBLISH(errorCode_ERR, "ERR", currentData.getErrAsString().data());
PUBLISH(offReason_OR, "OR", currentData.getOrAsString().data());
Expand Down
5 changes: 4 additions & 1 deletion src/MqttHandleVedirectHass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,10 @@ void MqttHandleVedirectHassClass::publishConfig()
if (!optMpptData.has_value()) { continue; }

publishSensor("MPPT serial number", "mdi:counter", "SER", nullptr, nullptr, nullptr, *optMpptData);
publishSensor("MPPT firmware number", "mdi:counter", "FW", nullptr, nullptr, nullptr, *optMpptData);
publishSensor("MPPT firmware version integer", "mdi:counter", "FWI", nullptr, nullptr, nullptr, *optMpptData);
publishSensor("MPPT firmware version formatted", "mdi:counter", "FWF", nullptr, nullptr, nullptr, *optMpptData);
publishSensor("MPPT firmware version FW", "mdi:counter", "FW", nullptr, nullptr, nullptr, *optMpptData);
publishSensor("MPPT firmware version FWE", "mdi:counter", "FWE", nullptr, nullptr, nullptr, *optMpptData);
publishSensor("MPPT state of operation", "mdi:wrench", "CS", nullptr, nullptr, nullptr, *optMpptData);
publishSensor("MPPT error code", "mdi:bell", "ERR", nullptr, nullptr, nullptr, *optMpptData);
publishSensor("MPPT off reason", "mdi:wrench", "OR", nullptr, nullptr, nullptr, *optMpptData);
Expand Down

0 comments on commit bfa55a8

Please sign in to comment.