PLCS7.cs 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596
  1. using snap7Enc;
  2. using snap7Enc.Types;
  3. using System;
  4. using System.Collections.Concurrent;
  5. using System.Collections.Generic;
  6. using System.Diagnostics;
  7. using System.Linq;
  8. using System.Reflection;
  9. using System.Runtime.InteropServices;
  10. using System.Text;
  11. using System.Threading;
  12. using System.Threading.Tasks;
  13. using System.Timers;
  14. namespace PLCS7
  15. {
  16. public interface IPLCS7
  17. {
  18. bool PLCConnect();
  19. void PLCDisconnect();
  20. bool WriteToPLC(object abstractPLCMsg, PLCDataType whoami);
  21. List<object> ReadFromPLC(PLCDataType whichToRead, int index);
  22. }
  23. public enum PLCDataType
  24. {
  25. terminal,
  26. central,
  27. parkingSpace
  28. }
  29. public abstract class AbstractPLCLinker : IPLCS7
  30. {
  31. protected const int mainBlockOffset = 52;
  32. protected const int parkingSpaceOffset = 22;
  33. protected const int terminalLength = 50;
  34. protected const int parkingSpaceLength = 56;
  35. /// <summary>
  36. /// PLC 连接状态flag
  37. /// </summary>
  38. public bool isConnected = false;
  39. /// <summary>
  40. /// plc中cpu类型
  41. /// </summary>
  42. protected CpuType cpu;
  43. /// <summary>
  44. /// PLC的IP地址
  45. /// </summary>
  46. protected string ip;
  47. /// <summary>
  48. /// PLC的端口号
  49. /// </summary>
  50. protected Int16 rack;
  51. /// <summary>
  52. /// 工作站号
  53. /// </summary>
  54. protected Int16 slot;
  55. /// <summary>
  56. /// 终端DB块iD
  57. /// </summary>
  58. protected int terminalDB;
  59. /// <summary>
  60. /// 中心DB块iD
  61. /// </summary>
  62. protected int centralDB;
  63. /// <summary>
  64. /// 车位DB块ID
  65. /// </summary>
  66. protected int parkingSpaceDB;
  67. /// <summary>
  68. /// 终端个数
  69. /// </summary>
  70. protected int terminalCount;
  71. /// <summary>
  72. /// 停车位个数
  73. /// </summary>
  74. protected int parkingSpaceCount;
  75. /// <summary>
  76. /// PLC S7连接对象
  77. /// </summary>
  78. protected static Plc plc = null;
  79. /// <summary>
  80. /// 用于将写PLC指令排队的阻塞队列
  81. /// </summary>
  82. protected static BlockingCollection<MsgNodeToWrite> writingBlockingCollection = new BlockingCollection<MsgNodeToWrite>();
  83. /// <summary>
  84. /// 写线程,控制PLC写入频率
  85. /// </summary>
  86. protected static Thread writeThread;
  87. /// <summary>
  88. /// 系统关闭
  89. /// </summary>
  90. protected bool closed;
  91. /// <summary>
  92. /// 读写锁
  93. /// </summary>
  94. protected static object readWriteLock = new object();
  95. /// <summary>
  96. /// 连接
  97. /// </summary>
  98. /// <returns></returns>
  99. public abstract bool PLCConnect();
  100. /// <summary>
  101. /// 断开连接
  102. /// </summary>
  103. public abstract void PLCDisconnect();
  104. /// <summary>
  105. /// 读PLC
  106. /// </summary>
  107. /// <param name="whichToRead"></param>
  108. /// <param name="index"></param>
  109. /// <returns></returns>
  110. public abstract List<object> ReadFromPLC(PLCDataType whichToRead, int index);
  111. /// <summary>
  112. /// 写PLC
  113. /// </summary>
  114. /// <param name="abstractPLCMsg"></param>
  115. /// <param name="whoami"></param>
  116. /// <returns></returns>
  117. public abstract bool WriteToPLC(object abstractPLCMsg, PLCDataType whoami);
  118. }
  119. public class PLCLinker : AbstractPLCLinker
  120. {
  121. ///// <summary>
  122. ///// PLC刷新频率,来自于配置文件
  123. ///// </summary>
  124. //private int PLC_refresh_interval;
  125. ///// <summary>
  126. ///// 无法获取配置文件时使用的PLC刷新频率
  127. ///// </summary>
  128. //private const short PLC_TIME_SCALE = 200;
  129. //************************************** 方法区 *************************************
  130. public void test()
  131. {
  132. Random rnd = new Random();
  133. Task t = Task.Factory.StartNew(() =>
  134. {
  135. while (true)
  136. {
  137. TerminalStru terminal1 = new TerminalStru();
  138. terminal1 = (TerminalStru)ReadStruFromPLC(terminal1, 27, 0);
  139. Console.WriteLine(terminal1.ToString());
  140. Thread.Sleep(200);
  141. terminal1.terminalStatus = (short)rnd.Next(1, 6);
  142. terminal1.licenseCodeA = rnd.Next(3000, 9999);
  143. terminal1.receiptNum = rnd.Next(3000, 9999);
  144. terminal1.licVerification = (short)rnd.Next(1, 555);
  145. WriteStruToPLC(terminal1, 27, 0);
  146. //List<byte> bList = Struct.ToBytes(terminal1).ToList();
  147. //WriteMultipleBytes(27, bList, 0);
  148. ////203 chars
  149. //string str = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbccc";
  150. ////pl.WriteMultipleBytes(1, (Encoding.ASCII.GetBytes(str)).ToList());
  151. //byte[] bytes = pl.ReadMultipleBytes(27, 50).ToArray();
  152. //string str2 = Encoding.ASCII.GetString(bytes);
  153. //Console.WriteLine(str2);
  154. //if (str == str2)
  155. //{
  156. // Console.WriteLine("equals");
  157. //}
  158. //else
  159. //{
  160. // Console.WriteLine("error, unequal");
  161. //}
  162. Thread.Sleep(2000);
  163. }
  164. });
  165. t.Wait();
  166. }
  167. /// <summary>
  168. /// PLCLinker构造函数
  169. /// </summary>
  170. /// <param name="cpu"></param>
  171. /// <param name="ip"></param>
  172. /// <param name="rack"></param>
  173. /// <param name="slot"></param>
  174. /// <param name="terminalDB"></param>
  175. /// <param name="centralDB"></param>
  176. /// <param name="parkingSpaceDB"></param>
  177. public PLCLinker(CpuType cpu, string ip, short rack, short slot, int terminalDB, int centralDB, int parkingSpaceDB, int terminalCount, int parkingSpaceCount)
  178. {
  179. this.cpu = cpu;
  180. this.ip = ip;
  181. this.rack = rack;
  182. this.slot = slot;
  183. this.terminalDB = terminalDB;
  184. this.centralDB = centralDB;
  185. this.parkingSpaceDB = parkingSpaceDB;
  186. this.terminalCount = terminalCount;
  187. this.parkingSpaceCount = parkingSpaceCount;
  188. isConnected = PLCConnect();
  189. }
  190. /// <summary>
  191. /// 读取指定数据块中多个字节
  192. /// </summary>
  193. /// <param name="db"></param>
  194. /// <param name="length"></param>
  195. /// <param name="startAddr"></param>
  196. /// <returns></returns>
  197. private List<byte> ReadMultipleBytes(int db, int length, int startAddr = 0)
  198. {
  199. List<byte> resultBytes = new List<byte>();
  200. int index = startAddr;
  201. int remains = length;
  202. while (remains > 0)
  203. {
  204. int maxToRead = Math.Min(remains, 200);
  205. try
  206. {
  207. byte[] temp = plc.ReadBytes(DataType.DataBlock, db, index, maxToRead);
  208. if (temp == null)
  209. return new List<byte>();
  210. resultBytes.AddRange(temp);
  211. remains -= maxToRead;
  212. index += maxToRead;
  213. }
  214. catch { }
  215. }
  216. return resultBytes;
  217. }
  218. /// <summary>
  219. /// 写入指定数据块中多个字节
  220. /// </summary>
  221. /// <param name="db"></param>
  222. /// <param name="bytesToWrite"></param>
  223. /// <param name="startAddr"></param>
  224. /// <returns></returns>
  225. private ErrorCode WriteMultipleBytes(int db, List<byte> bytesToWrite, int startAddr = 0)
  226. {
  227. int index = startAddr;
  228. int remains = bytesToWrite.Count();
  229. try
  230. {
  231. while (remains > 0)
  232. {
  233. int maxToWrite = Math.Min(remains, 200);
  234. ErrorCode ec = plc.WriteBytes(DataType.DataBlock, db, index, bytesToWrite.GetRange(index, maxToWrite).ToArray());
  235. index += maxToWrite;
  236. remains -= maxToWrite;
  237. if (!ec.Equals(ErrorCode.NoError)) { return ec; }
  238. }
  239. }
  240. catch (Exception e) { Console.WriteLine(e.Message); }
  241. return ErrorCode.NoError;
  242. }
  243. /// <summary>
  244. /// 从PLC中读取结构体
  245. /// </summary>
  246. /// <param name="obj"></param>
  247. /// <param name="db"></param>
  248. /// <param name="startAddr"></param>
  249. /// <returns></returns>
  250. private object ReadStruFromPLC(object obj, int db, int startAddr = 0)
  251. {
  252. Type structType = obj.GetType();
  253. object returnedObj;
  254. try
  255. {
  256. //returnedObj = plc.ReadStruct(structType, db, startAddr);
  257. int numBytes = Struct.GetStructSize(structType);
  258. var resultBytes = plc.ReadBytes(DataType.DataBlock, db, startAddr, numBytes);
  259. returnedObj = Struct.FromBytes(structType, resultBytes);
  260. if (returnedObj != null) { return returnedObj; }
  261. }
  262. catch (Exception e)
  263. {
  264. Console.WriteLine(e.Message);
  265. }
  266. return null;
  267. //Console.WriteLine(ts.ToString());
  268. }
  269. /// <summary>
  270. /// 向PLC中写入结构体
  271. /// </summary>
  272. /// <param name="obj"></param>
  273. /// <param name="db"></param>
  274. /// <param name="startAddr"></param>
  275. private ErrorCode WriteStruToPLC(object obj, int db, int startAddr = 0)
  276. {
  277. Console.WriteLine("write to PLC");
  278. ErrorCode ec = ErrorCode.NoError;
  279. try
  280. {
  281. //ec = plc.WriteStruct(obj, 22, startAddr);
  282. List<byte> bList = Struct.ToBytes(obj).ToList();
  283. ec = WriteMultipleBytes(db, bList, startAddr);
  284. }
  285. catch (Exception e) { Console.WriteLine(ec.ToString() + "," + e.Message); }
  286. return ec;
  287. }
  288. private short BytesRevert(short num)
  289. {
  290. byte[] temp = BitConverter.GetBytes(num);
  291. Array.Reverse(temp);
  292. return BitConverter.ToInt16(temp, 0);
  293. }
  294. private int BytesRevert(int num)
  295. {
  296. byte[] temp = BitConverter.GetBytes(num);
  297. Array.Reverse(temp);
  298. return BitConverter.ToInt32(temp, 0);
  299. }
  300. /// <summary>
  301. /// 从阻塞队列获取需写入PLC数据并写入PLC,时间间隔在线程中控制
  302. /// </summary>
  303. /// <returns></returns>
  304. private bool WriteAccordingly()
  305. {
  306. MsgNodeToWrite msg = null;
  307. try
  308. {
  309. msg = writingBlockingCollection.Take();
  310. //Console.WriteLine("取出后," + writingBlockingCollection.Count);
  311. }
  312. catch (Exception ex) { Console.WriteLine("获取PLC写对象异常," + ex.Message); }
  313. if (msg == null || msg.abstractPLCMsg == null)
  314. {
  315. Console.WriteLine((msg == null) + "," + (msg.abstractPLCMsg == null));
  316. return false;
  317. }
  318. //更新设备状态
  319. isConnected = plc.IsConnected;
  320. if (isConnected)
  321. {
  322. lock (readWriteLock)
  323. {
  324. if (msg.abstractPLCMsg.GetType().Equals(typeof(TerminalStru)))
  325. {
  326. TerminalStru ts = (TerminalStru)msg.abstractPLCMsg;
  327. if (ts.terminalID <= 0 || ts.terminalID > terminalCount) { Console.WriteLine("终端id:" + ts.terminalID); return false; }
  328. int offset = terminalLength * (ts.terminalID - 1);
  329. if (msg.whoami.Equals(PLCDataType.central))
  330. {
  331. if (ts.paymentStatus != (short)-1) { plc.WriteBytes(DataType.DataBlock, terminalDB, 28 + offset, BitConverter.GetBytes(BytesRevert(ts.paymentStatus))); }
  332. if (ts.licVerification != (short)-1) { plc.WriteBytes(DataType.DataBlock, terminalDB, 30 + offset, BitConverter.GetBytes(BytesRevert(ts.licVerification))); }
  333. if (ts.parkingFee != (short)-1) { plc.WriteBytes(DataType.DataBlock, terminalDB, 32 + offset, BitConverter.GetBytes(BytesRevert(ts.parkingFee))); }
  334. if (ts.userType != (short)-1) { plc.WriteBytes(DataType.DataBlock, terminalDB, 34 + offset, BitConverter.GetBytes(BytesRevert(ts.userType))); }
  335. }
  336. else if (msg.whoami.Equals(PLCDataType.terminal))
  337. {
  338. //if (ts.terminalStatus != (short)-1) { plc.WriteBytes(DataType.DataBlock, terminalDB, 2 + offset, BitConverter.GetBytes(BytesRevert(ts.terminalStatus))); }
  339. if (ts.paymentStatus != (short)-1) { plc.WriteBytes(DataType.DataBlock, terminalDB, 28 + offset, BitConverter.GetBytes(BytesRevert(ts.paymentStatus))); }
  340. if (ts.btnStatus != (short)-1) { plc.WriteBytes(DataType.DataBlock, terminalDB, 4 + offset, BitConverter.GetBytes(BytesRevert(ts.btnStatus))); }
  341. if (ts.cmd != (short)-1) { plc.WriteBytes(DataType.DataBlock, terminalDB, 6 + offset, BitConverter.GetBytes(BytesRevert(ts.cmd))); }
  342. if (ts.licenseCodeA != -1) { plc.WriteBytes(DataType.DataBlock, terminalDB, 8 + offset, BitConverter.GetBytes(BytesRevert(ts.licenseCodeA))); }
  343. if (ts.licenseCodeB != -1) { plc.WriteBytes(DataType.DataBlock, terminalDB, 12 + offset, BitConverter.GetBytes(BytesRevert(ts.licenseCodeB))); }
  344. if (ts.licenseCodeC != -1) { plc.WriteBytes(DataType.DataBlock, terminalDB, 16 + offset, BitConverter.GetBytes(BytesRevert(ts.licenseCodeC))); }
  345. if (ts.licenseCodeD != -1) { plc.WriteBytes(DataType.DataBlock, terminalDB, 20 + offset, BitConverter.GetBytes(BytesRevert(ts.licenseCodeD))); }
  346. if (ts.receiptNum != -1) { plc.WriteBytes(DataType.DataBlock, terminalDB, 24 + offset, BitConverter.GetBytes(BytesRevert(ts.receiptNum))); }
  347. if (ts.termHeartbeat != 0) { plc.WriteBytes(DataType.DataBlock, terminalDB, 48 + offset, BitConverter.GetBytes(BytesRevert(ts.termHeartbeat))); }
  348. }
  349. }
  350. else if (msg.abstractPLCMsg.GetType().Equals(typeof(MainBlockStru)) && msg.whoami.Equals(PLCDataType.central))
  351. {
  352. //只允许中控写入
  353. MainBlockStru mbs = (MainBlockStru)msg.abstractPLCMsg;
  354. //byte[] temp = BitConverter.GetBytes(BytesRevert(mbs.licenseReceived));
  355. if (mbs.centralHearbeat != (short)-1) { plc.WriteBytes(DataType.DataBlock, centralDB, mainBlockOffset + 8, BitConverter.GetBytes(BytesRevert(mbs.centralHearbeat))); }
  356. if (mbs.licenseReceived != (short)-1) { plc.WriteBytes(DataType.DataBlock, centralDB, mainBlockOffset, BitConverter.GetBytes(BytesRevert(mbs.licenseReceived))); }
  357. if (mbs.bookParkCmd != (short)-1) { plc.WriteBytes(DataType.DataBlock, centralDB, mainBlockOffset - 4, BitConverter.GetBytes(BytesRevert(mbs.bookParkCmd))); }
  358. if (mbs.bookFetchCmd != (short)-1) { plc.WriteBytes(DataType.DataBlock, centralDB, mainBlockOffset - 2, BitConverter.GetBytes(BytesRevert(mbs.bookFetchCmd))); }
  359. if (mbs.processCompleted != (short)-1) { plc.WriteBytes(DataType.DataBlock, centralDB, 16, BitConverter.GetBytes(BytesRevert(mbs.processCompleted))); }
  360. //ErrorCode ec = plc.WriteBytes(DataType.DataBlock, centralDB, mainBlockOffset, temp);
  361. //if (!ec.Equals(ErrorCode.NoError)) { return false; }
  362. }
  363. else if (msg.abstractPLCMsg.GetType().Equals(typeof(ParkingSpaceStru)) && msg.whoami.Equals(PLCDataType.central))
  364. {
  365. //只允许中控写入,中控只允许写车位状态
  366. ParkingSpaceStru pss = (ParkingSpaceStru)msg.abstractPLCMsg;
  367. int offset = parkingSpaceLength * (pss.parkingSpace - 1) + parkingSpaceOffset;
  368. byte[] temp = BitConverter.GetBytes(BytesRevert(pss.spaceStatus));
  369. ErrorCode ec = plc.WriteBytes(DataType.DataBlock, parkingSpaceDB, offset, temp);
  370. if (!ec.Equals(ErrorCode.NoError)) { return false; }
  371. }
  372. else { Console.WriteLine(msg.whoami); return false; }
  373. }
  374. }
  375. else { Console.WriteLine("掉线"); return false; }
  376. return true;
  377. }
  378. /// <summary>
  379. /// 读取PLC数据块
  380. /// </summary>
  381. /// <param name="whichToRead"></param>
  382. /// <param name="index"></param>
  383. /// <returns></returns>
  384. public override List<object> ReadFromPLC(PLCDataType whichToRead, int index)
  385. {
  386. //更新设备状态
  387. isConnected = plc.IsConnected;
  388. List<object> result = new List<object>();
  389. if (!isConnected)
  390. {
  391. PLCConnect();
  392. }
  393. if (isConnected)
  394. {
  395. lock (readWriteLock)
  396. {
  397. switch (whichToRead)
  398. {
  399. case PLCDataType.central:
  400. object obj = ReadStruFromPLC(new MainBlockStru(), centralDB);
  401. if (obj != null) { result.Add(obj); }
  402. break;
  403. case PLCDataType.terminal:
  404. TerminalStru ts = new TerminalStru();
  405. //index 在合理范围读取单一元素,否则全部读取
  406. if (index > 0 && index < terminalCount)
  407. {
  408. obj = ReadStruFromPLC(ts, terminalDB, Struct.GetStructSize(ts.GetType()) * (index - 1));
  409. if (obj != null) { result.Add(obj); }
  410. }
  411. else
  412. {
  413. for (int i = 0; i < terminalCount; i++)
  414. {
  415. obj = ReadStruFromPLC(ts, terminalDB, Struct.GetStructSize(ts.GetType()) * i);
  416. if (obj != null) { result.Add(obj); }
  417. }
  418. }
  419. break;
  420. case PLCDataType.parkingSpace:
  421. ParkingSpaceStru pss = new ParkingSpaceStru();
  422. //index 在合理范围读取单一元素,否则全部读取
  423. if (index > 0 && index < parkingSpaceCount)
  424. {
  425. obj = ReadStruFromPLC(pss, parkingSpaceDB, Struct.GetStructSize(pss.GetType()) * (index - 1));
  426. if (obj != null) { result.Add(obj); }
  427. }
  428. else
  429. {
  430. for (int i = 0; i < parkingSpaceCount; i++)
  431. {
  432. obj = ReadStruFromPLC(pss, parkingSpaceDB, Struct.GetStructSize(pss.GetType()) * i);
  433. if (obj != null) { result.Add(obj); }
  434. }
  435. }
  436. break;
  437. default:
  438. Console.WriteLine("wrong type");
  439. break;
  440. }
  441. }
  442. }
  443. return result;
  444. }
  445. /// <summary>
  446. /// 写入PLC,其中可写入但不需写入字段请赋值为-1
  447. /// </summary>
  448. /// <param name="abstractPLCMsg"></param>
  449. /// <param name="whoami"></param>
  450. /// <returns></returns>
  451. public override bool WriteToPLC(object abstractPLCMsg, PLCDataType whoami)
  452. {
  453. //更新设备状态
  454. isConnected = plc.IsConnected;
  455. if (abstractPLCMsg != null)
  456. {
  457. writingBlockingCollection.Add(new MsgNodeToWrite(abstractPLCMsg, whoami));
  458. //Console.WriteLine("加入后," + writingBlockingCollection.Count);
  459. return true;
  460. }
  461. else
  462. return false;
  463. }
  464. /// <summary>
  465. /// 连接PLC
  466. /// </summary>
  467. /// <returns></returns>
  468. public override bool PLCConnect()
  469. {
  470. closed = false;
  471. writeThread = new Thread(() =>
  472. {
  473. //Stopwatch stopwatch = new Stopwatch();
  474. while (!closed)
  475. {
  476. //stopwatch.Restart();
  477. bool result = WriteAccordingly();
  478. if (!result)
  479. Console.WriteLine("写PLC操作异常");
  480. Thread.Sleep(20);
  481. //stopwatch.Stop();
  482. //Console.WriteLine(stopwatch.ElapsedMilliseconds / 1000.0f);
  483. }
  484. });
  485. writeThread.IsBackground = true;
  486. writeThread.Priority = ThreadPriority.AboveNormal;
  487. writeThread.Start();
  488. if (plc == null)
  489. {
  490. plc = new Plc(cpu, ip, rack, slot);
  491. }
  492. if (plc != null)
  493. {
  494. ErrorCode err = plc.Open();
  495. if (err != ErrorCode.NoError) { Console.WriteLine("connection error"); isConnected = false; }
  496. else { Console.WriteLine("connected"); isConnected = true; }
  497. }
  498. else { isConnected = false; }
  499. return isConnected;
  500. }
  501. /// <summary>
  502. /// 关闭PLC连接
  503. /// </summary>
  504. public override void PLCDisconnect()
  505. {
  506. //try
  507. //{
  508. // if (writeThread != null)
  509. // writeThread.Abort();
  510. //}
  511. //catch (Exception ex) { Console.WriteLine("强制终止写PLC线程," + ex.Message); }
  512. closed = true;
  513. if (plc != null)
  514. {
  515. plc.Close();
  516. }
  517. }
  518. /// <summary>
  519. /// 根据地址偏移量写入PLC
  520. /// </summary>
  521. /// <param name="whichToWrite"></param>
  522. /// <param name="offset"></param>
  523. /// <param name="value"></param>
  524. /// <returns></returns>
  525. public bool WriteAccordingToOffset(PLCDataType whichToWrite, int offset, object value)
  526. {
  527. isConnected = plc.IsConnected;
  528. if (value == null)
  529. return false;
  530. if (isConnected)
  531. {
  532. ErrorCode ec = ErrorCode.NoError;
  533. switch (whichToWrite)
  534. {
  535. case PLCDataType.terminal:
  536. if (value.GetType().Equals(typeof(int)))
  537. {
  538. ec = plc.WriteBytes(DataType.DataBlock, terminalDB, offset, BitConverter.GetBytes(BytesRevert((int)value)));
  539. }
  540. else if (value.GetType().Equals(typeof(short)))
  541. {
  542. ec = plc.WriteBytes(DataType.DataBlock, terminalDB, offset, BitConverter.GetBytes(BytesRevert((short)value)));
  543. }
  544. if (ec.Equals(ErrorCode.NoError)) { return true; }
  545. else { return false; }
  546. break;
  547. case PLCDataType.central:
  548. if (value.GetType().Equals(typeof(int)))
  549. {
  550. ec = plc.WriteBytes(DataType.DataBlock, centralDB, offset, BitConverter.GetBytes(BytesRevert((int)value)));
  551. }
  552. else if (value.GetType().Equals(typeof(short)))
  553. {
  554. ec = plc.WriteBytes(DataType.DataBlock, centralDB, offset, BitConverter.GetBytes(BytesRevert((short)value)));
  555. }
  556. if (ec.Equals(ErrorCode.NoError)) { return true; }
  557. else { return false; }
  558. break;
  559. case PLCDataType.parkingSpace:
  560. if (value.GetType().Equals(typeof(int)))
  561. {
  562. ec = plc.WriteBytes(DataType.DataBlock, parkingSpaceDB, offset, BitConverter.GetBytes(BytesRevert((int)value)));
  563. }
  564. else if (value.GetType().Equals(typeof(short)))
  565. {
  566. ec = plc.WriteBytes(DataType.DataBlock, parkingSpaceDB, offset, BitConverter.GetBytes(BytesRevert((short)value)));
  567. }
  568. if (ec.Equals(ErrorCode.NoError)) { return true; }
  569. else { return false; }
  570. break;
  571. }
  572. }
  573. return false;
  574. }
  575. }
  576. public class MsgNodeToWrite
  577. {
  578. public object abstractPLCMsg;
  579. public PLCDataType whoami;
  580. public MsgNodeToWrite(object abstractPLCMsg, PLCDataType whoami)
  581. {
  582. this.abstractPLCMsg = abstractPLCMsg;
  583. this.whoami = whoami;
  584. }
  585. }
  586. }