Where is the Mdot-box data (temp, press,light,etc... )?


#1

Hello, it is my first post:
I have installed Loraserver system, and I have connected the MDOT-BOX with MUlTECH conduit (forward mode) with LoraServer system (lora-gateway, lora-app-server,loraServer).

I have also connected mosquitto topic with the command: “mosquitto_sub -v -t “application/3/node/008000000000XXXX/rx” -v -u someuser -P somepassword”.
This command provides the following information:

“application/3/node/008000000000db13/rx {“applicationID”:“3",“applicationName”:“Lantia_App”,“deviceName”:“MDOT-BOX”,“devEUI”:“008000000000db13",“rxInfo”:[{“mac”:“00800000a000060e”,“rssi”:-24,“loRaSNR”:11.8,“name”:“00800000a000060e”,“latitude”:0,“longitude”:0,“altitude”:0}],“txInfo”:{“frequency”:868300000,“dataRate”:{“modulation”:“LORA”,“bandwidth”:125,“spreadFactor”:12},“adr”:false,“codeRate”:“4/5"},“fCnt”:206,“fPort”:1,“data”:“Dgb/DggGTPEFA24LAZ0=“}”

For each JSON generated by Mosquitto, I have decripted it with Lora-packet and got this:


decoding from Base64: Dgb/DggGTPEFA24LAZ0=
Decoded packet

      Message Type = Join Request
        PHYPayload = 0E06FF0E08064CF105036E0B019D

    ( PHYPayload = AppEUI[8] | DevEUI[8] | DevNonce[2] | MIC[4] )
            AppEUI = 05F14C06080EFF06
            DevEUI = 9D010B6E03
          DevNonce =
               MIC = 6E0B019D

application/3/node/008000000000db13/rx {“applicationID”:“3”,“applicationName”:“Lantia_App”,“deviceName”:“MDOT-BOX”,“devEUI”:“008000000000db13”,“rxInfo”:[{“mac”:“00800000a000060e”,“rssi”:-24,“loRaSNR”:8.8,“name”:“00800000a000060e”,“latitude”:0,“longitude”:0,“altitude”:0}],“txInfo”:{“frequency”:868500000,“dataRate”:{“modulation”:“LORA”,“bandwidth”:125,“spreadFactor”:12},“adr”:false,“codeRate”:“4/5”},“fCnt”:207,“fPort”:1,“data”:“Dgb/DggGTOsFA4gLAZ0=“}

decoding from Base64: Dgb/DggGTOsFA4gLAZ0=
Decoded packet

      Message Type = Join Request
        PHYPayload = 0E06FF0E08064CEB0503880B019D

    ( PHYPayload = AppEUI[8] | DevEUI[8] | DevNonce[2] | MIC[4] )
            AppEUI = 05EB4C06080EFF06
            DevEUI = 9D010B8803
          DevNonce =
               MIC = 880B019D

application/3/node/008000000000db13/rx {“applicationID”:“3",“applicationName”:“Lantia_App”,“deviceName”:“MDOT-BOX”,“devEUI”:“008000000000db13",“rxInfo”:[{“mac”:“00800000a000060e”,“rssi”:-24,“loRaSNR”:12.2,“name”:“00800000a000060e”,“latitude”:0,“longitude”:0,“altitude”:0}],“txInfo”:{“frequency”:868300000,“dataRate”:{“modulation”:“LORA”,“bandwidth”:125,“spreadFactor”:12},“adr”:false,“codeRate”:“4/5"},“fCnt”:208,“fPort”:1,“data”:“Dgb/DggGTNkFA48LAZ0=“}
decoding from Base64: Dgb/DggGTNkFA48LAZ0=
Decoded packet

      Message Type = Join Request
        PHYPayload = 0E06FF0E08064CD905038F0B019D

    ( PHYPayload = AppEUI[8] | DevEUI[8] | DevNonce[2] | MIC[4] )
            AppEUI = 05D94C06080EFF06
            DevEUI = 9D010B8F03
          DevNonce =
               MIC = 8F0B019D

All the Json messages are JoinRequest type.

I would want to get the MDOT sensor data, i. e., temperature, pression, light, gps, but I don´t know how do this.

Best regard
Antonio


#2

It is in the base64 encoded data field of the ...../rx topic. You need to decode the base64 encoded payload to bytes and then decode these based on the encoding of the mDot temperature, press ion, light, gps, … Please refer to the the MDot box documentation for the encoding of these fields.


#3

Sorry, I would like to explain it better.

This is the message I got from MDOT-BOX:

application/3/node/008000000000db13/rx {“applicationID”:“3",“applicationName”:“Lantia_App”,“deviceName”:“MDOT-BOX”,“devEUI”:“008000000000db13",“rxInfo”:[{“mac”:“00800000a000060e”,“rssi”:-24,“loRaSNR”:12.2,“name”:“00800000a000060e”,“latitude”:0,“longitude”:0,“altitude”:0}],“txInfo”:{“frequency”:868300000,“dataRate”:{“modulation”:“LORA”,“bandwidth”:125,“spreadFactor”:12},“adr”:false,“codeRate”:“4/5"},“fCnt”:208,“fPort”:1,“data”:“Dgb/DggGTNkFA48LAZ0=“}

I select the “data” field, that is: “Dgb/DggGTNkFA48LAZ0=” from “”data”:“Dgb/DggGTNkFA48LAZ0=”
and apply this decrypter “https://lorawan-packet-decoder-0ta6puiniaut.runkit.sh.”

That site returns me this:

Message Type = Join Request
AppEUI = 0500000008000000
DevEUI = 0E020B0000
DevNonce =
MIC = 000B020E

The payload always is Join Request type. Should I send a downlink message to Mdot in order to accept the connection ?


#4

The data field is not a LoRaWAN frame. It contains the decrypted FRMPayload field of a LoRaWAN frame, thus the payload sent by your mDot. I don’t think that the https://lorawan-packet-decoder-0ta6puiniaut.runkit.sh decoder knows anything about how to decode this back to temp, gps, etc… For this you need to refer to the documentation of the mDot box.


#5

With the mDot you configure your own data packet structure when you program it using the Mbed software.

For example in my program, after I join the network this is how I send data from a tank level sensor and battery voltage reading:

    uint16_t tank = TankPin.read_u16();
    tx_data.push_back((tank >> 8) & 0xFF);
    tx_data.push_back(tank & 0xFF);

    uint16_t battery = BatPin.read_u16();
    tx_data.push_back((battery >> 8) & 0xFF);
    tx_data.push_back(battery & 0xFF);
    logInfo("bat: %lu [0x%04X] tank: %lu [0x%04X]", battery, battery, tank, tank);

Then in Node-red to decompile this message I use:

//extract Mdot info
var raw_tank_lvl = parseInt(msg.data.substring(0,4), 16); 
var raw_battery = parseInt(msg.data.substring(4,8), 16);

//apply scaling factor, round to integer
var tank_lvl = Math.round((raw_tank_lvl-12770)/203);  //12850 = 0%, 33175 = 100%, ~203 per %     
var battery = Math.round((raw_battery/5142.58)*100); //5142.58 per volt, x 100 to round to 2 decimal places when passing ints\n\n    

//setup node-red messages
msgBat = {};
msgBat.payload = {};
msgBat.payload.value = [battery];
msgLvl = {}; 
msgLvl.payload = {};
msgLvl.payload.value = [tank_lvl];

Hope this helps


#6

i have succesfuly decoded the data from the MBOX using the following functions in the:
Organizations > LoRa Server > Applications > Application configuration > Payload decoder function:

function Decode(fPort, bytes) {
var s =‘0x’;
bytes.forEach(function(byte) {
s += (‘0’ + (byte & 0xFF).toString(16)).slice(-2);
});

  string=autoCase(s);

return string;

}

function autoCase(hex){

if (hex.substr(0,2)==‘0x’){
new_hex=preatyHex(hex);
}
else {
new_hex=hex;
}
console.log(new_hex);

// console.log(new_hex.substr(0,2)==00);
// console.log(new_hex.substr(4,2)==00);

hexLength=new_hex.length;
// console.log(new_hex.substr(hexLength-2,2));

// console.log(hexLength);

if (hexLength ==28 && new_hex.substr(0,2)==‘0e’) {
console.log(‘LoraDemo’)
string=DecodeLoraDemo(new_hex);

}
else if ((new_hex.substr(0,2)==‘1d’ && new_hex.substr(hexLength-2,2)==‘1d’) && hexLength>=26) {
console.log(‘SurveySweep’)
string=DecodeSurveySweep(new_hex);
}

else if (hexLength>=22 && (new_hex.substr(0,2)==‘00’ && new_hex.substr(4,2)==‘00’)){
console.log(‘SurveyGPS’)

  // new_hex=new_hex+'00000000000000000000';
  string=DecodeSurveyGPS(new_hex);

}

return string;
}

function DecodeLoraDemo(hex){

var xAc=parseInt(hex.substr(2,2),16)*0.0625;
var yAc=parseInt(hex.substr(4,2),16)*0.0625;
var zAc=parseInt(hex.substr(6,2),16)*0.0625;
var presure=parseInt(hex.substr(10,6),16)*0.25/1000;
var lux=parseInt(hex.substr(18,4),16)*0.25;
var temperature=parseInt(hex.substr(24,4),16)*0.0625;

return {“acceleration_X”:xAc, “acceleration_Y”:yAc, “acceleration_Z”:zAc, “presure”:presure, “lux”:lux,“temperature”:temperature}
}

function DecodeSurveyGPS(hex){

var temperature=parseInt(hex.substr(2,2),16);
var lat=parseInt(hex.substr(6,8),16)/(Math.pow(2,31)-1)*90;
var long=parseInt(hex.substr(14,8),16)/(Math.pow(2,31)-1)*180;

if (long > 180) {
long=(360-long)*(-1)
}
return {“temperature”:temperature, “LatitudeGPS”:lat, “LongitudeGPS”:long}
}

function DecodeSurveySweep (hex){

var QosUpLink = hex.substr(2,10); //4 bytes
var NumberOfGateways = parseInt(QosUpLink.substr(2,4),16);
var Margin=parseInt(QosUpLink.substr(6,2),16);
var TxPower=parseInt(QosUpLink.substr(8,2),16);

var QosDownLink = hex.substr(12,8); //3 bytes
var RSSI=parseInt(QosDownLink.substr(2,4),16);
var SNR=parseInt(QosDownLink.substr(6,2),16);

var LockStatus =parseInt(hex.substr(22,2),16).toString(2); //1 byte
var gpsStatus=checkgpsStatus(LockStatus.substr(0,4));
var numberOfSatelit = parseInt(LockStatus.substr(4,4),2);

var LatitudeGPS = hex.substr(24,10); //4 bytes
var LongitudeGPS =hex.substr(34,12); //5 bytes

return {“10_qosUpLink”: QosUpLink,
“11_numberOfGateways”: NumberOfGateways,
“12_margin”: Margin,
“13_txPower”: TxPower,
“20_qosDownLink”: QosDownLink,
“21_rSSI”: RSSI,
“22_SNR”: SNR,
“30_LockStatus”: LockStatus,
“31_gpsStatus”: gpsStatus,
“32_numberOfSatelit”: numberOfSatelit,
“40_LatitudeGPS”: LatitudeGPS,
“50_LongitudeGPS”: LongitudeGPS}
}

function checkgpsStatus(byteString){
/**
0 No GPS device detected.
1 No fix
2 2D fix – only latitude, longitude, and time are valid
3 3D fix – all data valid

ex: 1100
**/

resultat=’’;

if (byteString.substr(0,1)==0){
resultat += 'No GPS device detected, ';
}
else if (byteString.substr(0,1)==1){
resultat += 'GPS device detected, ';
}

if (byteString.substr(1,1)==1){
resultat += 'No Fix ';
}
else if (byteString.substr(2,1)==1) {
resultat += '2DFix ';
}
else if (byteString.substr(3,1)==1) {
resultat += '3DFix ';
}

return resultat;
}

function preatyHex(hex){
if (hex.substr(0,2)==‘0x’){
hex=hex.substr(2,hex.length);
}
return hex;
}

best regards