Skip to content

Commit 173cfd9

Browse files
committed
Migrate to W3C WoT TD 1.0 standard
1 parent 98b916e commit 173cfd9

File tree

3 files changed

+51
-183
lines changed

3 files changed

+51
-183
lines changed

ESPWebThingAdapter.h

Lines changed: 14 additions & 113 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ class WebThingAdapter {
5555
}
5656

5757
MDNS.addService("webthing", "tcp", port);
58-
MDNS.addServiceTxt("webthing", "tcp", "path", "/");
58+
MDNS.addServiceTxt("webthing", "tcp", "path", "/.well-known/wot-thing-description");
5959

6060
DefaultHeaders::Instance().addHeader("Access-Control-Allow-Origin", "*");
6161
DefaultHeaders::Instance().addHeader("Access-Control-Allow-Methods",
@@ -70,7 +70,7 @@ class WebThingAdapter {
7070
this->server.on("/*", HTTP_OPTIONS,
7171
std::bind(&WebThingAdapter::handleOptions, this,
7272
std::placeholders::_1));
73-
this->server.on("/", HTTP_GET,
73+
this->server.on("/.well-known/wot-thing-description", HTTP_GET,
7474
std::bind(&WebThingAdapter::handleThings, this,
7575
std::placeholders::_1));
7676

@@ -131,17 +131,7 @@ class WebThingAdapter {
131131
std::bind(&WebThingAdapter::handleThingPropertiesGet,
132132
this, std::placeholders::_1,
133133
device->firstProperty));
134-
this->server.on((deviceBase + "/actions").c_str(), HTTP_GET,
135-
std::bind(&WebThingAdapter::handleThingActionsGet, this,
136-
std::placeholders::_1, device));
137-
this->server.on((deviceBase + "/actions").c_str(), HTTP_POST,
138-
std::bind(&WebThingAdapter::handleThingActionsPost, this,
139-
std::placeholders::_1, device),
140-
NULL,
141-
std::bind(&WebThingAdapter::handleBody, this,
142-
std::placeholders::_1, std::placeholders::_2,
143-
std::placeholders::_3, std::placeholders::_4,
144-
std::placeholders::_5));
134+
145135
this->server.on((deviceBase + "/events").c_str(), HTTP_GET,
146136
std::bind(&WebThingAdapter::handleThingEventsGet, this,
147137
std::placeholders::_1, device));
@@ -362,16 +352,15 @@ class WebThingAdapter {
362352
request->beginResponseStream("application/json");
363353

364354
DynamicJsonDocument buf(LARGE_JSON_DOCUMENT_SIZE);
365-
JsonArray things = buf.to<JsonArray>();
355+
JsonObject thing = buf.to<JsonObject>();
366356
ThingDevice *device = this->firstDevice;
367357
while (device != nullptr) {
368-
JsonObject descr = things.createNestedObject();
369-
device->serialize(descr, ip, port);
370-
descr["href"] = "/things/" + device->id;
358+
device->serialize(thing, ip, port);
359+
thing["href"] = "/things/" + device->id;
371360
device = device->next;
372361
}
373362

374-
serializeJson(things, *response);
363+
serializeJson(thing, *response);
375364
request->send(response);
376365
}
377366

@@ -474,6 +463,7 @@ class WebThingAdapter {
474463
void handleThingActionPost(AsyncWebServerRequest *request,
475464
ThingDevice *device, ThingAction *action) {
476465
if (!verifyHost(request)) {
466+
Serial.println("Invalid Host");
477467
return;
478468
}
479469

@@ -486,31 +476,19 @@ class WebThingAdapter {
486476
new DynamicJsonDocument(SMALL_JSON_DOCUMENT_SIZE);
487477
auto error = deserializeJson(*newBuffer, (const char *)body_data);
488478
if (error) { // unable to parse json
479+
Serial.println("Unable to parse JSON");
489480
b_has_body_data = false;
490481
memset(body_data, 0, sizeof(body_data));
491482
request->send(500);
492483
delete newBuffer;
493484
return;
494485
}
495486

496-
JsonObject newAction = newBuffer->as<JsonObject>();
497-
498-
if (!newAction.containsKey(action->id)) {
499-
b_has_body_data = false;
500-
memset(body_data, 0, sizeof(body_data));
501-
request->send(400);
502-
delete newBuffer;
503-
return;
504-
}
505-
506-
ThingActionObject *obj = device->requestAction(newBuffer);
507-
487+
ThingActionObject *obj = action->create(newBuffer);
508488
if (obj == nullptr) {
509-
b_has_body_data = false;
510-
memset(body_data, 0, sizeof(body_data));
511-
request->send(500);
512-
delete newBuffer;
513-
return;
489+
memset(body_data, 0, sizeof(body_data));
490+
request->send(500);
491+
return;
514492
}
515493

516494
#ifndef WITHOUT_WS
@@ -567,84 +545,7 @@ class WebThingAdapter {
567545
request->send(response);
568546
}
569547

570-
void handleThingActionsGet(AsyncWebServerRequest *request,
571-
ThingDevice *device) {
572-
if (!verifyHost(request)) {
573-
return;
574-
}
575-
AsyncResponseStream *response =
576-
request->beginResponseStream("application/json");
577-
578-
DynamicJsonDocument doc(LARGE_JSON_DOCUMENT_SIZE);
579-
JsonArray queue = doc.to<JsonArray>();
580-
device->serializeActionQueue(queue);
581-
serializeJson(queue, *response);
582-
request->send(response);
583-
}
584-
585-
void handleThingActionsPost(AsyncWebServerRequest *request,
586-
ThingDevice *device) {
587-
if (!verifyHost(request)) {
588-
return;
589-
}
590-
591-
if (!b_has_body_data) {
592-
request->send(422); // unprocessable entity (b/c no body)
593-
return;
594-
}
595-
596-
DynamicJsonDocument *newBuffer =
597-
new DynamicJsonDocument(SMALL_JSON_DOCUMENT_SIZE);
598-
auto error = deserializeJson(*newBuffer, (const char *)body_data);
599-
if (error) { // unable to parse json
600-
b_has_body_data = false;
601-
memset(body_data, 0, sizeof(body_data));
602-
request->send(500);
603-
delete newBuffer;
604-
return;
605-
}
606-
607-
JsonObject newAction = newBuffer->as<JsonObject>();
608-
609-
if (newAction.size() != 1) {
610-
b_has_body_data = false;
611-
memset(body_data, 0, sizeof(body_data));
612-
request->send(400);
613-
delete newBuffer;
614-
return;
615-
}
616-
617-
ThingActionObject *obj = device->requestAction(newBuffer);
618-
619-
if (obj == nullptr) {
620-
b_has_body_data = false;
621-
memset(body_data, 0, sizeof(body_data));
622-
request->send(500);
623-
delete newBuffer;
624-
return;
625-
}
626-
627-
#ifndef WITHOUT_WS
628-
obj->setNotifyFunction(std::bind(&ThingDevice::sendActionStatus, device,
629-
std::placeholders::_1));
630-
#endif
631-
632-
DynamicJsonDocument respBuffer(SMALL_JSON_DOCUMENT_SIZE);
633-
JsonObject item = respBuffer.to<JsonObject>();
634-
obj->serialize(item, device->id);
635-
String jsonStr;
636-
serializeJson(item, jsonStr);
637-
AsyncWebServerResponse *response =
638-
request->beginResponse(201, "application/json", jsonStr);
639-
request->send(response);
640-
641-
b_has_body_data = false;
642-
memset(body_data, 0, sizeof(body_data));
643-
644-
obj->start();
645-
}
646-
647-
void handleThingEventsGet(AsyncWebServerRequest *request,
548+
void handleThingEventsGet(AsyncWebServerRequest *request,
648549
ThingDevice *device) {
649550
if (!verifyHost(request)) {
650551
return;

Thing.h

Lines changed: 35 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -99,8 +99,7 @@ class ThingActionObject {
9999
JsonObject data = obj.createNestedObject(name);
100100

101101
JsonObject actionObj = actionRequest->as<JsonObject>();
102-
JsonObject inner = actionObj[name];
103-
data["input"] = inner["input"];
102+
data["input"] = actionObj;
104103

105104
data["status"] = status;
106105
data["timeRequested"] = timeRequested;
@@ -126,8 +125,7 @@ class ThingActionObject {
126125
setStatus("pending");
127126

128127
JsonObject actionObj = actionRequest->as<JsonObject>();
129-
JsonObject inner = actionObj[name];
130-
start_fn(inner["input"]);
128+
start_fn(actionObj);
131129

132130
finish();
133131
}
@@ -197,7 +195,7 @@ class ThingAction {
197195
// 2.11 Action object: A links array (An array of Link objects linking
198196
// to one or more representations of an Action resource, each with an
199197
// implied default rel=action.)
200-
JsonArray inline_links = obj.createNestedArray("links");
198+
JsonArray inline_links = obj.createNestedArray("forms");
201199
JsonObject inline_links_prop = inline_links.createNestedObject();
202200
inline_links_prop["href"] = "/things/" + deviceId + "/actions/" + id;
203201
}
@@ -297,7 +295,7 @@ class ThingItem {
297295
// 2.9 Property object: A links array (An array of Link objects linking
298296
// to one or more representations of a Property resource, each with an
299297
// implied default rel=property.)
300-
JsonArray inline_links = obj.createNestedArray("links");
298+
JsonArray inline_links = obj.createNestedArray("forms");
301299
JsonObject inline_links_prop = inline_links.createNestedObject();
302300
inline_links_prop["href"] =
303301
"/things/" + deviceId + "/" + resourceType + "/" + id;
@@ -460,8 +458,6 @@ class ThingEventObject {
460458
data["data"] = *this->getValue().string;
461459
break;
462460
}
463-
464-
data["timestamp"] = timestamp;
465461
}
466462
};
467463

@@ -696,9 +692,11 @@ class ThingDevice {
696692
}
697693

698694
void serialize(JsonObject descr, String ip, uint16_t port) {
699-
descr["id"] = this->id;
695+
descr["id"] = "uri:" + this->id;
700696
descr["title"] = this->title;
701-
descr["@context"] = "https://webthings.io/schemas";
697+
698+
JsonArray context = descr.createNestedArray("@context");
699+
context.add("https://www.w3.org/2019/wot/td/v1");
702700

703701
if (this->description != "") {
704702
descr["description"] = this->description;
@@ -715,7 +713,8 @@ class ThingDevice {
715713
descr.createNestedObject("securityDefinitions");
716714
JsonObject nosecSc = securityDefinitions.createNestedObject("nosec_sc");
717715
nosecSc["scheme"] = "nosec";
718-
descr["security"] = "nosec_sc";
716+
JsonArray securityJson = descr.createNestedArray("security");
717+
securityJson.add("nosec_sc");
719718

720719
JsonArray typeJson = descr.createNestedArray("@type");
721720
const char **type = this->type;
@@ -724,43 +723,33 @@ class ThingDevice {
724723
type++;
725724
}
726725

727-
JsonArray links = descr.createNestedArray("links");
728-
{
729-
JsonObject links_prop = links.createNestedObject();
730-
links_prop["rel"] = "properties";
731-
links_prop["href"] = "/things/" + this->id + "/properties";
732-
}
733-
734-
{
735-
JsonObject links_prop = links.createNestedObject();
736-
links_prop["rel"] = "actions";
737-
links_prop["href"] = "/things/" + this->id + "/actions";
738-
}
739-
740-
{
741-
JsonObject links_prop = links.createNestedObject();
742-
links_prop["rel"] = "events";
743-
links_prop["href"] = "/things/" + this->id + "/events";
744-
}
745-
746-
#ifndef WITHOUT_WS
747-
{
748-
JsonObject links_prop = links.createNestedObject();
749-
links_prop["rel"] = "alternate";
750-
751-
if (port != 80) {
752-
char buffer[33];
753-
itoa(port, buffer, 10);
754-
links_prop["href"] =
755-
"ws://" + ip + ":" + buffer + "/things/" + this->id;
756-
} else {
757-
links_prop["href"] = "ws://" + ip + "/things/" + this->id;
758-
}
759-
}
760-
#endif
761-
762726
ThingProperty *property = this->firstProperty;
763727
if (property != nullptr) {
728+
JsonArray forms = descr.createNestedArray("forms");
729+
JsonObject forms_prop = forms.createNestedObject();
730+
forms_prop["rel"] = "properties";
731+
JsonArray context = forms_prop.createNestedArray("op");
732+
context.add("readallproperties");
733+
context.add("writeallproperties");
734+
forms_prop["href"] = "/things/" + this->id + "/properties";
735+
736+
737+
#ifndef WITHOUT_WS
738+
{
739+
JsonObject forms_prop = forms.createNestedObject();
740+
//links_prop["rel"] = "alternate";
741+
742+
if (port != 80) {
743+
char buffer[33];
744+
itoa(port, buffer, 10);
745+
forms_prop["href"] =
746+
"ws://" + ip + ":" + buffer + "/things/" + this->id;
747+
} else {
748+
forms_prop["href"] = "ws://" + ip + "/things/" + this->id;
749+
}
750+
}
751+
#endif
752+
764753
JsonObject properties = descr.createNestedObject("properties");
765754
while (property != nullptr) {
766755
JsonObject obj = properties.createNestedObject(property->id);

WiFi101WebThingAdapter.h

Lines changed: 2 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -308,30 +308,8 @@ class WebThingAdapter {
308308
handleError();
309309
}
310310
return;
311-
} else if (uri == deviceBase + "/properties") {
312-
if (method == HTTP_GET || method == HTTP_OPTIONS) {
313-
handleThingPropertiesGet(device->firstProperty);
314-
} else {
315-
handleError();
316-
}
317-
return;
318-
} else if (uri == deviceBase + "/actions") {
319-
if (method == HTTP_GET || method == HTTP_OPTIONS) {
320-
handleThingActionsGet(device);
321-
} else if (method == HTTP_POST) {
322-
handleThingActionsPost(device);
323-
} else {
324-
handleError();
325-
}
326-
return;
327-
} else if (uri == deviceBase + "/events") {
328-
if (method == HTTP_GET || method == HTTP_OPTIONS) {
329-
handleThingEventsGet(device);
330-
} else {
331-
handleError();
332-
}
333-
return;
334-
} else {
311+
}
312+
} else {
335313
ThingProperty *property = device->firstProperty;
336314
while (property != nullptr) {
337315
String propertyBase = deviceBase + "/properties/" + property->id;

0 commit comments

Comments
 (0)