// SPDX-License-Identifier: Apache-2.0 // Copyright Pionix GmbH and Contributors to EVerest #include #include #include namespace module { namespace conversions { ocpp::v2::FirmwareStatusEnum to_ocpp_firmware_status_enum(const types::system::FirmwareUpdateStatusEnum status) { switch (status) { case types::system::FirmwareUpdateStatusEnum::Downloaded: return ocpp::v2::FirmwareStatusEnum::Downloaded; case types::system::FirmwareUpdateStatusEnum::DownloadFailed: return ocpp::v2::FirmwareStatusEnum::DownloadFailed; case types::system::FirmwareUpdateStatusEnum::Downloading: return ocpp::v2::FirmwareStatusEnum::Downloading; case types::system::FirmwareUpdateStatusEnum::DownloadScheduled: return ocpp::v2::FirmwareStatusEnum::DownloadScheduled; case types::system::FirmwareUpdateStatusEnum::DownloadPaused: return ocpp::v2::FirmwareStatusEnum::DownloadPaused; case types::system::FirmwareUpdateStatusEnum::Idle: return ocpp::v2::FirmwareStatusEnum::Idle; case types::system::FirmwareUpdateStatusEnum::InstallationFailed: return ocpp::v2::FirmwareStatusEnum::InstallationFailed; case types::system::FirmwareUpdateStatusEnum::Installing: return ocpp::v2::FirmwareStatusEnum::Installing; case types::system::FirmwareUpdateStatusEnum::Installed: return ocpp::v2::FirmwareStatusEnum::Installed; case types::system::FirmwareUpdateStatusEnum::InstallRebooting: return ocpp::v2::FirmwareStatusEnum::InstallRebooting; case types::system::FirmwareUpdateStatusEnum::InstallScheduled: return ocpp::v2::FirmwareStatusEnum::InstallScheduled; case types::system::FirmwareUpdateStatusEnum::InstallVerificationFailed: return ocpp::v2::FirmwareStatusEnum::InstallVerificationFailed; case types::system::FirmwareUpdateStatusEnum::InvalidSignature: return ocpp::v2::FirmwareStatusEnum::InvalidSignature; case types::system::FirmwareUpdateStatusEnum::SignatureVerified: return ocpp::v2::FirmwareStatusEnum::SignatureVerified; } throw std::out_of_range("Could not convert FirmwareUpdateStatusEnum to FirmwareStatusEnum"); } ocpp::v2::DataTransferStatusEnum to_ocpp_data_transfer_status_enum(types::ocpp::DataTransferStatus status) { switch (status) { case types::ocpp::DataTransferStatus::Accepted: return ocpp::v2::DataTransferStatusEnum::Accepted; case types::ocpp::DataTransferStatus::Rejected: return ocpp::v2::DataTransferStatusEnum::Rejected; case types::ocpp::DataTransferStatus::UnknownMessageId: return ocpp::v2::DataTransferStatusEnum::UnknownMessageId; case types::ocpp::DataTransferStatus::UnknownVendorId: return ocpp::v2::DataTransferStatusEnum::UnknownVendorId; case types::ocpp::DataTransferStatus::Offline: return ocpp::v2::DataTransferStatusEnum::UnknownVendorId; } return ocpp::v2::DataTransferStatusEnum::UnknownVendorId; } ocpp::v2::DataTransferRequest to_ocpp_data_transfer_request(types::ocpp::DataTransferRequest request) { ocpp::v2::DataTransferRequest ocpp_request; ocpp_request.vendorId = request.vendor_id; if (request.message_id.has_value()) { ocpp_request.messageId = request.message_id.value(); } if (request.data.has_value()) { try { ocpp_request.data = json::parse(request.data.value()); } catch (const json::exception& e) { EVLOG_error << "Parsing of data transfer request data json failed because: " << "(" << e.what() << ")"; } } if (request.custom_data.has_value()) { auto custom_data = request.custom_data.value(); try { json custom_data_json = json::parse(custom_data.data); if (not custom_data_json.contains("vendorId")) { EVLOG_warning << "DataTransferRequest custom_data.data does not contain vendorId, automatically adding it"; custom_data_json["vendorId"] = custom_data.vendor_id; } ocpp_request.customData = custom_data_json; } catch (const json::exception& e) { EVLOG_error << "Parsing of data transfer request custom_data json failed because: " << "(" << e.what() << ")"; } } return ocpp_request; } ocpp::v2::DataTransferResponse to_ocpp_data_transfer_response(types::ocpp::DataTransferResponse response) { ocpp::v2::DataTransferResponse ocpp_response; ocpp_response.status = conversions::to_ocpp_data_transfer_status_enum(response.status); if (response.data.has_value()) { ocpp_response.data = json::parse(response.data.value()); } if (response.custom_data.has_value()) { auto custom_data = response.custom_data.value(); json custom_data_json = json::parse(custom_data.data); if (not custom_data_json.contains("vendorId")) { EVLOG_warning << "DataTransferResponse custom_data.data does not contain vendorId, automatically adding it"; custom_data_json["vendorId"] = custom_data.vendor_id; } ocpp_response.customData = custom_data_json; } return ocpp_response; } ocpp::v2::SampledValue to_ocpp_sampled_value(const ocpp::v2::ReadingContextEnum& reading_context, const ocpp::v2::MeasurandEnum& measurand, const std::string& unit, const std::optional phase, ocpp::v2::LocationEnum location) { ocpp::v2::SampledValue sampled_value; ocpp::v2::UnitOfMeasure unit_of_measure; sampled_value.context = reading_context; sampled_value.location = location; sampled_value.measurand = measurand; unit_of_measure.unit = unit; sampled_value.unitOfMeasure = unit_of_measure; sampled_value.phase = phase; return sampled_value; } ocpp::v2::SignedMeterValue to_ocpp_signed_meter_value(const types::units_signed::SignedMeterValue& signed_meter_value) { ocpp::v2::SignedMeterValue ocpp_signed_meter_value; ocpp_signed_meter_value.signedMeterData = signed_meter_value.signed_meter_data; ocpp_signed_meter_value.signingMethod = signed_meter_value.signing_method; ocpp_signed_meter_value.encodingMethod = signed_meter_value.encoding_method; ocpp_signed_meter_value.publicKey = signed_meter_value.public_key.value_or(""); return ocpp_signed_meter_value; } ocpp::v2::MeterValue to_ocpp_meter_value(const types::powermeter::Powermeter& power_meter, const ocpp::v2::ReadingContextEnum& reading_context, const std::optional signed_meter_value) { ocpp::v2::MeterValue meter_value; meter_value.timestamp = ocpp_conversions::to_ocpp_datetime_or_now(power_meter.timestamp); bool energy_Wh_import_signed_total_added = false; // individual signed meter values can be provided by the power_meter itself ocpp::v2::SampledValue sampled_value = to_ocpp_sampled_value( reading_context, ocpp::v2::MeasurandEnum::Energy_Active_Import_Register, "Wh", std::nullopt); // Energy.Active.Import.Register if (power_meter.energy_Wh_import_signed.has_value()) { sampled_value.value = power_meter.energy_Wh_import.total; const auto& energy_Wh_import_signed = power_meter.energy_Wh_import_signed.value(); if (energy_Wh_import_signed.total.has_value()) { sampled_value.signedMeterValue = to_ocpp_signed_meter_value(energy_Wh_import_signed.total.value()); energy_Wh_import_signed_total_added = true; } meter_value.sampledValue.push_back(sampled_value); } if (not energy_Wh_import_signed_total_added) { // No signed meter value for Energy.Active.Import.Register added, either no signed meter values are available or // just one global signed_meter_value is present signed_meter_value is intended for OCMF style blobs of signed // meter value reports during transaction start or end // This is interpreted as Energy.Active.Import.Register sampled_value = to_ocpp_sampled_value(reading_context, ocpp::v2::MeasurandEnum::Energy_Active_Import_Register, "Wh", std::nullopt); sampled_value.value = power_meter.energy_Wh_import.total; // add signedMeterValue if present if (signed_meter_value.has_value()) { sampled_value.signedMeterValue = to_ocpp_signed_meter_value(signed_meter_value.value()); } meter_value.sampledValue.push_back(sampled_value); } if (power_meter.energy_Wh_import.L1.has_value()) { sampled_value = to_ocpp_sampled_value(reading_context, ocpp::v2::MeasurandEnum::Energy_Active_Import_Register, "Wh", ocpp::v2::PhaseEnum::L1); sampled_value.value = power_meter.energy_Wh_import.L1.value(); if (power_meter.energy_Wh_import_signed.has_value()) { const auto& energy_Wh_import_signed = power_meter.energy_Wh_import_signed.value(); if (energy_Wh_import_signed.L1.has_value()) { sampled_value.signedMeterValue = to_ocpp_signed_meter_value(energy_Wh_import_signed.L1.value()); } } meter_value.sampledValue.push_back(sampled_value); } if (power_meter.energy_Wh_import.L2.has_value()) { sampled_value = to_ocpp_sampled_value(reading_context, ocpp::v2::MeasurandEnum::Energy_Active_Import_Register, "Wh", ocpp::v2::PhaseEnum::L2); sampled_value.value = power_meter.energy_Wh_import.L2.value(); if (power_meter.energy_Wh_import_signed.has_value()) { const auto& energy_Wh_import_signed = power_meter.energy_Wh_import_signed.value(); if (energy_Wh_import_signed.L2.has_value()) { sampled_value.signedMeterValue = to_ocpp_signed_meter_value(energy_Wh_import_signed.L2.value()); } } meter_value.sampledValue.push_back(sampled_value); } if (power_meter.energy_Wh_import.L3.has_value()) { sampled_value = to_ocpp_sampled_value(reading_context, ocpp::v2::MeasurandEnum::Energy_Active_Import_Register, "Wh", ocpp::v2::PhaseEnum::L3); sampled_value.value = power_meter.energy_Wh_import.L3.value(); if (power_meter.energy_Wh_import_signed.has_value()) { const auto& energy_Wh_import_signed = power_meter.energy_Wh_import_signed.value(); if (energy_Wh_import_signed.L3.has_value()) { sampled_value.signedMeterValue = to_ocpp_signed_meter_value(energy_Wh_import_signed.L3.value()); } } meter_value.sampledValue.push_back(sampled_value); } // Energy.Active.Export.Register if (power_meter.energy_Wh_export.has_value()) { auto sampled_value = to_ocpp_sampled_value( reading_context, ocpp::v2::MeasurandEnum::Energy_Active_Export_Register, "Wh", std::nullopt); sampled_value.value = power_meter.energy_Wh_export.value().total; if (power_meter.energy_Wh_export_signed.has_value()) { const auto& energy_Wh_export_signed = power_meter.energy_Wh_export_signed.value(); if (energy_Wh_export_signed.total.has_value()) { sampled_value.signedMeterValue = to_ocpp_signed_meter_value(energy_Wh_export_signed.total.value()); } } meter_value.sampledValue.push_back(sampled_value); if (power_meter.energy_Wh_export.value().L1.has_value()) { sampled_value = to_ocpp_sampled_value( reading_context, ocpp::v2::MeasurandEnum::Energy_Active_Export_Register, "Wh", ocpp::v2::PhaseEnum::L1); sampled_value.value = power_meter.energy_Wh_export.value().L1.value(); if (power_meter.energy_Wh_export_signed.has_value()) { const auto& energy_Wh_export_signed = power_meter.energy_Wh_export_signed.value(); if (energy_Wh_export_signed.L1.has_value()) { sampled_value.signedMeterValue = to_ocpp_signed_meter_value(energy_Wh_export_signed.L1.value()); } } meter_value.sampledValue.push_back(sampled_value); } if (power_meter.energy_Wh_export.value().L2.has_value()) { sampled_value = to_ocpp_sampled_value( reading_context, ocpp::v2::MeasurandEnum::Energy_Active_Export_Register, "Wh", ocpp::v2::PhaseEnum::L2); sampled_value.value = power_meter.energy_Wh_export.value().L2.value(); if (power_meter.energy_Wh_export_signed.has_value()) { const auto& energy_Wh_export_signed = power_meter.energy_Wh_export_signed.value(); if (energy_Wh_export_signed.L2.has_value()) { sampled_value.signedMeterValue = to_ocpp_signed_meter_value(energy_Wh_export_signed.L2.value()); } } meter_value.sampledValue.push_back(sampled_value); } if (power_meter.energy_Wh_export.value().L3.has_value()) { sampled_value = to_ocpp_sampled_value( reading_context, ocpp::v2::MeasurandEnum::Energy_Active_Export_Register, "Wh", ocpp::v2::PhaseEnum::L3); sampled_value.value = power_meter.energy_Wh_export.value().L3.value(); if (power_meter.energy_Wh_export_signed.has_value()) { const auto& energy_Wh_export_signed = power_meter.energy_Wh_export_signed.value(); if (energy_Wh_export_signed.L3.has_value()) { sampled_value.signedMeterValue = to_ocpp_signed_meter_value(energy_Wh_export_signed.L3.value()); } } meter_value.sampledValue.push_back(sampled_value); } } // Power.Active.Import if (power_meter.power_W.has_value()) { auto sampled_value = to_ocpp_sampled_value(reading_context, ocpp::v2::MeasurandEnum::Power_Active_Import, "W", std::nullopt); sampled_value.value = power_meter.power_W.value().total; if (power_meter.power_W_signed.has_value()) { const auto& power_W_signed = power_meter.power_W_signed.value(); if (power_W_signed.total.has_value()) { sampled_value.signedMeterValue = to_ocpp_signed_meter_value(power_W_signed.total.value()); } } meter_value.sampledValue.push_back(sampled_value); if (power_meter.power_W.value().L1.has_value()) { sampled_value = to_ocpp_sampled_value(reading_context, ocpp::v2::MeasurandEnum::Power_Active_Import, "W", ocpp::v2::PhaseEnum::L1); sampled_value.value = power_meter.power_W.value().L1.value(); if (power_meter.power_W_signed.has_value()) { const auto& power_W_signed = power_meter.power_W_signed.value(); if (power_W_signed.L1.has_value()) { sampled_value.signedMeterValue = to_ocpp_signed_meter_value(power_W_signed.L1.value()); } } meter_value.sampledValue.push_back(sampled_value); } if (power_meter.power_W.value().L2.has_value()) { sampled_value = to_ocpp_sampled_value(reading_context, ocpp::v2::MeasurandEnum::Power_Active_Import, "W", ocpp::v2::PhaseEnum::L2); sampled_value.value = power_meter.power_W.value().L2.value(); if (power_meter.power_W_signed.has_value()) { const auto& power_W_signed = power_meter.power_W_signed.value(); if (power_W_signed.L2.has_value()) { sampled_value.signedMeterValue = to_ocpp_signed_meter_value(power_W_signed.L2.value()); } } meter_value.sampledValue.push_back(sampled_value); } if (power_meter.power_W.value().L3.has_value()) { sampled_value = to_ocpp_sampled_value(reading_context, ocpp::v2::MeasurandEnum::Power_Active_Import, "W", ocpp::v2::PhaseEnum::L3); sampled_value.value = power_meter.power_W.value().L3.value(); if (power_meter.power_W_signed.has_value()) { const auto& power_W_signed = power_meter.power_W_signed.value(); if (power_W_signed.L3.has_value()) { sampled_value.signedMeterValue = to_ocpp_signed_meter_value(power_W_signed.L3.value()); } } meter_value.sampledValue.push_back(sampled_value); } } // Power.Reactive.Import if (power_meter.VAR.has_value()) { auto sampled_value = to_ocpp_sampled_value(reading_context, ocpp::v2::MeasurandEnum::Power_Reactive_Import, "var", std::nullopt); sampled_value.value = power_meter.VAR.value().total; if (power_meter.VAR_signed.has_value()) { const auto& VAR_signed = power_meter.VAR_signed.value(); if (VAR_signed.total.has_value()) { sampled_value.signedMeterValue = to_ocpp_signed_meter_value(VAR_signed.total.value()); } } meter_value.sampledValue.push_back(sampled_value); if (power_meter.VAR.value().L1.has_value()) { sampled_value = to_ocpp_sampled_value(reading_context, ocpp::v2::MeasurandEnum::Power_Reactive_Import, "var", ocpp::v2::PhaseEnum::L1); sampled_value.value = power_meter.VAR.value().L1.value(); if (power_meter.VAR_signed.has_value()) { const auto& VAR_signed = power_meter.VAR_signed.value(); if (VAR_signed.L1.has_value()) { sampled_value.signedMeterValue = to_ocpp_signed_meter_value(VAR_signed.L1.value()); } } meter_value.sampledValue.push_back(sampled_value); } if (power_meter.VAR.value().L2.has_value()) { sampled_value = to_ocpp_sampled_value(reading_context, ocpp::v2::MeasurandEnum::Power_Reactive_Import, "var", ocpp::v2::PhaseEnum::L2); sampled_value.value = power_meter.VAR.value().L2.value(); if (power_meter.VAR_signed.has_value()) { const auto& VAR_signed = power_meter.VAR_signed.value(); if (VAR_signed.L2.has_value()) { sampled_value.signedMeterValue = to_ocpp_signed_meter_value(VAR_signed.L2.value()); } } meter_value.sampledValue.push_back(sampled_value); } if (power_meter.VAR.value().L3.has_value()) { sampled_value = to_ocpp_sampled_value(reading_context, ocpp::v2::MeasurandEnum::Power_Reactive_Import, "var", ocpp::v2::PhaseEnum::L3); sampled_value.value = power_meter.VAR.value().L3.value(); if (power_meter.VAR_signed.has_value()) { const auto& VAR_signed = power_meter.VAR_signed.value(); if (VAR_signed.L3.has_value()) { sampled_value.signedMeterValue = to_ocpp_signed_meter_value(VAR_signed.L3.value()); } } meter_value.sampledValue.push_back(sampled_value); } } // Current.Import if (power_meter.current_A.has_value()) { auto sampled_value = to_ocpp_sampled_value(reading_context, ocpp::v2::MeasurandEnum::Current_Import, "A", std::nullopt); if (power_meter.current_A.value().L1.has_value()) { sampled_value = to_ocpp_sampled_value(reading_context, ocpp::v2::MeasurandEnum::Current_Import, "A", ocpp::v2::PhaseEnum::L1); sampled_value.value = power_meter.current_A.value().L1.value(); if (power_meter.current_A_signed.has_value()) { const auto& current_A_signed = power_meter.current_A_signed.value(); if (current_A_signed.L1.has_value()) { sampled_value.signedMeterValue = to_ocpp_signed_meter_value(current_A_signed.L1.value()); } } meter_value.sampledValue.push_back(sampled_value); } if (power_meter.current_A.value().L2.has_value()) { sampled_value = to_ocpp_sampled_value(reading_context, ocpp::v2::MeasurandEnum::Current_Import, "A", ocpp::v2::PhaseEnum::L2); sampled_value.value = power_meter.current_A.value().L2.value(); if (power_meter.current_A_signed.has_value()) { const auto& current_A_signed = power_meter.current_A_signed.value(); if (current_A_signed.L2.has_value()) { sampled_value.signedMeterValue = to_ocpp_signed_meter_value(current_A_signed.L2.value()); } } meter_value.sampledValue.push_back(sampled_value); } if (power_meter.current_A.value().L3.has_value()) { sampled_value = to_ocpp_sampled_value(reading_context, ocpp::v2::MeasurandEnum::Current_Import, "A", ocpp::v2::PhaseEnum::L3); sampled_value.value = power_meter.current_A.value().L3.value(); if (power_meter.current_A_signed.has_value()) { const auto& current_A_signed = power_meter.current_A_signed.value(); if (current_A_signed.L3.has_value()) { sampled_value.signedMeterValue = to_ocpp_signed_meter_value(current_A_signed.L3.value()); } } meter_value.sampledValue.push_back(sampled_value); } if (power_meter.current_A.value().DC.has_value()) { sampled_value = to_ocpp_sampled_value(reading_context, ocpp::v2::MeasurandEnum::Current_Import, "A", std::nullopt); sampled_value.value = power_meter.current_A.value().DC.value(); if (power_meter.current_A_signed.has_value()) { const auto& current_A_signed = power_meter.current_A_signed.value(); if (current_A_signed.DC.has_value()) { sampled_value.signedMeterValue = to_ocpp_signed_meter_value(current_A_signed.DC.value()); } } meter_value.sampledValue.push_back(sampled_value); } if (power_meter.current_A.value().N.has_value()) { sampled_value = to_ocpp_sampled_value(reading_context, ocpp::v2::MeasurandEnum::Current_Import, "A", ocpp::v2::PhaseEnum::N); sampled_value.value = power_meter.current_A.value().N.value(); if (power_meter.current_A_signed.has_value()) { const auto& current_A_signed = power_meter.current_A_signed.value(); if (current_A_signed.N.has_value()) { sampled_value.signedMeterValue = to_ocpp_signed_meter_value(current_A_signed.N.value()); } } meter_value.sampledValue.push_back(sampled_value); } } // Voltage if (power_meter.voltage_V.has_value()) { if (power_meter.voltage_V.value().L1.has_value()) { sampled_value = to_ocpp_sampled_value(reading_context, ocpp::v2::MeasurandEnum::Voltage, "V", ocpp::v2::PhaseEnum::L1_N); sampled_value.value = power_meter.voltage_V.value().L1.value(); if (power_meter.voltage_V_signed.has_value()) { const auto& voltage_V_signed = power_meter.voltage_V_signed.value(); if (voltage_V_signed.L1.has_value()) { sampled_value.signedMeterValue = to_ocpp_signed_meter_value(voltage_V_signed.L1.value()); } } meter_value.sampledValue.push_back(sampled_value); } if (power_meter.voltage_V.value().L2.has_value()) { sampled_value = to_ocpp_sampled_value(reading_context, ocpp::v2::MeasurandEnum::Voltage, "V", ocpp::v2::PhaseEnum::L2_N); sampled_value.value = power_meter.voltage_V.value().L2.value(); if (power_meter.voltage_V_signed.has_value()) { const auto& voltage_V_signed = power_meter.voltage_V_signed.value(); if (voltage_V_signed.L2.has_value()) { sampled_value.signedMeterValue = to_ocpp_signed_meter_value(voltage_V_signed.L2.value()); } } meter_value.sampledValue.push_back(sampled_value); } if (power_meter.voltage_V.value().L3.has_value()) { sampled_value = to_ocpp_sampled_value(reading_context, ocpp::v2::MeasurandEnum::Voltage, "V", ocpp::v2::PhaseEnum::L3_N); sampled_value.value = power_meter.voltage_V.value().L3.value(); if (power_meter.voltage_V_signed.has_value()) { const auto& voltage_V_signed = power_meter.voltage_V_signed.value(); if (voltage_V_signed.L3.has_value()) { sampled_value.signedMeterValue = to_ocpp_signed_meter_value(voltage_V_signed.L3.value()); } } meter_value.sampledValue.push_back(sampled_value); } if (power_meter.voltage_V.value().DC.has_value()) { sampled_value = to_ocpp_sampled_value(reading_context, ocpp::v2::MeasurandEnum::Voltage, "V", std::nullopt); sampled_value.value = power_meter.voltage_V.value().DC.value(); if (power_meter.voltage_V_signed.has_value()) { const auto& voltage_V_signed = power_meter.voltage_V_signed.value(); if (voltage_V_signed.DC.has_value()) { sampled_value.signedMeterValue = to_ocpp_signed_meter_value(voltage_V_signed.DC.value()); } } meter_value.sampledValue.push_back(sampled_value); } } return meter_value; } ocpp::v2::LogStatusEnum to_ocpp_log_status_enum(types::system::UploadLogsStatus log_status) { switch (log_status) { case types::system::UploadLogsStatus::Accepted: return ocpp::v2::LogStatusEnum::Accepted; case types::system::UploadLogsStatus::Rejected: return ocpp::v2::LogStatusEnum::Rejected; case types::system::UploadLogsStatus::AcceptedCanceled: return ocpp::v2::LogStatusEnum::AcceptedCanceled; } throw std::runtime_error("Could not convert UploadLogsStatus"); } ocpp::v2::GetLogResponse to_ocpp_get_log_response(const types::system::UploadLogsResponse& response) { ocpp::v2::GetLogResponse _response; _response.status = to_ocpp_log_status_enum(response.upload_logs_status); if (response.file_name.has_value()) { // we just truncate here since the upload operation could have already been started by the system module and // we cant do much about it, so best we can do is truncate the filename and rather make sure in the system // module that shorter filenames are used _response.filename = ocpp::CiString<255>(response.file_name.value(), ocpp::StringTooLarge::Truncate); } return _response; } ocpp::v2::UpdateFirmwareStatusEnum to_ocpp_update_firmware_status_enum(const types::system::UpdateFirmwareResponse& response) { switch (response) { case types::system::UpdateFirmwareResponse::Accepted: return ocpp::v2::UpdateFirmwareStatusEnum::Accepted; case types::system::UpdateFirmwareResponse::Rejected: return ocpp::v2::UpdateFirmwareStatusEnum::Rejected; case types::system::UpdateFirmwareResponse::AcceptedCanceled: return ocpp::v2::UpdateFirmwareStatusEnum::AcceptedCanceled; case types::system::UpdateFirmwareResponse::InvalidCertificate: return ocpp::v2::UpdateFirmwareStatusEnum::InvalidCertificate; case types::system::UpdateFirmwareResponse::RevokedCertificate: return ocpp::v2::UpdateFirmwareStatusEnum::RevokedCertificate; } throw std::runtime_error("Could not convert UpdateFirmwareResponse"); } ocpp::v2::UpdateFirmwareResponse to_ocpp_update_firmware_response(const types::system::UpdateFirmwareResponse& response) { ocpp::v2::UpdateFirmwareResponse _response; _response.status = conversions::to_ocpp_update_firmware_status_enum(response); return _response; } ocpp::v2::UploadLogStatusEnum to_ocpp_upload_logs_status_enum(types::system::LogStatusEnum status) { switch (status) { case types::system::LogStatusEnum::BadMessage: return ocpp::v2::UploadLogStatusEnum::BadMessage; case types::system::LogStatusEnum::Idle: return ocpp::v2::UploadLogStatusEnum::Idle; case types::system::LogStatusEnum::NotSupportedOperation: return ocpp::v2::UploadLogStatusEnum::NotSupportedOperation; case types::system::LogStatusEnum::PermissionDenied: return ocpp::v2::UploadLogStatusEnum::PermissionDenied; case types::system::LogStatusEnum::Uploaded: return ocpp::v2::UploadLogStatusEnum::Uploaded; case types::system::LogStatusEnum::UploadFailure: return ocpp::v2::UploadLogStatusEnum::UploadFailure; case types::system::LogStatusEnum::Uploading: return ocpp::v2::UploadLogStatusEnum::Uploading; case types::system::LogStatusEnum::AcceptedCanceled: return ocpp::v2::UploadLogStatusEnum::AcceptedCanceled; } throw std::runtime_error("Could not convert UploadLogStatusEnum"); } ocpp::v2::BootReasonEnum to_ocpp_boot_reason(types::system::BootReason reason) { switch (reason) { case types::system::BootReason::ApplicationReset: return ocpp::v2::BootReasonEnum::ApplicationReset; case types::system::BootReason::FirmwareUpdate: return ocpp::v2::BootReasonEnum::FirmwareUpdate; case types::system::BootReason::LocalReset: return ocpp::v2::BootReasonEnum::LocalReset; case types::system::BootReason::PowerUp: return ocpp::v2::BootReasonEnum::PowerUp; case types::system::BootReason::RemoteReset: return ocpp::v2::BootReasonEnum::RemoteReset; case types::system::BootReason::ScheduledReset: return ocpp::v2::BootReasonEnum::ScheduledReset; case types::system::BootReason::Triggered: return ocpp::v2::BootReasonEnum::Triggered; case types::system::BootReason::Unknown: return ocpp::v2::BootReasonEnum::Unknown; case types::system::BootReason::Watchdog: return ocpp::v2::BootReasonEnum::Watchdog; } throw std::runtime_error("Could not convert BootReasonEnum"); } ocpp::v2::ReasonEnum to_ocpp_reason(types::evse_manager::StopTransactionReason reason) { switch (reason) { case types::evse_manager::StopTransactionReason::DeAuthorized: return ocpp::v2::ReasonEnum::DeAuthorized; case types::evse_manager::StopTransactionReason::EmergencyStop: return ocpp::v2::ReasonEnum::EmergencyStop; case types::evse_manager::StopTransactionReason::EnergyLimitReached: return ocpp::v2::ReasonEnum::EnergyLimitReached; case types::evse_manager::StopTransactionReason::EVDisconnected: return ocpp::v2::ReasonEnum::EVDisconnected; case types::evse_manager::StopTransactionReason::GroundFault: return ocpp::v2::ReasonEnum::GroundFault; case types::evse_manager::StopTransactionReason::HardReset: return ocpp::v2::ReasonEnum::ImmediateReset; case types::evse_manager::StopTransactionReason::Local: return ocpp::v2::ReasonEnum::Local; case types::evse_manager::StopTransactionReason::LocalOutOfCredit: return ocpp::v2::ReasonEnum::LocalOutOfCredit; case types::evse_manager::StopTransactionReason::MasterPass: return ocpp::v2::ReasonEnum::MasterPass; case types::evse_manager::StopTransactionReason::Other: return ocpp::v2::ReasonEnum::Other; case types::evse_manager::StopTransactionReason::OvercurrentFault: return ocpp::v2::ReasonEnum::OvercurrentFault; case types::evse_manager::StopTransactionReason::PowerLoss: return ocpp::v2::ReasonEnum::PowerLoss; case types::evse_manager::StopTransactionReason::PowerQuality: return ocpp::v2::ReasonEnum::PowerQuality; case types::evse_manager::StopTransactionReason::Reboot: return ocpp::v2::ReasonEnum::Reboot; case types::evse_manager::StopTransactionReason::Remote: return ocpp::v2::ReasonEnum::Remote; case types::evse_manager::StopTransactionReason::SOCLimitReached: return ocpp::v2::ReasonEnum::SOCLimitReached; case types::evse_manager::StopTransactionReason::StoppedByEV: return ocpp::v2::ReasonEnum::StoppedByEV; case types::evse_manager::StopTransactionReason::TimeLimitReached: return ocpp::v2::ReasonEnum::TimeLimitReached; case types::evse_manager::StopTransactionReason::Timeout: return ocpp::v2::ReasonEnum::Timeout; case types::evse_manager::StopTransactionReason::ReqEnergyTransferRejected: return ocpp::v2::ReasonEnum::ReqEnergyTransferRejected; case types::evse_manager::StopTransactionReason::SoftReset: case types::evse_manager::StopTransactionReason::UnlockCommand: case types::evse_manager::StopTransactionReason::EVSEDisabled: return ocpp::v2::ReasonEnum::Other; } return ocpp::v2::ReasonEnum::Other; } ocpp::v2::IdToken to_ocpp_id_token(const types::authorization::IdToken& id_token) { ocpp::v2::IdToken ocpp_id_token = {id_token.value, types::authorization::id_token_type_to_string(id_token.type)}; if (id_token.additional_info.has_value()) { std::vector ocpp_additional_info; const auto& additional_info = id_token.additional_info.value(); for (const auto& entry : additional_info) { ocpp_additional_info.push_back({entry.value, entry.type}); } ocpp_id_token.additionalInfo = ocpp_additional_info; } return ocpp_id_token; } ocpp::v2::CertificateActionEnum to_ocpp_certificate_action_enum(const types::iso15118::CertificateActionEnum& action) { switch (action) { case types::iso15118::CertificateActionEnum::Install: return ocpp::v2::CertificateActionEnum::Install; case types::iso15118::CertificateActionEnum::Update: return ocpp::v2::CertificateActionEnum::Update; } throw std::out_of_range("Could not convert CertificateActionEnum"); // this should never happen } types::evse_manager::StopTransactionReason to_everest_stop_transaction_reason(const ocpp::v2::ReasonEnum& stop_reason) { switch (stop_reason) { case ocpp::v2::ReasonEnum::DeAuthorized: return types::evse_manager::StopTransactionReason::DeAuthorized; case ocpp::v2::ReasonEnum::EmergencyStop: return types::evse_manager::StopTransactionReason::EmergencyStop; case ocpp::v2::ReasonEnum::EnergyLimitReached: return types::evse_manager::StopTransactionReason::EnergyLimitReached; case ocpp::v2::ReasonEnum::EVDisconnected: return types::evse_manager::StopTransactionReason::EVDisconnected; case ocpp::v2::ReasonEnum::GroundFault: return types::evse_manager::StopTransactionReason::GroundFault; case ocpp::v2::ReasonEnum::ImmediateReset: return types::evse_manager::StopTransactionReason::HardReset; case ocpp::v2::ReasonEnum::Local: return types::evse_manager::StopTransactionReason::Local; case ocpp::v2::ReasonEnum::LocalOutOfCredit: return types::evse_manager::StopTransactionReason::LocalOutOfCredit; case ocpp::v2::ReasonEnum::MasterPass: return types::evse_manager::StopTransactionReason::MasterPass; case ocpp::v2::ReasonEnum::Other: return types::evse_manager::StopTransactionReason::Other; case ocpp::v2::ReasonEnum::OvercurrentFault: return types::evse_manager::StopTransactionReason::OvercurrentFault; case ocpp::v2::ReasonEnum::PowerLoss: return types::evse_manager::StopTransactionReason::PowerLoss; case ocpp::v2::ReasonEnum::PowerQuality: return types::evse_manager::StopTransactionReason::PowerQuality; case ocpp::v2::ReasonEnum::Reboot: return types::evse_manager::StopTransactionReason::Reboot; case ocpp::v2::ReasonEnum::Remote: return types::evse_manager::StopTransactionReason::Remote; case ocpp::v2::ReasonEnum::SOCLimitReached: return types::evse_manager::StopTransactionReason::SOCLimitReached; case ocpp::v2::ReasonEnum::StoppedByEV: return types::evse_manager::StopTransactionReason::StoppedByEV; case ocpp::v2::ReasonEnum::TimeLimitReached: return types::evse_manager::StopTransactionReason::TimeLimitReached; case ocpp::v2::ReasonEnum::Timeout: return types::evse_manager::StopTransactionReason::Timeout; case ocpp::v2::ReasonEnum::ReqEnergyTransferRejected: return types::evse_manager::StopTransactionReason::ReqEnergyTransferRejected; } return types::evse_manager::StopTransactionReason::Other; } std::vector to_ocpp_ocsp_request_data_vector( const std::vector& certificate_hash_data_info) { std::vector ocsp_request_data_list; for (const auto& certificate_hash_data : certificate_hash_data_info) { ocpp::v2::OCSPRequestData ocsp_request_data; ocsp_request_data.hashAlgorithm = conversions::to_ocpp_hash_algorithm_enum(certificate_hash_data.hashAlgorithm); ocsp_request_data.issuerKeyHash = certificate_hash_data.issuerKeyHash; ocsp_request_data.issuerNameHash = certificate_hash_data.issuerNameHash; ocsp_request_data.responderURL = certificate_hash_data.responderURL; ocsp_request_data.serialNumber = certificate_hash_data.serialNumber; ocsp_request_data_list.push_back(ocsp_request_data); } return ocsp_request_data_list; } ocpp::v2::HashAlgorithmEnum to_ocpp_hash_algorithm_enum(const types::iso15118::HashAlgorithm hash_algorithm) { switch (hash_algorithm) { case types::iso15118::HashAlgorithm::SHA256: return ocpp::v2::HashAlgorithmEnum::SHA256; case types::iso15118::HashAlgorithm::SHA384: return ocpp::v2::HashAlgorithmEnum::SHA384; case types::iso15118::HashAlgorithm::SHA512: return ocpp::v2::HashAlgorithmEnum::SHA512; } throw std::out_of_range("Could not convert types::iso15118::HashAlgorithm to ocpp::v2::HashAlgorithmEnum"); } std::vector to_ocpp_get_variable_data_vector(const std::vector& get_variable_request_vector) { std::vector ocpp_get_variable_data_vector; for (const auto& get_variable_request : get_variable_request_vector) { ocpp::v2::GetVariableData get_variable_data; get_variable_data.component = to_ocpp_component(get_variable_request.component_variable.component); get_variable_data.variable = to_ocpp_variable(get_variable_request.component_variable.variable); if (get_variable_request.attribute_type.has_value()) { get_variable_data.attributeType = to_ocpp_attribute_enum(get_variable_request.attribute_type.value()); } ocpp_get_variable_data_vector.push_back(get_variable_data); } return ocpp_get_variable_data_vector; } std::vector to_ocpp_set_variable_data_vector(const std::vector& set_variable_request_vector) { std::vector ocpp_set_variable_data_vector; for (const auto& set_variable_request : set_variable_request_vector) { ocpp::v2::SetVariableData set_variable_data; set_variable_data.component = to_ocpp_component(set_variable_request.component_variable.component); set_variable_data.variable = to_ocpp_variable(set_variable_request.component_variable.variable); if (set_variable_request.attribute_type.has_value()) { set_variable_data.attributeType = to_ocpp_attribute_enum(set_variable_request.attribute_type.value()); } try { set_variable_data.attributeValue = set_variable_request.value; } catch (std::runtime_error& e) { EVLOG_error << "Could not convert attributeValue to CiString"; continue; } ocpp_set_variable_data_vector.push_back(set_variable_data); } return ocpp_set_variable_data_vector; } ocpp::v2::Component to_ocpp_component(const types::ocpp::Component& component) { ocpp::v2::Component _component; _component.name = component.name; if (component.evse.has_value()) { _component.evse = to_ocpp_evse(component.evse.value()); } if (component.instance.has_value()) { _component.instance = component.instance.value(); } return _component; } ocpp::v2::Variable to_ocpp_variable(const types::ocpp::Variable& variable) { ocpp::v2::Variable _variable; _variable.name = variable.name; if (variable.instance.has_value()) { _variable.instance = variable.instance.value(); } return _variable; } ocpp::v2::EVSE to_ocpp_evse(const types::ocpp::EVSE& evse) { ocpp::v2::EVSE _evse; _evse.id = evse.id; if (evse.connector_id.has_value()) { _evse.connectorId = evse.connector_id.value(); } return _evse; } ocpp::v2::AttributeEnum to_ocpp_attribute_enum(const types::ocpp::AttributeEnum attribute_enum) { switch (attribute_enum) { case types::ocpp::AttributeEnum::Actual: return ocpp::v2::AttributeEnum::Actual; case types::ocpp::AttributeEnum::Target: return ocpp::v2::AttributeEnum::Target; case types::ocpp::AttributeEnum::MinSet: return ocpp::v2::AttributeEnum::MinSet; case types::ocpp::AttributeEnum::MaxSet: return ocpp::v2::AttributeEnum::MaxSet; } throw std::out_of_range("Could not convert AttributeEnum"); } ocpp::v2::Get15118EVCertificateRequest to_ocpp_get_15118_certificate_request(const types::iso15118::RequestExiStreamSchema& request) { ocpp::v2::Get15118EVCertificateRequest _request; _request.iso15118SchemaVersion = request.iso15118_schema_version; _request.exiRequest = request.exi_request; _request.action = conversions::to_ocpp_certificate_action_enum(request.certificate_action); return _request; } ocpp::v2::EnergyTransferModeEnum to_ocpp_energy_transfer_mode(const types::iso15118::EnergyTransferMode transfer_mode) { switch (transfer_mode) { case types::iso15118::EnergyTransferMode::AC_single_phase_core: return ocpp::v2::EnergyTransferModeEnum::AC_single_phase; case types::iso15118::EnergyTransferMode::AC_two_phase: return ocpp::v2::EnergyTransferModeEnum::AC_two_phase; case types::iso15118::EnergyTransferMode::AC_three_phase_core: return ocpp::v2::EnergyTransferModeEnum::AC_three_phase; case types::iso15118::EnergyTransferMode::DC: case types::iso15118::EnergyTransferMode::DC_core: case types::iso15118::EnergyTransferMode::DC_extended: case types::iso15118::EnergyTransferMode::DC_combo_core: case types::iso15118::EnergyTransferMode::DC_unique: return ocpp::v2::EnergyTransferModeEnum::DC; // OCPP 2.1+ enums case types::iso15118::EnergyTransferMode::AC_BPT: return ocpp::v2::EnergyTransferModeEnum::AC_BPT; case types::iso15118::EnergyTransferMode::AC_BPT_DER: return ocpp::v2::EnergyTransferModeEnum::AC_BPT_DER; case types::iso15118::EnergyTransferMode::AC_DER: return ocpp::v2::EnergyTransferModeEnum::AC_DER; case types::iso15118::EnergyTransferMode::DC_BPT: return ocpp::v2::EnergyTransferModeEnum::DC_BPT; case types::iso15118::EnergyTransferMode::DC_ACDP: return ocpp::v2::EnergyTransferModeEnum::DC_ACDP; case types::iso15118::EnergyTransferMode::DC_ACDP_BPT: return ocpp::v2::EnergyTransferModeEnum::DC_ACDP_BPT; case types::iso15118::EnergyTransferMode::WPT: return ocpp::v2::EnergyTransferModeEnum::WPT; // revisit: OCPP does not yet know about MCS case types::iso15118::EnergyTransferMode::MCS: return ocpp::v2::EnergyTransferModeEnum::DC; case types::iso15118::EnergyTransferMode::MCS_BPT: return ocpp::v2::EnergyTransferModeEnum::DC_BPT; } throw std::out_of_range("Could not convert EnergyTransferMode"); } ocpp::v2::MobilityNeedsModeEnum to_ocpp_mobility_needs_mode(const types::iso15118::MobilityNeedsMode mobility_needs_mode) { switch (mobility_needs_mode) { case types::iso15118::MobilityNeedsMode::EVCC: return ocpp::v2::MobilityNeedsModeEnum::EVCC; case types::iso15118::MobilityNeedsMode::EVCC_SECC: return ocpp::v2::MobilityNeedsModeEnum::EVCC_SECC; } throw std::out_of_range("Could not convert MobilityNeedsMode"); } ocpp::v2::ControlModeEnum to_ocpp_control_mode(const types::iso15118::ControlMode control_mode) { switch (control_mode) { case types::iso15118::ControlMode::DynamicControl: return ocpp::v2::ControlModeEnum::DynamicControl; case types::iso15118::ControlMode::ScheduledControl: return ocpp::v2::ControlModeEnum::ScheduledControl; } throw std::out_of_range("Could not convert ControlMode"); } ocpp::v2::EVEnergyOffer to_ocpp_ev_energy_offer(const types::iso15118::EVEnergyOffer& ev_energy_offer) { ocpp::v2::EVEnergyOffer result; result.evPowerSchedule.timeAnchor = ocpp::DateTime(ev_energy_offer.ev_power_schedule.time_anchor); result.evPowerSchedule.evPowerScheduleEntries.reserve( ev_energy_offer.ev_power_schedule.ev_power_schedule_entries.size()); for (const auto& entry : ev_energy_offer.ev_power_schedule.ev_power_schedule_entries) { ocpp::v2::EVPowerScheduleEntry ocpp_entry; ocpp_entry.power = entry.power; ocpp_entry.duration = entry.duration; result.evPowerSchedule.evPowerScheduleEntries.emplace_back(ocpp_entry); } if (ev_energy_offer.ev_absolute_price_schedule.has_value()) { const auto& iso_absolute_price_schedule = ev_energy_offer.ev_absolute_price_schedule.value(); ocpp::v2::EVAbsolutePriceSchedule absolute_price_schedule; absolute_price_schedule.timeAnchor = ocpp::DateTime(iso_absolute_price_schedule.time_anchor); absolute_price_schedule.priceAlgorithm = iso_absolute_price_schedule.price_algorithm; absolute_price_schedule.currency = iso_absolute_price_schedule.currency; absolute_price_schedule.evAbsolutePriceScheduleEntries.reserve( iso_absolute_price_schedule.ev_absolute_price_schedule_entries.size()); for (const auto& iso_entry : iso_absolute_price_schedule.ev_absolute_price_schedule_entries) { ocpp::v2::EVAbsolutePriceScheduleEntry entry; entry.duration = iso_entry.duration; entry.evPriceRule.reserve(iso_entry.ev_price_rule.size()); // TODO(mlitre): Transform float to rational number for (const auto& iso_rule : iso_entry.ev_price_rule) { ocpp::v2::PriceRule rule; // rule.energyFee = iso_rule.energy_fee; // rule.powerRangeStart = iso_rule.power_range_start; } } } return result; } ocpp::v2::IslandingDetectionEnum to_ocpp_islanding_detection(const types::iso15118::IslandingDetection islanding_detection) { switch (islanding_detection) { case types::iso15118::IslandingDetection::NoAntiIslandingSupport: return ocpp::v2::IslandingDetectionEnum::NoAntiIslandingSupport; case types::iso15118::IslandingDetection::ZeroCrossingDetection: return ocpp::v2::IslandingDetectionEnum::ZeroCrossingDetection; case types::iso15118::IslandingDetection::FrequencyJump: return ocpp::v2::IslandingDetectionEnum::FrequencyJump; case types::iso15118::IslandingDetection::ImpedanceAtFrequency: return ocpp::v2::IslandingDetectionEnum::ImpedanceAtFrequency; case types::iso15118::IslandingDetection::ImpedanceMeasurement: return ocpp::v2::IslandingDetectionEnum::ImpedanceMeasurement; case types::iso15118::IslandingDetection::SandiaFrequencyShift: return ocpp::v2::IslandingDetectionEnum::SandiaFrequencyShift; case types::iso15118::IslandingDetection::SandiaVoltageShift: return ocpp::v2::IslandingDetectionEnum::SandiaVoltageShift; case types::iso15118::IslandingDetection::SlipModeFrequencyShift: return ocpp::v2::IslandingDetectionEnum::SlipModeFrequencyShift; case types::iso15118::IslandingDetection::VoltageVectorShift: return ocpp::v2::IslandingDetectionEnum::VoltageVectorShift; case types::iso15118::IslandingDetection::OtherActive: return ocpp::v2::IslandingDetectionEnum::OtherActive; case types::iso15118::IslandingDetection::OtherPassive: return ocpp::v2::IslandingDetectionEnum::OtherPassive; case types::iso15118::IslandingDetection::RCLQFactor: return ocpp::v2::IslandingDetectionEnum::RCLQFactor; case types::iso15118::IslandingDetection::RoCoF: return ocpp::v2::IslandingDetectionEnum::RoCoF; case types::iso15118::IslandingDetection::UFP_OFP: return ocpp::v2::IslandingDetectionEnum::UFP_OFP; case types::iso15118::IslandingDetection::UVP_OVP: return ocpp::v2::IslandingDetectionEnum::UVP_OVP; } throw std::out_of_range("Could not convert IslandingDetection"); } ocpp::v2::DERControlEnum to_ocpp_der_control(const types::iso15118::DERControl der_control) { switch (der_control) { case types::iso15118::DERControl::EnterService: return ocpp::v2::DERControlEnum::EnterService; case types::iso15118::DERControl::FixedPFAbsorb: return ocpp::v2::DERControlEnum::FixedPFAbsorb; case types::iso15118::DERControl::FixedPFInject: return ocpp::v2::DERControlEnum::FixedPFInject; case types::iso15118::DERControl::FixedVar: return ocpp::v2::DERControlEnum::FixedVar; case types::iso15118::DERControl::FreqDroop: return ocpp::v2::DERControlEnum::FreqDroop; case types::iso15118::DERControl::FreqWatt: return ocpp::v2::DERControlEnum::FreqWatt; case types::iso15118::DERControl::VoltWatt: return ocpp::v2::DERControlEnum::VoltWatt; case types::iso15118::DERControl::VoltVar: return ocpp::v2::DERControlEnum::VoltVar; case types::iso15118::DERControl::Gradients: return ocpp::v2::DERControlEnum::Gradients; case types::iso15118::DERControl::HFMayTrip: return ocpp::v2::DERControlEnum::HFMayTrip; case types::iso15118::DERControl::HFMustTrip: return ocpp::v2::DERControlEnum::HFMustTrip; case types::iso15118::DERControl::HVMustTrip: return ocpp::v2::DERControlEnum::HVMustTrip; case types::iso15118::DERControl::LFMustTrip: return ocpp::v2::DERControlEnum::LFMustTrip; case types::iso15118::DERControl::LVMustTrip: return ocpp::v2::DERControlEnum::LVMustTrip; case types::iso15118::DERControl::PowerMonitoringMustTrip: return ocpp::v2::DERControlEnum::PowerMonitoringMustTrip; case types::iso15118::DERControl::HVMayTrip: return ocpp::v2::DERControlEnum::HVMayTrip; case types::iso15118::DERControl::LVMayTrip: return ocpp::v2::DERControlEnum::LVMayTrip; case types::iso15118::DERControl::HVMomCess: return ocpp::v2::DERControlEnum::HVMomCess; case types::iso15118::DERControl::LVMomCess: return ocpp::v2::DERControlEnum::LVMomCess; case types::iso15118::DERControl::LimitMaxDischarge: return ocpp::v2::DERControlEnum::LimitMaxDischarge; case types::iso15118::DERControl::WattPF: return ocpp::v2::DERControlEnum::WattPF; case types::iso15118::DERControl::WattVar: return ocpp::v2::DERControlEnum::WattVar; } throw std::out_of_range("Could not convert DERControl"); } ocpp::v2::ChargingNeeds to_ocpp_charging_needs(const types::iso15118::ChargingNeeds& charging_needs) { ocpp::v2::ChargingNeeds _charging_needs; _charging_needs.requestedEnergyTransfer = to_ocpp_energy_transfer_mode(charging_needs.requested_energy_transfer); if (charging_needs.available_energy_transfer.has_value() and not charging_needs.available_energy_transfer->empty()) { const auto& available = charging_needs.available_energy_transfer.value(); _charging_needs.availableEnergyTransfer = {}; _charging_needs.availableEnergyTransfer->reserve(available.size()); for (const auto& energy : available) { _charging_needs.availableEnergyTransfer->emplace_back(to_ocpp_energy_transfer_mode(energy)); } } if (charging_needs.mobility_needs_mode.has_value()) { _charging_needs.mobilityNeedsMode = to_ocpp_mobility_needs_mode(charging_needs.mobility_needs_mode.value()); } if (charging_needs.control_mode.has_value()) { _charging_needs.controlMode = to_ocpp_control_mode(charging_needs.control_mode.value()); } if (charging_needs.departure_time.has_value()) { _charging_needs.departureTime = ocpp::DateTime(charging_needs.departure_time.value()); } if (charging_needs.ac_charging_parameters.has_value()) { const auto& ac = charging_needs.ac_charging_parameters.value(); auto& ac_charging_parameters = _charging_needs.acChargingParameters.emplace(); ac_charging_parameters.energyAmount = ac.energy_amount; ac_charging_parameters.evMinCurrent = ac.ev_min_current; ac_charging_parameters.evMaxCurrent = ac.ev_max_current; ac_charging_parameters.evMaxVoltage = ac.ev_max_voltage; } else if (charging_needs.dc_charging_parameters.has_value()) { const auto& dc = charging_needs.dc_charging_parameters.value(); auto& dc_charging_parameters = _charging_needs.dcChargingParameters.emplace(); dc_charging_parameters.evMaxCurrent = dc.ev_max_current; dc_charging_parameters.evMaxVoltage = dc.ev_max_voltage; dc_charging_parameters.energyAmount = dc.energy_amount; dc_charging_parameters.evMaxPower = dc.ev_max_power; dc_charging_parameters.stateOfCharge = dc.state_of_charge; dc_charging_parameters.evEnergyCapacity = dc.ev_energy_capacity; dc_charging_parameters.fullSoC = dc.full_soc; dc_charging_parameters.bulkSoC = dc.bulk_soc; } else if (charging_needs.v2x_charging_parameters.has_value()) { const auto& v2x = charging_needs.v2x_charging_parameters.value(); auto& v2x_charging_params = _charging_needs.v2xChargingParameters.emplace(); v2x_charging_params.evMaxEnergyRequest = v2x.ev_max_energy_request; v2x_charging_params.evMinEnergyRequest = v2x.ev_min_energy_request; v2x_charging_params.evMaxV2XEnergyRequest = v2x.ev_max_v2xenergy_request; v2x_charging_params.evMinV2XEnergyRequest = v2x.ev_min_v2xenergy_request; v2x_charging_params.evTargetEnergyRequest = v2x.ev_target_energy_request; v2x_charging_params.targetSoC = v2x.target_soc; v2x_charging_params.maxVoltage = v2x.max_voltage; v2x_charging_params.minVoltage = v2x.min_voltage; v2x_charging_params.maxChargeCurrent = v2x.max_charge_current; v2x_charging_params.minChargeCurrent = v2x.min_charge_current; v2x_charging_params.maxChargePower = v2x.max_charge_power; v2x_charging_params.maxChargePower_L2 = v2x.max_charge_power_l2; v2x_charging_params.maxChargePower_L3 = v2x.max_charge_power_l3; v2x_charging_params.minChargePower = v2x.min_charge_power; v2x_charging_params.minChargePower_L2 = v2x.min_charge_power_l2; v2x_charging_params.minChargePower_L3 = v2x.min_charge_power_l3; v2x_charging_params.maxDischargeCurrent = v2x.max_discharge_current; v2x_charging_params.minDischargeCurrent = v2x.min_discharge_current; v2x_charging_params.maxDischargePower = v2x.max_discharge_power; v2x_charging_params.maxDischargePower_L2 = v2x.max_discharge_power_l2; v2x_charging_params.maxDischargePower_L3 = v2x.max_discharge_power_l3; v2x_charging_params.minDischargePower = v2x.min_discharge_power; v2x_charging_params.minDischargePower_L2 = v2x.min_discharge_power_l2; v2x_charging_params.minDischargePower_L3 = v2x.min_discharge_power_l3; } if (charging_needs.der_charging_parameters.has_value()) { const auto& der = charging_needs.der_charging_parameters.value(); auto& der_charging_params = _charging_needs.derChargingParameters.emplace(); der_charging_params.evDurationLevel1DCInjection = der.ev_duration_level1dcinjection; der_charging_params.evMaximumLevel1DCInjection = der.ev_maximum_level1dcinjection; der_charging_params.evDurationLevel2DCInjection = der.ev_duration_level2dcinjection; der_charging_params.evMaximumLevel2DCInjection = der.ev_maximum_level2dcinjection; der_charging_params.evIslandingTripTime = der.ev_islanding_trip_time; if (der.ev_islanding_detection_method.has_value()) { der_charging_params.evIslandingDetectionMethod = {}; der_charging_params.evIslandingDetectionMethod->reserve(der.ev_islanding_detection_method->size()); for (const auto& method : der.ev_islanding_detection_method.value()) { der_charging_params.evIslandingDetectionMethod->emplace_back(to_ocpp_islanding_detection(method)); } } der_charging_params.evInverterHwVersion = der.ev_inverter_hw_version; der_charging_params.evInverterSwVersion = der.ev_inverter_sw_version; der_charging_params.evInverterManufacturer = der.ev_inverter_manufacturer; der_charging_params.evInverterModel = der.ev_inverter_model; der_charging_params.evInverterSerialNumber = der.ev_inverter_serial_number; der_charging_params.evOverExcitedMaxDischargePower = der.ev_over_excited_max_discharge_power; der_charging_params.evOverExcitedPowerFactor = der.ev_over_excited_power_factor; der_charging_params.evUnderExcitedMaxDischargePower = der.ev_under_excited_max_discharge_power; der_charging_params.evUnderExcitedPowerFactor = der.ev_under_excited_power_factor; der_charging_params.maxDischargeApparentPower = der.max_discharge_apparent_power; der_charging_params.maxDischargeApparentPower_L2 = der.max_discharge_apparent_power_l2; der_charging_params.maxDischargeApparentPower_L3 = der.max_discharge_apparent_power_l3; der_charging_params.maxApparentPower = der.max_apparent_power; der_charging_params.maxChargeApparentPower = der.max_charge_apparent_power; der_charging_params.maxChargeApparentPower_L2 = der.max_charge_apparent_power_l2; der_charging_params.maxChargeApparentPower_L3 = der.max_charge_apparent_power_l3; der_charging_params.maxChargeReactivePower = der.max_charge_reactive_power; der_charging_params.maxChargeReactivePower_L2 = der.max_charge_reactive_power_l2; der_charging_params.maxChargeReactivePower_L3 = der.max_charge_reactive_power_l3; der_charging_params.maxDischargeReactivePower = der.max_discharge_reactive_power; der_charging_params.maxDischargeReactivePower_L2 = der.max_discharge_reactive_power_l2; der_charging_params.maxDischargeReactivePower_L3 = der.max_discharge_reactive_power_l3; der_charging_params.minDischargeReactivePower = der.min_discharge_reactive_power; der_charging_params.minDischargeReactivePower_L2 = der.min_discharge_reactive_power_l2; der_charging_params.minDischargeReactivePower_L3 = der.min_discharge_reactive_power_l3; der_charging_params.minChargeReactivePower = der.min_charge_reactive_power; der_charging_params.minChargeReactivePower_L2 = der.min_charge_reactive_power_l2; der_charging_params.minChargeReactivePower_L3 = der.min_charge_reactive_power_l3; der_charging_params.evReactiveSusceptance = der.ev_reactive_susceptance; der_charging_params.evSessionTotalDischargeEnergyAvailable = der.ev_session_total_discharge_energy_available; der_charging_params.maxNominalVoltage = der.max_nominal_voltage; der_charging_params.minNominalVoltage = der.min_nominal_voltage; der_charging_params.nominalVoltage = der.nominal_voltage; der_charging_params.nominalVoltageOffset = der.nominal_voltage_offset; if (der.ev_supported_dercontrol.has_value()) { der_charging_params.evSupportedDERControl = {}; der_charging_params.evSupportedDERControl->reserve(der.ev_supported_dercontrol->size()); for (const auto& der_control : der.ev_supported_dercontrol.value()) { der_charging_params.evSupportedDERControl->emplace_back(to_ocpp_der_control(der_control)); } } } // TODO(mlitre): Support ev energy offer // if (charging_needs.ev_energy_offer.has_value()) { // _charging_needs.evEnergyOffer = to_ocpp_ev_energy_offer(charging_needs.ev_energy_offer.value()); //} return _charging_needs; } ocpp::v2::ReserveNowStatusEnum to_ocpp_reservation_status(const types::reservation::ReservationResult result) { switch (result) { case types::reservation::ReservationResult::Accepted: return ocpp::v2::ReserveNowStatusEnum::Accepted; case types::reservation::ReservationResult::Faulted: return ocpp::v2::ReserveNowStatusEnum::Faulted; case types::reservation::ReservationResult::Occupied: return ocpp::v2::ReserveNowStatusEnum::Occupied; case types::reservation::ReservationResult::Rejected: return ocpp::v2::ReserveNowStatusEnum::Rejected; case types::reservation::ReservationResult::Unavailable: return ocpp::v2::ReserveNowStatusEnum::Unavailable; } throw std::out_of_range("Could not convert ReservationResult"); } ocpp::v2::ReservationUpdateStatusEnum to_ocpp_reservation_update_status_enum(const types::reservation::Reservation_status status) { switch (status) { case types::reservation::Reservation_status::Expired: return ocpp::v2::ReservationUpdateStatusEnum::Expired; case types::reservation::Reservation_status::Removed: return ocpp::v2::ReservationUpdateStatusEnum::Removed; case types::reservation::Reservation_status::Cancelled: case types::reservation::Reservation_status::Placed: case types::reservation::Reservation_status::Used: // OCPP should not convert a status enum that is not an OCPP type. throw std::out_of_range("Could not convert ReservationUpdateStatus: OCPP does not know this type"); } throw std::out_of_range("Could not convert ReservationUpdateStatus"); } types::system::UploadLogsRequest to_everest_upload_logs_request(const ocpp::v2::GetLogRequest& request) { types::system::UploadLogsRequest _request; _request.location = request.log.remoteLocation.get(); _request.retries = request.retries; _request.retry_interval_s = request.retryInterval; if (request.log.oldestTimestamp.has_value()) { _request.oldest_timestamp = request.log.oldestTimestamp.value().to_rfc3339(); } if (request.log.latestTimestamp.has_value()) { _request.latest_timestamp = request.log.latestTimestamp.value().to_rfc3339(); } _request.type = ocpp::v2::conversions::log_enum_to_string(request.logType); _request.request_id = request.requestId; return _request; } types::system::FirmwareUpdateRequest to_everest_firmware_update_request(const ocpp::v2::UpdateFirmwareRequest& request) { types::system::FirmwareUpdateRequest _request; _request.request_id = request.requestId; _request.location = request.firmware.location.get(); _request.retries = request.retries; _request.retry_interval_s = request.retryInterval; _request.retrieve_timestamp = request.firmware.retrieveDateTime.to_rfc3339(); if (request.firmware.installDateTime.has_value()) { _request.install_timestamp = request.firmware.installDateTime.value().to_rfc3339(); } if (request.firmware.signingCertificate.has_value()) { _request.signing_certificate = request.firmware.signingCertificate.value().get(); } if (request.firmware.signature.has_value()) { _request.signature = request.firmware.signature.value().get(); } return _request; } types::iso15118::Status to_everest_iso15118_status(const ocpp::v2::Iso15118EVCertificateStatusEnum& status) { switch (status) { case ocpp::v2::Iso15118EVCertificateStatusEnum::Accepted: return types::iso15118::Status::Accepted; case ocpp::v2::Iso15118EVCertificateStatusEnum::Failed: return types::iso15118::Status::Failed; } throw std::out_of_range("Could not convert Iso15118EVCertificateStatusEnum"); // this should never happen } types::ocpp::DataTransferStatus to_everest_data_transfer_status(ocpp::v2::DataTransferStatusEnum status) { switch (status) { case ocpp::v2::DataTransferStatusEnum::Accepted: return types::ocpp::DataTransferStatus::Accepted; case ocpp::v2::DataTransferStatusEnum::Rejected: return types::ocpp::DataTransferStatus::Rejected; case ocpp::v2::DataTransferStatusEnum::UnknownMessageId: return types::ocpp::DataTransferStatus::UnknownMessageId; case ocpp::v2::DataTransferStatusEnum::UnknownVendorId: return types::ocpp::DataTransferStatus::UnknownVendorId; } return types::ocpp::DataTransferStatus::UnknownVendorId; } types::ocpp::DataTransferRequest to_everest_data_transfer_request(ocpp::v2::DataTransferRequest request) { types::ocpp::DataTransferRequest data_transfer_request; data_transfer_request.vendor_id = request.vendorId.get(); if (request.messageId.has_value()) { data_transfer_request.message_id = request.messageId.value().get(); } if (request.data.has_value()) { data_transfer_request.data = request.data.value().dump(); } if (request.customData.has_value()) { auto ocpp_custom_data = request.customData.value(); types::ocpp::CustomData custom_data{ocpp_custom_data.at("vendorId"), ocpp_custom_data.dump()}; data_transfer_request.custom_data = custom_data; } return data_transfer_request; } types::ocpp::DataTransferResponse to_everest_data_transfer_response(ocpp::v2::DataTransferResponse response) { types::ocpp::DataTransferResponse everest_response; everest_response.status = conversions::to_everest_data_transfer_status(response.status); if (response.data.has_value()) { everest_response.data = response.data.value().dump(); } if (response.customData.has_value()) { auto ocpp_custom_data = response.customData.value(); types::ocpp::CustomData custom_data{ocpp_custom_data.at("vendorId"), ocpp_custom_data.dump()}; everest_response.custom_data = ocpp_custom_data; } return everest_response; } types::authorization::ValidationResult to_everest_validation_result(const ocpp::v2::IdTokenInfo& idTokenInfo) { types::authorization::ValidationResult validation_result; validation_result.authorization_status = to_everest_authorization_status(idTokenInfo.status); if (idTokenInfo.cacheExpiryDateTime.has_value()) { validation_result.expiry_time.emplace(idTokenInfo.cacheExpiryDateTime.value().to_rfc3339()); } if (idTokenInfo.groupIdToken.has_value()) { validation_result.parent_id_token = to_everest_id_token(idTokenInfo.groupIdToken.value()); } if (idTokenInfo.personalMessage.has_value()) { const types::text_message::MessageContent content = to_everest_message_content(idTokenInfo.personalMessage.value()); validation_result.tariff_messages.push_back(content); } if (idTokenInfo.customData.has_value() && idTokenInfo.customData.value().contains("vendorId") && idTokenInfo.customData.value().at("vendorId").get() == "org.openchargealliance.multilanguage" && idTokenInfo.customData.value().contains("personalMessageExtra")) { const json& multi_language_personal_messages = idTokenInfo.customData.value().at("personalMessageExtra"); for (const auto& messages : multi_language_personal_messages.items()) { const types::text_message::MessageContent content = messages.value(); validation_result.tariff_messages.push_back(content); } } if (idTokenInfo.evseId.has_value()) { validation_result.evse_ids = idTokenInfo.evseId.value(); } return validation_result; } types::authorization::ValidationResult to_everest_validation_result(const ocpp::v2::AuthorizeResponse& response) { types::authorization::ValidationResult validation_result = to_everest_validation_result(response.idTokenInfo); if (response.certificateStatus.has_value()) { validation_result.certificate_status.emplace(to_everest_certificate_status(response.certificateStatus.value())); } if (validation_result.allowed_energy_transfer_modes.has_value()) { validation_result.allowed_energy_transfer_modes = to_everest_allowed_energy_transfer_modes(response.allowedEnergyTransfer.value()); } return validation_result; } types::authorization::AuthorizationStatus to_everest_authorization_status(const ocpp::v2::AuthorizationStatusEnum status) { switch (status) { case ocpp::v2::AuthorizationStatusEnum::Accepted: return types::authorization::AuthorizationStatus::Accepted; case ocpp::v2::AuthorizationStatusEnum::Blocked: return types::authorization::AuthorizationStatus::Blocked; case ocpp::v2::AuthorizationStatusEnum::ConcurrentTx: return types::authorization::AuthorizationStatus::ConcurrentTx; case ocpp::v2::AuthorizationStatusEnum::Expired: return types::authorization::AuthorizationStatus::Expired; case ocpp::v2::AuthorizationStatusEnum::Invalid: return types::authorization::AuthorizationStatus::Invalid; case ocpp::v2::AuthorizationStatusEnum::NoCredit: return types::authorization::AuthorizationStatus::NoCredit; case ocpp::v2::AuthorizationStatusEnum::NotAllowedTypeEVSE: return types::authorization::AuthorizationStatus::NotAllowedTypeEVSE; case ocpp::v2::AuthorizationStatusEnum::NotAtThisLocation: return types::authorization::AuthorizationStatus::NotAtThisLocation; case ocpp::v2::AuthorizationStatusEnum::NotAtThisTime: return types::authorization::AuthorizationStatus::NotAtThisTime; case ocpp::v2::AuthorizationStatusEnum::Unknown: return types::authorization::AuthorizationStatus::Unknown; } throw std::out_of_range( "Could not convert ocpp::v2::AuthorizationStatusEnum to types::authorization::AuthorizationStatus"); } types::authorization::IdToken to_everest_id_token(const ocpp::v2::IdToken& id_token) { types::authorization::IdToken _id_token; _id_token.value = id_token.idToken.get(); _id_token.type = types::authorization::string_to_id_token_type(id_token.type); return _id_token; } types::authorization::CertificateStatus to_everest_certificate_status(const ocpp::v2::AuthorizeCertificateStatusEnum status) { switch (status) { case ocpp::v2::AuthorizeCertificateStatusEnum::Accepted: return types::authorization::CertificateStatus::Accepted; case ocpp::v2::AuthorizeCertificateStatusEnum::SignatureError: return types::authorization::CertificateStatus::SignatureError; case ocpp::v2::AuthorizeCertificateStatusEnum::CertificateExpired: return types::authorization::CertificateStatus::CertificateExpired; case ocpp::v2::AuthorizeCertificateStatusEnum::CertificateRevoked: return types::authorization::CertificateStatus::CertificateRevoked; case ocpp::v2::AuthorizeCertificateStatusEnum::NoCertificateAvailable: return types::authorization::CertificateStatus::NoCertificateAvailable; case ocpp::v2::AuthorizeCertificateStatusEnum::CertChainError: return types::authorization::CertificateStatus::CertChainError; case ocpp::v2::AuthorizeCertificateStatusEnum::ContractCancelled: return types::authorization::CertificateStatus::ContractCancelled; } throw std::out_of_range("Could not convert ocpp::v2::AuthorizeCertificateStatusEnum to " "types::authorization::CertificateStatus"); } types::ocpp::OcppTransactionEvent to_everest_ocpp_transaction_event(const ocpp::v2::TransactionEventRequest& transaction_event) { types::ocpp::OcppTransactionEvent ocpp_transaction_event; switch (transaction_event.eventType) { case ocpp::v2::TransactionEventEnum::Started: ocpp_transaction_event.transaction_event = types::ocpp::TransactionEvent::Started; break; case ocpp::v2::TransactionEventEnum::Updated: ocpp_transaction_event.transaction_event = types::ocpp::TransactionEvent::Updated; break; case ocpp::v2::TransactionEventEnum::Ended: ocpp_transaction_event.transaction_event = types::ocpp::TransactionEvent::Ended; break; } if (transaction_event.evse.has_value()) { ocpp_transaction_event.evse = to_everest_evse(transaction_event.evse.value()); } ocpp_transaction_event.session_id = transaction_event.transactionInfo.transactionId; // session_id == transaction_id for OCPP2.0.1 ocpp_transaction_event.transaction_id = transaction_event.transactionInfo.transactionId; return ocpp_transaction_event; } types::text_message::MessageFormat to_everest_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::MessageFormatEnum to types::text_message::MessageFormat"); } types::text_message::MessageContent to_everest_message_content(const ocpp::v2::MessageContent& message_content) { types::text_message::MessageContent everest_message_content; everest_message_content.format = to_everest_message_format(message_content.format); everest_message_content.content = message_content.content; everest_message_content.language = message_content.language; return everest_message_content; } types::ocpp::OcppTransactionEventResponse to_everest_transaction_event_response(const ocpp::v2::TransactionEventResponse& transaction_event_response) { types::ocpp::OcppTransactionEventResponse everest_transaction_event_response; everest_transaction_event_response.total_cost = transaction_event_response.totalCost; everest_transaction_event_response.charging_priority = transaction_event_response.chargingPriority; if (transaction_event_response.updatedPersonalMessage.has_value()) { everest_transaction_event_response.personal_message = to_everest_message_content(transaction_event_response.updatedPersonalMessage.value()); } return everest_transaction_event_response; } types::ocpp::BootNotificationResponse to_everest_boot_notification_response(const ocpp::v2::BootNotificationResponse& boot_notification_response) { types::ocpp::BootNotificationResponse everest_boot_notification_response; everest_boot_notification_response.status = to_everest_registration_status(boot_notification_response.status); everest_boot_notification_response.current_time = boot_notification_response.currentTime.to_rfc3339(); everest_boot_notification_response.interval = boot_notification_response.interval; if (boot_notification_response.statusInfo.has_value()) { everest_boot_notification_response.status_info = to_everest_status_info_type(boot_notification_response.statusInfo.value()); } return everest_boot_notification_response; } types::ocpp::RegistrationStatus to_everest_registration_status(const ocpp::v2::RegistrationStatusEnum& registration_status) { switch (registration_status) { case ocpp::v2::RegistrationStatusEnum::Accepted: return types::ocpp::RegistrationStatus::Accepted; case ocpp::v2::RegistrationStatusEnum::Pending: return types::ocpp::RegistrationStatus::Pending; case ocpp::v2::RegistrationStatusEnum::Rejected: return types::ocpp::RegistrationStatus::Rejected; } throw std::out_of_range("Could not convert ocpp::v2::RegistrationStatusEnum to types::ocpp::RegistrationStatus"); } types::ocpp::StatusInfoType to_everest_status_info_type(const ocpp::v2::StatusInfo& status_info) { types::ocpp::StatusInfoType everest_status_info; everest_status_info.reason_code = status_info.reasonCode; everest_status_info.additional_info = status_info.additionalInfo; return everest_status_info; } std::vector to_everest_get_variable_result_vector(const std::vector& get_variable_result_vector) { std::vector response; for (const auto& get_variable_result : get_variable_result_vector) { types::ocpp::GetVariableResult _get_variable_result; _get_variable_result.status = to_everest_get_variable_status_enum_type(get_variable_result.attributeStatus); _get_variable_result.component_variable = {conversions::to_everest_component(get_variable_result.component), conversions::to_everest_variable(get_variable_result.variable)}; if (get_variable_result.attributeType.has_value()) { _get_variable_result.attribute_type = conversions::to_everest_attribute_enum(get_variable_result.attributeType.value()); } if (get_variable_result.attributeValue.has_value()) { _get_variable_result.value = get_variable_result.attributeValue.value().get(); } response.push_back(_get_variable_result); } return response; } std::vector to_everest_set_variable_result_vector(const std::vector& set_variable_result_vector) { std::vector response; for (const auto& set_variable_result : set_variable_result_vector) { types::ocpp::SetVariableResult _set_variable_result; _set_variable_result.status = conversions::to_everest_set_variable_status_enum_type(set_variable_result.attributeStatus); _set_variable_result.component_variable = {conversions::to_everest_component(set_variable_result.component), conversions::to_everest_variable(set_variable_result.variable)}; if (set_variable_result.attributeType.has_value()) { _set_variable_result.attribute_type = conversions::to_everest_attribute_enum(set_variable_result.attributeType.value()); } response.push_back(_set_variable_result); } return response; } types::ocpp::Component to_everest_component(const ocpp::v2::Component& component) { types::ocpp::Component _component; _component.name = component.name; if (component.evse.has_value()) { _component.evse = to_everest_evse(component.evse.value()); } if (component.instance.has_value()) { _component.instance = component.instance.value(); } return _component; } types::ocpp::Variable to_everest_variable(const ocpp::v2::Variable& variable) { types::ocpp::Variable _variable; _variable.name = variable.name; if (variable.instance.has_value()) { _variable.instance = variable.instance.value(); } return _variable; } types::ocpp::EVSE to_everest_evse(const ocpp::v2::EVSE& evse) { types::ocpp::EVSE _evse; _evse.id = evse.id; if (evse.connectorId.has_value()) { _evse.connector_id = evse.connectorId.value(); } return _evse; } types::ocpp::AttributeEnum to_everest_attribute_enum(const ocpp::v2::AttributeEnum attribute_enum) { switch (attribute_enum) { case ocpp::v2::AttributeEnum::Actual: return types::ocpp::AttributeEnum::Actual; case ocpp::v2::AttributeEnum::Target: return types::ocpp::AttributeEnum::Target; case ocpp::v2::AttributeEnum::MinSet: return types::ocpp::AttributeEnum::MinSet; case ocpp::v2::AttributeEnum::MaxSet: return types::ocpp::AttributeEnum::MaxSet; } throw std::out_of_range("Could not convert AttributeEnum"); } types::ocpp::GetVariableStatusEnumType to_everest_get_variable_status_enum_type(const ocpp::v2::GetVariableStatusEnum get_variable_status) { switch (get_variable_status) { case ocpp::v2::GetVariableStatusEnum::Accepted: return types::ocpp::GetVariableStatusEnumType::Accepted; case ocpp::v2::GetVariableStatusEnum::Rejected: return types::ocpp::GetVariableStatusEnumType::Rejected; case ocpp::v2::GetVariableStatusEnum::UnknownComponent: return types::ocpp::GetVariableStatusEnumType::UnknownComponent; case ocpp::v2::GetVariableStatusEnum::UnknownVariable: return types::ocpp::GetVariableStatusEnumType::UnknownVariable; case ocpp::v2::GetVariableStatusEnum::NotSupportedAttributeType: return types::ocpp::GetVariableStatusEnumType::NotSupportedAttributeType; } throw std::out_of_range("Could not convert GetVariableStatusEnumType"); } types::ocpp::SetVariableStatusEnumType to_everest_set_variable_status_enum_type(const ocpp::v2::SetVariableStatusEnum set_variable_status) { switch (set_variable_status) { case ocpp::v2::SetVariableStatusEnum::Accepted: return types::ocpp::SetVariableStatusEnumType::Accepted; case ocpp::v2::SetVariableStatusEnum::Rejected: return types::ocpp::SetVariableStatusEnumType::Rejected; case ocpp::v2::SetVariableStatusEnum::UnknownComponent: return types::ocpp::SetVariableStatusEnumType::UnknownComponent; case ocpp::v2::SetVariableStatusEnum::UnknownVariable: return types::ocpp::SetVariableStatusEnumType::UnknownVariable; case ocpp::v2::SetVariableStatusEnum::NotSupportedAttributeType: return types::ocpp::SetVariableStatusEnumType::NotSupportedAttributeType; case ocpp::v2::SetVariableStatusEnum::RebootRequired: return types::ocpp::SetVariableStatusEnumType::RebootRequired; } throw std::out_of_range("Could not convert GetVariableStatusEnumType"); } types::ocpp::ChargingSchedules to_everest_charging_schedules(const std::vector& composite_schedules) { types::ocpp::ChargingSchedules charging_schedules; for (const auto& composite_schedule : composite_schedules) { charging_schedules.schedules.push_back(conversions::to_everest_charging_schedule(composite_schedule)); } return charging_schedules; } types::ocpp::ChargingSchedule to_everest_charging_schedule(const ocpp::v2::EnhancedCompositeSchedule& composite_schedule) { types::ocpp::ChargingSchedule charging_schedule; charging_schedule.evse = composite_schedule.evseId; charging_schedule.charging_rate_unit = ocpp::v2::conversions::charging_rate_unit_enum_to_string(composite_schedule.chargingRateUnit); charging_schedule.evse = composite_schedule.evseId; charging_schedule.duration = composite_schedule.duration; charging_schedule.start_schedule = composite_schedule.scheduleStart.to_rfc3339(); // min_charging_rate is not given as part of a OCPP2.0.1 composite schedule for (const auto& charging_schedule_period : composite_schedule.chargingSchedulePeriod) { charging_schedule.charging_schedule_period.push_back( to_everest_charging_schedule_period(charging_schedule_period)); } return charging_schedule; } types::ocpp::Operation_mode to_everest_operation_mode(const ocpp::v2::OperationModeEnum operation_mode) { switch (operation_mode) { case ocpp::v2::OperationModeEnum::Idle: return types::ocpp::Operation_mode::Idle; case ocpp::v2::OperationModeEnum::ChargingOnly: return types::ocpp::Operation_mode::ChargingOnly; case ocpp::v2::OperationModeEnum::CentralSetpoint: return types::ocpp::Operation_mode::CentralSetpoint; case ocpp::v2::OperationModeEnum::ExternalSetpoint: return types::ocpp::Operation_mode::ExternalSetpoint; case ocpp::v2::OperationModeEnum::ExternalLimits: return types::ocpp::Operation_mode::ExternalLimits; case ocpp::v2::OperationModeEnum::CentralFrequency: return types::ocpp::Operation_mode::CentralFrequency; case ocpp::v2::OperationModeEnum::LocalFrequency: return types::ocpp::Operation_mode::LocalFrequency; case ocpp::v2::OperationModeEnum::LocalLoadBalancing: return types::ocpp::Operation_mode::LocalLoadBalancing; } throw std::out_of_range("Could not convert operation mode enum."); } types::ocpp::ChargingSchedulePeriod to_everest_charging_schedule_period(const ocpp::v2::ChargingSchedulePeriod& period) { if (not period.limit.has_value()) { EVLOG_warning << "Received ChargingSchedulePeriod without a limit. Limit defaults to 0!"; } types::ocpp::ChargingSchedulePeriod _period; _period.start_period = period.startPeriod; _period.limit = period.limit.value_or(0); _period.limit_L2 = period.limit_L2; _period.limit_L3 = period.limit_L3; _period.number_phases = period.numberPhases; _period.phase_to_use = period.phaseToUse; _period.discharge_limit = period.dischargeLimit; _period.discharge_limit_L2 = period.dischargeLimit_L2; _period.discharge_limit_L3 = period.dischargeLimit_L3; _period.setpoint = period.setpoint; _period.setpoint_L2 = period.setpoint_L2; _period.setpoint_L3 = period.setpoint_L3; _period.setpoint_reactive = period.setpointReactive; _period.setpoint_reactive_L2 = period.setpointReactive_L2; _period.setpoint_reactive_L3 = period.setpointReactive_L3; _period.preconditioning_request = period.preconditioningRequest; _period.evse_sleep = period.evseSleep; _period.v2x_baseline = period.v2xBaseline; if (period.operationMode.has_value()) { _period.operation_mode = to_everest_operation_mode(period.operationMode.value()); } if (period.v2xFreqWattCurve.has_value()) { _period.v2x_freq_watt_curve = std::vector(); for (const auto& point : period.v2xFreqWattCurve.value()) { _period.v2x_freq_watt_curve->push_back({point.frequency, point.power}); } } if (period.v2xSignalWattCurve.has_value()) { _period.v2x_signal_watt_curve = std::vector(); for (const auto& point : period.v2xSignalWattCurve.value()) { _period.v2x_signal_watt_curve->push_back({point.signal, point.power}); } } return _period; } types::ocpp::ChargingSchedulePeriod to_everest_charging_schedule_period(const ocpp::v2::EnhancedChargingSchedulePeriod& period) { if (not period.limit.has_value()) { EVLOG_warning << "Received ChargingSchedulePeriod without a limit. Limit defaults to 0!"; } types::ocpp::ChargingSchedulePeriod _period; _period.start_period = period.startPeriod; _period.limit = period.limit.value_or(0); _period.limit_L2 = period.limit_L2; _period.limit_L3 = period.limit_L3; _period.number_phases = period.numberPhases; _period.phase_to_use = period.phaseToUse; _period.discharge_limit = period.dischargeLimit; _period.discharge_limit_L2 = period.dischargeLimit_L2; _period.discharge_limit_L3 = period.dischargeLimit_L3; _period.setpoint = period.setpoint; _period.setpoint_L2 = period.setpoint_L2; _period.setpoint_L3 = period.setpoint_L3; _period.setpoint_reactive = period.setpointReactive; _period.setpoint_reactive_L2 = period.setpointReactive_L2; _period.setpoint_reactive_L3 = period.setpointReactive_L3; _period.preconditioning_request = period.preconditioningRequest; _period.evse_sleep = period.evseSleep; _period.v2x_baseline = period.v2xBaseline; _period.stack_level = period.stackLevel; if (period.operationMode.has_value()) { _period.operation_mode = to_everest_operation_mode(period.operationMode.value()); } if (period.v2xFreqWattCurve.has_value()) { _period.v2x_freq_watt_curve = std::vector(); for (const auto& point : period.v2xFreqWattCurve.value()) { _period.v2x_freq_watt_curve->push_back({point.frequency, point.power}); } } if (period.v2xSignalWattCurve.has_value()) { _period.v2x_signal_watt_curve = std::vector(); for (const auto& point : period.v2xSignalWattCurve.value()) { _period.v2x_signal_watt_curve->push_back({point.signal, point.power}); } } return _period; } ocpp::v2::DisplayMessageStatusEnum to_ocpp_display_message_status_enum(const types::display_message::DisplayMessageStatusEnum& from) { switch (from) { case types::display_message::DisplayMessageStatusEnum::Accepted: return ocpp::v2::DisplayMessageStatusEnum::Accepted; case types::display_message::DisplayMessageStatusEnum::NotSupportedMessageFormat: return ocpp::v2::DisplayMessageStatusEnum::NotSupportedMessageFormat; case types::display_message::DisplayMessageStatusEnum::Rejected: return ocpp::v2::DisplayMessageStatusEnum::Rejected; case types::display_message::DisplayMessageStatusEnum::NotSupportedPriority: return ocpp::v2::DisplayMessageStatusEnum::NotSupportedPriority; case types::display_message::DisplayMessageStatusEnum::NotSupportedState: return ocpp::v2::DisplayMessageStatusEnum::NotSupportedState; case types::display_message::DisplayMessageStatusEnum::UnknownTransaction: return ocpp::v2::DisplayMessageStatusEnum::UnknownTransaction; } throw std::out_of_range("Could not convert DisplayMessageStatusEnum"); } ocpp::v2::SetDisplayMessageResponse to_ocpp_set_display_message_response(const types::display_message::SetDisplayMessageResponse& response) { ocpp::v2::SetDisplayMessageResponse ocpp_response; ocpp_response.status = to_ocpp_display_message_status_enum(response.status); if (response.status_info.has_value()) { ocpp_response.statusInfo = ocpp::v2::StatusInfo(); ocpp_response.statusInfo.value().additionalInfo = response.status_info.value(); } return ocpp_response; } types::display_message::MessagePriorityEnum to_everest_display_message_priority_enum(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 MessagePriorityEnum"); } types::display_message::MessageStateEnum to_everest_display_message_state_enum(const ocpp::v2::MessageStateEnum& message_state) { switch (message_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 display message state enum."); } types::display_message::GetDisplayMessageRequest to_everest_display_message_request(const ocpp::v2::GetDisplayMessagesRequest& request) { types::display_message::GetDisplayMessageRequest result_request; result_request.id = request.id; if (request.priority.has_value()) { result_request.priority = to_everest_display_message_priority_enum(request.priority.value()); } if (request.state.has_value()) { result_request.state = to_everest_display_message_state_enum(request.state.value()); } return result_request; } types::display_message::ClearDisplayMessageRequest to_everest_clear_display_message_request(const ocpp::v2::ClearDisplayMessageRequest& request) { types::display_message::ClearDisplayMessageRequest result_request; result_request.id = request.id; return result_request; } ocpp::v2::ClearMessageStatusEnum to_ocpp_clear_message_response_enum(const types::display_message::ClearMessageResponseEnum& response_enum) { switch (response_enum) { case types::display_message::ClearMessageResponseEnum::Accepted: return ocpp::v2::ClearMessageStatusEnum::Accepted; case types::display_message::ClearMessageResponseEnum::Unknown: return ocpp::v2::ClearMessageStatusEnum::Unknown; } throw std::out_of_range("Could not convert ClearMessageResponseEnum"); } ocpp::v2::ClearDisplayMessageResponse to_ocpp_clear_display_message_response(const types::display_message::ClearDisplayMessageResponse& response) { ocpp::v2::ClearDisplayMessageResponse result_response; result_response.status = to_ocpp_clear_message_response_enum(response.status); if (response.status_info.has_value()) { result_response.statusInfo = ocpp::v2::StatusInfo(); result_response.statusInfo.value().additionalInfo = response.status_info.value(); } return result_response; } types::iso15118::EnergyTransferMode to_everest_allowed_energy_transfer_mode(const ocpp::v2::EnergyTransferModeEnum& allowed_energy_transfer_mode) { switch (allowed_energy_transfer_mode) { case ocpp::v2::EnergyTransferModeEnum::AC_BPT: return types::iso15118::EnergyTransferMode::AC_BPT; case ocpp::v2::EnergyTransferModeEnum::AC_BPT_DER: return types::iso15118::EnergyTransferMode::AC_BPT_DER; case ocpp::v2::EnergyTransferModeEnum::AC_DER: return types::iso15118::EnergyTransferMode::AC_DER; case ocpp::v2::EnergyTransferModeEnum::AC_single_phase: return types::iso15118::EnergyTransferMode::AC_single_phase_core; case ocpp::v2::EnergyTransferModeEnum::AC_three_phase: return types::iso15118::EnergyTransferMode::AC_three_phase_core; case ocpp::v2::EnergyTransferModeEnum::AC_two_phase: return types::iso15118::EnergyTransferMode::AC_two_phase; case ocpp::v2::EnergyTransferModeEnum::DC: return types::iso15118::EnergyTransferMode::DC; case ocpp::v2::EnergyTransferModeEnum::DC_BPT: return types::iso15118::EnergyTransferMode::DC_BPT; case ocpp::v2::EnergyTransferModeEnum::DC_ACDP: return types::iso15118::EnergyTransferMode::DC_ACDP; case ocpp::v2::EnergyTransferModeEnum::DC_ACDP_BPT: return types::iso15118::EnergyTransferMode::DC_ACDP_BPT; case ocpp::v2::EnergyTransferModeEnum::WPT: return types::iso15118::EnergyTransferMode::WPT; } throw std::out_of_range("Could not convert EnergyTransferModeEnum"); } std::vector to_everest_allowed_energy_transfer_modes( const std::vector& allowed_energy_transfer_modes) { std::vector value{}; value.reserve(allowed_energy_transfer_modes.size()); for (const auto& mode : allowed_energy_transfer_modes) { value.push_back(to_everest_allowed_energy_transfer_mode(mode)); } return value; } ocpp::v2::OperationalStatusEnum to_ocpp_operational_status(types::ocpp::OperationalStatusEnumType value) { using FROM = types::ocpp::OperationalStatusEnumType; using TO = ocpp::v2::OperationalStatusEnum; TO result; switch (value) { case FROM::Inoperative: result = TO::Inoperative; break; case FROM::Operative: result = TO::Operative; break; default: throw std::out_of_range("Could not convert OperationalStatusEnumType"); } return result; } types::ocpp::ChangeAvailabilityStatusEnumType to_everest_change_availability_status(ocpp::v2::ChangeAvailabilityStatusEnum value) { using FROM = ocpp::v2::ChangeAvailabilityStatusEnum; using TO = types::ocpp::ChangeAvailabilityStatusEnumType; TO result; switch (value) { case FROM::Accepted: result = TO::Accepted; break; case FROM::Rejected: result = TO::Rejected; break; case FROM::Scheduled: result = TO::Scheduled; break; default: throw std::out_of_range("Could not convert ChangeAvailabilityStatusEnum"); } return result; } types::ocpp::StatusInfoType to_everest_status_info(const ocpp::v2::StatusInfo& value) { return {value.reasonCode, value.additionalInfo}; } ocpp::v2::ChangeAvailabilityRequest to_ocpp_change_availability_request(const types::ocpp::ChangeAvailabilityRequest& request) { ocpp::v2::ChangeAvailabilityRequest result; result.operationalStatus = to_ocpp_operational_status(request.operational_status); if (request.evse) { result.evse = to_ocpp_evse(request.evse.value()); } return result; } types::ocpp::ChangeAvailabilityResponse to_everest_change_availability_response(const ocpp::v2::ChangeAvailabilityResponse& response) { types::ocpp::ChangeAvailabilityResponse result; result.status = to_everest_change_availability_status(response.status); if (response.statusInfo) { result.status_info = to_everest_status_info(response.statusInfo.value()); } return result; } } // namespace conversions } // namespace module