Exemplo n.º 1
0
        public bool Prepare()
        {
            bool success = false;

            transactionDbContext = new UnitOfWork();
            Dictionary <long, ResourceDescription> resourceDescriptions = GetExtentValues(ModelCode.ENERGYCONSUMER, modelResourcesDesc.GetAllPropertyIds(ModelCode.ENERGYCONSUMER));

            List <Consumer> consumerDbEntities = transactionDbContext.ConsumerRepository.GetAll().ToList();

            foreach (Consumer consumer in consumerDbEntities)
            {
                if (modelChanges[DeltaOpType.Delete].Contains(consumer.ConsumerId))
                {
                    transactionDbContext.ConsumerRepository.Remove(consumer);
                }
                else if (modelChanges[DeltaOpType.Update].Contains(consumer.ConsumerId))
                {
                    consumer.ConsumerMRID = resourceDescriptions[consumer.ConsumerId].GetProperty(ModelCode.IDOBJ_MRID).AsString(); //TODO other prop, when added in model
                }
            }

            foreach (long gid in modelChanges[DeltaOpType.Insert])
            {
                ModelCode type = modelResourcesDesc.GetModelCodeFromId(gid);

                if (type == ModelCode.ENERGYCONSUMER)
                {
                    ResourceDescription resourceDescription = resourceDescriptions[gid];

                    if (resourceDescription != null)
                    {
                        Consumer consumer = new Consumer
                        {
                            ConsumerId   = resourceDescription.Id,
                            ConsumerMRID = resourceDescription.GetProperty(ModelCode.IDOBJ_MRID).AsString(),
                            FirstName    = "Added",   //TODO: resourceDescription.GetProperty(ModelCode.ENERGYCONSUMER_FIRSTNAME).AsString()
                            LastName     = "Consumer" //TODO: resourceDescription.GetProperty(ModelCode.ENERGYCONSUMER_LASTNAME).AsString() other prop, when added in model
                        };

                        transactionDbContext.ConsumerRepository.Add(consumer);
                    }
                    else
                    {
                        Logger.LogWarn($"Consumer with gid 0x{gid:X16} is not in network model");
                    }
                }
            }

            success = true;

            return(success);
        }
Exemplo n.º 2
0
        //popunjavanje 3. comboboxa iz 3. taba
        private void comboBox5_SelectedIndexChanged(object sender, EventArgs e)
        {
            listaPropertija.Clear();
            button3.Enabled   = false;
            richTextBox2.Text = string.Empty;
            comboBox6.Items.Clear();
            richTextBox4.Controls.Clear();
            richTextBox4.Clear();

            try
            {
                long gid = (long)comboBox5.SelectedItem;

                ModelCode           mc = modelRD.GetModelCodeFromId(gid);
                ResourceDescription rd = gda.GetValues(gid);


                for (int i = 0; i < rd.Properties.Count; i++)
                {
                    switch (rd.Properties[i].Type)
                    {
                    case PropertyType.Reference:
                        listaPropertija.Add(rd.Properties[i].Id);
                        break;

                    case PropertyType.ReferenceVector:
                        listaPropertija.Add(rd.Properties[i].Id);
                        break;
                    }
                }

                foreach (var v in listaPropertija)
                {
                    comboBox6.Items.Add(v);
                }
            }
            catch
            {
                richTextBox2.Text = "ERROR!";
            }

            if (comboBox5.SelectedItem != null)
            {
                comboBox6.Enabled = true;
                tipoviReferenciranihKlasa.Clear();
            }
            else
            {
                comboBox6.Enabled = false;
            }
        }
        public TopologyStatus GetElementTopologyStatus(long gid)
        {
            logger.LogDebug($"Getting element topology status for GID {gid}.");
            TopologyStatus retVal;
            DMSType        type = ModelCodeHelper.GetTypeFromModelCode(modelResourcesDesc.GetModelCodeFromId(gid));

            foreach (var item in elementsStatus)
            {
                if (item.Value.Contains(type))
                {
                    retVal = item.Key;
                    return(retVal);
                }
            }
            return(TopologyStatus.Regular);
        }
Exemplo n.º 4
0
        public async Task Notify(IPublishableMessage message, string publisherName)
        {
            while (!ReliableDictionariesInitialized)
            {
                await Task.Delay(1000);
            }

            if (message is EmailToOutageMessage emailMessage)
            {
                if (emailMessage.Gid == 0)
                {
                    Logger.LogError("Invalid email received.");
                    return;
                }

                Logger.LogInformation($"Received call from Energy Consumer with GID: 0x{emailMessage.Gid:X16}.");

                if (!modelResourcesDesc.GetModelCodeFromId(emailMessage.Gid).Equals(ModelCode.ENERGYCONSUMER))
                {
                    Logger.LogWarning($"Received GID 0x{emailMessage.Gid:X16} is not id of energy consumer.");
                    return;
                }

                var topologyProviderClient = TopologyProviderClient.CreateClient();
                var topology = await topologyProviderClient.GetOMSModel();

                if (!topology.GetElementByGid(emailMessage.Gid, out OutageTopologyElement elment))
                {
                    Logger.LogWarning($"Received GID 0x{emailMessage.Gid:X16} is not part of topology.");
                    return;
                }

                if (!timer.Enabled)
                {
                    timer.Start();
                }

                await Calls.SetAsync(emailMessage.Gid, emailMessage.Gid);

                Logger.LogInformation($"Current number of calls is: {await Calls.GetCountAsync()}.");

                if (await Calls.GetCountAsync() >= expectedCalls)
                {
                    await trackingAlgorithm.Start((await Calls.GetDataCopyAsync()).Keys.ToList());

                    await Calls.ClearAsync();

                    timer.Stop();
                }
            }
        }
Exemplo n.º 5
0
        public void Notify(IPublishableMessage message)
        {
            if (message is EmailToOutageMessage emailMessage)
            {
                if (emailMessage.Gid == 0)
                {
                    Logger.LogError("Invalid email received.");
                    return;
                }

                Logger.LogInfo($"Received call from Energy Consumer with GID: 0x{emailMessage.Gid:X16}.");

                if (!resourcesDesc.GetModelCodeFromId(emailMessage.Gid).Equals(ModelCode.ENERGYCONSUMER))
                {
                    Logger.LogWarn("Received GID is not id of energy consumer.");
                }
                else if (!outageModel.TopologyModel.OutageTopology.ContainsKey(emailMessage.Gid) && outageModel.TopologyModel.FirstNode != emailMessage.Gid)
                {
                    Logger.LogWarn("Received GID is not part of topology");
                }
                else
                {
                    if (!timer.Enabled) //first message
                    {
                        StartTimer();
                    }

                    calls.Enqueue(emailMessage.Gid);
                    Logger.LogInfo($"Current number of calls is: {calls.Count}.");
                    if (calls.Count >= expectedCalls)
                    {
                        trackingAlgorithm.Start(calls);

                        StopTimer();
                    }
                }
            }
            else
            {
                Logger.LogWarn("Received message is not EmailToOutageMessage.");
            }
        }
Exemplo n.º 6
0
        public async Task <bool> Prepare()
        {
            bool success;

            while (!ReliableDictionariesInitialized)
            {
                await Task.Delay(1000);
            }

            try
            {
                //INIT INCOMING SCADA MODEL with current model values
                await InitializeIncomingScadaModel();

                //IMPORT ALL measurements from NMS and create PointItems for them
                var enumerableModelChanges = await ModelChanges.GetEnumerableDictionaryAsync();

                Dictionary <long, IScadaModelPointItem> incomingPointItems = await CreatePointItemsFromNetworkModelMeasurements(enumerableModelChanges);

                //ORDER IS IMPORTANT due to IncomingAddressToGidMap validity: DELETE => UPDATE => INSERT
                var orderOfOperations = new List <DeltaOpType>()
                {
                    DeltaOpType.Delete, DeltaOpType.Update, DeltaOpType.Insert
                };

                foreach (var operation in orderOfOperations)
                {
                    foreach (long gid in enumerableModelChanges[(byte)operation])
                    {
                        ModelCode type = modelResourceDesc.GetModelCodeFromId(gid);
                        if (type != ModelCode.ANALOG && type != ModelCode.DISCRETE)
                        {
                            continue;
                        }

                        if (operation == DeltaOpType.Delete)
                        {
                            await HandleDeleteOperation(gid);
                        }
                        else if (operation == DeltaOpType.Update)
                        {
                            IScadaModelPointItem incomingPointItem = incomingPointItems[gid];
                            await HandleUpdateOperation(incomingPointItem, gid);
                        }
                        else if (operation == DeltaOpType.Insert)
                        {
                            IScadaModelPointItem incomingPointItem = incomingPointItems[gid];
                            await HandleInsertOperation(incomingPointItem, gid);
                        }
                    }
                }

                success = await CheckSuccessiveAddressCondition();

                ;
            }
            catch (Exception e)
            {
                string errorMessage = $"{baseLogString} Prepare => Exception: {e.Message}";
                Logger.LogError(errorMessage, e);
                success = false;
            }

            return(success);
        }
Exemplo n.º 7
0
        public async Task <bool> Prepare()
        {
            bool success;

            try
            {
                //INIT INCOMING SCADA MODEL with current model values
                //can not go with just 'incomingScadaModel = new Dictionary<long, ISCADAModelPointItem>(CurrentScadaModel)' because IncomingAddressToGidMap must also be initialized
                incomingScadaModel = new Dictionary <long, ISCADAModelPointItem>(CurrentScadaModel.Count);

                foreach (long gid in CurrentScadaModel.Keys)
                {
                    ModelCode            type      = modelResourceDesc.GetModelCodeFromId(gid);
                    ISCADAModelPointItem pointItem = CurrentScadaModel[gid].Clone();

                    IncomingScadaModel.Add(gid, pointItem);

                    if (!IncomingAddressToGidMap[pointItem.RegisterType].ContainsKey(pointItem.Address))
                    {
                        IncomingAddressToGidMap[pointItem.RegisterType].Add(pointItem.Address, gid);
                    }
                }

                //IMPORT ALL measurements from NMS and create PointItems for them
                Dictionary <long, ISCADAModelPointItem> incomingPointItems = await CreatePointItemsFromNetworkModelMeasurements();

                //ORDER IS IMPORTANT due to IncomingAddressToGidMap validity: DELETE => UPDATE => INSERT

                foreach (long gid in modelChanges[DeltaOpType.Delete])
                {
                    ModelCode type = modelResourceDesc.GetModelCodeFromId(gid);
                    if (type == ModelCode.ANALOG || type == ModelCode.DISCRETE)
                    {
                        if (!IncomingScadaModel.ContainsKey(gid))
                        {
                            success = false;
                            string message = $"Model update data in fault state. Deleting entity with gid: {gid}, that does not exists in SCADA model.";
                            Logger.LogError(message);
                            throw new ArgumentException(message);
                        }

                        ISCADAModelPointItem oldPointItem = IncomingScadaModel[gid];
                        IncomingScadaModel.Remove(gid);

                        IncomingAddressToGidMap[oldPointItem.RegisterType].Remove(oldPointItem.Address);
                    }
                }

                foreach (long gid in modelChanges[DeltaOpType.Update])
                {
                    ModelCode type = modelResourceDesc.GetModelCodeFromId(gid);
                    if (type == ModelCode.ANALOG || type == ModelCode.DISCRETE)
                    {
                        if (!IncomingScadaModel.ContainsKey(gid))
                        {
                            success = false;
                            string message = $"Model update data in fault state. Updating entity with gid: 0x{gid:X16}, that does not exists in SCADA model.";
                            Logger.LogError(message);
                            throw new ArgumentException(message);
                        }

                        ISCADAModelPointItem incomingPointItem = incomingPointItems[gid];
                        ISCADAModelPointItem oldPointItem      = IncomingScadaModel[gid];

                        if (!IncomingAddressToGidMap[oldPointItem.RegisterType].ContainsKey(oldPointItem.Address))
                        {
                            success = false;
                            string message = $"Model update data in fault state. Updating point with address: {oldPointItem.Address}, that does not exists in SCADA model.";
                            Logger.LogError(message);
                            throw new ArgumentException(message);
                        }

                        if (oldPointItem.Address != incomingPointItem.Address && IncomingAddressToGidMap[incomingPointItem.RegisterType].ContainsKey(incomingPointItem.Address))
                        {
                            success = false;
                            string message = $"Model update data in fault state. Trying to add point with address: {incomingPointItem.Address}, that already exists in SCADA model.";
                            Logger.LogError(message);
                            throw new ArgumentException(message);
                        }

                        IncomingScadaModel[gid] = incomingPointItem;

                        if (oldPointItem.Address != incomingPointItem.Address)
                        {
                            IncomingAddressToGidMap[oldPointItem.RegisterType].Remove(oldPointItem.Address);
                            IncomingAddressToGidMap[incomingPointItem.RegisterType].Add(incomingPointItem.Address, gid);
                        }
                    }
                }

                foreach (long gid in modelChanges[DeltaOpType.Insert])
                {
                    ModelCode type = modelResourceDesc.GetModelCodeFromId(gid);
                    if (type == ModelCode.ANALOG || type == ModelCode.DISCRETE)
                    {
                        if (IncomingScadaModel.ContainsKey(gid))
                        {
                            success = false;
                            string message = $"Model update data in fault state. Inserting gid: {gid}, that already exists in SCADA model.";
                            Logger.LogError(message);
                            throw new ArgumentException(message);
                        }

                        ISCADAModelPointItem incomingPointItem = incomingPointItems[gid];

                        if (IncomingAddressToGidMap[incomingPointItem.RegisterType].ContainsKey(incomingPointItem.Address))
                        {
                            success = false;
                            string message = $"Model update data in fault state. Trying to add point with address: {incomingPointItem.Address}, that already exists in SCADA model.";
                            Logger.LogError(message);
                            throw new ArgumentException(message);
                        }

                        IncomingScadaModel.Add(gid, incomingPointItem);
                        IncomingAddressToGidMap[incomingPointItem.RegisterType].Add(incomingPointItem.Address, gid);
                    }
                }

                success = true;
            }
            catch (Exception e)
            {
                Logger.LogError($"Exception caught in Prepare method on SCADAModel.", e);
                success = false;
            }

            return(success);
        }
        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 <bool> Prepare()
        {
            bool success;

            try
            {
                Logger.LogDebug("Enter prepare method");
                this.unitOfWork = new UnitOfWork();
                List <Consumer> consumerDbEntities = this.unitOfWork.ConsumerRepository.GetAll().ToList();

                var resourceDescriptions = await GetExtentValues(ModelCode.ENERGYCONSUMER, modelResourcesDesc.GetAllPropertyIds(ModelCode.ENERGYCONSUMER));

                var modelChangesEnumerable = await HistoryModelChanges.GetEnumerableDictionaryAsync();


                List <OutageEntity> activeOutages = this.unitOfWork.OutageRepository.GetAllActive().ToList();

                this.unitOfWork.OutageRepository.RemoveRange(activeOutages);

                //this.unitOfWork.OutageRepository.RemoveAll();
                //this.unitOfWork.EquipmentRepository.RemoveAll();
                //this.unitOfWork.EquipmentHistoricalRepository.RemoveAll();
                //this.unitOfWork.ConsumerHistoricalRepository.RemoveAll();

                foreach (Consumer consumer in consumerDbEntities)
                {
                    if (modelChangesEnumerable[(byte)DeltaOpType.Delete].Contains(consumer.ConsumerId))
                    {
                        this.unitOfWork.ConsumerRepository.Remove(consumer);
                    }
                    else if (modelChangesEnumerable[(byte)DeltaOpType.Update].Contains(consumer.ConsumerId))
                    {
                        consumer.ConsumerMRID = resourceDescriptions[consumer.ConsumerId].GetProperty(ModelCode.IDOBJ_MRID).AsString();
                        consumer.FirstName    = resourceDescriptions[consumer.ConsumerId].GetProperty(ModelCode.ENERGYCONSUMER_FIRSTNAME).AsString();
                        consumer.LastName     = resourceDescriptions[consumer.ConsumerId].GetProperty(ModelCode.ENERGYCONSUMER_LASTNAME).AsString();
                        consumer.Type         = (EnergyConsumerType)resourceDescriptions[consumer.ConsumerId].GetProperty(ModelCode.ENERGYCONSUMER_TYPE).AsEnum();
                        consumer.Outages.Clear();

                        this.unitOfWork.ConsumerRepository.Update(consumer);
                    }
                }

                foreach (long gid in modelChangesEnumerable[(byte)DeltaOpType.Insert])
                {
                    ModelCode type = modelResourcesDesc.GetModelCodeFromId(gid);

                    if (type != ModelCode.ENERGYCONSUMER)
                    {
                        continue;
                    }

                    ResourceDescription resourceDescription = resourceDescriptions[gid];

                    if (resourceDescription == null)
                    {
                        Logger.LogWarning($"Consumer with gid 0x{gid:X16} is not in network model");
                        continue;
                    }

                    Consumer consumer = new Consumer
                    {
                        ConsumerId   = resourceDescription.Id,
                        ConsumerMRID = resourceDescription.GetProperty(ModelCode.IDOBJ_MRID).AsString(),
                        FirstName    = resourceDescription.GetProperty(ModelCode.ENERGYCONSUMER_FIRSTNAME).AsString(),
                        LastName     = resourceDescription.GetProperty(ModelCode.ENERGYCONSUMER_LASTNAME).AsString(),
                        Type         = (EnergyConsumerType)resourceDescriptions[resourceDescription.Id].GetProperty(ModelCode.ENERGYCONSUMER_TYPE).AsEnum(),
                    };

                    if (this.unitOfWork.ConsumerRepository.Get(consumer.ConsumerId) == null)
                    {
                        this.unitOfWork.ConsumerRepository.Add(consumer);
                    }
                    else
                    {
                        Logger.LogWarning($"{baseLogString} Prepare => Consumer with gid 0x{consumer.ConsumerId:X16} already exists in DB. Delta Operation: {DeltaOpType.Insert}. Potential fixes: " +
                                          $"{Environment.NewLine}If MongoDB is empty => Delte rows from Consumer Table. " +
                                          $"{Environment.NewLine}If Mongo contains stored NetworkModel => Ignore this warn as it is part of initialization (part of the first distributed transaction).");
                    }
                }

                success = true;
            }
            catch (Exception e)
            {
                string message = $"{baseLogString} Prepare => Exception: {e.Message}";
                Logger.LogError(message, e);
                success = false;
                this.unitOfWork.Dispose();
            }

            return(success);
        }
        private async Task <bool> ImportAnalog()
        {
            bool             success;
            int              numberOfResources = 1000;
            List <ModelCode> props             = modelResourceDesc.GetAllPropertyIds(ModelCode.ANALOG);

            try
            {
                var nmsGdaClient = NetworkModelGdaClient.CreateClient();
                int iteratorId   = await nmsGdaClient.GetExtentValues(ModelCode.ANALOG, props);

                int resourcesLeft = await nmsGdaClient.IteratorResourcesLeft(iteratorId);

                while (resourcesLeft > 0)
                {
                    List <ResourceDescription> rds = await nmsGdaClient.IteratorNext(numberOfResources, iteratorId);

                    for (int i = 0; i < rds.Count; i++)
                    {
                        if (rds[i] == null)
                        {
                            continue;
                        }

                        long      gid  = rds[i].Id;
                        ModelCode type = modelResourceDesc.GetModelCodeFromId(gid);

                        AnalogPointItem analogPoint = new AnalogPointItem(AlarmConfigDataHelper.GetAlarmConfigData());

                        string debugMessage = $"{baseLogString} ImportAnalog => Before Initialization => Gid: 0x{analogPoint.Gid:X16}, Address: {analogPoint.Address}, CurrentRawValue: {analogPoint.CurrentRawValue}, Alarm: {analogPoint.Alarm}, ScalingFactor: {analogPoint.ScalingFactor}, Deviation: {analogPoint.Deviation}, MinRawValue: {analogPoint.MinRawValue}, MaxRawValue: {analogPoint.MaxRawValue}, NormalValue: {analogPoint.NormalValue}, RegisterType: {analogPoint.RegisterType}, Name: {analogPoint.Name}, Initialized: {analogPoint.Initialized}";
                        Logger.LogDebug(debugMessage);

                        pointItemHelper.InitializeAnalogPointItem(analogPoint, rds[i].Properties, ModelCode.ANALOG, enumDescs);

                        debugMessage = $"{baseLogString} ImportAnalog => After Initialization => Gid: 0x{analogPoint.Gid:X16}, Address: {analogPoint.Address}, CurrentRawValue: {analogPoint.CurrentRawValue}, Alarm: {analogPoint.Alarm}, ScalingFactor: {analogPoint.ScalingFactor}, Deviation: {analogPoint.Deviation}, MinRawValue: {analogPoint.MinRawValue}, MaxRawValue: {analogPoint.MaxRawValue}, NormalValue: {analogPoint.NormalValue}, RegisterType: {analogPoint.RegisterType}, Name: {analogPoint.Name}, Initialized: {analogPoint.Initialized}";
                        Logger.LogDebug(debugMessage);

                        if (await GidToPointItemMap.ContainsKeyAsync(gid))
                        {
                            string errorMessage = $"{baseLogString} ImportAnalog => SCADA model is invalid => Gid: 0x{gid:16} belongs to more than one entity.";
                            Logger.LogError(errorMessage);
                            throw new InternalSCADAServiceException(errorMessage);
                        }

                        await GidToPointItemMap.SetAsync(gid, analogPoint);

#if DEBUG
                        var pointItemResult = await GidToPointItemMap.TryGetValueAsync(gid);

                        if (pointItemResult.HasValue)
                        {
                            AnalogPointItem controlPointItem = pointItemResult.Value as AnalogPointItem;
                            debugMessage = $"{baseLogString} ImportAnalog => Control after CurrentGidToPointItemMap.SetAsync => Gid: 0x{controlPointItem.Gid:X16}, Address: {controlPointItem.Address}, CurrentRawValue: {controlPointItem.CurrentRawValue}, Alarm: {controlPointItem.Alarm}, ScalingFactor: {controlPointItem.ScalingFactor}, Deviation: {controlPointItem.Deviation}, MinRawValue: {controlPointItem.MinRawValue}, MaxRawValue: {controlPointItem.MaxRawValue}, NormalValue: {controlPointItem.NormalValue}, RegisterType: {controlPointItem.RegisterType}, Name: {controlPointItem.Name}, Initialized: {controlPointItem.Initialized}";
                            Logger.LogDebug(debugMessage);
                        }
                        else
                        {
                            string warningMessage = $"{baseLogString} ImportAnalog => Control after CurrentGidToPointItemMap.SetAsync => Gid: 0x{gid:X16} was not found in reliable collection '{ReliableDictionaryNames.GidToPointItemMap}' after the value was supposedly set.";
                            Logger.LogWarning(warningMessage);
                        }
#endif

                        short registerType = (short)analogPoint.RegisterType;
                        if (!(await AddressToGidMap.ContainsKeyAsync(registerType)))
                        {
                            await AddressToGidMap.SetAsync(registerType, new Dictionary <ushort, long>());
                        }

                        var addressToGidDictionaryResult = await AddressToGidMap.TryGetValueAsync(registerType);

                        if (!addressToGidDictionaryResult.HasValue)
                        {
                            string message = $"{baseLogString} ImportAnalog => reliable collection '{ReliableDictionaryNames.AddressToGidMap}' is not initialized properly.";
                            Logger.LogError(message);
                            throw new InternalSCADAServiceException(message);
                        }

                        var addressToGidDictionary = addressToGidDictionaryResult.Value;

                        if (addressToGidDictionary.ContainsKey(analogPoint.Address))
                        {
                            string message = $"{baseLogString} ImportAnalog => SCADA model is invalid => Address: {analogPoint.Address} (RegType: {registerType}) belongs to more than one entity.";
                            Logger.LogError(message);
                            throw new InternalSCADAServiceException(message);
                        }

                        addressToGidDictionary.Add(analogPoint.Address, rds[i].Id);
                        await AddressToGidMap.SetAsync(registerType, addressToGidDictionary);

                        debugMessage = $"{baseLogString} ImportAnalog => ANALOG measurement added to SCADA model [Gid: 0x{gid:X16}, Address: {analogPoint.Address}]";
                        Logger.LogDebug(debugMessage);
                    }

                    resourcesLeft = await nmsGdaClient.IteratorResourcesLeft(iteratorId);
                }

                await nmsGdaClient.IteratorClose(iteratorId);

                success = true;
            }
            catch (Exception ex)
            {
                success = false;
                string errorMessage = $"{baseLogString} ImportAnalog => failed with error: {ex.Message}";
                Trace.WriteLine(errorMessage);
                Logger.LogError(errorMessage, ex);
            }

            return(success);
        }