IoHeater.cs 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524
  1. using System;
  2. using System.Xml;
  3. using Aitex.Core.Common.DeviceData;
  4. using Aitex.Core.RT.DataCenter;
  5. using Aitex.Core.RT.Device;
  6. using Aitex.Core.RT.Event;
  7. using Aitex.Core.RT.IOCore;
  8. using Aitex.Core.RT.Log;
  9. using Aitex.Core.RT.OperationCenter;
  10. using Aitex.Core.RT.SCCore;
  11. using Aitex.Core.RT.Tolerance;
  12. using Aitex.Core.Util;
  13. using MECF.Framework.Common.Equipment;
  14. //using Venus_Core;
  15. namespace Venus_RT.Devices
  16. {
  17. //public interface IoHeaterController
  18. //{
  19. // bool SetPowerOnOff(bool isOn);
  20. // bool Ramp(float temp);
  21. // float GetFeedback();
  22. // float GetSetPoint();
  23. // bool GetIsOn();
  24. //}
  25. public class IoHeater : BaseDevice, IDevice
  26. {
  27. //public IoHeaterController Controller { get; set; }
  28. public double SetPointLimit
  29. {
  30. get
  31. {
  32. if (_aoSetPointLimit != null)
  33. return _GetRealFloat(_aoSetPointLimit);
  34. return 100;
  35. }
  36. }
  37. //public float CoolantInletTcFeedback
  38. //{
  39. // get
  40. // {
  41. // if (_aiCoolantInletTempFeedback == null) return -1;
  42. // return _GetRealFloat(_aiCoolantInletTempFeedback);
  43. // }
  44. //}
  45. //public float CoolantOutletTcFeedback
  46. //{
  47. // get
  48. // {
  49. // if (_aiCoolantOutletTempFeedback == null) return -1;
  50. // return _GetRealFloat(_aiCoolantOutletTempFeedback);
  51. // }
  52. //}
  53. //public float MonitorTcFeedback
  54. //{
  55. // get
  56. // {
  57. // if (_aiMonitorTcFeedback == null) return -1;
  58. // return _GetRealFloat(_aiMonitorTcFeedback);
  59. // }
  60. //}
  61. //[Subscription(AITHeaterPropertyName.ControlTcFeedback)]
  62. public float ControlTcFeedback
  63. {
  64. get
  65. {
  66. //if (Name == "ForelineHeater")
  67. //{
  68. // if (_aiControlTcFeedback == null) return -1;
  69. // return _GetRealFloat(_aiControlTcFeedback);
  70. //}
  71. if (_aiControlTcFeedback == null) return -1;
  72. float real = _GetRealFloat(_aiControlTcFeedback);
  73. return real;
  74. //return real - GetHeaterOffsetSetting(real - _offset);
  75. //return ((real - GetHeaterOffsetSetting(real - _offset)) >= ControlTcSetPoint - _offset) ? (real - _offset) : (real - GetHeaterOffsetSetting(real - _offset));
  76. }
  77. }
  78. //[Subscription(AITHeaterPropertyName.ControlTcSetPoint)]
  79. public float ControlTcSetPoint
  80. {
  81. get
  82. {
  83. if (_aoSetPoint != null)
  84. //return _aoSetPoint.Value;
  85. return _GetRealFloat(_aoSetPoint);
  86. //if (Controller != null)
  87. // return Controller.GetSetPoint();
  88. return 0;
  89. }
  90. private set
  91. {
  92. if (_aoSetPoint != null)
  93. {
  94. _SetRealFloat(_aoSetPoint, value);
  95. }
  96. }
  97. }
  98. //[Subscription(AITHeaterPropertyName.IsMonitorTcBroken)]
  99. public bool IsMonitorTcBroken
  100. {
  101. get
  102. {
  103. if (_diMonitorTcBroken != null)
  104. return _diMonitorTcBroken.Value;
  105. return false;
  106. }
  107. }
  108. //[Subscription(AITHeaterPropertyName.IsTcDeviation)]
  109. public bool IsTcDeviation
  110. {
  111. get
  112. {
  113. if (_diDeviation != null)
  114. return _diDeviation.Value;
  115. return false;
  116. }
  117. }
  118. //[Subscription(AITHeaterPropertyName.IsControlTcBroken)]
  119. public bool IsControlTcBroken
  120. {
  121. get
  122. {
  123. if (_diControlTcBroken != null)
  124. return _diControlTcBroken.Value;
  125. return false;
  126. }
  127. }
  128. [Subscription(AITHeaterPropertyName.IsPowerOnFeedback)]
  129. public bool IsPowerOnFeedback
  130. {
  131. get
  132. {
  133. //if (Controller != null)
  134. //{
  135. // return Controller.GetIsOn();
  136. //}
  137. if (_diPowerOnFeedback != null)
  138. return _diPowerOnFeedback.Value;
  139. if (_doPowerOn != null)
  140. return _doPowerOn.Value;
  141. return false;
  142. }
  143. }
  144. [Subscription(AITHeaterPropertyName.ControlTcSetPointView)]
  145. public float ControlTcSetPointView
  146. {
  147. get
  148. {
  149. return _controlTcSetPointView;
  150. }
  151. }
  152. [Subscription(AITHeaterPropertyName.IsPowerOnSetPoint)]
  153. public bool IsPowerOnSetPoint
  154. {
  155. get
  156. {
  157. if (_doPowerOn != null)
  158. return _doPowerOn.Value;
  159. return false;
  160. }
  161. set
  162. {
  163. if (_doPowerOn != null)
  164. {
  165. _doPowerOn.Value = value;
  166. }
  167. }
  168. }
  169. public string Unit { get; set; }
  170. //private int _stage = 0;
  171. private float _controlTcSetPointView = 0f;
  172. //private int _stageSet = 0;
  173. private float _offset = 0f;
  174. //private float _offsetSet = 0f;
  175. private readonly DIAccessor _diPowerOnFeedback;
  176. private readonly DIAccessor _diControlTcBroken;
  177. private readonly DIAccessor _diMonitorTcBroken;
  178. private readonly DIAccessor _diDeviation;
  179. private readonly DOAccessor _doPowerOn;
  180. private readonly AIAccessor _aiControlTcFeedback;
  181. //private readonly AIAccessor _aiMonitorTcFeedback;
  182. //private readonly AIAccessor _aiCoolantInletTempFeedback;
  183. //private readonly AIAccessor _aiCoolantOutletTempFeedback;
  184. private readonly AOAccessor _aoSetPoint;
  185. private AOAccessor _aoSetPointLimit;
  186. private readonly SCConfigItem _scSetPointLimit;
  187. private readonly R_TRIG _trigMonitorTcBroken = new R_TRIG();
  188. private readonly R_TRIG _trigControlTcBroken = new R_TRIG();
  189. private readonly R_TRIG _trigDeviation = new R_TRIG();
  190. //private readonly R_TRIG _trigCHBWallOTSW = new R_TRIG();
  191. private SCConfigItem _scEnableToleranceCheck;
  192. private SCConfigItem _scDeviationAlarmRange;
  193. private SCConfigItem _scDeviationAlarmTime;
  194. private SCConfigItem _scDeviationWarningRange;
  195. private SCConfigItem _scDeviationWarningTime;
  196. //private DeviceTimer _timerAlarm = new DeviceTimer();
  197. //private DeviceTimer _timerWarning = new DeviceTimer();
  198. //private readonly R_TRIG _trigWarning = new R_TRIG();
  199. //private readonly R_TRIG _trigAlarm = new R_TRIG();
  200. private ToleranceChecker _checkerWarning = new ToleranceChecker();
  201. private ToleranceChecker _checkerAlarm = new ToleranceChecker();
  202. private string HeaterDeviationAlarm = "HeaterDeviationAlarm";
  203. private bool isinit;
  204. private bool _isOn;
  205. public bool IsOn
  206. {
  207. set
  208. {
  209. _isOn = value;
  210. }
  211. }
  212. private float _TemperatureSetPoint;
  213. public float TemperatureSetPoint
  214. {
  215. set
  216. {
  217. if (value != _TemperatureSetPoint)
  218. {
  219. RampTemp(value);
  220. _TemperatureSetPoint = value;
  221. }
  222. }
  223. }
  224. public IoHeater(string module, XmlElement node, string ioModule = "")
  225. {
  226. base.Module = module;
  227. base.Name = node.GetAttribute("id");
  228. base.Display = node.GetAttribute("display");
  229. base.DeviceID = node.GetAttribute("schematicId");
  230. Unit = node.GetAttribute("unit");
  231. _diPowerOnFeedback = ParseDiNode("diPowerOnFeedback", node, ioModule);
  232. _diControlTcBroken = ParseDiNode("diControlTcBroken", node, ioModule);
  233. _diMonitorTcBroken = ParseDiNode("diMonitorTcBroken", node, ioModule);
  234. _doPowerOn = ParseDoNode("doPowerOn", node, ioModule);
  235. _diDeviation = ParseDiNode("diDeviation", node, ioModule);
  236. _aiControlTcFeedback = ParseAiNode("aiFeedback", node, ioModule);
  237. //_aiMonitorTcFeedback = ParseAiNode("aiMonitor", node, ioModule);
  238. //_aiCoolantInletTempFeedback = ParseAiNode("aiCoolantInletTemp", node, ioModule);
  239. //_aiCoolantOutletTempFeedback = ParseAiNode("aiCoolantOutletTemp", node, ioModule);
  240. _aoSetPoint = ParseAoNode("aoSetPoint", node, ioModule);
  241. _aoSetPointLimit = ParseAoNode("aoSetPointLimit", node, ioModule);
  242. _scSetPointLimit = ParseScNodeEx("scSetPointLimit", node, ioModule);
  243. }
  244. //public void UpdateConfig(double setPointLimit)
  245. //{
  246. // if (_aoSetPointLimit != null)
  247. // _aoSetPointLimit.Value = (short)setPointLimit;
  248. //}
  249. public bool Initialize()
  250. {
  251. DATA.Subscribe($"{Module}.{Name}.DeviceData", () =>
  252. {
  253. AITHeaterData data = new AITHeaterData()
  254. {
  255. Module = Module,
  256. DeviceName = Name,
  257. DeviceSchematicId = DeviceID,
  258. DisplayName = Display,
  259. FeedBack = ControlTcFeedback,
  260. //MonitorTcFeedBack = MonitorTcFeedback,
  261. //CoolantInletTcFeedback = CoolantInletTcFeedback,
  262. //CoolantOutletTcFeedback = CoolantOutletTcFeedback,
  263. Scale = SetPointLimit,
  264. SetPoint = ControlTcSetPoint,
  265. IsPowerOn = IsPowerOnFeedback,
  266. IsPowerOnSetPoint = IsPowerOnSetPoint,
  267. IsControlTcBroken = IsControlTcBroken,
  268. IsMonitorTcBroken = IsMonitorTcBroken,
  269. Unit = Unit,
  270. IsTcDeviation = IsTcDeviation,
  271. };
  272. return data;
  273. }, SubscriptionAttribute.FLAG.IgnoreSaveDB);
  274. DATA.Subscribe($"{Module}.{Name}.Temperature", () => ControlTcFeedback, SubscriptionAttribute.FLAG.IgnoreSaveDB);
  275. OP.Subscribe($"{Module}.{Name}.{AITHeaterOperation.SetPowerOnOff}", (functionName, param) =>
  276. {
  277. bool isEnable = (bool)param[0];
  278. return this.TurnOnOff(isEnable);
  279. });
  280. OP.Subscribe($"{Module}.{Name}.{AITHeaterOperation.Ramp}", (functionName, param) =>
  281. {
  282. float setpoint;
  283. float.TryParse((string)param[0], out setpoint);
  284. if (!RampTemp(setpoint)) return false;
  285. _controlTcSetPointView = setpoint;
  286. return true;
  287. });
  288. this.SetBySC(_aoSetPointLimit, _scSetPointLimit);
  289. _scEnableToleranceCheck = SC.GetConfigItem($"{Module}.{Name}.HeaterEnableTolerance");
  290. _scDeviationAlarmRange = SC.GetConfigItem($"{Module}.{Name}.HeaterAlarmRange");
  291. _scDeviationAlarmTime = SC.GetConfigItem($"{Module}.{Name}.HeaterAlarmTime");
  292. _scDeviationWarningRange = SC.GetConfigItem($"{Module}.{Name}.HeaterWarningRange");
  293. _scDeviationWarningTime = SC.GetConfigItem($"{Module}.{Name}.HeaterWarningTime");
  294. EV.Subscribe(new EventItem("Event", HeaterDeviationAlarm, "Heater Deviation Out of Tolerance", EventLevel.Alarm, EventType.HostNotification));
  295. isinit = true;
  296. return true;
  297. }
  298. public bool TurnOnOff(bool on)
  299. {
  300. //if (Controller != null)
  301. //{
  302. // Controller.SetPowerOnOff(on);
  303. // return true;
  304. //}
  305. if (!_doPowerOn.SetValue(on, out string reason))
  306. {
  307. LOG.Write(eEvent.WARN_DEVICE_IO_HEATER, ModuleHelper.Converter(Module), reason);
  308. return false;
  309. }
  310. SC.SetItemValue($"{Module}.{Name}.IsOn", on);
  311. LOG.Write(eEvent.INFO_DEVICE_IO_HEATER, ModuleHelper.Converter(Module), $"Set Heater {Name} Power {(on ? "ON" : "OFF")}");
  312. return true;
  313. }
  314. public bool RampTemp(float setpoint)
  315. {
  316. // 是否越界
  317. if (setpoint > SetPointLimit || setpoint < 0)
  318. {
  319. LOG.Write(eEvent.ERR_DEVICE_IO_HEATER, ModuleHelper.Converter(Module), $"{Name} 温度设定 {setpoint} 无效, 正确范围是 (0, {SetPointLimit})");
  320. return false;
  321. }
  322. if (setpoint == 0)
  323. {
  324. LOG.Write(eEvent.INFO_DEVICE_IO_HEATER, ModuleHelper.Converter(Module), $"{Name} setpoint = {setpoint}, ignore temperature control");
  325. return true;
  326. }
  327. SC.SetItemValue($"{Module}.{Name}.TemperatureSetPoint", setpoint);
  328. //if (Controller != null)
  329. //{
  330. // SC.SetItemValue($"{Module}.{Name}.TemperatureSetPoint", setpoint);
  331. // return Controller.Ramp(setpoint);
  332. //}
  333. //_offset = GetHeaterOffsetSetting(setpoint);
  334. // offset 处理后的设定值
  335. _controlTcSetPointView = setpoint;
  336. if (Name == "ForelineHeater")
  337. ControlTcSetPoint = setpoint;
  338. else
  339. ControlTcSetPoint = setpoint + _offset;
  340. LOG.Write(eEvent.INFO_DEVICE_IO_HEATER, ModuleHelper.Converter(Module), $"设定 {Display} 温度到 {setpoint}");
  341. return true;
  342. }
  343. public void Stop()
  344. {
  345. if (_aoSetPoint != null)
  346. {
  347. _aoSetPoint.Value = 0;
  348. }
  349. }
  350. public void Terminate()
  351. {
  352. }
  353. public void Monitor()
  354. {
  355. try
  356. {
  357. if (isinit == false)
  358. {
  359. return;
  360. }
  361. _trigControlTcBroken.CLK = IsControlTcBroken;
  362. if (_trigControlTcBroken.Q)
  363. {
  364. LOG.Write(eEvent.ERR_DEVICE_IO_HEATER, ModuleHelper.Converter(Module), $"{Display}, Found control TC broken");
  365. }
  366. _trigMonitorTcBroken.CLK = IsMonitorTcBroken;
  367. if (_trigMonitorTcBroken.Q)
  368. {
  369. LOG.Write(eEvent.ERR_DEVICE_IO_HEATER, ModuleHelper.Converter(Module), $"{Display}, Found monitor TC broken");
  370. }
  371. _trigDeviation.CLK = IsTcDeviation;
  372. if (_trigDeviation.Q)
  373. {
  374. LOG.Write(eEvent.ERR_DEVICE_IO_HEATER, ModuleHelper.Converter(Module), $"{Display}, Found TC Deviation out of range");
  375. }
  376. this.SetBySC(_aoSetPointLimit, _scSetPointLimit);
  377. CheckDeviation();
  378. TemperatureSetPoint = (float)SC.GetValue<double>($"{Module}.{Name}.TemperatureSetPoint");
  379. IsPowerOnSetPoint = SC.GetValue<bool>($"{Module}.{Name}.IsOn");
  380. }
  381. catch (Exception ex)
  382. {
  383. LOG.WriteExeption(ex);
  384. }
  385. }
  386. private void CheckDeviation()
  387. {
  388. if (!_scEnableToleranceCheck.BoolValue)
  389. return;
  390. //if (Controller != null && !Controller.GetIsOn())
  391. //{
  392. // return;
  393. //}
  394. if (!IsPowerOnFeedback)
  395. return;
  396. _checkerWarning.Monitor(ControlTcFeedback, ControlTcSetPoint - Math.Abs(_scDeviationWarningRange.IntValue)
  397. , ControlTcSetPoint + Math.Abs(_scDeviationWarningRange.IntValue), _scDeviationWarningTime.IntValue);
  398. if (_checkerWarning.Trig)
  399. {
  400. LOG.Write(eEvent.WARN_DEVICE_IO_HEATER, ModuleHelper.Converter(Module), $"{Name} temperature feedback deviation than {Math.Abs(_scDeviationWarningRange.IntValue)} from setpoint for {_scDeviationWarningTime.IntValue} seconds");
  401. }
  402. _checkerAlarm.Monitor(ControlTcFeedback, ControlTcSetPoint - Math.Abs(_scDeviationAlarmRange.IntValue)
  403. , ControlTcSetPoint + Math.Abs(_scDeviationAlarmRange.IntValue), _scDeviationAlarmTime.IntValue);
  404. if (_checkerAlarm.Trig)
  405. {
  406. LOG.Write(eEvent.ERR_DEVICE_IO_HEATER, ModuleHelper.Converter(Module), $"{Name} temperature feedback deviation than {Math.Abs(_scDeviationAlarmRange.IntValue)} from setpoint for {_scDeviationAlarmTime.IntValue} seconds");
  407. EV.Notify(HeaterDeviationAlarm);
  408. }
  409. }
  410. public void Reset()
  411. {
  412. _trigControlTcBroken.RST = true;
  413. _trigMonitorTcBroken.RST = true;
  414. _trigDeviation.RST = true;
  415. _checkerWarning.RST = true;
  416. _checkerAlarm.RST = true;
  417. }
  418. private void SetBySC(AOAccessor acc, SCConfigItem scItem)
  419. {
  420. if (scItem != null && acc != null)
  421. {
  422. //acc.Value = (short)scItem.IntValue;
  423. _SetRealFloat(acc, scItem.IntValue);
  424. }
  425. }
  426. //private float GetHeaterOffsetSetting(double val)
  427. //{
  428. // //if (SC.GetValue<bool>($"{Module}.BiasRf.EnableBiasRF")) return 0;
  429. // //if (SC.GetValue<bool>($"{Module}.Chiller.EnableChiller")) return 0;
  430. // int[] iTempPoint = new int[10];
  431. // float[] fOffsetValue = new float[10];
  432. // try
  433. // {
  434. // for (int i = 1; i < 10; i++)
  435. // {
  436. // iTempPoint[i] = SC.GetValue<int>($"{Module}.{Name}.TempOffsetPoint_{i}");
  437. // fOffsetValue[i] = (float)SC.GetValue<double>($"{Module}.{Name}.OffsetValue_{i}");
  438. // if (val < iTempPoint[i])
  439. // {
  440. // return (fOffsetValue[i] - fOffsetValue[i - 1]) / (iTempPoint[i] - iTempPoint[i - 1]) * ((float)val - iTempPoint[i - 1]) + fOffsetValue[i - 1];
  441. // }
  442. // }
  443. // }
  444. // catch
  445. // { }
  446. // return 0;
  447. //}
  448. }
  449. }