Compare commits

..

1 Commits

Author SHA1 Message Date
Ben Meadors
898cac3e0d 2.0 (To be merged Nov 1) 2022-10-29 08:20:32 -05:00
33 changed files with 247 additions and 631 deletions

View File

@@ -1,20 +0,0 @@
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

@@ -15,22 +15,22 @@ jobs:
run: |
git pull --recurse-submodules
git submodule update --remote --recursive
- name: Download nanopb
run: |
wget https://jpa.kapsi.fi/nanopb/download/nanopb-0.4.6-linux-x86.tar.gz
tar xvzf nanopb-0.4.6-linux-x86.tar.gz
mv nanopb-0.4.6-linux-x86 nanopb-0.4.6
- name: Re-generate protocol buffers
run: |
./bin/regen-protobufs.sh
./bin/regen-protos.sh
- name: Commit update
run: |
git config --global user.name 'github-actions'
git config --global user.email 'bot@noreply.github.com'
git remote set-url origin https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}
git add protobufs
git add proto
git add meshtastic
git commit -m "Update protobuf submodule" && git push || echo "No changes to commit"

6
.gitmodules vendored
View File

@@ -1,3 +1,3 @@
[submodule "protobufs"]
path = protobufs
url = http://github.com/meshtastic/protobufs
[submodule "proto"]
path = proto
url = https://github.com/meshtastic/Meshtastic-protobufs.git

View File

@@ -7,7 +7,7 @@
# Add files or directories matching the regex patterns to the blacklist. The
# 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,device_metadata_pb2.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
@@ -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
# --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,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,no-self-use,pointless-string-statement,too-few-public-methods,broad-except,no-else-return,no-else-raise,bare-except,too-many-public-methods
[BASIC]

View File

@@ -26,11 +26,11 @@ lint:
slow:
pytest -m unit --durations=5
protobufs: FORCE
proto: FORCE
git submodule update --init --recursive
git pull --rebase
git submodule update --remote --merge
./bin/regen-protobufs.sh
./bin/regen-protos.sh
# run the coverage report and open results in a browser
cov:

View File

@@ -2,8 +2,8 @@
[![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)
[![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)
[![CI](https://img.shields.io/github/workflow/status/meshtastic/Meshtastic-python/CI?label=actions&logo=github&color=yellow)](https://github.com/meshtastic/Meshtastic-python/actions/workflows/ci.yml)
[![CLA assistant](https://cla-assistant.io/readme/badge/meshtastic/Meshtastic-python)](https://cla-assistant.io/meshtastic/Meshtastic-python)
[![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)
@@ -14,10 +14,12 @@ 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.
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)**
**[Documentation/API Reference](https://python.meshtastic.org/)**
## Stats
![Alt](https://repobeats.axiom.co/api/embed/c71ee8fc4a79690402e5d2807a41eec5e96d9039.svg "Repobeats analytics image")
![Alt](https://repobeats.axiom.co/api/embed/3d64492daee3a603497071b45e6cdb81d9b2d421.svg "Repobeats analytics image")

View File

@@ -1,15 +1,15 @@
#!/bin/bash
./nanopb-0.4.6/generator-bin/protoc -I=protobufs --python_out meshtastic `ls protobufs/*.proto`
./nanopb-0.4.6/generator-bin/protoc -I=proto --python_out meshtastic `ls proto/*.proto`
# workaround for import bug in protoc https://github.com/protocolbuffers/protobuf/issues/1491#issuecomment-690618628
if [[ $OSTYPE == 'darwin'* ]]; then
sed -i '' -E 's/^(import.*_pb2)/from . \1/' meshtastic/*.py
# automate the current workaround (may be related to Meshtastic-protobufs issue #27 https://github.com/meshtastic/protobufs/issues/27)
# automate the current workaround (may be related to Meshtastic-protobufs issue #27 https://github.com/meshtastic/Meshtastic-protobufs/issues/27)
sed -i '' -E "s/^None = 0/globals()['None'] = 0/" meshtastic/mesh_pb2.py
else
sed -i -e 's/^import.*_pb2/from . \0/' meshtastic/*.py
# automate the current workaround (may be related to Meshtastic-protobufs issue #27 https://github.com/meshtastic/protobufs/issues/27)
# automate the current workaround (may be related to Meshtastic-protobufs issue #27 https://github.com/meshtastic/Meshtastic-protobufs/issues/27)
sed -i -e "s/^None = 0/globals()['None'] = 0/" meshtastic/mesh_pb2.py
fi

View File

@@ -3,7 +3,7 @@
Primary class: SerialInterface
Install with pip: "[pip3 install meshtastic](https://pypi.org/project/meshtastic/)"
Source code on [github](https://github.com/meshtastic/python)
Source code on [github](https://github.com/meshtastic/Meshtastic-python)
properties of SerialInterface:
@@ -182,7 +182,6 @@ protocols = {
portnums_pb2.PortNum.ADMIN_APP: KnownProtocol("admin", admin_pb2.AdminMessage),
portnums_pb2.PortNum.ROUTING_APP: KnownProtocol("routing", mesh_pb2.Routing),
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.SIMULATOR_APP: KnownProtocol("simulator", mesh_pb2.Compressed),
portnums_pb2.PortNum.TRACEROUTE_APP: KnownProtocol("traceroute", mesh_pb2.RouteDiscovery)
portnums_pb2.PortNum.REMOTE_HARDWARE_APP: KnownProtocol("remotehw", remote_hardware_pb2.HardwareMessage),
portnums_pb2.PortNum.SIMULATOR_APP: KnownProtocol("simulator", mesh_pb2.Compressed)
}

View File

@@ -177,7 +177,6 @@ def setPref(config, comp_name, valStr):
def onConnected(interface):
"""Callback invoked when we connect to a radio"""
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:
our_globals = Globals.getInstance()
args = our_globals.get_args()
@@ -192,7 +191,6 @@ def onConnected(interface):
alt = 0
lat = 0.0
lon = 0.0
# TODO: use getNode(args.dest) to be able to set it for a remote node
localConfig = interface.localNode.localConfig
if args.setalt:
alt = int(args.setalt)
@@ -217,29 +215,19 @@ def onConnected(interface):
if args.set_owner:
closeNow = True
waitForAckNak = True
print(f"Setting device owner to {args.set_owner}")
interface.getNode(args.dest, False).setOwner(args.set_owner)
interface.getNode(args.dest).setOwner(args.set_owner)
if args.set_owner_short:
closeNow = True
waitForAckNak = True
print(f"Setting device owner short to {args.set_owner_short}")
interface.getNode(args.dest, False).setOwner(long_name=None, short_name=args.set_owner_short)
interface.getNode(args.dest).setOwner(long_name=None, short_name=args.set_owner_short)
# TODO: add to export-config and configure
if args.set_canned_message:
closeNow = True
waitForAckNak = True
print(f"Setting canned plugin message to {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)
interface.getNode(args.dest).set_canned_message(args.set_canned_message)
if args.pos_fields:
# If --pos-fields invoked with args, set position fields
@@ -283,40 +271,27 @@ def onConnected(interface):
if args.reboot:
closeNow = True
waitForAckNak = True
interface.getNode(args.dest, False).reboot()
interface.getNode(args.dest).reboot()
if args.reboot_ota:
closeNow = True
waitForAckNak = True
interface.getNode(args.dest, False).rebootOTA()
interface.getNode(args.dest).rebootOTA();
if args.shutdown:
closeNow = True
waitForAckNak = True
interface.getNode(args.dest, False).shutdown()
interface.getNode(args.dest).shutdown()
if args.device_metadata:
closeNow = True
interface.getNode(args.dest).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:
closeNow = True
waitForAckNak = True
interface.getNode(args.dest, False).factoryReset()
interface.getNode(args.dest).factoryReset()
if args.reset_nodedb:
closeNow = True
waitForAckNak = True
interface.getNode(args.dest, False).resetNodeDb()
interface.getNode(args.dest).resetNodeDb()
if args.sendtext:
closeNow = True
@@ -337,13 +312,6 @@ def onConnected(interface):
interface.sendData(payload, args.dest, portNum=portnums_pb2.PortNum.REPLY_APP,
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.dest == BROADCAST_ADDR:
meshtastic.util.our_exit("Warning: Must use a destination node ID.")
@@ -408,22 +376,17 @@ def onConnected(interface):
configuration = yaml.safe_load(file)
closeNow = True
interface.getNode(args.dest, False).beginSettingsTransaction()
if 'owner' in configuration:
print(f"Setting device owner to {configuration['owner']}")
waitForAckNak = True
interface.getNode(args.dest, False).setOwner(configuration['owner'])
interface.getNode(args.dest).setOwner(configuration['owner'])
if 'owner_short' in configuration:
print(f"Setting device owner short to {configuration['owner_short']}")
waitForAckNak = True
interface.getNode(args.dest, False).setOwner(long_name=None, short_name=configuration['owner_short'])
interface.getNode(args.dest).setOwner(long_name=None, short_name=configuration['owner_short'])
if 'ownerShort' in configuration:
print(f"Setting device owner short to {configuration['ownerShort']}")
waitForAckNak = True
interface.getNode(args.dest, False).setOwner(long_name=None, short_name=configuration['ownerShort'])
interface.getNode(args.dest).setOwner(long_name=None, short_name=configuration['ownerShort'])
if 'channel_url' in configuration:
print("Setting channel url to", configuration['channel_url'])
@@ -461,15 +424,14 @@ def onConnected(interface):
for pref in configuration['config'][section]:
setPref(localConfig, f"{section}.{pref}", str(configuration['config'][section][pref]))
interface.getNode(args.dest).writeConfig(section)
if 'module_config' in configuration:
moduleConfig = interface.getNode(args.dest).moduleConfig
for section in configuration['module_config']:
for pref in configuration['module_config'][section]:
setPref(moduleConfig, f"{section}.{pref}", str(configuration['module_config'][section][pref]))
interface.getNode(args.dest).writeConfig(section)
interface.getNode(args.dest, False).commitSettingsTransaction()
print("Writing modified configuration to device")
if args.export_config:
@@ -587,11 +549,6 @@ def onConnected(interface):
print("")
interface.getNode(args.dest).get_canned_message()
if args.get_ringtone:
closeNow = True
print("")
interface.getNode(args.dest).get_ringtone()
if args.info:
print("")
# If we aren't trying to talk to our local node, don't show it
@@ -647,10 +604,6 @@ def onConnected(interface):
else:
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 (not args.seriallog) and closeNow:
interface.close() # after running command then exit
@@ -660,7 +613,6 @@ def onConnected(interface):
interface.close() # close the connection now, so that our app exits
def printConfig(config):
"""print configuration"""
objDesc = config.DESCRIPTOR
for config_section in objDesc.fields:
if config_section.name != "version":
@@ -733,7 +685,7 @@ def export_config(interface):
configObj["config"] = config
else:
configObj["config"] = config
module_config = MessageToDict(interface.localNode.moduleConfig)
if module_config:
# Convert inner keys to correct snake/camelCase
@@ -872,9 +824,6 @@ def initParser():
parser.add_argument("--get-canned-message", help="Show the canned message plugin message",
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",
action="store_true")
@@ -912,7 +861,7 @@ def initParser():
"--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'. "
"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 psk default --ch-index 0'. To set encryption with your "
"To set encryption back to the default:'--ch-set default --ch-index 0'. To set encryption with your "
"own key: '--ch-set psk 0x1a1a1a1a2b2b2b2b1a1a1a1a2b2b2b2b1a1a1a1a2b2b2b2b1a1a1a1a2b2b2b2b --ch-index 0'."),
nargs=2, action='append')
@@ -941,10 +890,7 @@ def initParser():
"--set-owner", help="Set device owner name", action="store")
parser.add_argument(
"--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")
"--set-canned-message", help="Set the canned messages plugin message (up to 1000 characters).", action="store")
parser.add_argument(
"--set-owner-short", help="Set device owner short name", action="store")
@@ -961,12 +907,6 @@ def initParser():
parser.add_argument(
"--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(
"--reboot", help="Tell the destination node to reboot", action="store_true")
@@ -979,15 +919,9 @@ def initParser():
parser.add_argument(
"--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(
"--factory-reset", help="Tell the destination node to install the default config", action="store_true")
parser.add_argument(
"--reset-nodedb", help="Tell the destination node clear its list of nodes", action="store_true")

View File

@@ -19,7 +19,7 @@ from . import mesh_pb2 as mesh__pb2
from . import module_config_pb2 as module__config__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\"\xf2\x0b\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\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\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\"\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_variantB_\n\x13\x63om.geeksville.meshB\x0b\x41\x64minProtosH\x03Z\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufsb\x06proto3')
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')
@@ -36,11 +36,11 @@ _sym_db.RegisterMessage(AdminMessage)
if _descriptor._USE_C_DESCRIPTORS == False:
DESCRIPTOR._options = None
DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\013AdminProtosH\003Z\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs'
DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\013AdminProtosH\003Z\"github.com/meshtastic/go/generated'
_ADMINMESSAGE._serialized_start=101
_ADMINMESSAGE._serialized_end=1623
_ADMINMESSAGE_CONFIGTYPE._serialized_start=1241
_ADMINMESSAGE_CONFIGTYPE._serialized_end=1390
_ADMINMESSAGE_MODULECONFIGTYPE._serialized_start=1393
_ADMINMESSAGE_MODULECONFIGTYPE._serialized_end=1604
_ADMINMESSAGE._serialized_end=1485
_ADMINMESSAGE_CONFIGTYPE._serialized_start=1148
_ADMINMESSAGE_CONFIGTYPE._serialized_end=1297
_ADMINMESSAGE_MODULECONFIGTYPE._serialized_start=1300
_ADMINMESSAGE_MODULECONFIGTYPE._serialized_end=1466
# @@protoc_insertion_point(module_scope)

View File

@@ -16,7 +16,7 @@ from . import channel_pb2 as channel__pb2
from . import config_pb2 as 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.LoRaConfigBa\n\x13\x63om.geeksville.meshB\rAppOnlyProtosH\x03Z\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufsb\x06proto3')
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')
@@ -31,7 +31,7 @@ _sym_db.RegisterMessage(ChannelSet)
if _descriptor._USE_C_DESCRIPTORS == False:
DESCRIPTOR._options = None
DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\rAppOnlyProtosH\003Z\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs'
DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\rAppOnlyProtosH\003Z\"github.com/meshtastic/go/generated'
_CHANNELSET._serialized_start=46
_CHANNELSET._serialized_end=135
# @@protoc_insertion_point(module_scope)

View File

@@ -14,7 +14,7 @@ _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(\tBm\n\x13\x63om.geeksville.meshB\x19\x43\x61nnedMessageConfigProtosH\x03Z\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufsb\x06proto3')
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')
@@ -29,7 +29,7 @@ _sym_db.RegisterMessage(CannedMessageModuleConfig)
if _descriptor._USE_C_DESCRIPTORS == False:
DESCRIPTOR._options = None
DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\031CannedMessageConfigProtosH\003Z\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs'
DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\031CannedMessageConfigProtosH\003Z\"github.com/meshtastic/go/generated'
_CANNEDMESSAGEMODULECONFIG._serialized_start=24
_CANNEDMESSAGEMODULECONFIG._serialized_end=69
# @@protoc_insertion_point(module_scope)

View File

@@ -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\x42\x61\n\x13\x63om.geeksville.meshB\rChannelProtosH\x03Z\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufsb\x06proto3')
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')
@@ -38,7 +38,7 @@ _sym_db.RegisterMessage(Channel)
if _descriptor._USE_C_DESCRIPTORS == False:
DESCRIPTOR._options = None
DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\rChannelProtosH\003Z\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs'
DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\rChannelProtosH\003Z\"github.com/meshtastic/go/generated'
_CHANNELSETTINGS.fields_by_name['channel_num']._options = None
_CHANNELSETTINGS.fields_by_name['channel_num']._serialized_options = b'\030\001'
_CHANNELSETTINGS._serialized_start=18

View File

File diff suppressed because one or more lines are too long

View File

@@ -14,7 +14,7 @@ _sym_db = _symbol_database.Default()
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x15\x64\x65vice_metadata.proto\"\x99\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\x42h\n\x13\x63om.geeksville.meshB\x14\x44\x65viceMetadataProtosH\x03Z\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufsb\x06proto3')
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')
@@ -29,7 +29,7 @@ _sym_db.RegisterMessage(DeviceMetadata)
if _descriptor._USE_C_DESCRIPTORS == False:
DESCRIPTOR._options = None
DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\024DeviceMetadataProtosH\003Z\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs'
_DEVICEMETADATA._serialized_start=26
_DEVICEMETADATA._serialized_end=179
DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\024DeviceMetadataProtosH\003Z\"github.com/meshtastic/go/generated'
_DEVICEMETADATA._serialized_start=25
_DEVICEMETADATA._serialized_end=97
# @@protoc_insertion_point(module_scope)

View File

@@ -17,7 +17,7 @@ from . import channel_pb2 as channel__pb2
from . import mesh_pb2 as 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\x42^\n\x13\x63om.geeksville.meshB\nDeviceOnlyH\x03Z\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufsb\x06proto3')
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')
_SCREENFONTS = DESCRIPTOR.enum_types_by_name['ScreenFonts']
ScreenFonts = enum_type_wrapper.EnumTypeWrapper(_SCREENFONTS)
@@ -53,7 +53,7 @@ _sym_db.RegisterMessage(OEMStore)
if _descriptor._USE_C_DESCRIPTORS == False:
DESCRIPTOR._options = None
DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\nDeviceOnlyH\003Z\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs'
DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\nDeviceOnlyH\003Z\"github.com/meshtastic/go/generated'
_SCREENFONTS._serialized_start=490
_SCREENFONTS._serialized_end=552
_DEVICESTATE._serialized_start=48

View File

@@ -16,7 +16,7 @@ from . import config_pb2 as config__pb2
from . import module_config_pb2 as 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\"\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(\rBc\n\x13\x63om.geeksville.meshB\x0fLocalOnlyProtosH\x03Z\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufsb\x06proto3')
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')
@@ -39,9 +39,9 @@ _sym_db.RegisterMessage(LocalModuleConfig)
if _descriptor._USE_C_DESCRIPTORS == False:
DESCRIPTOR._options = None
DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\017LocalOnlyProtosH\003Z\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs'
DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\017LocalOnlyProtosH\003Z\"github.com/meshtastic/go/generated'
_LOCALCONFIG._serialized_start=55
_LOCALCONFIG._serialized_end=359
_LOCALMODULECONFIG._serialized_start=362
_LOCALMODULECONFIG._serialized_end=875
_LOCALMODULECONFIG._serialized_end=772
# @@protoc_insertion_point(module_scope)

View File

@@ -18,7 +18,7 @@ from google.protobuf.json_format import MessageToJson
import meshtastic.node
from meshtastic import portnums_pb2, mesh_pb2
from meshtastic.util import stripnl, Timeout, Acknowledgment, our_exit, remove_keys_from_dict, convert_mac_addr
from meshtastic.util import stripnl, Timeout, 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
class MeshInterface:
@@ -47,12 +47,12 @@ class MeshInterface:
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._timeout = Timeout()
self._acknowledgment = Acknowledgment()
self.heartbeatTimer = None
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.nodesByNum = None
self.configId = None
self.defaultHopLimit = 3
self.gotResponse = False # used in gpio read
self.mask = None # used in gpio read and gpio watch
@@ -137,20 +137,7 @@ class MeshInterface:
"Latitude": formatFloat(pos.get("latitude"), 4, "°"),
"Longitude": formatFloat(pos.get("longitude"), 4, "°"),
"Altitude": formatFloat(pos.get("altitude"), 0, " m"),
})
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, "%"),
"Battery": formatFloat(pos.get("batteryLevel"), 2, "%"),
})
row.update({
@@ -170,24 +157,23 @@ class MeshInterface:
return table
def getNode(self, nodeId, requestConfig=True):
def getNode(self, nodeId):
"""Return a node object which contains device settings and channel info"""
if nodeId in (LOCAL_ADDR, BROADCAST_ADDR):
return self.localNode
else:
n = meshtastic.node.Node(self, nodeId)
# Only request device settings and channel info when necessary
if requestConfig:
logging.debug("About to requestConfig")
n.requestConfig()
if not n.waitForConfig():
our_exit("Error: Timed out waiting for node config")
logging.debug("About to requestConfig")
n.requestConfig()
if not n.waitForConfig():
our_exit("Error: Timed out waiting for node config")
return n
def sendText(self, text: AnyStr,
destinationId=BROADCAST_ADDR,
wantAck=False,
wantResponse=False,
hopLimit=None,
onResponse=None,
channelIndex=0):
"""Send a utf8 string to some other node, if the node has a display it
@@ -209,17 +195,21 @@ class MeshInterface:
Returns the sent packet. The id field will be populated in this packet
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,
portNum=portnums_pb2.PortNum.TEXT_MESSAGE_APP,
wantAck=wantAck,
wantResponse=wantResponse,
hopLimit=hopLimit,
onResponse=onResponse,
channelIndex=channelIndex)
def sendData(self, data, destinationId=BROADCAST_ADDR,
portNum=portnums_pb2.PortNum.PRIVATE_APP, wantAck=False,
wantResponse=False,
hopLimit=None,
onResponse=None,
channelIndex=0):
"""Send a data packet to some other node
@@ -244,6 +234,8 @@ class MeshInterface:
Returns the sent packet. The id field will be populated in this packet
and can be used to track future message acks/naks.
"""
if hopLimit is None:
hopLimit = self.defaultHopLimit
if getattr(data, "SerializeToString", None):
logging.debug(f"Serializing protobuf as data: {stripnl(data)}")
@@ -266,7 +258,8 @@ class MeshInterface:
if onResponse is not None:
self._addResponseHandler(meshPacket.id, onResponse)
p = self._sendPacket(meshPacket, destinationId, wantAck=wantAck)
p = self._sendPacket(meshPacket, destinationId,
wantAck=wantAck, hopLimit=hopLimit)
return p
def sendPosition(self, latitude=0.0, longitude=0.0, altitude=0, timeSec=0,
@@ -305,43 +298,20 @@ class MeshInterface:
wantAck=wantAck,
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):
self.responseHandlers[requestId] = ResponseHandler(callback)
def _sendPacket(self, meshPacket,
destinationId=BROADCAST_ADDR,
wantAck=False):
wantAck=False, hopLimit=None):
"""Send a MeshPacket to the specified node (or if unspecified, broadcast).
You probably don't want this - use sendData instead.
Returns the sent packet. The id field will be populated in this packet and
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...
if(self.myInfo is not None and destinationId != self.myInfo.my_node_num):
@@ -375,8 +345,6 @@ class MeshInterface:
meshPacket.to = nodeNum
meshPacket.want_ack = wantAck
loraConfig = getattr(self.localNode.localConfig, 'lora')
hopLimit = getattr(loraConfig, 'hop_limit')
meshPacket.hop_limit = hopLimit
# if the user hasn't set an ID for this packet (likely and recommended),
@@ -398,18 +366,6 @@ class MeshInterface:
if not success:
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):
"""Get info about my node."""
if self.myInfo is None:
@@ -761,8 +717,7 @@ class MeshInterface:
# we keep the responseHandler in dict until we get a non ack
handler = self.responseHandlers.pop(requestId, None)
if handler is not None:
if not isAck or (isAck and handler.__name__ == "onAckNak"):
handler.callback(asDict)
handler.callback(asDict)
logging.debug(f"Publishing {topic}: packet={stripnl(asDict)} ")
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

@@ -15,7 +15,7 @@ _sym_db = _symbol_database.Default()
from . import mesh_pb2 as 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(\tB^\n\x13\x63om.geeksville.meshB\nMQTTProtosH\x03Z\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufsb\x06proto3')
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')
@@ -30,7 +30,7 @@ _sym_db.RegisterMessage(ServiceEnvelope)
if _descriptor._USE_C_DESCRIPTORS == False:
DESCRIPTOR._options = None
DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\nMQTTProtosH\003Z\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs'
DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\nMQTTProtosH\003Z\"github.com/meshtastic/go/generated'
_SERVICEENVELOPE._serialized_start=26
_SERVICEENVELOPE._serialized_end=112
# @@protoc_insertion_point(module_scope)

View File

@@ -26,9 +26,8 @@ class Node:
self.partialChannels = None
self.noProto = noProto
self.cannedPluginMessage = None
self.cannedPluginMessageMessages = None
self.ringtone = None
self.ringtonePart = None
self.gotResponse = None
@@ -182,13 +181,6 @@ class Node:
logging.debug("Wrote module: canned_message")
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: audo")
time.sleep(0.3)
def writeConfig(self, config_name):
"""Write the current (edited) localConfig to the device"""
if self.localConfig is None:
@@ -224,8 +216,6 @@ class Node:
p.set_module_config.telemetry.CopyFrom(self.moduleConfig.telemetry)
elif config_name == '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)
else:
our_exit(f"Error: No valid config with name {config_name}")
@@ -300,30 +290,38 @@ class Node:
def setOwner(self, long_name=None, short_name=None, is_licensed=False):
"""Set device owner name"""
logging.debug(f"in setOwner nodeNum:{self.nodeNum}")
p = admin_pb2.AdminMessage()
nChars = 4
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()
if long_name is not None:
p.set_owner.long_name = long_name
p.set_owner.is_licensed = is_licensed
if short_name is not None:
short_name = short_name.strip()
if len(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.is_licensed = is_licensed
# 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.short_name:{p.set_owner.short_name}:')
logging.debug(f'p.set_owner.is_licensed:{p.set_owner.is_licensed}')
# 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)
return self._sendAdmin(p)
def getURL(self, includeAll: bool = True):
"""The sharable URL that describes the current channel"""
@@ -338,14 +336,14 @@ class Node:
some_bytes = channelSet.SerializeToString()
s = base64.urlsafe_b64encode(some_bytes).decode('ascii')
s = s.replace("=", "").replace("+", "-").replace("/", "_")
return f"https://meshtastic.org/e/#{s}"
return f"https://www.meshtastic.org/e/#{s}"
def setURL(self, url):
"""Set mesh network URL"""
if self.localConfig is None:
our_exit("Warning: No Config has been read")
# URLs are of the form https://meshtastic.org/d/#{base64_channel_set}
# URLs are of the form https://www.meshtastic.org/d/#{base64_channel_set}
# Split on '/#' to find the base64 encoded channel settings
splitURL = url.split("/#")
b64 = splitURL[-1]
@@ -380,73 +378,6 @@ class Node:
p.set_config.lora.CopyFrom(channelSet.lora_config)
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):
"""Handle the response packet for requesting canned message plugin message part 1"""
logging.debug(f'onResponseRequestCannedMessagePluginMessageMessages() p:{p}')
@@ -508,12 +439,7 @@ class Node:
p.set_canned_message_module_messages = chunk
logging.debug(f"Setting canned message '{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)
self._sendAdmin(p)
def exitSimulator(self):
"""Tell a simulator node to exit (this message
@@ -530,38 +456,7 @@ class Node:
p.reboot_seconds = secs
logging.info(f"Telling node to reboot in {secs} seconds")
# 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)
return self._sendAdmin(p)
def rebootOTA(self, secs: int = 10):
"""Tell the node to reboot into factory firmware."""
@@ -569,12 +464,7 @@ class Node:
p.reboot_ota_seconds = secs
logging.info(f"Telling node to reboot to OTA in {secs} seconds")
# 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)
return self._sendAdmin(p)
def shutdown(self, secs: int = 10):
"""Tell the node to shutdown."""
@@ -582,15 +472,10 @@ class Node:
p.shutdown_seconds = secs
logging.info(f"Telling node to shutdown in {secs} seconds")
# 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)
return self._sendAdmin(p)
def getMetadata(self):
"""Get the node's metadata."""
def getMetadata(self, secs: int = 10):
"""Tell the node to shutdown."""
p = admin_pb2.AdminMessage()
p.get_device_metadata_request = True
logging.info(f"Requesting device metadata")
@@ -603,12 +488,7 @@ class Node:
p.factory_reset = True
logging.info(f"Telling node to factory reset")
# 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)
return self._sendAdmin(p)
def resetNodeDb(self):
"""Tell the node to reset its list of nodes."""
@@ -616,12 +496,7 @@ class Node:
p.nodedb_reset = True
logging.info(f"Telling node to reset the NodeDB")
# 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)
return self._sendAdmin(p)
def _fixupChannels(self):
"""Fixup indexes and add disabled channels as needed"""
@@ -676,7 +551,7 @@ class Node:
return # Don't try to parse this routing message
lastTried = 0
if len(self.partialChannels) > 0:
lastTried = self.partialChannels[-1].index
lastTried = self.partialChannels[-1]
logging.debug(f"Retrying previous channel request.")
self._requestChannel(lastTried)
return
@@ -705,18 +580,6 @@ class Node:
else:
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):
"""Done with initial config messages, now send regular
MeshPackets to ask for settings"""
@@ -734,7 +597,7 @@ class Node:
# pylint: disable=R1710
def _sendAdmin(self, p: admin_pb2.AdminMessage, wantResponse=True,
def _sendAdmin(self, p: admin_pb2.AdminMessage, wantResponse=False,
onResponse=None, adminIndex=0):
"""Send an admin message to the specified node (or the local node if destNodeNum is zero)"""
@@ -744,10 +607,10 @@ class Node:
if adminIndex == 0: # unless a special channel index was used, we want to use the admin index
adminIndex = self.iface.localNode._getAdminChannelIndex()
logging.debug(f'adminIndex:{adminIndex}')
return self.iface.sendData(p, self.nodeNum,
portNum=portnums_pb2.PortNum.ADMIN_APP,
wantAck=False,
wantAck=True,
wantResponse=wantResponse,
onResponse=onResponse,
channelIndex=adminIndex)

View File

@@ -15,7 +15,7 @@ _sym_db = _symbol_database.Default()
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x0eportnums.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\x08PortnumsH\x03Z\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufsb\x06proto3')
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')
_PORTNUM = DESCRIPTOR.enum_types_by_name['PortNum']
PortNum = enum_type_wrapper.EnumTypeWrapper(_PORTNUM)
@@ -28,7 +28,6 @@ ROUTING_APP = 5
ADMIN_APP = 6
TEXT_MESSAGE_COMPRESSED_APP = 7
WAYPOINT_APP = 8
AUDIO_APP = 9
REPLY_APP = 32
IP_TUNNEL_APP = 33
SERIAL_APP = 64
@@ -37,7 +36,6 @@ RANGE_TEST_APP = 66
TELEMETRY_APP = 67
ZPS_APP = 68
SIMULATOR_APP = 69
TRACEROUTE_APP = 70
PRIVATE_APP = 256
ATAK_FORWARDER = 257
MAX = 511
@@ -46,7 +44,7 @@ MAX = 511
if _descriptor._USE_C_DESCRIPTORS == False:
DESCRIPTOR._options = None
DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\010PortnumsH\003Z\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs'
DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\010PortnumsH\003Z\"github.com/meshtastic/go/generated'
_PORTNUM._serialized_start=19
_PORTNUM._serialized_end=439
_PORTNUM._serialized_end=404
# @@protoc_insertion_point(module_scope)

View File

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

View File

@@ -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\x42\x62\n\x13\x63om.geeksville.meshB\x0eRemoteHardwareH\x03Z\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufsb\x06proto3')
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')
@@ -30,7 +30,7 @@ _sym_db.RegisterMessage(HardwareMessage)
if _descriptor._USE_C_DESCRIPTORS == False:
DESCRIPTOR._options = None
DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\016RemoteHardwareH\003Z\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs'
DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\016RemoteHardwareH\003Z\"github.com/meshtastic/go/generated'
_HARDWAREMESSAGE._serialized_start=26
_HARDWAREMESSAGE._serialized_end=229
_HARDWAREMESSAGE_TYPE._serialized_start=121

View File

@@ -1,35 +0,0 @@
# -*- coding: utf-8 -*-
# Generated by the protocol buffer compiler. DO NOT EDIT!
# source: 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\x0brtttl.proto\"\x1f\n\x0bRTTTLConfig\x12\x10\n\x08ringtone\x18\x01 \x01(\tBe\n\x13\x63om.geeksville.meshB\x11RTTTLConfigProtosH\x03Z\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufsb\x06proto3')
_RTTTLCONFIG = DESCRIPTOR.message_types_by_name['RTTTLConfig']
RTTTLConfig = _reflection.GeneratedProtocolMessageType('RTTTLConfig', (_message.Message,), {
'DESCRIPTOR' : _RTTTLCONFIG,
'__module__' : '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\021RTTTLConfigProtosH\003Z\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs'
_RTTTLCONFIG._serialized_start=15
_RTTTLCONFIG._serialized_end=46
# @@protoc_insertion_point(module_scope)

View File

@@ -14,7 +14,7 @@ _sym_db = _symbol_database.Default()
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x12storeforward.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\x07variantBi\n\x13\x63om.geeksville.meshB\x15StoreAndForwardProtosH\x03Z\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufsb\x06proto3')
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')
@@ -57,15 +57,15 @@ _sym_db.RegisterMessage(StoreAndForward.Heartbeat)
if _descriptor._USE_C_DESCRIPTORS == False:
DESCRIPTOR._options = None
DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\025StoreAndForwardProtosH\003Z\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs'
DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\025StoreAndForwardProtosH\003Z\"github.com/meshtastic/go/generated'
_STOREANDFORWARD._serialized_start=23
_STOREANDFORWARD._serialized_end=853
_STOREANDFORWARD_STATISTICS._serialized_start=246
_STOREANDFORWARD_STATISTICS._serialized_end=451
_STOREANDFORWARD_HISTORY._serialized_start=453
_STOREANDFORWARD_HISTORY._serialized_end=526
_STOREANDFORWARD_HEARTBEAT._serialized_start=528
_STOREANDFORWARD_HEARTBEAT._serialized_end=574
_STOREANDFORWARD_REQUESTRESPONSE._serialized_start=577
_STOREANDFORWARD_REQUESTRESPONSE._serialized_end=842
_STOREANDFORWARD._serialized_end=801
_STOREANDFORWARD_STATISTICS._serialized_start=223
_STOREANDFORWARD_STATISTICS._serialized_end=428
_STOREANDFORWARD_HISTORY._serialized_start=430
_STOREANDFORWARD_HISTORY._serialized_end=503
_STOREANDFORWARD_HEARTBEAT._serialized_start=505
_STOREANDFORWARD_HEARTBEAT._serialized_end=551
_STOREANDFORWARD_REQUESTRESPONSE._serialized_start=554
_STOREANDFORWARD_REQUESTRESPONSE._serialized_end=801
# @@protoc_insertion_point(module_scope)

View File

@@ -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*\xb9\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\x42\x63\n\x13\x63om.geeksville.meshB\x0fTelemetryProtosH\x03Z\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufsb\x06proto3')
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')
_TELEMETRYSENSORTYPE = DESCRIPTOR.enum_types_by_name['TelemetrySensorType']
TelemetrySensorType = enum_type_wrapper.EnumTypeWrapper(_TELEMETRYSENSORTYPE)
@@ -30,8 +30,6 @@ SHTC3 = 7
LPS22 = 8
QMC6310 = 9
QMI8658 = 10
QMC5883L = 11
SHT31 = 12
_DEVICEMETRICS = DESCRIPTOR.message_types_by_name['DeviceMetrics']
@@ -61,9 +59,9 @@ _sym_db.RegisterMessage(Telemetry)
if _descriptor._USE_C_DESCRIPTORS == False:
DESCRIPTOR._options = None
DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\017TelemetryProtosH\003Z\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs'
DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\017TelemetryProtosH\003Z\"github.com/meshtastic/go/generated'
_TELEMETRYSENSORTYPE._serialized_start=418
_TELEMETRYSENSORTYPE._serialized_end=603
_TELEMETRYSENSORTYPE._serialized_end=578
_DEVICEMETRICS._serialized_start=19
_DEVICEMETRICS._serialized_end=124
_ENVIRONMENTMETRICS._serialized_start=127

View File

@@ -159,42 +159,6 @@ class Timeout:
time.sleep(self.sleepInterval)
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():
"""A thread that accepts closures to run, and runs them as they are received"""
@@ -232,7 +196,7 @@ def support_info():
print('')
print('If having issues with meshtastic cli or python library')
print('or wish to make feature requests, visit:')
print('https://github.com/meshtastic/python/issues')
print('https://github.com/meshtastic/Meshtastic-python/issues')
print('When adding an issue, be sure to include the following info:')
print(f' System: {platform.system()}')
print(f' Platform: {platform.platform()}')

1
proto Submodule

Submodule proto added at a79e3aef81

Submodule protobufs deleted from 3b0d871ca1

View File

@@ -12,16 +12,16 @@ with open("README.md", "r") as fh:
# This call to setup() does all the work
setup(
name="meshtastic",
version="2.0.8",
version="2.0.0",
description="Python API & client shell for talking to Meshtastic devices",
long_description=long_description,
long_description_content_type="text/markdown",
url="https://github.com/meshtastic/python",
author="Meshtastic Developers",
author_email="contact@meshtastic.org",
license="GPL-3.0-only",
url="https://github.com/meshtastic/Meshtastic-python",
author="Kevin Hester",
author_email="kevinh@geeksville.com",
license="MIT",
classifiers=[
"License :: OSI Approved :: GNU General Public License v3 (GPLv3)",
"License :: OSI Approved :: MIT License",
"Development Status :: 4 - Beta",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",

View File

@@ -1,5 +1,5 @@
readme.txt for single standalone executable zip files that can be
downloaded from https://github.com/meshtastic/python/releases
downloaded from https://github.com/meshtastic/Meshtastic-python/releases
If you do not want to install python and/or the python libraries, you can download one of these
files to run the Meshtastic command line interface (CLI) as a standalone executable.