public async Task <bool> Prepare() { logger.LogDebug($"{baseLogString} Prepare entered."); bool success; //while (!isModelChangesInitialized) //{ // await Task.Delay(1000); //} try { var modelProviderClient = CeModelProviderClient.CreateClient(); success = await modelProviderClient.Prepare(); } catch (Exception ex) { Logger.LogError($"{baseLogString} Prepare => Exception: {ex.Message}", ex); success = false; } if (success) { Logger.LogInformation($"{baseLogString} Prepare => Preparation on CE Transaction actor SUCCESSFULLY finished."); } else { Logger.LogInformation($"{baseLogString} Prepare => Preparation on CE Transaction actor UNSUCCESSFULLY finished."); } return(success); }
public async Task Rollback() { logger.LogDebug($"{baseLogString} Rollback entered."); try { var modelProviderClient = CeModelProviderClient.CreateClient(); await modelProviderClient.Rollback(); Logger.LogInformation($"{baseLogString} Rollback => Rollback on CE Transaction actor SUCCESSFULLY finished."); } catch (Exception ex) { Logger.LogError($"{baseLogString} Rollback => Exception: {ex.Message}", ex); Logger.LogInformation($"{baseLogString} Rollback => Rollback on CE Transaction actor UNSUCCESSFULLY finished."); } }
public async Task Commit() { logger.LogDebug($"{baseLogString} Commit entered."); try { var modelProviderClient = CeModelProviderClient.CreateClient(); await modelProviderClient.Commit(); Logger.LogInformation($"{baseLogString} Commit => Commit on CE Transaction actor SUCCESSFULLY finished."); } catch (Exception ex) { Logger.LogError($"{baseLogString} Commit => " + $"{Environment.NewLine} Exception: {ex.Message} " + $"{Environment.NewLine} Stack trace: {ex.StackTrace}", ex); Logger.LogInformation($"{baseLogString} Commit => Commit on CE Transaction actor UNSUCCESSFULLY finished."); } }
public async Task Rollback() { logger.LogDebug($"{baseLogString} Rollback entered."); //while (!isModelChangesInitialized) //{ // await Task.Delay(1000); //} try { var modelProviderClient = CeModelProviderClient.CreateClient(); await modelProviderClient.Rollback(); Logger.LogInformation($"{baseLogString} Rollback => Rollback on CE Transaction actor SUCCESSFULLY finished."); } catch (Exception ex) { Logger.LogError($"{baseLogString} Rollback => Exception: {ex.Message}", ex); Logger.LogInformation($"{baseLogString} Rollback => Rollback on CE Transaction actor UNSUCCESSFULLY finished."); } }
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); }
public async Task <bool> ReportPotentialOutage(long elementGid, CommandOriginType commandOriginType, NetworkType networkType) { Logger.LogVerbose($"{baseLogString} ReportPotentialOutage method started. ElementGid: 0x{elementGid:X16}, CommandOriginType: {commandOriginType}, NetworkType: {networkType}"); while (!ReliableDictionariesInitialized) { await Task.Delay(1000); } try { #region Preconditions var ceModelProviderClient = CeModelProviderClient.CreateClient(); if (await ceModelProviderClient.IsRecloser(elementGid)) { Logger.LogWarning($"{baseLogString} ReportPotentialOutage => Element with gid 0x{elementGid:X16} is a Recloser. Call to ReportPotentialOutage aborted."); return(false); } var enumerableTopology = await OutageTopologyModel.GetEnumerableDictionaryAsync(); if (!enumerableTopology.ContainsKey(ReliableDictionaryNames.OutageTopologyModel)) { Logger.LogError($"{baseLogString} ReportPotentialOutage => Topology not found in Rel Dictionary: {ReliableDictionaryNames.OutageTopologyModel}."); return(false); } var topology = enumerableTopology[ReliableDictionaryNames.OutageTopologyModel]; var affectedConsumersGids = lifecycleHelper.GetAffectedConsumers(elementGid, topology, networkType); var historyDBManagerClient = HistoryDBManagerClient.CreateClient(); if (!(await CheckPreconditions(elementGid, commandOriginType, affectedConsumersGids, historyDBManagerClient))) { Logger.LogWarning($"{baseLogString} ReportPotentialOutage => Parameters do not satisfy required preconditions. ElementId: 0x{elementGid:X16}, CommandOriginType: {commandOriginType}"); return(false); } #endregion Preconditions Logger.LogInformation($"{baseLogString} ReportPotentialOutage => Reporting outage for gid: 0x{elementGid:X16}, CommandOriginType: {commandOriginType}"); var result = await StoreActiveOutage(elementGid, affectedConsumersGids, topology); if (!result.HasValue) { Logger.LogError($"{baseLogString} ReportPotentialOutage => Storing outage on element 0x{elementGid:X16} FAILED."); return(false); } var createdOutage = result.Value; Logger.LogInformation($"{baseLogString} ReportPotentialOutage => Outage on element with gid: 0x{createdOutage.OutageElementGid:x16} is successfully stored in database."); //await historyDBManagerClient.OnSwitchOpened(elementGid, createdOutage.OutageId); //await historyDBManagerClient.OnConsumerBlackedOut(affectedConsumersGids, createdOutage.OutageId); return(await lifecycleHelper.PublishOutageAsync(Topic.ACTIVE_OUTAGE, outageMessageMapper.MapOutageEntity(createdOutage))); } catch (Exception e) { string message = $"{baseLogString} ReportPotentialOutage => exception: {e.Message}"; Logger.LogError(message, e); return(false); } }
public async Task <UIModel> ConvertTopologyToUIModel(TopologyModel topology) { string verboseMessage = $"{baseLogString} ConvertTopologyToUIModel method called."; Logger.LogVerbose(verboseMessage); if (topology == null) { string message = $"{baseLogString} ConvertTopologyToUIModel => Provider topology is null."; Logger.LogError(message); throw new Exception(message); } UIModel uIModel = new UIModel(); Stack <long> stack = new Stack <long>(); Logger.LogDebug($"{baseLogString} ConvertTopologyToUIModel => Calling GetReclosers method from model provider client."); var modelProviderClient = CeModelProviderClient.CreateClient(); var reclosers = await modelProviderClient.GetReclosers(); Logger.LogDebug($"{baseLogString} ConvertTopologyToUIModel => GetReclosers method from model provider client has been called successfully."); uIModel.FirstNode = topology.FirstNode; stack.Push(topology.FirstNode); long nextElementGid; while (stack.Count > 0) { nextElementGid = stack.Pop(); if (topology.GetElementByGid(nextElementGid, out ITopologyElement element)) { if (!reclosers.Contains(nextElementGid)) { foreach (var child in element.SecondEnd) { long nextElement = child.Id; if (ModelCodeHelper.ExtractTypeFromGlobalId(child.Id) == 0) { if (child is Field field && field.Members.Count > 0) { nextElement = field.Members.First().Id; } else { string message = $"{baseLogString} ConvertTopologyToUIModel => Error while getting field in Topology to UIModel convert. Element is not field or field is empty."; Logger.LogError(message); throw new Exception(message); } } uIModel.AddRelation(element.Id, nextElement); stack.Push(nextElement); } } List <UIMeasurement> measurements = new List <UIMeasurement>(); foreach (var measurementGid in element.Measurements.Keys) { DMSType type = (DMSType)ModelCodeHelper.ExtractTypeFromGlobalId(measurementGid); if (type == DMSType.ANALOG) { Logger.LogDebug($"{baseLogString} ConvertTopologyToUIModel => Calling GetAnalogMeasurement method from measurement provider client for measurement GID {measurementGid:X16}."); var measurementProviderClient = MeasurementProviderClient.CreateClient(); AnalogMeasurement analogMeasurement = await measurementProviderClient.GetAnalogMeasurement(measurementGid); Logger.LogDebug($"{baseLogString} ConvertTopologyToUIModel => GetAnalogMeasurement method from measurement provider client has been called successfully."); measurements.Add(new UIMeasurement() { Gid = analogMeasurement.Id, Type = analogMeasurement.GetMeasurementType(), Value = analogMeasurement.GetCurrentValue() }); } else if (type == DMSType.DISCRETE) { Logger.LogDebug($"{baseLogString} ConvertTopologyToUIModel => Calling GetDiscreteMeasurement method from measurement provider client for measurement GID {measurementGid:X16}."); var measurementProviderClient = MeasurementProviderClient.CreateClient(); DiscreteMeasurement discreteMeasurement = await measurementProviderClient.GetDiscreteMeasurement(measurementGid); Logger.LogDebug($"{baseLogString} ConvertTopologyToUIModel => GetDiscreteMeasurement method from measurement provider client has been called successfully."); measurements.Add(new UIMeasurement() { Gid = discreteMeasurement.Id, Type = discreteMeasurement.GetMeasurementType(), Value = discreteMeasurement.GetCurrentValue() }); } } if (!uIModel.Nodes.ContainsKey(element.Id)) { UINode newUINode = new UINode() { Id = element.Id, Name = element.Name, Mrid = element.Mrid, Description = element.Description, DMSType = element.DmsType, NominalVoltage = element.NominalVoltage, Measurements = measurements, IsActive = element.IsActive, IsRemote = element.IsRemote, NoReclosing = element.NoReclosing }; uIModel.AddNode(newUINode); } }
public async Task <TopologyModel> UpdateLoadFlow(TopologyModel inputTopology) { string verboseMessage = $"{baseLogString} UpdateLoadFlow method called."; Logger.LogVerbose(verboseMessage); TopologyModel topology = inputTopology; try { Dictionary <long, float> loadOfFeeders = new Dictionary <long, float>(); feeders = new Dictionary <long, ITopologyElement>(); syncMachines = new Dictionary <long, ITopologyElement>(); dailyCurves = DailyCurveReader.ReadDailyCurves(); Logger.LogDebug($"{baseLogString} UpdateLoadFlow => Getting reclosers from model provider."); var modelProviderClient = CeModelProviderClient.CreateClient(); reclosers = await modelProviderClient.GetReclosers(); Logger.LogDebug($"{baseLogString} UpdateLoadFlow => Reclosers were delivered successfully."); if (topology == null) { string message = $"{baseLogString} UpdateLoadFlow => Topology is null."; Logger.LogWarning(message); //throw new Exception(message); return(topology); } await CalculateLoadFlow(topology, loadOfFeeders); await UpdateLoadFlowFromRecloser(topology, loadOfFeeders); foreach (var syncMachine in syncMachines.Values) { await SyncMachine(syncMachine, loadOfFeeders); } var commands = new Dictionary <long, float>(); var modbusData = new Dictionary <long, AnalogModbusData>(); foreach (var loadFeeder in loadOfFeeders) { if (feeders.TryGetValue(loadFeeder.Key, out ITopologyElement feeder)) { long signalGid = 0; foreach (var measurement in feeder.Measurements) { if (measurement.Value.Equals(AnalogMeasurementType.FEEDER_CURRENT.ToString())) { signalGid = measurement.Key; } } if (signalGid != 0) { Logger.LogDebug($"{baseLogString} UpdateLoadFlow => Calling SendAnalogCommand method from measurement provider. Measurement GID {signalGid:X16}, Value {loadFeeder.Value}."); commands.Add(signalGid, loadFeeder.Value); AlarmType alarmType = (loadFeeder.Value >= 36) ? AlarmType.HIGH_ALARM : AlarmType.NO_ALARM; modbusData.Add(signalGid, new AnalogModbusData(loadFeeder.Value, alarmType, signalGid, CommandOriginType.CE_COMMAND)); } else { Logger.LogWarning($"{baseLogString} UpdateLoadFlow => Feeder with GID 0x{feeder.Id:X16} does not have FEEDER_CURRENT measurement."); } } } var measurementProviderClient = MeasurementProviderClient.CreateClient(); await measurementProviderClient.SendMultipleAnalogCommand(commands, CommandOriginType.CE_COMMAND); Logger.LogDebug($"{baseLogString} UpdateLoadFlow => SendAnalogCommand method from measurement provider successfully finished."); Logger.LogDebug($"{baseLogString} UpdateLoadFlow => Calling update analog measurement method from measurement provider."); await measurementProviderClient.UpdateAnalogMeasurement(modbusData); Logger.LogDebug($"{baseLogString} UpdateLoadFlow => Update analog measurement method from measurement provider successfully finished."); } catch (Exception e) { string errorMessage = $"{baseLogString} UpdateLoadFlow => Exception: {e.Message}"; Logger.LogError(errorMessage, e); } return(topology); }
private async Task <ConditionalValue <IsolationAlgorithm> > CreateIsolatingAlgorithm(OutageEntity outageToIsolate) { List <long> defaultIsolationPoints = outageToIsolate.DefaultIsolationPoints.Select(point => point.EquipmentId).ToList(); if (defaultIsolationPoints.Count != 1 && defaultIsolationPoints.Count != 2) { Logger.LogWarning($"{baseLogString} CreateIsolatingAlgorithm => Number of defaultIsolationPoints ({defaultIsolationPoints.Count}) is out of range [1, 2]."); return(new ConditionalValue <IsolationAlgorithm>(false, null)); } var measurementMapClient = MeasurementMapClient.CreateClient(); var ceModelProvider = CeModelProviderClient.CreateClient(); bool isFirstBreakerRecloser = await ceModelProvider.IsRecloser(defaultIsolationPoints[0]); #region HeadBreaker long headBreakerGid = await GetHeadBreakerAsync(defaultIsolationPoints, isFirstBreakerRecloser); if (headBreakerGid <= 0) { Logger.LogWarning($"{baseLogString} CreateIsolatingAlgorithm => Head breaker not found."); return(new ConditionalValue <IsolationAlgorithm>(false, null)); } ModelCode headBreakerModelCode = modelResourcesDesc.GetModelCodeFromId(headBreakerGid); if (headBreakerModelCode != ModelCode.BREAKER) { Logger.LogError($"{baseLogString} CreateIsolatingAlgorithm => Head breaker type is {headBreakerModelCode}, not a {ModelCode.BREAKER}."); return(new ConditionalValue <IsolationAlgorithm>(false, null)); } var headBreakerMeasurementGid = (await measurementMapClient.GetMeasurementsOfElement(headBreakerGid)).FirstOrDefault(); if (headBreakerMeasurementGid <= 0) { Logger.LogWarning($"{baseLogString} CreateIsolatingAlgorithm => Head breaker measurement not found."); return(new ConditionalValue <IsolationAlgorithm>(false, null)); } #endregion HeadBreaker #region Recloser long recloserGid = await GetRecloserAsync(defaultIsolationPoints, isFirstBreakerRecloser); long recloserMeasurementGid = -1; if (recloserGid > 0) //ne mora postojati recloser { ModelCode recloserModelCode = modelResourcesDesc.GetModelCodeFromId(recloserGid); if (recloserModelCode != ModelCode.BREAKER) { Logger.LogError($"{baseLogString} CreateIsolatingAlgorithm => Recloser type is {headBreakerModelCode}, not a {ModelCode.BREAKER}."); return(new ConditionalValue <IsolationAlgorithm>(false, null)); } var ceModelProviderClient = CeModelProviderClient.CreateClient(); if (!await ceModelProviderClient.IsRecloser(recloserGid)) { Logger.LogError($"{baseLogString} CreateIsolatingAlgorithm => Breaker with gid 0x{recloserGid:X16} is not a Recloser."); return(new ConditionalValue <IsolationAlgorithm>(false, null)); } recloserMeasurementGid = (await measurementMapClient.GetMeasurementsOfElement(headBreakerGid)).FirstOrDefault(); if (recloserMeasurementGid <= 0) { Logger.LogWarning($"{baseLogString} CreateIsolatingAlgorithm => Head breaker measurement not found."); return(new ConditionalValue <IsolationAlgorithm>(false, null)); } } #endregion Recloser var algorithm = new IsolationAlgorithm() { OutageId = outageToIsolate.OutageId, HeadBreakerGid = headBreakerGid, HeadBreakerMeasurementGid = headBreakerMeasurementGid, CurrentBreakerGid = headBreakerGid, CurrentBreakerMeasurementGid = headBreakerMeasurementGid, RecloserGid = recloserGid, RecloserMeasurementGid = recloserMeasurementGid, CycleCounter = 0, }; return(new ConditionalValue <IsolationAlgorithm>(true, algorithm)); }
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."); } } }