SparkplugNet
SparkplugNet copied to clipboard
Application known metrics by topic class
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.