private async Task SendModelUpdateCommands()
        {
            var scadaCommandingClient           = ScadaCommandingClient.CreateClient();
            var enumerableAddressToGidMapResult = await AddressToGidMap.GetEnumerableDictionaryAsync();

            var tasks = new List <Task>()
            {
                Task.Run(async() =>
                {
                    var key = (short)PointType.ANALOG_OUTPUT;
                    if (!enumerableAddressToGidMapResult.ContainsKey(key))
                    {
                        return;
                    }

                    var analogItemsAddressToGidMap = enumerableAddressToGidMapResult[key];
                    var analogCommandingValues     = new Dictionary <long, float>(analogItemsAddressToGidMap.Count);

                    foreach (long gid in analogItemsAddressToGidMap.Values)
                    {
                        var result          = await GidToPointItemMap.TryGetValueAsync(gid);
                        var analogPointItem = result.Value as IAnalogPointItem;

                        analogCommandingValues.Add(gid, analogPointItem.CurrentEguValue);
                    }

                    if (analogCommandingValues.Count > 0)
                    {
                        await scadaCommandingClient.SendMultipleAnalogCommand(analogCommandingValues, CommandOriginType.MODEL_UPDATE_COMMAND);
                    }
                }),

                Task.Run(async() =>
                {
                    var key = (short)PointType.DIGITAL_OUTPUT;
                    if (!enumerableAddressToGidMapResult.ContainsKey(key))
                    {
                        return;
                    }

                    var discreteItemsAddressToGidMap = enumerableAddressToGidMapResult[key];
                    var discreteCommandingValues     = new Dictionary <long, ushort>(discreteItemsAddressToGidMap.Count);

                    foreach (long gid in discreteItemsAddressToGidMap.Values)
                    {
                        var result            = await GidToPointItemMap.TryGetValueAsync(gid);
                        var discretePointItem = result.Value as IDiscretePointItem;

                        discreteCommandingValues.Add(gid, discretePointItem.CurrentValue);
                    }

                    if (discreteCommandingValues.Count > 0)
                    {
                        await scadaCommandingClient.SendMultipleDiscreteCommand(discreteCommandingValues, CommandOriginType.MODEL_UPDATE_COMMAND);
                    }
                }),
            };

            Task.WaitAll(tasks.ToArray());
        }
Exemplo n.º 2
0
        public async Task <IScadaModelPointItem> UpdatePointItemRawValue(long gid, int rawValue)
        {
            string verboseMessage = $"{baseLogString} entering UpdatePointItemRawValue method.";

            Logger.LogVerbose(verboseMessage);

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

            if (!await GidToPointItemMap.ContainsKeyAsync(gid))
            {
                string message = $"{baseLogString} UpdatePointItemRawValue => Entity with Gid: 0x{gid:X16} does not exist in GidToPointItemMap.";
                Logger.LogError(message);
                throw new ArgumentException(message);
            }

            if ((await GidToPointItemMap.TryGetValueAsync(gid)).Value is IAnalogPointItem analogPoint)
            {
                if (!analogPoint.Initialized)
                {
                    string errorMessage = $"{baseLogString} SendSingleAnalogCommand => PointItem was initialized. Gid: 0x{analogPoint.Gid:X16}, Addres: {analogPoint.Address}, Name: {analogPoint.Name}, RegisterType: {analogPoint.RegisterType}, Initialized: {analogPoint.Initialized}";
                    Logger.LogError(errorMessage);
                }

                analogPoint.CurrentEguValue = analogPoint.RawToEguValueConversion(rawValue);
                await GidToPointItemMap.SetAsync(analogPoint.Gid, analogPoint);

                var result = await GidToPointItemMap.TryGetValueAsync(analogPoint.Gid);

                if (result.HasValue)
                {
                    return(result.Value as IAnalogPointItem);
                }
                else
                {
                    string errorMessage = $"{baseLogString} UpdateAnalogPointItemEguValue => TryGetValueAsync() returns no value";
                    Logger.LogError(errorMessage);
                    throw new Exception(errorMessage);
                }
            }
            else if ((await GidToPointItemMap.TryGetValueAsync(gid)).Value is IDiscretePointItem discretePoint)
            {
                discretePoint.CurrentValue = (ushort)rawValue;
                await GidToPointItemMap.SetAsync(discretePoint.Gid, discretePoint);

                var result = await GidToPointItemMap.TryGetValueAsync(discretePoint.Gid);

                if (result.HasValue)
                {
                    return(result.Value as IDiscretePointItem);
                }
                else
                {
                    string errorMessage = $"{baseLogString} UpdateAnalogPointItemEguValue => TryGetValueAsync() returns no value.";
                    Logger.LogError(errorMessage);
                    throw new Exception(errorMessage);
                }
            }
            else
            {
                string errorMessage = $"{baseLogString} UpdatePointItemRawValue => Entity with Gid: 0x{gid:X16} does not implement IAnalogPointItem nor IDiscretePointItem.";
                Logger.LogError(errorMessage);
                throw new ArgumentException(errorMessage);
            }
        }
        private async Task <bool> ImportDiscrete()
        {
            bool             success;
            int              numberOfResources = 1000;
            List <ModelCode> props             = modelResourceDesc.GetAllPropertyIds(ModelCode.DISCRETE);

            try
            {
                var nmsGdaClient = NetworkModelGdaClient.CreateClient();
                int iteratorId   = await nmsGdaClient.GetExtentValues(ModelCode.DISCRETE, 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);

                        DiscretePointItem discretePoint = new DiscretePointItem(AlarmConfigDataHelper.GetAlarmConfigData());

                        string debugMessage = $"{baseLogString} ImportDiscrete => Before Initialization => Gid: 0x{discretePoint.Gid:X16}, Address: {discretePoint.Address}, CurrentValue: {discretePoint.CurrentValue}, Alarm: {discretePoint.Alarm}, AbnormalValue: {discretePoint.AbnormalValue}, DiscreteType: {discretePoint.DiscreteType}, MinValue: {discretePoint.MinValue}, MaxValue: {discretePoint.MaxValue}, NormalValue: {discretePoint.NormalValue}, RegisterType: {discretePoint.RegisterType}, Name: {discretePoint.Name}, Initialized: {discretePoint.Initialized}";
                        Logger.LogDebug(debugMessage);

                        pointItemHelper.InitializeDiscretePointItem(discretePoint, rds[i].Properties, ModelCode.DISCRETE, enumDescs);

                        debugMessage = $"{baseLogString} ImportDiscrete => After Initialization => Gid: 0x{discretePoint.Gid:X16}, Address: {discretePoint.Address}, CurrentValue: {discretePoint.CurrentValue}, Alarm: {discretePoint.Alarm}, AbnormalValue: {discretePoint.AbnormalValue}, DiscreteType: {discretePoint.DiscreteType}, MinValue: {discretePoint.MinValue}, MaxValue: {discretePoint.MaxValue}, NormalValue: {discretePoint.NormalValue}, RegisterType: {discretePoint.RegisterType}, Name: {discretePoint.Name}, Initialized: {discretePoint.Initialized}";
                        Logger.LogDebug(debugMessage);

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

                        await GidToPointItemMap.SetAsync(gid, discretePoint);

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

                        if (pointItemResult.HasValue)
                        {
                            DiscretePointItem controlPointItem = pointItemResult.Value as DiscretePointItem;
                            debugMessage = $"{baseLogString} ImportDiscrete => Control after CurrentGidToPointItemMap.SetAsync => Gid: 0x{controlPointItem.Gid:X16}, Address: {controlPointItem.Address}, CurrentValue: {controlPointItem.CurrentValue}, Alarm: {controlPointItem.Alarm}, AbnormalValue: {controlPointItem.AbnormalValue}, DiscreteType: {controlPointItem.DiscreteType}, MinValue: {controlPointItem.MinValue}, MaxValue: {controlPointItem.MaxValue}, NormalValue: {controlPointItem.NormalValue}, RegisterType: {controlPointItem.RegisterType}, Name: {controlPointItem.Name}, Initialized: {controlPointItem.Initialized}";
                            Logger.LogDebug(debugMessage);
                        }
                        else
                        {
                            string warningMessage = $"{baseLogString} ImportDiscrete => 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)discretePoint.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} ImportDiscrete => reliable collection '{ReliableDictionaryNames.AddressToGidMap}' is not initialized properly.";
                            Logger.LogError(message);
                            throw new InternalSCADAServiceException(message);
                        }

                        var addressToGidDictionary = addressToGidDictionaryResult.Value;

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

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

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

                    resourcesLeft = await nmsGdaClient.IteratorResourcesLeft(iteratorId);
                }

                await nmsGdaClient.IteratorClose(iteratorId);

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

            return(success);
        }