I am trying to send message from one node to the other, via hops in between. Please provide an example, how to write a python code using meshtastic API for it!
Create a file called test.py with the following.
import meshtastic
interface = meshtastic.SerialInterface()
interface.sendText(âhello meshâ, hopLimit=6)
interface.close()
Run the file
python3 test.py
Have you used the version 1.1.32? Because I am getting the following error:
arijit@arijit-Lenovo-G550:~/meshtasticGUI$ python3 test.py
Traceback (most recent call last):
File âtest.pyâ, line 3, in
interface.sendText(âhello meshâ, hopLimit=6)
TypeError: sendText() got an unexpected keyword argument âhopLimitâ
alas, the python API for setting hop limit wasnât added until 1.2.
Okay, @geeksville. Could you please tell me at the time of multi hop communication, do we need to make the nodes as router to make it relay devices, so that it can re-transmit and forward packets?
By default all meshtastic devices relay messages if on the same channel. The default hop limit is currently set at 3.
If it is so, then the wantAck (successId or FailId) will come from the targeted end node or the intermediate node? When I am trying to send the message as Broadcasting, then all the nodes are receiving the message, but when I am uni-casting to a particular node, it is received only at that particular node, no hops in between is receiving the messages.
Is this an academic exercise or are you looking for practical results? Right now i believe the messages bleed through the network until the message hop counter decreases to zero. Direct messages to specific users (or subgroup of users) will be added eventually once the multichannel support is working fully but from a practical point of view, the person you are trying to contact over the mesh will respond to your message.
yes, it is an academic exercise, so I just need an Ack from the end node. Just need to know whether the Ack will come from the end node, where the hop count will become zero, or from the intermediate node? For this, do I need to use the hop as router?
Have you read through all the Protobufs and understand what the router mode does?
âAre we operating as a router. Changes behavior in the following ways: The device will only sleep for critically low battery level (i.e. always tries to stay alive for the mesh) In the future routing decisions will preferentially route packets through nodes with this attribute (because assumed good line of sight)â
want_ack
âThis packet is being sent as a reliable message, we would prefer it to arrive at the destination. We would like to receive a ack packet in response. Broadcasts messages treat this flag specially: Since acks for broadcasts would rapidly flood the channel, the normal ack behavior is suppressed. Instead, the original sender listens to see if at least one node is rebroadcasting this packet (because naive flooding algorithm). If it hears that the odds (given typical LoRa topologies) the odds are very high that every node should eventually receive the message. So FloodingRouter.cpp generates an implicit ack which is delivered to the original sender. If after some time we donât hear anyone rebroadcast our packet, we will timeout and retransmit, using the regular resend logic. Note: This flag is normally sent in a flag bit in the header when sent over the wireâ
ok, I understood the router mode part, but what about the other question I asked?
The want_ack flag on a packet indicates that the message should be sent âreliablyâ and the intervening nodes will forward and send back errors if the message can not be delivered. So message delivery to the remote node does not result in a packet gettting delivered back to the sender. Messhage non delivery results in error messages getting returned.
If you also require a message from the receiving node when the message is delivered you can set (the poorly named) âwant_responseâ to true. Then the remote side will at least send back an ACK packet (all the way back to the original sender) or if your application has some other reply, it will be sent as the ACK.
Hi @geeksville,
def sendText(self, text, destinationId=BROADCAST_ADDR, wantAck=False, wantResponse=False):
'''Send a utf8 string to some other node, if the node has a display it will also be shown on the device.
Arguments:
text {string} -- The text to send
Keyword Arguments:
destinationId {nodeId or nodeNum} -- where to send this message (default: {BROADCAST_ADDR})
portNum -- the application portnum (similar to IP port numbers) of the destination, see portnums.proto for a list
wantAck -- True if you want the message sent in a reliable manner (with retries and ack/nak provided for delivery)
Returns the sent packet. The id field will be populated in this packet and can be used to track future message acks/naks.
'''
return self.sendData(text.encode("utf-8"), destinationId,
portNum=portnums_pb2.PortNum.TEXT_MESSAGE_APP, wantAck=wantAck, wantResponse=wantResponse)
This is the code snippet from the 1.1.32 init.py, when I used wantResponse = True in my python program; no response is recieved from the end node, whether it is unicast or broadcast.
Instruction of my code was:
interface.sendText(EntryText, destinationId = '!246f287793f4', wantResponse = True)
and
interface.sendText(EntryText, wantResponse = True)
Only wantAck is working correctly. Tell me whether wantResponse work at all in prior versions of 1.2 or not?
prior to 1.2 wantResponse was only handled by the receiving app. So it would check for that flag and if set, send a response packet.
In 1.2 or later, the behavior was generalized: If an app responds to a wantResponse=true packet, the reply is routed back to the original requestor (unchanged from 1.1).
But if the receving node opts not to respond to a packet (possibly because no particular response is needed or there isnât even an app listening on that portnum): the routing layer will generate a simple/bare ACK response which is then routed all the way back to the requester.