matth-x / MicroOcpp

OCPP 1.6 client for microcontrollers
MIT License
300 stars 131 forks source link

Support for binary data over websockets #269

Open V2G-UK opened 4 months ago

V2G-UK commented 4 months ago

Having started experimenting with more "efficient" message encodings than the very verbose JSON, a problem has become apparent.

This is evident when using SteVe as well as our "homebrew" OCPP 1.6-J server. As far as I can tell, although Arduino WebSockets includes support for WSop_binary, MicroOcpp does not.

That means the servers barf when they validate a received message purporting to be WSop_text, complaining about an "Invalid UTF-8 string".

matth-x commented 4 months ago

The two relevant touch points with the ArduinoWebSockets library are here:

https://github.com/matth-x/MicroOcpp/blob/b5f37233671f2aa0d3883d78246c3183dd205706/src/MicroOcpp/Core/Connection.cpp#L55-L57

https://github.com/matth-x/MicroOcpp/blob/b5f37233671f2aa0d3883d78246c3183dd205706/src/MicroOcpp/Core/Connection.cpp#L72-L81

Probably it will suffice to exchange sendTXT with the corresponding send function and to move the event handler for WStype_TEXT into the WStype_BIN section.

V2G-UK commented 3 months ago

Thanks for the tips Matthias.

I've successfully kept SteVe happy by implementing a quick'n'dirty hack, which also involved adding a call to my newly created WSClient::sendBIN() in Core/RequestQueue.cpp.

I guess that leaves 2 questions:

1) Given the current "OCPP 2.lite" discussions at the OCA, are you likely to formally add binary message support to MicroOcpp in the not too distant future?

2) A much bigger question! The changes I've implemented have increased CPU utilisation rather than reduced it. Have you ever considered a "rewrite" to allow alternative message encodings without having to go via the JSON middle man?

matth-x commented 3 months ago

Happy to hear that it works!

  1. For an official feature of MicroOcpp, it should either be an acknowledged extension by the OCA or should actually be used in at least one productive system (or planned to). For evaluation purposes, I thinks it's most practical to have it in the eval/msgpack branch and keep that branch up-to-date with master.
  2. That surprises me to be honest. The following benchmark of the MsgPack feature of ArduinoJson suggests a significant speedup: https://github.com/fabianoriccardi/benchmark-json-messagepack In my understanding, ArduinoJson builds up the same DOM regardless of JSON and MsgPack, but eventually serializes into a different format depending on the user selection. Maybe a question in the issue section of ArduinoJson could clear this up. I would rather assume that the sendBIN function of the WebSockets library is somehow less optimized than sendTXT. Anyway, for the new OCPP 2.0.1 modules, I've already refined the architecture so that the Operation classes encapsulate all JSON (de)serialization and the business logic is moved to the corresponding Model entity. That way it will be possible to replace the message format by exchanging the OCPP message (de)serializer while the rest of the business logic remains intact. Of course I will eventually refactor the existing modules so that they align with this architecture.
V2G-UK commented 3 months ago
  1. OK, thanks.

  2. My apologies for the confusion. I got MsgPack encoding working as a proof of concept but I haven't tested it yet. My overly brief remark was prompted by (very!) preliminary work with alternative binary encodings.

It sounds as though the refined architecture you mention may well address my concerns.