Esempio n. 1
0
        private async Task PublishScadaData(Topic topic, ScadaMessage scadaMessage)
        {
            string verboseMessage = $"{baseLogString} entering PublishScadaData method.";

            Logger.LogVerbose(verboseMessage);

            try
            {
                ScadaPublication   scadaPublication = new ScadaPublication(topic, scadaMessage);
                IPublisherContract publisherClient  = PublisherClient.CreateClient();
                await publisherClient.Publish(scadaPublication, MicroserviceNames.ScadaModelProviderService);

                Logger.LogInformation($"{baseLogString} PublishScadaData => SCADA service published data of topic: {scadaPublication.Topic}, publisher name: {MicroserviceNames.ScadaModelProviderService}");
            }
            catch (Exception e)
            {
                string errorMessage = $"{baseLogString} PublishScadaData => exception {e.Message}";
                Logger.LogError(errorMessage, e);
                throw e;
            }

            StringBuilder sb = new StringBuilder();

            sb.AppendLine($"{baseLogString} PublishScadaData => MeasurementCache content: ");

            var enumerableMeasurementCache = await MeasurementsCache.GetEnumerableDictionaryAsync();

            foreach (long gid in enumerableMeasurementCache.Keys)
            {
                ModbusData data = enumerableMeasurementCache[gid];

                if (data is AnalogModbusData analogModbusData)
                {
                    sb.AppendLine($"Analog data line: [gid] 0x{gid:X16}, [value] {analogModbusData.Value}, [alarm] {analogModbusData.Alarm}");
                }
                else if (data is DiscreteModbusData discreteModbusData)
                {
                    sb.AppendLine($"Discrete data line: [gid] 0x{gid:X16}, [value] {discreteModbusData.Value}, [alarm] {discreteModbusData.Alarm}");
                }
                else
                {
                    sb.AppendLine($"UNKNOWN data type: {data.GetType()}");
                }
            }

            Logger.LogDebug(sb.ToString());
        }
Esempio n. 2
0
        public async Task MakeDiscreteEntryToMeasurementCache(Dictionary <long, DiscreteModbusData> data, bool permissionToPublishData)
        {
            string verboseMessage = $"{baseLogString} entering MakeDiscreteEntryToMeasurementCache method.";

            Logger.LogVerbose(verboseMessage);

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

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

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

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

            foreach (long gid in data.Keys)
            {
                if (!await MeasurementsCache.ContainsKeyAsync(gid))
                {
                    Logger.LogDebug($"{baseLogString} MakeDiscreteEntryToMeasurementCache => 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} MakeDiscreteEntryToMeasurementCache => Gid 0x{gid:X16} does not exist in '{ReliableDictionaryNames.MeasurementsCache}'.";
                        Logger.LogError(errorMessage);
                        throw new Exception(errorMessage);
                    }

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

                    if (discreteCacheItem.Value != data[gid].Value || discreteCacheItem.CommandOrigin != data[gid].CommandOrigin)
                    {
                        Logger.LogDebug($"{baseLogString} MakeDiscreteEntryToMeasurementCache => Value changed on element with Gid: 0x{discreteCacheItem.MeasurementGid:X16}; Old value: {discreteCacheItem.Value}; new value: {data[gid].Value}");

                        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 MultipleDiscreteValueSCADAMessage(publicationData);
                await PublishScadaData(Topic.SWITCH_STATUS, scadaMessage);
            }
        }