BasicMessageHandler.cs 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. using EVCB_OCPP.Packet.Features;
  2. using EVCB_OCPP.Packet.Messages;
  3. using EVCB_OCPP.Packet.Messages.Basic;
  4. using Newtonsoft.Json;
  5. using Newtonsoft.Json.Linq;
  6. using Newtonsoft.Json.Serialization;
  7. using NLog;
  8. using OCPPServer.Protocol;
  9. using System;
  10. using System.Collections.Generic;
  11. using System.Linq;
  12. using System.Text;
  13. using System.Threading.Tasks;
  14. using Packet20 = EVCB_OCPP.Packet20;
  15. namespace EVCB_OCPP.WSServer.Message
  16. {
  17. /// <summary>
  18. /// 實現 OCPP 基本傳送規範,
  19. /// 1.訊息 基本格式,將訊息包裝成 Call 、CallResult、CallError 三種格式
  20. /// 2.OCPP 定義的傳送規則:交易相關的訊息必須依照時序性傳送,一個傳完才能接著送下一個(忽略規則 由Center System定義)
  21. /// </summary>
  22. internal class BasicMessageHandler
  23. {
  24. static protected ILogger logger = NLog.LogManager.GetCurrentClassLogger();
  25. #region 傳送 or 解析訊息需要欄位
  26. private const int INDEX_MESSAGEID = 0;
  27. private const int INDEX_UNIQUEID = 1;
  28. internal const int TYPENUMBER_CALL = 2;
  29. private const int INDEX_CALL_ACTION = 2;
  30. private const int INDEX_CALL_PAYLOAD = 3;
  31. internal const int TYPENUMBER_CALLRESULT = 3;
  32. private const int INDEX_CALLRESULT_PAYLOAD = 2;
  33. internal const int TYPENUMBER_CALLERROR = 4;
  34. private const int INDEX_CALLERROR_ERRORCODE = 2;
  35. private const int INDEX_CALLERROR_DESCRIPTION = 3;
  36. private const int INDEX_CALLERROR_PAYLOAD = 4;
  37. private const string CALL_FORMAT = "[2,\"{0}\",\"{1}\",{2}]";
  38. private const string CALLRESULT_FORMAT = "[3,\"{0}\",{1}]";
  39. private const string CALLERROR_FORMAT = "[4,\"{0}\",\"{1}\",\"{2}\",{3}]";
  40. private const string DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss'Z'";
  41. private const string DATE_FORMAT_WITH_MS = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'";
  42. #endregion
  43. private OCPP16MessageHandler _ocpp16Handler = new OCPP16MessageHandler();
  44. private OCPP20MessageHandler _ocpp20Handler = new OCPP20MessageHandler();
  45. /// <summary>
  46. /// 將收到的封包做基本的拆解分成 Call 、CallResult、CallError
  47. /// </summary>
  48. /// <param name="client"></param>
  49. /// <param name="data"></param>
  50. /// <returns></returns>
  51. internal MessageResult AnalysisReceiveData(ClientData client, string data)
  52. {
  53. MessageResult result = null;
  54. if (client.IsOCPP16)
  55. {
  56. result = _ocpp16Handler.AnalysisReceiveData(client, data);
  57. }
  58. else
  59. {
  60. result = _ocpp20Handler.AnalysisReceiveData(client, data);
  61. }
  62. return result;
  63. }
  64. static internal string GenerateCallError(string uniqueId, string errorCode, string errorDescription)
  65. {
  66. string msg = string.Format(CALLERROR_FORMAT, uniqueId, errorCode, errorDescription, "{}");
  67. return msg;
  68. }
  69. static internal string GenerateConfirmation(string uniqueId,IConfirmation confirmation)
  70. {
  71. string msg = string.Empty;
  72. if (confirmation != null && confirmation.Validate())
  73. {
  74. msg = string.Format(CALLRESULT_FORMAT, uniqueId, JsonConvert.SerializeObject(confirmation, new JsonSerializerSettings() { ContractResolver = new CamelCasePropertyNamesContractResolver(), NullValueHandling = NullValueHandling.Ignore, Formatting = Formatting.None }));
  75. }
  76. else
  77. {
  78. logger.Error(string.Format("confirmation is null or InVaild in GenerateConfirmation Method"), "Warning");
  79. }
  80. return msg;
  81. }
  82. static internal string GenerateConfirmationofOCPP20(string uniqueId, Packet20.Messages.IConfirmation confirmation)
  83. {
  84. string msg = string.Empty;
  85. if (confirmation != null && confirmation.Validate())
  86. {
  87. msg = string.Format(CALLRESULT_FORMAT, uniqueId, JsonConvert.SerializeObject(confirmation, new JsonSerializerSettings() { ContractResolver = new CamelCasePropertyNamesContractResolver(), NullValueHandling = NullValueHandling.Ignore, Formatting = Formatting.None }));
  88. }
  89. else
  90. {
  91. logger.Error(string.Format("confirmation is null or InVaild in GenerateConfirmation Method"), "Warning");
  92. }
  93. return msg;
  94. }
  95. static internal string GenerateRequest(string uniqueId, string action,IRequest request)
  96. {
  97. string msg = string.Empty;
  98. if (request != null && request.Validate())
  99. {
  100. msg = string.Format(CALL_FORMAT, uniqueId, action, JsonConvert.SerializeObject(request, new JsonSerializerSettings() { ContractResolver = new CamelCasePropertyNamesContractResolver(), NullValueHandling = NullValueHandling.Ignore, Formatting = Formatting.None }));
  101. }
  102. else
  103. {
  104. logger.Error(string.Format("confirmation is null or InVaild in GenerateRequest Method"), "Warning");
  105. }
  106. return msg;
  107. }
  108. static internal string GenerateRequestofOCPP20(string uniqueId, string action, Packet20.Messages.IRequest request)
  109. {
  110. string msg = string.Empty;
  111. if (request != null && request.Validate())
  112. {
  113. msg = string.Format(CALL_FORMAT, uniqueId, action, JsonConvert.SerializeObject(request, new JsonSerializerSettings() { NullValueHandling = NullValueHandling.Ignore, Formatting = Formatting.None }));
  114. }
  115. else
  116. {
  117. logger.Error(string.Format("confirmation is null or InVaild in GenerateRequest Method"), "Warning");
  118. }
  119. return msg;
  120. }
  121. static internal string GenerateDestroyRequest(string uniqueId, string action, string request)
  122. {
  123. return string.Format(CALL_FORMAT, uniqueId, action, request);
  124. }
  125. }
  126. }