Requirements
An active Ubidots account.
An active account on The Things Network.
A cellphone running either Android or iOS.
MOKOSmart's LW001-BG PRO LoRaWAN Tracker.
1. Get the device's credentials
1. Turn on your mobile cellphone's Bluetooth and then turn on your MOKOSmart LW001-BG PRO by following the procedure as depicted in the following image:
Pro Tip: If the procedure was successful, the green power LED will flash once followed by the blue LED flashing intermittently, meaning the device is now discoverable.
2. Open "MKLora" app on your cellphone
3. Tap on the "Connect" button at the upper right corner
4. When asked for a password, type "Moko4321" (default password) and hit "OK":
5. Select "LORA" tab and then the "Connection Settings" option as depicted below:
6. Copy/save the following values since you'll need them for further steps:
DevEUI
AppEUI
AppKey
7. Click on "Region/Subnet" settings and select "US915"
2. Connect device to Network Server
Follow the steps below to connect your device to TTN's LoRaWAN Network Server:
Log in to your TTN Console
Choose the region
Click on "Go to applications"
Add application by clicking on "+ Add application"
Fill in the application information (ID, name and description)
Click "Create application"
7. Click on the "+ Add end device" button:
8. Set the parameters as the following GIF shows (click on it to open in another tab):
Band/region
LoRAWAN version
DevEui
AppEui
9. Click on "Payload formatters" → "Uplink"
10. select "Custom Javascript formatter"
11. Delete all the code at "Formatter code" and Paste the following code:
function decodeUplink(input) {
var payload = {};
payload = buildPayload(input.bytes, input.fPort);
return {
data: payload,
warnings: [],
errors: []
};
}
function buildPayload(bytes, port){
var payload = buildCommonPayload(bytes, port);
let callables =
{
1:payload,
2:locationHandler(bytes, payload),
3:payload["status"]["context"]["error"] = noLocationHandler(bytes, payload)
};
callables[port];
return payload;
}
function buildCommonPayload(_bytes, _port)
{
var payload = {};
var _deviceStatus = _bytes[0];
var _temperature = _bytes[1];
var _ACKAndBatteryVoltage = _bytes[2];
var _operationMode = _deviceStatus & 0x3;//bit0~1
var _batteryStatus = _deviceStatus & 0x4;//bi2
var _motionState = _deviceStatus & (1 << 4);//bit5
//correction for the sign
if(_temperature > 128){_temperature -= 256;}
var _ACK = _ACKAndBatteryVoltage & 0xF;
var _batteryVoltage = ((_ACKAndBatteryVoltage & 0xF0)>>4)*0.1 + 2.2;
var payloadType;
if(_port == 0x1){payloadType = "heartbeat-payload";}
else if(_port == 0x2){payloadType = "location-fixed-payload";}
else if(_port == 0x3){payloadType = "no-location-fixed-payload";}
payload = {
"temperature":{
"value":_temperature
},
"battery-voltage":{
"value":_batteryVoltage
},
"status": {
"value":_port,
"context":{
"payload-type":payloadType,
"battery-status":_batteryStatus,
"operation-mode":_operationMode,
"motion-status":_motionState,
"error":"none"
}
},
};
return payload;
}
function noLocationHandler(bytes)
{
const ERROR_MESSAGES = {
0: "WIFI positioning time not enough",
1: "WIFI position strategies timeout",
2: "WIFI module is not detected",
3: "BlueTooth positioning time not enough",
4: "BlueTooth position strategies timeout",
5: "BlueTooth broadcasting in progress",
6: "GPS position time budget over",
7: "GPS coarse positioning timeout",
8: "GPS fine positioning timeout",
9: "GPS position time is not enough",
10: "GPS aiding positioning timeout",
11: "GPS cold start positioning timeout",
12: "Interrupted by downlink for position",
13: "Interrupted positioning at start of movement"
}
return ERROR_MESSAGES[bytes[3]];
}
function timeStampParser(bytes)
{
var timeStamp = 0;
var years = bytes[4] << 8 | bytes[5] << 0;
var months = bytes[6] - 1;
var days = bytes[7];
var hours = bytes[8];
var minutes = bytes[9];
var seconds = bytes[10];
var timezone = bytes[11];
timeStamp = (Date.UTC(years, months, days, hours, minutes, seconds));
if(timezone > 128)
{
timezone = timezone -256;
timeStamp = timeStamp + timezone * (-1) * 60 * 60 * 1000;
}
else
{
timeStamp = timeStamp - timezone * 60 * 60 * 1000;
}
return timeStamp;
}
function coordinatesParser(coordinate)
{
//2147483648=0x80000000
//4294967296=0x100000000
if(coordinate > 2147483648){coordinate -= 4294967296};
coordinate /= 10000000;
return coordinate;
}
function locationHandler(bytes, payload)
{
var fixedType;
var positioningType = bytes[3];
var timeStamp = 0;
timeStamp = timeStampParser(bytes);
if(positioningType === 0x00){fixedType = "Wifi";}
else if(positioningType == 0x01){fixedType = "BlueTooth";}
else if(positioningType == 0x02){fixedType = "GPS";}
else
{
payload["status"]["context"]["error"] = "invalid positioning value";
return;
}
Object.assign(payload.temperature, {"context": {"timestamp": timeStamp}});
Object.assign(payload["battery-voltage"], {"context": {"timestamp": timeStamp}});
Object.assign(payload["status"]["context"], {"timestamp": timeStamp});
if(positioningType == 0x02)
{
var lat = (bytes[13]<< 24 | bytes[14]<< 16 | bytes[15]<< 8 | bytes[16]<< 0);
var lng = (bytes[17]<< 24 | bytes[18]<< 16 | bytes[19]<< 8 | bytes[20]<< 0);
lat = coordinatesParser(lat);
lng = coordinatesParser(lng);
var positionPayload = {
"position":{
"value":1,
"timestamp":timeStamp,
"context":{
"lat":lat,
"lng":lng,
"fixed-type":"GPS",
}
},
};
Object.assign(payload, positionPayload);
}
}
3. Set up Ubidots Integration
1. Go to your Ubidots account's Plugins section
2. Create a new "The Things Stack" integration.
3. Click on the Plugin
4. Search for its "Decoder" section
5. Copy the plugin's "HTTPs Endpoint URL"
6. Head back to your TTN application
7. On the left side of the screen look for "Integrations" → "Webhooks"
8. Choose "Custom webhook"
9. Edit the following settings:
Fill the "Webhook ID" with the desired label for it
Set "Base URL:" to https://dataplugin.ubidots.com
Click on "Add header entry" and type "X-Auth-Token" followed by your token on the next text field
Click on "Add header entry" and type "Content-Type" followed by "application/json" in the next text field
Mark the checkbox under "Uplink message"
Paste the part of your plugin's HTTP endpoint URL after the "/api....". E.g., "/api/web-hook/....."
It should look like this:
4. Visualizing Data on Ubidots
Head to your Ubidots account on the "Devices" section, there you'll be able to see a newly created device with data being ingested.
5. Troubleshooting
If you are constantly getting "no-location-fixed" feedback from the device, you can try the following:
Turn off your device and turn it back on in order to make the device discoverable by Bluetooth. Then, use the mobile app to access the device's settings as described in the first section. Then, head over to the "POSITION" tab as illustrated below:
Once there, you'll see the "GPS Fix" option.
Tap on "GPS Fix" to change the configuration parameter. First, you can try modifying the "Time Budget" by setting it to a larger period. Use 76200 s and hit the save button at the upper right corner in order to save the changes.
If this doesn't fix the problem, you can try changing the "Fine Timeout" as depicted below.
6. Feedback, Suggestions and Related Articles
Feel free to post questions or suggestions in our community portal, or contact us via support@ubidots.com.
Other users also found helpful...