Skip to content

ArduinoJson 6 #99

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

Merged
merged 12 commits into from
Dec 30, 2019
99 changes: 49 additions & 50 deletions ESPWebThingAdapter.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,10 +85,9 @@ class WebThingAdapter {
#ifndef WITHOUT_WS
void sendChangedPropsOrEvents(ThingDevice* device, const char* type, ThingItem* rootItem) {
// Prepare one buffer per device
DynamicJsonBuffer buf(1024);
JsonObject& message = buf.createObject();
DynamicJsonDocument message(1024);
message["messageType"] = type;
JsonObject& prop = message.createNestedObject("data");
JsonObject prop = message.createNestedObject("data");
bool dataToSend = false;
ThingItem* item = rootItem;
while (item != nullptr) {
Expand All @@ -101,7 +100,7 @@ class WebThingAdapter {
}
if (dataToSend) {
String jsonStr;
message.printTo(jsonStr);
serializeJson(message, jsonStr);
// Inform all connected ws clients of a Thing about changed properties
((AsyncWebSocket*)device->ws)->textAll(jsonStr.c_str(), jsonStr.length());
}
Expand Down Expand Up @@ -173,12 +172,11 @@ class WebThingAdapter {
}

#ifndef WITHOUT_WS
void sendErrorMsg(DynamicJsonBuffer &buffer, AsyncWebSocketClient& client, int status, const char* msg) {
JsonObject& prop = buffer.createObject();
void sendErrorMsg(DynamicJsonDocument &prop, AsyncWebSocketClient& client, int status, const char* msg) {
prop["error"] = msg;
prop["status"] = status;
String jsonStr;
prop.printTo(jsonStr);
serializeJson(prop, jsonStr);
client.text(jsonStr.c_str(), jsonStr.length());
}

Expand All @@ -198,36 +196,36 @@ class WebThingAdapter {
// spec. For now each Thing stores its own Websocket connection object therefore.

// Parse request
DynamicJsonBuffer newBuffer(1024);
JsonObject& newProp = newBuffer.parseObject(rawData);
if (!newProp.success()) {
sendErrorMsg(newBuffer, *client, 400, "Invalid json");
DynamicJsonDocument newProp(1024);
auto error = deserializeJson(newProp, rawData);
if (error) {
sendErrorMsg(newProp, *client, 400, "Invalid json");
return;
}

String messageType = newProp["messageType"].as<String>();
const JsonVariant& dataVariant = newProp["data"];
JsonVariant dataVariant = newProp["data"];
if (!dataVariant.is<JsonObject>()) {
sendErrorMsg(newBuffer, *client, 400, "data must be an object");
sendErrorMsg(newProp, *client, 400, "data must be an object");
return;
}

const JsonObject &data = dataVariant.as<const JsonObject&>();
JsonObject data = dataVariant.as<JsonObject>();

if (messageType == "setProperty") {
for (auto kv : data) {
ThingProperty* property = device->findProperty(kv.key);
ThingProperty* property = device->findProperty(kv.key().c_str());
if (property) {
setThingProperty(data, property);
}
}

// Send confirmation by sending back the received property object
String jsonStr;
data.printTo(jsonStr);
serializeJson(data, jsonStr);
client->text(jsonStr.c_str(), jsonStr.length());
} else if (messageType == "requestAction") {
sendErrorMsg(newBuffer, *client, 400, "Not supported yet");
sendErrorMsg(newProp, *client, 400, "Not supported yet");
} else if (messageType == "addEventSubscription") {
// We report back all property state changes. We'd require a map
// of subscribed properties per websocket connection otherwise
Expand All @@ -248,26 +246,26 @@ class WebThingAdapter {
}
AsyncResponseStream *response = request->beginResponseStream("application/json");

DynamicJsonBuffer buf(1024);
JsonArray& things = buf.createArray();
DynamicJsonDocument buf(1024);
JsonArray things = buf.to<JsonArray>();
ThingDevice* device = this->firstDevice;
while (device != nullptr) {
JsonObject& descr = things.createNestedObject();
JsonObject descr = things.createNestedObject();
this->serializeDevice(descr, device);
descr["href"] = "/things/" + device->id;
device = device->next;
}

things.printTo(*response);
serializeJson(things, *response);
request->send(response);

}

void serializePropertyOrEvent(JsonObject& descr, ThingDevice* device, const char* type, bool isProp, ThingItem* item) {
void serializePropertyOrEvent(JsonObject descr, ThingDevice* device, const char* type, bool isProp, ThingItem* item) {
String basePath = "/things/" + device->id + "/"+ type + "/";
JsonObject& props = descr.createNestedObject(type);
JsonObject props = descr.createNestedObject(type);
while (item != nullptr) {
JsonObject& prop = props.createNestedObject(item->id);
JsonObject prop = props.createNestedObject(item->id);
switch (item->type) {
case NO_STATE:
break;
Expand Down Expand Up @@ -313,7 +311,7 @@ class WebThingAdapter {

if (hasEnum) {
enumVal = property->propertyEnum;
JsonArray &propEnum = prop.createNestedArray("enum");
JsonArray propEnum = prop.createNestedArray("enum");
while (property->propertyEnum != nullptr && (*enumVal) != nullptr){
propEnum.add(*enumVal);
enumVal++;
Expand All @@ -326,47 +324,47 @@ class WebThingAdapter {
}

// 2.9 Property object: A links array (An array of Link objects linking to one or more representations of a Property resource, each with an implied default rel=property.)
JsonArray& inline_links = prop.createNestedArray("links");
JsonObject& inline_links_prop = inline_links.createNestedObject();
JsonArray inline_links = prop.createNestedArray("links");
JsonObject inline_links_prop = inline_links.createNestedObject();
inline_links_prop["href"] = basePath + item->id;

item = item->next;
}
}

void serializeDevice(JsonObject& descr, ThingDevice* device) {
void serializeDevice(JsonObject descr, ThingDevice* device) {
descr["id"] = device->id;
descr["title"] = device->title;
descr["@context"] = "https://iot.mozilla.org/schemas";
// TODO: descr["base"] = ???

JsonObject& securityDefinitions = descr.createNestedObject("securityDefinitions");
JsonObject& nosecSc = securityDefinitions.createNestedObject("nosec_sc");
JsonObject securityDefinitions = descr.createNestedObject("securityDefinitions");
JsonObject nosecSc = securityDefinitions.createNestedObject("nosec_sc");
nosecSc["scheme"] = "nosec";

JsonArray& typeJson = descr.createNestedArray("@type");
JsonArray typeJson = descr.createNestedArray("@type");
const char** type = device->type;
while ((*type) != nullptr) {
typeJson.add(*type);
type++;
}

JsonArray& links = descr.createNestedArray("links");
JsonArray links = descr.createNestedArray("links");
{
JsonObject& links_prop = links.createNestedObject();
JsonObject links_prop = links.createNestedObject();
links_prop["rel"] = "properties";
links_prop["href"] = "/things/" + device->id + "/properties";
}

{
JsonObject& links_prop = links.createNestedObject();
JsonObject links_prop = links.createNestedObject();
links_prop["rel"] = "events";
links_prop["href"] = "/things/" + device->id + "/events";
}

#ifndef WITHOUT_WS
{
JsonObject& links_prop = links.createNestedObject();
JsonObject links_prop = links.createNestedObject();
links_prop["rel"] = "alternate";
char buffer [33];
itoa(port, buffer, 10);
Expand All @@ -391,15 +389,15 @@ class WebThingAdapter {
}
AsyncResponseStream *response = request->beginResponseStream("application/json");

DynamicJsonBuffer buf(1024);
JsonObject& descr = buf.createObject();
DynamicJsonDocument buf(1024);
JsonObject descr = buf.to<JsonObject>();
this->serializeDevice(descr, device);

descr.printTo(*response);
serializeJson(descr, *response);
request->send(response);
}

void serializeThingItem(ThingItem* item, JsonObject& prop) {
void serializeThingItem(ThingItem* item, JsonObject prop) {
switch (item->type) {
case NO_STATE:
break;
Expand All @@ -421,24 +419,24 @@ class WebThingAdapter {
}
AsyncResponseStream *response = request->beginResponseStream("application/json");

DynamicJsonBuffer buf(256);
JsonObject& prop = buf.createObject();
DynamicJsonDocument doc(256);
JsonObject prop = doc.to<JsonObject>();
serializeThingItem(item, prop);
prop.printTo(*response);
serializeJson(prop, *response);
request->send(response);
}

void handleThingGetAll(AsyncWebServerRequest *request, ThingDevice* device, ThingItem* rootItem) {
AsyncResponseStream *response = request->beginResponseStream("application/json");

DynamicJsonBuffer buf(256);
JsonObject& prop = buf.createObject();
DynamicJsonDocument doc(256);
JsonObject prop = doc.to<JsonObject>();
ThingItem *item = rootItem;
while (item != nullptr) {
serializeThingItem(item, prop);
item = item->next;
}
prop.printTo(*response);
serializeJson(prop, *response);
request->send(response);
}

Expand All @@ -451,7 +449,7 @@ class WebThingAdapter {
b_has_body_data = true;
}

void setThingProperty(const JsonObject& newProp, ThingProperty* property) {
void setThingProperty(const JsonObject newProp, ThingProperty* property) {
const JsonVariant newValue = newProp[property->id];

switch (property->type) {
Expand Down Expand Up @@ -485,19 +483,20 @@ class WebThingAdapter {
return;
}

DynamicJsonBuffer newBuffer(256);
JsonObject& newProp = newBuffer.parseObject(body_data);
if (!newProp.success()) { // unable to parse json
DynamicJsonDocument newBuffer(256);
auto error = deserializeJson(newBuffer, body_data);
if (error) { // unable to parse json
b_has_body_data = false;
memset(body_data, 0, sizeof(body_data));
request->send(500);
return;
}
JsonObject newProp = newBuffer.to<JsonObject>();

setThingProperty(newProp, property);

AsyncResponseStream *response = request->beginResponseStream("application/json");
newProp.printTo(*response);
serializeJson(newProp, *response);
request->send(response);

b_has_body_data = false;
Expand Down
38 changes: 19 additions & 19 deletions EthernetWebThingAdapter.h
Original file line number Diff line number Diff line change
Expand Up @@ -332,17 +332,17 @@ class WebThingAdapter {
sendOk();
sendHeaders();

DynamicJsonBuffer buf;
JsonArray& things = buf.createArray();
DynamicJsonDocument buf(256);
JsonArray things = buf.to<JsonArray>();
ThingDevice* device = firstDevice;
while (device != nullptr) {
JsonObject& descr = things.createNestedObject();
JsonObject descr = things.createNestedObject();
serializeDevice(descr, device);
descr["href"] = "/things/" + device->id;
device = device->next;
}

things.printTo(client);
serializeJson(things, client);
delay(1);
client.stop();
}
Expand All @@ -352,11 +352,11 @@ class WebThingAdapter {
sendOk();
sendHeaders();

DynamicJsonBuffer buf;
JsonObject& descr = buf.createObject();
DynamicJsonDocument buf(256);
JsonObject descr = buf.to<JsonObject>();
serializeDevice(descr, device);

descr.printTo(client);
serializeJson(descr, client);
delay(1);
client.stop();
}
Expand All @@ -365,8 +365,7 @@ class WebThingAdapter {
sendOk();
sendHeaders();

DynamicJsonBuffer buf;
JsonObject& prop = buf.createObject();
DynamicJsonDocument prop(256);
switch (property->type) {
case BOOLEAN:
prop[property->id] = property->getValue().boolean;
Expand All @@ -378,16 +377,17 @@ class WebThingAdapter {
prop[property->id] = *property->getValue().string;
break;
}
prop.printTo(client);
serializeJson(prop, client);
delay(1);
client.stop();
}

void handlePropertyPut(ThingProperty* property) {
sendOk();
sendHeaders();
DynamicJsonBuffer newBuffer;
JsonObject& newProp = newBuffer.parseObject(content);
DynamicJsonDocument newBuffer(256);
deserializeJson(newBuffer, content);
JsonObject newProp = newBuffer.to<JsonObject>();
JsonVariant newValue = newProp[property->id];

switch (property->type) {
Expand Down Expand Up @@ -431,28 +431,28 @@ class WebThingAdapter {
retries = 0;
}

void serializeDevice(JsonObject& descr, ThingDevice* device) {
void serializeDevice(JsonObject descr, ThingDevice* device) {
descr["id"] = device->id;
descr["title"] = device->title;
descr["@context"] = "https://iot.mozilla.org/schemas";
// TODO: descr["base"] = ???

JsonObject& securityDefinitions = descr.createNestedObject("securityDefinitions");
JsonObject& nosecSc = securityDefinitions.createNestedObject("nosec_sc");
JsonObject securityDefinitions = descr.createNestedObject("securityDefinitions");
JsonObject nosecSc = securityDefinitions.createNestedObject("nosec_sc");
nosecSc["scheme"] = "nosec";

JsonArray& typeJson = descr.createNestedArray("@type");
JsonArray typeJson = descr.createNestedArray("@type");
const char** type = device->type;
while ((*type) != nullptr) {
typeJson.add(*type);
type++;
}

JsonObject& props = descr.createNestedObject("properties");
JsonObject props = descr.createNestedObject("properties");

ThingProperty* property = device->firstProperty;
while (property != nullptr) {
JsonObject& prop = props.createNestedObject(property->id);
JsonObject prop = props.createNestedObject(property->id);
switch (property->type) {
case BOOLEAN:
prop["type"] = "boolean";
Expand Down Expand Up @@ -498,7 +498,7 @@ class WebThingAdapter {

if (hasEnum) {
enumVal = property->propertyEnum;
JsonArray &propEnum = prop.createNestedArray("enum");
JsonArray propEnum = prop.createNestedArray("enum");
while (property->propertyEnum != nullptr && (*enumVal) != nullptr){
propEnum.add(*enumVal);
enumVal++;
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ USER_LIB_PATH?=${extra_dir}/Arduino/libraries

ArduinoJson_url?=https://github.com/bblanchon/ArduinoJson
ArduinoJson_dir?=${extra_dir}/Arduino/libraries/ArduinoJson
ArduinoJson_version?=v5.13.4
ArduinoJson_version?=v6.13.0
arduino_lib_dirs+=${ArduinoJson_dir}

${ArduinoJson_dir}:
Expand Down
Loading