Appendix E: Connection and Solution Deployment
Overview
Intended audience: Users of the main text. When operations in the main text encounter issues such as a decoder not taking effect, the gateway not receiving data, no device telemetry, or abnormal MQTT subscriptions, consult this appendix to locate the problem. You may also read it in advance before configuration to avoid common mistakes.
1. LoRaWAN Uplink Decoder
1.1 What the Decoder Does
LoRaWAN devices report raw bytes. Without a decoder, telemetry contains only a hexadecimal string, and values such as temperature and humidity cannot be identified directly. A decoder converts byte data into named fields and values.
The decoder is attached to the device profile, not to an individual device. All devices of the same model share one decoder; replacing the decoder affects all devices under that model. The decoder is called directly by the transport layer and does not need to be handled in a rule chain; by the time data enters the rule chain, decoding is already complete.
1.2 ES5 Is Required
The platform's JavaScript engine supports only ES5. If a script uses ES6+ syntax, the upload may appear successful, but it will fail silently at runtime, with no error message, and telemetry will contain only hex. This is one of the most common pitfalls.
1.3 ES5 Rewrite Reference Table
| ES6+ syntax (incompatible; causes the decoder to fail silently) | ES5 syntax |
|---|---|
const bytes = input.bytes; | var bytes = input.bytes; |
let temp = 0; | var temp = 0; |
var f = (x) => x * 2; | function f(x) { return x * 2; } |
var s = `temperature${temp}`; | var s = 'temperature' + temp; |
if (arr.includes(x)) { } | if (arr.indexOf(x) >= 0) { } |
hex.padStart(2, '0'); | (hex.length < 2 ? '0' + hex : hex); |
Object.assign(a, b); | Manually copy key by key |
for (var x of arr) | for (var i = 0; i < arr.length; i++) |
class Foo { } | function Foo() { } |
var {a, b} = obj; | var a = obj.a; var b = obj.b; |
After obtaining a vendor script, first search for the three keywords const, let, and =>. If any are present, rewrite them according to the table above.
1.4 Complete Decoder Example
The following example can be used directly: the first two bytes are temperature (0.1°C), and the last two bytes are humidity (0.1%).
function decodeUplink(input) {
var bytes = input.bytes;
// Example: first two bytes are temperature (0.1°C), last two bytes are humidity (0.1%)
var temperature = ((bytes[0] << 8) | bytes[1]) / 10;
var humidity = ((bytes[2] << 8) | bytes[3]) / 10;
return {
data: {
temperature: temperature,
humidity: humidity
}
};
}
Each key in the returned data object becomes a telemetry entry. The example above generates two entries: temperature and humidity.
Raw hex is always retained: even if decoding succeeds, telemetry will contain both the decoded fields and the raw hex. This allows you to trace back to the raw data if the decoder is incorrect, without data loss.
1.5 Debugging the Decoder
Decoder errors do not cause uplink data loss, but fields will be missing from telemetry. Troubleshooting steps:
- On the device details page, check Latest Telemetry to see whether the expected fields are present.
- If only a hex string is shown, the decoder is not taking effect. Possible causes include the decoder not being selected, a script runtime exception, or the use of ES6 syntax.
- If field names are correct but values are abnormal, the byte order or scaling factor is incorrect.
2. Gateway Hardware Configuration (Packet Forwarder)
After adding the gateway in the all-in-one device UI, you must also configure the packet forwarder in the gateway's own management UI (not the all-in-one device UI):
| Parameter | Value |
|---|---|
| Server Address | IP address of the all-in-one device |
| Server Port (up) | Check the table below by frequency band; for example, EU868 uses 1700 |
| Server Port (down) | Same as up |
| Protocol | Semtech UDP packet forwarder |
| Frequency Band | UDP Port |
|---|---|
| EU868 | 1700 |
| US915 | 1701 (sub-band 1) |
| CN470 | 1702 (channel-plan 10) |
| AS923 | 1703 |
| AU915 | 1704 (sub-band 1) |
| KR920 | 1705 |
| IN865 | 1706 |
| RU864 | 1707 |
| EU433 | 1708 |
| CN779 | 1709 |
Common configuration error: the port and frequency band do not match. For example, if the gateway is set to 1700 but the device profile selects CN470 (corresponding to 1702), packets are sent to a port where no one is listening. The gateway may show "Connected", but the device will never receive data. The frequency bands of the gateway, device profile, and device must be consistent, and the UDP port must correspond to the frequency band.
3. LoRaWAN Common Troubleshooting
3.1 Device Created but No Data
Troubleshoot in the following order; do not skip steps:
- Is the gateway online? Check the status in the gateway list. If it is offline, resolve the gateway issue first (main text Section 1, Step 6, and Appendix 2).
- Has the device joined? Check the device details page for a join record. If there is no record, check whether DevEUI / AppEUI / AppKey are correct, or whether the device is powered on and within coverage.
- Is the frequency band correct? The device, device profile, and gateway must use the same frequency band, and the gateway's UDP port must correspond to the frequency band.
- Telemetry exists but is all hex — decoder issue. See Appendix 1, and focus on ES5 syntax.
3.2 Device Loses Connection After Changing Frequency Band
This is normal. When the frequency band changes, the radio parameters change, and the device must rejoin. Reset the device or trigger a join again.
3.3 Class A Device Downlink Not Taking Effect
Class A devices open a receive window only after an uplink. Downlink commands are queued and sent on the device's next uplink. If the device reports once per hour, a downlink may take up to one hour.
If immediate downlink is required, use Class C, but power consumption increases significantly, so it is not suitable for battery-powered devices.
3.4 Telemetry Exists but Is All Hex
The decoder is not taking effect. Three possibilities:
- No decoder is selected in the device profile.
- The script throws an exception at runtime.
- The script uses ES6 syntax (most common).
First search the script for const, let, and =>, and rewrite them according to Appendix 1.3.
4. MQTT Subscription Troubleshooting
Each row in the list page shows "↙ Received / ✓ Successful". Expand to see more detailed counters.
A message from the broker to telemetry must pass six checks. If any check fails, the message is dropped and counted in the corresponding counter:
Received message messagesReceived
↓
① Size check Exceeds maximum payload → droppedTooLarge
↓
② JSON parsing Not valid JSON → droppedNotJson
↓
③ Get device name Path not found → droppedNoDeviceName
↓
④ Find/create device Auto-create not enabled → droppedDeviceNotFound
↓
⑤ Get telemetry Path not found or empty → droppedNoTelemetry
↓
⑥ Write Success → telemetryPublished
Use the counters to locate the problem:
| Symptom | Cause and handling |
|---|---|
| Received = 0 | No message received. Check the broker address, authentication, and topic filter (especially leading/trailing spaces). |
| Received > 0, Successful = 0 | Messages are coming in but all are dropped. Check the following counters. |
| droppedNotJson high | The sender is not sending JSON; it may be binary or plain text. |
| droppedNoDeviceName high | The device name path is incorrect. Capture a real message and compare the path. |
| droppedNoTelemetry high | The telemetry path is incorrect, or that node is an empty object. |
| droppedDeviceNotFound high | Auto-create device is not enabled, and the device does not exist. |
| droppedTooLarge high | Increase "Maximum Payload". |
When troubleshooting link issues, follow this order: first check the counters to identify which stage is blocked, then modify the configuration. Do not start by enabling DEBUG logs and restarting the service—the counters have already narrowed the problem down to a specific step.