IoHeater.cs 12 KB

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