You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
100 lines
3.4 KiB
JavaScript
100 lines
3.4 KiB
JavaScript
// This is for TTNv2 (deprecated)
|
|
// configured for having no Choice of Recipient for CannedMessages
|
|
function Decoder(bytes, port) {
|
|
var data = {}
|
|
function bytesToString(a) {
|
|
return a.map(function(x){ return String.fromCharCode(x) }).join('') // because very OLD js parser
|
|
}
|
|
switch (port) {
|
|
case 1: // Technical Received Acknowledgment '|5||C|'
|
|
// 31 32 33 34 35 20
|
|
data.type = 'ack'
|
|
data.ack = 'recv'
|
|
data.msgid = bytesToString(bytes.splice(0,5))
|
|
data.rssi = bytes.splice(0,1) * 1
|
|
break;
|
|
case 2: // Read and Operational Acknowledgment 'AA|5|' and Operational '33|5|<CustomByte(s)>'
|
|
// AA 31 32 33 34 35
|
|
// operational ack with Payload "test"(maybe you should use a single byte)
|
|
// 33 31 32 33 34 35 54 65 73 74
|
|
data.type = 'ack'
|
|
data.ack = bytes.splice(0,1) == 0xAA ? 'read' : 'operational'
|
|
data.msgid = bytesToString(bytes.splice(0,5))
|
|
if (data.ack === 'operational') {
|
|
data.operationalData = bytesToString(bytes)
|
|
}
|
|
break;
|
|
case 3: // Status & Canned Messages
|
|
|
|
break;
|
|
case '4': // Battery and Power Notifications
|
|
// Startup 'FF'
|
|
// Shutdown 'EE'
|
|
// Low Battery 'FD'
|
|
// ChargingOn '|V|CC'
|
|
// ChargingOff'|V|BB'
|
|
break;
|
|
case 5: // OTAStatus + LoneWorker/SOS Trigger + GPS Tracking Port '|G|'
|
|
// GPS Tracking '|G|'
|
|
//// 00 1E 33 D7 00 4A 2C 31 10
|
|
// SOS Start 'FF|G|'
|
|
//// FF 00 1E 33 D7 00 4A 2C 31 10
|
|
// SOS End 'FE|G|'
|
|
//// FE 00 1E 33 D7 00 4A 2C 31 10
|
|
// LoneWorker Lack of movement 'FD|G|'
|
|
//// FD 00 1E 33 D7 00 4A 2C 31 10
|
|
// LoneWorker Falldetect 'FC|G|'
|
|
//// FC 00 1E 33 D7 00 4A 2C 31 10
|
|
// LoneWorker End 'FB|G|'
|
|
//// FB 00 1E 33 D7 00 4A 2C 31 10
|
|
// OTA/PagerStatus 'FA|G||V|'
|
|
//// FA 00 1E 33 D7 00 4A 2C 31 10 28
|
|
if (bytes.length !== 9) { // we have more than just the |G| block
|
|
if (bytes.length === 10) {
|
|
switch(bytes[0]) {
|
|
case 0xFF: // SOS Start
|
|
data.type = 'sos'
|
|
data.sos = true
|
|
break;
|
|
case 0xFE: // SOS End
|
|
data.type = 'sos'
|
|
data.sos = false
|
|
break;
|
|
case 0xFD: // LoneWorker Lack of movement
|
|
data.type = 'sos'
|
|
data.sos = false
|
|
data.loneworker = 'lackofmovement'
|
|
break;
|
|
case 0xFC: // LoneWorker Falldetect
|
|
data.type = 'sos'
|
|
data.sos = false
|
|
data.loneworker = 'falldetect'
|
|
break;
|
|
case 0xFB: // LoneWorker End
|
|
data.type = 'sos'
|
|
data.sos = false
|
|
data.loneworker = false
|
|
break;
|
|
}
|
|
bytes.splice(0,1)
|
|
}
|
|
if (bytes.length === 11) { // OTA PagerStatus
|
|
data.type = 'ota'
|
|
data.ota = 'status'
|
|
data.battery = bytes[10] * 1
|
|
bytes.splice(0,1)
|
|
}
|
|
} else { // we are having a normal gps block only
|
|
data.type = 'gps'
|
|
}
|
|
var gpsBlock = bytes.splice(0,9)
|
|
data.latitude = ((gpsBlock[0]<<24)>>>0) + ((gpsBlock[1]<<16)>>>0) + ((gpsBlock[2]<<8)>>>0) + gpsBlock[3]
|
|
data.latitude /= 10e4
|
|
data.longitude = ((gpsBlock[4]<<24)>>>0) + ((gpsBlock[5]<<16)>>>0) + ((gpsBlock[6]<<8)>>>0) + gpsBlock[7]
|
|
data.longitude /= 10e4
|
|
data.lastGPSAcquisition = gpsBlock[8]
|
|
break;
|
|
}
|
|
return data;
|
|
}
|