Hex to Base64 function

The project I am working on requires me to set the ID and channel data of a device.
Both are in HEX, I managed to get the ID data working fine but the channel data is an issue
becaue its a 16bit hex value

0x00FF,0x0000,0x0000,0x0000,0x0000,0x0000
Node Red is viving me "/wAAAAAA"
And it should be "AP8AAAAAAAAAAAAA"

This is how im doing it in the function

let buff = new Buffer([0x00FF,0x0000,0x0000,0x0000,0x0000,0x0000]);
let base64data = buff.toString('base64');
msg.payload.data = base64data;

Im assuming the reason for this is that the buffer is only 8bit and it needs to be 16bit?

Hi @vangalvin

Couple of points...

  • You cannot initialise a Buffer with 16 bit data.
    • as you suspected, it is truncating your integers to bytes
  • Also, new Buffer is depreciated (so wont work in the future anyhow)
    • use Buffer.from(...) instead.

So two ways:

1: You can iterate the 16 bit data and write it to a buffer using the buffer functions e.g. buf.writeUInt16LE() then call toString("base64").

2: Alternatively, you could use a Uint16Array as an intermediate variable for conversion ...

var data = [0x00FF,0x0000,0x0000,0x0000,0x0000,0x0000];
var arr = new Uint16Array(data);
var buf = Buffer.from(arr.buffer);
buf.swap16();
msg.payload = {
    srcData: data,
    asBuffer: buf,
    asBase64: buf.toString("base64")
}
return msg;

image

1 Like

That works a treat thanks!
Is there a way to concatinate the buffer as well?

Initially I was going to allow each part to be set indavidually, Like the devEui and appEui but thinking about it this would end up being a pain.

var devEui = [0x32, 0x42, 0x33, 0x00, 0x00, 0x88, 0x88, 0x06];
var appEui = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00];
var appKey = [0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x66, 0x01];
var data = [0x00FF,0x0000,0x0000,0x0000,0x0000,0x0000];

var arr = new Uint16Array(data);
var buf = Buffer.from(arr.buffer);

buf.swap16();
msg.payload = {
    srcData: data,
    asBuffer: buf,
    asBase64: buf.toString("base64")
}
return msg;

The output should end up something like
MkIzAACIiAYAAAAAAAAAAIiIiIiIiIiIiIiIiIiIZgEA/wAAAAAAAAAAAAA=

Or would I be better off sending them in seperate packets?

Sure see the buffer documentation

var devEui = Buffer.from( [0x32, 0x42, 0x33, 0x00, 0x00, 0x88, 0x88, 0x06] );
var appEui = Buffer.from( [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] );
var appKey = Buffer.from( [0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x66, 0x01] );

var data = [0x00FF,0x0000,0x0000,0x0000,0x0000,0x0000];
var arr = new Uint16Array(data);
var buf = Buffer.from(arr.buffer);
buf.swap16();

const totalLength = buf.length + devEui.length + appEui.length + appKey.length;

var finalBuffer = Buffer.concat([devEui, appEui, appKey, buf], totalLength);

msg.payload = {
    srcData: data,
    asBuffer: buf,
    asBase64: buf.toString("base64"),
    finalBuffer: finalBuffer,
    finalBufferB64: finalBuffer.toString("base64")
}
return msg;

2 Likes

Awesome, thanks for that and I see what i was doing wrong when i tried to do it..
var finalBuffer = Buffer.concat([devEui, appEui, appKey, buf], totalLength);

not the way I was trying to do it. :slight_smile:
var finalBuffer = Buffer.concat(devEui, appEui, appKey, buf);

Now I just have to hope the data rates are up to the task. If the radio drops below DR3 they its limited to 51 bytes :frowning:

Thanks you so much for you help with this
:

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.