/// <summary> /// Reads through a report subtree and creates a report from it /// </summary> /// <param name="reader"></param> /// <param name="nodeName"></param> /// <param name="deviceName"></param> /// <returns> a RP node </returns> private void CreateReports(NodeBase lnode, IEnumerable <XElement> elements, XNamespace ns) { if (lnode == null || elements == null || lnode.Parent == null || lnode.Parent.Parent == null) { Logger.getLogger().LogError("CreateReports: Something is null"); } // We are at the LN level, up 2 levels is an ied Iec61850Model _dataModel = (lnode.Parent.Parent as NodeIed).Model; foreach (XElement el in elements) { List <NodeRCB> nodeRCBs = new List <NodeRCB>(); XAttribute a = el.Attribute("buffered"); bool buffered = a != null ? (a.Value.ToLower() == "true") : false; string fc = buffered ? "BR" : "RP"; a = el.Attribute("indexed"); bool indexed = a != null ? (a.Value.ToLower() == "true") : true; // default true??? uint maxRptEnabled = 1; XElement xeRptEnabled = el.Element(ns + "RptEnabled"); if (xeRptEnabled != null) { a = xeRptEnabled.Attribute("max"); try { maxRptEnabled = uint.Parse(a.Value); } catch { } } // correction necessary??? if (!indexed) { maxRptEnabled = 1; } if (maxRptEnabled < 1) { maxRptEnabled = 1; } if (maxRptEnabled > 99) { maxRptEnabled = 99; } for (int i = 0; i < maxRptEnabled; i++) { nodeRCBs.Add(new NodeRCB(el.Attribute("name").Value + (indexed ? (i + 1).ToString("D2") : ""))); lnode.AddChildNode(nodeRCBs[i]); nodeRCBs[i].isBuffered = buffered; } // rptID NodeData RptId = new NodeData("RptID"); RptId.SCL_FCDesc = fc; RptId.DataType = scsm_MMS_TypeEnum.visible_string; a = el.Attribute("rptID"); RptId.DataValue = a != null ? a.Value : ""; // datSet NodeData DatSet = new NodeData("DatSet"); DatSet.SCL_FCDesc = fc; DatSet.DataType = scsm_MMS_TypeEnum.visible_string; a = el.Attribute("datSet"); DatSet.DataValue = a != null ? a.Value : null; // null accepted // confRev NodeData ConfRev = new NodeData("ConfRev"); ConfRev.SCL_FCDesc = fc; ConfRev.DataType = scsm_MMS_TypeEnum.unsigned; a = el.Attribute("confRev"); try { ConfRev.DataValue = uint.Parse(a.Value); } catch { ConfRev.DataValue = (uint)1; } // bufTime NodeData BufTm = new NodeData("BufTm"); BufTm.SCL_FCDesc = fc; BufTm.DataType = scsm_MMS_TypeEnum.unsigned; a = el.Attribute("bufTime"); try { BufTm.DataValue = uint.Parse(a.Value); } catch { BufTm.DataValue = (uint)0; } // intgPd NodeData IntgPd = new NodeData("IntgPd"); IntgPd.SCL_FCDesc = fc; IntgPd.DataType = scsm_MMS_TypeEnum.unsigned; a = el.Attribute("intgPd"); try { IntgPd.DataValue = uint.Parse(a.Value); } catch { IntgPd.DataValue = (uint)0; } // <TrgOps dchg="true" qchg="false" dupd="false" period="true" /> NodeData TrgOps = new NodeData("TrgOps"); TrgOps.SCL_FCDesc = fc; TrgOps.DataType = scsm_MMS_TypeEnum.integer; IEC61850.Common.TriggerOptions trgOptions = IEC61850.Common.TriggerOptions.NONE; XElement xeTrgOps = el.Element(ns + "TrgOps"); if (xeTrgOps != null) { a = xeTrgOps.Attribute("dchg"); if ((a != null ? a.Value : "false").ToLower() == "true") { trgOptions |= IEC61850.Common.TriggerOptions.DATA_CHANGED; } a = xeTrgOps.Attribute("qchg"); if ((a != null ? a.Value : "false").ToLower() == "true") { trgOptions |= IEC61850.Common.TriggerOptions.QUALITY_CHANGED; } a = xeTrgOps.Attribute("dupd"); if ((a != null ? a.Value : "false").ToLower() == "true") { trgOptions |= IEC61850.Common.TriggerOptions.DATA_UPDATE; } a = xeTrgOps.Attribute("period"); if ((a != null ? a.Value : "false").ToLower() == "true") { trgOptions |= IEC61850.Common.TriggerOptions.INTEGRITY; } a = xeTrgOps.Attribute("gi"); if ((a != null ? a.Value : "true").ToLower() == "true") // default true { trgOptions |= IEC61850.Common.TriggerOptions.GI; } } TrgOps.DataValue = trgOptions; // <OptFields seqNum="true" timeStamp="true" dataSet="true" reasonCode="true" dataRef="false" entryID="true" configRef="true" bufOvfl="true" /> NodeData OptFlds = new NodeData("OptFlds"); OptFlds.SCL_FCDesc = fc; OptFlds.DataType = scsm_MMS_TypeEnum.integer; IEC61850.Common.ReportOptions rptOptions = IEC61850.Common.ReportOptions.NONE; XElement xeOptFields = el.Element(ns + "OptFields"); if (xeOptFields != null) { a = xeOptFields.Attribute("seqNum"); if ((a != null ? a.Value : "false").ToLower() == "true") { rptOptions |= IEC61850.Common.ReportOptions.SEQ_NUM; } a = xeOptFields.Attribute("timeStamp"); if ((a != null ? a.Value : "false").ToLower() == "true") { rptOptions |= IEC61850.Common.ReportOptions.TIME_STAMP; } a = xeOptFields.Attribute("dataSet"); if ((a != null ? a.Value : "false").ToLower() == "true") { rptOptions |= IEC61850.Common.ReportOptions.DATA_SET; } a = xeOptFields.Attribute("reasonCode"); if ((a != null ? a.Value : "false").ToLower() == "true") { rptOptions |= IEC61850.Common.ReportOptions.REASON_FOR_INCLUSION; } a = xeOptFields.Attribute("dataRef"); if ((a != null ? a.Value : "false").ToLower() == "true") { rptOptions |= IEC61850.Common.ReportOptions.DATA_REFERENCE; } a = xeOptFields.Attribute("entryID"); if ((a != null ? a.Value : "false").ToLower() == "true") { rptOptions |= IEC61850.Common.ReportOptions.ENTRY_ID; } a = xeOptFields.Attribute("configRef"); if ((a != null ? a.Value : "false").ToLower() == "true") { rptOptions |= IEC61850.Common.ReportOptions.CONF_REV; } a = xeOptFields.Attribute("bufOvfl"); if ((a != null ? a.Value : "false").ToLower() == "true") { rptOptions |= IEC61850.Common.ReportOptions.BUFFER_OVERFLOW; } } OptFlds.DataValue = rptOptions; for (int i = 0; i < maxRptEnabled; i++) { nodeRCBs[i].AddChildNode(RptId); nodeRCBs[i].AddChildNode(DatSet); nodeRCBs[i].AddChildNode(ConfRev); nodeRCBs[i].AddChildNode(OptFlds); nodeRCBs[i].AddChildNode(BufTm); nodeRCBs[i].AddChildNode(TrgOps); nodeRCBs[i].AddChildNode(IntgPd); } } }
/// <summary> /// Creates a DA node from parsed XML /// </summary> /// <param name="reader"></param> /// <returns></returns> private void CreateDataAttributes(NodeBase root, IEnumerable <XElement> elements, XNamespace ns) { foreach (XElement el in elements) { if (el.Attribute("name") != null) { NodeData data = new NodeData(el.Attribute("name").Value); if (el.Attribute("fc") != null) { data.SCL_FCDesc = el.Attribute("fc").Value; } else if (root is NodeData && !(root is NodeDO)) { data.SCL_FCDesc = (root as NodeData).SCL_FCDesc; } var bType = el.Attribute("bType"); if (bType == null) { XElement en = el.Element(ns + "Val"); if (en != null) { data.DataValue = en.Value; } // Inheritance if (root is NodeData && !(root is NodeDO)) { data.SCL_BType = (root as NodeData).SCL_BType; } } else { data.SCL_BType = bType.Value; if (data.SCL_BType.Equals("Struct") && null != el.Attribute("type")) { data.SCL_Type = el.Attribute("type").Value; } else if (data.SCL_BType.Equals("Enum")) { data.SCL_BType = String.Concat(data.SCL_BType, " (Integer)"); if (null != el.Attribute("type")) { data.SCL_Type = el.Attribute("type").Value; } } } IEC61850.Common.TriggerOptions trgOptions = IEC61850.Common.TriggerOptions.NONE; XAttribute a = el.Attribute("dchg"); if ((a != null ? a.Value : "false").ToLower() == "true") { trgOptions |= IEC61850.Common.TriggerOptions.DATA_CHANGED; } a = el.Attribute("qchg"); if ((a != null ? a.Value : "false").ToLower() == "true") { trgOptions |= IEC61850.Common.TriggerOptions.QUALITY_CHANGED; } a = el.Attribute("dupd"); if ((a != null ? a.Value : "false").ToLower() == "true") { trgOptions |= IEC61850.Common.TriggerOptions.DATA_UPDATE; } data.SCL_TrgOps = (byte)trgOptions; // Inheritance if ((root is NodeData && !(root is NodeDO)) && trgOptions == IEC61850.Common.TriggerOptions.NONE) { data.SCL_TrgOps = (root as NodeData).SCL_TrgOps; } int cnt = 0; if (el.Attribute("count") != null) { int.TryParse(el.Attribute("count").Value, out cnt); } data.SCL_ArraySize = cnt; root.AddChildNode(data); } } }
private void ReadDataInstanceValues(NodeBase lnroot, IEnumerable <XElement> elements, XNamespace ns) { foreach (XElement inst in elements) { XAttribute a = inst.Attribute("name"); if (a == null) { logger.LogDebug("SCL DAI/DOI attribute 'name' not found for " + inst.ToString() + ", node " + lnroot.IecAddress); return; } NodeBase child = lnroot.FindChildNode(a.Value); if (child == null) { logger.LogDebug("SCL DAI/DOI child " + a.Value + " not found for " + inst.ToString() + ", node " + lnroot.IecAddress); return; } XElement val = inst.Element(ns + "Val"); if (val != null && (child is NodeData) && !(child is NodeDO)) { // Read value in NodeData data = child as NodeData; logger.LogDebug("SCL Value found for " + child.IecAddress + ": val = " + val.Value + ", BType=" + data.SCL_BType); IEC61850.Server.DataAttributeType at = IEC61850.Server.DataAttribute.typeFromSCLString(data.SCL_BType); try { if (at == IEC61850.Server.DataAttributeType.ENUMERATED) { NodeBase myEnum = _dataModels[0].enums.FindChildNode(data.SCL_Type); if (myEnum != null) { NodeData myVal = (NodeData)myEnum.FindChildNode(val.Value); if (myVal != null) { data.DataValue = int.Parse((string)myVal.DataValue); data.DataType = scsm_MMS_TypeEnum.integer; } } } else if (at == IEC61850.Server.DataAttributeType.VISIBLE_STRING_32 || at == IEC61850.Server.DataAttributeType.VISIBLE_STRING_64 || at == IEC61850.Server.DataAttributeType.VISIBLE_STRING_65 || at == IEC61850.Server.DataAttributeType.VISIBLE_STRING_129 || at == IEC61850.Server.DataAttributeType.VISIBLE_STRING_255 || at == IEC61850.Server.DataAttributeType.UNICODE_STRING_255) { data.DataValue = val.Value; data.DataType = scsm_MMS_TypeEnum.visible_string; } else if (at == IEC61850.Server.DataAttributeType.UNICODE_STRING_255) { data.DataValue = val.Value; data.DataType = scsm_MMS_TypeEnum.mMSString; } else if (at == IEC61850.Server.DataAttributeType.INT8 || at == IEC61850.Server.DataAttributeType.INT16 || at == IEC61850.Server.DataAttributeType.INT32) { data.DataValue = int.Parse(val.Value); data.DataType = scsm_MMS_TypeEnum.integer; } else if (at == IEC61850.Server.DataAttributeType.INT64) { data.DataValue = long.Parse(val.Value); data.DataType = scsm_MMS_TypeEnum.integer; } else if (at == IEC61850.Server.DataAttributeType.INT8U || at == IEC61850.Server.DataAttributeType.INT16U || at == IEC61850.Server.DataAttributeType.INT32U) { data.DataValue = uint.Parse(val.Value); data.DataType = scsm_MMS_TypeEnum.unsigned; } else if (at == IEC61850.Server.DataAttributeType.BOOLEAN) { data.DataValue = val.Value.ToUpper() == "TRUE"; data.DataType = scsm_MMS_TypeEnum.boolean; } else if (at == IEC61850.Server.DataAttributeType.FLOAT32) { data.DataValue = float.Parse(val.Value); data.DataType = scsm_MMS_TypeEnum.floating_point; } else if (at == IEC61850.Server.DataAttributeType.FLOAT64) { data.DataValue = double.Parse(val.Value); data.DataType = scsm_MMS_TypeEnum.floating_point; } else { logger.LogWarning("Reading initial value for type " + at.ToString() + " not supported!"); } } catch { logger.LogDebug("Error parsing SCL Value (above) for type " + at.ToString()); } } else { // Try children SDI ReadDataInstanceValues(child, inst.Elements(ns + "SDI"), ns); // Try children DAI ReadDataInstanceValues(child, inst.Elements(ns + "DAI"), ns); } } }
private void processReportControl(XmlNode LNNodeCn, NodeBase LNNb) { NodeBase lnfc = LNNb.AddChildNode(new NodeFC("RP")); string[] rptIDSplit = LNNodeCn.Attributes.GetNamedItem("rptID").Value.ToString().Split('$'); NodeBase lnfccn = lnfc.AddChildNode(new NodeData(rptIDSplit[rptIDSplit.Length - 1])); foreach (XmlAttribute Attr in LNNodeCn.Attributes) { NodeBase nd = null; switch (Attr.Name.ToLower()) { case "rptid": nd = new NodeData("RptId"); (nd as NodeData).DataType = scsm_MMS_TypeEnum.visible_string; (nd as NodeData).StringValue = Attr.Value; lnfccn.AddChildNode(nd); break; case "confrev": nd = new NodeData("ConfRev"); (nd as NodeData).DataType = scsm_MMS_TypeEnum.unsigned; (nd as NodeData).DataValue = Attr.Value; lnfccn.AddChildNode(nd); break; case "intgpd": nd = new NodeData("IntgPd"); (nd as NodeData).DataType = scsm_MMS_TypeEnum.unsigned; (nd as NodeData).DataValue = Attr.Value; lnfccn.AddChildNode(nd); break; case "datset": nd = new NodeData("DatSet"); (nd as NodeData).DataType = scsm_MMS_TypeEnum.visible_string; (nd as NodeData).StringValue = Attr.Value; lnfccn.AddChildNode(nd); break; case "buftime": nd = new NodeData("BufTm"); (nd as NodeData).DataType = scsm_MMS_TypeEnum.unsigned; (nd as NodeData).DataValue = Attr.Value; lnfccn.AddChildNode(nd); break; } } foreach (XmlNode LNNodeCnCn in LNNodeCn.ChildNodes) { NodeBase nd = null; switch (LNNodeCnCn.Name.ToLower()) { case "trgops": nd = new NodeData("TrgOps"); (nd as NodeData).DataType = scsm_MMS_TypeEnum.bit_string; lnfccn.AddChildNode(nd); break; case "optfields": nd = new NodeData("OptFlds"); (nd as NodeData).DataType = scsm_MMS_TypeEnum.bit_string; lnfccn.AddChildNode(nd); break; case "rptenabled": nd = new NodeData("RprEna"); (nd as NodeData).DataType = scsm_MMS_TypeEnum.boolean; (nd as NodeData).DataValue = LNNodeCnCn.Value; lnfccn.AddChildNode(nd); break; } } }
private void processGSEControl(XmlNode LNNodeCn, NodeBase LNNb, XmlNodeList DataSets, XmlNodeList GSE) { NodeBase LNFc = LNNb.AddChildNode(new NodeFC("GO")); NodeBase DO = LNFc.AddChildNode(new NodeData(getStringAttribute(LNNodeCn, "name"))); NodeBase Nd = new NodeData("GoID"); (Nd as NodeData).DataType = scsm_MMS_TypeEnum.visible_string; (Nd as NodeData).DataValue = getStringAttribute(LNNodeCn, "appID"); DO.AddChildNode(Nd); Nd = new NodeData("DatSet"); (Nd as NodeData).DataType = scsm_MMS_TypeEnum.visible_string; (Nd as NodeData).DataValue = LNNb.IecAddress + "$" + getStringAttribute(LNNodeCn, "datSet"); DO.AddChildNode(Nd); if (GSE.Count > 0) { foreach (XmlNode GSENode in GSE) { if (GSENode.Name == "GSE" && getStringAttribute(LNNodeCn, "name") == getStringAttribute(GSENode, "cbName")) { foreach (XmlNode GSENodeCn in GSENode.ChildNodes) { if (GSENodeCn.Name == "Address") { Nd = new NodeData("DstAddress"); (Nd as NodeData).DataType = scsm_MMS_TypeEnum.structure; NodeBase DA = DO.AddChildNode(Nd); foreach (XmlNode GSENodeCnCn in GSENodeCn.ChildNodes) { switch (getStringAttribute(GSENodeCnCn, "type")) { case "MAC-Address": Nd = new NodeData("Addr"); (Nd as NodeData).DataType = scsm_MMS_TypeEnum.visible_string; (Nd as NodeData).DataValue = GSENodeCnCn.InnerText; DA.AddChildNode(Nd); break; case "APPID": Nd = new NodeData("APPID"); (Nd as NodeData).DataType = scsm_MMS_TypeEnum.visible_string; (Nd as NodeData).DataValue = Convert.ToUInt32(GSENodeCnCn.InnerText).ToString(); DA.AddChildNode(Nd); break; case "VLAN-PRIORITY": Nd = new NodeData("PRIORITY"); (Nd as NodeData).DataType = scsm_MMS_TypeEnum.visible_string; (Nd as NodeData).DataValue = GSENodeCnCn.InnerText; DA.AddChildNode(Nd); break; } } } break; } } } } }
private void processDOI(string LNNodeLnType, string LNNodeCnName, XmlNode LNNodeCn, NodeBase LNNb, XmlNodeList LNodeTypeNodes, XmlNodeList DOTypeNodes, XmlNodeList DATypeNodes) { // Process Instantiated Data Object foreach (XmlNode LNNodeTypeNodesNd in LNodeTypeNodes) { foreach (XmlNode LNNodeTypeNodesNdCn in LNNodeTypeNodesNd.ChildNodes) { if (LNNodeCnName == getStringAttribute(LNNodeTypeNodesNdCn, "name") && LNNodeLnType == getStringAttribute(LNNodeTypeNodesNd, "id")) { foreach (XmlNode DOTypeNodesNd in DOTypeNodes) { if (getStringAttribute(LNNodeTypeNodesNdCn, "type") == getStringAttribute(DOTypeNodesNd, "id")) { foreach (XmlNode DOTypeNodesNdCn in DOTypeNodesNd.ChildNodes) { if (DOTypeNodesNdCn.Name == "DA") { NodeBase LNFC = LNNb.AddChildNode(new NodeFC(getStringAttribute(DOTypeNodesNdCn, "fc"))); NodeBase LNFCCn = LNFC.AddChildNode(new NodeData(getStringAttribute(LNNodeTypeNodesNdCn, "name"))); NodeData Nd = new NodeData(getStringAttribute(DOTypeNodesNdCn, "name")); Nd.DataType = getVarDataType(getStringAttribute(DOTypeNodesNdCn, "bType")); NodeBase DOCn = LNFCCn.AddChildNode(Nd); if (Nd.DataType == scsm_MMS_TypeEnum.structure) { processStructDAType(DOCn, getStringAttribute(DOTypeNodesNdCn, "type"), DATypeNodes); } } } } } } } } foreach (XmlNode LNNodeCnNd in LNNodeCn.ChildNodes) { if (LNNodeCnNd.Name == "DAI") { if (getStringAttribute(LNNodeCnNd, "name") == "d") { foreach (XmlNode LNNodeCnNdCn in LNNodeCnNd) { if (LNNodeCnNdCn.Name == "Val") { NodeBase FCNb = LNNb.FindChildNode("DC"); if (FCNb != null) { NodeBase[] FCNbCn = FCNb.GetChildNodes(); if (FCNbCn.Length > 0) { foreach (NodeBase DO in FCNbCn) { if (DO.Name == LNNodeCnName) { NodeBase[] DOCn = DO.GetChildNodes(); if (DOCn.Length > 0) { foreach (NodeBase DA in DOCn) { if (DA.Name == "d") { (DA as NodeData).DataValue = LNNodeCnNdCn.InnerText; } } } } } } } int i = 0; } } } } } }