SparkplugNet icon indicating copy to clipboard operation
SparkplugNet copied to clipboard

Application known metrics by topic class

Open jeff-pf opened this issue 1 year ago • 0 comments

After wrestling with this for the last couple of days - I came up with this solution. I have not found any issues yet. I think it might make sense for the library.

I added a class to handle known metrics by topic (i force birth messages to NDATA when added)

    /// <summary>
    /// A class to handle known metrics by topic.
    /// </summary>
    public class  KnownMetricsByNodeDevice
    {
        /// <summary>
        /// The all known metrics by topic (node/device).
        /// </summary>
        public ConcurrentDictionary<string, KnownMetricStorage> Dict = new();
        /// <summary>
        /// The all known metrics by topic (node/device).
        /// </summary>
        public List<T> AllMetrics()
        {
            List<T> m = new List<T>();

            return m;
        }
        /// <summary>
        /// get metrics for topic.
        /// </summary>
        public KnownMetricStorage GetTopicMetrics(string topic)
        {
            IEnumerable<T> metric = new List<T>();
            KnownMetricStorage metrics = new KnownMetricStorage(metric);
            this.Dict.TryGetValue(topic, out var tmpmetrics);

            if (tmpmetrics != null) { metrics = tmpmetrics; }

            return metrics;

        }
        /// <summary>
        /// add metric - should only be called from adding birth metrics.
        /// </summary>
        public void AddMetric(Metric metric)
        {
            if (metric.Topic is not null)
            {
                if (this.Dict.ContainsKey(metric.Topic.ToString()))
                {
                    metric.Topic = new SparkplugMessageTopic(SparkplugNamespace.VersionB, metric.Topic.GroupIdentifier, SparkplugMessageType.NodeData,metric.Topic.EdgeNodeIdentifier,null);
                    this.Dict[metric.Topic.ToString()].AddVersionB_BirthMetric(metric);
                }
                else
                {
                    List<T> metrics = new List<T>();
                    KnownMetricStorage ms = new KnownMetricStorage(metrics);
                    this.Dict[metric.Topic.ToString()] = ms;
                }
            }
            else
            {
                //add exception
            }
        }
        /// <summary>
        /// update metric.
        /// </summary>
        public void UpdateMetric(Metric metric)
        {
            if (metric.Topic is not null)
            {
                if (this.Dict.ContainsKey(metric.Topic.ToString()))
                {
                    this.Dict[metric.Topic.ToString()].UpdateMetric(metric);
                }
                else
                {
                    //add exception
                }
            }
            else
            {
                //add exception
            }
        }
    }

And then in the application add birth messages and update data messages (working just with nodes currently).

       while (!_stop)
       {
           lock (x)
           {
               if (birthList.Count > 0)
               {
                   foreach (var metric in birthList)
                   {
                       if (metric.Topic is not null)
                       {
                           application.AllKnownMetrics.AddMetric(metric);
                       }
                   }

                   birthList.Clear();
               }
           }

           if (nodeData.Count > 0)
           {
               lock (y)
               {
                   foreach (var metric in nodeData)
                   {
                       if (metric.Topic is not null)
                       {
                           application.AllKnownMetrics.UpdateMetric(metric);
                       }
                   }
               }

               nodeData.Clear();
           }

           Thread.Sleep(100);
       }

Looking for any feedback.

jeff-pf avatar Mar 28 '24 21:03 jeff-pf