Skip to content

Commit

Permalink
Merge branch 'main' into feature/756-refactor-naming-of-component-sch…
Browse files Browse the repository at this point in the history
…emas
  • Loading branch information
maaikez committed Sep 23, 2024
2 parents 64dad58 + 2647ee4 commit dcb0b05
Show file tree
Hide file tree
Showing 33 changed files with 723 additions and 745 deletions.
6 changes: 3 additions & 3 deletions .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
* @pietfried @hikinggrass @marcemmers @maaikez

/config/v16/ @pietfried @hikinggrass
/include/ocpp/v16/ @pietfried @hikinggrass
/lib/ocpp/v16/ @pietfried @hikinggrass
/config/v16/ @pietfried @hikinggrass @maaikez
/include/ocpp/v16/ @pietfried @hikinggrass @maaikez
/lib/ocpp/v16/ @pietfried @hikinggrass @maaikez

/.github/ @pietfried @hikinggrass
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.14)

project(ocpp
VERSION 0.16.2
VERSION 0.17.0
DESCRIPTION "A C++ implementation of the Open Charge Point Protocol"
LANGUAGES CXX
)
Expand Down
16 changes: 8 additions & 8 deletions doc/ocpp_201_status.md
Original file line number Diff line number Diff line change
Expand Up @@ -1266,7 +1266,7 @@ This document contains the status of which OCPP 2.0.1 numbered functional requir
| K01.FR.40 || `Absolute`/`Recurring` profiles without `startSchedule` fields are rejected. |
| K01.FR.41 || `Relative` profiles with `startSchedule` fields are rejected. |
| K01.FR.42 | ⛽️ | |
| K01.FR.43 | | Open question to OCA - https://oca.causewaynow.com/wg/OCA-TWG/mail/thread/4254 |
| K01.FR.43 | | Open question to OCA - https://oca.causewaynow.com/wg/OCA-TWG/mail/thread/4254 |
| K01.FR.44 || We reject invalid profiles instead of modifying and accepting them. |
| K01.FR.45 || We reject invalid profiles instead of modifying and accepting them. |
| K01.FR.46 | ⛽️ | K08 |
Expand All @@ -1285,8 +1285,8 @@ This document contains the status of which OCPP 2.0.1 numbered functional requir
| K02.FR.01 || |
| K02.FR.02 || This should be handled by the user of `libocpp`. |
| K02.FR.03 || |
| K02.FR.04 | | |
| K02.FR.05 | | |
| K02.FR.04 | | |
| K02.FR.05 | | |
| K02.FR.06 | | The same as K01.FR.21 |
| K02.FR.07 | | The same as K01.FR.22 |
| K02.FR.08 | | |
Expand All @@ -1308,7 +1308,7 @@ This document contains the status of which OCPP 2.0.1 numbered functional requir

| ID | Status | Remark |
|-----------|--------|--------------------------------------------------|
| K04.FR.01 | | |
| K04.FR.01 | | |
| K04.FR.02 | | |
| K04.FR.03 || |
| K04.FR.04 | | The same as K01.FR.21 |
Expand All @@ -1319,10 +1319,10 @@ This document contains the status of which OCPP 2.0.1 numbered functional requir
| ID | Status | Remark |
|-----------|--------|--------|
| K05.FR.01 || |
| K05.FR.02 | | |
| K05.FR.03 | | |
| K05.FR.04 | | |
| K05.FR.05 | | |
| K05.FR.02 | | |
| K05.FR.03 | | |
| K05.FR.04 | | |
| K05.FR.05 | | |

## SmartCharging - Offline Behavior Smart Charging During Transaction

Expand Down
2 changes: 0 additions & 2 deletions include/ocpp/common/utils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@ namespace ocpp {
/// \brief Case insensitive compare for a case insensitive (Ci)String
bool iequals(const std::string& lhs, const std::string rhs);

std::vector<std::string> get_vector_from_csv(const std::string& csv_str);

bool is_integer(const std::string& value);
std::tuple<bool, int> is_positive_integer(const std::string& value);
bool is_decimal_number(const std::string& value);
Expand Down
12 changes: 9 additions & 3 deletions include/ocpp/v16/charge_point.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -311,11 +311,17 @@ class ChargePoint {
/// be called when an EV is plugged in but the authorization is present within the specified ConnectionTimeout
void on_plugin_timeout(int32_t connector);

// \brief Notifies chargepoint that a SecurityEvent occurs. This will send a SecurityEventNotification.req to the
/// \brief Notifies chargepoint that a SecurityEvent occurs. This will send a SecurityEventNotification.req to the
/// CSMS
/// \param type type of the security event
/// \param event_type type of the security event
/// \param tech_info additional info of the security event
void on_security_event(const std::string& type, const std::string& tech_info);
/// \param critical if set this overwrites the default criticality recommended in the OCPP 1.6 security whitepaper.
/// A critical security event is transmitted as a message to the CSMS, a non-critical one is just written to the
/// security log
/// \param timestamp when this security event occured, if absent the current datetime is assumed
void on_security_event(const CiString<50>& event_type, const std::optional<CiString<255>>& tech_info,
const std::optional<bool>& critical = std::nullopt,
const std::optional<DateTime>& timestamp = std::nullopt);

/// \brief Handles an internal ChangeAvailabilityRequest (in the same way as if it was emitted by the CSMS).
/// \param request
Expand Down
15 changes: 11 additions & 4 deletions include/ocpp/v16/charge_point_impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -337,8 +337,9 @@ class ChargePointImpl : ocpp::ChargingStationBase {
void handleInstallCertificateRequest(Call<InstallCertificateRequest> call);
void handleGetLogRequest(Call<GetLogRequest> call);
void handleSignedUpdateFirmware(Call<SignedUpdateFirmwareRequest> call);
void securityEventNotification(const std::string& type, const std::string& tech_info,
const bool triggered_internally);
void securityEventNotification(const CiString<50>& event_type, const std::optional<CiString<255>>& tech_info,
const bool triggered_internally, const std::optional<bool>& critical = std::nullopt,
const std::optional<DateTime>& timestamp = std::nullopt);
void switchSecurityProfile(int32_t new_security_profile, int32_t max_connection_attempts);
// Local Authorization List profile
void handleSendLocalListRequest(Call<SendLocalListRequest> call);
Expand Down Expand Up @@ -647,9 +648,15 @@ class ChargePointImpl : ocpp::ChargingStationBase {

/// \brief Notifies chargepoint that a SecurityEvent occurs. This will send a SecurityEventNotification.req to the
/// CSMS
/// \param type type of the security event
/// \param event_type type of the security event
/// \param tech_info additional info of the security event
void on_security_event(const std::string& type, const std::string& tech_info);
/// \param critical if set this overwrites the default criticality recommended in the OCPP 1.6 security whitepaper.
/// A critical security event is transmitted as a message to the CSMS, a non-critical one is just written to the
/// security log
/// \param timestamp when this security event occured, if absent the current datetime is assumed
void on_security_event(const CiString<50>& event_type, const std::optional<CiString<255>>& tech_info,
const std::optional<bool>& critical = std::nullopt,
const std::optional<DateTime>& timestamp = std::nullopt);

/// \brief Handles an internal ChangeAvailabilityRequest (in the same way as if it was emitted by the CSMS).
/// \param request
Expand Down
22 changes: 11 additions & 11 deletions include/ocpp/v16/utils.hpp
Original file line number Diff line number Diff line change
@@ -1,28 +1,28 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright 2020 - 2024 Pionix GmbH and Contributors to EVerest
#ifndef V16_UTILS_HPP
#define V16_UTILS_HPP

#include <ocpp/common/call_types.hpp>
#include <ocpp/v16/messages/StopTransaction.hpp>
#include <ocpp/v16/ocpp_types.hpp>
#include <ocpp/v16/types.hpp>

namespace ocpp {
namespace v16 {
namespace utils {

size_t get_message_size(const ocpp::Call<StopTransactionRequest>& call) {
return json(call).at(CALL_PAYLOAD).dump().length();
}
size_t get_message_size(const ocpp::Call<StopTransactionRequest>& call);

/// \brief Drops every second entry from transactionData as long as the message size of the \p call is greater than the
/// \p max_message_size
void drop_transaction_data(size_t max_message_size, ocpp::Call<StopTransactionRequest>& call) {
auto& transaction_data = call.msg.transactionData.value();
while (get_message_size(call) > max_message_size && transaction_data.size() > 2) {
for (size_t i = 1; i < transaction_data.size() - 1; i = i + 2) {
transaction_data.erase(transaction_data.begin() + i);
}
}
}
void drop_transaction_data(size_t max_message_size, ocpp::Call<StopTransactionRequest>& call);

/// \brief Determines if a given \p security_event is critical as defined in the OCPP 1.6 security whitepaper
bool is_critical(const std::string& security_event);

} // namespace utils
} // namespace v16
} // namespace ocpp

#endif
10 changes: 7 additions & 3 deletions include/ocpp/v201/charge_point.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -352,8 +352,10 @@ class ChargePointInterface {
/// \param critical if set this overwrites the default criticality recommended in the OCPP 2.0.1 appendix. A
/// critical security event is transmitted as a message to the CSMS, a non-critical one is just written to the
/// security log
/// \param timestamp when this security event occured, if absent the current datetime is assumed
virtual void on_security_event(const CiString<50>& event_type, const std::optional<CiString<255>>& tech_info,
const std::optional<bool>& critical = std::nullopt) = 0;
const std::optional<bool>& critical = std::nullopt,
const std::optional<DateTime>& timestamp = std::nullopt) = 0;

/// \brief Event handler that will update the variable internally when it has been changed on the fly.
/// \param set_variable_data contains data of the variable to set
Expand Down Expand Up @@ -662,7 +664,8 @@ class ChargePoint : public ChargePointInterface, private ocpp::ChargingStationBa

// Functional Block A: Security
void security_event_notification_req(const CiString<50>& event_type, const std::optional<CiString<255>>& tech_info,
const bool triggered_internally, const bool critical);
const bool triggered_internally, const bool critical,
const std::optional<DateTime>& timestamp = std::nullopt);
void sign_certificate_req(const ocpp::CertificateSigningUseEnum& certificate_signing_use,
const bool initiated_by_trigger_message = false);

Expand Down Expand Up @@ -944,7 +947,8 @@ class ChargePoint : public ChargePointInterface, private ocpp::ChargingStationBa
void on_log_status_notification(UploadLogStatusEnum status, int32_t requestId) override;

void on_security_event(const CiString<50>& event_type, const std::optional<CiString<255>>& tech_info,
const std::optional<bool>& critical = std::nullopt) override;
const std::optional<bool>& critical = std::nullopt,
const std::optional<DateTime>& timestamp = std::nullopt) override;

void on_variable_changed(const SetVariableData& set_variable_data) override;

Expand Down
8 changes: 7 additions & 1 deletion include/ocpp/v201/database_handler.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@
namespace ocpp {
namespace v201 {

/// \brief Helper class for retrieving authorization cache entries from the database
struct AuthorizationCacheEntry {
IdTokenInfo id_token_info;
DateTime last_used;
};

class DatabaseHandler : public common::DatabaseHandlerCommon {
private:
void init_sql() override;
Expand Down Expand Up @@ -55,7 +61,7 @@ class DatabaseHandler : public common::DatabaseHandlerCommon {
/// \brief Gets cache entry for given \p id_token_hash if present
/// \param id_token_hash
/// \return
std::optional<IdTokenInfo> authorization_cache_get_entry(const std::string& id_token_hash);
std::optional<AuthorizationCacheEntry> authorization_cache_get_entry(const std::string& id_token_hash);

/// \brief Deletes the cache entry for the given \p id_token_hash
/// \param id_token_hash
Expand Down
46 changes: 40 additions & 6 deletions include/ocpp/v201/smart_charging.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ enum class ProfileValidationResultEnum {
ChargingStationMaxProfileCannotBeRelative,
ChargingStationMaxProfileEvseIdGreaterThanZero,
DuplicateTxDefaultProfileFound,
DuplicateProfileValidityPeriod
DuplicateProfileValidityPeriod,
RequestStartTransactionNonTxProfile
};

/// \brief This enhances the ChargingProfile type by additional paramaters that are required in the
Expand All @@ -60,6 +61,13 @@ struct ReportedChargingProfile {
}
};

/// \brief This is used to associate charging profiles with a source.
/// Based on the source a different validation path can be taken.
enum class AddChargingProfileSource {
SetChargingProfile,
RequestStartTransactionRequest
};

namespace conversions {
/// \brief Converts the given ProfileValidationResultEnum \p e to human readable string
/// \returns a string representation of the ProfileValidationResultEnum
Expand All @@ -76,9 +84,15 @@ class SmartChargingHandlerInterface {
public:
virtual ~SmartChargingHandlerInterface() = default;

virtual SetChargingProfileResponse validate_and_add_profile(ChargingProfile& profile, int32_t evse_id) = 0;
virtual SetChargingProfileResponse validate_and_add_profile(
ChargingProfile& profile, int32_t evse_id,
AddChargingProfileSource source_of_request = AddChargingProfileSource::SetChargingProfile) = 0;

virtual void delete_transaction_tx_profiles(const std::string& transaction_id) = 0;

virtual ProfileValidationResultEnum validate_profile(ChargingProfile& profile, int32_t evse_id) = 0;
virtual ProfileValidationResultEnum
validate_profile(ChargingProfile& profile, int32_t evse_id,
AddChargingProfileSource source_of_request = AddChargingProfileSource::SetChargingProfile) = 0;

virtual SetChargingProfileResponse add_profile(ChargingProfile& profile, int32_t evse_id) = 0;

Expand Down Expand Up @@ -109,18 +123,27 @@ class SmartChargingHandler : public SmartChargingHandlerInterface {
SmartChargingHandler(EvseManagerInterface& evse_manager, std::shared_ptr<DeviceModel>& device_model,
std::shared_ptr<ocpp::v201::DatabaseHandler> database_handler);

///
/// \brief for the given \p transaction_id removes the associated charging profile.
///
void delete_transaction_tx_profiles(const std::string& transaction_id) override;

///
/// \brief validates the given \p profile according to the specification,
/// adding it to our stored list of profiles if valid.
///
SetChargingProfileResponse validate_and_add_profile(ChargingProfile& profile, int32_t evse_id) override;
SetChargingProfileResponse validate_and_add_profile(
ChargingProfile& profile, int32_t evse_id,
AddChargingProfileSource source_of_request = AddChargingProfileSource::SetChargingProfile) override;

///
/// \brief validates the given \p profile according to the specification.
/// If a profile does not have validFrom or validTo set, we conform the values
/// to a representation that fits the spec.
///
ProfileValidationResultEnum validate_profile(ChargingProfile& profile, int32_t evse_id) override;
ProfileValidationResultEnum validate_profile(
ChargingProfile& profile, int32_t evse_id,
AddChargingProfileSource source_of_request = AddChargingProfileSource::SetChargingProfile) override;

///
/// \brief Adds a given \p profile and associated \p evse_id to our stored list of profiles
Expand Down Expand Up @@ -176,14 +199,20 @@ class SmartChargingHandler : public SmartChargingHandlerInterface {
///
/// \brief validates the given \p profile according to the specification
///
ProfileValidationResultEnum validate_tx_profile(const ChargingProfile& profile, int32_t evse_id) const;
ProfileValidationResultEnum validate_tx_profile(
const ChargingProfile& profile, int32_t evse_id,
AddChargingProfileSource source_of_request = AddChargingProfileSource::SetChargingProfile) const;

/// \brief validates that the given \p profile has valid charging schedules.
/// If a profiles charging schedule period does not have a valid numberPhases,
/// we set it to the default value (3).
ProfileValidationResultEnum validate_profile_schedules(ChargingProfile& profile,
std::optional<EvseInterface*> evse_opt = std::nullopt) const;

/// \brief validates that the given \p profile from a RequestStartTransactionRequest is of the correct type
/// TxProfile
ProfileValidationResultEnum validate_request_start_transaction_profile(const ChargingProfile& profile) const;

///
/// \brief Checks a given \p profile and associated \p evse_id validFrom and validTo range
/// This method assumes that the existing profile will have dates set for validFrom and validTo
Expand All @@ -196,6 +225,11 @@ class SmartChargingHandler : public SmartChargingHandlerInterface {
///
ProfileValidationResultEnum verify_no_conflicting_external_constraints_id(const ChargingProfile& profile) const;

///
/// \brief Retrieves existing profiles on the EVSE \p evse_id
///
std::vector<ChargingProfile> get_profiles_on_evse(int32_t evse_id) const;

private:
std::vector<ChargingProfile> get_station_wide_profiles() const;
std::vector<ChargingProfile> get_evse_specific_tx_default_profiles() const;
Expand Down
1 change: 1 addition & 0 deletions lib/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ if(LIBOCPP_ENABLE_V16)
ocpp/v16/ocpp_enums.cpp
ocpp/v16/ocpp_types.cpp
ocpp/v16/types.cpp
ocpp/v16/utils.cpp
)
add_subdirectory(ocpp/v16/messages)
endif()
Expand Down
10 changes: 0 additions & 10 deletions lib/ocpp/common/utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,6 @@ bool iequals(const std::string& lhs, const std::string rhs) {
return boost::algorithm::iequals(lhs, rhs);
}

std::vector<std::string> get_vector_from_csv(const std::string& csv_str) {
std::vector<std::string> csv;
std::string str;
std::stringstream ss(csv_str);
while (std::getline(ss, str, ',')) {
csv.push_back(str);
}
return csv;
}

bool is_integer(const std::string& value) {
if (value.empty()) {
return false;
Expand Down
5 changes: 3 additions & 2 deletions lib/ocpp/v16/charge_point.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -172,8 +172,9 @@ void ChargePoint::on_plugin_timeout(int32_t connector) {
this->charge_point->on_plugin_timeout(connector);
}

void ChargePoint::on_security_event(const std::string& type, const std::string& tech_info) {
this->charge_point->on_security_event(type, tech_info);
void ChargePoint::on_security_event(const CiString<50>& event_type, const std::optional<CiString<255>>& tech_info,
const std::optional<bool>& critical, const std::optional<DateTime>& timestamp) {
this->charge_point->on_security_event(event_type, tech_info, critical, timestamp);
}

ChangeAvailabilityResponse ChargePoint::on_change_availability(const ChangeAvailabilityRequest& request) {
Expand Down
2 changes: 1 addition & 1 deletion lib/ocpp/v16/charge_point_configuration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ std::string to_csl(const std::vector<std::string>& vec) {
}

void ChargePointConfiguration::init_supported_measurands() {
const auto _supported_measurands = ocpp::get_vector_from_csv(this->config["Internal"]["SupportedMeasurands"]);
const auto _supported_measurands = ocpp::split_string(this->config["Internal"]["SupportedMeasurands"], ',');
for (const auto& measurand : _supported_measurands) {
try {
const auto _measurand = conversions::string_to_measurand(measurand);
Expand Down
Loading

0 comments on commit dcb0b05

Please sign in to comment.