Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright 2025 Pionix GmbH and Contributors to EVerest
#pragma once

#include <iso15118/message/d2/msg_data_types.hpp>

namespace iso15118::d2::msg {

namespace data_types {} // namespace data_types

struct CableCheckRequest {
Header header;
data_types::DC_EVStatus ev_status;
};

struct CableCheckResponse {
Header header;
data_types::ResponseCode response_code;
data_types::DC_EVSEStatus evse_status;
data_types::EVSEProcessing evse_processing;
};

} // namespace iso15118::d2::msg
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright 2025 Pionix GmbH and Contributors to EVerest
#pragma once

#include <iso15118/message/d2/msg_data_types.hpp>
#include <optional>

namespace iso15118::d2::msg {

namespace data_types {} // namespace data_types

struct CurrentDemandRequest {
Header header;
data_types::DC_EVStatus ev_status;
data_types::PhysicalValue ev_target_current;
data_types::PhysicalValue ev_target_voltage;
std::optional<data_types::PhysicalValue> ev_maximum_voltage_limit{std::nullopt};
std::optional<data_types::PhysicalValue> ev_maximum_current_limit{std::nullopt};
std::optional<data_types::PhysicalValue> ev_maximum_power_limit{std::nullopt};
std::optional<bool> bulk_charging_complete{std::nullopt};
std::optional<bool> charging_complete{std::nullopt};
std::optional<data_types::PhysicalValue> remaining_time_to_full_soc{std::nullopt};
std::optional<data_types::PhysicalValue> remaining_time_to_bulk_soc{std::nullopt};
};

struct CurrentDemandResponse {
Header header;
data_types::ResponseCode response_code;
data_types::DC_EVSEStatus evse_status;
data_types::PhysicalValue evse_present_voltage;
data_types::PhysicalValue evse_present_current;
bool evse_current_limit_achieved;
bool evse_voltage_limit_achieved;
bool evse_power_limit_achieved;
data_types::EVSEID evse_id;
data_types::SAID sa_schedule_tuple_id;
std::optional<data_types::PhysicalValue> evse_maximum_voltage_limit{std::nullopt};
std::optional<data_types::PhysicalValue> evse_maximum_current_limit{std::nullopt};
std::optional<data_types::PhysicalValue> evse_maximum_power_limit{std::nullopt};
std::optional<data_types::MeterInfo> meter_info{std::nullopt};
std::optional<bool> receipt_required{std::nullopt};
};

} // namespace iso15118::d2::msg
116 changes: 116 additions & 0 deletions lib/everest/iso15118/include/iso15118/message/d2/msg_data_types.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@
#pragma once

#include <array>
#include <cstdint>
#include <optional>
#include <string>

#include <cbv2g/iso_2/iso2_msgDefDatatypes.h>
#include <vector>

namespace iso15118::d2::msg {

Expand All @@ -17,6 +19,15 @@ namespace data_types {
constexpr auto SESSION_ID_LENGTH = 8;
using SESSION_ID = std::array<uint8_t, SESSION_ID_LENGTH>; // hexBinary, max length 8

using PercentValue = uint8_t; // [0 - 100]
using SAID = int16_t; // [1-255]
using MeterID = std::string; // MaxLength: 32
using EVSEID = std::string; // Length: 7-37
using MeterReading = uint64_t; // Wh
using SigMeterReading = std::vector<uint8_t>; // MaxLength: 64
using MeterStatus = int16_t;
using TMeter = int16_t; // Unix timestamp format

enum class ResponseCode {
OK,
OK_NewSessionEstablished,
Expand Down Expand Up @@ -52,11 +63,108 @@ enum class FaultCode {
UnknownError,
};

enum class DC_EVErrorCode {
NO_ERROR,
FAILED_RESSTemperatureInhibit,
FAILED_EVShiftPosition,
FAILED_ChargerConnectorLockFault,
FAILED_EVRESSMalfunction,
FAILED_ChargingCurrentdifferential,
FAILED_ChargingVoltageOutOfRange,
Reserved_A,
Reserved_B,
Reserved_C,
FAILED_ChargingSystemIncompatibility,
NoData,
};

enum class EVSEProcessing {
Finished,
Ongoing,
Ongoing_WaitingForCustomerInteraction
};

enum class EVSENotification {
None,
StopCharging,
ReNegotiation,
};

enum class UnitSymbol {
h,
m,
s,
A,
V,
W,
Wh
};

enum class DC_EVSEStatusCode {
EVSE_NotReady,
EVSE_Ready,
EVSE_Shutdown,
EVSE_UtilityInterruptEvent,
EVSE_IsolationMonitoringActive,
EVSE_EmergencyShutdown,
EVSE_Malfunction,
Reserved_8,
Reserved_9,
Reserved_A,
Reserved_B,
Reserved_C
};

enum class isolationLevel {
Invalid,
Valid,
Warning,
Fault,
No_IMD
};

struct MeterInfo {
MeterID meter_id;
std::optional<MeterReading> meter_reading{std::nullopt};
std::optional<SigMeterReading> sig_meter_reading{std::nullopt};
std::optional<MeterStatus> meter_status{std::nullopt};
std::optional<TMeter> t_meter{std::nullopt};
};

struct PhysicalValue {
int16_t value{0};
int8_t multiplier{0}; // [-3 - 3]
UnitSymbol unit;
};

struct Notification {
FaultCode fault_code;
std::optional<std::string> fault_msg;
};

struct EVSEStatus {
uint16_t notification_max_delay{0};
EVSENotification evse_notification{EVSENotification::None};
};

struct AC_EVSEStatus : public EVSEStatus {
bool rcd;
};

struct DC_EVSEStatus : public EVSEStatus {
std::optional<isolationLevel> evse_isolation_status;
DC_EVSEStatusCode evse_status_code;
};

struct DC_EVStatus {
bool ev_ready;
DC_EVErrorCode ev_error_code;
PercentValue ev_ress_soc;
};

float from_PhysicalValue(const PhysicalValue& in);
PhysicalValue from_float(const float in, const data_types::UnitSymbol unit);

} // namespace data_types

struct Header {
Expand All @@ -68,4 +176,12 @@ struct Header {
void convert(const struct iso2_MessageHeaderType& in, Header& out);
void convert(const Header& in, struct iso2_MessageHeaderType& out);

void convert(const iso2_MeterInfoType& in, data_types::MeterInfo& out);
void convert(const data_types::MeterInfo& in, iso2_MeterInfoType& out);
void convert(const iso2_DC_EVStatusType& in, data_types::DC_EVStatus& out);
void convert(const data_types::AC_EVSEStatus& in, iso2_AC_EVSEStatusType& out);
void convert(const data_types::DC_EVSEStatus& in, iso2_DC_EVSEStatusType& out);
void convert(const iso2_PhysicalValueType& in, data_types::PhysicalValue& out);
void convert(const data_types::PhysicalValue& in, iso2_PhysicalValueType& out);

} // namespace iso15118::d2::msg
25 changes: 25 additions & 0 deletions lib/everest/iso15118/include/iso15118/message/d2/pre_charge.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright 2025 Pionix GmbH and Contributors to EVerest
#pragma once

#include <iso15118/message/d2/msg_data_types.hpp>

namespace iso15118::d2::msg {

namespace data_types {} // namespace data_types

struct PreChargeRequest {
Header header;
data_types::DC_EVStatus ev_status;
data_types::PhysicalValue ev_target_voltage;
data_types::PhysicalValue ev_target_current;
};

struct PreChargeResponse {
Header header;
data_types::ResponseCode response_code;
data_types::DC_EVSEStatus evse_status;
data_types::PhysicalValue evse_present_voltage;
};

} // namespace iso15118::d2::msg
16 changes: 16 additions & 0 deletions lib/everest/iso15118/include/iso15118/message/d2/type.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,14 @@ enum class Type {
SupportedAppProtocolRes,
SessionSetupReq,
SessionSetupRes,
CableCheckReq,
CableCheckRes,
PreChargeReq,
PreChargeRes,
CurrentDemandReq,
CurrentDemandRes,
WeldingDetectionReq,
WeldingDetectionRes
};

template <typename T> struct TypeTrait {
Expand Down Expand Up @@ -39,6 +47,14 @@ CREATE_TYPE_TRAIT(SupportedAppProtocolRequest, SupportedAppProtocolReq);
CREATE_TYPE_TRAIT(SupportedAppProtocolResponse, SupportedAppProtocolRes);
CREATE_TYPE_TRAIT(SessionSetupRequest, SessionSetupReq);
CREATE_TYPE_TRAIT(SessionSetupResponse, SessionSetupRes);
CREATE_TYPE_TRAIT(CableCheckRequest, CableCheckReq);
CREATE_TYPE_TRAIT(CableCheckResponse, CableCheckRes);
CREATE_TYPE_TRAIT(PreChargeRequest, PreChargeReq);
CREATE_TYPE_TRAIT(PreChargeResponse, PreChargeRes);
CREATE_TYPE_TRAIT(CurrentDemandRequest, CurrentDemandReq);
CREATE_TYPE_TRAIT(CurrentDemandResponse, CurrentDemandRes);
CREATE_TYPE_TRAIT(WeldingDetectionRequest, WeldingDetectionReq);
CREATE_TYPE_TRAIT(WeldingDetectionResponse, WeldingDetectionRes);

#ifdef CREATE_TYPE_TRAIT_PUSHED
#define CREATE_TYPE_TRAIT CREATE_TYPE_TRAIT_PUSHED
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright 2025 Pionix GmbH and Contributors to EVerest
#pragma once

#include <iso15118/message/d2/msg_data_types.hpp>

namespace iso15118::d2::msg {

namespace data_types {} // namespace data_types

struct WeldingDetectionRequest {
Header header;
data_types::DC_EVStatus ev_status;
};

struct WeldingDetectionResponse {
Header header;
data_types::ResponseCode response_code;
data_types::DC_EVSEStatus evse_status;
data_types::PhysicalValue evse_present_voltage;
};

} // namespace iso15118::d2::msg
4 changes: 4 additions & 0 deletions lib/everest/iso15118/src/iso15118/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,13 @@ target_sources(iso15118
message/dc_welding_detection.cpp
message/session_stop.cpp

message/d2/cable_check.cpp
message/d2/current_demand.cpp
message/d2/variant.cpp
message/d2/msg_data_types.cpp
message/d2/pre_charge.cpp
message/d2/session_setup.cpp
message/d2/welding_detection.cpp

tbd_controller.cpp
)
Expand Down
49 changes: 49 additions & 0 deletions lib/everest/iso15118/src/iso15118/message/d2/cable_check.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright 2025 Pionix GmbH and Contributors to EVerest
#include <iso15118/message/d2/cable_check.hpp>

#include <iso15118/detail/variant_access.hpp>

#include <cbv2g/iso_2/iso2_msgDefDecoder.h>
#include <cbv2g/iso_2/iso2_msgDefEncoder.h>

#include <iso15118/detail/helper.hpp>

namespace iso15118::d2::msg {

template <> void convert(const struct iso2_CableCheckReqType& in, CableCheckRequest& out) {
convert(in.DC_EVStatus, out.ev_status);
}

template <>
void insert_type(VariantAccess& va, const struct iso2_CableCheckReqType& in,
const struct iso2_MessageHeaderType& header) {
va.insert_type<CableCheckRequest>(in, header);
}

template <> void convert(const CableCheckResponse& in, struct iso2_CableCheckResType& out) {
init_iso2_CableCheckResType(&out);

cb_convert_enum(in.response_code, out.ResponseCode);
convert(in.evse_status, out.DC_EVSEStatus);
cb_convert_enum(in.evse_processing, out.EVSEProcessing);
}

template <> int serialize_to_exi(const CableCheckResponse& in, exi_bitstream_t& out) {

iso2_exiDocument doc;
init_iso2_exiDocument(&doc);

convert(in.header, doc.V2G_Message.Header);

CB_SET_USED(doc.V2G_Message.Body.CableCheckRes);
convert(in, doc.V2G_Message.Body.CableCheckRes);

return encode_iso2_exiDocument(&out, &doc);
}

template <> size_t serialize(const CableCheckResponse& in, const io::StreamOutputView& out) {
return serialize_helper(in, out);
}

} // namespace iso15118::d2::msg
Loading