Home > OS >  conversion of Byte array to 320 bits and then bit extraction 16 bits then 10 bits
conversion of Byte array to 320 bits and then bit extraction 16 bits then 10 bits

Time:12-12

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.

  • Related