public Iec61850State() { DataModel = new Iec61850Model(this); CaptureDb = new MMSCaptureDb(this); iso = new IsoLayers(this); OutstandingCalls = new ConcurrentDictionary <int, NodeBase[]>(2, 10); Controller = new Iec61850Controller(this, DataModel); }
private void WorkerThreadProc(object obj) { SCLServer self = (SCLServer)obj; logger.LogInfo(String.Format("SCL Server " + sclModel.iec.Name + " - Creating model. It takes a while...")); IedModel model = makeIecModel(); server = new IedServer(model); InitializeValues(sclModel.iec); server.Start(tcpPort); //Thread.Sleep(100); if (!server.isRunning()) { logger.LogError(String.Format("SCL Server " + sclModel.iec.Name + " Failed at port " + tcpPort.ToString() + "!!!")); self._run = false; } else { logger.LogInfo(String.Format("SCL Server " + sclModel.iec.Name + " Started at port " + tcpPort.ToString() + "!!!")); } while (self._run) { int waitres = WaitHandle.WaitAny(_waitHandles, 500); switch (waitres) { case 0: // endthread self._run = false; break; case WaitHandle.WaitTimeout: if (!server.isRunning()) //logger.LogInfo("Server not running???"); { self._run = false; } break; } } server.Stop(); resetModelObjects(sclModel.iec); server.Dispose(); server = null; model.Dispose(); model = null; sclModel = null; logger.LogInfo(String.Format("SCL Server Stopped")); }
/// <summary> /// Reads through the SCL file and looks for data sets and reports /// </summary> /// <param name="filename"></param> private void GetDataSetsAndReports(String filename, Iec61850Model _dataModel) { var reader = new XmlTextReader(filename); var iedName = ""; var deviceName = ""; var lnName = ""; _dataModel.lists = new NodeIed("lists", _dataModel); _dataModel.urcbs = new NodeIed("reports", _dataModel); while (reader.Read()) { if (reader.IsStartElement()) { NodeBase parent; switch (reader.Name) { case "IED": iedName = reader.GetAttribute("name"); break; case "LDevice": deviceName = reader.GetAttribute("inst"); break; case "LN0": lnName = String.Concat(reader.GetAttribute("prefix"), reader.GetAttribute("lnClass"), reader.GetAttribute("inst")); break; case "LN": lnName = String.Concat(reader.GetAttribute("prefix"), reader.GetAttribute("lnClass"), reader.GetAttribute("inst")); break; case "DataSet": parent = _dataModel.lists.AddChildNode(new NodeBase(String.Concat(iedName, deviceName))); // will return if already exists parent.AddChildNode(CreateDataSet(reader.ReadSubtree(), lnName, deviceName, _dataModel)); break; case "ReportControl": parent = _dataModel.urcbs.AddChildNode(new NodeBase(String.Concat(iedName, deviceName))); // will return if already exists parent.AddChildNode(CreateReport(reader.ReadSubtree(), lnName, deviceName)); break; } } } }
public Iec61850Controller(Iec61850State iecs, Iec61850Model model) { this.iecs = iecs; this.model = model; }
public NodeIed(string Name, Iec61850Model _model) : base(Name) { model = _model; }
/// <summary> /// Reads through a data set subtree and creates a data set node from it /// </summary> /// <param name="reader"></param> /// <param name="nodeName"></param> /// <param name="deviceName"></param> /// <returns> a VL node </returns> private NodeVL CreateDataSet(XmlReader reader, string nodeName, string deviceName, Iec61850Model _dataModel) { reader.Read(); var nodeVL = new NodeVL(String.Concat(nodeName, "$", reader.GetAttribute("name"))); var test = reader.GetAttribute("name"); while (reader.Read()) { if (reader.IsStartElement() && reader.Name.Equals("FCDA")) { var prefix = reader.GetAttribute("prefix"); var lnClass = reader.GetAttribute("lnClass"); var lnInst = reader.GetAttribute("lnInst"); var fullName = String.Concat(prefix, lnClass, lnInst); var ldInst = reader.GetAttribute("ldInst"); var doName = reader.GetAttribute("doName"); var fc = reader.GetAttribute("fc"); var nodeData = _dataModel.ied.AddChildNode(new NodeLD(String.Concat(_dataModel.ied.Name, ldInst))) .AddChildNode(new NodeLN(fullName)) .AddChildNode(new NodeFC(fc)).AddChildNode(new NodeData(doName)); nodeVL.ForceLinkChildNode(nodeData); } } return(nodeVL); }
public int Start(Iec61850Model model, int port) { sclModel = model; tcpPort = port; return(StartInternal(new ParameterizedThreadStart(WorkerThreadProc))); }
/// <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); } } }
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); } } }