Skip to content

Commit

Permalink
feat(waypoint): Waypoint creation/deletion
Browse files Browse the repository at this point in the history
Add methods to send (create or move), delete waypoint.
Add an example script to create, move, delete waypoint.
  • Loading branch information
loic-fejoz committed Dec 18, 2024
1 parent 7c89e23 commit 9284a84
Show file tree
Hide file tree
Showing 2 changed files with 150 additions and 0 deletions.
56 changes: 56 additions & 0 deletions examples/waypoint.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
"""Program to create and delete waypoint
To run:
python3 examples/waypoint.py --port /dev/ttyUSB0 create 45 test the_desc_2 '2024-12-18T23:05:23' 48.74 7.35
python examples/waypoint.py delete 45
"""

import argparse
import datetime
import sys
import time

import meshtastic
import meshtastic.serial_interface

parser = argparse.ArgumentParser(
prog='waypoint',
description='Create and delete Meshtastic waypoint')
parser.add_argument('--port', default=None)
parser.add_argument('--debug', default=False, action='store_true')

subparsers = parser.add_subparsers(dest='cmd')
parser_delete = subparsers.add_parser('delete', help='Delete a waypoint')
parser_delete.add_argument('id', help="id of the waypoint")

parser_create = subparsers.add_parser('create', help='Create a new waypoint')
parser_create.add_argument('id', help="id of the waypoint")
parser_create.add_argument('name', help="name of the waypoint")
parser_create.add_argument('description', help="description of the waypoint")
parser_create.add_argument('expire', help="expiration date of the waypoint as interpreted by datetime.fromisoformat")
parser_create.add_argument('latitude', help="latitude of the waypoint")
parser_create.add_argument('longitude', help="longitude of the waypoint")

args = parser.parse_args()
print(args)

# By default will try to find a meshtastic device,
# otherwise provide a device path like /dev/ttyUSB0
if args.debug:
d = sys.stderr
else:
d = None
with meshtastic.serial_interface.SerialInterface(args.port, debugOut=d) as iface:
if args.cmd == 'create':
p = iface.sendWaypoint(
id=int(args.id),
name=args.name,
description=args.description,
expire=int(datetime.datetime.fromisoformat(args.expire).timestamp()),
latitude=float(args.latitude),
longitude=float(args.longitude),
)
else:
p = iface.deleteWaypoint(int(args.id))
print(p)

# iface.close()
94 changes: 94 additions & 0 deletions meshtastic/mesh_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
import collections
import json
import logging
import math
import random
import secrets
import sys
import threading
import time
Expand Down Expand Up @@ -700,6 +702,98 @@ def onResponseTelemetry(self, p: dict):
"No response from node. At least firmware 2.1.22 is required on the destination node."
)

def sendWaypoint(
self,
name,
description,
expire: int,
id: Optional[int] = None,
latitude: float = 0.0,
longitude: float = 0.0,
destinationId: Union[int, str] = BROADCAST_ADDR,
wantAck: bool = True,
wantResponse: bool = False,
channelIndex: int = 0,
):
"""
Send a waypoint packet to some other node (normally a broadcast)
Returns the sent packet. The id field will be populated in this packet and
can be used to track future message acks/naks.
"""
w = mesh_pb2.Waypoint()
w.name = name
w.description = description
w.expire = expire
if id is None:
seed = secrets.randbits(32)
w.id = math.floor(seed * math.pow(2, -32) * 1e9)
logging.debug(f"w.id:{w.id}")
else:
w.id = id
if latitude != 0.0:
w.latitude_i = int(latitude * 1e7)
logging.debug(f"w.latitude_i:{w.latitude_i}")
if longitude != 0.0:
w.longitude_i = int(longitude * 1e7)
logging.debug(f"w.longitude_i:{w.longitude_i}")

if wantResponse:
onResponse = self.onResponseWaypoint
else:
onResponse = None

d = self.sendData(
w,
destinationId,
portNum=portnums_pb2.PortNum.WAYPOINT_APP,
wantAck=wantAck,
wantResponse=wantResponse,
onResponse=onResponse,
channelIndex=channelIndex,
)
if wantResponse:
self.waitForWaypoint()
return d

def deleteWaypoint(
self,
id: int,
destinationId: Union[int, str] = BROADCAST_ADDR,
wantAck: bool = True,
wantResponse: bool = False,
channelIndex: int = 0,
):
"""
Send a waypoint deletion packet to some other node (normally a broadcast)
NB: The id must be the waypoint's id and not the id of the packet creation.
Returns the sent packet. The id field will be populated in this packet and
can be used to track future message acks/naks.
"""
p = mesh_pb2.Waypoint()
p.id = id
p.expire = 0

if wantResponse:
onResponse = self.onResponseWaypoint
else:
onResponse = None

d = self.sendData(
p,
destinationId,
portNum=portnums_pb2.PortNum.WAYPOINT_APP,
wantAck=wantAck,
wantResponse=wantResponse,
onResponse=onResponse,
channelIndex=channelIndex,
)
if wantResponse:
self.waitForWaypoint()
return d

def _addResponseHandler(
self,
requestId: int,
Expand Down

0 comments on commit 9284a84

Please sign in to comment.