Skip to content

Commit

Permalink
Add group id token to transaction to be able to check for a reservati…
Browse files Browse the repository at this point in the history
…on with remote start / stop transaction.

Signed-off-by: Maaike Zijderveld, Alfen <[email protected]>
  • Loading branch information
Maaike Zijderveld, Alfen committed Jul 4, 2023
1 parent c44545d commit 17823d5
Show file tree
Hide file tree
Showing 5 changed files with 16 additions and 10 deletions.
3 changes: 2 additions & 1 deletion include/ocpp/v201/charge_point.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -196,10 +196,11 @@ class ChargePoint : ocpp::ChargingStationBase {
/// \param timestamp
/// \param meter_start
/// \param id_token
/// \param group_id_token Optional group id token
/// \param reservation_id
void on_transaction_started(const int32_t evse_id, const int32_t connector_id, const std::string& session_id,
const DateTime& timestamp, const MeterValue& meter_start, const IdToken& id_token,
const std::optional<int32_t>& reservation_id);
const std::optional<IdToken> &group_id_token, const std::optional<int32_t>& reservation_id);

/// \brief Event handler that should be called when a transaction has finished
/// \param evse_id
Expand Down
3 changes: 2 additions & 1 deletion include/ocpp/v201/evse.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,12 @@ class Evse {
/// \param timestamp timestamp of the start of the transaction
/// \param meter_start start meter value of the transaction
/// \param id_token id_token with which the transaction was authorized / started
/// \param group_id_token optional group id_token
/// \param reservation optional reservation_id if evse was reserved
/// \param sampled_data_tx_updated_interval Interval between sampling of metering (or other) data, intended to be
/// transmitted via TransactionEventRequest (eventType = Updated) messages
void open_transaction(const std::string& transaction_id, const int32_t connector_id, const DateTime& timestamp,
const MeterValue& meter_start, const IdToken& id_token,
const MeterValue& meter_start, const IdToken& id_token, const std::optional<IdToken> &group_id_token,
const std::optional<int32_t> reservation_id,
const int32_t sampled_data_tx_updated_interval);

Expand Down
1 change: 1 addition & 0 deletions include/ocpp/v201/transaction.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ namespace v201 {
struct EnhancedTransaction : public Transaction {
std::vector<MeterValue> meter_values;
IdToken id_token;
std::optional<IdToken> group_id_token;
std::optional<int32_t> reservation_id;
int32_t seq_no = 0;
int32_t get_seq_no();
Expand Down
17 changes: 9 additions & 8 deletions lib/ocpp/v201/charge_point.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,10 +85,11 @@ void ChargePoint::on_session_started(const int32_t evse_id, const int32_t connec
void ChargePoint::on_transaction_started(const int32_t evse_id, const int32_t connector_id,
const std::string& session_id, const DateTime& timestamp,
const MeterValue& meter_start, const IdToken& id_token,
const std::optional<IdToken>& group_id_token,
const std::optional<int32_t>& reservation_id) {

this->evses.at(evse_id)->open_transaction(session_id, connector_id, timestamp, meter_start, id_token,
reservation_id,
group_id_token, reservation_id,
this->device_model_manager->get_sampled_data_tx_updated_interval());
const auto& enhanced_transaction = this->evses.at(evse_id)->get_transaction();
const auto meter_value = utils::get_meter_value_with_measurands_applied(
Expand Down Expand Up @@ -443,9 +444,9 @@ bool ChargePoint::is_evse_connector_reserved_not_available(const std::unique_ptr
const CiString<36>& transaction_id_token = evse->get_transaction()->id_token.idToken;
const CiString<36>& call_id_token = id_token.idToken;
if (transaction_id_token != call_id_token &&
(group_id_token.has_value() && // TODO mz how does this group id token work?
group_id_token.value().idToken != transaction_id_token) // TODO mz get the group id token to compare
// with instead of transaction id token
(group_id_token.has_value() &&
evse->get_transaction()->group_id_token.has_value() &&
group_id_token.value().idToken != evse->get_transaction()->group_id_token.value().idToken)
) {
return true;
}
Expand Down Expand Up @@ -811,12 +812,12 @@ void ChargePoint::handle_remote_start_transaction_request(CallResult<RequestStar
const auto& evse = this->evses.at(evse_id);

if (evse != nullptr) {
// TODO mz F01.FR.26 If a Charging Station with support for Smart Charging receives a
// TODO F01.FR.26 If a Charging Station with support for Smart Charging receives a
// RequestStartTransactionRequest with an invalid ChargingProfile: The Charging Station SHALL respond with
// RequestStartTransactionResponse with status = Rejected and optionally with reasonCode = "InvalidProfile"
// or "InvalidSchedule".

// F01.FR.23: Faulted or unavailable. F01.FR.24: Occupied. Send rejected.
// F01.FR.23: Faulted or unavailable. F01.FR.24 / F02.FR.25: Occupied. Send rejected.
const bool available = is_evse_connector_available(evse);

// When available but there was a reservation for another token id or group token id:
Expand All @@ -825,13 +826,12 @@ void ChargePoint::handle_remote_start_transaction_request(CallResult<RequestStar
is_evse_connector_reserved_not_available(evse, call.msg.idToken, call.msg.groupIdToken);

if (!available || reserved) {
// TODO: When occupied and there is an active transaction: send rejected (F02.FR.25)

// 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 implemented as well, because
// in the current situation, this is an impossible state. (TODO: when more TxStartPoints are supported,
// add implementation for F01.FR.13 as well).
EVLOG_info << "Remote start transaction requested, but connector is not available or reserved.";
} else {
// F02: No active transaction yet and there is an available connector, so just send 'accepted'.
response.status = RequestStartStopStatusEnum::Accepted;
Expand All @@ -841,6 +841,7 @@ void ChargePoint::handle_remote_start_transaction_request(CallResult<RequestStar
// F01.FR.07 RequestStartTransactionRequest does not contain an evseId.The Charging Station MAY reject the
// RequestStartTransactionRequest. We do this for now (send rejected) (TODO: eventually support the charging
// station to )
EVLOG_warning << "No evse id given. Can not remote start transaction.";
}

const ocpp::CallResult<RequestStartTransactionResponse> call_result(response, call.uniqueId);
Expand Down
2 changes: 2 additions & 0 deletions lib/ocpp/v201/evse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ Everest::SteadyTimer& Evse::get_sampled_meter_values_timer() {

void Evse::open_transaction(const std::string& transaction_id, const int32_t connector_id, const DateTime& timestamp,
const MeterValue& meter_start, const IdToken& id_token,
const std::optional<IdToken>& group_id_token,
const std::optional<int32_t> reservation_id,
const int32_t sampled_data_tx_updated_interval) {
if (!this->id_connector_map.count(connector_id)) {
Expand All @@ -52,6 +53,7 @@ void Evse::open_transaction(const std::string& transaction_id, const int32_t con
this->transaction->transactionId = transaction_id;
this->transaction->reservation_id = reservation_id;
this->transaction->id_token = id_token;
this->transaction->group_id_token = group_id_token;

transaction->meter_values.push_back(meter_start);

Expand Down

0 comments on commit 17823d5

Please sign in to comment.