Compare commits

...

54 Commits
2.1.6 ... 2.2.7

Author SHA1 Message Date
github-actions
20bb1ebdfa bump version 2023-09-20 12:01:35 +00:00
Ben Meadors
a6d20abcdf Protobufs 2023-09-20 07:00:21 -05:00
github-actions
7d9e75cf3f bump version 2023-09-14 12:02:11 +00:00
Ben Meadors
7c3df00b46 Protos 2023-09-14 07:01:02 -05:00
github-actions
28e848ace6 bump version 2023-09-12 20:53:06 +00:00
Ben Meadors
849724a129 Protobufs 2023-09-12 15:51:52 -05:00
Ben Meadors
309b069558 Protos 2023-09-07 07:23:15 -05:00
github-actions
cbedc982b6 bump version 2023-09-07 12:17:06 +00:00
Ben Meadors
dd482f2f89 Merge pull request #458 from EliSchleifer/master
Upgrade trunk to 1.15.0; enable new security linters
2023-09-07 06:30:33 -05:00
Eli Schleifer
29331cc3d2 sort linters 2023-09-06 13:16:27 -07:00
Eli Schleifer
4f2fbe39c0 Upgrade trunk to 1.15.0; enable new security linters 2023-09-06 13:11:47 -07:00
github-actions
b2f3ba11ae bump version 2023-08-26 00:28:47 +00:00
Ben Meadors
08c0b0e940 Protos 2023-08-25 19:28:06 -05:00
github-actions
775cb4d650 bump version 2023-08-21 20:32:45 +00:00
Ben Meadors
52cc825b3e Update protobufs 2023-08-21 14:56:26 -05:00
Ben Meadors
ce3065b37d Merge pull request #457 from GUVWAF/reqTelemetry
Add `request-telemetry` option
2023-08-21 14:50:27 -05:00
GUVWAF
d6ee815183 Only wait if response is wanted 2023-08-21 21:09:12 +02:00
GUVWAF
0192eed76e Spacing 2023-08-21 21:04:30 +02:00
GUVWAF
9858fa1976 Add request-telemetry option 2023-08-21 20:58:27 +02:00
Ben Meadors
95bfc0b428 Merge pull request #455 from bmidgley/brad/error-exit
Exit with an error code on failure
2023-08-11 06:21:36 -05:00
Brad Midgley
130c82ae4f Exit with an error code on failure 2023-08-10 22:18:08 -06:00
Ben Meadors
3698f2e4fb Add bump_version back 2023-08-08 19:09:54 -05:00
Ben Meadors
f58f8bdb1d Comment bump version for now 2023-08-08 16:50:09 -05:00
Ben Meadors
e76c9852d6 2.2 changes and added device_metadata 2023-08-08 16:40:15 -05:00
Ben Meadors
0788c1fadc Update protos to 2.2 and add neighbor_info 2023-08-08 13:48:51 -05:00
github-actions
a8057ac670 bump version 2023-08-08 17:49:28 +00:00
Ben Meadors
bb067e0e1e Remove min app version check 2023-08-08 12:48:03 -05:00
github-actions
755e68040f bump version 2023-08-06 20:54:23 +00:00
Ben Meadors
1687a4cb90 Update protos 2023-08-06 15:53:37 -05:00
github-actions
03398c7e3b bump version 2023-08-01 01:45:41 +00:00
Ben Meadors
d27be003c7 Update protos 2023-07-31 20:12:28 -05:00
github-actions
8e39a00c30 bump version 2023-07-26 00:47:11 +00:00
Ben Meadors
055da95b8a Update protos and remove old max_channels check 2023-07-25 19:46:17 -05:00
Ben Meadors
0c2ad5c77c Merge pull request #453 from luzpaz/typos
Fix various source comment typos
2023-07-25 19:42:44 -05:00
luzpaz
0a88ca6a5c Fix various source comment typos
Found via `codespell -q 3`
2023-07-15 01:04:47 +00:00
github-actions
51079d4f25 bump version 2023-07-09 11:26:51 +00:00
Ben Meadors
4ca3b4bf58 Update protobufs 2023-07-09 06:25:24 -05:00
Ben Meadors
25d42d3361 Merge pull request #451 from hhartzer/python-3.11
Update Github CI removing end-of-lifed Python 3.6 and 3.7, add 3.11
2023-07-07 19:43:51 -05:00
Henrich Hartzer
a1bffe4f26 Update Github CI removing end-of-lifed Python 3.6 and 3.7, add 3.11 2023-07-07 15:44:19 +00:00
github-actions
b87630803f bump version 2023-06-28 01:16:18 +00:00
Ben Meadors
e2c7a2c32c Update protobufs 2023-06-27 20:14:40 -05:00
Ben Meadors
9dda5d6d2d Merge pull request #449 from pdxlocations/no-psk
Show Channels with No PSK on --info
2023-06-25 14:48:04 -05:00
Ben Meadors
c3be392533 Merge pull request #450 from GUVWAF/NeighborInfo
Setter for NeighborInfo Module
2023-06-25 14:47:22 -05:00
GUVWAF
f63f2e3e39 Merge remote-tracking branch 'origin/master' into NeighborInfo 2023-06-25 15:55:38 +02:00
github-actions
c8dbac7770 Update protobuf submodule 2023-06-25 13:53:04 +00:00
GUVWAF
959c597e33 Setter for NeighborInfo 2023-06-25 15:50:59 +02:00
pdxlocations
4b0ca13ad1 list channels with no psk 2023-06-15 21:29:46 -07:00
github-actions
811bfdcb8c bump version 2023-05-30 12:46:45 +00:00
Ben Meadors
79095dc243 Update protos 2023-05-30 07:38:53 -05:00
github-actions
ff9ab44796 bump version 2023-05-28 14:33:46 +00:00
Ben Meadors
77dea8ee67 Update protos 2023-05-28 09:32:34 -05:00
Ben Meadors
c2eb466792 Merge pull request #445 from mverch67/fix-444
Fix TypeError: 'NoneType'
2023-05-26 05:49:51 -05:00
Manuel Verch
b4405dc60e Fix TypeError: 'NoneType' 2023-04-11 17:24:45 +02:00
github-actions
dc3d43c57c bump version 2023-04-11 15:06:05 +00:00
22 changed files with 476 additions and 230 deletions

View File

@@ -13,11 +13,10 @@ jobs:
strategy:
matrix:
python-version:
- "3.6"
- "3.7"
- "3.8"
- "3.9"
- "3.10"
- "3.11"
steps:
- uses: actions/checkout@v2
- name: Install Python 3
@@ -55,11 +54,10 @@ jobs:
strategy:
matrix:
python-version:
- "3.6"
- "3.7"
- "3.8"
- "3.9"
- "3.10"
- "3.11"
steps:
- uses: actions/checkout@v2
- name: Install Python 3

1
.trunk/.gitignore vendored
View File

@@ -2,6 +2,7 @@
*logs
*actions
*notifications
*tools
plugins
user_trunk.yaml
user.yaml

View File

@@ -1,33 +1,40 @@
version: 0.1
cli:
version: 1.7.0
version: 1.15.0
plugins:
sources:
- id: trunk
ref: v0.0.14
ref: v1.2.2
uri: https://github.com/trunk-io/plugins
lint:
disabled:
- bandit
ignore:
- linters: [ALL]
paths:
# Ignore generated files
- meshtastic/*_pb2.py
enabled:
- actionlint@1.6.23
- black@23.3.0
- actionlint@1.6.25
- black@23.7.0
- checkov@2.4.9
- git-diff-check
- gitleaks@8.16.2
- gitleaks@8.18.0
- isort@5.12.0
- markdownlint@0.33.0
- prettier@2.8.7
- pylint@2.17.1
- ruff@0.0.260
- markdownlint@0.36.0
- osv-scanner@1.3.6
- prettier@3.0.3
- pylint@2.17.5
- ruff@0.0.287
- shellcheck@0.9.0
- shfmt@3.5.0
- yamllint@1.30.0
- shfmt@3.6.0
- taplo@0.8.1
- trivy@0.44.1
- trufflehog@3.54.3
- yamllint@1.32.0
runtimes:
enabled:
- go@1.19.5
- go@1.21.0
- node@18.12.1
- python@3.10.8
actions:

View File

@@ -1,4 +1,4 @@
# Note: Docs are generated from this command below, albeit from Vercel.
# The docs/ dir is not used and is no longer commited.
# The docs/ dir is not used and is no longer committed.
# see sachaw if you have questions
pdoc3 --html -f --output-dir docs meshtastic

View File

@@ -10,9 +10,6 @@ iface = meshtastic.serial_interface.SerialInterface()
# call showInfo() just to ensure values are populated
# info = iface.showInfo()
if iface.myInfo:
# print(f'myInfo:{iface.myInfo}')
print(f"firmware_version:{iface.myInfo.firmware_version}")
if iface.nodes:
for n in iface.nodes.values():

View File

@@ -98,7 +98,7 @@ LOCAL_ADDR = "^local"
"""A special ID that means the local node"""
BROADCAST_NUM = 0xFFFFFFFF
"""if using 8 bit nodenums this will be shortend on the target"""
"""if using 8 bit nodenums this will be shortened on the target"""
BROADCAST_ADDR = "^all"
"""A special ID that means broadcast"""
@@ -172,7 +172,7 @@ def _onNodeInfoReceive(iface, asDict):
# update node DB as needed
n = iface._getOrCreateByNum(asDict["from"])
n["user"] = p
# We now have a node ID, make sure it is uptodate in that table
# We now have a node ID, make sure it is up-to-date in that table
iface.nodes[p["id"]] = n
_receiveInfoUpdate(iface, asDict)

View File

@@ -412,6 +412,13 @@ def onConnected(interface):
print(f"Sending traceroute request to {dest} (this could take a while)")
interface.sendTraceRoute(dest, hopLimit)
if args.request_telemetry:
if args.dest == BROADCAST_ADDR:
meshtastic.util.our_exit("Warning: Must use a destination node ID.")
else:
print(f"Sending telemetry request to {args.dest} (this could take a while)")
interface.sendTelemetry(destinationId=args.dest, wantResponse=True)
if args.gpio_wrb or args.gpio_rd or args.gpio_watch:
if args.dest == BROADCAST_ADDR:
meshtastic.util.our_exit("Warning: Must use a destination node ID.")
@@ -779,6 +786,7 @@ def onConnected(interface):
except Exception as ex:
print(f"Aborting due to: {ex}")
interface.close() # close the connection now, so that our app exits
sys.exit(1)
def printConfig(config):
@@ -1187,6 +1195,14 @@ def initParser():
"Only nodes that have the encryption key can be traced.",
)
parser.add_argument(
"--request-telemetry",
help="Request telemetry from a node. "
"You need pass the destination ID as argument with '--dest'. "
"For repeaters, the nodeNum is required.",
action="store_true",
)
parser.add_argument(
"--ack",
help="Use in combination with --sendtext to wait for an acknowledgment.",

View File

@@ -14,17 +14,19 @@ _sym_db = _symbol_database.Default()
from meshtastic import channel_pb2 as meshtastic_dot_channel__pb2
from meshtastic import config_pb2 as meshtastic_dot_config__pb2
from meshtastic import connection_status_pb2 as meshtastic_dot_connection__status__pb2
from meshtastic import deviceonly_pb2 as meshtastic_dot_deviceonly__pb2
from meshtastic import mesh_pb2 as meshtastic_dot_mesh__pb2
from meshtastic import module_config_pb2 as meshtastic_dot_module__config__pb2
from meshtastic import connection_status_pb2 as meshtastic_dot_connection__status__pb2
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x16meshtastic/admin.proto\x1a\x18meshtastic/channel.proto\x1a\x17meshtastic/config.proto\x1a\x15meshtastic/mesh.proto\x1a\x1emeshtastic/module_config.proto\x1a\"meshtastic/connection_status.proto\"\xd8\x0c\n\x0c\x41\x64minMessage\x12\x1d\n\x13get_channel_request\x18\x01 \x01(\rH\x00\x12(\n\x14get_channel_response\x18\x02 \x01(\x0b\x32\x08.ChannelH\x00\x12\x1b\n\x11get_owner_request\x18\x03 \x01(\x08H\x00\x12#\n\x12get_owner_response\x18\x04 \x01(\x0b\x32\x05.UserH\x00\x12\x36\n\x12get_config_request\x18\x05 \x01(\x0e\x32\x18.AdminMessage.ConfigTypeH\x00\x12&\n\x13get_config_response\x18\x06 \x01(\x0b\x32\x07.ConfigH\x00\x12\x43\n\x19get_module_config_request\x18\x07 \x01(\x0e\x32\x1e.AdminMessage.ModuleConfigTypeH\x00\x12\x33\n\x1aget_module_config_response\x18\x08 \x01(\x0b\x32\r.ModuleConfigH\x00\x12\x34\n*get_canned_message_module_messages_request\x18\n \x01(\x08H\x00\x12\x35\n+get_canned_message_module_messages_response\x18\x0b \x01(\tH\x00\x12%\n\x1bget_device_metadata_request\x18\x0c \x01(\x08H\x00\x12\x37\n\x1cget_device_metadata_response\x18\r \x01(\x0b\x32\x0f.DeviceMetadataH\x00\x12\x1e\n\x14get_ringtone_request\x18\x0e \x01(\x08H\x00\x12\x1f\n\x15get_ringtone_response\x18\x0f \x01(\tH\x00\x12.\n$get_device_connection_status_request\x18\x10 \x01(\x08H\x00\x12H\n%get_device_connection_status_response\x18\x11 \x01(\x0b\x32\x17.DeviceConnectionStatusH\x00\x12&\n\x0cset_ham_mode\x18\x12 \x01(\x0b\x32\x0e.HamParametersH\x00\x12\x1a\n\tset_owner\x18 \x01(\x0b\x32\x05.UserH\x00\x12\x1f\n\x0bset_channel\x18! \x01(\x0b\x32\x08.ChannelH\x00\x12\x1d\n\nset_config\x18\" \x01(\x0b\x32\x07.ConfigH\x00\x12*\n\x11set_module_config\x18# \x01(\x0b\x32\r.ModuleConfigH\x00\x12,\n\"set_canned_message_module_messages\x18$ \x01(\tH\x00\x12\x1e\n\x14set_ringtone_message\x18% \x01(\tH\x00\x12\x1d\n\x13\x62\x65gin_edit_settings\x18@ \x01(\x08H\x00\x12\x1e\n\x14\x63ommit_edit_settings\x18\x41 \x01(\x08H\x00\x12\x1c\n\x12reboot_ota_seconds\x18_ \x01(\x05H\x00\x12\x18\n\x0e\x65xit_simulator\x18` \x01(\x08H\x00\x12\x18\n\x0ereboot_seconds\x18\x61 \x01(\x05H\x00\x12\x1a\n\x10shutdown_seconds\x18\x62 \x01(\x05H\x00\x12\x17\n\rfactory_reset\x18\x63 \x01(\x05H\x00\x12\x16\n\x0cnodedb_reset\x18\x64 \x01(\x05H\x00\"\x95\x01\n\nConfigType\x12\x11\n\rDEVICE_CONFIG\x10\x00\x12\x13\n\x0fPOSITION_CONFIG\x10\x01\x12\x10\n\x0cPOWER_CONFIG\x10\x02\x12\x12\n\x0eNETWORK_CONFIG\x10\x03\x12\x12\n\x0e\x44ISPLAY_CONFIG\x10\x04\x12\x0f\n\x0bLORA_CONFIG\x10\x05\x12\x14\n\x10\x42LUETOOTH_CONFIG\x10\x06\"\xd3\x01\n\x10ModuleConfigType\x12\x0f\n\x0bMQTT_CONFIG\x10\x00\x12\x11\n\rSERIAL_CONFIG\x10\x01\x12\x13\n\x0f\x45XTNOTIF_CONFIG\x10\x02\x12\x17\n\x13STOREFORWARD_CONFIG\x10\x03\x12\x14\n\x10RANGETEST_CONFIG\x10\x04\x12\x14\n\x10TELEMETRY_CONFIG\x10\x05\x12\x14\n\x10\x43\x41NNEDMSG_CONFIG\x10\x06\x12\x10\n\x0c\x41UDIO_CONFIG\x10\x07\x12\x19\n\x15REMOTEHARDWARE_CONFIG\x10\x08\x42\x11\n\x0fpayload_variant\"[\n\rHamParameters\x12\x11\n\tcall_sign\x18\x01 \x01(\t\x12\x10\n\x08tx_power\x18\x02 \x01(\x05\x12\x11\n\tfrequency\x18\x03 \x01(\x02\x12\x12\n\nshort_name\x18\x04 \x01(\tB`\n\x13\x63om.geeksville.meshB\x0b\x41\x64minProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3')
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x16meshtastic/admin.proto\x1a\x18meshtastic/channel.proto\x1a\x17meshtastic/config.proto\x1a\"meshtastic/connection_status.proto\x1a\x1bmeshtastic/deviceonly.proto\x1a\x15meshtastic/mesh.proto\x1a\x1emeshtastic/module_config.proto\"\xad\x0e\n\x0c\x41\x64minMessage\x12\x1d\n\x13get_channel_request\x18\x01 \x01(\rH\x00\x12(\n\x14get_channel_response\x18\x02 \x01(\x0b\x32\x08.ChannelH\x00\x12\x1b\n\x11get_owner_request\x18\x03 \x01(\x08H\x00\x12#\n\x12get_owner_response\x18\x04 \x01(\x0b\x32\x05.UserH\x00\x12\x36\n\x12get_config_request\x18\x05 \x01(\x0e\x32\x18.AdminMessage.ConfigTypeH\x00\x12&\n\x13get_config_response\x18\x06 \x01(\x0b\x32\x07.ConfigH\x00\x12\x43\n\x19get_module_config_request\x18\x07 \x01(\x0e\x32\x1e.AdminMessage.ModuleConfigTypeH\x00\x12\x33\n\x1aget_module_config_response\x18\x08 \x01(\x0b\x32\r.ModuleConfigH\x00\x12\x34\n*get_canned_message_module_messages_request\x18\n \x01(\x08H\x00\x12\x35\n+get_canned_message_module_messages_response\x18\x0b \x01(\tH\x00\x12%\n\x1bget_device_metadata_request\x18\x0c \x01(\x08H\x00\x12\x37\n\x1cget_device_metadata_response\x18\r \x01(\x0b\x32\x0f.DeviceMetadataH\x00\x12\x1e\n\x14get_ringtone_request\x18\x0e \x01(\x08H\x00\x12\x1f\n\x15get_ringtone_response\x18\x0f \x01(\tH\x00\x12.\n$get_device_connection_status_request\x18\x10 \x01(\x08H\x00\x12H\n%get_device_connection_status_response\x18\x11 \x01(\x0b\x32\x17.DeviceConnectionStatusH\x00\x12&\n\x0cset_ham_mode\x18\x12 \x01(\x0b\x32\x0e.HamParametersH\x00\x12/\n%get_node_remote_hardware_pins_request\x18\x13 \x01(\x08H\x00\x12Q\n&get_node_remote_hardware_pins_response\x18\x14 \x01(\x0b\x32\x1f.NodeRemoteHardwarePinsResponseH\x00\x12\x1a\n\tset_owner\x18 \x01(\x0b\x32\x05.UserH\x00\x12\x1f\n\x0bset_channel\x18! \x01(\x0b\x32\x08.ChannelH\x00\x12\x1d\n\nset_config\x18\" \x01(\x0b\x32\x07.ConfigH\x00\x12*\n\x11set_module_config\x18# \x01(\x0b\x32\r.ModuleConfigH\x00\x12,\n\"set_canned_message_module_messages\x18$ \x01(\tH\x00\x12\x1e\n\x14set_ringtone_message\x18% \x01(\tH\x00\x12\x1d\n\x13\x62\x65gin_edit_settings\x18@ \x01(\x08H\x00\x12\x1e\n\x14\x63ommit_edit_settings\x18\x41 \x01(\x08H\x00\x12\x1c\n\x12reboot_ota_seconds\x18_ \x01(\x05H\x00\x12\x18\n\x0e\x65xit_simulator\x18` \x01(\x08H\x00\x12\x18\n\x0ereboot_seconds\x18\x61 \x01(\x05H\x00\x12\x1a\n\x10shutdown_seconds\x18\x62 \x01(\x05H\x00\x12\x17\n\rfactory_reset\x18\x63 \x01(\x05H\x00\x12\x16\n\x0cnodedb_reset\x18\x64 \x01(\x05H\x00\"\x95\x01\n\nConfigType\x12\x11\n\rDEVICE_CONFIG\x10\x00\x12\x13\n\x0fPOSITION_CONFIG\x10\x01\x12\x10\n\x0cPOWER_CONFIG\x10\x02\x12\x12\n\x0eNETWORK_CONFIG\x10\x03\x12\x12\n\x0e\x44ISPLAY_CONFIG\x10\x04\x12\x0f\n\x0bLORA_CONFIG\x10\x05\x12\x14\n\x10\x42LUETOOTH_CONFIG\x10\x06\"\xa4\x02\n\x10ModuleConfigType\x12\x0f\n\x0bMQTT_CONFIG\x10\x00\x12\x11\n\rSERIAL_CONFIG\x10\x01\x12\x13\n\x0f\x45XTNOTIF_CONFIG\x10\x02\x12\x17\n\x13STOREFORWARD_CONFIG\x10\x03\x12\x14\n\x10RANGETEST_CONFIG\x10\x04\x12\x14\n\x10TELEMETRY_CONFIG\x10\x05\x12\x14\n\x10\x43\x41NNEDMSG_CONFIG\x10\x06\x12\x10\n\x0c\x41UDIO_CONFIG\x10\x07\x12\x19\n\x15REMOTEHARDWARE_CONFIG\x10\x08\x12\x17\n\x13NEIGHBORINFO_CONFIG\x10\t\x12\x1a\n\x16\x41MBIENTLIGHTING_CONFIG\x10\n\x12\x1a\n\x16\x44\x45TECTIONSENSOR_CONFIG\x10\x0b\x42\x11\n\x0fpayload_variant\"[\n\rHamParameters\x12\x11\n\tcall_sign\x18\x01 \x01(\t\x12\x10\n\x08tx_power\x18\x02 \x01(\x05\x12\x11\n\tfrequency\x18\x03 \x01(\x02\x12\x12\n\nshort_name\x18\x04 \x01(\t\"[\n\x1eNodeRemoteHardwarePinsResponse\x12\x39\n\x19node_remote_hardware_pins\x18\x01 \x03(\x0b\x32\x16.NodeRemoteHardwarePinB`\n\x13\x63om.geeksville.meshB\x0b\x41\x64minProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3')
_ADMINMESSAGE = DESCRIPTOR.message_types_by_name['AdminMessage']
_HAMPARAMETERS = DESCRIPTOR.message_types_by_name['HamParameters']
_NODEREMOTEHARDWAREPINSRESPONSE = DESCRIPTOR.message_types_by_name['NodeRemoteHardwarePinsResponse']
_ADMINMESSAGE_CONFIGTYPE = _ADMINMESSAGE.enum_types_by_name['ConfigType']
_ADMINMESSAGE_MODULECONFIGTYPE = _ADMINMESSAGE.enum_types_by_name['ModuleConfigType']
AdminMessage = _reflection.GeneratedProtocolMessageType('AdminMessage', (_message.Message,), {
@@ -41,16 +43,25 @@ HamParameters = _reflection.GeneratedProtocolMessageType('HamParameters', (_mess
})
_sym_db.RegisterMessage(HamParameters)
NodeRemoteHardwarePinsResponse = _reflection.GeneratedProtocolMessageType('NodeRemoteHardwarePinsResponse', (_message.Message,), {
'DESCRIPTOR' : _NODEREMOTEHARDWAREPINSRESPONSE,
'__module__' : 'meshtastic.admin_pb2'
# @@protoc_insertion_point(class_scope:NodeRemoteHardwarePinsResponse)
})
_sym_db.RegisterMessage(NodeRemoteHardwarePinsResponse)
if _descriptor._USE_C_DESCRIPTORS == False:
DESCRIPTOR._options = None
DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\013AdminProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000'
_ADMINMESSAGE._serialized_start=169
_ADMINMESSAGE._serialized_end=1793
_ADMINMESSAGE_CONFIGTYPE._serialized_start=1411
_ADMINMESSAGE_CONFIGTYPE._serialized_end=1560
_ADMINMESSAGE_MODULECONFIGTYPE._serialized_start=1563
_ADMINMESSAGE_MODULECONFIGTYPE._serialized_end=1774
_HAMPARAMETERS._serialized_start=1795
_HAMPARAMETERS._serialized_end=1886
_ADMINMESSAGE._serialized_start=198
_ADMINMESSAGE._serialized_end=2035
_ADMINMESSAGE_CONFIGTYPE._serialized_start=1572
_ADMINMESSAGE_CONFIGTYPE._serialized_end=1721
_ADMINMESSAGE_MODULECONFIGTYPE._serialized_start=1724
_ADMINMESSAGE_MODULECONFIGTYPE._serialized_end=2016
_HAMPARAMETERS._serialized_start=2037
_HAMPARAMETERS._serialized_end=2128
_NODEREMOTEHARDWAREPINSRESPONSE._serialized_start=2130
_NODEREMOTEHARDWAREPINSRESPONSE._serialized_end=2221
# @@protoc_insertion_point(module_scope)

View File

File diff suppressed because one or more lines are too long

View File

@@ -16,9 +16,11 @@ _sym_db = _symbol_database.Default()
from meshtastic import channel_pb2 as meshtastic_dot_channel__pb2
from meshtastic import localonly_pb2 as meshtastic_dot_localonly__pb2
from meshtastic import mesh_pb2 as meshtastic_dot_mesh__pb2
from meshtastic import telemetry_pb2 as meshtastic_dot_telemetry__pb2
from meshtastic import module_config_pb2 as meshtastic_dot_module__config__pb2
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1bmeshtastic/deviceonly.proto\x1a\x18meshtastic/channel.proto\x1a\x1ameshtastic/localonly.proto\x1a\x15meshtastic/mesh.proto\"\xe0\x01\n\x0b\x44\x65viceState\x12\x1c\n\x07my_node\x18\x02 \x01(\x0b\x32\x0b.MyNodeInfo\x12\x14\n\x05owner\x18\x03 \x01(\x0b\x32\x05.User\x12\x1a\n\x07node_db\x18\x04 \x03(\x0b\x32\t.NodeInfo\x12\"\n\rreceive_queue\x18\x05 \x03(\x0b\x32\x0b.MeshPacket\x12\x0f\n\x07version\x18\x08 \x01(\r\x12$\n\x0frx_text_message\x18\x07 \x01(\x0b\x32\x0b.MeshPacket\x12\x0f\n\x07no_save\x18\t \x01(\x08\x12\x15\n\rdid_gps_reset\x18\x0b \x01(\x08\":\n\x0b\x43hannelFile\x12\x1a\n\x08\x63hannels\x18\x01 \x03(\x0b\x32\x08.Channel\x12\x0f\n\x07version\x18\x02 \x01(\r\"\xf6\x01\n\x08OEMStore\x12\x16\n\x0eoem_icon_width\x18\x01 \x01(\r\x12\x17\n\x0foem_icon_height\x18\x02 \x01(\r\x12\x15\n\roem_icon_bits\x18\x03 \x01(\x0c\x12\x1e\n\x08oem_font\x18\x04 \x01(\x0e\x32\x0c.ScreenFonts\x12\x10\n\x08oem_text\x18\x05 \x01(\t\x12\x13\n\x0boem_aes_key\x18\x06 \x01(\x0c\x12&\n\x10oem_local_config\x18\x07 \x01(\x0b\x32\x0c.LocalConfig\x12\x33\n\x17oem_local_module_config\x18\x08 \x01(\x0b\x32\x12.LocalModuleConfig*>\n\x0bScreenFonts\x12\x0e\n\nFONT_SMALL\x10\x00\x12\x0f\n\x0b\x46ONT_MEDIUM\x10\x01\x12\x0e\n\nFONT_LARGE\x10\x02\x42_\n\x13\x63om.geeksville.meshB\nDeviceOnlyZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3')
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1bmeshtastic/deviceonly.proto\x1a\x18meshtastic/channel.proto\x1a\x1ameshtastic/localonly.proto\x1a\x15meshtastic/mesh.proto\x1a\x1ameshtastic/telemetry.proto\x1a\x1emeshtastic/module_config.proto\"\xc6\x02\n\x0b\x44\x65viceState\x12\x1c\n\x07my_node\x18\x02 \x01(\x0b\x32\x0b.MyNodeInfo\x12\x14\n\x05owner\x18\x03 \x01(\x0b\x32\x05.User\x12\"\n\rreceive_queue\x18\x05 \x03(\x0b\x32\x0b.MeshPacket\x12\x0f\n\x07version\x18\x08 \x01(\r\x12$\n\x0frx_text_message\x18\x07 \x01(\x0b\x32\x0b.MeshPacket\x12\x0f\n\x07no_save\x18\t \x01(\x08\x12\x15\n\rdid_gps_reset\x18\x0b \x01(\x08\x12 \n\x0brx_waypoint\x18\x0c \x01(\x0b\x32\x0b.MeshPacket\x12\x39\n\x19node_remote_hardware_pins\x18\r \x03(\x0b\x32\x16.NodeRemoteHardwarePin\x12#\n\x0cnode_db_lite\x18\x0e \x03(\x0b\x32\r.NodeInfoLite\"\xab\x01\n\x0cNodeInfoLite\x12\x0b\n\x03num\x18\x01 \x01(\r\x12\x13\n\x04user\x18\x02 \x01(\x0b\x32\x05.User\x12\x1f\n\x08position\x18\x03 \x01(\x0b\x32\r.PositionLite\x12\x0b\n\x03snr\x18\x04 \x01(\x02\x12\x12\n\nlast_heard\x18\x05 \x01(\x07\x12&\n\x0e\x64\x65vice_metrics\x18\x06 \x01(\x0b\x32\x0e.DeviceMetrics\x12\x0f\n\x07\x63hannel\x18\x07 \x01(\r\"\x85\x01\n\x0cPositionLite\x12\x12\n\nlatitude_i\x18\x01 \x01(\x0f\x12\x13\n\x0blongitude_i\x18\x02 \x01(\x0f\x12\x10\n\x08\x61ltitude\x18\x03 \x01(\x05\x12\x0c\n\x04time\x18\x04 \x01(\x07\x12,\n\x0flocation_source\x18\x05 \x01(\x0e\x32\x13.Position.LocSource\":\n\x0b\x43hannelFile\x12\x1a\n\x08\x63hannels\x18\x01 \x03(\x0b\x32\x08.Channel\x12\x0f\n\x07version\x18\x02 \x01(\r\"\xf6\x01\n\x08OEMStore\x12\x16\n\x0eoem_icon_width\x18\x01 \x01(\r\x12\x17\n\x0foem_icon_height\x18\x02 \x01(\r\x12\x15\n\roem_icon_bits\x18\x03 \x01(\x0c\x12\x1e\n\x08oem_font\x18\x04 \x01(\x0e\x32\x0c.ScreenFonts\x12\x10\n\x08oem_text\x18\x05 \x01(\t\x12\x13\n\x0boem_aes_key\x18\x06 \x01(\x0c\x12&\n\x10oem_local_config\x18\x07 \x01(\x0b\x32\x0c.LocalConfig\x12\x33\n\x17oem_local_module_config\x18\x08 \x01(\x0b\x32\x12.LocalModuleConfig\"J\n\x15NodeRemoteHardwarePin\x12\x10\n\x08node_num\x18\x01 \x01(\r\x12\x1f\n\x03pin\x18\x02 \x01(\x0b\x32\x12.RemoteHardwarePin*>\n\x0bScreenFonts\x12\x0e\n\nFONT_SMALL\x10\x00\x12\x0f\n\x0b\x46ONT_MEDIUM\x10\x01\x12\x0e\n\nFONT_LARGE\x10\x02\x42_\n\x13\x63om.geeksville.meshB\nDeviceOnlyZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3')
_SCREENFONTS = DESCRIPTOR.enum_types_by_name['ScreenFonts']
ScreenFonts = enum_type_wrapper.EnumTypeWrapper(_SCREENFONTS)
@@ -28,8 +30,11 @@ FONT_LARGE = 2
_DEVICESTATE = DESCRIPTOR.message_types_by_name['DeviceState']
_NODEINFOLITE = DESCRIPTOR.message_types_by_name['NodeInfoLite']
_POSITIONLITE = DESCRIPTOR.message_types_by_name['PositionLite']
_CHANNELFILE = DESCRIPTOR.message_types_by_name['ChannelFile']
_OEMSTORE = DESCRIPTOR.message_types_by_name['OEMStore']
_NODEREMOTEHARDWAREPIN = DESCRIPTOR.message_types_by_name['NodeRemoteHardwarePin']
DeviceState = _reflection.GeneratedProtocolMessageType('DeviceState', (_message.Message,), {
'DESCRIPTOR' : _DEVICESTATE,
'__module__' : 'meshtastic.deviceonly_pb2'
@@ -37,6 +42,20 @@ DeviceState = _reflection.GeneratedProtocolMessageType('DeviceState', (_message.
})
_sym_db.RegisterMessage(DeviceState)
NodeInfoLite = _reflection.GeneratedProtocolMessageType('NodeInfoLite', (_message.Message,), {
'DESCRIPTOR' : _NODEINFOLITE,
'__module__' : 'meshtastic.deviceonly_pb2'
# @@protoc_insertion_point(class_scope:NodeInfoLite)
})
_sym_db.RegisterMessage(NodeInfoLite)
PositionLite = _reflection.GeneratedProtocolMessageType('PositionLite', (_message.Message,), {
'DESCRIPTOR' : _POSITIONLITE,
'__module__' : 'meshtastic.deviceonly_pb2'
# @@protoc_insertion_point(class_scope:PositionLite)
})
_sym_db.RegisterMessage(PositionLite)
ChannelFile = _reflection.GeneratedProtocolMessageType('ChannelFile', (_message.Message,), {
'DESCRIPTOR' : _CHANNELFILE,
'__module__' : 'meshtastic.deviceonly_pb2'
@@ -51,16 +70,29 @@ OEMStore = _reflection.GeneratedProtocolMessageType('OEMStore', (_message.Messag
})
_sym_db.RegisterMessage(OEMStore)
NodeRemoteHardwarePin = _reflection.GeneratedProtocolMessageType('NodeRemoteHardwarePin', (_message.Message,), {
'DESCRIPTOR' : _NODEREMOTEHARDWAREPIN,
'__module__' : 'meshtastic.deviceonly_pb2'
# @@protoc_insertion_point(class_scope:NodeRemoteHardwarePin)
})
_sym_db.RegisterMessage(NodeRemoteHardwarePin)
if _descriptor._USE_C_DESCRIPTORS == False:
DESCRIPTOR._options = None
DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\nDeviceOnlyZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000'
_SCREENFONTS._serialized_start=644
_SCREENFONTS._serialized_end=706
_DEVICESTATE._serialized_start=109
_DEVICESTATE._serialized_end=333
_CHANNELFILE._serialized_start=335
_CHANNELFILE._serialized_end=393
_OEMSTORE._serialized_start=396
_OEMSTORE._serialized_end=642
_SCREENFONTS._serialized_start=1192
_SCREENFONTS._serialized_end=1254
_DEVICESTATE._serialized_start=169
_DEVICESTATE._serialized_end=495
_NODEINFOLITE._serialized_start=498
_NODEINFOLITE._serialized_end=669
_POSITIONLITE._serialized_start=672
_POSITIONLITE._serialized_end=805
_CHANNELFILE._serialized_start=807
_CHANNELFILE._serialized_end=865
_OEMSTORE._serialized_start=868
_OEMSTORE._serialized_end=1114
_NODEREMOTEHARDWAREPIN._serialized_start=1116
_NODEREMOTEHARDWAREPIN._serialized_end=1190
# @@protoc_insertion_point(module_scope)

View File

@@ -16,7 +16,7 @@ from meshtastic import config_pb2 as meshtastic_dot_config__pb2
from meshtastic import module_config_pb2 as meshtastic_dot_module__config__pb2
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1ameshtastic/localonly.proto\x1a\x17meshtastic/config.proto\x1a\x1emeshtastic/module_config.proto\"\xb0\x02\n\x0bLocalConfig\x12$\n\x06\x64\x65vice\x18\x01 \x01(\x0b\x32\x14.Config.DeviceConfig\x12(\n\x08position\x18\x02 \x01(\x0b\x32\x16.Config.PositionConfig\x12\"\n\x05power\x18\x03 \x01(\x0b\x32\x13.Config.PowerConfig\x12&\n\x07network\x18\x04 \x01(\x0b\x32\x15.Config.NetworkConfig\x12&\n\x07\x64isplay\x18\x05 \x01(\x0b\x32\x15.Config.DisplayConfig\x12 \n\x04lora\x18\x06 \x01(\x0b\x32\x12.Config.LoRaConfig\x12*\n\tbluetooth\x18\x07 \x01(\x0b\x32\x17.Config.BluetoothConfig\x12\x0f\n\x07version\x18\x08 \x01(\r\"\x81\x04\n\x11LocalModuleConfig\x12&\n\x04mqtt\x18\x01 \x01(\x0b\x32\x18.ModuleConfig.MQTTConfig\x12*\n\x06serial\x18\x02 \x01(\x0b\x32\x1a.ModuleConfig.SerialConfig\x12G\n\x15\x65xternal_notification\x18\x03 \x01(\x0b\x32(.ModuleConfig.ExternalNotificationConfig\x12\x37\n\rstore_forward\x18\x04 \x01(\x0b\x32 .ModuleConfig.StoreForwardConfig\x12\x31\n\nrange_test\x18\x05 \x01(\x0b\x32\x1d.ModuleConfig.RangeTestConfig\x12\x30\n\ttelemetry\x18\x06 \x01(\x0b\x32\x1d.ModuleConfig.TelemetryConfig\x12\x39\n\x0e\x63\x61nned_message\x18\x07 \x01(\x0b\x32!.ModuleConfig.CannedMessageConfig\x12(\n\x05\x61udio\x18\t \x01(\x0b\x32\x19.ModuleConfig.AudioConfig\x12;\n\x0fremote_hardware\x18\n \x01(\x0b\x32\".ModuleConfig.RemoteHardwareConfig\x12\x0f\n\x07version\x18\x08 \x01(\rBd\n\x13\x63om.geeksville.meshB\x0fLocalOnlyProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3')
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1ameshtastic/localonly.proto\x1a\x17meshtastic/config.proto\x1a\x1emeshtastic/module_config.proto\"\xb0\x02\n\x0bLocalConfig\x12$\n\x06\x64\x65vice\x18\x01 \x01(\x0b\x32\x14.Config.DeviceConfig\x12(\n\x08position\x18\x02 \x01(\x0b\x32\x16.Config.PositionConfig\x12\"\n\x05power\x18\x03 \x01(\x0b\x32\x13.Config.PowerConfig\x12&\n\x07network\x18\x04 \x01(\x0b\x32\x15.Config.NetworkConfig\x12&\n\x07\x64isplay\x18\x05 \x01(\x0b\x32\x15.Config.DisplayConfig\x12 \n\x04lora\x18\x06 \x01(\x0b\x32\x12.Config.LoRaConfig\x12*\n\tbluetooth\x18\x07 \x01(\x0b\x32\x17.Config.BluetoothConfig\x12\x0f\n\x07version\x18\x08 \x01(\r\"\xb8\x05\n\x11LocalModuleConfig\x12&\n\x04mqtt\x18\x01 \x01(\x0b\x32\x18.ModuleConfig.MQTTConfig\x12*\n\x06serial\x18\x02 \x01(\x0b\x32\x1a.ModuleConfig.SerialConfig\x12G\n\x15\x65xternal_notification\x18\x03 \x01(\x0b\x32(.ModuleConfig.ExternalNotificationConfig\x12\x37\n\rstore_forward\x18\x04 \x01(\x0b\x32 .ModuleConfig.StoreForwardConfig\x12\x31\n\nrange_test\x18\x05 \x01(\x0b\x32\x1d.ModuleConfig.RangeTestConfig\x12\x30\n\ttelemetry\x18\x06 \x01(\x0b\x32\x1d.ModuleConfig.TelemetryConfig\x12\x39\n\x0e\x63\x61nned_message\x18\x07 \x01(\x0b\x32!.ModuleConfig.CannedMessageConfig\x12(\n\x05\x61udio\x18\t \x01(\x0b\x32\x19.ModuleConfig.AudioConfig\x12;\n\x0fremote_hardware\x18\n \x01(\x0b\x32\".ModuleConfig.RemoteHardwareConfig\x12\x37\n\rneighbor_info\x18\x0b \x01(\x0b\x32 .ModuleConfig.NeighborInfoConfig\x12=\n\x10\x61mbient_lighting\x18\x0c \x01(\x0b\x32#.ModuleConfig.AmbientLightingConfig\x12=\n\x10\x64\x65tection_sensor\x18\r \x01(\x0b\x32#.ModuleConfig.DetectionSensorConfig\x12\x0f\n\x07version\x18\x08 \x01(\rBd\n\x13\x63om.geeksville.meshB\x0fLocalOnlyProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3')
@@ -43,5 +43,5 @@ if _descriptor._USE_C_DESCRIPTORS == False:
_LOCALCONFIG._serialized_start=88
_LOCALCONFIG._serialized_end=392
_LOCALMODULECONFIG._serialized_start=395
_LOCALMODULECONFIG._serialized_end=908
_LOCALMODULECONFIG._serialized_end=1091
# @@protoc_insertion_point(module_scope)

View File

@@ -2,12 +2,12 @@
"""
import collections
import json
import logging
import random
import sys
import threading
import time
import json
from datetime import datetime
from typing import AnyStr
@@ -18,7 +18,7 @@ from pubsub import pub
from tabulate import tabulate
import meshtastic.node
from meshtastic import mesh_pb2, portnums_pb2
from meshtastic import mesh_pb2, portnums_pb2, telemetry_pb2
from meshtastic.__init__ import (
BROADCAST_ADDR,
BROADCAST_NUM,
@@ -61,6 +61,7 @@ class MeshInterface:
self.noProto = noProto
self.localNode = meshtastic.node.Node(self, -1) # We fixup nodenum later
self.myInfo = None # We don't have device info yet
self.metadata = None # We don't have device metadata yet
self.responseHandlers = {} # A map from request ID to the handler
self.failure = (
None # If we've encountered a fatal exception it will be kept here
@@ -102,6 +103,9 @@ class MeshInterface:
myinfo = ""
if self.myInfo:
myinfo = f"\nMy info: {stripnl(MessageToJson(self.myInfo))}"
metadata = ""
if self.metadata:
metadata = f"\nMetadata: {stripnl(MessageToJson(self.metadata))}"
mesh = "\n\nNodes in mesh: "
nodes = {}
if self.nodes:
@@ -119,10 +123,10 @@ class MeshInterface:
n2["user"]["macaddr"] = addr
# use id as dictionary key for correct json format in list of nodes
nodeid = n2['user']['id']
n2['user'].pop('id')
nodeid = n2["user"]["id"]
n2["user"].pop("id")
nodes[nodeid] = n2
infos = owner + myinfo + mesh + json.dumps(nodes)
infos = owner + myinfo + metadata + mesh + json.dumps(nodes)
print(infos)
return infos
@@ -130,7 +134,7 @@ class MeshInterface:
"""Show table summary of nodes in mesh"""
def formatFloat(value, precision=2, unit=""):
"""Format a float value with precsion."""
"""Format a float value with precision."""
return f"{value:.{precision}f}{unit}" if value else None
def getLH(ts):
@@ -405,6 +409,70 @@ class MeshInterface:
self._acknowledgment.receivedTraceRoute = True
def sendTelemetry(self, destinationId=BROADCAST_ADDR, wantResponse=False):
"""Send telemetry and optionally ask for a response"""
r = telemetry_pb2.Telemetry()
node = next(n for n in self.nodes.values() if n["num"] == self.localNode.nodeNum)
if node is not None:
metrics = node.get("deviceMetrics")
if metrics:
batteryLevel = metrics.get("batteryLevel")
if batteryLevel is not None:
r.device_metrics.battery_level = batteryLevel
voltage = metrics.get("voltage")
if voltage is not None:
r.device_metrics.voltage = voltage
channel_utilization = metrics.get("channelUtilization")
if channel_utilization is not None:
r.device_metrics.channel_utilization = channel_utilization
air_util_tx = metrics.get("airUtilTx")
if air_util_tx is not None:
r.device_metrics.air_util_tx = air_util_tx
if wantResponse:
onResponse = self.onResponseTelemetry
else:
onResponse = None
if destinationId.startswith("!"):
destinationId = int(destinationId[1:], 16)
else:
destinationId = int(destinationId)
self.sendData(
r,
destinationId=destinationId,
portNum=portnums_pb2.PortNum.TELEMETRY_APP,
wantResponse=wantResponse,
onResponse=onResponse,
)
if wantResponse:
self.waitForTelemetry()
def onResponseTelemetry(self, p):
"""on response for telemetry"""
if p["decoded"]["portnum"] == 'TELEMETRY_APP':
self._acknowledgment.receivedTelemetry = True
telemetry = telemetry_pb2.Telemetry()
telemetry.ParseFromString(p["decoded"]["payload"])
print("Telemetry received:")
if telemetry.device_metrics.battery_level is not None:
print(f"Battery level: {telemetry.device_metrics.battery_level:.2f}%")
if telemetry.device_metrics.voltage is not None:
print(f"Voltage: {telemetry.device_metrics.voltage:.2f} V")
if telemetry.device_metrics.channel_utilization is not None:
print(
f"Total channel utilization: {telemetry.device_metrics.channel_utilization:.2f}%"
)
if telemetry.device_metrics.air_util_tx is not None:
print(f"Transmit air utilization: {telemetry.device_metrics.air_util_tx:.2f}%")
elif p["decoded"]["portnum"] == 'ROUTING_APP':
if p["decoded"]["routing"]["errorReason"] == 'NO_RESPONSE':
our_exit("No response from node. At least firmware 2.1.22 is required on the destination node.")
def _addResponseHandler(self, requestId, callback):
self.responseHandlers[requestId] = ResponseHandler(callback)
@@ -487,6 +555,12 @@ class MeshInterface:
success = self._timeout.waitForTraceRoute(waitFactor, self._acknowledgment)
if not success:
raise Exception("Timed out waiting for traceroute")
def waitForTelemetry(self):
"""Wait for telemetry"""
success = self._timeout.waitForTelemetry(self._acknowledgment)
if not success:
raise Exception("Timed out waiting for telemetry")
def getMyNodeInfo(self):
"""Get info about my node."""
@@ -697,25 +771,16 @@ class MeshInterface:
logging.debug(f"Received myinfo: {stripnl(fromRadio.my_info)}")
failmsg = None
# Check for app too old
if self.myInfo.min_app_version > OUR_APP_VERSION:
failmsg = (
"This device needs a newer python client, run 'pip install --upgrade meshtastic'."
"For more information see https://tinyurl.com/5bjsxu32"
)
# check for firmware too old
if self.myInfo.max_channels == 0:
failmsg = (
"This version of meshtastic-python requires device firmware version 1.2 or later. "
"For more information see https://tinyurl.com/5bjsxu32"
)
if failmsg:
self.failure = Exception(failmsg)
self.isConnected.set() # let waitConnected return this exception
self.close()
elif fromRadio.HasField("metadata"):
self.metadata = fromRadio.metadata
logging.debug(f"Received device metadata: {stripnl(fromRadio.metadata)}")
elif fromRadio.HasField("node_info"):
node = asDict["nodeInfo"]
try:
@@ -800,6 +865,14 @@ class MeshInterface:
self.localNode.moduleConfig.remote_hardware.CopyFrom(
fromRadio.moduleConfig.remote_hardware
)
elif fromRadio.moduleConfig.HasField("neighbor_info"):
self.localNode.moduleConfig.neighbor_info.CopyFrom(
fromRadio.moduleConfig.neighbor_info
)
elif fromRadio.moduleConfig.HasField("detection_sensor"):
self.localNode.moduleConfig.detection_sensor.CopyFrom(
fromRadio.moduleConfig.detection_sensor
)
else:
logging.debug("Unexpected FromRadio payload")
@@ -843,7 +916,7 @@ class MeshInterface:
if nodeNum in self.nodesByNum:
return self.nodesByNum[nodeNum]
else:
n = {"num": nodeNum} # Create a minimial node db entry
n = {"num": nodeNum} # Create a minimal node db entry
self.nodesByNum[nodeNum] = n
return n
@@ -898,6 +971,7 @@ class MeshInterface:
topic = "meshtastic.receive" # Generic unknown packet type
decoded = None
portnum = portnums_pb2.PortNum.Name(portnums_pb2.PortNum.UNKNOWN_APP)
if "decoded" in asDict:
decoded = asDict["decoded"]
# The default MessageToDict converts byte arrays into base64 strings.
@@ -905,53 +979,52 @@ class MeshInterface:
# byte array.
decoded["payload"] = meshPacket.decoded.payload
# UNKNOWN_APP is the default protobuf portnum value, and therefore if not
# set it will not be populated at all to make API usage easier, set
# it to prevent confusion
if decoded and "portnum" not in decoded:
new_portnum = portnums_pb2.PortNum.Name(portnums_pb2.PortNum.UNKNOWN_APP)
decoded["portnum"] = new_portnum
logging.warning(f"portnum was not in decoded. Setting to:{new_portnum}")
# UNKNOWN_APP is the default protobuf portnum value, and therefore if not
# set it will not be populated at all to make API usage easier, set
# it to prevent confusion
if "portnum" not in decoded:
decoded["portnum"] = portnum
logging.warning(f"portnum was not in decoded. Setting to:{portnum}")
else:
portnum = decoded["portnum"]
portnum = decoded["portnum"]
topic = f"meshtastic.receive.data.{portnum}"
topic = f"meshtastic.receive.data.{portnum}"
# decode position protobufs and update nodedb, provide decoded version
# as "position" in the published msg move the following into a 'decoders'
# API that clients could register?
portNumInt = meshPacket.decoded.portnum # we want portnum as an int
handler = protocols.get(portNumInt)
# The decoded protobuf as a dictionary (if we understand this message)
p = None
if handler is not None:
topic = f"meshtastic.receive.{handler.name}"
# decode position protobufs and update nodedb, provide decoded version
# as "position" in the published msg move the following into a 'decoders'
# API that clients could register?
portNumInt = meshPacket.decoded.portnum # we want portnum as an int
handler = protocols.get(portNumInt)
# The decoded protobuf as a dictionary (if we understand this message)
p = None
if handler is not None:
topic = f"meshtastic.receive.{handler.name}"
# Convert to protobuf if possible
if handler.protobufFactory is not None:
pb = handler.protobufFactory()
pb.ParseFromString(meshPacket.decoded.payload)
p = google.protobuf.json_format.MessageToDict(pb)
asDict["decoded"][handler.name] = p
# Also provide the protobuf raw
asDict["decoded"][handler.name]["raw"] = pb
# Convert to protobuf if possible
if handler.protobufFactory is not None:
pb = handler.protobufFactory()
pb.ParseFromString(meshPacket.decoded.payload)
p = google.protobuf.json_format.MessageToDict(pb)
asDict["decoded"][handler.name] = p
# Also provide the protobuf raw
asDict["decoded"][handler.name]["raw"] = pb
# Call specialized onReceive if necessary
if handler.onReceive is not None:
handler.onReceive(self, asDict)
# Call specialized onReceive if necessary
if handler.onReceive is not None:
handler.onReceive(self, asDict)
# Is this message in response to a request, if so, look for a handler
requestId = decoded.get("requestId")
if requestId is not None:
# We ignore ACK packets, but send NAKs and data responses to the handlers
routing = decoded.get("routing")
isAck = routing is not None and ("errorReason" not in routing)
if not isAck:
# we keep the responseHandler in dict until we get a non ack
handler = self.responseHandlers.pop(requestId, None)
if handler is not None:
if not isAck or (isAck and handler.__name__ == "onAckNak"):
handler.callback(asDict)
# Is this message in response to a request, if so, look for a handler
requestId = decoded.get("requestId")
if requestId is not None:
# We ignore ACK packets, but send NAKs and data responses to the handlers
routing = decoded.get("routing")
isAck = routing is not None and ("errorReason" not in routing)
if not isAck:
# we keep the responseHandler in dict until we get a non ack
handler = self.responseHandlers.pop(requestId, None)
if handler is not None:
if not isAck or (isAck and handler.__name__ == "onAckNak"):
handler.callback(asDict)
logging.debug(f"Publishing {topic}: packet={stripnl(asDict)} ")
publishingThread.queueWork(

View File

File diff suppressed because one or more lines are too long

View File

File diff suppressed because one or more lines are too long

View File

@@ -49,8 +49,8 @@ class Node:
for c in self.channels:
# print('c.settings.psk:', c.settings.psk)
cStr = stripnl(MessageToJson(c.settings))
# only show if there is no psk (meaning disabled channel)
if c.settings.psk:
# don't show disabled channels
if channel_pb2.Channel.Role.Name(c.role) != "DISABLED":
print(
f" {channel_pb2.Channel.Role.Name(c.role)} psk={pskToString(c.settings.psk)} {cStr}"
)
@@ -188,6 +188,10 @@ class Node:
p.set_module_config.remote_hardware.CopyFrom(
self.moduleConfig.remote_hardware
)
elif config_name == "neighbor_info":
p.set_module_config.neighbor_info.CopyFrom(self.moduleConfig.neighbor_info)
elif config_name == "detection_sensor":
p.set_module_config.detection_sensor.CopyFrom(self.moduleConfig.detection_sensor)
else:
our_exit(f"Error: No valid config with name {config_name}")
@@ -217,7 +221,7 @@ class Node:
return ch
def deleteChannel(self, channelIndex):
"""Delete the specifed channelIndex and shift other channels up"""
"""Delete the specified channelIndex and shift other channels up"""
ch = self.channels[channelIndex]
if ch.role not in (
channel_pb2.Channel.Role.SECONDARY,
@@ -233,7 +237,7 @@ class Node:
self._fixupChannels() # expand back to 8 channels
index = channelIndex
while index < self.iface.myInfo.max_channels:
while index < 8:
self.writeChannel(index, adminIndex=adminIndex)
index += 1
@@ -625,7 +629,7 @@ class Node:
# Add extra disabled channels as needed
index = len(self.channels)
while index < self.iface.myInfo.max_channels:
while index < 8:
ch = channel_pb2.Channel()
ch.role = channel_pb2.Channel.Role.DISABLED
ch.index = index
@@ -650,7 +654,7 @@ class Node:
return
c = p["decoded"]["admin"]["raw"].get_device_metadata_response
self._timeout.reset() # We made foreward progress
self._timeout.reset() # We made forward progress
logging.debug(f"Received metadata {stripnl(c)}")
print(f"\nfirmware_version: {c.firmware_version}")
print(f"device_state_version: {c.device_state_version}")
@@ -677,7 +681,7 @@ class Node:
c = p["decoded"]["admin"]["raw"].get_channel_response
self.partialChannels.append(c)
self._timeout.reset() # We made foreward progress
self._timeout.reset() # We made forward progress
logging.debug(f"Received channel {stripnl(c)}")
index = c.index
@@ -690,7 +694,7 @@ class Node:
c.role == channel_pb2.Channel.Role.DISABLED
) and fastChannelDownload
if quitEarly or index >= self.iface.myInfo.max_channels - 1:
if quitEarly or index >= 8 - 1:
logging.debug("Finished downloading channels")
self.channels = self.partialChannels

View File

@@ -15,7 +15,7 @@ _sym_db = _symbol_database.Default()
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x19meshtastic/portnums.proto*\xa4\x03\n\x07PortNum\x12\x0f\n\x0bUNKNOWN_APP\x10\x00\x12\x14\n\x10TEXT_MESSAGE_APP\x10\x01\x12\x17\n\x13REMOTE_HARDWARE_APP\x10\x02\x12\x10\n\x0cPOSITION_APP\x10\x03\x12\x10\n\x0cNODEINFO_APP\x10\x04\x12\x0f\n\x0bROUTING_APP\x10\x05\x12\r\n\tADMIN_APP\x10\x06\x12\x1f\n\x1bTEXT_MESSAGE_COMPRESSED_APP\x10\x07\x12\x10\n\x0cWAYPOINT_APP\x10\x08\x12\r\n\tAUDIO_APP\x10\t\x12\r\n\tREPLY_APP\x10 \x12\x11\n\rIP_TUNNEL_APP\x10!\x12\x0e\n\nSERIAL_APP\x10@\x12\x15\n\x11STORE_FORWARD_APP\x10\x41\x12\x12\n\x0eRANGE_TEST_APP\x10\x42\x12\x11\n\rTELEMETRY_APP\x10\x43\x12\x0b\n\x07ZPS_APP\x10\x44\x12\x11\n\rSIMULATOR_APP\x10\x45\x12\x12\n\x0eTRACEROUTE_APP\x10\x46\x12\x10\n\x0bPRIVATE_APP\x10\x80\x02\x12\x13\n\x0e\x41TAK_FORWARDER\x10\x81\x02\x12\x08\n\x03MAX\x10\xff\x03\x42]\n\x13\x63om.geeksville.meshB\x08PortnumsZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3')
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x19meshtastic/portnums.proto*\xd4\x03\n\x07PortNum\x12\x0f\n\x0bUNKNOWN_APP\x10\x00\x12\x14\n\x10TEXT_MESSAGE_APP\x10\x01\x12\x17\n\x13REMOTE_HARDWARE_APP\x10\x02\x12\x10\n\x0cPOSITION_APP\x10\x03\x12\x10\n\x0cNODEINFO_APP\x10\x04\x12\x0f\n\x0bROUTING_APP\x10\x05\x12\r\n\tADMIN_APP\x10\x06\x12\x1f\n\x1bTEXT_MESSAGE_COMPRESSED_APP\x10\x07\x12\x10\n\x0cWAYPOINT_APP\x10\x08\x12\r\n\tAUDIO_APP\x10\t\x12\x18\n\x14\x44\x45TECTION_SENSOR_APP\x10\n\x12\r\n\tREPLY_APP\x10 \x12\x11\n\rIP_TUNNEL_APP\x10!\x12\x0e\n\nSERIAL_APP\x10@\x12\x15\n\x11STORE_FORWARD_APP\x10\x41\x12\x12\n\x0eRANGE_TEST_APP\x10\x42\x12\x11\n\rTELEMETRY_APP\x10\x43\x12\x0b\n\x07ZPS_APP\x10\x44\x12\x11\n\rSIMULATOR_APP\x10\x45\x12\x12\n\x0eTRACEROUTE_APP\x10\x46\x12\x14\n\x10NEIGHBORINFO_APP\x10G\x12\x10\n\x0bPRIVATE_APP\x10\x80\x02\x12\x13\n\x0e\x41TAK_FORWARDER\x10\x81\x02\x12\x08\n\x03MAX\x10\xff\x03\x42]\n\x13\x63om.geeksville.meshB\x08PortnumsZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3')
_PORTNUM = DESCRIPTOR.enum_types_by_name['PortNum']
PortNum = enum_type_wrapper.EnumTypeWrapper(_PORTNUM)
@@ -29,6 +29,7 @@ ADMIN_APP = 6
TEXT_MESSAGE_COMPRESSED_APP = 7
WAYPOINT_APP = 8
AUDIO_APP = 9
DETECTION_SENSOR_APP = 10
REPLY_APP = 32
IP_TUNNEL_APP = 33
SERIAL_APP = 64
@@ -38,6 +39,7 @@ TELEMETRY_APP = 67
ZPS_APP = 68
SIMULATOR_APP = 69
TRACEROUTE_APP = 70
NEIGHBORINFO_APP = 71
PRIVATE_APP = 256
ATAK_FORWARDER = 257
MAX = 511
@@ -48,5 +50,5 @@ if _descriptor._USE_C_DESCRIPTORS == False:
DESCRIPTOR._options = None
DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\010PortnumsZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000'
_PORTNUM._serialized_start=30
_PORTNUM._serialized_end=450
_PORTNUM._serialized_end=498
# @@protoc_insertion_point(module_scope)

View File

@@ -60,7 +60,7 @@ class StreamInterface(MeshInterface):
# Send some bogus UART characters to force a sleeping device to wake, and
# if the reading statemachine was parsing a bad packet make sure
# we write enought start bytes to force it to resync (we don't use START1
# we write enough start bytes to force it to resync (we don't use START1
# because we want to ensure it is looking for START1)
p = bytearray([START2] * 32)
self._writeBytes(p)

View File

@@ -6,7 +6,7 @@ import subprocess
import time
# Do not like using hard coded sleeps, but it probably makes
# sense to pause for the radio at apprpriate times
# sense to pause for the radio at appropriate times
import pytest
from ..util import findPorts

View File

@@ -14,7 +14,7 @@ import subprocess
import time
# Do not like using hard coded sleeps, but it probably makes
# sense to pause for the radio at apprpriate times
# sense to pause for the radio at appropriate times
import pytest
from ..util import findPorts

View File

@@ -192,7 +192,16 @@ class Timeout:
return True
time.sleep(self.sleepInterval)
return False
def waitForTelemetry(self, acknowledgment):
"""Block until telemetry response is received. Returns True if telemetry response has been received."""
self.reset()
while time.time() < self.expireTime:
if getattr(acknowledgment, "receivedTelemetry", None):
acknowledgment.reset()
return True
time.sleep(self.sleepInterval)
return False
class Acknowledgment:
"A class that records which type of acknowledgment was just received, if any."
@@ -203,6 +212,7 @@ class Acknowledgment:
self.receivedNak = False
self.receivedImplAck = False
self.receivedTraceRoute = False
self.receivedTelemetry = False
def reset(self):
"""reset"""
@@ -210,6 +220,7 @@ class Acknowledgment:
self.receivedNak = False
self.receivedImplAck = False
self.receivedTraceRoute = False
self.receivedTelemetry = False
class DeferredExecution:

View File

@@ -13,7 +13,7 @@ with open("README.md", "r") as fh:
# This call to setup() does all the work
setup(
name="meshtastic",
version="2.1.5",
version="2.2.6",
description="Python API & client shell for talking to Meshtastic devices",
long_description=long_description,
long_description_content_type="text/markdown",
@@ -28,6 +28,7 @@ setup(
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
],
packages=["meshtastic"],
include_package_data=True,