mirror of
https://github.com/meshtastic/python.git
synced 2026-01-02 12:57:56 -05:00
Compare commits
19 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
23bb2e26f9 | ||
|
|
b59ecff272 | ||
|
|
17f3605736 | ||
|
|
a689fd73a2 | ||
|
|
da30e1141a | ||
|
|
b4bd9568e4 | ||
|
|
aed4f25cf5 | ||
|
|
5c312bedc1 | ||
|
|
428e9a228c | ||
|
|
4500850063 | ||
|
|
bcce5687c5 | ||
|
|
b9d805057f | ||
|
|
d77335caa7 | ||
|
|
b692ef4cfb | ||
|
|
e725292ee0 | ||
|
|
abf9e96d3d | ||
|
|
740f0f0961 | ||
|
|
abb00251c0 | ||
|
|
3335b3d651 |
1
.github/workflows/release.yml
vendored
1
.github/workflows/release.yml
vendored
@@ -52,6 +52,7 @@ jobs:
|
|||||||
prerelease: true
|
prerelease: true
|
||||||
release_name: Meshtastic Python ${{ steps.get_version.outputs.version }}
|
release_name: Meshtastic Python ${{ steps.get_version.outputs.version }}
|
||||||
tag_name: ${{ steps.get_version.outputs.version }}
|
tag_name: ${{ steps.get_version.outputs.version }}
|
||||||
|
commitish: ${{ steps.commit_updated.outputs.sha }}
|
||||||
body: |
|
body: |
|
||||||
Autogenerated by github action, developer should edit as required before publishing...
|
Autogenerated by github action, developer should edit as required before publishing...
|
||||||
env:
|
env:
|
||||||
|
|||||||
@@ -314,35 +314,17 @@ def onConnected(interface):
|
|||||||
print("Setting device position and enabling fixed position setting")
|
print("Setting device position and enabling fixed position setting")
|
||||||
# can include lat/long/alt etc: latitude = 37.5, longitude = -122.1
|
# can include lat/long/alt etc: latitude = 37.5, longitude = -122.1
|
||||||
interface.localNode.setFixedPosition(lat, lon, alt)
|
interface.localNode.setFixedPosition(lat, lon, alt)
|
||||||
elif not args.no_time:
|
|
||||||
# We normally provide a current time to the mesh when we connect
|
|
||||||
if (
|
|
||||||
interface.localNode.nodeNum in interface.nodesByNum
|
|
||||||
and "position" in interface.nodesByNum[interface.localNode.nodeNum]
|
|
||||||
):
|
|
||||||
# send the same position the node already knows, just to update time
|
|
||||||
position = interface.nodesByNum[interface.localNode.nodeNum]["position"]
|
|
||||||
interface.sendPosition(
|
|
||||||
position.get("latitude", 0.0),
|
|
||||||
position.get("longitude", 0.0),
|
|
||||||
position.get("altitude", 0.0),
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
interface.sendPosition()
|
|
||||||
|
|
||||||
if args.set_owner:
|
if args.set_owner or args.set_owner_short:
|
||||||
closeNow = True
|
closeNow = True
|
||||||
waitForAckNak = True
|
waitForAckNak = True
|
||||||
print(f"Setting device owner to {args.set_owner}")
|
if args.set_owner and args.set_owner_short:
|
||||||
interface.getNode(args.dest, False).setOwner(args.set_owner)
|
print(f"Setting device owner to {args.set_owner} and short name to {args.set_owner_short}")
|
||||||
|
elif args.set_owner:
|
||||||
if args.set_owner_short:
|
print(f"Setting device owner to {args.set_owner}")
|
||||||
closeNow = True
|
else: # short name only
|
||||||
waitForAckNak = True
|
print(f"Setting device owner short to {args.set_owner_short}")
|
||||||
print(f"Setting device owner short to {args.set_owner_short}")
|
interface.getNode(args.dest, False).setOwner(long_name=args.set_owner, short_name=args.set_owner_short)
|
||||||
interface.getNode(args.dest, False).setOwner(
|
|
||||||
long_name=None, short_name=args.set_owner_short
|
|
||||||
)
|
|
||||||
|
|
||||||
# TODO: add to export-config and configure
|
# TODO: add to export-config and configure
|
||||||
if args.set_canned_message:
|
if args.set_canned_message:
|
||||||
@@ -778,7 +760,8 @@ def onConnected(interface):
|
|||||||
channelIndex = mt_config.channel_index
|
channelIndex = mt_config.channel_index
|
||||||
if channelIndex is None:
|
if channelIndex is None:
|
||||||
meshtastic.util.our_exit("Warning: Need to specify '--ch-index'.", 1)
|
meshtastic.util.our_exit("Warning: Need to specify '--ch-index'.", 1)
|
||||||
ch = interface.getNode(args.dest).channels[channelIndex]
|
node = interface.getNode(args.dest)
|
||||||
|
ch = node.channels[channelIndex]
|
||||||
|
|
||||||
if args.ch_enable or args.ch_disable:
|
if args.ch_enable or args.ch_disable:
|
||||||
print(
|
print(
|
||||||
@@ -836,7 +819,7 @@ def onConnected(interface):
|
|||||||
ch.role = channel_pb2.Channel.Role.DISABLED
|
ch.role = channel_pb2.Channel.Role.DISABLED
|
||||||
|
|
||||||
print(f"Writing modified channels to device")
|
print(f"Writing modified channels to device")
|
||||||
interface.getNode(args.dest).writeChannel(channelIndex)
|
node.writeChannel(channelIndex)
|
||||||
|
|
||||||
if args.get_canned_message:
|
if args.get_canned_message:
|
||||||
closeNow = True
|
closeNow = True
|
||||||
@@ -1466,6 +1449,10 @@ def initParser():
|
|||||||
|
|
||||||
group.add_argument("--set-owner", help="Set device owner name", action="store")
|
group.add_argument("--set-owner", help="Set device owner name", action="store")
|
||||||
|
|
||||||
|
group.add_argument(
|
||||||
|
"--set-owner-short", help="Set device owner short name", action="store"
|
||||||
|
)
|
||||||
|
|
||||||
group.add_argument(
|
group.add_argument(
|
||||||
"--set-canned-message",
|
"--set-canned-message",
|
||||||
help="Set the canned messages plugin message (up to 200 characters).",
|
help="Set the canned messages plugin message (up to 200 characters).",
|
||||||
@@ -1478,10 +1465,6 @@ def initParser():
|
|||||||
action="store",
|
action="store",
|
||||||
)
|
)
|
||||||
|
|
||||||
group.add_argument(
|
|
||||||
"--set-owner-short", help="Set device owner short name", action="store"
|
|
||||||
)
|
|
||||||
|
|
||||||
group.add_argument(
|
group.add_argument(
|
||||||
"--set-ham", help="Set licensed Ham ID and turn off encryption", action="store"
|
"--set-ham", help="Set licensed Ham ID and turn off encryption", action="store"
|
||||||
)
|
)
|
||||||
@@ -1587,7 +1570,7 @@ def initParser():
|
|||||||
|
|
||||||
group.add_argument(
|
group.add_argument(
|
||||||
"--no-time",
|
"--no-time",
|
||||||
help="Suppress sending the current time to the mesh",
|
help="Deprecated. Retained for backwards compatibility in scripts, but is a no-op.",
|
||||||
action="store_true",
|
action="store_true",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -442,7 +442,6 @@ class MeshInterface: # pylint: disable=R0902
|
|||||||
latitude: float = 0.0,
|
latitude: float = 0.0,
|
||||||
longitude: float = 0.0,
|
longitude: float = 0.0,
|
||||||
altitude: int = 0,
|
altitude: int = 0,
|
||||||
timeSec: int = 0,
|
|
||||||
destinationId: Union[int, str] = BROADCAST_ADDR,
|
destinationId: Union[int, str] = BROADCAST_ADDR,
|
||||||
wantAck: bool = False,
|
wantAck: bool = False,
|
||||||
wantResponse: bool = False,
|
wantResponse: bool = False,
|
||||||
@@ -454,8 +453,6 @@ class MeshInterface: # pylint: disable=R0902
|
|||||||
Also, the device software will notice this packet and use it to automatically
|
Also, the device software will notice this packet and use it to automatically
|
||||||
set its notion of the local position.
|
set its notion of 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
|
Returns the sent packet. The id field will be populated in this packet and
|
||||||
can be used to track future message acks/naks.
|
can be used to track future message acks/naks.
|
||||||
"""
|
"""
|
||||||
@@ -472,11 +469,6 @@ class MeshInterface: # pylint: disable=R0902
|
|||||||
p.altitude = int(altitude)
|
p.altitude = int(altitude)
|
||||||
logging.debug(f"p.altitude:{p.altitude}")
|
logging.debug(f"p.altitude:{p.altitude}")
|
||||||
|
|
||||||
if timeSec == 0:
|
|
||||||
timeSec = int(time.time()) # returns unix timestamp in seconds
|
|
||||||
p.time = timeSec
|
|
||||||
logging.debug(f"p.time:{p.time}")
|
|
||||||
|
|
||||||
if wantResponse:
|
if wantResponse:
|
||||||
onResponse = self.onResponsePosition
|
onResponse = self.onResponsePosition
|
||||||
else:
|
else:
|
||||||
@@ -812,19 +804,22 @@ class MeshInterface: # pylint: disable=R0902
|
|||||||
lambda: pub.sendMessage("meshtastic.connection.lost", interface=self)
|
lambda: pub.sendMessage("meshtastic.connection.lost", interface=self)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def sendHeartbeat(self):
|
||||||
|
"""Sends a heartbeat to the radio. Can be used to verify the connection is healthy."""
|
||||||
|
p = mesh_pb2.ToRadio()
|
||||||
|
p.heartbeat.CopyFrom(mesh_pb2.Heartbeat())
|
||||||
|
self._sendToRadio(p)
|
||||||
|
|
||||||
def _startHeartbeat(self):
|
def _startHeartbeat(self):
|
||||||
"""We need to send a heartbeat message to the device every X seconds"""
|
"""We need to send a heartbeat message to the device every X seconds"""
|
||||||
|
|
||||||
def callback():
|
def callback():
|
||||||
self.heartbeatTimer = None
|
self.heartbeatTimer = None
|
||||||
i = 300
|
interval = 300
|
||||||
logging.debug(f"Sending heartbeat, interval {i} seconds")
|
logging.debug(f"Sending heartbeat, interval {interval} seconds")
|
||||||
if i != 0:
|
self.heartbeatTimer = threading.Timer(interval, callback)
|
||||||
self.heartbeatTimer = threading.Timer(i, callback)
|
self.heartbeatTimer.start()
|
||||||
self.heartbeatTimer.start()
|
self.sendHeartbeat()
|
||||||
p = mesh_pb2.ToRadio()
|
|
||||||
p.heartbeat.CopyFrom(mesh_pb2.Heartbeat())
|
|
||||||
self._sendToRadio(p)
|
|
||||||
|
|
||||||
callback() # run our periodic callback now, it will make another timer if necessary
|
callback() # run our periodic callback now, it will make another timer if necessary
|
||||||
|
|
||||||
@@ -975,13 +970,6 @@ class MeshInterface: # pylint: disable=R0902
|
|||||||
self.localNode.nodeNum = self.myInfo.my_node_num
|
self.localNode.nodeNum = self.myInfo.my_node_num
|
||||||
logging.debug(f"Received myinfo: {stripnl(fromRadio.my_info)}")
|
logging.debug(f"Received myinfo: {stripnl(fromRadio.my_info)}")
|
||||||
|
|
||||||
failmsg = None
|
|
||||||
|
|
||||||
if failmsg:
|
|
||||||
self.failure = MeshInterface.MeshInterfaceError(failmsg)
|
|
||||||
self.isConnected.set() # let waitConnected return this exception
|
|
||||||
self.close()
|
|
||||||
|
|
||||||
elif fromRadio.HasField("metadata"):
|
elif fromRadio.HasField("metadata"):
|
||||||
self.metadata = fromRadio.metadata
|
self.metadata = fromRadio.metadata
|
||||||
logging.debug(f"Received device metadata: {stripnl(fromRadio.metadata)}")
|
logging.debug(f"Received device metadata: {stripnl(fromRadio.metadata)}")
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import base64
|
|||||||
import logging
|
import logging
|
||||||
import time
|
import time
|
||||||
|
|
||||||
from typing import Union
|
from typing import Optional, Union
|
||||||
|
|
||||||
from meshtastic.protobuf import admin_pb2, apponly_pb2, channel_pb2, localonly_pb2, mesh_pb2, portnums_pb2
|
from meshtastic.protobuf import admin_pb2, apponly_pb2, channel_pb2, localonly_pb2, mesh_pb2, portnums_pb2
|
||||||
from meshtastic.util import (
|
from meshtastic.util import (
|
||||||
@@ -279,7 +279,7 @@ class Node:
|
|||||||
return c.index
|
return c.index
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
def setOwner(self, long_name=None, short_name=None, is_licensed=False):
|
def setOwner(self, long_name: Optional[str]=None, short_name: Optional[str]=None, is_licensed: bool=False):
|
||||||
"""Set device owner name"""
|
"""Set device owner name"""
|
||||||
logging.debug(f"in setOwner nodeNum:{self.nodeNum}")
|
logging.debug(f"in setOwner nodeNum:{self.nodeNum}")
|
||||||
p = admin_pb2.AdminMessage()
|
p = admin_pb2.AdminMessage()
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -324,6 +324,14 @@ class _HardwareModelEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._
|
|||||||
Heltec Mesh Node T114 board with nRF52840 CPU, and a 1.14 inch TFT display, Ultimate low-power design,
|
Heltec Mesh Node T114 board with nRF52840 CPU, and a 1.14 inch TFT display, Ultimate low-power design,
|
||||||
specifically adapted for the Meshtatic project
|
specifically adapted for the Meshtatic project
|
||||||
"""
|
"""
|
||||||
|
SENSECAP_INDICATOR: _HardwareModel.ValueType # 70
|
||||||
|
"""
|
||||||
|
Sensecap Indicator from Seeed Studio. ESP32-S3 device with TFT and RP2040 coprocessor
|
||||||
|
"""
|
||||||
|
TRACKER_T1000_E: _HardwareModel.ValueType # 71
|
||||||
|
"""
|
||||||
|
Seeed studio T1000-E tracker card. NRF52840 w/ LR1110 radio, GPS, button, buzzer, and sensors.
|
||||||
|
"""
|
||||||
PRIVATE_HW: _HardwareModel.ValueType # 255
|
PRIVATE_HW: _HardwareModel.ValueType # 255
|
||||||
"""
|
"""
|
||||||
------------------------------------------------------------------------------------------------------------------------------------------
|
------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
@@ -632,6 +640,14 @@ HELTEC_MESH_NODE_T114: HardwareModel.ValueType # 69
|
|||||||
Heltec Mesh Node T114 board with nRF52840 CPU, and a 1.14 inch TFT display, Ultimate low-power design,
|
Heltec Mesh Node T114 board with nRF52840 CPU, and a 1.14 inch TFT display, Ultimate low-power design,
|
||||||
specifically adapted for the Meshtatic project
|
specifically adapted for the Meshtatic project
|
||||||
"""
|
"""
|
||||||
|
SENSECAP_INDICATOR: HardwareModel.ValueType # 70
|
||||||
|
"""
|
||||||
|
Sensecap Indicator from Seeed Studio. ESP32-S3 device with TFT and RP2040 coprocessor
|
||||||
|
"""
|
||||||
|
TRACKER_T1000_E: HardwareModel.ValueType # 71
|
||||||
|
"""
|
||||||
|
Seeed studio T1000-E tracker card. NRF52840 w/ LR1110 radio, GPS, button, buzzer, and sensors.
|
||||||
|
"""
|
||||||
PRIVATE_HW: HardwareModel.ValueType # 255
|
PRIVATE_HW: HardwareModel.ValueType # 255
|
||||||
"""
|
"""
|
||||||
------------------------------------------------------------------------------------------------------------------------------------------
|
------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -185,7 +185,7 @@ def test_sendPosition(caplog):
|
|||||||
with caplog.at_level(logging.DEBUG):
|
with caplog.at_level(logging.DEBUG):
|
||||||
iface.sendPosition()
|
iface.sendPosition()
|
||||||
iface.close()
|
iface.close()
|
||||||
assert re.search(r"p.time:", caplog.text, re.MULTILINE)
|
# assert re.search(r"p.time:", caplog.text, re.MULTILINE)
|
||||||
|
|
||||||
|
|
||||||
# TODO
|
# TODO
|
||||||
|
|||||||
Submodule protobufs updated: 10494bf328...b1a79d5db0
@@ -1,6 +1,6 @@
|
|||||||
[tool.poetry]
|
[tool.poetry]
|
||||||
name = "meshtastic"
|
name = "meshtastic"
|
||||||
version = "2.4.0a0"
|
version = "2.4.1"
|
||||||
description = "Python API & client shell for talking to Meshtastic devices"
|
description = "Python API & client shell for talking to Meshtastic devices"
|
||||||
authors = ["Meshtastic Developers <contact@meshtastic.org>"]
|
authors = ["Meshtastic Developers <contact@meshtastic.org>"]
|
||||||
license = "GPL-3.0-only"
|
license = "GPL-3.0-only"
|
||||||
|
|||||||
Reference in New Issue
Block a user