BMUManager.cs 7.5 KB

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