using EVCB_OCPP.Packet.Messages.Basic; using EVCB_OCPP.WSServer.Dto; using log4net.Core; using Microsoft.Extensions.Logging; namespace EVCB_OCPP.WSServer.Service.WsService; public enum BootStatus { Startup = 0, Initializing, Pending, Accepted } public class WsClientData : WsSession { /// <summary> /// 根據unique id來儲存.取出OCPP Request /// </summary> public Queue queue = new Queue(); public EVCB_OCPP20.Packet.Messages.Basic.Queue queue20 = new EVCB_OCPP20.Packet.Messages.Basic.Queue(); public BootStatus BootStatus { get; set; } = BootStatus.Startup; //public bool? IsPending { set; get; } public bool IsCheckIn { set; get; } = false; public string ChargeBoxId { set; get; } public Guid CustomerId { get; set; } public string MachineId { set; get; } public bool ISOCPP20 { set; get; } public bool ResetSecurityProfile { set; get; } public bool IsAC { set; get; } = true; #region Billing public Dictionary<string, string> UserPrices { set; get; } = new Dictionary<string, string>(); public Dictionary<string, string> UserDisplayPrices { set; get; } = new Dictionary<string, string>(); public List<ChargingPrice> ChargingPrices { set; get; } /// <summary> /// 電樁顯示費率 /// </summary> public string DisplayPrice { set; get; } /// <summary> /// 充電費率 以小時計費 /// </summary> public decimal ChargingFeebyHour { set; get; } /// <summary> /// 停車費率 以小時計費 /// </summary> public decimal ParkingFee { set; get; } /// <summary> /// 電樁是否計費 /// </summary> public bool IsBilling { set; get; } /// <summary> /// 收費方式 1: 以度計費 2:以小時計費 /// </summary> public int BillingMethod { set; get; } /// <summary> /// 電樁適用幣別 /// </summary> public string Currency { get; internal set; } #endregion public string CustomerName { get; set; } public string ChargePointVendor { get; set; } //public int? StationId { set; get; } = null; public Dictionary<string, object> Data = new Dictionary<string, object>(); public event EventHandler<string> m_ReceiveData; private string stringBuffer = string.Empty; private readonly ILogger<WsClientData> logger; private List<Task> AttachedTasks = new List<Task>(); public WsClientData(ILogger<WsClientData> logger) : base(logger) { ChargeBoxId = SessionID; MachineId = SessionID; this.logger = logger; } public void AddTask(Task toAddTask) { AttachedTasks.Add(toAddTask); toAddTask.ContinueWith(t => { AttachedTasks.Remove(toAddTask); }); } internal override void HandleReceivedData(string data) { stringBuffer += data; //logger.LogInformation("{StringBuffer}", stringBuffer); while (TryGetOCPPMsg(ref stringBuffer, out var msg)) { m_ReceiveData?.Invoke(this, msg); } } private bool TryGetOCPPMsg(ref string buffer, out string msg) { msg = string.Empty; int? startIndex = null; int? stopIndex = null; uint cnt = 0; for (int index = 0; index < buffer.Length; index++) { if (buffer[index] == '[') { cnt++; if (startIndex == null) { startIndex = index; } } if (startIndex != null && buffer[index] == ']') { cnt--; } if (startIndex != null && cnt == 0) { stopIndex = index; break; } } if (startIndex is not null && stopIndex is not null) { msg = buffer.Substring(startIndex.Value, (stopIndex.Value - startIndex.Value)+1); buffer = buffer.Substring(stopIndex.Value + 1); return true; } return false; } }