-
-
Notifications
You must be signed in to change notification settings - Fork 207
adr: plugin_skeleton: Use the result in the comment #721
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Hi @ekaitz-zarraga, I do not think this is is an issue, the comment just contains an example of the data-structure. In your case it might have returned DR 5, but this depends on the uplink DR of your device, this has nothing to do with the skeleton. The skeleton just returns the same value as the input. |
Oh yes, you are right, but the default adr does return that. |
c0e6c98
to
f244847
Compare
But it would return that for the message of the example. We could say "for that input, the default ADR would return..." |
The input example contains |
what do you mean? I made this. I took the default algorithm, and executed it independently: export function name() {
return "JS example for default ADR algorithm";
}
export function id() {
return "js_example_default";
}
export function handle(req) {
let resp = {
dr: req.dr,
txPowerIndex: req.txPowerIndex,
nbTrans: req.nbTrans,
};
if (!req.adr) {
return resp;
}
if (req.dr > req.maxDr) {
resp.dr = req.maxDr;
}
// Set the new Nb Trans.
resp.nbTrans = getNbTrans(req.nbTrans, getPacketLossPercentage(req));
// Calculate the number of steps.
let snrMax = getMaxSnr(req);
let snrMargin = snrMax - req.requiredSnrForDr - req.installationMargin;
let nStep = Math.floor(snrMargin / 3);
// In case of negative steps the ADR algorithm will increase the TxPower
// if possible. To avoid up / down / up / down TxPower changes, wait until
// we have at least the required number of uplink history elements.
if (nStep < 0 && getHistoryCount(req) != requiredHistoryCount()) {
return resp;
}
let [desiredTxPowerIndex, desiredDr] = getIdealTxPowerIndexAndDr(
nStep,
resp.txPowerIndex,
resp.dr,
req.maxTxPowerIndex,
req.maxDr,
);
resp.dr = desiredDr;
resp.txPowerIndex = desiredTxPowerIndex;
return resp;
}
function getIdealTxPowerIndexAndDr(nbStep, txPowerIndex, dr, maxTxPowerIndex, maxDr) {
while (nbStep !== 0) {
if (nbStep > 0) {
if (dr < maxDr) {
// Increase the DR.
dr++;
} else if (txPowerIndex < maxTxPowerIndex) {
// Decrease the Tx Power.
txPowerIndex++;
}
nbStep--;
} else {
// Incease the TxPower.
if (txPowerIndex > 0) {
txPowerIndex--;
}
nbStep++;
}
}
return [txPowerIndex, dr];
}
function requiredHistoryCount() {
return 20;
}
function getHistoryCount(req) {
let count = 0;
for (let uh of req.uplinkHistory) {
if (uh.txPowerIndex === req.txPowerIndex) {
count++;
}
}
return count;
}
function getMaxSnr(req) {
let maxSnr = -999.0;
for (let uh of req.uplinkHistory) {
if (uh.maxSnr > maxSnr) {
maxSnr = uh.maxSnr;
}
}
return maxSnr;
}
function getNbTrans(currentNbTrans, pktLossRate) {
const pktLossTable = [
[1, 1, 2],
[1, 2, 3],
[2, 3, 3],
[3, 3, 3],
];
if (currentNbTrans < 1) {
currentNbTrans = 1;
}
if (currentNbTrans > 3) {
currentNbTrans = 3;
}
const nbTransIndex = currentNbTrans - 1;
if (pktLossRate < 5.0) {
return pktLossTable[0][nbTransIndex];
} else if (pktLossRate < 10.0) {
return pktLossTable[1][nbTransIndex];
} else if (pktLossRate < 30.0) {
return pktLossTable[2][nbTransIndex];
}
return pktLossTable[3][nbTransIndex];
}
function getPacketLossPercentage(req) {
if (req.uplinkHistory.length < requiredHistoryCount()) {
return 0.0;
}
let lostPackets = 0;
let previousFCnt = req.uplinkHistory[0].fCnt;
for (let uh of req.uplinkHistory.slice(1)) {
lostPackets += uh.fCnt - previousFCnt - 1;
previousFCnt = uh.fCnt;
}
return lostPackets / req.uplinkHistory.length * 100.0;
}
console.log(JSON.stringify(handle(
{
regionConfigId: "eu868",
regionCommonName: "EU868",
devEui: "0102030405060708",
macVersion: "1.0.3",
regParamsRevision: "A",
adr: true,
dr: 1,
txPowerIndex: 0,
nbTrans: 1,
maxTxPowerIndex: 15,
requiredSnrForDr: -17.5,
installationMargin: 10,
minDr: 0,
maxDr: 5,
skipFCntCheck: false,
deviceVariables: {
"varA": "value1",
"varB": "value2",
},
uplinkHistory: [
{
"fCnt": 10,
"maxSnr": 7.5,
"maxRssi": -110,
"txPowerIndex": 0,
"gatewayCount": 3
}
]
}))) That prints:
|
This is the input example:
The function is: export function handle(req) {
return {
dr: req.dr,
txPowerIndex: req.txPowerIndex,
nbTrans: req.nbTrans
};
} Thus output:
The scope of the comments is the plugin skeleton, it does not apply to the behavior of the ADR plugin you have implemented. I'm going to close this PR as I do not think the examples are wrong. They are there such that you know which fields will be available in the object and to get a sense of what data they will hold. It does not define the behavior of the codec function. That is up to how you implement the ADR algorithm. For some it might be |
👍 |
The comment of the
plugin_skeleton.js
does not happen to be what the algorithm returns for the input example. This might confuse users.This commit fixes that.