IoHeater.cs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383
  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.OperationCenter;
  9. using Aitex.Core.RT.SCCore;
  10. using Aitex.Core.Util;
  11. namespace VirgoRT.Devices
  12. {
  13. public class IoHeater : BaseDevice, IDevice
  14. {
  15. public double SetPointLimit
  16. {
  17. get
  18. {
  19. if (_aoSetPointLimit != null)
  20. //return _aoSetPointLimit.Value;
  21. return _GetRealFloat(_aoSetPointLimit);
  22. return 100;
  23. }
  24. }
  25. [Subscription(AITHeaterPropertyName.CoolantInletTempFeedback)]
  26. public float CoolantInletTcFeedback
  27. {
  28. get
  29. {
  30. if (_aiCoolantInletTempFeedback == null) return -1;
  31. //return _aiMonitorTcFeedback.Value;
  32. return _GetRealFloat(_aiCoolantInletTempFeedback);
  33. }
  34. }
  35. [Subscription(AITHeaterPropertyName.CoolantOutletTempFeedback)]
  36. public float CoolantOutletTcFeedback
  37. {
  38. get
  39. {
  40. if (_aiCoolantOutletTempFeedback == null) return -1;
  41. //return _aiMonitorTcFeedback.Value;
  42. return _GetRealFloat(_aiCoolantOutletTempFeedback);
  43. }
  44. }
  45. [Subscription(AITHeaterPropertyName.MonitorTcFeedback)]
  46. public float MonitorTcFeedback
  47. {
  48. get
  49. {
  50. if (_aiMonitorTcFeedback == null) return -1;
  51. //return _aiMonitorTcFeedback.Value;
  52. return _GetRealFloat(_aiMonitorTcFeedback);
  53. }
  54. }
  55. [Subscription(AITHeaterPropertyName.ControlTcFeedback)]
  56. public float ControlTcFeedback
  57. {
  58. get
  59. {
  60. if (Name == "ForelineHeater")
  61. {
  62. if (_aiControlTcFeedback == null) return -1;
  63. return _GetRealFloat(_aiControlTcFeedback);
  64. }
  65. if (_aiControlTcFeedback == null) return -1;
  66. float real = _GetRealFloat(_aiControlTcFeedback);
  67. return real - GetHeaterOffsetSetting(real - _offset);
  68. //return ((real - GetHeaterOffsetSetting(real - _offset)) >= ControlTcSetPoint - _offset) ? (real - _offset) : (real - GetHeaterOffsetSetting(real - _offset));
  69. }
  70. }
  71. [Subscription(AITHeaterPropertyName.ControlTcSetPoint)]
  72. public float ControlTcSetPoint
  73. {
  74. get
  75. {
  76. if (_aoSetPoint != null)
  77. //return _aoSetPoint.Value;
  78. return _GetRealFloat(_aoSetPoint);
  79. return 0;
  80. }
  81. private set
  82. {
  83. if (_aoSetPoint != null)
  84. {
  85. //_aoSetPoint.Value = (short)setpoint;
  86. _SetRealFloat(_aoSetPoint, value);
  87. }
  88. }
  89. }
  90. [Subscription(AITHeaterPropertyName.IsMonitorTcBroken)]
  91. public bool IsMonitorTcBroken
  92. {
  93. get
  94. {
  95. if (_diMonitorTcBroken != null)
  96. return _diMonitorTcBroken.Value;
  97. return false;
  98. }
  99. }
  100. [Subscription(AITHeaterPropertyName.IsTcDeviation)]
  101. public bool IsTcDeviation
  102. {
  103. get
  104. {
  105. if (_diDeviation != null)
  106. return _diDeviation.Value;
  107. return false;
  108. }
  109. }
  110. [Subscription(AITHeaterPropertyName.IsControlTcBroken)]
  111. public bool IsControlTcBroken
  112. {
  113. get
  114. {
  115. if (_diControlTcBroken != null)
  116. return _diControlTcBroken.Value;
  117. return false;
  118. }
  119. }
  120. [Subscription(AITHeaterPropertyName.IsPowerOnFeedback)]
  121. public bool IsPowerOnFeedback
  122. {
  123. get
  124. {
  125. if (_diPowerOnFeedback != null)
  126. return _diPowerOnFeedback.Value;
  127. if (_doPowerOn != null)
  128. return _doPowerOn.Value;
  129. return false;
  130. }
  131. }
  132. [Subscription(AITHeaterPropertyName.ControlTcSetPointView)]
  133. public float ControlTcSetPointView
  134. {
  135. get
  136. {
  137. return _controlTcSetPointView;
  138. }
  139. }
  140. [Subscription(AITHeaterPropertyName.IsPowerOnSetPoint)]
  141. public bool IsPowerOnSetPoint
  142. {
  143. get
  144. {
  145. if (_doPowerOn != null)
  146. return _doPowerOn.Value;
  147. return false;
  148. }
  149. }
  150. public string Unit { get; set; }
  151. //private int _stage = 0;
  152. private float _controlTcSetPointView = 0f;
  153. //private int _stageSet = 0;
  154. private float _offset = 0f;
  155. //private float _offsetSet = 0f;
  156. private readonly DIAccessor _diPowerOnFeedback;
  157. private readonly DIAccessor _diControlTcBroken;
  158. private readonly DIAccessor _diMonitorTcBroken;
  159. private readonly DIAccessor _diDeviation;
  160. private readonly DOAccessor _doPowerOn;
  161. private readonly AIAccessor _aiControlTcFeedback;
  162. private readonly AIAccessor _aiMonitorTcFeedback;
  163. private readonly AIAccessor _aiCoolantInletTempFeedback;
  164. private readonly AIAccessor _aiCoolantOutletTempFeedback;
  165. private readonly AOAccessor _aoSetPoint;
  166. private AOAccessor _aoSetPointLimit;
  167. private readonly SCConfigItem _scSetPointLimit;
  168. private readonly R_TRIG _trigMonitorTcBroken = new R_TRIG();
  169. private readonly R_TRIG _trigControlTcBroken = new R_TRIG();
  170. private readonly R_TRIG _trigDeviation = new R_TRIG();
  171. public IoHeater(string module, XmlElement node, string ioModule = "")
  172. {
  173. base.Module = module;
  174. base.Name = node.GetAttribute("id");
  175. base.Display = node.GetAttribute("display");
  176. base.DeviceID = node.GetAttribute("schematicId");
  177. Unit = node.GetAttribute("unit");
  178. _diPowerOnFeedback = ParseDiNode("diPowerOnFeedback", node, ioModule);
  179. _diControlTcBroken = ParseDiNode("diControlTcBroken", node, ioModule);
  180. _diMonitorTcBroken = ParseDiNode("diMonitorTcBroken", node, ioModule);
  181. _doPowerOn = ParseDoNode("doPowerOn", node, ioModule);
  182. _diDeviation = ParseDiNode("diDeviation", node, ioModule);
  183. _aiControlTcFeedback = ParseAiNode("aiFeedback", node, ioModule);
  184. _aiMonitorTcFeedback = ParseAiNode("aiMonitor", node, ioModule);
  185. _aiCoolantInletTempFeedback = ParseAiNode("aiCoolantInletTemp", node, ioModule);
  186. _aiCoolantOutletTempFeedback = ParseAiNode("aiCoolantOutletTemp", node, ioModule);
  187. _aoSetPoint = ParseAoNode("aoSetPoint", node, ioModule);
  188. _aoSetPointLimit = ParseAoNode("aoSetPointLimit", node, ioModule);
  189. _scSetPointLimit = ParseScNodeEx("scSetPointLimit", node, ioModule);
  190. }
  191. //public void UpdateConfig(double setPointLimit)
  192. //{
  193. // if (_aoSetPointLimit != null)
  194. // _aoSetPointLimit.Value = (short)setPointLimit;
  195. //}
  196. public bool Initialize()
  197. {
  198. DATA.Subscribe($"{Module}.{Name}.DeviceData", () =>
  199. {
  200. AITHeaterData data = new AITHeaterData()
  201. {
  202. Module = Module,
  203. DeviceName = Name,
  204. DeviceSchematicId = DeviceID,
  205. DisplayName = Display,
  206. FeedBack = ControlTcFeedback,
  207. MonitorTcFeedBack = MonitorTcFeedback,
  208. CoolantInletTcFeedback = CoolantInletTcFeedback,
  209. CoolantOutletTcFeedback = CoolantOutletTcFeedback,
  210. Scale = SetPointLimit,
  211. SetPoint = ControlTcSetPointView,
  212. IsPowerOn = IsPowerOnFeedback,
  213. IsPowerOnSetPoint = IsPowerOnSetPoint,
  214. IsControlTcBroken = IsControlTcBroken,
  215. IsMonitorTcBroken = IsMonitorTcBroken,
  216. Unit = Unit,
  217. IsTcDeviation = IsTcDeviation,
  218. };
  219. return data;
  220. }, SubscriptionAttribute.FLAG.IgnoreSaveDB);
  221. DATA.Subscribe($"{Module}.{Name}.Temperature", () => ControlTcFeedback, SubscriptionAttribute.FLAG.IgnoreSaveDB);
  222. OP.Subscribe($"{Module}.{Name}.{AITHeaterOperation.SetPowerOnOff}", (functionName, param) =>
  223. {
  224. bool isEnable = Convert.ToBoolean((string)param[0]);
  225. return this.TurnOnOff(isEnable);
  226. });
  227. OP.Subscribe($"{Module}.{Name}.{AITHeaterOperation.Ramp}", (functionName, param) =>
  228. {
  229. float setpoint = (float)Convert.ToDouble((string)param[0]);
  230. if (!RampTemp(setpoint)) return false;
  231. return true;
  232. });
  233. this.SetBySC(_aoSetPointLimit, _scSetPointLimit);
  234. return true;
  235. }
  236. public bool TurnOnOff(bool on)
  237. {
  238. if (!_doPowerOn.SetValue(on, out string reason))
  239. {
  240. EV.PostWarningLog(Module, reason);
  241. return false;
  242. }
  243. EV.PostInfoLog(Module, $"Set Heater {Name} Power {(on ? "ON" : "OFF")}");
  244. return true;
  245. }
  246. public bool RampTemp(float setpoint)
  247. {
  248. //_stageSet = (setpoint < 100) ? 3 : (setpoint < 200 && setpoint >= 100) ? 5 : (setpoint >= 200) ? 6 : 0;
  249. _offset = GetHeaterOffsetSetting(setpoint);
  250. // offset 处理后的设定值
  251. _controlTcSetPointView = setpoint;
  252. if (Name == "ForelineHeater")
  253. ControlTcSetPoint = setpoint;
  254. else
  255. ControlTcSetPoint = setpoint + _offset;
  256. // 是否越界
  257. if (setpoint > SetPointLimit || setpoint < 0)
  258. {
  259. EV.PostAlarmLog(Module, $"{Name} 温度设定 {setpoint} 无效, 正确范围是 (0, {SetPointLimit})");
  260. return false;
  261. }
  262. EV.PostInfoLog(Module, $"设定 {Display} 温度到 {setpoint}");
  263. return true;
  264. }
  265. public void Stop()
  266. {
  267. if (_aoSetPoint != null)
  268. {
  269. _aoSetPoint.Value = 0;
  270. }
  271. }
  272. public void Terminate()
  273. {
  274. }
  275. public void Monitor()
  276. {
  277. _trigControlTcBroken.CLK = IsControlTcBroken;
  278. if (_trigControlTcBroken.Q)
  279. {
  280. EV.PostWarningLog(Module, $"{Display}, Found control TC broken");
  281. }
  282. _trigMonitorTcBroken.CLK = IsMonitorTcBroken;
  283. if (_trigMonitorTcBroken.Q)
  284. {
  285. EV.PostWarningLog(Module, $"{Display}, Found monitor TC broken");
  286. }
  287. _trigDeviation.CLK = IsTcDeviation;
  288. if (_trigDeviation.Q)
  289. {
  290. EV.PostWarningLog(Module, $"{Display}, Found TC Deviation out of range");
  291. }
  292. this.SetBySC(_aoSetPointLimit, _scSetPointLimit);
  293. }
  294. public void Reset()
  295. {
  296. _trigControlTcBroken.RST = true;
  297. _trigMonitorTcBroken.RST = true;
  298. _trigDeviation.RST = true;
  299. }
  300. private void SetBySC(AOAccessor acc, SCConfigItem scItem)
  301. {
  302. if (scItem != null && acc != null)
  303. {
  304. //acc.Value = (short)scItem.IntValue;
  305. _SetRealFloat(acc, scItem.IntValue);
  306. }
  307. }
  308. private float GetHeaterOffsetSetting(double val)
  309. {
  310. if (SC.GetValue<bool>($"{Module}.BiasRf.EnableBiasRF")) return 0;
  311. if (SC.GetValue<bool>($"{Module}.Chiller.EnableChiller")) return 0;
  312. int[] iTempPoint = new int[10];
  313. float[] fOffsetValue = new float[10];
  314. try
  315. {
  316. for (int i = 1; i < 10; i++)
  317. {
  318. iTempPoint[i] = SC.GetValue<int>($"{Module}.HeaterChamber.TempOffsetPoint_{i}");
  319. fOffsetValue[i] = (float)SC.GetValue<double>($"{Module}.HeaterChamber.OffsetValue_{i}");
  320. if (val < iTempPoint[i])
  321. {
  322. return (fOffsetValue[i] - fOffsetValue[i - 1]) / (iTempPoint[i] - iTempPoint[i - 1]) * ((float)val - iTempPoint[i - 1]) + fOffsetValue[i - 1];
  323. }
  324. }
  325. }
  326. catch
  327. { }
  328. return 0;
  329. }
  330. }
  331. }