123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155 |
- 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
- {
- /// <summary>
- /// 實現 OCPP 基本傳送規範,
- /// 1.訊息 基本格式,將訊息包裝成 Call 、CallResult、CallError 三種格式
- /// 2.OCPP 定義的傳送規則:交易相關的訊息必須依照時序性傳送,一個傳完才能接著送下一個(忽略規則 由Center System定義)
- /// </summary>
- 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();
- /// <summary>
- /// 將收到的封包做基本的拆解分成 Call 、CallResult、CallError
- /// </summary>
- /// <param name="client"></param>
- /// <param name="data"></param>
- /// <returns></returns>
- 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);
- }
- }
- }
|