lorawan-server icon indicating copy to clipboard operation
lorawan-server copied to clipboard

Unable to make a device join

Open MatthiasCAlbrecht opened this issue 4 years ago • 14 comments

Hello everyone,

I am new to the LoRaWAN technology. I have a KLAX power meter (https://iot-shop.de/produkt/klax), a Kerilink Wirnet iFemtoCell gateway and a Raspberry Pi on which I run the lorawan-server. I have set up the server and the gateway connects to my server. The device uses OTAA. I configured the device and it appears unter Activated Nodes. On the dashboard, I see incoming joins from my device. It will repeat until I get a downlinks_lost. Here you see that sequence:

Last Occurred Entity Eid Text Args
2020-01-31 22:53:45 gateway 7276FF00390404A0 downlinks_lost 1
2020-01-31 22:53:45 node 022CDE41 repeated_reset 33
2020-01-31 22:53:45 device BC9740FFFE1065FB join <<"022CDE41">>
2020-01-31 22:52:39 device BC9740FFFE1065FB join <<"022CDE41">>

As good as I could I followed the trouble shooting "No downlink frames delivered" and I think I got everything right. So I went to the gateway log: tail -f /user/spf/var/log/spf.log, e.g. after a new startup:

Jan 31 22:02:05 klk-wifc-0404A0 local1.notice spf: INFO: [down] PULL_ACK received in 1.85 ms Jan 31 22:02:15 klk-wifc-0404A0 local1.notice spf: INFO: Received pkt from mote: FE297028 (fcnt=46037) Jan 31 22:02:15 klk-wifc-0404A0 local1.notice spf: JSON up: {"rxpk":[{"tmst":416935612,"time":"2020-01-31T22:02:15Z","chan":7,"rfch":1,"freq":868.500000,"stat":1,"modu":"LORA","datr":"SF12BW125","codr":"4/5","lsnr":7.5,"rssi":-13,"size":23,"data":"AChwKf7/1bNw+2UQ/v9Al7zlNGXIKZE="}]} Jan 31 22:02:15 klk-wifc-0404A0 local1.notice spf: INFO: [up] PUSH_ACK received in 1 ms Jan 31 22:02:15 klk-wifc-0404A0 local1.notice spf: INFO: [down] PULL_RESP received - token[165:98] :) Jan 31 22:02:15 klk-wifc-0404A0 local1.notice spf: JSON down: {"txpk":{"powe":13,"imme":false,"tmst":422935612,"codr":"4/5","datr":"SF12BW125","freq":863,"modu":"LORA","rfch":0,"ipol":true,"size":17,"data":"IN/o73+jPl90wq0X3NHZbGg="}} Jan 31 22:02:15 klk-wifc-0404A0 local1.notice spf: INFO: [down] PULL_ACK received in 1.86 ms

From what I can see, the gateway receives a message

JSON up: {"rxpk":[{"tmst":416935612,"time":"2020-01-31T22:02:15Z","chan":7,"rfch":1,"freq":868.500000,"stat":1,"modu":"LORA","datr":"SF12BW125","codr":"4/5","lsnr":7.5,"rssi":-13,"size":23,"data":"AChwKf7/1bNw+2UQ/v9Al7zlNGXIKZE="}]}

and sends a message

JSON down: {"txpk":{"powe":13,"imme":false,"tmst":422935612,"codr":"4/5","datr":"SF12BW125","freq":863,"modu":"LORA","rfch":0,"ipol":true,"size":17,"data":"IN/o73+jPl90wq0X3NHZbGg="}}

which seems to be confirmed by the device by

INFO: [down] PULL_ACK received in 1.86 ms

So I think, that the gateway and the device can communicate both ways. The join is reported in the dashboard. But then comes the downlink lost. I thought it might be a missing handler. So I configured a handler and a connector not really knowing what I am doing. Still the same situation.

So, would a join request be handled by the lorawan-server without a handler being configured or does a proper handler have to be configured?

I apologized for being LoRaWAN illiterate and appreciate the help,

Matthias

MatthiasCAlbrecht avatar Jan 31 '20 22:01 MatthiasCAlbrecht

Hello Matthias,   No handler is needed for Join. That should always work.   Note that the messages like PULL_RESP or PULL_ACK are exchanged between the server and the gateway only. They do not confirm the message was received by the device successfully.   In fact, I believe the message was never received by the end device. Your radio-level configuration feels wrong. Please have a look at https://github.com/gotthardp/lorawan-server/blob/master/doc/Regions.md and double check your values: the delta between your TX and RX is 6, so in the transmission you sent the TX2 was used (this is OK). However, the TX "freq"=863, which is not a standard value-- for Europe it should be 869.525. Are you sure your device is configured to expect TX on that freq in the TX2 window?

gotthardp avatar Feb 01 '20 00:02 gotthardp

Good morning Petr,

thanks for your help. You were right. When I could not get the device to respond I changed to value of Initial RX2 Freq to 863. I changed it now to 869.525 and verified https://github.com/gotthardp/lorawan-server/blob/master/doc/Regions.md. Still this is the outcome:

Feb 1 09:16:16 klk-wifc-0404A0 local1.notice spf: JSON up: {"stat":{"time":"2020-02-01 09:16:16 GMT","rxnb":3,"rxok":0,"rxfw":0,"ackr":100.0,"dwnb":0,"txnb":0,"ping":2}} Feb 1 09:16:16 klk-wifc-0404A0 local1.notice spf: INFO: [up] PUSH_ACK received in 1 ms Feb 1 09:16:25 klk-wifc-0404A0 local1.notice spf: INFO: [down] PULL_ACK received in 1.76 ms Feb 1 09:16:35 klk-wifc-0404A0 local1.notice spf: INFO: Received pkt from mote: FE297028 (fcnt=46037) Feb 1 09:16:35 klk-wifc-0404A0 local1.notice spf: JSON up: {"rxpk":[{"tmst":2222323004,"time":"2020-02-01T09:16:35Z","chan":7,"rfch":1,"freq":868.500000,"stat":1,"modu":"LORA","datr":"SF12BW125","codr":"4/5","lsnr":9.8,"rssi":-11,"size":23,"data":"AChwKf7/1bNw+2UQ/v9Al7z83z2NVTY="}]} Feb 1 09:16:35 klk-wifc-0404A0 local1.notice spf: INFO: [up] PUSH_ACK received in 1 ms Feb 1 09:16:35 klk-wifc-0404A0 local1.notice spf: INFO: [down] PULL_RESP received - token[187:26] :) Feb 1 09:16:35 klk-wifc-0404A0 local1.notice spf: JSON down: {"txpk":{"powe":13,"imme":false,"tmst":2227323004,"codr":"4/5","datr":"SF12BW125","freq":868.5,"modu":"LORA","rfch":0,"ipol":true,"size":17,"data":"IEPqPJppNaGGUVpyAStO6i4="}} Feb 1 09:16:35 klk-wifc-0404A0 local1.notice spf: INFO: [down] PULL_ACK received in 1.75 ms Feb 1 09:16:45 klk-wifc-0404A0 local1.notice spf: INFO: [down] PULL_ACK received in 1.75 ms Feb 1 09:16:46 klk-wifc-0404A0 local1.notice spf: ##### 2020-02-01 09:16:46 GMT #####

Thank you for your help,

Matthias

MatthiasCAlbrecht avatar Feb 01 '20 09:02 MatthiasCAlbrecht

Could you share log from the server too? The rxpk looks like a non-join frame.

gotthardp avatar Feb 01 '20 10:02 gotthardp

of course:

ssh [email protected] tail /var/log/lorawan-server/debug.log

2020-02-01 09:28:00.796 [warning] <0.4447.0>@lorawan_backend_factory:send_to_connectors:179 Message not sent to any connector 2020-02-01 09:28:00.997 [info] <0.4447.0> device BC9740FFFE1065FB {join,<<"022CDE41">>} 2020-02-01 09:28:00.998 [warning] <0.4447.0> node 022CDE41 {repeated_reset,41} 2020-02-01 09:28:00.999 [debug] <0.4447.0>@lorawan_mac:encode_accept:441 Join-Accept <<"022CDE41">>, netid <<0,0,1>>, cflist undefined, rx1droff 0, rx2dr 0, appkey <<"1E28F337100E8C0F00017D3210F073F0">>, appnce <<"31C9F9">> 2020-02-01 09:28:01.000 [debug] <0.4447.0>@lorawan_handler:join:117 Join-Accept in RX2: {rxq,868.1,<<"SF12BW125">>,<<"4/5">>,{{2020,2,1},{9,28,0.0}},undefined,2907980564,-16,11.8} {0,0,869.525} 2020-02-01 09:48:59.054 [warning] <0.4741.0>@lorawan_backend_factory:send_to_connectors:179 Message not sent to any connector 2020-02-01 09:48:59.255 [info] <0.4741.0> device BC9740FFFE1065FB {join,<<"022CDE41">>} 2020-02-01 09:48:59.256 [warning] <0.4741.0> node 022CDE41 {repeated_reset,42} 2020-02-01 09:48:59.257 [debug] <0.4741.0>@lorawan_mac:encode_accept:441 Join-Accept <<"022CDE41">>, netid <<0,0,1>>, cflist undefined, rx1droff 0, rx2dr 0, appkey <<"1E28F337100E8C0F00017D3210F073F0">>, appnce <<"956507">> 2020-02-01 09:48:59.258 [debug] <0.4741.0>@lorawan_handler:join:114 Join-Accept in RX1: {rxq,868.5,<<"SF12BW125">>,<<"4/5">>,{{2020,2,1},{9,48,59.0}},undefined,4166229820,-20,8.2}

MatthiasCAlbrecht avatar Feb 01 '20 10:02 MatthiasCAlbrecht

2020-02-01 09:28:00.796 [warning] <0.4447.0>@lorawan_backend_factory:send_to_connectors:179 Message not sent to any connector

Suggests the join was successful, it device sent another message, but didn't receive downlink it expected so it triggered a re-join. Could it be possible?

gotthardp avatar Feb 01 '20 10:02 gotthardp

Good evening Petr,

I really appreciate your prompt help and was sad when I left the house for today's business. I did not know, that the warning you copied means that the join was successful. Well the protocol specified for the device goes like this:

  • Device power up
  • LoRa JOINS Request
  • Uplink Port 101 INFO (SW Version sent to cloud)
  • Uplink PORT 100 CONFIG (Measurement Interval sent to could)
  • ...

Then the docs give for Uplink Port 101 INFO:

  • Payload Version Uint8
  • Status -> Bit 0-3 -> Battery Stand (From 0 to 10 in 10 % steps) Bit 4-5 -> 00 for SML etc. Bit 6 -> Registers configured (1 TRUE, 0 FALSE) Bit 7 -> Connection Test (1 TRUE, 0 FALSE)
  • App Main Version Uint8
  • App Minor Version Uint8

From my understanding that is two consecutive uplink packages. I do not see that after the Uplink Port 101 INFO there needs to be a response. But the docs says, that there is a Downlink Port 101 INFO:

  • Byte 0: GET DEVICE INFO -> Value must be true (!= 0)

I will attach the doc so that you can have a look. Maybe and Uplink 101 must be followed by a Downlink Port 101 INFO and thereafter the device will answer with the Uplink Port 101 INFO. How could I debug this?

Two more questions: to handle and incoming message and form a response a pure handler will do, correct? I do not necessarily need a connector? And then: when I write a parser for the uplink, what is the input? Only the payload without the LoRaWAN details or the LoRAWAN package itself?

Oh, since I do not speak Erlang (I am C++ mostly), what does this in your doc mean:

fun (Fields, <<16#0402:16, Temp:16/signed>>) -> Fields#{temp => Temp}; (Fields, <<16#0405:16, Level>>) -> Fields#{level => Level} end.

16 Bits of the value 0402:16 and then this OR 16 Bits of the value 0405 and then that?

Thank you very much and have a great weekend,

Matthias

AO-T-KLAX.pdf

MatthiasCAlbrecht avatar Feb 01 '20 20:02 MatthiasCAlbrecht

I suspect the device really expects the Downlink response. The decoder expects the application payload, i.e. what is written in your PDF. Teh LoRaWAN fields are handled by the server. I really suggest you get familiar a bit with the Erlang syntax, but to answer your question: yes, the code means 0x0402 followed by 16-bit Temp, or 0x0405 followed by 8-bit Level.

gotthardp avatar Feb 02 '20 23:02 gotthardp

Good evening Petr,

let me first thank you for your support. I was out of town, so the late answer. Well, here they are:

(a) I called the manufacturer for the KLAX and after some chat he said "The KLAX has to be on the meter to function properly. Otherwise it will not continue properly - evan after a join." Well, I had the device next to me not attached to a meter.

(b) The manufacturer said that there are open source implementations of parsers for the device which I like to share:

Parser für TTN https://github.com/Alpha-Omega-Technology/ttn-klax Parser in Elixir https://github.com/ZennerIoT/element-parsers/blob/master/lib/comtac_klax.ex

Once I get the device connected to a meter I will restart my attempts with a parser.

(c) On my flight to Munich I started to read a book about Erlang. Funny language. I will continue and even came across pattern matching by now.

(d) Handling a device which I do not understand did not seem to be the right entry point to the subject. So I ordered a SODAQ ExpLoRer which arrived today. That is a freely programmable Arduino device with a LoRa-module. I managed to get that running following the "getting started" within less then two hours. And about 30 min later I could send a message from that board to the gateway and your server. The payload is "SODAQ" and when I did not have a handler defined and instead selected semtech_mote I got events with these Args: {1,<<"SODAQ">>}. Obviously the join worked and your server understood the payload. What is the 1 in front of the payload?

(e) Then I set up a handler with just an Application name ("ExpLoRer") and D/L Expires set to "When Superseded". I assume that I could now define a connector and send the payload through the connector to whatever is defined in the connector, correct? For debugging, what is the best way to see the available data for the uplink parser? In the debug log I only see things which went wrong, correct? Where can I see all incoming frames?

I enjoy the communication with you very much. Thanks again,

Matthias

MatthiasCAlbrecht avatar Feb 06 '20 22:02 MatthiasCAlbrecht

Thanks :) (b) Elixir is a layer on top of Erlang, so you should be able to translate the binary syntax more easily than with other languages. There we attempts to run lorawan-server in Elixir (thus you could use the Elixir function directly), but I believe they were not (yet) successfull. (d) The number is a port number. (e) Yes, you need to have a Handler (possibly with empty functions) and a Connector. I believe the best for debugging is to use a WebSocket interface and the integrated "Demo Page" as described here: https://github.com/gotthardp/lorawan-server/blob/master/doc/Connectors.md#web-sockets (This is what I use for debugging.) The correctly handled frames are not shown in the log. You can see them on the Frames page.

Petr

gotthardp avatar Feb 06 '20 22:02 gotthardp

Good evening Petr, I have got your demo page running (for me: http://192.168.35.208:8090/admin/ws.html, since I moved everything to port 8090). When I enter the link "/ws/uplink/02EB7A9E" an JSON, I get "RECEIVED: {"data":"534F444151","devaddr":"02EB7A9E","netid":"000001","port":1}" after I configured those uplink fields in the corresponding handler. And I managed to connect a simple websocket-client in parallel to the address and get the same data.

Looking at the documentation I wonder how I send a downlink from my websocket client to the device? Just send something to the websocket-server and that will be the payload for the downlink? Like {port, data}?

Thank you and have a good evening,

Matthias

MatthiasCAlbrecht avatar Feb 09 '20 20:02 MatthiasCAlbrecht

Hello. Just define a JSON string and send it to the websocket. The data and port fields should be enough. Some examples are at https://github.com/gotthardp/lorawan-server/blob/master/doc/Handlers.md#downlink

gotthardp avatar Feb 09 '20 21:02 gotthardp

Well, did just this: gedit client.js const WebSocket = require('ws');

const ws = new WebSocket('ws://192.168.35.208:8090/ws/uplink/02EB7A9E');

ws.on('message', function incoming(data) { console.log(data); ws.send('{"data":"48656c6c6f2c20776f726c6421","devaddr":"02EB7A9E"}'); }); node client.js

{"data":"534F444151","devaddr":"02EB7A9E","netid":"000001","port":1}

an the serial output of the board: Hello, world!

This is the function to read from LoRa on the board: https://github.com/SodaqMoja/Sodaq_RN2483

receive(uint8_t* buffer, uint16_t size, uint16_t payloadStartPosition = 0)

There is no port in the function. Funny. But otherwise it works. Thanks a lot. Will post more comments.

MatthiasCAlbrecht avatar Feb 09 '20 21:02 MatthiasCAlbrecht

Oh, just saw that:

port | Integer | LoRaWAN port number in the range 1-223. Optional for Class A: if not specified, the uplink port number will be used. Mandatory for Class C.

MatthiasCAlbrecht avatar Feb 09 '20 21:02 MatthiasCAlbrecht

Good evening Petr,

well, I am making progress. I can program my SODAQ ExpLoRer board to send and receive messages. And now I have a SML meter next to my desk and the Klax attached to it. When I power up the meter, it sends a join to the server. This is, what is shown for the events:

Last Occurred | Entity | Eid | Text | Args

2020-02-11 18:53:09 | device | BC9740FFFE1065DD | join | <<"0361E185">>

Thereafter, no frames are transmitted from the device even though the protocol says it will after a successful join. How can I debug if the server send an accept of the join to the device and the device received it?

Thank you, Matthias

MatthiasCAlbrecht avatar Feb 11 '20 21:02 MatthiasCAlbrecht