using System; using System.Threading.Tasks; using System.Net.NetworkInformation; using System.Threading; using SystemX.Net.Platform.Common.Event; using SystemX.Net.Platform.Common.Util; using static SystemX.PLC.Interface.PLCCommDefinition; namespace SystemX.PLC.Interface { /// /// Example to represent how to build a device manager. /// A Device Manager constructs a device in run-time environment using a defined dll name in the configuration xml. /// The named dll for a device is bound in run-time environment as well. /// Device manager is an inherited class from a CpDeviceManagerBase and a corresponding interface. /// public class PLCModMgr { public event EventPLCHandler EventPLC; public FunctionEventHandler FuncEvtHndl; public PLCDevice plcDev; public PLCConnectionInfo PLCInfo; public bool IsOpened { get; set; } = false; public PLCModMgr(PLCConnectionInfo infoinput) { PLCInfo = infoinput; } public bool CloseDevice() { bool bResult = plcDev.DevClose(); IsOpened = !bResult; return true; } public bool OpenDevice() { if (IsOpened == true) return IsOpened; plcDev = new PLCDevice(); FuncEvtHndl = new FunctionEventHandler(); //FuncEvtHndl.OnReceive += FuncEvtHndl_OnPLCReceive; plcDev.FuncEvtHndl = FuncEvtHndl; plcDev.DeviceID = PLCInfo.Name; plcDev.CPU_TYPE_STR = PLCInfo.CPUType; plcDev.PLC_IP_ADDR = PLCInfo.IP; plcDev.PLC_PORT_NUMBER = Convert.ToInt32(PLCInfo.Port); plcDev.CONNECTION_TYPE_STR = PLCInfo.ConnectionType != "UDP" ? "TCP" : "UDP"; plcDev.READPORT = (PLCInfo.RWType == PLCCommDefinition.ePLCRWType.Read.ToString()) ? true : false; plcDev.TIMEOUT = Convert.ToInt32(PLCInfo.Timeout); Task conPing = new Task(() => PingToPLC()); conPing.Start(); Task conPLC = conPing.ContinueWith(x => ConnectToPLC()); return true; } public bool PingToPLC() { try { Ping pingtoPLC = new Ping(); int nCount = 0; while (true) { PingReply reply = pingtoPLC.Send(PLCInfo.IP); if (reply.Status == IPStatus.Success) break; LogMessage.MessageOutput.ConsoleWrite($"PLC Connection Failed. Retry #{nCount} - IP:{PLCInfo.IP}, Port:{PLCInfo.Port}", ConsoleColor.Red, LogMessage.LogMessageLevel.FATAL); Thread.Sleep(1000); nCount++; } return true; } catch (Exception ex) { LogMessage.MessageOutput.ConsoleWrite($" - PLC Connection error: {PLCInfo.Name}, {PLCInfo.IP}:{PLCInfo.Port} - {PLCInfo.ConnectionType}", ConsoleColor.Blue, LogMessage.LogMessageLevel.NONE); LogMessage.MessageOutput.ConsoleWrite($" -> Reason: {ex.Message}", ConsoleColor.Blue, LogMessage.LogMessageLevel.NONE); throw; } } public bool ConnectToPLC() { try { IsOpened = plcDev.DevOpen(); if (IsOpened == false) plcDev = null; LogMessage.MessageOutput.ConsoleWrite($"PLC Connection Success. - IP:{PLCInfo.IP}, Port:{PLCInfo.Port} ", ConsoleColor.Green, LogMessage.LogMessageLevel.NONE); return IsOpened; } catch (Exception ex) { LogMessage.MessageOutput.ConsoleWrite($" - PLC Connection error: {PLCInfo.Name}, {PLCInfo.IP}:{PLCInfo.Port} - {PLCInfo.ConnectionType}", ConsoleColor.Blue, LogMessage.LogMessageLevel.NONE); LogMessage.MessageOutput.ConsoleWrite($" -> Reason: {ex.Message}", ConsoleColor.Blue, LogMessage.LogMessageLevel.NONE); throw; } } private void FuncEvtHndl_OnPLCReceive(object sender, string data) { if (data.Contains(";")) { string address = data.Split(';')[0]; int value = Convert.ToInt32(data.Split(';')[1]); EventPLC?.Invoke(address, value); } } public async Task SingleScanStartAsync() { if (!IsOpened) return; await plcDev.SingleScanStartAsync(); } public bool AddDevices(string deviceNames) { if (!IsOpened) return false; return plcDev.AddDevices(deviceNames); } public int ReadDevice(string deviceName) { try { if (!IsOpened) return -1; return plcDev.ReadDevice(deviceName); } catch (Exception ex) { LogMessage.MessageOutput.ConsoleWrite($"PLC Device Reading Error: {deviceName}", ConsoleColor.Red, LogMessage.LogMessageLevel.NONE); LogMessage.MessageOutput.ConsoleWrite($" - Detail: {ex.Message}", ConsoleColor.Red, LogMessage.LogMessageLevel.NONE); throw; } } public bool WriteDevice(string deviceName, int value) { if (!IsOpened) return false; return plcDev.WriteDevice(deviceName, value); } public bool WriteBitDevice(string deviceName, int[] value) { if (!IsOpened) return false; return plcDev.WriteBitDevice(deviceName, value); } } }