IoHeater.cs 17 KB

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