Exemple #1
0
        public void GenerateOutage(ActiveOutageBindingModel outage)
        {
            CancellationTokenSource tokenSource = new CancellationTokenSource();
            CancellationToken       token       = tokenSource.Token;

            Task task = Task.Run(() =>
            {
                token.ThrowIfCancellationRequested();

                ScadaNotification scadaCallback = new ScadaNotification("OUTAGE_SIMULATOR", outage);
                SubscriberProxy scadaSubscriber = proxyFactory.CreateProxy <SubscriberProxy, ISubscriber>(scadaCallback, EndpointNames.SubscriberEndpoint);

                if (scadaSubscriber == null)
                {
                    string message = "GenerateOutage task => SubscriberProxy is null";
                    Logger.LogError(message);
                    return;
                }

                scadaSubscriber.Subscribe(Topic.SWITCH_STATUS);

                bool toContinue = !token.IsCancellationRequested;
                while (toContinue)
                {
                    //TODO: OUTAGE LOGIC

                    if (token.IsCancellationRequested)
                    {
                        // Clean up here
                        scadaSubscriber.Close();
                        toContinue = false;
                        //token.ThrowIfCancellationRequested();
                    }
                }
            }, token);

            outageTokenMap.Add(outage.OutageElement.GID, tokenSource);

            ActiveOutages.Add(outage);
            activeOutagesMap.Add(outage.OutageElement.GID, outage);

            Dispatcher.BeginInvoke((Action)(() => parent.TabControl.SelectedIndex = 0));
        }
        public bool StartIsolationAlgorthm(OutageEntity outageToIsolate)
        {
            List <long> defaultIsolationPoints = outageToIsolate.DefaultIsolationPoints.Select(point => point.EquipmentId).ToList();

            bool isIsolated;
            bool isFirstBreakerRecloser;

            if (defaultIsolationPoints.Count > 0 && defaultIsolationPoints.Count < 3)
            {
                long headBreaker = -1;
                long recloser    = -1;
                try
                {
                    isFirstBreakerRecloser = CheckIfBreakerIsRecloser(defaultIsolationPoints[0]);
                    //TODO is second recloser (future)
                }
                catch (Exception e)
                {
                    Logger.LogWarn("Exception on method CheckIfBreakerIsRecloser()", e);
                    throw e;
                }

                GetHeadBreakerAndRecloser(defaultIsolationPoints, isFirstBreakerRecloser, ref headBreaker, ref recloser);


                if (headBreaker != -1)
                {
                    ModelCode mc = outageModel.modelResourcesDesc.GetModelCodeFromId(headBreaker);
                    if (mc == ModelCode.BREAKER)
                    {
                        long headBreakerMeasurementId, recloserMeasurementId;
                        using (MeasurementMapProxy measurementMapProxy = proxyFactory.CreateProxy <MeasurementMapProxy, IMeasurementMapContract>(EndpointNames.MeasurementMapEndpoint))
                        {
                            try
                            {
                                headBreakerMeasurementId = measurementMapProxy.GetMeasurementsOfElement(headBreaker)[0];
                                if (recloser != -1)
                                {
                                    recloserMeasurementId = measurementMapProxy.GetMeasurementsOfElement(recloser)[0];
                                }
                                else
                                {
                                    recloserMeasurementId = -1;
                                }
                            }
                            catch (Exception e)
                            {
                                Logger.LogError("Error on GetMeasurementsForElement() method.", e);
                                throw e;
                            }
                        }

                        Logger.LogInfo($"Head breaker id: 0x{headBreaker:X16}, recloser id: 0x{recloser:X16} (-1 if no recloser).");

                        //ALGORITHM
                        AutoResetEvent    autoResetEvent    = new AutoResetEvent(false);
                        CancelationObject cancelationObject = new CancelationObject()
                        {
                            CancelationSignal = false
                        };
                        Timer             timer             = InitalizeAlgorthmTimer(cancelationObject, autoResetEvent);
                        ScadaNotification scadaNotification = new ScadaNotification("OutageModel_SCADA_Subscriber", new OutageIsolationAlgorithm.OutageIsolationAlgorithmParameters(headBreakerMeasurementId, recloserMeasurementId, autoResetEvent));
                        SubscriberProxy   subscriberProxy   = proxyFactory.CreateProxy <SubscriberProxy, ISubscriber>(scadaNotification, EndpointNames.SubscriberEndpoint);
                        subscriberProxy.Subscribe(Topic.SWITCH_STATUS);

                        long currentBreakerId = headBreaker;

                        while (!cancelationObject.CancelationSignal)
                        {
                            if (outageModel.TopologyModel.OutageTopology.ContainsKey(currentBreakerId))
                            {
                                currentBreakerId = outageModel.GetNextBreaker(currentBreakerId);
                                Logger.LogDebug($"Next breaker is 0x{currentBreakerId:X16}.");

                                if (currentBreakerId == -1 || currentBreakerId == recloser)
                                {
                                    //TODO: planned outage
                                    string message = "End of the feeder, no outage detected.";
                                    Logger.LogWarn(message);
                                    isIsolated = false;
                                    subscriberProxy.Close();
                                    outageModel.commandedElements.Clear();
                                    throw new Exception(message);
                                }
                                //TODO: SCADACommand
                                SendSCADACommand(currentBreakerId, DiscreteCommandingType.OPEN);
                                SendSCADACommand(headBreaker, DiscreteCommandingType.CLOSE);

                                timer.Start();
                                Logger.LogDebug("Timer started.");
                                autoResetEvent.WaitOne();
                                if (timer.Enabled)
                                {
                                    timer.Stop();
                                    Logger.LogDebug("Timer stoped");
                                    SendSCADACommand(currentBreakerId, DiscreteCommandingType.CLOSE);
                                }
                            }
                        }

                        long nextBreakerId = outageModel.GetNextBreaker(currentBreakerId);
                        if (currentBreakerId != 0 && currentBreakerId != recloser)
                        {
                            outageToIsolate.OptimumIsolationPoints = outageModel.GetEquipmentEntity(new List <long> {
                                currentBreakerId, nextBreakerId
                            });


                            if (!outageModel.TopologyModel.OutageTopology.ContainsKey(nextBreakerId))
                            {
                                string message = $"Breaker (next breaker) with id: 0x{nextBreakerId:X16} is not in topology";
                                Logger.LogError(message);
                                throw new Exception(message);
                            }

                            long outageElement = outageModel.TopologyModel.OutageTopology[nextBreakerId].FirstEnd;

                            if (!outageModel.TopologyModel.OutageTopology[currentBreakerId].SecondEnd.Contains(outageElement))
                            {
                                string message = $"Outage element with gid: 0x{outageElement:X16} is not on a second end of current breaker id";
                                Logger.LogError(message);
                                throw new Exception(message);
                            }

                            //TODO: SCADA Command
                            subscriberProxy.Close();
                            outageModel.optimumIsolationPoints.Add(currentBreakerId);
                            outageModel.optimumIsolationPoints.Add(nextBreakerId);
                            SendSCADACommand(currentBreakerId, DiscreteCommandingType.OPEN);
                            SendSCADACommand(nextBreakerId, DiscreteCommandingType.OPEN);

                            outageToIsolate.IsolatedTime     = DateTime.UtcNow;
                            outageToIsolate.OutageElementGid = outageElement;
                            outageToIsolate.OutageState      = OutageState.ISOLATED;

                            Logger.LogInfo($"Isolation of outage with id {outageToIsolate.OutageId}. Optimum isolation points: 0x{currentBreakerId:X16} and 0x{nextBreakerId:X16}, and outage element id is 0x{outageElement:X16}");
                            isIsolated = true;
                        }
                        else
                        {
                            string message = "End of the feeder, no outage detected.";
                            Logger.LogWarn(message);
                            isIsolated = false;
                            subscriberProxy.Close();
                            outageModel.commandedElements.Clear();
                            throw new Exception(message);
                        }
                    }
                    else
                    {
                        Logger.LogWarn($"Head breaker type is {mc}, not a {ModelCode.BREAKER}.");
                        isIsolated = false;
                    }
                }
                else
                {
                    Logger.LogWarn("Head breaker not found.");
                    isIsolated = false;
                }
            }
            else
            {
                Logger.LogWarn($"Number of defaultIsolationPoints ({defaultIsolationPoints.Count}) is out of range [1, 2].");
                isIsolated = false;
            }


            outageModel.commandedElements.Clear();
            return(isIsolated);
        }