using Aitex.Core.RT.Event; using Aitex.Core.RT.IOCore; using Aitex.Core.RT.Log; using HslCommunication; using HslCommunication.ModBus; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Xml; namespace MECF.Framework.RT.Core.IoProviders { public class ModbusSerial : IoProvider { //private string address; private string portName; private byte station; public int diStartAddress; public int doStartAddress; public int aiStartAddress; public int aoStartAddress; public string dataformat; public bool addressstartwithzero; //public bool stringReverse; private ModbusRtu _readerClient = null; public bool IsCommunicationError = false; private bool _isConnected; private object _locker = new object(); private bool _enableLog { get;set; } protected override void SetParameter(XmlElement nodeParameter) { //address = nodeParameter.GetAttribute("address"); portName = nodeParameter.GetAttribute("PortName"); station = (byte)Convert.ToInt32(nodeParameter.GetAttribute("station")); //stringReverse = Convert.ToBoolean(nodeParameter.GetAttribute("stringReverse")); diStartAddress = int.Parse(nodeParameter.GetAttribute("diStartAddress")); aiStartAddress = int.Parse(nodeParameter.GetAttribute("aiStartAddress")); doStartAddress = int.Parse(nodeParameter.GetAttribute("doStartAddress")); aoStartAddress = int.Parse(nodeParameter.GetAttribute("aoStartAddress")); dataformat = nodeParameter.GetAttribute("dataformat"); //OP.Subscribe("System.ModbusPLC", InvokeReset); _readerClient = new ModbusRtu(); _readerClient.SerialPortInni(portName); _readerClient.Open(); } public int _connecteTimes { get; set; } protected override bool OnTimer() { if (!_isConnected) return true; lock (_locker) { try { foreach (var bufferSection in _blockSections) { if (bufferSection.Type == IoType.DI) { bool[] diBuffer = ReadDi(bufferSection.Offset, bufferSection.Size); if (diBuffer != null) { _buffer.SetDiBuffer(_source, bufferSection.Offset, diBuffer); //TraceArray(diBuffer); } } else if (bufferSection.Type == IoType.DO) { bool[] doBuffer = ReadDi(bufferSection.Offset, bufferSection.Size); if (doBuffer != null) { _buffer.SetDoBuffer(_source, bufferSection.Offset, doBuffer); } } else if (bufferSection.Type == IoType.AI) { short[] aiBuffer = ReadAi(bufferSection.Offset, bufferSection.Size); if (aiBuffer != null) { _buffer.SetAiBuffer(_source, bufferSection.Offset, aiBuffer); } } else if (bufferSection.Type == IoType.AO) { short[] aoBuffer = ReadAi(bufferSection.Offset, bufferSection.Size); if (aoBuffer != null) { _buffer.SetAoBuffer(_source, bufferSection.Offset, aoBuffer); } } } } catch (Exception ex) { LOG.Write(ex); Close(); } } return true; } //public void Reset() //{ //} protected override bool[] ReadDi(int offset, int size) { int intSize = size % 16 == 0 ? size / 16 : (size / 16 + 1); int address = offset + diStartAddress; OperateResult ret; ret = _readerClient.ReadInt16(address.ToString(), (ushort)intSize); if (!ret.IsSuccess) return null; List retList = new List(); foreach (var value in ret.Content) { for (int i = 0; i < 16; i++) { int comValue = 1 << i; retList.Add((value & comValue) == comValue); } } return retList.Take(size).ToArray(); } protected override float[] ReadAiFloat(int offset, int size) { return null; } protected override short[] ReadAi(int offset, int size) { int address = offset + aiStartAddress; OperateResult ret; ret = _readerClient.ReadInt16(address.ToString(), (ushort)size); if (!ret.IsSuccess) return null; return ret.Content; } public override bool SetValue(AOAccessor aoItem, short value) { //if (!_trigConnected.M) // return false; int address = aoItem.Index + aoStartAddress; lock (_locker) { OperateResult ret = null; if (aoItem.Name.Contains("Inclination") || aoItem.Name.Contains("Position") || aoItem.Name.Contains("SoftUpLimit") || aoItem.Name.Contains("AfterReturnZero") || aoItem.Name.Contains("MoveDistance")) ret = _readerClient.Write(address.ToString(), Convert.ToInt16(value)); else ret = _readerClient.Write(address.ToString(), Convert.ToUInt16(value)); if (_enableLog) LOG.Write($"MPLC Write AO address:{ address} to { value},result:{ret.IsSuccess},message:{ret.Message}"); if (!ret.IsSuccess) LOG.Write($"MPLC failed to write AO address:{ address} to { value},result:{ret.IsSuccess},message:{ret.Message}"); return ret.IsSuccess; } } public override bool SetValue(DOAccessor doItem, bool value) { //if (!_trigConnected.M) // return false; lock (_locker) { int address = doItem.Index / 16 + doStartAddress; var ret = _readerClient.ReadInt16(address.ToString()); if (!ret.IsSuccess) return false; int valueSet = ret.Content; var val = 1 << (doItem.Index % 16); if ((ret.Content & val) == val) { if (!value) valueSet -= val; } else { if (value) valueSet += val; } var ret2 = _readerClient.Write(address.ToString(), Convert.ToUInt16(valueSet)); if (_enableLog) LOG.Write($"MPLC Write AO address:{ address} to { valueSet},result:{ret.IsSuccess},message:{ret.Message}"); return ret2.IsSuccess; } } protected override void Close() { try { _readerClient.Close(); _readerClient.Dispose(); } catch (Exception ex) { LOG.Write(ex.Message); } } protected override void Open() { _readerClient.Open(); try { _isConnected = _readerClient.IsOpen(); } catch (Exception ex) { IsCommunicationError = true; LOG.Write(ex.Message); } } public byte[] ReadResultRender(OperateResult result, string address) { byte[] buffer = new byte[32]; if (result.IsSuccess) { _connecteTimes = 0; IsCommunicationError = false; var dat2 = (Convert.ToUInt32(result.Content.ToString()) & 0xFFFF); var dat1 = (Convert.ToUInt32(result.Content.ToString()) >> 16 & 0xFFFF); uint[] data = new uint[] { dat1, dat2 }; for (int j = 0; j < 2; j++) { for (int i = 0; i < 16; i++) { buffer[j * 16 + i] = Convert.ToByte((data[j] >> i) & 0x01); } } string str = string.Join("", Array.ConvertAll(buffer, x => x.ToString())); if (_enableLog) LOG.Info($"Read Success,Data:{ str} ({ result.Content.ToString()}:{dat1}、{dat2})"); return buffer; } else { IsCommunicationError = true; EV.PostAlarmLog("System.PLC", $"[{address}] Read Failed {Environment.NewLine}Reason:{result.ToMessageShowString()}"); //MessageBox.Show(DateTime.Now.ToString("[HH:mm:ss] ") + $"[{address}] Read Failed {Environment.NewLine}Reason:{result.ToMessageShowString()}"); } return buffer; } public void WriteResultRender(OperateResult result, string address, int data, string str) { if (result.IsSuccess) { _connecteTimes = 0; IsCommunicationError = false; if (_enableLog) LOG.Info("Write Success,Data" + str + "(" + data.ToString() + ")"); } else { IsCommunicationError = true; EV.PostAlarmLog("System.PLC", $"[{address}] Write Failed {Environment.NewLine}Reason:{result.ToMessageShowString()}"); } } public bool InvokeReset(string arg1, object[] arg2) { _connecteTimes = 0; if (!_isConnected || IsCommunicationError) Open(); IsCommunicationError = false; return true; } protected override void WriteDo(int offset, bool[] buffer) { } protected override void WriteAo(int offset, short[] buffer) { } } }