using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Xml.Linq; using SystemX.Net.Platform.Common.Util; using static SystemX.PLC.Interface.PLCCommDefinition; using static SystemX.PLC.Model.ModelSetupTemplate; namespace SystemX.PLC.Interface { public class PLCAddressManager { public bool AutoConnection { get; set; } = false; public Dictionary DescriptionDictionary { get; set; } = new Dictionary(); public Dictionary DataDictionary { get; set; } = new Dictionary(); public Dictionary OperationDictionary { get; set; } = new Dictionary(); public Dictionary ConnInfoDictionary { get; set; } = new Dictionary(); public PLCAddressManager(string strPath) { LoadAddressXML(strPath); } public ePLCAreaType AddressSectionCheck(string strName) { if (DataDictionary.Values.Where(x => x.DataName == strName).ToList().Count > 0) return ePLCAreaType.Data; else if (OperationDictionary.Values.Where(x => x.DataName == strName).ToList().Count > 0) return ePLCAreaType.Operation; else return ePLCAreaType.None; } public bool IsDataSectionSignal(string strName) { if (DataDictionary.Values.Where(x => x.DataName == strName).ToList().Count > 0) return true; else return false; } public bool IsOperationSectionSignal(string strName) { if (OperationDictionary.Values.Where(x => x.DataName == strName).ToList().Count > 0) return true; else return false; } public PLCAddressTemplate FindDataDicPLCAddressElementByDataName(string strName) { List vtmplt = DataDictionary.Values.Where(x => x.DataName == strName).ToList(); List vOpTmplt = OperationDictionary.Values.Where(x => x.DataName == strName).ToList(); vtmplt = vtmplt.Union(vOpTmplt).ToList(); if (vtmplt.Count == 0) { LogMessage.MessageOutput.ConsoleWrite($"Cannot Find PLC Address which has a name as : {strName}.", ConsoleColor.Red, LogMessage.LogMessageLevel.FATAL); return null; } return vtmplt[0]; } public PLCAddressTemplate FindOperationPLCAddressElementByDataName(string strName) { List vtmplt = OperationDictionary.Values.Where(x => x.DataName == strName).ToList(); if (vtmplt.Count == 0) { LogMessage.MessageOutput.ConsoleWrite($"Cannot Find PLC Address which has a name as : {strName}.", ConsoleColor.Red, LogMessage.LogMessageLevel.FATAL); return null; } return vtmplt[0]; } public PLCAddressTemplate FindPLCOperationTemplateElementByPLCDevice(string PLCDevice) { List vTemplate = OperationDictionary.Values.Where(x => x.PLCAddress == PLCDevice).ToList(); if (vTemplate.Count <= 0) return null; return vTemplate[0]; } public PLCAddressTemplate FindPLCAddressElement(string strKey) { PLCAddressTemplate tmplt = null; if (DataDictionary.ContainsKey(strKey)) tmplt = DataDictionary[strKey]; else if (OperationDictionary.ContainsKey(strKey)) tmplt = OperationDictionary[strKey]; return tmplt; } public PLCAddressTemplate FindPLCAddressElementByDataName(string strDataName) { PLCAddressTemplate tmpltDataName = FindDataDicPLCAddressElementByDataName(strDataName); if (tmpltDataName == null) tmpltDataName = FindOperationPLCAddressElementByDataName(strDataName); return tmpltDataName; } public PLCAddressTemplate FindPLCAddressElementByAssociatedKeyAddress(string strKeyAddress, Dictionary dicResult) { List vResults = (from addrTmplt in dicResult.Values where addrTmplt.IsMyAssociation(strKeyAddress) select addrTmplt).ToList(); if (vResults.Count > 0) return vResults[0]; return null; } void LoadAddressXML(string strXmlPath) { if (!File.Exists(strXmlPath)) return; XDocument xDoc = XDocument.Load(strXmlPath); var xElement = xDoc.Element(PLCCommDefinition.ModelRoot); if (xElement == null) return; DescriptionDictionary = new Dictionary(); DataDictionary = new Dictionary(); OperationDictionary = new Dictionary(); ConnInfoDictionary = new Dictionary(); var xelemDescRoot = xElement.Element(PLCCommDefinition.DescriptionRoot); var xelemConRoot = xElement.Element(PLCCommDefinition.ConnectionInfoRoot); var xelemOpRoot = xElement.Element(PLCCommDefinition.OpearationAreaRoot); var xelemDataRoot = xElement.Element(PLCCommDefinition.DataAreaRoot); LoadXmlDataForDescTemplate(xelemDescRoot, DescriptionDictionary); LoadXmlDataForConninfoTemplate(xelemConRoot, ConnInfoDictionary); LoadXmlDataForDataTemplate(xelemOpRoot, OperationDictionary); LoadXmlDataForDataTemplate(xelemDataRoot, DataDictionary); AutoConnection = Convert.ToBoolean(xelemConRoot.Attribute("AutoConnection").Value); } void LoadXmlDataForDescTemplate(XElement xElemRoot, Dictionary dicResult) { foreach (XElement elem in xElemRoot.Elements()) { if (elem.Name != PLCCommDefinition.DescElement) continue; string strName = string.Empty; string strDataType = string.Empty; string strDesc = string.Empty; string strValue = elem.Value; GetDescAttributes(elem, ref strName, ref strDataType, ref strDesc); dicResult.Add(strName, new ModelElementData() { Name = strName, DataType = strDataType, Desc = strDesc }); } } void GetDescAttributes(XElement xElem, ref string strName, ref string strType, ref string strDesc) { strName = string.Empty; strType = string.Empty; strDesc = string.Empty; foreach (XAttribute xattrb in xElem.Attributes()) { if (xattrb.Name == PLCCommDefinition.AttrbName) strName = xattrb.Value; else if (xattrb.Name == PLCCommDefinition.AttrbDataType) strType = xattrb.Value; else if (xattrb.Name == PLCCommDefinition.AttrbDesc) strDesc = xattrb.Value; } } void LoadXmlDataForConninfoTemplate(XElement xElemRoot, Dictionary dicResult) { foreach (XElement elem in xElemRoot.Elements()) { if (elem.Name != PLCCommDefinition.ConnectionInfoElement) continue; Dictionary dicValue = new Dictionary(); GetAddrAttributes(elem, dicValue); dicResult.Add(dicValue[PLCCommDefinition.eConnectionElem.Name.ToString()], new PLCConnectionInfo() { Name = dicValue[PLCCommDefinition.eConnectionElem.Name.ToString()], CPUType = dicValue[PLCCommDefinition.eConnectionElem.CPUType.ToString()], RWType = dicValue[PLCCommDefinition.eConnectionElem.RWType.ToString()], IP = dicValue[PLCCommDefinition.eConnectionElem.IP.ToString()], Port = dicValue[PLCCommDefinition.eConnectionElem.Port.ToString()], ConnectionType = dicValue[PLCCommDefinition.eConnectionElem.ConnectionType.ToString()], Timeout = dicValue[PLCCommDefinition.eConnectionElem.Timeout.ToString()] }); } } void LoadXmlDataForDataTemplate(XElement xElemRoot, Dictionary dicResult) { try { foreach (XElement elem in xElemRoot.Elements()) { if (elem.Name != PLCCommDefinition.AddrElement) continue; Dictionary dicValue = new Dictionary(); GetAddrAttributes(elem, dicValue); dicResult.Add(dicValue[PLCCommDefinition.AttrbAddrArea] + dicValue[PLCCommDefinition.AttrbAddrAddress], new PLCAddressTemplate() { Area = dicValue[PLCCommDefinition.AttrbAddrArea], Address = dicValue[PLCCommDefinition.AttrbAddrAddress], Length = dicValue[PLCCommDefinition.AttrbAddrLength], DataName = dicValue[PLCCommDefinition.AttrbAddrDataName], DataType = dicValue[PLCCommDefinition.AttrbAddrDataType], Operation = dicValue[PLCCommDefinition.AttrbAddrOperation], Desc = dicValue[PLCCommDefinition.AttrbAddrDesc] }); dicResult[dicValue[PLCCommDefinition.AttrbAddrArea] + dicValue[PLCCommDefinition.AttrbAddrAddress]].SetAssocationKeys(); } } catch (Exception ex) { LogMessage.MessageOutput.ConsoleWrite($"Error occured in LoadXmlDataForDataTemplate. \n - Error Message: {ex.Message}"); } } void GetAddrAttributes(XElement xElem, Dictionary dicValue) { foreach (XAttribute xattrb in xElem.Attributes()) dicValue.Add(xattrb.Name.ToString(), xattrb.Value); } } }