Jelajahi Sumber

temp commit

Robert 11 bulan lalu
induk
melakukan
e9c17f227a

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

@@ -2,12 +2,14 @@
 using EVCB_OCPP.Domain.Models.MainDb;
 using EVCB_OCPP.Domain.Models.MainDb;
 using EVCB_OCPP.Packet.Features;
 using EVCB_OCPP.Packet.Features;
 using EVCB_OCPP.Packet.Messages;
 using EVCB_OCPP.Packet.Messages;
+using EVCB_OCPP.Packet.Messages.Core;
 using EVCB_OCPP.WSServer.Message;
 using EVCB_OCPP.WSServer.Message;
 using EVCB_OCPP.WSServer.Service;
 using EVCB_OCPP.WSServer.Service;
 using EVCB_OCPP.WSServer.Service.WsService;
 using EVCB_OCPP.WSServer.Service.WsService;
 using Microsoft.EntityFrameworkCore;
 using Microsoft.EntityFrameworkCore;
 using Microsoft.Extensions.Configuration;
 using Microsoft.Extensions.Configuration;
 using Microsoft.Extensions.Logging;
 using Microsoft.Extensions.Logging;
+using Microsoft.VisualBasic;
 using Newtonsoft.Json;
 using Newtonsoft.Json;
 using Quartz;
 using Quartz;
 using System;
 using System;
@@ -25,21 +27,21 @@ public class ServerMessageJob : IJob
     public ServerMessageJob(
     public ServerMessageJob(
         ProtalServer protalServer,
         ProtalServer protalServer,
         ConfirmWaitingMessageSerevice confirmWaitingMessageSerevice,
         ConfirmWaitingMessageSerevice confirmWaitingMessageSerevice,
-        VendorIdReplaceService vendorIdReplaceService,
+        //VendorIdUpdateService vendorIdReplaceService,
         IConfiguration configuration,
         IConfiguration configuration,
         IDbContextFactory<MainDBContext> maindbContextFactory,
         IDbContextFactory<MainDBContext> maindbContextFactory,
         ILogger<ServerMessageJob> logger)
         ILogger<ServerMessageJob> logger)
     {
     {
         this.protalServer = protalServer;
         this.protalServer = protalServer;
         this.confirmWaitingMessageSerevice = confirmWaitingMessageSerevice;
         this.confirmWaitingMessageSerevice = confirmWaitingMessageSerevice;
-        this.vendorIdReplaceService = vendorIdReplaceService;
+        //this.vendorIdUpdateService = vendorIdReplaceService;
         this.maindbContextFactory = maindbContextFactory;
         this.maindbContextFactory = maindbContextFactory;
         this.logger = logger;
         this.logger = logger;
     }
     }
 
 
     private readonly ProtalServer protalServer;
     private readonly ProtalServer protalServer;
     private readonly ConfirmWaitingMessageSerevice confirmWaitingMessageSerevice;
     private readonly ConfirmWaitingMessageSerevice confirmWaitingMessageSerevice;
-    private readonly VendorIdReplaceService vendorIdReplaceService;
+    //private readonly VendorIdUpdateService vendorIdUpdateService;
     private readonly IDbContextFactory<MainDBContext> maindbContextFactory;
     private readonly IDbContextFactory<MainDBContext> maindbContextFactory;
     private readonly ILogger<ServerMessageJob> logger;
     private readonly ILogger<ServerMessageJob> logger;
 
 
@@ -73,6 +75,7 @@ public class ServerMessageJob : IJob
         DateTime dt = new DateTime(1991, 1, 1);
         DateTime dt = new DateTime(1991, 1, 1);
         DateTime currentTime = dateTimeNow;
         DateTime currentTime = dateTimeNow;
         List<ServerMessage> commandList;
         List<ServerMessage> commandList;
+        List<Task> waitTasks = new List<Task>();
 
 
         using (var db = await maindbContextFactory.CreateDbContextAsync())
         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));
             // 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;
             WsClientData session;
             string uuid = string.Empty;
             string uuid = string.Empty;
 
 
             if (!clientDic.TryGetValue(charger_SN, out session))
             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")));
             //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.IsCheckIn && !session.ISOCPP20)
             if (session.ISOCPP20)
             if (session.ISOCPP20)
             {
             {
-                continue;
+                //continue;
+                return;
             }
             }
 
 
             string rawRequest = string.Empty;
             string rawRequest = string.Empty;
@@ -129,6 +135,10 @@ public class ServerMessageJob : IJob
                 if (_RequestType != null && item.CreatedBy != "Destroyer")
                 if (_RequestType != null && item.CreatedBy != "Destroyer")
                 {
                 {
                     request = JsonConvert.DeserializeObject(item.OutRequest, _RequestType) as IRequest;
                     request = JsonConvert.DeserializeObject(item.OutRequest, _RequestType) as IRequest;
+                    if (action == Actions.DataTransfer)
+                    {
+                        ReplaceVID(session, action, request);
+                    }
                     uuid = session.queue.store(request);
                     uuid = session.queue.store(request);
                     rawRequest = BasicMessageHandler.GenerateRequest(uuid, item.OutAction, request);
                     rawRequest = BasicMessageHandler.GenerateRequest(uuid, item.OutAction, request);
                     protalServer.SendMsg(session, rawRequest, string.Format("{0} {1}", action, "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);
                 //protalServer.AddConfirmMessage(charger_SN, item.Id, item.SerialNo, item.OutAction, uuid, item.CreatedBy, rawRequest);
 
 
                 await Task.Delay(100);
                 await Task.Delay(100);
 
 
             }
             }
         }
         }
+        );
+        await Task.WhenAll(waitTasks);
     }
     }
 
 
     private void ResendServerMessage(Dictionary<string, WsClientData> clientDic)
     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.Urls.Add("http://*:80");
 
 
             app.InitStationConfigService();
             app.InitStationConfigService();
-            app.InitVendorIdReplaceService();
+            //app.InitVendorIdReplaceService();
             app.Run();
             app.Run();
             //host.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());
                                 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)
                                     if (session.BootStatus == BootStatus.Startup)
                                     {
                                     {
                                         session.BootStatus = BootStatus.Initializing;
                                         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.Linq;
 using System.Text;
 using System.Text;
 using System.Threading.Tasks;
 using System.Threading.Tasks;
+using EVCB_OCPP.WSServer.Service.DbService;
 
 
 namespace EVCB_OCPP.WSServer.Service
 namespace EVCB_OCPP.WSServer.Service
 {
 {
@@ -55,9 +56,11 @@ namespace EVCB_OCPP.WSServer.Service
         }
         }
 
 
         public ConfirmWaitingMessageSerevice(
         public ConfirmWaitingMessageSerevice(
+            IMainDbService mainDbService,
             IDbContextFactory<MainDBContext> maindbContextFactory
             IDbContextFactory<MainDBContext> maindbContextFactory
             ,ILogger<ConfirmWaitingMessageSerevice> logger)
             ,ILogger<ConfirmWaitingMessageSerevice> logger)
         {
         {
+            this.mainDbService = mainDbService;
             this.maindbContextFactory = maindbContextFactory;
             this.maindbContextFactory = maindbContextFactory;
             this.logger = logger;
             this.logger = logger;
         }
         }
@@ -65,6 +68,7 @@ namespace EVCB_OCPP.WSServer.Service
         public event EventHandler<ConfirmWaitingMessageRemoveReason> OnMessageRemoved;
         public event EventHandler<ConfirmWaitingMessageRemoveReason> OnMessageRemoved;
 
 
         private readonly Object _lockConfirmPacketList = new object();
         private readonly Object _lockConfirmPacketList = new object();
+        private readonly IMainDbService mainDbService;
         private readonly IDbContextFactory<MainDBContext> maindbContextFactory;
         private readonly IDbContextFactory<MainDBContext> maindbContextFactory;
         private readonly ILogger<ConfirmWaitingMessageSerevice> logger;
         private readonly ILogger<ConfirmWaitingMessageSerevice> logger;
         private readonly List<NeedConfirmMessage> needConfirmPacketList = new();
         private readonly List<NeedConfirmMessage> needConfirmPacketList = new();
@@ -101,15 +105,17 @@ namespace EVCB_OCPP.WSServer.Service
             //db.Configuration.ValidateOnSaveEnabled = false;// 因為Entity有些欄位必填,若不避開會有Validate錯誤
             //db.Configuration.ValidateOnSaveEnabled = false;// 因為Entity有些欄位必填,若不避開會有Validate錯誤
             // var _UpdatedItem = db.ServerMessage.Where(x => x.Id == item.Id).FirstOrDefault();
             // 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
             #endregion
         }
         }
@@ -209,7 +215,7 @@ namespace EVCB_OCPP.WSServer.Service
             var waiObj = new MessageResultWaitObject();
             var waiObj = new MessageResultWaitObject();
             asyncWaitingTasks.Add(msgId, waiObj);
             asyncWaitingTasks.Add(msgId, waiObj);
             var task = waiObj.Lock.WaitAsync(token);
             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;
             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.ConnectionFactory;
 using EVCB_OCPP.Domain.Models.MainDb;
 using EVCB_OCPP.Domain.Models.MainDb;
 using EVCB_OCPP.WSServer.Helper;
 using EVCB_OCPP.WSServer.Helper;
+using Microsoft.AspNetCore.Connections;
 using Microsoft.Data.SqlClient;
 using Microsoft.Data.SqlClient;
 using Microsoft.EntityFrameworkCore;
 using Microsoft.EntityFrameworkCore;
 using Microsoft.Extensions.Caching.Memory;
 using Microsoft.Extensions.Caching.Memory;
@@ -44,6 +45,7 @@ public interface IMainDbService
     Task UpdateMachineConnectionType(string chargeBoxId, int v);
     Task UpdateMachineConnectionType(string chargeBoxId, int v);
     Task<string> GetMachineConnectorType(string chargeBoxId, CancellationToken token = default);
     Task<string> GetMachineConnectorType(string chargeBoxId, CancellationToken token = default);
     Task SetMachineConnectionType(string chargeBoxId, int connectionType, CancellationToken token = default);
     Task SetMachineConnectionType(string chargeBoxId, int connectionType, CancellationToken token = default);
+    Task UpdateServerMessageUpdateTime(int table_id);
 }
 }
 
 
 public class MainDbService : IMainDbService
 public class MainDbService : IMainDbService
@@ -71,6 +73,7 @@ public class MainDbService : IMainDbService
         InitUpdateConnectorStatusHandler();
         InitUpdateConnectorStatusHandler();
         InitUpdateMachineBasicInfoHandler();
         InitUpdateMachineBasicInfoHandler();
         InitAddServerMessageHandler();
         InitAddServerMessageHandler();
+        InitUpdateServerMessageUpdateOnHandler();
     }
     }
 
 
     private const string CustomerMemCacheKeyFromat = "Customer_{0}";
     private const string CustomerMemCacheKeyFromat = "Customer_{0}";
@@ -88,6 +91,7 @@ public class MainDbService : IMainDbService
     private GroupHandler<StatusNotificationParam> statusNotificationHandler;
     private GroupHandler<StatusNotificationParam> statusNotificationHandler;
     private GroupHandler<UpdateMachineBasicInfoParam> updateMachineBasicInfoHandler;
     private GroupHandler<UpdateMachineBasicInfoParam> updateMachineBasicInfoHandler;
     private GroupHandler<ServerMessage> addServerMessageHandler;
     private GroupHandler<ServerMessage> addServerMessageHandler;
+    private GroupHandler<int> updateServerMessageUpdateOnHandler;
 
 
     public async Task<MachineAndCustomerInfo> GetMachineIdAndCustomerInfo(string ChargeBoxId, CancellationToken token = default)
     public async Task<MachineAndCustomerInfo> GetMachineIdAndCustomerInfo(string ChargeBoxId, CancellationToken token = default)
     {
     {
@@ -327,6 +331,11 @@ public class MainDbService : IMainDbService
         return;
         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)
     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();
         using var db = await contextFactory.CreateDbContextAsync();
@@ -432,6 +441,20 @@ public class MainDbService : IMainDbService
             workerCnt: 10);
             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)
     private async Task UpdateMachineBasicInfoEF(string chargeBoxId, Machine machine)
     {
     {
         using var semaphoreWrapper = await startupSemaphore.GetToken();
         using var semaphoreWrapper = await startupSemaphore.GetToken();
@@ -480,6 +503,26 @@ public class MainDbService : IMainDbService
         bundleHandlerData.CompletedDatas.AddRange(bundleHandlerData.Datas);
         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)
     private async Task UpdateConnectorStatusEF(string Id, ConnectorStatus Status)
     {
     {
         using var db = await contextFactory.CreateDbContextAsync();
         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];
         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,
         await ComparenUpdateConfig(chargeBoxId,
-            evseCurrentConfigs: confirmation.configurationKey.ToDictionary(x => x.key, x => x.value),
+            evseCurrentConfigs: evseCurrentConfigs,
             evseDbConfigs: dbConfigs,
             evseDbConfigs: dbConfigs,
             token);
             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.Message;
 using EVCB_OCPP.WSServer.Service.WsService;
 using EVCB_OCPP.WSServer.Service.WsService;
 using Microsoft.Extensions.DependencyInjection;
 using Microsoft.Extensions.DependencyInjection;
@@ -12,24 +14,24 @@ using System.Threading.Tasks;
 
 
 namespace EVCB_OCPP.WSServer.Service
 namespace EVCB_OCPP.WSServer.Service
 {
 {
-    public static class VendorIdReplaceServiceExt
+    public static class VendorIdUpdateServiceExt
     {
     {
         public static Task InitVendorIdReplaceService(this IHost host)
         public static Task InitVendorIdReplaceService(this IHost host)
         {
         {
             var server = host.Services.GetRequiredService<ProtalServer>();
             var server = host.Services.GetRequiredService<ProtalServer>();
-            var vendorIdReplaceService = host.Services.GetRequiredService<VendorIdReplaceService>();
+            var vendorIdReplaceService = host.Services.GetRequiredService<VendorIdUpdateService>();
             server.InitActions.Add(vendorIdReplaceService.GetAndRecordVendorId);
             server.InitActions.Add(vendorIdReplaceService.GetAndRecordVendorId);
             return host.Services.GetRequiredService<StationConfigService>().Init();
             return host.Services.GetRequiredService<StationConfigService>().Init();
         }
         }
     }
     }
 
 
-    internal class VendorIdReplaceService
+    public class VendorIdUpdateService
     {
     {
-        public VendorIdReplaceService(
+        public VendorIdUpdateService(
             ProtalServer protalServer
             ProtalServer protalServer
             , ServerMessageService messageService
             , ServerMessageService messageService
             , ConfirmWaitingMessageSerevice confirmWaitingMessageSerevice
             , ConfirmWaitingMessageSerevice confirmWaitingMessageSerevice
-            , ILogger<VendorIdReplaceService> logger
+            , ILogger<VendorIdUpdateService> logger
             )
             )
         {
         {
             this.protalServer = protalServer;
             this.protalServer = protalServer;
@@ -38,13 +40,12 @@ namespace EVCB_OCPP.WSServer.Service
             this.logger = logger;
             this.logger = logger;
         }
         }
 
 
-
         private static string Session_VID_Key = "StationConfigService_Station";
         private static string Session_VID_Key = "StationConfigService_Station";
 
 
         private readonly ProtalServer protalServer;
         private readonly ProtalServer protalServer;
         private readonly ServerMessageService messageService;
         private readonly ServerMessageService messageService;
         private readonly ConfirmWaitingMessageSerevice confirmWaitingMessageSerevice;
         private readonly ConfirmWaitingMessageSerevice confirmWaitingMessageSerevice;
-        private readonly ILogger<VendorIdReplaceService> logger;
+        private readonly ILogger<VendorIdUpdateService> logger;
 
 
         internal async Task GetAndRecordVendorId(WsClientData wsClient, CancellationToken token)
         internal async Task GetAndRecordVendorId(WsClientData wsClient, CancellationToken token)
         {
         {
@@ -67,6 +68,22 @@ namespace EVCB_OCPP.WSServer.Service
             SetSessionVendorId(wsClient, vendorId.value);
             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)
         private async Task<MessageResult> GetEvseCurrentConfig(string chargeBoxId, CancellationToken token = default)
         {
         {
@@ -75,14 +92,25 @@ namespace EVCB_OCPP.WSServer.Service
             return response;
             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 ||
             if (session is null ||
                 !session.Data.ContainsKey(Session_VID_Key))
                 !session.Data.ContainsKey(Session_VID_Key))
             {
             {
                 return null;
                 return null;
             }
             }
-            return (int?)session.Data[Session_VID_Key];
+            return (string)session.Data[Session_VID_Key];
         }
         }
 
 
         private void SetSessionVendorId(WsClientData session, string vid)
         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
     #endregion
 
 
     public string CustomerName { get; set; }
     public string CustomerName { get; set; }
+    public string ChargePointVendor { get; set; }
 
 
     //public int? StationId { set; get; } = null;
     //public int? StationId { set; get; } = null;
     public Dictionary<string, object> Data = new Dictionary<string, object>();
     public Dictionary<string, object> Data = new Dictionary<string, object>();