コード例 #1
0
        public Dictionary<Topic, SCADAPublication> GetIntegrityUpdate()
        {
            if (IntegrityUpdateService.scadaModel == null)
            {
                string message = $"GetIntegrityUpdate => SCADA model is null.";
                Logger.LogError(message);
                throw new InternalSCADAServiceException(message);
            }

            var currentScadaModel = IntegrityUpdateService.scadaModel.CurrentScadaModel;
            var commandValuesCache = IntegrityUpdateService.scadaModel.CommandedValuesCache;

            Dictionary<long, AnalogModbusData> analogModbusData = new Dictionary<long, AnalogModbusData>();
            Dictionary<long, DiscreteModbusData> discreteModbusData = new Dictionary<long, DiscreteModbusData>();

            foreach(long gid in currentScadaModel.Keys)
            {
                CommandOriginType commandOrigin = CommandOriginType.OTHER_COMMAND;

                if (currentScadaModel[gid] is AnalogSCADAModelPointItem analogPointItem)
                {
                    if (commandValuesCache.ContainsKey(gid) && commandValuesCache[gid].Value == analogPointItem.CurrentRawValue)
                    {
                        commandOrigin = commandValuesCache[gid].CommandOrigin;
                    }

                    AnalogModbusData analogValue = new AnalogModbusData(analogPointItem.CurrentEguValue, analogPointItem.Alarm, gid, commandOrigin);
                    analogModbusData.Add(gid, analogValue);
                }
                else if(currentScadaModel[gid] is DiscreteSCADAModelPointItem discretePointItem)
                {
                    if (commandValuesCache.ContainsKey(gid) && commandValuesCache[gid].Value == discretePointItem.CurrentValue)
                    {
                        commandOrigin = commandValuesCache[gid].CommandOrigin;
                    }

                    DiscreteModbusData discreteValue = new DiscreteModbusData(discretePointItem.CurrentValue, discretePointItem.Alarm, gid, commandOrigin);
                    discreteModbusData.Add(gid, discreteValue);
                }
            }

            MultipleAnalogValueSCADAMessage analogValuesMessage = new MultipleAnalogValueSCADAMessage(analogModbusData);
            SCADAPublication measurementPublication = new SCADAPublication(Topic.MEASUREMENT, analogValuesMessage);

            MultipleDiscreteValueSCADAMessage discreteValuesMessage = new MultipleDiscreteValueSCADAMessage(discreteModbusData);
            SCADAPublication switchStatusPublication = new SCADAPublication(Topic.SWITCH_STATUS, discreteValuesMessage);

            Dictionary<Topic, SCADAPublication> scadaPublications = new Dictionary<Topic, SCADAPublication>
            {
                { Topic.MEASUREMENT, measurementPublication },
                { Topic.SWITCH_STATUS, switchStatusPublication },
            };

            return scadaPublications;
        }
コード例 #2
0
        private void MakeAnalogEntryToMeasurementCache(Dictionary <long, AnalogModbusData> data, bool permissionToPublishData)
        {
            Dictionary <long, AnalogModbusData> publicationData = new Dictionary <long, AnalogModbusData>();

            if (data == null)
            {
                string message = $"WriteToMeasurementsCache() => readAnalogCommand.Data is null.";
                Logger.LogError(message);
                throw new NullReferenceException(message);
            }

            foreach (long gid in data.Keys)
            {
                if (!MeasurementsCache.ContainsKey(gid))
                {
                    MeasurementsCache.Add(gid, data[gid]);

                    if (!publicationData.ContainsKey(gid))
                    {
                        publicationData.Add(gid, data[gid]);
                    }
                    else
                    {
                        publicationData[gid] = data[gid];
                    }
                }
                else if (MeasurementsCache[gid] is AnalogModbusData analogCacheItem && analogCacheItem.Value != data[gid].Value)
                {
                    Logger.LogDebug($"Value changed on element with id: {analogCacheItem.MeasurementGid}. Old value: {analogCacheItem.Value}; new value: {data[gid].Value}");
                    MeasurementsCache[gid] = data[gid];


                    if (!publicationData.ContainsKey(gid))
                    {
                        publicationData.Add(gid, MeasurementsCache[gid] as AnalogModbusData);
                    }
                    else
                    {
                        publicationData[gid] = MeasurementsCache[gid] as AnalogModbusData;
                    }
                }
            }

            //if data is empty that means that there are no new values in the current acquisition cycle
            if (permissionToPublishData && publicationData.Count > 0)
            {
                SCADAMessage scadaMessage = new MultipleAnalogValueSCADAMessage(publicationData);
                PublishScadaData(Topic.MEASUREMENT, scadaMessage);
            }
        }
コード例 #3
0
        public void Notify(IPublishableMessage message)
        {
            if (message is SingleAnalogValueSCADAMessage)
            {
                SingleAnalogValueSCADAMessage msg = (SingleAnalogValueSCADAMessage)message;
                Console.WriteLine($"Merenje: {msg.AnalogModbusData.MeasurementGid} {msg.AnalogModbusData.Value}");
            }
            else if (message is MultipleAnalogValueSCADAMessage)
            {
                MultipleAnalogValueSCADAMessage msg = (MultipleAnalogValueSCADAMessage)message;
                foreach (var item in msg.Data)
                {
                    Console.WriteLine($"Merenje: {item.Key} {item.Value}");
                }
            }
            TopologyForUIMessage model = message as TopologyForUIMessage;

            PrintUI(model.UIModel);
        }
コード例 #4
0
        public async Task <ScadaPublication> GetIntegrityUpdateForSpecificTopic(Topic topic)
        {
            while (!ReliableDictionariesInitialized)
            {
                await Task.Delay(1000);
            }

            if (GidToPointItemMap == null)
            {
                string message = $"GetIntegrityUpdate => GidToPointItemMap is null.";
                Logger.LogError(message);
                throw new InternalSCADAServiceException(message);
            }

            if (CommandDescriptionCache == null)
            {
                string message = $"GetIntegrityUpdate => CommandDescriptionCache is null.";
                Logger.LogError(message);
                throw new InternalSCADAServiceException(message);
            }

            Dictionary <long, AnalogModbusData>   analogModbusData   = new Dictionary <long, AnalogModbusData>();
            Dictionary <long, DiscreteModbusData> discreteModbusData = new Dictionary <long, DiscreteModbusData>();

            var enumerableGidToPointItemMap = await GidToPointItemMap.GetEnumerableDictionaryAsync();

            foreach (long gid in enumerableGidToPointItemMap.Keys)
            {
                CommandOriginType commandOrigin = CommandOriginType.UNKNOWN_ORIGIN;

                if (topic == Topic.MEASUREMENT && enumerableGidToPointItemMap[gid] is IAnalogPointItem analogPointItem)
                {
                    var result = await CommandDescriptionCache.TryGetValueAsync(gid);

                    if (result.HasValue && result.Value.Value == analogPointItem.CurrentRawValue)
                    {
                        commandOrigin = result.Value.CommandOrigin;
                    }

                    AnalogModbusData analogValue = new AnalogModbusData(analogPointItem.CurrentEguValue, analogPointItem.Alarm, gid, commandOrigin);
                    analogModbusData.Add(gid, analogValue);
                }
                else if (topic == Topic.SWITCH_STATUS && enumerableGidToPointItemMap[gid] is IDiscretePointItem discretePointItem)
                {
                    var result = await CommandDescriptionCache.TryGetValueAsync(gid);

                    if (result.HasValue && result.Value.Value == discretePointItem.CurrentValue)
                    {
                        commandOrigin = result.Value.CommandOrigin;
                    }


                    DiscreteModbusData discreteValue = new DiscreteModbusData(discretePointItem.CurrentValue, discretePointItem.Alarm, gid, commandOrigin);
                    discreteModbusData.Add(gid, discreteValue);
                }
            }

            ScadaPublication scadaPublication;

            if (topic == Topic.MEASUREMENT)
            {
                MultipleAnalogValueSCADAMessage analogValuesMessage = new MultipleAnalogValueSCADAMessage(analogModbusData);
                scadaPublication = new ScadaPublication(Topic.MEASUREMENT, analogValuesMessage);
            }
            else if (topic == Topic.SWITCH_STATUS)
            {
                MultipleDiscreteValueSCADAMessage discreteValuesMessage = new MultipleDiscreteValueSCADAMessage(discreteModbusData);
                scadaPublication = new ScadaPublication(Topic.SWITCH_STATUS, discreteValuesMessage);
            }
            else
            {
                string message = $"GetIntegrityUpdate => argument topic is neither Topic.MEASUREMENT nor Topic.SWITCH_STATUS.";
                Logger.LogError(message);
                throw new ArgumentException(message);
            }

            return(scadaPublication);
        }
コード例 #5
0
        public async Task MakeAnalogEntryToMeasurementCache(Dictionary <long, AnalogModbusData> data, bool permissionToPublishData)
        {
            string verboseMessage = $"{baseLogString} entering MakeAnalogEntryToMeasurementCache method.";

            Logger.LogVerbose(verboseMessage);

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

            Dictionary <long, AnalogModbusData> publicationData = new Dictionary <long, AnalogModbusData>();

            if (data == null)
            {
                string message = $"{baseLogString} MakeAnalogEntryToMeasurementCache => data is null.";
                Logger.LogError(message);
                throw new NullReferenceException(message);
            }

            if (MeasurementsCache == null)
            {
                string message = $"{baseLogString} MakeAnalogEntryToMeasurementCache => gidToPointItemMap is null.";
                Logger.LogError(message);
                throw new InternalSCADAServiceException(message);
            }

            foreach (long gid in data.Keys)
            {
                if (!await MeasurementsCache.ContainsKeyAsync(gid))
                {
                    Logger.LogDebug($"{baseLogString} MakeAnalogEntryToMeasurementCache => Adding entry to MeasurementCache. Gid: {gid:X16}, Value: {data[gid].Value}, Alarm: {data[gid].Alarm}, CommandOrigin: {data[gid].CommandOrigin}");

                    await MeasurementsCache.SetAsync(gid, data[gid]);

                    publicationData[gid] = data[gid];
                }
                else
                {
                    var result = await MeasurementsCache.TryGetValueAsync(gid);

                    if (!result.HasValue)
                    {
                        string errorMessage = $"{baseLogString} MakeAnalogEntryToMeasurementCache => Gid 0x{gid:X16} does not exist in '{ReliableDictionaryNames.MeasurementsCache}'.";
                        Logger.LogError(errorMessage);
                        throw new Exception(errorMessage);
                    }

                    if (!(result.Value is AnalogModbusData analogCacheItem))
                    {
                        string errorMessage = $"{baseLogString} MakeAnalogEntryToMeasurementCache => Entity with Gid 0x{gid:X16} is not of type: {typeof(AnalogModbusData)}.";
                        Logger.LogError(errorMessage);
                        throw new Exception(errorMessage);
                    }

                    if (analogCacheItem.Value != data[gid].Value || (analogCacheItem.CommandOrigin != data[gid].CommandOrigin && data[gid].CommandOrigin != CommandOriginType.UNKNOWN_ORIGIN))
                    {
                        Logger.LogDebug($"{baseLogString} MakeAnalogEntryToMeasurementCache => Value changed on element with Gid: 0x{analogCacheItem.MeasurementGid:X16}. Old value: {analogCacheItem.Value}, New value: {data[gid].Value}, Alarm: {data[gid].Alarm}, CommandOrigin: {data[gid].CommandOrigin}");

                        await MeasurementsCache.SetAsync(gid, data[gid]);

                        publicationData[gid] = data[gid];
                    }
                }
            }

            //if data is empty that means that there are no new values in the current acquisition cycle
            if (permissionToPublishData && publicationData.Count > 0)
            {
                ScadaMessage scadaMessage = new MultipleAnalogValueSCADAMessage(publicationData);
                await PublishScadaData(Topic.MEASUREMENT, scadaMessage);
            }
        }
コード例 #6
0
        public SCADAPublication GetIntegrityUpdateForSpecificTopic(Topic topic)
        {
            if (IntegrityUpdateService.scadaModel == null)
            {
                string message = $"GetIntegrityUpdate => SCADA model is null.";
                Logger.LogError(message);
                throw new InternalSCADAServiceException(message);
            }

            SCADAPublication scadaPublication;

            var currentScadaModel = IntegrityUpdateService.scadaModel.CurrentScadaModel;
            var commandValuesCache = IntegrityUpdateService.scadaModel.CommandedValuesCache;

            Dictionary<long, AnalogModbusData> analogModbusData = new Dictionary<long, AnalogModbusData>();
            Dictionary<long, DiscreteModbusData> discreteModbusData = new Dictionary<long, DiscreteModbusData>();

            foreach (long gid in currentScadaModel.Keys)
            {
                CommandOriginType commandOrigin = CommandOriginType.OTHER_COMMAND;

                if (topic == Topic.MEASUREMENT && currentScadaModel[gid] is AnalogSCADAModelPointItem analogPointItem)
                {
                    if (commandValuesCache.ContainsKey(gid) && commandValuesCache[gid].Value == analogPointItem.CurrentRawValue)
                    {
                        commandOrigin = commandValuesCache[gid].CommandOrigin;
                    }

                    AnalogModbusData analogValue = new AnalogModbusData(analogPointItem.CurrentEguValue, analogPointItem.Alarm, gid, commandOrigin);
                    analogModbusData.Add(gid, analogValue);
                }
                else if (topic == Topic.SWITCH_STATUS && currentScadaModel[gid] is DiscreteSCADAModelPointItem discretePointItem)
                {
                    if (commandValuesCache.ContainsKey(gid) && commandValuesCache[gid].Value == discretePointItem.CurrentValue)
                    {
                        commandOrigin = commandValuesCache[gid].CommandOrigin;
                    }

                    DiscreteModbusData discreteValue = new DiscreteModbusData(discretePointItem.CurrentValue, discretePointItem.Alarm, gid, commandOrigin);
                    discreteModbusData.Add(gid, discreteValue);
                }
            }

            if(topic == Topic.MEASUREMENT)
            {
                MultipleAnalogValueSCADAMessage analogValuesMessage = new MultipleAnalogValueSCADAMessage(analogModbusData);
                scadaPublication = new SCADAPublication(Topic.MEASUREMENT, analogValuesMessage);

            }
            else if(topic == Topic.SWITCH_STATUS)
            {
                MultipleDiscreteValueSCADAMessage discreteValuesMessage = new MultipleDiscreteValueSCADAMessage(discreteModbusData);
                scadaPublication = new SCADAPublication(Topic.SWITCH_STATUS, discreteValuesMessage);
            }
            else
            {
                string message = $"GetIntegrityUpdate => argument topic is neither Topic.MEASUREMENT nor Topic.SWITCH_STATUS.";
                Logger.LogError(message);
                throw new ArgumentException(message);
            }

            return scadaPublication;
        }