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",