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