ModuleFsmDevice.cs 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335
  1. using Aitex.Core.RT.Device;
  2. using Aitex.Core.RT.Event;
  3. using Aitex.Core.RT.Fsm;
  4. using Aitex.Core.RT.Log;
  5. using Aitex.Core.RT.Routine;
  6. using Aitex.Core.RT.SCCore;
  7. using System;
  8. using System.Collections.Generic;
  9. using System.Diagnostics;
  10. using System.Linq;
  11. using System.Text;
  12. using System.Threading;
  13. using System.Threading.Tasks;
  14. namespace FurnaceRT.Equipments.Systems
  15. {
  16. public class ModuleFsmDevice : FsmDevice
  17. {
  18. public bool IsInstalled
  19. {
  20. get
  21. {
  22. if (!SC.ContainsItem($"System.SetUp.Is{Module}Installed"))
  23. return true;
  24. return SC.GetValue<bool>($"System.SetUp.Is{Module}Installed");
  25. }
  26. }
  27. public virtual bool IsOnline
  28. {
  29. get;
  30. set;
  31. }
  32. protected Queue<IRoutine> QueueRoutine
  33. {
  34. get { return _routine; }
  35. }
  36. private Queue<IRoutine> _routine = new Queue<IRoutine>();
  37. public ModuleFsmDevice() : base()
  38. {
  39. }
  40. public override bool Initialize()
  41. {
  42. return base.Initialize();
  43. }
  44. public Result StartRoutine(IRoutine routine)
  45. {
  46. QueueRoutine.Clear();
  47. QueueRoutine.Enqueue(routine);
  48. return QueueRoutine.Peek().Start();
  49. }
  50. public Result StartRoutine()
  51. {
  52. if (_routine.Count == 0)
  53. return Result.DONE;
  54. Result ret = Result.DONE;
  55. var lst = _routine.ToList();
  56. for (int i = 0; i < lst.Count; i++)
  57. {
  58. ret = lst[i].Start();
  59. if (ret == Result.DONE)
  60. {
  61. _routine.Dequeue();
  62. continue;
  63. }
  64. else
  65. {
  66. break;
  67. }
  68. }
  69. return Result.RUN;
  70. }
  71. public Result MonitorRoutine()
  72. {
  73. if (_routine.Count == 0)
  74. return Result.DONE;
  75. IRoutine routine = _routine.Peek();
  76. Result ret = routine.Monitor();
  77. if (ret == Result.DONE)
  78. {
  79. _routine.Dequeue();
  80. var lst = _routine.ToList();
  81. for (int i = 0; i < lst.Count; i++)
  82. {
  83. ret = lst[i].Start();
  84. if (ret == Result.DONE)
  85. {
  86. _routine.Dequeue();
  87. continue;
  88. }
  89. else
  90. {
  91. break;
  92. }
  93. }
  94. }
  95. return ret;
  96. }
  97. public void AbortRoutine()
  98. {
  99. if (_routine != null && _routine.Any())
  100. {
  101. _routine.Peek().Abort();
  102. _routine.Clear();
  103. }
  104. }
  105. }
  106. public class FsmDevice : BaseDevice, IDevice
  107. {
  108. private Thread _thread = null;
  109. private IStateMachine _fsm = null;
  110. public int FsmState
  111. {
  112. get { return _fsm.State; }
  113. }
  114. public int FsmPreviousState
  115. {
  116. get { return _fsm.PrevState; }
  117. }
  118. public string StringFsmStatus
  119. {
  120. get
  121. {
  122. return _fsmStateMap.ContainsKey(FsmState) ? _fsmStateMap[FsmState] : FsmState.ToString();
  123. }
  124. }
  125. Dictionary<int, string> _fsmStateMap = new Dictionary<int, string>();
  126. Dictionary<int, string> _fsmMessageMap = new Dictionary<int, string>();
  127. public FsmDevice() : base()
  128. {
  129. }
  130. public void MapState(int state, string stringState)
  131. {
  132. _fsmStateMap[state] = stringState;
  133. }
  134. public void MapMessage(int msg, string stringMessage)
  135. {
  136. _fsmMessageMap[msg] = stringMessage;
  137. }
  138. public void EnableFsm(int fsmInterval, object initState)
  139. {
  140. EnableFsm(fsmInterval, (int)initState);
  141. }
  142. public void EnableFsm(int fsmInterval, int initState)
  143. {
  144. _fsm = new StateMachine($"{Module} {Name} FSM", initState, fsmInterval);
  145. _fsm.Start();
  146. _thread = new Thread(new ThreadStart(_fsm.Loop));
  147. _thread.Name = _fsm.Name;
  148. _thread.Start();
  149. while (!_thread.IsAlive)
  150. Thread.Sleep(1);
  151. }
  152. public virtual bool Initialize()
  153. {
  154. return true;
  155. }
  156. public virtual void Monitor()
  157. {
  158. }
  159. public virtual void Terminate()
  160. {
  161. if (_fsm != null)
  162. {
  163. _fsm.Stop();
  164. }
  165. if (_thread != null)
  166. {
  167. if (_thread.IsAlive)
  168. {
  169. Thread.Sleep(100);
  170. if (_thread.IsAlive)
  171. {
  172. try
  173. {
  174. _thread.Abort();
  175. }
  176. catch (Exception ex)
  177. {
  178. LOG.Error(String.Format("Entity terminate has exception."), ex);
  179. }
  180. }
  181. }
  182. }
  183. //Term();
  184. }
  185. public virtual void Reset()
  186. {
  187. }
  188. protected void Transition<T, V>(T state, V msg, FsmFunc func, T next)
  189. {
  190. Debug.Assert(typeof(T).IsEnum && typeof(V).IsEnum);
  191. int _state = Convert.ToInt32(state);
  192. int _next = Convert.ToInt32(next);
  193. int _msg = Convert.ToInt32(msg);
  194. Transition(_state, _msg, func, _next);
  195. }
  196. protected void Transition(int state, int msg, FsmFunc func, int next)
  197. {
  198. if (_fsm != null)
  199. _fsm.Transition(state, msg, func, next);
  200. }
  201. protected void AnyStateTransition(int msg, FsmFunc func, int next)
  202. {
  203. if (_fsm != null)
  204. _fsm.AnyStateTransition(msg, func, next);
  205. }
  206. protected void AnyStateTransition<T, V>(V msg, FsmFunc func, T next)
  207. {
  208. Debug.Assert(typeof(T).IsEnum && typeof(V).IsEnum);
  209. int _next = Convert.ToInt32(next);
  210. int _msg = Convert.ToInt32(msg);
  211. AnyStateTransition(_msg, func, _next);
  212. }
  213. protected void EnterExitTransition<T, V>(T state, FsmFunc enter, Nullable<V> msg, FsmFunc exit) where V : struct
  214. {
  215. Debug.Assert(typeof(T).IsEnum && ((msg == null) || typeof(V).IsEnum));
  216. int _state = Convert.ToInt32(state);
  217. int _msg = msg == null ? (int)FSM_MSG.NONE : Convert.ToInt32(msg);
  218. EnterExitTransition(_state, enter, _msg, exit);
  219. }
  220. protected void EnterExitTransition(int state, FsmFunc enter, int msg, FsmFunc exit)
  221. {
  222. if (_fsm != null)
  223. _fsm.EnterExitTransition(state, enter, msg, exit);
  224. }
  225. public void PostMsg<T>(T msg, params object[] args) where T : struct
  226. {
  227. Debug.Assert(typeof(T).IsEnum);
  228. int id = Convert.ToInt32(msg);
  229. PostMsg(id, args);
  230. }
  231. public void PostMsg(int msg, params object[] args)
  232. {
  233. if (_fsm == null)
  234. {
  235. LOG.Error($"fsm is null, post msg {msg}");
  236. return;
  237. }
  238. _fsm.PostMsgWithoutLock(msg, args);
  239. }
  240. public bool CheckAllMessageProcessed()
  241. {
  242. return _fsm.CheckExecuted();
  243. }
  244. public bool CheckToPostMessage<T>(T msg, params object[] args)
  245. {
  246. return CheckToPostMessage(Convert.ToInt32(msg));
  247. }
  248. public bool CheckToPostMessage(int msg, params object[] args)
  249. {
  250. int state = _fsm.State;
  251. string status = _fsmStateMap[state];
  252. if (!_fsm.FindTransition(_fsm.State, msg))
  253. {
  254. string message = string.Empty;
  255. if (_fsmMessageMap.ContainsKey(msg))
  256. message = _fsmMessageMap[msg];
  257. else
  258. {
  259. message = msg.ToString();
  260. }
  261. EV.PostWarningLog(Module, $"{Name} is in {status} state,can not do {message}");
  262. return false;
  263. }
  264. _fsm.PostMsg(msg, args);
  265. return true;
  266. }
  267. }
  268. }