| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414 |
- using GSG.NET.Concurrent;
- using GSG.NET.Extensions;
- using GSG.NET.Logging;
- using GSG.NET.TCP;
- using GSG.NET.Utils;
- using Peak.Can.Basic;
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using System.IO;
- using System.Linq;
- using System.Text;
- using System.Threading;
- using System.Threading.Tasks;
- using VehicleControlSystem.ControlLayer.IO;
- using VehicleControlSystem.ControlLayer.Serial.DataModel;
- namespace VehicleControlSystem.ControlLayer.Serial.BatteryTabos
- {
- public class Peak : ICanConnecter
- {
- /// <summary>
- /// Peak USB Handle
- /// </summary>
- UInt16 handle = PCANBasic.PCAN_PCIBUS2;
- static Logger logger = Logger.GetLogger();
- protected TsQueue<object> qqW = new TsQueue<object>(128);//write
- BMUManager manager = null;
- object lockObject = new object();
- uint idOffset = 0x460;
- string errormsg = string.Empty;
- #region Enum
- public enum eSendMode
- {
- MANUAL = 0,
- AUTO,
- AUTO_STOP
- }
- public enum eCanRecvCase
- {
- NONE = 0,
- CASE1,
- CASE2,
- CASE3,
- }
- enum eMsgCaseFirst : int
- {
- Voltage_LOW = 2,
- Voltage_HIGH = 3,
- Current_LOW = 4,
- Current_HIGH = 5,
- BatteryBitStatus_LOW = 6,
- BatteryBitStatus_HIGH = 7
- }
- enum eMsgCaseSecond : int
- {
- ChargeFull_LOW = 2,
- ChargeFull_HIGH = 3,
- DisChargeEmpty_LOW,
- DisChargeEmpty_HIGH,
- SOC,
- SOH
- }
- enum eMsgCaseThird
- {
- Capacity_LOW = 2,
- Capacity_High,
- Energy_LOW,
- Energy_HIGH,
- Temperature_LOW,
- Temperature_HIGH
- }
- #endregion
- public Peak(BMUManager mrg)
- {
- this.manager = mrg;
- }
- public void Enqueue(object o)
- {
- this.qqW.Enqueue(o);
- }
- void TryToConnect()
- {
- this.qqW.Clear();
- var ll = PCANBasic.Reset(this.handle);
- ll = PCANBasic.Uninitialize(this.handle);
- var result = PCANBasic.Initialize(this.handle, TPCANBaudrate.PCAN_BAUD_500K, TPCANType.PCAN_TYPE_ISA, IOPort: 460, 3);
- if (result == TPCANStatus.PCAN_ERROR_OK)
- this.IsConnected = this.GetStatus();
- }
- bool isConnected = false;
- public bool IsConnected
- {
- get => this.isConnected;
- set
- {
- if (this.isConnected == value) return;
- this.isConnected = value;
- if (value)
- this.manager._OnConnected();
- else
- this.manager._OnDisconnected();
- }
- }
- public void _ThreadPoolingReceiveData()
- {
- while (!this.manager.cancel.Canceled)
- {
- try
- {
- if (!IsConnected)
- {
- Thread.Sleep(3000);
- this.TryToConnect();
- continue;
- }
- object o = this.qqW.Dequeue();
- if (o is PollingObject) //Scan 을 주기적 으로 진행.
- {
- //this.PollingBattery();
- this.Write(eSendMode.MANUAL);
- this.ReadMessage();
- }
- //else if ( o is ISetData ) //하나의 명령을 수행.
- //{
- // //ExecuteSetData( o as ISetData );
- //}
- else if (o is DoInvokeChangedReceivedData) //Scan 이후 결과를 처리. Manager 에서 처리
- {
- //this.manager._InvokeChgdReceivedData();
- this.manager._InvokeChgdWordsAndBits();
- }
- }
- catch (ThreadAbortException exception)
- {
- logger.E($"eSlnet {this.manager.BMUConfig.ID} - {exception.Message}");
- //h.CloseSocket();
- }
- catch (ObjectDisposedException exception)
- {
- logger.E(exception);
- this.CanError();
- }
- catch (IOException exception)
- {
- logger.E(exception);
- this.CanError();
- }
- catch (Exception exception)
- {
- this.CanError();
- logger.E($"eSlnet {exception.Message}");
- }
- }
- }
- private void PollingBattery()
- {
- var ll = this.manager.ReceivedDataDic.Values.ToList();
- ll.ForEach(x =>
- {
- var kind = CastTo<eDataKind>.From<Enum>(x.DataKind);
- switch (kind)
- {
- case eDataKind.Voltage:
- break;
- case eDataKind.Current:
- break;
- case eDataKind.BatteryState:
- break;
- case eDataKind.ChargeCompleteTime:
- break;
- case eDataKind.DisChargeCompleteTime:
- break;
- case eDataKind.SOC:
- break;
- case eDataKind.SOH:
- break;
- case eDataKind.ResidualCapacity:
- break;
- case eDataKind.ResidualEnergy:
- break;
- case eDataKind.Temperature:
- break;
- default:
- break;
- }
- });
- }
- int Write(eSendMode mode)
- {
- var data = new TPCANMsg();
- data.DATA = new byte[8];
- data.ID = idOffset + Convert.ToByte(this.manager.BMUConfig.ID);
- data.LEN = Convert.ToByte(8);
- data.MSGTYPE = TPCANMessageType.PCAN_MESSAGE_STANDARD;
- switch (mode)
- {
- case eSendMode.MANUAL:
- data.DATA[0] = Convert.ToByte(0x60 + Convert.ToByte(this.manager.BMUConfig.ID));
- break;
- case eSendMode.AUTO:
- data.DATA[0] = 0xAA;
- data.DATA[1] = 0xE0;
- break;
- case eSendMode.AUTO_STOP:
- data.DATA[0] = 0xAA;
- data.DATA[1] = 0x60;
- break;
- }
- var result = PCANBasic.Write(this.handle, ref data);
- if (result != TPCANStatus.PCAN_ERROR_OK)
- throw new Exception("Peak Write Fail");
- return 0;
- }
- int Write(bool auto = false)
- {
- var data = new TPCANMsg();
- data.DATA = new byte[8];
- data.ID = idOffset + Convert.ToByte(this.manager.BMUConfig.ID);
- data.LEN = Convert.ToByte(8);
- data.MSGTYPE = TPCANMessageType.PCAN_MESSAGE_STANDARD;
- if (auto)
- {
- data.DATA[0] = 0xAA;
- data.DATA[1] = 0xE0;
- }
- else
- {
- data.DATA[0] = Convert.ToByte(0x60 + Convert.ToByte(this.manager.BMUConfig.ID));
- }
- var result = PCANBasic.Write(this.handle, ref data);
- // Write Error
- if (result != TPCANStatus.PCAN_ERROR_OK)
- {
- logger.E($"[Battery Peak] - {result} -");
- return 9999;
- }
- return (int)result;
- }
- /// <summary>
- /// Peak Receive
- /// </summary>
- /// <returns></returns>
- TPCANStatus ReadMessage()
- {
- TPCANMsg canMsg = new TPCANMsg();
- canMsg.DATA = new byte[8];
- TPCANTimestamp CANTimeStamp;
- TPCANStatus stsResult = TPCANStatus.PCAN_ERROR_UNKNOWN;
- for (int i = 0; i < 3; i++)
- {
- Thread.Sleep(30);
- stsResult = PCANBasic.Read(this.handle, out canMsg, out CANTimeStamp);
- if (stsResult == TPCANStatus.PCAN_ERROR_OK)
- {
- if (canMsg.ID == 0x460)
- this.PeackCANRecv(canMsg);
- }
- else
- {
- this.IsConnected = this.GetStatus();
- return stsResult;
- }
- //else if (canMsg.ID != 0x460)
- //{
- // this.IsConnected = this.GetStatus();
- // return stsResult = TPCANStatus.PCAN_ERROR_UNKNOWN;
- //}
- }
- return stsResult;
- }
- void PeackCANRecv(TPCANMsg recv)
- {
- var mb = new MemoryBuffer(recv.DATA);
- if (mb.Length < 8)
- {
- logger.E($" - [Battery Recv Length Error] - {mb.Length} -");
- return;
- }
- mb.Read1Byte();
- var index = (eCanRecvCase)mb.Read1Byte();
- switch (index)
- {
- case eCanRecvCase.NONE:
- break;
- case eCanRecvCase.CASE1:
- this.manager.ReceivedDataDic[eDataKind.Voltage].Value = mb.ReadLeShort();
- this.manager.ReceivedDataDic[eDataKind.Current].Value = mb.ReadLeShort();
- this.manager.ReceivedDataDic[eDataKind.BatteryState].Value = mb.ReadLeShort();
- break;
- case eCanRecvCase.CASE2:
- this.manager.ReceivedDataDic[eDataKind.ChargeCompleteTime].Value = mb.ReadLeShort();
- this.manager.ReceivedDataDic[eDataKind.DisChargeCompleteTime].Value = mb.ReadLeShort();
- this.manager.ReceivedDataDic[eDataKind.SOC].Value = mb.ReadByte();
- this.manager.ReceivedDataDic[eDataKind.SOH].Value = mb.ReadByte();
- break;
- case eCanRecvCase.CASE3:
- this.manager.ReceivedDataDic[eDataKind.ResidualCapacity].Value = mb.ReadLeShort();
- this.manager.ReceivedDataDic[eDataKind.ResidualEnergy].Value = mb.ReadLeShort();
- this.manager.ReceivedDataDic[eDataKind.Temperature].Value = mb.ReadLeShort();
- break;
- }
- }
- /// <summary>
- /// Battery State To -> [2^6] Bool List
- /// </summary>
- /// <param name="state"></param>
- void BatteryStateCheck(double state)
- {
- var cd = Convert.ToByte(state);
- var rs = new BitArray(new byte[] { cd });
- var result = rs.Cast<object>().ToList();
- }
- void CanError()
- {
- this.IsConnected = false;
- var result = PCANBasic.Uninitialize(this.handle);
- }
- bool GetStatus()
- {
- bool result = false;
- TPCANMsg msg;
- msg.DATA = new byte[8];
- TPCANTimestamp canTimeStamp;
- Write(eSendMode.MANUAL);
- Thread.Sleep(100);
- var state = PCANBasic.Read(this.handle, out msg, out canTimeStamp);
- if (state != TPCANStatus.PCAN_ERROR_OK)
- {
- logger.E($"[BMS] - Disconnected [{state}]");
- return false;
- }
- //if (msg.ID == 0x460)
- // result = true;
- //else
- // result = false;
- return true;
- }
- private void DisConnect()
- {
- this.IsConnected = false;
- PCANBasic.Reset(this.handle);
- PCANBasic.Uninitialize(this.handle);
- this.manager._OnDisconnected();
- }
- }
- }
|