StationConfigService.cs 7.1 KB

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