123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238 |
- using EVCB_OCPP.Domain;
- using EVCB_OCPP.Domain.Models.MainDb;
- using EVCB_OCPP.Packet.Features;
- using EVCB_OCPP.Packet.Messages;
- using EVCB_OCPP.Packet.Messages.Core;
- using EVCB_OCPP.WSServer.Message;
- using EVCB_OCPP.WSServer.Service;
- using EVCB_OCPP.WSServer.Service.DbService;
- using EVCB_OCPP.WSServer.Service.WsService;
- using Microsoft.EntityFrameworkCore;
- using Microsoft.Extensions.Configuration;
- using Microsoft.Extensions.Logging;
- using Microsoft.VisualBasic;
- using Newtonsoft.Json;
- using Quartz;
- using System;
- using System.Collections.Generic;
- using System.Diagnostics;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- namespace EVCB_OCPP.WSServer.Jobs;
- [DisallowConcurrentExecution]
- public class ServerMessageJob : IJob
- {
- public ServerMessageJob(
- ProtalServer protalServer,
- ConfirmWaitingMessageSerevice confirmWaitingMessageSerevice,
- //VendorIdUpdateService vendorIdReplaceService,
- IConfiguration configuration,
- IDbContextFactory<MainDBContext> maindbContextFactory,
- IMainDbService mainDbService,
- ILogger<ServerMessageJob> logger)
- {
- this.protalServer = protalServer;
- this.confirmWaitingMessageSerevice = confirmWaitingMessageSerevice;
-
- this.maindbContextFactory = maindbContextFactory;
- this.mainDbService = mainDbService;
- this.logger = logger;
- }
- private readonly ProtalServer protalServer;
- private readonly ConfirmWaitingMessageSerevice confirmWaitingMessageSerevice;
-
- private readonly IDbContextFactory<MainDBContext> maindbContextFactory;
- private readonly IMainDbService mainDbService;
- private readonly ILogger<ServerMessageJob> logger;
- public async Task Execute(IJobExecutionContext context)
- {
-
- try
- {
- await ExecuteTrigger();
- }
- catch (Exception ex)
- {
- logger.LogError("ServerMessageTrigger Ex:{0}", ex.ToString());
- }
- }
- private Task ExecuteTrigger()
- {
- var clientDic = protalServer.GetClientDic();
- confirmWaitingMessageSerevice.RemoveExpiredConfirmMessage();
- ResendServerMessage(clientDic);
- return SendNewServerMessage(clientDic);
- }
- private async Task SendNewServerMessage(Dictionary<string, WsClientData> clientDic)
- {
- BasicMessageHandler msgAnalyser = new BasicMessageHandler();
- DateTime dateTimeNow = DateTime.UtcNow;
- DateTime startDt = dateTimeNow.AddSeconds(-30);
- DateTime dt = new DateTime(1991, 1, 1);
- DateTime currentTime = dateTimeNow;
- List<ServerMessage> commandList;
- List<Task> waitTasks = new List<Task>();
- using (var db = await maindbContextFactory.CreateDbContextAsync())
- {
- commandList = await db.ServerMessage.Where(c => c.ReceivedOn == dt && c.UpdatedOn == dt && c.CreatedOn >= startDt && c.CreatedOn <= currentTime).AsNoTracking().ToListAsync();
- }
-
- var cmdMachineList = commandList.Select(c => c.ChargeBoxId).Distinct().ToList();
- if (commandList.Count > 0)
- {
-
- }
- Dictionary<WsClientData, List<ServerMessage>> toSendWsClientDataMsgPair =
- commandList
- .GroupBy(x => x.ChargeBoxId)
- .Where(x => clientDic.ContainsKey(x.Key))
- .ToDictionary(x => clientDic[x.Key], x => x.ToList());
- await Parallel.ForEachAsync(toSendWsClientDataMsgPair, async (sendPair, token) =>
-
- {
- WsClientData session = sendPair.Key;
- string charger_SN = session.ChargeBoxId;
- string uuid = string.Empty;
-
- if (session.ISOCPP20)
- {
-
- return;
- }
- string rawRequest = string.Empty;
- List<ServerMessage> cmdList = sendPair.Value;
- var profiles = protalServer.Profiles;
- foreach (var item in cmdList)
- {
- IRequest request = null;
- Actions action = Actions.None;
- Enum.TryParse(item.OutAction, out action);
- Type _RequestType = null;
- for (int i = 0; i < profiles.Count; i++)
- {
- var feature = profiles[i].GetFeaturebyAction(item.OutAction);
- if (feature != null)
- {
- _RequestType = feature.GetRequestType();
- break;
- }
- }
- if (_RequestType != null && item.CreatedBy != "Destroyer")
- {
- request = JsonConvert.DeserializeObject(item.OutRequest, _RequestType) as IRequest;
- if (action == Actions.DataTransfer)
- {
- ReplaceVID(session, action, request);
- }
- if (action == Actions.GetDiagnostics)
- {
- if (!await mainDbService.GetIsEvseDiagnosticsStatusAvalaible(charger_SN))
- {
- using (var db = await maindbContextFactory.CreateDbContextAsync())
- {
- var last = await db.ServerMessage.FirstOrDefaultAsync(x => x.Id == item.Id);
- if (last != null)
- {
- last.ReceivedOn = dateTimeNow;
- }
- await db.SaveChangesAsync();
- }
- await mainDbService.ContinueLastEvseDiagnostic(charger_SN);
- continue;
- }
- }
- uuid = session.queue.store(request);
- rawRequest = BasicMessageHandler.GenerateRequest(uuid, item.OutAction, request);
- protalServer.SendMsg(session, rawRequest, string.Format("{0} {1}", action, "Request"), "");
- }
- if (item.CreatedBy == "Destroyer")
- {
- if (_RequestType != null)
- {
- request = Activator.CreateInstance(_RequestType) as IRequest;
- uuid = session.queue.store(request);
- rawRequest = BasicMessageHandler.GenerateDestroyRequest(uuid, item.OutAction, item.OutRequest);
- protalServer.SendMsg(session, rawRequest, string.Format("{0} {1}", action, "Request"), "");
- }
- else
- {
- rawRequest = BasicMessageHandler.GenerateDestroyRequest(Guid.NewGuid().ToString(), item.OutAction, item.OutRequest);
- protalServer.SendMsg(session, rawRequest, string.Format("{0} {1}", action, "Request"), "");
- }
- }
- var tmpTask = confirmWaitingMessageSerevice.Add(charger_SN, item.Id, item.SerialNo, item.OutAction, uuid, item.CreatedBy, rawRequest);
- waitTasks.Add(tmpTask);
-
- await Task.Delay(100);
- }
- }
- );
- await Task.WhenAll(waitTasks);
- }
- private void ResendServerMessage(Dictionary<string, WsClientData> clientDic)
- {
- DateTime dateTimeNow = DateTime.UtcNow;
- List<NeedConfirmMessage> resendList = confirmWaitingMessageSerevice.GetPendingMessages();
- foreach (var resendItem in resendList)
- {
- WsClientData session;
- if (clientDic.TryGetValue(resendItem.ChargePointSerialNumber, out session))
- {
- if (dateTimeNow.Subtract(resendItem.SentOn).TotalSeconds > 1)
- {
- confirmWaitingMessageSerevice.SignalMessageSended(resendItem);
- protalServer.SendMsg(session, resendItem.SentMessage, string.Format("{0} {1}", resendItem.SentAction, "Request"), "");
- }
- }
- }
- }
- private void ReplaceVID(WsClientData session, Actions action, IRequest request)
- {
- if (action != Actions.DataTransfer ||
- request is not DataTransferRequest dataTransferRequest)
- {
- return;
- }
- string vid = session.ChargePointVendor;
- if (string.IsNullOrEmpty(vid))
- {
- dataTransferRequest.vendorId = string.Empty;
- return;
- }
- dataTransferRequest.vendorId = vid;
- }
- }
|