-
Notifications
You must be signed in to change notification settings - Fork 307
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Migrate to ArduinoJson version 6 #622
Conversation
mkfrey
commented
Aug 25, 2019
- Migrate the code from ArduinoJson v5 to v6
- Resolve memory allocation issues resulting from the migration
- Reduce unnecessary copying of some JSON related strings
- Change to StaticJsonBuffer if possible
Would it be possible to integrate some sort of #606 in this PR? |
@MajorTwip I will make sure to include it in the pull request for the JSON optimization changes. |
src/Homie/Boot/BootConfig.cpp
Outdated
JsonObject& parsedJson = parseJsonBuffer.parseObject(body); | ||
if (!parsedJson.success()) { | ||
StaticJsonDocument<JSON_OBJECT_SIZE(2)> parseJsonDoc; | ||
char* body = (char*)(request->_tempObject); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are reusing the _tempObject
as buffer in the JsonDocument. It might be better to use an AsyncCallbackJsonWebHandler
instead of an AsyncWebServerRequest
. This is only a suggestion for further optimization.
https://github.com/me-no-dev/ESPAsyncWebServer#json-body-handling-with-arduinojson
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for your suggestion. I didn't know that ESPAsyncWebServer had this feature.
I took a look at the implementation, but ESPAsyncWebServer doesn't seem to allow to use a static buffer and the dynamic allocation uses a fixed size, so more RAM than necessary is consumed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good.
I only found one problem with the size of the ip address. Other comments are only hints about style. Or similar minor things.
src/Homie/Boot/BootConfig.cpp
Outdated
__SendJSONError(request, F("✖ Invalid or too big JSON")); | ||
return; | ||
} | ||
|
||
JsonObject parsedJson = parseJsonDoc.as<JsonObject>(); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
superfluous empty line
src/Homie/Boot/BootConfig.cpp
Outdated
@@ -143,8 +144,8 @@ void BootConfig::_onWifiConnectRequest(AsyncWebServerRequest *request) { | |||
void BootConfig::_onWifiStatusRequest(AsyncWebServerRequest *request) { | |||
Interface::get().getLogger() << F("Received Wi-Fi status request") << endl; | |||
|
|||
DynamicJsonBuffer generatedJsonBuffer(JSON_OBJECT_SIZE(2)); | |||
JsonObject& json = generatedJsonBuffer.createObject(); | |||
StaticJsonDocument<JSON_OBJECT_SIZE(2) + 18 + 16> generatedJsonDoc; // Includes memory to duplicate strings for status and local_ip |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please explain how you calculated these numbers.
Are only IPv4 addresses allowed? If not we run in trouble with IPv6 addresses.
You might also place your comment above the line. This increases the readability.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Currently, WiFi.localIP()
only returns an IPv4 address. But I could change the value to 40 to fit IPv6 addresses in the future.
18 ist the size of the longest WiFi status string, which is "no_ssid_available". Since this is a flash string it needs to be duplicated by ArduinoJson.
src/Homie/Boot/BootConfig.cpp
Outdated
if (!parsedJson.success()) { | ||
StaticJsonDocument<JSON_OBJECT_SIZE(1)> parseJsonDoc; | ||
char* body = (char*)(request->_tempObject); | ||
if (deserializeJson(parseJsonDoc, body) != DeserializationError::Ok || !parseJsonDoc.is<JsonObject>()) { // do not use plain String, else fails |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does the comment still make any sense? The comment also doesn't describe why. I would be in favor to remove this comment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have no idea why it was there the first place. I'll remove it.
src/Homie/Boot/BootConfig.cpp
Outdated
__SendJSONError(request, F("✖ Invalid or too big JSON")); | ||
return; | ||
} | ||
|
||
JsonObject parsedJson = parseJsonDoc.as<JsonObject>(); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
superfluous empty line
src/Homie/Config.cpp
Outdated
Interface::get().getLogger() << F("✖ Invalid JSON in the config file") << endl; | ||
return false; | ||
} | ||
|
||
JsonObject parsedJson = jsonDoc.as<JsonObject>(); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
superfluous empty line
src/Homie/Config.cpp
Outdated
Interface::get().getLogger() << F("✖ Invalid or too big JSON") << endl; | ||
return false; | ||
} | ||
|
||
JsonObject patchObject = patchJsonDoc.as<JsonObject>(); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
superfluous empty line
I did a test run on my temp-sensor. I can run the configurator and also run it with my preconfigured filesystem. |
@iluminat23 I committed your proposed changes to the pull request and also made sure to make the linter happy again. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good.
Are the commit squashed when the branch is merged or do you need to do this? I'm not used to work with github merge requests.
AFAIK both commits will be merged separately into the branch on approval. Since the first commit doesn't contain a serious issue, I don't think squashing them would be necessary, but I could do it if you like. |
In my projects I would definitely do this. A clean history is a big plus. It makes refactoring or bug hunting mach easier. |
* Migrate the code from ArduinoJson v5 to v6 * Resolve memory allocation issues resulting from the migration * Reduce unnecessary copying of some JSON related strings * Change to StaticJsonBuffer if possible * Use C++ casts instead of C-style casts * Remove unnecessary comments * Serialize JsonDocument instead of JsonObject
5cd999f
to
1491400
Compare
I squashed the commits. |
Will test this, when I have some spare time. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The changes work very well for me.