scada-tag-audit
Pre-commissioning cross-vendor tag database drift audit for SCADA integrators.
Reads an Ignition HMI tag CSV export + a Rockwell Studio 5000 L5X export, reconciles them, and produces a self-contained HTML report flagging the drift patterns that break faceplates at commissioning-week: orphaned HMI bindings, type mismatches, and naming-convention drift between what the PLC exports and what the HMI references.
Runs on the integrator's laptop. No cloud upload. No vendor API dependency. No client data leaves the machine.
Install
Windows .exe (recommended for integrators): download the latest from Releases.
Double-click to run (opens file-picker dialogs for both inputs), or invoke from a terminal with arguments.
Python package (for CLI-culture users):
pip install scada-tag-audit
Requires Python 3.10+.
Quick start
Double-click scada-tag-audit.exe and select the two exports when prompted. Report opens in your default browser.
Or from a terminal:
scada-tag-audit --ignition path/to/tags.csv --rockwell path/to/routine.L5X --output drift-report.html
The HTML report is self-contained (no external dependencies), safe to email or archive.
What it flags
| Category | Color | Severity | Meaning |
|---|---|---|---|
| Orphaned HMI binding | Red | High | HMI references a PLC tag that does not exist. Faceplate breaks at go-live. |
| Type mismatch | Purple | High | Same tag, incompatible data types PLC-side vs HMI-side (e.g. PLC REAL, HMI Int4). |
| Naming convention drift | Yellow | Medium | Reference resolves under normalization but not exact match (e.g. Pump2_Run vs Pump_2_Run). |
| Unit mismatch | Blue | Info | HMI declares engineering units; PLC counterpart has no EU metadata. |
| Orphaned PLC tag | Orange | Info | PLC tag exists but no HMI tag references it. Cleanup opportunity. |
| Exact match | Green | None | Reference resolves cleanly with compatible types. |
How it works
The engine extracts PLC-side references from Ignition's OPC Item Paths (e.g. [Global_PLC]Motor1_Run → Motor1_Run) and matches them against Rockwell tag names from the L5X. When exact matches fail, it retries under name normalization (case-fold, prefix strip, separator collapse, letter-digit boundary insertion). Every reference that fails to resolve becomes an orphan. Every match with incompatible data types becomes a type-mismatch finding.
The HTML report groups findings by severity: actionable drift (commissioning breakers) at the top, informational rows below, exact matches collapsed at the bottom.
Development
git clone https://github.com/Yveshby27/scada-tag-audit
cd scada-tag-audit
pip install -e ".[dev]"
pytest
v0.1 scope + limitations + roadmap
In scope: Ignition tag CSV + Rockwell Studio 5000 L5X exports. Base tag reconciliation across scalar data types (BOOL, SINT, INT, DINT, REAL, LREAL, STRING).
Known v0.1 limitations (will produce false findings; be aware):
- UDT member references are not resolved. If your Ignition HMI references a Rockwell UDT member (e.g.
[PLC]Pump_1.SpeedwherePump_1is a UDT-typed base tag), the parser extracts the last segment (Speed) and fails to find it as a top-level PLC tag. Result: falseorphaned_hmi_bindingfinding. UDT-heavy PlantPAx projects will surface many of these. v0.2 roadmap. - Alias chains are not resolved. L5X alias tags parse as base tags, but the drift engine does not chase
AliasForreferences to detect when an HMI reference through an alias resolves to a valid base tag. Simple flat aliases still match when the HMI references either name directly. v0.2 roadmap. - Wonderware .aaGDB, Kepware XML, FactoryTalk, Iconics, OPC UA custom information models — not parsed. v0.2+ roadmap if the wedge holds.
Practical implication: run against a small representative slice of your project first to calibrate the false-positive rate for your codebase. If UDT-member false-orphans dominate, wait for v0.2 UDT support.
Feedback on which limitations hurt most is exactly what determines the v0.2 priority. Reach out via the article link below.
Background
Notes on why this exists: What small SCADA integrators actually ship when the tag database drifts.
If you run a small integrator shop (2-15 EE) delivering multi-vendor projects and the pain shape matches what you see, reach out. LinkedIn or email in the article.
License
MIT
Metadata
Release files for scada-tag-audit 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| scada_tag_audit-0.1.1.tar.gz | 31.2 kB | Without provenance | Details for scada_tag_audit-0.1.1.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| scada_tag_audit-0.1.1-py3-none-any.whl | Python 3 | none | any | Details for scada_tag_audit-0.1.1-py3-none-any.whl |
Total release size: 46.9 kB
Release files / scada_tag_audit-0.1.1.tar.gz
| Download URL | scada_tag_audit-0.1.1.tar.gz |
|---|---|
| Size | 31.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
f0280ab0e51ba93a456ca53f77d6bc50053422393e4947e0014a7aeb51e6b2bd
|
|
BLAKE2b-256 checksum How to use checksums |
b00f0a6fbc717d708d95f14f1e0d2b92378224d601803e0c2b0ce0053ddc726a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.9
|
Release files / scada_tag_audit-0.1.1-py3-none-any.whl
| Download URL | scada_tag_audit-0.1.1-py3-none-any.whl |
|---|---|
| Size | 15.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
2c47e86cb0dffa37839853ed14138338a941a3a0bb424bdee3552ad25b01c119
|
|
BLAKE2b-256 checksum How to use checksums |
84c9fd781b5d2a0f22f6acdce4180877ff61b9bd3b22bc0937194e5b8cb46ae9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.9
|
Security for scada-tag-audit 0.1.1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.