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);
}
}
}