handling variable length of payload

39 views
Skip to first unread message

Mr. PO

unread,
Mar 5, 2019, 2:53:03 PM3/5/19
to LoRaWAN Server Users
May I ask help about how to create handler for uplink data with logic to handle variable length of payload:

Payload type 1:
437A120010000000001000000000

Handler for Payload1:
fun(#{port := 24}=Fields, <<Dig1:1, Dig2:1, Ana1:1, Ana2:1, SSI:1, MBUS:1, UsrTrg:1, Rfu:1, Bat:8, Temp:8/signed,  RSSI:8/signed, Dig1control:8, Dig1counter:32, Dig2control:8, Dig2counter:32, Data/binary >>) ->
       Fields#{ sensor => 'digital', data => #{battery => Bat, temperature => Temp, rssi => RSSI, d1counter => Dig1counter,  d2counter => Dig2counter}};
      (Fields, _) ->
        Fields
end.

But:
Payload type 2 from same sensor:
4F7A12001000000000100000000040000000000400000000

How to handle inside handler variable length payload, based on first byte of payload (Ana1 and Ana2 bits are 1)?

Added bytes from sensor are:
<<Ana1settings:8,Ana1float:32, Ana2settings:8,Ana2float:32 >>

Or is it better to just use different handlers for differently configured sensor?
Type of sensor can have some 8 kind of payloads depending on how it is configured.

I'm very early on my learning curve ;-) , so please help.

Br, Mr PO from Finland

Petr Gotthard

unread,
Mar 5, 2019, 3:52:22 PM3/5/19
to Mr. PO, LoRaWAN Server Users

If the payload types are distinguisable from each other (using the port number, payload length or some bit/byte inside the payload) you can build a handler with alternative function:

 

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

This is effectively two functions: The first part is used when the payload starts 0402, the second when it starts 0405.
You can have two or more parts. Even in your example, there are also two parts: the first is used when port is 24 and the payload matches what you specified, the second part is used otherwise.

Please note that the first match is selected, so e.g. this:

fun (Fields, <<Num1, Num2>>) -> Fields; (Fields, <<NumA, NumB>>) -> Fields end.

will never match the second part because it is indistinguishable from the first.
In your case, the last part of your string (Data/binary) is dangerous as it matches "any remaining bytes". It can easily match binaries that shouldn't be matched.


Regards,
Petr

 

______________________________________________________________
> Od: "Mr. PO" <Panul...@gmail.com>
> Komu: "LoRaWAN Server Users" <lorawan...@googlegroups.com>
> Datum: 05.03.2019 20:57
> Předmět: handling variable length of payload
>

--
You received this message because you are subscribed to the Google Groups "LoRaWAN Server Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to lorawan-serve...@googlegroups.com.
To post to this group, send email to lorawan...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/lorawan-server/4ecfddf2-9bf4-4701-b720-8671696969b4%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Mr. PO

unread,
Mar 6, 2019, 1:18:39 AM3/6/19
to LoRaWAN Server Users
Thank you!
I think I got the idea now.
Will test it soon.
Any idea to have a place for user made handlers? May help newcomers (like me) to start using sensors...just my two cents.
Br,
Mr. PO
Message has been deleted

Mr. PO

unread,
Mar 6, 2019, 2:20:04 AM3/6/19
to LoRaWAN Server Users
Hello,
This is my test but it is not accepted...port is same 24 but first payload byte is different and this I use to select which one to run. Is there a typo or real erlang error, I can not see..please help.
fun(#{port := 24}=Fields, <<8#43:8, Channels:4, SSI:1, MBUS:1, UsrTrg:1, Rfu:1, Bat:8, Temp:8/signed,  RSSI:8/signed, Dig1control:8, Dig1counter:32, Dig2control:8, Dig2counter:32>>) ->
       Fields#{ sensor => 'digital', data => #{battery => Bat, temperature => Temp, rssi => RSSI, d1counter => Dig1counter,  d2counter => Dig2counter}};
(Fields, <<8#4F:8, Channels:4, SSI:1, MBUS:1, UsrTrg:1, Rfu:1, Bat:8, Temp:8/signed,  RSSI:8/signed, Dig1control:8, Dig1counter:32, Dig2control:8, Dig2counter:32, Ana1settings:8, Ana1float:32/float, Ana2settings:8, Ana2float:32/float >>) ->
       Fields#{ sensor => 'digital', data => #{battery => Bat, temperature => Temp, rssi => RSSI, d1counter => Dig1counter,  d2counter => Dig2counter, ana1setting => Ana1settings, ana1value => Ana1float, ana2setting => Ana2settings, ana2value => Ana2float}};
(Fields, _) ->
        Fields
end.

Petr Gotthard

unread,
Mar 6, 2019, 4:41:31 AM3/6/19
to Mr. PO, LoRaWAN Server Users

A good practice is to use your Erlang compiler to syntax check your functions. Just type ‘erl’ to start the command line and then copy paste your function there. If you get no error and the console prints something like ‘#Fun<erl_eval.12.118419387>’ then your function is syntactically correct.

 

Your function is incorrect because of “8#4F”-- “F” is not a valid digit in an octal number system.

 

 

Petr

--

You received this message because you are subscribed to the Google Groups "LoRaWAN Server Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to lorawan-serve...@googlegroups.com.
To post to this group, send email to lorawan...@googlegroups.com.

Mr. PO

unread,
Mar 6, 2019, 5:04:45 AM3/6/19
to LoRaWAN Server Users
Thanx, next I have to take eye to the hand to see...
Br,
Mr PO

Mr. PO

unread,
Mar 6, 2019, 6:25:53 AM3/6/19
to LoRaWAN Server Users
Oh, I noticed that first payload byte can not be used anymore if used for matching, so binary must be :

fun(#{port := 24}=Fields, <<16#43:8,  Bat:8, Temp:8/signed,  RSSI:8/signed, Dig1control:8, Dig1counter:32, Dig2control:8, Dig2counter:32>>) ->
       Fields#{ sensor => 'digital', data => #{battery => Bat, temperature => Temp, rssi => RSSI, d1counter => Dig1counter,  d2counter => Dig2counter}};

Br,
Mr PO

Mr. PO

unread,
Mar 6, 2019, 12:02:38 PM3/6/19
to LoRaWAN Server Users
This might be solution:
fun(#{port := 24}=Fields, <<SSI:1, MBUS:1, UsrTrg:1, Rfu:1,16#3:4,  Bat:8, Temp:8/signed,  RSSI:8/signed, Dig1control:8, Dig1counter:32, Dig2control:8, Dig2counter:32>>) ->
Ciao!
Reply all
Reply to author
Forward
0 new messages