Feature: Migrated ArduinoJson 6 to 7

This commit is contained in:
Thomas Basler 2024-04-02 23:23:12 +02:00
parent e7a9c96b72
commit 2e3125fe8d
26 changed files with 149 additions and 152 deletions

View File

@ -30,8 +30,6 @@
#define DEV_MAX_MAPPING_NAME_STRLEN 63 #define DEV_MAX_MAPPING_NAME_STRLEN 63
#define JSON_BUFFER_SIZE 12288
struct CHANNEL_CONFIG_T { struct CHANNEL_CONFIG_T {
uint16_t MaxChannelPower; uint16_t MaxChannelPower;
char Name[CHAN_MAX_NAME_STRLEN]; char Name[CHAN_MAX_NAME_STRLEN];

View File

@ -66,10 +66,10 @@ private:
void publishInverterNumber(std::shared_ptr<InverterAbstract> 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 publishInverterNumber(std::shared_ptr<InverterAbstract> 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<InverterAbstract> inv, const char* caption, const char* subTopic, const char* payload_on, const char* payload_off); void publishInverterBinarySensor(std::shared_ptr<InverterAbstract> inv, const char* caption, const char* subTopic, const char* payload_on, const char* payload_off);
static void createInverterInfo(DynamicJsonDocument& doc, std::shared_ptr<InverterAbstract> inv); static void createInverterInfo(JsonDocument& doc, std::shared_ptr<InverterAbstract> inv);
static void createDtuInfo(DynamicJsonDocument& doc); 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 getDtuUniqueId();
static String getDtuUrl(); static String getDtuUrl();

View File

@ -10,6 +10,6 @@ public:
static uint64_t generateDtuSerial(); static uint64_t generateDtuSerial();
static int getTimezoneOffset(); static int getTimezoneOffset();
static void restartDtu(); 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(); static void removeAllFiles();
}; };

View File

@ -38,7 +38,7 @@ public:
static void writeConfig(JsonVariant& retMsg, const WebApiError code = WebApiError::GenericSuccess, const String& message = "Settings saved!"); 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: private:
AsyncWebServer _server; AsyncWebServer _server;

View File

@ -5,7 +5,7 @@ enum WebApiError {
GenericBase = 1000, GenericBase = 1000,
GenericSuccess, GenericSuccess,
GenericNoValueFound, GenericNoValueFound,
GenericDataTooLarge, GenericDataTooLarge, // not used anymore
GenericParseError, GenericParseError,
GenericValueMissing, GenericValueMissing,
GenericWriteFailed, GenericWriteFailed,

View File

@ -4,8 +4,6 @@
#include <ESPAsyncWebServer.h> #include <ESPAsyncWebServer.h>
#include <TaskSchedulerDeclarations.h> #include <TaskSchedulerDeclarations.h>
#define MQTT_JSON_DOC_SIZE 10240
class WebApiMqttClass { class WebApiMqttClass {
public: public:
void init(AsyncWebServer& server, Scheduler& scheduler); void init(AsyncWebServer& server, Scheduler& scheduler);

View File

@ -38,7 +38,7 @@ build_unflags =
lib_deps = lib_deps =
mathieucarbou/ESP Async WebServer @ 2.9.0 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 https://github.com/bertmelis/espMqttClient.git#v1.6.0
nrf24/RF24 @ ^1.4.8 nrf24/RF24 @ ^1.4.8
olikraus/U8g2 @ ^2.35.15 olikraus/U8g2 @ ^2.35.15

View File

@ -25,17 +25,13 @@ bool ConfigurationClass::write()
} }
config.Cfg.SaveCount++; config.Cfg.SaveCount++;
DynamicJsonDocument doc(JSON_BUFFER_SIZE); JsonDocument doc;
if (!Utils::checkJsonAlloc(doc, __FUNCTION__, __LINE__)) { JsonObject cfg = doc["cfg"].to<JsonObject>();
return false;
}
JsonObject cfg = doc.createNestedObject("cfg");
cfg["version"] = config.Cfg.Version; cfg["version"] = config.Cfg.Version;
cfg["save_count"] = config.Cfg.SaveCount; cfg["save_count"] = config.Cfg.SaveCount;
JsonObject wifi = doc.createNestedObject("wifi"); JsonObject wifi = doc["wifi"].to<JsonObject>();
wifi["ssid"] = config.WiFi.Ssid; wifi["ssid"] = config.WiFi.Ssid;
wifi["password"] = config.WiFi.Password; wifi["password"] = config.WiFi.Password;
wifi["ip"] = IPAddress(config.WiFi.Ip).toString(); wifi["ip"] = IPAddress(config.WiFi.Ip).toString();
@ -47,10 +43,10 @@ bool ConfigurationClass::write()
wifi["hostname"] = config.WiFi.Hostname; wifi["hostname"] = config.WiFi.Hostname;
wifi["aptimeout"] = config.WiFi.ApTimeout; wifi["aptimeout"] = config.WiFi.ApTimeout;
JsonObject mdns = doc.createNestedObject("mdns"); JsonObject mdns = doc["mdns"].to<JsonObject>();
mdns["enabled"] = config.Mdns.Enabled; mdns["enabled"] = config.Mdns.Enabled;
JsonObject ntp = doc.createNestedObject("ntp"); JsonObject ntp = doc["ntp"].to<JsonObject>();
ntp["server"] = config.Ntp.Server; ntp["server"] = config.Ntp.Server;
ntp["timezone"] = config.Ntp.Timezone; ntp["timezone"] = config.Ntp.Timezone;
ntp["timezone_descr"] = config.Ntp.TimezoneDescr; ntp["timezone_descr"] = config.Ntp.TimezoneDescr;
@ -58,7 +54,7 @@ bool ConfigurationClass::write()
ntp["longitude"] = config.Ntp.Longitude; ntp["longitude"] = config.Ntp.Longitude;
ntp["sunsettype"] = config.Ntp.SunsetType; ntp["sunsettype"] = config.Ntp.SunsetType;
JsonObject mqtt = doc.createNestedObject("mqtt"); JsonObject mqtt = doc["mqtt"].to<JsonObject>();
mqtt["enabled"] = config.Mqtt.Enabled; mqtt["enabled"] = config.Mqtt.Enabled;
mqtt["hostname"] = config.Mqtt.Hostname; mqtt["hostname"] = config.Mqtt.Hostname;
mqtt["port"] = config.Mqtt.Port; mqtt["port"] = config.Mqtt.Port;
@ -69,27 +65,27 @@ bool ConfigurationClass::write()
mqtt["publish_interval"] = config.Mqtt.PublishInterval; mqtt["publish_interval"] = config.Mqtt.PublishInterval;
mqtt["clean_session"] = config.Mqtt.CleanSession; mqtt["clean_session"] = config.Mqtt.CleanSession;
JsonObject mqtt_lwt = mqtt.createNestedObject("lwt"); JsonObject mqtt_lwt = mqtt["lwt"].to<JsonObject>();
mqtt_lwt["topic"] = config.Mqtt.Lwt.Topic; mqtt_lwt["topic"] = config.Mqtt.Lwt.Topic;
mqtt_lwt["value_online"] = config.Mqtt.Lwt.Value_Online; mqtt_lwt["value_online"] = config.Mqtt.Lwt.Value_Online;
mqtt_lwt["value_offline"] = config.Mqtt.Lwt.Value_Offline; mqtt_lwt["value_offline"] = config.Mqtt.Lwt.Value_Offline;
mqtt_lwt["qos"] = config.Mqtt.Lwt.Qos; mqtt_lwt["qos"] = config.Mqtt.Lwt.Qos;
JsonObject mqtt_tls = mqtt.createNestedObject("tls"); JsonObject mqtt_tls = mqtt["tls"].to<JsonObject>();
mqtt_tls["enabled"] = config.Mqtt.Tls.Enabled; mqtt_tls["enabled"] = config.Mqtt.Tls.Enabled;
mqtt_tls["root_ca_cert"] = config.Mqtt.Tls.RootCaCert; mqtt_tls["root_ca_cert"] = config.Mqtt.Tls.RootCaCert;
mqtt_tls["certlogin"] = config.Mqtt.Tls.CertLogin; mqtt_tls["certlogin"] = config.Mqtt.Tls.CertLogin;
mqtt_tls["client_cert"] = config.Mqtt.Tls.ClientCert; mqtt_tls["client_cert"] = config.Mqtt.Tls.ClientCert;
mqtt_tls["client_key"] = config.Mqtt.Tls.ClientKey; mqtt_tls["client_key"] = config.Mqtt.Tls.ClientKey;
JsonObject mqtt_hass = mqtt.createNestedObject("hass"); JsonObject mqtt_hass = mqtt["hass"].to<JsonObject>();
mqtt_hass["enabled"] = config.Mqtt.Hass.Enabled; mqtt_hass["enabled"] = config.Mqtt.Hass.Enabled;
mqtt_hass["retain"] = config.Mqtt.Hass.Retain; mqtt_hass["retain"] = config.Mqtt.Hass.Retain;
mqtt_hass["topic"] = config.Mqtt.Hass.Topic; mqtt_hass["topic"] = config.Mqtt.Hass.Topic;
mqtt_hass["individual_panels"] = config.Mqtt.Hass.IndividualPanels; mqtt_hass["individual_panels"] = config.Mqtt.Hass.IndividualPanels;
mqtt_hass["expire"] = config.Mqtt.Hass.Expire; mqtt_hass["expire"] = config.Mqtt.Hass.Expire;
JsonObject dtu = doc.createNestedObject("dtu"); JsonObject dtu = doc["dtu"].to<JsonObject>();
dtu["serial"] = config.Dtu.Serial; dtu["serial"] = config.Dtu.Serial;
dtu["poll_interval"] = config.Dtu.PollInterval; dtu["poll_interval"] = config.Dtu.PollInterval;
dtu["nrf_pa_level"] = config.Dtu.Nrf.PaLevel; dtu["nrf_pa_level"] = config.Dtu.Nrf.PaLevel;
@ -97,14 +93,14 @@ bool ConfigurationClass::write()
dtu["cmt_frequency"] = config.Dtu.Cmt.Frequency; dtu["cmt_frequency"] = config.Dtu.Cmt.Frequency;
dtu["cmt_country_mode"] = config.Dtu.Cmt.CountryMode; dtu["cmt_country_mode"] = config.Dtu.Cmt.CountryMode;
JsonObject security = doc.createNestedObject("security"); JsonObject security = doc["security"].to<JsonObject>();
security["password"] = config.Security.Password; security["password"] = config.Security.Password;
security["allow_readonly"] = config.Security.AllowReadonly; security["allow_readonly"] = config.Security.AllowReadonly;
JsonObject device = doc.createNestedObject("device"); JsonObject device = doc["device"].to<JsonObject>();
device["pinmapping"] = config.Dev_PinMapping; device["pinmapping"] = config.Dev_PinMapping;
JsonObject display = device.createNestedObject("display"); JsonObject display = device["display"].to<JsonObject>();
display["powersafe"] = config.Display.PowerSafe; display["powersafe"] = config.Display.PowerSafe;
display["screensaver"] = config.Display.ScreenSaver; display["screensaver"] = config.Display.ScreenSaver;
display["rotation"] = config.Display.Rotation; display["rotation"] = config.Display.Rotation;
@ -113,15 +109,15 @@ bool ConfigurationClass::write()
display["diagram_duration"] = config.Display.Diagram.Duration; display["diagram_duration"] = config.Display.Diagram.Duration;
display["diagram_mode"] = config.Display.Diagram.Mode; display["diagram_mode"] = config.Display.Diagram.Mode;
JsonArray leds = device.createNestedArray("led"); JsonArray leds = device["led"].to<JsonArray>();
for (uint8_t i = 0; i < PINMAPPING_LED_COUNT; i++) { for (uint8_t i = 0; i < PINMAPPING_LED_COUNT; i++) {
JsonObject led = leds.createNestedObject(); JsonObject led = leds.add<JsonObject>();
led["brightness"] = config.Led_Single[i].Brightness; led["brightness"] = config.Led_Single[i].Brightness;
} }
JsonArray inverters = doc.createNestedArray("inverters"); JsonArray inverters = doc["inverters"].to<JsonArray>();
for (uint8_t i = 0; i < INV_MAX_COUNT; i++) { for (uint8_t i = 0; i < INV_MAX_COUNT; i++) {
JsonObject inv = inverters.createNestedObject(); JsonObject inv = inverters.add<JsonObject>();
inv["serial"] = config.Inverter[i].Serial; inv["serial"] = config.Inverter[i].Serial;
inv["name"] = config.Inverter[i].Name; inv["name"] = config.Inverter[i].Name;
inv["order"] = config.Inverter[i].Order; inv["order"] = config.Inverter[i].Order;
@ -134,15 +130,19 @@ bool ConfigurationClass::write()
inv["zero_day"] = config.Inverter[i].ZeroYieldDayOnMidnight; inv["zero_day"] = config.Inverter[i].ZeroYieldDayOnMidnight;
inv["yieldday_correction"] = config.Inverter[i].YieldDayCorrection; inv["yieldday_correction"] = config.Inverter[i].YieldDayCorrection;
JsonArray channel = inv.createNestedArray("channel"); JsonArray channel = inv["channel"].to<JsonArray>();
for (uint8_t c = 0; c < INV_MAX_CHAN_COUNT; c++) { for (uint8_t c = 0; c < INV_MAX_CHAN_COUNT; c++) {
JsonObject chanData = channel.createNestedObject(); JsonObject chanData = channel.add<JsonObject>();
chanData["name"] = config.Inverter[i].channel[c].Name; chanData["name"] = config.Inverter[i].channel[c].Name;
chanData["max_power"] = config.Inverter[i].channel[c].MaxChannelPower; chanData["max_power"] = config.Inverter[i].channel[c].MaxChannelPower;
chanData["yield_total_offset"] = config.Inverter[i].channel[c].YieldTotalOffset; chanData["yield_total_offset"] = config.Inverter[i].channel[c].YieldTotalOffset;
} }
} }
if (!Utils::checkJsonAlloc(doc, __FUNCTION__, __LINE__)) {
return false;
}
// Serialize JSON to file // Serialize JSON to file
if (serializeJson(doc, f) == 0) { if (serializeJson(doc, f) == 0) {
MessageOutput.println("Failed to write file"); MessageOutput.println("Failed to write file");
@ -157,11 +157,7 @@ bool ConfigurationClass::read()
{ {
File f = LittleFS.open(CONFIG_FILENAME, "r", false); File f = LittleFS.open(CONFIG_FILENAME, "r", false);
DynamicJsonDocument doc(JSON_BUFFER_SIZE); JsonDocument doc;
if (!Utils::checkJsonAlloc(doc, __FUNCTION__, __LINE__)) {
return false;
}
// Deserialize the JSON document // Deserialize the JSON document
const DeserializationError error = deserializeJson(doc, f); const DeserializationError error = deserializeJson(doc, f);
@ -169,6 +165,10 @@ bool ConfigurationClass::read()
MessageOutput.println("Failed to read file, using default configuration"); MessageOutput.println("Failed to read file, using default configuration");
} }
if (!Utils::checkJsonAlloc(doc, __FUNCTION__, __LINE__)) {
return false;
}
JsonObject cfg = doc["cfg"]; JsonObject cfg = doc["cfg"];
config.Cfg.Version = cfg["version"] | CONFIG_VERSION; config.Cfg.Version = cfg["version"] | CONFIG_VERSION;
config.Cfg.SaveCount = cfg["save_count"] | 0; config.Cfg.SaveCount = cfg["save_count"] | 0;
@ -324,11 +324,7 @@ void ConfigurationClass::migrate()
return; return;
} }
DynamicJsonDocument doc(JSON_BUFFER_SIZE); JsonDocument doc;
if (!Utils::checkJsonAlloc(doc, __FUNCTION__, __LINE__)) {
return;
}
// Deserialize the JSON document // Deserialize the JSON document
const DeserializationError error = deserializeJson(doc, f); const DeserializationError error = deserializeJson(doc, f);
@ -337,6 +333,10 @@ void ConfigurationClass::migrate()
return; return;
} }
if (!Utils::checkJsonAlloc(doc, __FUNCTION__, __LINE__)) {
return;
}
if (config.Cfg.Version < 0x00011700) { if (config.Cfg.Version < 0x00011700) {
JsonArray inverters = doc["inverters"]; JsonArray inverters = doc["inverters"];
for (uint8_t i = 0; i < INV_MAX_COUNT; i++) { for (uint8_t i = 0; i < INV_MAX_COUNT; i++) {

View File

@ -137,10 +137,7 @@ void MqttHandleHassClass::publishInverterField(std::shared_ptr<InverterAbstract>
name = "CH" + chanNum + " " + fieldName; name = "CH" + chanNum + " " + fieldName;
} }
DynamicJsonDocument root(1024); JsonDocument root;
if (!Utils::checkJsonAlloc(root, __FUNCTION__, __LINE__)) {
return;
}
root["name"] = name; root["name"] = name;
root["stat_t"] = stateTopic; root["stat_t"] = stateTopic;
@ -163,6 +160,10 @@ void MqttHandleHassClass::publishInverterField(std::shared_ptr<InverterAbstract>
root["stat_cla"] = stateCls; root["stat_cla"] = stateCls;
} }
if (!Utils::checkJsonAlloc(root, __FUNCTION__, __LINE__)) {
return;
}
String buffer; String buffer;
serializeJson(root, buffer); serializeJson(root, buffer);
publish(configTopic, buffer); publish(configTopic, buffer);
@ -185,10 +186,7 @@ void MqttHandleHassClass::publishInverterButton(std::shared_ptr<InverterAbstract
const String cmdTopic = MqttSettings.getPrefix() + serial + "/" + subTopic; const String cmdTopic = MqttSettings.getPrefix() + serial + "/" + subTopic;
DynamicJsonDocument root(1024); JsonDocument root;
if (!Utils::checkJsonAlloc(root, __FUNCTION__, __LINE__)) {
return;
}
root["name"] = caption; root["name"] = caption;
root["uniq_id"] = serial + "_" + buttonId; root["uniq_id"] = serial + "_" + buttonId;
@ -204,6 +202,10 @@ void MqttHandleHassClass::publishInverterButton(std::shared_ptr<InverterAbstract
createInverterInfo(root, inv); createInverterInfo(root, inv);
if (!Utils::checkJsonAlloc(root, __FUNCTION__, __LINE__)) {
return;
}
String buffer; String buffer;
serializeJson(root, buffer); serializeJson(root, buffer);
publish(configTopic, buffer); publish(configTopic, buffer);
@ -227,10 +229,7 @@ void MqttHandleHassClass::publishInverterNumber(
const String cmdTopic = MqttSettings.getPrefix() + serial + "/" + commandTopic; const String cmdTopic = MqttSettings.getPrefix() + serial + "/" + commandTopic;
const String statTopic = MqttSettings.getPrefix() + serial + "/" + stateTopic; const String statTopic = MqttSettings.getPrefix() + serial + "/" + stateTopic;
DynamicJsonDocument root(1024); JsonDocument root;
if (!Utils::checkJsonAlloc(root, __FUNCTION__, __LINE__)) {
return;
}
root["name"] = caption; root["name"] = caption;
root["uniq_id"] = serial + "_" + buttonId; root["uniq_id"] = serial + "_" + buttonId;
@ -246,6 +245,10 @@ void MqttHandleHassClass::publishInverterNumber(
createInverterInfo(root, inv); createInverterInfo(root, inv);
if (!Utils::checkJsonAlloc(root, __FUNCTION__, __LINE__)) {
return;
}
String buffer; String buffer;
serializeJson(root, buffer); serializeJson(root, buffer);
publish(configTopic, buffer); publish(configTopic, buffer);
@ -265,10 +268,7 @@ void MqttHandleHassClass::publishInverterBinarySensor(std::shared_ptr<InverterAb
const String statTopic = MqttSettings.getPrefix() + serial + "/" + subTopic; const String statTopic = MqttSettings.getPrefix() + serial + "/" + subTopic;
DynamicJsonDocument root(1024); JsonDocument root;
if (!Utils::checkJsonAlloc(root, __FUNCTION__, __LINE__)) {
return;
}
root["name"] = caption; root["name"] = caption;
root["uniq_id"] = serial + "_" + sensorId; root["uniq_id"] = serial + "_" + sensorId;
@ -278,6 +278,10 @@ void MqttHandleHassClass::publishInverterBinarySensor(std::shared_ptr<InverterAb
createInverterInfo(root, inv); createInverterInfo(root, inv);
if (!Utils::checkJsonAlloc(root, __FUNCTION__, __LINE__)) {
return;
}
String buffer; String buffer;
serializeJson(root, buffer); serializeJson(root, buffer);
publish(configTopic, buffer); publish(configTopic, buffer);
@ -293,10 +297,7 @@ void MqttHandleHassClass::publishDtuSensor(const char* name, const char* device_
topic = id; topic = id;
} }
DynamicJsonDocument root(1024); JsonDocument root;
if (!Utils::checkJsonAlloc(root, __FUNCTION__, __LINE__)) {
return;
}
root["name"] = name; root["name"] = name;
root["uniq_id"] = getDtuUniqueId() + "_" + id; root["uniq_id"] = getDtuUniqueId() + "_" + id;
@ -322,6 +323,10 @@ void MqttHandleHassClass::publishDtuSensor(const char* name, const char* device_
createDtuInfo(root); createDtuInfo(root);
if (!Utils::checkJsonAlloc(root, __FUNCTION__, __LINE__)) {
return;
}
String buffer; String buffer;
const String configTopic = "sensor/" + getDtuUniqueId() + "/" + id + "/config"; const String configTopic = "sensor/" + getDtuUniqueId() + "/" + id + "/config";
serializeJson(root, buffer); serializeJson(root, buffer);
@ -339,10 +344,7 @@ void MqttHandleHassClass::publishDtuBinarySensor(const char* name, const char* d
topic = String("dtu/") + "/" + id; topic = String("dtu/") + "/" + id;
} }
DynamicJsonDocument root(1024); JsonDocument root;
if (!Utils::checkJsonAlloc(root, __FUNCTION__, __LINE__)) {
return;
}
root["name"] = name; root["name"] = name;
root["uniq_id"] = getDtuUniqueId() + "_" + id; root["uniq_id"] = getDtuUniqueId() + "_" + id;
@ -359,13 +361,17 @@ void MqttHandleHassClass::publishDtuBinarySensor(const char* name, const char* d
createDtuInfo(root); createDtuInfo(root);
if (!Utils::checkJsonAlloc(root, __FUNCTION__, __LINE__)) {
return;
}
String buffer; String buffer;
const String configTopic = "binary_sensor/" + getDtuUniqueId() + "/" + id + "/config"; const String configTopic = "binary_sensor/" + getDtuUniqueId() + "/" + id + "/config";
serializeJson(root, buffer); serializeJson(root, buffer);
publish(configTopic, buffer); publish(configTopic, buffer);
} }
void MqttHandleHassClass::createInverterInfo(DynamicJsonDocument& root, std::shared_ptr<InverterAbstract> inv) void MqttHandleHassClass::createInverterInfo(JsonDocument& root, std::shared_ptr<InverterAbstract> inv)
{ {
createDeviceInfo( createDeviceInfo(
root, root,
@ -378,7 +384,7 @@ void MqttHandleHassClass::createInverterInfo(DynamicJsonDocument& root, std::sha
getDtuUniqueId()); getDtuUniqueId());
} }
void MqttHandleHassClass::createDtuInfo(DynamicJsonDocument& root) void MqttHandleHassClass::createDtuInfo(JsonDocument& root)
{ {
createDeviceInfo( createDeviceInfo(
root, root,
@ -391,12 +397,12 @@ void MqttHandleHassClass::createDtuInfo(DynamicJsonDocument& root)
} }
void MqttHandleHassClass::createDeviceInfo( void MqttHandleHassClass::createDeviceInfo(
DynamicJsonDocument& root, JsonDocument& root,
const String& name, const String& identifiers, const String& configuration_url, const String& name, const String& identifiers, const String& configuration_url,
const String& manufacturer, const String& model, const String& sw_version, const String& manufacturer, const String& model, const String& sw_version,
const String& via_device) const String& via_device)
{ {
auto object = root.createNestedObject("dev"); auto object = root["dev"].to<JsonObject>();
object["name"] = name; object["name"] = name;
object["ids"] = identifiers; object["ids"] = identifiers;

View File

@ -8,8 +8,6 @@
#include <LittleFS.h> #include <LittleFS.h>
#include <string.h> #include <string.h>
#define JSON_BUFFER_SIZE 6144
#ifndef DISPLAY_TYPE #ifndef DISPLAY_TYPE
#define DISPLAY_TYPE 0U #define DISPLAY_TYPE 0U
#endif #endif
@ -141,7 +139,7 @@ bool PinMappingClass::init(const String& deviceMapping)
return false; return false;
} }
DynamicJsonDocument doc(JSON_BUFFER_SIZE); JsonDocument doc;
// Deserialize the JSON document // Deserialize the JSON document
DeserializationError error = deserializeJson(doc, f); DeserializationError error = deserializeJson(doc, f);
if (error) { if (error) {
@ -216,4 +214,4 @@ bool PinMappingClass::isValidCmt2300Config() const
bool PinMappingClass::isValidEthConfig() const bool PinMappingClass::isValidEthConfig() const
{ {
return _pinMapping.eth_enabled; return _pinMapping.eth_enabled;
} }

View File

@ -69,9 +69,9 @@ void Utils::restartDtu()
ESP.restart(); 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); MessageOutput.printf("Alloc failed: %s, %d\r\n", function, line);
return false; return false;
} }

View File

@ -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(); auto& retMsg = response->getRoot();
retMsg["type"] = "warning"; retMsg["type"] = "warning";
@ -99,14 +99,6 @@ bool WebApiClass::parseRequestData(AsyncWebServerRequest* request, AsyncJsonResp
} }
const String json = request->getParam("data", true)->value(); 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); const DeserializationError error = deserializeJson(json_document, json);
if (error) { if (error) {
retMsg["message"] = "Failed to parse data!"; retMsg["message"] = "Failed to parse data!";

View File

@ -53,7 +53,7 @@ void WebApiConfigClass::onConfigDelete(AsyncWebServerRequest* request)
} }
AsyncJsonResponse* response = new AsyncJsonResponse(); AsyncJsonResponse* response = new AsyncJsonResponse();
DynamicJsonDocument root(1024); JsonDocument root;
if (!WebApi.parseRequestData(request, response, root)) { if (!WebApi.parseRequestData(request, response, root)) {
return; return;
} }
@ -95,7 +95,7 @@ void WebApiConfigClass::onConfigListGet(AsyncWebServerRequest* request)
AsyncJsonResponse* response = new AsyncJsonResponse(); AsyncJsonResponse* response = new AsyncJsonResponse();
auto& root = response->getRoot(); auto& root = response->getRoot();
auto data = root.createNestedArray("configs"); auto data = root["configs"].to<JsonArray>();
File rootfs = LittleFS.open("/"); File rootfs = LittleFS.open("/");
File file = rootfs.openNextFile(); File file = rootfs.openNextFile();
@ -103,7 +103,7 @@ void WebApiConfigClass::onConfigListGet(AsyncWebServerRequest* request)
if (file.isDirectory()) { if (file.isDirectory()) {
continue; continue;
} }
JsonObject obj = data.createNestedObject(); JsonObject obj = data.add<JsonObject>();
obj["name"] = String(file.name()); obj["name"] = String(file.name());
file = rootfs.openNextFile(); file = rootfs.openNextFile();

View File

@ -26,15 +26,15 @@ void WebApiDeviceClass::onDeviceAdminGet(AsyncWebServerRequest* request)
return; return;
} }
AsyncJsonResponse* response = new AsyncJsonResponse(false, MQTT_JSON_DOC_SIZE); AsyncJsonResponse* response = new AsyncJsonResponse();
auto& root = response->getRoot(); auto& root = response->getRoot();
const CONFIG_T& config = Configuration.get(); const CONFIG_T& config = Configuration.get();
const PinMapping_t& pin = PinMapping.get(); const PinMapping_t& pin = PinMapping.get();
auto curPin = root.createNestedObject("curPin"); auto curPin = root["curPin"].to<JsonObject>();
curPin["name"] = config.Dev_PinMapping; curPin["name"] = config.Dev_PinMapping;
auto nrfPinObj = curPin.createNestedObject("nrf24"); auto nrfPinObj = curPin["nrf24"].to<JsonObject>();
nrfPinObj["clk"] = pin.nrf24_clk; nrfPinObj["clk"] = pin.nrf24_clk;
nrfPinObj["cs"] = pin.nrf24_cs; nrfPinObj["cs"] = pin.nrf24_cs;
nrfPinObj["en"] = pin.nrf24_en; nrfPinObj["en"] = pin.nrf24_en;
@ -42,7 +42,7 @@ void WebApiDeviceClass::onDeviceAdminGet(AsyncWebServerRequest* request)
nrfPinObj["miso"] = pin.nrf24_miso; nrfPinObj["miso"] = pin.nrf24_miso;
nrfPinObj["mosi"] = pin.nrf24_mosi; nrfPinObj["mosi"] = pin.nrf24_mosi;
auto cmtPinObj = curPin.createNestedObject("cmt"); auto cmtPinObj = curPin["cmt"].to<JsonObject>();
cmtPinObj["clk"] = pin.cmt_clk; cmtPinObj["clk"] = pin.cmt_clk;
cmtPinObj["cs"] = pin.cmt_cs; cmtPinObj["cs"] = pin.cmt_cs;
cmtPinObj["fcs"] = pin.cmt_fcs; cmtPinObj["fcs"] = pin.cmt_fcs;
@ -50,7 +50,7 @@ void WebApiDeviceClass::onDeviceAdminGet(AsyncWebServerRequest* request)
cmtPinObj["gpio2"] = pin.cmt_gpio2; cmtPinObj["gpio2"] = pin.cmt_gpio2;
cmtPinObj["gpio3"] = pin.cmt_gpio3; cmtPinObj["gpio3"] = pin.cmt_gpio3;
auto ethPinObj = curPin.createNestedObject("eth"); auto ethPinObj = curPin["eth"].to<JsonObject>();
ethPinObj["enabled"] = pin.eth_enabled; ethPinObj["enabled"] = pin.eth_enabled;
ethPinObj["phy_addr"] = pin.eth_phy_addr; ethPinObj["phy_addr"] = pin.eth_phy_addr;
ethPinObj["power"] = pin.eth_power; ethPinObj["power"] = pin.eth_power;
@ -59,19 +59,19 @@ void WebApiDeviceClass::onDeviceAdminGet(AsyncWebServerRequest* request)
ethPinObj["type"] = pin.eth_type; ethPinObj["type"] = pin.eth_type;
ethPinObj["clk_mode"] = pin.eth_clk_mode; ethPinObj["clk_mode"] = pin.eth_clk_mode;
auto displayPinObj = curPin.createNestedObject("display"); auto displayPinObj = curPin["display"].to<JsonObject>();
displayPinObj["type"] = pin.display_type; displayPinObj["type"] = pin.display_type;
displayPinObj["data"] = pin.display_data; displayPinObj["data"] = pin.display_data;
displayPinObj["clk"] = pin.display_clk; displayPinObj["clk"] = pin.display_clk;
displayPinObj["cs"] = pin.display_cs; displayPinObj["cs"] = pin.display_cs;
displayPinObj["reset"] = pin.display_reset; displayPinObj["reset"] = pin.display_reset;
auto ledPinObj = curPin.createNestedObject("led"); auto ledPinObj = curPin["led"].to<JsonObject>();
for (uint8_t i = 0; i < PINMAPPING_LED_COUNT; i++) { for (uint8_t i = 0; i < PINMAPPING_LED_COUNT; i++) {
ledPinObj["led" + String(i)] = pin.led[i]; ledPinObj["led" + String(i)] = pin.led[i];
} }
auto display = root.createNestedObject("display"); auto display = root["display"].to<JsonObject>();
display["rotation"] = config.Display.Rotation; display["rotation"] = config.Display.Rotation;
display["power_safe"] = config.Display.PowerSafe; display["power_safe"] = config.Display.PowerSafe;
display["screensaver"] = config.Display.ScreenSaver; display["screensaver"] = config.Display.ScreenSaver;
@ -80,9 +80,9 @@ void WebApiDeviceClass::onDeviceAdminGet(AsyncWebServerRequest* request)
display["diagramduration"] = config.Display.Diagram.Duration; display["diagramduration"] = config.Display.Diagram.Duration;
display["diagrammode"] = config.Display.Diagram.Mode; display["diagrammode"] = config.Display.Diagram.Mode;
auto leds = root.createNestedArray("led"); auto leds = root["led"].to<JsonArray>();
for (uint8_t i = 0; i < PINMAPPING_LED_COUNT; i++) { for (uint8_t i = 0; i < PINMAPPING_LED_COUNT; i++) {
auto led = leds.createNestedObject(); auto led = leds.add<JsonObject>();
led["brightness"] = config.Led_Single[i].Brightness; led["brightness"] = config.Led_Single[i].Brightness;
} }
@ -96,9 +96,9 @@ void WebApiDeviceClass::onDeviceAdminPost(AsyncWebServerRequest* request)
return; return;
} }
AsyncJsonResponse* response = new AsyncJsonResponse(false, MQTT_JSON_DOC_SIZE); AsyncJsonResponse* response = new AsyncJsonResponse();
DynamicJsonDocument root(MQTT_JSON_DOC_SIZE); JsonDocument root;
if (!WebApi.parseRequestData(request, response, root, MQTT_JSON_DOC_SIZE)) { if (!WebApi.parseRequestData(request, response, root)) {
return; return;
} }

View File

@ -62,10 +62,10 @@ void WebApiDtuClass::onDtuAdminGet(AsyncWebServerRequest* request)
root["cmt_country"] = config.Dtu.Cmt.CountryMode; root["cmt_country"] = config.Dtu.Cmt.CountryMode;
root["cmt_chan_width"] = Hoymiles.getRadioCmt()->getChannelWidth(); root["cmt_chan_width"] = Hoymiles.getRadioCmt()->getChannelWidth();
auto data = root.createNestedArray("country_def"); auto data = root["country_def"].to<JsonArray>();
auto countryDefs = Hoymiles.getRadioCmt()->getCountryFrequencyList(); auto countryDefs = Hoymiles.getRadioCmt()->getCountryFrequencyList();
for (const auto& definition : countryDefs) { for (const auto& definition : countryDefs) {
auto obj = data.createNestedObject(); auto obj = data.add<JsonObject>();
obj["freq_default"] = definition.definition.Freq_Default; obj["freq_default"] = definition.definition.Freq_Default;
obj["freq_min"] = definition.definition.Freq_Min; obj["freq_min"] = definition.definition.Freq_Min;
obj["freq_max"] = definition.definition.Freq_Max; obj["freq_max"] = definition.definition.Freq_Max;
@ -84,7 +84,7 @@ void WebApiDtuClass::onDtuAdminPost(AsyncWebServerRequest* request)
} }
AsyncJsonResponse* response = new AsyncJsonResponse(); AsyncJsonResponse* response = new AsyncJsonResponse();
DynamicJsonDocument root(1024); JsonDocument root;
if (!WebApi.parseRequestData(request, response, root)) { if (!WebApi.parseRequestData(request, response, root)) {
return; return;
} }

View File

@ -20,7 +20,7 @@ void WebApiEventlogClass::onEventlogStatus(AsyncWebServerRequest* request)
return; return;
} }
AsyncJsonResponse* response = new AsyncJsonResponse(false, 2048); AsyncJsonResponse* response = new AsyncJsonResponse();
auto& root = response->getRoot(); auto& root = response->getRoot();
uint64_t serial = 0; uint64_t serial = 0;
@ -47,10 +47,10 @@ void WebApiEventlogClass::onEventlogStatus(AsyncWebServerRequest* request)
uint8_t logEntryCount = inv->EventLog()->getEntryCount(); uint8_t logEntryCount = inv->EventLog()->getEntryCount();
root["count"] = logEntryCount; root["count"] = logEntryCount;
JsonArray eventsArray = root.createNestedArray("events"); JsonArray eventsArray = root["events"].to<JsonArray>();
for (uint8_t logEntry = 0; logEntry < logEntryCount; logEntry++) { for (uint8_t logEntry = 0; logEntry < logEntryCount; logEntry++) {
JsonObject eventsObject = eventsArray.createNestedObject(); JsonObject eventsObject = eventsArray.add<JsonObject>();
AlarmLogEntry_t entry; AlarmLogEntry_t entry;
inv->EventLog()->getLogEntry(logEntry, entry, locale); inv->EventLog()->getLogEntry(logEntry, entry, locale);

View File

@ -21,7 +21,7 @@ void WebApiGridProfileClass::onGridProfileStatus(AsyncWebServerRequest* request)
return; return;
} }
AsyncJsonResponse* response = new AsyncJsonResponse(false, 8192); AsyncJsonResponse* response = new AsyncJsonResponse();
auto& root = response->getRoot(); auto& root = response->getRoot();
uint64_t serial = 0; uint64_t serial = 0;
@ -36,17 +36,17 @@ void WebApiGridProfileClass::onGridProfileStatus(AsyncWebServerRequest* request)
root["name"] = inv->GridProfile()->getProfileName(); root["name"] = inv->GridProfile()->getProfileName();
root["version"] = inv->GridProfile()->getProfileVersion(); root["version"] = inv->GridProfile()->getProfileVersion();
auto jsonSections = root.createNestedArray("sections"); auto jsonSections = root["sections"].to<JsonArray>();
auto profSections = inv->GridProfile()->getProfile(); auto profSections = inv->GridProfile()->getProfile();
for (auto &profSection : profSections) { for (auto &profSection : profSections) {
auto jsonSection = jsonSections.createNestedObject(); auto jsonSection = jsonSections.add<JsonObject>();
jsonSection["name"] = profSection.SectionName; jsonSection["name"] = profSection.SectionName;
auto jsonItems = jsonSection.createNestedArray("items"); auto jsonItems = jsonSection["items"].to<JsonArray>();
for (auto &profItem : profSection.items) { for (auto &profItem : profSection.items) {
auto jsonItem = jsonItems.createNestedObject(); auto jsonItem = jsonItems.add<JsonObject>();
jsonItem["n"] = profItem.Name; jsonItem["n"] = profItem.Name;
jsonItem["u"] = profItem.Unit; jsonItem["u"] = profItem.Unit;
@ -65,7 +65,7 @@ void WebApiGridProfileClass::onGridProfileRawdata(AsyncWebServerRequest* request
return; return;
} }
AsyncJsonResponse* response = new AsyncJsonResponse(false, 4096); AsyncJsonResponse* response = new AsyncJsonResponse();
auto& root = response->getRoot(); auto& root = response->getRoot();
uint64_t serial = 0; uint64_t serial = 0;
@ -77,7 +77,7 @@ void WebApiGridProfileClass::onGridProfileRawdata(AsyncWebServerRequest* request
auto inv = Hoymiles.getInverterBySerial(serial); auto inv = Hoymiles.getInverterBySerial(serial);
if (inv != nullptr) { if (inv != nullptr) {
auto raw = root.createNestedArray("raw"); auto raw = root["raw"].to<JsonArray>();
auto data = inv->GridProfile()->getRawData(); auto data = inv->GridProfile()->getRawData();
copyArray(&data[0], data.size(), raw); copyArray(&data[0], data.size(), raw);

View File

@ -29,15 +29,15 @@ void WebApiInverterClass::onInverterList(AsyncWebServerRequest* request)
return; return;
} }
AsyncJsonResponse* response = new AsyncJsonResponse(false, 768 * INV_MAX_COUNT); AsyncJsonResponse* response = new AsyncJsonResponse();
auto& root = response->getRoot(); auto& root = response->getRoot();
JsonArray data = root.createNestedArray("inverter"); JsonArray data = root["inverter"].to<JsonArray>();
const CONFIG_T& config = Configuration.get(); const CONFIG_T& config = Configuration.get();
for (uint8_t i = 0; i < INV_MAX_COUNT; i++) { for (uint8_t i = 0; i < INV_MAX_COUNT; i++) {
if (config.Inverter[i].Serial > 0) { if (config.Inverter[i].Serial > 0) {
JsonObject obj = data.createNestedObject(); JsonObject obj = data.add<JsonObject>();
obj["id"] = i; obj["id"] = i;
obj["name"] = String(config.Inverter[i].Name); obj["name"] = String(config.Inverter[i].Name);
obj["order"] = config.Inverter[i].Order; obj["order"] = config.Inverter[i].Order;
@ -67,9 +67,9 @@ void WebApiInverterClass::onInverterList(AsyncWebServerRequest* request)
max_channels = inv->Statistics()->getChannelsByType(TYPE_DC).size(); max_channels = inv->Statistics()->getChannelsByType(TYPE_DC).size();
} }
JsonArray channel = obj.createNestedArray("channel"); JsonArray channel = obj["channel"].to<JsonArray>();
for (uint8_t c = 0; c < max_channels; c++) { for (uint8_t c = 0; c < max_channels; c++) {
JsonObject chanData = channel.createNestedObject(); JsonObject chanData = channel.add<JsonObject>();
chanData["name"] = config.Inverter[i].channel[c].Name; chanData["name"] = config.Inverter[i].channel[c].Name;
chanData["max_power"] = config.Inverter[i].channel[c].MaxChannelPower; chanData["max_power"] = config.Inverter[i].channel[c].MaxChannelPower;
chanData["yield_total_offset"] = config.Inverter[i].channel[c].YieldTotalOffset; chanData["yield_total_offset"] = config.Inverter[i].channel[c].YieldTotalOffset;
@ -88,7 +88,7 @@ void WebApiInverterClass::onInverterAdd(AsyncWebServerRequest* request)
} }
AsyncJsonResponse* response = new AsyncJsonResponse(); AsyncJsonResponse* response = new AsyncJsonResponse();
DynamicJsonDocument root(1024); JsonDocument root;
if (!WebApi.parseRequestData(request, response, root)) { if (!WebApi.parseRequestData(request, response, root)) {
return; return;
} }
@ -163,7 +163,7 @@ void WebApiInverterClass::onInverterEdit(AsyncWebServerRequest* request)
} }
AsyncJsonResponse* response = new AsyncJsonResponse(); AsyncJsonResponse* response = new AsyncJsonResponse();
DynamicJsonDocument root(1024); JsonDocument root;
if (!WebApi.parseRequestData(request, response, root)) { if (!WebApi.parseRequestData(request, response, root)) {
return; return;
} }
@ -283,7 +283,7 @@ void WebApiInverterClass::onInverterDelete(AsyncWebServerRequest* request)
} }
AsyncJsonResponse* response = new AsyncJsonResponse(); AsyncJsonResponse* response = new AsyncJsonResponse();
DynamicJsonDocument root(1024); JsonDocument root;
if (!WebApi.parseRequestData(request, response, root)) { if (!WebApi.parseRequestData(request, response, root)) {
return; return;
} }
@ -328,7 +328,7 @@ void WebApiInverterClass::onInverterOrder(AsyncWebServerRequest* request)
} }
AsyncJsonResponse* response = new AsyncJsonResponse(); AsyncJsonResponse* response = new AsyncJsonResponse();
DynamicJsonDocument root(1024); JsonDocument root;
if (!WebApi.parseRequestData(request, response, root)) { if (!WebApi.parseRequestData(request, response, root)) {
return; return;
} }

View File

@ -58,7 +58,7 @@ void WebApiLimitClass::onLimitPost(AsyncWebServerRequest* request)
} }
AsyncJsonResponse* response = new AsyncJsonResponse(); AsyncJsonResponse* response = new AsyncJsonResponse();
DynamicJsonDocument root(1024); JsonDocument root;
if (!WebApi.parseRequestData(request, response, root)) { if (!WebApi.parseRequestData(request, response, root)) {
return; return;
} }

View File

@ -22,9 +22,9 @@ void WebApiMaintenanceClass::onRebootPost(AsyncWebServerRequest* request)
return; return;
} }
AsyncJsonResponse* response = new AsyncJsonResponse(false, MQTT_JSON_DOC_SIZE); AsyncJsonResponse* response = new AsyncJsonResponse();
DynamicJsonDocument root(MQTT_JSON_DOC_SIZE); JsonDocument root;
if (!WebApi.parseRequestData(request, response, root, MQTT_JSON_DOC_SIZE)) { if (!WebApi.parseRequestData(request, response, root)) {
return; return;
} }

View File

@ -26,7 +26,7 @@ void WebApiMqttClass::onMqttStatus(AsyncWebServerRequest* request)
return; return;
} }
AsyncJsonResponse* response = new AsyncJsonResponse(false, MQTT_JSON_DOC_SIZE); AsyncJsonResponse* response = new AsyncJsonResponse();
auto& root = response->getRoot(); auto& root = response->getRoot();
const CONFIG_T& config = Configuration.get(); const CONFIG_T& config = Configuration.get();
@ -60,7 +60,7 @@ void WebApiMqttClass::onMqttAdminGet(AsyncWebServerRequest* request)
return; return;
} }
AsyncJsonResponse* response = new AsyncJsonResponse(false, MQTT_JSON_DOC_SIZE); AsyncJsonResponse* response = new AsyncJsonResponse();
auto& root = response->getRoot(); auto& root = response->getRoot();
const CONFIG_T& config = Configuration.get(); const CONFIG_T& config = Configuration.get();
@ -98,9 +98,9 @@ void WebApiMqttClass::onMqttAdminPost(AsyncWebServerRequest* request)
return; return;
} }
AsyncJsonResponse* response = new AsyncJsonResponse(false, MQTT_JSON_DOC_SIZE); AsyncJsonResponse* response = new AsyncJsonResponse();
DynamicJsonDocument root(MQTT_JSON_DOC_SIZE); JsonDocument root;
if (!WebApi.parseRequestData(request, response, root, MQTT_JSON_DOC_SIZE)) { if (!WebApi.parseRequestData(request, response, root)) {
return; return;
} }

View File

@ -83,7 +83,7 @@ void WebApiNetworkClass::onNetworkAdminPost(AsyncWebServerRequest* request)
} }
AsyncJsonResponse* response = new AsyncJsonResponse(); AsyncJsonResponse* response = new AsyncJsonResponse();
DynamicJsonDocument root(1024); JsonDocument root;
if (!WebApi.parseRequestData(request, response, root)) { if (!WebApi.parseRequestData(request, response, root)) {
return; return;
} }

View File

@ -95,7 +95,7 @@ void WebApiNtpClass::onNtpAdminPost(AsyncWebServerRequest* request)
} }
AsyncJsonResponse* response = new AsyncJsonResponse(); AsyncJsonResponse* response = new AsyncJsonResponse();
DynamicJsonDocument root(1024); JsonDocument root;
if (!WebApi.parseRequestData(request, response, root)) { if (!WebApi.parseRequestData(request, response, root)) {
return; return;
} }
@ -194,7 +194,7 @@ void WebApiNtpClass::onNtpTimePost(AsyncWebServerRequest* request)
} }
AsyncJsonResponse* response = new AsyncJsonResponse(); AsyncJsonResponse* response = new AsyncJsonResponse();
DynamicJsonDocument root(1024); JsonDocument root;
if (!WebApi.parseRequestData(request, response, root)) { if (!WebApi.parseRequestData(request, response, root)) {
return; return;
} }

View File

@ -51,7 +51,7 @@ void WebApiPowerClass::onPowerPost(AsyncWebServerRequest* request)
} }
AsyncJsonResponse* response = new AsyncJsonResponse(); AsyncJsonResponse* response = new AsyncJsonResponse();
DynamicJsonDocument root(1024); JsonDocument root;
if (!WebApi.parseRequestData(request, response, root)) { if (!WebApi.parseRequestData(request, response, root)) {
return; return;
} }

View File

@ -42,7 +42,7 @@ void WebApiSecurityClass::onSecurityPost(AsyncWebServerRequest* request)
} }
AsyncJsonResponse* response = new AsyncJsonResponse(); AsyncJsonResponse* response = new AsyncJsonResponse();
DynamicJsonDocument root(1024); JsonDocument root;
if (!WebApi.parseRequestData(request, response, root)) { if (!WebApi.parseRequestData(request, response, root)) {
return; return;
} }

View File

@ -73,19 +73,20 @@ void WebApiWsLiveClass::sendDataTaskCb()
try { try {
std::lock_guard<std::mutex> lock(_mutex); std::lock_guard<std::mutex> lock(_mutex);
DynamicJsonDocument root(4096); JsonDocument root;
if (!Utils::checkJsonAlloc(root, __FUNCTION__, __LINE__)) {
continue;
}
JsonVariant var = root; JsonVariant var = root;
auto invArray = var.createNestedArray("inverters"); auto invArray = var["inverters"].to<JsonArray>();
auto invObject = invArray.createNestedObject(); auto invObject = invArray.add<JsonObject>();
generateCommonJsonResponse(var); generateCommonJsonResponse(var);
generateInverterCommonJsonResponse(invObject, inv); generateInverterCommonJsonResponse(invObject, inv);
generateInverterChannelJsonResponse(invObject, inv); generateInverterChannelJsonResponse(invObject, inv);
if (!Utils::checkJsonAlloc(root, __FUNCTION__, __LINE__)) {
continue;
}
String buffer; String buffer;
serializeJson(root, buffer); serializeJson(root, buffer);
@ -101,12 +102,12 @@ void WebApiWsLiveClass::sendDataTaskCb()
void WebApiWsLiveClass::generateCommonJsonResponse(JsonVariant& root) void WebApiWsLiveClass::generateCommonJsonResponse(JsonVariant& root)
{ {
JsonObject totalObj = root.createNestedObject("total"); auto totalObj = root["total"].to<JsonObject>();
addTotalField(totalObj, "Power", Datastore.getTotalAcPowerEnabled(), "W", Datastore.getTotalAcPowerDigits()); addTotalField(totalObj, "Power", Datastore.getTotalAcPowerEnabled(), "W", Datastore.getTotalAcPowerDigits());
addTotalField(totalObj, "YieldDay", Datastore.getTotalAcYieldDayEnabled(), "Wh", Datastore.getTotalAcYieldDayDigits()); addTotalField(totalObj, "YieldDay", Datastore.getTotalAcYieldDayEnabled(), "Wh", Datastore.getTotalAcYieldDayDigits());
addTotalField(totalObj, "YieldTotal", Datastore.getTotalAcYieldTotalEnabled(), "kWh", Datastore.getTotalAcYieldTotalDigits()); addTotalField(totalObj, "YieldTotal", Datastore.getTotalAcYieldTotalEnabled(), "kWh", Datastore.getTotalAcYieldTotalDigits());
JsonObject hintObj = root.createNestedObject("hints"); JsonObject hintObj = root["hints"].to<JsonObject>();
struct tm timeinfo; struct tm timeinfo;
hintObj["time_sync"] = !getLocalTime(&timeinfo, 5); hintObj["time_sync"] = !getLocalTime(&timeinfo, 5);
hintObj["radio_problem"] = (Hoymiles.getRadioNrf()->isInitialized() && (!Hoymiles.getRadioNrf()->isConnected() || !Hoymiles.getRadioNrf()->isPVariant())) || (Hoymiles.getRadioCmt()->isInitialized() && (!Hoymiles.getRadioCmt()->isConnected())); 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 // Loop all channels
for (auto& t : inv->Statistics()->getChannelTypes()) { for (auto& t : inv->Statistics()->getChannelTypes()) {
JsonObject chanTypeObj = root.createNestedObject(inv->Statistics()->getChannelTypeName(t)); auto chanTypeObj = root[inv->Statistics()->getChannelTypeName(t)].to<JsonObject>();
for (auto& c : inv->Statistics()->getChannelsByType(t)) { for (auto& c : inv->Statistics()->getChannelsByType(t)) {
if (t == TYPE_DC) { if (t == TYPE_DC) {
chanTypeObj[String(static_cast<uint8_t>(c))]["name"]["u"] = inv_cfg->channel[c].Name; chanTypeObj[String(static_cast<uint8_t>(c))]["name"]["u"] = inv_cfg->channel[c].Name;
@ -221,10 +222,10 @@ void WebApiWsLiveClass::onLivedataStatus(AsyncWebServerRequest* request)
try { try {
std::lock_guard<std::mutex> lock(_mutex); std::lock_guard<std::mutex> lock(_mutex);
AsyncJsonResponse* response = new AsyncJsonResponse(false, 4096); AsyncJsonResponse* response = new AsyncJsonResponse();
auto& root = response->getRoot(); auto& root = response->getRoot();
JsonArray invArray = root.createNestedArray("inverters"); auto invArray = root["inverters"].to<JsonArray>();
uint64_t serial = 0; uint64_t serial = 0;
if (request->hasParam("inv")) { if (request->hasParam("inv")) {
@ -235,7 +236,7 @@ void WebApiWsLiveClass::onLivedataStatus(AsyncWebServerRequest* request)
if (serial > 0) { if (serial > 0) {
auto inv = Hoymiles.getInverterBySerial(serial); auto inv = Hoymiles.getInverterBySerial(serial);
if (inv != nullptr) { if (inv != nullptr) {
JsonObject invObject = invArray.createNestedObject(); JsonObject invObject = invArray.add<JsonObject>();
generateInverterCommonJsonResponse(invObject, inv); generateInverterCommonJsonResponse(invObject, inv);
generateInverterChannelJsonResponse(invObject, inv); generateInverterChannelJsonResponse(invObject, inv);
} }
@ -247,13 +248,17 @@ void WebApiWsLiveClass::onLivedataStatus(AsyncWebServerRequest* request)
continue; continue;
} }
JsonObject invObject = invArray.createNestedObject(); JsonObject invObject = invArray.add<JsonObject>();
generateInverterCommonJsonResponse(invObject, inv); generateInverterCommonJsonResponse(invObject, inv);
} }
} }
generateCommonJsonResponse(root); generateCommonJsonResponse(root);
if (!Utils::checkJsonAlloc(root, __FUNCTION__, __LINE__)) {
return;
}
response->setLength(); response->setLength();
request->send(response); request->send(response);