OsakaPumpTGkine.cs 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586
  1. using Aitex.Core.Common.DeviceData;
  2. using Aitex.Core.RT.DataCenter;
  3. using Aitex.Core.RT.Event;
  4. using Aitex.Core.RT.Log;
  5. using Aitex.Core.RT.OperationCenter;
  6. using Aitex.Core.RT.SCCore;
  7. using Aitex.Core.Util;
  8. using MECF.Framework.Common.Communications;
  9. using MECF.Framework.Common.Device.Bases;
  10. using System;
  11. using System.Collections.Generic;
  12. using System.Diagnostics;
  13. using System.IO.Ports;
  14. namespace MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Pumps.OsakaPumpTGkine
  15. {
  16. public class HighLevelReader
  17. {
  18. public OsakaPumpTGkineLowerWriteHandler IndexWriter { get; set; }
  19. public OsakaPumpTGkineLowerWriteHandler CommandWriter { get; set; }
  20. public OsakaPumpTGkineLowerReadHandler CommandReader { get; set; }
  21. public OsakaPumpTGkineLowerReadHandler ValueReader { get; set; }
  22. public bool IsActive { get; set; }
  23. public OsakaPumpTGkineHandler ActiveHandler { get; set; }
  24. private OsakaPumpTGkine _device;
  25. private byte _indexNumberLow;
  26. private Stopwatch _timer = new Stopwatch();
  27. public void Reset(OsakaPumpTGkine device, byte indexNumberHigh, byte indexNumberLow)
  28. {
  29. IndexWriter = new OsakaPumpTGkineLowerWriteHandler(device, 0x80, 0x80, indexNumberHigh, indexNumberLow);
  30. CommandWriter = new OsakaPumpTGkineLowerWriteHandler(device, 0x80, 0x81, 0x00, 0x55);
  31. CommandReader = new OsakaPumpTGkineLowerReadHandler(device, 0x80, 0x81);
  32. ValueReader = new OsakaPumpTGkineLowerReadHandler(device, 0x80, 0x82);
  33. ActiveHandler = IndexWriter;
  34. _device = device;
  35. _indexNumberLow = indexNumberLow;
  36. IsActive = true;
  37. }
  38. public void Clear()
  39. {
  40. IsActive = false;
  41. IndexWriter = null;
  42. CommandWriter = null;
  43. CommandReader = null;
  44. ValueReader = null;
  45. _device = null;
  46. _indexNumberLow = 0;
  47. }
  48. public void ReadDone()
  49. {
  50. if (!IsActive)
  51. return;
  52. if (ActiveHandler == CommandReader)
  53. {
  54. ActiveHandler = ValueReader;
  55. return;
  56. }
  57. if (ActiveHandler == ValueReader)
  58. {
  59. _device.NoteReadResult(_indexNumberLow, ValueReader.ResultHigh, ValueReader.ResultLow);
  60. Clear();
  61. return;
  62. }
  63. }
  64. public void WriteDone()
  65. {
  66. if (!IsActive)
  67. return;
  68. if (ActiveHandler == IndexWriter)
  69. {
  70. ActiveHandler = CommandWriter;
  71. return;
  72. }
  73. if (ActiveHandler == CommandWriter)
  74. {
  75. ActiveHandler = CommandReader;
  76. return;
  77. }
  78. }
  79. }
  80. public class HighLevelWriter
  81. {
  82. public OsakaPumpTGkineLowerWriteHandler IndexWriter { get; set; }
  83. public OsakaPumpTGkineLowerWriteHandler ValueWriter { get; set; }
  84. public OsakaPumpTGkineLowerWriteHandler CommandWriter { get; set; }
  85. public OsakaPumpTGkineLowerReadHandler CommandReader { get; set; }
  86. public bool IsActive { get; set; }
  87. public OsakaPumpTGkineHandler ActiveHandler { get; set; }
  88. private OsakaPumpTGkine _device;
  89. private byte _indexNumberLow;
  90. private byte _valueHigh;
  91. private byte _valueLow;
  92. private Stopwatch _timer = new Stopwatch();
  93. public void Reset(OsakaPumpTGkine device, byte indexNumberHigh, byte indexNumberLow, byte valueHigh, byte valueLow)
  94. {
  95. IndexWriter = new OsakaPumpTGkineLowerWriteHandler(device, 0x80, 0x80, indexNumberHigh, indexNumberLow);
  96. ValueWriter = new OsakaPumpTGkineLowerWriteHandler(device, 0x80, 0x82, valueHigh, valueLow);
  97. CommandWriter = new OsakaPumpTGkineLowerWriteHandler(device, 0x80, 0x81, 0x00, 0xAA);
  98. CommandReader = new OsakaPumpTGkineLowerReadHandler(device, 0x80, 0x81);
  99. ActiveHandler = IndexWriter;
  100. _device = device;
  101. _indexNumberLow = indexNumberLow;
  102. _valueHigh = valueHigh;
  103. _valueLow = valueLow;
  104. IsActive = true;
  105. }
  106. public void Clear()
  107. {
  108. IsActive = false;
  109. IndexWriter = null;
  110. CommandWriter = null;
  111. CommandReader = null;
  112. ValueWriter = null;
  113. _device = null;
  114. _indexNumberLow = 0;
  115. _valueHigh = 0;
  116. _valueLow = 0;
  117. }
  118. public void ReadDone()
  119. {
  120. if (!IsActive)
  121. return;
  122. if (ActiveHandler == CommandReader)
  123. {
  124. Clear();
  125. return;
  126. }
  127. }
  128. public void WriteDone()
  129. {
  130. if (!IsActive)
  131. return;
  132. if (ActiveHandler == IndexWriter)
  133. {
  134. ActiveHandler = ValueWriter;
  135. return;
  136. }
  137. if (ActiveHandler == ValueWriter)
  138. {
  139. ActiveHandler = CommandWriter;
  140. return;
  141. }
  142. if (ActiveHandler == CommandWriter)
  143. {
  144. ActiveHandler = CommandReader;
  145. return;
  146. }
  147. }
  148. }
  149. public class OsakaPumpTGkine : PumpBase, IConnection
  150. {
  151. public string Address { get { return _address; } }
  152. public bool IsConnected => Connection != null && Connection.IsConnected && !_connection.IsCommunicationError;
  153. public bool Connect()
  154. {
  155. return true;
  156. }
  157. public bool Disconnect()
  158. {
  159. return true;
  160. }
  161. public string PortStatus { get; set; } = "Closed";
  162. private OsakaPumpTGkineConnection _connection;
  163. public OsakaPumpTGkineConnection Connection
  164. {
  165. get { return _connection; }
  166. }
  167. public override bool IsStable
  168. {
  169. get { return IsAtTargetSpeed && !IsBrake; }
  170. }
  171. public override AITPumpData DeviceData
  172. {
  173. get
  174. {
  175. AITPumpData data = new AITPumpData()
  176. {
  177. DeviceName = Name,
  178. DeviceSchematicId = DeviceID,
  179. DisplayName = Display,
  180. DeviceModule = Module,
  181. IsError = IsFailure || IsAlarm,
  182. IsOn = IsAtTargetSpeed,
  183. Speed = (int)Speed,
  184. };
  185. return data;
  186. }
  187. }
  188. public bool IsRemoteControl { get; private set; }
  189. public bool IsRunning { get; private set; }
  190. public bool IsFailure { get; private set; }
  191. public bool IsAlarm { get; private set; }
  192. public bool IsAtTargetSpeed { get; private set; }
  193. public bool IsAtRatedSpeed { get; private set; }
  194. public bool IsAtLowSpeed { get; private set; }
  195. public bool IsNotRotation { get; private set; }
  196. public bool IsBrake { get; private set; }
  197. public bool IsAccelerate { get; private set; }
  198. private R_TRIG _trigError = new R_TRIG();
  199. private R_TRIG _trigCommunicationError = new R_TRIG();
  200. private R_TRIG _trigRetryConnect = new R_TRIG();
  201. private PeriodicJob _thread;
  202. private object _locker = new object();
  203. private bool _enableLog;
  204. private string _address;
  205. private string _scRoot;
  206. private R_TRIG _trigWarningMessage = new R_TRIG();
  207. private HighLevelReader _reader = new HighLevelReader();
  208. private HighLevelWriter _writer = new HighLevelWriter();
  209. private FixSizeQueue<byte> _readIndexNumber = new FixSizeQueue<byte>(10);
  210. private FixSizeQueue<Tuple<byte, byte, byte>> _writeIndexNumber = new FixSizeQueue<Tuple<byte, byte, byte>>(10);
  211. private Stopwatch _readSpeedTimer = new Stopwatch();
  212. public OsakaPumpTGkine(string module, string name, string scRoot) : base(module, name)
  213. {
  214. _scRoot = scRoot;
  215. }
  216. public override bool Initialize()
  217. {
  218. base.Initialize();
  219. if (_connection != null && _connection.IsConnected)
  220. return true;
  221. if (_connection != null && _connection.IsConnected)
  222. _connection.Disconnect();
  223. _address = SC.GetStringValue($"{_scRoot}.Address");
  224. _enableLog = SC.GetValue<bool>($"{_scRoot}.EnableLogMessage");
  225. _connection = new OsakaPumpTGkineConnection(_address);
  226. _connection.EnableLog(_enableLog);
  227. if (_connection.Connect())
  228. {
  229. PortStatus = "Open";
  230. EV.PostInfoLog(Module, $"{Module}.{Name} connected");
  231. }
  232. DATA.Subscribe($"{Module}.{Name}.IsConnected", () => IsConnected);
  233. DATA.Subscribe($"{Module}.{Name}.Address", () => Address);
  234. OP.Subscribe($"{Module}.{Name}.Reconnect", (string cmd, object[] args) =>
  235. {
  236. Disconnect();
  237. Reset();
  238. Connect();
  239. return true;
  240. });
  241. _thread = new PeriodicJob(100, OnTimer, $"{Module}.{Name} MonitorHandler", true);
  242. _readSpeedTimer.Start();
  243. return true;
  244. }
  245. public bool Initialize(string portName, int baudRate = 9600, int dataBits = 8, Parity parity = Parity.None, StopBits stopBits = StopBits.One)
  246. {
  247. base.Initialize();
  248. //_address = SC.GetStringValue($"{(!string.IsNullOrEmpty(_scRoot) ? _scRoot + "." : "")}{Module}.{Name}.Address");
  249. _enableLog = true;// SC.GetValue<bool>($"{(!string.IsNullOrEmpty(_scRoot) ? _scRoot + "." : "")}{Module}.{Name}.EnableLogMessage");
  250. _connection = new OsakaPumpTGkineConnection(portName, baudRate, dataBits, parity, stopBits);
  251. _connection.EnableLog(_enableLog);
  252. if (_connection.Connect())
  253. {
  254. PortStatus = "Open";
  255. EV.PostInfoLog(Module, $"{Module}.{Name} connected");
  256. }
  257. _thread = new PeriodicJob(2000, OnTimer, $"{Module}.{Name} MonitorHandler", true);
  258. return true;
  259. }
  260. private bool OnTimer()
  261. {
  262. try
  263. {
  264. _connection.MonitorTimeout();
  265. if (!_connection.IsConnected || _connection.IsCommunicationError)
  266. {
  267. _trigRetryConnect.CLK = !_connection.IsConnected;
  268. if (_trigRetryConnect.Q)
  269. {
  270. _connection.SetPortAddress(SC.GetStringValue($"{_scRoot}.Address"));
  271. if (!_connection.Connect())
  272. {
  273. EV.PostAlarmLog(Module, $"Can not connect with {_connection.Address}, {Module}.{Name}");
  274. }
  275. else
  276. {
  277. //_lstHandler.AddLast(new OsakaPumpTGkineQueryPinHandler(this, _deviceAddress));
  278. //_lstHandler.AddLast(new OsakaPumpTGkineSetCommModeHandler(this, _deviceAddress, EnumRfPowerCommunicationMode.Host));
  279. }
  280. }
  281. return true;
  282. }
  283. HandlerBase handler = null;
  284. if (!_connection.IsBusy)
  285. {
  286. lock (_locker)
  287. {
  288. if (_writer.IsActive)
  289. {
  290. handler = _writer.ActiveHandler;
  291. }
  292. else if (_reader.IsActive)
  293. {
  294. handler = _reader.ActiveHandler;
  295. }
  296. else if (_writeIndexNumber.TryDequeue(out var writeTask))
  297. {
  298. _writer.Reset(this, 0x00, writeTask.Item1, writeTask.Item2, writeTask.Item3);
  299. handler = _writer.ActiveHandler;
  300. }
  301. else if (_readIndexNumber.TryDequeue(out var readTask))
  302. {
  303. _reader.Reset(this, 0x00, readTask);
  304. handler = _reader.ActiveHandler;
  305. }
  306. if (handler == null)
  307. {
  308. if (_readSpeedTimer.ElapsedMilliseconds > 1000)
  309. {
  310. _readSpeedTimer.Restart();
  311. ReadPumpSpeed();
  312. }
  313. else
  314. {
  315. ReadPumpStatus();
  316. }
  317. }
  318. }
  319. if (handler != null)
  320. {
  321. _connection.Execute(handler);
  322. }
  323. }
  324. }
  325. catch (Exception ex)
  326. {
  327. LOG.Write(ex);
  328. }
  329. return true;
  330. }
  331. internal void NoteLowerWriteDone()
  332. {
  333. _reader.WriteDone();
  334. _writer.WriteDone();
  335. }
  336. internal void NoteLowerReadDone()
  337. {
  338. _reader.ReadDone();
  339. _writer.ReadDone();
  340. }
  341. internal void NoteReadResult(byte indexNumberLow, byte valueHigh, byte valueLow)
  342. {
  343. if (indexNumberLow == 0x40)
  344. {
  345. if (valueHigh == 0x01 && valueLow == 0x20)//准备就绪
  346. {
  347. IsRunning = true;
  348. IsAtTargetSpeed = false;
  349. IsNotRotation = true;
  350. }
  351. else if (valueHigh == 0x03 && valueLow == 0x80) //加速中
  352. {
  353. IsRunning = true;
  354. IsAccelerate = true;
  355. }
  356. else if (valueHigh == 0x63 && valueLow == 0x00)//额定转速中
  357. {
  358. IsRunning = true;
  359. IsAtTargetSpeed = true;
  360. IsAtRatedSpeed = true;
  361. }
  362. else if (valueHigh == 0x01 && valueLow == 0x40)//减速中
  363. {
  364. IsRunning = true;
  365. IsBrake = true;
  366. }
  367. else if (valueHigh == 0x05 && valueLow == 0x40) //减速中且报警
  368. {
  369. IsBrake = true;
  370. IsFailure = true;
  371. IsAlarm = true;
  372. }
  373. else if (valueHigh == 0x05 && valueLow == 0x02)//未旋转且报警
  374. {
  375. IsNotRotation = true;
  376. IsFailure = true;
  377. IsAlarm = true;
  378. }
  379. else if (valueHigh == 0x05 && valueLow == 0x00) //自由转动且报警
  380. {
  381. IsFailure = true;
  382. IsAlarm = true;
  383. }
  384. else
  385. {
  386. IsRunning = false;
  387. IsFailure = false;
  388. IsAlarm = false;
  389. IsAtTargetSpeed = false;
  390. IsAtRatedSpeed = false;
  391. IsAtLowSpeed = false;
  392. IsNotRotation = false;
  393. IsBrake = false;
  394. IsAccelerate = false;
  395. }
  396. }
  397. if (indexNumberLow == 0x01)
  398. {
  399. Speed = ((valueHigh << 8) + (valueLow & 0xFFFF)) * 60;
  400. }
  401. if (indexNumberLow == 0x12)
  402. {
  403. Temperature = (float)(((valueHigh << 8) + (valueLow & 0xFFFF)) / 10.0);
  404. }
  405. }
  406. internal void NoteWrite()
  407. {
  408. }
  409. public override void Monitor()
  410. {
  411. try
  412. {
  413. //_connection.EnableLog(_enableLog);
  414. _trigCommunicationError.CLK = _connection.IsCommunicationError;
  415. if (_trigCommunicationError.Q)
  416. {
  417. EV.PostAlarmLog(Module, $"{Module}.{Name} communication error, {_connection.LastCommunicationError}");
  418. }
  419. }
  420. catch (Exception ex)
  421. {
  422. LOG.Write(ex);
  423. }
  424. }
  425. public override void SetPumpOnOff(bool isOn)
  426. {
  427. byte valueHigh = 0;
  428. byte valueLow = 0;
  429. valueHigh = Converter.SetBit(valueHigh, 1, true);
  430. _writeIndexNumber.Enqueue(Tuple.Create(isOn ? (byte)0x08 : (byte)0x09, valueHigh, valueLow));
  431. }
  432. public override void Reset()
  433. {
  434. _trigError.RST = true;
  435. _connection.SetCommunicationError(false, "");
  436. _trigCommunicationError.RST = true;
  437. _enableLog = SC.GetValue<bool>($"{_scRoot}.EnableLogMessage");
  438. _trigRetryConnect.RST = true;
  439. base.Reset();
  440. }
  441. public void ReadPumpStatus()
  442. {
  443. _readIndexNumber.Enqueue(0x40);
  444. }
  445. public void ReadPumpSpeed()
  446. {
  447. _readIndexNumber.Enqueue(0x01);
  448. }
  449. public void ReadPumpMotorTemp()
  450. {
  451. _readIndexNumber.Enqueue(0x12);
  452. }
  453. public void ReadPumpErrorCode()
  454. {
  455. _readIndexNumber.Enqueue(0x17);
  456. }
  457. public void NoteError(string reason)
  458. {
  459. if (reason != null)
  460. {
  461. _trigWarningMessage.CLK = true;
  462. if (_trigWarningMessage.Q)
  463. {
  464. EV.PostWarningLog(Module, $"{Module}.{Name} error, {reason}");
  465. }
  466. }
  467. else
  468. {
  469. }
  470. }
  471. }
  472. }