Browse Source

1. add filter for adding machine error to db
2. restrict get configuration keys when update station configuraiton
3. fix repeating sending get configuration after station changed
4. dont try to get configuraiton if no station configuraiton is set

Robert 10 months ago
parent
commit
4d118385bb

+ 115 - 91
EVCB_OCPP.WSServer/Message/CoreProfileHandler.cs

@@ -289,107 +289,112 @@ internal partial class ProfileHandler
 					}
 					break;
 				case Actions.StatusNotification:
-					{
-						var statusNotificationTimer = Stopwatch.StartNew();
-						long s1 = 0, s2 = 0, s3 = 0, s4 = 0, s5 = 0;
-						//只保留最新上報狀況
-						StatusNotificationRequest _request = request as StatusNotificationRequest;
-						int preStatus = 0;
-						ConnectorStatus _oldStatus;
-
-						_oldStatus = await mainDbService.GetConnectorStatus(session.ChargeBoxId, _request.connectorId);
+                    {
+                        var statusNotificationTimer = Stopwatch.StartNew();
+                        long s1 = 0, s2 = 0, s3 = 0, s4 = 0, s5 = 0;
+                        //只保留最新上報狀況
+                        StatusNotificationRequest _request = request as StatusNotificationRequest;
+                        int preStatus = 0;
+                        ConnectorStatus _oldStatus;
 
-						s1 = statusNotificationTimer.ElapsedMilliseconds;
+                        _oldStatus = await mainDbService.GetConnectorStatus(session.ChargeBoxId, _request.connectorId);
 
-						if (_oldStatus != null && (_request.status != (ChargePointStatus)_oldStatus.Status || _request.status == ChargePointStatus.Faulted))
-						{
-							preStatus = _oldStatus.Status;
+                        s1 = statusNotificationTimer.ElapsedMilliseconds;
 
-							await mainDbService.UpdateConnectorStatus(_oldStatus.Id, new ConnectorStatus()
-							{
-								CreatedOn = _request.timestamp.HasValue ? _request.timestamp.Value : DateTime.UtcNow,
-								Status = (int)_request.status,
-								ChargePointErrorCodeId = (int)_request.errorCode,
-								ErrorInfo = string.IsNullOrEmpty(_request.info) ? string.Empty : _request.info,
-								VendorId = string.IsNullOrEmpty(_request.vendorId) ? string.Empty : _request.vendorId,
-								VendorErrorCode = string.IsNullOrEmpty(_request.vendorErrorCode) ? string.Empty : _request.vendorErrorCode
-							});
+                        if (_oldStatus != null && (_request.status != (ChargePointStatus)_oldStatus.Status || _request.status == ChargePointStatus.Faulted))
+                        {
+                            preStatus = _oldStatus.Status;
 
-							if (preStatus == (int)ChargePointStatus.Faulted)
-							{
-								if (_request.status != ChargePointStatus.Faulted ||
-									(_oldStatus.ChargePointErrorCodeId != (int)_request.errorCode && _oldStatus.VendorErrorCode != _request.vendorErrorCode))
-								{									
-									await mainDbService.FillupFinishedTimetoMachineError(
-										ConnectorId: (byte)_request.connectorId,
-										FinishedOn: _request.timestamp.HasValue ? _request.timestamp.Value : DateTime.UtcNow,									
-										ChargeBoxId: session.ChargeBoxId,
-										PreviousErrorOn: _oldStatus.CreatedOn
-										);
-								}
+                            await mainDbService.UpdateConnectorStatus(_oldStatus.Id, new ConnectorStatus()
+                            {
+                                CreatedOn = _request.timestamp.HasValue ? _request.timestamp.Value : DateTime.UtcNow,
+                                Status = (int)_request.status,
+                                ChargePointErrorCodeId = (int)_request.errorCode,
+                                ErrorInfo = string.IsNullOrEmpty(_request.info) ? string.Empty : _request.info,
+                                VendorId = string.IsNullOrEmpty(_request.vendorId) ? string.Empty : _request.vendorId,
+                                VendorErrorCode = string.IsNullOrEmpty(_request.vendorErrorCode) ? string.Empty : _request.vendorErrorCode
+                            });
+
+                            if (preStatus == (int)ChargePointStatus.Faulted)
+                            {
+                                if (_request.status != ChargePointStatus.Faulted ||
+                                    (_oldStatus.ChargePointErrorCodeId != (int)_request.errorCode && _oldStatus.VendorErrorCode != _request.vendorErrorCode))
+                                {
+                                    await mainDbService.FillupFinishedTimetoMachineError(
+                                        ConnectorId: (byte)_request.connectorId,
+                                        FinishedOn: _request.timestamp.HasValue ? _request.timestamp.Value : DateTime.UtcNow,
+                                        ChargeBoxId: session.ChargeBoxId,
+                                        PreviousErrorOn: _oldStatus.CreatedOn
+                                        );
+                                }
 
-							}
-						}
+                            }
+                        }
 
-						s2 = statusNotificationTimer.ElapsedMilliseconds;
+                        s2 = statusNotificationTimer.ElapsedMilliseconds;
 
-						if (_oldStatus == null)
-						{
-							await mainDbService.AddConnectorStatus(
-								ChargeBoxId: session.ChargeBoxId,
-								ConnectorId: (byte)_request.connectorId,
-								CreatedOn: _request.timestamp.HasValue ? _request.timestamp.Value : DateTime.UtcNow,
-								Status: (int)_request.status,
-								ChargePointErrorCodeId: (int)_request.errorCode,
-								ErrorInfo: string.IsNullOrEmpty(_request.info) ? string.Empty : _request.info,
-								VendorId: string.IsNullOrEmpty(_request.vendorId) ? string.Empty : _request.vendorId,
-								VendorErrorCode: string.IsNullOrEmpty(_request.vendorErrorCode) ? string.Empty : _request.vendorErrorCode);
-						}
-						s3 = statusNotificationTimer.ElapsedMilliseconds;
+                        if (_oldStatus == null)
+                        {
+                            await mainDbService.AddConnectorStatus(
+                                ChargeBoxId: session.ChargeBoxId,
+                                ConnectorId: (byte)_request.connectorId,
+                                CreatedOn: _request.timestamp.HasValue ? _request.timestamp.Value : DateTime.UtcNow,
+                                Status: (int)_request.status,
+                                ChargePointErrorCodeId: (int)_request.errorCode,
+                                ErrorInfo: string.IsNullOrEmpty(_request.info) ? string.Empty : _request.info,
+                                VendorId: string.IsNullOrEmpty(_request.vendorId) ? string.Empty : _request.vendorId,
+                                VendorErrorCode: string.IsNullOrEmpty(_request.vendorErrorCode) ? string.Empty : _request.vendorErrorCode);
+                        }
+                        s3 = statusNotificationTimer.ElapsedMilliseconds;
 
-						if (_request.status == Packet.Messages.SubTypes.ChargePointStatus.Faulted)
-						{
-							await mainDbService.AddMachineError(ConnectorId: (byte)_request.connectorId,
-									CreatedOn: _request.timestamp.HasValue ? _request.timestamp.Value : DateTime.UtcNow,
-									Status: (int)_request.status,
-									ChargeBoxId: session.ChargeBoxId,
-									ErrorCodeId: (int)_request.errorCode,
-									ErrorInfo: string.IsNullOrEmpty(_request.info) ? string.Empty : _request.info,
-									PreStatus: _oldStatus == null ? -1 : preStatus,
-									VendorErrorCode: string.IsNullOrEmpty(_request.vendorErrorCode) ? string.Empty : _request.vendorErrorCode,
-									VendorId: string.IsNullOrEmpty(_request.vendorId) ? string.Empty : _request.vendorId);
-						}
+                        bool isNeedAddMachineError = CheckNeedAddMachineError(_request, _oldStatus);
 
-						s4 = statusNotificationTimer.ElapsedMilliseconds;
-						if (_request.status == Packet.Messages.SubTypes.ChargePointStatus.Faulted)
-						{
-							//var businessService = BusinessServiceFactory.CreateBusinessService(session.CustomerId.ToString());
-							//var businessService = await serviceProvider.GetService<BusinessServiceFactory>().CreateBusinessService(session.CustomerId.ToString());
-							var businessService = await businessServiceFactory.CreateBusinessService(session.CustomerId.ToString());
-							var notification = businessService.NotifyFaultStatus(new ErrorDetails()
-							{
-								ChargeBoxId = session.ChargeBoxId,
-								ConnectorId = _request.connectorId,
-								ErrorCode = _request.errorCode,
-								Info = string.IsNullOrEmpty(_request.info) ? string.Empty : _request.info,
-								OCcuredOn = _request.timestamp ?? DateTime.UtcNow,
-								VendorErrorCode = string.IsNullOrEmpty(_request.vendorErrorCode) ? string.Empty : _request.vendorErrorCode,
+                        //if (_request.status == Packet.Messages.SubTypes.ChargePointStatus.Faulted &&
+                        //(_oldStatus != null && 
+                        //(_oldStatus.ChargePointErrorCodeId != (int)_request.errorCode && _oldStatus.VendorErrorCode != _request.vendorErrorCode)))
+                        if (isNeedAddMachineError)
+                        {
+                            await mainDbService.AddMachineError(ConnectorId: (byte)_request.connectorId,
+                                    CreatedOn: _request.timestamp.HasValue ? _request.timestamp.Value : DateTime.UtcNow,
+                                    Status: (int)_request.status,
+                                    ChargeBoxId: session.ChargeBoxId,
+                                    ErrorCodeId: (int)_request.errorCode,
+                                    ErrorInfo: string.IsNullOrEmpty(_request.info) ? string.Empty : _request.info,
+                                    PreStatus: _oldStatus == null ? -1 : preStatus,
+                                    VendorErrorCode: string.IsNullOrEmpty(_request.vendorErrorCode) ? string.Empty : _request.vendorErrorCode,
+                                    VendorId: string.IsNullOrEmpty(_request.vendorId) ? string.Empty : _request.vendorId);
+                        }
 
-							});
-						}
-						s5 = statusNotificationTimer.ElapsedMilliseconds;
+                        s4 = statusNotificationTimer.ElapsedMilliseconds;
+                        if (_request.status == Packet.Messages.SubTypes.ChargePointStatus.Faulted)
+                        {
+                            //var businessService = BusinessServiceFactory.CreateBusinessService(session.CustomerId.ToString());
+                            //var businessService = await serviceProvider.GetService<BusinessServiceFactory>().CreateBusinessService(session.CustomerId.ToString());
+                            var businessService = await businessServiceFactory.CreateBusinessService(session.CustomerId.ToString());
+                            var notification = businessService.NotifyFaultStatus(new ErrorDetails()
+                            {
+                                ChargeBoxId = session.ChargeBoxId,
+                                ConnectorId = _request.connectorId,
+                                ErrorCode = _request.errorCode,
+                                Info = string.IsNullOrEmpty(_request.info) ? string.Empty : _request.info,
+                                OCcuredOn = _request.timestamp ?? DateTime.UtcNow,
+                                VendorErrorCode = string.IsNullOrEmpty(_request.vendorErrorCode) ? string.Empty : _request.vendorErrorCode,
+
+                            });
+                        }
+                        s5 = statusNotificationTimer.ElapsedMilliseconds;
 
-						var confirm = new StatusNotificationConfirmation() { };
-						result.Message = confirm;
-						result.Success = true;
+                        var confirm = new StatusNotificationConfirmation() { };
+                        result.Message = confirm;
+                        result.Success = true;
 
-						statusNotificationTimer.Stop();						
-						if (statusNotificationTimer.ElapsedMilliseconds / 1000 > 1)
-						{
-							logger.LogCritical(string.Format("StatusNotification took {0}/{1}/{2}/{3}/{4}", s1, s2, s3, s4, s5));
-						}
-					}
-					break;
+                        statusNotificationTimer.Stop();
+                        if (statusNotificationTimer.ElapsedMilliseconds / 1000 > 1)
+                        {
+                            logger.LogCritical(string.Format("StatusNotification took {0}/{1}/{2}/{3}/{4}", s1, s2, s3, s4, s5));
+                        }
+                    }
+                    break;
 				case Actions.Heartbeat:
 					{
 
@@ -956,7 +961,7 @@ internal partial class ProfileHandler
 		return result;
 	}
 
-	async internal Task<MessageResult> ExecuteCoreConfirm(Actions action, WsClientData session, IConfirmation confirm, string requestId)
+    async internal Task<MessageResult> ExecuteCoreConfirm(Actions action, WsClientData session, IConfirmation confirm, string requestId)
 	{
 		MessageResult result = new MessageResult() { Success = true };
 
@@ -1782,5 +1787,24 @@ internal partial class ProfileHandler
 		return energy;
 	}
 
-
+    private static bool CheckNeedAddMachineError(StatusNotificationRequest _request, ConnectorStatus _oldStatus)
+    {
+        bool isNeedAddMachineError = false;
+        if (_oldStatus == null && _request.status == ChargePointStatus.Faulted)
+            isNeedAddMachineError = true;
+
+        if (_oldStatus != null)
+        {
+            if (_oldStatus.Status != (int)ChargePointStatus.Faulted)
+            {
+                isNeedAddMachineError = true;
+            }
+            else if (_oldStatus.ChargePointErrorCodeId != (int)_request.errorCode && _oldStatus.VendorErrorCode != _request.vendorErrorCode)
+            {
+                isNeedAddMachineError = true;
+            }
+        }
+
+        return isNeedAddMachineError;
+    }
 }

+ 3 - 2
EVCB_OCPP.WSServer/Service/ServerMessageService.cs

@@ -22,13 +22,14 @@ public class ServerMessageService
     private readonly IMainDbService mainDbService;
     private readonly ILogger<ServerMessageService> logger;
 
-    internal Task<string> SendGetEVSEConfigureRequest(string chargeBoxId, string serialNo = "")
+    internal Task<string> SendGetEVSEConfigureRequest(string chargeBoxId, List<string> configKeys = default , string serialNo = "")
     {
         if (string.IsNullOrEmpty(chargeBoxId)) return null;
+        List<string> toPassConfig = configKeys == default ? new List<string>() : configKeys;
         return mainDbService.AddServerMessage(
             ChargeBoxId: chargeBoxId,
             OutAction: Actions.GetConfiguration.ToString(),
-            OutRequest: new GetConfigurationRequest() { key = new List<string>() },
+            OutRequest: new GetConfigurationRequest() { key = toPassConfig },
             SerialNo: serialNo
             );
     }

+ 14 - 11
EVCB_OCPP.WSServer/Service/StationConfigService.cs

@@ -62,6 +62,7 @@ public class StationConfigService
         var stationId = await webDbService.GetEvseStation(chargeBoxId, token);
         if (stationId is null)
         {
+            logger.LogInformation("{chargeBoxId} doesn't belongs to any station", chargeBoxId);
             return;
         }
 
@@ -135,39 +136,42 @@ public class StationConfigService
             {
                 sessionStationId = currentStation;
                 await UpdateEvseConfig(evse.ChargeBoxId, currentStation.Value);
+                SetSessionStation(evse, sessionStationId);
             }
         }
     }
 
     private async Task UpdateEvseConfig(string chargeBoxId, int stationId, CancellationToken token = default)
     {
-        GetConfigurationConfirmation confirmation = await GetEvseCurrentConfig(chargeBoxId, token);
-        if (confirmation is null)
+        Dictionary<string, string> dbConfigs = null;
+
+        if (!stationConfigRecord.ContainsKey(stationId))
         {
-            logger.LogWarning("{chargeBoxId} get config from evse failed", chargeBoxId);
+            logger.LogInformation("{chargeBoxId} doesnt has station config", chargeBoxId);
             return;
         }
+        dbConfigs = stationConfigRecord[stationId];
 
-        if (!stationConfigRecord.ContainsKey(stationId))
+        GetConfigurationConfirmation confirmation = await GetEvseCurrentConfig(chargeBoxId, ConfigKeys: dbConfigs.Keys.ToList(), token: token);
+        if (confirmation is null)
         {
-            logger.LogInformation("{chargeBoxId} doesnt has station config", chargeBoxId);
+            logger.LogWarning("{chargeBoxId} get config from evse failed", chargeBoxId);
             return;
         }
 
-        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 CompareAndUpdateConfig(chargeBoxId,
             evseCurrentConfigs: evseCurrentConfigs,
             evseDbConfigs: dbConfigs,
             token);
     }
 
 
-    private async Task<GetConfigurationConfirmation> GetEvseCurrentConfig(string chargeBoxId, CancellationToken token = default)
+    private async Task<GetConfigurationConfirmation> GetEvseCurrentConfig(string chargeBoxId, List<string> ConfigKeys = default, CancellationToken token = default)
     {
-        var sendTask = async (string serialNo) => await messageService.SendGetEVSEConfigureRequest(chargeBoxId, serialNo: serialNo);
+        var sendTask = async (string serialNo) => await messageService.SendGetEVSEConfigureRequest(chargeBoxId, configKeys: ConfigKeys, serialNo: serialNo);
         var response = await confirmWaitingMessageSerevice.SendAndWaitUntilResultAsync(sendTask, token);
         if (response is GetConfigurationConfirmation confirmation)
         {
@@ -192,10 +196,9 @@ public class StationConfigService
         }
 
         return stationConfigRecord[staionID];
-        //return webDbService.GetCustomerStationEvseConfig(chargeBoxId, token);
     }
 
-    internal async Task ComparenUpdateConfig(string chargeBoxId,
+    internal async Task CompareAndUpdateConfig(string chargeBoxId,
         Dictionary<string, string> evseCurrentConfigs,
         Dictionary<string, string> evseDbConfigs,
         CancellationToken token = default)

+ 0 - 128
EVCB_OCPP.WSServer/Service/VendorIdUpdateService.cs

@@ -1,128 +0,0 @@
-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;
-using Microsoft.Extensions.Hosting;
-using Microsoft.Extensions.Logging;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace EVCB_OCPP.WSServer.Service
-{
-    public static class VendorIdUpdateServiceExt
-    {
-        public static Task InitVendorIdReplaceService(this IHost host)
-        {
-            var server = host.Services.GetRequiredService<ProtalServer>();
-            var vendorIdReplaceService = host.Services.GetRequiredService<VendorIdUpdateService>();
-            server.InitActions.Add(vendorIdReplaceService.GetAndRecordVendorId);
-            return host.Services.GetRequiredService<StationConfigService>().Init();
-        }
-    }
-
-    public class VendorIdUpdateService
-    {
-        public VendorIdUpdateService(
-            ProtalServer protalServer
-            , ServerMessageService messageService
-            , ConfirmWaitingMessageSerevice confirmWaitingMessageSerevice
-            , ILogger<VendorIdUpdateService> logger
-            )
-        {
-            this.protalServer = protalServer;
-            this.messageService = messageService;
-            this.confirmWaitingMessageSerevice = confirmWaitingMessageSerevice;
-            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<VendorIdUpdateService> logger;
-
-        internal async Task GetAndRecordVendorId(WsClientData wsClient, CancellationToken token)
-        {
-            var confirmation = await GetEvseCurrentConfig(wsClient.ChargeBoxId, token);
-
-            if (confirmation is null)
-            {
-                logger.LogWarning("{chargeBoxId} get config from evse failed", wsClient.ChargeBoxId);
-                return;
-            }
-
-            var vendorId = confirmation.configurationKey?.FirstOrDefault(x => x.key == "ChargePointVendorId");
-            if (vendorId is null)
-            {
-                logger.LogWarning("{chargeBoxId} get vendorId from evse failed", wsClient.ChargeBoxId);
-                return;
-            }
-
-            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<GetConfigurationConfirmation> GetEvseCurrentConfig(string chargeBoxId, CancellationToken token = default)
-        {
-            var sendTask = async (string serialNo) => await messageService.SendGetEVSEConfigureRequest(chargeBoxId, serialNo: serialNo);
-            var response = await confirmWaitingMessageSerevice.SendAndWaitUntilResultAsync(sendTask, token);
-            if (response is GetConfigurationConfirmation confirm)
-            {
-                return confirm;
-            }
-            return null;
-        }
-
-        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 (string)session.Data[Session_VID_Key];
-        }
-
-        private void SetSessionVendorId(WsClientData session, string vid)
-        {
-            if (session is null)
-            {
-                return;
-            }
-            session.Data[Session_VID_Key] = vid;
-        }
-    }
-}

+ 1 - 1
version.txt

@@ -1 +1 @@
-Docker_v1.1.31
+Docker_v1.1.32