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,604 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright Pionix GmbH and Contributors to EVerest
|
||||
|
||||
#include <everest/conversions/ocpp/evse_security_ocpp.hpp>
|
||||
|
||||
EvseSecurity::EvseSecurity(evse_securityIntf& r_security) : r_security(r_security) {
|
||||
}
|
||||
|
||||
EvseSecurity::~EvseSecurity() {
|
||||
}
|
||||
|
||||
ocpp::InstallCertificateResult EvseSecurity::install_ca_certificate(const std::string& certificate,
|
||||
const ocpp::CaCertificateType& certificate_type) {
|
||||
try {
|
||||
return conversions::to_ocpp(
|
||||
this->r_security.call_install_ca_certificate(certificate, conversions::from_ocpp(certificate_type)));
|
||||
} catch (const std::out_of_range& e) {
|
||||
EVLOG_warning << e.what();
|
||||
return ocpp::InstallCertificateResult::WriteError;
|
||||
}
|
||||
}
|
||||
|
||||
ocpp::DeleteCertificateResult
|
||||
EvseSecurity::delete_certificate(const ocpp::CertificateHashDataType& certificate_hash_data) {
|
||||
try {
|
||||
return conversions::to_ocpp(
|
||||
this->r_security.call_delete_certificate(conversions::from_ocpp(certificate_hash_data)));
|
||||
} catch (const std::out_of_range& e) {
|
||||
EVLOG_warning << e.what();
|
||||
return ocpp::DeleteCertificateResult::Failed;
|
||||
}
|
||||
}
|
||||
|
||||
ocpp::InstallCertificateResult
|
||||
EvseSecurity::update_leaf_certificate(const std::string& certificate_chain,
|
||||
const ocpp::CertificateSigningUseEnum& certificate_type) {
|
||||
try {
|
||||
return conversions::to_ocpp(
|
||||
this->r_security.call_update_leaf_certificate(certificate_chain, conversions::from_ocpp(certificate_type)));
|
||||
} catch (const std::out_of_range& e) {
|
||||
EVLOG_warning << e.what();
|
||||
return ocpp::InstallCertificateResult::WriteError;
|
||||
}
|
||||
}
|
||||
|
||||
ocpp::CertificateValidationResult EvseSecurity::verify_certificate(const std::string& certificate_chain,
|
||||
const ocpp::LeafCertificateType& certificate_type) {
|
||||
try {
|
||||
return conversions::to_ocpp(
|
||||
this->r_security.call_verify_certificate(certificate_chain, {conversions::from_ocpp(certificate_type)}));
|
||||
} catch (const std::out_of_range& e) {
|
||||
EVLOG_warning << e.what();
|
||||
return ocpp::CertificateValidationResult::Unknown;
|
||||
}
|
||||
}
|
||||
|
||||
ocpp::CertificateValidationResult
|
||||
EvseSecurity::verify_certificate(const std::string& certificate_chain,
|
||||
const std::vector<ocpp::LeafCertificateType>& certificate_types) {
|
||||
std::vector<types::evse_security::LeafCertificateType> _certificate_types;
|
||||
|
||||
for (const auto& certificate_type : certificate_types) {
|
||||
try {
|
||||
_certificate_types.push_back(conversions::from_ocpp(certificate_type));
|
||||
} catch (const std::out_of_range& e) {
|
||||
EVLOG_warning << e.what();
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
return conversions::to_ocpp(this->r_security.call_verify_certificate(certificate_chain, _certificate_types));
|
||||
} catch (const std::out_of_range& e) {
|
||||
EVLOG_warning << e.what();
|
||||
return ocpp::CertificateValidationResult::Unknown;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<ocpp::CertificateHashDataChain>
|
||||
EvseSecurity::get_installed_certificates(const std::vector<ocpp::CertificateType>& certificate_types) {
|
||||
std::vector<ocpp::CertificateHashDataChain> result;
|
||||
|
||||
std::vector<types::evse_security::CertificateType> _certificate_types;
|
||||
|
||||
for (const auto& certificate_type : certificate_types) {
|
||||
try {
|
||||
_certificate_types.push_back(conversions::from_ocpp(certificate_type));
|
||||
} catch (const std::out_of_range& e) {
|
||||
EVLOG_warning << e.what();
|
||||
}
|
||||
}
|
||||
|
||||
const auto installed_certificates = this->r_security.call_get_installed_certificates(_certificate_types);
|
||||
|
||||
for (const auto& certificate_hash_data : installed_certificates.certificate_hash_data_chain) {
|
||||
try {
|
||||
result.push_back(conversions::to_ocpp(certificate_hash_data));
|
||||
} catch (const std::out_of_range& e) {
|
||||
EVLOG_warning << e.what();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<ocpp::OCSPRequestData> EvseSecurity::get_v2g_ocsp_request_data() {
|
||||
std::vector<ocpp::OCSPRequestData> result;
|
||||
|
||||
const auto ocsp_request_data = this->r_security.call_get_v2g_ocsp_request_data();
|
||||
for (const auto& ocsp_request_entry : ocsp_request_data.ocsp_request_data_list) {
|
||||
try {
|
||||
result.push_back(conversions::to_ocpp(ocsp_request_entry));
|
||||
} catch (const std::out_of_range& e) {
|
||||
EVLOG_warning << e.what();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<ocpp::OCSPRequestData> EvseSecurity::get_mo_ocsp_request_data(const std::string& certificate_chain) {
|
||||
std::vector<ocpp::OCSPRequestData> result;
|
||||
|
||||
const auto ocsp_request_data = this->r_security.call_get_mo_ocsp_request_data(certificate_chain);
|
||||
for (const auto& ocsp_request_entry : ocsp_request_data.ocsp_request_data_list) {
|
||||
try {
|
||||
result.push_back(conversions::to_ocpp(ocsp_request_entry));
|
||||
} catch (const std::out_of_range& e) {
|
||||
EVLOG_warning << e.what();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void EvseSecurity::update_ocsp_cache(const ocpp::CertificateHashDataType& certificate_hash_data,
|
||||
const std::string& ocsp_response) {
|
||||
try {
|
||||
this->r_security.call_update_ocsp_cache(conversions::from_ocpp(certificate_hash_data), ocsp_response);
|
||||
} catch (const std::out_of_range& e) {
|
||||
EVLOG_warning << e.what();
|
||||
}
|
||||
}
|
||||
|
||||
bool EvseSecurity::is_ca_certificate_installed(const ocpp::CaCertificateType& certificate_type) {
|
||||
try {
|
||||
return this->r_security.call_is_ca_certificate_installed(conversions::from_ocpp(certificate_type));
|
||||
} catch (const std::out_of_range& e) {
|
||||
EVLOG_warning << e.what();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
ocpp::GetCertificateSignRequestResult
|
||||
EvseSecurity::generate_certificate_signing_request(const ocpp::CertificateSigningUseEnum& certificate_type,
|
||||
const std::string& country, const std::string& organization,
|
||||
const std::string& common, bool use_tpm) {
|
||||
try {
|
||||
auto csr_response = this->r_security.call_generate_certificate_signing_request(
|
||||
conversions::from_ocpp(certificate_type), country, organization, common, use_tpm);
|
||||
|
||||
ocpp::GetCertificateSignRequestResult result;
|
||||
|
||||
result.status = conversions::to_ocpp(csr_response.status);
|
||||
if (csr_response.csr.has_value()) {
|
||||
result.csr = csr_response.csr;
|
||||
}
|
||||
|
||||
return result;
|
||||
} catch (const std::out_of_range& e) {
|
||||
EVLOG_warning << e.what();
|
||||
ocpp::GetCertificateSignRequestResult result;
|
||||
result.status = ocpp::GetCertificateSignRequestStatus::GenerationError;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
ocpp::GetCertificateInfoResult
|
||||
EvseSecurity::get_leaf_certificate_info(const ocpp::CertificateSigningUseEnum& certificate_type, bool include_ocsp) {
|
||||
try {
|
||||
const auto info_response = this->r_security.call_get_leaf_certificate_info(
|
||||
conversions::from_ocpp(certificate_type), types::evse_security::EncodingFormat::PEM, include_ocsp);
|
||||
|
||||
ocpp::GetCertificateInfoResult result;
|
||||
|
||||
result.status = conversions::to_ocpp(info_response.status);
|
||||
if (info_response.info.has_value()) {
|
||||
result.info = conversions::to_ocpp(info_response.info.value());
|
||||
}
|
||||
|
||||
return result;
|
||||
} catch (const std::out_of_range& e) {
|
||||
EVLOG_warning << e.what();
|
||||
ocpp::GetCertificateInfoResult result;
|
||||
result.status = ocpp::GetCertificateInfoStatus::Rejected;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
bool EvseSecurity::update_certificate_links(const ocpp::CertificateSigningUseEnum& certificate_type) {
|
||||
// TODO: Implement if required
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string EvseSecurity::get_verify_file(const ocpp::CaCertificateType& certificate_type) {
|
||||
try {
|
||||
return this->r_security.call_get_verify_file(conversions::from_ocpp(certificate_type));
|
||||
} catch (const std::out_of_range& e) {
|
||||
EVLOG_warning << e.what();
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
std::string EvseSecurity::get_verify_location(const ocpp::CaCertificateType& certificate_type) {
|
||||
try {
|
||||
return this->r_security.call_get_verify_location(conversions::from_ocpp(certificate_type));
|
||||
} catch (std::out_of_range& e) {
|
||||
EVLOG_warning << e.what();
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
int EvseSecurity::get_leaf_expiry_days_count(const ocpp::CertificateSigningUseEnum& certificate_type) {
|
||||
try {
|
||||
return this->r_security.call_get_leaf_expiry_days_count(conversions::from_ocpp(certificate_type));
|
||||
} catch (const std::out_of_range& e) {
|
||||
EVLOG_warning << e.what();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
namespace conversions {
|
||||
|
||||
ocpp::CaCertificateType to_ocpp(types::evse_security::CaCertificateType other) {
|
||||
switch (other) {
|
||||
case types::evse_security::CaCertificateType::V2G:
|
||||
return ocpp::CaCertificateType::V2G;
|
||||
case types::evse_security::CaCertificateType::MO:
|
||||
return ocpp::CaCertificateType::MO;
|
||||
case types::evse_security::CaCertificateType::CSMS:
|
||||
return ocpp::CaCertificateType::CSMS;
|
||||
case types::evse_security::CaCertificateType::MF:
|
||||
return ocpp::CaCertificateType::MF;
|
||||
}
|
||||
throw std::out_of_range("Could not convert types::evse_security::CaCertificateType to ocpp::CaCertificateType");
|
||||
}
|
||||
|
||||
ocpp::LeafCertificateType to_ocpp(types::evse_security::LeafCertificateType other) {
|
||||
switch (other) {
|
||||
case types::evse_security::LeafCertificateType::CSMS:
|
||||
return ocpp::LeafCertificateType::CSMS;
|
||||
case types::evse_security::LeafCertificateType::V2G:
|
||||
return ocpp::LeafCertificateType::V2G;
|
||||
case types::evse_security::LeafCertificateType::MF:
|
||||
return ocpp::LeafCertificateType::MF;
|
||||
case types::evse_security::LeafCertificateType::MO:
|
||||
return ocpp::LeafCertificateType::MO;
|
||||
}
|
||||
throw std::out_of_range(
|
||||
"Could not convert types::evse_security::LeafCertificateType to ocpp::CertificateSigningUseEnum");
|
||||
}
|
||||
|
||||
ocpp::CertificateType to_ocpp(types::evse_security::CertificateType other) {
|
||||
switch (other) {
|
||||
case types::evse_security::CertificateType::V2GRootCertificate:
|
||||
return ocpp::CertificateType::V2GRootCertificate;
|
||||
case types::evse_security::CertificateType::MORootCertificate:
|
||||
return ocpp::CertificateType::MORootCertificate;
|
||||
case types::evse_security::CertificateType::CSMSRootCertificate:
|
||||
return ocpp::CertificateType::CSMSRootCertificate;
|
||||
case types::evse_security::CertificateType::V2GCertificateChain:
|
||||
return ocpp::CertificateType::V2GCertificateChain;
|
||||
case types::evse_security::CertificateType::MFRootCertificate:
|
||||
return ocpp::CertificateType::MFRootCertificate;
|
||||
}
|
||||
throw std::out_of_range("Could not convert types::evse_security::CertificateType to ocpp::CertificateType");
|
||||
}
|
||||
|
||||
ocpp::HashAlgorithmEnumType to_ocpp(types::evse_security::HashAlgorithm other) {
|
||||
switch (other) {
|
||||
case types::evse_security::HashAlgorithm::SHA256:
|
||||
return ocpp::HashAlgorithmEnumType::SHA256;
|
||||
case types::evse_security::HashAlgorithm::SHA384:
|
||||
return ocpp::HashAlgorithmEnumType::SHA384;
|
||||
case types::evse_security::HashAlgorithm::SHA512:
|
||||
return ocpp::HashAlgorithmEnumType::SHA512;
|
||||
}
|
||||
throw std::out_of_range("Could not convert types::evse_security::HashAlgorithm to ocpp::HashAlgorithmEnumType");
|
||||
}
|
||||
|
||||
ocpp::InstallCertificateResult to_ocpp(types::evse_security::InstallCertificateResult other) {
|
||||
switch (other) {
|
||||
case types::evse_security::InstallCertificateResult::InvalidSignature:
|
||||
return ocpp::InstallCertificateResult::InvalidSignature;
|
||||
case types::evse_security::InstallCertificateResult::InvalidCertificateChain:
|
||||
return ocpp::InstallCertificateResult::InvalidCertificateChain;
|
||||
case types::evse_security::InstallCertificateResult::InvalidFormat:
|
||||
return ocpp::InstallCertificateResult::InvalidFormat;
|
||||
case types::evse_security::InstallCertificateResult::InvalidCommonName:
|
||||
return ocpp::InstallCertificateResult::InvalidCommonName;
|
||||
case types::evse_security::InstallCertificateResult::NoRootCertificateInstalled:
|
||||
return ocpp::InstallCertificateResult::NoRootCertificateInstalled;
|
||||
case types::evse_security::InstallCertificateResult::Expired:
|
||||
return ocpp::InstallCertificateResult::Expired;
|
||||
case types::evse_security::InstallCertificateResult::CertificateStoreMaxLengthExceeded:
|
||||
return ocpp::InstallCertificateResult::CertificateStoreMaxLengthExceeded;
|
||||
case types::evse_security::InstallCertificateResult::WriteError:
|
||||
return ocpp::InstallCertificateResult::WriteError;
|
||||
case types::evse_security::InstallCertificateResult::Accepted:
|
||||
return ocpp::InstallCertificateResult::Accepted;
|
||||
}
|
||||
throw std::out_of_range(
|
||||
"Could not convert types::evse_security::InstallCertificateResult to ocpp::InstallCertificateResult");
|
||||
}
|
||||
|
||||
ocpp::CertificateValidationResult to_ocpp(types::evse_security::CertificateValidationResult other) {
|
||||
switch (other) {
|
||||
case types::evse_security::CertificateValidationResult::Valid:
|
||||
return ocpp::CertificateValidationResult::Valid;
|
||||
case types::evse_security::CertificateValidationResult::InvalidSignature:
|
||||
return ocpp::CertificateValidationResult::InvalidSignature;
|
||||
case types::evse_security::CertificateValidationResult::IssuerNotFound:
|
||||
return ocpp::CertificateValidationResult::IssuerNotFound;
|
||||
case types::evse_security::CertificateValidationResult::InvalidLeafSignature:
|
||||
return ocpp::CertificateValidationResult::InvalidLeafSignature;
|
||||
case types::evse_security::CertificateValidationResult::InvalidChain:
|
||||
return ocpp::CertificateValidationResult::InvalidChain;
|
||||
case types::evse_security::CertificateValidationResult::Unknown:
|
||||
return ocpp::CertificateValidationResult::Unknown;
|
||||
case types::evse_security::CertificateValidationResult::Expired:
|
||||
return ocpp::CertificateValidationResult::Expired;
|
||||
}
|
||||
throw std::out_of_range("Could not convert types::evse_security::CertificateValidationResult to "
|
||||
"ocpp::CertificateValidationResult");
|
||||
}
|
||||
|
||||
ocpp::GetCertificateInfoStatus to_ocpp(types::evse_security::GetCertificateInfoStatus other) {
|
||||
switch (other) {
|
||||
case types::evse_security::GetCertificateInfoStatus::Accepted:
|
||||
return ocpp::GetCertificateInfoStatus::Accepted;
|
||||
case types::evse_security::GetCertificateInfoStatus::Rejected:
|
||||
return ocpp::GetCertificateInfoStatus::Rejected;
|
||||
case types::evse_security::GetCertificateInfoStatus::NotFound:
|
||||
return ocpp::GetCertificateInfoStatus::NotFound;
|
||||
case types::evse_security::GetCertificateInfoStatus::NotFoundValid:
|
||||
return ocpp::GetCertificateInfoStatus::NotFoundValid;
|
||||
case types::evse_security::GetCertificateInfoStatus::PrivateKeyNotFound:
|
||||
return ocpp::GetCertificateInfoStatus::PrivateKeyNotFound;
|
||||
}
|
||||
throw std::out_of_range("Could not convert types::evse_security::GetCertificateInfoStatus to "
|
||||
"ocpp::GetCertificateInfoStatus");
|
||||
}
|
||||
|
||||
ocpp::DeleteCertificateResult to_ocpp(types::evse_security::DeleteCertificateResult other) {
|
||||
switch (other) {
|
||||
case types::evse_security::DeleteCertificateResult::Accepted:
|
||||
return ocpp::DeleteCertificateResult::Accepted;
|
||||
case types::evse_security::DeleteCertificateResult::Failed:
|
||||
return ocpp::DeleteCertificateResult::Failed;
|
||||
case types::evse_security::DeleteCertificateResult::NotFound:
|
||||
return ocpp::DeleteCertificateResult::NotFound;
|
||||
}
|
||||
throw std::out_of_range(
|
||||
"Could not convert types::evse_security::DeleteCertificateResult to ocpp::DeleteCertificateResult");
|
||||
}
|
||||
|
||||
ocpp::GetCertificateSignRequestStatus to_ocpp(types::evse_security::GetCertificateSignRequestStatus other) {
|
||||
switch (other) {
|
||||
case types::evse_security::GetCertificateSignRequestStatus::Accepted:
|
||||
return ocpp::GetCertificateSignRequestStatus::Accepted;
|
||||
case types::evse_security::GetCertificateSignRequestStatus::InvalidRequestedType:
|
||||
return ocpp::GetCertificateSignRequestStatus::InvalidRequestedType;
|
||||
case types::evse_security::GetCertificateSignRequestStatus::KeyGenError:
|
||||
return ocpp::GetCertificateSignRequestStatus::KeyGenError;
|
||||
case types::evse_security::GetCertificateSignRequestStatus::GenerationError:
|
||||
return ocpp::GetCertificateSignRequestStatus::GenerationError;
|
||||
}
|
||||
throw std::out_of_range("Could not convert types::evse_security::GetCertificateSignRequestStatus to "
|
||||
"ocpp::GetCertificateSignRequestStatus");
|
||||
}
|
||||
|
||||
ocpp::CertificateHashDataType to_ocpp(types::evse_security::CertificateHashData other) {
|
||||
ocpp::CertificateHashDataType lhs;
|
||||
lhs.hashAlgorithm = to_ocpp(other.hash_algorithm);
|
||||
lhs.issuerNameHash = other.issuer_name_hash;
|
||||
lhs.issuerKeyHash = other.issuer_key_hash;
|
||||
lhs.serialNumber = other.serial_number;
|
||||
return lhs;
|
||||
}
|
||||
|
||||
ocpp::CertificateHashDataChain to_ocpp(types::evse_security::CertificateHashDataChain other) {
|
||||
ocpp::CertificateHashDataChain lhs;
|
||||
lhs.certificateType = to_ocpp(other.certificate_type);
|
||||
lhs.certificateHashData = to_ocpp(other.certificate_hash_data);
|
||||
if (other.child_certificate_hash_data.has_value()) {
|
||||
std::vector<ocpp::CertificateHashDataType> v;
|
||||
for (const auto& certificate_hash_data : other.child_certificate_hash_data.value()) {
|
||||
v.push_back(to_ocpp(certificate_hash_data));
|
||||
}
|
||||
lhs.childCertificateHashData = v;
|
||||
}
|
||||
return lhs;
|
||||
}
|
||||
|
||||
ocpp::OCSPRequestData to_ocpp(types::evse_security::OCSPRequestData other) {
|
||||
ocpp::OCSPRequestData lhs;
|
||||
if (other.certificate_hash_data.has_value()) {
|
||||
lhs.issuerNameHash = other.certificate_hash_data.value().issuer_name_hash;
|
||||
lhs.issuerKeyHash = other.certificate_hash_data.value().issuer_key_hash;
|
||||
lhs.serialNumber = other.certificate_hash_data.value().serial_number;
|
||||
lhs.hashAlgorithm = to_ocpp(other.certificate_hash_data.value().hash_algorithm);
|
||||
}
|
||||
if (other.responder_url.has_value()) {
|
||||
lhs.responderUrl = other.responder_url.value();
|
||||
}
|
||||
return lhs;
|
||||
}
|
||||
|
||||
ocpp::CertificateOCSP to_ocpp(types::evse_security::CertificateOCSP other) {
|
||||
ocpp::CertificateOCSP lhs;
|
||||
lhs.hash = to_ocpp(other.hash);
|
||||
|
||||
if (other.ocsp_path.has_value()) {
|
||||
lhs.ocsp_path = other.ocsp_path.value();
|
||||
}
|
||||
|
||||
return lhs;
|
||||
}
|
||||
|
||||
ocpp::CertificateInfo to_ocpp(types::evse_security::CertificateInfo other) {
|
||||
ocpp::CertificateInfo lhs;
|
||||
lhs.certificate_path = other.certificate;
|
||||
lhs.certificate_single_path = other.certificate_single;
|
||||
lhs.key_path = other.key;
|
||||
lhs.password = other.password;
|
||||
lhs.certificate_count = other.certificate_count;
|
||||
|
||||
if (other.ocsp.has_value()) {
|
||||
for (auto& ocsp_data : other.ocsp.value()) {
|
||||
lhs.ocsp.push_back(to_ocpp(ocsp_data));
|
||||
}
|
||||
}
|
||||
|
||||
return lhs;
|
||||
}
|
||||
|
||||
types::evse_security::CaCertificateType from_ocpp(ocpp::CaCertificateType other) {
|
||||
switch (other) {
|
||||
case ocpp::CaCertificateType::V2G:
|
||||
return types::evse_security::CaCertificateType::V2G;
|
||||
case ocpp::CaCertificateType::MO:
|
||||
return types::evse_security::CaCertificateType::MO;
|
||||
case ocpp::CaCertificateType::CSMS:
|
||||
return types::evse_security::CaCertificateType::CSMS;
|
||||
case ocpp::CaCertificateType::MF:
|
||||
return types::evse_security::CaCertificateType::MF;
|
||||
case ocpp::CaCertificateType::OEM:
|
||||
throw std::out_of_range("Could not convert ocpp::CaCertificateType::OEM to evse_security::CaCertificateType");
|
||||
}
|
||||
throw std::out_of_range("Could not convert ocpp::CaCertificateType to evse_security::CaCertificateType");
|
||||
}
|
||||
|
||||
types::evse_security::LeafCertificateType from_ocpp(ocpp::CertificateSigningUseEnum other) {
|
||||
switch (other) {
|
||||
case ocpp::CertificateSigningUseEnum::ChargingStationCertificate:
|
||||
return types::evse_security::LeafCertificateType::CSMS;
|
||||
case ocpp::CertificateSigningUseEnum::V2GCertificate:
|
||||
return types::evse_security::LeafCertificateType::V2G;
|
||||
case ocpp::CertificateSigningUseEnum::ManufacturerCertificate:
|
||||
return types::evse_security::LeafCertificateType::MF;
|
||||
case ocpp::CertificateSigningUseEnum::V2G20Certificate:
|
||||
throw std::out_of_range("Could not convert ocpp::CertificateSigningUseEnum::V2G20Certificate to "
|
||||
"evse_security::LeafCertificateType");
|
||||
}
|
||||
throw std::out_of_range(
|
||||
"Could not convert ocpp::CertificateSigningUseEnum to types::evse_security::LeafCertificateType");
|
||||
}
|
||||
|
||||
types::evse_security::LeafCertificateType from_ocpp(ocpp::LeafCertificateType other) {
|
||||
switch (other) {
|
||||
case ocpp::LeafCertificateType::CSMS:
|
||||
return types::evse_security::LeafCertificateType::CSMS;
|
||||
case ocpp::LeafCertificateType::V2G:
|
||||
return types::evse_security::LeafCertificateType::V2G;
|
||||
case ocpp::LeafCertificateType::MF:
|
||||
return types::evse_security::LeafCertificateType::MF;
|
||||
case ocpp::LeafCertificateType::MO:
|
||||
return types::evse_security::LeafCertificateType::MO;
|
||||
}
|
||||
throw std::out_of_range(
|
||||
"Could not convert ocpp::CertificateSigningUseEnum to types::evse_security::LeafCertificateType");
|
||||
}
|
||||
|
||||
types::evse_security::CertificateType from_ocpp(ocpp::CertificateType other) {
|
||||
switch (other) {
|
||||
case ocpp::CertificateType::V2GRootCertificate:
|
||||
return types::evse_security::CertificateType::V2GRootCertificate;
|
||||
case ocpp::CertificateType::MORootCertificate:
|
||||
return types::evse_security::CertificateType::MORootCertificate;
|
||||
case ocpp::CertificateType::CSMSRootCertificate:
|
||||
return types::evse_security::CertificateType::CSMSRootCertificate;
|
||||
case ocpp::CertificateType::V2GCertificateChain:
|
||||
return types::evse_security::CertificateType::V2GCertificateChain;
|
||||
case ocpp::CertificateType::MFRootCertificate:
|
||||
return types::evse_security::CertificateType::MFRootCertificate;
|
||||
case ocpp::CertificateType::OEMRootCertificate:
|
||||
throw std::out_of_range("Could not convert ocpp::CertificateType::OEMRootCertificate to "
|
||||
"evse_security::CertificateType");
|
||||
}
|
||||
throw std::out_of_range("Could not convert ocpp::CertificateType to types::evse_security::CertificateType");
|
||||
}
|
||||
|
||||
types::evse_security::HashAlgorithm from_ocpp(ocpp::HashAlgorithmEnumType other) {
|
||||
switch (other) {
|
||||
case ocpp::HashAlgorithmEnumType::SHA256:
|
||||
return types::evse_security::HashAlgorithm::SHA256;
|
||||
case ocpp::HashAlgorithmEnumType::SHA384:
|
||||
return types::evse_security::HashAlgorithm::SHA384;
|
||||
case ocpp::HashAlgorithmEnumType::SHA512:
|
||||
return types::evse_security::HashAlgorithm::SHA512;
|
||||
}
|
||||
throw std::out_of_range("Could not convert ocpp::HashAlgorithmEnumType to types::evse_security::HashAlgorithm");
|
||||
}
|
||||
|
||||
types::evse_security::InstallCertificateResult from_ocpp(ocpp::InstallCertificateResult other) {
|
||||
switch (other) {
|
||||
case ocpp::InstallCertificateResult::InvalidSignature:
|
||||
return types::evse_security::InstallCertificateResult::InvalidSignature;
|
||||
case ocpp::InstallCertificateResult::InvalidCertificateChain:
|
||||
return types::evse_security::InstallCertificateResult::InvalidCertificateChain;
|
||||
case ocpp::InstallCertificateResult::InvalidFormat:
|
||||
return types::evse_security::InstallCertificateResult::InvalidFormat;
|
||||
case ocpp::InstallCertificateResult::InvalidCommonName:
|
||||
return types::evse_security::InstallCertificateResult::InvalidCommonName;
|
||||
case ocpp::InstallCertificateResult::NoRootCertificateInstalled:
|
||||
return types::evse_security::InstallCertificateResult::NoRootCertificateInstalled;
|
||||
case ocpp::InstallCertificateResult::Expired:
|
||||
return types::evse_security::InstallCertificateResult::Expired;
|
||||
case ocpp::InstallCertificateResult::CertificateStoreMaxLengthExceeded:
|
||||
return types::evse_security::InstallCertificateResult::CertificateStoreMaxLengthExceeded;
|
||||
case ocpp::InstallCertificateResult::WriteError:
|
||||
return types::evse_security::InstallCertificateResult::WriteError;
|
||||
case ocpp::InstallCertificateResult::Accepted:
|
||||
return types::evse_security::InstallCertificateResult::Accepted;
|
||||
}
|
||||
throw std::out_of_range(
|
||||
"Could not convert ocpp::InstallCertificateResult to types::evse_security::InstallCertificateResult");
|
||||
}
|
||||
|
||||
types::evse_security::DeleteCertificateResult from_ocpp(ocpp::DeleteCertificateResult other) {
|
||||
switch (other) {
|
||||
case ocpp::DeleteCertificateResult::Accepted:
|
||||
return types::evse_security::DeleteCertificateResult::Accepted;
|
||||
case ocpp::DeleteCertificateResult::Failed:
|
||||
return types::evse_security::DeleteCertificateResult::Failed;
|
||||
case ocpp::DeleteCertificateResult::NotFound:
|
||||
return types::evse_security::DeleteCertificateResult::NotFound;
|
||||
}
|
||||
throw std::out_of_range(
|
||||
"Could not convert ocpp::DeleteCertificateResult to types::evse_security::DeleteCertificateResult");
|
||||
}
|
||||
|
||||
types::evse_security::CertificateHashData from_ocpp(ocpp::CertificateHashDataType other) {
|
||||
types::evse_security::CertificateHashData lhs;
|
||||
lhs.hash_algorithm = from_ocpp(other.hashAlgorithm);
|
||||
lhs.issuer_name_hash = other.issuerNameHash;
|
||||
lhs.issuer_key_hash = other.issuerKeyHash;
|
||||
lhs.serial_number = other.serialNumber;
|
||||
return lhs;
|
||||
}
|
||||
|
||||
types::evse_security::CertificateHashDataChain from_ocpp(ocpp::CertificateHashDataChain other) {
|
||||
types::evse_security::CertificateHashDataChain lhs;
|
||||
lhs.certificate_type = from_ocpp(other.certificateType);
|
||||
lhs.certificate_hash_data = from_ocpp(other.certificateHashData);
|
||||
if (other.childCertificateHashData.has_value()) {
|
||||
std::vector<types::evse_security::CertificateHashData> v;
|
||||
for (const auto& certificate_hash_data : other.childCertificateHashData.value()) {
|
||||
v.push_back(from_ocpp(certificate_hash_data));
|
||||
}
|
||||
lhs.child_certificate_hash_data = v;
|
||||
}
|
||||
return lhs;
|
||||
}
|
||||
|
||||
types::evse_security::OCSPRequestData from_ocpp(ocpp::OCSPRequestData other) {
|
||||
types::evse_security::OCSPRequestData lhs;
|
||||
types::evse_security::CertificateHashData certificate_hash_data;
|
||||
certificate_hash_data.issuer_name_hash = other.issuerNameHash;
|
||||
certificate_hash_data.issuer_key_hash = other.issuerKeyHash;
|
||||
certificate_hash_data.serial_number = other.serialNumber;
|
||||
certificate_hash_data.hash_algorithm = from_ocpp(other.hashAlgorithm);
|
||||
lhs.certificate_hash_data = certificate_hash_data;
|
||||
lhs.responder_url = other.responderUrl;
|
||||
return lhs;
|
||||
}
|
||||
|
||||
types::evse_security::CertificateInfo from_ocpp(ocpp::CertificateInfo other) {
|
||||
types::evse_security::CertificateInfo lhs;
|
||||
lhs.certificate = other.certificate_path;
|
||||
lhs.certificate_single = other.certificate_single_path;
|
||||
lhs.certificate_count = other.certificate_count;
|
||||
lhs.key = other.key_path;
|
||||
lhs.password = other.password;
|
||||
return lhs;
|
||||
}
|
||||
|
||||
} // namespace conversions
|
||||
@@ -0,0 +1,425 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright Pionix GmbH and Contributors to EVerest
|
||||
|
||||
#include <everest/conversions/ocpp/ocpp_conversions.hpp>
|
||||
|
||||
#include <everest/logging.hpp>
|
||||
|
||||
#include "generated/types/display_message.hpp"
|
||||
|
||||
namespace ocpp_conversions {
|
||||
types::display_message::MessagePriorityEnum
|
||||
to_everest_display_message_priority(const ocpp::v2::MessagePriorityEnum& priority) {
|
||||
switch (priority) {
|
||||
case ocpp::v2::MessagePriorityEnum::AlwaysFront:
|
||||
return types::display_message::MessagePriorityEnum::AlwaysFront;
|
||||
case ocpp::v2::MessagePriorityEnum::InFront:
|
||||
return types::display_message::MessagePriorityEnum::InFront;
|
||||
case ocpp::v2::MessagePriorityEnum::NormalCycle:
|
||||
return types::display_message::MessagePriorityEnum::NormalCycle;
|
||||
}
|
||||
throw std::out_of_range(
|
||||
"Could not convert ocpp::v2::MessagePriorityEnum to types::display_message::MessagePriorityEnum");
|
||||
}
|
||||
|
||||
ocpp::v2::MessagePriorityEnum
|
||||
to_ocpp_201_message_priority(const types::display_message::MessagePriorityEnum& priority) {
|
||||
switch (priority) {
|
||||
case types::display_message::MessagePriorityEnum::AlwaysFront:
|
||||
return ocpp::v2::MessagePriorityEnum::AlwaysFront;
|
||||
case types::display_message::MessagePriorityEnum::InFront:
|
||||
return ocpp::v2::MessagePriorityEnum::InFront;
|
||||
case types::display_message::MessagePriorityEnum::NormalCycle:
|
||||
return ocpp::v2::MessagePriorityEnum::NormalCycle;
|
||||
}
|
||||
throw std::out_of_range(
|
||||
"Could not convert types::display_message::MessagePriorityEnum to ocpp::v2::MessagePriorityEnum");
|
||||
}
|
||||
|
||||
types::display_message::MessageStateEnum to_everest_display_message_state(const ocpp::v2::MessageStateEnum& state) {
|
||||
switch (state) {
|
||||
case ocpp::v2::MessageStateEnum::Charging:
|
||||
return types::display_message::MessageStateEnum::Charging;
|
||||
case ocpp::v2::MessageStateEnum::Faulted:
|
||||
return types::display_message::MessageStateEnum::Faulted;
|
||||
case ocpp::v2::MessageStateEnum::Idle:
|
||||
return types::display_message::MessageStateEnum::Idle;
|
||||
case ocpp::v2::MessageStateEnum::Unavailable:
|
||||
return types::display_message::MessageStateEnum::Unavailable;
|
||||
case ocpp::v2::MessageStateEnum::Suspended:
|
||||
return types::display_message::MessageStateEnum::Suspending;
|
||||
case ocpp::v2::MessageStateEnum::Discharging:
|
||||
return types::display_message::MessageStateEnum::Discharging;
|
||||
}
|
||||
throw std::out_of_range("Could not convert ocpp::v2::MessageStateEnum to types::display_message::MessageStateEnum");
|
||||
}
|
||||
|
||||
ocpp::v2::MessageStateEnum to_ocpp_201_display_message_state(const types::display_message::MessageStateEnum& state) {
|
||||
switch (state) {
|
||||
case types::display_message::MessageStateEnum::Charging:
|
||||
return ocpp::v2::MessageStateEnum::Charging;
|
||||
case types::display_message::MessageStateEnum::Faulted:
|
||||
return ocpp::v2::MessageStateEnum::Faulted;
|
||||
case types::display_message::MessageStateEnum::Idle:
|
||||
return ocpp::v2::MessageStateEnum::Idle;
|
||||
case types::display_message::MessageStateEnum::Unavailable:
|
||||
return ocpp::v2::MessageStateEnum::Unavailable;
|
||||
case types::display_message::MessageStateEnum::Suspending:
|
||||
return ocpp::v2::MessageStateEnum::Suspended;
|
||||
case types::display_message::MessageStateEnum::Discharging:
|
||||
return ocpp::v2::MessageStateEnum::Discharging;
|
||||
}
|
||||
throw std::out_of_range("Could not convert types::display_message::MessageStateEnum to ocpp::v2::MessageStateEnum");
|
||||
}
|
||||
|
||||
types::text_message::MessageFormat
|
||||
to_everest_display_message_format(const ocpp::v2::MessageFormatEnum& message_format) {
|
||||
switch (message_format) {
|
||||
case ocpp::v2::MessageFormatEnum::ASCII:
|
||||
return types::text_message::MessageFormat::ASCII;
|
||||
case ocpp::v2::MessageFormatEnum::HTML:
|
||||
return types::text_message::MessageFormat::HTML;
|
||||
case ocpp::v2::MessageFormatEnum::URI:
|
||||
return types::text_message::MessageFormat::URI;
|
||||
case ocpp::v2::MessageFormatEnum::UTF8:
|
||||
return types::text_message::MessageFormat::UTF8;
|
||||
case ocpp::v2::MessageFormatEnum::QRCODE:
|
||||
return types::text_message::MessageFormat::QRCODE;
|
||||
}
|
||||
throw std::out_of_range("Could not convert ocpp::v2::MessageFormat to types::display_message::MessageFormatEnum");
|
||||
}
|
||||
|
||||
ocpp::v2::MessageFormatEnum to_ocpp_201_message_format_enum(const types::text_message::MessageFormat& format) {
|
||||
switch (format) {
|
||||
case types::text_message::MessageFormat::ASCII:
|
||||
return ocpp::v2::MessageFormatEnum::ASCII;
|
||||
case types::text_message::MessageFormat::HTML:
|
||||
return ocpp::v2::MessageFormatEnum::HTML;
|
||||
case types::text_message::MessageFormat::URI:
|
||||
return ocpp::v2::MessageFormatEnum::URI;
|
||||
case types::text_message::MessageFormat::UTF8:
|
||||
return ocpp::v2::MessageFormatEnum::UTF8;
|
||||
case types::text_message::MessageFormat::QRCODE:
|
||||
return ocpp::v2::MessageFormatEnum::QRCODE;
|
||||
}
|
||||
|
||||
throw std::out_of_range("Could not convert types::display_message::MessageFormat to ocpp::v2::MessageFormatEnum");
|
||||
}
|
||||
|
||||
ocpp::IdentifierType to_ocpp_identifiertype_enum(const types::display_message::IdentifierType identifier_type) {
|
||||
switch (identifier_type) {
|
||||
case types::display_message::IdentifierType::IdToken:
|
||||
return ocpp::IdentifierType::IdToken;
|
||||
case types::display_message::IdentifierType::SessionId:
|
||||
return ocpp::IdentifierType::SessionId;
|
||||
case types::display_message::IdentifierType::TransactionId:
|
||||
return ocpp::IdentifierType::TransactionId;
|
||||
}
|
||||
|
||||
throw std::out_of_range("types::display_message::Identifier_type to ocpp::IdentierType");
|
||||
}
|
||||
|
||||
types::display_message::IdentifierType to_everest_identifier_type_enum(const ocpp::IdentifierType identifier_type) {
|
||||
switch (identifier_type) {
|
||||
case ocpp::IdentifierType::SessionId:
|
||||
return types::display_message::IdentifierType::SessionId;
|
||||
case ocpp::IdentifierType::IdToken:
|
||||
return types::display_message::IdentifierType::IdToken;
|
||||
case ocpp::IdentifierType::TransactionId:
|
||||
return types::display_message::IdentifierType::TransactionId;
|
||||
}
|
||||
throw std::out_of_range("ocpp::IdentierType to types::display_message::Identifier_type");
|
||||
}
|
||||
|
||||
types::text_message::MessageContent
|
||||
to_everest_display_message_content(const ocpp::DisplayMessageContent& message_content) {
|
||||
types::text_message::MessageContent message;
|
||||
message.content = message_content.message;
|
||||
if (message_content.message_format.has_value()) {
|
||||
message.format = to_everest_display_message_format(message_content.message_format.value());
|
||||
}
|
||||
message.language = message_content.language;
|
||||
|
||||
return message;
|
||||
}
|
||||
|
||||
types::display_message::DisplayMessage to_everest_display_message(const ocpp::DisplayMessage& display_message) {
|
||||
types::display_message::DisplayMessage m;
|
||||
m.id = display_message.id;
|
||||
m.message.content = display_message.message.message;
|
||||
if (display_message.message.message_format.has_value()) {
|
||||
m.message.format = to_everest_display_message_format(display_message.message.message_format.value());
|
||||
}
|
||||
m.message.language = display_message.message.language;
|
||||
|
||||
if (display_message.priority.has_value()) {
|
||||
m.priority = ocpp_conversions::to_everest_display_message_priority(display_message.priority.value());
|
||||
}
|
||||
|
||||
m.qr_code = display_message.qr_code;
|
||||
m.identifier_id = display_message.identifier_id;
|
||||
if (display_message.identifier_type.has_value()) {
|
||||
m.identifier_type = to_everest_identifier_type_enum(display_message.identifier_type.value());
|
||||
}
|
||||
|
||||
if (display_message.state.has_value()) {
|
||||
m.state = to_everest_display_message_state(display_message.state.value());
|
||||
}
|
||||
|
||||
if (display_message.timestamp_from.has_value()) {
|
||||
m.timestamp_from = display_message.timestamp_from.value().to_rfc3339();
|
||||
}
|
||||
|
||||
if (display_message.timestamp_to.has_value()) {
|
||||
m.timestamp_to = display_message.timestamp_to.value().to_rfc3339();
|
||||
}
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
ocpp::DisplayMessage to_ocpp_display_message(const types::display_message::DisplayMessage& display_message) {
|
||||
ocpp::DisplayMessage m;
|
||||
m.id = display_message.id;
|
||||
m.message.message = display_message.message.content;
|
||||
m.message.language = display_message.message.language;
|
||||
if (display_message.message.format.has_value()) {
|
||||
m.message.message_format = to_ocpp_201_message_format_enum(display_message.message.format.value());
|
||||
}
|
||||
|
||||
if (display_message.priority.has_value()) {
|
||||
m.priority = ocpp_conversions::to_ocpp_201_message_priority(display_message.priority.value());
|
||||
}
|
||||
|
||||
m.qr_code = display_message.qr_code;
|
||||
m.identifier_id = display_message.identifier_id;
|
||||
if (display_message.identifier_type.has_value()) {
|
||||
m.identifier_type = to_ocpp_identifiertype_enum(display_message.identifier_type.value());
|
||||
}
|
||||
|
||||
if (display_message.state.has_value()) {
|
||||
m.state = to_ocpp_201_display_message_state(display_message.state.value());
|
||||
}
|
||||
|
||||
try {
|
||||
if (display_message.timestamp_from.has_value()) {
|
||||
m.timestamp_from = ocpp::DateTime(display_message.timestamp_from.value());
|
||||
}
|
||||
if (display_message.timestamp_to.has_value()) {
|
||||
m.timestamp_to = ocpp::DateTime(display_message.timestamp_to.value());
|
||||
}
|
||||
} catch (const ocpp::TimePointParseException& e) {
|
||||
EVLOG_warning << "Could not parse timestamp when converting DisplayMessage: " << e.what();
|
||||
}
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
types::session_cost::TariffMessage to_everest_tariff_message(const ocpp::TariffMessage& tariff_message) {
|
||||
types::session_cost::TariffMessage m;
|
||||
m.ocpp_transaction_id = tariff_message.ocpp_transaction_id;
|
||||
m.identifier_id = tariff_message.identifier_id;
|
||||
if (tariff_message.identifier_type.has_value()) {
|
||||
m.identifier_type = to_everest_identifier_type_enum(tariff_message.identifier_type.value());
|
||||
}
|
||||
|
||||
for (const auto& message : tariff_message.message) {
|
||||
types::text_message::MessageContent content = to_everest_display_message_content(message);
|
||||
m.messages.push_back(content);
|
||||
}
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
types::session_cost::DefaultPrice to_everest_default_price(const std::vector<ocpp::DisplayMessageContent>& messages) {
|
||||
types::session_cost::DefaultPrice default_price;
|
||||
for (const auto& message : messages) {
|
||||
default_price.messages.push_back(to_everest_display_message_content(message));
|
||||
}
|
||||
return default_price;
|
||||
}
|
||||
|
||||
types::session_cost::SessionStatus to_everest_running_cost_state(const ocpp::RunningCostState& state) {
|
||||
switch (state) {
|
||||
case ocpp::RunningCostState::Charging:
|
||||
return types::session_cost::SessionStatus::Running;
|
||||
case ocpp::RunningCostState::Idle:
|
||||
return types::session_cost::SessionStatus::Idle;
|
||||
case ocpp::RunningCostState::Finished:
|
||||
return types::session_cost::SessionStatus::Finished;
|
||||
}
|
||||
throw std::out_of_range("Could not convert ocpp::RunningCostState to types::session_cost::SessionStatus");
|
||||
}
|
||||
|
||||
types::session_cost::SessionCostChunk create_session_cost_chunk(const double& price, const uint32_t& number_of_decimals,
|
||||
const std::optional<ocpp::DateTime>& timestamp,
|
||||
const std::optional<uint32_t>& meter_value) {
|
||||
types::session_cost::SessionCostChunk chunk;
|
||||
chunk.cost = types::money::MoneyAmount();
|
||||
chunk.cost->value = static_cast<int>(price * (pow(10, number_of_decimals)));
|
||||
if (timestamp.has_value()) {
|
||||
chunk.timestamp_to = timestamp.value().to_rfc3339();
|
||||
}
|
||||
chunk.metervalue_to = meter_value;
|
||||
return chunk;
|
||||
}
|
||||
|
||||
types::money::Price create_price(const double& price, const uint32_t& number_of_decimals,
|
||||
std::optional<types::money::CurrencyCode> currency_code) {
|
||||
types::money::Price p;
|
||||
types::money::Currency currency;
|
||||
currency.code = currency_code;
|
||||
currency.decimals = number_of_decimals;
|
||||
p.currency = currency;
|
||||
p.value.value = static_cast<int>(price * (pow(10, number_of_decimals)));
|
||||
return p;
|
||||
}
|
||||
|
||||
types::session_cost::ChargingPriceComponent
|
||||
create_charging_price_component(const double& price, const uint32_t& number_of_decimals,
|
||||
const types::session_cost::CostCategory category,
|
||||
std::optional<types::money::CurrencyCode> currency_code) {
|
||||
types::session_cost::ChargingPriceComponent c;
|
||||
c.category = category;
|
||||
c.price = create_price(price, number_of_decimals, currency_code);
|
||||
return c;
|
||||
}
|
||||
|
||||
types::session_cost::SessionCost create_session_cost(const ocpp::RunningCost& running_cost,
|
||||
const uint32_t number_of_decimals,
|
||||
std::optional<types::money::CurrencyCode> currency_code) {
|
||||
types::session_cost::SessionCost cost;
|
||||
cost.session_id = running_cost.transaction_id;
|
||||
cost.currency.code = currency_code;
|
||||
cost.currency.decimals = static_cast<int32_t>(number_of_decimals);
|
||||
cost.status = to_everest_running_cost_state(running_cost.state);
|
||||
cost.qr_code = running_cost.qr_code_text;
|
||||
if (running_cost.cost_messages.has_value()) {
|
||||
cost.message = std::vector<types::text_message::MessageContent>();
|
||||
for (const ocpp::DisplayMessageContent& message : running_cost.cost_messages.value()) {
|
||||
const auto m = to_everest_display_message_content(message);
|
||||
cost.message->push_back(m);
|
||||
}
|
||||
}
|
||||
|
||||
types::session_cost::SessionCostChunk chunk = create_session_cost_chunk(
|
||||
running_cost.cost, number_of_decimals, running_cost.timestamp, running_cost.meter_value);
|
||||
cost.cost_chunks = std::vector<types::session_cost::SessionCostChunk>();
|
||||
cost.cost_chunks->push_back(chunk);
|
||||
|
||||
if (running_cost.charging_price.has_value()) {
|
||||
cost.charging_price = std::vector<types::session_cost::ChargingPriceComponent>();
|
||||
const ocpp::RunningCostChargingPrice& price = running_cost.charging_price.value();
|
||||
if (price.hour_price.has_value()) {
|
||||
types::session_cost::ChargingPriceComponent hour_price = create_charging_price_component(
|
||||
price.hour_price.value(), number_of_decimals, types::session_cost::CostCategory::Time, currency_code);
|
||||
cost.charging_price->push_back(hour_price);
|
||||
}
|
||||
if (price.kWh_price.has_value()) {
|
||||
types::session_cost::ChargingPriceComponent energy_price = create_charging_price_component(
|
||||
price.kWh_price.value(), number_of_decimals, types::session_cost::CostCategory::Energy, currency_code);
|
||||
cost.charging_price->push_back(energy_price);
|
||||
}
|
||||
if (price.flat_fee.has_value()) {
|
||||
types::session_cost::ChargingPriceComponent flat_fee_price = create_charging_price_component(
|
||||
price.flat_fee.value(), number_of_decimals, types::session_cost::CostCategory::FlatFee, currency_code);
|
||||
cost.charging_price->push_back(flat_fee_price);
|
||||
}
|
||||
}
|
||||
|
||||
if (running_cost.idle_price.has_value()) {
|
||||
types::session_cost::IdlePrice idle_price;
|
||||
const ocpp::RunningCostIdlePrice& ocpp_idle_price = running_cost.idle_price.value();
|
||||
if (ocpp_idle_price.idle_hour_price.has_value()) {
|
||||
idle_price.hour_price =
|
||||
create_price(ocpp_idle_price.idle_hour_price.value(), number_of_decimals, currency_code);
|
||||
}
|
||||
|
||||
if (ocpp_idle_price.idle_grace_minutes.has_value()) {
|
||||
idle_price.grace_minutes = ocpp_idle_price.idle_grace_minutes.value();
|
||||
}
|
||||
|
||||
cost.idle_price = idle_price;
|
||||
}
|
||||
|
||||
if (running_cost.next_period_at_time.has_value() || running_cost.next_period_charging_price.has_value() ||
|
||||
running_cost.next_period_idle_price.has_value()) {
|
||||
types::session_cost::NextPeriodPrice next_period;
|
||||
if (running_cost.next_period_at_time.has_value()) {
|
||||
next_period.timestamp_from = running_cost.next_period_at_time.value().to_rfc3339();
|
||||
}
|
||||
if (running_cost.next_period_idle_price.has_value()) {
|
||||
types::session_cost::IdlePrice next_period_idle_price;
|
||||
const ocpp::RunningCostIdlePrice& ocpp_next_period_idle_price = running_cost.next_period_idle_price.value();
|
||||
if (ocpp_next_period_idle_price.idle_hour_price.has_value()) {
|
||||
next_period_idle_price.hour_price = create_price(ocpp_next_period_idle_price.idle_hour_price.value(),
|
||||
number_of_decimals, currency_code);
|
||||
}
|
||||
|
||||
if (ocpp_next_period_idle_price.idle_grace_minutes.has_value()) {
|
||||
next_period_idle_price.grace_minutes = ocpp_next_period_idle_price.idle_grace_minutes.value();
|
||||
}
|
||||
|
||||
next_period.idle_price = next_period_idle_price;
|
||||
}
|
||||
if (running_cost.next_period_charging_price.has_value()) {
|
||||
const ocpp::RunningCostChargingPrice& next_period_charging_price =
|
||||
running_cost.next_period_charging_price.value();
|
||||
|
||||
next_period.charging_price = std::vector<types::session_cost::ChargingPriceComponent>();
|
||||
|
||||
if (next_period_charging_price.hour_price.has_value()) {
|
||||
types::session_cost::ChargingPriceComponent hour_price =
|
||||
create_charging_price_component(next_period_charging_price.hour_price.value(), number_of_decimals,
|
||||
types::session_cost::CostCategory::Time, currency_code);
|
||||
next_period.charging_price.push_back(hour_price);
|
||||
}
|
||||
|
||||
if (next_period_charging_price.kWh_price.has_value()) {
|
||||
types::session_cost::ChargingPriceComponent energy_price =
|
||||
create_charging_price_component(next_period_charging_price.kWh_price.value(), number_of_decimals,
|
||||
types::session_cost::CostCategory::Energy, currency_code);
|
||||
next_period.charging_price.push_back(energy_price);
|
||||
}
|
||||
|
||||
if (next_period_charging_price.flat_fee.has_value()) {
|
||||
types::session_cost::ChargingPriceComponent flat_fee_price =
|
||||
create_charging_price_component(next_period_charging_price.flat_fee.value(), number_of_decimals,
|
||||
types::session_cost::CostCategory::FlatFee, currency_code);
|
||||
next_period.charging_price.push_back(flat_fee_price);
|
||||
}
|
||||
}
|
||||
|
||||
cost.next_period = next_period;
|
||||
}
|
||||
|
||||
return cost;
|
||||
}
|
||||
|
||||
ocpp::DateTime to_ocpp_datetime_or_now(const std::string& datetime_string) {
|
||||
std::optional<ocpp::DateTime> timestamp;
|
||||
try {
|
||||
return ocpp::DateTime(datetime_string);
|
||||
} catch (const ocpp::TimePointParseException& e) {
|
||||
EVLOG_warning << "Could not parse datetime string: " << e.what() << ". Using current DateTime instead";
|
||||
}
|
||||
return ocpp::DateTime();
|
||||
}
|
||||
|
||||
ocpp::ReservationCheckStatus
|
||||
to_ocpp_reservation_check_status(const types::reservation::ReservationCheckStatus& status) {
|
||||
switch (status) {
|
||||
case types::reservation::ReservationCheckStatus::NotReserved:
|
||||
return ocpp::ReservationCheckStatus::NotReserved;
|
||||
case types::reservation::ReservationCheckStatus::ReservedForToken:
|
||||
return ocpp::ReservationCheckStatus::ReservedForToken;
|
||||
case types::reservation::ReservationCheckStatus::ReservedForOtherToken:
|
||||
return ocpp::ReservationCheckStatus::ReservedForOtherToken;
|
||||
case types::reservation::ReservationCheckStatus::ReservedForOtherTokenAndHasParentToken:
|
||||
return ocpp::ReservationCheckStatus::ReservedForOtherTokenAndHasParentToken;
|
||||
}
|
||||
|
||||
EVLOG_warning << "Could not convert reservation check status. Returning default 'NotReserved.";
|
||||
return ocpp::ReservationCheckStatus::NotReserved;
|
||||
}
|
||||
|
||||
} // namespace ocpp_conversions
|
||||
Reference in New Issue
Block a user