diff --git a/include/Configuration.h b/include/Configuration.h index bb0e478f2..e13b558aa 100644 --- a/include/Configuration.h +++ b/include/Configuration.h @@ -30,8 +30,6 @@ #define DEV_MAX_MAPPING_NAME_STRLEN 63 -#define JSON_BUFFER_SIZE 12288 - struct CHANNEL_CONFIG_T { uint16_t MaxChannelPower; char Name[CHAN_MAX_NAME_STRLEN]; diff --git a/include/MqttHandleHass.h b/include/MqttHandleHass.h index feb867435..a76cb0c7b 100644 --- a/include/MqttHandleHass.h +++ b/include/MqttHandleHass.h @@ -66,10 +66,10 @@ class MqttHandleHassClass { void publishInverterNumber(std::shared_ptr inv, const char* caption, const char* icon, const char* category, const char* commandTopic, const char* stateTopic, const char* unitOfMeasure, const int16_t min = 1, const int16_t max = 100); void publishInverterBinarySensor(std::shared_ptr inv, const char* caption, const char* subTopic, const char* payload_on, const char* payload_off); - static void createInverterInfo(DynamicJsonDocument& doc, std::shared_ptr inv); - static void createDtuInfo(DynamicJsonDocument& doc); + static void createInverterInfo(JsonDocument& doc, std::shared_ptr inv); + static void createDtuInfo(JsonDocument& doc); - static void createDeviceInfo(DynamicJsonDocument& doc, const String& name, const String& identifiers, const String& configuration_url, const String& manufacturer, const String& model, const String& sw_version, const String& via_device = ""); + static void createDeviceInfo(JsonDocument& doc, const String& name, const String& identifiers, const String& configuration_url, const String& manufacturer, const String& model, const String& sw_version, const String& via_device = ""); static String getDtuUniqueId(); static String getDtuUrl(); diff --git a/include/Utils.h b/include/Utils.h index fddc2ab97..f81e73180 100644 --- a/include/Utils.h +++ b/include/Utils.h @@ -10,6 +10,6 @@ class Utils { static uint64_t generateDtuSerial(); static int getTimezoneOffset(); static void restartDtu(); - static bool checkJsonAlloc(const DynamicJsonDocument& doc, const char* function, const uint16_t line); + static bool checkJsonAlloc(const JsonDocument& doc, const char* function, const uint16_t line); static void removeAllFiles(); }; diff --git a/include/WebApi.h b/include/WebApi.h index 5e5af5278..b4c499833 100644 --- a/include/WebApi.h +++ b/include/WebApi.h @@ -38,7 +38,7 @@ class WebApiClass { static void writeConfig(JsonVariant& retMsg, const WebApiError code = WebApiError::GenericSuccess, const String& message = "Settings saved!"); - static bool parseRequestData(AsyncWebServerRequest* request, AsyncJsonResponse* response, DynamicJsonDocument& json_document, size_t max_document_size = 1024); + static bool parseRequestData(AsyncWebServerRequest* request, AsyncJsonResponse* response, JsonDocument& json_document); private: AsyncWebServer _server; diff --git a/include/WebApi_errors.h b/include/WebApi_errors.h index efb890c5c..675419d72 100644 --- a/include/WebApi_errors.h +++ b/include/WebApi_errors.h @@ -5,7 +5,7 @@ enum WebApiError { GenericBase = 1000, GenericSuccess, GenericNoValueFound, - GenericDataTooLarge, + GenericDataTooLarge, // not used anymore GenericParseError, GenericValueMissing, GenericWriteFailed, diff --git a/include/WebApi_mqtt.h b/include/WebApi_mqtt.h index b259752b1..6e428249e 100644 --- a/include/WebApi_mqtt.h +++ b/include/WebApi_mqtt.h @@ -4,8 +4,6 @@ #include #include -#define MQTT_JSON_DOC_SIZE 10240 - class WebApiMqttClass { public: void init(AsyncWebServer& server, Scheduler& scheduler); diff --git a/platformio.ini b/platformio.ini index 06e663c27..2eef6f078 100644 --- a/platformio.ini +++ b/platformio.ini @@ -38,7 +38,7 @@ build_unflags = lib_deps = mathieucarbou/ESP Async WebServer @ 2.9.0 - bblanchon/ArduinoJson @ ^6.21.5 + bblanchon/ArduinoJson @ ^7.0.4 https://github.com/bertmelis/espMqttClient.git#v1.6.0 nrf24/RF24 @ ^1.4.8 olikraus/U8g2 @ ^2.35.15 diff --git a/src/Configuration.cpp b/src/Configuration.cpp index 3b189187c..8e8030745 100644 --- a/src/Configuration.cpp +++ b/src/Configuration.cpp @@ -25,17 +25,13 @@ bool ConfigurationClass::write() } config.Cfg.SaveCount++; - DynamicJsonDocument doc(JSON_BUFFER_SIZE); + JsonDocument doc; - if (!Utils::checkJsonAlloc(doc, __FUNCTION__, __LINE__)) { - return false; - } - - JsonObject cfg = doc.createNestedObject("cfg"); + JsonObject cfg = doc["cfg"].to(); cfg["version"] = config.Cfg.Version; cfg["save_count"] = config.Cfg.SaveCount; - JsonObject wifi = doc.createNestedObject("wifi"); + JsonObject wifi = doc["wifi"].to(); wifi["ssid"] = config.WiFi.Ssid; wifi["password"] = config.WiFi.Password; wifi["ip"] = IPAddress(config.WiFi.Ip).toString(); @@ -47,10 +43,10 @@ bool ConfigurationClass::write() wifi["hostname"] = config.WiFi.Hostname; wifi["aptimeout"] = config.WiFi.ApTimeout; - JsonObject mdns = doc.createNestedObject("mdns"); + JsonObject mdns = doc["mdns"].to(); mdns["enabled"] = config.Mdns.Enabled; - JsonObject ntp = doc.createNestedObject("ntp"); + JsonObject ntp = doc["ntp"].to(); ntp["server"] = config.Ntp.Server; ntp["timezone"] = config.Ntp.Timezone; ntp["timezone_descr"] = config.Ntp.TimezoneDescr; @@ -58,7 +54,7 @@ bool ConfigurationClass::write() ntp["longitude"] = config.Ntp.Longitude; ntp["sunsettype"] = config.Ntp.SunsetType; - JsonObject mqtt = doc.createNestedObject("mqtt"); + JsonObject mqtt = doc["mqtt"].to(); mqtt["enabled"] = config.Mqtt.Enabled; mqtt["hostname"] = config.Mqtt.Hostname; mqtt["port"] = config.Mqtt.Port; @@ -69,27 +65,27 @@ bool ConfigurationClass::write() mqtt["publish_interval"] = config.Mqtt.PublishInterval; mqtt["clean_session"] = config.Mqtt.CleanSession; - JsonObject mqtt_lwt = mqtt.createNestedObject("lwt"); + JsonObject mqtt_lwt = mqtt["lwt"].to(); mqtt_lwt["topic"] = config.Mqtt.Lwt.Topic; mqtt_lwt["value_online"] = config.Mqtt.Lwt.Value_Online; mqtt_lwt["value_offline"] = config.Mqtt.Lwt.Value_Offline; mqtt_lwt["qos"] = config.Mqtt.Lwt.Qos; - JsonObject mqtt_tls = mqtt.createNestedObject("tls"); + JsonObject mqtt_tls = mqtt["tls"].to(); mqtt_tls["enabled"] = config.Mqtt.Tls.Enabled; mqtt_tls["root_ca_cert"] = config.Mqtt.Tls.RootCaCert; mqtt_tls["certlogin"] = config.Mqtt.Tls.CertLogin; mqtt_tls["client_cert"] = config.Mqtt.Tls.ClientCert; mqtt_tls["client_key"] = config.Mqtt.Tls.ClientKey; - JsonObject mqtt_hass = mqtt.createNestedObject("hass"); + JsonObject mqtt_hass = mqtt["hass"].to(); mqtt_hass["enabled"] = config.Mqtt.Hass.Enabled; mqtt_hass["retain"] = config.Mqtt.Hass.Retain; mqtt_hass["topic"] = config.Mqtt.Hass.Topic; mqtt_hass["individual_panels"] = config.Mqtt.Hass.IndividualPanels; mqtt_hass["expire"] = config.Mqtt.Hass.Expire; - JsonObject dtu = doc.createNestedObject("dtu"); + JsonObject dtu = doc["dtu"].to(); dtu["serial"] = config.Dtu.Serial; dtu["poll_interval"] = config.Dtu.PollInterval; dtu["nrf_pa_level"] = config.Dtu.Nrf.PaLevel; @@ -97,14 +93,14 @@ bool ConfigurationClass::write() dtu["cmt_frequency"] = config.Dtu.Cmt.Frequency; dtu["cmt_country_mode"] = config.Dtu.Cmt.CountryMode; - JsonObject security = doc.createNestedObject("security"); + JsonObject security = doc["security"].to(); security["password"] = config.Security.Password; security["allow_readonly"] = config.Security.AllowReadonly; - JsonObject device = doc.createNestedObject("device"); + JsonObject device = doc["device"].to(); device["pinmapping"] = config.Dev_PinMapping; - JsonObject display = device.createNestedObject("display"); + JsonObject display = device["display"].to(); display["powersafe"] = config.Display.PowerSafe; display["screensaver"] = config.Display.ScreenSaver; display["rotation"] = config.Display.Rotation; @@ -113,15 +109,15 @@ bool ConfigurationClass::write() display["diagram_duration"] = config.Display.Diagram.Duration; display["diagram_mode"] = config.Display.Diagram.Mode; - JsonArray leds = device.createNestedArray("led"); + JsonArray leds = device["led"].to(); for (uint8_t i = 0; i < PINMAPPING_LED_COUNT; i++) { - JsonObject led = leds.createNestedObject(); + JsonObject led = leds.add(); led["brightness"] = config.Led_Single[i].Brightness; } - JsonArray inverters = doc.createNestedArray("inverters"); + JsonArray inverters = doc["inverters"].to(); for (uint8_t i = 0; i < INV_MAX_COUNT; i++) { - JsonObject inv = inverters.createNestedObject(); + JsonObject inv = inverters.add(); inv["serial"] = config.Inverter[i].Serial; inv["name"] = config.Inverter[i].Name; inv["order"] = config.Inverter[i].Order; @@ -134,15 +130,19 @@ bool ConfigurationClass::write() inv["zero_day"] = config.Inverter[i].ZeroYieldDayOnMidnight; inv["yieldday_correction"] = config.Inverter[i].YieldDayCorrection; - JsonArray channel = inv.createNestedArray("channel"); + JsonArray channel = inv["channel"].to(); for (uint8_t c = 0; c < INV_MAX_CHAN_COUNT; c++) { - JsonObject chanData = channel.createNestedObject(); + JsonObject chanData = channel.add(); chanData["name"] = config.Inverter[i].channel[c].Name; chanData["max_power"] = config.Inverter[i].channel[c].MaxChannelPower; chanData["yield_total_offset"] = config.Inverter[i].channel[c].YieldTotalOffset; } } + if (!Utils::checkJsonAlloc(doc, __FUNCTION__, __LINE__)) { + return false; + } + // Serialize JSON to file if (serializeJson(doc, f) == 0) { MessageOutput.println("Failed to write file"); @@ -157,11 +157,7 @@ bool ConfigurationClass::read() { File f = LittleFS.open(CONFIG_FILENAME, "r", false); - DynamicJsonDocument doc(JSON_BUFFER_SIZE); - - if (!Utils::checkJsonAlloc(doc, __FUNCTION__, __LINE__)) { - return false; - } + JsonDocument doc; // Deserialize the JSON document const DeserializationError error = deserializeJson(doc, f); @@ -169,6 +165,10 @@ bool ConfigurationClass::read() MessageOutput.println("Failed to read file, using default configuration"); } + if (!Utils::checkJsonAlloc(doc, __FUNCTION__, __LINE__)) { + return false; + } + JsonObject cfg = doc["cfg"]; config.Cfg.Version = cfg["version"] | CONFIG_VERSION; config.Cfg.SaveCount = cfg["save_count"] | 0; @@ -324,11 +324,7 @@ void ConfigurationClass::migrate() return; } - DynamicJsonDocument doc(JSON_BUFFER_SIZE); - - if (!Utils::checkJsonAlloc(doc, __FUNCTION__, __LINE__)) { - return; - } + JsonDocument doc; // Deserialize the JSON document const DeserializationError error = deserializeJson(doc, f); @@ -337,6 +333,10 @@ void ConfigurationClass::migrate() return; } + if (!Utils::checkJsonAlloc(doc, __FUNCTION__, __LINE__)) { + return; + } + if (config.Cfg.Version < 0x00011700) { JsonArray inverters = doc["inverters"]; for (uint8_t i = 0; i < INV_MAX_COUNT; i++) { diff --git a/src/MqttHandleHass.cpp b/src/MqttHandleHass.cpp index 21ff0fa2b..a2d998d10 100644 --- a/src/MqttHandleHass.cpp +++ b/src/MqttHandleHass.cpp @@ -137,10 +137,7 @@ void MqttHandleHassClass::publishInverterField(std::shared_ptr name = "CH" + chanNum + " " + fieldName; } - DynamicJsonDocument root(1024); - if (!Utils::checkJsonAlloc(root, __FUNCTION__, __LINE__)) { - return; - } + JsonDocument root; root["name"] = name; root["stat_t"] = stateTopic; @@ -163,6 +160,10 @@ void MqttHandleHassClass::publishInverterField(std::shared_ptr root["stat_cla"] = stateCls; } + if (!Utils::checkJsonAlloc(root, __FUNCTION__, __LINE__)) { + return; + } + String buffer; serializeJson(root, buffer); publish(configTopic, buffer); @@ -185,10 +186,7 @@ void MqttHandleHassClass::publishInverterButton(std::shared_ptr inv) +void MqttHandleHassClass::createInverterInfo(JsonDocument& root, std::shared_ptr inv) { createDeviceInfo( root, @@ -378,7 +384,7 @@ void MqttHandleHassClass::createInverterInfo(DynamicJsonDocument& root, std::sha getDtuUniqueId()); } -void MqttHandleHassClass::createDtuInfo(DynamicJsonDocument& root) +void MqttHandleHassClass::createDtuInfo(JsonDocument& root) { createDeviceInfo( root, @@ -391,12 +397,12 @@ void MqttHandleHassClass::createDtuInfo(DynamicJsonDocument& root) } void MqttHandleHassClass::createDeviceInfo( - DynamicJsonDocument& root, + JsonDocument& root, const String& name, const String& identifiers, const String& configuration_url, const String& manufacturer, const String& model, const String& sw_version, const String& via_device) { - auto object = root.createNestedObject("dev"); + auto object = root["dev"].to(); object["name"] = name; object["ids"] = identifiers; diff --git a/src/PinMapping.cpp b/src/PinMapping.cpp index 8d7062b01..74f282855 100644 --- a/src/PinMapping.cpp +++ b/src/PinMapping.cpp @@ -8,8 +8,6 @@ #include #include -#define JSON_BUFFER_SIZE 6144 - #ifndef DISPLAY_TYPE #define DISPLAY_TYPE 0U #endif @@ -141,7 +139,7 @@ bool PinMappingClass::init(const String& deviceMapping) return false; } - DynamicJsonDocument doc(JSON_BUFFER_SIZE); + JsonDocument doc; // Deserialize the JSON document DeserializationError error = deserializeJson(doc, f); if (error) { @@ -216,4 +214,4 @@ bool PinMappingClass::isValidCmt2300Config() const bool PinMappingClass::isValidEthConfig() const { return _pinMapping.eth_enabled; -} \ No newline at end of file +} diff --git a/src/Utils.cpp b/src/Utils.cpp index 7ad072938..6bedd2cbd 100644 --- a/src/Utils.cpp +++ b/src/Utils.cpp @@ -69,9 +69,9 @@ void Utils::restartDtu() ESP.restart(); } -bool Utils::checkJsonAlloc(const DynamicJsonDocument& doc, const char* function, const uint16_t line) +bool Utils::checkJsonAlloc(const JsonDocument& doc, const char* function, const uint16_t line) { - if (doc.capacity() == 0) { + if (doc.overflowed()) { MessageOutput.printf("Alloc failed: %s, %d\r\n", function, line); return false; } diff --git a/src/WebApi.cpp b/src/WebApi.cpp index 10f3e28d9..04821d7e1 100644 --- a/src/WebApi.cpp +++ b/src/WebApi.cpp @@ -85,7 +85,7 @@ void WebApiClass::writeConfig(JsonVariant& retMsg, const WebApiError code, const } } -bool WebApiClass::parseRequestData(AsyncWebServerRequest* request, AsyncJsonResponse* response, DynamicJsonDocument& json_document, size_t max_document_size) +bool WebApiClass::parseRequestData(AsyncWebServerRequest* request, AsyncJsonResponse* response, JsonDocument& json_document) { auto& retMsg = response->getRoot(); retMsg["type"] = "warning"; @@ -99,14 +99,6 @@ bool WebApiClass::parseRequestData(AsyncWebServerRequest* request, AsyncJsonResp } const String json = request->getParam("data", true)->value(); - if (json.length() > max_document_size) { - retMsg["message"] = "Data too large!"; - retMsg["code"] = WebApiError::GenericDataTooLarge; - response->setLength(); - request->send(response); - return false; - } - const DeserializationError error = deserializeJson(json_document, json); if (error) { retMsg["message"] = "Failed to parse data!"; diff --git a/src/WebApi_config.cpp b/src/WebApi_config.cpp index f76a2e0ad..99a539edc 100644 --- a/src/WebApi_config.cpp +++ b/src/WebApi_config.cpp @@ -53,7 +53,7 @@ void WebApiConfigClass::onConfigDelete(AsyncWebServerRequest* request) } AsyncJsonResponse* response = new AsyncJsonResponse(); - DynamicJsonDocument root(1024); + JsonDocument root; if (!WebApi.parseRequestData(request, response, root)) { return; } @@ -95,7 +95,7 @@ void WebApiConfigClass::onConfigListGet(AsyncWebServerRequest* request) AsyncJsonResponse* response = new AsyncJsonResponse(); auto& root = response->getRoot(); - auto data = root.createNestedArray("configs"); + auto data = root["configs"].to(); File rootfs = LittleFS.open("/"); File file = rootfs.openNextFile(); @@ -103,7 +103,7 @@ void WebApiConfigClass::onConfigListGet(AsyncWebServerRequest* request) if (file.isDirectory()) { continue; } - JsonObject obj = data.createNestedObject(); + JsonObject obj = data.add(); obj["name"] = String(file.name()); file = rootfs.openNextFile(); diff --git a/src/WebApi_device.cpp b/src/WebApi_device.cpp index 1cc142207..421f9456e 100644 --- a/src/WebApi_device.cpp +++ b/src/WebApi_device.cpp @@ -26,15 +26,15 @@ void WebApiDeviceClass::onDeviceAdminGet(AsyncWebServerRequest* request) return; } - AsyncJsonResponse* response = new AsyncJsonResponse(false, MQTT_JSON_DOC_SIZE); + AsyncJsonResponse* response = new AsyncJsonResponse(); auto& root = response->getRoot(); const CONFIG_T& config = Configuration.get(); const PinMapping_t& pin = PinMapping.get(); - auto curPin = root.createNestedObject("curPin"); + auto curPin = root["curPin"].to(); curPin["name"] = config.Dev_PinMapping; - auto nrfPinObj = curPin.createNestedObject("nrf24"); + auto nrfPinObj = curPin["nrf24"].to(); nrfPinObj["clk"] = pin.nrf24_clk; nrfPinObj["cs"] = pin.nrf24_cs; nrfPinObj["en"] = pin.nrf24_en; @@ -42,7 +42,7 @@ void WebApiDeviceClass::onDeviceAdminGet(AsyncWebServerRequest* request) nrfPinObj["miso"] = pin.nrf24_miso; nrfPinObj["mosi"] = pin.nrf24_mosi; - auto cmtPinObj = curPin.createNestedObject("cmt"); + auto cmtPinObj = curPin["cmt"].to(); cmtPinObj["clk"] = pin.cmt_clk; cmtPinObj["cs"] = pin.cmt_cs; cmtPinObj["fcs"] = pin.cmt_fcs; @@ -50,7 +50,7 @@ void WebApiDeviceClass::onDeviceAdminGet(AsyncWebServerRequest* request) cmtPinObj["gpio2"] = pin.cmt_gpio2; cmtPinObj["gpio3"] = pin.cmt_gpio3; - auto ethPinObj = curPin.createNestedObject("eth"); + auto ethPinObj = curPin["eth"].to(); ethPinObj["enabled"] = pin.eth_enabled; ethPinObj["phy_addr"] = pin.eth_phy_addr; ethPinObj["power"] = pin.eth_power; @@ -59,19 +59,19 @@ void WebApiDeviceClass::onDeviceAdminGet(AsyncWebServerRequest* request) ethPinObj["type"] = pin.eth_type; ethPinObj["clk_mode"] = pin.eth_clk_mode; - auto displayPinObj = curPin.createNestedObject("display"); + auto displayPinObj = curPin["display"].to(); displayPinObj["type"] = pin.display_type; displayPinObj["data"] = pin.display_data; displayPinObj["clk"] = pin.display_clk; displayPinObj["cs"] = pin.display_cs; displayPinObj["reset"] = pin.display_reset; - auto ledPinObj = curPin.createNestedObject("led"); + auto ledPinObj = curPin["led"].to(); for (uint8_t i = 0; i < PINMAPPING_LED_COUNT; i++) { ledPinObj["led" + String(i)] = pin.led[i]; } - auto display = root.createNestedObject("display"); + auto display = root["display"].to(); display["rotation"] = config.Display.Rotation; display["power_safe"] = config.Display.PowerSafe; display["screensaver"] = config.Display.ScreenSaver; @@ -80,9 +80,9 @@ void WebApiDeviceClass::onDeviceAdminGet(AsyncWebServerRequest* request) display["diagramduration"] = config.Display.Diagram.Duration; display["diagrammode"] = config.Display.Diagram.Mode; - auto leds = root.createNestedArray("led"); + auto leds = root["led"].to(); for (uint8_t i = 0; i < PINMAPPING_LED_COUNT; i++) { - auto led = leds.createNestedObject(); + auto led = leds.add(); led["brightness"] = config.Led_Single[i].Brightness; } @@ -96,9 +96,9 @@ void WebApiDeviceClass::onDeviceAdminPost(AsyncWebServerRequest* request) return; } - AsyncJsonResponse* response = new AsyncJsonResponse(false, MQTT_JSON_DOC_SIZE); - DynamicJsonDocument root(MQTT_JSON_DOC_SIZE); - if (!WebApi.parseRequestData(request, response, root, MQTT_JSON_DOC_SIZE)) { + AsyncJsonResponse* response = new AsyncJsonResponse(); + JsonDocument root; + if (!WebApi.parseRequestData(request, response, root)) { return; } diff --git a/src/WebApi_dtu.cpp b/src/WebApi_dtu.cpp index bbcd909f1..a2192c7ce 100644 --- a/src/WebApi_dtu.cpp +++ b/src/WebApi_dtu.cpp @@ -62,10 +62,10 @@ void WebApiDtuClass::onDtuAdminGet(AsyncWebServerRequest* request) root["cmt_country"] = config.Dtu.Cmt.CountryMode; root["cmt_chan_width"] = Hoymiles.getRadioCmt()->getChannelWidth(); - auto data = root.createNestedArray("country_def"); + auto data = root["country_def"].to(); auto countryDefs = Hoymiles.getRadioCmt()->getCountryFrequencyList(); for (const auto& definition : countryDefs) { - auto obj = data.createNestedObject(); + auto obj = data.add(); obj["freq_default"] = definition.definition.Freq_Default; obj["freq_min"] = definition.definition.Freq_Min; obj["freq_max"] = definition.definition.Freq_Max; @@ -84,7 +84,7 @@ void WebApiDtuClass::onDtuAdminPost(AsyncWebServerRequest* request) } AsyncJsonResponse* response = new AsyncJsonResponse(); - DynamicJsonDocument root(1024); + JsonDocument root; if (!WebApi.parseRequestData(request, response, root)) { return; } diff --git a/src/WebApi_eventlog.cpp b/src/WebApi_eventlog.cpp index 51e85affa..3637a3d9e 100644 --- a/src/WebApi_eventlog.cpp +++ b/src/WebApi_eventlog.cpp @@ -20,7 +20,7 @@ void WebApiEventlogClass::onEventlogStatus(AsyncWebServerRequest* request) return; } - AsyncJsonResponse* response = new AsyncJsonResponse(false, 2048); + AsyncJsonResponse* response = new AsyncJsonResponse(); auto& root = response->getRoot(); uint64_t serial = 0; @@ -47,10 +47,10 @@ void WebApiEventlogClass::onEventlogStatus(AsyncWebServerRequest* request) uint8_t logEntryCount = inv->EventLog()->getEntryCount(); root["count"] = logEntryCount; - JsonArray eventsArray = root.createNestedArray("events"); + JsonArray eventsArray = root["events"].to(); for (uint8_t logEntry = 0; logEntry < logEntryCount; logEntry++) { - JsonObject eventsObject = eventsArray.createNestedObject(); + JsonObject eventsObject = eventsArray.add(); AlarmLogEntry_t entry; inv->EventLog()->getLogEntry(logEntry, entry, locale); diff --git a/src/WebApi_gridprofile.cpp b/src/WebApi_gridprofile.cpp index 60c340fa0..2527396d5 100644 --- a/src/WebApi_gridprofile.cpp +++ b/src/WebApi_gridprofile.cpp @@ -21,7 +21,7 @@ void WebApiGridProfileClass::onGridProfileStatus(AsyncWebServerRequest* request) return; } - AsyncJsonResponse* response = new AsyncJsonResponse(false, 8192); + AsyncJsonResponse* response = new AsyncJsonResponse(); auto& root = response->getRoot(); uint64_t serial = 0; @@ -36,17 +36,17 @@ void WebApiGridProfileClass::onGridProfileStatus(AsyncWebServerRequest* request) root["name"] = inv->GridProfile()->getProfileName(); root["version"] = inv->GridProfile()->getProfileVersion(); - auto jsonSections = root.createNestedArray("sections"); + auto jsonSections = root["sections"].to(); auto profSections = inv->GridProfile()->getProfile(); for (auto &profSection : profSections) { - auto jsonSection = jsonSections.createNestedObject(); + auto jsonSection = jsonSections.add(); jsonSection["name"] = profSection.SectionName; - auto jsonItems = jsonSection.createNestedArray("items"); + auto jsonItems = jsonSection["items"].to(); for (auto &profItem : profSection.items) { - auto jsonItem = jsonItems.createNestedObject(); + auto jsonItem = jsonItems.add(); jsonItem["n"] = profItem.Name; jsonItem["u"] = profItem.Unit; @@ -65,7 +65,7 @@ void WebApiGridProfileClass::onGridProfileRawdata(AsyncWebServerRequest* request return; } - AsyncJsonResponse* response = new AsyncJsonResponse(false, 4096); + AsyncJsonResponse* response = new AsyncJsonResponse(); auto& root = response->getRoot(); uint64_t serial = 0; @@ -77,7 +77,7 @@ void WebApiGridProfileClass::onGridProfileRawdata(AsyncWebServerRequest* request auto inv = Hoymiles.getInverterBySerial(serial); if (inv != nullptr) { - auto raw = root.createNestedArray("raw"); + auto raw = root["raw"].to(); auto data = inv->GridProfile()->getRawData(); copyArray(&data[0], data.size(), raw); diff --git a/src/WebApi_inverter.cpp b/src/WebApi_inverter.cpp index eb48c8efa..0d82a3264 100644 --- a/src/WebApi_inverter.cpp +++ b/src/WebApi_inverter.cpp @@ -29,15 +29,15 @@ void WebApiInverterClass::onInverterList(AsyncWebServerRequest* request) return; } - AsyncJsonResponse* response = new AsyncJsonResponse(false, 768 * INV_MAX_COUNT); + AsyncJsonResponse* response = new AsyncJsonResponse(); auto& root = response->getRoot(); - JsonArray data = root.createNestedArray("inverter"); + JsonArray data = root["inverter"].to(); const CONFIG_T& config = Configuration.get(); for (uint8_t i = 0; i < INV_MAX_COUNT; i++) { if (config.Inverter[i].Serial > 0) { - JsonObject obj = data.createNestedObject(); + JsonObject obj = data.add(); obj["id"] = i; obj["name"] = String(config.Inverter[i].Name); obj["order"] = config.Inverter[i].Order; @@ -67,9 +67,9 @@ void WebApiInverterClass::onInverterList(AsyncWebServerRequest* request) max_channels = inv->Statistics()->getChannelsByType(TYPE_DC).size(); } - JsonArray channel = obj.createNestedArray("channel"); + JsonArray channel = obj["channel"].to(); for (uint8_t c = 0; c < max_channels; c++) { - JsonObject chanData = channel.createNestedObject(); + JsonObject chanData = channel.add(); chanData["name"] = config.Inverter[i].channel[c].Name; chanData["max_power"] = config.Inverter[i].channel[c].MaxChannelPower; chanData["yield_total_offset"] = config.Inverter[i].channel[c].YieldTotalOffset; @@ -88,7 +88,7 @@ void WebApiInverterClass::onInverterAdd(AsyncWebServerRequest* request) } AsyncJsonResponse* response = new AsyncJsonResponse(); - DynamicJsonDocument root(1024); + JsonDocument root; if (!WebApi.parseRequestData(request, response, root)) { return; } @@ -163,7 +163,7 @@ void WebApiInverterClass::onInverterEdit(AsyncWebServerRequest* request) } AsyncJsonResponse* response = new AsyncJsonResponse(); - DynamicJsonDocument root(1024); + JsonDocument root; if (!WebApi.parseRequestData(request, response, root)) { return; } @@ -283,7 +283,7 @@ void WebApiInverterClass::onInverterDelete(AsyncWebServerRequest* request) } AsyncJsonResponse* response = new AsyncJsonResponse(); - DynamicJsonDocument root(1024); + JsonDocument root; if (!WebApi.parseRequestData(request, response, root)) { return; } @@ -328,7 +328,7 @@ void WebApiInverterClass::onInverterOrder(AsyncWebServerRequest* request) } AsyncJsonResponse* response = new AsyncJsonResponse(); - DynamicJsonDocument root(1024); + JsonDocument root; if (!WebApi.parseRequestData(request, response, root)) { return; } diff --git a/src/WebApi_limit.cpp b/src/WebApi_limit.cpp index 890589267..79d6039fc 100644 --- a/src/WebApi_limit.cpp +++ b/src/WebApi_limit.cpp @@ -58,7 +58,7 @@ void WebApiLimitClass::onLimitPost(AsyncWebServerRequest* request) } AsyncJsonResponse* response = new AsyncJsonResponse(); - DynamicJsonDocument root(1024); + JsonDocument root; if (!WebApi.parseRequestData(request, response, root)) { return; } diff --git a/src/WebApi_maintenance.cpp b/src/WebApi_maintenance.cpp index 538f087ab..a7eeb4240 100644 --- a/src/WebApi_maintenance.cpp +++ b/src/WebApi_maintenance.cpp @@ -22,9 +22,9 @@ void WebApiMaintenanceClass::onRebootPost(AsyncWebServerRequest* request) return; } - AsyncJsonResponse* response = new AsyncJsonResponse(false, MQTT_JSON_DOC_SIZE); - DynamicJsonDocument root(MQTT_JSON_DOC_SIZE); - if (!WebApi.parseRequestData(request, response, root, MQTT_JSON_DOC_SIZE)) { + AsyncJsonResponse* response = new AsyncJsonResponse(); + JsonDocument root; + if (!WebApi.parseRequestData(request, response, root)) { return; } diff --git a/src/WebApi_mqtt.cpp b/src/WebApi_mqtt.cpp index 78fed2046..88c2a4ab2 100644 --- a/src/WebApi_mqtt.cpp +++ b/src/WebApi_mqtt.cpp @@ -26,7 +26,7 @@ void WebApiMqttClass::onMqttStatus(AsyncWebServerRequest* request) return; } - AsyncJsonResponse* response = new AsyncJsonResponse(false, MQTT_JSON_DOC_SIZE); + AsyncJsonResponse* response = new AsyncJsonResponse(); auto& root = response->getRoot(); const CONFIG_T& config = Configuration.get(); @@ -60,7 +60,7 @@ void WebApiMqttClass::onMqttAdminGet(AsyncWebServerRequest* request) return; } - AsyncJsonResponse* response = new AsyncJsonResponse(false, MQTT_JSON_DOC_SIZE); + AsyncJsonResponse* response = new AsyncJsonResponse(); auto& root = response->getRoot(); const CONFIG_T& config = Configuration.get(); @@ -98,9 +98,9 @@ void WebApiMqttClass::onMqttAdminPost(AsyncWebServerRequest* request) return; } - AsyncJsonResponse* response = new AsyncJsonResponse(false, MQTT_JSON_DOC_SIZE); - DynamicJsonDocument root(MQTT_JSON_DOC_SIZE); - if (!WebApi.parseRequestData(request, response, root, MQTT_JSON_DOC_SIZE)) { + AsyncJsonResponse* response = new AsyncJsonResponse(); + JsonDocument root; + if (!WebApi.parseRequestData(request, response, root)) { return; } diff --git a/src/WebApi_network.cpp b/src/WebApi_network.cpp index b7fbbe518..158c8bde9 100644 --- a/src/WebApi_network.cpp +++ b/src/WebApi_network.cpp @@ -83,7 +83,7 @@ void WebApiNetworkClass::onNetworkAdminPost(AsyncWebServerRequest* request) } AsyncJsonResponse* response = new AsyncJsonResponse(); - DynamicJsonDocument root(1024); + JsonDocument root; if (!WebApi.parseRequestData(request, response, root)) { return; } diff --git a/src/WebApi_ntp.cpp b/src/WebApi_ntp.cpp index 343d94b5a..07553921d 100644 --- a/src/WebApi_ntp.cpp +++ b/src/WebApi_ntp.cpp @@ -95,7 +95,7 @@ void WebApiNtpClass::onNtpAdminPost(AsyncWebServerRequest* request) } AsyncJsonResponse* response = new AsyncJsonResponse(); - DynamicJsonDocument root(1024); + JsonDocument root; if (!WebApi.parseRequestData(request, response, root)) { return; } @@ -194,7 +194,7 @@ void WebApiNtpClass::onNtpTimePost(AsyncWebServerRequest* request) } AsyncJsonResponse* response = new AsyncJsonResponse(); - DynamicJsonDocument root(1024); + JsonDocument root; if (!WebApi.parseRequestData(request, response, root)) { return; } diff --git a/src/WebApi_power.cpp b/src/WebApi_power.cpp index 2f921d74d..f019ce334 100644 --- a/src/WebApi_power.cpp +++ b/src/WebApi_power.cpp @@ -51,7 +51,7 @@ void WebApiPowerClass::onPowerPost(AsyncWebServerRequest* request) } AsyncJsonResponse* response = new AsyncJsonResponse(); - DynamicJsonDocument root(1024); + JsonDocument root; if (!WebApi.parseRequestData(request, response, root)) { return; } diff --git a/src/WebApi_security.cpp b/src/WebApi_security.cpp index 05f829c55..78eaffe0b 100644 --- a/src/WebApi_security.cpp +++ b/src/WebApi_security.cpp @@ -42,7 +42,7 @@ void WebApiSecurityClass::onSecurityPost(AsyncWebServerRequest* request) } AsyncJsonResponse* response = new AsyncJsonResponse(); - DynamicJsonDocument root(1024); + JsonDocument root; if (!WebApi.parseRequestData(request, response, root)) { return; } diff --git a/src/WebApi_ws_live.cpp b/src/WebApi_ws_live.cpp index 354ed3728..f378e3ab1 100644 --- a/src/WebApi_ws_live.cpp +++ b/src/WebApi_ws_live.cpp @@ -73,19 +73,20 @@ void WebApiWsLiveClass::sendDataTaskCb() try { std::lock_guard lock(_mutex); - DynamicJsonDocument root(4096); - if (!Utils::checkJsonAlloc(root, __FUNCTION__, __LINE__)) { - continue; - } + JsonDocument root; JsonVariant var = root; - auto invArray = var.createNestedArray("inverters"); - auto invObject = invArray.createNestedObject(); + auto invArray = var["inverters"].to(); + auto invObject = invArray.add(); generateCommonJsonResponse(var); generateInverterCommonJsonResponse(invObject, inv); generateInverterChannelJsonResponse(invObject, inv); + if (!Utils::checkJsonAlloc(root, __FUNCTION__, __LINE__)) { + continue; + } + String buffer; serializeJson(root, buffer); @@ -101,12 +102,12 @@ void WebApiWsLiveClass::sendDataTaskCb() void WebApiWsLiveClass::generateCommonJsonResponse(JsonVariant& root) { - JsonObject totalObj = root.createNestedObject("total"); + auto totalObj = root["total"].to(); addTotalField(totalObj, "Power", Datastore.getTotalAcPowerEnabled(), "W", Datastore.getTotalAcPowerDigits()); addTotalField(totalObj, "YieldDay", Datastore.getTotalAcYieldDayEnabled(), "Wh", Datastore.getTotalAcYieldDayDigits()); addTotalField(totalObj, "YieldTotal", Datastore.getTotalAcYieldTotalEnabled(), "kWh", Datastore.getTotalAcYieldTotalDigits()); - JsonObject hintObj = root.createNestedObject("hints"); + JsonObject hintObj = root["hints"].to(); struct tm timeinfo; hintObj["time_sync"] = !getLocalTime(&timeinfo, 5); hintObj["radio_problem"] = (Hoymiles.getRadioNrf()->isInitialized() && (!Hoymiles.getRadioNrf()->isConnected() || !Hoymiles.getRadioNrf()->isPVariant())) || (Hoymiles.getRadioCmt()->isInitialized() && (!Hoymiles.getRadioCmt()->isConnected())); @@ -144,7 +145,7 @@ void WebApiWsLiveClass::generateInverterChannelJsonResponse(JsonObject& root, st // Loop all channels for (auto& t : inv->Statistics()->getChannelTypes()) { - JsonObject chanTypeObj = root.createNestedObject(inv->Statistics()->getChannelTypeName(t)); + auto chanTypeObj = root[inv->Statistics()->getChannelTypeName(t)].to(); for (auto& c : inv->Statistics()->getChannelsByType(t)) { if (t == TYPE_DC) { chanTypeObj[String(static_cast(c))]["name"]["u"] = inv_cfg->channel[c].Name; @@ -221,10 +222,10 @@ void WebApiWsLiveClass::onLivedataStatus(AsyncWebServerRequest* request) try { std::lock_guard lock(_mutex); - AsyncJsonResponse* response = new AsyncJsonResponse(false, 4096); + AsyncJsonResponse* response = new AsyncJsonResponse(); auto& root = response->getRoot(); - JsonArray invArray = root.createNestedArray("inverters"); + auto invArray = root["inverters"].to(); uint64_t serial = 0; if (request->hasParam("inv")) { @@ -235,7 +236,7 @@ void WebApiWsLiveClass::onLivedataStatus(AsyncWebServerRequest* request) if (serial > 0) { auto inv = Hoymiles.getInverterBySerial(serial); if (inv != nullptr) { - JsonObject invObject = invArray.createNestedObject(); + JsonObject invObject = invArray.add(); generateInverterCommonJsonResponse(invObject, inv); generateInverterChannelJsonResponse(invObject, inv); } @@ -247,13 +248,17 @@ void WebApiWsLiveClass::onLivedataStatus(AsyncWebServerRequest* request) continue; } - JsonObject invObject = invArray.createNestedObject(); + JsonObject invObject = invArray.add(); generateInverterCommonJsonResponse(invObject, inv); } } generateCommonJsonResponse(root); + if (!Utils::checkJsonAlloc(root, __FUNCTION__, __LINE__)) { + return; + } + response->setLength(); request->send(response);