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
This commit is contained in:
Eric F
2026-06-08 00:38:27 -04:00
parent 468cfeaa50
commit d398a6ced2
7326 changed files with 1177561 additions and 7 deletions

View File

@@ -0,0 +1,183 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright Pionix GmbH and Contributors to EVerest
#include "ocppImpl.hpp"
#include "everest/conversions/ocpp/evse_security_ocpp.hpp"
#include "ocpp/v2/ocpp_types.hpp"
#include <conversions.hpp>
#include <everest/conversions/ocpp/ocpp_conversions.hpp>
namespace {
inline module::ocpp_generic::ocppImpl::MonitorListEntry convert(const types::ocpp::ComponentVariable& cv) {
using namespace module::conversions;
return {to_ocpp_component(cv.component), to_ocpp_variable(cv.variable)};
}
} // namespace
namespace module {
namespace ocpp_generic {
void ocppImpl::init() {
}
void ocppImpl::ready() {
}
bool ocppImpl::handle_stop() {
// Disconnects the websocket connection and stops the OCPP communication.
// No OCPP messages will be stored and sent after a restart.
bool result{false};
if (mod->charge_point == nullptr) {
EVLOG_warning << "ChargePoint not initialized, cannot handle stop command";
} else {
std::lock_guard lock(chargepoint_state_mutex);
mod->charging_schedules_timer_stop();
mod->charge_point->stop();
result = true;
}
return result;
}
bool ocppImpl::handle_restart() {
// Connects the websocket and enables OCPP communication after a previous
// stop call.
bool result{false};
if (mod->charge_point == nullptr) {
EVLOG_warning << "ChargePoint not initialized, cannot handle restart command";
} else {
std::lock_guard lock(chargepoint_state_mutex);
mod->charging_schedules_timer_start();
mod->charge_point->start(ocpp::v2::BootReasonEnum::ApplicationReset, true);
result = true;
}
return result;
}
void ocppImpl::handle_security_event(types::ocpp::SecurityEvent& event) {
if (this->mod->charge_point == nullptr) {
EVLOG_warning << "ChargePoint not yet initialized. Cannot handle security event.";
return;
}
std::optional<ocpp::DateTime> timestamp;
if (event.timestamp.has_value()) {
timestamp = ocpp_conversions::to_ocpp_datetime_or_now(event.timestamp.value());
}
this->mod->charge_point->on_security_event(event.type, event.info, event.critical, timestamp);
}
std::vector<types::ocpp::GetVariableResult>
ocppImpl::handle_get_variables(std::vector<types::ocpp::GetVariableRequest>& requests) {
if (this->mod->charge_point == nullptr) {
EVLOG_warning << "ChargePoint not yet initialized. Cannot handle get variables request.";
std::vector<types::ocpp::GetVariableResult> results;
for (const auto& req : requests) {
types::ocpp::GetVariableResult result;
result.status = types::ocpp::GetVariableStatusEnumType::Rejected;
result.component_variable.component = req.component_variable.component;
result.component_variable.variable = req.component_variable.variable;
result.attribute_type = req.attribute_type;
results.push_back(result);
}
return results;
}
const auto _requests = conversions::to_ocpp_get_variable_data_vector(requests);
const auto response = this->mod->charge_point->get_variables(_requests);
return conversions::to_everest_get_variable_result_vector(response);
}
std::vector<types::ocpp::SetVariableResult>
ocppImpl::handle_set_variables(std::vector<types::ocpp::SetVariableRequest>& requests, std::string& source) {
if (this->mod->charge_point == nullptr) {
EVLOG_warning << "ChargePoint not yet initialized. Cannot handle set variables request.";
std::vector<types::ocpp::SetVariableResult> results;
for (const auto& req : requests) {
types::ocpp::SetVariableResult result;
result.status = types::ocpp::SetVariableStatusEnumType ::Rejected;
result.component_variable.component = req.component_variable.component;
result.component_variable.variable = req.component_variable.variable;
result.attribute_type = req.attribute_type;
results.push_back(result);
}
return results;
}
const auto _requests = conversions::to_ocpp_set_variable_data_vector(requests);
const auto response_map = this->mod->charge_point->set_variables(_requests, source);
std::vector<ocpp::v2::SetVariableResult> response;
for (const auto& [set_variable_data, set_variable_result] : response_map) {
response.push_back(set_variable_result);
}
return conversions::to_everest_set_variable_result_vector(response);
}
types::ocpp::ChangeAvailabilityResponse
ocppImpl::handle_change_availability(types::ocpp::ChangeAvailabilityRequest& request) {
using ChangeAvailabilityStatusEnum = ocpp::v2::ChangeAvailabilityStatusEnum;
ocpp::v2::ChangeAvailabilityResponse result;
result.status = ChangeAvailabilityStatusEnum::Rejected;
if (mod->charge_point == nullptr) {
EVLOG_warning << "ChargePoint not initialized, cannot handle change availability command";
} else {
const auto ocpp_request = conversions::to_ocpp_change_availability_request(request);
result = mod->charge_point->on_change_availability(ocpp_request);
}
return conversions::to_everest_change_availability_response(result);
}
void ocppImpl::handle_monitor_variables(std::vector<types::ocpp::ComponentVariable>& component_variables) {
using namespace ocpp::v2;
if (mod->charge_point == nullptr) {
EVLOG_warning << "ChargePoint not initialized, cannot handle monitor variables command";
} else {
std::lock_guard lock(monitor_list_mutex);
if (monitor_list.empty()) {
// register a handler
mod->charge_point->register_variable_listener(
[this](auto&, const Component& component, const Variable& variable, auto&, auto&, auto&,
const std::string& value) { variable_changed(component, variable, value); });
}
// add variables to monitor list
for (const auto& cv : component_variables) {
// failures to insert are likely to be the same variable being
// requested again
(void)monitor_list.insert(convert(cv));
}
}
}
void ocppImpl::variable_changed(const ocpp::v2::Component& component, const ocpp::v2::Variable& variable,
const std::string& value) {
using namespace conversions;
MonitorListEntry entry{component, variable};
bool publish;
{
std::lock_guard lock(monitor_list_mutex);
const auto it = monitor_list.find(entry);
publish = it != monitor_list.end();
}
if (publish) {
// monitor entry exists - publish
types::ocpp::EventData event_data;
event_data.component_variable.component = to_everest_component(component);
event_data.component_variable.variable = to_everest_variable(variable);
event_data.event_id = 0;
event_data.timestamp = ocpp::DateTime();
event_data.trigger = types::ocpp::EventTriggerEnum::Delta;
event_data.actual_value = value;
event_data.event_notification_type = types::ocpp::EventNotificationType::CustomMonitor;
publish_event_data(event_data);
}
}
} // namespace ocpp_generic
} // namespace module