private void TransformToTopologyElement(ResourceDescription modelEntity)
        {
            DMSType dmsType;

            dmsType = GetDMSTypeOfTopologyElement(modelEntity.Id);

            if (dmsType == DMSType.DISCRETE)
            {
                Measurement newDiscrete = GetPopulatedDiscreteMeasurement(modelEntity);
                Measurements.Add(newDiscrete.Id, newDiscrete);
                Provider.Instance.MeasurementProvider.AddDiscreteMeasurement(newDiscrete as DiscreteMeasurement);
            }
            else if (dmsType == DMSType.ANALOG)
            {
                Measurement newAnalog = GetPopulatedAnalogMeasurement(modelEntity);
                Measurements.Add(newAnalog.Id, newAnalog);
                Provider.Instance.MeasurementProvider.AddAnalogMeasurement(newAnalog as AnalogMeasurement);
            }
            else if (dmsType != DMSType.MASK_TYPE && dmsType != DMSType.BASEVOLTAGE)
            {
                ITopologyElement newElement = GetPopulatedElement(modelEntity);
                TopologyElements.Add(newElement.Id, newElement);
                if (dmsType == DMSType.ENERGYSOURCE)
                {
                    EnergySources.Add(newElement.Id);
                }
                ElementConnections.Add(modelEntity.Id, (GetAllReferencedElements(modelEntity)));
            }
        }
        public IMaxTree <ElementType> BuildMaxTree(ElementType[] element_array, IComparer <ElementType> element_value_comparer, ITopologyElement topology, int real_element_count, IProgressReporter reporter)
        {
            this.d_element_array        = element_array;
            this.element_value_comparer = element_value_comparer;
            this.element_index_comparer = new ComparerArrayIndex <ElementType>(element_value_comparer, element_array);

            this.d_topology = topology;
            this.d_reporter = reporter;

            this.d_done = 0;
            this.d_elements_to_queued    = new bool[d_element_array.Length];
            this.d_neigbor_element_array = new int[d_topology.MaximumConnectivity];
            this.d_fringe          = new PriorityQueueC5 <int>(element_index_comparer);
            this.d_component_stack = new Stack <Tuple <ElementType, IList <int>, IList <MaxTreeNode <ElementType> > > >();



            d_fringe.Enqueue(0);
            d_elements_to_queued[0] = true;
            // Build tree
            while (d_fringe.Count != 0)
            {
                Process(d_fringe.PeekLast());
            }
            Tuple <ElementType, IList <int>, IList <MaxTreeNode <ElementType> > > component = d_component_stack.Pop();
            MaxTreeNode <ElementType> bottom_level_node = new MaxTreeNode <ElementType>(component.Item1, component.Item2, component.Item3, element_value_comparer);

            return(new MaxTree <ElementType>(bottom_level_node, d_element_array.Length, real_element_count, element_value_comparer));
        }
        private async Task <ITopologyElement> CreateNoScadaMeasurementAsync(ITopologyElement element)
        {
            string verboseMessage = $"{baseLogString} entering CreateNoScadaMeasurement method.";

            Logger.LogVerbose(verboseMessage);

            DMSType dMSType = GetDMSTypeOfTopologyElement(element.Id);

            if (dMSType == DMSType.LOADBREAKSWITCH ||
                dMSType == DMSType.BREAKER ||
                dMSType == DMSType.FUSE ||
                dMSType == DMSType.DISCONNECTOR)
            {
                ArtificalDiscreteMeasurement measurement = GetNoScadaDiscreteMeasurement();
                element.Measurements.Add(measurement.Id, "SWITCH_STATUS");
                measurement.ElementId = element.Id;
                var measurementProviderClient = MeasurementProviderClient.CreateClient();
                await measurementProviderClient.AddDiscreteMeasurement(measurement);

                measurementProviderClient = MeasurementProviderClient.CreateClient();
                await measurementProviderClient.AddMeasurementElementPair(measurement.Id, element.Id);
            }

            return(element);
        }
        public IMaxTree <ElementType> BuildMaxTree(ElementType[] element_array, IComparer <ElementType> element_value_comparer, ITopologyElement topology, int real_element_count, IProgressReporter reporter)
        {
            this.d_element_array         = element_array;
            this.element_value_comparer  = element_value_comparer;
            this.element_index_comparer  = new ComparerArrayIndex <ElementType>(element_value_comparer, element_array);
            this.d_topology              = topology;
            this.d_elements_to_processed = new bool[d_element_array.Length];
            this.d_neigbor_element_array = new int[d_topology.MaximumConnectivity];
            this.d_fringe            = new Stack <OrderedBag <int> >();
            this.d_component_stack   = new Stack <Tuple <ElementType, IList <int>, IList <MaxTreeNode <ElementType> > > >();
            this.d_bottom_level_node = null;

            process(0);
            // build tree
            while (d_fringe.Count != 0)
            {
                if (d_fringe.Peek().Count == 0)
                {
                    decrease_process_level(); // continue on a lower level
                }
                else
                {
                    // otherwise keep on processing the fringe
                    process(d_fringe.Peek().RemoveFirst());
                }
            }
            return(new MaxTree <ElementType>(d_bottom_level_node, d_element_array.Length, real_element_count, element_value_comparer));
        }
Пример #5
0
        private void DeEnergizeElementsUnder(ITopologyElement element)
        {
            Stack <ITopologyElement> stack = new Stack <ITopologyElement>();

            stack.Push(element);
            ITopologyElement nextElement;

            while (stack.Count > 0)
            {
                nextElement          = stack.Pop();
                nextElement.IsActive = false;
                if (nextElement is Field field)
                {
                    foreach (var member in field.Members)
                    {
                        TurnOffAllMeasurement(member.Measurements);
                        member.IsActive = false;
                    }
                }

                TurnOffAllMeasurement(nextElement.Measurements);

                foreach (var child in nextElement.SecondEnd)
                {
                    if (!reclosers.Contains(child.Id))
                    {
                        stack.Push(child);
                    }
                }
            }
        }
Пример #6
0
 public Field(ITopologyElement firstElement) : base(++fieldNumber)
 {
     Members = new List <ITopologyElement>()
     {
         firstElement
     };
     Mrid = $"F_{fieldNumber}";
     Name = $"F_{fieldNumber}";
 }
Пример #7
0
 public void AddElement(ITopologyElement newElement)
 {
     if (!TopologyElements.ContainsKey(newElement.Id))
     {
         TopologyElements.Add(newElement.Id, newElement);
     }
     else
     {
         //Logger.Instance.LogWarn($"Topology element with GID 0x{newElement.Id.ToString("X16")} is already added.");
     }
 }
Пример #8
0
        private ITopology CalculateLoadFlowFromRecloser(ITopologyElement recloser, ITopology topology, Dictionary <long, float> loadOfFeeders)
        {
            long measurementGid = 0;

            if (recloser.Measurements.Count == 1)
            {
                //dogovor je da prekidaci imaju samo discrete measurement
                measurementGid = recloser.Measurements.First().Key;
            }
            else
            {
                logger.LogWarn($"[CalculateLoadFlowFromRecloser] Recloser with GID 0x{recloser.Id.ToString("X16")} does not have proper measurements.");
            }

            if (recloser.FirstEnd != null && recloser.SecondEnd.Count == 1)
            {
                if (recloser.FirstEnd.IsActive && !recloser.SecondEnd.First().IsActive)
                {
                    if (IsElementEnergized(recloser, out float load))
                    {
                        CalculateLoadFlowUpsideDown(recloser.SecondEnd.First(), recloser.Id, recloser.FirstEnd.Feeder, loadOfFeeders);
                    }
                    else
                    {
                        Thread thread = new Thread(() => CommandToRecloser(measurementGid, 0, CommandOriginType.CE_COMMAND, recloser));
                        thread.Start();
                    }
                }
                else if (!recloser.FirstEnd.IsActive && recloser.SecondEnd.First().IsActive)
                {
                    if (IsElementEnergized(recloser, out float load))
                    {
                        CalculateLoadFlowUpsideDown(recloser.FirstEnd, recloser.Id, recloser.SecondEnd.First().Feeder, loadOfFeeders);
                    }
                    else
                    {
                        Thread thread = new Thread(() => CommandToRecloser(measurementGid, 0, CommandOriginType.CE_COMMAND, recloser));
                        thread.Start();
                    }
                }
                else
                {
                    //TODO: pitati asistente, da li da se prenese na Validate
                    scadaCommanding.SendDiscreteCommand(measurementGid, 1, CommandOriginType.CE_COMMAND);
                    recloser.IsActive = false;
                }
            }
            else
            {
                logger.LogDebug($"[CalculateLoadFlowFromRecloser] Recloser with GID 0x{recloser.Id.ToString("X16")} does not have both ends, or have more than one on one end.");
            }
            return(topology);
        }
Пример #9
0
 public Feeder(ITopologyElement element) : base(element.Id)
 {
     Id             = element.Id;
     Description    = element.Description;
     Mrid           = element.Mrid;
     Name           = element.Name;
     NominalVoltage = element.NominalVoltage;
     FirstEnd       = element.FirstEnd;
     SecondEnd      = element.SecondEnd;
     DmsType        = element.DmsType;
     Measurements   = element.Measurements;
     IsRemote       = element.IsRemote;
     IsActive       = element.IsActive;
 }
Пример #10
0
        private void ConnectTwoNodes(ITopologyElement newNode, ITopologyElement parent)
        {
            bool newElementIsField    = TopologyHelper.Instance.GetElementTopologyStatus(newNode.Id) == TopologyStatus.Field;
            bool parentElementIsField = TopologyHelper.Instance.GetElementTopologyStatus(parent.Id) == TopologyStatus.Field;

            if (newElementIsField && !parentElementIsField)
            {
                var field = new Field(newNode);
                field.FirstEnd   = parent;
                newNode.FirstEnd = parent;
                fields.Add(field);
                parent.SecondEnd.Add(field);
            }
            else if (newElementIsField && parentElementIsField)
            {
                try
                {
                    GetField(parent.Id).Members.Add(newNode);
                    newNode.FirstEnd = parent;
                    parent.SecondEnd.Add(newNode);
                }
                catch (Exception)
                {
                    string message = $"Element with GID 0x{parent.Id.ToString("X16")} has no field.";
                    logger.LogDebug(message);
                    throw new Exception(message);
                }
            }
            else if (!newElementIsField && parentElementIsField)
            {
                var field = GetField(parent.Id);
                if (field == null)
                {
                    string message = $"Element with GID 0x{parent.Id.ToString("X16")} has no field.";
                    logger.LogDebug(message);
                    throw new Exception(message);
                }
                else
                {
                    field.SecondEnd.Add(newNode);
                    parent.SecondEnd.Add(newNode);
                    newNode.FirstEnd = field;
                }
            }
            else
            {
                newNode.FirstEnd = parent;
                parent.SecondEnd.Add(newNode);
            }
        }
Пример #11
0
        public bool GetElementByGid(long gid, out ITopologyElement topologyElement)
        {
            bool success = false;

            if (TopologyElements.ContainsKey(gid))
            {
                topologyElement = TopologyElements[gid];
                success         = true;
            }
            else
            {
                topologyElement = null;
            }
            return(success);
        }
Пример #12
0
        private void CreateNoScadaMeasurement(ITopologyElement element)
        {
            DMSType dMSType = GetDMSTypeOfTopologyElement(element.Id);

            if (dMSType == DMSType.LOADBREAKSWITCH ||
                dMSType == DMSType.BREAKER ||
                dMSType == DMSType.FUSE ||
                dMSType == DMSType.DISCONNECTOR)
            {
                ArtificalDiscreteMeasurement measurement = GetNoScadaDiscreteMeasurement();
                element.Measurements.Add(measurement.Id, "SWITCH_STATUS");
                measurement.ElementId = element.Id;
                Provider.Instance.MeasurementProvider.AddDiscreteMeasurement(measurement);
                Provider.Instance.MeasurementProvider.AddMeasurementElementPair(measurement.Id, element.Id);
            }
        }
Пример #13
0
 public Recloser(ITopologyElement element) : base(element.Id)
 {
     Id               = element.Id;
     Description      = element.Description;
     Mrid             = element.Mrid;
     Name             = element.Name;
     NominalVoltage   = element.NominalVoltage;
     FirstEnd         = element.FirstEnd;
     SecondEnd        = element.SecondEnd;
     DmsType          = element.DmsType;
     Measurements     = element.Measurements;
     IsRemote         = element.IsRemote;
     IsActive         = element.IsActive;
     NoReclosing      = element.NoReclosing;
     NumberOfTry      = 0;
     MaxNumberOfTries = 3;
 }
Пример #14
0
        private async Task DeEnergizeElementsUnder(ITopologyElement element)
        {
            string verboseMessage = $"{baseLogString} DeEnergizeElementsUnder method called => Element: {element?.Id:X16}.";

            Logger.LogVerbose(verboseMessage);

            Stack <ITopologyElement> stack = new Stack <ITopologyElement>();

            stack.Push(element);
            ITopologyElement nextElement;

            while (stack.Count > 0)
            {
                nextElement          = stack.Pop();
                nextElement.IsActive = false;
                if (nextElement is Field field)
                {
                    foreach (var member in field.Members)
                    {
                        await TurnOffAllMeasurement(member.Measurements);

                        member.IsActive = false;
                    }
                }

                await TurnOffAllMeasurement(nextElement.Measurements);

                foreach (var child in nextElement.SecondEnd)
                {
                    if (!reclosers.Contains(child.Id))
                    {
                        stack.Push(child);
                    }
                }
            }
        }
 public IMaxTree <ElementType> BuildMaxTree(ElementType[] element_array, IComparer <ElementType> element_value_comparer, ITopologyElement topology, int real_element_count)
 {
     return(BuildMaxTree(element_array, element_value_comparer, topology, real_element_count, null));
 }
Пример #16
0
 public MaxTreeAutoDual(IAlgebraReal <ElementType> algebra, IMaxTreeBuilder <ElementType> builder, ITopologyElement topology, ElementType[] element_values)
 {
     this.algebra        = algebra;
     this.max_tree       = builder.BuildMaxTree(element_values, new ComparerNatural <ElementType>(), topology, element_values.Length);
     this.min_tree       = builder.BuildMaxTree(element_values, new ComparerNatural <ElementType>(true), topology, element_values.Length);
     this.element_values = ToolsCollection.Copy(element_values);
 }
Пример #17
0
        private async Task CommandToRecloser(long measurementGid, int value, CommandOriginType originType, ITopologyElement recloser)
        {
            string verboseMessage = $"{baseLogString} CommandToRecloser method called.";

            Logger.LogVerbose(verboseMessage);

            if (recloser == null)
            {
                string message = $"{baseLogString} CommandToRecloser => NULL value has been passed instead of element.";
                Logger.LogError(message);
                throw new Exception(message);
            }

            if (!(recloser is Recloser))
            {
                string message = $"{baseLogString} CommandToRecloser => Element with GID {recloser.Id:X16} is not a recloser.";
                Logger.LogError(message);
                throw new Exception(message);
            }

            Logger.LogDebug($"{baseLogString} CommandToRecloser => Enetring in sleep for 20 seconds.");
            await Task.Delay(recloserInterval);

            Logger.LogDebug($"{baseLogString} CommandToRecloser => Waking up after 20 seconds.");

            var topologyProviderClient = TopologyProviderClient.CreateClient();
            int counter = await topologyProviderClient.GetRecloserCount(recloser.Id);

            if (((Recloser)recloser).MaxNumberOfTries > counter)
            {
                topologyProviderClient = TopologyProviderClient.CreateClient();
                await topologyProviderClient.RecloserOpened(recloser.Id);

                Logger.LogDebug($"{baseLogString} CommandToRecloser => Calling SendDiscreteCommand method from measurement provider. Measurement GID: {measurementGid:X16}, Value: {value}, OriginType {originType}.");
                var measurementProviderClient = MeasurementProviderClient.CreateClient();
                await measurementProviderClient.SendSingleDiscreteCommand(measurementGid, value, originType);

                Logger.LogDebug($"{baseLogString} CommandToRecloser => SendDiscreteCommand method has been successfully called.");
            }
        }
Пример #18
0
        public static void GetShellRBA <RasterType>(IImageRaster <RasterType, bool> source, ITopologyElement topology, IImageRaster <RasterType, bool> target, bool border_is_shell)
            where RasterType : IRasterInteger
        {
            int[] element_neigbour_array = new int[topology.MaximumConnectivity];


            for (int element_index = 0; element_index < source.Raster.ElementCount; element_index++)
            {
                if (source.GetElementValue(element_index))
                {
                    bool is_shell = false;
                    topology.ElementNeighboursRBA(element_index, element_neigbour_array);

                    foreach (int other_element_index in element_neigbour_array)
                    {
                        if (other_element_index != -1)
                        {
                            if (!source.GetElementValue(other_element_index))
                            {
                                is_shell = true;
                            }
                        }
                        else
                        {
                            if (border_is_shell)
                            {
                                is_shell = true;
                            }
                        }
                    }

                    if (is_shell)
                    {
                        target.SetElementValue(element_index, true);
                    }
                }
            }
        }
        private void ConnectTwoNodes(ITopologyElement newNode, ITopologyElement parent)
        {
            string verboseMessage = $"{baseLogString} ConnectTwoNodes method called. New node GID {newNode?.Id:X16}, Parent node GID {parent?.Id:X16}.";

            Logger.LogVerbose(verboseMessage);

            if (newNode == null)
            {
                string message = $"{baseLogString} ConnectTwoNodes => New node is null.";
                Logger.LogError(message);
                throw new Exception(message);
            }

            if (parent == null)
            {
                string message = $"{baseLogString} ConnectTwoNodes => Parent node is null.";
                Logger.LogError(message);
                throw new Exception(message);
            }

            bool newElementIsField    = TopologyHelper.Instance.GetElementTopologyStatus(newNode.Id) == TopologyStatus.Field;
            bool parentElementIsField = TopologyHelper.Instance.GetElementTopologyStatus(parent.Id) == TopologyStatus.Field;

            if (newElementIsField && !parentElementIsField)
            {
                var field = new Field(newNode);
                field.FirstEnd   = parent;
                newNode.FirstEnd = parent;
                fields.Add(field);
                parent.SecondEnd.Add(field);
            }
            else if (newElementIsField && parentElementIsField)
            {
                try
                {
                    GetField(parent.Id).Members.Add(newNode);
                    newNode.FirstEnd = parent;
                    parent.SecondEnd.Add(newNode);
                }
                catch (Exception)
                {
                    string message = $"{baseLogString} ConnectTwoNodes => Element with GID {parent.Id:X16} has no field.";
                    Logger.LogError(message);
                    throw new Exception(message);
                }
            }
            else if (!newElementIsField && parentElementIsField)
            {
                var field = GetField(parent.Id);
                if (field == null)
                {
                    string message = $"{baseLogString} ConnectTwoNodes => Element with GID {parent.Id:X16} has no field.";
                    Logger.LogError(message);
                    throw new Exception(message);
                }
                else
                {
                    field.SecondEnd.Add(newNode);
                    parent.SecondEnd.Add(newNode);
                    newNode.FirstEnd = field;
                }
            }
            else
            {
                newNode.FirstEnd = parent;
                parent.SecondEnd.Add(newNode);
            }
        }
Пример #20
0
        private async Task <Tuple <bool, float> > IsElementEnergized(ITopologyElement element)
        {
            string verboseMessage = $"{baseLogString} IsElementEnergized method called => Element: {element?.Id:X16}.";

            Logger.LogVerbose(verboseMessage);

            float load      = 0;
            bool  pastState = element.IsActive;

            element.IsActive = true;

            foreach (var measurement in element.Measurements)
            {
                if ((DMSType)ModelCodeHelper.ExtractTypeFromGlobalId(measurement.Key) == DMSType.DISCRETE ||
                    measurement.Key < 10000)
                {
                    Logger.LogDebug($"{baseLogString} IsElementEnergized => Getting discrete value of {measurement.Key:X16} from measurement provider.");
                    var  measurementProviderClient = MeasurementProviderClient.CreateClient();
                    bool isOpen = await measurementProviderClient.GetDiscreteValue(measurement.Key);

                    Logger.LogDebug($"{baseLogString} IsElementEnergized => Discrete value of {measurement.Key:X16} has been delivered successfully. Result is [{isOpen}].");

                    // Value je true ako je prekidac otvoren, tada je element neaktivan
                    element.IsActive = !isOpen;
                    break;
                }
            }

            if (element.IsActive)
            {
                if (!pastState)
                {
                    await TurnOnAllMeasurement(element.Measurements);
                }

                List <AnalogMeasurement> analogMeasurements = await GetMeasurements(element.Measurements);

                if (element.DmsType.Equals(DMSType.SYNCHRONOUSMACHINE.ToString()))
                {
                    if (!syncMachines.ContainsKey(element.Id))
                    {
                        syncMachines.Add(element.Id, element);
                    }
                }
                else
                {
                    if (element.IsRemote)
                    {
                        float power   = 0;
                        float voltage = 0;
                        foreach (var analogMeasurement in analogMeasurements)
                        {
                            if (analogMeasurement.GetMeasurementType().Equals(AnalogMeasurementType.POWER.ToString()))
                            {
                                power = analogMeasurement.GetCurrentValue();
                            }
                            else if (analogMeasurement.GetMeasurementType().Equals(AnalogMeasurementType.VOLTAGE.ToString()))
                            {
                                voltage = analogMeasurement.GetCurrentValue();
                            }
                        }

                        if (power != 0 && voltage != 0)
                        {
                            load = (float)Math.Round(power / voltage);
                        }
                    }
                    else if (element is EnergyConsumer consumer)
                    {
                        if (dailyCurves.TryGetValue(EnergyConsumerTypeToDailyCurveConverter.GetDailyCurveType(consumer.Type), out DailyCurve curve))
                        {
                            load = (float)Math.Round(curve.GetValue((short)DateTime.Now.Hour) * 1000 / 220);
                        }
                    }
                }
            }

            return(new Tuple <bool, float>(element.IsActive, load));
        }
Пример #21
0
        private async Task SyncMachine(ITopologyElement element, Dictionary <long, float> loadOfFeeders)
        {
            string verboseMessage = $"{baseLogString} SyncMachine method called. Element with GID {element?.Id:X16}";

            Logger.LogVerbose(verboseMessage);

            if (element == null)
            {
                string message = $"{baseLogString} UpdateLoadFlow => Element is null.";
                Logger.LogError(message);
                throw new Exception(message);
            }

            if (!(element is SynchronousMachine))
            {
                string message = $"{baseLogString} UpdateLoadFlow => Element is not SynchronousMachine.";
                Logger.LogError(message);
                throw new Exception(message);
            }

            AnalogMeasurement powerMeasurement   = null;
            AnalogMeasurement voltageMeasurement = null;

            if (element.Feeder != null)
            {
                if (loadOfFeeders.TryGetValue(element.Feeder.Id, out float feederLoad))
                {
                    float machineCurrentChange;
                    if (feederLoad > 36)
                    {
                        float improvementFactor = feederLoad - 36;

                        machineCurrentChange = (((SynchronousMachine)element).Capacity >= improvementFactor)
                                                    ? improvementFactor
                                                    : ((SynchronousMachine)element).Capacity;
                    }
                    else
                    {
                        machineCurrentChange = 0;
                    }

                    foreach (var meas in element.Measurements)
                    {
                        if (meas.Value.Equals(AnalogMeasurementType.POWER.ToString()))
                        {
                            Logger.LogDebug($"{baseLogString} UpdateLoadFlow => Calling GetAnalogMeasurement method from measurement provider. Measurement GID {meas.Key:X16}.");
                            var measurementProviderClient = MeasurementProviderClient.CreateClient();
                            powerMeasurement = await measurementProviderClient.GetAnalogMeasurement(meas.Key);

                            Logger.LogDebug($"{baseLogString} UpdateLoadFlow => GetAnalogMeasurement method called successfully.");

                            if (powerMeasurement == null)
                            {
                                Logger.LogError($"{baseLogString} UpdateLoadFlow => Synchronous machine with GID {element.Id:X16} does not have POWER measurement.");
                            }
                        }

                        if (meas.Value.Equals(AnalogMeasurementType.VOLTAGE.ToString()))
                        {
                            Logger.LogDebug($"{baseLogString} UpdateLoadFlow => Calling GetAnalogMeasurement method from measurement provider. Measurement GID {meas.Key:X16}.");
                            var measurementProviderClient = MeasurementProviderClient.CreateClient();
                            voltageMeasurement = await measurementProviderClient.GetAnalogMeasurement(meas.Key);

                            Logger.LogDebug($"{baseLogString} UpdateLoadFlow => GetAnalogMeasurement method called successfully.");

                            if (voltageMeasurement == null)
                            {
                                Logger.LogError($"{baseLogString} UpdateLoadFlow => Synchronous machine with GID {element.Id:X16} does not have VOLTAGE measurement.");
                            }
                        }
                    }

                    if (powerMeasurement != null && voltageMeasurement != null)
                    {
                        float newNeededPower = machineCurrentChange * voltageMeasurement.GetCurrentValue();
                        float newSMPower     = (((SynchronousMachine)element).Capacity >= newNeededPower)
                                                    ? newNeededPower
                                                    : ((SynchronousMachine)element).Capacity;

                        Logger.LogDebug($"{baseLogString} UpdateLoadFlow => Calling SendAnalogCommand method from measurement provider. Measurement GID {powerMeasurement.Id:X16}, Value {newSMPower}.");
                        var measurementProviderClient = MeasurementProviderClient.CreateClient();
                        await measurementProviderClient.SendSingleAnalogCommand(powerMeasurement.Id, newSMPower, CommandOriginType.CE_COMMAND);

                        Logger.LogDebug($"{baseLogString} UpdateLoadFlow => SendAnalogCommand method called successfully.");

                        Dictionary <long, AnalogModbusData> data = new Dictionary <long, AnalogModbusData>(1)
                        {
                            { powerMeasurement.Id, new AnalogModbusData(newSMPower, AlarmType.NO_ALARM, powerMeasurement.Id, CommandOriginType.CE_COMMAND) }
                        };

                        Logger.LogDebug($"{baseLogString} UpdateLoadFlow => Calling UpdateAnalogMeasurement method from measurement provider.");
                        measurementProviderClient = MeasurementProviderClient.CreateClient();
                        await measurementProviderClient.UpdateAnalogMeasurement(data);

                        Logger.LogDebug($"{baseLogString} UpdateLoadFlow => UpdateAnalogMeasurement method called successfully.");

                        loadOfFeeders[element.Feeder.Id] -= newSMPower / voltageMeasurement.GetCurrentValue();
                    }
                    else
                    {
                        Logger.LogError($"{baseLogString} UpdateLoadFlow => Synchronous machine with GID {element.Id:X16} does not have measurements for calculating CURRENT.");
                    }
                }
            }
            else
            {
                Logger.LogError($"{baseLogString} UpdateLoadFlow => Synchronous machine with GID {element.Id:X16} does not belond to any feeder.");
            }
        }
Пример #22
0
        public Tuple <int[, ], float[, ]> build_super_shape(float[] image, int neigbour_count, ITopologyElement topology)
        {
            int[,] neigbour_elements    = new int[image.Length, neigbour_count];
            float[,] neigbour_distances = new float[image.Length, neigbour_count];
            Parallel.For(0, image.Length, index_element =>
            {
                //int index_current = 0;
                //int index_fringe_end = 0;
                for (int i = 0; i < neigbour_count; i++)
                {
                }
            });


            return(new Tuple <int[, ], float[, ]>(neigbour_elements, neigbour_distances));
        }
Пример #23
0
        private void SyncMachine(ITopologyElement element, Dictionary <long, float> loadOfFeeders)
        {
            AnalogMeasurement powerMeasurement   = null;
            AnalogMeasurement voltageMeasurement = null;

            if (element.Feeder != null)
            {
                if (loadOfFeeders.TryGetValue(element.Feeder.Id, out float feederLoad))
                {
                    float machineCurrentChange;
                    if (feederLoad > 36)
                    {
                        float improvementFactor = feederLoad - 36;

                        machineCurrentChange = (((SynchronousMachine)element).Capacity >= improvementFactor)
                                                    ? improvementFactor
                                                    : ((SynchronousMachine)element).Capacity;
                    }
                    else
                    {
                        machineCurrentChange = 0;
                    }

                    foreach (var meas in element.Measurements)
                    {
                        if (meas.Value.Equals(AnalogMeasurementType.POWER.ToString()))
                        {
                            if (!Provider.Instance.MeasurementProvider.TryGetAnalogMeasurement(meas.Key, out powerMeasurement))
                            {
                                logger.LogError($"[Load flow] Synchronous machine with GID 0x{element.Id:X16} does not have POWER measurement.");
                            }
                        }

                        if (meas.Value.Equals(AnalogMeasurementType.VOLTAGE.ToString()))
                        {
                            if (!Provider.Instance.MeasurementProvider.TryGetAnalogMeasurement(meas.Key, out voltageMeasurement))
                            {
                                logger.LogError($"[Load flow] Synchronous machine with GID 0x{element.Id:X16} does not have VOLTAGE measurement.");
                            }
                        }
                    }

                    if (powerMeasurement != null && voltageMeasurement != null)
                    {
                        float newNeededPower = machineCurrentChange * voltageMeasurement.GetCurrentValue();
                        float newSMPower     = (((SynchronousMachine)element).Capacity >= newNeededPower)
                                                    ? newNeededPower
                                                    : ((SynchronousMachine)element).Capacity;

                        scadaCommanding.SendAnalogCommand(powerMeasurement.Id, newSMPower, CommandOriginType.CE_COMMAND);

                        Dictionary <long, AnalogModbusData> data = new Dictionary <long, AnalogModbusData>(1)
                        {
                            { powerMeasurement.Id, new AnalogModbusData(newSMPower, AlarmType.NO_ALARM, powerMeasurement.Id, CommandOriginType.CE_COMMAND) }
                        };

                        Provider.Instance.MeasurementProvider.UpdateAnalogMeasurement(data);

                        loadOfFeeders[element.Feeder.Id] -= newSMPower / voltageMeasurement.GetCurrentValue();
                    }
                    else
                    {
                        logger.LogError($"[Load flow] Synchronous machine with GID 0x{element.Id:X16} does not have CURRENT measurement.");
                    }
                }
            }
            else
            {
                logger.LogWarn($"[Load flow] Synchronous machine with GID 0x{element.Id:X16} does not belond to any feeder.");
            }
        }
Пример #24
0
 private void CommandToRecloser(long measurementGid, int value, CommandOriginType originType, ITopologyElement recloser)
 {
     Thread.Sleep(10000);
     if (!((Recloser)recloser).IsReachedMaximumOfTries())
     {
         scadaCommanding.SendDiscreteCommand(measurementGid, value, originType);
         ((Recloser)recloser).NumberOfTry++;
     }
 }
Пример #25
0
        private void CalculateLoadFlowUpsideDown(ITopologyElement element, long sourceElementGid, ITopologyElement feeder, Dictionary <long, float> loadOfFeeders)
        {
            Stack <Tuple <ITopologyElement, long> > stack = new Stack <Tuple <ITopologyElement, long> >();

            stack.Push(new Tuple <ITopologyElement, long>(element, sourceElementGid));

            Tuple <ITopologyElement, long> tuple;
            ITopologyElement nextElement;
            long             sourceGid;

            while (stack.Count > 0)
            {
                tuple       = stack.Pop();
                nextElement = tuple.Item1;
                sourceGid   = tuple.Item2;

                if (IsElementEnergized(nextElement, out float load))
                {
                    if (!nextElement.DmsType.Equals(DMSType.ENERGYCONSUMER.ToString()) &&
                        nextElement.FirstEnd.Id != sourceGid)
                    {
                        stack.Push(new Tuple <ITopologyElement, long>(nextElement.FirstEnd, nextElement.Id));
                    }

                    foreach (var child in nextElement.SecondEnd)
                    {
                        if (child.Id != sourceGid)
                        {
                            stack.Push(new Tuple <ITopologyElement, long>(child, nextElement.Id));
                        }
                    }

                    if (feeder != null)
                    {
                        if (loadOfFeeders.ContainsKey(feeder.Id))
                        {
                            loadOfFeeders[feeder.Id] += load;
                        }
                        else
                        {
                            loadOfFeeders.Add(feeder.Id, load);
                        }
                    }
                }
                else
                {
                    if (nextElement.DmsType.Equals(DMSType.FUSE.ToString()))
                    {
                        DeEnergizeElementsUnder(nextElement);
                    }
                    else
                    {
                        foreach (var child in nextElement.SecondEnd)
                        {
                            if (child.Id != sourceGid)
                            {
                                stack.Push(new Tuple <ITopologyElement, long>(child, nextElement.Id));
                            }
                        }
                    }
                }
            }
        }
Пример #26
0
        private async Task TransformToTopologyElementAsync(ResourceDescription modelEntity)
        {
            string verboseMessage = $"{baseLogString} entering TransformToTopologyElement method.";

            Logger.LogVerbose(verboseMessage);

            DMSType dmsType;

            dmsType = GetDMSTypeOfTopologyElement(modelEntity.Id);

            if (dmsType == DMSType.DISCRETE)
            {
                Measurement newDiscrete = await GetPopulatedDiscreteMeasurement(modelEntity);

                if (!await Measurements.ContainsKeyAsync(newDiscrete.Id))
                {
                    await Measurements.SetAsync(newDiscrete.Id, newDiscrete);                     //contains moze da bude false, a da kad doje ova linija na red, da vrednost bude popunjena, zato SetAsync, ali onda je sam if suvisan (ne znam da li je kljucan za neku logiku...)
                }
                var measurementProviderClient = MeasurementProviderClient.CreateClient();
                await measurementProviderClient.AddDiscreteMeasurement(newDiscrete as DiscreteMeasurement);
            }
            else if (dmsType == DMSType.ANALOG)
            {
                Measurement newAnalog = await GetPopulatedAnalogMeasurement(modelEntity);

                if (!await Measurements.ContainsKeyAsync(newAnalog.Id))
                {
                    await Measurements.SetAsync(newAnalog.Id, newAnalog);                     //contains moze da bude false, a da kad doje ova linija na red, da vrednost bude popunjena, zato SetAsync, ali onda je sam if suvisan (ne znam da li je kljucan za neku logiku...)
                }
                var measurementProviderClient = MeasurementProviderClient.CreateClient();
                await measurementProviderClient.AddAnalogMeasurement(newAnalog as AnalogMeasurement);
            }
            else if (dmsType != DMSType.MASK_TYPE && dmsType != DMSType.BASEVOLTAGE)
            {
                ITopologyElement newElement = await GetPopulatedElement(modelEntity);

                //lock (syncObj)
                //{
                if (!await TopologyElements.ContainsKeyAsync(newElement.Id))
                {
                    await TopologyElements.SetAsync(newElement.Id, newElement);                     //contains moze da bude false, a da kad doje ova linija na red, da vrednost bude popunjena, zato SetAsync, ali onda je sam if suvisan (ne znam da li je kljucan za neku logiku...)
                }
                else
                {
                    Logger.LogDebug($"{baseLogString} TransformToTopologyElementAsync => TopologyElements contain key {newElement.Id:X16}");
                }
                //}

                if (dmsType == DMSType.ENERGYSOURCE)
                {
                    var energySourcesResult = await EnergySources.TryGetValueAsync(ReliableDictionaryNames.EnergySources);

                    if (energySourcesResult.HasValue)
                    {
                        var energySources = energySourcesResult.Value;
                        energySources.Add(newElement.Id);

                        await EnergySources.SetAsync(ReliableDictionaryNames.EnergySources, energySources);
                    }
                    else
                    {
                        Logger.LogWarning($"{baseLogString} Reliable collection '{ReliableDictionaryNames.EnergySources}' was not defined yet. Handling...");
                        await EnergySources.SetAsync(ReliableDictionaryNames.EnergySources, new List <long>() { newElement.Id });
                    }
                }

                //lock (syncObj)
                //{
                if (!await ElementConnections.ContainsKeyAsync(modelEntity.Id))
                {
                    await ElementConnections.SetAsync(modelEntity.Id, await GetAllReferencedElements(modelEntity));                     //contains moze da bude false, a da kad doje ova linija na red, da vrednost bude popunjena, zato SetAsync, ali onda je sam if suvisan (ne znam da li je kljucan za neku logiku...)
                }
                else
                {
                    Logger.LogDebug($"{baseLogString} TransformToTopologyElementAsync => ElementConnections contain key {modelEntity.Id:X16}");
                }
                //}
            }
        }
Пример #27
0
        private async Task <TopologyModel> CalculateLoadFlowFromRecloser(ITopologyElement recloser, TopologyModel topology, Dictionary <long, float> loadOfFeeders)
        {
            string verboseMessage = $"{baseLogString} CalculateLoadFlowFromRecloser method called. Element with GID {recloser?.Id:X16}.";

            Logger.LogVerbose(verboseMessage);

            if (recloser == null)
            {
                string message = $"{baseLogString} CalculateLoadFlowUpsideDown => NULL value has been passed instead of recloser.";
                Logger.LogError(message);
                throw new Exception(message);
            }

            if (topology == null)
            {
                string message = $"{baseLogString} CalculateLoadFlowUpsideDown => NULL value has been passed instead of topology.";
                Logger.LogError(message);
                throw new Exception(message);
            }

            long measurementGid = 0;

            if (recloser.Measurements.Count == 1)
            {
                //dogovor je da prekidaci imaju samo discrete measurement
                measurementGid = recloser.Measurements.First().Key;
            }
            else
            {
                Logger.LogWarning($"{baseLogString} CalculateLoadFlowUpsideDown => Recloser with GID {recloser.Id:X16} does not have proper measurements.");
            }


            bool isEnergized = false;

            if (recloser.FirstEnd != null && recloser.SecondEnd.Count == 1)
            {
                if (recloser.FirstEnd.IsActive && !recloser.SecondEnd.First().IsActive)
                {
                    Tuple <bool, float> tuple = await IsElementEnergized(recloser);

                    isEnergized = tuple.Item1;
                    float load = tuple.Item2;
                    if (isEnergized)
                    {
                        await CalculateLoadFlowUpsideDown(recloser.SecondEnd.First(), recloser.Id, recloser.FirstEnd.Feeder, loadOfFeeders);
                    }
                    else if (!recloser.IsActive)
                    {
                        Thread thread = new Thread(async() => await CommandToRecloser(measurementGid, (int)DiscreteCommandingType.CLOSE, CommandOriginType.CE_COMMAND, recloser));
                        thread.Start();
                    }
                }
                else if (!recloser.FirstEnd.IsActive && recloser.SecondEnd.First().IsActive)
                {
                    Tuple <bool, float> tuple = await IsElementEnergized(recloser);

                    isEnergized = tuple.Item1;
                    float load = tuple.Item2;

                    if (isEnergized)
                    {
                        await CalculateLoadFlowUpsideDown(recloser.FirstEnd, recloser.Id, recloser.SecondEnd.First().Feeder, loadOfFeeders);
                    }
                    else if (!recloser.IsActive)
                    {
                        Thread thread = new Thread(async() => await CommandToRecloser(measurementGid, (int)DiscreteCommandingType.CLOSE, CommandOriginType.CE_COMMAND, recloser));
                        thread.Start();
                    }
                }
                else if (recloser.IsActive)
                {
                    Logger.LogDebug($"{baseLogString} TurnOnAllMeasurement => Calling SendDiscreteCommand method from measurement provider. Measurement GID {measurementGid:X16}, Value 1.");
                    var measurementProviderClient = MeasurementProviderClient.CreateClient();
                    await measurementProviderClient.SendSingleDiscreteCommand(measurementGid, (int)DiscreteCommandingType.OPEN, CommandOriginType.CE_COMMAND);

                    Logger.LogDebug($"{baseLogString} TurnOnAllMeasurement => SendDiscreteCommand method from measurement provider successfully finished.");
                    recloser.IsActive = false;
                }
            }
            else
            {
                Logger.LogDebug($"{baseLogString} TurnOnAllMeasurement =>  Recloser with GID {recloser.Id:X16} does not have both ends, or have more than one on one end.");
            }
            return(topology);
        }
Пример #28
0
        private async Task CalculateLoadFlowUpsideDown(ITopologyElement element, long sourceElementGid, ITopologyElement feeder, Dictionary <long, float> loadOfFeeders)
        {
            string verboseMessage = $"{baseLogString} CalculateLoadFlowUpsideDown method called. Element with GID {element?.Id:X16}, Source GID {sourceElementGid}.";

            Logger.LogVerbose(verboseMessage);

            if (element == null)
            {
                string message = $"{baseLogString} CalculateLoadFlowUpsideDown => NULL value has been passed instead of element.";
                Logger.LogError(message);
                throw new Exception(message);
            }

            if (feeder == null)
            {
                string message = $"{baseLogString} CalculateLoadFlowUpsideDown => NULL value has been passed instead of feeder.";
                Logger.LogError(message);
                throw new Exception(message);
            }

            Stack <Tuple <ITopologyElement, long> > stack = new Stack <Tuple <ITopologyElement, long> >();

            stack.Push(new Tuple <ITopologyElement, long>(element, sourceElementGid));

            Tuple <ITopologyElement, long> tuple;
            ITopologyElement nextElement;
            long             sourceGid;

            while (stack.Count > 0)
            {
                tuple       = stack.Pop();
                nextElement = tuple.Item1;
                sourceGid   = tuple.Item2;

                Tuple <bool, float> resTuple = await IsElementEnergized(nextElement);

                bool  isEnergized = resTuple.Item1;
                float load        = resTuple.Item2;

                if (isEnergized)
                {
                    if (!nextElement.DmsType.Equals(DMSType.ENERGYCONSUMER.ToString()) &&
                        nextElement.FirstEnd.Id != sourceGid)
                    {
                        stack.Push(new Tuple <ITopologyElement, long>(nextElement.FirstEnd, nextElement.Id));
                    }

                    foreach (var child in nextElement.SecondEnd)
                    {
                        if (child.Id != sourceGid)
                        {
                            stack.Push(new Tuple <ITopologyElement, long>(child, nextElement.Id));
                        }
                    }

                    if (feeder != null)
                    {
                        if (loadOfFeeders.ContainsKey(feeder.Id))
                        {
                            loadOfFeeders[feeder.Id] += load;
                        }
                        else
                        {
                            loadOfFeeders.Add(feeder.Id, load);
                        }
                    }
                }
                else
                {
                    if (nextElement.DmsType.Equals(DMSType.FUSE.ToString()))
                    {
                        await DeEnergizeElementsUnder(nextElement);
                    }
                    else
                    {
                        foreach (var child in nextElement.SecondEnd)
                        {
                            if (child.Id != sourceGid)
                            {
                                stack.Push(new Tuple <ITopologyElement, long>(child, nextElement.Id));
                            }
                        }
                    }
                }
            }
        }
        public async Task <TopologyModel> CreateGraphTopology(long firstElementGid, string whoIsCalling)
        {
            Logger.LogVerbose($"{baseLogString} CreateGraphTopology method called, by {whoIsCalling}.");

            ITopologyElement currentFider = null;

            Logger.LogDebug($"{baseLogString} CreateGraphTopology => Calling GetElementModels method from model provider.");
            var modelProviderClient = CeModelProviderClient.CreateClient();
            var dict = await modelProviderClient.GetElementModels();

            elements = TransformDictionary(dict);
            Logger.LogDebug($"{baseLogString} CreateGraphTopology => GetElementModels method from model provider has been called successfully.");

            Logger.LogDebug($"{baseLogString} CreateGraphTopology => Calling GetConnections method from model provider.");
            modelProviderClient = CeModelProviderClient.CreateClient();
            connections         = await modelProviderClient.GetConnections();

            Logger.LogDebug($"{baseLogString} CreateGraphTopology => GetConnections method from model provider has been called successfully.");

            Logger.LogDebug($"{baseLogString} CreateGraphTopology => Calling GetReclosers method from model provider.");
            modelProviderClient = CeModelProviderClient.CreateClient();
            reclosers           = await modelProviderClient.GetReclosers();

            Logger.LogDebug($"{baseLogString} CreateGraphTopology => GetReclosers method from model provider has been called successfully.");

            Logger.LogDebug($"{baseLogString} CreateGraphTopology => Creating topology from first element with GID {firstElementGid:X16} started.");

            visited = new HashSet <long>();
            stack   = new Stack <long>();
            fields  = new List <Field>();

            TopologyModel topology = new TopologyModel
            {
                FirstNode = firstElementGid
            };

            try
            {
                stack.Push(firstElementGid);
                ITopologyElement currentElement;
                long             currentElementId = 0;

                while (stack.Count > 0)
                {
                    currentElementId = stack.Pop();
                    if (!visited.Contains(currentElementId))
                    {
                        visited.Add(currentElementId);
                    }

                    if (!elements.TryGetValue(currentElementId, out currentElement))
                    {
                        string message = $"{baseLogString} CreateGraphTopology => Failed to build topology.Topology does not contain element with GID {currentElementId:X16}.";
                        Logger.LogError(message);
                        return(topology);
                        //throw new Exception(message);
                    }

                    List <long> referencedElements = GetReferencedElementsWithoutIgnorables(currentElementId);

                    foreach (var element in referencedElements)
                    {
                        if (elements.TryGetValue(element, out ITopologyElement newNode))
                        {
                            if (!reclosers.Contains(element))
                            {
                                ConnectTwoNodes(newNode, currentElement);
                                stack.Push(element);
                            }
                            else
                            {
                                currentElement.SecondEnd.Add(newNode);
                                if (newNode.FirstEnd == null)
                                {
                                    newNode.FirstEnd = currentElement;
                                }
                                else
                                {
                                    newNode.SecondEnd.Add(currentElement);
                                }

                                if (!topology.TopologyElements.ContainsKey(newNode.Id))
                                {
                                    topology.AddElement(newNode);
                                }
                            }
                        }
                        else
                        {
                            Logger.LogError($"{baseLogString} CreateGraphTopology => Element with GID {element:X16} does not exist in collection of elements.");
                        }
                    }

                    if (currentElement is Feeder)
                    {
                        currentFider = currentElement;
                    }
                    else
                    {
                        currentElement.Feeder = currentFider;
                    }

                    topology.AddElement(currentElement);
                }

                foreach (var field in fields)
                {
                    topology.AddElement(field);
                }

                //long size = 0;
                //using (Stream stream = new MemoryStream())
                //{
                //    BinaryFormatter formatter = new BinaryFormatter();
                //    formatter.Serialize(stream, topology);
                //    size = stream.Length;
                //}

                //using (FileStream writer = new FileStream(@"E:\LogFiles\Topology.txt", FileMode.OpenOrCreate))
                //{
                //    DataContractSerializer serializer = new DataContractSerializer(topology.GetType());
                //    serializer.WriteObject(writer, topology);
                //}
            }
            catch (Exception e)
            {
                Logger.LogError($"{baseLogString} Uhvacen eksepsn. {e.Message} {e.StackTrace}");
            }

            Logger.LogDebug($"{baseLogString} CreateGraphTopology => Topology successfully created.");
            return(topology);
        }
Пример #30
0
        private bool IsElementEnergized(ITopologyElement element, out float load)
        {
            load = 0;
            bool pastState = element.IsActive;

            element.IsActive = true;

            foreach (var measurement in element.Measurements)
            {
                if ((DMSType)ModelCodeHelper.ExtractTypeFromGlobalId(measurement.Key) == DMSType.DISCRETE ||
                    measurement.Key < 10000)
                {
                    // Value je true ako je prekidac otvoren, tada je element neaktivan
                    element.IsActive = !Provider.Instance.MeasurementProvider.GetDiscreteValue(measurement.Key);
                    break;
                }
            }

            if (element.IsActive)
            {
                if (!pastState)
                {
                    TurnOnAllMeasurement(element.Measurements);
                }
                var analogMeasurements = GetMeasurements(element.Measurements);

                if (element.DmsType.Equals(DMSType.SYNCHRONOUSMACHINE.ToString()))
                {
                    if (!syncMachines.ContainsKey(element.Id))
                    {
                        syncMachines.Add(element.Id, element);
                    }
                }
                else
                {
                    if (element.IsRemote)
                    {
                        float power   = 0;
                        float voltage = 0;
                        foreach (var analogMeasurement in analogMeasurements)
                        {
                            if (analogMeasurement.GetMeasurementType().Equals(AnalogMeasurementType.POWER.ToString()))
                            {
                                power = analogMeasurement.GetCurrentValue();
                            }
                            else if (analogMeasurement.GetMeasurementType().Equals(AnalogMeasurementType.VOLTAGE.ToString()))
                            {
                                voltage = analogMeasurement.GetCurrentValue();
                            }
                        }

                        if (power != 0 && voltage != 0)
                        {
                            load = (float)Math.Round(power / voltage);
                        }
                    }
                    else if (element is EnergyConsumer consumer)
                    {
                        if (dailyCurves.TryGetValue(EnergyConsumerTypeToDailyCurveConverter.GetDailyCurveType(consumer.Type), out DailyCurve curve))
                        {
                            load = (float)Math.Round(curve.GetValue((short)DateTime.Now.Hour) * 1000 / 220);
                        }
                    }
                }
            }

            return(element.IsActive);
        }