Skip to content

Commit

Permalink
Some changes to check if there is a reservation for an evse / id toke…
Browse files Browse the repository at this point in the history
…n (needed for remote start).

Signed-off-by: Maaike Zijderveld, iolar <[email protected]>
  • Loading branch information
maaikez committed Nov 22, 2024
1 parent 6c3a3ec commit 7840131
Show file tree
Hide file tree
Showing 9 changed files with 48 additions and 36 deletions.
9 changes: 9 additions & 0 deletions include/ocpp/common/types.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -834,6 +834,15 @@ struct CompositeScheduleDefaultLimits {
int32_t number_phases;
};

/// \brief Status of a reservation check.
enum class ReservationCheckStatus {
NotReserved, ///< @brief No reservation of this evse and / or id token
ReservedForToken, ///< @brief Reservation for this token.
ReservedForOtherTokenAndParentToken, ///< @brief Reserved for other token and parent token.
ReservedForOtherTokenAndHasNoParentToken, ///< @brief Reserved for other token and reservation has no parent token.
ReservedForOtherTokenAndHasParentToken, ///< @brief Reserved for other token but reservation has a parent token.
};

} // namespace ocpp

#endif
2 changes: 1 addition & 1 deletion include/ocpp/v16/charge_point.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -563,7 +563,7 @@ class ChargePoint {
/// \param callback
/// \ingroup ocpp16_callbacks
void register_is_token_reserved_for_connector_callback(
const std::function<bool(const int32_t connector, const std::string& id_token)>& callback);
const std::function<ReservationCheckStatus(const int32_t connector, const std::string& id_token)>& callback);

/// \brief Registers a callback function for the session cost datatransfer message (California Pricing Requirements)
/// \param session_cost_callback The callback.
Expand Down
5 changes: 3 additions & 2 deletions include/ocpp/v16/charge_point_impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,8 @@ class ChargePointImpl : ocpp::ChargingStationBase {
transaction_updated_callback;
std::function<void(const int32_t connector, const std::string& session_id, const int32_t transaction_id)>
transaction_stopped_callback;
std::function<bool(const int32_t connector, const std::string& id_token)> is_token_reserved_for_connector_callback;
std::function<ocpp::ReservationCheckStatus(const int32_t connector, const std::string& id_token)>
is_token_reserved_for_connector_callback;

// iso15118 callback
std::function<void(const int32_t connector, const ocpp::v201::Get15118EVCertificateResponse& certificate_response,
Expand Down Expand Up @@ -865,7 +866,7 @@ class ChargePointImpl : ocpp::ChargingStationBase {
/// received.
/// \param callback
void register_is_token_reserved_for_connector_callback(
const std::function<bool(const int32_t connector, const std::string& id_token)>& callback);
const std::function<ReservationCheckStatus(const int32_t connector, const std::string& id_token)>& callback);

void register_session_cost_callback(
const std::function<DataTransferResponse(const RunningCost& running_cost, const uint32_t number_of_decimals)>&
Expand Down
12 changes: 3 additions & 9 deletions include/ocpp/v201/charge_point.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -568,16 +568,10 @@ class ChargePoint : public ChargePointInterface, private ocpp::ChargingStationBa
/// \param evse The evse id that must be checked. Reservation will be checked for all connectors.
/// \param id_token The id token to check if it is reserved for that token.
/// \param group_id_token The group id token to check if it is reserved for that group id.
/// \return True when one of the EVSE connectors is reserved for another id token or group id token than the given
/// tokens.
/// If id_token is different than reserved id_token, but group_id_token is equal to reserved group_id_token,
/// returns true.
/// If both are different, returns true.
/// If id_token is equal to reserved id_token or group_id_token is equal, return false.
/// If there is no reservation, return false.
/// \return The status of the reservation for this evse, id token and group id token.
///
bool is_evse_reserved_for_other(EvseInterface& evse, const IdToken& id_token,
const std::optional<IdToken>& group_id_token) const;
ReservationCheckStatus is_evse_reserved_for_other(EvseInterface& evse, const IdToken& id_token,
const std::optional<IdToken>& group_id_token) const;

///
/// \brief Check if one of the connectors of the evse is available (both connectors faulted or unavailable or on of
Expand Down
8 changes: 4 additions & 4 deletions include/ocpp/v201/charge_point_callbacks.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,13 +79,13 @@ struct Callbacks {
std::function<RequestStartStopStatusEnum(const RequestStartTransactionRequest& request,
const bool authorize_remote_start)>
remote_start_transaction_callback;

///
/// \brief Check if the current reservation for the given evse id is made for the id token / group id token.
/// \return True if evse is reserved for the given id token / group id token, false if it is reserved for another
/// one.
/// \return The reservation check status of this evse / id token.
///
std::function<bool(const int32_t evse_id, const CiString<36> idToken,
const std::optional<CiString<36>> groupIdToken)>
std::function<ocpp::ReservationCheckStatus(const int32_t evse_id, const CiString<36> idToken,
const std::optional<CiString<36>> groupIdToken)>
is_reservation_for_token_callback;
std::function<UpdateFirmwareResponse(const UpdateFirmwareRequest& request)> update_firmware_request_callback;
// callback to be called when a variable has been changed by the CSMS
Expand Down
2 changes: 1 addition & 1 deletion lib/ocpp/v16/charge_point.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,7 @@ void ChargePoint::register_security_event_callback(
}

void ChargePoint::register_is_token_reserved_for_connector_callback(
const std::function<bool(const int32_t connector, const std::string& id_token)>& callback) {
const std::function<ocpp::ReservationCheckStatus(const int32_t connector, const std::string& id_token)>& callback) {
this->charge_point->register_is_token_reserved_for_connector_callback(callback);
}

Expand Down
21 changes: 14 additions & 7 deletions lib/ocpp/v16/charge_point_impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1957,11 +1957,18 @@ void ChargePointImpl::handleRemoteStartTransactionRequest(ocpp::Call<RemoteStart
continue;
}

if (this->is_token_reserved_for_connector_callback != nullptr &&
this->status->get_state(connector) == ChargePointStatus::Reserved &&
!this->is_token_reserved_for_connector_callback(connector, call.msg.idTag.get())) {
obtainable = false;
continue;
if (this->is_token_reserved_for_connector_callback != nullptr) {
const ocpp::ReservationCheckStatus reservation_status =
is_token_reserved_for_connector_callback(connector, call.msg.idTag.get());

const bool is_reserved =
(reservation_status == ocpp::ReservationCheckStatus::ReservedForOtherTokenAndHasNoParentToken ||
reservation_status == ocpp::ReservationCheckStatus::ReservedForOtherTokenAndParentToken);

if (this->status->get_state(connector) == ChargePointStatus::Reserved && is_reserved) {
obtainable = false;
continue;
}
}

if (obtainable) {
Expand Down Expand Up @@ -2018,7 +2025,7 @@ void ChargePointImpl::handleRemoteStartTransactionRequest(ocpp::Call<RemoteStart
} else {
this->provide_token_callback(call.msg.idTag.get(), referenced_connectors, true); // prevalidated
}
};
}
}

bool ChargePointImpl::validate_against_cache_entries(CiString<20> id_tag) {
Expand Down Expand Up @@ -4490,7 +4497,7 @@ void ChargePointImpl::register_security_event_callback(
}

void ChargePointImpl::register_is_token_reserved_for_connector_callback(
const std::function<bool(const int32_t connector, const std::string& id_token)>& callback) {
const std::function<ocpp::ReservationCheckStatus(const int32_t connector, const std::string& id_token)>& callback) {
this->is_token_reserved_for_connector_callback = callback;
}

Expand Down
21 changes: 11 additions & 10 deletions lib/ocpp/v201/charge_point.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1968,17 +1968,13 @@ std::optional<int32_t> ChargePoint::get_transaction_evseid(const CiString<36>& t
return std::nullopt;
}

bool ChargePoint::is_evse_reserved_for_other(EvseInterface& evse, const IdToken& id_token,
const std::optional<IdToken>& group_id_token) const {
const uint32_t connectors = evse.get_number_of_connectors();
ocpp::ReservationCheckStatus
ChargePoint::is_evse_reserved_for_other(EvseInterface& evse, const IdToken& id_token,
const std::optional<IdToken>& group_id_token) const {
const std::optional<CiString<36>> groupIdToken =
group_id_token.has_value() ? group_id_token.value().idToken : std::optional<CiString<36>>{};

if (!callbacks.is_reservation_for_token_callback(evse.get_id(), id_token.idToken, groupIdToken)) {
return true;
}

return false;
return callbacks.is_reservation_for_token_callback(evse.get_id(), id_token.idToken, groupIdToken);
}

bool ChargePoint::is_evse_connector_available(EvseInterface& evse) const {
Expand Down Expand Up @@ -3184,9 +3180,14 @@ void ChargePoint::handle_remote_start_transaction_request(Call<RequestStartTrans

// When available but there was a reservation for another token id or group token id:
// send rejected (F01.FR.21 & F01.FR.22)
const bool reserved = is_evse_reserved_for_other(evse, call.msg.idToken, call.msg.groupIdToken);
ocpp::ReservationCheckStatus reservation_status =
is_evse_reserved_for_other(evse, call.msg.idToken, call.msg.groupIdToken);

const bool is_reserved =
(reservation_status == ocpp::ReservationCheckStatus::ReservedForOtherTokenAndParentToken ||
reservation_status == ocpp::ReservationCheckStatus::ReservedForOtherTokenAndHasNoParentToken);

if (!available or reserved) {
if (!available or is_reserved) {
// Note: we only support TxStartPoint PowerPathClosed, so we did not implement starting a
// transaction first (and send TransactionEventRequest (eventType = Started). Only if a transaction
// is authorized, a TransactionEventRequest will be sent. Because of this, F01.FR.13 is not
Expand Down
4 changes: 2 additions & 2 deletions tests/lib/ocpp/v201/test_charge_point.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -183,8 +183,8 @@ class ChargePointCommonTestFixtureV201 : public DatabaseTestingUtils {
testing::MockFunction<RequestStartStopStatusEnum(const RequestStartTransactionRequest& request,
const bool authorize_remote_start)>
remote_start_transaction_callback_mock;
testing::MockFunction<bool(const int32_t evse_id, const CiString<36> idToken,
const std::optional<CiString<36>> groupIdToken)>
testing::MockFunction<ocpp::ReservationCheckStatus(const int32_t evse_id, const CiString<36> idToken,
const std::optional<CiString<36>> groupIdToken)>
is_reservation_for_token_callback_mock;
testing::MockFunction<UpdateFirmwareResponse(const UpdateFirmwareRequest& request)>
update_firmware_request_callback_mock;
Expand Down

0 comments on commit 7840131

Please sign in to comment.