BMUManager.cs 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. using GSG.NET.Concurrent;
  2. using GSG.NET.Extensions;
  3. using GSG.NET.Logging;
  4. using GSG.NET.Quartz;
  5. using GSG.NET.Utils;
  6. using System;
  7. using System.Collections.Generic;
  8. using System.Linq;
  9. using System.Text;
  10. using System.Threading;
  11. using System.Threading.Tasks;
  12. using VehicleControlSystem.ControlLayer.Serial.DataModel;
  13. namespace VehicleControlSystem.ControlLayer.Serial.BatteryTabos
  14. {
  15. public class BMUManager
  16. {
  17. static Logger logger = Logger.GetLogger();
  18. Peak com = null;
  19. Advantech adCom = null;
  20. public Config BMUConfig { get; set; }
  21. public bool IsConnected { get { return this.adCom.IsConnected; } }
  22. internal Dictionary<eDataKind, ReceivedData> ReceivedDataDic = new Dictionary<eDataKind , DataModel.ReceivedData>();
  23. protected TsQueue<QueObject> qq = new TsQueue<QueObject>( 512 );
  24. public ThreadCancel cancel = new ThreadCancel();
  25. CbTimer polling = new CbTimer();
  26. long collectNo = 0;
  27. long collectElasped = 0;
  28. protected object LockObject = new object();
  29. public enum eCANSelect
  30. {
  31. Advantech = 0,
  32. Peak
  33. }
  34. #region Event
  35. public event Action<string,bool> OnConnect;
  36. public event Action<string, bool> OnDisconnect;
  37. public event Action<ReceivedData> OnChangedReceivedData;
  38. public event Action<List<ReceivedData>> OnFirstColtd;
  39. #endregion
  40. public BMUManager()
  41. {
  42. this.BMUConfig = new Config();
  43. this.Init();
  44. }
  45. private void Init()
  46. {
  47. EnumExtensions.GetValues<eDataKind>().ToList().ForEach( x =>
  48. {
  49. var data = new ReceivedData( x );
  50. switch ( x )
  51. {
  52. case eDataKind.Voltage:
  53. data.Scale = 0.01;
  54. break;
  55. case eDataKind.Current:
  56. data.Scale = 0.01;
  57. break;
  58. case eDataKind.BatteryState:
  59. data.Scale = 1;
  60. break;
  61. case eDataKind.ChargeCompleteTime:
  62. data.Scale = 60;
  63. break;
  64. case eDataKind.DisChargeCompleteTime:
  65. data.Scale = 60;
  66. break;
  67. case eDataKind.SOC:
  68. data.Scale = 1;
  69. break;
  70. case eDataKind.SOH:
  71. data.Scale = 1;
  72. break;
  73. case eDataKind.ResidualCapacity:
  74. data.Scale = 0.01;
  75. break;
  76. case eDataKind.ResidualEnergy:
  77. data.Scale = 0.1;
  78. break;
  79. case eDataKind.Temperature:
  80. data.Scale = 0.1;
  81. break;
  82. default:
  83. break;
  84. }
  85. this.ReceivedDataDic.Add( x, data);
  86. } );
  87. }
  88. protected void EnqueueToNet( object o )
  89. {
  90. //this.com.Enqueue( o );
  91. this.adCom.Enqueue( o );
  92. }
  93. protected void _ThPullQueue()
  94. {
  95. while ( !cancel.Canceled )
  96. {
  97. try
  98. {
  99. var qo = this.qq.Dequeue();
  100. if ( qo is QoConnect )
  101. DelegateUtils.Invoke( OnConnect , qo.Arg0, qo.Arg1 );
  102. else if ( qo is QoDisconnected )
  103. DelegateUtils.Invoke( OnDisconnect , qo.Arg0, qo.Arg1 );
  104. else if ( qo is QoReceivedDataChanged )
  105. DelegateUtils.Invoke( OnChangedReceivedData , qo.Arg0 );
  106. //else if ( qo is QoSendMessageSuccess )
  107. // DelegateUtils.Invoke( OnSendSetDataSuccess, qo.Arg0 );
  108. else
  109. Assert.Fail( "Unk Object {0}" , qo );
  110. }
  111. catch ( ThreadAbortException )
  112. {
  113. break;
  114. }
  115. catch ( Exception e )
  116. {
  117. logger.E( e );
  118. }
  119. }
  120. }
  121. #region Net Invoke Method
  122. internal void _OnConnected()
  123. {
  124. if ( 0 != collectNo )
  125. this.qq.Enqueue( new QoConnect { Arg0 = this.BMUConfig.ID, Arg1 = true } );
  126. _OnTimePoll();
  127. }
  128. internal void _OnDisconnected()
  129. {
  130. this.qq.Enqueue( new QoDisconnected { Arg0 = this.BMUConfig.ID, Arg1 = false } );
  131. }
  132. internal void _InvokeChgdWordsAndBits()
  133. {
  134. //Todo: 변경 된 내용 처리.
  135. if ( 0 == collectNo )
  136. {
  137. //this.qq.Enqueue( new QoConnect { Arg0 = this.BMUConfig.ID } );
  138. var ll = this.ReceivedDataDic.Values.ToList();
  139. DelegateUtils.Invoke( OnFirstColtd, ll );
  140. }
  141. //var v = new MapScan
  142. //{
  143. // CollectTime = (int)SwUtils.Elapsed( collectElasped )
  144. //};
  145. //DlgUtils.Invoke( OnCollected, v );
  146. if ( long.MaxValue <= this.collectNo )
  147. this.collectNo = 1;
  148. this.collectNo++;
  149. var rlist = this.ReceivedDataDic.Values.ToList();
  150. rlist.ForEach( r =>
  151. {
  152. if ( r.IsChanged )
  153. {
  154. r.IsChanged = false;
  155. //clone test
  156. //var clone = ObjectCopyUtils.DeepClone( r );
  157. this.qq.Enqueue( new QoReceivedDataChanged { Arg0 = r } );
  158. }
  159. } );
  160. //다음 timer 기동 시 까지 잠시 대기
  161. polling.Once( _OnTimePoll, 1000 );
  162. }
  163. void _OnTimePoll()
  164. {
  165. //Todo: Scan 으로 읽어 오는 영역의 명령을 Net 쪽으로 보내야함.
  166. lock ( this.LockObject )
  167. {
  168. collectElasped = SwUtils.T;
  169. this.EnqueueToNet( new PollingObject() );
  170. this.EnqueueToNet( new DoInvokeChangedReceivedData() );//Invoke Changed
  171. }
  172. }
  173. //internal void _OnSendDataSuccess( ISetData data )
  174. //{
  175. // this.qq.Enqueue( new QoSendMessageSuccess { Arg0 = data } );
  176. //}
  177. #endregion
  178. #region Public Method
  179. public void Connect(eCANSelect select)
  180. {
  181. //외부 전달 시작
  182. this.cancel.AddGo( _ThPullQueue );
  183. //읽기 시작.
  184. switch ( select )
  185. {
  186. case eCANSelect.Advantech:
  187. this.adCom = new Advantech( this , "can1" );
  188. this.cancel.AddGo( this.adCom._ThreadPoolingReceiveData );
  189. break;
  190. case eCANSelect.Peak:
  191. this.com = new Peak( this );
  192. this.cancel.AddGo( this.com._ThreadPoolingReceiveData );
  193. break;
  194. }
  195. }
  196. public void Disconnect()
  197. {
  198. collectNo = 0;
  199. //Thread Stop
  200. this.cancel.Cancel();
  201. this.cancel.StopWaitAll();
  202. }
  203. public void test()
  204. {
  205. var clone = this.ReceivedDataDic.Values.FirstOrDefault();
  206. this.qq.Enqueue( new QoReceivedDataChanged { Arg0 = clone } );
  207. }
  208. #endregion
  209. }
  210. }