Files
cariflex/tools/openocpp/include/openocpp/module/heartbeat_module.h
Eric F d398a6ced2 Add extracted tools: CitrineOS, OpenOCPP, ShapeShifter
- 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
2026-06-08 00:38:27 -04:00

130 lines
5.1 KiB
C++

#ifndef CHARGELAB_OPEN_FIRMWARE_HEARTBEAT_MODULE_H
#define CHARGELAB_OPEN_FIRMWARE_HEARTBEAT_MODULE_H
#include "openocpp/module/common_templates.h"
#include "openocpp/interface/component/system_interface.h"
#include "openocpp/common/operation_holder.h"
#include "openocpp/common/settings.h"
#include <utility>
namespace chargelab {
class HeartbeatModule : public ServiceStatefulGeneral {
public:
HeartbeatModule(
std::shared_ptr<Settings> settings,
std::shared_ptr<SystemInterface> const& system_interface
)
: settings_(std::move(settings)),
system_interface_(system_interface),
pending_heartbeat_req_ {system_interface}
{
}
~HeartbeatModule() override {
CHARGELAB_LOG_MESSAGE(debug) << "Deleting HeartbeatModule";
}
public:
void runStep(ocpp1_6::OcppRemote &remote) override {
if (!pending_heartbeat_req_.wasIdleFor(settings_->HeartbeatInterval.getValue())) {
if (!force_heartbeat_ || pending_heartbeat_req_.operationInProgress())
return;
}
pending_heartbeat_req_.setWithTimeout(
settings_->DefaultMessageTimeout.getValue(),
remote.sendHeartbeatReq({})
);
force_heartbeat_ = false;
}
void onHeartbeatRsp(
const std::string &unique_id,
const std::variant<ocpp1_6::HeartbeatRsp, ocpp1_6::CallError> &rsp
) override {
if (pending_heartbeat_req_ == unique_id) {
pending_heartbeat_req_ = kNoOperation;
if (std::holds_alternative<ocpp1_6::HeartbeatRsp>(rsp)) {
auto const& value = std::get<ocpp1_6::HeartbeatRsp>(rsp);
auto const& ts = value.currentTime.getTimestamp();
if (ts.has_value()) {
system_interface_->setSystemClock(ts.value());
} else {
CHARGELAB_LOG_MESSAGE(warning) << "Invalid Heartbeat response timestamp: "
<< value.currentTime;
}
} else {
CHARGELAB_LOG_MESSAGE(warning) << "Error response to Hearbeat request: " << std::get<ocpp1_6::CallError> (rsp);
}
}
}
void runStep(ocpp2_0::OcppRemote &remote) override {
if (!pending_heartbeat_req_.wasIdleFor(settings_->HeartbeatInterval.getValue())) {
if (!force_heartbeat_ || pending_heartbeat_req_.operationInProgress())
return;
}
pending_heartbeat_req_.setWithTimeout(
settings_->DefaultMessageTimeout.getValue(),
remote.sendHeartbeatReq({})
);
force_heartbeat_ = false;
}
void onHeartbeatRsp(
const std::string &unique_id,
const std::variant<ocpp2_0::HeartbeatResponse, ocpp2_0::CallError> &rsp
) override {
if (pending_heartbeat_req_ == unique_id) {
pending_heartbeat_req_ = kNoOperation;
if (std::holds_alternative<ocpp2_0::HeartbeatResponse>(rsp)) {
auto const& value = std::get<ocpp2_0::HeartbeatResponse>(rsp);
auto const& ts = value.currentTime.getTimestamp();
if (ts.has_value()) {
system_interface_->setSystemClock(ts.value());
} else {
CHARGELAB_LOG_MESSAGE(warning) << "Invalid Heartbeat response timestamp: "
<< value.currentTime;
}
} else {
CHARGELAB_LOG_MESSAGE(warning) << "Error response to Hearbeat request: " << std::get<ocpp2_0::CallError> (rsp);
}
}
}
std::optional<ocpp1_6::ResponseToRequest<ocpp1_6::TriggerMessageRsp>>
onTriggerMessageReq(const ocpp1_6::TriggerMessageReq &req) override {
if (req.requestedMessage == ocpp1_6::MessageTrigger::kHeartbeat) {
force_heartbeat_ = true;
return ocpp1_6::TriggerMessageRsp {ocpp1_6::TriggerMessageStatus::kAccepted};
}
return std::nullopt;
}
std::optional<ocpp2_0::ResponseToRequest<ocpp2_0::TriggerMessageResponse>>
onTriggerMessageReq(const ocpp2_0::TriggerMessageRequest &request) override {
if (request.requestedMessage == ocpp2_0::MessageTriggerEnumType::kHeartbeat) {
force_heartbeat_ = true;
return ocpp2_0::TriggerMessageResponse {ocpp2_0::TriggerMessageStatusEnumType::kAccepted};
}
return std::nullopt;
}
private:
std::shared_ptr<Settings> settings_;
std::shared_ptr<SystemInterface> system_interface_;
OperationHolder<std::string> pending_heartbeat_req_;
bool force_heartbeat_ = false;
};
}
#endif //CHARGELAB_OPEN_FIRMWARE_HEARTBEAT_MODULE_H