using IPLCConnect; using S7.Net; using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; namespace S7Connect { [PLCProtocol( PLCProtocol.S7)] public sealed class S7 : IPLCConnect.IPLCConnect { public PLCProtocol Protocol => PLCProtocol.S7; [AllowNull] private Plc plc; private bool isConnected = false; private bool isfirst = true; public CpuType CpuType { get; set; } = CpuType.S71200; public Int16 Rack { get; set; } = 0; public Int16 Slot { get; set; } = 1; public bool IsConnected { get => isConnected; set { if (isConnected != value || isfirst) { isConnected = value; StatusChanged?.Invoke(this, value); } isfirst = false; } } public string IP { get; private set; } = "127.0.0.1"; public int Port { get; private set; } = 502; public event EventHandler StatusChanged; public void Connect() { if (plc == null) return; try { plc.Open(); IsConnected = plc.IsConnected; } catch { IsConnected = false; } } public void DisConnect() { if (plc == null) return; try { plc.Close(); } catch { } IsConnected = false; } public void Dispose() { try { plc?.Close(); } catch { } plc = null; } public void Init(string ip, int port) { try { IP = ip; plc = new Plc(this.CpuType, IP, Rack, Slot); } catch { } IsConnected = false; } public T Read(string addr) where T : unmanaged { try { if (plc == null || !plc.IsConnected) { IsConnected = false; return default; } if (string.IsNullOrEmpty(addr)) return default; object? value = plc.Read(addr); if (value == null) return default; if (typeof(T) == value.GetType()) return (T)value; switch (value) { case byte b: return Unsafe.As(ref b); case ushort us: return Unsafe.As(ref us); case uint ui: return Unsafe.As(ref ui); } return (T)plc.Read(addr)!; } catch { DisConnect(); } return default; } public void Write(string addr, T value) where T : unmanaged { if(plc ==null || !plc.IsConnected) { IsConnected = false; return; } if (string.IsNullOrEmpty(addr)) return; try { plc.Write(addr, value); } catch { DisConnect(); } } public bool ReadBit(string addr, byte bitindex) { if (string.IsNullOrEmpty(addr)) return false; return Read(addr); } public void Writebit(string addr, byte bitindex, bool value) { if (string.IsNullOrEmpty(addr)) return; Write(addr, value); } } }