mirror of
https://github.com/UtilitechAS/amsreader-firmware.git
synced 2026-03-27 10:40:45 +00:00
Heap memory improvements
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"));
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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() {
|
||||
|
||||
Reference in New Issue
Block a user