diff --git a/.vscode/launch.json b/.vscode/launch.json index 83c15a3..c1aab52 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -44,6 +44,14 @@ "justMyCode": true, "args": ["--debug", "--test"] }, + { + "name": "meshtastic settime", + "type": "python", + "request": "launch", + "module": "meshtastic", + "justMyCode": true, + "args": ["--debug", "--settime"] + }, { "name": "meshtastic sendtext", "type": "python", diff --git a/docs/meshtastic/index.html b/docs/meshtastic/index.html index c66e4e8..fc29746 100644 --- a/docs/meshtastic/index.html +++ b/docs/meshtastic/index.html @@ -126,6 +126,7 @@ import logging import time import sys import traceback +import time from . import mesh_pb2 from . import util from pubsub import pub @@ -185,6 +186,32 @@ class MeshInterface: meshPacket.decoded.want_response = wantResponse 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): + """ + 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. + """ + meshPacket = mesh_pb2.MeshPacket() + if(latitude != 0.0): + meshPacket.decoded.position.latitude_i = int(latitude / 1e-7) + + if(longitude != 0.0): + meshPacket.decoded.position.longitude_i = int(longitude / 1e-7) + + if(altitude != 0): + meshPacket.decoded.position.altitude = int(altitude) + + if timeSec == 0: + timeSec = time.time() # returns unix timestamp in seconds + meshPacket.decoded.position.time = int(timeSec) + + meshPacket.decoded.want_response = wantResponse + 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.""" @@ -623,6 +650,7 @@ class StreamInterface(MeshInterface): @@ -682,6 +710,32 @@ debugOut

meshPacket.decoded.want_response = wantResponse 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): + """ + 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. + """ + meshPacket = mesh_pb2.MeshPacket() + if(latitude != 0.0): + meshPacket.decoded.position.latitude_i = int(latitude / 1e-7) + + if(longitude != 0.0): + meshPacket.decoded.position.longitude_i = int(longitude / 1e-7) + + if(altitude != 0): + meshPacket.decoded.position.altitude = int(altitude) + + if timeSec == 0: + timeSec = time.time() # returns unix timestamp in seconds + meshPacket.decoded.position.time = int(timeSec) + + meshPacket.decoded.want_response = wantResponse + 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.""" @@ -908,6 +962,45 @@ You probably don't want this - use sendData instead.

self._sendToRadio(toRadio) +
+def sendPosition(self, latitude=0.0, longitude=0.0, altitude=0, timeSec=0, destinationId='^all', wantAck=False, wantResponse=False) +
+
+

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.

+
+ +Expand source code + +
def sendPosition(self, latitude=0.0, longitude=0.0, altitude=0, timeSec=0, destinationId=BROADCAST_ADDR, wantAck=False, wantResponse=False):
+    """
+    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.
+    """
+    meshPacket = mesh_pb2.MeshPacket()
+    if(latitude != 0.0):
+        meshPacket.decoded.position.latitude_i = int(latitude / 1e-7)
+
+    if(longitude != 0.0):
+        meshPacket.decoded.position.longitude_i = int(longitude / 1e-7)
+
+    if(altitude != 0):
+        meshPacket.decoded.position.altitude = int(altitude)
+
+    if timeSec == 0:
+        timeSec = time.time() # returns unix timestamp in seconds
+    meshPacket.decoded.position.time = int(timeSec)
+
+    meshPacket.decoded.want_response = wantResponse
+    self.sendPacket(meshPacket, destinationId, wantAck=wantAck)
+
+
def sendText(self, text, destinationId='^all', wantAck=False, wantResponse=False)
@@ -1119,6 +1212,7 @@ debugOut {stream} – If a stream is provided, any debug serial output from @@ -1164,6 +1258,7 @@ debugOut {stream} – If a stream is provided, any debug serial output from diff --git a/meshtastic/__init__.py b/meshtastic/__init__.py index 100e262..1b82fca 100644 --- a/meshtastic/__init__.py +++ b/meshtastic/__init__.py @@ -55,6 +55,7 @@ import logging import time import sys import traceback +import time from . import mesh_pb2 from . import util from pubsub import pub @@ -114,6 +115,32 @@ class MeshInterface: meshPacket.decoded.want_response = wantResponse 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): + """ + 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. + """ + meshPacket = mesh_pb2.MeshPacket() + if(latitude != 0.0): + meshPacket.decoded.position.latitude_i = int(latitude / 1e-7) + + if(longitude != 0.0): + meshPacket.decoded.position.longitude_i = int(longitude / 1e-7) + + if(altitude != 0): + meshPacket.decoded.position.altitude = int(altitude) + + if timeSec == 0: + timeSec = time.time() # returns unix timestamp in seconds + meshPacket.decoded.position.time = int(timeSec) + + meshPacket.decoded.want_response = wantResponse + 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.""" diff --git a/meshtastic/__main__.py b/meshtastic/__main__.py index 9140dd0..fdf447d 100644 --- a/meshtastic/__main__.py +++ b/meshtastic/__main__.py @@ -30,6 +30,10 @@ def onConnected(interface): global args print("Connected to radio") try: + if args.settime: + print("Setting device RTC time") + interface.sendPosition() # can include lat/long/alt etc: latitude = 37.5, longitude = -122.1 + if args.sendtext: print(f"Sending text message {args.sendtext} to {args.dest}") interface.sendText(args.sendtext, args.dest, @@ -100,6 +104,9 @@ def main(): parser.add_argument( "--sendtext", help="Send a text message") + parser.add_argument( + "--settime", help="Set the real time clock on the device", action="store_true") + parser.add_argument("--debug", help="Show API library debug log messages", action="store_true") diff --git a/proto b/proto index 9d083d5..ab28131 160000 --- a/proto +++ b/proto @@ -1 +1 @@ -Subproject commit 9d083d5d4ff4ef095135b18468004eaba77cb691 +Subproject commit ab281311c49f2a9099d66fc6d211dca96d9603b3 diff --git a/setup.py b/setup.py index 3abfb9e..82ae9fe 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.7.8", + version="0.7.9", description="Python API & client shell for talking to Meshtastic devices", long_description=long_description, long_description_content_type="text/markdown",