i am hoping some clever people here would be able to help me , i am new to JavaScript and trying to figure out how to code the following as i get stuck when the payload string is not standard 8 bit 1 byte groups, so i receive 320 bit 40 byte array. the first few values are fine to extract as they are 16 bits , then 8 bits then 32 bits of info but the next value is only 10 bits and i get stuck here. so i should probably be converting the 40 bytes into 320 bits and then shifting right for each number of bit per variable? i am not sure how to do this. This is my payload format and in brackets is the number of bits for that variable. any help would be appreciated.
https://www.iotsoundsensor.com/wp-content/uploads/2021/11/310_payload_parser_manual.html
function Decoder(bytes, port) {
//8 bit single byte values
var messageinfo = bytes[2]>>[2];
var battery = bytes[2]>>[0];
var latitude = bytes[4]>>[4];
var longatude = bytes[4]>>[4];
//now have 10 bit values to decode
var LAfast = bytes[15]>>>[0];
var LAslow = bytes[16]>>>[2];
return {
messageinfo: messageinfo,
battery: battery/10,
LAfast : LAfast/10,
LAslow : LAslow/10,
latitude: latitude,
longatude: longatude
}
}
CodePudding user response:
I've re-written the Decode()
function based on the JavaScript code at iot-source (which is really the bible for decoding these messages).
I've created a getField()
function for decoding fields at a given offset, length, and resolution and also a getBits()
function to retrieve an array of bits for later decoding (used for the LAxxx fields).
I've used the example from the page above as an input to Decode():
function hexToByteArray(hex) {
return Array.from({ length: hex.length/2}, (v,n) => parseInt(hex.slice(n * 2, n*2 2), 16));
}
function getField(offset, length, bytes, resolution = 1) {
return bytesToNum(bytes.slice(offset, offset length)) * resolution;
}
function bytesToNum(bytes) {
return bytes.reduce((acc, b, x) => acc | (b << (x * 8)), 0);
}
// Convert a byte segment to bits
function getBits(offset, length, bytes) {
return bytes.slice(offset, offset length).map((byt) => {
return Array.from({ length: 8 }).map((x, i) => {
return ((byt * (2 ** i) & 0x80) !== 0 ? 1 : 0);
});
}, []).flat();
}
function parseBits(bits) {
return bits.reduce((acc, b, i) => {
return acc 0.1*(bits[bits.length - 1 - i] ? 2**(i): 0);
}, 30);
}
function Decoder(bytes, port) {
let offset = 0;
let messageinfo = getField(offset, 2, bytes, 1);
let battery = getField(offset = 2, 1, bytes, 0.1);
// NB: We should check messageinfo to ensure these are actually present...
let latitude = getField(offset = 1, 4, bytes, 1e-7);
let longitude = getField(offset = 4, 4, bytes, 1e-7);
// Skip parsing timestamp for now...
offset = 4
let bitArray = getBits(offset = 4, 20, bytes);
let bitIndex = 0;
let LAfast = parseBits(bitArray.slice(bitIndex, bitIndex = 10));
let LAslow = parseBits(bitArray.slice(bitIndex, bitIndex = 10));
let LCfast = parseBits(bitArray.slice(bitIndex, bitIndex = 10));
let LCslow = parseBits(bitArray.slice(bitIndex, bitIndex = 10));
return {
messageinfo,
battery,
LAfast,
LAslow,
LCfast,
LCslow,
latitude,
longitude
}
}
let bytes = (hexToByteArray('7FFF3F6599341FE38C11036A608C60370DA561584699336CDB55CDB390F44BD4B5B9D5390E34BCE3'))
console.log(Decoder(bytes))
.as-console-wrapper { max-height: 100% !important; top: 0; }
CodePudding user response:
Thank you for the feedback guys.