StationConfigService.cs 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. using EVCB_OCPP.Packet.Messages.Core;
  2. using EVCB_OCPP.WSServer.Message;
  3. using EVCB_OCPP.WSServer.Service.DbService;
  4. using EVCB_OCPP.WSServer.Service.WsService;
  5. using log4net.Core;
  6. using Microsoft.Extensions.DependencyInjection;
  7. using Microsoft.Extensions.Hosting;
  8. using Microsoft.Extensions.Logging;
  9. using System;
  10. using System.Collections.Generic;
  11. using System.Linq;
  12. using System.Text;
  13. using System.Threading.Tasks;
  14. namespace EVCB_OCPP.WSServer.Service;
  15. public static class StationConfigServiceExt
  16. {
  17. public static Task InitStationConfigService(this IHost host)
  18. {
  19. var server = host.Services.GetRequiredService<ProtalServer>();
  20. var stationConfigService = host.Services.GetRequiredService<StationConfigService>();
  21. server.InitActions.Add(stationConfigService.CheckAndUpdateEvseConfig);
  22. return host.Services.GetRequiredService<StationConfigService>().Init();
  23. }
  24. }
  25. public class StationConfigService
  26. {
  27. public StationConfigService(
  28. ProtalServer portalServer
  29. , WebDbService webDbService
  30. , ServerMessageService messageService
  31. , ConfirmWaitingMessageSerevice confirmWaitingMessageSerevice
  32. , ILogger<StationConfigService> logger)
  33. {
  34. this.portalServer = portalServer;
  35. this.webDbService = webDbService;
  36. this.messageService = messageService;
  37. this.confirmWaitingMessageSerevice = confirmWaitingMessageSerevice;
  38. this.logger = logger;
  39. }
  40. private readonly ProtalServer portalServer;
  41. private readonly WebDbService webDbService;
  42. private readonly ServerMessageService messageService;
  43. private readonly ConfirmWaitingMessageSerevice confirmWaitingMessageSerevice;
  44. private readonly ILogger<StationConfigService> logger;
  45. internal static Dictionary<int, Dictionary<string, string>> stationConfigRecord = null;
  46. public async Task Init()
  47. {
  48. stationConfigRecord = await webDbService.GetStationEvseConfigs();
  49. }
  50. public async Task CheckAndUpdateEvseConfig(WsClientData session, CancellationToken token = default)
  51. {
  52. var chargeBoxId = session.ChargeBoxId;
  53. var stationId = await webDbService.GetEvseStation(chargeBoxId);
  54. if (stationId is null)
  55. {
  56. return;
  57. }
  58. if (session.StationId != stationId)
  59. {
  60. session.StationId = stationId;
  61. await UpdateEvseConfig(chargeBoxId, stationId.Value);
  62. }
  63. return;
  64. }
  65. public async Task CheckAndUpdateStationConfig()
  66. {
  67. await UpdateStationConfigChangedEvses();
  68. await UpdateStationChangedEvses();
  69. return;
  70. }
  71. private async Task UpdateStationConfigChangedEvses()
  72. {
  73. List<int> modifiedStations = new();
  74. var dbStationEvseConfig = await webDbService.GetStationEvseConfigs();
  75. foreach (var stationConfig in dbStationEvseConfig)
  76. {
  77. if (!stationConfigRecord.ContainsKey(stationConfig.Key) ||
  78. !CheckIsEqual(stationConfig.Value, stationConfigRecord[stationConfig.Key]))
  79. {
  80. modifiedStations.Add(stationConfig.Key);
  81. }
  82. }
  83. if (modifiedStations.Count == 0)
  84. {
  85. return;
  86. }
  87. stationConfigRecord = dbStationEvseConfig;
  88. var connectedEvses = portalServer.GetClientDic().Values;
  89. foreach (var evse in connectedEvses)
  90. {
  91. if (evse.IsCheckIn &&
  92. evse.StationId is not null &&
  93. modifiedStations.Contains(evse.StationId.Value))
  94. {
  95. await UpdateEvseConfig(evse.ChargeBoxId, evse.StationId.Value);
  96. }
  97. }
  98. }
  99. private async Task UpdateStationChangedEvses()
  100. {
  101. List<string> modifiedEvses = new();
  102. var connectedEvses = portalServer.GetClientDic().Values.ToList();
  103. foreach (var evse in connectedEvses)
  104. {
  105. var currentStation = await webDbService.GetEvseStation(evse.ChargeBoxId);
  106. if (currentStation is null)
  107. {
  108. evse.StationId = null;
  109. continue;
  110. }
  111. if (evse.StationId != currentStation)
  112. {
  113. evse.StationId = currentStation;
  114. await UpdateEvseConfig(evse.ChargeBoxId, currentStation.Value);
  115. }
  116. }
  117. }
  118. private async Task UpdateEvseConfig(string chargeBoxId, int stationId, CancellationToken token = default)
  119. {
  120. MessageResult getEvseCurrentConfigResponse = await GetEvseCurrentConfig(chargeBoxId, token);
  121. if (!getEvseCurrentConfigResponse.Success || getEvseCurrentConfigResponse.Message is not GetConfigurationConfirmation confirmation)
  122. {
  123. logger.LogWarning("{chargeBoxId} get config from evse failed", chargeBoxId);
  124. return;
  125. }
  126. if (!stationConfigRecord.ContainsKey(stationId))
  127. {
  128. logger.LogInformation("{chargeBoxId} doesnt has station config", chargeBoxId);
  129. return;
  130. }
  131. var dbConfigs = stationConfigRecord[stationId];
  132. await ComparenUpdateConfig(chargeBoxId,
  133. evseCurrentConfigs: confirmation.configurationKey.ToDictionary(x => x.key, x => x.value),
  134. evseDbConfigs: dbConfigs,
  135. token);
  136. }
  137. private async Task<MessageResult> GetEvseCurrentConfig(string chargeBoxId, CancellationToken token = default)
  138. {
  139. var sendTask = async () => await messageService.SendGetEVSEConfigureRequest(chargeBoxId);
  140. var response = await confirmWaitingMessageSerevice.SendAndWaitUntilResultAsync(sendTask, token);
  141. return response;
  142. }
  143. private async Task<Dictionary<string, string>> GetEvseDBCurrentConfig(string chargeBoxId, CancellationToken token = default)
  144. {
  145. var receivedStaionID = await webDbService.GetEvseStation(chargeBoxId, token);
  146. if (receivedStaionID is null)
  147. {
  148. logger.LogInformation("{chargeBoxId} station not found", chargeBoxId);
  149. return null;
  150. }
  151. var staionID = receivedStaionID.Value;
  152. if (!stationConfigRecord.Keys.Contains(staionID))
  153. {
  154. stationConfigRecord[staionID] = await webDbService.GetEvseStationConfig(staionID);
  155. }
  156. return stationConfigRecord[staionID];
  157. //return webDbService.GetCustomerStationEvseConfig(chargeBoxId, token);
  158. }
  159. internal async Task ComparenUpdateConfig(string chargeBoxId,
  160. Dictionary<string, string> evseCurrentConfigs,
  161. Dictionary<string, string> evseDbConfigs,
  162. CancellationToken token = default)
  163. {
  164. foreach (var config in evseDbConfigs)
  165. {
  166. if (evseCurrentConfigs.Keys.Contains(config.Key) &&
  167. evseCurrentConfigs[config.Key] == config.Value)
  168. {
  169. continue;
  170. }
  171. MessageResult response = null;
  172. var sendTask = async () => await messageService.SendChangeConfigurationRequest(chargeBoxId, config.Key, config.Value);
  173. response = await confirmWaitingMessageSerevice.SendAndWaitUntilResultAsync(sendTask, token);
  174. }
  175. }
  176. private bool CheckIsEqual(Dictionary<string, string> d1, Dictionary<string, string> d2)
  177. {
  178. return d1.Count == d2.Count && d1.All(
  179. (d1KV) => d2.TryGetValue(d1KV.Key, out var d2Value) && (
  180. d1KV.Value == d2Value ||
  181. d1KV.Value?.Equals(d2Value) == true)
  182. );
  183. }
  184. }