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:
@@ -0,0 +1,787 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright (C) 2022-2023 chargebyte GmbH
|
||||
// Copyright (C) 2022-2023 Contributors to EVerest
|
||||
#include "ISO15118_chargerImpl.hpp"
|
||||
#include "log.hpp"
|
||||
#include "v2g_ctx.hpp"
|
||||
#include <algorithm>
|
||||
|
||||
const std::string CERTS_SUB_DIR = "certs"; // relativ path of the certs
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
using BidiMode = types::iso15118::SaeJ2847BidiMode;
|
||||
|
||||
namespace module {
|
||||
namespace charger {
|
||||
|
||||
void ISO15118_chargerImpl::init() {
|
||||
if (!v2g_ctx) {
|
||||
dlog(DLOG_LEVEL_ERROR, "v2g_ctx not created");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Configure if_name and auth_mode */
|
||||
v2g_ctx->if_name = mod->config.device.data();
|
||||
dlog(DLOG_LEVEL_DEBUG, "if_name %s", v2g_ctx->if_name);
|
||||
v2g_ctx->proxy_if_name = mod->config.proxy_device.empty() ? nullptr : mod->config.proxy_device.data();
|
||||
|
||||
/* Configure tls_security */
|
||||
if (mod->config.tls_security == "force") {
|
||||
v2g_ctx->tls_security = TLS_SECURITY_FORCE;
|
||||
dlog(DLOG_LEVEL_DEBUG, "tls_security force");
|
||||
} else if (mod->config.tls_security == "allow") {
|
||||
v2g_ctx->tls_security = TLS_SECURITY_ALLOW;
|
||||
dlog(DLOG_LEVEL_DEBUG, "tls_security allow");
|
||||
} else {
|
||||
v2g_ctx->tls_security = TLS_SECURITY_PROHIBIT;
|
||||
dlog(DLOG_LEVEL_DEBUG, "tls_security prohibit");
|
||||
}
|
||||
|
||||
v2g_ctx->network_read_timeout_tls = mod->config.tls_timeout;
|
||||
|
||||
v2g_ctx->certs_path = mod->info.paths.etc / CERTS_SUB_DIR;
|
||||
|
||||
// Subscribe all vars
|
||||
mod->r_iso2->subscribe_supported_app_protocols_secc([this](const auto value) {
|
||||
if (auto merged = merge_supported_app_protocols(value, ProtocolSource::Iso2)) {
|
||||
publish_supported_app_protocols_secc(*merged);
|
||||
}
|
||||
});
|
||||
mod->r_iso2->subscribe_require_auth_eim([this]() {
|
||||
if (not mod->selected_iso20()) {
|
||||
publish_require_auth_eim(nullptr);
|
||||
}
|
||||
});
|
||||
mod->r_iso20->subscribe_require_auth_eim([this]() {
|
||||
if (mod->selected_iso20()) {
|
||||
publish_require_auth_eim(nullptr);
|
||||
}
|
||||
});
|
||||
|
||||
mod->r_iso2->subscribe_require_auth_pnc([this](const auto value) {
|
||||
if (not mod->selected_iso20()) {
|
||||
publish_require_auth_pnc(value);
|
||||
}
|
||||
});
|
||||
mod->r_iso20->subscribe_require_auth_pnc([this](const auto value) {
|
||||
if (mod->selected_iso20()) {
|
||||
publish_require_auth_pnc(value);
|
||||
}
|
||||
});
|
||||
|
||||
mod->r_iso2->subscribe_ac_close_contactor([this]() {
|
||||
if (not mod->selected_iso20()) {
|
||||
publish_ac_close_contactor(nullptr);
|
||||
}
|
||||
});
|
||||
mod->r_iso20->subscribe_ac_close_contactor([this]() {
|
||||
if (mod->selected_iso20()) {
|
||||
publish_ac_close_contactor(nullptr);
|
||||
}
|
||||
});
|
||||
|
||||
mod->r_iso2->subscribe_ac_open_contactor([this]() {
|
||||
if (not mod->selected_iso20()) {
|
||||
publish_ac_open_contactor(nullptr);
|
||||
}
|
||||
});
|
||||
mod->r_iso20->subscribe_supported_app_protocols_secc([this](const auto value) {
|
||||
if (auto merged = merge_supported_app_protocols(value, ProtocolSource::Iso20)) {
|
||||
publish_supported_app_protocols_secc(*merged);
|
||||
}
|
||||
});
|
||||
mod->r_iso20->subscribe_ac_open_contactor([this]() {
|
||||
if (mod->selected_iso20()) {
|
||||
publish_ac_open_contactor(nullptr);
|
||||
}
|
||||
});
|
||||
|
||||
mod->r_iso2->subscribe_start_cable_check([this]() {
|
||||
if (not mod->selected_iso20()) {
|
||||
publish_start_cable_check(nullptr);
|
||||
}
|
||||
});
|
||||
mod->r_iso20->subscribe_start_cable_check([this]() {
|
||||
if (mod->selected_iso20()) {
|
||||
publish_start_cable_check(nullptr);
|
||||
}
|
||||
});
|
||||
|
||||
mod->r_iso2->subscribe_start_pre_charge([this]() {
|
||||
if (not mod->selected_iso20()) {
|
||||
publish_start_pre_charge(nullptr);
|
||||
}
|
||||
});
|
||||
mod->r_iso20->subscribe_start_pre_charge([this]() {
|
||||
if (mod->selected_iso20()) {
|
||||
publish_start_pre_charge(nullptr);
|
||||
}
|
||||
});
|
||||
|
||||
mod->r_iso2->subscribe_dc_open_contactor([this]() {
|
||||
if (not mod->selected_iso20()) {
|
||||
publish_dc_open_contactor(nullptr);
|
||||
}
|
||||
});
|
||||
mod->r_iso20->subscribe_dc_open_contactor([this]() {
|
||||
if (mod->selected_iso20()) {
|
||||
publish_dc_open_contactor(nullptr);
|
||||
}
|
||||
});
|
||||
|
||||
mod->r_iso2->subscribe_v2g_setup_finished([this]() {
|
||||
if (not mod->selected_iso20()) {
|
||||
publish_v2g_setup_finished(nullptr);
|
||||
}
|
||||
});
|
||||
mod->r_iso20->subscribe_v2g_setup_finished([this]() {
|
||||
if (mod->selected_iso20()) {
|
||||
publish_v2g_setup_finished(nullptr);
|
||||
}
|
||||
});
|
||||
|
||||
mod->r_iso2->subscribe_current_demand_started([this]() {
|
||||
if (not mod->selected_iso20()) {
|
||||
publish_current_demand_started(nullptr);
|
||||
}
|
||||
});
|
||||
mod->r_iso20->subscribe_current_demand_started([this]() {
|
||||
if (mod->selected_iso20()) {
|
||||
publish_current_demand_started(nullptr);
|
||||
}
|
||||
});
|
||||
|
||||
mod->r_iso2->subscribe_current_demand_finished([this]() {
|
||||
if (not mod->selected_iso20()) {
|
||||
publish_current_demand_finished(nullptr);
|
||||
}
|
||||
});
|
||||
mod->r_iso20->subscribe_current_demand_finished([this]() {
|
||||
if (mod->selected_iso20()) {
|
||||
publish_current_demand_finished(nullptr);
|
||||
}
|
||||
});
|
||||
|
||||
mod->r_iso2->subscribe_sae_bidi_mode_active([this]() {
|
||||
if (not mod->selected_iso20()) {
|
||||
publish_sae_bidi_mode_active(nullptr);
|
||||
}
|
||||
});
|
||||
mod->r_iso20->subscribe_sae_bidi_mode_active([this]() {
|
||||
if (mod->selected_iso20()) {
|
||||
publish_sae_bidi_mode_active(nullptr);
|
||||
}
|
||||
});
|
||||
|
||||
mod->r_iso2->subscribe_evcc_id([this](const auto id) {
|
||||
if (not mod->selected_iso20()) {
|
||||
publish_evcc_id(id);
|
||||
}
|
||||
});
|
||||
mod->r_iso20->subscribe_evcc_id([this](const auto id) {
|
||||
if (mod->selected_iso20()) {
|
||||
publish_evcc_id(id);
|
||||
}
|
||||
});
|
||||
|
||||
mod->r_iso2->subscribe_selected_payment_option([this](const auto o) {
|
||||
if (not mod->selected_iso20()) {
|
||||
publish_selected_payment_option(o);
|
||||
}
|
||||
});
|
||||
mod->r_iso20->subscribe_selected_payment_option([this](const auto o) {
|
||||
if (mod->selected_iso20()) {
|
||||
publish_selected_payment_option(o);
|
||||
}
|
||||
});
|
||||
|
||||
mod->r_iso2->subscribe_requested_energy_transfer_mode([this](const auto o) {
|
||||
if (not mod->selected_iso20()) {
|
||||
publish_requested_energy_transfer_mode(o);
|
||||
}
|
||||
});
|
||||
mod->r_iso20->subscribe_requested_energy_transfer_mode([this](const auto o) {
|
||||
if (mod->selected_iso20()) {
|
||||
publish_requested_energy_transfer_mode(o);
|
||||
}
|
||||
});
|
||||
|
||||
mod->r_iso2->subscribe_departure_time([this](const auto o) {
|
||||
if (not mod->selected_iso20()) {
|
||||
publish_departure_time(o);
|
||||
}
|
||||
});
|
||||
mod->r_iso20->subscribe_departure_time([this](const auto o) {
|
||||
if (mod->selected_iso20()) {
|
||||
publish_departure_time(o);
|
||||
}
|
||||
});
|
||||
|
||||
mod->r_iso2->subscribe_ac_eamount([this](const auto o) {
|
||||
if (not mod->selected_iso20()) {
|
||||
publish_ac_eamount(o);
|
||||
}
|
||||
});
|
||||
mod->r_iso20->subscribe_ac_eamount([this](const auto o) {
|
||||
if (mod->selected_iso20()) {
|
||||
publish_ac_eamount(o);
|
||||
}
|
||||
});
|
||||
|
||||
mod->r_iso2->subscribe_ac_ev_max_voltage([this](const auto o) {
|
||||
if (not mod->selected_iso20()) {
|
||||
publish_ac_ev_max_voltage(o);
|
||||
}
|
||||
});
|
||||
mod->r_iso20->subscribe_ac_ev_max_voltage([this](const auto o) {
|
||||
if (mod->selected_iso20()) {
|
||||
publish_ac_ev_max_voltage(o);
|
||||
}
|
||||
});
|
||||
|
||||
mod->r_iso2->subscribe_ac_ev_max_current([this](const auto o) {
|
||||
if (not mod->selected_iso20()) {
|
||||
publish_ac_ev_max_current(o);
|
||||
}
|
||||
});
|
||||
mod->r_iso20->subscribe_ac_ev_max_current([this](const auto o) {
|
||||
if (mod->selected_iso20()) {
|
||||
publish_ac_ev_max_current(o);
|
||||
}
|
||||
});
|
||||
|
||||
mod->r_iso2->subscribe_ac_ev_min_current([this](const auto o) {
|
||||
if (not mod->selected_iso20()) {
|
||||
publish_ac_ev_min_current(o);
|
||||
}
|
||||
});
|
||||
mod->r_iso20->subscribe_ac_ev_min_current([this](const auto o) {
|
||||
if (mod->selected_iso20()) {
|
||||
publish_ac_ev_min_current(o);
|
||||
}
|
||||
});
|
||||
|
||||
mod->r_iso20->subscribe_ac_ev_power_limits([this](const auto o) {
|
||||
if (mod->selected_iso20()) {
|
||||
publish_ac_ev_power_limits(o);
|
||||
}
|
||||
});
|
||||
|
||||
mod->r_iso20->subscribe_ac_ev_present_powers([this](const auto o) {
|
||||
if (mod->selected_iso20()) {
|
||||
publish_ac_ev_present_powers(o);
|
||||
}
|
||||
});
|
||||
|
||||
mod->r_iso20->subscribe_ac_ev_dynamic_control_mode([this](const auto o) {
|
||||
if (mod->selected_iso20()) {
|
||||
publish_ac_ev_dynamic_control_mode(o);
|
||||
}
|
||||
});
|
||||
|
||||
mod->r_iso2->subscribe_dc_ev_energy_capacity([this](const auto o) {
|
||||
if (not mod->selected_iso20()) {
|
||||
publish_dc_ev_energy_capacity(o);
|
||||
}
|
||||
});
|
||||
mod->r_iso20->subscribe_dc_ev_energy_capacity([this](const auto o) {
|
||||
if (mod->selected_iso20()) {
|
||||
publish_dc_ev_energy_capacity(o);
|
||||
}
|
||||
});
|
||||
|
||||
mod->r_iso2->subscribe_dc_ev_energy_request([this](const auto o) {
|
||||
if (not mod->selected_iso20()) {
|
||||
publish_dc_ev_energy_request(o);
|
||||
}
|
||||
});
|
||||
mod->r_iso20->subscribe_dc_ev_energy_request([this](const auto o) {
|
||||
if (mod->selected_iso20()) {
|
||||
publish_dc_ev_energy_request(o);
|
||||
}
|
||||
});
|
||||
|
||||
mod->r_iso2->subscribe_dc_full_soc([this](const auto o) {
|
||||
if (not mod->selected_iso20()) {
|
||||
publish_dc_full_soc(o);
|
||||
}
|
||||
});
|
||||
mod->r_iso20->subscribe_dc_full_soc([this](const auto o) {
|
||||
if (mod->selected_iso20()) {
|
||||
publish_dc_full_soc(o);
|
||||
}
|
||||
});
|
||||
|
||||
mod->r_iso2->subscribe_dc_bulk_soc([this](const auto o) {
|
||||
if (not mod->selected_iso20()) {
|
||||
publish_dc_bulk_soc(o);
|
||||
}
|
||||
});
|
||||
mod->r_iso20->subscribe_dc_bulk_soc([this](const auto o) {
|
||||
if (mod->selected_iso20()) {
|
||||
publish_dc_bulk_soc(o);
|
||||
}
|
||||
});
|
||||
|
||||
mod->r_iso2->subscribe_dc_ev_status([this](const auto o) {
|
||||
if (not mod->selected_iso20()) {
|
||||
publish_dc_ev_status(o);
|
||||
}
|
||||
});
|
||||
mod->r_iso20->subscribe_dc_ev_status([this](const auto o) {
|
||||
if (mod->selected_iso20()) {
|
||||
publish_dc_ev_status(o);
|
||||
}
|
||||
});
|
||||
|
||||
mod->r_iso2->subscribe_dc_bulk_charging_complete([this](const auto o) {
|
||||
if (not mod->selected_iso20()) {
|
||||
publish_dc_bulk_charging_complete(o);
|
||||
}
|
||||
});
|
||||
mod->r_iso20->subscribe_dc_bulk_charging_complete([this](const auto o) {
|
||||
if (mod->selected_iso20()) {
|
||||
publish_dc_bulk_charging_complete(o);
|
||||
}
|
||||
});
|
||||
|
||||
mod->r_iso2->subscribe_dc_charging_complete([this](const auto o) {
|
||||
if (not mod->selected_iso20()) {
|
||||
publish_dc_charging_complete(o);
|
||||
}
|
||||
});
|
||||
mod->r_iso20->subscribe_dc_charging_complete([this](const auto o) {
|
||||
if (mod->selected_iso20()) {
|
||||
publish_dc_charging_complete(o);
|
||||
}
|
||||
});
|
||||
|
||||
mod->r_iso2->subscribe_dc_ev_target_voltage_current([this](const auto o) {
|
||||
if (not mod->selected_iso20()) {
|
||||
publish_dc_ev_target_voltage_current(o);
|
||||
}
|
||||
});
|
||||
mod->r_iso20->subscribe_dc_ev_target_voltage_current([this](const auto o) {
|
||||
if (mod->selected_iso20()) {
|
||||
publish_dc_ev_target_voltage_current(o);
|
||||
}
|
||||
});
|
||||
|
||||
mod->r_iso2->subscribe_dc_ev_maximum_limits([this](const auto o) {
|
||||
if (not mod->selected_iso20()) {
|
||||
publish_dc_ev_maximum_limits(o);
|
||||
}
|
||||
});
|
||||
mod->r_iso20->subscribe_dc_ev_maximum_limits([this](const auto o) {
|
||||
if (mod->selected_iso20()) {
|
||||
publish_dc_ev_maximum_limits(o);
|
||||
}
|
||||
});
|
||||
|
||||
mod->r_iso2->subscribe_dc_ev_remaining_time([this](const auto o) {
|
||||
if (not mod->selected_iso20()) {
|
||||
publish_dc_ev_remaining_time(o);
|
||||
}
|
||||
});
|
||||
mod->r_iso20->subscribe_dc_ev_remaining_time([this](const auto o) {
|
||||
if (mod->selected_iso20()) {
|
||||
publish_dc_ev_remaining_time(o);
|
||||
}
|
||||
});
|
||||
|
||||
mod->r_iso2->subscribe_hlc_session_failed([this](const auto reason) {
|
||||
if (not mod->selected_iso20()) {
|
||||
publish_hlc_session_failed(reason);
|
||||
}
|
||||
});
|
||||
mod->r_iso20->subscribe_hlc_session_failed([this](const auto reason) {
|
||||
if (mod->selected_iso20()) {
|
||||
publish_hlc_session_failed(reason);
|
||||
}
|
||||
});
|
||||
|
||||
mod->r_iso2->subscribe_dlink_terminate([this]() {
|
||||
if (not mod->selected_iso20()) {
|
||||
publish_dlink_terminate(nullptr);
|
||||
}
|
||||
});
|
||||
mod->r_iso20->subscribe_dlink_terminate([this]() {
|
||||
if (mod->selected_iso20()) {
|
||||
publish_dlink_terminate(nullptr);
|
||||
}
|
||||
});
|
||||
|
||||
mod->r_iso2->subscribe_dlink_error([this]() {
|
||||
if (not mod->selected_iso20()) {
|
||||
publish_dlink_error(nullptr);
|
||||
}
|
||||
});
|
||||
mod->r_iso20->subscribe_dlink_error([this]() {
|
||||
if (mod->selected_iso20()) {
|
||||
publish_dlink_error(nullptr);
|
||||
}
|
||||
});
|
||||
|
||||
mod->r_iso2->subscribe_dlink_pause([this]() {
|
||||
if (not mod->selected_iso20()) {
|
||||
publish_dlink_pause(nullptr);
|
||||
}
|
||||
});
|
||||
mod->r_iso20->subscribe_dlink_pause([this]() {
|
||||
if (mod->selected_iso20()) {
|
||||
publish_dlink_pause(nullptr);
|
||||
}
|
||||
});
|
||||
|
||||
mod->r_iso2->subscribe_ev_app_protocol([this](const auto o) {
|
||||
if (not mod->selected_iso20()) {
|
||||
publish_ev_app_protocol(o);
|
||||
}
|
||||
});
|
||||
mod->r_iso20->subscribe_ev_app_protocol([this](const auto o) {
|
||||
if (mod->selected_iso20()) {
|
||||
publish_ev_app_protocol(o);
|
||||
}
|
||||
});
|
||||
|
||||
mod->r_iso2->subscribe_v2g_messages([this](const auto o) {
|
||||
if (not mod->selected_iso20()) {
|
||||
publish_v2g_messages(o);
|
||||
}
|
||||
});
|
||||
mod->r_iso20->subscribe_v2g_messages([this](const auto o) {
|
||||
if (mod->selected_iso20()) {
|
||||
publish_v2g_messages(o);
|
||||
}
|
||||
});
|
||||
|
||||
mod->r_iso2->subscribe_selected_protocol([this](const auto o) {
|
||||
if (not mod->selected_iso20()) {
|
||||
publish_selected_protocol(o);
|
||||
}
|
||||
});
|
||||
mod->r_iso20->subscribe_selected_protocol([this](const auto o) {
|
||||
if (mod->selected_iso20()) {
|
||||
publish_selected_protocol(o);
|
||||
}
|
||||
});
|
||||
|
||||
mod->r_iso2->subscribe_selected_service_parameters([this](const auto& param) {
|
||||
if (not mod->selected_iso20()) {
|
||||
publish_selected_service_parameters(param);
|
||||
}
|
||||
});
|
||||
|
||||
mod->r_iso20->subscribe_selected_service_parameters([this](const auto& param) {
|
||||
if (mod->selected_iso20()) {
|
||||
publish_selected_service_parameters(param);
|
||||
}
|
||||
});
|
||||
|
||||
mod->r_iso2->subscribe_display_parameters([this](const auto o) {
|
||||
if (not mod->selected_iso20()) {
|
||||
publish_display_parameters(o);
|
||||
}
|
||||
});
|
||||
mod->r_iso20->subscribe_display_parameters([this](const auto o) {
|
||||
if (mod->selected_iso20()) {
|
||||
publish_display_parameters(o);
|
||||
}
|
||||
});
|
||||
|
||||
mod->r_iso20->subscribe_d20_dc_dynamic_charge_mode([this](const auto o) {
|
||||
if (mod->selected_iso20()) {
|
||||
publish_d20_dc_dynamic_charge_mode(o);
|
||||
}
|
||||
});
|
||||
|
||||
mod->r_iso2->subscribe_dc_ev_present_voltage([this](const auto o) {
|
||||
if (not mod->selected_iso20()) {
|
||||
publish_dc_ev_present_voltage(o);
|
||||
}
|
||||
});
|
||||
|
||||
mod->r_iso20->subscribe_dc_ev_present_voltage([this](const auto o) {
|
||||
if (mod->selected_iso20()) {
|
||||
publish_dc_ev_present_voltage(o);
|
||||
}
|
||||
});
|
||||
|
||||
mod->r_iso2->subscribe_meter_info_requested([this]() {
|
||||
if (not mod->selected_iso20()) {
|
||||
publish_meter_info_requested(nullptr);
|
||||
}
|
||||
});
|
||||
|
||||
mod->r_iso20->subscribe_meter_info_requested([this]() {
|
||||
if (mod->selected_iso20()) {
|
||||
publish_meter_info_requested(nullptr);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void ISO15118_chargerImpl::ready() {
|
||||
}
|
||||
|
||||
std::optional<types::iso15118::SupportedAppProtocols>
|
||||
ISO15118_chargerImpl::merge_supported_app_protocols(const types::iso15118::SupportedAppProtocols& value,
|
||||
ProtocolSource source) {
|
||||
std::lock_guard<std::mutex> lock(supported_app_protocols_mutex);
|
||||
bool changed = false;
|
||||
|
||||
for (const auto protocol : value.app_protocols) {
|
||||
if (std::find(supported_app_protocols.app_protocols.begin(), supported_app_protocols.app_protocols.end(),
|
||||
protocol) == supported_app_protocols.app_protocols.end()) {
|
||||
supported_app_protocols.app_protocols.push_back(protocol);
|
||||
changed = true;
|
||||
}
|
||||
protocol_sources[protocol] = source;
|
||||
}
|
||||
|
||||
return changed ? std::make_optional(supported_app_protocols) : std::nullopt;
|
||||
}
|
||||
|
||||
void ISO15118_chargerImpl::handle_setup(types::iso15118::EVSEID& evse_id,
|
||||
types::iso15118::SaeJ2847BidiMode& sae_j2847_mode, bool& debug_mode) {
|
||||
mod->r_iso20->call_setup(evse_id, sae_j2847_mode, debug_mode);
|
||||
mod->r_iso2->call_setup(evse_id, sae_j2847_mode, debug_mode);
|
||||
}
|
||||
|
||||
void ISO15118_chargerImpl::handle_set_charging_parameters(types::iso15118::SetupPhysicalValues& physical_values) {
|
||||
mod->r_iso20->call_set_charging_parameters(physical_values);
|
||||
mod->r_iso2->call_set_charging_parameters(physical_values);
|
||||
}
|
||||
|
||||
void ISO15118_chargerImpl::handle_session_setup(std::vector<types::iso15118::PaymentOption>& payment_options,
|
||||
bool& supported_certificate_service,
|
||||
bool& central_contract_validation_allowed) {
|
||||
mod->r_iso20->call_session_setup(payment_options, supported_certificate_service,
|
||||
central_contract_validation_allowed);
|
||||
mod->r_iso2->call_session_setup(payment_options, supported_certificate_service,
|
||||
central_contract_validation_allowed);
|
||||
}
|
||||
|
||||
void ISO15118_chargerImpl::handle_bpt_setup(types::iso15118::BptSetup& bpt_config) {
|
||||
if (mod->selected_iso20()) {
|
||||
mod->r_iso20->call_bpt_setup(bpt_config);
|
||||
}
|
||||
}
|
||||
|
||||
void ISO15118_chargerImpl::handle_set_powersupply_capabilities(types::power_supply_DC::Capabilities& capabilities) {
|
||||
mod->r_iso20->call_set_powersupply_capabilities(capabilities);
|
||||
mod->r_iso2->call_set_powersupply_capabilities(capabilities);
|
||||
}
|
||||
|
||||
void ISO15118_chargerImpl::handle_authorization_response(
|
||||
types::authorization::AuthorizationStatus& authorization_status,
|
||||
types::authorization::CertificateStatus& certificate_status) {
|
||||
if (mod->selected_iso20()) {
|
||||
mod->r_iso20->call_authorization_response(authorization_status, certificate_status);
|
||||
} else {
|
||||
mod->r_iso2->call_authorization_response(authorization_status, certificate_status);
|
||||
}
|
||||
}
|
||||
|
||||
void ISO15118_chargerImpl::handle_ac_contactor_closed(bool& status) {
|
||||
if (mod->selected_iso20()) {
|
||||
mod->r_iso20->call_ac_contactor_closed(status);
|
||||
} else {
|
||||
mod->r_iso2->call_ac_contactor_closed(status);
|
||||
}
|
||||
}
|
||||
|
||||
void ISO15118_chargerImpl::handle_dlink_ready(bool& value) {
|
||||
if (mod->selected_iso20()) {
|
||||
mod->r_iso20->call_dlink_ready(value);
|
||||
} else {
|
||||
mod->r_iso2->call_dlink_ready(value);
|
||||
}
|
||||
}
|
||||
|
||||
void ISO15118_chargerImpl::handle_cable_check_finished(bool& status) {
|
||||
if (mod->selected_iso20()) {
|
||||
mod->r_iso20->call_cable_check_finished(status);
|
||||
} else {
|
||||
mod->r_iso2->call_cable_check_finished(status);
|
||||
}
|
||||
}
|
||||
|
||||
void ISO15118_chargerImpl::handle_receipt_is_required(bool& receipt_required) {
|
||||
mod->r_iso20->call_receipt_is_required(receipt_required);
|
||||
mod->r_iso2->call_receipt_is_required(receipt_required);
|
||||
}
|
||||
|
||||
void ISO15118_chargerImpl::handle_stop_charging(bool& stop) {
|
||||
if (mod->selected_iso20()) {
|
||||
mod->r_iso20->call_stop_charging(stop);
|
||||
} else {
|
||||
mod->r_iso2->call_stop_charging(stop);
|
||||
}
|
||||
}
|
||||
|
||||
void ISO15118_chargerImpl::handle_pause_charging(bool& pause) {
|
||||
if (mod->selected_iso20()) {
|
||||
mod->r_iso20->call_pause_charging(pause);
|
||||
} else {
|
||||
mod->r_iso2->call_pause_charging(pause);
|
||||
}
|
||||
}
|
||||
|
||||
void ISO15118_chargerImpl::handle_no_energy_pause_charging(types::iso15118::NoEnergyPauseMode& mode) {
|
||||
if (mod->selected_iso20()) {
|
||||
mod->r_iso20->call_no_energy_pause_charging(mode);
|
||||
} else {
|
||||
mod->r_iso2->call_no_energy_pause_charging(mode);
|
||||
}
|
||||
}
|
||||
|
||||
bool ISO15118_chargerImpl::handle_update_supported_app_protocols(
|
||||
types::iso15118::SupportedAppProtocols& updated_supported_app_protocols) {
|
||||
bool iso20_configured = false;
|
||||
|
||||
if (updated_supported_app_protocols.app_protocols.empty()) {
|
||||
v2g_ctx->iso20_proxy_enabled = false;
|
||||
EVLOG_info << "No protocols configured, disabling ISO-20 proxy routing";
|
||||
// Forward empty updates to both implementations
|
||||
// TODO(FH): Currently only forwarded to the ISO-2 module, because ISO-20 module is not able to
|
||||
// disable supported protocols. Currently, this implementation gap has been resolved by deactivating
|
||||
// the ISO-20 proxy if the ISO-20 protocol has not been enabled. In that case, the ISO-2
|
||||
// proxy takes over the responsibility for responding to the SupportedAppReq.
|
||||
const bool ok_iso2 = mod->r_iso2->call_update_supported_app_protocols(updated_supported_app_protocols);
|
||||
mod->r_iso20->call_update_supported_app_protocols(updated_supported_app_protocols);
|
||||
return ok_iso2;
|
||||
}
|
||||
|
||||
types::iso15118::SupportedAppProtocols iso2_payload;
|
||||
types::iso15118::SupportedAppProtocols iso20_payload;
|
||||
|
||||
{
|
||||
/* Iterate though the list of supported_app_protocols and check whether the received protocol is intended for
|
||||
the r_iso2 or the r_iso20 instance */
|
||||
std::lock_guard<std::mutex> lock(supported_app_protocols_mutex);
|
||||
for (const auto protocol : updated_supported_app_protocols.app_protocols) {
|
||||
const auto source_it = protocol_sources.find(protocol);
|
||||
const bool known_protocol = std::find(this->supported_app_protocols.app_protocols.begin(),
|
||||
this->supported_app_protocols.app_protocols.end(),
|
||||
protocol) != this->supported_app_protocols.app_protocols.end();
|
||||
if (source_it == protocol_sources.end() || !known_protocol) {
|
||||
EVLOG_warning << "Received update for unsupported app protocol: "
|
||||
<< types::iso15118::supported_app_protocol_to_string(protocol);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (source_it->second == ProtocolSource::Iso20) {
|
||||
iso20_configured = true;
|
||||
iso20_payload.app_protocols.push_back(protocol);
|
||||
} else {
|
||||
iso2_payload.app_protocols.push_back(protocol);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* update supported protocols */
|
||||
bool ok = true;
|
||||
if (!iso2_payload.app_protocols.empty()) {
|
||||
ok = mod->r_iso2->call_update_supported_app_protocols(iso2_payload) && ok;
|
||||
}
|
||||
if (!iso20_payload.app_protocols.empty()) {
|
||||
ok = mod->r_iso20->call_update_supported_app_protocols(iso20_payload) && ok;
|
||||
}
|
||||
|
||||
/* route to ISO-20 proxy only when ISO15118-20 is explicitly configured. */
|
||||
v2g_ctx->iso20_proxy_enabled = iso20_configured;
|
||||
if (!iso20_configured) {
|
||||
EVLOG_debug << "Disabling ISO-20 proxy routing since no ISO15118-20 protocol is configured";
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
void ISO15118_chargerImpl::handle_update_energy_transfer_modes(
|
||||
std::vector<types::iso15118::EnergyTransferMode>& supported_energy_transfer_modes) {
|
||||
mod->r_iso20->call_update_energy_transfer_modes(supported_energy_transfer_modes);
|
||||
mod->r_iso2->call_update_energy_transfer_modes(supported_energy_transfer_modes);
|
||||
}
|
||||
|
||||
void ISO15118_chargerImpl::handle_update_ac_max_current(double& max_current) {
|
||||
mod->r_iso20->call_update_ac_max_current(max_current);
|
||||
mod->r_iso2->call_update_ac_max_current(max_current);
|
||||
}
|
||||
|
||||
void ISO15118_chargerImpl::handle_update_ac_parameters(types::iso15118::AcParameters& ac_parameters) {
|
||||
if (mod->selected_iso20()) {
|
||||
mod->r_iso20->call_update_ac_parameters(ac_parameters);
|
||||
}
|
||||
}
|
||||
|
||||
void ISO15118_chargerImpl::handle_update_ac_maximum_limits(types::iso15118::AcEvseMaximumPower& maximum_limits) {
|
||||
if (mod->selected_iso20()) {
|
||||
mod->r_iso20->call_update_ac_maximum_limits(maximum_limits);
|
||||
}
|
||||
}
|
||||
|
||||
void ISO15118_chargerImpl::handle_update_ac_minimum_limits(types::iso15118::AcEvseMinimumPower& minimum_limits) {
|
||||
if (mod->selected_iso20()) {
|
||||
mod->r_iso20->call_update_ac_minimum_limits(minimum_limits);
|
||||
}
|
||||
}
|
||||
|
||||
void ISO15118_chargerImpl::handle_update_ac_target_values(types::iso15118::AcTargetValues& target_values) {
|
||||
if (mod->selected_iso20()) {
|
||||
mod->r_iso20->call_update_ac_target_values(target_values);
|
||||
}
|
||||
}
|
||||
|
||||
void ISO15118_chargerImpl::handle_update_ac_present_power(types::units::Power& present_power) {
|
||||
if (mod->selected_iso20()) {
|
||||
mod->r_iso20->call_update_ac_present_power(present_power);
|
||||
}
|
||||
}
|
||||
|
||||
void ISO15118_chargerImpl::handle_update_dc_maximum_limits(types::iso15118::DcEvseMaximumLimits& maximum_limits) {
|
||||
mod->r_iso20->call_update_dc_maximum_limits(maximum_limits);
|
||||
mod->r_iso2->call_update_dc_maximum_limits(maximum_limits);
|
||||
}
|
||||
|
||||
void ISO15118_chargerImpl::handle_update_dc_minimum_limits(types::iso15118::DcEvseMinimumLimits& minimum_limits) {
|
||||
mod->r_iso20->call_update_dc_minimum_limits(minimum_limits);
|
||||
mod->r_iso2->call_update_dc_minimum_limits(minimum_limits);
|
||||
}
|
||||
|
||||
void ISO15118_chargerImpl::handle_update_isolation_status(types::iso15118::IsolationStatus& isolation_status) {
|
||||
if (mod->selected_iso20()) {
|
||||
mod->r_iso20->call_update_isolation_status(isolation_status);
|
||||
} else {
|
||||
mod->r_iso2->call_update_isolation_status(isolation_status);
|
||||
}
|
||||
}
|
||||
|
||||
void ISO15118_chargerImpl::handle_update_dc_present_values(
|
||||
types::iso15118::DcEvsePresentVoltageCurrent& present_voltage_current) {
|
||||
mod->r_iso20->call_update_dc_present_values(present_voltage_current);
|
||||
mod->r_iso2->call_update_dc_present_values(present_voltage_current);
|
||||
}
|
||||
|
||||
void ISO15118_chargerImpl::handle_update_meter_info(types::powermeter::Powermeter& powermeter) {
|
||||
mod->r_iso20->call_update_meter_info(powermeter);
|
||||
mod->r_iso2->call_update_meter_info(powermeter);
|
||||
}
|
||||
|
||||
void ISO15118_chargerImpl::handle_send_error(types::iso15118::EvseError& error) {
|
||||
if (mod->selected_iso20()) {
|
||||
mod->r_iso20->call_send_error(error);
|
||||
} else {
|
||||
mod->r_iso2->call_send_error(error);
|
||||
}
|
||||
}
|
||||
|
||||
void ISO15118_chargerImpl::handle_reset_error() {
|
||||
if (mod->selected_iso20()) {
|
||||
mod->r_iso20->call_reset_error();
|
||||
} else {
|
||||
mod->r_iso2->call_reset_error();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace charger
|
||||
} // namespace module
|
||||
@@ -0,0 +1,111 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright Pionix GmbH and Contributors to EVerest
|
||||
#ifndef CHARGER_ISO15118_CHARGER_IMPL_HPP
|
||||
#define CHARGER_ISO15118_CHARGER_IMPL_HPP
|
||||
|
||||
//
|
||||
// AUTO GENERATED - MARKED REGIONS WILL BE KEPT
|
||||
// template version 3
|
||||
//
|
||||
|
||||
#include <generated/interfaces/ISO15118_charger/Implementation.hpp>
|
||||
|
||||
#include "../IsoMux.hpp"
|
||||
|
||||
// ev@75ac1216-19eb-4182-a85c-820f1fc2c091:v1
|
||||
#include <mutex>
|
||||
#include <optional>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "v2g.hpp"
|
||||
extern struct v2g_context* v2g_ctx;
|
||||
// ev@75ac1216-19eb-4182-a85c-820f1fc2c091:v1
|
||||
|
||||
namespace module {
|
||||
namespace charger {
|
||||
|
||||
struct Conf {};
|
||||
|
||||
class ISO15118_chargerImpl : public ISO15118_chargerImplBase {
|
||||
public:
|
||||
ISO15118_chargerImpl() = delete;
|
||||
ISO15118_chargerImpl(Everest::ModuleAdapter* ev, const Everest::PtrContainer<IsoMux>& mod, Conf& config) :
|
||||
ISO15118_chargerImplBase(ev, "charger"), mod(mod), config(config){};
|
||||
|
||||
// ev@8ea32d28-373f-4c90-ae5e-b4fcc74e2a61:v1
|
||||
// insert your public definitions here
|
||||
// ev@8ea32d28-373f-4c90-ae5e-b4fcc74e2a61:v1
|
||||
|
||||
protected:
|
||||
// command handler functions (virtual)
|
||||
virtual void handle_setup(types::iso15118::EVSEID& evse_id, types::iso15118::SaeJ2847BidiMode& sae_j2847_mode,
|
||||
bool& debug_mode) override;
|
||||
virtual void handle_set_charging_parameters(types::iso15118::SetupPhysicalValues& physical_values) override;
|
||||
virtual void handle_session_setup(std::vector<types::iso15118::PaymentOption>& payment_options,
|
||||
bool& supported_certificate_service,
|
||||
bool& central_contract_validation_allowed) override;
|
||||
virtual void handle_bpt_setup(types::iso15118::BptSetup& bpt_config) override;
|
||||
virtual void handle_set_powersupply_capabilities(types::power_supply_DC::Capabilities& capabilities) override;
|
||||
virtual void handle_authorization_response(types::authorization::AuthorizationStatus& authorization_status,
|
||||
types::authorization::CertificateStatus& certificate_status) override;
|
||||
virtual void handle_ac_contactor_closed(bool& status) override;
|
||||
virtual void handle_dlink_ready(bool& value) override;
|
||||
virtual void handle_cable_check_finished(bool& status) override;
|
||||
virtual void handle_receipt_is_required(bool& receipt_required) override;
|
||||
virtual void handle_stop_charging(bool& stop) override;
|
||||
virtual void handle_pause_charging(bool& pause) override;
|
||||
virtual void handle_no_energy_pause_charging(types::iso15118::NoEnergyPauseMode& mode) override;
|
||||
virtual bool
|
||||
handle_update_supported_app_protocols(types::iso15118::SupportedAppProtocols& supported_app_protocols) override;
|
||||
virtual void handle_update_energy_transfer_modes(
|
||||
std::vector<types::iso15118::EnergyTransferMode>& supported_energy_transfer_modes) override;
|
||||
virtual void handle_update_ac_max_current(double& max_current) override;
|
||||
virtual void handle_update_ac_parameters(types::iso15118::AcParameters& ac_parameters) override;
|
||||
virtual void handle_update_ac_maximum_limits(types::iso15118::AcEvseMaximumPower& maximum_limits) override;
|
||||
virtual void handle_update_ac_minimum_limits(types::iso15118::AcEvseMinimumPower& minimum_limits) override;
|
||||
virtual void handle_update_ac_target_values(types::iso15118::AcTargetValues& target_values) override;
|
||||
virtual void handle_update_ac_present_power(types::units::Power& present_power) override;
|
||||
virtual void handle_update_dc_maximum_limits(types::iso15118::DcEvseMaximumLimits& maximum_limits) override;
|
||||
virtual void handle_update_dc_minimum_limits(types::iso15118::DcEvseMinimumLimits& minimum_limits) override;
|
||||
virtual void handle_update_isolation_status(types::iso15118::IsolationStatus& isolation_status) override;
|
||||
virtual void
|
||||
handle_update_dc_present_values(types::iso15118::DcEvsePresentVoltageCurrent& present_voltage_current) override;
|
||||
virtual void handle_update_meter_info(types::powermeter::Powermeter& powermeter) override;
|
||||
virtual void handle_send_error(types::iso15118::EvseError& error) override;
|
||||
virtual void handle_reset_error() override;
|
||||
|
||||
// ev@d2d1847a-7b88-41dd-ad07-92785f06f5c4:v1
|
||||
// insert your protected definitions here
|
||||
// ev@d2d1847a-7b88-41dd-ad07-92785f06f5c4:v1
|
||||
|
||||
private:
|
||||
const Everest::PtrContainer<IsoMux>& mod;
|
||||
const Conf& config;
|
||||
|
||||
virtual void init() override;
|
||||
virtual void ready() override;
|
||||
|
||||
// ev@3370e4dd-95f4-47a9-aaec-ea76f34a66c9:v1
|
||||
// insert your private definitions here
|
||||
types::iso15118::SupportedAppProtocols supported_app_protocols; // aggregated set of protocols from iso2/iso20
|
||||
std::mutex supported_app_protocols_mutex; // guards shared protocol state
|
||||
enum class ProtocolSource {
|
||||
Iso2,
|
||||
Iso20
|
||||
};
|
||||
std::unordered_map<types::iso15118::SupportedAppProtocol, ProtocolSource>
|
||||
protocol_sources; // tracks which instance advertised each protocol
|
||||
|
||||
std::optional<types::iso15118::SupportedAppProtocols>
|
||||
merge_supported_app_protocols(const types::iso15118::SupportedAppProtocols& value, ProtocolSource source);
|
||||
// ev@3370e4dd-95f4-47a9-aaec-ea76f34a66c9:v1
|
||||
};
|
||||
|
||||
// ev@3d7da0ad-02c2-493d-9920-0bbbd56b9876:v1
|
||||
// insert other definitions here
|
||||
// ev@3d7da0ad-02c2-493d-9920-0bbbd56b9876:v1
|
||||
|
||||
} // namespace charger
|
||||
} // namespace module
|
||||
|
||||
#endif // CHARGER_ISO15118_CHARGER_IMPL_HPP
|
||||
Reference in New Issue
Block a user