Closed folksman closed 2 years ago
The node ID and corresponding node address are saved on the master node's dhcp_dict
. Any mesh node can look up the node ID for an assigned node address by calling lookup_node_id
I have not tested this code snippet.
# assuming nrf.available() == True
rx_frame = nrf.read()
rx_id = nrf.lookup_node_id(
rx_frame.header.from_node
)
print("node ID {} sent msg {}".format(
rx_id,
rx_frame.message.decode()
))
Some of this answer relates to the data structure that the mesh/network API use to transport data.
It give a error.. looks like rx_frame.message.decode() is wrong
rx_frame.message
should always be a bytearray or bytes object, so try str(rx_frame.message)
. TBH, this is a basic python problem and not a lib problem.
It would also help if you actually posted the error message instead of interpreting the error as you understand it.
this prints "5b'H\xee\x00\x00'" but i want see the real message instead
btw i simple use the c++ mesh example which sends the time loop 1000,2000 etc.
on normal idle function i get Received payload (2000,) from 0o5 to 0o0 type 77 id 4 reserved 240 length 4
i want only the 2000
this prints "5b'H\xee\x00\x00'" but i want see the real message instead
What prints that? The code I suggested in this issue? Is this the output from str(rx_frame.message)
or from rx_frame.message.decode()
? BTW, b'H\xee\x00\x00'
is the representation of a bytes object, and IDK where the 5
in the beginning is from.
on normal idle function i get Received payload (2000,) from 0o5 to 0o0 type 77 id 4 reserved 240 length 4
i want only the 2000
All frames' messages are in the form of bytearray or bytes object. To get the number representation of data contained in the message, you need to unpack it from the bytearray form. This is demonstrated in the examples by using struct.unpack()
. To learn more about how to use struct.unpack()
, you should read the python docs as that is not a function from this lib.
unsigned_short_int = struct.unpack("H", rx_frame.message[:2])[0]
The format characters used as the first argument follows C++ datatypes, so it helps to know what is being sent (int
/char
/short
/etc).
None of this info is specific to this lib. It's all basic python.
difficult to understand as python beginner but got it. sorry to border you for non lib specific questions. i was think there are a simple function to get message content .. why not?
is there a way to can get the pure message without know length and knowing datatype of it? Am 14. Jan. 2022, 15:50 +0100 schrieb Brendan @.***>:
this prints "5b'H\xee\x00\x00'" but i want see the real message instead What prints that? The code I suggested in this issue? Is this the output from str(rx_frame.message) or from rx_frame.message.decode()? BTW, b'H\xee\x00\x00' is the representation of a bytes object, and IDK where the 5 in the beginning is from. on normal idle function i get Received payload (2000,) from 0o5 to 0o0 type 77 id 4 reserved 240 length 4 i want only the 2000 All frames' messages are in the form of bytearray or bytes object. To get the number representation of data contained in the message, you need to unpack it from the bytearray form. This is demonstrated in the examples by using struct.unpack(). To learn more about how too use struct.unpack() you should read the python docs as that is not a function from this lib.
• to get a number that takes up the first 2 bytes of the message, you would use unsigned_short_int = struct.unpack("H", rx_frame.message[:2])[0] The format characters used as the first argument follows C++ datatypes, so it helps to know what is being sent (int/char/short/etc).
None of this info is specific to this lib. It's all basic python. — Reply to this email directly, view it on GitHub, or unsubscribe. Triage notifications on the go with GitHub Mobile for iOS or Android. You are receiving this because you authored the thread.Message ID: @.***>
i was think there are a simple function to get message content .. why not?
Because it would require an assumption that the app you're writing will only use certain data types and in a certain arrangement/order. Assumptions are what make "smart" programming dumber; it's never a good idea to assume when writing code.
is there a way to can get the pure message without know length and knowing datatype of it?
Generally, no. Setting aside what I just said about assumptions, the radio itself is designed to only transmit binary data. Meaning, it is up to the user how the binary data is constructed and deciphered.
This lib isn't meant to do all the work for you; it's only meant to do the interactions between the user's app and the radio's hardware.
I think i got it now. thx for your excellent explanation! It means the message is not always a string.. it will be always a specific data type, thats why rx need to know it to not lost the set data type from tx? Is that correct?
It means the message is not always a string.. it will be always a specific data type, thats why rx need to know it to not lost the set data type from tx? Is that correct?
I'm not sure what you mean here. The English is so confusing (the word "lost" seems like the wrong choice). I feel like if I try to answer, I could cause you even more confusion. But I think you are working with the correct idea about the message now.
i now fully understand it. Thank you! For what is the message_type exactly used? Can i set them free as i wish? If yes i can use them to know on RX side which kind of message will comes and how to use struct as example.
Do not confuse message_type
with data type. message_type
is specific to the networking API. It is only meant to help the receiving node filter out messages or give special treatment to a certain message_type
.
It can be a single an int in range 0-255 or a single letter for which the ASCII value is used as the message_type
. Users should not use a message_type
greater than 127 because this lib reserves certain message types to do network-specific things.
You can, however, relate a certain message_type to an arrangement of datatypes.
if rx_frame.header.message_type == ord('F'):
# use "HiB" for message_type "F" (or 0x46 or 70)
(my_short, my_int, my_bool) = struct.unpack("HiB", rx_frame.message[:7])
i understand. good to know and very helpful!
i stuck in other point. sending strings. as example on c++ i have char[] my_string = "Hello";
and send it as 'x' message_type. Now the problem is on python side.. i not get it read out :( Thats what i try but not working
if rx_frame.header.message_type == ord('x'):
print(struct.unpack("s", rx_frame.message[:2])[0])
RuntimeError: puffer size does not equal the format (its translated)
I know its again not a Lib issue but your help would be great.
To unpack a string using struct.unpack()
, you need to specify the length of the expected string. I have not tested this code.
# this is a c-string in bytes object form
rx_msg = b'Hello\0' # length is 6 bytes
# in python we don't care about the terminating '\0'
rx_str = struct.unpack("5s", rx_msg[:5])[0]
Here's the info you need from the python docs:
For the 's' format character, the count is interpreted as the length of the bytes, not a repeat count like for the other format characters; for example, '10s' means a single 10-byte string, while '10c' means 10 characters. If a count is not given, it defaults to 1. For packing, the string is truncated or padded with null bytes as appropriate to make it fit. For unpacking, the resulting bytes object always has exactly the specified number of bytes. As a special case, '0s' means a single, empty string (while '0c' means 0 characters).
You could also use the decode()
method available to all bytearray and bytes objects.
rx_msg = bytearray(b'Hello\0')
rx_str = rx_msg[:5].decode() # assumes UTF-8 encoding
Another basic python trick you don't seem to understand is "slicing". This happens when we use :
inside the square brackets (like arr[:2]
). More/better info on that in tutorials like this StackOverflow answer
thanks to your great description i now fully understand and get all working as expected. Can you please me tell me for what excactly stay the [0] on end of rx_str = struct.unpack("5s", rx_msg[:5])[0]
?
struct.unpack()
will always return a tuple containing all the unpacked data as individual elements, even if there is only 1 element that was unpacked. By using a [0]
at the end, we only store the first element to a single variable, not the tuple of a single element.
>>> data = struct.unpack("B", b"\0")
>>> print(data)
(0,)
>>> data = struct.unpack("B", b"\0")[0]
>>> print(data)
0
We don't need the [0]
when "expanding" multiple elements of a tuple into multiple variables
>>> data = struct.unpack("3B", b"\0\1\2")
>>> print(data)
(0, 1, 2)
>>> byte_1, byte_2, byte_3 = data
>>> print(byte_1, byte_2, byte_3)
0 1 2
I stuck in simple get message with different sizes in Mesh sample.
I want send from a slave node a simple text message (for own protocol usage) and on console master print out the node id, and just the message. The message from slave nodes can have different sizes.
Can you may give me here a small example?