Exemplo n.º 1
0
        private async Task HandleUpdateOperation(IScadaModelPointItem incomingPointItem, long gid)
        {
            var pointItemResult = await IncomingGidToPointItemMap.TryGetValueAsync(gid);

            if (!pointItemResult.HasValue)
            {
                string errorMessage = $"{baseLogString} HandleUpdateOperation => Model update data in fault state. Updating entity with gid: {gid:X16}, that does not exists in IncomingGidToPointItemMap.";
                Logger.LogError(errorMessage);
                throw new ArgumentException(errorMessage);
            }

            IScadaModelPointItem oldPointItem = pointItemResult.Value;

            var addressToGidMapResult = await IncomingAddressToGidMap.TryGetValueAsync((short)oldPointItem.RegisterType);

            if (!addressToGidMapResult.HasValue)
            {
                string errorMessage = $"{baseLogString} HandleUpdateOperation => Model update data in fault state. Updating entity with gid: {gid:X16}, {oldPointItem.RegisterType} registry type does not exist in incoming IncomingAddressToGidMap.";
                Logger.LogError(errorMessage);
                throw new ArgumentException(errorMessage);
            }

            var incomingAddressToGidMapDictionary = addressToGidMapResult.Value;

            if (!incomingAddressToGidMapDictionary.ContainsKey(oldPointItem.Address))
            {
                string message = $"{baseLogString} HandleUpdateOperation => Model update data in fault state. Updating point with address: {oldPointItem.Address}, that does not exists in IncomingAddressToGidMap.";
                Logger.LogError(message);
                throw new ArgumentException(message);
            }

            if (oldPointItem.Address != incomingPointItem.Address && incomingAddressToGidMapDictionary.ContainsKey(incomingPointItem.Address))
            {
                string message = $"{baseLogString} HandleUpdateOperation => Model update data in fault state. Trying to add point with address: {incomingPointItem.Address}, that already exists in IncomingAddressToGidMap.";
                Logger.LogError(message);
                throw new ArgumentException(message);
            }

            string appendMessage = ""; string oldAddressText = "";

            //LOGIC
            await IncomingGidToPointItemMap.SetAsync(gid, incomingPointItem);

            if (oldPointItem.Address != incomingPointItem.Address)
            {
                incomingAddressToGidMapDictionary.Remove(oldPointItem.Address);
                incomingAddressToGidMapDictionary.Add(incomingPointItem.Address, gid);

                await IncomingAddressToGidMap.SetAsync((short)oldPointItem.RegisterType, incomingAddressToGidMapDictionary);

                appendMessage  = " and IncomingAddressToGidMap";
                oldAddressText = $", Old address: {oldPointItem.Address}";
            }

            string debugMessage = $"{baseLogString} HandleUpdateOperation => SUCCESSFULLY updated point from IncomingGidToPointItemMap{appendMessage}. Gid: 0x{incomingPointItem.Gid:X16}, Address: {incomingPointItem.Address}{oldAddressText}";

            Logger.LogDebug(debugMessage);
        }
Exemplo n.º 2
0
        private async Task HandleDeleteOperation(long gid)
        {
            var pointItemResult = await IncomingGidToPointItemMap.TryGetValueAsync(gid);

            if (!pointItemResult.HasValue)
            {
                string errorMessage = $"{baseLogString} HandleDeleteOperation => Model update data in fault state. Deleting entity with gid: {gid:X16}, that does not exists in IncomingGidToPointItemMap.";
                Logger.LogError(errorMessage);
                throw new ArgumentException(errorMessage);
            }

            IScadaModelPointItem oldPointItem = pointItemResult.Value;

            Dictionary <ushort, long> incomingAddressToGidMapDictionary;
            var type = (short)oldPointItem.RegisterType;

            var addressToGidMapResult = await IncomingAddressToGidMap.TryGetValueAsync(type);

            if (!addressToGidMapResult.HasValue)
            {
                incomingAddressToGidMapDictionary = new Dictionary <ushort, long>();
            }
            else
            {
                incomingAddressToGidMapDictionary = addressToGidMapResult.Value;
            }

            if (!incomingAddressToGidMapDictionary.ContainsKey(oldPointItem.Address))
            {
                string message = $"{baseLogString} HandleDeleteOperation => Model update data in fault state. Deleting point with address: {oldPointItem.Address}, that does not exists in IncomingAddressToGidMap.";
                Logger.LogError(message);
                throw new ArgumentException(message);
            }

            //LOGIC
            await IncomingGidToPointItemMap.TryRemoveAsync(gid);

            incomingAddressToGidMapDictionary.Remove(oldPointItem.Address);
            await IncomingAddressToGidMap.SetAsync(type, incomingAddressToGidMapDictionary);

            string debugMessage = $"{baseLogString} HandleDeleteOperation => SUCCESSFULLY deleted point from IncomingGidToPointItemMap and IncomingAddressToGidMap. Gid: 0x{oldPointItem.Gid:X16}, Address: {oldPointItem.Address}";

            Logger.LogDebug(debugMessage);
        }
Exemplo n.º 3
0
        private async Task InitializeIncomingScadaModel()
        {
            var enumerableCurrentGidToPointItemMap = await CurrentGidToPointItemMap.GetEnumerableDictionaryAsync();

            foreach (long gid in enumerableCurrentGidToPointItemMap.Keys)
            {
                //NODO: to tasks, await all (performanse)

                IScadaModelPointItem pointItem = enumerableCurrentGidToPointItemMap[gid].Clone();

                await IncomingGidToPointItemMap.SetAsync(gid, pointItem);

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

                var addressToGidDictionaryResult = await IncomingAddressToGidMap.TryGetValueAsync(registerType);

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

                var addressToGidDictionary = addressToGidDictionaryResult.Value;

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

                addressToGidDictionary.Add(pointItem.Address, pointItem.Gid);
                await IncomingAddressToGidMap.SetAsync(registerType, addressToGidDictionary);

                string debugMessage = $"{baseLogString} InitializeIncomingScadaModel => measurement added to Incoming SCADA model [Gid: 0x{gid:X16}, Address: {pointItem.Address}]";
                Logger.LogDebug(debugMessage);
            }
        }
Exemplo n.º 4
0
        private async Task HandleInsertOperation(IScadaModelPointItem incomingPointItem, long gid)
        {
            var pointItemResult = await IncomingGidToPointItemMap.TryGetValueAsync(gid);

            if (pointItemResult.HasValue)
            {
                string errorMessage = $"{baseLogString} HandleInsertOperation => Model update data in fault state. Inserting entity with gid: {gid:X16}, that already exists in IncomingGidToPointItemMap.";
                Logger.LogError(errorMessage);
                throw new ArgumentException(errorMessage);
            }

            Dictionary <ushort, long> incomingAddressToGidMapDictionary;
            var type = (short)incomingPointItem.RegisterType;
            var addressToGidMapResult = await IncomingAddressToGidMap.TryGetValueAsync(type);

            if (!addressToGidMapResult.HasValue)
            {
                incomingAddressToGidMapDictionary = new Dictionary <ushort, long>();
            }
            else
            {
                incomingAddressToGidMapDictionary = addressToGidMapResult.Value;
            }

            if (incomingAddressToGidMapDictionary.ContainsKey(incomingPointItem.Address))
            {
                string message = $"{baseLogString} HandleInsertOperation => Model update data in fault state. Inserting entity with address: {incomingPointItem.Address}, that already exists in IncomingAddressToGidMap.";
                Logger.LogError(message);
                throw new ArgumentException(message);
            }

            //LOGIC
            await IncomingGidToPointItemMap.SetAsync(gid, incomingPointItem);

            incomingAddressToGidMapDictionary.Add(incomingPointItem.Address, gid);
            await IncomingAddressToGidMap.SetAsync(type, incomingAddressToGidMapDictionary);

            string debugMessage = $"{baseLogString} HandleInsertOperation => SUCCESSFULLY inserted point into IncomingGidToPointItemMap and IncomingAddressToGidMap. Gid: 0x{incomingPointItem.Gid:X16}, Address: {incomingPointItem.Address}";

            Logger.LogDebug(debugMessage);
        }
Exemplo n.º 5
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.º 6
0
        public async Task <bool> SendSingleAnalogCommand(long gid, float commandingValue, CommandOriginType commandOriginType)
        {
            string verboseMessage = $"{baseLogString} SendSingleAnalogCommand method called. gid: {gid:X16}, commandingValue: {commandingValue}, commandOriginType: {commandOriginType}";

            Logger.LogVerbose(verboseMessage);

            IScadaModelReadAccessContract           scadaModelReadAccessClient = ScadaModelReadAccessClient.CreateClient();
            Dictionary <long, IScadaModelPointItem> gidToPointItemMap          = await scadaModelReadAccessClient.GetGidToPointItemMap();

            if (gidToPointItemMap == null)
            {
                string message = $"{baseLogString} SendSingleAnalogCommand => SendSingleAnalogCommand => SCADA model is null.";
                Logger.LogError(message);
                //throw new InternalSCADAServiceException(message);
                return(false);
            }

            if (!gidToPointItemMap.ContainsKey(gid))
            {
                string message = $"{baseLogString} SendSingleAnalogCommand => Entity with gid: 0x{gid:X16} does not exist in current SCADA model.";
                Logger.LogError(message);
                //throw new ArgumentException(message);
                return(false);
            }

            IScadaModelPointItem pointItem = gidToPointItemMap[gid];

            if (!(pointItem is IAnalogPointItem analogPointItem && pointItem.RegisterType == PointType.ANALOG_OUTPUT))
            {
                string message = $"{baseLogString} SendSingleAnalogCommand => Either RegistarType of entity with gid: 0x{gid:X16} is not ANALOG_OUTPUT or entity does not implement IAnalogPointItem interface.";
                Logger.LogError(message);
                //throw new ArgumentException(message);
                return(false);
            }

            try
            {
                if (!analogPointItem.Initialized)
                {
                    string errorMessage = $"{baseLogString} SendSingleAnalogCommand => PointItem was initialized. Gid: 0x{analogPointItem.Gid:X16}, Addres: {analogPointItem.Address}, Name: {analogPointItem.Name}, RegisterType: {analogPointItem.RegisterType}, Initialized: {analogPointItem.Initialized}";
                    Logger.LogError(errorMessage);
                }

                //LOGIC
                int modbusValue = analogPointItem.EguToRawValueConversion(commandingValue);

                string debugMessage = $"{baseLogString} SendSingleAnalogCommand => Calling SendSingleCommand({pointItem}, {modbusValue}, {commandOriginType})";
                Logger.LogDebug(verboseMessage);

                //KEY LOGIC
                await SendSingleCommand(pointItem, modbusValue, commandOriginType);

                debugMessage = $"{baseLogString} SendSingleAnalogCommand => SendSingleCommand() executed SUCCESSFULLY";
                Logger.LogDebug(debugMessage);

                return(true);
            }
            catch (Exception e)
            {
                string message = $"{baseLogString} SendSingleAnalogCommand => Exception in SendAnalogCommand() method.";
                Logger.LogError(message, e);
                //throw new InternalSCADAServiceException(message, e);
                return(false);
            }
        }