123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400 |
- using Aitex.Core.RT.Device;
- using MECF.Framework.Common.Communications;
- using MECF.Framework.Common.Event;
- using System;
- using System.Xml;
- namespace MECF.Framework.Common.PLC
- {
- public class WcfPlc : BaseDevice, IConnection, IConnectable, IPlc
- {
- private WcfPlcServiceClient _plcClient;
- public AlarmEventItem AlarmConnectFailed { get; set; }
- public AlarmEventItem AlarmCommunicationError { get; set; }
- public event Action OnConnected;
- public event Action OnDisconnected;
- private FsmConnection _connection;
- private int _heartbeat = 1;
- private string _wcfConfigName;
- public WcfPlc(string module, XmlElement node, string ioModule = "")
- {
- var attrModule = node.GetAttribute("module");
- Module = string.IsNullOrEmpty(attrModule) ? module : attrModule;
- Name = node.GetAttribute("id");
- _wcfConfigName = node.GetAttribute("wcf");
- }
- public WcfPlc(string module, string name, string wcfConfigName)
- {
- Module = module;
- Name = name;
- _wcfConfigName = wcfConfigName;
- }
- public bool Initialize()
- {
- if (string.IsNullOrEmpty(_wcfConfigName))
- {
- _plcClient = new WcfPlcServiceClient();
- }
- else
- {
- _plcClient = new WcfPlcServiceClient(_wcfConfigName);
- }
- AlarmConnectFailed = SubscribeAlarm($"{Module}.{Name}.ConnectionError", $"Can not connect with {Address}", null);
- AlarmCommunicationError = SubscribeAlarm($"{Module}.{Name}.CommunicationError", $"Can not Communication {Address}", null);
- _connection = new FsmConnection();
- IConnectionContext contex = new StaticConnectionContext()
- {
- IsEnabled = true,
- Address = "WCF PLC",
- EnableCheckConnection = false,
- EnableLog = false,
- MaxRetryConnectCount = 3,
- IsAscii = false,
- NewLine = string.Empty,
- RetryConnectIntervalMs = 1000,
- };
- _connection.OnConnected += _connection_OnConnected;
- _connection.OnDisconnected += _connection_OnDisconnected;
- _connection.OnError += _connection_OnError;
- _connection.Initialize(50, this, contex);
- return true;
- }
- private void _connection_OnError(string error)
- {
- AlarmConnectFailed.Set(error);
- }
- private void _connection_OnDisconnected()
- {
- if (OnDisconnected != null)
- OnDisconnected();
- }
- private void _connection_OnConnected()
- {
- if (OnConnected != null)
- OnConnected();
- }
- public void Monitor()
- {
- }
- public void Terminate()
- {
- }
- public void Reset()
- {
- ResetAlarm();
- _connection.InvokeReset();
- }
- #region IConnection
- public string Address { get; }
- public bool IsConnected { get; set; }
- public bool Connect()
- {
- _connection.InvokeConnect();
- return true;
- }
- public bool Disconnect()
- {
- _connection.InvokeDisconnect();
- return true;
- }
- #endregion
- #region IConnectable
- #pragma warning disable 0067
- public event Action<string> OnCommunicationError;
- public event Action<string> OnAsciiDataReceived;
- public event Action<byte[]> OnBinaryDataReceived;
- #pragma warning restore 0067
- public bool Connect(out string reason)
- {
- reason = string.Empty;
- return true;
- }
- public bool Disconnect(out string reason)
- {
- reason = string.Empty;
- return true;
- }
- public bool CheckIsConnected()
- {
- if (_plcClient == null)
- return false;
- _heartbeat++;
- if(_plcClient.Heartbeat(_heartbeat)>0 && !_plcClient.ActionFailed)
- return true;
- return false;
- }
- public bool ReadBool(string address, out bool[] data, int length, out string reason)
- {
- if (!_connection.IsConnected)
- {
- reason = "Not connected with PLC";
- data = null;
- return false;
- }
- if (HasAlarm)
- {
- reason = "Has alarm";
- data = null;
- return false;
- }
- data = _plcClient.ReadDi(0, length, out reason);
- if (data == null || _plcClient.ActionFailed)
- {
- AlarmCommunicationError.Description = "Failed read PLC data";
- AlarmCommunicationError.Set();
- return false;
- }
- return true;
- }
- public bool ReadInt16(string address, out short[] data, int length, out string reason)
- {
- if (!_connection.IsConnected)
- {
- reason = "Not connected with PLC";
- data = null;
- return false;
- }
- if (HasAlarm)
- {
- reason = "Has alarm";
- data = null;
- return false;
- }
- data = _plcClient.ReadAiInt16(0, length, out reason);
- if (data == null || _plcClient.ActionFailed)
- {
- AlarmCommunicationError.Description = "Failed read PLC data";
- AlarmCommunicationError.Set();
- return false;
- }
- return true;
- }
- public bool WriteBool(string address, bool[] data, out string reason)
- {
- if (!_connection.IsConnected)
- {
- reason = "Not connected with PLC";
- data = null;
- return false;
- }
- if (HasAlarm)
- {
- reason = "Has alarm";
- data = null;
- return false;
- }
-
- bool result = _plcClient.WriteDo(0, data, out reason);
- if (!result || _plcClient.ActionFailed)
- {
- AlarmCommunicationError.Description = "Failed write PLC data";
- AlarmCommunicationError.Set();
- return false;
- }
- return true;
- }
- public bool WriteInt16(string address, short[] data , out string reason)
- {
- if (!_connection.IsConnected)
- {
- reason = "Not connected with PLC";
- data = null;
- return false;
- }
- if (HasAlarm)
- {
- reason = "Has alarm";
- data = null;
- return false;
- }
- bool result = _plcClient.WriteAoInt16(0, data, out reason);
- if (!result || _plcClient.ActionFailed)
- {
- AlarmCommunicationError.Description = "Failed write PLC data";
- AlarmCommunicationError.Set();
- return false;
- }
- return true;
- }
- public bool SendBinaryData(byte[] data)
- {
- return true;
- }
- public bool SendAsciiData(string data)
- {
- return true;
- }
- #endregion
- public bool Read(string variable, out object data, string type, int length, out string reason)
- {
- if (!_connection.IsConnected)
- {
- reason = "Not connected with PLC";
- data = null;
- return false;
- }
- if (HasAlarm)
- {
- reason = "Has alarm";
- data = null;
- return false;
- }
- bool result= _plcClient.Read(variable, out data, type, length, out reason);
- if (data == null || _plcClient.ActionFailed)
- {
- AlarmCommunicationError.Description = "Failed read PLC data";
- AlarmCommunicationError.Set();
- return false;
- }
- return result;
- }
- public bool WriteArrayElement(string variable, int index, object value, out string reason)
- {
- if (!_connection.IsConnected)
- {
- reason = "Not connected with PLC";
- return false;
- }
- if (HasAlarm)
- {
- reason = "Has alarm";
- return false;
- }
- bool result = _plcClient.WriteArrayElement(variable, index, value, out reason);
- if (_plcClient.ActionFailed)
- {
- AlarmCommunicationError.Description = "Failed read PLC data";
- AlarmCommunicationError.Set();
- return false;
- }
- return result;
- }
- public bool ReadFloat(string address, out float[] data, int length, out string reason)
- {
- if (!_connection.IsConnected)
- {
- reason = "Not connected with PLC";
- data = null;
- return false;
- }
- if (HasAlarm)
- {
- reason = "Has alarm";
- data = null;
- return false;
- }
- data = _plcClient.ReadAiFloat(0, length, out reason);
- if (data == null || _plcClient.ActionFailed)
- {
- AlarmCommunicationError.Description = "Failed read PLC data";
- AlarmCommunicationError.Set();
- return false;
- }
- return true;
- }
- public bool WriteFloat(string address, float[] data, out string reason)
- {
- if (!_connection.IsConnected)
- {
- reason = "Not connected with PLC";
- data = null;
- return false;
- }
- if (HasAlarm)
- {
- reason = "Has alarm";
- data = null;
- return false;
- }
- bool result = _plcClient.WriteAoFloat(0, data, out reason);
- if (!result || _plcClient.ActionFailed)
- {
- AlarmCommunicationError.Description = "Failed write PLC data";
- AlarmCommunicationError.Set();
- return false;
- }
- return true;
- }
- }
- }
|