From 32f3c504d914988919cd771a59a28e2b8a9c8ca4 Mon Sep 17 00:00:00 2001 From: geeksville Date: Sun, 5 Jul 2020 12:01:35 -0700 Subject: [PATCH] 0.7.9 add sendPosition(lat, lng, alt) method also... Use this method for the --settime command line flag - which sets the device time to be the same as the local computers time (in UTC) 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. """ --- .vscode/launch.json | 8 ++++ docs/meshtastic/index.html | 95 ++++++++++++++++++++++++++++++++++++++ meshtastic/__init__.py | 27 +++++++++++ meshtastic/__main__.py | 7 +++ proto | 2 +- setup.py | 2 +- 6 files changed, 139 insertions(+), 2 deletions(-) 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",