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); } }
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); } } } }
void makeIedModelFromIecModel(Iec61850Model model, NodeBase iec) { foreach (NodeBase child in iec.GetChildNodes()) { if ((child is NodeData && !(child is NodeDO)) || child is NodeVLM) { // First DataAttribute child // Create the whole path down to Ied List <NodeBase> path = new List <NodeBase>(); NodeBase nb = child.Parent; while (nb != null && !(nb is NodeIed)) { path.Add(nb); nb = nb.Parent; } NodeBase subtree = model.ied; string fc = ""; if (child is NodeData && !(child is NodeDO)) { fc = (child as NodeData).SCL_FCDesc; if (String.IsNullOrEmpty(fc)) { logger.LogError("FC is empty for DataAttribute: " + child.IecAddress); continue; } } path.Reverse(); foreach (NodeBase pnb in path) { if (pnb is NodeLD) { subtree = subtree.AddChildNode(new NodeLD(pnb.Name)); } else if (pnb is NodeLN) { subtree = subtree.AddChildNode(new NodeLN(pnb.Name)); // Inserting the FC level if (!String.IsNullOrEmpty(fc)) // due to VLM { subtree = subtree.AddChildNode(new NodeFC(fc)); } } else if (pnb is NodeDO) { subtree = subtree.AddChildNode(new NodeDO(pnb.Name)); } else if (pnb is NodeRCB) { subtree = subtree.AddChildNode(new NodeRCB(pnb.Name)); (subtree as NodeRCB).isBuffered = (pnb as NodeRCB).isBuffered; if ((pnb as NodeRCB).isBuffered) { model.brcbs.AddChildNode(new NodeLD(path[0].Name)).LinkChildNodeByName(subtree); } else { model.urcbs.AddChildNode(new NodeLD(path[0].Name)).LinkChildNodeByName(subtree); } } else if (pnb is NodeVL) { //subtree = subtree.AddChildNode(new NodeVL(pnb.Name)); model.lists.AddChildNode(new NodeLD(path[0].Name)).LinkChildNodeByName(pnb); } } if (!(child is NodeVLM)) { subtree.LinkChildNodeByName(child); } else { // Fill the gap -> find the link for VLM nodes (child as NodeVLM).LinkedNode = model.iec.FindSubNode(child.Name); if ((child as NodeVLM).LinkedNode == null) { logger.LogWarning("DataSet " + child.Parent.IecAddress + ": node " + child.Name + " not found in the model!"); } } } else { // Recursive call makeIedModelFromIecModel(model, child); } } }