Pārlūkot izejas kodu

api/v1/cpo/activesession optimize complete

Robert 1 gadu atpakaļ
vecāks
revīzija
227a26079c

+ 172 - 104
EVCB_OCPP.WEBAPI/Controllers/Version1/CPOController.cs

@@ -16,6 +16,7 @@ using Microsoft.Extensions.Configuration;
 using Microsoft.Extensions.DependencyInjection;
 using Microsoft.Extensions.Logging;
 using System.Diagnostics;
+using EVCB_OCPP.Domain.Models.Database;
 
 namespace EVCB_OCPP.WEBAPI.Controllers.Version1
 {
@@ -26,15 +27,15 @@ namespace EVCB_OCPP.WEBAPI.Controllers.Version1
     [Route("api/v1/cpo")]
     public class CPOController : ControllerBase
     {
-        private readonly IServiceProvider serviceProvider;
-        private readonly ILogger<CPOController> logger;
-
         public CPOController(IServiceProvider serviceProvider, IConfiguration configuration, ILogger<CPOController> logger)
         {
             this.serviceProvider = serviceProvider;
             this.logger = logger;
         }
 
+        private readonly IServiceProvider serviceProvider;
+        private readonly ILogger<CPOController> logger;
+
         [Route("station")]
         [HttpGet]
         public async Task<IActionResult> Station()
@@ -42,21 +43,25 @@ namespace EVCB_OCPP.WEBAPI.Controllers.Version1
             var result = new CPOOuterResponse();
             //HttpStatusCode statusCode = HttpStatusCode.InternalServerError;
             int statusCode = StatusCodes.Status500InternalServerError;
+
             try
             {
-                if (Request.Headers.ContainsKey(EVCBConfiguration.Header_PartnerId))
+                if (!IsCustomerIdAvaliable())
                 {
-                    var _customerId = Request.Headers[EVCBConfiguration.Header_PartnerId].First();
-                    ChargingStationService _service = serviceProvider.GetRequiredService<ChargingStationService>();
+                    return StatusCode(statusCode, result);
+                }
 
-                    var _innerResponse = new { Stations = await _service.GetStationsbyCustomerIdAsync(_customerId) };
+                var _customerId = GetCustomerId();
 
-                    result.Data = JsonConvert.SerializeObject(_innerResponse, EVCBConfiguration.JSONSERIALIZER_FORMAT);
-                    result.StatusCode = (int)CPO_StatusCode.Success;
-                    result.StatusMessage = CPO_StatusMessage.Success;
-                    //statusCode = HttpStatusCode.OK;
-                    statusCode = StatusCodes.Status200OK;
-                }
+                ChargingStationService _service = serviceProvider.GetRequiredService<ChargingStationService>();
+
+                var _innerResponse = new { Stations = await _service.GetStationsbyCustomerIdAsync(_customerId) };
+
+                result.Data = JsonConvert.SerializeObject(_innerResponse, EVCBConfiguration.JSONSERIALIZER_FORMAT);
+                result.StatusCode = (int)CPO_StatusCode.Success;
+                result.StatusMessage = CPO_StatusMessage.Success;
+                //statusCode = HttpStatusCode.OK;
+                statusCode = StatusCodes.Status200OK;
                 //return Request.CreateResponse(statusCode, result);
                 return StatusCode(statusCode, result);
             }
@@ -68,9 +73,6 @@ namespace EVCB_OCPP.WEBAPI.Controllers.Version1
                 //return Request.CreateResponse(statusCode, result);
                 return StatusCode(statusCode, result);
             }
-            finally
-            {
-            }
         }
 
         [Route("information")]
@@ -86,49 +88,52 @@ namespace EVCB_OCPP.WEBAPI.Controllers.Version1
             {
                 ChargePointService _CPService = serviceProvider.GetRequiredService<ChargePointService>();// new ChargePointService();
                 var tt = _CPService.GetLastUpdatedTimebyMachineId("0da4f4a6-a952-46f0-b2f3-696385a9a56a");
-                if (Request.Headers.ContainsKey(EVCBConfiguration.Header_PartnerId))
+                if (!IsCustomerIdAvaliable())
                 {
-                    var _customerId = Request.Headers[EVCBConfiguration.Header_PartnerId].First();
+                    //return Request.CreateResponse(statusCode, result);
+                    return StatusCode(statusCode, result);
+                }
 
-                    var _innerResponse = new { EVSEs = new List<EVSE>() };
-                    ChargingStationService _stationService = serviceProvider.GetRequiredService<ChargingStationService>();// new ChargingStationService();
+                var _customerId = GetCustomerId();
 
-                    if (StationId > -1)
+                var _innerResponse = new { EVSEs = new List<EVSE>() };
+                ChargingStationService _stationService = serviceProvider.GetRequiredService<ChargingStationService>();// new ChargingStationService();
+
+                if (StationId > -1)
+                {
+                    if (_stationService.ContainsStation(_customerId, StationId))
                     {
-                        if (_stationService.ContainsStation(_customerId, StationId))
+                        if (DateTo.HasValue)
                         {
-                            if (DateTo.HasValue)
+                            if (!DateFrom.HasValue)
                             {
-                                if (!DateFrom.HasValue)
-                                {
-
-                                    result.StatusMessage = CPO_StatusMessage.ERROR_MSG_PARAMETER_OUTOFRANGE_INCORRECT;
-                                    result.StatusCode = (int)CPO_StatusCode.PARAMETER_OUTOFRANGE_INCORRECT;
-                                    //statusCode = HttpStatusCode.BadRequest;
-                                    statusCode = StatusCodes.Status400BadRequest;
-                                    //return Request.CreateResponse(statusCode, result);
-                                    return StatusCode(statusCode, result);
-                                }
-                            }
-                            _innerResponse = new { EVSEs = _stationService.GetEVSEsbyStationId(StationId, DateFrom, DateTo, Offset.Value, Limit == -1 ? 1000 : Limit.Value) };
-
 
+                                result.StatusMessage = CPO_StatusMessage.ERROR_MSG_PARAMETER_OUTOFRANGE_INCORRECT;
+                                result.StatusCode = (int)CPO_StatusCode.PARAMETER_OUTOFRANGE_INCORRECT;
+                                //statusCode = HttpStatusCode.BadRequest;
+                                statusCode = StatusCodes.Status400BadRequest;
+                                //return Request.CreateResponse(statusCode, result);
+                                return StatusCode(statusCode, result);
+                            }
                         }
-                    }
-                    else
-                    {
-                        _innerResponse = new { EVSEs = new List<EVSE>() };
-                        _innerResponse.EVSEs.Add(_CPService.GetEVSEsbyChargeBoxId(ChargeBoxId, DateFrom, DateTo));
+                        _innerResponse = new { EVSEs = _stationService.GetEVSEsbyStationId(StationId, DateFrom, DateTo, Offset.Value, Limit == -1 ? 1000 : Limit.Value) };
 
 
                     }
+                }
+                else
+                {
+                    _innerResponse = new { EVSEs = new List<EVSE>() };
+                    _innerResponse.EVSEs.Add(_CPService.GetEVSEsbyChargeBoxId(ChargeBoxId, DateFrom, DateTo));
+
 
-                    result.Data = JsonConvert.SerializeObject(_innerResponse, EVCBConfiguration.JSONSERIALIZER_FORMAT);
-                    result.StatusCode = (int)CPO_StatusCode.Success;
-                    result.StatusMessage = CPO_StatusMessage.Success;
-                    //statusCode = HttpStatusCode.OK;
-                    statusCode = StatusCodes.Status200OK;
                 }
+
+                result.Data = JsonConvert.SerializeObject(_innerResponse, EVCBConfiguration.JSONSERIALIZER_FORMAT);
+                result.StatusCode = (int)CPO_StatusCode.Success;
+                result.StatusMessage = CPO_StatusMessage.Success;
+                //statusCode = HttpStatusCode.OK;
+                statusCode = StatusCodes.Status200OK;
                 //return Request.CreateResponse(statusCode, result);
                 return StatusCode(statusCode, result);
             }
@@ -154,9 +159,10 @@ namespace EVCB_OCPP.WEBAPI.Controllers.Version1
             var _innerData = new { Result = CommandResponseType.Rejected.ToString(), Timeout = 60 };
             try
             {
-                string _CustomerId = string.Empty;
+                string _CustomerId = GetCustomerId();
+                logger.LogTrace($"StartSession {request.ChargeBoxId} {_CustomerId}");
 
-                if (!ContainsChargePoint(request.ChargeBoxId, out _CustomerId))
+                if (!await ContainsChargePointAsync(request.ChargeBoxId, _CustomerId))
                 {
                     // 沒槍~ 沒得充...                   
                     result.StatusMessage = CPO_StatusMessage.ERROR_MSG_CHARGEBOXID_DOESNT_EXIST;
@@ -171,9 +177,12 @@ namespace EVCB_OCPP.WEBAPI.Controllers.Version1
 
                 ChargePointService _CPService = serviceProvider.GetRequiredService<ChargePointService>();
 
-                if (!string.IsNullOrEmpty(request.ChargeBoxId) && request.ChargeBoxId.Length <= 25 && (!request.ConnectorId.HasValue
-                   || (_CPService.GetNumberofConnectors(request.ChargeBoxId) >= request.ConnectorId && request.ConnectorId > 0))
-                    && !string.IsNullOrEmpty(request.Token) && request.Token.Length <= 20)
+                if (!string.IsNullOrEmpty(request.ChargeBoxId) && 
+                    request.ChargeBoxId.Length <= 25 && 
+                    (!request.ConnectorId.HasValue ||
+                        (_CPService.GetNumberofConnectors(request.ChargeBoxId) >= request.ConnectorId && request.ConnectorId > 0)) &&
+                    !string.IsNullOrEmpty(request.Token) &&
+                    request.Token.Length <= 20)
                 {
                     InternalHttpClient _client = serviceProvider.GetRequiredService<InternalHttpClient>();
                     ICustomerService _customer = serviceProvider.GetRequiredService<ICustomerService>();
@@ -183,7 +192,6 @@ namespace EVCB_OCPP.WEBAPI.Controllers.Version1
                     {
                         ConnectorId = request.ConnectorId,
                         IdTag = request.Token
-
                     };
 
                     string urlformat = "{0}://{1}";
@@ -258,9 +266,9 @@ namespace EVCB_OCPP.WEBAPI.Controllers.Version1
             var _innerData = new { Result = CommandResponseType.Rejected.ToString(), Timeout = 60 };
             try
             {
-                string _CustomerId = string.Empty;
+                string _CustomerId = GetCustomerId();
 
-                if (!ContainsChargePoint(ChargeBoxId, out _CustomerId))
+                if (!await ContainsChargePointAsync(ChargeBoxId, _CustomerId))
                 {
                     // 沒槍~ 沒得充...                   
                     result.StatusMessage = CPO_StatusMessage.ERROR_MSG_CHARGEBOXID_DOESNT_EXIST;
@@ -1186,7 +1194,7 @@ namespace EVCB_OCPP.WEBAPI.Controllers.Version1
         [Route("activesession")]
         [Produces(typeof(CPOOuterResponse))]
         [HttpGet]
-        public IActionResult ActiveSession(string ChargeBoxId, string SessionId = "", string IdTag = "")
+        public async Task<IActionResult> ActiveSession(string ChargeBoxId, int? SessionId = null, string IdTag = null)
         {
             var result = new CPOOuterResponse();
             //HttpStatusCode statusCode = HttpStatusCode.InternalServerError;
@@ -1194,9 +1202,9 @@ namespace EVCB_OCPP.WEBAPI.Controllers.Version1
 
             try
             {
-                string _CustomerId = string.Empty;
+                string _CustomerId = GetCustomerId();
 
-                if (!ContainsChargePoint(ChargeBoxId, out _CustomerId))
+                if (!await ContainsChargePointAsync(ChargeBoxId, _CustomerId))
                 {
                     // 沒槍~ 沒得充...                   
                     result.StatusMessage = CPO_StatusMessage.ERROR_MSG_CHARGEBOXID_DOESNT_EXIST;
@@ -1209,66 +1217,40 @@ namespace EVCB_OCPP.WEBAPI.Controllers.Version1
 
                 // query meter value
                 ChargePointService _service = serviceProvider.GetRequiredService<ChargePointService>();
-                var transactionDatas = _service.GetActiveSessionInfo(ChargeBoxId, new List<Measurand>()
+                var transactionDatas = await _service.GetActiveSessionInfoAsync(ChargeBoxId, new List<Measurand>()
                 {  Measurand.Voltage,
                    Measurand.Current_Import,
                    Measurand.SoC,
                    Measurand.Power_Active_Import,
                    Measurand.TotalEnergy,
                    Measurand.ChargingCost
-                }, SessionId, IdTag);
+                }, _CustomerId, SessionId, IdTag);
 
-                if (transactionDatas == null)
+                if (transactionDatas is null)
                 {
                     result.StatusCode = (int)CPO_StatusCode.CANT_FOUND_DATA;
                     result.StatusMessage = CPO_StatusMessage.ERROR_MSG_CANT_FIND_RESULT;
                     //statusCode = HttpStatusCode.NotFound;
                     statusCode = StatusCodes.Status404NotFound;
-                }
-                else
-                {
-                    List<ActiveSession> _innerData = new();
 
-                    foreach (var transactionData in transactionDatas)
-                    {
-
-
-                        string currencyText = string.IsNullOrEmpty(transactionData.Fee) ? "TWD" : transactionData.Fee.Remove(0, transactionData.Fee.Length - 3);
+                    return StatusCode(statusCode, result);
+                }
 
-                        _innerData.Add(new ActiveSession()
-                        {
+                List<ActiveSession> _innerData = new();
 
-                            ChargeBoxId = ChargeBoxId,
-                            SessionId = transactionData.Id,
-                            ElaspedTime = (int)DateTime.UtcNow.Subtract(transactionData.StartTime).TotalMinutes,
-                            ConnectorId = transactionData.ConnectorId,
-                            IdTag = transactionData.StartIdTag,
-                            Power = transactionData.MeterValues == null ? "0" : transactionData.MeterValues.Where(x => x.Measurand == Packet.Messages.SubTypes.Measurand.Power_Active_Import).Select(x => x.Value).FirstOrDefault(),
-                            Power_Format = transactionData.MeterValues == null ? UnitOfMeasure.W.ToString() : transactionData.MeterValues.Where(x => x.Measurand == Packet.Messages.SubTypes.Measurand.Power_Active_Import).Select(x => x.Unit.ToString()).FirstOrDefault(),
-                            Current = transactionData.MeterValues == null ? "0" : transactionData.MeterValues.Where(x => x.Measurand == Packet.Messages.SubTypes.Measurand.Current_Import).Select(x => x.Value).FirstOrDefault(),
-                            Current_Format = transactionData.MeterValues == null ? UnitOfMeasure.A.ToString() : transactionData.MeterValues.Where(x => x.Measurand == Packet.Messages.SubTypes.Measurand.Current_Import).Select(x => x.Unit.ToString()).FirstOrDefault(),
-                            Energy = transactionData.MeterValues == null ? "0" : transactionData.MeterValues.Where(x => x.Measurand == Packet.Messages.SubTypes.Measurand.TotalEnergy).Select(x => x.Value).FirstOrDefault(),
-                            Energy_Format = transactionData.MeterValues == null ? UnitOfMeasure.Wh.ToString() : transactionData.MeterValues.Where(x => x.Measurand == Packet.Messages.SubTypes.Measurand.TotalEnergy).Select(x => x.Unit.ToString()).FirstOrDefault(),
-                            Voltage = transactionData.MeterValues == null ? "0" : transactionData.MeterValues.Where(x => x.Measurand == Packet.Messages.SubTypes.Measurand.Voltage).Select(x => x.Value).FirstOrDefault(),
-                            Voltage_Format = transactionData.MeterValues == null ? UnitOfMeasure.V.ToString() : transactionData.MeterValues.Where(x => x.Measurand == Packet.Messages.SubTypes.Measurand.Voltage).Select(x => x.Unit.ToString()).FirstOrDefault(),
-                            SOC = transactionData.MeterValues == null ? "0" : transactionData.MeterValues.Where(x => x.Measurand == Packet.Messages.SubTypes.Measurand.SoC).Select(x => x.Unit.ToString()).FirstOrDefault() == null ? null : transactionData.MeterValues.Where(x => x.Measurand == Packet.Messages.SubTypes.Measurand.SoC).Select(x => x.Value).FirstOrDefault(),
-                            SOC_Format = transactionData.MeterValues == null ? UnitOfMeasure.Percent.ToString() : transactionData.MeterValues.Where(x => x.Measurand == Packet.Messages.SubTypes.Measurand.SoC).Select(x => x.Unit.ToString()).FirstOrDefault(),
-                            CurrentCost = transactionData.MeterValues == null ? "0" : transactionData.MeterValues.Where(x => x.Measurand == Packet.Messages.SubTypes.Measurand.ChargingCost).Select(x => x.Value).FirstOrDefault(),
-                            Currency = currencyText
-                        });
-                        decimal energy = decimal.Parse(_innerData[_innerData.Count - 1].Energy);
-                        energy = _innerData[^1].Energy_Format == UnitOfMeasure.Wh.ToString() ? Decimal.Divide(energy, 1000) : energy;
-                        _innerData[^1].Energy = energy.ToString("0.000");
-                        _innerData[^1].Energy_Format = UnitOfMeasure.kWh.ToString();
-                    }
-                    var _innerResponse = new { Sessions = _innerData };
-                    result.Data = JsonConvert.SerializeObject(_innerResponse, EVCBConfiguration.JSONSERIALIZER_FORMAT);
+                foreach (TransasctionData transactionData in transactionDatas)
+                {
+                    string currencyText = string.IsNullOrEmpty(transactionData.Fee) ? "TWD" : transactionData.Fee.Remove(0, transactionData.Fee.Length - 3);
 
-                    result.StatusCode = (int)CPO_StatusCode.Success;
-                    result.StatusMessage = CPO_StatusMessage.Success;
-                    //statusCode = HttpStatusCode.OK;
-                    statusCode = StatusCodes.Status200OK;
+                    _innerData.Add(ToActiveSession(ChargeBoxId, transactionData));
                 }
+                var _innerResponse = new { Sessions = _innerData };
+                result.Data = JsonConvert.SerializeObject(_innerResponse, EVCBConfiguration.JSONSERIALIZER_FORMAT);
+
+                result.StatusCode = (int)CPO_StatusCode.Success;
+                result.StatusMessage = CPO_StatusMessage.Success;
+                //statusCode = HttpStatusCode.OK;
+                statusCode = StatusCodes.Status200OK;
 
                 //return Request.CreateResponse(statusCode, result);
                 return StatusCode(statusCode, result);
@@ -1794,16 +1776,102 @@ namespace EVCB_OCPP.WEBAPI.Controllers.Version1
         private bool ContainsChargePoint(string chargeBoxId, out string customerId)
         {
             customerId = string.Empty;
+            if (!IsCustomerIdAvaliable()) 
+                return false;
+            customerId = GetCustomerId();
 
-            if (!Request.Headers.ContainsKey(EVCBConfiguration.Header_PartnerId)) return false;
-
-            customerId = Request.Headers[EVCBConfiguration.Header_PartnerId].First();
+            return ContainsChargePointAsync(chargeBoxId, customerId).Result;
+        }
 
+        private ValueTask<bool> ContainsChargePointAsync(string chargeBoxId, string customerId)
+        {
             ChargePointService _service = serviceProvider.GetRequiredService<ChargePointService>();//;new ChargePointService();
-            return _service.ContainsChargePoint(chargeBoxId, customerId);
+            return _service.ContainsChargePointAsync(chargeBoxId, customerId);
+        }
 
+        private string GetCustomerId()
+        {
+            if (!IsCustomerIdAvaliable())
+                return string.Empty;
+            return Request.Headers[EVCBConfiguration.Header_PartnerId].First();
+        }
+
+        private bool IsCustomerIdAvaliable()
+        {
+            return Request.Headers.ContainsKey(EVCBConfiguration.Header_PartnerId);
         }
 
+        private ActiveSession ToActiveSession(string ChargeBoxId, TransasctionData trans)
+        {
+            string currencyText = string.IsNullOrEmpty(trans.Fee) ? "TWD" : trans.Fee.Remove(0, trans.Fee.Length - 3);
+
+            var toRerurn = new ActiveSession()
+            {
+                ChargeBoxId = ChargeBoxId,
+                SessionId = trans.Id,
+                ElaspedTime = (int)DateTime.UtcNow.Subtract(trans.StartTime).TotalMinutes,
+                ConnectorId = trans.ConnectorId,
+                IdTag = trans.StartIdTag,
+                Currency = currencyText
+            };
+
+            toRerurn.Power = "0";
+            toRerurn.Power_Format = UnitOfMeasure.W.ToString();
+            toRerurn.Current = "0";
+            toRerurn.Current_Format = UnitOfMeasure.A.ToString();
+            toRerurn.Energy = "0";
+            toRerurn.Energy_Format = UnitOfMeasure.Wh.ToString();
+            toRerurn.Voltage = "0";
+            toRerurn.Voltage_Format = UnitOfMeasure.V.ToString();
+            toRerurn.SOC = "0";
+            toRerurn.SOC_Format = UnitOfMeasure.Percent.ToString();
+            toRerurn.CurrentCost = "0";
+
+            Models.ConnectorMeterValue power = trans.MeterValues.FirstOrDefault(x => x.Measurand == Measurand.Power_Active_Import);
+            if (power is not null)
+            {
+                toRerurn.Power = power.Value;
+                toRerurn.Power_Format = power.Unit.ToString();
+            }
+            Models.ConnectorMeterValue current = trans.MeterValues.FirstOrDefault(x => x.Measurand == Measurand.Current_Import);
+            if (current is not null)
+            {
+                toRerurn.Current = current.Value;
+                toRerurn.Current_Format = current.Unit.ToString();
+            }
+            Models.ConnectorMeterValue _energy = trans.MeterValues.FirstOrDefault(x => x.Measurand == Measurand.TotalEnergy);
+            if (_energy is not null)
+            {
+                toRerurn.Energy = _energy.Value;
+                toRerurn.Energy_Format = _energy.Unit.ToString();
+            }
+            Models.ConnectorMeterValue voltage = trans.MeterValues.FirstOrDefault(x => x.Measurand == Measurand.Voltage);
+            if (voltage is not null)
+            {
+                toRerurn.Voltage = voltage.Value;
+                toRerurn.Voltage_Format = voltage.Unit.ToString();
+            }
+            Models.ConnectorMeterValue soc = trans.MeterValues.FirstOrDefault(x => x.Measurand == Measurand.SoC);
+            if (soc is not null)
+            {
+                toRerurn.SOC = soc.Value;
+                toRerurn.SOC_Format = soc.Unit.ToString();
+            }
+            Models.ConnectorMeterValue cost = trans.MeterValues.FirstOrDefault(x => x.Measurand == Measurand.ChargingCost);
+            if (cost is not null)
+            {
+                toRerurn.CurrentCost = cost.Value;
+            }
+
+            if (toRerurn.Energy_Format == UnitOfMeasure.Wh.ToString())
+            {
+                decimal energy = decimal.Parse(toRerurn.Energy);
+                energy = Decimal.Divide(energy, 1000);
+                toRerurn.Energy = energy.ToString("0.000");
+                toRerurn.Energy_Format = UnitOfMeasure.kWh.ToString();
+            }
 
+            return toRerurn;
+        }
     }
 }

+ 5 - 2
EVCB_OCPP.WEBAPI/Controllers/Version1/InternalController.cs

@@ -581,8 +581,11 @@ namespace EVCB_OCPP.WEBAPI.Controllers.Version1
                 ChargePointStatus? currentStatus = StartTransaction.ConnectorId.HasValue ? chargePointService.GetChargePointCurrentSatus(ChargeBoxId, StartTransaction.ConnectorId.Value).Value : (ChargePointStatus?)null;
 
 
-                if (StartTransaction.ConnectorId.HasValue && chargePointService.GetChargePointCurrentSatus(ChargeBoxId, StartTransaction.ConnectorId.Value).HasValue &&
-                    (currentStatus != ChargePointStatus.Available && currentStatus != ChargePointStatus.Reserved && currentStatus != ChargePointStatus.Preparing))
+                if (StartTransaction.ConnectorId.HasValue &&
+                    chargePointService.GetChargePointCurrentSatus(ChargeBoxId, StartTransaction.ConnectorId.Value).HasValue &&
+                    (currentStatus != ChargePointStatus.Available && 
+                    currentStatus != ChargePointStatus.Reserved &&
+                    currentStatus != ChargePointStatus.Preparing))
                 {
                     //return Request.CreateResponse(HttpStatusCode.BadRequest, new ErrorResponse() { Code = 2103, Message = EVCBConfiguration.ERROR_MSG_CONNECTOR_ISNOT_AVAILIABLE_MODE });
                     return StatusCode(

+ 4 - 1
EVCB_OCPP.WEBAPI/Services/ApiLogDbService.cs

@@ -217,6 +217,7 @@ namespace EVCB_OCPP.WEBAPI.Services
                 """;
 
             using var sqlConnection = await apiLogDbConnectionFactory.CreateAsync();
+            using var trans = await sqlConnection.BeginTransactionAsync();
 
             foreach (var log in parmsList)
             {
@@ -245,8 +246,10 @@ namespace EVCB_OCPP.WEBAPI.Services
                 parameters.Add("@RequestContentBody", log.RequestContentBody, DbType.String);
                 parameters.Add("@ResponseContentBody", log.ResponseContentBody, DbType.String);
 
-                await sqlConnection.ExecuteAsync(command, parameters);
+                await sqlConnection.ExecuteAsync(command, parameters, trans);
             }
+
+            await trans.CommitAsync();
         }
 
         private async ValueTask<bool> GetTableExist(DateTime tableDateTime)

+ 144 - 107
EVCB_OCPP.WEBAPI/Services/ChargePointService.cs

@@ -13,6 +13,9 @@ using Microsoft.Data.SqlClient;
 using EVCB_OCPP.Domain;
 using EVCB_OCPP.WEBAPI.Helpers;
 using System.Threading.Tasks;
+using System.Diagnostics;
+using Microsoft.Extensions.Logging;
+using NLog;
 
 namespace EVCB_OCPP.WEBAPI.Services
 {
@@ -30,17 +33,26 @@ namespace EVCB_OCPP.WEBAPI.Services
         private readonly IServiceProvider serviceProvider;
         private readonly SqlConnectionFactory<MainDBContext> mainDbConneciotnFactory;
         private readonly SqlConnectionFactory<MeterValueDBContext> meterValueDbConnectionFactory;
+        private readonly MainDbService mainDbService;
+        private readonly MeterValueDbService meterValueDbService;
+        private readonly ILogger<ChargePointService> logger;
 
         public ChargePointService(
             IServiceProvider serviceProvider,
             SqlConnectionFactory<MainDBContext> mainDbConneciotnFactory,
-            SqlConnectionFactory<MeterValueDBContext> meterValueDbConnectionFactory)
+            SqlConnectionFactory<MeterValueDBContext> meterValueDbConnectionFactory,
+            MainDbService mainDbService,
+            MeterValueDbService meterValueDbService,
+            ILogger<ChargePointService> logger)
         {
             //mainConnectionString = configuration.GetConnectionString("MainDBContext");
             //meterConnectionString = configuration.GetConnectionString("MeterValueDBContext");
             this.serviceProvider = serviceProvider;
             this.mainDbConneciotnFactory = mainDbConneciotnFactory;
             this.meterValueDbConnectionFactory = meterValueDbConnectionFactory;
+            this.mainDbService = mainDbService;
+            this.meterValueDbService = meterValueDbService;
+            this.logger = logger;
         }
 
         public DateTime GetLastUpdatedTimebyMachineId(string machineId)
@@ -434,139 +446,164 @@ namespace EVCB_OCPP.WEBAPI.Services
         }
 
 
-        public bool ContainsChargePoint(string chargeBoxId, string customerId)
+        public ValueTask<bool> ContainsChargePointAsync(string chargeBoxId, string customerId)
         {
-            bool existed = false;
-
-            if (string.IsNullOrEmpty(chargeBoxId)) return existed;
-
-            var parameters = new DynamicParameters();
-            parameters.Add("@ChargeBoxId", chargeBoxId, DbType.String, ParameterDirection.Input, 50);
-            parameters.Add("@CustomerId", customerId, DbType.String, ParameterDirection.Input, 36);
-
-
-            using (SqlConnection conn = mainDbConneciotnFactory.Create())
-            {
-                string strSql = "Select Count(*) from [dbo].[Machine] where ChargeBoxId=@ChargeBoxId and CustomerId=@CustomerId  and IsDelete=0; ";
-                existed = conn.ExecuteScalar<bool>(strSql, parameters, null, EVCBConfiguration.DB_DefaultConnectionTimeout);
-            }
+            return mainDbService.ContainsChargePointAsync(chargeBoxId, customerId);
+        }
 
-            return existed;
+        public List<TransasctionData> GetActiveSessionInfo(string chargeBoxId, List<Measurand> requiredMeasurands, int? sessionId = null, string idTag = "")
+        {
+            return GetActiveSessionInfoAsync(chargeBoxId, requiredMeasurands, sessionId: sessionId,idTag: idTag).Result;
         }
 
-        public List<TransasctionData> GetActiveSessionInfo(string chargeBoxId, List<Measurand> requiredMeasurands, string sessionId = "", string idTag = "")
+        public async Task<List<TransasctionData>> GetActiveSessionInfoAsync(string chargeBoxId, List<Measurand> requiredMeasurands,string customerId = null, int? sessionId = null, string idTag = null)
         {
             List<ConnectorMeterValue> meterValues = new List<ConnectorMeterValue>();
             ConnectorMeterValueModel meterModel = null;
             List<TransasctionData> transactionDatas = null;
-            if (string.IsNullOrEmpty(chargeBoxId)) return transactionDatas;
 
+            if (string.IsNullOrEmpty(chargeBoxId)) 
+                return transactionDatas;
 
-            try
-            {
-                var parameters = new DynamicParameters();
-                parameters.Add("@ChargeBoxId", chargeBoxId, DbType.String, ParameterDirection.Input, 50);
+            var watch = Stopwatch.StartNew();
+            var times = new List<long>();
 
+            transactionDatas = await mainDbService.GetActiveTransactionAsync(chargeBoxId, customerId, sessionId, idTag);
+            times.Add(watch.ElapsedMilliseconds);
 
-                using (SqlConnection conn = mainDbConneciotnFactory.Create())
-                {
-                    string date = DateTime.UtcNow.ToString("yyMMdd");
-                    string strSql = string.Empty;
-                    if (string.IsNullOrEmpty(sessionId) && string.IsNullOrEmpty(idTag))
-                    {
-                        strSql = "Select Id, ConnectorId, StartTime,Fee, StartIdTag from TransactionRecord " +
-                            "where StopTime = '1991-01-01 00:00:00.000' and ChargeBoxId = @ChargeBoxId and StartTime in (select  max(StartTime) from[TransactionRecord] where StopTime = '1991-01-01 00:00:00.000' and ChargeBoxId = @ChargeBoxId group by ConnectorId )";
-                    }
-                    else
-                    {
-                        parameters.Add(string.IsNullOrEmpty(sessionId) ? "@StartIdTag" : "@Id", string.IsNullOrEmpty(sessionId) ? idTag : sessionId, DbType.String, ParameterDirection.Input, 20);
-
-                        strSql = "Select Id, ConnectorId, StartTime,Fee, StartIdTag from TransactionRecord " +
-                          "where StopTime = '1991-01-01 00:00:00.000' and ChargeBoxId = @ChargeBoxId and StartTime in (select  max(StartTime) from [TransactionRecord] where  " + (string.IsNullOrEmpty(sessionId) ? "StartIdTag=@StartIdTag" : "Id=@Id") + " and StopTime = '1991-01-01 00:00:00.000' and ChargeBoxId = @ChargeBoxId group by ConnectorId )";
-
-                    }
-
-                    transactionDatas = conn.Query<TransasctionData>(strSql, parameters, null, true, EVCBConfiguration.DB_DefaultConnectionTimeout).ToList();
-
-
-                }
-
-            }
-            catch (Exception ex)
+            if (transactionDatas.Count == 0)
             {
-                ;
+                return new List<TransasctionData>();
             }
 
-
-            for (int i = 0; i < requiredMeasurands.Count; i++)
+            List<ConnectorMeterValueModel> metervalues = new();
+            var minStartTime = transactionDatas.Select(x => x.StartTime).Min();
+            while (minStartTime <= DateTime.Now)
             {
-                for (int j = 0; j < transactionDatas.Count; j++)
-                {
-                    var parameters = new DynamicParameters();
-                    parameters.Add("@ChargeBoxId", chargeBoxId, DbType.String, ParameterDirection.Input, 50);
-                    parameters.Add("@TransactionId", transactionDatas[j].Id, DbType.Int32, ParameterDirection.Input);
-                    parameters.Add("@MeasurandId", requiredMeasurands[i], DbType.Int32, ParameterDirection.Input);
-
-                    try
-                    {
-                        int retry = 0;
-                        string date = DateTime.UtcNow.ToString("yyMMdd");
+                var result = await meterValueDbService.GetChargeBoxTransactionMeterValues(
+                    minStartTime, chargeBoxId, transactionDatas.Select(x => x.Id), requiredMeasurands.Select(x => (int)x));
+                metervalues.AddRange(result);
 
-                        while (retry < 2)
-                        {
-                            retry++;
-                            using (SqlConnection conn = meterValueDbConnectionFactory.Create())
-                            {                              
-                                string strSql = "Select Top(1) * from [dbo].[ConnectorMeterValueRecord" + date + "] where ChargeBoxId=@ChargeBoxId and TransactionId=@TransactionId and MeasurandId=@MeasurandId order by CreatedOn desc;";
-                                meterModel = conn.QueryFirstOrDefault<ConnectorMeterValueModel>(strSql, parameters, null, EVCBConfiguration.DB_DefaultConnectionTimeout);//.FirstOrDefault();
-                                if (meterModel == null)
-                                {
-                                    date = transactionDatas[j].StartTime.ToString("yyMMdd");
-                                }
-                                else
-                                {
-                                    retry = 2;
-                                }
-
-                            }
-                        }
-
-                        if (meterModel != null)
-                        {
-                            if (transactionDatas[j].MeterValues == null)
-                            {
-                                transactionDatas[j].MeterValues = new List<ConnectorMeterValue>();
-                            }
+                minStartTime = minStartTime.AddDays(1);
 
-                            transactionDatas[j].MeterValues.Add(new ConnectorMeterValue()
-                            {
-                                ChargeBoxId = meterModel.ChargeBoxId,
-                                ConnectorId = meterModel.ConnectorId,
-                                CreatedOn = meterModel.CreatedOn,
-                                Context = meterModel.ContextId < 1 ? (ReadingContext?)null : (ReadingContext?)meterModel.ContextId,
-                                Format = meterModel.FormatId < 1 ? (ValueFormat?)null : (ValueFormat?)meterModel.FormatId,
-                                Location = meterModel.LocationId < 1 ? (Location?)null : (Location?)meterModel.LocationId,
-                                Measurand = meterModel.MeasurandId < 1 ? (Measurand?)null : (Measurand?)meterModel.MeasurandId,
-                                Phase = meterModel.PhaseId < 1 ? (Phase?)null : (Phase?)meterModel.PhaseId,
-                                Unit = meterModel.UnitId < 1 ? (UnitOfMeasure?)UnitOfMeasure.Wh : (UnitOfMeasure?)meterModel.UnitId,
-                                Value = meterModel.Value,
-                                TransactionId = meterModel.TransactionId
+                times.Add(watch.ElapsedMilliseconds);
+            }
 
-                            });
+            var transIdMeterValuesPair = metervalues.GroupBy(x => x.TransactionId).ToDictionary(x => x.Key, x => x.ToList());
 
+            foreach (var trans in transactionDatas)
+            {
+                if (trans.MeterValues == null)
+                {
+                    trans.MeterValues = new List<ConnectorMeterValue>();
+                }
 
+                if (!transIdMeterValuesPair.ContainsKey(trans.Id))
+                {
+                    continue;
+                }
+                var transMeterValues = transIdMeterValuesPair[trans.Id];
 
-                        }
-                    }
-                    catch (Exception ex)
+                foreach(var _meterModel in transMeterValues)
+                {
+                    trans.MeterValues.Add(new ConnectorMeterValue()
                     {
-                        break;
-                    }
-                }
+                        ChargeBoxId = _meterModel.ChargeBoxId,
+                        ConnectorId = _meterModel.ConnectorId,
+                        CreatedOn = _meterModel.CreatedOn,
+                        Context = _meterModel.ContextId < 1 ? (ReadingContext?)null : (ReadingContext?)_meterModel.ContextId,
+                        Format = _meterModel.FormatId < 1 ? (ValueFormat?)null : (ValueFormat?)_meterModel.FormatId,
+                        Location = _meterModel.LocationId < 1 ? (Location?)null : (Location?)_meterModel.LocationId,
+                        Measurand = _meterModel.MeasurandId < 1 ? (Measurand?)null : (Measurand?)_meterModel.MeasurandId,
+                        Phase = _meterModel.PhaseId < 1 ? (Phase?)null : (Phase?)_meterModel.PhaseId,
+                        Unit = _meterModel.UnitId < 1 ? (UnitOfMeasure?)UnitOfMeasure.Wh : (UnitOfMeasure?)_meterModel.UnitId,
+                        Value = _meterModel.Value,
+                        TransactionId = _meterModel.TransactionId
 
+                    });
+                }
+            }
 
+            times.Add(watch.ElapsedMilliseconds);
+            watch.Stop();
+            if (watch.ElapsedMilliseconds > 1000)
+            {
+                logger.LogWarning($"{nameof(GetActiveSessionInfoAsync)} {string.Join("/", times)}");
             }
 
+            //for (int i = 0; i < requiredMeasurands.Count; i++)
+            //{
+            //    for (int j = 0; j < transactionDatas.Count; j++)
+            //    {
+            //        var parameters = new DynamicParameters();
+            //        parameters.Add("@ChargeBoxId", chargeBoxId, DbType.String, ParameterDirection.Input, 50);
+            //        parameters.Add("@TransactionId", transactionDatas[j].Id, DbType.Int32, ParameterDirection.Input);
+            //        parameters.Add("@MeasurandId", requiredMeasurands[i], DbType.Int32, ParameterDirection.Input);
+
+            //        try
+            //        {
+            //            int retry = 0;
+            //            string date = DateTime.UtcNow.ToString("yyMMdd");
+
+            //            while (retry < 2)
+            //            {
+            //                retry++;
+            //                using (SqlConnection conn = await meterValueDbConnectionFactory.CreateAsync())
+            //                {
+            //                    string strSql = $"""
+            //                        SELECT Top(1) * from [dbo].[ConnectorMeterValueRecord{date}]
+            //                        WHERE ChargeBoxId=@ChargeBoxId and TransactionId=@TransactionId and MeasurandId=@MeasurandId 
+            //                        order by CreatedOn desc;
+            //                        """;
+            //                    meterModel = await conn.QueryFirstOrDefaultAsync<ConnectorMeterValueModel>(strSql, parameters, commandTimeout:EVCBConfiguration.DB_DefaultConnectionTimeout);//.FirstOrDefault();
+            //                    if (meterModel == null)
+            //                    {
+            //                        date = transactionDatas[j].StartTime.ToString("yyMMdd");
+            //                    }
+            //                    else
+            //                    {
+            //                        retry = 2;
+            //                    }
+
+            //                }
+            //            }
+
+            //            if (meterModel != null)
+            //            {
+            //                if (transactionDatas[j].MeterValues == null)
+            //                {
+            //                    transactionDatas[j].MeterValues = new List<ConnectorMeterValue>();
+            //                }
+
+            //                transactionDatas[j].MeterValues.Add(new ConnectorMeterValue()
+            //                {
+            //                    ChargeBoxId = meterModel.ChargeBoxId,
+            //                    ConnectorId = meterModel.ConnectorId,
+            //                    CreatedOn = meterModel.CreatedOn,
+            //                    Context = meterModel.ContextId < 1 ? (ReadingContext?)null : (ReadingContext?)meterModel.ContextId,
+            //                    Format = meterModel.FormatId < 1 ? (ValueFormat?)null : (ValueFormat?)meterModel.FormatId,
+            //                    Location = meterModel.LocationId < 1 ? (Location?)null : (Location?)meterModel.LocationId,
+            //                    Measurand = meterModel.MeasurandId < 1 ? (Measurand?)null : (Measurand?)meterModel.MeasurandId,
+            //                    Phase = meterModel.PhaseId < 1 ? (Phase?)null : (Phase?)meterModel.PhaseId,
+            //                    Unit = meterModel.UnitId < 1 ? (UnitOfMeasure?)UnitOfMeasure.Wh : (UnitOfMeasure?)meterModel.UnitId,
+            //                    Value = meterModel.Value,
+            //                    TransactionId = meterModel.TransactionId
+
+            //                });
+
+
+
+            //            }
+            //        }
+            //        catch (Exception ex)
+            //        {
+            //            break;
+            //        }
+            //    }
+
+
+            //}
+
             return transactionDatas;
         }
 

+ 2 - 2
EVCB_OCPP.WEBAPI/Services/ChargingStationService.cs

@@ -89,7 +89,7 @@ namespace EVCB_OCPP.WEBAPI.Services
             //    station.EVSEs = await GetEVSEsbyStationIdAsync(station.Id, null, null, -1, 100000);
             //});
 
-            var stationMachinePair = await GetStationMachinePairAsync(_stations.Select(x => x.Id));
+            Dictionary<int, List<string>> stationMachinePair = await GetStationMachinePairAsync(_stations.Select(x => x.Id));
             times.Add(watch.ElapsedMilliseconds);
 
             foreach (var station in _stations)
@@ -240,7 +240,7 @@ namespace EVCB_OCPP.WEBAPI.Services
                     .ToDictionary(x=>x.Key,x=>x.Value);
 
 
-                var pairs = await _CPService.GetBasicInfobyIdAsync(_machineUpdateOnPairs.Select(x=> x.Key));
+                Dictionary<string, EVSE> pairs = await _CPService.GetBasicInfobyIdAsync(_machineUpdateOnPairs.Select(x=> x.Key));
                 times.Add(watch.ElapsedMilliseconds);
 
                 foreach (var pair in pairs)

+ 2 - 1
EVCB_OCPP.WEBAPI/Services/InternalHttpClient.cs

@@ -16,7 +16,8 @@ namespace EVCB_OCPP.WEBAPI.Services
 {
     public class InternalHttpClient
     {
-        private const string DockerSelfUrl = "{0}://host.docker.internal:{1}";
+        //private const string DockerSelfUrl = "{0}://host.docker.internal:{1}";
+        private const string DockerSelfUrl = "http://localhost";
         private readonly HttpClientService httpClient;
         private readonly bool isInDocker;
 

+ 116 - 0
EVCB_OCPP.WEBAPI/Services/MainDbService.cs

@@ -0,0 +1,116 @@
+using Dapper;
+using EVCB_OCPP.Domain;
+using EVCB_OCPP.WEBAPI.Helpers;
+using EVCB_OCPP.WEBAPI.Models.WebAPI.Dto;
+using Microsoft.Data.SqlClient;
+using Microsoft.Extensions.Caching.Memory;
+using Microsoft.Extensions.Logging;
+using System;
+using System.Collections.Generic;
+using System.Data;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace EVCB_OCPP.WEBAPI.Services
+{
+    public class MainDbService
+    {
+        public MainDbService(
+            SqlConnectionFactory<MainDBContext> mainDbConneciotnFactory,
+            IMemoryCache memoryCache,
+            ILogger<MainDbService> logger)
+        {
+            this.memoryCache = memoryCache;
+            this.logger = logger;
+            this.mainDbConneciotnFactory = mainDbConneciotnFactory;
+        }
+
+        private readonly SqlConnectionFactory<MainDBContext> mainDbConneciotnFactory;
+        private readonly IMemoryCache memoryCache;
+        private readonly ILogger<MainDbService> logger;
+
+        public async ValueTask<bool> ContainsChargePointAsync(string chargeBoxId, string customerId)
+        {
+            bool existed = false;
+
+            if (string.IsNullOrEmpty(chargeBoxId)) return existed;
+
+            var parameters = new DynamicParameters();
+            parameters.Add("@ChargeBoxId", chargeBoxId, DbType.String, ParameterDirection.Input, 50);
+            parameters.Add("@CustomerId", customerId, DbType.String, ParameterDirection.Input, 36);
+
+
+            using (SqlConnection conn = await mainDbConneciotnFactory.CreateAsync())
+            {
+                string strSql = "Select COUNT(1) from [dbo].[Machine] where ChargeBoxId=@ChargeBoxId and CustomerId=@CustomerId  and IsDelete=0; ";
+                existed = await conn.ExecuteScalarAsync<bool>(strSql, parameters, null, EVCBConfiguration.DB_DefaultConnectionTimeout);
+            }
+
+            return existed;
+        }
+
+        internal async Task<List<TransasctionData>> GetActiveTransactionAsync(string chargeBoxId,string customerId, int? sessionId, string idTag)
+        {
+            var toReturn = new List<TransasctionData>();
+            try
+            {
+                var parameters = new DynamicParameters();
+                parameters.Add("@CustomerId", customerId, DbType.String, ParameterDirection.Input, 50);
+                parameters.Add("@ChargeBoxId", chargeBoxId, DbType.String, ParameterDirection.Input, 50);
+                parameters.Add("@StartIdTag",idTag, DbType.String, ParameterDirection.Input, 20);
+                parameters.Add("@Id", sessionId is null ? 0 : sessionId.Value, DbType.Int32, ParameterDirection.Input, 20);
+
+                string date = DateTime.UtcNow.ToString("yyMMdd");
+                //string strSql = string.Empty;
+                var cmd = CreateGetActiveTransactionCmd(customerId, sessionId, idTag);
+
+                using SqlConnection conn = await mainDbConneciotnFactory.CreateAsync();
+                toReturn = (await conn.QueryAsync<TransasctionData>(cmd, parameters, commandTimeout: EVCBConfiguration.DB_DefaultConnectionTimeout)).ToList();
+
+            }
+            catch (Exception ex)
+            {
+                logger.LogError(ex.Message);
+                logger.LogError(ex.StackTrace);
+            }
+
+            return toReturn;
+        }
+
+        private string CreateGetActiveTransactionCmd(string customerId, int? sessionId, string idTag)
+        {
+            string cmdBase = """
+                    WITH CTE AS (
+                        SELECT
+                            Id, ConnectorId, StartTime, Fee, StartIdTag,
+                            ROW_NUMBER() OVER (PARTITION BY s.ConnectorId ORDER BY s.StartTime DESC) AS RowNum
+                        FROM [dbo].[TransactionRecord] s
+                        WHERE StopTime = '1991-01-01 00:00:00.000' AND ChargeBoxId = @ChargeBoxId
+                            AND StopTransactionReportedOn = '1991-01-01 00:00:00.000'
+                            {0}
+                    )
+                    SELECT Id, ConnectorId, StartTime, Fee, StartIdTag
+                    FROM CTE
+                    WHERE RowNum = 1;
+                    """;
+            string param = string.Empty;
+
+            if (!string.IsNullOrEmpty(customerId))
+            {
+                param += ("AND CustomerId = @CustomerId ");
+            }
+
+            if (!string.IsNullOrEmpty(idTag))
+            {
+                param += ("AND StartIdTag = @StartIdTag ");
+            }
+
+            if (sessionId is not null)
+            {
+                param += ("AND Id = @Id ");
+            }
+
+            return string.Format(cmdBase, param);
+        }
+    }
+}

+ 60 - 0
EVCB_OCPP.WEBAPI/Services/MeterValueDbService.cs

@@ -0,0 +1,60 @@
+using Dapper;
+using EVCB_OCPP.Domain;
+using EVCB_OCPP.Packet.Messages.SubTypes;
+using EVCB_OCPP.WEBAPI.Helpers;
+using EVCB_OCPP.WEBAPI.Models;
+using EVCB_OCPP.WEBAPI.Models.WebAPI.Dto;
+using Microsoft.Data.SqlClient;
+using Microsoft.Extensions.Logging;
+using System;
+using System.Collections.Generic;
+using System.Data;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace EVCB_OCPP.WEBAPI.Services;
+
+public class MeterValueDbService
+{
+    public MeterValueDbService(
+        SqlConnectionFactory<MeterValueDBContext> meterValueDbConnectionFactory,
+        ILogger<MeterValueDbService> logger)
+    {
+        this.meterValueDbConnectionFactory = meterValueDbConnectionFactory;
+        this.logger = logger;
+    }
+
+    private readonly SqlConnectionFactory<MeterValueDBContext> meterValueDbConnectionFactory;
+    private readonly ILogger<MeterValueDbService> logger;
+
+    internal async Task<List<ConnectorMeterValueModel>> GetChargeBoxTransactionMeterValues(DateTime minStartTime, string chargeBoxId, IEnumerable<int> transactionIds, IEnumerable<int> measurandCodes)
+    {
+        var toReturn = new List<ConnectorMeterValueModel>();
+        string date = minStartTime.ToString("yyMMdd");
+        string cmd = $"""
+                    WITH CTE AS (
+                        SELECT
+                            s.*,
+                            ROW_NUMBER() OVER (PARTITION BY s.MeasurandId ORDER BY s.CreatedOn DESC) AS RowNum
+                        FROM [dbo].[ConnectorMeterValueRecord{date}] s
+                        WHERE s.ChargeBoxId = @ChargeBoxId
+                            AND s.TransactionId IN @TransactionIds
+                            AND s.MeasurandId IN @MeasurandIds
+                    )
+                    SELECT *
+                    FROM CTE
+                    WHERE RowNum = 1;
+                    """;
+
+        var parameters = new DynamicParameters();
+        parameters.Add("@ChargeBoxId", chargeBoxId, DbType.String, ParameterDirection.Input, 50);
+        parameters.Add("@TransactionIds", transactionIds);
+        parameters.Add("@MeasurandIds", measurandCodes);
+
+        using SqlConnection conn = await meterValueDbConnectionFactory.CreateAsync();
+        var result = await conn.QueryAsync<ConnectorMeterValueModel>(cmd, parameters, commandTimeout: EVCBConfiguration.DB_DefaultConnectionTimeout);
+        toReturn = result.ToList();
+
+        return toReturn;
+    }
+}

+ 6 - 0
EVCB_OCPP.WEBAPI/Services/OcppApiV1Service.cs

@@ -0,0 +1,6 @@
+namespace EVCB_OCPP.WEBAPI.Services
+{
+    public class OcppApiV1Service
+    {
+    }
+}

+ 30 - 20
EVCB_OCPP.WEBAPI/Services/ServerTriggerService.cs

@@ -13,6 +13,7 @@ using System.Net;
 using Microsoft.Data.SqlClient;
 using EVCB_OCPP.WEBAPI.Helpers;
 using EVCB_OCPP.Domain;
+using System.Threading.Tasks;
 
 namespace EVCB_OCPP.WEBAPI.Services
 {
@@ -20,6 +21,7 @@ namespace EVCB_OCPP.WEBAPI.Services
     public interface IServerTriggerService
     {
         void AddMessage(string ChargeBoxId, string uuid, IRequest request);
+        Task AddMessageAsync(string ChargeBoxId, string uuid, IRequest request);
 
     }
 
@@ -106,13 +108,24 @@ namespace EVCB_OCPP.WEBAPI.Services
 
         public void AddMessage(string ChargeBoxId, string uuid, IRequest request)
         {
-            string sql_MachineOperateRecord = "INSERT INTO [dbo].[MachineOperateRecord](SerialNo, RequestType, RequestContent,Status, CreatedOn, FinishedOn,"
-         + " EVSE_Value, EVSE_Status, ChargeBoxId, Action, ReportedOn) VALUES (@SerialNo, @RequestType, @RequestContent, @Status, @CreatedOn, @FinishedOn, @EVSE_Value, "
-         + "@EVSE_Status, @ChargeBoxId, @Action,@ReportedOn);";
+            AddMessageAsync(ChargeBoxId, uuid, request).Wait();
+        }
 
-            string sql_ServerMessage = "INSERT INTO [dbo].[ServerMessage] (SerialNo, OutAction, OutRequest, InMessage, CreatedOn, CreatedBy, ReceivedOn, ChargeBoxId" +
-                ", UpdatedOn)  VALUES (@SerialNo, @OutAction, @OutRequest, @InMessage, @CreatedOn, @CreatedBy, @ReceivedOn, @ChargeBoxId" +
-                ", @UpdatedOn);";
+        public async Task AddMessageAsync(string ChargeBoxId, string uuid, IRequest request)
+        {
+            string sql_MachineOperateRecord = """
+                INSERT INTO [dbo].[MachineOperateRecord]
+                (SerialNo, RequestType, RequestContent,Status, CreatedOn, FinishedOn, EVSE_Value, EVSE_Status, ChargeBoxId, Action, ReportedOn) 
+                VALUES
+                (@SerialNo, @RequestType, @RequestContent, @Status, @CreatedOn, @FinishedOn, @EVSE_Value, @EVSE_Status, @ChargeBoxId, @Action, @ReportedOn);
+                """;
+
+            string sql_ServerMessage = """
+                INSERT INTO [dbo].[ServerMessage] 
+                (SerialNo, OutAction, OutRequest, InMessage, CreatedOn, CreatedBy, ReceivedOn, ChargeBoxId, UpdatedOn)
+                VALUES
+                 (@SerialNo, @OutAction, @OutRequest, @InMessage, @CreatedOn, @CreatedBy, @ReceivedOn, @ChargeBoxId, @UpdatedOn);
+                """;
 
             string key = string.Empty;
             var parameters = new DynamicParameters();
@@ -137,23 +150,20 @@ namespace EVCB_OCPP.WEBAPI.Services
             parameters.Add("@ReportedOn", EVCBConfiguration.DefaultTime, DbType.DateTime, ParameterDirection.Input);
 
 
-            using (SqlConnection conn = mainDbConnectionFactory.Create())
+            using (SqlConnection conn = await mainDbConnectionFactory.CreateAsync())
+            using (var transaction = await conn.BeginTransactionAsync())
             {
-                using (var transaction = conn.BeginTransaction())
+                try
                 {
-                    try
-                    {
-                        conn.Execute(sql_MachineOperateRecord, parameters, transaction);
-                        conn.Execute(sql_ServerMessage, parameters, transaction);
-                        transaction.Commit();
-                    }
-                    catch
-                    {
-                        transaction.Rollback();
-                        throw;
-                    }
+                    await conn.ExecuteAsync(sql_MachineOperateRecord, parameters, transaction);
+                    await conn.ExecuteAsync(sql_ServerMessage, parameters, transaction);
+                    await transaction.CommitAsync();
+                }
+                catch
+                {
+                    await transaction.RollbackAsync();
+                    throw;
                 }
-
             }
         }
 

+ 3 - 0
EVCB_OCPP.WEBAPI/Startup.cs

@@ -62,7 +62,10 @@ namespace EVCB_OCPP.WEBAPI
             services.AddSingleton<InernalAuthentication>();
             services.AddSingleton<InternalHttpClient>();
 
+            services.AddMemoryCache();
             services.AddSingleton<ApiLogDbService>();
+            services.AddSingleton<MainDbService>();
+            services.AddSingleton<MeterValueDbService>();
         }
 
         // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.