PowerSupplierSerialPortModbusDevice.cs 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785
  1. using Aitex.Core.RT.Log;
  2. using Aitex.Core.Util;
  3. using DocumentFormat.OpenXml.InkML;
  4. using MECF.Framework.Common.CommonData.PowerSupplier;
  5. using MECF.Framework.Common.Communications;
  6. using MECF.Framework.Common.Net;
  7. using System;
  8. using System.Collections.Concurrent;
  9. using System.Collections.Generic;
  10. using System.IO.Ports;
  11. using System.Linq;
  12. using System.Net.Sockets;
  13. using System.Text;
  14. using System.Threading;
  15. using System.Threading.Tasks;
  16. namespace MECF.Framework.Common.Device.PowerSupplier
  17. {
  18. public class PowerSupplierSerialPortModbusDevice
  19. {
  20. #region 常量
  21. private const short CURRENT_SETTING_ADDRESS = 0x0101;
  22. private const short OUTPUT_CONTROL_ADDRESS = 0x0110;
  23. private const short STEP_PERIOD_ADDRESS = 0x1400;
  24. private const short STEP_PERIOD_START_ADDRESS = 0x1640;
  25. private const short VOLTAGE_OUTPUT_ADDRESS = 0x0201;
  26. private const short POWER_CONTROL_ADDRESS = 0x0113;
  27. private const short POWER_RUN_MODEL_ADDRESS = 0x0111;
  28. /// <summary>
  29. /// 电源状态(00-cv输出,01-cc输出)
  30. /// </summary>
  31. private const short POWER_STATUS_ADDRESS = 0x0200;
  32. private const string SET_POINT = "SetPoint";
  33. private const string CURRENT = "Current";
  34. private const string VOLTAGE = "Voltage";
  35. private const string ENABLED = "Enabled";
  36. private const string POWER_STATUS = "PowerStatus";
  37. private const string POWER_CONTROL = "PowerControl";
  38. private const string POWER_RUN_MODEL = "PowerRunModel";
  39. /// <summary>
  40. /// 步阶数据数量
  41. /// </summary>
  42. private const int STEP_PERIOD_LENGTH = 6;
  43. #endregion
  44. #region 内部变量
  45. private string _name;
  46. private ConcurrentQueue<PowerSupplierCommand> _commandQueue=new ConcurrentQueue<PowerSupplierCommand>();
  47. private SerialPort _serialPort;
  48. private bool _connected;
  49. private object _locker = new object();
  50. private int _lockTimeout = 1000;
  51. private PowerSupplierMessage _netMessage = new PowerSupplierMessage();
  52. private object _sendLocker = new object();
  53. private object _receiveLocker = new object();
  54. private int _receiveTimeout = 1000;
  55. private int _sendTimeout = 1000;
  56. /// <summary>
  57. /// 错误
  58. /// </summary>
  59. private string _errmsg;
  60. /// <summary>
  61. /// 离线时间
  62. /// </summary>
  63. private DateTime _offlineDateTime = DateTime.Now;
  64. /// <summary>
  65. /// 是否重连
  66. /// </summary>
  67. private bool _reconnect = false;
  68. /// <summary>
  69. /// 首次连接成功
  70. /// </summary>
  71. private bool _isFirstConnected = false;
  72. #endregion
  73. #region 属性
  74. public bool Connected { get { return _connected; } }
  75. #endregion
  76. /// <summary>
  77. /// 构造函数
  78. /// </summary>
  79. /// <param name="ip"></param>
  80. /// <param name="port"></param>
  81. public PowerSupplierSerialPortModbusDevice(string name, string portName, int baudRate = 9600, StopBits stopBits = StopBits.One, int dataBits = 8, Parity parity = Parity.None, bool reconnect = false)
  82. {
  83. _name = name;
  84. _serialPort = new SerialPort();
  85. _serialPort.BaudRate = baudRate;
  86. _serialPort.StopBits = stopBits;
  87. _serialPort.DataBits = dataBits;
  88. _serialPort.Parity = parity;
  89. _serialPort.PortName = portName;
  90. _serialPort.ReadTimeout = _receiveTimeout;
  91. _serialPort.WriteTimeout = _sendTimeout;
  92. _serialPort.ErrorReceived += SerialPort_ErrorReceived;
  93. _reconnect = reconnect;
  94. PeriodicJob periodicJob = new PeriodicJob(20, OnTimer, $"{name}.ModbusDevice.Thread", true);
  95. }
  96. /// <summary>
  97. /// 出现错误
  98. /// </summary>
  99. /// <param name="sender"></param>
  100. /// <param name="e"></param>
  101. private void SerialPort_ErrorReceived(object sender, SerialErrorReceivedEventArgs e)
  102. {
  103. LOG.WriteLog(eEvent.ERR_POWERSUPPLIER, _name, e.EventType.ToString());
  104. }
  105. /// <summary>
  106. /// 定时器
  107. /// </summary>
  108. /// <returns></returns>
  109. private bool OnTimer()
  110. {
  111. if (!_connected)
  112. {
  113. if (DateTime.Now.Subtract(_offlineDateTime).TotalSeconds >= 5 && _commandQueue.Count != 0)
  114. {
  115. ClearSendQueue();
  116. }
  117. if (_reconnect&&_isFirstConnected)
  118. {
  119. Start();
  120. }
  121. return true;
  122. }
  123. if (_commandQueue.Count!=0)
  124. {
  125. if(_commandQueue.TryDequeue(out PowerSupplierCommand command))
  126. {
  127. if (_connected)
  128. {
  129. if (command.CommandCode == 0x03)
  130. {
  131. ApplyDataOperation(command);
  132. }
  133. }
  134. }
  135. }
  136. return true;
  137. }
  138. /// <summary>
  139. /// 清空发送队列
  140. /// </summary>
  141. private void ClearSendQueue()
  142. {
  143. try
  144. {
  145. while (_commandQueue.Count != 0)
  146. {
  147. _commandQueue.TryDequeue(out var result);
  148. }
  149. }
  150. catch
  151. {
  152. }
  153. }
  154. /// <summary>
  155. /// 连接
  156. /// </summary>
  157. /// <returns></returns>
  158. public bool Start()
  159. {
  160. if (!_connected)
  161. {
  162. try
  163. {
  164. _serialPort.Open();
  165. LOG.WriteLog(eEvent.INFO_LINMOT, _name, $"connect port[{_serialPort.PortName}] success");
  166. _connected = true;
  167. if(!_isFirstConnected)
  168. {
  169. _isFirstConnected = true;
  170. }
  171. return true;
  172. }
  173. catch (Exception ex)
  174. {
  175. return false;
  176. }
  177. }
  178. return true;
  179. }
  180. /// <summary>
  181. /// 设置通道输出开关控制
  182. /// </summary>
  183. /// <param name="channel"></param>
  184. /// <param name="currentValue"></param>
  185. /// <returns></returns>
  186. public void SetChannelOutputSwitchControl(byte channel, bool enabled)
  187. {
  188. if (Connected)
  189. {
  190. PowerSupplierCommand command = new PowerSupplierCommand();
  191. command.Channel = channel;
  192. command.CommandCode = 0x06;
  193. command.Address = (ushort)(OUTPUT_CONTROL_ADDRESS);
  194. command.Datas = new ushort[] { enabled ? (ushort)01 : (ushort)00 };
  195. SetOperation(command);
  196. }
  197. else
  198. {
  199. WriteErrorMsg($"{_name} is not connected");
  200. }
  201. }
  202. /// <summary>
  203. /// 设置电源控制
  204. /// </summary>
  205. /// <param name="channel"></param>
  206. /// <param name="currentValue"></param>
  207. /// <returns></returns>
  208. public void SetChannelPowerControl(byte channel,byte remoteControl)
  209. {
  210. if (Connected)
  211. {
  212. PowerSupplierCommand command = new PowerSupplierCommand();
  213. command.Channel = channel;
  214. command.CommandCode = 0x06;
  215. command.Address = (ushort)(POWER_CONTROL_ADDRESS);
  216. command.Datas = new ushort[] { remoteControl };
  217. SetOperation(command);
  218. }
  219. else
  220. {
  221. WriteErrorMsg($"{_name} is not connected");
  222. }
  223. }
  224. /// <summary>
  225. /// 设置电源运行模式
  226. /// </summary>
  227. /// <param name="channel"></param>
  228. /// <param name="currentValue"></param>
  229. /// <returns></returns>
  230. public void SetChannelPowerRunmodelControl(byte channel,byte model)
  231. {
  232. if (Connected)
  233. {
  234. PowerSupplierCommand command = new PowerSupplierCommand();
  235. command.Channel = channel;
  236. command.CommandCode = 0x06;
  237. command.Address = (ushort)(POWER_RUN_MODEL_ADDRESS);
  238. command.Datas = new ushort[] { model };
  239. SetOperation(command);
  240. }
  241. else
  242. {
  243. WriteErrorMsg($"{_name} is not connected");
  244. }
  245. }
  246. /// <summary>
  247. /// 设置步阶数据
  248. /// </summary>
  249. /// <param name="channel"></param>
  250. /// <param name="stepDatas"></param>
  251. public bool SetStepPeriod(byte channel,List<PowerSupplierStepPeriodData> stepDatas,int scale)
  252. {
  253. if(Connected)
  254. {
  255. PowerSupplierCommand command = new PowerSupplierCommand();
  256. command.Channel = channel;
  257. command.CommandCode = 0x10;
  258. command.Address = (ushort)STEP_PERIOD_ADDRESS;
  259. command.RegisterCount =(ushort)(STEP_PERIOD_LENGTH * stepDatas.Count);
  260. command.Datas = new ushort[STEP_PERIOD_LENGTH * stepDatas.Count];
  261. for(int i = 0;i<stepDatas.Count;i++)
  262. {
  263. PowerSupplierStepPeriodData data = stepDatas[i];
  264. command.Datas[0 + STEP_PERIOD_LENGTH * i] = (ushort)6000;
  265. command.Datas[1 + STEP_PERIOD_LENGTH * i] = (ushort)Math.Round(stepDatas[i].Current*scale,0);
  266. command.Datas[2 + STEP_PERIOD_LENGTH * i] = stepDatas[i].Hour;
  267. command.Datas[3+STEP_PERIOD_LENGTH*i]= stepDatas[i].Minute;
  268. command.Datas[4+STEP_PERIOD_LENGTH*i]= stepDatas[i].Second;
  269. command.Datas[5 + STEP_PERIOD_LENGTH * i] = stepDatas[i].Microsecond;
  270. }
  271. return SetOperation(command);
  272. }
  273. else
  274. {
  275. WriteErrorMsg($"{_name} is not connected");
  276. }
  277. return false;
  278. }
  279. /// <summary>
  280. /// 启动步阶
  281. /// </summary>
  282. /// <param name="channel"></param>
  283. /// <param name="startStep"></param>
  284. /// <param name="endStep"></param>
  285. /// <param name="cycle"></param>
  286. public bool StartStepPeriod(byte channel,ushort startStep,ushort endStep,ushort cycle)
  287. {
  288. if (Connected)
  289. {
  290. PowerSupplierCommand command = new PowerSupplierCommand();
  291. command.Channel = channel;
  292. command.CommandCode = 0x10;
  293. command.Address = (ushort)STEP_PERIOD_START_ADDRESS;
  294. command.RegisterCount = 3;
  295. command.Datas = new ushort[3] { startStep,endStep,cycle };
  296. return SetOperation(command);
  297. }
  298. else
  299. {
  300. WriteErrorMsg($"{_name} is not connected");
  301. }
  302. return false;
  303. }
  304. /// <summary>
  305. /// 设置电流
  306. /// </summary>
  307. /// <param name="channel"></param>
  308. /// <param name="currentValue"></param>
  309. /// <returns></returns>
  310. public void SetCurrentValue(byte channel,ushort currentValue)
  311. {
  312. if (Connected)
  313. {
  314. PowerSupplierCommand command = new PowerSupplierCommand();
  315. command.Channel = channel;
  316. command.CommandCode = 0x06;
  317. command.Address = (ushort)(CURRENT_SETTING_ADDRESS);
  318. command.Datas = new ushort[] { currentValue };
  319. SetOperation(command);
  320. }
  321. else
  322. {
  323. WriteErrorMsg($"{_name} is not connected");
  324. }
  325. }
  326. /// <summary>
  327. /// 设置电源状态
  328. /// </summary>
  329. /// <param name="channel"></param>
  330. /// <param name="currentValue"></param>
  331. /// <returns></returns>
  332. public void SetChannelPowerStatus(byte channel, byte powerStatus)
  333. {
  334. if (Connected)
  335. {
  336. PowerSupplierCommand command = new PowerSupplierCommand();
  337. command.Channel = channel;
  338. command.CommandCode = 0x06;
  339. command.Address = (ushort)(POWER_STATUS_ADDRESS);
  340. command.Datas = new ushort[] { powerStatus };
  341. SetOperation(command);
  342. }
  343. else
  344. {
  345. WriteErrorMsg($"{_name} is not connected");
  346. }
  347. }
  348. /// <summary>
  349. /// 获取通道输出开关控制
  350. /// </summary>
  351. /// <param name="channel"></param>
  352. /// <returns></returns>
  353. public void GetChannelOutput(byte channel)
  354. {
  355. if (Connected)
  356. {
  357. PowerSupplierCommand applyCommand = new PowerSupplierCommand();
  358. applyCommand.Channel = channel;
  359. applyCommand.CommandCode = 0x03;
  360. applyCommand.Address = (ushort)(OUTPUT_CONTROL_ADDRESS);
  361. applyCommand.RegisterCount = 1;
  362. applyCommand.Variables.Add(ENABLED,(0,1));
  363. _commandQueue.Enqueue(applyCommand);
  364. }
  365. else
  366. {
  367. WriteErrorMsg($"{_name} is not connected");
  368. }
  369. }
  370. /// <summary>
  371. /// 获取通道电源控制
  372. /// </summary>
  373. /// <param name="channel"></param>
  374. /// <returns></returns>
  375. public void GetChannelPowerControl(byte channel)
  376. {
  377. if (Connected)
  378. {
  379. PowerSupplierCommand applyCommand = new PowerSupplierCommand();
  380. applyCommand.Channel = channel;
  381. applyCommand.CommandCode = 0x03;
  382. applyCommand.Address = (ushort)(POWER_CONTROL_ADDRESS);
  383. applyCommand.RegisterCount = 1;
  384. applyCommand.Variables.Add(POWER_CONTROL, (0, 1));
  385. _commandQueue.Enqueue(applyCommand);
  386. }
  387. else
  388. {
  389. WriteErrorMsg($"{_name} is not connected");
  390. }
  391. }
  392. /// <summary>
  393. /// 获取通道电流设置数值
  394. /// </summary>
  395. /// <param name="channel"></param>
  396. /// <returns></returns>
  397. public void GetChannelCurrentSetting(byte channel)
  398. {
  399. if (Connected)
  400. {
  401. PowerSupplierCommand applyCommand = new PowerSupplierCommand();
  402. applyCommand.Channel = channel;
  403. applyCommand.CommandCode = 0x03;
  404. applyCommand.Address = (ushort)(CURRENT_SETTING_ADDRESS);
  405. applyCommand.RegisterCount = 1;
  406. applyCommand.Variables.Add(SET_POINT,(0,1));
  407. _commandQueue.Enqueue(applyCommand);
  408. }
  409. else
  410. {
  411. WriteErrorMsg($"{_name} is not connected");
  412. }
  413. }
  414. /// <summary>
  415. /// 获取电源状态设置数值
  416. /// </summary>
  417. /// <param name="channel"></param>
  418. /// <returns></returns>
  419. public void GetChannelPowerStatus(byte channel)
  420. {
  421. if (Connected)
  422. {
  423. PowerSupplierCommand applyCommand = new PowerSupplierCommand();
  424. applyCommand.Channel = channel;
  425. applyCommand.CommandCode = 0x03;
  426. applyCommand.Address = (ushort)(POWER_STATUS_ADDRESS);
  427. applyCommand.RegisterCount = 1;
  428. applyCommand.Variables.Add(POWER_STATUS, (0,1));
  429. _commandQueue.Enqueue(applyCommand);
  430. }
  431. else
  432. {
  433. WriteErrorMsg($"{_name} is not connected");
  434. }
  435. }
  436. /// <summary>
  437. /// 获取电源运行模式
  438. /// </summary>
  439. /// <param name="channel"></param>
  440. /// <returns></returns>
  441. public void GetChannelPowerRunModel(byte channel)
  442. {
  443. if (Connected)
  444. {
  445. PowerSupplierCommand applyCommand = new PowerSupplierCommand();
  446. applyCommand.Channel = channel;
  447. applyCommand.CommandCode = 0x03;
  448. applyCommand.Address = (ushort)(POWER_RUN_MODEL_ADDRESS);
  449. applyCommand.RegisterCount = 1;
  450. applyCommand.Variables.Add(POWER_RUN_MODEL, (0, 1));
  451. _commandQueue.Enqueue(applyCommand);
  452. }
  453. else
  454. {
  455. WriteErrorMsg($"{_name} is not connected");
  456. }
  457. }
  458. /// <summary>
  459. /// 申请电压和电流数值
  460. /// </summary>
  461. /// <param name="channel"></param>
  462. /// <returns></returns>
  463. public void GetChannelVoltageAndCurrent(byte channel)
  464. {
  465. if (Connected)
  466. {
  467. PowerSupplierCommand applyCommand = new PowerSupplierCommand();
  468. applyCommand.Channel = channel;
  469. applyCommand.CommandCode = 0x03;
  470. applyCommand.Address = (ushort)(VOLTAGE_OUTPUT_ADDRESS);
  471. applyCommand.RegisterCount = 4;
  472. applyCommand.Variables.Add(VOLTAGE,(0,2));
  473. applyCommand.Variables.Add(CURRENT,(2,2));
  474. _commandQueue.Enqueue(applyCommand);
  475. }
  476. else
  477. {
  478. WriteErrorMsg($"{_name} is not connected");
  479. }
  480. }
  481. /// <summary>
  482. /// 设置操作
  483. /// </summary>
  484. /// <param name="command"></param>
  485. /// <returns></returns>
  486. private bool SetOperation(PowerSupplierCommand command)
  487. {
  488. NetResult netResult = SetData(command);
  489. if (!netResult.IsSuccess)
  490. {
  491. LOG.WriteLog(eEvent.ERR_POWERSUPPLIER, _name, $"write value {command.Datas[0]} failed,{netResult.Message}");
  492. return false;
  493. }
  494. return true;
  495. }
  496. /// <summary>
  497. /// 设置数据
  498. /// </summary>
  499. /// <typeparam name="T"></typeparam>
  500. /// <param name="data"></param>
  501. /// <returns></returns>
  502. public NetResult SetData(PowerSupplierCommand data)
  503. {
  504. if (Monitor.TryEnter(_locker, _lockTimeout))
  505. {
  506. NetResult result = ReadFromServer(data);
  507. if (!result.IsSuccess)
  508. {
  509. Monitor.Exit(_locker);
  510. return NetResult.CreateFailedResult(result.ErrorCode, result.Message);
  511. }
  512. bool confirmResult = _netMessage.ConfirmResponseResult();
  513. if (!confirmResult)
  514. {
  515. Monitor.Exit(_locker);
  516. return NetResult.CreateFailedResult(_netMessage.ErrorCode, _netMessage.ErrorMsg);
  517. }
  518. Monitor.Exit(_locker);
  519. return NetResult.CreateSuccessResult();
  520. }
  521. else
  522. {
  523. return NetResult.CreateFailedResult(NetErrorCode.GetLockTimeout);
  524. }
  525. }
  526. /// <summary>
  527. /// 从服务端读取数据
  528. /// </summary>
  529. /// <typeparam name="T"></typeparam>
  530. /// <param name="data"></param>
  531. /// <returns></returns>
  532. private NetResult ReadFromServer(PowerSupplierCommand data)
  533. {
  534. byte[] buffer = _netMessage.Code(data);
  535. NetResult sendResult = Send(buffer);
  536. if (!sendResult.IsSuccess)
  537. {
  538. return NetResult.CreateFailedResult(sendResult.ErrorCode, sendResult.Message);
  539. }
  540. _netMessage.SendBytes = buffer;
  541. _netMessage.SetProtocolHeadBytesLength();
  542. NetResult<byte[]> headerResult = Receive(_netMessage.ProtocolHeadBytesLength);
  543. if (!headerResult.IsSuccess)
  544. {
  545. return NetResult.CreateFailedResult(headerResult.ErrorCode, headerResult.Message);
  546. }
  547. _netMessage.HeadBytes = headerResult.Data;
  548. if (!_netMessage.CheckHeadBytesLegal())
  549. {
  550. return NetResult.CreateFailedResult(NetErrorCode.InvalidHeader);
  551. }
  552. NetResult<byte[]> contentResult = Receive(_netMessage.GetContentLengthByHeadBytes());
  553. if (!contentResult.IsSuccess)
  554. {
  555. return NetResult.CreateFailedResult(contentResult.ErrorCode, contentResult.Message);
  556. }
  557. _netMessage.ContentBytes = contentResult.Data;
  558. bool dataValid = _netMessage.CheckDataLegal();
  559. if (!dataValid)
  560. {
  561. return NetResult.CreateFailedResult(_netMessage.ErrorCode, _netMessage.ErrorMsg);
  562. }
  563. return NetResult.CreateSuccessResult();
  564. }
  565. /// <summary>
  566. /// 申请数据操作
  567. /// </summary>
  568. /// <param name="command"></param>
  569. private void ApplyDataOperation(PowerSupplierCommand command)
  570. {
  571. NetResult<PowerSupplierCommand> netResult = ApplyData(command);
  572. if (!netResult.IsSuccess)
  573. {
  574. List<string> keys = command.Variables.Keys.ToList();
  575. string str = String.Join(" ", keys);
  576. WriteErrorMsg($"apply {str} error");
  577. return;
  578. }
  579. if(netResult.Data.Datas!=null)
  580. {
  581. Dictionary<string, (int,int)> dictionary = command.Variables;
  582. List<string> keys = dictionary.Keys.ToList();
  583. foreach(string item in keys)
  584. {
  585. var result = dictionary[item];
  586. if(item==ENABLED)
  587. {
  588. PowerSupplierDeviceConfigManager.Instance.UpdateModuleVariable(_name, command.Channel, ENABLED, netResult.Data.Datas[result.Item1] == 0x01);
  589. }
  590. else
  591. {
  592. if(result.Item2==1)
  593. {
  594. PowerSupplierDeviceConfigManager.Instance.UpdateModuleVariable(_name, command.Channel, item, netResult.Data.Datas[result.Item1]);
  595. }
  596. else if(result.Item2==2)
  597. {
  598. int value = netResult.Data.Datas[result.Item1] * 255 + netResult.Data.Datas[result.Item1+1];
  599. PowerSupplierDeviceConfigManager.Instance.UpdateModuleVariable(_name, command.Channel, item, value);
  600. }
  601. }
  602. }
  603. }
  604. }
  605. /// <summary>
  606. /// 申请数据
  607. /// </summary>
  608. /// <typeparam name="T">申请指令类型</typeparam>
  609. /// <param name="data">指令对象</param>
  610. /// <returns>返回数据对象</returns>
  611. public NetResult<PowerSupplierCommand> ApplyData(PowerSupplierCommand data)
  612. {
  613. if (Monitor.TryEnter(_locker, _lockTimeout))
  614. {
  615. NetResult result = ReadFromServer(data);
  616. if (!result.IsSuccess)
  617. {
  618. Monitor.Exit(_locker);
  619. return NetResult.CreateFailedResult<PowerSupplierCommand>(result.ErrorCode, result.Message);
  620. }
  621. Monitor.Exit(_locker);
  622. return NetResult.CreateSuccessResult<PowerSupplierCommand>(_netMessage.Decode());
  623. }
  624. else
  625. {
  626. return NetResult.CreateFailedResult<PowerSupplierCommand>(NetErrorCode.GetLockTimeout);
  627. }
  628. }
  629. /// <summary>
  630. /// 发送数据
  631. /// </summary>
  632. /// <param name="data"></param>
  633. /// <returns></returns>
  634. public NetResult Send(byte[] data)
  635. {
  636. if (!Connected)
  637. {
  638. return NetResult.CreateFailedResult(NetErrorCode.NetOffline);
  639. }
  640. //清除缓存数据
  641. ClearPreData();
  642. //进入发送
  643. if (Monitor.TryEnter(_sendLocker, _sendTimeout))
  644. {
  645. if (_serialPort == null)
  646. {
  647. return NetResult.CreateFailedResult(NetErrorCode.NullSocketObject);
  648. }
  649. try
  650. {
  651. _serialPort.Write(data,0,data.Length);
  652. Monitor.Exit(_sendLocker);
  653. return NetResult.CreateSuccessResult();
  654. }
  655. catch (Exception ex)
  656. {
  657. Monitor.Exit(_sendLocker);
  658. WriteErrorMsg(ex.Message);
  659. return NetResult.CreateFailedResult((int)NetErrorCode.InnerException, ex.Message);
  660. }
  661. }
  662. else
  663. {
  664. return NetResult.CreateFailedResult(NetErrorCode.GetLockTimeout);
  665. }
  666. }
  667. /// <summary>
  668. /// 接收数据
  669. /// </summary>
  670. /// <param name="length"></param>
  671. /// <returns></returns>
  672. public NetResult<byte[]> Receive(int length)
  673. {
  674. if (!Connected)
  675. {
  676. return NetResult.CreateFailedResult<byte[]>(NetErrorCode.NetOffline);
  677. }
  678. if (Monitor.TryEnter(_receiveLocker, _receiveTimeout))
  679. {
  680. if (_serialPort == null)
  681. {
  682. return NetResult.CreateFailedResult<byte[]>(NetErrorCode.NullSocketObject);
  683. }
  684. try
  685. {
  686. byte[] buffer = new byte[length];
  687. DateTime dt = DateTime.Now;
  688. while(true)
  689. {
  690. if(_serialPort.BytesToRead>=length)
  691. {
  692. _serialPort.Read(buffer, 0, length);
  693. break;
  694. }
  695. if(DateTime.Now.Subtract(dt).TotalMilliseconds>=_receiveTimeout)
  696. {
  697. Monitor.Exit(_receiveLocker);
  698. return NetResult.CreateFailedResult<byte[]>(NetErrorCode.ReceiveTimeout);
  699. }
  700. }
  701. Monitor.Exit(_receiveLocker);
  702. return NetResult.CreateSuccessResult<byte[]>(buffer);
  703. }
  704. catch (SocketException ex)
  705. {
  706. Monitor.Exit(_receiveLocker);
  707. return NetResult.CreateFailedResult<byte[]>((int)NetErrorCode.InnerException, ex.Message);
  708. }
  709. catch (Exception ex)
  710. {
  711. Monitor.Exit(_receiveLocker);
  712. return NetResult.CreateFailedResult<byte[]>((int)NetErrorCode.InnerException, ex.Message);
  713. }
  714. }
  715. else
  716. {
  717. return NetResult.CreateFailedResult<byte[]>(NetErrorCode.GetLockTimeout);
  718. }
  719. }
  720. /// <summary>
  721. /// 清除先前的数据
  722. /// </summary>
  723. public void ClearPreData()
  724. {
  725. if (!Connected)
  726. {
  727. return;
  728. }
  729. if (Monitor.TryEnter(_receiveLocker, _receiveTimeout))
  730. {
  731. try
  732. {
  733. while (_serialPort.BytesToRead != 0)
  734. {
  735. byte[] buffer = new byte[_serialPort.BytesToRead];
  736. _serialPort.Read(buffer,0, buffer.Length);
  737. }
  738. Monitor.Exit(_receiveLocker);
  739. }
  740. catch (SocketException ex)
  741. {
  742. Monitor.Exit(_receiveLocker);
  743. }
  744. catch (Exception ex)
  745. {
  746. Monitor.Exit(_receiveLocker);
  747. }
  748. }
  749. }
  750. /// <summary>
  751. /// 记录错误信息
  752. /// </summary>
  753. /// <param name="msg"></param>
  754. private void WriteErrorMsg(string msg, bool disConnected = true)
  755. {
  756. if (disConnected)
  757. {
  758. _connected = false;
  759. _offlineDateTime = DateTime.Now;
  760. }
  761. if (_errmsg != msg)
  762. {
  763. _errmsg = msg;
  764. LOG.WriteLog(eEvent.ERR_POWERSUPPLIER, _name, msg);
  765. }
  766. }
  767. }
  768. }