Calculate Lost Frames from LoRaWAN-Frame-Counter
Detects missing LoRaWAN frames via a rolling frame counter comparison. Outputs lost-frame count and flags session resets/rejoins. Works with any network server and with 16- or 32-bit counters.
Who it’s for
For IoT integrators and platform operators who need to know whether a LoRaWAN device is actually delivering every uplink, not just whether it’s sending something. Silent packet loss, caused by RF interference, marginal coverage, gateway congestion, or duty-cycle collisions, doesn’t show up in the payload itself. A sensor can look “online” while a growing share of its readings never arrive. This calculated field turns the LoRaWAN frame counter, which every uplink already carries, into a direct, per-device loss metric without requiring any change to the sensor or its payload format.
What it does
The calculated field reads the LoRaWAN device’s frame counter (fCnt) as a rolling time series argument limited to the last 2 values. On every new uplink it compares the current counter value to the previous one. The previous value must be inside the Time window (60 hours by default). After a longer gap there is nothing to compare with, so frames lost during that gap are not counted:
- A gap greater than 1 means uplinks were missed in between, the field writes the exact count to
frameCounterLost. - A duplicate frame (the same counter value as the previous one) is not counted as loss. The field compares the two newest values by timestamp. If a frame reaches ThingsBoard late, after a newer one, and is saved with its arrival time, the field reads it as a reset.
- A counter value lower than the previous one, from a device rejoin or from the counter starting again from 0, is written to
frameCounterReset(1) instead of being misread as a frame loss, avoiding a false spike right after every reset.
Both frameCounterLost and frameCounterReset are written back to the same entity as new time series keys, on every uplink (including frameCounterLost = 0), so downstream alarms can clear correctly and reception can be confirmed as clean, not just guessed from the lack of alarms.
How to set up
No relations or related entities are required, this CF operates on telemetry from a single entity.
The fCnt time series key must already be published by the device before the CF can evaluate. This is not part of a standard sensor payload and typically needs to be extracted from the network server’s uplink metadata and saved as its own telemetry key first. If your data comes through a ThingsBoard integration, add fCnt to the telemetry in its uplink converter. Otherwise, set up your network server to send fCnt as a telemetry key.
Install the calculated field on the device profile (recommended, so it applies automatically to every device of that type) or on a single device entity if only one sensor needs it.
Make sure the output keys frameCounterLost and frameCounterReset don’t collide with existing telemetry keys on the target entity, unless overwriting is intended.
How to customize
- To use a different telemetry key — change the Time series key on the
counterargument to match whatever key yourfCntvalue is published under. - To rename the output keys — rename
frameCounterLostandframeCounterResetin the script’s return objects to whatever your dashboards and alarm rules expect. - To adjust the detection window — change the Time window on the rolling argument (default 60 hours). Widen it if your devices report less frequently than that, or if you want to count frames lost during a longer outage, for example when a gateway is down for several days. Max values should stay at 2, since the logic always compares exactly the last two received counter values.
Tips
- To alarm on frame loss — create an alarm rule on
frameCounterLost > 0(or a higher threshold, depending on how much loss is tolerable for the use case). Alarm onframeCounterLostitself, not onframeCounterReset, a reset is expected device behavior, not a delivery problem. - To flag devices with recurring connectivity problems — chain a second calculated field of type Time series data aggregation on top of
frameCounterReset(Sum, daily or weekly interval) to get arejoinsPerXmetric, and alarm on that (e.g.rejoinsPerX > 2) instead of individual reset events, a single rejoin is normal, a cluster of them is the actual signal.
Share Your Calculated Field with the Community
Built a useful data transformation? Export it as a JSON from ThingsBoard and publish it to the IoT Hub. Share it with thousands of ThingsBoard developers worldwide.