- CitrineOS core extracted (CSMS OCPP 2.0.1) - OpenOCPP extracted (firmware OCPP 1.6J/2.0.1) - ShapeShifter library installed (pip install -e) - ShapeShifter specification extracted - EVerest extracted TODO updated with progress
76 lines
2.2 KiB
C++
76 lines
2.2 KiB
C++
// SPDX-License-Identifier: Apache-2.0
|
|
// Copyright 2023 - 2023 Pionix GmbH and Contributors to EVerest
|
|
#include "fsm_controller.hpp"
|
|
|
|
#include <everest/slac/fsm/ev/states/others.hpp>
|
|
|
|
FSMController::FSMController(slac::fsm::ev::Context& context) : ctx(context){};
|
|
|
|
void FSMController::signal_new_slac_message(slac::messages::HomeplugMessage& msg) {
|
|
if (running == false) {
|
|
return;
|
|
}
|
|
{
|
|
const std::lock_guard<std::mutex> feed_lck(feed_mtx);
|
|
ctx.slac_message = msg;
|
|
fsm.handle_event(slac::fsm::ev::Event::SLAC_MESSAGE);
|
|
}
|
|
|
|
new_event = true;
|
|
new_event_cv.notify_all();
|
|
}
|
|
|
|
void FSMController::signal_reset() {
|
|
signal_simple_event(slac::fsm::ev::Event::RESET);
|
|
}
|
|
|
|
void FSMController::signal_trigger_matching() {
|
|
signal_simple_event(slac::fsm::ev::Event::TRIGGER_MATCHING);
|
|
}
|
|
|
|
bool FSMController::signal_simple_event(slac::fsm::ev::Event ev) {
|
|
const std::lock_guard<std::mutex> feed_lck(feed_mtx);
|
|
auto event_result = fsm.handle_event(ev);
|
|
|
|
new_event = true;
|
|
new_event_cv.notify_all();
|
|
|
|
return event_result == fsm::HandleEventResult::SUCCESS;
|
|
}
|
|
|
|
void FSMController::run() {
|
|
ctx.log_info("Starting the SLAC state machine");
|
|
|
|
fsm.reset<slac::fsm::ev::ResetState>(ctx);
|
|
|
|
std::unique_lock<std::mutex> feed_lck(feed_mtx);
|
|
|
|
running = true;
|
|
|
|
while (true) {
|
|
auto feed_result = fsm.feed();
|
|
|
|
if (feed_result.transition()) {
|
|
// call immediately again
|
|
continue;
|
|
} else if (feed_result.internal_error() || feed_result.unhandled_event()) {
|
|
// FIXME (aw): would need to log here!
|
|
} else if (feed_result.has_value() == true) {
|
|
const auto timeout = *feed_result;
|
|
if (timeout == 0) {
|
|
// call feed directly again
|
|
continue;
|
|
}
|
|
new_event_cv.wait_for(feed_lck, std::chrono::milliseconds(timeout), [this] { return new_event; });
|
|
} else {
|
|
// nothing happened, no return value -> wait for new event
|
|
new_event_cv.wait(feed_lck, [this] { return new_event; });
|
|
}
|
|
|
|
if (new_event) {
|
|
// we got a new event, reset it and let run feed again
|
|
new_event = false;
|
|
}
|
|
}
|
|
}
|