123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254 |
- using EVCB_OCPP.Packet.Messages.Core;
- using EVCB_OCPP.Packet.Messages.SubTypes;
- using EVCB_OCPP.WSServer.Message;
- using EVCB_OCPP.WSServer.Service.DbService;
- using EVCB_OCPP.WSServer.Service.WsService;
- using log4net.Core;
- 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 StationConfigServiceExt
- {
- public static Task InitStationConfigService(this IHost host)
- {
- var server = host.Services.GetRequiredService<ProtalServer>();
- var stationConfigService = host.Services.GetRequiredService<StationConfigService>();
- server.InitActions.Add(stationConfigService.CheckAndUpdateEvseConfigOnConnnected);
- return host.Services.GetRequiredService<StationConfigService>().Init();
- }
- }
- public class StationConfigService
- {
- public StationConfigService(
- ProtalServer portalServer
- , WebDbService webDbService
- , ServerMessageService messageService
- , ConfirmWaitingMessageSerevice confirmWaitingMessageSerevice
- , ILogger<StationConfigService> logger)
- {
- this.portalServer = portalServer;
- this.webDbService = webDbService;
- this.messageService = messageService;
- this.confirmWaitingMessageSerevice = confirmWaitingMessageSerevice;
- this.logger = logger;
- }
- private static string Session_Station_Key = "StationConfigService_Station";
- private readonly ProtalServer portalServer;
- private readonly WebDbService webDbService;
- private readonly ServerMessageService messageService;
- private readonly ConfirmWaitingMessageSerevice confirmWaitingMessageSerevice;
- private readonly ILogger<StationConfigService> logger;
- internal static Dictionary<int, Dictionary<string, string>> stationConfigRecord = null;
- public async Task Init()
- {
- stationConfigRecord = await webDbService.GetStationEvseConfigs();
- }
- public async Task CheckAndUpdateEvseConfigOnConnnected(WsClientData session, CancellationToken token = default)
- {
- var chargeBoxId = session.ChargeBoxId;
- var stationId = await webDbService.GetEvseStation(chargeBoxId, token);
- if (stationId is null)
- {
- logger.LogInformation("{chargeBoxId} doesn't belongs to any station", chargeBoxId);
- return;
- }
- int? sessionStationId = GetSessionStation(session);
- if (sessionStationId != stationId)
- {
- SetSessionStation(session, stationId);
- var configs = session.Data.ContainsKey(GlobalConfig.BootData_EVSEConfig_Key) ? session.Data[GlobalConfig.BootData_EVSEConfig_Key] as List<KeyValue> : null;
- await UpdateEvseConfig(chargeBoxId, stationId.Value, evseCurrentKeys: configs, token: token);
- }
- return;
- }
- public async Task CheckAndUpdateStationConfig()
- {
- await UpdateStationConfigChangedEvses();
- await UpdateStationChangedEvses();
- return;
- }
- private async Task UpdateStationConfigChangedEvses()
- {
- List<int> modifiedStations = new();
- var dbStationEvseConfig = await webDbService.GetStationEvseConfigs();
- foreach (var stationConfig in dbStationEvseConfig)
- {
- if (!stationConfigRecord.ContainsKey(stationConfig.Key) ||
- !CheckIsEqual(stationConfig.Value, stationConfigRecord[stationConfig.Key]))
- {
- modifiedStations.Add(stationConfig.Key);
- }
- }
- if (modifiedStations.Count == 0)
- {
- return;
- }
- stationConfigRecord = dbStationEvseConfig;
- Dictionary<string, WsClientData>.ValueCollection connectedEvses = portalServer.GetClientDic().Values;
- List<Task> updateTasks = new List<Task>();
- foreach (WsClientData evse in connectedEvses)
- {
- int? sessionStationId = GetSessionStation(evse);
- if (sessionStationId is not null &&
- modifiedStations.Contains(sessionStationId.Value))
- {
- var tmp = UpdateEvseConfig(evse.ChargeBoxId, sessionStationId.Value);
- updateTasks.Add(tmp);
- }
- }
- await Task.WhenAll(updateTasks);
- }
- private async Task UpdateStationChangedEvses()
- {
- List<string> modifiedEvses = new();
- var connectedEvses = portalServer.GetClientDic().Values.Where(x => x.IsCheckIn).ToList();
- var evseStationPair = await webDbService.GetEvseStationPair(connectedEvses.Select(x => x.ChargeBoxId).ToList());
- foreach (var evse in connectedEvses)
- {
- //var currentStation = await webDbService.GetEvseStation(evse.ChargeBoxId);
- int? currentStation = evseStationPair.ContainsKey(evse.ChargeBoxId) ? evseStationPair[evse.ChargeBoxId] : null;
- if (currentStation is null)
- {
- SetSessionStation(evse, null);
- continue;
- }
- int? sessionStationId = GetSessionStation(evse);
- if (sessionStationId != currentStation)
- {
- sessionStationId = currentStation;
- await UpdateEvseConfig(evse.ChargeBoxId, currentStation.Value);
- SetSessionStation(evse, sessionStationId);
- }
- }
- }
- private async Task UpdateEvseConfig(string chargeBoxId, int stationId, List<KeyValue> evseCurrentKeys = null, CancellationToken token = default)
- {
- Dictionary<string, string> dbConfigs = null;
- if (!stationConfigRecord.ContainsKey(stationId))
- {
- logger.LogInformation("{chargeBoxId} doesnt has station config", chargeBoxId);
- return;
- }
- dbConfigs = stationConfigRecord[stationId];
- if (evseCurrentKeys == null)
- {
- GetConfigurationConfirmation confirmation = await GetEvseCurrentConfig(chargeBoxId, ConfigKeys: dbConfigs.Keys.ToList(), token: token);
- if (confirmation is null)
- {
- logger.LogWarning("{chargeBoxId} get config from evse failed", chargeBoxId);
- return;
- }
- evseCurrentKeys = confirmation.configurationKey;
- }
- Dictionary<string, string> evseCurrentConfigs = new Dictionary<string, string>();
- evseCurrentConfigs = evseCurrentKeys.DistinctBy(x=>x.key).ToDictionary(x => x.key, x => x.value);
- await CompareAndUpdateConfig(chargeBoxId,
- evseCurrentConfigs: evseCurrentConfigs,
- evseDbConfigs: dbConfigs,
- token);
- }
- private async Task<GetConfigurationConfirmation> GetEvseCurrentConfig(string chargeBoxId, List<string> ConfigKeys = default, CancellationToken token = default)
- {
- var sendTask = async (string serialNo) => await messageService.SendGetEVSEConfigureRequest(chargeBoxId, configKeys: ConfigKeys, serialNo: serialNo);
- var response = await confirmWaitingMessageSerevice.SendAndWaitUntilResultAsync(sendTask, token: token);
- if (response is GetConfigurationConfirmation confirmation)
- {
- return confirmation;
- }
- return null;
- }
- private async Task<Dictionary<string, string>> GetEvseDBCurrentConfig(string chargeBoxId, CancellationToken token = default)
- {
- var receivedStaionID = await webDbService.GetEvseStation(chargeBoxId, token);
- if (receivedStaionID is null)
- {
- logger.LogInformation("{chargeBoxId} station not found", chargeBoxId);
- return null;
- }
- var staionID = receivedStaionID.Value;
- if (!stationConfigRecord.Keys.Contains(staionID))
- {
- stationConfigRecord[staionID] = await webDbService.GetEvseStationConfig(staionID);
- }
- return stationConfigRecord[staionID];
- }
- internal async Task CompareAndUpdateConfig(string chargeBoxId,
- Dictionary<string, string> evseCurrentConfigs,
- Dictionary<string, string> evseDbConfigs,
- CancellationToken token = default)
- {
- foreach (var config in evseDbConfigs)
- {
- if (evseCurrentConfigs.Keys.Contains(config.Key) &&
- evseCurrentConfigs[config.Key] == config.Value)
- {
- continue;
- }
- object response = null;
- var sendTask = async (string serialNo) => await messageService.SendChangeConfigurationRequest(chargeBoxId, config.Key, config.Value, serialNo: serialNo);
- response = await confirmWaitingMessageSerevice.SendAndWaitResultAsync(sendTask, token: token);
- }
- }
- private bool CheckIsEqual(Dictionary<string, string> d1, Dictionary<string, string> d2)
- {
- return d1.Count == d2.Count && d1.All(
- (d1KV) => d2.TryGetValue(d1KV.Key, out var d2Value) && (
- d1KV.Value == d2Value ||
- d1KV.Value?.Equals(d2Value) == true)
- );
- }
- private int? GetSessionStation(WsClientData session)
- {
- if (session is null ||
- !session.Data.ContainsKey(Session_Station_Key))
- {
- return null;
- }
- return (int?)session.Data[Session_Station_Key];
- }
- private void SetSessionStation(WsClientData session, int? stationId)
- {
- if (session is null)
- {
- return;
- }
- session.Data[Session_Station_Key] = stationId;
- }
- }
|