Ejemplo n.º 1
0
        public async Task Start(List <long> calls)
        {
            Logger.LogDebug("Starting tracking algorithm.");

            //on every start tracking algorithm get up to date outage topology model
            var topologyProviderClient = TopologyProviderClient.CreateClient();

            outageTopologyModel = await topologyProviderClient.GetOMSModel();

            this.potentialOutages = LocateSwitchesUsingCalls(calls);
            this.outages          = new List <long>();
            HashSet <long> visited = new HashSet <long>();
            bool           foundOutage = false;
            long           currentGid, previousGid;

            currentGid = this.potentialOutages[0];

            try
            {
                while (this.potentialOutages.Count > 0)
                {
                    currentGid  = this.potentialOutages[0];
                    previousGid = currentGid;
                    this.outages.Add(currentGid);
                    outageTopologyModel.GetElementByGid(currentGid, out OutageTopologyElement topologyElement);
                    this.potentialOutages.Remove(currentGid);
                    while (topologyElement.DmsType != "ENERGYSOURCE" && !topologyElement.IsRemote && this.potentialOutages.Count > 0)
                    {
                        foundOutage = false;
                        if (TraceDFS(visited, topologyElement, foundOutage))
                        {
                            this.outages.Remove(previousGid);
                            this.outages.Add(currentGid);
                            previousGid = currentGid;
                        }
                        topologyElement = GetSwitch(topologyElement.FirstEnd);
                        if (topologyElement == null)
                        {
                            break;
                        }
                        currentGid = topologyElement.Id;
                    }
                }
            }
            catch (Exception ex)
            {
                string message = $"Tracing algorithm failed with error: {ex.Message}";
                Logger.LogError(message);
                Console.WriteLine(message);
            }

            var reportOutageClient = PotentialOutageReportingClient.CreateClient();

            foreach (var potentialOutageElementGid in this.outages)
            {
                var ceModelProviderClient = CeModelProviderClient.CreateClient();
                if (!await ceModelProviderClient.IsRecloser(potentialOutageElementGid))
                {
                    //TODO: razdvojiti metode scada, noScada
                    await reportOutageClient.ReportPotentialOutage(potentialOutageElementGid, CommandOriginType.NON_SCADA_OUTAGE, NetworkType.NON_SCADA_NETWORK);
                }
                else
                {
                    Logger.LogDebug($"{baseLogString} Start => Element with gid 0x{potentialOutageElementGid:X16} is a Recloser. ReportPotentialOutage call is not required.");
                }
            }
        }
        public async Task Notify(IPublishableMessage message, string publisherName)
        {
            Logger.LogDebug($"{baseLogString} Notify method started.");

            while (!ReliableDictionariesInitialized)
            {
                await Task.Delay(1000);
            }

            try
            {
                if (message is MultipleDiscreteValueSCADAMessage multipleDiscreteValueSCADAMessage)
                {
                    Logger.LogDebug($"{baseLogString} MultipleDiscreteValueSCADAMessage received.");
                    var discreteData = multipleDiscreteValueSCADAMessage.Data;

                    #region HeadBreakers
                    var enumerableHeadBreakerMeasurements = await MonitoredHeadBreakerMeasurements.GetEnumerableDictionaryAsync();

                    foreach (var headMeasurementGid in enumerableHeadBreakerMeasurements.Keys)
                    {
                        if (!discreteData.ContainsKey(headMeasurementGid))
                        {
                            continue;
                        }

                        await MonitoredHeadBreakerMeasurements.SetAsync(headMeasurementGid, discreteData[headMeasurementGid]);
                    }
                    #endregion HeadBreakers

                    #region CommandedElements
                    var measurementProviderClient   = MeasurementProviderClient.CreateClient();
                    var enumerableCommandedElements = await CommandedElements.GetEnumerableDictionaryAsync();

                    foreach (var commandedElementGid in enumerableCommandedElements.Keys)
                    {
                        var measurementGid = (await measurementProviderClient.GetMeasurementsOfElement(commandedElementGid)).FirstOrDefault();
                        var measurement    = await measurementProviderClient.GetDiscreteMeasurement(measurementGid);

                        if (measurement is ArtificalDiscreteMeasurement)
                        {
                            await CommandedElements.TryRemoveAsync(commandedElementGid);

                            Logger.LogInformation($"{baseLogString} Notify => Command on element 0x{commandedElementGid:X16} executed (ArtificalDiscreteMeasurement). New value: {measurement.CurrentOpen}");
                            continue;
                        }

                        if (!discreteData.ContainsKey(measurementGid))
                        {
                            continue;
                        }

                        if (discreteData[measurementGid].Value == (ushort)enumerableCommandedElements[commandedElementGid].CommandingType)
                        {
                            if ((await CommandedElements.TryRemoveAsync(commandedElementGid)).HasValue)
                            {
                                Logger.LogInformation($"{baseLogString} Notify => Command on element 0x{commandedElementGid:X16} executed. New value: {discreteData[measurementGid].Value}");
                            }
                        }
                    }
                    #endregion CommandedElements
                }
                else if (message is OMSModelMessage omsModelMessage)
                {
                    Logger.LogDebug($"{baseLogString} OMSModelMessage received. Count {omsModelMessage.OutageTopologyModel.OutageTopology.Count}");

                    OutageTopologyModel topology = omsModelMessage.OutageTopologyModel;
                    await OutageTopologyModel.SetAsync(ReliableDictionaryNames.OutageTopologyModel, topology);

                    var reportingOutageClient = PotentialOutageReportingClient.CreateClient();

                    while (true)
                    {
                        var result = await PotentialOutagesQueue.TryDequeueAsync();

                        if (!result.HasValue)
                        {
                            break;
                        }

                        var command = result.Value;

                        await reportingOutageClient.ReportPotentialOutage(command.ElementGid, command.CommandOriginType, command.NetworkType);

                        Logger.LogInformation($"{baseLogString} PotentianOutageCommand executed. ElementGid: 0x{command.ElementGid:X16}, OriginType: {command.CommandOriginType}");
                    }
                }
                else
                {
                    Logger.LogWarning($"{baseLogString} Notify => unexpected type of message: {message.GetType()}");
                    return;
                }
            }
            catch (Exception e)
            {
                string errorMessage = $"{baseLogString} Notify => Exception: {e.Message}";
                Logger.LogError(errorMessage, e);
            }
        }