mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2025-12-06 15:59:52 +03:00
support for device in json body
This commit is contained in:
@@ -33,19 +33,21 @@ WebAPIService::WebAPIService(AsyncWebServer * server, SecurityManager * security
|
|||||||
|
|
||||||
// GET /{device}
|
// GET /{device}
|
||||||
// GET /{device}/{name}
|
// GET /{device}/{name}
|
||||||
// GET /device={device}?cmd={name}?data={value}[?id={hc}
|
// GET /device={device}?cmd={name}?data={value}[?id={hc}]
|
||||||
void WebAPIService::webAPIService_get(AsyncWebServerRequest * request) {
|
void WebAPIService::webAPIService_get(AsyncWebServerRequest * request) {
|
||||||
std::string device("");
|
// initialize parameters. These will be extracted from the URL
|
||||||
std::string cmd("");
|
std::string device_s("");
|
||||||
|
std::string cmd_s("");
|
||||||
|
std::string value_s("");
|
||||||
int id = -1;
|
int id = -1;
|
||||||
std::string value("");
|
|
||||||
|
|
||||||
parse(request, device, cmd, id, value); // pass it defaults
|
parse(request, device_s, cmd_s, id, value_s);
|
||||||
}
|
}
|
||||||
|
|
||||||
// For POSTS with an optional JSON body
|
// For POSTS with an optional JSON body
|
||||||
// HTTP_POST | HTTP_PUT | HTTP_PATCH
|
// HTTP_POST | HTTP_PUT | HTTP_PATCH
|
||||||
// POST/PUT /{device}[/{hc}][/{name}]
|
// POST /{device}[/{hc|id}][/{name}]
|
||||||
|
// the body must have 'value'. Optional are device, name, hc and id
|
||||||
void WebAPIService::webAPIService_post(AsyncWebServerRequest * request, JsonVariant & json) {
|
void WebAPIService::webAPIService_post(AsyncWebServerRequest * request, JsonVariant & json) {
|
||||||
// if no body then treat it as a secure GET
|
// if no body then treat it as a secure GET
|
||||||
if (not json.is<JsonObject>()) {
|
if (not json.is<JsonObject>()) {
|
||||||
@@ -53,13 +55,34 @@ void WebAPIService::webAPIService_post(AsyncWebServerRequest * request, JsonVari
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// extract values from the json
|
// extract values from the json. these will be used as default values
|
||||||
// these will be used as default values
|
|
||||||
auto && body = json.as<JsonObject>();
|
auto && body = json.as<JsonObject>();
|
||||||
|
|
||||||
std::string device = body["name"].as<std::string>(); // note this was called device in the v2
|
#if defined(EMSESP_STANDALONE)
|
||||||
std::string cmd = body["cmd"].as<std::string>();
|
Serial.println("webAPIService_post: ");
|
||||||
int id = -1;
|
serializeJson(body, Serial);
|
||||||
|
Serial.println();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// make sure we have a value. There must always be a value
|
||||||
|
if (!body.containsKey(F_(value))) {
|
||||||
|
send_message_response(request, 400, "Problems parsing JSON, missing value"); // Bad Request
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string value_s = body["value"].as<std::string>(); // always convert value to string
|
||||||
|
std::string device_s = body["device"].as<std::string>();
|
||||||
|
|
||||||
|
// get the command. It can be either 'name' or 'cmd'
|
||||||
|
std::string cmd_s("");
|
||||||
|
if (body.containsKey("name")) {
|
||||||
|
cmd_s = body["name"].as<std::string>();
|
||||||
|
} else if (body.containsKey("cmd")) {
|
||||||
|
cmd_s = body["cmd"].as<std::string>();
|
||||||
|
}
|
||||||
|
|
||||||
|
// for id, it can be part of the hc or id keys in the json body
|
||||||
|
int id = -1;
|
||||||
if (body.containsKey("id")) {
|
if (body.containsKey("id")) {
|
||||||
id = body["id"];
|
id = body["id"];
|
||||||
} else if (body.containsKey("hc")) {
|
} else if (body.containsKey("hc")) {
|
||||||
@@ -68,15 +91,8 @@ void WebAPIService::webAPIService_post(AsyncWebServerRequest * request, JsonVari
|
|||||||
id = -1;
|
id = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// make sure we have a value. There must always be a value
|
|
||||||
if (!body.containsKey(F_(value))) {
|
|
||||||
send_message_response(request, 400, "Problems parsing JSON"); // Bad Request
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
std::string value = body["value"].as<std::string>(); // always convert value to string
|
|
||||||
|
|
||||||
// now parse the URL. The URL is always leading and will overwrite anything provided in the json body
|
// now parse the URL. The URL is always leading and will overwrite anything provided in the json body
|
||||||
parse(request, device, cmd, id, value); // pass it defaults
|
parse(request, device_s, cmd_s, id, value_s); // pass it defaults
|
||||||
}
|
}
|
||||||
|
|
||||||
// parse the URL looking for query or path parameters
|
// parse the URL looking for query or path parameters
|
||||||
@@ -97,7 +113,7 @@ void WebAPIService::parse(AsyncWebServerRequest * request, std::string & device_
|
|||||||
uint8_t device_type;
|
uint8_t device_type;
|
||||||
int8_t id_n = -1; // default hc
|
int8_t id_n = -1; // default hc
|
||||||
|
|
||||||
// check for query parameters first
|
// check for query parameters first, the old style from v2
|
||||||
// /device={device}?cmd={name}?data={value}[?id={hc}
|
// /device={device}?cmd={name}?data={value}[?id={hc}
|
||||||
if (p.paths().size() == 0) {
|
if (p.paths().size() == 0) {
|
||||||
// get the device
|
// get the device
|
||||||
@@ -126,27 +142,31 @@ void WebAPIService::parse(AsyncWebServerRequest * request, std::string & device_
|
|||||||
id_n = Helpers::atoint(request->getParam("hc")->value().c_str());
|
id_n = Helpers::atoint(request->getParam("hc")->value().c_str());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// parse paths and json data from the OpenAPI standard
|
// parse paths and json data from the newer OpenAPI standard
|
||||||
// /{device}[/{hc}][/{name}]
|
// [/{device}][/{hc}][/{name}]
|
||||||
// first param must be a valid device, which includes "system"
|
// all paths are optional. If not set then take the values from the json body (if available)
|
||||||
device_s = p.paths().front();
|
|
||||||
|
|
||||||
auto num_paths = p.paths().size();
|
// see if we have a device in the path
|
||||||
if (num_paths == 1) {
|
size_t num_paths = p.paths().size();
|
||||||
// if there are no more paths parameters, default to 'info'
|
if (num_paths) {
|
||||||
// cmd_s = "info_short";
|
// assume the next path is the 'device'. Note this could also have the value of system.
|
||||||
// check empty command in Command::find_command and set the default there!
|
device_s = p.paths().front();
|
||||||
} else if (num_paths == 2) {
|
|
||||||
cmd_s = p.paths()[1];
|
if (num_paths == 2) {
|
||||||
} else if (num_paths > 2) {
|
// next path is the name or cmd
|
||||||
// check in Command::find_command makes prefix to TAG
|
cmd_s = p.paths()[1];
|
||||||
cmd_s = p.paths()[1] + "/" + p.paths()[2];
|
} else if (num_paths > 2) {
|
||||||
|
// check in Command::find_command makes prefix to TAG
|
||||||
|
cmd_s = p.paths()[1] + "/" + p.paths()[2];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// now go and validate everything
|
|
||||||
|
// now go and verify the values
|
||||||
|
|
||||||
// device check
|
// device check
|
||||||
if (device_s.empty()) {
|
if (device_s.empty()) {
|
||||||
|
// see if we have a device embedded in the json body, then use that
|
||||||
send_message_response(request, 422, "Missing device"); // Unprocessable Entity
|
send_message_response(request, 422, "Missing device"); // Unprocessable Entity
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -231,6 +251,8 @@ void WebAPIService::send_message_response(AsyncWebServerRequest * request, uint1
|
|||||||
response->setContentType("application/json");
|
response->setContentType("application/json");
|
||||||
request->send(response);
|
request->send(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EMSESP::logger().debug(F("API returns, code: %d, message: %s"), error_code, error_message);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user