I am building an application in node-red for my SODAQ tracker device.
So far I succeeded in sending a twitter message with my device location.
I want to extend the twitter message with RSSI and ID of the LoRaWan which is receiving my device messages.
I can not find the right settings for the ttn device / ttn message in node-red to accomplish this. I am not sure if this is the right way to do this. Can somebody put me on the right track to make this happen.
The purpose of my application is testing the coverage of the network in the Eindhoven region with a mobile device.
Which version of the library are you using? The MQTT format changed for production (v2), so using some staging (v1) version might not expose the meta data?
To see what version is installed:
cd $HOME/.node-red
npm list node-red-contrib-ttn
Today, the current version is 2.0.1.
Meanwhile, in 2019, the support and maintenance for this SDK has been discontinued, it is not recommended to use the SDK for new projects.
(Also, see https://ttnmapper.org.)
Hi Arjan,
I’m using the 2.0.1 version of node-red-contrib-ttn
I don’t know what to fill in for ‘event’ or ‘field’ in the ttn-device or ttn-message to get the meta data value out the input node block for e.g. the RSSI.
for tty-device the only thing that works as event is “activations”
But maybe I’m completely wrong and missing the point.
Just started with TTN two weeks ago and with the device and gate-way already running not too bad I would say. Only the SW knowledge is lacking.
For me, a ttn message
node with just a configuration for the app, gets me an object that includes metadata
, which includes gateways
. Simply connecting a ttn message
node with a debug
node, and setting the latter to log complete msg object
gives me all the details in the debug panel.
By the way: using a standard Node-RED mqtt
input node is much easier, I feel…
For ttn device
nodes the TTN Node-RED Quick Start links to “and other device events”, which I guess translates to:
- down/scheduled
- down/sent
- down/acks
- up/errors
- down/errors
- activations/errors
I’ve tested a few from the list. Indeed, for example down/scheduled
, down/sent
and down/errors
work for me, but wildcards such as #
or down/+
are not allowed, and just errors
shows no results even when down/errors
gets an event:
To test down/errors
: in TTN Console go to the device and schedule a downlink of type “fields”, entering something like {"foo": "bar"}
without providing an encoder payload function. When the downlink is to be sent (after an uplink was received) this will throw “Downlink Payload not valid: fields supplied, but no Encoder function set”. To get rid of that error, just schedule another downlink of type “bytes” and enter something like 00
.
Finally… Beware that you might need to upgrade Node-RED. The “App” field should be a dropdown, and it needs to show a pencil icon to the right. Older versions might show just a text field, but it does not suffice to just enter some text in the “App” field.
The above screenshots are no longer valid for later releases of the TTN’s Node-RED library. Read on!
Thanks Arjan, I now have meta data in node-red. Next step is making a function that combines the specific metadata and pay load fields to a twitter message.
Thanks for the other info too. I will have a look into ttnmapper.org and will register my SODAQ device and fill in some blank spots.
Solution:
“ttn message” (node block)
“function” block with return “msg.metadata”
“debug” block with for instance “msg.frequency”
This show the ‘frequency’ meta data in the debug window
1/30/2017, 10:33:55 PMnode: df2f9ca1.3092d
msg.frequency : number
868.1
useful tip. thank you
Note that you’d get multiple gateways in your meta data if the node’s packets were received by multiple.
You can also use the function block to return the data just as you want it. Like:
// Just a helper variable to use below
var gateways = msg.metadata.gateways;
return {
// Assuming the TTN Payload Functions decode some bytes from the node
// into a "location" in the output:
mylocation: msg.payload_fields.location,
// Some fields from the metadata
freq: msg.metadata.frequency,
cr: msg.metadata.cr,
dr: msg.metadata.dr,
// Combine RSSI and SNR of all gateways into two arrays:
rssi: gateways.map(gw => gw.rssi),
snr: gateways.map(gw => gw.snr),
// ...or: get an array with an object for each gateway:
gateways: gateways.map(gw => {
return {
location: {
lat: gw.latitude,
lng: gw.longitude
},
rssi: gw.rssi,
snr: gw.snr
}
})
};
When printing “complete msg object” in a debug node, you’d then get something like:
{
"mylocation": {
"lat": -33.8688,
"lng": 151.2092
},
"freq": 868.1,
"rssi": [-36, -45],
"snr": [9, 9],
"gateways": [
{
"id": "eui-b827ebffff5fe05c",
"location": {
"lat": 52.12345,
"lng": 4.12345
},
"rssi": -36,
"snr": 9
},
{
"id": "eui-5ccf7ff42f1970ec",
"location": {
"lat": 52.54321,
"lng": 4.54321
},
"rssi": -45,
"snr": 9
}
]
}
Or to get a msg.payload
for a Node-RED Twitter input:
var gateways = msg.metadata.gateways;
msg.payload = "Received by "
+ gateways.length
+ " gateway(s), with RSSIs "
+ gateways.map(gw => gw.rssi).join(", ")
+ " and SNRs "
+ gateways.map(gw => gw.snr).join(", ")
;
return msg;
…to get
Received by 2 gateway(s), with RSSIs -38, -44 and SNRs 9, 9
Works great, see below !
Thanks for making the story complete.
brandevoort IoT @brandevoort_eu 24s25 seconds ago
More
Received by 1 gateway(s), with RSSIs -49 and SNRs 7.8
Nice. If you want to get rid of the plural thing when not needed, then:
// Just some helpers
var gateways = msg.metadata.gateways;
var count = gateways.length;
var s = count === 1 ? "" : "s";
var rssi = gateways.map(gw => gw.rssi).join(", ");
var snr = gateways.map(gw => gw.snr).join(", ");
msg.payload =
"Received by " + count + " gateway" + s +
", with RSSI" + s + " " + rssi +
" and SNR" + s + " " + snr;
msg.payload =
`Received by ${count} gateway${s}, with RSSI${s} ${rssi} and SNR${s} ${snr}`;
This is gold-plating but good for learning
I end up with the following twitter message :
brandevoort IoT @brandevoort_eu 34s34 seconds ago
Object position : 51.4571686 , 5.6171753
Gateway ID : eui-b827ebfffe517647
RSSI=-48 SNR=9.8
I still have to catch a second gateway to see what it looks like in “plural” mode
Hi @arjanvanb and @mvbakel,
I have been reading through this post and the node-red quick start as well.
I finally made the flow as shown below.
But when I inject the time stamp, it shows
22/08/2017, 19:40:32node: function
msg : Object
object
_msgid: "8cd2f01e.744d4"
topic: ""
payload: 1494689048489
Can you please let me know what I am doing wrong.
Regards,
Sid
My flow is :
[{“id”:“f2a8dc4b.63b01”,“type”:“ttn message”,“z”:“ba1baf4e.520de”,“name”:"",“app”:“9a11302e.19f89”,“dev_id”:“sidsfirstdevice”,“field”:"",“x”:256,“y”:212,“wires”:[[“9f122e7e.f7cfc”]]},{“id”:“a86ec9a1.145318”,“type”:“debug”,“z”:“ba1baf4e.520de”,“name”:“device”,“active”:true,“console”:“false”,“complete”:“true”,“x”:511,“y”:124,“wires”:[]},{“id”:“d53d0a4b.c61a18”,“type”:“ttn send”,“z”:“ba1baf4e.520de”,“name”:"",“app”:“9a11302e.19f89”,“dev_id”:“sidsfirstdevice”,“port”:“1”,“x”:550,“y”:386,“wires”:[]},{“id”:“b62e1981.26e528”,“type”:“ttn device”,“z”:“ba1baf4e.520de”,“name”:"",“app”:“9a11302e.19f89”,“dev_id”:“sidsfirstdevice”,“event”:“activations”,“x”:249,“y”:124,“wires”:[[“a86ec9a1.145318”]]},{“id”:“9f122e7e.f7cfc”,“type”:“debug”,“z”:“ba1baf4e.520de”,“name”:“message”,“active”:true,“console”:“false”,“complete”:“true”,“x”:507,“y”:218,“wires”:[]},{“id”:“f3454569.753e38”,“type”:“debug”,“z”:“ba1baf4e.520de”,“name”:“function”,“active”:true,“console”:“false”,“complete”:“true”,“x”:551,“y”:303,“wires”:[]},{“id”:“4549c7c1.fa3508”,“type”:“inject”,“z”:“ba1baf4e.520de”,“name”:"",“topic”:"",“payload”:"",“payloadType”:“date”,“repeat”:"",“crontab”:"",“once”:false,“x”:188,“y”:324,“wires”:[[“d53d0a4b.c61a18”,“f3454569.753e38”]]},{“id”:“9a11302e.19f89”,“type”:“ttn app”,“z”:“ba1baf4e.520de”,“appId”:“sidsfirstapplication”,“region”:“se”,“accessKey”:“ttn-account-v2.R7yqoOfazcI7IWHgMCVmeOM8tXI9mC7QwcE6H2VYCtg”}]
I am loging the messages from my ttn node running the cayenneLPP sketch to a local file on my desktop computer using NodeRed. This works using the following NodeRed flow:
I would like to have the timestamp out of the metadate which i obtained with the following code in the function node:
return {
//Some fields from the metadata
time: msg.metadata.time };
to be logged with the payload. How can I convert the time metadata to be a payload type and combine it so that I get one line log entries with timestamp first followed by the payload. Everything I tried was not successful…
Can somebody give me a hint?
Yes, thanks, but SPLIT only works on the payload part of the message and my extracted time from metadata is not payload… I do not see how split and join would help eafter looking at the example but I am a nodered newbie
deleted…