Beispiel #1
0
        public void AddPNMObject(PhysicalNetworkModel.Terminal terminal)
        {
            if (terminal.ConductingEquipment.@ref == "76c96252-b533-44b1-aac2-9efb184dc9e7")
            {
            }


            string xml = "<cim:Terminal rdf:ID = '_" + terminal.mRID + "'>\r\n";

            if (terminal.name == null)
            {
                xml += "  <cim:IdentifiedObject.name>" + "T" + terminal.sequenceNumber + "</cim:IdentifiedObject.name>\r\n";
            }
            else
            {
                xml += "  <cim:IdentifiedObject.name>" + terminal.name + "</cim:IdentifiedObject.name>\r\n";
            }

            xml += "  <cim:ACDCTerminal.sequenceNumber>" + terminal.sequenceNumber + "</cim:ACDCTerminal.sequenceNumber>\r\n";

            // ABCN on everything except cables, to avoid connectivity struggle issues inside substation in PF
            var ci = _cimContext.GetObject <PhysicalNetworkModel.ConductingEquipment>(terminal.ConductingEquipment.@ref);

            if (ci is PhysicalNetworkModel.ACLineSegment)
            {
                xml += "  <cim:Terminal.phases rdf:resource='http://iec.ch/TC57/2013/CIM-schema-cim16#PhaseCode.ABC'/>\r\n";
            }
            else
            {
                xml += "  <cim:Terminal.phases rdf:resource='http://iec.ch/TC57/2013/CIM-schema-cim16#PhaseCode.ABCN'/>\r\n";
            }

            /*
             * if (!ForceThreePhases)
             *  xml += "  <cim:Terminal.phases rdf:resource='http://iec.ch/TC57/2013/CIM-schema-cim16#PhaseCode." + terminal.phases.ToString() + "'/>\r\n";
             * else
             *  xml += "  <cim:Terminal.phases rdf:resource='http://iec.ch/TC57/2013/CIM-schema-cim16#PhaseCode.ABCN'/>\r\n";
             */


            if (terminal.ConnectivityNode != null)
            {
                xml += "  <cim:Terminal.ConnectivityNode rdf:resource = '#_" + terminal.ConnectivityNode.@ref + "'/>\r\n";
            }

            xml += "  <cim:Terminal.ConductingEquipment rdf:resource='#_" + terminal.ConductingEquipment.@ref + "'/>\r\n";
            xml += "</cim:Terminal>\r\n\r\n";
            _writer.Write(xml);
        }
        public void TestLineMerging()
        {
            // Breaker in BRB
            var swBRB = _context.GetObject <PhysicalNetworkModel.Switch>("366461ea-69b3-4e55-8459-228d9d33668e");

            // Load Break Switch in 30904
            var sw30904 = _context.GetObject <PhysicalNetworkModel.Switch>("15088672-f80c-453c-8bc6-30550ab00780");

            var inputObjects = _context.GetAllObjects().Where(o => (o is PhysicalNetworkModel.ACLineSegment && o.name != null && o.name.Contains("BRB-30904")) || !(o is PhysicalNetworkModel.ACLineSegment));

            var converter = new PNM2PowerFactoryCimConverter(inputObjects, new List <IPreProcessor> {
                new ACLSMerger(new MappingContext())
            });

            var outputCimObjects = converter.GetCimObjects().ToList();

            // Check that the two switches point to each other via the same ACLS
            Assert.AreEqual(swBRB.GetNeighborConductingEquipments().OfType <PhysicalNetworkModel.ACLineSegment>().First(), sw30904.GetNeighborConductingEquipments().OfType <PhysicalNetworkModel.ACLineSegment>().First());
        }
Beispiel #3
0
        public static List <IdentifiedObject> Filter(CimContext context, FilterRule rule)
        {
            //List<IdentifiedObject> result = new List<IdentifiedObject>();
            Dictionary <string, IdentifiedObject> result = new Dictionary <string, IdentifiedObject>();

            HashSet <string> assetRefs        = new HashSet <string>();
            HashSet <string> assetInfoRefs    = new HashSet <string>();
            HashSet <string> assetModelRefs   = new HashSet <string>();
            HashSet <string> manufacturerRefs = new HashSet <string>();

            HashSet <PhysicalNetworkModel.ConnectivityNode> cnAlreadyWritten = new HashSet <PhysicalNetworkModel.ConnectivityNode>();

            FeederInfoContext feederContext = new FeederInfoContext(context);

            feederContext.CreateFeederObjects();



            foreach (var cimObject in context.GetAllObjects())
            {
                if ((cimObject is PhysicalNetworkModel.ConductingEquipment &&
                     ((PhysicalNetworkModel.ConductingEquipment)cimObject).BaseVoltage >= rule.MinVoltageLevel) ||
                    !(cimObject is PhysicalNetworkModel.ConductingEquipment) ||
                    cimObject is PhysicalNetworkModel.PowerTransformer ||
                    cimObject is PhysicalNetworkModel.ExternalNetworkInjection ||
                    (cimObject is EnergyConsumer && ((PowerSystemResource)cimObject).PSRType == "Aftagepunkt_fællesmaaling")
                    )
                {
                    if (
                        cimObject is PhysicalNetworkModel.ACLineSegment ||
                        cimObject is PhysicalNetworkModel.BusbarSection ||
                        cimObject is PhysicalNetworkModel.LoadBreakSwitch ||
                        cimObject is PhysicalNetworkModel.Breaker ||
                        cimObject is PhysicalNetworkModel.Disconnector ||
                        cimObject is PhysicalNetworkModel.Fuse ||
                        cimObject is PhysicalNetworkModel.Substation ||
                        cimObject is PhysicalNetworkModel.VoltageLevel ||
                        cimObject is PhysicalNetworkModel.Bay ||
                        cimObject is PhysicalNetworkModel.PowerTransformer ||
                        cimObject is PhysicalNetworkModel.PowerTransformerEnd ||
                        cimObject is PhysicalNetworkModel.ExternalNetworkInjection ||
                        cimObject is PhysicalNetworkModel.PetersenCoil ||
                        cimObject is PhysicalNetworkModel.CurrentTransformer ||
                        cimObject is PhysicalNetworkModel.PotentialTransformer ||
                        cimObject is PhysicalNetworkModel.EnergyConsumer ||
                        cimObject is PhysicalNetworkModel.RatioTapChanger ||
                        cimObject is PhysicalNetworkModel.LinearShuntCompensator/* ||
                                                                                 * cimObject is PhysicalNetworkModel.Asset ||
                                                                                 * cimObject is PhysicalNetworkModel.AssetInfo ||
                                                                                 * cimObject is PhysicalNetworkModel.ProductAssetModel ||
                                                                                 * cimObject is PhysicalNetworkModel.Manufacturer */
                        )

                    {
                        // Find substation
                        Substation partOfSt = null;

                        if (cimObject is Substation)
                        {
                            partOfSt = (Substation)cimObject;
                        }

                        if (cimObject.IsInsideSubstation(context))
                        {
                            partOfSt = cimObject.GetSubstation(true, context);
                        }

                        if (cimObject is ExternalNetworkInjection)
                        {
                            var eni       = cimObject as ExternalNetworkInjection;
                            var neighbors = eni.GetNeighborConductingEquipments();

                            if (neighbors.Exists(c => c.IsInsideSubstation() && (rule.IncludeSpecificSubstations == null || rule.IncludeSpecificSubstations.Contains(c.GetSubstation().name))))
                            {
                                var ce = neighbors.First(c => c.IsInsideSubstation() && (rule.IncludeSpecificSubstations == null || rule.IncludeSpecificSubstations.Contains(c.GetSubstation().name)));

                                // put injection inside substation
                                eni.BaseVoltage = ce.BaseVoltage;
                                if (ce is BusbarSection)
                                {
                                    eni.EquipmentContainer = new EquipmentEquipmentContainer()
                                    {
                                        @ref = context.GetObject <VoltageLevel>(ce.EquipmentContainer.@ref).mRID
                                    };
                                }
                                else
                                {
                                    eni.EquipmentContainer = new EquipmentEquipmentContainer()
                                    {
                                        @ref = context.GetObject <Bay>(ce.EquipmentContainer.@ref).VoltageLevel.@ref
                                    };
                                }
                            }
                        }

                        // Tap changer
                        if (cimObject is RatioTapChanger)
                        {
                            var tap = cimObject as RatioTapChanger;

                            if (!(tap.TransformerEnd != null && tap.TransformerEnd.@ref != null && result.ContainsKey(tap.TransformerEnd.@ref)))
                            {
                                continue;
                            }

                            var ptEnd = context.GetObject <PowerTransformerEnd>(tap.TransformerEnd.@ref);
                        }


                        //  AuxiliaryEquipment - transfer the one pointing to 60 kV breakers only
                        if (cimObject is AuxiliaryEquipment)
                        {
                            var aux = cimObject as AuxiliaryEquipment;

                            // If not connected to terminal, then skip
                            if (aux.Terminal == null)
                            {
                                continue;
                            }

                            var swTerminal = context.GetObject <Terminal>(aux.Terminal.@ref);
                            var ctObj      = context.GetObject <IdentifiedObject>(swTerminal.ConductingEquipment.@ref);

                            if (ctObj is Switch)
                            {
                                Switch ctSw = ctObj as Switch;

                                // If not connedted to breaker, then skip
                                if (!(ctSw is Breaker))
                                {
                                    continue;
                                }

                                // if not 60000 volt, then skip
                                if (ctSw.BaseVoltage != 60000)
                                {
                                    continue;
                                }

                                // If bay name contains transformer, skup
                                var swBayName = ctSw.GetBay(true, context).name;
                                if (swBayName.ToLower().Contains("transformer"))
                                {
                                    continue;
                                }
                            }
                        }


                        // Generel voltage check
                        if (!(cimObject is ConductingEquipment) ||
                            rule.MinVoltageLevel == 0 ||
                            ((ConductingEquipment)cimObject).BaseVoltage == 0 ||
                            ((ConductingEquipment)cimObject).BaseVoltage >= rule.MinVoltageLevel ||
                            (cimObject is EnergyConsumer && ((PowerSystemResource)cimObject).PSRType == "Aftagepunkt_fællesmaaling"))
                        {
                            // Add high voltage measured customer, even if lv modelled
                            if (cimObject is EnergyConsumer && ((EnergyConsumer)cimObject).PSRType == "Aftagepunkt_fællesmaaling" && ((EnergyConsumer)cimObject).BaseVoltage == 400)
                            {
                                // Don't add low voltage consumers if min voltage > 15000
                                if (rule.MinVoltageLevel > 15000)
                                {
                                    continue;
                                }


                                var ec = cimObject as EnergyConsumer;


                                if (ec.name == "571313124501138119")
                                {
                                }

                                var ecAclsNeighbors = context.GetNeighborConductingEquipments(ec).Where(c => c is ACLineSegment).ToList();

                                if (ecAclsNeighbors.Count == 1)
                                {
                                    var ecTerminal = context.GetConnections(ec)[0].Terminal;

                                    var aclsTrafoConnections = context.GetNeighborConductingEquipments(ecAclsNeighbors[0]).Where(c => c is PowerTransformer).ToList();

                                    if (aclsTrafoConnections.Count == 1)
                                    {
                                        var trafo   = aclsTrafoConnections[0];
                                        var trafoCn = context.GetConnections(trafo).Where(c => c.Terminal.sequenceNumber == "2").ToList();

                                        if (trafoCn.Count == 1)
                                        {
                                            var trafoTerminal2   = trafoCn[0].Terminal;
                                            var trafoTerminal2Cn = trafoCn[0].ConnectivityNode;

                                            context.ConnectTerminalToAnotherConnectitityNode(ecTerminal, trafoTerminal2Cn);

                                            var ptSt = trafo.GetSubstation(false, context);

                                            if (ptSt != null)
                                            {
                                                var stVls = context.GetSubstationVoltageLevels(ptSt);

                                                var vl = stVls.Find(o => o.BaseVoltage == ec.BaseVoltage);

                                                if (vl != null)
                                                {
                                                    ec.EquipmentContainer = new EquipmentEquipmentContainer()
                                                    {
                                                        @ref = vl.mRID
                                                    };
                                                }
                                            }

                                            //ec.EquipmentContainer = new EquipmentEquipmentContainer() { @ref = trafo.EquipmentContainer.@ref };
                                        }
                                    }
                                }
                                else if (ecAclsNeighbors.Count > 1)
                                {
                                    Logger.Log(LogLevel.Warning, "Cannot convert: " + ec.name + " multiply cables connected to customer. Must be modelled in PF.");
                                    continue;
                                }
                            }

                            // Check if substation should be filtered away
                            if (cimObject is Substation st)
                            {
                                var priVoltage = st.GetPrimaryVoltageLevel(context);
                                if (priVoltage < rule.MinVoltageLevel)
                                {
                                    continue;
                                }
                            }

                            // Check if power transformer should be filtered away
                            if (cimObject is PowerTransformer pt)
                            {
                                var ends = pt.GetEnds(context);

                                if (!ends.Exists(e => e.BaseVoltage >= rule.MinVoltageLevel))
                                {
                                    continue;
                                }
                            }

                            // Check if power transformer should be filtered away
                            if (cimObject is PowerTransformerEnd ptEnd)
                            {
                                var ptOfPtEnd = context.GetObject <PowerTransformer>(ptEnd.PowerTransformer.@ref);

                                var ends = ptOfPtEnd.GetEnds(context);

                                if (!ends.Exists(e => e.BaseVoltage >= rule.MinVoltageLevel))
                                {
                                    continue;
                                }
                            }


                            // Check if object part of substation should be filtered away due to voltage level
                            if (partOfSt != null)
                            {
                                var priVoltage = partOfSt.GetPrimaryVoltageLevel(context);
                                if (priVoltage < rule.MinVoltageLevel)
                                {
                                    continue;
                                }
                            }


                            // If part of substation, check if we should filter away
                            if (partOfSt != null && (rule.IncludeSpecificSubstations == null ||
                                                     (rule.IncludeSpecificSubstations.Count > 1 &&
                                                      !rule.IncludeSpecificSubstations.Contains(partOfSt.name))))
                            {
                                // Don't filter anything away, if not specific substations specified
                                if (rule.IncludeSpecificSubstations != null)
                                {
                                    bool skip = true;

                                    // Check if substation is feeded from included primary substation

                                    if (partOfSt.PSRType == "SecondarySubstation" &&
                                        partOfSt.InternalFeeders != null &&
                                        partOfSt.InternalFeeders.Count > 0 &&
                                        partOfSt.InternalFeeders[0].ConnectionPoint != null &&
                                        partOfSt.InternalFeeders[0].ConnectionPoint.Substation != null &&
                                        partOfSt.InternalFeeders[0].ConnectionPoint.Substation.name != null)
                                    {
                                        var feededStName = partOfSt.InternalFeeders[0].ConnectionPoint.Substation.name;

                                        if (rule.IncludeSpecificSubstations == null || rule.IncludeSpecificSubstations.Contains(feededStName))
                                        {
                                            skip = false;
                                        }
                                    }

                                    if (skip)
                                    {
                                        continue;
                                    }
                                }
                            }

                            // If acls, check if we should filter away
                            if (cimObject is ACLineSegment && (rule.IncludeSpecificLines == null || rule.IncludeSpecificLines.Count > 1))
                            {
                                bool continueToCheck = true;

                                var acls = cimObject as ACLineSegment;

                                // check if feeded from primary substation
                                var aclsFeeders = feederContext.GeConductingEquipmentFeeders(acls);

                                if (aclsFeeders != null && aclsFeeders.Count > 0)
                                {
                                    if (rule.IncludeSpecificSubstations == null)
                                    {
                                        continueToCheck = false;
                                    }
                                    else
                                    {
                                        var feededStName = aclsFeeders[0].ConnectionPoint.Substation.name;

                                        if (rule.IncludeSpecificSubstations == null || rule.IncludeSpecificSubstations.Contains(feededStName))
                                        {
                                            continueToCheck = false;
                                        }
                                    }
                                }

                                if (continueToCheck)
                                {
                                    if (acls.PSRType == "InternalCable")
                                    {
                                        var aclsSt = acls.GetSubstation(false, context);

                                        if (!(aclsSt != null && (rule.IncludeSpecificSubstations == null || rule.IncludeSpecificSubstations.Contains(aclsSt.name))))
                                        {
                                            continue;
                                        }
                                    }
                                    else if (acls.name != null && acls.name.Contains("#"))
                                    {
                                        var nameSplit = acls.name.Split('#');

                                        var nameWithoutDelStr = nameSplit[0].ToUpper();

                                        if (rule.IncludeSpecificLines != null && !rule.IncludeSpecificLines.Contains(nameWithoutDelStr))
                                        {
                                            continue;
                                        }
                                    }
                                    else
                                    {
                                        continue;
                                    }
                                }
                            }

                            // If min voltagelevel > 400, don't include cable boxes and stuff inside cable boxes
                            if (rule.MinVoltageLevel > 400 &&
                                partOfSt != null
                                &&
                                (partOfSt.PSRType == "CableBox" || partOfSt.PSRType == "T-Junction"))
                            {
                                continue;
                            }

                            if (rule.MinVoltageLevel > 400 &&
                                partOfSt != null &&
                                partOfSt.PSRType == "Tower" &&
                                partOfSt.GetPrimaryVoltageLevel(context) < 1000)
                            {
                                continue;
                            }



                            // don't add voltage level, we do this later
                            if (cimObject is VoltageLevel)
                            {
                                continue;
                            }

                            result.Add(cimObject.mRID, cimObject);

                            // Add terminals if conducting equipment
                            if (cimObject is ConductingEquipment)
                            {
                                var ci = cimObject as PhysicalNetworkModel.ConductingEquipment;

                                foreach (var tc in context.GetConnections(ci))
                                {
                                    string stName = "";

                                    if (partOfSt != null && partOfSt.name != null)
                                    {
                                        stName = partOfSt.name + "_";
                                    }

                                    //tc.Terminal.phases = PhysicalNetworkModel.PhaseCode.ABCN;
                                    tc.Terminal.name = stName + ci.name + "_T" + tc.Terminal.sequenceNumber;
                                    result.Add(tc.Terminal.mRID, tc.Terminal);


                                    // add connectivity node, if not already added
                                    if (!cnAlreadyWritten.Contains(tc.ConnectivityNode))
                                    {
                                        result.Add(tc.ConnectivityNode.mRID, tc.ConnectivityNode);
                                    }

                                    cnAlreadyWritten.Add(tc.ConnectivityNode);
                                }
                            }

                            // Add location
                            if (cimObject is PowerSystemResource)
                            {
                                var psrObj = cimObject as PowerSystemResource;

                                if (psrObj.PSRType != "InternalCable")
                                {
                                    if (psrObj.Location != null && psrObj.Location.@ref != null)
                                    {
                                        var loc = context.GetObject <PhysicalNetworkModel.LocationExt>(psrObj.Location.@ref);
                                        result.Add(loc.mRID, loc);
                                    }
                                }
                            }

                            // Add substation voltage levels
                            if (cimObject is Substation)
                            {
                                var psrObj = cimObject as Substation;

                                var voltageLevels = context.GetSubstationVoltageLevels(psrObj);

                                foreach (var vl in voltageLevels)
                                {
                                    result.Add(vl.mRID, vl);
                                }
                            }
                        }
                    }
                }
            }

            // Add protective equipment (relays)
            foreach (var cimObject in context.GetAllObjects())
            {
                if (cimObject is ProtectionEquipmentExt)
                {
                    var pe = cimObject as ProtectionEquipmentExt;

                    if (pe.ProtectedSwitches != null && pe.ProtectedSwitches.Length > 0 && result.ContainsKey(pe.ProtectedSwitches[0].@ref))
                    {
                        result.Add(cimObject.mRID, cimObject);
                    }
                }
            }

            //////////////////////////////////////////////////////////////////////////////////7
            // Add Asset stuff
            //////////////////////////////////////////////////////////////////////////////////7

            // Asset ref
            foreach (var cimObject in result.Values)
            {
                if (cimObject is PowerSystemResource)
                {
                    var psr = cimObject as PowerSystemResource;

                    if (psr.Assets != null && psr.Assets.@ref != null)
                    {
                        assetRefs.Add(psr.Assets.@ref);
                    }
                }
            }

            // Asset
            foreach (var cimObject in context.GetAllObjects())
            {
                if (cimObject is PhysicalNetworkModel.Asset)
                {
                    var asset = cimObject as PhysicalNetworkModel.Asset;

                    if (!assetRefs.Contains(asset.mRID))
                    {
                        continue;
                    }

                    if (asset.AssetInfo != null && asset.AssetInfo.@ref != null && !assetInfoRefs.Contains(asset.AssetInfo.@ref))
                    {
                        assetInfoRefs.Add(asset.AssetInfo.@ref);
                    }

                    result.Add(asset.mRID, asset);
                }
            }

            // Asset info
            foreach (var cimObject in context.GetAllObjects())
            {
                if (cimObject is PhysicalNetworkModel.AssetInfo)
                {
                    var assetInfo = cimObject as PhysicalNetworkModel.AssetInfo;

                    if (!assetInfoRefs.Contains(assetInfo.mRID))
                    {
                        continue;
                    }


                    if (!(cimObject is PhysicalNetworkModel.CurrentTransformerInfoExt ||
                          cimObject is PhysicalNetworkModel.CableInfoExt ||
                          cimObject is PhysicalNetworkModel.OverheadWireInfoExt))
                    {
                    }

                    if (assetInfo.AssetModel != null && assetInfo.AssetModel.@ref != null && !assetModelRefs.Contains(assetInfo.AssetModel.@ref))
                    {
                        assetModelRefs.Add(assetInfo.AssetModel.@ref);
                    }

                    result.Add(assetInfo.mRID, assetInfo);
                }
            }

            // Asset model
            foreach (var cimObject in context.GetAllObjects())
            {
                if (cimObject is PhysicalNetworkModel.ProductAssetModel)
                {
                    var assetModel = cimObject as PhysicalNetworkModel.ProductAssetModel;

                    if (!assetModelRefs.Contains(assetModel.mRID))
                    {
                        continue;
                    }

                    if (assetModel.Manufacturer != null && assetModel.Manufacturer.@ref != null && !manufacturerRefs.Contains(assetModel.Manufacturer.@ref))
                    {
                        manufacturerRefs.Add(assetModel.Manufacturer.@ref);
                    }

                    result.Add(assetModel.mRID, assetModel);
                }
            }

            // Manufacturer
            foreach (var cimObject in context.GetAllObjects())
            {
                if (cimObject is PhysicalNetworkModel.Manufacturer)
                {
                    var manu = cimObject as PhysicalNetworkModel.Manufacturer;

                    if (!manufacturerRefs.Contains(manu.mRID))
                    {
                        continue;
                    }

                    result.Add(manu.mRID, manu);
                }
            }

            return(result.Values.ToList());
        }
        public IEnumerable <IdentifiedObject> Transform(CimContext context, IEnumerable <IdentifiedObject> input)
        {
            HashSet <PhysicalNetworkModel.IdentifiedObject> dropList = new HashSet <IdentifiedObject>();

            List <PhysicalNetworkModel.IdentifiedObject> addList = new List <IdentifiedObject>();

            foreach (var inputCimObject in input)
            {
                // Find connectivity nodes outside substations
                if (inputCimObject is ConnectivityNode && !dropList.Contains(inputCimObject) && !inputCimObject.IsInsideSubstation(context))
                {
                    ConnectivityNode cn = inputCimObject as ConnectivityNode;

                    // Handle that acls cn relationship might have changed
                    var cnNeighborsx = cn.GetNeighborConductingEquipments(context);

                    // If two acls and we are above low voltage, merge them
                    if (cnNeighborsx.Count(o => o.BaseVoltage > 5000) > 0)
                    {
                        // acls <-> acls
                        if (cnNeighborsx.Count(o => o is ACLineSegmentExt) == 2)
                        {
                            var acls = cnNeighborsx.Where(o => o is ACLineSegmentExt).ToList();

                            var acls1 = acls[0] as ACLineSegment;
                            var acls2 = acls[1] as ACLineSegment;

                            // NEVER MERGE
                            bool theSame = false;

                            // Compate bch
                            if (acls1.bch != null && acls2.bch != null && !CompareAclsValue(acls1.length.Value, acls1.bch.Value, acls2.length.Value, acls2.bch.Value))
                            {
                                theSame = false;
                            }

                            // Compate b0ch
                            if (acls1.b0ch != null && acls2.b0ch != null && !CompareAclsValue(acls1.length.Value, acls1.b0ch.Value, acls2.length.Value, acls2.b0ch.Value))
                            {
                                theSame = false;
                            }

                            // Compare gch
                            if (acls1.gch != null && acls2.gch != null && !CompareAclsValue(acls1.length.Value, acls1.gch.Value, acls2.length.Value, acls2.gch.Value))
                            {
                                theSame = false;
                            }

                            // Compare g0ch
                            if (acls1.g0ch != null && acls2.g0ch != null && !CompareAclsValue(acls1.length.Value, acls1.g0ch.Value, acls2.length.Value, acls2.g0ch.Value))
                            {
                                theSame = false;
                            }

                            // Compare r
                            if (acls1.r != null && acls2.r != null && !CompareAclsValue(acls1.length.Value, acls1.r.Value, acls2.length.Value, acls2.r.Value))
                            {
                                theSame = false;
                            }

                            // Compare r0
                            if (acls1.r0 != null && acls2.r0 != null && !CompareAclsValue(acls1.length.Value, acls1.r0.Value, acls2.length.Value, acls2.r0.Value))
                            {
                                theSame = false;
                            }

                            // Compare x
                            if (acls1.x != null && acls2.x != null && !CompareAclsValue(acls1.length.Value, acls1.x.Value, acls2.length.Value, acls2.x.Value))
                            {
                                theSame = false;
                            }

                            // Compare x0
                            if (acls1.x0 != null && acls2.x0 != null && !CompareAclsValue(acls1.length.Value, acls1.x0.Value, acls2.length.Value, acls2.x0.Value))
                            {
                                theSame = false;
                            }


                            // If the cables have the same eletrical charastica, merge them
                            if (theSame)
                            {
                                // ACLS 1 will survive, ACLS 2 and the CN will die
                                dropList.Add(cn);
                                dropList.Add(acls2);

                                // drop acls 2 terminals
                                foreach (var tc in context.GetConnections(acls2))
                                {
                                    dropList.Add(tc.Terminal);
                                }

                                var loc1 = context.GetObject <LocationExt>(acls1.Location.@ref);
                                var loc2 = context.GetObject <LocationExt>(acls2.Location.@ref);

                                LineMerger lm = new LineMerger();

                                // Convert to NTS geometries
                                lm.Add(GetGeometry(loc1));
                                lm.Add(GetGeometry(loc2));

                                // Merge the two line strings
                                var mergedLineList = lm.GetMergedLineStrings();

                                if (mergedLineList.Count != 1)
                                {
                                    throw new Exception("Cannot merge ACLS: " + acls1.mRID + " and " + acls2.mRID);
                                }

                                // Overwrite loc 1 coordinated with merged strings
                                loc1.coordinates = GetPoints((ILineString)mergedLineList[0]).ToArray();

                                // Sum length
                                acls1.length.Value += acls2.length.Value;

                                // Sum bch
                                if (acls1.bch != null && acls2.bch != null)
                                {
                                    acls1.bch.Value += acls2.bch.Value;
                                }

                                // Sum b0ch
                                if (acls1.b0ch != null && acls2.b0ch != null)
                                {
                                    acls1.b0ch.Value += acls2.b0ch.Value;
                                }

                                // Sum gch
                                if (acls1.gch != null && acls2.gch != null)
                                {
                                    acls1.gch.Value += acls2.gch.Value;
                                }

                                // Sum g0ch
                                if (acls1.g0ch != null && acls2.g0ch != null)
                                {
                                    acls1.g0ch.Value += acls2.g0ch.Value;
                                }

                                // Sum r
                                if (acls1.r != null && acls2.r != null)
                                {
                                    acls1.r.Value += acls2.r.Value;
                                }

                                // Sum r0
                                if (acls1.r0 != null && acls2.r0 != null)
                                {
                                    acls1.r0.Value += acls2.r0.Value;
                                }

                                // Sum x
                                if (acls1.x != null && acls2.x != null)
                                {
                                    acls1.x.Value += acls2.x.Value;
                                }

                                // Sum x0
                                if (acls1.x0 != null && acls2.x0 != null)
                                {
                                    acls1.x0.Value += acls2.x0.Value;
                                }

                                // Find cn in the other end of ACLS 2
                                var acls2otherEndCn = context.GetConnections(acls2).Find(o => o.ConnectivityNode != cn);

                                // Get terminal of ACLS 1 that point to ACLS 2
                                var acls1Terminal = acls1.GetTerminal(acls2, true, context);

                                // Disconnect ACLS 2 terminals
                                var acls2connections = context.GetConnections(acls2);

                                List <Terminal> terminalsToDisconnect = new List <Terminal>();

                                foreach (var acls2con in acls2connections)
                                {
                                    terminalsToDisconnect.Add(acls2con.Terminal);
                                }

                                foreach (var t2d in terminalsToDisconnect)
                                {
                                    context.DisconnectTerminalFromConnectitityNode(t2d);
                                }

                                // Change terminal of ACLS 1 to point to ACLS 2 other end CN
                                context.ConnectTerminalToAnotherConnectitityNode(acls1Terminal, acls2otherEndCn.ConnectivityNode);
                            }
                            else
                            {
                                // Cable are not the same, we need to add a susbstation to act as a junction

                                // Create muffe station
                                var st = new PhysicalNetworkModel.Substation();
                                st.mRID    = Guid.NewGuid().ToString();
                                st.name    = "Junction";
                                st.PSRType = "Junction";
                                addList.Add(st);

                                // Create voltage level
                                var vl = new PhysicalNetworkModel.VoltageLevel();
                                vl.mRID                = Guid.NewGuid().ToString();
                                vl.BaseVoltage         = acls1.BaseVoltage;
                                vl.name                = "VL";
                                vl.EquipmentContainer1 = new VoltageLevelEquipmentContainer()
                                {
                                    @ref = st.mRID
                                };
                                addList.Add(vl);

                                // Relate cn to voltage level
                                if (_mappingContext.ConnectivityNodeToVoltageLevel.ContainsKey(cn))
                                {
                                    _mappingContext.ConnectivityNodeToVoltageLevel.Remove(cn);
                                }

                                _mappingContext.ConnectivityNodeToVoltageLevel.Add(cn, vl);
                            }
                        }
                        // <> 2 kabler
                        else
                        {
                            // Create muffe station
                            var st = new PhysicalNetworkModel.Substation();
                            st.mRID    = Guid.NewGuid().ToString();
                            st.name    = "MUFFE";
                            st.PSRType = "Junction";
                            addList.Add(st);

                            // Create voltage level
                            var vl = new PhysicalNetworkModel.VoltageLevel();
                            vl.mRID                = Guid.NewGuid().ToString();
                            vl.BaseVoltage         = cnNeighborsx[0].BaseVoltage;
                            vl.name                = "VL";
                            vl.EquipmentContainer1 = new VoltageLevelEquipmentContainer()
                            {
                                @ref = st.mRID
                            };
                            addList.Add(vl);

                            // Relate cn to voltage level
                            if (_mappingContext.ConnectivityNodeToVoltageLevel.ContainsKey(cn))
                            {
                                _mappingContext.ConnectivityNodeToVoltageLevel.Remove(cn);
                            }

                            _mappingContext.ConnectivityNodeToVoltageLevel.Add(cn, vl);
                        }
                    }
                }
            }

            // return objects, except the one dropped
            foreach (var inputObj in input)
            {
                if (!dropList.Contains(inputObj))
                {
                    yield return(inputObj);
                }
            }

            // yield added objects,
            foreach (var inputObj in addList)
            {
                yield return(inputObj);
            }
        }
        public KonstantCimArchiveWriter(IEnumerable <PhysicalNetworkModel.IdentifiedObject> cimObjects, string outputFolder, string archiveName, Guid modelRdfId, bool highVoltageOnly = false)
        {
            System.IO.Directory.CreateDirectory(outputFolder);
            System.IO.Directory.CreateDirectory(outputFolder + "\\files");

            CimContext initialContext = CimContext.Create(cimObjects);

            string eqTempFileName = outputFolder + @"\files\" + archiveName + "_eq.xml";
            string glTempFileName = outputFolder + @"\files\" + archiveName + "_gl.xml";
            string aiTempFileName = outputFolder + @"\files\" + archiveName + "_ai.xml";
            string peTempFileName = outputFolder + @"\files\" + archiveName + "_pe.xml";


            Dictionary <string, string> assetToEqRefs = new Dictionary <string, string>();

            var filtered = FilterHelper.Filter(initialContext, new FilterRule()
            {
                MinVoltageLevel = highVoltageOnly ? 20000 : 10000,
            });


            var mappingContext = new MappingContext();

            // Reinitialize cim context to filtered objects
            CimContext _context = CimContext.Create(filtered);


            var converter = new PNM2PowerFactoryCimConverter(filtered,
                                                             new List <IPreProcessor> {
                new ACLSMerger(mappingContext),
                new TransformerCableMerger(mappingContext),
                new KonstantBigEnergyConsumerHandler(mappingContext),
                new KonstantPowerFactoryDataPrepareAndFix(mappingContext)
            });

            // Reinitialize cim context to converted objects
            var outputCimObjects = converter.GetCimObjects().ToList();


            // We need to reinitialize context, because converter has modified objects
            _context = CimContext.Create(outputCimObjects);

            var eqWriter = new EQ_Writer(eqTempFileName, _context, mappingContext, modelRdfId, archiveName);

            eqWriter.ForceThreePhases = true;

            var glWriter = new GL_Writer(glTempFileName);
            var aiWriter = new AI_Writer(aiTempFileName, _context, mappingContext);
            var peWriter = new PE_Writer(peTempFileName, _context, mappingContext);


            //////////////////////
            // do the lines
            var lineContext = new LineInfoContext(_context);
            //lineContext.CreateLineInfo();
            Dictionary <SimpleLine, string> lineToGuid = new Dictionary <SimpleLine, string>();


            foreach (var line in lineContext.GetLines())
            {
                var lineGuid = GUIDHelper.CreateDerivedGuid(Guid.Parse(line.Children[0].Equipment.mRID), 678, true).ToString();
                lineToGuid.Add(line, lineGuid);

                //eqWriter.AddLine(lineGuid, line.Name);
            }

            //////////////////////
            // do the general cim objects
            foreach (var cimObject in _context.GetAllObjects())
            {
                if (cimObject.name != null && cimObject.name.Contains("571313124501006982"))
                {
                }

                if (!(cimObject is Location) && !(cimObject is VoltageLevel && ((VoltageLevel)cimObject).BaseVoltage < 400))
                {
                    if (cimObject is ACLineSegment)
                    {
                        var acls = cimObject as ACLineSegment;

                        var lines = lineContext.GetLines().Where(l => l.Children.Exists(c => c.Equipment == acls)).ToList();

                        if (lines.Count == 1)
                        {
                            var line = lines[0];
                            eqWriter.AddPNMObject(acls, lineToGuid[line]);
                        }
                        else
                        {
                            eqWriter.AddPNMObject((dynamic)cimObject);
                        }
                    }
                    else
                    {
                        // Don't add things that goes into asset and protectionn file
                        if (!(
                                (cimObject is PhysicalNetworkModel.Asset) ||
                                (cimObject is PhysicalNetworkModel.AssetInfo) ||
                                (cimObject is PhysicalNetworkModel.ProductAssetModel) ||
                                (cimObject is PhysicalNetworkModel.Manufacturer) ||
                                (cimObject is CurrentTransformerExt) ||
                                (cimObject is PotentialTransformer) ||
                                (cimObject is ProtectionEquipmentExt)
                                ))
                        {
                            eqWriter.AddPNMObject((dynamic)cimObject);
                        }
                    }
                }

                if (cimObject is PowerSystemResource)
                {
                    var psrObj = cimObject as PowerSystemResource;

                    if (psrObj.Location != null && psrObj.Location.@ref != null && psrObj.PSRType != "InternalCable")
                    {
                        var loc = _context.GetObject <PhysicalNetworkModel.LocationExt>(psrObj.Location.@ref);
                        glWriter.AddLocation(Guid.Parse(psrObj.mRID), loc);
                    }
                    if (psrObj.Assets != null && psrObj.Assets.@ref != null)
                    {
                        assetToEqRefs.Add(psrObj.Assets.@ref, psrObj.mRID);
                    }
                }
            }

            //////////////////////
            // do the asset object
            foreach (var cimObject in _context.GetAllObjects())
            {
                if (cimObject is PhysicalNetworkModel.Asset)
                {
                    if (assetToEqRefs.ContainsKey(cimObject.mRID))
                    {
                        var eqMrid = assetToEqRefs[cimObject.mRID];
                        aiWriter.AddPNMObject((dynamic)cimObject, eqMrid);
                    }
                }

                if (cimObject is PhysicalNetworkModel.AssetInfo)
                {
                    aiWriter.AddPNMObject((dynamic)cimObject);
                }

                if (cimObject is PhysicalNetworkModel.ProductAssetModel)
                {
                    aiWriter.AddPNMObject((dynamic)cimObject);
                }

                if (cimObject is PhysicalNetworkModel.Manufacturer)
                {
                    aiWriter.AddPNMObject((dynamic)cimObject);
                }
            }

            //////////////////////
            // do the projection object
            foreach (var cimObject in _context.GetAllObjects())
            {
                if (cimObject is PhysicalNetworkModel.ProtectionEquipment)
                {
                    peWriter.AddPNMObject((dynamic)cimObject);
                }
                if (cimObject is PhysicalNetworkModel.PotentialTransformer)
                {
                    peWriter.AddPNMObject((dynamic)cimObject);
                }
                if (cimObject is PhysicalNetworkModel.CurrentTransformer)
                {
                    peWriter.AddPNMObject((dynamic)cimObject);
                }
            }

            eqWriter.Close();
            glWriter.Close();
            aiWriter.Close();
            peWriter.Close();

            string startPath = outputFolder + "\\files";
            string zipPath   = outputFolder + "\\" + archiveName + ".zip";

            File.Delete(zipPath);

            ZipFile.CreateFromDirectory(startPath, zipPath);
        }
Beispiel #6
0
        public IEnumerable <IdentifiedObject> Transform(CimContext context, IEnumerable <IdentifiedObject> inputParam)
        {
            FeederInfoContext feederContext = new FeederInfoContext(context);

            feederContext.CreateFeederObjects();

            List <IdentifiedObject> input = inputParam.ToList();

            HashSet <PhysicalNetworkModel.IdentifiedObject> dropList = new HashSet <IdentifiedObject>();
            List <PhysicalNetworkModel.IdentifiedObject>    addList  = new List <IdentifiedObject>();

            // AssetInfo to Asset ref dictionary
            Dictionary <string, string> assetInfoToAssetRef = new Dictionary <string, string>();

            foreach (var inputCimObject in input)
            {
                if (inputCimObject is PhysicalNetworkModel.Asset)
                {
                    var asset = inputCimObject as PhysicalNetworkModel.Asset;

                    if (asset.AssetInfo != null && !assetInfoToAssetRef.ContainsKey(asset.AssetInfo.@ref))
                    {
                        assetInfoToAssetRef.Add(asset.AssetInfo.@ref, asset.mRID);
                    }
                }
            }

            // Asset to Equipment ref dictionary
            Dictionary <string, string> assetToEquipmentRef = new Dictionary <string, string>();

            foreach (var inputCimObject in input)
            {
                if (inputCimObject is PhysicalNetworkModel.PowerSystemResource)
                {
                    var psr = inputCimObject as PhysicalNetworkModel.PowerSystemResource;
                    if (psr.Assets != null)
                    {
                        assetToEquipmentRef.Add(psr.Assets.@ref, psr.mRID);
                    }
                }
            }

            // Set busbar names to station + voltagelevel + bay
            foreach (var inputCimObject in input)
            {
                if (inputCimObject is BusbarSection)
                {
                    var bus = inputCimObject as BusbarSection;

                    var st = bus.GetSubstation(true, context);

                    bus.name = st.name + "_" + GetVoltageLevelStr(bus.BaseVoltage) + "_" + bus.name;

                    var feederInfo = feederContext.GeConductingEquipmentFeederInfo(bus);
                    if (feederInfo != null && feederInfo.Feeders != null && feederInfo.Feeders.Count > 0)
                    {
                        var feeder = feederInfo.Feeders[0];

                        if (feeder.ConnectionPoint.Substation != null)
                        {
                            bus.description = feeder.ConnectionPoint.Substation.name;
                        }
                    }
                }
            }

            // Set feeder name on junction connectivity nodes between cables
            foreach (var inputCimObject in input)
            {
                if (inputCimObject is ConnectivityNode)
                {
                    var cn = inputCimObject as ConnectivityNode;

                    if (cn.mRID == "c540b203-e442-7027-824c-bc561b3de47d")
                    {
                    }

                    var cnEqs = context.GetConnections(cn);

                    if (cnEqs.Count > 0)
                    {
                        if (cnEqs.All(e => e.ConductingEquipment is ACLineSegment))
                        {
                            var eq = cnEqs.First().ConductingEquipment;

                            var feederInfo = feederContext.GeConductingEquipmentFeederInfo(eq);

                            if (feederInfo != null && feederInfo.Feeders != null && feederInfo.Feeders.Count > 0)
                            {
                                var feeder = feederInfo.Feeders[0];

                                if (feeder.ConnectionPoint.Substation != null)
                                {
                                    cn.description = feeder.ConnectionPoint.Substation.name;
                                }
                            }
                        }
                    }
                }
            }

            // Set peterson coil name to station + gis name + min og max
            foreach (var inputCimObject in input)
            {
                if (inputCimObject is PetersenCoil)
                {
                    var coil = inputCimObject as PetersenCoil;

                    var st = coil.GetSubstation(true, context);

                    if (coil.Asset != null && coil.Asset.AssetInfo != null && coil.Asset.AssetInfo.@ref != null)
                    {
                        var coilInfo = context.GetObject <PetersenCoilInfoExt>(coil.Asset.AssetInfo.@ref);

                        coil.name = st.name + " " + coil.name;

                        if (coilInfo != null && coilInfo.minimumCurrent != null && coilInfo.maximumCurrent != null)
                        {
                            coil.name += " " + (int)coilInfo?.minimumCurrent?.Value + "-" + (int)coilInfo?.maximumCurrent?.Value;
                        }
                        else
                        {
                            Logger.Log(LogLevel.Warning, "Slukkepole på station: " + st.name + " mangler værdier.");
                        }
                    }
                    else
                    {
                        coil.name = st.name + " " + coil.name + " 0-0";
                    }
                }
            }

            // Set reactor coil (linear shunt compensator) to station + gis name + min og max
            foreach (var inputCimObject in input)
            {
                if (inputCimObject is LinearShuntCompensator)
                {
                    var coil = inputCimObject as LinearShuntCompensator;

                    var st = coil.GetSubstation(true, context);

                    if (coil.Asset != null && coil.Asset.AssetInfo != null && coil.Asset.AssetInfo.@ref != null)
                    {
                        var coilInfo = context.GetObject <LinearShuntCompensatorInfoExt>(coil.Asset.AssetInfo.@ref);

                        coil.name = st.name + " " + coil.name;

                        if (coilInfo != null && coilInfo.minimumReactivePower != null && coilInfo.maximumReactivePower != null)
                        {
                            coil.name += " " + (int)coilInfo?.minimumReactivePower?.Value + "-" + (int)coilInfo?.maximumReactivePower?.Value;
                        }
                        else
                        {
                            Logger.Log(LogLevel.Warning, "Reaktorspole på station: " + st.name + " mangler værdier.");
                        }
                    }
                    else
                    {
                        coil.name = st.name + " " + coil.name + " 0-0";
                    }
                }
            }

            // Remove injection > 50 kV
            foreach (var inputCimObject in input)
            {
                if (inputCimObject is ExternalNetworkInjection)
                {
                    var inj = inputCimObject as ExternalNetworkInjection;

                    if (inj.BaseVoltage > 50000)
                    {
                        dropList.Add(inj);

                        var injConnections = context.GetConnections(inj);

                        foreach (var injCon in injConnections)
                        {
                            dropList.Add(injCon.Terminal);
                        }
                    }
                }
            }

            // Fix and check objects
            foreach (var inputCimObject in input)
            {
                // Remove switch gear busbar asset model information (because PF complain about missing type, and Konstant/Thue says he don't want types into PF for now
                if (inputCimObject is BusbarSectionInfo)
                {
                    BusbarSectionInfo bsi = inputCimObject as BusbarSectionInfo;
                    bsi.AssetModel = null;

                    var assetMrid = assetInfoToAssetRef[inputCimObject.mRID];
                    var asset     = context.GetObject <PhysicalNetworkModel.Asset>(assetMrid);
                    asset.type       = null;
                    asset.name       = null;
                    asset.AssetModel = null;
                }

                // Remove asset manufacture information on busbars and switches
                if (inputCimObject is BusbarSection || inputCimObject is Switch)
                {
                    ConductingEquipment ci = inputCimObject as ConductingEquipment;
                    var asset = context.GetObject <PhysicalNetworkModel.Asset>(ci.Assets.@ref);
                    asset.type       = null;
                    asset.name       = null;
                    asset.AssetModel = null;
                }

                // Remove measurment current transformer and cts sitting on voltage level < 60 kV
                if (inputCimObject is CurrentTransformer && !((CurrentTransformer)inputCimObject).PSRType.ToLower().Contains("kundemaaling"))
                {
                    var ct = inputCimObject as CurrentTransformer;

                    bool ctIsDropped = false;

                    try
                    {
                        var ctTerminal = context.GetObject <Terminal>(ct.Terminal.@ref);

                        var ctEq = context.GetObject <ConductingEquipment>(ctTerminal.ConductingEquipment.@ref);

                        if (ctEq.BaseVoltage < 60000)
                        {
                            dropList.Add(ct);
                            ctIsDropped = true;
                        }
                    }
                    catch (ArgumentException ex)
                    {
                        dropList.Add(ct);
                        ctIsDropped = true;
                    }

                    // Move CT to line end, transformer end

                    var st = ct.GetSubstation(true, context);

                    foreach (var eq in st.GetEquipments(context))
                    {
                        // If component inside same bay as ct
                        if (eq is ConductingEquipment && eq.EquipmentContainer.@ref == ct.EquipmentContainer.@ref)
                        {
                            var ci = eq as ConductingEquipment;

                            var ciConnections = context.GetConnections(ci);


                            foreach (var ciConnection in ciConnections)
                            {
                                var ciNeighbors = context.GetConnections(ciConnection.ConnectivityNode).Where(c => c.ConductingEquipment != ci).ToList();

                                if (ciNeighbors.Any(c => c.ConductingEquipment is ACLineSegment))
                                {
                                    ct.Terminal.@ref = ciConnection.Terminal.mRID;
                                }
                                else if (ciNeighbors.Any(c => c.ConductingEquipment is PowerTransformer))
                                {
                                    ct.Terminal.@ref = ciConnection.Terminal.mRID;
                                }
                                else if (ciNeighbors.Count == 0)
                                {
                                    ct.Terminal.@ref = ciConnection.Terminal.mRID;
                                }
                            }
                        }
                    }
                }

                // Check that current transformer infos has currents
                if (inputCimObject is CurrentTransformerInfoExt)
                {
                    var ctInfo    = inputCimObject as CurrentTransformerInfoExt;
                    var assetMrid = assetInfoToAssetRef[ctInfo.mRID];
                    var eqMrid    = assetToEquipmentRef[assetMrid];

                    var ct      = context.GetObject <CurrentTransformerExt>(eqMrid);
                    var ctAsset = context.GetObject <PhysicalNetworkModel.Asset>(assetMrid);

                    if (ct.PSRType != null && ct.PSRType == "StromTransformer")
                    {
                        // Make sure primary and secondary current is set, because otherwise PF import fails
                        if (ctInfo.primaryCurrent == null)
                        {
                            var stName  = ct.GetSubstation(true, context).name;
                            var bayName = ct.GetBay(true, context).name;

                            Logger.Log(LogLevel.Warning, "CT Missing primary current. Will not be transfered to PF: " + stName + " " + bayName);
                            ctInfo.primaryCurrent = new CurrentFlow()
                            {
                                Value = 0, unit = UnitSymbol.A
                            };

                            dropList.Add(ct);
                            dropList.Add(ctAsset);
                            dropList.Add(ctInfo);
                        }

                        if (ctInfo.secondaryCurrent == null)
                        {
                            var stName  = ct.GetSubstation(true, context).name;
                            var bayName = ct.GetBay(true, context).name;

                            Logger.Log(LogLevel.Warning, "CT Missing secondary current: " + stName + " " + bayName);
                            ctInfo.secondaryCurrent = new CurrentFlow()
                            {
                                Value = 0, unit = UnitSymbol.A
                            };
                        }
                    }
                    else
                    {
                        dropList.Add(ct);
                        dropList.Add(ctAsset);
                        dropList.Add(ctInfo);
                    }
                }

                // Remove potential transformers sitting on voltage level < 60 kV
                if (inputCimObject is PotentialTransformer)
                {
                    var pt = inputCimObject as PotentialTransformer;

                    // If terminal point to object we don't have including - i.e. some 400 volt component - don't bother with the CT
                    if (context.GetAllObjects().Exists(o => o.mRID == pt.Terminal.@ref))
                    {
                        var ptTerminal = context.GetObject <Terminal>(pt.Terminal.@ref);

                        var ptEq = context.GetObject <ConductingEquipment>(ptTerminal.ConductingEquipment.@ref);

                        if (ptEq.BaseVoltage < 60000)
                        {
                            dropList.Add(pt);
                        }
                    }
                    else
                    {
                        dropList.Add(pt);
                    }
                }

                // Check that potential transformer info has voltages
                if (inputCimObject is PotentialTransformerInfoExt)
                {
                    var vtInfo = inputCimObject as PotentialTransformerInfoExt;

                    var assetMrid = assetInfoToAssetRef[vtInfo.mRID];
                    var eqMrid    = assetToEquipmentRef[assetMrid];

                    var vtAsset = context.GetObject <PhysicalNetworkModel.Asset>(assetMrid);
                    var vt      = context.GetObject <PotentialTransformer>(eqMrid);
                    var vtSt    = vt.GetSubstation(true, context);

                    // Make sure primary and secondary voltage is set, because otherwise PF import fails
                    if (vtInfo.primaryVoltage == null)
                    {
                        vtInfo.primaryVoltage = new Voltage()
                        {
                            Value = 0, unit = UnitSymbol.V
                        };

                        var stName  = vt.GetSubstation(true, context).name;
                        var bayName = vt.GetBay(true, context).name;

                        Logger.Log(LogLevel.Warning, "VT Missing primary voltage. VT will not be transfered to PF." + stName + " " + bayName);

                        dropList.Add(vt);
                        dropList.Add(vtAsset);
                        dropList.Add(vtInfo);
                    }
                    else if (vtInfo.secondaryVoltage == null)
                    {
                        vtInfo.secondaryVoltage = new Voltage()
                        {
                            Value = 0, unit = UnitSymbol.V
                        };

                        var stName  = vt.GetSubstation(true, context).name;
                        var bayName = vt.GetBay(true, context).name;

                        Logger.Log(LogLevel.Warning, "VT Missing secondary voltage. VI will not be transfered to PF." + stName + " " + bayName);

                        dropList.Add(vt);
                        dropList.Add(vtAsset);
                        dropList.Add(vtInfo);
                    }
                }


                // Set relay names to station + bay
                if (inputCimObject is ProtectionEquipment)
                {
                    var relay = inputCimObject as ProtectionEquipment;

                    // get relay station and bay via the switch it is connected to
                    if (relay.ProtectedSwitches != null && relay.ProtectedSwitches.Length > 0)
                    {
                        try
                        {
                            var peSw = context.GetObject <PowerSystemResource>(relay.ProtectedSwitches[0].@ref);
                            var bay  = peSw.GetBay(true, context);
                            var st   = peSw.GetSubstation(true, context);

                            relay.name = st.name + " " + bay.name;
                        }
                        catch (Exception ex)
                        {
                            Logger.Log(LogLevel.Warning, "Cannot find switch: " + relay.ProtectedSwitches[0].@ref + " connected to replay: " + inputCimObject.mRID);
                        }
                    }
                    else
                    {
                        dropList.Add(inputCimObject);
                    }
                }

                // Set electrical values on internal substation cables to 0
                if (inputCimObject is ACLineSegment)
                {
                    var acls = inputCimObject as ACLineSegment;

                    if (acls.PSRType == "InternalCable")
                    {
                        // Set name to internal cable
                        acls.name = "Internal Cable";

                        // Set length to 1 meter
                        acls.length.Value = 1;

                        // Set value to zero
                        acls.r = new Resistance()
                        {
                            Value = 0
                        };
                        acls.r0 = new Resistance()
                        {
                            Value = 0
                        };
                        acls.x = new Reactance()
                        {
                            Value = 0
                        };
                        acls.x0 = new Reactance()
                        {
                            Value = 0
                        };
                        acls.bch = new Susceptance()
                        {
                            Value = 0
                        };
                        acls.b0ch = new Susceptance()
                        {
                            Value = 0
                        };
                        acls.gch = new Conductance()
                        {
                            Value = 0
                        };
                        acls.g0ch = new Conductance()
                        {
                            Value = 0
                        };
                    }
                }

                // Sæt transformer vikling navn og r,x,b,g værdier på vikling 2 til 0
                if (inputCimObject is PowerTransformerEndExt)
                {
                    var ptEnd = inputCimObject as PowerTransformerEndExt;

                    var pt = context.GetObject <PowerTransformer>(ptEnd.PowerTransformer.@ref);

                    ptEnd.name = pt.Substation.name + "_" + pt.name + "_T" + ptEnd.endNumber;

                    /* Don't calculate r,x,b,g anymore.
                     * if (ptEnd.endNumber == "1")
                     * {
                     *  ptEnd.b0 = new Susceptance() { Value = 0 };
                     *  ptEnd.g0 = new Conductance() { Value = 0 };
                     *
                     *  if (ptEnd.ratedU == null ||
                     *      ptEnd.ratedS == null ||
                     *      ptEnd.excitingCurrentZero == null ||
                     *      ptEnd.loss == null ||
                     *      ptEnd.lossZero == null ||
                     *      ptEnd.uk == null)
                     *  {
                     *      // FIX: burde måske logge fejl, men PF skal nok brokke sig
                     *  }
                     *  else
                     *  {
                     *      // Beregn r: loss * (ratedU / ratedS * 1000)^2
                     *      ptEnd.r = new Resistance() { Value = ptEnd.loss.Value * Math.Pow((ptEnd.ratedU.Value / (ptEnd.ratedS.Value * 1000)), 2) };
                     *
                     *      // Beregn g: (LossZero / ratedU^2)
                     *      double g = ptEnd.lossZero.Value / Math.Pow(ptEnd.ratedU.Value, 2);
                     *      ptEnd.g = new Conductance() { Value = g };
                     *
                     *      // Beregn YOC: (excitingCurrentZero*ratedS)/(100 * (ratedU^2))
                     *      double yoc = (ptEnd.excitingCurrentZero.Value * (ptEnd.ratedS.Value * 1000)) / (100 * Math.Pow(ptEnd.ratedU.Value, 2));
                     *
                     *      // Beregn b: SQRT(YOC^2-g^2)
                     *      ptEnd.b = new Susceptance()
                     *      {
                     *          Value = Math.Sqrt(Math.Pow(yoc, 2) - Math.Pow(g, 2))
                     *      };
                     *
                     *      // Beregn Zk: (uk*ratedU^2)/(100*ratedS)
                     *      double zk = (ptEnd.uk.Value * Math.Pow(ptEnd.ratedU.Value, 2)) / (100 * (ptEnd.ratedS.Value * 1000));
                     *
                     *      // Beregn x: SQRT(Zk^2-r^2)
                     *      ptEnd.x = new Reactance()
                     *      {
                     *          Value = Math.Sqrt(
                     *              Math.Pow(zk, 2) - Math.Pow(ptEnd.r.Value, 2)
                     *         )
                     *      };
                     *  }
                     * }
                     */

                    if (ptEnd.endNumber == "2")
                    {
                        // Set value to zero
                        ptEnd.r = new Resistance()
                        {
                            Value = 0
                        };
                        ptEnd.r0 = new Resistance()
                        {
                            Value = 0
                        };
                        ptEnd.x = new Reactance()
                        {
                            Value = 0
                        };
                        ptEnd.x0 = new Reactance()
                        {
                            Value = 0
                        };
                        ptEnd.b = new Susceptance()
                        {
                            Value = 0
                        };
                        ptEnd.b0 = new Susceptance()
                        {
                            Value = 0
                        };
                        ptEnd.g = new Conductance()
                        {
                            Value = 0
                        };
                        ptEnd.g0 = new Conductance()
                        {
                            Value = 0
                        };
                    }
                }

                // Remove 'TRF' from transformer name
                if (inputCimObject is PowerTransformer)
                {
                    inputCimObject.name = inputCimObject.name.Replace("TRF", "");
                }

                // Ensure bay name is max 32 charaters
                if (inputCimObject is IdentifiedObject && inputCimObject.name != null && inputCimObject.name.Length > 32)
                {
                    inputCimObject.name = inputCimObject.name.Substring(0, 32);
                }

                // Set name of disconnectors to ADSK
                if (inputCimObject is Disconnector)
                {
                    inputCimObject.name = "ADSK";
                }

                // Set name of disconnectors to ADSK
                if (inputCimObject is Fuse)
                {
                    inputCimObject.name = "SIKRING";
                }

                // Ensure connectivity nodes / busbars have proper names.
                // Needed by Konstant to support short circuit result extracts etc. PF uses the name of the node/busbar in reports.
                // Also needed to support time series import (Jakob busbar naming)
                if (inputCimObject is ConnectivityNode)
                {
                    var cn = inputCimObject as ConnectivityNode;

                    if (cn.mRID == "1663a3a8-a706-726a-8de5-7f57e2f9e68b")
                    {
                    }

                    if (cn.name == null || cn.name.Length == 0)
                    {
                        var cnNeighbors = cn.GetNeighborConductingEquipments(context);

                        var pt  = cnNeighbors.Find(o => o is PowerTransformer) as PowerTransformer;
                        var bus = cnNeighbors.Find(o => o is BusbarSection);

                        if (pt != null)
                        {
                            var stVoltageLevels = context.GetSubstationVoltageLevels(pt.Substation);

                            var    ptConnections     = context.GetConnections(pt);
                            var    ptTerminal        = ptConnections.First(c => c.ConnectivityNode == cn);
                            var    ptEnds            = pt.GetEnds(context);
                            var    ptEnd             = ptEnds.Find(e => e.Terminal.@ref == ptTerminal.Terminal.mRID);
                            double ptEndVoltageLevel = ptEnd.BaseVoltage;

                            if (pt.name != null)
                            {
                                // HACK SHOULD BE CLEANED UP
                                // Terminal actual exist in source, but get trown away in filter, because nothing connected to it

                                if (!ptConnections.Exists(c => c.Terminal.sequenceNumber == "2"))
                                {
                                    Logger.Log(LogLevel.Info, "Station: " + pt.Substation.name + " Trafo: " + pt.name + " mangler secondær skinne. Vil bliver oprettet");

                                    var ptLvCn = new ConnectivityNode()
                                    {
                                        mRID = Guid.NewGuid().ToString(), name = pt.GetSubstation(true, context).name + "_" + GetVoltageLevelStr(400) + "_" + pt.name.Replace("TRF", "")
                                    };

                                    addList.Add(ptLvCn);

                                    if (stVoltageLevels.Exists(o => o.BaseVoltage == 400))
                                    {
                                        var vl = stVoltageLevels.First(o => o.BaseVoltage == 400);

                                        _mappingContext.ConnectivityNodeToVoltageLevel.Add(ptLvCn, vl);
                                    }
                                    else
                                    {
                                        var vl = new DAX.CIM.PhysicalNetworkModel.VoltageLevel()
                                        {
                                            mRID = Guid.NewGuid().ToString(),
                                            name = "0,4 kV",
                                            EquipmentContainer1 = new VoltageLevelEquipmentContainer()
                                            {
                                                @ref = pt.Substation.mRID
                                            },
                                            BaseVoltage = 400
                                        };

                                        addList.Add(vl);

                                        stVoltageLevels.Add(vl);
                                        _mappingContext.ConnectivityNodeToVoltageLevel.Add(ptLvCn, vl);
                                    }

                                    var ptLvTerminal = new Terminal()
                                    {
                                        mRID             = Guid.NewGuid().ToString(),
                                        phases           = PhaseCode.ABCN,
                                        phasesSpecified  = true,
                                        sequenceNumber   = "2",
                                        ConnectivityNode = new TerminalConnectivityNode()
                                        {
                                            @ref = ptLvCn.mRID
                                        },
                                        ConductingEquipment = new TerminalConductingEquipment {
                                            @ref = pt.mRID
                                        }
                                    };

                                    var ptEnd2 = context.GetPowerTransformerEnds(pt).First(p => p.endNumber == "2");
                                    ptEnd2.Terminal = new TransformerEndTerminal()
                                    {
                                        @ref = ptLvTerminal.mRID
                                    };

                                    addList.Add(ptLvTerminal);
                                }
                            }



                            // IF the PT END CN is connected to a conducting equipment
                            if (cnNeighbors.Exists(o => !(o is PowerTransformer) && o.BaseVoltage > 0.0))
                            {
                                ptEndVoltageLevel = cnNeighbors.First(o => !(o is PowerTransformer) && o.BaseVoltage > 0.0).BaseVoltage;

                                if (stVoltageLevels.Exists(o => o.BaseVoltage == ptEndVoltageLevel))
                                {
                                    var vl = stVoltageLevels.First(o => o.BaseVoltage == ptEndVoltageLevel);

                                    _mappingContext.ConnectivityNodeToVoltageLevel.Add(cn, vl);
                                }
                            }
                            // IF the PT END CN is *not* connected to anything
                            else
                            {
                                // Set CN to PT END voltage level
                                var vl = stVoltageLevels.First(o => o.BaseVoltage == ptEndVoltageLevel);
                                _mappingContext.ConnectivityNodeToVoltageLevel.Add(cn, vl);

                                // If 60 kV transformer secondary side
                                if (ptEndVoltageLevel < 20000 && ptEndVoltageLevel > 5000)
                                {
                                    if (ptEnds.Exists(e => e.BaseVoltage == 60000))
                                    {
                                        EnergyConsumer ec = new EnergyConsumer()
                                        {
                                            mRID = GUIDHelper.CreateDerivedGuid(Guid.Parse(pt.mRID), 1001, true).ToString(),
                                            name = pt.GetSubstation(true, context).name + "_" + GetVoltageLevelStr(ptEndVoltageLevel) + "_" + pt.name.Replace("TRF", ""),
                                            EquipmentContainer = new EquipmentEquipmentContainer()
                                            {
                                                @ref = vl.mRID
                                            },
                                            BaseVoltage = vl.BaseVoltage
                                        };

                                        Terminal ecTerm = new Terminal()
                                        {
                                            mRID = GUIDHelper.CreateDerivedGuid(Guid.Parse(pt.mRID), 1002, true).ToString(),
                                            name = ec.name + "_T1",
                                            ConductingEquipment = new TerminalConductingEquipment()
                                            {
                                                @ref = ec.mRID
                                            },
                                            ConnectivityNode = new TerminalConnectivityNode()
                                            {
                                                @ref = cn.mRID
                                            }
                                        };

                                        addList.Add(ec);
                                        addList.Add(ecTerm);
                                    }
                                }
                            }

                            cn.name = pt.GetSubstation(true, context).name + "_" + GetVoltageLevelStr(ptEndVoltageLevel) + "_" + pt.name.Replace("TRF", "");

                            /*
                             * // Hvis trafo deler node med skinne, eller node er 400 volt, så brug jakob navngivning
                             * if (bus != null || ptEndVoltageLevel == 400)
                             *  cn.name = pt.GetSubstation(true, context).name + "_" + GetVoltageLevelStr(ptEndVoltageLevel) + "_" + pt.name.Replace("TRF", "");
                             * else
                             *  cn.name = "CN";
                             */
                        }
                        else if (bus != null && bus.name != null)
                        {
                            cn.name        = bus.name;
                            cn.description = bus.description;
                        }
                        else
                        {
                            var bay = cn.GetBay(false, context);

                            if (bay != null)
                            {
                                if (cnNeighbors.Count == 1 || cnNeighbors.Exists(n => !(n is Switch)))
                                {
                                    cn.name = bay.name + " ENDE";
                                }
                                else
                                {
                                    cn.name = bay.name;
                                }
                            }
                            else
                            {
                                cn.name = "CN";
                            }
                        }
                    }
                }
            }

            // return objects, except the one dropped
            foreach (var inputObj in input)
            {
                if (!dropList.Contains(inputObj))
                {
                    yield return(inputObj);
                }
            }

            // yield added objects,
            foreach (var inputObj in addList)
            {
                yield return(inputObj);
            }
        }
        public void TestEngumEQWriter()
        {
            bool includeAll = false;

            var mappingContext = new MappingContext();

            var converter = new PNM2PowerFactoryCimConverter(_context.GetAllObjects(),
                                                             new List <IPreProcessor> {
                new ACLSMerger(mappingContext),
                new KonstantPowerFactoryDataPrepareAndFix(mappingContext)
            });

            var outputCimObjects = converter.GetCimObjects().ToList();

            // We need to reinitialize context, because converter has modified objects
            _context = CimContext.Create(outputCimObjects);

            var eqWriter = new EQ_Writer(eqTempFileName, _context, mappingContext, Guid.Parse("48acc999-f45c-475a-b61c-09e7d1001fc1"), "Engum");

            var glWriter = new GL_Writer(glTempFileName);

            HashSet <PhysicalNetworkModel.ConnectivityNode> cnAlreadyWritten = new HashSet <PhysicalNetworkModel.ConnectivityNode>();

            foreach (var cimObject in _context.GetAllObjects())
            {
                if ((cimObject is PhysicalNetworkModel.ConductingEquipment && ((PhysicalNetworkModel.ConductingEquipment)cimObject).BaseVoltage > 5000) ||
                    !(cimObject is PhysicalNetworkModel.ConductingEquipment) ||
                    cimObject is PhysicalNetworkModel.PowerTransformer
                    )
                {
                    if (
                        cimObject is PhysicalNetworkModel.ACLineSegment ||
                        cimObject is PhysicalNetworkModel.BusbarSection ||
                        cimObject is PhysicalNetworkModel.LoadBreakSwitch ||
                        cimObject is PhysicalNetworkModel.Breaker ||
                        cimObject is PhysicalNetworkModel.Disconnector ||
                        cimObject is PhysicalNetworkModel.Fuse ||
                        cimObject is PhysicalNetworkModel.Terminal ||
                        (cimObject is PhysicalNetworkModel.ConnectivityNode && cimObject.IsInsideSubstation()) ||
                        cimObject is PhysicalNetworkModel.Substation ||
                        cimObject is PhysicalNetworkModel.VoltageLevel ||
                        cimObject is PhysicalNetworkModel.Bay ||
                        cimObject is PhysicalNetworkModel.PowerTransformer ||
                        cimObject is PhysicalNetworkModel.PowerTransformerEnd
                        )
                    {
                        // Add substations
                        if (cimObject is PhysicalNetworkModel.Substation && (cimObject.name == "BRB" || cimObject.name == "30904" || includeAll))
                        {
                            var st = cimObject as PhysicalNetworkModel.Substation;

                            if (st.PSRType == "PrimarySubstation" || st.PSRType == "SecondarySubstation" || st.PSRType == "Junction")
                            {
                                eqWriter.AddPNMObject((dynamic)cimObject);

                                // Add location
                                var loc = _context.GetObject <PhysicalNetworkModel.LocationExt>(st.Location.@ref);
                                glWriter.AddLocation(Guid.Parse(st.mRID), loc);
                            }
                        }

                        // Add voltage levels
                        if (cimObject is PhysicalNetworkModel.VoltageLevel && (cimObject.GetSubstation().name == "BRB" || cimObject.GetSubstation().name == "30904" || includeAll))
                        {
                            eqWriter.AddPNMObject((dynamic)cimObject);
                        }

                        // Power transformer
                        if (cimObject is PhysicalNetworkModel.PowerTransformer && (cimObject.GetSubstation().name == "BRB" || cimObject.GetSubstation().name == "30904" || includeAll))
                        {
                            eqWriter.AddPNMObject((dynamic)cimObject);

                            // Add terminals
                            var ci = cimObject as PhysicalNetworkModel.ConductingEquipment;
                            foreach (var tc in _context.GetConnections(ci))
                            {
                                tc.Terminal.phases = PhysicalNetworkModel.PhaseCode.ABCN;
                                tc.Terminal.name   = ci.name + "_T" + tc.Terminal.sequenceNumber;
                                eqWriter.AddPNMObject((dynamic)tc.Terminal);
                            }
                        }

                        // Power transformer end
                        if (cimObject is PhysicalNetworkModel.PowerTransformerEnd && (cimObject.GetSubstation().name == "BRB" || cimObject.GetSubstation().name == "30904" || includeAll))
                        {
                            PhysicalNetworkModel.PowerTransformerEnd ptend = cimObject as PhysicalNetworkModel.PowerTransformerEnd;


                            ptend.r = new PhysicalNetworkModel.Resistance()
                            {
                                Value = 0.1
                            };
                            ptend.r0 = new PhysicalNetworkModel.Resistance()
                            {
                                Value = 0.2
                            };
                            ptend.x = new PhysicalNetworkModel.Reactance()
                            {
                                Value = 0.3
                            };
                            //ptend.x0 = new PhysicalNetworkModel.Reactance() { Value = 0.4 };
                            ptend.b = new PhysicalNetworkModel.Susceptance {
                                Value = 0.5
                            };
                            ptend.b0 = new PhysicalNetworkModel.Susceptance {
                                Value = 0.6
                            };
                            ptend.g = new PhysicalNetworkModel.Conductance {
                                Value = 0.7
                            };
                            ptend.g0 = new PhysicalNetworkModel.Conductance {
                                Value = 0.8
                            };
                            ptend.rground = new PhysicalNetworkModel.Resistance {
                                Value = 0.9
                            };
                            ptend.xground = new PhysicalNetworkModel.Reactance {
                                Value = 0.91
                            };
                            ptend.phaseAngleClock = "11";
                            ptend.grounded        = false;

                            eqWriter.AddPNMObject((dynamic)cimObject);
                        }


                        // Add bays
                        if (cimObject is PhysicalNetworkModel.Bay && (cimObject.GetSubstation().name == "BRB" || cimObject.GetSubstation().name == "30904" || includeAll))
                        {
                            eqWriter.AddPNMObject((dynamic)cimObject);
                        }


                        // Add ACLS
                        if (cimObject is PhysicalNetworkModel.ACLineSegment && cimObject.name != null && (cimObject.name.Contains("BRB-30904") || includeAll))
                        {
                            eqWriter.AddPNMObject((dynamic)cimObject);

                            // Add terminals
                            var ci = cimObject as PhysicalNetworkModel.ConductingEquipment;
                            foreach (var tc in _context.GetConnections(ci))
                            {
                                eqWriter.AddPNMObject((dynamic)tc.Terminal);
                            }

                            // Add location
                            if (ci.PSRType != "InternalCable")
                            {
                                var loc = _context.GetObject <PhysicalNetworkModel.LocationExt>(ci.Location.@ref);
                                glWriter.AddLocation(Guid.Parse(ci.mRID), loc);
                            }
                        }

                        // Add stuff inside substation
                        if (!(cimObject is PhysicalNetworkModel.PowerTransformer) && cimObject.IsInsideSubstation() && (cimObject.GetSubstation().name == "BRB" || cimObject.GetSubstation().name == "30904" || includeAll))
                        {
                            // fix busbar voltage level ref
                            if (cimObject is PhysicalNetworkModel.BusbarSection)
                            {
                                var busbar = cimObject as PhysicalNetworkModel.BusbarSection;
                                busbar.EquipmentContainer.@ref = busbar.GetSubstation().GetVoltageLevel(busbar.BaseVoltage).mRID;
                            }

                            eqWriter.AddPNMObject((dynamic)cimObject);
                            if (cimObject is PhysicalNetworkModel.ConductingEquipment)
                            {
                                var ci = cimObject as PhysicalNetworkModel.ConductingEquipment;
                                foreach (var tc in _context.GetConnections(ci))
                                {
                                    eqWriter.AddPNMObject((dynamic)tc.Terminal);

                                    if (!cnAlreadyWritten.Contains(tc.ConnectivityNode))
                                    {
                                        eqWriter.AddPNMObject((dynamic)tc.ConnectivityNode);
                                    }

                                    cnAlreadyWritten.Add(tc.ConnectivityNode);
                                }
                            }
                        }
                    }
                }
            }

            // Add peterson coil

            var coil = new PhysicalNetworkModel.PetersenCoil();

            var priTrafo = outputCimObjects.Find(o => o is PhysicalNetworkModel.PowerTransformer && o.GetSubstation().name == "BRB");
            var coilSt   = priTrafo.GetSubstation();

            coil.mRID               = Guid.NewGuid().ToString();
            coil.name               = "Test coil";
            coil.BaseVoltage        = 10000;
            coil.EquipmentContainer = new PhysicalNetworkModel.EquipmentEquipmentContainer()
            {
                @ref = coilSt.GetVoltageLevel(10000).mRID
            };
            coil.mode     = PhysicalNetworkModel.PetersenCoilModeKind.@fixed;
            coil.nominalU = new PhysicalNetworkModel.Voltage()
            {
                Value = 10000
            };
            coil.positionCurrent = new PhysicalNetworkModel.CurrentFlow()
            {
                Value = 99.99
            };
            coil.offsetCurrent = new PhysicalNetworkModel.CurrentFlow {
                Value = 9.99
            };
            coil.r = new PhysicalNetworkModel.Resistance()
            {
                Value = 9.99
            };
            coil.xGroundMin = new PhysicalNetworkModel.Reactance {
                Value = 0.99
            };
            coil.xGroundMax = new PhysicalNetworkModel.Reactance {
                Value = 9.99
            };
            coil.xGroundNominal = new PhysicalNetworkModel.Reactance {
                Value = 4.99
            };



            var trafoCons = _context.GetConnections(priTrafo);

            var secTer = trafoCons.Find(o => o.Terminal.sequenceNumber == "1");

            var coilTer = new PhysicalNetworkModel.Terminal();

            coilTer.mRID = Guid.NewGuid().ToString();
            coilTer.ConductingEquipment = new PhysicalNetworkModel.TerminalConductingEquipment()
            {
                @ref = coil.mRID
            };
            coilTer.ConnectivityNode = new PhysicalNetworkModel.TerminalConnectivityNode()
            {
                @ref = secTer.ConnectivityNode.mRID
            };
            coilTer.phases = PhysicalNetworkModel.PhaseCode.N;



            eqWriter.AddPNMObject(coil);
            eqWriter.AddPNMObject(coilTer);

            eqWriter.Close();
            glWriter.Close();

            string startPath = folder + "\\files";
            string zipPath   = folder + "\\export.zip";

            File.Delete(zipPath);

            ZipFile.CreateFromDirectory(startPath, zipPath);
        }