Compare commits

...

77 Commits
2.0.2 ... 2.1.4

Author SHA1 Message Date
Ben Meadors
c65a60d22d Update protos 2023-03-28 19:35:48 -05:00
github-actions
3a6475dc9d bump version 2023-03-26 20:30:40 +00:00
Ben Meadors
6f91479605 Re-cut protos for spelling fix 2023-03-26 15:29:14 -05:00
github-actions
bbebddea78 bump version 2023-03-26 19:45:12 +00:00
Ben Meadors
45be828183 Merge pull request #432 from mverch67/master
Fix remote_hardware configuration
2023-03-26 14:43:41 -05:00
Ben Meadors
e0753d4745 Added new smart broadcast properties 2023-03-26 14:43:07 -05:00
Manuel
21f2e185f2 Merge branch 'master' into master 2023-03-26 20:03:19 +02:00
Manuel Verch
4bfedf6aa9 added missing audio module remote config 2023-03-26 19:59:25 +02:00
Manuel Verch
193c3faca5 Fix remote_hardware configuration 2023-03-26 16:25:59 +02:00
Manuel Verch
1f47c225b3 Fix remote_hardware configuration 2023-03-25 21:37:10 +01:00
github-actions
1b372fca8d bump version 2023-03-19 18:38:37 +00:00
Ben Meadors
5e7b6027fa Bump to 2.1.x 2023-03-19 13:36:38 -05:00
Ben Meadors
64bd5deb4b Update protos to 2.1.3 2023-03-19 13:35:13 -05:00
Ben Meadors
d0fdb9b570 Merge pull request #428 from GUVWAF/remoteAdmin
Get and set methods for remote node using one admin message
2023-03-19 13:31:49 -05:00
Garth Vander Houwen
f37755209e Merge pull request #429 from GUVWAF/configSnake
Convert sections to snake_case when configuring
2023-03-19 09:17:30 -07:00
GUVWAF
297c0dbc0e Convert sections to snake_case when configuring 2023-03-19 15:25:08 +01:00
GUVWAF
7de17f7c94 Display that '--nodes' is not supported for a remote node 2023-03-19 14:42:44 +01:00
GUVWAF
55f6494681 Wait for ACK after setting remote config 2023-03-19 14:42:12 +01:00
GUVWAF
b2cfebc5a7 '--set' works as well, also chained commands 2023-03-18 21:12:05 +01:00
GUVWAF
802768e0cc Nicer printing 2023-03-18 16:40:27 +01:00
GUVWAF
f68e4112e1 Remote get method works 2023-03-18 15:20:00 +01:00
github-actions
19b4cd65ce bump version 2023-02-10 20:53:49 +00:00
Ben Meadors
ef12125785 Update protos 2023-02-10 13:26:29 -06:00
Garth Vander Houwen
014993f058 Merge pull request #417 from tobymurray/patch-2 2023-02-09 10:01:21 -08:00
github-actions
a10da7d3ed bump version 2023-01-31 16:54:53 +00:00
Ben Meadors
786dca9d13 Protos 2023-01-31 10:53:03 -06:00
github-actions
1cfd471abc bump version 2023-01-29 23:04:27 +00:00
Ben Meadors
9ff575c388 Hack to make python compile again 2023-01-29 15:19:03 -06:00
Toby Murray
b973e39ef7 Fix link to Getting Started Guide
Previous link (https://meshtastic.org/docs/software/python/python-installation) 404's
2023-01-16 13:53:31 -05:00
github-actions
75cdc5a36b bump version 2023-01-07 21:29:31 +00:00
Thomas Göttgens
93441a473f Merge pull request #414 from meshtastic/ringtone-support
get and set RTTTL ringtone
2023-01-04 20:23:28 +01:00
Thomas Göttgens
7b8a83ade7 get and set RTTTL ringtone 2023-01-04 19:52:24 +01:00
github-actions
2cf1ce2898 Update protobuf submodule 2023-01-04 17:19:27 +00:00
Sacha Weatherstone
e4890bfff2 Update README.md 2023-01-02 16:49:27 +11:00
github-actions
5c6ba26334 Update protobuf submodule 2022-12-29 16:18:30 +00:00
Thomas Göttgens
e6e3ad121d Merge pull request #413 from GUVWAF/metrics
Display battery level, channel and Tx air util. with --nodes
2022-12-29 17:13:00 +01:00
Thomas Göttgens
7133c859d6 Merge pull request #411 from mkinney/fix_pylint_warnings
fix pylint warnings
2022-12-29 17:12:00 +01:00
GUVWAF
8acf0b849a --nodes displays battery, channel and Tx air util. 2022-12-29 17:00:35 +01:00
github-actions
42f6818a02 bump version 2022-12-28 16:41:43 +00:00
github-actions
af043ef5c0 Update protobuf submodule 2022-12-28 16:37:24 +00:00
github-actions
4f46858643 bump version 2022-12-27 21:23:16 +00:00
Thomas Göttgens
ddc47fb8de Merge pull request #412 from meshtastic/remote-hardware
tryfix remote hardware
2022-12-27 22:16:57 +01:00
Thomas Göttgens
7ee134b819 tryfix remote hardware 2022-12-27 21:32:25 +01:00
Ben Meadors
254e9f4015 Typos 2022-12-22 14:35:48 -06:00
Mike Kinney
babd1242d5 fix pylint warnings 2022-12-20 11:18:40 -08:00
mkinney
cc99ea009e Update README.md
fix codecoverage link
2022-12-20 11:00:01 -08:00
github-actions
76407e11f8 bump version 2022-12-06 14:44:31 +00:00
Thomas Göttgens
57719ddd5e Merge pull request #407 from GUVWAF/traceRoute
Traceroute option
2022-12-06 15:36:49 +01:00
GUVWAF
d0b8b9ff1b Forgot to convert into TRACEROUTE_APP 2022-12-06 14:18:30 +01:00
github-actions
c5c9723208 Update protobuf submodule 2022-12-06 13:16:28 +00:00
Ben Meadors
9bceaafd9c Merge pull request #406 from GUVWAF/hopLimit
Set hopLimit to the config of the device
2022-12-05 20:10:27 -06:00
GUVWAF
7d3a9178ea Add traceroute option 2022-12-05 20:36:34 +01:00
GUVWAF
2c76c0cafa Remove setting hopLimit to default
Instead set is to config of device
2022-12-05 20:04:38 +01:00
GUVWAF
82977e9ef2 Fix --ch-set help message 2022-12-05 20:02:53 +01:00
Sacha Weatherstone
7a9c25da8e Merge pull request #404 from ahmedkadd/fix-script-typo
Rename protobufs shell script to fix typo
2022-12-02 14:39:18 +11:00
Ahmed Kaddoura
342c48fb16 Rename protobufs shell script to fix typo 2022-11-30 07:58:56 -08:00
github-actions
6bc955a403 bump version 2022-11-27 12:10:59 +00:00
Ben Meadors
741ba378ab Merge pull request #402 from GUVWAF/wantResponse
Only set wantResponse for admin packets
2022-11-27 06:10:01 -06:00
GUVWAF
c1054caf4a Only set wantResponse for admin packets 2022-11-27 12:44:58 +01:00
Ben Meadors
24b97d9277 Merge pull request #401 from GUVWAF/setowner
Remove automatic short owner naming and increase to 4 characters
2022-11-26 07:56:34 -06:00
GUVWAF
868fb64857 Only set is_licensed if long_name is set 2022-11-26 11:08:00 +01:00
GUVWAF
8729e97e1b Remove automatic short owner naming and increase to 4 characters 2022-11-26 10:52:20 +01:00
github-actions
aaed54393e bump version 2022-11-22 17:03:56 +00:00
Ben Meadors
d12776bb5f Merge pull request #400 from meshtastic/transaction-for-config
Transactions for editing settings
2022-11-21 15:27:31 -06:00
Ben Meadors
7829f6afca Args 2022-11-20 20:01:50 -06:00
Ben Meadors
4bd10bc102 Add begin / edit transactions for setting updates 2022-11-20 19:46:43 -06:00
Ben Meadors
3821e02f09 Update protos 2022-11-20 19:11:38 -06:00
Ben Meadors
97689da0b4 Merge pull request #395 from GUVWAF/master
Change how admin packets to remote nodes are handled
2022-11-19 15:36:33 -06:00
GUVWAF
5c75e74bf9 Don't request config and channels if not needed.
Instead, wait for an (implicit) ACK or NAK.
Applies to admin packets set-owner, reboot,
shutdown, factory-reset and reset-nodedb.
2022-11-19 21:19:06 +01:00
GUVWAF
388a46abf4 Merge branch 'meshtastic:master' into master 2022-11-15 13:26:30 +01:00
github-actions
6b89fc81a1 bump version 2022-11-10 03:23:52 +00:00
Ben Meadors
c9b5d5d697 Update protos and add audio 2022-11-09 21:20:38 -06:00
Ben Meadors
f16dd0e737 Update url 2022-11-08 18:25:49 -06:00
Ben Meadors
5ed19eff73 Create cleanup_artifacts.yml 2022-11-05 06:52:28 -05:00
github-actions
0b3605141d bump version 2022-11-03 13:02:34 +00:00
GUVWAF
f1df14ca92 lastTried channel should be its index 2022-11-03 09:28:15 +01:00
GUVWAF
7aff5e9ee5 Unset wantAck if you set wantResponse for Admin 2022-11-02 09:49:20 +01:00
31 changed files with 1054 additions and 412 deletions

20
.github/workflows/cleanup_artifacts.yml vendored Normal file
View File

@@ -0,0 +1,20 @@
name: Remove old artifacts
on:
schedule:
# Every day at 1am
- cron: '0 1 * * *'
workflow_dispatch:
jobs:
remove-old-artifacts:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- name: Remove old artifacts
uses: c-hive/gha-remove-artifacts@v1
with:
age: '1 month'
skip-tags: true

View File

@@ -7,7 +7,7 @@
# Add files or directories matching the regex patterns to the blacklist. The # Add files or directories matching the regex patterns to the blacklist. The
# regex matches against base names, not paths. # regex matches against base names, not paths.
ignore-patterns=mqtt_pb2.py,channel_pb2.py,telemetry_pb2.py,admin_pb2.py,config_pb2.py,deviceonly_pb2.py,apponly_pb2.py,remote_hardware_pb2.py,portnums_pb2.py,mesh_pb2.py,storeforward_pb2.py,cannedmessages_pb2.py,module_config_pb2.py,localonly_pb2.py,node.py ignore-patterns=mqtt_pb2.py,channel_pb2.py,telemetry_pb2.py,admin_pb2.py,config_pb2.py,deviceonly_pb2.py,apponly_pb2.py,remote_hardware_pb2.py,portnums_pb2.py,mesh_pb2.py,storeforward_pb2.py,cannedmessages_pb2.py,module_config_pb2.py,localonly_pb2.py,node.py,device_metadata_pb2.py
@@ -23,7 +23,7 @@ ignore-patterns=mqtt_pb2.py,channel_pb2.py,telemetry_pb2.py,admin_pb2.py,config_
# no Warning level messages displayed, use"--disable=all --enable=classes # no Warning level messages displayed, use"--disable=all --enable=classes
# --disable=W" # --disable=W"
# #
disable=invalid-name,fixme,logging-fstring-interpolation,too-many-statements,too-many-branches,too-many-locals,no-member,f-string-without-interpolation,protected-access,no-self-use,pointless-string-statement,too-few-public-methods,broad-except,no-else-return,no-else-raise,bare-except,too-many-public-methods disable=invalid-name,fixme,logging-fstring-interpolation,too-many-statements,too-many-branches,too-many-locals,no-member,f-string-without-interpolation,protected-access,pointless-string-statement,too-few-public-methods,broad-except,no-else-return,no-else-raise,bare-except,too-many-public-methods
[BASIC] [BASIC]

View File

@@ -1,8 +1,8 @@
# Meshtastic Python # Meshtastic Python
[![codecov](https://codecov.io/gh/meshtastic/python/branch/master/graph/badge.svg?token=TIWPJL73KV)](https://codecov.io/gh/meshtastic/python) [![codecov](https://codecov.io/gh/meshtastic/Meshtastic-python/branch/master/graph/badge.svg?token=TIWPJL73KV)](https://codecov.io/gh/meshtastic/Meshtastic-python)
![PyPI - Downloads](https://img.shields.io/pypi/dm/meshtastic) ![PyPI - Downloads](https://img.shields.io/pypi/dm/meshtastic)
[![CI](https://img.shields.io/github/workflow/status/meshtastic/python/CI?label=actions&logo=github&color=yellow)](https://github.com/meshtastic/python/actions/workflows/ci.yml) [![CI](https://img.shields.io/github/actions/workflow/status/meshtastic/python/ci.yml?branch=master&label=actions&logo=github&color=yellow)](https://github.com/meshtastic/python/actions/workflows/ci.yml)
[![CLA assistant](https://cla-assistant.io/readme/badge/meshtastic/python)](https://cla-assistant.io/meshtastic/python) [![CLA assistant](https://cla-assistant.io/readme/badge/meshtastic/python)](https://cla-assistant.io/meshtastic/python)
[![Fiscal Contributors](https://opencollective.com/meshtastic/tiers/badge.svg?label=Fiscal%20Contributors&color=deeppink)](https://opencollective.com/meshtastic/) [![Fiscal Contributors](https://opencollective.com/meshtastic/tiers/badge.svg?label=Fiscal%20Contributors&color=deeppink)](https://opencollective.com/meshtastic/)
[![Vercel](https://img.shields.io/static/v1?label=Powered%20by&message=Vercel&style=flat&logo=vercel&color=000000)](https://vercel.com?utm_source=meshtastic&utm_campaign=oss) [![Vercel](https://img.shields.io/static/v1?label=Powered%20by&message=Vercel&style=flat&logo=vercel&color=000000)](https://vercel.com?utm_source=meshtastic&utm_campaign=oss)
@@ -14,7 +14,7 @@ This small library (and example application) provides an easy API for sending an
It also provides access to any of the operations/data available in the device user interface or the Android application. It also provides access to any of the operations/data available in the device user interface or the Android application.
Events are delivered using a publish-subscribe model, and you can subscribe to only the message types you are interested in. Events are delivered using a publish-subscribe model, and you can subscribe to only the message types you are interested in.
**[Getting Started Guide](https://meshtastic.org/docs/software/python/python-installation)** **[Getting Started Guide](https://meshtastic.org/docs/software/python/cli/installation)**
**[Documentation/API Reference](https://python.meshtastic.org/)** **[Documentation/API Reference](https://python.meshtastic.org/)**

View File

@@ -1,6 +1,10 @@
#!/bin/bash #!/bin/bash
./nanopb-0.4.6/generator-bin/protoc -I=protobufs --python_out meshtastic `ls protobufs/*.proto` #Uncomment to run hack
#gsed -i 's/import "\//import ".\//g' ./protobufs/meshtastic/*
#gsed -i 's/package meshtastic;//g' ./protobufs/meshtastic/*
./nanopb-0.4.6/generator-bin/protoc -I=protobufs --python_out ./ ./protobufs/meshtastic/*.proto
# workaround for import bug in protoc https://github.com/protocolbuffers/protobuf/issues/1491#issuecomment-690618628 # workaround for import bug in protoc https://github.com/protocolbuffers/protobuf/issues/1491#issuecomment-690618628

View File

@@ -182,6 +182,7 @@ protocols = {
portnums_pb2.PortNum.ADMIN_APP: KnownProtocol("admin", admin_pb2.AdminMessage), portnums_pb2.PortNum.ADMIN_APP: KnownProtocol("admin", admin_pb2.AdminMessage),
portnums_pb2.PortNum.ROUTING_APP: KnownProtocol("routing", mesh_pb2.Routing), portnums_pb2.PortNum.ROUTING_APP: KnownProtocol("routing", mesh_pb2.Routing),
portnums_pb2.PortNum.TELEMETRY_APP: KnownProtocol("telemetry", telemetry_pb2.Telemetry), portnums_pb2.PortNum.TELEMETRY_APP: KnownProtocol("telemetry", telemetry_pb2.Telemetry),
portnums_pb2.PortNum.REMOTE_HARDWARE_APP: KnownProtocol("remotehw", remote_hardware_pb2.HardwareMessage), portnums_pb2.PortNum.REMOTE_HARDWARE_APP: KnownProtocol("remotehw", remote_hardware_pb2.HardwareMessage),
portnums_pb2.PortNum.SIMULATOR_APP: KnownProtocol("simulator", mesh_pb2.Compressed) portnums_pb2.PortNum.SIMULATOR_APP: KnownProtocol("simulator", mesh_pb2.Compressed),
portnums_pb2.PortNum.TRACEROUTE_APP: KnownProtocol("traceroute", mesh_pb2.RouteDiscovery)
} }

View File

@@ -53,10 +53,11 @@ def onConnection(interface, topic=pub.AUTO_TOPIC): # pylint: disable=W0613
print(f"Connection changed: {topic.getName()}") print(f"Connection changed: {topic.getName()}")
def getPref(config, comp_name): def getPref(node, comp_name):
"""Get a channel or preferences value""" """Get a channel or preferences value"""
name = splitCompoundName(comp_name) name = splitCompoundName(comp_name)
wholeField = name[0] == name[1] # We want the whole field
camel_name = meshtastic.util.snake_to_camel(name[1]) camel_name = meshtastic.util.snake_to_camel(name[1])
# Note: protobufs has the keys in snake_case, so snake internally # Note: protobufs has the keys in snake_case, so snake internally
@@ -64,26 +65,49 @@ def getPref(config, comp_name):
logging.debug(f'snake_name:{snake_name} camel_name:{camel_name}') logging.debug(f'snake_name:{snake_name} camel_name:{camel_name}')
logging.debug(f'use camel:{Globals.getInstance().get_camel_case()}') logging.debug(f'use camel:{Globals.getInstance().get_camel_case()}')
objDesc = config.DESCRIPTOR # First validate the input
print() localConfig = node.localConfig
config_type = objDesc.fields_by_name.get(name[0]) moduleConfig = node.moduleConfig
pref = False found = False
if config_type: for config in [localConfig, moduleConfig]:
pref = config_type.message_type.fields_by_name.get(snake_name) objDesc = config.DESCRIPTOR
config_type = objDesc.fields_by_name.get(name[0])
pref = False
if config_type:
pref = config_type.message_type.fields_by_name.get(snake_name)
if pref or wholeField:
found = True
break
if (not pref) or (not config_type): if not found:
if Globals.getInstance().get_camel_case():
print(f"{localConfig.__class__.__name__} and {moduleConfig.__class__.__name__} do not have an attribute {snake_name}.")
else:
print(f"{localConfig.__class__.__name__} and {moduleConfig.__class__.__name__} do not have attribute {snake_name}.")
print("Choices are...")
printConfig(localConfig)
printConfig(moduleConfig)
return False return False
# read the value # Check if we need to request the config
config_values = getattr(config, config_type.name) if len(config.ListFields()) != 0:
pref_value = getattr(config_values, pref.name) # read the value
config_values = getattr(config, config_type.name)
if Globals.getInstance().get_camel_case(): if not wholeField:
print(f"{str(config_type.name)}.{camel_name}: {str(pref_value)}") pref_value = getattr(config_values, pref.name)
logging.debug(f"{str(config_type.name)}.{camel_name}: {str(pref_value)}") if Globals.getInstance().get_camel_case():
else: print(f"{str(config_type.name)}.{camel_name}: {str(pref_value)}")
print(f"{str(config_type.name)}.{snake_name}: {str(pref_value)}") logging.debug(f"{str(config_type.name)}.{camel_name}: {str(pref_value)}")
logging.debug(f"{str(config_type.name)}.{snake_name}: {str(pref_value)}") else:
print(f"{str(config_type.name)}.{snake_name}: {str(pref_value)}")
logging.debug(f"{str(config_type.name)}.{snake_name}: {str(pref_value)}")
else:
print(f"{str(config_type.name)}:\n{str(config_values)}")
logging.debug(f"{str(config_type.name)}: {str(config_values)}")
else:
# Always show whole field for remote node
node.requestConfig(config_type)
return True return True
def splitCompoundName(comp_name): def splitCompoundName(comp_name):
@@ -177,6 +201,7 @@ def setPref(config, comp_name, valStr):
def onConnected(interface): def onConnected(interface):
"""Callback invoked when we connect to a radio""" """Callback invoked when we connect to a radio"""
closeNow = False # Should we drop the connection after we finish? closeNow = False # Should we drop the connection after we finish?
waitForAckNak = False # Should we wait for an acknowledgment if we send to a remote node?
try: try:
our_globals = Globals.getInstance() our_globals = Globals.getInstance()
args = our_globals.get_args() args = our_globals.get_args()
@@ -191,6 +216,7 @@ def onConnected(interface):
alt = 0 alt = 0
lat = 0.0 lat = 0.0
lon = 0.0 lon = 0.0
# TODO: use getNode(args.dest) to be able to set it for a remote node
localConfig = interface.localNode.localConfig localConfig = interface.localNode.localConfig
if args.setalt: if args.setalt:
alt = int(args.setalt) alt = int(args.setalt)
@@ -215,19 +241,29 @@ def onConnected(interface):
if args.set_owner: if args.set_owner:
closeNow = True closeNow = True
waitForAckNak = True
print(f"Setting device owner to {args.set_owner}") print(f"Setting device owner to {args.set_owner}")
interface.getNode(args.dest).setOwner(args.set_owner) interface.getNode(args.dest, False).setOwner(args.set_owner)
if args.set_owner_short: if args.set_owner_short:
closeNow = True closeNow = True
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).setOwner(long_name=None, 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:
closeNow = True closeNow = True
waitForAckNak = True
print(f"Setting canned plugin message to {args.set_canned_message}") print(f"Setting canned plugin message to {args.set_canned_message}")
interface.getNode(args.dest).set_canned_message(args.set_canned_message) interface.getNode(args.dest, False).set_canned_message(args.set_canned_message)
# TODO: add to export-config and configure
if args.set_ringtone:
closeNow = True
waitForAckNak = True
print(f"Setting ringtone to {args.set_ringtone}")
interface.getNode(args.dest, False).set_ringtone(args.set_ringtone)
if args.pos_fields: if args.pos_fields:
# If --pos-fields invoked with args, set position fields # If --pos-fields invoked with args, set position fields
@@ -271,27 +307,40 @@ def onConnected(interface):
if args.reboot: if args.reboot:
closeNow = True closeNow = True
interface.getNode(args.dest).reboot() waitForAckNak = True
interface.getNode(args.dest, False).reboot()
if args.reboot_ota: if args.reboot_ota:
closeNow = True closeNow = True
interface.getNode(args.dest).rebootOTA(); waitForAckNak = True
interface.getNode(args.dest, False).rebootOTA()
if args.shutdown: if args.shutdown:
closeNow = True closeNow = True
interface.getNode(args.dest).shutdown() waitForAckNak = True
interface.getNode(args.dest, False).shutdown()
if args.device_metadata: if args.device_metadata:
closeNow = True closeNow = True
interface.getNode(args.dest).getMetadata() interface.getNode(args.dest, False).getMetadata()
if args.begin_edit:
closeNow = True
interface.getNode(args.dest, False).beginSettingsTransaction()
if args.commit_edit:
closeNow = True
interface.getNode(args.dest, False).commitSettingsTransaction()
if args.factory_reset: if args.factory_reset:
closeNow = True closeNow = True
interface.getNode(args.dest).factoryReset() waitForAckNak = True
interface.getNode(args.dest, False).factoryReset()
if args.reset_nodedb: if args.reset_nodedb:
closeNow = True closeNow = True
interface.getNode(args.dest).resetNodeDb() waitForAckNak = True
interface.getNode(args.dest, False).resetNodeDb()
if args.sendtext: if args.sendtext:
closeNow = True closeNow = True
@@ -312,6 +361,13 @@ def onConnected(interface):
interface.sendData(payload, args.dest, portNum=portnums_pb2.PortNum.REPLY_APP, interface.sendData(payload, args.dest, portNum=portnums_pb2.PortNum.REPLY_APP,
wantAck=True, wantResponse=True) wantAck=True, wantResponse=True)
if args.traceroute:
loraConfig = getattr(interface.localNode.localConfig, 'lora')
hopLimit = getattr(loraConfig, 'hop_limit')
dest = str(args.traceroute)
print(f"Sending traceroute request to {dest} (this could take a while)")
interface.sendTraceRoute(dest, hopLimit)
if args.gpio_wrb or args.gpio_rd or args.gpio_watch: if args.gpio_wrb or args.gpio_rd or args.gpio_watch:
if args.dest == BROADCAST_ADDR: if args.dest == BROADCAST_ADDR:
meshtastic.util.our_exit("Warning: Must use a destination node ID.") meshtastic.util.our_exit("Warning: Must use a destination node ID.")
@@ -350,18 +406,26 @@ def onConnected(interface):
# handle settings # handle settings
if args.set: if args.set:
closeNow = True closeNow = True
node = interface.getNode(args.dest) waitForAckNak = True
node = interface.getNode(args.dest, False)
# Handle the int/float/bool arguments # Handle the int/float/bool arguments
pref = None pref = None
for pref in args.set: for pref in args.set:
found = setPref(node.localConfig, pref[0], pref[1]) found = False
if not found: field = splitCompoundName(pref[0].lower())[0]
found = setPref(node.moduleConfig, pref[0], pref[1]) for config in [node.localConfig, node.moduleConfig]:
config_type = config.DESCRIPTOR.fields_by_name.get(field)
if config_type:
if len(config.ListFields()) == 0:
node.requestConfig(config.DESCRIPTOR.fields_by_name.get(field))
found = setPref(config, pref[0], pref[1])
if found:
break
if found: if found:
print("Writing modified preferences to device") print("Writing modified preferences to device")
interface.getNode(args.dest).writeConfig(splitCompoundName(pref[0].lower())[0]) node.writeConfig(field)
else: else:
if Globals.getInstance().get_camel_case(): if Globals.getInstance().get_camel_case():
print(f"{node.localConfig.__class__.__name__} and {node.moduleConfig.__class__.__name__} do not have an attribute {pref[0]}.") print(f"{node.localConfig.__class__.__name__} and {node.moduleConfig.__class__.__name__} do not have an attribute {pref[0]}.")
@@ -376,17 +440,22 @@ def onConnected(interface):
configuration = yaml.safe_load(file) configuration = yaml.safe_load(file)
closeNow = True closeNow = True
interface.getNode(args.dest, False).beginSettingsTransaction()
if 'owner' in configuration: if 'owner' in configuration:
print(f"Setting device owner to {configuration['owner']}") print(f"Setting device owner to {configuration['owner']}")
interface.getNode(args.dest).setOwner(configuration['owner']) waitForAckNak = True
interface.getNode(args.dest, False).setOwner(configuration['owner'])
if 'owner_short' in configuration: if 'owner_short' in configuration:
print(f"Setting device owner short to {configuration['owner_short']}") print(f"Setting device owner short to {configuration['owner_short']}")
interface.getNode(args.dest).setOwner(long_name=None, short_name=configuration['owner_short']) waitForAckNak = True
interface.getNode(args.dest, False).setOwner(long_name=None, short_name=configuration['owner_short'])
if 'ownerShort' in configuration: if 'ownerShort' in configuration:
print(f"Setting device owner short to {configuration['ownerShort']}") print(f"Setting device owner short to {configuration['ownerShort']}")
interface.getNode(args.dest).setOwner(long_name=None, short_name=configuration['ownerShort']) waitForAckNak = True
interface.getNode(args.dest, False).setOwner(long_name=None, short_name=configuration['ownerShort'])
if 'channel_url' in configuration: if 'channel_url' in configuration:
print("Setting channel url to", configuration['channel_url']) print("Setting channel url to", configuration['channel_url'])
@@ -422,16 +491,17 @@ def onConnected(interface):
localConfig = interface.getNode(args.dest).localConfig localConfig = interface.getNode(args.dest).localConfig
for section in configuration['config']: for section in configuration['config']:
for pref in configuration['config'][section]: for pref in configuration['config'][section]:
setPref(localConfig, f"{section}.{pref}", str(configuration['config'][section][pref])) setPref(localConfig, f"{meshtastic.util.camel_to_snake(section)}.{pref}", str(configuration['config'][section][pref]))
interface.getNode(args.dest).writeConfig(section) interface.getNode(args.dest).writeConfig(meshtastic.util.camel_to_snake(section))
if 'module_config' in configuration: if 'module_config' in configuration:
moduleConfig = interface.getNode(args.dest).moduleConfig moduleConfig = interface.getNode(args.dest).moduleConfig
for section in configuration['module_config']: for section in configuration['module_config']:
for pref in configuration['module_config'][section]: for pref in configuration['module_config'][section]:
setPref(moduleConfig, f"{section}.{pref}", str(configuration['module_config'][section][pref])) setPref(moduleConfig, f"{meshtastic.util.camel_to_snake(section)}.{pref}", str(configuration['module_config'][section][pref]))
interface.getNode(args.dest).writeConfig(section) interface.getNode(args.dest).writeConfig(meshtastic.util.camel_to_snake(section))
interface.getNode(args.dest, False).commitSettingsTransaction()
print("Writing modified configuration to device") print("Writing modified configuration to device")
if args.export_config: if args.export_config:
@@ -549,41 +619,38 @@ def onConnected(interface):
print("") print("")
interface.getNode(args.dest).get_canned_message() interface.getNode(args.dest).get_canned_message()
if args.get_ringtone:
closeNow = True
print("")
interface.getNode(args.dest).get_ringtone()
if args.info: if args.info:
print("") print("")
# If we aren't trying to talk to our local node, don't show it # If we aren't trying to talk to our local node, don't show it
if args.dest == BROADCAST_ADDR: if args.dest == BROADCAST_ADDR:
interface.showInfo() interface.showInfo()
print("")
print("") interface.getNode(args.dest).showInfo()
interface.getNode(args.dest).showInfo() closeNow = True
closeNow = True # FIXME, for now we leave the link up while talking to remote nodes print("")
print("") else:
print("Showing info of remote node is not supported.")
print("Use the '--get' command for a specific configuration (e.g. 'lora') instead.")
if args.get: if args.get:
closeNow = True closeNow = True
localConfig = interface.getNode(args.dest).localConfig node = interface.getNode(args.dest, False)
moduleConfig = interface.getNode(args.dest).moduleConfig
# Handle the int/float/bool arguments
for pref in args.get: for pref in args.get:
found = getPref(localConfig, pref[0]) found = getPref(node, pref[0])
if not found:
found = getPref(moduleConfig, pref[0])
if not found: if found:
if Globals.getInstance().get_camel_case():
print(f"{localConfig.__class__.__name__} and {moduleConfig.__class__.__name__} do not have an attribute {pref[0]}.")
else:
print(f"{localConfig.__class__.__name__} and {moduleConfig.__class__.__name__} do not have attribute {pref[0]}.")
print("Choices are...")
printConfig(localConfig)
printConfig(moduleConfig)
else:
print("Completed getting preferences") print("Completed getting preferences")
if args.nodes: if args.nodes:
closeNow = True closeNow = True
if args.dest != BROADCAST_ADDR:
print("Showing node list of a remote node is not supported.")
return
interface.showNodes() interface.showNodes()
if args.qr: if args.qr:
@@ -604,6 +671,10 @@ def onConnected(interface):
else: else:
tunnel.Tunnel(interface, subnet=args.tunnel_net) tunnel.Tunnel(interface, subnet=args.tunnel_net)
if args.dest != BROADCAST_ADDR and waitForAckNak:
print(f"Waiting for an acknowledgment from remote node (this could take a while)")
interface.getNode(args.dest, False).iface.waitForAckNak()
# if the user didn't ask for serial debugging output, we might want to exit after we've done our operation # if the user didn't ask for serial debugging output, we might want to exit after we've done our operation
if (not args.seriallog) and closeNow: if (not args.seriallog) and closeNow:
interface.close() # after running command then exit interface.close() # after running command then exit
@@ -613,6 +684,7 @@ def onConnected(interface):
interface.close() # close the connection now, so that our app exits interface.close() # close the connection now, so that our app exits
def printConfig(config): def printConfig(config):
"""print configuration"""
objDesc = config.DESCRIPTOR objDesc = config.DESCRIPTOR
for config_section in objDesc.fields: for config_section in objDesc.fields:
if config_section.name != "version": if config_section.name != "version":
@@ -685,7 +757,7 @@ def export_config(interface):
configObj["config"] = config configObj["config"] = config
else: else:
configObj["config"] = config configObj["config"] = config
module_config = MessageToDict(interface.localNode.moduleConfig) module_config = MessageToDict(interface.localNode.moduleConfig)
if module_config: if module_config:
# Convert inner keys to correct snake/camelCase # Convert inner keys to correct snake/camelCase
@@ -824,6 +896,9 @@ def initParser():
parser.add_argument("--get-canned-message", help="Show the canned message plugin message", parser.add_argument("--get-canned-message", help="Show the canned message plugin message",
action="store_true") action="store_true")
parser.add_argument("--get-ringtone", help="Show the stored ringtone",
action="store_true")
parser.add_argument("--nodes", help="Print Node List in a pretty formatted table", parser.add_argument("--nodes", help="Print Node List in a pretty formatted table",
action="store_true") action="store_true")
@@ -861,7 +936,7 @@ def initParser():
"--ch-set", help=("Set a channel parameter. To see channel settings available:'--ch-set all all --ch-index 0'. " "--ch-set", help=("Set a channel parameter. To see channel settings available:'--ch-set all all --ch-index 0'. "
"Can set the 'psk' using this command. To disable encryption on primary channel:'--ch-set psk none --ch-index 0'. " "Can set the 'psk' using this command. To disable encryption on primary channel:'--ch-set psk none --ch-index 0'. "
"To set encryption with a new random key on second channel:'--ch-set psk random --ch-index 1'. " "To set encryption with a new random key on second channel:'--ch-set psk random --ch-index 1'. "
"To set encryption back to the default:'--ch-set default --ch-index 0'. To set encryption with your " "To set encryption back to the default:'--ch-set psk default --ch-index 0'. To set encryption with your "
"own key: '--ch-set psk 0x1a1a1a1a2b2b2b2b1a1a1a1a2b2b2b2b1a1a1a1a2b2b2b2b1a1a1a1a2b2b2b2b --ch-index 0'."), "own key: '--ch-set psk 0x1a1a1a1a2b2b2b2b1a1a1a1a2b2b2b2b1a1a1a1a2b2b2b2b1a1a1a1a2b2b2b2b --ch-index 0'."),
nargs=2, action='append') nargs=2, action='append')
@@ -890,7 +965,10 @@ def initParser():
"--set-owner", help="Set device owner name", action="store") "--set-owner", help="Set device owner name", action="store")
parser.add_argument( parser.add_argument(
"--set-canned-message", help="Set the canned messages plugin message (up to 1000 characters).", action="store") "--set-canned-message", help="Set the canned messages plugin message (up to 200 characters).", action="store")
parser.add_argument(
"--set-ringtone", help="Set the Notification Ringtone (up to 230 characters).", action="store")
parser.add_argument( parser.add_argument(
"--set-owner-short", help="Set device owner short name", action="store") "--set-owner-short", help="Set device owner short name", action="store")
@@ -907,6 +985,12 @@ def initParser():
parser.add_argument( parser.add_argument(
"--sendping", help="Send a ping message (which requests a reply)", action="store_true") "--sendping", help="Send a ping message (which requests a reply)", action="store_true")
parser.add_argument(
"--traceroute", help="Traceroute from connected node to a destination. " \
"You need pass the destination ID as argument, like " \
"this: '--traceroute !ba4bf9d0' " \
"Only nodes that have the encryption key can be traced.")
parser.add_argument( parser.add_argument(
"--reboot", help="Tell the destination node to reboot", action="store_true") "--reboot", help="Tell the destination node to reboot", action="store_true")
@@ -919,9 +1003,15 @@ def initParser():
parser.add_argument( parser.add_argument(
"--device-metadata", help="Get the device metadata from the node", action="store_true") "--device-metadata", help="Get the device metadata from the node", action="store_true")
parser.add_argument(
"--begin-edit", help="Tell the node to open a transaction to edit settings", action="store_true")
parser.add_argument(
"--commit-edit", help="Tell the node to commit open settings transaction", action="store_true")
parser.add_argument( parser.add_argument(
"--factory-reset", help="Tell the destination node to install the default config", action="store_true") "--factory-reset", help="Tell the destination node to install the default config", action="store_true")
parser.add_argument( parser.add_argument(
"--reset-nodedb", help="Tell the destination node clear its list of nodes", action="store_true") "--reset-nodedb", help="Tell the destination node clear its list of nodes", action="store_true")

View File

@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Generated by the protocol buffer compiler. DO NOT EDIT! # Generated by the protocol buffer compiler. DO NOT EDIT!
# source: admin.proto # source: meshtastic/admin.proto
"""Generated protocol buffer code.""" """Generated protocol buffer code."""
from google.protobuf import descriptor as _descriptor from google.protobuf import descriptor as _descriptor
from google.protobuf import descriptor_pool as _descriptor_pool from google.protobuf import descriptor_pool as _descriptor_pool
@@ -12,35 +12,45 @@ from google.protobuf import symbol_database as _symbol_database
_sym_db = _symbol_database.Default() _sym_db = _symbol_database.Default()
from . import channel_pb2 as channel__pb2 from meshtastic import channel_pb2 as meshtastic_dot_channel__pb2
from . import config_pb2 as config__pb2 from meshtastic import config_pb2 as meshtastic_dot_config__pb2
from . import device_metadata_pb2 as device__metadata__pb2 from meshtastic import mesh_pb2 as meshtastic_dot_mesh__pb2
from . import mesh_pb2 as mesh__pb2 from meshtastic import module_config_pb2 as meshtastic_dot_module__config__pb2
from . import module_config_pb2 as module__config__pb2 from meshtastic import connection_status_pb2 as meshtastic_dot_connection__status__pb2
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x0b\x61\x64min.proto\x1a\rchannel.proto\x1a\x0c\x63onfig.proto\x1a\x15\x64\x65vice_metadata.proto\x1a\nmesh.proto\x1a\x13module_config.proto\"\xe8\n\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\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\x1c\n\x12\x63onfirm_set_config\x18@ \x01(\x08H\x00\x12#\n\x19\x63onfirm_set_module_config\x18\x41 \x01(\x08H\x00\x12\x1d\n\x13\x63onfirm_set_channel\x18\x42 \x01(\x08H\x00\x12\x1b\n\x11\x63onfirm_set_radio\x18\x43 \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\"\xa6\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\x42\x11\n\x0fpayload_variantBH\n\x13\x63om.geeksville.meshB\x0b\x41\x64minProtosH\x03Z\"github.com/meshtastic/go/generatedb\x06proto3') 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')
_ADMINMESSAGE = DESCRIPTOR.message_types_by_name['AdminMessage'] _ADMINMESSAGE = DESCRIPTOR.message_types_by_name['AdminMessage']
_HAMPARAMETERS = DESCRIPTOR.message_types_by_name['HamParameters']
_ADMINMESSAGE_CONFIGTYPE = _ADMINMESSAGE.enum_types_by_name['ConfigType'] _ADMINMESSAGE_CONFIGTYPE = _ADMINMESSAGE.enum_types_by_name['ConfigType']
_ADMINMESSAGE_MODULECONFIGTYPE = _ADMINMESSAGE.enum_types_by_name['ModuleConfigType'] _ADMINMESSAGE_MODULECONFIGTYPE = _ADMINMESSAGE.enum_types_by_name['ModuleConfigType']
AdminMessage = _reflection.GeneratedProtocolMessageType('AdminMessage', (_message.Message,), { AdminMessage = _reflection.GeneratedProtocolMessageType('AdminMessage', (_message.Message,), {
'DESCRIPTOR' : _ADMINMESSAGE, 'DESCRIPTOR' : _ADMINMESSAGE,
'__module__' : 'admin_pb2' '__module__' : 'meshtastic.admin_pb2'
# @@protoc_insertion_point(class_scope:AdminMessage) # @@protoc_insertion_point(class_scope:AdminMessage)
}) })
_sym_db.RegisterMessage(AdminMessage) _sym_db.RegisterMessage(AdminMessage)
HamParameters = _reflection.GeneratedProtocolMessageType('HamParameters', (_message.Message,), {
'DESCRIPTOR' : _HAMPARAMETERS,
'__module__' : 'meshtastic.admin_pb2'
# @@protoc_insertion_point(class_scope:HamParameters)
})
_sym_db.RegisterMessage(HamParameters)
if _descriptor._USE_C_DESCRIPTORS == False: if _descriptor._USE_C_DESCRIPTORS == False:
DESCRIPTOR._options = None DESCRIPTOR._options = None
DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\013AdminProtosH\003Z\"github.com/meshtastic/go/generated' DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\013AdminProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000'
_ADMINMESSAGE._serialized_start=101 _ADMINMESSAGE._serialized_start=169
_ADMINMESSAGE._serialized_end=1485 _ADMINMESSAGE._serialized_end=1793
_ADMINMESSAGE_CONFIGTYPE._serialized_start=1148 _ADMINMESSAGE_CONFIGTYPE._serialized_start=1411
_ADMINMESSAGE_CONFIGTYPE._serialized_end=1297 _ADMINMESSAGE_CONFIGTYPE._serialized_end=1560
_ADMINMESSAGE_MODULECONFIGTYPE._serialized_start=1300 _ADMINMESSAGE_MODULECONFIGTYPE._serialized_start=1563
_ADMINMESSAGE_MODULECONFIGTYPE._serialized_end=1466 _ADMINMESSAGE_MODULECONFIGTYPE._serialized_end=1774
_HAMPARAMETERS._serialized_start=1795
_HAMPARAMETERS._serialized_end=1886
# @@protoc_insertion_point(module_scope) # @@protoc_insertion_point(module_scope)

View File

@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Generated by the protocol buffer compiler. DO NOT EDIT! # Generated by the protocol buffer compiler. DO NOT EDIT!
# source: apponly.proto # source: meshtastic/apponly.proto
"""Generated protocol buffer code.""" """Generated protocol buffer code."""
from google.protobuf import descriptor as _descriptor from google.protobuf import descriptor as _descriptor
from google.protobuf import descriptor_pool as _descriptor_pool from google.protobuf import descriptor_pool as _descriptor_pool
@@ -12,18 +12,18 @@ from google.protobuf import symbol_database as _symbol_database
_sym_db = _symbol_database.Default() _sym_db = _symbol_database.Default()
from . import channel_pb2 as channel__pb2 from meshtastic import channel_pb2 as meshtastic_dot_channel__pb2
from . import config_pb2 as config__pb2 from meshtastic import config_pb2 as meshtastic_dot_config__pb2
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\rapponly.proto\x1a\rchannel.proto\x1a\x0c\x63onfig.proto\"Y\n\nChannelSet\x12\"\n\x08settings\x18\x01 \x03(\x0b\x32\x10.ChannelSettings\x12\'\n\x0blora_config\x18\x02 \x01(\x0b\x32\x12.Config.LoRaConfigBJ\n\x13\x63om.geeksville.meshB\rAppOnlyProtosH\x03Z\"github.com/meshtastic/go/generatedb\x06proto3') DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x18meshtastic/apponly.proto\x1a\x18meshtastic/channel.proto\x1a\x17meshtastic/config.proto\"Y\n\nChannelSet\x12\"\n\x08settings\x18\x01 \x03(\x0b\x32\x10.ChannelSettings\x12\'\n\x0blora_config\x18\x02 \x01(\x0b\x32\x12.Config.LoRaConfigBb\n\x13\x63om.geeksville.meshB\rAppOnlyProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3')
_CHANNELSET = DESCRIPTOR.message_types_by_name['ChannelSet'] _CHANNELSET = DESCRIPTOR.message_types_by_name['ChannelSet']
ChannelSet = _reflection.GeneratedProtocolMessageType('ChannelSet', (_message.Message,), { ChannelSet = _reflection.GeneratedProtocolMessageType('ChannelSet', (_message.Message,), {
'DESCRIPTOR' : _CHANNELSET, 'DESCRIPTOR' : _CHANNELSET,
'__module__' : 'apponly_pb2' '__module__' : 'meshtastic.apponly_pb2'
# @@protoc_insertion_point(class_scope:ChannelSet) # @@protoc_insertion_point(class_scope:ChannelSet)
}) })
_sym_db.RegisterMessage(ChannelSet) _sym_db.RegisterMessage(ChannelSet)
@@ -31,7 +31,7 @@ _sym_db.RegisterMessage(ChannelSet)
if _descriptor._USE_C_DESCRIPTORS == False: if _descriptor._USE_C_DESCRIPTORS == False:
DESCRIPTOR._options = None DESCRIPTOR._options = None
DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\rAppOnlyProtosH\003Z\"github.com/meshtastic/go/generated' DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\rAppOnlyProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000'
_CHANNELSET._serialized_start=46 _CHANNELSET._serialized_start=79
_CHANNELSET._serialized_end=135 _CHANNELSET._serialized_end=168
# @@protoc_insertion_point(module_scope) # @@protoc_insertion_point(module_scope)

View File

@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Generated by the protocol buffer compiler. DO NOT EDIT! # Generated by the protocol buffer compiler. DO NOT EDIT!
# source: cannedmessages.proto # source: meshtastic/cannedmessages.proto
"""Generated protocol buffer code.""" """Generated protocol buffer code."""
from google.protobuf import descriptor as _descriptor from google.protobuf import descriptor as _descriptor
from google.protobuf import descriptor_pool as _descriptor_pool from google.protobuf import descriptor_pool as _descriptor_pool
@@ -14,14 +14,14 @@ _sym_db = _symbol_database.Default()
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x14\x63\x61nnedmessages.proto\"-\n\x19\x43\x61nnedMessageModuleConfig\x12\x10\n\x08messages\x18\x01 \x01(\tBV\n\x13\x63om.geeksville.meshB\x19\x43\x61nnedMessageConfigProtosH\x03Z\"github.com/meshtastic/go/generatedb\x06proto3') DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1fmeshtastic/cannedmessages.proto\"-\n\x19\x43\x61nnedMessageModuleConfig\x12\x10\n\x08messages\x18\x01 \x01(\tBn\n\x13\x63om.geeksville.meshB\x19\x43\x61nnedMessageConfigProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3')
_CANNEDMESSAGEMODULECONFIG = DESCRIPTOR.message_types_by_name['CannedMessageModuleConfig'] _CANNEDMESSAGEMODULECONFIG = DESCRIPTOR.message_types_by_name['CannedMessageModuleConfig']
CannedMessageModuleConfig = _reflection.GeneratedProtocolMessageType('CannedMessageModuleConfig', (_message.Message,), { CannedMessageModuleConfig = _reflection.GeneratedProtocolMessageType('CannedMessageModuleConfig', (_message.Message,), {
'DESCRIPTOR' : _CANNEDMESSAGEMODULECONFIG, 'DESCRIPTOR' : _CANNEDMESSAGEMODULECONFIG,
'__module__' : 'cannedmessages_pb2' '__module__' : 'meshtastic.cannedmessages_pb2'
# @@protoc_insertion_point(class_scope:CannedMessageModuleConfig) # @@protoc_insertion_point(class_scope:CannedMessageModuleConfig)
}) })
_sym_db.RegisterMessage(CannedMessageModuleConfig) _sym_db.RegisterMessage(CannedMessageModuleConfig)
@@ -29,7 +29,7 @@ _sym_db.RegisterMessage(CannedMessageModuleConfig)
if _descriptor._USE_C_DESCRIPTORS == False: if _descriptor._USE_C_DESCRIPTORS == False:
DESCRIPTOR._options = None DESCRIPTOR._options = None
DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\031CannedMessageConfigProtosH\003Z\"github.com/meshtastic/go/generated' DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\031CannedMessageConfigProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000'
_CANNEDMESSAGEMODULECONFIG._serialized_start=24 _CANNEDMESSAGEMODULECONFIG._serialized_start=35
_CANNEDMESSAGEMODULECONFIG._serialized_end=69 _CANNEDMESSAGEMODULECONFIG._serialized_end=80
# @@protoc_insertion_point(module_scope) # @@protoc_insertion_point(module_scope)

View File

@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Generated by the protocol buffer compiler. DO NOT EDIT! # Generated by the protocol buffer compiler. DO NOT EDIT!
# source: channel.proto # source: meshtastic/channel.proto
"""Generated protocol buffer code.""" """Generated protocol buffer code."""
from google.protobuf import descriptor as _descriptor from google.protobuf import descriptor as _descriptor
from google.protobuf import descriptor_pool as _descriptor_pool from google.protobuf import descriptor_pool as _descriptor_pool
@@ -14,7 +14,7 @@ _sym_db = _symbol_database.Default()
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\rchannel.proto\"\x83\x01\n\x0f\x43hannelSettings\x12\x17\n\x0b\x63hannel_num\x18\x01 \x01(\rB\x02\x18\x01\x12\x0b\n\x03psk\x18\x02 \x01(\x0c\x12\x0c\n\x04name\x18\x03 \x01(\t\x12\n\n\x02id\x18\x04 \x01(\x07\x12\x16\n\x0euplink_enabled\x18\x05 \x01(\x08\x12\x18\n\x10\x64ownlink_enabled\x18\x06 \x01(\x08\"\x8b\x01\n\x07\x43hannel\x12\r\n\x05index\x18\x01 \x01(\x05\x12\"\n\x08settings\x18\x02 \x01(\x0b\x32\x10.ChannelSettings\x12\x1b\n\x04role\x18\x03 \x01(\x0e\x32\r.Channel.Role\"0\n\x04Role\x12\x0c\n\x08\x44ISABLED\x10\x00\x12\x0b\n\x07PRIMARY\x10\x01\x12\r\n\tSECONDARY\x10\x02\x42J\n\x13\x63om.geeksville.meshB\rChannelProtosH\x03Z\"github.com/meshtastic/go/generatedb\x06proto3') DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x18meshtastic/channel.proto\"\x83\x01\n\x0f\x43hannelSettings\x12\x17\n\x0b\x63hannel_num\x18\x01 \x01(\rB\x02\x18\x01\x12\x0b\n\x03psk\x18\x02 \x01(\x0c\x12\x0c\n\x04name\x18\x03 \x01(\t\x12\n\n\x02id\x18\x04 \x01(\x07\x12\x16\n\x0euplink_enabled\x18\x05 \x01(\x08\x12\x18\n\x10\x64ownlink_enabled\x18\x06 \x01(\x08\"\x8b\x01\n\x07\x43hannel\x12\r\n\x05index\x18\x01 \x01(\x05\x12\"\n\x08settings\x18\x02 \x01(\x0b\x32\x10.ChannelSettings\x12\x1b\n\x04role\x18\x03 \x01(\x0e\x32\r.Channel.Role\"0\n\x04Role\x12\x0c\n\x08\x44ISABLED\x10\x00\x12\x0b\n\x07PRIMARY\x10\x01\x12\r\n\tSECONDARY\x10\x02\x42\x62\n\x13\x63om.geeksville.meshB\rChannelProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3')
@@ -23,14 +23,14 @@ _CHANNEL = DESCRIPTOR.message_types_by_name['Channel']
_CHANNEL_ROLE = _CHANNEL.enum_types_by_name['Role'] _CHANNEL_ROLE = _CHANNEL.enum_types_by_name['Role']
ChannelSettings = _reflection.GeneratedProtocolMessageType('ChannelSettings', (_message.Message,), { ChannelSettings = _reflection.GeneratedProtocolMessageType('ChannelSettings', (_message.Message,), {
'DESCRIPTOR' : _CHANNELSETTINGS, 'DESCRIPTOR' : _CHANNELSETTINGS,
'__module__' : 'channel_pb2' '__module__' : 'meshtastic.channel_pb2'
# @@protoc_insertion_point(class_scope:ChannelSettings) # @@protoc_insertion_point(class_scope:ChannelSettings)
}) })
_sym_db.RegisterMessage(ChannelSettings) _sym_db.RegisterMessage(ChannelSettings)
Channel = _reflection.GeneratedProtocolMessageType('Channel', (_message.Message,), { Channel = _reflection.GeneratedProtocolMessageType('Channel', (_message.Message,), {
'DESCRIPTOR' : _CHANNEL, 'DESCRIPTOR' : _CHANNEL,
'__module__' : 'channel_pb2' '__module__' : 'meshtastic.channel_pb2'
# @@protoc_insertion_point(class_scope:Channel) # @@protoc_insertion_point(class_scope:Channel)
}) })
_sym_db.RegisterMessage(Channel) _sym_db.RegisterMessage(Channel)
@@ -38,13 +38,13 @@ _sym_db.RegisterMessage(Channel)
if _descriptor._USE_C_DESCRIPTORS == False: if _descriptor._USE_C_DESCRIPTORS == False:
DESCRIPTOR._options = None DESCRIPTOR._options = None
DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\rChannelProtosH\003Z\"github.com/meshtastic/go/generated' DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\rChannelProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000'
_CHANNELSETTINGS.fields_by_name['channel_num']._options = None _CHANNELSETTINGS.fields_by_name['channel_num']._options = None
_CHANNELSETTINGS.fields_by_name['channel_num']._serialized_options = b'\030\001' _CHANNELSETTINGS.fields_by_name['channel_num']._serialized_options = b'\030\001'
_CHANNELSETTINGS._serialized_start=18 _CHANNELSETTINGS._serialized_start=29
_CHANNELSETTINGS._serialized_end=149 _CHANNELSETTINGS._serialized_end=160
_CHANNEL._serialized_start=152 _CHANNEL._serialized_start=163
_CHANNEL._serialized_end=291 _CHANNEL._serialized_end=302
_CHANNEL_ROLE._serialized_start=243 _CHANNEL_ROLE._serialized_start=254
_CHANNEL_ROLE._serialized_end=291 _CHANNEL_ROLE._serialized_end=302
# @@protoc_insertion_point(module_scope) # @@protoc_insertion_point(module_scope)

View File

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,85 @@
# -*- coding: utf-8 -*-
# Generated by the protocol buffer compiler. DO NOT EDIT!
# source: meshtastic/connection_status.proto
"""Generated protocol buffer code."""
from google.protobuf import descriptor as _descriptor
from google.protobuf import descriptor_pool as _descriptor_pool
from google.protobuf import message as _message
from google.protobuf import reflection as _reflection
from google.protobuf import symbol_database as _symbol_database
# @@protoc_insertion_point(imports)
_sym_db = _symbol_database.Default()
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\"meshtastic/connection_status.proto\"\x85\x02\n\x16\x44\x65viceConnectionStatus\x12(\n\x04wifi\x18\x01 \x01(\x0b\x32\x15.WifiConnectionStatusH\x00\x88\x01\x01\x12\x30\n\x08\x65thernet\x18\x02 \x01(\x0b\x32\x19.EthernetConnectionStatusH\x01\x88\x01\x01\x12\x32\n\tbluetooth\x18\x03 \x01(\x0b\x32\x1a.BluetoothConnectionStatusH\x02\x88\x01\x01\x12,\n\x06serial\x18\x04 \x01(\x0b\x32\x17.SerialConnectionStatusH\x03\x88\x01\x01\x42\x07\n\x05_wifiB\x0b\n\t_ethernetB\x0c\n\n_bluetoothB\t\n\x07_serial\"\\\n\x14WifiConnectionStatus\x12(\n\x06status\x18\x01 \x01(\x0b\x32\x18.NetworkConnectionStatus\x12\x0c\n\x04ssid\x18\x02 \x01(\t\x12\x0c\n\x04rssi\x18\x03 \x01(\x05\"D\n\x18\x45thernetConnectionStatus\x12(\n\x06status\x18\x01 \x01(\x0b\x32\x18.NetworkConnectionStatus\"{\n\x17NetworkConnectionStatus\x12\x12\n\nip_address\x18\x01 \x01(\x07\x12\x14\n\x0cis_connected\x18\x02 \x01(\x08\x12\x19\n\x11is_mqtt_connected\x18\x03 \x01(\x08\x12\x1b\n\x13is_syslog_connected\x18\x04 \x01(\x08\"L\n\x19\x42luetoothConnectionStatus\x12\x0b\n\x03pin\x18\x01 \x01(\r\x12\x0c\n\x04rssi\x18\x02 \x01(\x05\x12\x14\n\x0cis_connected\x18\x03 \x01(\x08\"<\n\x16SerialConnectionStatus\x12\x0c\n\x04\x62\x61ud\x18\x01 \x01(\r\x12\x14\n\x0cis_connected\x18\x02 \x01(\x08\x42\x65\n\x13\x63om.geeksville.meshB\x10\x43onnStatusProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3')
_DEVICECONNECTIONSTATUS = DESCRIPTOR.message_types_by_name['DeviceConnectionStatus']
_WIFICONNECTIONSTATUS = DESCRIPTOR.message_types_by_name['WifiConnectionStatus']
_ETHERNETCONNECTIONSTATUS = DESCRIPTOR.message_types_by_name['EthernetConnectionStatus']
_NETWORKCONNECTIONSTATUS = DESCRIPTOR.message_types_by_name['NetworkConnectionStatus']
_BLUETOOTHCONNECTIONSTATUS = DESCRIPTOR.message_types_by_name['BluetoothConnectionStatus']
_SERIALCONNECTIONSTATUS = DESCRIPTOR.message_types_by_name['SerialConnectionStatus']
DeviceConnectionStatus = _reflection.GeneratedProtocolMessageType('DeviceConnectionStatus', (_message.Message,), {
'DESCRIPTOR' : _DEVICECONNECTIONSTATUS,
'__module__' : 'meshtastic.connection_status_pb2'
# @@protoc_insertion_point(class_scope:DeviceConnectionStatus)
})
_sym_db.RegisterMessage(DeviceConnectionStatus)
WifiConnectionStatus = _reflection.GeneratedProtocolMessageType('WifiConnectionStatus', (_message.Message,), {
'DESCRIPTOR' : _WIFICONNECTIONSTATUS,
'__module__' : 'meshtastic.connection_status_pb2'
# @@protoc_insertion_point(class_scope:WifiConnectionStatus)
})
_sym_db.RegisterMessage(WifiConnectionStatus)
EthernetConnectionStatus = _reflection.GeneratedProtocolMessageType('EthernetConnectionStatus', (_message.Message,), {
'DESCRIPTOR' : _ETHERNETCONNECTIONSTATUS,
'__module__' : 'meshtastic.connection_status_pb2'
# @@protoc_insertion_point(class_scope:EthernetConnectionStatus)
})
_sym_db.RegisterMessage(EthernetConnectionStatus)
NetworkConnectionStatus = _reflection.GeneratedProtocolMessageType('NetworkConnectionStatus', (_message.Message,), {
'DESCRIPTOR' : _NETWORKCONNECTIONSTATUS,
'__module__' : 'meshtastic.connection_status_pb2'
# @@protoc_insertion_point(class_scope:NetworkConnectionStatus)
})
_sym_db.RegisterMessage(NetworkConnectionStatus)
BluetoothConnectionStatus = _reflection.GeneratedProtocolMessageType('BluetoothConnectionStatus', (_message.Message,), {
'DESCRIPTOR' : _BLUETOOTHCONNECTIONSTATUS,
'__module__' : 'meshtastic.connection_status_pb2'
# @@protoc_insertion_point(class_scope:BluetoothConnectionStatus)
})
_sym_db.RegisterMessage(BluetoothConnectionStatus)
SerialConnectionStatus = _reflection.GeneratedProtocolMessageType('SerialConnectionStatus', (_message.Message,), {
'DESCRIPTOR' : _SERIALCONNECTIONSTATUS,
'__module__' : 'meshtastic.connection_status_pb2'
# @@protoc_insertion_point(class_scope:SerialConnectionStatus)
})
_sym_db.RegisterMessage(SerialConnectionStatus)
if _descriptor._USE_C_DESCRIPTORS == False:
DESCRIPTOR._options = None
DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\020ConnStatusProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000'
_DEVICECONNECTIONSTATUS._serialized_start=39
_DEVICECONNECTIONSTATUS._serialized_end=300
_WIFICONNECTIONSTATUS._serialized_start=302
_WIFICONNECTIONSTATUS._serialized_end=394
_ETHERNETCONNECTIONSTATUS._serialized_start=396
_ETHERNETCONNECTIONSTATUS._serialized_end=464
_NETWORKCONNECTIONSTATUS._serialized_start=466
_NETWORKCONNECTIONSTATUS._serialized_end=589
_BLUETOOTHCONNECTIONSTATUS._serialized_start=591
_BLUETOOTHCONNECTIONSTATUS._serialized_end=667
_SERIALCONNECTIONSTATUS._serialized_start=669
_SERIALCONNECTIONSTATUS._serialized_end=729
# @@protoc_insertion_point(module_scope)

View File

@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Generated by the protocol buffer compiler. DO NOT EDIT! # Generated by the protocol buffer compiler. DO NOT EDIT!
# source: device_metadata.proto # source: meshtastic/device_metadata.proto
"""Generated protocol buffer code.""" """Generated protocol buffer code."""
from google.protobuf import descriptor as _descriptor from google.protobuf import descriptor as _descriptor
from google.protobuf import descriptor_pool as _descriptor_pool from google.protobuf import descriptor_pool as _descriptor_pool
@@ -12,16 +12,18 @@ from google.protobuf import symbol_database as _symbol_database
_sym_db = _symbol_database.Default() _sym_db = _symbol_database.Default()
from meshtastic import config_pb2 as meshtastic_dot_config__pb2
from meshtastic import mesh_pb2 as meshtastic_dot_mesh__pb2
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x15\x64\x65vice_metadata.proto\"H\n\x0e\x44\x65viceMetadata\x12\x18\n\x10\x66irmware_version\x18\x01 \x01(\t\x12\x1c\n\x14\x64\x65vice_state_version\x18\x02 \x01(\rBQ\n\x13\x63om.geeksville.meshB\x14\x44\x65viceMetadataProtosH\x03Z\"github.com/meshtastic/go/generatedb\x06proto3') DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n meshtastic/device_metadata.proto\x1a\x17meshtastic/config.proto\x1a\x15meshtastic/mesh.proto\"\xfc\x01\n\x0e\x44\x65viceMetadata\x12\x18\n\x10\x66irmware_version\x18\x01 \x01(\t\x12\x1c\n\x14\x64\x65vice_state_version\x18\x02 \x01(\r\x12\x13\n\x0b\x63\x61nShutdown\x18\x03 \x01(\x08\x12\x0f\n\x07hasWifi\x18\x04 \x01(\x08\x12\x14\n\x0chasBluetooth\x18\x05 \x01(\x08\x12\x13\n\x0bhasEthernet\x18\x06 \x01(\x08\x12\'\n\x04role\x18\x07 \x01(\x0e\x32\x19.Config.DeviceConfig.Role\x12\x16\n\x0eposition_flags\x18\x08 \x01(\r\x12 \n\x08hw_model\x18\t \x01(\x0e\x32\x0e.HardwareModelBi\n\x13\x63om.geeksville.meshB\x14\x44\x65viceMetadataProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3')
_DEVICEMETADATA = DESCRIPTOR.message_types_by_name['DeviceMetadata'] _DEVICEMETADATA = DESCRIPTOR.message_types_by_name['DeviceMetadata']
DeviceMetadata = _reflection.GeneratedProtocolMessageType('DeviceMetadata', (_message.Message,), { DeviceMetadata = _reflection.GeneratedProtocolMessageType('DeviceMetadata', (_message.Message,), {
'DESCRIPTOR' : _DEVICEMETADATA, 'DESCRIPTOR' : _DEVICEMETADATA,
'__module__' : 'device_metadata_pb2' '__module__' : 'meshtastic.device_metadata_pb2'
# @@protoc_insertion_point(class_scope:DeviceMetadata) # @@protoc_insertion_point(class_scope:DeviceMetadata)
}) })
_sym_db.RegisterMessage(DeviceMetadata) _sym_db.RegisterMessage(DeviceMetadata)
@@ -29,7 +31,7 @@ _sym_db.RegisterMessage(DeviceMetadata)
if _descriptor._USE_C_DESCRIPTORS == False: if _descriptor._USE_C_DESCRIPTORS == False:
DESCRIPTOR._options = None DESCRIPTOR._options = None
DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\024DeviceMetadataProtosH\003Z\"github.com/meshtastic/go/generated' DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\024DeviceMetadataProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000'
_DEVICEMETADATA._serialized_start=25 _DEVICEMETADATA._serialized_start=85
_DEVICEMETADATA._serialized_end=97 _DEVICEMETADATA._serialized_end=337
# @@protoc_insertion_point(module_scope) # @@protoc_insertion_point(module_scope)

View File

@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Generated by the protocol buffer compiler. DO NOT EDIT! # Generated by the protocol buffer compiler. DO NOT EDIT!
# source: deviceonly.proto # source: meshtastic/deviceonly.proto
"""Generated protocol buffer code.""" """Generated protocol buffer code."""
from google.protobuf.internal import enum_type_wrapper from google.protobuf.internal import enum_type_wrapper
from google.protobuf import descriptor as _descriptor from google.protobuf import descriptor as _descriptor
@@ -13,11 +13,12 @@ from google.protobuf import symbol_database as _symbol_database
_sym_db = _symbol_database.Default() _sym_db = _symbol_database.Default()
from . import channel_pb2 as channel__pb2 from meshtastic import channel_pb2 as meshtastic_dot_channel__pb2
from . import mesh_pb2 as mesh__pb2 from meshtastic import localonly_pb2 as meshtastic_dot_localonly__pb2
from meshtastic import mesh_pb2 as meshtastic_dot_mesh__pb2
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x10\x64\x65viceonly.proto\x1a\rchannel.proto\x1a\nmesh.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\"\x99\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*>\n\x0bScreenFonts\x12\x0e\n\nFONT_SMALL\x10\x00\x12\x0f\n\x0b\x46ONT_MEDIUM\x10\x01\x12\x0e\n\nFONT_LARGE\x10\x02\x42G\n\x13\x63om.geeksville.meshB\nDeviceOnlyH\x03Z\"github.com/meshtastic/go/generatedb\x06proto3') 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')
_SCREENFONTS = DESCRIPTOR.enum_types_by_name['ScreenFonts'] _SCREENFONTS = DESCRIPTOR.enum_types_by_name['ScreenFonts']
ScreenFonts = enum_type_wrapper.EnumTypeWrapper(_SCREENFONTS) ScreenFonts = enum_type_wrapper.EnumTypeWrapper(_SCREENFONTS)
@@ -31,21 +32,21 @@ _CHANNELFILE = DESCRIPTOR.message_types_by_name['ChannelFile']
_OEMSTORE = DESCRIPTOR.message_types_by_name['OEMStore'] _OEMSTORE = DESCRIPTOR.message_types_by_name['OEMStore']
DeviceState = _reflection.GeneratedProtocolMessageType('DeviceState', (_message.Message,), { DeviceState = _reflection.GeneratedProtocolMessageType('DeviceState', (_message.Message,), {
'DESCRIPTOR' : _DEVICESTATE, 'DESCRIPTOR' : _DEVICESTATE,
'__module__' : 'deviceonly_pb2' '__module__' : 'meshtastic.deviceonly_pb2'
# @@protoc_insertion_point(class_scope:DeviceState) # @@protoc_insertion_point(class_scope:DeviceState)
}) })
_sym_db.RegisterMessage(DeviceState) _sym_db.RegisterMessage(DeviceState)
ChannelFile = _reflection.GeneratedProtocolMessageType('ChannelFile', (_message.Message,), { ChannelFile = _reflection.GeneratedProtocolMessageType('ChannelFile', (_message.Message,), {
'DESCRIPTOR' : _CHANNELFILE, 'DESCRIPTOR' : _CHANNELFILE,
'__module__' : 'deviceonly_pb2' '__module__' : 'meshtastic.deviceonly_pb2'
# @@protoc_insertion_point(class_scope:ChannelFile) # @@protoc_insertion_point(class_scope:ChannelFile)
}) })
_sym_db.RegisterMessage(ChannelFile) _sym_db.RegisterMessage(ChannelFile)
OEMStore = _reflection.GeneratedProtocolMessageType('OEMStore', (_message.Message,), { OEMStore = _reflection.GeneratedProtocolMessageType('OEMStore', (_message.Message,), {
'DESCRIPTOR' : _OEMSTORE, 'DESCRIPTOR' : _OEMSTORE,
'__module__' : 'deviceonly_pb2' '__module__' : 'meshtastic.deviceonly_pb2'
# @@protoc_insertion_point(class_scope:OEMStore) # @@protoc_insertion_point(class_scope:OEMStore)
}) })
_sym_db.RegisterMessage(OEMStore) _sym_db.RegisterMessage(OEMStore)
@@ -53,13 +54,13 @@ _sym_db.RegisterMessage(OEMStore)
if _descriptor._USE_C_DESCRIPTORS == False: if _descriptor._USE_C_DESCRIPTORS == False:
DESCRIPTOR._options = None DESCRIPTOR._options = None
DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\nDeviceOnlyH\003Z\"github.com/meshtastic/go/generated' DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\nDeviceOnlyZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000'
_SCREENFONTS._serialized_start=490 _SCREENFONTS._serialized_start=644
_SCREENFONTS._serialized_end=552 _SCREENFONTS._serialized_end=706
_DEVICESTATE._serialized_start=48 _DEVICESTATE._serialized_start=109
_DEVICESTATE._serialized_end=272 _DEVICESTATE._serialized_end=333
_CHANNELFILE._serialized_start=274 _CHANNELFILE._serialized_start=335
_CHANNELFILE._serialized_end=332 _CHANNELFILE._serialized_end=393
_OEMSTORE._serialized_start=335 _OEMSTORE._serialized_start=396
_OEMSTORE._serialized_end=488 _OEMSTORE._serialized_end=642
# @@protoc_insertion_point(module_scope) # @@protoc_insertion_point(module_scope)

View File

@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Generated by the protocol buffer compiler. DO NOT EDIT! # Generated by the protocol buffer compiler. DO NOT EDIT!
# source: localonly.proto # source: meshtastic/localonly.proto
"""Generated protocol buffer code.""" """Generated protocol buffer code."""
from google.protobuf import descriptor as _descriptor from google.protobuf import descriptor as _descriptor
from google.protobuf import descriptor_pool as _descriptor_pool from google.protobuf import descriptor_pool as _descriptor_pool
@@ -12,11 +12,11 @@ from google.protobuf import symbol_database as _symbol_database
_sym_db = _symbol_database.Default() _sym_db = _symbol_database.Default()
from . import config_pb2 as config__pb2 from meshtastic import config_pb2 as meshtastic_dot_config__pb2
from . import module_config_pb2 as module__config__pb2 from meshtastic import module_config_pb2 as meshtastic_dot_module__config__pb2
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x0flocalonly.proto\x1a\x0c\x63onfig.proto\x1a\x13module_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\"\x9a\x03\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\x0f\n\x07version\x18\x08 \x01(\rBL\n\x13\x63om.geeksville.meshB\x0fLocalOnlyProtosH\x03Z\"github.com/meshtastic/go/generatedb\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\"\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')
@@ -24,14 +24,14 @@ _LOCALCONFIG = DESCRIPTOR.message_types_by_name['LocalConfig']
_LOCALMODULECONFIG = DESCRIPTOR.message_types_by_name['LocalModuleConfig'] _LOCALMODULECONFIG = DESCRIPTOR.message_types_by_name['LocalModuleConfig']
LocalConfig = _reflection.GeneratedProtocolMessageType('LocalConfig', (_message.Message,), { LocalConfig = _reflection.GeneratedProtocolMessageType('LocalConfig', (_message.Message,), {
'DESCRIPTOR' : _LOCALCONFIG, 'DESCRIPTOR' : _LOCALCONFIG,
'__module__' : 'localonly_pb2' '__module__' : 'meshtastic.localonly_pb2'
# @@protoc_insertion_point(class_scope:LocalConfig) # @@protoc_insertion_point(class_scope:LocalConfig)
}) })
_sym_db.RegisterMessage(LocalConfig) _sym_db.RegisterMessage(LocalConfig)
LocalModuleConfig = _reflection.GeneratedProtocolMessageType('LocalModuleConfig', (_message.Message,), { LocalModuleConfig = _reflection.GeneratedProtocolMessageType('LocalModuleConfig', (_message.Message,), {
'DESCRIPTOR' : _LOCALMODULECONFIG, 'DESCRIPTOR' : _LOCALMODULECONFIG,
'__module__' : 'localonly_pb2' '__module__' : 'meshtastic.localonly_pb2'
# @@protoc_insertion_point(class_scope:LocalModuleConfig) # @@protoc_insertion_point(class_scope:LocalModuleConfig)
}) })
_sym_db.RegisterMessage(LocalModuleConfig) _sym_db.RegisterMessage(LocalModuleConfig)
@@ -39,9 +39,9 @@ _sym_db.RegisterMessage(LocalModuleConfig)
if _descriptor._USE_C_DESCRIPTORS == False: if _descriptor._USE_C_DESCRIPTORS == False:
DESCRIPTOR._options = None DESCRIPTOR._options = None
DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\017LocalOnlyProtosH\003Z\"github.com/meshtastic/go/generated' DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\017LocalOnlyProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000'
_LOCALCONFIG._serialized_start=55 _LOCALCONFIG._serialized_start=88
_LOCALCONFIG._serialized_end=359 _LOCALCONFIG._serialized_end=392
_LOCALMODULECONFIG._serialized_start=362 _LOCALMODULECONFIG._serialized_start=395
_LOCALMODULECONFIG._serialized_end=772 _LOCALMODULECONFIG._serialized_end=908
# @@protoc_insertion_point(module_scope) # @@protoc_insertion_point(module_scope)

View File

@@ -18,7 +18,7 @@ from google.protobuf.json_format import MessageToJson
import meshtastic.node import meshtastic.node
from meshtastic import portnums_pb2, mesh_pb2 from meshtastic import portnums_pb2, mesh_pb2
from meshtastic.util import stripnl, Timeout, our_exit, remove_keys_from_dict, convert_mac_addr from meshtastic.util import stripnl, Timeout, Acknowledgment, our_exit, remove_keys_from_dict, convert_mac_addr
from meshtastic.__init__ import LOCAL_ADDR, BROADCAST_NUM, BROADCAST_ADDR, ResponseHandler, publishingThread, OUR_APP_VERSION, protocols from meshtastic.__init__ import LOCAL_ADDR, BROADCAST_NUM, BROADCAST_ADDR, ResponseHandler, publishingThread, OUR_APP_VERSION, protocols
class MeshInterface: class MeshInterface:
@@ -47,12 +47,12 @@ class MeshInterface:
self.responseHandlers = {} # A map from request ID to the handler 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 self.failure = None # If we've encountered a fatal exception it will be kept here
self._timeout = Timeout() self._timeout = Timeout()
self._acknowledgment = Acknowledgment()
self.heartbeatTimer = None self.heartbeatTimer = None
random.seed() # FIXME, we should not clobber the random seedval here, instead tell user they must call it random.seed() # FIXME, we should not clobber the random seedval here, instead tell user they must call it
self.currentPacketId = random.randint(0, 0xffffffff) self.currentPacketId = random.randint(0, 0xffffffff)
self.nodesByNum = None self.nodesByNum = None
self.configId = None self.configId = None
self.defaultHopLimit = 3
self.gotResponse = False # used in gpio read self.gotResponse = False # used in gpio read
self.mask = None # used in gpio read and gpio watch self.mask = None # used in gpio read and gpio watch
@@ -137,7 +137,20 @@ class MeshInterface:
"Latitude": formatFloat(pos.get("latitude"), 4, "°"), "Latitude": formatFloat(pos.get("latitude"), 4, "°"),
"Longitude": formatFloat(pos.get("longitude"), 4, "°"), "Longitude": formatFloat(pos.get("longitude"), 4, "°"),
"Altitude": formatFloat(pos.get("altitude"), 0, " m"), "Altitude": formatFloat(pos.get("altitude"), 0, " m"),
"Battery": formatFloat(pos.get("batteryLevel"), 2, "%"), })
metrics = node.get('deviceMetrics')
if metrics:
batteryLevel = metrics.get('batteryLevel')
if batteryLevel is not None:
if batteryLevel == 0:
batteryString = "Powered"
else:
batteryString = str(batteryLevel)+"%"
row.update({"Battery": batteryString})
row.update({
"Channel util.": formatFloat(metrics.get('channelUtilization'), 2, "%"),
"Tx air util.": formatFloat(metrics.get('airUtilTx'), 2, "%"),
}) })
row.update({ row.update({
@@ -157,23 +170,24 @@ class MeshInterface:
return table return table
def getNode(self, nodeId): def getNode(self, nodeId, requestChannels=True):
"""Return a node object which contains device settings and channel info""" """Return a node object which contains device settings and channel info"""
if nodeId in (LOCAL_ADDR, BROADCAST_ADDR): if nodeId in (LOCAL_ADDR, BROADCAST_ADDR):
return self.localNode return self.localNode
else: else:
n = meshtastic.node.Node(self, nodeId) n = meshtastic.node.Node(self, nodeId)
logging.debug("About to requestConfig") # Only request device settings and channel info when necessary
n.requestConfig() if requestChannels:
if not n.waitForConfig(): logging.debug("About to requestChannels")
our_exit("Error: Timed out waiting for node config") n.requestChannels()
if not n.waitForConfig():
our_exit("Error: Timed out waiting for channels")
return n return n
def sendText(self, text: AnyStr, def sendText(self, text: AnyStr,
destinationId=BROADCAST_ADDR, destinationId=BROADCAST_ADDR,
wantAck=False, wantAck=False,
wantResponse=False, wantResponse=False,
hopLimit=None,
onResponse=None, onResponse=None,
channelIndex=0): channelIndex=0):
"""Send a utf8 string to some other node, if the node has a display it """Send a utf8 string to some other node, if the node has a display it
@@ -195,21 +209,17 @@ class MeshInterface:
Returns the sent packet. The id field will be populated in this packet Returns the sent packet. The id field will be populated in this packet
and can be used to track future message acks/naks. and can be used to track future message acks/naks.
""" """
if hopLimit is None:
hopLimit = self.defaultHopLimit
return self.sendData(text.encode("utf-8"), destinationId, return self.sendData(text.encode("utf-8"), destinationId,
portNum=portnums_pb2.PortNum.TEXT_MESSAGE_APP, portNum=portnums_pb2.PortNum.TEXT_MESSAGE_APP,
wantAck=wantAck, wantAck=wantAck,
wantResponse=wantResponse, wantResponse=wantResponse,
hopLimit=hopLimit,
onResponse=onResponse, onResponse=onResponse,
channelIndex=channelIndex) channelIndex=channelIndex)
def sendData(self, data, destinationId=BROADCAST_ADDR, def sendData(self, data, destinationId=BROADCAST_ADDR,
portNum=portnums_pb2.PortNum.PRIVATE_APP, wantAck=False, portNum=portnums_pb2.PortNum.PRIVATE_APP, wantAck=False,
wantResponse=False, wantResponse=False,
hopLimit=None,
onResponse=None, onResponse=None,
channelIndex=0): channelIndex=0):
"""Send a data packet to some other node """Send a data packet to some other node
@@ -234,8 +244,6 @@ class MeshInterface:
Returns the sent packet. The id field will be populated in this packet Returns the sent packet. The id field will be populated in this packet
and can be used to track future message acks/naks. and can be used to track future message acks/naks.
""" """
if hopLimit is None:
hopLimit = self.defaultHopLimit
if getattr(data, "SerializeToString", None): if getattr(data, "SerializeToString", None):
logging.debug(f"Serializing protobuf as data: {stripnl(data)}") logging.debug(f"Serializing protobuf as data: {stripnl(data)}")
@@ -258,8 +266,7 @@ class MeshInterface:
if onResponse is not None: if onResponse is not None:
self._addResponseHandler(meshPacket.id, onResponse) self._addResponseHandler(meshPacket.id, onResponse)
p = self._sendPacket(meshPacket, destinationId, p = self._sendPacket(meshPacket, destinationId, wantAck=wantAck)
wantAck=wantAck, hopLimit=hopLimit)
return p return p
def sendPosition(self, latitude=0.0, longitude=0.0, altitude=0, timeSec=0, def sendPosition(self, latitude=0.0, longitude=0.0, altitude=0, timeSec=0,
@@ -298,20 +305,43 @@ class MeshInterface:
wantAck=wantAck, wantAck=wantAck,
wantResponse=wantResponse) wantResponse=wantResponse)
def sendTraceRoute(self, dest, hopLimit):
"""Send the trace route"""
r = mesh_pb2.RouteDiscovery()
self.sendData(r, destinationId=dest, portNum=portnums_pb2.PortNum.TRACEROUTE_APP,
wantResponse=True, onResponse=self.onResponseTraceRoute)
# extend timeout based on number of nodes, limit by configured hopLimit
waitFactor = min(len(self.nodes)-1, hopLimit)
self.waitForTraceRoute(waitFactor)
def onResponseTraceRoute(self, p):
"""on response for trace route"""
routeDiscovery = mesh_pb2.RouteDiscovery()
routeDiscovery.ParseFromString(p["decoded"]["payload"])
asDict = google.protobuf.json_format.MessageToDict(routeDiscovery)
print("Route traced:")
routeStr = self._nodeNumToId(p["to"])
if "route" in asDict:
for nodeNum in asDict["route"]:
routeStr += " --> " + self._nodeNumToId(nodeNum)
routeStr += " --> " + self._nodeNumToId(p["from"])
print(routeStr)
self._acknowledgment.receivedTraceRoute = True
def _addResponseHandler(self, requestId, callback): def _addResponseHandler(self, requestId, callback):
self.responseHandlers[requestId] = ResponseHandler(callback) self.responseHandlers[requestId] = ResponseHandler(callback)
def _sendPacket(self, meshPacket, def _sendPacket(self, meshPacket,
destinationId=BROADCAST_ADDR, destinationId=BROADCAST_ADDR,
wantAck=False, hopLimit=None): wantAck=False):
"""Send a MeshPacket to the specified node (or if unspecified, broadcast). """Send a MeshPacket to the specified node (or if unspecified, broadcast).
You probably don't want this - use sendData instead. You probably don't want this - use sendData instead.
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.
""" """
if hopLimit is None:
hopLimit = self.defaultHopLimit
# We allow users to talk to the local node before we've completed the full connection flow... # We allow users to talk to the local node before we've completed the full connection flow...
if(self.myInfo is not None and destinationId != self.myInfo.my_node_num): if(self.myInfo is not None and destinationId != self.myInfo.my_node_num):
@@ -345,6 +375,8 @@ class MeshInterface:
meshPacket.to = nodeNum meshPacket.to = nodeNum
meshPacket.want_ack = wantAck meshPacket.want_ack = wantAck
loraConfig = getattr(self.localNode.localConfig, 'lora')
hopLimit = getattr(loraConfig, 'hop_limit')
meshPacket.hop_limit = hopLimit meshPacket.hop_limit = hopLimit
# if the user hasn't set an ID for this packet (likely and recommended), # if the user hasn't set an ID for this packet (likely and recommended),
@@ -366,6 +398,18 @@ class MeshInterface:
if not success: if not success:
raise Exception("Timed out waiting for interface config") raise Exception("Timed out waiting for interface config")
def waitForAckNak(self):
"""Wait for the ack/nak"""
success = self._timeout.waitForAckNak(self._acknowledgment)
if not success:
raise Exception("Timed out waiting for an acknowledgment")
def waitForTraceRoute(self, waitFactor):
"""Wait for trace route"""
success = self._timeout.waitForTraceRoute(waitFactor, self._acknowledgment)
if not success:
raise Exception("Timed out waiting for traceroute")
def getMyNodeInfo(self): def getMyNodeInfo(self):
"""Get info about my node.""" """Get info about my node."""
if self.myInfo is None: if self.myInfo is None:
@@ -478,7 +522,7 @@ class MeshInterface:
Done with initial config messages, now send regular MeshPackets Done with initial config messages, now send regular MeshPackets
to ask for settings and channels to ask for settings and channels
""" """
self.localNode.requestConfig() self.localNode.requestChannels()
def _handleFromRadio(self, fromRadioBytes): def _handleFromRadio(self, fromRadioBytes):
""" """
@@ -571,6 +615,10 @@ class MeshInterface:
self.localNode.moduleConfig.telemetry.CopyFrom(fromRadio.moduleConfig.telemetry) self.localNode.moduleConfig.telemetry.CopyFrom(fromRadio.moduleConfig.telemetry)
elif fromRadio.moduleConfig.HasField("canned_message"): elif fromRadio.moduleConfig.HasField("canned_message"):
self.localNode.moduleConfig.canned_message.CopyFrom(fromRadio.moduleConfig.canned_message) self.localNode.moduleConfig.canned_message.CopyFrom(fromRadio.moduleConfig.canned_message)
elif fromRadio.moduleConfig.HasField("audio"):
self.localNode.moduleConfig.audio.CopyFrom(fromRadio.moduleConfig.audio)
elif fromRadio.moduleConfig.HasField("remote_hardware"):
self.localNode.moduleConfig.remote_hardware.CopyFrom(fromRadio.moduleConfig.remote_hardware)
else: else:
logging.debug("Unexpected FromRadio payload") logging.debug("Unexpected FromRadio payload")
@@ -717,7 +765,8 @@ class MeshInterface:
# we keep the responseHandler in dict until we get a non ack # we keep the responseHandler in dict until we get a non ack
handler = self.responseHandlers.pop(requestId, None) handler = self.responseHandlers.pop(requestId, None)
if handler is not None: if handler is not None:
handler.callback(asDict) if not isAck or (isAck and handler.__name__ == "onAckNak"):
handler.callback(asDict)
logging.debug(f"Publishing {topic}: packet={stripnl(asDict)} ") logging.debug(f"Publishing {topic}: packet={stripnl(asDict)} ")
publishingThread.queueWork(lambda: pub.sendMessage( publishingThread.queueWork(lambda: pub.sendMessage(

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

@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Generated by the protocol buffer compiler. DO NOT EDIT! # Generated by the protocol buffer compiler. DO NOT EDIT!
# source: mqtt.proto # source: meshtastic/mqtt.proto
"""Generated protocol buffer code.""" """Generated protocol buffer code."""
from google.protobuf import descriptor as _descriptor from google.protobuf import descriptor as _descriptor
from google.protobuf import descriptor_pool as _descriptor_pool from google.protobuf import descriptor_pool as _descriptor_pool
@@ -12,17 +12,17 @@ from google.protobuf import symbol_database as _symbol_database
_sym_db = _symbol_database.Default() _sym_db = _symbol_database.Default()
from . import mesh_pb2 as mesh__pb2 from meshtastic import mesh_pb2 as meshtastic_dot_mesh__pb2
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\nmqtt.proto\x1a\nmesh.proto\"V\n\x0fServiceEnvelope\x12\x1b\n\x06packet\x18\x01 \x01(\x0b\x32\x0b.MeshPacket\x12\x12\n\nchannel_id\x18\x02 \x01(\t\x12\x12\n\ngateway_id\x18\x03 \x01(\tBG\n\x13\x63om.geeksville.meshB\nMQTTProtosH\x03Z\"github.com/meshtastic/go/generatedb\x06proto3') DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x15meshtastic/mqtt.proto\x1a\x15meshtastic/mesh.proto\"V\n\x0fServiceEnvelope\x12\x1b\n\x06packet\x18\x01 \x01(\x0b\x32\x0b.MeshPacket\x12\x12\n\nchannel_id\x18\x02 \x01(\t\x12\x12\n\ngateway_id\x18\x03 \x01(\tB_\n\x13\x63om.geeksville.meshB\nMQTTProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3')
_SERVICEENVELOPE = DESCRIPTOR.message_types_by_name['ServiceEnvelope'] _SERVICEENVELOPE = DESCRIPTOR.message_types_by_name['ServiceEnvelope']
ServiceEnvelope = _reflection.GeneratedProtocolMessageType('ServiceEnvelope', (_message.Message,), { ServiceEnvelope = _reflection.GeneratedProtocolMessageType('ServiceEnvelope', (_message.Message,), {
'DESCRIPTOR' : _SERVICEENVELOPE, 'DESCRIPTOR' : _SERVICEENVELOPE,
'__module__' : 'mqtt_pb2' '__module__' : 'meshtastic.mqtt_pb2'
# @@protoc_insertion_point(class_scope:ServiceEnvelope) # @@protoc_insertion_point(class_scope:ServiceEnvelope)
}) })
_sym_db.RegisterMessage(ServiceEnvelope) _sym_db.RegisterMessage(ServiceEnvelope)
@@ -30,7 +30,7 @@ _sym_db.RegisterMessage(ServiceEnvelope)
if _descriptor._USE_C_DESCRIPTORS == False: if _descriptor._USE_C_DESCRIPTORS == False:
DESCRIPTOR._options = None DESCRIPTOR._options = None
DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\nMQTTProtosH\003Z\"github.com/meshtastic/go/generated' DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\nMQTTProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000'
_SERVICEENVELOPE._serialized_start=26 _SERVICEENVELOPE._serialized_start=48
_SERVICEENVELOPE._serialized_end=112 _SERVICEENVELOPE._serialized_end=134
# @@protoc_insertion_point(module_scope) # @@protoc_insertion_point(module_scope)

View File

@@ -6,7 +6,7 @@ import base64
import time import time
from google.protobuf.json_format import MessageToJson from google.protobuf.json_format import MessageToJson
from meshtastic import portnums_pb2, apponly_pb2, admin_pb2, channel_pb2, localonly_pb2 from meshtastic import portnums_pb2, apponly_pb2, admin_pb2, channel_pb2, localonly_pb2
from meshtastic.util import pskToString, stripnl, Timeout, our_exit, fromPSK from meshtastic.util import pskToString, stripnl, Timeout, our_exit, fromPSK, camel_to_snake
class Node: class Node:
@@ -26,8 +26,9 @@ class Node:
self.partialChannels = None self.partialChannels = None
self.noProto = noProto self.noProto = noProto
self.cannedPluginMessage = None self.cannedPluginMessage = None
self.cannedPluginMessageMessages = None self.cannedPluginMessageMessages = None
self.ringtone = None
self.ringtonePart = None
self.gotResponse = None self.gotResponse = None
@@ -60,13 +61,60 @@ class Node:
print(f"Module preferences: {prefs}\n") print(f"Module preferences: {prefs}\n")
self.showChannels() self.showChannels()
def requestConfig(self): def requestChannels(self):
"""Send regular MeshPackets to ask for settings and channels.""" """Send regular MeshPackets to ask channels."""
logging.debug(f"requestConfig for nodeNum:{self.nodeNum}") logging.debug(f"requestChannels for nodeNum:{self.nodeNum}")
self.channels = None self.channels = None
self.partialChannels = [] # We keep our channels in a temp array until finished self.partialChannels = [] # We keep our channels in a temp array until finished
self._requestChannel(0) self._requestChannel(0)
def onResponseRequestSettings(self, p):
"""Handle the response packets for requesting settings _requestSettings()"""
logging.debug(f'onResponseRequestSetting() p:{p}')
if "routing" in p["decoded"]:
if p["decoded"]["routing"]["errorReason"] != "NONE":
print(f'Error on response: {p["decoded"]["routing"]["errorReason"]}')
self.iface._acknowledgment.receivedNak = True
else:
self.iface._acknowledgment.receivedAck = True
print("")
adminMessage = p["decoded"]["admin"]
if "getConfigResponse" in adminMessage:
resp = adminMessage["getConfigResponse"]
field = list(resp.keys())[0]
config_type = self.localConfig.DESCRIPTOR.fields_by_name.get(camel_to_snake(field))
config_values = getattr(self.localConfig, config_type.name)
elif "getModuleConfigResponse" in adminMessage:
resp = adminMessage["getModuleConfigResponse"]
field = list(resp.keys())[0]
config_type = self.moduleConfig.DESCRIPTOR.fields_by_name.get(camel_to_snake(field))
config_values = getattr(self.moduleConfig, config_type.name)
else:
print("Did not receive a valid response. Make sure to have a shared channel named 'admin'.")
return
for key, value in resp[field].items():
setattr(config_values, camel_to_snake(key), value)
print(f"{str(camel_to_snake(field))}:\n{str(config_values)}")
def requestConfig(self, configType):
if self == self.iface.localNode:
onResponse = None
else:
onResponse = self.onResponseRequestSettings
print("Requesting current config from remote node (this can take a while).")
msgIndex = configType.index
if configType.containing_type.full_name == "LocalConfig":
p = admin_pb2.AdminMessage()
p.get_config_request = msgIndex
self._sendAdmin(p, wantResponse=True, onResponse=onResponse)
else:
p = admin_pb2.AdminMessage()
p.get_module_config_request = msgIndex
self._sendAdmin(p, wantResponse=True, onResponse=onResponse)
if onResponse:
self.iface.waitForAckNak()
def turnOffEncryptionOnPrimaryChannel(self): def turnOffEncryptionOnPrimaryChannel(self):
"""Turn off encryption on primary channel.""" """Turn off encryption on primary channel."""
@@ -181,6 +229,20 @@ class Node:
logging.debug("Wrote module: canned_message") logging.debug("Wrote module: canned_message")
time.sleep(0.3) time.sleep(0.3)
if self.moduleConfig.audio:
p = admin_pb2.AdminMessage()
p.set_module_config.audio.CopyFrom(self.moduleConfig.audio)
self._sendAdmin(p)
logging.debug("Wrote module: audio")
time.sleep(0.3)
if self.moduleConfig.remote_hardware:
p = admin_pb2.AdminMessage()
p.set_module_config.remote_hardware.CopyFrom(self.moduleConfig.remote_hardware)
self._sendAdmin(p)
logging.debug("Wrote module: remote_hardware")
time.sleep(0.3)
def writeConfig(self, config_name): def writeConfig(self, config_name):
"""Write the current (edited) localConfig to the device""" """Write the current (edited) localConfig to the device"""
if self.localConfig is None: if self.localConfig is None:
@@ -216,11 +278,19 @@ class Node:
p.set_module_config.telemetry.CopyFrom(self.moduleConfig.telemetry) p.set_module_config.telemetry.CopyFrom(self.moduleConfig.telemetry)
elif config_name == 'canned_message': elif config_name == 'canned_message':
p.set_module_config.canned_message.CopyFrom(self.moduleConfig.canned_message) p.set_module_config.canned_message.CopyFrom(self.moduleConfig.canned_message)
elif config_name == 'audio':
p.set_module_config.audio.CopyFrom(self.moduleConfig.audio)
elif config_name == 'remote_hardware':
p.set_module_config.remote_hardware.CopyFrom(self.moduleConfig.remote_hardware)
else: else:
our_exit(f"Error: No valid config with name {config_name}") our_exit(f"Error: No valid config with name {config_name}")
logging.debug(f"Wrote: {config_name}") logging.debug(f"Wrote: {config_name}")
self._sendAdmin(p) if self == self.iface.localNode:
onResponse = None
else:
onResponse = self.onAckNak
self._sendAdmin(p, onResponse=onResponse)
def writeChannel(self, channelIndex, adminIndex=0): def writeChannel(self, channelIndex, adminIndex=0):
"""Write the current (edited) channel to the device""" """Write the current (edited) channel to the device"""
@@ -290,38 +360,30 @@ class Node:
def setOwner(self, long_name=None, short_name=None, is_licensed=False): def setOwner(self, long_name=None, short_name=None, is_licensed=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}")
nChars = 3
minChars = 2
if long_name is not None:
long_name = long_name.strip()
if short_name is None:
words = long_name.split()
if len(long_name) <= nChars:
short_name = long_name
elif len(words) >= minChars:
short_name = ''.join(map(lambda word: word[0], words))
else:
trans = str.maketrans(dict.fromkeys('aeiouAEIOU'))
short_name = long_name[0] + long_name[1:].translate(trans)
if len(short_name) < nChars:
short_name = long_name[:nChars]
p = admin_pb2.AdminMessage() p = admin_pb2.AdminMessage()
nChars = 4
if long_name is not None: if long_name is not None:
long_name = long_name.strip()
p.set_owner.long_name = long_name p.set_owner.long_name = long_name
p.set_owner.is_licensed = is_licensed
if short_name is not None: if short_name is not None:
short_name = short_name.strip() short_name = short_name.strip()
if len(short_name) > nChars: if len(short_name) > nChars:
short_name = short_name[:nChars] short_name = short_name[:nChars]
print(f"Maximum is 4 characters, truncated to {short_name}")
p.set_owner.short_name = short_name p.set_owner.short_name = short_name
p.set_owner.is_licensed = is_licensed
# Note: These debug lines are used in unit tests # Note: These debug lines are used in unit tests
logging.debug(f'p.set_owner.long_name:{p.set_owner.long_name}:') logging.debug(f'p.set_owner.long_name:{p.set_owner.long_name}:')
logging.debug(f'p.set_owner.short_name:{p.set_owner.short_name}:') logging.debug(f'p.set_owner.short_name:{p.set_owner.short_name}:')
logging.debug(f'p.set_owner.is_licensed:{p.set_owner.is_licensed}') logging.debug(f'p.set_owner.is_licensed:{p.set_owner.is_licensed}')
return self._sendAdmin(p) # If sending to a remote node, wait for ACK/NAK
if self == self.iface.localNode:
onResponse = None
else:
onResponse = self.onAckNak
return self._sendAdmin(p, onResponse=onResponse)
def getURL(self, includeAll: bool = True): def getURL(self, includeAll: bool = True):
"""The sharable URL that describes the current channel""" """The sharable URL that describes the current channel"""
@@ -378,6 +440,73 @@ class Node:
p.set_config.lora.CopyFrom(channelSet.lora_config) p.set_config.lora.CopyFrom(channelSet.lora_config)
self._sendAdmin(p) self._sendAdmin(p)
def onResponseRequestRingtone(self, p):
"""Handle the response packet for requesting ringtone part 1"""
logging.debug(f'onResponseRequestRingtone() p:{p}')
errorFound = False
if "routing" in p["decoded"]:
if p["decoded"]["routing"]["errorReason"] != "NONE":
errorFound = True
print(f'Error on response: {p["decoded"]["routing"]["errorReason"]}')
if errorFound is False:
if "decoded" in p:
if "admin" in p["decoded"]:
if "raw" in p["decoded"]["admin"]:
self.ringtonePart = p["decoded"]["admin"]["raw"].get_ringtone_response
logging.debug(f'self.ringtonePart:{self.ringtonePart}')
self.gotResponse = True
def get_ringtone(self):
"""Get the ringtone. Concatenate all pieces together and return a single string."""
logging.debug(f'in get_ringtone()')
if not self.ringtone:
p1 = admin_pb2.AdminMessage()
p1.get_ringtone_request = True
self.gotResponse = False
self._sendAdmin(p1, wantResponse=True, onResponse=self.onResponseRequestRingtone)
while self.gotResponse is False:
time.sleep(0.1)
logging.debug(f'self.ringtone:{self.ringtone}')
self.ringtone = ""
if self.ringtonePart:
self.ringtone += self.ringtonePart
print(f'ringtone:{self.ringtone}')
logging.debug(f'ringtone:{self.ringtone}')
return self.ringtone
def set_ringtone(self, ringtone):
"""Set the ringtone. The ringtone length must be less than 230 character."""
if len(ringtone) > 230:
our_exit("Warning: The ringtone must be less than 230 characters.")
# split into chunks
chunks = []
chunks_size = 230
for i in range(0, len(ringtone), chunks_size):
chunks.append(ringtone[i: i + chunks_size])
# for each chunk, send a message to set the values
#for i in range(0, len(chunks)):
for i, chunk in enumerate(chunks):
p = admin_pb2.AdminMessage()
# TODO: should be a way to improve this
if i == 0:
p.set_ringtone_message = chunk
logging.debug(f"Setting ringtone '{chunk}' part {i+1}")
# If sending to a remote node, wait for ACK/NAK
if self == self.iface.localNode:
onResponse = None
else:
onResponse = self.onAckNak
return self._sendAdmin(p, onResponse=onResponse)
def onResponseRequestCannedMessagePluginMessageMessages(self, p): def onResponseRequestCannedMessagePluginMessageMessages(self, p):
"""Handle the response packet for requesting canned message plugin message part 1""" """Handle the response packet for requesting canned message plugin message part 1"""
logging.debug(f'onResponseRequestCannedMessagePluginMessageMessages() p:{p}') logging.debug(f'onResponseRequestCannedMessagePluginMessageMessages() p:{p}')
@@ -439,7 +568,12 @@ class Node:
p.set_canned_message_module_messages = chunk p.set_canned_message_module_messages = chunk
logging.debug(f"Setting canned message '{chunk}' part {i+1}") logging.debug(f"Setting canned message '{chunk}' part {i+1}")
self._sendAdmin(p) # If sending to a remote node, wait for ACK/NAK
if self == self.iface.localNode:
onResponse = None
else:
onResponse = self.onAckNak
return self._sendAdmin(p, onResponse=onResponse)
def exitSimulator(self): def exitSimulator(self):
"""Tell a simulator node to exit (this message """Tell a simulator node to exit (this message
@@ -456,7 +590,38 @@ class Node:
p.reboot_seconds = secs p.reboot_seconds = secs
logging.info(f"Telling node to reboot in {secs} seconds") logging.info(f"Telling node to reboot in {secs} seconds")
return self._sendAdmin(p) # If sending to a remote node, wait for ACK/NAK
if self == self.iface.localNode:
onResponse = None
else:
onResponse = self.onAckNak
return self._sendAdmin(p, onResponse=onResponse)
def beginSettingsTransaction(self):
"""Tell the node to open a transaction to edit settings."""
p = admin_pb2.AdminMessage()
p.begin_edit_settings = True
logging.info(f"Telling open a transaction to edit settings")
# If sending to a remote node, wait for ACK/NAK
if self == self.iface.localNode:
onResponse = None
else:
onResponse = self.onAckNak
return self._sendAdmin(p, onResponse=onResponse)
def commitSettingsTransaction(self):
"""Tell the node to commit the open transaction for editing settings."""
p = admin_pb2.AdminMessage()
p.commit_edit_settings = True
logging.info(f"Telling node to commit open transaction for editing settings")
# If sending to a remote node, wait for ACK/NAK
if self == self.iface.localNode:
onResponse = None
else:
onResponse = self.onAckNak
return self._sendAdmin(p, onResponse=onResponse)
def rebootOTA(self, secs: int = 10): def rebootOTA(self, secs: int = 10):
"""Tell the node to reboot into factory firmware.""" """Tell the node to reboot into factory firmware."""
@@ -464,7 +629,12 @@ class Node:
p.reboot_ota_seconds = secs p.reboot_ota_seconds = secs
logging.info(f"Telling node to reboot to OTA in {secs} seconds") logging.info(f"Telling node to reboot to OTA in {secs} seconds")
return self._sendAdmin(p) # If sending to a remote node, wait for ACK/NAK
if self == self.iface.localNode:
onResponse = None
else:
onResponse = self.onAckNak
return self._sendAdmin(p, onResponse=onResponse)
def shutdown(self, secs: int = 10): def shutdown(self, secs: int = 10):
"""Tell the node to shutdown.""" """Tell the node to shutdown."""
@@ -472,10 +642,15 @@ class Node:
p.shutdown_seconds = secs p.shutdown_seconds = secs
logging.info(f"Telling node to shutdown in {secs} seconds") logging.info(f"Telling node to shutdown in {secs} seconds")
return self._sendAdmin(p) # If sending to a remote node, wait for ACK/NAK
if self == self.iface.localNode:
onResponse = None
else:
onResponse = self.onAckNak
return self._sendAdmin(p, onResponse=onResponse)
def getMetadata(self, secs: int = 10): def getMetadata(self):
"""Tell the node to shutdown.""" """Get the node's metadata."""
p = admin_pb2.AdminMessage() p = admin_pb2.AdminMessage()
p.get_device_metadata_request = True p.get_device_metadata_request = True
logging.info(f"Requesting device metadata") logging.info(f"Requesting device metadata")
@@ -488,7 +663,12 @@ class Node:
p.factory_reset = True p.factory_reset = True
logging.info(f"Telling node to factory reset") logging.info(f"Telling node to factory reset")
return self._sendAdmin(p) # If sending to a remote node, wait for ACK/NAK
if self == self.iface.localNode:
onResponse = None
else:
onResponse = self.onAckNak
return self._sendAdmin(p, onResponse=onResponse)
def resetNodeDb(self): def resetNodeDb(self):
"""Tell the node to reset its list of nodes.""" """Tell the node to reset its list of nodes."""
@@ -496,7 +676,12 @@ class Node:
p.nodedb_reset = True p.nodedb_reset = True
logging.info(f"Telling node to reset the NodeDB") logging.info(f"Telling node to reset the NodeDB")
return self._sendAdmin(p) # If sending to a remote node, wait for ACK/NAK
if self == self.iface.localNode:
onResponse = None
else:
onResponse = self.onAckNak
return self._sendAdmin(p, onResponse=onResponse)
def _fixupChannels(self): def _fixupChannels(self):
"""Fixup indexes and add disabled channels as needed""" """Fixup indexes and add disabled channels as needed"""
@@ -551,7 +736,7 @@ class Node:
return # Don't try to parse this routing message return # Don't try to parse this routing message
lastTried = 0 lastTried = 0
if len(self.partialChannels) > 0: if len(self.partialChannels) > 0:
lastTried = self.partialChannels[-1] lastTried = self.partialChannels[-1].index
logging.debug(f"Retrying previous channel request.") logging.debug(f"Retrying previous channel request.")
self._requestChannel(lastTried) self._requestChannel(lastTried)
return return
@@ -580,6 +765,18 @@ class Node:
else: else:
self._requestChannel(index + 1) self._requestChannel(index + 1)
def onAckNak(self, p):
if p["decoded"]["routing"]["errorReason"] != "NONE":
print(f'Received a NAK, error reason: {p["decoded"]["routing"]["errorReason"]}')
self.iface._acknowledgment.receivedNak = True
else:
if int(p["from"]) == self.iface.localNode.nodeNum:
print(f'Received an implicit ACK. Packet will likely arrive, but cannot be guaranteed.')
self.iface._acknowledgment.receivedImplAck = True
else:
print(f'Received an ACK.')
self.iface._acknowledgment.receivedAck = True
def _requestChannel(self, channelNum: int): def _requestChannel(self, channelNum: int):
"""Done with initial config messages, now send regular """Done with initial config messages, now send regular
MeshPackets to ask for settings""" MeshPackets to ask for settings"""
@@ -597,7 +794,7 @@ class Node:
# pylint: disable=R1710 # pylint: disable=R1710
def _sendAdmin(self, p: admin_pb2.AdminMessage, wantResponse=False, def _sendAdmin(self, p: admin_pb2.AdminMessage, wantResponse=True,
onResponse=None, adminIndex=0): onResponse=None, adminIndex=0):
"""Send an admin message to the specified node (or the local node if destNodeNum is zero)""" """Send an admin message to the specified node (or the local node if destNodeNum is zero)"""
@@ -607,10 +804,10 @@ class Node:
if adminIndex == 0: # unless a special channel index was used, we want to use the admin index if adminIndex == 0: # unless a special channel index was used, we want to use the admin index
adminIndex = self.iface.localNode._getAdminChannelIndex() adminIndex = self.iface.localNode._getAdminChannelIndex()
logging.debug(f'adminIndex:{adminIndex}') logging.debug(f'adminIndex:{adminIndex}')
return self.iface.sendData(p, self.nodeNum, return self.iface.sendData(p, self.nodeNum,
portNum=portnums_pb2.PortNum.ADMIN_APP, portNum=portnums_pb2.PortNum.ADMIN_APP,
wantAck=True, wantAck=False,
wantResponse=wantResponse, wantResponse=wantResponse,
onResponse=onResponse, onResponse=onResponse,
channelIndex=adminIndex) channelIndex=adminIndex)

View File

@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Generated by the protocol buffer compiler. DO NOT EDIT! # Generated by the protocol buffer compiler. DO NOT EDIT!
# source: portnums.proto # source: meshtastic/portnums.proto
"""Generated protocol buffer code.""" """Generated protocol buffer code."""
from google.protobuf.internal import enum_type_wrapper from google.protobuf.internal import enum_type_wrapper
from google.protobuf import descriptor as _descriptor from google.protobuf import descriptor as _descriptor
@@ -15,7 +15,7 @@ _sym_db = _symbol_database.Default()
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x0eportnums.proto*\x81\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\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\x10\n\x0bPRIVATE_APP\x10\x80\x02\x12\x13\n\x0e\x41TAK_FORWARDER\x10\x81\x02\x12\x08\n\x03MAX\x10\xff\x03\x42\x45\n\x13\x63om.geeksville.meshB\x08PortnumsH\x03Z\"github.com/meshtastic/go/generatedb\x06proto3') 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')
_PORTNUM = DESCRIPTOR.enum_types_by_name['PortNum'] _PORTNUM = DESCRIPTOR.enum_types_by_name['PortNum']
PortNum = enum_type_wrapper.EnumTypeWrapper(_PORTNUM) PortNum = enum_type_wrapper.EnumTypeWrapper(_PORTNUM)
@@ -28,6 +28,7 @@ ROUTING_APP = 5
ADMIN_APP = 6 ADMIN_APP = 6
TEXT_MESSAGE_COMPRESSED_APP = 7 TEXT_MESSAGE_COMPRESSED_APP = 7
WAYPOINT_APP = 8 WAYPOINT_APP = 8
AUDIO_APP = 9
REPLY_APP = 32 REPLY_APP = 32
IP_TUNNEL_APP = 33 IP_TUNNEL_APP = 33
SERIAL_APP = 64 SERIAL_APP = 64
@@ -36,6 +37,7 @@ RANGE_TEST_APP = 66
TELEMETRY_APP = 67 TELEMETRY_APP = 67
ZPS_APP = 68 ZPS_APP = 68
SIMULATOR_APP = 69 SIMULATOR_APP = 69
TRACEROUTE_APP = 70
PRIVATE_APP = 256 PRIVATE_APP = 256
ATAK_FORWARDER = 257 ATAK_FORWARDER = 257
MAX = 511 MAX = 511
@@ -44,7 +46,7 @@ MAX = 511
if _descriptor._USE_C_DESCRIPTORS == False: if _descriptor._USE_C_DESCRIPTORS == False:
DESCRIPTOR._options = None DESCRIPTOR._options = None
DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\010PortnumsH\003Z\"github.com/meshtastic/go/generated' DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\010PortnumsZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000'
_PORTNUM._serialized_start=19 _PORTNUM._serialized_start=30
_PORTNUM._serialized_end=404 _PORTNUM._serialized_end=450
# @@protoc_insertion_point(module_scope) # @@protoc_insertion_point(module_scope)

View File

@@ -23,7 +23,7 @@ def onGPIOreceive(packet, interface):
#print(f'mask:{interface.mask}') #print(f'mask:{interface.mask}')
value = int(gpioValue) & int(interface.mask) value = int(gpioValue) & int(interface.mask)
print(f'Received RemoteHardware typ={hw["typ"]}, gpio_value={gpioValue} value={value}') print(f'Received RemoteHardware type={hw["type"]}, gpio_value={gpioValue} value={value}')
interface.gotResponse = True interface.gotResponse = True
@@ -66,7 +66,7 @@ class RemoteHardwareClient:
""" """
logging.debug(f'writeGPIOs nodeid:{nodeid} mask:{mask} vals:{vals}') logging.debug(f'writeGPIOs nodeid:{nodeid} mask:{mask} vals:{vals}')
r = remote_hardware_pb2.HardwareMessage() r = remote_hardware_pb2.HardwareMessage()
r.typ = remote_hardware_pb2.HardwareMessage.Type.WRITE_GPIOS r.type = remote_hardware_pb2.HardwareMessage.Type.WRITE_GPIOS
r.gpio_mask = mask r.gpio_mask = mask
r.gpio_value = vals r.gpio_value = vals
return self._sendHardware(nodeid, r) return self._sendHardware(nodeid, r)
@@ -75,7 +75,7 @@ class RemoteHardwareClient:
"""Read the specified bits from GPIO inputs on the device""" """Read the specified bits from GPIO inputs on the device"""
logging.debug(f'readGPIOs nodeid:{nodeid} mask:{mask}') logging.debug(f'readGPIOs nodeid:{nodeid} mask:{mask}')
r = remote_hardware_pb2.HardwareMessage() r = remote_hardware_pb2.HardwareMessage()
r.typ = remote_hardware_pb2.HardwareMessage.Type.READ_GPIOS r.type = remote_hardware_pb2.HardwareMessage.Type.READ_GPIOS
r.gpio_mask = mask r.gpio_mask = mask
return self._sendHardware(nodeid, r, wantResponse=True, onResponse=onResponse) return self._sendHardware(nodeid, r, wantResponse=True, onResponse=onResponse)
@@ -83,7 +83,7 @@ class RemoteHardwareClient:
"""Watch the specified bits from GPIO inputs on the device for changes""" """Watch the specified bits from GPIO inputs on the device for changes"""
logging.debug(f'watchGPIOs nodeid:{nodeid} mask:{mask}') logging.debug(f'watchGPIOs nodeid:{nodeid} mask:{mask}')
r = remote_hardware_pb2.HardwareMessage() r = remote_hardware_pb2.HardwareMessage()
r.typ = remote_hardware_pb2.HardwareMessage.Type.WATCH_GPIOS r.type = remote_hardware_pb2.HardwareMessage.Type.WATCH_GPIOS
r.gpio_mask = mask r.gpio_mask = mask
self.iface.mask = mask self.iface.mask = mask
return self._sendHardware(nodeid, r) return self._sendHardware(nodeid, r)

View File

@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Generated by the protocol buffer compiler. DO NOT EDIT! # Generated by the protocol buffer compiler. DO NOT EDIT!
# source: remote_hardware.proto # source: meshtastic/remote_hardware.proto
"""Generated protocol buffer code.""" """Generated protocol buffer code."""
from google.protobuf import descriptor as _descriptor from google.protobuf import descriptor as _descriptor
from google.protobuf import descriptor_pool as _descriptor_pool from google.protobuf import descriptor_pool as _descriptor_pool
@@ -14,7 +14,7 @@ _sym_db = _symbol_database.Default()
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x15remote_hardware.proto\"\xcb\x01\n\x0fHardwareMessage\x12#\n\x04type\x18\x01 \x01(\x0e\x32\x15.HardwareMessage.Type\x12\x11\n\tgpio_mask\x18\x02 \x01(\x04\x12\x12\n\ngpio_value\x18\x03 \x01(\x04\"l\n\x04Type\x12\t\n\x05UNSET\x10\x00\x12\x0f\n\x0bWRITE_GPIOS\x10\x01\x12\x0f\n\x0bWATCH_GPIOS\x10\x02\x12\x11\n\rGPIOS_CHANGED\x10\x03\x12\x0e\n\nREAD_GPIOS\x10\x04\x12\x14\n\x10READ_GPIOS_REPLY\x10\x05\x42K\n\x13\x63om.geeksville.meshB\x0eRemoteHardwareH\x03Z\"github.com/meshtastic/go/generatedb\x06proto3') DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n meshtastic/remote_hardware.proto\"\xcb\x01\n\x0fHardwareMessage\x12#\n\x04type\x18\x01 \x01(\x0e\x32\x15.HardwareMessage.Type\x12\x11\n\tgpio_mask\x18\x02 \x01(\x04\x12\x12\n\ngpio_value\x18\x03 \x01(\x04\"l\n\x04Type\x12\t\n\x05UNSET\x10\x00\x12\x0f\n\x0bWRITE_GPIOS\x10\x01\x12\x0f\n\x0bWATCH_GPIOS\x10\x02\x12\x11\n\rGPIOS_CHANGED\x10\x03\x12\x0e\n\nREAD_GPIOS\x10\x04\x12\x14\n\x10READ_GPIOS_REPLY\x10\x05\x42\x63\n\x13\x63om.geeksville.meshB\x0eRemoteHardwareZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3')
@@ -22,7 +22,7 @@ _HARDWAREMESSAGE = DESCRIPTOR.message_types_by_name['HardwareMessage']
_HARDWAREMESSAGE_TYPE = _HARDWAREMESSAGE.enum_types_by_name['Type'] _HARDWAREMESSAGE_TYPE = _HARDWAREMESSAGE.enum_types_by_name['Type']
HardwareMessage = _reflection.GeneratedProtocolMessageType('HardwareMessage', (_message.Message,), { HardwareMessage = _reflection.GeneratedProtocolMessageType('HardwareMessage', (_message.Message,), {
'DESCRIPTOR' : _HARDWAREMESSAGE, 'DESCRIPTOR' : _HARDWAREMESSAGE,
'__module__' : 'remote_hardware_pb2' '__module__' : 'meshtastic.remote_hardware_pb2'
# @@protoc_insertion_point(class_scope:HardwareMessage) # @@protoc_insertion_point(class_scope:HardwareMessage)
}) })
_sym_db.RegisterMessage(HardwareMessage) _sym_db.RegisterMessage(HardwareMessage)
@@ -30,9 +30,9 @@ _sym_db.RegisterMessage(HardwareMessage)
if _descriptor._USE_C_DESCRIPTORS == False: if _descriptor._USE_C_DESCRIPTORS == False:
DESCRIPTOR._options = None DESCRIPTOR._options = None
DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\016RemoteHardwareH\003Z\"github.com/meshtastic/go/generated' DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\016RemoteHardwareZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000'
_HARDWAREMESSAGE._serialized_start=26 _HARDWAREMESSAGE._serialized_start=37
_HARDWAREMESSAGE._serialized_end=229 _HARDWAREMESSAGE._serialized_end=240
_HARDWAREMESSAGE_TYPE._serialized_start=121 _HARDWAREMESSAGE_TYPE._serialized_start=132
_HARDWAREMESSAGE_TYPE._serialized_end=229 _HARDWAREMESSAGE_TYPE._serialized_end=240
# @@protoc_insertion_point(module_scope) # @@protoc_insertion_point(module_scope)

35
meshtastic/rtttl_pb2.py Normal file
View File

@@ -0,0 +1,35 @@
# -*- coding: utf-8 -*-
# Generated by the protocol buffer compiler. DO NOT EDIT!
# source: meshtastic/rtttl.proto
"""Generated protocol buffer code."""
from google.protobuf import descriptor as _descriptor
from google.protobuf import descriptor_pool as _descriptor_pool
from google.protobuf import message as _message
from google.protobuf import reflection as _reflection
from google.protobuf import symbol_database as _symbol_database
# @@protoc_insertion_point(imports)
_sym_db = _symbol_database.Default()
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x16meshtastic/rtttl.proto\"\x1f\n\x0bRTTTLConfig\x12\x10\n\x08ringtone\x18\x01 \x01(\tBf\n\x13\x63om.geeksville.meshB\x11RTTTLConfigProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3')
_RTTTLCONFIG = DESCRIPTOR.message_types_by_name['RTTTLConfig']
RTTTLConfig = _reflection.GeneratedProtocolMessageType('RTTTLConfig', (_message.Message,), {
'DESCRIPTOR' : _RTTTLCONFIG,
'__module__' : 'meshtastic.rtttl_pb2'
# @@protoc_insertion_point(class_scope:RTTTLConfig)
})
_sym_db.RegisterMessage(RTTTLConfig)
if _descriptor._USE_C_DESCRIPTORS == False:
DESCRIPTOR._options = None
DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\021RTTTLConfigProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000'
_RTTTLCONFIG._serialized_start=26
_RTTTLCONFIG._serialized_end=57
# @@protoc_insertion_point(module_scope)

View File

@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Generated by the protocol buffer compiler. DO NOT EDIT! # Generated by the protocol buffer compiler. DO NOT EDIT!
# source: storeforward.proto # source: meshtastic/storeforward.proto
"""Generated protocol buffer code.""" """Generated protocol buffer code."""
from google.protobuf import descriptor as _descriptor from google.protobuf import descriptor as _descriptor
from google.protobuf import descriptor_pool as _descriptor_pool from google.protobuf import descriptor_pool as _descriptor_pool
@@ -14,7 +14,7 @@ _sym_db = _symbol_database.Default()
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x12storeforward.proto\"\x8a\x06\n\x0fStoreAndForward\x12,\n\x02rr\x18\x01 \x01(\x0e\x32 .StoreAndForward.RequestResponse\x12*\n\x05stats\x18\x02 \x01(\x0b\x32\x1b.StoreAndForward.Statistics\x12)\n\x07history\x18\x03 \x01(\x0b\x32\x18.StoreAndForward.History\x12-\n\theartbeat\x18\x04 \x01(\x0b\x32\x1a.StoreAndForward.Heartbeat\x1a\xcd\x01\n\nStatistics\x12\x16\n\x0emessages_total\x18\x01 \x01(\r\x12\x16\n\x0emessages_saved\x18\x02 \x01(\r\x12\x14\n\x0cmessages_max\x18\x03 \x01(\r\x12\x0f\n\x07up_time\x18\x04 \x01(\r\x12\x10\n\x08requests\x18\x05 \x01(\r\x12\x18\n\x10requests_history\x18\x06 \x01(\r\x12\x11\n\theartbeat\x18\x07 \x01(\x08\x12\x12\n\nreturn_max\x18\x08 \x01(\r\x12\x15\n\rreturn_window\x18\t \x01(\r\x1aI\n\x07History\x12\x18\n\x10history_messages\x18\x01 \x01(\r\x12\x0e\n\x06window\x18\x02 \x01(\r\x12\x14\n\x0clast_request\x18\x03 \x01(\r\x1a.\n\tHeartbeat\x12\x0e\n\x06period\x18\x01 \x01(\r\x12\x11\n\tsecondary\x18\x02 \x01(\r\"\xf7\x01\n\x0fRequestResponse\x12\t\n\x05UNSET\x10\x00\x12\x10\n\x0cROUTER_ERROR\x10\x01\x12\x14\n\x10ROUTER_HEARTBEAT\x10\x02\x12\x0f\n\x0bROUTER_PING\x10\x03\x12\x0f\n\x0bROUTER_PONG\x10\x04\x12\x0f\n\x0bROUTER_BUSY\x10\x05\x12\x12\n\x0eROUTER_HISTORY\x10\x06\x12\x10\n\x0c\x43LIENT_ERROR\x10\x65\x12\x12\n\x0e\x43LIENT_HISTORY\x10\x66\x12\x10\n\x0c\x43LIENT_STATS\x10g\x12\x0f\n\x0b\x43LIENT_PING\x10h\x12\x0f\n\x0b\x43LIENT_PONG\x10i\x12\x10\n\x0c\x43LIENT_ABORT\x10jBR\n\x13\x63om.geeksville.meshB\x15StoreAndForwardProtosH\x03Z\"github.com/meshtastic/go/generatedb\x06proto3') DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1dmeshtastic/storeforward.proto\"\xbe\x06\n\x0fStoreAndForward\x12,\n\x02rr\x18\x01 \x01(\x0e\x32 .StoreAndForward.RequestResponse\x12,\n\x05stats\x18\x02 \x01(\x0b\x32\x1b.StoreAndForward.StatisticsH\x00\x12+\n\x07history\x18\x03 \x01(\x0b\x32\x18.StoreAndForward.HistoryH\x00\x12/\n\theartbeat\x18\x04 \x01(\x0b\x32\x1a.StoreAndForward.HeartbeatH\x00\x12\x0f\n\x05\x65mpty\x18\x05 \x01(\x08H\x00\x1a\xcd\x01\n\nStatistics\x12\x16\n\x0emessages_total\x18\x01 \x01(\r\x12\x16\n\x0emessages_saved\x18\x02 \x01(\r\x12\x14\n\x0cmessages_max\x18\x03 \x01(\r\x12\x0f\n\x07up_time\x18\x04 \x01(\r\x12\x10\n\x08requests\x18\x05 \x01(\r\x12\x18\n\x10requests_history\x18\x06 \x01(\r\x12\x11\n\theartbeat\x18\x07 \x01(\x08\x12\x12\n\nreturn_max\x18\x08 \x01(\r\x12\x15\n\rreturn_window\x18\t \x01(\r\x1aI\n\x07History\x12\x18\n\x10history_messages\x18\x01 \x01(\r\x12\x0e\n\x06window\x18\x02 \x01(\r\x12\x14\n\x0clast_request\x18\x03 \x01(\r\x1a.\n\tHeartbeat\x12\x0e\n\x06period\x18\x01 \x01(\r\x12\x11\n\tsecondary\x18\x02 \x01(\r\"\x89\x02\n\x0fRequestResponse\x12\t\n\x05UNSET\x10\x00\x12\x10\n\x0cROUTER_ERROR\x10\x01\x12\x14\n\x10ROUTER_HEARTBEAT\x10\x02\x12\x0f\n\x0bROUTER_PING\x10\x03\x12\x0f\n\x0bROUTER_PONG\x10\x04\x12\x0f\n\x0bROUTER_BUSY\x10\x05\x12\x12\n\x0eROUTER_HISTORY\x10\x06\x12\x10\n\x0cROUTER_STATS\x10\x07\x12\x10\n\x0c\x43LIENT_ERROR\x10@\x12\x12\n\x0e\x43LIENT_HISTORY\x10\x41\x12\x10\n\x0c\x43LIENT_STATS\x10\x42\x12\x0f\n\x0b\x43LIENT_PING\x10\x43\x12\x0f\n\x0b\x43LIENT_PONG\x10\x44\x12\x10\n\x0c\x43LIENT_ABORT\x10jB\t\n\x07variantBj\n\x13\x63om.geeksville.meshB\x15StoreAndForwardProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3')
@@ -27,26 +27,26 @@ StoreAndForward = _reflection.GeneratedProtocolMessageType('StoreAndForward', (_
'Statistics' : _reflection.GeneratedProtocolMessageType('Statistics', (_message.Message,), { 'Statistics' : _reflection.GeneratedProtocolMessageType('Statistics', (_message.Message,), {
'DESCRIPTOR' : _STOREANDFORWARD_STATISTICS, 'DESCRIPTOR' : _STOREANDFORWARD_STATISTICS,
'__module__' : 'storeforward_pb2' '__module__' : 'meshtastic.storeforward_pb2'
# @@protoc_insertion_point(class_scope:StoreAndForward.Statistics) # @@protoc_insertion_point(class_scope:StoreAndForward.Statistics)
}) })
, ,
'History' : _reflection.GeneratedProtocolMessageType('History', (_message.Message,), { 'History' : _reflection.GeneratedProtocolMessageType('History', (_message.Message,), {
'DESCRIPTOR' : _STOREANDFORWARD_HISTORY, 'DESCRIPTOR' : _STOREANDFORWARD_HISTORY,
'__module__' : 'storeforward_pb2' '__module__' : 'meshtastic.storeforward_pb2'
# @@protoc_insertion_point(class_scope:StoreAndForward.History) # @@protoc_insertion_point(class_scope:StoreAndForward.History)
}) })
, ,
'Heartbeat' : _reflection.GeneratedProtocolMessageType('Heartbeat', (_message.Message,), { 'Heartbeat' : _reflection.GeneratedProtocolMessageType('Heartbeat', (_message.Message,), {
'DESCRIPTOR' : _STOREANDFORWARD_HEARTBEAT, 'DESCRIPTOR' : _STOREANDFORWARD_HEARTBEAT,
'__module__' : 'storeforward_pb2' '__module__' : 'meshtastic.storeforward_pb2'
# @@protoc_insertion_point(class_scope:StoreAndForward.Heartbeat) # @@protoc_insertion_point(class_scope:StoreAndForward.Heartbeat)
}) })
, ,
'DESCRIPTOR' : _STOREANDFORWARD, 'DESCRIPTOR' : _STOREANDFORWARD,
'__module__' : 'storeforward_pb2' '__module__' : 'meshtastic.storeforward_pb2'
# @@protoc_insertion_point(class_scope:StoreAndForward) # @@protoc_insertion_point(class_scope:StoreAndForward)
}) })
_sym_db.RegisterMessage(StoreAndForward) _sym_db.RegisterMessage(StoreAndForward)
@@ -57,15 +57,15 @@ _sym_db.RegisterMessage(StoreAndForward.Heartbeat)
if _descriptor._USE_C_DESCRIPTORS == False: if _descriptor._USE_C_DESCRIPTORS == False:
DESCRIPTOR._options = None DESCRIPTOR._options = None
DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\025StoreAndForwardProtosH\003Z\"github.com/meshtastic/go/generated' DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\025StoreAndForwardProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000'
_STOREANDFORWARD._serialized_start=23 _STOREANDFORWARD._serialized_start=34
_STOREANDFORWARD._serialized_end=801 _STOREANDFORWARD._serialized_end=864
_STOREANDFORWARD_STATISTICS._serialized_start=223 _STOREANDFORWARD_STATISTICS._serialized_start=257
_STOREANDFORWARD_STATISTICS._serialized_end=428 _STOREANDFORWARD_STATISTICS._serialized_end=462
_STOREANDFORWARD_HISTORY._serialized_start=430 _STOREANDFORWARD_HISTORY._serialized_start=464
_STOREANDFORWARD_HISTORY._serialized_end=503 _STOREANDFORWARD_HISTORY._serialized_end=537
_STOREANDFORWARD_HEARTBEAT._serialized_start=505 _STOREANDFORWARD_HEARTBEAT._serialized_start=539
_STOREANDFORWARD_HEARTBEAT._serialized_end=551 _STOREANDFORWARD_HEARTBEAT._serialized_end=585
_STOREANDFORWARD_REQUESTRESPONSE._serialized_start=554 _STOREANDFORWARD_REQUESTRESPONSE._serialized_start=588
_STOREANDFORWARD_REQUESTRESPONSE._serialized_end=801 _STOREANDFORWARD_REQUESTRESPONSE._serialized_end=853
# @@protoc_insertion_point(module_scope) # @@protoc_insertion_point(module_scope)

View File

@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Generated by the protocol buffer compiler. DO NOT EDIT! # Generated by the protocol buffer compiler. DO NOT EDIT!
# source: telemetry.proto # source: meshtastic/telemetry.proto
"""Generated protocol buffer code.""" """Generated protocol buffer code."""
from google.protobuf.internal import enum_type_wrapper from google.protobuf.internal import enum_type_wrapper
from google.protobuf import descriptor as _descriptor from google.protobuf import descriptor as _descriptor
@@ -15,7 +15,7 @@ _sym_db = _symbol_database.Default()
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x0ftelemetry.proto\"i\n\rDeviceMetrics\x12\x15\n\rbattery_level\x18\x01 \x01(\r\x12\x0f\n\x07voltage\x18\x02 \x01(\x02\x12\x1b\n\x13\x63hannel_utilization\x18\x03 \x01(\x02\x12\x13\n\x0b\x61ir_util_tx\x18\x04 \x01(\x02\"\x9b\x01\n\x12\x45nvironmentMetrics\x12\x13\n\x0btemperature\x18\x01 \x01(\x02\x12\x19\n\x11relative_humidity\x18\x02 \x01(\x02\x12\x1b\n\x13\x62\x61rometric_pressure\x18\x03 \x01(\x02\x12\x16\n\x0egas_resistance\x18\x04 \x01(\x02\x12\x0f\n\x07voltage\x18\x05 \x01(\x02\x12\x0f\n\x07\x63urrent\x18\x06 \x01(\x02\"\x82\x01\n\tTelemetry\x12\x0c\n\x04time\x18\x01 \x01(\x07\x12(\n\x0e\x64\x65vice_metrics\x18\x02 \x01(\x0b\x32\x0e.DeviceMetricsH\x00\x12\x32\n\x13\x65nvironment_metrics\x18\x03 \x01(\x0b\x32\x13.EnvironmentMetricsH\x00\x42\t\n\x07variant*\xa0\x01\n\x13TelemetrySensorType\x12\x10\n\x0cSENSOR_UNSET\x10\x00\x12\n\n\x06\x42ME280\x10\x01\x12\n\n\x06\x42ME680\x10\x02\x12\x0b\n\x07MCP9808\x10\x03\x12\n\n\x06INA260\x10\x04\x12\n\n\x06INA219\x10\x05\x12\n\n\x06\x42MP280\x10\x06\x12\t\n\x05SHTC3\x10\x07\x12\t\n\x05LPS22\x10\x08\x12\x0b\n\x07QMC6310\x10\t\x12\x0b\n\x07QMI8658\x10\nBL\n\x13\x63om.geeksville.meshB\x0fTelemetryProtosH\x03Z\"github.com/meshtastic/go/generatedb\x06proto3') DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1ameshtastic/telemetry.proto\"i\n\rDeviceMetrics\x12\x15\n\rbattery_level\x18\x01 \x01(\r\x12\x0f\n\x07voltage\x18\x02 \x01(\x02\x12\x1b\n\x13\x63hannel_utilization\x18\x03 \x01(\x02\x12\x13\n\x0b\x61ir_util_tx\x18\x04 \x01(\x02\"\x9b\x01\n\x12\x45nvironmentMetrics\x12\x13\n\x0btemperature\x18\x01 \x01(\x02\x12\x19\n\x11relative_humidity\x18\x02 \x01(\x02\x12\x1b\n\x13\x62\x61rometric_pressure\x18\x03 \x01(\x02\x12\x16\n\x0egas_resistance\x18\x04 \x01(\x02\x12\x0f\n\x07voltage\x18\x05 \x01(\x02\x12\x0f\n\x07\x63urrent\x18\x06 \x01(\x02\"\xbf\x02\n\x11\x41irQualityMetrics\x12\x15\n\rpm10_standard\x18\x01 \x01(\r\x12\x15\n\rpm25_standard\x18\x02 \x01(\r\x12\x16\n\x0epm100_standard\x18\x03 \x01(\r\x12\x1a\n\x12pm10_environmental\x18\x04 \x01(\r\x12\x1a\n\x12pm25_environmental\x18\x05 \x01(\r\x12\x1b\n\x13pm100_environmental\x18\x06 \x01(\r\x12\x16\n\x0eparticles_03um\x18\x07 \x01(\r\x12\x16\n\x0eparticles_05um\x18\x08 \x01(\r\x12\x16\n\x0eparticles_10um\x18\t \x01(\r\x12\x16\n\x0eparticles_25um\x18\n \x01(\r\x12\x16\n\x0eparticles_50um\x18\x0b \x01(\r\x12\x17\n\x0fparticles_100um\x18\x0c \x01(\r\"\xb5\x01\n\tTelemetry\x12\x0c\n\x04time\x18\x01 \x01(\x07\x12(\n\x0e\x64\x65vice_metrics\x18\x02 \x01(\x0b\x32\x0e.DeviceMetricsH\x00\x12\x32\n\x13\x65nvironment_metrics\x18\x03 \x01(\x0b\x32\x13.EnvironmentMetricsH\x00\x12\x31\n\x13\x61ir_quality_metrics\x18\x04 \x01(\x0b\x32\x12.AirQualityMetricsH\x00\x42\t\n\x07variant*\xc7\x01\n\x13TelemetrySensorType\x12\x10\n\x0cSENSOR_UNSET\x10\x00\x12\n\n\x06\x42ME280\x10\x01\x12\n\n\x06\x42ME680\x10\x02\x12\x0b\n\x07MCP9808\x10\x03\x12\n\n\x06INA260\x10\x04\x12\n\n\x06INA219\x10\x05\x12\n\n\x06\x42MP280\x10\x06\x12\t\n\x05SHTC3\x10\x07\x12\t\n\x05LPS22\x10\x08\x12\x0b\n\x07QMC6310\x10\t\x12\x0b\n\x07QMI8658\x10\n\x12\x0c\n\x08QMC5883L\x10\x0b\x12\t\n\x05SHT31\x10\x0c\x12\x0c\n\x08PMSA003I\x10\rBd\n\x13\x63om.geeksville.meshB\x0fTelemetryProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3')
_TELEMETRYSENSORTYPE = DESCRIPTOR.enum_types_by_name['TelemetrySensorType'] _TELEMETRYSENSORTYPE = DESCRIPTOR.enum_types_by_name['TelemetrySensorType']
TelemetrySensorType = enum_type_wrapper.EnumTypeWrapper(_TELEMETRYSENSORTYPE) TelemetrySensorType = enum_type_wrapper.EnumTypeWrapper(_TELEMETRYSENSORTYPE)
@@ -30,28 +30,39 @@ SHTC3 = 7
LPS22 = 8 LPS22 = 8
QMC6310 = 9 QMC6310 = 9
QMI8658 = 10 QMI8658 = 10
QMC5883L = 11
SHT31 = 12
PMSA003I = 13
_DEVICEMETRICS = DESCRIPTOR.message_types_by_name['DeviceMetrics'] _DEVICEMETRICS = DESCRIPTOR.message_types_by_name['DeviceMetrics']
_ENVIRONMENTMETRICS = DESCRIPTOR.message_types_by_name['EnvironmentMetrics'] _ENVIRONMENTMETRICS = DESCRIPTOR.message_types_by_name['EnvironmentMetrics']
_AIRQUALITYMETRICS = DESCRIPTOR.message_types_by_name['AirQualityMetrics']
_TELEMETRY = DESCRIPTOR.message_types_by_name['Telemetry'] _TELEMETRY = DESCRIPTOR.message_types_by_name['Telemetry']
DeviceMetrics = _reflection.GeneratedProtocolMessageType('DeviceMetrics', (_message.Message,), { DeviceMetrics = _reflection.GeneratedProtocolMessageType('DeviceMetrics', (_message.Message,), {
'DESCRIPTOR' : _DEVICEMETRICS, 'DESCRIPTOR' : _DEVICEMETRICS,
'__module__' : 'telemetry_pb2' '__module__' : 'meshtastic.telemetry_pb2'
# @@protoc_insertion_point(class_scope:DeviceMetrics) # @@protoc_insertion_point(class_scope:DeviceMetrics)
}) })
_sym_db.RegisterMessage(DeviceMetrics) _sym_db.RegisterMessage(DeviceMetrics)
EnvironmentMetrics = _reflection.GeneratedProtocolMessageType('EnvironmentMetrics', (_message.Message,), { EnvironmentMetrics = _reflection.GeneratedProtocolMessageType('EnvironmentMetrics', (_message.Message,), {
'DESCRIPTOR' : _ENVIRONMENTMETRICS, 'DESCRIPTOR' : _ENVIRONMENTMETRICS,
'__module__' : 'telemetry_pb2' '__module__' : 'meshtastic.telemetry_pb2'
# @@protoc_insertion_point(class_scope:EnvironmentMetrics) # @@protoc_insertion_point(class_scope:EnvironmentMetrics)
}) })
_sym_db.RegisterMessage(EnvironmentMetrics) _sym_db.RegisterMessage(EnvironmentMetrics)
AirQualityMetrics = _reflection.GeneratedProtocolMessageType('AirQualityMetrics', (_message.Message,), {
'DESCRIPTOR' : _AIRQUALITYMETRICS,
'__module__' : 'meshtastic.telemetry_pb2'
# @@protoc_insertion_point(class_scope:AirQualityMetrics)
})
_sym_db.RegisterMessage(AirQualityMetrics)
Telemetry = _reflection.GeneratedProtocolMessageType('Telemetry', (_message.Message,), { Telemetry = _reflection.GeneratedProtocolMessageType('Telemetry', (_message.Message,), {
'DESCRIPTOR' : _TELEMETRY, 'DESCRIPTOR' : _TELEMETRY,
'__module__' : 'telemetry_pb2' '__module__' : 'meshtastic.telemetry_pb2'
# @@protoc_insertion_point(class_scope:Telemetry) # @@protoc_insertion_point(class_scope:Telemetry)
}) })
_sym_db.RegisterMessage(Telemetry) _sym_db.RegisterMessage(Telemetry)
@@ -59,13 +70,15 @@ _sym_db.RegisterMessage(Telemetry)
if _descriptor._USE_C_DESCRIPTORS == False: if _descriptor._USE_C_DESCRIPTORS == False:
DESCRIPTOR._options = None DESCRIPTOR._options = None
DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\017TelemetryProtosH\003Z\"github.com/meshtastic/go/generated' DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\017TelemetryProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000'
_TELEMETRYSENSORTYPE._serialized_start=418 _TELEMETRYSENSORTYPE._serialized_start=802
_TELEMETRYSENSORTYPE._serialized_end=578 _TELEMETRYSENSORTYPE._serialized_end=1001
_DEVICEMETRICS._serialized_start=19 _DEVICEMETRICS._serialized_start=30
_DEVICEMETRICS._serialized_end=124 _DEVICEMETRICS._serialized_end=135
_ENVIRONMENTMETRICS._serialized_start=127 _ENVIRONMENTMETRICS._serialized_start=138
_ENVIRONMENTMETRICS._serialized_end=282 _ENVIRONMENTMETRICS._serialized_end=293
_TELEMETRY._serialized_start=285 _AIRQUALITYMETRICS._serialized_start=296
_TELEMETRY._serialized_end=415 _AIRQUALITYMETRICS._serialized_end=615
_TELEMETRY._serialized_start=618
_TELEMETRY._serialized_end=799
# @@protoc_insertion_point(module_scope) # @@protoc_insertion_point(module_scope)

View File

@@ -23,7 +23,7 @@ def test_RemoteHardwareClient():
def test_onGPIOreceive(capsys): def test_onGPIOreceive(capsys):
"""Test onGPIOreceive""" """Test onGPIOreceive"""
iface = MagicMock(autospec=SerialInterface) iface = MagicMock(autospec=SerialInterface)
packet = {'decoded': {'remotehw': {'typ': 'foo', 'gpioValue': '4096' }}} packet = {'decoded': {'remotehw': {'type': 'foo', 'gpioValue': '4096' }}}
onGPIOreceive(packet, iface) onGPIOreceive(packet, iface)
out, err = capsys.readouterr() out, err = capsys.readouterr()
assert re.search(r'Received RemoteHardware', out) assert re.search(r'Received RemoteHardware', out)

View File

@@ -159,6 +159,42 @@ class Timeout:
time.sleep(self.sleepInterval) time.sleep(self.sleepInterval)
return False return False
def waitForAckNak(self, acknowledgment, attrs=('receivedAck', 'receivedNak', 'receivedImplAck')):
"""Block until an ACK or NAK has been received. Returns True if ACK or NAK has been received."""
self.reset()
while time.time() < self.expireTime:
if any(map(lambda a: getattr(acknowledgment, a, None), attrs)):
acknowledgment.reset()
return True
time.sleep(self.sleepInterval)
return False
def waitForTraceRoute(self, waitFactor, acknowledgment, attr='receivedTraceRoute'):
"""Block until traceroute response is received. Returns True if traceroute response has been received."""
self.expireTimeout *= waitFactor
self.reset()
while time.time() < self.expireTime:
if getattr(acknowledgment, attr, 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."
def __init__(self):
"""initialize"""
self.receivedAck = False
self.receivedNak = False
self.receivedImplAck = False
self.receivedTraceRoute = False
def reset(self):
"""reset"""
self.receivedAck = False
self.receivedNak = False
self.receivedImplAck = False
self.receivedTraceRoute = False
class DeferredExecution(): class DeferredExecution():
"""A thread that accepts closures to run, and runs them as they are received""" """A thread that accepts closures to run, and runs them as they are received"""

38
meshtastic/xmodem_pb2.py Normal file
View File

@@ -0,0 +1,38 @@
# -*- coding: utf-8 -*-
# Generated by the protocol buffer compiler. DO NOT EDIT!
# source: meshtastic/xmodem.proto
"""Generated protocol buffer code."""
from google.protobuf import descriptor as _descriptor
from google.protobuf import descriptor_pool as _descriptor_pool
from google.protobuf import message as _message
from google.protobuf import reflection as _reflection
from google.protobuf import symbol_database as _symbol_database
# @@protoc_insertion_point(imports)
_sym_db = _symbol_database.Default()
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x17meshtastic/xmodem.proto\"\xab\x01\n\x06XModem\x12 \n\x07\x63ontrol\x18\x01 \x01(\x0e\x32\x0f.XModem.Control\x12\x0b\n\x03seq\x18\x02 \x01(\r\x12\r\n\x05\x63rc16\x18\x03 \x01(\r\x12\x0e\n\x06\x62uffer\x18\x04 \x01(\x0c\"S\n\x07\x43ontrol\x12\x07\n\x03NUL\x10\x00\x12\x07\n\x03SOH\x10\x01\x12\x07\n\x03STX\x10\x02\x12\x07\n\x03\x45OT\x10\x04\x12\x07\n\x03\x41\x43K\x10\x06\x12\x07\n\x03NAK\x10\x15\x12\x07\n\x03\x43\x41N\x10\x18\x12\t\n\x05\x43TRLZ\x10\x1a\x42\x61\n\x13\x63om.geeksville.meshB\x0cXmodemProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3')
_XMODEM = DESCRIPTOR.message_types_by_name['XModem']
_XMODEM_CONTROL = _XMODEM.enum_types_by_name['Control']
XModem = _reflection.GeneratedProtocolMessageType('XModem', (_message.Message,), {
'DESCRIPTOR' : _XMODEM,
'__module__' : 'meshtastic.xmodem_pb2'
# @@protoc_insertion_point(class_scope:XModem)
})
_sym_db.RegisterMessage(XModem)
if _descriptor._USE_C_DESCRIPTORS == False:
DESCRIPTOR._options = None
DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\014XmodemProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000'
_XMODEM._serialized_start=28
_XMODEM._serialized_end=199
_XMODEM_CONTROL._serialized_start=116
_XMODEM_CONTROL._serialized_end=199
# @@protoc_insertion_point(module_scope)

View File

@@ -12,7 +12,7 @@ with open("README.md", "r") as fh:
# This call to setup() does all the work # This call to setup() does all the work
setup( setup(
name="meshtastic", name="meshtastic",
version="2.0.1", version="2.1.3",
description="Python API & client shell for talking to Meshtastic devices", description="Python API & client shell for talking to Meshtastic devices",
long_description=long_description, long_description=long_description,
long_description_content_type="text/markdown", long_description_content_type="text/markdown",