How to use "bitmap" in LoRa Serialization library?

The LoRa Serialization library lets me encode for humidity, temperature, and others, but I’m having trouble with the bitmap.

So others see the full setup for the basics that work:
–>On the Payload Formats tab, encoder, use the following (modify accordingly):

function Encoder(json, port) {
  var bytes = encode([json.humidity, json.temperature], [humidity, temperature]);
  return bytes;
}

// https://github.com/thesolarnomad/lora-serialization/blob/master/src/encoder.js
// paste the entire contents of the encoder.js below

For the JSON fields:

{"humidity": 48.2, "temperature": 24.82 }

which gives

// encoded payload:
D4 12 09 B2

For bitmap (boolean?), I’m trying the following to be able to send on/off to various functions on the node. I believe I’m not formatting the bytes variable properly in the second line:

function Encoder(json, port) {
var bytes = encode([json.bitmap], [bitmap]);  //missing something ???
  return bytes;
}

with various attempts in the fields:

{"a": false}    //outputs 00
{"a": true}     //outputs 80
{"a": true, "b": true, "c": true, "d": true, "e": true, "f": false, "g": true, "h": true}   //outputs 00

Thank you again for the help–and your time.

Actually, this one is weird. (And I cannot reproduce that; looking at the code I expect, and get, 0x00 no matter what.)

Though indeed LoRa Serialization’s decoder returns properties named a, b, and so on, its encoder expects an array of booleans. Also, it needs to know in which JSON attribute that array is passed. So, specify an array with at most 8 boolean values:

{"myFlags": [true, true, true, true, true, false, true, true]}

…along with:

function Encoder(json, port) {
  return encode([json.myFlags], [bitmap]);
}

The above nicely yields 0xFB.

The encoder cannot just assume the flags are at the top level of the JSON object, as one could also specify multiple bitmap fields:

function Encoder(json, port) {
  return encode([json.myFlags, json.otherFlags], [bitmap, bitmap]);
}

…along with:

{
  "myFlags": [true, true, true, true, true, false, true, true],
  "otherFlags": [true, true]
}

This yields 0xFBC0.

But of course, the encoder could support input that matches the output that the decoder creates. The decoder for the above encoder reads:

function Decoder(bytes, port) {
  return decode(bytes, [bitmap, bitmap], ['myFlags', 'otherFlags']);
}

…and for 0xFBC0 would yield:

{
  "myFlags": {
    "a": true,
    "b": true,
    "c": true,
    "d": true,
    "e": true,
    "f": false,
    "g": true,
    "h": true
  },
  "otherFlags": {
    "a": true,
    "b": true,
    "c": false,
    "d": false,
    "e": false,
    "f": false,
    "g": false,
    "h": false
  }
}

So, indeed the encoder and decoder are not symmetric. Not too hard to change (or to also support the named attributes rather than an array), but I’m not sure if the author has a specific reason for this?

Giving it some more thought, it’s very unlikely that a Decoder (for uplinks) and Encoder (for downlinks) need to handle the same details. No symmetry as for the JSON needed/expected at all.

And maybe returning the named a, b, c and all is just a convenience, intended for further handling. Like:

function Decoder(bytes, port) {
  var decoded = decode(bytes,
    [humidity, temperature, bitmap],
    ['h', 't', 'flags']
  );

  // Process the bitmask results
  decoded.button1 = decoded.flags.a;
  decoded.button2 = decoded.flags.b;
  decoded.alarm = decoded.flags.c;

  // suppress the "flags" attribute in the result
  delete decoded.flags;

  return decoded;
}

For 0xD41209B280 this would yield (sorted for readability):

{
  "h": 48.2,
  "t": 24.82,
  "button1": true,
  "button2": false,
  "alarm": false
}

Likewise, the encoder could do some pre-processing:

function Encoder(json, port) {
  var flags = [json.enableThis, json.enableThat];
  return encode([flags, json.threshold], [bitmap, uint8]);
}

…along with:

{"enableThis": false, "enableThat": true, "threshold": 10}

Of course, the library could go to extremes to allow for specifying the intended names for each bitmask boolean too. But it’s easily done in the Payload Formats functions instead.

2 Likes