SeqenecRoutine.cs 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835
  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. private int _id; //step index
  46. private Stack<int> _steps = new Stack<int>();
  47. private STATE state; //step state //idel,wait,
  48. //loop control
  49. private int loop = 0;
  50. private int loopCount = 0;
  51. private int loopID = 0;
  52. private DeviceTimer timer = new DeviceTimer();
  53. public int LoopCounter { get { return loop; } }
  54. // public int Timeout { get { return (int)(timer.GetTotalTime() / 1000); } }
  55. //状态持续时间,单位为秒
  56. public int Elapsed { get { return (int)(timer.GetElapseTime() / 1000); } }
  57. protected RoutineResult RoutineToken = new RoutineResult() { Result = RoutineState.Running };
  58. public void Reset()
  59. {
  60. _id = 0;
  61. _steps.Clear();
  62. loop = 0;
  63. state = STATE.IDLE;
  64. counter.Start(60*60*100); //默认1小时
  65. RoutineToken.Result = RoutineState.Running;
  66. }
  67. protected void PerformRoutineStep(int id, Func<RoutineState> execution, RoutineResult result)
  68. {
  69. if (!Acitve(id))
  70. return;
  71. result.Result = execution();
  72. }
  73. #region interface
  74. public Tuple<bool, Result> Loop<T>(T id, Func<bool> func, int count)
  75. {
  76. int idx = Convert.ToInt32(id);
  77. bool bActive = Acitve(idx);
  78. if (bActive)
  79. {
  80. if (!func())
  81. {
  82. return Tuple.Create(bActive, Result.FAIL); //执行错误
  83. }
  84. loopID = idx;
  85. loopCount = count;
  86. next();
  87. return Tuple.Create(true, Result.RUN);
  88. }
  89. return Tuple.Create(false, Result.RUN);
  90. }
  91. public Tuple<bool, Result> EndLoop<T>(T id, Func<bool> func)
  92. {
  93. int idx = Convert.ToInt32(id);
  94. bool bActive = Acitve(idx);
  95. if (bActive)
  96. {
  97. if (++loop >= loopCount) //Loop 结束
  98. {
  99. if (!func())
  100. {
  101. return Tuple.Create(bActive, Result.FAIL); //执行错误
  102. }
  103. loop = 0;
  104. next();
  105. return Tuple.Create(true, Result.RUN);
  106. }
  107. //继续下一LOOP
  108. next(loopID);
  109. return Tuple.Create(true, Result.RUN);
  110. }
  111. return Tuple.Create(false, Result.RUN);
  112. }
  113. public Tuple<bool, Result> ExecuteAndWait<T>(T id, IRoutine routine)
  114. {
  115. int idx = Convert.ToInt32(id);
  116. bool bActive = Acitve(idx);
  117. if (bActive)
  118. {
  119. if (state == STATE.IDLE)
  120. {
  121. Result startRet = routine.Start();
  122. if (startRet == Result.FAIL)
  123. {
  124. return Tuple.Create(true, Result.FAIL); //执行错误
  125. }else if (startRet == Result.DONE)
  126. {
  127. next();
  128. return Tuple.Create(true, Result.DONE);
  129. }
  130. state = STATE.WAIT;
  131. }
  132. Result ret = routine.Monitor();
  133. if (ret == Result.DONE)
  134. {
  135. next();
  136. return Tuple.Create(true, Result.DONE);
  137. }
  138. else if (ret == Result.FAIL || ret == Result.TIMEOUT)
  139. {
  140. return Tuple.Create(true, Result.FAIL);
  141. }
  142. else
  143. {
  144. return Tuple.Create(true, Result.RUN);
  145. }
  146. }
  147. return Tuple.Create(false, Result.RUN);
  148. }
  149. public Tuple<bool, Result> ExecuteAndWaitPumpDown<T>(T id, IRoutine routine, double BasePressure)
  150. {
  151. int idx = Convert.ToInt32(id);
  152. bool bActive = Acitve(idx);
  153. if (bActive)
  154. {
  155. if (state == STATE.IDLE)
  156. {
  157. Result startRet = routine.Start(BasePressure);
  158. if (startRet == Result.FAIL)
  159. {
  160. return Tuple.Create(true, Result.FAIL); //执行错误
  161. }
  162. else if (startRet == Result.DONE)
  163. {
  164. next();
  165. return Tuple.Create(true, Result.DONE);
  166. }
  167. state = STATE.WAIT;
  168. }
  169. Result ret = routine.Monitor();
  170. if (ret == Result.DONE)
  171. {
  172. next();
  173. return Tuple.Create(true, Result.DONE);
  174. }
  175. else if (ret == Result.FAIL || ret == Result.TIMEOUT)
  176. {
  177. return Tuple.Create(true, Result.FAIL);
  178. }
  179. else
  180. {
  181. return Tuple.Create(true, Result.RUN);
  182. }
  183. }
  184. return Tuple.Create(false, Result.RUN);
  185. }
  186. public Tuple<bool, Result> ExecuteAndWait<T>(T id, List<IRoutine> routines)
  187. {
  188. int idx = Convert.ToInt32(id);
  189. bool bActive = Acitve(idx);
  190. if (bActive)
  191. {
  192. if (state == STATE.IDLE)
  193. {
  194. foreach (var item in routines)
  195. {
  196. if (item.Start() == Result.FAIL)
  197. return Tuple.Create(true, Result.FAIL);
  198. }
  199. state = STATE.WAIT;
  200. }
  201. //wait all sub failed or completedboo
  202. bool bFail = false;
  203. bool bDone = true;
  204. foreach (var item in routines)
  205. {
  206. Result ret = item.Monitor();
  207. bDone &= (ret == Result.FAIL || ret == Result.DONE);
  208. bFail |= ret == Result.FAIL;
  209. }
  210. if (bDone)
  211. {
  212. next();
  213. if(bFail)
  214. return Tuple.Create(true, Result.FAIL);
  215. return Tuple.Create(true, Result.DONE);
  216. }
  217. return Tuple.Create(true, Result.RUN);
  218. }
  219. return Tuple.Create(false, Result.RUN);
  220. }
  221. public Tuple<bool, Result> Check<T>(T id, Func<bool> func) //顺序执行
  222. {
  223. return Check(Check(Convert.ToInt32(id), func));
  224. }
  225. public Tuple<bool, Result> Execute<T>(T id, Func<bool> func) //顺序执行
  226. {
  227. return Check(execute(Convert.ToInt32(id), func));
  228. }
  229. public Tuple<bool, Result> Wait<T>(T id, Func<bool> func, double timeout = int.MaxValue) //Wait condition
  230. {
  231. return Check(wait(Convert.ToInt32(id), func, timeout));
  232. }
  233. public Tuple<bool, Result> Wait<T>(T id, Func<bool?> func, double timeout = int.MaxValue) //Wait condition
  234. {
  235. return Check(wait(Convert.ToInt32(id), func, timeout));
  236. }
  237. public Tuple<bool, Result> ExecuteAndWait<T>(T id, Func<bool> execute, Func<bool?> check, double timeout = int.MaxValue)
  238. {
  239. int idx = Convert.ToInt32(id);
  240. bool bActive = Acitve(idx);
  241. bool? bExecute = false;
  242. if (bActive)
  243. {
  244. if (state == STATE.IDLE)
  245. {
  246. if (!execute())
  247. {
  248. return Tuple.Create(bActive, Result.FAIL); //执行错误
  249. }
  250. timer.Start(timeout);
  251. state = STATE.WAIT;
  252. }
  253. bExecute = check();
  254. if (bExecute == null)
  255. {
  256. return Tuple.Create(bActive, Result.FAIL); //Termianate
  257. }
  258. else
  259. {
  260. if (bExecute.Value) //检查Success, next
  261. {
  262. next();
  263. return Tuple.Create(true, Result.RUN);
  264. }
  265. }
  266. if(timer.IsTimeout())
  267. return Tuple.Create(true, Result.TIMEOUT);
  268. return Tuple.Create(true, Result.RUN);
  269. }
  270. return Tuple.Create(false, Result.RUN);
  271. }
  272. public Tuple<bool, Result> ExecuteAndWait<T>(T id, Func<bool> execute, Func<bool?> check, Func<double> time)
  273. {
  274. int idx = Convert.ToInt32(id);
  275. bool bActive = Acitve(idx);
  276. bool? bExecute = false;
  277. double timeout = 0;
  278. if (bActive)
  279. {
  280. if (state == STATE.IDLE)
  281. {
  282. timeout = time();
  283. if (!execute())
  284. {
  285. return Tuple.Create(true, Result.FAIL); //执行错误
  286. }
  287. timer.Start(timeout);
  288. state = STATE.WAIT;
  289. }
  290. bExecute = check();
  291. if (bExecute == null)
  292. {
  293. return Tuple.Create(true, Result.FAIL); //Termianate
  294. }
  295. if (bExecute.Value) //检查Success, next
  296. {
  297. next();
  298. return Tuple.Create(true, Result.RUN);
  299. }
  300. if (timer.IsTimeout())
  301. return Tuple.Create(true, Result.TIMEOUT);
  302. return Tuple.Create(true, Result.RUN);
  303. }
  304. return Tuple.Create(false, Result.RUN);
  305. }
  306. public Tuple<bool, Result> Wait<T>(T id, IRoutine rt)
  307. {
  308. int idx = Convert.ToInt32(id);
  309. bool bActive = Acitve(idx);
  310. if (bActive)
  311. {
  312. if (state == STATE.IDLE)
  313. {
  314. rt.Start();
  315. state = STATE.WAIT;
  316. }
  317. Result ret = rt.Monitor();
  318. return Tuple.Create(true, ret);
  319. }
  320. return Tuple.Create(false, Result.RUN);
  321. }
  322. //Monitor
  323. public Tuple<bool, Result> Monitor<T>(T id, Func<bool> func, Func<bool> check, double time)
  324. {
  325. int idx = Convert.ToInt32(id);
  326. bool bActive = Acitve(idx);
  327. bool bCheck = false;
  328. if (bActive)
  329. {
  330. if (state == STATE.IDLE)
  331. {
  332. if ((func != null) && !func())
  333. {
  334. return Tuple.Create(true, Result.FAIL);
  335. }
  336. timer.Start(time);
  337. state = STATE.WAIT;
  338. }
  339. bCheck = check();
  340. if (!bCheck)
  341. {
  342. return Tuple.Create(true, Result.FAIL); //Termianate
  343. }
  344. if (timer.IsTimeout())
  345. {
  346. next();
  347. }
  348. return Tuple.Create(true, Result.RUN);
  349. }
  350. return Tuple.Create(false, Result.RUN);
  351. }
  352. //Delay
  353. public Tuple<bool, Result> Delay<T>(T id, Func<bool> func, double time)
  354. {
  355. int idx = Convert.ToInt32(id);
  356. bool bActive = Acitve(idx);
  357. if (bActive)
  358. {
  359. if (state == STATE.IDLE)
  360. {
  361. if ((func != null) && !func())
  362. {
  363. return Tuple.Create(true, Result.FAIL);
  364. }
  365. timer.Start(time);
  366. state = STATE.WAIT;
  367. }
  368. if (timer.IsTimeout())
  369. {
  370. next();
  371. }
  372. return Tuple.Create(true, Result.RUN);
  373. }
  374. return Tuple.Create(false, Result.RUN);
  375. }
  376. //先delay 再运行
  377. public Tuple<bool, Result> DelayCheck<T>(T id, Func<bool> func, double time)
  378. {
  379. int idx = Convert.ToInt32(id);
  380. bool bActive = Acitve(idx);
  381. if (bActive)
  382. {
  383. if (state == STATE.IDLE)
  384. {
  385. timer.Start(time);
  386. state = STATE.WAIT;
  387. }
  388. if (timer.IsTimeout())
  389. {
  390. if (func != null && !func())
  391. {
  392. return Tuple.Create(true, Result.FAIL);
  393. }
  394. next();
  395. }
  396. return Tuple.Create(true, Result.RUN);
  397. }
  398. return Tuple.Create(false, Result.RUN);
  399. }
  400. #endregion
  401. private Tuple<bool,bool> execute(int id, Func<bool> func) //顺序执行
  402. {
  403. bool bActive = Acitve(id);
  404. bool bExecute = false;
  405. if (bActive)
  406. {
  407. bExecute = func();
  408. if (bExecute)
  409. {
  410. next();
  411. }
  412. }
  413. return Tuple.Create(bActive, bExecute);
  414. }
  415. private Tuple<bool, bool> Check(int id, Func<bool> func) //check
  416. {
  417. bool bActive = Acitve(id);
  418. bool bExecute = false;
  419. if (bActive)
  420. {
  421. bExecute = func();
  422. next();
  423. }
  424. return Tuple.Create(bActive, bExecute);
  425. }
  426. /// <summary>
  427. /// </summary>
  428. /// <param name="id"></param>
  429. /// <param name="func"></param>
  430. /// <param name="timeout"></param>
  431. /// <returns>
  432. /// item1 Active
  433. /// item2 execute
  434. /// item3 Timeout
  435. ///</returns>
  436. private Tuple<bool,bool, bool> wait(int id, Func<bool> func, double timeout = int.MaxValue) //Wait condition
  437. {
  438. bool bActive = Acitve(id);
  439. bool bExecute = false;
  440. bool bTimeout = false;
  441. if (bActive)
  442. {
  443. if (state == STATE.IDLE)
  444. {
  445. timer.Start(timeout);
  446. state = STATE.WAIT;
  447. }
  448. bExecute = func();
  449. if (bExecute)
  450. {
  451. next();
  452. }
  453. bTimeout = timer.IsTimeout();
  454. }
  455. return Tuple.Create(bActive, bExecute, bTimeout);
  456. }
  457. private Tuple<bool, bool?, bool> wait(int id, Func<bool?> func, double timeout = int.MaxValue) //Wait condition && Check error
  458. {
  459. bool bActive = Acitve(id);
  460. bool? bExecute = false;
  461. bool bTimeout = false;
  462. if (bActive)
  463. {
  464. if (state == STATE.IDLE)
  465. {
  466. timer.Start(timeout);
  467. state = STATE.WAIT;
  468. }
  469. bExecute = func();
  470. if (bExecute.HasValue && bExecute.Value)
  471. {
  472. next();
  473. }
  474. bTimeout = timer.IsTimeout();
  475. }
  476. return Tuple.Create(bActive, bExecute, bTimeout);
  477. }
  478. /// <summary>
  479. /// </summary>
  480. /// <param name="value"></param>
  481. /// <returns>
  482. /// item1 true, return item2
  483. /// </returns>
  484. private Tuple<bool,Result> Check(Tuple<bool, bool> value)
  485. {
  486. if (value.Item1)
  487. {
  488. if (!value.Item2)
  489. {
  490. return Tuple.Create(true, Result.FAIL);
  491. }
  492. return Tuple.Create(true, Result.RUN);
  493. }
  494. return Tuple.Create(false, Result.RUN);
  495. }
  496. private Tuple<bool, Result> Check(Tuple<bool, bool, bool> value)
  497. {
  498. if (value.Item1) // 当前执行
  499. {
  500. if (CheckTimeout(value)) //timeout
  501. {
  502. return Tuple.Create(true, Result.TIMEOUT);
  503. }
  504. return Tuple.Create(true, Result.RUN);
  505. }
  506. return Tuple.Create(false, Result.RUN);
  507. }
  508. private Tuple<bool, Result> Check(Tuple<bool, bool?, bool> value)
  509. {
  510. if (value.Item1) // 当前执行
  511. {
  512. if (value.Item2 == null)
  513. {
  514. return Tuple.Create(true, Result.FAIL);
  515. }
  516. else
  517. {
  518. if (value.Item2 == false && value.Item3 == true) //timeout
  519. {
  520. return Tuple.Create(true, Result.TIMEOUT);
  521. }
  522. return Tuple.Create(true, Result.RUN);
  523. }
  524. }
  525. return Tuple.Create(false, Result.RUN);
  526. }
  527. private bool CheckTimeout(Tuple<bool, bool, bool> value)
  528. {
  529. return value.Item1 == true && value.Item2 == false && value.Item3 == true;
  530. }
  531. private bool Acitve(int id) //
  532. {
  533. if (_steps.Contains(id))
  534. return false;
  535. this._id = id;
  536. return true;
  537. }
  538. private void next()
  539. {
  540. _steps.Push(this._id);
  541. state = STATE.IDLE;
  542. }
  543. private void next(int step) //loop
  544. {
  545. while(_steps.Pop() != step);
  546. state = STATE.IDLE;
  547. }
  548. public void Delay(int id, double delaySeconds)
  549. {
  550. Tuple<bool, Result> ret = Delay(id, () =>
  551. {
  552. return true;
  553. }, delaySeconds * 1000);
  554. if (ret.Item1)
  555. {
  556. if (ret.Item2 == Result.RUN)
  557. {
  558. throw (new RoutineBreakException());
  559. }
  560. }
  561. }
  562. }
  563. public class ModuleRoutine : SeqenecRoutine
  564. {
  565. public string Module { get; set; }
  566. public string Name { get; set; }
  567. public delegate RoutineState RoutineFunc<T>(T arg);
  568. protected void Notify(string message)
  569. {
  570. EV.PostInfoLog(Module, $"[{Name}] routine, {message}");
  571. }
  572. protected void Stop(string failReason)
  573. {
  574. EV.PostAlarmLog(Module, $"[{Name}] routine failed, {failReason}");
  575. }
  576. public void TimeDelay(int id, double time)
  577. {
  578. Tuple<bool, Result> ret = Delay(id, () =>
  579. {
  580. Notify($"Delay {time} seconds");
  581. return true;
  582. }, time * 1000);
  583. if (ret.Item1)
  584. {
  585. if (ret.Item2 == Result.RUN)
  586. {
  587. throw (new RoutineBreakException());
  588. }
  589. }
  590. }
  591. protected void ExecuteRoutine(int id, IRoutine routine)
  592. {
  593. Tuple<bool, Result> ret = ExecuteAndWait(id, routine);
  594. if (ret.Item1)
  595. {
  596. if (ret.Item2 == Result.FAIL)
  597. {
  598. throw (new RoutineFaildException());
  599. }
  600. else if (ret.Item2 == Result.RUN)
  601. {
  602. throw (new RoutineBreakException());
  603. }
  604. }
  605. }
  606. protected void ExecutePumpDownRoutine(int id, IRoutine routine, double BasePressure)
  607. {
  608. Tuple<bool, Result> ret = ExecuteAndWaitPumpDown(id, routine, BasePressure);
  609. if (ret.Item1)
  610. {
  611. if (ret.Item2 == Result.FAIL)
  612. {
  613. throw (new RoutineFaildException());
  614. }
  615. else if (ret.Item2 == Result.RUN)
  616. {
  617. throw (new RoutineBreakException());
  618. }
  619. }
  620. }
  621. protected void PerformStep<T, T1>(T step, RoutineFunc<T1> func, T1 param1)
  622. {
  623. int idx = Convert.ToInt32(step);
  624. RoutineState state = func(param1);
  625. }
  626. }
  627. public class QueueRoutine
  628. {
  629. private Queue< IRoutine > _steps = new Queue< IRoutine >();
  630. private IRoutine _currentStep = null;
  631. public void Add(IRoutine step)
  632. {
  633. _steps.Enqueue(step);
  634. }
  635. public void Reset()
  636. {
  637. _steps.Clear();
  638. _currentStep = null;
  639. }
  640. public void Abort()
  641. {
  642. if (_currentStep != null)
  643. _currentStep.Abort();
  644. Reset();
  645. }
  646. public Result Start(params object[] objs)
  647. {
  648. if (_steps.Count == 0)
  649. return Result.DONE;
  650. _currentStep = _steps.Dequeue();
  651. return _currentStep.Start(objs);
  652. }
  653. public Result Monitor(params object[] objs)
  654. {
  655. Result ret = Result.FAIL;
  656. if (_currentStep != null)
  657. {
  658. ret = _currentStep.Monitor();
  659. }
  660. if (ret == Result.DONE)
  661. {
  662. _currentStep = _steps.Count > 0 ? _steps.Dequeue() : null;
  663. if (_currentStep != null)
  664. {
  665. return _currentStep.Start(objs);
  666. }
  667. }
  668. return ret;
  669. }
  670. }
  671. }