WcfPlc.cs 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400
  1. using Aitex.Core.RT.Device;
  2. using MECF.Framework.Common.Communications;
  3. using MECF.Framework.Common.Event;
  4. using System;
  5. using System.Xml;
  6. namespace MECF.Framework.Common.PLC
  7. {
  8. public class WcfPlc : BaseDevice, IConnection, IConnectable, IPlc
  9. {
  10. private WcfPlcServiceClient _plcClient;
  11. public AlarmEventItem AlarmConnectFailed { get; set; }
  12. public AlarmEventItem AlarmCommunicationError { get; set; }
  13. public event Action OnConnected;
  14. public event Action OnDisconnected;
  15. private FsmConnection _connection;
  16. private int _heartbeat = 1;
  17. private string _wcfConfigName;
  18. public WcfPlc(string module, XmlElement node, string ioModule = "")
  19. {
  20. var attrModule = node.GetAttribute("module");
  21. Module = string.IsNullOrEmpty(attrModule) ? module : attrModule;
  22. Name = node.GetAttribute("id");
  23. _wcfConfigName = node.GetAttribute("wcf");
  24. }
  25. public WcfPlc(string module, string name, string wcfConfigName)
  26. {
  27. Module = module;
  28. Name = name;
  29. _wcfConfigName = wcfConfigName;
  30. }
  31. public bool Initialize()
  32. {
  33. if (string.IsNullOrEmpty(_wcfConfigName))
  34. {
  35. _plcClient = new WcfPlcServiceClient();
  36. }
  37. else
  38. {
  39. _plcClient = new WcfPlcServiceClient(_wcfConfigName);
  40. }
  41. AlarmConnectFailed = SubscribeAlarm($"{Module}.{Name}.ConnectionError", $"Can not connect with {Address}", null);
  42. AlarmCommunicationError = SubscribeAlarm($"{Module}.{Name}.CommunicationError", $"Can not Communication {Address}", null);
  43. _connection = new FsmConnection();
  44. IConnectionContext contex = new StaticConnectionContext()
  45. {
  46. IsEnabled = true,
  47. Address = "WCF PLC",
  48. EnableCheckConnection = false,
  49. EnableLog = false,
  50. MaxRetryConnectCount = 3,
  51. IsAscii = false,
  52. NewLine = string.Empty,
  53. RetryConnectIntervalMs = 1000,
  54. };
  55. _connection.OnConnected += _connection_OnConnected;
  56. _connection.OnDisconnected += _connection_OnDisconnected;
  57. _connection.OnError += _connection_OnError;
  58. _connection.Initialize(50, this, contex);
  59. return true;
  60. }
  61. private void _connection_OnError(string error)
  62. {
  63. AlarmConnectFailed.Set(error);
  64. }
  65. private void _connection_OnDisconnected()
  66. {
  67. if (OnDisconnected != null)
  68. OnDisconnected();
  69. }
  70. private void _connection_OnConnected()
  71. {
  72. if (OnConnected != null)
  73. OnConnected();
  74. }
  75. public void Monitor()
  76. {
  77. }
  78. public void Terminate()
  79. {
  80. }
  81. public void Reset()
  82. {
  83. ResetAlarm();
  84. _connection.InvokeReset();
  85. }
  86. #region IConnection
  87. public string Address { get; }
  88. public bool IsConnected { get; set; }
  89. public bool Connect()
  90. {
  91. _connection.InvokeConnect();
  92. return true;
  93. }
  94. public bool Disconnect()
  95. {
  96. _connection.InvokeDisconnect();
  97. return true;
  98. }
  99. #endregion
  100. #region IConnectable
  101. #pragma warning disable 0067
  102. public event Action<string> OnCommunicationError;
  103. public event Action<string> OnAsciiDataReceived;
  104. public event Action<byte[]> OnBinaryDataReceived;
  105. #pragma warning restore 0067
  106. public bool Connect(out string reason)
  107. {
  108. reason = string.Empty;
  109. return true;
  110. }
  111. public bool Disconnect(out string reason)
  112. {
  113. reason = string.Empty;
  114. return true;
  115. }
  116. public bool CheckIsConnected()
  117. {
  118. if (_plcClient == null)
  119. return false;
  120. _heartbeat++;
  121. if(_plcClient.Heartbeat(_heartbeat)>0 && !_plcClient.ActionFailed)
  122. return true;
  123. return false;
  124. }
  125. public bool ReadBool(string address, out bool[] data, int length, out string reason)
  126. {
  127. if (!_connection.IsConnected)
  128. {
  129. reason = "Not connected with PLC";
  130. data = null;
  131. return false;
  132. }
  133. if (HasAlarm)
  134. {
  135. reason = "Has alarm";
  136. data = null;
  137. return false;
  138. }
  139. data = _plcClient.ReadDi(0, length, out reason);
  140. if (data == null || _plcClient.ActionFailed)
  141. {
  142. AlarmCommunicationError.Description = "Failed read PLC data";
  143. AlarmCommunicationError.Set();
  144. return false;
  145. }
  146. return true;
  147. }
  148. public bool ReadInt16(string address, out short[] data, int length, out string reason)
  149. {
  150. if (!_connection.IsConnected)
  151. {
  152. reason = "Not connected with PLC";
  153. data = null;
  154. return false;
  155. }
  156. if (HasAlarm)
  157. {
  158. reason = "Has alarm";
  159. data = null;
  160. return false;
  161. }
  162. data = _plcClient.ReadAiInt16(0, length, out reason);
  163. if (data == null || _plcClient.ActionFailed)
  164. {
  165. AlarmCommunicationError.Description = "Failed read PLC data";
  166. AlarmCommunicationError.Set();
  167. return false;
  168. }
  169. return true;
  170. }
  171. public bool WriteBool(string address, bool[] data, out string reason)
  172. {
  173. if (!_connection.IsConnected)
  174. {
  175. reason = "Not connected with PLC";
  176. data = null;
  177. return false;
  178. }
  179. if (HasAlarm)
  180. {
  181. reason = "Has alarm";
  182. data = null;
  183. return false;
  184. }
  185. bool result = _plcClient.WriteDo(0, data, out reason);
  186. if (!result || _plcClient.ActionFailed)
  187. {
  188. AlarmCommunicationError.Description = "Failed write PLC data";
  189. AlarmCommunicationError.Set();
  190. return false;
  191. }
  192. return true;
  193. }
  194. public bool WriteInt16(string address, short[] data , out string reason)
  195. {
  196. if (!_connection.IsConnected)
  197. {
  198. reason = "Not connected with PLC";
  199. data = null;
  200. return false;
  201. }
  202. if (HasAlarm)
  203. {
  204. reason = "Has alarm";
  205. data = null;
  206. return false;
  207. }
  208. bool result = _plcClient.WriteAoInt16(0, data, out reason);
  209. if (!result || _plcClient.ActionFailed)
  210. {
  211. AlarmCommunicationError.Description = "Failed write PLC data";
  212. AlarmCommunicationError.Set();
  213. return false;
  214. }
  215. return true;
  216. }
  217. public bool SendBinaryData(byte[] data)
  218. {
  219. return true;
  220. }
  221. public bool SendAsciiData(string data)
  222. {
  223. return true;
  224. }
  225. #endregion
  226. public bool Read(string variable, out object data, string type, int length, out string reason)
  227. {
  228. if (!_connection.IsConnected)
  229. {
  230. reason = "Not connected with PLC";
  231. data = null;
  232. return false;
  233. }
  234. if (HasAlarm)
  235. {
  236. reason = "Has alarm";
  237. data = null;
  238. return false;
  239. }
  240. bool result= _plcClient.Read(variable, out data, type, length, out reason);
  241. if (data == null || _plcClient.ActionFailed)
  242. {
  243. AlarmCommunicationError.Description = "Failed read PLC data";
  244. AlarmCommunicationError.Set();
  245. return false;
  246. }
  247. return result;
  248. }
  249. public bool WriteArrayElement(string variable, int index, object value, out string reason)
  250. {
  251. if (!_connection.IsConnected)
  252. {
  253. reason = "Not connected with PLC";
  254. return false;
  255. }
  256. if (HasAlarm)
  257. {
  258. reason = "Has alarm";
  259. return false;
  260. }
  261. bool result = _plcClient.WriteArrayElement(variable, index, value, out reason);
  262. if (_plcClient.ActionFailed)
  263. {
  264. AlarmCommunicationError.Description = "Failed read PLC data";
  265. AlarmCommunicationError.Set();
  266. return false;
  267. }
  268. return result;
  269. }
  270. public bool ReadFloat(string address, out float[] data, int length, out string reason)
  271. {
  272. if (!_connection.IsConnected)
  273. {
  274. reason = "Not connected with PLC";
  275. data = null;
  276. return false;
  277. }
  278. if (HasAlarm)
  279. {
  280. reason = "Has alarm";
  281. data = null;
  282. return false;
  283. }
  284. data = _plcClient.ReadAiFloat(0, length, out reason);
  285. if (data == null || _plcClient.ActionFailed)
  286. {
  287. AlarmCommunicationError.Description = "Failed read PLC data";
  288. AlarmCommunicationError.Set();
  289. return false;
  290. }
  291. return true;
  292. }
  293. public bool WriteFloat(string address, float[] data, out string reason)
  294. {
  295. if (!_connection.IsConnected)
  296. {
  297. reason = "Not connected with PLC";
  298. data = null;
  299. return false;
  300. }
  301. if (HasAlarm)
  302. {
  303. reason = "Has alarm";
  304. data = null;
  305. return false;
  306. }
  307. bool result = _plcClient.WriteAoFloat(0, data, out reason);
  308. if (!result || _plcClient.ActionFailed)
  309. {
  310. AlarmCommunicationError.Description = "Failed write PLC data";
  311. AlarmCommunicationError.Set();
  312. return false;
  313. }
  314. return true;
  315. }
  316. }
  317. }