13 Incheckningar 86d74463d3 ... c9c4b47be8

Upphovsman SHA1 Meddelande Datum
  Jessica Tseng c9c4b47be8 加入ID_OccupancyFeeAct 取消ActionId 3 2 år sedan
  Jessica Tseng a733b7d339 1. 新增 DataTransfer ID_OccupancyFeeAct 作為 2 år sedan
  Jessica Tseng 0398984f4d 1. 調整取佔用費金額 取不到資料應回覆Reject 2 år sedan
  Jessica Tseng ef13130dc4 新增佔用費相關流程 2 år sedan
  Jessica Tseng 238ef3ed12 新增佔用費流程 2 år sedan
  Jessica Tseng 5835a6d2be 台泥簡訊服務帳密變更 2 år sedan
  Jessica Tseng b50e3eeff9 1.加入StopTransaction 處理遇到Exception 不回電樁訊息,讓電樁重送Request 2 år sedan
  Jessica Tseng 1f2ad91319 1. fix send sms 餘額不足 回覆時間太久導致電樁斷線重連 2 år sedan
  Jessica Tseng 4c96346753 1. Fix 站點告警簡訊 內容誤植問題 2 år sedan
  Jessica Tseng d3c3465d48 Fix bug vendorErrorCode ="" 發送簡訊問題 2 år sedan
  Jessica Tseng 0c4b7075eb 1. 新增alarm sms 功能 2 år sedan
  Jessica Tseng 7ea02c1d37 1. 調整拔槍通知 2 år sedan
  Jessica Tseng f66cfe6506 1.加入拔槍通知 2 år sedan

+ 3 - 1
EVCB_OCPP.WSServer/App.config

@@ -15,7 +15,9 @@
   <appSettings>   
      <add key="LocalAuthAPI" value="" />
     <add key="WSPort" value="2012" />
-    <add key="WSSPort" value="2016" />  
+    <add key="WSSPort" value="2016" />
+    <add key="AlarmNotificationCond" value="012251,012252,042251,042252,042267,042327,042328,042304,012304" />
+    <add key="SMS_Receivers" value="0983105714,0929168960" />
   </appSettings>
   <startup>
     <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.1" />

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


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

@@ -8,6 +8,7 @@ namespace EVCB_OCPP.WSServer.Dto
 {
     public class TCCStationInfoDto
     {
+        public string Name { set; get; }
         public decimal Lat { set; get; }
 
         public decimal Long { set; get; }

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

@@ -138,6 +138,7 @@
       <HintPath>..\packages\System.Threading.Tasks.Extensions.4.5.2\lib\netstandard2.0\System.Threading.Tasks.Extensions.dll</HintPath>
     </Reference>
     <Reference Include="System.Transactions" />
+    <Reference Include="System.Web" />
     <Reference Include="System.Xml.Linq" />
     <Reference Include="System.Data.DataSetExtensions" />
     <Reference Include="Microsoft.CSharp" />
@@ -177,6 +178,7 @@
     <Compile Include="Properties\AssemblyInfo.cs" />
     <Compile Include="ProtalServer.cs" />
     <Compile Include="Service\OuterHttpClient.cs" />
+    <Compile Include="Service\SMSService.cs" />
     <Compile Include="SuperSocket.Command\ProcessCallCmd.cs" />
     <Compile Include="SuperSocket.Command\ProcessCallErrorCmd.cs" />
     <Compile Include="SuperSocket.Command\ProcessCallResultCmd.cs" />

+ 0 - 1
EVCB_OCPP.WSServer/GitVersion.yml

@@ -1,6 +1,5 @@
 assembly-versioning-scheme: MajorMinorPatch
 assembly-informational-format: '{ShortSha}'
 next-version: 0.1.0
-branches: {}
 ignore:
   sha: []

+ 36 - 4
EVCB_OCPP.WSServer/GlobalConfig.cs

@@ -11,7 +11,8 @@ namespace EVCB_OCPP.WSServer
         {
             "WSPort",
             "WSSPort",
-            ""
+            "AlarmNotificationCond",
+            "SMS_Receivers"
         };
 
         public static string TCC_API_URL = string.Empty;
@@ -24,8 +25,6 @@ namespace EVCB_OCPP.WSServer
         /// </summary>
         private static int DEFAULT_HEARTBEAT_INTERVAL = 60;
 
-
-
         /// <summary>
         ///WS Port
         /// </summary>
@@ -37,6 +36,18 @@ namespace EVCB_OCPP.WSServer
         /// </summary>
         private static int WSS_Port = 2013;
 
+
+        /// <summary>
+        ///WS Port
+        /// </summary>
+        private static string AlarmNotificationCond = string.Empty;
+
+
+        /// <summary>
+        ///WSS Port
+        /// </summary>
+        private static string SMS_Receivers = string.Empty;
+
         /// <summary>
         /// Load setting from app.config 
         /// </summary>
@@ -55,7 +66,6 @@ namespace EVCB_OCPP.WSServer
                         case "WSPort":// convert to int type                       
                             {
                                 var value = ConfigurationManager.AppSettings[key];
-
                                 WS_Port = Convert.ToInt32(value);
                             }
                             break;
@@ -66,6 +76,18 @@ namespace EVCB_OCPP.WSServer
                                 WSS_Port = Convert.ToInt32(value);
                             }
                             break;
+                        case "AlarmNotificationCond":// convert to int type                       
+                            {
+                                AlarmNotificationCond = ConfigurationManager.AppSettings[key];
+
+                            }
+                            break;
+                        case "SMS_Receivers":// convert to int type                       
+                            {
+                                SMS_Receivers = ConfigurationManager.AppSettings[key];
+
+                            }
+                            break;
                         default://convert to string type                             
                             break;
 
@@ -83,6 +105,16 @@ namespace EVCB_OCPP.WSServer
             return result;
         }
 
+        public static string GetAlarmNotification_Cond()
+        {
+            return AlarmNotificationCond;
+        }
+
+        public static string GetSMS_Receivers()
+        {
+            return SMS_Receivers;
+        }
+
 
 
         public static int GetWS_Port()

+ 417 - 133
EVCB_OCPP.WSServer/Message/CoreProfileHandler.cs

@@ -8,6 +8,7 @@ using EVCB_OCPP.Packet.Messages.SubTypes;
 using EVCB_OCPP.WSServer.Dto;
 using EVCB_OCPP.WSServer.Service;
 using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
 using NLog;
 using OCPPPackage.Profiles;
 using OCPPServer.Protocol;
@@ -20,6 +21,7 @@ using System.Data.SqlClient;
 using System.Diagnostics;
 using System.Globalization;
 using System.Linq;
+using System.Net;
 using System.Threading.Tasks;
 
 namespace EVCB_OCPP.WSServer.Message
@@ -62,11 +64,56 @@ namespace EVCB_OCPP.WSServer.Message
 
     }
 
+    public class ID_GetOccupancyFee
+    {
+        public int ConnectorId { set; get; }
+
+        public string occupancySN { set; get; }
+
+        /// <summary>
+        ///  1. Get occupancy fee info. 2. Cancel local deduction
+        /// </summary>
+        public int Action { set; get; }
+
+    }
+
+    public class ID_GetOccupancyFeeResult
+    {
+        public string msgId { set; get; }
+        public int ConnectorId { set; get; }
+
+        public string occupancySN { set; get; }
+
+        public string startTime { set; get; }
+
+        public int? duration { set; get; }
+
+
+        public decimal? occupancyFee { set; get; }
+
+
+    }
+
+    public class ID_OccupancyFeeResult
+    {
+        public string occupancySN { set; get; }
+
+        public string creditNo { set; get; }
+
+
+        public bool deductResult { set; get; }
+
+        public decimal amount { set; get; }
+
+        public string approvalNo { set; get; }
+
+    }
     internal partial class ProfileHandler
     {
         static private ILogger logger = NLog.LogManager.GetCurrentClassLogger();
         string webConnectionString = ConfigurationManager.ConnectionStrings["WebDBContext"].ConnectionString;
         private OuterHttpClient httpClient = new OuterHttpClient();
+        private SMSService smsService = new SMSService();
         async internal Task<MessageResult> ExecuteCoreRequest(Actions action, ClientData session, IRequest request)
         {
             Stopwatch watch = new Stopwatch();
@@ -83,6 +130,7 @@ namespace EVCB_OCPP.WSServer.Message
                     case Actions.DataTransfer:
                         {
                             DataTransferRequest _request = request as DataTransferRequest;
+
                             var confirm = new DataTransferConfirmation() { status = DataTransferStatus.UnknownMessageId };
 
                             if (_request.messageId == "ID_CreditDeductResult")
@@ -144,6 +192,178 @@ namespace EVCB_OCPP.WSServer.Message
                                     confirm.data = JsonConvert.SerializeObject(new { msgId = "ID_ReaderStatus", ConnectorId = preauth_status.ConnectorId });
                                 }
                             }
+                            if (_request.messageId == "ConnectorUnplugged")
+                            {
+                                logger.Debug("ConnectorUnplugged");
+                                JObject jo = JObject.Parse(_request.data);
+
+                                var businessService = BusinessServiceFactory.CreateBusinessService(session.CustomerId.ToString());
+                                await businessService.NotifyConnectorUnplugged(session.ChargeBoxId, jo["idTx"].Value<string>(), jo["timestamp"].Value<string>());
+
+                                confirm.status = DataTransferStatus.Accepted;
+                            }
+                            if (_request.messageId == "ID_OccupancyFeeAct")
+                            {
+                                var getOccupancyFee = JsonConvert.DeserializeObject<ID_GetOccupancyFee>(_request.data);
+                                ID_GetOccupancyFeeResult occupancyFeeResult = new ID_GetOccupancyFeeResult()
+                                {
+                                    msgId = _request.messageId,
+                                    ConnectorId = getOccupancyFee.ConnectorId,
+                                    occupancySN = getOccupancyFee.occupancySN
+                                };
+
+                                if(getOccupancyFee.Action==1)
+                                {
+                                    var report = new
+                                    {
+                                        ChargeBoxId = session.ChargeBoxId,
+                                        occupancySN = getOccupancyFee.occupancySN
+
+                                    };
+                                    var response = await httpClient.Post(GlobalConfig.TCC_API_URL + "occupancy_payment", new Dictionary<string, string>()
+                                        {
+                                            { "PartnerId",session.CustomerId.ToString()}
+
+                                        }, report, GlobalConfig.TCC_SALTKEY);
+
+                                    if (!response.Success)
+                                    {
+                                        confirm.status = DataTransferStatus.Rejected;
+                                        confirm.data = JsonConvert.SerializeObject(occupancyFeeResult);
+                                    }
+                                    else
+                                    {
+
+                                        var _httpResult = JsonConvert.DeserializeObject<CPOOuterResponse>(response.Response);
+                                        if (_httpResult.StatusCode != 1000)
+                                        {
+                                            confirm.status = DataTransferStatus.Rejected;
+                                            confirm.data = JsonConvert.SerializeObject(occupancyFeeResult);
+                                        }
+                                        else
+                                        {
+                                            confirm.status = DataTransferStatus.Accepted;
+
+                                            JObject jo = JObject.Parse(_httpResult.Data);
+                                            if (jo.ContainsKey("ChargeEndTime"))
+                                            {
+                                                occupancyFeeResult.startTime = jo["ChargeEndTime"].Value<string>();
+
+                                            }
+                                            if (jo.ContainsKey("OccupancyDuration"))
+                                            {
+                                                occupancyFeeResult.duration = jo["OccupancyDuration"].Value<int>();
+                                            }
+
+                                            if (jo.ContainsKey("OccupancyFee"))
+                                            {
+                                                occupancyFeeResult.occupancyFee = jo["OccupancyFee"].Value<decimal>();
+                                            }
+
+                                            confirm.data = JsonConvert.SerializeObject(occupancyFeeResult);
+
+                                        }
+                                    }
+                                }
+                                else if (getOccupancyFee.Action == 2)
+                                {
+                                    var report = new
+                                    {
+                                        ChargeBoxId = session.ChargeBoxId,
+                                        occupancySN = getOccupancyFee.occupancySN
+
+                                    };
+                                    var response = await httpClient.Post(GlobalConfig.TCC_API_URL + "resume_occupancy", new Dictionary<string, string>()
+                                        {
+                                            { "PartnerId",session.CustomerId.ToString()}
+
+                                        }, report, GlobalConfig.TCC_SALTKEY);
+
+                                    if (!response.Success)
+                                    {
+                                        confirm.status = DataTransferStatus.Rejected;
+                                        confirm.data = JsonConvert.SerializeObject(occupancyFeeResult, GlobalConfig.JSONSERIALIZER_FORMAT);
+                                    }
+                                    else
+                                    {
+
+                                        var _httpResult = JsonConvert.DeserializeObject<CPOOuterResponse>(response.Response);
+                                        if (_httpResult.StatusCode != 1000)
+                                        {
+                                            confirm.status = DataTransferStatus.Rejected;
+                                            confirm.data = JsonConvert.SerializeObject(occupancyFeeResult, GlobalConfig.JSONSERIALIZER_FORMAT);
+                                        }
+                                        else
+                                        {
+                                            confirm.status = DataTransferStatus.Accepted;
+                                            confirm.data = JsonConvert.SerializeObject(occupancyFeeResult,GlobalConfig.JSONSERIALIZER_FORMAT);
+
+                                        }
+                                    }
+                                }
+                                else 
+                                {
+                                    var report = new
+                                    {
+                                        ChargeBoxId = session.ChargeBoxId,
+                                        occupancySN = getOccupancyFee.occupancySN
+
+                                    };
+                                    var response = await httpClient.Post(GlobalConfig.TCC_API_URL + "writeoff_occupancy", new Dictionary<string, string>()
+                                        {
+                                            { "PartnerId",session.CustomerId.ToString()}
+
+                                        }, report, GlobalConfig.TCC_SALTKEY);
+
+                                    if (!response.Success)
+                                    {
+                                        confirm.status = DataTransferStatus.Rejected;
+                                        confirm.data = JsonConvert.SerializeObject(occupancyFeeResult, GlobalConfig.JSONSERIALIZER_FORMAT);
+                                    }
+                                    else
+                                    {
+
+                                        var _httpResult = JsonConvert.DeserializeObject<CPOOuterResponse>(response.Response);
+                                        if (_httpResult.StatusCode != 1000)
+                                        {
+                                            confirm.status = DataTransferStatus.Rejected;
+                                            confirm.data = JsonConvert.SerializeObject(occupancyFeeResult, GlobalConfig.JSONSERIALIZER_FORMAT);
+                                        }
+                                        else
+                                        {
+                                            confirm.status = DataTransferStatus.Accepted;
+                                            confirm.data = JsonConvert.SerializeObject(occupancyFeeResult, GlobalConfig.JSONSERIALIZER_FORMAT);
+
+                                        }
+                                    }
+                                }
+
+                            }
+                            if (_request.messageId == "ID_OccupancyDeductResult")
+                            {
+
+                                var occupancyFeeResult = JsonConvert.DeserializeObject<ID_OccupancyFeeResult>(_request.data);
+                                var report = new
+                                {
+                                    OccupancySN = occupancyFeeResult.occupancySN,
+                                    CreditNo = occupancyFeeResult.creditNo,
+                                    DeductResult = occupancyFeeResult.deductResult,
+                                    Amount = occupancyFeeResult.amount,
+                                    ApprovalNo = occupancyFeeResult.approvalNo
+
+                                };
+
+                                var response = await httpClient.Post(GlobalConfig.TCC_API_URL + "occupancyfee_result", new Dictionary<string, string>()
+                                        {
+                                            { "PartnerId",session.CustomerId.ToString()}
+
+                                        }, report, GlobalConfig.TCC_SALTKEY);
+
+                                logger.Debug(JsonConvert.SerializeObject(response));
+
+                                confirm.status = DataTransferStatus.Accepted;
+                                confirm.data = JsonConvert.SerializeObject(new { msgId = _request.messageId, occupancySN = occupancyFeeResult.occupancySN });
+                            }
                             result.Message = confirm;
                             result.Success = true;
                         }
@@ -262,6 +482,27 @@ namespace EVCB_OCPP.WSServer.Message
 
                             if (_request.status == Packet.Messages.SubTypes.ChargePointStatus.Faulted)
                             {
+                                var alarmCond = GlobalConfig.GetAlarmNotification_Cond();
+
+                                if (!string.IsNullOrEmpty(_request.vendorErrorCode) && alarmCond.Contains(_request.vendorErrorCode))
+                                {
+                                    List<string> sendlist = GlobalConfig.GetSMS_Receivers().Split(',').ToList();
+                                    foreach (var item in sendlist)
+                                    {
+
+                                        string message = string.Format("[{0}告警-{1}]\r\n{2} -{3}\r\n時間:{4}\r\n", session.StationName, _request.vendorErrorCode, session.ChargeBoxId,
+                                            _request.connectorId, DateTime.UtcNow.AddHours(8).ToString("yyyy/MM/dd HH:mm:ss"));
+                                        string errorMsg = string.Empty;
+                                        errorMsg = await smsService.SendMessage(item, message);
+
+                                        if (!string.IsNullOrEmpty(errorMsg))
+                                        {
+                                            logger.Error("Send SMS  " + message);
+                                            logger.Error("Send SMS Error " + errorMsg);
+                                        }
+                                    }
+                                }
+
                                 var businessService = BusinessServiceFactory.CreateBusinessService(session.CustomerId.ToString());
                                 var notification = businessService.NotifyFaultStatus(new ErrorDetails()
                                 {
@@ -273,6 +514,8 @@ namespace EVCB_OCPP.WSServer.Message
                                     VendorErrorCode = string.IsNullOrEmpty(_request.vendorErrorCode) ? string.Empty : _request.vendorErrorCode,
 
                                 });
+
+
                             }
 
                             var confirm = new StatusNotificationConfirmation() { };
@@ -292,7 +535,6 @@ namespace EVCB_OCPP.WSServer.Message
                         {
 
                             MeterValuesRequest _request = request as MeterValuesRequest;
-                            decimal energy_kwh = 0;
 
                             if (_request.meterValue.Count > 0)
                             {
@@ -302,60 +544,12 @@ namespace EVCB_OCPP.WSServer.Message
                                 {
                                     foreach (var item in _request.meterValue)
                                     {
-                                        int registerCount = item.sampledValue.Where(x => x.measurand == Measurand.Energy_Active_Import_Interval).ToList().Count;
-                                        if (registerCount > 0)
-                                        {
-                                            registerCount = 0;
-                                        }
-                                        else
-                                        {
-                                            registerCount = item.sampledValue.Where(x => x.measurand == Measurand.Energy_Active_Import_Register).ToList().Count;
-                                        }
 
-                                        if (registerCount > 0)
-                                        {
-                                            string voltage_text = item.sampledValue.Where(x => x.measurand == Measurand.Voltage).Select(x => x.value).FirstOrDefault();
-                                            decimal voltage = decimal.Parse(voltage_text);
-                                            string current_text = item.sampledValue.Where(x => x.measurand == Measurand.Current_Import).Select(x => x.value).FirstOrDefault();
-                                            decimal current = decimal.Parse(current_text);
-                                            decimal meterStart = 0;
-                                            string energyRegister_text = item.sampledValue.Where(x => x.measurand == Measurand.Energy_Active_Import_Register).Select(x => x.value).FirstOrDefault();
-                                            decimal energyRegister = decimal.Parse(energyRegister_text);
-                                            using (var maindb = new MainDBContext())
-                                            {
-                                                meterStart = maindb.TransactionRecord.Where(x => x.Id == _request.transactionId.Value).Select(x => x.MeterStart).FirstOrDefault();
-                                            }
 
-                                            item.sampledValue.Add(new SampledValue()
-                                            {
-                                                context = ReadingContext.Sample_Periodic,
-                                                format = ValueFormat.Raw,
-                                                location = Location.Outlet,
-                                                phase = Phase.L1_N,
-                                                unit = UnitOfMeasure.kWh,
-                                                measurand = Measurand.Energy_Active_Import_Interval,
-                                                value = decimal.Divide(decimal.Subtract(energyRegister, meterStart), (decimal)1000).ToString()
-                                            });
-                                            item.sampledValue.Add(new SampledValue()
-                                            {
-                                                context = ReadingContext.Sample_Periodic,
-                                                format = ValueFormat.Raw,
-                                                location = Location.Outlet,
-                                                phase = Phase.L1_N,
-                                                unit = UnitOfMeasure.kW,
-                                                measurand = Measurand.Power_Active_Import,
-                                                value = decimal.Divide(decimal.Multiply(voltage, current), (decimal)1000).ToString()
-                                            });
-                                        }
                                         foreach (var sampleVaule in item.sampledValue)
                                         {
                                             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";
 
@@ -532,109 +726,110 @@ 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()
+                                    var transaction = db.TransactionRecord.Where(x => x.Id == _request.transactionId
+                                     && x.ChargeBoxId == session.ChargeBoxId).FirstOrDefault();
+
+                                    // throw new Exception("123");
+                                    //遠傳太久以前的停止充電 直接拒絕 避免電樁持續重送~~~~~~~
+                                    if (_request.timestamp < new DateTime(2021, 11, 1))
                                     {
-                                        idTagInfo = new IdTagInfo()
+                                        var confirm = new StopTransactionConfirmation()
                                         {
-                                            status = AuthorizationStatus.Invalid
-                                        }
-
-                                    };
-
-                                    result.Message = confirm;
-                                    result.Success = true;
-                                    return result;
-                                }
-
+                                            idTagInfo = new IdTagInfo()
+                                            {
+                                                status = AuthorizationStatus.Invalid
+                                            }
 
-                                if (transaction != null)
-                                {
-                                    var confirm = new StopTransactionConfirmation()
-                                    {
-                                        idTagInfo = _idTagInfo
+                                        };
 
-                                    };
-                                    //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.StopIdTag = _request.idTag;
-                                    transaction.Receipt = string.Empty;
-                                    transaction.Cost = session.IsBilling ? -1 : 0;
 
-                                    await db.SaveChangesAsync();
+                                    if (transaction != null)
+                                    {
+                                        var confirm = new StopTransactionConfirmation()
+                                        {
+                                            idTagInfo = _idTagInfo
 
+                                        };
+                                        //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.StopIdTag = _request.idTag;
+                                        transaction.Receipt = string.Empty;
+                                        transaction.Cost = session.IsBilling ? -1 : 0;
 
-                                    if (session.IsBilling)
-                                    {
-                                        db.ServerMessage.Add(new ServerMessage()
+                                        await db.SaveChangesAsync();
+
+
+
+                                        if (session.IsBilling)
                                         {
-                                            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.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();
-                                    }
+                                            db.SaveChanges();
+                                        }
 
-                                    result.Message = confirm;
-                                    result.Success = true;
-                                }
-                                else
-                                {
+                                        result.Message = confirm;
+                                        result.Success = true;
+                                    }
+                                    else
+                                    {
 
-                                    result.Exception = new Exception("Can't find transactionId " + _request.transactionId);
+                                        result.Exception = new Exception("Can't find transactionId " + _request.transactionId);
 
+                                    }
                                 }
-                            }
 
-                            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),
@@ -650,14 +845,24 @@ namespace EVCB_OCPP.WSServer.Message
                                           };
 
 
-                                                _meterDb.Database.ExecuteSqlCommand(sp, parameter.ToArray());
+                                                    _meterDb.Database.ExecuteSqlCommand(sp, parameter.ToArray());
+                                                }
                                             }
                                         }
-                                    }
 
 
+                                    }
                                 }
                             }
+                            catch (Exception ex)
+                            {
+                                result.Exception = new Exception("TransactionId " + _request.transactionId + " " + ex.Message);
+                                result.CallErrorMsg = "Reject Response Message";
+                                result.Success = false;
+                                // return result;
+                            }
+
+
 
 
                         }
@@ -710,7 +915,7 @@ namespace EVCB_OCPP.WSServer.Message
             return result;
         }
 
-        internal MessageResult ExecuteCoreConfirm(Actions action, ClientData session, IConfirmation confirm, string requestId)
+        async internal Task<MessageResult> ExecuteCoreConfirm(Actions action, ClientData session, IConfirmation confirm, string requestId)
         {
             MessageResult result = new MessageResult() { Success = true };
 
@@ -763,6 +968,32 @@ namespace EVCB_OCPP.WSServer.Message
                                         if (feedto == null || string.IsNullOrEmpty(feedto.Fee)) return result;
                                         string currency = feedto.Fee.Substring(feedto.Fee.Length - 3);
                                         decimal chargingCost = 0;
+
+                                        using (var meterdb = new MeterValueDBContext())
+                                        {
+                                            string sp = "[dbo].[uspInsertMeterValueRecord] @ChargeBoxId," +
+                               "@ConnectorId,@Value,@CreatedOn,@ContextId,@FormatId,@MeasurandId,@PhaseId,@LocationId,@UnitId,@TransactionId";
+
+                                            List<SqlParameter> parameter = new List<SqlParameter>
+                                                {
+                                                      new SqlParameter("ChargeBoxId",session.ChargeBoxId),
+                                                      new SqlParameter("ConnectorId",  (byte)feedto.ConnectorId),
+                                                      new SqlParameter("Value",txEnergy.PeriodEnergy.Sum(x=>x.Value)),
+                                                      new SqlParameter("CreatedOn",DateTime.UtcNow),
+                                                      new SqlParameter("ContextId",(int)ReadingContext.Sample_Periodic),
+                                                      new SqlParameter("FormatId",(int)ValueFormat.Raw),
+                                                      new SqlParameter("MeasurandId",(int)Measurand.TotalEnergy),
+                                                      new SqlParameter("PhaseId", -1),
+                                                      new SqlParameter("LocationId", -1),
+                                                      new SqlParameter("UnitId", (int)UnitOfMeasure.kWh),
+                                                      new SqlParameter("TransactionId",feedto.Id),
+                                                };
+
+
+                                            meterdb.Database.ExecuteSqlCommand(sp, parameter.ToArray());
+                                        }
+
+
                                         if (feedto.Fee.Length > 58)
                                         {
                                             chargingPrices = JsonConvert.DeserializeObject<List<ChargingPrice>>(feedto.Fee.Split('|')[0]);
@@ -835,8 +1066,8 @@ namespace EVCB_OCPP.WSServer.Message
                                             chargingCost = DollarRounding(chargingCost, session.Currency);
                                         }
 
-                                        // 計算停車費
-                                        var parkingFee = decimal.Parse(feedto.Fee.Split('&')[1]);
+                                        // 計算停車費 台泥不適用此停車費模式
+                                        var parkingFee = 0;// decimal.Parse(feedto.Fee.Split('&')[1]);
                                         var stoptime = feedto.StopTime == GlobalConfig.DefaultNullTime ? DateTime.Parse(DateTime.UtcNow.ToString("yyyy/MM/dd HH:mm")) : DateTime.Parse(feedto.StopTime.ToString("yyyy/MM/dd HH:mm"));
                                         var starttime = DateTime.Parse(feedto.StartTime.ToString("yyyy/MM/dd HH:mm"));
                                         var totalHours = stoptime.Subtract(starttime).TotalHours;
@@ -928,15 +1159,70 @@ namespace EVCB_OCPP.WSServer.Message
                                                 tx.Cost = chargingCost + parkingCost;
                                             }
 
+
+                                            tx.StopTransactionReportedOn = DateTime.UtcNow;
                                             tx.Receipt = receipt;
                                             tx.UploadedtoTTIA = true;
                                             db.Configuration.AutoDetectChangesEnabled = false;
                                             db.Configuration.ValidateOnSaveEnabled = false;
                                             db.TransactionRecord.Attach(tx);
+                                            db.Entry(tx).Property(x => x.StopTransactionReportedOn).IsModified = true;
                                             db.Entry(tx).Property(x => x.Cost).IsModified = true;
                                             db.Entry(tx).Property(x => x.Receipt).IsModified = true;
                                             db.Entry(tx).Property(x => x.UploadedtoTTIA).IsModified = true;
 
+                                            #region 同步發送充電結束通知
+                                            decimal? discountFee = null;//折扣金額
+                                            decimal? chargingAmount = null;//充電抵用金使用金額
+                                            decimal? actualFee = null;  //實際付款金額
+
+                                            var request = new
+                                            {
+                                                ChargeBoxId = tx.ChargeBoxId,
+                                                ConnectorId = tx.ConnectorId,
+                                                SessionId = tx.Id,
+                                                MeterStart = tx.MeterStart,
+                                                MeterStop = tx.MeterStop,
+                                                IdTag = tx.StartIdTag,
+                                                StartTime = tx.StartTime.ToString(GlobalConfig.UTC_DATETIMEFORMAT),
+                                                StopTime = tx.StopTime.ToString(GlobalConfig.UTC_DATETIMEFORMAT),
+                                                StopReason = tx.StopReasonId < 1 ? "Unknown" : (tx.StopReasonId > 12 ? "Unknown" : ((Reason)tx.StopReasonId).ToString()),
+                                                Receipt = tx.Receipt,
+                                                TotalCost = tx.Cost,
+                                                Fee = tx.Fee
+
+                                            };
+
+                                            var response = await httpClient.Post(GlobalConfig.TCC_API_URL + "completed_session", new Dictionary<string, string>()
+                                                {
+                                                    { "PartnerId",session.CustomerId.ToString()}
+
+                                                }, request, GlobalConfig.TCC_SALTKEY);
+
+                                            var _httpResult = JsonConvert.DeserializeObject<CPOOuterResponse>(response.Response);
+                                            if (!string.IsNullOrEmpty(_httpResult.Data))
+                                            {
+                                                JObject jo = JObject.Parse(_httpResult.Data);
+                                                if (jo.ContainsKey("discountAmount"))
+                                                {
+                                                    discountFee = jo["discountAmount"].Value<decimal>();
+
+                                                }
+
+                                                if (jo.ContainsKey("chargingAmount"))
+                                                {
+                                                    chargingAmount = jo["chargingAmount"].Value<decimal>();
+                                                }
+
+
+                                                if (jo.ContainsKey("actualAmount"))
+                                                {
+                                                    actualFee = jo["actualAmount"].Value<decimal>();
+                                                }
+                                            }
+                                            #endregion
+
+
                                             db.ServerMessage.Add(new ServerMessage()
                                             {
                                                 ChargeBoxId = session.ChargeBoxId,
@@ -954,17 +1240,15 @@ namespace EVCB_OCPP.WSServer.Message
                                                                     description = JsonConvert.SerializeObject(new
                                                                     {
                                                                         chargedEnergy = chargedEnergy,
-                                                                        chargingFee = chargingCost,
+                                                                        chargingFee = actualFee.HasValue ? actualFee : chargingCost,
                                                                         parkTime = (int)stoptime.Subtract(starttime).TotalSeconds,
                                                                         parkingFee = parkingCost,
                                                                         currency = currency,
-                                                                        couponPoint = 0,
                                                                         accountBalance = accountBalance - tx.Cost
-                                                                    })
+                                                                    }, GlobalConfig.JSONSERIALIZER_FORMAT)
                                                                 })
 
-                                                            },
-                                                            new JsonSerializerSettings() { NullValueHandling = NullValueHandling.Ignore, Formatting = Formatting.None }),
+                                                            }, GlobalConfig.JSONSERIALIZER_FORMAT),
                                                 SerialNo = Guid.NewGuid().ToString(),
                                                 InMessage = string.Empty
 

+ 14 - 1
EVCB_OCPP.WSServer/Program.cs

@@ -1,15 +1,28 @@
 using Newtonsoft.Json;
 using System;
+using System.Collections.Generic;
 using System.Net.Http;
 using System.Threading.Tasks;
 
 namespace EVCB_OCPP.WSServer
 {
-   
+
     class Program
     {
         static void Main(string[] args)
         {
+
+            Dictionary<long, long> dictionary = new Dictionary<long, long>()
+            {
+                {  DateTimeOffset.Now.AddDays(-3).ToUnixTimeSeconds(),  DateTimeOffset.Now.ToUnixTimeSeconds()},
+                {  DateTimeOffset.Now.AddDays(-2).ToUnixTimeSeconds(),  DateTimeOffset.Now.ToUnixTimeSeconds()},
+                {  DateTimeOffset.Now.AddDays(-1).ToUnixTimeSeconds(),  DateTimeOffset.Now.ToUnixTimeSeconds()}
+
+             };
+
+          var ttt=   JsonConvert.SerializeObject(dictionary);
+
+
             Console.WriteLine("====================================================================================================");
             Console.WriteLine("====================================================================================================");
             Console.WriteLine("==                                                                                                ==");

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

@@ -31,8 +31,8 @@ using System.Runtime.InteropServices;
 //
 // 您可以指定所有的值,或將組建編號或修訂編號設為預設值
 // 指定為預設值: 
-// [assembly: AssemblyVersion("1.0.6.0")]
-[assembly: AssemblyVersion("1.0.6.0")]
-[assembly: AssemblyFileVersion("1.0.6.0")]
+// [assembly: AssemblyVersion("0.1.0.0")]
+[assembly: AssemblyVersion("0.1.0.0")]
+[assembly: AssemblyFileVersion("0.1.0.0")]
 
-[assembly: AssemblyInformationalVersion("da8c40a")]
+[assembly: AssemblyInformationalVersion("a733b7d")]

+ 79 - 32
EVCB_OCPP.WSServer/ProtalServer.cs

@@ -350,7 +350,7 @@ namespace EVCB_OCPP.WSServer
             {
                 var parameters = new DynamicParameters();
                 parameters.Add("@MachineId", machineId, DbType.String, ParameterDirection.Input);
-                string sql = " SELECT CAST([Latitude] as DECIMAL(5,2)) Lat,CAST([Longitude] as DECIMAL(5, 2))  Long ,SUBSTRING([Address],1,3) as zipcode FROM[StationMachine]  left join [dbo].[Station]" +
+                string sql = " SELECT Name,CAST([Latitude] as DECIMAL(5,2)) Lat,CAST([Longitude] as DECIMAL(5, 2))  Long ,SUBSTRING([Address],1,3) as zipcode FROM[StationMachine]  left join [dbo].[Station]" +
                "  on[StationMachine].StationId = Station.[Id]  where StationMachine.MachineId=@MachineId; ";
 
                 var result = await conn.QueryAsync<TCCStationInfoDto>(sql, parameters);
@@ -763,7 +763,7 @@ namespace EVCB_OCPP.WSServer
                                             if (stationInfo != null)
                                             {
                                                 session.StationLocation = string.Format("{0},{1}", stationInfo.Lat, stationInfo.Long);
-                                                session.StationName = stationInfo.ZipCode;
+                                                session.StationName = stationInfo.Name;
                                             }
                                             using (var db = new MainDBContext())
                                             {
@@ -908,10 +908,19 @@ namespace EVCB_OCPP.WSServer
                             }
                             else
                             {
-                                string response = BasicMessageHandler.GenerateCallError(analysisResult.UUID, OCPPErrorCodes.InternalError, OCPPErrorDescription.InternalError);
-                                string errorMsg = replyResult.Exception != null ? replyResult.Exception.ToString() : string.Empty;
 
-                                Send(session, response, string.Format("{0} {1}", analysisResult.Action, "Error"), errorMsg);
+                                if (action == Actions.StopTransaction && replyResult.CallErrorMsg == "Reject Response Message")
+                                {
+                                    //do nothing 
+                                }
+                                else
+                                {
+                                    string response = BasicMessageHandler.GenerateCallError(analysisResult.UUID, OCPPErrorCodes.InternalError, OCPPErrorDescription.InternalError);
+                                    string errorMsg = replyResult.Exception != null ? replyResult.Exception.ToString() : string.Empty;
+
+                                    Send(session, response, string.Format("{0} {1}", analysisResult.Action, "Error"), errorMsg);
+                                }
+
                             }
 
                             if (action == Actions.StartTransaction)
@@ -1035,7 +1044,7 @@ namespace EVCB_OCPP.WSServer
             }
         }
 
-        private void ProcessConfirmationMessage(MessageResult analysisResult, ClientData session, Actions action)
+        async private void ProcessConfirmationMessage(MessageResult analysisResult, ClientData session, Actions action)
         {
 
             BasicMessageHandler msgAnalyser = new BasicMessageHandler();
@@ -1047,7 +1056,7 @@ namespace EVCB_OCPP.WSServer
                 {
                     case "Core":
                         {
-                            confirmResult = profileHandler.ExecuteCoreConfirm(action, session, (IConfirmation)analysisResult.Message, analysisResult.RequestId);
+                            confirmResult = await profileHandler.ExecuteCoreConfirm(action, session, (IConfirmation)analysisResult.Message, analysisResult.RequestId);
                         }
                         break;
                     case "FirmwareManagement":
@@ -1664,13 +1673,7 @@ namespace EVCB_OCPP.WSServer
                         {
                             try
                             {
-                                if (string.IsNullOrEmpty(client.StationLocation))
-                                {
-                                    Console.WriteLine(client.StationLocation + " is empty");
-                                    continue;
-                                }
-
-
+                                if (string.IsNullOrEmpty(client.StationLocation)) continue;
                                 if (TCCStationDic.ContainsKey(client.StationLocation))
                                 {
                                     db.ServerMessage.Add(new ServerMessage()
@@ -1743,29 +1746,73 @@ namespace EVCB_OCPP.WSServer
                             {
 
                                 string displayPriceText = await SetDefaultFee(session);
-                                if (!string.IsNullOrEmpty(displayPriceText) && displayPriceText != session.DisplayPrice)
+                                if (!string.IsNullOrEmpty(displayPriceText))
                                 {
-                                    clientDic[item.Key].DisplayPrice = displayPriceText;
+                                    if (displayPriceText.StartsWith(";"))
+                                        return;
+                                    bool changeChargingPrice = false;
+                                    bool changeParkingPrice = false;
+                                    var displayPrices = displayPriceText.Split(';');
+                                    if (displayPrices[0] != session.DisplayChargingPrice)
+                                    {
+                                        changeChargingPrice = true;
+                                        clientDic[item.Key].DisplayChargingPrice = displayPrices[0];
+                                    }
+
+                                    if (displayPrices[1] != session.DisplayParkingPrice)
+                                    {
+                                        changeParkingPrice = true;
+                                        clientDic[item.Key].DisplayParkingPrice = displayPrices[1];
+                                    }
 
                                     using (var db = new MainDBContext())
                                     {
-                                        db.ServerMessage.Add(new ServerMessage()
+                                        if (changeChargingPrice)
                                         {
-                                            ChargeBoxId = session.ChargeBoxId,
-                                            CreatedBy = "Server",
-                                            CreatedOn = DateTime.UtcNow,
-                                            OutAction = Actions.ChangeConfiguration.ToString(),
-                                            OutRequest = JsonConvert.SerializeObject(
-                                                    new ChangeConfigurationRequest()
+                                            db.ServerMessage.Add(new ServerMessage()
+                                            {
+                                                ChargeBoxId = session.ChargeBoxId,
+                                                CreatedBy = "Server",
+                                                CreatedOn = DateTime.UtcNow,
+                                                OutAction = Actions.ChangeConfiguration.ToString(),
+                                                OutRequest = JsonConvert.SerializeObject(
+                                                   new ChangeConfigurationRequest()
+                                                   {
+                                                       key = "DefaultPrice",
+                                                       value = clientDic[item.Key].DisplayChargingPrice
+                                                   },
+                                                   new JsonSerializerSettings() { NullValueHandling = NullValueHandling.Ignore, Formatting = Formatting.None }),
+                                                SerialNo = Guid.NewGuid().ToString(),
+                                                InMessage = string.Empty
+
+                                            }); ;
+                                        }
+                                        if (changeParkingPrice)
+                                        {
+                                            db.ServerMessage.Add(new ServerMessage()
+                                            {
+                                                ChargeBoxId = session.ChargeBoxId,
+                                                CreatedBy = "Server",
+                                                CreatedOn = DateTime.UtcNow,
+                                                OutAction = Actions.DataTransfer.ToString(),
+                                                OutRequest = JsonConvert.SerializeObject(
+                                                new DataTransferRequest()
+                                                {
+                                                    messageId = "ID_SetOccupancyPrice",
+                                                    vendorId = "Phihong Technology",
+                                                    data = JsonConvert.SerializeObject(new
                                                     {
-                                                        key = "DefaultPrice",
-                                                        value = clientDic[item.Key].DisplayPrice
-                                                    },
-                                                    new JsonSerializerSettings() { NullValueHandling = NullValueHandling.Ignore, Formatting = Formatting.None }),
-                                            SerialNo = Guid.NewGuid().ToString(),
-                                            InMessage = string.Empty
+                                                        price = Convert.ToDouble(session.DisplayParkingPrice)
 
-                                        }); ;
+                                                    })
+
+                                                },
+                                                new JsonSerializerSettings() { NullValueHandling = NullValueHandling.Ignore, Formatting = Formatting.None }),
+                                                SerialNo = Guid.NewGuid().ToString(),
+                                                InMessage = string.Empty
+
+                                            });
+                                        }
 
                                         if (session.CustomerId == new Guid("10C7F5BD-C89A-4E2A-8611-B617E0B41A73"))
                                         {
@@ -1876,7 +1923,7 @@ namespace EVCB_OCPP.WSServer
                         }
                     }
 
-                    displayPriceText = stationPrice.FeeName;
+                    displayPriceText = string.Format("{0};{1}", stationPrice.FeeName, stationPrice.ParkingFee);
                     client.BillingMethod = stationPrice.BillingMethod;
                     client.Currency = stationPrice.Currency;
                     client.ChargingFeebyHour = stationPrice.ChargingFeebyHour;
@@ -1973,7 +2020,7 @@ namespace EVCB_OCPP.WSServer
                 foreach (var item in removeList)
                 {
                     needConfirmPacketList.Remove(item);
-                }               
+                }
             }
         }
 

+ 1 - 1
EVCB_OCPP.WSServer/Service/BusinessServiceFactory.cs

@@ -14,7 +14,7 @@ namespace EVCB_OCPP.WSServer.Service
 
         Task NotifyFaultStatus(ErrorDetails details);
 
-        Task NotifyConnectorUnplugged(string chargeBoxId,string data);
+        Task NotifyConnectorUnplugged(string chargeBoxId,string transactionId,string timestamp);
 
     }
 

+ 1 - 1
EVCB_OCPP.WSServer/Service/LocalBusinessService.cs

@@ -78,7 +78,7 @@ namespace EVCB_OCPP.WSServer.Service
 
         }
 
-        async public Task NotifyConnectorUnplugged(string chargeBoxId, string data)
+        async public Task NotifyConnectorUnplugged(string chargeBoxId, string transactionId, string timestamp)
         {
             await Task.Delay(10);
         }

+ 7 - 9
EVCB_OCPP.WSServer/Service/OuterBusinessService.cs

@@ -150,27 +150,25 @@ namespace EVCB_OCPP.WSServer.Service
 
         }
 
-        async public Task NotifyConnectorUnplugged(string chargeBoxId, string data)
+        async public Task NotifyConnectorUnplugged(string chargeBoxId, string transactionId, string timestamp)
         {
             try
             {
-                JObject jo = JObject.Parse(data);
+                var details = new { ChargeBoxId = chargeBoxId, SessionId = transactionId, Timestamp = timestamp };
+                logger.Debug("NotifyConnectorUnplugged: " + JsonConvert.SerializeObject(details));
 
-                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);
+                            }, details, signMaterial.SaltKey).ConfigureAwait(false);
 
 
+                    
+                    logger.Debug( JsonConvert.SerializeObject(response));
                 }
 
 

+ 62 - 0
EVCB_OCPP.WSServer/Service/SMSService.cs

@@ -0,0 +1,62 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net.Http;
+using System.Text;
+using System.Threading.Tasks;
+using System.Web;
+
+namespace EVCB_OCPP.WSServer.Service
+{
+    public class SMSService
+    {
+       async public Task<string> SendMessage(string phoneNumber, string message)
+        {
+            string errorMsg = string.Empty;
+            int result = 0;
+            try
+            {
+                errorMsg = string.Empty;
+                HttpClient client = new HttpClient();
+                StringBuilder url = new StringBuilder("http://smexpress.mitake.com.tw:7002/SpSendUtf?");
+                url.Append("username=").Append(HttpUtility.UrlEncode("83196607SMS",
+                    Encoding.UTF8));
+                url.Append("&password=").Append(HttpUtility.UrlEncode("83196607SMS@nhoa.tcc",
+                    Encoding.UTF8));
+                url.Append("&encoding=UTF8");
+                url.Append("&dstaddr=").Append(phoneNumber);
+                url.Append("&smbody=").Append(HttpUtility.UrlEncode(message,
+                    Encoding.UTF8).Replace("+", "%20"));
+                url.Append("&CharsetURL=").Append("utf-8");
+
+                var id = await client.GetStringAsync(url.ToString());
+
+                if (!SendResult(id))
+                {
+                    result = -1;
+                    errorMsg = id;
+                }
+            }
+            catch (Exception ex)
+            {
+                result = -1;
+                errorMsg = ex.Message;
+            }
+
+            return errorMsg;
+        }
+
+        private bool SendResult(string response)
+        {
+            bool result = false;
+
+            if (response.Contains("msgid="))
+            {
+                result = true;
+
+            }
+
+            return result;
+        }
+    }
+}

+ 7 - 2
EVCB_OCPP.WSServer/SuperSocket.Protocol/ClientData.cs

@@ -37,9 +37,14 @@ namespace OCPPServer.Protocol
         public List<ChargingPrice> ChargingPrices { set; get; }
 
         /// <summary>
-        /// 電樁顯示費率
+        /// 電樁顯示充電費率
         /// </summary>
-        public string DisplayPrice { set; get; }
+        public string DisplayChargingPrice { set; get; }
+
+        /// <summary>
+        /// 電樁占用費顯示費率
+        /// </summary>
+        public string DisplayParkingPrice { set; get; }
 
         /// <summary>
         /// 充電費率 以小時計費

BIN
SocketCommon/bin/Release/SuperSocket.Common.dll


BIN
SuperWebSocket/bin/Debug/SuperSocket.Common.dll


BIN
SuperWebSocket/bin/Debug/SuperWebSocket.dll


BIN
SuperWebSocket/bin/Debug/SuperWebSocket.pdb