/// state object to handle per-device registers and its acks
// confirm downlink is received on the device state
function confirmDownlink(device){
if(!state.hasOwnProperty(device)) return;
let toAck = state[device].toAck;
if(toAck===undefined) return;
// initialize acks if not already defined
if(state[device].ack===undefined) state[device].ack = {};
state[device].ack[key] = toAck[key];
// clear pending elements
delete state[device].toAck;
// selects the registers that are required to send
function getRegistersToSend(device, target){
if(!state.hasOwnProperty(device)) return target;
let current = state[device].ack;
if(!current) return target;
for (var key in target) {
if(!current.hasOwnProperty(key)){
modified[key] = target[key];
}else if(current[key]!==target[key]){
modified[key] = target[key];
// convert JSON device downlink data to register configuration
function getRegistersConfig(payload){
// should return an object with register number & its value
// uplink method definition
module.exports.uplink = function(payload, meta){
let deviceId = meta.device;
if(payload==="15"|| payload==="16"){
confirmDownlink(deviceId);
// return undefined so nothing is stored in bucket
// normal payload procesing here
// downlink method definition
module.exports.downlink = function(payload, meta){
let deviceId = meta.device;
let deviceRegisters = getRegistersConfig(payload);
let changedRegisters = getRegistersToSend(deviceId, deviceRegisters);
// compute registers to send and its order
let registers = Object.keys(changedRegisters);
// ascending -> device will request more
registers = registers.sort().slice(0,4);
// desdencing -> no more downlinks
registers = registers.sort().reverse();
// init toAck state on device
if(!state.hasOwnProperty(deviceId)) state[deviceId] = {};
state[deviceId].toAck = {};
// generate downlink output
let bytes = [], written = 0;
registers.forEach(function(v) {
// write register number and its value
bytes[written++] = parseInt(v, 16);
bytes[written++] = changedRegisters[v];
// add register to pending ack
state[deviceId].toAck[v] = changedRegisters[v];
// convert buffer to hex for sigfox processing
return Buffer.from(bytes).toString('hex');