Compare commits

..

8 Commits

Author SHA1 Message Date
Ben Meadors
7422d9d314 Update 2025-03-04 08:15:55 -06:00
Ben Meadors
5ee0264737 Where's intellisense when you need it 2025-03-03 15:28:14 -06:00
Ben Meadors
ec13bd308a Remove print 2025-03-03 15:23:48 -06:00
Ben Meadors
2d88d8e918 Good lawd I did that in a hurry 2025-03-03 15:23:21 -06:00
Ben Meadors
fb48fc20b3 Optionals 2025-03-03 07:56:03 -06:00
Ben Meadors
336e5154a3 Add args for cli 2025-03-03 06:58:45 -06:00
Ben Meadors
3008e039fb Bump version 2025-03-03 06:51:12 -06:00
Ben Meadors
4bf61d4c98 Add backup / restore admin commands 2025-03-03 06:48:06 -06:00
69 changed files with 876 additions and 3639 deletions

View File

@@ -1,22 +0,0 @@
# Contributing to Meshtastic Python
## Development resources
- [API Documentation](https://python.meshtastic.org/)
- [Meshtastic Python Development](https://meshtastic.org/docs/development/python/)
- [Building Meshtastic Python](https://meshtastic.org/docs/development/python/building/)
- [Using the Meshtastic Python Library](https://meshtastic.org/docs/development/python/library/)
## How to check your code (pytest/pylint) before a PR
- [Pre-requisites](https://meshtastic.org/docs/development/python/building/#pre-requisites)
- also execute `poetry install --all-extras --with dev,powermon` for all optional dependencies
- check your code with github ci actions locally
- You need to have act installed. You can get it at https://nektosact.com/
- on linux: `act -P ubuntu-latest=-self-hosted --matrix "python-version:3.12"`
- on windows:
- linux checks (linux docker): `act --matrix "python-version:3.12"`
- windows checks (windows host): `act -P ubuntu-latest=-self-hosted --matrix "python-version:3.12"`
- or run all locally:
- run `poetry run pylint meshtastic examples/ --ignore-patterns ".*_pb2.pyi?$"`
- run `poetry run mypy meshtastic/`
- run `poetry run pytest`
- more commands see [CI workflow](https://github.com/meshtastic/python/blob/master/.github/workflows/ci.yml)

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 105 KiB

3
.gitignore vendored
View File

@@ -17,5 +17,4 @@ examples/__pycache__
meshtastic.spec
.hypothesis/
coverage.xml
.ipynb_checkpoints
.cursor/
.ipynb_checkpoints

12
.vscode/launch.json vendored
View File

@@ -4,7 +4,6 @@
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "meshtastic BLE",
"type": "debugpy",
@@ -262,14 +261,7 @@
"module": "meshtastic",
"justMyCode": true,
"args": ["--nodes", "--show-fields", "AKA,Pubkey,Role,Role,Role,Latitude,Latitude,deviceMetrics.voltage"]
},
{
"name": "meshtastic --export-config",
"type": "debugpy",
"request": "launch",
"module": "meshtastic",
"justMyCode": true,
"args": ["--export-config", "config.json"]
},
}
]
}

View File

View File

@@ -1,10 +1,4 @@
<div align="center" markdown="1">
<img src=".github/meshtastic_logo.png" alt="Meshtastic Logo" width="80"/>
<h1 align="center"> Meshtastic Python
</h1>
<p style="font-size:15px;" align="center">A Python library and client for use with Meshtastic devices. </p>
# Meshtastic Python
[![codecov](https://codecov.io/gh/meshtastic/python/branch/master/graph/badge.svg?token=TIWPJL73KV)](https://codecov.io/gh/meshtastic/python)
![PyPI - Downloads](https://img.shields.io/pypi/dm/meshtastic)
@@ -13,20 +7,17 @@
[![Fiscal Contributors](https://opencollective.com/meshtastic/tiers/badge.svg?label=Fiscal%20Contributors&color=deeppink)](https://opencollective.com/meshtastic/)
![GPL-3.0](https://img.shields.io/badge/License-GPL%20v3-blue.svg)
</div>
<div align="center">
<a href="https://meshtastic.org/docs/software/python/cli/installation">Getting Started Guide</a>
-
<a href="https://python.meshtastic.org">API Documentation</a>
</div>
## Overview
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.
**[Getting Started Guide](https://meshtastic.org/docs/software/python/cli/installation)**
**[API Documentation](https://python.meshtastic.org)**
## Call for Contributors
This library and CLI has gone without a consistent maintainer for a while, and there's many improvements that could be made. We're all volunteers here and help is extremely appreciated, whether in implementing your own needs or helping maintain the library and CLI in general.

View File

@@ -6,12 +6,6 @@ set -e
#gsed -i 's/import "\//import ".\//g' ./protobufs/meshtastic/*
#gsed -i 's/package meshtastic;//g' ./protobufs/meshtastic/*
POETRYDIR=$(poetry env info --path)
if [[ -z "${POETRYDIR}" ]]; then
poetry install
fi
# protoc looks for mypy plugin in the python path
source $(poetry env info --path)/bin/activate
@@ -28,7 +22,6 @@ OUTDIR=${TMPDIR}/out
PYIDIR=${TMPDIR}/out
mkdir -p "${OUTDIR}" "${INDIR}" "${PYIDIR}"
cp ./protobufs/meshtastic/*.proto "${INDIR}"
cp ./protobufs/nanopb.proto "${INDIR}"
# OS-X sed is apparently a little different and expects an arg for -i
if [[ $OSTYPE == 'darwin'* ]]; then
@@ -43,8 +36,6 @@ $SEDCMD 's/^package meshtastic;/package meshtastic.protobuf;/' "${INDIR}/"*.prot
# fix the imports to match
$SEDCMD 's/^import "meshtastic\//import "meshtastic\/protobuf\//' "${INDIR}/"*.proto
$SEDCMD 's/^import "nanopb.proto"/import "meshtastic\/protobuf\/nanopb.proto"/' "${INDIR}/"*.proto
# Generate the python files
./nanopb-0.4.8/generator-bin/protoc -I=$TMPDIR/in --python_out "${OUTDIR}" "--mypy_out=${PYIDIR}" $INDIR/*.proto

View File

@@ -4,9 +4,6 @@ owner_short: BOB
channel_url: https://www.meshtastic.org/e/#CgMSAQESCDgBQANIAVAe
canned_messages: Hi|Bye|Yes|No|Ok
ringtone: 24:d=32,o=5,b=565:f6,p,f6,4p,p,f6,p,f6,2p,p,b6,p,b6,p,b6,p,b6,p,b,p,b,p,b,p,b,p,b,p,b,p,b,p,b,1p.,2p.,p
location:
lat: 35.88888
lon: -93.88888

View File

@@ -25,7 +25,6 @@ parser_create = subparsers.add_parser('create', help='Create a new waypoint')
parser_create.add_argument('id', help="id of the waypoint")
parser_create.add_argument('name', help="name of the waypoint")
parser_create.add_argument('description', help="description of the waypoint")
parser_create.add_argument('icon', help="icon of the waypoint")
parser_create.add_argument('expire', help="expiration date of the waypoint as interpreted by datetime.fromisoformat")
parser_create.add_argument('latitude', help="latitude of the waypoint")
parser_create.add_argument('longitude', help="longitude of the waypoint")
@@ -45,7 +44,6 @@ with meshtastic.serial_interface.SerialInterface(args.port, debugOut=d) as iface
waypoint_id=int(args.id),
name=args.name,
description=args.description,
icon=args.icon,
expire=int(datetime.datetime.fromisoformat(args.expire).timestamp()),
latitude=float(args.latitude),
longitude=float(args.longitude),

View File

@@ -35,7 +35,6 @@ type of packet, you should subscribe to the full topic name. If you want to see
- `meshtastic.receive.data.portnum(packet)` (where portnum is an integer or well known PortNum enum)
- `meshtastic.node.updated(node = NodeInfo)` - published when a node in the DB changes (appears, location changed, username changed, etc...)
- `meshtastic.log.line(line)` - a raw unparsed log line from the radio
- `meshtastic.clientNotification(notification, interface) - a ClientNotification sent from the radio
We receive position, user, or data packets from the mesh. You probably only care about `meshtastic.receive.data`. The first argument for
that publish will be the packet. Text or binary data packets (from `sendData` or `sendText`) will both arrive this way. If you print packet
@@ -129,7 +128,6 @@ NODELESS_WANT_CONFIG_ID = 69420
publishingThread = DeferredExecution("publishing")
logger = logging.getLogger(__name__)
class ResponseHandler(NamedTuple):
"""A pending response callback, waiting for a response to one of our messages"""
@@ -161,31 +159,31 @@ def _onTextReceive(iface, asDict):
#
# Usually btw this problem is caused by apps sending binary data but setting the payload type to
# text.
logger.debug(f"in _onTextReceive() asDict:{asDict}")
logging.debug(f"in _onTextReceive() asDict:{asDict}")
try:
asBytes = asDict["decoded"]["payload"]
asDict["decoded"]["text"] = asBytes.decode("utf-8")
except Exception as ex:
logger.error(f"Malformatted utf8 in text message: {ex}")
logging.error(f"Malformatted utf8 in text message: {ex}")
_receiveInfoUpdate(iface, asDict)
def _onPositionReceive(iface, asDict):
"""Special auto parsing for received messages"""
logger.debug(f"in _onPositionReceive() asDict:{asDict}")
logging.debug(f"in _onPositionReceive() asDict:{asDict}")
if "decoded" in asDict:
if "position" in asDict["decoded"] and "from" in asDict:
p = asDict["decoded"]["position"]
logger.debug(f"p:{p}")
logging.debug(f"p:{p}")
p = iface._fixupPosition(p)
logger.debug(f"after fixup p:{p}")
logging.debug(f"after fixup p:{p}")
# update node DB as needed
iface._getOrCreateByNum(asDict["from"])["position"] = p
def _onNodeInfoReceive(iface, asDict):
"""Special auto parsing for received messages"""
logger.debug(f"in _onNodeInfoReceive() asDict:{asDict}")
logging.debug(f"in _onNodeInfoReceive() asDict:{asDict}")
if "decoded" in asDict:
if "user" in asDict["decoded"] and "from" in asDict:
p = asDict["decoded"]["user"]
@@ -199,7 +197,7 @@ def _onNodeInfoReceive(iface, asDict):
def _onTelemetryReceive(iface, asDict):
"""Automatically update device metrics on received packets"""
logger.debug(f"in _onTelemetryReceive() asDict:{asDict}")
logging.debug(f"in _onTelemetryReceive() asDict:{asDict}")
if "from" not in asDict:
return
@@ -223,7 +221,7 @@ def _onTelemetryReceive(iface, asDict):
updateObj = telemetry.get(toUpdate)
newMetrics = node.get(toUpdate, {})
newMetrics.update(updateObj)
logger.debug(f"updating {toUpdate} metrics for {asDict['from']} to {newMetrics}")
logging.debug(f"updating {toUpdate} metrics for {asDict['from']} to {newMetrics}")
node[toUpdate] = newMetrics
def _receiveInfoUpdate(iface, asDict):
@@ -235,7 +233,7 @@ def _receiveInfoUpdate(iface, asDict):
def _onAdminReceive(iface, asDict):
"""Special auto parsing for received messages"""
logger.debug(f"in _onAdminReceive() asDict:{asDict}")
logging.debug(f"in _onAdminReceive() asDict:{asDict}")
if "decoded" in asDict and "from" in asDict and "admin" in asDict["decoded"]:
adminMessage = asDict["decoded"]["admin"]["raw"]
iface._getOrCreateByNum(asDict["from"])["adminSessionPassKey"] = adminMessage.session_passkey

View File

@@ -3,13 +3,12 @@
# We just hit the 1600 line limit for main.py, but I currently have a huge set of powermon/structured logging changes
# later we can have a separate changelist to refactor main.py into smaller files
# pylint: disable=R0917,C0302
# pylint: disable=too-many-lines
from typing import List, Optional, Union
from types import ModuleType
import argparse
argcomplete: Union[None, ModuleType] = None
try:
import argcomplete # type: ignore
@@ -60,17 +59,15 @@ except ImportError as e:
have_powermon = False
powermon_exception = e
meter = None
from meshtastic.protobuf import channel_pb2, config_pb2, portnums_pb2, mesh_pb2
from meshtastic.protobuf import admin_pb2, channel_pb2, config_pb2, portnums_pb2
from meshtastic.version import get_active_version
logger = logging.getLogger(__name__)
def onReceive(packet, interface) -> None:
"""Callback invoked when a packet arrives"""
args = mt_config.args
try:
d = packet.get("decoded")
logger.debug(f"in onReceive() d:{d}")
logging.debug(f"in onReceive() d:{d}")
# Exit once we receive a reply
if (
@@ -104,7 +101,7 @@ def onConnection(interface, topic=pub.AUTO_TOPIC) -> None: # pylint: disable=W0
def checkChannel(interface: MeshInterface, channelIndex: int) -> bool:
"""Given an interface and channel index, return True if that channel is non-disabled on the local node"""
ch = interface.localNode.getChannelByChannelIndex(channelIndex)
logger.debug(f"ch:{ch}")
logging.debug(f"ch:{ch}")
return ch and ch.role != channel_pb2.Channel.Role.DISABLED
@@ -117,7 +114,7 @@ def getPref(node, comp_name) -> bool:
else:
pref_value = meshtastic.util.toStr(pref_value)
print(f"{str(config_type.name)}.{uni_name}: {str(pref_value)}")
logger.debug(f"{str(config_type.name)}.{uni_name}: {str(pref_value)}")
logging.debug(f"{str(config_type.name)}.{uni_name}: {str(pref_value)}")
name = splitCompoundName(comp_name)
wholeField = name[0] == name[1] # We want the whole field
@@ -126,8 +123,8 @@ def getPref(node, comp_name) -> bool:
# Note: protobufs has the keys in snake_case, so snake internally
snake_name = meshtastic.util.camel_to_snake(name[1])
uni_name = camel_name if mt_config.camel_case else snake_name
logger.debug(f"snake_name:{snake_name} camel_name:{camel_name}")
logger.debug(f"use camel:{mt_config.camel_case}")
logging.debug(f"snake_name:{snake_name} camel_name:{camel_name}")
logging.debug(f"use camel:{mt_config.camel_case}")
# First validate the input
localConfig = node.localConfig
@@ -201,8 +198,8 @@ def setPref(config, comp_name, raw_val) -> bool:
snake_name = meshtastic.util.camel_to_snake(name[-1])
camel_name = meshtastic.util.snake_to_camel(name[-1])
uni_name = camel_name if mt_config.camel_case else snake_name
logger.debug(f"snake_name:{snake_name}")
logger.debug(f"camel_name:{camel_name}")
logging.debug(f"snake_name:{snake_name}")
logging.debug(f"camel_name:{camel_name}")
objDesc = config.DESCRIPTOR
config_part = config
@@ -226,7 +223,7 @@ def setPref(config, comp_name, raw_val) -> bool:
val = meshtastic.util.fromStr(raw_val)
else:
val = raw_val
logger.debug(f"valStr:{raw_val} val:{val}")
logging.debug(f"valStr:{raw_val} val:{val}")
if snake_name == "wifi_psk" and len(str(raw_val)) < 8:
print("Warning: network.wifi_psk must be 8 or more characters.")
@@ -277,8 +274,7 @@ def setPref(config, comp_name, raw_val) -> bool:
else:
print(f"Adding '{raw_val}' to the {pref.name} list")
cur_vals = [x for x in getattr(config_values, pref.name) if x not in [0, "", b""]]
if val not in cur_vals:
cur_vals.append(val)
cur_vals.append(val)
getattr(config_values, pref.name)[:] = cur_vals
return True
@@ -343,60 +339,32 @@ def onConnected(interface):
# can include lat/long/alt etc: latitude = 37.5, longitude = -122.1
interface.getNode(args.dest, False, **getNode_kwargs).setFixedPosition(lat, lon, alt)
if args.set_owner or args.set_owner_short or args.set_is_unmessageable:
if args.set_owner or args.set_owner_short:
closeNow = True
waitForAckNak = True
if args.set_owner and args.set_owner_short:
print(f"Setting device owner to {args.set_owner} and short name to {args.set_owner_short}")
elif args.set_owner:
print(f"Setting device owner to {args.set_owner}")
else: # short name only
print(f"Setting device owner short to {args.set_owner_short}")
interface.getNode(args.dest, False, **getNode_kwargs).setOwner(long_name=args.set_owner, short_name=args.set_owner_short)
long_name = args.set_owner.strip() if args.set_owner else None
short_name = args.set_owner_short.strip() if args.set_owner_short else None
if long_name is not None and not long_name:
meshtastic.util.our_exit("ERROR: Long Name cannot be empty or contain only whitespace characters")
if short_name is not None and not short_name:
meshtastic.util.our_exit("ERROR: Short Name cannot be empty or contain only whitespace characters")
if long_name and short_name:
print(f"Setting device owner to {long_name} and short name to {short_name}")
elif long_name:
print(f"Setting device owner to {long_name}")
elif short_name:
print(f"Setting device owner short to {short_name}")
unmessagable = None
if args.set_is_unmessageable is not None:
unmessagable = (
meshtastic.util.fromStr(args.set_is_unmessageable)
if isinstance(args.set_is_unmessageable, str)
else args.set_is_unmessageable
)
print(f"Setting device owner is_unmessageable to {unmessagable}")
interface.getNode(args.dest, False, **getNode_kwargs).setOwner(
long_name=long_name,
short_name=short_name,
is_unmessagable=unmessagable
)
# TODO: add to export-config and configure
if args.set_canned_message:
closeNow = True
waitForAckNak = True
node = interface.getNode(args.dest, False, **getNode_kwargs)
if node.module_available(mesh_pb2.CANNEDMSG_CONFIG):
print(f"Setting canned plugin message to {args.set_canned_message}")
node.set_canned_message(args.set_canned_message)
else:
print("Canned Message module is excluded by firmware; skipping set.")
print(f"Setting canned plugin message to {args.set_canned_message}")
interface.getNode(args.dest, False, **getNode_kwargs).set_canned_message(
args.set_canned_message
)
# TODO: add to export-config and configure
if args.set_ringtone:
closeNow = True
waitForAckNak = True
node = interface.getNode(args.dest, False, **getNode_kwargs)
if node.module_available(mesh_pb2.EXTNOTIF_CONFIG):
print(f"Setting ringtone to {args.set_ringtone}")
node.set_ringtone(args.set_ringtone)
else:
print("External Notification is excluded by firmware; skipping ringtone set.")
print(f"Setting ringtone to {args.set_ringtone}")
interface.getNode(args.dest, False, **getNode_kwargs).set_ringtone(args.set_ringtone)
if args.pos_fields:
# If --pos-fields invoked with args, set position fields
@@ -434,8 +402,6 @@ def onConnected(interface):
print(" ".join(fieldNames))
if args.set_ham:
if not args.set_ham.strip():
meshtastic.util.our_exit("ERROR: Ham radio callsign cannot be empty or contain only whitespace characters")
closeNow = True
print(f"Setting Ham ID to {args.set_ham} and turning off encryption")
interface.getNode(args.dest, **getNode_kwargs).setOwner(args.set_ham, is_licensed=True)
@@ -496,6 +462,22 @@ def onConnected(interface):
waitForAckNak = True
interface.getNode(args.dest, False, **getNode_kwargs).removeFavorite(args.remove_favorite_node)
if args.backup_prefs:
closeNow = True
waitForAckNak = True
print(f"Backing up preferences to {args.backup_prefs}")
interface.getNode(args.dest, False, **getNode_kwargs).backupPreferences(args.backup_prefs)
if args.restore_prefs:
closeNow = True
waitForAckNak = True
interface.getNode(args.dest, False, **getNode_kwargs).restorePreferences(args.restore_prefs)
if args.remove_backup_prefs:
closeNow = True
waitForAckNak = True
interface.getNode(args.dest, False, **getNode_kwargs).removePreferencesBackups(args.remove_backup_prefs)
if args.set_ignored_node:
closeNow = True
waitForAckNak = True
@@ -612,7 +594,7 @@ def onConnected(interface):
time.sleep(1)
if interface.gotResponse:
break
logger.debug(f"end of gpio_rd")
logging.debug(f"end of gpio_rd")
if args.gpio_watch:
bitmask = int(args.gpio_watch, 16)
@@ -678,20 +660,11 @@ def onConnected(interface):
interface.getNode(args.dest, False, **getNode_kwargs).beginSettingsTransaction()
if "owner" in configuration:
# Validate owner name before setting
owner_name = str(configuration["owner"]).strip()
if not owner_name:
meshtastic.util.our_exit("ERROR: Long Name cannot be empty or contain only whitespace characters")
print(f"Setting device owner to {configuration['owner']}")
waitForAckNak = True
interface.getNode(args.dest, False, **getNode_kwargs).setOwner(configuration["owner"])
time.sleep(0.5)
if "owner_short" in configuration:
# Validate owner short name before setting
owner_short_name = str(configuration["owner_short"]).strip()
if not owner_short_name:
meshtastic.util.our_exit("ERROR: Short Name cannot be empty or contain only whitespace characters")
print(
f"Setting device owner short to {configuration['owner_short']}"
)
@@ -699,13 +672,8 @@ def onConnected(interface):
interface.getNode(args.dest, False, **getNode_kwargs).setOwner(
long_name=None, short_name=configuration["owner_short"]
)
time.sleep(0.5)
if "ownerShort" in configuration:
# Validate owner short name before setting
owner_short_name = str(configuration["ownerShort"]).strip()
if not owner_short_name:
meshtastic.util.our_exit("ERROR: Short Name cannot be empty or contain only whitespace characters")
print(
f"Setting device owner short to {configuration['ownerShort']}"
)
@@ -713,27 +681,14 @@ def onConnected(interface):
interface.getNode(args.dest, False, **getNode_kwargs).setOwner(
long_name=None, short_name=configuration["ownerShort"]
)
time.sleep(0.5)
if "channel_url" in configuration:
print("Setting channel url to", configuration["channel_url"])
interface.getNode(args.dest, **getNode_kwargs).setURL(configuration["channel_url"])
time.sleep(0.5)
if "channelUrl" in configuration:
print("Setting channel url to", configuration["channelUrl"])
interface.getNode(args.dest, **getNode_kwargs).setURL(configuration["channelUrl"])
time.sleep(0.5)
if "canned_messages" in configuration:
print("Setting canned message messages to", configuration["canned_messages"])
interface.getNode(args.dest, **getNode_kwargs).set_canned_message(configuration["canned_messages"])
time.sleep(0.5)
if "ringtone" in configuration:
print("Setting ringtone to", configuration["ringtone"])
interface.getNode(args.dest, **getNode_kwargs).set_ringtone(configuration["ringtone"])
time.sleep(0.5)
if "location" in configuration:
alt = 0
@@ -752,7 +707,6 @@ def onConnected(interface):
print(f"Fixing longitude at {lon} degrees")
print("Setting device position")
interface.localNode.setFixedPosition(lat, lon, alt)
time.sleep(0.5)
if "config" in configuration:
localConfig = interface.getNode(args.dest, **getNode_kwargs).localConfig
@@ -763,7 +717,6 @@ def onConnected(interface):
interface.getNode(args.dest, **getNode_kwargs).writeConfig(
meshtastic.util.camel_to_snake(section)
)
time.sleep(0.5)
if "module_config" in configuration:
moduleConfig = interface.getNode(args.dest, **getNode_kwargs).moduleConfig
@@ -776,7 +729,6 @@ def onConnected(interface):
interface.getNode(args.dest, **getNode_kwargs).writeConfig(
meshtastic.util.camel_to_snake(section)
)
time.sleep(0.5)
interface.getNode(args.dest, False, **getNode_kwargs).commitSettingsTransaction()
print("Writing modified configuration to device")
@@ -785,20 +737,9 @@ def onConnected(interface):
if args.dest != BROADCAST_ADDR:
print("Exporting configuration of remote nodes is not supported.")
return
# export the configuration (the opposite of '--configure')
closeNow = True
config_txt = export_config(interface)
if args.export_config == "-":
# Output to stdout (preserves legacy use of `> file.yaml`)
print(config_txt)
else:
try:
with open(args.export_config, "w", encoding="utf-8") as f:
f.write(config_txt)
print(f"Exported configuration to {args.export_config}")
except Exception as e:
meshtastic.util.our_exit(f"ERROR: Failed to write config file: {e}")
export_config(interface)
if args.ch_set_url:
closeNow = True
@@ -969,14 +910,12 @@ def onConnected(interface):
if args.get_canned_message:
closeNow = True
print("")
messages = interface.getNode(args.dest, **getNode_kwargs).get_canned_message()
print(f"canned_plugin_message:{messages}")
interface.getNode(args.dest, **getNode_kwargs).get_canned_message()
if args.get_ringtone:
closeNow = True
print("")
ringtone = interface.getNode(args.dest, **getNode_kwargs).get_ringtone()
print(f"ringtone:{ringtone}")
interface.getNode(args.dest, **getNode_kwargs).get_ringtone()
if args.info:
print("")
@@ -1068,7 +1007,7 @@ def onConnected(interface):
# Even if others said we could close, stay open if the user asked for a tunnel
closeNow = False
if interface.noProto:
logger.warning(f"Not starting Tunnel - disabled by noProto")
logging.warning(f"Not starting Tunnel - disabled by noProto")
else:
if args.tunnel_net:
tunnel.Tunnel(interface, subnet=args.tunnel_net)
@@ -1131,38 +1070,15 @@ def subscribe() -> None:
# pub.subscribe(onNode, "meshtastic.node")
def set_missing_flags_false(config_dict: dict, true_defaults: set[tuple[str, str]]) -> None:
"""Ensure that missing default=True keys are present in the config_dict and set to False."""
for path in true_defaults:
d = config_dict
for key in path[:-1]:
if key not in d or not isinstance(d[key], dict):
d[key] = {}
d = d[key]
if path[-1] not in d:
d[path[-1]] = False
def export_config(interface) -> str:
"""used in --export-config"""
configObj = {}
# A list of configuration keys that should be set to False if they are missing
true_defaults = {
("bluetooth", "enabled"),
("lora", "sx126xRxBoostedGain"),
("lora", "txEnabled"),
("lora", "usePreset"),
("position", "positionBroadcastSmartEnabled"),
("security", "serialEnabled"),
("mqtt", "encryptionEnabled"),
}
owner = interface.getLongName()
owner_short = interface.getShortName()
channel_url = interface.localNode.getURL()
myinfo = interface.getMyNodeInfo()
canned_messages = interface.getCannedMessage()
ringtone = interface.getRingtone()
pos = myinfo.get("position")
lat = None
lon = None
@@ -1181,10 +1097,6 @@ def export_config(interface) -> str:
configObj["channelUrl"] = channel_url
else:
configObj["channel_url"] = channel_url
if canned_messages:
configObj["canned_messages"] = canned_messages
if ringtone:
configObj["ringtone"] = ringtone
# lat and lon don't make much sense without the other (so fill with 0s), and alt isn't meaningful without both
if lat or lon:
configObj["location"] = {"lat": lat or float(0), "lon": lon or float(0)}
@@ -1192,7 +1104,6 @@ def export_config(interface) -> str:
configObj["location"]["alt"] = alt
config = MessageToDict(interface.localNode.localConfig) #checkme - Used as a dictionary here and a string below
#was used as a string here and a Dictionary above
if config:
# Convert inner keys to correct snake/camelCase
prefs = {}
@@ -1215,8 +1126,6 @@ def export_config(interface) -> str:
else:
configObj["config"] = config
set_missing_flags_false(configObj["config"], true_defaults)
module_config = MessageToDict(interface.localNode.moduleConfig)
if module_config:
# Convert inner keys to correct snake/camelCase
@@ -1232,6 +1141,7 @@ def export_config(interface) -> str:
config_txt = "# start of Meshtastic configure yaml\n" #checkme - "config" (now changed to config_out)
#was used as a string here and a Dictionary above
config_txt += yaml.dump(configObj)
print(config_txt)
return config_txt
@@ -1259,14 +1169,14 @@ def create_power_meter():
meter = SimPowerSupply()
if meter and v:
logger.info(f"Setting power supply to {v} volts")
logging.info(f"Setting power supply to {v} volts")
meter.v = v
meter.powerOn()
if args.power_wait:
input("Powered on, press enter to continue...")
else:
logger.info("Powered-on, waiting for device to boot")
logging.info("Powered-on, waiting for device to boot")
time.sleep(5)
@@ -1280,10 +1190,6 @@ def common():
format="%(levelname)s file:%(filename)s %(funcName)s line:%(lineno)s %(message)s",
)
# set all meshtastic loggers to DEBUG
if not (args.debug or args.listen) and args.debuglib:
logging.getLogger('meshtastic').setLevel(logging.DEBUG)
if len(sys.argv) == 1:
parser.print_help(sys.stderr)
meshtastic.util.our_exit("", 1)
@@ -1292,22 +1198,6 @@ def common():
meshtastic.util.support_info()
meshtastic.util.our_exit("", 0)
# Early validation for owner names before attempting device connection
if hasattr(args, 'set_owner') and args.set_owner is not None:
stripped_long_name = args.set_owner.strip()
if not stripped_long_name:
meshtastic.util.our_exit("ERROR: Long Name cannot be empty or contain only whitespace characters")
if hasattr(args, 'set_owner_short') and args.set_owner_short is not None:
stripped_short_name = args.set_owner_short.strip()
if not stripped_short_name:
meshtastic.util.our_exit("ERROR: Short Name cannot be empty or contain only whitespace characters")
if hasattr(args, 'set_ham') and args.set_ham is not None:
stripped_ham_name = args.set_ham.strip()
if not stripped_ham_name:
meshtastic.util.our_exit("ERROR: Ham radio callsign cannot be empty or contain only whitespace characters")
if have_powermon:
create_power_meter()
@@ -1325,7 +1215,7 @@ def common():
args.seriallog = "none" # assume no debug output in this case
if args.deprecated is not None:
logger.error(
logging.error(
"This option has been deprecated, see help below for the correct replacement..."
)
parser.print_help(sys.stderr)
@@ -1344,10 +1234,10 @@ def common():
logfile = sys.stdout
elif args.seriallog == "none":
args.seriallog = None
logger.debug("Not logging serial output")
logging.debug("Not logging serial output")
logfile = None
else:
logger.info(f"Logging serial output to {args.seriallog}")
logging.info(f"Logging serial output to {args.seriallog}")
# Note: using "line buffering"
# pylint: disable=R1732
logfile = open(args.seriallog, "w+", buffering=1, encoding="utf8")
@@ -1355,7 +1245,7 @@ def common():
subscribe()
if args.ble_scan:
logger.debug("BLE scan starting")
logging.debug("BLE scan starting")
for x in BLEInterface.scan():
print(f"Found: name='{x.name}' address='{x.address}'")
meshtastic.util.our_exit("BLE scan finished", 0)
@@ -1365,7 +1255,6 @@ def common():
debugOut=logfile,
noProto=args.noproto,
noNodes=args.no_nodes,
timeout=args.timeout,
)
elif args.host:
try:
@@ -1380,7 +1269,6 @@ def common():
debugOut=logfile,
noProto=args.noproto,
noNodes=args.no_nodes,
timeout=args.timeout,
)
except Exception as ex:
meshtastic.util.our_exit(f"Error connecting to {args.host}:{ex}", 1)
@@ -1391,7 +1279,6 @@ def common():
debugOut=logfile,
noProto=args.noproto,
noNodes=args.no_nodes,
timeout=args.timeout,
)
except FileNotFoundError:
# Handle the case where the serial device is not found
@@ -1429,7 +1316,6 @@ def common():
debugOut=logfile,
noProto=args.noproto,
noNodes=args.no_nodes,
timeout=args.timeout,
)
except Exception as ex:
meshtastic.util.our_exit(
@@ -1450,7 +1336,7 @@ def common():
while True:
time.sleep(1000)
except KeyboardInterrupt:
logger.info("Exiting due to keyboard interrupt")
logging.info("Exiting due to keyboard interrupt")
# don't call exit, background threads might be running still
# sys.exit(0)
@@ -1539,10 +1425,8 @@ def addImportExportArgs(parser: argparse.ArgumentParser) -> argparse.ArgumentPar
)
group.add_argument(
"--export-config",
nargs="?",
const="-", # default to "-" if no value provided
metavar="FILE",
help="Export device config as YAML (to stdout if no file given)"
help="Export the configuration in yaml(.yml) format.",
action="store_true",
)
return parser
@@ -1664,11 +1548,6 @@ def addConfigArgs(parser: argparse.ArgumentParser) -> argparse.ArgumentParser:
"--set-ham", help="Set licensed Ham ID and turn off encryption", action="store"
)
group.add_argument(
"--set-is-unmessageable", "--set-is-unmessagable",
help="Set if a node is messageable or not", action="store"
)
group.add_argument(
"--ch-set-url", "--seturl",
help="Set all channels and set LoRa config from a supplied URL",
@@ -1931,12 +1810,40 @@ def addRemoteAdminArgs(parser: argparse.ArgumentParser) -> argparse.ArgumentPars
action="store_true",
)
group.add_argument(
"--backup-prefs",
help="Tell the destination node to create a backup preferences file."
"Location: 0 for local flash, 1 for SD card.",
default=admin_pb2.AdminMessage.BackupLocation.FLASH,
nargs="?",
const=0,
)
group.add_argument(
"--restore-prefs",
help="Tell the destination node to remove backup preferences files."
"Location: 0 for local flash, 1 for SD card.",
default=admin_pb2.AdminMessage.BackupLocation.FLASH,
nargs="?",
const=0,
)
group.add_argument(
"--remove-backup-prefs",
help="Tell the destination node to remove backup preferences files."
"Location: 0 for local flash, 1 for SD card.",
default=admin_pb2.AdminMessage.BackupLocation.FLASH,
nargs="?",
const=0,
)
group.add_argument(
"--remove-node",
help="Tell the destination node to remove a specific node from its NodeDB. "
"Use the node ID with a '!' or '0x' prefix or the node number.",
metavar="!xxxxxxxx"
)
group.add_argument(
"--set-favorite-node",
help="Tell the destination node to set the specified node to be favorited on the NodeDB. "
@@ -2057,10 +1964,6 @@ def initParser():
"--debug", help="Show API library debug log messages", action="store_true"
)
group.add_argument(
"--debuglib", help="Show only API library debug log messages", action="store_true"
)
group.add_argument(
"--test",
help="Run stress test against all connected Meshtastic devices",

View File

@@ -2,7 +2,6 @@
import argparse
import logging
import os
from typing import cast, List
import dash_bootstrap_components as dbc # type: ignore[import-untyped]
@@ -144,8 +143,8 @@ def create_dash(slog_path: str) -> Dash:
"""
app = Dash(external_stylesheets=[dbc.themes.BOOTSTRAP])
dpwr = read_pandas(os.path.join(slog_path, "power.feather"))
dslog = read_pandas(os.path.join(slog_path, "slog.feather"))
dpwr = read_pandas(f"{slog_path}/power.feather")
dslog = read_pandas(f"{slog_path}/slog.feather")
pmon_raises = get_pmon_raises(dslog)
@@ -191,7 +190,7 @@ def main():
parser = create_argparser()
args = parser.parse_args()
if not args.slog:
args.slog = os.path.join(root_dir(), "latest")
args.slog = f"{root_dir()}/latest"
app = create_dash(slog_path=args.slog)
port = 8051

View File

@@ -23,7 +23,6 @@ FROMRADIO_UUID = "2c55e69e-4993-11ed-b878-0242ac120002"
FROMNUM_UUID = "ed9da18c-a800-4f66-a670-aa7547e34453"
LEGACY_LOGRADIO_UUID = "6c6fd238-78fa-436b-aacf-15c5be1ef2e2"
LOGRADIO_UUID = "5a3d6e49-06e6-4423-9944-e9de8cdf9547"
logger = logging.getLogger(__name__)
class BLEInterface(MeshInterface):
@@ -32,33 +31,32 @@ class BLEInterface(MeshInterface):
class BLEError(Exception):
"""An exception class for BLE errors."""
def __init__( # pylint: disable=R0917
def __init__(
self,
address: Optional[str],
noProto: bool = False,
debugOut: Optional[io.TextIOWrapper]=None,
noNodes: bool = False,
timeout: int = 300,
) -> None:
MeshInterface.__init__(
self, debugOut=debugOut, noProto=noProto, noNodes=noNodes, timeout=timeout
self, debugOut=debugOut, noProto=noProto, noNodes=noNodes
)
self.should_read = False
logger.debug("Threads starting")
logging.debug("Threads starting")
self._want_receive = True
self._receiveThread: Optional[Thread] = Thread(
target=self._receiveFromRadioImpl, name="BLEReceive", daemon=True
)
self._receiveThread.start()
logger.debug("Threads running")
logging.debug("Threads running")
self.client: Optional[BLEClient] = None
try:
logger.debug(f"BLE connecting to: {address if address else 'any'}")
logging.debug(f"BLE connecting to: {address if address else 'any'}")
self.client = self.connect(address)
logger.debug("BLE connected")
logging.debug("BLE connected")
except BLEInterface.BLEError as e:
self.close()
raise e
@@ -71,13 +69,13 @@ class BLEInterface(MeshInterface):
if self.client.has_characteristic(LOGRADIO_UUID):
self.client.start_notify(LOGRADIO_UUID, self.log_radio_handler)
logger.debug("Mesh configure starting")
logging.debug("Mesh configure starting")
self._startConfig()
if not self.noProto:
self._waitConnected(timeout=60.0)
self.waitForConfig()
logger.debug("Register FROMNUM notify callback")
logging.debug("Register FROMNUM notify callback")
self.client.start_notify(FROMNUM_UUID, self.from_num_handler)
# We MUST run atexit (if we can) because otherwise (at least on linux) the BLE device is not disconnected
@@ -85,23 +83,12 @@ class BLEInterface(MeshInterface):
# Note: the on disconnected callback will call our self.close which will make us nicely wait for threads to exit
self._exit_handler = atexit.register(self.client.disconnect)
def __repr__(self):
rep = f"BLEInterface(address={self.client.address if self.client else None!r}"
if self.debugOut is not None:
rep += f", debugOut={self.debugOut!r}"
if self.noProto:
rep += ", noProto=True"
if self.noNodes:
rep += ", noNodes=True"
rep += ")"
return rep
def from_num_handler(self, _, b: bytes) -> None: # pylint: disable=C0116
"""Handle callbacks for fromnum notify.
Note: this method does not need to be async because it is just setting a bool.
"""
from_num = struct.unpack("<I", bytes(b))[0]
logger.debug(f"FROMNUM notify: {from_num}")
logging.debug(f"FROMNUM notify: {from_num}")
self.should_read = True
async def log_radio_handler(self, _, b): # pylint: disable=C0116
@@ -116,7 +103,7 @@ class BLEInterface(MeshInterface):
)
self._handleLogLine(message)
except google.protobuf.message.DecodeError:
logger.warning("Malformed LogRecord received. Skipping.")
logging.warning("Malformed LogRecord received. Skipping.")
async def legacy_log_radio_handler(self, _, b): # pylint: disable=C0116
log_radio = b.decode("utf-8").replace("\n", "")
@@ -126,7 +113,7 @@ class BLEInterface(MeshInterface):
def scan() -> List[BLEDevice]:
"""Scan for available BLE devices."""
with BLEClient() as client:
logger.info("Scanning for BLE devices (takes 10 seconds)...")
logging.info("Scanning for BLE devices (takes 10 seconds)...")
response = client.discover(
timeout=10, return_adv=True, service_uuids=[SERVICE_UUID]
)
@@ -176,7 +163,7 @@ class BLEInterface(MeshInterface):
# Bleak docs recommend always doing a scan before connecting (even if we know addr)
device = self.find_device(address)
client = BLEClient(device.address, disconnected_callback=lambda _: self.close())
client = BLEClient(device.address, disconnected_callback=lambda _: self.close)
client.connect()
client.discover()
return client
@@ -188,19 +175,19 @@ class BLEInterface(MeshInterface):
retries: int = 0
while self._want_receive:
if self.client is None:
logger.debug(f"BLE client is None, shutting down")
logging.debug(f"BLE client is None, shutting down")
self._want_receive = False
continue
try:
b = bytes(self.client.read_gatt_char(FROMRADIO_UUID))
except BleakDBusError as e:
# Device disconnected probably, so end our read loop immediately
logger.debug(f"Device disconnected, shutting down {e}")
logging.debug(f"Device disconnected, shutting down {e}")
self._want_receive = False
except BleakError as e:
# We were definitely disconnected
if "Not connected" in str(e):
logger.debug(f"Device disconnected, shutting down {e}")
logging.debug(f"Device disconnected, shutting down {e}")
self._want_receive = False
else:
raise BLEInterface.BLEError("Error reading BLE") from e
@@ -210,7 +197,7 @@ class BLEInterface(MeshInterface):
retries += 1
continue
break
logger.debug(f"FROMRADIO read: {b.hex()}")
logging.debug(f"FROMRADIO read: {b.hex()}")
self._handleFromRadio(b)
else:
time.sleep(0.01)
@@ -218,7 +205,7 @@ class BLEInterface(MeshInterface):
def _sendToRadioImpl(self, toRadio) -> None:
b: bytes = toRadio.SerializeToString()
if b and self.client: # we silently ignore writes while we are shutting down
logger.debug(f"TORADIO write: {b.hex()}")
logging.debug(f"TORADIO write: {b.hex()}")
try:
self.client.write_gatt_char(
TORADIO_UUID, b, response=True
@@ -236,7 +223,7 @@ class BLEInterface(MeshInterface):
try:
MeshInterface.close(self)
except Exception as e:
logger.error(f"Error closing mesh interface: {e}")
logging.error(f"Error closing mesh interface: {e}")
if self._want_receive:
self._want_receive = False # Tell the thread we want it to stop
@@ -265,7 +252,7 @@ class BLEClient:
self._eventThread.start()
if not address:
logger.debug("No address provided - only discover method will work.")
logging.debug("No address provided - only discover method will work.")
return
self.bleak_client = BleakClient(address, **kwargs)

View File

@@ -1,6 +1,6 @@
"""Mesh Interface class
"""
# pylint: disable=R0917,C0302
# pylint: disable=R0917
import collections
import json
@@ -17,7 +17,6 @@ from decimal import Decimal
from typing import Any, Callable, Dict, List, Optional, Union
import google.protobuf.json_format
try:
import print_color # type: ignore[import-untyped]
except ImportError as e:
@@ -47,7 +46,6 @@ from meshtastic.util import (
stripnl,
)
logger = logging.getLogger(__name__)
def _timeago(delta_secs: int) -> str:
"""Convert a number of seconds in the past into a short, friendly string
@@ -90,7 +88,7 @@ class MeshInterface: # pylint: disable=R0902
super().__init__(self.message)
def __init__(
self, debugOut=None, noProto: bool = False, noNodes: bool = False, timeout: int = 300
self, debugOut=None, noProto: bool = False, noNodes: bool = False
) -> None:
"""Constructor
@@ -99,14 +97,13 @@ class MeshInterface: # pylint: disable=R0902
link - just be a dumb serial client.
noNodes -- If True, instruct the node to not send its nodedb
on startup, just other configuration information.
timeout -- How long to wait for replies (default: 300 seconds)
"""
self.debugOut = debugOut
self.nodes: Optional[Dict[str, Dict]] = None # FIXME
self.isConnected: threading.Event = threading.Event()
self.noProto: bool = noProto
self.localNode: meshtastic.node.Node = meshtastic.node.Node(
self, -1, timeout=timeout
self, -1
) # We fixup nodenum later
self.myInfo: Optional[
mesh_pb2.MyNodeInfo
@@ -120,7 +117,7 @@ class MeshInterface: # pylint: disable=R0902
self.failure = (
None # If we've encountered a fatal exception it will be kept here
)
self._timeout: Timeout = Timeout(maxSecs=timeout)
self._timeout: Timeout = Timeout()
self._acknowledgment: Acknowledgment = Acknowledgment()
self.heartbeatTimer: Optional[threading.Timer] = None
random.seed() # FIXME, we should not clobber the random seedval here, instead tell user they must call it
@@ -152,11 +149,11 @@ class MeshInterface: # pylint: disable=R0902
def __exit__(self, exc_type, exc_value, trace):
if exc_type is not None and exc_value is not None:
logger.error(
logging.error(
f"An exception of type {exc_type} with value {exc_value} has occurred"
)
if trace is not None:
logger.error(f"Traceback:\n{''.join(traceback.format_tb(trace))}")
logging.error(f"Traceback: {trace}")
self.close()
@staticmethod
@@ -284,7 +281,7 @@ class MeshInterface: # pylint: disable=R0902
def getNestedValue(node_dict: Dict[str, Any], key_path: str) -> Any:
if key_path.index(".") < 0:
logger.debug("getNestedValue was called without a nested path.")
logging.debug("getNestedValue was called without a nested path.")
return None
keys = key_path.split(".")
value: Optional[Union[str, dict]] = node_dict
@@ -307,7 +304,7 @@ class MeshInterface: # pylint: disable=R0902
rows: List[Dict[str, Any]] = []
if self.nodesByNum:
logger.debug(f"self.nodes:{self.nodes}")
logging.debug(f"self.nodes:{self.nodes}")
for node in self.nodesByNum.values():
if not includeSelf and node["num"] == self.localNode.nodeNum:
continue
@@ -386,7 +383,7 @@ class MeshInterface: # pylint: disable=R0902
n = meshtastic.node.Node(self, nodeId, timeout=timeout)
# Only request device settings and channel info when necessary
if requestChannels:
logger.debug("About to requestChannels")
logging.debug("About to requestChannels")
n.requestChannels()
retries_left = requestChannelAttempts
last_index: int = 0
@@ -414,8 +411,7 @@ class MeshInterface: # pylint: disable=R0902
wantResponse: bool = False,
onResponse: Optional[Callable[[dict], Any]] = None,
channelIndex: int = 0,
portNum: portnums_pb2.PortNum.ValueType = portnums_pb2.PortNum.TEXT_MESSAGE_APP,
replyId: Optional[int]=None,
portNum: portnums_pb2.PortNum.ValueType = portnums_pb2.PortNum.TEXT_MESSAGE_APP
):
"""Send a utf8 string to some other node, if the node has a display it
will also be shown on the device.
@@ -432,7 +428,6 @@ class MeshInterface: # pylint: disable=R0902
send an application layer response
portNum -- the application portnum (similar to IP port numbers)
of the destination, see portnums.proto for a list
replyId -- the ID of the message that this packet is a response to
Returns the sent packet. The id field will be populated in this packet
and can be used to track future message acks/naks.
@@ -446,7 +441,6 @@ class MeshInterface: # pylint: disable=R0902
wantResponse=wantResponse,
onResponse=onResponse,
channelIndex=channelIndex,
replyId=replyId
)
@@ -457,7 +451,7 @@ class MeshInterface: # pylint: disable=R0902
onResponse: Optional[Callable[[dict], Any]] = None,
channelIndex: int = 0,
):
"""Send an alert text to some other node. This is similar to a text message,
"""Send an alert text to some other node. This is similar to a text message,
but carries a higher priority and is capable of generating special notifications
on certain clients.
@@ -483,18 +477,6 @@ class MeshInterface: # pylint: disable=R0902
priority=mesh_pb2.MeshPacket.Priority.ALERT
)
def sendMqttClientProxyMessage(self, topic: str, data: bytes):
"""Send an MQTT Client Proxy message to the radio.
Topic and data should be the MQTT topic and the message
payload from an MQTT broker, respectively."""
prox = mesh_pb2.MqttClientProxyMessage()
prox.topic = topic
prox.data = data
toRadio = mesh_pb2.ToRadio()
toRadio.mqttClientProxyMessage.CopyFrom(prox)
self._sendToRadio(toRadio)
def sendData(
self,
data,
@@ -509,7 +491,6 @@ class MeshInterface: # pylint: disable=R0902
pkiEncrypted: Optional[bool]=False,
publicKey: Optional[bytes]=None,
priority: mesh_pb2.MeshPacket.Priority.ValueType=mesh_pb2.MeshPacket.Priority.RELIABLE,
replyId: Optional[int]=None,
): # pylint: disable=R0913
"""Send a data packet to some other node
@@ -534,18 +515,17 @@ class MeshInterface: # pylint: disable=R0902
will implicitly be true.
channelIndex -- channel number to use
hopLimit -- hop limit to use
replyId -- the ID of the message that this packet is a response to
Returns the sent packet. The id field will be populated in this packet
and can be used to track future message acks/naks.
"""
if getattr(data, "SerializeToString", None):
logger.debug(f"Serializing protobuf as data: {stripnl(data)}")
logging.debug(f"Serializing protobuf as data: {stripnl(data)}")
data = data.SerializeToString()
logger.debug(f"len(data): {len(data)}")
logger.debug(
logging.debug(f"len(data): {len(data)}")
logging.debug(
f"mesh_pb2.Constants.DATA_PAYLOAD_LEN: {mesh_pb2.Constants.DATA_PAYLOAD_LEN}"
)
if len(data) > mesh_pb2.Constants.DATA_PAYLOAD_LEN:
@@ -562,13 +542,11 @@ class MeshInterface: # pylint: disable=R0902
meshPacket.decoded.portnum = portNum
meshPacket.decoded.want_response = wantResponse
meshPacket.id = self._generatePacketId()
if replyId is not None:
meshPacket.decoded.reply_id = replyId
if priority is not None:
meshPacket.priority = priority
if onResponse is not None:
logger.debug(f"Setting a response handler for requestId {meshPacket.id}")
logging.debug(f"Setting a response handler for requestId {meshPacket.id}")
self._addResponseHandler(meshPacket.id, onResponse, ackPermitted=onResponseAckPermitted)
p = self._sendPacket(meshPacket, destinationId, wantAck=wantAck, hopLimit=hopLimit, pkiEncrypted=pkiEncrypted, publicKey=publicKey)
return p
@@ -595,15 +573,15 @@ class MeshInterface: # pylint: disable=R0902
p = mesh_pb2.Position()
if latitude != 0.0:
p.latitude_i = int(latitude / 1e-7)
logger.debug(f"p.latitude_i:{p.latitude_i}")
logging.debug(f"p.latitude_i:{p.latitude_i}")
if longitude != 0.0:
p.longitude_i = int(longitude / 1e-7)
logger.debug(f"p.longitude_i:{p.longitude_i}")
logging.debug(f"p.longitude_i:{p.longitude_i}")
if altitude != 0:
p.altitude = int(altitude)
logger.debug(f"p.altitude:{p.altitude}")
logging.debug(f"p.altitude:{p.altitude}")
if wantResponse:
onResponse = self.onResponsePosition
@@ -830,7 +808,6 @@ class MeshInterface: # pylint: disable=R0902
self,
name,
description,
icon,
expire: int,
waypoint_id: Optional[int] = None,
latitude: float = 0.0,
@@ -849,22 +826,21 @@ class MeshInterface: # pylint: disable=R0902
w = mesh_pb2.Waypoint()
w.name = name
w.description = description
w.icon = icon
w.expire = expire
if waypoint_id is None:
# Generate a waypoint's id, NOT a packet ID.
# same algorithm as https://github.com/meshtastic/js/blob/715e35d2374276a43ffa93c628e3710875d43907/src/meshDevice.ts#L791
seed = secrets.randbits(32)
w.id = math.floor(seed * math.pow(2, -32) * 1e9)
logger.debug(f"w.id:{w.id}")
logging.debug(f"w.id:{w.id}")
else:
w.id = waypoint_id
if latitude != 0.0:
w.latitude_i = int(latitude * 1e7)
logger.debug(f"w.latitude_i:{w.latitude_i}")
logging.debug(f"w.latitude_i:{w.latitude_i}")
if longitude != 0.0:
w.longitude_i = int(longitude * 1e7)
logger.debug(f"w.longitude_i:{w.longitude_i}")
logging.debug(f"w.longitude_i:{w.longitude_i}")
if wantResponse:
onResponse = self.onResponseWaypoint
@@ -896,7 +872,7 @@ class MeshInterface: # pylint: disable=R0902
Send a waypoint deletion packet to some other node (normally a broadcast)
NB: The id must be the waypoint's id and not the id of the packet creation.
Returns the sent packet. The id field will be populated in this packet and
can be used to track future message acks/naks.
"""
@@ -979,7 +955,7 @@ class MeshInterface: # pylint: disable=R0902
else:
nodeNum = node["num"]
else:
logger.warning("Warning: There were no self.nodes.")
logging.warning("Warning: There were no self.nodes.")
meshPacket.to = nodeNum
meshPacket.want_ack = wantAck
@@ -1003,11 +979,11 @@ class MeshInterface: # pylint: disable=R0902
toRadio.packet.CopyFrom(meshPacket)
if self.noProto:
logger.warning(
logging.warning(
"Not sending packet because protocol use is disabled by noProto"
)
else:
logger.debug(f"Sending packet: {stripnl(meshPacket)}")
logging.debug(f"Sending packet: {stripnl(meshPacket)}")
self._sendToRadio(toRadio)
return meshPacket
@@ -1058,7 +1034,7 @@ class MeshInterface: # pylint: disable=R0902
"""Get info about my node."""
if self.myInfo is None or self.nodesByNum is None:
return None
logger.debug(f"self.nodesByNum:{self.nodesByNum}")
logging.debug(f"self.nodesByNum:{self.nodesByNum}")
return self.nodesByNum.get(self.myInfo.my_node_num)
def getMyUser(self):
@@ -1089,20 +1065,6 @@ class MeshInterface: # pylint: disable=R0902
return user.get("publicKey", None)
return None
def getCannedMessage(self):
"""Get canned message"""
node = self.localNode
if node is not None:
return node.get_canned_message()
return None
def getRingtone(self):
"""Get ringtone"""
node = self.localNode
if node is not None:
return node.get_ringtone()
return None
def _waitConnected(self, timeout=30.0):
"""Block until the initial node db download is complete, or timeout
and raise an exception"""
@@ -1148,7 +1110,7 @@ class MeshInterface: # pylint: disable=R0902
def callback():
self.heartbeatTimer = None
interval = 300
logger.debug(f"Sending heartbeat, interval {interval} seconds")
logging.debug(f"Sending heartbeat, interval {interval} seconds")
self.heartbeatTimer = threading.Timer(interval, callback)
self.heartbeatTimer.start()
self.sendHeartbeat()
@@ -1206,11 +1168,11 @@ class MeshInterface: # pylint: disable=R0902
def _sendToRadio(self, toRadio: mesh_pb2.ToRadio) -> None:
"""Send a ToRadio protobuf to the device"""
if self.noProto:
logger.warning(
logging.warning(
"Not sending packet because protocol use is disabled by noProto"
)
else:
# logger.debug(f"Sending toRadio: {stripnl(toRadio)}")
# logging.debug(f"Sending toRadio: {stripnl(toRadio)}")
if not toRadio.HasField("packet"):
# not a meshpacket -- send immediately, give queue a chance,
@@ -1223,38 +1185,38 @@ class MeshInterface: # pylint: disable=R0902
resentQueue = collections.OrderedDict()
while self.queue:
# logger.warn("queue: " + " ".join(f'{k:08x}' for k in self.queue))
# logging.warn("queue: " + " ".join(f'{k:08x}' for k in self.queue))
while not self._queueHasFreeSpace():
logger.debug("Waiting for free space in TX Queue")
logging.debug("Waiting for free space in TX Queue")
time.sleep(0.5)
try:
toResend = self.queue.popitem(last=False)
except KeyError:
break
packetId, packet = toResend
# logger.warn(f"packet: {packetId:08x} {packet}")
# logging.warn(f"packet: {packetId:08x} {packet}")
resentQueue[packetId] = packet
if packet is False:
continue
self._queueClaim()
if packet != toRadio:
logger.debug(f"Resending packet ID {packetId:08x} {packet}")
logging.debug(f"Resending packet ID {packetId:08x} {packet}")
self._sendToRadioImpl(packet)
# logger.warn("resentQueue: " + " ".join(f'{k:08x}' for k in resentQueue))
# logging.warn("resentQueue: " + " ".join(f'{k:08x}' for k in resentQueue))
for packetId, packet in resentQueue.items():
if (
self.queue.pop(packetId, False) is False
): # Packet got acked under us
logger.debug(f"packet {packetId:08x} got acked under us")
logging.debug(f"packet {packetId:08x} got acked under us")
continue
if packet:
self.queue[packetId] = packet
# logger.warn("queue + resentQueue: " + " ".join(f'{k:08x}' for k in self.queue))
# logging.warn("queue + resentQueue: " + " ".join(f'{k:08x}' for k in self.queue))
def _sendToRadioImpl(self, toRadio: mesh_pb2.ToRadio) -> None:
"""Send a ToRadio protobuf to the device"""
logger.error(f"Subclass must provide toradio: {toRadio}")
logging.error(f"Subclass must provide toradio: {toRadio}")
def _handleConfigComplete(self) -> None:
"""
@@ -1270,22 +1232,22 @@ class MeshInterface: # pylint: disable=R0902
def _handleQueueStatusFromRadio(self, queueStatus) -> None:
self.queueStatus = queueStatus
logger.debug(
logging.debug(
f"TX QUEUE free {queueStatus.free} of {queueStatus.maxlen}, res = {queueStatus.res}, id = {queueStatus.mesh_packet_id:08x} "
)
if queueStatus.res:
return
# logger.warn("queue: " + " ".join(f'{k:08x}' for k in self.queue))
# logging.warn("queue: " + " ".join(f'{k:08x}' for k in self.queue))
justQueued = self.queue.pop(queueStatus.mesh_packet_id, None)
if justQueued is None and queueStatus.mesh_packet_id != 0:
self.queue[queueStatus.mesh_packet_id] = False
logger.debug(
logging.debug(
f"Reply for unexpected packet ID {queueStatus.mesh_packet_id:08x}"
)
# logger.warn("queue: " + " ".join(f'{k:08x}' for k in self.queue))
# logging.warn("queue: " + " ".join(f'{k:08x}' for k in self.queue))
def _handleFromRadio(self, fromRadioBytes):
"""
@@ -1293,30 +1255,30 @@ class MeshInterface: # pylint: disable=R0902
Called by subclasses."""
fromRadio = mesh_pb2.FromRadio()
logger.debug(
logging.debug(
f"in mesh_interface.py _handleFromRadio() fromRadioBytes: {fromRadioBytes}"
)
try:
fromRadio.ParseFromString(fromRadioBytes)
except Exception as ex:
logger.error(
logging.error(
f"Error while parsing FromRadio bytes:{fromRadioBytes} {ex}"
)
traceback.print_exc()
raise ex
asDict = google.protobuf.json_format.MessageToDict(fromRadio)
logger.debug(f"Received from radio: {fromRadio}")
logging.debug(f"Received from radio: {fromRadio}")
if fromRadio.HasField("my_info"):
self.myInfo = fromRadio.my_info
self.localNode.nodeNum = self.myInfo.my_node_num
logger.debug(f"Received myinfo: {stripnl(fromRadio.my_info)}")
logging.debug(f"Received myinfo: {stripnl(fromRadio.my_info)}")
elif fromRadio.HasField("metadata"):
self.metadata = fromRadio.metadata
logger.debug(f"Received device metadata: {stripnl(fromRadio.metadata)}")
logging.debug(f"Received device metadata: {stripnl(fromRadio.metadata)}")
elif fromRadio.HasField("node_info"):
logger.debug(f"Received nodeinfo: {asDict['nodeInfo']}")
logging.debug(f"Received nodeinfo: {asDict['nodeInfo']}")
node = self._getOrCreateByNum(asDict["nodeInfo"]["num"])
node.update(asDict["nodeInfo"])
@@ -1324,7 +1286,7 @@ class MeshInterface: # pylint: disable=R0902
newpos = self._fixupPosition(node["position"])
node["position"] = newpos
except:
logger.debug("Node without position")
logging.debug("Node without position")
# no longer necessary since we're mutating directly in nodesByNum via _getOrCreateByNum
# self.nodesByNum[node["num"]] = node
@@ -1339,7 +1301,7 @@ class MeshInterface: # pylint: disable=R0902
elif fromRadio.config_complete_id == self.configId:
# we ignore the config_complete_id, it is unneeded for our
# stream API fromRadio.config_complete_id
logger.debug(f"Config complete ID {self.configId}")
logging.debug(f"Config complete ID {self.configId}")
self._handleConfigComplete()
elif fromRadio.HasField("channel"):
self._handleChannel(fromRadio.channel)
@@ -1349,14 +1311,6 @@ class MeshInterface: # pylint: disable=R0902
self._handleLogRecord(fromRadio.log_record)
elif fromRadio.HasField("queueStatus"):
self._handleQueueStatusFromRadio(fromRadio.queueStatus)
elif fromRadio.HasField("clientNotification"):
publishingThread.queueWork(
lambda: pub.sendMessage(
"meshtastic.clientNotification",
notification=fromRadio.clientNotification,
interface=self,
)
)
elif fromRadio.HasField("mqttClientProxyMessage"):
publishingThread.queueWork(
@@ -1454,7 +1408,7 @@ class MeshInterface: # pylint: disable=R0902
)
else:
logger.debug("Unexpected FromRadio payload")
logging.debug("Unexpected FromRadio payload")
def _fixupPosition(self, position: Dict) -> Dict:
"""Convert integer lat/lon into floats
@@ -1488,7 +1442,7 @@ class MeshInterface: # pylint: disable=R0902
try:
return self.nodesByNum[num]["user"]["id"] # type: ignore[index]
except:
logger.debug(f"Node {num} not found for fromId")
logging.debug(f"Node {num} not found for fromId")
return None
def _getOrCreateByNum(self, nodeNum):
@@ -1544,7 +1498,7 @@ class MeshInterface: # pylint: disable=R0902
# from might be missing if the nodenum was zero.
if not hack and "from" not in asDict:
asDict["from"] = 0
logger.error(
logging.error(
f"Device returned a packet we sent, ignoring: {stripnl(asDict)}"
)
print(
@@ -1558,11 +1512,11 @@ class MeshInterface: # pylint: disable=R0902
try:
asDict["fromId"] = self._nodeNumToId(asDict["from"], False)
except Exception as ex:
logger.warning(f"Not populating fromId {ex}")
logging.warning(f"Not populating fromId {ex}")
try:
asDict["toId"] = self._nodeNumToId(asDict["to"])
except Exception as ex:
logger.warning(f"Not populating toId {ex}")
logging.warning(f"Not populating toId {ex}")
# We could provide our objects as DotMaps - which work with . notation or as dictionaries
# asObj = DotMap(asDict)
@@ -1582,7 +1536,7 @@ class MeshInterface: # pylint: disable=R0902
# it to prevent confusion
if "portnum" not in decoded:
decoded["portnum"] = portnum
logger.warning(f"portnum was not in decoded. Setting to:{portnum}")
logging.warning(f"portnum was not in decoded. Setting to:{portnum}")
else:
portnum = decoded["portnum"]
@@ -1614,7 +1568,7 @@ class MeshInterface: # pylint: disable=R0902
# Is this message in response to a request, if so, look for a handler
requestId = decoded.get("requestId")
if requestId is not None:
logger.debug(f"Got a response for requestId {requestId}")
logging.debug(f"Got a response for requestId {requestId}")
# We ignore ACK packets unless the callback is named `onAckNak`
# or the handler is set as ackPermitted, but send NAKs and
# other, data-containing responses to the handlers
@@ -1631,12 +1585,12 @@ class MeshInterface: # pylint: disable=R0902
or handler.ackPermitted
):
handler = self.responseHandlers.pop(requestId, None)
logger.debug(
logging.debug(
f"Calling response handler for requestId {requestId}"
)
handler.callback(asDict)
logger.debug(f"Publishing {topic}: packet={stripnl(asDict)} ")
logging.debug(f"Publishing {topic}: packet={stripnl(asDict)} ")
publishingThread.queueWork(
lambda: pub.sendMessage(topic, packet=asDict, interface=self)
)

View File

@@ -16,11 +16,8 @@ from meshtastic.util import (
pskToString,
stripnl,
message_to_json,
generate_channel_hash,
to_node_num,
)
logger = logging.getLogger(__name__)
class Node:
"""A model of a (local or remote) node in the mesh
@@ -45,30 +42,11 @@ class Node:
self.gotResponse = None
def __repr__(self):
r = f"Node({self.iface!r}, 0x{self.nodeNum:08x}"
if self.noProto:
r += ", noProto=True"
if self._timeout.expireTimeout != 300:
r += ", timeout={self._timeout.expireTimeout!r}"
r += ")"
return r
def module_available(self, excluded_bit: int) -> bool:
"""Check DeviceMetadata.excluded_modules to see if a module is available."""
meta = getattr(self.iface, "metadata", None)
if meta is None:
return True
try:
return (meta.excluded_modules & excluded_bit) == 0
except Exception:
return True
def showChannels(self):
"""Show human readable description of our channels."""
print("Channels:")
if self.channels:
logger.debug(f"self.channels:{self.channels}")
logging.debug(f"self.channels:{self.channels}")
for c in self.channels:
cStr = message_to_json(c.settings)
# don't show disabled channels
@@ -101,7 +79,7 @@ class Node:
def requestChannels(self, startingIndex: int = 0):
"""Send regular MeshPackets to ask channels."""
logger.debug(f"requestChannels for nodeNum:{self.nodeNum}")
logging.debug(f"requestChannels for nodeNum:{self.nodeNum}")
# only initialize if we're starting out fresh
if startingIndex == 0:
self.channels = None
@@ -110,7 +88,7 @@ class Node:
def onResponseRequestSettings(self, p):
"""Handle the response packets for requesting settings _requestSettings()"""
logger.debug(f"onResponseRequestSetting() p:{p}")
logging.debug(f"onResponseRequestSetting() p:{p}")
config_values = None
if "routing" in p["decoded"]:
if p["decoded"]["routing"]["errorReason"] != "NONE":
@@ -237,7 +215,7 @@ class Node:
else:
our_exit(f"Error: No valid config with name {config_name}")
logger.debug(f"Wrote: {config_name}")
logging.debug(f"Wrote: {config_name}")
if self == self.iface.localNode:
onResponse = None
else:
@@ -250,7 +228,7 @@ class Node:
p = admin_pb2.AdminMessage()
p.set_channel.CopyFrom(self.channels[channelIndex])
self._sendAdmin(p, adminIndex=adminIndex)
logger.debug(f"Wrote channel {channelIndex}")
logging.debug(f"Wrote channel {channelIndex}")
def getChannelByChannelIndex(self, channelIndex):
"""Get channel by channelIndex
@@ -311,37 +289,28 @@ class Node:
return c.index
return 0
def setOwner(self, long_name: Optional[str]=None, short_name: Optional[str]=None, is_licensed: bool=False, is_unmessagable: Optional[bool]=None):
def setOwner(self, long_name: Optional[str]=None, short_name: Optional[str]=None, is_licensed: bool=False):
"""Set device owner name"""
logger.debug(f"in setOwner nodeNum:{self.nodeNum}")
logging.debug(f"in setOwner nodeNum:{self.nodeNum}")
self.ensureSessionKey()
p = admin_pb2.AdminMessage()
nChars = 4
if long_name is not None:
long_name = long_name.strip()
# Validate that long_name is not empty or whitespace-only
if not long_name:
our_exit("ERROR: Long Name cannot be empty or contain only whitespace characters")
p.set_owner.long_name = long_name
p.set_owner.is_licensed = is_licensed
if short_name is not None:
short_name = short_name.strip()
# Validate that short_name is not empty or whitespace-only
if not short_name:
our_exit("ERROR: Short Name cannot be empty or contain only whitespace characters")
if len(short_name) > nChars:
short_name = short_name[:nChars]
print(f"Maximum is 4 characters, truncated to {short_name}")
p.set_owner.short_name = short_name
if is_unmessagable is not None:
p.set_owner.is_unmessagable = is_unmessagable
# Note: These debug lines are used in unit tests
logger.debug(f"p.set_owner.long_name:{p.set_owner.long_name}:")
logger.debug(f"p.set_owner.short_name:{p.set_owner.short_name}:")
logger.debug(f"p.set_owner.is_licensed:{p.set_owner.is_licensed}")
logger.debug(f"p.set_owner.is_unmessagable:{p.set_owner.is_unmessagable}:")
logging.debug(f"p.set_owner.long_name:{p.set_owner.long_name}:")
logging.debug(f"p.set_owner.short_name:{p.set_owner.short_name}:")
logging.debug(f"p.set_owner.is_licensed:{p.set_owner.is_licensed}")
# If sending to a remote node, wait for ACK/NAK
if self == self.iface.localNode:
onResponse = None
@@ -424,7 +393,7 @@ class Node:
ch.index = i
ch.settings.CopyFrom(chs)
self.channels[ch.index] = ch
logger.debug(f"Channel i:{i} ch:{ch}")
logging.debug(f"Channel i:{i} ch:{ch}")
self.writeChannel(ch.index)
i = i + 1
@@ -435,7 +404,7 @@ class Node:
def onResponseRequestRingtone(self, p):
"""Handle the response packet for requesting ringtone part 1"""
logger.debug(f"onResponseRequestRingtone() p:{p}")
logging.debug(f"onResponseRequestRingtone() p:{p}")
errorFound = False
if "routing" in p["decoded"]:
if p["decoded"]["routing"]["errorReason"] != "NONE":
@@ -448,16 +417,12 @@ class Node:
self.ringtonePart = p["decoded"]["admin"][
"raw"
].get_ringtone_response
logger.debug(f"self.ringtonePart:{self.ringtonePart}")
logging.debug(f"self.ringtonePart:{self.ringtonePart}")
self.gotResponse = True
def get_ringtone(self):
"""Get the ringtone. Concatenate all pieces together and return a single string."""
logger.debug(f"in get_ringtone()")
if not self.module_available(mesh_pb2.EXTNOTIF_CONFIG):
logging.warning("External Notification module not present (excluded by firmware)")
return None
logging.debug(f"in get_ringtone()")
if not self.ringtone:
p1 = admin_pb2.AdminMessage()
p1.get_ringtone_request = True
@@ -468,20 +433,18 @@ class Node:
while self.gotResponse is False:
time.sleep(0.1)
logger.debug(f"self.ringtone:{self.ringtone}")
logging.debug(f"self.ringtone:{self.ringtone}")
self.ringtone = ""
if self.ringtonePart:
self.ringtone += self.ringtonePart
logger.debug(f"ringtone:{self.ringtone}")
print(f"ringtone:{self.ringtone}")
logging.debug(f"ringtone:{self.ringtone}")
return self.ringtone
def set_ringtone(self, ringtone):
"""Set the ringtone. The ringtone length must be less than 230 character."""
if not self.module_available(mesh_pb2.EXTNOTIF_CONFIG):
logging.warning("External Notification module not present (excluded by firmware)")
return None
if len(ringtone) > 230:
our_exit("Warning: The ringtone must be less than 230 characters.")
@@ -501,7 +464,7 @@ class Node:
if i == 0:
p.set_ringtone_message = chunk
logger.debug(f"Setting ringtone '{chunk}' part {i+1}")
logging.debug(f"Setting ringtone '{chunk}' part {i+1}")
# If sending to a remote node, wait for ACK/NAK
if self == self.iface.localNode:
onResponse = None
@@ -511,7 +474,7 @@ class Node:
def onResponseRequestCannedMessagePluginMessageMessages(self, p):
"""Handle the response packet for requesting canned message plugin message part 1"""
logger.debug(f"onResponseRequestCannedMessagePluginMessageMessages() p:{p}")
logging.debug(f"onResponseRequestCannedMessagePluginMessageMessages() p:{p}")
errorFound = False
if "routing" in p["decoded"]:
if p["decoded"]["routing"]["errorReason"] != "NONE":
@@ -524,17 +487,14 @@ class Node:
self.cannedPluginMessageMessages = p["decoded"]["admin"][
"raw"
].get_canned_message_module_messages_response
logger.debug(
logging.debug(
f"self.cannedPluginMessageMessages:{self.cannedPluginMessageMessages}"
)
self.gotResponse = True
def get_canned_message(self):
"""Get the canned message string. Concatenate all pieces together and return a single string."""
logger.debug(f"in get_canned_message()")
if not self.module_available(mesh_pb2.CANNEDMSG_CONFIG):
logging.warning("Canned Message module not present (excluded by firmware)")
return None
logging.debug(f"in get_canned_message()")
if not self.cannedPluginMessage:
p1 = admin_pb2.AdminMessage()
p1.get_canned_message_module_messages_request = True
@@ -547,7 +507,7 @@ class Node:
while self.gotResponse is False:
time.sleep(0.1)
logger.debug(
logging.debug(
f"self.cannedPluginMessageMessages:{self.cannedPluginMessageMessages}"
)
@@ -555,14 +515,12 @@ class Node:
if self.cannedPluginMessageMessages:
self.cannedPluginMessage += self.cannedPluginMessageMessages
logger.debug(f"canned_plugin_message:{self.cannedPluginMessage}")
print(f"canned_plugin_message:{self.cannedPluginMessage}")
logging.debug(f"canned_plugin_message:{self.cannedPluginMessage}")
return self.cannedPluginMessage
def set_canned_message(self, message):
"""Set the canned message. The canned messages length must be less than 200 character."""
if not self.module_available(mesh_pb2.CANNEDMSG_CONFIG):
logging.warning("Canned Message module not present (excluded by firmware)")
return None
if len(message) > 200:
our_exit("Warning: The canned message must be less than 200 characters.")
@@ -582,7 +540,7 @@ class Node:
if i == 0:
p.set_canned_message_module_messages = chunk
logger.debug(f"Setting canned message '{chunk}' part {i+1}")
logging.debug(f"Setting canned message '{chunk}' part {i+1}")
# If sending to a remote node, wait for ACK/NAK
if self == self.iface.localNode:
onResponse = None
@@ -596,7 +554,7 @@ class Node:
self.ensureSessionKey()
p = admin_pb2.AdminMessage()
p.exit_simulator = True
logger.debug("in exitSimulator()")
logging.debug("in exitSimulator()")
return self._sendAdmin(p)
@@ -605,7 +563,7 @@ class Node:
self.ensureSessionKey()
p = admin_pb2.AdminMessage()
p.reboot_seconds = secs
logger.info(f"Telling node to reboot in {secs} seconds")
logging.info(f"Telling node to reboot in {secs} seconds")
# If sending to a remote node, wait for ACK/NAK
if self == self.iface.localNode:
@@ -619,7 +577,7 @@ class Node:
self.ensureSessionKey()
p = admin_pb2.AdminMessage()
p.begin_edit_settings = True
logger.info(f"Telling open a transaction to edit settings")
logging.info(f"Telling open a transaction to edit settings")
# If sending to a remote node, wait for ACK/NAK
if self == self.iface.localNode:
@@ -633,7 +591,7 @@ class Node:
self.ensureSessionKey()
p = admin_pb2.AdminMessage()
p.commit_edit_settings = True
logger.info(f"Telling node to commit open transaction for editing settings")
logging.info(f"Telling node to commit open transaction for editing settings")
# If sending to a remote node, wait for ACK/NAK
if self == self.iface.localNode:
@@ -647,7 +605,7 @@ class Node:
self.ensureSessionKey()
p = admin_pb2.AdminMessage()
p.reboot_ota_seconds = secs
logger.info(f"Telling node to reboot to OTA in {secs} seconds")
logging.info(f"Telling node to reboot to OTA in {secs} seconds")
# If sending to a remote node, wait for ACK/NAK
if self == self.iface.localNode:
@@ -661,7 +619,7 @@ class Node:
self.ensureSessionKey()
p = admin_pb2.AdminMessage()
p.enter_dfu_mode_request = True
logger.info(f"Telling node to enable DFU mode")
logging.info(f"Telling node to enable DFU mode")
# If sending to a remote node, wait for ACK/NAK
if self == self.iface.localNode:
@@ -675,7 +633,7 @@ class Node:
self.ensureSessionKey()
p = admin_pb2.AdminMessage()
p.shutdown_seconds = secs
logger.info(f"Telling node to shutdown in {secs} seconds")
logging.info(f"Telling node to shutdown in {secs} seconds")
# If sending to a remote node, wait for ACK/NAK
if self == self.iface.localNode:
@@ -688,7 +646,7 @@ class Node:
"""Get the node's metadata."""
p = admin_pb2.AdminMessage()
p.get_device_metadata_request = True
logger.info(f"Requesting device metadata")
logging.info(f"Requesting device metadata")
self._sendAdmin(
p, wantResponse=True, onResponse=self.onRequestGetMetadata
@@ -701,10 +659,10 @@ class Node:
p = admin_pb2.AdminMessage()
if full:
p.factory_reset_device = True
logger.info(f"Telling node to factory reset (full device reset)")
logging.info(f"Telling node to factory reset (full device reset)")
else:
p.factory_reset_config = True
logger.info(f"Telling node to factory reset (config reset)")
logging.info(f"Telling node to factory reset (config reset)")
# If sending to a remote node, wait for ACK/NAK
if self == self.iface.localNode:
@@ -716,7 +674,11 @@ class Node:
def removeNode(self, nodeId: Union[int, str]):
"""Tell the node to remove a specific node by ID"""
self.ensureSessionKey()
nodeId = to_node_num(nodeId)
if isinstance(nodeId, str):
if nodeId.startswith("!"):
nodeId = int(nodeId[1:], 16)
else:
nodeId = int(nodeId)
p = admin_pb2.AdminMessage()
p.remove_by_nodenum = nodeId
@@ -730,7 +692,11 @@ class Node:
def setFavorite(self, nodeId: Union[int, str]):
"""Tell the node to set the specified node ID to be favorited on the NodeDB on the device"""
self.ensureSessionKey()
nodeId = to_node_num(nodeId)
if isinstance(nodeId, str):
if nodeId.startswith("!"):
nodeId = int(nodeId[1:], 16)
else:
nodeId = int(nodeId)
p = admin_pb2.AdminMessage()
p.set_favorite_node = nodeId
@@ -741,10 +707,53 @@ class Node:
onResponse = self.onAckNak
return self._sendAdmin(p, onResponse=onResponse)
def removeFavorite(self, nodeId: Union[int, str]):
"""Tell the node to set the specified node ID to be un-favorited on the NodeDB on the device"""
def backupPreferences(self, location: Optional[admin_pb2.AdminMessage.BackupLocation.ValueType] = 0):
"""Tell the node to backup preferences to flash."""
self.ensureSessionKey()
nodeId = to_node_num(nodeId)
p = admin_pb2.AdminMessage()
p.backup_preferences = location
if self == self.iface.localNode:
onResponse = None
else:
onResponse = self.onAckNak
return self._sendAdmin(p, onResponse=onResponse)
def restorePreferences(self, location: Optional[admin_pb2.AdminMessage.BackupLocation.ValueType] = 0):
"""Tell the node to restore preferences from backup."""
self.ensureSessionKey()
p = admin_pb2.AdminMessage()
p.restore_preferences = location
if self == self.iface.localNode:
onResponse = None
else:
onResponse = self.onAckNak
return self._sendAdmin(p, onResponse=onResponse)
def removePreferencesBackups(self, location: Optional[admin_pb2.AdminMessage.BackupLocation.ValueType] = 0):
"""Tell the node to remove backup preferences from the filesystem."""
self.ensureSessionKey()
p = admin_pb2.AdminMessage()
p.remove_backup_preferences = location
if self == self.iface.localNode:
onResponse = None
else:
onResponse = self.onAckNak
return self._sendAdmin(p, onResponse=onResponse)
def removeFavorite(self, nodeId: Union[int, str]):
"""Tell the node to set the specified node ID to be un-favorited on the NodeDB on the device."""
self.ensureSessionKey()
if isinstance(nodeId, str):
if nodeId.startswith("!"):
nodeId = int(nodeId[1:], 16)
else:
nodeId = int(nodeId)
p = admin_pb2.AdminMessage()
p.remove_favorite_node = nodeId
@@ -758,7 +767,11 @@ class Node:
def setIgnored(self, nodeId: Union[int, str]):
"""Tell the node to set the specified node ID to be ignored on the NodeDB on the device"""
self.ensureSessionKey()
nodeId = to_node_num(nodeId)
if isinstance(nodeId, str):
if nodeId.startswith("!"):
nodeId = int(nodeId[1:], 16)
else:
nodeId = int(nodeId)
p = admin_pb2.AdminMessage()
p.set_ignored_node = nodeId
@@ -772,7 +785,11 @@ class Node:
def removeIgnored(self, nodeId: Union[int, str]):
"""Tell the node to set the specified node ID to be un-ignored on the NodeDB on the device"""
self.ensureSessionKey()
nodeId = to_node_num(nodeId)
if isinstance(nodeId, str):
if nodeId.startswith("!"):
nodeId = int(nodeId[1:], 16)
else:
nodeId = int(nodeId)
p = admin_pb2.AdminMessage()
p.remove_ignored_node = nodeId
@@ -788,7 +805,7 @@ class Node:
self.ensureSessionKey()
p = admin_pb2.AdminMessage()
p.nodedb_reset = True
logger.info(f"Telling node to reset the NodeDB")
logging.info(f"Telling node to reset the NodeDB")
# If sending to a remote node, wait for ACK/NAK
if self == self.iface.localNode:
@@ -829,7 +846,7 @@ class Node:
self.ensureSessionKey()
p = admin_pb2.AdminMessage()
p.remove_fixed_position = True
logger.info(f"Telling node to remove fixed position")
logging.info(f"Telling node to remove fixed position")
if self == self.iface.localNode:
onResponse = None
@@ -844,7 +861,7 @@ class Node:
timeSec = int(time.time())
p = admin_pb2.AdminMessage()
p.set_time_only = timeSec
logger.info(f"Setting node time to {timeSec}")
logging.info(f"Setting node time to {timeSec}")
if self == self.iface.localNode:
onResponse = None
@@ -876,7 +893,7 @@ class Node:
def onRequestGetMetadata(self, p):
"""Handle the response packet for requesting device metadata getMetadata()"""
logger.debug(f"onRequestGetMetadata() p:{p}")
logging.debug(f"onRequestGetMetadata() p:{p}")
if "routing" in p["decoded"]:
if p["decoded"]["routing"]["errorReason"] != "NONE":
@@ -888,30 +905,30 @@ class Node:
portnums_pb2.PortNum.ROUTING_APP
):
if p["decoded"]["routing"]["errorReason"] != "NONE":
logger.warning(
logging.warning(
f'Metadata request failed, error reason: {p["decoded"]["routing"]["errorReason"]}'
)
self._timeout.expireTime = time.time() # Do not wait any longer
return # Don't try to parse this routing message
logger.debug(f"Retrying metadata request.")
logging.debug(f"Retrying metadata request.")
self.getMetadata()
return
c = p["decoded"]["admin"]["raw"].get_device_metadata_response
self._timeout.reset() # We made forward progress
logger.debug(f"Received metadata {stripnl(c)}")
logging.debug(f"Received metadata {stripnl(c)}")
print(f"\nfirmware_version: {c.firmware_version}")
print(f"device_state_version: {c.device_state_version}")
def onResponseRequestChannel(self, p):
"""Handle the response packet for requesting a channel _requestChannel()"""
logger.debug(f"onResponseRequestChannel() p:{p}")
logging.debug(f"onResponseRequestChannel() p:{p}")
if p["decoded"]["portnum"] == portnums_pb2.PortNum.Name(
portnums_pb2.PortNum.ROUTING_APP
):
if p["decoded"]["routing"]["errorReason"] != "NONE":
logger.warning(
logging.warning(
f'Channel request failed, error reason: {p["decoded"]["routing"]["errorReason"]}'
)
self._timeout.expireTime = time.time() # Do not wait any longer
@@ -919,18 +936,18 @@ class Node:
lastTried = 0
if len(self.partialChannels) > 0:
lastTried = self.partialChannels[-1].index
logger.debug(f"Retrying previous channel request.")
logging.debug(f"Retrying previous channel request.")
self._requestChannel(lastTried)
return
c = p["decoded"]["admin"]["raw"].get_channel_response
self.partialChannels.append(c)
self._timeout.reset() # We made forward progress
logger.debug(f"Received channel {stripnl(c)}")
logging.debug(f"Received channel {stripnl(c)}")
index = c.index
if index >= 8 - 1:
logger.debug("Finished downloading channels")
logging.debug("Finished downloading channels")
self.channels = self.partialChannels
self._fixupChannels()
@@ -965,11 +982,11 @@ class Node:
print(
f"Requesting channel {channelNum} info from remote node (this could take a while)"
)
logger.debug(
logging.debug(
f"Requesting channel {channelNum} info from remote node (this could take a while)"
)
else:
logger.debug(f"Requesting channel {channelNum}")
logging.debug(f"Requesting channel {channelNum}")
return self._sendAdmin(
p, wantResponse=True, onResponse=self.onResponseRequestChannel
@@ -986,7 +1003,7 @@ class Node:
"""Send an admin message to the specified node (or the local node if destNodeNum is zero)"""
if self.noProto:
logger.warning(
logging.warning(
f"Not sending packet because protocol use is disabled by noProto"
)
else:
@@ -994,15 +1011,18 @@ class Node:
adminIndex == 0
): # unless a special channel index was used, we want to use the admin index
adminIndex = self.iface.localNode._getAdminChannelIndex()
logger.debug(f"adminIndex:{adminIndex}")
nodeid = to_node_num(self.nodeNum)
logging.debug(f"adminIndex:{adminIndex}")
if isinstance(self.nodeNum, int):
nodeid = self.nodeNum
else: # assume string starting with !
nodeid = int(self.nodeNum[1:],16)
if "adminSessionPassKey" in self.iface._getOrCreateByNum(nodeid):
p.session_passkey = self.iface._getOrCreateByNum(nodeid).get("adminSessionPassKey")
return self.iface.sendData(
p,
self.nodeNum,
portNum=portnums_pb2.PortNum.ADMIN_APP,
wantAck=True,
wantAck=False,
wantResponse=wantResponse,
onResponse=onResponse,
channelIndex=adminIndex,
@@ -1012,27 +1032,13 @@ class Node:
def ensureSessionKey(self):
"""If our entry in iface.nodesByNum doesn't already have an adminSessionPassKey, make a request to get one"""
if self.noProto:
logger.warning(
logging.warning(
f"Not ensuring session key, because protocol use is disabled by noProto"
)
else:
nodeid = to_node_num(self.nodeNum)
if isinstance(self.nodeNum, int):
nodeid = self.nodeNum
else: # assume string starting with !
nodeid = int(self.nodeNum[1:],16)
if self.iface._getOrCreateByNum(nodeid).get("adminSessionPassKey") is None:
self.requestConfig(admin_pb2.AdminMessage.SESSIONKEY_CONFIG)
def get_channels_with_hash(self):
"""Return a list of dicts with channel info and hash."""
result = []
if self.channels:
for c in self.channels:
if c.settings and hasattr(c.settings, "name") and hasattr(c.settings, "psk"):
hash_val = generate_channel_hash(c.settings.name, c.settings.psk)
else:
hash_val = None
result.append({
"index": c.index,
"role": channel_pb2.Channel.Role.Name(c.role),
"name": c.settings.name if c.settings and hasattr(c.settings, "name") else "",
"hash": hash_val,
})
return result

View File

File diff suppressed because one or more lines are too long

View File

@@ -74,9 +74,7 @@ class AdminMessage(google.protobuf.message.Message):
TODO: REPLACE
"""
SESSIONKEY_CONFIG: AdminMessage._ConfigType.ValueType # 8
"""
Session key config
"""
""""""
DEVICEUI_CONFIG: AdminMessage._ConfigType.ValueType # 9
"""
device-ui config
@@ -120,9 +118,7 @@ class AdminMessage(google.protobuf.message.Message):
TODO: REPLACE
"""
SESSIONKEY_CONFIG: AdminMessage.ConfigType.ValueType # 8
"""
Session key config
"""
""""""
DEVICEUI_CONFIG: AdminMessage.ConfigType.ValueType # 9
"""
device-ui config
@@ -270,44 +266,6 @@ class AdminMessage(google.protobuf.message.Message):
Backup to the SD card
"""
@typing.final
class InputEvent(google.protobuf.message.Message):
"""
Input event message to be sent to the node.
"""
DESCRIPTOR: google.protobuf.descriptor.Descriptor
EVENT_CODE_FIELD_NUMBER: builtins.int
KB_CHAR_FIELD_NUMBER: builtins.int
TOUCH_X_FIELD_NUMBER: builtins.int
TOUCH_Y_FIELD_NUMBER: builtins.int
event_code: builtins.int
"""
The input event code
"""
kb_char: builtins.int
"""
Keyboard character code
"""
touch_x: builtins.int
"""
The touch X coordinate
"""
touch_y: builtins.int
"""
The touch Y coordinate
"""
def __init__(
self,
*,
event_code: builtins.int = ...,
kb_char: builtins.int = ...,
touch_x: builtins.int = ...,
touch_y: builtins.int = ...,
) -> None: ...
def ClearField(self, field_name: typing.Literal["event_code", b"event_code", "kb_char", b"kb_char", "touch_x", b"touch_x", "touch_y", b"touch_y"]) -> None: ...
SESSION_PASSKEY_FIELD_NUMBER: builtins.int
GET_CHANNEL_REQUEST_FIELD_NUMBER: builtins.int
GET_CHANNEL_RESPONSE_FIELD_NUMBER: builtins.int
@@ -334,7 +292,6 @@ class AdminMessage(google.protobuf.message.Message):
BACKUP_PREFERENCES_FIELD_NUMBER: builtins.int
RESTORE_PREFERENCES_FIELD_NUMBER: builtins.int
REMOVE_BACKUP_PREFERENCES_FIELD_NUMBER: builtins.int
SEND_INPUT_EVENT_FIELD_NUMBER: builtins.int
SET_OWNER_FIELD_NUMBER: builtins.int
SET_CHANNEL_FIELD_NUMBER: builtins.int
SET_CONFIG_FIELD_NUMBER: builtins.int
@@ -354,8 +311,6 @@ class AdminMessage(google.protobuf.message.Message):
REMOVE_IGNORED_NODE_FIELD_NUMBER: builtins.int
BEGIN_EDIT_SETTINGS_FIELD_NUMBER: builtins.int
COMMIT_EDIT_SETTINGS_FIELD_NUMBER: builtins.int
ADD_CONTACT_FIELD_NUMBER: builtins.int
KEY_VERIFICATION_FIELD_NUMBER: builtins.int
FACTORY_RESET_DEVICE_FIELD_NUMBER: builtins.int
REBOOT_OTA_SECONDS_FIELD_NUMBER: builtins.int
EXIT_SIMULATOR_FIELD_NUMBER: builtins.int
@@ -567,13 +522,6 @@ class AdminMessage(google.protobuf.message.Message):
Respond with the mesh's nodes with their available gpio pins for RemoteHardware module use
"""
@property
def send_input_event(self) -> global___AdminMessage.InputEvent:
"""
Send an input event to the node.
This is used to trigger physical input events like button presses, touch events, etc.
"""
@property
def set_owner(self) -> meshtastic.protobuf.mesh_pb2.User:
"""
@@ -620,18 +568,6 @@ class AdminMessage(google.protobuf.message.Message):
Tell the node to store UI data persistently.
"""
@property
def add_contact(self) -> global___SharedContact:
"""
Add a contact (User) to the nodedb
"""
@property
def key_verification(self) -> global___KeyVerificationAdmin:
"""
Initiate or respond to a key verification request
"""
def __init__(
self,
*,
@@ -661,7 +597,6 @@ class AdminMessage(google.protobuf.message.Message):
backup_preferences: global___AdminMessage.BackupLocation.ValueType = ...,
restore_preferences: global___AdminMessage.BackupLocation.ValueType = ...,
remove_backup_preferences: global___AdminMessage.BackupLocation.ValueType = ...,
send_input_event: global___AdminMessage.InputEvent | None = ...,
set_owner: meshtastic.protobuf.mesh_pb2.User | None = ...,
set_channel: meshtastic.protobuf.channel_pb2.Channel | None = ...,
set_config: meshtastic.protobuf.config_pb2.Config | None = ...,
@@ -681,8 +616,6 @@ class AdminMessage(google.protobuf.message.Message):
remove_ignored_node: builtins.int = ...,
begin_edit_settings: builtins.bool = ...,
commit_edit_settings: builtins.bool = ...,
add_contact: global___SharedContact | None = ...,
key_verification: global___KeyVerificationAdmin | None = ...,
factory_reset_device: builtins.int = ...,
reboot_ota_seconds: builtins.int = ...,
exit_simulator: builtins.bool = ...,
@@ -691,9 +624,9 @@ class AdminMessage(google.protobuf.message.Message):
factory_reset_config: builtins.int = ...,
nodedb_reset: builtins.int = ...,
) -> None: ...
def HasField(self, field_name: typing.Literal["add_contact", b"add_contact", "backup_preferences", b"backup_preferences", "begin_edit_settings", b"begin_edit_settings", "commit_edit_settings", b"commit_edit_settings", "delete_file_request", b"delete_file_request", "enter_dfu_mode_request", b"enter_dfu_mode_request", "exit_simulator", b"exit_simulator", "factory_reset_config", b"factory_reset_config", "factory_reset_device", b"factory_reset_device", "get_canned_message_module_messages_request", b"get_canned_message_module_messages_request", "get_canned_message_module_messages_response", b"get_canned_message_module_messages_response", "get_channel_request", b"get_channel_request", "get_channel_response", b"get_channel_response", "get_config_request", b"get_config_request", "get_config_response", b"get_config_response", "get_device_connection_status_request", b"get_device_connection_status_request", "get_device_connection_status_response", b"get_device_connection_status_response", "get_device_metadata_request", b"get_device_metadata_request", "get_device_metadata_response", b"get_device_metadata_response", "get_module_config_request", b"get_module_config_request", "get_module_config_response", b"get_module_config_response", "get_node_remote_hardware_pins_request", b"get_node_remote_hardware_pins_request", "get_node_remote_hardware_pins_response", b"get_node_remote_hardware_pins_response", "get_owner_request", b"get_owner_request", "get_owner_response", b"get_owner_response", "get_ringtone_request", b"get_ringtone_request", "get_ringtone_response", b"get_ringtone_response", "get_ui_config_request", b"get_ui_config_request", "get_ui_config_response", b"get_ui_config_response", "key_verification", b"key_verification", "nodedb_reset", b"nodedb_reset", "payload_variant", b"payload_variant", "reboot_ota_seconds", b"reboot_ota_seconds", "reboot_seconds", b"reboot_seconds", "remove_backup_preferences", b"remove_backup_preferences", "remove_by_nodenum", b"remove_by_nodenum", "remove_favorite_node", b"remove_favorite_node", "remove_fixed_position", b"remove_fixed_position", "remove_ignored_node", b"remove_ignored_node", "restore_preferences", b"restore_preferences", "send_input_event", b"send_input_event", "set_canned_message_module_messages", b"set_canned_message_module_messages", "set_channel", b"set_channel", "set_config", b"set_config", "set_favorite_node", b"set_favorite_node", "set_fixed_position", b"set_fixed_position", "set_ham_mode", b"set_ham_mode", "set_ignored_node", b"set_ignored_node", "set_module_config", b"set_module_config", "set_owner", b"set_owner", "set_ringtone_message", b"set_ringtone_message", "set_scale", b"set_scale", "set_time_only", b"set_time_only", "shutdown_seconds", b"shutdown_seconds", "store_ui_config", b"store_ui_config"]) -> builtins.bool: ...
def ClearField(self, field_name: typing.Literal["add_contact", b"add_contact", "backup_preferences", b"backup_preferences", "begin_edit_settings", b"begin_edit_settings", "commit_edit_settings", b"commit_edit_settings", "delete_file_request", b"delete_file_request", "enter_dfu_mode_request", b"enter_dfu_mode_request", "exit_simulator", b"exit_simulator", "factory_reset_config", b"factory_reset_config", "factory_reset_device", b"factory_reset_device", "get_canned_message_module_messages_request", b"get_canned_message_module_messages_request", "get_canned_message_module_messages_response", b"get_canned_message_module_messages_response", "get_channel_request", b"get_channel_request", "get_channel_response", b"get_channel_response", "get_config_request", b"get_config_request", "get_config_response", b"get_config_response", "get_device_connection_status_request", b"get_device_connection_status_request", "get_device_connection_status_response", b"get_device_connection_status_response", "get_device_metadata_request", b"get_device_metadata_request", "get_device_metadata_response", b"get_device_metadata_response", "get_module_config_request", b"get_module_config_request", "get_module_config_response", b"get_module_config_response", "get_node_remote_hardware_pins_request", b"get_node_remote_hardware_pins_request", "get_node_remote_hardware_pins_response", b"get_node_remote_hardware_pins_response", "get_owner_request", b"get_owner_request", "get_owner_response", b"get_owner_response", "get_ringtone_request", b"get_ringtone_request", "get_ringtone_response", b"get_ringtone_response", "get_ui_config_request", b"get_ui_config_request", "get_ui_config_response", b"get_ui_config_response", "key_verification", b"key_verification", "nodedb_reset", b"nodedb_reset", "payload_variant", b"payload_variant", "reboot_ota_seconds", b"reboot_ota_seconds", "reboot_seconds", b"reboot_seconds", "remove_backup_preferences", b"remove_backup_preferences", "remove_by_nodenum", b"remove_by_nodenum", "remove_favorite_node", b"remove_favorite_node", "remove_fixed_position", b"remove_fixed_position", "remove_ignored_node", b"remove_ignored_node", "restore_preferences", b"restore_preferences", "send_input_event", b"send_input_event", "session_passkey", b"session_passkey", "set_canned_message_module_messages", b"set_canned_message_module_messages", "set_channel", b"set_channel", "set_config", b"set_config", "set_favorite_node", b"set_favorite_node", "set_fixed_position", b"set_fixed_position", "set_ham_mode", b"set_ham_mode", "set_ignored_node", b"set_ignored_node", "set_module_config", b"set_module_config", "set_owner", b"set_owner", "set_ringtone_message", b"set_ringtone_message", "set_scale", b"set_scale", "set_time_only", b"set_time_only", "shutdown_seconds", b"shutdown_seconds", "store_ui_config", b"store_ui_config"]) -> None: ...
def WhichOneof(self, oneof_group: typing.Literal["payload_variant", b"payload_variant"]) -> typing.Literal["get_channel_request", "get_channel_response", "get_owner_request", "get_owner_response", "get_config_request", "get_config_response", "get_module_config_request", "get_module_config_response", "get_canned_message_module_messages_request", "get_canned_message_module_messages_response", "get_device_metadata_request", "get_device_metadata_response", "get_ringtone_request", "get_ringtone_response", "get_device_connection_status_request", "get_device_connection_status_response", "set_ham_mode", "get_node_remote_hardware_pins_request", "get_node_remote_hardware_pins_response", "enter_dfu_mode_request", "delete_file_request", "set_scale", "backup_preferences", "restore_preferences", "remove_backup_preferences", "send_input_event", "set_owner", "set_channel", "set_config", "set_module_config", "set_canned_message_module_messages", "set_ringtone_message", "remove_by_nodenum", "set_favorite_node", "remove_favorite_node", "set_fixed_position", "remove_fixed_position", "set_time_only", "get_ui_config_request", "get_ui_config_response", "store_ui_config", "set_ignored_node", "remove_ignored_node", "begin_edit_settings", "commit_edit_settings", "add_contact", "key_verification", "factory_reset_device", "reboot_ota_seconds", "exit_simulator", "reboot_seconds", "shutdown_seconds", "factory_reset_config", "nodedb_reset"] | None: ...
def HasField(self, field_name: typing.Literal["backup_preferences", b"backup_preferences", "begin_edit_settings", b"begin_edit_settings", "commit_edit_settings", b"commit_edit_settings", "delete_file_request", b"delete_file_request", "enter_dfu_mode_request", b"enter_dfu_mode_request", "exit_simulator", b"exit_simulator", "factory_reset_config", b"factory_reset_config", "factory_reset_device", b"factory_reset_device", "get_canned_message_module_messages_request", b"get_canned_message_module_messages_request", "get_canned_message_module_messages_response", b"get_canned_message_module_messages_response", "get_channel_request", b"get_channel_request", "get_channel_response", b"get_channel_response", "get_config_request", b"get_config_request", "get_config_response", b"get_config_response", "get_device_connection_status_request", b"get_device_connection_status_request", "get_device_connection_status_response", b"get_device_connection_status_response", "get_device_metadata_request", b"get_device_metadata_request", "get_device_metadata_response", b"get_device_metadata_response", "get_module_config_request", b"get_module_config_request", "get_module_config_response", b"get_module_config_response", "get_node_remote_hardware_pins_request", b"get_node_remote_hardware_pins_request", "get_node_remote_hardware_pins_response", b"get_node_remote_hardware_pins_response", "get_owner_request", b"get_owner_request", "get_owner_response", b"get_owner_response", "get_ringtone_request", b"get_ringtone_request", "get_ringtone_response", b"get_ringtone_response", "get_ui_config_request", b"get_ui_config_request", "get_ui_config_response", b"get_ui_config_response", "nodedb_reset", b"nodedb_reset", "payload_variant", b"payload_variant", "reboot_ota_seconds", b"reboot_ota_seconds", "reboot_seconds", b"reboot_seconds", "remove_backup_preferences", b"remove_backup_preferences", "remove_by_nodenum", b"remove_by_nodenum", "remove_favorite_node", b"remove_favorite_node", "remove_fixed_position", b"remove_fixed_position", "remove_ignored_node", b"remove_ignored_node", "restore_preferences", b"restore_preferences", "set_canned_message_module_messages", b"set_canned_message_module_messages", "set_channel", b"set_channel", "set_config", b"set_config", "set_favorite_node", b"set_favorite_node", "set_fixed_position", b"set_fixed_position", "set_ham_mode", b"set_ham_mode", "set_ignored_node", b"set_ignored_node", "set_module_config", b"set_module_config", "set_owner", b"set_owner", "set_ringtone_message", b"set_ringtone_message", "set_scale", b"set_scale", "set_time_only", b"set_time_only", "shutdown_seconds", b"shutdown_seconds", "store_ui_config", b"store_ui_config"]) -> builtins.bool: ...
def ClearField(self, field_name: typing.Literal["backup_preferences", b"backup_preferences", "begin_edit_settings", b"begin_edit_settings", "commit_edit_settings", b"commit_edit_settings", "delete_file_request", b"delete_file_request", "enter_dfu_mode_request", b"enter_dfu_mode_request", "exit_simulator", b"exit_simulator", "factory_reset_config", b"factory_reset_config", "factory_reset_device", b"factory_reset_device", "get_canned_message_module_messages_request", b"get_canned_message_module_messages_request", "get_canned_message_module_messages_response", b"get_canned_message_module_messages_response", "get_channel_request", b"get_channel_request", "get_channel_response", b"get_channel_response", "get_config_request", b"get_config_request", "get_config_response", b"get_config_response", "get_device_connection_status_request", b"get_device_connection_status_request", "get_device_connection_status_response", b"get_device_connection_status_response", "get_device_metadata_request", b"get_device_metadata_request", "get_device_metadata_response", b"get_device_metadata_response", "get_module_config_request", b"get_module_config_request", "get_module_config_response", b"get_module_config_response", "get_node_remote_hardware_pins_request", b"get_node_remote_hardware_pins_request", "get_node_remote_hardware_pins_response", b"get_node_remote_hardware_pins_response", "get_owner_request", b"get_owner_request", "get_owner_response", b"get_owner_response", "get_ringtone_request", b"get_ringtone_request", "get_ringtone_response", b"get_ringtone_response", "get_ui_config_request", b"get_ui_config_request", "get_ui_config_response", b"get_ui_config_response", "nodedb_reset", b"nodedb_reset", "payload_variant", b"payload_variant", "reboot_ota_seconds", b"reboot_ota_seconds", "reboot_seconds", b"reboot_seconds", "remove_backup_preferences", b"remove_backup_preferences", "remove_by_nodenum", b"remove_by_nodenum", "remove_favorite_node", b"remove_favorite_node", "remove_fixed_position", b"remove_fixed_position", "remove_ignored_node", b"remove_ignored_node", "restore_preferences", b"restore_preferences", "session_passkey", b"session_passkey", "set_canned_message_module_messages", b"set_canned_message_module_messages", "set_channel", b"set_channel", "set_config", b"set_config", "set_favorite_node", b"set_favorite_node", "set_fixed_position", b"set_fixed_position", "set_ham_mode", b"set_ham_mode", "set_ignored_node", b"set_ignored_node", "set_module_config", b"set_module_config", "set_owner", b"set_owner", "set_ringtone_message", b"set_ringtone_message", "set_scale", b"set_scale", "set_time_only", b"set_time_only", "shutdown_seconds", b"shutdown_seconds", "store_ui_config", b"store_ui_config"]) -> None: ...
def WhichOneof(self, oneof_group: typing.Literal["payload_variant", b"payload_variant"]) -> typing.Literal["get_channel_request", "get_channel_response", "get_owner_request", "get_owner_response", "get_config_request", "get_config_response", "get_module_config_request", "get_module_config_response", "get_canned_message_module_messages_request", "get_canned_message_module_messages_response", "get_device_metadata_request", "get_device_metadata_response", "get_ringtone_request", "get_ringtone_response", "get_device_connection_status_request", "get_device_connection_status_response", "set_ham_mode", "get_node_remote_hardware_pins_request", "get_node_remote_hardware_pins_response", "enter_dfu_mode_request", "delete_file_request", "set_scale", "backup_preferences", "restore_preferences", "remove_backup_preferences", "set_owner", "set_channel", "set_config", "set_module_config", "set_canned_message_module_messages", "set_ringtone_message", "remove_by_nodenum", "set_favorite_node", "remove_favorite_node", "set_fixed_position", "remove_fixed_position", "set_time_only", "get_ui_config_request", "get_ui_config_response", "store_ui_config", "set_ignored_node", "remove_ignored_node", "begin_edit_settings", "commit_edit_settings", "factory_reset_device", "reboot_ota_seconds", "exit_simulator", "reboot_seconds", "shutdown_seconds", "factory_reset_config", "nodedb_reset"] | None: ...
global___AdminMessage = AdminMessage
@@ -762,128 +695,3 @@ class NodeRemoteHardwarePinsResponse(google.protobuf.message.Message):
def ClearField(self, field_name: typing.Literal["node_remote_hardware_pins", b"node_remote_hardware_pins"]) -> None: ...
global___NodeRemoteHardwarePinsResponse = NodeRemoteHardwarePinsResponse
@typing.final
class SharedContact(google.protobuf.message.Message):
DESCRIPTOR: google.protobuf.descriptor.Descriptor
NODE_NUM_FIELD_NUMBER: builtins.int
USER_FIELD_NUMBER: builtins.int
SHOULD_IGNORE_FIELD_NUMBER: builtins.int
MANUALLY_VERIFIED_FIELD_NUMBER: builtins.int
node_num: builtins.int
"""
The node number of the contact
"""
should_ignore: builtins.bool
"""
Add this contact to the blocked / ignored list
"""
manually_verified: builtins.bool
"""
Set the IS_KEY_MANUALLY_VERIFIED bit
"""
@property
def user(self) -> meshtastic.protobuf.mesh_pb2.User:
"""
The User of the contact
"""
def __init__(
self,
*,
node_num: builtins.int = ...,
user: meshtastic.protobuf.mesh_pb2.User | None = ...,
should_ignore: builtins.bool = ...,
manually_verified: builtins.bool = ...,
) -> None: ...
def HasField(self, field_name: typing.Literal["user", b"user"]) -> builtins.bool: ...
def ClearField(self, field_name: typing.Literal["manually_verified", b"manually_verified", "node_num", b"node_num", "should_ignore", b"should_ignore", "user", b"user"]) -> None: ...
global___SharedContact = SharedContact
@typing.final
class KeyVerificationAdmin(google.protobuf.message.Message):
"""
This message is used by a client to initiate or complete a key verification
"""
DESCRIPTOR: google.protobuf.descriptor.Descriptor
class _MessageType:
ValueType = typing.NewType("ValueType", builtins.int)
V: typing_extensions.TypeAlias = ValueType
class _MessageTypeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[KeyVerificationAdmin._MessageType.ValueType], builtins.type):
DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor
INITIATE_VERIFICATION: KeyVerificationAdmin._MessageType.ValueType # 0
"""
This is the first stage, where a client initiates
"""
PROVIDE_SECURITY_NUMBER: KeyVerificationAdmin._MessageType.ValueType # 1
"""
After the nonce has been returned over the mesh, the client prompts for the security number
And uses this message to provide it to the node.
"""
DO_VERIFY: KeyVerificationAdmin._MessageType.ValueType # 2
"""
Once the user has compared the verification message, this message notifies the node.
"""
DO_NOT_VERIFY: KeyVerificationAdmin._MessageType.ValueType # 3
"""
This is the cancel path, can be taken at any point
"""
class MessageType(_MessageType, metaclass=_MessageTypeEnumTypeWrapper):
"""
Three stages of this request.
"""
INITIATE_VERIFICATION: KeyVerificationAdmin.MessageType.ValueType # 0
"""
This is the first stage, where a client initiates
"""
PROVIDE_SECURITY_NUMBER: KeyVerificationAdmin.MessageType.ValueType # 1
"""
After the nonce has been returned over the mesh, the client prompts for the security number
And uses this message to provide it to the node.
"""
DO_VERIFY: KeyVerificationAdmin.MessageType.ValueType # 2
"""
Once the user has compared the verification message, this message notifies the node.
"""
DO_NOT_VERIFY: KeyVerificationAdmin.MessageType.ValueType # 3
"""
This is the cancel path, can be taken at any point
"""
MESSAGE_TYPE_FIELD_NUMBER: builtins.int
REMOTE_NODENUM_FIELD_NUMBER: builtins.int
NONCE_FIELD_NUMBER: builtins.int
SECURITY_NUMBER_FIELD_NUMBER: builtins.int
message_type: global___KeyVerificationAdmin.MessageType.ValueType
remote_nodenum: builtins.int
"""
The nodenum we're requesting
"""
nonce: builtins.int
"""
The nonce is used to track the connection
"""
security_number: builtins.int
"""
The 4 digit code generated by the remote node, and communicated outside the mesh
"""
def __init__(
self,
*,
message_type: global___KeyVerificationAdmin.MessageType.ValueType = ...,
remote_nodenum: builtins.int = ...,
nonce: builtins.int = ...,
security_number: builtins.int | None = ...,
) -> None: ...
def HasField(self, field_name: typing.Literal["_security_number", b"_security_number", "security_number", b"security_number"]) -> builtins.bool: ...
def ClearField(self, field_name: typing.Literal["_security_number", b"_security_number", "message_type", b"message_type", "nonce", b"nonce", "remote_nodenum", b"remote_nodenum", "security_number", b"security_number"]) -> None: ...
def WhichOneof(self, oneof_group: typing.Literal["_security_number", b"_security_number"]) -> typing.Literal["security_number"] | None: ...
global___KeyVerificationAdmin = KeyVerificationAdmin

View File

@@ -15,14 +15,14 @@ from meshtastic.protobuf import channel_pb2 as meshtastic_dot_protobuf_dot_chann
from meshtastic.protobuf import config_pb2 as meshtastic_dot_protobuf_dot_config__pb2
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n!meshtastic/protobuf/apponly.proto\x12\x13meshtastic.protobuf\x1a!meshtastic/protobuf/channel.proto\x1a meshtastic/protobuf/config.proto\"\x81\x01\n\nChannelSet\x12\x36\n\x08settings\x18\x01 \x03(\x0b\x32$.meshtastic.protobuf.ChannelSettings\x12;\n\x0blora_config\x18\x02 \x01(\x0b\x32&.meshtastic.protobuf.Config.LoRaConfigBc\n\x14org.meshtastic.protoB\rAppOnlyProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3')
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n!meshtastic/protobuf/apponly.proto\x12\x13meshtastic.protobuf\x1a!meshtastic/protobuf/channel.proto\x1a meshtastic/protobuf/config.proto\"\x81\x01\n\nChannelSet\x12\x36\n\x08settings\x18\x01 \x03(\x0b\x32$.meshtastic.protobuf.ChannelSettings\x12;\n\x0blora_config\x18\x02 \x01(\x0b\x32&.meshtastic.protobuf.Config.LoRaConfigBb\n\x13\x63om.geeksville.meshB\rAppOnlyProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3')
_globals = globals()
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.protobuf.apponly_pb2', _globals)
if _descriptor._USE_C_DESCRIPTORS == False:
DESCRIPTOR._options = None
DESCRIPTOR._serialized_options = b'\n\024org.meshtastic.protoB\rAppOnlyProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000'
DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\rAppOnlyProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000'
_globals['_CHANNELSET']._serialized_start=128
_globals['_CHANNELSET']._serialized_end=257
# @@protoc_insertion_point(module_scope)

View File

@@ -13,14 +13,14 @@ _sym_db = _symbol_database.Default()
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1emeshtastic/protobuf/atak.proto\x12\x13meshtastic.protobuf\"\xa5\x02\n\tTAKPacket\x12\x15\n\ris_compressed\x18\x01 \x01(\x08\x12-\n\x07\x63ontact\x18\x02 \x01(\x0b\x32\x1c.meshtastic.protobuf.Contact\x12)\n\x05group\x18\x03 \x01(\x0b\x32\x1a.meshtastic.protobuf.Group\x12+\n\x06status\x18\x04 \x01(\x0b\x32\x1b.meshtastic.protobuf.Status\x12\'\n\x03pli\x18\x05 \x01(\x0b\x32\x18.meshtastic.protobuf.PLIH\x00\x12,\n\x04\x63hat\x18\x06 \x01(\x0b\x32\x1c.meshtastic.protobuf.GeoChatH\x00\x12\x10\n\x06\x64\x65tail\x18\x07 \x01(\x0cH\x00\x42\x11\n\x0fpayload_variant\"\\\n\x07GeoChat\x12\x0f\n\x07message\x18\x01 \x01(\t\x12\x0f\n\x02to\x18\x02 \x01(\tH\x00\x88\x01\x01\x12\x18\n\x0bto_callsign\x18\x03 \x01(\tH\x01\x88\x01\x01\x42\x05\n\x03_toB\x0e\n\x0c_to_callsign\"_\n\x05Group\x12-\n\x04role\x18\x01 \x01(\x0e\x32\x1f.meshtastic.protobuf.MemberRole\x12\'\n\x04team\x18\x02 \x01(\x0e\x32\x19.meshtastic.protobuf.Team\"\x19\n\x06Status\x12\x0f\n\x07\x62\x61ttery\x18\x01 \x01(\r\"4\n\x07\x43ontact\x12\x10\n\x08\x63\x61llsign\x18\x01 \x01(\t\x12\x17\n\x0f\x64\x65vice_callsign\x18\x02 \x01(\t\"_\n\x03PLI\x12\x12\n\nlatitude_i\x18\x01 \x01(\x0f\x12\x13\n\x0blongitude_i\x18\x02 \x01(\x0f\x12\x10\n\x08\x61ltitude\x18\x03 \x01(\x05\x12\r\n\x05speed\x18\x04 \x01(\r\x12\x0e\n\x06\x63ourse\x18\x05 \x01(\r*\xc0\x01\n\x04Team\x12\x14\n\x10Unspecifed_Color\x10\x00\x12\t\n\x05White\x10\x01\x12\n\n\x06Yellow\x10\x02\x12\n\n\x06Orange\x10\x03\x12\x0b\n\x07Magenta\x10\x04\x12\x07\n\x03Red\x10\x05\x12\n\n\x06Maroon\x10\x06\x12\n\n\x06Purple\x10\x07\x12\r\n\tDark_Blue\x10\x08\x12\x08\n\x04\x42lue\x10\t\x12\x08\n\x04\x43yan\x10\n\x12\x08\n\x04Teal\x10\x0b\x12\t\n\x05Green\x10\x0c\x12\x0e\n\nDark_Green\x10\r\x12\t\n\x05\x42rown\x10\x0e*\x7f\n\nMemberRole\x12\x0e\n\nUnspecifed\x10\x00\x12\x0e\n\nTeamMember\x10\x01\x12\x0c\n\x08TeamLead\x10\x02\x12\x06\n\x02HQ\x10\x03\x12\n\n\x06Sniper\x10\x04\x12\t\n\x05Medic\x10\x05\x12\x13\n\x0f\x46orwardObserver\x10\x06\x12\x07\n\x03RTO\x10\x07\x12\x06\n\x02K9\x10\x08\x42`\n\x14org.meshtastic.protoB\nATAKProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3')
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1emeshtastic/protobuf/atak.proto\x12\x13meshtastic.protobuf\"\xa5\x02\n\tTAKPacket\x12\x15\n\ris_compressed\x18\x01 \x01(\x08\x12-\n\x07\x63ontact\x18\x02 \x01(\x0b\x32\x1c.meshtastic.protobuf.Contact\x12)\n\x05group\x18\x03 \x01(\x0b\x32\x1a.meshtastic.protobuf.Group\x12+\n\x06status\x18\x04 \x01(\x0b\x32\x1b.meshtastic.protobuf.Status\x12\'\n\x03pli\x18\x05 \x01(\x0b\x32\x18.meshtastic.protobuf.PLIH\x00\x12,\n\x04\x63hat\x18\x06 \x01(\x0b\x32\x1c.meshtastic.protobuf.GeoChatH\x00\x12\x10\n\x06\x64\x65tail\x18\x07 \x01(\x0cH\x00\x42\x11\n\x0fpayload_variant\"\\\n\x07GeoChat\x12\x0f\n\x07message\x18\x01 \x01(\t\x12\x0f\n\x02to\x18\x02 \x01(\tH\x00\x88\x01\x01\x12\x18\n\x0bto_callsign\x18\x03 \x01(\tH\x01\x88\x01\x01\x42\x05\n\x03_toB\x0e\n\x0c_to_callsign\"_\n\x05Group\x12-\n\x04role\x18\x01 \x01(\x0e\x32\x1f.meshtastic.protobuf.MemberRole\x12\'\n\x04team\x18\x02 \x01(\x0e\x32\x19.meshtastic.protobuf.Team\"\x19\n\x06Status\x12\x0f\n\x07\x62\x61ttery\x18\x01 \x01(\r\"4\n\x07\x43ontact\x12\x10\n\x08\x63\x61llsign\x18\x01 \x01(\t\x12\x17\n\x0f\x64\x65vice_callsign\x18\x02 \x01(\t\"_\n\x03PLI\x12\x12\n\nlatitude_i\x18\x01 \x01(\x0f\x12\x13\n\x0blongitude_i\x18\x02 \x01(\x0f\x12\x10\n\x08\x61ltitude\x18\x03 \x01(\x05\x12\r\n\x05speed\x18\x04 \x01(\r\x12\x0e\n\x06\x63ourse\x18\x05 \x01(\r*\xc0\x01\n\x04Team\x12\x14\n\x10Unspecifed_Color\x10\x00\x12\t\n\x05White\x10\x01\x12\n\n\x06Yellow\x10\x02\x12\n\n\x06Orange\x10\x03\x12\x0b\n\x07Magenta\x10\x04\x12\x07\n\x03Red\x10\x05\x12\n\n\x06Maroon\x10\x06\x12\n\n\x06Purple\x10\x07\x12\r\n\tDark_Blue\x10\x08\x12\x08\n\x04\x42lue\x10\t\x12\x08\n\x04\x43yan\x10\n\x12\x08\n\x04Teal\x10\x0b\x12\t\n\x05Green\x10\x0c\x12\x0e\n\nDark_Green\x10\r\x12\t\n\x05\x42rown\x10\x0e*\x7f\n\nMemberRole\x12\x0e\n\nUnspecifed\x10\x00\x12\x0e\n\nTeamMember\x10\x01\x12\x0c\n\x08TeamLead\x10\x02\x12\x06\n\x02HQ\x10\x03\x12\n\n\x06Sniper\x10\x04\x12\t\n\x05Medic\x10\x05\x12\x13\n\x0f\x46orwardObserver\x10\x06\x12\x07\n\x03RTO\x10\x07\x12\x06\n\x02K9\x10\x08\x42_\n\x13\x63om.geeksville.meshB\nATAKProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3')
_globals = globals()
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.protobuf.atak_pb2', _globals)
if _descriptor._USE_C_DESCRIPTORS == False:
DESCRIPTOR._options = None
DESCRIPTOR._serialized_options = b'\n\024org.meshtastic.protoB\nATAKProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000'
DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\nATAKProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000'
_globals['_TEAM']._serialized_start=721
_globals['_TEAM']._serialized_end=913
_globals['_MEMBERROLE']._serialized_start=915

View File

@@ -13,14 +13,14 @@ _sym_db = _symbol_database.Default()
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n(meshtastic/protobuf/cannedmessages.proto\x12\x13meshtastic.protobuf\"-\n\x19\x43\x61nnedMessageModuleConfig\x12\x10\n\x08messages\x18\x01 \x01(\tBo\n\x14org.meshtastic.protoB\x19\x43\x61nnedMessageConfigProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3')
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n(meshtastic/protobuf/cannedmessages.proto\x12\x13meshtastic.protobuf\"-\n\x19\x43\x61nnedMessageModuleConfig\x12\x10\n\x08messages\x18\x01 \x01(\tBn\n\x13\x63om.geeksville.meshB\x19\x43\x61nnedMessageConfigProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3')
_globals = globals()
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.protobuf.cannedmessages_pb2', _globals)
if _descriptor._USE_C_DESCRIPTORS == False:
DESCRIPTOR._options = None
DESCRIPTOR._serialized_options = b'\n\024org.meshtastic.protoB\031CannedMessageConfigProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000'
DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\031CannedMessageConfigProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000'
_globals['_CANNEDMESSAGEMODULECONFIG']._serialized_start=65
_globals['_CANNEDMESSAGEMODULECONFIG']._serialized_end=110
# @@protoc_insertion_point(module_scope)

View File

@@ -13,22 +13,22 @@ _sym_db = _symbol_database.Default()
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n!meshtastic/protobuf/channel.proto\x12\x13meshtastic.protobuf\"\xc1\x01\n\x0f\x43hannelSettings\x12\x17\n\x0b\x63hannel_num\x18\x01 \x01(\rB\x02\x18\x01\x12\x0b\n\x03psk\x18\x02 \x01(\x0c\x12\x0c\n\x04name\x18\x03 \x01(\t\x12\n\n\x02id\x18\x04 \x01(\x07\x12\x16\n\x0euplink_enabled\x18\x05 \x01(\x08\x12\x18\n\x10\x64ownlink_enabled\x18\x06 \x01(\x08\x12<\n\x0fmodule_settings\x18\x07 \x01(\x0b\x32#.meshtastic.protobuf.ModuleSettings\">\n\x0eModuleSettings\x12\x1a\n\x12position_precision\x18\x01 \x01(\r\x12\x10\n\x08is_muted\x18\x02 \x01(\x08\"\xb3\x01\n\x07\x43hannel\x12\r\n\x05index\x18\x01 \x01(\x05\x12\x36\n\x08settings\x18\x02 \x01(\x0b\x32$.meshtastic.protobuf.ChannelSettings\x12/\n\x04role\x18\x03 \x01(\x0e\x32!.meshtastic.protobuf.Channel.Role\"0\n\x04Role\x12\x0c\n\x08\x44ISABLED\x10\x00\x12\x0b\n\x07PRIMARY\x10\x01\x12\r\n\tSECONDARY\x10\x02\x42\x63\n\x14org.meshtastic.protoB\rChannelProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3')
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n!meshtastic/protobuf/channel.proto\x12\x13meshtastic.protobuf\"\xc1\x01\n\x0f\x43hannelSettings\x12\x17\n\x0b\x63hannel_num\x18\x01 \x01(\rB\x02\x18\x01\x12\x0b\n\x03psk\x18\x02 \x01(\x0c\x12\x0c\n\x04name\x18\x03 \x01(\t\x12\n\n\x02id\x18\x04 \x01(\x07\x12\x16\n\x0euplink_enabled\x18\x05 \x01(\x08\x12\x18\n\x10\x64ownlink_enabled\x18\x06 \x01(\x08\x12<\n\x0fmodule_settings\x18\x07 \x01(\x0b\x32#.meshtastic.protobuf.ModuleSettings\"E\n\x0eModuleSettings\x12\x1a\n\x12position_precision\x18\x01 \x01(\r\x12\x17\n\x0fis_client_muted\x18\x02 \x01(\x08\"\xb3\x01\n\x07\x43hannel\x12\r\n\x05index\x18\x01 \x01(\x05\x12\x36\n\x08settings\x18\x02 \x01(\x0b\x32$.meshtastic.protobuf.ChannelSettings\x12/\n\x04role\x18\x03 \x01(\x0e\x32!.meshtastic.protobuf.Channel.Role\"0\n\x04Role\x12\x0c\n\x08\x44ISABLED\x10\x00\x12\x0b\n\x07PRIMARY\x10\x01\x12\r\n\tSECONDARY\x10\x02\x42\x62\n\x13\x63om.geeksville.meshB\rChannelProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3')
_globals = globals()
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.protobuf.channel_pb2', _globals)
if _descriptor._USE_C_DESCRIPTORS == False:
DESCRIPTOR._options = None
DESCRIPTOR._serialized_options = b'\n\024org.meshtastic.protoB\rChannelProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000'
DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\rChannelProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000'
_CHANNELSETTINGS.fields_by_name['channel_num']._options = None
_CHANNELSETTINGS.fields_by_name['channel_num']._serialized_options = b'\030\001'
_globals['_CHANNELSETTINGS']._serialized_start=59
_globals['_CHANNELSETTINGS']._serialized_end=252
_globals['_MODULESETTINGS']._serialized_start=254
_globals['_MODULESETTINGS']._serialized_end=316
_globals['_CHANNEL']._serialized_start=319
_globals['_CHANNEL']._serialized_end=498
_globals['_CHANNEL_ROLE']._serialized_start=450
_globals['_CHANNEL_ROLE']._serialized_end=498
_globals['_MODULESETTINGS']._serialized_end=323
_globals['_CHANNEL']._serialized_start=326
_globals['_CHANNEL']._serialized_end=505
_globals['_CHANNEL_ROLE']._serialized_start=457
_globals['_CHANNEL_ROLE']._serialized_end=505
# @@protoc_insertion_point(module_scope)

View File

@@ -127,23 +127,23 @@ class ModuleSettings(google.protobuf.message.Message):
DESCRIPTOR: google.protobuf.descriptor.Descriptor
POSITION_PRECISION_FIELD_NUMBER: builtins.int
IS_MUTED_FIELD_NUMBER: builtins.int
IS_CLIENT_MUTED_FIELD_NUMBER: builtins.int
position_precision: builtins.int
"""
Bits of precision for the location sent in position packets.
"""
is_muted: builtins.bool
is_client_muted: builtins.bool
"""
Controls whether or not the client / device should mute the current channel
Controls whether or not the phone / clients should mute the current channel
Useful for noisy public channels you don't necessarily want to disable
"""
def __init__(
self,
*,
position_precision: builtins.int = ...,
is_muted: builtins.bool = ...,
is_client_muted: builtins.bool = ...,
) -> None: ...
def ClearField(self, field_name: typing.Literal["is_muted", b"is_muted", "position_precision", b"position_precision"]) -> None: ...
def ClearField(self, field_name: typing.Literal["is_client_muted", b"is_client_muted", "position_precision", b"position_precision"]) -> None: ...
global___ModuleSettings = ModuleSettings

View File

@@ -15,14 +15,14 @@ from meshtastic.protobuf import localonly_pb2 as meshtastic_dot_protobuf_dot_loc
from meshtastic.protobuf import mesh_pb2 as meshtastic_dot_protobuf_dot_mesh__pb2
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n$meshtastic/protobuf/clientonly.proto\x12\x13meshtastic.protobuf\x1a#meshtastic/protobuf/localonly.proto\x1a\x1emeshtastic/protobuf/mesh.proto\"\xc4\x03\n\rDeviceProfile\x12\x16\n\tlong_name\x18\x01 \x01(\tH\x00\x88\x01\x01\x12\x17\n\nshort_name\x18\x02 \x01(\tH\x01\x88\x01\x01\x12\x18\n\x0b\x63hannel_url\x18\x03 \x01(\tH\x02\x88\x01\x01\x12\x35\n\x06\x63onfig\x18\x04 \x01(\x0b\x32 .meshtastic.protobuf.LocalConfigH\x03\x88\x01\x01\x12\x42\n\rmodule_config\x18\x05 \x01(\x0b\x32&.meshtastic.protobuf.LocalModuleConfigH\x04\x88\x01\x01\x12:\n\x0e\x66ixed_position\x18\x06 \x01(\x0b\x32\x1d.meshtastic.protobuf.PositionH\x05\x88\x01\x01\x12\x15\n\x08ringtone\x18\x07 \x01(\tH\x06\x88\x01\x01\x12\x1c\n\x0f\x63\x61nned_messages\x18\x08 \x01(\tH\x07\x88\x01\x01\x42\x0c\n\n_long_nameB\r\n\x0b_short_nameB\x0e\n\x0c_channel_urlB\t\n\x07_configB\x10\n\x0e_module_configB\x11\n\x0f_fixed_positionB\x0b\n\t_ringtoneB\x12\n\x10_canned_messagesBf\n\x14org.meshtastic.protoB\x10\x43lientOnlyProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3')
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n$meshtastic/protobuf/clientonly.proto\x12\x13meshtastic.protobuf\x1a#meshtastic/protobuf/localonly.proto\x1a\x1emeshtastic/protobuf/mesh.proto\"\xc4\x03\n\rDeviceProfile\x12\x16\n\tlong_name\x18\x01 \x01(\tH\x00\x88\x01\x01\x12\x17\n\nshort_name\x18\x02 \x01(\tH\x01\x88\x01\x01\x12\x18\n\x0b\x63hannel_url\x18\x03 \x01(\tH\x02\x88\x01\x01\x12\x35\n\x06\x63onfig\x18\x04 \x01(\x0b\x32 .meshtastic.protobuf.LocalConfigH\x03\x88\x01\x01\x12\x42\n\rmodule_config\x18\x05 \x01(\x0b\x32&.meshtastic.protobuf.LocalModuleConfigH\x04\x88\x01\x01\x12:\n\x0e\x66ixed_position\x18\x06 \x01(\x0b\x32\x1d.meshtastic.protobuf.PositionH\x05\x88\x01\x01\x12\x15\n\x08ringtone\x18\x07 \x01(\tH\x06\x88\x01\x01\x12\x1c\n\x0f\x63\x61nned_messages\x18\x08 \x01(\tH\x07\x88\x01\x01\x42\x0c\n\n_long_nameB\r\n\x0b_short_nameB\x0e\n\x0c_channel_urlB\t\n\x07_configB\x10\n\x0e_module_configB\x11\n\x0f_fixed_positionB\x0b\n\t_ringtoneB\x12\n\x10_canned_messagesBe\n\x13\x63om.geeksville.meshB\x10\x43lientOnlyProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3')
_globals = globals()
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.protobuf.clientonly_pb2', _globals)
if _descriptor._USE_C_DESCRIPTORS == False:
DESCRIPTOR._options = None
DESCRIPTOR._serialized_options = b'\n\024org.meshtastic.protoB\020ClientOnlyProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000'
DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\020ClientOnlyProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000'
_globals['_DEVICEPROFILE']._serialized_start=131
_globals['_DEVICEPROFILE']._serialized_end=583
# @@protoc_insertion_point(module_scope)

View File

File diff suppressed because one or more lines are too long

View File

@@ -64,7 +64,6 @@ class Config(google.protobuf.message.Message):
Description: Infrastructure node for extending network coverage by relaying messages with minimal overhead. Not visible in Nodes list.
Technical Details: Mesh packets will simply be rebroadcasted over this node. Nodes configured with this role will not originate NodeInfo, Position, Telemetry
or any other packet type. They will simply rebroadcast any mesh packets on the same frequency, channel num, spread factor, and coding rate.
Deprecated in v2.7.11 because it creates "holes" in the mesh rebroadcast chain.
"""
TRACKER: Config.DeviceConfig._Role.ValueType # 5
"""
@@ -117,13 +116,6 @@ class Config(google.protobuf.message.Message):
but should not be given priority over other routers in order to avoid unnecessaraily
consuming hops.
"""
CLIENT_BASE: Config.DeviceConfig._Role.ValueType # 12
"""
Description: Treats packets from or to favorited nodes as ROUTER, and all other packets as CLIENT.
Technical Details: Used for stronger attic/roof nodes to distribute messages more widely
from weaker, indoor, or less-well-positioned nodes. Recommended for users with multiple nodes
where one CLIENT_BASE acts as a more powerful base station, such as an attic/roof node.
"""
class Role(_Role, metaclass=_RoleEnumTypeWrapper):
"""
@@ -156,7 +148,6 @@ class Config(google.protobuf.message.Message):
Description: Infrastructure node for extending network coverage by relaying messages with minimal overhead. Not visible in Nodes list.
Technical Details: Mesh packets will simply be rebroadcasted over this node. Nodes configured with this role will not originate NodeInfo, Position, Telemetry
or any other packet type. They will simply rebroadcast any mesh packets on the same frequency, channel num, spread factor, and coding rate.
Deprecated in v2.7.11 because it creates "holes" in the mesh rebroadcast chain.
"""
TRACKER: Config.DeviceConfig.Role.ValueType # 5
"""
@@ -209,13 +200,6 @@ class Config(google.protobuf.message.Message):
but should not be given priority over other routers in order to avoid unnecessaraily
consuming hops.
"""
CLIENT_BASE: Config.DeviceConfig.Role.ValueType # 12
"""
Description: Treats packets from or to favorited nodes as ROUTER, and all other packets as CLIENT.
Technical Details: Used for stronger attic/roof nodes to distribute messages more widely
from weaker, indoor, or less-well-positioned nodes. Recommended for users with multiple nodes
where one CLIENT_BASE acts as a more powerful base station, such as an attic/roof node.
"""
class _RebroadcastMode:
ValueType = typing.NewType("ValueType", builtins.int)
@@ -288,73 +272,6 @@ class Config(google.protobuf.message.Message):
Only rebroadcasts packets with standard portnums: NodeInfo, Text, Position, Telemetry, and Routing.
"""
class _BuzzerMode:
ValueType = typing.NewType("ValueType", builtins.int)
V: typing_extensions.TypeAlias = ValueType
class _BuzzerModeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[Config.DeviceConfig._BuzzerMode.ValueType], builtins.type):
DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor
ALL_ENABLED: Config.DeviceConfig._BuzzerMode.ValueType # 0
"""
Default behavior.
Buzzer is enabled for all audio feedback including button presses and alerts.
"""
DISABLED: Config.DeviceConfig._BuzzerMode.ValueType # 1
"""
Disabled.
All buzzer audio feedback is disabled.
"""
NOTIFICATIONS_ONLY: Config.DeviceConfig._BuzzerMode.ValueType # 2
"""
Notifications Only.
Buzzer is enabled only for notifications and alerts, but not for button presses.
External notification config determines the specifics of the notification behavior.
"""
SYSTEM_ONLY: Config.DeviceConfig._BuzzerMode.ValueType # 3
"""
Non-notification system buzzer tones only.
Buzzer is enabled only for non-notification tones such as button presses, startup, shutdown, but not for alerts.
"""
DIRECT_MSG_ONLY: Config.DeviceConfig._BuzzerMode.ValueType # 4
"""
Direct Message notifications only.
Buzzer is enabled only for direct messages and alerts, but not for button presses.
External notification config determines the specifics of the notification behavior.
"""
class BuzzerMode(_BuzzerMode, metaclass=_BuzzerModeEnumTypeWrapper):
"""
Defines buzzer behavior for audio feedback
"""
ALL_ENABLED: Config.DeviceConfig.BuzzerMode.ValueType # 0
"""
Default behavior.
Buzzer is enabled for all audio feedback including button presses and alerts.
"""
DISABLED: Config.DeviceConfig.BuzzerMode.ValueType # 1
"""
Disabled.
All buzzer audio feedback is disabled.
"""
NOTIFICATIONS_ONLY: Config.DeviceConfig.BuzzerMode.ValueType # 2
"""
Notifications Only.
Buzzer is enabled only for notifications and alerts, but not for button presses.
External notification config determines the specifics of the notification behavior.
"""
SYSTEM_ONLY: Config.DeviceConfig.BuzzerMode.ValueType # 3
"""
Non-notification system buzzer tones only.
Buzzer is enabled only for non-notification tones such as button presses, startup, shutdown, but not for alerts.
"""
DIRECT_MSG_ONLY: Config.DeviceConfig.BuzzerMode.ValueType # 4
"""
Direct Message notifications only.
Buzzer is enabled only for direct messages and alerts, but not for button presses.
External notification config determines the specifics of the notification behavior.
"""
ROLE_FIELD_NUMBER: builtins.int
SERIAL_ENABLED_FIELD_NUMBER: builtins.int
BUTTON_GPIO_FIELD_NUMBER: builtins.int
@@ -366,7 +283,6 @@ class Config(google.protobuf.message.Message):
DISABLE_TRIPLE_CLICK_FIELD_NUMBER: builtins.int
TZDEF_FIELD_NUMBER: builtins.int
LED_HEARTBEAT_DISABLED_FIELD_NUMBER: builtins.int
BUZZER_MODE_FIELD_NUMBER: builtins.int
role: global___Config.DeviceConfig.Role.ValueType
"""
Sets the role of node
@@ -417,11 +333,6 @@ class Config(google.protobuf.message.Message):
"""
If true, disable the default blinking LED (LED_PIN) behavior on the device
"""
buzzer_mode: global___Config.DeviceConfig.BuzzerMode.ValueType
"""
Controls buzzer behavior for audio feedback
Defaults to ENABLED
"""
def __init__(
self,
*,
@@ -436,9 +347,8 @@ class Config(google.protobuf.message.Message):
disable_triple_click: builtins.bool = ...,
tzdef: builtins.str = ...,
led_heartbeat_disabled: builtins.bool = ...,
buzzer_mode: global___Config.DeviceConfig.BuzzerMode.ValueType = ...,
) -> None: ...
def ClearField(self, field_name: typing.Literal["button_gpio", b"button_gpio", "buzzer_gpio", b"buzzer_gpio", "buzzer_mode", b"buzzer_mode", "disable_triple_click", b"disable_triple_click", "double_tap_as_button_press", b"double_tap_as_button_press", "is_managed", b"is_managed", "led_heartbeat_disabled", b"led_heartbeat_disabled", "node_info_broadcast_secs", b"node_info_broadcast_secs", "rebroadcast_mode", b"rebroadcast_mode", "role", b"role", "serial_enabled", b"serial_enabled", "tzdef", b"tzdef"]) -> None: ...
def ClearField(self, field_name: typing.Literal["button_gpio", b"button_gpio", "buzzer_gpio", b"buzzer_gpio", "disable_triple_click", b"disable_triple_click", "double_tap_as_button_press", b"double_tap_as_button_press", "is_managed", b"is_managed", "led_heartbeat_disabled", b"led_heartbeat_disabled", "node_info_broadcast_secs", b"node_info_broadcast_secs", "rebroadcast_mode", b"rebroadcast_mode", "role", b"role", "serial_enabled", b"serial_enabled", "tzdef", b"tzdef"]) -> None: ...
@typing.final
class PositionConfig(google.protobuf.message.Message):
@@ -705,7 +615,7 @@ class Config(google.protobuf.message.Message):
POWERMON_ENABLES_FIELD_NUMBER: builtins.int
is_power_saving: builtins.bool
"""
Description: Will sleep everything as much as possible, for the tracker and sensor role this will also include the lora radio.
Description: Will sleep everything as much as possible, for the tracker and sensor role this will also include the lora radio.
Don't use this setting if you want to use your device with the phone apps or are using a device without a user button.
Technical Details: Works for ESP32 devices and NRF52 devices in the Sensor or Tracker roles
"""
@@ -871,7 +781,6 @@ class Config(google.protobuf.message.Message):
IPV4_CONFIG_FIELD_NUMBER: builtins.int
RSYSLOG_SERVER_FIELD_NUMBER: builtins.int
ENABLED_PROTOCOLS_FIELD_NUMBER: builtins.int
IPV6_ENABLED_FIELD_NUMBER: builtins.int
wifi_enabled: builtins.bool
"""
Enable WiFi (disables Bluetooth)
@@ -887,7 +796,7 @@ class Config(google.protobuf.message.Message):
"""
ntp_server: builtins.str
"""
NTP server to use if WiFi is conneced, defaults to `meshtastic.pool.ntp.org`
NTP server to use if WiFi is conneced, defaults to `0.pool.ntp.org`
"""
eth_enabled: builtins.bool
"""
@@ -905,10 +814,6 @@ class Config(google.protobuf.message.Message):
"""
Flags for enabling/disabling network protocols
"""
ipv6_enabled: builtins.bool
"""
Enable/Disable ipv6 support
"""
@property
def ipv4_config(self) -> global___Config.NetworkConfig.IpV4Config:
"""
@@ -927,10 +832,9 @@ class Config(google.protobuf.message.Message):
ipv4_config: global___Config.NetworkConfig.IpV4Config | None = ...,
rsyslog_server: builtins.str = ...,
enabled_protocols: builtins.int = ...,
ipv6_enabled: builtins.bool = ...,
) -> None: ...
def HasField(self, field_name: typing.Literal["ipv4_config", b"ipv4_config"]) -> builtins.bool: ...
def ClearField(self, field_name: typing.Literal["address_mode", b"address_mode", "enabled_protocols", b"enabled_protocols", "eth_enabled", b"eth_enabled", "ipv4_config", b"ipv4_config", "ipv6_enabled", b"ipv6_enabled", "ntp_server", b"ntp_server", "rsyslog_server", b"rsyslog_server", "wifi_enabled", b"wifi_enabled", "wifi_psk", b"wifi_psk", "wifi_ssid", b"wifi_ssid"]) -> None: ...
def ClearField(self, field_name: typing.Literal["address_mode", b"address_mode", "enabled_protocols", b"enabled_protocols", "eth_enabled", b"eth_enabled", "ipv4_config", b"ipv4_config", "ntp_server", b"ntp_server", "rsyslog_server", b"rsyslog_server", "wifi_enabled", b"wifi_enabled", "wifi_psk", b"wifi_psk", "wifi_ssid", b"wifi_ssid"]) -> None: ...
@typing.final
class DisplayConfig(google.protobuf.message.Message):
@@ -940,20 +844,80 @@ class Config(google.protobuf.message.Message):
DESCRIPTOR: google.protobuf.descriptor.Descriptor
class _DeprecatedGpsCoordinateFormat:
class _GpsCoordinateFormat:
ValueType = typing.NewType("ValueType", builtins.int)
V: typing_extensions.TypeAlias = ValueType
class _DeprecatedGpsCoordinateFormatEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[Config.DisplayConfig._DeprecatedGpsCoordinateFormat.ValueType], builtins.type):
class _GpsCoordinateFormatEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[Config.DisplayConfig._GpsCoordinateFormat.ValueType], builtins.type):
DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor
UNUSED: Config.DisplayConfig._DeprecatedGpsCoordinateFormat.ValueType # 0
class DeprecatedGpsCoordinateFormat(_DeprecatedGpsCoordinateFormat, metaclass=_DeprecatedGpsCoordinateFormatEnumTypeWrapper):
DEC: Config.DisplayConfig._GpsCoordinateFormat.ValueType # 0
"""
Deprecated in 2.7.4: Unused
GPS coordinates are displayed in the normal decimal degrees format:
DD.DDDDDD DDD.DDDDDD
"""
DMS: Config.DisplayConfig._GpsCoordinateFormat.ValueType # 1
"""
GPS coordinates are displayed in the degrees minutes seconds format:
DD°MM'SS"C DDD°MM'SS"C, where C is the compass point representing the locations quadrant
"""
UTM: Config.DisplayConfig._GpsCoordinateFormat.ValueType # 2
"""
Universal Transverse Mercator format:
ZZB EEEEEE NNNNNNN, where Z is zone, B is band, E is easting, N is northing
"""
MGRS: Config.DisplayConfig._GpsCoordinateFormat.ValueType # 3
"""
Military Grid Reference System format:
ZZB CD EEEEE NNNNN, where Z is zone, B is band, C is the east 100k square, D is the north 100k square,
E is easting, N is northing
"""
OLC: Config.DisplayConfig._GpsCoordinateFormat.ValueType # 4
"""
Open Location Code (aka Plus Codes).
"""
OSGR: Config.DisplayConfig._GpsCoordinateFormat.ValueType # 5
"""
Ordnance Survey Grid Reference (the National Grid System of the UK).
Format: AB EEEEE NNNNN, where A is the east 100k square, B is the north 100k square,
E is the easting, N is the northing
"""
UNUSED: Config.DisplayConfig.DeprecatedGpsCoordinateFormat.ValueType # 0
class GpsCoordinateFormat(_GpsCoordinateFormat, metaclass=_GpsCoordinateFormatEnumTypeWrapper):
"""
How the GPS coordinates are displayed on the OLED screen.
"""
DEC: Config.DisplayConfig.GpsCoordinateFormat.ValueType # 0
"""
GPS coordinates are displayed in the normal decimal degrees format:
DD.DDDDDD DDD.DDDDDD
"""
DMS: Config.DisplayConfig.GpsCoordinateFormat.ValueType # 1
"""
GPS coordinates are displayed in the degrees minutes seconds format:
DD°MM'SS"C DDD°MM'SS"C, where C is the compass point representing the locations quadrant
"""
UTM: Config.DisplayConfig.GpsCoordinateFormat.ValueType # 2
"""
Universal Transverse Mercator format:
ZZB EEEEEE NNNNNNN, where Z is zone, B is band, E is easting, N is northing
"""
MGRS: Config.DisplayConfig.GpsCoordinateFormat.ValueType # 3
"""
Military Grid Reference System format:
ZZB CD EEEEE NNNNN, where Z is zone, B is band, C is the east 100k square, D is the north 100k square,
E is easting, N is northing
"""
OLC: Config.DisplayConfig.GpsCoordinateFormat.ValueType # 4
"""
Open Location Code (aka Plus Codes).
"""
OSGR: Config.DisplayConfig.GpsCoordinateFormat.ValueType # 5
"""
Ordnance Survey Grid Reference (the National Grid System of the UK).
Format: AB EEEEE NNNNN, where A is the east 100k square, B is the north 100k square,
E is the easting, N is the northing
"""
class _DisplayUnits:
ValueType = typing.NewType("ValueType", builtins.int)
@@ -992,22 +956,18 @@ class Config(google.protobuf.message.Message):
DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor
OLED_AUTO: Config.DisplayConfig._OledType.ValueType # 0
"""
Default / Autodetect
Default / Auto
"""
OLED_SSD1306: Config.DisplayConfig._OledType.ValueType # 1
"""
Default / Autodetect
Default / Auto
"""
OLED_SH1106: Config.DisplayConfig._OledType.ValueType # 2
"""
Default / Autodetect
Default / Auto
"""
OLED_SH1107: Config.DisplayConfig._OledType.ValueType # 3
"""
Can not be auto detected but set by proto. Used for 128x64 screens
"""
OLED_SH1107_128_128: Config.DisplayConfig._OledType.ValueType # 4
"""
Can not be auto detected but set by proto. Used for 128x128 screens
"""
@@ -1018,22 +978,18 @@ class Config(google.protobuf.message.Message):
OLED_AUTO: Config.DisplayConfig.OledType.ValueType # 0
"""
Default / Autodetect
Default / Auto
"""
OLED_SSD1306: Config.DisplayConfig.OledType.ValueType # 1
"""
Default / Autodetect
Default / Auto
"""
OLED_SH1106: Config.DisplayConfig.OledType.ValueType # 2
"""
Default / Autodetect
Default / Auto
"""
OLED_SH1107: Config.DisplayConfig.OledType.ValueType # 3
"""
Can not be auto detected but set by proto. Used for 128x64 screens
"""
OLED_SH1107_128_128: Config.DisplayConfig.OledType.ValueType # 4
"""
Can not be auto detected but set by proto. Used for 128x128 screens
"""
@@ -1163,15 +1119,13 @@ class Config(google.protobuf.message.Message):
WAKE_ON_TAP_OR_MOTION_FIELD_NUMBER: builtins.int
COMPASS_ORIENTATION_FIELD_NUMBER: builtins.int
USE_12H_CLOCK_FIELD_NUMBER: builtins.int
USE_LONG_NODE_NAME_FIELD_NUMBER: builtins.int
screen_on_secs: builtins.int
"""
Number of seconds the screen stays on after pressing the user button or receiving a message
0 for default of one minute MAXUINT for always on
"""
gps_format: global___Config.DisplayConfig.DeprecatedGpsCoordinateFormat.ValueType
gps_format: global___Config.DisplayConfig.GpsCoordinateFormat.ValueType
"""
Deprecated in 2.7.4: Unused
How the GPS coordinates are formatted on the OLED screen.
"""
auto_screen_carousel_secs: builtins.int
@@ -1217,16 +1171,11 @@ class Config(google.protobuf.message.Message):
If false (default), the device will display the time in 24-hour format on screen.
If true, the device will display the time in 12-hour format on screen.
"""
use_long_node_name: builtins.bool
"""
If false (default), the device will use short names for various display screens.
If true, node names will show in long format
"""
def __init__(
self,
*,
screen_on_secs: builtins.int = ...,
gps_format: global___Config.DisplayConfig.DeprecatedGpsCoordinateFormat.ValueType = ...,
gps_format: global___Config.DisplayConfig.GpsCoordinateFormat.ValueType = ...,
auto_screen_carousel_secs: builtins.int = ...,
compass_north_top: builtins.bool = ...,
flip_screen: builtins.bool = ...,
@@ -1237,9 +1186,8 @@ class Config(google.protobuf.message.Message):
wake_on_tap_or_motion: builtins.bool = ...,
compass_orientation: global___Config.DisplayConfig.CompassOrientation.ValueType = ...,
use_12h_clock: builtins.bool = ...,
use_long_node_name: builtins.bool = ...,
) -> None: ...
def ClearField(self, field_name: typing.Literal["auto_screen_carousel_secs", b"auto_screen_carousel_secs", "compass_north_top", b"compass_north_top", "compass_orientation", b"compass_orientation", "displaymode", b"displaymode", "flip_screen", b"flip_screen", "gps_format", b"gps_format", "heading_bold", b"heading_bold", "oled", b"oled", "screen_on_secs", b"screen_on_secs", "units", b"units", "use_12h_clock", b"use_12h_clock", "use_long_node_name", b"use_long_node_name", "wake_on_tap_or_motion", b"wake_on_tap_or_motion"]) -> None: ...
def ClearField(self, field_name: typing.Literal["auto_screen_carousel_secs", b"auto_screen_carousel_secs", "compass_north_top", b"compass_north_top", "compass_orientation", b"compass_orientation", "displaymode", b"displaymode", "flip_screen", b"flip_screen", "gps_format", b"gps_format", "heading_bold", b"heading_bold", "oled", b"oled", "screen_on_secs", b"screen_on_secs", "units", b"units", "use_12h_clock", b"use_12h_clock", "wake_on_tap_or_motion", b"wake_on_tap_or_motion"]) -> None: ...
@typing.final
class LoRaConfig(google.protobuf.message.Message):
@@ -1343,26 +1291,6 @@ class Config(google.protobuf.message.Message):
"""
Philippines 915mhz
"""
ANZ_433: Config.LoRaConfig._RegionCode.ValueType # 22
"""
Australia / New Zealand 433MHz
"""
KZ_433: Config.LoRaConfig._RegionCode.ValueType # 23
"""
Kazakhstan 433MHz
"""
KZ_863: Config.LoRaConfig._RegionCode.ValueType # 24
"""
Kazakhstan 863MHz
"""
NP_865: Config.LoRaConfig._RegionCode.ValueType # 25
"""
Nepal 865MHz
"""
BR_902: Config.LoRaConfig._RegionCode.ValueType # 26
"""
Brazil 902MHz
"""
class RegionCode(_RegionCode, metaclass=_RegionCodeEnumTypeWrapper): ...
UNSET: Config.LoRaConfig.RegionCode.ValueType # 0
@@ -1453,26 +1381,6 @@ class Config(google.protobuf.message.Message):
"""
Philippines 915mhz
"""
ANZ_433: Config.LoRaConfig.RegionCode.ValueType # 22
"""
Australia / New Zealand 433MHz
"""
KZ_433: Config.LoRaConfig.RegionCode.ValueType # 23
"""
Kazakhstan 433MHz
"""
KZ_863: Config.LoRaConfig.RegionCode.ValueType # 24
"""
Kazakhstan 863MHz
"""
NP_865: Config.LoRaConfig.RegionCode.ValueType # 25
"""
Nepal 865MHz
"""
BR_902: Config.LoRaConfig.RegionCode.ValueType # 26
"""
Brazil 902MHz
"""
class _ModemPreset:
ValueType = typing.NewType("ValueType", builtins.int)

View File

@@ -13,14 +13,14 @@ _sym_db = _symbol_database.Default()
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n+meshtastic/protobuf/connection_status.proto\x12\x13meshtastic.protobuf\"\xd5\x02\n\x16\x44\x65viceConnectionStatus\x12<\n\x04wifi\x18\x01 \x01(\x0b\x32).meshtastic.protobuf.WifiConnectionStatusH\x00\x88\x01\x01\x12\x44\n\x08\x65thernet\x18\x02 \x01(\x0b\x32-.meshtastic.protobuf.EthernetConnectionStatusH\x01\x88\x01\x01\x12\x46\n\tbluetooth\x18\x03 \x01(\x0b\x32..meshtastic.protobuf.BluetoothConnectionStatusH\x02\x88\x01\x01\x12@\n\x06serial\x18\x04 \x01(\x0b\x32+.meshtastic.protobuf.SerialConnectionStatusH\x03\x88\x01\x01\x42\x07\n\x05_wifiB\x0b\n\t_ethernetB\x0c\n\n_bluetoothB\t\n\x07_serial\"p\n\x14WifiConnectionStatus\x12<\n\x06status\x18\x01 \x01(\x0b\x32,.meshtastic.protobuf.NetworkConnectionStatus\x12\x0c\n\x04ssid\x18\x02 \x01(\t\x12\x0c\n\x04rssi\x18\x03 \x01(\x05\"X\n\x18\x45thernetConnectionStatus\x12<\n\x06status\x18\x01 \x01(\x0b\x32,.meshtastic.protobuf.NetworkConnectionStatus\"{\n\x17NetworkConnectionStatus\x12\x12\n\nip_address\x18\x01 \x01(\x07\x12\x14\n\x0cis_connected\x18\x02 \x01(\x08\x12\x19\n\x11is_mqtt_connected\x18\x03 \x01(\x08\x12\x1b\n\x13is_syslog_connected\x18\x04 \x01(\x08\"L\n\x19\x42luetoothConnectionStatus\x12\x0b\n\x03pin\x18\x01 \x01(\r\x12\x0c\n\x04rssi\x18\x02 \x01(\x05\x12\x14\n\x0cis_connected\x18\x03 \x01(\x08\"<\n\x16SerialConnectionStatus\x12\x0c\n\x04\x62\x61ud\x18\x01 \x01(\r\x12\x14\n\x0cis_connected\x18\x02 \x01(\x08\x42\x66\n\x14org.meshtastic.protoB\x10\x43onnStatusProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3')
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n+meshtastic/protobuf/connection_status.proto\x12\x13meshtastic.protobuf\"\xd5\x02\n\x16\x44\x65viceConnectionStatus\x12<\n\x04wifi\x18\x01 \x01(\x0b\x32).meshtastic.protobuf.WifiConnectionStatusH\x00\x88\x01\x01\x12\x44\n\x08\x65thernet\x18\x02 \x01(\x0b\x32-.meshtastic.protobuf.EthernetConnectionStatusH\x01\x88\x01\x01\x12\x46\n\tbluetooth\x18\x03 \x01(\x0b\x32..meshtastic.protobuf.BluetoothConnectionStatusH\x02\x88\x01\x01\x12@\n\x06serial\x18\x04 \x01(\x0b\x32+.meshtastic.protobuf.SerialConnectionStatusH\x03\x88\x01\x01\x42\x07\n\x05_wifiB\x0b\n\t_ethernetB\x0c\n\n_bluetoothB\t\n\x07_serial\"p\n\x14WifiConnectionStatus\x12<\n\x06status\x18\x01 \x01(\x0b\x32,.meshtastic.protobuf.NetworkConnectionStatus\x12\x0c\n\x04ssid\x18\x02 \x01(\t\x12\x0c\n\x04rssi\x18\x03 \x01(\x05\"X\n\x18\x45thernetConnectionStatus\x12<\n\x06status\x18\x01 \x01(\x0b\x32,.meshtastic.protobuf.NetworkConnectionStatus\"{\n\x17NetworkConnectionStatus\x12\x12\n\nip_address\x18\x01 \x01(\x07\x12\x14\n\x0cis_connected\x18\x02 \x01(\x08\x12\x19\n\x11is_mqtt_connected\x18\x03 \x01(\x08\x12\x1b\n\x13is_syslog_connected\x18\x04 \x01(\x08\"L\n\x19\x42luetoothConnectionStatus\x12\x0b\n\x03pin\x18\x01 \x01(\r\x12\x0c\n\x04rssi\x18\x02 \x01(\x05\x12\x14\n\x0cis_connected\x18\x03 \x01(\x08\"<\n\x16SerialConnectionStatus\x12\x0c\n\x04\x62\x61ud\x18\x01 \x01(\r\x12\x14\n\x0cis_connected\x18\x02 \x01(\x08\x42\x65\n\x13\x63om.geeksville.meshB\x10\x43onnStatusProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3')
_globals = globals()
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.protobuf.connection_status_pb2', _globals)
if _descriptor._USE_C_DESCRIPTORS == False:
DESCRIPTOR._options = None
DESCRIPTOR._serialized_options = b'\n\024org.meshtastic.protoB\020ConnStatusProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000'
DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\020ConnStatusProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000'
_globals['_DEVICECONNECTIONSTATUS']._serialized_start=69
_globals['_DEVICECONNECTIONSTATUS']._serialized_end=410
_globals['_WIFICONNECTIONSTATUS']._serialized_start=412

View File

@@ -13,30 +13,26 @@ _sym_db = _symbol_database.Default()
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n#meshtastic/protobuf/device_ui.proto\x12\x13meshtastic.protobuf\"\xff\x05\n\x0e\x44\x65viceUIConfig\x12\x0f\n\x07version\x18\x01 \x01(\r\x12\x19\n\x11screen_brightness\x18\x02 \x01(\r\x12\x16\n\x0escreen_timeout\x18\x03 \x01(\r\x12\x13\n\x0bscreen_lock\x18\x04 \x01(\x08\x12\x15\n\rsettings_lock\x18\x05 \x01(\x08\x12\x10\n\x08pin_code\x18\x06 \x01(\r\x12)\n\x05theme\x18\x07 \x01(\x0e\x32\x1a.meshtastic.protobuf.Theme\x12\x15\n\ralert_enabled\x18\x08 \x01(\x08\x12\x16\n\x0e\x62\x61nner_enabled\x18\t \x01(\x08\x12\x14\n\x0cring_tone_id\x18\n \x01(\r\x12/\n\x08language\x18\x0b \x01(\x0e\x32\x1d.meshtastic.protobuf.Language\x12\x34\n\x0bnode_filter\x18\x0c \x01(\x0b\x32\x1f.meshtastic.protobuf.NodeFilter\x12:\n\x0enode_highlight\x18\r \x01(\x0b\x32\".meshtastic.protobuf.NodeHighlight\x12\x18\n\x10\x63\x61libration_data\x18\x0e \x01(\x0c\x12*\n\x08map_data\x18\x0f \x01(\x0b\x32\x18.meshtastic.protobuf.Map\x12\x36\n\x0c\x63ompass_mode\x18\x10 \x01(\x0e\x32 .meshtastic.protobuf.CompassMode\x12\x18\n\x10screen_rgb_color\x18\x11 \x01(\r\x12\x1b\n\x13is_clockface_analog\x18\x12 \x01(\x08\x12K\n\ngps_format\x18\x13 \x01(\x0e\x32\x37.meshtastic.protobuf.DeviceUIConfig.GpsCoordinateFormat\"V\n\x13GpsCoordinateFormat\x12\x07\n\x03\x44\x45\x43\x10\x00\x12\x07\n\x03\x44MS\x10\x01\x12\x07\n\x03UTM\x10\x02\x12\x08\n\x04MGRS\x10\x03\x12\x07\n\x03OLC\x10\x04\x12\x08\n\x04OSGR\x10\x05\x12\x07\n\x03MLS\x10\x06\"\xa7\x01\n\nNodeFilter\x12\x16\n\x0eunknown_switch\x18\x01 \x01(\x08\x12\x16\n\x0eoffline_switch\x18\x02 \x01(\x08\x12\x19\n\x11public_key_switch\x18\x03 \x01(\x08\x12\x11\n\thops_away\x18\x04 \x01(\x05\x12\x17\n\x0fposition_switch\x18\x05 \x01(\x08\x12\x11\n\tnode_name\x18\x06 \x01(\t\x12\x0f\n\x07\x63hannel\x18\x07 \x01(\x05\"~\n\rNodeHighlight\x12\x13\n\x0b\x63hat_switch\x18\x01 \x01(\x08\x12\x17\n\x0fposition_switch\x18\x02 \x01(\x08\x12\x18\n\x10telemetry_switch\x18\x03 \x01(\x08\x12\x12\n\niaq_switch\x18\x04 \x01(\x08\x12\x11\n\tnode_name\x18\x05 \x01(\t\"=\n\x08GeoPoint\x12\x0c\n\x04zoom\x18\x01 \x01(\x05\x12\x10\n\x08latitude\x18\x02 \x01(\x05\x12\x11\n\tlongitude\x18\x03 \x01(\x05\"U\n\x03Map\x12+\n\x04home\x18\x01 \x01(\x0b\x32\x1d.meshtastic.protobuf.GeoPoint\x12\r\n\x05style\x18\x02 \x01(\t\x12\x12\n\nfollow_gps\x18\x03 \x01(\x08*>\n\x0b\x43ompassMode\x12\x0b\n\x07\x44YNAMIC\x10\x00\x12\x0e\n\nFIXED_RING\x10\x01\x12\x12\n\x0e\x46REEZE_HEADING\x10\x02*%\n\x05Theme\x12\x08\n\x04\x44\x41RK\x10\x00\x12\t\n\x05LIGHT\x10\x01\x12\x07\n\x03RED\x10\x02*\xc0\x02\n\x08Language\x12\x0b\n\x07\x45NGLISH\x10\x00\x12\n\n\x06\x46RENCH\x10\x01\x12\n\n\x06GERMAN\x10\x02\x12\x0b\n\x07ITALIAN\x10\x03\x12\x0e\n\nPORTUGUESE\x10\x04\x12\x0b\n\x07SPANISH\x10\x05\x12\x0b\n\x07SWEDISH\x10\x06\x12\x0b\n\x07\x46INNISH\x10\x07\x12\n\n\x06POLISH\x10\x08\x12\x0b\n\x07TURKISH\x10\t\x12\x0b\n\x07SERBIAN\x10\n\x12\x0b\n\x07RUSSIAN\x10\x0b\x12\t\n\x05\x44UTCH\x10\x0c\x12\t\n\x05GREEK\x10\r\x12\r\n\tNORWEGIAN\x10\x0e\x12\r\n\tSLOVENIAN\x10\x0f\x12\r\n\tUKRAINIAN\x10\x10\x12\r\n\tBULGARIAN\x10\x11\x12\t\n\x05\x43ZECH\x10\x12\x12\n\n\x06\x44\x41NISH\x10\x13\x12\x16\n\x12SIMPLIFIED_CHINESE\x10\x1e\x12\x17\n\x13TRADITIONAL_CHINESE\x10\x1f\x42\x64\n\x14org.meshtastic.protoB\x0e\x44\x65viceUIProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3')
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n#meshtastic/protobuf/device_ui.proto\x12\x13meshtastic.protobuf\"\xeb\x03\n\x0e\x44\x65viceUIConfig\x12\x0f\n\x07version\x18\x01 \x01(\r\x12\x19\n\x11screen_brightness\x18\x02 \x01(\r\x12\x16\n\x0escreen_timeout\x18\x03 \x01(\r\x12\x13\n\x0bscreen_lock\x18\x04 \x01(\x08\x12\x15\n\rsettings_lock\x18\x05 \x01(\x08\x12\x10\n\x08pin_code\x18\x06 \x01(\r\x12)\n\x05theme\x18\x07 \x01(\x0e\x32\x1a.meshtastic.protobuf.Theme\x12\x15\n\ralert_enabled\x18\x08 \x01(\x08\x12\x16\n\x0e\x62\x61nner_enabled\x18\t \x01(\x08\x12\x14\n\x0cring_tone_id\x18\n \x01(\r\x12/\n\x08language\x18\x0b \x01(\x0e\x32\x1d.meshtastic.protobuf.Language\x12\x34\n\x0bnode_filter\x18\x0c \x01(\x0b\x32\x1f.meshtastic.protobuf.NodeFilter\x12:\n\x0enode_highlight\x18\r \x01(\x0b\x32\".meshtastic.protobuf.NodeHighlight\x12\x18\n\x10\x63\x61libration_data\x18\x0e \x01(\x0c\x12*\n\x08map_data\x18\x0f \x01(\x0b\x32\x18.meshtastic.protobuf.Map\"\xa7\x01\n\nNodeFilter\x12\x16\n\x0eunknown_switch\x18\x01 \x01(\x08\x12\x16\n\x0eoffline_switch\x18\x02 \x01(\x08\x12\x19\n\x11public_key_switch\x18\x03 \x01(\x08\x12\x11\n\thops_away\x18\x04 \x01(\x05\x12\x17\n\x0fposition_switch\x18\x05 \x01(\x08\x12\x11\n\tnode_name\x18\x06 \x01(\t\x12\x0f\n\x07\x63hannel\x18\x07 \x01(\x05\"~\n\rNodeHighlight\x12\x13\n\x0b\x63hat_switch\x18\x01 \x01(\x08\x12\x17\n\x0fposition_switch\x18\x02 \x01(\x08\x12\x18\n\x10telemetry_switch\x18\x03 \x01(\x08\x12\x12\n\niaq_switch\x18\x04 \x01(\x08\x12\x11\n\tnode_name\x18\x05 \x01(\t\"=\n\x08GeoPoint\x12\x0c\n\x04zoom\x18\x01 \x01(\x05\x12\x10\n\x08latitude\x18\x02 \x01(\x05\x12\x11\n\tlongitude\x18\x03 \x01(\x05\"U\n\x03Map\x12+\n\x04home\x18\x01 \x01(\x0b\x32\x1d.meshtastic.protobuf.GeoPoint\x12\r\n\x05style\x18\x02 \x01(\t\x12\x12\n\nfollow_gps\x18\x03 \x01(\x08*%\n\x05Theme\x12\x08\n\x04\x44\x41RK\x10\x00\x12\t\n\x05LIGHT\x10\x01\x12\x07\n\x03RED\x10\x02*\x8b\x02\n\x08Language\x12\x0b\n\x07\x45NGLISH\x10\x00\x12\n\n\x06\x46RENCH\x10\x01\x12\n\n\x06GERMAN\x10\x02\x12\x0b\n\x07ITALIAN\x10\x03\x12\x0e\n\nPORTUGUESE\x10\x04\x12\x0b\n\x07SPANISH\x10\x05\x12\x0b\n\x07SWEDISH\x10\x06\x12\x0b\n\x07\x46INNISH\x10\x07\x12\n\n\x06POLISH\x10\x08\x12\x0b\n\x07TURKISH\x10\t\x12\x0b\n\x07SERBIAN\x10\n\x12\x0b\n\x07RUSSIAN\x10\x0b\x12\t\n\x05\x44UTCH\x10\x0c\x12\t\n\x05GREEK\x10\r\x12\r\n\tNORWEGIAN\x10\x0e\x12\r\n\tSLOVENIAN\x10\x0f\x12\x16\n\x12SIMPLIFIED_CHINESE\x10\x1e\x12\x17\n\x13TRADITIONAL_CHINESE\x10\x1f\x42\x63\n\x13\x63om.geeksville.meshB\x0e\x44\x65viceUIProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3')
_globals = globals()
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.protobuf.device_ui_pb2', _globals)
if _descriptor._USE_C_DESCRIPTORS == False:
DESCRIPTOR._options = None
DESCRIPTOR._serialized_options = b'\n\024org.meshtastic.protoB\016DeviceUIProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000'
_globals['_COMPASSMODE']._serialized_start=1278
_globals['_COMPASSMODE']._serialized_end=1340
_globals['_THEME']._serialized_start=1342
_globals['_THEME']._serialized_end=1379
_globals['_LANGUAGE']._serialized_start=1382
_globals['_LANGUAGE']._serialized_end=1702
DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\016DeviceUIProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000'
_globals['_THEME']._serialized_start=1002
_globals['_THEME']._serialized_end=1039
_globals['_LANGUAGE']._serialized_start=1042
_globals['_LANGUAGE']._serialized_end=1309
_globals['_DEVICEUICONFIG']._serialized_start=61
_globals['_DEVICEUICONFIG']._serialized_end=828
_globals['_DEVICEUICONFIG_GPSCOORDINATEFORMAT']._serialized_start=742
_globals['_DEVICEUICONFIG_GPSCOORDINATEFORMAT']._serialized_end=828
_globals['_NODEFILTER']._serialized_start=831
_globals['_NODEFILTER']._serialized_end=998
_globals['_NODEHIGHLIGHT']._serialized_start=1000
_globals['_NODEHIGHLIGHT']._serialized_end=1126
_globals['_GEOPOINT']._serialized_start=1128
_globals['_GEOPOINT']._serialized_end=1189
_globals['_MAP']._serialized_start=1191
_globals['_MAP']._serialized_end=1276
_globals['_DEVICEUICONFIG']._serialized_end=552
_globals['_NODEFILTER']._serialized_start=555
_globals['_NODEFILTER']._serialized_end=722
_globals['_NODEHIGHLIGHT']._serialized_start=724
_globals['_NODEHIGHLIGHT']._serialized_end=850
_globals['_GEOPOINT']._serialized_start=852
_globals['_GEOPOINT']._serialized_end=913
_globals['_MAP']._serialized_start=915
_globals['_MAP']._serialized_end=1000
# @@protoc_insertion_point(module_scope)

View File

@@ -17,41 +17,6 @@ else:
DESCRIPTOR: google.protobuf.descriptor.FileDescriptor
class _CompassMode:
ValueType = typing.NewType("ValueType", builtins.int)
V: typing_extensions.TypeAlias = ValueType
class _CompassModeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_CompassMode.ValueType], builtins.type):
DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor
DYNAMIC: _CompassMode.ValueType # 0
"""
Compass with dynamic ring and heading
"""
FIXED_RING: _CompassMode.ValueType # 1
"""
Compass with fixed ring and heading
"""
FREEZE_HEADING: _CompassMode.ValueType # 2
"""
Compass with heading and freeze option
"""
class CompassMode(_CompassMode, metaclass=_CompassModeEnumTypeWrapper): ...
DYNAMIC: CompassMode.ValueType # 0
"""
Compass with dynamic ring and heading
"""
FIXED_RING: CompassMode.ValueType # 1
"""
Compass with fixed ring and heading
"""
FREEZE_HEADING: CompassMode.ValueType # 2
"""
Compass with heading and freeze option
"""
global___CompassMode = CompassMode
class _Theme:
ValueType = typing.NewType("ValueType", builtins.int)
V: typing_extensions.TypeAlias = ValueType
@@ -157,22 +122,6 @@ class _LanguageEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumT
"""
Slovenian
"""
UKRAINIAN: _Language.ValueType # 16
"""
Ukrainian
"""
BULGARIAN: _Language.ValueType # 17
"""
Bulgarian
"""
CZECH: _Language.ValueType # 18
"""
Czech
"""
DANISH: _Language.ValueType # 19
"""
Danish
"""
SIMPLIFIED_CHINESE: _Language.ValueType # 30
"""
Simplified Chinese (experimental)
@@ -251,22 +200,6 @@ SLOVENIAN: Language.ValueType # 15
"""
Slovenian
"""
UKRAINIAN: Language.ValueType # 16
"""
Ukrainian
"""
BULGARIAN: Language.ValueType # 17
"""
Bulgarian
"""
CZECH: Language.ValueType # 18
"""
Czech
"""
DANISH: Language.ValueType # 19
"""
Danish
"""
SIMPLIFIED_CHINESE: Language.ValueType # 30
"""
Simplified Chinese (experimental)
@@ -285,91 +218,6 @@ class DeviceUIConfig(google.protobuf.message.Message):
DESCRIPTOR: google.protobuf.descriptor.Descriptor
class _GpsCoordinateFormat:
ValueType = typing.NewType("ValueType", builtins.int)
V: typing_extensions.TypeAlias = ValueType
class _GpsCoordinateFormatEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[DeviceUIConfig._GpsCoordinateFormat.ValueType], builtins.type):
DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor
DEC: DeviceUIConfig._GpsCoordinateFormat.ValueType # 0
"""
GPS coordinates are displayed in the normal decimal degrees format:
DD.DDDDDD DDD.DDDDDD
"""
DMS: DeviceUIConfig._GpsCoordinateFormat.ValueType # 1
"""
GPS coordinates are displayed in the degrees minutes seconds format:
DD°MM'SS"C DDD°MM'SS"C, where C is the compass point representing the locations quadrant
"""
UTM: DeviceUIConfig._GpsCoordinateFormat.ValueType # 2
"""
Universal Transverse Mercator format:
ZZB EEEEEE NNNNNNN, where Z is zone, B is band, E is easting, N is northing
"""
MGRS: DeviceUIConfig._GpsCoordinateFormat.ValueType # 3
"""
Military Grid Reference System format:
ZZB CD EEEEE NNNNN, where Z is zone, B is band, C is the east 100k square, D is the north 100k square,
E is easting, N is northing
"""
OLC: DeviceUIConfig._GpsCoordinateFormat.ValueType # 4
"""
Open Location Code (aka Plus Codes).
"""
OSGR: DeviceUIConfig._GpsCoordinateFormat.ValueType # 5
"""
Ordnance Survey Grid Reference (the National Grid System of the UK).
Format: AB EEEEE NNNNN, where A is the east 100k square, B is the north 100k square,
E is the easting, N is the northing
"""
MLS: DeviceUIConfig._GpsCoordinateFormat.ValueType # 6
"""
Maidenhead Locator System
Described here: https://en.wikipedia.org/wiki/Maidenhead_Locator_System
"""
class GpsCoordinateFormat(_GpsCoordinateFormat, metaclass=_GpsCoordinateFormatEnumTypeWrapper):
"""
How the GPS coordinates are displayed on the OLED screen.
"""
DEC: DeviceUIConfig.GpsCoordinateFormat.ValueType # 0
"""
GPS coordinates are displayed in the normal decimal degrees format:
DD.DDDDDD DDD.DDDDDD
"""
DMS: DeviceUIConfig.GpsCoordinateFormat.ValueType # 1
"""
GPS coordinates are displayed in the degrees minutes seconds format:
DD°MM'SS"C DDD°MM'SS"C, where C is the compass point representing the locations quadrant
"""
UTM: DeviceUIConfig.GpsCoordinateFormat.ValueType # 2
"""
Universal Transverse Mercator format:
ZZB EEEEEE NNNNNNN, where Z is zone, B is band, E is easting, N is northing
"""
MGRS: DeviceUIConfig.GpsCoordinateFormat.ValueType # 3
"""
Military Grid Reference System format:
ZZB CD EEEEE NNNNN, where Z is zone, B is band, C is the east 100k square, D is the north 100k square,
E is easting, N is northing
"""
OLC: DeviceUIConfig.GpsCoordinateFormat.ValueType # 4
"""
Open Location Code (aka Plus Codes).
"""
OSGR: DeviceUIConfig.GpsCoordinateFormat.ValueType # 5
"""
Ordnance Survey Grid Reference (the National Grid System of the UK).
Format: AB EEEEE NNNNN, where A is the east 100k square, B is the north 100k square,
E is the easting, N is the northing
"""
MLS: DeviceUIConfig.GpsCoordinateFormat.ValueType # 6
"""
Maidenhead Locator System
Described here: https://en.wikipedia.org/wiki/Maidenhead_Locator_System
"""
VERSION_FIELD_NUMBER: builtins.int
SCREEN_BRIGHTNESS_FIELD_NUMBER: builtins.int
SCREEN_TIMEOUT_FIELD_NUMBER: builtins.int
@@ -385,10 +233,6 @@ class DeviceUIConfig(google.protobuf.message.Message):
NODE_HIGHLIGHT_FIELD_NUMBER: builtins.int
CALIBRATION_DATA_FIELD_NUMBER: builtins.int
MAP_DATA_FIELD_NUMBER: builtins.int
COMPASS_MODE_FIELD_NUMBER: builtins.int
SCREEN_RGB_COLOR_FIELD_NUMBER: builtins.int
IS_CLOCKFACE_ANALOG_FIELD_NUMBER: builtins.int
GPS_FORMAT_FIELD_NUMBER: builtins.int
version: builtins.int
"""
A version integer used to invalidate saved files when we make incompatible changes.
@@ -425,24 +269,6 @@ class DeviceUIConfig(google.protobuf.message.Message):
"""
8 integers for screen calibration data
"""
compass_mode: global___CompassMode.ValueType
"""
Compass mode
"""
screen_rgb_color: builtins.int
"""
RGB color for BaseUI
0xRRGGBB format, e.g. 0xFF0000 for red
"""
is_clockface_analog: builtins.bool
"""
Clockface analog style
true for analog clockface, false for digital clockface
"""
gps_format: global___DeviceUIConfig.GpsCoordinateFormat.ValueType
"""
How the GPS coordinates are formatted on the OLED screen.
"""
@property
def node_filter(self) -> global___NodeFilter:
"""
@@ -479,13 +305,9 @@ class DeviceUIConfig(google.protobuf.message.Message):
node_highlight: global___NodeHighlight | None = ...,
calibration_data: builtins.bytes = ...,
map_data: global___Map | None = ...,
compass_mode: global___CompassMode.ValueType = ...,
screen_rgb_color: builtins.int = ...,
is_clockface_analog: builtins.bool = ...,
gps_format: global___DeviceUIConfig.GpsCoordinateFormat.ValueType = ...,
) -> None: ...
def HasField(self, field_name: typing.Literal["map_data", b"map_data", "node_filter", b"node_filter", "node_highlight", b"node_highlight"]) -> builtins.bool: ...
def ClearField(self, field_name: typing.Literal["alert_enabled", b"alert_enabled", "banner_enabled", b"banner_enabled", "calibration_data", b"calibration_data", "compass_mode", b"compass_mode", "gps_format", b"gps_format", "is_clockface_analog", b"is_clockface_analog", "language", b"language", "map_data", b"map_data", "node_filter", b"node_filter", "node_highlight", b"node_highlight", "pin_code", b"pin_code", "ring_tone_id", b"ring_tone_id", "screen_brightness", b"screen_brightness", "screen_lock", b"screen_lock", "screen_rgb_color", b"screen_rgb_color", "screen_timeout", b"screen_timeout", "settings_lock", b"settings_lock", "theme", b"theme", "version", b"version"]) -> None: ...
def ClearField(self, field_name: typing.Literal["alert_enabled", b"alert_enabled", "banner_enabled", b"banner_enabled", "calibration_data", b"calibration_data", "language", b"language", "map_data", b"map_data", "node_filter", b"node_filter", "node_highlight", b"node_highlight", "pin_code", b"pin_code", "ring_tone_id", b"ring_tone_id", "screen_brightness", b"screen_brightness", "screen_lock", b"screen_lock", "screen_timeout", b"screen_timeout", "settings_lock", b"settings_lock", "theme", b"theme", "version", b"version"]) -> None: ...
global___DeviceUIConfig = DeviceUIConfig

View File

@@ -12,21 +12,21 @@ _sym_db = _symbol_database.Default()
from meshtastic.protobuf import channel_pb2 as meshtastic_dot_protobuf_dot_channel__pb2
from meshtastic.protobuf import config_pb2 as meshtastic_dot_protobuf_dot_config__pb2
from meshtastic.protobuf import localonly_pb2 as meshtastic_dot_protobuf_dot_localonly__pb2
from meshtastic.protobuf import mesh_pb2 as meshtastic_dot_protobuf_dot_mesh__pb2
from meshtastic.protobuf import telemetry_pb2 as meshtastic_dot_protobuf_dot_telemetry__pb2
from meshtastic.protobuf import nanopb_pb2 as meshtastic_dot_protobuf_dot_nanopb__pb2
from meshtastic.protobuf import config_pb2 as meshtastic_dot_protobuf_dot_config__pb2
from meshtastic.protobuf import localonly_pb2 as meshtastic_dot_protobuf_dot_localonly__pb2
import nanopb_pb2 as nanopb__pb2
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n$meshtastic/protobuf/deviceonly.proto\x12\x13meshtastic.protobuf\x1a!meshtastic/protobuf/channel.proto\x1a meshtastic/protobuf/config.proto\x1a#meshtastic/protobuf/localonly.proto\x1a\x1emeshtastic/protobuf/mesh.proto\x1a#meshtastic/protobuf/telemetry.proto\x1a meshtastic/protobuf/nanopb.proto\"\x99\x01\n\x0cPositionLite\x12\x12\n\nlatitude_i\x18\x01 \x01(\x0f\x12\x13\n\x0blongitude_i\x18\x02 \x01(\x0f\x12\x10\n\x08\x61ltitude\x18\x03 \x01(\x05\x12\x0c\n\x04time\x18\x04 \x01(\x07\x12@\n\x0flocation_source\x18\x05 \x01(\x0e\x32\'.meshtastic.protobuf.Position.LocSource\"\x94\x02\n\x08UserLite\x12\x13\n\x07macaddr\x18\x01 \x01(\x0c\x42\x02\x18\x01\x12\x11\n\tlong_name\x18\x02 \x01(\t\x12\x12\n\nshort_name\x18\x03 \x01(\t\x12\x34\n\x08hw_model\x18\x04 \x01(\x0e\x32\".meshtastic.protobuf.HardwareModel\x12\x13\n\x0bis_licensed\x18\x05 \x01(\x08\x12;\n\x04role\x18\x06 \x01(\x0e\x32-.meshtastic.protobuf.Config.DeviceConfig.Role\x12\x12\n\npublic_key\x18\x07 \x01(\x0c\x12\x1c\n\x0fis_unmessagable\x18\t \x01(\x08H\x00\x88\x01\x01\x42\x12\n\x10_is_unmessagable\"\xf0\x02\n\x0cNodeInfoLite\x12\x0b\n\x03num\x18\x01 \x01(\r\x12+\n\x04user\x18\x02 \x01(\x0b\x32\x1d.meshtastic.protobuf.UserLite\x12\x33\n\x08position\x18\x03 \x01(\x0b\x32!.meshtastic.protobuf.PositionLite\x12\x0b\n\x03snr\x18\x04 \x01(\x02\x12\x12\n\nlast_heard\x18\x05 \x01(\x07\x12:\n\x0e\x64\x65vice_metrics\x18\x06 \x01(\x0b\x32\".meshtastic.protobuf.DeviceMetrics\x12\x0f\n\x07\x63hannel\x18\x07 \x01(\r\x12\x10\n\x08via_mqtt\x18\x08 \x01(\x08\x12\x16\n\thops_away\x18\t \x01(\rH\x00\x88\x01\x01\x12\x13\n\x0bis_favorite\x18\n \x01(\x08\x12\x12\n\nis_ignored\x18\x0b \x01(\x08\x12\x10\n\x08next_hop\x18\x0c \x01(\r\x12\x10\n\x08\x62itfield\x18\r \x01(\rB\x0c\n\n_hops_away\"\xa1\x03\n\x0b\x44\x65viceState\x12\x30\n\x07my_node\x18\x02 \x01(\x0b\x32\x1f.meshtastic.protobuf.MyNodeInfo\x12(\n\x05owner\x18\x03 \x01(\x0b\x32\x19.meshtastic.protobuf.User\x12\x36\n\rreceive_queue\x18\x05 \x03(\x0b\x32\x1f.meshtastic.protobuf.MeshPacket\x12\x0f\n\x07version\x18\x08 \x01(\r\x12\x38\n\x0frx_text_message\x18\x07 \x01(\x0b\x32\x1f.meshtastic.protobuf.MeshPacket\x12\x13\n\x07no_save\x18\t \x01(\x08\x42\x02\x18\x01\x12\x19\n\rdid_gps_reset\x18\x0b \x01(\x08\x42\x02\x18\x01\x12\x34\n\x0brx_waypoint\x18\x0c \x01(\x0b\x32\x1f.meshtastic.protobuf.MeshPacket\x12M\n\x19node_remote_hardware_pins\x18\r \x03(\x0b\x32*.meshtastic.protobuf.NodeRemoteHardwarePin\"}\n\x0cNodeDatabase\x12\x0f\n\x07version\x18\x01 \x01(\r\x12\\\n\x05nodes\x18\x02 \x03(\x0b\x32!.meshtastic.protobuf.NodeInfoLiteB*\x92?\'\x92\x01$std::vector<meshtastic_NodeInfoLite>\"N\n\x0b\x43hannelFile\x12.\n\x08\x63hannels\x18\x01 \x03(\x0b\x32\x1c.meshtastic.protobuf.Channel\x12\x0f\n\x07version\x18\x02 \x01(\r\"\x86\x02\n\x11\x42\x61\x63kupPreferences\x12\x0f\n\x07version\x18\x01 \x01(\r\x12\x11\n\ttimestamp\x18\x02 \x01(\x07\x12\x30\n\x06\x63onfig\x18\x03 \x01(\x0b\x32 .meshtastic.protobuf.LocalConfig\x12=\n\rmodule_config\x18\x04 \x01(\x0b\x32&.meshtastic.protobuf.LocalModuleConfig\x12\x32\n\x08\x63hannels\x18\x05 \x01(\x0b\x32 .meshtastic.protobuf.ChannelFile\x12(\n\x05owner\x18\x06 \x01(\x0b\x32\x19.meshtastic.protobuf.UserBn\n\x14org.meshtastic.protoB\nDeviceOnlyZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x92?\x0b\xc2\x01\x08<vector>b\x06proto3')
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n$meshtastic/protobuf/deviceonly.proto\x12\x13meshtastic.protobuf\x1a!meshtastic/protobuf/channel.proto\x1a\x1emeshtastic/protobuf/mesh.proto\x1a#meshtastic/protobuf/telemetry.proto\x1a meshtastic/protobuf/config.proto\x1a#meshtastic/protobuf/localonly.proto\x1a\x0cnanopb.proto\"\x99\x01\n\x0cPositionLite\x12\x12\n\nlatitude_i\x18\x01 \x01(\x0f\x12\x13\n\x0blongitude_i\x18\x02 \x01(\x0f\x12\x10\n\x08\x61ltitude\x18\x03 \x01(\x05\x12\x0c\n\x04time\x18\x04 \x01(\x07\x12@\n\x0flocation_source\x18\x05 \x01(\x0e\x32\'.meshtastic.protobuf.Position.LocSource\"\xe2\x01\n\x08UserLite\x12\x13\n\x07macaddr\x18\x01 \x01(\x0c\x42\x02\x18\x01\x12\x11\n\tlong_name\x18\x02 \x01(\t\x12\x12\n\nshort_name\x18\x03 \x01(\t\x12\x34\n\x08hw_model\x18\x04 \x01(\x0e\x32\".meshtastic.protobuf.HardwareModel\x12\x13\n\x0bis_licensed\x18\x05 \x01(\x08\x12;\n\x04role\x18\x06 \x01(\x0e\x32-.meshtastic.protobuf.Config.DeviceConfig.Role\x12\x12\n\npublic_key\x18\x07 \x01(\x0c\"\xde\x02\n\x0cNodeInfoLite\x12\x0b\n\x03num\x18\x01 \x01(\r\x12+\n\x04user\x18\x02 \x01(\x0b\x32\x1d.meshtastic.protobuf.UserLite\x12\x33\n\x08position\x18\x03 \x01(\x0b\x32!.meshtastic.protobuf.PositionLite\x12\x0b\n\x03snr\x18\x04 \x01(\x02\x12\x12\n\nlast_heard\x18\x05 \x01(\x07\x12:\n\x0e\x64\x65vice_metrics\x18\x06 \x01(\x0b\x32\".meshtastic.protobuf.DeviceMetrics\x12\x0f\n\x07\x63hannel\x18\x07 \x01(\r\x12\x10\n\x08via_mqtt\x18\x08 \x01(\x08\x12\x16\n\thops_away\x18\t \x01(\rH\x00\x88\x01\x01\x12\x13\n\x0bis_favorite\x18\n \x01(\x08\x12\x12\n\nis_ignored\x18\x0b \x01(\x08\x12\x10\n\x08next_hop\x18\x0c \x01(\rB\x0c\n\n_hops_away\"\xa1\x03\n\x0b\x44\x65viceState\x12\x30\n\x07my_node\x18\x02 \x01(\x0b\x32\x1f.meshtastic.protobuf.MyNodeInfo\x12(\n\x05owner\x18\x03 \x01(\x0b\x32\x19.meshtastic.protobuf.User\x12\x36\n\rreceive_queue\x18\x05 \x03(\x0b\x32\x1f.meshtastic.protobuf.MeshPacket\x12\x0f\n\x07version\x18\x08 \x01(\r\x12\x38\n\x0frx_text_message\x18\x07 \x01(\x0b\x32\x1f.meshtastic.protobuf.MeshPacket\x12\x13\n\x07no_save\x18\t \x01(\x08\x42\x02\x18\x01\x12\x19\n\rdid_gps_reset\x18\x0b \x01(\x08\x42\x02\x18\x01\x12\x34\n\x0brx_waypoint\x18\x0c \x01(\x0b\x32\x1f.meshtastic.protobuf.MeshPacket\x12M\n\x19node_remote_hardware_pins\x18\r \x03(\x0b\x32*.meshtastic.protobuf.NodeRemoteHardwarePin\"}\n\x0cNodeDatabase\x12\x0f\n\x07version\x18\x01 \x01(\r\x12\\\n\x05nodes\x18\x02 \x03(\x0b\x32!.meshtastic.protobuf.NodeInfoLiteB*\x92?\'\x92\x01$std::vector<meshtastic_NodeInfoLite>\"N\n\x0b\x43hannelFile\x12.\n\x08\x63hannels\x18\x01 \x03(\x0b\x32\x1c.meshtastic.protobuf.Channel\x12\x0f\n\x07version\x18\x02 \x01(\r\"\x86\x02\n\x11\x42\x61\x63kupPreferences\x12\x0f\n\x07version\x18\x01 \x01(\r\x12\x11\n\ttimestamp\x18\x02 \x01(\x07\x12\x30\n\x06\x63onfig\x18\x03 \x01(\x0b\x32 .meshtastic.protobuf.LocalConfig\x12=\n\rmodule_config\x18\x04 \x01(\x0b\x32&.meshtastic.protobuf.LocalModuleConfig\x12\x32\n\x08\x63hannels\x18\x05 \x01(\x0b\x32 .meshtastic.protobuf.ChannelFile\x12(\n\x05owner\x18\x06 \x01(\x0b\x32\x19.meshtastic.protobuf.UserBm\n\x13\x63om.geeksville.meshB\nDeviceOnlyZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x92?\x0b\xc2\x01\x08<vector>b\x06proto3')
_globals = globals()
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.protobuf.deviceonly_pb2', _globals)
if _descriptor._USE_C_DESCRIPTORS == False:
DESCRIPTOR._options = None
DESCRIPTOR._serialized_options = b'\n\024org.meshtastic.protoB\nDeviceOnlyZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000\222?\013\302\001\010<vector>'
DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\nDeviceOnlyZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000\222?\013\302\001\010<vector>'
_USERLITE.fields_by_name['macaddr']._options = None
_USERLITE.fields_by_name['macaddr']._serialized_options = b'\030\001'
_DEVICESTATE.fields_by_name['no_save']._options = None
@@ -35,18 +35,18 @@ if _descriptor._USE_C_DESCRIPTORS == False:
_DEVICESTATE.fields_by_name['did_gps_reset']._serialized_options = b'\030\001'
_NODEDATABASE.fields_by_name['nodes']._options = None
_NODEDATABASE.fields_by_name['nodes']._serialized_options = b'\222?\'\222\001$std::vector<meshtastic_NodeInfoLite>'
_globals['_POSITIONLITE']._serialized_start=271
_globals['_POSITIONLITE']._serialized_end=424
_globals['_USERLITE']._serialized_start=427
_globals['_USERLITE']._serialized_end=703
_globals['_NODEINFOLITE']._serialized_start=706
_globals['_NODEINFOLITE']._serialized_end=1074
_globals['_DEVICESTATE']._serialized_start=1077
_globals['_DEVICESTATE']._serialized_end=1494
_globals['_NODEDATABASE']._serialized_start=1496
_globals['_NODEDATABASE']._serialized_end=1621
_globals['_CHANNELFILE']._serialized_start=1623
_globals['_CHANNELFILE']._serialized_end=1701
_globals['_BACKUPPREFERENCES']._serialized_start=1704
_globals['_BACKUPPREFERENCES']._serialized_end=1966
_globals['_POSITIONLITE']._serialized_start=251
_globals['_POSITIONLITE']._serialized_end=404
_globals['_USERLITE']._serialized_start=407
_globals['_USERLITE']._serialized_end=633
_globals['_NODEINFOLITE']._serialized_start=636
_globals['_NODEINFOLITE']._serialized_end=986
_globals['_DEVICESTATE']._serialized_start=989
_globals['_DEVICESTATE']._serialized_end=1406
_globals['_NODEDATABASE']._serialized_start=1408
_globals['_NODEDATABASE']._serialized_end=1533
_globals['_CHANNELFILE']._serialized_start=1535
_globals['_CHANNELFILE']._serialized_end=1613
_globals['_BACKUPPREFERENCES']._serialized_start=1616
_globals['_BACKUPPREFERENCES']._serialized_end=1878
# @@protoc_insertion_point(module_scope)

View File

@@ -79,7 +79,6 @@ class UserLite(google.protobuf.message.Message):
IS_LICENSED_FIELD_NUMBER: builtins.int
ROLE_FIELD_NUMBER: builtins.int
PUBLIC_KEY_FIELD_NUMBER: builtins.int
IS_UNMESSAGABLE_FIELD_NUMBER: builtins.int
macaddr: builtins.bytes
"""
This is the addr of the radio.
@@ -115,10 +114,6 @@ class UserLite(google.protobuf.message.Message):
The public key of the user's device.
This is sent out to other nodes on the mesh to allow them to compute a shared secret key.
"""
is_unmessagable: builtins.bool
"""
Whether or not the node can be messaged
"""
def __init__(
self,
*,
@@ -129,11 +124,8 @@ class UserLite(google.protobuf.message.Message):
is_licensed: builtins.bool = ...,
role: meshtastic.protobuf.config_pb2.Config.DeviceConfig.Role.ValueType = ...,
public_key: builtins.bytes = ...,
is_unmessagable: builtins.bool | None = ...,
) -> None: ...
def HasField(self, field_name: typing.Literal["_is_unmessagable", b"_is_unmessagable", "is_unmessagable", b"is_unmessagable"]) -> builtins.bool: ...
def ClearField(self, field_name: typing.Literal["_is_unmessagable", b"_is_unmessagable", "hw_model", b"hw_model", "is_licensed", b"is_licensed", "is_unmessagable", b"is_unmessagable", "long_name", b"long_name", "macaddr", b"macaddr", "public_key", b"public_key", "role", b"role", "short_name", b"short_name"]) -> None: ...
def WhichOneof(self, oneof_group: typing.Literal["_is_unmessagable", b"_is_unmessagable"]) -> typing.Literal["is_unmessagable"] | None: ...
def ClearField(self, field_name: typing.Literal["hw_model", b"hw_model", "is_licensed", b"is_licensed", "long_name", b"long_name", "macaddr", b"macaddr", "public_key", b"public_key", "role", b"role", "short_name", b"short_name"]) -> None: ...
global___UserLite = UserLite
@@ -153,7 +145,6 @@ class NodeInfoLite(google.protobuf.message.Message):
IS_FAVORITE_FIELD_NUMBER: builtins.int
IS_IGNORED_FIELD_NUMBER: builtins.int
NEXT_HOP_FIELD_NUMBER: builtins.int
BITFIELD_FIELD_NUMBER: builtins.int
num: builtins.int
"""
The node number
@@ -193,11 +184,6 @@ class NodeInfoLite(google.protobuf.message.Message):
"""
Last byte of the node number of the node that should be used as the next hop to reach this node.
"""
bitfield: builtins.int
"""
Bitfield for storing booleans.
LSB 0 is_key_manually_verified
"""
@property
def user(self) -> global___UserLite:
"""
@@ -232,10 +218,9 @@ class NodeInfoLite(google.protobuf.message.Message):
is_favorite: builtins.bool = ...,
is_ignored: builtins.bool = ...,
next_hop: builtins.int = ...,
bitfield: builtins.int = ...,
) -> None: ...
def HasField(self, field_name: typing.Literal["_hops_away", b"_hops_away", "device_metrics", b"device_metrics", "hops_away", b"hops_away", "position", b"position", "user", b"user"]) -> builtins.bool: ...
def ClearField(self, field_name: typing.Literal["_hops_away", b"_hops_away", "bitfield", b"bitfield", "channel", b"channel", "device_metrics", b"device_metrics", "hops_away", b"hops_away", "is_favorite", b"is_favorite", "is_ignored", b"is_ignored", "last_heard", b"last_heard", "next_hop", b"next_hop", "num", b"num", "position", b"position", "snr", b"snr", "user", b"user", "via_mqtt", b"via_mqtt"]) -> None: ...
def ClearField(self, field_name: typing.Literal["_hops_away", b"_hops_away", "channel", b"channel", "device_metrics", b"device_metrics", "hops_away", b"hops_away", "is_favorite", b"is_favorite", "is_ignored", b"is_ignored", "last_heard", b"last_heard", "next_hop", b"next_hop", "num", b"num", "position", b"position", "snr", b"snr", "user", b"user", "via_mqtt", b"via_mqtt"]) -> None: ...
def WhichOneof(self, oneof_group: typing.Literal["_hops_away", b"_hops_away"]) -> typing.Literal["hops_away"] | None: ...
global___NodeInfoLite = NodeInfoLite

View File

@@ -1,30 +0,0 @@
# -*- coding: utf-8 -*-
# Generated by the protocol buffer compiler. DO NOT EDIT!
# source: meshtastic/protobuf/interdevice.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 symbol_database as _symbol_database
from google.protobuf.internal import builder as _builder
# @@protoc_insertion_point(imports)
_sym_db = _symbol_database.Default()
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n%meshtastic/protobuf/interdevice.proto\x12\x13meshtastic.protobuf\"s\n\nSensorData\x12.\n\x04type\x18\x01 \x01(\x0e\x32 .meshtastic.protobuf.MessageType\x12\x15\n\x0b\x66loat_value\x18\x02 \x01(\x02H\x00\x12\x16\n\x0cuint32_value\x18\x03 \x01(\rH\x00\x42\x06\n\x04\x64\x61ta\"_\n\x12InterdeviceMessage\x12\x0e\n\x04nmea\x18\x01 \x01(\tH\x00\x12\x31\n\x06sensor\x18\x02 \x01(\x0b\x32\x1f.meshtastic.protobuf.SensorDataH\x00\x42\x06\n\x04\x64\x61ta*\xd5\x01\n\x0bMessageType\x12\x07\n\x03\x41\x43K\x10\x00\x12\x15\n\x10\x43OLLECT_INTERVAL\x10\xa0\x01\x12\x0c\n\x07\x42\x45\x45P_ON\x10\xa1\x01\x12\r\n\x08\x42\x45\x45P_OFF\x10\xa2\x01\x12\r\n\x08SHUTDOWN\x10\xa3\x01\x12\r\n\x08POWER_ON\x10\xa4\x01\x12\x0f\n\nSCD41_TEMP\x10\xb0\x01\x12\x13\n\x0eSCD41_HUMIDITY\x10\xb1\x01\x12\x0e\n\tSCD41_CO2\x10\xb2\x01\x12\x0f\n\nAHT20_TEMP\x10\xb3\x01\x12\x13\n\x0e\x41HT20_HUMIDITY\x10\xb4\x01\x12\x0f\n\nTVOC_INDEX\x10\xb5\x01\x42g\n\x14org.meshtastic.protoB\x11InterdeviceProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3')
_globals = globals()
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.protobuf.interdevice_pb2', _globals)
if _descriptor._USE_C_DESCRIPTORS == False:
DESCRIPTOR._options = None
DESCRIPTOR._serialized_options = b'\n\024org.meshtastic.protoB\021InterdeviceProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000'
_globals['_MESSAGETYPE']._serialized_start=277
_globals['_MESSAGETYPE']._serialized_end=490
_globals['_SENSORDATA']._serialized_start=62
_globals['_SENSORDATA']._serialized_end=177
_globals['_INTERDEVICEMESSAGE']._serialized_start=179
_globals['_INTERDEVICEMESSAGE']._serialized_end=274
# @@protoc_insertion_point(module_scope)

View File

@@ -1,105 +0,0 @@
"""
@generated by mypy-protobuf. Do not edit manually!
isort:skip_file
"""
import builtins
import google.protobuf.descriptor
import google.protobuf.internal.enum_type_wrapper
import google.protobuf.message
import sys
import typing
if sys.version_info >= (3, 10):
import typing as typing_extensions
else:
import typing_extensions
DESCRIPTOR: google.protobuf.descriptor.FileDescriptor
class _MessageType:
ValueType = typing.NewType("ValueType", builtins.int)
V: typing_extensions.TypeAlias = ValueType
class _MessageTypeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_MessageType.ValueType], builtins.type):
DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor
ACK: _MessageType.ValueType # 0
COLLECT_INTERVAL: _MessageType.ValueType # 160
"""in ms"""
BEEP_ON: _MessageType.ValueType # 161
"""duration ms"""
BEEP_OFF: _MessageType.ValueType # 162
"""cancel prematurely"""
SHUTDOWN: _MessageType.ValueType # 163
POWER_ON: _MessageType.ValueType # 164
SCD41_TEMP: _MessageType.ValueType # 176
SCD41_HUMIDITY: _MessageType.ValueType # 177
SCD41_CO2: _MessageType.ValueType # 178
AHT20_TEMP: _MessageType.ValueType # 179
AHT20_HUMIDITY: _MessageType.ValueType # 180
TVOC_INDEX: _MessageType.ValueType # 181
class MessageType(_MessageType, metaclass=_MessageTypeEnumTypeWrapper):
"""encapsulate up to 1k of NMEA string data"""
ACK: MessageType.ValueType # 0
COLLECT_INTERVAL: MessageType.ValueType # 160
"""in ms"""
BEEP_ON: MessageType.ValueType # 161
"""duration ms"""
BEEP_OFF: MessageType.ValueType # 162
"""cancel prematurely"""
SHUTDOWN: MessageType.ValueType # 163
POWER_ON: MessageType.ValueType # 164
SCD41_TEMP: MessageType.ValueType # 176
SCD41_HUMIDITY: MessageType.ValueType # 177
SCD41_CO2: MessageType.ValueType # 178
AHT20_TEMP: MessageType.ValueType # 179
AHT20_HUMIDITY: MessageType.ValueType # 180
TVOC_INDEX: MessageType.ValueType # 181
global___MessageType = MessageType
@typing.final
class SensorData(google.protobuf.message.Message):
DESCRIPTOR: google.protobuf.descriptor.Descriptor
TYPE_FIELD_NUMBER: builtins.int
FLOAT_VALUE_FIELD_NUMBER: builtins.int
UINT32_VALUE_FIELD_NUMBER: builtins.int
type: global___MessageType.ValueType
"""The message type"""
float_value: builtins.float
uint32_value: builtins.int
def __init__(
self,
*,
type: global___MessageType.ValueType = ...,
float_value: builtins.float = ...,
uint32_value: builtins.int = ...,
) -> None: ...
def HasField(self, field_name: typing.Literal["data", b"data", "float_value", b"float_value", "uint32_value", b"uint32_value"]) -> builtins.bool: ...
def ClearField(self, field_name: typing.Literal["data", b"data", "float_value", b"float_value", "type", b"type", "uint32_value", b"uint32_value"]) -> None: ...
def WhichOneof(self, oneof_group: typing.Literal["data", b"data"]) -> typing.Literal["float_value", "uint32_value"] | None: ...
global___SensorData = SensorData
@typing.final
class InterdeviceMessage(google.protobuf.message.Message):
DESCRIPTOR: google.protobuf.descriptor.Descriptor
NMEA_FIELD_NUMBER: builtins.int
SENSOR_FIELD_NUMBER: builtins.int
nmea: builtins.str
@property
def sensor(self) -> global___SensorData: ...
def __init__(
self,
*,
nmea: builtins.str = ...,
sensor: global___SensorData | None = ...,
) -> None: ...
def HasField(self, field_name: typing.Literal["data", b"data", "nmea", b"nmea", "sensor", b"sensor"]) -> builtins.bool: ...
def ClearField(self, field_name: typing.Literal["data", b"data", "nmea", b"nmea", "sensor", b"sensor"]) -> None: ...
def WhichOneof(self, oneof_group: typing.Literal["data", b"data"]) -> typing.Literal["nmea", "sensor"] | None: ...
global___InterdeviceMessage = InterdeviceMessage

View File

@@ -15,14 +15,14 @@ from meshtastic.protobuf import config_pb2 as meshtastic_dot_protobuf_dot_config
from meshtastic.protobuf import module_config_pb2 as meshtastic_dot_protobuf_dot_module__config__pb2
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n#meshtastic/protobuf/localonly.proto\x12\x13meshtastic.protobuf\x1a meshtastic/protobuf/config.proto\x1a\'meshtastic/protobuf/module_config.proto\"\xfa\x03\n\x0bLocalConfig\x12\x38\n\x06\x64\x65vice\x18\x01 \x01(\x0b\x32(.meshtastic.protobuf.Config.DeviceConfig\x12<\n\x08position\x18\x02 \x01(\x0b\x32*.meshtastic.protobuf.Config.PositionConfig\x12\x36\n\x05power\x18\x03 \x01(\x0b\x32\'.meshtastic.protobuf.Config.PowerConfig\x12:\n\x07network\x18\x04 \x01(\x0b\x32).meshtastic.protobuf.Config.NetworkConfig\x12:\n\x07\x64isplay\x18\x05 \x01(\x0b\x32).meshtastic.protobuf.Config.DisplayConfig\x12\x34\n\x04lora\x18\x06 \x01(\x0b\x32&.meshtastic.protobuf.Config.LoRaConfig\x12>\n\tbluetooth\x18\x07 \x01(\x0b\x32+.meshtastic.protobuf.Config.BluetoothConfig\x12\x0f\n\x07version\x18\x08 \x01(\r\x12<\n\x08security\x18\t \x01(\x0b\x32*.meshtastic.protobuf.Config.SecurityConfig\"\xf0\x07\n\x11LocalModuleConfig\x12:\n\x04mqtt\x18\x01 \x01(\x0b\x32,.meshtastic.protobuf.ModuleConfig.MQTTConfig\x12>\n\x06serial\x18\x02 \x01(\x0b\x32..meshtastic.protobuf.ModuleConfig.SerialConfig\x12[\n\x15\x65xternal_notification\x18\x03 \x01(\x0b\x32<.meshtastic.protobuf.ModuleConfig.ExternalNotificationConfig\x12K\n\rstore_forward\x18\x04 \x01(\x0b\x32\x34.meshtastic.protobuf.ModuleConfig.StoreForwardConfig\x12\x45\n\nrange_test\x18\x05 \x01(\x0b\x32\x31.meshtastic.protobuf.ModuleConfig.RangeTestConfig\x12\x44\n\ttelemetry\x18\x06 \x01(\x0b\x32\x31.meshtastic.protobuf.ModuleConfig.TelemetryConfig\x12M\n\x0e\x63\x61nned_message\x18\x07 \x01(\x0b\x32\x35.meshtastic.protobuf.ModuleConfig.CannedMessageConfig\x12<\n\x05\x61udio\x18\t \x01(\x0b\x32-.meshtastic.protobuf.ModuleConfig.AudioConfig\x12O\n\x0fremote_hardware\x18\n \x01(\x0b\x32\x36.meshtastic.protobuf.ModuleConfig.RemoteHardwareConfig\x12K\n\rneighbor_info\x18\x0b \x01(\x0b\x32\x34.meshtastic.protobuf.ModuleConfig.NeighborInfoConfig\x12Q\n\x10\x61mbient_lighting\x18\x0c \x01(\x0b\x32\x37.meshtastic.protobuf.ModuleConfig.AmbientLightingConfig\x12Q\n\x10\x64\x65tection_sensor\x18\r \x01(\x0b\x32\x37.meshtastic.protobuf.ModuleConfig.DetectionSensorConfig\x12\x46\n\npaxcounter\x18\x0e \x01(\x0b\x32\x32.meshtastic.protobuf.ModuleConfig.PaxcounterConfig\x12\x0f\n\x07version\x18\x08 \x01(\rBe\n\x14org.meshtastic.protoB\x0fLocalOnlyProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3')
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n#meshtastic/protobuf/localonly.proto\x12\x13meshtastic.protobuf\x1a meshtastic/protobuf/config.proto\x1a\'meshtastic/protobuf/module_config.proto\"\xfa\x03\n\x0bLocalConfig\x12\x38\n\x06\x64\x65vice\x18\x01 \x01(\x0b\x32(.meshtastic.protobuf.Config.DeviceConfig\x12<\n\x08position\x18\x02 \x01(\x0b\x32*.meshtastic.protobuf.Config.PositionConfig\x12\x36\n\x05power\x18\x03 \x01(\x0b\x32\'.meshtastic.protobuf.Config.PowerConfig\x12:\n\x07network\x18\x04 \x01(\x0b\x32).meshtastic.protobuf.Config.NetworkConfig\x12:\n\x07\x64isplay\x18\x05 \x01(\x0b\x32).meshtastic.protobuf.Config.DisplayConfig\x12\x34\n\x04lora\x18\x06 \x01(\x0b\x32&.meshtastic.protobuf.Config.LoRaConfig\x12>\n\tbluetooth\x18\x07 \x01(\x0b\x32+.meshtastic.protobuf.Config.BluetoothConfig\x12\x0f\n\x07version\x18\x08 \x01(\r\x12<\n\x08security\x18\t \x01(\x0b\x32*.meshtastic.protobuf.Config.SecurityConfig\"\xf0\x07\n\x11LocalModuleConfig\x12:\n\x04mqtt\x18\x01 \x01(\x0b\x32,.meshtastic.protobuf.ModuleConfig.MQTTConfig\x12>\n\x06serial\x18\x02 \x01(\x0b\x32..meshtastic.protobuf.ModuleConfig.SerialConfig\x12[\n\x15\x65xternal_notification\x18\x03 \x01(\x0b\x32<.meshtastic.protobuf.ModuleConfig.ExternalNotificationConfig\x12K\n\rstore_forward\x18\x04 \x01(\x0b\x32\x34.meshtastic.protobuf.ModuleConfig.StoreForwardConfig\x12\x45\n\nrange_test\x18\x05 \x01(\x0b\x32\x31.meshtastic.protobuf.ModuleConfig.RangeTestConfig\x12\x44\n\ttelemetry\x18\x06 \x01(\x0b\x32\x31.meshtastic.protobuf.ModuleConfig.TelemetryConfig\x12M\n\x0e\x63\x61nned_message\x18\x07 \x01(\x0b\x32\x35.meshtastic.protobuf.ModuleConfig.CannedMessageConfig\x12<\n\x05\x61udio\x18\t \x01(\x0b\x32-.meshtastic.protobuf.ModuleConfig.AudioConfig\x12O\n\x0fremote_hardware\x18\n \x01(\x0b\x32\x36.meshtastic.protobuf.ModuleConfig.RemoteHardwareConfig\x12K\n\rneighbor_info\x18\x0b \x01(\x0b\x32\x34.meshtastic.protobuf.ModuleConfig.NeighborInfoConfig\x12Q\n\x10\x61mbient_lighting\x18\x0c \x01(\x0b\x32\x37.meshtastic.protobuf.ModuleConfig.AmbientLightingConfig\x12Q\n\x10\x64\x65tection_sensor\x18\r \x01(\x0b\x32\x37.meshtastic.protobuf.ModuleConfig.DetectionSensorConfig\x12\x46\n\npaxcounter\x18\x0e \x01(\x0b\x32\x32.meshtastic.protobuf.ModuleConfig.PaxcounterConfig\x12\x0f\n\x07version\x18\x08 \x01(\rBd\n\x13\x63om.geeksville.meshB\x0fLocalOnlyProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3')
_globals = globals()
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.protobuf.localonly_pb2', _globals)
if _descriptor._USE_C_DESCRIPTORS == False:
DESCRIPTOR._options = None
DESCRIPTOR._serialized_options = b'\n\024org.meshtastic.protoB\017LocalOnlyProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000'
DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\017LocalOnlyProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000'
_globals['_LOCALCONFIG']._serialized_start=136
_globals['_LOCALCONFIG']._serialized_end=642
_globals['_LOCALMODULECONFIG']._serialized_start=645

View File

File diff suppressed because one or more lines are too long

View File

@@ -295,7 +295,7 @@ class _HardwareModelEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._
"""
TWC_MESH_V4: _HardwareModel.ValueType # 62
"""
TWC_MESH_V4
TWC_MESH_V4
Adafruit NRF52840 feather express with SX1262, SSD1306 OLED and NEO6M GPS
"""
NRF52_PROMICRO_DIY: _HardwareModel.ValueType # 63
@@ -402,127 +402,6 @@ class _HardwareModelEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._
MeshLink board developed by LoraItalia. NRF52840, eByte E22900M22S (Will also come with other frequencies), 25w MPPT solar charger (5v,12v,18v selectable), support for gps, buzzer, oled or e-ink display, 10 gpios, hardware watchdog
https://www.loraitalia.it
"""
XIAO_NRF52_KIT: _HardwareModel.ValueType # 88
"""
Seeed XIAO nRF52840 + Wio SX1262 kit
"""
THINKNODE_M1: _HardwareModel.ValueType # 89
"""
Elecrow ThinkNode M1 & M2
https://www.elecrow.com/wiki/ThinkNode-M1_Transceiver_Device(Meshtastic)_Power_By_nRF52840.html
https://www.elecrow.com/wiki/ThinkNode-M2_Transceiver_Device(Meshtastic)_Power_By_NRF52840.html (this actually uses ESP32-S3)
"""
THINKNODE_M2: _HardwareModel.ValueType # 90
T_ETH_ELITE: _HardwareModel.ValueType # 91
"""
Lilygo T-ETH-Elite
"""
HELTEC_SENSOR_HUB: _HardwareModel.ValueType # 92
"""
Heltec HRI-3621 industrial probe
"""
RESERVED_FRIED_CHICKEN: _HardwareModel.ValueType # 93
"""
Reserved Fried Chicken ID for future use
"""
HELTEC_MESH_POCKET: _HardwareModel.ValueType # 94
"""
Heltec Magnetic Power Bank with Meshtastic compatible
"""
SEEED_SOLAR_NODE: _HardwareModel.ValueType # 95
"""
Seeed Solar Node
"""
NOMADSTAR_METEOR_PRO: _HardwareModel.ValueType # 96
"""
NomadStar Meteor Pro https://nomadstar.ch/
"""
CROWPANEL: _HardwareModel.ValueType # 97
"""
Elecrow CrowPanel Advance models, ESP32-S3 and TFT with SX1262 radio plugin
"""
LINK_32: _HardwareModel.ValueType # 98
"""
Lilygo LINK32 board with sensors
"""
SEEED_WIO_TRACKER_L1: _HardwareModel.ValueType # 99
"""
Seeed Tracker L1
"""
SEEED_WIO_TRACKER_L1_EINK: _HardwareModel.ValueType # 100
"""
Seeed Tracker L1 EINK driver
"""
MUZI_R1_NEO: _HardwareModel.ValueType # 101
"""
Muzi Works R1 Neo
"""
T_DECK_PRO: _HardwareModel.ValueType # 102
"""
Lilygo T-Deck Pro
"""
T_LORA_PAGER: _HardwareModel.ValueType # 103
"""
Lilygo TLora Pager
"""
M5STACK_RESERVED: _HardwareModel.ValueType # 104
"""
M5Stack Reserved
0x68
"""
WISMESH_TAG: _HardwareModel.ValueType # 105
"""
RAKwireless WisMesh Tag
"""
RAK3312: _HardwareModel.ValueType # 106
"""
RAKwireless WisBlock Core RAK3312 https://docs.rakwireless.com/product-categories/wisduo/rak3112-module/overview/
"""
THINKNODE_M5: _HardwareModel.ValueType # 107
"""
Elecrow ThinkNode M5 https://www.elecrow.com/wiki/ThinkNode_M5_Meshtastic_LoRa_Signal_Transceiver_ESP32-S3.html
"""
HELTEC_MESH_SOLAR: _HardwareModel.ValueType # 108
"""
MeshSolar is an integrated power management and communication solution designed for outdoor low-power devices.
https://heltec.org/project/meshsolar/
"""
T_ECHO_LITE: _HardwareModel.ValueType # 109
"""
Lilygo T-Echo Lite
"""
HELTEC_V4: _HardwareModel.ValueType # 110
"""
New Heltec LoRA32 with ESP32-S3 CPU
"""
M5STACK_C6L: _HardwareModel.ValueType # 111
"""
M5Stack C6L
"""
M5STACK_CARDPUTER_ADV: _HardwareModel.ValueType # 112
"""
M5Stack Cardputer Adv
"""
HELTEC_WIRELESS_TRACKER_V2: _HardwareModel.ValueType # 113
"""
ESP32S3 main controller with GPS and TFT screen.
"""
T_WATCH_ULTRA: _HardwareModel.ValueType # 114
"""
LilyGo T-Watch Ultra
"""
THINKNODE_M3: _HardwareModel.ValueType # 115
"""
Elecrow ThinkNode M3
"""
WISMESH_TAP_V2: _HardwareModel.ValueType # 116
"""
RAK WISMESH_TAP_V2 with ESP32-S3 CPU
"""
RAK3401: _HardwareModel.ValueType # 117
"""
RAK3401
"""
PRIVATE_HW: _HardwareModel.ValueType # 255
"""
------------------------------------------------------------------------------------------------------------------------------------------
@@ -801,7 +680,7 @@ CDEBYTE EoRa-S3 board using their own MM modules, clone of LILYGO T3S3
"""
TWC_MESH_V4: HardwareModel.ValueType # 62
"""
TWC_MESH_V4
TWC_MESH_V4
Adafruit NRF52840 feather express with SX1262, SSD1306 OLED and NEO6M GPS
"""
NRF52_PROMICRO_DIY: HardwareModel.ValueType # 63
@@ -908,127 +787,6 @@ MESHLINK: HardwareModel.ValueType # 87
MeshLink board developed by LoraItalia. NRF52840, eByte E22900M22S (Will also come with other frequencies), 25w MPPT solar charger (5v,12v,18v selectable), support for gps, buzzer, oled or e-ink display, 10 gpios, hardware watchdog
https://www.loraitalia.it
"""
XIAO_NRF52_KIT: HardwareModel.ValueType # 88
"""
Seeed XIAO nRF52840 + Wio SX1262 kit
"""
THINKNODE_M1: HardwareModel.ValueType # 89
"""
Elecrow ThinkNode M1 & M2
https://www.elecrow.com/wiki/ThinkNode-M1_Transceiver_Device(Meshtastic)_Power_By_nRF52840.html
https://www.elecrow.com/wiki/ThinkNode-M2_Transceiver_Device(Meshtastic)_Power_By_NRF52840.html (this actually uses ESP32-S3)
"""
THINKNODE_M2: HardwareModel.ValueType # 90
T_ETH_ELITE: HardwareModel.ValueType # 91
"""
Lilygo T-ETH-Elite
"""
HELTEC_SENSOR_HUB: HardwareModel.ValueType # 92
"""
Heltec HRI-3621 industrial probe
"""
RESERVED_FRIED_CHICKEN: HardwareModel.ValueType # 93
"""
Reserved Fried Chicken ID for future use
"""
HELTEC_MESH_POCKET: HardwareModel.ValueType # 94
"""
Heltec Magnetic Power Bank with Meshtastic compatible
"""
SEEED_SOLAR_NODE: HardwareModel.ValueType # 95
"""
Seeed Solar Node
"""
NOMADSTAR_METEOR_PRO: HardwareModel.ValueType # 96
"""
NomadStar Meteor Pro https://nomadstar.ch/
"""
CROWPANEL: HardwareModel.ValueType # 97
"""
Elecrow CrowPanel Advance models, ESP32-S3 and TFT with SX1262 radio plugin
"""
LINK_32: HardwareModel.ValueType # 98
"""
Lilygo LINK32 board with sensors
"""
SEEED_WIO_TRACKER_L1: HardwareModel.ValueType # 99
"""
Seeed Tracker L1
"""
SEEED_WIO_TRACKER_L1_EINK: HardwareModel.ValueType # 100
"""
Seeed Tracker L1 EINK driver
"""
MUZI_R1_NEO: HardwareModel.ValueType # 101
"""
Muzi Works R1 Neo
"""
T_DECK_PRO: HardwareModel.ValueType # 102
"""
Lilygo T-Deck Pro
"""
T_LORA_PAGER: HardwareModel.ValueType # 103
"""
Lilygo TLora Pager
"""
M5STACK_RESERVED: HardwareModel.ValueType # 104
"""
M5Stack Reserved
0x68
"""
WISMESH_TAG: HardwareModel.ValueType # 105
"""
RAKwireless WisMesh Tag
"""
RAK3312: HardwareModel.ValueType # 106
"""
RAKwireless WisBlock Core RAK3312 https://docs.rakwireless.com/product-categories/wisduo/rak3112-module/overview/
"""
THINKNODE_M5: HardwareModel.ValueType # 107
"""
Elecrow ThinkNode M5 https://www.elecrow.com/wiki/ThinkNode_M5_Meshtastic_LoRa_Signal_Transceiver_ESP32-S3.html
"""
HELTEC_MESH_SOLAR: HardwareModel.ValueType # 108
"""
MeshSolar is an integrated power management and communication solution designed for outdoor low-power devices.
https://heltec.org/project/meshsolar/
"""
T_ECHO_LITE: HardwareModel.ValueType # 109
"""
Lilygo T-Echo Lite
"""
HELTEC_V4: HardwareModel.ValueType # 110
"""
New Heltec LoRA32 with ESP32-S3 CPU
"""
M5STACK_C6L: HardwareModel.ValueType # 111
"""
M5Stack C6L
"""
M5STACK_CARDPUTER_ADV: HardwareModel.ValueType # 112
"""
M5Stack Cardputer Adv
"""
HELTEC_WIRELESS_TRACKER_V2: HardwareModel.ValueType # 113
"""
ESP32S3 main controller with GPS and TFT screen.
"""
T_WATCH_ULTRA: HardwareModel.ValueType # 114
"""
LilyGo T-Watch Ultra
"""
THINKNODE_M3: HardwareModel.ValueType # 115
"""
Elecrow ThinkNode M3
"""
WISMESH_TAP_V2: HardwareModel.ValueType # 116
"""
RAK WISMESH_TAP_V2 with ESP32-S3 CPU
"""
RAK3401: HardwareModel.ValueType # 117
"""
RAK3401
"""
PRIVATE_HW: HardwareModel.ValueType # 255
"""
------------------------------------------------------------------------------------------------------------------------------------------
@@ -1210,77 +968,6 @@ If you see this failure in the field please post in the forum because we are int
"""
global___CriticalErrorCode = CriticalErrorCode
class _FirmwareEdition:
ValueType = typing.NewType("ValueType", builtins.int)
V: typing_extensions.TypeAlias = ValueType
class _FirmwareEditionEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_FirmwareEdition.ValueType], builtins.type):
DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor
VANILLA: _FirmwareEdition.ValueType # 0
"""
Vanilla firmware
"""
SMART_CITIZEN: _FirmwareEdition.ValueType # 1
"""
Firmware for use in the Smart Citizen environmental monitoring network
"""
OPEN_SAUCE: _FirmwareEdition.ValueType # 16
"""
Open Sauce, the maker conference held yearly in CA
"""
DEFCON: _FirmwareEdition.ValueType # 17
"""
DEFCON, the yearly hacker conference
"""
BURNING_MAN: _FirmwareEdition.ValueType # 18
"""
Burning Man, the yearly hippie gathering in the desert
"""
HAMVENTION: _FirmwareEdition.ValueType # 19
"""
Hamvention, the Dayton amateur radio convention
"""
DIY_EDITION: _FirmwareEdition.ValueType # 127
"""
Placeholder for DIY and unofficial events
"""
class FirmwareEdition(_FirmwareEdition, metaclass=_FirmwareEditionEnumTypeWrapper):
"""
Enum to indicate to clients whether this firmware is a special firmware build, like an event.
The first 16 values are reserved for non-event special firmwares, like the Smart Citizen use case.
"""
VANILLA: FirmwareEdition.ValueType # 0
"""
Vanilla firmware
"""
SMART_CITIZEN: FirmwareEdition.ValueType # 1
"""
Firmware for use in the Smart Citizen environmental monitoring network
"""
OPEN_SAUCE: FirmwareEdition.ValueType # 16
"""
Open Sauce, the maker conference held yearly in CA
"""
DEFCON: FirmwareEdition.ValueType # 17
"""
DEFCON, the yearly hacker conference
"""
BURNING_MAN: FirmwareEdition.ValueType # 18
"""
Burning Man, the yearly hippie gathering in the desert
"""
HAMVENTION: FirmwareEdition.ValueType # 19
"""
Hamvention, the Dayton amateur radio convention
"""
DIY_EDITION: FirmwareEdition.ValueType # 127
"""
Placeholder for DIY and unofficial events
"""
global___FirmwareEdition = FirmwareEdition
class _ExcludedModules:
ValueType = typing.NewType("ValueType", builtins.int)
V: typing_extensions.TypeAlias = ValueType
@@ -1343,14 +1030,6 @@ class _ExcludedModulesEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper
"""
Paxcounter module
"""
BLUETOOTH_CONFIG: _ExcludedModules.ValueType # 8192
"""
Bluetooth config (not technically a module, but used to indicate bluetooth capabilities)
"""
NETWORK_CONFIG: _ExcludedModules.ValueType # 16384
"""
Network config (not technically a module, but used to indicate network capabilities)
"""
class ExcludedModules(_ExcludedModules, metaclass=_ExcludedModulesEnumTypeWrapper):
"""
@@ -1415,14 +1094,6 @@ PAXCOUNTER_CONFIG: ExcludedModules.ValueType # 4096
"""
Paxcounter module
"""
BLUETOOTH_CONFIG: ExcludedModules.ValueType # 8192
"""
Bluetooth config (not technically a module, but used to indicate bluetooth capabilities)
"""
NETWORK_CONFIG: ExcludedModules.ValueType # 16384
"""
Network config (not technically a module, but used to indicate network capabilities)
"""
global___ExcludedModules = ExcludedModules
@typing.final
@@ -1747,7 +1418,6 @@ class User(google.protobuf.message.Message):
IS_LICENSED_FIELD_NUMBER: builtins.int
ROLE_FIELD_NUMBER: builtins.int
PUBLIC_KEY_FIELD_NUMBER: builtins.int
IS_UNMESSAGABLE_FIELD_NUMBER: builtins.int
id: builtins.str
"""
A globally unique ID string for this user.
@@ -1792,10 +1462,6 @@ class User(google.protobuf.message.Message):
The public key of the user's device.
This is sent out to other nodes on the mesh to allow them to compute a shared secret key.
"""
is_unmessagable: builtins.bool
"""
Whether or not the node can be messaged
"""
def __init__(
self,
*,
@@ -1807,11 +1473,8 @@ class User(google.protobuf.message.Message):
is_licensed: builtins.bool = ...,
role: meshtastic.protobuf.config_pb2.Config.DeviceConfig.Role.ValueType = ...,
public_key: builtins.bytes = ...,
is_unmessagable: builtins.bool | None = ...,
) -> None: ...
def HasField(self, field_name: typing.Literal["_is_unmessagable", b"_is_unmessagable", "is_unmessagable", b"is_unmessagable"]) -> builtins.bool: ...
def ClearField(self, field_name: typing.Literal["_is_unmessagable", b"_is_unmessagable", "hw_model", b"hw_model", "id", b"id", "is_licensed", b"is_licensed", "is_unmessagable", b"is_unmessagable", "long_name", b"long_name", "macaddr", b"macaddr", "public_key", b"public_key", "role", b"role", "short_name", b"short_name"]) -> None: ...
def WhichOneof(self, oneof_group: typing.Literal["_is_unmessagable", b"_is_unmessagable"]) -> typing.Literal["is_unmessagable"] | None: ...
def ClearField(self, field_name: typing.Literal["hw_model", b"hw_model", "id", b"id", "is_licensed", b"is_licensed", "long_name", b"long_name", "macaddr", b"macaddr", "public_key", b"public_key", "role", b"role", "short_name", b"short_name"]) -> None: ...
global___User = User
@@ -1943,11 +1606,6 @@ class Routing(google.protobuf.message.Message):
"""
Admin packet sent using PKC, but not from a public key on the admin key list
"""
RATE_LIMIT_EXCEEDED: Routing._Error.ValueType # 38
"""
Airtime fairness rate limit exceeded for a packet
This typically enforced per portnum and is used to prevent a single node from monopolizing airtime
"""
class Error(_Error, metaclass=_ErrorEnumTypeWrapper):
"""
@@ -2021,11 +1679,6 @@ class Routing(google.protobuf.message.Message):
"""
Admin packet sent using PKC, but not from a public key on the admin key list
"""
RATE_LIMIT_EXCEEDED: Routing.Error.ValueType # 38
"""
Airtime fairness rate limit exceeded for a packet
This typically enforced per portnum and is used to prevent a single node from monopolizing airtime
"""
ROUTE_REQUEST_FIELD_NUMBER: builtins.int
ROUTE_REPLY_FIELD_NUMBER: builtins.int
@@ -2144,41 +1797,6 @@ class Data(google.protobuf.message.Message):
global___Data = Data
@typing.final
class KeyVerification(google.protobuf.message.Message):
"""
The actual over-the-mesh message doing KeyVerification
"""
DESCRIPTOR: google.protobuf.descriptor.Descriptor
NONCE_FIELD_NUMBER: builtins.int
HASH1_FIELD_NUMBER: builtins.int
HASH2_FIELD_NUMBER: builtins.int
nonce: builtins.int
"""
random value Selected by the requesting node
"""
hash1: builtins.bytes
"""
The final authoritative hash, only to be sent by NodeA at the end of the handshake
"""
hash2: builtins.bytes
"""
The intermediary hash (actually derived from hash1),
sent from NodeB to NodeA in response to the initial message.
"""
def __init__(
self,
*,
nonce: builtins.int = ...,
hash1: builtins.bytes = ...,
hash2: builtins.bytes = ...,
) -> None: ...
def ClearField(self, field_name: typing.Literal["hash1", b"hash1", "hash2", b"hash2", "nonce", b"nonce"]) -> None: ...
global___KeyVerification = KeyVerification
@typing.final
class Waypoint(google.protobuf.message.Message):
"""
@@ -2456,83 +2074,6 @@ class MeshPacket(google.protobuf.message.Message):
The message is delayed and was originally a direct message
"""
class _TransportMechanism:
ValueType = typing.NewType("ValueType", builtins.int)
V: typing_extensions.TypeAlias = ValueType
class _TransportMechanismEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[MeshPacket._TransportMechanism.ValueType], builtins.type):
DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor
TRANSPORT_INTERNAL: MeshPacket._TransportMechanism.ValueType # 0
"""
The default case is that the node generated a packet itself
"""
TRANSPORT_LORA: MeshPacket._TransportMechanism.ValueType # 1
"""
Arrived via the primary LoRa radio
"""
TRANSPORT_LORA_ALT1: MeshPacket._TransportMechanism.ValueType # 2
"""
Arrived via a secondary LoRa radio
"""
TRANSPORT_LORA_ALT2: MeshPacket._TransportMechanism.ValueType # 3
"""
Arrived via a tertiary LoRa radio
"""
TRANSPORT_LORA_ALT3: MeshPacket._TransportMechanism.ValueType # 4
"""
Arrived via a quaternary LoRa radio
"""
TRANSPORT_MQTT: MeshPacket._TransportMechanism.ValueType # 5
"""
Arrived via an MQTT connection
"""
TRANSPORT_MULTICAST_UDP: MeshPacket._TransportMechanism.ValueType # 6
"""
Arrived via Multicast UDP
"""
TRANSPORT_API: MeshPacket._TransportMechanism.ValueType # 7
"""
Arrived via API connection
"""
class TransportMechanism(_TransportMechanism, metaclass=_TransportMechanismEnumTypeWrapper):
"""
Enum to identify which transport mechanism this packet arrived over
"""
TRANSPORT_INTERNAL: MeshPacket.TransportMechanism.ValueType # 0
"""
The default case is that the node generated a packet itself
"""
TRANSPORT_LORA: MeshPacket.TransportMechanism.ValueType # 1
"""
Arrived via the primary LoRa radio
"""
TRANSPORT_LORA_ALT1: MeshPacket.TransportMechanism.ValueType # 2
"""
Arrived via a secondary LoRa radio
"""
TRANSPORT_LORA_ALT2: MeshPacket.TransportMechanism.ValueType # 3
"""
Arrived via a tertiary LoRa radio
"""
TRANSPORT_LORA_ALT3: MeshPacket.TransportMechanism.ValueType # 4
"""
Arrived via a quaternary LoRa radio
"""
TRANSPORT_MQTT: MeshPacket.TransportMechanism.ValueType # 5
"""
Arrived via an MQTT connection
"""
TRANSPORT_MULTICAST_UDP: MeshPacket.TransportMechanism.ValueType # 6
"""
Arrived via Multicast UDP
"""
TRANSPORT_API: MeshPacket.TransportMechanism.ValueType # 7
"""
Arrived via API connection
"""
FROM_FIELD_NUMBER: builtins.int
TO_FIELD_NUMBER: builtins.int
CHANNEL_FIELD_NUMBER: builtins.int
@@ -2553,7 +2094,6 @@ class MeshPacket(google.protobuf.message.Message):
NEXT_HOP_FIELD_NUMBER: builtins.int
RELAY_NODE_FIELD_NUMBER: builtins.int
TX_AFTER_FIELD_NUMBER: builtins.int
TRANSPORT_MECHANISM_FIELD_NUMBER: builtins.int
to: builtins.int
"""
The (immediate) destination for this packet
@@ -2647,7 +2187,7 @@ class MeshPacket(google.protobuf.message.Message):
"""
next_hop: builtins.int
"""
Last byte of the node number of the node that should be used as the next hop in routing.
Last byte of the node number of the node that should be used as the next hop in routing.
Set by the firmware internally, clients are not supposed to set this.
"""
relay_node: builtins.int
@@ -2661,10 +2201,6 @@ class MeshPacket(google.protobuf.message.Message):
Timestamp after which this packet may be sent.
Set by the firmware internally, clients are not supposed to set this.
"""
transport_mechanism: global___MeshPacket.TransportMechanism.ValueType
"""
Indicates which transport mechanism this packet arrived over
"""
@property
def decoded(self) -> global___Data:
"""
@@ -2693,10 +2229,9 @@ class MeshPacket(google.protobuf.message.Message):
next_hop: builtins.int = ...,
relay_node: builtins.int = ...,
tx_after: builtins.int = ...,
transport_mechanism: global___MeshPacket.TransportMechanism.ValueType = ...,
) -> None: ...
def HasField(self, field_name: typing.Literal["decoded", b"decoded", "encrypted", b"encrypted", "payload_variant", b"payload_variant"]) -> builtins.bool: ...
def ClearField(self, field_name: typing.Literal["channel", b"channel", "decoded", b"decoded", "delayed", b"delayed", "encrypted", b"encrypted", "from", b"from", "hop_limit", b"hop_limit", "hop_start", b"hop_start", "id", b"id", "next_hop", b"next_hop", "payload_variant", b"payload_variant", "pki_encrypted", b"pki_encrypted", "priority", b"priority", "public_key", b"public_key", "relay_node", b"relay_node", "rx_rssi", b"rx_rssi", "rx_snr", b"rx_snr", "rx_time", b"rx_time", "to", b"to", "transport_mechanism", b"transport_mechanism", "tx_after", b"tx_after", "via_mqtt", b"via_mqtt", "want_ack", b"want_ack"]) -> None: ...
def ClearField(self, field_name: typing.Literal["channel", b"channel", "decoded", b"decoded", "delayed", b"delayed", "encrypted", b"encrypted", "from", b"from", "hop_limit", b"hop_limit", "hop_start", b"hop_start", "id", b"id", "next_hop", b"next_hop", "payload_variant", b"payload_variant", "pki_encrypted", b"pki_encrypted", "priority", b"priority", "public_key", b"public_key", "relay_node", b"relay_node", "rx_rssi", b"rx_rssi", "rx_snr", b"rx_snr", "rx_time", b"rx_time", "to", b"to", "tx_after", b"tx_after", "via_mqtt", b"via_mqtt", "want_ack", b"want_ack"]) -> None: ...
def WhichOneof(self, oneof_group: typing.Literal["payload_variant", b"payload_variant"]) -> typing.Literal["decoded", "encrypted"] | None: ...
global___MeshPacket = MeshPacket
@@ -2735,7 +2270,6 @@ class NodeInfo(google.protobuf.message.Message):
HOPS_AWAY_FIELD_NUMBER: builtins.int
IS_FAVORITE_FIELD_NUMBER: builtins.int
IS_IGNORED_FIELD_NUMBER: builtins.int
IS_KEY_MANUALLY_VERIFIED_FIELD_NUMBER: builtins.int
num: builtins.int
"""
The node number
@@ -2777,12 +2311,6 @@ class NodeInfo(google.protobuf.message.Message):
True if node is in our ignored list
Persists between NodeDB internal clean ups
"""
is_key_manually_verified: builtins.bool
"""
True if node public key has been verified.
Persists between NodeDB internal clean ups
LSB 0 of the bitfield
"""
@property
def user(self) -> global___User:
"""
@@ -2816,10 +2344,9 @@ class NodeInfo(google.protobuf.message.Message):
hops_away: builtins.int | None = ...,
is_favorite: builtins.bool = ...,
is_ignored: builtins.bool = ...,
is_key_manually_verified: builtins.bool = ...,
) -> None: ...
def HasField(self, field_name: typing.Literal["_hops_away", b"_hops_away", "device_metrics", b"device_metrics", "hops_away", b"hops_away", "position", b"position", "user", b"user"]) -> builtins.bool: ...
def ClearField(self, field_name: typing.Literal["_hops_away", b"_hops_away", "channel", b"channel", "device_metrics", b"device_metrics", "hops_away", b"hops_away", "is_favorite", b"is_favorite", "is_ignored", b"is_ignored", "is_key_manually_verified", b"is_key_manually_verified", "last_heard", b"last_heard", "num", b"num", "position", b"position", "snr", b"snr", "user", b"user", "via_mqtt", b"via_mqtt"]) -> None: ...
def ClearField(self, field_name: typing.Literal["_hops_away", b"_hops_away", "channel", b"channel", "device_metrics", b"device_metrics", "hops_away", b"hops_away", "is_favorite", b"is_favorite", "is_ignored", b"is_ignored", "last_heard", b"last_heard", "num", b"num", "position", b"position", "snr", b"snr", "user", b"user", "via_mqtt", b"via_mqtt"]) -> None: ...
def WhichOneof(self, oneof_group: typing.Literal["_hops_away", b"_hops_away"]) -> typing.Literal["hops_away"] | None: ...
global___NodeInfo = NodeInfo
@@ -2839,8 +2366,6 @@ class MyNodeInfo(google.protobuf.message.Message):
MIN_APP_VERSION_FIELD_NUMBER: builtins.int
DEVICE_ID_FIELD_NUMBER: builtins.int
PIO_ENV_FIELD_NUMBER: builtins.int
FIRMWARE_EDITION_FIELD_NUMBER: builtins.int
NODEDB_COUNT_FIELD_NUMBER: builtins.int
my_node_num: builtins.int
"""
Tells the phone what our node number is, default starting value is
@@ -2864,15 +2389,6 @@ class MyNodeInfo(google.protobuf.message.Message):
"""
The PlatformIO environment used to build this firmware
"""
firmware_edition: global___FirmwareEdition.ValueType
"""
The indicator for whether this device is running event firmware and which
"""
nodedb_count: builtins.int
"""
The number of nodes in the nodedb.
This is used by the phone to know how many NodeInfo packets to expect on want_config
"""
def __init__(
self,
*,
@@ -2881,10 +2397,8 @@ class MyNodeInfo(google.protobuf.message.Message):
min_app_version: builtins.int = ...,
device_id: builtins.bytes = ...,
pio_env: builtins.str = ...,
firmware_edition: global___FirmwareEdition.ValueType = ...,
nodedb_count: builtins.int = ...,
) -> None: ...
def ClearField(self, field_name: typing.Literal["device_id", b"device_id", "firmware_edition", b"firmware_edition", "min_app_version", b"min_app_version", "my_node_num", b"my_node_num", "nodedb_count", b"nodedb_count", "pio_env", b"pio_env", "reboot_count", b"reboot_count"]) -> None: ...
def ClearField(self, field_name: typing.Literal["device_id", b"device_id", "min_app_version", b"min_app_version", "my_node_num", b"my_node_num", "pio_env", b"pio_env", "reboot_count", b"reboot_count"]) -> None: ...
global___MyNodeInfo = MyNodeInfo
@@ -3204,11 +2718,6 @@ class ClientNotification(google.protobuf.message.Message):
TIME_FIELD_NUMBER: builtins.int
LEVEL_FIELD_NUMBER: builtins.int
MESSAGE_FIELD_NUMBER: builtins.int
KEY_VERIFICATION_NUMBER_INFORM_FIELD_NUMBER: builtins.int
KEY_VERIFICATION_NUMBER_REQUEST_FIELD_NUMBER: builtins.int
KEY_VERIFICATION_FINAL_FIELD_NUMBER: builtins.int
DUPLICATED_PUBLIC_KEY_FIELD_NUMBER: builtins.int
LOW_ENTROPY_KEY_FIELD_NUMBER: builtins.int
reply_id: builtins.int
"""
The id of the packet we're notifying in response to
@@ -3225,16 +2734,6 @@ class ClientNotification(google.protobuf.message.Message):
"""
The message body of the notification
"""
@property
def key_verification_number_inform(self) -> global___KeyVerificationNumberInform: ...
@property
def key_verification_number_request(self) -> global___KeyVerificationNumberRequest: ...
@property
def key_verification_final(self) -> global___KeyVerificationFinal: ...
@property
def duplicated_public_key(self) -> global___DuplicatedPublicKey: ...
@property
def low_entropy_key(self) -> global___LowEntropyKey: ...
def __init__(
self,
*,
@@ -3242,104 +2741,13 @@ class ClientNotification(google.protobuf.message.Message):
time: builtins.int = ...,
level: global___LogRecord.Level.ValueType = ...,
message: builtins.str = ...,
key_verification_number_inform: global___KeyVerificationNumberInform | None = ...,
key_verification_number_request: global___KeyVerificationNumberRequest | None = ...,
key_verification_final: global___KeyVerificationFinal | None = ...,
duplicated_public_key: global___DuplicatedPublicKey | None = ...,
low_entropy_key: global___LowEntropyKey | None = ...,
) -> None: ...
def HasField(self, field_name: typing.Literal["_reply_id", b"_reply_id", "duplicated_public_key", b"duplicated_public_key", "key_verification_final", b"key_verification_final", "key_verification_number_inform", b"key_verification_number_inform", "key_verification_number_request", b"key_verification_number_request", "low_entropy_key", b"low_entropy_key", "payload_variant", b"payload_variant", "reply_id", b"reply_id"]) -> builtins.bool: ...
def ClearField(self, field_name: typing.Literal["_reply_id", b"_reply_id", "duplicated_public_key", b"duplicated_public_key", "key_verification_final", b"key_verification_final", "key_verification_number_inform", b"key_verification_number_inform", "key_verification_number_request", b"key_verification_number_request", "level", b"level", "low_entropy_key", b"low_entropy_key", "message", b"message", "payload_variant", b"payload_variant", "reply_id", b"reply_id", "time", b"time"]) -> None: ...
@typing.overload
def HasField(self, field_name: typing.Literal["_reply_id", b"_reply_id", "reply_id", b"reply_id"]) -> builtins.bool: ...
def ClearField(self, field_name: typing.Literal["_reply_id", b"_reply_id", "level", b"level", "message", b"message", "reply_id", b"reply_id", "time", b"time"]) -> None: ...
def WhichOneof(self, oneof_group: typing.Literal["_reply_id", b"_reply_id"]) -> typing.Literal["reply_id"] | None: ...
@typing.overload
def WhichOneof(self, oneof_group: typing.Literal["payload_variant", b"payload_variant"]) -> typing.Literal["key_verification_number_inform", "key_verification_number_request", "key_verification_final", "duplicated_public_key", "low_entropy_key"] | None: ...
global___ClientNotification = ClientNotification
@typing.final
class KeyVerificationNumberInform(google.protobuf.message.Message):
DESCRIPTOR: google.protobuf.descriptor.Descriptor
NONCE_FIELD_NUMBER: builtins.int
REMOTE_LONGNAME_FIELD_NUMBER: builtins.int
SECURITY_NUMBER_FIELD_NUMBER: builtins.int
nonce: builtins.int
remote_longname: builtins.str
security_number: builtins.int
def __init__(
self,
*,
nonce: builtins.int = ...,
remote_longname: builtins.str = ...,
security_number: builtins.int = ...,
) -> None: ...
def ClearField(self, field_name: typing.Literal["nonce", b"nonce", "remote_longname", b"remote_longname", "security_number", b"security_number"]) -> None: ...
global___KeyVerificationNumberInform = KeyVerificationNumberInform
@typing.final
class KeyVerificationNumberRequest(google.protobuf.message.Message):
DESCRIPTOR: google.protobuf.descriptor.Descriptor
NONCE_FIELD_NUMBER: builtins.int
REMOTE_LONGNAME_FIELD_NUMBER: builtins.int
nonce: builtins.int
remote_longname: builtins.str
def __init__(
self,
*,
nonce: builtins.int = ...,
remote_longname: builtins.str = ...,
) -> None: ...
def ClearField(self, field_name: typing.Literal["nonce", b"nonce", "remote_longname", b"remote_longname"]) -> None: ...
global___KeyVerificationNumberRequest = KeyVerificationNumberRequest
@typing.final
class KeyVerificationFinal(google.protobuf.message.Message):
DESCRIPTOR: google.protobuf.descriptor.Descriptor
NONCE_FIELD_NUMBER: builtins.int
REMOTE_LONGNAME_FIELD_NUMBER: builtins.int
ISSENDER_FIELD_NUMBER: builtins.int
VERIFICATION_CHARACTERS_FIELD_NUMBER: builtins.int
nonce: builtins.int
remote_longname: builtins.str
isSender: builtins.bool
verification_characters: builtins.str
def __init__(
self,
*,
nonce: builtins.int = ...,
remote_longname: builtins.str = ...,
isSender: builtins.bool = ...,
verification_characters: builtins.str = ...,
) -> None: ...
def ClearField(self, field_name: typing.Literal["isSender", b"isSender", "nonce", b"nonce", "remote_longname", b"remote_longname", "verification_characters", b"verification_characters"]) -> None: ...
global___KeyVerificationFinal = KeyVerificationFinal
@typing.final
class DuplicatedPublicKey(google.protobuf.message.Message):
DESCRIPTOR: google.protobuf.descriptor.Descriptor
def __init__(
self,
) -> None: ...
global___DuplicatedPublicKey = DuplicatedPublicKey
@typing.final
class LowEntropyKey(google.protobuf.message.Message):
DESCRIPTOR: google.protobuf.descriptor.Descriptor
def __init__(
self,
) -> None: ...
global___LowEntropyKey = LowEntropyKey
@typing.final
class FileInfo(google.protobuf.message.Message):
"""
@@ -3650,17 +3058,9 @@ class Heartbeat(google.protobuf.message.Message):
DESCRIPTOR: google.protobuf.descriptor.Descriptor
NONCE_FIELD_NUMBER: builtins.int
nonce: builtins.int
"""
The nonce of the heartbeat message
"""
def __init__(
self,
*,
nonce: builtins.int = ...,
) -> None: ...
def ClearField(self, field_name: typing.Literal["nonce", b"nonce"]) -> None: ...
global___Heartbeat = Heartbeat

View File

File diff suppressed because one or more lines are too long

View File

@@ -165,7 +165,6 @@ class ModuleConfig(google.protobuf.message.Message):
PUBLISH_INTERVAL_SECS_FIELD_NUMBER: builtins.int
POSITION_PRECISION_FIELD_NUMBER: builtins.int
SHOULD_REPORT_LOCATION_FIELD_NUMBER: builtins.int
publish_interval_secs: builtins.int
"""
How often we should report our info to the map (in seconds)
@@ -174,18 +173,13 @@ class ModuleConfig(google.protobuf.message.Message):
"""
Bits of precision for the location sent (default of 32 is full precision).
"""
should_report_location: builtins.bool
"""
Whether we have opted-in to report our location to the map
"""
def __init__(
self,
*,
publish_interval_secs: builtins.int = ...,
position_precision: builtins.int = ...,
should_report_location: builtins.bool = ...,
) -> None: ...
def ClearField(self, field_name: typing.Literal["position_precision", b"position_precision", "publish_interval_secs", b"publish_interval_secs", "should_report_location", b"should_report_location"]) -> None: ...
def ClearField(self, field_name: typing.Literal["position_precision", b"position_precision", "publish_interval_secs", b"publish_interval_secs"]) -> None: ...
@typing.final
class RemoteHardwareConfig(google.protobuf.message.Message):
@@ -560,14 +554,6 @@ class ModuleConfig(google.protobuf.message.Message):
"""NMEA messages specifically tailored for CalTopo"""
WS85: ModuleConfig.SerialConfig._Serial_Mode.ValueType # 6
"""Ecowitt WS85 weather station"""
VE_DIRECT: ModuleConfig.SerialConfig._Serial_Mode.ValueType # 7
"""VE.Direct is a serial protocol used by Victron Energy products
https://beta.ivc.no/wiki/index.php/Victron_VE_Direct_DIY_Cable
"""
MS_CONFIG: ModuleConfig.SerialConfig._Serial_Mode.ValueType # 8
"""Used to configure and view some parameters of MeshSolar.
https://heltec.org/project/meshsolar/
"""
class Serial_Mode(_Serial_Mode, metaclass=_Serial_ModeEnumTypeWrapper):
"""
@@ -583,14 +569,6 @@ class ModuleConfig(google.protobuf.message.Message):
"""NMEA messages specifically tailored for CalTopo"""
WS85: ModuleConfig.SerialConfig.Serial_Mode.ValueType # 6
"""Ecowitt WS85 weather station"""
VE_DIRECT: ModuleConfig.SerialConfig.Serial_Mode.ValueType # 7
"""VE.Direct is a serial protocol used by Victron Energy products
https://beta.ivc.no/wiki/index.php/Victron_VE_Direct_DIY_Cable
"""
MS_CONFIG: ModuleConfig.SerialConfig.Serial_Mode.ValueType # 8
"""Used to configure and view some parameters of MeshSolar.
https://heltec.org/project/meshsolar/
"""
ENABLED_FIELD_NUMBER: builtins.int
ECHO_FIELD_NUMBER: builtins.int
@@ -824,7 +802,6 @@ class ModuleConfig(google.protobuf.message.Message):
ENABLED_FIELD_NUMBER: builtins.int
SENDER_FIELD_NUMBER: builtins.int
SAVE_FIELD_NUMBER: builtins.int
CLEAR_ON_REBOOT_FIELD_NUMBER: builtins.int
enabled: builtins.bool
"""
Enable the Range Test Module
@@ -838,20 +815,14 @@ class ModuleConfig(google.protobuf.message.Message):
Bool value indicating that this node should save a RangeTest.csv file.
ESP32 Only
"""
clear_on_reboot: builtins.bool
"""
Bool indicating that the node should cleanup / destroy it's RangeTest.csv file.
ESP32 Only
"""
def __init__(
self,
*,
enabled: builtins.bool = ...,
sender: builtins.int = ...,
save: builtins.bool = ...,
clear_on_reboot: builtins.bool = ...,
) -> None: ...
def ClearField(self, field_name: typing.Literal["clear_on_reboot", b"clear_on_reboot", "enabled", b"enabled", "save", b"save", "sender", b"sender"]) -> None: ...
def ClearField(self, field_name: typing.Literal["enabled", b"enabled", "save", b"save", "sender", b"sender"]) -> None: ...
@typing.final
class TelemetryConfig(google.protobuf.message.Message):
@@ -874,7 +845,6 @@ class ModuleConfig(google.protobuf.message.Message):
HEALTH_MEASUREMENT_ENABLED_FIELD_NUMBER: builtins.int
HEALTH_UPDATE_INTERVAL_FIELD_NUMBER: builtins.int
HEALTH_SCREEN_ENABLED_FIELD_NUMBER: builtins.int
DEVICE_TELEMETRY_ENABLED_FIELD_NUMBER: builtins.int
device_update_interval: builtins.int
"""
Interval in seconds of how often we should try to send our
@@ -935,11 +905,6 @@ class ModuleConfig(google.protobuf.message.Message):
"""
Enable/Disable the health telemetry module on-device display
"""
device_telemetry_enabled: builtins.bool
"""
Enable/Disable the device telemetry module to send metrics to the mesh
Note: We will still send telemtry to the connected phone / client every minute over the API
"""
def __init__(
self,
*,
@@ -956,9 +921,8 @@ class ModuleConfig(google.protobuf.message.Message):
health_measurement_enabled: builtins.bool = ...,
health_update_interval: builtins.int = ...,
health_screen_enabled: builtins.bool = ...,
device_telemetry_enabled: builtins.bool = ...,
) -> None: ...
def ClearField(self, field_name: typing.Literal["air_quality_enabled", b"air_quality_enabled", "air_quality_interval", b"air_quality_interval", "device_telemetry_enabled", b"device_telemetry_enabled", "device_update_interval", b"device_update_interval", "environment_display_fahrenheit", b"environment_display_fahrenheit", "environment_measurement_enabled", b"environment_measurement_enabled", "environment_screen_enabled", b"environment_screen_enabled", "environment_update_interval", b"environment_update_interval", "health_measurement_enabled", b"health_measurement_enabled", "health_screen_enabled", b"health_screen_enabled", "health_update_interval", b"health_update_interval", "power_measurement_enabled", b"power_measurement_enabled", "power_screen_enabled", b"power_screen_enabled", "power_update_interval", b"power_update_interval"]) -> None: ...
def ClearField(self, field_name: typing.Literal["air_quality_enabled", b"air_quality_enabled", "air_quality_interval", b"air_quality_interval", "device_update_interval", b"device_update_interval", "environment_display_fahrenheit", b"environment_display_fahrenheit", "environment_measurement_enabled", b"environment_measurement_enabled", "environment_screen_enabled", b"environment_screen_enabled", "environment_update_interval", b"environment_update_interval", "health_measurement_enabled", b"health_measurement_enabled", "health_screen_enabled", b"health_screen_enabled", "health_update_interval", b"health_update_interval", "power_measurement_enabled", b"power_measurement_enabled", "power_screen_enabled", b"power_screen_enabled", "power_update_interval", b"power_update_interval"]) -> None: ...
@typing.final
class CannedMessageConfig(google.protobuf.message.Message):

View File

@@ -15,16 +15,16 @@ from meshtastic.protobuf import config_pb2 as meshtastic_dot_protobuf_dot_config
from meshtastic.protobuf import mesh_pb2 as meshtastic_dot_protobuf_dot_mesh__pb2
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1emeshtastic/protobuf/mqtt.proto\x12\x13meshtastic.protobuf\x1a meshtastic/protobuf/config.proto\x1a\x1emeshtastic/protobuf/mesh.proto\"j\n\x0fServiceEnvelope\x12/\n\x06packet\x18\x01 \x01(\x0b\x32\x1f.meshtastic.protobuf.MeshPacket\x12\x12\n\nchannel_id\x18\x02 \x01(\t\x12\x12\n\ngateway_id\x18\x03 \x01(\t\"\x83\x04\n\tMapReport\x12\x11\n\tlong_name\x18\x01 \x01(\t\x12\x12\n\nshort_name\x18\x02 \x01(\t\x12;\n\x04role\x18\x03 \x01(\x0e\x32-.meshtastic.protobuf.Config.DeviceConfig.Role\x12\x34\n\x08hw_model\x18\x04 \x01(\x0e\x32\".meshtastic.protobuf.HardwareModel\x12\x18\n\x10\x66irmware_version\x18\x05 \x01(\t\x12\x41\n\x06region\x18\x06 \x01(\x0e\x32\x31.meshtastic.protobuf.Config.LoRaConfig.RegionCode\x12H\n\x0cmodem_preset\x18\x07 \x01(\x0e\x32\x32.meshtastic.protobuf.Config.LoRaConfig.ModemPreset\x12\x1b\n\x13has_default_channel\x18\x08 \x01(\x08\x12\x12\n\nlatitude_i\x18\t \x01(\x0f\x12\x13\n\x0blongitude_i\x18\n \x01(\x0f\x12\x10\n\x08\x61ltitude\x18\x0b \x01(\x05\x12\x1a\n\x12position_precision\x18\x0c \x01(\r\x12\x1e\n\x16num_online_local_nodes\x18\r \x01(\r\x12!\n\x19has_opted_report_location\x18\x0e \x01(\x08\x42`\n\x14org.meshtastic.protoB\nMQTTProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3')
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1emeshtastic/protobuf/mqtt.proto\x12\x13meshtastic.protobuf\x1a meshtastic/protobuf/config.proto\x1a\x1emeshtastic/protobuf/mesh.proto\"j\n\x0fServiceEnvelope\x12/\n\x06packet\x18\x01 \x01(\x0b\x32\x1f.meshtastic.protobuf.MeshPacket\x12\x12\n\nchannel_id\x18\x02 \x01(\t\x12\x12\n\ngateway_id\x18\x03 \x01(\t\"\xe0\x03\n\tMapReport\x12\x11\n\tlong_name\x18\x01 \x01(\t\x12\x12\n\nshort_name\x18\x02 \x01(\t\x12;\n\x04role\x18\x03 \x01(\x0e\x32-.meshtastic.protobuf.Config.DeviceConfig.Role\x12\x34\n\x08hw_model\x18\x04 \x01(\x0e\x32\".meshtastic.protobuf.HardwareModel\x12\x18\n\x10\x66irmware_version\x18\x05 \x01(\t\x12\x41\n\x06region\x18\x06 \x01(\x0e\x32\x31.meshtastic.protobuf.Config.LoRaConfig.RegionCode\x12H\n\x0cmodem_preset\x18\x07 \x01(\x0e\x32\x32.meshtastic.protobuf.Config.LoRaConfig.ModemPreset\x12\x1b\n\x13has_default_channel\x18\x08 \x01(\x08\x12\x12\n\nlatitude_i\x18\t \x01(\x0f\x12\x13\n\x0blongitude_i\x18\n \x01(\x0f\x12\x10\n\x08\x61ltitude\x18\x0b \x01(\x05\x12\x1a\n\x12position_precision\x18\x0c \x01(\r\x12\x1e\n\x16num_online_local_nodes\x18\r \x01(\rB_\n\x13\x63om.geeksville.meshB\nMQTTProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3')
_globals = globals()
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.protobuf.mqtt_pb2', _globals)
if _descriptor._USE_C_DESCRIPTORS == False:
DESCRIPTOR._options = None
DESCRIPTOR._serialized_options = b'\n\024org.meshtastic.protoB\nMQTTProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000'
DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\nMQTTProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000'
_globals['_SERVICEENVELOPE']._serialized_start=121
_globals['_SERVICEENVELOPE']._serialized_end=227
_globals['_MAPREPORT']._serialized_start=230
_globals['_MAPREPORT']._serialized_end=745
_globals['_MAPREPORT']._serialized_end=710
# @@protoc_insertion_point(module_scope)

View File

@@ -72,7 +72,6 @@ class MapReport(google.protobuf.message.Message):
ALTITUDE_FIELD_NUMBER: builtins.int
POSITION_PRECISION_FIELD_NUMBER: builtins.int
NUM_ONLINE_LOCAL_NODES_FIELD_NUMBER: builtins.int
HAS_OPTED_REPORT_LOCATION_FIELD_NUMBER: builtins.int
long_name: builtins.str
"""
A full name for this user, i.e. "Kevin Hester"
@@ -127,11 +126,6 @@ class MapReport(google.protobuf.message.Message):
"""
Number of online nodes (heard in the last 2 hours) this node has in its list that were received locally (not via MQTT)
"""
has_opted_report_location: builtins.bool
"""
User has opted in to share their location (map report) with the mqtt server
Controlled by map_report.should_report_location
"""
def __init__(
self,
*,
@@ -148,8 +142,7 @@ class MapReport(google.protobuf.message.Message):
altitude: builtins.int = ...,
position_precision: builtins.int = ...,
num_online_local_nodes: builtins.int = ...,
has_opted_report_location: builtins.bool = ...,
) -> None: ...
def ClearField(self, field_name: typing.Literal["altitude", b"altitude", "firmware_version", b"firmware_version", "has_default_channel", b"has_default_channel", "has_opted_report_location", b"has_opted_report_location", "hw_model", b"hw_model", "latitude_i", b"latitude_i", "long_name", b"long_name", "longitude_i", b"longitude_i", "modem_preset", b"modem_preset", "num_online_local_nodes", b"num_online_local_nodes", "position_precision", b"position_precision", "region", b"region", "role", b"role", "short_name", b"short_name"]) -> None: ...
def ClearField(self, field_name: typing.Literal["altitude", b"altitude", "firmware_version", b"firmware_version", "has_default_channel", b"has_default_channel", "hw_model", b"hw_model", "latitude_i", b"latitude_i", "long_name", b"long_name", "longitude_i", b"longitude_i", "modem_preset", b"modem_preset", "num_online_local_nodes", b"num_online_local_nodes", "position_precision", b"position_precision", "region", b"region", "role", b"role", "short_name", b"short_name"]) -> None: ...
global___MapReport = MapReport

View File

@@ -1,35 +0,0 @@
# -*- coding: utf-8 -*-
# Generated by the protocol buffer compiler. DO NOT EDIT!
# source: meshtastic/protobuf/nanopb.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 symbol_database as _symbol_database
from google.protobuf.internal import builder as _builder
# @@protoc_insertion_point(imports)
_sym_db = _symbol_database.Default()
from google.protobuf import descriptor_pb2 as google_dot_protobuf_dot_descriptor__pb2
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n meshtastic/protobuf/nanopb.proto\x1a google/protobuf/descriptor.proto\"\xa4\x07\n\rNanoPBOptions\x12\x10\n\x08max_size\x18\x01 \x01(\x05\x12\x12\n\nmax_length\x18\x0e \x01(\x05\x12\x11\n\tmax_count\x18\x02 \x01(\x05\x12&\n\x08int_size\x18\x07 \x01(\x0e\x32\x08.IntSize:\nIS_DEFAULT\x12$\n\x04type\x18\x03 \x01(\x0e\x32\n.FieldType:\nFT_DEFAULT\x12\x18\n\nlong_names\x18\x04 \x01(\x08:\x04true\x12\x1c\n\rpacked_struct\x18\x05 \x01(\x08:\x05\x66\x61lse\x12\x1a\n\x0bpacked_enum\x18\n \x01(\x08:\x05\x66\x61lse\x12\x1b\n\x0cskip_message\x18\x06 \x01(\x08:\x05\x66\x61lse\x12\x18\n\tno_unions\x18\x08 \x01(\x08:\x05\x66\x61lse\x12\r\n\x05msgid\x18\t \x01(\r\x12\x1e\n\x0f\x61nonymous_oneof\x18\x0b \x01(\x08:\x05\x66\x61lse\x12\x15\n\x06proto3\x18\x0c \x01(\x08:\x05\x66\x61lse\x12#\n\x14proto3_singular_msgs\x18\x15 \x01(\x08:\x05\x66\x61lse\x12\x1d\n\x0e\x65num_to_string\x18\r \x01(\x08:\x05\x66\x61lse\x12\x1b\n\x0c\x66ixed_length\x18\x0f \x01(\x08:\x05\x66\x61lse\x12\x1a\n\x0b\x66ixed_count\x18\x10 \x01(\x08:\x05\x66\x61lse\x12\x1e\n\x0fsubmsg_callback\x18\x16 \x01(\x08:\x05\x66\x61lse\x12/\n\x0cmangle_names\x18\x11 \x01(\x0e\x32\x11.TypenameMangling:\x06M_NONE\x12(\n\x11\x63\x61llback_datatype\x18\x12 \x01(\t:\rpb_callback_t\x12\x34\n\x11\x63\x61llback_function\x18\x13 \x01(\t:\x19pb_default_field_callback\x12\x30\n\x0e\x64\x65scriptorsize\x18\x14 \x01(\x0e\x32\x0f.DescriptorSize:\x07\x44S_AUTO\x12\x1a\n\x0b\x64\x65\x66\x61ult_has\x18\x17 \x01(\x08:\x05\x66\x61lse\x12\x0f\n\x07include\x18\x18 \x03(\t\x12\x0f\n\x07\x65xclude\x18\x1a \x03(\t\x12\x0f\n\x07package\x18\x19 \x01(\t\x12\x41\n\rtype_override\x18\x1b \x01(\x0e\x32*.google.protobuf.FieldDescriptorProto.Type\x12\x19\n\x0bsort_by_tag\x18\x1c \x01(\x08:\x04true\x12.\n\rfallback_type\x18\x1d \x01(\x0e\x32\n.FieldType:\x0b\x46T_CALLBACK*i\n\tFieldType\x12\x0e\n\nFT_DEFAULT\x10\x00\x12\x0f\n\x0b\x46T_CALLBACK\x10\x01\x12\x0e\n\nFT_POINTER\x10\x04\x12\r\n\tFT_STATIC\x10\x02\x12\r\n\tFT_IGNORE\x10\x03\x12\r\n\tFT_INLINE\x10\x05*D\n\x07IntSize\x12\x0e\n\nIS_DEFAULT\x10\x00\x12\x08\n\x04IS_8\x10\x08\x12\t\n\x05IS_16\x10\x10\x12\t\n\x05IS_32\x10 \x12\t\n\x05IS_64\x10@*Z\n\x10TypenameMangling\x12\n\n\x06M_NONE\x10\x00\x12\x13\n\x0fM_STRIP_PACKAGE\x10\x01\x12\r\n\tM_FLATTEN\x10\x02\x12\x16\n\x12M_PACKAGE_INITIALS\x10\x03*E\n\x0e\x44\x65scriptorSize\x12\x0b\n\x07\x44S_AUTO\x10\x00\x12\x08\n\x04\x44S_1\x10\x01\x12\x08\n\x04\x44S_2\x10\x02\x12\x08\n\x04\x44S_4\x10\x04\x12\x08\n\x04\x44S_8\x10\x08:E\n\x0enanopb_fileopt\x12\x1c.google.protobuf.FileOptions\x18\xf2\x07 \x01(\x0b\x32\x0e.NanoPBOptions:G\n\rnanopb_msgopt\x12\x1f.google.protobuf.MessageOptions\x18\xf2\x07 \x01(\x0b\x32\x0e.NanoPBOptions:E\n\x0enanopb_enumopt\x12\x1c.google.protobuf.EnumOptions\x18\xf2\x07 \x01(\x0b\x32\x0e.NanoPBOptions:>\n\x06nanopb\x12\x1d.google.protobuf.FieldOptions\x18\xf2\x07 \x01(\x0b\x32\x0e.NanoPBOptionsB>\n\x18\x66i.kapsi.koti.jpa.nanopbZ\"github.com/meshtastic/go/generated')
_globals = globals()
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.protobuf.nanopb_pb2', _globals)
if _descriptor._USE_C_DESCRIPTORS == False:
DESCRIPTOR._options = None
DESCRIPTOR._serialized_options = b'\n\030fi.kapsi.koti.jpa.nanopbZ\"github.com/meshtastic/go/generated'
_globals['_FIELDTYPE']._serialized_start=1005
_globals['_FIELDTYPE']._serialized_end=1110
_globals['_INTSIZE']._serialized_start=1112
_globals['_INTSIZE']._serialized_end=1180
_globals['_TYPENAMEMANGLING']._serialized_start=1182
_globals['_TYPENAMEMANGLING']._serialized_end=1272
_globals['_DESCRIPTORSIZE']._serialized_start=1274
_globals['_DESCRIPTORSIZE']._serialized_end=1343
_globals['_NANOPBOPTIONS']._serialized_start=71
_globals['_NANOPBOPTIONS']._serialized_end=1003
# @@protoc_insertion_point(module_scope)

View File

@@ -1,324 +0,0 @@
"""
@generated by mypy-protobuf. Do not edit manually!
isort:skip_file
Custom options for defining:
- Maximum size of string/bytes
- Maximum number of elements in array
These are used by nanopb to generate statically allocable structures
for memory-limited environments.
"""
import builtins
import collections.abc
import google.protobuf.descriptor
import google.protobuf.descriptor_pb2
import google.protobuf.internal.containers
import google.protobuf.internal.enum_type_wrapper
import google.protobuf.internal.extension_dict
import google.protobuf.message
import sys
import typing
if sys.version_info >= (3, 10):
import typing as typing_extensions
else:
import typing_extensions
DESCRIPTOR: google.protobuf.descriptor.FileDescriptor
class _FieldType:
ValueType = typing.NewType("ValueType", builtins.int)
V: typing_extensions.TypeAlias = ValueType
class _FieldTypeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_FieldType.ValueType], builtins.type):
DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor
FT_DEFAULT: _FieldType.ValueType # 0
"""Automatically decide field type, generate static field if possible."""
FT_CALLBACK: _FieldType.ValueType # 1
"""Always generate a callback field."""
FT_POINTER: _FieldType.ValueType # 4
"""Always generate a dynamically allocated field."""
FT_STATIC: _FieldType.ValueType # 2
"""Generate a static field or raise an exception if not possible."""
FT_IGNORE: _FieldType.ValueType # 3
"""Ignore the field completely."""
FT_INLINE: _FieldType.ValueType # 5
"""Legacy option, use the separate 'fixed_length' option instead"""
class FieldType(_FieldType, metaclass=_FieldTypeEnumTypeWrapper): ...
FT_DEFAULT: FieldType.ValueType # 0
"""Automatically decide field type, generate static field if possible."""
FT_CALLBACK: FieldType.ValueType # 1
"""Always generate a callback field."""
FT_POINTER: FieldType.ValueType # 4
"""Always generate a dynamically allocated field."""
FT_STATIC: FieldType.ValueType # 2
"""Generate a static field or raise an exception if not possible."""
FT_IGNORE: FieldType.ValueType # 3
"""Ignore the field completely."""
FT_INLINE: FieldType.ValueType # 5
"""Legacy option, use the separate 'fixed_length' option instead"""
global___FieldType = FieldType
class _IntSize:
ValueType = typing.NewType("ValueType", builtins.int)
V: typing_extensions.TypeAlias = ValueType
class _IntSizeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_IntSize.ValueType], builtins.type):
DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor
IS_DEFAULT: _IntSize.ValueType # 0
"""Default, 32/64bit based on type in .proto"""
IS_8: _IntSize.ValueType # 8
IS_16: _IntSize.ValueType # 16
IS_32: _IntSize.ValueType # 32
IS_64: _IntSize.ValueType # 64
class IntSize(_IntSize, metaclass=_IntSizeEnumTypeWrapper): ...
IS_DEFAULT: IntSize.ValueType # 0
"""Default, 32/64bit based on type in .proto"""
IS_8: IntSize.ValueType # 8
IS_16: IntSize.ValueType # 16
IS_32: IntSize.ValueType # 32
IS_64: IntSize.ValueType # 64
global___IntSize = IntSize
class _TypenameMangling:
ValueType = typing.NewType("ValueType", builtins.int)
V: typing_extensions.TypeAlias = ValueType
class _TypenameManglingEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_TypenameMangling.ValueType], builtins.type):
DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor
M_NONE: _TypenameMangling.ValueType # 0
"""Default, no typename mangling"""
M_STRIP_PACKAGE: _TypenameMangling.ValueType # 1
"""Strip current package name"""
M_FLATTEN: _TypenameMangling.ValueType # 2
"""Only use last path component"""
M_PACKAGE_INITIALS: _TypenameMangling.ValueType # 3
"""Replace the package name by the initials"""
class TypenameMangling(_TypenameMangling, metaclass=_TypenameManglingEnumTypeWrapper): ...
M_NONE: TypenameMangling.ValueType # 0
"""Default, no typename mangling"""
M_STRIP_PACKAGE: TypenameMangling.ValueType # 1
"""Strip current package name"""
M_FLATTEN: TypenameMangling.ValueType # 2
"""Only use last path component"""
M_PACKAGE_INITIALS: TypenameMangling.ValueType # 3
"""Replace the package name by the initials"""
global___TypenameMangling = TypenameMangling
class _DescriptorSize:
ValueType = typing.NewType("ValueType", builtins.int)
V: typing_extensions.TypeAlias = ValueType
class _DescriptorSizeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_DescriptorSize.ValueType], builtins.type):
DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor
DS_AUTO: _DescriptorSize.ValueType # 0
"""Select minimal size based on field type"""
DS_1: _DescriptorSize.ValueType # 1
"""1 word; up to 15 byte fields, no arrays"""
DS_2: _DescriptorSize.ValueType # 2
"""2 words; up to 4095 byte fields, 4095 entry arrays"""
DS_4: _DescriptorSize.ValueType # 4
"""4 words; up to 2^32-1 byte fields, 2^16-1 entry arrays"""
DS_8: _DescriptorSize.ValueType # 8
"""8 words; up to 2^32-1 entry arrays"""
class DescriptorSize(_DescriptorSize, metaclass=_DescriptorSizeEnumTypeWrapper): ...
DS_AUTO: DescriptorSize.ValueType # 0
"""Select minimal size based on field type"""
DS_1: DescriptorSize.ValueType # 1
"""1 word; up to 15 byte fields, no arrays"""
DS_2: DescriptorSize.ValueType # 2
"""2 words; up to 4095 byte fields, 4095 entry arrays"""
DS_4: DescriptorSize.ValueType # 4
"""4 words; up to 2^32-1 byte fields, 2^16-1 entry arrays"""
DS_8: DescriptorSize.ValueType # 8
"""8 words; up to 2^32-1 entry arrays"""
global___DescriptorSize = DescriptorSize
@typing.final
class NanoPBOptions(google.protobuf.message.Message):
"""This is the inner options message, which basically defines options for
a field. When it is used in message or file scope, it applies to all
fields.
"""
DESCRIPTOR: google.protobuf.descriptor.Descriptor
MAX_SIZE_FIELD_NUMBER: builtins.int
MAX_LENGTH_FIELD_NUMBER: builtins.int
MAX_COUNT_FIELD_NUMBER: builtins.int
INT_SIZE_FIELD_NUMBER: builtins.int
TYPE_FIELD_NUMBER: builtins.int
LONG_NAMES_FIELD_NUMBER: builtins.int
PACKED_STRUCT_FIELD_NUMBER: builtins.int
PACKED_ENUM_FIELD_NUMBER: builtins.int
SKIP_MESSAGE_FIELD_NUMBER: builtins.int
NO_UNIONS_FIELD_NUMBER: builtins.int
MSGID_FIELD_NUMBER: builtins.int
ANONYMOUS_ONEOF_FIELD_NUMBER: builtins.int
PROTO3_FIELD_NUMBER: builtins.int
PROTO3_SINGULAR_MSGS_FIELD_NUMBER: builtins.int
ENUM_TO_STRING_FIELD_NUMBER: builtins.int
FIXED_LENGTH_FIELD_NUMBER: builtins.int
FIXED_COUNT_FIELD_NUMBER: builtins.int
SUBMSG_CALLBACK_FIELD_NUMBER: builtins.int
MANGLE_NAMES_FIELD_NUMBER: builtins.int
CALLBACK_DATATYPE_FIELD_NUMBER: builtins.int
CALLBACK_FUNCTION_FIELD_NUMBER: builtins.int
DESCRIPTORSIZE_FIELD_NUMBER: builtins.int
DEFAULT_HAS_FIELD_NUMBER: builtins.int
INCLUDE_FIELD_NUMBER: builtins.int
EXCLUDE_FIELD_NUMBER: builtins.int
PACKAGE_FIELD_NUMBER: builtins.int
TYPE_OVERRIDE_FIELD_NUMBER: builtins.int
SORT_BY_TAG_FIELD_NUMBER: builtins.int
FALLBACK_TYPE_FIELD_NUMBER: builtins.int
max_size: builtins.int
"""Allocated size for 'bytes' and 'string' fields.
For string fields, this should include the space for null terminator.
"""
max_length: builtins.int
"""Maximum length for 'string' fields. Setting this is equivalent
to setting max_size to a value of length+1.
"""
max_count: builtins.int
"""Allocated number of entries in arrays ('repeated' fields)"""
int_size: global___IntSize.ValueType
"""Size of integer fields. Can save some memory if you don't need
full 32 bits for the value.
"""
type: global___FieldType.ValueType
"""Force type of field (callback or static allocation)"""
long_names: builtins.bool
"""Use long names for enums, i.e. EnumName_EnumValue."""
packed_struct: builtins.bool
"""Add 'packed' attribute to generated structs.
Note: this cannot be used on CPUs that break on unaligned
accesses to variables.
"""
packed_enum: builtins.bool
"""Add 'packed' attribute to generated enums."""
skip_message: builtins.bool
"""Skip this message"""
no_unions: builtins.bool
"""Generate oneof fields as normal optional fields instead of union."""
msgid: builtins.int
"""integer type tag for a message"""
anonymous_oneof: builtins.bool
"""decode oneof as anonymous union"""
proto3: builtins.bool
"""Proto3 singular field does not generate a "has_" flag"""
proto3_singular_msgs: builtins.bool
"""Force proto3 messages to have no "has_" flag.
This was default behavior until nanopb-0.4.0.
"""
enum_to_string: builtins.bool
"""Generate an enum->string mapping function (can take up lots of space)."""
fixed_length: builtins.bool
"""Generate bytes arrays with fixed length"""
fixed_count: builtins.bool
"""Generate repeated field with fixed count"""
submsg_callback: builtins.bool
"""Generate message-level callback that is called before decoding submessages.
This can be used to set callback fields for submsgs inside oneofs.
"""
mangle_names: global___TypenameMangling.ValueType
"""Shorten or remove package names from type names.
This option applies only on the file level.
"""
callback_datatype: builtins.str
"""Data type for storage associated with callback fields."""
callback_function: builtins.str
"""Callback function used for encoding and decoding.
Prior to nanopb-0.4.0, the callback was specified in per-field pb_callback_t
structure. This is still supported, but does not work inside e.g. oneof or pointer
fields. Instead, a new method allows specifying a per-message callback that
will be called for all callback fields in a message type.
"""
descriptorsize: global___DescriptorSize.ValueType
"""Select the size of field descriptors. This option has to be defined
for the whole message, not per-field. Usually automatic selection is
ok, but if it results in compilation errors you can increase the field
size here.
"""
default_has: builtins.bool
"""Set default value for has_ fields."""
package: builtins.str
"""Package name that applies only for nanopb."""
type_override: google.protobuf.descriptor_pb2.FieldDescriptorProto.Type.ValueType
"""Override type of the field in generated C code. Only to be used with related field types"""
sort_by_tag: builtins.bool
"""Due to historical reasons, nanopb orders fields in structs by their tag number
instead of the order in .proto. Set this to false to keep the .proto order.
The default value will probably change to false in nanopb-0.5.0.
"""
fallback_type: global___FieldType.ValueType
"""Set the FT_DEFAULT field conversion strategy.
A field that can become a static member of a c struct (e.g. int, bool, etc)
will be a a static field.
Fields with dynamic length are converted to either a pointer or a callback.
"""
@property
def include(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.str]:
"""Extra files to include in generated `.pb.h`"""
@property
def exclude(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.str]:
"""Automatic includes to exclude from generated `.pb.h`
Same as nanopb_generator.py command line flag -x.
"""
def __init__(
self,
*,
max_size: builtins.int | None = ...,
max_length: builtins.int | None = ...,
max_count: builtins.int | None = ...,
int_size: global___IntSize.ValueType | None = ...,
type: global___FieldType.ValueType | None = ...,
long_names: builtins.bool | None = ...,
packed_struct: builtins.bool | None = ...,
packed_enum: builtins.bool | None = ...,
skip_message: builtins.bool | None = ...,
no_unions: builtins.bool | None = ...,
msgid: builtins.int | None = ...,
anonymous_oneof: builtins.bool | None = ...,
proto3: builtins.bool | None = ...,
proto3_singular_msgs: builtins.bool | None = ...,
enum_to_string: builtins.bool | None = ...,
fixed_length: builtins.bool | None = ...,
fixed_count: builtins.bool | None = ...,
submsg_callback: builtins.bool | None = ...,
mangle_names: global___TypenameMangling.ValueType | None = ...,
callback_datatype: builtins.str | None = ...,
callback_function: builtins.str | None = ...,
descriptorsize: global___DescriptorSize.ValueType | None = ...,
default_has: builtins.bool | None = ...,
include: collections.abc.Iterable[builtins.str] | None = ...,
exclude: collections.abc.Iterable[builtins.str] | None = ...,
package: builtins.str | None = ...,
type_override: google.protobuf.descriptor_pb2.FieldDescriptorProto.Type.ValueType | None = ...,
sort_by_tag: builtins.bool | None = ...,
fallback_type: global___FieldType.ValueType | None = ...,
) -> None: ...
def HasField(self, field_name: typing.Literal["anonymous_oneof", b"anonymous_oneof", "callback_datatype", b"callback_datatype", "callback_function", b"callback_function", "default_has", b"default_has", "descriptorsize", b"descriptorsize", "enum_to_string", b"enum_to_string", "fallback_type", b"fallback_type", "fixed_count", b"fixed_count", "fixed_length", b"fixed_length", "int_size", b"int_size", "long_names", b"long_names", "mangle_names", b"mangle_names", "max_count", b"max_count", "max_length", b"max_length", "max_size", b"max_size", "msgid", b"msgid", "no_unions", b"no_unions", "package", b"package", "packed_enum", b"packed_enum", "packed_struct", b"packed_struct", "proto3", b"proto3", "proto3_singular_msgs", b"proto3_singular_msgs", "skip_message", b"skip_message", "sort_by_tag", b"sort_by_tag", "submsg_callback", b"submsg_callback", "type", b"type", "type_override", b"type_override"]) -> builtins.bool: ...
def ClearField(self, field_name: typing.Literal["anonymous_oneof", b"anonymous_oneof", "callback_datatype", b"callback_datatype", "callback_function", b"callback_function", "default_has", b"default_has", "descriptorsize", b"descriptorsize", "enum_to_string", b"enum_to_string", "exclude", b"exclude", "fallback_type", b"fallback_type", "fixed_count", b"fixed_count", "fixed_length", b"fixed_length", "include", b"include", "int_size", b"int_size", "long_names", b"long_names", "mangle_names", b"mangle_names", "max_count", b"max_count", "max_length", b"max_length", "max_size", b"max_size", "msgid", b"msgid", "no_unions", b"no_unions", "package", b"package", "packed_enum", b"packed_enum", "packed_struct", b"packed_struct", "proto3", b"proto3", "proto3_singular_msgs", b"proto3_singular_msgs", "skip_message", b"skip_message", "sort_by_tag", b"sort_by_tag", "submsg_callback", b"submsg_callback", "type", b"type", "type_override", b"type_override"]) -> None: ...
global___NanoPBOptions = NanoPBOptions
NANOPB_FILEOPT_FIELD_NUMBER: builtins.int
NANOPB_MSGOPT_FIELD_NUMBER: builtins.int
NANOPB_ENUMOPT_FIELD_NUMBER: builtins.int
NANOPB_FIELD_NUMBER: builtins.int
nanopb_fileopt: google.protobuf.internal.extension_dict._ExtensionFieldDescriptor[google.protobuf.descriptor_pb2.FileOptions, global___NanoPBOptions]
nanopb_msgopt: google.protobuf.internal.extension_dict._ExtensionFieldDescriptor[google.protobuf.descriptor_pb2.MessageOptions, global___NanoPBOptions]
nanopb_enumopt: google.protobuf.internal.extension_dict._ExtensionFieldDescriptor[google.protobuf.descriptor_pb2.EnumOptions, global___NanoPBOptions]
nanopb: google.protobuf.internal.extension_dict._ExtensionFieldDescriptor[google.protobuf.descriptor_pb2.FieldOptions, global___NanoPBOptions]

View File

@@ -13,14 +13,14 @@ _sym_db = _symbol_database.Default()
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\"meshtastic/protobuf/paxcount.proto\x12\x13meshtastic.protobuf\"5\n\x08Paxcount\x12\x0c\n\x04wifi\x18\x01 \x01(\r\x12\x0b\n\x03\x62le\x18\x02 \x01(\r\x12\x0e\n\x06uptime\x18\x03 \x01(\rBd\n\x14org.meshtastic.protoB\x0ePaxcountProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3')
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\"meshtastic/protobuf/paxcount.proto\x12\x13meshtastic.protobuf\"5\n\x08Paxcount\x12\x0c\n\x04wifi\x18\x01 \x01(\r\x12\x0b\n\x03\x62le\x18\x02 \x01(\r\x12\x0e\n\x06uptime\x18\x03 \x01(\rBc\n\x13\x63om.geeksville.meshB\x0ePaxcountProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3')
_globals = globals()
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.protobuf.paxcount_pb2', _globals)
if _descriptor._USE_C_DESCRIPTORS == False:
DESCRIPTOR._options = None
DESCRIPTOR._serialized_options = b'\n\024org.meshtastic.protoB\016PaxcountProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000'
DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\016PaxcountProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000'
_globals['_PAXCOUNT']._serialized_start=59
_globals['_PAXCOUNT']._serialized_end=112
# @@protoc_insertion_point(module_scope)

View File

@@ -13,14 +13,14 @@ _sym_db = _symbol_database.Default()
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\"meshtastic/protobuf/portnums.proto\x12\x13meshtastic.protobuf*\xf6\x04\n\x07PortNum\x12\x0f\n\x0bUNKNOWN_APP\x10\x00\x12\x14\n\x10TEXT_MESSAGE_APP\x10\x01\x12\x17\n\x13REMOTE_HARDWARE_APP\x10\x02\x12\x10\n\x0cPOSITION_APP\x10\x03\x12\x10\n\x0cNODEINFO_APP\x10\x04\x12\x0f\n\x0bROUTING_APP\x10\x05\x12\r\n\tADMIN_APP\x10\x06\x12\x1f\n\x1bTEXT_MESSAGE_COMPRESSED_APP\x10\x07\x12\x10\n\x0cWAYPOINT_APP\x10\x08\x12\r\n\tAUDIO_APP\x10\t\x12\x18\n\x14\x44\x45TECTION_SENSOR_APP\x10\n\x12\r\n\tALERT_APP\x10\x0b\x12\x18\n\x14KEY_VERIFICATION_APP\x10\x0c\x12\r\n\tREPLY_APP\x10 \x12\x11\n\rIP_TUNNEL_APP\x10!\x12\x12\n\x0ePAXCOUNTER_APP\x10\"\x12\x0e\n\nSERIAL_APP\x10@\x12\x15\n\x11STORE_FORWARD_APP\x10\x41\x12\x12\n\x0eRANGE_TEST_APP\x10\x42\x12\x11\n\rTELEMETRY_APP\x10\x43\x12\x0b\n\x07ZPS_APP\x10\x44\x12\x11\n\rSIMULATOR_APP\x10\x45\x12\x12\n\x0eTRACEROUTE_APP\x10\x46\x12\x14\n\x10NEIGHBORINFO_APP\x10G\x12\x0f\n\x0b\x41TAK_PLUGIN\x10H\x12\x12\n\x0eMAP_REPORT_APP\x10I\x12\x13\n\x0fPOWERSTRESS_APP\x10J\x12\x18\n\x14RETICULUM_TUNNEL_APP\x10L\x12\x0f\n\x0b\x43\x41YENNE_APP\x10M\x12\x10\n\x0bPRIVATE_APP\x10\x80\x02\x12\x13\n\x0e\x41TAK_FORWARDER\x10\x81\x02\x12\x08\n\x03MAX\x10\xff\x03\x42^\n\x14org.meshtastic.protoB\x08PortnumsZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3')
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\"meshtastic/protobuf/portnums.proto\x12\x13meshtastic.protobuf*\xb1\x04\n\x07PortNum\x12\x0f\n\x0bUNKNOWN_APP\x10\x00\x12\x14\n\x10TEXT_MESSAGE_APP\x10\x01\x12\x17\n\x13REMOTE_HARDWARE_APP\x10\x02\x12\x10\n\x0cPOSITION_APP\x10\x03\x12\x10\n\x0cNODEINFO_APP\x10\x04\x12\x0f\n\x0bROUTING_APP\x10\x05\x12\r\n\tADMIN_APP\x10\x06\x12\x1f\n\x1bTEXT_MESSAGE_COMPRESSED_APP\x10\x07\x12\x10\n\x0cWAYPOINT_APP\x10\x08\x12\r\n\tAUDIO_APP\x10\t\x12\x18\n\x14\x44\x45TECTION_SENSOR_APP\x10\n\x12\r\n\tALERT_APP\x10\x0b\x12\r\n\tREPLY_APP\x10 \x12\x11\n\rIP_TUNNEL_APP\x10!\x12\x12\n\x0ePAXCOUNTER_APP\x10\"\x12\x0e\n\nSERIAL_APP\x10@\x12\x15\n\x11STORE_FORWARD_APP\x10\x41\x12\x12\n\x0eRANGE_TEST_APP\x10\x42\x12\x11\n\rTELEMETRY_APP\x10\x43\x12\x0b\n\x07ZPS_APP\x10\x44\x12\x11\n\rSIMULATOR_APP\x10\x45\x12\x12\n\x0eTRACEROUTE_APP\x10\x46\x12\x14\n\x10NEIGHBORINFO_APP\x10G\x12\x0f\n\x0b\x41TAK_PLUGIN\x10H\x12\x12\n\x0eMAP_REPORT_APP\x10I\x12\x13\n\x0fPOWERSTRESS_APP\x10J\x12\x10\n\x0bPRIVATE_APP\x10\x80\x02\x12\x13\n\x0e\x41TAK_FORWARDER\x10\x81\x02\x12\x08\n\x03MAX\x10\xff\x03\x42]\n\x13\x63om.geeksville.meshB\x08PortnumsZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3')
_globals = globals()
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.protobuf.portnums_pb2', _globals)
if _descriptor._USE_C_DESCRIPTORS == False:
DESCRIPTOR._options = None
DESCRIPTOR._serialized_options = b'\n\024org.meshtastic.protoB\010PortnumsZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000'
DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\010PortnumsZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000'
_globals['_PORTNUM']._serialized_start=60
_globals['_PORTNUM']._serialized_end=690
_globals['_PORTNUM']._serialized_end=621
# @@protoc_insertion_point(module_scope)

View File

@@ -97,10 +97,6 @@ class _PortNumEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTy
"""
Same as Text Message but used for critical alerts.
"""
KEY_VERIFICATION_APP: _PortNum.ValueType # 12
"""
Module/port for handling key verification requests.
"""
REPLY_APP: _PortNum.ValueType # 32
"""
Provides a 'ping' service that replies to any packet it receives.
@@ -183,17 +179,6 @@ class _PortNumEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTy
"""
PowerStress based monitoring support (for automated power consumption testing)
"""
RETICULUM_TUNNEL_APP: _PortNum.ValueType # 76
"""
Reticulum Network Stack Tunnel App
ENCODING: Fragmented RNS Packet. Handled by Meshtastic RNS interface
"""
CAYENNE_APP: _PortNum.ValueType # 77
"""
App for transporting Cayenne Low Power Payload, popular for LoRaWAN sensor nodes. Offers ability to send
arbitrary telemetry over meshtastic that is not covered by telemetry.proto
ENCODING: CayenneLLP
"""
PRIVATE_APP: _PortNum.ValueType # 256
"""
Private applications should use portnums >= 256.
@@ -301,10 +286,6 @@ ALERT_APP: PortNum.ValueType # 11
"""
Same as Text Message but used for critical alerts.
"""
KEY_VERIFICATION_APP: PortNum.ValueType # 12
"""
Module/port for handling key verification requests.
"""
REPLY_APP: PortNum.ValueType # 32
"""
Provides a 'ping' service that replies to any packet it receives.
@@ -387,17 +368,6 @@ POWERSTRESS_APP: PortNum.ValueType # 74
"""
PowerStress based monitoring support (for automated power consumption testing)
"""
RETICULUM_TUNNEL_APP: PortNum.ValueType # 76
"""
Reticulum Network Stack Tunnel App
ENCODING: Fragmented RNS Packet. Handled by Meshtastic RNS interface
"""
CAYENNE_APP: PortNum.ValueType # 77
"""
App for transporting Cayenne Low Power Payload, popular for LoRaWAN sensor nodes. Offers ability to send
arbitrary telemetry over meshtastic that is not covered by telemetry.proto
ENCODING: CayenneLLP
"""
PRIVATE_APP: PortNum.ValueType # 256
"""
Private applications should use portnums >= 256.

View File

@@ -13,14 +13,14 @@ _sym_db = _symbol_database.Default()
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\"meshtastic/protobuf/powermon.proto\x12\x13meshtastic.protobuf\"\xe0\x01\n\x08PowerMon\"\xd3\x01\n\x05State\x12\x08\n\x04None\x10\x00\x12\x11\n\rCPU_DeepSleep\x10\x01\x12\x12\n\x0e\x43PU_LightSleep\x10\x02\x12\x0c\n\x08Vext1_On\x10\x04\x12\r\n\tLora_RXOn\x10\x08\x12\r\n\tLora_TXOn\x10\x10\x12\x11\n\rLora_RXActive\x10 \x12\t\n\x05\x42T_On\x10@\x12\x0b\n\x06LED_On\x10\x80\x01\x12\x0e\n\tScreen_On\x10\x80\x02\x12\x13\n\x0eScreen_Drawing\x10\x80\x04\x12\x0c\n\x07Wifi_On\x10\x80\x08\x12\x0f\n\nGPS_Active\x10\x80\x10\"\x88\x03\n\x12PowerStressMessage\x12;\n\x03\x63md\x18\x01 \x01(\x0e\x32..meshtastic.protobuf.PowerStressMessage.Opcode\x12\x13\n\x0bnum_seconds\x18\x02 \x01(\x02\"\x9f\x02\n\x06Opcode\x12\t\n\x05UNSET\x10\x00\x12\x0e\n\nPRINT_INFO\x10\x01\x12\x0f\n\x0b\x46ORCE_QUIET\x10\x02\x12\r\n\tEND_QUIET\x10\x03\x12\r\n\tSCREEN_ON\x10\x10\x12\x0e\n\nSCREEN_OFF\x10\x11\x12\x0c\n\x08\x43PU_IDLE\x10 \x12\x11\n\rCPU_DEEPSLEEP\x10!\x12\x0e\n\nCPU_FULLON\x10\"\x12\n\n\x06LED_ON\x10\x30\x12\x0b\n\x07LED_OFF\x10\x31\x12\x0c\n\x08LORA_OFF\x10@\x12\x0b\n\x07LORA_TX\x10\x41\x12\x0b\n\x07LORA_RX\x10\x42\x12\n\n\x06\x42T_OFF\x10P\x12\t\n\x05\x42T_ON\x10Q\x12\x0c\n\x08WIFI_OFF\x10`\x12\x0b\n\x07WIFI_ON\x10\x61\x12\x0b\n\x07GPS_OFF\x10p\x12\n\n\x06GPS_ON\x10qBd\n\x14org.meshtastic.protoB\x0ePowerMonProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3')
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\"meshtastic/protobuf/powermon.proto\x12\x13meshtastic.protobuf\"\xe0\x01\n\x08PowerMon\"\xd3\x01\n\x05State\x12\x08\n\x04None\x10\x00\x12\x11\n\rCPU_DeepSleep\x10\x01\x12\x12\n\x0e\x43PU_LightSleep\x10\x02\x12\x0c\n\x08Vext1_On\x10\x04\x12\r\n\tLora_RXOn\x10\x08\x12\r\n\tLora_TXOn\x10\x10\x12\x11\n\rLora_RXActive\x10 \x12\t\n\x05\x42T_On\x10@\x12\x0b\n\x06LED_On\x10\x80\x01\x12\x0e\n\tScreen_On\x10\x80\x02\x12\x13\n\x0eScreen_Drawing\x10\x80\x04\x12\x0c\n\x07Wifi_On\x10\x80\x08\x12\x0f\n\nGPS_Active\x10\x80\x10\"\x88\x03\n\x12PowerStressMessage\x12;\n\x03\x63md\x18\x01 \x01(\x0e\x32..meshtastic.protobuf.PowerStressMessage.Opcode\x12\x13\n\x0bnum_seconds\x18\x02 \x01(\x02\"\x9f\x02\n\x06Opcode\x12\t\n\x05UNSET\x10\x00\x12\x0e\n\nPRINT_INFO\x10\x01\x12\x0f\n\x0b\x46ORCE_QUIET\x10\x02\x12\r\n\tEND_QUIET\x10\x03\x12\r\n\tSCREEN_ON\x10\x10\x12\x0e\n\nSCREEN_OFF\x10\x11\x12\x0c\n\x08\x43PU_IDLE\x10 \x12\x11\n\rCPU_DEEPSLEEP\x10!\x12\x0e\n\nCPU_FULLON\x10\"\x12\n\n\x06LED_ON\x10\x30\x12\x0b\n\x07LED_OFF\x10\x31\x12\x0c\n\x08LORA_OFF\x10@\x12\x0b\n\x07LORA_TX\x10\x41\x12\x0b\n\x07LORA_RX\x10\x42\x12\n\n\x06\x42T_OFF\x10P\x12\t\n\x05\x42T_ON\x10Q\x12\x0c\n\x08WIFI_OFF\x10`\x12\x0b\n\x07WIFI_ON\x10\x61\x12\x0b\n\x07GPS_OFF\x10p\x12\n\n\x06GPS_ON\x10qBc\n\x13\x63om.geeksville.meshB\x0ePowerMonProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3')
_globals = globals()
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.protobuf.powermon_pb2', _globals)
if _descriptor._USE_C_DESCRIPTORS == False:
DESCRIPTOR._options = None
DESCRIPTOR._serialized_options = b'\n\024org.meshtastic.protoB\016PowerMonProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000'
DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\016PowerMonProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000'
_globals['_POWERMON']._serialized_start=60
_globals['_POWERMON']._serialized_end=284
_globals['_POWERMON_STATE']._serialized_start=73

View File

@@ -13,14 +13,14 @@ _sym_db = _symbol_database.Default()
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n)meshtastic/protobuf/remote_hardware.proto\x12\x13meshtastic.protobuf\"\xdf\x01\n\x0fHardwareMessage\x12\x37\n\x04type\x18\x01 \x01(\x0e\x32).meshtastic.protobuf.HardwareMessage.Type\x12\x11\n\tgpio_mask\x18\x02 \x01(\x04\x12\x12\n\ngpio_value\x18\x03 \x01(\x04\"l\n\x04Type\x12\t\n\x05UNSET\x10\x00\x12\x0f\n\x0bWRITE_GPIOS\x10\x01\x12\x0f\n\x0bWATCH_GPIOS\x10\x02\x12\x11\n\rGPIOS_CHANGED\x10\x03\x12\x0e\n\nREAD_GPIOS\x10\x04\x12\x14\n\x10READ_GPIOS_REPLY\x10\x05\x42\x64\n\x14org.meshtastic.protoB\x0eRemoteHardwareZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3')
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n)meshtastic/protobuf/remote_hardware.proto\x12\x13meshtastic.protobuf\"\xdf\x01\n\x0fHardwareMessage\x12\x37\n\x04type\x18\x01 \x01(\x0e\x32).meshtastic.protobuf.HardwareMessage.Type\x12\x11\n\tgpio_mask\x18\x02 \x01(\x04\x12\x12\n\ngpio_value\x18\x03 \x01(\x04\"l\n\x04Type\x12\t\n\x05UNSET\x10\x00\x12\x0f\n\x0bWRITE_GPIOS\x10\x01\x12\x0f\n\x0bWATCH_GPIOS\x10\x02\x12\x11\n\rGPIOS_CHANGED\x10\x03\x12\x0e\n\nREAD_GPIOS\x10\x04\x12\x14\n\x10READ_GPIOS_REPLY\x10\x05\x42\x63\n\x13\x63om.geeksville.meshB\x0eRemoteHardwareZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3')
_globals = globals()
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.protobuf.remote_hardware_pb2', _globals)
if _descriptor._USE_C_DESCRIPTORS == False:
DESCRIPTOR._options = None
DESCRIPTOR._serialized_options = b'\n\024org.meshtastic.protoB\016RemoteHardwareZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000'
DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\016RemoteHardwareZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000'
_globals['_HARDWAREMESSAGE']._serialized_start=67
_globals['_HARDWAREMESSAGE']._serialized_end=290
_globals['_HARDWAREMESSAGE_TYPE']._serialized_start=182

View File

@@ -13,14 +13,14 @@ _sym_db = _symbol_database.Default()
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1fmeshtastic/protobuf/rtttl.proto\x12\x13meshtastic.protobuf\"\x1f\n\x0bRTTTLConfig\x12\x10\n\x08ringtone\x18\x01 \x01(\tBg\n\x14org.meshtastic.protoB\x11RTTTLConfigProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3')
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1fmeshtastic/protobuf/rtttl.proto\x12\x13meshtastic.protobuf\"\x1f\n\x0bRTTTLConfig\x12\x10\n\x08ringtone\x18\x01 \x01(\tBf\n\x13\x63om.geeksville.meshB\x11RTTTLConfigProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3')
_globals = globals()
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.protobuf.rtttl_pb2', _globals)
if _descriptor._USE_C_DESCRIPTORS == False:
DESCRIPTOR._options = None
DESCRIPTOR._serialized_options = b'\n\024org.meshtastic.protoB\021RTTTLConfigProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000'
DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\021RTTTLConfigProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000'
_globals['_RTTTLCONFIG']._serialized_start=56
_globals['_RTTTLCONFIG']._serialized_end=87
# @@protoc_insertion_point(module_scope)

View File

@@ -13,14 +13,14 @@ _sym_db = _symbol_database.Default()
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n&meshtastic/protobuf/storeforward.proto\x12\x13meshtastic.protobuf\"\xc0\x07\n\x0fStoreAndForward\x12@\n\x02rr\x18\x01 \x01(\x0e\x32\x34.meshtastic.protobuf.StoreAndForward.RequestResponse\x12@\n\x05stats\x18\x02 \x01(\x0b\x32/.meshtastic.protobuf.StoreAndForward.StatisticsH\x00\x12?\n\x07history\x18\x03 \x01(\x0b\x32,.meshtastic.protobuf.StoreAndForward.HistoryH\x00\x12\x43\n\theartbeat\x18\x04 \x01(\x0b\x32..meshtastic.protobuf.StoreAndForward.HeartbeatH\x00\x12\x0e\n\x04text\x18\x05 \x01(\x0cH\x00\x1a\xcd\x01\n\nStatistics\x12\x16\n\x0emessages_total\x18\x01 \x01(\r\x12\x16\n\x0emessages_saved\x18\x02 \x01(\r\x12\x14\n\x0cmessages_max\x18\x03 \x01(\r\x12\x0f\n\x07up_time\x18\x04 \x01(\r\x12\x10\n\x08requests\x18\x05 \x01(\r\x12\x18\n\x10requests_history\x18\x06 \x01(\r\x12\x11\n\theartbeat\x18\x07 \x01(\x08\x12\x12\n\nreturn_max\x18\x08 \x01(\r\x12\x15\n\rreturn_window\x18\t \x01(\r\x1aI\n\x07History\x12\x18\n\x10history_messages\x18\x01 \x01(\r\x12\x0e\n\x06window\x18\x02 \x01(\r\x12\x14\n\x0clast_request\x18\x03 \x01(\r\x1a.\n\tHeartbeat\x12\x0e\n\x06period\x18\x01 \x01(\r\x12\x11\n\tsecondary\x18\x02 \x01(\r\"\xbc\x02\n\x0fRequestResponse\x12\t\n\x05UNSET\x10\x00\x12\x10\n\x0cROUTER_ERROR\x10\x01\x12\x14\n\x10ROUTER_HEARTBEAT\x10\x02\x12\x0f\n\x0bROUTER_PING\x10\x03\x12\x0f\n\x0bROUTER_PONG\x10\x04\x12\x0f\n\x0bROUTER_BUSY\x10\x05\x12\x12\n\x0eROUTER_HISTORY\x10\x06\x12\x10\n\x0cROUTER_STATS\x10\x07\x12\x16\n\x12ROUTER_TEXT_DIRECT\x10\x08\x12\x19\n\x15ROUTER_TEXT_BROADCAST\x10\t\x12\x10\n\x0c\x43LIENT_ERROR\x10@\x12\x12\n\x0e\x43LIENT_HISTORY\x10\x41\x12\x10\n\x0c\x43LIENT_STATS\x10\x42\x12\x0f\n\x0b\x43LIENT_PING\x10\x43\x12\x0f\n\x0b\x43LIENT_PONG\x10\x44\x12\x10\n\x0c\x43LIENT_ABORT\x10jB\t\n\x07variantBk\n\x14org.meshtastic.protoB\x15StoreAndForwardProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3')
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n&meshtastic/protobuf/storeforward.proto\x12\x13meshtastic.protobuf\"\xc0\x07\n\x0fStoreAndForward\x12@\n\x02rr\x18\x01 \x01(\x0e\x32\x34.meshtastic.protobuf.StoreAndForward.RequestResponse\x12@\n\x05stats\x18\x02 \x01(\x0b\x32/.meshtastic.protobuf.StoreAndForward.StatisticsH\x00\x12?\n\x07history\x18\x03 \x01(\x0b\x32,.meshtastic.protobuf.StoreAndForward.HistoryH\x00\x12\x43\n\theartbeat\x18\x04 \x01(\x0b\x32..meshtastic.protobuf.StoreAndForward.HeartbeatH\x00\x12\x0e\n\x04text\x18\x05 \x01(\x0cH\x00\x1a\xcd\x01\n\nStatistics\x12\x16\n\x0emessages_total\x18\x01 \x01(\r\x12\x16\n\x0emessages_saved\x18\x02 \x01(\r\x12\x14\n\x0cmessages_max\x18\x03 \x01(\r\x12\x0f\n\x07up_time\x18\x04 \x01(\r\x12\x10\n\x08requests\x18\x05 \x01(\r\x12\x18\n\x10requests_history\x18\x06 \x01(\r\x12\x11\n\theartbeat\x18\x07 \x01(\x08\x12\x12\n\nreturn_max\x18\x08 \x01(\r\x12\x15\n\rreturn_window\x18\t \x01(\r\x1aI\n\x07History\x12\x18\n\x10history_messages\x18\x01 \x01(\r\x12\x0e\n\x06window\x18\x02 \x01(\r\x12\x14\n\x0clast_request\x18\x03 \x01(\r\x1a.\n\tHeartbeat\x12\x0e\n\x06period\x18\x01 \x01(\r\x12\x11\n\tsecondary\x18\x02 \x01(\r\"\xbc\x02\n\x0fRequestResponse\x12\t\n\x05UNSET\x10\x00\x12\x10\n\x0cROUTER_ERROR\x10\x01\x12\x14\n\x10ROUTER_HEARTBEAT\x10\x02\x12\x0f\n\x0bROUTER_PING\x10\x03\x12\x0f\n\x0bROUTER_PONG\x10\x04\x12\x0f\n\x0bROUTER_BUSY\x10\x05\x12\x12\n\x0eROUTER_HISTORY\x10\x06\x12\x10\n\x0cROUTER_STATS\x10\x07\x12\x16\n\x12ROUTER_TEXT_DIRECT\x10\x08\x12\x19\n\x15ROUTER_TEXT_BROADCAST\x10\t\x12\x10\n\x0c\x43LIENT_ERROR\x10@\x12\x12\n\x0e\x43LIENT_HISTORY\x10\x41\x12\x10\n\x0c\x43LIENT_STATS\x10\x42\x12\x0f\n\x0b\x43LIENT_PING\x10\x43\x12\x0f\n\x0b\x43LIENT_PONG\x10\x44\x12\x10\n\x0c\x43LIENT_ABORT\x10jB\t\n\x07variantBj\n\x13\x63om.geeksville.meshB\x15StoreAndForwardProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3')
_globals = globals()
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.protobuf.storeforward_pb2', _globals)
if _descriptor._USE_C_DESCRIPTORS == False:
DESCRIPTOR._options = None
DESCRIPTOR._serialized_options = b'\n\024org.meshtastic.protoB\025StoreAndForwardProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000'
DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\025StoreAndForwardProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000'
_globals['_STOREANDFORWARD']._serialized_start=64
_globals['_STOREANDFORWARD']._serialized_end=1024
_globals['_STOREANDFORWARD_STATISTICS']._serialized_start=366

View File

File diff suppressed because one or more lines are too long

View File

@@ -167,46 +167,6 @@ class _TelemetrySensorTypeEnumTypeWrapper(google.protobuf.internal.enum_type_wra
"""
DFRobot Gravity tipping bucket rain gauge
"""
DPS310: _TelemetrySensorType.ValueType # 36
"""
Infineon DPS310 High accuracy pressure and temperature
"""
RAK12035: _TelemetrySensorType.ValueType # 37
"""
RAKWireless RAK12035 Soil Moisture Sensor Module
"""
MAX17261: _TelemetrySensorType.ValueType # 38
"""
MAX17261 lipo battery gauge
"""
PCT2075: _TelemetrySensorType.ValueType # 39
"""
PCT2075 Temperature Sensor
"""
ADS1X15: _TelemetrySensorType.ValueType # 40
"""
ADS1X15 ADC
"""
ADS1X15_ALT: _TelemetrySensorType.ValueType # 41
"""
ADS1X15 ADC_ALT
"""
SFA30: _TelemetrySensorType.ValueType # 42
"""
Sensirion SFA30 Formaldehyde sensor
"""
SEN5X: _TelemetrySensorType.ValueType # 43
"""
SEN5X PM SENSORS
"""
TSL2561: _TelemetrySensorType.ValueType # 44
"""
TSL2561 light sensor
"""
BH1750: _TelemetrySensorType.ValueType # 45
"""
BH1750 light sensor
"""
class TelemetrySensorType(_TelemetrySensorType, metaclass=_TelemetrySensorTypeEnumTypeWrapper):
"""
@@ -357,46 +317,6 @@ DFROBOT_RAIN: TelemetrySensorType.ValueType # 35
"""
DFRobot Gravity tipping bucket rain gauge
"""
DPS310: TelemetrySensorType.ValueType # 36
"""
Infineon DPS310 High accuracy pressure and temperature
"""
RAK12035: TelemetrySensorType.ValueType # 37
"""
RAKWireless RAK12035 Soil Moisture Sensor Module
"""
MAX17261: TelemetrySensorType.ValueType # 38
"""
MAX17261 lipo battery gauge
"""
PCT2075: TelemetrySensorType.ValueType # 39
"""
PCT2075 Temperature Sensor
"""
ADS1X15: TelemetrySensorType.ValueType # 40
"""
ADS1X15 ADC
"""
ADS1X15_ALT: TelemetrySensorType.ValueType # 41
"""
ADS1X15 ADC_ALT
"""
SFA30: TelemetrySensorType.ValueType # 42
"""
Sensirion SFA30 Formaldehyde sensor
"""
SEN5X: TelemetrySensorType.ValueType # 43
"""
SEN5X PM SENSORS
"""
TSL2561: TelemetrySensorType.ValueType # 44
"""
TSL2561 light sensor
"""
BH1750: TelemetrySensorType.ValueType # 45
"""
BH1750 light sensor
"""
global___TelemetrySensorType = TelemetrySensorType
@typing.final
@@ -484,8 +404,6 @@ class EnvironmentMetrics(google.protobuf.message.Message):
RADIATION_FIELD_NUMBER: builtins.int
RAINFALL_1H_FIELD_NUMBER: builtins.int
RAINFALL_24H_FIELD_NUMBER: builtins.int
SOIL_MOISTURE_FIELD_NUMBER: builtins.int
SOIL_TEMPERATURE_FIELD_NUMBER: builtins.int
temperature: builtins.float
"""
Temperature measured
@@ -568,14 +486,6 @@ class EnvironmentMetrics(google.protobuf.message.Message):
"""
Rainfall in the last 24 hours in mm
"""
soil_moisture: builtins.int
"""
Soil moisture measured (% 1-100)
"""
soil_temperature: builtins.float
"""
Soil temperature measured (*C)
"""
def __init__(
self,
*,
@@ -599,11 +509,9 @@ class EnvironmentMetrics(google.protobuf.message.Message):
radiation: builtins.float | None = ...,
rainfall_1h: builtins.float | None = ...,
rainfall_24h: builtins.float | None = ...,
soil_moisture: builtins.int | None = ...,
soil_temperature: builtins.float | None = ...,
) -> None: ...
def HasField(self, field_name: typing.Literal["_barometric_pressure", b"_barometric_pressure", "_current", b"_current", "_distance", b"_distance", "_gas_resistance", b"_gas_resistance", "_iaq", b"_iaq", "_ir_lux", b"_ir_lux", "_lux", b"_lux", "_radiation", b"_radiation", "_rainfall_1h", b"_rainfall_1h", "_rainfall_24h", b"_rainfall_24h", "_relative_humidity", b"_relative_humidity", "_soil_moisture", b"_soil_moisture", "_soil_temperature", b"_soil_temperature", "_temperature", b"_temperature", "_uv_lux", b"_uv_lux", "_voltage", b"_voltage", "_weight", b"_weight", "_white_lux", b"_white_lux", "_wind_direction", b"_wind_direction", "_wind_gust", b"_wind_gust", "_wind_lull", b"_wind_lull", "_wind_speed", b"_wind_speed", "barometric_pressure", b"barometric_pressure", "current", b"current", "distance", b"distance", "gas_resistance", b"gas_resistance", "iaq", b"iaq", "ir_lux", b"ir_lux", "lux", b"lux", "radiation", b"radiation", "rainfall_1h", b"rainfall_1h", "rainfall_24h", b"rainfall_24h", "relative_humidity", b"relative_humidity", "soil_moisture", b"soil_moisture", "soil_temperature", b"soil_temperature", "temperature", b"temperature", "uv_lux", b"uv_lux", "voltage", b"voltage", "weight", b"weight", "white_lux", b"white_lux", "wind_direction", b"wind_direction", "wind_gust", b"wind_gust", "wind_lull", b"wind_lull", "wind_speed", b"wind_speed"]) -> builtins.bool: ...
def ClearField(self, field_name: typing.Literal["_barometric_pressure", b"_barometric_pressure", "_current", b"_current", "_distance", b"_distance", "_gas_resistance", b"_gas_resistance", "_iaq", b"_iaq", "_ir_lux", b"_ir_lux", "_lux", b"_lux", "_radiation", b"_radiation", "_rainfall_1h", b"_rainfall_1h", "_rainfall_24h", b"_rainfall_24h", "_relative_humidity", b"_relative_humidity", "_soil_moisture", b"_soil_moisture", "_soil_temperature", b"_soil_temperature", "_temperature", b"_temperature", "_uv_lux", b"_uv_lux", "_voltage", b"_voltage", "_weight", b"_weight", "_white_lux", b"_white_lux", "_wind_direction", b"_wind_direction", "_wind_gust", b"_wind_gust", "_wind_lull", b"_wind_lull", "_wind_speed", b"_wind_speed", "barometric_pressure", b"barometric_pressure", "current", b"current", "distance", b"distance", "gas_resistance", b"gas_resistance", "iaq", b"iaq", "ir_lux", b"ir_lux", "lux", b"lux", "radiation", b"radiation", "rainfall_1h", b"rainfall_1h", "rainfall_24h", b"rainfall_24h", "relative_humidity", b"relative_humidity", "soil_moisture", b"soil_moisture", "soil_temperature", b"soil_temperature", "temperature", b"temperature", "uv_lux", b"uv_lux", "voltage", b"voltage", "weight", b"weight", "white_lux", b"white_lux", "wind_direction", b"wind_direction", "wind_gust", b"wind_gust", "wind_lull", b"wind_lull", "wind_speed", b"wind_speed"]) -> None: ...
def HasField(self, field_name: typing.Literal["_barometric_pressure", b"_barometric_pressure", "_current", b"_current", "_distance", b"_distance", "_gas_resistance", b"_gas_resistance", "_iaq", b"_iaq", "_ir_lux", b"_ir_lux", "_lux", b"_lux", "_radiation", b"_radiation", "_rainfall_1h", b"_rainfall_1h", "_rainfall_24h", b"_rainfall_24h", "_relative_humidity", b"_relative_humidity", "_temperature", b"_temperature", "_uv_lux", b"_uv_lux", "_voltage", b"_voltage", "_weight", b"_weight", "_white_lux", b"_white_lux", "_wind_direction", b"_wind_direction", "_wind_gust", b"_wind_gust", "_wind_lull", b"_wind_lull", "_wind_speed", b"_wind_speed", "barometric_pressure", b"barometric_pressure", "current", b"current", "distance", b"distance", "gas_resistance", b"gas_resistance", "iaq", b"iaq", "ir_lux", b"ir_lux", "lux", b"lux", "radiation", b"radiation", "rainfall_1h", b"rainfall_1h", "rainfall_24h", b"rainfall_24h", "relative_humidity", b"relative_humidity", "temperature", b"temperature", "uv_lux", b"uv_lux", "voltage", b"voltage", "weight", b"weight", "white_lux", b"white_lux", "wind_direction", b"wind_direction", "wind_gust", b"wind_gust", "wind_lull", b"wind_lull", "wind_speed", b"wind_speed"]) -> builtins.bool: ...
def ClearField(self, field_name: typing.Literal["_barometric_pressure", b"_barometric_pressure", "_current", b"_current", "_distance", b"_distance", "_gas_resistance", b"_gas_resistance", "_iaq", b"_iaq", "_ir_lux", b"_ir_lux", "_lux", b"_lux", "_radiation", b"_radiation", "_rainfall_1h", b"_rainfall_1h", "_rainfall_24h", b"_rainfall_24h", "_relative_humidity", b"_relative_humidity", "_temperature", b"_temperature", "_uv_lux", b"_uv_lux", "_voltage", b"_voltage", "_weight", b"_weight", "_white_lux", b"_white_lux", "_wind_direction", b"_wind_direction", "_wind_gust", b"_wind_gust", "_wind_lull", b"_wind_lull", "_wind_speed", b"_wind_speed", "barometric_pressure", b"barometric_pressure", "current", b"current", "distance", b"distance", "gas_resistance", b"gas_resistance", "iaq", b"iaq", "ir_lux", b"ir_lux", "lux", b"lux", "radiation", b"radiation", "rainfall_1h", b"rainfall_1h", "rainfall_24h", b"rainfall_24h", "relative_humidity", b"relative_humidity", "temperature", b"temperature", "uv_lux", b"uv_lux", "voltage", b"voltage", "weight", b"weight", "white_lux", b"white_lux", "wind_direction", b"wind_direction", "wind_gust", b"wind_gust", "wind_lull", b"wind_lull", "wind_speed", b"wind_speed"]) -> None: ...
@typing.overload
def WhichOneof(self, oneof_group: typing.Literal["_barometric_pressure", b"_barometric_pressure"]) -> typing.Literal["barometric_pressure"] | None: ...
@typing.overload
@@ -627,10 +535,6 @@ class EnvironmentMetrics(google.protobuf.message.Message):
@typing.overload
def WhichOneof(self, oneof_group: typing.Literal["_relative_humidity", b"_relative_humidity"]) -> typing.Literal["relative_humidity"] | None: ...
@typing.overload
def WhichOneof(self, oneof_group: typing.Literal["_soil_moisture", b"_soil_moisture"]) -> typing.Literal["soil_moisture"] | None: ...
@typing.overload
def WhichOneof(self, oneof_group: typing.Literal["_soil_temperature", b"_soil_temperature"]) -> typing.Literal["soil_temperature"] | None: ...
@typing.overload
def WhichOneof(self, oneof_group: typing.Literal["_temperature", b"_temperature"]) -> typing.Literal["temperature"] | None: ...
@typing.overload
def WhichOneof(self, oneof_group: typing.Literal["_uv_lux", b"_uv_lux"]) -> typing.Literal["uv_lux"] | None: ...
@@ -665,16 +569,6 @@ class PowerMetrics(google.protobuf.message.Message):
CH2_CURRENT_FIELD_NUMBER: builtins.int
CH3_VOLTAGE_FIELD_NUMBER: builtins.int
CH3_CURRENT_FIELD_NUMBER: builtins.int
CH4_VOLTAGE_FIELD_NUMBER: builtins.int
CH4_CURRENT_FIELD_NUMBER: builtins.int
CH5_VOLTAGE_FIELD_NUMBER: builtins.int
CH5_CURRENT_FIELD_NUMBER: builtins.int
CH6_VOLTAGE_FIELD_NUMBER: builtins.int
CH6_CURRENT_FIELD_NUMBER: builtins.int
CH7_VOLTAGE_FIELD_NUMBER: builtins.int
CH7_CURRENT_FIELD_NUMBER: builtins.int
CH8_VOLTAGE_FIELD_NUMBER: builtins.int
CH8_CURRENT_FIELD_NUMBER: builtins.int
ch1_voltage: builtins.float
"""
Voltage (Ch1)
@@ -699,46 +593,6 @@ class PowerMetrics(google.protobuf.message.Message):
"""
Current (Ch3)
"""
ch4_voltage: builtins.float
"""
Voltage (Ch4)
"""
ch4_current: builtins.float
"""
Current (Ch4)
"""
ch5_voltage: builtins.float
"""
Voltage (Ch5)
"""
ch5_current: builtins.float
"""
Current (Ch5)
"""
ch6_voltage: builtins.float
"""
Voltage (Ch6)
"""
ch6_current: builtins.float
"""
Current (Ch6)
"""
ch7_voltage: builtins.float
"""
Voltage (Ch7)
"""
ch7_current: builtins.float
"""
Current (Ch7)
"""
ch8_voltage: builtins.float
"""
Voltage (Ch8)
"""
ch8_current: builtins.float
"""
Current (Ch8)
"""
def __init__(
self,
*,
@@ -748,19 +602,9 @@ class PowerMetrics(google.protobuf.message.Message):
ch2_current: builtins.float | None = ...,
ch3_voltage: builtins.float | None = ...,
ch3_current: builtins.float | None = ...,
ch4_voltage: builtins.float | None = ...,
ch4_current: builtins.float | None = ...,
ch5_voltage: builtins.float | None = ...,
ch5_current: builtins.float | None = ...,
ch6_voltage: builtins.float | None = ...,
ch6_current: builtins.float | None = ...,
ch7_voltage: builtins.float | None = ...,
ch7_current: builtins.float | None = ...,
ch8_voltage: builtins.float | None = ...,
ch8_current: builtins.float | None = ...,
) -> None: ...
def HasField(self, field_name: typing.Literal["_ch1_current", b"_ch1_current", "_ch1_voltage", b"_ch1_voltage", "_ch2_current", b"_ch2_current", "_ch2_voltage", b"_ch2_voltage", "_ch3_current", b"_ch3_current", "_ch3_voltage", b"_ch3_voltage", "_ch4_current", b"_ch4_current", "_ch4_voltage", b"_ch4_voltage", "_ch5_current", b"_ch5_current", "_ch5_voltage", b"_ch5_voltage", "_ch6_current", b"_ch6_current", "_ch6_voltage", b"_ch6_voltage", "_ch7_current", b"_ch7_current", "_ch7_voltage", b"_ch7_voltage", "_ch8_current", b"_ch8_current", "_ch8_voltage", b"_ch8_voltage", "ch1_current", b"ch1_current", "ch1_voltage", b"ch1_voltage", "ch2_current", b"ch2_current", "ch2_voltage", b"ch2_voltage", "ch3_current", b"ch3_current", "ch3_voltage", b"ch3_voltage", "ch4_current", b"ch4_current", "ch4_voltage", b"ch4_voltage", "ch5_current", b"ch5_current", "ch5_voltage", b"ch5_voltage", "ch6_current", b"ch6_current", "ch6_voltage", b"ch6_voltage", "ch7_current", b"ch7_current", "ch7_voltage", b"ch7_voltage", "ch8_current", b"ch8_current", "ch8_voltage", b"ch8_voltage"]) -> builtins.bool: ...
def ClearField(self, field_name: typing.Literal["_ch1_current", b"_ch1_current", "_ch1_voltage", b"_ch1_voltage", "_ch2_current", b"_ch2_current", "_ch2_voltage", b"_ch2_voltage", "_ch3_current", b"_ch3_current", "_ch3_voltage", b"_ch3_voltage", "_ch4_current", b"_ch4_current", "_ch4_voltage", b"_ch4_voltage", "_ch5_current", b"_ch5_current", "_ch5_voltage", b"_ch5_voltage", "_ch6_current", b"_ch6_current", "_ch6_voltage", b"_ch6_voltage", "_ch7_current", b"_ch7_current", "_ch7_voltage", b"_ch7_voltage", "_ch8_current", b"_ch8_current", "_ch8_voltage", b"_ch8_voltage", "ch1_current", b"ch1_current", "ch1_voltage", b"ch1_voltage", "ch2_current", b"ch2_current", "ch2_voltage", b"ch2_voltage", "ch3_current", b"ch3_current", "ch3_voltage", b"ch3_voltage", "ch4_current", b"ch4_current", "ch4_voltage", b"ch4_voltage", "ch5_current", b"ch5_current", "ch5_voltage", b"ch5_voltage", "ch6_current", b"ch6_current", "ch6_voltage", b"ch6_voltage", "ch7_current", b"ch7_current", "ch7_voltage", b"ch7_voltage", "ch8_current", b"ch8_current", "ch8_voltage", b"ch8_voltage"]) -> None: ...
def HasField(self, field_name: typing.Literal["_ch1_current", b"_ch1_current", "_ch1_voltage", b"_ch1_voltage", "_ch2_current", b"_ch2_current", "_ch2_voltage", b"_ch2_voltage", "_ch3_current", b"_ch3_current", "_ch3_voltage", b"_ch3_voltage", "ch1_current", b"ch1_current", "ch1_voltage", b"ch1_voltage", "ch2_current", b"ch2_current", "ch2_voltage", b"ch2_voltage", "ch3_current", b"ch3_current", "ch3_voltage", b"ch3_voltage"]) -> builtins.bool: ...
def ClearField(self, field_name: typing.Literal["_ch1_current", b"_ch1_current", "_ch1_voltage", b"_ch1_voltage", "_ch2_current", b"_ch2_current", "_ch2_voltage", b"_ch2_voltage", "_ch3_current", b"_ch3_current", "_ch3_voltage", b"_ch3_voltage", "ch1_current", b"ch1_current", "ch1_voltage", b"ch1_voltage", "ch2_current", b"ch2_current", "ch2_voltage", b"ch2_voltage", "ch3_current", b"ch3_current", "ch3_voltage", b"ch3_voltage"]) -> None: ...
@typing.overload
def WhichOneof(self, oneof_group: typing.Literal["_ch1_current", b"_ch1_current"]) -> typing.Literal["ch1_current"] | None: ...
@typing.overload
@@ -773,26 +617,6 @@ class PowerMetrics(google.protobuf.message.Message):
def WhichOneof(self, oneof_group: typing.Literal["_ch3_current", b"_ch3_current"]) -> typing.Literal["ch3_current"] | None: ...
@typing.overload
def WhichOneof(self, oneof_group: typing.Literal["_ch3_voltage", b"_ch3_voltage"]) -> typing.Literal["ch3_voltage"] | None: ...
@typing.overload
def WhichOneof(self, oneof_group: typing.Literal["_ch4_current", b"_ch4_current"]) -> typing.Literal["ch4_current"] | None: ...
@typing.overload
def WhichOneof(self, oneof_group: typing.Literal["_ch4_voltage", b"_ch4_voltage"]) -> typing.Literal["ch4_voltage"] | None: ...
@typing.overload
def WhichOneof(self, oneof_group: typing.Literal["_ch5_current", b"_ch5_current"]) -> typing.Literal["ch5_current"] | None: ...
@typing.overload
def WhichOneof(self, oneof_group: typing.Literal["_ch5_voltage", b"_ch5_voltage"]) -> typing.Literal["ch5_voltage"] | None: ...
@typing.overload
def WhichOneof(self, oneof_group: typing.Literal["_ch6_current", b"_ch6_current"]) -> typing.Literal["ch6_current"] | None: ...
@typing.overload
def WhichOneof(self, oneof_group: typing.Literal["_ch6_voltage", b"_ch6_voltage"]) -> typing.Literal["ch6_voltage"] | None: ...
@typing.overload
def WhichOneof(self, oneof_group: typing.Literal["_ch7_current", b"_ch7_current"]) -> typing.Literal["ch7_current"] | None: ...
@typing.overload
def WhichOneof(self, oneof_group: typing.Literal["_ch7_voltage", b"_ch7_voltage"]) -> typing.Literal["ch7_voltage"] | None: ...
@typing.overload
def WhichOneof(self, oneof_group: typing.Literal["_ch8_current", b"_ch8_current"]) -> typing.Literal["ch8_current"] | None: ...
@typing.overload
def WhichOneof(self, oneof_group: typing.Literal["_ch8_voltage", b"_ch8_voltage"]) -> typing.Literal["ch8_voltage"] | None: ...
global___PowerMetrics = PowerMetrics
@@ -817,117 +641,57 @@ class AirQualityMetrics(google.protobuf.message.Message):
PARTICLES_50UM_FIELD_NUMBER: builtins.int
PARTICLES_100UM_FIELD_NUMBER: builtins.int
CO2_FIELD_NUMBER: builtins.int
CO2_TEMPERATURE_FIELD_NUMBER: builtins.int
CO2_HUMIDITY_FIELD_NUMBER: builtins.int
FORM_FORMALDEHYDE_FIELD_NUMBER: builtins.int
FORM_HUMIDITY_FIELD_NUMBER: builtins.int
FORM_TEMPERATURE_FIELD_NUMBER: builtins.int
PM40_STANDARD_FIELD_NUMBER: builtins.int
PARTICLES_40UM_FIELD_NUMBER: builtins.int
PM_TEMPERATURE_FIELD_NUMBER: builtins.int
PM_HUMIDITY_FIELD_NUMBER: builtins.int
PM_VOC_IDX_FIELD_NUMBER: builtins.int
PM_NOX_IDX_FIELD_NUMBER: builtins.int
PARTICLES_TPS_FIELD_NUMBER: builtins.int
pm10_standard: builtins.int
"""
Concentration Units Standard PM1.0 in ug/m3
Concentration Units Standard PM1.0
"""
pm25_standard: builtins.int
"""
Concentration Units Standard PM2.5 in ug/m3
Concentration Units Standard PM2.5
"""
pm100_standard: builtins.int
"""
Concentration Units Standard PM10.0 in ug/m3
Concentration Units Standard PM10.0
"""
pm10_environmental: builtins.int
"""
Concentration Units Environmental PM1.0 in ug/m3
Concentration Units Environmental PM1.0
"""
pm25_environmental: builtins.int
"""
Concentration Units Environmental PM2.5 in ug/m3
Concentration Units Environmental PM2.5
"""
pm100_environmental: builtins.int
"""
Concentration Units Environmental PM10.0 in ug/m3
Concentration Units Environmental PM10.0
"""
particles_03um: builtins.int
"""
0.3um Particle Count in #/0.1l
0.3um Particle Count
"""
particles_05um: builtins.int
"""
0.5um Particle Count in #/0.1l
0.5um Particle Count
"""
particles_10um: builtins.int
"""
1.0um Particle Count in #/0.1l
1.0um Particle Count
"""
particles_25um: builtins.int
"""
2.5um Particle Count in #/0.1l
2.5um Particle Count
"""
particles_50um: builtins.int
"""
5.0um Particle Count in #/0.1l
5.0um Particle Count
"""
particles_100um: builtins.int
"""
10.0um Particle Count in #/0.1l
10.0um Particle Count
"""
co2: builtins.int
"""
CO2 concentration in ppm
"""
co2_temperature: builtins.float
"""
CO2 sensor temperature in degC
"""
co2_humidity: builtins.float
"""
CO2 sensor relative humidity in %
"""
form_formaldehyde: builtins.float
"""
Formaldehyde sensor formaldehyde concentration in ppb
"""
form_humidity: builtins.float
"""
Formaldehyde sensor relative humidity in %RH
"""
form_temperature: builtins.float
"""
Formaldehyde sensor temperature in degrees Celsius
"""
pm40_standard: builtins.int
"""
Concentration Units Standard PM4.0 in ug/m3
"""
particles_40um: builtins.int
"""
4.0um Particle Count in #/0.1l
"""
pm_temperature: builtins.float
"""
PM Sensor Temperature
"""
pm_humidity: builtins.float
"""
PM Sensor humidity
"""
pm_voc_idx: builtins.float
"""
PM Sensor VOC Index
"""
pm_nox_idx: builtins.float
"""
PM Sensor NOx Index
"""
particles_tps: builtins.float
"""
Typical Particle Size in um
10.0um Particle Count
"""
def __init__(
self,
@@ -945,34 +709,12 @@ class AirQualityMetrics(google.protobuf.message.Message):
particles_50um: builtins.int | None = ...,
particles_100um: builtins.int | None = ...,
co2: builtins.int | None = ...,
co2_temperature: builtins.float | None = ...,
co2_humidity: builtins.float | None = ...,
form_formaldehyde: builtins.float | None = ...,
form_humidity: builtins.float | None = ...,
form_temperature: builtins.float | None = ...,
pm40_standard: builtins.int | None = ...,
particles_40um: builtins.int | None = ...,
pm_temperature: builtins.float | None = ...,
pm_humidity: builtins.float | None = ...,
pm_voc_idx: builtins.float | None = ...,
pm_nox_idx: builtins.float | None = ...,
particles_tps: builtins.float | None = ...,
) -> None: ...
def HasField(self, field_name: typing.Literal["_co2", b"_co2", "_co2_humidity", b"_co2_humidity", "_co2_temperature", b"_co2_temperature", "_form_formaldehyde", b"_form_formaldehyde", "_form_humidity", b"_form_humidity", "_form_temperature", b"_form_temperature", "_particles_03um", b"_particles_03um", "_particles_05um", b"_particles_05um", "_particles_100um", b"_particles_100um", "_particles_10um", b"_particles_10um", "_particles_25um", b"_particles_25um", "_particles_40um", b"_particles_40um", "_particles_50um", b"_particles_50um", "_particles_tps", b"_particles_tps", "_pm100_environmental", b"_pm100_environmental", "_pm100_standard", b"_pm100_standard", "_pm10_environmental", b"_pm10_environmental", "_pm10_standard", b"_pm10_standard", "_pm25_environmental", b"_pm25_environmental", "_pm25_standard", b"_pm25_standard", "_pm40_standard", b"_pm40_standard", "_pm_humidity", b"_pm_humidity", "_pm_nox_idx", b"_pm_nox_idx", "_pm_temperature", b"_pm_temperature", "_pm_voc_idx", b"_pm_voc_idx", "co2", b"co2", "co2_humidity", b"co2_humidity", "co2_temperature", b"co2_temperature", "form_formaldehyde", b"form_formaldehyde", "form_humidity", b"form_humidity", "form_temperature", b"form_temperature", "particles_03um", b"particles_03um", "particles_05um", b"particles_05um", "particles_100um", b"particles_100um", "particles_10um", b"particles_10um", "particles_25um", b"particles_25um", "particles_40um", b"particles_40um", "particles_50um", b"particles_50um", "particles_tps", b"particles_tps", "pm100_environmental", b"pm100_environmental", "pm100_standard", b"pm100_standard", "pm10_environmental", b"pm10_environmental", "pm10_standard", b"pm10_standard", "pm25_environmental", b"pm25_environmental", "pm25_standard", b"pm25_standard", "pm40_standard", b"pm40_standard", "pm_humidity", b"pm_humidity", "pm_nox_idx", b"pm_nox_idx", "pm_temperature", b"pm_temperature", "pm_voc_idx", b"pm_voc_idx"]) -> builtins.bool: ...
def ClearField(self, field_name: typing.Literal["_co2", b"_co2", "_co2_humidity", b"_co2_humidity", "_co2_temperature", b"_co2_temperature", "_form_formaldehyde", b"_form_formaldehyde", "_form_humidity", b"_form_humidity", "_form_temperature", b"_form_temperature", "_particles_03um", b"_particles_03um", "_particles_05um", b"_particles_05um", "_particles_100um", b"_particles_100um", "_particles_10um", b"_particles_10um", "_particles_25um", b"_particles_25um", "_particles_40um", b"_particles_40um", "_particles_50um", b"_particles_50um", "_particles_tps", b"_particles_tps", "_pm100_environmental", b"_pm100_environmental", "_pm100_standard", b"_pm100_standard", "_pm10_environmental", b"_pm10_environmental", "_pm10_standard", b"_pm10_standard", "_pm25_environmental", b"_pm25_environmental", "_pm25_standard", b"_pm25_standard", "_pm40_standard", b"_pm40_standard", "_pm_humidity", b"_pm_humidity", "_pm_nox_idx", b"_pm_nox_idx", "_pm_temperature", b"_pm_temperature", "_pm_voc_idx", b"_pm_voc_idx", "co2", b"co2", "co2_humidity", b"co2_humidity", "co2_temperature", b"co2_temperature", "form_formaldehyde", b"form_formaldehyde", "form_humidity", b"form_humidity", "form_temperature", b"form_temperature", "particles_03um", b"particles_03um", "particles_05um", b"particles_05um", "particles_100um", b"particles_100um", "particles_10um", b"particles_10um", "particles_25um", b"particles_25um", "particles_40um", b"particles_40um", "particles_50um", b"particles_50um", "particles_tps", b"particles_tps", "pm100_environmental", b"pm100_environmental", "pm100_standard", b"pm100_standard", "pm10_environmental", b"pm10_environmental", "pm10_standard", b"pm10_standard", "pm25_environmental", b"pm25_environmental", "pm25_standard", b"pm25_standard", "pm40_standard", b"pm40_standard", "pm_humidity", b"pm_humidity", "pm_nox_idx", b"pm_nox_idx", "pm_temperature", b"pm_temperature", "pm_voc_idx", b"pm_voc_idx"]) -> None: ...
def HasField(self, field_name: typing.Literal["_co2", b"_co2", "_particles_03um", b"_particles_03um", "_particles_05um", b"_particles_05um", "_particles_100um", b"_particles_100um", "_particles_10um", b"_particles_10um", "_particles_25um", b"_particles_25um", "_particles_50um", b"_particles_50um", "_pm100_environmental", b"_pm100_environmental", "_pm100_standard", b"_pm100_standard", "_pm10_environmental", b"_pm10_environmental", "_pm10_standard", b"_pm10_standard", "_pm25_environmental", b"_pm25_environmental", "_pm25_standard", b"_pm25_standard", "co2", b"co2", "particles_03um", b"particles_03um", "particles_05um", b"particles_05um", "particles_100um", b"particles_100um", "particles_10um", b"particles_10um", "particles_25um", b"particles_25um", "particles_50um", b"particles_50um", "pm100_environmental", b"pm100_environmental", "pm100_standard", b"pm100_standard", "pm10_environmental", b"pm10_environmental", "pm10_standard", b"pm10_standard", "pm25_environmental", b"pm25_environmental", "pm25_standard", b"pm25_standard"]) -> builtins.bool: ...
def ClearField(self, field_name: typing.Literal["_co2", b"_co2", "_particles_03um", b"_particles_03um", "_particles_05um", b"_particles_05um", "_particles_100um", b"_particles_100um", "_particles_10um", b"_particles_10um", "_particles_25um", b"_particles_25um", "_particles_50um", b"_particles_50um", "_pm100_environmental", b"_pm100_environmental", "_pm100_standard", b"_pm100_standard", "_pm10_environmental", b"_pm10_environmental", "_pm10_standard", b"_pm10_standard", "_pm25_environmental", b"_pm25_environmental", "_pm25_standard", b"_pm25_standard", "co2", b"co2", "particles_03um", b"particles_03um", "particles_05um", b"particles_05um", "particles_100um", b"particles_100um", "particles_10um", b"particles_10um", "particles_25um", b"particles_25um", "particles_50um", b"particles_50um", "pm100_environmental", b"pm100_environmental", "pm100_standard", b"pm100_standard", "pm10_environmental", b"pm10_environmental", "pm10_standard", b"pm10_standard", "pm25_environmental", b"pm25_environmental", "pm25_standard", b"pm25_standard"]) -> None: ...
@typing.overload
def WhichOneof(self, oneof_group: typing.Literal["_co2", b"_co2"]) -> typing.Literal["co2"] | None: ...
@typing.overload
def WhichOneof(self, oneof_group: typing.Literal["_co2_humidity", b"_co2_humidity"]) -> typing.Literal["co2_humidity"] | None: ...
@typing.overload
def WhichOneof(self, oneof_group: typing.Literal["_co2_temperature", b"_co2_temperature"]) -> typing.Literal["co2_temperature"] | None: ...
@typing.overload
def WhichOneof(self, oneof_group: typing.Literal["_form_formaldehyde", b"_form_formaldehyde"]) -> typing.Literal["form_formaldehyde"] | None: ...
@typing.overload
def WhichOneof(self, oneof_group: typing.Literal["_form_humidity", b"_form_humidity"]) -> typing.Literal["form_humidity"] | None: ...
@typing.overload
def WhichOneof(self, oneof_group: typing.Literal["_form_temperature", b"_form_temperature"]) -> typing.Literal["form_temperature"] | None: ...
@typing.overload
def WhichOneof(self, oneof_group: typing.Literal["_particles_03um", b"_particles_03um"]) -> typing.Literal["particles_03um"] | None: ...
@typing.overload
def WhichOneof(self, oneof_group: typing.Literal["_particles_05um", b"_particles_05um"]) -> typing.Literal["particles_05um"] | None: ...
@@ -983,12 +725,8 @@ class AirQualityMetrics(google.protobuf.message.Message):
@typing.overload
def WhichOneof(self, oneof_group: typing.Literal["_particles_25um", b"_particles_25um"]) -> typing.Literal["particles_25um"] | None: ...
@typing.overload
def WhichOneof(self, oneof_group: typing.Literal["_particles_40um", b"_particles_40um"]) -> typing.Literal["particles_40um"] | None: ...
@typing.overload
def WhichOneof(self, oneof_group: typing.Literal["_particles_50um", b"_particles_50um"]) -> typing.Literal["particles_50um"] | None: ...
@typing.overload
def WhichOneof(self, oneof_group: typing.Literal["_particles_tps", b"_particles_tps"]) -> typing.Literal["particles_tps"] | None: ...
@typing.overload
def WhichOneof(self, oneof_group: typing.Literal["_pm100_environmental", b"_pm100_environmental"]) -> typing.Literal["pm100_environmental"] | None: ...
@typing.overload
def WhichOneof(self, oneof_group: typing.Literal["_pm100_standard", b"_pm100_standard"]) -> typing.Literal["pm100_standard"] | None: ...
@@ -1000,16 +738,6 @@ class AirQualityMetrics(google.protobuf.message.Message):
def WhichOneof(self, oneof_group: typing.Literal["_pm25_environmental", b"_pm25_environmental"]) -> typing.Literal["pm25_environmental"] | None: ...
@typing.overload
def WhichOneof(self, oneof_group: typing.Literal["_pm25_standard", b"_pm25_standard"]) -> typing.Literal["pm25_standard"] | None: ...
@typing.overload
def WhichOneof(self, oneof_group: typing.Literal["_pm40_standard", b"_pm40_standard"]) -> typing.Literal["pm40_standard"] | None: ...
@typing.overload
def WhichOneof(self, oneof_group: typing.Literal["_pm_humidity", b"_pm_humidity"]) -> typing.Literal["pm_humidity"] | None: ...
@typing.overload
def WhichOneof(self, oneof_group: typing.Literal["_pm_nox_idx", b"_pm_nox_idx"]) -> typing.Literal["pm_nox_idx"] | None: ...
@typing.overload
def WhichOneof(self, oneof_group: typing.Literal["_pm_temperature", b"_pm_temperature"]) -> typing.Literal["pm_temperature"] | None: ...
@typing.overload
def WhichOneof(self, oneof_group: typing.Literal["_pm_voc_idx", b"_pm_voc_idx"]) -> typing.Literal["pm_voc_idx"] | None: ...
global___AirQualityMetrics = AirQualityMetrics
@@ -1032,9 +760,6 @@ class LocalStats(google.protobuf.message.Message):
NUM_RX_DUPE_FIELD_NUMBER: builtins.int
NUM_TX_RELAY_FIELD_NUMBER: builtins.int
NUM_TX_RELAY_CANCELED_FIELD_NUMBER: builtins.int
HEAP_TOTAL_BYTES_FIELD_NUMBER: builtins.int
HEAP_FREE_BYTES_FIELD_NUMBER: builtins.int
NUM_TX_DROPPED_FIELD_NUMBER: builtins.int
uptime_seconds: builtins.int
"""
How long the device has been running since the last reboot (in seconds)
@@ -1081,18 +806,6 @@ class LocalStats(google.protobuf.message.Message):
Number of times we canceled a packet to be relayed, because someone else did it before us.
This will always be zero for ROUTERs/REPEATERs. If this number is high, some other node(s) is/are relaying faster than you.
"""
heap_total_bytes: builtins.int
"""
Number of bytes used in the heap
"""
heap_free_bytes: builtins.int
"""
Number of bytes free in the heap
"""
num_tx_dropped: builtins.int
"""
Number of packets that were dropped because the transmit queue was full.
"""
def __init__(
self,
*,
@@ -1107,11 +820,8 @@ class LocalStats(google.protobuf.message.Message):
num_rx_dupe: builtins.int = ...,
num_tx_relay: builtins.int = ...,
num_tx_relay_canceled: builtins.int = ...,
heap_total_bytes: builtins.int = ...,
heap_free_bytes: builtins.int = ...,
num_tx_dropped: builtins.int = ...,
) -> None: ...
def ClearField(self, field_name: typing.Literal["air_util_tx", b"air_util_tx", "channel_utilization", b"channel_utilization", "heap_free_bytes", b"heap_free_bytes", "heap_total_bytes", b"heap_total_bytes", "num_online_nodes", b"num_online_nodes", "num_packets_rx", b"num_packets_rx", "num_packets_rx_bad", b"num_packets_rx_bad", "num_packets_tx", b"num_packets_tx", "num_rx_dupe", b"num_rx_dupe", "num_total_nodes", b"num_total_nodes", "num_tx_dropped", b"num_tx_dropped", "num_tx_relay", b"num_tx_relay", "num_tx_relay_canceled", b"num_tx_relay_canceled", "uptime_seconds", b"uptime_seconds"]) -> None: ...
def ClearField(self, field_name: typing.Literal["air_util_tx", b"air_util_tx", "channel_utilization", b"channel_utilization", "num_online_nodes", b"num_online_nodes", "num_packets_rx", b"num_packets_rx", "num_packets_rx_bad", b"num_packets_rx_bad", "num_packets_tx", b"num_packets_tx", "num_rx_dupe", b"num_rx_dupe", "num_total_nodes", b"num_total_nodes", "num_tx_relay", b"num_tx_relay", "num_tx_relay_canceled", b"num_tx_relay_canceled", "uptime_seconds", b"uptime_seconds"]) -> None: ...
global___LocalStats = LocalStats
@@ -1156,84 +866,6 @@ class HealthMetrics(google.protobuf.message.Message):
global___HealthMetrics = HealthMetrics
@typing.final
class HostMetrics(google.protobuf.message.Message):
"""
Linux host metrics
"""
DESCRIPTOR: google.protobuf.descriptor.Descriptor
UPTIME_SECONDS_FIELD_NUMBER: builtins.int
FREEMEM_BYTES_FIELD_NUMBER: builtins.int
DISKFREE1_BYTES_FIELD_NUMBER: builtins.int
DISKFREE2_BYTES_FIELD_NUMBER: builtins.int
DISKFREE3_BYTES_FIELD_NUMBER: builtins.int
LOAD1_FIELD_NUMBER: builtins.int
LOAD5_FIELD_NUMBER: builtins.int
LOAD15_FIELD_NUMBER: builtins.int
USER_STRING_FIELD_NUMBER: builtins.int
uptime_seconds: builtins.int
"""
Host system uptime
"""
freemem_bytes: builtins.int
"""
Host system free memory
"""
diskfree1_bytes: builtins.int
"""
Host system disk space free for /
"""
diskfree2_bytes: builtins.int
"""
Secondary system disk space free
"""
diskfree3_bytes: builtins.int
"""
Tertiary disk space free
"""
load1: builtins.int
"""
Host system one minute load in 1/100ths
"""
load5: builtins.int
"""
Host system five minute load in 1/100ths
"""
load15: builtins.int
"""
Host system fifteen minute load in 1/100ths
"""
user_string: builtins.str
"""
Optional User-provided string for arbitrary host system information
that doesn't make sense as a dedicated entry.
"""
def __init__(
self,
*,
uptime_seconds: builtins.int = ...,
freemem_bytes: builtins.int = ...,
diskfree1_bytes: builtins.int = ...,
diskfree2_bytes: builtins.int | None = ...,
diskfree3_bytes: builtins.int | None = ...,
load1: builtins.int = ...,
load5: builtins.int = ...,
load15: builtins.int = ...,
user_string: builtins.str | None = ...,
) -> None: ...
def HasField(self, field_name: typing.Literal["_diskfree2_bytes", b"_diskfree2_bytes", "_diskfree3_bytes", b"_diskfree3_bytes", "_user_string", b"_user_string", "diskfree2_bytes", b"diskfree2_bytes", "diskfree3_bytes", b"diskfree3_bytes", "user_string", b"user_string"]) -> builtins.bool: ...
def ClearField(self, field_name: typing.Literal["_diskfree2_bytes", b"_diskfree2_bytes", "_diskfree3_bytes", b"_diskfree3_bytes", "_user_string", b"_user_string", "diskfree1_bytes", b"diskfree1_bytes", "diskfree2_bytes", b"diskfree2_bytes", "diskfree3_bytes", b"diskfree3_bytes", "freemem_bytes", b"freemem_bytes", "load1", b"load1", "load15", b"load15", "load5", b"load5", "uptime_seconds", b"uptime_seconds", "user_string", b"user_string"]) -> None: ...
@typing.overload
def WhichOneof(self, oneof_group: typing.Literal["_diskfree2_bytes", b"_diskfree2_bytes"]) -> typing.Literal["diskfree2_bytes"] | None: ...
@typing.overload
def WhichOneof(self, oneof_group: typing.Literal["_diskfree3_bytes", b"_diskfree3_bytes"]) -> typing.Literal["diskfree3_bytes"] | None: ...
@typing.overload
def WhichOneof(self, oneof_group: typing.Literal["_user_string", b"_user_string"]) -> typing.Literal["user_string"] | None: ...
global___HostMetrics = HostMetrics
@typing.final
class Telemetry(google.protobuf.message.Message):
"""
@@ -1249,7 +881,6 @@ class Telemetry(google.protobuf.message.Message):
POWER_METRICS_FIELD_NUMBER: builtins.int
LOCAL_STATS_FIELD_NUMBER: builtins.int
HEALTH_METRICS_FIELD_NUMBER: builtins.int
HOST_METRICS_FIELD_NUMBER: builtins.int
time: builtins.int
"""
Seconds since 1970 - or 0 for unknown/unset
@@ -1290,12 +921,6 @@ class Telemetry(google.protobuf.message.Message):
Health telemetry metrics
"""
@property
def host_metrics(self) -> global___HostMetrics:
"""
Linux host metrics
"""
def __init__(
self,
*,
@@ -1306,11 +931,10 @@ class Telemetry(google.protobuf.message.Message):
power_metrics: global___PowerMetrics | None = ...,
local_stats: global___LocalStats | None = ...,
health_metrics: global___HealthMetrics | None = ...,
host_metrics: global___HostMetrics | None = ...,
) -> None: ...
def HasField(self, field_name: typing.Literal["air_quality_metrics", b"air_quality_metrics", "device_metrics", b"device_metrics", "environment_metrics", b"environment_metrics", "health_metrics", b"health_metrics", "host_metrics", b"host_metrics", "local_stats", b"local_stats", "power_metrics", b"power_metrics", "variant", b"variant"]) -> builtins.bool: ...
def ClearField(self, field_name: typing.Literal["air_quality_metrics", b"air_quality_metrics", "device_metrics", b"device_metrics", "environment_metrics", b"environment_metrics", "health_metrics", b"health_metrics", "host_metrics", b"host_metrics", "local_stats", b"local_stats", "power_metrics", b"power_metrics", "time", b"time", "variant", b"variant"]) -> None: ...
def WhichOneof(self, oneof_group: typing.Literal["variant", b"variant"]) -> typing.Literal["device_metrics", "environment_metrics", "air_quality_metrics", "power_metrics", "local_stats", "health_metrics", "host_metrics"] | None: ...
def HasField(self, field_name: typing.Literal["air_quality_metrics", b"air_quality_metrics", "device_metrics", b"device_metrics", "environment_metrics", b"environment_metrics", "health_metrics", b"health_metrics", "local_stats", b"local_stats", "power_metrics", b"power_metrics", "variant", b"variant"]) -> builtins.bool: ...
def ClearField(self, field_name: typing.Literal["air_quality_metrics", b"air_quality_metrics", "device_metrics", b"device_metrics", "environment_metrics", b"environment_metrics", "health_metrics", b"health_metrics", "local_stats", b"local_stats", "power_metrics", b"power_metrics", "time", b"time", "variant", b"variant"]) -> None: ...
def WhichOneof(self, oneof_group: typing.Literal["variant", b"variant"]) -> typing.Literal["device_metrics", "environment_metrics", "air_quality_metrics", "power_metrics", "local_stats", "health_metrics"] | None: ...
global___Telemetry = Telemetry

View File

@@ -13,14 +13,14 @@ _sym_db = _symbol_database.Default()
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n meshtastic/protobuf/xmodem.proto\x12\x13meshtastic.protobuf\"\xbf\x01\n\x06XModem\x12\x34\n\x07\x63ontrol\x18\x01 \x01(\x0e\x32#.meshtastic.protobuf.XModem.Control\x12\x0b\n\x03seq\x18\x02 \x01(\r\x12\r\n\x05\x63rc16\x18\x03 \x01(\r\x12\x0e\n\x06\x62uffer\x18\x04 \x01(\x0c\"S\n\x07\x43ontrol\x12\x07\n\x03NUL\x10\x00\x12\x07\n\x03SOH\x10\x01\x12\x07\n\x03STX\x10\x02\x12\x07\n\x03\x45OT\x10\x04\x12\x07\n\x03\x41\x43K\x10\x06\x12\x07\n\x03NAK\x10\x15\x12\x07\n\x03\x43\x41N\x10\x18\x12\t\n\x05\x43TRLZ\x10\x1a\x42\x62\n\x14org.meshtastic.protoB\x0cXmodemProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3')
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n meshtastic/protobuf/xmodem.proto\x12\x13meshtastic.protobuf\"\xbf\x01\n\x06XModem\x12\x34\n\x07\x63ontrol\x18\x01 \x01(\x0e\x32#.meshtastic.protobuf.XModem.Control\x12\x0b\n\x03seq\x18\x02 \x01(\r\x12\r\n\x05\x63rc16\x18\x03 \x01(\r\x12\x0e\n\x06\x62uffer\x18\x04 \x01(\x0c\"S\n\x07\x43ontrol\x12\x07\n\x03NUL\x10\x00\x12\x07\n\x03SOH\x10\x01\x12\x07\n\x03STX\x10\x02\x12\x07\n\x03\x45OT\x10\x04\x12\x07\n\x03\x41\x43K\x10\x06\x12\x07\n\x03NAK\x10\x15\x12\x07\n\x03\x43\x41N\x10\x18\x12\t\n\x05\x43TRLZ\x10\x1a\x42\x61\n\x13\x63om.geeksville.meshB\x0cXmodemProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3')
_globals = globals()
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.protobuf.xmodem_pb2', _globals)
if _descriptor._USE_C_DESCRIPTORS == False:
DESCRIPTOR._options = None
DESCRIPTOR._serialized_options = b'\n\024org.meshtastic.protoB\014XmodemProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000'
DESCRIPTOR._serialized_options = b'\n\023com.geeksville.meshB\014XmodemProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000'
_globals['_XMODEM']._serialized_start=58
_globals['_XMODEM']._serialized_end=249
_globals['_XMODEM_CONTROL']._serialized_start=166

View File

@@ -7,11 +7,10 @@ from pubsub import pub # type: ignore[import-untyped]
from meshtastic.protobuf import portnums_pb2, remote_hardware_pb2
from meshtastic.util import our_exit
logger = logging.getLogger(__name__)
def onGPIOreceive(packet, interface) -> None:
"""Callback for received GPIO responses"""
logger.debug(f"packet:{packet} interface:{interface}")
logging.debug(f"packet:{packet} interface:{interface}")
gpioValue = 0
hw = packet["decoded"]["remotehw"]
if "gpioValue" in hw:
@@ -77,7 +76,7 @@ class RemoteHardwareClient:
Write the specified vals bits to the device GPIOs. Only bits in mask that
are 1 will be changed
"""
logger.debug(f"writeGPIOs nodeid:{nodeid} mask:{mask} vals:{vals}")
logging.debug(f"writeGPIOs nodeid:{nodeid} mask:{mask} vals:{vals}")
r = remote_hardware_pb2.HardwareMessage()
r.type = remote_hardware_pb2.HardwareMessage.Type.WRITE_GPIOS
r.gpio_mask = mask
@@ -86,7 +85,7 @@ class RemoteHardwareClient:
def readGPIOs(self, nodeid, mask, onResponse=None):
"""Read the specified bits from GPIO inputs on the device"""
logger.debug(f"readGPIOs nodeid:{nodeid} mask:{mask}")
logging.debug(f"readGPIOs nodeid:{nodeid} mask:{mask}")
r = remote_hardware_pb2.HardwareMessage()
r.type = remote_hardware_pb2.HardwareMessage.Type.READ_GPIOS
r.gpio_mask = mask
@@ -94,7 +93,7 @@ class RemoteHardwareClient:
def watchGPIOs(self, nodeid, mask):
"""Watch the specified bits from GPIO inputs on the device for changes"""
logger.debug(f"watchGPIOs nodeid:{nodeid} mask:{mask}")
logging.debug(f"watchGPIOs nodeid:{nodeid} mask:{mask}")
r = remote_hardware_pb2.HardwareMessage()
r.type = remote_hardware_pb2.HardwareMessage.Type.WATCH_GPIOS
r.gpio_mask = mask

View File

@@ -2,9 +2,8 @@
"""
# pylint: disable=R0917
import logging
import sys
import platform
import time
from io import TextIOWrapper
from typing import List, Optional
@@ -13,27 +12,20 @@ import serial # type: ignore[import-untyped]
import meshtastic.util
from meshtastic.stream_interface import StreamInterface
logger = logging.getLogger(__name__)
if platform.system() != "Windows":
import termios
class SerialInterface(StreamInterface):
"""Interface class for meshtastic devices over a serial link"""
def __init__(
self,
devPath: Optional[str] = None,
debugOut=None,
noProto: bool = False,
connectNow: bool = True,
noNodes: bool = False,
timeout: int = 300
) -> None:
def __init__(self, devPath: Optional[str]=None, debugOut=None, noProto: bool=False, connectNow: bool=True, noNodes: bool=False) -> None:
"""Constructor, opens a connection to a specified serial port, or if unspecified try to
find one Meshtastic device by probing
Keyword Arguments:
devPath {string} -- A filepath to a device, i.e. /dev/ttyUSB0 (default: {None})
debugOut {stream} -- If a stream is provided, any debug serial output from the device will be emitted to that stream. (default: {None})
timeout -- How long to wait for replies (default: 300 seconds)
"""
self.noProto = noProto
@@ -41,7 +33,7 @@ class SerialInterface(StreamInterface):
if self.devPath is None:
ports: List[str] = meshtastic.util.findPorts(True)
logger.debug(f"ports:{ports}")
logging.debug(f"ports:{ports}")
if len(ports) == 0:
print("No Serial Meshtastic device detected, attempting TCP connection on localhost.")
return
@@ -52,11 +44,16 @@ class SerialInterface(StreamInterface):
else:
self.devPath = ports[0]
logger.debug(f"Connecting to {self.devPath}")
logging.debug(f"Connecting to {self.devPath}")
if sys.platform != "win32":
# first we need to set the HUPCL so the device will not reboot based on RTS and/or DTR
# see https://github.com/pyserial/pyserial/issues/124
if platform.system() != "Windows":
with open(self.devPath, encoding="utf8") as f:
self._set_hupcl_with_termios(f)
attrs = termios.tcgetattr(f)
attrs[2] = attrs[2] & ~termios.HUPCL
termios.tcsetattr(f, termios.TCSAFLUSH, attrs)
f.close()
time.sleep(0.1)
self.stream = serial.Serial(
@@ -66,44 +63,15 @@ class SerialInterface(StreamInterface):
time.sleep(0.1)
StreamInterface.__init__(
self, debugOut=debugOut, noProto=noProto, connectNow=connectNow, noNodes=noNodes, timeout=timeout
self, debugOut=debugOut, noProto=noProto, connectNow=connectNow, noNodes=noNodes
)
def _set_hupcl_with_termios(self, f: TextIOWrapper):
"""first we need to set the HUPCL so the device will not reboot based on RTS and/or DTR
see https://github.com/pyserial/pyserial/issues/124
"""
if sys.platform == "win32":
return
import termios # pylint: disable=C0415,E0401
attrs = termios.tcgetattr(f)
attrs[2] = attrs[2] & ~termios.HUPCL
termios.tcsetattr(f, termios.TCSAFLUSH, attrs)
def __repr__(self):
rep = f"SerialInterface(devPath={self.devPath!r}"
if hasattr(self, 'debugOut') and self.debugOut is not None:
rep += f", debugOut={self.debugOut!r}"
if self.noProto:
rep += ", noProto=True"
if hasattr(self, 'noNodes') and self.noNodes:
rep += ", noNodes=True"
rep += ")"
return rep
def close(self) -> None:
"""Close a connection to the device"""
if hasattr(self, "stream") and self.stream and getattr(self.stream, "is_open", False):
try:
self.stream.flush()
time.sleep(0.1)
except Exception as e:
logger.debug(f"Exception during flush: {e}")
try:
self.stream.close()
except Exception as e:
logger.debug(f"Exception during close: {e}")
self.stream = None
logger.debug("Closing Serial stream")
if self.stream: # Stream can be null if we were already closed
self.stream.flush() # FIXME: why are there these two flushes with 100ms sleeps? This shouldn't be necessary
time.sleep(0.1)
self.stream.flush()
time.sleep(0.1)
logging.debug("Closing Serial stream")
StreamInterface.close(self)

View File

@@ -10,7 +10,6 @@ import time
from dataclasses import dataclass
from datetime import datetime
from functools import reduce
from pathlib import Path
from typing import Optional, List, Tuple
import parse # type: ignore[import-untyped]
@@ -23,7 +22,6 @@ from meshtastic.powermon import PowerMeter
from .arrow import FeatherWriter
logger = logging.getLogger(__name__)
def root_dir() -> str:
"""Return the root directory for slog files."""
@@ -31,9 +29,9 @@ def root_dir() -> str:
app_name = "meshtastic"
app_author = "meshtastic"
app_dir = platformdirs.user_data_dir(app_name, app_author)
dir_name = Path(app_dir, "slogs")
dir_name.mkdir(exist_ok=True, parents=True)
return str(dir_name)
dir_name = f"{app_dir}/slogs"
os.makedirs(dir_name, exist_ok=True)
return dir_name
@dataclass(init=False)
@@ -146,7 +144,7 @@ class StructuredLogger:
self.power_logger = power_logger
# Setup the arrow writer (and its schema)
self.writer = FeatherWriter(os.path.join(dir_path, "slog"))
self.writer = FeatherWriter(f"{dir_path}/slog")
all_fields = reduce(
(lambda x, y: x + y), map(lambda x: x.fields, log_defs.values())
)
@@ -166,7 +164,7 @@ class StructuredLogger:
self.raw_file: Optional[
io.TextIOWrapper
] = open( # pylint: disable=consider-using-with
os.path.join(dir_path, "raw.txt"), "w", encoding="utf8"
f"{dir_path}/raw.txt", "w", encoding="utf8"
)
# We need a closure here because the subscription API is very strict about exact arg matching
@@ -199,7 +197,7 @@ class StructuredLogger:
if m:
src = m.group(1)
args = m.group(2)
logger.debug(f"SLog {src}, args: {args}")
logging.debug(f"SLog {src}, args: {args}")
d = log_defs.get(src)
if d:
@@ -221,9 +219,9 @@ class StructuredLogger:
# If the last field is an empty string, remove it
del di[last_field[0]]
else:
logger.warning(f"Failed to parse slog {line} with {d.format}")
logging.warning(f"Failed to parse slog {line} with {d.format}")
else:
logger.warning(f"Unknown Structured Log: {line}")
logging.warning(f"Unknown Structured Log: {line}")
# Store our structured log record
if di or self.include_raw:
@@ -258,28 +256,23 @@ class LogSet:
if not dir_name:
app_dir = root_dir()
app_time_dir = Path(app_dir, datetime.now().strftime('%Y%m%d-%H%M%S'))
app_time_dir.mkdir(exist_ok=True)
dir_name = str(app_time_dir)
dir_name = f"{app_dir}/{datetime.now().strftime('%Y%m%d-%H%M%S')}"
os.makedirs(dir_name, exist_ok=True)
# Also make a 'latest' directory that always points to the most recent logs
latest_dir = Path(app_dir, "latest")
latest_dir.unlink(missing_ok=True)
# symlink might fail on some platforms, if it does fail silently
try:
latest_dir.symlink_to(dir_name, target_is_directory=True)
except OSError:
pass
if os.path.exists(f"{app_dir}/latest"):
os.unlink(f"{app_dir}/latest")
os.symlink(dir_name, f"{app_dir}/latest", target_is_directory=True)
self.dir_name = dir_name
logger.info(f"Writing slogs to {dir_name}")
logging.info(f"Writing slogs to {dir_name}")
self.power_logger: Optional[PowerLogger] = (
None
if not power_meter
else PowerLogger(power_meter, os.path.join(self.dir_name, "power"))
else PowerLogger(power_meter, f"{self.dir_name}/power")
)
self.slog_logger: Optional[StructuredLogger] = StructuredLogger(
@@ -293,7 +286,7 @@ class LogSet:
"""Close the log set."""
if self.slog_logger:
logger.info(f"Closing slogs in {self.dir_name}")
logging.info(f"Closing slogs in {self.dir_name}")
atexit.unregister(
self.atexit_handler
) # docs say it will silently ignore if not found

View File

@@ -17,26 +17,17 @@ START1 = 0x94
START2 = 0xC3
HEADER_LEN = 4
MAX_TO_FROM_RADIO_SIZE = 512
logger = logging.getLogger(__name__)
class StreamInterface(MeshInterface):
"""Interface class for meshtastic devices over a stream link (serial, TCP, etc)"""
def __init__( # pylint: disable=R0917
self,
debugOut: Optional[io.TextIOWrapper] = None,
noProto: bool = False,
connectNow: bool = True,
noNodes: bool = False,
timeout: int = 300
) -> None:
def __init__(self, debugOut: Optional[io.TextIOWrapper]=None, noProto: bool=False, connectNow: bool=True, noNodes: bool=False) -> None:
"""Constructor, opens a connection to self.stream
Keyword Arguments:
debugOut {stream} -- If a stream is provided, any debug serial output from the
device will be emitted to that stream. (default: {None})
timeout -- How long to wait for replies (default: 300 seconds)
Raises:
Exception: [description]
@@ -57,7 +48,7 @@ class StreamInterface(MeshInterface):
# FIXME, figure out why daemon=True causes reader thread to exit too early
self._rxThread = threading.Thread(target=self.__reader, args=(), daemon=True, name="stream reader")
MeshInterface.__init__(self, debugOut=debugOut, noProto=noProto, noNodes=noNodes, timeout=timeout)
MeshInterface.__init__(self, debugOut=debugOut, noProto=noProto, noNodes=noNodes)
# Start the reader thread after superclass constructor completes init
if connectNow:
@@ -91,7 +82,7 @@ class StreamInterface(MeshInterface):
"""We override the superclass implementation to close our port"""
MeshInterface._disconnected(self)
logger.debug("Closing our port")
logging.debug("Closing our port")
# pylint: disable=E0203
if not self.stream is None:
# pylint: disable=E0203
@@ -120,17 +111,17 @@ class StreamInterface(MeshInterface):
def _sendToRadioImpl(self, toRadio) -> None:
"""Send a ToRadio protobuf to the device"""
logger.debug(f"Sending: {stripnl(toRadio)}")
logging.debug(f"Sending: {stripnl(toRadio)}")
b: bytes = toRadio.SerializeToString()
bufLen: int = len(b)
# We convert into a string, because the TCP code doesn't work with byte arrays
header: bytes = bytes([START1, START2, (bufLen >> 8) & 0xFF, bufLen & 0xFF])
logger.debug(f"sending header:{header!r} b:{b!r}")
logging.debug(f"sending header:{header!r} b:{b!r}")
self._writeBytes(header + b)
def close(self) -> None:
"""Close a connection to the device"""
logger.debug("Closing stream")
logging.debug("Closing stream")
MeshInterface.close(self)
# pyserial cancel_read doesn't seem to work, therefore we ask the
# reader thread to close things for us
@@ -157,18 +148,18 @@ class StreamInterface(MeshInterface):
def __reader(self) -> None:
"""The reader thread that reads bytes from our stream"""
logger.debug("in __reader()")
logging.debug("in __reader()")
empty = bytes()
try:
while not self._wantExit:
# logger.debug("reading character")
# logging.debug("reading character")
b: Optional[bytes] = self._readBytes(1)
# logger.debug("In reader loop")
# logger.debug(f"read returned {b}")
# logging.debug("In reader loop")
# logging.debug(f"read returned {b}")
if b is not None and len(cast(bytes, b)) > 0:
c: int = b[0]
# logger.debug(f'c:{c}')
# logging.debug(f'c:{c}')
ptr: int = len(self._rxBuf)
# Assume we want to append this byte, fixme use bytearray instead
@@ -185,7 +176,7 @@ class StreamInterface(MeshInterface):
if c != START2:
self._rxBuf = empty # failed to find start2
elif ptr >= HEADER_LEN - 1: # we've at least got a header
# logger.debug('at least we received a header')
# logging.debug('at least we received a header')
# big endian length follows header
packetlen = (self._rxBuf[2] << 8) + self._rxBuf[3]
@@ -201,32 +192,32 @@ class StreamInterface(MeshInterface):
try:
self._handleFromRadio(self._rxBuf[HEADER_LEN:])
except Exception as ex:
logger.error(
logging.error(
f"Error while handling message from radio {ex}"
)
traceback.print_exc()
self._rxBuf = empty
else:
# logger.debug(f"timeout")
# logging.debug(f"timeout")
pass
except serial.SerialException as ex:
if (
not self._wantExit
): # We might intentionally get an exception during shutdown
logger.warning(
logging.warning(
f"Meshtastic serial port disconnected, disconnecting... {ex}"
)
except OSError as ex:
if (
not self._wantExit
): # We might intentionally get an exception during shutdown
logger.error(
logging.error(
f"Unexpected OSError, terminating meshtastic reader... {ex}"
)
except Exception as ex:
logger.error(
logging.error(
f"Unexpected exception, terminating meshtastic reader... {ex}"
)
finally:
logger.debug("reader is exiting")
logging.debug("reader is exiting")
self._disconnected()

View File

@@ -207,30 +207,6 @@ nano_g1 = SupportedDevice(
usb_product_id_in_hex="55d4",
)
seeed_xiao_s3 = SupportedDevice(
name = "Seeed Xiao ESP32-S3",
version = "",
for_firmware="seeed-xiao-esp32s3",
baseport_on_linux="ttyACM",
baseport_on_mac="cu.usbmodem",
usb_vendor_id_in_hex="2886",
usb_product_id_in_hex="0059",
)
tdeck = SupportedDevice(
name="T-Deck",
version="",
for_firmware="t-deck", # Confirmed firmware identifier
device_class="esp32",
baseport_on_linux="ttyACM",
baseport_on_mac="cu.usbmodem",
baseport_on_windows="COM",
usb_vendor_id_in_hex="303a", # Espressif Systems (VERIFIED)
usb_product_id_in_hex="1001", # VERIFIED from actual device
)
supported_devices = [
tbeam_v0_7,
tbeam_v1_1,
@@ -250,6 +226,4 @@ supported_devices = [
rak4631_19003,
rak11200,
nano_g1,
seeed_xiao_s3,
tdeck, # T-Deck support added
]

View File

@@ -1,16 +1,13 @@
"""TCPInterface class for interfacing with http endpoint
"""
# pylint: disable=R0917
import contextlib
import logging
import socket
import time
from typing import Optional
from typing import Optional, cast
from meshtastic.stream_interface import StreamInterface
DEFAULT_TCP_PORT = 4403
logger = logging.getLogger(__name__)
class TCPInterface(StreamInterface):
"""Interface class for meshtastic devices over a TCP link"""
@@ -23,13 +20,11 @@ class TCPInterface(StreamInterface):
connectNow: bool=True,
portNumber: int=DEFAULT_TCP_PORT,
noNodes:bool=False,
timeout: int = 300,
):
"""Constructor, opens a connection to a specified IP address/hostname
Keyword Arguments:
hostname {string} -- Hostname/IP address of the device to connect to
timeout -- How long to wait for replies (default: 300 seconds)
"""
self.stream = None
@@ -40,78 +35,52 @@ class TCPInterface(StreamInterface):
self.socket: Optional[socket.socket] = None
if connectNow:
self.myConnect()
logging.debug(f"Connecting to {hostname}") # type: ignore[str-bytes-safe]
server_address: tuple[str, int] = (hostname, portNumber)
sock: Optional[socket.socket] = socket.create_connection(server_address)
self.socket = sock
else:
self.socket = None
super().__init__(debugOut=debugOut, noProto=noProto, connectNow=connectNow, noNodes=noNodes, timeout=timeout)
def __repr__(self):
rep = f"TCPInterface({self.hostname!r}"
if self.debugOut is not None:
rep += f", debugOut={self.debugOut!r}"
if self.noProto:
rep += ", noProto=True"
if self.socket is None:
rep += ", connectNow=False"
if self.portNumber != DEFAULT_TCP_PORT:
rep += f", portNumber={self.portNumber!r}"
if self.noNodes:
rep += ", noNodes=True"
rep += ")"
return rep
StreamInterface.__init__(
self, debugOut=debugOut, noProto=noProto, connectNow=connectNow, noNodes=noNodes
)
def _socket_shutdown(self) -> None:
"""Shutdown the socket.
Note: Broke out this line so the exception could be unit tested.
"""
if self.socket is not None:
self.socket.shutdown(socket.SHUT_RDWR)
if self.socket: #mian: please check that this should be "if self.socket:"
cast(socket.socket, self.socket).shutdown(socket.SHUT_RDWR)
def myConnect(self) -> None:
"""Connect to socket"""
logger.debug(f"Connecting to {self.hostname}") # type: ignore[str-bytes-safe]
server_address = (self.hostname, self.portNumber)
self.socket = socket.create_connection(server_address)
server_address: tuple[str, int] = (self.hostname, self.portNumber)
sock: Optional[socket.socket] = socket.create_connection(server_address)
self.socket = sock
def close(self) -> None:
"""Close a connection to the device"""
logger.debug("Closing TCP stream")
super().close()
logging.debug("Closing TCP stream")
StreamInterface.close(self)
# Sometimes the socket read might be blocked in the reader thread.
# Therefore we force the shutdown by closing the socket here
self._wantExit = True
if self.socket is not None:
with contextlib.suppress(Exception): # Ignore errors in shutdown, because we might have a race with the server
self._wantExit: bool = True
if not self.socket is None:
try:
self._socket_shutdown()
except:
pass # Ignore errors in shutdown, because we might have a race with the server
self.socket.close()
self.socket = None
def _writeBytes(self, b: bytes) -> None:
"""Write an array of bytes to our stream and flush"""
if self.socket is not None:
if self.socket:
self.socket.send(b)
def _readBytes(self, length) -> Optional[bytes]:
"""Read an array of bytes from our stream"""
if self.socket is not None:
data = self.socket.recv(length)
# empty byte indicates a disconnected socket,
# we need to handle it to avoid an infinite loop reading from null socket
if data == b'':
logger.debug("dead socket, re-connecting")
# cleanup and reconnect socket without breaking reader thread
with contextlib.suppress(Exception):
self._socket_shutdown()
self.socket.close()
self.socket = None
time.sleep(1)
self.myConnect()
self._startConfig()
return None
return data
# no socket, break reader thread
self._wantExit = True
return None
if self.socket:
return self.socket.recv(length)
else:
return None

View File

@@ -29,7 +29,6 @@ testNumber: int = 0
sendingInterface = None
logger = logging.getLogger(__name__)
def onReceive(packet, interface) -> None:
"""Callback invoked when a packet arrives"""
@@ -80,7 +79,7 @@ def testSend(
else:
toNode = toInterface.myInfo.my_node_num
logger.debug(f"Sending test wantAck={wantAck} packet from {fromNode} to {toNode}")
logging.debug(f"Sending test wantAck={wantAck} packet from {fromNode} to {toNode}")
# pylint: disable=W0603
global sendingInterface
sendingInterface = fromInterface
@@ -99,7 +98,7 @@ def testSend(
def runTests(numTests: int=50, wantAck: bool=False, maxFailures: int=0) -> bool:
"""Run the tests."""
logger.info(f"Running {numTests} tests with wantAck={wantAck}")
logging.info(f"Running {numTests} tests with wantAck={wantAck}")
numFail: int = 0
numSuccess: int = 0
for _ in range(numTests):
@@ -113,26 +112,26 @@ def runTests(numTests: int=50, wantAck: bool=False, maxFailures: int=0) -> bool:
)
if not success:
numFail = numFail + 1
logger.error(
logging.error(
f"Test {testNumber} failed, expected packet not received ({numFail} failures so far)"
)
else:
numSuccess = numSuccess + 1
logger.info(
logging.info(
f"Test {testNumber} succeeded {numSuccess} successes {numFail} failures so far"
)
time.sleep(1)
if numFail > maxFailures:
logger.error("Too many failures! Test failed!")
logging.error("Too many failures! Test failed!")
return False
return True
def testThread(numTests=50) -> bool:
"""Test thread"""
logger.info("Found devices, starting tests...")
logging.info("Found devices, starting tests...")
result: bool = runTests(numTests, wantAck=True)
if result:
# Run another test
@@ -149,7 +148,7 @@ def onConnection(topic=pub.AUTO_TOPIC) -> None:
def openDebugLog(portName) -> io.TextIOWrapper:
"""Open the debug log file"""
debugname = "log" + portName.replace("/", "_")
logger.info(f"Writing serial debugging to {debugname}")
logging.info(f"Writing serial debugging to {debugname}")
return open(debugname, "w+", buffering=1, encoding="utf8")
@@ -178,7 +177,7 @@ def testAll(numTests: int=5) -> bool:
)
)
logger.info("Ports opened, starting test")
logging.info("Ports opened, starting test")
result: bool = testThread(numTests)
for i in interfaces:
@@ -197,14 +196,14 @@ def testSimulator() -> None:
python3 -c 'from meshtastic.test import testSimulator; testSimulator()'
"""
logging.basicConfig(level=logging.DEBUG)
logger.info("Connecting to simulator on localhost!")
logging.info("Connecting to simulator on localhost!")
try:
iface: meshtastic.tcp_interface.TCPInterface = TCPInterface("localhost")
iface.showInfo()
iface.localNode.showInfo()
iface.localNode.exitSimulator()
iface.close()
logger.info("Integration test successful!")
logging.info("Integration test successful!")
except:
print("Error while testing simulator:", sys.exc_info()[0])
traceback.print_exc()

View File

@@ -6,11 +6,7 @@ import sys
import pytest
try:
# Depends upon matplotlib & other packages in poetry's analysis group, not installed by default
from meshtastic.analysis.__main__ import main
except ImportError:
pytest.skip("Can't import meshtastic.analysis", allow_module_level=True)
from meshtastic.analysis.__main__ import main
@pytest.mark.unit

View File

@@ -18,7 +18,6 @@ from meshtastic.__main__ import (
onNode,
onReceive,
tunnelMain,
set_missing_flags_false,
)
from meshtastic import mt_config
@@ -35,6 +34,7 @@ from ..tcp_interface import TCPInterface
# from ..remote_hardware import onGPIOreceive
# from ..config_pb2 import Config
@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
def test_main_init_parser_no_args(capsys):
@@ -454,37 +454,6 @@ def test_main_set_owner_short_to_bob(capsys):
assert err == ""
mo.assert_called()
@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
def test_main_set_is_unmessageable_to_true(capsys):
"""Test --set-is-unmessageable true"""
sys.argv = ["", "--set-is-unmessageable", "true"]
mt_config.args = sys.argv
iface = MagicMock(autospec=SerialInterface)
with patch("meshtastic.serial_interface.SerialInterface", return_value=iface) as mo:
main()
out, err = capsys.readouterr()
assert re.search(r"Connected to radio", out, re.MULTILINE)
assert re.search(r"Setting device owner is_unmessageable to True", out, re.MULTILINE)
assert err == ""
mo.assert_called()
@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
def test_main_set_is_unmessagable_to_true(capsys):
"""Test --set-is-unmessagable true"""
sys.argv = ["", "--set-is-unmessagable", "true"]
mt_config.args = sys.argv
iface = MagicMock(autospec=SerialInterface)
with patch("meshtastic.serial_interface.SerialInterface", return_value=iface) as mo:
main()
out, err = capsys.readouterr()
assert re.search(r"Connected to radio", out, re.MULTILINE)
assert re.search(r"Setting device owner is_unmessageable to True", out, re.MULTILINE)
assert err == ""
mo.assert_called()
@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
@@ -525,44 +494,6 @@ def test_main_get_canned_messages(capsys, caplog, iface_with_nodes):
assert err == ""
mo.assert_called()
@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
def test_main_set_ringtone(capsys):
"""Test --set-ringtone"""
sys.argv = ["", "--set-ringtone", "foo,bar"]
mt_config.args = sys.argv
iface = MagicMock(autospec=SerialInterface)
with patch("meshtastic.serial_interface.SerialInterface", return_value=iface) as mo:
main()
out, err = capsys.readouterr()
assert re.search(r"Connected to radio", out, re.MULTILINE)
assert re.search(r"Setting ringtone to foo,bar", out, re.MULTILINE)
assert err == ""
mo.assert_called()
@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
def test_main_get_ringtone(capsys, caplog, iface_with_nodes):
"""Test --get-ringtone"""
sys.argv = ["", "--get-ringtone"]
mt_config.args = sys.argv
iface = iface_with_nodes
iface.devPath = "bar"
mocked_node = MagicMock(autospec=Node)
mocked_node.get_ringtone.return_value = "foo,bar"
iface.localNode = mocked_node
with caplog.at_level(logging.DEBUG):
with patch("meshtastic.serial_interface.SerialInterface", return_value=iface) as mo:
main()
out, err = capsys.readouterr()
assert re.search(r"Connected to radio", out, re.MULTILINE)
assert re.search(r"ringtone:foo,bar", out, re.MULTILINE)
assert err == ""
mo.assert_called()
@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
@@ -757,11 +688,12 @@ def test_main_sendtext_with_invalid_channel_nine(caplog, capsys):
@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
@patch("meshtastic.serial_interface.SerialInterface._set_hupcl_with_termios")
@patch("termios.tcsetattr")
@patch("termios.tcgetattr")
@patch("builtins.open", new_callable=mock_open, read_data="data")
@patch("serial.Serial")
@patch("meshtastic.util.findPorts", return_value=["/dev/ttyUSBfake"])
def test_main_sendtext_with_dest(mock_findPorts, mock_serial, mocked_open, mock_hupcl, capsys, caplog, iface_with_nodes):
def test_main_sendtext_with_dest(mock_findPorts, mock_serial, mocked_open, mock_get, mock_set, capsys, caplog, iface_with_nodes):
"""Test --sendtext with --dest"""
sys.argv = ["", "--sendtext", "hello", "--dest", "foo"]
mt_config.args = sys.argv
@@ -955,11 +887,12 @@ def test_main_seturl(capsys):
@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
@patch("meshtastic.serial_interface.SerialInterface._set_hupcl_with_termios")
@patch("termios.tcsetattr")
@patch("termios.tcgetattr")
@patch("builtins.open", new_callable=mock_open, read_data="data")
@patch("serial.Serial")
@patch("meshtastic.util.findPorts", return_value=["/dev/ttyUSBfake"])
def test_main_set_valid(mocked_findports, mocked_serial, mocked_open, mocked_hupcl, capsys):
def test_main_set_valid(mocked_findports, mocked_serial, mocked_open, mocked_get, mocked_set, capsys):
"""Test --set with valid field"""
sys.argv = ["", "--set", "network.wifi_ssid", "foo"]
mt_config.args = sys.argv
@@ -979,11 +912,12 @@ def test_main_set_valid(mocked_findports, mocked_serial, mocked_open, mocked_hup
@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
@patch("meshtastic.serial_interface.SerialInterface._set_hupcl_with_termios")
@patch("termios.tcsetattr")
@patch("termios.tcgetattr")
@patch("builtins.open", new_callable=mock_open, read_data="data")
@patch("serial.Serial")
@patch("meshtastic.util.findPorts", return_value=["/dev/ttyUSBfake"])
def test_main_set_valid_wifi_psk(mocked_findports, mocked_serial, mocked_open, mocked_hupcl, capsys):
def test_main_set_valid_wifi_psk(mocked_findports, mocked_serial, mocked_open, mocked_get, mocked_set, capsys):
"""Test --set with valid field"""
sys.argv = ["", "--set", "network.wifi_psk", "123456789"]
mt_config.args = sys.argv
@@ -1003,11 +937,12 @@ def test_main_set_valid_wifi_psk(mocked_findports, mocked_serial, mocked_open, m
@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
@patch("meshtastic.serial_interface.SerialInterface._set_hupcl_with_termios")
@patch("termios.tcsetattr")
@patch("termios.tcgetattr")
@patch("builtins.open", new_callable=mock_open, read_data="data")
@patch("serial.Serial")
@patch("meshtastic.util.findPorts", return_value=["/dev/ttyUSBfake"])
def test_main_set_invalid_wifi_psk(mocked_findports, mocked_serial, mocked_open, mocked_hupcl, capsys):
def test_main_set_invalid_wifi_psk(mocked_findports, mocked_serial, mocked_open, mocked_get, mocked_set, capsys):
"""Test --set with an invalid value (psk must be 8 or more characters)"""
sys.argv = ["", "--set", "network.wifi_psk", "1234567"]
mt_config.args = sys.argv
@@ -1030,11 +965,12 @@ def test_main_set_invalid_wifi_psk(mocked_findports, mocked_serial, mocked_open,
@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
@patch("meshtastic.serial_interface.SerialInterface._set_hupcl_with_termios")
@patch("termios.tcsetattr")
@patch("termios.tcgetattr")
@patch("builtins.open", new_callable=mock_open, read_data="data")
@patch("serial.Serial")
@patch("meshtastic.util.findPorts", return_value=["/dev/ttyUSBfake"])
def test_main_set_valid_camel_case(mocked_findports, mocked_serial, mocked_open, mocked_hupcl, capsys):
def test_main_set_valid_camel_case(mocked_findports, mocked_serial, mocked_open, mocked_get, mocked_set, capsys):
"""Test --set with valid field"""
sys.argv = ["", "--set", "network.wifi_ssid", "foo"]
mt_config.args = sys.argv
@@ -1055,11 +991,12 @@ def test_main_set_valid_camel_case(mocked_findports, mocked_serial, mocked_open,
@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
@patch("meshtastic.serial_interface.SerialInterface._set_hupcl_with_termios")
@patch("termios.tcsetattr")
@patch("termios.tcgetattr")
@patch("builtins.open", new_callable=mock_open, read_data="data")
@patch("serial.Serial")
@patch("meshtastic.util.findPorts", return_value=["/dev/ttyUSBfake"])
def test_main_set_with_invalid(mocked_findports, mocked_serial, mocked_open, mocked_hupcl, capsys):
def test_main_set_with_invalid(mocked_findports, mocked_serial, mocked_open, mocked_get, mocked_set, capsys):
"""Test --set with invalid field"""
sys.argv = ["", "--set", "foo", "foo"]
mt_config.args = sys.argv
@@ -1080,11 +1017,12 @@ def test_main_set_with_invalid(mocked_findports, mocked_serial, mocked_open, moc
# TODO: write some negative --configure tests
@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
@patch("meshtastic.serial_interface.SerialInterface._set_hupcl_with_termios")
@patch("termios.tcsetattr")
@patch("termios.tcgetattr")
@patch("builtins.open", new_callable=mock_open, read_data="data")
@patch("serial.Serial")
@patch("meshtastic.util.findPorts", return_value=["/dev/ttyUSBfake"])
def test_main_configure_with_snake_case(mocked_findports, mocked_serial, mocked_open, mocked_hupcl, capsys):
def test_main_configure_with_snake_case(mocked_findports, mocked_serial, mocked_open, mocked_get, mocked_set, capsys):
"""Test --configure with valid file"""
sys.argv = ["", "--configure", "example_config.yaml"]
mt_config.args = sys.argv
@@ -1112,11 +1050,12 @@ def test_main_configure_with_snake_case(mocked_findports, mocked_serial, mocked_
@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
@patch("meshtastic.serial_interface.SerialInterface._set_hupcl_with_termios")
@patch("termios.tcsetattr")
@patch("termios.tcgetattr")
@patch("builtins.open", new_callable=mock_open, read_data="data")
@patch("serial.Serial")
@patch("meshtastic.util.findPorts", return_value=["/dev/ttyUSBfake"])
def test_main_configure_with_camel_case_keys(mocked_findports, mocked_serial, mocked_open, mocked_hupcl, capsys):
def test_main_configure_with_camel_case_keys(mocked_findports, mocked_serial, mocked_open, mocked_get, mocked_set, capsys):
"""Test --configure with valid file"""
sys.argv = ["", "--configure", "exampleConfig.yaml"]
mt_config.args = sys.argv
@@ -1785,8 +1724,6 @@ def test_main_export_config(capsys):
mo.getLongName.return_value = "foo"
mo.getShortName.return_value = "oof"
mo.localNode.getURL.return_value = "bar"
mo.getCannedMessage.return_value = "foo|bar"
mo.getRingtone.return_value = "24:d=32,o=5"
mo.getMyNodeInfo().get.return_value = {
"latitudeI": 1100000000,
"longitudeI": 1200000000,
@@ -1801,8 +1738,7 @@ position_broadcast_smart: true
fixed_position: true
position_flags: 35"""
export_config(mo)
out = export_config(mo)
err = ""
out, err = capsys.readouterr()
# ensure we do not output this line
assert not re.search(r"Connected to radio", out, re.MULTILINE)
@@ -1889,41 +1825,6 @@ position_flags: 35"""
# mo.assert_called()
@pytest.mark.unit
def test_set_missing_flags_false():
"""Test set_missing_flags_false() function"""
config = {
"bluetooth": {
"enabled": True
},
"lora": {
"txEnabled": True
}
}
false_defaults = {
("bluetooth", "enabled"),
("lora", "sx126xRxBoostedGain"),
("lora", "txEnabled"),
("lora", "usePreset"),
("position", "positionBroadcastSmartEnabled"),
("security", "serialEnabled"),
("mqtt", "encryptionEnabled"),
}
set_missing_flags_false(config, false_defaults)
# Preserved
assert config["bluetooth"]["enabled"] is True
assert config["lora"]["txEnabled"] is True
# Added
assert config["lora"]["usePreset"] is False
assert config["lora"]["sx126xRxBoostedGain"] is False
assert config["position"]["positionBroadcastSmartEnabled"] is False
assert config["security"]["serialEnabled"] is False
assert config["mqtt"]["encryptionEnabled"] is False
@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
def test_main_gpio_rd_no_gpio_channel(capsys):
@@ -2713,16 +2614,16 @@ def test_tunnel_subnet_arg_with_no_devices(mock_platform_system, caplog, capsys)
assert err == ""
@pytest.mark.skipif(sys.platform == "win32", reason="on windows is no fcntl module")
@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
@patch("platform.system")
@patch("meshtastic.serial_interface.SerialInterface._set_hupcl_with_termios")
@patch("termios.tcsetattr")
@patch("termios.tcgetattr")
@patch("builtins.open", new_callable=mock_open, read_data="data")
@patch("serial.Serial")
@patch("meshtastic.util.findPorts", return_value=["/dev/ttyUSBfake"])
def test_tunnel_tunnel_arg(
mocked_findPorts, mocked_serial, mocked_open, mock_hupcl, mock_platform_system, caplog, iface_with_nodes, capsys
mocked_findPorts, mocked_serial, mocked_open, mock_get, mock_set, mock_platform_system, caplog, iface_with_nodes, capsys
):
"""Test tunnel with tunnel arg (act like we are on a linux system)"""
@@ -2812,91 +2713,3 @@ def test_remove_ignored_node():
main()
mocked_node.removeIgnored.assert_called_once_with("!12345678")
@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
def test_main_set_owner_whitespace_only(capsys):
"""Test --set-owner with whitespace-only name"""
sys.argv = ["", "--set-owner", " "]
mt_config.args = sys.argv
with pytest.raises(SystemExit) as excinfo:
main()
out, _ = capsys.readouterr()
assert "ERROR: Long Name cannot be empty or contain only whitespace characters" in out
assert excinfo.value.code == 1
@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
def test_main_set_owner_empty_string(capsys):
"""Test --set-owner with empty string"""
sys.argv = ["", "--set-owner", ""]
mt_config.args = sys.argv
with pytest.raises(SystemExit) as excinfo:
main()
out, _ = capsys.readouterr()
assert "ERROR: Long Name cannot be empty or contain only whitespace characters" in out
assert excinfo.value.code == 1
@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
def test_main_set_owner_short_whitespace_only(capsys):
"""Test --set-owner-short with whitespace-only name"""
sys.argv = ["", "--set-owner-short", " "]
mt_config.args = sys.argv
with pytest.raises(SystemExit) as excinfo:
main()
out, _ = capsys.readouterr()
assert "ERROR: Short Name cannot be empty or contain only whitespace characters" in out
assert excinfo.value.code == 1
@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
def test_main_set_owner_short_empty_string(capsys):
"""Test --set-owner-short with empty string"""
sys.argv = ["", "--set-owner-short", ""]
mt_config.args = sys.argv
with pytest.raises(SystemExit) as excinfo:
main()
out, _ = capsys.readouterr()
assert "ERROR: Short Name cannot be empty or contain only whitespace characters" in out
assert excinfo.value.code == 1
@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
def test_main_set_ham_whitespace_only(capsys):
"""Test --set-ham with whitespace-only name"""
sys.argv = ["", "--set-ham", " "]
mt_config.args = sys.argv
with pytest.raises(SystemExit) as excinfo:
main()
out, _ = capsys.readouterr()
assert "ERROR: Ham radio callsign cannot be empty or contain only whitespace characters" in out
assert excinfo.value.code == 1
@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
def test_main_set_ham_empty_string(capsys):
"""Test --set-ham with empty string"""
sys.argv = ["", "--set-ham", ""]
mt_config.args = sys.argv
with pytest.raises(SystemExit) as excinfo:
main()
out, _ = capsys.readouterr()
assert "ERROR: Ham radio callsign cannot be empty or contain only whitespace characters" in out
assert excinfo.value.code == 1

View File

@@ -11,12 +11,8 @@ from ..protobuf import mesh_pb2, config_pb2
from .. import BROADCAST_ADDR, LOCAL_ADDR
from ..mesh_interface import MeshInterface, _timeago
from ..node import Node
try:
# Depends upon the powermon group, not installed by default
from ..slog import LogSet
from ..powermon import SimPowerSupply
except ImportError:
pytest.skip("Can't import LogSet or SimPowerSupply", allow_module_level=True)
from ..slog import LogSet
from ..powermon import SimPowerSupply
# TODO
# from ..config import Config
@@ -525,28 +521,6 @@ def test_getMyNodeInfo():
myinfo = iface.getMyNodeInfo()
assert myinfo == anode
@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
def test_getCannedMessage():
"""Test MeshInterface.getCannedMessage()"""
iface = MeshInterface(noProto=True)
node = MagicMock()
node.get_canned_message.return_value = "Hi|Bye|Yes"
iface.localNode = node
result = iface.getCannedMessage()
assert result == "Hi|Bye|Yes"
@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
def test_getRingtone():
"""Test MeshInterface.getRingtone()"""
iface = MeshInterface(noProto=True)
node = MagicMock()
node.get_ringtone.return_value = "foo,bar"
iface.localNode = node
result = iface.getRingtone()
assert result == "foo,bar"
@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
@@ -565,6 +539,7 @@ def test_generatePacketId(capsys):
assert err == ""
assert pytest_wrapped_e.type == MeshInterface.MeshInterfaceError
@pytest.mark.unit
@pytest.mark.usefixtures("reset_mt_config")
def test_fixupPosition_empty_pos():
@@ -672,21 +647,15 @@ def test_getOrCreateByNum(iface_with_nodes):
@pytest.mark.unit
def test_exit_with_exception(caplog):
"""Test __exit__()"""
iface = MeshInterface(noProto=True)
with caplog.at_level(logging.ERROR):
try:
with MeshInterface(noProto=True):
raise ValueError("Something went wrong")
except:
assert re.search(
r"An exception of type <class \'ValueError\'> with value Something went wrong has occurred",
caplog.text,
re.MULTILINE,
)
assert re.search(
r"Traceback:\n.*in test_exit_with_exception\n {4}raise ValueError\(\"Something went wrong\"\)",
caplog.text,
re.MULTILINE
)
iface.__exit__("foo", "bar", "baz")
assert re.search(
r"An exception of type foo with value bar has occurred",
caplog.text,
re.MULTILINE,
)
assert re.search(r"Traceback: baz", caplog.text, re.MULTILINE)
@pytest.mark.unit

View File

@@ -1254,7 +1254,8 @@ def test_requestChannels_non_localNode_starting_index(caplog):
# },
# 'id': 1692918436,
# 'hopLimit': 3,
# 'priority': 'RELIABLE',
# 'priority':
# 'RELIABLE',
# 'raw': 'fake',
# 'fromId': '!9388f81c',
# 'toId': '!9388f81c'
@@ -1479,77 +1480,6 @@ def test_remove_ignored(ignored):
iface.sendData.assert_called_once()
@pytest.mark.unit
def test_setOwner_whitespace_only_long_name(capsys):
"""Test setOwner with whitespace-only long name"""
iface = MagicMock(autospec=MeshInterface)
anode = Node(iface, 123, noProto=True)
with pytest.raises(SystemExit) as excinfo:
anode.setOwner(long_name=" ")
out, _ = capsys.readouterr()
assert "ERROR: Long Name cannot be empty or contain only whitespace characters" in out
assert excinfo.value.code == 1
@pytest.mark.unit
def test_setOwner_empty_long_name(capsys):
"""Test setOwner with empty long name"""
iface = MagicMock(autospec=MeshInterface)
anode = Node(iface, 123, noProto=True)
with pytest.raises(SystemExit) as excinfo:
anode.setOwner(long_name="")
out, _ = capsys.readouterr()
assert "ERROR: Long Name cannot be empty or contain only whitespace characters" in out
assert excinfo.value.code == 1
@pytest.mark.unit
def test_setOwner_whitespace_only_short_name(capsys):
"""Test setOwner with whitespace-only short name"""
iface = MagicMock(autospec=MeshInterface)
anode = Node(iface, 123, noProto=True)
with pytest.raises(SystemExit) as excinfo:
anode.setOwner(short_name=" ")
out, _ = capsys.readouterr()
assert "ERROR: Short Name cannot be empty or contain only whitespace characters" in out
assert excinfo.value.code == 1
@pytest.mark.unit
def test_setOwner_empty_short_name(capsys):
"""Test setOwner with empty short name"""
iface = MagicMock(autospec=MeshInterface)
anode = Node(iface, 123, noProto=True)
with pytest.raises(SystemExit) as excinfo:
anode.setOwner(short_name="")
out, _ = capsys.readouterr()
assert "ERROR: Short Name cannot be empty or contain only whitespace characters" in out
assert excinfo.value.code == 1
@pytest.mark.unit
def test_setOwner_valid_names(caplog):
"""Test setOwner with valid names"""
iface = MagicMock(autospec=MeshInterface)
anode = Node(iface, 123, noProto=True)
with caplog.at_level(logging.DEBUG):
anode.setOwner(long_name="ValidName", short_name="VN")
# Should not raise any exceptions
# Note: When noProto=True, _sendAdmin is not called as the method returns early
assert re.search(r'p.set_owner.long_name:ValidName:', caplog.text, re.MULTILINE)
assert re.search(r'p.set_owner.short_name:VN:', caplog.text, re.MULTILINE)
# TODO
# @pytest.mark.unitslow
# def test_waitForConfig():

View File

@@ -2,7 +2,6 @@
# pylint: disable=R0917
import re
import sys
from unittest.mock import mock_open, patch
import pytest
@@ -10,14 +9,16 @@ import pytest
from ..serial_interface import SerialInterface
from ..protobuf import config_pb2
@pytest.mark.unit
@patch("time.sleep")
@patch("meshtastic.serial_interface.SerialInterface._set_hupcl_with_termios")
@patch("termios.tcsetattr")
@patch("termios.tcgetattr")
@patch("builtins.open", new_callable=mock_open, read_data="data")
@patch("serial.Serial")
@patch("meshtastic.util.findPorts", return_value=["/dev/ttyUSBfake"])
def test_SerialInterface_single_port(
mocked_findPorts, mocked_serial, mocked_open, mock_hupcl, mock_sleep, capsys
mocked_findPorts, mocked_serial, mocked_open, mock_get, mock_set, mock_sleep, capsys
):
"""Test that we can instantiate a SerialInterface with a single port"""
iface = SerialInterface(noProto=True)
@@ -27,12 +28,9 @@ def test_SerialInterface_single_port(
iface.close()
mocked_findPorts.assert_called()
mocked_serial.assert_called()
# doesn't get called in SerialInterface on windows
if sys.platform != "win32":
mocked_open.assert_called()
mock_hupcl.assert_called()
mocked_open.assert_called()
mock_get.assert_called()
mock_set.assert_called()
mock_sleep.assert_called()
out, err = capsys.readouterr()
assert re.search(r"Nodes in mesh", out, re.MULTILINE)

View File

@@ -9,11 +9,7 @@ import pytest
from meshtastic import mt_config
from ..tcp_interface import TCPInterface
try:
# Depends upon pytap2, not installed by default
from ..tunnel import Tunnel, onTunnelReceive
except ImportError:
pytest.skip("Can't import Tunnel or onTunnelReceive", allow_module_level=True)
from ..tunnel import Tunnel, onTunnelReceive
@pytest.mark.unit

View File

@@ -11,19 +11,16 @@ from hypothesis import given, strategies as st
from meshtastic.supported_device import SupportedDevice
from meshtastic.protobuf import mesh_pb2
from meshtastic.util import (
DEFAULT_KEY,
Timeout,
active_ports_on_supported_devices,
camel_to_snake,
catchAndIgnore,
channel_hash,
convert_mac_addr,
eliminate_duplicate_port,
findPorts,
fixme,
fromPSK,
fromStr,
generate_channel_hash,
genPSK256,
hexstr,
ipstr,
@@ -566,7 +563,7 @@ def test_active_ports_on_supported_devices_mac_duplicates_check(mock_platform, m
def test_message_to_json_shows_all():
"""Test that message_to_json prints fields that aren't included in data passed in"""
actual = json.loads(message_to_json(mesh_pb2.MyNodeInfo()))
expected = { "myNodeNum": 0, "rebootCount": 0, "minAppVersion": 0, "deviceId": "", "pioEnv": "", 'firmwareEdition': 'VANILLA', 'nodedbCount': 0 }
expected = { "myNodeNum": 0, "rebootCount": 0, "minAppVersion": 0, "deviceId": "", "pioEnv": "" }
assert actual == expected
@pytest.mark.unit
@@ -673,45 +670,3 @@ def test_shorthex():
assert result == b'\x05'
result = fromStr('0xffff')
assert result == b'\xff\xff'
def test_channel_hash_basics():
"Test the default key and LongFast with channel_hash"
assert channel_hash(DEFAULT_KEY) == 2
assert channel_hash("LongFast".encode("utf-8")) == 10
@given(st.text(min_size=1, max_size=12))
def test_channel_hash_fuzz(channel_name):
"Test channel_hash with fuzzed channel names, ensuring it produces single-byte values"
hashed = channel_hash(channel_name.encode("utf-8"))
assert 0 <= hashed <= 0xFF
def test_generate_channel_hash_basics():
"Test the default key and LongFast/MediumFast with generate_channel_hash"
assert generate_channel_hash("LongFast", "AQ==") == 8
assert generate_channel_hash("LongFast", bytes([1])) == 8
assert generate_channel_hash("LongFast", DEFAULT_KEY) == 8
assert generate_channel_hash("MediumFast", DEFAULT_KEY) == 31
@given(st.text(min_size=1, max_size=12))
def test_generate_channel_hash_fuzz_default_key(channel_name):
"Test generate_channel_hash with fuzzed channel names and the default key, ensuring it produces single-byte values"
hashed = generate_channel_hash(channel_name, DEFAULT_KEY)
assert 0 <= hashed <= 0xFF
@given(st.text(min_size=1, max_size=12), st.binary(min_size=1, max_size=1))
def test_generate_channel_hash_fuzz_simple(channel_name, key_bytes):
"Test generate_channel_hash with fuzzed channel names and one-byte keys, ensuring it produces single-byte values"
hashed = generate_channel_hash(channel_name, key_bytes)
assert 0 <= hashed <= 0xFF
@given(st.text(min_size=1, max_size=12), st.binary(min_size=16, max_size=16))
def test_generate_channel_hash_fuzz_aes128(channel_name, key_bytes):
"Test generate_channel_hash with fuzzed channel names and 128-bit keys, ensuring it produces single-byte values"
hashed = generate_channel_hash(channel_name, key_bytes)
assert 0 <= hashed <= 0xFF
@given(st.text(min_size=1, max_size=12), st.binary(min_size=32, max_size=32))
def test_generate_channel_hash_fuzz_aes256(channel_name, key_bytes):
"Test generate_channel_hash with fuzzed channel names and 256-bit keys, ensuring it produces single-byte values"
hashed = generate_channel_hash(channel_name, key_bytes)
assert 0 <= hashed <= 0xFF

View File

@@ -26,11 +26,10 @@ from meshtastic.protobuf import portnums_pb2
from meshtastic import mt_config
from meshtastic.util import ipstr, readnet_u16
logger = logging.getLogger(__name__)
def onTunnelReceive(packet, interface): # pylint: disable=W0613
"""Callback for received tunneled messages from mesh."""
logger.debug(f"in onTunnelReceive()")
logging.debug(f"in onTunnelReceive()")
tunnelInstance = mt_config.tunnelInstance
tunnelInstance.onReceive(packet)
@@ -93,7 +92,7 @@ class Tunnel:
self.LOG_TRACE = 5
# TODO: check if root?
logger.info(
logging.info(
"Starting IP to mesh tunnel (you must be root for this *pre-alpha* "
"feature to work). Mesh members:"
)
@@ -105,13 +104,13 @@ class Tunnel:
for node in self.iface.nodes.values():
nodeId = node["user"]["id"]
ip = self._nodeNumToIp(node["num"])
logger.info(f"Node { nodeId } has IP address { ip }")
logging.info(f"Node { nodeId } has IP address { ip }")
logger.debug("creating TUN device with MTU=200")
logging.debug("creating TUN device with MTU=200")
# FIXME - figure out real max MTU, it should be 240 - the overhead bytes for SubPacket and Data
self.tun = None
if self.iface.noProto:
logger.warning(
logging.warning(
f"Not creating a TapDevice() because it is disabled by noProto"
)
else:
@@ -121,11 +120,11 @@ class Tunnel:
self._rxThread = None
if self.iface.noProto:
logger.warning(
logging.warning(
f"Not starting TUN reader because it is disabled by noProto"
)
else:
logger.debug(f"starting TUN reader, our IP address is {myAddr}")
logging.debug(f"starting TUN reader, our IP address is {myAddr}")
self._rxThread = threading.Thread(
target=self.__tunReader, args=(), daemon=True
)
@@ -135,9 +134,9 @@ class Tunnel:
"""onReceive"""
p = packet["decoded"]["payload"]
if packet["from"] == self.iface.myInfo.my_node_num:
logger.debug("Ignoring message we sent")
logging.debug("Ignoring message we sent")
else:
logger.debug(f"Received mesh tunnel message type={type(p)} len={len(p)}")
logging.debug(f"Received mesh tunnel message type={type(p)} len={len(p)}")
# we don't really need to check for filtering here (sender should have checked),
# but this provides useful debug printing on types of packets received
if not self.iface.noProto:
@@ -153,7 +152,7 @@ class Tunnel:
ignore = False # Assume we will be forwarding the packet
if protocol in self.protocolBlacklist:
ignore = True
logger.log(
logging.log(
self.LOG_TRACE, f"Ignoring blacklisted protocol 0x{protocol:02x}"
)
elif protocol == 0x01: # ICMP
@@ -161,7 +160,7 @@ class Tunnel:
icmpCode = p[21]
checksum = p[22:24]
# pylint: disable=line-too-long
logger.debug(
logging.debug(
f"forwarding ICMP message src={ipstr(srcaddr)}, dest={ipstr(destAddr)}, type={icmpType}, code={icmpCode}, checksum={checksum}"
)
# reply to pings (swap src and dest but keep rest of packet unchanged)
@@ -172,19 +171,19 @@ class Tunnel:
destport = readnet_u16(p, subheader + 2)
if destport in self.udpBlacklist:
ignore = True
logger.log(self.LOG_TRACE, f"ignoring blacklisted UDP port {destport}")
logging.log(self.LOG_TRACE, f"ignoring blacklisted UDP port {destport}")
else:
logger.debug(f"forwarding udp srcport={srcport}, destport={destport}")
logging.debug(f"forwarding udp srcport={srcport}, destport={destport}")
elif protocol == 0x06: # TCP
srcport = readnet_u16(p, subheader)
destport = readnet_u16(p, subheader + 2)
if destport in self.tcpBlacklist:
ignore = True
logger.log(self.LOG_TRACE, f"ignoring blacklisted TCP port {destport}")
logging.log(self.LOG_TRACE, f"ignoring blacklisted TCP port {destport}")
else:
logger.debug(f"forwarding tcp srcport={srcport}, destport={destport}")
logging.debug(f"forwarding tcp srcport={srcport}, destport={destport}")
else:
logger.warning(
logging.warning(
f"forwarding unexpected protocol 0x{protocol:02x}, "
"src={ipstr(srcaddr)}, dest={ipstr(destAddr)}"
)
@@ -193,10 +192,10 @@ class Tunnel:
def __tunReader(self):
tap = self.tun
logger.debug("TUN reader running")
logging.debug("TUN reader running")
while True:
p = tap.read()
# logger.debug(f"IP packet received on TUN interface, type={type(p)}")
# logging.debug(f"IP packet received on TUN interface, type={type(p)}")
destAddr = p[16:20]
if not self._shouldFilterPacket(p):
@@ -211,7 +210,7 @@ class Tunnel:
for node in self.iface.nodes.values():
nodeNum = node["num"] & 0xFFFF
# logger.debug(f"Considering nodenum 0x{nodeNum:x} for ipBits 0x{ipBits:x}")
# logging.debug(f"Considering nodenum 0x{nodeNum:x} for ipBits 0x{ipBits:x}")
if (nodeNum) == ipBits:
return node["user"]["id"]
return None
@@ -223,12 +222,12 @@ class Tunnel:
"""Forward the provided IP packet into the mesh"""
nodeId = self._ipToNodeId(destAddr)
if nodeId is not None:
logger.debug(
logging.debug(
f"Forwarding packet bytelen={len(p)} dest={ipstr(destAddr)}, destNode={nodeId}"
)
self.iface.sendData(p, nodeId, portnums_pb2.IP_TUNNEL_APP, wantAck=False)
else:
logger.warning(
logging.warning(
f"Dropping packet because no node found for destIP={ipstr(destAddr)}"
)

View File

@@ -38,9 +38,6 @@ blacklistVids: Dict = dict.fromkeys([0x1366, 0x0483, 0x1915, 0x0925, 0x04b4])
0x303a Heltec tracker"""
whitelistVids = dict.fromkeys([0x239a, 0x303a])
logger = logging.getLogger(__name__)
DEFAULT_KEY = base64.b64decode("1PG7OiApB1nwvP+rz05pAQ==".encode("utf-8"))
def quoteBooleans(a_string: str) -> str:
"""Quote booleans
@@ -144,7 +141,7 @@ def catchAndIgnore(reason: str, closure) -> None:
try:
closure()
except BaseException as ex:
logger.error(f"Exception thrown in {reason}: {ex}")
logging.error(f"Exception thrown in {reason}: {ex}")
def findPorts(eliminate_duplicates: bool=False) -> List[str]:
@@ -201,9 +198,9 @@ class Timeout:
self.sleepInterval: float = 0.1
self.expireTimeout: int = maxSecs
def reset(self, expireTimeout=None):
def reset(self) -> None:
"""Restart the waitForSet timer"""
self.expireTime = time.time() + (self.expireTimeout if expireTimeout is None else expireTimeout)
self.expireTime = time.time() + self.expireTimeout
def waitForSet(self, target, attrs=()) -> bool:
"""Block until the specified attributes are set. Returns True if config has been received."""
@@ -228,7 +225,8 @@ class Timeout:
def waitForTraceRoute(self, waitFactor, acknowledgment, attr="receivedTraceRoute") -> bool:
"""Block until traceroute response is received. Returns True if traceroute response has been received."""
self.reset(self.expireTimeout * waitFactor)
self.expireTimeout *= waitFactor
self.reset()
while time.time() < self.expireTime:
if getattr(acknowledgment, attr, None):
acknowledgment.reset()
@@ -310,7 +308,7 @@ class DeferredExecution:
o = self.queue.get()
o()
except:
logger.error(
logging.error(
f"Unexpected error in deferred execution {sys.exc_info()[0]}"
)
print(traceback.format_exc())
@@ -367,30 +365,6 @@ def remove_keys_from_dict(keys: Union[Tuple, List, Set], adict: Dict) -> Dict:
remove_keys_from_dict(keys, val)
return adict
def channel_hash(data: bytes) -> int:
"""Compute an XOR hash from bytes for channel evaluation."""
result = 0
for char in data:
result ^= char
return result
def generate_channel_hash(name: Union[str, bytes], key: Union[str, bytes]) -> int:
"""generate the channel number by hashing the channel name and psk (accepts str or bytes for both)"""
# Handle key as str or bytes
if isinstance(key, str):
key = base64.b64decode(key.replace("-", "+").replace("_", "/").encode("utf-8"))
if len(key) == 1:
key = DEFAULT_KEY[:-1] + key
# Handle name as str or bytes
if isinstance(name, str):
name = name.encode("utf-8")
h_name = channel_hash(name)
h_key = channel_hash(key)
result: int = h_name ^ h_key
return result
def hexstr(barray: bytes) -> str:
"""Print a string of hex digits"""
@@ -718,20 +692,3 @@ def message_to_json(message: Message, multiline: bool=False) -> str:
except TypeError:
json = MessageToJson(message, including_default_value_fields=True) # type: ignore[call-arg] # pylint: disable=E1123
return stripnl(json) if not multiline else json
def to_node_num(node_id: Union[int, str]) -> int:
"""
Normalize a node id from int | '!hex' | '0xhex' | 'decimal' to int.
"""
if isinstance(node_id, int):
return node_id
s = str(node_id).strip()
if s.startswith("!"):
s = s[1:]
if s.lower().startswith("0x"):
return int(s, 16)
try:
return int(s, 10)
except ValueError:
return int(s, 16)

View File

@@ -1,6 +1,6 @@
[tool.poetry]
name = "meshtastic"
version = "2.7.4"
version = "2.6.0a1"
description = "Python API & client shell for talking to Meshtastic devices"
authors = ["Meshtastic Developers <contact@meshtastic.org>"]
license = "GPL-3.0-only"