ModuleFsmDevice.cs 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343
  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. private bool _isInitialized = false;
  111. public int FsmState
  112. {
  113. get { return _fsm.State; }
  114. }
  115. public bool IsInitialized
  116. {
  117. get { return _isInitialized; }
  118. }
  119. public int FsmPreviousState
  120. {
  121. get { return _fsm.PrevState; }
  122. }
  123. public string StringFsmStatus
  124. {
  125. get
  126. {
  127. return _fsmStateMap.ContainsKey(FsmState) ? _fsmStateMap[FsmState] : FsmState.ToString();
  128. }
  129. }
  130. Dictionary<int, string> _fsmStateMap = new Dictionary<int, string>();
  131. Dictionary<int, string> _fsmMessageMap = new Dictionary<int, string>();
  132. public FsmDevice() : base()
  133. {
  134. }
  135. public void MapState(int state, string stringState)
  136. {
  137. _fsmStateMap[state] = stringState;
  138. }
  139. public void MapMessage(int msg, string stringMessage)
  140. {
  141. _fsmMessageMap[msg] = stringMessage;
  142. }
  143. public void EnableFsm(int fsmInterval, object initState)
  144. {
  145. EnableFsm(fsmInterval, (int)initState);
  146. }
  147. public void EnableFsm(int fsmInterval, int initState)
  148. {
  149. _fsm = new StateMachine($"{Module} {Name} FSM", initState, fsmInterval);
  150. _fsm.Start();
  151. _thread = new Thread(new ThreadStart(_fsm.Loop));
  152. _thread.Name = _fsm.Name;
  153. _thread.Start();
  154. while (!_thread.IsAlive)
  155. Thread.Sleep(1);
  156. }
  157. public virtual bool Initialize()
  158. {
  159. _isInitialized = true;
  160. return true;
  161. }
  162. public virtual void Monitor()
  163. {
  164. }
  165. public virtual void Terminate()
  166. {
  167. if (_fsm != null)
  168. {
  169. _fsm.Stop();
  170. }
  171. if (_thread != null)
  172. {
  173. if (_thread.IsAlive)
  174. {
  175. Thread.Sleep(100);
  176. if (_thread.IsAlive)
  177. {
  178. try
  179. {
  180. _thread.Abort();
  181. }
  182. catch (Exception ex)
  183. {
  184. LOG.Error(String.Format("Entity terminate has exception."), ex);
  185. }
  186. }
  187. }
  188. }
  189. //Term();
  190. }
  191. public virtual void Reset()
  192. {
  193. }
  194. protected void Transition<T, V>(T state, V msg, FsmFunc func, T next)
  195. {
  196. Debug.Assert(typeof(T).IsEnum && typeof(V).IsEnum);
  197. int _state = Convert.ToInt32(state);
  198. int _next = Convert.ToInt32(next);
  199. int _msg = Convert.ToInt32(msg);
  200. Transition(_state, _msg, func, _next);
  201. }
  202. protected void Transition(int state, int msg, FsmFunc func, int next)
  203. {
  204. if (_fsm != null)
  205. _fsm.Transition(state, msg, func, next);
  206. }
  207. protected void AnyStateTransition(int msg, FsmFunc func, int next)
  208. {
  209. if (_fsm != null)
  210. _fsm.AnyStateTransition(msg, func, next);
  211. }
  212. protected void AnyStateTransition<T, V>(V msg, FsmFunc func, T next)
  213. {
  214. Debug.Assert(typeof(T).IsEnum && typeof(V).IsEnum);
  215. int _next = Convert.ToInt32(next);
  216. int _msg = Convert.ToInt32(msg);
  217. AnyStateTransition(_msg, func, _next);
  218. }
  219. protected void EnterExitTransition<T, V>(T state, FsmFunc enter, Nullable<V> msg, FsmFunc exit) where V : struct
  220. {
  221. Debug.Assert(typeof(T).IsEnum && ((msg == null) || typeof(V).IsEnum));
  222. int _state = Convert.ToInt32(state);
  223. int _msg = msg == null ? (int)FSM_MSG.NONE : Convert.ToInt32(msg);
  224. EnterExitTransition(_state, enter, _msg, exit);
  225. }
  226. protected void EnterExitTransition(int state, FsmFunc enter, int msg, FsmFunc exit)
  227. {
  228. if (_fsm != null)
  229. _fsm.EnterExitTransition(state, enter, msg, exit);
  230. }
  231. public void PostMsg<T>(T msg, params object[] args) where T : struct
  232. {
  233. Debug.Assert(typeof(T).IsEnum);
  234. int id = Convert.ToInt32(msg);
  235. PostMsg(id, args);
  236. }
  237. public void PostMsg(int msg, params object[] args)
  238. {
  239. if (_fsm == null)
  240. {
  241. LOG.Error($"fsm is null, post msg {msg}");
  242. return;
  243. }
  244. _fsm.PostMsgWithoutLock(msg, args);
  245. }
  246. public bool CheckAllMessageProcessed()
  247. {
  248. return _fsm.CheckExecuted();
  249. }
  250. public bool CheckToPostMessage<T>(T msg, params object[] args)
  251. {
  252. return CheckToPostMessage(Convert.ToInt32(msg));
  253. }
  254. public bool CheckToPostMessage(int msg, params object[] args)
  255. {
  256. int state = _fsm.State;
  257. string status = _fsmStateMap[state];
  258. if (!_fsm.FindTransition(_fsm.State, msg))
  259. {
  260. string message = string.Empty;
  261. if (_fsmMessageMap.ContainsKey(msg))
  262. message = _fsmMessageMap[msg];
  263. else
  264. {
  265. message = msg.ToString();
  266. }
  267. EV.PostWarningLog(Module, $"{Name} is in {status} state,can not do {message}");
  268. return false;
  269. }
  270. _fsm.PostMsg(msg, args);
  271. return true;
  272. }
  273. }
  274. }