We publish size claims for ECP in the repo and in earlier posts (format comparison, LoRaWAN frame budget). Those numbers come from our own builds and public test vectors.
This post is different. It covers a short technical trial run by Novatore Solutions, an external engineering team, in a collaboration with us. We agreed the scenario and the pass/fail bar. They built the apps, ran the vectors, and wrote up the measurements. We are reporting their results, with credit to them.
I'm on the Egonex team. Where I say "we expected," that is our side. Where I cite sizes and pass rates, that is from Novatore's trial summary.
What they built
Scenario: cold-storage temperature alerts. Sensor side decides when a reading is a breach (warmer than the threshold). Monitor side consumes alerts and verifies integrity.
Stack they used:
.NET 8
ECP.Core 2.0.6
MQTTnet
Mosquitto on localhost:1883 (macOS)
Per alert they published two binary frames on MQTT:
coldstorage/alerts/{zone}/uet
coldstorage/alerts/{zone}/envelope
Temperature excursions mapped to EmergencyType.Custom1. Envelope payload for the reference sample looked like:
Z3|-2.0C|thr-18.0C|S042
That is domain text inside a signed envelope. The compact token stays at 8 bytes either way.
There is no official ECP MQTT NuGet package. They put raw ECP bytes on MQTT topics, same idea as dropping bytes into any other transport.
Pass/fail bar
We asked them to treat the public test vectors as the gate. Four files in the repo. Their harness reported:
File Result
uet-vectors.json 8/8
envelope-vectors.json 9/9
hmac-vectors.json 7/7
negative-vectors.json 10/10
Total 34/34
That matched what we hoped for on conformance. For a first external integration in a few days, a clean sweep on the official vectors was the main thing we cared about.
Size on their sample
Their comparison used a typical minified JSON alert object for the same event, then the ECP forms they actually sent.
Format Bytes
JSON (minified) 146
ECP Envelope (signed, 12-byte HMAC) 57
ECP UET 8
Envelope math for the 57-byte sample: 22-byte header + payload + 12-byte HMAC. During runs they also saw 58-byte envelopes when the payload length moved by one character. Expected.
Against their JSON object that is about 61% smaller for the signed envelope and about 95% smaller for the token. Different baseline than CAP XML (669 bytes) in Part 1. Same direction: the binary path is short on the wire.
Integrity check
Envelope verification used HMAC-SHA256 with a 12-byte truncated tag.
They deliberately tampered a payload on the wire (one byte in the text, thr → ths). The monitor kept running and printed a clean reject:
✗ REJECT [ENV] reason=hmac-invalid
Valid path looked like:
✓ ALERT [ENV] ... bytes=58 hmac=✓
Wrong key → reject. Tamper → reject. Consumer stays up. That path worked more cleanly than we usually see on a first cut of "sensor publish / monitor verify" demos.
How to read these numbers
The useful takeaway is practical: an outside team took public ECP.Core, mapped a domain event, put binary on MQTT, decoded it, verified HMAC, and cleared the official vectors. For their cold-storage sample, the signed envelope and the 8-byte token were both shorter than the JSON object they compared against.
Keep the scope in mind. The broker was local Mosquitto, not a production cold-chain fleet. CAP still owns public alerting interoperability when that is the requirement. HMAC on the envelope assumes you already have a key story; the trial does not cover provisioning or secure element design.
Novatore built the apps and wrote the measurements. If you want the same bar on your machine, run the public vectors and drop ECP bytes onto your own MQTT path.
Why we care
Internal ProofCard runs and our own benchmarks are useful. An external team hitting 34/34 and shipping a working encode → MQTT → decode → verify loop is a different kind of signal. Short trial, concrete scenario, written measurements.
If you integrate ECP, start from the same gate they used: test-vectors and the wire format spec.
git clone https://github.com/Egonex-Code/ecp-protocol.git
cd ecp-protocol
run the official vectors against your decoder
NuGet entry point: ECP.Core.
Related reading
Part 1 — CAP / JSON / ECP size comparison
Part 2 — LoRaWAN frame budget
GitHub — ecp-protocol
Novatore Solutions
Thanks to the Novatore engineering team for running the trial and documenting the results.
Question: If you have put a custom binary alert format on MQTT (or anything similar), what broke first: schema drift, HMAC/key handling, or topic design?
Top comments (0)