Move serial number formatting to inverter class

This commit is contained in:
Thomas Basler 2022-10-29 00:25:01 +02:00
parent f21dd351ef
commit f741fea333
9 changed files with 43 additions and 81 deletions

View File

@ -5,6 +5,13 @@
InverterAbstract::InverterAbstract(uint64_t serial) InverterAbstract::InverterAbstract(uint64_t serial)
{ {
_serial.u64 = serial; _serial.u64 = serial;
char serial_buff[sizeof(uint64_t) * 8 + 1];
snprintf(serial_buff, sizeof(serial_buff), "%0x%08x",
((uint32_t)((serial >> 32) & 0xFFFFFFFF)),
((uint32_t)(serial & 0xFFFFFFFF)));
_serialString = serial_buff;
_alarmLogParser.reset(new AlarmLogParser()); _alarmLogParser.reset(new AlarmLogParser());
_devInfoParser.reset(new DevInfoParser()); _devInfoParser.reset(new DevInfoParser());
_powerCommandParser.reset(new PowerCommandParser()); _powerCommandParser.reset(new PowerCommandParser());
@ -26,6 +33,11 @@ uint64_t InverterAbstract::serial()
return _serial.u64; return _serial.u64;
} }
const String& InverterAbstract::serialString()
{
return _serialString;
}
void InverterAbstract::setName(const char* name) void InverterAbstract::setName(const char* name)
{ {
uint8_t len = strlen(name); uint8_t len = strlen(name);

View File

@ -33,6 +33,7 @@ public:
explicit InverterAbstract(uint64_t serial); explicit InverterAbstract(uint64_t serial);
void init(); void init();
uint64_t serial(); uint64_t serial();
const String& serialString();
void setName(const char* name); void setName(const char* name);
const char* name(); const char* name();
virtual String typeName() = 0; virtual String typeName() = 0;
@ -64,6 +65,7 @@ public:
private: private:
serial_u _serial; serial_u _serial;
String _serialString;
char _name[MAX_NAME_LENGTH] = ""; char _name[MAX_NAME_LENGTH] = "";
fragment_t _rxFragmentBuffer[MAX_RF_FRAGMENT_COUNT]; fragment_t _rxFragmentBuffer[MAX_RF_FRAGMENT_COUNT];
uint8_t _rxFragmentMaxPacketId = 0; uint8_t _rxFragmentMaxPacketId = 0;

View File

@ -85,10 +85,7 @@ void MqttHassPublishingClass::publishField(std::shared_ptr<InverterAbstract> inv
return; return;
} }
char serial[sizeof(uint64_t) * 8 + 1]; String serial = inv->serialString();
snprintf(serial, sizeof(serial), "%0x%08x",
((uint32_t)((inv->serial() >> 32) & 0xFFFFFFFF)),
((uint32_t)(inv->serial() & 0xFFFFFFFF)));
String fieldName; String fieldName;
if (channel == CH0 && fieldType.fieldId == FLD_PDC) { if (channel == CH0 && fieldType.fieldId == FLD_PDC) {
@ -97,7 +94,7 @@ void MqttHassPublishingClass::publishField(std::shared_ptr<InverterAbstract> inv
fieldName = inv->Statistics()->getChannelFieldName(channel, fieldType.fieldId); fieldName = inv->Statistics()->getChannelFieldName(channel, fieldType.fieldId);
} }
String configTopic = "sensor/dtu_" + String(serial) String configTopic = "sensor/dtu_" + serial
+ "/" + "ch" + String(channel) + "_" + fieldName + "/" + "ch" + String(channel) + "_" + fieldName
+ "/config"; + "/config";
@ -117,7 +114,7 @@ void MqttHassPublishingClass::publishField(std::shared_ptr<InverterAbstract> inv
root[F("name")] = name; root[F("name")] = name;
root[F("stat_t")] = stateTopic; root[F("stat_t")] = stateTopic;
root[F("unit_of_meas")] = inv->Statistics()->getChannelFieldUnit(channel, fieldType.fieldId); root[F("unit_of_meas")] = inv->Statistics()->getChannelFieldUnit(channel, fieldType.fieldId);
root[F("uniq_id")] = String(serial) + "_ch" + String(channel) + "_" + fieldName; root[F("uniq_id")] = serial + "_ch" + String(channel) + "_" + fieldName;
JsonObject deviceObj = root.createNestedObject("dev"); JsonObject deviceObj = root.createNestedObject("dev");
createDeviceInfo(deviceObj, inv); createDeviceInfo(deviceObj, inv);
@ -142,24 +139,21 @@ void MqttHassPublishingClass::publishField(std::shared_ptr<InverterAbstract> inv
void MqttHassPublishingClass::publishInverterButton(std::shared_ptr<InverterAbstract> inv, const char* caption, const char* icon, const char* category, const char* deviceClass, const char* subTopic, const char* payload) void MqttHassPublishingClass::publishInverterButton(std::shared_ptr<InverterAbstract> inv, const char* caption, const char* icon, const char* category, const char* deviceClass, const char* subTopic, const char* payload)
{ {
char serial[sizeof(uint64_t) * 8 + 1]; String serial = inv->serialString();
snprintf(serial, sizeof(serial), "%0x%08x",
((uint32_t)((inv->serial() >> 32) & 0xFFFFFFFF)),
((uint32_t)(inv->serial() & 0xFFFFFFFF)));
String buttonId = caption; String buttonId = caption;
buttonId.replace(" ", "_"); buttonId.replace(" ", "_");
buttonId.toLowerCase(); buttonId.toLowerCase();
String configTopic = "button/dtu_" + String(serial) String configTopic = "button/dtu_" + serial
+ "/" + buttonId + "/" + buttonId
+ "/config"; + "/config";
String cmdTopic = MqttSettings.getPrefix() + String(serial) + "/" + subTopic; String cmdTopic = MqttSettings.getPrefix() + serial + "/" + subTopic;
DynamicJsonDocument root(1024); DynamicJsonDocument root(1024);
root[F("name")] = caption; root[F("name")] = caption;
root[F("uniq_id")] = String(serial) + "_" + buttonId; root[F("uniq_id")] = serial + "_" + buttonId;
if (strcmp(icon, "")) { if (strcmp(icon, "")) {
root[F("ic")] = icon; root[F("ic")] = icon;
} }
@ -183,25 +177,22 @@ void MqttHassPublishingClass::publishInverterNumber(
const char* commandTopic, const char* stateTopic, const char* unitOfMeasure, const char* commandTopic, const char* stateTopic, const char* unitOfMeasure,
int16_t min, int16_t max) int16_t min, int16_t max)
{ {
char serial[sizeof(uint64_t) * 8 + 1]; String serial = inv->serialString();
snprintf(serial, sizeof(serial), "%0x%08x",
((uint32_t)((inv->serial() >> 32) & 0xFFFFFFFF)),
((uint32_t)(inv->serial() & 0xFFFFFFFF)));
String buttonId = caption; String buttonId = caption;
buttonId.replace(" ", "_"); buttonId.replace(" ", "_");
buttonId.toLowerCase(); buttonId.toLowerCase();
String configTopic = "number/dtu_" + String(serial) String configTopic = "number/dtu_" + serial
+ "/" + buttonId + "/" + buttonId
+ "/config"; + "/config";
String cmdTopic = MqttSettings.getPrefix() + String(serial) + "/" + commandTopic; String cmdTopic = MqttSettings.getPrefix() + serial + "/" + commandTopic;
String statTopic = MqttSettings.getPrefix() + String(serial) + "/" + stateTopic; String statTopic = MqttSettings.getPrefix() + serial + "/" + stateTopic;
DynamicJsonDocument root(1024); DynamicJsonDocument root(1024);
root[F("name")] = caption; root[F("name")] = caption;
root[F("uniq_id")] = String(serial) + "_" + buttonId; root[F("uniq_id")] = serial + "_" + buttonId;
if (strcmp(icon, "")) { if (strcmp(icon, "")) {
root[F("ic")] = icon; root[F("ic")] = icon;
} }
@ -222,24 +213,21 @@ void MqttHassPublishingClass::publishInverterNumber(
void MqttHassPublishingClass::publishInverterBinarySensor(std::shared_ptr<InverterAbstract> inv, const char* caption, const char* subTopic, const char* payload_on, const char* payload_off) void MqttHassPublishingClass::publishInverterBinarySensor(std::shared_ptr<InverterAbstract> inv, const char* caption, const char* subTopic, const char* payload_on, const char* payload_off)
{ {
char serial[sizeof(uint64_t) * 8 + 1]; String serial = inv->serialString();
snprintf(serial, sizeof(serial), "%0x%08x",
((uint32_t)((inv->serial() >> 32) & 0xFFFFFFFF)),
((uint32_t)(inv->serial() & 0xFFFFFFFF)));
String sensorId = caption; String sensorId = caption;
sensorId.replace(" ", "_"); sensorId.replace(" ", "_");
sensorId.toLowerCase(); sensorId.toLowerCase();
String configTopic = "binary_sensor/dtu_" + String(serial) String configTopic = "binary_sensor/dtu_" + serial
+ "/" + sensorId + "/" + sensorId
+ "/config"; + "/config";
String statTopic = MqttSettings.getPrefix() + String(serial) + "/" + subTopic; String statTopic = MqttSettings.getPrefix() + serial + "/" + subTopic;
DynamicJsonDocument root(1024); DynamicJsonDocument root(1024);
root[F("name")] = caption; root[F("name")] = caption;
root[F("uniq_id")] = String(serial) + "_" + sensorId; root[F("uniq_id")] = serial + "_" + sensorId;
root[F("stat_t")] = statTopic; root[F("stat_t")] = statTopic;
root[F("pl_on")] = payload_on; root[F("pl_on")] = payload_on;
root[F("pl_off")] = payload_off; root[F("pl_off")] = payload_off;
@ -254,13 +242,8 @@ void MqttHassPublishingClass::publishInverterBinarySensor(std::shared_ptr<Invert
void MqttHassPublishingClass::createDeviceInfo(JsonObject& object, std::shared_ptr<InverterAbstract> inv) void MqttHassPublishingClass::createDeviceInfo(JsonObject& object, std::shared_ptr<InverterAbstract> inv)
{ {
char serial[sizeof(uint64_t) * 8 + 1];
snprintf(serial, sizeof(serial), "%0x%08x",
((uint32_t)((inv->serial() >> 32) & 0xFFFFFFFF)),
((uint32_t)(inv->serial() & 0xFFFFFFFF)));
object[F("name")] = inv->name(); object[F("name")] = inv->name();
object[F("ids")] = String(serial); object[F("ids")] = inv->serialString();
object[F("cu")] = String(F("http://")) + WiFi.localIP().toString(); object[F("cu")] = String(F("http://")) + WiFi.localIP().toString();
object[F("mf")] = F("OpenDTU"); object[F("mf")] = F("OpenDTU");
object[F("mdl")] = inv->typeName(); object[F("mdl")] = inv->typeName();

View File

@ -33,11 +33,7 @@ void MqttPublishingClass::loop()
for (uint8_t i = 0; i < Hoymiles.getNumInverters(); i++) { for (uint8_t i = 0; i < Hoymiles.getNumInverters(); i++) {
auto inv = Hoymiles.getInverterByPos(i); auto inv = Hoymiles.getInverterByPos(i);
char buffer[sizeof(uint64_t) * 8 + 1]; String subtopic = inv->serialString();
snprintf(buffer, sizeof(buffer), "%0x%08x",
((uint32_t)((inv->serial() >> 32) & 0xFFFFFFFF)),
((uint32_t)(inv->serial() & 0xFFFFFFFF)));
String subtopic = String(buffer);
// Name // Name
MqttSettings.publish(subtopic + "/name", inv->name()); MqttSettings.publish(subtopic + "/name", inv->name());
@ -110,12 +106,6 @@ String MqttPublishingClass::getTopic(std::shared_ptr<InverterAbstract> inv, uint
return String(""); return String("");
} }
char buffer[sizeof(uint64_t) * 8 + 1];
snprintf(buffer, sizeof(buffer), "%0x%08x",
((uint32_t)((inv->serial() >> 32) & 0xFFFFFFFF)),
((uint32_t)(inv->serial() & 0xFFFFFFFF)));
String invSerial = String(buffer);
String chanName; String chanName;
if (channel == 0 && fieldId == FLD_PDC) { if (channel == 0 && fieldId == FLD_PDC) {
chanName = "powerdc"; chanName = "powerdc";
@ -124,5 +114,5 @@ String MqttPublishingClass::getTopic(std::shared_ptr<InverterAbstract> inv, uint
chanName.toLowerCase(); chanName.toLowerCase();
} }
return invSerial + "/" + String(channel) + "/" + chanName; return inv->serialString() + "/" + String(channel) + "/" + chanName;
} }

View File

@ -29,13 +29,7 @@ void WebApiDevInfoClass::onDevInfoStatus(AsyncWebServerRequest* request)
for (uint8_t i = 0; i < Hoymiles.getNumInverters(); i++) { for (uint8_t i = 0; i < Hoymiles.getNumInverters(); i++) {
auto inv = Hoymiles.getInverterByPos(i); auto inv = Hoymiles.getInverterByPos(i);
// Inverter Serial is read as HEX JsonObject devInfoObj = root[inv->serialString()].createNestedObject();
char buffer[sizeof(uint64_t) * 8 + 1];
snprintf(buffer, sizeof(buffer), "%0x%08x",
((uint32_t)((inv->serial() >> 32) & 0xFFFFFFFF)),
((uint32_t)(inv->serial() & 0xFFFFFFFF)));
JsonObject devInfoObj = root[buffer].createNestedObject();
devInfoObj[F("valid_data")] = inv->DevInfo()->getLastUpdate() > 0; devInfoObj[F("valid_data")] = inv->DevInfo()->getLastUpdate() > 0;
devInfoObj[F("fw_bootloader_version")] = inv->DevInfo()->getFwBootloaderVersion(); devInfoObj[F("fw_bootloader_version")] = inv->DevInfo()->getFwBootloaderVersion();
devInfoObj[F("fw_build_version")] = inv->DevInfo()->getFwBuildVersion(); devInfoObj[F("fw_build_version")] = inv->DevInfo()->getFwBuildVersion();

View File

@ -34,16 +34,12 @@ void WebApiEventlogClass::onEventlogStatus(AsyncWebServerRequest* request)
auto inv = Hoymiles.getInverterBySerial(serial); auto inv = Hoymiles.getInverterBySerial(serial);
if (inv != nullptr) { if (inv != nullptr) {
// Inverter Serial is read as HEX String serial = inv->serialString();
char buffer[sizeof(uint64_t) * 8 + 1];
snprintf(buffer, sizeof(buffer), "%0x%08x",
((uint32_t)((inv->serial() >> 32) & 0xFFFFFFFF)),
((uint32_t)(inv->serial() & 0xFFFFFFFF)));
uint8_t logEntryCount = inv->EventLog()->getEntryCount(); uint8_t logEntryCount = inv->EventLog()->getEntryCount();
root[buffer]["count"] = logEntryCount; root[serial]["count"] = logEntryCount;
JsonArray eventsArray = root[buffer].createNestedArray(F("events")); JsonArray eventsArray = root[serial].createNestedArray(F("events"));
for (uint8_t logEntry = 0; logEntry < logEntryCount; logEntry++) { for (uint8_t logEntry = 0; logEntry < logEntryCount; logEntry++) {
JsonObject eventsObject = eventsArray.createNestedObject(); JsonObject eventsObject = eventsArray.createNestedObject();

View File

@ -29,14 +29,10 @@ void WebApiLimitClass::onLimitStatus(AsyncWebServerRequest* request)
for (uint8_t i = 0; i < Hoymiles.getNumInverters(); i++) { for (uint8_t i = 0; i < Hoymiles.getNumInverters(); i++) {
auto inv = Hoymiles.getInverterByPos(i); auto inv = Hoymiles.getInverterByPos(i);
// Inverter Serial is read as HEX String serial = inv->serialString();
char buffer[sizeof(uint64_t) * 8 + 1];
snprintf(buffer, sizeof(buffer), "%0x%08x",
((uint32_t)((inv->serial() >> 32) & 0xFFFFFFFF)),
((uint32_t)(inv->serial() & 0xFFFFFFFF)));
root[buffer]["limit_relative"] = inv->SystemConfigPara()->getLimitPercent(); root[serial]["limit_relative"] = inv->SystemConfigPara()->getLimitPercent();
root[buffer]["max_power"] = inv->DevInfo()->getMaxPower(); root[serial]["max_power"] = inv->DevInfo()->getMaxPower();
LastCommandSuccess status = inv->SystemConfigPara()->getLastLimitCommandSuccess(); LastCommandSuccess status = inv->SystemConfigPara()->getLastLimitCommandSuccess();
String limitStatus = "Unknown"; String limitStatus = "Unknown";
@ -49,7 +45,7 @@ void WebApiLimitClass::onLimitStatus(AsyncWebServerRequest* request)
else if (status == LastCommandSuccess::CMD_PENDING) { else if (status == LastCommandSuccess::CMD_PENDING) {
limitStatus = "Pending"; limitStatus = "Pending";
} }
root[buffer]["limit_set_status"] = limitStatus; root[serial]["limit_set_status"] = limitStatus;
} }
response->setLength(); response->setLength();

View File

@ -29,12 +29,6 @@ void WebApiPowerClass::onPowerStatus(AsyncWebServerRequest* request)
for (uint8_t i = 0; i < Hoymiles.getNumInverters(); i++) { for (uint8_t i = 0; i < Hoymiles.getNumInverters(); i++) {
auto inv = Hoymiles.getInverterByPos(i); auto inv = Hoymiles.getInverterByPos(i);
// Inverter Serial is read as HEX
char buffer[sizeof(uint64_t) * 8 + 1];
snprintf(buffer, sizeof(buffer), "%0x%08x",
((uint32_t)((inv->serial() >> 32) & 0xFFFFFFFF)),
((uint32_t)(inv->serial() & 0xFFFFFFFF)));
LastCommandSuccess status = inv->PowerCommand()->getLastPowerCommandSuccess(); LastCommandSuccess status = inv->PowerCommand()->getLastPowerCommandSuccess();
String limitStatus = "Unknown"; String limitStatus = "Unknown";
if (status == LastCommandSuccess::CMD_OK) { if (status == LastCommandSuccess::CMD_OK) {
@ -44,7 +38,7 @@ void WebApiPowerClass::onPowerStatus(AsyncWebServerRequest* request)
} else if (status == LastCommandSuccess::CMD_PENDING) { } else if (status == LastCommandSuccess::CMD_PENDING) {
limitStatus = "Pending"; limitStatus = "Pending";
} }
root[buffer]["power_set_status"] = limitStatus; root[inv->serialString()]["power_set_status"] = limitStatus;
} }
response->setLength(); response->setLength();

View File

@ -77,12 +77,7 @@ void WebApiWsLiveClass::generateJsonResponse(JsonVariant& root)
for (uint8_t i = 0; i < Hoymiles.getNumInverters(); i++) { for (uint8_t i = 0; i < Hoymiles.getNumInverters(); i++) {
auto inv = Hoymiles.getInverterByPos(i); auto inv = Hoymiles.getInverterByPos(i);
char buffer[sizeof(uint64_t) * 8 + 1]; root[i][F("serial")] = inv->serialString();
snprintf(buffer, sizeof(buffer), "%0x%08x",
((uint32_t)((inv->serial() >> 32) & 0xFFFFFFFF)),
((uint32_t)(inv->serial() & 0xFFFFFFFF)));
root[i][F("serial")] = String(buffer);
root[i][F("name")] = inv->name(); root[i][F("name")] = inv->name();
root[i][F("data_age")] = (millis() - inv->Statistics()->getLastUpdate()) / 1000; root[i][F("data_age")] = (millis() - inv->Statistics()->getLastUpdate()) / 1000;
root[i][F("reachable")] = inv->isReachable(); root[i][F("reachable")] = inv->isReachable();