Skip to content

Commit

Permalink
Transaction event changes to get remote start / stop working and comp…
Browse files Browse the repository at this point in the history
…liant to octt (#138)

* Send a transaction event after every charging state changed. Store remote start id and  send trigger reason RemoteStart with the very first transaction event after the remote start request.
* Also add charging state to newly created transaction
* Add charging state to on_transaction_stopped
* Move remote start triggerreason up so it is also sent for a TransactionEventEnum::Started


Signed-off-by: Maaike Zijderveld, Alfen <[email protected]>
  • Loading branch information
maaikez authored Aug 17, 2023
1 parent 694ce69 commit 4660464
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 5 deletions.
4 changes: 3 additions & 1 deletion include/ocpp/v201/charge_point.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,8 @@ class ChargePoint : ocpp::ChargingStationBase {
data_transfer_callbacks;
std::mutex data_transfer_callbacks_mutex;

std::map<int32_t, std::pair<IdToken, int32_t>> remote_start_id_per_evse;

// timers
Everest::SteadyTimer heartbeat_timer;
Everest::SteadyTimer boot_notification_timer;
Expand Down Expand Up @@ -297,7 +299,7 @@ class ChargePoint : ocpp::ChargingStationBase {
/// \param signed_meter_value
void on_transaction_finished(const int32_t evse_id, const DateTime& timestamp, const MeterValue& meter_stop,
const ReasonEnum reason, const std::optional<std::string>& id_token,
const std::optional<std::string>& signed_meter_value);
const std::optional<std::string>& signed_meter_value, const ChargingStateEnum charging_state);

/// \brief Event handler that should be called when a session has finished
/// \param evse_id
Expand Down
53 changes: 49 additions & 4 deletions lib/ocpp/v201/charge_point.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ void ChargePoint::on_transaction_started(const int32_t evse_id, const int32_t co
ControllerComponentVariables::SampledDataTxStartedMeasurands)));

Transaction transaction{enhanced_transaction->transactionId};
transaction.chargingState = charging_state;
if (remote_start_id.has_value()) {
transaction.remoteStartId = remote_start_id.value();
enhanced_transaction->remoteStartId = remote_start_id.value();
Expand All @@ -162,8 +163,10 @@ void ChargePoint::on_transaction_started(const int32_t evse_id, const int32_t co
void ChargePoint::on_transaction_finished(const int32_t evse_id, const DateTime& timestamp,
const MeterValue& meter_stop, const ReasonEnum reason,
const std::optional<std::string>& id_token,
const std::optional<std::string>& signed_meter_value) {
const auto& enhanced_transaction = this->evses.at(evse_id)->get_transaction();
const std::optional<std::string>& signed_meter_value,
const ChargingStateEnum charging_state) {
auto& enhanced_transaction = this->evses.at(evse_id)->get_transaction();
enhanced_transaction->chargingState = charging_state;
if (enhanced_transaction == nullptr) {
EVLOG_warning << "Received notification of finished transaction while no transaction was active";
return;
Expand Down Expand Up @@ -231,6 +234,14 @@ bool ChargePoint::on_charging_state_changed(const uint32_t evse_id,
this->evses.at(static_cast<int32_t>(evse_id))->get_transaction();
if (transaction != nullptr) {
transaction->chargingState = charging_state;
this->transaction_event_req(
TransactionEventEnum::Updated, DateTime(),
transaction->get_transaction(),
TriggerReasonEnum::ChargingStateChanged,
transaction->get_seq_no(), std::nullopt,
this->evses.at(static_cast<int32_t>(evse_id))->get_evse_info(),
std::nullopt, std::nullopt, std::nullopt, std::nullopt,
std::nullopt);
return true;
} else {
EVLOG_warning
Expand Down Expand Up @@ -845,12 +856,43 @@ void ChargePoint::transaction_event_req(const TransactionEventEnum& event_type,

ocpp::Call<TransactionEventRequest> call(req, this->message_queue->createMessageId());

// Check if id token is in the remote start map, because when a remote
// start request is done, the first transaction event request should
// always contain trigger reason 'RemoteStart'.
auto it = std::find_if(
remote_start_id_per_evse.begin(), remote_start_id_per_evse.end(),
[&id_token, &evse](const std::pair<int32_t, std::pair<IdToken, int32_t>>& remote_start_per_evse) {
if (id_token.has_value() &&
remote_start_per_evse.second.first.idToken == id_token.value().idToken) {

if (remote_start_per_evse.first == 0) {
return true;
}

if (evse.has_value() &&
evse.value().id == remote_start_per_evse.first) {
return true;
}
}
return false;
}
);

if (it != remote_start_id_per_evse.end()) {
// Found remote start. Set remote start id and the trigger reason.
call.msg.triggerReason = TriggerReasonEnum::RemoteStart;
call.msg.transactionInfo.remoteStartId = it->second.second;

remote_start_id_per_evse.erase(it);
}

if (event_type == TransactionEventEnum::Started) {
if (!evse.has_value() or !id_token.has_value()) {
EVLOG_error << "Request to send TransactionEvent(Started) without given evse or id_token. These properties "
"are required for this eventType \"Started\"!";
return;
}

auto future = this->send_async<TransactionEventRequest>(call);
const auto enhanced_message = future.get();
if (enhanced_message.messageType == MessageType::TransactionEventResponse) {
Expand Down Expand Up @@ -1246,12 +1288,15 @@ void ChargePoint::handle_remote_start_transaction_request(Call<RequestStartTrans
} else {
// F02: No active transaction yet and there is an available connector, so just send 'accepted'.
response.status = RequestStartStopStatusEnum::Accepted;

remote_start_id_per_evse[evse_id] = {msg.idToken, msg.remoteStartId};
}
}
} else {
// F01.FR.07 RequestStartTransactionRequest does not contain an evseId.The Charging Station MAY reject the
// 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 )
// station to accept no evse id. If so: add token and remote start id for evse id 0 to remote_start_id_per_evse,
// so we know for '0' it means 'all evse id's').
EVLOG_warning << "No evse id given. Can not remote start transaction.";
}

Expand Down

0 comments on commit 4660464

Please sign in to comment.