public async Task <bool> SendRepairCrew(long outageId) { Logger.LogDebug($"{baseLogString} SendRepairCrew method started. OutageId {outageId}"); while (!ReliableDictionariesInitialized) { await Task.Delay(1000); } try { var result = await lifecycleHelper.GetIsolatedOutage(outageId); if (!result.HasValue) { Logger.LogError($"{baseLogString} SendRepairCrew => Isolated Outage is null. OutageId {outageId}"); return(false); } var outageEntity = result.Value; Logger.LogInformation($"{baseLogString} SendRepairCrew => Entering 10 sec delay."); await Task.Delay(10_000); Logger.LogInformation($"{baseLogString} SendRepairCrew => 10 sec delay ended."); var outageSimulatorClient = OutageSimulatorClient.CreateClient(); if (!await outageSimulatorClient.StopOutageSimulation(outageEntity.OutageElementGid)) { string message = $"{baseLogString} SendRepairCrew => StopOutageSimulation for element 0x{outageEntity.OutageElementGid:X16} failed. OutageId {outageId}"; Logger.LogError(message); return(false); } outageEntity.OutageState = OutageState.REPAIRED; outageEntity.RepairedTime = DateTime.UtcNow; var outageModelAccessClient = OutageModelAccessClient.CreateClient(); await outageModelAccessClient.UpdateOutage(outageEntity); return(await lifecycleHelper.PublishOutageAsync(Topic.ACTIVE_OUTAGE, this.outageMessageMapper.MapOutageEntity(outageEntity))); } catch (Exception e) { string message = $"{baseLogString} SendRepairCrew => Exception: {e.Message}"; Logger.LogError(message, e); return(false); } }
private async Task <bool> StartLocationAndIsolationAlgorithm(OutageEntity outageEntity, OutageTopologyModel topology) { long reportedGid = outageEntity.DefaultIsolationPoints.First().EquipmentId; if (!topology.GetElementByGid(reportedGid, out OutageTopologyElement topologyElement)) { Logger.LogError($"{baseLogString} StartLocationAndIsolationAlgorithm => element with gid 0x{reportedGid:X16} not found in outage topology model."); return(false); } long upBreaker; long outageElementGid = -1; Logger.LogInformation($"{baseLogString} StartLocationAndIsolationAlgorithm => Entering 10 sec delay."); await Task.Delay(10_000); Logger.LogInformation($"{baseLogString} StartLocationAndIsolationAlgorithm => 10 sec delay ended."); var outageSimulatorClient = OutageSimulatorClient.CreateClient(); var outageModelAccessClient = OutageModelAccessClient.CreateClient(); //Da li je prijaveljen element OutageElement if (await outageSimulatorClient.IsOutageElement(reportedGid)) { outageElementGid = reportedGid; } //Da li je mozda na ACL-novima ispod prijavljenog elementa else { for (int i = 0; i < topologyElement.SecondEnd.Count; i++) { var potentialOutageElementGid = topologyElement.SecondEnd[i]; if (!(await outageSimulatorClient.IsOutageElement(potentialOutageElementGid))) { continue; } if (outageElementGid == -1) { outageElementGid = potentialOutageElementGid; outageEntity.OutageElementGid = outageElementGid; //outageEntity.AffectedConsumers = await lifecycleHelper.GetAffectedConsumersFromDatabase(lifecycleHelper.GetAffectedConsumers(outageElementGid, topology, NetworkType.NON_SCADA_NETWORK)); } else { //KAKO SE ULAZI U OVAJ ELSE? => u else se ulazi tako sto se ide kroz for i prvi element se oznaci kao outage element, zatim se pronaje jos neki... znaci ovo je nacin da se kreira drugi, treci outage, na racvanju ispod elementa, po for-u.... var entity = new OutageEntity() { OutageElementGid = potentialOutageElementGid, ReportTime = DateTime.UtcNow }; await outageModelAccessClient.AddOutage(entity); } } } //Tragamo za ACL-om gore ka source-u while (outageElementGid == -1 && !topologyElement.IsRemote && topologyElement.DmsType != "ENERGYSOURCE") { if (await outageSimulatorClient.IsOutageElement(topologyElement.Id)) { outageElementGid = topologyElement.Id; outageEntity.OutageElementGid = outageElementGid; } topology.GetElementByGid(topologyElement.FirstEnd, out topologyElement); } if (outageElementGid == -1) { outageEntity.OutageState = OutageState.REMOVED; await outageModelAccessClient.RemoveOutage(outageEntity); Logger.LogError($"{baseLogString} StartLocationAndIsolationAlgorithm => End of feeder no outage detected."); return(false); } topology.GetElementByGidFirstEnd(outageEntity.OutageElementGid, out topologyElement); while (topologyElement.DmsType != "BREAKER") { topology.GetElementByGidFirstEnd(topologyElement.Id, out topologyElement); } upBreaker = topologyElement.Id; long nextBreaker = lifecycleHelper.GetNextBreaker(outageEntity.OutageElementGid, topology); if (!topology.OutageTopology.ContainsKey(nextBreaker)) { string message = $"{baseLogString} StartLocationAndIsolationAlgorithm => Breaker (next breaker) with id: 0x{nextBreaker:X16} is not in topology"; Logger.LogError(message); throw new Exception(message); } long outageElement = topology.OutageTopology[nextBreaker].FirstEnd; if (!topology.OutageTopology[upBreaker].SecondEnd.Contains(outageElement)) { string message = $"{baseLogString} StartLocationAndIsolationAlgorithm => Outage element with gid: 0x{outageElement:X16} is not on a second end of current breaker id"; Logger.LogError(message); throw new Exception(message); } outageEntity.OptimumIsolationPoints = await lifecycleHelper.GetEquipmentEntityAsync(new List <long>() { upBreaker, nextBreaker }); outageEntity.IsolatedTime = DateTime.UtcNow; outageEntity.OutageState = OutageState.ISOLATED; await outageModelAccessClient.UpdateOutage(outageEntity); var commands = new Dictionary <long, DiscreteCommandingType> { { upBreaker, DiscreteCommandingType.OPEN }, { nextBreaker, DiscreteCommandingType.OPEN }, }; var enumerableCommandedElements = await CommandedElements.GetEnumerableDictionaryAsync(); if (!await lifecycleHelper.SendMultipleScadaCommandAsync(commands, enumerableCommandedElements, CommandOriginType.LOCATION_AND_ISOLATING_ALGORITHM_COMMAND)) { string message = $"{baseLogString} StartLocationAndIsolationAlgorithm => Sending multiple command failed."; Logger.LogError(message); return(false); } commands.Keys.ToList().ForEach(async commandedElementGid => { await ElementsToBeIgnoredInReportPotentialOutage.SetAsync(commandedElementGid, DateTime.UtcNow); Logger.LogDebug($"{baseLogString} SendCommands => Element 0x{commandedElementGid:X16} set to collection '{ReliableDictionaryNames.ElementsToBeIgnoredInReportPotentialOutage}' at {DateTime.UtcNow}."); }); return(true); }