private async Task <bool> StartIsolationAlgorthm(OutageEntity outageToIsolate) { var result = await CreateIsolatingAlgorithm(outageToIsolate); if (!result.HasValue) { Logger.LogError($"{baseLogString} StartIsolationAlgorthm => CreateIsolatingAlgorithm did not return a vaule."); return(false); } var algorithm = result.Value; Logger.LogInformation($"{baseLogString} StartIsolationAlgorthm => HeadBreakerGid: 0x{algorithm.HeadBreakerGid:X16}, RecloserGd: 0x{algorithm.RecloserGid:X16} (Recloser gid is -1 if there is no recloser...)."); var scadaClient = ScadaIntegrityUpdateClient.CreateClient(); var scadaPublication = await scadaClient.GetIntegrityUpdateForSpecificTopic(Topic.SWITCH_STATUS); if (!(scadaPublication.Message is MultipleDiscreteValueSCADAMessage multipleDiscreteValueSCADAMessage)) { Logger.LogError($"{baseLogString} StartIsolationAlgorthm => ScadaPublication message is not of expected type: {typeof(MultipleDiscreteValueSCADAMessage)}, but of type: {scadaPublication.Message.GetType()}"); return(false); } if (!multipleDiscreteValueSCADAMessage.Data.ContainsKey(algorithm.HeadBreakerMeasurementGid)) { Logger.LogError($"{baseLogString} StartIsolationAlgorthm => HeadBreakerMeasurement with gid: 0x{algorithm.HeadBreakerMeasurementGid:X16} not found in integrity update data received from scada."); return(false); } var discreteModbusData = multipleDiscreteValueSCADAMessage.Data[algorithm.HeadBreakerMeasurementGid]; await MonitoredHeadBreakerMeasurements.SetAsync(algorithm.HeadBreakerMeasurementGid, discreteModbusData); await StartedIsolationAlgorithms.SetAsync(algorithm.HeadBreakerGid, algorithm); return(true); }
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); } }