WisNode Tag Quick Start Guide
Prerequisites
Before going through each step in this WisNode Tag guide, prepare the items listed below:
- WisNode Tag
- WisGate Edge gateway
- An Android or iOS device with Bluetooth
Gateway Requirements
TrackIT requires a RAK gateway running WisGateOS 2 v2.2.2 or later. For gateway firmware version details, refer to the WisGateOS 2 Release Notes .
- On WisGateOS 2 v2.2.2 or later, the TrackIT Data Broker is included in the gateway firmware. No additional installation is required.
- On WisGateOS 2 v2.3.1 or later, the TrackIT Data Broker is provided as an Extension. Install the TrackIT Data Broker extension before adding the gateway to TrackIT. For installation instructions, refer to Trackit-data-Broker .
IMPORTANT
Without the TrackIT Data Broker Extension, gateways running WisGateOS 2 v2.3.1 or later cannot forward WisNode Tag data to TrackIT.
Package Inclusion
- 1× WisNode Tag
- 1× 4-pin magnetic pogo-pin USB charging cable
- 1× Lanyard
Figure 1: Inclusion listProduct Configuration
Tracker Setup
Add Tracker
-
Download and install the TrackIT App on your smartphone.
-
Turn on Bluetooth on your smartphone.
-
Connect your smartphone to the Wi-Fi AP of your RAK WisGate Edge gateway, and make sure the gateway has internet access.
-
Open the TrackIT App. If prompted, allow location permission.
-
Read and accept the Terms and Conditions and Privacy Policy, then tap Sign in with RAK ID.
Figure 1: Welcome screen -
Sign in with your RAK ID. If you do not have an account, tap Create new to register one.
Figure 1: Sign in screen -
After signing in, the App will prompt you to add a tracker. To start the pairing process, press the + ADD TRACKER button.
Figure 1: Add tracker and Start Pairing screen
Pair and Set Up the Tracker
-
Keep the phone near the device, press and hold the center button for at least 3 seconds, then tap START PAIRING.
Figure 1: Tracker not foundNOTEIf the device was turned on previously, you may need to restart it, as the Bluetooth is available for pairing for 30s.
-
After successful pairing, you will see a configuration screen, where you will be able to change the tracker's default name and the working mode.
Figure 1: setup_tracker
LoRaWAN Mode
In the Set up tracker interface, locate the Working Mode section and select LoRaWAN. This configures the WisNode Tag to communicate over a LoRaWAN network, enabling long-range, low-power data transmission to a Network Server. After selecting LoRaWAN, you choose how the Network Server is hosted.
Embedded NS
Selecting Embedded NS configures the WisNode Tag to connect to the Built-in Network Server of a RAK WisGate Edge gateway. This simplifies deployment—TrackIT automatically registers the device, and location data appears on the TrackIT map.
Figure 1: Embedded NSTrackIT Setup
-
After selecting LoRAWAN, choose RAK Embedded NS from the two options displayed.
-
Ensure the gateway is powered on and ready, then tap the GATEWAY ON button.
Figure 1: Gateway ON -
When prompted, tap GO TO WI-FI SETTINGS.
Your phone will be redirected to the Wi-Fi settings page.
-
Select and connect to the Wi-Fi AP of your RAK WisGate Edge gateway.
-
If prompted, enter the gateway login credentials.
Default credentials:
- Username: root
- Password: root
Figure 1: Connecting Wifi -
After a successful login, the TrackIT app automatically creates an application in the gateway’s Built-in Network Server and registers the WisNode Tag.
When the registration is complete, tap VIEW ON MAP to view the WisNode Tag location on the TrackIT map.
Figure 1: TrackIT Map
Built-in Network Server
After TrackIT automatically registers the device on the gateway's Built-in Network Server, you can view uplink data directly through the gateway's Web UI.
-
Log in to the gateway's Web UI.
-
Navigate to LoRa® > Configuration and confirm Work mode is set to Built-in network server.
-
Go to the LoRa® > Applications tab—the automatically created WisNode Tag entry appears here.
-
Click the Application, then select End devices and go to the Configuration tab. Click Packet capture to view uplink data. For payload decoding details, see the LoRaWAN Payload Reference.
Figure 1: bulit In NS
Third-party NS
Choosing Third-party NS directs the WisNode Tag to transmit data to an external Network Server (e.g., TTN, ChirpStack, or your own LNS). In this mode, TrackIT acts only as a configuration tool—location data is not available on the TrackIT map, as all uplinks go directly to your external backend.
Figure 1: Third LNS-
After selecting LoRaWAN, choose Third Party NS from the two options.
-
Review the displayed credentials: Device EUI, Application EUI, Application Key, Class, and Join mode. From the Region menu, select the appropriate LoRaWAN frequency band.
Figure 1: Configure Lorawan -
Press CONFIRM to choose the selected LoRaWAN region. Then, press CONTINUE.
NOTEA notification will be displayed, that in Third-party LNS mode the device's position data will be not available on the TrackIt App's map as the data will be sent to the Third-party Network Server directly.
Figure 1: Confirm Configuration
The Things Network (TTN)
Before viewing data, ensure the following prerequisites are met:
-
An Application and Device are added on the TTN server. See Adding Devices.
-
Gateways are connected to TTN v3 via UDP. See How to Connect RAK Gateways to TTN v3 via UDP.
-
Log in to the TTN Console .
-
Navigate to your Application and select the target End Device.
-
Open the Live data tab to view uplink packets.
Figure 1: TTN Server -
Navigate to the Payload formatters tab. Set Formatter type to Custom Javascript formatter, paste the following code into the Formatter code field, and click Save changes.
Click to view the code
function readUInt32BE(bytes, offset) {
return (
((bytes[offset] << 24) >>> 0) +
((bytes[offset + 1] << 16) >>> 0) +
((bytes[offset + 2] << 8) >>> 0) +
(bytes[offset + 3] >>> 0)
) >>> 0;
}
function readInt32BE(bytes, offset) {
var value = readUInt32BE(bytes, offset);
return value > 0x7fffffff ? value - 0x100000000 : value;
}
function parseStatus(status) {
return {
workmode: status & 0x3f,
charging: (status & 0x40) !== 0,
raw_status: status
};
}
function addStatusFields(decoded, status) {
var parsed = parseStatus(status);
decoded.workmode = parsed.workmode;
decoded.charging = parsed.charging;
decoded.raw_status = parsed.raw_status;
}
function readAscii(bytes, offset, length) {
var chars = [];
for (var i = 0; i < length; i++) {
var c = bytes[offset + i];
if (c === 0) {
break;
}
chars.push(String.fromCharCode(c));
}
return chars.join("");
}
function decodeTrackItPayload(bytes, fPort) {
var decoded = {
f_port: fPort,
errors: []
};
if (fPort !== 2) {
decoded.errors.push("unexpected_fport");
}
if (!bytes || bytes.length < 2) {
decoded.errors.push("payload_too_short");
return decoded;
}
var header = bytes[0];
decoded.header = header;
decoded.pkt_id = bytes[1];
switch (header) {
case 0xca:
if (bytes.length < 16) {
decoded.errors.push("invalid_0xCA_length");
return decoded;
}
decoded.type = "no_fix";
decoded.app_id = readUInt32BE(bytes, 2);
decoded.dev_id = readUInt32BE(bytes, 6);
decoded.battery = bytes[10];
decoded.utc = readUInt32BE(bytes, 11);
addStatusFields(decoded, bytes[15]);
break;
case 0xcb:
if (bytes.length < 26) {
decoded.errors.push("invalid_0xCB_length");
return decoded;
}
decoded.type = "position";
decoded.app_id = readUInt32BE(bytes, 2);
decoded.dev_id = readUInt32BE(bytes, 6);
decoded.longitude = readInt32BE(bytes, 10) / 1000000;
decoded.latitude = readInt32BE(bytes, 14) / 1000000;
decoded.accuracy = bytes[18];
decoded.satellites = bytes[19];
decoded.battery = bytes[20];
decoded.utc = readUInt32BE(bytes, 21);
addStatusFields(decoded, bytes[25]);
break;
case 0xcc:
if (bytes.length < 18) {
decoded.errors.push("invalid_0xCC_length");
return decoded;
}
decoded.type = "sos";
decoded.app_id = readUInt32BE(bytes, 2);
decoded.dev_id = readUInt32BE(bytes, 6);
decoded.longitude = readInt32BE(bytes, 10) / 1000000;
decoded.latitude = readInt32BE(bytes, 14) / 1000000;
decoded.sos_info = readAscii(bytes, 18, bytes.length - 18);
break;
case 0xcd:
if (bytes.length < 10) {
decoded.errors.push("invalid_0xCD_length");
return decoded;
}
decoded.type = "cancel_sos";
decoded.app_id = readUInt32BE(bytes, 2);
decoded.dev_id = readUInt32BE(bytes, 6);
break;
case 0xce:
if (bytes.length < 11) {
decoded.errors.push("invalid_0xCE_length");
return decoded;
}
decoded.type = "alarm";
decoded.app_id = readUInt32BE(bytes, 2);
decoded.dev_id = readUInt32BE(bytes, 6);
decoded.alarm_level = bytes[10];
break;
default:
decoded.type = "unknown";
decoded.errors.push("unknown_header_0x" + header.toString(16));
break;
}
return decoded;
}
// TTN entry function: must be named decodeUplink
function decodeUplink(input) {
var data = decodeTrackItPayload(input.bytes, input.fPort);
return {
data: data,
warnings: [],
errors: data.errors
};
}
Use the payload decoder to parse the data. You can now view the decoded data.
Figure 1: TTN DecoderChirpStack V4
Before viewing data, ensure the following prerequisites are met:
-
An Application and Device are added on the ChirpStack V4 server. See Connecting a device.
-
Gateways are connected to ChirpStack v4 via UDP. See How to Connect RAK Gateways to Chirpstack v4 via UDP.
-
Log in to the ChirpStack Network Server.
<IP address of ChirpStack>:8080 -
In the left navigation pane, go to Applications, select your target application, and then choose the specific end device.
-
Navigate to the device's Events tab to view uplink data.
Figure 1: Chirpstackv4 Server -
Navigate to the target Device Profiles. In the Codec tab, set Payload codec to JavaScript functions, paste the following code into the Codec functions field, and click Submit.
Click to view the code
// 1. Helper functions: Parse specific data formats from byte arrays
function readUInt32BE(bytes, offset) {
return (
((bytes[offset] << 24) >>> 0) +
((bytes[offset + 1] << 16) >>> 0) +
((bytes[offset + 2] << 8) >>> 0) +
(bytes[offset + 3] >>> 0)
) >>> 0;
}
function readInt32BE(bytes, offset) {
var value = readUInt32BE(bytes, offset);
return value > 0x7fffffff ? value - 0x100000000 : value;
}
function parseStatus(status) {
return {
workmode: status & 0x3f,
charging: (status & 0x40) !== 0,
raw_status: status
};
}
function addStatusFields(decoded, status) {
var parsed = parseStatus(status);
decoded.workmode = parsed.workmode;
decoded.charging = parsed.charging;
decoded.raw_status = parsed.raw_status;
}
function readAscii(bytes, offset, length) {
var chars = [];
for (var i = 0; i < length; i++) {
var c = bytes[offset + i];
if (c === 0) {
break;
}
chars.push(String.fromCharCode(c));
}
return chars.join("");
}
// 2. Core decoding function
function decodeTrackItPayload(bytes, fPort) {
var decoded = {
f_port: fPort,
errors: []
};
if (fPort !== 2) {
decoded.errors.push("unexpected_fport");
}
if (!bytes || bytes.length < 2) {
decoded.errors.push("payload_too_short");
return decoded;
}
var header = bytes[0];
decoded.header = header;
decoded.pkt_id = bytes[1];
switch (header) {
case 0xca:
if (bytes.length < 16) {
decoded.errors.push("invalid_0xCA_length");
return decoded;
}
decoded.type = "no_fix";
decoded.app_id = readUInt32BE(bytes, 2);
decoded.dev_id = readUInt32BE(bytes, 6);
decoded.battery = bytes[10];
decoded.utc = readUInt32BE(bytes, 11);
addStatusFields(decoded, bytes[15]);
break;
case 0xcb:
if (bytes.length < 26) {
decoded.errors.push("invalid_0xCB_length");
return decoded;
}
decoded.type = "position";
decoded.app_id = readUInt32BE(bytes, 2);
decoded.dev_id = readUInt32BE(bytes, 6);
decoded.longitude = readInt32BE(bytes, 10) / 1000000;
decoded.latitude = readInt32BE(bytes, 14) / 1000000;
decoded.accuracy = bytes[18];
decoded.satellites = bytes[19];
decoded.battery = bytes[20];
decoded.utc = readUInt32BE(bytes, 21);
addStatusFields(decoded, bytes[25]);
break;
case 0xcc:
if (bytes.length < 18) {
decoded.errors.push("invalid_0xCC_length");
return decoded;
}
decoded.type = "sos";
decoded.app_id = readUInt32BE(bytes, 2);
decoded.dev_id = readUInt32BE(bytes, 6);
decoded.longitude = readInt32BE(bytes, 10) / 1000000;
decoded.latitude = readInt32BE(bytes, 14) / 1000000;
decoded.sos_info = readAscii(bytes, 18, bytes.length - 18);
break;
case 0xcd:
if (bytes.length < 10) {
decoded.errors.push("invalid_0xCD_length");
return decoded;
}
decoded.type = "cancel_sos";
decoded.app_id = readUInt32BE(bytes, 2);
decoded.dev_id = readUInt32BE(bytes, 6);
break;
case 0xce:
if (bytes.length < 11) {
decoded.errors.push("invalid_0xCE_length");
return decoded;
}
decoded.type = "alarm";
decoded.app_id = readUInt32BE(bytes, 2);
decoded.dev_id = readUInt32BE(bytes, 6);
decoded.alarm_level = bytes[10];
break;
default:
decoded.type = "unknown";
decoded.errors.push("unknown_header_0x" + header.toString(16));
break;
}
return decoded;
}
// 3. ChirpStack entry function - Option 1: Decode(fPort, bytes)
function Decode(fPort, bytes) {
return decodeTrackItPayload(bytes, fPort);
}
// 4. ChirpStack entry function - Option 2: decodeUplink(input) (for compatibility with newer versions)
function decodeUplink(input) {
var data = decodeTrackItPayload(input.bytes, input.fPort);
return {
data: data,
warnings: [],
errors: data.errors
};
}
Use the payload decoder to parse the data. You can now view the decoded data.
Figure 1: Chirpstackv4 Decoder1
Figure 1: Chirpstackv4 Decoder2Set Battery Mode (Optional)
By default, Battery Mode is set to Monitor Mode, and the Update Interval is set to 2 minutes.
To change the battery mode:
-
Locate the Battery section.
-
Select Static, Monitor, or Movement-based.
Figure 1: Static Mode-
Configure the update interval or alarm intensity, depending on the selected mode.
-
Click SAVE CHANGES.
After the setting is saved, the firmware applies the new battery mode and may restart the LoRaWAN join process. For details, refer to the Battery Modes.
For custom applications, use BLE command 0x29 to set the battery mode, and 0x2A or 0x2E to configure the interval or movement level. For details, refer to the BLE API Reference.
The firmware mode mapping is as follows:
| Battery Mode | Firmware Mode Name | Firmware Code |
|---|---|---|
| Static Mode | LoRaWAN node static | 0x0B |
| Monitor Mode | LoRaWAN node beacon | 0x08 |
| Movement Mode | LoRaWAN node alarm | 0x09 |
