diff --git a/README.md b/README.md index 6effc52c..6099943b 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ # DBM Dynamic Bandwidth Monitor\ Leak detection method implemented in a real-time data historian\ -Copyright (C) 2014-2024 J.H. Fitié, Vitens N.V. +Copyright (C) 2014-2025 J.H. Fitié, Vitens N.V. ## Description Water company Vitens has created a demonstration site called the Vitens Innovation Playground (VIP), in which new technologies and methodologies are developed, tested, and demonstrated. The projects conducted in the demonstration site can be categorized into one of four themes: energy optimization, real-time leak detection, online water quality monitoring, and customer interaction. In the real-time leak detection theme, a method for leak detection based on statistical demand forecasting was developed. diff --git a/src/DBMDataRef/DBMDataRef.vb b/src/DBMDataRef/DBMDataRef.vb index 19c01d79..d0751d91 100644 --- a/src/DBMDataRef/DBMDataRef.vb +++ b/src/DBMDataRef/DBMDataRef.vb @@ -1,6 +1,6 @@ ' Dynamic Bandwidth Monitor ' Leak detection method implemented in a real-time data historian -' Copyright (C) 2014-2024 J.H. Fitié, Vitens N.V. +' Copyright (C) 2014-2025 J.H. Fitié, Vitens N.V. ' ' This file is part of DBM. ' @@ -25,6 +25,7 @@ Imports System.DateTime Imports System.Double Imports System.Math Imports System.Runtime.InteropServices +Imports System.Threading Imports OSIsoft.AF.Asset Imports OSIsoft.AF.Asset.AFAttributeTrait Imports OSIsoft.AF.Data @@ -83,13 +84,15 @@ Namespace Vitens.DynamicBandwidthMonitor ' process output. + Const MaxAnnotationsSize As Integer = 1000 ' Maximum number of annotations Const StaleDataMinutes As Integer = 10 ' Minutes until snapshot is stale Const CategoryNoCorrelation As String = "NoCorrelation" Const pValueLoHi As Double = 0.95 ' Confidence interval for Lo and Hi Const pValueMinMax As Double = 0.9999 ' CI for Minimum and Maximum - Private _annotations As New Dictionary(Of AFTime, Object) + Private _lock As New Object ' Object for exclusive lock on critical section. + Private _annotations As New SortedDictionary(Of AFTime, Object) Private Shared _dbm As New DBM(New DBMLoggerAFTrace) @@ -279,20 +282,31 @@ Namespace Vitens.DynamicBandwidthMonitor If value IsNot Nothing Then ' Key - _annotations.Remove(value.Timestamp) ' Remove existing - value.Annotated = False + Monitor.Enter(_lock) ' Block + Try - If annotation IsNot Nothing Then ' Value + _annotations.Remove(value.Timestamp) ' Remove existing + value.Annotated = False - DBM.Logger.LogDebug( - "value.Timestamp " & - value.Timestamp.LocalTime.ToString("s") & "; " & - "annotation " & DirectCast(annotation, String), Attribute.GetPath) + If annotation IsNot Nothing Then ' Value - _annotations.Add(value.Timestamp, annotation) ' Add - value.Annotated = True + While _annotations.Count >= MaxAnnotationsSize ' Limit size + _annotations.Remove(_annotations.Keys.First()) ' Remove oldest + End While - End If + DBM.Logger.LogDebug( + "value.Timestamp " & + value.Timestamp.LocalTime.ToString("s") & "; " & + "annotation " & DirectCast(annotation, String), Attribute.GetPath) + + _annotations.Add(value.Timestamp, annotation) ' Add + value.Annotated = True + + End If + + Finally + Monitor.Exit(_lock) ' Unblock + End Try End If @@ -308,12 +322,22 @@ Namespace Vitens.DynamicBandwidthMonitor ' attributes" GetAnnotation = Nothing - If value IsNot Nothing AndAlso - _annotations.TryGetValue(value.Timestamp, GetAnnotation) Then - _annotations.Remove(value.Timestamp) ' Remove after get - Return GetAnnotation - Else - Return String.Empty ' Default + If value IsNot Nothing Then ' Key + + Monitor.Enter(_lock) ' Block + Try + + If _annotations.TryGetValue(value.Timestamp, GetAnnotation) Then + _annotations.Remove(value.Timestamp) ' Remove after get + Return GetAnnotation + Else + Return String.Empty ' Default + End If + + Finally + Monitor.Exit(_lock) ' Unblock + End Try + End If End Function diff --git a/src/dbm/DBMManifest.vb b/src/dbm/DBMManifest.vb index 25bb2939..e0223bae 100644 --- a/src/dbm/DBMManifest.vb +++ b/src/dbm/DBMManifest.vb @@ -1,6 +1,6 @@ ' Dynamic Bandwidth Monitor ' Leak detection method implemented in a real-time data historian -' Copyright (C) 2014-2024 J.H. Fitié, Vitens N.V. +' Copyright (C) 2014-2025 J.H. Fitié, Vitens N.V. ' ' This file is part of DBM. ' @@ -30,6 +30,6 @@ "Leak detection method implemented in a real-time data historian")> + "Copyright (C) 2014-2025 J.H. Fitié, Vitens N.V.")>