using EVCB_OCPP.Domain; using EVCB_OCPP.Packet.Messages.SubTypes; using EVCB_OCPP.WSServer.Dto; using EVCB_OCPP.WSServer.Service.DbService; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using NLog; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace EVCB_OCPP.WSServer.Service { internal class CPOOuterResponse { public CPOOuterResponse() { StatusCode = 0; } public int StatusCode { set; get; } public string StatusMessage { set; get; } public string Data { set; get; } [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] public string SerialNo { set; get; } [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] public string ErrorDetail { set; get; } } internal class CustomerSignMaterial { internal bool CallsThirdParty { set; get; } internal string Id { set; get; } internal string APIUrl { set; get; } internal string SaltKey { set; get; } } public class OuterBusinessService : IBusinessService { private readonly ILogger logger; private readonly IDbContextFactory maindbContextFactory; private readonly IMainDbService mainDbService; private readonly OuterHttpClient httpClient; private string _CustomerId = string.Empty; private CustomerSignMaterial signMaterial = null; public string CustomerId { get => _CustomerId; set { _CustomerId = value; signMaterial = GetSign(_CustomerId).Result; } } internal CustomerSignMaterial CustomerSignMaterial { get => signMaterial; set { signMaterial = value; _CustomerId = signMaterial.Id; } } public OuterBusinessService( ILogger logger, IDbContextFactory maindbContextFactory, IMainDbService mainDbService, OuterHttpClient httpClient) { this.logger = logger; this.maindbContextFactory = maindbContextFactory; this.mainDbService = mainDbService; this.httpClient = httpClient; } async public Task Authorize(string chargeBoxId, string idTag, int? connectorId = null) { //return new IdTokenInfo() { IdTagInfo = new IdTagInfo() //{ // expiryDate = DateTime.UtcNow.AddDays(1), // status = AuthorizationStatus.Accepted //} }; //await Task.Delay(10); IdTokenInfo result = new IdTokenInfo() { IdTagInfo = new IdTagInfo() { status = AuthorizationStatus.Invalid } }; try { logger.LogInformation(chargeBoxId + " Charging Monitor======================================>"); string requestParams = idTag.StartsWith("vid:") ? await GetRequestParamsAsPnC(chargeBoxId, idTag, connectorId) : GetRequestParamsAsNormal(chargeBoxId, idTag); logger.LogInformation($"{chargeBoxId} Authorize : {signMaterial.APIUrl + requestParams}"); HttpResult response = await httpClient.Post(signMaterial.APIUrl + requestParams, new Dictionary() { { "PartnerId",signMaterial.Id} }, requestBody: null, saltkey: signMaterial.SaltKey).ConfigureAwait(false); logger.LogInformation($"{chargeBoxId} response : {JsonConvert.SerializeObject(response)}"); if (response.Success) { //Console.WriteLine(response.Response); var _httpResult = JsonConvert.DeserializeObject(response.Response); JObject jo = JObject.Parse(_httpResult.Data); if (jo.ContainsKey("ExpiryDate")) { DateTime dt = jo["ExpiryDate"].Value(); result.IdTagInfo.expiryDate = dt; } if (jo.ContainsKey("ParentIdTag")) { string _Message = jo["ParentIdTag"].Value(); result.IdTagInfo.parentIdTag = _Message; } if (jo.ContainsKey("ChargePointFee")) { for(int i=0;i< jo["ChargePointFee"].Count();i++) { if(i==0) { result.ChargePointFee = new List(); } result.ChargePointFee.Add(jo["ChargePointFee"][i].ToObject()); } } if (jo.ContainsKey("ChargepointFee")) { for (int i = 0; i < jo["ChargepointFee"].Count(); i++) { if (i == 0) { result.ChargePointFee = new List(); } result.ChargePointFee.Add(jo["ChargepointFee"][i].ToObject()); } } if (jo.ContainsKey("AccountBalance")) { decimal accountBalance = jo["AccountBalance"].Value(); result.AccountBalance = accountBalance; } if (jo.ContainsKey("Status")) { string _Message = jo["Status"].Value(); result.IdTagInfo.status = (AuthorizationStatus)Enum.Parse(typeof(AuthorizationStatus), _Message); } } else { logger.LogError(chargeBoxId + " OuterBusinessService.Authorize Fail: " + response.Response); } } catch (Exception ex) { result.IdTagInfo.status = AuthorizationStatus.Invalid; logger.LogError(chargeBoxId + " OuterBusinessService.Authorize Ex: " + ex.ToString()); } return result; } async public Task NotifyFaultStatus(ErrorDetails details) { try { if (signMaterial.CallsThirdParty) { var response = await httpClient.Post(signMaterial.APIUrl + "connectorfault", new Dictionary() { { "PartnerId",signMaterial.Id} }, details, signMaterial.SaltKey).ConfigureAwait(false); } } catch (Exception ex) { logger.LogError(details.ChargeBoxId + " OuterBusinessService.NotifyFaultStatus Ex: " + ex.ToString()); } } async public Task NotifyConnectorUnplugged(string chargeBoxId, string data) { try { JObject jo = JObject.Parse(data); var details = new { ChargeBoxId = chargeBoxId, SessionId = jo["idTx"].Value(), Timestamp = jo["timestamp"].Value() }; if (signMaterial.CallsThirdParty) { var response = await httpClient.Post(signMaterial.APIUrl + "connectorunplugged", new Dictionary() { { "PartnerId",signMaterial.Id} }, details, signMaterial.SaltKey).ConfigureAwait(false); } } catch (Exception ex) { logger.LogError(chargeBoxId + " OuterBusinessService.NotifyConnectorUnplugged Ex: " + ex.ToString()); } } private async Task GetSign(string customerId) { Guid Id = new Guid(customerId); CustomerSignMaterial _customer = new CustomerSignMaterial(); //using (var db = new MainDBContext()) //using (var db = maindbContextFactory.CreateDbContextAsync()) //{ // _customer = await db.Customer.Where(x => x.Id == Id).Select(x => new CustomerSignMaterial() { Id = x.Id.ToString(), APIUrl = x.ApiUrl, SaltKey = x.ApiKey, CallsThirdParty = x.CallPartnerApiOnSchedule }).FirstOrDefaultAsync(); //} var _customerDb = await mainDbService.GetCustomer(Id); if (_customerDb is not null) { _customer.Id = _customerDb.Id.ToString(); _customer.APIUrl = _customerDb.ApiUrl; _customer.SaltKey = _customerDb.ApiKey; _customer.CallsThirdParty = _customerDb.CallPartnerApiOnSchedule; } return _customer; } private async ValueTask GetRequestParamsAsPnC(string chargeBoxId, string idTag, int? connectorId) { idTag = idTag.Replace("vid:", ""); if (connectorId is null) { using (var db = await maindbContextFactory.CreateDbContextAsync()) { var connectorStatuses = await db.ConnectorStatus.Where(x => x.ChargeBoxId == chargeBoxId). Select(x => new { x.ConnectorId, x.Status, x.CreatedOn }).ToListAsync(); var connectorStatus = connectorStatuses.Where(x => x.Status == 2).OrderByDescending(x => x.CreatedOn).FirstOrDefault(); if (connectorStatus != null) { connectorId = connectorStatus.ConnectorId; } } } return string.Format("charging_auth?ChargeBoxId={0}&ConnectorId={1}&IdTag={2}", chargeBoxId, connectorId, idTag); } private string GetRequestParamsAsNormal(string chargeBoxId, string idTag) { return string.Format("charging_auth?ChargeBoxId={0}&IdTag={1}", chargeBoxId, idTag); } public Task NotifyConnectorUnplugged(string data) { throw new NotImplementedException(); } } }