using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Threading; using System.Threading.Tasks; using SystemX.Net.Platform.Common.Event; using SystemX.Net.Platform.Common.Util; using static SystemX.PLC.Interface.PLCCommDefinition; namespace SystemX.PLC.Interface.MxComponent { public class PLCCommMxCMgr : PLCCommManager { private int TimeOut; public Dictionary PLCManagers { get; set; } = new Dictionary(); public FunctionEventHandler EventAlwaysUpdate { get; set; } public PLCCommMxCMgr(string strPLCConnInfoXmlPath) : base(strPLCConnInfoXmlPath) { AddrMgr = new PLCAddressManager(strPLCConnInfoXmlPath); EventAlwaysUpdate = new FunctionEventHandler(); EventChangeUpdate = new FunctionEventHandler(); TimeOut = 0; foreach (PLCConnectionInfo coninfo in AddrMgr.ConnInfoDictionary.Values) { if (TimeOut < int.Parse(coninfo.Timeout)) TimeOut = int.Parse(coninfo.Timeout); PLCManagers.Add((ePLCRWType)Enum.Parse(typeof(ePLCRWType), coninfo.RWType), new PLCModMxCMgr(coninfo, EventAlwaysUpdate, EventChangeUpdate)); } } public override bool OpenPLCConnection() { Task openconn = new Task(() => TryOpenPLCConnection()); openconn.Start(); bool bResult = openconn.Result; if (bResult) { //Task plcoperation = openconn.ContinueWith(x => StartPLCOperation()); Task plcoperation = new Task(() => StartPLCOperation()); plcoperation.Start(); bResult = plcoperation.Result; } return bResult; /* if (plcoperation.Wait(TimeOut)) return true; else return false; */ } public bool TryOpenPLCConnection() { try { foreach (PLCModMxCMgr conmgr in PLCManagers.Values) { if (!conmgr.OpenDevice()) return false; Stopwatch stTimeOut = new Stopwatch(); stTimeOut.Start(); while (true) { if (conmgr.IsOpened == true) break; if (stTimeOut.ElapsedMilliseconds >= TimeOut) { LogMessage.MessageOutput.ConsoleWrite("PLC Connection Waiting TimeOut.", ConsoleColor.Red, LogMessage.LogMessageLevel.FATAL); return false; } Thread.Sleep(50); } SetAddress(conmgr, AddrMgr.OperationDictionary, true); SetAddress(conmgr, AddrMgr.DataDictionary, false); } LogMessage.MessageOutput.ConsoleWrite("PLC Connection Waiting for Success.", ConsoleColor.Blue, LogMessage.LogMessageLevel.NONE); return true; } catch (Exception ex) { LogMessage.MessageOutput.ConsoleWrite($"PLC Connection Open Error.\n - Error Message: {ex.Message}", ConsoleColor.Red, LogMessage.LogMessageLevel.FATAL); return false; } } private bool findType(ePLCRWType type) { var findValue = PLCManagers.FirstOrDefault(t => t.Key == type); if (findValue.Value != null) return true; else return false; } private PLCModMxCMgr findMgr(ePLCRWType type) { var findValue = PLCManagers.FirstOrDefault(t => t.Key == type); if (findValue.Value != null) return findValue.Value; else return null; } public override bool StartPLCOperation() { try { OperationStarted = true; if(findType(ePLCRWType.Read)) { findMgr(ePLCRWType.Read).SingleScanStartAsync(); findMgr(ePLCRWType.Read).StartMonitor(); } if (findType(ePLCRWType.ReadWrite)) { findMgr(ePLCRWType.ReadWrite).SingleScanStartAsync(); findMgr(ePLCRWType.ReadWrite).StartMonitor(); } LogMessage.MessageOutput.ConsoleWrite("PLC Operation has been Started.", ConsoleColor.Blue, LogMessage.LogMessageLevel.NONE); return true; } catch (Exception ex) { LogMessage.MessageOutput.ConsoleWrite($"PLC Connection Open Error.\n - Error Message: {ex.Message}", ConsoleColor.Red, LogMessage.LogMessageLevel.FATAL); return false; } } public override void NowScanDataArea() { if (findType(ePLCRWType.Read)) findMgr(ePLCRWType.Read).NowScanDataArea(); if (findType(ePLCRWType.ReadWrite)) findMgr(ePLCRWType.ReadWrite).NowScanDataArea(); } public override bool StopPLCOperation() { try { OperationStarted = false; if (findType(ePLCRWType.Read)) findMgr(ePLCRWType.Read).StopMonitor(); if (findType(ePLCRWType.ReadWrite)) findMgr(ePLCRWType.ReadWrite).StopMonitor(); LogMessage.MessageOutput.ConsoleWrite("PLC Operation has been Stopped.", ConsoleColor.Blue, LogMessage.LogMessageLevel.NONE); return true; } catch (Exception ex) { LogMessage.MessageOutput.ConsoleWrite($"PLC Connection Open Error.\n - Error Message: {ex.Message}", ConsoleColor.Red, LogMessage.LogMessageLevel.FATAL); return false; } } public override bool ClosePLCConnection() { try { foreach (PLCModMxCMgr conmgr in PLCManagers.Values) conmgr.CloseDevice(); OperationStarted = false; return true; } catch (Exception ex) { LogMessage.MessageOutput.ConsoleWrite($"PLC Connection Close Error.\n - Error Message: {ex.Message}", ConsoleColor.Red, LogMessage.LogMessageLevel.FATAL); return false; } } public void ReceivePLCEvent(PLCModMxCMgr sender, PLCAddressTemplate template) { if (template == null) return; if (IsMySubscription(template)) { ReceivePLCEvent(template.Address, template.RawValue[0]); } } public override void ReceivePLCEvent(string address, int value) { } public bool IsMySubscription(PLCAddressTemplate template) { if (AddrMgr.OperationDictionary.ContainsValue(template)) return true; if (AddrMgr.DataDictionary.ContainsValue(template)) return true; return false; } void SetAddress(PLCModMxCMgr module, Dictionary addressInfo, bool bOperation) { foreach (PLCAddressTemplate addrinfo in addressInfo.Values) module.AddDevices(addrinfo, bOperation); } public override void UpdateAll(bool bRefineWrongChar) { foreach (PLCModMxCMgr conmgr in PLCManagers.Values) { conmgr.UpdateArea(AddrMgr.OperationDictionary.Values.ToList(), bRefineWrongChar); conmgr.UpdateArea(AddrMgr.DataDictionary.Values.ToList(), bRefineWrongChar); } } public override void SelectUpdate(ePLCAreaType pat, PLCAddressTemplate tmplt, bool bRefineWrongChar) { if (pat == ePLCAreaType.Operation) { foreach (PLCModMxCMgr conmgr in PLCManagers.Values) { conmgr.UpdateSelectArea(tmplt, bRefineWrongChar); //conmgr.UpdateArea(AddrMgr.DataDictionary.Values.ToList(), bRefineWrongChar); } } if (pat == ePLCAreaType.Data) { foreach (PLCModMxCMgr conmgr in PLCManagers.Values) { //conmgr.UpdateArea(AddrMgr.OperationDictionary.Values.ToList(), bRefineWrongChar); conmgr.UpdateSelectArea(tmplt, bRefineWrongChar); } } } public override string GetDeviceValue(PLCAddressTemplate tmplt) { try { if (!CheckConnectionState(tmplt)) return string.Empty; string strReadValue = ""; if (findType(ePLCRWType.Read)) strReadValue = findMgr(ePLCRWType.Read).GetDeviceValue(tmplt); else if (findType(ePLCRWType.ReadWrite)) strReadValue = findMgr(ePLCRWType.ReadWrite).GetDeviceValue(tmplt); return strReadValue; } catch (Exception ex) { LogMessage.MessageOutput.ConsoleWrite($"PLC Manager is failed to Get Device Value. The Address: {tmplt.AddressKey} has not been read by unidentified errors. ", ConsoleColor.Red, LogMessage.LogMessageLevel.FATAL); LogMessage.MessageOutput.ConsoleWrite($" - Error Message: {ex.Message}", ConsoleColor.Red, LogMessage.LogMessageLevel.FATAL); return string.Empty; } } public override string ReadDevice(PLCAddressTemplate tmplt) { try { if (!CheckConnectionState(tmplt)) return string.Empty; string strReadValue = ""; if (findType(ePLCRWType.Read)) strReadValue = findMgr(ePLCRWType.Read).ReadDevice(tmplt); else if (findType(ePLCRWType.ReadWrite)) strReadValue = findMgr(ePLCRWType.ReadWrite).ReadDevice(tmplt); return strReadValue; } catch (Exception ex) { LogMessage.MessageOutput.ConsoleWrite($"PLC Manager is failed to Read Device. The Address: {tmplt.AddressKey} has not been read by unidentified errors. ", ConsoleColor.Red, LogMessage.LogMessageLevel.FATAL); LogMessage.MessageOutput.ConsoleWrite($" - Error Message: {ex.Message}", ConsoleColor.Red, LogMessage.LogMessageLevel.FATAL); return string.Empty; } } public override string ReadDevice(PLCAddressTemplate tmplt, bool bAsciiReverse = false) { try { if (!CheckConnectionState(tmplt)) return string.Empty; string strReadValue = ""; if (findType(ePLCRWType.Read)) strReadValue = findMgr(ePLCRWType.Read).ReadDevice(tmplt, bAsciiReverse); else if (findType(ePLCRWType.ReadWrite)) strReadValue = findMgr(ePLCRWType.ReadWrite).ReadDevice(tmplt, bAsciiReverse); return strReadValue; } catch (Exception ex) { LogMessage.MessageOutput.ConsoleWrite($"PLC Manager is failed to Read Device. The Address: {tmplt.AddressKey} has not been read by unidentified errors. ", ConsoleColor.Red, LogMessage.LogMessageLevel.FATAL); LogMessage.MessageOutput.ConsoleWrite($" - Error Message: {ex.Message}", ConsoleColor.Red, LogMessage.LogMessageLevel.FATAL); return string.Empty; } } public override bool WriteDevice(PLCAddressTemplate tmplt, string strValue, bool bVerification = false) { try { if (!CheckConnectionState(tmplt)) return false; if (findType(ePLCRWType.Write)) findMgr(ePLCRWType.Write).WriteDevice(tmplt, strValue); else if (findType(ePLCRWType.ReadWrite)) findMgr(ePLCRWType.ReadWrite).WriteDevice(tmplt, strValue); if (bVerification) { string strReadValue = ""; if (findType(ePLCRWType.Read)) strReadValue = findMgr(ePLCRWType.Read).ReadDevice(tmplt); else if (findType(ePLCRWType.ReadWrite)) strReadValue = findMgr(ePLCRWType.ReadWrite).ReadDevice(tmplt); if (strReadValue == strValue) { LogMessage.MessageOutput.ConsoleWrite($"The Address: {tmplt.PLCAddress} has not been written #Intent:{strValue} - #Actual:{tmplt.Value} by unidentified errors. ", ConsoleColor.Red, LogMessage.LogMessageLevel.NONE); return false; } } return true; } catch (Exception ex) { LogMessage.MessageOutput.ConsoleWrite($"PLC Manager is failed to Write Device. The Address: {tmplt.AddressKey} has not been written by unidentified errors. ", ConsoleColor.Red, LogMessage.LogMessageLevel.FATAL); LogMessage.MessageOutput.ConsoleWrite($" - Error Message: {ex.Message}", ConsoleColor.Red, LogMessage.LogMessageLevel.FATAL); return false; } } bool CheckConnectionState(PLCAddressTemplate tmplt) { try { int nCount = 0; bool bConError = false; if (!OperationStarted) { while (true) { if (OperationStarted || nCount > 100) { bConError = true; break; } nCount++; Thread.Sleep(100); } } if (bConError == true) { LogMessage.MessageOutput.ConsoleWrite($"PLC Connection Trouble has been detected. ", ConsoleColor.Red, LogMessage.LogMessageLevel.FATAL); LogMessage.MessageOutput.ConsoleWrite($"The Address: {tmplt.PLCAddress} has not been written. ", ConsoleColor.Red, LogMessage.LogMessageLevel.FATAL); return false; } return true; } catch (Exception) { throw; } } } }