diff --git a/include/ocpp/common/message_queue.hpp b/include/ocpp/common/message_queue.hpp index d5726976d..a46a6f6cd 100644 --- a/include/ocpp/common/message_queue.hpp +++ b/include/ocpp/common/message_queue.hpp @@ -580,7 +580,8 @@ template class MessageQueue { } /// \brief Gets all persisted messages of normal message queue and persisted message queue from the database - void get_persisted_messages_from_db(bool ignore_security_event_notifications = false) { + void get_persisted_messages_from_db(std::vector& transactionInFlight, + bool ignore_security_event_notifications = false) { std::vector queue_types = {QueueType::Normal, QueueType::Transaction}; // do for Normal and Transaction queue for (const auto queue_type : queue_types) { @@ -610,6 +611,8 @@ template class MessageQueue { normal_message_queue.push_back(message); } else if (queue_type == QueueType::Transaction) { transaction_message_queue.push_back(message); + Call call = persisted_message.json_message; + transactionInFlight.push_back(call.msg.transactionId); } } } diff --git a/include/ocpp/v16/charge_point_impl.hpp b/include/ocpp/v16/charge_point_impl.hpp index 000c246fe..b6a82433e 100644 --- a/include/ocpp/v16/charge_point_impl.hpp +++ b/include/ocpp/v16/charge_point_impl.hpp @@ -247,7 +247,8 @@ class ChargePointImpl : ocpp::ChargingStationBase { /// resuming_session_ids contain the internal session_id, this function attempts to resume the transaction by /// initializing it and adding it to the \ref transaction_handler. If the session_id is not part of \p /// resuming_session_ids a StopTransaction.req is initiated to properly close the transaction. - void try_resume_transactions(const std::set& resuming_session_ids); + void try_resume_transactions(const std::vector transactionIdsInFlight, + const std::set& resuming_session_ids); void stop_all_transactions(); void stop_all_transactions(Reason reason); bool validate_against_cache_entries(CiString<20> id_tag); diff --git a/lib/ocpp/v16/charge_point_impl.cpp b/lib/ocpp/v16/charge_point_impl.cpp index 8f8a74868..f123cbea6 100644 --- a/lib/ocpp/v16/charge_point_impl.cpp +++ b/lib/ocpp/v16/charge_point_impl.cpp @@ -478,7 +478,8 @@ void ChargePointImpl::update_clock_aligned_meter_values_interval() { } } -void ChargePointImpl::try_resume_transactions(const std::set& resuming_session_ids) { +void ChargePointImpl::try_resume_transactions(const std::vector& transactionIdsInFlight, + const std::set& resuming_session_ids) { std::vector transactions; try { transactions = this->database_handler->get_transactions(true); @@ -514,10 +515,15 @@ void ChargePointImpl::try_resume_transactions(const std::set& resum EVLOG_info << "Trying to resume transaction with session_id: " << transaction_entry.session_id << " and transaction_id: " << transaction_entry.transaction_id; - - if (this->message_queue->contains_stop_transaction_message(transaction_entry.transaction_id)) { + // The case is possible that the transacion_id is already earesed from this->message_queue, + // then the else case enters and the transaction is stopped again. To avoid, that the transactiondIdsInFlight + // are additionally checked. + if (this->message_queue->contains_stop_transaction_message(transaction_entry.transaction_id) || + std::find(transactionIdsInFlight.begin(), transactionIdsInFlight.end(), transaction_entry.transaction_id) != + transactionIdsInFlight.end()) { // StopTransaction.req is already queued for the transaction in the database, so we mark the transaction as // stopped and wait for the StopTransaction.conf + EVLOG_info << "Is already sent"; transaction->set_finished(); this->transaction_handler->add_stopped_transaction(transaction->get_connector()); } else { @@ -1074,10 +1080,12 @@ bool ChargePointImpl::start(const std::map& connector_st this->init_state_machine(connector_status_map); this->init_websocket(); this->websocket->connect(); + std::vector transactionIdsInFlight; // push transaction messages including SecurityEventNotification.req onto the message queue - this->message_queue->get_persisted_messages_from_db(this->configuration->getDisableSecurityEventNotifications()); + this->message_queue->get_persisted_messages_from_db(transactionIdsInFlight, + this->configuration->getDisableSecurityEventNotifications()); this->boot_notification(); - this->try_resume_transactions(resuming_session_ids); + this->try_resume_transactions(transactionIdsInFlight, resuming_session_ids); this->call_set_connection_timeout(); switch (bootreason) {