From 1f4af574e6c66bbf04d791bc7189196f40968a68 Mon Sep 17 00:00:00 2001 From: geeksville Date: Tue, 8 Sep 2020 10:01:08 -0700 Subject: [PATCH] 1.0.1 --- docs/meshtastic/index.html | 125 +++++++++++++++++++++++++++++-------- setup.py | 2 +- 2 files changed, 100 insertions(+), 27 deletions(-) diff --git a/docs/meshtastic/index.html b/docs/meshtastic/index.html index 0cb6265..112116f 100644 --- a/docs/meshtastic/index.html +++ b/docs/meshtastic/index.html @@ -174,17 +174,22 @@ class MeshInterface: Keyword Arguments: destinationId {nodeId or nodeNum} -- where to send this message (default: {BROADCAST_ADDR}) + + Returns the sent packet. The id field will be populated in this packet and can be used to track future message acks/naks. """ - self.sendData(text.encode("utf-8"), destinationId, - dataType=mesh_pb2.Data.CLEAR_TEXT, wantAck=wantAck, wantResponse=wantResponse) + return self.sendData(text.encode("utf-8"), destinationId, + dataType=mesh_pb2.Data.CLEAR_TEXT, wantAck=wantAck, wantResponse=wantResponse) def sendData(self, byteData, destinationId=BROADCAST_ADDR, dataType=mesh_pb2.Data.OPAQUE, wantAck=False, wantResponse=False): - """Send a data packet to some other node""" + """Send a data packet to some other node + + Returns the sent packet. The id field will be populated in this packet and can be used to track future message acks/naks. + """ meshPacket = mesh_pb2.MeshPacket() meshPacket.decoded.data.payload = byteData meshPacket.decoded.data.typ = dataType meshPacket.decoded.want_response = wantResponse - self.sendPacket(meshPacket, destinationId, wantAck=wantAck) + return self.sendPacket(meshPacket, destinationId, wantAck=wantAck) def sendPosition(self, latitude=0.0, longitude=0.0, altitude=0, timeSec=0, destinationId=BROADCAST_ADDR, wantAck=False, wantResponse=False): """ @@ -194,6 +199,8 @@ class MeshInterface: the local position. If timeSec is not specified (recommended), we will use the local machine time. + + Returns the sent packet. The id field will be populated in this packet and can be used to track future message acks/naks. """ meshPacket = mesh_pb2.MeshPacket() if(latitude != 0.0): @@ -210,11 +217,14 @@ class MeshInterface: meshPacket.decoded.position.time = int(timeSec) meshPacket.decoded.want_response = wantResponse - self.sendPacket(meshPacket, destinationId, wantAck=wantAck) + return self.sendPacket(meshPacket, destinationId, wantAck=wantAck) def sendPacket(self, meshPacket, destinationId=BROADCAST_ADDR, wantAck=False): """Send a MeshPacket to the specified node (or if unspecified, broadcast). - You probably don't want this - use sendData instead.""" + You probably don't want this - use sendData instead. + + Returns the sent packet. The id field will be populated in this packet and can be used to track future message acks/naks. + """ toRadio = mesh_pb2.ToRadio() # FIXME add support for non broadcast addresses @@ -223,12 +233,19 @@ class MeshInterface: elif destinationId == BROADCAST_ADDR: nodeNum = BROADCAST_NUM else: - nodeNum = self.nodes[destinationId].num + nodeNum = self.nodes[destinationId]['num'] meshPacket.to = nodeNum meshPacket.want_ack = wantAck + + # if the user hasn't set an ID for this packet (likely and recommended), we should pick a new unique ID + # so the message can be tracked. + if meshPacket.id == 0: + meshPacket.id = self._generatePacketId() + toRadio.packet.CopyFrom(meshPacket) self._sendToRadio(toRadio) + return meshPacket def writeConfig(self): """Write the current (edited) radioConfig to the device""" @@ -239,6 +256,11 @@ class MeshInterface: t.set_radio.CopyFrom(self.radioConfig) self._sendToRadio(t) + def _generatePacketId(self): + """Get a new unique packet ID""" + self.currentPacketId = (self.currentPacketId + 1) & 0xffffffff + return self.currentPacketId + def _disconnected(self): """Called by subclasses to tell clients this interface has disconnected""" self.isConnected = False @@ -256,6 +278,7 @@ class MeshInterface: self.nodes = {} # nodes keyed by ID self._nodesByNum = {} # nodes keyed by nodenum self.radioConfig = None + self.currentPacketId = None startConfig = mesh_pb2.ToRadio() startConfig.want_config_id = MY_CONFIG_ID # we don't use this value @@ -279,6 +302,9 @@ class MeshInterface: if self.myInfo.min_app_version > OUR_APP_VERSION: raise Exception( "This device needs a newer python client, please \"pip install --upgrade meshtastic\"") + # start assigning our packet IDs from the opposite side of where our local device is assigning them + self.currentPacketId = ( + self.myInfo.current_packet_id + 0x80000000) & 0xffffffff elif fromRadio.HasField("radio"): self.radioConfig = fromRadio.radio elif fromRadio.HasField("node_info"): @@ -714,17 +740,22 @@ debugOut

Keyword Arguments: destinationId {nodeId or nodeNum} -- where to send this message (default: {BROADCAST_ADDR}) + + Returns the sent packet. The id field will be populated in this packet and can be used to track future message acks/naks. """ - self.sendData(text.encode("utf-8"), destinationId, - dataType=mesh_pb2.Data.CLEAR_TEXT, wantAck=wantAck, wantResponse=wantResponse) + return self.sendData(text.encode("utf-8"), destinationId, + dataType=mesh_pb2.Data.CLEAR_TEXT, wantAck=wantAck, wantResponse=wantResponse) def sendData(self, byteData, destinationId=BROADCAST_ADDR, dataType=mesh_pb2.Data.OPAQUE, wantAck=False, wantResponse=False): - """Send a data packet to some other node""" + """Send a data packet to some other node + + Returns the sent packet. The id field will be populated in this packet and can be used to track future message acks/naks. + """ meshPacket = mesh_pb2.MeshPacket() meshPacket.decoded.data.payload = byteData meshPacket.decoded.data.typ = dataType meshPacket.decoded.want_response = wantResponse - self.sendPacket(meshPacket, destinationId, wantAck=wantAck) + return self.sendPacket(meshPacket, destinationId, wantAck=wantAck) def sendPosition(self, latitude=0.0, longitude=0.0, altitude=0, timeSec=0, destinationId=BROADCAST_ADDR, wantAck=False, wantResponse=False): """ @@ -734,6 +765,8 @@ debugOut

the local position. If timeSec is not specified (recommended), we will use the local machine time. + + Returns the sent packet. The id field will be populated in this packet and can be used to track future message acks/naks. """ meshPacket = mesh_pb2.MeshPacket() if(latitude != 0.0): @@ -750,11 +783,14 @@ debugOut

meshPacket.decoded.position.time = int(timeSec) meshPacket.decoded.want_response = wantResponse - self.sendPacket(meshPacket, destinationId, wantAck=wantAck) + return self.sendPacket(meshPacket, destinationId, wantAck=wantAck) def sendPacket(self, meshPacket, destinationId=BROADCAST_ADDR, wantAck=False): """Send a MeshPacket to the specified node (or if unspecified, broadcast). - You probably don't want this - use sendData instead.""" + You probably don't want this - use sendData instead. + + Returns the sent packet. The id field will be populated in this packet and can be used to track future message acks/naks. + """ toRadio = mesh_pb2.ToRadio() # FIXME add support for non broadcast addresses @@ -763,12 +799,19 @@ debugOut

elif destinationId == BROADCAST_ADDR: nodeNum = BROADCAST_NUM else: - nodeNum = self.nodes[destinationId].num + nodeNum = self.nodes[destinationId]['num'] meshPacket.to = nodeNum meshPacket.want_ack = wantAck + + # if the user hasn't set an ID for this packet (likely and recommended), we should pick a new unique ID + # so the message can be tracked. + if meshPacket.id == 0: + meshPacket.id = self._generatePacketId() + toRadio.packet.CopyFrom(meshPacket) self._sendToRadio(toRadio) + return meshPacket def writeConfig(self): """Write the current (edited) radioConfig to the device""" @@ -779,6 +822,11 @@ debugOut

t.set_radio.CopyFrom(self.radioConfig) self._sendToRadio(t) + def _generatePacketId(self): + """Get a new unique packet ID""" + self.currentPacketId = (self.currentPacketId + 1) & 0xffffffff + return self.currentPacketId + def _disconnected(self): """Called by subclasses to tell clients this interface has disconnected""" self.isConnected = False @@ -796,6 +844,7 @@ debugOut

self.nodes = {} # nodes keyed by ID self._nodesByNum = {} # nodes keyed by nodenum self.radioConfig = None + self.currentPacketId = None startConfig = mesh_pb2.ToRadio() startConfig.want_config_id = MY_CONFIG_ID # we don't use this value @@ -819,6 +868,9 @@ debugOut

if self.myInfo.min_app_version > OUR_APP_VERSION: raise Exception( "This device needs a newer python client, please \"pip install --upgrade meshtastic\"") + # start assigning our packet IDs from the opposite side of where our local device is assigning them + self.currentPacketId = ( + self.myInfo.current_packet_id + 0x80000000) & 0xffffffff elif fromRadio.HasField("radio"): self.radioConfig = fromRadio.radio elif fromRadio.HasField("node_info"): @@ -941,18 +993,22 @@ debugOut

def sendData(self, byteData, destinationId='^all', dataType=0, wantAck=False, wantResponse=False)
-

Send a data packet to some other node

+

Send a data packet to some other node

+

Returns the sent packet. The id field will be populated in this packet and can be used to track future message acks/naks.

Expand source code
def sendData(self, byteData, destinationId=BROADCAST_ADDR, dataType=mesh_pb2.Data.OPAQUE, wantAck=False, wantResponse=False):
-    """Send a data packet to some other node"""
+    """Send a data packet to some other node
+
+    Returns the sent packet. The id field will be populated in this packet and can be used to track future message acks/naks.
+    """
     meshPacket = mesh_pb2.MeshPacket()
     meshPacket.decoded.data.payload = byteData
     meshPacket.decoded.data.typ = dataType
     meshPacket.decoded.want_response = wantResponse
-    self.sendPacket(meshPacket, destinationId, wantAck=wantAck)
+ return self.sendPacket(meshPacket, destinationId, wantAck=wantAck)
@@ -960,14 +1016,18 @@ debugOut

Send a MeshPacket to the specified node (or if unspecified, broadcast). -You probably don't want this - use sendData instead.

+You probably don't want this - use sendData instead.

+

Returns the sent packet. The id field will be populated in this packet and can be used to track future message acks/naks.

Expand source code
def sendPacket(self, meshPacket, destinationId=BROADCAST_ADDR, wantAck=False):
     """Send a MeshPacket to the specified node (or if unspecified, broadcast).
-    You probably don't want this - use sendData instead."""
+    You probably don't want this - use sendData instead.
+
+    Returns the sent packet. The id field will be populated in this packet and can be used to track future message acks/naks.
+    """
     toRadio = mesh_pb2.ToRadio()
     # FIXME add support for non broadcast addresses
 
@@ -976,12 +1036,19 @@ You probably don't want this - use sendData instead.

elif destinationId == BROADCAST_ADDR: nodeNum = BROADCAST_NUM else: - nodeNum = self.nodes[destinationId].num + nodeNum = self.nodes[destinationId]['num'] meshPacket.to = nodeNum meshPacket.want_ack = wantAck + + # if the user hasn't set an ID for this packet (likely and recommended), we should pick a new unique ID + # so the message can be tracked. + if meshPacket.id == 0: + meshPacket.id = self._generatePacketId() + toRadio.packet.CopyFrom(meshPacket) - self._sendToRadio(toRadio)
+ self._sendToRadio(toRadio) + return meshPacket
@@ -991,7 +1058,8 @@ You probably don't want this - use sendData instead.

Send a position packet to some other node (normally a broadcast)

Also, the device software will notice this packet and use it to automatically set its notion of the local position.

-

If timeSec is not specified (recommended), we will use the local machine time.

+

If timeSec is not specified (recommended), we will use the local machine time.

+

Returns the sent packet. The id field will be populated in this packet and can be used to track future message acks/naks.

Expand source code @@ -1004,6 +1072,8 @@ the local position.

the local position. If timeSec is not specified (recommended), we will use the local machine time. + + Returns the sent packet. The id field will be populated in this packet and can be used to track future message acks/naks. """ meshPacket = mesh_pb2.MeshPacket() if(latitude != 0.0): @@ -1020,7 +1090,7 @@ the local position.

meshPacket.decoded.position.time = int(timeSec) meshPacket.decoded.want_response = wantResponse - self.sendPacket(meshPacket, destinationId, wantAck=wantAck)
+ return self.sendPacket(meshPacket, destinationId, wantAck=wantAck)
@@ -1031,7 +1101,8 @@ the local position.

Arguments

text {string} – The text to send

Keyword Arguments: -destinationId {nodeId or nodeNum} – where to send this message (default: {BROADCAST_ADDR})

+destinationId {nodeId or nodeNum} – where to send this message (default: {BROADCAST_ADDR})

+

Returns the sent packet. The id field will be populated in this packet and can be used to track future message acks/naks.

Expand source code @@ -1044,9 +1115,11 @@ destinationId {nodeId or nodeNum} – where to send this message (default: { Keyword Arguments: destinationId {nodeId or nodeNum} -- where to send this message (default: {BROADCAST_ADDR}) + + Returns the sent packet. The id field will be populated in this packet and can be used to track future message acks/naks. """ - self.sendData(text.encode("utf-8"), destinationId, - dataType=mesh_pb2.Data.CLEAR_TEXT, wantAck=wantAck, wantResponse=wantResponse) + return self.sendData(text.encode("utf-8"), destinationId, + dataType=mesh_pb2.Data.CLEAR_TEXT, wantAck=wantAck, wantResponse=wantResponse)
diff --git a/setup.py b/setup.py index 84f43e5..ea116ab 100644 --- a/setup.py +++ b/setup.py @@ -10,7 +10,7 @@ with open("README.md", "r") as fh: # This call to setup() does all the work setup( name="meshtastic", - version="0.9.2", + version="1.0.1", description="Python API & client shell for talking to Meshtastic devices", long_description=long_description, long_description_content_type="text/markdown",