The Signal Quality Engine is now open source
By Dimitri Lafleur
The Signal Quality Engine (SQE) is a Python library that processes raw SCADA telemetry through a fixed DSP pipeline of filters, drift detection, spike detection, frequency analysis, and a composite quality score. It is now available under the Apache 2.0 license.
Why this exists#
RTU and PLC simulators generate noisy, sometimes pathological data. Downstream logic such as alarm evaluation, historian compression, and operator displays needs to know how much to trust each value. Writing one-off threshold checks per signal doesn't scale, and tuning them by hand across hundreds of points is brittle.
SQE replaces that with a deterministic pipeline that scores every signal on every scan against five dimensions: noise, drift, spikes, oscillation energy, and missing samples. The output is a single Signal Quality Index (0–100) per point, per scan, with component breakdowns and automatic incident lifecycle events.
What's in the box#
- Filter bank: EWMA, high-pass, and moving average, all running in parallel per signal
- Drift detector: sustained, transient, and monotonic drift with configurable thresholds
- Spike detector: sliding-window variance with adaptive σ thresholds
- Oscillation detector: correlation-based and FFT frequency analysis
- Innovation model: Kalman-inspired residual tracking for early degradation signals
- SQI composite: weighted across all detector outputs, with trend tracking and quality classification
- Incident engine: lifecycle events (started, updated, resolved) with hysteresis to avoid flapping
- CLI tool: analyze, simulate, replay, and evaluate from the command line
- Integration adapters: drop-in connectors for the PointCore simulator, PLC scan engine, and comms front-end
Determinism matters#
Every computation in SQE is deterministic. No background threads, no async, no random seeds that vary between runs. Given the same input scans and config, the processed signals, SQI values, and incident IDs are byte-for-byte identical across runs. The replay harness and a diff-based determinism check in the test suite verify this.
Scan timing is predictable: ~0.1–0.2ms per signal per scan on consumer hardware, with fixed memory allocation. For a 100-signal setup inside a 100ms PLC scan window, SQE uses roughly 10–20% of the budget.
Try it#
pip install -e .
pip install -e ".[all]" # with plotting support
# Quick demo
sqe simulate --duration 500 --noise 1.5 --plot
# Run the test suite
pytest -q
The repo is at github.com/dimilafl/rtu. Contributions, issues, and questions are welcome.
Related work
The engine's place in the stack.
Simulators produce the telemetry. SQE scores it before control logic consumes it.