Browse Source

test pass

Robert 1 year ago
parent
commit
c6112528f1

+ 14 - 0
EVCB_OCPP.WSServer/Dto/StationMachine.cs

@@ -0,0 +1,14 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace EVCB_OCPP.WSServer.Dto
+{
+    internal class StationMachine
+    {
+        public int StationId { get; set; }
+        public string ChargeBoxId { get; set; }
+    }
+}

+ 1 - 0
EVCB_OCPP.WSServer/Dto/StationMachineConfig.cs

@@ -8,6 +8,7 @@ namespace EVCB_OCPP.WSServer.Dto
 {
     public class StationMachineConfig
     {
+        public int StationId { get; set; }
         public string ConfigureName { get; set; }
         public string ConfigureSetting { get; set; }
     }

+ 9 - 0
EVCB_OCPP.WSServer/HostedProtalServer.cs

@@ -127,6 +127,15 @@ namespace EVCB_OCPP.WSServer
                         .RepeatForever())
                 );
 
+                q.ScheduleJob<StationConfigPollingJob>(trigger =>
+                    trigger
+                    .WithIdentity("StationConfigPollingJobTrigger")
+                    .StartNow()
+                    .WithSimpleSchedule(x => x
+                        .WithIntervalInSeconds(30)
+                        .RepeatForever())
+                );
+
                 //q.ScheduleJob<GoogleCheckJob>(trigger =>
                 //    trigger
                 //    .WithIdentity("GoogleCheckJobTrigger")

+ 70 - 60
EVCB_OCPP.WSServer/Jobs/ServerMessageJob.cs

@@ -53,17 +53,23 @@ public class ServerMessageJob : IJob
         }
     }
 
-    private async Task ExecuteTrigger()
+    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();
-        var dateTimeNow = DateTime.UtcNow;
+        DateTime dateTimeNow = DateTime.UtcNow;
         DateTime startDt = dateTimeNow.AddSeconds(-30);
         DateTime dt = new DateTime(1991, 1, 1);
         DateTime currentTime = dateTimeNow;
         List<ServerMessage> commandList;
-        var clientDic = protalServer.GetClientDic();
 
         using (var db = await maindbContextFactory.CreateDbContextAsync())
         {
@@ -75,22 +81,6 @@ public class ServerMessageJob : IJob
         {
             // Console.WriteLine(string.Format("Now:{0} commandList Count:{1} ", DateTime.UtcNow.ToString("yyyy/MM/dd HH:mm:ss"), commandList.Count));
         }
-        //List<NeedConfirmMessage> resendList = protalServer.GetResendMessage();
-        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"), "");
-                }
-
-            }
-
-        }
         foreach (var charger_SN in cmdMachineList)
         {
             WsClientData session;
@@ -104,70 +94,90 @@ public class ServerMessageJob : IJob
             //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")));
 
             //if (session.IsCheckIn && !session.ISOCPP20)
-            if (!session.ISOCPP20)
+            if (session.ISOCPP20)
             {
-                string rawRequest = string.Empty;
+                continue;
+            }
 
-                var cmdList = commandList.Where(c => c.ChargeBoxId == charger_SN).ToList();
+            string rawRequest = string.Empty;
 
-                var profiles = protalServer.Profiles;
+            var cmdList = commandList.Where(c => c.ChargeBoxId == charger_SN).ToList();
 
-                foreach (var item in cmdList)
+            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++)
                 {
-                    IRequest request = null;
-                    Actions action = Actions.None;
-                    Enum.TryParse(item.OutAction, out action);
-                    Type _RequestType = null;
+                    var feature = profiles[i].GetFeaturebyAction(item.OutAction);
 
-                    for (int i = 0; i < profiles.Count; i++)
+                    if (feature != null)
                     {
-                        var feature = profiles[i].GetFeaturebyAction(item.OutAction);
-
-                        if (feature != null)
-                        {
-                            _RequestType = feature.GetRequestType();
-                            break;
-                        }
+                        _RequestType = feature.GetRequestType();
+                        break;
                     }
+                }
 
-                    if (_RequestType != null && item.CreatedBy != "Destroyer")
+                if (_RequestType != null && item.CreatedBy != "Destroyer")
+                {
+                    request = JsonConvert.DeserializeObject(item.OutRequest, _RequestType) as IRequest;
+                    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 = JsonConvert.DeserializeObject(item.OutRequest, _RequestType) as IRequest;
+                        request = Activator.CreateInstance(_RequestType) as IRequest;
                         uuid = session.queue.store(request);
-                        rawRequest = BasicMessageHandler.GenerateRequest(uuid, item.OutAction, request);
+                        rawRequest = BasicMessageHandler.GenerateDestroyRequest(uuid, item.OutAction, item.OutRequest);
                         protalServer.SendMsg(session, rawRequest, string.Format("{0} {1}", action, "Request"), "");
-                    }
-
 
-                    if (item.CreatedBy == "Destroyer")
+                    }
+                    else
                     {
 
-                        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"), "");
+                        rawRequest = BasicMessageHandler.GenerateDestroyRequest(Guid.NewGuid().ToString(), item.OutAction, item.OutRequest);
+                        protalServer.SendMsg(session, rawRequest, string.Format("{0} {1}", action, "Request"), "");
 
-                        }
                     }
+                }
 
-                    await confirmWaitingMessageSerevice.Add(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 confirmWaitingMessageSerevice.Add(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);
+
+            }
+        }
+    }
 
+    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"), "");
                 }
 
             }
-        }
 
+        }
     }
 }

+ 46 - 0
EVCB_OCPP.WSServer/Jobs/StationConfigPollingJob.cs

@@ -0,0 +1,46 @@
+using EVCB_OCPP.WSServer.Service.DbService;
+using Quartz;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace EVCB_OCPP.WSServer.Jobs
+{
+    [DisallowConcurrentExecution]
+    internal class StationConfigPollingJob : IJob
+    {
+        public StationConfigPollingJob(
+            ProtalServer protalServer, 
+            WebDbService webDbService)
+        {
+            this.protalServer = protalServer;
+            this.webDbService = webDbService;
+        }
+
+        private readonly ProtalServer protalServer;
+        private readonly WebDbService webDbService;
+
+        public async Task Execute(IJobExecutionContext context)
+        {
+            var connectedEvses = protalServer.GetClientDic();
+            connectedEvses = connectedEvses.Where(x => x.Value.IsCheckIn = true).ToDictionary(x=>x.Key, x=>x.Value);
+
+            Dictionary<int, Dictionary<string, string>> stationEvseConfigs = await webDbService.GetStationEvseConfigs();
+            Dictionary<string, int> evseStationPair = await webDbService.GetEvseStationPair(connectedEvses.Keys.ToList());
+
+            foreach ( var chargboxId in connectedEvses.Keys ) 
+            {
+                if (!evseStationPair.ContainsKey(chargboxId))
+                {
+                    continue;
+                }
+
+                var stationId = evseStationPair[chargboxId];
+                var configs = stationEvseConfigs[stationId];
+                await protalServer.CheckandUpdateConfig(chargboxId, configs);
+            }
+        }
+    }
+}

+ 24 - 98
EVCB_OCPP.WSServer/ProtalServer.cs

@@ -57,9 +57,9 @@ namespace EVCB_OCPP.WSServer
         public ProtalServer(
             ILogger<ProtalServer> logger
             , IConfiguration configuration
-            , IDbContextFactory<MainDBContext> maindbContextFactory
+            //, IDbContextFactory<MainDBContext> maindbContextFactory
             , IMainDbService mainDbService
-            , IDbContextFactory<ConnectionLogDBContext> connectionLogdbContextFactory
+            //, IDbContextFactory<ConnectionLogDBContext> connectionLogdbContextFactory
             , ISqlConnectionFactory<WebDBConetext> webDbConnectionFactory
             , ISqlConnectionFactory<MainDBContext> mainDbConnectionFactory
             , IHostEnvironment environment
@@ -75,9 +75,9 @@ namespace EVCB_OCPP.WSServer
             _ct = _cts.Token;
             this.logger = logger;
             this.configuration = configuration;
-            this.maindbContextFactory = maindbContextFactory;
+            //this.maindbContextFactory = maindbContextFactory;
             this.mainDbService = mainDbService;
-            this.webDbConnectionFactory = webDbConnectionFactory;
+            //this.webDbConnectionFactory = webDbConnectionFactory;
             //this.connectionLogdbContextFactory = connectionLogdbContextFactory;
             //this.ocppWSServerFactory = ocppWSServerFactory;
             this.connectionLogdbService = connectionLogdbService;
@@ -104,9 +104,9 @@ namespace EVCB_OCPP.WSServer
         private readonly ILogger<ProtalServer> logger;
         private readonly IConfiguration configuration;
         //private readonly IServiceProvider serviceProvider;
-        private readonly IDbContextFactory<MainDBContext> maindbContextFactory;
+        //private readonly IDbContextFactory<MainDBContext> maindbContextFactory;
         private readonly IMainDbService mainDbService;
-        private readonly ISqlConnectionFactory<WebDBConetext> webDbConnectionFactory;
+        //private readonly ISqlConnectionFactory<WebDBConetext> webDbConnectionFactory;
 
         //private readonly IDbContextFactory<ConnectionLogDBContext> connectionLogdbContextFactory;
         //private readonly IOCPPWSServerFactory ocppWSServerFactory;
@@ -714,8 +714,8 @@ namespace EVCB_OCPP.WSServer
                                 {
                                     if (session.BootStatus == BootStatus.Startup)
                                     {
-                                        session.AddTask(InitializeEVSE(session));
                                         session.BootStatus = BootStatus.Initializing;
+                                        session.AddTask(StartInitializeEVSE(session));
                                     }
 
                                     if (bootNotificationConfirmation.status == Packet.Messages.SubTypes.RegistrationStatus.Accepted)
@@ -995,22 +995,23 @@ namespace EVCB_OCPP.WSServer
             }
         }
 
+        private async Task StartInitializeEVSE(WsClientData session)
+        {
+            await InitializeEVSE(session);
+            session.BootStatus = BootStatus.Pending;
+        }
+
         private async Task InitializeEVSE(WsClientData session)
         {
             // Pending mode 下發設定 
-            using (var db = await maindbContextFactory.CreateDbContextAsync())
+            string connectorType = await mainDbService.GetMachineConnectorType(session.ChargeBoxId);
+            if (!string.IsNullOrEmpty(connectorType) &&
+                (connectorType.Contains("6") || connectorType.Contains("7") || connectorType.Contains("8") || connectorType.Contains("9")))
             {
-                var machine = await db.Machine.Where(x => x.ChargeBoxId == session.ChargeBoxId).FirstOrDefaultAsync();
-                if (machine != null)
-                {
-                    if (machine.ConnectorType.Contains("6") || machine.ConnectorType.Contains("7") || machine.ConnectorType.Contains("8") || machine.ConnectorType.Contains("9"))
-                    {
-                        session.IsAC = false;
-                    }
-                    machine.ConnectionType = session.UriScheme.Contains("wss") ? 2 : 1;
-                    await db.SaveChangesAsync();
-                }
+                session.IsAC = false;
             }
+            await mainDbService.SetMachineConnectionType(session.ChargeBoxId, session.UriScheme.Contains("wss") ? 2 : 1);
+
             string requestId = string.Empty;
             MessageResult response = null;
             Func<Task<string>> sendTask = null;
@@ -1020,7 +1021,7 @@ namespace EVCB_OCPP.WSServer
 
             sendTask = async () => await messageService.SendChangeConfigurationRequest(
                 session.ChargeBoxId, key: "DefaultPrice", value: displayPriceText);
-            await confirmWaitingMessageSerevice.SendAndWaitUntilResultAsync(sendTask);
+            await confirmWaitingMessageSerevice.SendAndWaitUntilResultAsync(sendTask, session.DisconnetCancellationToken);
 
             if (session.CustomerId == new Guid("298918C0-6BB5-421A-88CC-4922F918E85E") || session.CustomerId == new Guid("9E6BFDCC-09FB-4DAB-A428-43FE507600A3"))
             {
@@ -1035,7 +1036,7 @@ namespace EVCB_OCPP.WSServer
             }
 
             sendTask = async () => await messageService.SendGetEVSEConfigureRequest(session.ChargeBoxId);
-            response = await confirmWaitingMessageSerevice.SendAndWaitUntilResultAsync(sendTask);
+            response = await confirmWaitingMessageSerevice.SendAndWaitUntilResultAsync(sendTask, session.DisconnetCancellationToken);
             if (response.Success && response.Message is GetConfigurationConfirmation confirmation)
             {
                 await CheckandUpdateConfig(session.ChargeBoxId, confirmation.configurationKey.ToDictionary(x => x.key, x => x.value));
@@ -1046,15 +1047,10 @@ namespace EVCB_OCPP.WSServer
                 messageId: "ID_FirmwareVersion",
                 vendorId: "Phihong Technology",
                 data: string.Empty);
-            await confirmWaitingMessageSerevice.SendAndWaitUntilResultAsync(sendTask);
-
-            if (session.BootStatus == BootStatus.Initializing)
-            {
-                session.BootStatus = BootStatus.Pending;
-            }
+            await confirmWaitingMessageSerevice.SendAndWaitUntilResultAsync(sendTask, session.DisconnetCancellationToken);
         }
 
-        private async Task CheckandUpdateConfig(string chargeBoxId, Dictionary<string,string> currentConfigs)
+        internal async Task CheckandUpdateConfig(string chargeBoxId, Dictionary<string,string> currentConfigs, CancellationToken token = default)
         {
             List<KeyValuePair<string, string>> configs = await webDbService.GetCustomerStationEvseConfig(chargeBoxId);
             if (configs == null)
@@ -1073,7 +1069,7 @@ namespace EVCB_OCPP.WSServer
 
                 MessageResult response = null;
                 var sendTask = async () => await messageService.SendChangeConfigurationRequest(chargeBoxId, config.Key, config.Value);
-                response = await confirmWaitingMessageSerevice.SendAndWaitUntilResultAsync(sendTask);
+                response = await confirmWaitingMessageSerevice.SendAndWaitUntilResultAsync(sendTask, token);
             }
         }
 
@@ -1097,76 +1093,6 @@ namespace EVCB_OCPP.WSServer
 
         }
 
-        async private Task<string> SetDefaultFee(WsClientData client)
-        {
-            string displayPriceText = string.Empty;
-            string charingPriceText = string.Empty;
-
-            if (string.IsNullOrEmpty(client.ChargeBoxId)) return displayPriceText;
-
-            try
-            {
-
-                using (SqlConnection conn = await webDbConnectionFactory.CreateAsync())
-                {
-                    var parameters = new DynamicParameters();
-                    parameters.Add("@MachineId", client.MachineId, DbType.String, ParameterDirection.Input, 36);
-                    string displayPricestrSql = "";
-                    string strSql = "";
-
-                    if (client.IsAC)
-                    {
-                        displayPricestrSql = "   SELECT  [AC_BillingMethod] as BillingMethod,[AC_FeeName] as FeeName,[AC_Fee] as ChargingFeebyHour" +
-                    "  ,[AC_ParkingFee] as ParkingFee, [Currency]  FROM[StationMachine]  left join[dbo].[Station]" +
-                    "  on[StationMachine].StationId = Station.[Id]  where StationMachine.MachineId=@MachineId and Station.IsBilling=1; ";
-
-                        strSql = " SELECT CAST( [StartTime] as varchar(5)) StartTime,CAST( [EndTime] as varchar(5)) EndTime,[Fee]  FROM[StationMachine]  left join [dbo].[StationFee]" +
-                       " on[StationMachine].StationId = StationFee.StationId  where StationMachine.MachineId =@MachineId and StationFee.IsAC=1; ";
-                    }
-                    else
-                    {
-                        displayPricestrSql = "   SELECT  [DC_BillingMethod] as BillingMethod,[DC_FeeName] as FeeName,[DC_Fee] as ChargingFeebyHour" +
-                   "  ,[DC_ParkingFee] as ParkingFee, [Currency]  FROM[StationMachine]  left join[dbo].[Station]" +
-                   "  on[StationMachine].StationId = Station.[Id]  where StationMachine.MachineId=@MachineId and Station.IsBilling=1; ";
-
-                        strSql = " SELECT CAST( [StartTime] as varchar(5)) StartTime,CAST( [EndTime] as varchar(5)) EndTime,[Fee]  FROM[StationMachine]  left join [dbo].[StationFee]" +
-                       " on[StationMachine].StationId = StationFee.StationId  where StationMachine.MachineId =@MachineId and StationFee.IsAC=0; ";
-
-                    }
-                    //var result = await conn.QueryAsync<StationFee>(displayPricestrSql, parameters);
-                    var result = await conn.QueryFirstOrDefaultAsync<StationFee>(displayPricestrSql, parameters);
-                    if (result == default)
-                    {
-                        return string.Empty;
-                    }
-                    var stationPrice = result;//.First();
-
-                    if (stationPrice.BillingMethod == 1)
-                    {
-                        var chargingPriceResult = await conn.QueryAsync<ChargingPrice>(strSql, parameters);
-                        client.ChargingPrices = chargingPriceResult.ToList();
-                        if (string.IsNullOrEmpty(client.ChargingPrices[0].StartTime))
-                        {
-                            client.ChargingPrices = new List<ChargingPrice>();
-                        }
-                    }
-
-                    displayPriceText = stationPrice.FeeName;
-                    client.BillingMethod = stationPrice.BillingMethod;
-                    client.Currency = stationPrice.Currency;
-                    client.ChargingFeebyHour = stationPrice.ChargingFeebyHour;
-                    client.ParkingFee = stationPrice.ParkingFee;
-                    client.IsBilling = true;
-                }
-            }
-            catch (Exception ex)
-            {
-                logger.LogError("SetDefaultFee", ex.ToString());
-            }
-
-            return displayPriceText;
-        }
-
         internal async void RemoveClient(WsClientData session, string reason)
         {
             if (session == null)

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

@@ -72,16 +72,18 @@ namespace EVCB_OCPP.WSServer.Service
 
         internal async Task Add(string chargePointSerialNumber, int table_id, string requestId, string action, string msg_id, string createdBy, string sendMessage)
         {
-            NeedConfirmMessage _needConfirmMsg = new NeedConfirmMessage();
-            _needConfirmMsg.Id = table_id;
-            _needConfirmMsg.SentAction = action;
-            _needConfirmMsg.SentOn = DateTime.UtcNow;
-            _needConfirmMsg.SentTimes = 4;
-            _needConfirmMsg.ChargePointSerialNumber = chargePointSerialNumber;
-            _needConfirmMsg.RequestId = requestId;
-            _needConfirmMsg.SentUniqueId = msg_id;
-            _needConfirmMsg.CreatedBy = createdBy;
-            _needConfirmMsg.SentMessage = sendMessage;
+            NeedConfirmMessage _needConfirmMsg = new NeedConfirmMessage
+            {
+                Id = table_id,
+                SentAction = action,
+                SentOn = DateTime.UtcNow,
+                SentTimes = 4,
+                ChargePointSerialNumber = chargePointSerialNumber,
+                RequestId = requestId,
+                SentUniqueId = msg_id,
+                CreatedBy = createdBy,
+                SentMessage = sendMessage
+            };
 
             if (needConfirmActions.Contains(action))
             {
@@ -190,15 +192,15 @@ namespace EVCB_OCPP.WSServer.Service
             }
         }
 
-        internal async Task<MessageResult> SendAndWaitUntilResultAsync(Func<Task<string>> sendTask)
+        internal async Task<MessageResult> SendAndWaitUntilResultAsync(Func<Task<string>> startSendTaskFunc, CancellationToken token = default)
         {
             MessageResult response;
             do
             {
-                var requestId = await sendTask();
+                var requestId = await startSendTaskFunc();
                 response = await WaitResultAsync(requestId);
             }
-            while (response == null);
+            while (response == null && !token.IsCancellationRequested);
             return response;
         }
 

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

@@ -42,6 +42,8 @@ public interface IMainDbService
     Task<bool> UpdateHeartBeats(List<string> machineIds);
     Task UpdateTransactionSOC(int id, string startsoc, string stopsoc);
     Task UpdateMachineConnectionType(string chargeBoxId, int v);
+    Task<string> GetMachineConnectorType(string chargeBoxId);
+    Task SetMachineConnectionType(string chargeBoxId, int v);
 }
 
 public class MainDbService : IMainDbService
@@ -973,6 +975,31 @@ public class MainDbService : IMainDbService
 
         return true;
     }
+
+    public async Task<string> GetMachineConnectorType(string chargeBoxId)
+    {
+        using var db = await contextFactory.CreateDbContextAsync();
+
+        var machine = await db.Machine.Where(x => x.ChargeBoxId == chargeBoxId).FirstOrDefaultAsync();
+        if (machine == null)
+        {
+            return null;
+        }
+        return machine.ConnectorType;
+    }
+
+    public async Task SetMachineConnectionType(string chargeBoxId,int v)
+    {
+        using var db = await contextFactory.CreateDbContextAsync();
+
+        var machine = await db.Machine.Where(x => x.ChargeBoxId == chargeBoxId).FirstOrDefaultAsync();
+        if (machine == null)
+        {
+            return;
+        }
+        machine.ConnectionType = v;
+        return;
+    }
 }
 
 public record MachineAndCustomerInfo(string MachineId, Guid CustomerId, string CustomerName);

+ 32 - 0
EVCB_OCPP.WSServer/Service/DbService/WebDbService.cs

@@ -154,4 +154,36 @@ public class WebDbService
         var configs = await conn.QueryAsync<StationMachineConfig>(getConfigStrSql, parameters);
         return configs.Select(x => new KeyValuePair<string, string>(x.ConfigureName, x.ConfigureSetting)).ToList();
     }
+
+    internal async Task<Dictionary<string, int>> GetEvseStationPair(List<string> chargeboxIds)
+    {
+        string getStationStrSql = """
+                SELECT [StationId],[ChargeBoxId]
+                FROM [dbo].[StationMachine]
+                WHERE [ChargeBoxId] IN @ChargeBoxIds;
+                """;
+        var parameters = new DynamicParameters();
+        parameters.Add("@ChargeBoxIds", chargeboxIds, direction: ParameterDirection.Input, size: 25);
+        using SqlConnection conn = await webDbConnectionFactory.CreateAsync();
+        var configs = await conn.QueryAsync<StationMachine>(getStationStrSql, parameters);
+        return configs.ToDictionary(x => x.ChargeBoxId, x => x.StationId);
+    }
+
+    internal async Task<Dictionary<int, Dictionary<string, string>>> GetStationEvseConfigs()
+    {
+        string getSql = """
+                SELECT [StationId],[ConfigureName],[ConfigureSetting]
+                FROM [dbo].[StationMachine]
+                """;
+        using SqlConnection conn = await webDbConnectionFactory.CreateAsync();
+        var configs = await conn.QueryAsync<StationMachineConfig>(getSql);
+        return configs
+            .GroupBy(x => x.StationId)
+            .ToDictionary(
+                x => x.Key,
+                x => x.ToDictionary(
+                    x => x.ConfigureName, 
+                    x => x.ConfigureSetting
+            ));
+    }
 }

+ 2 - 0
EVCB_OCPP.WSServer/Service/WsService/WsSession.cs

@@ -35,6 +35,8 @@ public class WsSession
 
     public SemaphoreSlim EndConnSemaphore { get; } = new SemaphoreSlim(0);
 
+    public CancellationToken DisconnetCancellationToken => disconnectCancellationTokenSource.Token;
+
     //public event OCPPClientDataEventHandler<WsSession, String> m_ReceiveData;
 
     public event EventHandler<string> SessionClosed;