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

Generate OCPP 2.1 public draft messages #845

Draft
wants to merge 20 commits into
base: main
Choose a base branch
from

Conversation

hikinggrass
Copy link
Contributor

Describe your changes

First draft of changes needed to include 2.1 messages. At the moment this contains certain (arguably a bit hacky) code generator changes to generate new 2.1 messages in their own namespace, while changing 2.0.1 message definitions based on the 2.1 schemas. Here we need a bit more fine-grained handling

Issue ticket number and link

Checklist before requesting a review

@@ -74,8 +74,8 @@ struct Callbacks {
/// \return True if evse is reserved for the given id token / group id token, false if it is reserved for another
/// one.
///
std::function<bool(const int32_t evse_id, const CiString<36> idToken,
const std::optional<CiString<36>> groupIdToken)>
std::function<bool(const int32_t evse_id, const CiString<255> idToken,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't really a backwards-compatible change in the 2.1 schemas. Changes like this happened in a few different messages/types and need case-by-case handling. Either by adding additional conversion functions or different message generation for 2.0.1 and 2.1

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be ok to accept larger tokens here. This is only an issue if e.g. OCTT tests for OCPP2.0.1 if we accept larger tokens.

@@ -19,7 +19,7 @@ namespace v201 {
struct AuthorizeRequest : public ocpp::Message {
IdToken idToken;
std::optional<CustomData> customData;
std::optional<CiString<5500>> certificate;
std::optional<CiString<10000>> certificate;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could probably be reported via FieldLength variable for the AuthorizeRequest.certificate instance which should make this change backwards-compatible with 2.0.1

@@ -20,8 +20,10 @@ namespace v201 {
struct Get15118EVCertificateRequest : public ocpp::Message {
CiString<50> iso15118SchemaVersion;
CertificateActionEnum action;
CiString<5600> exiRequest;
CiString<11000> exiRequest;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding a FieldLength variable for Get15118EVCertificateRequest.exiRequest should make this backwards-compatible with 2.0.1

@@ -40,7 +40,7 @@ struct GetCertificateStatusResponse : public ocpp::Message {
GetCertificateStatusEnum status;
std::optional<CustomData> customData;
std::optional<StatusInfo> statusInfo;
std::optional<CiString<5500>> ocspResult;
std::optional<CiString<18000>> ocspResult;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding a FieldLength variable for GetCertificateStatusResponse.ocspResult should make this backwards-compatible with 2.0.1

@@ -18,7 +18,7 @@ namespace v201 {
/// \brief Contains a OCPP InstallCertificate message
struct InstallCertificateRequest : public ocpp::Message {
InstallCertificateUseEnum certificateType;
CiString<5500> certificate;
CiString<10000> certificate;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding a FieldLength variable for InstallCertificateRequest.certificate should make this backwards-compatible with 2.0.1

@@ -17,7 +17,7 @@ namespace v201 {

/// \brief Contains a OCPP PublishFirmware message
struct PublishFirmwareRequest : public ocpp::Message {
CiString<512> location;
CiString<2000> location;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding a FieldLength variable for PublishFirmwareRequest.location should make this backwards-compatible with 2.0.1

@@ -19,8 +19,9 @@ namespace v201 {
struct PublishFirmwareStatusNotificationRequest : public ocpp::Message {
PublishFirmwareStatusEnum status;
std::optional<CustomData> customData;
std::optional<std::vector<CiString<512>>> location;
std::optional<std::vector<CiString<2000>>> location;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding a FieldLength variable for PublishFirmwareStatusNotificationRequest.location should make this backwards-compatible with 2.0.1

std::optional<std::vector<MeterValue>> meterValue;
std::optional<bool> offline;
std::optional<int32_t> numberOfPhasesUsed;
std::optional<int32_t> cableMaxCurrent;
std::optional<float> cableMaxCurrent;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't strictly backwards compatible with 2.0.1 and probably needs additional handling

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change doesnt seem to make a lot of sense. In transaction_event_req we could continue to use an int and make an implicit cast to float

We should make sure that the float is serialized to an int in 2.0.1 when transmitting to the CSMS.

struct AdditionalInfo {
CiString<36> additionalIdToken;
CiString<255> additionalIdToken;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO: find out implications for backwards compatibility with 2.0.1

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Our best chance is to allow 255 here since we can then try to send to the CSMS. If the CSMS can handle it - fine. If it cant, we have at least tried and the CSMS will likely respond with a CALLERROR

@@ -34,8 +64,8 @@ void from_json(const json& j, AdditionalInfo& k);
std::ostream& operator<<(std::ostream& os, const AdditionalInfo& k);

struct IdToken {
CiString<36> idToken;
IdTokenEnum type;
CiString<255> idToken;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO: find out implications for backwards compatibility with 2.0.1

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Our best chance is to allow 255 here since we can then try to send to the CSMS. If the CSMS can handle it - fine. If it cant, we have at least tried and the CSMS will likely respond with a CALLERROR

@@ -54,7 +84,7 @@ struct OCSPRequestData {
CiString<128> issuerNameHash;
CiString<128> issuerKeyHash;
CiString<40> serialNumber;
CiString<512> responderURL;
CiString<2000> responderURL;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO: find out implications for backwards compatibility with 2.0.1

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same argument like with the id token. Lets allow the larger value here.

@@ -69,7 +99,7 @@ std::ostream& operator<<(std::ostream& os, const OCSPRequestData& k);

struct MessageContent {
MessageFormatEnum format;
CiString<512> content;
CiString<1024> content;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO: find out implications for backwards compatibility with 2.0.1

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Allow since its from CSMS

std::optional<CustomData> customData;
std::optional<float> limit;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO: find out implications for backwards compatibility with 2.0.1
This was required in 2.0.1 and is optional now in 2.1

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thats ok as long as we make sure that we always set this limit for v201 (which we do because it was required before).

@@ -285,7 +893,7 @@ void from_json(const json& j, CertificateHashDataChain& k);
std::ostream& operator<<(std::ostream& os, const CertificateHashDataChain& k);

struct LogParameters {
CiString<512> remoteLocation;
CiString<2000> remoteLocation;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO: find out implications for backwards compatibility with 2.0.1

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is ok

Comment on lines +1029 to +1030
std::optional<CiString<50>> signingMethod;
std::optional<CiString<2500>> publicKey;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO: find out implications for backwards compatibility with 2.0.1
These two fields were required in 2.0.1 and are now optional in 2.1

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here we should implement different handling for 2.0.1 and 2.1 in the respective message handling

Comment on lines +1429 to +1432
float energyAmount;
float evMinCurrent;
float evMaxCurrent;
float evMaxVoltage;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO: find out implications for backwards compatibility with 2.0.1
type change from int to float

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Accept the change. We dont have any handling in libocpp with this type. We should implement different handling for 2.0.1 and 2.1 and make sure that the float is serialized to an int in 2.0.1 when transmitting to the CSMS.

Comment on lines +1593 to +1598
float evMaxCurrent;
float evMaxVoltage;
std::optional<CustomData> customData;
std::optional<int32_t> energyAmount;
std::optional<int32_t> evMaxPower;
std::optional<float> evMaxPower;
std::optional<float> evEnergyCapacity;
std::optional<float> energyAmount;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO: find out implications for backwards compatibility with 2.0.1
type change from int to float

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Accept the change. We dont have any handling in libocpp with this type. We should implement different handling for 2.0.1 and 2.1 and make sure that the float is serialized to an int in 2.0.1 when transmitting to the CSMS.

CiString<255> key;
VPNEnum type;
std::optional<CustomData> customData;
std::optional<CiString<20>> group;
std::optional<CiString<50>> group;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO: find out implications for backwards compatibility with 2.0.1

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Accept

int32_t messageTimeout;
CiString<2000> ocppCsmsUrl;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO: find out implications for backwards compatibility with 2.0.1

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Accept

@@ -890,7 +1992,7 @@ void from_json(const json& j, SetMonitoringResult& k);
std::ostream& operator<<(std::ostream& os, const SetMonitoringResult& k);

struct SetVariableData {
CiString<1000> attributeValue;
CiString<2500> attributeValue;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO: find out implications for backwards compatibility with 2.0.1

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Accept

@@ -943,7 +2132,7 @@ void from_json(const json& j, Transaction& k);
std::ostream& operator<<(std::ostream& os, const Transaction& k);

struct Firmware {
CiString<512> location;
CiString<2000> location;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO: find out implications for backwards compatibility with 2.0.1

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Accept

Comment on lines +174 to +195
namespace ChargingLimitSourceEnumStringType {
inline const CiString<20> EMS = "EMS";
inline const CiString<20> OTHER = "Other";
inline const CiString<20> SO = "SO";
inline const CiString<20> CSO = "CSO";
} // namespace ChargingLimitSourceEnumStringType

namespace IdTokenEnumStringType {
inline const CiString<20> Value = "Value";
inline const CiString<20> Central = "Central";
inline const CiString<20> DirectPayment = "DirectPayment";
inline const CiString<20> eMAID = "eMAID";
inline const CiString<20> EVCCID = "EVCCID";
inline const CiString<20> ISO14443 = "ISO14443";
inline const CiString<20> ISO15693 = "ISO15693";
inline const CiString<20> KeyCode = "KeyCode";
inline const CiString<20> Local = "Local";
inline const CiString<20> MacAddress = "MacAddress";
inline const CiString<20> NEMA = "NEMA";
inline const CiString<20> NoAuthorization = "NoAuthorization";
inline const CiString<20> VIN = "VIN";
} // namespace IdTokenEnumStringType
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO: move this to constants.hpp

@@ -792,7 +792,7 @@ std::optional<std::string> ChargePoint::get_evse_transaction_id(int32_t evse_id)
return evse.get_transaction()->transactionId.get();
}

AuthorizeResponse ChargePoint::validate_token(const IdToken id_token, const std::optional<CiString<5500>>& certificate,
AuthorizeResponse ChargePoint::validate_token(const IdToken id_token, const std::optional<CiString<10000>>& certificate,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO: find out implications for backwards compatibility with 2.0.1

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

accept

@@ -1929,8 +1929,8 @@ bool ChargePoint::is_evse_reserved_for_other(EvseInterface& evse, const IdToken&
const ConnectorStatusEnum status =
evse.get_connector(static_cast<int32_t>(i))->get_effective_connector_status();
if (status == ConnectorStatusEnum::Reserved) {
const std::optional<CiString<36>> groupIdToken =
group_id_token.has_value() ? group_id_token.value().idToken : std::optional<CiString<36>>{};
const std::optional<CiString<255>> groupIdToken =
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO: find out implications for backwards compatibility with 2.0.1

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

accept

@@ -2113,7 +2113,7 @@ void ChargePoint::notify_report_req(const int request_id, const std::vector<Repo
}
}

AuthorizeResponse ChargePoint::authorize_req(const IdToken id_token, const std::optional<CiString<5500>>& certificate,
AuthorizeResponse ChargePoint::authorize_req(const IdToken id_token, const std::optional<CiString<10000>>& certificate,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO: find out implications for backwards compatibility with 2.0.1

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

accept

@@ -102,7 +102,7 @@ void period_entry_t::init(const DateTime& in_start, int in_duration, const Charg
const auto start_tp = std::chrono::floor<seconds>(in_start.to_time_point());
start = std::move(DateTime(start_tp + seconds(in_period.startPeriod)));
end = std::move(DateTime(start_tp + seconds(in_duration)));
limit = in_period.limit;
limit = in_period.limit.value_or(0); // FIXME
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO: find out implications for backwards compatibility with 2.0.1
(limit became optional)

Comment on lines 452 to 465
} else if (candidate_period.limit.has_value()) {
const auto charge_point_max_phases = candidate_period.numberPhases.value_or(default_number_phases);

const auto period_max_phases = prevailing_period.numberPhases.value_or(default_number_phases);
adjusted_period.numberPhases = std::min(charge_point_max_phases, period_max_phases);

if (current_charging_rate_unit_enum == ChargingRateUnitEnum::A) {
if (candidate_period.limit < prevailing_period.limit) {
adjusted_period.limit = candidate_period.limit;
if (candidate_period.limit.value() < prevailing_period.limit.value_or(DEFAULT_LIMIT_AMPS)) {
adjusted_period.limit = candidate_period.limit.value();
}
} else {
const auto charge_point_limit_per_phase = candidate_period.limit / charge_point_max_phases;
const auto period_limit_per_phase = prevailing_period.limit / period_max_phases;
const auto charge_point_limit_per_phase = candidate_period.limit.value() / charge_point_max_phases;
const auto period_limit_per_phase = prevailing_period.limit.value_or(0) / period_max_phases; // FIXME

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO: find out implications for backwards compatibility with 2.0.1
(limit became optional)

Still a lot of failures, likely from the extension/modification if ChargingSchedulePerios (limit becoming optional)

Signed-off-by: Kai-Uwe Hermann <[email protected]>
…c-draft-messages

# Conflicts:
#	lib/ocpp/v201/charge_point.cpp
#	lib/ocpp/v201/smart_charging.cpp
#	tests/lib/ocpp/v201/mocks/smart_charging_handler_mock.hpp
#	tests/lib/ocpp/v201/test_charge_point.cpp

Signed-off-by: Kai-Uwe Hermann <[email protected]>
Signed-off-by: Kai-Uwe Hermann <[email protected]>
Signed-off-by: Kai-Uwe Hermann <[email protected]>
This was broken in an earlier attempt to adapt it to the optional "limit"

Signed-off-by: Kai-Uwe Hermann <[email protected]>
Signed-off-by: Kai-Uwe Hermann <[email protected]>
…c-draft-messages

# Conflicts:
#	lib/ocpp/v201/profile.cpp
#	tests/lib/ocpp/v201/test_charge_point.cpp
#	tests/lib/ocpp/v201/test_composite_schedule.cpp
#	tests/lib/ocpp/v201/test_database_handler.cpp
#	tests/lib/ocpp/v201/test_profile.cpp

Signed-off-by: Kai-Uwe Hermann <[email protected]>
@@ -74,8 +74,8 @@ struct Callbacks {
/// \return True if evse is reserved for the given id token / group id token, false if it is reserved for another
/// one.
///
std::function<bool(const int32_t evse_id, const CiString<36> idToken,
const std::optional<CiString<36>> groupIdToken)>
std::function<bool(const int32_t evse_id, const CiString<255> idToken,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be ok to accept larger tokens here. This is only an issue if e.g. OCTT tests for OCPP2.0.1 if we accept larger tokens.

std::optional<std::vector<MeterValue>> meterValue;
std::optional<bool> offline;
std::optional<int32_t> numberOfPhasesUsed;
std::optional<int32_t> cableMaxCurrent;
std::optional<float> cableMaxCurrent;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change doesnt seem to make a lot of sense. In transaction_event_req we could continue to use an int and make an implicit cast to float

We should make sure that the float is serialized to an int in 2.0.1 when transmitting to the CSMS.

struct AdditionalInfo {
CiString<36> additionalIdToken;
CiString<255> additionalIdToken;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Our best chance is to allow 255 here since we can then try to send to the CSMS. If the CSMS can handle it - fine. If it cant, we have at least tried and the CSMS will likely respond with a CALLERROR

@@ -34,8 +64,8 @@ void from_json(const json& j, AdditionalInfo& k);
std::ostream& operator<<(std::ostream& os, const AdditionalInfo& k);

struct IdToken {
CiString<36> idToken;
IdTokenEnum type;
CiString<255> idToken;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Our best chance is to allow 255 here since we can then try to send to the CSMS. If the CSMS can handle it - fine. If it cant, we have at least tried and the CSMS will likely respond with a CALLERROR

@@ -54,7 +84,7 @@ struct OCSPRequestData {
CiString<128> issuerNameHash;
CiString<128> issuerKeyHash;
CiString<40> serialNumber;
CiString<512> responderURL;
CiString<2000> responderURL;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same argument like with the id token. Lets allow the larger value here.

@@ -890,7 +1992,7 @@ void from_json(const json& j, SetMonitoringResult& k);
std::ostream& operator<<(std::ostream& os, const SetMonitoringResult& k);

struct SetVariableData {
CiString<1000> attributeValue;
CiString<2500> attributeValue;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Accept

@@ -943,7 +2132,7 @@ void from_json(const json& j, Transaction& k);
std::ostream& operator<<(std::ostream& os, const Transaction& k);

struct Firmware {
CiString<512> location;
CiString<2000> location;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Accept

@@ -792,7 +792,7 @@ std::optional<std::string> ChargePoint::get_evse_transaction_id(int32_t evse_id)
return evse.get_transaction()->transactionId.get();
}

AuthorizeResponse ChargePoint::validate_token(const IdToken id_token, const std::optional<CiString<5500>>& certificate,
AuthorizeResponse ChargePoint::validate_token(const IdToken id_token, const std::optional<CiString<10000>>& certificate,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

accept

@@ -1929,8 +1929,8 @@ bool ChargePoint::is_evse_reserved_for_other(EvseInterface& evse, const IdToken&
const ConnectorStatusEnum status =
evse.get_connector(static_cast<int32_t>(i))->get_effective_connector_status();
if (status == ConnectorStatusEnum::Reserved) {
const std::optional<CiString<36>> groupIdToken =
group_id_token.has_value() ? group_id_token.value().idToken : std::optional<CiString<36>>{};
const std::optional<CiString<255>> groupIdToken =
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

accept

@@ -2113,7 +2113,7 @@ void ChargePoint::notify_report_req(const int request_id, const std::vector<Repo
}
}

AuthorizeResponse ChargePoint::authorize_req(const IdToken id_token, const std::optional<CiString<5500>>& certificate,
AuthorizeResponse ChargePoint::authorize_req(const IdToken id_token, const std::optional<CiString<10000>>& certificate,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

accept

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

Successfully merging this pull request may close these issues.

2 participants