CommonCustomerService.cs 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412
  1. using EVCB_OCPP.TaskScheduler.Models;
  2. using Newtonsoft.Json;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.Diagnostics;
  6. using System.Linq;
  7. using System.Text;
  8. using System.Threading;
  9. using System.Threading.Tasks;
  10. using System.Transactions;
  11. namespace EVCB_OCPP.TaskScheduler.Services
  12. {
  13. public class CommonCustomerService : ICustomerService
  14. {
  15. private NLog.ILogger logger = NLog.LogManager.GetCurrentClassLogger();
  16. private Guid customerId = Guid.Empty;
  17. private string customerName = string.Empty;
  18. private string _partnerAPIRoot = string.Empty;
  19. private string _saltkey = string.Empty;
  20. private CancellationToken _ct;
  21. private DatabaseService _dbService = new DatabaseService();
  22. private ParallelOptions po = new ParallelOptions();
  23. private OuterHttpClient httpClient = new OuterHttpClient();
  24. private int ChargeRecordCallCounter = 0;
  25. public CommonCustomerService() { }
  26. public CommonCustomerService(Guid customerId)
  27. {
  28. this.customerId = customerId;
  29. customerName = _dbService.GetCustomerName(this.customerId);
  30. _dbService.GetCustomerName(this.customerId);
  31. var connectionInfo = _dbService.GetAPIConnectionInfo(customerId);
  32. _saltkey = connectionInfo.ApiKey;
  33. _partnerAPIRoot = connectionInfo.ApiUrl;
  34. }
  35. public List<Guid> GetCallPartnerCustomers()
  36. {
  37. return _dbService.GetCallParterAPICustomers();
  38. }
  39. async public Task ReportStartTransaction()
  40. {
  41. var items = _dbService.GetNeedReportSession(customerId, true, 1000);
  42. Stopwatch watch = new Stopwatch();
  43. watch.Start();
  44. List<Task> groupTasks = new List<Task>();
  45. int skipCount = 0;
  46. int count = items.Count / 5 <= 100 ? items.Count : items.Count / 5;
  47. while (skipCount < items.Count)
  48. {
  49. if (items.Count - skipCount < count)
  50. {
  51. count = items.Count - skipCount;
  52. }
  53. var templst = items.Skip(skipCount).Take(count).ToList();
  54. if (templst.Count > 0)
  55. {
  56. Task t = Task.Factory.StartNew(async () =>
  57. {
  58. await Assigned_StartTransactionCallbackTask(templst);
  59. }, TaskCreationOptions.AttachedToParent);
  60. groupTasks.Add(t);
  61. }
  62. skipCount += count;
  63. }
  64. while (ChargeRecordCallCounter != groupTasks.Count)
  65. {
  66. await Task.Delay(10);
  67. }
  68. watch.Stop();
  69. logger.Debug("ReportStartTransaction Task(" + items.Count() + ") : It takes " + watch.ElapsedMilliseconds / 1000 + " Seconds");
  70. }
  71. async private Task Assigned_StartTransactionCallbackTask(List<Models.Transaction> reportlst)
  72. {
  73. await Task.Factory.StartNew(async () =>
  74. {
  75. //處理主機傳送的有指令
  76. try
  77. {
  78. if (reportlst.Count > 0)
  79. {
  80. int completecounter = 0;
  81. Dictionary<int, TransactionResponse> sendBack = new Dictionary<int, TransactionResponse>();
  82. object responseLock = new object();
  83. po.CancellationToken = _ct;
  84. po.MaxDegreeOfParallelism = System.Environment.ProcessorCount;
  85. Parallel.ForEach(reportlst, po, async (r) =>
  86. {
  87. var request = new
  88. {
  89. ChargeBoxId = r.ChargeBoxId,
  90. ConnectorId = r.ConnectorId,
  91. SessionId = r.Id,
  92. MeterStart = r.MeterStart,
  93. IdTag = r.StartIdTag,
  94. StartTime = r.StartTime.ToString(DefaultSetting.UTC_DATETIMEFORMAT)
  95. };
  96. var response = await httpClient.Post(_partnerAPIRoot + "start_session", new Dictionary<string, string>()
  97. {
  98. { "PartnerId",customerId.ToString()}
  99. }, JsonConvert.SerializeObject(request, DefaultSetting.JSONSERIALIZER_FORMAT), _saltkey);
  100. lock (responseLock)
  101. {
  102. sendBack.Add(r.Id, new TransactionResponse()
  103. {
  104. StartTransactionReportedOn = DateTime.Now,
  105. ErrorMsg = response.Success ? null :
  106. (response.Exception == null ? response.Response : response.Exception.ToString())
  107. });
  108. completecounter++;
  109. }
  110. });
  111. while (completecounter != reportlst.Count)
  112. {
  113. await Task.Delay(10);
  114. }
  115. _dbService.ReportStartTx(sendBack);
  116. }
  117. }
  118. catch (Exception ex)
  119. {
  120. Console.WriteLine("Assigned_StartTransactionCallbackTask Exception: " + ex.GetBaseException().ToString());
  121. }
  122. ChargeRecordCallCounter++;
  123. }, TaskCreationOptions.AttachedToParent);
  124. }
  125. async public Task ReportStopTransaction()
  126. {
  127. var items = _dbService.GetNeedReportSession(customerId, false, 1000);
  128. Stopwatch watch = new Stopwatch();
  129. watch.Start();
  130. List<Task> groupTasks = new List<Task>();
  131. int skipCount = 0;
  132. int count = items.Count / 5 <= 100 ? items.Count : items.Count / 5;
  133. while (skipCount < items.Count)
  134. {
  135. if (items.Count - skipCount < count)
  136. {
  137. count = items.Count - skipCount;
  138. }
  139. var templst = items.Skip(skipCount).Take(count).ToList();
  140. if (templst.Count > 0)
  141. {
  142. Task t = Task.Factory.StartNew(async () =>
  143. {
  144. await Assigned_StopTransactionCallbackTask(templst);
  145. }, TaskCreationOptions.AttachedToParent);
  146. groupTasks.Add(t);
  147. }
  148. skipCount += count;
  149. }
  150. while (ChargeRecordCallCounter != groupTasks.Count)
  151. {
  152. await Task.Delay(10);
  153. }
  154. watch.Stop();
  155. Console.WriteLine("ReportStopTransaction Task(" + items.Count() + ") : It takes " + watch.ElapsedMilliseconds / 1000 + " Seconds");
  156. }
  157. async private Task Assigned_StopTransactionCallbackTask(List<Models.Transaction> reportlst)
  158. {
  159. await Task.Factory.StartNew(async () =>
  160. {
  161. //處理主機傳送的有指令
  162. try
  163. {
  164. if (reportlst.Count > 0)
  165. {
  166. int completecounter = 0;
  167. Dictionary<int, TransactionResponse> sendBack = new Dictionary<int, TransactionResponse>();
  168. object responseLock = new object();
  169. po.CancellationToken = _ct;
  170. po.MaxDegreeOfParallelism = System.Environment.ProcessorCount;
  171. Parallel.ForEach(reportlst, po, async (r) =>
  172. {
  173. var request = new
  174. {
  175. ChargeBoxId = r.ChargeBoxId,
  176. ConnectorId = r.ConnectorId,
  177. SessionId = r.Id,
  178. MeterStart = r.MeterStart,
  179. MeterStop = r.MeterStop,
  180. IdTag = r.StartIdTag,
  181. StartTime = r.StartTime.ToString(DefaultSetting.UTC_DATETIMEFORMAT),
  182. StopTime = r.StopTime.ToString(DefaultSetting.UTC_DATETIMEFORMAT),
  183. StopReason = r.StopReasonId < 1 ? "Unknown" : (r.StopReasonId > 12 ? "Unknown" : ((Reason)r.StopReasonId).ToString()),
  184. Receipt = r.Receipt,
  185. TotalCost = r.Cost,
  186. Fee = r.Fee
  187. };
  188. var response = await httpClient.Post(_partnerAPIRoot + "completed_session", new Dictionary<string, string>()
  189. {
  190. { "PartnerId",customerId.ToString()}
  191. }, JsonConvert.SerializeObject(request, DefaultSetting.JSONSERIALIZER_FORMAT), _saltkey);
  192. lock (responseLock)
  193. {
  194. sendBack.Add(r.Id, new TransactionResponse()
  195. {
  196. StopTransactionReportedOn = DateTime.Now,
  197. ErrorMsg = response.Success ? null :
  198. (response.Exception == null ? response.Response : response.Exception.ToString())
  199. });
  200. completecounter++;
  201. }
  202. });
  203. while (completecounter != reportlst.Count)
  204. {
  205. await Task.Delay(10);
  206. }
  207. _dbService.ReportStopTx(sendBack);
  208. }
  209. }
  210. catch (Exception ex)
  211. {
  212. Console.WriteLine("Assigned_StartTransactionCallbackTask Exception: " + ex.GetBaseException().ToString());
  213. }
  214. ChargeRecordCallCounter++;
  215. }, TaskCreationOptions.AttachedToParent);
  216. }
  217. async public Task MonitorRemoteCommand()
  218. {
  219. Stopwatch watch = new Stopwatch();
  220. watch.Start();
  221. _dbService.TurntoTimeoutMachineOperateCommands(60);
  222. await Task.Delay(10);
  223. watch.Stop();
  224. logger.Debug("ReportExecutionofRemoteCommand Task : It takes " + watch.ElapsedMilliseconds / 1000 + " Seconds");
  225. }
  226. async public Task ReportExecutionofRemoteCommand()
  227. {
  228. var items = _dbService.GetNeedReportExecution(customerId, 1000);
  229. Stopwatch watch = new Stopwatch();
  230. watch.Start();
  231. List<Task> groupTasks = new List<Task>();
  232. int skipCount = 0;
  233. int count = items.Count / 5 <= 100 ? items.Count : items.Count / 5;
  234. while (skipCount < items.Count)
  235. {
  236. if (items.Count - skipCount < count)
  237. {
  238. count = items.Count - skipCount;
  239. }
  240. var templst = items.Skip(skipCount).Take(count).ToList();
  241. if (templst.Count > 0)
  242. {
  243. Task t = Task.Factory.StartNew(async () =>
  244. {
  245. await Assigned_ReportExecutionofRemoteCommandTask(templst);
  246. }, TaskCreationOptions.AttachedToParent);
  247. groupTasks.Add(t);
  248. }
  249. skipCount += count;
  250. }
  251. while (ChargeRecordCallCounter != groupTasks.Count)
  252. {
  253. await Task.Delay(10);
  254. }
  255. watch.Stop();
  256. logger.Debug("ReportExecutionofRemoteCommand Task(" + items.Count() + ") : It takes " + watch.ElapsedMilliseconds / 1000 + " Seconds");
  257. }
  258. async private Task Assigned_ReportExecutionofRemoteCommandTask(List<MachineOperateRecord> reportlst)
  259. {
  260. await Task.Factory.StartNew(async () =>
  261. {
  262. //處理主機傳送的有指令
  263. try
  264. {
  265. if (reportlst.Count > 0)
  266. {
  267. int completecounter = 0;
  268. Dictionary<int, BasicResponse> sendBack = new Dictionary<int, BasicResponse>();
  269. object responseLock = new object();
  270. po.CancellationToken = _ct;
  271. po.MaxDegreeOfParallelism = System.Environment.ProcessorCount;
  272. Parallel.ForEach(reportlst, po, async (r) =>
  273. {
  274. var request = new
  275. {
  276. ChargeBoxId = r.ChargeBoxId,
  277. SerialNo = r.SerialNo,
  278. CommandType = r.ActionConverttoCommandType(),
  279. Result = r.GetExecution().Result,
  280. Message = r.GetExecution().Detail,
  281. };
  282. var response = await httpClient.Post(_partnerAPIRoot + "commands/results", new Dictionary<string, string>()
  283. {
  284. { "PartnerId",customerId.ToString()}
  285. }, JsonConvert.SerializeObject(request, DefaultSetting.JSONSERIALIZER_FORMAT), _saltkey);
  286. lock (responseLock)
  287. {
  288. sendBack.Add(r.Id, new BasicResponse()
  289. {
  290. ReportedOn = DateTime.Now,
  291. ErrorMsg = response.Success ? null :
  292. (response.Exception == null ? response.Response : response.Exception.ToString())
  293. });
  294. completecounter++;
  295. }
  296. });
  297. while (completecounter != reportlst.Count)
  298. {
  299. await Task.Delay(10);
  300. }
  301. _dbService.ReportExecution(sendBack);
  302. }
  303. }
  304. catch (Exception ex)
  305. {
  306. Console.WriteLine("Assigned_ReportExecutionofRemoteCommandTask Exception: " + ex.GetBaseException().ToString());
  307. }
  308. ChargeRecordCallCounter++;
  309. }, TaskCreationOptions.AttachedToParent);
  310. }
  311. }
  312. }