SeqenecRoutine.cs 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Collections.Specialized;
  4. using System.Linq;
  5. using System.Text;
  6. using Aitex.Core.RT.Event;
  7. using Aitex.Core.RT.Log;
  8. using Aitex.Core.Util;
  9. namespace Aitex.Core.RT.Routine
  10. {
  11. public class RoutineFaildException : ApplicationException
  12. {
  13. public RoutineFaildException() { }
  14. public RoutineFaildException(string message)
  15. : base(message) { }
  16. }
  17. public class RoutineBreakException : ApplicationException
  18. {
  19. public RoutineBreakException() { }
  20. public RoutineBreakException(string message)
  21. : base(message) { }
  22. }
  23. public enum RoutineState
  24. {
  25. Running,
  26. Failed,
  27. Timeout,
  28. Finished,
  29. }
  30. public class RoutineResult
  31. {
  32. public RoutineState Result;
  33. public string ErrorMessage;
  34. }
  35. public class SeqenecRoutine
  36. {
  37. //timer, 计算routine时间
  38. protected DeviceTimer counter = new DeviceTimer();
  39. protected DeviceTimer delayTimer = new DeviceTimer();
  40. private enum STATE
  41. {
  42. IDLE,
  43. WAIT,
  44. }
  45. public int TokenId
  46. {
  47. get { return _id; }
  48. }
  49. private int _id; //step index
  50. /// <summary>
  51. /// already done steps
  52. /// </summary>
  53. private Stack<int> _steps = new Stack<int>();
  54. private STATE state; //step state //idel,wait,
  55. //loop control
  56. private int loop = 0;
  57. private int loopCount = 0;
  58. private int loopID = 0;
  59. private DeviceTimer timer = new DeviceTimer();
  60. public int LoopCounter { get { return loop; } }
  61. public int LoopTotalTime { get { return loopCount; } }
  62. // public int Timeout { get { return (int)(timer.GetTotalTime() / 1000); } }
  63. //状态持续时间,单位为秒
  64. public int Elapsed { get { return (int)(timer.GetElapseTime() / 1000); } }
  65. protected RoutineResult RoutineToken = new RoutineResult() { Result = RoutineState.Running };
  66. public void Reset()
  67. {
  68. _id = 0;
  69. _steps.Clear();
  70. loop = 0;
  71. loopCount = 0;
  72. state = STATE.IDLE;
  73. counter.Start(60*60*100); //默认1小时
  74. RoutineToken.Result = RoutineState.Running;
  75. }
  76. protected void PerformRoutineStep(int id, Func<RoutineState> execution, RoutineResult result)
  77. {
  78. if (!Acitve(id))
  79. return;
  80. result.Result = execution();
  81. }
  82. #region interface
  83. public void StopLoop()
  84. {
  85. loop = loopCount;
  86. }
  87. public Tuple<bool, Result> Loop<T>(T id, Func<bool> func, int count)
  88. {
  89. int idx = Convert.ToInt32(id);
  90. bool bActive = Acitve(idx);
  91. if (bActive)
  92. {
  93. if (!func())
  94. {
  95. return Tuple.Create(bActive, Result.FAIL); //执行错误
  96. }
  97. loopID = idx;
  98. loopCount = count;
  99. next();
  100. return Tuple.Create(true, Result.RUN);
  101. }
  102. return Tuple.Create(false, Result.RUN);
  103. }
  104. public Tuple<bool, Result> EndLoop<T>(T id, Func<bool> func)
  105. {
  106. int idx = Convert.ToInt32(id);
  107. bool bActive = Acitve(idx);
  108. if (bActive)
  109. {
  110. if (++loop >= loopCount) //Loop 结束
  111. {
  112. if (!func())
  113. {
  114. return Tuple.Create(bActive, Result.FAIL); //执行错误
  115. }
  116. loop = 0;
  117. loopCount = 0; // Loop 结束时,当前loop和loop总数都清零
  118. next();
  119. return Tuple.Create(true, Result.RUN);
  120. }
  121. //继续下一LOOP
  122. next(loopID);
  123. return Tuple.Create(true, Result.RUN);
  124. }
  125. return Tuple.Create(false, Result.RUN);
  126. }
  127. public Tuple<bool, Result> Check<T>(T id, Func<bool> func) //顺序执行
  128. {
  129. return Check(Check(Convert.ToInt32(id), func));
  130. }
  131. public Tuple<bool, Result> Execute<T>(T id, Func<bool> func) //顺序执行
  132. {
  133. return Check(execute(Convert.ToInt32(id), func));
  134. }
  135. public Tuple<bool, Result> Wait<T>(T id, Func<bool> func, double timeout = int.MaxValue) //Wait condition
  136. {
  137. return Check(wait(Convert.ToInt32(id), func, timeout));
  138. }
  139. public Tuple<bool, Result> Wait<T>(T id, Func<bool?> func, double timeout = int.MaxValue) //Wait condition
  140. {
  141. return Check(wait(Convert.ToInt32(id), func, timeout));
  142. }
  143. public Tuple<bool, Result> ExecuteAndWait<T>(T id, Func<bool> execute, Func<bool?> check, double timeout = int.MaxValue)
  144. {
  145. int idx = Convert.ToInt32(id);
  146. bool bActive = Acitve(idx);
  147. bool? bExecute = false;
  148. if (bActive)
  149. {
  150. if (state == STATE.IDLE)
  151. {
  152. if (!execute())
  153. {
  154. return Tuple.Create(bActive, Result.FAIL); //执行错误
  155. }
  156. timer.Start(timeout);
  157. state = STATE.WAIT;
  158. }
  159. bExecute = check();
  160. if (bExecute == null)
  161. {
  162. return Tuple.Create(bActive, Result.FAIL); //Termianate
  163. }
  164. else
  165. {
  166. if (bExecute.Value) //检查Success, next
  167. {
  168. next();
  169. return Tuple.Create(true, Result.RUN);
  170. }
  171. }
  172. if(timer.IsTimeout())
  173. return Tuple.Create(true, Result.TIMEOUT);
  174. return Tuple.Create(true, Result.RUN);
  175. }
  176. return Tuple.Create(false, Result.RUN);
  177. }
  178. public Tuple<bool, Result> ExecuteAndWait<T>(T id, Func<bool> execute, Func<bool?> check, Func<double> time)
  179. {
  180. int idx = Convert.ToInt32(id);
  181. bool bActive = Acitve(idx);
  182. bool? bExecute = false;
  183. double timeout = 0;
  184. if (bActive)
  185. {
  186. if (state == STATE.IDLE)
  187. {
  188. timeout = time();
  189. if (!execute())
  190. {
  191. return Tuple.Create(true, Result.FAIL); //执行错误
  192. }
  193. timer.Start(timeout);
  194. state = STATE.WAIT;
  195. }
  196. bExecute = check();
  197. if (bExecute == null)
  198. {
  199. return Tuple.Create(true, Result.FAIL); //Termianate
  200. }
  201. if (bExecute.Value) //检查Success, next
  202. {
  203. next();
  204. return Tuple.Create(true, Result.RUN);
  205. }
  206. if (timer.IsTimeout())
  207. return Tuple.Create(true, Result.TIMEOUT);
  208. return Tuple.Create(true, Result.RUN);
  209. }
  210. return Tuple.Create(false, Result.RUN);
  211. }
  212. //Monitor
  213. public Tuple<bool, Result> Monitor<T>(T id, Func<bool> func, Func<bool> check, double time)
  214. {
  215. int idx = Convert.ToInt32(id);
  216. bool bActive = Acitve(idx);
  217. bool bCheck = false;
  218. if (bActive)
  219. {
  220. if (state == STATE.IDLE)
  221. {
  222. if ((func != null) && !func())
  223. {
  224. return Tuple.Create(true, Result.FAIL);
  225. }
  226. timer.Start(time);
  227. state = STATE.WAIT;
  228. }
  229. bCheck = check();
  230. if (!bCheck)
  231. {
  232. return Tuple.Create(true, Result.FAIL); //Termianate
  233. }
  234. if (timer.IsTimeout())
  235. {
  236. next();
  237. }
  238. return Tuple.Create(true, Result.RUN);
  239. }
  240. return Tuple.Create(false, Result.RUN);
  241. }
  242. //Delay
  243. public Tuple<bool, Result> Delay<T>(T id, Func<bool> func, double time)
  244. {
  245. int idx = Convert.ToInt32(id);
  246. bool bActive = Acitve(idx);
  247. if (bActive)
  248. {
  249. if (state == STATE.IDLE)
  250. {
  251. if ((func != null) && !func())
  252. {
  253. return Tuple.Create(true, Result.FAIL);
  254. }
  255. timer.Start(time);
  256. state = STATE.WAIT;
  257. }
  258. if (timer.IsTimeout())
  259. {
  260. next();
  261. }
  262. return Tuple.Create(true, Result.RUN);
  263. }
  264. return Tuple.Create(false, Result.RUN);
  265. }
  266. //先delay 再运行
  267. public Tuple<bool, Result> DelayCheck<T>(T id, Func<bool> func, double time)
  268. {
  269. int idx = Convert.ToInt32(id);
  270. bool bActive = Acitve(idx);
  271. if (bActive)
  272. {
  273. if (state == STATE.IDLE)
  274. {
  275. timer.Start(time);
  276. state = STATE.WAIT;
  277. }
  278. if (timer.IsTimeout())
  279. {
  280. if (func != null && !func())
  281. {
  282. return Tuple.Create(true, Result.FAIL);
  283. }
  284. next();
  285. }
  286. return Tuple.Create(true, Result.RUN);
  287. }
  288. return Tuple.Create(false, Result.RUN);
  289. }
  290. #endregion
  291. private Tuple<bool,bool> execute(int id, Func<bool> func) //顺序执行
  292. {
  293. bool bActive = Acitve(id);
  294. bool bExecute = false;
  295. if (bActive)
  296. {
  297. bExecute = func();
  298. if (bExecute)
  299. {
  300. next();
  301. }
  302. }
  303. return Tuple.Create(bActive, bExecute);
  304. }
  305. private Tuple<bool, bool> Check(int id, Func<bool> func) //check
  306. {
  307. bool bActive = Acitve(id);
  308. bool bExecute = false;
  309. if (bActive)
  310. {
  311. bExecute = func();
  312. next();
  313. }
  314. return Tuple.Create(bActive, bExecute);
  315. }
  316. /// <summary>
  317. /// </summary>
  318. /// <param name="id"></param>
  319. /// <param name="func"></param>
  320. /// <param name="timeout"></param>
  321. /// <returns>
  322. /// item1 Active
  323. /// item2 execute
  324. /// item3 Timeout
  325. ///</returns>
  326. private Tuple<bool,bool, bool> wait(int id, Func<bool> func, double timeout = int.MaxValue) //Wait condition
  327. {
  328. bool bActive = Acitve(id);
  329. bool bExecute = false;
  330. bool bTimeout = false;
  331. if (bActive)
  332. {
  333. if (state == STATE.IDLE)
  334. {
  335. timer.Start(timeout);
  336. state = STATE.WAIT;
  337. }
  338. bExecute = func();
  339. if (bExecute)
  340. {
  341. next();
  342. }
  343. bTimeout = timer.IsTimeout();
  344. }
  345. return Tuple.Create(bActive, bExecute, bTimeout);
  346. }
  347. private Tuple<bool, bool?, bool> wait(int id, Func<bool?> func, double timeout = int.MaxValue) //Wait condition && Check error
  348. {
  349. bool bActive = Acitve(id);
  350. bool? bExecute = false;
  351. bool bTimeout = false;
  352. if (bActive)
  353. {
  354. if (state == STATE.IDLE)
  355. {
  356. timer.Start(timeout);
  357. state = STATE.WAIT;
  358. }
  359. bExecute = func();
  360. if (bExecute.HasValue && bExecute.Value)
  361. {
  362. next();
  363. }
  364. bTimeout = timer.IsTimeout();
  365. }
  366. return Tuple.Create(bActive, bExecute, bTimeout);
  367. }
  368. /// <summary>
  369. /// </summary>
  370. /// <param name="value"></param>
  371. /// <returns>
  372. /// item1 true, return item2
  373. /// </returns>
  374. private Tuple<bool,Result> Check(Tuple<bool, bool> value)
  375. {
  376. if (value.Item1)
  377. {
  378. if (!value.Item2)
  379. {
  380. return Tuple.Create(true, Result.FAIL);
  381. }
  382. return Tuple.Create(true, Result.RUN);
  383. }
  384. return Tuple.Create(false, Result.RUN);
  385. }
  386. private Tuple<bool, Result> Check(Tuple<bool, bool, bool> value)
  387. {
  388. if (value.Item1) // 当前执行
  389. {
  390. if (CheckTimeout(value)) //timeout
  391. {
  392. return Tuple.Create(true, Result.TIMEOUT);
  393. }
  394. return Tuple.Create(true, Result.RUN);
  395. }
  396. return Tuple.Create(false, Result.RUN);
  397. }
  398. private Tuple<bool, Result> Check(Tuple<bool, bool?, bool> value)
  399. {
  400. if (value.Item1) // 当前执行
  401. {
  402. if (value.Item2 == null)
  403. {
  404. return Tuple.Create(true, Result.FAIL);
  405. }
  406. else
  407. {
  408. if (value.Item2 == false && value.Item3 == true) //timeout
  409. {
  410. return Tuple.Create(true, Result.TIMEOUT);
  411. }
  412. return Tuple.Create(true, Result.RUN);
  413. }
  414. }
  415. return Tuple.Create(false, Result.RUN);
  416. }
  417. private bool CheckTimeout(Tuple<bool, bool, bool> value)
  418. {
  419. return value.Item1 == true && value.Item2 == false && value.Item3 == true;
  420. }
  421. private bool Acitve(int id) //
  422. {
  423. if (_steps.Contains(id))
  424. return false;
  425. this._id = id;
  426. return true;
  427. }
  428. private void next()
  429. {
  430. _steps.Push(this._id);
  431. state = STATE.IDLE;
  432. }
  433. private void next(int step) //loop
  434. {
  435. while(_steps.Pop() != step);
  436. state = STATE.IDLE;
  437. }
  438. public void Delay(int id, double delaySeconds)
  439. {
  440. Tuple<bool, Result> ret = Delay(id, () =>
  441. {
  442. return true;
  443. }, delaySeconds * 1000);
  444. if (ret.Item1)
  445. {
  446. if (ret.Item2 == Result.RUN)
  447. {
  448. throw (new RoutineBreakException());
  449. }
  450. }
  451. }
  452. public bool IsActived(int id)
  453. {
  454. return _steps.Contains(id);
  455. }
  456. }
  457. public class ModuleRoutine : SeqenecRoutine
  458. {
  459. public string Module { get; set; }
  460. public string Name { get; set; }
  461. public string StepName
  462. {
  463. get
  464. {
  465. return _stepName;
  466. }
  467. }
  468. protected string _stepName;
  469. public TimeSpan StepLeftTime
  470. {
  471. get
  472. {
  473. if (_stepSpan.TotalMilliseconds < 1)
  474. return _stepSpan;
  475. return (_stepSpan - (DateTime.Now - _stepStartTime));
  476. }
  477. }
  478. protected TimeSpan _stepSpan = new TimeSpan(0, 0, 0, 0);
  479. protected DateTime _stepStartTime;
  480. public delegate RoutineState RoutineFunc<T>(T arg);
  481. protected void Notify(string message)
  482. {
  483. EV.PostInfoLog(Module, $"{Module} {Name}, {message}");
  484. }
  485. protected void Stop(string failReason)
  486. {
  487. EV.PostAlarmLog(Module, $"{Module} {Name} failed, {failReason}");
  488. }
  489. private static object locker=new object();
  490. public void Abort(string failReason)
  491. {
  492. //lock (locker)
  493. //{
  494. //Thread.Sleep(500);
  495. EV.PostAlarmLog(Module, $"{Module} {Name} {failReason}");
  496. //}
  497. }
  498. public void TimeDelay(int id, string stepName, double time)
  499. {
  500. Tuple<bool, Result> ret = Delay(id, () =>
  501. {
  502. Notify($"Delay {time} seconds");
  503. _stepSpan = new TimeSpan(0, 0, 0, (int)time);
  504. _stepStartTime = DateTime.Now;
  505. _stepName = stepName;
  506. return true;
  507. }, time * 1000);
  508. if (ret.Item1)
  509. {
  510. if (ret.Item2 == Result.RUN)
  511. {
  512. throw (new RoutineBreakException());
  513. }
  514. }
  515. }
  516. public void TimeDelay(int id, double time)
  517. {
  518. Tuple<bool, Result> ret = Delay(id, () =>
  519. {
  520. Notify($"Delay {time} seconds");
  521. _stepSpan = new TimeSpan(0,0,0,(int)time);
  522. _stepStartTime = DateTime.Now;
  523. return true;
  524. }, time * 1000);
  525. if (ret.Item1)
  526. {
  527. if (ret.Item2 == Result.RUN)
  528. {
  529. throw (new RoutineBreakException());
  530. }
  531. }
  532. }
  533. protected void PerformStep<T, T1>(T step, RoutineFunc<T1> func, T1 param1)
  534. {
  535. int idx = Convert.ToInt32(step);
  536. RoutineState state = func(param1);
  537. }
  538. }
  539. public class QueueRoutine
  540. {
  541. private Queue<IStepRoutine> _steps = new Queue<IStepRoutine>();
  542. private IStepRoutine _currentStep = null;
  543. public void Add(IStepRoutine step)
  544. {
  545. _steps.Enqueue(step);
  546. }
  547. public void Reset()
  548. {
  549. _steps.Clear();
  550. _currentStep = null;
  551. }
  552. public void Abort()
  553. {
  554. if (_currentStep != null)
  555. _currentStep.Abort();
  556. Reset();
  557. }
  558. public RState Start(params object[] objs)
  559. {
  560. if (_steps.Count == 0)
  561. return RState.End;
  562. _currentStep = _steps.Dequeue();
  563. return _currentStep.Start(objs);
  564. }
  565. public RState Monitor(params object[] objs)
  566. {
  567. RState ret = RState.Failed;
  568. if (_currentStep != null)
  569. {
  570. ret = _currentStep.Monitor();
  571. }
  572. if (ret == RState.End)
  573. {
  574. _currentStep = _steps.Count > 0 ? _steps.Dequeue() : null;
  575. if (_currentStep != null)
  576. {
  577. return _currentStep.Start(objs);
  578. }
  579. }
  580. return ret;
  581. }
  582. }
  583. }