Compare commits

..

26 Commits

Author SHA1 Message Date
mkinney
7903a4720d Merge pull request #330 from mkinney/1.2-legacy
1.2 legacy
2022-04-27 12:04:37 -07:00
mkinney
19648e3418 Merge branch 'meshtastic:1.2-legacy' into 1.2-legacy 2022-04-27 12:01:18 -07:00
Mike Kinney
49ee6b5988 update protobufs for 1.2 2022-04-27 12:00:37 -07:00
github-actions
5ac9867a91 bump version 2022-04-27 18:37:44 +00:00
mkinney
efa9469602 Merge pull request #329 from mkinney/1.2-legacy
1.2 legacy
2022-04-27 11:34:28 -07:00
Mike Kinney
e2f38b640b remove epaper 2022-04-27 11:32:14 -07:00
Mike Kinney
60d7540950 add nano_g1 2022-04-27 11:31:19 -07:00
github-actions
5761c89818 bump version 2022-03-21 17:49:55 +00:00
mkinney
d205d8e9ba Merge pull request #309 from mkinney/wifi_password_check
add wifi min length check
2022-03-21 10:48:05 -07:00
Mike Kinney
384ad456ae add wifi min length check 2022-03-21 10:44:46 -07:00
github-actions
a99397468f bump version 2022-03-16 02:59:04 +00:00
mkinney
f31297194a Merge pull request #305 from mkinney/1.2-legacy
fix the vendor and product id for tlora v1
2022-03-15 19:53:29 -07:00
Mike Kinney
4dc3bea674 fix the vendor and product id for tlora v1 2022-03-15 19:52:45 -07:00
github-actions
95f5d77c47 bump version 2022-03-16 02:34:58 +00:00
mkinney
5034e2ca43 Merge pull request #304 from mkinney/1.2-legacy
fix some tlora entries
2022-03-15 19:33:47 -07:00
Mike Kinney
eb4f68fccc fix some tlora entries 2022-03-15 19:32:27 -07:00
github-actions
de03f8e1fb bump version 2022-03-08 18:57:44 +00:00
mkinney
56f3e8a893 Merge pull request #297 from mkinney/1.2-legacy
refactor util; add duplicate check
2022-03-08 10:38:37 -08:00
mkinney
fbe0c09909 Merge branch '1.2-legacy' into 1.2-legacy 2022-03-08 10:37:15 -08:00
Mike Kinney
20c65974e9 refactor code to util 2022-03-08 10:34:46 -08:00
Mike Kinney
96e42ac3f2 add duplicate check 2022-03-08 10:24:44 -08:00
github-actions
3912f5728a bump version 2022-03-08 06:40:00 +00:00
mkinney
c016176520 Update release.yml 2022-03-07 22:38:45 -08:00
Mike Kinney
e6999ba5ad keep sha ref and use it for subsequent checkouts 2022-03-07 22:38:27 -08:00
Mike Kinney
5590dbeb6f do not checkout the code again 2022-03-07 22:38:06 -08:00
mkinney
e8a2909173 Merge pull request #294 from mkinney/bug_when_ports_not_sorted
fix when ports are not sorted
2022-03-07 22:37:49 -08:00
43 changed files with 2029 additions and 2244 deletions

View File

@@ -1,4 +1,4 @@
name: CI
name: Linting and Tests
on:
push:
branches:
@@ -42,14 +42,14 @@ jobs:
run: |
pytest --cov=meshtastic --cov-report=xml
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v2
uses: codecov/codecov-action@v1
with:
token: ${{ secrets.CODECOV_TOKEN }}
files: ./coverage.xml
file: ./coverage.xml
flags: unittests
name: codecov-umbrella
yml: ./codecov.yml
fail_ci_if_error: true
verbose: true
validate:
runs-on: ubuntu-latest
strategy:

View File

@@ -18,9 +18,9 @@ jobs:
- 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
wget https://jpa.kapsi.fi/nanopb/download/nanopb-0.4.4-linux-x86.tar.gz
tar xvzf nanopb-0.4.4-linux-x86.tar.gz
mv nanopb-0.4.4-linux-x86 nanopb-0.4.4
- name: Re-generate protocol buffers
run: |

3
.gitignore vendored
View File

@@ -5,7 +5,8 @@ dist
*.egg-info
log_*
.eggs
nanopb-*
nanopb-0.4.4
nanopb-0.4.5
.*swp
.coverage
*.py-E

1
.gitmodules vendored
View File

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

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
ignore-patterns=mqtt_pb2.py,channel_pb2.py,environmental_measurement_pb2.py,admin_pb2.py,radioconfig_pb2.py,deviceonly_pb2.py,apponly_pb2.py,remote_hardware_pb2.py,portnums_pb2.py,mesh_pb2.py,storeforward_pb2.py,cannedmessages_pb2.py
@@ -25,6 +25,7 @@ ignore-patterns=mqtt_pb2.py,channel_pb2.py,telemetry_pb2.py,admin_pb2.py,config_
#
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]
# Good variable names which should always be accepted, separated by a comma
@@ -40,7 +41,7 @@ bad-names=foo,bar,baz,toto,tutu,tata
max-line-length=150
# Maximum number of lines in a module
max-module-lines=1600
max-module-lines=1400

68
.vscode/launch.json vendored
View File

@@ -42,71 +42,7 @@
"request": "launch",
"module": "meshtastic",
"justMyCode": true,
"args": ["--debug"]
},
{
"name": "meshtastic debug getPref",
"type": "python",
"request": "launch",
"module": "meshtastic",
"justMyCode": true,
"args": ["--debug", "--get", "power.is_power_saving"]
},
{
"name": "meshtastic debug getPref telemetry",
"type": "python",
"request": "launch",
"module": "meshtastic",
"justMyCode": true,
"args": ["--debug", "--get", "telemetry.environment_update_interval"]
},
{
"name": "meshtastic debug info",
"type": "python",
"request": "launch",
"module": "meshtastic",
"justMyCode": true,
"args": ["--debug", "--info"]
},
{
"name": "meshtastic debug set region",
"type": "python",
"request": "launch",
"module": "meshtastic",
"justMyCode": true,
"args": ["--debug", "--set", "lora.region", "1"]
},
{
"name": "meshtastic debug setPref",
"type": "python",
"request": "launch",
"module": "meshtastic",
"justMyCode": true,
"args": ["--debug", "--set", "power.is_power_saving", "1"]
},
{
"name": "meshtastic debug setPref telemetry.environment_measurement_enabled",
"type": "python",
"request": "launch",
"module": "meshtastic",
"justMyCode": true,
"args": ["--debug", "--set", "telemetry.environment_measurement_enabled", "1"]
},
{
"name": "meshtastic debug setPref telemetry.environment_screen_enabled",
"type": "python",
"request": "launch",
"module": "meshtastic",
"justMyCode": true,
"args": ["--debug", "--set", "telemetry.environment_screen_enabled", "1"]
},
{
"name": "meshtastic debug setPref telemetry",
"type": "python",
"request": "launch",
"module": "meshtastic",
"justMyCode": true,
"args": ["--debug", "--set", "telemetry.environment_measurement_enabled", "1"]
"args": ["--debug" ]
},
{
"name": "meshtastic setpref",
@@ -156,7 +92,7 @@
"module": "meshtastic",
"justMyCode": true,
"args": ["--debug", "--sendtext", "pytest"]
},
}
{
"name": "meshtastic showNodes",
"type": "python",

View File

@@ -6,10 +6,6 @@ test:
virt:
pytest -m smokevirt
# run the smoke1 test (after doing a factory reset and unplugging/replugging in device)
smoke1:
pytest -m smoke1 -s -vv
# local install
install:
pip install .

View File

@@ -1,25 +1,15 @@
# Meshtastic Python
# Meshtastic-python
[![Open in Visual Studio Code](https://open.vscode.dev/badges/open-in-vscode.svg)](https://open.vscode.dev/meshtastic/Meshtastic-python)
![Unit Tests](https://github.com/meshtastic/Meshtastic-python/actions/workflows/ci.yml/badge.svg)
[![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/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)
## Overview
A python client for using [Meshtastic](https://www.meshtastic.org) devices. This small library (and example application) provides an easy API for sending and receiving messages over mesh radios. 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.
A Python client for use with Meshtastic devices.
This small library (and example application) provides an easy API for sending and receiving messages over mesh radios.
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.
Full documentation including examples [here](https://meshtastic.org/docs/software/python/python-installation).
The library api is documented [here](https://meshtastic-python.vercel.app/meshtastic/index.html)
**[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/3d64492daee3a603497071b45e6cdb81d9b2d421.svg "Repobeats analytics image")
[![Powered by Vercel](https://raw.githubusercontent.com/abumalick/powered-by-vercel/master/powered-by-vercel.svg)](https://vercel.com?utm_source=meshtastic&utm_campaign=oss)

View File

@@ -34,7 +34,7 @@ Basic functionality is complete now.
- DONE add fromId and toId to received messages dictionaries
- make command line options for displaying/changing config
- update nodedb as nodes change
- localConfig - getter/setter syntax: https://www.python-course.eu/python3_properties.php
- radioConfig - getter/setter syntax: https://www.python-course.eu/python3_properties.php
- let user change radio params via commandline options
- keep nodedb up-to-date based on received MeshPackets
- handle radio reboots and redownload db when that happens. Look for a special FromRadio.rebooted packet

View File

@@ -1,6 +1,6 @@
#!/bin/bash
./nanopb-0.4.6/generator-bin/protoc -I=proto --python_out meshtastic `ls proto/*.proto`
./nanopb-0.4.4/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

View File

@@ -12,5 +12,6 @@ location:
userPrefs:
region: 1
isAlwaysPowered: 'true'
sendOwnerInterval: 2
screenOnSecs: 31536000
waitBluetoothSecs: 31536000

View File

@@ -12,6 +12,7 @@ location:
user_prefs:
region: 1
is_always_powered: 'true'
send_owner_interval: 2
screen_on_secs: 31536000
wait_bluetooth_secs: 31536000
location_share: 'LocEnabled'

View File

@@ -1,14 +0,0 @@
"""Demonstration of how to look up a radio's location via its LAN connection.
Before running, connect your machine to the same WiFi network as the radio.
"""
import meshtastic
import meshtastic.tcp_interface
radio_hostname = "meshtastic.local" # Can also be an IP
iface = meshtastic.tcp_interface.TCPInterface(radio_hostname)
my_node_num = iface.myInfo.my_node_num
pos = iface.nodesByNum[my_node_num]["position"]
print (pos)
iface.close()

View File

@@ -7,7 +7,7 @@ Source code on [github](https://github.com/meshtastic/Meshtastic-python)
properties of SerialInterface:
- localConfig - Current radio configuration and device settings, if you write to this the new settings will be applied to
- radioConfig - Current radio configuration and device settings, if you write to this the new settings will be applied to
the device.
- nodes - The database of received nodes. Includes always up-to-date location and username information for each
node in the mesh. This is a read-only datastructure.
@@ -79,8 +79,8 @@ from google.protobuf.json_format import MessageToJson
from meshtastic.util import fixme, catchAndIgnore, stripnl, DeferredExecution, Timeout
from meshtastic.node import Node
from meshtastic import (mesh_pb2, portnums_pb2, apponly_pb2, admin_pb2,
telemetry_pb2, remote_hardware_pb2,
channel_pb2, config_pb2, util)
environmental_measurement_pb2, remote_hardware_pb2,
channel_pb2, radioconfig_pb2, util)
# Note: To follow PEP224, comments should be after the module variable.
@@ -94,7 +94,7 @@ BROADCAST_NUM = 0xffffffff
BROADCAST_ADDR = "^all"
"""A special ID that means broadcast"""
OUR_APP_VERSION = 20300
OUR_APP_VERSION = 20200
"""The numeric buildnumber (shared with android apps) specifying the
level of device code we are guaranteed to understand
@@ -181,6 +181,7 @@ protocols = {
portnums_pb2.PortNum.NODEINFO_APP: KnownProtocol("user", mesh_pb2.User, _onNodeInfoReceive),
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.ENVIRONMENTAL_MEASUREMENT_APP: KnownProtocol("environmental", environmental_measurement_pb2.EnvironmentalMeasurement),
portnums_pb2.PortNum.REMOTE_HARDWARE_APP: KnownProtocol(
"remotehw", remote_hardware_pb2.HardwareMessage)
}

View File

@@ -16,7 +16,7 @@ import meshtastic.util
import meshtastic.test
from meshtastic import remote_hardware
from meshtastic.ble_interface import BLEInterface
from meshtastic import portnums_pb2, channel_pb2, config_pb2
from meshtastic import portnums_pb2, channel_pb2, radioconfig_pb2
from meshtastic.globals import Globals
from meshtastic.__init__ import BROADCAST_ADDR
@@ -52,72 +52,78 @@ def onConnection(interface, topic=pub.AUTO_TOPIC): # pylint: disable=W0613
print(f"Connection changed: {topic.getName()}")
def getPref(config, comp_name):
def getPref(attributes, name):
"""Get a channel or preferences value"""
name = splitCompoundName(comp_name)
camel_name = meshtastic.util.snake_to_camel(name[1])
camel_name = meshtastic.util.snake_to_camel(name)
# Note: protobufs has the keys in snake_case, so snake internally
snake_name = meshtastic.util.camel_to_snake(name[1])
snake_name = meshtastic.util.camel_to_snake(name)
logging.debug(f'snake_name:{snake_name} camel_name:{camel_name}')
logging.debug(f'use camel:{Globals.getInstance().get_camel_case()}')
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 (not pref) or (not config_type):
return False
objDesc = attributes.DESCRIPTOR
field = objDesc.fields_by_name.get(snake_name)
if not field:
if Globals.getInstance().get_camel_case():
print(f"{attributes.__class__.__name__} does not have an attribute called {camel_name}, so you can not get it.")
else:
print(f"{attributes.__class__.__name__} does not have an attribute called {snake_name}, so you can not get it.")
print(f"Choices in sorted order are:")
names = []
for f in objDesc.fields:
tmp_name = f'{f.name}'
if Globals.getInstance().get_camel_case():
tmp_name = meshtastic.util.snake_to_camel(tmp_name)
names.append(tmp_name)
for temp_name in sorted(names):
print(f" {temp_name}")
return
# read the value
config_values = getattr(config, config_type.name)
pref_value = getattr(config_values, pref.name)
val = getattr(attributes, snake_name)
if Globals.getInstance().get_camel_case():
print(f"{str(config_type.name)}.{camel_name}: {str(pref_value)}")
logging.debug(f"{str(config_type.name)}.{camel_name}: {str(pref_value)}")
print(f"{camel_name}: {str(val)}")
logging.debug(f"{camel_name}: {str(val)}")
else:
print(f"{str(config_type.name)}.{snake_name}: {str(pref_value)}")
logging.debug(f"{str(config_type.name)}.{snake_name}: {str(pref_value)}")
return True
print(f"{snake_name}: {str(val)}")
logging.debug(f"{snake_name}: {str(val)}")
def splitCompoundName(comp_name):
name = comp_name.split(".",1)
if len(name) != 2:
name[0]=comp_name
name.append(comp_name)
return name
def setPref(config, comp_name, valStr):
def setPref(attributes, name, valStr):
"""Set a channel or preferences value"""
name = splitCompoundName(comp_name)
snake_name = meshtastic.util.camel_to_snake(name[1])
camel_name = meshtastic.util.snake_to_camel(name[1])
snake_name = meshtastic.util.camel_to_snake(name)
camel_name = meshtastic.util.snake_to_camel(name)
logging.debug(f'snake_name:{snake_name}')
logging.debug(f'camel_name:{camel_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 (not pref) or (not config_type):
return False
objDesc = attributes.DESCRIPTOR
field = objDesc.fields_by_name.get(snake_name)
if not field:
if Globals.getInstance().get_camel_case():
print(f"{attributes.__class__.__name__} does not have an attribute called {camel_name}, so you can not set it.")
else:
print(f"{attributes.__class__.__name__} does not have an attribute called {snake_name}, so you can not set it.")
print(f"Choices in sorted order are:")
names = []
for f in objDesc.fields:
tmp_name = f'{f.name}'
if Globals.getInstance().get_camel_case():
tmp_name = meshtastic.util.snake_to_camel(tmp_name)
names.append(tmp_name)
for temp_name in sorted(names):
print(f" {temp_name}")
return
val = meshtastic.util.fromStr(valStr)
logging.debug(f'valStr:{valStr} val:{val}')
if snake_name == 'psk' and len(valStr) < 8:
print(f"Warning: wifi.psk must be 8 or more characters.")
return
if snake_name == 'wifi_password' and len(valStr) < 8:
print(f"Warning: wifi_password must be 8 or more characters.")
return
enumType = pref.enum_type
enumType = field.enum_type
# pylint: disable=C0123
if enumType and type(val) == str:
# We've failed so far to convert this string into an enum, try to find it by reflection
@@ -126,9 +132,9 @@ def setPref(config, comp_name, valStr):
val = e.number
else:
if Globals.getInstance().get_camel_case():
print(f"{name[0]}.{camel_name} does not have an enum called {val}, so you can not set it.")
print(f"{camel_name} does not have an enum called {val}, so you can not set it.")
else:
print(f"{name[0]}.{snake_name} does not have an enum called {val}, so you can not set it.")
print(f"{snake_name} does not have an enum called {val}, so you can not set it.")
print(f"Choices in sorted order are:")
names = []
for f in enumType.values:
@@ -137,31 +143,16 @@ def setPref(config, comp_name, valStr):
for temp_name in sorted(names):
print(f" {temp_name}")
return
# note: 'ignore_incoming' is a repeating field
if snake_name != 'ignore_incoming':
try:
config_values = getattr(config, config_type.name)
setattr(config_values, pref.name, val)
except TypeError:
# The setter didn't like our arg type guess try again as a string
config_values = getattr(config, config_type.name)
setattr(config_values, pref.name, valStr)
else:
if val == 0:
# clear values
print("Clearing ignore_incoming list")
del config_type.message_type.ignore_incoming[:]
else:
print(f"Adding '{val}' to the ignore_incoming list")
config_type.message_type.ignore_incoming.extend([val])
try:
setattr(attributes, snake_name, val)
except TypeError:
# The setter didn't like our arg type guess try again as a string
setattr(attributes, snake_name, valStr)
if Globals.getInstance().get_camel_case():
print(f"Set {name[0]}.{camel_name} to {valStr}")
print(f"Set {camel_name} to {valStr}")
else:
print(f"Set {name[0]}.{snake_name} to {valStr}")
return True
print(f"Set {snake_name} to {valStr}")
def onConnected(interface):
@@ -181,18 +172,18 @@ def onConnected(interface):
alt = 0
lat = 0.0
lon = 0.0
localConfig = interface.localNode.localConfig
prefs = interface.localNode.radioConfig.preferences
if args.setalt:
alt = int(args.setalt)
localConfig.fixed_position = True
prefs.fixed_position = True
print(f"Fixing altitude at {alt} meters")
if args.setlat:
lat = float(args.setlat)
localConfig.fixed_position = True
prefs.fixed_position = True
print(f"Fixing latitude at {lat} degrees")
if args.setlon:
lon = float(args.setlon)
localConfig.fixed_position = True
prefs.fixed_position = True
print(f"Fixing longitude at {lon} degrees")
print("Setting device position")
@@ -222,36 +213,49 @@ def onConnected(interface):
if args.pos_fields:
# If --pos-fields invoked with args, set position fields
closeNow = True
localConfig = interface.getNode(args.dest).localConfig
prefs = interface.getNode(args.dest).radioConfig.preferences
allFields = 0
try:
for field in args.pos_fields:
v_field = config_pb2.PositionFlags.Value(field)
v_field = radioconfig_pb2.PositionFlags.Value(field)
allFields |= v_field
except ValueError:
print("ERROR: supported position fields are:")
print(config_pb2.PositionFlags.keys())
print(radioconfig_pb2.PositionFlags.keys())
print("If no fields are specified, will read and display current value.")
else:
print(f"Setting position fields to {allFields}")
setPref(localConfig, 'position_flags', f'{allFields:d}')
setPref(prefs, 'position_flags', f'{allFields:d}')
print("Writing modified preferences to device")
interface.getNode(args.dest).writeConfig()
elif args.pos_fields is not None:
# If --pos-fields invoked without args, read and display current value
closeNow = True
localConfig = interface.getNode(args.dest).localConfig
prefs = interface.getNode(args.dest).radioConfig.preferences
fieldNames = []
for bit in config_pb2.PositionFlags.values():
if localConfig.position_flags & bit:
fieldNames.append(config_pb2.PositionFlags.Name(bit))
for bit in radioconfig_pb2.PositionFlags.values():
if prefs.position_flags & bit:
fieldNames.append(radioconfig_pb2.PositionFlags.Name(bit))
print(' '.join(fieldNames))
if args.set_team:
closeNow = True
try:
v_team = meshtastic.mesh_pb2.Team.Value(args.set_team.upper())
except ValueError:
v_team = 0
print(f"ERROR: Team \'{args.set_team}\' not found.")
print("Try a team name from the sorted list below, or use 'CLEAR' for unaffiliated:")
print(sorted(meshtastic.mesh_pb2.Team.keys()))
else:
print(f"Setting team to {meshtastic.mesh_pb2.Team.Name(v_team)}")
interface.getNode(args.dest).setOwner(team=v_team)
if args.set_ham:
closeNow = True
print(f"Setting Ham ID to {args.set_ham} and turning off encryption")
@@ -324,22 +328,14 @@ def onConnected(interface):
# handle settings
if args.set:
closeNow = True
node = interface.getNode(args.dest)
prefs = interface.getNode(args.dest).radioConfig.preferences
# Handle the int/float/bool arguments
for pref in args.set:
found = setPref(node.localConfig, pref[0], pref[1])
if not found:
found = setPref(node.moduleConfig, pref[0], pref[1])
setPref(prefs, pref[0], pref[1])
if found:
print("Writing modified preferences to device")
interface.getNode(args.dest).writeConfig()
else:
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("Writing modified preferences to device")
interface.getNode(args.dest).writeConfig()
if args.configure:
with open(args.configure[0], encoding='utf8') as file:
@@ -370,35 +366,35 @@ def onConnected(interface):
alt = 0
lat = 0.0
lon = 0.0
localConfig = interface.localNode.localConfig
prefs = interface.localNode.radioConfig.preferences
if 'alt' in configuration['location']:
alt = int(configuration['location']['alt'])
localConfig.fixed_position = True
prefs.fixed_position = True
print(f"Fixing altitude at {alt} meters")
if 'lat' in configuration['location']:
lat = float(configuration['location']['lat'])
localConfig.fixed_position = True
prefs.fixed_position = True
print(f"Fixing latitude at {lat} degrees")
if 'lon' in configuration['location']:
lon = float(configuration['location']['lon'])
localConfig.fixed_position = True
prefs.fixed_position = True
print(f"Fixing longitude at {lon} degrees")
print("Setting device position")
interface.sendPosition(lat, lon, alt)
interface.localNode.writeConfig()
if 'user_prefs' in configuration:
localConfig = interface.getNode(args.dest).localConfig
prefs = interface.getNode(args.dest).radioConfig.preferences
for pref in configuration['user_prefs']:
setPref(localConfig, pref, str(configuration['user_prefs'][pref]))
setPref(prefs, pref, str(configuration['user_prefs'][pref]))
print("Writing modified preferences to device")
interface.getNode(args.dest).writeConfig()
if 'userPrefs' in configuration:
localConfig = interface.getNode(args.dest).localConfig
prefs = interface.getNode(args.dest).radioConfig.preferences
for pref in configuration['userPrefs']:
setPref(localConfig, pref, str(configuration['userPrefs'][pref]))
setPref(prefs, pref, str(configuration['userPrefs'][pref]))
print("Writing modified preferences to device")
interface.getNode(args.dest).writeConfig()
@@ -447,56 +443,66 @@ def onConnected(interface):
print(f"Deleting channel {channelIndex}")
ch = interface.getNode(args.dest).deleteChannel(channelIndex)
def setSimpleConfig(modem_preset):
"""Set one of the simple modem_config"""
# Completely new radio settings
chs = config_pb2.Config.LoRaConfig()
chs.modem_preset = modem_preset
prefs = interface.getNode(args.dest).localConfig
prefs.lora.CopyFrom(chs)
interface.getNode(args.dest).writeConfig()
# handle the simple radio set commands
if args.ch_vlongslow:
setSimpleConfig(config_pb2.Config.LoRaConfig.ModemPreset.VLongSlow)
if args.ch_longslow:
setSimpleConfig(config_pb2.Config.LoRaConfig.ModemPreset.LongSlow)
if args.ch_longfast:
setSimpleConfig(config_pb2.Config.LoRaConfig.ModemPreset.LongFast)
if args.ch_midslow:
setSimpleConfig(config_pb2.Config.LoRaConfig.ModemPreset.MidSlow)
if args.ch_midfast:
setSimpleConfig(config_pb2.Config.LoRaConfig.ModemPreset.MidFast)
if args.ch_shortslow:
setSimpleConfig(config_pb2.Config.LoRaConfig.ModemPreset.ShortSlow)
if args.ch_shortfast:
setSimpleConfig(config_pb2.Config.LoRaConfig.ModemPreset.ShortFast)
if args.ch_set or args.ch_enable or args.ch_disable:
ch_changes = [args.ch_longslow, args.ch_longfast,
args.ch_mediumslow, args.ch_mediumfast,
args.ch_shortslow, args.ch_shortfast]
any_primary_channel_changes = any(x for x in ch_changes)
if args.ch_set or any_primary_channel_changes or args.ch_enable or args.ch_disable:
closeNow = True
channelIndex = our_globals.get_channel_index()
if channelIndex is None:
meshtastic.util.our_exit("Warning: Need to specify '--ch-index'.", 1)
if any_primary_channel_changes:
# we assume that they want the primary channel if they're setting range values
channelIndex = 0
else:
meshtastic.util.our_exit("Warning: Need to specify '--ch-index'.", 1)
ch = interface.getNode(args.dest).channels[channelIndex]
if args.ch_enable or args.ch_disable:
if any_primary_channel_changes or args.ch_enable or args.ch_disable:
if channelIndex == 0:
if channelIndex == 0 and not any_primary_channel_changes:
meshtastic.util.our_exit("Warning: Cannot enable/disable PRIMARY channel.")
if channelIndex != 0:
if any_primary_channel_changes:
meshtastic.util.our_exit("Warning: Standard channel settings can only be applied to the PRIMARY channel")
enable = True # default to enable
if args.ch_enable:
enable = True
if args.ch_disable:
enable = False
def setSimpleChannel(modem_config):
"""Set one of the simple modem_config only based channels"""
# Completely new channel settings
chs = channel_pb2.ChannelSettings()
chs.modem_config = modem_config
chs.psk = bytes([1]) # Use default channel psk 1
ch.settings.CopyFrom(chs)
# handle the simple channel set commands
if args.ch_longslow:
setSimpleChannel(channel_pb2.ChannelSettings.ModemConfig.Bw125Cr48Sf4096)
if args.ch_longfast:
setSimpleChannel(channel_pb2.ChannelSettings.ModemConfig.Bw31_25Cr48Sf512)
if args.ch_mediumslow:
setSimpleChannel(channel_pb2.ChannelSettings.ModemConfig.Bw250Cr46Sf2048)
if args.ch_mediumfast:
setSimpleChannel(channel_pb2.ChannelSettings.ModemConfig.Bw250Cr47Sf1024)
if args.ch_shortslow:
setSimpleChannel(channel_pb2.ChannelSettings.ModemConfig.Bw125Cr45Sf128)
if args.ch_shortfast:
setSimpleChannel(channel_pb2.ChannelSettings.ModemConfig.Bw500Cr45Sf128)
# Handle the channel settings
for pref in (args.ch_set or []):
if pref[0] == "psk":
@@ -532,21 +538,12 @@ def onConnected(interface):
if args.get:
closeNow = True
localConfig = interface.getNode(args.dest).localConfig
moduleConfig = interface.getNode(args.dest).moduleConfig
prefs = interface.getNode(args.dest).radioConfig.preferences
# Handle the int/float/bool arguments
for pref in args.get:
found = getPref(localConfig, pref[0])
if not found:
found = getPref(moduleConfig, pref[0])
getPref(prefs, pref[0])
if not 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("Completed getting preferences")
if args.nodes:
@@ -630,7 +627,7 @@ def export_config(interface):
if alt:
config += f" alt: {alt}\n"
config += "\n"
preferences = f'{interface.localNode.localConfig}'
preferences = f'{interface.localNode.radioConfig.preferences}'
prefs = preferences.splitlines()
if prefs:
if Globals.getInstance().get_camel_case():
@@ -808,9 +805,6 @@ def initParser():
"own key: '--ch-set psk 0x1a1a1a1a2b2b2b2b1a1a1a1a2b2b2b2b1a1a1a1a2b2b2b2b1a1a1a1a2b2b2b2b --ch-index 0'."),
nargs=2, action='append')
parser.add_argument(
"--ch-vlongslow", help="Change to the very long-range and slow channel", action='store_true')
parser.add_argument(
"--ch-longslow", help="Change to the long-range and slow channel", action='store_true')
@@ -818,10 +812,10 @@ def initParser():
"--ch-longfast", help="Change to the long-range and fast channel", action='store_true')
parser.add_argument(
"--ch-midslow", help="Change to the mid-range and slow channel", action='store_true')
"--ch-mediumslow", help="Change to the medium-range and slow channel", action='store_true')
parser.add_argument(
"--ch-midfast", help="Change to the mid-range and fast channel", action='store_true')
"--ch-mediumfast", help="Change to the medium-range and fast channel", action='store_true')
parser.add_argument(
"--ch-shortslow", help="Change to the short-range and slow channel", action='store_true')
@@ -838,6 +832,9 @@ def initParser():
parser.add_argument(
"--set-owner-short", help="Set device owner short name", action="store")
parser.add_argument(
"--set-team", help="Set team affiliation (an invalid team will list valid values)", action="store")
parser.add_argument(
"--set-ham", help="Set licensed Ham ID and turn off encryption", action="store")
@@ -899,6 +896,13 @@ def initParser():
parser.add_argument("--noproto", help="Don't start the API, just function as a dumb serial terminal.",
action="store_true")
parser.add_argument('--setchan', dest='deprecated', nargs=2, action='append',
help='Deprecated, use "--ch-set param value" instead')
parser.add_argument('--set-router', dest='deprecated',
action='store_true', help='Deprecated, use "--set is_router true" instead')
parser.add_argument('--unset-router', dest='deprecated',
action='store_false', help='Deprecated, use "--set is_router false" instead')
have_tunnel = platform.system() == 'Linux'
if have_tunnel:
parser.add_argument('--tunnel', action='store_true',

View File

@@ -13,18 +13,15 @@ _sym_db = _symbol_database.Default()
from . import channel_pb2 as channel__pb2
from . import config_pb2 as config__pb2
from . import mesh_pb2 as mesh__pb2
from . import module_config_pb2 as module__config__pb2
from . import radioconfig_pb2 as radioconfig__pb2
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x0b\x61\x64min.proto\x1a\rchannel.proto\x1a\x0c\x63onfig.proto\x1a\nmesh.proto\x1a\x13module_config.proto\"\xc4\x0c\n\x0c\x41\x64minMessage\x12\x1a\n\tset_owner\x18\x02 \x01(\x0b\x32\x05.UserH\x00\x12\x1f\n\x0bset_channel\x18\x03 \x01(\x0b\x32\x08.ChannelH\x00\x12\x1d\n\x13get_channel_request\x18\x06 \x01(\rH\x00\x12(\n\x14get_channel_response\x18\x07 \x01(\x0b\x32\x08.ChannelH\x00\x12\x1b\n\x11get_owner_request\x18\x08 \x01(\x08H\x00\x12#\n\x12get_owner_response\x18\t \x01(\x0b\x32\x05.UserH\x00\x12\x36\n\x12get_config_request\x18\n \x01(\x0e\x32\x18.AdminMessage.ConfigTypeH\x00\x12&\n\x13get_config_response\x18\x0b \x01(\x0b\x32\x07.ConfigH\x00\x12\x1d\n\nset_config\x18\x0c \x01(\x0b\x32\x07.ConfigH\x00\x12\x1c\n\x12\x63onfirm_set_config\x18\r \x01(\x08H\x00\x12\x43\n\x19get_module_config_request\x18\x0e \x01(\x0e\x32\x1e.AdminMessage.ModuleConfigTypeH\x00\x12\x33\n\x1aget_module_config_response\x18\x0f \x01(\x0b\x32\r.ModuleConfigH\x00\x12*\n\x11set_module_config\x18\x10 \x01(\x0b\x32\r.ModuleConfigH\x00\x12#\n\x19\x63onfirm_set_module_config\x18\x11 \x01(\x08H\x00\x12\x1d\n\x13\x63onfirm_set_channel\x18 \x01(\x08H\x00\x12\x1b\n\x11\x63onfirm_set_radio\x18! \x01(\x08H\x00\x12\x18\n\x0e\x65xit_simulator\x18\" \x01(\x08H\x00\x12\x18\n\x0ereboot_seconds\x18# \x01(\x05H\x00\x12\x31\n\'get_canned_message_module_part1_request\x18$ \x01(\x08H\x00\x12\x32\n(get_canned_message_module_part1_response\x18% \x01(\tH\x00\x12\x31\n\'get_canned_message_module_part2_request\x18& \x01(\x08H\x00\x12\x32\n(get_canned_message_module_part2_response\x18\' \x01(\tH\x00\x12\x31\n\'get_canned_message_module_part3_request\x18( \x01(\x08H\x00\x12\x32\n(get_canned_message_module_part3_response\x18) \x01(\tH\x00\x12\x31\n\'get_canned_message_module_part4_request\x18* \x01(\x08H\x00\x12\x32\n(get_canned_message_module_part4_response\x18+ \x01(\tH\x00\x12)\n\x1fset_canned_message_module_part1\x18, \x01(\tH\x00\x12)\n\x1fset_canned_message_module_part2\x18- \x01(\tH\x00\x12)\n\x1fset_canned_message_module_part3\x18. \x01(\tH\x00\x12)\n\x1fset_canned_message_module_part4\x18/ \x01(\tH\x00\x12\x1a\n\x10shutdown_seconds\x18\x33 \x01(\x05H\x00\"|\n\nConfigType\x12\x11\n\rDEVICE_CONFIG\x10\x00\x12\x13\n\x0fPOSITION_CONFIG\x10\x01\x12\x10\n\x0cPOWER_CONFIG\x10\x02\x12\x0f\n\x0bWIFI_CONFIG\x10\x03\x12\x12\n\x0e\x44ISPLAY_CONFIG\x10\x04\x12\x0f\n\x0bLORA_CONFIG\x10\x05\"\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\t\n\x07variantBG\n\x13\x63om.geeksville.meshB\x0b\x41\x64minProtosH\x03Z!github.com/meshtastic/gomeshprotob\x06proto3')
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x0b\x61\x64min.proto\x1a\rchannel.proto\x1a\nmesh.proto\x1a\x11radioconfig.proto\"\xa1\x08\n\x0c\x41\x64minMessage\x12!\n\tset_radio\x18\x01 \x01(\x0b\x32\x0c.RadioConfigH\x00\x12\x1a\n\tset_owner\x18\x02 \x01(\x0b\x32\x05.UserH\x00\x12\x1f\n\x0bset_channel\x18\x03 \x01(\x0b\x32\x08.ChannelH\x00\x12\x1b\n\x11get_radio_request\x18\x04 \x01(\x08H\x00\x12*\n\x12get_radio_response\x18\x05 \x01(\x0b\x32\x0c.RadioConfigH\x00\x12\x1d\n\x13get_channel_request\x18\x06 \x01(\rH\x00\x12(\n\x14get_channel_response\x18\x07 \x01(\x0b\x32\x08.ChannelH\x00\x12\x1b\n\x11get_owner_request\x18\x08 \x01(\x08H\x00\x12#\n\x12get_owner_response\x18\t \x01(\x0b\x32\x05.UserH\x00\x12\x1d\n\x13\x63onfirm_set_channel\x18 \x01(\x08H\x00\x12\x1b\n\x11\x63onfirm_set_radio\x18! \x01(\x08H\x00\x12\x18\n\x0e\x65xit_simulator\x18\" \x01(\x08H\x00\x12\x18\n\x0ereboot_seconds\x18# \x01(\x05H\x00\x12\x31\n\'get_canned_message_plugin_part1_request\x18$ \x01(\x08H\x00\x12\x32\n(get_canned_message_plugin_part1_response\x18% \x01(\tH\x00\x12\x31\n\'get_canned_message_plugin_part2_request\x18& \x01(\x08H\x00\x12\x32\n(get_canned_message_plugin_part2_response\x18\' \x01(\tH\x00\x12\x31\n\'get_canned_message_plugin_part3_request\x18( \x01(\x08H\x00\x12\x32\n(get_canned_message_plugin_part3_response\x18) \x01(\tH\x00\x12\x31\n\'get_canned_message_plugin_part4_request\x18* \x01(\x08H\x00\x12\x32\n(get_canned_message_plugin_part4_response\x18+ \x01(\tH\x00\x12)\n\x1fset_canned_message_plugin_part1\x18, \x01(\tH\x00\x12)\n\x1fset_canned_message_plugin_part2\x18- \x01(\tH\x00\x12)\n\x1fset_canned_message_plugin_part3\x18. \x01(\tH\x00\x12)\n\x1fset_canned_message_plugin_part4\x18/ \x01(\tH\x00\x12\x1a\n\x10shutdown_seconds\x18\x33 \x01(\x05H\x00\x42\t\n\x07variantBG\n\x13\x63om.geeksville.meshB\x0b\x41\x64minProtosH\x03Z!github.com/meshtastic/gomeshprotob\x06proto3')
_ADMINMESSAGE = DESCRIPTOR.message_types_by_name['AdminMessage']
_ADMINMESSAGE_CONFIGTYPE = _ADMINMESSAGE.enum_types_by_name['ConfigType']
_ADMINMESSAGE_MODULECONFIGTYPE = _ADMINMESSAGE.enum_types_by_name['ModuleConfigType']
AdminMessage = _reflection.GeneratedProtocolMessageType('AdminMessage', (_message.Message,), {
'DESCRIPTOR' : _ADMINMESSAGE,
'__module__' : 'admin_pb2'
@@ -36,10 +33,6 @@ if _descriptor._USE_C_DESCRIPTORS == False:
DESCRIPTOR._options = None
DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\013AdminProtosH\003Z!github.com/meshtastic/gomeshproto'
_ADMINMESSAGE._serialized_start=78
_ADMINMESSAGE._serialized_end=1682
_ADMINMESSAGE_CONFIGTYPE._serialized_start=1378
_ADMINMESSAGE_CONFIGTYPE._serialized_end=1502
_ADMINMESSAGE_MODULECONFIGTYPE._serialized_start=1505
_ADMINMESSAGE_MODULECONFIGTYPE._serialized_end=1671
_ADMINMESSAGE._serialized_start=62
_ADMINMESSAGE._serialized_end=1119
# @@protoc_insertion_point(module_scope)

View File

@@ -13,10 +13,9 @@ _sym_db = _symbol_database.Default()
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.LoRaConfigBI\n\x13\x63om.geeksville.meshB\rAppOnlyProtosH\x03Z!github.com/meshtastic/gomeshprotob\x06proto3')
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\rapponly.proto\x1a\rchannel.proto\"0\n\nChannelSet\x12\"\n\x08settings\x18\x01 \x03(\x0b\x32\x10.ChannelSettingsBI\n\x13\x63om.geeksville.meshB\rAppOnlyProtosH\x03Z!github.com/meshtastic/gomeshprotob\x06proto3')
@@ -32,6 +31,6 @@ if _descriptor._USE_C_DESCRIPTORS == False:
DESCRIPTOR._options = None
DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\rAppOnlyProtosH\003Z!github.com/meshtastic/gomeshproto'
_CHANNELSET._serialized_start=46
_CHANNELSET._serialized_end=135
_CHANNELSET._serialized_start=32
_CHANNELSET._serialized_end=80
# @@protoc_insertion_point(module_scope)

View File

@@ -14,22 +14,22 @@ _sym_db = _symbol_database.Default()
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x14\x63\x61nnedmessages.proto\"w\n\x19\x43\x61nnedMessageModuleConfig\x12\x15\n\rmessagesPart1\x18\x0b \x01(\t\x12\x15\n\rmessagesPart2\x18\x0c \x01(\t\x12\x15\n\rmessagesPart3\x18\r \x01(\t\x12\x15\n\rmessagesPart4\x18\x0e \x01(\tBU\n\x13\x63om.geeksville.meshB\x19\x43\x61nnedMessageConfigProtosH\x03Z!github.com/meshtastic/gomeshprotob\x06proto3')
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x14\x63\x61nnedmessages.proto\"w\n\x19\x43\x61nnedMessagePluginConfig\x12\x15\n\rmessagesPart1\x18\x0b \x01(\t\x12\x15\n\rmessagesPart2\x18\x0c \x01(\t\x12\x15\n\rmessagesPart3\x18\r \x01(\t\x12\x15\n\rmessagesPart4\x18\x0e \x01(\tBU\n\x13\x63om.geeksville.meshB\x19\x43\x61nnedMessageConfigProtosH\x03Z!github.com/meshtastic/gomeshprotob\x06proto3')
_CANNEDMESSAGEMODULECONFIG = DESCRIPTOR.message_types_by_name['CannedMessageModuleConfig']
CannedMessageModuleConfig = _reflection.GeneratedProtocolMessageType('CannedMessageModuleConfig', (_message.Message,), {
'DESCRIPTOR' : _CANNEDMESSAGEMODULECONFIG,
_CANNEDMESSAGEPLUGINCONFIG = DESCRIPTOR.message_types_by_name['CannedMessagePluginConfig']
CannedMessagePluginConfig = _reflection.GeneratedProtocolMessageType('CannedMessagePluginConfig', (_message.Message,), {
'DESCRIPTOR' : _CANNEDMESSAGEPLUGINCONFIG,
'__module__' : 'cannedmessages_pb2'
# @@protoc_insertion_point(class_scope:CannedMessageModuleConfig)
# @@protoc_insertion_point(class_scope:CannedMessagePluginConfig)
})
_sym_db.RegisterMessage(CannedMessageModuleConfig)
_sym_db.RegisterMessage(CannedMessagePluginConfig)
if _descriptor._USE_C_DESCRIPTORS == False:
DESCRIPTOR._options = None
DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\031CannedMessageConfigProtosH\003Z!github.com/meshtastic/gomeshproto'
_CANNEDMESSAGEMODULECONFIG._serialized_start=24
_CANNEDMESSAGEMODULECONFIG._serialized_end=143
_CANNEDMESSAGEPLUGINCONFIG._serialized_start=24
_CANNEDMESSAGEPLUGINCONFIG._serialized_end=143
# @@protoc_insertion_point(module_scope)

View File

@@ -14,12 +14,13 @@ _sym_db = _symbol_database.Default()
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\rchannel.proto\"\x7f\n\x0f\x43hannelSettings\x12\x13\n\x0b\x63hannel_num\x18\t \x01(\r\x12\x0b\n\x03psk\x18\x04 \x01(\x0c\x12\x0c\n\x04name\x18\x05 \x01(\t\x12\n\n\x02id\x18\n \x01(\x07\x12\x16\n\x0euplink_enabled\x18\x10 \x01(\x08\x12\x18\n\x10\x64ownlink_enabled\x18\x11 \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\x42I\n\x13\x63om.geeksville.meshB\rChannelProtosH\x03Z!github.com/meshtastic/gomeshprotob\x06proto3')
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\rchannel.proto\"\x91\x03\n\x0f\x43hannelSettings\x12\x10\n\x08tx_power\x18\x01 \x01(\x05\x12\x32\n\x0cmodem_config\x18\x03 \x01(\x0e\x32\x1c.ChannelSettings.ModemConfig\x12\x11\n\tbandwidth\x18\x06 \x01(\r\x12\x15\n\rspread_factor\x18\x07 \x01(\r\x12\x13\n\x0b\x63oding_rate\x18\x08 \x01(\r\x12\x13\n\x0b\x63hannel_num\x18\t \x01(\r\x12\x0b\n\x03psk\x18\x04 \x01(\x0c\x12\x0c\n\x04name\x18\x05 \x01(\t\x12\n\n\x02id\x18\n \x01(\x07\x12\x16\n\x0euplink_enabled\x18\x10 \x01(\x08\x12\x18\n\x10\x64ownlink_enabled\x18\x11 \x01(\x08\"\x8a\x01\n\x0bModemConfig\x12\x12\n\x0e\x42w125Cr45Sf128\x10\x00\x12\x12\n\x0e\x42w500Cr45Sf128\x10\x01\x12\x14\n\x10\x42w31_25Cr48Sf512\x10\x02\x12\x13\n\x0f\x42w125Cr48Sf4096\x10\x03\x12\x13\n\x0f\x42w250Cr46Sf2048\x10\x04\x12\x13\n\x0f\x42w250Cr47Sf1024\x10\x05\"\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\x42I\n\x13\x63om.geeksville.meshB\rChannelProtosH\x03Z!github.com/meshtastic/gomeshprotob\x06proto3')
_CHANNELSETTINGS = DESCRIPTOR.message_types_by_name['ChannelSettings']
_CHANNEL = DESCRIPTOR.message_types_by_name['Channel']
_CHANNELSETTINGS_MODEMCONFIG = _CHANNELSETTINGS.enum_types_by_name['ModemConfig']
_CHANNEL_ROLE = _CHANNEL.enum_types_by_name['Role']
ChannelSettings = _reflection.GeneratedProtocolMessageType('ChannelSettings', (_message.Message,), {
'DESCRIPTOR' : _CHANNELSETTINGS,
@@ -39,10 +40,12 @@ if _descriptor._USE_C_DESCRIPTORS == False:
DESCRIPTOR._options = None
DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\rChannelProtosH\003Z!github.com/meshtastic/gomeshproto'
_CHANNELSETTINGS._serialized_start=17
_CHANNELSETTINGS._serialized_end=144
_CHANNEL._serialized_start=147
_CHANNEL._serialized_end=286
_CHANNEL_ROLE._serialized_start=238
_CHANNEL_ROLE._serialized_end=286
_CHANNELSETTINGS._serialized_start=18
_CHANNELSETTINGS._serialized_end=419
_CHANNELSETTINGS_MODEMCONFIG._serialized_start=281
_CHANNELSETTINGS_MODEMCONFIG._serialized_end=419
_CHANNEL._serialized_start=422
_CHANNEL._serialized_end=561
_CHANNEL_ROLE._serialized_start=513
_CHANNEL_ROLE._serialized_end=561
# @@protoc_insertion_point(module_scope)

View File

@@ -1,119 +0,0 @@
# -*- coding: utf-8 -*-
# Generated by the protocol buffer compiler. DO NOT EDIT!
# source: config.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\x0c\x63onfig.proto\"\xf8\x11\n\x06\x43onfig\x12&\n\x06\x64\x65vice\x18\x01 \x01(\x0b\x32\x14.Config.DeviceConfigH\x00\x12*\n\x08position\x18\x02 \x01(\x0b\x32\x16.Config.PositionConfigH\x00\x12$\n\x05power\x18\x03 \x01(\x0b\x32\x13.Config.PowerConfigH\x00\x12\"\n\x04wifi\x18\x04 \x01(\x0b\x32\x12.Config.WiFiConfigH\x00\x12(\n\x07\x64isplay\x18\x05 \x01(\x0b\x32\x15.Config.DisplayConfigH\x00\x12\"\n\x04lora\x18\x06 \x01(\x0b\x32\x12.Config.LoRaConfigH\x00\x1a\xd8\x01\n\x0c\x44\x65viceConfig\x12\'\n\x04role\x18\x01 \x01(\x0e\x32\x19.Config.DeviceConfig.Role\x12\x17\n\x0fserial_disabled\x18\x02 \x01(\x08\x12\x15\n\rfactory_reset\x18\x03 \x01(\x08\x12\x19\n\x11\x64\x65\x62ug_log_enabled\x18\x04 \x01(\x08\x12\x12\n\nntp_server\x18\x05 \x01(\t\"@\n\x04Role\x12\n\n\x06\x43lient\x10\x00\x12\x0e\n\nClientMute\x10\x01\x12\n\n\x06Router\x10\x02\x12\x10\n\x0cRouterClient\x10\x03\x1a\xa8\x03\n\x0ePositionConfig\x12\x1f\n\x17position_broadcast_secs\x18\x01 \x01(\r\x12)\n!position_broadcast_smart_disabled\x18\x02 \x01(\x08\x12\x16\n\x0e\x66ixed_position\x18\x03 \x01(\x08\x12\x14\n\x0cgps_disabled\x18\x05 \x01(\x08\x12\x1b\n\x13gps_update_interval\x18\x06 \x01(\r\x12\x18\n\x10gps_attempt_time\x18\x07 \x01(\r\x12\x16\n\x0eposition_flags\x18\n \x01(\r\"\xcc\x01\n\rPositionFlags\x12\x11\n\rPOS_UNDEFINED\x10\x00\x12\x10\n\x0cPOS_ALTITUDE\x10\x01\x12\x0f\n\x0bPOS_ALT_MSL\x10\x02\x12\x0f\n\x0bPOS_GEO_SEP\x10\x04\x12\x0b\n\x07POS_DOP\x10\x08\x12\r\n\tPOS_HVDOP\x10\x10\x12\x11\n\rPOS_SATINVIEW\x10 \x12\x0f\n\x0bPOS_SEQ_NOS\x10@\x12\x12\n\rPOS_TIMESTAMP\x10\x80\x01\x12\x10\n\x0bPOS_HEADING\x10\x80\x02\x12\x0e\n\tPOS_SPEED\x10\x80\x04\x1a\xf4\x03\n\x0bPowerConfig\x12\x39\n\x0e\x63harge_current\x18\x01 \x01(\x0e\x32!.Config.PowerConfig.ChargeCurrent\x12\x17\n\x0fis_power_saving\x18\x02 \x01(\x08\x12&\n\x1eon_battery_shutdown_after_secs\x18\x04 \x01(\r\x12\x1f\n\x17\x61\x64\x63_multiplier_override\x18\x06 \x01(\x02\x12\x1b\n\x13wait_bluetooth_secs\x18\x07 \x01(\r\x12\x1d\n\x15mesh_sds_timeout_secs\x18\t \x01(\r\x12\x10\n\x08sds_secs\x18\n \x01(\r\x12\x0f\n\x07ls_secs\x18\x0b \x01(\r\x12\x15\n\rmin_wake_secs\x18\x0c \x01(\r\"\xd1\x01\n\rChargeCurrent\x12\x0b\n\x07MAUnset\x10\x00\x12\t\n\x05MA100\x10\x01\x12\t\n\x05MA190\x10\x02\x12\t\n\x05MA280\x10\x03\x12\t\n\x05MA360\x10\x04\x12\t\n\x05MA450\x10\x05\x12\t\n\x05MA550\x10\x06\x12\t\n\x05MA630\x10\x07\x12\t\n\x05MA700\x10\x08\x12\t\n\x05MA780\x10\t\x12\t\n\x05MA880\x10\n\x12\t\n\x05MA960\x10\x0b\x12\n\n\x06MA1000\x10\x0c\x12\n\n\x06MA1080\x10\r\x12\n\n\x06MA1160\x10\x0e\x12\n\n\x06MA1240\x10\x0f\x12\n\n\x06MA1320\x10\x10\x1aK\n\nWiFiConfig\x12\x0c\n\x04ssid\x18\x01 \x01(\t\x12\x0b\n\x03psk\x18\x02 \x01(\t\x12\x0f\n\x07\x61p_mode\x18\x03 \x01(\x08\x12\x11\n\tap_hidden\x18\x04 \x01(\x08\x1a\x8f\x02\n\rDisplayConfig\x12\x16\n\x0escreen_on_secs\x18\x01 \x01(\r\x12=\n\ngps_format\x18\x02 \x01(\x0e\x32).Config.DisplayConfig.GpsCoordinateFormat\x12!\n\x19\x61uto_screen_carousel_secs\x18\x03 \x01(\r\"\x83\x01\n\x13GpsCoordinateFormat\x12\x10\n\x0cGpsFormatDec\x10\x00\x12\x10\n\x0cGpsFormatDMS\x10\x01\x12\x10\n\x0cGpsFormatUTM\x10\x02\x12\x11\n\rGpsFormatMGRS\x10\x03\x12\x10\n\x0cGpsFormatOLC\x10\x04\x12\x11\n\rGpsFormatOSGR\x10\x05\x1a\x93\x04\n\nLoRaConfig\x12\x10\n\x08tx_power\x18\x01 \x01(\x05\x12\x34\n\x0cmodem_preset\x18\x02 \x01(\x0e\x32\x1e.Config.LoRaConfig.ModemPreset\x12\x11\n\tbandwidth\x18\x03 \x01(\r\x12\x15\n\rspread_factor\x18\x04 \x01(\r\x12\x13\n\x0b\x63oding_rate\x18\x05 \x01(\r\x12\x18\n\x10\x66requency_offset\x18\x06 \x01(\x02\x12-\n\x06region\x18\x07 \x01(\x0e\x32\x1d.Config.LoRaConfig.RegionCode\x12\x11\n\thop_limit\x18\x08 \x01(\r\x12\x13\n\x0btx_disabled\x18\t \x01(\x08\x12\x17\n\x0fignore_incoming\x18g \x03(\r\"\x81\x01\n\nRegionCode\x12\t\n\x05Unset\x10\x00\x12\x06\n\x02US\x10\x01\x12\t\n\x05\x45U433\x10\x02\x12\t\n\x05\x45U868\x10\x03\x12\x06\n\x02\x43N\x10\x04\x12\x06\n\x02JP\x10\x05\x12\x07\n\x03\x41NZ\x10\x06\x12\x06\n\x02KR\x10\x07\x12\x06\n\x02TW\x10\x08\x12\x06\n\x02RU\x10\t\x12\x06\n\x02IN\x10\n\x12\t\n\x05NZ865\x10\x0b\x12\x06\n\x02TH\x10\x0c\"p\n\x0bModemPreset\x12\x0c\n\x08LongFast\x10\x00\x12\x0c\n\x08LongSlow\x10\x01\x12\r\n\tVLongSlow\x10\x02\x12\x0b\n\x07MedSlow\x10\x03\x12\x0b\n\x07MedFast\x10\x04\x12\r\n\tShortSlow\x10\x05\x12\r\n\tShortFast\x10\x06\x42\x10\n\x0epayloadVariantBH\n\x13\x63om.geeksville.meshB\x0c\x43onfigProtosH\x03Z!github.com/meshtastic/gomeshprotob\x06proto3')
_CONFIG = DESCRIPTOR.message_types_by_name['Config']
_CONFIG_DEVICECONFIG = _CONFIG.nested_types_by_name['DeviceConfig']
_CONFIG_POSITIONCONFIG = _CONFIG.nested_types_by_name['PositionConfig']
_CONFIG_POWERCONFIG = _CONFIG.nested_types_by_name['PowerConfig']
_CONFIG_WIFICONFIG = _CONFIG.nested_types_by_name['WiFiConfig']
_CONFIG_DISPLAYCONFIG = _CONFIG.nested_types_by_name['DisplayConfig']
_CONFIG_LORACONFIG = _CONFIG.nested_types_by_name['LoRaConfig']
_CONFIG_DEVICECONFIG_ROLE = _CONFIG_DEVICECONFIG.enum_types_by_name['Role']
_CONFIG_POSITIONCONFIG_POSITIONFLAGS = _CONFIG_POSITIONCONFIG.enum_types_by_name['PositionFlags']
_CONFIG_POWERCONFIG_CHARGECURRENT = _CONFIG_POWERCONFIG.enum_types_by_name['ChargeCurrent']
_CONFIG_DISPLAYCONFIG_GPSCOORDINATEFORMAT = _CONFIG_DISPLAYCONFIG.enum_types_by_name['GpsCoordinateFormat']
_CONFIG_LORACONFIG_REGIONCODE = _CONFIG_LORACONFIG.enum_types_by_name['RegionCode']
_CONFIG_LORACONFIG_MODEMPRESET = _CONFIG_LORACONFIG.enum_types_by_name['ModemPreset']
Config = _reflection.GeneratedProtocolMessageType('Config', (_message.Message,), {
'DeviceConfig' : _reflection.GeneratedProtocolMessageType('DeviceConfig', (_message.Message,), {
'DESCRIPTOR' : _CONFIG_DEVICECONFIG,
'__module__' : 'config_pb2'
# @@protoc_insertion_point(class_scope:Config.DeviceConfig)
})
,
'PositionConfig' : _reflection.GeneratedProtocolMessageType('PositionConfig', (_message.Message,), {
'DESCRIPTOR' : _CONFIG_POSITIONCONFIG,
'__module__' : 'config_pb2'
# @@protoc_insertion_point(class_scope:Config.PositionConfig)
})
,
'PowerConfig' : _reflection.GeneratedProtocolMessageType('PowerConfig', (_message.Message,), {
'DESCRIPTOR' : _CONFIG_POWERCONFIG,
'__module__' : 'config_pb2'
# @@protoc_insertion_point(class_scope:Config.PowerConfig)
})
,
'WiFiConfig' : _reflection.GeneratedProtocolMessageType('WiFiConfig', (_message.Message,), {
'DESCRIPTOR' : _CONFIG_WIFICONFIG,
'__module__' : 'config_pb2'
# @@protoc_insertion_point(class_scope:Config.WiFiConfig)
})
,
'DisplayConfig' : _reflection.GeneratedProtocolMessageType('DisplayConfig', (_message.Message,), {
'DESCRIPTOR' : _CONFIG_DISPLAYCONFIG,
'__module__' : 'config_pb2'
# @@protoc_insertion_point(class_scope:Config.DisplayConfig)
})
,
'LoRaConfig' : _reflection.GeneratedProtocolMessageType('LoRaConfig', (_message.Message,), {
'DESCRIPTOR' : _CONFIG_LORACONFIG,
'__module__' : 'config_pb2'
# @@protoc_insertion_point(class_scope:Config.LoRaConfig)
})
,
'DESCRIPTOR' : _CONFIG,
'__module__' : 'config_pb2'
# @@protoc_insertion_point(class_scope:Config)
})
_sym_db.RegisterMessage(Config)
_sym_db.RegisterMessage(Config.DeviceConfig)
_sym_db.RegisterMessage(Config.PositionConfig)
_sym_db.RegisterMessage(Config.PowerConfig)
_sym_db.RegisterMessage(Config.WiFiConfig)
_sym_db.RegisterMessage(Config.DisplayConfig)
_sym_db.RegisterMessage(Config.LoRaConfig)
if _descriptor._USE_C_DESCRIPTORS == False:
DESCRIPTOR._options = None
DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\014ConfigProtosH\003Z!github.com/meshtastic/gomeshproto'
_CONFIG._serialized_start=17
_CONFIG._serialized_end=2313
_CONFIG_DEVICECONFIG._serialized_start=264
_CONFIG_DEVICECONFIG._serialized_end=480
_CONFIG_DEVICECONFIG_ROLE._serialized_start=416
_CONFIG_DEVICECONFIG_ROLE._serialized_end=480
_CONFIG_POSITIONCONFIG._serialized_start=483
_CONFIG_POSITIONCONFIG._serialized_end=907
_CONFIG_POSITIONCONFIG_POSITIONFLAGS._serialized_start=703
_CONFIG_POSITIONCONFIG_POSITIONFLAGS._serialized_end=907
_CONFIG_POWERCONFIG._serialized_start=910
_CONFIG_POWERCONFIG._serialized_end=1410
_CONFIG_POWERCONFIG_CHARGECURRENT._serialized_start=1201
_CONFIG_POWERCONFIG_CHARGECURRENT._serialized_end=1410
_CONFIG_WIFICONFIG._serialized_start=1412
_CONFIG_WIFICONFIG._serialized_end=1487
_CONFIG_DISPLAYCONFIG._serialized_start=1490
_CONFIG_DISPLAYCONFIG._serialized_end=1761
_CONFIG_DISPLAYCONFIG_GPSCOORDINATEFORMAT._serialized_start=1630
_CONFIG_DISPLAYCONFIG_GPSCOORDINATEFORMAT._serialized_end=1761
_CONFIG_LORACONFIG._serialized_start=1764
_CONFIG_LORACONFIG._serialized_end=2295
_CONFIG_LORACONFIG_REGIONCODE._serialized_start=2052
_CONFIG_LORACONFIG_REGIONCODE._serialized_end=2181
_CONFIG_LORACONFIG_MODEMPRESET._serialized_start=2183
_CONFIG_LORACONFIG_MODEMPRESET._serialized_end=2295
# @@protoc_insertion_point(module_scope)

View File

@@ -2,7 +2,6 @@
# Generated by the protocol buffer compiler. DO NOT EDIT!
# source: deviceonly.proto
"""Generated protocol buffer code."""
from google.protobuf.internal import enum_type_wrapper
from google.protobuf import descriptor as _descriptor
from google.protobuf import descriptor_pool as _descriptor_pool
from google.protobuf import message as _message
@@ -15,20 +14,32 @@ _sym_db = _symbol_database.Default()
from . import channel_pb2 as channel__pb2
from . import mesh_pb2 as mesh__pb2
from . import radioconfig_pb2 as radioconfig__pb2
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x10\x64\x65viceonly.proto\x1a\rchannel.proto\x1a\nmesh.proto\"\xe6\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(\x08J\x04\x08\x0c\x10\r\":\n\x0b\x43hannelFile\x12\x1a\n\x08\x63hannels\x18\x01 \x03(\x0b\x32\x08.Channel\x12\x0f\n\x07version\x18\x02 \x01(\r\"\x84\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*>\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\x46\n\x13\x63om.geeksville.meshB\nDeviceOnlyH\x03Z!github.com/meshtastic/gomeshprotob\x06proto3')
_SCREENFONTS = DESCRIPTOR.enum_types_by_name['ScreenFonts']
ScreenFonts = enum_type_wrapper.EnumTypeWrapper(_SCREENFONTS)
FONT_SMALL = 0
FONT_MEDIUM = 1
FONT_LARGE = 2
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x10\x64\x65viceonly.proto\x1a\rchannel.proto\x1a\nmesh.proto\x1a\x11radioconfig.proto\"\x80\x01\n\x11LegacyRadioConfig\x12\x39\n\x0bpreferences\x18\x01 \x01(\x0b\x32$.LegacyRadioConfig.LegacyPreferences\x1a\x30\n\x11LegacyPreferences\x12\x1b\n\x06region\x18\x0f \x01(\x0e\x32\x0b.RegionCode\"\x8f\x02\n\x0b\x44\x65viceState\x12\'\n\x0blegacyRadio\x18\x01 \x01(\x0b\x32\x12.LegacyRadioConfig\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(\x08J\x04\x08\x0c\x10\r\")\n\x0b\x43hannelFile\x12\x1a\n\x08\x63hannels\x18\x01 \x03(\x0b\x32\x08.ChannelBF\n\x13\x63om.geeksville.meshB\nDeviceOnlyH\x03Z!github.com/meshtastic/gomeshprotob\x06proto3')
_LEGACYRADIOCONFIG = DESCRIPTOR.message_types_by_name['LegacyRadioConfig']
_LEGACYRADIOCONFIG_LEGACYPREFERENCES = _LEGACYRADIOCONFIG.nested_types_by_name['LegacyPreferences']
_DEVICESTATE = DESCRIPTOR.message_types_by_name['DeviceState']
_CHANNELFILE = DESCRIPTOR.message_types_by_name['ChannelFile']
_OEMSTORE = DESCRIPTOR.message_types_by_name['OEMStore']
LegacyRadioConfig = _reflection.GeneratedProtocolMessageType('LegacyRadioConfig', (_message.Message,), {
'LegacyPreferences' : _reflection.GeneratedProtocolMessageType('LegacyPreferences', (_message.Message,), {
'DESCRIPTOR' : _LEGACYRADIOCONFIG_LEGACYPREFERENCES,
'__module__' : 'deviceonly_pb2'
# @@protoc_insertion_point(class_scope:LegacyRadioConfig.LegacyPreferences)
})
,
'DESCRIPTOR' : _LEGACYRADIOCONFIG,
'__module__' : 'deviceonly_pb2'
# @@protoc_insertion_point(class_scope:LegacyRadioConfig)
})
_sym_db.RegisterMessage(LegacyRadioConfig)
_sym_db.RegisterMessage(LegacyRadioConfig.LegacyPreferences)
DeviceState = _reflection.GeneratedProtocolMessageType('DeviceState', (_message.Message,), {
'DESCRIPTOR' : _DEVICESTATE,
'__module__' : 'deviceonly_pb2'
@@ -43,23 +54,16 @@ ChannelFile = _reflection.GeneratedProtocolMessageType('ChannelFile', (_message.
})
_sym_db.RegisterMessage(ChannelFile)
OEMStore = _reflection.GeneratedProtocolMessageType('OEMStore', (_message.Message,), {
'DESCRIPTOR' : _OEMSTORE,
'__module__' : 'deviceonly_pb2'
# @@protoc_insertion_point(class_scope:OEMStore)
})
_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/gomeshproto'
_SCREENFONTS._serialized_start=475
_SCREENFONTS._serialized_end=537
_DEVICESTATE._serialized_start=48
_DEVICESTATE._serialized_end=278
_CHANNELFILE._serialized_start=280
_CHANNELFILE._serialized_end=338
_OEMSTORE._serialized_start=341
_OEMSTORE._serialized_end=473
_LEGACYRADIOCONFIG._serialized_start=67
_LEGACYRADIOCONFIG._serialized_end=195
_LEGACYRADIOCONFIG_LEGACYPREFERENCES._serialized_start=147
_LEGACYRADIOCONFIG_LEGACYPREFERENCES._serialized_end=195
_DEVICESTATE._serialized_start=198
_DEVICESTATE._serialized_end=469
_CHANNELFILE._serialized_start=471
_CHANNELFILE._serialized_end=512
# @@protoc_insertion_point(module_scope)

View File

@@ -0,0 +1,35 @@
# -*- coding: utf-8 -*-
# Generated by the protocol buffer compiler. DO NOT EDIT!
# source: environmental_measurement.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\x1f\x65nvironmental_measurement.proto\"\xa1\x01\n\x18\x45nvironmentalMeasurement\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\x42#Z!github.com/meshtastic/gomeshprotob\x06proto3')
_ENVIRONMENTALMEASUREMENT = DESCRIPTOR.message_types_by_name['EnvironmentalMeasurement']
EnvironmentalMeasurement = _reflection.GeneratedProtocolMessageType('EnvironmentalMeasurement', (_message.Message,), {
'DESCRIPTOR' : _ENVIRONMENTALMEASUREMENT,
'__module__' : 'environmental_measurement_pb2'
# @@protoc_insertion_point(class_scope:EnvironmentalMeasurement)
})
_sym_db.RegisterMessage(EnvironmentalMeasurement)
if _descriptor._USE_C_DESCRIPTORS == False:
DESCRIPTOR._options = None
DESCRIPTOR._serialized_options = b'Z!github.com/meshtastic/gomeshproto'
_ENVIRONMENTALMEASUREMENT._serialized_start=36
_ENVIRONMENTALMEASUREMENT._serialized_end=197
# @@protoc_insertion_point(module_scope)

View File

@@ -1,47 +0,0 @@
# -*- coding: utf-8 -*-
# Generated by the protocol buffer compiler. DO NOT EDIT!
# source: localonly.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()
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\"\xfe\x01\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\x04wifi\x18\x04 \x01(\x0b\x32\x12.Config.WiFiConfig\x12&\n\x07\x64isplay\x18\x05 \x01(\x0b\x32\x15.Config.DisplayConfig\x12 \n\x04lora\x18\x06 \x01(\x0b\x32\x12.Config.LoRaConfig\x12\x0f\n\x07version\x18\x07 \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(\rBK\n\x13\x63om.geeksville.meshB\x0fLocalOnlyProtosH\x03Z!github.com/meshtastic/gomeshprotob\x06proto3')
_LOCALCONFIG = DESCRIPTOR.message_types_by_name['LocalConfig']
_LOCALMODULECONFIG = DESCRIPTOR.message_types_by_name['LocalModuleConfig']
LocalConfig = _reflection.GeneratedProtocolMessageType('LocalConfig', (_message.Message,), {
'DESCRIPTOR' : _LOCALCONFIG,
'__module__' : 'localonly_pb2'
# @@protoc_insertion_point(class_scope:LocalConfig)
})
_sym_db.RegisterMessage(LocalConfig)
LocalModuleConfig = _reflection.GeneratedProtocolMessageType('LocalModuleConfig', (_message.Message,), {
'DESCRIPTOR' : _LOCALMODULECONFIG,
'__module__' : 'localonly_pb2'
# @@protoc_insertion_point(class_scope:LocalModuleConfig)
})
_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/gomeshproto'
_LOCALCONFIG._serialized_start=55
_LOCALCONFIG._serialized_end=309
_LOCALMODULECONFIG._serialized_start=312
_LOCALMODULECONFIG._serialized_end=722
# @@protoc_insertion_point(module_scope)

View File

@@ -422,8 +422,8 @@ class MeshInterface:
"""We need to send a heartbeat message to the device every X seconds"""
def callback():
self.heartbeatTimer = None
prefs = self.localNode.localConfig
i = prefs.power.ls_secs / 2
prefs = self.localNode.radioConfig.preferences
i = prefs.phone_timeout_secs / 2
logging.debug(f"Sending heartbeat, interval {i}")
if i != 0:
self.heartbeatTimer = threading.Timer(i, callback)
@@ -532,44 +532,14 @@ class MeshInterface:
# stream API fromRadio.config_complete_id
logging.debug(f"Config complete ID {self.configId}")
self._handleConfigComplete()
elif fromRadio.HasField("packet"):
self._handlePacketFromRadio(fromRadio.packet)
elif fromRadio.rebooted:
# Tell clients the device went away. Careful not to call the overridden
# subclass version that closes the serial port
MeshInterface._disconnected(self)
self._startConfig() # redownload the node db etc...
elif fromRadio.config or fromRadio.moduleConfig:
if fromRadio.config.HasField("device"):
self.localNode.localConfig.device.CopyFrom(fromRadio.config.device)
elif fromRadio.config.HasField("position"):
self.localNode.localConfig.position.CopyFrom(fromRadio.config.position)
elif fromRadio.config.HasField("power"):
self.localNode.localConfig.power.CopyFrom(fromRadio.config.power)
elif fromRadio.config.HasField("wifi"):
self.localNode.localConfig.wifi.CopyFrom(fromRadio.config.wifi)
elif fromRadio.config.HasField("display"):
self.localNode.localConfig.display.CopyFrom(fromRadio.config.display)
elif fromRadio.config.HasField("lora"):
self.localNode.localConfig.lora.CopyFrom(fromRadio.config.lora)
elif fromRadio.moduleConfig.HasField("mqtt"):
self.localNode.moduleConfig.mqtt.CopyFrom(fromRadio.moduleConfig.mqtt)
elif fromRadio.moduleConfig.HasField("serial"):
self.localNode.moduleConfig.serial.CopyFrom(fromRadio.moduleConfig.serial)
elif fromRadio.moduleConfig.HasField("external_notification"):
self.localNode.moduleConfig.external_notification.CopyFrom(fromRadio.moduleConfig.external_notification)
elif fromRadio.moduleConfig.HasField("range_test"):
self.localNode.moduleConfig.range_test.CopyFrom(fromRadio.moduleConfig.range_test)
elif fromRadio.moduleConfig.HasField("telemetry"):
self.localNode.moduleConfig.telemetry.CopyFrom(fromRadio.moduleConfig.telemetry)
elif fromRadio.moduleConfig.HasField("canned_message"):
self.localNode.moduleConfig.canned_message.CopyFrom(fromRadio.moduleConfig.canned_message)
else:
logging.debug("Unexpected FromRadio payload")

View File

File diff suppressed because one or more lines are too long

View File

@@ -1,122 +0,0 @@
# -*- coding: utf-8 -*-
# Generated by the protocol buffer compiler. DO NOT EDIT!
# source: module_config.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()
from . import telemetry_pb2 as telemetry__pb2
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x13module_config.proto\x1a\x0ftelemetry.proto\"\xd7\x12\n\x0cModuleConfig\x12(\n\x04mqtt\x18\x01 \x01(\x0b\x32\x18.ModuleConfig.MQTTConfigH\x00\x12,\n\x06serial\x18\x02 \x01(\x0b\x32\x1a.ModuleConfig.SerialConfigH\x00\x12I\n\x15\x65xternal_notification\x18\x03 \x01(\x0b\x32(.ModuleConfig.ExternalNotificationConfigH\x00\x12\x39\n\rstore_forward\x18\x04 \x01(\x0b\x32 .ModuleConfig.StoreForwardConfigH\x00\x12\x33\n\nrange_test\x18\x05 \x01(\x0b\x32\x1d.ModuleConfig.RangeTestConfigH\x00\x12\x32\n\ttelemetry\x18\x06 \x01(\x0b\x32\x1d.ModuleConfig.TelemetryConfigH\x00\x12;\n\x0e\x63\x61nned_message\x18\x07 \x01(\x0b\x32!.ModuleConfig.CannedMessageConfigH\x00\x1ao\n\nMQTTConfig\x12\x10\n\x08\x64isabled\x18\x01 \x01(\x08\x12\x0f\n\x07\x61\x64\x64ress\x18\x02 \x01(\t\x12\x10\n\x08username\x18\x03 \x01(\t\x12\x10\n\x08password\x18\x04 \x01(\t\x12\x1a\n\x12\x65ncryption_enabled\x18\x05 \x01(\x08\x1a\x93\x04\n\x0cSerialConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x0c\n\x04\x65\x63ho\x18\x02 \x01(\x08\x12\x0b\n\x03rxd\x18\x03 \x01(\r\x12\x0b\n\x03txd\x18\x04 \x01(\r\x12\x34\n\x04\x62\x61ud\x18\x05 \x01(\x0e\x32&.ModuleConfig.SerialConfig.Serial_Baud\x12\x0f\n\x07timeout\x18\x06 \x01(\r\x12\x34\n\x04mode\x18\x07 \x01(\x0e\x32&.ModuleConfig.SerialConfig.Serial_Mode\"\x8a\x02\n\x0bSerial_Baud\x12\x10\n\x0c\x42\x41UD_Default\x10\x00\x12\x0c\n\x08\x42\x41UD_110\x10\x01\x12\x0c\n\x08\x42\x41UD_300\x10\x02\x12\x0c\n\x08\x42\x41UD_600\x10\x03\x12\r\n\tBAUD_1200\x10\x04\x12\r\n\tBAUD_2400\x10\x05\x12\r\n\tBAUD_4800\x10\x06\x12\r\n\tBAUD_9600\x10\x07\x12\x0e\n\nBAUD_19200\x10\x08\x12\x0e\n\nBAUD_38400\x10\t\x12\x0e\n\nBAUD_57600\x10\n\x12\x0f\n\x0b\x42\x41UD_115200\x10\x0b\x12\x0f\n\x0b\x42\x41UD_230400\x10\x0c\x12\x0f\n\x0b\x42\x41UD_460800\x10\r\x12\x0f\n\x0b\x42\x41UD_576000\x10\x0e\x12\x0f\n\x0b\x42\x41UD_921600\x10\x0f\"@\n\x0bSerial_Mode\x12\x10\n\x0cMODE_Default\x10\x00\x12\x0f\n\x0bMODE_SIMPLE\x10\x01\x12\x0e\n\nMODE_PROTO\x10\x02\x1a\x8b\x01\n\x1a\x45xternalNotificationConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x11\n\toutput_ms\x18\x02 \x01(\r\x12\x0e\n\x06output\x18\x03 \x01(\r\x12\x0e\n\x06\x61\x63tive\x18\x04 \x01(\x08\x12\x15\n\ralert_message\x18\x05 \x01(\x08\x12\x12\n\nalert_bell\x18\x06 \x01(\x08\x1a\x84\x01\n\x12StoreForwardConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x11\n\theartbeat\x18\x02 \x01(\x08\x12\x0f\n\x07records\x18\x03 \x01(\r\x12\x1a\n\x12history_return_max\x18\x04 \x01(\r\x12\x1d\n\x15history_return_window\x18\x05 \x01(\r\x1a@\n\x0fRangeTestConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x0e\n\x06sender\x18\x02 \x01(\r\x12\x0c\n\x04save\x18\x03 \x01(\x08\x1a\xf9\x02\n\x0fTelemetryConfig\x12\x1e\n\x16\x64\x65vice_update_interval\x18\x01 \x01(\r\x12#\n\x1b\x65nvironment_update_interval\x18\x02 \x01(\r\x12\'\n\x1f\x65nvironment_measurement_enabled\x18\x03 \x01(\x08\x12\"\n\x1a\x65nvironment_screen_enabled\x18\x04 \x01(\x08\x12.\n&environment_read_error_count_threshold\x18\x05 \x01(\r\x12%\n\x1d\x65nvironment_recovery_interval\x18\x06 \x01(\r\x12&\n\x1e\x65nvironment_display_fahrenheit\x18\x07 \x01(\x08\x12\x35\n\x17\x65nvironment_sensor_type\x18\x08 \x01(\x0e\x32\x14.TelemetrySensorType\x12\x1e\n\x16\x65nvironment_sensor_pin\x18\t \x01(\r\x1a\xd6\x04\n\x13\x43\x61nnedMessageConfig\x12\x17\n\x0frotary1_enabled\x18\x01 \x01(\x08\x12\x19\n\x11inputbroker_pin_a\x18\x02 \x01(\r\x12\x19\n\x11inputbroker_pin_b\x18\x03 \x01(\r\x12\x1d\n\x15inputbroker_pin_press\x18\x04 \x01(\r\x12N\n\x14inputbroker_event_cw\x18\x05 \x01(\x0e\x32\x30.ModuleConfig.CannedMessageConfig.InputEventChar\x12O\n\x15inputbroker_event_ccw\x18\x06 \x01(\x0e\x32\x30.ModuleConfig.CannedMessageConfig.InputEventChar\x12Q\n\x17inputbroker_event_press\x18\x07 \x01(\x0e\x32\x30.ModuleConfig.CannedMessageConfig.InputEventChar\x12\x17\n\x0fupdown1_enabled\x18\x08 \x01(\x08\x12\x0f\n\x07\x65nabled\x18\t \x01(\x08\x12\x1a\n\x12\x61llow_input_source\x18\n \x01(\t\x12\x11\n\tsend_bell\x18\x0b \x01(\x08\"\x83\x01\n\x0eInputEventChar\x12\x0c\n\x08KEY_NONE\x10\x00\x12\n\n\x06KEY_UP\x10\x11\x12\x0c\n\x08KEY_DOWN\x10\x12\x12\x0c\n\x08KEY_LEFT\x10\x13\x12\r\n\tKEY_RIGHT\x10\x14\x12\x0e\n\nKEY_SELECT\x10\n\x12\x0c\n\x08KEY_BACK\x10\x1b\x12\x0e\n\nKEY_CANCEL\x10\x18\x42\x10\n\x0epayloadVariantBN\n\x13\x63om.geeksville.meshB\x12ModuleConfigProtosH\x03Z!github.com/meshtastic/gomeshprotob\x06proto3')
_MODULECONFIG = DESCRIPTOR.message_types_by_name['ModuleConfig']
_MODULECONFIG_MQTTCONFIG = _MODULECONFIG.nested_types_by_name['MQTTConfig']
_MODULECONFIG_SERIALCONFIG = _MODULECONFIG.nested_types_by_name['SerialConfig']
_MODULECONFIG_EXTERNALNOTIFICATIONCONFIG = _MODULECONFIG.nested_types_by_name['ExternalNotificationConfig']
_MODULECONFIG_STOREFORWARDCONFIG = _MODULECONFIG.nested_types_by_name['StoreForwardConfig']
_MODULECONFIG_RANGETESTCONFIG = _MODULECONFIG.nested_types_by_name['RangeTestConfig']
_MODULECONFIG_TELEMETRYCONFIG = _MODULECONFIG.nested_types_by_name['TelemetryConfig']
_MODULECONFIG_CANNEDMESSAGECONFIG = _MODULECONFIG.nested_types_by_name['CannedMessageConfig']
_MODULECONFIG_SERIALCONFIG_SERIAL_BAUD = _MODULECONFIG_SERIALCONFIG.enum_types_by_name['Serial_Baud']
_MODULECONFIG_SERIALCONFIG_SERIAL_MODE = _MODULECONFIG_SERIALCONFIG.enum_types_by_name['Serial_Mode']
_MODULECONFIG_CANNEDMESSAGECONFIG_INPUTEVENTCHAR = _MODULECONFIG_CANNEDMESSAGECONFIG.enum_types_by_name['InputEventChar']
ModuleConfig = _reflection.GeneratedProtocolMessageType('ModuleConfig', (_message.Message,), {
'MQTTConfig' : _reflection.GeneratedProtocolMessageType('MQTTConfig', (_message.Message,), {
'DESCRIPTOR' : _MODULECONFIG_MQTTCONFIG,
'__module__' : 'module_config_pb2'
# @@protoc_insertion_point(class_scope:ModuleConfig.MQTTConfig)
})
,
'SerialConfig' : _reflection.GeneratedProtocolMessageType('SerialConfig', (_message.Message,), {
'DESCRIPTOR' : _MODULECONFIG_SERIALCONFIG,
'__module__' : 'module_config_pb2'
# @@protoc_insertion_point(class_scope:ModuleConfig.SerialConfig)
})
,
'ExternalNotificationConfig' : _reflection.GeneratedProtocolMessageType('ExternalNotificationConfig', (_message.Message,), {
'DESCRIPTOR' : _MODULECONFIG_EXTERNALNOTIFICATIONCONFIG,
'__module__' : 'module_config_pb2'
# @@protoc_insertion_point(class_scope:ModuleConfig.ExternalNotificationConfig)
})
,
'StoreForwardConfig' : _reflection.GeneratedProtocolMessageType('StoreForwardConfig', (_message.Message,), {
'DESCRIPTOR' : _MODULECONFIG_STOREFORWARDCONFIG,
'__module__' : 'module_config_pb2'
# @@protoc_insertion_point(class_scope:ModuleConfig.StoreForwardConfig)
})
,
'RangeTestConfig' : _reflection.GeneratedProtocolMessageType('RangeTestConfig', (_message.Message,), {
'DESCRIPTOR' : _MODULECONFIG_RANGETESTCONFIG,
'__module__' : 'module_config_pb2'
# @@protoc_insertion_point(class_scope:ModuleConfig.RangeTestConfig)
})
,
'TelemetryConfig' : _reflection.GeneratedProtocolMessageType('TelemetryConfig', (_message.Message,), {
'DESCRIPTOR' : _MODULECONFIG_TELEMETRYCONFIG,
'__module__' : 'module_config_pb2'
# @@protoc_insertion_point(class_scope:ModuleConfig.TelemetryConfig)
})
,
'CannedMessageConfig' : _reflection.GeneratedProtocolMessageType('CannedMessageConfig', (_message.Message,), {
'DESCRIPTOR' : _MODULECONFIG_CANNEDMESSAGECONFIG,
'__module__' : 'module_config_pb2'
# @@protoc_insertion_point(class_scope:ModuleConfig.CannedMessageConfig)
})
,
'DESCRIPTOR' : _MODULECONFIG,
'__module__' : 'module_config_pb2'
# @@protoc_insertion_point(class_scope:ModuleConfig)
})
_sym_db.RegisterMessage(ModuleConfig)
_sym_db.RegisterMessage(ModuleConfig.MQTTConfig)
_sym_db.RegisterMessage(ModuleConfig.SerialConfig)
_sym_db.RegisterMessage(ModuleConfig.ExternalNotificationConfig)
_sym_db.RegisterMessage(ModuleConfig.StoreForwardConfig)
_sym_db.RegisterMessage(ModuleConfig.RangeTestConfig)
_sym_db.RegisterMessage(ModuleConfig.TelemetryConfig)
_sym_db.RegisterMessage(ModuleConfig.CannedMessageConfig)
if _descriptor._USE_C_DESCRIPTORS == False:
DESCRIPTOR._options = None
DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\022ModuleConfigProtosH\003Z!github.com/meshtastic/gomeshproto'
_MODULECONFIG._serialized_start=41
_MODULECONFIG._serialized_end=2432
_MODULECONFIG_MQTTCONFIG._serialized_start=445
_MODULECONFIG_MQTTCONFIG._serialized_end=556
_MODULECONFIG_SERIALCONFIG._serialized_start=559
_MODULECONFIG_SERIALCONFIG._serialized_end=1090
_MODULECONFIG_SERIALCONFIG_SERIAL_BAUD._serialized_start=758
_MODULECONFIG_SERIALCONFIG_SERIAL_BAUD._serialized_end=1024
_MODULECONFIG_SERIALCONFIG_SERIAL_MODE._serialized_start=1026
_MODULECONFIG_SERIALCONFIG_SERIAL_MODE._serialized_end=1090
_MODULECONFIG_EXTERNALNOTIFICATIONCONFIG._serialized_start=1093
_MODULECONFIG_EXTERNALNOTIFICATIONCONFIG._serialized_end=1232
_MODULECONFIG_STOREFORWARDCONFIG._serialized_start=1235
_MODULECONFIG_STOREFORWARDCONFIG._serialized_end=1367
_MODULECONFIG_RANGETESTCONFIG._serialized_start=1369
_MODULECONFIG_RANGETESTCONFIG._serialized_end=1433
_MODULECONFIG_TELEMETRYCONFIG._serialized_start=1436
_MODULECONFIG_TELEMETRYCONFIG._serialized_end=1813
_MODULECONFIG_CANNEDMESSAGECONFIG._serialized_start=1816
_MODULECONFIG_CANNEDMESSAGECONFIG._serialized_end=2414
_MODULECONFIG_CANNEDMESSAGECONFIG_INPUTEVENTCHAR._serialized_start=2283
_MODULECONFIG_CANNEDMESSAGECONFIG_INPUTEVENTCHAR._serialized_end=2414
# @@protoc_insertion_point(module_scope)

View File

@@ -5,22 +5,21 @@ import logging
import base64
import time
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
from meshtastic.util import pskToString, stripnl, Timeout, our_exit, fromPSK
class Node:
"""A model of a (local or remote) node in the mesh
Includes methods for localConfig, moduleConfig and channels
Includes methods for radioConfig and channels
"""
def __init__(self, iface, nodeNum, noProto=False):
"""Constructor"""
self.iface = iface
self.nodeNum = nodeNum
self.localConfig = localonly_pb2.LocalConfig()
self.moduleConfig = localonly_pb2.LocalModuleConfig()
self.radioConfig = None
self.channels = None
self._timeout = Timeout(maxSecs=300)
self.partialChannels = None
@@ -55,22 +54,27 @@ class Node:
def showInfo(self):
"""Show human readable description of our node"""
prefs = ""
if self.localConfig:
prefs = stripnl(MessageToJson(self.localConfig))
if self.radioConfig and self.radioConfig.preferences:
prefs = stripnl(MessageToJson(self.radioConfig.preferences))
print(f"Preferences: {prefs}\n")
prefs = ""
if self.moduleConfig:
prefs = stripnl(MessageToJson(self.moduleConfig))
print(f"Module preferences: {prefs}\n")
self.showChannels()
def requestConfig(self):
"""Send regular MeshPackets to ask for settings and channels."""
logging.debug(f"requestConfig for nodeNum:{self.nodeNum}")
self.radioConfig = None
self.channels = None
self.partialChannels = [] # We keep our channels in a temp array until finished
self._requestChannel(0)
# Note: We do not get the canned plugin message, unless get_canned_message() is called
self.cannedPluginMessage = None
self.cannedPluginMessagePart1 = None
self.cannedPluginMessagePart2 = None
self.cannedPluginMessagePart3 = None
self.cannedPluginMessagePart4 = None
self._requestSettings()
def turnOffEncryptionOnPrimaryChannel(self):
"""Turn off encryption on primary channel."""
@@ -80,109 +84,25 @@ class Node:
def waitForConfig(self, attribute='channels'):
"""Block until radio config is received. Returns True if config has been received."""
return self._timeout.waitForSet(self, attrs=('localConfig', attribute))
return self._timeout.waitForSet(self, attrs=('radioConfig', attribute))
def writeConfig(self):
"""Write the current (edited) localConfig to the device"""
if self.localConfig is None:
our_exit("Error: No localConfig has been read")
"""Write the current (edited) radioConfig to the device"""
if self.radioConfig is None:
our_exit("Error: No RadioConfig has been read")
if self.localConfig.device:
p = admin_pb2.AdminMessage()
p.set_config.device.CopyFrom(self.localConfig.device)
self._sendAdmin(p)
logging.debug("Wrote device")
time.sleep(0.1)
p = admin_pb2.AdminMessage()
p.set_radio.CopyFrom(self.radioConfig)
if self.localConfig.position:
p = admin_pb2.AdminMessage()
p.set_config.position.CopyFrom(self.localConfig.position)
self._sendAdmin(p)
logging.debug("Wrote position")
time.sleep(0.1)
if self.localConfig.power:
p = admin_pb2.AdminMessage()
p.set_config.power.CopyFrom(self.localConfig.power)
self._sendAdmin(p)
logging.debug("Wrote power")
time.sleep(0.1)
if self.localConfig.wifi:
p = admin_pb2.AdminMessage()
p.set_config.wifi.CopyFrom(self.localConfig.wifi)
self._sendAdmin(p)
logging.debug("Wrote wifi")
time.sleep(0.1)
if self.localConfig.display:
p = admin_pb2.AdminMessage()
p.set_config.display.CopyFrom(self.localConfig.display)
self._sendAdmin(p)
logging.debug("Wrote display")
time.sleep(0.1)
if self.localConfig.lora:
p = admin_pb2.AdminMessage()
p.set_config.lora.CopyFrom(self.localConfig.lora)
self._sendAdmin(p)
logging.debug("Wrote lora")
time.sleep(0.1)
if self.moduleConfig.mqtt:
p = admin_pb2.AdminMessage()
p.set_module_config.mqtt.CopyFrom(self.moduleConfig.mqtt)
self._sendAdmin(p)
logging.debug("Wrote module: mqtt")
time.sleep(0.1)
if self.moduleConfig.serial:
p = admin_pb2.AdminMessage()
p.set_module_config.serial.CopyFrom(self.moduleConfig.serial)
self._sendAdmin(p)
logging.debug("Wrote module: serial")
time.sleep(0.1)
if self.moduleConfig.external_notification:
p = admin_pb2.AdminMessage()
p.set_module_config.external_notification.CopyFrom(self.moduleConfig.external_notification)
self._sendAdmin(p)
logging.debug("Wrote module: external_notification")
time.sleep(0.1)
if self.moduleConfig.store_forward:
p = admin_pb2.AdminMessage()
p.set_module_config.store_forward.CopyFrom(self.moduleConfig.store_forward)
self._sendAdmin(p)
logging.debug("Wrote module: store_forward")
time.sleep(0.1)
if self.moduleConfig.range_test:
p = admin_pb2.AdminMessage()
p.set_module_config.range_test.CopyFrom(self.moduleConfig.range_test)
self._sendAdmin(p)
logging.debug("Wrote module: range_test")
time.sleep(0.1)
if self.moduleConfig.telemetry:
p = admin_pb2.AdminMessage()
p.set_module_config.telemetry.CopyFrom(self.moduleConfig.telemetry)
self._sendAdmin(p)
logging.debug("Wrote module: telemetry")
time.sleep(0.1)
if self.moduleConfig.canned_message:
p = admin_pb2.AdminMessage()
p.set_module_config.canned_message.CopyFrom(self.moduleConfig.canned_message)
self._sendAdmin(p)
logging.debug("Wrote module: canned_message")
time.sleep(0.1)
self._sendAdmin(p)
logging.debug("Wrote config")
def writeChannel(self, channelIndex, adminIndex=0):
"""Write the current (edited) channel to the device"""
p = admin_pb2.AdminMessage()
p.set_channel.CopyFrom(self.channels[channelIndex])
self._sendAdmin(p, adminIndex=adminIndex)
logging.debug(f"Wrote channel {channelIndex}")
@@ -243,7 +163,7 @@ class Node:
else:
return 0
def setOwner(self, long_name=None, short_name=None, is_licensed=False):
def setOwner(self, long_name=None, short_name=None, is_licensed=False, team=None):
"""Set device owner name"""
logging.debug(f"in setOwner nodeNum:{self.nodeNum}")
nChars = 3
@@ -272,11 +192,14 @@ class Node:
short_name = short_name[:nChars]
p.set_owner.short_name = short_name
p.set_owner.is_licensed = is_licensed
if team is not None:
p.set_owner.team = team
# 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}')
logging.debug(f'p.set_owner.team:{p.set_owner.team}')
return self._sendAdmin(p)
def getURL(self, includeAll: bool = True):
@@ -289,12 +212,12 @@ class Node:
channelSet.settings.append(c.settings)
some_bytes = channelSet.SerializeToString()
s = base64.urlsafe_b64encode(some_bytes).decode('ascii')
return f"https://www.meshtastic.org/e/#{s}".replace("=", "")
return f"https://www.meshtastic.org/d/#{s}".replace("=", "")
def setURL(self, url):
"""Set mesh network URL"""
if self.localConfig is None:
our_exit("Warning: No Config has been read")
if self.radioConfig is None:
our_exit("Warning: No RadioConfig has been read")
# URLs are of the form https://www.meshtastic.org/d/#{base64_channel_set}
# Split on '/#' to find the base64 encoded channel settings
@@ -327,6 +250,42 @@ class Node:
self.writeChannel(ch.index)
i = i + 1
def onResponseRequestSettings(self, p):
"""Handle the response packet for requesting settings _requestSettings()"""
logging.debug(f'onResponseRequestSetting() 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:
self.radioConfig = p["decoded"]["admin"]["raw"].get_radio_response
logging.debug(f'self.radioConfig:{self.radioConfig}')
logging.debug("Received radio config, now fetching channels...")
self._timeout.reset() # We made foreward progress
self._requestChannel(0) # now start fetching channels
def _requestSettings(self):
"""Done with initial config messages, now send regular
MeshPackets to ask for settings."""
p = admin_pb2.AdminMessage()
p.get_radio_request = True
# TODO: should we check that localNode has an 'admin' channel?
# Show progress message for super slow operations
if self != self.iface.localNode:
print("Requesting preferences from remote node.")
print("Be sure:")
print(" 1. There is a SECONDARY channel named 'admin'.")
print(" 2. The '--seturl' was used to configure.")
print(" 3. All devices have the same modem config. (i.e., '--ch-longfast')")
print(" 4. All devices have been rebooted after all of the above. (optional, but recommended)")
print("Note: This could take a while (it requests remote channel configs, then writes config)")
return self._sendAdmin(p, wantResponse=True, onResponse=self.onResponseRequestSettings)
def onResponseRequestCannedMessagePluginMessagePart1(self, p):
"""Handle the response packet for requesting canned message plugin message part 1"""
logging.debug(f'onResponseRequestCannedMessagePluginMessagePart1() p:{p}')
@@ -339,7 +298,7 @@ class Node:
if "decoded" in p:
if "admin" in p["decoded"]:
if "raw" in p["decoded"]["admin"]:
self.cannedPluginMessagePart1 = p["decoded"]["admin"]["raw"].get_canned_message_module_part1_response
self.cannedPluginMessagePart1 = p["decoded"]["admin"]["raw"].get_canned_message_plugin_part1_response
logging.debug(f'self.cannedPluginMessagePart1:{self.cannedPluginMessagePart1}')
self.gotResponse = True
@@ -355,7 +314,7 @@ class Node:
if "decoded" in p:
if "admin" in p["decoded"]:
if "raw" in p["decoded"]["admin"]:
self.cannedPluginMessagePart2 = p["decoded"]["admin"]["raw"].get_canned_message_module_part2_response
self.cannedPluginMessagePart2 = p["decoded"]["admin"]["raw"].get_canned_message_plugin_part2_response
logging.debug(f'self.cannedPluginMessagePart2:{self.cannedPluginMessagePart2}')
self.gotResponse = True
@@ -371,7 +330,7 @@ class Node:
if "decoded" in p:
if "admin" in p["decoded"]:
if "raw" in p["decoded"]["admin"]:
self.cannedPluginMessagePart3 = p["decoded"]["admin"]["raw"].get_canned_message_module_part3_response
self.cannedPluginMessagePart3 = p["decoded"]["admin"]["raw"].get_canned_message_plugin_part3_response
logging.debug(f'self.cannedPluginMessagePart3:{self.cannedPluginMessagePart3}')
self.gotResponse = True
@@ -387,7 +346,7 @@ class Node:
if "decoded" in p:
if "admin" in p["decoded"]:
if "raw" in p["decoded"]["admin"]:
self.cannedPluginMessagePart4 = p["decoded"]["admin"]["raw"].get_canned_message_module_part4_response
self.cannedPluginMessagePart4 = p["decoded"]["admin"]["raw"].get_canned_message_plugin_part4_response
logging.debug(f'self.cannedPluginMessagePart4:{self.cannedPluginMessagePart4}')
self.gotResponse = True
@@ -397,28 +356,28 @@ class Node:
if not self.cannedPluginMessage:
p1 = admin_pb2.AdminMessage()
p1.get_canned_message_module_part1_request = True
p1.get_canned_message_plugin_part1_request = True
self.gotResponse = False
self._sendAdmin(p1, wantResponse=True, onResponse=self.onResponseRequestCannedMessagePluginMessagePart1)
while self.gotResponse is False:
time.sleep(0.1)
p2 = admin_pb2.AdminMessage()
p2.get_canned_message_module_part2_request = True
p2.get_canned_message_plugin_part2_request = True
self.gotResponse = False
self._sendAdmin(p2, wantResponse=True, onResponse=self.onResponseRequestCannedMessagePluginMessagePart2)
while self.gotResponse is False:
time.sleep(0.1)
p3 = admin_pb2.AdminMessage()
p3.get_canned_message_module_part3_request = True
p3.get_canned_message_plugin_part3_request = True
self.gotResponse = False
self._sendAdmin(p3, wantResponse=True, onResponse=self.onResponseRequestCannedMessagePluginMessagePart3)
while self.gotResponse is False:
time.sleep(0.1)
p4 = admin_pb2.AdminMessage()
p4.get_canned_message_module_part4_request = True
p4.get_canned_message_plugin_part4_request = True
self.gotResponse = False
self._sendAdmin(p4, wantResponse=True, onResponse=self.onResponseRequestCannedMessagePluginMessagePart4)
while self.gotResponse is False:
@@ -466,13 +425,13 @@ class Node:
# TODO: should be a way to improve this
if i == 0:
p.set_canned_message_module_part1 = chunk
p.set_canned_message_plugin_part1 = chunk
elif i == 1:
p.set_canned_message_module_part2 = chunk
p.set_canned_message_plugin_part2 = chunk
elif i == 2:
p.set_canned_message_module_part3 = chunk
p.set_canned_message_plugin_part3 = chunk
elif i == 3:
p.set_canned_message_module_part4 = chunk
p.set_canned_message_plugin_part4 = chunk
logging.debug(f"Setting canned message '{chunk}' part {i+1}")
self._sendAdmin(p)

View File

@@ -15,7 +15,7 @@ _sym_db = _symbol_database.Default()
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x0eportnums.proto*\xee\x02\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\x10\n\x0bPRIVATE_APP\x10\x80\x02\x12\x13\n\x0e\x41TAK_FORWARDER\x10\x81\x02\x12\x08\n\x03MAX\x10\xff\x03\x42\x44\n\x13\x63om.geeksville.meshB\x08PortnumsH\x03Z!github.com/meshtastic/gomeshprotob\x06proto3')
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x0eportnums.proto*\xcb\x02\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\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!\n\x1d\x45NVIRONMENTAL_MEASUREMENT_APP\x10\x43\x12\x0b\n\x07ZPS_APP\x10\x44\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\x44\n\x13\x63om.geeksville.meshB\x08PortnumsH\x03Z!github.com/meshtastic/gomeshprotob\x06proto3')
_PORTNUM = DESCRIPTOR.enum_types_by_name['PortNum']
PortNum = enum_type_wrapper.EnumTypeWrapper(_PORTNUM)
@@ -26,14 +26,12 @@ POSITION_APP = 3
NODEINFO_APP = 4
ROUTING_APP = 5
ADMIN_APP = 6
TEXT_MESSAGE_COMPRESSED_APP = 7
WAYPOINT_APP = 8
REPLY_APP = 32
IP_TUNNEL_APP = 33
SERIAL_APP = 64
STORE_FORWARD_APP = 65
RANGE_TEST_APP = 66
TELEMETRY_APP = 67
ENVIRONMENTAL_MEASUREMENT_APP = 67
ZPS_APP = 68
PRIVATE_APP = 256
ATAK_FORWARDER = 257
@@ -45,5 +43,5 @@ if _descriptor._USE_C_DESCRIPTORS == False:
DESCRIPTOR._options = None
DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\010PortnumsH\003Z!github.com/meshtastic/gomeshproto'
_PORTNUM._serialized_start=19
_PORTNUM._serialized_end=385
_PORTNUM._serialized_end=350
# @@protoc_insertion_point(module_scope)

View File

File diff suppressed because one or more lines are too long

View File

@@ -50,7 +50,7 @@ class SerialInterface(StreamInterface):
f.close()
time.sleep(0.1)
self.stream = serial.Serial(self.devPath, 115200, exclusive=True, timeout=0.5, write_timeout=0)
self.stream = serial.Serial(self.devPath, 921600, exclusive=True, timeout=0.5, write_timeout=0)
self.stream.flush()
time.sleep(0.1)

View File

@@ -131,9 +131,9 @@ class StreamInterface(MeshInterface):
try:
while not self._wantExit:
#logging.debug("reading character")
logging.debug("reading character")
b = self._readBytes(1)
#logging.debug("In reader loop")
logging.debug("In reader loop")
#logging.debug(f"read returned {b}")
if len(b) > 0:
c = b[0]

View File

@@ -47,6 +47,9 @@ tlora_v1_3 = SupportedDevice(name="T-Lora", version="1.3", for_firmware="tlora-v
tlora_v2 = SupportedDevice(name="T-Lora", version="2", for_firmware="tlora-v2",
baseport_on_linux="ttyACM", baseport_on_mac="cu.usbmodem",
usb_vendor_id_in_hex="1a86", usb_product_id_in_hex="55d4")
tlora_v2_1 = SupportedDevice(name="T-Lora", version="2.1", for_firmware="tlora-v2-1",
baseport_on_linux="ttyACM", baseport_on_mac="cu.usbmodem",
usb_vendor_id_in_hex="1a86", usb_product_id_in_hex="55d4")
tlora_v2_1_1_6 = SupportedDevice(name="T-Lora", version="2.1-1.6", for_firmware="tlora-v2-1-1.6",
baseport_on_linux="ttyACM", baseport_on_mac="cu.usbmodem",
usb_vendor_id_in_hex="1a86", usb_product_id_in_hex="55d4")
@@ -73,10 +76,6 @@ rak4631_5005 = SupportedDevice(name="RAK 4631 5005", version="", for_firmware="r
device_class="nrf52",
baseport_on_linux="ttyACM", baseport_on_mac="cu.usbmodem",
usb_vendor_id_in_hex="239a", usb_product_id_in_hex="0029")
rak4631_5005_epaper = SupportedDevice(name="RAK 4631 5005 14000 epaper", version="", for_firmware="rak4631_5005_epaper",
device_class="nrf52",
baseport_on_linux="ttyACM", baseport_on_mac="cu.usbmodem",
usb_vendor_id_in_hex="239a", usb_product_id_in_hex="0029")
# Note: The 19003 reports same product id as 5005 in boot mode
rak4631_19003 = SupportedDevice(name="RAK 4631 19003", version="", for_firmware="rak4631_19003",
device_class="nrf52",
@@ -87,7 +86,7 @@ nano_g1 = SupportedDevice(name="Nano G1", version="", for_firmware="nano-g1",
usb_vendor_id_in_hex="1a86", usb_product_id_in_hex="55d4")
supported_devices = [tbeam_v0_7, tbeam_v1_1, tbeam_M8N, tbeam_M8N_SX1262,
tlora_v1, tlora_v1_3, tlora_v2, tlora_v2_1_1_6,
tlora_v1, tlora_v1_3, tlora_v2, tlora_v2_1, tlora_v2_1_1_6,
heltec_v1, heltec_v2_0, heltec_v2_1,
meshtastic_diy_v1, techo_1, rak4631_5005, rak4631_5005_epaper, rak4631_19003,
meshtastic_diy_v1, techo_1, rak4631_5005, rak4631_19003,
rak11200, nano_g1]

View File

@@ -1,72 +0,0 @@
# -*- coding: utf-8 -*-
# Generated by the protocol buffer compiler. DO NOT EDIT!
# source: telemetry.proto
"""Generated protocol buffer code."""
from google.protobuf.internal import enum_type_wrapper
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\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*\xa2\x01\n\x13TelemetrySensorType\x12\n\n\x06NotSet\x10\x00\x12\t\n\x05\x44HT11\x10\x01\x12\x0b\n\x07\x44S18B20\x10\x02\x12\t\n\x05\x44HT12\x10\x03\x12\t\n\x05\x44HT21\x10\x04\x12\t\n\x05\x44HT22\x10\x05\x12\n\n\x06\x42ME280\x10\x06\x12\n\n\x06\x42ME680\x10\x07\x12\x0b\n\x07MCP9808\x10\x08\x12\t\n\x05SHTC3\x10\t\x12\n\n\x06INA260\x10\n\x12\n\n\x06INA219\x10\x0b\x42K\n\x13\x63om.geeksville.meshB\x0fTelemetryProtosH\x03Z!github.com/meshtastic/gomeshprotob\x06proto3')
_TELEMETRYSENSORTYPE = DESCRIPTOR.enum_types_by_name['TelemetrySensorType']
TelemetrySensorType = enum_type_wrapper.EnumTypeWrapper(_TELEMETRYSENSORTYPE)
NotSet = 0
DHT11 = 1
DS18B20 = 2
DHT12 = 3
DHT21 = 4
DHT22 = 5
BME280 = 6
BME680 = 7
MCP9808 = 8
SHTC3 = 9
INA260 = 10
INA219 = 11
_DEVICEMETRICS = DESCRIPTOR.message_types_by_name['DeviceMetrics']
_ENVIRONMENTMETRICS = DESCRIPTOR.message_types_by_name['EnvironmentMetrics']
_TELEMETRY = DESCRIPTOR.message_types_by_name['Telemetry']
DeviceMetrics = _reflection.GeneratedProtocolMessageType('DeviceMetrics', (_message.Message,), {
'DESCRIPTOR' : _DEVICEMETRICS,
'__module__' : 'telemetry_pb2'
# @@protoc_insertion_point(class_scope:DeviceMetrics)
})
_sym_db.RegisterMessage(DeviceMetrics)
EnvironmentMetrics = _reflection.GeneratedProtocolMessageType('EnvironmentMetrics', (_message.Message,), {
'DESCRIPTOR' : _ENVIRONMENTMETRICS,
'__module__' : 'telemetry_pb2'
# @@protoc_insertion_point(class_scope:EnvironmentMetrics)
})
_sym_db.RegisterMessage(EnvironmentMetrics)
Telemetry = _reflection.GeneratedProtocolMessageType('Telemetry', (_message.Message,), {
'DESCRIPTOR' : _TELEMETRY,
'__module__' : 'telemetry_pb2'
# @@protoc_insertion_point(class_scope:Telemetry)
})
_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/gomeshproto'
_TELEMETRYSENSORTYPE._serialized_start=418
_TELEMETRYSENSORTYPE._serialized_end=580
_DEVICEMETRICS._serialized_start=19
_DEVICEMETRICS._serialized_end=124
_ENVIRONMENTMETRICS._serialized_start=127
_ENVIRONMENTMETRICS._serialized_end=282
_TELEMETRY._serialized_start=285
_TELEMETRY._serialized_end=415
# @@protoc_insertion_point(module_scope)

View File

File diff suppressed because it is too large Load Diff

View File

@@ -10,8 +10,7 @@ from ..mesh_interface import MeshInterface
from ..node import Node
from .. import mesh_pb2
from ..__init__ import LOCAL_ADDR, BROADCAST_ADDR
# TODO
#from ..config import Config
from ..radioconfig_pb2 import RadioConfig
from ..util import Timeout
@@ -178,34 +177,32 @@ def test_sendPosition(caplog):
assert re.search(r'p.time:', caplog.text, re.MULTILINE)
# TODO
#@pytest.mark.unit
#@pytest.mark.usefixtures("reset_globals")
#def test_close_with_heartbeatTimer(caplog):
# """Test close() with heartbeatTimer"""
# iface = MeshInterface(noProto=True)
# anode = Node('foo', 'bar')
# aconfig = Config()
# aonfig.preferences.phone_timeout_secs = 10
# anode.config = aconfig
# iface.localNode = anode
# assert iface.heartbeatTimer is None
# with caplog.at_level(logging.DEBUG):
# iface._startHeartbeat()
# assert iface.heartbeatTimer is not None
# iface.close()
@pytest.mark.unit
@pytest.mark.usefixtures("reset_globals")
def test_close_with_heartbeatTimer(caplog):
"""Test close() with heartbeatTimer"""
iface = MeshInterface(noProto=True)
anode = Node('foo', 'bar')
radioConfig = RadioConfig()
radioConfig.preferences.phone_timeout_secs = 10
anode.radioConfig = radioConfig
iface.localNode = anode
assert iface.heartbeatTimer is None
with caplog.at_level(logging.DEBUG):
iface._startHeartbeat()
assert iface.heartbeatTimer is not None
iface.close()
# TODO
#@pytest.mark.unit
#@pytest.mark.usefixtures("reset_globals")
#def test_handleFromRadio_empty_payload(caplog):
# """Test _handleFromRadio"""
# iface = MeshInterface(noProto=True)
# with caplog.at_level(logging.DEBUG):
# iface._handleFromRadio(b'')
# iface.close()
# assert re.search(r'Unexpected FromRadio payload', caplog.text, re.MULTILINE)
@pytest.mark.unit
@pytest.mark.usefixtures("reset_globals")
def test_handleFromRadio_empty_payload(caplog):
"""Test _handleFromRadio"""
iface = MeshInterface(noProto=True)
with caplog.at_level(logging.DEBUG):
iface._handleFromRadio(b'')
iface.close()
assert re.search(r'Unexpected FromRadio payload', caplog.text, re.MULTILINE)
@pytest.mark.unit
@@ -216,13 +213,13 @@ def test_handleFromRadio_with_my_info(caplog):
# It "translates" to this:
# my_info {
# my_node_num: 682584012
# num_bands: 13
# firmware_version: "1.2.49.5354c49"
# reboot_count: 13
# bitrate: 17.088470458984375
# message_timeout_msec: 300000
# min_app_version: 20200
# max_channels: 8
# has_wifi: true
# }
from_radio_bytes = b'\x1a,\x08\xcc\xcf\xbd\xc5\x02\x18\r2\x0e1.2.49.5354c49P\r]0\xb5\x88Ah\xe0\xa7\x12p\xe8\x9d\x01x\x08\x90\x01\x01'
iface = MeshInterface(noProto=True)
@@ -230,6 +227,7 @@ def test_handleFromRadio_with_my_info(caplog):
iface._handleFromRadio(from_radio_bytes)
iface.close()
assert re.search(r'Received myinfo', caplog.text, re.MULTILINE)
assert re.search(r'num_bands: 13', caplog.text, re.MULTILINE)
assert re.search(r'max_channels: 8', caplog.text, re.MULTILINE)
@@ -607,12 +605,11 @@ def test_getOrCreateByNum(iface_with_nodes):
assert tmp['num'] == 2475227164
# TODO
#@pytest.mark.unit
#def test_enter():
# """Test __enter__()"""
# iface = MeshInterface(noProto=True)
# assert iface == iface.__enter__()
@pytest.mark.unit
def test_enter():
"""Test __enter__()"""
iface = MeshInterface(noProto=True)
assert iface == iface.__enter__()
@pytest.mark.unit

View File

File diff suppressed because it is too large Load Diff

View File

@@ -170,6 +170,20 @@ def test_smoke1_port():
assert return_value == 0
@pytest.mark.smoke1
def test_smoke1_set_is_router_true():
"""Test --set is_router true"""
return_value, out = subprocess.getstatusoutput('meshtastic --set is_router true')
assert re.match(r'Connected to radio', out)
assert re.search(r'^Set is_router to true', out, re.MULTILINE)
assert return_value == 0
# pause for the radio
time.sleep(PAUSE_AFTER_COMMAND)
return_value, out = subprocess.getstatusoutput('meshtastic --get is_router')
assert re.search(r'^is_router: True', out, re.MULTILINE)
assert return_value == 0
@pytest.mark.smoke1
def test_smoke1_set_location_info():
"""Test --setlat, --setlon and --setalt """
@@ -188,6 +202,20 @@ def test_smoke1_set_location_info():
assert return_value == 0
@pytest.mark.smoke1
def test_smoke1_set_is_router_false():
"""Test --set is_router false"""
return_value, out = subprocess.getstatusoutput('meshtastic --set is_router false')
assert re.match(r'Connected to radio', out)
assert re.search(r'^Set is_router to false', out, re.MULTILINE)
assert return_value == 0
# pause for the radio
time.sleep(PAUSE_AFTER_COMMAND)
return_value, out = subprocess.getstatusoutput('meshtastic --get is_router')
assert re.search(r'^is_router: False', out, re.MULTILINE)
assert return_value == 0
@pytest.mark.smoke1
def test_smoke1_set_owner():
"""Test --set-owner name"""
@@ -215,42 +243,38 @@ def test_smoke1_set_owner():
@pytest.mark.smoke1
def test_smoke1_ch_set_modem_config():
"""Test --ch-set modem_config"""
return_value, out = subprocess.getstatusoutput('meshtastic --ch-set modem_config MidFast')
assert re.search(r'Warning: Need to specify', out, re.MULTILINE)
assert return_value == 1
# pause for the radio
time.sleep(PAUSE_AFTER_COMMAND)
return_value, out = subprocess.getstatusoutput('meshtastic --info')
assert not re.search(r'MidFast', out, re.MULTILINE)
def test_smoke1_set_team():
"""Test --set-team """
# unset the team
return_value, out = subprocess.getstatusoutput('meshtastic --set-team CLEAR')
assert re.match(r'Connected to radio', out)
assert re.search(r'^Setting team to CLEAR', out, re.MULTILINE)
assert return_value == 0
# pause for the radio
time.sleep(PAUSE_AFTER_COMMAND)
return_value, out = subprocess.getstatusoutput('meshtastic --ch-set modem_config MidFast --ch-index 0')
assert re.match(r'Connected to radio', out)
assert re.search(r'^Set modem_config to MidFast', out, re.MULTILINE)
time.sleep(PAUSE_AFTER_REBOOT)
return_value, out = subprocess.getstatusoutput('meshtastic --set-team CYAN')
assert re.search(r'Setting team to CYAN', out, re.MULTILINE)
assert return_value == 0
# pause for the radio
time.sleep(PAUSE_AFTER_REBOOT)
return_value, out = subprocess.getstatusoutput('meshtastic --info')
assert re.search(r'MidFast', out, re.MULTILINE)
assert re.search(r'CYAN', out, re.MULTILINE)
assert return_value == 0
@pytest.mark.smoke1
def test_smoke1_ch_values():
"""Test --ch-vlongslow --ch-longslow, --ch-longfast, --ch-mediumslow, --ch-mediumsfast,
"""Test --ch-longslow, --ch-longfast, --ch-mediumslow, --ch-mediumsfast,
--ch-shortslow, and --ch-shortfast arguments
"""
exp = {
'--ch-vlongslow': '{ "psk": "AQ==" }',
'--ch-longslow': 'LongSlow',
'--ch-longfast': 'LongFast',
'--ch-midslow': 'MidSlow',
'--ch-midfast': 'MidFast',
'--ch-shortslow': 'ShortSlow',
'--ch-shortfast': 'ShortFast'
'--ch-longslow': 'Bw125Cr48Sf4096',
'--ch-longfast': 'Bw31_25Cr48Sf512',
'--ch-mediumslow': 'Bw250Cr46Sf2048',
'--ch-mediumfast': 'Bw250Cr47Sf1024',
# for some reason, this value does not show any modemConfig
'--ch-shortslow': '{ "psk',
'--ch-shortfast': 'Bw500Cr45Sf128'
}
for key, val in exp.items():
@@ -554,6 +578,30 @@ def test_smoke1_ensure_ch_del_third_of_three_channels():
time.sleep(PAUSE_AFTER_COMMAND)
@pytest.mark.smoke1
def test_smoke1_ch_set_modem_config():
"""Test --ch-set modem_config"""
return_value, out = subprocess.getstatusoutput('meshtastic --ch-set modem_config Bw31_25Cr48Sf512')
assert re.search(r'Warning: Need to specify', out, re.MULTILINE)
assert return_value == 1
# pause for the radio
time.sleep(PAUSE_AFTER_COMMAND)
return_value, out = subprocess.getstatusoutput('meshtastic --info')
assert not re.search(r'Bw31_25Cr48Sf512', out, re.MULTILINE)
assert return_value == 0
# pause for the radio
time.sleep(PAUSE_AFTER_COMMAND)
return_value, out = subprocess.getstatusoutput('meshtastic --ch-set modem_config Bw31_25Cr48Sf512 --ch-index 0')
assert re.match(r'Connected to radio', out)
assert re.search(r'^Set modem_config to Bw31_25Cr48Sf512', out, re.MULTILINE)
assert return_value == 0
# pause for the radio
time.sleep(PAUSE_AFTER_COMMAND)
return_value, out = subprocess.getstatusoutput('meshtastic --info')
assert re.search(r'Bw31_25Cr48Sf512', out, re.MULTILINE)
assert return_value == 0
@pytest.mark.smoke1
def test_smoke1_seturl_default():
"""Test --seturl with default value"""
@@ -602,6 +650,7 @@ def test_smoke1_configure():
assert re.search('^Setting device position', out, re.MULTILINE)
assert re.search('^Set region to 1', out, re.MULTILINE)
assert re.search('^Set is_always_powered to true', out, re.MULTILINE)
assert re.search('^Set send_owner_interval to 2', out, re.MULTILINE)
assert re.search('^Set screen_on_secs to 31536000', out, re.MULTILINE)
assert re.search('^Set wait_bluetooth_secs to 31536000', out, re.MULTILINE)
assert re.search('^Writing modified preferences to device', out, re.MULTILINE)

View File

@@ -175,6 +175,20 @@ def test_smokevirt_port():
assert len(ports) == 0
@pytest.mark.smokevirt
def test_smokevirt_set_is_router_true():
"""Test --set is_router true"""
return_value, out = subprocess.getstatusoutput('meshtastic --host localhost --set is_router true')
assert re.match(r'Connected to radio', out)
assert re.search(r'^Set is_router to true', out, re.MULTILINE)
assert return_value == 0
# pause for the radio
time.sleep(PAUSE_AFTER_COMMAND)
return_value, out = subprocess.getstatusoutput('meshtastic --host localhost --get is_router')
assert re.search(r'^is_router: True', out, re.MULTILINE)
assert return_value == 0
@pytest.mark.smokevirt
def test_smokevirt_set_location_info():
"""Test --setlat, --setlon and --setalt """
@@ -193,6 +207,20 @@ def test_smokevirt_set_location_info():
assert return_value == 0
@pytest.mark.smokevirt
def test_smokevirt_set_is_router_false():
"""Test --set is_router false"""
return_value, out = subprocess.getstatusoutput('meshtastic --host localhost --set is_router false')
assert re.match(r'Connected to radio', out)
assert re.search(r'^Set is_router to false', out, re.MULTILINE)
assert return_value == 0
# pause for the radio
time.sleep(PAUSE_AFTER_COMMAND)
return_value, out = subprocess.getstatusoutput('meshtastic --host localhost --get is_router')
assert re.search(r'^is_router: False', out, re.MULTILINE)
assert return_value == 0
@pytest.mark.smokevirt
def test_smokevirt_set_owner():
"""Test --set-owner name"""
@@ -219,18 +247,38 @@ def test_smokevirt_set_owner():
assert return_value == 0
@pytest.mark.smokevirt
def test_smokevirt_set_team():
"""Test --set-team """
# unset the team
return_value, out = subprocess.getstatusoutput('meshtastic --host localhost --set-team CLEAR')
assert re.match(r'Connected to radio', out)
assert re.search(r'^Setting team to CLEAR', out, re.MULTILINE)
assert return_value == 0
# pause for the radio
time.sleep(PAUSE_AFTER_REBOOT)
return_value, out = subprocess.getstatusoutput('meshtastic --host localhost --set-team CYAN')
assert re.search(r'Setting team to CYAN', out, re.MULTILINE)
assert return_value == 0
# pause for the radio
time.sleep(PAUSE_AFTER_REBOOT)
return_value, out = subprocess.getstatusoutput('meshtastic --host localhost --info')
assert re.search(r'CYAN', out, re.MULTILINE)
assert return_value == 0
@pytest.mark.smokevirt
def test_smokevirt_ch_values():
"""Test --ch-longslow, --ch-longfast, --ch-mediumslow, --ch-mediumsfast,
--ch-shortslow, and --ch-shortfast arguments
"""
exp = {
'--ch-longslow': 'LongSlow',
'--ch-longfast': 'LongFast',
'--ch-midslow': 'MidSlow',
'--ch-midfast': 'MidFast',
'--ch-shortslow': 'ShortSlow',
'--ch-shortfast': 'ShortFast'
'--ch-longslow': 'Bw125Cr48Sf4096',
'--ch-longfast': 'Bw31_25Cr48Sf512',
'--ch-mediumslow': 'Bw250Cr46Sf2048',
'--ch-mediumfast': 'Bw250Cr47Sf1024',
'--ch-shortslow': '{ "psk',
'--ch-shortfast': 'Bw500Cr45Sf128'
}
for key, val in exp.items():
@@ -563,14 +611,14 @@ def test_smokevirt_ch_set_modem_config():
assert return_value == 0
# pause for the radio
time.sleep(PAUSE_AFTER_COMMAND)
return_value, out = subprocess.getstatusoutput('meshtastic --host localhost --ch-set modem_config MidSlow --ch-index 0')
return_value, out = subprocess.getstatusoutput('meshtastic --host localhost --ch-set modem_config Bw31_25Cr48Sf512 --ch-index 0')
assert re.match(r'Connected to radio', out)
assert re.search(r'^Set modem_config to MidSlow', out, re.MULTILINE)
assert re.search(r'^Set modem_config to Bw31_25Cr48Sf512', out, re.MULTILINE)
assert return_value == 0
# pause for the radio
time.sleep(PAUSE_AFTER_COMMAND)
return_value, out = subprocess.getstatusoutput('meshtastic --host localhost --info')
assert re.search(r'MidSlow', out, re.MULTILINE)
assert re.search(r'Bw31_25Cr48Sf512', out, re.MULTILINE)
assert return_value == 0

View File

@@ -1,7 +1,7 @@
"""Meshtastic unit tests for stream_interface.py"""
import logging
#import re
import re
from unittest.mock import MagicMock
import pytest
@@ -35,49 +35,48 @@ def test_StreamInterface_with_noProto(caplog):
assert data == test_data
# TODO
### Note: This takes a bit, so moving from unit to slow
### Tip: If you want to see the print output, run with '-s' flag:
### pytest -s meshtastic/tests/test_stream_interface.py::test_sendToRadioImpl
#@pytest.mark.unitslow
#@pytest.mark.usefixtures("reset_globals")
#def test_sendToRadioImpl(caplog):
# """Test _sendToRadioImpl()"""
#
## def add_header(b):
## """Add header stuffs for radio"""
## bufLen = len(b)
## header = bytes([START1, START2, (bufLen >> 8) & 0xff, bufLen & 0xff])
## return header + b
#
# # captured raw bytes of a Heltec2.1 radio with 2 channels (primary and a secondary channel named "gpio")
# raw_1_my_info = b'\x1a,\x08\xdc\x8c\xd5\xc5\x02\x18\r2\x0e1.2.49.5354c49P\x15]\xe1%\x17Eh\xe0\xa7\x12p\xe8\x9d\x01x\x08\x90\x01\x01'
# raw_2_node_info = b'"9\x08\xdc\x8c\xd5\xc5\x02\x12(\n\t!28b5465c\x12\x0cUnknown 465c\x1a\x03?5C"\x06$o(\xb5F\\0\n\x1a\x02 1%M<\xc6a'
# # pylint: disable=C0301
# raw_3_node_info = b'"C\x08\xa4\x8c\xd5\xc5\x02\x12(\n\t!28b54624\x12\x0cUnknown 4624\x1a\x03?24"\x06$o(\xb5F$0\n\x1a\x07 5MH<\xc6a%G<\xc6a=\x00\x00\xc0@'
# raw_4_complete = b'@\xcf\xe5\xd1\x8c\x0e'
# # pylint: disable=C0301
# raw_5_prefs = b'Z6\r\\F\xb5(\x15\\F\xb5("\x1c\x08\x06\x12\x13*\x11\n\x0f0\x84\x07P\xac\x02\x88\x01\x01\xb0\t#\xb8\t\x015]$\xddk5\xd5\x7f!b=M<\xc6aP\x03`F'
# # pylint: disable=C0301
# raw_6_channel0 = b'Z.\r\\F\xb5(\x15\\F\xb5("\x14\x08\x06\x12\x0b:\t\x12\x05\x18\x01"\x01\x01\x18\x015^$\xddk5\xd6\x7f!b=M<\xc6aP\x03`F'
# # pylint: disable=C0301
# raw_7_channel1 = b'ZS\r\\F\xb5(\x15\\F\xb5("9\x08\x06\x120:.\x08\x01\x12(" \xb4&\xb3\xc7\x06\xd8\xe39%\xba\xa5\xee\x8eH\x06\xf6\xf4H\xe8\xd5\xc1[ao\xb5Y\\\xb4"\xafmi*\x04gpio\x18\x025_$\xddk5\xd7\x7f!b=M<\xc6aP\x03`F'
# raw_8_channel2 = b'Z)\r\\F\xb5(\x15\\F\xb5("\x0f\x08\x06\x12\x06:\x04\x08\x02\x12\x005`$\xddk5\xd8\x7f!b=M<\xc6aP\x03`F'
# raw_blank = b''
#
# test_data = b'hello'
# stream = MagicMock()
# #stream.read.return_value = add_header(test_data)
# stream.read.side_effect = [ raw_1_my_info, raw_2_node_info, raw_3_node_info, raw_4_complete,
# raw_5_prefs, raw_6_channel0, raw_7_channel1, raw_8_channel2,
# raw_blank, raw_blank]
# toRadio = MagicMock()
# toRadio.SerializeToString.return_value = test_data
# with caplog.at_level(logging.DEBUG):
# iface = StreamInterface(noProto=True, connectNow=False)
# iface.stream = stream
# iface.connect()
# iface._sendToRadioImpl(toRadio)
# assert re.search(r'Sending: ', caplog.text, re.MULTILINE)
# assert re.search(r'reading character', caplog.text, re.MULTILINE)
# assert re.search(r'In reader loop', caplog.text, re.MULTILINE)
## Note: This takes a bit, so moving from unit to slow
## Tip: If you want to see the print output, run with '-s' flag:
## pytest -s meshtastic/tests/test_stream_interface.py::test_sendToRadioImpl
@pytest.mark.unitslow
@pytest.mark.usefixtures("reset_globals")
def test_sendToRadioImpl(caplog):
"""Test _sendToRadioImpl()"""
# def add_header(b):
# """Add header stuffs for radio"""
# bufLen = len(b)
# header = bytes([START1, START2, (bufLen >> 8) & 0xff, bufLen & 0xff])
# return header + b
# captured raw bytes of a Heltec2.1 radio with 2 channels (primary and a secondary channel named "gpio")
raw_1_my_info = b'\x1a,\x08\xdc\x8c\xd5\xc5\x02\x18\r2\x0e1.2.49.5354c49P\x15]\xe1%\x17Eh\xe0\xa7\x12p\xe8\x9d\x01x\x08\x90\x01\x01'
raw_2_node_info = b'"9\x08\xdc\x8c\xd5\xc5\x02\x12(\n\t!28b5465c\x12\x0cUnknown 465c\x1a\x03?5C"\x06$o(\xb5F\\0\n\x1a\x02 1%M<\xc6a'
# pylint: disable=C0301
raw_3_node_info = b'"C\x08\xa4\x8c\xd5\xc5\x02\x12(\n\t!28b54624\x12\x0cUnknown 4624\x1a\x03?24"\x06$o(\xb5F$0\n\x1a\x07 5MH<\xc6a%G<\xc6a=\x00\x00\xc0@'
raw_4_complete = b'@\xcf\xe5\xd1\x8c\x0e'
# pylint: disable=C0301
raw_5_prefs = b'Z6\r\\F\xb5(\x15\\F\xb5("\x1c\x08\x06\x12\x13*\x11\n\x0f0\x84\x07P\xac\x02\x88\x01\x01\xb0\t#\xb8\t\x015]$\xddk5\xd5\x7f!b=M<\xc6aP\x03`F'
# pylint: disable=C0301
raw_6_channel0 = b'Z.\r\\F\xb5(\x15\\F\xb5("\x14\x08\x06\x12\x0b:\t\x12\x05\x18\x01"\x01\x01\x18\x015^$\xddk5\xd6\x7f!b=M<\xc6aP\x03`F'
# pylint: disable=C0301
raw_7_channel1 = b'ZS\r\\F\xb5(\x15\\F\xb5("9\x08\x06\x120:.\x08\x01\x12(" \xb4&\xb3\xc7\x06\xd8\xe39%\xba\xa5\xee\x8eH\x06\xf6\xf4H\xe8\xd5\xc1[ao\xb5Y\\\xb4"\xafmi*\x04gpio\x18\x025_$\xddk5\xd7\x7f!b=M<\xc6aP\x03`F'
raw_8_channel2 = b'Z)\r\\F\xb5(\x15\\F\xb5("\x0f\x08\x06\x12\x06:\x04\x08\x02\x12\x005`$\xddk5\xd8\x7f!b=M<\xc6aP\x03`F'
raw_blank = b''
test_data = b'hello'
stream = MagicMock()
#stream.read.return_value = add_header(test_data)
stream.read.side_effect = [ raw_1_my_info, raw_2_node_info, raw_3_node_info, raw_4_complete,
raw_5_prefs, raw_6_channel0, raw_7_channel1, raw_8_channel2,
raw_blank, raw_blank]
toRadio = MagicMock()
toRadio.SerializeToString.return_value = test_data
with caplog.at_level(logging.DEBUG):
iface = StreamInterface(noProto=True, connectNow=False)
iface.stream = stream
iface.connect()
iface._sendToRadioImpl(toRadio)
assert re.search(r'Sending: ', caplog.text, re.MULTILINE)
assert re.search(r'reading character', caplog.text, re.MULTILINE)
assert re.search(r'In reader loop', caplog.text, re.MULTILINE)

View File

@@ -337,9 +337,9 @@ def test_eliminate_duplicate_port():
assert eliminate_duplicate_port(['/dev/cu.SLAB_USBtoUART', '/dev/cu.usbserial-0001']) == ['/dev/cu.usbserial-0001']
assert eliminate_duplicate_port(['/dev/cu.usbserial-0001', '/dev/cu.SLAB_USBtoUART']) == ['/dev/cu.usbserial-0001']
assert eliminate_duplicate_port(['/dev/cu.usbmodem11301', '/dev/cu.wchusbserial11301']) == ['/dev/cu.wchusbserial11301']
assert eliminate_duplicate_port(['/dev/cu.wchusbserial11301', '/dev/cu.usbmodem11301']) == ['/dev/cu.wchusbserial11301']
assert eliminate_duplicate_port(['/dev/cu.usbmodem53230051441', '/dev/cu.wchusbserial53230051441']) == ['/dev/cu.wchusbserial53230051441']
assert eliminate_duplicate_port(['/dev/cu.wchusbserial53230051441', '/dev/cu.usbmodem53230051441']) == ['/dev/cu.wchusbserial53230051441']
assert eliminate_duplicate_port(['/dev/cu.wchusbserial11301', '/dev/cu.usbmodem11301']) == ['/dev/cu.wchusbserial11301']
@patch('platform.version', return_value='10.0.22000.194')
@patch('platform.release', return_value='10')

View File

@@ -266,7 +266,7 @@ def camel_to_snake(a_string):
def detect_supported_devices():
"""detect supported devices based on vendor id"""
"""detect supported devices"""
system = platform.system()
#print(f'system:{system}')
@@ -285,8 +285,19 @@ def detect_supported_devices():
if re.search(search, lsusb_output, re.MULTILINE):
#print(f'Found vendor id that matches')
devices = get_devices_with_vendor_id(vid)
# check device id
for device in devices:
possible_devices.add(device)
#print(f'device:{device} device.usb_product_id_in_hex:{device.usb_product_id_in_hex}')
if device.usb_product_id_in_hex:
search = f' {vid}:{device.usb_product_id_in_hex} '
#print(f'search:"{search}"')
if re.search(search, lsusb_output, re.MULTILINE):
# concatenate the devices with vendor id to possibles
possible_devices.add(device)
else:
# if there is a supported device witout a product id, then it
# might be a match... so, concatenate
possible_devices.add(device)
elif system == "Windows":
# if windows, run Get-PnpDevice
@@ -302,8 +313,22 @@ def detect_supported_devices():
if re.search(search, sp_output, re.MULTILINE):
#print(f'Found vendor id that matches')
devices = get_devices_with_vendor_id(vid)
# check device id
for device in devices:
possible_devices.add(device)
#print(f'device:{device} device.usb_product_id_in_hex:{device.usb_product_id_in_hex}')
if device.usb_product_id_in_hex:
search = f'DeviceID.*{vid.upper()}&PID_{device.usb_product_id_in_hex.upper()}'
#print(f'search:"{search}"')
if re.search(search, sp_output, re.MULTILINE):
# concatenate the devices with vendor id to possibles
possible_devices.add(device)
# do a check to see if there is a Windows driver issue
if detect_windows_needs_driver(device, False):
print("WARNING: Need to install driver.")
else:
# if there is a supported device witout a product id, then it
# might be a match... so, concatenate
possible_devices.add(device)
elif system == "Darwin":
# run: system_profiler SPUSBDataType
@@ -318,8 +343,19 @@ def detect_supported_devices():
if re.search(search, sp_output, re.MULTILINE):
#print(f'Found vendor id that matches')
devices = get_devices_with_vendor_id(vid)
# check device id
for device in devices:
possible_devices.add(device)
#print(f'device:{device} device.usb_product_id_in_hex:{device.usb_product_id_in_hex}')
if device.usb_product_id_in_hex:
search = f'Product ID: 0x{device.usb_product_id_in_hex}'
#print(f'search:"{search}"')
if re.search(search, sp_output, re.MULTILINE):
# concatenate the devices with vendor id to possibles
possible_devices.add(device)
else:
# if there is a supported device witout a product id, then it
# might be a match... so, concatenate
possible_devices.add(device)
return possible_devices

2
proto

Submodule proto updated: c63a16c32f...c851209e0b

View File

@@ -12,7 +12,7 @@ with open("README.md", "r") as fh:
# This call to setup() does all the work
setup(
name="meshtastic",
version="1.3alpha.19",
version="1.2.94",
description="Python API & client shell for talking to Meshtastic devices",
long_description=long_description,
long_description_content_type="text/markdown",
@@ -22,7 +22,8 @@ setup(
license="MIT",
classifiers=[
"License :: OSI Approved :: MIT License",
"Development Status :: 4 - Beta",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.6",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
@@ -37,7 +38,7 @@ setup(
extras_require={
'tunnel': ["pytap2>=2.0.0"]
},
python_requires='>=3.7',
python_requires='>=3.6',
entry_points={
"console_scripts": [
"meshtastic=meshtastic.__main__:main",