Переглянути джерело

1.同步到 Master Commit 9a46efb7
2. Handshake 不存取資料庫 ,電樁若沒入庫後續再透過Task清除
3.SecurityLevel 統一規格

Jessica Tseng 2 роки тому
батько
коміт
5a408bc2ca

+ 7 - 5
EVCB_OCPP.WSServer/App.config

@@ -7,18 +7,20 @@
     <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
   </configSections>
    <connectionStrings>
-     <add name="ConnectionLogDBContext" connectionString="data source=172.1.2.187;initial catalog=StandardOCPP_ConnectionLog;;persist security info=True;user id=sa;password=Ph0930118811;MultipleActiveResultSets=True;App=EntityFramework; Max Pool Size=500" providerName="System.Data.SqlClient" />
-     <add name="MainDBContext" connectionString="data source=172.1.2.187;initial catalog=StandardOCPP_Main;;persist security info=True;user id=sa;password=Ph0930118811;MultipleActiveResultSets=True;App=EntityFramework; Max Pool Size=500" providerName="System.Data.SqlClient" />
-     <add name="MeterValueDBContext" connectionString="data source=172.1.2.187;initial catalog=StandardOCPP_MeterValue;;persist security info=True;user id=sa;password=Ph0930118811;MultipleActiveResultSets=True;App=EntityFramework; Max Pool Size=500" providerName="System.Data.SqlClient" />
-     <add name="WebDBContext" connectionString="data source=172.1.2.187;initial catalog=StandardOCPP_Web;;persist security info=True;user id=sa;password=Ph0930118811;MultipleActiveResultSets=True;App=EntityFramework; Max Pool Size=500" providerName="System.Data.SqlClient" />
+     <add name="ConnectionLogDBContext" connectionString="data source=172.1.2.187;initial catalog=StandardDev_ConnectionLog;persist security info=True;user id=sa;password=Ph0930118811;MultipleActiveResultSets=True;App=EntityFramework; Max Pool Size=50000;Connection Timeout=180" providerName="System.Data.SqlClient" />
+     <add name="MainDBContext" connectionString="data source=172.1.0.131;initial catalog=StandardDev_Main;persist security info=True;user id=sa;password=Ph0930118811;MultipleActiveResultSets=True;App=EntityFramework; Max Pool Size=50000;Connection Timeout=180" providerName="System.Data.SqlClient" />
+     <add name="MeterValueDBContext" connectionString="data source=172.1.0.131;initial catalog=StandardDev_MeterValue;persist security info=True;user id=sa;password=Ph0930118811;MultipleActiveResultSets=True;App=EntityFramework; Max Pool Size=50000;Connection Timeout=180" providerName="System.Data.SqlClient" />
+     <add name="WebDBContext" connectionString="data source=172.1.0.131;initial catalog=StandardDev_Web;persist security info=True;user id=sa;password=Ph0930118811;MultipleActiveResultSets=True;App=EntityFramework; Max Pool Size=50000;Connection Timeout=180" providerName="System.Data.SqlClient" />
    </connectionStrings>
   <appSettings>   
     <add key="LocalAuthAPI" value="" />
     <add key="WSPort" value="2012" />
-    <add key="WSSPort" value="2016" />
+    <add key="WSSPort" value="2013,2014" />
     <add key="OCPP20_WSUrl" value="ws://ocpp.phihong.com.tw:5004" />
     <add key="OCPP20_WSSUrl" value="ws://ocpp.phihong.com.tw:5004" />
     <add key="MaintainMode" value="0" />
+    <add key="SecurityProfileLevel" value="0" />
+    <add key="SecurityPassword" value="0" />
   </appSettings>
   <startup>
     <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.1" />

+ 25 - 0
EVCB_OCPP.WSServer/Dto/StationInfoDto.cs

@@ -0,0 +1,25 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace EVCB_OCPP.WSServer.Dto
+{
+    public class StationInfoDto
+    {
+
+        public int Id { set; get; }
+
+        /// <summary>
+        /// LoadingBalance Mode
+        /// 0:None 1: Average
+        /// 2:FCFS 3:Manual
+        /// </summary>
+        public int LBMode { set; get; }
+
+        public int Availability { set; get; }
+
+
+    }
+}

+ 0 - 18
EVCB_OCPP.WSServer/Dto/TCCStationInfoDto.cs

@@ -1,18 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace EVCB_OCPP.WSServer.Dto
-{
-    public class TCCStationInfoDto
-    {
-        public decimal Lat { set; get; }
-
-        public decimal Long { set; get; }
-
-        public string ZipCode { set; get; }
-
-    }
-}

+ 0 - 16
EVCB_OCPP.WSServer/Dto/TCCWeatherDto.cs

@@ -1,16 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace EVCB_OCPP.WSServer.Dto
-{
-    public class TCCWeatherDto
-    {
-        public int WeatherID { set; get; }
-
-
-        public int Temperature { set; get; }
-    }
-}

+ 7 - 2
EVCB_OCPP.WSServer/EVCB_OCPP.WSServer.csproj

@@ -111,6 +111,9 @@
     <Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
       <HintPath>..\packages\NLog.4.6.6\lib\net45\NLog.dll</HintPath>
     </Reference>
+    <Reference Include="Quartz, Version=3.6.2.0, Culture=neutral, PublicKeyToken=f6b8c98a402cc8a4, processorArchitecture=MSIL">
+      <HintPath>..\packages\Quartz.3.6.2\lib\net462\Quartz.dll</HintPath>
+    </Reference>
     <Reference Include="System" />
     <Reference Include="System.Buffers, Version=4.0.2.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
       <HintPath>..\packages\System.Buffers.4.4.0\lib\netstandard2.0\System.Buffers.dll</HintPath>
@@ -132,6 +135,7 @@
     <Reference Include="System.Runtime.CompilerServices.Unsafe, Version=4.0.6.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
       <HintPath>..\packages\System.Runtime.CompilerServices.Unsafe.4.7.1\lib\net461\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
     </Reference>
+    <Reference Include="System.Runtime.Remoting" />
     <Reference Include="System.Runtime.Serialization" />
     <Reference Include="System.ServiceModel" />
     <Reference Include="System.Threading.Tasks.Extensions, Version=4.2.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
@@ -151,9 +155,9 @@
     <Compile Include="Dto\IdTokenInfo.cs" />
     <Compile Include="Dto\ID_GetTxUserInfo.cs" />
     <Compile Include="Dto\StationFee.cs" />
-    <Compile Include="Dto\TCCWeatherDto.cs" />
+    <Compile Include="Dto\StationInfoDto.cs" />
     <Compile Include="Dto\TransactionEnergy.cs" />
-    <Compile Include="Dto\TCCStationInfoDto.cs" />
+    <Compile Include="Helper\EncodeHelper.cs" />
     <Compile Include="Message\OCPP16MessageHandler.cs" />
     <Compile Include="Message\OCPP20MessageHandler.cs" />
     <Compile Include="Message\SecurityProfileHandler.cs" />
@@ -240,6 +244,7 @@
       <Install>false</Install>
     </BootstrapperPackage>
   </ItemGroup>
+  <ItemGroup />
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <PropertyGroup>
     <PreBuildEvent>GitVersion.exe $(ProjectDir) /updateassemblyinfo</PreBuildEvent>

+ 51 - 11
EVCB_OCPP.WSServer/GlobalConfig.cs

@@ -10,12 +10,17 @@ namespace EVCB_OCPP.WSServer
         public static List<string> ConfigKeys = new List<string>()
         {
             "WSPort",
-            "WSSPort",
+            "WSSPort_1",
+            "WSSPort_2",
             "OCPP20_WSUrl",
-            "OCPP20_WSSUrl"
+            "OCPP20_WSSUrl",
+            "SecurityProfileLevel",
+            "SecurityPassword"
         };
 
-        public static  string UTC_DATETIMEFORMAT = "yyyy-MM-dd'T'HH':'mm':'ss'Z'";
+        public static List<string> DenyModelNames = new List<string>();
+
+        public static string UTC_DATETIMEFORMAT = "yyyy-MM-dd'T'HH':'mm':'ss'Z'";
 
         public static string TCC_API_URL = string.Empty;
 
@@ -25,6 +30,10 @@ namespace EVCB_OCPP.WSServer
 
         public static string OCPP20_WSSUrl = string.Empty;
 
+        public static int SecurityProfileLevel = 0;
+
+        public static string SecurityPassword = string.Empty;
+
         public static JsonSerializerSettings JSONSERIALIZER_FORMAT = new JsonSerializerSettings()
         {
             NullValueHandling = NullValueHandling.Ignore,
@@ -46,9 +55,14 @@ namespace EVCB_OCPP.WSServer
 
 
         /// <summary>
-        ///WSS Port
+        ///WSS Port 1
         /// </summary>
-        private static int WSS_Port = 2013;
+        private static int WSS_Port_1 = 2013;
+
+        /// <summary>
+        ///WSS Port 2
+        /// </summary>
+        private static int WSS_Port_2 = 2014;
 
         /// <summary>
         /// Load setting from app.config 
@@ -72,11 +86,18 @@ namespace EVCB_OCPP.WSServer
                                 WS_Port = Convert.ToInt32(value);
                             }
                             break;
-                        case "WSSPort":
+                        case "WSSPort_1":
                             {
-                                var value = ConfigurationManager.AppSettings[key];
+                                var value = ConfigurationManager.AppSettings[key].Split(',')[0];
 
-                                WSS_Port = Convert.ToInt32(value);
+                                WSS_Port_1 = Convert.ToInt32(value);
+                            }
+                            break;
+                        case "WSSPort_2":
+                            {
+                                var value = ConfigurationManager.AppSettings[key].Split(',')[1];
+
+                                WSS_Port_2 = Convert.ToInt32(value);
                             }
                             break;
                         case "OCPP20_WSUrl":// convert to int type                       
@@ -93,6 +114,20 @@ namespace EVCB_OCPP.WSServer
                                 OCPP20_WSSUrl = value;
                             }
                             break;
+                        case "SecurityProfileLevel":
+                            {
+                                var value = ConfigurationManager.AppSettings[key];
+
+                                SecurityProfileLevel = Convert.ToInt32(value);
+                            }
+                            break;
+                        case "SecurityPassword":                 
+                            {
+                                var value = ConfigurationManager.AppSettings[key];
+
+                                SecurityPassword = value;
+                            }
+                            break;
                         default://convert to string type                             
                             break;
 
@@ -118,9 +153,14 @@ namespace EVCB_OCPP.WSServer
         }
 
 
-        public static int GetWSS_Port()
+        public static int GetWSS_Port_1()
+        {
+            return WSS_Port_1;
+        }
+
+        public static int GetWSS_Port_2()
         {
-            return WSS_Port;
+            return WSS_Port_2;
         }
 
         public static int GetHEARTBEAT_INTERVAL()
@@ -129,7 +169,7 @@ namespace EVCB_OCPP.WSServer
         }
 
         public static readonly int DB_DefaultConnectionTimeout = 60;
-   
+
         /// <summary>
         /// 預設 Null的 DateTime 
         /// </summary>

+ 33 - 0
EVCB_OCPP.WSServer/Helper/EncodeHelper.cs

@@ -0,0 +1,33 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace EVCB_OCPP.WSServer.Helper
+{
+    internal static class EncodeHelper
+    {
+        /// <summary>
+        /// Base 64 轉碼
+        /// </summary>
+        /// <param name="plainText"></param>
+        /// <returns></returns>
+        internal static string EncodeBase64(string plainText)
+        {
+            var plainTextBytes = System.Text.Encoding.UTF8.GetBytes(plainText);
+            return System.Convert.ToBase64String(plainTextBytes);
+        }
+
+        /// <summary>
+        /// Base 64 解碼
+        /// </summary>
+        /// <param name="base64EncodedData"></param>
+        /// <returns></returns>
+        internal static string DecodeBase64(string base64EncodedData)
+        {
+            var base64EncodedBytes = System.Convert.FromBase64String(base64EncodedData);
+            return System.Text.Encoding.UTF8.GetString(base64EncodedBytes);
+        }
+    }
+}

+ 126 - 118
EVCB_OCPP.WSServer/Message/CoreProfileHandler.cs

@@ -166,6 +166,7 @@ namespace EVCB_OCPP.WSServer.Message
                         break;
                     case Actions.BootNotification:
                         {
+                            Debug.WriteLine(DateTime.UtcNow);
                             if (session.CustomerId == Guid.Empty)
                             {
                                 result.Message = new BootNotificationConfirmation() { currentTime = DateTime.UtcNow, interval = 5, status = RegistrationStatus.Pending };
@@ -192,16 +193,23 @@ namespace EVCB_OCPP.WSServer.Message
 
 
 
-                                    //    var configVaule = db.MachineConfiguration.Where(x => x.ChargeBoxId == session.ChargeBoxId && x.ConfigureName == StandardConfiguration.HeartbeatInterval)
-                                    //        .Select(x => x.ConfigureSetting).FirstOrDefault();
+                                    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);
-                                    //    }
+                                    if (configVaule != null)
+                                    {
+                                        int.TryParse(configVaule, out heartbeat_interval);
                                     }
-                                    var confirm = new BootNotificationConfirmation() { currentTime = DateTime.UtcNow, interval = heartbeat_interval, status = Packet.Messages.SubTypes.RegistrationStatus.Accepted };                            
-                                result.Message = confirm;
+                                }
+                                if (session.IsPending == true)
+                                {
+                                    session.IsPending = false;
+                                }
+                                if (session.IsPending == null)
+                                {
+                                    session.IsPending = true;
+                                }
+
                             }
 
                             result.Success = true;
@@ -495,6 +503,8 @@ namespace EVCB_OCPP.WSServer.Message
 
                             using (var db = new MainDBContext())
                             {
+                                db.Database.Log = Console.Write;
+
                                 var _CustomerId = db.Machine.Where(x => x.ChargeBoxId == session.ChargeBoxId).Include(x => x.Customer).
                                      Select(x => x.CustomerId).FirstOrDefault();
 
@@ -572,129 +582,130 @@ namespace EVCB_OCPP.WSServer.Message
                             {
                                 _idTagInfo = new IdTagInfo() { expiryDate = DateTime.UtcNow.AddDays(1), status = AuthorizationStatus.Accepted };
                             }
-
-                            using (var db = new MainDBContext())
+                            try
                             {
-                                var transaction = db.TransactionRecord.Where(x => x.Id == _request.transactionId
-                                 && x.ChargeBoxId == session.ChargeBoxId).FirstOrDefault();
-
-
-
-                                //遠傳太久以前的停止充電 直接拒絕 避免電樁持續重送~~~~~~~
-                                if (_request.timestamp < new DateTime(2021, 11, 1))
+                                using (var db = new MainDBContext())
                                 {
-                                    var confirm = new StopTransactionConfirmation()
-                                    {
-                                        idTagInfo = new IdTagInfo()
-                                        {
-                                            status = AuthorizationStatus.Invalid
-                                        }
+                                    var transaction = db.TransactionRecord.Where(x => x.Id == _request.transactionId
+                                     && x.ChargeBoxId == session.ChargeBoxId).FirstOrDefault();
 
-                                    };
 
-                                    result.Message = confirm;
-                                    result.Success = true;
-                                    return result;
-                                }
 
-
-                                if (transaction != null)
-                                {
-                                    var confirm = new StopTransactionConfirmation()
+                                    //遠傳太久以前的停止充電 直接拒絕 避免電樁持續重送~~~~~~~
+                                    if (_request.timestamp < new DateTime(2021, 11, 1))
                                     {
-                                        idTagInfo = _idTagInfo
+                                        var confirm = new StopTransactionConfirmation()
+                                        {
+                                            idTagInfo = new IdTagInfo()
+                                            {
+                                                status = AuthorizationStatus.Invalid
+                                            }
 
-                                    };
+                                        };
 
-                                    //Avoid rewrite transaction data
-                                    if (transaction.StopTime != GlobalConfig.DefaultNullTime)
-                                    {
                                         result.Message = confirm;
                                         result.Success = true;
                                         return result;
                                     }
 
-                                    _ConnectorId = transaction.ConnectorId;
-                                    transaction.MeterStop = _request.meterStop;
-                                    transaction.StopTime = _request.timestamp.ToUniversalTime();
-                                    transaction.StopReasonId = _request.reason.HasValue ? (int)_request.reason.Value : 0;
-                                    transaction.StopReason = _request.reason.HasValue ? _request.reason.Value.ToString() : Reason.Local.ToString();
-                                    transaction.StopIdTag = _request.idTag;
-                                    transaction.Receipt = string.Empty;
-                                    transaction.Cost = session.IsBilling ? -1 : 0;
 
-                                    if (_request.transactionData != null && _request.transactionData.Count > 0)
+                                    if (transaction != null)
                                     {
-                                        _request.transactionData[0].sampledValue.Add(new SampledValue()
+                                        var confirm = new StopTransactionConfirmation()
                                         {
-                                            context = ReadingContext.Transaction_End,
-                                            format = ValueFormat.Raw,
-                                            location = Location.Outlet,
-                                            phase = _request.transactionData[0].sampledValue.Where(x => x.context.HasValue).Select(x => x.phase).FirstOrDefault(),
-                                            unit = UnitOfMeasure.Wh,
-                                            measurand = Measurand.TotalEnergy,
-                                            value = decimal.Subtract(transaction.MeterStop, transaction.MeterStart).ToString()
-                                        });
-                                    }
+                                            idTagInfo = _idTagInfo
 
+                                        };
 
-                                    await db.SaveChangesAsync();
+                                        //Avoid rewrite transaction data
+                                        if (transaction.StopTime != GlobalConfig.DefaultNullTime)
+                                        {
+                                            result.Message = confirm;
+                                            result.Success = true;
+                                            return result;
+                                        }
 
+                                        _ConnectorId = transaction.ConnectorId;
+                                        transaction.MeterStop = _request.meterStop;
+                                        transaction.StopTime = _request.timestamp.ToUniversalTime();
+                                        transaction.StopReasonId = _request.reason.HasValue ? (int)_request.reason.Value : 0;
+                                        transaction.StopReason = _request.reason.HasValue ? _request.reason.Value.ToString() : Reason.Local.ToString();
+                                        transaction.StopIdTag = _request.idTag;
+                                        transaction.Receipt = string.Empty;
+                                        transaction.Cost = session.IsBilling ? -1 : 0;
 
-                                    if (session.IsBilling)
-                                    {
-                                        db.ServerMessage.Add(new ServerMessage()
+                                        if (_request.transactionData != null && _request.transactionData.Count > 0)
                                         {
-                                            ChargeBoxId = session.ChargeBoxId,
-                                            CreatedBy = "Server",
-                                            CreatedOn = DateTime.UtcNow,
-                                            OutAction = Actions.DataTransfer.ToString(),
-                                            OutRequest = JsonConvert.SerializeObject(
-                                                       new DataTransferRequest()
-                                                       {
-                                                           messageId = "ID_TxEnergy",
-                                                           vendorId = "Phihong Technology",
-                                                           data = JsonConvert.SerializeObject(new { txId = _request.transactionId, ConnectorId = transaction.ConnectorId })
-                                                       },
-                                                       new JsonSerializerSettings() { NullValueHandling = NullValueHandling.Ignore, Formatting = Formatting.None }),
-                                            SerialNo = Guid.NewGuid().ToString(),
-                                            InMessage = string.Empty
+                                            _request.transactionData[0].sampledValue.Add(new SampledValue()
+                                            {
+                                                context = ReadingContext.Transaction_End,
+                                                format = ValueFormat.Raw,
+                                                location = Location.Outlet,
+                                                phase = _request.transactionData[0].sampledValue.Where(x => x.context.HasValue).Select(x => x.phase).FirstOrDefault(),
+                                                unit = UnitOfMeasure.Wh,
+                                                measurand = Measurand.TotalEnergy,
+                                                value = decimal.Subtract(transaction.MeterStop, transaction.MeterStart).ToString()
+                                            });
+                                        }
 
-                                        });
 
-                                        db.SaveChanges();
-                                    }
+                                        await db.SaveChangesAsync();
 
-                                    result.Message = confirm;
-                                    result.Success = true;
-                                }
-                                else
-                                {
 
-                                    result.Exception = new Exception("Can't find transactionId " + _request.transactionId);
+                                        if (session.IsBilling)
+                                        {
+                                            db.ServerMessage.Add(new ServerMessage()
+                                            {
+                                                ChargeBoxId = session.ChargeBoxId,
+                                                CreatedBy = "Server",
+                                                CreatedOn = DateTime.UtcNow,
+                                                OutAction = Actions.DataTransfer.ToString(),
+                                                OutRequest = JsonConvert.SerializeObject(
+                                                           new DataTransferRequest()
+                                                           {
+                                                               messageId = "ID_TxEnergy",
+                                                               vendorId = "Phihong Technology",
+                                                               data = JsonConvert.SerializeObject(new { txId = _request.transactionId, ConnectorId = transaction.ConnectorId })
+                                                           },
+                                                           new JsonSerializerSettings() { NullValueHandling = NullValueHandling.Ignore, Formatting = Formatting.None }),
+                                                SerialNo = Guid.NewGuid().ToString(),
+                                                InMessage = string.Empty
+
+                                            });
+
+                                            db.SaveChanges();
+                                        }
+
+                                        result.Message = confirm;
+                                        result.Success = true;
+                                    }
+                                    else
+                                    {
+
+                                        result.Exception = new Exception("Can't find transactionId " + _request.transactionId);
 
+                                    }
                                 }
-                            }
 
-                            #region Save MeterValue
+                                #region Save MeterValue
 
-                            if (_request.transactionData != null)
-                            {
-                                if (_request.transactionData.Count > 0)
+                                if (_request.transactionData != null)
                                 {
-                                    using (var _meterDb = new MeterValueDBContext())
+                                    if (_request.transactionData.Count > 0)
                                     {
-                                        foreach (var item in _request.transactionData)
+                                        using (var _meterDb = new MeterValueDBContext())
                                         {
-                                            foreach (var sampleVaule in item.sampledValue)
+                                            foreach (var item in _request.transactionData)
                                             {
-                                                decimal value = Convert.ToDecimal(sampleVaule.value);
+                                                foreach (var sampleVaule in item.sampledValue)
+                                                {
+                                                    decimal value = Convert.ToDecimal(sampleVaule.value);
 
 
-                                                string sp = "[dbo].[uspInsertMeterValueRecord] @ChargeBoxId," +
-                             "@ConnectorId,@Value,@CreatedOn,@ContextId,@FormatId,@MeasurandId,@PhaseId,@LocationId,@UnitId,@TransactionId";
+                                                    string sp = "[dbo].[uspInsertMeterValueRecord] @ChargeBoxId," +
+                                 "@ConnectorId,@Value,@CreatedOn,@ContextId,@FormatId,@MeasurandId,@PhaseId,@LocationId,@UnitId,@TransactionId";
 
-                                                List<SqlParameter> parameter = new List<SqlParameter>
+                                                    List<SqlParameter> parameter = new List<SqlParameter>
                                         {
                                               new SqlParameter("ChargeBoxId",session.ChargeBoxId),
                                               new SqlParameter("ConnectorId",  (byte)_ConnectorId),
@@ -710,17 +721,24 @@ namespace EVCB_OCPP.WSServer.Message
                                           };
 
 
-                                                _meterDb.Database.ExecuteSqlCommand(sp, parameter.ToArray());
+                                                    _meterDb.Database.ExecuteSqlCommand(sp, parameter.ToArray());
+                                                }
                                             }
                                         }
-                                    }
 
 
+                                    }
                                 }
-                            }
-
-                            #endregion
 
+                                #endregion
+                            }
+                            catch (Exception ex)
+                            {
+                                result.Exception = new Exception("TransactionId " + _request.transactionId + " " + ex.Message);
+                                result.CallErrorMsg = "Reject Response Message";
+                                result.Success = false;
+                                // return result;
+                            }
                         }
                         break;
                     case Actions.Authorize:
@@ -1001,25 +1019,14 @@ namespace EVCB_OCPP.WSServer.Message
 
                                             }
 
-                                            if (session.CustomerId == new Guid("009E603C-79CD-4620-A2B8-D9349C0E8AD8"))
-                                            {
-                                                chargingCost = confirmbill.Count > 0 ? confirmbill.Sum(x => x.Total) : chargingCost;
-                                                chargingCost = chargedEnergy == 0 ? 0 : (chargingCost + parkingCost < 1 ? 1 : chargingCost);  //台泥最低一元
-                                                receipt += string.Format("|Total Energy Fee : ${0}", chargingCost);
+                                            chargingCost = confirmbill.Count > 0 ? confirmbill.Sum(x => x.Total) : chargingCost;
+                                            receipt += string.Format("|Total Energy Fee : ${0}", chargingCost);
 
-                                                receipt += string.Format("|Parking Fee: | {0} - {1} @ ${2}/hr=${3}", feedto.StartTime.ToString("hh:mm tt", new CultureInfo("en-us")),
-                                                feedto.StopTime.ToString("hh:mm tt", new CultureInfo("en-us")), parkingFee, parkingCost);
-                                                tx.Cost = chargingCost + parkingCost;
-                                            }
-                                            else
-                                            {
-                                                chargingCost = confirmbill.Count > 0 ? confirmbill.Sum(x => x.Total) : chargingCost;
-                                                receipt += string.Format("|Total Energy Fee : ${0}", chargingCost);
+                                            receipt += string.Format("|Parking Fee: | {0} - {1}: | {2} @ ${3}/hr= ${4}", feedto.StartTime.ToString("hh:mm tt", new CultureInfo("en-us")),
+                                            feedto.StopTime.ToString("hh:mm tt", new CultureInfo("en-us")), (totalHours / 1 >= 1) ? string.Format("{0} hours {1} minutes", (int)totalHours / 1, ((totalHours % 1) * 60).ToString("0.0")) : string.Format("{0} minutes", ((totalHours % 1) * 60).ToString("0.0")), parkingFee, parkingCost);
+                                            receipt += string.Format("|Stop Reason: {0}", tx.StopReason);
 
-                                                receipt += string.Format("|Parking Fee: | {0} - {1} @ ${2}/hr=${3}", feedto.StartTime.ToString("hh:mm tt", new CultureInfo("en-us")),
-                                                feedto.StopTime.ToString("hh:mm tt", new CultureInfo("en-us")), parkingFee, parkingCost);
-                                                tx.Cost = chargingCost + parkingCost;
-                                            }
+                                            tx.Cost = chargingCost + parkingCost;
 
 
                                             if (customerInfo != null && customerInfo.InstantStopTxReport)
@@ -1041,7 +1048,7 @@ namespace EVCB_OCPP.WSServer.Message
                                                     Fee = tx.Fee
 
                                                 };
-
+                                                logger.Debug("completed_session " + JsonConvert.SerializeObject(request));
                                                 var response = await httpClient.Post(customerInfo.ApiUrl + "completed_session", new Dictionary<string, string>()
                                                 {
                                                     { "PartnerId",session.CustomerId.ToString()}
@@ -1049,6 +1056,7 @@ namespace EVCB_OCPP.WSServer.Message
                                                 }, request, customerInfo.ApiKey);
 
                                                 var _httpResult = JsonConvert.DeserializeObject<CPOOuterResponse>(response.Response);
+                                                logger.Debug("completed_session Response" + response.Response);
                                                 JObject jo = JObject.Parse(_httpResult.Data);
                                                 if (jo.ContainsKey("CouponPoint"))
                                                 {

+ 13 - 12
EVCB_OCPP.WSServer/Message/FirmwareManagementProfileHandler.cs

@@ -77,6 +77,10 @@ namespace EVCB_OCPP.WSServer.Message
 
                                         db.SaveChanges();
 
+                                        var clearMachine = db.Machine.Where(x => x.Id == machine.Id).FirstOrDefault();
+                                        clearMachine.FW_AssignedVersion = null;
+                                        db.SaveChanges();
+
                                     }
 
                                 }
@@ -91,18 +95,15 @@ namespace EVCB_OCPP.WSServer.Message
                                     {
                                         item.EVSE_Status = (int)_request.status;
                                         item.FinishedOn = DateTime.UtcNow;
-                                        if (string.IsNullOrEmpty(item.EVSE_Value))
-                                        {
-                                            Console.WriteLine("怎麼悾悾的");
-                                        }
-
-                                        if (!string.IsNullOrEmpty(item.EVSE_Value) && _request.status == Packet.Messages.SubTypes.FirmwareStatus.Installed)
-                                        {
-                                            int version = 0;
-                                            int.TryParse(item.EVSE_Value.Split(':').Last(), out version);
-                                            var machine = db.Machine.Where(x => x.ChargeBoxId == session.ChargeBoxId).FirstOrDefault();
-                                            machine.FW_VersionReport = version;
-                                        }
+                                       
+
+                                        //if (!string.IsNullOrEmpty(item.EVSE_Value) && _request.status == Packet.Messages.SubTypes.FirmwareStatus.Installed)
+                                        //{
+                                        //    int version = 0;
+                                        //    int.TryParse(item.EVSE_Value.Split(':').Last(), out version);
+                                        //    var machine = db.Machine.Where(x => x.ChargeBoxId == session.ChargeBoxId).FirstOrDefault();
+                                        //    machine.FW_VersionReport = version;
+                                        //}
                                     }
 
 

+ 5 - 4
EVCB_OCPP.WSServer/Message/SmartChargingProfileHandler.cs

@@ -22,6 +22,7 @@ namespace EVCB_OCPP.WSServer.Message
             {
                 var _setProfileRequest = new SetChargingProfileRequest()
                 {
+                    //   
                     connectorId = 0,
                     csChargingProfiles = new Packet.Messages.SubTypes.csChargingProfiles()
                     {
@@ -33,14 +34,14 @@ namespace EVCB_OCPP.WSServer.Message
                             chargingRateUnit = unit,
                             chargingSchedulePeriod = new List<Packet.Messages.SubTypes.ChargingSchedulePeriod>()
                                                     {
-                                                        new Packet.Messages.SubTypes.ChargingSchedulePeriod(){  startPeriod=0, limit=value*1000}
+                                                        new Packet.Messages.SubTypes.ChargingSchedulePeriod(){  startPeriod=0, limit=value }
                                                     },
-                            duration = 60,
-
+                            duration = 86400,
                         },
                         recurrencyKind = Packet.Messages.SubTypes.RecurrencyKindType.Daily,
                         stackLevel = 1,
 
+
                     }
                 };
 
@@ -51,7 +52,7 @@ namespace EVCB_OCPP.WSServer.Message
                     CreatedOn = DateTime.UtcNow,
                     OutAction = _setProfileRequest.Action.ToString(),
                     OutRequest = JsonConvert.SerializeObject(_setProfileRequest, new JsonSerializerSettings() { NullValueHandling = NullValueHandling.Ignore, Formatting = Formatting.None }),
-                    SerialNo = Guid.Empty.ToString(),
+                    SerialNo = Guid.NewGuid().ToString(),
                     InMessage = string.Empty
 
                 });

+ 1 - 1
EVCB_OCPP.WSServer/Properties/AssemblyInfo.cs

@@ -35,4 +35,4 @@ using System.Runtime.InteropServices;
 [assembly: AssemblyVersion("1.0.6.0")]
 [assembly: AssemblyFileVersion("1.0.6.0")]
 
-[assembly: AssemblyInformationalVersion("d6fe7ae")]
+[assembly: AssemblyInformationalVersion("f4abcad")]

Різницю між файлами не показано, бо вона завелика
+ 259 - 489
EVCB_OCPP.WSServer/ProtalServer.cs


+ 93 - 136
EVCB_OCPP.WSServer/Service/LoadingBalanceService.cs

@@ -6,6 +6,7 @@ using System.Configuration;
 using System.Data;
 using System.Data.SqlClient;
 using System.Linq;
+using System.Threading.Tasks;
 
 namespace EVCB_OCPP.WSServer.Service
 {
@@ -46,9 +47,9 @@ namespace EVCB_OCPP.WSServer.Service
         }
 
 
-        public bool IsNeedtoCancelSetting(int stationId, string machineId, string chargeBoxId)
+        async public Task<bool> IsNeedtoCancelSetting(int stationId, string machineId, string chargeBoxId)
         {
-            var setting = GetLoadBalance(stationId);
+            var setting = await GetLoadBalance(stationId);
             if (setting == null) return false;
 
             lock (GetLock(stationId))
@@ -56,14 +57,14 @@ namespace EVCB_OCPP.WSServer.Service
                 if (setting.LBMode > 0 && setting.LBMode < 3 && !IsStillInTransactions(chargeBoxId))
                 {
                     // renew table
-                    UpdateLoadbalanceRecord(stationId, machineId, 0, DateTime.UtcNow);
+                    //    UpdateLoadbalanceRecord(stationId, machineId, 0, DateTime.UtcNow);
                     return true;
 
                 }
 
                 if (setting.LBMode >= 3 || setting.LBMode < 1)
                 {
-                    CloseLoadbalanceRecord(stationId);
+                    //   CloseLoadbalanceRecord(stationId);
 
                 }
             }
@@ -174,65 +175,12 @@ namespace EVCB_OCPP.WSServer.Service
 
 
 
-        public Dictionary<string, decimal?> GetRerangeSettingPower(int stationId)
-        {
-            Dictionary<string, decimal?> dic = new Dictionary<string, decimal?>();
-            var setting = GetLoadBalance(stationId);
-            if (setting == null) return null;
-
-            lock (GetLock(stationId))
-            {
-                if (setting != null && setting.LBMode == 2)
-                {
-                    string machineId = string.Empty;
-                    decimal ratedPower = GetRatedPower(machineId);
-                    //找站內最早要充電的交易 下發充電Power & 填寫新給的Power
-                    using (SqlConnection conn = new SqlConnection(mainConnectionString))
-                    {
-                        var parameters = new DynamicParameters();
-                        parameters.Add("@StationId", stationId, DbType.Int32, ParameterDirection.Input);
-                        string strSql = "Select M.Id from [dbo].[LoadingBalance] LB,  [dbo].[Machine] M  where LB.StationId=@StationId and  LB.MachineId=M.Id and LB.Power < M.RatedPower and LB.FinishedOn='1991/01/01' order by LB.Id asc; ";
-                        machineId = conn.ExecuteScalar<string>(strSql, parameters);
-                    }
-
-                    if (!string.IsNullOrEmpty(machineId))
-                    {
-                        decimal estimatedPwerValue = GetFCFSPower(stationId, machineId, setting.LBCurrent);
-
-                        // renew table
-                        UpdateLoadbalanceRecord(stationId, machineId, estimatedPwerValue, null, true);
-                        // UpdateLoadbalanceRecord(stationId, machineId, estimatedPwerValue, null);
-
-                        dic.Add(machineId, estimatedPwerValue);
-                    }
-
-
-                }
-
-                if (setting != null && setting.LBMode == 1)
-                {
-                    dic = GetAveragePower(stationId, setting.LBCurrent);
-                    foreach (var kv in dic)
-                    {
-                        if (kv.Value.HasValue)
-                        {
-                            UpdateLoadbalanceRecord(stationId, kv.Key, 0, DateTime.UtcNow);
-                            UpdateLoadbalanceRecord(stationId, kv.Key, kv.Value.Value, null);
-                        }
-
-                    }
-                }
-            }
 
 
-            return dic;
-
-        }
-
-        public Dictionary<string, decimal?> GetSettingPower(int stationId, string machineId)
+        async public Task<Dictionary<string, decimal?>> GetSettingPower(int stationId)
         {
             Dictionary<string, decimal?> dic = new Dictionary<string, decimal?>();
-            var setting = GetLoadBalance(stationId);
+            var setting = await GetLoadBalance(stationId);
             if (setting == null) return null;
 
             lock (GetLock(stationId))
@@ -242,31 +190,9 @@ namespace EVCB_OCPP.WSServer.Service
                 {
                     if (setting.LBMode == 1)
                     {
-                        dic = GetAveragePower(stationId, setting.LBCurrent, machineId);
-                        foreach (var kv in dic)
-                        {
-                            if (kv.Value.HasValue)
-                            {
-                                UpdateLoadbalanceRecord(stationId, kv.Key, 0, DateTime.UtcNow);
-                                UpdateLoadbalanceRecord(stationId, kv.Key, kv.Value.Value, null);
-                            }
-
-                        }
+                        dic = GetAveragePower(stationId, setting.LBCurrent).Result;
                     }
-                    else if (setting.LBMode == 2)
-                    {
-                        dic.Add(machineId, GetFCFSPower(stationId, machineId, setting.LBCurrent));
-
-                        UpdateLoadbalanceRecord(stationId, machineId, 0, DateTime.UtcNow);
-                        UpdateLoadbalanceRecord(stationId, machineId, dic[machineId].Value, null);
 
-                    }
-                    else
-                    {
-                        // 把LB TABLE 關閉
-                        CloseLoadbalanceRecord(stationId);
-
-                    }
                 }
 
             }
@@ -275,7 +201,7 @@ namespace EVCB_OCPP.WSServer.Service
         }
 
 
-        public LoadBalanceSetting GetLoadBalance(int stationId)
+        async public Task<LoadBalanceSetting> GetLoadBalance(int stationId)
         {
             LoadBalanceSetting setting = null;
             using (SqlConnection conn = new SqlConnection(webConnectionString))
@@ -284,12 +210,13 @@ namespace EVCB_OCPP.WSServer.Service
                 parameters.Add("@StationId", stationId, DbType.Int32, ParameterDirection.Input);
 
                 string strSql = "Select LBMode,LBCurrent from [dbo].[Station] where Id=@StationId ; ";
-                setting = conn.Query<LoadBalanceSetting>(strSql, parameters).FirstOrDefault();
+                var result = await conn.QueryAsync<LoadBalanceSetting>(strSql, parameters);
+                setting = result.FirstOrDefault();
             }
             return setting;
         }
 
-        private List<string> GetIdsbyStationId(int stationId)
+        async private Task<List<string>> GetIdsbyStationId(int stationId)
         {
             List<string> machineIds = new List<string>();
             using (SqlConnection conn = new SqlConnection(webConnectionString))
@@ -297,97 +224,127 @@ namespace EVCB_OCPP.WSServer.Service
                 var parameters = new DynamicParameters();
                 parameters.Add("@StationId", stationId, DbType.Int16, ParameterDirection.Input);
                 string strSql = "Select MachineId from [dbo].[StationMachine] where StationId=@StationId; ";
-                machineIds = conn.Query<String>(strSql, parameters).ToList();
+                var result = await conn.QueryAsync<String>(strSql, parameters);
+                machineIds = result.ToList();
             }
             return machineIds;
         }
 
 
 
-        private Dictionary<string, decimal?> GetAveragePower(int stationId, int availableCapacity, string machineId = "")
+        async private Task<Dictionary<string, decimal?>> GetAveragePower(int stationId, int availableCapacity)
         {
             Dictionary<string, decimal?> dic = new Dictionary<string, decimal?>();
-            //總量 * 該樁的額定功率/該站充電中樁的總額定功率
-            List<string> _MachineIds = new List<string>();
-            int skipCount = 0;
-            int size = 200;
-            int takeCount = 0;
-            int totalRatePower = 0;
-
-            using (SqlConnection conn = new SqlConnection(mainConnectionString))
+            availableCapacity = (int)(availableCapacity * 1000 / 1.05M);
+            int keepPower = 0;
+            //讀取上一次斷線但還沒充完電的分配量
+            var offlineCPs = GetChargeBoxIdbyOfflineCharging(stationId, out keepPower);
+            //扣除Keep充電功率  =  分配充電量
+            var totalPower = availableCapacity - keepPower;
+
+            if (totalPower > 0)
             {
-                var parameters = new DynamicParameters();
-                parameters.Add("@StationId", stationId, DbType.Int32, ParameterDirection.Input);
-                string strSql = "Select MachineId from [dbo].[LoadingBalance] where StationId=@StationId and FinishedOn='1991/01/01'; ";
-                _MachineIds = conn.Query<string>(strSql, parameters).ToList();
-            }
+                //總量 * 該樁的額定功率/該站充電中樁的總額定功率
+                var onlineChargingCPs = await GetOnlineChargerwithCharging(stationId);
+                if (onlineChargingCPs.Count > 0)
+                {
+                    int singlePower = (int)Decimal.Divide(totalPower, onlineChargingCPs.Count);
+
+                    foreach (var id in onlineChargingCPs)
+                    {
+                        dic.Add(id, singlePower);
+                    }
+                }
 
-            if (!string.IsNullOrEmpty(machineId) && !_MachineIds.Contains(machineId))
-            {
-                _MachineIds.Add(machineId);
             }
 
-            while (skipCount < _MachineIds.Count())
-            {
-                takeCount = _MachineIds.Count() - skipCount > size ? size : _MachineIds.Count() - skipCount;
+            return dic;
 
-                using (SqlConnection conn = new SqlConnection(mainConnectionString))
+        }
+
+        async private Task<List<string>> GetOnlineChargerwithCharging(int stationId)
+        {
+            List<string> results = new List<string>();
+            List<string> machineIds = await GetIdsbyStationId(stationId);
+            List<string> chargeboxids = new List<string>();
+            using (SqlConnection conn = new SqlConnection(mainConnectionString))
+            {
+                string onlineChargerSql = "Select ChargeBoxId from [dbo].[Machine] where Id in @machineIds and [Online]=1; ";
+                var onlineResult = await conn.QueryAsync<string>(onlineChargerSql, new { machineIds = machineIds.ToArray() });
+                chargeboxids = onlineResult.ToList();
+                foreach (var chargeboxid in chargeboxids)
                 {
-                    string strSql = "Select Sum(RatedPower) from [dbo].[Machine] where Id in @machineIds and [Online]=1; ";
-                    totalRatePower += conn.ExecuteScalar<Int32>(strSql, new { machineIds = _MachineIds.ToArray() });
-                    skipCount += takeCount;
+                    string txSql = "SELECT TOP(1) [Id] from [dbo].[TransactionRecord] where ChargeBoxId=@ChargeBoxId and StopTime = '1991-01-01 00:00:00.000'; ";
+                    var txId = await conn.ExecuteScalarAsync<Int64>(txSql, new { ChargeBoxId = chargeboxid });
+                    if (txId > 0)
+                    {
+                        results.Add(chargeboxid);
+                    }
                 }
-            }
 
-            foreach (var id in _MachineIds)
-            {
-                int singleRatePower = (int)GetRatedPower(id);
-                var value = totalRatePower == 0 ? 0 : availableCapacity * singleRatePower / totalRatePower;
-                dic.Add(id, value);
             }
+            return results;
+        }
 
-            return dic;
+        /// <summary>
+        /// 取得斷線樁號
+        /// </summary>
+        /// <param name="stationId">站點代號</param>
+        /// <param name="ratedPowers">總額定功率</param>
+        /// <returns></returns>
+        private List<string> GetChargeBoxIdbyOfflineCharging(int stationId, out int ratedPowers)
+        {
+            List<string> machineIds = GetIdsbyStationId(stationId).Result;
+            List<string> result = new List<string>();
+            ratedPowers = 0;
+            using (SqlConnection conn = new SqlConnection(mainConnectionString))
+            {
 
+                string offlineChargerSql = "Select ChargeBoxId from [dbo].[Machine] where Id in @machineIds and [Online]=0; ";
+                result = conn.Query<string>(offlineChargerSql, new { machineIds = machineIds }).ToList();
+                foreach (var charger in result)
+                {
+                    string txSql = "SELECT TOP(1) [Id] from [dbo].[TransactionRecord] where ChargeBoxId=@ChargeBoxId and StopTime = '1991-01-01 00:00:00.000'; ";
+                    var txId = conn.ExecuteScalar<Int64>(txSql, new { ChargeBoxId = charger });
+                    if (txId > 0)
+                    {
+                        string ratedPowerSql = "Select Sum(RatedPower) from [dbo].[Machine] where ChargeBoxId=@ChargeBoxId and [Online]=0; ";
+                        ratedPowers += conn.ExecuteScalar<int>(ratedPowerSql, new { ChargeBoxId = charger });
+                    }
+                }
+            }
+            ratedPowers *= 1000;
+            return result;
         }
 
-        private decimal GetRatedPower(string machineId)
+        private decimal GetRatedPowerbyChargeBoxId(string chargeBoxId)
         {
             decimal ratedPower = 0;
             using (SqlConnection conn = new SqlConnection(mainConnectionString))
             {
                 var parameters = new DynamicParameters();
-                parameters.Add("@machineId", machineId, DbType.String, ParameterDirection.Input);
+                parameters.Add("@machineId", chargeBoxId, DbType.String, ParameterDirection.Input);
                 string strSql = "Select RatedPower from [dbo].[Machine] where Id=@machineId; ";
                 ratedPower = conn.ExecuteScalar<Int32>(strSql, parameters);
             }
             return ratedPower;
         }
 
-        private decimal GetFCFSPower(int stationId, string machineId, int availableCapacity)
+        private decimal GetRatedPowerbyId(string machineId)
         {
-
-            decimal ongoingPower = 0;
-            decimal singleRatePower = GetRatedPower(machineId);
-
-            //先找LB 裡面目前下發的Power
-            decimal? currentPower = GetCurrentSetting(machineId);
-
-            if (!currentPower.HasValue) currentPower = 0;
-
-            //總量 - 所有正在進行的Power
+            decimal ratedPower = 0;
             using (SqlConnection conn = new SqlConnection(mainConnectionString))
             {
                 var parameters = new DynamicParameters();
-                parameters.Add("@StationId", stationId, DbType.Int32, ParameterDirection.Input);
-                string strSql = "Select Sum(Power) from [dbo].[LoadingBalance] where StationId=@StationId and FinishedOn='1991/01/01'; ";
-                ongoingPower = conn.ExecuteScalar<Int32>(strSql, parameters);
+                parameters.Add("@machineId", machineId, DbType.String, ParameterDirection.Input);
+                string strSql = "Select RatedPower from [dbo].[Machine] where Id=@machineId; ";
+                ratedPower = conn.ExecuteScalar<Int32>(strSql, parameters);
             }
-
-            return availableCapacity - (ongoingPower - currentPower.Value) > singleRatePower ? singleRatePower :
-                (availableCapacity - (ongoingPower - currentPower.Value) > 0 ? availableCapacity - (ongoingPower - currentPower.Value) : 0);
+            return ratedPower;
         }
 
 
+
     }
 }
 

+ 9 - 5
EVCB_OCPP.WSServer/SuperSocket.Protocol/ClientData.cs

@@ -16,7 +16,7 @@ namespace OCPPServer.Protocol
 
         public EVCB_OCPP20.Packet.Messages.Basic.Queue queue20 = new EVCB_OCPP20.Packet.Messages.Basic.Queue();
 
-        public bool IsPending { set; get; }
+        public bool? IsPending { set; get; }
         public bool IsCheckIn { set; get; }
 
         public string ChargeBoxId { set; get; }
@@ -34,7 +34,7 @@ namespace OCPPServer.Protocol
 
         #region Billing
 
-        public Dictionary<string,string> UserPrices { set; get; }
+        public Dictionary<string, string> UserPrices { set; get; }
 
         public Dictionary<string, string> UserDisplayPrices { set; get; }
 
@@ -64,7 +64,7 @@ namespace OCPPServer.Protocol
         /// 收費方式 1: 以度計費 2:以小時計費
         /// </summary>
         public int BillingMethod { set; get; }
-       
+
 
         /// <summary>
         /// 電樁適用幣別
@@ -76,10 +76,13 @@ namespace OCPPServer.Protocol
         public string CustomerName { get; set; }
 
 
-        public string StationName { set; get; }
+        public string StationId { set; get; }
+
+
+        public bool InStock { set; get; }
+
 
 
-        public string StationLocation { set; get; }
 
         public delegate void OCPPClientDataEventHandler<ClientData, String>(ClientData clientdata, String msg);
 
@@ -87,6 +90,7 @@ namespace OCPPServer.Protocol
 
         public ClientData()
         {
+            InStock = true;
             IsAC = true;
             IsPending = false;
             IsCheckIn = false;

+ 3 - 3
EVCB_OCPP.WSServer/SuperSocket.Protocol/OCPPLog.cs

@@ -170,7 +170,7 @@ namespace OCPPServer.SubProtocol
         /// <param name="arg0">The arg0.</param>
         public void ErrorFormat(string format, object arg0)
         {
-
+            m_Log.Error(string.Format(format, arg0));
         }
 
         /// <summary>
@@ -243,7 +243,7 @@ namespace OCPPServer.SubProtocol
         /// <param name="arg0">The arg0.</param>
         public void FatalFormat(string format, object arg0)
         {
-
+            m_Log.Fatal(string.Format(format, arg0));
         }
 
         /// <summary>
@@ -253,7 +253,7 @@ namespace OCPPServer.SubProtocol
         /// <param name="args">The args.</param>
         public void FatalFormat(string format, params object[] args)
         {
-
+           
         }
 
         /// <summary>

+ 85 - 42
EVCB_OCPP.WSServer/SuperSocket.Protocol/OCPPWSServer.cs

@@ -1,5 +1,7 @@
 
 using EVCB_OCPP.Domain;
+using EVCB_OCPP.WSServer;
+using EVCB_OCPP.WSServer.Helper;
 using NLog;
 using OCPPPackage.Profiles;
 using SuperWebSocket;
@@ -65,10 +67,13 @@ namespace OCPPServer.Protocol
 
         protected override bool ValidateHandshake(ClientData session, string origin)
         {
+            int securityProfile = GlobalConfig.SecurityProfileLevel;
+            string authorizationKey = GlobalConfig.SecurityPassword;
+            bool authorizated = false;
+
             session.ISOCPP20 = session.SecWebSocketProtocol.ToLower().Contains("ocpp2.0");
 
-            int securityProfile = 0;
-            string authorizationKey = string.Empty;
+
             if (string.IsNullOrEmpty(session.Path))
             {
                 logger.Warn("===========================================");
@@ -85,40 +90,71 @@ namespace OCPPServer.Protocol
             }
 
             logger.Info(string.Format("ValidateHandshake: {0}", session.Path));
-            bool isExistedSN = false;
-            bool authorizated = false;
-          //  using (var db = new MainDBContext())
-            {
 
-                session.CustomerId = Guid.Empty;
-                session.MachineId = String.Empty;
-                isExistedSN  =true;
-
-                if (!isExistedSN)
-                {
-                    StringBuilder responseBuilder = new StringBuilder();
-
-                    responseBuilder.AppendFormatWithCrCf(@"HTTP/{0} {1} {2}", "1.1",
-                    (int)HttpStatusCode.NotFound, @"Not Found");
-                  
-                    responseBuilder.AppendWithCrCf();
-                    string sb = responseBuilder.ToString();
-                    byte[] data = Encoding.UTF8.GetBytes(sb);
-                    ((IWebSocketSession)session).SendRawData(data, 0, data.Length);
-
-                    logger.Info(sb);
-                    return false;
-                }
-
-              
-
-                if (session.ISOCPP20)
-                {
-                    // 1.6 server only support change server  function
-                    securityProfile = 0;
-                }
+            if (session.ISOCPP20)
+            {
+                // 1.6 server only support change server  function
+                securityProfile = 0;
             }
-            if (securityProfile == 3 && session.UriScheme == "ws")
+
+            switch (securityProfile)
+            {
+                case 0:
+                    {
+                        authorizated = true;
+                    }
+                    break;
+                case 1:
+                    {
+                        if(session.UriScheme == "ws")
+                        {
+                            string client_authorization = string.Empty;
+                            if (session.Items.ContainsKey("Authorization") || session.Items.ContainsKey("authorization"))
+                            {
+                                client_authorization = session.Items.ContainsKey("Authorization") ? session.Items["Authorization"].ToString().Replace("Basic ", "") : session.Items["authorization"].ToString().Replace("Basic ", "");
+                            }
+                            if (ValidateSecurity(session.ChargeBoxId, authorizationKey, client_authorization))
+                            {
+                                authorizated = true;
+                            }
+                            else
+                            {
+                                logger.Warn(string.Format(" {0} ValidateSecurity Fail client_authorization:[{1}]:", session.ChargeBoxId, client_authorization));
+                            }
+                        }
+                      
+                    }
+                    break;
+                case 2:
+                    {
+                        if (session.UriScheme == "wss")
+                        {
+                            string client_authorization = string.Empty;
+                            if (session.Items.ContainsKey("Authorization") || session.Items.ContainsKey("authorization"))
+                            {
+                                client_authorization = session.Items.ContainsKey("Authorization") ? session.Items["Authorization"].ToString().Replace("Basic ", "") : session.Items["authorization"].ToString().Replace("Basic ", "");
+                            }
+                            if (ValidateSecurity(session.ChargeBoxId, authorizationKey, client_authorization))
+                            {
+                                authorizated = true;
+                            }
+                            else
+                            {
+                                logger.Warn(string.Format(" {0} ValidateSecurity Fail client_authorization:[{1}]:", session.ChargeBoxId, client_authorization));
+                            }
+                        }
+                    }
+                    break;
+                case 3:
+                    {
+                        authorizated = false;
+                    }
+                    break;
+                default:
+                    break;
+            }       
+           
+            if(!authorizated)
             {
                 StringBuilder responseBuilder = new StringBuilder();
 
@@ -133,17 +169,24 @@ namespace OCPPServer.Protocol
                 logger.Info(sb);
                 return false;
             }
+           
+
+            return true;
+        }
+
 
-            if ((securityProfile == 1 || securityProfile == 2))
-            {
-                if (securityProfile == 2 && session.UriScheme == "ws")
-                {
-                    authorizated = false;
-                }               
 
+        private bool ValidateSecurity(string chargeBoxId, string authorizationKey, string client_authorization)
+        {
+            bool result = false;
+            if (string.IsNullOrEmpty(client_authorization)) return result;
+
+            string server_authorization = EncodeHelper.EncodeBase64(string.Format("{0}:{1}", chargeBoxId, authorizationKey));
+            if (client_authorization == server_authorization)
+            {
+                result =  true;
             }
-            
-            return true;
+            return result;
         }
     }
 }

+ 1 - 0
EVCB_OCPP.WSServer/packages.config

@@ -18,6 +18,7 @@
   <package id="NLog" version="4.6.6" targetFramework="net471" />
   <package id="NLog.Config" version="4.6.6" targetFramework="net471" />
   <package id="NLog.Schema" version="4.6.6" targetFramework="net471" />
+  <package id="Quartz" version="3.6.2" targetFramework="net471" />
   <package id="System.Buffers" version="4.4.0" targetFramework="net471" />
   <package id="System.ComponentModel.Annotations" version="4.7.0" targetFramework="net471" />
   <package id="System.Memory" version="4.5.2" targetFramework="net471" />

BIN
SuperWebSocket/bin/Debug/SuperWebSocket.dll


BIN
SuperWebSocket/bin/Debug/SuperWebSocket.pdb


Деякі файли не було показано, через те що забагато файлів було змінено