This tutorial demonstrates how to use machine learning Edge AI with ML.NET (Tutorial) demonstrates using ML.NET 4.0 for real-time anomaly detection on sensor data using FrameworX Script TasksClasses.
Table of Contents maxLevel 2 minLevel 2 indent 10px exclude Steps style none
Scripts → Tutorial | Concept | How-to Guide | Reference
With these tags created: Pressure (Integer) and AnomalyBuffer (Text Array 9 position)
In Devices → Protocols, select the Value Simulator and click the "New Channel..." button.
In Devices → Points, create points to generate simulated data.
TagName | Node | Address | DataType | AccessType |
---|---|---|---|---|
Tag.Pressure | Node.ValueSimulator1Node1 | INTEGER:0,100,1 | Native | AccessType.Read |
For more information about the Value Simulator, see: Value Simulator Connector
Create tags:Tag.SensorValue
(Double) - Current readingTag.AnomalyScore
(Double) - Detection scoreTag.IsAnomaly
(Boolean) - Alert flagTag.Threshold
(Double) - Detection threshold (default: 0.3)Navigate to Scripts →
Classes
AnomalyDetector
csharp
// Simple spike detection using ML.NET
using Microsoft.ML;
using Microsoft.ML.Data;
// Static ML context (initialized once)
if (@Tag.MLContext == null)
{
@Tag.MLContext = new MLContext(seed: 0);
@Tag.DetectionEngine = InitializeDetector();
}
// Data class for ML model
public class SensorData
{
public float Value { get; set; }
}
public class AnomalyPrediction
{
[VectorType(3)]
public double[] Prediction { get; set; }
}
// Initialize detector (runs once)
private ITransformer InitializeDetector()
{
var dataView = @Tag.MLContext.Data.LoadFromEnumerable(new List<SensorData>());
var pipeline = @Tag.MLContext.Transforms
.DetectSpikeBySsa(
outputColumnName: "Prediction",
inputColumnName: "Value",
confidence: 95,
pvalueHistoryLength: 30,
trainingWindowSize: 90,
seasonalityWindowSize: 30);
return pipeline.Fit(dataView);
}
// Detection logic (runs every second)
var currentValue = (float)@Tag.SensorValue;
var data = new SensorData { Value = currentValue };
var prediction = @Tag.DetectionEngine.Transform(
@Tag.MLContext.Data.LoadFromEnumerable(new[] { data }));
var result = @Tag.MLContext.Data
.CreateEnumerable<AnomalyPrediction>(prediction, false)
.First();
// Update tags with results
@Tag.AnomalyScore = result.Prediction[0]; // Spike score
@Tag.IsAnomaly = result.Prediction[0] > @Tag.Threshold;
// Log anomalies
if (@Tag.IsAnomaly)
{
@Alarm.GlobalSettings.AuditTrail.AddCustomMessage(
$"Anomaly detected: Sensor={currentValue:F2}, Score={result.Prediction[0]:F3}");
}
SensorSimulator
csharp
// Simulate normal sensor data with occasional spikes
Random rand = new Random();
double baseValue = 50.0;
double noise = rand.NextDouble() * 5 - 2.5;
// Inject anomaly occasionally (5% chance)
if (rand.NextDouble() < 0.05)
{
@Tag.SensorValue = baseValue + (rand.NextDouble() * 30 + 20); // Spike
}
else
{
@Tag.SensorValue = baseValue + noise; // Normal variation
}
Click the "Create a New Class" button
In "Import code from Library:", select AnomalyML
Open the script and uncomment the line that returns the detection to the AnomalyBuffer tag in Check() method.
This expression will check for anomalies each time the tag value changes.
Go to Scripts → Expressions
Create the following expression:
ObjectName | Expression | Execution |
---|---|---|
Script.Class.AnomalyML.Check(<DesiredTag>) | OnChange |
Where:
<DesiredTag> is the tag you want to monitor for anomalies
Example:
ObjectName | Expression | Execution |
---|---|---|
Script.Class.AnomalyML.Check(Tag.Pressure) | OnChange |
Go in Runtime → “Run Startup”
Wait a couple minutes to have some data in the model.
Open the PropertyWatch
See the values in the AnomalyBuffer, to see the predictions.
Page Tree | ||||
---|---|---|---|---|
|