EurothermP116.cs 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Threading;
  4. using Aitex.Core.RT.DataCenter;
  5. using Aitex.Core.RT.Device;
  6. using Aitex.Core.RT.Event;
  7. using Aitex.Core.RT.Log;
  8. using Aitex.Core.RT.OperationCenter;
  9. using Aitex.Core.RT.SCCore;
  10. using Aitex.Core.Util;
  11. using MECF.Framework.Common.Communications;
  12. namespace MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Temperatures.Eurotherms
  13. {
  14. public class AdressInfo
  15. {
  16. public string Name { get; set; }
  17. public byte DeviceAddress { get; set; }
  18. public int UnitAddress { get; set; }
  19. public int Length { get; set; }
  20. public int Data;
  21. public string Remark { get; set; }//H3-N2-H4-N5-H6(H3代表连续3个地址有数据,N2代表H3与H4中间有两个地址为预留)
  22. }
  23. public class EurothermP116 : BaseDevice, IConnection,IDevice
  24. {
  25. private EurothermP116Connection _connection;
  26. private bool _activeMonitorStatus;
  27. private int _errorCode;
  28. private R_TRIG _trigCommunicationError = new R_TRIG();
  29. private R_TRIG _trigRetryConnect = new R_TRIG();
  30. private PeriodicJob _thread;
  31. //private int tempCount = 1;
  32. private LinkedList<HandlerBase> _lstHandler = new LinkedList<HandlerBase>();
  33. private object _locker = new object();
  34. private bool _enableLog = true;
  35. private string _scRoot;
  36. //private int _actualTempValue = 999;
  37. //private int _settingTempValue = 888;
  38. public int moduleCount { get; set; }
  39. private int _tempWarningMaxDiff = 1; //报警最大温度(实际温度与设定温度之间的差值)
  40. //private R_TRIG[] TempWarningTrig = new R_TRIG[12]; //温度报警
  41. //string[] WarningInfo = new string[12] { "HeatTMAPanel","HeatTCSPanel","OuterPanel","MidPanel","InnerPanel","HeatShowerOuter", "HeatShowerInner", "HeatShowerMid", "HeatDptPanel","HeatLeakSource","HeatLeakBypass","HeatDptGate"};
  42. //public float[] ActualTemp = new float[12];
  43. //public float[] SettingTemp = new float[12];
  44. public float fPVInValue, fTargetSP;
  45. public int iAM = -1;
  46. public string Address
  47. {
  48. get; set;
  49. }
  50. public bool IsConnected
  51. {
  52. get
  53. {
  54. return _connection != null && _connection.IsConnected;
  55. }
  56. }
  57. public bool Connect()
  58. {
  59. return true;
  60. }
  61. public bool Disconnect()
  62. {
  63. return true;
  64. }
  65. public EurothermP116(string module, string name, string scRoot) : base(module, name, name, name)
  66. {
  67. _scRoot = scRoot;
  68. _activeMonitorStatus = true;
  69. }
  70. ~EurothermP116()
  71. {
  72. _connection.Disconnect();
  73. }
  74. //public P116PIDTC(string module, string name, string scRoot) : base(module, name, name, name)
  75. //{
  76. // //tempCount = count;
  77. // _scRoot = scRoot;
  78. // _activeMonitorStatus = true;
  79. //}
  80. public void QueryTemp()
  81. {
  82. _lstHandler.AddLast(new P116PIDTCQueryHandler(this, "QueryPVInValue", 0x01, 0x00, 0x01, 0x00, 0x01));
  83. _lstHandler.AddLast(new P116PIDTCQueryHandler(this, "QueryTargetSP", 0x01, 0x00, 0x02, 0x00, 0x01));
  84. _lstHandler.AddLast(new P116PIDTCQueryHandler(this, "QueryAM", 0x01, 0x01, 0x11, 0x00, 0x01));
  85. }
  86. public void ResetDevice()
  87. {
  88. }
  89. public void QueryError()
  90. {
  91. EV.PostInfoLog(Module, "Query error");
  92. }
  93. public bool Initialize()
  94. {
  95. // string portName = SC.GetStringValue($"{_scRoot}.{Module}.{Name}.Address");
  96. string portName =SC.GetStringValue($"{Name}.Address");
  97. Address = portName;
  98. //int address = SC.GetValue<int>($"{_scRoot}.{Name}.DeviceAddress");
  99. moduleCount= SC.GetValue<int>($"{Name}.Modules");
  100. _enableLog = SC.GetValue<bool>($"{Name}.EnableLogMessage");
  101. _connection = new EurothermP116Connection(portName);
  102. _connection.EnableLog(_enableLog);
  103. _tempWarningMaxDiff = SC.GetValue<int>($"{Name}.TempWarnMaxDiff");
  104. //
  105. fPVInValue = fTargetSP = 0.0f;
  106. iAM = -1;
  107. int count = SC.ContainsItem("System.ComPortRetryCount") ? SC.GetValue<int>("System.ComPortRetryCount") : 5;
  108. int sleep = SC.ContainsItem("System.ComPortRetryDelayTime") ? SC.GetValue<int>("System.ComPortRetryDelayTime") : 2;
  109. if (sleep <= 0 || sleep > 10)
  110. sleep = 2;
  111. int retry = 0;
  112. do
  113. {
  114. _connection.Disconnect();
  115. Thread.Sleep(sleep * 1000);
  116. if (_connection.Connect())
  117. {
  118. EV.PostInfoLog(Module, $"{Name} connected");
  119. break;
  120. }
  121. if (count > 0 && retry++ > count)
  122. {
  123. LOG.Write($"Retry connect {Module}.{Name} stop retry.");
  124. EV.PostAlarmLog(Module, $"Can't connect to {Module}.{Name}.");
  125. break;
  126. }
  127. Thread.Sleep(sleep * 1000);
  128. LOG.Write($"Retry connect {Module}.{Name} for the {retry + 1} time.");
  129. } while (true);
  130. _thread = new PeriodicJob(200, OnTimer, $"{Module}.{Name} MonitorHandler", true);
  131. DATA.Subscribe($"{Module}.{Name}.PVInValue", () => fPVInValue);
  132. DATA.Subscribe($"{Module}.{Name}.TargetSP", () => fTargetSP) ;
  133. DATA.Subscribe($"{Module}.{Name}.AM", () => iAM);
  134. OP.Subscribe($"{Module}.{Name}.WritePVInValue", SetPVInValue);
  135. OP.Subscribe($"{Module}.{Name}.WriteTargetSP", SetTargetSP);
  136. OP.Subscribe($"{Module}.{Name}.WriteAM", SetAM); //0-Auto,1-Manual,2-Off
  137. ConnectionManager.Instance.Subscribe($"{Name}", this);
  138. return true;
  139. }
  140. public int _connecteTimes { get; set; }
  141. private bool OnTimer()
  142. {
  143. try
  144. {
  145. _connection.MonitorTimeout();
  146. if (!_connection.IsConnected || _connection.IsCommunicationError)
  147. {
  148. lock (_locker)
  149. {
  150. _lstHandler.Clear();
  151. }
  152. _trigRetryConnect.CLK = !_connection.IsConnected;
  153. if (_trigRetryConnect.Q)
  154. {
  155. //_connection.SetPortAddress(SC.GetStringValue($"{_scRoot}.{Name}.Address"));
  156. _connection.SetPortAddress(SC.GetStringValue($"{Name}.Address"));
  157. if (!_connection.Connect())
  158. {
  159. EV.PostAlarmLog(Module, $"Can not connect with {_connection.Address}, {Module}.{Name}");
  160. }
  161. }
  162. //if (_trigRetryConnect.CLK)
  163. //{
  164. // if (!_connection.Connect())
  165. // {
  166. // if (_trigRetryConnect.Q)
  167. // {
  168. // EV.PostAlarmLog(Module, $"Can not connect with {_connection.Address}, {Module}.{Name}");
  169. // }
  170. // }
  171. // else
  172. // {
  173. // EV.PostAlarmLog(Module, $"Retry connect succee with {_connection.Address}, {Module}.{Name}");
  174. // _trigRetryConnect.CLK = false;
  175. // }
  176. // Thread.Sleep(3000);
  177. //}
  178. if (_connecteTimes++ < 3)
  179. _connection.ForceClear();
  180. else _connecteTimes= 4;
  181. return true;
  182. }
  183. HandlerBase handler = null;
  184. //if (!_connection.IsBusy)
  185. //{
  186. lock (_locker)
  187. {
  188. if (_lstHandler.Count == 0 && !IsConfig)
  189. QueryTemp();
  190. if (_lstHandler.Count > 0 && !_connection.IsBusy)
  191. {
  192. handler = _lstHandler.First.Value;
  193. _lstHandler.RemoveFirst();
  194. if (handler != null)
  195. {
  196. _connection.Execute(handler);
  197. }
  198. }
  199. }
  200. }
  201. catch (Exception ex)
  202. {
  203. LOG.Write(ex);
  204. }
  205. return true;
  206. }
  207. internal void NoteError()
  208. {
  209. }
  210. public void Monitor()
  211. {
  212. try
  213. {
  214. _connection.EnableLog(_enableLog);
  215. if (_connecteTimes < 4) return;
  216. _trigCommunicationError.CLK = _connection.IsCommunicationError;
  217. if (_trigCommunicationError.Q)
  218. {
  219. //for (int i = 0; i < 12; i++)
  220. //{
  221. // ActualTemp[i] = 0;
  222. // SettingTemp[i] = 0;
  223. //}
  224. fPVInValue = 0f;
  225. fTargetSP = 0f;
  226. iAM = -1;
  227. EV.PostAlarmLog(Module, $"{Module}.{Name} communication error, {_connection.LastCommunicationError}");
  228. }
  229. //MonitorWarning();
  230. }
  231. catch (Exception ex)
  232. {
  233. LOG.Write(ex);
  234. }
  235. }
  236. //private void MonitorWarning()
  237. //{
  238. // for (int i = 0; i < 12; i++)
  239. // {
  240. // TempWarningTrig[i].CLK = SettingTemp[i] > 0 && _tempWarningMaxDiff > 0 && Math.Abs(ActualTemp[i] - SettingTemp[i]) > _tempWarningMaxDiff;
  241. // if (TempWarningTrig[i].Q)
  242. // {
  243. // EV.PostWarningLog(Module, $"{WarningInfo[i]},the difference between the actual value and the set value is too large");
  244. // }
  245. // }
  246. //}
  247. public bool IsConfig { get; set; }
  248. public bool SetPVInValue(string cmd, object [] obj)//设置单个地址 0x0001
  249. {
  250. IsConfig = true;
  251. _lstHandler.Clear();
  252. lock (_locker)
  253. {
  254. if (obj.Length > 0)
  255. {
  256. byte DeviceAddress = 0x01;
  257. int adress = 0x0001;
  258. byte addressH = Convert.ToByte((adress >> 8) & 0xff); ;
  259. byte addressL = Convert.ToByte(adress & 0xff);
  260. //var floatdata = Convert.ToSingle(objs[1]) * 10;
  261. //var data = Convert.ToInt16(floatdata);
  262. var data = Convert.ToInt16(obj[0]);
  263. byte dataH = Convert.ToByte((data >> 8) & 0xff);
  264. byte dataL = Convert.ToByte(data & 0xff);
  265. _lstHandler.AddLast(new P116PIDTCWriteSingleHandler(this, "WritePVInValue", DeviceAddress, addressH, addressL, dataH, dataL));
  266. }
  267. }
  268. return true;
  269. }
  270. public bool SetTargetSP(string cmd, object[] obj)//设置单个地址 0x0002
  271. {
  272. IsConfig = true;
  273. _lstHandler.Clear();
  274. lock (_locker)
  275. {
  276. if (obj.Length > 0)
  277. {
  278. byte DeviceAddress = 0x01;
  279. int adress = 0x0002;
  280. byte addressH = Convert.ToByte((adress >> 8) & 0xff); ;
  281. byte addressL = Convert.ToByte(adress & 0xff);
  282. var data = Convert.ToInt16(obj[0]) * 10;//10倍值
  283. byte dataH = Convert.ToByte((data >> 8) & 0xff);
  284. byte dataL = Convert.ToByte(data & 0xff);
  285. _lstHandler.AddLast(new P116PIDTCWriteSingleHandler(this, "WriteTargetSP", DeviceAddress, addressH, addressL, dataH, dataL));
  286. }
  287. }
  288. return true;
  289. }
  290. public bool SetAM(string cmd, object[] obj)//设置单个地址 0x0111 = 273
  291. {
  292. IsConfig = true;
  293. _lstHandler.Clear();
  294. lock (_locker)
  295. {
  296. if (obj.Length > 0)
  297. {
  298. byte DeviceAddress = 0x01;
  299. int adress = 0x0111;
  300. byte addressH = Convert.ToByte((adress >> 8) & 0xff); ;
  301. byte addressL = Convert.ToByte(adress & 0xff);
  302. var data = Convert.ToInt16(obj[0]);
  303. if (data == 0)
  304. {
  305. //开启自动
  306. byte dataH = Convert.ToByte((data >> 8) & 0xff);
  307. byte dataL = Convert.ToByte(data & 0xff);
  308. _lstHandler.AddLast(new P116PIDTCWriteSingleHandler(this, "WriteAM", DeviceAddress, addressH, addressL, dataH, dataL));
  309. }
  310. else if(data == 2)
  311. {
  312. //关闭输出
  313. //A-M:address 273
  314. data = 0x1;
  315. byte dataH = Convert.ToByte((data >> 8) & 0xff);
  316. byte dataL = Convert.ToByte(data & 0xff);
  317. _lstHandler.AddLast(new P116PIDTCWriteSingleHandler(this, "WriteAM", DeviceAddress, addressH, addressL, dataH, dataL));
  318. //OP: address 3
  319. adress = 0x0003;
  320. addressH = Convert.ToByte((adress >> 8) & 0xff); ;
  321. addressL = Convert.ToByte(adress & 0xff);
  322. data = 0x0;
  323. dataH = Convert.ToByte((data >> 8) & 0xff);
  324. dataL = Convert.ToByte(data & 0xff);
  325. _lstHandler.AddLast(new P116PIDTCWriteSingleHandler(this, "WriteAM", DeviceAddress, addressH, addressL, dataH, dataL));
  326. }
  327. else
  328. {
  329. EV.PostWarningLog(Module, "Find wrong parameter when writing AM.");
  330. }
  331. }
  332. }
  333. return true;
  334. }
  335. public void Reset()
  336. {
  337. _connecteTimes = 0;
  338. _connection.SetCommunicationError(false, "");
  339. _trigCommunicationError.RST = true;
  340. _enableLog = SC.GetValue<bool>($"{Name}.EnableLogMessage");
  341. _trigRetryConnect.RST = true;
  342. //for (int i = 0; i < 12; i++)
  343. //{
  344. // TempWarningTrig[i].RST = true;
  345. //}
  346. }
  347. public void RespondAbnormal(int funcode, int abnormalcode)
  348. {
  349. if (funcode == 0x83)
  350. {
  351. foreach (var code in AbnormalCode)
  352. {
  353. if (code.Key == abnormalcode)
  354. EV.PostWarningLog(Name, $"Query Abnormal:{code.Value}");
  355. }
  356. }
  357. if (funcode == 0x90 || funcode == 0x86)
  358. {
  359. foreach (var code in AbnormalCode)
  360. {
  361. if (code.Key == abnormalcode)
  362. EV.PostWarningLog(Name, $"Write Abnormal:{code.Value}");
  363. }
  364. }
  365. }
  366. public Dictionary<int, string> AbnormalCode = new Dictionary<int, string>()
  367. {
  368. { 1,"ncorrect function code, this machine does not correspond to the function code." },
  369. { 2,"Incorrect data address" },
  370. { 3,"Incorrect data." },
  371. { 4,"operation error" },
  372. };
  373. public void SetActiveMonitor(bool active)
  374. {
  375. _activeMonitorStatus = active;
  376. }
  377. public void SetErrorCode(int errorCode)
  378. {
  379. _errorCode = errorCode;
  380. }
  381. public void Terminate()
  382. {
  383. _connection.Disconnect();
  384. }
  385. //public Dictionary<string, AdressInfo> _dicAdressInfo = new Dictionary<string, AdressInfo>()//配置最多32个数据
  386. //{
  387. // {"WritePVInValue", new AdressInfo() { DeviceAddress=0x01, UnitAddress = 0x0001,Length = 1 } },//手册 8-7
  388. // {"WriteTargetSP", new AdressInfo() { DeviceAddress=0x01, UnitAddress = 0x0002,Length = 1 } },
  389. //};
  390. }
  391. }