In the field: what the engine carries¶
The examples run against simulators, and their Real hardware sections say honestly that most of those paths have not been tried with the device on a desk. That is about the examples. The engine itself is not new: it is the same engine that runs production systems today, and it is tested the same way every time it changes.
Data-centre monitoring (DCIM)¶
The engine is the core of several data centre infrastructure monitoring (DCIM) systems, set up and run by different teams. Every UPS, PDU, cooling unit, generator, sensor and meter of the site is a device of the engine; it polls them, keeps their alarms, writes their history and serves the operators' web application.
One of them, as configured today:
| devices | 1 837 — 1 510 over SNMP, 325 over Modbus TCP |
points (<io>) |
272 042, in 7 517 blocks |
| documents | 14 per node: the field (one document per floor), alarms, events, history, assets, work orders, the web back end |
connections (<con>) |
85: 26 SNMP, 14 SQL, Modbus TCP, HTTP / REST / SOAP, MQTT over WebSocket for the browsers, cluster and replication links, SMTP, SFTP, an MCP endpoint and a telnet maintenance shell |
| engine threads | about 330: a thread per document, connection and thread element, and 207 workers |
| nodes | three, every document a master on one node and a spare on the others; failover, replication and a journal of records that survives a node going down |
| databases | PostgreSQL (TimescaleDB for the value history) over ODBC: alarms, events and value history written by the engine's own record pipeline, assets and work orders read and written by the documents |
| in front | a load balancer and web servers; the operators' Angular application talks to the engine over HTTPS and WebSocket |
One measured figure from that system's logs: a single floor document replicates about 1 000 value changes a second to the other nodes, all day.
The configuration is large, and it is still the same kind of XML as in
PRJEDU_modbus: <con>, <dev>, <bi>, <io>, classes, *_fnc chains.
Nothing in it needs a different engine or a different build.
Measured in the lab¶
Figures from the engine's own measurements, on a laptop (Intel Core i7-12700H) unless it says Linux. They are what one process does, not a limit: a system that needs more spreads its documents over threads, processes and nodes.
| Modbus master, 1 000 polls a second of 100 registers each (100 000 values a second), each value scaled, rounded and checked against alarm limits by its function chain | about one third of one CPU core |
| MQTT broker on Linux, 10 000 connected clients | idle: 2.5 % of a core, 99 % of messages within 1.6 ms |
| MQTT broker on Linux, 10 000 subscribers at 1 000 messages a second | 7 % of a core, 99 % within 0.28 ms |
| camera capture and inspection in the engine | about 600 frames a second captured, every one inspected |
PRJEDU_robotarm (robot at 20 steps a second, cell polling every 100 ms) |
16 % of one core, 31 MB |
How it is tested¶
Every change to the engine goes through the same checks before a release:
- More than 100 regression rigs. Each is a small project of its own — an XML configuration, scripts, often a fake device or server written in Python — with a test script that starts the engine, drives it, and checks what it did, value by value and log line by log line. A rig is written for every fault found in the field and for every new feature, and kept: record pipeline, cluster failover, Modbus, SNMP, OPC UA, SQL pools, MQTT, TLS, cameras, licences, health alarms, scripts, time and decimal values and many more. Many run on Linux as well as on Windows.
- The examples in this repository are run too, on Windows, Linux x64 and Linux arm64 (Raspberry Pi), when the engine changes under them — the Python examples, for instance, under both Python versions on all three.
- Unit tests of the core library (types, the XML engine, XPath, values): more than 1 300 checks, on Windows and Linux.
- Linux CI builds everything with gcc and clang, and once more with
charunsigned, as ARM sees it, on every push.
A fault found in the field is first reproduced in a rig, then fixed, and the rig stays in the set — the reason a later change cannot quietly bring it back.