ソースを参照

1. 資料庫DLL 版本:2e4a9e8
2. 調整Console命令功能列
3. 新增CDFA功能 (Running Cost 沒有打開待確認 DC樁可使用)

Jessica Tseng 3 年 前
コミット
ae02c193b8

BIN
EVCB_OCPP.WSServer/DLL/EVCB_OCPP.Domain.dll


BIN
EVCB_OCPP.WSServer/DLL/EVCB_OCPP.Packet.dll


+ 17 - 2
EVCB_OCPP.WSServer/Message/BasicMessageHandler.cs

@@ -1,4 +1,5 @@
-using EVCB_OCPP.Packet.Messages;
+using EVCB_OCPP.Packet.Features;
+using EVCB_OCPP.Packet.Messages;
 using Newtonsoft.Json;
 using Newtonsoft.Json.Serialization;
 using NLog;
@@ -110,7 +111,21 @@ namespace EVCB_OCPP.WSServer.Message
             }
             else
             {
-                logger.Error(string.Format("confirmation is null  or InVaild in GenerateRequest Method"), "Warning");
+                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;
         }

+ 146 - 9
EVCB_OCPP.WSServer/Message/CoreProfileHandler.cs

@@ -56,6 +56,7 @@ namespace EVCB_OCPP.WSServer.Message
                             {
                                 var _machine = db.Machine.Where(x => x.ChargeBoxId == session.ChargeBoxId).FirstOrDefault();
                                 _machine.ChargeBoxSerialNumber = string.IsNullOrEmpty(_request.chargeBoxSerialNumber) ? string.Empty : _request.chargeBoxSerialNumber;
+                                _machine.ChargePointSerialNumber = string.IsNullOrEmpty(_request.chargePointSerialNumber) ? string.Empty : _request.chargePointSerialNumber;
                                 _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;
@@ -66,6 +67,8 @@ namespace EVCB_OCPP.WSServer.Message
 
                                 db.SaveChanges();
 
+                                logger.Error(string.Format("{0} ChargeBoxSerialNumber:{1} ", session.ChargeBoxId, _request.chargePointSerialNumber));
+
                                 var configVaule = db.MachineConfiguration.Where(x => x.ChargeBoxId == session.ChargeBoxId && x.ConfigureName == StandardConfiguration.HeartbeatInterval)
                                     .Select(x => x.ConfigureSetting).FirstOrDefault();
 
@@ -207,6 +210,10 @@ namespace EVCB_OCPP.WSServer.Message
                     case Actions.MeterValues:
                         {
                             MeterValuesRequest _request = request as MeterValuesRequest;
+                            string feeText = session.FeeDescription.Split(';')[1].Replace(" Current Rate: $", "").Split(' ')[0];
+
+                            decimal fee = decimal.Parse(feeText);
+                            decimal energy_kwh = 0;
 
                             if (_request.meterValue.Count > 0)
                             {
@@ -219,6 +226,11 @@ namespace EVCB_OCPP.WSServer.Message
 
                                             decimal value = Convert.ToDecimal(sampleVaule.value);
 
+                                            if (sampleVaule.context == ReadingContext.Sample_Periodic && sampleVaule.measurand == Measurand.Energy_Active_Import_Interval)
+                                            {
+                                                energy_kwh = sampleVaule.unit == UnitOfMeasure.Wh ? Decimal.Divide(value, 1000) : value;
+                                            }
+
                                             string sp = "[dbo].[uspInsertMeterValueRecord] @ChargeBoxId," +
                          "@ConnectorId,@Value,@CreatedOn,@ContextId,@FormatId,@MeasurandId,@PhaseId,@LocationId,@UnitId,@TransactionId";
 
@@ -249,6 +261,52 @@ namespace EVCB_OCPP.WSServer.Message
                                 }
                             }
 
+                            if (energy_kwh > 0)
+                            {
+                                try
+                                {
+                                    // ************等Alston 可以使用在打開這個功能 ~ 電樁畫面上目前不會顯示
+                                    //using (var db = new MainDBContext())
+                                    //{
+                                    //    db.ServerMessage.Add(new ServerMessage()
+                                    //    {
+                                    //        ChargeBoxId = session.ChargeBoxId,
+                                    //        CreatedBy = "Server",
+                                    //        CreatedOn = DateTime.Now,
+                                    //        OutAction = Actions.DataTransfer.ToString(),
+                                    //        OutRequest = JsonConvert.SerializeObject(
+                                    //                new DataTransferRequest()
+                                    //                {
+                                    //                    messageId = "RunningCost",
+                                    //                    vendorId = "Phihong Technology",
+                                    //                    data = JsonConvert.SerializeObject(new
+                                    //                    {
+                                    //                        txId = _request.transactionId,
+                                    //                        description = string.Format("Connection Fee: $0.00 {0}; Session Fee: ${1} {0}; Occupancy Fee: " +
+                                    //                        "$0.00 {0}; Total Cost: ${1} {0}; Account Balance: $155.05 {0}", session.Currency,
+                                    //                      Decimal.Multiply(energy_kwh, fee))
+                                    //                    })
+
+                                    //                },
+                                    //                new JsonSerializerSettings() { NullValueHandling = NullValueHandling.Ignore, Formatting = Formatting.None }),
+                                    //        SerialNo = Guid.NewGuid().ToString(),
+                                    //        InMessage = string.Empty
+
+                                    //    }); ;
+
+                                    //    db.SaveChanges();
+
+                                    //}
+                                }
+                                catch (Exception ex)
+                                {
+
+                                    Console.WriteLine(string.Format("{0} :{1}", session.ChargeBoxId + " RunningCost", ex.Message));
+
+                                }
+
+                            }
+
                             var confirm = new MeterValuesConfirmation() { };
                             result.Message = confirm;
                             result.Success = true;
@@ -263,9 +321,12 @@ namespace EVCB_OCPP.WSServer.Message
                             int _transactionId = -1;
 
                             var businessService = BusinessServiceFactory.CreateBusinessService(session.CustomerId.ToString());
-                            //var _idTagInfo = new IdTagInfo() { status = AuthorizationStatus.Accepted };                        
                             var _idTagInfo = _request.idTag == "Backend" ? new IdTagInfo() { expiryDate = DateTime.UtcNow.AddDays(1), status = AuthorizationStatus.Accepted } : await businessService.Authorize(session.ChargeBoxId, _request.idTag);
-
+                            //特例****飛宏客戶旗下的電樁,若遇到Portal沒回應的狀況 ~允許充電
+                            if (session.CustomerId.ToString().ToUpper() == "8456AED9-6DD9-4BF3-A94C-9F5DCB9506F7" && _idTagInfo.status == AuthorizationStatus.ConcurrentTx)
+                            {
+                                _idTagInfo = new IdTagInfo() { expiryDate = DateTime.UtcNow.AddDays(1), status = AuthorizationStatus.Accepted };
+                            }
 
                             using (var db = new MainDBContext())
                             {
@@ -289,7 +350,7 @@ namespace EVCB_OCPP.WSServer.Message
                                         CustomerId = _CustomerId,
                                         StartTime = _request.timestamp,
                                         ReservationId = _request.reservationId.HasValue ? _request.reservationId.Value : 0,
-
+                                        Fee = session.FeeDescription
 
                                     };
 
@@ -298,14 +359,14 @@ namespace EVCB_OCPP.WSServer.Message
                                     db.SaveChanges();
 
                                     _transactionId = _newTransaction.Id;
-                                    Console.WriteLine("***************************************************** ");
-                                    Console.WriteLine(string.Format("{0} :TransactionId {1} ", session.ChargeBoxId, _newTransaction.Id));
-                                    Console.WriteLine("***************************************************** ");
+                                    logger.Info("***************************************************** ");
+                                    logger.Info(string.Format("{0} :TransactionId {1} ", session.ChargeBoxId, _newTransaction.Id));
+                                    logger.Info("***************************************************** ");
                                 }
                                 else
                                 {
                                     _transactionId = _existedTx.Id;
-                                    Console.WriteLine("Duplication ***************************************************** " + _existedTx.Id);
+                                    logger.Error("Duplication ***************************************************** " + _existedTx.Id);
                                 }
                             }
 
@@ -329,8 +390,13 @@ namespace EVCB_OCPP.WSServer.Message
 
                             var businessService = BusinessServiceFactory.CreateBusinessService(session.CustomerId.ToString());
 
+                            //特例****飛宏客戶旗下的電樁,若遇到Portal沒回應的狀況 ~允許充電
+                            var _idTagInfo = string.IsNullOrEmpty(_request.idTag) ? null : (_request.idTag == "Backend" ? new IdTagInfo() { expiryDate = DateTime.UtcNow.AddDays(1), status = AuthorizationStatus.Accepted } : await businessService.Authorize(session.ChargeBoxId, _request.idTag));
 
-                            var _idTagInfo = string.IsNullOrEmpty(_request.idTag)? null:(_request.idTag == "Backend" ? new IdTagInfo() { expiryDate = DateTime.UtcNow.AddDays(1), status = AuthorizationStatus.Accepted } : await businessService.Authorize(session.ChargeBoxId, _request.idTag));
+                            if (session.CustomerId.ToString().ToUpper() == "8456AED9-6DD9-4BF3-A94C-9F5DCB9506F7" && _idTagInfo != null && _idTagInfo.status == AuthorizationStatus.ConcurrentTx)
+                            {
+                                _idTagInfo = new IdTagInfo() { expiryDate = DateTime.UtcNow.AddDays(1), status = AuthorizationStatus.Accepted };
+                            }
 
 
 
@@ -341,11 +407,44 @@ namespace EVCB_OCPP.WSServer.Message
 
                                 if (transaction != null)
                                 {
+                                    decimal energy_kwh = decimal.Subtract(_request.meterStop, transaction.MeterStart);
+                                   
+                                    energy_kwh = decimal.Divide(energy_kwh, 1000);
+                                    string feeText = transaction.Fee.Split(';')[1].Replace(" Current Rate: $", "").Split(' ')[0];
+                                    decimal fee = decimal.Parse(feeText);
+                                    decimal cost = Decimal.Multiply(energy_kwh, (decimal)fee);
+                                    if (session.Currency == "USD" || session.Currency == "EUR")
+                                    {
+                                        //0.4867
+                                        if ((int)(cost * 100) < cost * 100)
+                                        {
+                                            cost = Decimal.Add(cost, (decimal)0.01);//0.4967
+
+                                        }
+
+                                        cost = Decimal.Parse(cost.ToString("0.00"));
+                                    }
+                                    else
+                                    {
+                                        if ((int)(cost) < cost )
+                                        {
+                                            cost = Decimal.Add(cost, (decimal)1);
+                                        }
+
+                                        cost = Decimal.Parse(cost.ToString("0"));
+                                    }
+                                    string receipt = string.Format("Connection Fee: $0.00 {0}; Session Fee: ${1} {0}; Occupancy Fee: " +
+                                                                    "$0.00 {0}; Total Cost: ${1} {0}; Account Balance: $4555 {0}", session.Currency,
+                                                                     cost);
+
+
                                     _ConnectorId = transaction.ConnectorId;
                                     transaction.MeterStop = _request.meterStop;
                                     transaction.StopTime = _request.timestamp;
                                     transaction.StopReasonId = _request.reason.HasValue ? (int)_request.reason.Value : 0;
                                     transaction.StopIdTag = _request.idTag;
+                                    transaction.Receipt = receipt;
+                                    transaction.Cost = cost;
 
                                     if (_TransactionDatas.Count > 0)
                                     {
@@ -358,6 +457,39 @@ namespace EVCB_OCPP.WSServer.Message
                                         idTagInfo = _idTagInfo
 
                                     };
+
+
+
+                                    if (energy_kwh > 0)
+                                    {
+                                        db.ServerMessage.Add(new ServerMessage()
+                                        {
+                                            ChargeBoxId = session.ChargeBoxId,
+                                            CreatedBy = "Server",
+                                            CreatedOn = DateTime.Now,
+                                            OutAction = Actions.DataTransfer.ToString(),
+                                            OutRequest = JsonConvert.SerializeObject(
+                                                       new DataTransferRequest()
+                                                       {
+                                                           messageId = "FinalCost",
+                                                           vendorId = "Phihong Technology",
+                                                           data = JsonConvert.SerializeObject(new
+                                                           {
+                                                               txId = _request.transactionId,
+                                                               description = string.Format("Connection Fee: $0.00 {0}; Session Fee: ${1} {0}; Occupancy Fee: " +
+                                                            "$0.00 {0}; Total Cost: ${1} {0}; Account Balance: $4555 {0}", session.Currency,
+                                                            energy_kwh, Decimal.Multiply(energy_kwh, (decimal)fee))
+                                                           })
+
+                                                       },
+                                                       new JsonSerializerSettings() { NullValueHandling = NullValueHandling.Ignore, Formatting = Formatting.None }),
+                                            SerialNo = Guid.NewGuid().ToString(),
+                                            InMessage = string.Empty
+
+                                        }); ;
+
+                                        db.SaveChanges();
+                                    }
                                     result.Message = confirm;
                                     result.Success = true;
                                 }
@@ -415,12 +547,17 @@ namespace EVCB_OCPP.WSServer.Message
                         {
                             AuthorizeRequest _request = request as AuthorizeRequest;
 
-
+                            //特例****飛宏客戶旗下的電樁,若遇到Portal沒回應的狀況 ~允許充電
                             var businessService = BusinessServiceFactory.CreateBusinessService(session.CustomerId.ToString());
                             var confirm = new AuthorizeConfirmation()
                             {
                                 idTagInfo = _request.idTag == "Backend" ? new IdTagInfo() { expiryDate = DateTime.UtcNow.AddDays(1), status = AuthorizationStatus.Accepted } : await businessService.Authorize(session.ChargeBoxId, _request.idTag)
                             };
+
+                            if (session.CustomerId.ToString().ToUpper() == "8456AED9-6DD9-4BF3-A94C-9F5DCB9506F7" && confirm.idTagInfo.status == AuthorizationStatus.ConcurrentTx)
+                            {
+                                confirm.idTagInfo = new IdTagInfo() { expiryDate = DateTime.UtcNow.AddDays(1), status = AuthorizationStatus.Accepted };
+                            }
                             result.Message = confirm;
                             result.Success = true;
                         }

+ 18 - 2
EVCB_OCPP.WSServer/Program.cs

@@ -1,14 +1,30 @@
 using Newtonsoft.Json;
 using System;
+using System.Net.Http;
+using System.Threading.Tasks;
 
 namespace EVCB_OCPP.WSServer
 {
+   
     class Program
     {
         static void Main(string[] args)
         {
-
-
+            Console.WriteLine("====================================================================================================");
+            Console.WriteLine("====================================================================================================");
+            Console.WriteLine("==                                                                                                ==");
+            Console.WriteLine("==       ------------               -----------      -------------         -------------          ==");
+            Console.WriteLine("==    ---            ---       ----                  ----------------      ----------------       ==");
+            Console.WriteLine("==    ---            ---     ----                    ----            ---   ----            ---    ==");
+            Console.WriteLine("==    ---            ---    ----                     ----            ---   ----            ---    ==");
+            Console.WriteLine("==    ---            ---    ----                     ---- -------------    ---- -------------     ==");
+            Console.WriteLine("==    ---            ---    ----                     ---- -----------      ---- -----------       ==");
+            Console.WriteLine("==    ---            ---      ----                   ----                  ----                   ==");
+            Console.WriteLine("==    ---            ---        ----                 ----                  ----                   ==");
+            Console.WriteLine("==       -----------                -----------      ----                  ----                   ==");
+            Console.WriteLine("==                                                                                                ==");
+            Console.WriteLine("====================================================================================================");
+            Console.WriteLine("====================================================================================================");
             ProtalServer s = new ProtalServer();
             Console.WriteLine("Starting Server...");
             s.Start();

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

@@ -35,4 +35,4 @@ using System.Runtime.InteropServices;
 [assembly: AssemblyVersion("0.1.0.0")]
 [assembly: AssemblyFileVersion("0.1.0.0")]
 
-[assembly: AssemblyInformationalVersion("92414dc")]
+[assembly: AssemblyInformationalVersion("087b534")]

+ 90 - 39
EVCB_OCPP.WSServer/ProtalServer.cs

@@ -1,4 +1,5 @@
-using EVCB_OCPP.Domain;
+using Dapper;
+using EVCB_OCPP.Domain;
 using EVCB_OCPP.Domain.Models.Database;
 using EVCB_OCPP.Packet.Features;
 using EVCB_OCPP.Packet.Messages;
@@ -17,6 +18,7 @@ using SuperSocket.SocketBase.Config;
 using System;
 using System.Collections.Generic;
 using System.Configuration;
+using System.Data;
 using System.Data.Entity;
 using System.Data.SqlClient;
 using System.Diagnostics;
@@ -147,18 +149,18 @@ namespace EVCB_OCPP.WSServer
                 switch (input.ToLower())
                 {
                     case "stop":
-                        logger.Info("Command stop");
+                        Console.WriteLine("Command stop");
                         Stop();
                         break;
 
                     case "gc":
-                        logger.Info("Command GC");
+                        Console.WriteLine("Command GC");
                         GC.Collect();
                         break;
 
                     case "lc":
                         {
-                            logger.Info("Command List Clients");
+                            Console.WriteLine("Command List Clients");
                             Dictionary<string, ClientData> _copyClientDic = null;
                             lock (_lockClientDic)
                             {
@@ -169,7 +171,7 @@ namespace EVCB_OCPP.WSServer
                             int i = 1;
                             foreach (var c in list)
                             {
-                                logger.Info(i + ":" + c.ChargeBoxId + " " + c.SessionID);
+                                Console.WriteLine(i + ":" + c.ChargeBoxId + " " + c.SessionID);
                                 i++;
                             }
 
@@ -177,58 +179,60 @@ namespace EVCB_OCPP.WSServer
                         break;
                     case "lcn":
                         {
-                            logger.Info("Command List Customer Name");
+                            Console.WriteLine("Command List Customer Name");
                             Dictionary<string, ClientData> _copyClientDic = null;
                             lock (_lockClientDic)
                             {
                                 _copyClientDic = new Dictionary<string, ClientData>(clientDic);
 
                             }
-                            var lcn = clientDic.Select(c => c.Value.CustomerId).Distinct().ToList();
+                            var lcn = clientDic.Select(c => c.Value.CustomerName).Distinct().ToList();
                             int iLcn = 1;
                             foreach (var c in lcn)
                             {
-                                logger.Info(iLcn + ":" + c + ":" + clientDic.Where(z => z.Value.CustomerId == c).Count().ToString());
+                                Console.WriteLine(iLcn + ":" + c + ":" + clientDic.Where(z => z.Value.CustomerName == c).Count().ToString());
                                 iLcn++;
                             }
 
                         }
                         break;
                     case "help":
-                        logger.Info("Command help!!");
-                        logger.Info("lcn : List Customer Name");
-                        logger.Info("gc : GC Collect");
-                        logger.Info("lc : List Clients");
-                        logger.Info("cls : clear console");
-                        logger.Info("silent : silent");
-                        logger.Info("show : show log");
+                        Console.WriteLine("Command help!!");
+                        Console.WriteLine("lcn : List Customer Name");
+                        Console.WriteLine("gc : GC Collect");
+                        Console.WriteLine("lc : List Clients");
+                        Console.WriteLine("cls : clear console");
+                        Console.WriteLine("silent : silent");
+                        Console.WriteLine("show : show log");
                         // logger.Info("rcl : show Real Connection Limit");
                         break;
                     case "cls":
-                        logger.Info("Command clear");
+                        Console.WriteLine("Command clear");
                         Console.Clear();
                         break;
 
                     case "silent":
-                        logger.Info("Command silent");
+                        Console.WriteLine("Command silent");
                         var xe = XElement.Load("NLog.config");
                         var xns = xe.GetDefaultNamespace();
                         var minlevelattr = xe.Descendants(xns + "rules").Elements(xns + "logger")
                             .Where(c => c.Attribute("writeTo").Value.Equals("console")).Attributes("minlevel").FirstOrDefault();
                         if (minlevelattr != null)
                         {
-                            minlevelattr.Value = "info";
+                            
+                            minlevelattr.Value = "Warn";
                         }
                         xe.Save("NLog.config");
                         break;
                     case "show":
-                        logger.Info("Command show");
+                        Console.WriteLine("Command show");
                         var xe1 = XElement.Load("NLog.config");
                         var xns1 = xe1.GetDefaultNamespace();
                         var minlevelattr1 = xe1.Descendants(xns1 + "rules").Elements(xns1 + "logger")
                             .Where(c => c.Attribute("writeTo").Value.Equals("console")).Attributes("minlevel").FirstOrDefault();
                         if (minlevelattr1 != null)
                         {
+                           
                             minlevelattr1.Value = "trace";
                         }
                         xe1.Save("NLog.config");
@@ -278,6 +282,53 @@ namespace EVCB_OCPP.WSServer
 
         }
 
+        private string SetDefaultFee(string chargeBoxId, string machineId)
+        {
+           
+            string feeText = "0.00";
+            string currencyText = "USD";
+            if (string.IsNullOrEmpty(chargeBoxId)) return feeText;
+
+            using (SqlConnection conn = new SqlConnection(webConnectionString))
+            {
+                var parameters = new DynamicParameters();
+                parameters.Add("@MachineId", machineId, DbType.String, ParameterDirection.Input);
+                string strSql = "SELECT  CAST( [Fee] as varchar(5))+' '+ [Currency]    FROM[StationMachine]  left join[StandardOCPP_Web].[dbo].[Station]" +
+                "  on[StationMachine].StationId = Station.[Id]  where StationMachine.MachineId=@MachineId ; ";
+                feeText = conn.ExecuteScalar<string>(strSql, parameters);              
+                currencyText = feeText.Split(' ')[1];               
+                feeText = feeText.Split(' ')[0];
+                feeText = string.Format("Connection Fee: $0.00 {0}/time; Current Rate: ${1} {0}/kWh; Occupancy Fee: $0.00 {0}/hr",currencyText, string.IsNullOrEmpty(feeText) ? "0.00" : feeText);
+            }
+
+            using (var db = new MainDBContext())
+            {
+                db.ServerMessage.Add(new ServerMessage()
+                {
+                    ChargeBoxId = chargeBoxId,
+                    CreatedBy = "Server",
+                    CreatedOn = DateTime.Now,
+                    OutAction = Actions.ChangeConfiguration.ToString(),
+                    OutRequest = JsonConvert.SerializeObject(
+                            new ChangeConfigurationRequest()
+                            {
+                                key = "DefaultPrice",
+                                // value= "Connection Fee: $0.00 USD/time; Current Rate: $1.02 USD/kWh; Occupancy Fee: $0.00 USD/hr"
+                                value = feeText
+                            },
+                            new JsonSerializerSettings() { NullValueHandling = NullValueHandling.Ignore, Formatting = Formatting.None }),
+                    SerialNo = Guid.NewGuid().ToString(),
+                    InMessage = string.Empty
+
+                }); ;
+
+                db.SaveChanges();
+
+            }
+
+            return feeText;
+        }
+
         private void CheckEVSEConfigure(string chargeBoxId)
         {
             if (string.IsNullOrEmpty(chargeBoxId)) return;
@@ -652,13 +703,18 @@ namespace EVCB_OCPP.WSServer
             }
             catch (Exception ex)
             {
-                logger.Error(string.Format("**Exception :{0} ", ex.ToString()));
+
 
                 if (ex.InnerException != null)
                 {
-                    logger.Error(string.Format("**Inner exception :{0} ", ex.InnerException.ToString()));
+                    logger.Error(string.Format("{0} **Inner Exception :{1} ", session.ChargeBoxId + rawdata, ex.ToString()));
+
 
                 }
+                else
+                {
+                    logger.Error(string.Format("{0} **Exception :{1} ", session.ChargeBoxId, ex.ToString()));
+                }
             }
 
 
@@ -682,8 +738,6 @@ namespace EVCB_OCPP.WSServer
                     case "Core":
                         {
 
-
-
                             var replyResult = await profileHandler.ExecuteCoreRequest(action, session, (IRequest)analysisResult.Message).ConfigureAwait(false);
                             if (replyResult.Success)
                             {
@@ -707,6 +761,10 @@ namespace EVCB_OCPP.WSServer
                                             }
                                         }
 
+                                        session.FeeDescription = SetDefaultFee(session.ChargeBoxId, session.MachineId);
+                                        session.Currency = session.FeeDescription.Substring(session.FeeDescription.Length-6, 3);
+                                       // Console.WriteLine("*"+session.Currency+"*");
+
                                         CheckVersion(session.ChargeBoxId);
                                         CheckEVSEConfigure(session.ChargeBoxId);
 
@@ -1119,6 +1177,7 @@ namespace EVCB_OCPP.WSServer
                 }
             }
         }
+        string webConnectionString = ConfigurationManager.ConnectionStrings["WebDBContext"].ConnectionString;
 
         async private void ServerMessageTrigger()
         {
@@ -1155,7 +1214,7 @@ namespace EVCB_OCPP.WSServer
                             string uuid = string.Empty;
                             if (clientDic.TryGetValue(charger_SN, out session))
                             {
-                                Console.WriteLine(string.Format("charger_SN:{0} startDt:{1} CreatedOn:{2}", charger_SN, startDt.ToString("yyyy/MM/dd HH:mm:ss"), DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss")));
+                                logger.Debug(string.Format("charger_SN:{0} startDt:{1} CreatedOn:{2}", charger_SN, startDt.ToString("yyyy/MM/dd HH:mm:ss"), DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss")));
 
                                 if (session.IsCheckIn && !session.ISOCPP20)
                                 {
@@ -1190,11 +1249,10 @@ namespace EVCB_OCPP.WSServer
 
                                         if (item.CreatedBy == "Destroyer")
                                         {
-                                            Console.WriteLine("********************************");
+                                           
                                             if (_RequestType != null)
                                             {
-                                                request = Activator.CreateInstance(_RequestType) as IRequest;
-                                                Console.WriteLine("++++++++++++++++++++++++++++++++++++++++");
+                                                request = Activator.CreateInstance(_RequestType) as IRequest;                                            
                                                 uuid = session.queue.store(request);
                                                 string rawRequest = BasicMessageHandler.GenerateDestroyRequest(uuid, item.OutAction, item.OutRequest);
                                                 Send(session, rawRequest, string.Format("{0} {1}", action, "Request"), "");
@@ -1221,7 +1279,7 @@ namespace EVCB_OCPP.WSServer
                                         db.Entry(_UpdatedItem).Property(x => x.UpdatedOn).IsModified = true;// 可以直接使用這方式強制某欄位要更新,只是查詢集合耗效能而己
 
                                         db.SaveChanges();
-
+                                        await Task.Delay(10);
                                         #endregion
 
 
@@ -1234,7 +1292,7 @@ namespace EVCB_OCPP.WSServer
                     }
 
                     await Task.Delay(1000);
-                    //  Thread.CurrentThread.Join(1000);
+                
                 }
                 catch (Exception ex)
                 {
@@ -1362,11 +1420,7 @@ namespace EVCB_OCPP.WSServer
 
                 lock (_lockConfirmPacketList)
                 {
-                    needConfirmPacketList.Add(_needConfirmMsg);
-                    if (action == "GetConfiguration")
-                    {
-                        Console.WriteLine("AddConfirmMessage: " + msg_id);
-                    }
+                    needConfirmPacketList.Add(_needConfirmMsg);                  
                 }
             }
         }
@@ -1390,10 +1444,7 @@ namespace EVCB_OCPP.WSServer
             bool confirmed = false;
             if (needConfirmActions.Contains(analysisResult.Action))
             {
-                if (analysisResult.Action == "GetConfiguration")
-                {
-                    Console.WriteLine("ReConfirmMessage: " + analysisResult.UUID);
-                }
+                
                 NeedConfirmMessage foundRequest = null;
                 lock (_lockConfirmPacketList)
                 {
@@ -1438,7 +1489,7 @@ namespace EVCB_OCPP.WSServer
 
         private void RemoveClient(ClientData session)
         {
-            Console.WriteLine("*********");
+          
 
             if (session != null)
             {

+ 2 - 0
EVCB_OCPP.WSServer/Service/BusinessServiceFactory.cs

@@ -14,6 +14,8 @@ namespace EVCB_OCPP.WSServer.Service
 
         Task NotifyFaultStatus(ErrorDetails details);
 
+        Task NotifyConnectorUnplugged(string chargeBoxId,string data);
+
     }
 
     static public class BusinessServiceFactory

+ 4 - 0
EVCB_OCPP.WSServer/Service/LocalBusinessService.cs

@@ -72,6 +72,10 @@ namespace EVCB_OCPP.WSServer.Service
 
         }
 
+        async public Task NotifyConnectorUnplugged(string chargeBoxId, string data)
+        {
+            await Task.Delay(10);
+        }
 
         async public Task NotifyFaultStatus(ErrorDetails details)
         {

+ 33 - 0
EVCB_OCPP.WSServer/Service/OuterBusinessService.cs

@@ -133,6 +133,34 @@ namespace EVCB_OCPP.WSServer.Service
 
         }
 
+        async public Task NotifyConnectorUnplugged(string chargeBoxId, string data)
+        {
+            try
+            {
+                JObject jo = JObject.Parse(data);
+
+                var details = new { ChargeBoxId = chargeBoxId, SessionId = jo["idTx"].Value<Int32>(), Timestamp = jo["timestamp"].Value<DateTime>() };
+                if (signMaterial.CallsThirdParty)
+                {
+                    var response = await httpClient.Post(signMaterial.APIUrl + "connectorunplugged", new Dictionary<string, string>()
+                            {
+                                { "PartnerId",signMaterial.Id}
+
+                            }, JsonConvert.SerializeObject(details, new JsonSerializerSettings() { DateTimeZoneHandling = DateTimeZoneHandling.Utc, 
+                                NullValueHandling = NullValueHandling.Ignore, Formatting = Formatting.None }), signMaterial.SaltKey).ConfigureAwait(false);
+
+
+                }
+
+
+            }
+            catch (Exception ex)
+            {
+
+                logger.Error(chargeBoxId + " OuterBusinessService.NotifyConnectorUnplugged Ex: " + ex.ToString());
+            }
+
+        }
 
         private CustomerSignMaterial GetSign(string customerId)
         {
@@ -146,5 +174,10 @@ namespace EVCB_OCPP.WSServer.Service
             }
             return _customer;
         }
+
+        public Task NotifyConnectorUnplugged(string data)
+        {
+            throw new NotImplementedException();
+        }
     }
 }

+ 3 - 0
EVCB_OCPP.WSServer/SuperSocket.Protocol/ClientData.cs

@@ -27,7 +27,10 @@ namespace OCPPServer.Protocol
 
         public bool ResetSecurityProfile { set; get; }
 
+        public string FeeDescription { set; get; }
+
         public string CustomerName { get; set; }
+        public string Currency { get; internal set; }
 
         public delegate void OCPPClientDataEventHandler<ClientData, String>(ClientData clientdata, String msg);
 

+ 8 - 4
EVCB_OCPP.WSServer/SuperSocket.Protocol/OCPPWSServer.cs

@@ -1,5 +1,6 @@
 
 using EVCB_OCPP.Domain;
+using NLog;
 using OCPPPackage.Profiles;
 using SuperWebSocket;
 using SuperWebSocket.SubProtocol;
@@ -15,6 +16,8 @@ namespace OCPPServer.Protocol
 {
     public class OCPPWSServer : WebSocketServer<ClientData>
     {
+
+        static private ILogger logger = NLog.LogManager.GetCurrentClassLogger();
         /// <summary>
         /// 可允許連線Clinet數
         /// </summary>
@@ -67,19 +70,20 @@ namespace OCPPServer.Protocol
             string authorizationKey = string.Empty;
             if (string.IsNullOrEmpty(session.Path))
             {
-                Console.WriteLine("===========================================");
-                Console.WriteLine("session.Path EMPTY");
-                Console.WriteLine("===========================================");
+                logger.Warn("===========================================");
+                logger.Warn("session.Path EMPTY");
+                logger.Warn("===========================================");
             }
 
             string[] words = session.Path.Split('/');
             session.ChargeBoxId = words.Last();
-            Console.WriteLine(string.Format("{0} :ValidateHandshake: {1}", DateTime.Now.ToString("yy/MM/dd HH:mm:ss.fff"), session.Path));
+            logger.Info(string.Format("ValidateHandshake: {0}", session.Path));
             bool isExistedSN = false;
             bool authorizated = false;
             using (var db = new MainDBContext())
             {
                 var machine = db.Machine.Where(x => x.ChargeBoxId == session.ChargeBoxId && x.IsDelete == false).Select(x => new { x.CustomerId, x.Id }).FirstOrDefault();
+                session.CustomerName = machine == null ? "Unknown" : db.Customer.Where(x => x.Id == machine.CustomerId).Select(x => x.Name).FirstOrDefault();
                 session.CustomerId = machine == null ? Guid.Empty : machine.CustomerId;
                 session.MachineId = machine == null ? String.Empty : machine.Id;
                 isExistedSN = machine == null ? false : true;

+ 11 - 0
SuperWebSocket/SuperWebSocket.NET45.csproj

@@ -52,6 +52,9 @@
       <SpecificVersion>False</SpecificVersion>
       <HintPath>..\Reference\Json.NET\Net40\Newtonsoft.Json.dll</HintPath>
     </Reference>
+    <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="SuperSocket.Common, Version=1.5.0.0, Culture=neutral, PublicKeyToken=6c80000676988ebb, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
       <HintPath>..\Reference\SuperSocket\Net45\$(Configuration)\SuperSocket.Common.dll</HintPath>
@@ -63,6 +66,11 @@
     <Reference Include="System" />
     <Reference Include="System.Core" />
     <Reference Include="Microsoft.CSharp" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.IO.Compression" />
+    <Reference Include="System.Runtime.Serialization" />
+    <Reference Include="System.ServiceModel" />
+    <Reference Include="System.Transactions" />
     <Reference Include="System.Xml" />
     <Reference Include="System.Configuration" />
   </ItemGroup>
@@ -129,6 +137,9 @@
     <Compile Include="WebSocketSession.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
   </ItemGroup>
+  <ItemGroup>
+    <None Include="packages.config" />
+  </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
        Other similar extension points exist, see Microsoft.Common.targets.

+ 6 - 3
SuperWebSocket/WebSocketServer.cs

@@ -12,6 +12,7 @@ using System.Text.RegularExpressions;
 using System.Threading;
 using System.Threading.Tasks;
 using Newtonsoft.Json;
+using NLog;
 using SuperSocket.Common;
 using SuperSocket.SocketBase;
 using SuperSocket.SocketBase.Command;
@@ -141,6 +142,8 @@ namespace SuperWebSocket
 
         }
 
+        static private ILogger logger = NLog.LogManager.GetCurrentClassLogger();
+
         private Dictionary<string, ISubProtocol<TWebSocketSession>> m_SubProtocols = new Dictionary<string, ISubProtocol<TWebSocketSession>>(StringComparer.OrdinalIgnoreCase);
 
         internal ISubProtocol<TWebSocketSession> DefaultSubProtocol { get; private set; }
@@ -595,10 +598,10 @@ namespace SuperWebSocket
             string line;
             string firstLine = string.Empty;
             string prevKey = string.Empty;
-
+            logger.Info("============================================================");
             while (!string.IsNullOrEmpty(line = reader.ReadLine()))
             {
-                Console.WriteLine(session.SessionID + " " + line);
+                logger.Info(session.SessionID + " " + line);
                 if (string.IsNullOrEmpty(firstLine))
                 {
                     firstLine = line;
@@ -647,7 +650,7 @@ namespace SuperWebSocket
 
                 prevKey = key;
             }
-
+            logger.Info("============================================================");
             var metaInfo = firstLine.Split(m_SpaceChar);
 
             session.Method = metaInfo[0];

+ 1 - 0
SuperWebSocket/packages.config

@@ -5,6 +5,7 @@
   <package id="MongoDB.Driver" version="2.7.0" targetFramework="net461" />
   <package id="MongoDB.Driver.Core" version="2.7.0" targetFramework="net461" />
   <package id="Newtonsoft.Json" version="10.0.2" targetFramework="net40" requireReinstallation="true" />
+  <package id="NLog" version="4.6.6" targetFramework="net461" />
   <package id="System.Buffers" version="4.3.0" targetFramework="net461" />
   <package id="System.Runtime.InteropServices.RuntimeInformation" version="4.0.0" targetFramework="net461" />
 </packages>

BIN
TestTool.RemoteTriggerAPP/DLL/EVCB_OCPP.Domain.dll


BIN
TestTool.RemoteTriggerAPP/DLL/EVCB_OCPP.Packet.dll


+ 1 - 1
TestTool.RemoteTriggerAPP/MainWindow.xaml

@@ -5,7 +5,7 @@
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
         xmlns:local="clr-namespace:TestTool.RemoteTriggerAPP"      
         mc:Ignorable="d"
-        Title="下發測試用工具(公司內網) V1.1.31 (20210601)" Height="481" Width="652">
+        Title="下發測試用工具(公司內網) V1.1.32 (20210810)" Height="481" Width="652">
     <Viewbox>
         <Grid Margin="0,2,2,0">
             <Grid.ColumnDefinitions>

+ 12 - 0
TestTool.RemoteTriggerAPP/MainWindow.xaml.cs

@@ -52,6 +52,18 @@ namespace TestTool.RemoteTriggerAPP
         bool isDestroyMode = false;
         public MainWindow()
         {
+            var oo = new { idToken = "3345678", price = "Connection Fee: $2.11 NTD/time; Current Rate: $2.22 NTD/kWh;Occupancy Fee: $2.33 NTD/hr; Account Balance: $2444 NTD" };
+
+
+            var tt = new DataTransferRequest()
+            {
+                vendorId = "Phihong Technology",
+                messageId = "SetUserPrice",
+                data = JsonConvert.SerializeObject(oo)
+            };
+
+            var ttt = JsonConvert.SerializeObject(tt);
+
 
             InitializeComponent();
             Loaded += MainWindow_Loaded;