Nice, thanks for sharing! But beware, the following won’t work for values larger than 255 seconds:
bytes[1] = object.Seconds >> 8;
bytes[2] = object.Seconds;
Unlike in, e.g., C++ where a byte can really only hold 8 bits and all other bits are simply discarded, JavaScript does not have such specific types. (Instead, everything is a floating point.) Above, bytes[2]
will hold the full value, not just limited to its 8 least significant bits. You can try with {"Control": "PERIOD", "Seconds": 300}
, which will not throw an error in the JavaScript, but TTN will still reject with Error("Encoder Output not valid: Numbers in Array should be between 0 and 255")
.
Also, it seems you need 3 bytes for the time?
So, I’d use:
// test with: {"Control": "PERIOD", "Seconds": 86400} => 01 01 51 80 (24 hours)
bytes[1] = object.Seconds >> 16;
bytes[2] = object.Seconds >> 8 & 0xFF;
bytes[3] = object.Seconds & 0xFF;
For bytes[1]
you don’t need the & 0xFF
to limit to 8 bits (as all bits in the leftmost bytes are zeroes), but it won’t harm either.
And just some notes in case you didn’t know:
You’re defaulting to zero. Probably by design, but just so you’re aware: {"Control": "DO", "DO1": 2, "DO2": "foo"}
(where DO3 is missing and the others have invalid values) will silently set all outputs to zero. If you don’t expect errors in the input, then you could simply use:
bytes[1] = object.DO1;
bytes[2] = object.DO2;
bytes[3] = object.DO3;
You can define helper functions too, either above Encoder
or within that function. Like:
// Decodes the value to either 1 or 0
function onoff(val) {
// Non-strict equals: return 1 for the number 1 or the string "1"
if (val == 1) {
return 1;
}
// Default all missing or invalid values to 0
return 0;
}
function Encoder(object, port) {
var bytes = [];
if (object.Control === "DO") {
//test with: {"Control": "DO", "DO1":1 , "DO2":1, "DO3":1} => 02 01 01 01 (where 1 = on, 0 = off)
bytes[0] = 0x02;
bytes[1] = onoff(object.DO1);
bytes[2] = onoff(object.DO2);
bytes[3] = onoff(object.DO3);
}
...
}
If you want to fail on invalid inputs then we’d need to investigate on how TTN acts on returning a null
value or on throwing an error. (TTN Console might work differently from the APIs there; not sure if there’s any documentation about that.)