Application payloads should really be limited, if only to comply with the TTN Fair Access Policy of 30 seconds per day for uplinks, and 10 messages per day for downlinks. Let’s compile a checklist of best practices to achieve that:
-
Always, always, always use binary encoding to send your data. See The Things Uno MQTT Workshop for an introduction to TTN’s payload functions to help you decode it.
Why? From The Things Network 2016 Update, where “SF7” is actually not bad at all:
Don’t waste your time!
- Simple:
{ “Count”: 1234, "Temperature": 20.635 }
- 40 bytes: 292 messages per day (SF7)
- Remove counter (
is already included in header†), spaces, and compress names:{“t”:20.63}
- 11 bytes: 486 messages per day
- No JSON:
20.63
- 5 bytes: 582 messages per day
- Signed 16 bit integer
- 0x080F
- 2 bytes: 648 messages per day
And from Slack:
We’re definitely moving away from JSON (and even plaintext) data. The MQTT or API would just give you the (base64 encoded) binary data that your device sent. And then you can run it through ConCaVa. Or just convert the binary data to whatever value you want with two lines of code.
- Simple:
-
Do not send a precision that is higher than your use case needs, or your sensors offer. Like a GPS unit might be less accurate than you think; see Best practices when sending GPS location data.
-
Combine sensors in a single device, or when collecting data that is not needed realtime then consider sending in small batches. As the LoRaWAN protocol always adds at least 13 bytes of overhead to the application payload, and also needs some air time to send some more housekeeping data, a 55 bytes application payload might only need 2 to 2.5 times more air time compared to 8 bytes. See Spreadsheet for LoRa airtime calculation, and compare different payload sizes with different spread factors.
-
When a single node has multiple sensors for which to expect similar readings, maybe a single (multi-byte) value of one sensor plus (smaller) offsets for the other sensors can decrease the data size.
-
Only send (in short intervals) when the data has changed more than some threshold. (But consider sending more often whenever the data changes, if only as that makes it easier to detect faulty sensors that emit readings that change randomly.)
-
If it’s about finding lost things or reading data on command (rather than tracking continuously), assuming a LoRaWAN Class A device (where an end-device can receive some data right after sending some), and when not expecting the device to move out of range:
make the device send a small “alive” packet quite often, and only if the application responds in some specific way, send a measurement. (This might also preserve battery life.)(it seems even “alive” packets need quite some air time and would quickly hit the maximum daily Fair Access Policy limit; to be continued…) But note that the application should then only reply in a specific way when data is needed, and keep silent if not:Fair Access Policy: Practice
- […]
- Downlink bandwidth is even more restricted
- you can’t send all messages as ‘confirmed uplink’
…which might actually be limited to only 10 downlink messages per day!
-
When sending battery level, there is no need to include that in every single packet.
-
If your node can send different message types: use the LoRaWAN “port” to define what payload is sent.
-
If you have old and new nodes that use different encodings of their data: as one can always determine the node’s ID from the LoRaWAN header, one does not need to send any software version if one keeps a proper administration of node IDs and their installed software.
† Beware that FCntUp might also be increased for non-application uplinks, like for responses to MAC commands.