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);
        }
Beispiel #6
0
        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));
        }
Beispiel #10
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.");
                }
            }
        }