Browse Source

2020/10/28
Actions:
OCPP2.0支援Heartbeat 、 BootNotification、StatusNotification

Jessica Tseng 4 years ago
parent
commit
260f55d7ec

BIN
EVCB_OCPP.WSServer/DLL/EVCB_OCPP.Packet20.dll


+ 4 - 3
EVCB_OCPP.WSServer/Message/BasicMessageHandler.cs

@@ -3,6 +3,7 @@ using EVCB_OCPP.Packet.Messages;
 using EVCB_OCPP.Packet.Messages.Basic;
 using Newtonsoft.Json;
 using Newtonsoft.Json.Linq;
+using Newtonsoft.Json.Serialization;
 using NLog;
 using OCPPServer.Protocol;
 using System;
@@ -84,7 +85,7 @@ namespace EVCB_OCPP.WSServer.Message
             if (confirmation != null && confirmation.Validate())
             {
 
-                msg = string.Format(CALLRESULT_FORMAT, uniqueId, JsonConvert.SerializeObject(confirmation, new JsonSerializerSettings() { NullValueHandling = NullValueHandling.Ignore, Formatting = Formatting.None }));
+                msg = string.Format(CALLRESULT_FORMAT, uniqueId, JsonConvert.SerializeObject(confirmation, new JsonSerializerSettings() { ContractResolver = new CamelCasePropertyNamesContractResolver(), NullValueHandling = NullValueHandling.Ignore, Formatting = Formatting.None }));
             }
             else
             {
@@ -98,7 +99,7 @@ namespace EVCB_OCPP.WSServer.Message
             if (confirmation != null && confirmation.Validate())
             {
 
-                msg = string.Format(CALLRESULT_FORMAT, uniqueId, JsonConvert.SerializeObject(confirmation, new JsonSerializerSettings() { NullValueHandling = NullValueHandling.Ignore, Formatting = Formatting.None }));
+                msg = string.Format(CALLRESULT_FORMAT, uniqueId, JsonConvert.SerializeObject(confirmation, new JsonSerializerSettings() { ContractResolver = new CamelCasePropertyNamesContractResolver(), NullValueHandling = NullValueHandling.Ignore, Formatting = Formatting.None }));
             }
             else
             {
@@ -113,7 +114,7 @@ namespace EVCB_OCPP.WSServer.Message
             if (request != null && request.Validate())
             {
 
-                msg = string.Format(CALL_FORMAT, uniqueId, action, JsonConvert.SerializeObject(request, new JsonSerializerSettings() { NullValueHandling = NullValueHandling.Ignore, Formatting = Formatting.None }));
+                msg = string.Format(CALL_FORMAT, uniqueId, action, JsonConvert.SerializeObject(request, new JsonSerializerSettings() { ContractResolver = new CamelCasePropertyNamesContractResolver(), NullValueHandling = NullValueHandling.Ignore, Formatting = Formatting.None }));
             }
             else
             {

+ 4 - 0
EVCB_OCPP.WSServer/Message/MessageResult.cs

@@ -48,6 +48,10 @@ namespace EVCB_OCPP.WSServer.Message
 
         internal IConfirmation Confirmation { set; get; }
 
+        internal EVCB_OCPP.Packet20.Messages.IRequest Request20 { set; get; }
+
+        internal EVCB_OCPP.Packet20.Messages.IConfirmation Confirmation20 { set; get; }
+
         internal Exception Exception { get; set; }
     }
 

+ 66 - 58
EVCB_OCPP.WSServer/Message/OCPP20MessageHandler.cs

@@ -1,6 +1,6 @@
-using EVCB_OCPP.Packet.Messages;
-using EVCB_OCPP.Packet.Messages.Basic;
+using EVCB_OCPP.Packet.Messages.Basic;
 using EVCB_OCPP.Packet20.Features;
+using EVCB_OCPP.Packet20.Messages;
 using Newtonsoft.Json;
 using Newtonsoft.Json.Linq;
 using NLog;
@@ -10,7 +10,9 @@ using System.Collections.Generic;
 using System.Linq;
 using System.Text;
 using System.Threading.Tasks;
-
+using I20Request = EVCB_OCPP.Packet20.Messages.IRequest;
+using I20Confirmation = EVCB_OCPP.Packet20.Messages.IConfirmation;
+using EVCB_OCPP.Packet.Messages;
 
 namespace EVCB_OCPP.WSServer.Message
 {
@@ -47,7 +49,7 @@ namespace EVCB_OCPP.WSServer.Message
 
         private List<Profile> profiles = new List<Profile>()
         {
-             new CoreProfile(),            
+             new CoreProfile(),
 
         };
 
@@ -78,12 +80,12 @@ namespace EVCB_OCPP.WSServer.Message
                                 Actions action = Actions.None;
                                 Enum.TryParse<Actions>(msg.Action, out action);
                                 result.Action = msg.Action;
-                                if (baseResult.Request != null)
+                                if (baseResult.Request20 != null)
                                 {
-                                    if (baseResult.Request.Validate())
+                                    if (baseResult.Request20.Validate())
                                     {
                                         result.Id = TYPENUMBER_CALL;
-                                        result.Message = baseResult.Request;
+                                        result.Message = baseResult.Request20;
 
                                     }
                                     else
@@ -92,7 +94,7 @@ namespace EVCB_OCPP.WSServer.Message
                                         string replyMsg = BasicMessageHandler.GenerateCallError(msg.Id, OCPPErrorCodes.OccurenceConstraintViolation.ToString(),
                                              OCPPErrorDescription.OccurenceConstraintViolation);
                                         result.Id = TYPENUMBER_CALL;
-                                        result.Message = baseResult.Request;
+                                        result.Message = baseResult.Request20;
                                         result.Success = false;
                                         result.CallErrorMsg = replyMsg;
                                         result.Exception = new Exception("Validation Failed");
@@ -104,7 +106,7 @@ namespace EVCB_OCPP.WSServer.Message
 
                                     string replyMsg = BasicMessageHandler.GenerateCallError(msg.Id, OCPPErrorCodes.OccurenceConstraintViolation, OCPPErrorDescription.OccurenceConstraintViolation);
                                     result.Id = TYPENUMBER_CALL;
-                                    result.Message = baseResult.Request;
+                                    result.Message = baseResult.Request20;
                                     result.Success = false;
                                     result.CallErrorMsg = replyMsg;
                                     result.Exception = baseResult.Exception;
@@ -114,55 +116,55 @@ namespace EVCB_OCPP.WSServer.Message
                             break;
                         case TYPENUMBER_CALLRESULT:
                             {
-                                BasicMessageResult baseResult = UnPackPayloadbyCallResult(client.queue, msg.Id, msg.Payload.ToString());
-
-                                if (baseResult.Confirmation != null)
-                                {
-
-                                    if (baseResult.Confirmation.Validate())
-                                    {
-                                        result.Id = TYPENUMBER_CALLRESULT;
-                                        result.Message = baseResult.Confirmation;
-                                        result.Action = baseResult.Confirmation.GetRequest().Action;
-                                        //return data
-                                    }
-                                    else
-                                    {
-                                        string replyMsg = BasicMessageHandler.GenerateCallError(msg.Id, OCPPErrorCodes.OccurenceConstraintViolation.ToString(),
-                                      OCPPErrorDescription.OccurenceConstraintViolation);
-                                        result.Id = TYPENUMBER_CALLRESULT;
-                                        result.Message = baseResult.Confirmation;
-                                        result.Success = false;
-                                        result.CallErrorMsg = replyMsg;
-                                        result.Exception = new Exception("Validate Failed");
-                                    }
-                                }
-                                else
-                                {
-                                    string replyMsg = BasicMessageHandler.GenerateCallError(msg.Id, OCPPErrorCodes.OccurenceConstraintViolation.ToString(),
-                                   OCPPErrorDescription.OccurenceConstraintViolation);
-                                    result.Id = TYPENUMBER_CALLRESULT;
-                                    result.Message = baseResult.Confirmation;
-                                    result.Success = false;
-                                    result.CallErrorMsg = replyMsg;
-                                    result.Exception = baseResult.Exception;
-                                }
+                                //BasicMessageResult baseResult = UnPackPayloadbyCallResult(client.queue, msg.Id, msg.Payload.ToString());
+
+                                //if (baseResult.Confirmation != null)
+                                //{
+
+                                //    if (baseResult.Confirmation.Validate())
+                                //    {
+                                //        result.Id = TYPENUMBER_CALLRESULT;
+                                //        result.Message = baseResult.Confirmation;
+                                //        result.Action = baseResult.Confirmation.GetRequest().Action;
+                                //        //return data
+                                //    }
+                                //    else
+                                //    {
+                                //        string replyMsg = BasicMessageHandler.GenerateCallError(msg.Id, OCPPErrorCodes.OccurenceConstraintViolation.ToString(),
+                                //      OCPPErrorDescription.OccurenceConstraintViolation);
+                                //        result.Id = TYPENUMBER_CALLRESULT;
+                                //        result.Message = baseResult.Confirmation;
+                                //        result.Success = false;
+                                //        result.CallErrorMsg = replyMsg;
+                                //        result.Exception = new Exception("Validate Failed");
+                                //    }
+                                //}
+                                //else
+                                //{
+                                //    string replyMsg = BasicMessageHandler.GenerateCallError(msg.Id, OCPPErrorCodes.OccurenceConstraintViolation.ToString(),
+                                //   OCPPErrorDescription.OccurenceConstraintViolation);
+                                //    result.Id = TYPENUMBER_CALLRESULT;
+                                //    result.Message = baseResult.Confirmation;
+                                //    result.Success = false;
+                                //    result.CallErrorMsg = replyMsg;
+                                //    result.Exception = baseResult.Exception;
+                                //}
 
                             }
                             break;
                         case TYPENUMBER_CALLERROR:
                             {
                                 result.Id = TYPENUMBER_CALLERROR;
-                                var sentRequest = UnPackPayloadbyCallError(client.queue, msg.Id);
+                                // var sentRequest = UnPackPayloadbyCallError(client.queue, msg.Id);
 
-                                if (sentRequest != null)
-                                {
-                                    IRequest request = sentRequest as IRequest;
-                                    result.Action = request.Action;
+                                //if (sentRequest != null)
+                                //{
+                                //    I20Request request = sentRequest as I20Request;
+                                //    result.Action = request.Action;
 
-                                    result.Message = sentRequest;
-                                    result.ReceivedErrorCode = string.Format("ErrorMsg {0}:{1}", ((CallErrorMessage)msg).ErrorCode, ((CallErrorMessage)msg).ErrorDescription);
-                                }
+                                //    result.Message = sentRequest;
+                                //    result.ReceivedErrorCode = string.Format("ErrorMsg {0}:{1}", ((CallErrorMessage)msg).ErrorCode, ((CallErrorMessage)msg).ErrorDescription);
+                                //}
 
 
                             }
@@ -269,8 +271,9 @@ namespace EVCB_OCPP.WSServer.Message
                         break;
                     }
                 }
-
-                result.Request = JsonConvert.DeserializeObject(payload, feature.GetRequestType()) as IRequest;
+                string tt = "{  \"connectorId\": 1,  \"evseId\": 1,  \"connectorStatus\": \"Occupied\",  \"timestamp\": \"2020-10-28T08:28:47Z\"}";
+                var gg = JsonConvert.DeserializeObject(tt, typeof(StatusNotificationRequest));
+                result.Request20 = JsonConvert.DeserializeObject(payload, feature.GetRequestType()) as I20Request;
 
             }
             catch (Exception ex)
@@ -283,12 +286,12 @@ namespace EVCB_OCPP.WSServer.Message
             return result;
         }
 
-        private BasicMessageResult UnPackPayloadbyCallResult(Queue requestQueue, string uniqueId, string payload)
+        private BasicMessageResult UnPackPayloadbyCallResult(EVCB_OCPP.Packet20.Messages.Basic.Queue requestQueue, string uniqueId, string payload)
         {
             BasicMessageResult result = new BasicMessageResult();
             try
             {
-                IRequest request = requestQueue.RestoreRequest(uniqueId);
+                I20Request request = requestQueue.RestoreRequest(uniqueId);
                 Feature feature = null;
                 foreach (var profile in profiles)
                 {
@@ -303,9 +306,10 @@ namespace EVCB_OCPP.WSServer.Message
                     }
                 }
 
-                IConfirmation confrim = JsonConvert.DeserializeObject(payload, feature.GetConfirmationType()) as IConfirmation;
+
+                I20Confirmation confrim = JsonConvert.DeserializeObject(payload, feature.GetConfirmationType()) as I20Confirmation;
                 confrim.SetRequest(request);
-                result.Confirmation = confrim;
+                result.Confirmation20 = confrim;
 
             }
             catch (Exception ex)
@@ -318,15 +322,19 @@ namespace EVCB_OCPP.WSServer.Message
 
         }
 
-        private IRequest UnPackPayloadbyCallError(Queue requestQueue, string uniqueId)
+        private I20Request UnPackPayloadbyCallError(EVCB_OCPP.Packet20.Messages.Basic.Queue requestQueue, string uniqueId)
         {
-            IRequest sentMsg = requestQueue.RestoreRequest(uniqueId);
+            I20Request sentMsg = requestQueue.RestoreRequest(uniqueId);
 
             return sentMsg;
 
         }
+
+
+
         #endregion
 
 
+
     }
 }

+ 14 - 1
EVCB_OCPP.WSServer/Program.cs

@@ -1,6 +1,6 @@
 using EVCB_OCPP.Packet.Features;
 using EVCB_OCPP.Packet.Messages.Basic;
-using EVCB_OCPP.Packet.Messages.Core;
+using EVCB_OCPP.Packet20.Messages;
 using EVCB_OCPP.WSServer.Message;
 using Newtonsoft.Json;
 using Newtonsoft.Json.Linq;
@@ -16,7 +16,9 @@ namespace EVCB_OCPP.WSServer
     {
         static void Main(string[] args)
         {
+            string tt = "{  \"connectorId\": 1,  \"evseId\": 1,  \"connectorStatus\": \"Occupied\",  \"timestamp\": \"2020-10-28T08:28:47Z\"}";
 
+          var gg=  JsonConvert.DeserializeObject<StatusNotificationRequest>(tt);
 
             ProtalServer s = new ProtalServer();
             Console.WriteLine("Starting Server...");
@@ -24,5 +26,16 @@ namespace EVCB_OCPP.WSServer
 
             Console.Read();
         }
+
+        public static object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
+        {
+            DateTime? timevalue = null;
+            if (reader.Value != null)
+            {
+                DateTime date = ((DateTime)reader.Value).ToLocalTime();
+                timevalue = new DateTime(date.Year, date.Month, date.Day, date.TimeOfDay.Hours, date.TimeOfDay.Minutes, date.TimeOfDay.Seconds, 000);
+            }
+            return timevalue;
+        }
     }
 }

+ 37 - 1
EVCB_OCPP.WSServer/ProtalServer.cs

@@ -373,7 +373,7 @@ namespace EVCB_OCPP.WSServer
             {
                 lock (_lockClientDic)
                 {
-                    bool isNotSupported = session.SecWebSocketProtocol.Contains("ocpp1.6") ? false : true;
+                    bool isNotSupported = session.SecWebSocketProtocol.Contains("ocpp1.6") ?false : session.SecWebSocketProtocol.Contains("ocpp2.0") ? false : true;
                     if (isNotSupported)
                     {
                         //logger.Debug(string.Format("ChargeBoxId:{0} SecWebSocketProtocol:{1} NotSupported", session.ChargeBoxId, session.SecWebSocketProtocol));
@@ -543,6 +543,42 @@ namespace EVCB_OCPP.WSServer
                                                 string response = BasicMessageHandler.GenerateConfirmationofOCPP20(analysisResult.UUID, (Packet20.Messages.IConfirmation)result.Message);
                                                 Send(session, response, string.Format("{0} {1}", analysisResult.Action, "Response"), result.Exception == null ? string.Empty : result.Exception.ToString());
 
+                                            }
+                                            break;
+                                        case Actions.StatusNotification:
+                                            {
+                                                Packet20.Messages.StatusNotificationRequest _request = (Packet20.Messages.IRequest)analysisResult.Message as Packet20.Messages.StatusNotificationRequest;
+                                               // int heartbeat_interval = GlobalConfig.GetHEARTBEAT_INTERVAL();
+                                                //using (var db = new MainDBContext())
+                                                //{
+                                                //    var _machine = db.Machine.Where(x => x.ChargeBoxId == session.ChargeBoxId).FirstOrDefault();
+                                                //    _machine.ChargeBoxSerialNumber = string.IsNullOrEmpty(_request.chargeBoxSerialNumber) ? string.Empty : _request.chargeBoxSerialNumber;
+                                                //    _machine.ChargePointModel = string.IsNullOrEmpty(_request.chargePointModel) ? string.Empty : _request.chargePointModel;
+                                                //    _machine.ChargePointVendor = string.IsNullOrEmpty(_request.chargePointVendor) ? string.Empty : _request.chargePointVendor;
+                                                //    _machine.FW_CurrentVersion = string.IsNullOrEmpty(_request.firmwareVersion) ? string.Empty : _request.firmwareVersion;
+                                                //    _machine.Iccid = string.IsNullOrEmpty(_request.iccid) ? string.Empty : _request.iccid;
+                                                //    _machine.Imsi = string.IsNullOrEmpty(_request.imsi) ? string.Empty : _request.imsi;
+                                                //    _machine.MeterSerialNumber = string.IsNullOrEmpty(_request.meterSerialNumber) ? string.Empty : _request.meterSerialNumber;
+                                                //    _machine.MeterType = string.IsNullOrEmpty(_request.meterType) ? string.Empty : _request.meterType;
+
+                                                //    db.SaveChanges();
+
+                                                //    var configVaule = db.MachineConfiguration.Where(x => x.ChargeBoxId == session.ChargeBoxId && x.ConfigureName == StandardConfiguration.HeartbeatInterval)
+                                                //        .Select(x => x.ConfigureSetting).FirstOrDefault();
+
+                                                //    if (configVaule != null)
+                                                //    {
+                                                //        int.TryParse(configVaule, out heartbeat_interval);
+                                                //    }
+                                                //}
+                                                var confirm = new Packet20.Messages.StatusNotificationResponse() {   };
+
+                                                result.Message = confirm;
+                                                result.Success = true;
+
+                                                string response = BasicMessageHandler.GenerateConfirmationofOCPP20(analysisResult.UUID, (Packet20.Messages.IConfirmation)result.Message);
+                                                Send(session, response, string.Format("{0} {1}", analysisResult.Action, "Response"), result.Exception == null ? string.Empty : result.Exception.ToString());
+
                                             }
                                             break;
                                         default:

+ 10 - 3
SuperWebSocket/WebSocketSession.cs

@@ -225,6 +225,7 @@ namespace SuperWebSocket
 
         string IWebSocketSession.GetAvailableSubProtocol(string protocol)
         {
+            protocol = "ocpp1.6, ocpp2.0";
             if (string.IsNullOrEmpty(protocol))
             {
                 SubProtocol = AppServer.DefaultSubProtocol;
@@ -233,11 +234,17 @@ namespace SuperWebSocket
 
             var arrNames = protocol.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
 
-            foreach(var name in arrNames)
+            if (protocol.ToLower().Contains("ocpp2.0"))
             {
+                arrNames = new string[] { "ocpp2.0" };
+            }
+
+            foreach (var name in arrNames)
+            {
+
                 var subProtocol = AppServer.GetSubProtocol(name);
 
-                if(subProtocol != null)
+                if (subProtocol != null)
                 {
                     SubProtocol = subProtocol;
                     return name;
@@ -396,7 +403,7 @@ namespace SuperWebSocket
         {
             if (!ProtocolProcessor.CanSendBinaryData)
             {
-                if(Logger.IsErrorEnabled)
+                if (Logger.IsErrorEnabled)
                     Logger.Error("The websocket of this version cannot used for sending binary data!");
                 return;
             }