InterlockLimit.cs 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488
  1. using System;
  2. using System.Collections.Generic;
  3. using Aitex.Core.RT.DataCenter;
  4. using Aitex.Core.RT.SCCore;
  5. using Aitex.Core.Util;
  6. using DocumentFormat.OpenXml.Spreadsheet;
  7. namespace Aitex.Core.RT.IOCore
  8. {
  9. /*
  10. *
  11. <Action do="DO_MFC1_valve__" value="true" tip="" tip.zh-CN="" tip.en-US="">
  12. <Limit di="DI_Chamber_door_sw" value="true" tip="" tip.zh-CN="" tip.en-US="" />
  13. </Action>
  14. *
  15. */
  16. public abstract class InterlockLimit
  17. {
  18. public string Name
  19. {
  20. get { return _name; }
  21. }
  22. public abstract bool CurrentValue { get; }
  23. public abstract string LimitReason { get; }
  24. public bool LimitValue
  25. {
  26. get { return _limitValue; }
  27. }
  28. public string Tip
  29. {
  30. get
  31. {
  32. return _tip;
  33. }
  34. }
  35. public string Condition { get; set; }//AND,OR,EXOR,BLANK
  36. public bool IsFloatType { get; set; }
  37. private string _name;
  38. private bool _limitValue;
  39. private string _tip;
  40. private Dictionary<string, string> _cultureTip = new Dictionary<string, string>();
  41. R_TRIG _trigger = new R_TRIG();
  42. public InterlockLimit(string name, bool value, string tip, Dictionary<string, string> cultureTip)
  43. {
  44. _name = name;
  45. _limitValue = value;
  46. _tip = tip;
  47. _cultureTip = cultureTip;
  48. }
  49. public bool IsSame(string name, bool value)
  50. {
  51. return (name == _name) && (_limitValue == value);
  52. }
  53. public bool IsSame(InterlockLimit limit)
  54. {
  55. return (limit.Name == _name) && (_limitValue == limit.LimitValue);
  56. }
  57. public bool IsTriggered()
  58. {
  59. _trigger.CLK = CurrentValue != _limitValue;
  60. return _trigger.Q;
  61. }
  62. public bool CanDo(out string reason)
  63. {
  64. reason = string.Empty;
  65. if (CurrentValue == _limitValue)
  66. return true;
  67. reason = LimitReason;
  68. return false;
  69. }
  70. }
  71. internal class DiLimit : InterlockLimit
  72. {
  73. private DIAccessor _di;
  74. public DiLimit(DIAccessor diItem, bool value, string tip, Dictionary<string, string> cultureTip, string condition = "AND")
  75. : base(diItem.Name, value, tip, cultureTip)
  76. {
  77. _di = diItem;
  78. Condition = condition;
  79. }
  80. public DiLimit(DIAccessor diItem, bool value, string condition)
  81. : base(diItem.Name, value, "", null)
  82. {
  83. _di = diItem;
  84. Condition = condition;
  85. }
  86. public override bool CurrentValue
  87. {
  88. get { return _di.Value; }
  89. }
  90. public override string LimitReason
  91. {
  92. get
  93. {
  94. return string.Format("DI-{0}({1}) = [{2}],{3}", _di.IoTableIndex, _di.Name, _di.Value ? "ON" : "OFF", Tip);
  95. }
  96. }
  97. }
  98. internal class DoLimit : InterlockLimit
  99. {
  100. private DOAccessor _do;
  101. public DoLimit(DOAccessor doItem, bool value, string tip, Dictionary<string, string> cultureTip, string condition = "AND")
  102. : base(doItem.Name, value, tip, cultureTip)
  103. {
  104. _do = doItem;
  105. Condition = condition;
  106. }
  107. public DoLimit(DOAccessor doItem, bool value, string condition)
  108. : base(doItem.Name, value, "", null)
  109. {
  110. _do = doItem;
  111. Condition = condition;
  112. }
  113. public override bool CurrentValue
  114. {
  115. get { return _do.Value; }
  116. }
  117. public override string LimitReason
  118. {
  119. get
  120. {
  121. return string.Format("DO-{0}({1}) = [{2}],{3}", _do.IoTableIndex, _do.Name, _do.Value ? "ON" : "OFF", Tip);
  122. }
  123. }
  124. }
  125. internal class AoLimit : InterlockLimit
  126. {
  127. /// <summary>
  128. //LT(less than) 小于
  129. //LE(less than or equal to) 小于等于
  130. //EQ(equal to) 等于
  131. //NE(not equal to) 不等于
  132. //GE(greater than or equal to)大于等于
  133. //GT(greater than) 大于
  134. //B(bool)
  135. /// </summary>
  136. private AOAccessor _ao;
  137. private float _limitFloatValue;
  138. private string _operator;
  139. private string _module = "";
  140. public AoLimit(AOAccessor aoItem, string value, string condition, bool isFloatType = true)
  141. : base(aoItem.Name, true, "", null)
  142. {
  143. _ao = aoItem;
  144. Condition = condition;
  145. IsFloatType = isFloatType;
  146. //if (value.StartsWith(">="))
  147. //{
  148. // _operator = ">=";
  149. //}
  150. //else if (value.StartsWith("<="))
  151. //{
  152. // _operator = "<=";
  153. //}
  154. //else if (value.StartsWith(">"))
  155. //{
  156. // _operator = ">";
  157. //}
  158. //else if (value.StartsWith("<"))
  159. //{
  160. // _operator = "<";
  161. //}
  162. //else
  163. //{
  164. // _operator = "=";
  165. //}
  166. if (value.Contains("GT"))
  167. {
  168. _operator = "GT";
  169. }
  170. else if (value.Contains("GE"))
  171. {
  172. _operator = "GE";
  173. }
  174. else if (value.Contains("NE"))
  175. {
  176. _operator = "NE";
  177. }
  178. else if (value.Contains("EQ"))
  179. {
  180. _operator = "EQ";
  181. }
  182. else if (value.Contains("LE"))
  183. {
  184. _operator = "LE";
  185. }
  186. else if (value.Contains("LT"))
  187. {
  188. _operator = "LT";
  189. }
  190. float.TryParse(value.Replace(_operator, ""), out _limitFloatValue);
  191. var paras = aoItem.Name.Split('.');
  192. if (paras != null && paras.Length > 1)
  193. _module = paras[0];
  194. }
  195. public override string LimitReason
  196. {
  197. get
  198. {
  199. return string.Format("AO-{0}({1}) = [{2}],{3}", _ao.IoTableIndex, _ao.Name, (SC.ContainsItem($"{_module}.IsAIAOFloatType") && SC.GetValue<bool>($"{_module}.IsAIAOFloatType") ? _ao.FloatValue : _ao.Value), Tip);
  200. }
  201. }
  202. public override bool CurrentValue
  203. {
  204. get
  205. {
  206. switch (_operator)
  207. {
  208. case "GT":
  209. return (SC.ContainsItem($"{_module}.IsAIAOFloatType") && SC.GetValue<bool>($"{_module}.IsAIAOFloatType") ? _ao.FloatValue : _ao.Value) > _limitFloatValue;
  210. case "GE":
  211. return (SC.ContainsItem($"{_module}.IsAIAOFloatType") && SC.GetValue<bool>($"{_module}.IsAIAOFloatType") ? _ao.FloatValue : _ao.Value) >= _limitFloatValue;
  212. case "NE":
  213. return (SC.ContainsItem($"{_module}.IsAIAOFloatType") && SC.GetValue<bool>($"{_module}.IsAIAOFloatType") ? _ao.FloatValue : _ao.Value) != _limitFloatValue;
  214. case "EQ":
  215. return Math.Abs((SC.ContainsItem($"{_module}.IsAIAOFloatType") && SC.GetValue<bool>($"{_module}.IsAIAOFloatType") ? _ao.FloatValue : _ao.Value) - _limitFloatValue) < 0.000001;
  216. case "LE":
  217. return (SC.ContainsItem($"{_module}.IsAIAOFloatType") && SC.GetValue<bool>($"{_module}.IsAIAOFloatType") ? _ao.FloatValue : _ao.Value) <= _limitFloatValue;
  218. case "LT":
  219. return (SC.ContainsItem($"{_module}.IsAIAOFloatType") && SC.GetValue<bool>($"{_module}.IsAIAOFloatType") ? _ao.FloatValue : _ao.Value) < _limitFloatValue;
  220. default:
  221. return false;
  222. }
  223. }
  224. }
  225. }
  226. internal class AiLimit : InterlockLimit
  227. {
  228. /// <summary>
  229. //LT(less than) 小于
  230. //LE(less than or equal to) 小于等于
  231. //EQ(equal to) 等于
  232. //NE(not equal to) 不等于
  233. //GE(greater than or equal to)大于等于
  234. //GT(greater than) 大于
  235. //B(bool)
  236. /// </summary>
  237. private AIAccessor _ai;
  238. private float _limitFloatValue;
  239. private string _operator;
  240. private string _module = "";
  241. public AiLimit(AIAccessor aiItem, string value, string condition, bool isFloatType = true)
  242. : base(aiItem.Name, true, "", null)
  243. {
  244. _ai = aiItem;
  245. Condition = condition;
  246. IsFloatType = isFloatType;
  247. //if (value.StartsWith(">="))
  248. //{
  249. // _operator = ">=";
  250. //}
  251. //else if (value.StartsWith("<="))
  252. //{
  253. // _operator = "<=";
  254. //}
  255. //else if (value.StartsWith(">"))
  256. //{
  257. // _operator = ">";
  258. //}
  259. //else if (value.StartsWith("<"))
  260. //{
  261. // _operator = "<";
  262. //}
  263. //else
  264. //{
  265. // _operator = "=";
  266. //}
  267. if (value.Contains("GT"))
  268. {
  269. _operator = "GT";
  270. }
  271. else if (value.Contains("GE"))
  272. {
  273. _operator = "GE";
  274. }
  275. else if (value.Contains("NE"))
  276. {
  277. _operator = "NE";
  278. }
  279. else if (value.Contains("EQ"))
  280. {
  281. _operator = "EQ";
  282. }
  283. else if (value.Contains("LE"))
  284. {
  285. _operator = "LE";
  286. }
  287. else if (value.Contains("LT"))
  288. {
  289. _operator = "LT";
  290. }
  291. float.TryParse(value.Replace(_operator, ""), out _limitFloatValue);
  292. var paras = aiItem.Name.Split('.');
  293. if (paras != null && paras.Length > 1)
  294. _module = paras[0];
  295. }
  296. public override string LimitReason
  297. {
  298. get
  299. {
  300. return string.Format("AO-{0}({1}) = [{2}],{3}", _ai.IoTableIndex, _ai.Name, (SC.ContainsItem($"{_module}.IsAIAOFloatType") && SC.GetValue<bool>($"{_module}.IsAIAOFloatType") ? _ai.FloatValue : _ai.Value), Tip);
  301. }
  302. }
  303. public override bool CurrentValue
  304. {
  305. get
  306. {
  307. switch (_operator)
  308. {
  309. case "GT":
  310. return (SC.ContainsItem($"{_module}.IsAIAOFloatType") && SC.GetValue<bool>($"{_module}.IsAIAOFloatType") ? _ai.FloatValue : _ai.Value) > _limitFloatValue;
  311. case "GE":
  312. return (SC.ContainsItem($"{_module}.IsAIAOFloatType") && SC.GetValue<bool>($"{_module}.IsAIAOFloatType") ? _ai.FloatValue : _ai.Value) >= _limitFloatValue;
  313. case "NE":
  314. return (SC.ContainsItem($"{_module}.IsAIAOFloatType") && SC.GetValue<bool>($"{_module}.IsAIAOFloatType") ? _ai.FloatValue : _ai.Value) != _limitFloatValue;
  315. case "EQ":
  316. return Math.Abs((SC.ContainsItem($"{_module}.IsAIAOFloatType") && SC.GetValue<bool>($"{_module}.IsAIAOFloatType") ? _ai.FloatValue : _ai.Value) - _limitFloatValue) < 0.000001;
  317. case "LE":
  318. return (SC.ContainsItem($"{_module}.IsAIAOFloatType") && SC.GetValue<bool>($"{_module}.IsAIAOFloatType") ? _ai.FloatValue : _ai.Value) <= _limitFloatValue;
  319. case "LT":
  320. return (SC.ContainsItem($"{_module}.IsAIAOFloatType") && SC.GetValue<bool>($"{_module}.IsAIAOFloatType") ? _ai.FloatValue : _ai.Value) < _limitFloatValue;
  321. default:
  322. return false;
  323. }
  324. }
  325. }
  326. }
  327. internal class UserDefineLimit : InterlockLimit
  328. {
  329. public UserDefineLimit(string name, bool limitValue, string condition)
  330. : base(name, limitValue, "", null)
  331. {
  332. Condition = condition;
  333. }
  334. public override bool CurrentValue { get; }
  335. public override string LimitReason { get; }
  336. }
  337. internal class DataPollLimit : InterlockLimit
  338. {
  339. /// <summary>
  340. //LT(less than) 小于
  341. //LE(less than or equal to) 小于等于
  342. //EQ(equal to) 等于
  343. //NE(not equal to) 不等于
  344. //GE(greater than or equal to)大于等于
  345. //GT(greater than) 大于
  346. //B(bool)
  347. /// </summary>
  348. private string _operator;
  349. private string _operatorTip;
  350. private float _limitFloatValue;
  351. private bool _limitBoolValue;
  352. public DataPollLimit(string name, string limitValue, string condition)
  353. : base(name, true, "", null)
  354. {
  355. Condition = condition;
  356. if (limitValue.Contains("GT"))
  357. {
  358. _operator = "GT";
  359. _operatorTip = ">";
  360. float.TryParse(limitValue.Replace(_operator, ""), out _limitFloatValue);
  361. }
  362. else if (limitValue.Contains("GE"))
  363. {
  364. _operator = "GE";
  365. _operatorTip = ">=";
  366. float.TryParse(limitValue.Replace(_operator, ""), out _limitFloatValue);
  367. }
  368. else if (limitValue.Contains("NE"))
  369. {
  370. _operator = "NE";
  371. _operatorTip = "!=";
  372. float.TryParse(limitValue.Replace(_operator, ""), out _limitFloatValue);
  373. }
  374. else if (limitValue.Contains("EQ"))
  375. {
  376. _operator = "EQ";
  377. _operatorTip = "==";
  378. float.TryParse(limitValue.Replace(_operator, ""), out _limitFloatValue);
  379. }
  380. else if (limitValue.Contains("LE"))
  381. {
  382. _operator = "LE";
  383. _operatorTip = "<=";
  384. float.TryParse(limitValue.Replace(_operator, ""), out _limitFloatValue);
  385. }
  386. else if (limitValue.Contains("LT"))
  387. {
  388. _operator = "LT";
  389. _operatorTip = "<";
  390. float.TryParse(limitValue.Replace(_operator, ""), out _limitFloatValue);
  391. }
  392. else
  393. {
  394. _operator = "B";
  395. _operatorTip = "true";
  396. _limitBoolValue = limitValue.ToUpper().Contains("ON") ? true : false;
  397. }
  398. }
  399. public override bool CurrentValue
  400. {
  401. get
  402. {
  403. switch (_operator)
  404. {
  405. case "GT":
  406. float.TryParse(DATA.Poll(Name).ToString(), out float valueGT);
  407. return valueGT > _limitFloatValue;
  408. case "GE":
  409. float.TryParse(DATA.Poll(Name).ToString(), out float valueGE);
  410. return valueGE >= _limitFloatValue;
  411. case "NE":
  412. float.TryParse(DATA.Poll(Name).ToString(), out float valueNE);
  413. return valueNE != _limitFloatValue;
  414. case "EQ":
  415. float.TryParse(DATA.Poll(Name).ToString(), out float valueEQ);
  416. return valueEQ == _limitFloatValue;
  417. case "LE":
  418. float.TryParse(DATA.Poll(Name).ToString(), out float valueLE);
  419. return valueLE <= _limitFloatValue;
  420. case "LT":
  421. float.TryParse(DATA.Poll(Name).ToString(), out float valueLT);
  422. return valueLT < _limitFloatValue;
  423. case "B":
  424. bool.TryParse(DATA.Poll(Name).ToString(), out bool valueB);
  425. return !(valueB ^ _limitBoolValue);
  426. default:
  427. return false;
  428. }
  429. }
  430. }
  431. public override string LimitReason
  432. {
  433. get
  434. {
  435. return $"DATA.Poll-{Name} = [{DATA.Poll(Name)}] not {_operatorTip} {(_operator == "B" ? _limitBoolValue.ToString() : _limitFloatValue.ToString())}";
  436. }
  437. }
  438. }
  439. public class CustomLimitBase : InterlockLimit
  440. {
  441. public CustomLimitBase(string name, bool limitValue, string tip, Dictionary<string, string> cultureTip) : base(name, limitValue, tip, cultureTip)
  442. {
  443. }
  444. public override bool CurrentValue { get; }
  445. public override string LimitReason { get; }
  446. }
  447. }