diff --git a/lib/AmsConfiguration/include/AmsConfiguration.h b/lib/AmsConfiguration/include/AmsConfiguration.h index c62cfb7d..3b8e4df7 100644 --- a/lib/AmsConfiguration/include/AmsConfiguration.h +++ b/lib/AmsConfiguration/include/AmsConfiguration.h @@ -9,6 +9,12 @@ #include #include "Arduino.h" +#if defined(ESP8266) +#define BUF_SIZE_COMMON 1024 +#else +#define BUF_SIZE_COMMON 4096 +#endif + #define EEPROM_SIZE 1024*3 #define EEPROM_EXPECTED_VERSION 104 // Used to check if config is stored. Change if structure changes #define EEPROM_CLEARED_INDICATOR 0xFC diff --git a/lib/AmsJsonGenerator/src/AmsJsonGenerator.cpp b/lib/AmsJsonGenerator/src/AmsJsonGenerator.cpp index 257a96f8..dcedc843 100644 --- a/lib/AmsJsonGenerator/src/AmsJsonGenerator.cpp +++ b/lib/AmsJsonGenerator/src/AmsJsonGenerator.cpp @@ -170,7 +170,7 @@ void AmsJsonGenerator::generateConfigurationJson(AmsConfiguration* config, char* qsr = LittleFS.exists(FILE_MQTT_CERT); qsk = LittleFS.exists(FILE_MQTT_KEY); } - pos += snprintf_P(buf+pos, bufSize-pos, PSTR(",\"q\":{\"h\":\"%s\",\"p\":%d,\"u\":\"%s\",\"a\":\"%s\",\"c\":\"%s\",\"b\":\"%s\",\"r\":\"%s\",\"m\":%d,\"s\":{\"e\":%s,\"c\":%s,\"r\":%s,\"k\":%s},\"t\":%d,\"d\":%d,\"i\":%d,\"k\":%d,\"e\":%d}"), + pos += snprintf_P(buf+pos, bufSize-pos, PSTR(",\"q\":{\"h\":\"%s\",\"p\":%d,\"u\":\"%s\",\"a\":\"%s\",\"c\":\"%s\",\"b\":\"%s\",\"r\":\"%s\",\"m\":%d,\"s\":{\"e\":%s,\"c\":%s,\"r\":%s,\"k\":%s},\"t\":%d,\"d\":%d,\"i\":%d,\"k\":%d,\"e\":%s}"), mqttConfig.host, mqttConfig.port, mqttConfig.username, diff --git a/lib/AmsMqttHandler/include/AmsMqttHandler.h b/lib/AmsMqttHandler/include/AmsMqttHandler.h index c210ab0f..0520b98b 100644 --- a/lib/AmsMqttHandler/include/AmsMqttHandler.h +++ b/lib/AmsMqttHandler/include/AmsMqttHandler.h @@ -29,21 +29,16 @@ public: #endif this->config = config; config->getMqttConfig(mqttConfig); - AmsMqttHandler(mqttConfig, debugger, buf, updater); + mqttConfigChanged = true; + init(debugger, buf, updater); }; #if defined(AMS_REMOTE_DEBUG) AmsMqttHandler(MqttConfig& MqttConfig, RemoteDebug* debugger, char* buf, AmsFirmwareUpdater* updater) { #else AmsMqttHandler(MqttConfig& MqttConfig, Stream* debugger, char* buf, AmsFirmwareUpdater* updater) { #endif - this->debugger = debugger; - this->json = buf; - this->updater = updater; - mqtt.dropOverflow(true); - - pubTopic = String(mqttConfig.publishTopic); - subTopic = String(mqttConfig.subscribeTopic); - if(subTopic.isEmpty()) subTopic = pubTopic+"/command"; + this->mqttConfig = MqttConfig; + init(debugger, buf, updater); } void setCaVerification(bool); @@ -88,16 +83,18 @@ protected: #endif AmsConfiguration* config; MqttConfig mqttConfig; - bool mqttConfigChanged = false; - + bool mqttConfigChanged = true; + #if defined(ESP32) + MQTTClient mqtt = MQTTClient(2048); + #else MQTTClient mqtt = MQTTClient(256); + #endif unsigned long lastMqttRetry = -10000; bool caVerification = true; WiFiClient *mqttClient = NULL; WiFiClientSecure *mqttSecureClient = NULL; boolean _connected = false; char* json; - uint16_t BufferSize = 2048; uint64_t lastStateUpdate = 0; uint64_t lastSuccessfulLoop = 0; @@ -106,6 +103,22 @@ protected: AmsFirmwareUpdater* updater = NULL; bool rebootSuggested = false; + +private: + #if defined(AMS_REMOTE_DEBUG) + void init(RemoteDebug* debugger, char* buf, AmsFirmwareUpdater* updater) { + #else + void init(Stream* debugger, char* buf, AmsFirmwareUpdater* updater) { + #endif + this->debugger = debugger; + this->json = buf; + this->updater = updater; + mqtt.dropOverflow(true); + + pubTopic = String(mqttConfig.publishTopic); + subTopic = String(mqttConfig.subscribeTopic); + if(subTopic.isEmpty()) subTopic = pubTopic+"/command"; + } }; #endif diff --git a/lib/DomoticzMqttHandler/src/DomoticzMqttHandler.cpp b/lib/DomoticzMqttHandler/src/DomoticzMqttHandler.cpp index 269268dc..d46acea6 100644 --- a/lib/DomoticzMqttHandler/src/DomoticzMqttHandler.cpp +++ b/lib/DomoticzMqttHandler/src/DomoticzMqttHandler.cpp @@ -29,7 +29,7 @@ bool DomoticzMqttHandler::publish(AmsData* update, AmsData* previousState, Energ if(energy > 0.0) { char val[16]; snprintf_P(val, 16, PSTR("%.1f;%.1f"), (data.getActiveImportPower()/1.0), energy*1000.0); - snprintf_P(json, BufferSize, DOMOTICZ_JSON, + snprintf_P(json, BUF_SIZE_COMMON, DOMOTICZ_JSON, config.elidx, val ); @@ -44,7 +44,7 @@ bool DomoticzMqttHandler::publish(AmsData* update, AmsData* previousState, Energ if (config.vl1idx > 0){ char val[16]; snprintf_P(val, 16, PSTR("%.2f"), data.getL1Voltage()); - snprintf_P(json, BufferSize, DOMOTICZ_JSON, + snprintf_P(json, BUF_SIZE_COMMON, DOMOTICZ_JSON, config.vl1idx, val ); @@ -55,7 +55,7 @@ bool DomoticzMqttHandler::publish(AmsData* update, AmsData* previousState, Energ if (config.vl2idx > 0){ char val[16]; snprintf_P(val, 16, PSTR("%.2f"), data.getL2Voltage()); - snprintf_P(json, BufferSize, DOMOTICZ_JSON, + snprintf_P(json, BUF_SIZE_COMMON, DOMOTICZ_JSON, config.vl2idx, val ); @@ -66,7 +66,7 @@ bool DomoticzMqttHandler::publish(AmsData* update, AmsData* previousState, Energ if (config.vl3idx > 0){ char val[16]; snprintf(val, 16, "%.2f", data.getL3Voltage()); - snprintf_P(json, BufferSize, DOMOTICZ_JSON, + snprintf_P(json, BUF_SIZE_COMMON, DOMOTICZ_JSON, config.vl3idx, val ); @@ -77,7 +77,7 @@ bool DomoticzMqttHandler::publish(AmsData* update, AmsData* previousState, Energ if (config.cl1idx > 0){ char val[16]; snprintf(val, 16, "%.1f;%.1f;%.1f", data.getL1Current(), data.getL2Current(), data.getL3Current()); - snprintf_P(json, BufferSize, DOMOTICZ_JSON, + snprintf_P(json, BUF_SIZE_COMMON, DOMOTICZ_JSON, config.cl1idx, val ); diff --git a/lib/HomeAssistantMqttHandler/src/HomeAssistantMqttHandler.cpp b/lib/HomeAssistantMqttHandler/src/HomeAssistantMqttHandler.cpp index 79fb9778..ac174c6b 100644 --- a/lib/HomeAssistantMqttHandler/src/HomeAssistantMqttHandler.cpp +++ b/lib/HomeAssistantMqttHandler/src/HomeAssistantMqttHandler.cpp @@ -135,7 +135,7 @@ bool HomeAssistantMqttHandler::publishList1(AmsData* data, EnergyAccounting* ea) char pt[24]; toJsonIsoTimestamp(data->getPackageTimestamp(), pt, sizeof(pt)); - snprintf_P(json, BufferSize, HA1_JSON, data->getActiveImportPower(), pt); + snprintf_P(json, BUF_SIZE_COMMON, HA1_JSON, data->getActiveImportPower(), pt); return mqtt.publish(pubTopic + "/power", json); } @@ -146,7 +146,7 @@ bool HomeAssistantMqttHandler::publishList2(AmsData* data, EnergyAccounting* ea) char pt[24]; toJsonIsoTimestamp(data->getPackageTimestamp(), pt, sizeof(pt)); - snprintf_P(json, BufferSize, HA3_JSON, + snprintf_P(json, BUF_SIZE_COMMON, HA3_JSON, data->getListId().c_str(), data->getMeterId().c_str(), getMeterModel(data).c_str(), @@ -176,7 +176,7 @@ bool HomeAssistantMqttHandler::publishList3(AmsData* data, EnergyAccounting* ea) memset(pt, 0, 24); toJsonIsoTimestamp(data->getPackageTimestamp(), pt, sizeof(pt)); - snprintf_P(json, BufferSize, HA2_JSON, + snprintf_P(json, BUF_SIZE_COMMON, HA2_JSON, data->getActiveImportCounter(), data->getActiveExportCounter(), data->getReactiveImportCounter(), @@ -194,7 +194,7 @@ bool HomeAssistantMqttHandler::publishList4(AmsData* data, EnergyAccounting* ea) char pt[24]; toJsonIsoTimestamp(data->getPackageTimestamp(), pt, sizeof(pt)); - snprintf_P(json, BufferSize, HA4_JSON, + snprintf_P(json, BUF_SIZE_COMMON, HA4_JSON, data->getListId().c_str(), data->getMeterId().c_str(), getMeterModel(data).c_str(), @@ -246,7 +246,7 @@ bool HomeAssistantMqttHandler::publishRealtime(AmsData* data, EnergyAccounting* if(!peaks.isEmpty()) peaks += ","; peaks += String(ea->getPeak(i).value / 100.0, 2); } - uint16_t pos = snprintf_P(json, BufferSize, PSTR("{\"max\":%.1f,\"peaks\":[%s],\"threshold\":%d,\"hour\":{\"use\":%.2f,\"cost\":%.2f,\"produced\":%.2f,\"income\":%.2f},\"day\":{\"use\":%.2f,\"cost\":%.2f,\"produced\":%.2f,\"income\":%.2f},\"month\":{\"use\":%.2f,\"cost\":%.2f,\"produced\":%.2f,\"income\":%.2f}"), + uint16_t pos = snprintf_P(json, BUF_SIZE_COMMON, PSTR("{\"max\":%.1f,\"peaks\":[%s],\"threshold\":%d,\"hour\":{\"use\":%.2f,\"cost\":%.2f,\"produced\":%.2f,\"income\":%.2f},\"day\":{\"use\":%.2f,\"cost\":%.2f,\"produced\":%.2f,\"income\":%.2f},\"month\":{\"use\":%.2f,\"cost\":%.2f,\"produced\":%.2f,\"income\":%.2f}"), ea->getMonthMax(), peaks.c_str(), ea->getCurrentThreshold(), @@ -266,7 +266,7 @@ bool HomeAssistantMqttHandler::publishRealtime(AmsData* data, EnergyAccounting* uint32_t ms = millis(); if(lastThresholdPublish == 0 || ms-lastThresholdPublish > 3600000) { EnergyAccountingConfig* conf = ea->getConfig(); - pos += snprintf_P(json+pos, BufferSize-pos, PSTR(",\"thresholds\": [%d,%d,%d,%d,%d,%d,%d,%d,%d]"), + pos += snprintf_P(json+pos, BUF_SIZE_COMMON-pos, PSTR(",\"thresholds\": [%d,%d,%d,%d,%d,%d,%d,%d,%d]"), conf->thresholds[0], conf->thresholds[1], conf->thresholds[2], @@ -283,7 +283,7 @@ bool HomeAssistantMqttHandler::publishRealtime(AmsData* data, EnergyAccounting* time_t now = time(nullptr); char pt[24]; toJsonIsoTimestamp(now, pt, sizeof(pt)); - pos += snprintf_P(json+pos, BufferSize-pos, PSTR(",\"t\":%s"), pt); + pos += snprintf_P(json+pos, BUF_SIZE_COMMON-pos, PSTR(",\"t\":%s"), pt); json[pos++] = '}'; json[pos] = '\0'; @@ -301,7 +301,7 @@ bool HomeAssistantMqttHandler::publishTemperatures(AmsConfiguration* config, HwT TempSensorData* data = hw->getTempSensorData(i); if(data != NULL) { String id = toHex(data->address, 8); - pos += snprintf_P(json+pos, BufferSize-pos, PSTR("\"%s\":%.2f,"), + pos += snprintf_P(json+pos, BUF_SIZE_COMMON-pos, PSTR("\"%s\":%.2f,"), id.c_str(), data->lastRead ); @@ -309,13 +309,13 @@ bool HomeAssistantMqttHandler::publishTemperatures(AmsConfiguration* config, HwT publishTemperatureSensor(i+1, id); } } - pos += snprintf_P(json+pos, BufferSize-pos, PSTR("}")); + pos += snprintf_P(json+pos, BUF_SIZE_COMMON-pos, PSTR("}")); time_t now = time(nullptr); char pt[24]; toJsonIsoTimestamp(now, pt, sizeof(pt)); - pos += snprintf_P(json+pos, BufferSize-pos, PSTR(",\"t\":%s"), pt); - pos += snprintf_P(json+pos, BufferSize-pos, PSTR("}")); + 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); loop(); @@ -416,33 +416,33 @@ bool HomeAssistantMqttHandler::publishPrices(PriceService* ps) { toJsonIsoTimestamp(ts, ts6hr, sizeof(ts6hr)); } - uint16_t pos = snprintf_P(json, BufferSize, PSTR("{\"id\":\"%s\",\"prices\":{\"import\":["), WiFi.macAddress().c_str()); + uint16_t pos = snprintf_P(json, BUF_SIZE_COMMON, PSTR("{\"id\":\"%s\",\"prices\":{\"import\":["), WiFi.macAddress().c_str()); uint8_t currentPricePointIndex = ps->getCurrentPricePointIndex(); uint8_t numberOfPoints = ps->getNumberOfPointsAvailable(); for(int i = currentPricePointIndex; i < numberOfPoints; i++) { float val = ps->getPricePoint(PRICE_DIRECTION_IMPORT, i); if(val == PRICE_NO_VALUE) { - pos += snprintf_P(json+pos, BufferSize-pos, PSTR("null,")); + pos += snprintf_P(json+pos, BUF_SIZE_COMMON-pos, PSTR("null,")); } else { - pos += snprintf_P(json+pos, BufferSize-pos, PSTR("%.4f,"), val); + pos += snprintf_P(json+pos, BUF_SIZE_COMMON-pos, PSTR("%.4f,"), val); } } if(rteInit && ps->isExportPricesDifferentFromImport()) { pos--; - pos += snprintf_P(json+pos, BufferSize-pos, PSTR("],\"export\":[")); + pos += snprintf_P(json+pos, BUF_SIZE_COMMON-pos, PSTR("],\"export\":[")); for(int i = currentPricePointIndex; i < numberOfPoints; i++) { float val = ps->getPricePoint(PRICE_DIRECTION_EXPORT, i); if(val == PRICE_NO_VALUE) { - pos += snprintf_P(json+pos, BufferSize-pos, PSTR("null,")); + pos += snprintf_P(json+pos, BUF_SIZE_COMMON-pos, PSTR("null,")); } else { - pos += snprintf_P(json+pos, BufferSize-pos, PSTR("%.4f,"), val); + pos += snprintf_P(json+pos, BUF_SIZE_COMMON-pos, PSTR("%.4f,"), val); } } } pos--; - pos += snprintf_P(json+pos, BufferSize-pos, PSTR("],\"min\":%.4f,\"max\":%.4f,\"cheapest1hr\":%s,\"cheapest3hr\":%s,\"cheapest6hr\":%s}"), + pos += snprintf_P(json+pos, BUF_SIZE_COMMON-pos, PSTR("],\"min\":%.4f,\"max\":%.4f,\"cheapest1hr\":%s,\"cheapest3hr\":%s,\"cheapest6hr\":%s}"), min == INT16_MAX ? 0.0 : min, max == INT16_MIN ? 0.0 : max, ts1hr, @@ -452,7 +452,7 @@ bool HomeAssistantMqttHandler::publishPrices(PriceService* ps) { char pt[24]; toJsonIsoTimestamp(now, pt, sizeof(pt)); - pos += snprintf_P(json+pos, BufferSize-pos, PSTR(",\"t\":%s"), pt); + pos += snprintf_P(json+pos, BUF_SIZE_COMMON-pos, PSTR(",\"t\":%s"), pt); json[pos++] = '}'; json[pos] = '\0'; @@ -473,7 +473,7 @@ bool HomeAssistantMqttHandler::publishSystem(HwTools* hw, PriceService* ps, Ener char pt[24]; toJsonIsoTimestamp(now, pt, sizeof(pt)); - snprintf_P(json, BufferSize, PSTR("{\"id\":\"%s\",\"name\":\"%s\",\"up\":%d,\"vcc\":%.3f,\"rssi\":%d,\"temp\":%.2f,\"version\":\"%s\",\"t\":%s}"), + snprintf_P(json, BUF_SIZE_COMMON, PSTR("{\"id\":\"%s\",\"name\":\"%s\",\"up\":%d,\"vcc\":%.3f,\"rssi\":%d,\"temp\":%.2f,\"version\":\"%s\",\"t\":%s}"), WiFi.macAddress().c_str(), mqttConfig.clientId, (uint32_t) (millis64()/1000), @@ -499,7 +499,7 @@ void HomeAssistantMqttHandler::publishSensor(const HomeAssistantSensor sensor) { uid.replace("]", ""); uid.replace("'", ""); } - snprintf_P(json, BufferSize, HADISCOVER_JSON, + snprintf_P(json, BUF_SIZE_COMMON, HADISCOVER_JSON, sensorNamePrefix.c_str(), sensor.name, mqttConfig.publishTopic, sensor.topic, @@ -805,7 +805,7 @@ bool HomeAssistantMqttHandler::publishRaw(uint8_t* raw, size_t length) { if(strlen(mqttConfig.publishTopic) == 0 || !mqtt.connected()) return false; - if(length <= 0 || length > BufferSize) return false; + if(length <= 0 || length > BUF_SIZE_COMMON) return false; if(!dInit) { // Not sure how this sensor should be defined in HA, so skipping for now @@ -815,7 +815,7 @@ bool HomeAssistantMqttHandler::publishRaw(uint8_t* raw, size_t length) { String str = toHex(raw, length); - snprintf_P(json, BufferSize, PSTR("{\"data\":\"%s\"}"), str.c_str()); + snprintf_P(json, BUF_SIZE_COMMON, PSTR("{\"data\":\"%s\"}"), str.c_str()); char topic[192]; snprintf_P(topic, 192, PSTR("%s/data"), mqttConfig.publishTopic); bool ret = mqtt.publish(topic, json); @@ -825,7 +825,7 @@ bool HomeAssistantMqttHandler::publishRaw(uint8_t* raw, size_t length) { bool HomeAssistantMqttHandler::publishFirmware() { if(!fInit) { - snprintf_P(json, BufferSize, PSTR("{\"name\":\"%sFirmware\",\"stat_t\":\"%s/firmware\",\"uniq_id\":\"%s_fwupgrade\",\"dev_cla\":\"firmware\",\"cmd_t\":\"%s\",\"pl_inst\":\"fwupgrade\"}"), + 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(), deviceUid.c_str(), @@ -835,7 +835,7 @@ bool HomeAssistantMqttHandler::publishFirmware() { loop(); return fInit; } - snprintf_P(json, BufferSize, PSTR("{\"installed_version\":\"%s\",\"latest_version\":\"%s\",\"title\":\"amsreader firmware\",\"release_url\":\"https://github.com/UtilitechAS/amsreader-firmware/releases\",\"release_summary\":\"New version %s is available\",\"update_percentage\":%s}"), + snprintf_P(json, BUF_SIZE_COMMON, PSTR("{\"installed_version\":\"%s\",\"latest_version\":\"%s\",\"title\":\"amsreader firmware\",\"release_url\":\"https://github.com/UtilitechAS/amsreader-firmware/releases\",\"release_summary\":\"New version %s is available\",\"update_percentage\":%s}"), FirmwareVersion::VersionString, strlen(updater->getNextVersion()) == 0 ? FirmwareVersion::VersionString : updater->getNextVersion(), strlen(updater->getNextVersion()) == 0 ? FirmwareVersion::VersionString : updater->getNextVersion(), diff --git a/lib/JsonMqttHandler/src/JsonMqttHandler.cpp b/lib/JsonMqttHandler/src/JsonMqttHandler.cpp index 724945a4..cc38f5ed 100644 --- a/lib/JsonMqttHandler/src/JsonMqttHandler.cpp +++ b/lib/JsonMqttHandler/src/JsonMqttHandler.cpp @@ -19,7 +19,7 @@ bool JsonMqttHandler::publish(AmsData* update, AmsData* previousState, EnergyAcc } bool ret = false; - memset(json, 0, BufferSize); + memset(json, 0, BUF_SIZE_COMMON); AmsData data; if(mqttConfig.stateUpdate) { @@ -59,7 +59,7 @@ bool JsonMqttHandler::publish(AmsData* update, AmsData* previousState, EnergyAcc } uint16_t JsonMqttHandler::appendJsonHeader(AmsData* data) { - return snprintf_P(json, BufferSize, PSTR("{\"id\":\"%s\",\"name\":\"%s\",\"up\":%u,\"t\":%lu,\"vcc\":%.3f,\"rssi\":%d,\"temp\":%.2f,"), + return snprintf_P(json, BUF_SIZE_COMMON, PSTR("{\"id\":\"%s\",\"name\":\"%s\",\"up\":%u,\"t\":%lu,\"vcc\":%.3f,\"rssi\":%d,\"temp\":%.2f,"), WiFi.macAddress().c_str(), mqttConfig.clientId, (uint32_t) (millis64()/1000), @@ -86,7 +86,7 @@ uint16_t JsonMqttHandler::appendJsonFooter(EnergyAccounting* ea, uint16_t pos) { peaks += String(ea->getPeak(i).value / 100.0, 2); } - return snprintf_P(json+pos, BufferSize-pos, PSTR("%s\"%sh\":%.3f,\"%sd\":%.2f,\"%sm\":%.1f,\"%st\":%d,\"%sx\":%.2f,\"%she\":%.3f,\"%sde\":%.2f,\"%sme\":%.1f,\"peaks\":[%s]%s"), + return snprintf_P(json+pos, BUF_SIZE_COMMON-pos, PSTR("%s\"%sh\":%.3f,\"%sd\":%.2f,\"%sm\":%.1f,\"%st\":%d,\"%sx\":%.2f,\"%she\":%.3f,\"%sde\":%.2f,\"%sme\":%.1f,\"peaks\":[%s]%s"), strlen(pf) == 0 ? "},\"realtime\":{" : ",", pf, ea->getUseThisHour(), @@ -112,9 +112,9 @@ uint16_t JsonMqttHandler::appendJsonFooter(EnergyAccounting* ea, uint16_t pos) { bool JsonMqttHandler::publishList1(AmsData* data, EnergyAccounting* ea) { uint16_t pos = appendJsonHeader(data); if(mqttConfig.payloadFormat != 6) { - pos += snprintf_P(json+pos, BufferSize-pos, PSTR("\"data\":{")); + pos += snprintf_P(json+pos, BUF_SIZE_COMMON-pos, PSTR("\"data\":{")); } - pos += snprintf_P(json+pos, BufferSize-pos, PSTR("\"P\":%d"), data->getActiveImportPower()); + pos += snprintf_P(json+pos, BUF_SIZE_COMMON-pos, PSTR("\"P\":%d"), data->getActiveImportPower()); pos += appendJsonFooter(ea, pos); json[pos++] = '}'; json[pos] = '\0'; @@ -130,9 +130,9 @@ bool JsonMqttHandler::publishList1(AmsData* data, EnergyAccounting* ea) { bool JsonMqttHandler::publishList2(AmsData* data, EnergyAccounting* ea) { uint16_t pos = appendJsonHeader(data); if(mqttConfig.payloadFormat != 6) { - pos += snprintf_P(json+pos, BufferSize-pos, PSTR("\"data\":{")); + pos += snprintf_P(json+pos, BUF_SIZE_COMMON-pos, PSTR("\"data\":{")); } - pos += snprintf_P(json+pos, BufferSize-pos, PSTR("\"lv\":\"%s\",\"meterId\":\"%s\",\"type\":\"%s\",\"P\":%d,\"Q\":%d,\"PO\":%d,\"QO\":%d,\"I1\":%.2f,\"I2\":%.2f,\"I3\":%.2f,\"U1\":%.2f,\"U2\":%.2f,\"U3\":%.2f"), + pos += snprintf_P(json+pos, BUF_SIZE_COMMON-pos, PSTR("\"lv\":\"%s\",\"meterId\":\"%s\",\"type\":\"%s\",\"P\":%d,\"Q\":%d,\"PO\":%d,\"QO\":%d,\"I1\":%.2f,\"I2\":%.2f,\"I3\":%.2f,\"U1\":%.2f,\"U2\":%.2f,\"U3\":%.2f"), data->getListId().c_str(), data->getMeterId().c_str(), getMeterModel(data).c_str(), @@ -162,9 +162,9 @@ bool JsonMqttHandler::publishList2(AmsData* data, EnergyAccounting* ea) { bool JsonMqttHandler::publishList3(AmsData* data, EnergyAccounting* ea) { uint16_t pos = appendJsonHeader(data); if(mqttConfig.payloadFormat != 6) { - pos += snprintf_P(json+pos, BufferSize-pos, PSTR("\"data\":{")); + pos += snprintf_P(json+pos, BUF_SIZE_COMMON-pos, PSTR("\"data\":{")); } - pos += snprintf_P(json+pos, BufferSize-pos, PSTR("\"lv\":\"%s\",\"meterId\":\"%s\",\"type\":\"%s\",\"P\":%d,\"Q\":%d,\"PO\":%d,\"QO\":%d,\"I1\":%.2f,\"I2\":%.2f,\"I3\":%.2f,\"U1\":%.2f,\"U2\":%.2f,\"U3\":%.2f,\"tPI\":%.3f,\"tPO\":%.3f,\"tQI\":%.3f,\"tQO\":%.3f,\"rtc\":%lu"), + pos += snprintf_P(json+pos, BUF_SIZE_COMMON-pos, PSTR("\"lv\":\"%s\",\"meterId\":\"%s\",\"type\":\"%s\",\"P\":%d,\"Q\":%d,\"PO\":%d,\"QO\":%d,\"I1\":%.2f,\"I2\":%.2f,\"I3\":%.2f,\"U1\":%.2f,\"U2\":%.2f,\"U3\":%.2f,\"tPI\":%.3f,\"tPO\":%.3f,\"tQI\":%.3f,\"tQO\":%.3f,\"rtc\":%lu"), data->getListId().c_str(), data->getMeterId().c_str(), getMeterModel(data).c_str(), @@ -199,9 +199,9 @@ bool JsonMqttHandler::publishList3(AmsData* data, EnergyAccounting* ea) { bool JsonMqttHandler::publishList4(AmsData* data, EnergyAccounting* ea) { uint16_t pos = appendJsonHeader(data); if(mqttConfig.payloadFormat != 6) { - pos += snprintf_P(json+pos, BufferSize-pos, PSTR("\"data\":{")); + pos += snprintf_P(json+pos, BUF_SIZE_COMMON-pos, PSTR("\"data\":{")); } - pos += snprintf_P(json+pos, BufferSize-pos, PSTR("\"lv\":\"%s\",\"meterId\":\"%s\",\"type\":\"%s\",\"P\":%d,\"P1\":%d,\"P2\":%d,\"P3\":%d,\"Q\":%d,\"PO\":%d,\"PO1\":%d,\"PO2\":%d,\"PO3\":%d,\"QO\":%d,\"I1\":%.2f,\"I2\":%.2f,\"I3\":%.2f,\"U1\":%.2f,\"U2\":%.2f,\"U3\":%.2f,\"PF\":%.2f,\"PF1\":%.2f,\"PF2\":%.2f,\"PF3\":%.2f,\"tPI\":%.3f,\"tPO\":%.3f,\"tQI\":%.3f,\"tQO\":%.3f,\"tPI1\":%.3f,\"tPI2\":%.3f,\"tPI3\":%.3f,\"tPO1\":%.3f,\"tPO2\":%.3f,\"tPO3\":%.3f,\"rtc\":%lu"), + pos += snprintf_P(json+pos, BUF_SIZE_COMMON-pos, PSTR("\"lv\":\"%s\",\"meterId\":\"%s\",\"type\":\"%s\",\"P\":%d,\"P1\":%d,\"P2\":%d,\"P3\":%d,\"Q\":%d,\"PO\":%d,\"PO1\":%d,\"PO2\":%d,\"PO3\":%d,\"QO\":%d,\"I1\":%.2f,\"I2\":%.2f,\"I3\":%.2f,\"U1\":%.2f,\"U2\":%.2f,\"U3\":%.2f,\"PF\":%.2f,\"PF1\":%.2f,\"PF2\":%.2f,\"PF3\":%.2f,\"tPI\":%.3f,\"tPO\":%.3f,\"tQI\":%.3f,\"tQO\":%.3f,\"tPI1\":%.3f,\"tPI2\":%.3f,\"tPI3\":%.3f,\"tPO1\":%.3f,\"tPO2\":%.3f,\"tPO3\":%.3f,\"rtc\":%lu"), data->getListId().c_str(), data->getMeterId().c_str(), getMeterModel(data).c_str(), @@ -387,17 +387,17 @@ bool JsonMqttHandler::publishPrices(PriceService* ps) { } if(mqttConfig.payloadFormat == 6) { - uint16_t pos = snprintf_P(json, BufferSize, PSTR("{\"id\":\"%s\","), WiFi.macAddress().c_str()); + uint16_t pos = snprintf_P(json, BUF_SIZE_COMMON, PSTR("{\"id\":\"%s\","), WiFi.macAddress().c_str()); for(uint8_t i = 0;i < 38; i++) { if(values[i] == PRICE_NO_VALUE) { - pos += snprintf_P(json+pos, BufferSize-pos, PSTR("\"pr_%d\":null,"), i); + pos += snprintf_P(json+pos, BUF_SIZE_COMMON-pos, PSTR("\"pr_%d\":null,"), i); } else { - pos += snprintf_P(json+pos, BufferSize-pos, PSTR("\"pr_%d\":%.4f,"), i, values[i]); + pos += snprintf_P(json+pos, BUF_SIZE_COMMON-pos, PSTR("\"pr_%d\":%.4f,"), i, values[i]); } } - pos += snprintf_P(json+pos, BufferSize-pos, PSTR("\"pr_min\":%.4f,\"pr_max\":%.4f,\"pr_cheapest1hr\":%s,\"pr_cheapest3hr\":%s,\"pr_cheapest6hr\":%s}"), + pos += snprintf_P(json+pos, BUF_SIZE_COMMON-pos, PSTR("\"pr_min\":%.4f,\"pr_max\":%.4f,\"pr_cheapest1hr\":%s,\"pr_cheapest3hr\":%s,\"pr_cheapest6hr\":%s}"), min == INT16_MAX ? 0.0 : min, max == INT16_MIN ? 0.0 : max, ts1hr, @@ -405,33 +405,33 @@ bool JsonMqttHandler::publishPrices(PriceService* ps) { ts6hr ); } else { - uint16_t pos = snprintf_P(json, BufferSize, PSTR("{\"id\":\"%s\",\"prices\":{\"import\":["), WiFi.macAddress().c_str()); + uint16_t pos = snprintf_P(json, BUF_SIZE_COMMON, PSTR("{\"id\":\"%s\",\"prices\":{\"import\":["), WiFi.macAddress().c_str()); uint8_t currentPricePointIndex = ps->getCurrentPricePointIndex(); uint8_t numberOfPoints = ps->getNumberOfPointsAvailable(); for(int i = currentPricePointIndex; i < numberOfPoints; i++) { float val = ps->getPricePoint(PRICE_DIRECTION_IMPORT, i); if(val == PRICE_NO_VALUE) { - pos += snprintf_P(json+pos, BufferSize-pos, PSTR("null,")); + pos += snprintf_P(json+pos, BUF_SIZE_COMMON-pos, PSTR("null,")); } else { - pos += snprintf_P(json+pos, BufferSize-pos, PSTR("%.4f,"), val); + pos += snprintf_P(json+pos, BUF_SIZE_COMMON-pos, PSTR("%.4f,"), val); } } if(hasExport && ps->isExportPricesDifferentFromImport()) { pos--; - pos += snprintf_P(json+pos, BufferSize-pos, PSTR("],\"export\":[")); + pos += snprintf_P(json+pos, BUF_SIZE_COMMON-pos, PSTR("],\"export\":[")); for(int i = currentPricePointIndex; i < numberOfPoints; i++) { float val = ps->getPricePoint(PRICE_DIRECTION_EXPORT, i); if(val == PRICE_NO_VALUE) { - pos += snprintf_P(json+pos, BufferSize-pos, PSTR("null,")); + pos += snprintf_P(json+pos, BUF_SIZE_COMMON-pos, PSTR("null,")); } else { - pos += snprintf_P(json+pos, BufferSize-pos, PSTR("%.4f,"), val); + pos += snprintf_P(json+pos, BUF_SIZE_COMMON-pos, PSTR("%.4f,"), val); } } } pos--; - pos += snprintf_P(json+pos, BufferSize-pos, PSTR("],\"min\":%.4f,\"max\":%.4f,\"cheapest1hr\":%s,\"cheapest3hr\":%s,\"cheapest6hr\":%s}}"), + pos += snprintf_P(json+pos, BUF_SIZE_COMMON-pos, PSTR("],\"min\":%.4f,\"max\":%.4f,\"cheapest1hr\":%s,\"cheapest3hr\":%s,\"cheapest6hr\":%s}}"), min == INT16_MAX ? 0.0 : min, max == INT16_MIN ? 0.0 : max, ts1hr, @@ -456,7 +456,7 @@ bool JsonMqttHandler::publishSystem(HwTools* hw, PriceService* ps, EnergyAccount if(strlen(mqttConfig.publishTopic) == 0 || !connected()) return false; - snprintf_P(json, BufferSize, PSTR("{\"id\":\"%s\",\"name\":\"%s\",\"up\":%d,\"vcc\":%.3f,\"rssi\":%d,\"temp\":%.2f,\"version\":\"%s\"}"), + snprintf_P(json, BUF_SIZE_COMMON, PSTR("{\"id\":\"%s\",\"name\":\"%s\",\"up\":%d,\"vcc\":%.3f,\"rssi\":%d,\"temp\":%.2f,\"version\":\"%s\"}"), WiFi.macAddress().c_str(), mqttConfig.clientId, (uint32_t) (millis64()/1000), @@ -485,11 +485,11 @@ bool JsonMqttHandler::publishRaw(uint8_t* raw, size_t length) { if(strlen(mqttConfig.publishTopic) == 0 || !mqtt.connected()) return false; - if(length <= 0 || length > BufferSize) return false; + if(length <= 0 || length > BUF_SIZE_COMMON) return false; String str = toHex(raw, length); - snprintf_P(json, BufferSize, PSTR("{\"data\":\"%s\"}"), str.c_str()); + snprintf_P(json, BUF_SIZE_COMMON, PSTR("{\"data\":\"%s\"}"), str.c_str()); char topic[192]; snprintf_P(topic, 192, PSTR("%s/data"), mqttConfig.publishTopic); bool ret = mqtt.publish(topic, json); @@ -498,7 +498,7 @@ bool JsonMqttHandler::publishRaw(uint8_t* raw, size_t length) { } bool JsonMqttHandler::publishFirmware() { - snprintf_P(json, BufferSize, PSTR("{\"installed_version\":\"%s\",\"latest_version\":\"%s\",\"title\":\"amsreader firmware\",\"release_url\":\"https://github.com/UtilitechAS/amsreader-firmware/releases\",\"release_summary\":\"New version %s is available\",\"update_percentage\":%s}"), + snprintf_P(json, BUF_SIZE_COMMON, PSTR("{\"installed_version\":\"%s\",\"latest_version\":\"%s\",\"title\":\"amsreader firmware\",\"release_url\":\"https://github.com/UtilitechAS/amsreader-firmware/releases\",\"release_summary\":\"New version %s is available\",\"update_percentage\":%s}"), FirmwareVersion::VersionString, strlen(updater->getNextVersion()) == 0 ? FirmwareVersion::VersionString : updater->getNextVersion(), strlen(updater->getNextVersion()) == 0 ? FirmwareVersion::VersionString : updater->getNextVersion(), @@ -546,16 +546,22 @@ void JsonMqttHandler::onMessage(String &topic, String &payload) { } else if(strcmp_P(action, PSTR("dayplot")) == 0) { char pubTopic[192]; snprintf_P(pubTopic, 192, PSTR("%s/dayplot"), mqttConfig.publishTopic); - AmsJsonGenerator::generateDayPlotJson(ds, json, BufferSize); + AmsJsonGenerator::generateDayPlotJson(ds, json, BUF_SIZE_COMMON); bool ret = mqtt.publish(pubTopic, json); loop(); } else if(strcmp_P(action, PSTR("monthplot")) == 0) { char pubTopic[192]; snprintf_P(pubTopic, 192, PSTR("%s/monthplot"), mqttConfig.publishTopic); - AmsJsonGenerator::generateMonthPlotJson(ds, json, BufferSize); + AmsJsonGenerator::generateMonthPlotJson(ds, json, BUF_SIZE_COMMON); bool ret = mqtt.publish(pubTopic, json); loop(); - } else if(strcmp_P(action, PSTR("config")) == 0 && obj.containsKey(F("config"))) { + } else if(strcmp_P(action, PSTR("getconfig")) == 0) { + char pubTopic[192]; + snprintf_P(pubTopic, 192, PSTR("%s/config"), mqttConfig.publishTopic); + AmsJsonGenerator::generateConfigurationJson(config, json, BUF_SIZE_COMMON); + bool ret = mqtt.publish(pubTopic, json); + loop(); + } else if(strcmp_P(action, PSTR("setconfig")) == 0 && obj.containsKey(F("config"))) { JsonObject configObj = obj[F("config")]; handleConfigMessage(configObj); } @@ -568,13 +574,13 @@ void JsonMqttHandler::onMessage(String &topic, String &payload) { } else if(payload.equals(F("dayplot"))) { char pubTopic[192]; snprintf_P(pubTopic, 192, PSTR("%s/dayplot"), mqttConfig.publishTopic); - AmsJsonGenerator::generateDayPlotJson(ds, json, BufferSize); + AmsJsonGenerator::generateDayPlotJson(ds, json, BUF_SIZE_COMMON); bool ret = mqtt.publish(pubTopic, json); loop(); } else if(payload.equals(F("monthplot"))) { char pubTopic[192]; snprintf_P(pubTopic, 192, PSTR("%s/monthplot"), mqttConfig.publishTopic); - AmsJsonGenerator::generateMonthPlotJson(ds, json, BufferSize); + AmsJsonGenerator::generateMonthPlotJson(ds, json, BUF_SIZE_COMMON); bool ret = mqtt.publish(pubTopic, json); loop(); } @@ -607,7 +613,8 @@ void JsonMqttHandler::handleConfigMessage(JsonObject& configObj) { if(generalObj.containsKey(F("u"))) { strlcpy(webConfig.username, generalObj[F("u")], sizeof(webConfig.username)); } - if(generalObj.containsKey(F("p"))) { + // Check if password is provided and that it is not empty and is not equal *** (which is used in the UI to indicate that the password is set but not shown) + if(generalObj.containsKey(F("p")) && strlen(generalObj[F("p")]) > 0 && strcmp(generalObj[F("p")], "***") != 0) { strlcpy(webConfig.password, generalObj[F("p")], sizeof(webConfig.password)); } } @@ -633,14 +640,13 @@ void JsonMqttHandler::handleConfigMessage(JsonObject& configObj) { newConfig.baud = meterObj[F("b")]; } if(meterObj.containsKey(F("p"))) { - // TODO, string to enum newConfig.parity = meterObj[F("p")]; } if(meterObj.containsKey(F("i"))) { newConfig.invert = meterObj[F("i")]; } if(meterObj.containsKey(F("s"))) { - newConfig.bufferSize = meterObj[F("s")] / 64; // convert from bytes to 64 byte blocks + newConfig.bufferSize = (int) meterObj[F("s")] / 64; // convert from bytes to 64 byte blocks } if(meterObj.containsKey(F("d"))) { newConfig.distributionSystem = meterObj[F("d")]; @@ -657,10 +663,16 @@ void JsonMqttHandler::handleConfigMessage(JsonObject& configObj) { bool enabled = encryptionObj[F("e")]; if(enabled) { if(encryptionObj.containsKey(F("k"))) { - // TODO + String encryptionKeyHex = encryptionObj[F("k")]; + if(encryptionKeyHex.length() == 16) { + fromHex(newConfig.encryptionKey, encryptionKeyHex, 16); + } } if(encryptionObj.containsKey(F("a"))) { - // TODO + String authenticationKeyHex = encryptionObj[F("a")]; + if(authenticationKeyHex.length() == 16) { + fromHex(newConfig.authenticationKey, authenticationKeyHex, 16); + } } } else { memset(newConfig.encryptionKey, 0, sizeof(newConfig.encryptionKey)); @@ -668,378 +680,456 @@ void JsonMqttHandler::handleConfigMessage(JsonObject& configObj) { } } } + if(meterObj.containsKey(F("m"))) { + JsonObject multipliersObj = meterObj[F("m")]; + bool enabled = multipliersObj[F("e")]; + if(enabled) { + if(multipliersObj.containsKey(F("w"))) { + newConfig.wattageMultiplier = multipliersObj[F("w")]; + } + if(multipliersObj.containsKey(F("v"))) { + newConfig.voltageMultiplier = multipliersObj[F("v")]; + } + if(multipliersObj.containsKey(F("a"))) { + newConfig.amperageMultiplier = multipliersObj[F("a")]; + } + if(multipliersObj.containsKey(F("c"))) { + newConfig.accumulatedMultiplier = multipliersObj[F("c")]; + } + } else { + newConfig.wattageMultiplier = 1.0; + newConfig.voltageMultiplier = 1.0; + newConfig.amperageMultiplier = 1.0; + newConfig.accumulatedMultiplier = 1.0; + } + } config->setMeterConfig(newConfig); } - if(configObj.containsKey(F("system"))) { - SystemConfig newConfig; - config->getSystemConfig(newConfig); - - JsonObject systemObj = configObj[F("system")]; - if(systemObj.containsKey(F("country"))) { - strlcpy(newConfig.country, systemObj[F("country")], sizeof(newConfig.country)); - } - if(systemObj.containsKey(F("firmwareChannel"))) { - newConfig.firmwareChannel = systemObj[F("firmwareChannel")]; - } - config->setSystemConfig(newConfig); - } - - if(configObj.containsKey(F("network"))) { + // Network + if(configObj.containsKey(F("n"))) { NetworkConfig newConfig; config->getNetworkConfig(newConfig); - JsonObject networkObj = configObj[F("network")]; - if(networkObj.containsKey(F("mode"))) { - newConfig.mode = networkObj[F("mode")]; + JsonObject networkObj = configObj[F("n")]; + if(networkObj.containsKey(F("c"))) { + newConfig.mode = networkObj[F("c")]; } - if(newConfig.mode == 1 || newConfig.mode == 2) { - if(networkObj.containsKey(F("ssid"))) { - strlcpy(newConfig.ssid, networkObj[F("ssid")], sizeof(newConfig.ssid)); - } - if(networkObj.containsKey(F("psk"))) { - strlcpy(newConfig.psk, networkObj[F("psk")], sizeof(newConfig.psk)); - } - if(networkObj.containsKey(F("power"))) { - newConfig.power = networkObj[F("power")]; - } - if(networkObj.containsKey(F("sleep"))) { - newConfig.sleep = networkObj[F("sleep")]; - } - if(networkObj.containsKey(F("use11b"))) { - newConfig.use11b = networkObj[F("use11b")]; + if(networkObj.containsKey(F("m"))) { + if(strcmp_P(networkObj[F("m")], PSTR("dhcp")) == 0) { + newConfig.mode = 1; + } else if(strcmp_P(networkObj[F("m")], PSTR("static")) == 0) { + newConfig.mode = 2; } } - if(networkObj.containsKey(F("ip"))) { - strlcpy(newConfig.ip, networkObj[F("ip")], sizeof(newConfig.ip)); + + if(networkObj.containsKey(F("i"))) { + strlcpy(newConfig.ip, networkObj[F("i")], sizeof(newConfig.ip)); } - if(networkObj.containsKey(F("gateway"))) { - strlcpy(newConfig.gateway, networkObj[F("gateway")], sizeof(newConfig.gateway)); + if(networkObj.containsKey(F("s"))) { + strlcpy(newConfig.subnet, networkObj[F("s")], sizeof(newConfig.subnet)); } - if(networkObj.containsKey(F("subnet"))) { - strlcpy(newConfig.subnet, networkObj[F("subnet")], sizeof(newConfig.subnet)); + if(networkObj.containsKey(F("g"))) { + strlcpy(newConfig.gateway, networkObj[F("g")], sizeof(newConfig.gateway)); } - if(networkObj.containsKey(F("dns1"))) { - strlcpy(newConfig.dns1, networkObj[F("dns1")], sizeof(newConfig.dns1)); + if(networkObj.containsKey(F("d1"))) { + strlcpy(newConfig.dns1, networkObj[F("d1")], sizeof(newConfig.dns1)); } - if(networkObj.containsKey(F("dns2"))) { - strlcpy(newConfig.dns2, networkObj[F("dns2")], sizeof(newConfig.dns2)); + if(networkObj.containsKey(F("d2"))) { + strlcpy(newConfig.dns2, networkObj[F("d2")], sizeof(newConfig.dns2)); } - if(networkObj.containsKey(F("mdns"))) { - newConfig.mdns = networkObj[F("mdns")]; + if(networkObj.containsKey(F("d"))) { + newConfig.mdns = networkObj[F("d")]; } - if(networkObj.containsKey(F("ipv6"))) { - newConfig.ipv6 = networkObj[F("ipv6")]; + if(networkObj.containsKey(F("x"))) { + newConfig.ipv6 = networkObj[F("x")]; } config->setNetworkConfig(newConfig); + + NtpConfig ntpConfig; + config->getNtpConfig(ntpConfig); + if(networkObj.containsKey(F("n1"))) { + strlcpy(ntpConfig.server, networkObj[F("n1")], sizeof(ntpConfig.server)); + config->setNtpConfig(ntpConfig); + } + if(networkObj.containsKey(F("h"))) { + ntpConfig.dhcp = networkObj[F("h")]; + config->setNtpConfig(ntpConfig); + } + config->getNtpConfig(ntpConfig); } - if(configObj.containsKey(F("meter"))) { - MeterConfig newConfig; - config->getMeterConfig(newConfig); + // WiFi + if(configObj.containsKey(F("w"))) { + NetworkConfig newConfig; + config->getNetworkConfig(newConfig); - JsonObject meterObj = configObj[F("meter")]; - if(meterObj.containsKey(F("baud"))) { - newConfig.baud = meterObj[F("baud")]; - } - if(meterObj.containsKey(F("parity"))) { - newConfig.parity = meterObj[F("parity")]; - } - if(meterObj.containsKey(F("invert"))) { - newConfig.invert = meterObj[F("invert")]; - } - if(meterObj.containsKey(F("distributionSystem"))) { - newConfig.distributionSystem = meterObj[F("distributionSystem")]; - } - if(meterObj.containsKey(F("mainFuse"))) { - newConfig.mainFuse = meterObj[F("mainFuse")]; - } - if(meterObj.containsKey(F("productionCapacity"))) { - newConfig.productionCapacity = meterObj[F("productionCapacity")]; - } - if(meterObj.containsKey(F("wattageMultiplier"))) { - newConfig.wattageMultiplier = meterObj[F("wattageMultiplier")]; - } - if(meterObj.containsKey(F("voltageMultiplier"))) { - newConfig.voltageMultiplier = meterObj[F("voltageMultiplier")]; - } - if(meterObj.containsKey(F("amperageMultiplier"))) { - newConfig.amperageMultiplier = meterObj[F("amperageMultiplier")]; - } - if(meterObj.containsKey(F("accumulatedMultiplier"))) { - newConfig.accumulatedMultiplier = meterObj[F("accumulatedMultiplier")]; - } - if(meterObj.containsKey(F("parser"))) { - newConfig.parser = meterObj[F("parser")]; - } - if(meterObj.containsKey(F("bufferSize"))) { - newConfig.bufferSize = meterObj[F("bufferSize")]; - } - if(meterObj.containsKey(F("rxPin"))) { - newConfig.rxPin = meterObj[F("rxPin")]; - } - if(meterObj.containsKey(F("rxPinPullup"))) { - newConfig.rxPinPullup = meterObj[F("rxPinPullup")]; - } - if(meterObj.containsKey(F("txPin"))) { - newConfig.txPin = meterObj[F("txPin")]; + if(newConfig.mode == 1 || newConfig.mode == 2) { + JsonObject wifiObj = configObj[F("w")]; + if(wifiObj.containsKey(F("s"))) { + strlcpy(newConfig.ssid, wifiObj[F("s")], sizeof(newConfig.ssid)); + } + // Check if PSK is provided and that it is not empty and is not equal *** (which is used in the UI to indicate that the password is set but not shown) + if(wifiObj.containsKey(F("p")) && strlen(wifiObj[F("p")]) > 0 && strcmp(wifiObj[F("p")], "***") != 0) { + strlcpy(newConfig.psk, wifiObj[F("p")], sizeof(newConfig.psk)); + } + if(wifiObj.containsKey(F("w"))) { + newConfig.power = wifiObj[F("w")]; + } + if(wifiObj.containsKey(F("z"))) { + newConfig.sleep = wifiObj[F("z")]; + } + if(wifiObj.containsKey(F("b"))) { + newConfig.use11b = wifiObj[F("b")]; + } + config->setNetworkConfig(newConfig); } } - if(configObj.containsKey(F("mqtt"))) { + // MQTT + if(configObj.containsKey(F("q"))) { + JsonObject mqttObj = configObj[F("q")]; MqttConfig newConfig; config->getMqttConfig(newConfig); - - JsonObject mqttObj = configObj[F("mqtt")]; - if(mqttObj.containsKey(F("host"))) { - strlcpy(newConfig.host, mqttObj[F("host")], sizeof(newConfig.host)); + if(mqttObj.containsKey(F("p"))) { + newConfig.port = mqttObj[F("p")]; } - if(mqttObj.containsKey(F("port"))) { - newConfig.port = mqttObj[F("port")]; + if(mqttObj.containsKey(F("u"))) { + strlcpy(newConfig.username, mqttObj[F("u")], sizeof(newConfig.username)); } - if(mqttObj.containsKey(F("clientId"))) { - strlcpy(newConfig.clientId, mqttObj[F("clientId")], sizeof(newConfig.clientId)); + // Check if password is provided and that it is not empty and is not equal *** (which is used in the UI to indicate that the password is set but not shown) + if(mqttObj.containsKey(F("a")) && strlen(mqttObj[F("a")]) > 0 && strcmp(mqttObj[F("a")], "***") != 0) { + strlcpy(newConfig.password, mqttObj[F("a")], sizeof(newConfig.password)); } - if(mqttObj.containsKey(F("publishTopic"))) { - strlcpy(newConfig.publishTopic, mqttObj[F("publishTopic")], sizeof(newConfig.publishTopic)); + if(mqttObj.containsKey(F("c"))) { + strlcpy(newConfig.clientId, mqttObj[F("c")], sizeof(newConfig.clientId)); } - if(mqttObj.containsKey(F("subscribeTopic"))) { - strlcpy(newConfig.subscribeTopic, mqttObj[F("subscribeTopic")], sizeof(newConfig.subscribeTopic)); + if(mqttObj.containsKey(F("b"))) { + strlcpy(newConfig.publishTopic, mqttObj[F("b")], sizeof(newConfig.publishTopic)); } - if(mqttObj.containsKey(F("username"))) { - strlcpy(newConfig.username, mqttObj[F("username")], sizeof(newConfig.username)); + if(mqttObj.containsKey(F("r"))) { + strlcpy(newConfig.subscribeTopic, mqttObj[F("r")], sizeof(newConfig.subscribeTopic)); } - if(mqttObj.containsKey(F("password"))) { - strlcpy(newConfig.password, mqttObj[F("password")], sizeof(newConfig.password)); + if(mqttObj.containsKey(F("m"))) { + newConfig.payloadFormat = mqttObj[F("m")]; } - if(mqttObj.containsKey(F("payloadFormat"))) { - newConfig.payloadFormat = mqttObj[F("payloadFormat")]; + if(mqttObj.containsKey(F("t"))) { + newConfig.stateUpdate = mqttObj[F("s")]; } - if(mqttObj.containsKey(F("ssl"))) { - newConfig.ssl = mqttObj[F("ssl")]; + if(mqttObj.containsKey(F("d"))) { + newConfig.stateUpdateInterval = mqttObj[F("d")]; } - if(mqttObj.containsKey(F("stateUpdate"))) { - newConfig.stateUpdate = mqttObj[F("stateUpdate")]; + if(mqttObj.containsKey(F("i"))) { + newConfig.timeout = mqttObj[F("i")]; } - if(mqttObj.containsKey(F("stateUpdateInterval"))) { - newConfig.stateUpdateInterval = mqttObj[F("stateUpdateInterval")]; + if(mqttObj.containsKey(F("k"))) { + newConfig.keepalive = mqttObj[F("k")]; } - if(mqttObj.containsKey(F("timeout"))) { - newConfig.timeout = mqttObj[F("timeout")]; - } - if(mqttObj.containsKey(F("keepalive"))) { - newConfig.keepalive = mqttObj[F("keepalive")]; - } - if(mqttObj.containsKey(F("rebootMinutes"))) { - newConfig.rebootMinutes = mqttObj[F("rebootMinutes")]; + if(mqttObj.containsKey(F("e"))) { + newConfig.rebootMinutes = mqttObj[F("e")]; } config->setMqttConfig(newConfig); - if(mqttObj.containsKey(F("domoticz"))) { - DomoticzConfig newConfig; - config->getDomoticzConfig(newConfig); - JsonObject domoticzObj = mqttObj[F("domoticz")]; - if(domoticzObj.containsKey(F("elidx"))) { - newConfig.elidx = domoticzObj[F("elidx")]; + if(newConfig.payloadFormat == 3) { // Domiticz + if(configObj.containsKey(F("o"))) { + JsonObject domoticzObj = configObj[F("o")]; + DomoticzConfig domoticzConfig; + config->getDomoticzConfig(domoticzConfig); + if(domoticzObj.containsKey(F("e"))) { + domoticzConfig.elidx = domoticzObj[F("e")]; + } + if(domoticzObj.containsKey(F("c"))) { + domoticzConfig.cl1idx = domoticzObj[F("c")]; + } + if(domoticzObj.containsKey(F("u1"))) { + domoticzConfig.vl1idx = domoticzObj[F("u1")]; + } + if(domoticzObj.containsKey(F("u2"))) { + domoticzConfig.vl2idx = domoticzObj[F("u2")]; + } + if(domoticzObj.containsKey(F("u3"))) { + domoticzConfig.vl3idx = domoticzObj[F("u3")]; + } + config->setDomoticzConfig(domoticzConfig); } - if(domoticzObj.containsKey(F("vl1idx"))) { - newConfig.vl1idx = domoticzObj[F("vl1idx")]; + } else if(newConfig.payloadFormat == 4) { // Home Assistant + if(configObj.containsKey(F("h"))) { + JsonObject haObj = configObj[F("h")]; + HomeAssistantConfig haConfig; + config->getHomeAssistantConfig(haConfig); + if(haObj.containsKey(F("t"))) { + strlcpy(haConfig.discoveryPrefix, haObj[F("t")], sizeof(haConfig.discoveryPrefix)); + } + if(haObj.containsKey(F("h"))) { + strlcpy(haConfig.discoveryHostname, haObj[F("h")], sizeof(haConfig.discoveryHostname)); + } + if(haObj.containsKey(F("n"))) { + strlcpy(haConfig.discoveryNameTag, haObj[F("n")], sizeof(haConfig.discoveryNameTag)); + } + config->setHomeAssistantConfig(haConfig); } - if(domoticzObj.containsKey(F("vl2idx"))) { - newConfig.vl2idx = domoticzObj[F("vl2idx")]; - } - if(domoticzObj.containsKey(F("vl3idx"))) { - newConfig.vl3idx = domoticzObj[F("vl3idx")]; - } - if(domoticzObj.containsKey(F("cl1idx"))) { - newConfig.cl1idx = domoticzObj[F("cl1idx")]; - } - config->setDomoticzConfig(newConfig); - } - - if(mqttObj.containsKey(F("homeAssistant"))) { - HomeAssistantConfig newConfig; - config->getHomeAssistantConfig(newConfig); - JsonObject haObj = mqttObj[F("homeAssistant")]; - if(haObj.containsKey(F("discoveryPrefix"))) { - strlcpy(newConfig.discoveryPrefix, haObj[F("discoveryPrefix")], sizeof(newConfig.discoveryPrefix)); - } - if(haObj.containsKey(F("discoveryHostname"))) { - strlcpy(newConfig.discoveryHostname, haObj[F("discoveryHostname")], sizeof(newConfig.discoveryHostname)); - } - if(haObj.containsKey(F("discoveryNameTag"))) { - strlcpy(newConfig.discoveryNameTag, haObj[F("discoveryNameTag")], sizeof(newConfig.discoveryNameTag)); - } - config->setHomeAssistantConfig(newConfig); } } - if(configObj.containsKey(F("debug"))) { - DebugConfig newConfig; - config->getDebugConfig(newConfig); - - JsonObject debugObj = configObj[F("debug")]; - if(debugObj.containsKey(F("telnet"))) { - newConfig.telnet = debugObj[F("telnet")]; - } - if(debugObj.containsKey(F("serial"))) { - newConfig.serial = debugObj[F("serial")]; - } - if(debugObj.containsKey(F("level"))) { - newConfig.level = debugObj[F("level")]; - } - config->setDebugConfig(newConfig); - } - - if(configObj.containsKey(F("gpio"))) { - GpioConfig newConfig; - config->getGpioConfig(newConfig); - - JsonObject gpioObj = configObj[F("gpio")]; - if(gpioObj.containsKey(F("apPin"))) { - newConfig.apPin = gpioObj[F("apPin")]; - } - if(gpioObj.containsKey(F("ledPin"))) { - newConfig.ledPin = gpioObj[F("ledPin")]; - } - if(gpioObj.containsKey(F("ledInverted"))) { - newConfig.ledInverted = gpioObj[F("ledInverted")]; - } - if(gpioObj.containsKey(F("ledPinRed"))) { - newConfig.ledPinRed = gpioObj[F("ledPinRed")]; - } - if(gpioObj.containsKey(F("ledPinGreen"))) { - newConfig.ledPinGreen = gpioObj[F("ledPinGreen")]; - } - if(gpioObj.containsKey(F("ledPinBlue"))) { - newConfig.ledPinBlue = gpioObj[F("ledPinBlue")]; - } - if(gpioObj.containsKey(F("ledRgbInverted"))) { - newConfig.ledRgbInverted = gpioObj[F("ledRgbInverted")]; - } - if(gpioObj.containsKey(F("tempSensorPin"))) { - newConfig.tempSensorPin = gpioObj[F("tempSensorPin")]; - } - if(gpioObj.containsKey(F("tempAnalogSensorPin"))) { - newConfig.tempAnalogSensorPin = gpioObj[F("tempAnalogSensorPin")]; - } - if(gpioObj.containsKey(F("vccPin"))) { - newConfig.vccPin = gpioObj[F("vccPin")]; - } - if(gpioObj.containsKey(F("vccOffset"))) { - newConfig.vccOffset = gpioObj[F("vccOffset")]; - } - if(gpioObj.containsKey(F("vccMultiplier"))) { - newConfig.vccMultiplier = gpioObj[F("vccMultiplier")]; - } - if(gpioObj.containsKey(F("vccBootLimit"))) { - newConfig.vccBootLimit = gpioObj[F("vccBootLimit")]; - } - if(gpioObj.containsKey(F("vccResistorGnd"))) { - newConfig.vccResistorGnd = gpioObj[F("vccResistorGnd")]; - } - if(gpioObj.containsKey(F("vccResistorVcc"))) { - newConfig.vccResistorVcc = gpioObj[F("vccResistorVcc")]; - } - if(gpioObj.containsKey(F("ledDisablePin"))) { - newConfig.ledDisablePin = gpioObj[F("ledDisablePin")]; - } - if(gpioObj.containsKey(F("ledBehaviour"))) { - newConfig.ledBehaviour = gpioObj[F("ledBehaviour")]; - } - config->setGpioConfig(newConfig); - } - - if(configObj.containsKey(F("ntp"))) { - NtpConfig newConfig; - config->getNtpConfig(newConfig); - - JsonObject ntpObj = configObj[F("ntp")]; - if(ntpObj.containsKey(F("enable"))) { - newConfig.enable = ntpObj[F("enable")]; - } - if(ntpObj.containsKey(F("dhcp"))) { - newConfig.dhcp = ntpObj[F("dhcp")]; - } - if(ntpObj.containsKey(F("server"))) { - strlcpy(newConfig.server, ntpObj[F("server")], sizeof(newConfig.server)); - } - config->setNtpConfig(newConfig); - } - - if(configObj.containsKey(F("priceService"))) { + // Price service + if(configObj.containsKey(F("p"))) { PriceServiceConfig newConfig; config->getPriceServiceConfig(newConfig); - JsonObject priceServiceObj = configObj[F("priceService")]; - if(priceServiceObj.containsKey(F("area"))) { - strlcpy(newConfig.area, priceServiceObj[F("area")], sizeof(newConfig.area)); + JsonObject priceServiceObj = configObj[F("p")]; + if(priceServiceObj.containsKey(F("e"))) { + newConfig.enabled = priceServiceObj[F("e")]; } - if(priceServiceObj.containsKey(F("currency"))) { - strlcpy(newConfig.currency, priceServiceObj[F("currency")], sizeof(newConfig.currency)); + if(priceServiceObj.containsKey(F("r"))) { + strlcpy(newConfig.area, priceServiceObj[F("r")], sizeof(newConfig.area)); } - if(priceServiceObj.containsKey(F("resolutionInMinutes"))) { - newConfig.resolutionInMinutes = priceServiceObj[F("resolutionInMinutes")]; + if(priceServiceObj.containsKey(F("c"))) { + strlcpy(newConfig.currency, priceServiceObj[F("c")], sizeof(newConfig.currency)); } - if(priceServiceObj.containsKey(F("enabled"))) { - newConfig.enabled = priceServiceObj[F("enabled")]; + if(priceServiceObj.containsKey(F("m"))) { + newConfig.resolutionInMinutes = priceServiceObj[F("m")]; } config->setPriceServiceConfig(newConfig); } - if(configObj.containsKey(F("cloud"))) { - JsonObject cloudObj = configObj[F("cloud")]; - - if(cloudObj.containsKey(F("amsleser"))) { - CloudConfig newConfig; - config->getCloudConfig(newConfig); - - JsonObject amsCloudObj = cloudObj[F("amsleser")]; - if(amsCloudObj.containsKey(F("enabled"))) { - newConfig.enabled = amsCloudObj[F("enabled")]; - } - if(amsCloudObj.containsKey(F("interval"))) { - newConfig.interval = amsCloudObj[F("interval")]; - } - if(amsCloudObj.containsKey(F("hostname"))) { - strlcpy(newConfig.hostname, amsCloudObj[F("hostname")], sizeof(newConfig.hostname)); - } - if(amsCloudObj.containsKey(F("port"))) { - newConfig.port = amsCloudObj[F("port")]; - } - if(amsCloudObj.containsKey(F("clientId"))) { - strlcpy((char*)newConfig.clientId, amsCloudObj[F("clientId")], sizeof(newConfig.clientId)); - } - if(amsCloudObj.containsKey(F("proto"))) { - newConfig.proto = amsCloudObj[F("proto")]; - } - config->setCloudConfig(newConfig); + // Thresholds + if(configObj.containsKey(F("t"))) { + EnergyAccountingConfig newConfig; + config->getEnergyAccountingConfig(newConfig); + JsonObject thresholdObj = configObj[F("t")]; + if(thresholdObj.containsKey(F("h"))) { + newConfig.hours = thresholdObj[F("h")]; } - - if(cloudObj.containsKey(F("zmartcharge"))) { - ZmartChargeConfig newConfig; - config->getZmartChargeConfig(newConfig); - JsonObject zmartChargeObj = cloudObj[F("zmartcharge")]; - if(zmartChargeObj.containsKey(F("enabled"))) { - newConfig.enabled = zmartChargeObj[F("enabled")]; + if(thresholdObj.containsKey(F("t"))) { + JsonArray thresholdsArray = thresholdObj[F("t")].as(); + for(size_t i = 0; i < thresholdsArray.size(); i++) { + newConfig.thresholds[i] = thresholdsArray[i]; } - if(zmartChargeObj.containsKey(F("token"))) { - strlcpy(newConfig.token, zmartChargeObj[F("token")], sizeof(newConfig.token)); - } - if(zmartChargeObj.containsKey(F("baseUrl"))) { - strlcpy(newConfig.baseUrl, zmartChargeObj[F("baseUrl")], sizeof(newConfig.baseUrl)); - } - config->setZmartChargeConfig(newConfig); } + config->setEnergyAccountingConfig(newConfig); + } - if(cloudObj.containsKey(F("energyspeedometer"))) { - SystemConfig newConfig; - config->getSystemConfig(newConfig); - JsonObject speedometerObj = cloudObj[F("energyspeedometer")]; - if(speedometerObj.containsKey(F("enabled"))) { - newConfig.energyspeedometer = speedometerObj[F("enabled")]; + // Debug + if(configObj.containsKey(F("d"))) { + DebugConfig newConfig; + config->getDebugConfig(newConfig); + + JsonObject debugObj = configObj[F("d")]; + if(debugObj.containsKey(F("s"))) { + newConfig.serial = debugObj[F("s")]; + } + if(debugObj.containsKey(F("t"))) { + newConfig.telnet = debugObj[F("t")]; + } + if(debugObj.containsKey(F("l"))) { + newConfig.level = debugObj[F("l")]; + } + config->setDebugConfig(newConfig); + } + + // Cloud + if(configObj.containsKey(F("c"))) { + CloudConfig newConfig; + config->getCloudConfig(newConfig); + + JsonObject cloudObj = configObj[F("c")]; + if(cloudObj.containsKey(F("e"))) { + newConfig.enabled = cloudObj[F("e")]; + } + if(cloudObj.containsKey(F("p"))) { + newConfig.proto = cloudObj[F("p")]; + } + config->setCloudConfig(newConfig); + + if(cloudObj.containsKey(F("es"))) { + SystemConfig sysConfig; + config->getSystemConfig(sysConfig); + sysConfig.energyspeedometer = cloudObj[F("es")]; + config->setSystemConfig(sysConfig); + } + if(cloudObj.containsKey(F("ze"))) { + ZmartChargeConfig zmartConfig; + config->getZmartChargeConfig(zmartConfig); + zmartConfig.enabled = cloudObj[F("ze")]; + if(cloudObj.containsKey(F("zt"))) { + strlcpy(zmartConfig.token, cloudObj[F("zt")], sizeof(zmartConfig.token)); } - config->setSystemConfig(newConfig); + if(cloudObj.containsKey(F("zu"))) { + strlcpy(zmartConfig.baseUrl, cloudObj[F("zu")], sizeof(zmartConfig.baseUrl)); + } + config->setZmartChargeConfig(zmartConfig); + } + } + + // UI + if(configObj.containsKey(F("u"))) { + UiConfig newConfig; + config->getUiConfig(newConfig); + JsonObject uiObj = configObj[F("u")]; + if(uiObj.containsKey(F("i"))) { + newConfig.showImport = uiObj[F("i")]; + } + if(uiObj.containsKey(F("e"))) { + newConfig.showExport = uiObj[F("e")]; + } + if(uiObj.containsKey(F("v"))) { + newConfig.showVoltage = uiObj[F("v")]; + } + if(uiObj.containsKey(F("a"))) { + newConfig.showAmperage = uiObj[F("a")]; + } + if(uiObj.containsKey(F("r"))) { + newConfig.showReactive = uiObj[F("r")]; + } + if(uiObj.containsKey(F("c"))) { + newConfig.showRealtime = uiObj[F("c")]; + } + if(uiObj.containsKey(F("t"))) { + newConfig.showPeaks = uiObj[F("t")]; + } + if(uiObj.containsKey(F("p"))) { + newConfig.showPricePlot = uiObj[F("p")]; + } + if(uiObj.containsKey(F("d"))) { + newConfig.showDayPlot = uiObj[F("d")]; + } + if(uiObj.containsKey(F("m"))) { + newConfig.showMonthPlot = uiObj[F("m")]; + } + if(uiObj.containsKey(F("s"))) { + newConfig.showTemperaturePlot = uiObj[F("s")]; + } + if(uiObj.containsKey(F("l"))) { + newConfig.showRealtimePlot = uiObj[F("l")]; + } + if(uiObj.containsKey(F("h"))) { + newConfig.showPerPhasePower = uiObj[F("h")]; + } + if(uiObj.containsKey(F("f"))) { + newConfig.showPowerFactor = uiObj[F("f")]; + } + if(uiObj.containsKey(F("k"))) { + newConfig.darkMode = uiObj[F("k")]; + } + if(uiObj.containsKey(F("lang"))) { + strlcpy(newConfig.language, uiObj[F("lang")], sizeof(newConfig.language)); + } + config->setUiConfig(newConfig); + } + + // System + if(configObj.containsKey(F("s"))) { + SystemConfig sysConfig; + config->getSystemConfig(sysConfig); + JsonObject sysObj = configObj[F("s")]; + if(sysObj.containsKey(F("b"))) { + sysConfig.boardType = sysObj[F("b")]; + } + if(sysObj.containsKey(F("v"))) { + sysConfig.vendorConfigured = sysObj[F("v")]; + } + if(sysObj.containsKey(F("u"))) { + sysConfig.userConfigured = sysObj[F("u")]; + } + if(sysObj.containsKey(F("d"))) { + sysConfig.dataCollectionConsent = sysObj[F("d")]; + } + if(sysObj.containsKey(F("o"))) { + strlcpy(sysConfig.country, sysObj[F("o")], sizeof(sysConfig.country)); + } + if(sysObj.containsKey(F("c"))) { + sysConfig.firmwareChannel = sysObj[F("c")]; + } + config->setSystemConfig(sysConfig); + } + + // GPIO + if(configObj.containsKey(F("i"))) { + JsonObject gpioObj = configObj[F("i")]; + GpioConfig newConfig; + config->getGpioConfig(newConfig); + if(gpioObj.containsKey(F("a"))) { + newConfig.apPin = gpioObj[F("a")]; + } + if(gpioObj.containsKey(F("l"))) { + JsonObject ledObj = gpioObj[F("l")]; + if(ledObj.containsKey(F("p"))) { + newConfig.ledPin = ledObj[F("p")]; + } + if(ledObj.containsKey(F("i"))) { + newConfig.ledInverted = ledObj[F("i")]; + } + } + if(gpioObj.containsKey(F("r"))) { + JsonObject rgbLedObj = gpioObj[F("r")]; + if(rgbLedObj.containsKey(F("r"))) { + newConfig.ledPinRed = rgbLedObj[F("r")]; + } + if(rgbLedObj.containsKey(F("g"))) { + newConfig.ledPinGreen = rgbLedObj[F("g")]; + } + if(rgbLedObj.containsKey(F("b"))) { + newConfig.ledPinBlue = rgbLedObj[F("b")]; + } + if(rgbLedObj.containsKey(F("i"))) { + newConfig.ledRgbInverted = rgbLedObj[F("i")]; + } + } + if(gpioObj.containsKey(F("d"))) { + JsonObject ledDisableObj = gpioObj[F("d")]; + if(ledDisableObj.containsKey(F("d"))) { + newConfig.ledDisablePin = ledDisableObj[F("d")]; + } + if(ledDisableObj.containsKey(F("b"))) { + newConfig.ledBehaviour = ledDisableObj[F("b")]; + } + } + if(gpioObj.containsKey(F("t"))) { + JsonObject tempSensorObj = gpioObj[F("t")]; + if(tempSensorObj.containsKey(F("d"))) { + newConfig.tempSensorPin = tempSensorObj[F("d")]; + } + if(tempSensorObj.containsKey(F("a"))) { + newConfig.tempAnalogSensorPin = tempSensorObj[F("a")]; + } + } + if(gpioObj.containsKey(F("v"))) { + JsonObject vccObj = gpioObj[F("v")]; + if(vccObj.containsKey(F("p"))) { + newConfig.vccPin = vccObj[F("p")]; + } + if(vccObj.containsKey(F("o"))) { + newConfig.vccOffset = vccObj[F("o")]; + } + if(vccObj.containsKey(F("m"))) { + newConfig.vccMultiplier = vccObj[F("m")]; + } + if(vccObj.containsKey(F("d"))) { + JsonObject vccDividerObj = vccObj[F("d")]; + if(vccDividerObj.containsKey(F("v"))) { + newConfig.vccResistorVcc = vccDividerObj[F("v")]; + } + if(vccDividerObj.containsKey(F("g"))) { + newConfig.vccResistorGnd = vccDividerObj[F("g")]; + } + } + } + config->setGpioConfig(newConfig); + + if(gpioObj.containsKey(F("h"))) { + JsonObject hwObj = gpioObj[F("h")]; + MeterConfig meterConfig; + config->getMeterConfig(meterConfig); + if(hwObj.containsKey(F("p"))) { + meterConfig.rxPin = hwObj[F("p")]; + } + if(hwObj.containsKey(F("u"))) { + meterConfig.rxPinPullup = hwObj[F("u")]; + } + if(hwObj.containsKey(F("t"))) { + meterConfig.txPin = hwObj[F("t")]; + } + config->setMeterConfig(meterConfig); } } } diff --git a/lib/RawMqttHandler/src/RawMqttHandler.cpp b/lib/RawMqttHandler/src/RawMqttHandler.cpp index 521b592f..961ea6b4 100644 --- a/lib/RawMqttHandler/src/RawMqttHandler.cpp +++ b/lib/RawMqttHandler/src/RawMqttHandler.cpp @@ -400,7 +400,7 @@ bool RawMqttHandler::publishRaw(uint8_t* raw, size_t length) { if(topic.isEmpty() || !connected()) return false; - if(length <= 0 || length > BufferSize) return false; + if(length <= 0 || length > BUF_SIZE_COMMON) return false; String str = toHex(raw, length); bool ret = mqtt.publish(topic + "/data", str); diff --git a/lib/SvelteUi/include/AmsWebServer.h b/lib/SvelteUi/include/AmsWebServer.h index 5909708e..e846406a 100644 --- a/lib/SvelteUi/include/AmsWebServer.h +++ b/lib/SvelteUi/include/AmsWebServer.h @@ -104,8 +104,7 @@ private: String customFirmwareUrl; #endif - static const uint16_t BufferSize = 2048; - char* buf; + char* buf; #if defined(ESP8266) ESP8266WebServer server; diff --git a/lib/SvelteUi/src/AmsWebServer.cpp b/lib/SvelteUi/src/AmsWebServer.cpp index b4033891..ec4643e6 100644 --- a/lib/SvelteUi/src/AmsWebServer.cpp +++ b/lib/SvelteUi/src/AmsWebServer.cpp @@ -392,7 +392,7 @@ void AmsWebServer::sysinfoJson() { features += "\"zc\""; #endif - int size = snprintf_P(buf, BufferSize, SYSINFO_JSON, + int size = snprintf_P(buf, BUF_SIZE_COMMON, SYSINFO_JSON, FirmwareVersion::VersionString, #if defined(CONFIG_IDF_TARGET_ESP32S2) "esp32s2", @@ -584,7 +584,7 @@ void AmsWebServer::dataJson() { time_t now = time(nullptr); - snprintf_P(buf, BufferSize, DATA_JSON, + snprintf_P(buf, BUF_SIZE_COMMON, DATA_JSON, maxPwr == 0 ? meterState->isThreePhase() ? 20000 : 10000 : maxPwr, productionCapacity, mainFuse == 0 ? 40 : mainFuse, @@ -672,7 +672,7 @@ void AmsWebServer::dayplotJson() { if(ds == NULL) { notFound(); } else { - AmsJsonGenerator::generateDayPlotJson(ds, buf, BufferSize); + AmsJsonGenerator::generateDayPlotJson(ds, buf, BUF_SIZE_COMMON); addConditionalCloudHeaders(); server.sendHeader(HEADER_CACHE_CONTROL, CACHE_CONTROL_NO_CACHE); server.sendHeader(HEADER_PRAGMA, PRAGMA_NO_CACHE); @@ -690,7 +690,7 @@ void AmsWebServer::monthplotJson() { if(ds == NULL) { notFound(); } else { - AmsJsonGenerator::generateMonthPlotJson(ds, buf, BufferSize); + AmsJsonGenerator::generateMonthPlotJson(ds, buf, BUF_SIZE_COMMON); addConditionalCloudHeaders(); server.sendHeader(HEADER_CACHE_CONTROL, CACHE_CONTROL_NO_CACHE); server.sendHeader(HEADER_PRAGMA, PRAGMA_NO_CACHE); @@ -716,19 +716,19 @@ void AmsWebServer::energyPriceJson() { prices[i] = ps->getPriceForRelativeHour(PRICE_DIRECTION_IMPORT, i); } - uint16_t pos = snprintf_P(buf, BufferSize, PSTR("{\"currency\":\"%s\",\"source\":\"%s\""), + uint16_t pos = snprintf_P(buf, BUF_SIZE_COMMON, PSTR("{\"currency\":\"%s\",\"source\":\"%s\""), ps->getCurrency(), ps->getSource() ); for(uint8_t i = 0;i < 36; i++) { if(prices[i] == PRICE_NO_VALUE) { - pos += snprintf_P(buf+pos, BufferSize-pos, PSTR(",\"%02d\":null"), i); + pos += snprintf_P(buf+pos, BUF_SIZE_COMMON-pos, PSTR(",\"%02d\":null"), i); } else { - pos += snprintf_P(buf+pos, BufferSize-pos, PSTR(",\"%02d\":%.4f"), i, prices[i]); + pos += snprintf_P(buf+pos, BUF_SIZE_COMMON-pos, PSTR(",\"%02d\":%.4f"), i, prices[i]); } } - snprintf_P(buf+pos, BufferSize-pos, PSTR("}")); + snprintf_P(buf+pos, BUF_SIZE_COMMON-pos, PSTR("}")); addConditionalCloudHeaders(); server.sendHeader(HEADER_CACHE_CONTROL, CACHE_CONTROL_NO_CACHE); @@ -763,7 +763,7 @@ void AmsWebServer::priceJson(uint8_t direction) { prices[i] = ps->getPricePoint(direction, i); } - snprintf_P(buf, BufferSize, PSTR("{\"currency\":\"%s\",\"source\":\"%s\",\"resolution\":%d,\"direction\":\"%s\",\"cursor\":%d,\"importExportPriceDifferent\":%s,\"prices\":["), + snprintf_P(buf, BUF_SIZE_COMMON, PSTR("{\"currency\":\"%s\",\"source\":\"%s\",\"resolution\":%d,\"direction\":\"%s\",\"cursor\":%d,\"importExportPriceDifferent\":%s,\"prices\":["), ps->getCurrency(), ps->getSource(), ps->getResolutionInMinutes(), @@ -782,10 +782,10 @@ void AmsWebServer::priceJson(uint8_t direction) { for(uint8_t i = 0;i < numberOfPoints; i++) { if(prices[i] == PRICE_NO_VALUE) { - snprintf_P(buf, BufferSize, PSTR("%snull"), i == 0 ? "" : ","); + snprintf_P(buf, BUF_SIZE_COMMON, PSTR("%snull"), i == 0 ? "" : ","); server.sendContent(buf); } else { - snprintf_P(buf, BufferSize, PSTR("%s%.4f"), i == 0 ? "" : ",", prices[i]); + snprintf_P(buf, BUF_SIZE_COMMON, PSTR("%s%.4f"), i == 0 ? "" : ",", prices[i]); server.sendContent(buf); } } @@ -884,7 +884,7 @@ void AmsWebServer::configurationJson() { server.sendHeader(HEADER_EXPIRES, EXPIRES_OFF); server.setContentLength(CONTENT_LENGTH_UNKNOWN); - AmsJsonGenerator::generateConfigurationJson(config, buf, BufferSize); + AmsJsonGenerator::generateConfigurationJson(config, buf, BUF_SIZE_COMMON); server.send(200, MIME_JSON, buf); } @@ -921,7 +921,7 @@ void AmsWebServer::priceConfigJson() { } hours = hours.substring(0, hours.length()-1); - snprintf_P(buf, BufferSize, PSTR("{\"t\":%d,\"n\":\"%s\",\"d\":%d,\"a\":[%s],\"h\":[%s],\"v\":%.4f,\"s\":{\"m\":%d,\"d\":%d},\"e\":{\"m\":%d,\"d\":%d}}%s"), + snprintf_P(buf, BUF_SIZE_COMMON, PSTR("{\"t\":%d,\"n\":\"%s\",\"d\":%d,\"a\":[%s],\"h\":[%s],\"v\":%.4f,\"s\":{\"m\":%d,\"d\":%d},\"e\":{\"m\":%d,\"d\":%d}}%s"), p.type, p.name, p.direction, @@ -938,7 +938,7 @@ void AmsWebServer::priceConfigJson() { } } } - snprintf_P(buf, BufferSize, PSTR("]}")); + snprintf_P(buf, BUF_SIZE_COMMON, PSTR("]}")); server.sendContent(buf); } @@ -956,7 +956,7 @@ void AmsWebServer::translationsJson() { } } - snprintf_P(buf, BufferSize, PSTR("/translations-%s.json"), lang.c_str()); + snprintf_P(buf, BUF_SIZE_COMMON, PSTR("/translations-%s.json"), lang.c_str()); if(!LittleFS.exists(buf)) { notFound(); return; @@ -973,7 +973,7 @@ void AmsWebServer::translationsJson() { server.send(200, MIME_JSON); while(file.available() > 0) { - int len = file.readBytes(buf, BufferSize); + int len = file.readBytes(buf, BUF_SIZE_COMMON); server.sendContent(buf, len); } file.close(); @@ -988,7 +988,7 @@ void AmsWebServer::cloudkeyJson() { String seed = cloud->generateSeed(); - snprintf_P(buf, BufferSize, PSTR("{\"seed\":\"%s\"}"), seed.c_str()); + snprintf_P(buf, BUF_SIZE_COMMON, PSTR("{\"seed\":\"%s\"}"), seed.c_str()); server.setContentLength(strlen(buf)); server.sendHeader(HEADER_CACHE_CONTROL, CACHE_CONTROL_NO_CACHE); @@ -1437,19 +1437,19 @@ void AmsWebServer::handleSave() { uint8_t count = server.arg(F("rc")).toInt(); for(uint8_t i = 0; i < count; i++) { PriceConfig pc; - snprintf_P(buf, BufferSize, PSTR("rt%d"), i); + snprintf_P(buf, BUF_SIZE_COMMON, PSTR("rt%d"), i); pc.type = server.arg(buf).toInt(); - snprintf_P(buf, BufferSize, PSTR("rd%d"), i); + snprintf_P(buf, BUF_SIZE_COMMON, PSTR("rd%d"), i); pc.direction = server.arg(buf).toInt(); - snprintf_P(buf, BufferSize, PSTR("rv%d"), i); + snprintf_P(buf, BUF_SIZE_COMMON, PSTR("rv%d"), i); pc.value = server.arg(buf).toDouble() * 10000.0; - snprintf_P(buf, BufferSize, PSTR("rn%d"), i); + snprintf_P(buf, BUF_SIZE_COMMON, PSTR("rn%d"), i); String name = server.arg(buf); strcpy(pc.name, name.c_str()); int d = 0; pc.days = 0x00; - snprintf_P(buf, BufferSize, PSTR("ra%d"), i); + snprintf_P(buf, BUF_SIZE_COMMON, PSTR("ra%d"), i); String days = server.arg(buf); char * pch = strtok ((char*) days.c_str(),","); while (pch != NULL && d < 7) { @@ -1461,7 +1461,7 @@ void AmsWebServer::handleSave() { int h = 0; pc.hours = 0x00000000; - snprintf_P(buf, BufferSize, PSTR("rh%d"), i); + snprintf_P(buf, BUF_SIZE_COMMON, PSTR("rh%d"), i); String hours = server.arg(buf); pch = strtok ((char*) hours.c_str(),","); while (pch != NULL && h < 24) { @@ -1471,16 +1471,16 @@ void AmsWebServer::handleSave() { h++; } - snprintf_P(buf, BufferSize, PSTR("rsm%d"), i); + snprintf_P(buf, BUF_SIZE_COMMON, PSTR("rsm%d"), i); pc.start_month = server.arg(buf).toInt(); - snprintf_P(buf, BufferSize, PSTR("rsd%d"), i); + snprintf_P(buf, BUF_SIZE_COMMON, PSTR("rsd%d"), i); pc.start_dayofmonth = server.arg(buf).toInt(); - snprintf_P(buf, BufferSize, PSTR("rem%d"), i); + snprintf_P(buf, BUF_SIZE_COMMON, PSTR("rem%d"), i); pc.end_month = server.arg(buf).toInt(); - snprintf_P(buf, BufferSize, PSTR("red%d"), i); + snprintf_P(buf, BUF_SIZE_COMMON, PSTR("red%d"), i); pc.end_dayofmonth = server.arg(buf).toInt(); ps->setPriceConfig(i, pc); @@ -1522,7 +1522,7 @@ void AmsWebServer::handleSave() { success = false; } - snprintf_P(buf, BufferSize, RESPONSE_JSON, + snprintf_P(buf, BUF_SIZE_COMMON, RESPONSE_JSON, success ? "true" : "false", "", performRestart ? "true" : "false" @@ -1574,7 +1574,7 @@ void AmsWebServer::upgrade() { SystemConfig sys; config->getSystemConfig(sys); - snprintf_P(buf, BufferSize, RESPONSE_JSON, + snprintf_P(buf, BUF_SIZE_COMMON, RESPONSE_JSON, sys.dataCollectionConsent == 1 ? "true" : "false", "", sys.dataCollectionConsent == 1 ? "true" : "false" @@ -1637,7 +1637,7 @@ void AmsWebServer::firmwareUpload() { if (debugger->isActive(RemoteDebug::ERROR)) #endif debugger->printf_P(PSTR("Invalid file extension\n")); - snprintf_P(buf, BufferSize, RESPONSE_JSON, + snprintf_P(buf, BUF_SIZE_COMMON, RESPONSE_JSON, "false", "Invalid file extension", "false" @@ -1651,7 +1651,7 @@ void AmsWebServer::firmwareUpload() { if (debugger->isActive(RemoteDebug::ERROR)) #endif debugger->printf_P(PSTR("An error has occurred while starting firmware upload\n")); - snprintf_P(buf, BufferSize, RESPONSE_JSON, + snprintf_P(buf, BUF_SIZE_COMMON, RESPONSE_JSON, "false", "Unable to start firmware upgrade", "false" @@ -1678,7 +1678,7 @@ void AmsWebServer::firmwareUpload() { if (debugger->isActive(RemoteDebug::ERROR)) #endif debugger->printf_P(PSTR("An error has occurred while writing firmware to flash\n")); - snprintf_P(buf, BufferSize, RESPONSE_JSON, + snprintf_P(buf, BUF_SIZE_COMMON, RESPONSE_JSON, "false", "Unable to write to flash", "false" @@ -1704,7 +1704,7 @@ void AmsWebServer::firmwareUpload() { if (debugger->isActive(RemoteDebug::ERROR)) #endif debugger->printf_P(PSTR("An error has occurred while activating new firmware\n")); - snprintf_P(buf, BufferSize, RESPONSE_JSON, + snprintf_P(buf, BUF_SIZE_COMMON, RESPONSE_JSON, "false", "Unable to activate new firmware", "false" @@ -1752,7 +1752,7 @@ HTTPUpload& AmsWebServer::uploadFile(const char* path) { if (debugger->isActive(RemoteDebug::ERROR)) #endif debugger->printf_P(PSTR("An Error has occurred while writing file\n")); - snprintf_P(buf, BufferSize, RESPONSE_JSON, + snprintf_P(buf, BUF_SIZE_COMMON, RESPONSE_JSON, "false", "File size does not match", "false" @@ -1767,7 +1767,7 @@ HTTPUpload& AmsWebServer::uploadFile(const char* path) { file.close(); } else { debugger->printf_P(PSTR("File was not valid in the end... Write error: %d, \n"), file.getWriteError()); - snprintf_P(buf, BufferSize, RESPONSE_JSON, + snprintf_P(buf, BUF_SIZE_COMMON, RESPONSE_JSON, "false", "Upload ended, but file is missing", "false" @@ -1807,7 +1807,7 @@ void AmsWebServer::factoryResetPost() { success = true; } - snprintf_P(buf, BufferSize, RESPONSE_JSON, + snprintf_P(buf, BUF_SIZE_COMMON, RESPONSE_JSON, success ? "true" : "false", "", "true" @@ -1947,7 +1947,7 @@ void AmsWebServer::tariffJson() { String peaks; for(uint8_t x = 0;x < min((uint8_t) 5, eac->hours); x++) { EnergyAccountingPeak peak = ea->getPeak(x+1); - int len = snprintf_P(buf, BufferSize, PSTR("{\"d\":%d,\"h\":%d,\"v\":%.2f}"), + int len = snprintf_P(buf, BUF_SIZE_COMMON, PSTR("{\"d\":%d,\"h\":%d,\"v\":%.2f}"), peak.day, peak.hour, peak.value / 100.0 @@ -1957,7 +1957,7 @@ void AmsWebServer::tariffJson() { peaks += String(buf); } - snprintf_P(buf, BufferSize, TARIFF_JSON, + snprintf_P(buf, BUF_SIZE_COMMON, TARIFF_JSON, eac->thresholds[0], eac->thresholds[1], eac->thresholds[2], @@ -2010,14 +2010,14 @@ void AmsWebServer::realtimeJson() { offset = rtp->getSize(); } - uint16_t pos = snprintf_P(buf, BufferSize, PSTR("{\"offset\":%d,\"size\":%d,\"total\":%d,\"data\":["), offset, size, rtp->getSize()); + uint16_t pos = snprintf_P(buf, BUF_SIZE_COMMON, PSTR("{\"offset\":%d,\"size\":%d,\"total\":%d,\"data\":["), offset, size, rtp->getSize()); bool first = true; for(uint16_t i = 0; i < size; i++) { - pos += snprintf_P(buf+pos, BufferSize-pos, PSTR("%s%d"), first ? "" : ",", rtp->getValue(offset+i)); + pos += snprintf_P(buf+pos, BUF_SIZE_COMMON-pos, PSTR("%s%d"), first ? "" : ",", rtp->getValue(offset+i)); first = false; delay(1); } - pos += snprintf_P(buf+pos, BufferSize-pos, PSTR("]}")); + pos += snprintf_P(buf+pos, BUF_SIZE_COMMON-pos, PSTR("]}")); server.send(200, MIME_JSON, buf); } @@ -2050,59 +2050,59 @@ void AmsWebServer::configFileDownload() { server.setContentLength(CONTENT_LENGTH_UNKNOWN); server.send_P(200, MIME_PLAIN, PSTR("amsconfig\n")); - server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("version %s\n"), FirmwareVersion::VersionString)); - server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("boardType %d\n"), sys.boardType)); + server.sendContent(buf, snprintf_P(buf, BUF_SIZE_COMMON, PSTR("version %s\n"), FirmwareVersion::VersionString)); + server.sendContent(buf, snprintf_P(buf, BUF_SIZE_COMMON, PSTR("boardType %d\n"), sys.boardType)); if(includeWifi) { NetworkConfig network; config->getNetworkConfig(network); - server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("netmode %d\n"), network.mode)); - server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("hostname %s\n"), network.hostname)); - if(includeSecrets) server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("ssid %s\n"), network.ssid)); - if(includeSecrets) server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("psk %s\n"), network.psk)); + server.sendContent(buf, snprintf_P(buf, BUF_SIZE_COMMON, PSTR("netmode %d\n"), network.mode)); + server.sendContent(buf, snprintf_P(buf, BUF_SIZE_COMMON, PSTR("hostname %s\n"), network.hostname)); + if(includeSecrets) server.sendContent(buf, snprintf_P(buf, BUF_SIZE_COMMON, PSTR("ssid %s\n"), network.ssid)); + if(includeSecrets) server.sendContent(buf, snprintf_P(buf, BUF_SIZE_COMMON, PSTR("psk %s\n"), network.psk)); if(strlen(network.ip) > 0) { - server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("ip %s\n"), network.ip)); - if(strlen(network.gateway) > 0) server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("gateway %s\n"), network.gateway)); - if(strlen(network.subnet) > 0) server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("subnet %s\n"), network.subnet)); - if(strlen(network.dns1) > 0) server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("dns1 %s\n"), network.dns1)); - if(strlen(network.dns2) > 0) server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("dns2 %s\n"), network.dns2)); + server.sendContent(buf, snprintf_P(buf, BUF_SIZE_COMMON, PSTR("ip %s\n"), network.ip)); + if(strlen(network.gateway) > 0) server.sendContent(buf, snprintf_P(buf, BUF_SIZE_COMMON, PSTR("gateway %s\n"), network.gateway)); + if(strlen(network.subnet) > 0) server.sendContent(buf, snprintf_P(buf, BUF_SIZE_COMMON, PSTR("subnet %s\n"), network.subnet)); + if(strlen(network.dns1) > 0) server.sendContent(buf, snprintf_P(buf, BUF_SIZE_COMMON, PSTR("dns1 %s\n"), network.dns1)); + if(strlen(network.dns2) > 0) server.sendContent(buf, snprintf_P(buf, BUF_SIZE_COMMON, PSTR("dns2 %s\n"), network.dns2)); } - server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("mdns %d\n"), network.mdns ? 1 : 0)); - server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("use11b %d\n"), network.use11b ? 1 : 0)); + server.sendContent(buf, snprintf_P(buf, BUF_SIZE_COMMON, PSTR("mdns %d\n"), network.mdns ? 1 : 0)); + server.sendContent(buf, snprintf_P(buf, BUF_SIZE_COMMON, PSTR("use11b %d\n"), network.use11b ? 1 : 0)); } if(includeMqtt) { MqttConfig mqtt; config->getMqttConfig(mqtt); if(strlen(mqtt.host) > 0) { - server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("mqttHost %s\n"), mqtt.host)); - if(mqtt.port > 0) server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("mqttPort %d\n"), mqtt.port)); - if(strlen(mqtt.clientId) > 0) server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("mqttClientId %s\n"), mqtt.clientId)); - if(strlen(mqtt.publishTopic) > 0) server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("mqttPublishTopic %s\n"), mqtt.publishTopic)); - if(strlen(mqtt.subscribeTopic) > 0) server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("mqttSubscribeTopic %s\n"), mqtt.subscribeTopic)); - if(includeSecrets) server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("mqttUsername %s\n"), mqtt.username)); - if(includeSecrets) server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("mqttPassword %s\n"), mqtt.password)); - server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("mqttPayloadFormat %d\n"), mqtt.payloadFormat)); - server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("mqttSsl %d\n"), mqtt.ssl ? 1 : 0)); + server.sendContent(buf, snprintf_P(buf, BUF_SIZE_COMMON, PSTR("mqttHost %s\n"), mqtt.host)); + if(mqtt.port > 0) server.sendContent(buf, snprintf_P(buf, BUF_SIZE_COMMON, PSTR("mqttPort %d\n"), mqtt.port)); + if(strlen(mqtt.clientId) > 0) server.sendContent(buf, snprintf_P(buf, BUF_SIZE_COMMON, PSTR("mqttClientId %s\n"), mqtt.clientId)); + if(strlen(mqtt.publishTopic) > 0) server.sendContent(buf, snprintf_P(buf, BUF_SIZE_COMMON, PSTR("mqttPublishTopic %s\n"), mqtt.publishTopic)); + if(strlen(mqtt.subscribeTopic) > 0) server.sendContent(buf, snprintf_P(buf, BUF_SIZE_COMMON, PSTR("mqttSubscribeTopic %s\n"), mqtt.subscribeTopic)); + if(includeSecrets) server.sendContent(buf, snprintf_P(buf, BUF_SIZE_COMMON, PSTR("mqttUsername %s\n"), mqtt.username)); + if(includeSecrets) server.sendContent(buf, snprintf_P(buf, BUF_SIZE_COMMON, PSTR("mqttPassword %s\n"), mqtt.password)); + server.sendContent(buf, snprintf_P(buf, BUF_SIZE_COMMON, PSTR("mqttPayloadFormat %d\n"), mqtt.payloadFormat)); + server.sendContent(buf, snprintf_P(buf, BUF_SIZE_COMMON, PSTR("mqttSsl %d\n"), mqtt.ssl ? 1 : 0)); - if(mqtt.timeout > 0) server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("mqttTimeout %d\n"), mqtt.timeout)); - if(mqtt.keepalive > 0) server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("mqttKeepalive %d\n"), mqtt.keepalive)); - if(mqtt.rebootMinutes > 0) server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("mqttRebootMinutes %d\n"), mqtt.rebootMinutes)); + if(mqtt.timeout > 0) server.sendContent(buf, snprintf_P(buf, BUF_SIZE_COMMON, PSTR("mqttTimeout %d\n"), mqtt.timeout)); + if(mqtt.keepalive > 0) server.sendContent(buf, snprintf_P(buf, BUF_SIZE_COMMON, PSTR("mqttKeepalive %d\n"), mqtt.keepalive)); + if(mqtt.rebootMinutes > 0) server.sendContent(buf, snprintf_P(buf, BUF_SIZE_COMMON, PSTR("mqttRebootMinutes %d\n"), mqtt.rebootMinutes)); if(mqtt.payloadFormat == 3) { DomoticzConfig domo; config->getDomoticzConfig(domo); - server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("domoticzElidx %d\n"), domo.elidx)); - server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("domoticzVl1idx %d\n"), domo.vl1idx)); - server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("domoticzVl2idx %d\n"), domo.vl2idx)); - server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("domoticzVl3idx %d\n"), domo.vl3idx)); - server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("domoticzCl1idx %d\n"), domo.cl1idx)); + server.sendContent(buf, snprintf_P(buf, BUF_SIZE_COMMON, PSTR("domoticzElidx %d\n"), domo.elidx)); + server.sendContent(buf, snprintf_P(buf, BUF_SIZE_COMMON, PSTR("domoticzVl1idx %d\n"), domo.vl1idx)); + server.sendContent(buf, snprintf_P(buf, BUF_SIZE_COMMON, PSTR("domoticzVl2idx %d\n"), domo.vl2idx)); + server.sendContent(buf, snprintf_P(buf, BUF_SIZE_COMMON, PSTR("domoticzVl3idx %d\n"), domo.vl3idx)); + server.sendContent(buf, snprintf_P(buf, BUF_SIZE_COMMON, PSTR("domoticzCl1idx %d\n"), domo.cl1idx)); } else if(mqtt.payloadFormat == 4) { HomeAssistantConfig haconf; config->getHomeAssistantConfig(haconf); - server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("homeAssistantDiscoveryPrefix %s\n"), haconf.discoveryPrefix)); - server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("homeAssistantDiscoveryHostname %s\n"), haconf.discoveryHostname)); - server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("homeAssistantDiscoveryNameTag %s\n"), haconf.discoveryNameTag)); + server.sendContent(buf, snprintf_P(buf, BUF_SIZE_COMMON, PSTR("homeAssistantDiscoveryPrefix %s\n"), haconf.discoveryPrefix)); + server.sendContent(buf, snprintf_P(buf, BUF_SIZE_COMMON, PSTR("homeAssistantDiscoveryHostname %s\n"), haconf.discoveryHostname)); + server.sendContent(buf, snprintf_P(buf, BUF_SIZE_COMMON, PSTR("homeAssistantDiscoveryNameTag %s\n"), haconf.discoveryNameTag)); } } } @@ -2110,17 +2110,17 @@ void AmsWebServer::configFileDownload() { if(includeWeb && includeSecrets) { WebConfig web; config->getWebConfig(web); - server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("webSecurity %d\n"), web.security)); + server.sendContent(buf, snprintf_P(buf, BUF_SIZE_COMMON, PSTR("webSecurity %d\n"), web.security)); if(web.security > 0) { - server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("webUsername %s\n"), web.username)); - server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("webPassword %s\n"), web.password)); + server.sendContent(buf, snprintf_P(buf, BUF_SIZE_COMMON, PSTR("webUsername %s\n"), web.username)); + server.sendContent(buf, snprintf_P(buf, BUF_SIZE_COMMON, PSTR("webPassword %s\n"), web.password)); } } if(includeMeter) { MeterConfig meter; config->getMeterConfig(meter); - server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("meterBaud %d\n"), meter.baud)); + server.sendContent(buf, snprintf_P(buf, BUF_SIZE_COMMON, PSTR("meterBaud %d\n"), meter.baud)); char parity[4] = ""; switch(meter.parity) { case 2: @@ -2139,23 +2139,23 @@ void AmsWebServer::configFileDownload() { strcpy_P(parity, PSTR("8E1")); break; } - if(strlen(parity) > 0) server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("meterParity %s\n"), parity)); - server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("meterInvert %d\n"), meter.invert ? 1 : 0)); - server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("meterDistributionSystem %d\n"), meter.distributionSystem)); - server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("meterMainFuse %d\n"), meter.mainFuse)); - server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("meterProductionCapacity %d\n"), meter.productionCapacity)); + if(strlen(parity) > 0) server.sendContent(buf, snprintf_P(buf, BUF_SIZE_COMMON, PSTR("meterParity %s\n"), parity)); + server.sendContent(buf, snprintf_P(buf, BUF_SIZE_COMMON, PSTR("meterInvert %d\n"), meter.invert ? 1 : 0)); + server.sendContent(buf, snprintf_P(buf, BUF_SIZE_COMMON, PSTR("meterDistributionSystem %d\n"), meter.distributionSystem)); + server.sendContent(buf, snprintf_P(buf, BUF_SIZE_COMMON, PSTR("meterMainFuse %d\n"), meter.mainFuse)); + server.sendContent(buf, snprintf_P(buf, BUF_SIZE_COMMON, PSTR("meterProductionCapacity %d\n"), meter.productionCapacity)); if(includeSecrets) { - if(meter.encryptionKey[0] != 0x00) server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("meterEncryptionKey %s\n"), toHex(meter.encryptionKey, 16).c_str())); - if(meter.authenticationKey[0] != 0x00) server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("meterAuthenticationKey %s\n"), toHex(meter.authenticationKey, 16).c_str())); + if(meter.encryptionKey[0] != 0x00) server.sendContent(buf, snprintf_P(buf, BUF_SIZE_COMMON, PSTR("meterEncryptionKey %s\n"), toHex(meter.encryptionKey, 16).c_str())); + if(meter.authenticationKey[0] != 0x00) server.sendContent(buf, snprintf_P(buf, BUF_SIZE_COMMON, PSTR("meterAuthenticationKey %s\n"), toHex(meter.authenticationKey, 16).c_str())); } if(meter.wattageMultiplier != 1.0 && meter.wattageMultiplier != 0.0) - server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("meterWattageMultiplier %.3f\n"), meter.wattageMultiplier / 1000.0)); + server.sendContent(buf, snprintf_P(buf, BUF_SIZE_COMMON, PSTR("meterWattageMultiplier %.3f\n"), meter.wattageMultiplier / 1000.0)); if(meter.voltageMultiplier != 1.0 && meter.voltageMultiplier != 0.0) - server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("meterVoltageMultiplier %.3f\n"), meter.voltageMultiplier / 1000.0)); + server.sendContent(buf, snprintf_P(buf, BUF_SIZE_COMMON, PSTR("meterVoltageMultiplier %.3f\n"), meter.voltageMultiplier / 1000.0)); if(meter.amperageMultiplier != 1.0 && meter.amperageMultiplier != 0.0) - server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("meterAmperageMultiplier %.3f\n"), meter.amperageMultiplier / 1000.0)); + server.sendContent(buf, snprintf_P(buf, BUF_SIZE_COMMON, PSTR("meterAmperageMultiplier %.3f\n"), meter.amperageMultiplier / 1000.0)); if(meter.accumulatedMultiplier != 1.0 && meter.accumulatedMultiplier != 0.0) - server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("meterAccumulatedMultiplier %.3f\n"), meter.accumulatedMultiplier / 1000.0)); + server.sendContent(buf, snprintf_P(buf, BUF_SIZE_COMMON, PSTR("meterAccumulatedMultiplier %.3f\n"), meter.accumulatedMultiplier / 1000.0)); } if(includeGpio) { @@ -2163,41 +2163,41 @@ void AmsWebServer::configFileDownload() { config->getMeterConfig(meter); GpioConfig gpio; config->getGpioConfig(gpio); - if(meter.rxPin != 0xFF) server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("gpioHanPin %d\n"), meter.rxPin)); - if(meter.rxPin != 0xFF) server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("gpioHanPinPullup %d\n"), meter.rxPinPullup ? 1 : 0)); - if(gpio.apPin != 0xFF) server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("gpioApPin %d\n"), gpio.apPin)); - if(gpio.ledPin != 0xFF) server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("gpioLedPin %d\n"), gpio.ledPin)); - if(gpio.ledPin != 0xFF) server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("gpioLedInverted %d\n"), gpio.ledInverted ? 1 : 0)); - if(gpio.ledPinRed != 0xFF) server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("gpioLedPinRed %d\n"), gpio.ledPinRed)); - if(gpio.ledPinGreen != 0xFF) server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("gpioLedPinGreen %d\n"), gpio.ledPinGreen)); - if(gpio.ledPinBlue != 0xFF) server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("gpioLedPinBlue %d\n"), gpio.ledPinBlue)); - if(gpio.ledPinRed != 0xFF || gpio.ledPinGreen != 0xFF || gpio.ledPinBlue != 0xFF) server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("gpioLedRgbInverted %d\n"), gpio.ledRgbInverted ? 1 : 0)); - if(gpio.tempSensorPin != 0xFF) server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("gpioTempSensorPin %d\n"), gpio.tempSensorPin)); - if(gpio.tempAnalogSensorPin != 0xFF) server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("gpioTempAnalogSensorPin %d\n"), gpio.tempAnalogSensorPin)); - if(gpio.vccPin != 0xFF) server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("gpioVccPin %d\n"), gpio.vccPin)); - server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("gpioVccOffset %.2f\n"), gpio.vccOffset / 100.0)); - server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("gpioVccMultiplier %.3f\n"), gpio.vccMultiplier / 1000.0)); - server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("gpioVccBootLimit %.1f\n"), gpio.vccBootLimit / 10.0)); - if(gpio.vccPin != 0xFF && gpio.vccResistorGnd != 0) server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("gpioVccResistorGnd %d\n"), gpio.vccResistorGnd)); - if(gpio.vccPin != 0xFF && gpio.vccResistorVcc != 0) server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("gpioVccResistorVcc %d\n"), gpio.vccResistorVcc)); + if(meter.rxPin != 0xFF) server.sendContent(buf, snprintf_P(buf, BUF_SIZE_COMMON, PSTR("gpioHanPin %d\n"), meter.rxPin)); + if(meter.rxPin != 0xFF) server.sendContent(buf, snprintf_P(buf, BUF_SIZE_COMMON, PSTR("gpioHanPinPullup %d\n"), meter.rxPinPullup ? 1 : 0)); + if(gpio.apPin != 0xFF) server.sendContent(buf, snprintf_P(buf, BUF_SIZE_COMMON, PSTR("gpioApPin %d\n"), gpio.apPin)); + if(gpio.ledPin != 0xFF) server.sendContent(buf, snprintf_P(buf, BUF_SIZE_COMMON, PSTR("gpioLedPin %d\n"), gpio.ledPin)); + if(gpio.ledPin != 0xFF) server.sendContent(buf, snprintf_P(buf, BUF_SIZE_COMMON, PSTR("gpioLedInverted %d\n"), gpio.ledInverted ? 1 : 0)); + if(gpio.ledPinRed != 0xFF) server.sendContent(buf, snprintf_P(buf, BUF_SIZE_COMMON, PSTR("gpioLedPinRed %d\n"), gpio.ledPinRed)); + if(gpio.ledPinGreen != 0xFF) server.sendContent(buf, snprintf_P(buf, BUF_SIZE_COMMON, PSTR("gpioLedPinGreen %d\n"), gpio.ledPinGreen)); + if(gpio.ledPinBlue != 0xFF) server.sendContent(buf, snprintf_P(buf, BUF_SIZE_COMMON, PSTR("gpioLedPinBlue %d\n"), gpio.ledPinBlue)); + if(gpio.ledPinRed != 0xFF || gpio.ledPinGreen != 0xFF || gpio.ledPinBlue != 0xFF) server.sendContent(buf, snprintf_P(buf, BUF_SIZE_COMMON, PSTR("gpioLedRgbInverted %d\n"), gpio.ledRgbInverted ? 1 : 0)); + if(gpio.tempSensorPin != 0xFF) server.sendContent(buf, snprintf_P(buf, BUF_SIZE_COMMON, PSTR("gpioTempSensorPin %d\n"), gpio.tempSensorPin)); + if(gpio.tempAnalogSensorPin != 0xFF) server.sendContent(buf, snprintf_P(buf, BUF_SIZE_COMMON, PSTR("gpioTempAnalogSensorPin %d\n"), gpio.tempAnalogSensorPin)); + if(gpio.vccPin != 0xFF) server.sendContent(buf, snprintf_P(buf, BUF_SIZE_COMMON, PSTR("gpioVccPin %d\n"), gpio.vccPin)); + server.sendContent(buf, snprintf_P(buf, BUF_SIZE_COMMON, PSTR("gpioVccOffset %.2f\n"), gpio.vccOffset / 100.0)); + server.sendContent(buf, snprintf_P(buf, BUF_SIZE_COMMON, PSTR("gpioVccMultiplier %.3f\n"), gpio.vccMultiplier / 1000.0)); + server.sendContent(buf, snprintf_P(buf, BUF_SIZE_COMMON, PSTR("gpioVccBootLimit %.1f\n"), gpio.vccBootLimit / 10.0)); + if(gpio.vccPin != 0xFF && gpio.vccResistorGnd != 0) server.sendContent(buf, snprintf_P(buf, BUF_SIZE_COMMON, PSTR("gpioVccResistorGnd %d\n"), gpio.vccResistorGnd)); + if(gpio.vccPin != 0xFF && gpio.vccResistorVcc != 0) server.sendContent(buf, snprintf_P(buf, BUF_SIZE_COMMON, PSTR("gpioVccResistorVcc %d\n"), gpio.vccResistorVcc)); } if(includeNtp) { NtpConfig ntp; config->getNtpConfig(ntp); - server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("ntpEnable %d\n"), ntp.enable ? 1 : 0)); - server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("ntpDhcp %d\n"), ntp.dhcp ? 1 : 0)); - server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("ntpTimezone %s\n"), ntp.timezone)); - server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("ntpServer %s\n"), ntp.server)); + server.sendContent(buf, snprintf_P(buf, BUF_SIZE_COMMON, PSTR("ntpEnable %d\n"), ntp.enable ? 1 : 0)); + server.sendContent(buf, snprintf_P(buf, BUF_SIZE_COMMON, PSTR("ntpDhcp %d\n"), ntp.dhcp ? 1 : 0)); + server.sendContent(buf, snprintf_P(buf, BUF_SIZE_COMMON, PSTR("ntpTimezone %s\n"), ntp.timezone)); + server.sendContent(buf, snprintf_P(buf, BUF_SIZE_COMMON, PSTR("ntpServer %s\n"), ntp.server)); } if(includePrice) { PriceServiceConfig price; config->getPriceServiceConfig(price); - server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("priceEnabled %d\n"), price.enabled ? 1 : 0)); - if(strlen(price.entsoeToken) == 36 && includeSecrets) server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("priceEntsoeToken %s\n"), price.entsoeToken)); - server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("priceArea %s\n"), price.area)); - server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("priceCurrency %s\n"), price.currency)); + server.sendContent(buf, snprintf_P(buf, BUF_SIZE_COMMON, PSTR("priceEnabled %d\n"), price.enabled ? 1 : 0)); + if(strlen(price.entsoeToken) == 36 && includeSecrets) server.sendContent(buf, snprintf_P(buf, BUF_SIZE_COMMON, PSTR("priceEntsoeToken %s\n"), price.entsoeToken)); + server.sendContent(buf, snprintf_P(buf, BUF_SIZE_COMMON, PSTR("priceArea %s\n"), price.area)); + server.sendContent(buf, snprintf_P(buf, BUF_SIZE_COMMON, PSTR("priceCurrency %s\n"), price.currency)); if(ps != NULL) { uint8_t i = 0; std::vector pc = ps->getPriceConfig(); @@ -2263,7 +2263,7 @@ void AmsWebServer::configFileDownload() { if(strlen(hours) > 0) hours[strlen(hours)-1] = '\0'; } - server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("priceModifier %i \"%s\" %s %s %.4f %s %s %02d-%02d %02d-%02d\n"), + server.sendContent(buf, snprintf_P(buf, BUF_SIZE_COMMON, PSTR("priceModifier %i \"%s\" %s %s %.4f %s %s %02d-%02d %02d-%02d\n"), i, p.name, direction, @@ -2285,7 +2285,7 @@ void AmsWebServer::configFileDownload() { EnergyAccountingConfig eac; config->getEnergyAccountingConfig(eac); - if(eac.thresholds[9] > 0) server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("thresholds %d %d %d %d %d %d %d %d %d %d %d\n"), + if(eac.thresholds[9] > 0) server.sendContent(buf, snprintf_P(buf, BUF_SIZE_COMMON, PSTR("thresholds %d %d %d %d %d %d %d %d %d %d %d\n"), eac.thresholds[0], eac.thresholds[1], eac.thresholds[2], @@ -2303,7 +2303,7 @@ void AmsWebServer::configFileDownload() { if(ds != NULL) { DayDataPoints day = ds->getDayData(); - server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("dayplot %d %lu %.3f %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d"), + server.sendContent(buf, snprintf_P(buf, BUF_SIZE_COMMON, PSTR("dayplot %d %lu %.3f %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d"), day.version, (int32_t) day.lastMeterReadTime, day.activeImport / 1000.0, @@ -2334,7 +2334,7 @@ void AmsWebServer::configFileDownload() { ds->getHourImport(23) )); if(day.activeExport > 0) { - server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR(" %.3f %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n"), + server.sendContent(buf, snprintf_P(buf, BUF_SIZE_COMMON, PSTR(" %.3f %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n"), day.activeExport / 1000.0, ds->getHourExport(0), ds->getHourExport(1), @@ -2366,7 +2366,7 @@ void AmsWebServer::configFileDownload() { } MonthDataPoints month = ds->getMonthData(); - server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("monthplot %d %lu %.3f %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d"), + server.sendContent(buf, snprintf_P(buf, BUF_SIZE_COMMON, PSTR("monthplot %d %lu %.3f %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d"), month.version, (int32_t) month.lastMeterReadTime, month.activeImport / 1000.0, @@ -2404,7 +2404,7 @@ void AmsWebServer::configFileDownload() { ds->getDayImport(31) )); if(month.activeExport > 0) { - server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR(" %.3f %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n"), + server.sendContent(buf, snprintf_P(buf, BUF_SIZE_COMMON, PSTR(" %.3f %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n"), month.activeExport / 1000.0, ds->getDayExport(1), ds->getDayExport(2), @@ -2447,7 +2447,7 @@ void AmsWebServer::configFileDownload() { EnergyAccountingConfig eac; config->getEnergyAccountingConfig(eac); EnergyAccountingData ead = ea->getData(); - server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("energyaccounting %d %d %.2f %.2f %.2f %.2f %.2f %.2f %d %d %.2f %d %d %.2f %d %d %.2f %d %d %.2f %d %d %.2f %.2f %.2f"), + server.sendContent(buf, snprintf_P(buf, BUF_SIZE_COMMON, PSTR("energyaccounting %d %d %.2f %.2f %.2f %.2f %.2f %.2f %d %d %.2f %d %d %.2f %d %d %.2f %d %d %.2f %d %d %.2f %.2f %.2f"), ead.version, ead.month, ea->getCostYesterday(), @@ -2479,7 +2479,7 @@ void AmsWebServer::configFileDownload() { } void AmsWebServer::configFilePost() { - snprintf_P(buf, BufferSize, RESPONSE_JSON, + snprintf_P(buf, BUF_SIZE_COMMON, RESPONSE_JSON, "true", "", performRestart ? "true" : "false" @@ -2495,7 +2495,7 @@ void AmsWebServer::configFileUpload() { HTTPUpload& upload = uploadFile(FILE_CFG); if(upload.status == UPLOAD_FILE_END) { performRestart = true; - snprintf_P(buf, BufferSize, RESPONSE_JSON, + snprintf_P(buf, BUF_SIZE_COMMON, RESPONSE_JSON, "true", "", performRestart ? "true" : "false" @@ -2529,18 +2529,18 @@ void AmsWebServer::modifyDayPlot() { return; for(uint8_t i = 0; i < 24; i++) { - snprintf_P(buf, BufferSize, PSTR("i%02d"), i); + snprintf_P(buf, BUF_SIZE_COMMON, PSTR("i%02d"), i); if(server.hasArg(buf)) { ds->setHourImport(i, server.arg(buf).toDouble() * 1000); } - snprintf_P(buf, BufferSize, PSTR("e%02d"), i); + snprintf_P(buf, BUF_SIZE_COMMON, PSTR("e%02d"), i); if(server.hasArg(buf)) { ds->setHourExport(i, server.arg(buf).toDouble() * 1000); } } bool ret = ds->save(); - snprintf_P(buf, BufferSize, RESPONSE_JSON, + snprintf_P(buf, BUF_SIZE_COMMON, RESPONSE_JSON, "true", "", ret ? "true" : "false" @@ -2554,18 +2554,18 @@ void AmsWebServer::modifyMonthPlot() { return; for(uint8_t i = 1; i <= 31; i++) { - snprintf_P(buf, BufferSize, PSTR("i%02d"), i); + snprintf_P(buf, BUF_SIZE_COMMON, PSTR("i%02d"), i); if(server.hasArg(buf)) { ds->setDayImport(i, server.arg(buf).toDouble() * 1000); } - snprintf_P(buf, BufferSize, PSTR("e%02d"), i); + snprintf_P(buf, BUF_SIZE_COMMON, PSTR("e%02d"), i); if(server.hasArg(buf)) { ds->setDayExport(i, server.arg(buf).toDouble() * 1000); } } bool ret = ds->save(); - snprintf_P(buf, BufferSize, RESPONSE_JSON, + snprintf_P(buf, BUF_SIZE_COMMON, RESPONSE_JSON, "true", "", ret ? "true" : "false" @@ -2637,7 +2637,7 @@ void AmsWebServer::wifiScan() { return; int16_t count = WiFi.scanNetworks(); - int pos = snprintf_P(buf, BufferSize, PSTR("{\"c\":%d,\"n\":["), count); + int pos = snprintf_P(buf, BUF_SIZE_COMMON, PSTR("{\"c\":%d,\"n\":["), count); count = min(count, (int16_t) 25); // Max 25 so that we don't overflow the buffer size for (int16_t i = 0; i < count; i++) { uint8_t* bssid = WiFi.BSSID(i); @@ -2673,9 +2673,9 @@ void AmsWebServer::wifiScan() { char bssidStr[18] = { 0 }; sprintf(bssidStr, "%02X:%02X:%02X:%02X:%02X:%02X", bssid[0], bssid[1], bssid[2], bssid[3], bssid[4], bssid[5]); - pos += snprintf_P(buf+pos, BufferSize-pos, PSTR("{\"b\":\"%s\",\"s\":\"%s\",\"r\":%d,\"c\":%d,\"e\":\"%s\"}%s"), bssidStr, ssid.c_str(), rssi, chan, encStr, i == count-1 ? "" : ","); + pos += snprintf_P(buf+pos, BUF_SIZE_COMMON-pos, PSTR("{\"b\":\"%s\",\"s\":\"%s\",\"r\":%d,\"c\":%d,\"e\":\"%s\"}%s"), bssidStr, ssid.c_str(), rssi, chan, encStr, i == count-1 ? "" : ","); } - pos += snprintf_P(buf+pos, BufferSize-pos, PSTR("]}")); + pos += snprintf_P(buf+pos, BUF_SIZE_COMMON-pos, PSTR("]}")); WiFi.scanDelete(); server.sendHeader(HEADER_CACHE_CONTROL, CACHE_CONTROL_NO_CACHE); diff --git a/src/AmsToMqttBridge.cpp b/src/AmsToMqttBridge.cpp index 3f73900c..d83c53b2 100644 --- a/src/AmsToMqttBridge.cpp +++ b/src/AmsToMqttBridge.cpp @@ -115,8 +115,6 @@ RemoteDebug Debug; HardwareSerial Debug = Serial; #endif -#define BUF_SIZE_COMMON (2048) - #include "Timezones.h" #include "AmsFirmwareUpdater.h" @@ -1852,8 +1850,8 @@ void configFileParse() { size_t size; char* buf = (char*) commonBuffer; - memset(buf, 0, 1024); - while((size = file.readBytesUntil('\n', buf, 1024)) > 0) { + memset(buf, 0, BUF_SIZE_COMMON); + while((size = file.readBytesUntil('\n', buf, BUF_SIZE_COMMON)) > 0) { for(uint16_t i = 0; i < size; i++) { if(buf[i] < 32 || buf[i] > 126) { memset(buf+i, 0, size-i);