using EVCB_OCPP.TaskScheduler.Models; using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Transactions; namespace EVCB_OCPP.TaskScheduler.Services { public class CommonCustomerService : ICustomerService { private NLog.ILogger logger = NLog.LogManager.GetCurrentClassLogger(); private Guid customerId = Guid.Empty; private string customerName = string.Empty; private string _partnerAPIRoot = string.Empty; private string _saltkey = string.Empty; private CancellationToken _ct; private DatabaseService _dbService = new DatabaseService(); private ParallelOptions po = new ParallelOptions(); private OuterHttpClient httpClient = new OuterHttpClient(); private int ChargeRecordCallCounter = 0; public CommonCustomerService() { } public CommonCustomerService(Guid customerId) { this.customerId = customerId; customerName = _dbService.GetCustomerName(this.customerId); _dbService.GetCustomerName(this.customerId); var connectionInfo = _dbService.GetAPIConnectionInfo(customerId); _saltkey = connectionInfo.ApiKey; _partnerAPIRoot = connectionInfo.ApiUrl; } public List GetCallPartnerCustomers() { return _dbService.GetCallParterAPICustomers(); } async public Task ReportStartTransaction() { var items = _dbService.GetNeedReportSession(customerId, true, 1000); Stopwatch watch = new Stopwatch(); watch.Start(); List groupTasks = new List(); int skipCount = 0; int count = items.Count / 5 <= 100 ? items.Count : items.Count / 5; while (skipCount < items.Count) { if (items.Count - skipCount < count) { count = items.Count - skipCount; } var templst = items.Skip(skipCount).Take(count).ToList(); if (templst.Count > 0) { Task t = Task.Factory.StartNew(async () => { await Assigned_StartTransactionCallbackTask(templst); }, TaskCreationOptions.AttachedToParent); groupTasks.Add(t); } skipCount += count; } while (ChargeRecordCallCounter != groupTasks.Count) { await Task.Delay(10); } watch.Stop(); logger.Debug("ReportStartTransaction Task(" + items.Count() + ") : It takes " + watch.ElapsedMilliseconds / 1000 + " Seconds"); } async private Task Assigned_StartTransactionCallbackTask(List reportlst) { await Task.Factory.StartNew(async () => { //處理主機傳送的有指令 try { if (reportlst.Count > 0) { int completecounter = 0; Dictionary sendBack = new Dictionary(); object responseLock = new object(); po.CancellationToken = _ct; po.MaxDegreeOfParallelism = System.Environment.ProcessorCount; Parallel.ForEach(reportlst, po, async (r) => { var request = new { ChargeBoxId = r.ChargeBoxId, ConnectorId = r.ConnectorId, SessionId = r.Id, MeterStart = r.MeterStart, IdTag = r.StartIdTag, StartTime = r.StartTime.ToString(DefaultSetting.UTC_DATETIMEFORMAT) }; var response = await httpClient.Post(_partnerAPIRoot + "start_session", new Dictionary() { { "PartnerId",customerId.ToString()} }, JsonConvert.SerializeObject(request, DefaultSetting.JSONSERIALIZER_FORMAT), _saltkey); lock (responseLock) { sendBack.Add(r.Id, new TransactionResponse() { StartTransactionReportedOn = DateTime.Now, ErrorMsg = response.Success ? null : (response.Exception == null ? response.Response : response.Exception.ToString()) }); completecounter++; } }); while (completecounter != reportlst.Count) { await Task.Delay(10); } _dbService.ReportStartTx(sendBack); } } catch (Exception ex) { Console.WriteLine("Assigned_StartTransactionCallbackTask Exception: " + ex.GetBaseException().ToString()); } ChargeRecordCallCounter++; }, TaskCreationOptions.AttachedToParent); } async public Task ReportStopTransaction() { var items = _dbService.GetNeedReportSession(customerId, false, 1000); Stopwatch watch = new Stopwatch(); watch.Start(); List groupTasks = new List(); int skipCount = 0; int count = items.Count / 5 <= 100 ? items.Count : items.Count / 5; while (skipCount < items.Count) { if (items.Count - skipCount < count) { count = items.Count - skipCount; } var templst = items.Skip(skipCount).Take(count).ToList(); if (templst.Count > 0) { Task t = Task.Factory.StartNew(async () => { await Assigned_StopTransactionCallbackTask(templst); }, TaskCreationOptions.AttachedToParent); groupTasks.Add(t); } skipCount += count; } while (ChargeRecordCallCounter != groupTasks.Count) { await Task.Delay(10); } watch.Stop(); Console.WriteLine("ReportStopTransaction Task(" + items.Count() + ") : It takes " + watch.ElapsedMilliseconds / 1000 + " Seconds"); } async private Task Assigned_StopTransactionCallbackTask(List reportlst) { await Task.Factory.StartNew(async () => { //處理主機傳送的有指令 try { if (reportlst.Count > 0) { int completecounter = 0; Dictionary sendBack = new Dictionary(); object responseLock = new object(); po.CancellationToken = _ct; po.MaxDegreeOfParallelism = System.Environment.ProcessorCount; Parallel.ForEach(reportlst, po, async (r) => { var request = new { ChargeBoxId = r.ChargeBoxId, ConnectorId = r.ConnectorId, SessionId = r.Id, MeterStart = r.MeterStart, MeterStop = r.MeterStop, IdTag = r.StartIdTag, StartTime = r.StartTime.ToString(DefaultSetting.UTC_DATETIMEFORMAT), StopTime = r.StopTime.ToString(DefaultSetting.UTC_DATETIMEFORMAT), StopReason = r.StopReasonId < 1 ? "Unknown" : (r.StopReasonId > 12 ? "Unknown" : ((Reason)r.StopReasonId).ToString()), Receipt = r.Receipt, TotalCost = r.Cost, Fee = r.Fee }; var response = await httpClient.Post(_partnerAPIRoot + "completed_session", new Dictionary() { { "PartnerId",customerId.ToString()} }, JsonConvert.SerializeObject(request, DefaultSetting.JSONSERIALIZER_FORMAT), _saltkey); lock (responseLock) { sendBack.Add(r.Id, new TransactionResponse() { StopTransactionReportedOn = DateTime.Now, ErrorMsg = response.Success ? null : (response.Exception == null ? response.Response : response.Exception.ToString()) }); completecounter++; } }); while (completecounter != reportlst.Count) { await Task.Delay(10); } _dbService.ReportStopTx(sendBack); } } catch (Exception ex) { Console.WriteLine("Assigned_StartTransactionCallbackTask Exception: " + ex.GetBaseException().ToString()); } ChargeRecordCallCounter++; }, TaskCreationOptions.AttachedToParent); } async public Task MonitorRemoteCommand() { Stopwatch watch = new Stopwatch(); watch.Start(); _dbService.TurntoTimeoutMachineOperateCommands(60); await Task.Delay(10); watch.Stop(); logger.Debug("ReportExecutionofRemoteCommand Task : It takes " + watch.ElapsedMilliseconds / 1000 + " Seconds"); } async public Task ReportExecutionofRemoteCommand() { var items = _dbService.GetNeedReportExecution(customerId, 1000); Stopwatch watch = new Stopwatch(); watch.Start(); List groupTasks = new List(); int skipCount = 0; int count = items.Count / 5 <= 100 ? items.Count : items.Count / 5; while (skipCount < items.Count) { if (items.Count - skipCount < count) { count = items.Count - skipCount; } var templst = items.Skip(skipCount).Take(count).ToList(); if (templst.Count > 0) { Task t = Task.Factory.StartNew(async () => { await Assigned_ReportExecutionofRemoteCommandTask(templst); }, TaskCreationOptions.AttachedToParent); groupTasks.Add(t); } skipCount += count; } while (ChargeRecordCallCounter != groupTasks.Count) { await Task.Delay(10); } watch.Stop(); logger.Debug("ReportExecutionofRemoteCommand Task(" + items.Count() + ") : It takes " + watch.ElapsedMilliseconds / 1000 + " Seconds"); } async private Task Assigned_ReportExecutionofRemoteCommandTask(List reportlst) { await Task.Factory.StartNew(async () => { //處理主機傳送的有指令 try { if (reportlst.Count > 0) { int completecounter = 0; Dictionary sendBack = new Dictionary(); object responseLock = new object(); po.CancellationToken = _ct; po.MaxDegreeOfParallelism = System.Environment.ProcessorCount; Parallel.ForEach(reportlst, po, async (r) => { var request = new { ChargeBoxId = r.ChargeBoxId, SerialNo = r.SerialNo, CommandType = r.ActionConverttoCommandType(), Result = r.GetExecution().Result, Message = r.GetExecution().Detail, }; var response = await httpClient.Post(_partnerAPIRoot + "commands/results", new Dictionary() { { "PartnerId",customerId.ToString()} }, JsonConvert.SerializeObject(request, DefaultSetting.JSONSERIALIZER_FORMAT), _saltkey); lock (responseLock) { sendBack.Add(r.Id, new BasicResponse() { ReportedOn = DateTime.Now, ErrorMsg = response.Success ? null : (response.Exception == null ? response.Response : response.Exception.ToString()) }); completecounter++; } }); while (completecounter != reportlst.Count) { await Task.Delay(10); } _dbService.ReportExecution(sendBack); } } catch (Exception ex) { Console.WriteLine("Assigned_ReportExecutionofRemoteCommandTask Exception: " + ex.GetBaseException().ToString()); } ChargeRecordCallCounter++; }, TaskCreationOptions.AttachedToParent); } } }