|
@@ -28,6 +28,10 @@ using Microsoft.Extensions.Logging;
|
|
|
using EVCB_OCPP.WSServer.Service.WsService;
|
|
|
using System.Net.WebSockets;
|
|
|
using EVCB_OCPP.Domain.ConnectionFactory;
|
|
|
+using EVCB_OCPP.WSServer.Service.DbService;
|
|
|
+using EVCB_OCPP.Packet.Messages.SubTypes;
|
|
|
+using System.Linq;
|
|
|
+using Azure;
|
|
|
|
|
|
namespace EVCB_OCPP.WSServer
|
|
|
{
|
|
@@ -65,6 +69,7 @@ namespace EVCB_OCPP.WSServer
|
|
|
, ServerMessageService serverMessageService
|
|
|
, IServiceProvider serviceProvider
|
|
|
, OcppWebsocketService websocketService
|
|
|
+ , ConfirmWaitingMessageSerevice confirmWaitingMessageSerevice
|
|
|
, OuterHttpClient httpClient)
|
|
|
{
|
|
|
_ct = _cts.Token;
|
|
@@ -79,6 +84,7 @@ namespace EVCB_OCPP.WSServer
|
|
|
this.webDbService = webDbService;
|
|
|
this.messageService = serverMessageService;
|
|
|
this.websocketService = websocketService;
|
|
|
+ this.confirmWaitingMessageSerevice = confirmWaitingMessageSerevice;
|
|
|
this.httpClient = httpClient;
|
|
|
isInDocker = !string.IsNullOrEmpty(configuration["DOTNET_RUNNING_IN_CONTAINER"]);
|
|
|
|
|
@@ -94,7 +100,7 @@ namespace EVCB_OCPP.WSServer
|
|
|
private DateTime lastcheckdt = DateTime.UtcNow.AddSeconds(-20);
|
|
|
private ConcurrentDictionary<string, WsClientData> clientDic = new ConcurrentDictionary<string, WsClientData>();
|
|
|
//private readonly Object _lockClientDic = new object();
|
|
|
- private readonly Object _lockConfirmPacketList = new object();
|
|
|
+ //private readonly Object _lockConfirmPacketList = new object();
|
|
|
private readonly ILogger<ProtalServer> logger;
|
|
|
private readonly IConfiguration configuration;
|
|
|
//private readonly IServiceProvider serviceProvider;
|
|
@@ -108,10 +114,11 @@ namespace EVCB_OCPP.WSServer
|
|
|
private readonly WebDbService webDbService;
|
|
|
private readonly ServerMessageService messageService;
|
|
|
private readonly OcppWebsocketService websocketService;
|
|
|
+ private readonly ConfirmWaitingMessageSerevice confirmWaitingMessageSerevice;
|
|
|
private readonly ProfileHandler profileHandler;//= new ProfileHandler();
|
|
|
//private readonly string webConnectionString;// = ConfigurationManager.ConnectionStrings["WebDBContext"].ConnectionString;
|
|
|
private readonly bool isInDocker;
|
|
|
- private List<NeedConfirmMessage> needConfirmPacketList = new List<NeedConfirmMessage>();
|
|
|
+ //private List<NeedConfirmMessage> needConfirmPacketList = new List<NeedConfirmMessage>();
|
|
|
private DateTime checkUpdateDt = DateTime.UtcNow;
|
|
|
private DateTime _CheckFeeDt = DateTime.UtcNow;
|
|
|
private DateTime _CheckLBDt = DateTime.UtcNow;
|
|
@@ -164,18 +171,6 @@ namespace EVCB_OCPP.WSServer
|
|
|
return toReturn;
|
|
|
}
|
|
|
|
|
|
- internal List<NeedConfirmMessage> GetResendMessage()
|
|
|
- {
|
|
|
- List<NeedConfirmMessage> sendMessages = new List<NeedConfirmMessage>();
|
|
|
- lock (_lockConfirmPacketList)
|
|
|
- {
|
|
|
- sendMessages = needConfirmPacketList.Where(x => x.SentTimes > 1 && x.CreatedBy == "Server").ToList();
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- return sendMessages;
|
|
|
- }
|
|
|
-
|
|
|
internal IReadOnlyList<Profile> Profiles => profiles.AsReadOnly();
|
|
|
internal LoadingBalanceService LoadingBalanceService => _loadingBalanceService;
|
|
|
internal ProfileHandler ProfileHandler => profileHandler;
|
|
@@ -419,201 +414,11 @@ namespace EVCB_OCPP.WSServer
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- private void RunHttpConsoleService()
|
|
|
- {
|
|
|
- var appBuilder = WebApplication.CreateBuilder();
|
|
|
- appBuilder.Services.AddSingleton<IHostLifetime, DummyHostLifeTime>();
|
|
|
- var app = appBuilder.Build();
|
|
|
-
|
|
|
- var helpFunc = () => {
|
|
|
- return string.Join("\r\n", new[] {
|
|
|
- "Command help!!",
|
|
|
- "lcn : List Customer Name",
|
|
|
- "gc : GC Collect",
|
|
|
- "lc : List Clients",
|
|
|
- "silent : silent",
|
|
|
- "show : show log"
|
|
|
- });
|
|
|
- };
|
|
|
- app.MapGet("/", helpFunc);
|
|
|
- app.MapGet("/help", helpFunc);
|
|
|
-
|
|
|
- app.MapPost("/stop", () => {
|
|
|
- Stop();
|
|
|
- return "Command stop";
|
|
|
- });
|
|
|
-
|
|
|
- app.MapPost("/gc", () => {
|
|
|
- GC.Collect();
|
|
|
- return "Command GC";
|
|
|
- });
|
|
|
-
|
|
|
- app.MapPost("/lc", () => {
|
|
|
- List<string> toReturn = new List<string>() { "Command List Clients" };
|
|
|
- Dictionary<string, WsClientData> _copyClientDic = null;
|
|
|
- _copyClientDic = new Dictionary<string, WsClientData>(clientDic);
|
|
|
- var list = _copyClientDic.Select(c => c.Value).ToList();
|
|
|
- int i = 1;
|
|
|
- foreach (var c in list)
|
|
|
- {
|
|
|
- toReturn.Add(i + ":" + c.ChargeBoxId + " " + c.SessionID);
|
|
|
- i++;
|
|
|
- }
|
|
|
- return string.Join("\r\n", toReturn);
|
|
|
- });
|
|
|
-
|
|
|
- app.MapPost("/lcn", () => {
|
|
|
- List<string> toReturn = new List<string> { "Command List Customer Name" };
|
|
|
- Dictionary<string, WsClientData> _copyClientDic = null;
|
|
|
- _copyClientDic = new Dictionary<string, WsClientData>(clientDic);
|
|
|
- var lcn = clientDic.Select(c => c.Value.CustomerName).Distinct().ToList();
|
|
|
- int iLcn = 1;
|
|
|
- foreach (var c in lcn)
|
|
|
- {
|
|
|
- toReturn.Add(iLcn + ":" + c + ":" + clientDic.Where(z => z.Value.CustomerName == c).Count().ToString());
|
|
|
- iLcn++;
|
|
|
- }
|
|
|
- return string.Join("\r\n", toReturn);
|
|
|
- });
|
|
|
-
|
|
|
- app.MapPost("/silent", () => {
|
|
|
- foreach (var rule in LogManager.Configuration.LoggingRules)
|
|
|
- {
|
|
|
- if (rule.RuleName != "ConsoleLog")
|
|
|
- {
|
|
|
- continue;
|
|
|
- }
|
|
|
-
|
|
|
- var isTargetRule = rule.Targets.Any(x => x.Name.ToLower() == "console");
|
|
|
-
|
|
|
- if (isTargetRule)
|
|
|
- {
|
|
|
- rule.SetLoggingLevels(NLog.LogLevel.Warn, NLog.LogLevel.Off);
|
|
|
- }
|
|
|
- }
|
|
|
- return "Command silent";
|
|
|
- });
|
|
|
-
|
|
|
- app.MapPost("/show", () => {
|
|
|
- foreach (var rule in LogManager.Configuration.LoggingRules)
|
|
|
- {
|
|
|
- if (rule.RuleName != "ConsoleLog")
|
|
|
- {
|
|
|
- continue;
|
|
|
- }
|
|
|
-
|
|
|
- var isTargetRule = rule.Targets.Any(x => x.Name.ToLower() == "console");
|
|
|
-
|
|
|
- if (isTargetRule)
|
|
|
- {
|
|
|
- rule.SetLoggingLevels(NLog.LogLevel.Trace, NLog.LogLevel.Off);
|
|
|
- }
|
|
|
- }
|
|
|
- return "Command show";
|
|
|
- });
|
|
|
-
|
|
|
- app.MapGet("/threads", () => {
|
|
|
- ThreadPool.GetMaxThreads(out var maxWorkerThread,out var maxCompletionPortThreads);
|
|
|
- ThreadPool.GetAvailableThreads(out var avaliableWorkerThread, out var avaliableCompletionPortThreads);
|
|
|
- return $"WorkerThread:{avaliableWorkerThread}/{maxWorkerThread} CompletionPortThreads{avaliableCompletionPortThreads}/{maxCompletionPortThreads}";
|
|
|
- });
|
|
|
-
|
|
|
- app.MapPost("/threads", (int min, int max) => {
|
|
|
- ThreadPool.GetMaxThreads(out var maxWorkerThread, out var maxCompletionPortThreads);
|
|
|
- ThreadPool.GetAvailableThreads(out var avaliableWorkerThread, out var avaliableCompletionPortThreads);
|
|
|
- ThreadPool.SetMinThreads(min, 0);
|
|
|
- ThreadPool.SetMaxThreads(max, maxCompletionPortThreads);
|
|
|
- return $"WorkerThread:{avaliableWorkerThread}/{maxWorkerThread} CompletionPortThreads{avaliableCompletionPortThreads}/{maxCompletionPortThreads}";
|
|
|
- });
|
|
|
-
|
|
|
- app.Urls.Add("http://*:54088");
|
|
|
-
|
|
|
- _ = app.RunAsync();
|
|
|
-
|
|
|
- var builder = WebApplication.CreateBuilder();
|
|
|
- //builder.Configuration.AddJsonFile("./EVCB_OCPP.WSServer/appsettings.json");
|
|
|
- //var sec = builder.Configuration.GetSection("ReverseProxy");
|
|
|
- //Console.WriteLine($"Printing.............");
|
|
|
- //foreach (var pair in sec.AsEnumerable())
|
|
|
- //{
|
|
|
- // Console.WriteLine($"{pair.Key}:{pair.Value} \n");
|
|
|
- //}
|
|
|
-
|
|
|
- builder.Services.AddReverseProxy()
|
|
|
- .LoadFromConfig(builder.Configuration.GetSection("ReverseProxy"));
|
|
|
- builder.Services.AddSingleton<IHostLifetime, DummyHostLifeTime>();
|
|
|
- var yarpApp = builder.Build();
|
|
|
- yarpApp.Urls.Add("http://*:80");
|
|
|
- yarpApp.MapReverseProxy();
|
|
|
- _ = yarpApp.RunAsync();
|
|
|
- }
|
|
|
-
|
|
|
internal void Stop()
|
|
|
{
|
|
|
_cts?.Cancel();
|
|
|
}
|
|
|
|
|
|
- //private void OpenNetwork()
|
|
|
- //{
|
|
|
-
|
|
|
- // //載入OCPP Protocol
|
|
|
- // OCPPWSServer appServer = ocppWSServerFactory.Create(new List<OCPPSubProtocol>() { new OCPPSubProtocol(), new OCPPSubProtocol(" ocpp1.6"), new OCPPSubProtocol("ocpp2.0") });
|
|
|
- // //var appServer = new OCPPWSServer(new List<OCPPSubProtocol>() { new OCPPSubProtocol(), new OCPPSubProtocol(" ocpp1.6"), new OCPPSubProtocol("ocpp2.0") });
|
|
|
-
|
|
|
- // List<IListenerConfig> llistener = new List<IListenerConfig>();
|
|
|
-
|
|
|
- // if (GlobalConfig.GetWS_Port() != 0)
|
|
|
- // {
|
|
|
- // llistener.Add(new ListenerConfig { Ip = System.Net.IPAddress.Any.ToString(), Port = GlobalConfig.GetWS_Port(), Backlog = 100, Security = "None" });
|
|
|
- // }
|
|
|
-
|
|
|
- // foreach (var securityport in GlobalConfig.GetWSS_Ports())
|
|
|
- // {
|
|
|
- // llistener.Add(new ListenerConfig { Ip = System.Net.IPAddress.Any.ToString(), Port = securityport, Backlog = 100, Security = SslProtocols.Tls12.ToString() });
|
|
|
- // }
|
|
|
-
|
|
|
- // //var config = ConfigurationManager.GetSection("superSocket") as IConfigurationSource;\
|
|
|
- // //var certificate = configuration.GetSection("superSocket").GetSection("Servers:0").GetSection("Certificate").Get<CertificateConfig>();
|
|
|
- // var certificate = configuration.GetSection("SuperSocketServerCertificate").Get<CertificateConfig>();
|
|
|
- // ICertificateConfig Certificate = certificate;
|
|
|
- // IEnumerable<IListenerConfig> listeners = llistener;
|
|
|
-
|
|
|
- // //設定server config
|
|
|
- // var serverConfig = new ServerConfig
|
|
|
- // {
|
|
|
- // SendingQueueSize = 10,
|
|
|
- // //Port = Convert.ToInt32(2012),
|
|
|
- // //Ip = "172.17.40.13",
|
|
|
- // MaxRequestLength = 204800,
|
|
|
- // //Security = serverSecurity,
|
|
|
- // //Certificate = Certificate,
|
|
|
- // Listeners = listeners,
|
|
|
- // // LogAllSocketException = true,
|
|
|
- // KeepAliveTime = 10,
|
|
|
- // // LogBasicSessionActivity = true
|
|
|
- // //Security = "None"
|
|
|
- // };
|
|
|
-
|
|
|
- // //Setup with listening port
|
|
|
- // if (!appServer.Setup(serverConfig, logFactory: new NLogLoggerFactory()))
|
|
|
- // {
|
|
|
- // Console.WriteLine("Failed to setup!");
|
|
|
- // return;
|
|
|
- // }
|
|
|
-
|
|
|
- // appServer.NewSessionConnected += AppServer_NewSessionConnected;
|
|
|
- // appServer.SessionClosed += AppServer_SessionClosed;
|
|
|
-
|
|
|
-
|
|
|
- // //Try to start the appServer
|
|
|
- // if (!appServer.Start())
|
|
|
- // {
|
|
|
- // Console.WriteLine("Failed to start!");
|
|
|
- // //Console.ReadKey();
|
|
|
- // return;
|
|
|
- // }
|
|
|
- //}
|
|
|
-
|
|
|
async private void ReceivedMessageTimeLimited(object sender, string rawdata)
|
|
|
{
|
|
|
if (sender is not WsClientData session)
|
|
@@ -858,8 +663,6 @@ namespace EVCB_OCPP.WSServer
|
|
|
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
- await Task.Delay(10);
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
@@ -876,6 +679,10 @@ namespace EVCB_OCPP.WSServer
|
|
|
logger.LogError(string.Format("{0} **Exception :{1} ", session.ChargeBoxId, ex.ToString()));
|
|
|
}
|
|
|
}
|
|
|
+ finally
|
|
|
+ {
|
|
|
+ await Task.Delay(10);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
private async Task ProcessRequestMessage(MessageResult analysisResult, WsClientData session, Actions action)
|
|
@@ -901,57 +708,20 @@ namespace EVCB_OCPP.WSServer
|
|
|
{
|
|
|
string response = BasicMessageHandler.GenerateConfirmation(analysisResult.UUID, (IConfirmation)replyResult.Message);
|
|
|
|
|
|
-
|
|
|
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)
|
|
|
+ if (action == Actions.BootNotification && replyResult.Message is BootNotificationConfirmation bootNotificationConfirmation)
|
|
|
{
|
|
|
- if (((BootNotificationConfirmation)replyResult.Message).status == Packet.Messages.SubTypes.RegistrationStatus.Accepted)
|
|
|
+ if (session.BootStatus == BootStatus.Startup)
|
|
|
{
|
|
|
- session.IsCheckIn = true;
|
|
|
-
|
|
|
- await messageService.SendGetEVSEConfigureRequest(session.ChargeBoxId);
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- await messageService.SendDataTransferRequest(
|
|
|
- session.ChargeBoxId,
|
|
|
- messageId: "ID_FirmwareVersion",
|
|
|
- vendorId: "Phihong Technology",
|
|
|
- data: string.Empty);
|
|
|
+ session.AddTask(InitializeEVSE(session));
|
|
|
+ session.BootStatus = BootStatus.Initializing;
|
|
|
}
|
|
|
- else
|
|
|
- {
|
|
|
- // Pending mode 下發設定
|
|
|
- using (var db = await maindbContextFactory.CreateDbContextAsync())
|
|
|
- {
|
|
|
- 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();
|
|
|
- }
|
|
|
- }
|
|
|
|
|
|
- await SetDefaultFee(session);
|
|
|
-
|
|
|
-
|
|
|
- if (session.CustomerId == new Guid("298918C0-6BB5-421A-88CC-4922F918E85E") || session.CustomerId == new Guid("9E6BFDCC-09FB-4DAB-A428-43FE507600A3"))
|
|
|
- {
|
|
|
- await messageService.SendChangeConfigurationRequest(
|
|
|
- session.ChargeBoxId, key: "TimeOffset", value: "+08:00");
|
|
|
- }
|
|
|
-
|
|
|
- if (session.CustomerId == new Guid("D57D5BCC-C5B0-4031-A7AE-7516E00CB028") )
|
|
|
- {
|
|
|
- await messageService.SendChangeConfigurationRequest(
|
|
|
- session.ChargeBoxId, key: "StopTransactionOnInvalidId", value: "True");
|
|
|
- }
|
|
|
- }
|
|
|
+ if (bootNotificationConfirmation.status == Packet.Messages.SubTypes.RegistrationStatus.Accepted)
|
|
|
+ {
|
|
|
+ session.IsCheckIn = true;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
if (action == Actions.Authorize && replyResult.Message is AuthorizeConfirmation)
|
|
@@ -1102,7 +872,7 @@ namespace EVCB_OCPP.WSServer
|
|
|
{
|
|
|
|
|
|
BasicMessageHandler msgAnalyser = new BasicMessageHandler();
|
|
|
- if (await ReConfirmMessage(analysisResult))
|
|
|
+ if (await confirmWaitingMessageSerevice.TryConfirmMessage(analysisResult))
|
|
|
{
|
|
|
var profileName = profiles.Where(x => x.IsExisted(analysisResult.Action)).Select(x => x.Name).FirstOrDefault();
|
|
|
MessageResult confirmResult = null;
|
|
@@ -1170,7 +940,7 @@ namespace EVCB_OCPP.WSServer
|
|
|
private async void ProcessErrorMessage(MessageResult analysisResult, WsClientData session, Actions action)
|
|
|
{
|
|
|
BasicMessageHandler msgAnalyser = new BasicMessageHandler();
|
|
|
- if (await ReConfirmMessage(analysisResult))
|
|
|
+ if (await confirmWaitingMessageSerevice.TryConfirmMessage(analysisResult))
|
|
|
{
|
|
|
var profileName = profiles.Where(x => x.IsExisted(analysisResult.Action)).Select(x => x.Name).FirstOrDefault();
|
|
|
switch (profileName)
|
|
@@ -1225,6 +995,100 @@ namespace EVCB_OCPP.WSServer
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ private async Task InitializeEVSE(WsClientData session)
|
|
|
+ {
|
|
|
+ // Pending mode 下發設定
|
|
|
+ using (var db = await maindbContextFactory.CreateDbContextAsync())
|
|
|
+ {
|
|
|
+ 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();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ string requestId = string.Empty;
|
|
|
+ MessageResult response = null;
|
|
|
+
|
|
|
+ var displayPriceText = await webDbService.SetDefaultFee(session);
|
|
|
+ UpdateClientDisplayPrice(session.ChargeBoxId, displayPriceText);
|
|
|
+
|
|
|
+ do
|
|
|
+ {
|
|
|
+ requestId = await messageService.SendChangeConfigurationRequest(
|
|
|
+ session.ChargeBoxId, key: "DefaultPrice", value: displayPriceText);
|
|
|
+ response = await confirmWaitingMessageSerevice.WaitResultAsync(requestId);
|
|
|
+ }
|
|
|
+ while (response == null);
|
|
|
+ //await SetDefaultFee(session);
|
|
|
+
|
|
|
+ if (session.CustomerId == new Guid("298918C0-6BB5-421A-88CC-4922F918E85E") || session.CustomerId == new Guid("9E6BFDCC-09FB-4DAB-A428-43FE507600A3"))
|
|
|
+ {
|
|
|
+ await messageService.SendChangeConfigurationRequest(
|
|
|
+ session.ChargeBoxId, key: "TimeOffset", value: "+08:00");
|
|
|
+ }
|
|
|
+
|
|
|
+ if (session.CustomerId == new Guid("D57D5BCC-C5B0-4031-A7AE-7516E00CB028"))
|
|
|
+ {
|
|
|
+ await messageService.SendChangeConfigurationRequest(
|
|
|
+ session.ChargeBoxId, key: "StopTransactionOnInvalidId", value: "True");
|
|
|
+ }
|
|
|
+
|
|
|
+ do
|
|
|
+ {
|
|
|
+ requestId = await messageService.SendGetEVSEConfigureRequest(session.ChargeBoxId);
|
|
|
+ response = await confirmWaitingMessageSerevice.WaitResultAsync(requestId);
|
|
|
+ }
|
|
|
+ while (response == null);
|
|
|
+ //GetConfigurationConfirmation
|
|
|
+ if (response.Success && response.Message is GetConfigurationConfirmation confirmation)
|
|
|
+ {
|
|
|
+ await CheckandUpdateConfig(session.ChargeBoxId, confirmation.configurationKey.ToDictionary(x => x.key, x => x.value));
|
|
|
+ }
|
|
|
+
|
|
|
+ await messageService.SendDataTransferRequest(
|
|
|
+ session.ChargeBoxId,
|
|
|
+ messageId: "ID_FirmwareVersion",
|
|
|
+ vendorId: "Phihong Technology",
|
|
|
+ data: string.Empty);
|
|
|
+
|
|
|
+ if (session.BootStatus == BootStatus.Initializing)
|
|
|
+ {
|
|
|
+ session.BootStatus = BootStatus.Pending;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private async Task CheckandUpdateConfig(string chargeBoxId, Dictionary<string,string> currentConfigs)
|
|
|
+ {
|
|
|
+ List<KeyValuePair<string, string>> configs = await webDbService.GetCustomerStationEvseConfig(chargeBoxId);
|
|
|
+ if (configs == null)
|
|
|
+ {
|
|
|
+ logger.LogInformation("{0} get station config failed", chargeBoxId);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ foreach(var config in configs)
|
|
|
+ {
|
|
|
+ if (currentConfigs.Keys.Contains(config.Key) &&
|
|
|
+ currentConfigs[config.Key] == config.Value)
|
|
|
+ {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ MessageResult response = null;
|
|
|
+ do
|
|
|
+ {
|
|
|
+ var requestId = await messageService.SendChangeConfigurationRequest(chargeBoxId, config.Key, config.Value);
|
|
|
+ response = await confirmWaitingMessageSerevice.WaitResultAsync(requestId);
|
|
|
+ }
|
|
|
+ while (response == null);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
private void Send(WsClientData session, string msg, string messageType, string errorMsg = "")
|
|
|
{
|
|
|
try
|
|
@@ -1315,90 +1179,6 @@ namespace EVCB_OCPP.WSServer
|
|
|
return displayPriceText;
|
|
|
}
|
|
|
|
|
|
- internal void AddConfirmMessage(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;
|
|
|
-
|
|
|
- if (needConfirmActions.Contains(action))
|
|
|
- {
|
|
|
-
|
|
|
- lock (_lockConfirmPacketList)
|
|
|
- {
|
|
|
- needConfirmPacketList.Add(_needConfirmMsg);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- internal void RemoveConfirmMessage()
|
|
|
- {
|
|
|
- var before10Mins = DateTime.UtcNow.AddMinutes(-10);
|
|
|
- lock (_lockConfirmPacketList)
|
|
|
- {
|
|
|
- var removeList = needConfirmPacketList.Where(x => x.SentTimes == 0 || x.SentOn < before10Mins).ToList();
|
|
|
- foreach (var item in removeList)
|
|
|
- {
|
|
|
- needConfirmPacketList.Remove(item);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- private async Task<bool> ReConfirmMessage(MessageResult analysisResult)
|
|
|
- {
|
|
|
- bool confirmed = false;
|
|
|
- if (needConfirmActions.Contains(analysisResult.Action))
|
|
|
- {
|
|
|
-
|
|
|
- NeedConfirmMessage foundRequest = null;
|
|
|
- lock (_lockConfirmPacketList)
|
|
|
- {
|
|
|
- foundRequest = needConfirmPacketList.Where(x => x.SentUniqueId == analysisResult.UUID).FirstOrDefault();
|
|
|
- }
|
|
|
-
|
|
|
- if (foundRequest != null && foundRequest.Id > 0)
|
|
|
- {
|
|
|
- foundRequest.SentTimes = 0;
|
|
|
- foundRequest.SentInterval = 0;
|
|
|
- analysisResult.RequestId = foundRequest.RequestId;
|
|
|
-
|
|
|
- using (var db = await maindbContextFactory.CreateDbContextAsync())
|
|
|
- {
|
|
|
- var sc = await db.ServerMessage.Where(x => x.Id == foundRequest.Id).FirstOrDefaultAsync();
|
|
|
- sc.InMessage = JsonConvert.SerializeObject(analysisResult.Message, Formatting.None);
|
|
|
- sc.ReceivedOn = DateTime.UtcNow;
|
|
|
- await db.SaveChangesAsync();
|
|
|
- // Console.WriteLine(string.Format("Now:{0} ServerMessage Id:{1} ", DateTime.UtcNow.ToString("yyyy/MM/dd HH:mm:ss"), foundRequest.Id));
|
|
|
-
|
|
|
- }
|
|
|
- confirmed = true;
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- }
|
|
|
- else if (analysisResult.Action == Actions.TriggerMessage.ToString())
|
|
|
- {
|
|
|
- confirmed = true;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- logger.LogError(string.Format("Received no record Action:{0} MessageId:{1} ", analysisResult.Action, analysisResult.UUID));
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- return confirmed;
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
internal async void RemoveClient(WsClientData session, string reason)
|
|
|
{
|
|
|
if (session == null)
|