-
Notifications
You must be signed in to change notification settings - Fork 74
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: API module; delay sending commands to EvseManager until it is re…
…ady (#856) * fix: API module; delay sending commands to EvseManager until it is ready Signed-off-by: James Chapman <james.chapman@pionix.de> * fix: allow for 128 EvseManagers Signed-off-by: James Chapman <james.chapman@pionix.de> * fix: approach updated to allow multiple `ready` events from the same EVSE manager Signed-off-by: James Chapman <james.chapman@pionix.de> * fix: update to latest main and fix compile/merge issue Signed-off-by: James Chapman <james.chapman@pionix.de> --------- Signed-off-by: James Chapman <james.chapman@pionix.de>
- Loading branch information
Showing
8 changed files
with
363 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
// SPDX-License-Identifier: Apache-2.0 | ||
// Copyright Pionix GmbH and Contributors to EVerest | ||
|
||
#include "StartupMonitor.hpp" | ||
#include <everest/logging.hpp> | ||
|
||
#include <memory> | ||
|
||
namespace module { | ||
|
||
bool StartupMonitor::check_ready() { | ||
bool result{false}; | ||
if (ready_set) { | ||
result = ready_set->size() >= n_managers; | ||
} | ||
return result; | ||
} | ||
|
||
bool StartupMonitor::set_total(std::uint8_t total) { | ||
bool result{true}; | ||
{ | ||
std::lock_guard lock(mutex); | ||
if (!ready_set) { | ||
n_managers = total; | ||
if (total == 0) { | ||
managers_ready = true; | ||
} else { | ||
managers_ready = false; | ||
ready_set = std::make_unique<ready_t>(); | ||
} | ||
} else { | ||
// already set | ||
EVLOG_error << "Invalid attempt to set number of EVSE managers"; | ||
result = false; | ||
} | ||
} | ||
if (total == 0) { | ||
cv.notify_all(); | ||
} | ||
return result; | ||
} | ||
|
||
void StartupMonitor::wait_ready() { | ||
std::unique_lock lock(mutex); | ||
cv.wait(lock, [this] { return this->managers_ready; }); | ||
} | ||
|
||
bool StartupMonitor::notify_ready(const std::string& evse_manager_id) { | ||
bool result{true}; | ||
bool notify{false}; | ||
{ | ||
std::lock_guard lock(mutex); | ||
if (ready_set) { | ||
ready_set->insert(evse_manager_id); | ||
notify = StartupMonitor::check_ready(); | ||
if (notify) { | ||
managers_ready = true; | ||
n_managers = 0; | ||
ready_set->clear(); // reclaim memory | ||
} | ||
} else { | ||
result = false; | ||
if (managers_ready) { | ||
EVLOG_warning << "EVSE manager ready after complete"; | ||
} else { | ||
EVLOG_error << "EVSE manager ready before total number set"; | ||
} | ||
} | ||
} | ||
if (notify) { | ||
cv.notify_all(); | ||
} | ||
return result; | ||
} | ||
|
||
} // namespace module |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
// SPDX-License-Identifier: Apache-2.0 | ||
// Copyright Pionix GmbH and Contributors to EVerest | ||
#ifndef STARTUPMONITOR_HPP | ||
#define STARTUPMONITOR_HPP | ||
|
||
#include <condition_variable> | ||
#include <cstdint> | ||
#include <memory> | ||
#include <mutex> | ||
#include <set> | ||
#include <string> | ||
|
||
namespace module { | ||
|
||
/** | ||
* \brief collect ready responses from all EVSE managers | ||
* | ||
* Provides a mechanism for API code to wait for all EVSE managers to be ready. | ||
* Every EVSE manager is expected to set a `ready` variable to true. This class | ||
* collects the IDs of EVSE managers to check that the expected number are | ||
* ready before allowing API calls to proceed. | ||
* | ||
* \note an EVSE manager is not expected to set `ready` more than once, however | ||
* this class manages this so that the `ready` is only counted once. | ||
*/ | ||
class StartupMonitor { | ||
private: | ||
using ready_t = std::set<std::string>; | ||
|
||
std::condition_variable cv; | ||
std::mutex mutex; | ||
|
||
protected: | ||
std::unique_ptr<ready_t> ready_set; //!< set of received ready responses | ||
std::uint16_t n_managers{0}; //!< total number of EVSE managers | ||
bool managers_ready{false}; //!< all EVSE managers are ready | ||
|
||
/** | ||
* \brief check whether all ready responses have been received | ||
* \returns true when the ready set contains at least n_managers responses | ||
*/ | ||
bool check_ready(); | ||
|
||
public: | ||
/** | ||
* \brief set the total number of EVSE managers | ||
* \param[in] total the number of EVSE managers | ||
* \returns false if the total has already been set | ||
*/ | ||
bool set_total(std::uint8_t total); | ||
|
||
/** | ||
* \brief wait for all EVSE managers to be ready | ||
*/ | ||
void wait_ready(); | ||
|
||
/** | ||
* \brief notify that a specific EVSE manager is ready | ||
* \param[in] evse_manager_id the ID of the EVSE manager | ||
* \returns false if the total has not been set | ||
* \note notify_ready() may be called multiple times with the same evse_manager_id | ||
*/ | ||
bool notify_ready(const std::string& evse_manager_id); | ||
}; | ||
|
||
} // namespace module | ||
|
||
#endif // STARTUPMONITOR_HPP |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
set(TEST_TARGET_NAME ${PROJECT_NAME}_API_tests) | ||
add_executable(${TEST_TARGET_NAME}) | ||
|
||
add_dependencies(${TEST_TARGET_NAME} ${MODULE_NAME}) | ||
|
||
target_include_directories(${TEST_TARGET_NAME} PRIVATE | ||
. .. ../../../tests/include | ||
) | ||
|
||
target_sources(${TEST_TARGET_NAME} PRIVATE | ||
StartupMonitor_test.cpp | ||
../StartupMonitor.cpp | ||
) | ||
|
||
target_link_libraries(${TEST_TARGET_NAME} PRIVATE | ||
GTest::gtest_main | ||
) | ||
|
||
add_test(${TEST_TARGET_NAME} ${TEST_TARGET_NAME}) |
Oops, something went wrong.