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); } }