Open aruznieto opened 1 year ago
You have in the developper documentation all the information about uplink & downlink payload to manage the computations in your backend connected to ChirpStack. I'm not against an integration with ChirpStack in my backend to make the computation but I do not have any ChripStack instances available for making test.
Ok, I will test it, and If it works, I'll let you know
Hi, it works perfectly on ChirpStack, and the Codec too (only needs change "Decoder" to "Decode").
I have a question, the device is programed to send Downlink Power to Gateaway at any time?
good to know. downlink device RSSI is not sent to gateway, it's calculated by the device (if it is your question) uplink gateway RSSI is sent to server and returned to device I recommand to read the documentation where all of this has been detailed.
@aruznieto nice, so you've done all stuff only on chirpstack side, right? if so are you sending downlink? Would love to see your decoder/encoder shared :-)
Hi @hallard, I only the encoder (it's exactly the same that you can see in the DEVELOPMENT.md) removing const
from maxHdop
and minstats
function Decode(fPort, bytes, variables) {
var decoded = {};
// avoid sending Downlink ACK to integration (Cargo)
if (fPort === 1) {
var lonSign = (bytes[0]>>7) & 0x01 ? -1 : 1;
var latSign = (bytes[0]>>6) & 0x01 ? -1 : 1;
var encLat = ((bytes[0] & 0x3f)<<17)+
(bytes[1]<<9)+
(bytes[2]<<1)+
(bytes[3]>>7);
var encLon = ((bytes[3] & 0x7f)<<16)+
(bytes[4]<<8)+
bytes[5];
var hdop = bytes[8]/10;
var sats = bytes[9];
maxHdop = 2;
minSats = 5;
if ((hdop < maxHdop) && (sats >= minSats)) {
// Send only acceptable quality of position to mappers
decoded.latitude = latSign * (encLat * 108 + 53) / 10000000;
decoded.longitude = lonSign * (encLon * 215 + 107) / 10000000;
decoded.altitude = ((bytes[6]<<8)+bytes[7])-1000;
decoded.accuracy = (hdop*5+5)/10
decoded.hdop = hdop;
decoded.sats = sats;
} else {
decoded.error = "Need more GPS precision (hdop must be <"+maxHdop+
" & sats must be >= "+minSats+") current hdop: "+hdop+" & sats:"+sats;
}
return decoded;
}
return null;
}
I do not send downlink data but if @disk91 or somebody could share Encoder code It I could test it on ChirpStack.
thanks, I was hoping you send downlink, I know @disk91 will integrate chirpstack in his backend soon
OMG just retrieved I had prepared this job in node red, with distance calculation and gateway counts
And here the function code with data from Chirpstack (so easily transposable to Chirpstack decoder), don't ask me where I found calculation distance function, don't remember, only I had to google, but looks like not so bad :-)
Now need to finish downlink stuff
function distance(lat1, lon1, lat2, lon2) {
a1 = lat1 * Math.PI/180; // φ, λ in radians
a2 = lat2 * Math.PI/180;
d1 = (lat2-lat1) * Math.PI/180;
d2 = (lon2-lon1) * Math.PI/180;
a = Math.sin(d1/2) * Math.sin(d1/2) +
Math.cos(a1) * Math.cos(a2) *
Math.sin(d2/2) * Math.sin(d2/2);
c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
return 6371e3 * c; // in metres
}
var b = msg.payload.data;
var data = {};
var txt = "";
var color = "red";
// Get gateways array
var gws = msg.payload.rxInfo;
var minrssi = -999;
var maxrssi = +999;
// Calculate min/max RSSI
for (i=0; i<gws.length; i++) {
gw = gws[i];
if (gw.rssi < maxrssi) { maxrssi = gw.rssi; }
if (gw.rssi > minrssi) { minrssi = gw.rssi; }
}
// Only port with data
if (msg.payload.fPort == 1) {
var lonSign = (b[0]>>7) & 0x01 ? -1 : 1;
var latSign = (b[0]>>6) & 0x01 ? -1 : 1;
var encLat = ((b[0] & 0x3f)<<17)+(b[1]<<9)+(b[2]<<1)+(b[3]>>7);
var encLon = ((b[3] & 0x7f)<<16)+(b[4]<<8)+b[5];
var hdop = b[8]/10;
var sats = b[9];
const maxHdop = 2;
const minSats = 5;
data.accuracy = (hdop*5+5)/10
data.hdop = hdop;
data.sat = sats;
data.minrssi = minrssi;
data.maxrssi = maxrssi;
data.hotspot = gws.length;
txt = "Hdop="+hdop+" Sat="+sats;
// Send only acceptable quality of position to mappers
if ((hdop < maxHdop) && (sats >= minSats)) {
// Get gateways array
var mindist = 9999;
var maxdist = 0;
// Get node position
data.lat = latSign * (encLat * 108 + 53 ) / 10000000;
data.lon = lonSign * (encLon * 215 + 107) / 10000000;
data.alt = ((b[6]<<8)+b[7])-1000;
// Calculate distance between GW and node
for (i=0; i<gws.length; i++) {
gwlat = gws[i].location.latitude;
gwlon = gws[i].location.longitude;
node.warn("gwlat=" + gwlat + " gwlon=" + gwlon);
dist = distance(data.lat,data.lon,gwlat, gwlon);
node.warn("distance=" + dist);
if (dist>maxdist) {maxdist=dist;}
if (dist<mindist) {mindist=dist;}
}
data.mindist = Number(mindist.toFixed(0));
data.maxdist = Number(maxdist.toFixed(0));
color ="green";
}
msg.payload = data;
} else if (msg.payload.fPort == 2) {
txt = "Request downlink";
color = "green";
msg = null;
}
node.status({fill: color,text: txt});
return msg;
For the distance you are using "Harvesine Function", this it would be the Encoder function or you mix both?
For now only for decoding going to my dashboard, but will use these calculated data to send thru downlink according @disk91 documentation ASAP
Ah! Ok, I calculate the distance after with Python because I need to analyze other parameters too.
and here the working downlink (my node red specific but easy to adapt)
var data = Buffer.alloc(6);
data[0] = msg.fc & 0xFF; // Frame Counter
data[1] = msg.payload.minrssi + 200;
data[2] = msg.payload.maxrssi + 200;
data[3] = (msg.payload.maxdist/250).toFixed(0);
data[4] = (msg.payload.mindist/250).toFixed(0);
data[5] = msg.payload.hotspot;
var newMsg = {}
newMsg.payload = {
"confirmed": false,
"fPort": 2,
"data": Buffer.from(data,'hex').toString('base64')
}
newMsg.topic = msg.topicbase + "/command/down"
return newMsg;
works like a charm, special mention to @disk91, I feel so stupid not seeing sequenceID, because it's just frame count.
Hi, WioLoRaWANFieldTester can be configurated on ChirpStack and get GPS data on this software?