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

Change Call and CallResult to allow for cusomization #2

Open
OrangeTux opened this issue Dec 28, 2022 · 1 comment
Open

Change Call and CallResult to allow for cusomization #2

OrangeTux opened this issue Dec 28, 2022 · 1 comment

Comments

@OrangeTux
Copy link
Owner

I've worked with over a dozen of different charge points vendors. And I've learned that an OCPP framework must allow for customization as not all chargers follow the the OCPP specification exactly.

For example, chargers might add extra fields to a message. Or chargers add extra messages. Or chargers might support a mix of OCPP 1.6 and OCPP 2.0.1 messages.

The current implementation of rauts doesn't allow for customization. The problems are:

  1. Call.action is of type Action. Action is an enum like:
pub enum Action {
   Authorize,
   Heartbeat,
   ...
}

This choice makes it not possible to support a custom action.

  1. Call.payload is of type Payload. Again, Payload is an enum type. Adding a new payload or modify an existing payload requires modification to Payload.

CallResult suffers from the same problem.

The API of both types should be changed to allow users of rauts support for custom messages.

@konrad-grochowski-codetain
Copy link

konrad-grochowski-codetain commented Jan 3, 2023

For accepting extra fields in the message, serde's flatten can be used:
serde-rs/serde#941 (comment)

As for extending the variants of Action, my opinion is this requires big architecture changes. enum is supposed to represent a closed set of variants, the requirements you are describing make it cross this bound.

One proposition to fulfill this is to move all of enum into trait. So instead of Payload enum it would now become Payload trait, with arbitrary number of implementations (by default it would be implemented for all payload types).
Going this way requires dynamic dispatch (type of payload fields in ocpp::Message would then be Box<dyn Payload>).
Using this effectively in Router would probably mean going back to using TypeId as HashMap key, and then downcasting the message payload from Box<dyn ...> to concrete payload type in handler.

If it is feasible to know the set of messages beforehand for a type of charger, it is also possible to just make whole system generic across Payload type and create different Payload enums for different chargers. Sounds like not an easy solution to maintain though.

The last point, mix of OCPP 1.6 and OCPP 2.0.1 messages, can also be somehow solved like the previous problem, but it sounds like a nighmare to accept random messages one after another in different protocols. I could see this somehow working if we had two Payload traits, say PayloadOcpp16 and PayloadOcpp201, and additional Payload trait on top of them, which would combine them with impl Payload for T: PayloadOcpp16 {..} and impl Payload for T: PayloadOcpp201 {..}. Again, doesn't feel too clean to me.

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

2 participants