Skip to content

Commit 3faaf95

Browse files
committed
Reservation Handling in EvseManager (#1067)
Changed reservation handling in EvseManager: * Signaling reservation end after Signaling Disabled event. This allows OCPPs state machine to move from Reserved->Unavailable instead of Reserved->Available->Unavailable * Fixed issue that reservation was cancelled on every SessionFinished event: Canceling reservation in handle_withdraw_authorization when charger was authorized before * When a reservation is cancelled and it is a global reservation, all evse's that were reserved because of global reservations should go to available again. --------- Signed-off-by: Piet Gömpel <pietgoempel@gmail.com> Signed-off-by: Maaike Zijderveld, iolar <git.mail@iolar.nl> Co-authored-by: Maaike Zijderveld, iolar <git.mail@iolar.nl> Change libocpp dependency version to 0.23.2 which includes associated fixes for this release branch Signed-off-by: Kai-Uwe Hermann <kai-uwe.hermann@pionix.de>
1 parent 3d78cad commit 3faaf95

File tree

5 files changed

+53
-11
lines changed

5 files changed

+53
-11
lines changed

dependencies.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ libevse-security:
6767
# OCPP
6868
libocpp:
6969
git: https://github.com/EVerest/libocpp.git
70-
git_tag: v0.23.1
70+
git_tag: v0.23.2
7171
cmake_condition: "EVEREST_DEPENDENCY_ENABLED_LIBOCPP"
7272
# Josev
7373
Josev:

modules/Auth/lib/AuthHandler.cpp

+5-1
Original file line numberDiff line numberDiff line change
@@ -602,6 +602,10 @@ void AuthHandler::call_reservation_cancelled(const int32_t reservation_id,
602602
}
603603

604604
this->reservation_cancelled_callback(evse_id, reservation_id, reason, send_reservation_update);
605+
606+
// If this was a global reservation or there are global reservations which made evse's go to reserved because of
607+
// this reservation, they should be cancelled.
608+
this->check_evse_reserved_and_send_updates();
605609
}
606610

607611
void AuthHandler::handle_permanent_fault_raised(const int evse_id, const int32_t connector_id) {
@@ -734,7 +738,7 @@ void AuthHandler::handle_session_event(const int evse_id, const SessionEvent& ev
734738
// When reservation is started or ended, check if the number of reservations match the number of evses and
735739
// send 'reserved' notifications to the evse manager accordingly if needed.
736740
if (check_reservations) {
737-
check_evse_reserved_and_send_updates();
741+
this->check_evse_reserved_and_send_updates();
738742
}
739743
}
740744

modules/Auth/tests/reservation_tests.cpp

+37
Original file line numberDiff line numberDiff line change
@@ -1415,4 +1415,41 @@ TEST_F(ReservationHandlerTest, check_evses_to_reserve_scenario_5) {
14151415
EXPECT_TRUE(s.reserved.empty());
14161416
}
14171417

1418+
TEST_F(ReservationHandlerTest, check_evses_to_reserve_scenario_6) {
1419+
add_connector(0, 0, types::evse_manager::ConnectorTypeEnum::cCCS2, this->evses);
1420+
add_connector(0, 1, types::evse_manager::ConnectorTypeEnum::cType2, this->evses);
1421+
add_connector(1, 0, types::evse_manager::ConnectorTypeEnum::cCCS2, this->evses);
1422+
add_connector(1, 1, types::evse_manager::ConnectorTypeEnum::cType2, this->evses);
1423+
1424+
ReservationEvseStatus s = r.check_number_global_reservations_match_number_available_evses();
1425+
1426+
EXPECT_TRUE(s.available.empty());
1427+
EXPECT_TRUE(s.reserved.empty());
1428+
1429+
Reservation reservation1 = create_reservation(types::evse_manager::ConnectorTypeEnum::cCCS2);
1430+
EXPECT_EQ(r.make_reservation(std::nullopt, reservation1), ReservationResult::Accepted);
1431+
1432+
s = r.check_number_global_reservations_match_number_available_evses();
1433+
1434+
EXPECT_TRUE(s.available.empty());
1435+
EXPECT_TRUE(s.reserved.empty());
1436+
1437+
EXPECT_EQ(r.make_reservation(std::nullopt, create_reservation(types::evse_manager::ConnectorTypeEnum::cCCS2)),
1438+
ReservationResult::Accepted);
1439+
1440+
s = r.check_number_global_reservations_match_number_available_evses();
1441+
1442+
EXPECT_TRUE(s.available.empty());
1443+
ASSERT_EQ(s.reserved.size(), 2);
1444+
EXPECT_EQ(s.reserved.count(0), 1);
1445+
EXPECT_EQ(s.reserved.count(1), 1);
1446+
1447+
r.cancel_reservation(reservation1.reservation_id, false, types::reservation::ReservationEndReason::Cancelled);
1448+
1449+
s = r.check_number_global_reservations_match_number_available_evses();
1450+
1451+
EXPECT_EQ(s.available.size(), 2);
1452+
EXPECT_EQ(s.reserved.size(), 0);
1453+
}
1454+
14181455
} // namespace module

modules/EvseManager/EvseManager.cpp

-4
Original file line numberDiff line numberDiff line change
@@ -837,10 +837,6 @@ void EvseManager::ready() {
837837
error_handling->signal_error.connect([this](bool prevents_charging) { cancel_reservation(true); });
838838

839839
charger->signal_simple_event.connect([this](types::evse_manager::SessionEventEnum s) {
840-
// Cancel reservations if charger is disabled
841-
if (s == types::evse_manager::SessionEventEnum::Disabled) {
842-
cancel_reservation(true);
843-
}
844840
if (s == types::evse_manager::SessionEventEnum::SessionFinished) {
845841
// Reset EV information on Session start and end
846842
ev_info = types::evse_manager::EVInfo();

modules/EvseManager/evse/evse_managerImpl.cpp

+10-5
Original file line numberDiff line numberDiff line change
@@ -292,11 +292,6 @@ void evse_managerImpl::ready() {
292292
session_finished.meter_value = mod->get_latest_powermeter_data_billing();
293293
se.session_finished = session_finished;
294294
session_log.evse(false, fmt::format("Session Finished"));
295-
// Cancel reservation, reservation might be stored when swiping rfid, but timed out, so we should not
296-
// set the reservation id here.
297-
if (mod->is_reserved()) {
298-
mod->cancel_reservation(true);
299-
}
300295
session_log.stopSession();
301296
mod->telemetry.publish("session", "events",
302297
{{"timestamp", Everest::Date::to_rfc3339(date::utc_clock::now())},
@@ -332,6 +327,11 @@ void evse_managerImpl::ready() {
332327
this->mod->selected_protocol = "Unknown";
333328
}
334329

330+
// Cancel reservations if charger is disabled
331+
if (mod->is_reserved() and e == types::evse_manager::SessionEventEnum::Disabled) {
332+
mod->cancel_reservation(true);
333+
}
334+
335335
publish_selected_protocol(this->mod->selected_protocol);
336336
});
337337

@@ -421,6 +421,11 @@ void evse_managerImpl::handle_authorize_response(types::authorization::ProvidedI
421421
};
422422

423423
void evse_managerImpl::handle_withdraw_authorization() {
424+
// reservation_id might have been stored when reserved id token has been authorized, but timed out, so
425+
// we can consider the reservation as consumed
426+
if (mod->charger->get_authorized_eim() and mod->is_reserved()) {
427+
mod->cancel_reservation(true);
428+
}
424429
this->mod->charger->deauthorize();
425430
};
426431

0 commit comments

Comments
 (0)