using EVCB_OCPP.Packet.Features; using EVCB_OCPP.Packet.Messages; using Newtonsoft.Json; using Newtonsoft.Json.Serialization; using NLog; using OCPPServer.Protocol; namespace EVCB_OCPP.WSServer.Message { /// /// 實現 OCPP 基本傳送規範, /// 1.訊息 基本格式,將訊息包裝成 Call 、CallResult、CallError 三種格式 /// 2.OCPP 定義的傳送規則:交易相關的訊息必須依照時序性傳送,一個傳完才能接著送下一個(忽略規則 由Center System定義) /// internal class BasicMessageHandler { static protected ILogger logger = NLog.LogManager.GetCurrentClassLogger(); #region 傳送 or 解析訊息需要欄位 private const int INDEX_MESSAGEID = 0; private const int INDEX_UNIQUEID = 1; internal const int TYPENUMBER_CALL = 2; private const int INDEX_CALL_ACTION = 2; private const int INDEX_CALL_PAYLOAD = 3; internal const int TYPENUMBER_CALLRESULT = 3; private const int INDEX_CALLRESULT_PAYLOAD = 2; internal const int TYPENUMBER_CALLERROR = 4; private const int INDEX_CALLERROR_ERRORCODE = 2; private const int INDEX_CALLERROR_DESCRIPTION = 3; private const int INDEX_CALLERROR_PAYLOAD = 4; private const string CALL_FORMAT = "[2,\"{0}\",\"{1}\",{2}]"; private const string CALLRESULT_FORMAT = "[3,\"{0}\",{1}]"; private const string CALLERROR_FORMAT = "[4,\"{0}\",\"{1}\",\"{2}\",{3}]"; private const string DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss'Z'"; private const string DATE_FORMAT_WITH_MS = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"; #endregion private OCPP16MessageHandler _ocpp16Handler = new OCPP16MessageHandler(); private OCPP20MessageHandler _ocpp20Handler = new OCPP20MessageHandler(); /// /// 將收到的封包做基本的拆解分成 Call 、CallResult、CallError /// /// /// /// internal MessageResult AnalysisReceiveData(ClientData client, string data) { MessageResult result = null; if (!client.ISOCPP20) { result = _ocpp16Handler.AnalysisReceiveData(client, data); } else { result = _ocpp20Handler.AnalysisReceiveData(client, data); } return result; } static internal string GenerateCallError(string uniqueId, string errorCode, string errorDescription) { string msg = string.Format(CALLERROR_FORMAT, uniqueId, errorCode, errorDescription, "{}"); return msg; } static internal string GenerateConfirmation(string uniqueId, IConfirmation confirmation) { string msg = string.Empty; if (confirmation != null && confirmation.Validate()) { msg = string.Format(CALLRESULT_FORMAT, uniqueId, JsonConvert.SerializeObject(confirmation, new JsonSerializerSettings() { ContractResolver = new CamelCasePropertyNamesContractResolver(), NullValueHandling = NullValueHandling.Ignore, Formatting = Formatting.None })); } else { logger.Error(string.Format("confirmation is null or InVaild in GenerateConfirmation Method"), "Warning"); } return msg; } static internal string GenerateConfirmationofOCPP20(string uniqueId, EVCB_OCPP20.Packet.Messages.IConfirmation confirmation) { string msg = string.Empty; if (confirmation != null && confirmation.Validate()) { msg = string.Format(CALLRESULT_FORMAT, uniqueId, JsonConvert.SerializeObject(confirmation, new JsonSerializerSettings() { ContractResolver = new CamelCasePropertyNamesContractResolver(), NullValueHandling = NullValueHandling.Ignore, Formatting = Formatting.None })); } else { logger.Error(string.Format("confirmation is null or InVaild in GenerateConfirmation Method"), "Warning"); } return msg; } static internal string GenerateRequest(string uniqueId, string action, IRequest request) { string msg = string.Empty; if (request != null && request.Validate()) { msg = string.Format(CALL_FORMAT, uniqueId, action, JsonConvert.SerializeObject(request, new JsonSerializerSettings() { ContractResolver = new CamelCasePropertyNamesContractResolver(), NullValueHandling = NullValueHandling.Ignore, Formatting = Formatting.None })); } else { if (action == Actions.ChangeConfiguration.ToString()) { if(!request.Validate()) { logger.Error("!Validate", "Warning"); } if (request == null) { logger.Error("!NULL", "Warning"); } } logger.Error(string.Format("confirmation is null or InVaild in GenerateRequest Method "+ action), "Warning"); } return msg; } static internal string GenerateRequestofOCPP20(string uniqueId, string action, EVCB_OCPP20.Packet.Messages.IRequest request) { string msg = string.Empty; if (request != null && request.Validate()) { msg = string.Format(CALL_FORMAT, uniqueId, action, JsonConvert.SerializeObject(request, new JsonSerializerSettings() { ContractResolver = new CamelCasePropertyNamesContractResolver(), NullValueHandling = NullValueHandling.Ignore, Formatting = Formatting.None })); } else { logger.Error(string.Format("confirmation is null or InVaild in GenerateRequest Method"), "Warning"); } return msg; } static internal string GenerateDestroyRequest(string uniqueId, string action, string request) { return string.Format(CALL_FORMAT, uniqueId, action, request); } } }