Heap memory improvements

This commit is contained in:
Gunnar Skjold
2026-03-26 15:14:59 +01:00
parent 9609e9fb85
commit 048bd474e4
16 changed files with 135 additions and 113 deletions

View File

@@ -10,7 +10,7 @@
#include "Arduino.h"
#if defined(ESP8266)
#define BUF_SIZE_COMMON 1024
#define BUF_SIZE_COMMON 2048
#else
#define BUF_SIZE_COMMON 4096
#endif

View File

@@ -95,7 +95,9 @@ protected:
uint64_t lastList2 = 0;
uint8_t listType = 0, meterType = AmsTypeUnknown;
time_t packageTimestamp = 0;
String listId = "", meterId = "", meterModel = "";
char listId[32] = {};
char meterId[32] = {};
char meterModel[65] = {};
time_t meterTimestamp = 0;
uint32_t activeImportPower = 0, reactiveImportPower = 0, activeExportPower = 0, reactiveExportPower = 0;
float l1voltage = 0, l2voltage = 0, l3voltage = 0, l1current = 0, l2current = 0, l3current = 0;

View File

@@ -88,10 +88,10 @@ void AmsData::apply(AmsData& other) {
}
this->counterEstimated = false;
case 2:
this->listId = other.getListId();
this->meterId = other.getMeterId();
strncpy(this->listId, other.listId, sizeof(this->listId) - 1);
strncpy(this->meterId, other.meterId, sizeof(this->meterId) - 1);
this->meterType = other.getMeterType();
this->meterModel = other.getMeterModel();
strncpy(this->meterModel, other.meterModel, sizeof(this->meterModel) - 1);
this->reactiveImportPower = other.getReactiveImportPower();
this->reactiveExportPower = other.getReactiveExportPower();
this->l1current = other.getL1Current();
@@ -119,7 +119,7 @@ void AmsData::apply(OBIS_code_t obis, double value) {
if(obis.gr == 1) {
if(obis.sensor == 96) {
if(obis.tariff == 0) {
meterId = String((long) value, 10);
snprintf(meterId, sizeof(meterId), "%ld", (long) value);
return;
} else if(obis.tariff == 1) {
return;
@@ -278,11 +278,11 @@ uint8_t AmsData::getListType() {
}
String AmsData::getListId() {
return this->listId;
return String(this->listId);
}
String AmsData::getMeterId() {
return this->meterId;
return String(this->meterId);
}
uint8_t AmsData::getMeterType() {
@@ -290,7 +290,7 @@ uint8_t AmsData::getMeterType() {
}
String AmsData::getMeterModel() {
return this->meterModel;
return String(this->meterModel);
}
time_t AmsData::getMeterTimestamp() {

View File

@@ -98,8 +98,8 @@ protected:
uint64_t lastStateUpdate = 0;
uint64_t lastSuccessfulLoop = 0;
String pubTopic;
String subTopic;
char pubTopic[64];
char subTopic[64];
AmsFirmwareUpdater* updater = NULL;
bool rebootSuggested = false;
@@ -115,9 +115,14 @@ private:
this->updater = updater;
mqtt.dropOverflow(true);
pubTopic = String(mqttConfig.publishTopic);
subTopic = String(mqttConfig.subscribeTopic);
if(subTopic.isEmpty()) subTopic = pubTopic+"/command";
strncpy(pubTopic, mqttConfig.publishTopic, sizeof(pubTopic) - 1);
pubTopic[sizeof(pubTopic) - 1] = '\0';
if(strlen(mqttConfig.subscribeTopic) > 0) {
strncpy(subTopic, mqttConfig.subscribeTopic, sizeof(subTopic) - 1);
subTopic[sizeof(subTopic) - 1] = '\0';
} else {
snprintf(subTopic, sizeof(subTopic), "%s/command", mqttConfig.publishTopic);
}
}
};

View File

@@ -118,8 +118,9 @@ bool AmsMqttHandler::connect() {
mqtt.setTimeout(mqttConfig.timeout);
mqtt.setKeepAlive(mqttConfig.keepalive);
mqtt.begin(mqttConfig.host, mqttConfig.port, *actualClient);
String statusTopic = String(mqttConfig.publishTopic) + "/status";
mqtt.setWill(statusTopic.c_str(), "offline", true, 0);
char statusTopic[72];
snprintf(statusTopic, sizeof(statusTopic), "%s/status", mqttConfig.publishTopic);
mqtt.setWill(statusTopic, "offline", true, 0);
#if defined(ESP8266)
if(mqttSecureClient) {
@@ -160,17 +161,17 @@ bool AmsMqttHandler::connect() {
bool AmsMqttHandler::defaultSubscribe() {
bool ret = true;
if(!subTopic.isEmpty()) {
if(subTopic[0] != '\0') {
if(mqtt.subscribe(subTopic)) {
#if defined(AMS_REMOTE_DEBUG)
if (debugger->isActive(RemoteDebug::ERROR))
#endif
debugger->printf_P(PSTR(" Subscribed to [%s]\n"), subTopic.c_str());
debugger->printf_P(PSTR(" Subscribed to [%s]\n"), subTopic);
} else {
#if defined(AMS_REMOTE_DEBUG)
if (debugger->isActive(RemoteDebug::ERROR))
#endif
debugger->printf_P(PSTR(" Unable to subscribe to [%s]\n"), subTopic.c_str());
debugger->printf_P(PSTR(" Unable to subscribe to [%s]\n"), subTopic);
ret = false;
}
}

View File

@@ -88,7 +88,7 @@ bool HomeAssistantMqttHandler::postConnect() {
}
bool HomeAssistantMqttHandler::publish(AmsData* update, AmsData* previousState, EnergyAccounting* ea, PriceService* ps) {
if(pubTopic.isEmpty() || !connected())
if(pubTopic[0] == 'pubTopic.isEmpty()' || !connected())
return false;
if(time(nullptr) < FirmwareVersion::BuildEpoch)
@@ -136,7 +136,8 @@ bool HomeAssistantMqttHandler::publishList1(AmsData* data, EnergyAccounting* ea)
toJsonIsoTimestamp(data->getPackageTimestamp(), pt, sizeof(pt));
snprintf_P(json, BUF_SIZE_COMMON, HA1_JSON, data->getActiveImportPower(), pt);
return mqtt.publish(pubTopic + "/power", json);
{ char _t[72]; snprintf(_t, sizeof(_t), "%s/power", pubTopic);
return mqtt.publish(_t, json); }
}
bool HomeAssistantMqttHandler::publishList2(AmsData* data, EnergyAccounting* ea) {
@@ -162,7 +163,8 @@ bool HomeAssistantMqttHandler::publishList2(AmsData* data, EnergyAccounting* ea)
data->getL3Voltage(),
pt
);
return mqtt.publish(pubTopic + "/power", json);
{ char _t[72]; snprintf(_t, sizeof(_t), "%s/power", pubTopic);
return mqtt.publish(_t, json); }
}
bool HomeAssistantMqttHandler::publishList3(AmsData* data, EnergyAccounting* ea) {
@@ -184,7 +186,8 @@ bool HomeAssistantMqttHandler::publishList3(AmsData* data, EnergyAccounting* ea)
mt,
pt
);
return mqtt.publish(pubTopic + "/energy", json);
{ char _t[72]; snprintf(_t, sizeof(_t), "%s/energy", pubTopic);
return mqtt.publish(_t, json); }
}
bool HomeAssistantMqttHandler::publishList4(AmsData* data, EnergyAccounting* ea) {
@@ -226,7 +229,8 @@ bool HomeAssistantMqttHandler::publishList4(AmsData* data, EnergyAccounting* ea)
data->getL3ActiveExportCounter(),
pt
);
return mqtt.publish(pubTopic + "/power", json);
{ char _t[72]; snprintf(_t, sizeof(_t), "%s/power", pubTopic);
return mqtt.publish(_t, json); }
}
String HomeAssistantMqttHandler::getMeterModel(AmsData* data) {
@@ -288,7 +292,8 @@ bool HomeAssistantMqttHandler::publishRealtime(AmsData* data, EnergyAccounting*
json[pos++] = '}';
json[pos] = '\0';
return mqtt.publish(pubTopic + "/realtime", json);
{ char _t[72]; snprintf(_t, sizeof(_t), "%s/realtime", pubTopic);
return mqtt.publish(_t, json); }
}
bool HomeAssistantMqttHandler::publishTemperatures(AmsConfiguration* config, HwTools* hw) {
@@ -317,13 +322,14 @@ bool HomeAssistantMqttHandler::publishTemperatures(AmsConfiguration* config, HwT
pos += snprintf_P(json+pos, BUF_SIZE_COMMON-pos, PSTR(",\"t\":%s"), pt);
pos += snprintf_P(json+pos, BUF_SIZE_COMMON-pos, PSTR("}"));
bool ret = mqtt.publish(pubTopic + "/temperatures", json);
char _t[72]; snprintf(_t, sizeof(_t), "%s/temperatures", pubTopic);
bool ret = mqtt.publish(_t, json);
loop();
return ret;
}
bool HomeAssistantMqttHandler::publishPrices(PriceService* ps) {
if(pubTopic.isEmpty() || !connected())
if(pubTopic[0] == 'pubTopic.isEmpty()' || !connected())
return false;
if(!ps->hasPrice())
return false;
@@ -457,13 +463,14 @@ bool HomeAssistantMqttHandler::publishPrices(PriceService* ps) {
json[pos++] = '}';
json[pos] = '\0';
bool ret = mqtt.publish(pubTopic + "/prices", json, true, 0);
char _t[72]; snprintf(_t, sizeof(_t), "%s/prices", pubTopic);
bool ret = mqtt.publish(_t, json, true, 0);
loop();
return ret;
}
bool HomeAssistantMqttHandler::publishSystem(HwTools* hw, PriceService* ps, EnergyAccounting* ea) {
if(pubTopic.isEmpty() || !connected())
if(pubTopic[0] == 'pubTopic.isEmpty()' || !connected())
return false;
publishSystemSensors();
@@ -483,7 +490,8 @@ bool HomeAssistantMqttHandler::publishSystem(HwTools* hw, PriceService* ps, Ener
FirmwareVersion::VersionString,
pt
);
bool ret = mqtt.publish(pubTopic + "/state", json);
char _t[72]; snprintf(_t, sizeof(_t), "%s/state", pubTopic);
bool ret = mqtt.publish(_t, json);
loop();
return ret;
}
@@ -827,9 +835,9 @@ bool HomeAssistantMqttHandler::publishFirmware() {
if(!fInit) {
snprintf_P(json, BUF_SIZE_COMMON, PSTR("{\"name\":\"%sFirmware\",\"stat_t\":\"%s/firmware\",\"uniq_id\":\"%s_fwupgrade\",\"dev_cla\":\"firmware\",\"cmd_t\":\"%s\",\"pl_inst\":\"fwupgrade\"}"),
sensorNamePrefix.c_str(),
pubTopic.c_str(),
pubTopic,
deviceUid.c_str(),
subTopic.c_str()
subTopic
);
fInit = mqtt.publish(updateTopic + "/" + deviceUid + "/config", json, true, 0);
loop();
@@ -841,7 +849,8 @@ bool HomeAssistantMqttHandler::publishFirmware() {
strlen(updater->getNextVersion()) == 0 ? FirmwareVersion::VersionString : updater->getNextVersion(),
updater->getProgress() < 0 ? "null" : String(updater->getProgress(), 0)
);
bool ret = mqtt.publish(pubTopic + "/firmware", json);
char _t[72]; snprintf(_t, sizeof(_t), "%s/firmware", pubTopic);
bool ret = mqtt.publish(_t, json);
loop();
return ret;
}
@@ -858,7 +867,7 @@ void HomeAssistantMqttHandler::onMessage(String &topic, String &payload) {
priceImportInit = 0;
priceExportInit = 0;
}
} else if(topic.equals(subTopic)) {
} else if(topic == subTopic) {
if(payload.equals("fwupgrade")) {
if(strcmp(updater->getNextVersion(), FirmwareVersion::VersionString) != 0) {
updater->setTargetVersion(updater->getNextVersion());

View File

@@ -520,7 +520,7 @@ void JsonMqttHandler::onMessage(String &topic, String &payload) {
#endif
debugger->printf_P(PSTR("Received command [%s] to [%s]\n"), payload.c_str(), topic.c_str());
if(topic.equals(subTopic)) {
if(topic == subTopic) {
#if defined(AMS_REMOTE_DEBUG)
if (debugger->isActive(RemoteDebug::DEBUG))
#endif

View File

@@ -16,50 +16,53 @@ IEC6205621::IEC6205621(const char* p, Timezone* tz, MeterConfig* meterConfig) {
String payload(p+1);
lastUpdateMillis = millis64();
listId = payload.substring(payload.startsWith("/") ? 1 : 0, payload.indexOf("\n"));
String listIdStr = payload.substring(payload.startsWith("/") ? 1 : 0, payload.indexOf("\n"));
if(listId.startsWith(F("ADN"))) {
if(listIdStr.startsWith(F("ADN"))) {
meterType = AmsTypeAidon;
listId = listId.substring(0,4);
} else if(listId.startsWith(F("KFM"))) {
listIdStr = listIdStr.substring(0,4);
} else if(listIdStr.startsWith(F("KFM"))) {
meterType = AmsTypeKaifa;
listId = listId.substring(0,4);
} else if(listId.startsWith(F("KMP"))) {
listIdStr = listIdStr.substring(0,4);
} else if(listIdStr.startsWith(F("KMP"))) {
meterType = AmsTypeKamstrup;
listId = listId.substring(0,4);
} else if(listId.startsWith(F("KAM"))) {
listIdStr = listIdStr.substring(0,4);
} else if(listIdStr.startsWith(F("KAM"))) {
meterType = AmsTypeKamstrup;
listId = listId.substring(0,4);
} else if(listId.startsWith(F("ISk"))) {
listIdStr = listIdStr.substring(0,4);
} else if(listIdStr.startsWith(F("ISk"))) {
meterType = AmsTypeIskra;
listId = listId.substring(0,5);
} else if(listId.startsWith(F("XMX"))) {
listIdStr = listIdStr.substring(0,5);
} else if(listIdStr.startsWith(F("XMX"))) {
meterType = AmsTypeLandisGyr;
listId = listId.substring(0,6);
} else if(listId.startsWith(F("Ene")) || listId.startsWith(F("EST"))) {
listIdStr = listIdStr.substring(0,6);
} else if(listIdStr.startsWith(F("Ene")) || listIdStr.startsWith(F("EST"))) {
meterType = AmsTypeSagemcom;
listId = listId.substring(0,4);
} else if(listId.startsWith(F("LGF"))) {
listIdStr = listIdStr.substring(0,4);
} else if(listIdStr.startsWith(F("LGF"))) {
meterType = AmsTypeLandisGyr;
listId = listId.substring(0,4);
listIdStr = listIdStr.substring(0,4);
} else {
meterType = AmsTypeUnknown;
listId = listId.substring(0,4);
}
meterId = extract(payload, F("96.1.0"));
if(meterId.isEmpty()) {
meterId = extract(payload, F("0.0.5"));
listIdStr = listIdStr.substring(0,4);
}
strncpy(listId, listIdStr.c_str(), sizeof(listId) - 1);
meterModel = extract(payload, F("96.1.1"));
if(meterModel.isEmpty()) {
meterModel = extract(payload, F("96.1.7"));
if(meterModel.isEmpty()) {
meterModel = payload.substring(payload.indexOf(listId) + listId.length(), payload.indexOf(F("\n")));
meterModel.trim();
String meterIdStr = extract(payload, F("96.1.0"));
if(meterIdStr.isEmpty()) {
meterIdStr = extract(payload, F("0.0.5"));
}
strncpy(meterId, meterIdStr.c_str(), sizeof(meterId) - 1);
String meterModelStr = extract(payload, F("96.1.1"));
if(meterModelStr.isEmpty()) {
meterModelStr = extract(payload, F("96.1.7"));
if(meterModelStr.isEmpty()) {
meterModelStr = payload.substring(payload.indexOf(listIdStr) + listIdStr.length(), payload.indexOf(F("\n")));
meterModelStr.trim();
}
}
strncpy(meterModel, meterModelStr.c_str(), sizeof(meterModel) - 1);
tmElements_t tm { 0, 0, 0, 0, 0, 0, 0 };
String timestamp = extract(payload, F("1.0.0"));

View File

@@ -213,7 +213,7 @@ IEC6205675::IEC6205675(const char* d, Timezone* tz, uint8_t useMeterType, MeterC
uint8_t str_len = 0;
str_len = getString(AMS_OBIS_UNKNOWN_1, sizeof(AMS_OBIS_UNKNOWN_1), ((char *) (d)), str);
if(str_len > 0) {
meterId = String(str);
strncpy(meterId, str, sizeof(meterId) - 1);
}
listType = 4;
@@ -227,9 +227,8 @@ IEC6205675::IEC6205675(const char* d, Timezone* tz, uint8_t useMeterType, MeterC
} else if(data->base.type == CosemTypeOctetString) { // Assuming first string is a list identifier
memcpy(str, data->oct.data, data->oct.length);
str[data->oct.length] = 0x00;
String listId = String(str);
if(listId.startsWith(F("KFM_001"))) {
this->listId = listId;
if(strncmp(str, "KFM_001", 7) == 0) {
strncpy(this->listId, str, sizeof(this->listId) - 1);
meterType = AmsTypeKaifa;
uint8_t idx = 0;
@@ -241,12 +240,12 @@ IEC6205675::IEC6205675(const char* d, Timezone* tz, uint8_t useMeterType, MeterC
data = getCosemDataAt(idx++, ((char *) (d)));
memcpy(str, data->oct.data, data->oct.length);
str[data->oct.length] = 0x00;
meterId = String(str);
strncpy(meterId, str, sizeof(meterId) - 1);
data = getCosemDataAt(idx++, ((char *) (d)));
memcpy(str, data->oct.data, data->oct.length);
str[data->oct.length] = 0x00;
meterModel = String(str);
strncpy(meterModel, str, sizeof(meterModel) - 1);
data = getCosemDataAt(idx++, ((char *) (d)));
activeImportPower = ntohl(data->dlu.data);
@@ -277,12 +276,12 @@ IEC6205675::IEC6205675(const char* d, Timezone* tz, uint8_t useMeterType, MeterC
data = getCosemDataAt(idx++, ((char *) (d)));
memcpy(str, data->oct.data, data->oct.length);
str[data->oct.length] = 0x00;
meterId = String(str);
strncpy(meterId, str, sizeof(meterId) - 1);
data = getCosemDataAt(idx++, ((char *) (d)));
memcpy(str, data->oct.data, data->oct.length);
str[data->oct.length] = 0x00;
meterModel = String(str);
strncpy(meterModel, str, sizeof(meterModel) - 1);
data = getCosemDataAt(idx++, ((char *) (d)));
activeImportPower = ntohl(data->dlu.data);
@@ -301,7 +300,7 @@ IEC6205675::IEC6205675(const char* d, Timezone* tz, uint8_t useMeterType, MeterC
l1voltage = ntohl(data->dlu.data) / 10.0;
}
if(listType >= 2 && memcmp(meterModel.c_str(), "MA304T3", 7) == 0) {
if(listType >= 2 && memcmp(meterModel, "MA304T3", 7) == 0) {
l2voltage = sqrt(pow(l1voltage - l3voltage * cos(60 * (PI/180)), 2) + pow(l3voltage * sin(60 * (PI/180)),2));
l2currentMissing = true;
}
@@ -330,8 +329,8 @@ IEC6205675::IEC6205675(const char* d, Timezone* tz, uint8_t useMeterType, MeterC
}
lastUpdateMillis = millis64();
} else if(listId.startsWith("ISK")) { // Iskra special case
this->listId = listId;
} else if(strncmp(listId, "ISK", 3) == 0) { // Iskra special case
strncpy(this->listId, str, sizeof(this->listId) - 1);
meterType = AmsTypeIskra;
uint8_t idx = 0;
@@ -347,7 +346,7 @@ IEC6205675::IEC6205675(const char* d, Timezone* tz, uint8_t useMeterType, MeterC
data = getCosemDataAt(idx++, ((char *) (d)));
memcpy(str, data->oct.data, data->oct.length);
str[data->oct.length] = 0x00;
meterId = String(str);
strncpy(meterId, str, sizeof(meterId) - 1);
// 1.7.0
data = getCosemDataAt(idx++, ((char *) (d)));
@@ -427,7 +426,7 @@ IEC6205675::IEC6205675(const char* d, Timezone* tz, uint8_t useMeterType, MeterC
data = getCosemDataAt(idx++, ((char *) (d)));
memcpy(str, data->oct.data, data->oct.length);
str[data->oct.length] = 0x00;
meterId = String(str);
strncpy(meterId, str, sizeof(meterId) - 1);
// 96.3.10 Disconnect control
// 96.14.0 Currently acrive energy tariff
@@ -469,7 +468,7 @@ IEC6205675::IEC6205675(const char* d, Timezone* tz, uint8_t useMeterType, MeterC
data = getCosemDataAt(idx++, ((char *) (d)));
memcpy(str, data->oct.data, data->oct.length);
str[data->oct.length] = 0x00;
meterId = String(str);
strncpy(meterId, str, sizeof(meterId) - 1);
// 32.7.0
data = getCosemDataAt(idx++, ((char *) (d)));
@@ -526,7 +525,7 @@ IEC6205675::IEC6205675(const char* d, Timezone* tz, uint8_t useMeterType, MeterC
data = getCosemDataAt(idx++, ((char *) (d)));
memcpy(str, data->oct.data, data->oct.length);
str[data->oct.length] = 0x00;
meterId = String(str);
strncpy(meterId, str, sizeof(meterId) - 1);
// 1.7.0
data = getCosemDataAt(idx++, ((char *) (d)));
@@ -572,7 +571,7 @@ IEC6205675::IEC6205675(const char* d, Timezone* tz, uint8_t useMeterType, MeterC
data = getCosemDataAt(idx++, ((char *) (d)));
memcpy(str, data->oct.data, data->oct.length);
str[data->oct.length] = 0x00;
meterId = String(str);
strncpy(meterId, str, sizeof(meterId) - 1);
// 1.8.1
data = getCosemDataAt(idx++, ((char *) (d)));
@@ -633,7 +632,7 @@ IEC6205675::IEC6205675(const char* d, Timezone* tz, uint8_t useMeterType, MeterC
data = getCosemDataAt(idx++, ((char *) (d)));
memcpy(str, data->oct.data, data->oct.length);
str[data->oct.length] = 0x00;
meterId = String(str);
strncpy(meterId, str, sizeof(meterId) - 1);
// 1.7.0
data = getCosemDataAt(idx++, ((char *) (d)));
@@ -707,7 +706,7 @@ IEC6205675::IEC6205675(const char* d, Timezone* tz, uint8_t useMeterType, MeterC
data = getCosemDataAt(idx++, ((char *) (d)));
memcpy(str, data->oct.data, data->oct.length);
str[data->oct.length] = 0x00;
meterId = String(str);
strncpy(meterId, str, sizeof(meterId) - 1);
// 32.7.0
data = getCosemDataAt(idx++, ((char *) (d)));
@@ -778,7 +777,7 @@ IEC6205675::IEC6205675(const char* d, Timezone* tz, uint8_t useMeterType, MeterC
str_len = getString(AMS_OBIS_UNKNOWN_1, sizeof(AMS_OBIS_UNKNOWN_1), ((char *) (d)), str);
if(str_len > 0) {
meterType = AmsTypeIskra;
meterId = String(str);
strncpy(meterId, str, sizeof(meterId) - 1);
lastUpdateMillis = millis64();
listType = 3;
}
@@ -810,7 +809,7 @@ IEC6205675::IEC6205675(const char* d, Timezone* tz, uint8_t useMeterType, MeterC
uint8_t str_len = 0;
str_len = getString(AMS_OBIS_VERSION, sizeof(AMS_OBIS_VERSION), ((char *) (d)), str);
if(str_len > 0) {
listId = String(str);
strncpy(listId, str, sizeof(listId) - 1);
}
val = getNumber(AMS_OBIS_ACTIVE_EXPORT, sizeof(AMS_OBIS_ACTIVE_EXPORT), ((char *) (d)));
@@ -885,21 +884,21 @@ IEC6205675::IEC6205675(const char* d, Timezone* tz, uint8_t useMeterType, MeterC
str_len = getString(AMS_OBIS_METER_MODEL, sizeof(AMS_OBIS_METER_MODEL), ((char *) (d)), str);
if(str_len > 0) {
meterModel = String(str);
strncpy(meterModel, str, sizeof(meterModel) - 1);
} else {
str_len = getString(AMS_OBIS_METER_MODEL_2, sizeof(AMS_OBIS_METER_MODEL_2), ((char *) (d)), str);
if(str_len > 0) {
meterModel = String(str);
strncpy(meterModel, str, sizeof(meterModel) - 1);
}
}
str_len = getString(AMS_OBIS_METER_ID, sizeof(AMS_OBIS_METER_ID), ((char *) (d)), str);
if(str_len > 0) {
meterId = String(str);
strncpy(meterId, str, sizeof(meterId) - 1);
} else {
str_len = getString(AMS_OBIS_METER_ID_2, sizeof(AMS_OBIS_METER_ID_2), ((char *) (d)), str);
if(str_len > 0) {
meterId = String(str);
strncpy(meterId, str, sizeof(meterId) - 1);
}
}
@@ -1035,12 +1034,12 @@ IEC6205675::IEC6205675(const char* d, Timezone* tz, uint8_t useMeterType, MeterC
case CosemTypeString:
memcpy(str, mid->oct.data, mid->oct.length);
str[mid->oct.length] = 0x00;
meterId = String(str);
strncpy(meterId, str, sizeof(meterId) - 1);
break;
case CosemTypeOctetString:
memcpy(str, mid->str.data, mid->str.length);
str[mid->str.length] = 0x00;
meterId = String(str);
strncpy(meterId, str, sizeof(meterId) - 1);
break;
}
}
@@ -1059,9 +1058,9 @@ IEC6205675::IEC6205675(const char* d, Timezone* tz, uint8_t useMeterType, MeterC
meterType = AmsTypeIskra;
}
if(meterId.isEmpty() && meterType != AmsTypeUnknown) {
if(meterId[0] == '\0' && meterType != AmsTypeUnknown) {
stripNonAscii((uint8_t*) ctx.system_title, 8);
meterId = String((const char*)ctx.system_title);
strncpy(meterId, (const char*)ctx.system_title, sizeof(meterId) - 1);
}
}
@@ -1105,7 +1104,13 @@ IEC6205675::IEC6205675(const char* d, Timezone* tz, uint8_t useMeterType, MeterC
threePhase = true;
}
}
meterId.trim();
// Trim trailing whitespace from meterId
{
int len = strlen(meterId);
while(len > 0 && (meterId[len-1] == ' ' || meterId[len-1] == '\t' || meterId[len-1] == '\r' || meterId[len-1] == '\n')) {
meterId[--len] = '\0';
}
}
}
CosemData* IEC6205675::getCosemDataAt(uint8_t index, const char* ptr) {

View File

@@ -210,13 +210,13 @@ LNG::LNG(AmsData& meterState, const char* payload, uint8_t useMeterType, MeterCo
char str[item->oct.length+1];
memcpy(str, item->oct.data, item->oct.length);
str[item->oct.length] = '\0';
meterId = String(str);
strncpy(meterId, str, sizeof(meterId) - 1);
listType = listType >= 2 ? listType : 2;
} else if(descriptor->obis[4] == 1) {
char str[item->oct.length+1];
memcpy(str, item->oct.data, item->oct.length);
str[item->oct.length] = '\0';
meterModel = String(str);
strncpy(meterModel, str, sizeof(meterModel) - 1);
listType = listType >= 2 ? listType : 2;
}
}

View File

@@ -31,7 +31,7 @@ LNG2::LNG2(AmsData& meterState, const char* payload, uint8_t useMeterType, Meter
char str[64];
uint8_t str_len = getString((CosemData*) &d->meterId, str);
if(str_len > 0) {
this->meterId = String(str);
strncpy(this->meterId, str, sizeof(this->meterId) - 1);
}
listType = 3;
lastUpdateMillis = millis64();
@@ -57,7 +57,7 @@ LNG2::LNG2(AmsData& meterState, const char* payload, uint8_t useMeterType, Meter
char str[64];
uint8_t str_len = getString((CosemData*) &d->meterId, str);
if(str_len > 0) {
this->meterId = String(str);
strncpy(this->meterId, str, sizeof(this->meterId) - 1);
}
listType = 3;
lastUpdateMillis = millis64();

View File

@@ -409,7 +409,7 @@ bool RawMqttHandler::publishRaw(uint8_t* raw, size_t length) {
}
void RawMqttHandler::onMessage(String &topic, String &payload) {
if(topic.equals(subTopic)) {
if(topic == subTopic) {
if(payload.equals("fwupgrade")) {
if(strcmp(updater->getNextVersion(), FirmwareVersion::VersionString) != 0) {
updater->setTargetVersion(updater->getNextVersion());

View File

@@ -21,8 +21,8 @@ public:
int16_t getSize();
private:
int8_t* values;
uint8_t* scaling;
int8_t values[REALTIME_SIZE];
uint8_t scaling[REALTIME_SIZE];
unsigned long lastMillis = 0;
double lastReading = 0;

View File

@@ -5,11 +5,8 @@
*/
#include "RealtimePlot.h"
#include <stdlib.h>
RealtimePlot::RealtimePlot() {
values = (int8_t*) malloc(REALTIME_SIZE);
scaling = (uint8_t*) malloc(REALTIME_SIZE);
memset(values, 0, REALTIME_SIZE);
memset(scaling, 0, REALTIME_SIZE);
}

View File

@@ -96,12 +96,12 @@ private:
bool uploading = false;
File file;
bool performRestart = false;
String priceRegion = "";
String priceCurrency = "";
char priceRegion[8] = {};
char priceCurrency[4] = {};
#if defined(AMS2MQTT_FIRMWARE_URL)
String customFirmwareUrl = AMS2MQTT_FIRMWARE_URL;
char customFirmwareUrl[128] = AMS2MQTT_FIRMWARE_URL;
#else
String customFirmwareUrl;
char customFirmwareUrl[128] = {};
#endif
char* buf;

View File

@@ -648,8 +648,8 @@ void AmsWebServer::dataJson() {
ea->getProducedThisMonth(),
ea->getIncomeThisMonth(),
price == PRICE_NO_VALUE ? "false" : "true",
priceRegion.c_str(),
priceCurrency.c_str(),
priceRegion,
priceCurrency,
meterState->getLastError(),
ps == NULL ? 0 : ps->getLastError(),
(uint32_t) now,
@@ -1385,12 +1385,12 @@ void AmsWebServer::handleSave() {
}
if(server.hasArg(F("p")) && server.arg(F("p")) == F("true")) {
priceRegion = server.arg(F("pr"));
strncpy(priceRegion, server.arg(F("pr")).c_str(), sizeof(priceRegion) - 1);
PriceServiceConfig price;
price.enabled = server.hasArg(F("pe")) && server.arg(F("pe")) == F("true");
strcpy(price.entsoeToken, server.arg(F("pt")).c_str());
strcpy(price.area, priceRegion.c_str());
strcpy(price.area, priceRegion);
strcpy(price.currency, server.arg(F("pc")).c_str());
price.resolutionInMinutes = server.arg(F("pm")).toInt();
config->setPriceServiceConfig(price);
@@ -2022,8 +2022,8 @@ void AmsWebServer::realtimeJson() {
}
void AmsWebServer::setPriceSettings(String region, String currency) {
this->priceRegion = region;
this->priceCurrency = currency;
strncpy(this->priceRegion, region.c_str(), sizeof(this->priceRegion) - 1);
strncpy(this->priceCurrency, currency.c_str(), sizeof(this->priceCurrency) - 1);
}
void AmsWebServer::configFileDownload() {