SuperMCProtocalPLC.cs 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880
  1. using Aitex.Core.RT.DataCenter;
  2. using Aitex.Core.RT.Device;
  3. using Aitex.Core.RT.Event;
  4. using Aitex.Core.RT.Log;
  5. using Aitex.Core.RT.OperationCenter;
  6. using Aitex.Core.Util;
  7. using MECF.Framework.Common.Communications;
  8. using MECF.Framework.RT.Core.IoProviders;
  9. using MECF.Framework.RT.Core.IoProviders.Mitsubishis;
  10. using System;
  11. using System.Collections;
  12. using System.Collections.Generic;
  13. using System.Diagnostics;
  14. using System.Linq;
  15. using System.Net;
  16. using System.Net.Sockets;
  17. using System.Runtime.InteropServices;
  18. using System.Text;
  19. using System.Threading;
  20. using System.Threading.Tasks;
  21. using System.Xml;
  22. namespace EFEMRT.Devices
  23. {
  24. public class SuperMCProtocolPLC : IoProvider
  25. {
  26. private string _ip = "127.0.0.1";
  27. private string _localIp = "127.0.0.1";
  28. private int _port = 6731;
  29. private int _socketId = 101;
  30. private int _stationId = 102;
  31. private byte[] _bufferIn;
  32. private byte[] _bufferOut;
  33. private MCProtocol.MC_COMMAND_HEADER _header;
  34. //private MCProtocol.MC_RESPONSE_HEADER _response;
  35. private MCProtocol.MC_BATCH_COMMAND _batchCommand;
  36. private MCSocket _socket;
  37. private int demandAiFrom; //should be the same the offset in lstBuffers
  38. private int demandAiSize;
  39. private int demandAoFrom; //should be the same the offset in lstBuffers
  40. private int demandAoSize;
  41. private bool inDemanding = false;
  42. private string aiStoragename = "R";
  43. private string aoStoragename = "R";
  44. private string diStoragename = "M";
  45. private string doStoragename = "M";
  46. private int perIoLength = 960;
  47. private int diStartOffset=0;
  48. private int doStartOffset=0;
  49. private int aiStartOffset=0;
  50. private int aoStartOffset=0;
  51. private Stopwatch stopwatchDi = new Stopwatch();
  52. private Stopwatch stopwatchDo = new Stopwatch();
  53. private Stopwatch stopwatchAi = new Stopwatch();
  54. private Stopwatch stopwatchAo = new Stopwatch();
  55. private int comunicationSpanDi;
  56. private int comunicationSpanDo;
  57. private int comunicationSpanAi;
  58. private int comunicationSpanAo;
  59. protected int comunicationSpanTotal;
  60. private Stopwatch stopwatchTotal = new Stopwatch();
  61. private List<IoBlockItem> _blockSectionsDemand;
  62. public override void Initialize(string module, string name, List<IoBlockItem> lstBuffers, IIoBuffer buffer, XmlElement nodeParameter, Dictionary<int, string> ioMappingPathFile)
  63. {
  64. Module = module;
  65. Name = name;
  66. _source = module + "." + name;
  67. _buffer = buffer;
  68. _nodeParameter = nodeParameter;
  69. _blockSections = lstBuffers;
  70. buffer.SetBufferBlock(_source, lstBuffers);
  71. buffer.SetIoMap(_source, ioMappingPathFile);
  72. SetParameter(nodeParameter);
  73. State = IoProviderStateEnum.Uninitialized;
  74. _thread = new PeriodicJob(50, OnTimer, name);
  75. //Module = module;
  76. //Name = name;
  77. //_source = module + "." + name;
  78. //_buffer = buffer;
  79. //_nodeParameter = nodeParameter;
  80. //SetParameter(nodeParameter);
  81. //if (demandAiSize != 0 || demandAoSize != 0)
  82. //{
  83. // var lstBuffersnew = new List<IoBlockItem>();
  84. // foreach (var bf in lstBuffers)
  85. // {
  86. // if (demandAiSize > 0 && bf.Type == IoType.AI)
  87. // {
  88. // var bfNew = new IoBlockItem()
  89. // {
  90. // Offset = demandAiFrom + demandAiSize,
  91. // Size = bf.Size - demandAiSize,
  92. // Type = bf.Type,
  93. // };
  94. // lstBuffersnew.Add(bfNew);
  95. // }
  96. // else if (demandAoSize > 0 && bf.Type == IoType.AO)
  97. // {
  98. // var bfNew = new IoBlockItem()
  99. // {
  100. // Offset = demandAoFrom + demandAoSize,
  101. // Size = bf.Size - demandAoSize,
  102. // Type = bf.Type,
  103. // };
  104. // lstBuffersnew.Add(bfNew);
  105. // }
  106. // else
  107. // lstBuffersnew.Add(bf);
  108. // }
  109. // _blockSectionsDemand = lstBuffersnew;
  110. //}
  111. //_blockSections = lstBuffers;
  112. //buffer.SetBufferBlock(_source, lstBuffers);
  113. //buffer.SetIoMap(_source, ioMappingPathFile);
  114. //State = IoProviderStateEnum.Uninitialized;
  115. //_thread = new PeriodicJob(50, OnTimer, name);
  116. //DATA.Subscribe($"{Name}.ComunicationSpanTotal", () => comunicationSpanTotal);
  117. //DATA.Subscribe($"{Name}.ComunicationSpanDi", () => comunicationSpanDi);
  118. //DATA.Subscribe($"{Name}.ComunicationSpanDo", () => comunicationSpanDo);
  119. //DATA.Subscribe($"{Name}.ComunicationSpanAi", () => comunicationSpanAi);
  120. //DATA.Subscribe($"{Name}.ComunicationSpanAo", () => comunicationSpanAo);
  121. }
  122. protected override bool OnTimer()
  123. {
  124. if (State == IoProviderStateEnum.Uninitialized)
  125. {
  126. SetState(IoProviderStateEnum.Opening);
  127. Open();
  128. }
  129. if (State == IoProviderStateEnum.Opened)
  130. {
  131. try
  132. {
  133. stopwatchTotal.Start();
  134. foreach (var bufferSection in _blockSections)
  135. {
  136. if (bufferSection.Type == IoType.DI)
  137. {
  138. stopwatchDi.Start();
  139. bool[] diBuffer = ReadDi(bufferSection.Offset, bufferSection.Size);
  140. if (diBuffer != null)
  141. {
  142. _buffer.SetDiBuffer(_source, bufferSection.Offset, diBuffer);
  143. //TraceArray(diBuffer);
  144. }
  145. stopwatchDi.Stop();
  146. }
  147. else if (bufferSection.Type == IoType.AI)
  148. {
  149. stopwatchAi.Start();
  150. if (inDemanding)
  151. {
  152. short[] aiBuffer = ReadAi(bufferSection.Offset, bufferSection.Size);
  153. if (aiBuffer != null)
  154. {
  155. _buffer.SetAiBuffer(_source, bufferSection.Offset, aiBuffer);
  156. }
  157. }
  158. else
  159. {
  160. if (_blockSectionsDemand != null)
  161. {
  162. var section = _blockSectionsDemand.Find(x => x.Type == IoType.AI);
  163. if (section != null && demandAiSize > 0)
  164. {
  165. short[] aiBuffer = ReadAi(section.Offset, section.Size);
  166. if (aiBuffer != null)
  167. {
  168. _buffer.SetAiBuffer(_source, demandAiFrom, aiBuffer, demandAiSize);
  169. }
  170. }
  171. }
  172. else
  173. {
  174. short[] aiBuffer = ReadAi(bufferSection.Offset, bufferSection.Size);
  175. if (aiBuffer != null)
  176. {
  177. _buffer.SetAiBuffer(_source, bufferSection.Offset, aiBuffer);
  178. }
  179. }
  180. }
  181. stopwatchAi.Stop();
  182. }
  183. }
  184. comunicationSpanDi = (int)stopwatchDi.ElapsedMilliseconds;
  185. stopwatchDi.Reset();
  186. comunicationSpanAi = (int)stopwatchAi.ElapsedMilliseconds;
  187. stopwatchAi.Reset();
  188. stopwatchAo.Start();
  189. Dictionary<int, short[]> aos = _buffer.GetAoBuffer(_source);
  190. if (aos != null)
  191. {
  192. if (inDemanding)
  193. {
  194. if (demandAoSize > 0)
  195. {
  196. foreach (var ao in aos)
  197. {
  198. WriteAo(ao.Key, ao.Value);
  199. }
  200. }
  201. }
  202. else
  203. {
  204. foreach (var ao in aos)
  205. {
  206. if (ao.Key == demandAoFrom)
  207. {
  208. short[] data = new short[ao.Value.Length - demandAoSize];
  209. Array.Copy(ao.Value, demandAoSize, data, 0, data.Length);
  210. WriteAo(demandAoFrom + demandAoSize, data);
  211. }
  212. else
  213. WriteAo(ao.Key, ao.Value);
  214. }
  215. }
  216. }
  217. stopwatchAo.Stop();
  218. comunicationSpanAo = (int)stopwatchAo.ElapsedMilliseconds;
  219. stopwatchAo.Reset();
  220. stopwatchDo.Start();
  221. Dictionary<int, bool[]> dos = _buffer.GetDoBuffer(_source);
  222. if (dos != null)
  223. {
  224. foreach (var doo in dos)
  225. {
  226. WriteDo(doo.Key, doo.Value);
  227. }
  228. }
  229. stopwatchDo.Stop();
  230. comunicationSpanDo = (int)stopwatchDo.ElapsedMilliseconds;
  231. stopwatchDo.Reset();
  232. stopwatchTotal.Stop();
  233. comunicationSpanTotal = (int)stopwatchTotal.ElapsedMilliseconds;
  234. stopwatchTotal.Reset();
  235. }
  236. catch (Exception ex)
  237. {
  238. LOG.Write($"{Name} {ex}");
  239. //SetState(IoProviderStateEnum.Error);
  240. Thread.Sleep(1000);
  241. Close();
  242. Open();
  243. }
  244. }
  245. _trigError.CLK = State == IoProviderStateEnum.Error;
  246. if (_trigError.Q)
  247. {
  248. EV.PostMessage(Module, EventEnum.DefaultAlarm, string.Format("{0} error", _source));
  249. }
  250. return true;
  251. }
  252. protected override void SetParameter(XmlElement nodeParameter)
  253. {
  254. string strIp = nodeParameter.GetAttribute("ip");
  255. _localIp = nodeParameter.GetAttribute("localIp");
  256. string strPort = nodeParameter.GetAttribute("port");
  257. string networkId = nodeParameter.GetAttribute("network_id");
  258. string stationId = nodeParameter.GetAttribute("station_id");
  259. aiStoragename = nodeParameter.GetAttribute("aiStoragename");
  260. aoStoragename = nodeParameter.GetAttribute("aoStoragename");
  261. diStoragename = nodeParameter.GetAttribute("diStoragename");
  262. doStoragename = nodeParameter.GetAttribute("doStoragename");
  263. int.TryParse(nodeParameter.GetAttribute("perIoLength"), out perIoLength);
  264. perIoLength = perIoLength == 0 ? 960 : perIoLength;
  265. int.TryParse(nodeParameter.GetAttribute("demandAiFrom"), out demandAiFrom);
  266. int.TryParse(nodeParameter.GetAttribute("demandAiSize"), out demandAiSize);
  267. int.TryParse(nodeParameter.GetAttribute("demandAoFrom"), out demandAoFrom);
  268. int.TryParse(nodeParameter.GetAttribute("demandAoSize"), out demandAoSize);
  269. if (nodeParameter.HasAttribute("diStartOffset"))
  270. int.TryParse(nodeParameter.GetAttribute("diStartOffset"), out diStartOffset);
  271. if (nodeParameter.HasAttribute("doStartOffset"))
  272. int.TryParse(nodeParameter.GetAttribute("doStartOffset"), out doStartOffset);
  273. _port = int.Parse(strPort);
  274. _ip = strIp;
  275. _socketId = int.Parse(networkId);
  276. _stationId = int.Parse(stationId);
  277. DATA.Subscribe($"{Name}.CommunicationStatus", () => _socket == null ? false : _socket.Connected);
  278. OP.Subscribe($"{Name}.Reconnect", (string cmd, object[] args) =>
  279. {
  280. Close();
  281. Open();
  282. return true;
  283. });
  284. }
  285. protected override void Open()
  286. {
  287. _socket = new MCSocket();
  288. _header = new MCProtocol.MC_COMMAND_HEADER()
  289. {
  290. ProtocolID = MCProtocol.MC_SUBHEADER_COMMAND_MESSAGE,
  291. NetworkID = (byte)_socketId,
  292. StationID = (byte)_stationId,
  293. RequestIONumber = MCProtocol.MC_REQUEST_MODULE_IO_NUMBER,
  294. RequestStationNumber = MCProtocol.MC_REQUEST_MODULE_STATION_NUMBER,
  295. RequestDataLen = 0,
  296. CPUMonitorTimer = (ushort)(MCProtocol.MC_CPU_MONITOR_TIMER * 2),
  297. };
  298. _batchCommand = new MCProtocol.MC_BATCH_COMMAND()
  299. {
  300. Command = MCProtocol.MC_COMMAND_BATCH_READ,
  301. DeviceCode = MCProtocol.MC_DEVICE_CODE_DATA_REGISTER_WORD,
  302. DevicePoints = 0,
  303. HeadAddr = 0,
  304. Reserved = 0,
  305. SubCommand = MCProtocol.MC_SUBCOMMAND_WORD_UNITS,
  306. };
  307. _bufferOut = new byte[2048];
  308. _bufferIn = new byte[2048];
  309. _socket.Open(_ip, _port, _localIp);
  310. SetState(IoProviderStateEnum.Opened);
  311. }
  312. protected override void Close()
  313. {
  314. _socket.Close();
  315. SetState(IoProviderStateEnum.Closed);
  316. }
  317. protected override bool[] ReadDi(int _offset, int size)
  318. {
  319. int offset = _offset + diStartOffset;
  320. bool[] buff = new bool[size];
  321. int count = size / perIoLength;
  322. if (count < 1)
  323. {
  324. bool[] dibuffer = DoReadDi(offset, size);
  325. if (dibuffer != null)
  326. Array.Copy(dibuffer, 0, buff, 0, dibuffer.Length);
  327. }
  328. else
  329. {
  330. bool[] dibuffer;
  331. for (int i = 0; i < count; i++)
  332. {
  333. dibuffer = DoReadDi(i * perIoLength + offset, perIoLength);
  334. if (dibuffer != null)
  335. Array.Copy(dibuffer, 0, buff, i * perIoLength, dibuffer.Length);
  336. }
  337. if (size % perIoLength != 0)
  338. {
  339. dibuffer = DoReadDi(offset + perIoLength * count, size % perIoLength);
  340. if (dibuffer != null)
  341. Array.Copy(dibuffer, 0, buff, size - size % perIoLength, dibuffer.Length);
  342. }
  343. }
  344. return buff;
  345. }
  346. public bool SetDemandReadWrite()
  347. {
  348. inDemanding = true;
  349. Thread.Sleep(500);
  350. inDemanding = false;
  351. return true;
  352. }
  353. protected override short[] ReadAi(int offset, int size)
  354. {
  355. short[] buff = new short[size];
  356. int count = size / perIoLength;
  357. if (count < 1)
  358. {
  359. short[] aibuffer = DoReadAi(offset, size);
  360. if (aibuffer != null)
  361. Array.Copy(aibuffer, 0, buff, 0, aibuffer.Length);
  362. }
  363. else
  364. {
  365. short[] aibuffer;
  366. for (int i = 0; i < count; i++)
  367. {
  368. aibuffer = DoReadAi(i * perIoLength + offset, perIoLength);
  369. if (aibuffer != null)
  370. Array.Copy(aibuffer, 0, buff, i * perIoLength, aibuffer.Length);
  371. }
  372. if (size % perIoLength != 0)
  373. {
  374. aibuffer = DoReadAi(offset + perIoLength * count, size % perIoLength);
  375. if (aibuffer != null)
  376. Array.Copy(aibuffer, 0, buff, size - size % perIoLength, aibuffer.Length);
  377. }
  378. }
  379. return buff;
  380. }
  381. protected override void WriteDo(int _offset, bool[] data)
  382. {
  383. int offset = _offset + doStartOffset;
  384. bool[] databuffer = new bool[perIoLength];
  385. int count = data.Length / perIoLength;
  386. if (count < 1)
  387. {
  388. Array.Copy(data, 0, databuffer, 0, data.Length);
  389. Array.Resize(ref databuffer, data.Length);
  390. DoWriteDo(offset, databuffer);
  391. }
  392. else
  393. {
  394. for (int i = 0; i < count; i++)
  395. {
  396. Array.Copy(data, i * perIoLength, databuffer, 0, databuffer.Length);
  397. DoWriteDo(offset + perIoLength * i, databuffer);
  398. }
  399. if (data.Length % perIoLength != 0)
  400. {
  401. Array.Copy(data, perIoLength * count, databuffer, 0, data.Length % perIoLength);
  402. Array.Resize(ref databuffer, data.Length % perIoLength);
  403. DoWriteDo(offset + perIoLength * count, databuffer);
  404. }
  405. }
  406. }
  407. protected override void WriteAo(int offset, short[] data)
  408. {
  409. short[] databuffer = new short[perIoLength];
  410. int count = data.Length / perIoLength;
  411. if (count < 1)
  412. {
  413. Array.Copy(data, 0, databuffer, 0, data.Length);
  414. Array.Resize(ref databuffer, data.Length);
  415. DoWriteAo(offset, databuffer);
  416. }
  417. else
  418. {
  419. for (int i = 0; i < count; i++)
  420. {
  421. Array.Copy(data, i * perIoLength, databuffer, 0, databuffer.Length);
  422. DoWriteAo(offset + perIoLength * i, databuffer, data.Length, i);
  423. }
  424. if (data.Length % perIoLength != 0)
  425. {
  426. Array.Copy(data, perIoLength * count, databuffer, 0, data.Length % perIoLength);
  427. Array.Resize(ref databuffer, data.Length % perIoLength);
  428. DoWriteAo(offset + perIoLength * count, databuffer, data.Length);
  429. }
  430. }
  431. }
  432. private bool WriteData(byte[] data, int length)
  433. {
  434. return _socket.Write(data, length);
  435. }
  436. private int ReceiveData(byte[] data)
  437. {
  438. return _socket.Read(data);
  439. }
  440. private short[] DoReadAi(int offset, int size)
  441. {
  442. _batchCommand.DeviceCode = (byte)MelsecElement.ChooseMelsecElement(aiStoragename).m_nBinCode;
  443. _batchCommand.Command = MCProtocol.MC_COMMAND_BATCH_READ;
  444. _batchCommand.SubCommand = MCProtocol.MC_SUBCOMMAND_WORD_UNITS;
  445. _batchCommand.HeadAddr = (ushort)(offset & 0xFFFF);
  446. _batchCommand.Reserved = (byte)(offset >> 16);
  447. _batchCommand.DevicePoints = (ushort)size;
  448. _header.RequestDataLen = (ushort)(MCProtocol.MC_BATCH_COMMAND_SIZE + MCProtocol.JUNK_SIZE);
  449. byte[] buffer = MCProtocol.Struct2Bytes(_header);
  450. byte[] command = MCProtocol.Struct2Bytes(_batchCommand);
  451. Array.Copy(buffer, 0, _bufferOut, 0, buffer.Length);
  452. Array.Copy(command, 0, _bufferOut, MCProtocol.MC_QHEADER_COMMAND_SIZE, command.Length);
  453. if (!WriteData(_bufferOut, MCProtocol.MC_QHEADER_COMMAND_SIZE + MCProtocol.MC_BATCH_COMMAND_SIZE))
  454. {
  455. return null;
  456. }
  457. //receiveLen < MCProtocol.MC_QHEADER_RESPONSE_SIZE means no data in bufferIn
  458. int receiveLen = ReceiveData(_bufferIn);
  459. int dataLength = receiveLen - MCProtocol.MC_QHEADER_RESPONSE_SIZE;
  460. if (dataLength < 0)
  461. {
  462. return null;
  463. }
  464. MCProtocol.MC_RESPONSE_HEADER responseHeader =
  465. MCProtocol.ToStruct<MCProtocol.MC_RESPONSE_HEADER>(_bufferIn);
  466. if (responseHeader.ProtocolId != 0x00d0 && responseHeader.CompleteCode != MCProtocol.MC_COMPLETE_CODE_SUCCESS)
  467. {
  468. return null;
  469. }
  470. short[] datas = new short[size];
  471. byte[] dataBuff = new byte[dataLength];
  472. Array.Copy(_bufferIn, MCProtocol.MC_QHEADER_RESPONSE_SIZE, dataBuff, 0, dataBuff.Length);
  473. for (int i = 0, dataBuffIndex = 0; i < datas.Length & dataBuffIndex < dataBuff.Length; i++, dataBuffIndex += 2)
  474. {
  475. datas[i] = (short)BitConverter.ToUInt16(dataBuff, 0 + i * 2);
  476. }
  477. return datas;
  478. }
  479. private void DoWriteAo(int offset, short[] data, int total = 0, int count = 100)
  480. {
  481. ushort[] uData = new ushort[data.Length];
  482. uData = data.Select(x => (ushort)x).ToArray();
  483. _batchCommand.DeviceCode = (byte)MelsecElement.ChooseMelsecElement(aoStoragename).m_nBinCode;
  484. _batchCommand.Command = MCProtocol.MC_COMMAND_BATCH_WRITE;
  485. _batchCommand.SubCommand = MCProtocol.MC_SUBCOMMAND_WORD_UNITS;
  486. _batchCommand.HeadAddr = (ushort)(offset & 0xFFFF);
  487. _batchCommand.Reserved = (byte)(offset >> 16);
  488. _batchCommand.DevicePoints = (ushort)data.Length;
  489. _header.RequestDataLen = (ushort)(MCProtocol.MC_BATCH_COMMAND_SIZE + MCProtocol.JUNK_SIZE + MCProtocol.ShortSize * data.Length);
  490. byte[] header = MCProtocol.Struct2Bytes(_header);
  491. byte[] command = MCProtocol.Struct2Bytes(_batchCommand);
  492. byte[] byteData = MCProtocol.Ushort2Byte(uData);
  493. Array.Copy(header, 0, _bufferOut, 0, header.Length);
  494. Array.Copy(command, 0, _bufferOut, MCProtocol.MC_QHEADER_COMMAND_SIZE, command.Length);
  495. Array.Copy(byteData, 0, _bufferOut, MCProtocol.MC_QHEADER_COMMAND_SIZE + MCProtocol.MC_BATCH_COMMAND_SIZE, byteData.Length);
  496. if (!WriteData(_bufferOut, MCProtocol.MC_QHEADER_COMMAND_SIZE + MCProtocol.MC_BATCH_COMMAND_SIZE + MCProtocol.ShortSize * data.Length))
  497. {
  498. return;
  499. }
  500. if (ReceiveData(_bufferIn) <= 0)
  501. {
  502. return;
  503. }
  504. MCProtocol.MC_RESPONSE_HEADER responseHeader =
  505. MCProtocol.ToStruct<MCProtocol.MC_RESPONSE_HEADER>(_bufferIn);
  506. if (responseHeader.ProtocolId != 0x00d0 && responseHeader.CompleteCode != MCProtocol.MC_COMPLETE_CODE_SUCCESS)
  507. {
  508. LOG.Write(" failed with code," + responseHeader.CompleteCode);
  509. return;
  510. }
  511. }
  512. private bool[] DoReadDi(int offset, int size)
  513. {
  514. _batchCommand.DeviceCode = (byte)MelsecElement.ChooseMelsecElement(diStoragename).m_nBinCode;
  515. _batchCommand.Command = MCProtocol.MC_COMMAND_BATCH_READ;
  516. _batchCommand.SubCommand = MCProtocol.MC_SUBCOMMAND_WORD_UNITS;
  517. _batchCommand.HeadAddr = (ushort)(offset & 0xFFFF);
  518. _batchCommand.Reserved = (byte)(offset >> 16);
  519. _batchCommand.DevicePoints = (ushort)(size % 16 > 0 ? size / 16 + 1 : size / 16);
  520. _header.RequestDataLen = (ushort)(MCProtocol.MC_BATCH_COMMAND_SIZE + MCProtocol.JUNK_SIZE);
  521. byte[] buffer = MCProtocol.Struct2Bytes(_header);
  522. byte[] command = MCProtocol.Struct2Bytes(_batchCommand);
  523. Array.Copy(buffer, 0, _bufferOut, 0, buffer.Length);
  524. Array.Copy(command, 0, _bufferOut, MCProtocol.MC_QHEADER_COMMAND_SIZE, command.Length);
  525. if (!WriteData(_bufferOut, MCProtocol.MC_QHEADER_COMMAND_SIZE + MCProtocol.MC_BATCH_COMMAND_SIZE))
  526. {
  527. return null;
  528. }
  529. //receiveLen < MCProtocol.MC_QHEADER_RESPONSE_SIZE means no data in bufferIn
  530. int receiveLen = ReceiveData(_bufferIn);
  531. int dataLength = receiveLen - MCProtocol.MC_QHEADER_RESPONSE_SIZE;
  532. if (dataLength < 0)
  533. {
  534. return null;
  535. }
  536. MCProtocol.MC_RESPONSE_HEADER responseHeader =
  537. MCProtocol.ToStruct<MCProtocol.MC_RESPONSE_HEADER>(_bufferIn);
  538. if (responseHeader.ProtocolId != 0x00d0 && responseHeader.CompleteCode != MCProtocol.MC_COMPLETE_CODE_SUCCESS)
  539. {
  540. return null;
  541. }
  542. bool[] datas = new bool[dataLength * 8];
  543. byte[] dataBuff = new byte[dataLength];
  544. Array.Copy(_bufferIn, MCProtocol.MC_QHEADER_RESPONSE_SIZE, dataBuff, 0, dataBuff.Length);
  545. var bitArray = new BitArray(dataBuff);
  546. for (int i = 0; i < datas.Length; i++)
  547. {
  548. datas[i] = bitArray.Get(i);
  549. }
  550. return datas.Select(x => x).Take(size).ToArray();
  551. }
  552. private void DoWriteDo(int offset, bool[] data)
  553. {
  554. _batchCommand.DeviceCode = (byte)MelsecElement.ChooseMelsecElement(doStoragename).m_nBinCode;
  555. _batchCommand.Command = MCProtocol.MC_COMMAND_BATCH_WRITE;
  556. _batchCommand.SubCommand = MCProtocol.MC_SUBCOMMAND_WORD_UNITS;
  557. _batchCommand.HeadAddr = (ushort)(offset & 0xFFFF);
  558. _batchCommand.Reserved = (byte)(offset >> 16);
  559. _batchCommand.DevicePoints = (ushort)(data.Length % 16 > 0 ? data.Length / 16 + 1 : data.Length / 16);
  560. _header.RequestDataLen = (ushort)(MCProtocol.MC_BATCH_COMMAND_SIZE + MCProtocol.JUNK_SIZE + _batchCommand.DevicePoints * 2);
  561. //one word = two bytes , so _batchCommand.DevicePoints * 2
  562. byte[] byteData = new byte[_batchCommand.DevicePoints * 2];
  563. for (int i = 0, byteDataIndex = 0; i < data.Length & byteDataIndex < byteData.Length; i += 8, byteDataIndex++)
  564. {
  565. byteData[byteDataIndex] += (byte)(data[i] ? 1 : 0);
  566. byteData[byteDataIndex] += (byte)(i + 1 < data.Length && data[i + 1] ? 1 << 1 : 0);
  567. byteData[byteDataIndex] += (byte)(i + 2 < data.Length && data[i + 2] ? 1 << 2 : 0);
  568. byteData[byteDataIndex] += (byte)(i + 3 < data.Length && data[i + 3] ? 1 << 3 : 0);
  569. byteData[byteDataIndex] += (byte)(i + 4 < data.Length && data[i + 4] ? 1 << 4 : 0);
  570. byteData[byteDataIndex] += (byte)(i + 5 < data.Length && data[i + 5] ? 1 << 5 : 0);
  571. byteData[byteDataIndex] += (byte)(i + 6 < data.Length && data[i + 6] ? 1 << 6 : 0);
  572. byteData[byteDataIndex] += (byte)(i + 7 < data.Length && data[i + 7] ? 1 << 7 : 0);
  573. }
  574. byte[] header = MCProtocol.Struct2Bytes(_header);
  575. byte[] command = MCProtocol.Struct2Bytes(_batchCommand);
  576. Array.Copy(header, 0, _bufferOut, 0, header.Length);
  577. Array.Copy(command, 0, _bufferOut, MCProtocol.MC_QHEADER_COMMAND_SIZE, command.Length);
  578. Array.Copy(byteData, 0, _bufferOut, MCProtocol.MC_QHEADER_COMMAND_SIZE + MCProtocol.MC_BATCH_COMMAND_SIZE, byteData.Length);
  579. if (!WriteData(_bufferOut, MCProtocol.MC_QHEADER_COMMAND_SIZE + MCProtocol.MC_BATCH_COMMAND_SIZE + byteData.Length))
  580. {
  581. return;
  582. }
  583. if (ReceiveData(_bufferIn) <= 0)
  584. {
  585. return;
  586. }
  587. MCProtocol.MC_RESPONSE_HEADER responseHeader =
  588. MCProtocol.ToStruct<MCProtocol.MC_RESPONSE_HEADER>(_bufferIn);
  589. if (responseHeader.CompleteCode != MCProtocol.MC_COMPLETE_CODE_SUCCESS)
  590. {
  591. LOG.Write("Write PLC failed with code," + responseHeader.CompleteCode);
  592. return;
  593. }
  594. }
  595. }
  596. class MCSocket
  597. {
  598. private int m_nPort;
  599. private string m_strAddress;
  600. private Socket m_socket;
  601. private int m_nTimeOut;
  602. public MCSocket()
  603. {
  604. m_nTimeOut = 30000;
  605. }
  606. ~MCSocket()
  607. {
  608. }
  609. public bool Connected
  610. {
  611. get { return (m_socket != null && m_socket.Connected); }
  612. }
  613. public bool Open(string strAddress, int nPort, string strLocalAddress)
  614. {
  615. if (Connected)
  616. return true;
  617. Close();
  618. m_strAddress = strAddress;
  619. m_nPort = nPort;
  620. m_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
  621. try
  622. {
  623. // Bind to specific local endpoint
  624. IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Any, 0);
  625. m_socket.Bind(localEndPoint);
  626. IPAddress ipAddress = IPAddress.Parse(m_strAddress);
  627. IPEndPoint ipEndPoint = new IPEndPoint(ipAddress, m_nPort);
  628. //m_socket = new Socket(ipEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
  629. m_socket.SendTimeout = m_nTimeOut;
  630. m_socket.ReceiveTimeout = m_nTimeOut;
  631. m_socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true);
  632. m_socket.Connect(ipEndPoint);
  633. }
  634. catch (Exception ex)
  635. {
  636. LOG.Write(ex);
  637. return false;
  638. }
  639. return true;
  640. }
  641. public bool Close()
  642. {
  643. if (m_socket == null) return true;
  644. try
  645. {
  646. m_socket.Shutdown(SocketShutdown.Both);
  647. m_socket.Close();
  648. m_socket = null;
  649. }
  650. catch (Exception ex)
  651. {
  652. LOG.Write(ex);
  653. return false;
  654. }
  655. return true;
  656. }
  657. public int Read(byte[] buffer)
  658. {
  659. int ret = -1;
  660. if (!Connected) return ret;
  661. return m_socket.Receive(buffer);
  662. //try
  663. //{
  664. // ret = m_socket.Receive(buffer);
  665. //}
  666. //catch (Exception ex)
  667. //{
  668. // LOG.Write(ex);
  669. //}
  670. //return ret;
  671. }
  672. public bool Read(byte[] buffer, int length)
  673. {
  674. if (!Connected) return false;
  675. try
  676. {
  677. m_socket.Receive(buffer, SocketFlags.None);
  678. }
  679. catch (Exception ex)
  680. {
  681. LOG.Write(ex);
  682. return false;
  683. }
  684. return true;
  685. }
  686. public bool Write(byte[] buffer)
  687. {
  688. if (!Connected) return false;
  689. try
  690. {
  691. m_socket.Send(buffer, SocketFlags.None);
  692. }
  693. catch (Exception ex)
  694. {
  695. LOG.Write(ex);
  696. return false;
  697. }
  698. return true;
  699. }
  700. public bool Write(byte[] buffer, int length)
  701. {
  702. if (!Connected) return false;
  703. return m_socket.Send(buffer, length, SocketFlags.None) >= 0;
  704. //try
  705. //{
  706. // m_socket.Send(buffer, length, SocketFlags.None);
  707. //}
  708. //catch (Exception ex)
  709. //{
  710. // LOG.Write(ex);
  711. // return false;
  712. //}
  713. //return true;
  714. }
  715. }
  716. }