MicroOcpp
MicroOcpp copied to clipboard
"data" field in DataTransfer only allow text data. - Example about sendRequest() and setRequestHandler() is wrong.
Hi @matth-x .
I found "data" field in Datatransfer only allow string.
In OCPP 1.6 Specification - Edition 2 p.64, defines "data" 's field type as text.
Also. There is test case about datatransfer in OCTT.(TC_062)
In this test case, if I send JSON Object in data field, the test fails with this info. (The testcase was aborted because The message did not pass JSON schema validation. Reason: #/data: expected type: String, found: JSONObject)
So we need to serialize data to string in "data" field.
In MicroOcpp.h
/*
* Create and send an operation without using the built-in Operation class. This function bypasses
* the business logic which comes with this library. E.g. you can send unknown operations, extend
* OCPP or replace parts of the business logic with custom behavior.
*
* Use case 1, extend the library by sending additional operations. E.g. DataTransfer:
*
* sendRequest("DataTransfer", [] () -> std::unique_ptr<MicroOcpp::JsonDoc> {
* //will be called to create the request once this operation is being sent out
* size_t capacity = JSON_OBJECT_SIZE(3) +
* JSON_OBJECT_SIZE(2); //for calculating the required capacity, see https://arduinojson.org/v6/assistant/
* auto res = std::unique_ptr<MicroOcpp::JsonDoc>(new MicroOcpp::JsonDoc(capacity));
* JsonObject request = *res;
* request["vendorId"] = "My company Ltd.";
* request["messageId"] = "TargetValues";
* request["data"]["battery_capacity"] = 89;
* request["data"]["battery_soc"] = 34;
* return res;
* }, [] (JsonObject response) -> void {
* //will be called with the confirmation response of the server
* if (!strcmp(response["status"], "Accepted")) {
* //DataTransfer has been accepted
* int max_energy = response["data"]["max_energy"];
* }
* });
*
* Use case 2, bypass the business logic of this library for custom behavior. E.g. StartTransaction:
*
* sendRequest("StartTransaction", [] () -> std::unique_ptr<MicroOcpp::JsonDoc> {
* //will be called to create the request once this operation is being sent out
* size_t capacity = JSON_OBJECT_SIZE(4); //for calculating the required capacity, see https://arduinojson.org/v6/assistant/
* auto res = std::unique_ptr<MicroOcpp::JsonDoc>(new MicroOcpp::JsonDoc(capacity));
* JsonObject request = res->to<JsonObject>();
* request["connectorId"] = 1;
* request["idTag"] = "A9C3CE1D7B71EA";
* request["meterStart"] = 1234;
* request["timestamp"] = "2023-06-01T11:07:43Z"; //e.g. some historic transaction
* return res;
* }, [] (JsonObject response) -> void {
* //will be called with the confirmation response of the server
* const char *status = response["idTagInfo"]["status"];
* int transactionId = response["transactionId"];
* });
*
* In Use case 2, the library won't send any further StatusNotification or StopTransaction on
* its own.
*/
void sendRequest(const char *operationType,
std::function<std::unique_ptr<MicroOcpp::JsonDoc> ()> fn_createReq,
std::function<void (JsonObject)> fn_processConf);
/*
* Set a custom handler for an incoming operation type. This will update the core Operation registry
* of the library, potentially replacing the built-in Operation handler and bypassing the
* business logic of this library.
*
* Note that when replacing an operation handler, the attached listeners will be reset.
*
* Example usage:
*
* setRequestHandler("DataTransfer", [] (JsonObject request) -> void {
* //will be called with the request message from the server
* const char *vendorId = request["vendorId"];
* const char *messageId = request["messageId"];
* int battery_capacity = request["data"]["battery_capacity"];
* int battery_soc = request["data"]["battery_soc"];
* }, [] () -> std::unique_ptr<MicroOcpp::JsonDoc> {
* //will be called to create the response once this operation is being sent out
* size_t capacity = JSON_OBJECT_SIZE(2) +
* JSON_OBJECT_SIZE(1); //for calculating the required capacity, see https://arduinojson.org/v6/assistant/
* auto res = std::unique_ptr<MicroOcpp::JsonDoc>(new MicroOcpp::JsonDoc(capacity));
* JsonObject response = res->to<JsonObject>();
* response["status"] = "Accepted";
* response["data"]["max_energy"] = 59;
* return res;
* });
*/
void setRequestHandler(const char *operationType,
std::function<void (JsonObject)> fn_processReq,
std::function<std::unique_ptr<MicroOcpp::JsonDoc> ()> fn_createConf);
This example send "data" field as json object