Skip to content
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

"data" field in DataTransfer only allow text data. - Example about sendRequest() and setRequestHandler() is wrong. #395

Open
JungHeum-Park opened this issue Jan 13, 2025 · 0 comments

Comments

@JungHeum-Park
Copy link

JungHeum-Park commented Jan 13, 2025

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant