using Sharp7; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace snap7Enc { public class Plc : IDisposable { private S7Client Client; /// /// IP address of the PLC /// public string IP { get; private set; } /// /// CPU type of the PLC /// public CpuType CPU { get; private set; } /// /// Rack of the PLC /// public Int16 Rack { get; private set; } /// /// Slot of the CPU of the PLC /// public Int16 Slot { get; private set; } /// /// Checks if the socket is connected and polls the other peer (the PLC) to see if it's connected. /// This is the variable that you should continously check to see if the communication is working /// See also: http://stackoverflow.com/questions/2661764/how-to-check-if-a-socket-is-connected-disconnected-in-c /// public bool IsConnected { get { try { return Client.Connected; } catch { return false; } } } /// /// Creates a PLC object with all the parameters needed for connections. /// For S7-1200 and S7-1500, the default is rack = 0 and slot = 0. /// You need slot > 0 if you are connecting to external ethernet card (CP). /// For S7-300 and S7-400 the default is rack = 0 and slot = 2. /// /// CpuType of the PLC (select from the enum) /// Ip address of the PLC /// rack of the PLC, usually it's 0, but check in the hardware configuration of Step7 or TIA portal /// slot of the CPU of the PLC, usually it's 2 for S7300-S7400, 0 for S7-1200 and S7-1500. /// If you use an external ethernet card, this must be set accordingly. public Plc(CpuType cpu, string ip, Int16 rack, Int16 slot) { if (!Enum.IsDefined(typeof(CpuType), cpu)) throw new ArgumentException($"The value of argument '{nameof(cpu)}' ({cpu}) is invalid for Enum type '{typeof(CpuType).Name}'.", nameof(cpu)); if (string.IsNullOrEmpty(ip)) throw new ArgumentException("IP address must valid.", nameof(ip)); CPU = cpu; IP = ip; Rack = rack; Slot = slot; Client = new S7Client(); } public byte[] ReadBytes(DataType dataType, int db, int startByteAdr, int count) { try { if (Client != null) { byte[] buffer = new byte[count]; if (dataType == DataType.DataBlock) { Client.DBRead(db, startByteAdr, count, buffer); return buffer; } } } catch (Exception ex) { Console.WriteLine("snap7读异常," + ex.Message + "," + ex.StackTrace); } return null; } public ErrorCode WriteBytes(DataType dataType, int db, int startByteAdr, byte[] value) { try { if (Client != null) { if (dataType == DataType.DataBlock) { int result = Client.DBWrite(db, startByteAdr, value.Length, value); if (result == 0) return ErrorCode.NoError; } } } catch(Exception ex) { Console.WriteLine("snap7写异常,"+ex.Message+","+ex.StackTrace); } return ErrorCode.ConnectionError; } /// /// Open connection to PLC /// public ErrorCode Open() { int result = -1; if (Client != null) { result = Client.ConnectTo(IP, Rack, Slot); } return result == 0 ? ErrorCode.NoError : ErrorCode.ConnectionError; } /// /// Close connection to PLC /// public void Close() { if (Client != null) { if (Client.Connected) Client.Disconnect(); } } #region IDisposable Support private bool disposedValue = false; // To detect redundant calls /// /// Dispose Plc Object /// /// protected virtual void Dispose(bool disposing) { if (!disposedValue) { if (disposing) { Close(); } // TODO: free unmanaged resources (unmanaged objects) and override a finalizer below. // TODO: set large fields to null. disposedValue = true; } } // TODO: override a finalizer only if Dispose(bool disposing) above has code to free unmanaged resources. // ~Plc() { // // Do not change this code. Put cleanup code in Dispose(bool disposing) above. // Dispose(false); // } // This code added to correctly implement the disposable pattern. void IDisposable.Dispose() { // Do not change this code. Put cleanup code in Dispose(bool disposing) above. Dispose(true); // TODO: uncomment the following line if the finalizer is overridden above. // GC.SuppressFinalize(this); } #endregion } }