void recursiveLinkDA(NodeBase source, NodeBase target, NodeFC fc) { NodeBase linkedDa = target.LinkChildNodeByName(source); // Set FC if (linkedDa is NodeData && !(linkedDa is NodeDO)) { (linkedDa as NodeData).SCL_FCDesc = fc.Name; } // Check DO / DA types if (linkedDa != source) { // We are in a DA once again // That means this is a DO and not a DA // We have to create DO and add it to the iec model (target) // and replace linkedDa with this object NodeDO ido = new NodeDO(source.Name); ido.IsIecModel = true; target.RemoveChildNode(source); linkedDa = target.AddChildNode(ido); } foreach (NodeBase newSource in source.GetChildNodes()) { recursiveLinkDA(newSource, linkedDa, fc); } }
/// <summary> /// Creates a DO Type node from parsed XML /// </summary> /// <param name="reader"></param> /// <returns> a DO node representing a DOType </returns> private void CreateDataObjectTypes(List <NodeBase> list, IEnumerable <XElement> elements, XNamespace ns) { foreach (XElement el in elements) { NodeDO dataObject = new NodeDO(el.Attribute("id").Value); // SDOs foreach (XElement sdoel in el.Elements(ns + "SDO")) { NodeDO subDataObject = new NodeDO(sdoel.Attribute("name").Value); int cnt = 0; if (sdoel.Attribute("count") != null) { int.TryParse(sdoel.Attribute("count").Value, out cnt); } subDataObject.SCL_ArraySize = cnt; if (sdoel.Attribute("type") != null) { subDataObject.SCL_Type = sdoel.Attribute("type").Value; } dataObject.AddChildNode(subDataObject); } // DAs CreateDataAttributes(dataObject, el.Elements(ns + "DA"), ns); list.Add(dataObject); } }
/// <summary> /// Create a DO from parsed XML /// </summary> /// <param name="reader"></param> /// <returns> a DO Node representing a DO </returns> private void CreateDataObjects(NodeBase root, IEnumerable <XElement> elements, XNamespace ns) { foreach (XElement el in elements) { NodeDO dataObject = new NodeDO(el.Attribute("name").Value); var type = el.Attribute("type"); if (type != null) { dataObject.SCL_Type = type.Value; } root.AddChildNode(dataObject); } }
/// <summary> /// Creates a DO Type node from parsed XML /// </summary> /// <param name="reader"></param> /// <returns> a DO node representing a DOType </returns> private NodeDO CreateDigitalObjectType(XmlReader reader) { reader.Read(); var digitalObjectType = new NodeDO(reader.GetAttribute("id")); while (reader.Read()) { if (reader.IsStartElement() && reader.Name.Equals("DA")) { digitalObjectType.AddChildNode(CreateDataAttribute(reader.ReadSubtree())); } } return(digitalObjectType); }
/// <summary> /// Create a DO from parsed XML /// </summary> /// <param name="reader"></param> /// <returns> a DO Node representing a DO </returns> private NodeDO CreateDigitalObject(XmlReader reader) { reader.Read(); var digitalObject = new NodeDO(reader.GetAttribute("name")); if (reader.AttributeCount > 1) { digitalObject.SCL_Type = reader.GetAttribute("type"); } while (reader.Read()) { if (reader.IsStartElement() && reader.Name.Equals("DAI")) { digitalObject.AddChildNode(CreateDataAttribute(reader.ReadSubtree())); } } digitalObject.SortImmediateChildren(); return(digitalObject); }
void createData(NodeBase dt, ModelNode mn) { ModelNode newmn = null; NodeBase iter = null; bool isArr = false; if (dt is NodeDO) { NodeDO dO = (dt as NodeDO); isArr = dO.SCL_ArraySize > 0; newmn = new DataObject(dt.Name, mn, dO.SCL_ArraySize); } else if (dt is NodeData && !(dt is NodeDO)) { // dt is NodeDA NodeData dA = (NodeData)dt; isArr = dA.SCL_ArraySize > 0; FunctionalConstraint fc = DataAttribute.fcFromString(dA.SCL_FCDesc); IEC61850.Server.DataAttributeType t = DataAttribute.typeFromSCLString(dA.SCL_BType); newmn = new DataAttribute(dt.Name, mn, t, fc, dA.SCL_TrgOps, dA.SCL_ArraySize, 0); logger.LogDebug("DataAttribute " + dt.IecAddress + " TrgOps:" + dA.SCL_TrgOps.ToString()); } dt.SCLServerModelObject = newmn; if (isArr) { iter = dt.GetChildNode(0); } else { iter = dt; } foreach (NodeBase nb in iter.GetChildNodes()) { // Recursion createData(nb, newmn); } }
public void BuildIECModelFromMMSModel() { iec.DefineNVL = ied.DefineNVL; iec.Revision = ied.Revision; iec.VendorName = ied.VendorName; iec.ModelName = ied.ModelName; foreach (NodeLD ld in ied.GetChildNodes()) // LD level { NodeLD ild = new NodeLD(ld.Name); ild.IsIecModel = true; ild = (NodeLD)iec.AddChildNode(ild); foreach (NodeLN ln in ld.GetChildNodes()) // LN level { NodeLN iln = new NodeLN(ln.Name); iln.IsIecModel = true; iln = (NodeLN)ild.AddChildNode(iln); foreach (NodeFC fc in ln.GetChildNodes()) // FC level - skipping { if (fc.Name == "RP" || fc.Name == "BR") { continue; } // keep knowing FC for DA foreach (NodeDO dO in fc.GetChildNodes()) // DO level { NodeDO ido = new NodeDO(dO.Name); ido.IsIecModel = true; // AddChildNode returns original object if the same name found (new object is forgotten) ido = (NodeDO)iln.AddChildNode(ido); // At this point, it can happen that we get DO more than once (same DO in several FC) // For DOs, this is ok, FC is not relevant for DOs // Next level is peculiar: can be DO (subDataObject) or a DA // At this point, we will distinguish between DO and DA as follows: // At the first guess, we suppose DA // We will LINK the corresponding DA from MMS tree, and record the FC // If another object with the same name comes in (from another FC branch in MMS tree) // That means that we are not DA but DO (multiple FCs) // And this all has to be done recursively foreach (NodeBase da in dO.GetChildNodes()) { recursiveLinkDA(da, ido, fc); } } } } } // Add rcbs to LNs foreach (NodeLD ld in urcbs.GetChildNodes()) // LD level { foreach (NodeRCB urcb in ld.GetChildNodes()) { NodeBase ln = iec.FindNodeByAddress(ld.Name, urcb.Name.Remove(urcb.Name.IndexOf("$"))); if (ln != null) { ln.LinkChildNodeByName(urcb); } } } foreach (NodeLD ld in brcbs.GetChildNodes()) // LD level { foreach (NodeRCB brcb in ld.GetChildNodes()) { NodeBase ln = iec.FindNodeByAddress(ld.Name, brcb.Name.Remove(brcb.Name.IndexOf("$"))); if (ln != null) { ln.LinkChildNodeByName(brcb); } } } // Add datasets to LNs foreach (NodeLD ld in lists.GetChildNodes()) // LD level { foreach (NodeVL vl in ld.GetChildNodes()) { NodeBase ln = iec.FindNodeByAddress(ld.Name, vl.Name.Remove(vl.Name.IndexOf("$"))); if (ln != null) { ln.LinkChildNodeByName(vl); } } } }
/// <summary> /// Creates a logical node (LN) and all of its children, including /// FCs, DO's, and DA's /// </summary> /// <param name="reader"></param> /// <returns> a LN node </returns> private NodeLN CreateLogicalNode2(XmlReader reader) { reader.Read(); var prefix = reader.GetAttribute("prefix"); var lnClass = reader.GetAttribute("lnClass"); var inst = reader.GetAttribute("inst"); var type = reader.GetAttribute("lnType"); // LN name is a combination of prefix, lnCLass, and inst var name = !String.IsNullOrWhiteSpace(prefix) ? String.Concat(prefix, lnClass, inst) : String.Concat(lnClass, inst); NodeLN logicalNode = new NodeLN(name); logicalNode.TypeId = type; Hashtable functionalConstraints = new Hashtable(); NodeBase nodeType; try { nodeType = _nodeTypes.Single(nt => nt.Name.Equals(type)); } catch (Exception e) { logger.LogError("SCL Parser: LN type template not found: " + type.ToString() + ", for Node: " + name.ToString() + ", Exception: " + e.Message); return(null); } // for each DO in the LNodeType foreach (var dataObject in nodeType.GetChildNodes()) { NodeBase doType = null; try { doType = _dataObjectTypes.Single(dot => dot.Name.Equals((dataObject as NodeDO).SCL_Type)); } catch (Exception e) { logger.LogError("SCL Parser: DO type template not found: " + (dataObject as NodeDO).SCL_Type + ", for LN type: " + nodeType.Name + ", in node: " + name.ToString() + ", Exception: " + e.Message); continue; } // for each DA in the DOType foreach (var dataAttribute in doType.GetChildNodes()) { var fc = (dataAttribute as NodeData).SCL_FCDesc; (dataAttribute as NodeData).SCL_DOName = dataObject.Name; NodeData newNode = new NodeData(dataAttribute.Name); newNode.SCL_Type = (dataAttribute as NodeData).SCL_Type; newNode.SCL_BType = (dataAttribute as NodeData).SCL_BType; newNode.SCL_DOName = (dataAttribute as NodeData).SCL_DOName; newNode.SCL_FCDesc = (dataAttribute as NodeData).SCL_FCDesc; // when the type is specified (ie. when it's a struct), get the struct child nodes if (!String.IsNullOrWhiteSpace(newNode.SCL_Type)) { var dataType = _dataAttributeTypes.Single(dat => dat.Name.Equals((newNode.SCL_Type))); foreach (NodeBase child in dataType.GetChildNodes()) { var tempChild = new NodeData(child.Name); tempChild.SCL_BType = (child as NodeData).SCL_BType; if (!String.IsNullOrWhiteSpace((child as NodeData).SCL_Type)) { var subDataType = _dataAttributeTypes.Single(dat => dat.Name.Equals((child as NodeData).SCL_Type)); foreach (NodeBase subChild in subDataType.GetChildNodes()) { var tempSubChild = new NodeData(subChild.Name); tempSubChild.SCL_BType = (subChild as NodeData).SCL_BType; tempChild.AddChildNode(subChild); } } newNode.AddChildNode(tempChild); } } if (!functionalConstraints.ContainsKey(fc)) { NodeFC nodeFC = new NodeFC(fc); nodeFC.ForceAddChildNode(newNode); functionalConstraints.Add(fc, nodeFC); } else { (functionalConstraints[fc] as NodeBase).ForceAddChildNode(newNode); } } } // for each hashtable element foreach (var key in functionalConstraints.Keys) { var doList = new List <NodeDO>(); // for each data attribute of the functional constraint foreach (var da in (functionalConstraints[key] as NodeBase).GetChildNodes()) { var doName = (da as NodeData).SCL_DOName; if (doList.Exists(x => x.Name.Equals(doName))) { doList.Single(x => x.Name.Equals(doName)).AddChildNode(da); } else { var temp = new NodeDO(doName); temp.AddChildNode(da); doList.Add(temp); } } var nodeFC = new NodeFC(key as string); foreach (NodeDO x in doList) { nodeFC.AddChildNode(x); } nodeFC.SortImmediateChildren(); // alphabetical logicalNode.AddChildNode(nodeFC); } logicalNode.SortImmediateChildren(); // alphabetical return(logicalNode); }
private void CreateSDO_DA(NodeBase dataObject, NodeBase doType) { // for each DA in the DOType foreach (var dataAttribute in doType.GetChildNodes()) { if (dataAttribute is NodeDO) { // SDO (sub Data Object) NodeBase subDoType = null; try { subDoType = _dataObjectTypes.Single(dot => dot.Name.Equals((dataAttribute as NodeDO).SCL_Type)); } catch (Exception e) { logger.LogError("SCL Parser: SDO type template not found: " + (dataAttribute as NodeDO).SCL_Type + ", for DO type: " + doType.Name + ", for LN type: " + doType.Parent.Name + ", in node: " + dataObject.Parent.Name + ", Exception: " + e.Message); continue; } NodeDO subDataObject = new NodeDO(dataAttribute.Name); subDataObject.SCL_ArraySize = (dataAttribute as NodeDO).SCL_ArraySize; dataObject.AddChildNode(subDataObject); if (subDataObject.SCL_ArraySize > 0) { for (int i = 0; i < subDataObject.SCL_ArraySize; i++) { NodeDO arrDataObject = new NodeDO("[" + i.ToString() + "]"); subDataObject.AddChildNode(arrDataObject); arrDataObject.SCL_UpperDOName = dataObject.Name; foreach (var dataAttribute2 in subDoType.GetChildNodes()) { if (dataAttribute2 is NodeDO) { CreateSDO_DA(arrDataObject, subDoType); } else { CreateDataAttributesIEC(arrDataObject, dataAttribute2); } } } } else { foreach (var dataAttribute2 in subDoType.GetChildNodes()) { if (dataAttribute2 is NodeDO) { CreateSDO_DA(subDataObject, subDoType); } else { CreateDataAttributesIEC(subDataObject, dataAttribute2); } } } } if (dataAttribute is NodeData && !(dataAttribute is NodeDO)) { CreateDataAttributesIEC(dataObject, dataAttribute); } } }