node-red-contrib-condition-monitoring 0.3.3
Node-RED Nodes for anomaly detection, predictive maintenance, and time series analysis
node-red-contrib-condition-monitoring
A comprehensive Node-RED module for anomaly detection, predictive maintenance, and time series analysis.
Table of Contents
- Project Status: v0.3.2 Beta
- Important Disclaimer
- Background & Industry Context
- Features
- Installation
- Quick Start
- Available Nodes (15 Nodes)
- Pretrained Models (catalog)
- Which Node Should I Use?
- Usage Examples
- Node Configuration Examples
- Dynamic Configuration (msg.config)
- Docker Setup
- Dependencies
- Performance Features
- Documentation
- Contributing
- License
- Roadmap
Project Status: v0.3.2 Beta
Per-device signal buffers, LLM Analyzer, Vision Pipeline & Data-Source Simulators
- 15 Nodes - analysis, ML inference, vision pipeline, LLM analysis, and data-source simulators
- ISO 10816-3 Integration - Vibration severity assessment with zones A-D
- Butterworth Filter - 2nd order IIR filter with zero-phase filtering (filtfilt)
- Hysteresis (Anti-Flicker) - Prevents rapid alarm on/off switching
- Dynamic Sensor Weighting - Auto-adjusts weights based on sensor reliability
- Robust RUL Calculation - Theil-Sen estimator, median filter, moving average smoothing
- High-Performance FFT - Radix-4 Cooley-Tukey algorithm via fft.js
- State Persistence - Optional context-based state saving across restarts
- Comprehensive Testing - 405 unit tests with Jest framework
Important Disclaimer
This software is provided for condition monitoring and predictive maintenance purposes.
- NOT a replacement for safety-critical systems
- NOT suitable as the sole means of safety decision-making
- Should be used as an additional monitoring layer
- Always validate results with domain experts
- Follow proper safety protocols and regulations for your industry
Use at your own risk. See LICENSE file for full legal terms.
Background & Industry Context
Predictive maintenance works because machines don't fail randomly — they fail predictably, given the right signals. The industry converges on a small set of condition-monitoring techniques and a common pipeline shape, both of which this module implements as composable Node-RED nodes.
Common monitoring techniques → nodes in this module:
| Industry technique | Detects | Node(s) here |
|---|---|---|
| Vibration analysis (the dominant technique by market share) | bearing wear, misalignment, imbalance, looseness | signal-analyzer (FFT, RMS, kurtosis, crest factor, envelope), ISO 10816-3 zones |
| Thermal / process trending | overheating, degradation drift | trend-predictor, anomaly-detector |
| Anomaly detection on a learned "normal signature" | deviations preceding failure | anomaly-detector, isolation-forest-anomaly, pca-anomaly |
| Multi-signal fusion + asset context | a "digital profile" per asset | multi-value-processor, condition-monitoring-source, health-index |
| Root-cause + recommended action in the alert | actionable alerts, not just flags | llm-analyzer |
| Remaining Useful Life estimation | time-to-failure with confidence bounds | trend-predictor (RUL mode) |
The typical pipeline — sensors → fusion → anomaly/trend → health score → actionable alert — maps directly onto the architecture below, and runs on the edge (inside Node-RED) rather than requiring a cloud round-trip.
On the published benchmarks. Vendor case studies report figures such as ~70% of failures predicted ≥24h ahead, 25–35% less unplanned downtime, and 80–97% prediction accuracy.[^pdm1][^pdm2] These are third-party industry results under their own conditions — not benchmarks of this module. Treat them as motivation for the approach, and validate any deployment against your own data and domain experts (see the disclaimer above).
[^pdm1]: ThinkAI, Cutting Machine Downtime with Predictive Maintenance and AI — https://thinkaicorp.com/case-study-cutting-machine-downtime-with-predictive-maintenance-and-ai/ [^pdm2]: iFactory, Predictive Maintenance 2026: AI vs. Factory Downtime — https://ifactoryapp.com/blog/predictive-maintenance-2026-ai-factory-downtime
Features
- 15 Powerful Nodes - Complete condition monitoring + vision + LLM toolkit
- 10 Anomaly Detection Methods - Z-Score, IQR, Moving Average, Threshold, Percentile, EMA, CUSUM, Isolation Forest, PCA, Mahalanobis
- Signal Analysis - High-performance FFT (Radix-4), Vibration Features (RMS, Crest Factor, Kurtosis), Peak Detection, Envelope Analysis, Cepstrum, Autocorrelation (ACF), Sample Entropy, Periodicity Detection
- Correlation Analysis - Pearson, Spearman, Cross-Correlation with time lag detection
- Gearbox Diagnostics - Cepstrum analysis for gear mesh faults
- Reliability Analysis - Weibull distribution, B-life, MTTF, RUL
- Trend Prediction - Linear Regression, Exponential Smoothing, Rate of Change
- Multi-Value Processing - Split, Analyze, Correlate, Aggregate multiple sensors
- ML Inference - TensorFlow.js, ONNX, Keras, scikit-learn, TFLite, Google Coral (with persistent Python bridge)
- State Persistence - Optional buffer/statistics persistence across restarts
Installation
Prerequisites: Node.js >= 18, Node-RED >= 2.0.0
npm install node-red-contrib-condition-monitoring
Or install directly from Node-RED:
- Menu → Manage palette
- Install tab
- Search for
node-red-contrib-condition-monitoring - Click install
Quick Start
With Docker Compose (Recommended)
# Start Node-RED with the module
docker-compose up -d
# Access at http://localhost:1880
Import Example Flows
- Open Node-RED:
http://localhost:1880 - Menu → Import → Examples
- Select one of the example flows
Available Nodes (15 Nodes)
Nodes are grouped in the palette under five Condition Monitoring categories:
Condition Monitoring Stats (analysis), Condition Monitoring ML
(ml-inference, training-data-collector), Condition Monitoring Vision
(image-preprocess, vision-annotator), Condition Monitoring LLM (llm-analyzer)
and Condition Monitoring Demo (condition-monitoring-source, image-source, json-source).
Data sources for testing: condition-monitoring-source simulates realistic
sensor data — trended KPIs (vibration RMS, temperature, current, pressure with
degradation, faults, ISO thresholds, RUL) and, in waveform mode, a raw
vibration time-signal so the signal-analyzer (FFT/envelope/kurtosis) can be
driven too. image-source is its visual counterpart: it generates synthetic
inspection images with configurable defects (spot/scratch) + a ground-truth
mask to drive the vision pipeline. json-source is a generic structured-data
simulator — you define arbitrary fields (mean/noise/trend, optional anomaly
injection) and it emits JSON records to drive the object/record nodes
(multi-value-processor, health-index, pca-anomaly, training-data-collector,
llm-analyzer record mode).
Architecture at a glance
How the nodes fit together — data sources (or real inputs) feed the processing nodes, which emit results to dashboards/alarms/storage:
flowchart LR
subgraph SRC["🔌 Sources"]
EXT["Real inputs<br/>MQTT · OPC-UA · files"]:::src
CMS["CM Sensor Source"]:::src
IMS["CM Image Source"]:::src
JSS["CM JSON Source"]:::src
end
subgraph STATS["📊 Statistical analysis"]
AD["Anomaly Detector"]:::stats
IF["Isolation Forest"]:::stats
PCA["PCA Anomaly"]:::stats
MVP["Multi-Value Processor"]:::stats
SA["Signal Analyzer"]:::stats
TP["Trend Predictor"]:::stats
HI["Health Index"]:::stats
end
subgraph MLG["🤖 Machine learning"]
MLI["ML Inference"]:::ml
TDC["Training Data Collector"]:::ml
end
subgraph VIS["🖼️ Vision pipeline"]
IPP["Image Preprocess"]:::vis
VAN["Vision Annotator"]:::vis
end
subgraph LLMG["💬 LLM"]
LLA["LLM Analyzer"]:::llm
end
OUT["Dashboard · Alarm · Database"]:::sink
EXT --> AD & IF & SA & MVP & TDC
CMS -->|scalar| AD & IF & TP & HI
CMS -->|waveform| SA
JSS --> MVP & PCA & HI
IMS --> IPP --> MLI --> VAN --> OUT
AD & IF & SA & TP & HI & PCA --> OUT
MVP --> AD
MLI -->|predictions| OUT
AD -->|anomaly context| LLA --> OUT
TDC -.->|labelled data| MLI
classDef src fill:#9482f1,color:#fff,stroke:#6b5bd6;
classDef stats fill:#42a5f5,color:#fff,stroke:#1e88e5;
classDef ml fill:#ffa726,color:#3e2723,stroke:#fb8c00;
classDef vis fill:#ec407a,color:#fff,stroke:#d81b60;
classDef llm fill:#66bb6a,color:#fff,stroke:#43a047;
classDef sink fill:#26a69a,color:#fff,stroke:#1c7e74;
The vision path is its own short pipeline:
flowchart LR
IMG["Image<br/>(CM Image Source or PNG/JPEG)"]:::src --> P["Image Preprocess<br/>decode · resize · normalize → tensor"]:::vis
P --> M["ML Inference<br/>ONNX / TFJS model"]:::ml
M --> A["Vision Annotator<br/>boxes · masks · keypoints · heatmap…"]:::vis
A --> V["Annotated PNG<br/>(editor preview / dashboard)"]:::sink
classDef src fill:#9482f1,color:#fff,stroke:#6b5bd6;
classDef vis fill:#ec407a,color:#fff,stroke:#d81b60;
classDef ml fill:#ffa726,color:#3e2723,stroke:#fb8c00;
classDef sink fill:#26a69a,color:#fff,stroke:#1c7e74;
Core Analysis Nodes
1. Anomaly Detector
7 detection methods in one node:
| Method | Best For |
|---|---|
| Z-Score | Normal distributions, general purpose |
| IQR | Robust to outliers, skewed data |
| Threshold | Fixed min/max limits |
| Percentile | Dynamic bounds based on data distribution |
| EMA | Recent changes, adaptive baseline |
| CUSUM | Drift detection, gradual shifts |
| Moving Average | Smoothed baseline comparison |
Hysteresis (Anti-Flicker):
- Prevents rapid alarm on/off switching near thresholds
- Configurable consecutive samples before triggering
- Deadband percentage for exiting anomaly state
Multi-Sensor JSON Input:
- Accepts JSON objects with multiple sensors:
{ "temp": 65.2, "pressure": 4.5 } - Maintains separate buffers and hysteresis states per sensor
- Outputs combined result with per-sensor analysis
Example:
[MQTT Sensor] → [Anomaly Detector (Z-Score)] → [Normal] → [Dashboard]
→ [Anomaly] → [Alarm]
2. Isolation Forest
ML-based anomaly detection with online learning:
- Unsupervised learning - no training labels required
- Detects complex, multivariate anomalies
- 3 learning modes:
- Batch - Retrain when buffer full
- Incremental - Periodic retraining (configurable interval)
- Adaptive - Auto-adjust threshold based on feedback
- Configurable number of trees and samples per tree
3. Multi-Value Processor
4 modes for multi-sensor data:
| Mode | Function |
|---|---|
| Split | Extract individual values from arrays/objects |
| Analyze | Anomaly detection per value (Z-Score, IQR, Threshold, Mahalanobis) |
| Correlate | Pearson, Spearman, or Cross-Correlation between two sensors |
| Aggregate | Reduce to single value (Mean, Median, Min, Max, Sum, Range, StdDev) |
Mahalanobis Distance: Detects multivariate anomalies considering correlations between sensors.
Cross-Correlation: Finds time lag between sensors - detects propagation delays (e.g., temperature wave through pipe).
Example:
[Sensors] → [Multi-Value (Split)] → [Anomaly Detector] → ...
[Sensors] → [Multi-Value (Aggregate)] → Mean value for dashboard
4. Signal Analyzer
5 modes for signal analysis:
| Mode | Output |
|---|---|
| FFT | Frequency peaks, spectral features |
| Vibration | RMS, Crest Factor, Kurtosis, Skewness, Health Score, ISO 10816-3 assessment |
| Peaks | Local maxima/minima detection |
| Envelope | Bearing fault detection (BPFO, BPFI, BSF, FTF) with Butterworth filter |
| Cepstrum | Gearbox fault detection (GMF, sidebands) |
ISO 10816-3 Vibration Severity:
- Machine classes I-IV (small to large machines)
- Zones A-D with severity levels and recommendations
- Automatic alarm/warning thresholds
Butterworth Filter:
- 2nd order IIR filter for envelope analysis
- Zero-phase filtering (filtfilt) - no phase distortion
- Automatic fallback for edge cases
Multiple devices per node: set Group By to a message property
(typically topic, nested paths like payload.deviceId work too) and the node
keeps an independent buffer per device, emitting one result per device
tagged with msg.group. Max Groups (default 50) caps memory by dropping the
least recently used buffer. Left empty, the node keeps a single shared buffer.
pump-01/vibration ─┐
pump-02/vibration ─┼─→ [Signal Analyzer] ─→ one result per device
pump-03/vibration ─┘ groupBy: "topic"
Example:
[Vibration Sensor] → [Signal Analyzer (Vibration)] → RMS, ISO 10816 Zone
→ [Signal Analyzer (FFT)] → Frequency Peaks
→ [Signal Analyzer (Envelope)] → Bearing faults
5. Trend Predictor
3 modes for trend analysis:
| Mode | Output |
|---|---|
| Prediction | Future values, trend direction |
| RUL | Remaining Useful Life with confidence intervals |
| Rate of Change | First/second derivative, acceleration |
RUL Features:
- Configurable failure and warning thresholds
- Multiple time units (hours, minutes, days, cycles)
- Confidence intervals for predictions
- Status: healthy/warning/critical/failed
- Degradation models: Linear, Exponential, Weibull (reliability-based)
- Robust calculation: Theil-Sen estimator, median filter, moving average smoothing
Multi-Sensor JSON Input:
- Accepts JSON objects with multiple sensors:
{ "temp": 65.2, "vibration": 2.5 } - Calculates trends/RUL for each sensor independently
- Tracks threshold exceedance per sensor
Weibull Analysis:
- Automatic Weibull parameter estimation (β, η)
- B-Life calculation (B1, B5, B10, B50) - time when X% have failed
- Failure mode classification (infant_mortality, useful_life, wear_out, rapid_wear_out)
- MTTF calculation
Example:
[Temperature] → [Trend Predictor (RUL)] → "RUL: 48.5h (95% confidence)"
6. Health Index
Multi-sensor health aggregation:
- Weighted combination of sensors
- 0-100% health score
- Configurable aggregation methods (Weighted, Dynamic, Minimum, Average, Geometric)
- Dynamic weighting - Auto-adjusts weights based on sensor reliability
- Visual threshold configuration with slider-based UI
- Configurable status levels (healthy, warning, degraded, critical)
- Automatic worst sensor identification with reliability metrics
7. ML Inference
Machine Learning model inference with multiple runtime options:
JavaScript Runtimes (npm install)
Work immediately after installation - no additional setup:
- ONNX (.onnx) - PyTorch, TensorFlow, scikit-learn models
- TensorFlow.js (model.json + .bin) - Keras, TensorFlow models
Python Runtimes (Docker/Python required)
Require Python environment with ML libraries:
- TFLite (.tflite) - Edge/mobile optimized models
- Keras (.keras, .h5) - Native Keras models
- scikit-learn (.pkl, .joblib) - Classic ML (Random Forest, SVM, etc.)
Hardware Accelerated
- Google Coral / Edge TPU - 10-100x faster inference
Tip: Use ONNX format for best compatibility across frameworks. The node automatically detects available runtimes and shows warnings for Python-dependent formats.
8. PCA Anomaly Detection
Principal Component Analysis for multi-sensor anomaly detection:
- Reduces high-dimensional data to principal components
- Detects anomalies using Hotelling's T² and SPE statistics
- Auto-selects components based on explained variance threshold
- Contribution analysis - identifies which sensor caused the anomaly
| Method | Use Case |
|---|---|
| T² | Variations within normal operating space |
| SPE | New patterns not seen during training |
| Combined | Both T² and SPE (recommended) |
9. Training Data Collector
Collects sensor data for ML model training:
| Feature | Description |
|---|---|
| 3 Collection Modes | Batch, Streaming (JSONL), Time-Series Windows |
| Multiple Export Formats | CSV, JSONL, JSON with metadata |
| Auto-Compression | .gz compression for large datasets (>10k samples) |
| Train/Val/Test Split | Automatic dataset splitting with configurable ratios |
| Label Modes | Manual, from message, RUL countdown, unlabeled |
| S3 Upload | Direct upload to AWS S3 buckets |
| Data Validation | Rejects NaN/Infinity, tracks statistics |
Use Cases:
- Collect labeled training data from live sensors
- Create datasets for the training notebooks
- Export time-series windows for LSTM/Transformer training
- Automatic cloud backup to S3
Control Actions:
msg.action = "export"; // Export current buffer
msg.action = "clear"; // Clear buffer
msg.action = "stats"; // Get collection statistics
msg.action = "pause"; // Pause collection
msg.action = "resume"; // Resume collection
msg.action = "resetRul"; // Reset RUL counter
Example:
[Sensors] → [Multi-Value Processor] → [Training Data Collector] → [S3/File]
↑
[Inject: action="export"]
10. LLM Analyzer
Buffers sensor samples and asks an LLM to analyse them in plain language or structured JSON:
| Feature | Description |
|---|---|
| 5 Providers | Anthropic (Claude), OpenAI (GPT), Google (Gemini), Ollama (local), OpenAI-compatible (Groq, Together, OpenRouter, DeepSeek, Mistral, vLLM, LMStudio …) |
| 3 Trigger Modes | Batch (fire when N samples buffered), Manual (msg.flush=true), Interval (every X ms) |
| 2 Input Modes | Scalar (single sensor stream) or Record (multi-sensor objects with auto-detected columns) |
| 2 Output Modes | Text or structured JSON with example-based schema + optional dot-path field extraction |
| Cost Tracking | Per-call msg.usage plus lifetime msg.totalUsage and live status indicator |
| Buffer Caps | Hard ring-buffer size + separate cap on samples sent to the prompt |
| Persistence | Optional buffer + counters survive Node-RED redeploys |
| Concurrency-safe | Triggers during in-flight calls are queued, never silently dropped |
Use Cases:
- Operator-readable batch summaries ("the last 50 readings look unusual because ...")
- Structured anomaly scoring (LLM returns
{severity, score, summary}→ switch-node routes alarms) - Cross-sensor correlation in record mode ("temp spiked AND pressure dropped — typical leak pattern")
- Edge-deployable with Ollama for air-gapped sites
Configuration:
// Inputs
msg.payload // number / number[] (scalar) or object / object[] (record)
msg.flush // true → fire now (manual mode)
msg.prompt // per-message override of user prompt template
msg.systemPrompt, msg.model, msg.apiUrl // per-message overrides
// Outputs
msg.payload // text response, parsed JSON object, or extracted field
msg.usage // { inputTokens, outputTokens } from this call
msg.totalUsage // lifetime running totals + callCount
msg.samples // exact batch sent — useful for archiving / replay
msg.json // (JSON mode) full parsed object
msg.rawResponse // (JSON mode) raw LLM text
Example:
[Sensor] → [Anomaly Detector] → [LLM Analyzer (json)] → [Switch on score≥0.7] → [Alert]
11. Condition Monitoring Data Source
Synthetic sensor stream of a degrading machine — for demos, testing and predictive-maintenance prototyping (palette label CM Sensor Source):
| Feature | Description |
|---|---|
| Asset types | Pump, motor, fan, gearbox (with configurable RPM → shaft frequency) |
| Output modes | object (full JSON), value (vibration RMS), or waveform (raw vibration time-signal array + msg.samplingRate, for the Signal Analyzer) |
| Degradation model | Health (0–100%) decays by degRate × loadFactor × (1 + Σ fault severity) |
| Derived sensors | Vibration RMS (mm/s), temperature (°C), current (A), pressure (bar) |
| Fault injection | Imbalance (1×), misalignment (2×), bearing (~3.5×), looseness (0.5×) with characteristic frequencies |
| Thresholds + RUL | ISO 10816-style warn/alarm levels and an estimated remaining useful life |
| Streaming control | Auto-start on deploy, interval timer, or manual inject; start/stop/reset commands |
| Runtime overrides | msg.config adjusts load, faults, noise, thresholds and interval live |
| Reproducible | Optional integer seed for deterministic streams |
Configuration:
// Control inputs
msg.payload = "start" | "stop" | "reset"; // or msg.start / msg.stop / msg.reset = true
msg.config = { // live reconfiguration
load: 90, degRate: 0.2, noise: 0.1,
faults: { bearing: 0.85, imbalance: 0.2 },
warnThreshold: 4.5, alarmThreshold: 7.1, intervalMs: 500
};
msg.emit = true; // with msg.config: also emit a sample immediately
// Output (object mode)
msg.payload = { asset, health, status, rul, sensors:{...}, faults:[...], thresholds:{...} };
msg.status // "normal" | "warning" | "alarm"
msg.health // 0–100
msg.alarm // boolean
Example:
[Inject "start"] → [CM Data Source] → [Health Index / Signal Analyzer / Anomaly Detector]
Vision Nodes (for image models)
12. Image Preprocess
Turns a real image (PNG/JPEG Buffer) into a normalized tensor for ml-inference — pure-JS (pngjs + jpeg-js, no native deps).
| Feature | Description |
|---|---|
| Decode | PNG and JPEG buffers |
| Resize | bilinear / nearest to a target W×H |
| Normalize | 0-1, 0-255, -1..1, imagenet (mean/std), or custom mean/std |
| Layout | NCHW (ONNX) or NHWC (TFJS); channel order RGB/BGR; optional grayscale |
| Keeps the image | sets msg.image (resized PNG) so vision-annotator can draw on the real photo |
Output: msg.payload = flat tensor, msg.tensorShape = e.g. [1,3,224,224], msg.preprocess = metadata. Set the ml-inference Input shape to match.
13. Vision Annotator
Renders an image-model's output as an annotated image (PNG Buffer on msg.payload) plus structured msg.annotations. 9 modes:
| Mode | Annotation |
|---|---|
boxes |
bounding boxes (xyxy or yolo + NMS) |
obb |
oriented / rotated boxes |
segmentation |
semantic class-mask overlay (+ area fractions) |
instances |
per-object masks + bbox + area |
polygons |
contour outlines (+ area & perimeter) |
keypoints |
keypoints + skeleton (pose) |
heatmap |
scalar field → jet/gray colormap (depth / CAM / density) |
anomaly |
anomaly score field → heatmap + thresholded regions + metrics |
classification |
label banner + status dot (softmax confidence) |
With Editor preview on (default), the annotated image is drawn live as a thumbnail under the node on the canvas — double-click it to enlarge. Display it elsewhere with a dashboard ui_image, or via msg.payload.
A ready-to-run, self-validating example flow that exercises every node and every
annotation mode (with both synthetic and real pretrained models — SqueezeNet,
YOLOv10, YOLOv8-pose, Depth-Anything) lives in examples/test-suite.json. Fetch
the models first with bash tools/fetch-models.sh, then GET /test runs all
checks and GET /gallery shows every annotated image.
Data Source Nodes (Demo)
Simulate input so any node can be tested without real hardware. (The CM Sensor Source, node #11 above, is the third one — it also has a waveform output mode that emits a raw vibration time-signal for the Signal Analyzer.)
14. CM Image Source
Synthetic inspection-image generator (image-source) — the visual counterpart.
Produces a textured surface with configurable defects (spot / scratch / multiple),
severity, noise and optional degrade over time, plus a ground-truth mask
(msg.mask) and defect list. Drives the whole vision pipeline.
15. CM JSON Source
Generic structured-data simulator (json-source). Define arbitrary fields
({ "temperature": { "mean": 60, "noise": 2, "trend": 0.05 }, "asset": "pump-01" });
each numeric field is mean + trend·count + gaussian(noise), constants pass through.
Optional anomaly injection. Drives the object/record nodes (multi-value-processor,
health-index, pca-anomaly, training-data-collector, llm-analyzer record mode).
Pretrained Models (catalog)
A curated catalog of pretrained models for common use cases ships with the
package (nodes/model-catalog.json). In the ML Inference node, pick one from
the Pretrained dropdown — it auto-fills the source, URL, SHA-256, type and
input shape, and shows the matching preprocessing + annotation. The Insert full
pipeline button drops a ready-wired image-preprocess → ml-inference → vision-annotator chain.
| Use case | Model | Source | License |
|---|---|---|---|
| Image classification (ImageNet) | SqueezeNet 1.1 | ONNX Model Zoo | BSD-3-Clause |
| Object detection (COCO) | YOLOv10n (NMS-free) | onnx-community | AGPL-3.0 |
| Human pose / keypoints | YOLOv8n-pose | Xenova | AGPL-3.0 |
| Monocular depth | Depth-Anything-v2-small | onnx-community | Apache-2.0 |
| Surface defect segmentation | bundled (trained in-repo) | this package | Apache-2.0 |
| Vibration fault classification | bundled (trained in-repo) | this package | Apache-2.0 |
- Fetched on demand, not redistributed:
urlmodels download on deploy intoml-models/cacheand are verified against the catalog's SHA-256. Mind each model's license (YOLO is AGPL-3.0). Only the small in-repo models are bundled. - Pre-download everything for offline use with
bash tools/fetch-models.sh.
Which Node Should I Use?
Quick Decision Tree
Start from your data and goal, follow to the node:
flowchart TD
Q{"What is your data?"}
Q -->|"single numeric stream"| G1{"goal?"}
G1 -->|"fixed min/max limits"| AD1["Anomaly Detector · threshold"]
G1 -->|"statistical outliers"| AD2["Anomaly Detector · z-score / IQR"]
G1 -->|"gradual drift"| AD3["Anomaly Detector · CUSUM"]
G1 -->|"forecast / remaining useful life"| TP["Trend Predictor"]
Q -->|"many sensors at once"| G2{"goal?"}
G2 -->|"split / aggregate"| MVP["Multi-Value Processor"]
G2 -->|"correlated / multivariate"| PCA["PCA Anomaly · Mahalanobis"]
G2 -->|"single 0–100 score"| HI["Health Index"]
G2 -->|"complex, unsupervised"| IF["Isolation Forest"]
Q -->|"raw vibration waveform"| SA["Signal Analyzer<br/>FFT · vibration · envelope (bearings) · cepstrum (gears)"]
Q -->|"image / photo"| VIS["Image Preprocess → ML Inference → Vision Annotator"]
Q -->|"need a trained model"| ML["ML Inference (ONNX / TFJS)"]
Q -->|"want a text summary"| LLM["LLM Analyzer"]
Q -->|"build a training dataset"| TDC["Training Data Collector"]
Tip: the Demo sources (
CM Sensor Source,CM Image Source,CM JSON Source) let you drive any of these without real hardware.
Usage Examples
Simple Temperature Monitoring
[MQTT] → [Anomaly Detector] → [Normal] → [Dashboard]
→ [Anomaly] → [Email Alert]
Motor Predictive Maintenance
[Sensors] → [Multi-Value (Split)] → [Anomaly Detector]
→ [Trend Predictor] → RUL Display
→ [Signal Analyzer (FFT)] → Frequency Chart
→ [Health Index] → Dashboard
Bearing Vibration Analysis
[Vibration] → [Signal Analyzer (Vibration)] → Features
→ [Signal Analyzer (FFT)] → Frequencies
→ [Signal Analyzer (Envelope)] → Bearing Faults
→ [Anomaly Detector (IQR)] → Outliers
ML Anomaly Detection
[Features] → [ML Inference (Autoencoder)] → Reconstruction Error → [Anomaly Detector (Threshold)]
Node Configuration Examples
Anomaly Detector (Z-Score)
// Input
msg.payload = 42.5;
// Output
{
"payload": 42.5,
"isAnomaly": true,
"severity": "critical",
"method": "zscore",
"zScore": 3.2,
"mean": 35.0,
"stdDev": 2.3,
"threshold": 3.0,
"warningThreshold": 2.0,
"bufferSize": 100,
"windowSize": 100
}
Signal Analyzer (FFT)
// Input (continuous stream)
msg.payload = 0.45;
// Output
{
"payload": 0.45,
"peaks": [
{ "frequency": 30, "magnitude": 0.5 },
{ "frequency": 157, "magnitude": 0.3 }
],
"dominantFrequency": 30,
"features": {
"spectralCentroid": 85.2,
"crestFactor": 3.5,
"rms": 0.42
}
}
Trend Predictor (RUL Mode)
// Input
msg.payload = 75.2;
msg.timestamp = Date.now();
// Output (RUL Mode)
{
"payload": 75.2,
"rul": {
"value": 48.5,
"unit": "hours",
"lower": 42.1, // Lower confidence bound
"upper": 55.2, // Upper confidence bound
"confidence": 0.87, // R-squared
"status": "warning" // healthy/warning/critical/failed
},
"degradation": {
"percent": 75.2, // % toward failure threshold
"rate": 0.5, // Degradation rate per sample
"trend": "increasing"
},
"thresholds": {
"failure": 100,
"warning": 80
}
}
Dynamic Configuration (msg.config)
All major nodes support dynamic runtime configuration via msg.config. This allows you to override node settings on a per-message basis without redeploying the flow.
Supported Nodes and Parameters
Anomaly Detector
msg.config = {
method: "zscore", // Override detection method
zscoreThreshold: 2.5, // Override Z-score threshold
zscoreWarning: 1.8, // Override warning threshold
iqrMultiplier: 1.5, // Override IQR multiplier
minThreshold: 10, // Override min threshold
maxThreshold: 100, // Override max threshold
hysteresisEnabled: false, // Enable/disable hysteresis
consecutiveCount: 5 // Override consecutive count
};
msg.payload = 42.5;
Trend Predictor
msg.config = {
mode: "rate-of-change", // Override mode (prediction/rate-of-change/rul)
threshold: 80, // Override prediction threshold
rocThreshold: 5, // Override rate of change threshold
failureThreshold: 100, // Override RUL failure threshold
warningThreshold: 80, // Override RUL warning threshold
predictionSteps: 10 // Override prediction horizon
};
msg.payload = 75.2;
Signal Analyzer
msg.config = {
mode: "vibration", // Override mode (fft/vibration/peaks/envelope/cepstrum)
vibrationThreshold: 5, // Override vibration threshold
peakThreshold: 0.3 // Override peak detection threshold
};
msg.payload = [0.5, 0.7, 0.3, ...];
Health Index
msg.config = {
healthyThreshold: 90, // Override healthy threshold
warningThreshold: 70, // Override warning threshold
degradedThreshold: 50, // Override degraded threshold
criticalThreshold: 25, // Override critical threshold
aggregationMethod: "minimum", // Override aggregation (weighted/dynamic/minimum/average/geometric)
sensorWeights: { // Override sensor weights
"temp": 2.0,
"vibration": 1.5
}
};
msg.payload = { temp: 45, vibration: 2.3 };
Use Cases
- Adaptive Thresholds: Adjust thresholds based on time of day, operating mode, or external conditions
- A/B Testing: Compare different detection parameters on the same data stream
- Contextual Sensitivity: Use tighter thresholds during critical operations
- Batch Processing: Process historical data with different configurations
Docker Setup
For ML Inference Node
The ML Inference node requires a Debian-based container with native dependencies.
# Use the provided docker-compose.dev.yml
docker-compose -f docker-compose.dev.yml up
# This builds a custom image with:
# - Python 3 + build tools
# - TensorFlow.js Node bindings
# - ONNX Runtime Node bindings
Standard Setup
# Production mode
docker-compose up
# Development mode (hot-reload)
docker-compose -f docker-compose.dev.yml up
GPU Acceleration (NVIDIA, optional)
Both inference paths — the direct TensorFlow.js path in the Node-RED container and the MAX Engine bridge path (MAX Engine + ONNX Runtime) — can optionally run on an NVIDIA GPU. The CPU path stays the default; GPU is opt-in.
Host prerequisites:
- NVIDIA driver (compatible with CUDA 12.x)
- NVIDIA Container Toolkit
- Docker with Compose v2
Enable via Compose override:
docker compose -f docker-compose.dev.yml -f docker-compose.gpu.yml up --build
The override file swaps the Dockerfiles for their GPU variants (Dockerfile.gpu, Dockerfile.max.gpu) at build time and reserves the GPU(s) via deploy.resources. What this does:
| Container | GPU image base | Enabled backends |
|---|---|---|
node-red |
nvidia/cuda:12.4.1-cudnn-runtime-ubuntu22.04 |
@tensorflow/tfjs-node-gpu, tensorflow[and-cuda] |
max-engine |
nvidia/cuda:12.4.1-cudnn-runtime-ubuntu22.04 |
MAX Engine (GPU) + onnxruntime-gpu (CUDAExecutionProvider) |
The bridge code (nodes/python/max_bridge.py) automatically selects the best available backend in this order: MAX Engine GPU → ONNX Runtime CUDA → ONNX Runtime CPU.
Verification:
# ONNX Runtime should list CUDAExecutionProvider
docker compose -f docker-compose.dev.yml -f docker-compose.gpu.yml \
exec max-engine python3 -c "import onnxruntime as ort; print(ort.get_available_providers())"
# Bridge status (shows backend & loaded models)
curl http://localhost:8765/status
# Inside the Node-RED container: tfjs-node-gpu should find CUDA
docker compose -f docker-compose.dev.yml -f docker-compose.gpu.yml \
exec node-red node -e "require('@tensorflow/tfjs-node-gpu'); console.log('OK')"
Notes:
- The GPU images are significantly larger (several GB), so the first build takes correspondingly longer.
- If a single GPU path is enough, you can trim the override file and keep only the
max-engineor only thenode-redservice block. - For MAX-Engine-only acceleration, the official
modular/max-nvidia-fullimages are an alternative — usable as a drop-in forDockerfile.max.gpu(base image swap).
Dependencies
Required
- Node-RED >= 2.0.0
- Node.js >= 18.0.0 (the LLM Analyzer node uses the built-in
fetch)
Core Dependencies
fft.js- High-performance FFT (Radix-4 Cooley-Tukey algorithm)ml-isolation-forest- For Isolation Forest nodesimple-statistics- For statistical functions
Optional - JavaScript ML Runtimes
@tensorflow/tfjs-node- TensorFlow.js supportonnxruntime-node- ONNX Runtime support
Optional - Python ML Runtimes (Docker or manual)
For TFLite, Keras, and scikit-learn models:
pip install numpy tensorflow scikit-learn joblib tflite-runtime
# Use numpy<2 for tflite-runtime compatibility
pip install "numpy<2"
Performance Features
High-Performance FFT
The Signal Analyzer uses fft.js with the Radix-4 Cooley-Tukey algorithm:
- O(n log n) complexity vs O(n²) for naive DFT
- 10-100x faster for large signal buffers (2048+ samples)
- Automatic power-of-2 sizing and windowing (Hann, Hamming, Blackman)
Persistent Python Bridge
For Python-based ML models (Keras, scikit-learn, TFLite), a persistent subprocess is maintained:
- Single Python process shared across all ML Inference nodes
- Model caching - models stay loaded in memory between inferences
- 10-100x faster compared to spawning a new process per inference
- Automatic restart if the bridge crashes
Check bridge status via API: GET /ml-inference/python-bridge
State Persistence
Enable Persist State in node configuration to save:
- Data buffers and training history
- Calculated statistics (mean, std, thresholds)
- Trained model states (PCA, Isolation Forest)
States survive Node-RED restarts when using file-based context storage:
// settings.js
contextStorage: {
default: { module: "localfilesystem" }
}
Or use the provided Docker image which includes all dependencies.
Documentation
- training/models/README.md - ML models guide and training instructions
- CHANGELOG.md - Version history and changes
Contributing
Contributions are welcome! Please:
- Fork the repository
- Create a feature branch
- Add tests if applicable
- Submit a pull request
Sponsor this project
This package is developed and maintained in my own time. If it saves you some, consider supporting it:
License
Apache License 2.0 — see LICENSE and NOTICE.
Copyright 2025-2026 blanpa
Contributing and forks
Pull requests are welcome, including large ones. If you are planning a bigger change — a dependency migration, a restructure, new nodes — please open an issue first. We are happy to discuss it and to land substantial work here; that is usually less effort than maintaining a parallel package, and it keeps a single place for users to report bugs.
If you do publish a fork under its own package name, please also rename the
Node-RED node type IDs (for example myprefix-condition-monitoring-*) and use your own palette
category. Node-RED refuses to register a node type that is already claimed, so
identical type IDs make it impossible to install both packages side by side.
Roadmap
- Consolidate nodes into unified components
- ML Inference with Model Registry
- Google Coral / Edge TPU support
- PCA Anomaly Detection
- Bearing fault detection via Signal Analyzer (Envelope Mode)
- Weibull reliability analysis
- Cepstrum analysis for gearbox diagnostics
- Mahalanobis distance for multivariate anomalies
- ISO 10816-3 vibration severity assessment
- Hysteresis (anti-flicker) for anomaly detection
- Pre-trained models for common use cases (model catalog + ML Inference picker)
- Concept/data-drift monitoring + retraining feedback loop (current CUSUM
driftis process drift, not model/distribution drift) - Consistent severity/score in alert output across all anomaly nodes (
isolation-forest/pcalack theseverityfield thatanomaly-detectoralready emits)
Made with ❤️ for the Node-RED community