| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401 |
- using GSG.NET.Concurrent;
- using GSG.NET.Extensions;
- using GSG.NET.Logging;
- using GSG.NET.TCP;
- 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();
- }
- //Todo:Dll 에서 상태 가져오기
- 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 )
- {
- this.CanError( );
- }
- catch ( IOException 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;
- Thread.Sleep( 100 );
- for ( int i = 0; i < 3; i++ )
- {
- stsResult = PCANBasic.Read( this.handle , out canMsg , out CANTimeStamp );
- if ( canMsg.ID != 0x460 )
- {
- this.IsConnected = false;
- return 0;
- }
- if(stsResult == TPCANStatus.PCAN_ERROR_OK)
- this.PeackCANRecv( canMsg );
- }
- return stsResult;
- }
- void PeackCANRecv(TPCANMsg recv)
- {
- string packet = BitConverter.ToString( recv.DATA ).Replace( "-" , "" );
- eCanRecvCase recvIndex = eCanRecvCase.NONE;
- List<string> sList = new List<string>();
- for ( int i = 0; i < packet.Length; i++ )
- {
- if ( i % 2 == 0 )
- sList.Add( packet.Substring( i , 2 ) );
- }
- if ( recv.DATA[ 1 ] == 0 ) //empty
- return;
- else
- recvIndex = ( eCanRecvCase )recv.DATA[ 1 ];
- switch ( recvIndex )
- {
- case eCanRecvCase.NONE:
- break;
- case eCanRecvCase.CASE1:
- this.manager.ReceivedDataDic[ eDataKind.Voltage ].Value = Int32.Parse( sList[ ( int )eMsgCaseFirst.Voltage_HIGH ] + sList[ ( int )eMsgCaseFirst.Voltage_LOW ] , System.Globalization.NumberStyles.HexNumber );
- this.manager.ReceivedDataDic[ eDataKind.Current ].Value = Int32.Parse( sList[ ( int )eMsgCaseFirst.Current_HIGH ] + sList[ ( int )eMsgCaseFirst.Current_LOW ] , System.Globalization.NumberStyles.HexNumber );
- this.manager.ReceivedDataDic[ eDataKind.BatteryState ].Value = Int32.Parse( sList[ ( int )eMsgCaseFirst.BatteryBitStatus_HIGH ] + sList[ ( int )eMsgCaseFirst.BatteryBitStatus_LOW ] , System.Globalization.NumberStyles.HexNumber );
- break;
- case eCanRecvCase.CASE2:
- this.manager.ReceivedDataDic[ eDataKind.ChargeCompleteTime ].Value = Int32.Parse( sList[ ( int )eMsgCaseSecond.ChargeFull_HIGH ] + sList[ ( int )eMsgCaseSecond.ChargeFull_LOW ] , System.Globalization.NumberStyles.HexNumber );
- this.manager.ReceivedDataDic[ eDataKind.DisChargeCompleteTime ].Value = Int32.Parse( sList[ ( int )eMsgCaseSecond.DisChargeEmpty_HIGH ] + sList[ ( int )eMsgCaseSecond.DisChargeEmpty_LOW ] , System.Globalization.NumberStyles.HexNumber );
- this.manager.ReceivedDataDic[ eDataKind.SOC ].Value = Int32.Parse( sList[ ( int )eMsgCaseSecond.SOC ] , System.Globalization.NumberStyles.HexNumber );
- this.manager.ReceivedDataDic[ eDataKind.SOH ].Value = Int32.Parse( sList[ ( int )eMsgCaseSecond.SOH ] , System.Globalization.NumberStyles.HexNumber );
- break;
- case eCanRecvCase.CASE3:
- this.manager.ReceivedDataDic[ eDataKind.ResidualCapacity ].Value = Int32.Parse( sList[ ( int )eMsgCaseThird.Capacity_High ] + sList[ ( int )eMsgCaseThird.Capacity_LOW ] , System.Globalization.NumberStyles.HexNumber );
- this.manager.ReceivedDataDic[ eDataKind.ResidualEnergy ].Value = Int32.Parse( sList[ ( int )eMsgCaseThird.Energy_HIGH ] + sList[ ( int )eMsgCaseThird.Energy_LOW ] , System.Globalization.NumberStyles.HexNumber );
- this.manager.ReceivedDataDic[ eDataKind.Temperature ].Value = Int32.Parse( sList[ ( int )eMsgCaseThird.Temperature_HIGH ] + sList[ ( int )eMsgCaseThird.Temperature_LOW ] , System.Globalization.NumberStyles.HexNumber );
- 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( 10 );
- var state = PCANBasic.Read( this.handle , out msg , out canTimeStamp );
- if ( msg.ID == 0x460 )
- result = true;
- else
- result = false;
- return result;
- }
- private void DisConnect( )
- {
- this.IsConnected = false;
- PCANBasic.Reset( this.handle );
- PCANBasic.Uninitialize( this.handle );
- this.manager._OnDisconnected();
- }
- }
- }
|