Bladeren bron

temp commit

Robert 11 maanden geleden
bovenliggende
commit
e9c17f227a

+ 36 - 7
EVCB_OCPP.WSServer/Jobs/ServerMessageJob.cs

@@ -2,12 +2,14 @@
 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.WsService;
 using Microsoft.EntityFrameworkCore;
 using Microsoft.Extensions.Configuration;
 using Microsoft.Extensions.Logging;
+using Microsoft.VisualBasic;
 using Newtonsoft.Json;
 using Quartz;
 using System;
@@ -25,21 +27,21 @@ public class ServerMessageJob : IJob
     public ServerMessageJob(
         ProtalServer protalServer,
         ConfirmWaitingMessageSerevice confirmWaitingMessageSerevice,
-        VendorIdReplaceService vendorIdReplaceService,
+        //VendorIdUpdateService vendorIdReplaceService,
         IConfiguration configuration,
         IDbContextFactory<MainDBContext> maindbContextFactory,
         ILogger<ServerMessageJob> logger)
     {
         this.protalServer = protalServer;
         this.confirmWaitingMessageSerevice = confirmWaitingMessageSerevice;
-        this.vendorIdReplaceService = vendorIdReplaceService;
+        //this.vendorIdUpdateService = vendorIdReplaceService;
         this.maindbContextFactory = maindbContextFactory;
         this.logger = logger;
     }
 
     private readonly ProtalServer protalServer;
     private readonly ConfirmWaitingMessageSerevice confirmWaitingMessageSerevice;
-    private readonly VendorIdReplaceService vendorIdReplaceService;
+    //private readonly VendorIdUpdateService vendorIdUpdateService;
     private readonly IDbContextFactory<MainDBContext> maindbContextFactory;
     private readonly ILogger<ServerMessageJob> logger;
 
@@ -73,6 +75,7 @@ public class ServerMessageJob : IJob
         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())
         {
@@ -84,14 +87,16 @@ public class ServerMessageJob : IJob
         {
             // Console.WriteLine(string.Format("Now:{0} commandList Count:{1} ", DateTime.UtcNow.ToString("yyyy/MM/dd HH:mm:ss"), commandList.Count));
         }
-        foreach (var charger_SN in cmdMachineList)
+        await Parallel.ForEachAsync(cmdMachineList, async (charger_SN, token) => //{  });
+        //foreach (var charger_SN in cmdMachineList)
         {
             WsClientData session;
             string uuid = string.Empty;
 
             if (!clientDic.TryGetValue(charger_SN, out session))
             {
-                continue;
+                //continue;
+                return;
             }
 
             //logger.LogDebug(string.Format("charger_SN:{0} startDt:{1} CreatedOn:{2}", charger_SN, startDt.ToString("yyyy/MM/dd HH:mm:ss"), DateTime.UtcNow.ToString("yyyy/MM/dd HH:mm:ss")));
@@ -99,7 +104,8 @@ public class ServerMessageJob : IJob
             //if (session.IsCheckIn && !session.ISOCPP20)
             if (session.ISOCPP20)
             {
-                continue;
+                //continue;
+                return;
             }
 
             string rawRequest = string.Empty;
@@ -129,6 +135,10 @@ public class ServerMessageJob : IJob
                 if (_RequestType != null && item.CreatedBy != "Destroyer")
                 {
                     request = JsonConvert.DeserializeObject(item.OutRequest, _RequestType) as IRequest;
+                    if (action == Actions.DataTransfer)
+                    {
+                        ReplaceVID(session, action, request);
+                    }
                     uuid = session.queue.store(request);
                     rawRequest = BasicMessageHandler.GenerateRequest(uuid, item.OutAction, request);
                     protalServer.SendMsg(session, rawRequest, string.Format("{0} {1}", action, "Request"), "");
@@ -155,13 +165,16 @@ public class ServerMessageJob : IJob
                     }
                 }
 
-                await confirmWaitingMessageSerevice.Add(charger_SN, item.Id, item.SerialNo, item.OutAction, uuid, item.CreatedBy, rawRequest);
+                var tmpTask = confirmWaitingMessageSerevice.Add(charger_SN, item.Id, item.SerialNo, item.OutAction, uuid, item.CreatedBy, rawRequest);
+                waitTasks.Add(tmpTask);
                 //protalServer.AddConfirmMessage(charger_SN, item.Id, item.SerialNo, item.OutAction, uuid, item.CreatedBy, rawRequest);
 
                 await Task.Delay(100);
 
             }
         }
+        );
+        await Task.WhenAll(waitTasks);
     }
 
     private void ResendServerMessage(Dictionary<string, WsClientData> clientDic)
@@ -183,4 +196,20 @@ public class ServerMessageJob : IJob
 
         }
     }
+
+    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))
+        {
+            return;
+        }
+        dataTransferRequest.vendorId = vid;
+    }
 }

+ 1 - 1
EVCB_OCPP.WSServer/Program.cs

@@ -80,7 +80,7 @@ namespace EVCB_OCPP.WSServer
             app.Urls.Add("http://*:80");
 
             app.InitStationConfigService();
-            app.InitVendorIdReplaceService();
+            //app.InitVendorIdReplaceService();
             app.Run();
             //host.Run();
         }

+ 5 - 1
EVCB_OCPP.WSServer/ProtalServer.cs

@@ -715,8 +715,12 @@ namespace EVCB_OCPP.WSServer
 
                                 Send(session, response, string.Format("{0} {1}", analysisResult.Action, "Confirmation"), replyResult.Exception == null ? string.Empty : replyResult.Exception.ToString());
 
-                                if (action == Actions.BootNotification && replyResult.Message is BootNotificationConfirmation bootNotificationConfirmation)
+                                if (action == Actions.BootNotification && 
+                                    replyResult.Message is BootNotificationConfirmation bootNotificationConfirmation &&
+                                    analysisResult.Message is BootNotificationRequest bootNotificationRequest)
                                 {
+                                    session.ChargePointVendor = bootNotificationRequest.chargePointVendor;
+
                                     if (session.BootStatus == BootStatus.Startup)
                                     {
                                         session.BootStatus = BootStatus.Initializing;

+ 15 - 9
EVCB_OCPP.WSServer/Service/ConfirmWaitingMessageSerevice.cs

@@ -14,6 +14,7 @@ using System.Collections.Generic;
 using System.Linq;
 using System.Text;
 using System.Threading.Tasks;
+using EVCB_OCPP.WSServer.Service.DbService;
 
 namespace EVCB_OCPP.WSServer.Service
 {
@@ -55,9 +56,11 @@ namespace EVCB_OCPP.WSServer.Service
         }
 
         public ConfirmWaitingMessageSerevice(
+            IMainDbService mainDbService,
             IDbContextFactory<MainDBContext> maindbContextFactory
             ,ILogger<ConfirmWaitingMessageSerevice> logger)
         {
+            this.mainDbService = mainDbService;
             this.maindbContextFactory = maindbContextFactory;
             this.logger = logger;
         }
@@ -65,6 +68,7 @@ namespace EVCB_OCPP.WSServer.Service
         public event EventHandler<ConfirmWaitingMessageRemoveReason> OnMessageRemoved;
 
         private readonly Object _lockConfirmPacketList = new object();
+        private readonly IMainDbService mainDbService;
         private readonly IDbContextFactory<MainDBContext> maindbContextFactory;
         private readonly ILogger<ConfirmWaitingMessageSerevice> logger;
         private readonly List<NeedConfirmMessage> needConfirmPacketList = new();
@@ -101,15 +105,17 @@ namespace EVCB_OCPP.WSServer.Service
             //db.Configuration.ValidateOnSaveEnabled = false;// 因為Entity有些欄位必填,若不避開會有Validate錯誤
             // var _UpdatedItem = db.ServerMessage.Where(x => x.Id == item.Id).FirstOrDefault();
 
-            using (var db = await maindbContextFactory.CreateDbContextAsync())
-            {
-                db.ServerMessage.Attach(_UpdatedItem);
-                _UpdatedItem.UpdatedOn = dateTimeNow;
-                db.Entry(_UpdatedItem).Property(x => x.UpdatedOn).IsModified = true;// 可以直接使用這方式強制某欄位要更新,只是查詢集合耗效能而己
+            //using (var db = await maindbContextFactory.CreateDbContextAsync())
+            //{
+            //    db.ServerMessage.Attach(_UpdatedItem);
+            //    _UpdatedItem.UpdatedOn = dateTimeNow;
+            //    db.Entry(_UpdatedItem).Property(x => x.UpdatedOn).IsModified = true;// 可以直接使用這方式強制某欄位要更新,只是查詢集合耗效能而己
 
-                await db.SaveChangesAsync();
-                db.ChangeTracker.Clear();
-            }
+            //    await db.SaveChangesAsync();
+            //    db.ChangeTracker.Clear();
+            //}
+
+            await mainDbService.UpdateServerMessageUpdateTime(table_id);
 
             #endregion
         }
@@ -209,7 +215,7 @@ namespace EVCB_OCPP.WSServer.Service
             var waiObj = new MessageResultWaitObject();
             asyncWaitingTasks.Add(msgId, waiObj);
             var task = waiObj.Lock.WaitAsync(token);
-            var completedTask = await Task.WhenAny(task, Task.Delay(650_000));
+            var completedTask = await Task.WhenAny(task, Task.Delay(180_000));
             return waiObj.Result;
         }
 

+ 43 - 0
EVCB_OCPP.WSServer/Service/DbService/MainDbService.cs

@@ -3,6 +3,7 @@ using EVCB_OCPP.Domain;
 using EVCB_OCPP.Domain.ConnectionFactory;
 using EVCB_OCPP.Domain.Models.MainDb;
 using EVCB_OCPP.WSServer.Helper;
+using Microsoft.AspNetCore.Connections;
 using Microsoft.Data.SqlClient;
 using Microsoft.EntityFrameworkCore;
 using Microsoft.Extensions.Caching.Memory;
@@ -44,6 +45,7 @@ public interface IMainDbService
     Task UpdateMachineConnectionType(string chargeBoxId, int v);
     Task<string> GetMachineConnectorType(string chargeBoxId, CancellationToken token = default);
     Task SetMachineConnectionType(string chargeBoxId, int connectionType, CancellationToken token = default);
+    Task UpdateServerMessageUpdateTime(int table_id);
 }
 
 public class MainDbService : IMainDbService
@@ -71,6 +73,7 @@ public class MainDbService : IMainDbService
         InitUpdateConnectorStatusHandler();
         InitUpdateMachineBasicInfoHandler();
         InitAddServerMessageHandler();
+        InitUpdateServerMessageUpdateOnHandler();
     }
 
     private const string CustomerMemCacheKeyFromat = "Customer_{0}";
@@ -88,6 +91,7 @@ public class MainDbService : IMainDbService
     private GroupHandler<StatusNotificationParam> statusNotificationHandler;
     private GroupHandler<UpdateMachineBasicInfoParam> updateMachineBasicInfoHandler;
     private GroupHandler<ServerMessage> addServerMessageHandler;
+    private GroupHandler<int> updateServerMessageUpdateOnHandler;
 
     public async Task<MachineAndCustomerInfo> GetMachineIdAndCustomerInfo(string ChargeBoxId, CancellationToken token = default)
     {
@@ -327,6 +331,11 @@ public class MainDbService : IMainDbService
         return;
     }
 
+    public Task UpdateServerMessageUpdateTime(int table_id)
+    {
+        return updateServerMessageUpdateOnHandler.HandleAsync(table_id);
+    }
+
     private async Task UpdateTransactionEF(int transactionId, int meterStop, DateTime stopTime, int stopReasonId, string stopReason, string stopIdTag, string receipt, int cost)
     {
         using var db = await contextFactory.CreateDbContextAsync();
@@ -432,6 +441,20 @@ public class MainDbService : IMainDbService
             workerCnt: 10);
     }
 
+    private void InitUpdateServerMessageUpdateOnHandler()
+    {
+        if (updateServerMessageUpdateOnHandler is not null)
+        {
+            throw new Exception($"{nameof(InitUpdateMachineBasicInfoHandler)} should only called once");
+        }
+
+        updateServerMessageUpdateOnHandler = new GroupHandler<int>(
+            handleFunc: BundelUpdateServerMessageUpdateOn,
+            logger: loggerFactory.CreateLogger("UpdateServerMessageUpdateOnHandler"),
+            workerCnt: 10);
+    }
+    
+
     private async Task UpdateMachineBasicInfoEF(string chargeBoxId, Machine machine)
     {
         using var semaphoreWrapper = await startupSemaphore.GetToken();
@@ -480,6 +503,26 @@ public class MainDbService : IMainDbService
         bundleHandlerData.CompletedDatas.AddRange(bundleHandlerData.Datas);
     }
 
+    private async Task BundelUpdateServerMessageUpdateOn(BundleHandlerData<int> bundleHandlerData)
+    {
+        var ids = bundleHandlerData.Datas;
+        var sql = """
+            UPDATE [dbo].[ServerMessage]
+            SET UpdatedOn = @DateTimeNow
+            WHERE Id in @Ids
+            """;
+        DynamicParameters parameters = new DynamicParameters();
+        parameters.Add("DateTimeNow", DateTime.UtcNow, DbType.DateTime);
+        parameters.Add("Ids", ids);
+
+        using SqlConnection sqlConnection = await sqlConnectionFactory.CreateAsync();
+        var cnt = await sqlConnection.ExecuteAsync(sql, parameters);
+        if (cnt != 0 || ids.Count == 0)
+        {
+            bundleHandlerData.CompletedDatas.AddRange(ids);
+        }
+    }
+
     private async Task UpdateConnectorStatusEF(string Id, ConnectorStatus Status)
     {
         using var db = await contextFactory.CreateDbContextAsync();

+ 4 - 1
EVCB_OCPP.WSServer/Service/StationConfigService.cs

@@ -152,8 +152,11 @@ public class StationConfigService
         }
 
         var dbConfigs = stationConfigRecord[stationId];
+        Dictionary<string, string> evseCurrentConfigs = new Dictionary<string, string>();
+        evseCurrentConfigs = confirmation.configurationKey.DistinctBy(x=>x.key).ToDictionary(x => x.key, x => x.value);
+
         await ComparenUpdateConfig(chargeBoxId,
-            evseCurrentConfigs: confirmation.configurationKey.ToDictionary(x => x.key, x => x.value),
+            evseCurrentConfigs: evseCurrentConfigs,
             evseDbConfigs: dbConfigs,
             token);
     }

+ 38 - 10
EVCB_OCPP.WSServer/Service/VendorIdReplaceService.cs → EVCB_OCPP.WSServer/Service/VendorIdUpdateService.cs

@@ -1,4 +1,6 @@
-using EVCB_OCPP.Packet.Messages.Core;
+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.WsService;
 using Microsoft.Extensions.DependencyInjection;
@@ -12,24 +14,24 @@ using System.Threading.Tasks;
 
 namespace EVCB_OCPP.WSServer.Service
 {
-    public static class VendorIdReplaceServiceExt
+    public static class VendorIdUpdateServiceExt
     {
         public static Task InitVendorIdReplaceService(this IHost host)
         {
             var server = host.Services.GetRequiredService<ProtalServer>();
-            var vendorIdReplaceService = host.Services.GetRequiredService<VendorIdReplaceService>();
+            var vendorIdReplaceService = host.Services.GetRequiredService<VendorIdUpdateService>();
             server.InitActions.Add(vendorIdReplaceService.GetAndRecordVendorId);
             return host.Services.GetRequiredService<StationConfigService>().Init();
         }
     }
 
-    internal class VendorIdReplaceService
+    public class VendorIdUpdateService
     {
-        public VendorIdReplaceService(
+        public VendorIdUpdateService(
             ProtalServer protalServer
             , ServerMessageService messageService
             , ConfirmWaitingMessageSerevice confirmWaitingMessageSerevice
-            , ILogger<VendorIdReplaceService> logger
+            , ILogger<VendorIdUpdateService> logger
             )
         {
             this.protalServer = protalServer;
@@ -38,13 +40,12 @@ namespace EVCB_OCPP.WSServer.Service
             this.logger = logger;
         }
 
-
         private static string Session_VID_Key = "StationConfigService_Station";
 
         private readonly ProtalServer protalServer;
         private readonly ServerMessageService messageService;
         private readonly ConfirmWaitingMessageSerevice confirmWaitingMessageSerevice;
-        private readonly ILogger<VendorIdReplaceService> logger;
+        private readonly ILogger<VendorIdUpdateService> logger;
 
         internal async Task GetAndRecordVendorId(WsClientData wsClient, CancellationToken token)
         {
@@ -67,6 +68,22 @@ namespace EVCB_OCPP.WSServer.Service
             SetSessionVendorId(wsClient, vendorId.value);
         }
 
+        internal void ReplaceVID(WsClientData session, Actions action, IRequest request)
+        {
+            if (action != Actions.DataTransfer ||
+                request is not DataTransferRequest dataTransferRequest)
+            {
+                return;
+            }
+
+            string vid = GetSessionVendorId(session);
+            if (string.IsNullOrEmpty(vid))
+            {
+                return;
+            }
+            dataTransferRequest.vendorId = vid;
+        }
+
 
         private async Task<MessageResult> GetEvseCurrentConfig(string chargeBoxId, CancellationToken token = default)
         {
@@ -75,14 +92,25 @@ namespace EVCB_OCPP.WSServer.Service
             return response;
         }
 
-        private int? GetSessionVendorId(WsClientData session)
+        private string GetChargeBoxIdVendorId(string chargeBoxId)
+        {
+            var clients = protalServer.GetClientDic();
+            if (!clients.ContainsKey(chargeBoxId))
+            {
+                return null;
+            }
+            var session = clients[chargeBoxId];
+            return GetSessionVendorId(session);
+        }
+
+        private string GetSessionVendorId(WsClientData session)
         {
             if (session is null ||
                 !session.Data.ContainsKey(Session_VID_Key))
             {
                 return null;
             }
-            return (int?)session.Data[Session_VID_Key];
+            return (string)session.Data[Session_VID_Key];
         }
 
         private void SetSessionVendorId(WsClientData session, string vid)

+ 1 - 0
EVCB_OCPP.WSServer/Service/WsService/WsClientData.cs

@@ -81,6 +81,7 @@ public class WsClientData : WsSession
     #endregion
 
     public string CustomerName { get; set; }
+    public string ChargePointVendor { get; set; }
 
     //public int? StationId { set; get; } = null;
     public Dictionary<string, object> Data = new Dictionary<string, object>();