feat: Add CurrentDemandRes encoding support to universal EXI codec
- Implemented complete CurrentDemandRes encoder following C grammar states 317-329 - Added EncodeCurrentDemandResType with proper response code, DC_EVSEStatus, voltage/current values - Added EncodeDC_EVSEStatusType for EVSE status with optional isolation status - Fixed missing EncodeString and EncodeMeterInfo methods for string and meter data encoding - Added EncodeInteger64 for 64-bit TMeter field support - Fixed type conversions (uint to int) for proper bit stream encoding - Verified encoding functionality with CurrentDemandRes test XML - Encoder now supports both CurrentDemandReq and CurrentDemandRes as minimum requirement - Structured for expansion to support all ISO 15118 message types (universal codec) 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
		| @@ -446,7 +446,16 @@ namespace V2GDecoderNet | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     throw new Exception("Unsupported message type for encoding - only CurrentDemandReq supported"); | ||||
|                     var currentDemandRes = bodyElement.Element(ns3 + "CurrentDemandRes"); | ||||
|                     if (currentDemandRes != null) | ||||
|                     { | ||||
|                         v2gMessage.Body.CurrentDemandRes = ParseCurrentDemandResXml(currentDemandRes, ns3, ns4); | ||||
|                         v2gMessage.Body.CurrentDemandRes_isUsed = true; | ||||
|                     } | ||||
|                     else | ||||
|                     { | ||||
|                         throw new Exception("Unsupported message type for encoding - supported: CurrentDemandReq, CurrentDemandRes"); | ||||
|                     } | ||||
|                 } | ||||
|                  | ||||
|                 // Encode to EXI | ||||
| @@ -546,6 +555,130 @@ namespace V2GDecoderNet | ||||
|              | ||||
|             return req; | ||||
|         } | ||||
|  | ||||
|         private static CurrentDemandResType ParseCurrentDemandResXml(XElement resElement, XNamespace ns3, XNamespace ns4) | ||||
|         { | ||||
|             var res = new CurrentDemandResType(); | ||||
|              | ||||
|             // Parse ResponseCode | ||||
|             var responseCode = resElement.Element(ns3 + "ResponseCode"); | ||||
|             if (responseCode != null) | ||||
|             { | ||||
|                 res.ResponseCode = (ResponseCodeType)Enum.Parse(typeof(ResponseCodeType), responseCode.Value); | ||||
|             } | ||||
|              | ||||
|             // Parse DC_EVSEStatus | ||||
|             var dcEvseStatus = resElement.Element(ns3 + "DC_EVSEStatus"); | ||||
|             if (dcEvseStatus != null) | ||||
|             { | ||||
|                 res.DC_EVSEStatus = new DC_EVSEStatusType(); | ||||
|                  | ||||
|                 var notificationMaxDelay = dcEvseStatus.Element(ns4 + "NotificationMaxDelay"); | ||||
|                 if (notificationMaxDelay != null) | ||||
|                     res.DC_EVSEStatus.NotificationMaxDelay = ushort.Parse(notificationMaxDelay.Value); | ||||
|                      | ||||
|                 var evseNotification = dcEvseStatus.Element(ns4 + "EVSENotification"); | ||||
|                 if (evseNotification != null) | ||||
|                     res.DC_EVSEStatus.EVSENotification = (EVSENotificationType)int.Parse(evseNotification.Value); | ||||
|                      | ||||
|                 var evseIsolationStatus = dcEvseStatus.Element(ns4 + "EVSEIsolationStatus"); | ||||
|                 if (evseIsolationStatus != null) | ||||
|                 { | ||||
|                     res.DC_EVSEStatus.EVSEIsolationStatus = (IsolationLevelType)int.Parse(evseIsolationStatus.Value); | ||||
|                     res.DC_EVSEStatus.EVSEIsolationStatus_isUsed = true; | ||||
|                 } | ||||
|                  | ||||
|                 var evseStatusCode = dcEvseStatus.Element(ns4 + "EVSEStatusCode");   | ||||
|                 if (evseStatusCode != null) | ||||
|                     res.DC_EVSEStatus.EVSEStatusCode = (DC_EVSEStatusCodeType)int.Parse(evseStatusCode.Value); | ||||
|             } | ||||
|              | ||||
|             // Parse EVSEPresentVoltage | ||||
|             var evsePresentVoltage = resElement.Element(ns3 + "EVSEPresentVoltage"); | ||||
|             if (evsePresentVoltage != null) | ||||
|             { | ||||
|                 res.EVSEPresentVoltage = ParsePhysicalValueXml(evsePresentVoltage, ns4); | ||||
|             } | ||||
|              | ||||
|             // Parse EVSEPresentCurrent | ||||
|             var evsePresentCurrent = resElement.Element(ns3 + "EVSEPresentCurrent"); | ||||
|             if (evsePresentCurrent != null) | ||||
|             { | ||||
|                 res.EVSEPresentCurrent = ParsePhysicalValueXml(evsePresentCurrent, ns4); | ||||
|             } | ||||
|              | ||||
|             // Parse boolean flags | ||||
|             var evseCurrentLimitAchieved = resElement.Element(ns3 + "EVSECurrentLimitAchieved"); | ||||
|             if (evseCurrentLimitAchieved != null) | ||||
|                 res.EVSECurrentLimitAchieved = bool.Parse(evseCurrentLimitAchieved.Value); | ||||
|                  | ||||
|             var evseVoltageLimitAchieved = resElement.Element(ns3 + "EVSEVoltageLimitAchieved"); | ||||
|             if (evseVoltageLimitAchieved != null) | ||||
|                 res.EVSEVoltageLimitAchieved = bool.Parse(evseVoltageLimitAchieved.Value); | ||||
|                  | ||||
|             var evsePowerLimitAchieved = resElement.Element(ns3 + "EVSEPowerLimitAchieved"); | ||||
|             if (evsePowerLimitAchieved != null) | ||||
|                 res.EVSEPowerLimitAchieved = bool.Parse(evsePowerLimitAchieved.Value); | ||||
|              | ||||
|             // Parse optional limits | ||||
|             var evseMaximumVoltageLimit = resElement.Element(ns3 + "EVSEMaximumVoltageLimit"); | ||||
|             if (evseMaximumVoltageLimit != null) | ||||
|             { | ||||
|                 res.EVSEMaximumVoltageLimit = ParsePhysicalValueXml(evseMaximumVoltageLimit, ns4); | ||||
|                 res.EVSEMaximumVoltageLimit_isUsed = true; | ||||
|             } | ||||
|              | ||||
|             var evseMaximumCurrentLimit = resElement.Element(ns3 + "EVSEMaximumCurrentLimit"); | ||||
|             if (evseMaximumCurrentLimit != null) | ||||
|             { | ||||
|                 res.EVSEMaximumCurrentLimit = ParsePhysicalValueXml(evseMaximumCurrentLimit, ns4); | ||||
|                 res.EVSEMaximumCurrentLimit_isUsed = true; | ||||
|             } | ||||
|              | ||||
|             var evseMaximumPowerLimit = resElement.Element(ns3 + "EVSEMaximumPowerLimit"); | ||||
|             if (evseMaximumPowerLimit != null) | ||||
|             { | ||||
|                 res.EVSEMaximumPowerLimit = ParsePhysicalValueXml(evseMaximumPowerLimit, ns4); | ||||
|                 res.EVSEMaximumPowerLimit_isUsed = true; | ||||
|             } | ||||
|              | ||||
|             // Parse EVSEID | ||||
|             var evseid = resElement.Element(ns3 + "EVSEID"); | ||||
|             if (evseid != null) | ||||
|                 res.EVSEID = evseid.Value; | ||||
|                  | ||||
|             // Parse SAScheduleTupleID | ||||
|             var saScheduleTupleId = resElement.Element(ns3 + "SAScheduleTupleID"); | ||||
|             if (saScheduleTupleId != null) | ||||
|                 res.SAScheduleTupleID = byte.Parse(saScheduleTupleId.Value); | ||||
|                  | ||||
|             // Parse MeterInfo (optional) | ||||
|             var meterInfo = resElement.Element(ns3 + "MeterInfo"); | ||||
|             if (meterInfo != null) | ||||
|             { | ||||
|                 res.MeterInfo = new MeterInfoType(); | ||||
|                  | ||||
|                 var meterID = meterInfo.Element(ns4 + "MeterID"); | ||||
|                 if (meterID != null) | ||||
|                     res.MeterInfo.MeterID = meterID.Value; | ||||
|                      | ||||
|                 var meterReading = meterInfo.Element(ns4 + "MeterReading"); | ||||
|                 if (meterReading != null) | ||||
|                     res.MeterInfo.MeterReading = ulong.Parse(meterReading.Value); | ||||
|                      | ||||
|                 res.MeterInfo_isUsed = true; | ||||
|             } | ||||
|              | ||||
|             // Parse ReceiptRequired (optional) | ||||
|             var receiptRequired = resElement.Element(ns3 + "ReceiptRequired"); | ||||
|             if (receiptRequired != null) | ||||
|             { | ||||
|                 res.ReceiptRequired = bool.Parse(receiptRequired.Value); | ||||
|                 res.ReceiptRequired_isUsed = true; | ||||
|             } | ||||
|              | ||||
|             return res; | ||||
|         } | ||||
|          | ||||
|         private static PhysicalValueType ParsePhysicalValueXml(XElement element, XNamespace ns4) | ||||
|         { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 ChiKyun Kim
					ChiKyun Kim